Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// |
| 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 /// \file | 10 /// \file |
| 11 /// \brief Implements the InstX86Base class and its descendants. | 11 /// \brief Implements the InstX86Base class and its descendants. |
| 12 /// | 12 /// |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 15 #ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| 16 #define SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 16 #define SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| 17 | 17 |
| 18 #include "IceInstX86Base.h" | 18 #include "IceInstX86Base.h" |
| 19 | 19 |
| 20 #include "IceAssemblerX86Base.h" | 20 #include "IceAssemblerX86Base.h" |
| 21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
| 22 #include "IceCfgNode.h" | 22 #include "IceCfgNode.h" |
| 23 #include "IceDefs.h" | 23 #include "IceDefs.h" |
| 24 #include "IceInst.h" | 24 #include "IceInst.h" |
| 25 #include "IceOperand.h" | 25 #include "IceOperand.h" |
| 26 #include "IceTargetLowering.h" | 26 #include "IceTargetLowering.h" |
| 27 #include "IceTargetLoweringX86Base.h" | |
| 27 | 28 |
| 28 namespace Ice { | 29 namespace Ice { |
| 29 | 30 |
| 30 namespace X86Internal { | 31 namespace X86Internal { |
| 31 | 32 |
| 32 template <class Machine> | 33 template <class Machine> |
| 33 const char *InstX86Base<Machine>::getWidthString(Type Ty) { | 34 const char *InstX86Base<Machine>::getWidthString(Type Ty) { |
| 34 return Traits::TypeAttributes[Ty].WidthString; | 35 return Traits::TypeAttributes[Ty].WidthString; |
| 35 } | 36 } |
| 36 | 37 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 50 InstArithmetic::OpKind Op, | 51 InstArithmetic::OpKind Op, |
| 51 Variable *Beacon) | 52 Variable *Beacon) |
| 52 : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr), | 53 : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr), |
| 53 Op(Op) { | 54 Op(Op) { |
| 54 this->addSource(Data); | 55 this->addSource(Data); |
| 55 this->addSource(Addr); | 56 this->addSource(Addr); |
| 56 this->addSource(Beacon); | 57 this->addSource(Beacon); |
| 57 } | 58 } |
| 58 | 59 |
| 59 template <class Machine> | 60 template <class Machine> |
| 61 InstX86GetIP<Machine>::InstX86GetIP(Cfg *Func, Variable *Dest) | |
| 62 : InstX86Base<Machine>(Func, InstX86Base<Machine>::GetIP, 0, Dest) {} | |
| 63 | |
| 64 template <class Machine> | |
| 60 InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, | 65 InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, |
| 61 Operand *Source2) | 66 Operand *Source2) |
| 62 : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) { | 67 : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) { |
| 63 this->addSource(Source1); | 68 this->addSource(Source1); |
| 64 this->addSource(Source2); | 69 this->addSource(Source2); |
| 65 } | 70 } |
| 66 | 71 |
| 67 template <class Machine> | 72 template <class Machine> |
| 68 InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, | 73 InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, |
| 69 Operand *Source2) | 74 Operand *Source2) |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 Type Ty = getData()->getType(); | 392 Type Ty = getData()->getType(); |
| 388 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; | 393 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; |
| 389 getAddr()->dump(Func); | 394 getAddr()->dump(Func); |
| 390 Str << ", "; | 395 Str << ", "; |
| 391 getData()->dump(Func); | 396 getData()->dump(Func); |
| 392 Str << ", beacon="; | 397 Str << ", beacon="; |
| 393 getBeacon()->dump(Func); | 398 getBeacon()->dump(Func); |
| 394 } | 399 } |
| 395 | 400 |
| 396 template <class Machine> | 401 template <class Machine> |
| 402 void InstX86GetIP<Machine>::emit(const Cfg *Func) const { | |
| 403 if (!BuildDefs::dump()) | |
| 404 return; | |
| 405 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 406 assert(this->getDest()->hasReg()); | |
| 407 Str << "\t" | |
| 408 "addl\t$_GLOBAL_OFFSET_TABLE_, "; | |
| 409 this->getDest()->emit(Func); | |
| 410 } | |
| 411 | |
| 412 template <class Machine> | |
| 413 void InstX86GetIP<Machine>::emitIAS(const Cfg *Func) const { | |
| 414 if (Func->getContext()->getFlags().getOutFileType() == FT_Iasm) { | |
| 415 // TODO(stichnot): Find a workaround for llvm-mc's inability to handle | |
| 416 // something like ".long _GLOBAL_OFFSET_TABLE_ + ." . One possibility is to | |
| 417 // just use hybrid iasm output for this add instruction. | |
| 418 llvm::report_fatal_error( | |
| 419 "Iasm support for _GLOBAL_OFFSET_TABLE_ not implemented"); | |
| 420 } | |
| 421 typename InstX86Base<Machine>::Traits::Assembler *Asm = | |
| 422 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | |
| 423 assert(this->getDest()->hasReg()); | |
| 424 typename InstX86Base<Machine>::Traits::GPRRegister Reg = | |
| 425 InstX86Base<Machine>::Traits::getEncodedGPR(this->getDest()->getRegNum()); | |
| 426 Constant *GlobalOffsetTable = | |
| 427 Func->getContext()->getConstantExternSym("_GLOBAL_OFFSET_TABLE_"); | |
| 428 AssemblerFixup *Fixup = Asm->createFixup( | |
| 429 InstX86Base<Machine>::Traits::FixupKindGotPC, GlobalOffsetTable); | |
| 430 intptr_t OrigPos = Asm->getBufferSize(); | |
| 431 constexpr int32_t TempDisp = 0; | |
| 432 constexpr int32_t ImmediateWidth = 4; | |
| 433 // Emit the add instruction once, in a preliminary fashion, to find its total | |
| 434 // size. | |
| 435 Asm->add(IceType_i32, Reg, Immediate(TempDisp, Fixup)); | |
|
John
2015/12/22 15:44:38
I believe the assembler will always emit an addl i
Jim Stichnoth
2015/12/28 07:54:07
Right, but the specific issue here is that adding
| |
| 436 const int32_t Disp = Asm->getBufferSize() - OrigPos - ImmediateWidth; | |
| 437 // Now roll back and emit the add instruction again, this time with the | |
| 438 // correct displacement. | |
| 439 Asm->setBufferSize(OrigPos); | |
| 440 Asm->add(IceType_i32, Reg, Immediate(Disp, Fixup)); | |
| 441 } | |
| 442 | |
| 443 template <class Machine> | |
| 444 void InstX86GetIP<Machine>::dump(const Cfg *Func) const { | |
| 445 if (!BuildDefs::dump()) | |
| 446 return; | |
| 447 Ostream &Str = Func->getContext()->getStrDump(); | |
| 448 this->getDest()->dump(Func); | |
| 449 Str << " = call getIP"; | |
| 450 } | |
| 451 | |
| 452 template <class Machine> | |
| 397 void InstX86Label<Machine>::emit(const Cfg *Func) const { | 453 void InstX86Label<Machine>::emit(const Cfg *Func) const { |
| 398 if (!BuildDefs::dump()) | 454 if (!BuildDefs::dump()) |
| 399 return; | 455 return; |
| 400 Ostream &Str = Func->getContext()->getStrEmit(); | 456 Ostream &Str = Func->getContext()->getStrEmit(); |
| 401 Str << getName(Func) << ":"; | 457 Str << getName(Func) << ":"; |
| 402 } | 458 } |
| 403 | 459 |
| 404 template <class Machine> | 460 template <class Machine> |
| 405 void InstX86Label<Machine>::emitIAS(const Cfg *Func) const { | 461 void InstX86Label<Machine>::emitIAS(const Cfg *Func) const { |
| 406 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 462 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 695 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 751 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 696 } | 752 } |
| 697 } else if (const auto *Mem = llvm::dyn_cast< | 753 } else if (const auto *Mem = llvm::dyn_cast< |
| 698 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 754 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 699 Mem->emitSegmentOverride(Asm); | 755 Mem->emitSegmentOverride(Asm); |
| 700 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); | 756 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target)); |
| 701 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 757 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 702 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); | 758 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 703 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 759 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 704 AssemblerFixup *Fixup = | 760 AssemblerFixup *Fixup = |
| 705 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 761 Asm->createFixup(TargetX86Base<Machine>::getRelFixup(), Reloc); |
| 706 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); | 762 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| 707 } else if (const auto *Split = llvm::dyn_cast< | 763 } else if (const auto *Split = llvm::dyn_cast< |
| 708 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { | 764 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| 709 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 765 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 710 } else { | 766 } else { |
| 711 llvm_unreachable("Unexpected operand type"); | 767 llvm_unreachable("Unexpected operand type"); |
| 712 } | 768 } |
| 713 } | 769 } |
| 714 | 770 |
| 715 template <class Machine> | 771 template <class Machine> |
| 716 void emitIASAddrOpTyGPR( | 772 void emitIASAddrOpTyGPR( |
| 717 const Cfg *Func, Type Ty, | 773 const Cfg *Func, Type Ty, |
| 718 const typename InstX86Base<Machine>::Traits::Address &Addr, | 774 const typename InstX86Base<Machine>::Traits::Address &Addr, |
| 719 const Operand *Src, | 775 const Operand *Src, |
| 720 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 776 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| 721 &Emitter) { | 777 &Emitter) { |
| 722 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 778 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 723 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 779 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 724 // Src can only be Reg or Immediate. | 780 // Src can only be Reg or Immediate. |
| 725 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 781 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 726 assert(SrcVar->hasReg()); | 782 assert(SrcVar->hasReg()); |
| 727 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 783 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 728 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); | 784 InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()); |
| 729 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 785 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 730 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 786 } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 731 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); | 787 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| 732 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 788 } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 733 AssemblerFixup *Fixup = | 789 AssemblerFixup *Fixup = |
| 734 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | 790 Asm->createFixup(TargetX86Base<Machine>::getRelFixup(), Reloc); |
| 735 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); | 791 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| 736 } else { | 792 } else { |
| 737 llvm_unreachable("Unexpected operand type"); | 793 llvm_unreachable("Unexpected operand type"); |
| 738 } | 794 } |
| 739 } | 795 } |
| 740 | 796 |
| 741 template <class Machine> | 797 template <class Machine> |
| 742 void emitIASAsAddrOpTyGPR( | 798 void emitIASAsAddrOpTyGPR( |
| 743 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 799 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 744 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 800 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| (...skipping 2276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 return; | 3077 return; |
| 3022 Ostream &Str = Func->getContext()->getStrDump(); | 3078 Ostream &Str = Func->getContext()->getStrDump(); |
| 3023 Str << "IACA_END"; | 3079 Str << "IACA_END"; |
| 3024 } | 3080 } |
| 3025 | 3081 |
| 3026 } // end of namespace X86Internal | 3082 } // end of namespace X86Internal |
| 3027 | 3083 |
| 3028 } // end of namespace Ice | 3084 } // end of namespace Ice |
| 3029 | 3085 |
| 3030 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3086 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |