diff options
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPC.h | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 77 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCMCInstLower.cpp | 112 | 
4 files changed, 172 insertions, 35 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC.h b/llvm/lib/Target/PowerPC/PPC.h index 24e2710a15c..e3c071c4479 100644 --- a/llvm/lib/Target/PowerPC/PPC.h +++ b/llvm/lib/Target/PowerPC/PPC.h @@ -39,6 +39,22 @@ void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,  extern Target ThePPC32Target;  extern Target ThePPC64Target; +  namespace PPCII { +     +  /// Target Operand Flag enum. +  enum TOF { +    //===------------------------------------------------------------------===// +    // PPC Specific MachineOperand flags. +    MO_NO_FLAG, +     +    /// 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 earlier. +    MO_DARWIN_STUB +     +  }; +  } // end namespace PPCII +    } // end namespace llvm;  // Defines symbolic names for PowerPC registers.  This defines a mapping from diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index c1120d4f350..436a30241f8 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2451,7 +2451,11 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,                       SDValue &Chain, DebugLoc dl, int SPDiff, bool isTailCall,                       SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,                       SmallVector<SDValue, 8> &Ops, std::vector<EVT> &NodeTys, -                     bool isPPC64, bool isSVR4ABI) { +                     const PPCSubtarget &PPCSubTarget) { +   +  bool isPPC64 = PPCSubTarget.isPPC64(); +  bool isSVR4ABI = PPCSubTarget.isSVR4ABI(); +    EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();    NodeTys.push_back(MVT::Other);   // Returns a chain    NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use. @@ -2464,24 +2468,49 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,      Callee = SDValue(Dest, 0);      needIndirectCall = false;    } -  // XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201 -  // Use indirect calls for ALL functions calls in JIT mode, since the -  // far-call stubs may be outside relocation limits for a BL instruction. -  if (!DAG.getTarget().getSubtarget<PPCSubtarget>().isJITCodeModel()) { -    // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every -    // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol -    // node so that legalize doesn't hack it. -    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { +   +  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { +    // XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201 +    // Use indirect calls for ALL functions calls in JIT mode, since the +    // far-call stubs may be outside relocation limits for a BL instruction. +    if (!DAG.getTarget().getSubtarget<PPCSubtarget>().isJITCodeModel()) { +      unsigned OpFlags = 0; +      if (DAG.getTarget().getRelocationModel() != Reloc::Static && +          PPCSubTarget.getDarwinVers() < 9 && +          (G->getGlobal()->isDeclaration() || +           G->getGlobal()->isWeakForLinker())) { +        // 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 = PPCII::MO_DARWIN_STUB; +      } +       +      // If the callee is a GlobalAddress/ExternalSymbol node (quite common, +      // every direct call is) turn it into a TargetGlobalAddress / +      // TargetExternalSymbol node so that legalize doesn't hack it.        Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, -            Callee.getValueType()); +                                          Callee.getValueType(), +                                          0, OpFlags);        needIndirectCall = false; -    } +    }                   } +      if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { -      Callee = DAG.getTargetExternalSymbol(S->getSymbol(), -             Callee.getValueType()); -      needIndirectCall = false; +    unsigned char OpFlags = 0; +     +    if (DAG.getTarget().getRelocationModel() != Reloc::Static && +        PPCSubTarget.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 = PPCII::MO_DARWIN_STUB; +    } +     +    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(), +                                         OpFlags); +    needIndirectCall = false;    } +      if (needIndirectCall) {      // Otherwise, this is an indirect call.  We have to use a MTCTR/BCTRL pair      // to do the call, we can't use PPCISD::CALL. @@ -2628,8 +2657,7 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,    SmallVector<SDValue, 8> Ops;    unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, dl, SPDiff,                                   isTailCall, RegsToPass, Ops, NodeTys, -                                 PPCSubTarget.isPPC64(), -                                 PPCSubTarget.isSVR4ABI()); +                                 PPCSubTarget);    // When performing tail call optimization the callee pops its arguments off    // the stack. Account for this here so these bytes can be pushed back on in @@ -2717,15 +2745,14 @@ PPCTargetLowering::LowerCall(SDValue Chain, SDValue Callee,      isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,                                                     Ins, DAG); -  if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) { +  if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64())      return LowerCall_SVR4(Chain, Callee, CallConv, isVarArg,                            isTailCall, Outs, OutVals, Ins,                            dl, DAG, InVals); -  } else { -    return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg, -                            isTailCall, Outs, OutVals, Ins, -                            dl, DAG, InVals); -  } + +  return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg, +                          isTailCall, Outs, OutVals, Ins, +                          dl, DAG, InVals);  }  SDValue @@ -2924,10 +2951,9 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee,      InFlag = Chain.getValue(1);    } -  if (isTailCall) { +  if (isTailCall)      PrepareTailCall(DAG, InFlag, Chain, dl, false, SPDiff, NumBytes, LROp, FPOp,                      false, TailCallArguments); -  }    return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,                      RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, @@ -3293,10 +3319,9 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,      InFlag = Chain.getValue(1);    } -  if (isTailCall) { +  if (isTailCall)      PrepareTailCall(DAG, InFlag, Chain, dl, isPPC64, SPDiff, NumBytes, LROp,                      FPOp, true, TailCallArguments); -  }    return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,                      RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index fc7b7b3cb89..92369d6f1d7 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -58,7 +58,7 @@ enum PPC970_Unit {    PPC970_VPERM  = 6 << PPC970_Shift,   // Vector Permute Unit    PPC970_BRU    = 7 << PPC970_Shift    // Branch Unit  }; -} +} // end namespace PPCII  class PPCInstrInfo : public TargetInstrInfoImpl { diff --git a/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp b/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp index 6a753cf5f40..f7a9ba9cdfc 100644 --- a/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp +++ b/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp @@ -15,26 +15,125 @@  #include "PPC.h"  #include "llvm/CodeGen/AsmPrinter.h"  #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineModuleInfoImpls.h" +#include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCExpr.h"  #include "llvm/MC/MCInst.h"  #include "llvm/Target/Mangler.h" +#include "llvm/ADT/SmallString.h"  using namespace llvm; +static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { +  return AP.MMI->getObjFileInfo<MachineModuleInfoMachO>(); +} + + +static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ +  MCContext &Ctx = AP.OutContext; + +  SmallString<128> Name; +  if (!MO.isGlobal()) { +    assert(MO.isSymbol() && "Isn't a symbol reference"); +    Name += AP.MAI->getGlobalPrefix(); +    Name += MO.getSymbolName(); +  } else {     +    const GlobalValue *GV = MO.getGlobal(); +    bool isImplicitlyPrivate = false; +    if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB || +        //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY || +        //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY_PIC_BASE || +        //MO.getTargetFlags() == PPCII::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE +        0) +      isImplicitlyPrivate = true; +     +    AP.Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); +  } +   +  // If the target flags on the operand changes the name of the symbol, do that +  // before we return the symbol. +  switch (MO.getTargetFlags()) { +  default: break; +#if 0 +  case X86II::MO_DARWIN_NONLAZY: +  case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { +    Name += "$non_lazy_ptr"; +    MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); +     +    MachineModuleInfoImpl::StubValueTy &StubSym = +      getMachOMMI(AP).getGVStubEntry(Sym); +    if (StubSym.getPointer() == 0) { +      assert(MO.isGlobal() && "Extern symbol not handled yet"); +      StubSym = +      MachineModuleInfoImpl:: +      StubValueTy(Mang->getSymbol(MO.getGlobal()), +                  !MO.getGlobal()->hasInternalLinkage()); +    } +    return Sym; +  } +  case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { +    Name += "$non_lazy_ptr"; +    MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); +    MachineModuleInfoImpl::StubValueTy &StubSym = +      getMachOMMI(AP).getHiddenGVStubEntry(Sym); +    if (StubSym.getPointer() == 0) { +      assert(MO.isGlobal() && "Extern symbol not handled yet"); +      StubSym = +      MachineModuleInfoImpl:: +      StubValueTy(Mang->getSymbol(MO.getGlobal()), +                  !MO.getGlobal()->hasInternalLinkage()); +    } +    return Sym; +  } +#endif +  case PPCII::MO_DARWIN_STUB: { +    Name += "$stub"; +    MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); +    MachineModuleInfoImpl::StubValueTy &StubSym = +      getMachOMMI(AP).getFnStubEntry(Sym); +    if (StubSym.getPointer()) +      return Sym; +     +    if (MO.isGlobal()) { +      StubSym = +      MachineModuleInfoImpl:: +      StubValueTy(AP.Mang->getSymbol(MO.getGlobal()), +                  !MO.getGlobal()->hasInternalLinkage()); +    } else { +      Name.erase(Name.end()-5, Name.end()); +      StubSym = +      MachineModuleInfoImpl:: +      StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); +    } +    return Sym; +  } +  } +   +  return Ctx.GetOrCreateSymbol(Name.str()); +} +  static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,                                AsmPrinter &Printer) {    MCContext &Ctx = Printer.OutContext; -  const MCExpr *Expr; +  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; + +  const MCExpr *Expr = 0;    switch (MO.getTargetFlags()) {    default: assert(0 && "Unknown target flag on symbol operand"); -  case 0: -    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx); +  case PPCII::MO_NO_FLAG: +  // These affect the name of the symbol, not any suffix. +  case PPCII::MO_DARWIN_STUB:      break; +        #if 0 -  case ARMII::MO_LO16: +  case PPCII::MO_LO16:      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);      break;  #endif    } + +  if (Expr == 0) +    Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); +    if (!MO.isJTI() && MO.getOffset())      Expr = MCBinaryExpr::CreateAdd(Expr, @@ -68,11 +167,8 @@ void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,                                        MO.getMBB()->getSymbol(), AP.OutContext));        break;      case MachineOperand::MO_GlobalAddress: -      MCOp = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP); -      break;      case MachineOperand::MO_ExternalSymbol: -      MCOp = GetSymbolRef(MO,  -                          AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); +      MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP);        break;      case MachineOperand::MO_JumpTableIndex:        MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);  | 

