| Index: src/IceInstX86BaseImpl.h
|
| diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
|
| index caa8cd1a8c5d230a69c744f6ddb05b6b193fe5c0..f360946d50e1a8c6549b0644eb21514ecc040dd4 100644
|
| --- a/src/IceInstX86BaseImpl.h
|
| +++ b/src/IceInstX86BaseImpl.h
|
| @@ -403,40 +403,23 @@ template <typename TraitsType>
|
| void InstImpl<TraitsType>::InstX86GetIP::emit(const Cfg *Func) const {
|
| if (!BuildDefs::dump())
|
| return;
|
| + const auto *Dest = this->getDest();
|
| + assert(Dest->hasReg());
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| - assert(this->getDest()->hasReg());
|
| Str << "\t"
|
| - "addl\t$_GLOBAL_OFFSET_TABLE_, ";
|
| - this->getDest()->emit(Func);
|
| + "call"
|
| + "\t";
|
| + auto *Target = static_cast<TargetLowering *>(Func->getTarget());
|
| + Target->emitWithoutPrefix(Target->createGetIPForRegister(Dest));
|
| }
|
|
|
| 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");
|
| - }
|
| + const auto *Dest = this->getDest();
|
| 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));
|
| + assert(Dest->hasReg());
|
| + Asm->call(static_cast<TargetLowering *>(Func->getTarget())
|
| + ->createGetIPForRegister(Dest));
|
| }
|
|
|
| template <typename TraitsType>
|
| @@ -595,7 +578,6 @@ void InstImpl<TraitsType>::InstX86Jmp::emitIAS(const Cfg *Func) const {
|
| assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
|
| llvm::report_fatal_error("Assembler can't jmp to memory operand");
|
| } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
|
| - assert(CR->getOffset() == 0 && "We only support jumping to a function");
|
| Asm->jmp(CR);
|
| } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
|
| // NaCl trampoline calls refer to an address within the sandbox directly.
|
| @@ -653,7 +635,6 @@ void InstImpl<TraitsType>::InstX86Call::emitIAS(const Cfg *Func) const {
|
| assert(Mem->getSegmentRegister() == X86OperandMem::DefaultSegment);
|
| Asm->call(Mem->toAsmAddress(Asm, Target));
|
| } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(CallTarget)) {
|
| - assert(CR->getOffset() == 0 && "We only support calling a function");
|
| Asm->call(CR);
|
| } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(CallTarget)) {
|
| Asm->call(AssemblerImmediate(Imm->getValue()));
|
| @@ -748,10 +729,11 @@ void InstImpl<TraitsType>::emitIASRegOpTyGPR(const Cfg *Func, bool IsLea,
|
| } 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::TargetLowering::getAbsFixup(), Reloc);
|
| - (Asm->*(Emitter.GPRImm))(Ty, VarReg,
|
| - AssemblerImmediate(Reloc->getOffset(), Fixup));
|
| + const auto FixupKind = Reloc->getName() == GlobalOffsetTable
|
| + ? Traits::FK_GotPC
|
| + : Traits::TargetLowering::getAbsFixup();
|
| + AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
|
| + (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Fixup));
|
| } else if (const auto *Split = llvm::dyn_cast<VariableSplit>(Src)) {
|
| (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
|
| } else {
|
| @@ -773,10 +755,11 @@ 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::TargetLowering::getAbsFixup(), Reloc);
|
| - (Asm->*(Emitter.AddrImm))(Ty, Addr,
|
| - AssemblerImmediate(Reloc->getOffset(), Fixup));
|
| + const auto FixupKind = Reloc->getName() == GlobalOffsetTable
|
| + ? Traits::FK_GotPC
|
| + : Traits::TargetLowering::getAbsFixup();
|
| + AssemblerFixup *Fixup = Asm->createFixup(FixupKind, Reloc);
|
| + (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Fixup));
|
| } else {
|
| llvm_unreachable("Unexpected operand type");
|
| }
|
|
|