[PATCH] 32-bit PowerPC ELF Position Independent Code
Justin Hibbits
chmeeedalf at gmail.com
Fri Jul 18 15:14:37 PDT 2014
Hal,
D'oh, I manually ran the tests individually, rather than through the
framework. Here's a patch that actually works.
- Justin
On Fri, Jul 18, 2014 at 1:16 PM, Hal Finkel <hfinkel at anl.gov> wrote:
> Justin,
>
> I just tried to apply this patch but there is a regression test failure: Can you reproduce this?
>
> -Hal
>
> FAIL: LLVM :: CodeGen/PowerPC/stack-realign.ll (2902 of 11227)
> ******************** TEST 'LLVM :: CodeGen/PowerPC/stack-realign.ll' FAILED ********************
> Script:
> --
> /llvm-trunk-writable-build/Release+Asserts/bin/llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll | /llvm-trunk-writable-build/Release+Asserts/bin/FileCheck /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll
> /llvm-trunk-writable-build/Release+Asserts/bin/llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -disable-fp-elim < /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll | /llvm-trunk-writable-build/Release+Asserts/bin/FileCheck -check-prefix=CHECK-FP /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll
> /llvm-trunk-writable-build/Release+Asserts/bin/llc -mtriple=powerpc-unknown-linux-gnu -disable-fp-elim < /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll | /llvm-trunk-writable-build/Release+Asserts/bin/FileCheck -check-prefix=CHECK-32 /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll
> /llvm-trunk-writable-build/Release+Asserts/bin/llc -mtriple=powerpc-unknown-linux-gnu -disable-fp-elim < /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll | /llvm-trunk-writable-build/Release+Asserts/bin/FileCheck -check-prefix=CHECK-32-PIC /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll
> --
> Exit Code: 1
>
> Command Output (stderr):
> --
> /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll:89:21: error: expected string not found in input
> ; CHECK-32-PIC-DAG: stw 29, -12(1)
> ^
> <stdin>:7:2: note: scanning from here
> .cfi_startproc
> ^
> <stdin>:10:2: note: possible intended match here
> stw 31, -4(1)
> ^
> /src/llvm-trunk-writable/test/CodeGen/PowerPC/stack-realign.ll:145:21: error: expected string not found in input
> ; CHECK-32-PIC-DAG: stw 29, -12(1)
> ^
> <stdin>:49:2: note: scanning from here
> .cfi_startproc
> ^
> <stdin>:53:2: note: possible intended match here
> stw 31, -4(1)
> ^
>
> --
>
> ********************
> Testing Time: 68.39s
> ********************
> Failing Tests (1):
> LLVM :: CodeGen/PowerPC/stack-realign.ll
>
> Expected Passes : 11101
> Expected Failures : 90
> Unsupported Tests : 35
> Unexpected Failures: 1
> make[1]: *** [check-local] Error 1
>
>
> ----- Original Message -----
>> From: "Justin Hibbits" <chmeeedalf at gmail.com>
>> To: "Hal Finkel" <hfinkel at anl.gov>
>> Cc: llvm-commits at cs.uiuc.edu
>> Sent: Friday, July 18, 2014 2:04:22 AM
>> Subject: Re: [PATCH] 32-bit PowerPC ELF Position Independent Code
>>
>> Hi Hal,
>>
>> Here's the latest patch with whitespace and line fixes. Let me know
>> if
>> there are any other issues, cosmetic or otherwise. Some of the
>> whitespace I think looks a little weird, because I tried to follow
>> indenting rules to line up function arguments, as it appears
>> llvm-style
>> is, and it came out kind of weird with outdents due to nested
>> function
>> calls.
>>
>> - Justin
>>
>> On Fri, 18 Jul 2014 01:09:52 -0500
>> Hal Finkel <hfinkel at anl.gov> wrote:
>>
>> > Justin,
>> >
>> > Thanks, this looks good. You have a bunch of lines that are too
>> > long
>> > (80 characters is the limit). Now, parts of that code have
>> > long-standing violations of this, but let's not make it worse.
>> > Please
>> > wrap those lines that would go over 80 characters.
>> >
>> > -Hal
>> >
>> > ----- Original Message -----
>> > > From: "Justin Hibbits" <chmeeedalf at gmail.com>
>> > > To: "Hal Finkel" <hfinkel at anl.gov>
>> > > Cc: llvm-commits at cs.uiuc.edu
>> > > Sent: Friday, July 18, 2014 12:31:05 AM
>> > > Subject: Re: [PATCH] 32-bit PowerPC ELF Position Independent Code
>> > >
>> > > Hi Hal,
>> > >
>> > > Thanks for looking at this. Got another one for you now.
>> > >
>> > > On Wed, 16 Jul 2014 22:20:59 -0500
>> > > Hal Finkel <hfinkel at anl.gov> wrote:
>> > >
>> > > > Hi Justin,
>> > > >
>> > > > Thanks for working on this!
>> > > >
>> > > > As Bill said, we need test cases. In addition, a few comments:
>> > > >
>> > > > + const MCExpr *tocExpr =
>> > > > MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos,
>> > > > OutContext),
>> > > >
>> > > > +
>> > > > MCConstantExpr::Create(0x8000, OutContext),
>> > > >
>> > > > + OutContext);
>> > > >
>> > > > what is 0x8000? Please provide a comment.
>> > > >
>> > > > 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);
>> > > >
>> > > > It is okay here for TempReg to be R0?
>> > > >
>> > > > // automatically synthesizes these stubs.
>> > > >
>> > > > - OpFlags = PPCII::MO_DARWIN_STUB;
>> > > >
>> > > > + OpFlags = PPCII::MO_PLT_STUB;
>> > > >
>> > > > is this going to break Darwin?
>> > > >
>> > > > // 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;
>> > > >
>> > > > this too? Darwin breaking?
>> > > >
>> > > > - explicit PPCFunctionInfo(MachineFunction &MF)
>> > > > + explicit PPCFunctionInfo(MachineFunction &MFC)
>> > > > ...
>> > > > + MF(MFC),
>> > > >
>> > > > This is unnecessary; because of the way that C++ name lookup
>> > > > works, MF(MF) will be fine here.
>> > > >
>> > > > Thanks again,
>> > > > Hal
>> > >
>> > > I think I've addressed all your comments in my latest patch.
>> > > Mind
>> > > giving it another look?
>> > >
>> > > - Justin
>> > >
>> >
>>
>>
>
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
-------------- next part --------------
Index: include/llvm/Support/ELF.h
===================================================================
--- include/llvm/Support/ELF.h (revision 213379)
+++ 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/Object/ELF.cpp
===================================================================
--- lib/Object/ELF.cpp (revision 213379)
+++ lib/Object/ELF.cpp (working copy)
@@ -519,6 +519,7 @@
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_LO);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_PLTREL24);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32);
Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
===================================================================
--- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision 213379)
+++ 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 213379)
+++ lib/Target/PowerPC/PPC.h (working copy)
@@ -60,10 +60,11 @@
// 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_OR_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, and
+ /// for PIC calls on Linux and ELF systems.
+ MO_PLT_OR_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 213379)
+++ 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,66 @@
OutStreamer.EmitLabel(PICBase);
return;
}
+ case PPC::GetGBRO: {
+ // Get the offset from the GOT Base Register to the GOT
+ 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: {
+ // 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));
+ EmitToStreamer(OutStreamer, TmpInst);
+ return;
+ }
+ case PPC::LWZtoc: {
+ // Transform %X3 = LWZtoc <ga:@min1>, %X2
+ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
+
+ // Change the opcode to LWZ, and the global address operand to be a
+ // reference to the GOT entry we will synthesize later.
+ 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 +780,60 @@
EmitToStreamer(OutStreamer, TmpInst);
}
+void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
+ 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.");
+ OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
+ ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
+ SectionKind::getReadOnly()));
+
+ MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
+ MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
+
+ OutStreamer.EmitLabel(CurrentPos);
+
+ // The GOT pointer points to the middle of the GOT, in order to reference the
+ // entire 64kB range. 0x8000 is the midpoint.
+ 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.
+ // linux/ppc32 - Normal entry label.
+ if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_)
return AsmPrinter::EmitFunctionEntryLabel();
+
+ if (!Subtarget.isPPC64()) {
+ const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
+ if (PPCFI->usesPICBase()) {
+ MCSymbol *RelocSymbol = PPCFI->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 +873,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 +890,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/PPCFrameLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCFrameLowering.cpp (revision 213379)
+++ lib/Target/PowerPC/PPCFrameLowering.cpp (working copy)
@@ -461,7 +461,7 @@
const PPCRegisterInfo *RegInfo =
static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo());
bool HasBP = RegInfo->hasBasePointer(MF);
- unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg;
+ unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF) : FPReg;
unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg;
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
@@ -506,6 +506,7 @@
DebugLoc dl;
bool needsFrameMoves = MMI.hasDebugInfo() ||
MF.getFunction()->needsUnwindTableEntry();
+ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
// Get processor type.
bool isPPC64 = Subtarget.isPPC64();
@@ -546,7 +547,7 @@
bool HasBP = RegInfo->hasBasePointer(MF);
unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1;
- unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30;
+ unsigned BPReg = RegInfo->getBaseRegister(MF);
unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31;
unsigned LRReg = isPPC64 ? PPC::LR8 : PPC::LR;
unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0;
@@ -602,7 +603,9 @@
BPOffset = FFI->getObjectOffset(BPIndex);
} else {
BPOffset =
- PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
+ PPCFrameLowering::getBasePointerSaveOffset(isPPC64,
+ isDarwinABI,
+ isPIC);
}
}
@@ -839,6 +842,7 @@
// Get the ABI.
bool isDarwinABI = Subtarget.isDarwinABI();
bool isSVR4ABI = Subtarget.isSVR4ABI();
+ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
// Check if the link register (LR) has been saved.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
@@ -849,7 +853,7 @@
bool HasBP = RegInfo->hasBasePointer(MF);
unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1;
- unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30;
+ unsigned BPReg = RegInfo->getBaseRegister(MF);
unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31;
unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0;
unsigned TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
@@ -890,7 +894,9 @@
BPOffset = FFI->getObjectOffset(BPIndex);
} else {
BPOffset =
- PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
+ PPCFrameLowering::getBasePointerSaveOffset(isPPC64,
+ isDarwinABI,
+ isPIC);
}
}
@@ -1067,6 +1073,7 @@
int FPSI = FI->getFramePointerSaveIndex();
bool isPPC64 = Subtarget.isPPC64();
bool isDarwinABI = Subtarget.isDarwinABI();
+ bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
MachineFrameInfo *MFI = MF.getFrameInfo();
// If the frame pointer save index hasn't been defined yet.
@@ -1081,7 +1088,7 @@
int BPSI = FI->getBasePointerSaveIndex();
if (!BPSI && RegInfo->hasBasePointer(MF)) {
- int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI);
+ int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI, isPIC);
// Allocate the frame index for the base pointer save area.
BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
// Save the result.
Index: lib/Target/PowerPC/PPCFrameLowering.h
===================================================================
--- lib/Target/PowerPC/PPCFrameLowering.h (revision 213379)
+++ lib/Target/PowerPC/PPCFrameLowering.h (working copy)
@@ -97,12 +97,14 @@
/// getBasePointerSaveOffset - Return the previous frame offset to save the
/// base pointer.
- static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) {
+ static unsigned getBasePointerSaveOffset(bool isPPC64,
+ bool isDarwinABI,
+ bool isPIC) {
if (isDarwinABI)
return isPPC64 ? -16U : -8U;
// SVR4 ABI: First slot in the general register save area.
- return isPPC64 ? -16U : -8U;
+ return isPPC64 ? -16U : isPIC ? -12U : -8U;
}
/// getLinkageSize - Return the size of the PowerPC ABI linkage area.
Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp (revision 213379)
+++ 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"
@@ -275,9 +276,21 @@
DebugLoc dl;
if (PPCLowering->getPointerTy() == MVT::i32) {
- GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass);
+ if (PPCSubTarget->isTargetELF())
+ GlobalBaseReg = PPC::R30;
+ 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);
+ }
} else {
GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass);
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR8));
@@ -1445,7 +1458,13 @@
return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain);
}
case PPCISD::TOC_ENTRY: {
- assert (PPCSubTarget->isPPC64() && "Only supported for 64-bit ABI");
+ 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,
Index: lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelLowering.cpp (revision 213379)
+++ lib/Target/PowerPC/PPCISelLowering.cpp (working copy)
@@ -1491,10 +1491,9 @@
HiOpFlags = PPCII::MO_HA;
LoOpFlags = PPCII::MO_LO;
- // 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.
- bool isPIC = TM.getRelocationModel() == Reloc::PIC_ &&
- TM.getSubtarget<PPCSubtarget>().isDarwin();
+ // Don't use the pic base if not in PIC relocation model.
+ bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
+
if (isPIC) {
HiOpFlags |= PPCII::MO_PIC_FLAG;
LoOpFlags |= PPCII::MO_PIC_FLAG;
@@ -1550,6 +1549,15 @@
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,15 @@
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 +1717,14 @@
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 =
@@ -3357,15 +3382,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_OR_STUB;
}
// If the callee is a GlobalAddress/ExternalSymbol node (quite common,
@@ -3381,13 +3409,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_OR_STUB;
}
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(),
@@ -6613,7 +6643,10 @@
// Since FP is only updated here but NOT referenced, it's treated as GPR.
unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
- unsigned BP = (PVT == MVT::i64) ? PPC::X30 : PPC::R30;
+ unsigned BP = (PVT == MVT::i64) ? PPC::X30 :
+ (Subtarget.isSVR4ABI() &&
+ MF->getTarget().getRelocationModel() == Reloc::PIC_ ?
+ PPC::R29 : PPC::R30);
MachineInstrBuilder MIB;
Index: lib/Target/PowerPC/PPCInstrInfo.td
===================================================================
--- lib/Target/PowerPC/PPCInstrInfo.td (revision 213379)
+++ 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,18 @@
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))]>;
+// 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", []>;
+
+
// 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 213379)
+++ 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_OR_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_OR_STUB && isDarwin) {
MachineModuleInfoImpl::StubValueTy &StubSym =
getMachOMMI(AP).getFnStubEntry(Sym);
if (StubSym.getPointer())
@@ -136,6 +139,9 @@
break;
}
+ if (MO.getTargetFlags() == PPCII::MO_PLT_OR_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 213379)
+++ 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 213379)
+++ lib/Target/PowerPC/PPCMachineFunctionInfo.h (working copy)
@@ -92,6 +92,12 @@
/// 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)
: FramePointerSaveIndex(0),
@@ -109,7 +115,9 @@
VarArgsStackOffset(0),
VarArgsNumGPR(0),
VarArgsNumFPR(0),
- CRSpillFrameIndex(0) {}
+ CRSpillFrameIndex(0),
+ MF(MF),
+ 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/PPCRegisterInfo.cpp
===================================================================
--- lib/Target/PowerPC/PPCRegisterInfo.cpp (revision 213379)
+++ lib/Target/PowerPC/PPCRegisterInfo.cpp (working copy)
@@ -199,7 +199,16 @@
if (PPCFI->needsFP(MF))
Reserved.set(PPC::R31);
- if (hasBasePointer(MF))
+ if (hasBasePointer(MF)) {
+ if (Subtarget.isSVR4ABI() && !Subtarget.isPPC64() &&
+ MF.getTarget().getRelocationModel() == Reloc::PIC_)
+ Reserved.set(PPC::R29);
+ else
+ Reserved.set(PPC::R30);
+ }
+
+ if (Subtarget.isSVR4ABI() && !Subtarget.isPPC64() &&
+ MF.getTarget().getRelocationModel() == Reloc::PIC_)
Reserved.set(PPC::R30);
// Reserve Altivec registers when Altivec is unavailable.
@@ -843,7 +852,14 @@
if (!hasBasePointer(MF))
return getFrameRegister(MF);
- return Subtarget.isPPC64() ? PPC::X30 : PPC::R30;
+ if (Subtarget.isPPC64())
+ return PPC::X30;
+
+ if (Subtarget.isSVR4ABI() &&
+ MF.getTarget().getRelocationModel() == Reloc::PIC_)
+ return PPC::R29;
+
+ return PPC::R30;
}
bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
Index: lib/Target/PowerPC/PPCSubtarget.h
===================================================================
--- lib/Target/PowerPC/PPCSubtarget.h (revision 213379)
+++ 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(); }
Index: test/CodeGen/PowerPC/available-externally.ll
===================================================================
--- test/CodeGen/PowerPC/available-externally.ll (revision 213379)
+++ test/CodeGen/PowerPC/available-externally.ll (working copy)
@@ -1,7 +1,8 @@
; RUN: llc < %s -relocation-model=static | FileCheck %s -check-prefix=STATIC
-; RUN: llc < %s -relocation-model=pic | FileCheck %s -check-prefix=PIC
+; RUN: llc < %s -relocation-model=pic -mtriple=powerpc-apple-darwin8 | FileCheck %s -check-prefix=PIC
+; RUN: llc < %s -relocation-model=pic -mtriple=powerpc-unknown-linux | FileCheck %s -check-prefix=PICELF
; RUN: llc < %s -relocation-model=pic -mtriple=powerpc64-apple-darwin8 | FileCheck %s -check-prefix=PIC64
-; RUN: llc < %s -relocation-model=dynamic-no-pic | FileCheck %s -check-prefix=DYNAMIC
+; RUN: llc < %s -relocation-model=dynamic-no-pic -mtriple=powerpc-apple-darwin8 | FileCheck %s -check-prefix=DYNAMIC
; RUN: llc < %s -relocation-model=dynamic-no-pic -mtriple=powerpc64-apple-darwin8 | FileCheck %s -check-prefix=DYNAMIC64
; PR4482
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
@@ -18,6 +19,10 @@
; PIC: bl L_exact_log2$stub
; PIC: blr
+; PICELF: foo:
+; PICELF: bl exact_log2 at PLT
+; PICELF: blr
+
; PIC64: _foo:
; PIC64: bl L_exact_log2$stub
; PIC64: blr
Index: test/CodeGen/PowerPC/ppc32-pic.ll
===================================================================
--- test/CodeGen/PowerPC/ppc32-pic.ll (revision 0)
+++ test/CodeGen/PowerPC/ppc32-pic.ll (working copy)
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck %s
+ at foobar = common global i32 0, align 4
+
+define i32 @foo() {
+entry:
+ %0 = load i32* @foobar, align 4
+ ret i32 %0
+}
+
+; CHECK: [[POFF:\.L[0-9]+\$poff]]:
+; CHECK-NEXT: .long .L.TOC.-[[PB:\.L[0-9]+\$pb]]
+; CHECK-NEXT: foo:
+; CHECK: bl [[PB]]
+; CHECK-NEXT: [[PB]]:
+; CHECK: mflr 30
+; CHECK: lwz [[REG:[0-9]+]], [[POFF]]-[[PB]](30)
+; CHECK-NEXT: add 30, [[REG]], 30
+; CHECK: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.L.TOC.(30)
+; CHECK: lwz {{[0-9]+}}, 0([[VREG]])
+; CHECK: [[VREF]]:
+; CHECK-NEXT: .long foobar
Index: test/CodeGen/PowerPC/sections.ll
===================================================================
--- test/CodeGen/PowerPC/sections.ll (revision 213379)
+++ test/CodeGen/PowerPC/sections.ll (working copy)
@@ -1,5 +1,6 @@
; Test to make sure that bss sections are printed with '.section' directive.
; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck %s -check-prefix=PIC
@A = global i32 0
@@ -6,3 +7,6 @@
; CHECK: .section .bss,"aw", at nobits
; CHECK: .globl A
+; PIC: .section .got2,"aw", at progbits
+; PIC: .section .bss,"aw", at nobits
+; PIC: .globl A
Index: test/CodeGen/PowerPC/stack-realign.ll
===================================================================
--- test/CodeGen/PowerPC/stack-realign.ll (revision 213379)
+++ test/CodeGen/PowerPC/stack-realign.ll (working copy)
@@ -1,5 +1,7 @@
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -disable-fp-elim < %s | FileCheck -check-prefix=CHECK-FP %s
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu -disable-fp-elim < %s | FileCheck -check-prefix=CHECK-32 %s
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu -disable-fp-elim -relocation-model=pic < %s | FileCheck -check-prefix=CHECK-32-PIC %s
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
target triple = "powerpc64-unknown-linux-gnu"
@@ -7,6 +9,8 @@
declare void @bar(i32*)
+ at barbaz = external global i32
+
define void @goo(%struct.s* byval nocapture readonly %a) {
entry:
%x = alloca [2 x i32], align 32
@@ -16,8 +20,9 @@
store i32 %0, i32* %arrayidx, align 32
%b = getelementptr inbounds %struct.s* %a, i64 0, i32 1
%1 = load i32* %b, align 4
+ %2 = load i32* @barbaz, align 4
%arrayidx2 = getelementptr inbounds [2 x i32]* %x, i64 0, i64 1
- store i32 %1, i32* %arrayidx2, align 4
+ store i32 %2, i32* %arrayidx2, align 4
call void @bar(i32* %arrayidx)
ret void
}
@@ -69,6 +74,24 @@
; CHECK-FP-DAG: mtlr 0
; CHECK-FP: blr
+; CHECK-32-LABEL: @goo
+; CHECK-32-DAG: mflr 0
+; CHECK-32-DAG: rlwinm [[REG:[0-9]+]], 1, 0, 27, 31
+; CHECK-32-DAG: stw 30, -8(1)
+; CHECK-32-DAG: mr 30, 1
+; CHECK-32-DAG: stw 0, 4(1)
+; CHECK-32-DAG: subfic 0, [[REG]], -64
+; CHECK-32: stwux 1, 1, 0
+
+; CHECK-32-PIC-LABEL: @goo
+; CHECK-32-PIC-DAG: mflr 0
+; CHECK-32-PIC-DAG: rlwinm [[REG:[0-9]+]], 1, 0, 27, 31
+; CHECK-32-PIC-DAG: stw 29, -12(1)
+; CHECK-32-PIC-DAG: mr 29, 1
+; CHECK-32-PIC-DAG: stw 0, 4(1)
+; CHECK-32-PIC-DAG: subfic 0, [[REG]], -64
+; CHECK-32-PIC: stwux 1, 1, 0
+
; The large-frame-size case.
define void @hoo(%struct.s* byval nocapture readonly %a) {
entry:
@@ -99,6 +122,34 @@
; CHECK: blr
+; CHECK-32-LABEL: @hoo
+
+; CHECK-32-DAG: lis [[REG1:[0-9]+]], -13
+; CHECK-32-DAG: rlwinm [[REG3:[0-9]+]], 1, 0, 27, 31
+; CHECK-32-DAG: mflr 0
+; CHECK-32-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
+; CHECK-32-DAG: stw 30, -8(1)
+; CHECK-32-DAG: mr 30, 1
+; CHECK-32-DAG: stw 0, 4(1)
+; CHECK-32-DAG: subfc 0, [[REG3]], [[REG2]]
+; CHECK-32: stwux 1, 1, 0
+
+; CHECK-32: blr
+
+; CHECK-32-PIC-LABEL: @hoo
+
+; CHECK-32-PIC-DAG: lis [[REG1:[0-9]+]], -13
+; CHECK-32-PIC-DAG: rlwinm [[REG3:[0-9]+]], 1, 0, 27, 31
+; CHECK-32-PIC-DAG: mflr 0
+; CHECK-32-PIC-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
+; CHECK-32-PIC-DAG: stw 29, -12(1)
+; CHECK-32-PIC-DAG: mr 29, 1
+; CHECK-32-PIC-DAG: stw 0, 4(1)
+; CHECK-32-PIC-DAG: subfc 0, [[REG3]], [[REG2]]
+; CHECK-32: stwux 1, 1, 0
+
+; CHECK-32: blr
+
; Make sure that the FP save area is still allocated correctly relative to
; where r30 is saved.
define void @loo(%struct.s* byval nocapture readonly %a) {
Index: test/MC/PowerPC/ppc-reloc.s
===================================================================
--- test/MC/PowerPC/ppc-reloc.s (revision 0)
+++ test/MC/PowerPC/ppc-reloc.s (working copy)
@@ -0,0 +1,17 @@
+# RUN: llvm-mc -triple=powerpc-unknown-linux-gnu -filetype=obj %s | \
+# RUN: llvm-readobj -r | FileCheck %s
+ .section .text
+
+ .globl foo
+ .type foo, at function
+ .align 2
+foo:
+ bl printf at plt
+.LC1:
+ .size foo, . - foo
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (2) .rela.text {
+# CHECK-NEXT: 0x0 R_PPC_PLTREL24 printf 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
More information about the llvm-commits
mailing list