Index: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -611,6 +611,14 @@ } } + int PBPOffset = 0; + if (FI->usesPICBase()) { + MachineFrameInfo *FFI = MF.getFrameInfo(); + int PBPIndex = FI->getPICBasePointerSaveIndex(); + assert(PBPIndex && "No PIC Base Pointer Save Slot!"); + PBPOffset = FFI->getObjectOffset(PBPIndex); + } + // Get stack alignments. unsigned MaxAlign = MFI->getMaxAlignment(); if (HasBP && MaxAlign > 1) @@ -644,12 +652,11 @@ .addImm(FPOffset) .addReg(SPReg); - if (isPIC && !isDarwinABI && !isPPC64 && - MF.getInfo()->usesPICBase()) + if (FI->usesPICBase()) // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe. BuildMI(MBB, MBBI, dl, StoreInst) .addReg(PPC::R30) - .addImm(-8U) + .addImm(PBPOffset) .addReg(SPReg); if (HasBP) @@ -763,6 +770,15 @@ .addCFIIndex(CFIIndex); } + if (FI->usesPICBase()) { + // Describe where FP was saved, at a fixed offset from CFA. + unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true); + CFIIndex = MMI.addFrameInst( + MCCFIInstruction::createOffset(nullptr, Reg, PBPOffset)); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + } + if (HasBP) { // Describe where BP was saved, at a fixed offset from CFA. unsigned Reg = MRI->getDwarfRegNum(BPReg, true); @@ -932,6 +948,14 @@ } } + int PBPOffset = 0; + if (FI->usesPICBase()) { + MachineFrameInfo *FFI = MF.getFrameInfo(); + int PBPIndex = FI->getPICBasePointerSaveIndex(); + assert(PBPIndex && "No PIC Base Pointer Save Slot!"); + PBPOffset = FFI->getObjectOffset(PBPIndex); + } + bool UsesTCRet = RetOpcode == PPC::TCRETURNri || RetOpcode == PPC::TCRETURNdi || RetOpcode == PPC::TCRETURNai || @@ -1011,12 +1035,11 @@ .addImm(FPOffset) .addReg(SPReg); - if (isPIC && !isDarwinABI && !isPPC64 && - MF.getInfo()->usesPICBase()) + if (FI->usesPICBase()) // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe. BuildMI(MBB, MBBI, dl, LoadInst) .addReg(PPC::R30) - .addImm(-8U) + .addImm(PBPOffset) .addReg(SPReg); if (HasBP) @@ -1135,6 +1158,14 @@ FI->setBasePointerSaveIndex(BPSI); } + // Reserve stack space for the PIC Base register (R30). + // Only used in SVR4 32-bit. + if (FI->usesPICBase()) { + int PBPSI = FI->getPICBasePointerSaveIndex(); + PBPSI = MFI->CreateFixedObject(4, -8, true); + FI->setPICBasePointerSaveIndex(PBPSI); + } + // Reserve stack space to move the linkage area to in case of a tail call. int TCSPDelta = 0; if (MF.getTarget().Options.GuaranteedTailCallOpt && @@ -1266,6 +1297,15 @@ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); } + if (PFI->usesPICBase()) { + HasGPSaveArea = true; + + int FI = PFI->getPICBasePointerSaveIndex(); + assert(FI && "No PIC Base Pointer Save Slot!"); + + FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); + } + const PPCRegisterInfo *RegInfo = static_cast(MF.getSubtarget().getRegisterInfo()); if (RegInfo->hasBasePointer(MF)) { Index: llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h +++ llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h @@ -35,6 +35,9 @@ /// Frame index where the old base pointer is stored. int BasePointerSaveIndex; + /// Frame index where the old PIC base pointer is stored. + int PICBasePointerSaveIndex; + /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current /// function. This is only valid after the initial scan of the function by /// PEI. @@ -103,6 +106,7 @@ : FramePointerSaveIndex(0), ReturnAddrSaveIndex(0), BasePointerSaveIndex(0), + PICBasePointerSaveIndex(0), HasSpills(false), HasNonRISpills(false), SpillsCR(false), @@ -128,6 +132,9 @@ int getBasePointerSaveIndex() const { return BasePointerSaveIndex; } void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; } + int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; } + void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; } + unsigned getMinReservedArea() const { return MinReservedArea; } void setMinReservedArea(unsigned size) { MinReservedArea = size; } Index: llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll +++ llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll @@ -1,9 +1,12 @@ ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=LARGE-BSS %s @bar = common global i32 0, align 4 +declare i32 @call_foo(i32, ...) + define i32 @foo() { entry: %0 = load i32* @bar, align 4 + %call = call i32 (i32, ...)* @call_foo(i32 %0, i32 0, i32 1, i32 2, i32 4, i32 8, i32 16, i32 32, i32 64) ret i32 %0 } @@ -18,8 +21,9 @@ ; LARGE-BSS: mflr 30 ; LARGE-BSS: lwz [[REG:[0-9]+]], [[POFF]]-[[PB]](30) ; LARGE-BSS-NEXT: add 30, [[REG]], 30 -; LARGE-BSS: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.LTOC(30) +; LARGE-BSS-DAG: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.LTOC(30) ; LARGE-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]]) -; LARGE-BSS-DAG: lwz 30, -8(1) +; LARGE-BSS-DAG: stw {{[0-9]+}}, 8(1) +; LARGE-BSS: lwz 30, -8(1) ; LARGE-BSS: [[VREF]]: ; LARGE-BSS-NEXT: .long bar Index: llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll +++ llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll @@ -1,18 +1,24 @@ ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=SMALL-BSS %s @bar = common global i32 0, align 4 +declare i32 @call_foo(i32, ...) + define i32 @foo() { entry: %0 = load i32* @bar, align 4 - ret i32 %0 + %call = call i32 (i32, ...)* @call_foo(i32 %0, i32 0, i32 1, i32 2, i32 4, i32 8, i32 16, i32 32, i32 64) + ret i32 0 } !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIC Level", i32 1} ; SMALL-BSS-LABEL:foo: ; SMALL-BSS: stw 30, -8(1) +; SMALL-BSS: stwu 1, -32(1) ; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4 ; SMALL-BSS: mflr 30 -; SMALL-BSS: lwz [[VREG:[0-9]+]], bar@GOT(30) +; SMALL-BSS-DAG: stw {{[0-9]+}}, 8(1) +; SMALL-BSS-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30) ; SMALL-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]]) -; SMALL-BSS-DAG: lwz 30, -8(1) +; SMALL-BSS: bl call_foo@PLT +; SMALL-BSS: lwz 30, -8(1)