Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Dec 2014 18:22:23 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r276211 - in projects/clang350-import/contrib/llvm: include/llvm/IR include/llvm/MC include/llvm/Support lib/IR lib/MC lib/Target/PowerPC lib/Target/PowerPC/MCTargetDesc
Message-ID:  <201412251822.sBPIMNx4052289@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu Dec 25 18:22:22 2014
New Revision: 276211
URL: https://svnweb.freebsd.org/changeset/base/276211

Log:
  Pull in r214284 from upstream llvm trunk (by Hal Finkel):
  
    [PowerPC] Add JMP_SLOT relocation definitions
  
    This will be required by upcoming patches for LLDB support.
  
    Patch by Justin Hibbits!
  
  Pull in r221510 from upstream llvm trunk (by Justin Hibbits):
  
    Add Position-independent Code model Module API.
  
    Summary:
    This makes PIC levels a Module flag attribute, which can be queried by the
    backend.  The flag is named `PIC Level`, and can have a value of:
  
      0 - Backend-default
      1 - Small-model (-fpic)
      2 - Large-model (-fPIC)
  
    These match the `-pic-level' command line argument for clang, and the value of the
    preprocessor macro `__PIC__'.
  
    Test Plan:
    New flags tests specific for the 'PIC Level' module flag.
    Tests to be added as part of a future commit for PowerPC, which will use this new API.
  
    Reviewers: rafael, echristo
  
    Reviewed By: rafael, echristo
  
    Subscribers: rafael, llvm-commits
  
    Differential Revision: http://reviews.llvm.org/D5882
  
  Pull in r221791 from upstream llvm trunk (by Justin Hibbits):
  
    Add support for small-model PIC for PowerPC.
  
    Summary:
    Large-model was added first.  With the addition of support for multiple PIC
    models in LLVM, now add small-model PIC for 32-bit PowerPC, SysV4 ABI.  This
    generates more optimal code, for shared libraries with less than about 16380
    data objects.
  
    Test Plan: Test cases added or updated
  
    Reviewers: joerg, hfinkel
  
    Reviewed By: hfinkel
  
    Subscribers: jholewinski, mcrosier, emaste, llvm-commits
  
    Differential Revision: http://reviews.llvm.org/D5399
  
  Together, these changes implement small-model PIC support for PowerPC.
  
  Thanks to Justin Hibbits and Roman Divacky for their assistance in
  getting this working.

Modified:
  projects/clang350-import/contrib/llvm/include/llvm/IR/Module.h
  projects/clang350-import/contrib/llvm/include/llvm/MC/MCExpr.h
  projects/clang350-import/contrib/llvm/include/llvm/Support/CodeGen.h
  projects/clang350-import/contrib/llvm/include/llvm/Support/ELF.h
  projects/clang350-import/contrib/llvm/lib/IR/Module.cpp
  projects/clang350-import/contrib/llvm/lib/MC/MCExpr.cpp
  projects/clang350-import/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
  projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
  projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
  projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td

Modified: projects/clang350-import/contrib/llvm/include/llvm/IR/Module.h
==============================================================================
--- projects/clang350-import/contrib/llvm/include/llvm/IR/Module.h	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/include/llvm/IR/Module.h	Thu Dec 25 18:22:22 2014	(r276211)
@@ -23,6 +23,7 @@
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/DataTypes.h"
 #include <system_error>
 
@@ -620,6 +621,15 @@ public:
   unsigned getDwarfVersion() const;
 
 /// @}
+/// @name Utility functions for querying and setting PIC level
+/// @{
+
+  /// \brief Returns the PIC level (small or large model)
+  PICLevel::Level getPICLevel() const;
+
+  /// \brief Set the PIC level (small or large model)
+  void setPICLevel(PICLevel::Level PL);
+/// @}
 };
 
 /// An raw_ostream inserter for modules.

Modified: projects/clang350-import/contrib/llvm/include/llvm/MC/MCExpr.h
==============================================================================
--- projects/clang350-import/contrib/llvm/include/llvm/MC/MCExpr.h	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/include/llvm/MC/MCExpr.h	Thu Dec 25 18:22:22 2014	(r276211)
@@ -238,6 +238,7 @@ public:
     VK_PPC_GOT_TLSLD_HI,   // symbol@got@tlsld@h
     VK_PPC_GOT_TLSLD_HA,   // symbol@got@tlsld@ha
     VK_PPC_TLSLD,          // symbol@tlsld
+    VK_PPC_LOCAL,          // symbol@local
 
     VK_Mips_GPREL,
     VK_Mips_GOT_CALL,

