[PATCH] 32-bit PowerPC ELF Position Independent Code

Bill Schmidt wschmidt at linux.vnet.ibm.com
Mon Jul 14 13:29:30 PDT 2014


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

>+
>+
> // Standard shifts.  These are represented separately from the real shifts above
> // so that we can distinguish between shifts that allow 5-bit and 6-bit shift
> // amounts.
>Index: lib/Target/PowerPC/PPCMCInstLower.cpp
>===================================================================
>--- lib/Target/PowerPC/PPCMCInstLower.cpp	(revision 212105)
>+++ lib/Target/PowerPC/PPCMCInstLower.cpp	(working copy)
>@@ -13,6 +13,7 @@
> //===----------------------------------------------------------------------===//
> 
> #include "PPC.h"
>+#include "PPCSubtarget.h"
> #include "MCTargetDesc/PPCMCExpr.h"
> #include "llvm/ADT/SmallString.h"
> #include "llvm/ADT/Twine.h"
>@@ -39,12 +40,14 @@
>   Mangler *Mang = AP.Mang;
>   const DataLayout *DL = TM.getDataLayout();
>   MCContext &Ctx = AP.OutContext;
>+  bool isDarwin = TM.getSubtarget<PPCSubtarget>().isDarwin();
> 
>   SmallString<128> Name;
>   StringRef Suffix;
>-  if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB)
>-    Suffix = "$stub";
>-  else if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)
>+  if (MO.getTargetFlags() == PPCII::MO_PLT_STUB) {
>+    if (isDarwin)
>+      Suffix = "$stub";
>+  } else if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)
>     Suffix = "$non_lazy_ptr";
> 
>   if (!Suffix.empty())
>@@ -68,7 +71,7 @@
> 
>   // If the target flags on the operand changes the name of the symbol, do that
>   // before we return the symbol.
>-  if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB) {
>+  if (MO.getTargetFlags() == PPCII::MO_PLT_STUB && isDarwin) {
>     MachineModuleInfoImpl::StubValueTy &StubSym =
>       getMachOMMI(AP).getFnStubEntry(Sym);
>     if (StubSym.getPointer())
>@@ -136,6 +139,9 @@
>       break;
>   }
> 
>+  if (MO.getTargetFlags() == PPCII::MO_PLT_STUB && !isDarwin)
>+    RefKind = MCSymbolRefExpr::VK_PLT;
>+
>   const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
> 
>   if (!MO.isJTI() && MO.getOffset())
>Index: lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
>===================================================================
>--- lib/Target/PowerPC/PPCMachineFunctionInfo.cpp	(revision 212105)
>+++ lib/Target/PowerPC/PPCMachineFunctionInfo.cpp	(working copy)
>@@ -8,8 +8,16 @@
> //===----------------------------------------------------------------------===//
> 
> #include "PPCMachineFunctionInfo.h"
>+#include "llvm/IR/DataLayout.h"
>+#include "llvm/MC/MCContext.h"
>+#include "llvm/Target/TargetMachine.h"
> 
> using namespace llvm;
> 
> void PPCFunctionInfo::anchor() { }
> 
>+MCSymbol *PPCFunctionInfo::getPICOffsetSymbol() const {
>+  const DataLayout *DL = MF.getTarget().getDataLayout();
>+  return MF.getContext().GetOrCreateSymbol(Twine(DL->getPrivateGlobalPrefix())+
>+                                           Twine(MF.getFunctionNumber())+"$poff");
>+}
>Index: lib/Target/PowerPC/PPCMachineFunctionInfo.h
>===================================================================
>--- lib/Target/PowerPC/PPCMachineFunctionInfo.h	(revision 212105)
>+++ lib/Target/PowerPC/PPCMachineFunctionInfo.h	(working copy)
>@@ -92,8 +92,14 @@
>   /// 64-bit SVR4 ABI.
>   SmallVector<unsigned, 3> MustSaveCRs;
> 
>+  /// Hold onto our MachineFunction context.
>+  MachineFunction &MF;
>+
>+  /// Whether this uses the PIC Base register or not.
>+  bool UsesPICBase;
>+
> public:
>-  explicit PPCFunctionInfo(MachineFunction &MF) 
>+  explicit PPCFunctionInfo(MachineFunction &MFC) 
>     : FramePointerSaveIndex(0),
>       ReturnAddrSaveIndex(0),
>       BasePointerSaveIndex(0),
>@@ -109,7 +115,9 @@
>       VarArgsStackOffset(0),
>       VarArgsNumGPR(0),
>       VarArgsNumFPR(0),
>-      CRSpillFrameIndex(0) {}
>+      CRSpillFrameIndex(0),
>+      MF(MFC),
>+      UsesPICBase(0) {}
> 
>   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
>   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
>@@ -170,6 +178,11 @@
>   const SmallVectorImpl<unsigned> &
>     getMustSaveCRs() const { return MustSaveCRs; }
>   void addMustSaveCR(unsigned Reg) { MustSaveCRs.push_back(Reg); }
>+
>+  void setUsesPICBase(bool uses) { UsesPICBase = uses; }
>+  bool usesPICBase() const { return UsesPICBase; }
>+
>+  MCSymbol *getPICOffsetSymbol() const;
> };
> 
> } // end of namespace llvm
>Index: lib/Target/PowerPC/PPCSubtarget.h
>===================================================================
>--- lib/Target/PowerPC/PPCSubtarget.h	(revision 212105)
>+++ lib/Target/PowerPC/PPCSubtarget.h	(working copy)
>@@ -222,6 +222,9 @@
>   /// isBGQ - True if this is a BG/Q platform.
>   bool isBGQ() const { return TargetTriple.getVendor() == Triple::BGQ; }
> 
>+  bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
>+  bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
>+
>   bool isDarwinABI() const { return isDarwin(); }
>   bool isSVR4ABI() const { return !isDarwin(); }
> 
>



> 
> - Justin
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-- 
Bill Schmidt <wschmidt at linux.vnet.ibm.com>




More information about the llvm-commits mailing list