| 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 |