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, |
11 // primarily the constructors and the dump()/emit() methods. | 11 // primarily the constructors and the dump()/emit() methods. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
| 15 #include "assembler_ia32.h" |
15 #include "IceCfg.h" | 16 #include "IceCfg.h" |
16 #include "IceCfgNode.h" | 17 #include "IceCfgNode.h" |
17 #include "IceConditionCodesX8632.h" | 18 #include "IceConditionCodesX8632.h" |
18 #include "IceInst.h" | 19 #include "IceInst.h" |
19 #include "IceInstX8632.h" | 20 #include "IceInstX8632.h" |
20 #include "IceRegistersX8632.h" | 21 #include "IceRegistersX8632.h" |
21 #include "IceTargetLoweringX8632.h" | 22 #include "IceTargetLoweringX8632.h" |
22 #include "IceOperand.h" | 23 #include "IceOperand.h" |
23 | 24 |
24 namespace Ice { | 25 namespace Ice { |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 } | 325 } |
325 | 326 |
326 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) | 327 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) |
327 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { | 328 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { |
328 addSource(Dest); | 329 addSource(Dest); |
329 addSource(Source); | 330 addSource(Source); |
330 } | 331 } |
331 | 332 |
332 // ======================== Dump routines ======================== // | 333 // ======================== Dump routines ======================== // |
333 | 334 |
| 335 namespace { |
| 336 |
| 337 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, |
| 338 intptr_t StartPosition) { |
| 339 intptr_t EndPosition = Asm->GetPosition(); |
| 340 intptr_t LastFixupLoc = -1; |
| 341 AssemblerFixup *LastFixup = NULL; |
| 342 if (Asm->GetLatestFixup()) { |
| 343 LastFixup = Asm->GetLatestFixup(); |
| 344 LastFixupLoc = LastFixup->position(); |
| 345 } |
| 346 if (LastFixupLoc < StartPosition) { |
| 347 // The fixup doesn't apply to this current block. |
| 348 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) { |
| 349 Str << "\t.byte " |
| 350 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) |
| 351 << "\n"; |
| 352 } |
| 353 return; |
| 354 } |
| 355 const intptr_t FixupSize = 4; |
| 356 assert(LastFixupLoc + FixupSize <= EndPosition); |
| 357 // The fixup does apply to this current block. |
| 358 for (intptr_t i = 0; i < LastFixupLoc - StartPosition; ++i) { |
| 359 Str << "\t.byte " |
| 360 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) |
| 361 << "\n"; |
| 362 } |
| 363 Str << "\t.long " << LastFixup->value()->getName(); |
| 364 if (LastFixup->value()->getOffset()) { |
| 365 Str << " + " << LastFixup->value()->getOffset(); |
| 366 } |
| 367 Str << "\n"; |
| 368 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { |
| 369 Str << "\t.byte " << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(i)) |
| 370 << "\n"; |
| 371 } |
| 372 } |
| 373 |
| 374 } // end of anonymous namespace |
| 375 |
334 void InstX8632::dump(const Cfg *Func) const { | 376 void InstX8632::dump(const Cfg *Func) const { |
335 Ostream &Str = Func->getContext()->getStrDump(); | 377 Ostream &Str = Func->getContext()->getStrDump(); |
336 Str << "[X8632] "; | 378 Str << "[X8632] "; |
337 Inst::dump(Func); | 379 Inst::dump(Func); |
338 } | 380 } |
339 | 381 |
340 void InstX8632Label::emit(const Cfg *Func) const { | 382 void InstX8632Label::emit(const Cfg *Func) const { |
341 Ostream &Str = Func->getContext()->getStrEmit(); | 383 Ostream &Str = Func->getContext()->getStrEmit(); |
342 Str << getName(Func) << ":\n"; | 384 Str << getName(Func) << ":\n"; |
343 } | 385 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { | 471 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { |
430 Str << "cl"; | 472 Str << "cl"; |
431 EmittedSrc1 = true; | 473 EmittedSrc1 = true; |
432 } | 474 } |
433 } | 475 } |
434 if (!EmittedSrc1) | 476 if (!EmittedSrc1) |
435 Inst->getSrc(1)->emit(Func); | 477 Inst->getSrc(1)->emit(Func); |
436 Str << "\n"; | 478 Str << "\n"; |
437 } | 479 } |
438 | 480 |
| 481 void |
| 482 emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 483 const Operand *Src, |
| 484 const x86::AssemblerX86::TypedXmmEmitters &Emitter) { |
| 485 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 486 intptr_t StartPosition = Asm->GetPosition(); |
| 487 assert(Var->hasReg()); |
| 488 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 489 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 490 if (SrcVar->hasReg()) { |
| 491 RegX8632::XmmRegister SrcReg = |
| 492 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 493 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 494 } else { |
| 495 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 496 ->stackVarToAsmOperand(SrcVar); |
| 497 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 498 } |
| 499 } else if (const OperandX8632Mem *Mem = |
| 500 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 501 x86::Address SrcAddr = Mem->toAsmAddress(Asm); |
| 502 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); |
| 503 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 504 (Asm->*(Emitter.XmmAddr))( |
| 505 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 506 } else { |
| 507 llvm_unreachable("Unexpected operand type"); |
| 508 } |
| 509 Ostream &Str = Func->getContext()->getStrEmit(); |
| 510 emitIASBytes(Str, Asm, StartPosition); |
| 511 } |
| 512 |
439 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 513 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
440 const Variable *Src = llvm::dyn_cast<const Variable>(Source); | 514 const Variable *Src = llvm::dyn_cast<const Variable>(Source); |
441 if (Src == NULL) | 515 if (Src == NULL) |
442 return false; | 516 return false; |
443 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { | 517 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { |
444 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 518 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
445 // clear the upper 32 bits of rax. We need to recognize and | 519 // clear the upper 32 bits of rax. We need to recognize and |
446 // preserve these. | 520 // preserve these. |
447 return true; | 521 return true; |
448 } | 522 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 // Ternary ops | 579 // Ternary ops |
506 template <> const char *InstX8632Insertps::Opcode = "insertps"; | 580 template <> const char *InstX8632Insertps::Opcode = "insertps"; |
507 template <> const char *InstX8632Shufps::Opcode = "shufps"; | 581 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
508 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 582 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
509 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 583 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
510 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 584 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
511 // Three address ops | 585 // Three address ops |
512 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 586 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
513 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 587 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
514 | 588 |
| 589 // Binary XMM ops |
| 590 template <> |
| 591 const x86::AssemblerX86::TypedXmmEmitters InstX8632Addss::Emitter = { |
| 592 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; |
| 593 template <> |
| 594 const x86::AssemblerX86::TypedXmmEmitters InstX8632Addps::Emitter = { |
| 595 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; |
| 596 template <> |
| 597 const x86::AssemblerX86::TypedXmmEmitters InstX8632Divss::Emitter = { |
| 598 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; |
| 599 template <> |
| 600 const x86::AssemblerX86::TypedXmmEmitters InstX8632Divps::Emitter = { |
| 601 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL}; |
| 602 template <> |
| 603 const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulss::Emitter = { |
| 604 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL}; |
| 605 template <> |
| 606 const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulps::Emitter = { |
| 607 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL}; |
| 608 template <> |
| 609 const x86::AssemblerX86::TypedXmmEmitters InstX8632Padd::Emitter = { |
| 610 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL}; |
| 611 template <> |
| 612 const x86::AssemblerX86::TypedXmmEmitters InstX8632Pand::Emitter = { |
| 613 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL}; |
| 614 template <> |
| 615 const x86::AssemblerX86::TypedXmmEmitters InstX8632Pandn::Emitter = { |
| 616 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; |
| 617 template <> |
| 618 const x86::AssemblerX86::TypedXmmEmitters InstX8632Pmuludq::Emitter = { |
| 619 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; |
| 620 template <> |
| 621 const x86::AssemblerX86::TypedXmmEmitters InstX8632Por::Emitter = { |
| 622 &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; |
| 623 template <> |
| 624 const x86::AssemblerX86::TypedXmmEmitters InstX8632Psub::Emitter = { |
| 625 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; |
| 626 template <> |
| 627 const x86::AssemblerX86::TypedXmmEmitters InstX8632Pxor::Emitter = { |
| 628 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; |
| 629 template <> |
| 630 const x86::AssemblerX86::TypedXmmEmitters InstX8632Sqrtss::Emitter = { |
| 631 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; |
| 632 template <> |
| 633 const x86::AssemblerX86::TypedXmmEmitters InstX8632Subss::Emitter = { |
| 634 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; |
| 635 template <> |
| 636 const x86::AssemblerX86::TypedXmmEmitters InstX8632Subps::Emitter = { |
| 637 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; |
| 638 |
515 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 639 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
516 Ostream &Str = Func->getContext()->getStrEmit(); | 640 Ostream &Str = Func->getContext()->getStrEmit(); |
517 assert(getSrcSize() == 1); | 641 assert(getSrcSize() == 1); |
518 Type Ty = getSrc(0)->getType(); | 642 Type Ty = getSrc(0)->getType(); |
519 assert(Ty == IceType_f32 || Ty == IceType_f64); | 643 assert(Ty == IceType_f32 || Ty == IceType_f64); |
520 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 644 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
521 getDest()->emit(Func); | 645 getDest()->emit(Func); |
522 Str << ", "; | 646 Str << ", "; |
523 getSrc(0)->emit(Func); | 647 getSrc(0)->emit(Func); |
524 Str << "\n"; | 648 Str << "\n"; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 assert(Condition < CondX86::Cmpps_Invalid); | 907 assert(Condition < CondX86::Cmpps_Invalid); |
784 Str << "\t"; | 908 Str << "\t"; |
785 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 909 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
786 << "\t"; | 910 << "\t"; |
787 getDest()->emit(Func); | 911 getDest()->emit(Func); |
788 Str << ", "; | 912 Str << ", "; |
789 getSrc(1)->emit(Func); | 913 getSrc(1)->emit(Func); |
790 Str << "\n"; | 914 Str << "\n"; |
791 } | 915 } |
792 | 916 |
| 917 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 918 Ostream &Str = Func->getContext()->getStrEmit(); |
| 919 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 920 intptr_t StartPosition = Asm->GetPosition(); |
| 921 assert(getSrcSize() == 2); |
| 922 assert(Condition < CondX86::Cmpps_Invalid); |
| 923 // Assuming there isn't any load folding for cmpps, and vector constants |
| 924 // are not allowed in PNaCl. |
| 925 assert(llvm::isa<Variable>(getSrc(1))); |
| 926 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 927 if (SrcVar->hasReg()) { |
| 928 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
| 929 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 930 } else { |
| 931 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 932 ->stackVarToAsmOperand(SrcVar); |
| 933 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 934 Condition); |
| 935 } |
| 936 emitIASBytes(Str, Asm, StartPosition); |
| 937 } |
| 938 |
793 void InstX8632Cmpps::dump(const Cfg *Func) const { | 939 void InstX8632Cmpps::dump(const Cfg *Func) const { |
794 Ostream &Str = Func->getContext()->getStrDump(); | 940 Ostream &Str = Func->getContext()->getStrDump(); |
795 assert(Condition < CondX86::Cmpps_Invalid); | 941 assert(Condition < CondX86::Cmpps_Invalid); |
796 dumpDest(Func); | 942 dumpDest(Func); |
797 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 943 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
798 << "\t"; | 944 << "\t"; |
799 dumpSources(Func); | 945 dumpSources(Func); |
800 } | 946 } |
801 | 947 |
802 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 948 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 Ostream &Str = Func->getContext()->getStrEmit(); | 1032 Ostream &Str = Func->getContext()->getStrEmit(); |
887 assert(getSrcSize() == 2); | 1033 assert(getSrcSize() == 2); |
888 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1034 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
889 << "\t"; | 1035 << "\t"; |
890 getSrc(0)->emit(Func); | 1036 getSrc(0)->emit(Func); |
891 Str << ", "; | 1037 Str << ", "; |
892 getSrc(1)->emit(Func); | 1038 getSrc(1)->emit(Func); |
893 Str << "\n"; | 1039 Str << "\n"; |
894 } | 1040 } |
895 | 1041 |
| 1042 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
| 1043 assert(getSrcSize() == 2); |
| 1044 // Currently src0 is always a variable by convention, to avoid having |
| 1045 // two memory operands. |
| 1046 assert(llvm::isa<Variable>(getSrc(0))); |
| 1047 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
| 1048 Type Ty = Src0->getType(); |
| 1049 const static x86::AssemblerX86::TypedXmmEmitters Emitter = { |
| 1050 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL}; |
| 1051 emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter); |
| 1052 } |
| 1053 |
896 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1054 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
897 Ostream &Str = Func->getContext()->getStrDump(); | 1055 Ostream &Str = Func->getContext()->getStrDump(); |
898 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1056 Str << "ucomiss." << getSrc(0)->getType() << " "; |
899 dumpSources(Func); | 1057 dumpSources(Func); |
900 } | 1058 } |
901 | 1059 |
902 void InstX8632UD2::emit(const Cfg *Func) const { | 1060 void InstX8632UD2::emit(const Cfg *Func) const { |
903 Ostream &Str = Func->getContext()->getStrEmit(); | 1061 Ostream &Str = Func->getContext()->getStrEmit(); |
904 assert(getSrcSize() == 0); | 1062 assert(getSrcSize() == 0); |
905 Str << "\tud2\n"; | 1063 Str << "\tud2\n"; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 Str << ", "; | 1284 Str << ", "; |
1127 dumpSources(Func); | 1285 dumpSources(Func); |
1128 } | 1286 } |
1129 | 1287 |
1130 void InstX8632Nop::emit(const Cfg *Func) const { | 1288 void InstX8632Nop::emit(const Cfg *Func) const { |
1131 Ostream &Str = Func->getContext()->getStrEmit(); | 1289 Ostream &Str = Func->getContext()->getStrEmit(); |
1132 // TODO: Emit the right code for each variant. | 1290 // TODO: Emit the right code for each variant. |
1133 Str << "\tnop\t# variant = " << Variant << "\n"; | 1291 Str << "\tnop\t# variant = " << Variant << "\n"; |
1134 } | 1292 } |
1135 | 1293 |
| 1294 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 1295 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1296 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1297 intptr_t StartPosition = Asm->GetPosition(); |
| 1298 // TODO: Emit the right code for the variant. |
| 1299 Asm->nop(); |
| 1300 emitIASBytes(Str, Asm, StartPosition); |
| 1301 } |
| 1302 |
1136 void InstX8632Nop::dump(const Cfg *Func) const { | 1303 void InstX8632Nop::dump(const Cfg *Func) const { |
1137 Ostream &Str = Func->getContext()->getStrDump(); | 1304 Ostream &Str = Func->getContext()->getStrDump(); |
1138 Str << "nop (variant = " << Variant << ")"; | 1305 Str << "nop (variant = " << Variant << ")"; |
1139 } | 1306 } |
1140 | 1307 |
1141 void InstX8632Fld::emit(const Cfg *Func) const { | 1308 void InstX8632Fld::emit(const Cfg *Func) const { |
1142 Ostream &Str = Func->getContext()->getStrEmit(); | 1309 Ostream &Str = Func->getContext()->getStrEmit(); |
1143 assert(getSrcSize() == 1); | 1310 assert(getSrcSize() == 1); |
1144 Type Ty = getSrc(0)->getType(); | 1311 Type Ty = getSrc(0)->getType(); |
1145 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1312 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 } | 1432 } |
1266 | 1433 |
1267 void InstX8632Pop::emit(const Cfg *Func) const { | 1434 void InstX8632Pop::emit(const Cfg *Func) const { |
1268 Ostream &Str = Func->getContext()->getStrEmit(); | 1435 Ostream &Str = Func->getContext()->getStrEmit(); |
1269 assert(getSrcSize() == 0); | 1436 assert(getSrcSize() == 0); |
1270 Str << "\tpop\t"; | 1437 Str << "\tpop\t"; |
1271 getDest()->emit(Func); | 1438 getDest()->emit(Func); |
1272 Str << "\n"; | 1439 Str << "\n"; |
1273 } | 1440 } |
1274 | 1441 |
| 1442 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 1443 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1444 assert(getSrcSize() == 0); |
| 1445 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1446 intptr_t StartPosition = Asm->GetPosition(); |
| 1447 if (getDest()->hasReg()) { |
| 1448 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
| 1449 } else { |
| 1450 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1451 ->stackVarToAsmOperand(getDest())); |
| 1452 } |
| 1453 emitIASBytes(Str, Asm, StartPosition); |
| 1454 } |
| 1455 |
1275 void InstX8632Pop::dump(const Cfg *Func) const { | 1456 void InstX8632Pop::dump(const Cfg *Func) const { |
1276 Ostream &Str = Func->getContext()->getStrDump(); | 1457 Ostream &Str = Func->getContext()->getStrDump(); |
1277 dumpDest(Func); | 1458 dumpDest(Func); |
1278 Str << " = pop." << getDest()->getType() << " "; | 1459 Str << " = pop." << getDest()->getType() << " "; |
1279 } | 1460 } |
1280 | 1461 |
1281 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 1462 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
1282 Ostream &Str = Func->getContext()->getStrEmit(); | 1463 Ostream &Str = Func->getContext()->getStrEmit(); |
1283 Str << "\tsub\tesp, " << Amount << "\n"; | 1464 Str << "\tsub\tesp, " << Amount << "\n"; |
1284 Func->getTarget()->updateStackAdjustment(Amount); | 1465 Func->getTarget()->updateStackAdjustment(Amount); |
1285 } | 1466 } |
1286 | 1467 |
| 1468 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| 1469 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1470 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1471 intptr_t StartPosition = Asm->GetPosition(); |
| 1472 Asm->subl(RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
| 1473 emitIASBytes(Str, Asm, StartPosition); |
| 1474 Func->getTarget()->updateStackAdjustment(Amount); |
| 1475 } |
| 1476 |
1287 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 1477 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
1288 Ostream &Str = Func->getContext()->getStrDump(); | 1478 Ostream &Str = Func->getContext()->getStrDump(); |
1289 Str << "esp = sub.i32 esp, " << Amount; | 1479 Str << "esp = sub.i32 esp, " << Amount; |
1290 } | 1480 } |
1291 | 1481 |
1292 void InstX8632Push::emit(const Cfg *Func) const { | 1482 void InstX8632Push::emit(const Cfg *Func) const { |
1293 Ostream &Str = Func->getContext()->getStrEmit(); | 1483 Ostream &Str = Func->getContext()->getStrEmit(); |
1294 assert(getSrcSize() == 1); | 1484 assert(getSrcSize() == 1); |
1295 Type Ty = getSrc(0)->getType(); | 1485 Type Ty = getSrc(0)->getType(); |
1296 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1486 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 1539 snprintf(buf, llvm::array_lengthof(buf), "psra%s", |
1350 TypeX8632Attributes[getDest()->getType()].PackString); | 1540 TypeX8632Attributes[getDest()->getType()].PackString); |
1351 emitTwoAddress(buf, this, Func); | 1541 emitTwoAddress(buf, this, Func); |
1352 } | 1542 } |
1353 | 1543 |
1354 void InstX8632Ret::emit(const Cfg *Func) const { | 1544 void InstX8632Ret::emit(const Cfg *Func) const { |
1355 Ostream &Str = Func->getContext()->getStrEmit(); | 1545 Ostream &Str = Func->getContext()->getStrEmit(); |
1356 Str << "\tret\n"; | 1546 Str << "\tret\n"; |
1357 } | 1547 } |
1358 | 1548 |
| 1549 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 1550 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1551 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1552 intptr_t StartPosition = Asm->GetPosition(); |
| 1553 Asm->ret(); |
| 1554 emitIASBytes(Str, Asm, StartPosition); |
| 1555 } |
| 1556 |
1359 void InstX8632Ret::dump(const Cfg *Func) const { | 1557 void InstX8632Ret::dump(const Cfg *Func) const { |
1360 Ostream &Str = Func->getContext()->getStrDump(); | 1558 Ostream &Str = Func->getContext()->getStrDump(); |
1361 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 1559 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
1362 Str << "ret." << Ty << " "; | 1560 Str << "ret." << Ty << " "; |
1363 dumpSources(Func); | 1561 dumpSources(Func); |
1364 } | 1562 } |
1365 | 1563 |
1366 void InstX8632Xadd::emit(const Cfg *Func) const { | 1564 void InstX8632Xadd::emit(const Cfg *Func) const { |
1367 Ostream &Str = Func->getContext()->getStrEmit(); | 1565 Ostream &Str = Func->getContext()->getStrEmit(); |
1368 if (Locked) { | 1566 if (Locked) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 Str << "+"; | 1689 Str << "+"; |
1492 Offset->dump(Func, Str); | 1690 Offset->dump(Func, Str); |
1493 } | 1691 } |
1494 } else { | 1692 } else { |
1495 // There is only the offset. | 1693 // There is only the offset. |
1496 Offset->dump(Func, Str); | 1694 Offset->dump(Func, Str); |
1497 } | 1695 } |
1498 Str << "]"; | 1696 Str << "]"; |
1499 } | 1697 } |
1500 | 1698 |
| 1699 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
| 1700 int32_t Disp = 0; |
| 1701 AssemblerFixup *Fixup = NULL; |
| 1702 // Determine the offset (is it relocatable?) |
| 1703 if (getOffset()) { |
| 1704 if (ConstantInteger32 *CI = |
| 1705 llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 1706 Disp = static_cast<int32_t>(CI->getValue()); |
| 1707 } else if (ConstantRelocatable *CR = |
| 1708 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 1709 // TODO(jvoung): CR + non-zero-offset isn't really tested yet, |
| 1710 // since the addressing mode optimization doesn't try to combine |
| 1711 // ConstantRelocatable with something else. |
| 1712 assert(CR->getOffset() == 0); |
| 1713 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); |
| 1714 } else { |
| 1715 llvm_unreachable("Unexpected offset type"); |
| 1716 } |
| 1717 } |
| 1718 |
| 1719 // Now convert to the various possible forms. |
| 1720 if (getBase() && getIndex()) { |
| 1721 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 1722 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 1723 x86::ScaleFactor(getShift()), Disp); |
| 1724 } else if (getBase()) { |
| 1725 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); |
| 1726 } else if (getIndex()) { |
| 1727 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 1728 x86::ScaleFactor(getShift()), Disp); |
| 1729 } else { |
| 1730 return x86::Address::Absolute(Disp, Fixup); |
| 1731 } |
| 1732 } |
| 1733 |
1501 void VariableSplit::emit(const Cfg *Func) const { | 1734 void VariableSplit::emit(const Cfg *Func) const { |
1502 Ostream &Str = Func->getContext()->getStrEmit(); | 1735 Ostream &Str = Func->getContext()->getStrEmit(); |
1503 assert(!Var->hasReg()); | 1736 assert(!Var->hasReg()); |
1504 // The following is copied/adapted from TargetX8632::emitVariable(). | 1737 // The following is copied/adapted from TargetX8632::emitVariable(). |
1505 const TargetLowering *Target = Func->getTarget(); | 1738 const TargetLowering *Target = Func->getTarget(); |
1506 const Type Ty = IceType_i32; | 1739 const Type Ty = IceType_i32; |
1507 Str << TypeX8632Attributes[Ty].WidthString << " [" | 1740 Str << TypeX8632Attributes[Ty].WidthString << " [" |
1508 << Target->getRegName(Target->getFrameOrStackReg(), Ty); | 1741 << Target->getRegName(Target->getFrameOrStackReg(), Ty); |
1509 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); | 1742 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); |
1510 if (Part == High) | 1743 if (Part == High) |
(...skipping 20 matching lines...) Expand all Loading... |
1531 } | 1764 } |
1532 Str << "("; | 1765 Str << "("; |
1533 if (Func) | 1766 if (Func) |
1534 Var->dump(Func); | 1767 Var->dump(Func); |
1535 else | 1768 else |
1536 Var->dump(Str); | 1769 Var->dump(Str); |
1537 Str << ")"; | 1770 Str << ")"; |
1538 } | 1771 } |
1539 | 1772 |
1540 } // end of namespace Ice | 1773 } // end of namespace Ice |
OLD | NEW |