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