diff options
author | Chris Lattner <sabre@nondot.org> | 2009-07-09 06:34:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-07-09 06:34:26 +0000 |
commit | 51e8eabd3c50fc60e909cbd1729a8698c267beb2 (patch) | |
tree | 0efe6b91c4b2a9a815e7d8557a539b2f04076f43 /lib | |
parent | 485ded0db71b2abe51da919bd58501cee345c443 (diff) |
make direct calls set MO_PLT or MO_DARWIN_STUB as appropriate with fast isel.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75112 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86FastISel.cpp | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 58f5b988b0..31cb5a1a1b 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -1300,14 +1300,43 @@ bool X86FastISel::X86SelectCall(Instruction *I) { assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted; Emitted = true; } - + // Issue the call. - unsigned CallOpc = CalleeOp - ? (Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r) - : (Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32); - MachineInstrBuilder MIB = CalleeOp - ? BuildMI(MBB, DL, TII.get(CallOpc)).addReg(CalleeOp) - : BuildMI(MBB, DL, TII.get(CallOpc)).addGlobalAddress(GV); + MachineInstrBuilder MIB; + if (CalleeOp) { + // Register-indirect call. + unsigned CallOpc = Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r; + MIB = BuildMI(MBB, DL, TII.get(CallOpc)).addReg(CalleeOp); + + } else { + // Direct call. + assert(GV && "Not a direct call"); + unsigned CallOpc = + Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32; + + // See if we need any target-specific flags on the GV operand. + unsigned char OpFlags = 0; + + // On ELF targets, in both X86-64 and X86-32 mode, direct calls to + // external symbols most go through the PLT in PIC mode. If the symbol + // has hidden or protected visibility, or if it is static or local, then + // we don't need to use the PLT - we can directly call it. + if (Subtarget->isTargetELF() && + TM.getRelocationModel() == Reloc::PIC_ && + GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) { + OpFlags = X86II::MO_PLT; + } else if (Subtarget->isPICStyleStub() && + (GV->isDeclaration() || GV->isWeakForLinker()) && + Subtarget->getDarwinVers() < 9) { + // PC-relative references to external symbols should go through $stub, + // unless we're building with the leopard linker or later, which + // automatically synthesizes these stubs. + OpFlags = X86II::MO_DARWIN_STUB; + } + + + MIB = BuildMI(MBB, DL, TII.get(CallOpc)).addGlobalAddress(GV, 0, OpFlags); + } // Add an implicit use GOT pointer in EBX. if (Subtarget->isPICStyleGOT()) |