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 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 this->dumpDest(Func); | 615 this->dumpDest(Func); |
616 Str << " = "; | 616 Str << " = "; |
617 } | 617 } |
618 Str << "call "; | 618 Str << "call "; |
619 getCallTarget()->dump(Func); | 619 getCallTarget()->dump(Func); |
620 } | 620 } |
621 | 621 |
622 // The this->Opcode parameter needs to be char* and not IceString because of | 622 // The this->Opcode parameter needs to be char* and not IceString because of |
623 // template issues. | 623 // template issues. |
624 template <class Machine> | 624 template <class Machine> |
625 void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst, | 625 void InstX86Base<Machine>::emitTwoAddress(const Cfg *Func, const char *Opcode, |
626 const Cfg *Func) { | 626 const char *Suffix) const { |
627 if (!BuildDefs::dump()) | 627 if (!BuildDefs::dump()) |
628 return; | 628 return; |
629 Ostream &Str = Func->getContext()->getStrEmit(); | 629 Ostream &Str = Func->getContext()->getStrEmit(); |
630 assert(Inst->getSrcSize() == 2); | 630 assert(getSrcSize() == 2); |
631 Operand *Dest = Inst->getDest(); | 631 Operand *Dest = getDest(); |
632 if (Dest == nullptr) | 632 if (Dest == nullptr) |
633 Dest = Inst->getSrc(0); | 633 Dest = getSrc(0); |
634 assert(Dest == Inst->getSrc(0)); | 634 assert(Dest == getSrc(0)); |
635 Operand *Src1 = Inst->getSrc(1); | 635 Operand *Src1 = getSrc(1); |
636 Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType()) | 636 Str << "\t" << Opcode; |
637 << "\t"; | 637 if (Suffix != nullptr) |
| 638 Str << Suffix; |
| 639 Str << InstX86Base<Machine>::getWidthString(Dest->getType()) << "\t"; |
638 Src1->emit(Func); | 640 Src1->emit(Func); |
639 Str << ", "; | 641 Str << ", "; |
640 Dest->emit(Func); | 642 Dest->emit(Func); |
641 } | 643 } |
642 | 644 |
643 template <class Machine> | 645 template <class Machine> |
644 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 646 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
645 const typename InstX86Base< | 647 const typename InstX86Base< |
646 Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) { | 648 Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) { |
647 auto *Target = InstX86Base<Machine>::getTarget(Func); | 649 auto *Target = InstX86Base<Machine>::getTarget(Func); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 Type Ty = this->getSrc(0)->getType(); | 1003 Type Ty = this->getSrc(0)->getType(); |
1002 assert(isScalarFloatingType(Ty)); | 1004 assert(isScalarFloatingType(Ty)); |
1003 Str << "\t" | 1005 Str << "\t" |
1004 "sqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString | 1006 "sqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString |
1005 << "\t"; | 1007 << "\t"; |
1006 this->getSrc(0)->emit(Func); | 1008 this->getSrc(0)->emit(Func); |
1007 Str << ", "; | 1009 Str << ", "; |
1008 this->getDest()->emit(Func); | 1010 this->getDest()->emit(Func); |
1009 } | 1011 } |
1010 | 1012 |
1011 template <class Machine> | |
1012 void InstX86Addss<Machine>::emit(const Cfg *Func) const { | |
1013 if (!BuildDefs::dump()) | |
1014 return; | |
1015 char buf[30]; | |
1016 snprintf( | |
1017 buf, llvm::array_lengthof(buf), "add%s", | |
1018 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1019 .SdSsString); | |
1020 this->emitTwoAddress(buf, this, Func); | |
1021 } | |
1022 | |
1023 template <class Machine> | |
1024 void InstX86Padd<Machine>::emit(const Cfg *Func) const { | |
1025 if (!BuildDefs::dump()) | |
1026 return; | |
1027 char buf[30]; | |
1028 snprintf( | |
1029 buf, llvm::array_lengthof(buf), "padd%s", | |
1030 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1031 .PackString); | |
1032 this->emitTwoAddress(buf, this, Func); | |
1033 } | |
1034 | |
1035 template <class Machine> | |
1036 void InstX86Pmull<Machine>::emit(const Cfg *Func) const { | |
1037 if (!BuildDefs::dump()) | |
1038 return; | |
1039 char buf[30]; | |
1040 bool TypesAreValid = this->getDest()->getType() == IceType_v4i32 || | |
1041 this->getDest()->getType() == IceType_v8i16; | |
1042 auto *Target = InstX86Base<Machine>::getTarget(Func); | |
1043 bool InstructionSetIsValid = | |
1044 this->getDest()->getType() == IceType_v8i16 || | |
1045 Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1; | |
1046 (void)TypesAreValid; | |
1047 (void)InstructionSetIsValid; | |
1048 assert(TypesAreValid); | |
1049 assert(InstructionSetIsValid); | |
1050 snprintf( | |
1051 buf, llvm::array_lengthof(buf), "pmull%s", | |
1052 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1053 .PackString); | |
1054 this->emitTwoAddress(buf, this, Func); | |
1055 } | |
1056 | |
1057 template <class Machine> | |
1058 void InstX86Pmull<Machine>::emitIAS(const Cfg *Func) const { | |
1059 Type Ty = this->getDest()->getType(); | |
1060 bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16; | |
1061 auto *Target = InstX86Base<Machine>::getTarget(Func); | |
1062 bool InstructionSetIsValid = | |
1063 Ty == IceType_v8i16 || | |
1064 Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1; | |
1065 (void)TypesAreValid; | |
1066 (void)InstructionSetIsValid; | |
1067 assert(TypesAreValid); | |
1068 assert(InstructionSetIsValid); | |
1069 assert(this->getSrcSize() == 2); | |
1070 Type ElementTy = typeElementType(Ty); | |
1071 emitIASRegOpTyXMM<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1), | |
1072 this->Emitter); | |
1073 } | |
1074 | |
1075 template <class Machine> | |
1076 void InstX86Subss<Machine>::emit(const Cfg *Func) const { | |
1077 if (!BuildDefs::dump()) | |
1078 return; | |
1079 char buf[30]; | |
1080 snprintf( | |
1081 buf, llvm::array_lengthof(buf), "sub%s", | |
1082 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1083 .SdSsString); | |
1084 this->emitTwoAddress(buf, this, Func); | |
1085 } | |
1086 | |
1087 template <class Machine> | |
1088 void InstX86Psub<Machine>::emit(const Cfg *Func) const { | |
1089 if (!BuildDefs::dump()) | |
1090 return; | |
1091 char buf[30]; | |
1092 snprintf( | |
1093 buf, llvm::array_lengthof(buf), "psub%s", | |
1094 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1095 .PackString); | |
1096 this->emitTwoAddress(buf, this, Func); | |
1097 } | |
1098 | |
1099 template <class Machine> | |
1100 void InstX86Mulss<Machine>::emit(const Cfg *Func) const { | |
1101 if (!BuildDefs::dump()) | |
1102 return; | |
1103 char buf[30]; | |
1104 snprintf( | |
1105 buf, llvm::array_lengthof(buf), "mul%s", | |
1106 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1107 .SdSsString); | |
1108 this->emitTwoAddress(buf, this, Func); | |
1109 } | |
1110 | |
1111 template <class Machine> | |
1112 void InstX86Andnps<Machine>::emit(const Cfg *Func) const { | |
1113 if (!BuildDefs::dump()) | |
1114 return; | |
1115 | |
1116 char buf[30]; | |
1117 snprintf( | |
1118 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1119 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1120 .PdPsString); | |
1121 this->emitTwoAddress(buf, this, Func); | |
1122 } | |
1123 | |
1124 template <class Machine> | |
1125 void InstX86Andps<Machine>::emit(const Cfg *Func) const { | |
1126 if (!BuildDefs::dump()) | |
1127 return; | |
1128 | |
1129 char buf[30]; | |
1130 snprintf( | |
1131 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1132 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1133 .PdPsString); | |
1134 this->emitTwoAddress(buf, this, Func); | |
1135 } | |
1136 | |
1137 template <class Machine> | |
1138 void InstX86Maxss<Machine>::emit(const Cfg *Func) const { | |
1139 if (!BuildDefs::dump()) | |
1140 return; | |
1141 | |
1142 char buf[30]; | |
1143 snprintf( | |
1144 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1145 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1146 .SdSsString); | |
1147 this->emitTwoAddress(buf, this, Func); | |
1148 } | |
1149 | |
1150 template <class Machine> | |
1151 void InstX86Minss<Machine>::emit(const Cfg *Func) const { | |
1152 if (!BuildDefs::dump()) | |
1153 return; | |
1154 | |
1155 char buf[30]; | |
1156 snprintf( | |
1157 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1158 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1159 .SdSsString); | |
1160 this->emitTwoAddress(buf, this, Func); | |
1161 } | |
1162 | |
1163 template <class Machine> | |
1164 void InstX86Orps<Machine>::emit(const Cfg *Func) const { | |
1165 if (!BuildDefs::dump()) | |
1166 return; | |
1167 | |
1168 char buf[30]; | |
1169 snprintf( | |
1170 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1171 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1172 .PdPsString); | |
1173 this->emitTwoAddress(buf, this, Func); | |
1174 } | |
1175 | |
1176 template <class Machine> | |
1177 void InstX86Xorps<Machine>::emit(const Cfg *Func) const { | |
1178 if (!BuildDefs::dump()) | |
1179 return; | |
1180 | |
1181 char buf[30]; | |
1182 snprintf( | |
1183 buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, | |
1184 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1185 .PdPsString); | |
1186 this->emitTwoAddress(buf, this, Func); | |
1187 } | |
1188 | |
1189 template <class Machine> | |
1190 void InstX86Pmuludq<Machine>::emit(const Cfg *Func) const { | |
1191 if (!BuildDefs::dump()) | |
1192 return; | |
1193 assert(this->getSrc(0)->getType() == IceType_v4i32 && | |
1194 this->getSrc(1)->getType() == IceType_v4i32); | |
1195 this->emitTwoAddress(this->Opcode, this, Func); | |
1196 } | |
1197 | |
1198 template <class Machine> | |
1199 void InstX86Divss<Machine>::emit(const Cfg *Func) const { | |
1200 if (!BuildDefs::dump()) | |
1201 return; | |
1202 char buf[30]; | |
1203 snprintf( | |
1204 buf, llvm::array_lengthof(buf), "div%s", | |
1205 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
1206 .SdSsString); | |
1207 this->emitTwoAddress(buf, this, Func); | |
1208 } | |
1209 | |
1210 template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const { | 1013 template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const { |
1211 if (!BuildDefs::dump()) | 1014 if (!BuildDefs::dump()) |
1212 return; | 1015 return; |
1213 Ostream &Str = Func->getContext()->getStrEmit(); | 1016 Ostream &Str = Func->getContext()->getStrEmit(); |
1214 assert(this->getSrcSize() == 3); | 1017 assert(this->getSrcSize() == 3); |
1215 Operand *Src1 = this->getSrc(1); | 1018 Operand *Src1 = this->getSrc(1); |
1216 Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t"; | 1019 Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t"; |
1217 Src1->emit(Func); | 1020 Src1->emit(Func); |
1218 } | 1021 } |
1219 | 1022 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1276 InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0); | 1079 InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0); |
1277 const Variable *Dest = Inst->getDest(); | 1080 const Variable *Dest = Inst->getDest(); |
1278 const Operand *Src = Inst->getSrc(1); | 1081 const Operand *Src = Inst->getSrc(1); |
1279 emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter); | 1082 emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter); |
1280 } | 1083 } |
1281 | 1084 |
1282 template <class Machine> | 1085 template <class Machine> |
1283 void InstX86Blendvps<Machine>::emit(const Cfg *Func) const { | 1086 void InstX86Blendvps<Machine>::emit(const Cfg *Func) const { |
1284 if (!BuildDefs::dump()) | 1087 if (!BuildDefs::dump()) |
1285 return; | 1088 return; |
1286 assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
1287 InstX86Base<Machine>::Traits::SSE4_1); | |
1288 emitVariableBlendInst<Machine>(this->Opcode, this, Func); | 1089 emitVariableBlendInst<Machine>(this->Opcode, this, Func); |
1289 } | 1090 } |
1290 | 1091 |
1291 template <class Machine> | 1092 template <class Machine> |
1292 void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const { | 1093 void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const { |
1293 assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
1294 InstX86Base<Machine>::Traits::SSE4_1); | |
1295 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 1094 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
1296 Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps, | 1095 Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps, |
1297 &InstX86Base<Machine>::Traits::Assembler::blendvps}; | 1096 &InstX86Base<Machine>::Traits::Assembler::blendvps}; |
1298 emitIASVariableBlendInst<Machine>(this, Func, Emitter); | 1097 emitIASVariableBlendInst<Machine>(this, Func, Emitter); |
1299 } | 1098 } |
1300 | 1099 |
1301 template <class Machine> | 1100 template <class Machine> |
1302 void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const { | 1101 void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const { |
1303 if (!BuildDefs::dump()) | 1102 if (!BuildDefs::dump()) |
1304 return; | 1103 return; |
1305 assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
1306 InstX86Base<Machine>::Traits::SSE4_1); | |
1307 emitVariableBlendInst<Machine>(this->Opcode, this, Func); | 1104 emitVariableBlendInst<Machine>(this->Opcode, this, Func); |
1308 } | 1105 } |
1309 | 1106 |
1310 template <class Machine> | 1107 template <class Machine> |
1311 void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const { | 1108 void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const { |
1312 assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
1313 InstX86Base<Machine>::Traits::SSE4_1); | |
1314 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp | 1109 static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp |
1315 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb, | 1110 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb, |
1316 &InstX86Base<Machine>::Traits::Assembler::pblendvb}; | 1111 &InstX86Base<Machine>::Traits::Assembler::pblendvb}; |
1317 emitIASVariableBlendInst<Machine>(this, Func, Emitter); | 1112 emitIASVariableBlendInst<Machine>(this, Func, Emitter); |
1318 } | 1113 } |
1319 | 1114 |
1320 template <class Machine> | 1115 template <class Machine> |
1321 void InstX86Imul<Machine>::emit(const Cfg *Func) const { | 1116 void InstX86Imul<Machine>::emit(const Cfg *Func) const { |
1322 if (!BuildDefs::dump()) | 1117 if (!BuildDefs::dump()) |
1323 return; | 1118 return; |
(...skipping 11 matching lines...) Expand all Loading... |
1335 this->getSrc(1)->emit(Func); | 1130 this->getSrc(1)->emit(Func); |
1336 } else if (llvm::isa<Constant>(this->getSrc(1))) { | 1131 } else if (llvm::isa<Constant>(this->getSrc(1))) { |
1337 Str << "\t" | 1132 Str << "\t" |
1338 "imul" << this->getWidthString(Dest->getType()) << "\t"; | 1133 "imul" << this->getWidthString(Dest->getType()) << "\t"; |
1339 this->getSrc(1)->emit(Func); | 1134 this->getSrc(1)->emit(Func); |
1340 Str << ", "; | 1135 Str << ", "; |
1341 this->getSrc(0)->emit(Func); | 1136 this->getSrc(0)->emit(Func); |
1342 Str << ", "; | 1137 Str << ", "; |
1343 Dest->emit(Func); | 1138 Dest->emit(Func); |
1344 } else { | 1139 } else { |
1345 this->emitTwoAddress("imul", this, Func); | 1140 this->emitTwoAddress(Func, this->Opcode); |
1346 } | 1141 } |
1347 } | 1142 } |
1348 | 1143 |
1349 template <class Machine> | 1144 template <class Machine> |
1350 void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const { | 1145 void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const { |
1351 assert(this->getSrcSize() == 2); | 1146 assert(this->getSrcSize() == 2); |
1352 const Variable *Var = this->getDest(); | 1147 const Variable *Var = this->getDest(); |
1353 Type Ty = Var->getType(); | 1148 Type Ty = Var->getType(); |
1354 const Operand *Src = this->getSrc(1); | 1149 const Operand *Src = this->getSrc(1); |
1355 if (isByteSizedArithType(Ty)) { | 1150 if (isByteSizedArithType(Ty)) { |
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2784 template <class Machine> | 2579 template <class Machine> |
2785 void InstX86Fstp<Machine>::dump(const Cfg *Func) const { | 2580 void InstX86Fstp<Machine>::dump(const Cfg *Func) const { |
2786 if (!BuildDefs::dump()) | 2581 if (!BuildDefs::dump()) |
2787 return; | 2582 return; |
2788 Ostream &Str = Func->getContext()->getStrDump(); | 2583 Ostream &Str = Func->getContext()->getStrDump(); |
2789 this->dumpDest(Func); | 2584 this->dumpDest(Func); |
2790 Str << " = fstp." << this->getDest()->getType() << ", st(0)"; | 2585 Str << " = fstp." << this->getDest()->getType() << ", st(0)"; |
2791 } | 2586 } |
2792 | 2587 |
2793 template <class Machine> | 2588 template <class Machine> |
2794 void InstX86Pcmpeq<Machine>::emit(const Cfg *Func) const { | |
2795 if (!BuildDefs::dump()) | |
2796 return; | |
2797 char buf[30]; | |
2798 snprintf( | |
2799 buf, llvm::array_lengthof(buf), "pcmpeq%s", | |
2800 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
2801 .PackString); | |
2802 this->emitTwoAddress(buf, this, Func); | |
2803 } | |
2804 | |
2805 template <class Machine> | |
2806 void InstX86Pcmpgt<Machine>::emit(const Cfg *Func) const { | |
2807 if (!BuildDefs::dump()) | |
2808 return; | |
2809 char buf[30]; | |
2810 snprintf( | |
2811 buf, llvm::array_lengthof(buf), "pcmpgt%s", | |
2812 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
2813 .PackString); | |
2814 this->emitTwoAddress(buf, this, Func); | |
2815 } | |
2816 | |
2817 template <class Machine> | |
2818 void InstX86Pextr<Machine>::emit(const Cfg *Func) const { | 2589 void InstX86Pextr<Machine>::emit(const Cfg *Func) const { |
2819 if (!BuildDefs::dump()) | 2590 if (!BuildDefs::dump()) |
2820 return; | 2591 return; |
2821 Ostream &Str = Func->getContext()->getStrEmit(); | 2592 Ostream &Str = Func->getContext()->getStrEmit(); |
2822 assert(this->getSrcSize() == 2); | 2593 assert(this->getSrcSize() == 2); |
2823 // pextrb and pextrd are SSE4.1 instructions. | 2594 // pextrb and pextrd are SSE4.1 instructions. |
2824 assert(this->getSrc(0)->getType() == IceType_v8i16 || | |
2825 this->getSrc(0)->getType() == IceType_v8i1 || | |
2826 InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
2827 InstX86Base<Machine>::Traits::SSE4_1); | |
2828 Str << "\t" << this->Opcode | 2595 Str << "\t" << this->Opcode |
2829 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) | 2596 << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) |
2830 ->getType()] | 2597 ->getType()] |
2831 .PackString << "\t"; | 2598 .PackString << "\t"; |
2832 this->getSrc(1)->emit(Func); | 2599 this->getSrc(1)->emit(Func); |
2833 Str << ", "; | 2600 Str << ", "; |
2834 this->getSrc(0)->emit(Func); | 2601 this->getSrc(0)->emit(Func); |
2835 Str << ", "; | 2602 Str << ", "; |
2836 Variable *Dest = this->getDest(); | 2603 Variable *Dest = this->getDest(); |
2837 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2604 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
2838 // memory dest, but we aren't using it. For uniformity, just restrict them | 2605 // memory dest, but we aren't using it. For uniformity, just restrict them |
2839 // all to have a register dest for now. | 2606 // all to have a register dest for now. |
2840 assert(Dest->hasReg()); | 2607 assert(Dest->hasReg()); |
2841 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); | 2608 Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func); |
2842 } | 2609 } |
2843 | 2610 |
2844 template <class Machine> | 2611 template <class Machine> |
2845 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { | 2612 void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const { |
2846 assert(this->getSrcSize() == 2); | 2613 assert(this->getSrcSize() == 2); |
2847 // pextrb and pextrd are SSE4.1 instructions. | 2614 // pextrb and pextrd are SSE4.1 instructions. |
2848 const Variable *Dest = this->getDest(); | 2615 const Variable *Dest = this->getDest(); |
2849 Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( | 2616 Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( |
2850 this->getSrc(0)->getType()); | 2617 this->getSrc(0)->getType()); |
2851 assert(DispatchTy == IceType_i16 || | |
2852 InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
2853 InstX86Base<Machine>::Traits::SSE4_1); | |
2854 // pextrw must take a register dest. There is an SSE4.1 version that takes a | 2618 // pextrw must take a register dest. There is an SSE4.1 version that takes a |
2855 // memory dest, but we aren't using it. For uniformity, just restrict them | 2619 // memory dest, but we aren't using it. For uniformity, just restrict them |
2856 // all to have a register dest for now. | 2620 // all to have a register dest for now. |
2857 assert(Dest->hasReg()); | 2621 assert(Dest->hasReg()); |
2858 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2622 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
2859 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); | 2623 assert(llvm::cast<Variable>(this->getSrc(0))->hasReg()); |
2860 static const typename InstX86Base<Machine>::Traits::Assembler:: | 2624 static const typename InstX86Base<Machine>::Traits::Assembler:: |
2861 template ThreeOpImmEmitter< | 2625 template ThreeOpImmEmitter< |
2862 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 2626 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
2863 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 2627 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
2864 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr}; | 2628 Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr}; |
2865 emitIASThreeOpImmOps< | 2629 emitIASThreeOpImmOps< |
2866 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 2630 Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
2867 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 2631 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
2868 InstX86Base<Machine>::Traits::getEncodedGPR, | 2632 InstX86Base<Machine>::Traits::getEncodedGPR, |
2869 InstX86Base<Machine>::Traits::getEncodedXmm>( | 2633 InstX86Base<Machine>::Traits::getEncodedXmm>( |
2870 Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter); | 2634 Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter); |
2871 } | 2635 } |
2872 | 2636 |
2873 template <class Machine> | 2637 template <class Machine> |
2874 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { | 2638 void InstX86Pinsr<Machine>::emit(const Cfg *Func) const { |
2875 if (!BuildDefs::dump()) | 2639 if (!BuildDefs::dump()) |
2876 return; | 2640 return; |
2877 Ostream &Str = Func->getContext()->getStrEmit(); | 2641 Ostream &Str = Func->getContext()->getStrEmit(); |
2878 assert(this->getSrcSize() == 3); | 2642 assert(this->getSrcSize() == 3); |
2879 // pinsrb and pinsrd are SSE4.1 instructions. | |
2880 assert(this->getDest()->getType() == IceType_v8i16 || | |
2881 this->getDest()->getType() == IceType_v8i1 || | |
2882 InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
2883 InstX86Base<Machine>::Traits::SSE4_1); | |
2884 Str << "\t" << this->Opcode | 2643 Str << "\t" << this->Opcode |
2885 << InstX86Base< | 2644 << InstX86Base< |
2886 Machine>::Traits::TypeAttributes[this->getDest()->getType()] | 2645 Machine>::Traits::TypeAttributes[this->getDest()->getType()] |
2887 .PackString << "\t"; | 2646 .PackString << "\t"; |
2888 this->getSrc(2)->emit(Func); | 2647 this->getSrc(2)->emit(Func); |
2889 Str << ", "; | 2648 Str << ", "; |
2890 Operand *Src1 = this->getSrc(1); | 2649 Operand *Src1 = this->getSrc(1); |
2891 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { | 2650 if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) { |
2892 // If src1 is a register, it should always be r32. | 2651 // If src1 is a register, it should always be r32. |
2893 if (Src1Var->hasReg()) { | 2652 if (Src1Var->hasReg()) { |
(...skipping 11 matching lines...) Expand all Loading... |
2905 this->getDest()->emit(Func); | 2664 this->getDest()->emit(Func); |
2906 } | 2665 } |
2907 | 2666 |
2908 template <class Machine> | 2667 template <class Machine> |
2909 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { | 2668 void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const { |
2910 assert(this->getSrcSize() == 3); | 2669 assert(this->getSrcSize() == 3); |
2911 assert(this->getDest() == this->getSrc(0)); | 2670 assert(this->getDest() == this->getSrc(0)); |
2912 // pinsrb and pinsrd are SSE4.1 instructions. | 2671 // pinsrb and pinsrd are SSE4.1 instructions. |
2913 const Operand *Src0 = this->getSrc(1); | 2672 const Operand *Src0 = this->getSrc(1); |
2914 Type DispatchTy = Src0->getType(); | 2673 Type DispatchTy = Src0->getType(); |
2915 assert(DispatchTy == IceType_i16 || | |
2916 InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= | |
2917 InstX86Base<Machine>::Traits::SSE4_1); | |
2918 // If src1 is a register, it should always be r32 (this should fall out from | 2674 // If src1 is a register, it should always be r32 (this should fall out from |
2919 // the encodings for ByteRegs overlapping the encodings for r32), but we have | 2675 // the encodings for ByteRegs overlapping the encodings for r32), but we have |
2920 // to make sure the register allocator didn't choose an 8-bit high register | 2676 // to make sure the register allocator didn't choose an 8-bit high register |
2921 // like "ah". | 2677 // like "ah". |
2922 if (BuildDefs::asserts()) { | 2678 if (BuildDefs::asserts()) { |
2923 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2679 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
2924 if (Src0Var->hasReg()) { | 2680 if (Src0Var->hasReg()) { |
2925 int32_t RegNum = Src0Var->getRegNum(); | 2681 int32_t RegNum = Src0Var->getRegNum(); |
2926 int32_t BaseRegNum = InstX86Base<Machine>::Traits::getBaseReg(RegNum); | 2682 int32_t BaseRegNum = InstX86Base<Machine>::Traits::getBaseReg(RegNum); |
2927 (void)BaseRegNum; | 2683 (void)BaseRegNum; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 | 2798 |
3043 template <class Machine> | 2799 template <class Machine> |
3044 void InstX86Push<Machine>::dump(const Cfg *Func) const { | 2800 void InstX86Push<Machine>::dump(const Cfg *Func) const { |
3045 if (!BuildDefs::dump()) | 2801 if (!BuildDefs::dump()) |
3046 return; | 2802 return; |
3047 Ostream &Str = Func->getContext()->getStrDump(); | 2803 Ostream &Str = Func->getContext()->getStrDump(); |
3048 Str << "push." << this->getSrc(0)->getType() << " "; | 2804 Str << "push." << this->getSrc(0)->getType() << " "; |
3049 this->dumpSources(Func); | 2805 this->dumpSources(Func); |
3050 } | 2806 } |
3051 | 2807 |
3052 template <class Machine> | |
3053 void InstX86Psll<Machine>::emit(const Cfg *Func) const { | |
3054 if (!BuildDefs::dump()) | |
3055 return; | |
3056 assert(this->getDest()->getType() == IceType_v8i16 || | |
3057 this->getDest()->getType() == IceType_v8i1 || | |
3058 this->getDest()->getType() == IceType_v4i32 || | |
3059 this->getDest()->getType() == IceType_v4i1); | |
3060 char buf[30]; | |
3061 snprintf( | |
3062 buf, llvm::array_lengthof(buf), "psll%s", | |
3063 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
3064 .PackString); | |
3065 this->emitTwoAddress(buf, this, Func); | |
3066 } | |
3067 | |
3068 template <class Machine> | |
3069 void InstX86Psra<Machine>::emit(const Cfg *Func) const { | |
3070 if (!BuildDefs::dump()) | |
3071 return; | |
3072 assert(this->getDest()->getType() == IceType_v8i16 || | |
3073 this->getDest()->getType() == IceType_v8i1 || | |
3074 this->getDest()->getType() == IceType_v4i32 || | |
3075 this->getDest()->getType() == IceType_v4i1); | |
3076 char buf[30]; | |
3077 snprintf( | |
3078 buf, llvm::array_lengthof(buf), "psra%s", | |
3079 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
3080 .PackString); | |
3081 this->emitTwoAddress(buf, this, Func); | |
3082 } | |
3083 | |
3084 template <class Machine> | |
3085 void InstX86Psrl<Machine>::emit(const Cfg *Func) const { | |
3086 if (!BuildDefs::dump()) | |
3087 return; | |
3088 char buf[30]; | |
3089 snprintf( | |
3090 buf, llvm::array_lengthof(buf), "psrl%s", | |
3091 InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] | |
3092 .PackString); | |
3093 this->emitTwoAddress(buf, this, Func); | |
3094 } | |
3095 | |
3096 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { | 2808 template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { |
3097 if (!BuildDefs::dump()) | 2809 if (!BuildDefs::dump()) |
3098 return; | 2810 return; |
3099 Ostream &Str = Func->getContext()->getStrEmit(); | 2811 Ostream &Str = Func->getContext()->getStrEmit(); |
3100 Str << "\t" | 2812 Str << "\t" |
3101 "ret"; | 2813 "ret"; |
3102 } | 2814 } |
3103 | 2815 |
3104 template <class Machine> | 2816 template <class Machine> |
3105 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { | 2817 void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const { |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3311 return; | 3023 return; |
3312 Ostream &Str = Func->getContext()->getStrDump(); | 3024 Ostream &Str = Func->getContext()->getStrDump(); |
3313 Str << "IACA_END"; | 3025 Str << "IACA_END"; |
3314 } | 3026 } |
3315 | 3027 |
3316 } // end of namespace X86Internal | 3028 } // end of namespace X86Internal |
3317 | 3029 |
3318 } // end of namespace Ice | 3030 } // end of namespace Ice |
3319 | 3031 |
3320 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3032 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
OLD | NEW |