diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 9fe92ade6fa..f6f486fa9aa 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -309,41 +309,25 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { needCloseParen = true; } - if (Subtarget->isPICStyleStub()) { - // DARWIN/X86-32 in != static mode. - - // Link-once, declaration, or Weakly-linked global variables need - // non-lazily-resolved stubs - if (GV->isDeclaration() || GV->isWeakForLinker()) { - // Dynamically-resolved functions need a stub for the function. - assert(isa(GV)); - - // Function stubs are no longer needed for Mac OS X 10.5 and up. - if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { - O << Name; - } else { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - } - assert(MO.getTargetFlags() == 0); - } else { - O << Name; - } + // Handle dllimport linkage. + if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) + O << "__imp_"; + + if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); } else { - // Handle dllimport linkage. - if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) - O << "__imp_"; O << Name; - - // Assemble call via PLT for externally visible symbols. - if (MO.getTargetFlags() == X86II::MO_PLT) - O << "@PLT"; - - if (Subtarget->isTargetCygMing() && GV->isDeclaration()) - // Save function name for later type emission - CygMingStubs.insert(Name); } + // Assemble call via PLT for externally visible symbols. + if (MO.getTargetFlags() == X86II::MO_PLT) + O << "@PLT"; + + if (Subtarget->isTargetCygMing() && GV->isDeclaration()) + // Save function name for later type emission + CygMingStubs.insert(Name); + printOffset(MO.getOffset()); if (needCloseParen) @@ -355,15 +339,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { bool needCloseParen = false; std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); - // Print function stub suffix unless it's Mac OS X 10.5 and up. - if (Subtarget->isPICStyleStub() && - // DARWIN/X86-32 in != static mode. - Subtarget->getDarwinVers() < 9) { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - return; - } - + if (Name[0] == '$') { // The name begins with a dollar-sign. In order to avoid having it look // like an integer immediate to the assembler, enclose it in parens. @@ -371,7 +347,12 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { needCloseParen = true; } - O << Name; + if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); + } else { + O << Name; + } if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) { O << " + [.-"; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index eba503d8f2a..45ab8eb66fc 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1900,8 +1900,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (GlobalAddressSDNode *G = dyn_cast(Callee)) { // We should use extra load for direct calls to dllimported functions in // non-JIT mode. - if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), - getTargetMachine(), true)) { + GlobalValue *GV = G->getGlobal(); + if (!Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), true)) { unsigned char OpFlags = 0; // On ELF targets, in both X86-64 and X86-32 mode, direct calls to @@ -1910,11 +1910,18 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // we don't need to use the PLT - we can directly call it. if (Subtarget->isTargetELF() && getTargetMachine().getRelocationModel() == Reloc::PIC_ && - G->getGlobal()->hasDefaultVisibility() && - !G->getGlobal()->hasLocalLinkage()) + 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; + } - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy(), + Callee = DAG.getTargetGlobalAddress(GV, getPointerTy(), G->getOffset(), OpFlags); } } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { @@ -1923,9 +1930,16 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // On ELF targets, in either X86-64 or X86-32 mode, direct calls to external // symbols should go through the PLT. if (Subtarget->isTargetELF() && - getTargetMachine().getRelocationModel() == Reloc::PIC_) + getTargetMachine().getRelocationModel() == Reloc::PIC_) { OpFlags = X86II::MO_PLT; - + } else if (Subtarget->isPICStyleStub() && + 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; + } + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), OpFlags); } else if (IsTailCall) { diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 45f358470a0..2336d5698b1 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -154,6 +154,11 @@ namespace X86II { /// dllimport linkage on windows. MO_DLLIMPORT = 12, + /// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the + /// reference is actually to the "FOO$stub" symbol. This is used for calls + /// and jumps to external functions on Tiger and before. + MO_DARWIN_STUB = 13, + //===------------------------------------------------------------------===// // Instruction encodings. These are the standard/most common forms for X86