| OLD | NEW |
| 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 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 const Variable *Dest = Inst->getDest(); | 1230 const Variable *Dest = Inst->getDest(); |
| 1231 const Operand *Src = Inst->getSrc(1); | 1231 const Operand *Src = Inst->getSrc(1); |
| 1232 emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter); | 1232 emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter); |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 template <class Machine> | 1235 template <class Machine> |
| 1236 void InstX86Blendvps<Machine>::emit(const Cfg *Func) const { | 1236 void InstX86Blendvps<Machine>::emit(const Cfg *Func) const { |
| 1237 if (!BuildDefs::dump()) | 1237 if (!BuildDefs::dump()) |
| 1238 return; | 1238 return; |
| 1239 TargetLowering *Target = Func->getTarget(); | 1239 TargetLowering *Target = Func->getTarget(); |
| 1240 (void)Target; |
| 1240 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1241 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1241 Target) | 1242 Target) |
| 1242 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1243 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1243 emitVariableBlendInst<Machine>(this->Opcode, this, Func); | 1244 emitVariableBlendInst<Machine>(this->Opcode, this, Func); |
| 1244 } | 1245 } |
| 1245 | 1246 |
| 1246 template <class Machine> | 1247 template <class Machine> |
| 1247 void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const { | 1248 void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const { |
| 1248 TargetLowering *Target = Func->getTarget(); | 1249 TargetLowering *Target = Func->getTarget(); |
| 1250 (void)Target; |
| 1249 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1251 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1250 Target) | 1252 Target) |
| 1251 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1253 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1252 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 1254 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
| 1253 Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps, | 1255 Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps, |
| 1254 &InstX86Base<Machine>::Traits::Assembler::blendvps}; | 1256 &InstX86Base<Machine>::Traits::Assembler::blendvps}; |
| 1255 emitIASVariableBlendInst<Machine>(this, Func, Emitter); | 1257 emitIASVariableBlendInst<Machine>(this, Func, Emitter); |
| 1256 } | 1258 } |
| 1257 | 1259 |
| 1258 template <class Machine> | 1260 template <class Machine> |
| 1259 void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const { | 1261 void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const { |
| 1260 if (!BuildDefs::dump()) | 1262 if (!BuildDefs::dump()) |
| 1261 return; | 1263 return; |
| 1262 TargetLowering *Target = Func->getTarget(); | 1264 TargetLowering *Target = Func->getTarget(); |
| 1265 (void)Target; |
| 1263 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1266 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1264 Target) | 1267 Target) |
| 1265 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1268 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1266 emitVariableBlendInst<Machine>(this->Opcode, this, Func); | 1269 emitVariableBlendInst<Machine>(this->Opcode, this, Func); |
| 1267 } | 1270 } |
| 1268 | 1271 |
| 1269 template <class Machine> | 1272 template <class Machine> |
| 1270 void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const { | 1273 void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const { |
| 1271 TargetLowering *Target = Func->getTarget(); | 1274 TargetLowering *Target = Func->getTarget(); |
| 1275 (void)Target; |
| 1272 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1276 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1273 Target) | 1277 Target) |
| 1274 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1278 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1275 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 1279 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
| 1276 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb, | 1280 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb, |
| 1277 &InstX86Base<Machine>::Traits::Assembler::pblendvb}; | 1281 &InstX86Base<Machine>::Traits::Assembler::pblendvb}; |
| 1278 emitIASVariableBlendInst<Machine>(this, Func, Emitter); | 1282 emitIASVariableBlendInst<Machine>(this, Func, Emitter); |
| 1279 } | 1283 } |
| 1280 | 1284 |
| 1281 template <class Machine> | 1285 template <class Machine> |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1373 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1370 InstX86Base<Machine>::Traits::getEncodedGPR, | 1374 InstX86Base<Machine>::Traits::getEncodedGPR, |
| 1371 InstX86Base<Machine>::Traits::getEncodedGPR>( | 1375 InstX86Base<Machine>::Traits::getEncodedGPR>( |
| 1372 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); | 1376 Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter); |
| 1373 } | 1377 } |
| 1374 | 1378 |
| 1375 template <class Machine> | 1379 template <class Machine> |
| 1376 void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const { | 1380 void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const { |
| 1377 assert(this->getSrcSize() == 3); | 1381 assert(this->getSrcSize() == 3); |
| 1378 TargetLowering *Target = Func->getTarget(); | 1382 TargetLowering *Target = Func->getTarget(); |
| 1383 (void)Target; |
| 1379 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 1384 assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 1380 Target) | 1385 Target) |
| 1381 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 1386 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 1382 const Variable *Dest = this->getDest(); | 1387 const Variable *Dest = this->getDest(); |
| 1383 assert(Dest == this->getSrc(0)); | 1388 assert(Dest == this->getSrc(0)); |
| 1384 Type Ty = Dest->getType(); | 1389 Type Ty = Dest->getType(); |
| 1385 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1390 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1386 template ThreeOpImmEmitter< | 1391 template ThreeOpImmEmitter< |
| 1387 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1392 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1388 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 1393 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2301 ? this->getWidthString(DestTy) | 2306 ? this->getWidthString(DestTy) |
| 2302 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] | 2307 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| 2303 .SdSsString) << "\t"; | 2308 .SdSsString) << "\t"; |
| 2304 } | 2309 } |
| 2305 // For an integer truncation operation, src is wider than dest. In this case, | 2310 // For an integer truncation operation, src is wider than dest. In this case, |
| 2306 // we use a mov instruction whose data width matches the narrower dest. | 2311 // we use a mov instruction whose data width matches the narrower dest. |
| 2307 // TODO: This assert disallows usages such as copying a floating | 2312 // TODO: This assert disallows usages such as copying a floating |
| 2308 // point value between a vector and a scalar (which movss is used for). Clean | 2313 // point value between a vector and a scalar (which movss is used for). Clean |
| 2309 // this up. | 2314 // this up. |
| 2310 TargetLowering *Target = Func->getTarget(); | 2315 TargetLowering *Target = Func->getTarget(); |
| 2316 (void)Target; |
| 2311 assert(Target->typeWidthInBytesOnStack(DestTy) == | 2317 assert(Target->typeWidthInBytesOnStack(DestTy) == |
| 2312 Target->typeWidthInBytesOnStack(SrcTy)); | 2318 Target->typeWidthInBytesOnStack(SrcTy)); |
| 2313 const Operand *NewSrc = Src; | 2319 const Operand *NewSrc = Src; |
| 2314 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 2320 if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 2315 int32_t NewRegNum = Variable::NoRegister; | 2321 int32_t NewRegNum = Variable::NoRegister; |
| 2316 if (SrcVar->hasReg()) | 2322 if (SrcVar->hasReg()) |
| 2317 NewRegNum = InstX86Base<Machine>::Traits::getGprForType( | 2323 NewRegNum = InstX86Base<Machine>::Traits::getGprForType( |
| 2318 DestTy, SrcVar->getRegNum()); | 2324 DestTy, SrcVar->getRegNum()); |
| 2319 if (SrcTy != DestTy) | 2325 if (SrcTy != DestTy) |
| 2320 NewSrc = SrcVar->asType(DestTy, NewRegNum); | 2326 NewSrc = SrcVar->asType(DestTy, NewRegNum); |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2779 } | 2785 } |
| 2780 | 2786 |
| 2781 template <class Machine> | 2787 template <class Machine> |
| 2782 void InstX86Pextr<Machine>::emit(const Cfg *Func) const { | 2788 void InstX86Pextr<Machine>::emit(const Cfg *Func) const { |
| 2783 if (!BuildDefs::dump()) | 2789 if (!BuildDefs::dump()) |
| 2784 return; | 2790 return; |
| 2785 Ostream &Str = Func->getContext()->getStrEmit(); | 2791 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2786 assert(this->getSrcSize() == 2); | 2792 assert(this->getSrcSize() == 2); |
| 2787 // pextrb and pextrd are SSE4.1 instructions. | 2793 // pextrb and pextrd are SSE4.1 instructions. |
| 2788 TargetLowering *Target = Func->getTarget(); | 2794 TargetLowering *Target = Func->getTarget(); |
| 2795 (void)Target; |
| 2789 assert(this->getSrc(0)->getType() == IceType_v8i16 || | 2796 assert(this->getSrc(0)->getType() == IceType_v8i16 || |
| 2790 this->getSrc(0)->getType() == IceType_v8i1 || | 2797 this->getSrc(0)->getType() == IceType_v8i1 || |
| 2791 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2798 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2792 Target) | 2799 Target) |
| 2793 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2800 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2794 Str << "\t" << this->Opcode | 2801 Str << "\t" << this->Opcode |
| 2795 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 2802 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
| 2796 ->getType()] | 2803 ->getType()] |
| 2797 .PackString << "\t"; | 2804 .PackString << "\t"; |
| 2798 this->getSrc(1)->emit(Func); | 2805 this->getSrc(1)->emit(Func); |
| 2799 Str << ", "; | 2806 Str << ", "; |
| 2800 this->getSrc(0)->emit(Func); | 2807 this->getSrc(0)->emit(Func); |
| 2801 Str << ", "; | 2808 Str << ", "; |
| 2802 Variable *Dest = this->getDest(); | 2809 Variable *Dest = this->getDest(); |
| 2803 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2810 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
| 2804 // memory dest, but we aren't using it. For uniformity, just restrict them | 2811 // memory dest, but we aren't using it. For uniformity, just restrict them |
| 2805 // all to have a register dest for now. | 2812 // all to have a register dest for now. |
| 2806 assert(Dest->hasReg()); | 2813 assert(Dest->hasReg()); |
| 2807 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); | 2814 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); |
| 2808 } | 2815 } |
| 2809 | 2816 |
| 2810 template <class Machine> | 2817 template <class Machine> |
| 2811 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { | 2818 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { |
| 2812 assert(this->getSrcSize() == 2); | 2819 assert(this->getSrcSize() == 2); |
| 2813 // pextrb and pextrd are SSE4.1 instructions. | 2820 // pextrb and pextrd are SSE4.1 instructions. |
| 2814 const Variable *Dest = this->getDest(); | 2821 const Variable *Dest = this->getDest(); |
| 2815 Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( | 2822 Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( |
| 2816 this->getSrc(0)->getType()); | 2823 this->getSrc(0)->getType()); |
| 2817 TargetLowering *Target = Func->getTarget(); | 2824 TargetLowering *Target = Func->getTarget(); |
| 2825 (void)Target; |
| 2818 assert(DispatchTy == IceType_i16 || | 2826 assert(DispatchTy == IceType_i16 || |
| 2819 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2827 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2820 Target) | 2828 Target) |
| 2821 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2829 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2822 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2830 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
| 2823 // memory dest, but we aren't using it. For uniformity, just restrict them | 2831 // memory dest, but we aren't using it. For uniformity, just restrict them |
| 2824 // all to have a register dest for now. | 2832 // all to have a register dest for now. |
| 2825 assert(Dest->hasReg()); | 2833 assert(Dest->hasReg()); |
| 2826 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2834 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
| 2827 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); | 2835 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2839 } | 2847 } |
| 2840 | 2848 |
| 2841 template <class Machine> | 2849 template <class Machine> |
| 2842 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { | 2850 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { |
| 2843 if (!BuildDefs::dump()) | 2851 if (!BuildDefs::dump()) |
| 2844 return; | 2852 return; |
| 2845 Ostream &Str = Func->getContext()->getStrEmit(); | 2853 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2846 assert(this->getSrcSize() == 3); | 2854 assert(this->getSrcSize() == 3); |
| 2847 // pinsrb and pinsrd are SSE4.1 instructions. | 2855 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2848 TargetLowering *Target = Func->getTarget(); | 2856 TargetLowering *Target = Func->getTarget(); |
| 2857 (void)Target; |
| 2849 assert(this->getDest()->getType() == IceType_v8i16 || | 2858 assert(this->getDest()->getType() == IceType_v8i16 || |
| 2850 this->getDest()->getType() == IceType_v8i1 || | 2859 this->getDest()->getType() == IceType_v8i1 || |
| 2851 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2860 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2852 Target) | 2861 Target) |
| 2853 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2862 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2854 Str << "\t" << this->Opcode | 2863 Str << "\t" << this->Opcode |
| 2855 << InstX86Base< | 2864 << InstX86Base< |
| 2856 Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 2865 Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
| 2857 .PackString << "\t"; | 2866 .PackString << "\t"; |
| 2858 this->getSrc(2)->emit(Func); | 2867 this->getSrc(2)->emit(Func); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2876 } | 2885 } |
| 2877 | 2886 |
| 2878 template <class Machine> | 2887 template <class Machine> |
| 2879 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { | 2888 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { |
| 2880 assert(this->getSrcSize() == 3); | 2889 assert(this->getSrcSize() == 3); |
| 2881 assert(this->getDest() == this->getSrc(0)); | 2890 assert(this->getDest() == this->getSrc(0)); |
| 2882 // pinsrb and pinsrd are SSE4.1 instructions. | 2891 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2883 const Operand *Src0 = this->getSrc(1); | 2892 const Operand *Src0 = this->getSrc(1); |
| 2884 Type DispatchTy = Src0->getType(); | 2893 Type DispatchTy = Src0->getType(); |
| 2885 TargetLowering *Target = Func->getTarget(); | 2894 TargetLowering *Target = Func->getTarget(); |
| 2895 (void)Target; |
| 2886 assert(DispatchTy == IceType_i16 || | 2896 assert(DispatchTy == IceType_i16 || |
| 2887 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2897 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2888 Target) | 2898 Target) |
| 2889 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); | 2899 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1); |
| 2890 // If src1 is a register, it should always be r32 (this should fall out from | 2900 // If src1 is a register, it should always be r32 (this should fall out from |
| 2891 // the encodings for ByteRegs overlapping the encodings for r32), but we have | 2901 // the encodings for ByteRegs overlapping the encodings for r32), but we have |
| 2892 // to make sure the register allocator didn't choose an 8-bit high register | 2902 // to make sure the register allocator didn't choose an 8-bit high register |
| 2893 // like "ah". | 2903 // like "ah". |
| 2894 if (BuildDefs::asserts()) { | 2904 if (BuildDefs::asserts()) { |
| 2895 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2905 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3310 return; | 3320 return; |
| 3311 Ostream &Str = Func->getContext()->getStrDump(); | 3321 Ostream &Str = Func->getContext()->getStrDump(); |
| 3312 Str << "IACA_END"; | 3322 Str << "IACA_END"; |
| 3313 } | 3323 } |
| 3314 | 3324 |
| 3315 } // end of namespace X86Internal | 3325 } // end of namespace X86Internal |
| 3316 | 3326 |
| 3317 } // end of namespace Ice | 3327 } // end of namespace Ice |
| 3318 | 3328 |
| 3319 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3329 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |