[PATCH] 32-bit PowerPC ELF Position Independent Code

Justin Hibbits chmeeedalf at gmail.com
Tue Jul 15 22:36:53 PDT 2014


Hi Bill,

On Mon, 14 Jul 2014 15:29:30 -0500
Bill Schmidt <wschmidt at linux.vnet.ibm.com> wrote:

> Hi Justin,
> 
> Here are a few comments.  Please bear in mind that I'm not much of an
> expert on the 32-bit ABI, so I could miss some subtleties.  By the
> way, in case you aren't already, I'd recommend that you reference
> https://www.power.org/documentation/power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
> (free, but requires annoying registration) for this work.
> 
> On Fri, 2014-07-11 at 17:54 -0700, Justin Hibbits wrote:
> > Hi,
> > 
> > For the last few weeks I've been working off and on with ppc32 PIC
> > for ELF/SysVR4, and now have something to show for it.  The patch is
> > attached.  It passes all existing tests, and I haven't yet added new
> > tests for this.  I also tested by compiling zlib on FreeBSD/PowerPC,
> > and running some commands linked against it.
> 
> Before somebody else says it, and as I'm sure you already know:
> You'll need to add some new tests before committing the patch, to
> verify your new behaviors.
> 
> > 
> > Differences from GCC:
> > 
> > * GCC sets aside r30 as the PIC register, this will use any
> > available register.
> 
> This is not a good idea, as setting aside a register is done for a
> reason.  The linker expects that r30 will hold the address of the GOT,
> so some subtle bugs can arise from linker optimizations if you don't
> follow this convention.
> 
> > * GNU AS writes a real difference to the function pre-word, whereas
> > the LLVM assembler writes 0, with a relocation.  This appears to be
> >   irrelevant, as it works correctly in my test case.
> 
> I don't know offhand if this is generally safe or not -- you may want
> to scour the ABI document to see if there is a hidden reason for this.
> 
> Index: include/llvm/Support/ELF.h
> >===================================================================
> >--- include/llvm/Support/ELF.h	(revision 212105)
> >+++ include/llvm/Support/ELF.h	(working copy)
> >@@ -458,6 +458,7 @@
> >   R_PPC_GOT16_LO              = 15,
> >   R_PPC_GOT16_HI              = 16,
> >   R_PPC_GOT16_HA              = 17,
> >+  R_PPC_PLTREL24              = 18,
> >   R_PPC_REL32                 = 26,
> >   R_PPC_TLS                   = 67,
> >   R_PPC_DTPMOD32              = 68,
> >Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
> >===================================================================
> >--- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
> >(revision 212105) +++
> >lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
> >(working copy) @@ -83,7 +83,15 @@
> >       llvm_unreachable("Unimplemented");
> >     case PPC::fixup_ppc_br24:
> >     case PPC::fixup_ppc_br24abs:
> >-      Type = ELF::R_PPC_REL24;
> >+      switch (Modifier) {
> >+      default: llvm_unreachable("Unsupported Modifier");
> >+      case MCSymbolRefExpr::VK_None:
> >+        Type = ELF::R_PPC_REL24;
> >+        break;
> >+      case MCSymbolRefExpr::VK_PLT:
> >+        Type = ELF::R_PPC_PLTREL24;
> >+        break;
> >+      }
> >       break;
> >     case PPC::fixup_ppc_brcond14:
> >     case PPC::fixup_ppc_brcond14abs:
> >Index: lib/Target/PowerPC/PPC.h
> >===================================================================
> >--- lib/Target/PowerPC/PPC.h	(revision 212105)
> >+++ lib/Target/PowerPC/PPC.h	(working copy)
> >@@ -60,10 +60,10 @@
> >     // 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 = 1,
> >+    /// MO_PLT_STUB - On a symbol operand "FOO", this indicates
> >that the
> >+    /// reference is actually to the "FOO$stub" or "FOO at plt"
> >symbol.  This is
> >+    /// used for calls and jumps to external functions on Tiger and
> >earlier.
> >+    MO_PLT_STUB = 1,
> >     
> >     /// MO_PIC_FLAG - If this bit is set, the symbol reference is
> > relative to /// the function's picbase, e.g. lo16(symbol-picbase).
> >Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
> >===================================================================
> >--- lib/Target/PowerPC/PPCAsmPrinter.cpp	(revision 212105)
> >+++ lib/Target/PowerPC/PPCAsmPrinter.cpp	(working copy)
> >@@ -18,6 +18,7 @@
> > 
> > #include "PPC.h"
> > #include "InstPrinter/PPCInstPrinter.h"
> >+#include "PPCMachineFunctionInfo.h"
> > #include "MCTargetDesc/PPCMCExpr.h"
> > #include "MCTargetDesc/PPCPredicates.h"
> > #include "PPCSubtarget.h"
> >@@ -27,6 +28,7 @@
> > #include "llvm/ADT/SmallString.h"
> > #include "llvm/ADT/StringExtras.h"
> > #include "llvm/CodeGen/AsmPrinter.h"
> >+#include "llvm/CodeGen/MachineConstantPool.h"
> > #include "llvm/CodeGen/MachineFunctionPass.h"
> > #include "llvm/CodeGen/MachineInstr.h"
> > #include "llvm/CodeGen/MachineInstrBuilder.h"
> >@@ -100,6 +102,7 @@
> >     }
> > 
> >     bool doFinalization(Module &M) override;
> >+    void EmitStartOfAsmFile(Module &M) override;
> > 
> >     void EmitFunctionEntryLabel() override;
> > 
> >@@ -330,6 +333,58 @@
> >     OutStreamer.EmitLabel(PICBase);
> >     return;
> >   }
> >+  case PPC::GetGBRO: {
> >+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this,
> >Subtarget.isDarwin());
> >+    MCSymbol *PICOffset =
> >MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
> >+    TmpInst.setOpcode(PPC::LWZ);
> >+    const MCExpr *Exp =
> >+      MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None,
> >OutContext);
> >+    const MCExpr *PB =
> >+      MCSymbolRefExpr::Create(MF->getPICBaseSymbol(),
> >MCSymbolRefExpr::VK_None, OutContext);
> >+    const MCOperand MO = TmpInst.getOperand(1);
> >+    TmpInst.getOperand(1) =
> >(MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB,
> >OutContext)));
> >+    TmpInst.addOperand(MO);
> >+    EmitToStreamer(OutStreamer, TmpInst);
> >+    return;
> >+  }
> >+  case PPC::UpdateGBR: {
> >+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this,
> >Subtarget.isDarwin());
> >+    TmpInst.setOpcode(PPC::ADD4);
> >+    TmpInst.addOperand(TmpInst.getOperand(0));
> >+    EmitToStreamer(OutStreamer, TmpInst);
> >+    return;
> >+  }
> 
> Please add commentary explaining what GBRO and GBR mean.  I eventually
> figured it out, but the casual reader of the code shouldn't have to.
> 
> >+  case PPC::LWZtoc: {
> >+    // Transform %X3 = LDtoc <ga:@min1>, %X2
> 
> Update commentary to read LWZtoc as well.
> 
> >+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this,
> >Subtarget.isDarwin()); +
> >+    // Change the opcode to LD, and the global address operand to
> >be a
> >+    // reference to the TOC entry we will synthesize later.
> 
> Again the commentary is wrong.
> 
> >+    TmpInst.setOpcode(PPC::LWZ);
> >+    const MachineOperand &MO = MI->getOperand(1);
> >+
> >+    // Map symbol -> label of TOC entry
> >+    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
> >+    MCSymbol *MOSymbol = nullptr;
> >+    if (MO.isGlobal())
> >+      MOSymbol = getSymbol(MO.getGlobal());
> >+    else if (MO.isCPI())
> >+      MOSymbol = GetCPISymbol(MO.getIndex());
> >+    else if (MO.isJTI())
> >+      MOSymbol = GetJTISymbol(MO.getIndex());
> >+
> >+    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
> >+
> >+    const MCExpr *Exp =
> >+      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
> >+                              OutContext);
> >+    const MCExpr *PB =
> >+
> >MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
> >OutContext);
> >+    Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
> >+    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
> >+    EmitToStreamer(OutStreamer, TmpInst);
> >+    return;
> >+  }
> >   case PPC::LDtocJTI:
> >   case PPC::LDtocCPT:
> >   case PPC::LDtoc: {
> >@@ -717,9 +772,47 @@
> >   EmitToStreamer(OutStreamer, TmpInst);
> > }
> > 
> >+void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
> >+  if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_)
> >+    return AsmPrinter::EmitStartOfAsmFile(M);
> >+
> >+  OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
> >+         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
> >SectionKind::getReadOnly()));
> 
> I'm curious why you're using .got2 instead of .got.  As I understand
> it, this is usually only used for large code model, and not always
> then. With .got2 you will get separate PLT stubs for each file,
> rather than having the linker share them, so the same destination can
> get multiple PLT call stubs.
> 
> >+
> >+  MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
> >+  MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
> >+
> >+  OutStreamer.EmitLabel(CurrentPos);
> >+
> >+  const MCExpr *tocExpr =
> >MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos,
> >OutContext),
> >+
> >MCConstantExpr::Create(0x8000, OutContext),
> >+                                                  OutContext);
> >+
> >+  OutStreamer.EmitAssignment(TOCSym, tocExpr);
> >+
> >+  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
> >+}
> >+
> > void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
> >-  if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
> >+  if (!Subtarget.isPPC64() && TM.getRelocationModel() !=
> >Reloc::PIC_)  // linux/ppc32 - Normal entry label.
> >     return AsmPrinter::EmitFunctionEntryLabel();
> >+
> >+  if (!Subtarget.isPPC64()) {
> >+  	if (MF->getInfo<PPCFunctionInfo>()->usesPICBase()) {
> >+      MCSymbol *RelocSymbol =
> >MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
> >+      MCSymbol *PICBase = MF->getPICBaseSymbol();
> >+      OutStreamer.EmitLabel(RelocSymbol);
> >+
> >+      const MCExpr *OffsExpr =
> >+
> >MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
> >OutContext),
> >+                                MCSymbolRefExpr::Create(PICBase,
> >OutContext),
> >+                                OutContext);
> >+      OutStreamer.EmitValue(OffsExpr, 4);
> >+      OutStreamer.EmitLabel(CurrentFnSym);
> >+      return;
> >+    } else
> >+      return AsmPrinter::EmitFunctionEntryLabel();
> >+  }
> >     
> >   // Emit an official procedure descriptor.
> >   MCSectionSubPair Current = OutStreamer.getCurrentSection();
> >@@ -759,10 +852,17 @@
> >   PPCTargetStreamer &TS =
> >       static_cast<PPCTargetStreamer
> > &>(*OutStreamer.getTargetStreamer());
> > 
> >-  if (isPPC64 && !TOC.empty()) {
> >-    const MCSectionELF *Section =
> >OutStreamer.getContext().getELFSection(".toc",
> >+  if (!TOC.empty()) {
> >+    const MCSectionELF *Section;
> >+    
> >+    if (isPPC64)
> >+      Section = OutStreamer.getContext().getELFSection(".toc",
> >         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
> >         SectionKind::getReadOnly());
> >+	else
> >+      Section = OutStreamer.getContext().getELFSection(".got2",
> >+        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
> >+        SectionKind::getReadOnly());
> >     OutStreamer.SwitchSection(Section);
> > 
> >     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
> >@@ -769,7 +869,10 @@
> >          E = TOC.end(); I != E; ++I) {
> >       OutStreamer.EmitLabel(I->second);
> >       MCSymbol *S =
> > OutContext.GetOrCreateSymbol(I->first->getName());
> >-      TS.emitTCEntry(*S);
> >+      if (isPPC64)
> >+        TS.emitTCEntry(*S);
> >+      else
> >+        OutStreamer.EmitSymbolValue(S, 4);
> >     }
> >   }
> > 
> >Index: lib/Target/PowerPC/PPCCodeEmitter.cpp
> >===================================================================
> >--- lib/Target/PowerPC/PPCCodeEmitter.cpp	(revision 212105)
> >+++ lib/Target/PowerPC/PPCCodeEmitter.cpp	(working copy)
> >@@ -97,8 +97,8 @@
> > }
> > 
> > bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
> >-  assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
> >-          MF.getTarget().getRelocationModel() != Reloc::Static) &&
> >+  assert((MF.getTarget().getRelocationModel() == Reloc::Default ||
> >+          MF.getTarget().getRelocationModel() == Reloc::Static) &&
> >          "JIT relocation model must be set to static or default!");
> > 
> >   MMI = &getAnalysis<MachineModuleInfo>();
> 
> The above hunk isn't directly relevant to the content of this patch
> and should be committed separately.
> 
> >Index: lib/Target/PowerPC/PPCFastISel.cpp
> >===================================================================
> >--- lib/Target/PowerPC/PPCFastISel.cpp	(revision 212105)
> >+++ lib/Target/PowerPC/PPCFastISel.cpp	(working copy)
> >@@ -1491,8 +1491,18 @@
> >   // FIXME: We can and should optimize away the NOP for local calls.
> >   MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB,
> > FuncInfo.InsertPt, DbgLoc, TII.get(PPC::BL8_NOP));
> >+
> >+  unsigned char OpFlags = 0;
> >+
> >+  // Add MO_PLT for global address or external symbol in the PIC
> >relocation
> >+  // model.
> >+  if (PPCSubTarget->isTargetELF() &&
> >+      !PPCSubTarget->isPPC64() &&
> >+      TM.getRelocationModel() == Reloc::PIC_)
> >+    OpFlags = PPCII::MO_PLT_STUB;
> >+
> >   // Add callee.
> >-  MIB.addGlobalAddress(GV);
> >+  MIB.addGlobalAddress(GV, 0, OpFlags);
> > 
> >   // Add implicit physical register uses to the call.
> >   for (unsigned II = 0, IE = RegArgs.size(); II != IE; ++II)
> 
> Remove the above changes, as the code will never be executed.
> Currently fast-isel is implemented only for PPC64 SVR4 (see the end
> of the file). You are welcome to put this back in later if you want
> to go to the effort of making fast-isel work for 32-bit. ;)
> 
> >Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
> >===================================================================
> >--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp	(revision 212105)
> >+++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp	(working copy)
> >@@ -14,6 +14,7 @@
> > 
> > #include "PPC.h"
> > #include "MCTargetDesc/PPCPredicates.h"
> >+#include "PPCMachineFunctionInfo.h"
> > #include "PPCTargetMachine.h"
> > #include "llvm/CodeGen/MachineFunction.h"
> > #include "llvm/CodeGen/MachineInstrBuilder.h"
> >@@ -278,6 +279,12 @@
> >       GlobalBaseReg =
> > RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass);
> > BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
> > BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
> >+      if (PPCSubTarget->isTargetELF()) {
> >+        unsigned TempReg =
> >RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
> >+        BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::GetGBRO),
> >TempReg).addReg(GlobalBaseReg);
> >+        BuildMI(FirstMBB, MBBI, dl,
> >TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg).addReg(TempReg);
> >+        MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
> >+      }
> 
> As discussed earlier, you should use R30 for the GOT base.
> 
> >     } else {
> >       GlobalBaseReg =
> > RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass);
> > BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR8));
> >@@ -1445,6 +1452,11 @@
> >     return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain);
> >   }
> >   case PPCISD::TOC_ENTRY: {
> >+    if (PPCSubTarget->isSVR4ABI() && !PPCSubTarget->isPPC64()) {
> >+      SDValue GA = N->getOperand(0);
> >+      return CurDAG->getMachineNode(PPC::LWZtoc, dl, MVT::i32, GA,
> >+                                    N->getOperand(1));
> >+	}
> >     assert (PPCSubTarget->isPPC64() && "Only supported for 64-bit
> > ABI");
> 
> Please change the text on the assert, which is no longer correct with
> these changes.
> 
> > 
> >     // For medium and large code model, we generate two
> > instructions as
> >Index: lib/Target/PowerPC/PPCISelLowering.cpp
> >===================================================================
> >--- lib/Target/PowerPC/PPCISelLowering.cpp	(revision 212105)
> >+++ lib/Target/PowerPC/PPCISelLowering.cpp	(working copy)
> >@@ -1493,8 +1493,8 @@
> > 
> >   // Don't use the pic base if not in PIC relocation model.  Or if
> > we are on a // non-darwin platform.  We don't support PIC on other
> > platforms yet.
> 
> Please change the commentary to match the changes in the code.
> 
> >-  bool isPIC = TM.getRelocationModel() == Reloc::PIC_ &&
> >-               TM.getSubtarget<PPCSubtarget>().isDarwin();
> >+  bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
> >+
> >   if (isPIC) {
> >     HiOpFlags |= PPCII::MO_PIC_FLAG;
> >     LoOpFlags |= PPCII::MO_PIC_FLAG;
> >@@ -1550,6 +1550,14 @@
> > 
> >   unsigned MOHiFlag, MOLoFlag;
> >   bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag,
> > MOLoFlag);
> >+
> >+  if (isPIC && Subtarget.isSVR4ABI()) {
> >+    SDValue GA = DAG.getTargetConstantPool(C, PtrVT,
> >CP->getAlignment(), PPCII::MO_PIC_FLAG);
> >+    SDLoc DL(CP);
> >+    return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i32, GA,
> >+                       DAG.getNode(PPCISD::GlobalBaseReg, DL,
> >PtrVT));
> >+  }
> >+
> >   SDValue CPIHi =
> >     DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0,
> > MOHiFlag); SDValue CPILo =
> >@@ -1571,6 +1579,14 @@
> > 
> >   unsigned MOHiFlag, MOLoFlag;
> >   bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag,
> > MOLoFlag);
> >+
> >+  if (isPIC && Subtarget.isSVR4ABI()) {
> >+    SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
> >PPCII::MO_PIC_FLAG);
> >+    SDLoc DL(GA);
> >+    return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(JT), PtrVT, GA,
> >+                       DAG.getNode(PPCISD::GlobalBaseReg, DL,
> >PtrVT));
> >+  }
> >+
> >   SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
> > MOHiFlag); SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(),
> > PtrVT, MOLoFlag); return LowerLabelRef(JTIHi, JTILo, isPIC, DAG);
> >@@ -1700,6 +1716,12 @@
> >   unsigned MOHiFlag, MOLoFlag;
> >   bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag,
> > MOLoFlag, GV);
> > 
> >+  if (isPIC && Subtarget.isSVR4ABI()) {
> >+    SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT,
> >GSDN->getOffset(), PPCII::MO_PIC_FLAG);
> >+    return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i32, GA,
> >+                       DAG.getNode(PPCISD::GlobalBaseReg, DL,
> >MVT::i32));
> >+  }
> >+
> >   SDValue GAHi =
> >     DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(),
> > MOHiFlag); SDValue GALo =
> >@@ -3351,15 +3373,18 @@
> >     // 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 &&
> >+      if ((DAG.getTarget().getRelocationModel() != Reloc::Static &&
> >           (Subtarget.getTargetTriple().isMacOSX() &&
> >            Subtarget.getTargetTriple().isMacOSXVersionLT(10, 5)) &&
> >           (G->getGlobal()->isDeclaration() ||
> >-           G->getGlobal()->isWeakForLinker())) {
> >+           G->getGlobal()->isWeakForLinker())) ||
> >+          (Subtarget.isTargetELF() && !isPPC64 &&
> >+           !G->getGlobal()->hasLocalLinkage() &&
> >+           DAG.getTarget().getRelocationModel() == Reloc::PIC_)) {
> >         // 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;
> >+        OpFlags = PPCII::MO_PLT_STUB;
> >       }
> > 
> >       // If the callee is a GlobalAddress/ExternalSymbol node
> > (quite common,
> >@@ -3375,13 +3400,15 @@
> >   if (ExternalSymbolSDNode *S =
> > dyn_cast<ExternalSymbolSDNode>(Callee)) { unsigned char OpFlags = 0;
> > 
> >-    if (DAG.getTarget().getRelocationModel() != Reloc::Static &&
> >-        (Subtarget.getTargetTriple().isMacOSX() &&
> >-         Subtarget.getTargetTriple().isMacOSXVersionLT(10, 5))) {
> >+    if ((DAG.getTarget().getRelocationModel() != Reloc::Static &&
> >+         (Subtarget.getTargetTriple().isMacOSX() &&
> >+          Subtarget.getTargetTriple().isMacOSXVersionLT(10, 5))) ||
> >+        (Subtarget.isTargetELF() && !isPPC64 &&
> >+         DAG.getTarget().getRelocationModel() ==
> >Reloc::PIC_)	) {
> >       // 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;
> >+      OpFlags = PPCII::MO_PLT_STUB;
> >     }
> > 
> >     Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
> > Callee.getValueType(),
> >Index: lib/Target/PowerPC/PPCInstrInfo.td
> >===================================================================
> >--- lib/Target/PowerPC/PPCInstrInfo.td	(revision 212105)
> >+++ lib/Target/PowerPC/PPCInstrInfo.td	(working copy)
> >@@ -57,6 +57,9 @@
> >   SDTCisPtrTy<0>, SDTCisVT<1, i32>
> > ]>;
> > 
> >+def tocentry32 : Operand<iPTR> {
> >+  let MIOperandInfo = (ops i32imm:$imm);
> >+}
> > 
> > //===----------------------------------------------------------------------===//
> > // PowerPC specific DAG Nodes.
> >@@ -2400,6 +2403,15 @@
> > def : Pat<(PPCaddTls i32:$in, tglobaltlsaddr:$g),
> >           (ADD4TLS $in, tglobaltlsaddr:$g)>;
> > 
> >+// Support for Position-independent code
> >+def LWZtoc: Pseudo<(outs gprc:$rD), (ins tocentry32:$disp,
> >gprc:$reg),
> >+                  "#LWZtoc",
> >+                  [(set i32:$rD,
> >+                     (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
> >+def GetGBRO:	Pseudo<(outs gprc:$rT), (ins gprc:$rI),
> >"#GetGBR0", []>; +def UpdateGBR:	Pseudo<(outs gprc:$rT), (ins
> >gprc:$rI), "#UpdateGBR", []>;
> 
> Change #GetGBR0 to #GetGBRO.  I realize it doesn't really matter but
> they should be the same.
> 
> Again, it wouldn't hurt to document your acronym, but as long as you
> at least do it in PPCAsmPrinter.cpp that's probably enough.
> 
> Thanks,
> Bill

Thanks for reviewing the code.  I think I've addressed all your
comments, including adding a few rudimentary tests for it.  I've
attached the most recent patch for review.  I hope this can get in
before the 3.5 branch, so will also be looking for somebody with
commit privileges to do the honors.

Thanks,
Justin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ppc32pic_jul15.diff
Type: text/x-patch
Size: 25724 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140715/7bc261be/attachment.bin>


More information about the llvm-commits mailing list