Modified: projects/clang350-import/contrib/llvm/include/llvm/Support/CodeGen.h
==============================================================================
--- projects/clang350-import/contrib/llvm/include/llvm/Support/CodeGen.h	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/include/llvm/Support/CodeGen.h	Thu Dec 25 18:22:22 2014	(r276211)
@@ -30,6 +30,10 @@ namespace llvm {
     enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
   }
 
+  namespace PICLevel {
+    enum Level { Default=0, Small=1, Large=2 };
+  }
+
   // TLS models.
   namespace TLSModel {
     enum Model {

Modified: projects/clang350-import/contrib/llvm/include/llvm/Support/ELF.h
==============================================================================
--- projects/clang350-import/contrib/llvm/include/llvm/Support/ELF.h	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/include/llvm/Support/ELF.h	Thu Dec 25 18:22:22 2014	(r276211)
@@ -459,6 +459,8 @@ enum {
   R_PPC_GOT16_HI              = 16,
   R_PPC_GOT16_HA              = 17,
   R_PPC_PLTREL24              = 18,
+  R_PPC_JMP_SLOT              = 21,
+  R_PPC_LOCAL24PC             = 23,
   R_PPC_REL32                 = 26,
   R_PPC_TLS                   = 67,
   R_PPC_DTPMOD32              = 68,
@@ -547,6 +549,7 @@ enum {
   R_PPC64_GOT16_LO            = 15,
   R_PPC64_GOT16_HI            = 16,
   R_PPC64_GOT16_HA            = 17,
+  R_PPC64_JMP_SLOT            = 21,
   R_PPC64_REL32               = 26,
   R_PPC64_ADDR64              = 38,
   R_PPC64_ADDR16_HIGHER       = 39,

Modified: projects/clang350-import/contrib/llvm/lib/IR/Module.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/IR/Module.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/IR/Module.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -461,3 +461,16 @@ Comdat *Module::getOrInsertComdat(String
   Entry.second.Name = &Entry;
   return &Entry.second;
 }
+
+PICLevel::Level Module::getPICLevel() const {
+  Value *Val = getModuleFlag("PIC Level");
+
+  if (Val == NULL)
+    return PICLevel::Default;
+
+  return static_cast<PICLevel::Level>(cast<ConstantInt>(Val)->getZExtValue());
+}
+
+void Module::setPICLevel(PICLevel::Level PL) {
+  addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL);
+}

Modified: projects/clang350-import/contrib/llvm/lib/MC/MCExpr.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/MC/MCExpr.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/MC/MCExpr.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -247,6 +247,7 @@ StringRef MCSymbolRefExpr::getVariantKin
   case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h";
   case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
   case VK_PPC_TLSLD: return "tlsld";
+  case VK_PPC_LOCAL: return "local";
   case VK_Mips_GPREL: return "GPREL";
   case VK_Mips_GOT_CALL: return "GOT_CALL";
   case VK_Mips_GOT16: return "GOT16";

Modified: projects/clang350-import/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -95,6 +95,9 @@ unsigned PPCELFObjectWriter::getRelocTyp
       case MCSymbolRefExpr::VK_PLT:
         Type = ELF::R_PPC_PLTREL24;
         break;
+      case MCSymbolRefExpr::VK_PPC_LOCAL:
+        Type = ELF::R_PPC_LOCAL24PC;
+        break;
       }
       break;
     case PPC::fixup_ppc_brcond14:

Modified: projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -311,12 +311,35 @@ MCSymbol *PPCAsmPrinter::lookUpOrCreateT
 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   MCInst TmpInst;
   bool isPPC64 = Subtarget.isPPC64();
+  bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin();
+  const Module *M = MF->getFunction()->getParent();
+  PICLevel::Level PL = M->getPICLevel();
   
   // Lower multi-instruction pseudo operations.
   switch (MI->getOpcode()) {
   default: break;
   case TargetOpcode::DBG_VALUE:
     llvm_unreachable("Should be handled target independently");
+  case PPC::MoveGOTtoLR: {
+    // Transform %LR = MoveGOTtoLR
+    // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
+    // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
+    // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
+    //      blrl
+    // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
+    MCSymbol *GOTSymbol =
+      OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
+    const MCExpr *OffsExpr =
+      MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol,
+                                                      MCSymbolRefExpr::VK_PPC_LOCAL,
+                                                      OutContext),
+                              MCConstantExpr::Create(4, OutContext),
+                              OutContext);
+
+    // Emit the 'bl'.
+    EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
+    return;
+  }
   case PPC::MovePCtoLR:
   case PPC::MovePCtoLR8: {
     // Transform %LR = MovePCtoLR
@@ -335,10 +358,14 @@ void PPCAsmPrinter::EmitInstruction(cons
     OutStreamer.EmitLabel(PICBase);
     return;
   }
-  case PPC::GetGBRO: {
+  case PPC::UpdateGBR: {
+    // Transform %Rd = UpdateGBR(%Rt, %Ri)
+    // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri)
+    //       add %Rd, %Rt, %Ri
     // Get the offset from the GOT Base Register to the GOT
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
-    MCSymbol *PICOffset = MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
+    MCSymbol *PICOffset =
+      MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
     TmpInst.setOpcode(PPC::LWZ);
     const MCExpr *Exp =
       MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
@@ -346,26 +373,26 @@ void PPCAsmPrinter::EmitInstruction(cons
       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);
+    const MCOperand TR = TmpInst.getOperand(1);
+    const MCOperand PICR = TmpInst.getOperand(0);
+
+    // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri)
+    TmpInst.getOperand(1) =
+        MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext));
+    TmpInst.getOperand(0) = TR;
+    TmpInst.getOperand(2) = PICR;
     EmitToStreamer(OutStreamer, TmpInst);
-    return;
-  }
-  case PPC::UpdateGBR: {
-    // Update the GOT Base Register to point to the GOT.  It may be possible to
-    // merge this with the PPC::GetGBRO, doing it all in one step.
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+
     TmpInst.setOpcode(PPC::ADD4);
-    TmpInst.addOperand(TmpInst.getOperand(0));
+    TmpInst.getOperand(0) = PICR;
+    TmpInst.getOperand(1) = TR;
+    TmpInst.getOperand(2) = PICR;
     EmitToStreamer(OutStreamer, TmpInst);
     return;
   }
   case PPC::LWZtoc: {
-    // Transform %X3 = LWZtoc <ga:@min1>, %X2
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    // Transform %R3 = LWZtoc <ga:@min1>, %R2
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to LWZ, and the global address operand to be a
     // reference to the GOT entry we will synthesize later.
@@ -382,16 +409,23 @@ void PPCAsmPrinter::EmitInstruction(cons
     else if (MO.isJTI())
       MOSymbol = GetJTISymbol(MO.getIndex());
 
-    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+    if (PL == PICLevel::Small) {
+      const MCExpr *Exp =
+        MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT,
+                                OutContext);
+      TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
+    } else {
+      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);
+      const MCExpr *Exp =
+        MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
+                                OutContext);
+      const MCExpr *PB =
+        MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")),
+                                                             OutContext);
+      Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
+      TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
+    }
     EmitToStreamer(OutStreamer, TmpInst);
     return;
   }
