Chromium Code Reviews| Index: src/IceInstX86BaseImpl.h |
| diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h |
| index 2d8f6d17a05f7215d72207a67e07bcf1e14a7e3d..4646a68de46e58650830aaa529bea5492fa23d63 100644 |
| --- a/src/IceInstX86BaseImpl.h |
| +++ b/src/IceInstX86BaseImpl.h |
| @@ -24,6 +24,7 @@ |
| #include "IceInst.h" |
| #include "IceOperand.h" |
| #include "IceTargetLowering.h" |
| +#include "IceTargetLoweringX86Base.h" |
| namespace Ice { |
| @@ -57,6 +58,10 @@ InstX86FakeRMW<Machine>::InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, |
| } |
| template <class Machine> |
| +InstX86GetIP<Machine>::InstX86GetIP(Cfg *Func, Variable *Dest) |
| + : InstX86Base<Machine>(Func, InstX86Base<Machine>::GetIP, 0, Dest) {} |
| + |
| +template <class Machine> |
| InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, |
| Operand *Source2) |
| : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) { |
| @@ -396,6 +401,57 @@ void InstX86FakeRMW<Machine>::dump(const Cfg *Func) const { |
| } |
| template <class Machine> |
| +void InstX86GetIP<Machine>::emit(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + Ostream &Str = Func->getContext()->getStrEmit(); |
| + assert(this->getDest()->hasReg()); |
| + Str << "\t" |
| + "addl\t$_GLOBAL_OFFSET_TABLE_, "; |
| + this->getDest()->emit(Func); |
| +} |
| + |
| +template <class Machine> |
| +void InstX86GetIP<Machine>::emitIAS(const Cfg *Func) const { |
| + if (Func->getContext()->getFlags().getOutFileType() == FT_Iasm) { |
| + // TODO(stichnot): Find a workaround for llvm-mc's inability to handle |
| + // something like ".long _GLOBAL_OFFSET_TABLE_ + ." . One possibility is to |
| + // just use hybrid iasm output for this add instruction. |
| + llvm::report_fatal_error( |
| + "Iasm support for _GLOBAL_OFFSET_TABLE_ not implemented"); |
| + } |
| + typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| + Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| + assert(this->getDest()->hasReg()); |
| + typename InstX86Base<Machine>::Traits::GPRRegister Reg = |
| + InstX86Base<Machine>::Traits::getEncodedGPR(this->getDest()->getRegNum()); |
| + Constant *GlobalOffsetTable = |
| + Func->getContext()->getConstantExternSym("_GLOBAL_OFFSET_TABLE_"); |
| + AssemblerFixup *Fixup = Asm->createFixup( |
| + InstX86Base<Machine>::Traits::FK_GotPC, GlobalOffsetTable); |
| + intptr_t OrigPos = Asm->getBufferSize(); |
| + constexpr int32_t TempDisp = 0; |
| + constexpr int32_t ImmediateWidth = 4; |
| + // Emit the add instruction once, in a preliminary fashion, to find its total |
| + // size. |
| + Asm->add(IceType_i32, Reg, Immediate(TempDisp, Fixup)); |
|
John
2016/01/04 21:33:51
This should really be Traits::PointerType (not cur
Jim Stichnoth
2016/01/04 23:32:12
Done.
|
| + const int32_t Disp = Asm->getBufferSize() - OrigPos - ImmediateWidth; |
| + // Now roll back and emit the add instruction again, this time with the |
| + // correct displacement. |
| + Asm->setBufferSize(OrigPos); |
| + Asm->add(IceType_i32, Reg, Immediate(Disp, Fixup)); |
| +} |
| + |
| +template <class Machine> |
| +void InstX86GetIP<Machine>::dump(const Cfg *Func) const { |
| + if (!BuildDefs::dump()) |
| + return; |
| + Ostream &Str = Func->getContext()->getStrDump(); |
| + this->getDest()->dump(Func); |
| + Str << " = call getIP"; |
| +} |
| + |
| +template <class Machine> |
| void InstX86Label<Machine>::emit(const Cfg *Func) const { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -704,7 +760,7 @@ void emitIASRegOpTyGPR( |
| (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| AssemblerFixup *Fixup = |
| - Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| + Asm->createFixup(TargetX86Base<Machine>::getAbsFixup(), Reloc); |
| (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| } else if (const auto *Split = llvm::dyn_cast< |
| typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| @@ -733,7 +789,7 @@ void emitIASAddrOpTyGPR( |
| (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| AssemblerFixup *Fixup = |
| - Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| + Asm->createFixup(TargetX86Base<Machine>::getAbsFixup(), Reloc); |
| (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| } else { |
| llvm_unreachable("Unexpected operand type"); |