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 |