Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: src/IceInstX86BaseImpl.h

Issue 1676123002: Subzero: Use a proper RegNumT type instead of int32_t/SizeT. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make it possible to do "auto NewReg = RegNumT::NoRegister;" Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceOperand.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); 881 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
882 } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) { 882 } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
883 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, 883 (Asm->*(Emitter.XmmAddr))(Ty, VarReg,
884 Traits::Address::ofConstPool(Asm, Imm)); 884 Traits::Address::ofConstPool(Asm, Imm));
885 } else { 885 } else {
886 llvm_unreachable("Unexpected operand type"); 886 llvm_unreachable("Unexpected operand type");
887 } 887 }
888 } 888 }
889 889
890 template <typename TraitsType> 890 template <typename TraitsType>
891 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), 891 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
892 SReg_t (*srcEnc)(int32_t)> 892 SReg_t (*srcEnc)(RegNumT)>
893 void InstImpl<TraitsType>::emitIASCastRegOp( 893 void InstImpl<TraitsType>::emitIASCastRegOp(
894 const Cfg *Func, Type DestTy, const Variable *Dest, Type SrcTy, 894 const Cfg *Func, Type DestTy, const Variable *Dest, Type SrcTy,
895 const Operand *Src, const CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { 895 const Operand *Src, const CastEmitterRegOp<DReg_t, SReg_t> &Emitter) {
896 auto *Target = InstX86Base::getTarget(Func); 896 auto *Target = InstX86Base::getTarget(Func);
897 Assembler *Asm = Func->getAssembler<Assembler>(); 897 Assembler *Asm = Func->getAssembler<Assembler>();
898 assert(Dest->hasReg()); 898 assert(Dest->hasReg());
899 DReg_t DestReg = destEnc(Dest->getRegNum()); 899 DReg_t DestReg = destEnc(Dest->getRegNum());
900 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { 900 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
901 if (SrcVar->hasReg()) { 901 if (SrcVar->hasReg()) {
902 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); 902 SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
903 (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg); 903 (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
904 } else { 904 } else {
905 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar); 905 Address SrcStackAddr = Target->stackVarToAsmOperand(SrcVar);
906 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr); 906 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
907 } 907 }
908 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) { 908 } else if (const auto *Mem = llvm::dyn_cast<X86OperandMem>(Src)) {
909 Mem->emitSegmentOverride(Asm); 909 Mem->emitSegmentOverride(Asm);
910 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, 910 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy,
911 Mem->toAsmAddress(Asm, Target)); 911 Mem->toAsmAddress(Asm, Target));
912 } else { 912 } else {
913 llvm_unreachable("Unexpected operand type"); 913 llvm_unreachable("Unexpected operand type");
914 } 914 }
915 } 915 }
916 916
917 template <typename TraitsType> 917 template <typename TraitsType>
918 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), 918 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
919 SReg_t (*srcEnc)(int32_t)> 919 SReg_t (*srcEnc)(RegNumT)>
920 void InstImpl<TraitsType>::emitIASThreeOpImmOps( 920 void InstImpl<TraitsType>::emitIASThreeOpImmOps(
921 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, 921 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
922 const Operand *Src1, const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { 922 const Operand *Src1, const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
923 auto *Target = InstX86Base::getTarget(Func); 923 auto *Target = InstX86Base::getTarget(Func);
924 Assembler *Asm = Func->getAssembler<Assembler>(); 924 Assembler *Asm = Func->getAssembler<Assembler>();
925 // This only handles Dest being a register, and Src1 being an immediate. 925 // This only handles Dest being a register, and Src1 being an immediate.
926 assert(Dest->hasReg()); 926 assert(Dest->hasReg());
927 DReg_t DestReg = destEnc(Dest->getRegNum()); 927 DReg_t DestReg = destEnc(Dest->getRegNum());
928 AssemblerImmediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); 928 AssemblerImmediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
929 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src0)) { 929 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src0)) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 this->getSrc(2), Emitter); 1184 this->getSrc(2), Emitter);
1185 } 1185 }
1186 1186
1187 template <typename TraitsType> 1187 template <typename TraitsType>
1188 void InstImpl<TraitsType>::InstX86Cbwdq::emit(const Cfg *Func) const { 1188 void InstImpl<TraitsType>::InstX86Cbwdq::emit(const Cfg *Func) const {
1189 if (!BuildDefs::dump()) 1189 if (!BuildDefs::dump())
1190 return; 1190 return;
1191 Ostream &Str = Func->getContext()->getStrEmit(); 1191 Ostream &Str = Func->getContext()->getStrEmit();
1192 assert(this->getSrcSize() == 1); 1192 assert(this->getSrcSize() == 1);
1193 Operand *Src0 = this->getSrc(0); 1193 Operand *Src0 = this->getSrc(0);
1194 int32_t DestReg = this->getDest()->getRegNum(); 1194 const auto DestReg = this->getDest()->getRegNum();
1195 int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum(); 1195 const auto SrcReg = llvm::cast<Variable>(Src0)->getRegNum();
1196 (void)DestReg; 1196 (void)DestReg;
1197 (void)SrcReg; 1197 (void)SrcReg;
1198 switch (Src0->getType()) { 1198 switch (Src0->getType()) {
1199 default: 1199 default:
1200 llvm_unreachable("unexpected source type!"); 1200 llvm_unreachable("unexpected source type!");
1201 break; 1201 break;
1202 case IceType_i8: 1202 case IceType_i8:
1203 assert(SrcReg == RegisterSet::Reg_al); 1203 assert(SrcReg == RegisterSet::Reg_al);
1204 assert(DestReg == RegisterSet::Reg_ax || DestReg == RegisterSet::Reg_ah); 1204 assert(DestReg == RegisterSet::Reg_ax || DestReg == RegisterSet::Reg_ah);
1205 Str << "\t" 1205 Str << "\t"
(...skipping 19 matching lines...) Expand all
1225 "cqo"; 1225 "cqo";
1226 break; 1226 break;
1227 } 1227 }
1228 } 1228 }
1229 1229
1230 template <typename TraitsType> 1230 template <typename TraitsType>
1231 void InstImpl<TraitsType>::InstX86Cbwdq::emitIAS(const Cfg *Func) const { 1231 void InstImpl<TraitsType>::InstX86Cbwdq::emitIAS(const Cfg *Func) const {
1232 Assembler *Asm = Func->getAssembler<Assembler>(); 1232 Assembler *Asm = Func->getAssembler<Assembler>();
1233 assert(this->getSrcSize() == 1); 1233 assert(this->getSrcSize() == 1);
1234 Operand *Src0 = this->getSrc(0); 1234 Operand *Src0 = this->getSrc(0);
1235 int32_t DestReg = this->getDest()->getRegNum(); 1235 const auto DestReg = this->getDest()->getRegNum();
1236 int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum(); 1236 const auto SrcReg = llvm::cast<Variable>(Src0)->getRegNum();
1237 (void)DestReg; 1237 (void)DestReg;
1238 (void)SrcReg; 1238 (void)SrcReg;
1239 switch (Src0->getType()) { 1239 switch (Src0->getType()) {
1240 default: 1240 default:
1241 llvm_unreachable("unexpected source type!"); 1241 llvm_unreachable("unexpected source type!");
1242 break; 1242 break;
1243 case IceType_i8: 1243 case IceType_i8:
1244 assert(SrcReg == RegisterSet::Reg_al); 1244 assert(SrcReg == RegisterSet::Reg_al);
1245 assert(DestReg == RegisterSet::Reg_ax || DestReg == RegisterSet::Reg_ah); 1245 assert(DestReg == RegisterSet::Reg_ax || DestReg == RegisterSet::Reg_ah);
1246 Asm->cbw(); 1246 Asm->cbw();
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 Ostream &Str = Func->getContext()->getStrEmit(); 1980 Ostream &Str = Func->getContext()->getStrEmit();
1981 assert(this->getSrcSize() == 1); 1981 assert(this->getSrcSize() == 1);
1982 assert(this->getDest()->hasReg()); 1982 assert(this->getDest()->hasReg());
1983 Str << "\t" 1983 Str << "\t"
1984 "lea" << this->getWidthString(this->getDest()->getType()) << "\t"; 1984 "lea" << this->getWidthString(this->getDest()->getType()) << "\t";
1985 Operand *Src0 = this->getSrc(0); 1985 Operand *Src0 = this->getSrc(0);
1986 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { 1986 if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
1987 Type Ty = Src0Var->getType(); 1987 Type Ty = Src0Var->getType();
1988 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an 1988 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
1989 // acceptable type. 1989 // acceptable type.
1990 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister) 1990 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, RegNumT::NoRegister)
1991 ->emit(Func); 1991 ->emit(Func);
1992 } else { 1992 } else {
1993 Src0->emit(Func); 1993 Src0->emit(Func);
1994 } 1994 }
1995 Str << ", "; 1995 Str << ", ";
1996 this->getDest()->emit(Func); 1996 this->getDest()->emit(Func);
1997 } 1997 }
1998 1998
1999 template <typename TraitsType> 1999 template <typename TraitsType>
2000 void InstImpl<TraitsType>::InstX86Mov::emit(const Cfg *Func) const { 2000 void InstImpl<TraitsType>::InstX86Mov::emit(const Cfg *Func) const {
(...skipping 17 matching lines...) Expand all
2018 } 2018 }
2019 // For an integer truncation operation, src is wider than dest. In this case, 2019 // For an integer truncation operation, src is wider than dest. In this case,
2020 // we use a mov instruction whose data width matches the narrower dest. 2020 // we use a mov instruction whose data width matches the narrower dest.
2021 // TODO: This assert disallows usages such as copying a floating 2021 // TODO: This assert disallows usages such as copying a floating
2022 // point value between a vector and a scalar (which movss is used for). Clean 2022 // point value between a vector and a scalar (which movss is used for). Clean
2023 // this up. 2023 // this up.
2024 assert(InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(DestTy) == 2024 assert(InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(DestTy) ==
2025 InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(SrcTy)); 2025 InstX86Base::getTarget(Func)->typeWidthInBytesOnStack(SrcTy));
2026 const Operand *NewSrc = Src; 2026 const Operand *NewSrc = Src;
2027 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { 2027 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
2028 int32_t NewRegNum = Variable::NoRegister; 2028 auto NewRegNum = RegNumT::NoRegister;
2029 if (SrcVar->hasReg()) 2029 if (SrcVar->hasReg())
2030 NewRegNum = Traits::getGprForType(DestTy, SrcVar->getRegNum()); 2030 NewRegNum = Traits::getGprForType(DestTy, SrcVar->getRegNum());
2031 if (SrcTy != DestTy) 2031 if (SrcTy != DestTy)
2032 NewSrc = SrcVar->asType(DestTy, NewRegNum); 2032 NewSrc = SrcVar->asType(DestTy, NewRegNum);
2033 } 2033 }
2034 NewSrc->emit(Func); 2034 NewSrc->emit(Func);
2035 Str << ", "; 2035 Str << ", ";
2036 this->getDest()->emit(Func); 2036 this->getDest()->emit(Func);
2037 } 2037 }
2038 2038
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 Ostream &Str = Func->getContext()->getStrEmit(); 2544 Ostream &Str = Func->getContext()->getStrEmit();
2545 assert(this->getSrcSize() == 3); 2545 assert(this->getSrcSize() == 3);
2546 Str << "\t" << this->Opcode 2546 Str << "\t" << this->Opcode
2547 << Traits::TypeAttributes[this->getDest()->getType()].PackString << "\t"; 2547 << Traits::TypeAttributes[this->getDest()->getType()].PackString << "\t";
2548 this->getSrc(2)->emit(Func); 2548 this->getSrc(2)->emit(Func);
2549 Str << ", "; 2549 Str << ", ";
2550 Operand *Src1 = this->getSrc(1); 2550 Operand *Src1 = this->getSrc(1);
2551 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { 2551 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) {
2552 // If src1 is a register, it should always be r32. 2552 // If src1 is a register, it should always be r32.
2553 if (Src1Var->hasReg()) { 2553 if (Src1Var->hasReg()) {
2554 int32_t NewRegNum = Traits::getBaseReg(Src1Var->getRegNum()); 2554 const auto NewRegNum = Traits::getBaseReg(Src1Var->getRegNum());
2555 const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum); 2555 const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum);
2556 NewSrc->emit(Func); 2556 NewSrc->emit(Func);
2557 } else { 2557 } else {
2558 Src1Var->emit(Func); 2558 Src1Var->emit(Func);
2559 } 2559 }
2560 } else { 2560 } else {
2561 Src1->emit(Func); 2561 Src1->emit(Func);
2562 } 2562 }
2563 Str << ", "; 2563 Str << ", ";
2564 this->getDest()->emit(Func); 2564 this->getDest()->emit(Func);
2565 } 2565 }
2566 2566
2567 template <typename TraitsType> 2567 template <typename TraitsType>
2568 void InstImpl<TraitsType>::InstX86Pinsr::emitIAS(const Cfg *Func) const { 2568 void InstImpl<TraitsType>::InstX86Pinsr::emitIAS(const Cfg *Func) const {
2569 assert(this->getSrcSize() == 3); 2569 assert(this->getSrcSize() == 3);
2570 assert(this->getDest() == this->getSrc(0)); 2570 assert(this->getDest() == this->getSrc(0));
2571 // pinsrb and pinsrd are SSE4.1 instructions. 2571 // pinsrb and pinsrd are SSE4.1 instructions.
2572 const Operand *Src0 = this->getSrc(1); 2572 const Operand *Src0 = this->getSrc(1);
2573 Type DispatchTy = Src0->getType(); 2573 Type DispatchTy = Src0->getType();
2574 // If src1 is a register, it should always be r32 (this should fall out from 2574 // If src1 is a register, it should always be r32 (this should fall out from
2575 // the encodings for ByteRegs overlapping the encodings for r32), but we have 2575 // the encodings for ByteRegs overlapping the encodings for r32), but we have
2576 // to make sure the register allocator didn't choose an 8-bit high register 2576 // to make sure the register allocator didn't choose an 8-bit high register
2577 // like "ah". 2577 // like "ah".
2578 if (BuildDefs::asserts()) { 2578 if (BuildDefs::asserts()) {
2579 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { 2579 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
2580 if (Src0Var->hasReg()) { 2580 if (Src0Var->hasReg()) {
2581 int32_t RegNum = Src0Var->getRegNum(); 2581 const auto RegNum = Src0Var->getRegNum();
2582 int32_t BaseRegNum = Traits::getBaseReg(RegNum); 2582 const auto BaseRegNum = Traits::getBaseReg(RegNum);
2583 (void)BaseRegNum; 2583 (void)BaseRegNum;
2584 assert(Traits::getEncodedGPR(RegNum) == 2584 assert(Traits::getEncodedGPR(RegNum) ==
2585 Traits::getEncodedGPR(BaseRegNum)); 2585 Traits::getEncodedGPR(BaseRegNum));
2586 } 2586 }
2587 } 2587 }
2588 } 2588 }
2589 static const ThreeOpImmEmitter<XmmRegister, GPRRegister> Emitter = { 2589 static const ThreeOpImmEmitter<XmmRegister, GPRRegister> Emitter = {
2590 &Assembler::pinsr, &Assembler::pinsr}; 2590 &Assembler::pinsr, &Assembler::pinsr};
2591 emitIASThreeOpImmOps<XmmRegister, GPRRegister, Traits::getEncodedXmm, 2591 emitIASThreeOpImmOps<XmmRegister, GPRRegister, Traits::getEncodedXmm,
2592 Traits::getEncodedGPR>(Func, DispatchTy, this->getDest(), 2592 Traits::getEncodedGPR>(Func, DispatchTy, this->getDest(),
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
2889 return; 2889 return;
2890 Ostream &Str = Func->getContext()->getStrDump(); 2890 Ostream &Str = Func->getContext()->getStrDump();
2891 Str << "IACA_END"; 2891 Str << "IACA_END";
2892 } 2892 }
2893 2893
2894 } // end of namespace X86NAMESPACE 2894 } // end of namespace X86NAMESPACE
2895 2895
2896 } // end of namespace Ice 2896 } // end of namespace Ice
2897 2897
2898 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H 2898 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceOperand.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698