| OLD | NEW | 
|---|
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 
| 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 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, | 
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 403 } // end of anonymous namespace | 403 } // end of anonymous namespace | 
| 404 | 404 | 
| 405 void InstX8632::dump(const Cfg *Func) const { | 405 void InstX8632::dump(const Cfg *Func) const { | 
| 406   Ostream &Str = Func->getContext()->getStrDump(); | 406   Ostream &Str = Func->getContext()->getStrDump(); | 
| 407   Str << "[X8632] "; | 407   Str << "[X8632] "; | 
| 408   Inst::dump(Func); | 408   Inst::dump(Func); | 
| 409 } | 409 } | 
| 410 | 410 | 
| 411 void InstX8632Label::emit(const Cfg *Func) const { | 411 void InstX8632Label::emit(const Cfg *Func) const { | 
| 412   Ostream &Str = Func->getContext()->getStrEmit(); | 412   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 413   Str << getName(Func) << ":\n"; | 413   Str << getName(Func) << ":"; | 
| 414 } | 414 } | 
| 415 | 415 | 
| 416 void InstX8632Label::emitIAS(const Cfg *Func) const { | 416 void InstX8632Label::emitIAS(const Cfg *Func) const { | 
| 417   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 417   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 418   Asm->BindLocalLabel(Number); | 418   Asm->BindLocalLabel(Number); | 
| 419   // TODO(jvoung): remove the the textual label once forward branch | 419   // TODO(jvoung): remove the the textual label once forward branch | 
| 420   // fixups are used (and text assembler is not used). | 420   // fixups are used (and text assembler is not used). | 
| 421   Ostream &Str = Func->getContext()->getStrEmit(); | 421   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 422   Str << getName(Func) << ":\n"; | 422   Str << getName(Func) << ":\n"; | 
| 423 } | 423 } | 
| 424 | 424 | 
| 425 void InstX8632Label::dump(const Cfg *Func) const { | 425 void InstX8632Label::dump(const Cfg *Func) const { | 
| 426   Ostream &Str = Func->getContext()->getStrDump(); | 426   Ostream &Str = Func->getContext()->getStrDump(); | 
| 427   Str << getName(Func) << ":"; | 427   Str << getName(Func) << ":"; | 
| 428 } | 428 } | 
| 429 | 429 | 
| 430 void InstX8632Br::emit(const Cfg *Func) const { | 430 void InstX8632Br::emit(const Cfg *Func) const { | 
| 431   Ostream &Str = Func->getContext()->getStrEmit(); | 431   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 432   Str << "\t"; | 432   Str << "\t"; | 
| 433 | 433 | 
| 434   if (Condition == CondX86::Br_None) { | 434   if (Condition == CondX86::Br_None) { | 
| 435     Str << "jmp"; | 435     Str << "jmp"; | 
| 436   } else { | 436   } else { | 
| 437     Str << InstX8632BrAttributes[Condition].EmitString; | 437     Str << InstX8632BrAttributes[Condition].EmitString; | 
| 438   } | 438   } | 
| 439 | 439 | 
| 440   if (Label) { | 440   if (Label) { | 
| 441     Str << "\t" << Label->getName(Func) << "\n"; | 441     Str << "\t" << Label->getName(Func); | 
| 442   } else { | 442   } else { | 
| 443     if (Condition == CondX86::Br_None) { | 443     if (Condition == CondX86::Br_None) { | 
| 444       Str << "\t" << getTargetFalse()->getAsmName() << "\n"; | 444       Str << "\t" << getTargetFalse()->getAsmName(); | 
| 445     } else { | 445     } else { | 
| 446       Str << "\t" << getTargetTrue()->getAsmName() << "\n"; | 446       Str << "\t" << getTargetTrue()->getAsmName(); | 
| 447       if (getTargetFalse()) { | 447       if (getTargetFalse()) { | 
| 448         Str << "\tjmp\t" << getTargetFalse()->getAsmName() << "\n"; | 448         Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); | 
| 449       } | 449       } | 
| 450     } | 450     } | 
| 451   } | 451   } | 
| 452 } | 452 } | 
| 453 | 453 | 
| 454 void InstX8632Br::emitIAS(const Cfg *Func) const { | 454 void InstX8632Br::emitIAS(const Cfg *Func) const { | 
| 455   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 455   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 456   intptr_t StartPosition = Asm->GetPosition(); | 456   intptr_t StartPosition = Asm->GetPosition(); | 
| 457   if (Label) { | 457   if (Label) { | 
| 458     x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); | 458     x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 511       Str << ", label %" << getTargetFalse()->getName(); | 511       Str << ", label %" << getTargetFalse()->getName(); | 
| 512     } | 512     } | 
| 513   } | 513   } | 
| 514 } | 514 } | 
| 515 | 515 | 
| 516 void InstX8632Call::emit(const Cfg *Func) const { | 516 void InstX8632Call::emit(const Cfg *Func) const { | 
| 517   Ostream &Str = Func->getContext()->getStrEmit(); | 517   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 518   assert(getSrcSize() == 1); | 518   assert(getSrcSize() == 1); | 
| 519   Str << "\tcall\t"; | 519   Str << "\tcall\t"; | 
| 520   getCallTarget()->emit(Func); | 520   getCallTarget()->emit(Func); | 
| 521   Str << "\n"; |  | 
| 522   Func->getTarget()->resetStackAdjustment(); | 521   Func->getTarget()->resetStackAdjustment(); | 
| 523 } | 522 } | 
| 524 | 523 | 
| 525 void InstX8632Call::emitIAS(const Cfg *Func) const { | 524 void InstX8632Call::emitIAS(const Cfg *Func) const { | 
| 526   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 525   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 527   intptr_t StartPosition = Asm->GetPosition(); | 526   intptr_t StartPosition = Asm->GetPosition(); | 
| 528   Operand *Target = getCallTarget(); | 527   Operand *Target = getCallTarget(); | 
| 529   bool NeedsFallback = false; | 528   bool NeedsFallback = false; | 
| 530   if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 529   if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 
| 531     if (Var->hasReg()) { | 530     if (Var->hasReg()) { | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 555     llvm_unreachable("Unexpected operand type"); | 554     llvm_unreachable("Unexpected operand type"); | 
| 556   } | 555   } | 
| 557   if (NeedsFallback) { | 556   if (NeedsFallback) { | 
| 558     // TODO(jvoung): The ".long sym" hack doesn't work, since we need | 557     // TODO(jvoung): The ".long sym" hack doesn't work, since we need | 
| 559     // a pc-rel relocation and not an absolute relocation. | 558     // a pc-rel relocation and not an absolute relocation. | 
| 560     // | 559     // | 
| 561     // Still, we have at least filled the assembler buffer so that the | 560     // Still, we have at least filled the assembler buffer so that the | 
| 562     // instruction sizes/positions are correct for jumps. | 561     // instruction sizes/positions are correct for jumps. | 
| 563     // For now, fall back to the regular .s emission, after filling the buffer. | 562     // For now, fall back to the regular .s emission, after filling the buffer. | 
| 564     emit(Func); | 563     emit(Func); | 
|  | 564     Func->getContext()->getStrEmit() << "\n"; | 
| 565   } else { | 565   } else { | 
| 566     emitIASBytes(Func, Asm, StartPosition); | 566     emitIASBytes(Func, Asm, StartPosition); | 
| 567   } | 567   } | 
| 568   Func->getTarget()->resetStackAdjustment(); | 568   Func->getTarget()->resetStackAdjustment(); | 
| 569 } | 569 } | 
| 570 | 570 | 
| 571 void InstX8632Call::dump(const Cfg *Func) const { | 571 void InstX8632Call::dump(const Cfg *Func) const { | 
| 572   Ostream &Str = Func->getContext()->getStrDump(); | 572   Ostream &Str = Func->getContext()->getStrDump(); | 
| 573   if (getDest()) { | 573   if (getDest()) { | 
| 574     dumpDest(Func); | 574     dumpDest(Func); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 593   bool EmittedSrc1 = false; | 593   bool EmittedSrc1 = false; | 
| 594   if (ShiftHack) { | 594   if (ShiftHack) { | 
| 595     Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1)); | 595     Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1)); | 
| 596     if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { | 596     if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { | 
| 597       Str << "cl"; | 597       Str << "cl"; | 
| 598       EmittedSrc1 = true; | 598       EmittedSrc1 = true; | 
| 599     } | 599     } | 
| 600   } | 600   } | 
| 601   if (!EmittedSrc1) | 601   if (!EmittedSrc1) | 
| 602     Inst->getSrc(1)->emit(Func); | 602     Inst->getSrc(1)->emit(Func); | 
| 603   Str << "\n"; |  | 
| 604 } | 603 } | 
| 605 | 604 | 
| 606 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 605 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 
| 607                     const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 606                     const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 
| 608   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 607   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 609   intptr_t StartPosition = Asm->GetPosition(); | 608   intptr_t StartPosition = Asm->GetPosition(); | 
| 610   if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 609   if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 
| 611     if (Var->hasReg()) { | 610     if (Var->hasReg()) { | 
| 612       // We cheat a little and use GPRRegister even for byte operations. | 611       // We cheat a little and use GPRRegister even for byte operations. | 
| 613       RegX8632::GPRRegister VarReg = | 612       RegX8632::GPRRegister VarReg = | 
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1140 | 1139 | 
| 1141 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1140 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 
| 1142   Ostream &Str = Func->getContext()->getStrEmit(); | 1141   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1143   assert(getSrcSize() == 1); | 1142   assert(getSrcSize() == 1); | 
| 1144   Type Ty = getSrc(0)->getType(); | 1143   Type Ty = getSrc(0)->getType(); | 
| 1145   assert(isScalarFloatingType(Ty)); | 1144   assert(isScalarFloatingType(Ty)); | 
| 1146   Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1145   Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 
| 1147   getDest()->emit(Func); | 1146   getDest()->emit(Func); | 
| 1148   Str << ", "; | 1147   Str << ", "; | 
| 1149   getSrc(0)->emit(Func); | 1148   getSrc(0)->emit(Func); | 
| 1150   Str << "\n"; |  | 
| 1151 } | 1149 } | 
| 1152 | 1150 | 
| 1153 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 1151 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 
| 1154   char buf[30]; | 1152   char buf[30]; | 
| 1155   snprintf(buf, llvm::array_lengthof(buf), "add%s", | 1153   snprintf(buf, llvm::array_lengthof(buf), "add%s", | 
| 1156            TypeX8632Attributes[getDest()->getType()].SdSsString); | 1154            TypeX8632Attributes[getDest()->getType()].SdSsString); | 
| 1157   emitTwoAddress(buf, this, Func); | 1155   emitTwoAddress(buf, this, Func); | 
| 1158 } | 1156 } | 
| 1159 | 1157 | 
| 1160 template <> void InstX8632Padd::emit(const Cfg *Func) const { | 1158 template <> void InstX8632Padd::emit(const Cfg *Func) const { | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1229   snprintf(buf, llvm::array_lengthof(buf), "div%s", | 1227   snprintf(buf, llvm::array_lengthof(buf), "div%s", | 
| 1230            TypeX8632Attributes[getDest()->getType()].SdSsString); | 1228            TypeX8632Attributes[getDest()->getType()].SdSsString); | 
| 1231   emitTwoAddress(buf, this, Func); | 1229   emitTwoAddress(buf, this, Func); | 
| 1232 } | 1230 } | 
| 1233 | 1231 | 
| 1234 template <> void InstX8632Div::emit(const Cfg *Func) const { | 1232 template <> void InstX8632Div::emit(const Cfg *Func) const { | 
| 1235   Ostream &Str = Func->getContext()->getStrEmit(); | 1233   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1236   assert(getSrcSize() == 3); | 1234   assert(getSrcSize() == 3); | 
| 1237   Str << "\t" << Opcode << "\t"; | 1235   Str << "\t" << Opcode << "\t"; | 
| 1238   getSrc(1)->emit(Func); | 1236   getSrc(1)->emit(Func); | 
| 1239   Str << "\n"; |  | 
| 1240 } | 1237 } | 
| 1241 | 1238 | 
| 1242 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 1239 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 
| 1243   assert(getSrcSize() == 3); | 1240   assert(getSrcSize() == 3); | 
| 1244   const Operand *Src = getSrc(1); | 1241   const Operand *Src = getSrc(1); | 
| 1245   Type Ty = Src->getType(); | 1242   Type Ty = Src->getType(); | 
| 1246   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1243   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 
| 1247       &x86::AssemblerX86::div, &x86::AssemblerX86::div}; | 1244       &x86::AssemblerX86::div, &x86::AssemblerX86::div}; | 
| 1248   emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1245   emitIASOpTyGPR(Func, Ty, Src, Emitter); | 
| 1249 } | 1246 } | 
| 1250 | 1247 | 
| 1251 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 1248 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 
| 1252   Ostream &Str = Func->getContext()->getStrEmit(); | 1249   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1253   assert(getSrcSize() == 3); | 1250   assert(getSrcSize() == 3); | 
| 1254   Str << "\t" << Opcode << "\t"; | 1251   Str << "\t" << Opcode << "\t"; | 
| 1255   getSrc(1)->emit(Func); | 1252   getSrc(1)->emit(Func); | 
| 1256   Str << "\n"; |  | 
| 1257 } | 1253 } | 
| 1258 | 1254 | 
| 1259 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 1255 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 
| 1260   assert(getSrcSize() == 3); | 1256   assert(getSrcSize() == 3); | 
| 1261   const Operand *Src = getSrc(1); | 1257   const Operand *Src = getSrc(1); | 
| 1262   Type Ty = Src->getType(); | 1258   Type Ty = Src->getType(); | 
| 1263   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1259   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 
| 1264       &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; | 1260       &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; | 
| 1265   emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1261   emitIASOpTyGPR(Func, Ty, Src, Emitter); | 
| 1266 } | 1262 } | 
| 1267 | 1263 | 
| 1268 namespace { | 1264 namespace { | 
| 1269 | 1265 | 
| 1270 // pblendvb and blendvps take xmm0 as a final implicit argument. | 1266 // pblendvb and blendvps take xmm0 as a final implicit argument. | 
| 1271 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 1267 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 
| 1272                            const Cfg *Func) { | 1268                            const Cfg *Func) { | 
| 1273   Ostream &Str = Func->getContext()->getStrEmit(); | 1269   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1274   assert(Inst->getSrcSize() == 3); | 1270   assert(Inst->getSrcSize() == 3); | 
| 1275   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1271   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 
| 1276          RegX8632::Reg_xmm0); | 1272          RegX8632::Reg_xmm0); | 
| 1277   Str << "\t" << Opcode << "\t"; | 1273   Str << "\t" << Opcode << "\t"; | 
| 1278   Inst->getDest()->emit(Func); | 1274   Inst->getDest()->emit(Func); | 
| 1279   Str << ", "; | 1275   Str << ", "; | 
| 1280   Inst->getSrc(1)->emit(Func); | 1276   Inst->getSrc(1)->emit(Func); | 
| 1281   Str << "\n"; |  | 
| 1282 } | 1277 } | 
| 1283 | 1278 | 
| 1284 void | 1279 void | 
| 1285 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, | 1280 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, | 
| 1286                          const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 1281                          const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 
| 1287   assert(Inst->getSrcSize() == 3); | 1282   assert(Inst->getSrcSize() == 3); | 
| 1288   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1283   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 
| 1289          RegX8632::Reg_xmm0); | 1284          RegX8632::Reg_xmm0); | 
| 1290   const Variable *Dest = Inst->getDest(); | 1285   const Variable *Dest = Inst->getDest(); | 
| 1291   const Operand *Src = Inst->getSrc(1); | 1286   const Operand *Src = Inst->getSrc(1); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1325 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1320 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 
| 1326   Ostream &Str = Func->getContext()->getStrEmit(); | 1321   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1327   assert(getSrcSize() == 2); | 1322   assert(getSrcSize() == 2); | 
| 1328   if (isByteSizedArithType(getDest()->getType())) { | 1323   if (isByteSizedArithType(getDest()->getType())) { | 
| 1329     // The 8-bit version of imul only allows the form "imul r/m8". | 1324     // The 8-bit version of imul only allows the form "imul r/m8". | 
| 1330     Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 1325     Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 
| 1331     (void)Src0; | 1326     (void)Src0; | 
| 1332     assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); | 1327     assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); | 
| 1333     Str << "\timul\t"; | 1328     Str << "\timul\t"; | 
| 1334     getSrc(1)->emit(Func); | 1329     getSrc(1)->emit(Func); | 
| 1335     Str << "\n"; |  | 
| 1336   } else if (llvm::isa<Constant>(getSrc(1))) { | 1330   } else if (llvm::isa<Constant>(getSrc(1))) { | 
| 1337     Str << "\timul\t"; | 1331     Str << "\timul\t"; | 
| 1338     getDest()->emit(Func); | 1332     getDest()->emit(Func); | 
| 1339     Str << ", "; | 1333     Str << ", "; | 
| 1340     getSrc(0)->emit(Func); | 1334     getSrc(0)->emit(Func); | 
| 1341     Str << ", "; | 1335     Str << ", "; | 
| 1342     getSrc(1)->emit(Func); | 1336     getSrc(1)->emit(Func); | 
| 1343     Str << "\n"; |  | 
| 1344   } else { | 1337   } else { | 
| 1345     emitTwoAddress("imul", this, Func); | 1338     emitTwoAddress("imul", this, Func); | 
| 1346   } | 1339   } | 
| 1347 } | 1340 } | 
| 1348 | 1341 | 
| 1349 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 1342 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 
| 1350   assert(getSrcSize() == 2); | 1343   assert(getSrcSize() == 2); | 
| 1351   const Variable *Var = getDest(); | 1344   const Variable *Var = getDest(); | 
| 1352   Type Ty = Var->getType(); | 1345   Type Ty = Var->getType(); | 
| 1353   const Operand *Src = getSrc(1); | 1346   const Operand *Src = getSrc(1); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1390   assert(getSrcSize() == 1); | 1383   assert(getSrcSize() == 1); | 
| 1391   Operand *Src0 = getSrc(0); | 1384   Operand *Src0 = getSrc(0); | 
| 1392   assert(llvm::isa<Variable>(Src0)); | 1385   assert(llvm::isa<Variable>(Src0)); | 
| 1393   assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1386   assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 
| 1394   switch (Src0->getType()) { | 1387   switch (Src0->getType()) { | 
| 1395   default: | 1388   default: | 
| 1396     llvm_unreachable("unexpected source type!"); | 1389     llvm_unreachable("unexpected source type!"); | 
| 1397     break; | 1390     break; | 
| 1398   case IceType_i8: | 1391   case IceType_i8: | 
| 1399     assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1392     assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 
| 1400     Str << "\tcbw\n"; | 1393     Str << "\tcbw"; | 
| 1401     break; | 1394     break; | 
| 1402   case IceType_i16: | 1395   case IceType_i16: | 
| 1403     assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1396     assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 
| 1404     Str << "\tcwd\n"; | 1397     Str << "\tcwd"; | 
| 1405     break; | 1398     break; | 
| 1406   case IceType_i32: | 1399   case IceType_i32: | 
| 1407     assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1400     assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 
| 1408     Str << "\tcdq\n"; | 1401     Str << "\tcdq"; | 
| 1409     break; | 1402     break; | 
| 1410   } | 1403   } | 
| 1411 } | 1404 } | 
| 1412 | 1405 | 
| 1413 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1406 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 
| 1414   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1407   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1415   intptr_t StartPosition = Asm->GetPosition(); | 1408   intptr_t StartPosition = Asm->GetPosition(); | 
| 1416   assert(getSrcSize() == 1); | 1409   assert(getSrcSize() == 1); | 
| 1417   Operand *Src0 = getSrc(0); | 1410   Operand *Src0 = getSrc(0); | 
| 1418   assert(llvm::isa<Variable>(Src0)); | 1411   assert(llvm::isa<Variable>(Src0)); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 1438 } | 1431 } | 
| 1439 | 1432 | 
| 1440 void InstX8632Mul::emit(const Cfg *Func) const { | 1433 void InstX8632Mul::emit(const Cfg *Func) const { | 
| 1441   Ostream &Str = Func->getContext()->getStrEmit(); | 1434   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1442   assert(getSrcSize() == 2); | 1435   assert(getSrcSize() == 2); | 
| 1443   assert(llvm::isa<Variable>(getSrc(0))); | 1436   assert(llvm::isa<Variable>(getSrc(0))); | 
| 1444   assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1437   assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 
| 1445   assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1438   assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 
| 1446   Str << "\tmul\t"; | 1439   Str << "\tmul\t"; | 
| 1447   getSrc(1)->emit(Func); | 1440   getSrc(1)->emit(Func); | 
| 1448   Str << "\n"; |  | 
| 1449 } | 1441 } | 
| 1450 | 1442 | 
| 1451 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1443 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 
| 1452   assert(getSrcSize() == 2); | 1444   assert(getSrcSize() == 2); | 
| 1453   assert(llvm::isa<Variable>(getSrc(0))); | 1445   assert(llvm::isa<Variable>(getSrc(0))); | 
| 1454   assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1446   assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 
| 1455   assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1447   assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 
| 1456   const Operand *Src = getSrc(1); | 1448   const Operand *Src = getSrc(1); | 
| 1457   Type Ty = Src->getType(); | 1449   Type Ty = Src->getType(); | 
| 1458   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1450   const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 1476   Str << ", "; | 1468   Str << ", "; | 
| 1477   getSrc(1)->emit(Func); | 1469   getSrc(1)->emit(Func); | 
| 1478   Str << ", "; | 1470   Str << ", "; | 
| 1479   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1471   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 
| 1480     (void)ShiftReg; | 1472     (void)ShiftReg; | 
| 1481     assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1473     assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 
| 1482     Str << "cl"; | 1474     Str << "cl"; | 
| 1483   } else { | 1475   } else { | 
| 1484     getSrc(2)->emit(Func); | 1476     getSrc(2)->emit(Func); | 
| 1485   } | 1477   } | 
| 1486   Str << "\n"; |  | 
| 1487 } | 1478 } | 
| 1488 | 1479 | 
| 1489 void InstX8632Shld::emitIAS(const Cfg *Func) const { | 1480 void InstX8632Shld::emitIAS(const Cfg *Func) const { | 
| 1490   assert(getSrcSize() == 3); | 1481   assert(getSrcSize() == 3); | 
| 1491   assert(getDest() == getSrc(0)); | 1482   assert(getDest() == getSrc(0)); | 
| 1492   const Variable *Dest = getDest(); | 1483   const Variable *Dest = getDest(); | 
| 1493   const Operand *Src1 = getSrc(1); | 1484   const Operand *Src1 = getSrc(1); | 
| 1494   const Operand *Src2 = getSrc(2); | 1485   const Operand *Src2 = getSrc(2); | 
| 1495   static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1486   static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 
| 1496       &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; | 1487       &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1513   Str << ", "; | 1504   Str << ", "; | 
| 1514   getSrc(1)->emit(Func); | 1505   getSrc(1)->emit(Func); | 
| 1515   Str << ", "; | 1506   Str << ", "; | 
| 1516   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1507   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 
| 1517     (void)ShiftReg; | 1508     (void)ShiftReg; | 
| 1518     assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1509     assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 
| 1519     Str << "cl"; | 1510     Str << "cl"; | 
| 1520   } else { | 1511   } else { | 
| 1521     getSrc(2)->emit(Func); | 1512     getSrc(2)->emit(Func); | 
| 1522   } | 1513   } | 
| 1523   Str << "\n"; |  | 
| 1524 } | 1514 } | 
| 1525 | 1515 | 
| 1526 void InstX8632Shrd::emitIAS(const Cfg *Func) const { | 1516 void InstX8632Shrd::emitIAS(const Cfg *Func) const { | 
| 1527   assert(getSrcSize() == 3); | 1517   assert(getSrcSize() == 3); | 
| 1528   assert(getDest() == getSrc(0)); | 1518   assert(getDest() == getSrc(0)); | 
| 1529   const Variable *Dest = getDest(); | 1519   const Variable *Dest = getDest(); | 
| 1530   const Operand *Src1 = getSrc(1); | 1520   const Operand *Src1 = getSrc(1); | 
| 1531   const Operand *Src2 = getSrc(2); | 1521   const Operand *Src2 = getSrc(2); | 
| 1532   static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1522   static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 
| 1533       &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; | 1523       &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; | 
| 1534   emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1524   emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 
| 1535 } | 1525 } | 
| 1536 | 1526 | 
| 1537 void InstX8632Shrd::dump(const Cfg *Func) const { | 1527 void InstX8632Shrd::dump(const Cfg *Func) const { | 
| 1538   Ostream &Str = Func->getContext()->getStrDump(); | 1528   Ostream &Str = Func->getContext()->getStrDump(); | 
| 1539   dumpDest(Func); | 1529   dumpDest(Func); | 
| 1540   Str << " = shrd." << getDest()->getType() << " "; | 1530   Str << " = shrd." << getDest()->getType() << " "; | 
| 1541   dumpSources(Func); | 1531   dumpSources(Func); | 
| 1542 } | 1532 } | 
| 1543 | 1533 | 
| 1544 void InstX8632Cmov::emit(const Cfg *Func) const { | 1534 void InstX8632Cmov::emit(const Cfg *Func) const { | 
| 1545   Ostream &Str = Func->getContext()->getStrEmit(); | 1535   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1546   Str << "\t"; | 1536   Str << "\t"; | 
| 1547   assert(Condition != CondX86::Br_None); | 1537   assert(Condition != CondX86::Br_None); | 
| 1548   assert(getDest()->hasReg()); | 1538   assert(getDest()->hasReg()); | 
| 1549   Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 1539   Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 
| 1550   getDest()->emit(Func); | 1540   getDest()->emit(Func); | 
| 1551   Str << ", "; | 1541   Str << ", "; | 
| 1552   getSrc(1)->emit(Func); | 1542   getSrc(1)->emit(Func); | 
| 1553   Str << "\n"; |  | 
| 1554 } | 1543 } | 
| 1555 | 1544 | 
| 1556 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1545 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 
| 1557   assert(Condition != CondX86::Br_None); | 1546   assert(Condition != CondX86::Br_None); | 
| 1558   assert(getDest()->hasReg()); | 1547   assert(getDest()->hasReg()); | 
| 1559   assert(getSrcSize() == 2); | 1548   assert(getSrcSize() == 2); | 
| 1560   // Only need the reg/reg form now. | 1549   // Only need the reg/reg form now. | 
| 1561   const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1550   const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 
| 1562   assert(Src->hasReg()); | 1551   assert(Src->hasReg()); | 
| 1563   assert(Src->getType() == IceType_i32); | 1552   assert(Src->getType() == IceType_i32); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1580 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1569 void InstX8632Cmpps::emit(const Cfg *Func) const { | 
| 1581   Ostream &Str = Func->getContext()->getStrEmit(); | 1570   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1582   assert(getSrcSize() == 2); | 1571   assert(getSrcSize() == 2); | 
| 1583   assert(Condition < CondX86::Cmpps_Invalid); | 1572   assert(Condition < CondX86::Cmpps_Invalid); | 
| 1584   Str << "\t"; | 1573   Str << "\t"; | 
| 1585   Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1574   Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 
| 1586       << "\t"; | 1575       << "\t"; | 
| 1587   getDest()->emit(Func); | 1576   getDest()->emit(Func); | 
| 1588   Str << ", "; | 1577   Str << ", "; | 
| 1589   getSrc(1)->emit(Func); | 1578   getSrc(1)->emit(Func); | 
| 1590   Str << "\n"; |  | 
| 1591 } | 1579 } | 
| 1592 | 1580 | 
| 1593 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1581 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 
| 1594   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1582   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1595   intptr_t StartPosition = Asm->GetPosition(); | 1583   intptr_t StartPosition = Asm->GetPosition(); | 
| 1596   assert(getSrcSize() == 2); | 1584   assert(getSrcSize() == 2); | 
| 1597   assert(Condition < CondX86::Cmpps_Invalid); | 1585   assert(Condition < CondX86::Cmpps_Invalid); | 
| 1598   // Assuming there isn't any load folding for cmpps, and vector constants | 1586   // Assuming there isn't any load folding for cmpps, and vector constants | 
| 1599   // are not allowed in PNaCl. | 1587   // are not allowed in PNaCl. | 
| 1600   assert(llvm::isa<Variable>(getSrc(1))); | 1588   assert(llvm::isa<Variable>(getSrc(1))); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 1623 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1611 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 
| 1624   Ostream &Str = Func->getContext()->getStrEmit(); | 1612   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1625   assert(getSrcSize() == 3); | 1613   assert(getSrcSize() == 3); | 
| 1626   if (Locked) { | 1614   if (Locked) { | 
| 1627     Str << "\tlock"; | 1615     Str << "\tlock"; | 
| 1628   } | 1616   } | 
| 1629   Str << "\tcmpxchg\t"; | 1617   Str << "\tcmpxchg\t"; | 
| 1630   getSrc(0)->emit(Func); | 1618   getSrc(0)->emit(Func); | 
| 1631   Str << ", "; | 1619   Str << ", "; | 
| 1632   getSrc(2)->emit(Func); | 1620   getSrc(2)->emit(Func); | 
| 1633   Str << "\n"; |  | 
| 1634 } | 1621 } | 
| 1635 | 1622 | 
| 1636 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1623 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 
| 1637   assert(getSrcSize() == 3); | 1624   assert(getSrcSize() == 3); | 
| 1638   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1625   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1639   intptr_t StartPosition = Asm->GetPosition(); | 1626   intptr_t StartPosition = Asm->GetPosition(); | 
| 1640   Type Ty = getSrc(0)->getType(); | 1627   Type Ty = getSrc(0)->getType(); | 
| 1641   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1628   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 
| 1642   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1629   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 1643   const x86::Address Addr = Mem->toAsmAddress(Asm); | 1630   const x86::Address Addr = Mem->toAsmAddress(Asm); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 1663 } | 1650 } | 
| 1664 | 1651 | 
| 1665 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1652 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 
| 1666   Ostream &Str = Func->getContext()->getStrEmit(); | 1653   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1667   assert(getSrcSize() == 5); | 1654   assert(getSrcSize() == 5); | 
| 1668   if (Locked) { | 1655   if (Locked) { | 
| 1669     Str << "\tlock"; | 1656     Str << "\tlock"; | 
| 1670   } | 1657   } | 
| 1671   Str << "\tcmpxchg8b\t"; | 1658   Str << "\tcmpxchg8b\t"; | 
| 1672   getSrc(0)->emit(Func); | 1659   getSrc(0)->emit(Func); | 
| 1673   Str << "\n"; |  | 
| 1674 } | 1660 } | 
| 1675 | 1661 | 
| 1676 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1662 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 
| 1677   assert(getSrcSize() == 5); | 1663   assert(getSrcSize() == 5); | 
| 1678   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1664   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1679   intptr_t StartPosition = Asm->GetPosition(); | 1665   intptr_t StartPosition = Asm->GetPosition(); | 
| 1680   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1666   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 
| 1681   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1667   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 1682   const x86::Address Addr = Mem->toAsmAddress(Asm); | 1668   const x86::Address Addr = Mem->toAsmAddress(Asm); | 
| 1683   if (Locked) { | 1669   if (Locked) { | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1700   Ostream &Str = Func->getContext()->getStrEmit(); | 1686   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1701   assert(getSrcSize() == 1); | 1687   assert(getSrcSize() == 1); | 
| 1702   Str << "\tcvt"; | 1688   Str << "\tcvt"; | 
| 1703   if (isTruncating()) | 1689   if (isTruncating()) | 
| 1704     Str << "t"; | 1690     Str << "t"; | 
| 1705   Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1691   Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 
| 1706       << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 1692       << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 
| 1707   getDest()->emit(Func); | 1693   getDest()->emit(Func); | 
| 1708   Str << ", "; | 1694   Str << ", "; | 
| 1709   getSrc(0)->emit(Func); | 1695   getSrc(0)->emit(Func); | 
| 1710   Str << "\n"; |  | 
| 1711 } | 1696 } | 
| 1712 | 1697 | 
| 1713 void InstX8632Cvt::emitIAS(const Cfg *Func) const { | 1698 void InstX8632Cvt::emitIAS(const Cfg *Func) const { | 
| 1714   assert(getSrcSize() == 1); | 1699   assert(getSrcSize() == 1); | 
| 1715   const Variable *Dest = getDest(); | 1700   const Variable *Dest = getDest(); | 
| 1716   const Operand *Src = getSrc(0); | 1701   const Operand *Src = getSrc(0); | 
| 1717   Type DestTy = Dest->getType(); | 1702   Type DestTy = Dest->getType(); | 
| 1718   Type SrcTy = Src->getType(); | 1703   Type SrcTy = Src->getType(); | 
| 1719   switch (Variant) { | 1704   switch (Variant) { | 
| 1720   case Si2ss: { | 1705   case Si2ss: { | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1780   dumpSources(Func); | 1765   dumpSources(Func); | 
| 1781 } | 1766 } | 
| 1782 | 1767 | 
| 1783 void InstX8632Icmp::emit(const Cfg *Func) const { | 1768 void InstX8632Icmp::emit(const Cfg *Func) const { | 
| 1784   Ostream &Str = Func->getContext()->getStrEmit(); | 1769   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1785   assert(getSrcSize() == 2); | 1770   assert(getSrcSize() == 2); | 
| 1786   Str << "\tcmp\t"; | 1771   Str << "\tcmp\t"; | 
| 1787   getSrc(0)->emit(Func); | 1772   getSrc(0)->emit(Func); | 
| 1788   Str << ", "; | 1773   Str << ", "; | 
| 1789   getSrc(1)->emit(Func); | 1774   getSrc(1)->emit(Func); | 
| 1790   Str << "\n"; |  | 
| 1791 } | 1775 } | 
| 1792 | 1776 | 
| 1793 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 1777 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 
| 1794   assert(getSrcSize() == 2); | 1778   assert(getSrcSize() == 2); | 
| 1795   const Operand *Src0 = getSrc(0); | 1779   const Operand *Src0 = getSrc(0); | 
| 1796   const Operand *Src1 = getSrc(1); | 1780   const Operand *Src1 = getSrc(1); | 
| 1797   Type Ty = Src0->getType(); | 1781   Type Ty = Src0->getType(); | 
| 1798   static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1782   static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 
| 1799     &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp | 1783     &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp | 
| 1800   }; | 1784   }; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1817 } | 1801 } | 
| 1818 | 1802 | 
| 1819 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 1803 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 
| 1820   Ostream &Str = Func->getContext()->getStrEmit(); | 1804   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1821   assert(getSrcSize() == 2); | 1805   assert(getSrcSize() == 2); | 
| 1822   Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1806   Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 
| 1823       << "\t"; | 1807       << "\t"; | 
| 1824   getSrc(0)->emit(Func); | 1808   getSrc(0)->emit(Func); | 
| 1825   Str << ", "; | 1809   Str << ", "; | 
| 1826   getSrc(1)->emit(Func); | 1810   getSrc(1)->emit(Func); | 
| 1827   Str << "\n"; |  | 
| 1828 } | 1811 } | 
| 1829 | 1812 | 
| 1830 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1813 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 
| 1831   assert(getSrcSize() == 2); | 1814   assert(getSrcSize() == 2); | 
| 1832   // Currently src0 is always a variable by convention, to avoid having | 1815   // Currently src0 is always a variable by convention, to avoid having | 
| 1833   // two memory operands. | 1816   // two memory operands. | 
| 1834   assert(llvm::isa<Variable>(getSrc(0))); | 1817   assert(llvm::isa<Variable>(getSrc(0))); | 
| 1835   const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 1818   const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 
| 1836   Type Ty = Src0->getType(); | 1819   Type Ty = Src0->getType(); | 
| 1837   const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1820   const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 
| 1838     &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss | 1821     &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss | 
| 1839   }; | 1822   }; | 
| 1840   emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); | 1823   emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); | 
| 1841 } | 1824 } | 
| 1842 | 1825 | 
| 1843 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1826 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 
| 1844   Ostream &Str = Func->getContext()->getStrDump(); | 1827   Ostream &Str = Func->getContext()->getStrDump(); | 
| 1845   Str << "ucomiss." << getSrc(0)->getType() << " "; | 1828   Str << "ucomiss." << getSrc(0)->getType() << " "; | 
| 1846   dumpSources(Func); | 1829   dumpSources(Func); | 
| 1847 } | 1830 } | 
| 1848 | 1831 | 
| 1849 void InstX8632UD2::emit(const Cfg *Func) const { | 1832 void InstX8632UD2::emit(const Cfg *Func) const { | 
| 1850   Ostream &Str = Func->getContext()->getStrEmit(); | 1833   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1851   assert(getSrcSize() == 0); | 1834   assert(getSrcSize() == 0); | 
| 1852   Str << "\tud2\n"; | 1835   Str << "\tud2"; | 
| 1853 } | 1836 } | 
| 1854 | 1837 | 
| 1855 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1838 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 
| 1856   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1839   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1857   intptr_t StartPosition = Asm->GetPosition(); | 1840   intptr_t StartPosition = Asm->GetPosition(); | 
| 1858   Asm->ud2(); | 1841   Asm->ud2(); | 
| 1859   emitIASBytes(Func, Asm, StartPosition); | 1842   emitIASBytes(Func, Asm, StartPosition); | 
| 1860 } | 1843 } | 
| 1861 | 1844 | 
| 1862 void InstX8632UD2::dump(const Cfg *Func) const { | 1845 void InstX8632UD2::dump(const Cfg *Func) const { | 
| 1863   Ostream &Str = Func->getContext()->getStrDump(); | 1846   Ostream &Str = Func->getContext()->getStrDump(); | 
| 1864   Str << "ud2\n"; | 1847   Str << "ud2\n"; | 
| 1865 } | 1848 } | 
| 1866 | 1849 | 
| 1867 void InstX8632Test::emit(const Cfg *Func) const { | 1850 void InstX8632Test::emit(const Cfg *Func) const { | 
| 1868   Ostream &Str = Func->getContext()->getStrEmit(); | 1851   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1869   assert(getSrcSize() == 2); | 1852   assert(getSrcSize() == 2); | 
| 1870   Str << "\ttest\t"; | 1853   Str << "\ttest\t"; | 
| 1871   getSrc(0)->emit(Func); | 1854   getSrc(0)->emit(Func); | 
| 1872   Str << ", "; | 1855   Str << ", "; | 
| 1873   getSrc(1)->emit(Func); | 1856   getSrc(1)->emit(Func); | 
| 1874   Str << "\n"; |  | 
| 1875 } | 1857 } | 
| 1876 | 1858 | 
| 1877 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1859 void InstX8632Test::emitIAS(const Cfg *Func) const { | 
| 1878   assert(getSrcSize() == 2); | 1860   assert(getSrcSize() == 2); | 
| 1879   const Operand *Src0 = getSrc(0); | 1861   const Operand *Src0 = getSrc(0); | 
| 1880   const Operand *Src1 = getSrc(1); | 1862   const Operand *Src1 = getSrc(1); | 
| 1881   Type Ty = Src0->getType(); | 1863   Type Ty = Src0->getType(); | 
| 1882   // The Reg/Addr form of test is not encodeable. | 1864   // The Reg/Addr form of test is not encodeable. | 
| 1883   static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1865   static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 
| 1884     &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test | 1866     &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 1898 | 1880 | 
| 1899 void InstX8632Test::dump(const Cfg *Func) const { | 1881 void InstX8632Test::dump(const Cfg *Func) const { | 
| 1900   Ostream &Str = Func->getContext()->getStrDump(); | 1882   Ostream &Str = Func->getContext()->getStrDump(); | 
| 1901   Str << "test." << getSrc(0)->getType() << " "; | 1883   Str << "test." << getSrc(0)->getType() << " "; | 
| 1902   dumpSources(Func); | 1884   dumpSources(Func); | 
| 1903 } | 1885 } | 
| 1904 | 1886 | 
| 1905 void InstX8632Mfence::emit(const Cfg *Func) const { | 1887 void InstX8632Mfence::emit(const Cfg *Func) const { | 
| 1906   Ostream &Str = Func->getContext()->getStrEmit(); | 1888   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1907   assert(getSrcSize() == 0); | 1889   assert(getSrcSize() == 0); | 
| 1908   Str << "\tmfence\n"; | 1890   Str << "\tmfence"; | 
| 1909 } | 1891 } | 
| 1910 | 1892 | 
| 1911 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1893 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 
| 1912   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1894   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1913   intptr_t StartPosition = Asm->GetPosition(); | 1895   intptr_t StartPosition = Asm->GetPosition(); | 
| 1914   Asm->mfence(); | 1896   Asm->mfence(); | 
| 1915   emitIASBytes(Func, Asm, StartPosition); | 1897   emitIASBytes(Func, Asm, StartPosition); | 
| 1916 } | 1898 } | 
| 1917 | 1899 | 
| 1918 void InstX8632Mfence::dump(const Cfg *Func) const { | 1900 void InstX8632Mfence::dump(const Cfg *Func) const { | 
| 1919   Ostream &Str = Func->getContext()->getStrDump(); | 1901   Ostream &Str = Func->getContext()->getStrDump(); | 
| 1920   Str << "mfence\n"; | 1902   Str << "mfence\n"; | 
| 1921 } | 1903 } | 
| 1922 | 1904 | 
| 1923 void InstX8632Store::emit(const Cfg *Func) const { | 1905 void InstX8632Store::emit(const Cfg *Func) const { | 
| 1924   Ostream &Str = Func->getContext()->getStrEmit(); | 1906   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1925   assert(getSrcSize() == 2); | 1907   assert(getSrcSize() == 2); | 
| 1926   Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1908   Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 
| 1927       << "\t"; | 1909       << "\t"; | 
| 1928   getSrc(1)->emit(Func); | 1910   getSrc(1)->emit(Func); | 
| 1929   Str << ", "; | 1911   Str << ", "; | 
| 1930   getSrc(0)->emit(Func); | 1912   getSrc(0)->emit(Func); | 
| 1931   Str << "\n"; |  | 
| 1932 } | 1913 } | 
| 1933 | 1914 | 
| 1934 void InstX8632Store::emitIAS(const Cfg *Func) const { | 1915 void InstX8632Store::emitIAS(const Cfg *Func) const { | 
| 1935   assert(getSrcSize() == 2); | 1916   assert(getSrcSize() == 2); | 
| 1936   const Operand *Dest = getSrc(1); | 1917   const Operand *Dest = getSrc(1); | 
| 1937   const Operand *Src = getSrc(0); | 1918   const Operand *Src = getSrc(0); | 
| 1938   Type DestTy = Dest->getType(); | 1919   Type DestTy = Dest->getType(); | 
| 1939   if (isScalarFloatingType(DestTy)) { | 1920   if (isScalarFloatingType(DestTy)) { | 
| 1940     // Src must be a register, since Dest is a Mem operand of some kind. | 1921     // Src must be a register, since Dest is a Mem operand of some kind. | 
| 1941     const Variable *SrcVar = llvm::cast<Variable>(Src); | 1922     const Variable *SrcVar = llvm::cast<Variable>(Src); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1971   getSrc(0)->dump(Func); | 1952   getSrc(0)->dump(Func); | 
| 1972 } | 1953 } | 
| 1973 | 1954 | 
| 1974 void InstX8632StoreP::emit(const Cfg *Func) const { | 1955 void InstX8632StoreP::emit(const Cfg *Func) const { | 
| 1975   Ostream &Str = Func->getContext()->getStrEmit(); | 1956   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 1976   assert(getSrcSize() == 2); | 1957   assert(getSrcSize() == 2); | 
| 1977   Str << "\tmovups\t"; | 1958   Str << "\tmovups\t"; | 
| 1978   getSrc(1)->emit(Func); | 1959   getSrc(1)->emit(Func); | 
| 1979   Str << ", "; | 1960   Str << ", "; | 
| 1980   getSrc(0)->emit(Func); | 1961   getSrc(0)->emit(Func); | 
| 1981   Str << "\n"; |  | 
| 1982 } | 1962 } | 
| 1983 | 1963 | 
| 1984 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 1964 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 
| 1985   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1965   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 1986   intptr_t StartPosition = Asm->GetPosition(); | 1966   intptr_t StartPosition = Asm->GetPosition(); | 
| 1987   assert(getSrcSize() == 2); | 1967   assert(getSrcSize() == 2); | 
| 1988   const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1968   const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 
| 1989   const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1969   const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 
| 1990   assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1970   assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 1991   assert(Src->hasReg()); | 1971   assert(Src->hasReg()); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 2004 | 1984 | 
| 2005 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1985 void InstX8632StoreQ::emit(const Cfg *Func) const { | 
| 2006   Ostream &Str = Func->getContext()->getStrEmit(); | 1986   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2007   assert(getSrcSize() == 2); | 1987   assert(getSrcSize() == 2); | 
| 2008   assert(getSrc(1)->getType() == IceType_i64 || | 1988   assert(getSrc(1)->getType() == IceType_i64 || | 
| 2009          getSrc(1)->getType() == IceType_f64); | 1989          getSrc(1)->getType() == IceType_f64); | 
| 2010   Str << "\tmovq\t"; | 1990   Str << "\tmovq\t"; | 
| 2011   getSrc(1)->emit(Func); | 1991   getSrc(1)->emit(Func); | 
| 2012   Str << ", "; | 1992   Str << ", "; | 
| 2013   getSrc(0)->emit(Func); | 1993   getSrc(0)->emit(Func); | 
| 2014   Str << "\n"; |  | 
| 2015 } | 1994 } | 
| 2016 | 1995 | 
| 2017 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 1996 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 
| 2018   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1997   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2019   intptr_t StartPosition = Asm->GetPosition(); | 1998   intptr_t StartPosition = Asm->GetPosition(); | 
| 2020   assert(getSrcSize() == 2); | 1999   assert(getSrcSize() == 2); | 
| 2021   const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 2000   const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 
| 2022   const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2001   const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 
| 2023   assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2002   assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 2024   assert(Src->hasReg()); | 2003   assert(Src->hasReg()); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 2044   Str << ", "; | 2023   Str << ", "; | 
| 2045   Operand *Src0 = getSrc(0); | 2024   Operand *Src0 = getSrc(0); | 
| 2046   if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) { | 2025   if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) { | 
| 2047     Type Ty = VSrc0->getType(); | 2026     Type Ty = VSrc0->getType(); | 
| 2048     // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2027     // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 
| 2049     // acceptable type. | 2028     // acceptable type. | 
| 2050     VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); | 2029     VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); | 
| 2051   } else { | 2030   } else { | 
| 2052     Src0->emit(Func); | 2031     Src0->emit(Func); | 
| 2053   } | 2032   } | 
| 2054   Str << "\n"; |  | 
| 2055 } | 2033 } | 
| 2056 | 2034 | 
| 2057 template <> void InstX8632Mov::emit(const Cfg *Func) const { | 2035 template <> void InstX8632Mov::emit(const Cfg *Func) const { | 
| 2058   Ostream &Str = Func->getContext()->getStrEmit(); | 2036   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2059   assert(getSrcSize() == 1); | 2037   assert(getSrcSize() == 1); | 
| 2060   Operand *Src = getSrc(0); | 2038   Operand *Src = getSrc(0); | 
| 2061   // The llvm-mc assembler using Intel syntax has a bug in which "mov | 2039   // The llvm-mc assembler using Intel syntax has a bug in which "mov | 
| 2062   // reg, RelocatableConstant" does not generate the right instruction | 2040   // reg, RelocatableConstant" does not generate the right instruction | 
| 2063   // with a relocation.  To work around, we emit "lea reg, | 2041   // with a relocation.  To work around, we emit "lea reg, | 
| 2064   // RelocatableConstant".  Also, the lowering and legalization is | 2042   // RelocatableConstant".  Also, the lowering and legalization is | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 2088   // TODO: This assert disallows usages such as copying a floating point | 2066   // TODO: This assert disallows usages such as copying a floating point | 
| 2089   // value between a vector and a scalar (which movss is used for). | 2067   // value between a vector and a scalar (which movss is used for). | 
| 2090   // Clean this up. | 2068   // Clean this up. | 
| 2091   assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 2069   assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 
| 2092          Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 2070          Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 
| 2093   if (UseLeaHack) { | 2071   if (UseLeaHack) { | 
| 2094     Src->emit(Func); | 2072     Src->emit(Func); | 
| 2095     Str << ", %"; | 2073     Str << ", %"; | 
| 2096     getDest()->emit(Func); | 2074     getDest()->emit(Func); | 
| 2097     Str << "\n"; | 2075     Str << "\n"; | 
| 2098     Str << ".intel_syntax\n"; | 2076     Str << ".intel_syntax"; | 
| 2099   } else { | 2077   } else { | 
| 2100     getDest()->asType(Src->getType()).emit(Func); | 2078     getDest()->asType(Src->getType()).emit(Func); | 
| 2101     Str << ", "; | 2079     Str << ", "; | 
| 2102     Src->emit(Func); | 2080     Src->emit(Func); | 
| 2103     Str << "\n"; |  | 
| 2104   } | 2081   } | 
| 2105 } | 2082 } | 
| 2106 | 2083 | 
| 2107 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { | 2084 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { | 
| 2108   assert(getSrcSize() == 1); | 2085   assert(getSrcSize() == 1); | 
| 2109   const Variable *Dest = getDest(); | 2086   const Variable *Dest = getDest(); | 
| 2110   const Operand *Src = getSrc(0); | 2087   const Operand *Src = getSrc(0); | 
| 2111   Type DestTy = Dest->getType(); | 2088   Type DestTy = Dest->getType(); | 
| 2112   Type SrcTy = Src->getType(); | 2089   Type SrcTy = Src->getType(); | 
| 2113   // Mov can be used for GPRs or XMM registers. Also, the type does not | 2090   // Mov can be used for GPRs or XMM registers. Also, the type does not | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2214   // TODO(wala,stichnot): movups works with all vector operands, but | 2191   // TODO(wala,stichnot): movups works with all vector operands, but | 
| 2215   // there exist other instructions (movaps, movdqa, movdqu) that may | 2192   // there exist other instructions (movaps, movdqa, movdqu) that may | 
| 2216   // perform better, depending on the data type and alignment of the | 2193   // perform better, depending on the data type and alignment of the | 
| 2217   // operands. | 2194   // operands. | 
| 2218   Ostream &Str = Func->getContext()->getStrEmit(); | 2195   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2219   assert(getSrcSize() == 1); | 2196   assert(getSrcSize() == 1); | 
| 2220   Str << "\tmovups\t"; | 2197   Str << "\tmovups\t"; | 
| 2221   getDest()->emit(Func); | 2198   getDest()->emit(Func); | 
| 2222   Str << ", "; | 2199   Str << ", "; | 
| 2223   getSrc(0)->emit(Func); | 2200   getSrc(0)->emit(Func); | 
| 2224   Str << "\n"; |  | 
| 2225 } | 2201 } | 
| 2226 | 2202 | 
| 2227 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 2203 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 
| 2228   assert(getSrcSize() == 1); | 2204   assert(getSrcSize() == 1); | 
| 2229   assert(isVectorType(getDest()->getType())); | 2205   assert(isVectorType(getDest()->getType())); | 
| 2230   const Variable *Dest = getDest(); | 2206   const Variable *Dest = getDest(); | 
| 2231   const Operand *Src = getSrc(0); | 2207   const Operand *Src = getSrc(0); | 
| 2232   const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2208   const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 
| 2233     &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, | 2209     &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, | 
| 2234     &x86::AssemblerX86::movups | 2210     &x86::AssemblerX86::movups | 
| 2235   }; | 2211   }; | 
| 2236   emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2212   emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 
| 2237 } | 2213 } | 
| 2238 | 2214 | 
| 2239 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 2215 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 
| 2240   Ostream &Str = Func->getContext()->getStrEmit(); | 2216   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2241   assert(getSrcSize() == 1); | 2217   assert(getSrcSize() == 1); | 
| 2242   assert(getDest()->getType() == IceType_i64 || | 2218   assert(getDest()->getType() == IceType_i64 || | 
| 2243          getDest()->getType() == IceType_f64); | 2219          getDest()->getType() == IceType_f64); | 
| 2244   Str << "\tmovq\t"; | 2220   Str << "\tmovq\t"; | 
| 2245   getDest()->emit(Func); | 2221   getDest()->emit(Func); | 
| 2246   Str << ", "; | 2222   Str << ", "; | 
| 2247   getSrc(0)->emit(Func); | 2223   getSrc(0)->emit(Func); | 
| 2248   Str << "\n"; |  | 
| 2249 } | 2224 } | 
| 2250 | 2225 | 
| 2251 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { | 2226 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { | 
| 2252   assert(getSrcSize() == 1); | 2227   assert(getSrcSize() == 1); | 
| 2253   assert(getDest()->getType() == IceType_i64 || | 2228   assert(getDest()->getType() == IceType_i64 || | 
| 2254          getDest()->getType() == IceType_f64); | 2229          getDest()->getType() == IceType_f64); | 
| 2255   const Variable *Dest = getDest(); | 2230   const Variable *Dest = getDest(); | 
| 2256   const Operand *Src = getSrc(0); | 2231   const Operand *Src = getSrc(0); | 
| 2257   const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2232   const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 
| 2258     &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq | 2233     &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2294   const Operand *Src = getSrc(0); | 2269   const Operand *Src = getSrc(0); | 
| 2295   Type SrcTy = Src->getType(); | 2270   Type SrcTy = Src->getType(); | 
| 2296   assert(typeWidthInBytes(Dest->getType()) > 1); | 2271   assert(typeWidthInBytes(Dest->getType()) > 1); | 
| 2297   assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2272   assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 
| 2298   emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); | 2273   emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); | 
| 2299 } | 2274 } | 
| 2300 | 2275 | 
| 2301 void InstX8632Nop::emit(const Cfg *Func) const { | 2276 void InstX8632Nop::emit(const Cfg *Func) const { | 
| 2302   Ostream &Str = Func->getContext()->getStrEmit(); | 2277   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2303   // TODO: Emit the right code for each variant. | 2278   // TODO: Emit the right code for each variant. | 
| 2304   Str << "\tnop\t# variant = " << Variant << "\n"; | 2279   Str << "\tnop\t# variant = " << Variant; | 
| 2305 } | 2280 } | 
| 2306 | 2281 | 
| 2307 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2282 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 
| 2308   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2283   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2309   intptr_t StartPosition = Asm->GetPosition(); | 2284   intptr_t StartPosition = Asm->GetPosition(); | 
| 2310   // TODO: Emit the right code for the variant. | 2285   // TODO: Emit the right code for the variant. | 
| 2311   Asm->nop(); | 2286   Asm->nop(); | 
| 2312   emitIASBytes(Func, Asm, StartPosition); | 2287   emitIASBytes(Func, Asm, StartPosition); | 
| 2313 } | 2288 } | 
| 2314 | 2289 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 2325   if (Var && Var->hasReg()) { | 2300   if (Var && Var->hasReg()) { | 
| 2326     // This is a physical xmm register, so we need to spill it to a | 2301     // This is a physical xmm register, so we need to spill it to a | 
| 2327     // temporary stack slot. | 2302     // temporary stack slot. | 
| 2328     SizeT Width = typeWidthInBytes(Ty); | 2303     SizeT Width = typeWidthInBytes(Ty); | 
| 2329     Str << "\tsub\tesp, " << Width << "\n"; | 2304     Str << "\tsub\tesp, " << Width << "\n"; | 
| 2330     Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" | 2305     Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" | 
| 2331         << TypeX8632Attributes[Ty].WidthString << " [esp], "; | 2306         << TypeX8632Attributes[Ty].WidthString << " [esp], "; | 
| 2332     Var->emit(Func); | 2307     Var->emit(Func); | 
| 2333     Str << "\n"; | 2308     Str << "\n"; | 
| 2334     Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 2309     Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 
| 2335     Str << "\tadd\tesp, " << Width << "\n"; | 2310     Str << "\tadd\tesp, " << Width; | 
| 2336     return; | 2311     return; | 
| 2337   } | 2312   } | 
| 2338   Str << "\tfld\t"; | 2313   Str << "\tfld\t"; | 
| 2339   getSrc(0)->emit(Func); | 2314   getSrc(0)->emit(Func); | 
| 2340   Str << "\n"; |  | 
| 2341 } | 2315 } | 
| 2342 | 2316 | 
| 2343 void InstX8632Fld::emitIAS(const Cfg *Func) const { | 2317 void InstX8632Fld::emitIAS(const Cfg *Func) const { | 
| 2344   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2318   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2345   intptr_t StartPosition = Asm->GetPosition(); | 2319   intptr_t StartPosition = Asm->GetPosition(); | 
| 2346   assert(getSrcSize() == 1); | 2320   assert(getSrcSize() == 1); | 
| 2347   const Operand *Src = getSrc(0); | 2321   const Operand *Src = getSrc(0); | 
| 2348   Type Ty = Src->getType(); | 2322   Type Ty = Src->getType(); | 
| 2349   if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 2323   if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 
| 2350     if (Var->hasReg()) { | 2324     if (Var->hasReg()) { | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 2379 } | 2353 } | 
| 2380 | 2354 | 
| 2381 void InstX8632Fstp::emit(const Cfg *Func) const { | 2355 void InstX8632Fstp::emit(const Cfg *Func) const { | 
| 2382   Ostream &Str = Func->getContext()->getStrEmit(); | 2356   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2383   assert(getSrcSize() == 0); | 2357   assert(getSrcSize() == 0); | 
| 2384   // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2358   // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 
| 2385   // "partially" delete the fstp if the Dest is unused. | 2359   // "partially" delete the fstp if the Dest is unused. | 
| 2386   // Even if Dest is unused, the fstp should be kept for the SideEffects | 2360   // Even if Dest is unused, the fstp should be kept for the SideEffects | 
| 2387   // of popping the stack. | 2361   // of popping the stack. | 
| 2388   if (getDest() == NULL) { | 2362   if (getDest() == NULL) { | 
| 2389     Str << "\tfstp\tst(0)\n"; | 2363     Str << "\tfstp\tst(0)"; | 
| 2390     return; | 2364     return; | 
| 2391   } | 2365   } | 
| 2392   if (!getDest()->hasReg()) { | 2366   if (!getDest()->hasReg()) { | 
| 2393     Str << "\tfstp\t"; | 2367     Str << "\tfstp\t"; | 
| 2394     getDest()->emit(Func); | 2368     getDest()->emit(Func); | 
| 2395     Str << "\n"; |  | 
| 2396     return; | 2369     return; | 
| 2397   } | 2370   } | 
| 2398   // Dest is a physical (xmm) register, so st(0) needs to go through | 2371   // Dest is a physical (xmm) register, so st(0) needs to go through | 
| 2399   // memory.  Hack this by creating a temporary stack slot, spilling | 2372   // memory.  Hack this by creating a temporary stack slot, spilling | 
| 2400   // st(0) there, loading it into the xmm register, and deallocating | 2373   // st(0) there, loading it into the xmm register, and deallocating | 
| 2401   // the stack slot. | 2374   // the stack slot. | 
| 2402   Type Ty = getDest()->getType(); | 2375   Type Ty = getDest()->getType(); | 
| 2403   size_t Width = typeWidthInBytes(Ty); | 2376   size_t Width = typeWidthInBytes(Ty); | 
| 2404   Str << "\tsub\tesp, " << Width << "\n"; | 2377   Str << "\tsub\tesp, " << Width << "\n"; | 
| 2405   Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 2378   Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 
| 2406   Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 2379   Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 
| 2407   getDest()->emit(Func); | 2380   getDest()->emit(Func); | 
| 2408   Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 2381   Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; | 
| 2409   Str << "\tadd\tesp, " << Width << "\n"; | 2382   Str << "\tadd\tesp, " << Width; | 
| 2410 } | 2383 } | 
| 2411 | 2384 | 
| 2412 void InstX8632Fstp::emitIAS(const Cfg *Func) const { | 2385 void InstX8632Fstp::emitIAS(const Cfg *Func) const { | 
| 2413   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2386   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2414   intptr_t StartPosition = Asm->GetPosition(); | 2387   intptr_t StartPosition = Asm->GetPosition(); | 
| 2415   assert(getSrcSize() == 0); | 2388   assert(getSrcSize() == 0); | 
| 2416   const Variable *Dest = getDest(); | 2389   const Variable *Dest = getDest(); | 
| 2417   // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2390   // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 
| 2418   // "partially" delete the fstp if the Dest is unused. | 2391   // "partially" delete the fstp if the Dest is unused. | 
| 2419   // Even if Dest is unused, the fstp should be kept for the SideEffects | 2392   // Even if Dest is unused, the fstp should be kept for the SideEffects | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2477   Variable *Dest = getDest(); | 2450   Variable *Dest = getDest(); | 
| 2478   // pextrw must take a register dest. There is an SSE4.1 version that takes | 2451   // pextrw must take a register dest. There is an SSE4.1 version that takes | 
| 2479   // a memory dest, but we aren't using it. For uniformity, just restrict | 2452   // a memory dest, but we aren't using it. For uniformity, just restrict | 
| 2480   // them all to have a register dest for now. | 2453   // them all to have a register dest for now. | 
| 2481   assert(Dest->hasReg()); | 2454   assert(Dest->hasReg()); | 
| 2482   Dest->asType(IceType_i32).emit(Func); | 2455   Dest->asType(IceType_i32).emit(Func); | 
| 2483   Str << ", "; | 2456   Str << ", "; | 
| 2484   getSrc(0)->emit(Func); | 2457   getSrc(0)->emit(Func); | 
| 2485   Str << ", "; | 2458   Str << ", "; | 
| 2486   getSrc(1)->emit(Func); | 2459   getSrc(1)->emit(Func); | 
| 2487   Str << "\n"; |  | 
| 2488 } | 2460 } | 
| 2489 | 2461 | 
| 2490 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { | 2462 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { | 
| 2491   assert(getSrcSize() == 2); | 2463   assert(getSrcSize() == 2); | 
| 2492   // pextrb and pextrd are SSE4.1 instructions. | 2464   // pextrb and pextrd are SSE4.1 instructions. | 
| 2493   const Variable *Dest = getDest(); | 2465   const Variable *Dest = getDest(); | 
| 2494   Type DispatchTy = Dest->getType(); | 2466   Type DispatchTy = Dest->getType(); | 
| 2495   assert(DispatchTy == IceType_i16 || | 2467   assert(DispatchTy == IceType_i16 || | 
| 2496          static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2468          static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 
| 2497              TargetX8632::SSE4_1); | 2469              TargetX8632::SSE4_1); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 2527     if (VSrc1->hasReg()) { | 2499     if (VSrc1->hasReg()) { | 
| 2528       VSrc1->asType(IceType_i32).emit(Func); | 2500       VSrc1->asType(IceType_i32).emit(Func); | 
| 2529     } else { | 2501     } else { | 
| 2530       VSrc1->emit(Func); | 2502       VSrc1->emit(Func); | 
| 2531     } | 2503     } | 
| 2532   } else { | 2504   } else { | 
| 2533     Src1->emit(Func); | 2505     Src1->emit(Func); | 
| 2534   } | 2506   } | 
| 2535   Str << ", "; | 2507   Str << ", "; | 
| 2536   getSrc(2)->emit(Func); | 2508   getSrc(2)->emit(Func); | 
| 2537   Str << "\n"; |  | 
| 2538 } | 2509 } | 
| 2539 | 2510 | 
| 2540 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { | 2511 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { | 
| 2541   assert(getSrcSize() == 3); | 2512   assert(getSrcSize() == 3); | 
| 2542   assert(getDest() == getSrc(0)); | 2513   assert(getDest() == getSrc(0)); | 
| 2543   // pinsrb and pinsrd are SSE4.1 instructions. | 2514   // pinsrb and pinsrd are SSE4.1 instructions. | 
| 2544   const Operand *Src0 = getSrc(1); | 2515   const Operand *Src0 = getSrc(1); | 
| 2545   Type DispatchTy = Src0->getType(); | 2516   Type DispatchTy = Src0->getType(); | 
| 2546   assert(DispatchTy == IceType_i16 || | 2517   assert(DispatchTy == IceType_i16 || | 
| 2547          static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2518          static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2581   emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2552   emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 
| 2582                        RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2553                        RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 
| 2583       Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 2554       Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 
| 2584 } | 2555 } | 
| 2585 | 2556 | 
| 2586 void InstX8632Pop::emit(const Cfg *Func) const { | 2557 void InstX8632Pop::emit(const Cfg *Func) const { | 
| 2587   Ostream &Str = Func->getContext()->getStrEmit(); | 2558   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2588   assert(getSrcSize() == 0); | 2559   assert(getSrcSize() == 0); | 
| 2589   Str << "\tpop\t"; | 2560   Str << "\tpop\t"; | 
| 2590   getDest()->emit(Func); | 2561   getDest()->emit(Func); | 
| 2591   Str << "\n"; |  | 
| 2592 } | 2562 } | 
| 2593 | 2563 | 
| 2594 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2564 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 
| 2595   assert(getSrcSize() == 0); | 2565   assert(getSrcSize() == 0); | 
| 2596   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2566   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2597   intptr_t StartPosition = Asm->GetPosition(); | 2567   intptr_t StartPosition = Asm->GetPosition(); | 
| 2598   if (getDest()->hasReg()) { | 2568   if (getDest()->hasReg()) { | 
| 2599     Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2569     Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 
| 2600   } else { | 2570   } else { | 
| 2601     Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2571     Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 
| 2602                   ->stackVarToAsmOperand(getDest())); | 2572                   ->stackVarToAsmOperand(getDest())); | 
| 2603   } | 2573   } | 
| 2604   emitIASBytes(Func, Asm, StartPosition); | 2574   emitIASBytes(Func, Asm, StartPosition); | 
| 2605 } | 2575 } | 
| 2606 | 2576 | 
| 2607 void InstX8632Pop::dump(const Cfg *Func) const { | 2577 void InstX8632Pop::dump(const Cfg *Func) const { | 
| 2608   Ostream &Str = Func->getContext()->getStrDump(); | 2578   Ostream &Str = Func->getContext()->getStrDump(); | 
| 2609   dumpDest(Func); | 2579   dumpDest(Func); | 
| 2610   Str << " = pop." << getDest()->getType() << " "; | 2580   Str << " = pop." << getDest()->getType() << " "; | 
| 2611 } | 2581 } | 
| 2612 | 2582 | 
| 2613 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2583 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 
| 2614   Ostream &Str = Func->getContext()->getStrEmit(); | 2584   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2615   Str << "\tsub\tesp, " << Amount << "\n"; | 2585   Str << "\tsub\tesp, " << Amount; | 
| 2616   Func->getTarget()->updateStackAdjustment(Amount); | 2586   Func->getTarget()->updateStackAdjustment(Amount); | 
| 2617 } | 2587 } | 
| 2618 | 2588 | 
| 2619 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2589 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 
| 2620   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2590   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2621   intptr_t StartPosition = Asm->GetPosition(); | 2591   intptr_t StartPosition = Asm->GetPosition(); | 
| 2622   Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2592   Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 
| 2623   emitIASBytes(Func, Asm, StartPosition); | 2593   emitIASBytes(Func, Asm, StartPosition); | 
| 2624   Func->getTarget()->updateStackAdjustment(Amount); | 2594   Func->getTarget()->updateStackAdjustment(Amount); | 
| 2625 } | 2595 } | 
| 2626 | 2596 | 
| 2627 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2597 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 
| 2628   Ostream &Str = Func->getContext()->getStrDump(); | 2598   Ostream &Str = Func->getContext()->getStrDump(); | 
| 2629   Str << "esp = sub.i32 esp, " << Amount; | 2599   Str << "esp = sub.i32 esp, " << Amount; | 
| 2630 } | 2600 } | 
| 2631 | 2601 | 
| 2632 void InstX8632Push::emit(const Cfg *Func) const { | 2602 void InstX8632Push::emit(const Cfg *Func) const { | 
| 2633   Ostream &Str = Func->getContext()->getStrEmit(); | 2603   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2634   assert(getSrcSize() == 1); | 2604   assert(getSrcSize() == 1); | 
| 2635   // Push is currently only used for saving GPRs. | 2605   // Push is currently only used for saving GPRs. | 
| 2636   Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2606   Variable *Var = llvm::cast<Variable>(getSrc(0)); | 
| 2637   assert(Var->hasReg()); | 2607   assert(Var->hasReg()); | 
| 2638   Str << "\tpush\t"; | 2608   Str << "\tpush\t"; | 
| 2639   Var->emit(Func); | 2609   Var->emit(Func); | 
| 2640   Str << "\n"; |  | 
| 2641 } | 2610 } | 
| 2642 | 2611 | 
| 2643 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2612 void InstX8632Push::emitIAS(const Cfg *Func) const { | 
| 2644   assert(getSrcSize() == 1); | 2613   assert(getSrcSize() == 1); | 
| 2645   // Push is currently only used for saving GPRs. | 2614   // Push is currently only used for saving GPRs. | 
| 2646   Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2615   Variable *Var = llvm::cast<Variable>(getSrc(0)); | 
| 2647   assert(Var->hasReg()); | 2616   assert(Var->hasReg()); | 
| 2648   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2617   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2649   intptr_t StartPosition = Asm->GetPosition(); | 2618   intptr_t StartPosition = Asm->GetPosition(); | 
| 2650   Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2619   Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 2674          getDest()->getType() == IceType_v4i32 || | 2643          getDest()->getType() == IceType_v4i32 || | 
| 2675          getDest()->getType() == IceType_v4i1); | 2644          getDest()->getType() == IceType_v4i1); | 
| 2676   char buf[30]; | 2645   char buf[30]; | 
| 2677   snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 2646   snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 
| 2678            TypeX8632Attributes[getDest()->getType()].PackString); | 2647            TypeX8632Attributes[getDest()->getType()].PackString); | 
| 2679   emitTwoAddress(buf, this, Func); | 2648   emitTwoAddress(buf, this, Func); | 
| 2680 } | 2649 } | 
| 2681 | 2650 | 
| 2682 void InstX8632Ret::emit(const Cfg *Func) const { | 2651 void InstX8632Ret::emit(const Cfg *Func) const { | 
| 2683   Ostream &Str = Func->getContext()->getStrEmit(); | 2652   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2684   Str << "\tret\n"; | 2653   Str << "\tret"; | 
| 2685 } | 2654 } | 
| 2686 | 2655 | 
| 2687 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2656 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 
| 2688   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2657   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2689   intptr_t StartPosition = Asm->GetPosition(); | 2658   intptr_t StartPosition = Asm->GetPosition(); | 
| 2690   Asm->ret(); | 2659   Asm->ret(); | 
| 2691   emitIASBytes(Func, Asm, StartPosition); | 2660   emitIASBytes(Func, Asm, StartPosition); | 
| 2692 } | 2661 } | 
| 2693 | 2662 | 
| 2694 void InstX8632Ret::dump(const Cfg *Func) const { | 2663 void InstX8632Ret::dump(const Cfg *Func) const { | 
| 2695   Ostream &Str = Func->getContext()->getStrDump(); | 2664   Ostream &Str = Func->getContext()->getStrDump(); | 
| 2696   Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2665   Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 
| 2697   Str << "ret." << Ty << " "; | 2666   Str << "ret." << Ty << " "; | 
| 2698   dumpSources(Func); | 2667   dumpSources(Func); | 
| 2699 } | 2668 } | 
| 2700 | 2669 | 
| 2701 void InstX8632Xadd::emit(const Cfg *Func) const { | 2670 void InstX8632Xadd::emit(const Cfg *Func) const { | 
| 2702   Ostream &Str = Func->getContext()->getStrEmit(); | 2671   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2703   if (Locked) { | 2672   if (Locked) { | 
| 2704     Str << "\tlock"; | 2673     Str << "\tlock"; | 
| 2705   } | 2674   } | 
| 2706   Str << "\txadd\t"; | 2675   Str << "\txadd\t"; | 
| 2707   getSrc(0)->emit(Func); | 2676   getSrc(0)->emit(Func); | 
| 2708   Str << ", "; | 2677   Str << ", "; | 
| 2709   getSrc(1)->emit(Func); | 2678   getSrc(1)->emit(Func); | 
| 2710   Str << "\n"; |  | 
| 2711 } | 2679 } | 
| 2712 | 2680 | 
| 2713 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2681 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 
| 2714   assert(getSrcSize() == 2); | 2682   assert(getSrcSize() == 2); | 
| 2715   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2683   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2716   intptr_t StartPosition = Asm->GetPosition(); | 2684   intptr_t StartPosition = Asm->GetPosition(); | 
| 2717   Type Ty = getSrc(0)->getType(); | 2685   Type Ty = getSrc(0)->getType(); | 
| 2718   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2686   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 
| 2719   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2687   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 2720   const x86::Address Addr = Mem->toAsmAddress(Asm); | 2688   const x86::Address Addr = Mem->toAsmAddress(Asm); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 2738   Str << "xadd." << Ty << " "; | 2706   Str << "xadd." << Ty << " "; | 
| 2739   dumpSources(Func); | 2707   dumpSources(Func); | 
| 2740 } | 2708 } | 
| 2741 | 2709 | 
| 2742 void InstX8632Xchg::emit(const Cfg *Func) const { | 2710 void InstX8632Xchg::emit(const Cfg *Func) const { | 
| 2743   Ostream &Str = Func->getContext()->getStrEmit(); | 2711   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 2744   Str << "\txchg\t"; | 2712   Str << "\txchg\t"; | 
| 2745   getSrc(0)->emit(Func); | 2713   getSrc(0)->emit(Func); | 
| 2746   Str << ", "; | 2714   Str << ", "; | 
| 2747   getSrc(1)->emit(Func); | 2715   getSrc(1)->emit(Func); | 
| 2748   Str << "\n"; |  | 
| 2749 } | 2716 } | 
| 2750 | 2717 | 
| 2751 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2718 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 
| 2752   assert(getSrcSize() == 2); | 2719   assert(getSrcSize() == 2); | 
| 2753   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2720   x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 
| 2754   intptr_t StartPosition = Asm->GetPosition(); | 2721   intptr_t StartPosition = Asm->GetPosition(); | 
| 2755   Type Ty = getSrc(0)->getType(); | 2722   Type Ty = getSrc(0)->getType(); | 
| 2756   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2723   const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 
| 2757   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2724   assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 
| 2758   const x86::Address Addr = Mem->toAsmAddress(Asm); | 2725   const x86::Address Addr = Mem->toAsmAddress(Asm); | 
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2951   } | 2918   } | 
| 2952   Str << "("; | 2919   Str << "("; | 
| 2953   if (Func) | 2920   if (Func) | 
| 2954     Var->dump(Func); | 2921     Var->dump(Func); | 
| 2955   else | 2922   else | 
| 2956     Var->dump(Str); | 2923     Var->dump(Str); | 
| 2957   Str << ")"; | 2924   Str << ")"; | 
| 2958 } | 2925 } | 
| 2959 | 2926 | 
| 2960 } // end of namespace Ice | 2927 } // end of namespace Ice | 
| OLD | NEW | 
|---|