Chromium Code Reviews| 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(); |
|
Jim Stichnoth
2016/02/03 23:18:27
const Variable *
|
| + 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(); |
|
Jim Stichnoth
2016/02/03 23:18:27
const Variable *
|
| 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"); |
| } |