Index: src/IceInstX86BaseImpl.h |
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h |
index 96ed422920d8cd36073f9736f48aedb4559ac16d..addb59964479e5e509b8902923405ec8ab2d0491 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 @@ InstImpl<TraitsType>::InstX86FakeRMW::InstX86FakeRMW(Cfg *Func, Operand *Data, |
} |
template <typename TraitsType> |
+InstImpl<TraitsType>::InstX86GetIP::InstX86GetIP(Cfg *Func, Variable *Dest) |
+ : InstX86Base(Func, InstX86Base::GetIP, 0, Dest) {} |
+ |
+template <typename TraitsType> |
InstImpl<TraitsType>::InstX86Mul::InstX86Mul(Cfg *Func, Variable *Dest, |
Variable *Source1, |
Operand *Source2) |
@@ -391,6 +396,55 @@ void InstImpl<TraitsType>::InstX86FakeRMW::dump(const Cfg *Func) const { |
} |
template <typename TraitsType> |
+void InstImpl<TraitsType>::InstX86GetIP::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 <typename TraitsType> |
+void InstImpl<TraitsType>::InstX86GetIP::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"); |
+ } |
+ Assembler *Asm = Func->getAssembler<Assembler>(); |
+ assert(this->getDest()->hasReg()); |
+ GPRRegister Reg = Traits::getEncodedGPR(this->getDest()->getRegNum()); |
+ Constant *GlobalOffsetTable = |
+ Func->getContext()->getConstantExternSym("_GLOBAL_OFFSET_TABLE_"); |
+ AssemblerFixup *Fixup = Asm->createFixup(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. TODO(stichnot): IceType_i32 should really be something that |
+ // represents the target's pointer type. |
+ Asm->add(IceType_i32, Reg, AssemblerImmediate(TempDisp, Fixup)); |
+ 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, AssemblerImmediate(Disp, Fixup)); |
+} |
+ |
+template <typename TraitsType> |
+void InstImpl<TraitsType>::InstX86GetIP::dump(const Cfg *Func) const { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ this->getDest()->dump(Func); |
+ Str << " = call getIP"; |
+} |
+ |
+template <typename TraitsType> |
void InstImpl<TraitsType>::InstX86Label::emit(const Cfg *Func) const { |
if (!BuildDefs::dump()) |
return; |
@@ -679,7 +733,8 @@ void InstImpl<TraitsType>::emitIASRegOpTyGPR(const Cfg *Func, Type Ty, |
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); |
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
- AssemblerFixup *Fixup = Asm->createFixup(Traits::RelFixup, Reloc); |
+ AssemblerFixup *Fixup = |
+ Asm->createFixup(Traits::TargetLowering::getAbsFixup(), Reloc); |
(Asm->*(Emitter.GPRImm))(Ty, VarReg, |
AssemblerImmediate(Reloc->getOffset(), Fixup)); |
} else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) { |
@@ -703,7 +758,8 @@ void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, |
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
(Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); |
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
- AssemblerFixup *Fixup = Asm->createFixup(Traits::RelFixup, Reloc); |
+ AssemblerFixup *Fixup = |
+ Asm->createFixup(Traits::TargetLowering::getAbsFixup(), Reloc); |
(Asm->*(Emitter.AddrImm))(Ty, Addr, |
AssemblerImmediate(Reloc->getOffset(), Fixup)); |
} else { |