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