@@ -399,7 +433,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   case PPC::LDtocCPT:
   case PPC::LDtoc: {
     // Transform %X3 = LDtoc <ga:@min1>, %X2
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to LD, and the global address operand to be a
     // reference to the TOC entry we will synthesize later.
@@ -428,7 +462,7 @@ void PPCAsmPrinter::EmitInstruction(cons
       
   case PPC::ADDIStocHA: {
     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to ADDIS8.  If the global address is external, has
     // common linkage, is a non-local function address, or is a jump table
@@ -470,7 +504,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   }
   case PPC::LDtocL: {
     // Transform %Xd = LDtocL <ga:@sym>, %Xs
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to LD.  If the global address is external, has
     // common linkage, or is a jump table address, then reference the
@@ -507,7 +541,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   }
   case PPC::ADDItocL: {
     // Transform %Xd = ADDItocL %Xs, <ga:@sym>
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to ADDI8.  If the global address is external, then
     // generate a TOC entry and reference that.  Otherwise reference the
@@ -558,7 +592,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   case PPC::LDgotTprelL:
   case PPC::LDgotTprelL32: {
     // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
-    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
 
     // Change the opcode to LD.
     TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
@@ -841,7 +875,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   }
   }
 
-  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
   EmitToStreamer(OutStreamer, TmpInst);
 }
 
@@ -857,16 +891,14 @@ void PPCLinuxAsmPrinter::EmitStartOfAsmF
   if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_)
     return AsmPrinter::EmitStartOfAsmFile(M);
 
-  // FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not
-  // optimal for some cases.  We should consider supporting small model (-fpic)
-  // as well in the future.
-  assert(TM.getCodeModel() != CodeModel::Small &&
-         "Small code model PIC is currently unsupported.");
+  if (M.getPICLevel() == PICLevel::Small)
+    return AsmPrinter::EmitStartOfAsmFile(M);
+
   OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
          ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
          SectionKind::getReadOnly()));
 
-  MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
+  MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC"));
   MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
 
   OutStreamer.EmitLabel(CurrentPos);
