diff options
Diffstat (limited to 'lib/Target/Mips/MipsISelLowering.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 65b33c12b8..f9a4d4acff 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2849,12 +2849,14 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25 - bool GlobalOrExternal = false; + bool GlobalOrExternal = false, InternalLinkage = false; SDValue CalleeLo; if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { if (IsPICCall) { - if (G->getGlobal()->hasInternalLinkage()) + InternalLinkage = G->getGlobal()->hasInternalLinkage(); + + if (InternalLinkage) Callee = getAddrLocal(Callee, DAG, HasMips64); else if (LargeGOT) Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16, @@ -2901,8 +2903,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } // Insert node "GP copy globalreg" before call to function. - // Lazy-binding stubs require GP to point to the GOT. - if (IsPICCall) { + // + // R_MIPS_CALL* operators (emitted when non-internal functions are called + // in PIC mode) allow symbols to be resolved via lazy binding. + // The lazy binding stub requires GP to point to the GOT. + if (IsPICCall && !InternalLinkage) { unsigned GPReg = IsN64 ? Mips::GP_64 : Mips::GP; EVT Ty = IsN64 ? MVT::i64 : MVT::i32; RegsToPass.push_back(std::make_pair(GPReg, GetGlobalReg(DAG, Ty))); |