| 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 {
 | 
| 
 |