@@ -885,7 +917,9 @@ void PPCLinuxAsmPrinter::EmitStartOfAsmF
 
 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
   // linux/ppc32 - Normal entry label.
-  if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_)
+  if (!Subtarget.isPPC64() && 
+      (TM.getRelocationModel() != Reloc::PIC_ || 
+       MF->getFunction()->getParent()->getPICLevel() == PICLevel::Small))
     return AsmPrinter::EmitFunctionEntryLabel();
 
   if (!Subtarget.isPPC64()) {
@@ -897,7 +931,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEnt
 
       const MCExpr *OffsExpr =
         MCBinaryExpr::CreateSub(
-          MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
+          MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")),
                                                                OutContext),
                                   MCSymbolRefExpr::Create(PICBase, OutContext),
           OutContext);

Modified: projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -27,6 +27,7 @@
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -273,23 +274,29 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseRe
     // Insert the set of GlobalBaseReg into the first MBB of the function
     MachineBasicBlock &FirstMBB = MF->front();
     MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+    const Module *M = MF->getFunction()->getParent();
     DebugLoc dl;
 
     if (PPCLowering->getPointerTy() == MVT::i32) {
-      if (PPCSubTarget->isTargetELF())
+      if (PPCSubTarget->isTargetELF()) {
         GlobalBaseReg = PPC::R30;
-      else
+        if (M->getPICLevel() == PICLevel::Small) {
+          BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MoveGOTtoLR));
+          BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
+        } else {
+          BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
+          BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
+          unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
+          BuildMI(FirstMBB, MBBI, dl,
+                  TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg)
+                  .addReg(TempReg, RegState::Define).addReg(GlobalBaseReg);
+          MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
+        }
+      } else {
         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);
+        BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
+        BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
       }
     } else {
       GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass);
@@ -1429,13 +1436,13 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *
     return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain);
   }
   case PPCISD::TOC_ENTRY: {
+    assert ((PPCSubTarget->isPPC64() || PPCSubTarget->isSVR4ABI()) &&
+            "Only supported for 64-bit ABI and 32-bit SVR4");
     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 and 32-bit SVR4");
 
     // For medium and large code model, we generate two instructions as
     // described below.  Otherwise we allow SelectCodeCommon to handle this,

Modified: projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Thu Dec 25 18:22:22 2014	(r276211)
@@ -1653,6 +1653,8 @@ SDValue PPCTargetLowering::LowerGlobalTL
   const GlobalValue *GV = GA->getGlobal();
   EVT PtrVT = getPointerTy();
   bool is64bit = Subtarget.isPPC64();
+  const Module *M = DAG.getMachineFunction().getFunction()->getParent();
+  PICLevel::Level picLevel = M->getPICLevel();
 
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
 
@@ -1691,7 +1693,10 @@ SDValue PPCTargetLowering::LowerGlobalTL
       GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
                                    GOTReg, TGA);
     } else {
-      GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
+      if (picLevel == PICLevel::Small)
+        GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
+      else
+        GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
     }
     SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
                                    GOTPtr, TGA);
@@ -1721,7 +1726,10 @@ SDValue PPCTargetLowering::LowerGlobalTL
       GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
                            GOTReg, TGA);
     } else {
-      GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
+      if (picLevel == PICLevel::Small)
+        GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
+      else
+        GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
     }
     SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
                                    GOTPtr, TGA);

Modified: projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td
==============================================================================
--- projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td	Thu Dec 25 17:54:22 2014	(r276210)
+++ projects/clang350-import/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td	Thu Dec 25 18:22:22 2014	(r276211)
@@ -976,6 +976,9 @@ let isTerminator = 1, isBarrier = 1, PPC
 let Defs = [LR] in
   def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>,
                    PPC970_Unit_BRU;
+let Defs = [LR] in
+  def MoveGOTtoLR : Pseudo<(outs), (ins), "#MoveGOTtoLR", []>,
+                    PPC970_Unit_BRU;
 
 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
   let isBarrier = 1 in {
@@ -2444,15 +2447,13 @@ def ADDISdtprelHA32 : Pseudo<(outs gprc:
                                                 tglobaltlsaddr:$disp))]>;
 
 // 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 LWZtoc : Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
+                   "#LWZtoc",
+                   [(set i32:$rD,
+                      (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
 // Get Global (GOT) Base Register offset, from the word immediately preceding
 // the function label.
-def GetGBRO:	Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#GetGBRO", []>;
-// Update the Global(GOT) Base Register with the above offset.
-def UpdateGBR:	Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
+def UpdateGBR : Pseudo<(outs gprc:$rD, gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
 
 
 // Standard shifts.  These are represented separately from the real shifts above



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412251822.sBPIMNx4052289>