diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index 3b57390611b..d846365112d 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -297,6 +297,12 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const { unsigned FPReg = is31 ? PPC::R31 : PPC::R1; unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1; + const PPCRegisterInfo *RegInfo = + static_cast(MF.getTarget().getRegisterInfo()); + bool HasBP = RegInfo->hasBasePointer(MF); + unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg; + unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg; + for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE; ++BI) for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) { @@ -313,6 +319,13 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const { case PPC::FP8: MO.setReg(FP8Reg); break; + case PPC::BP: + MO.setReg(BPReg); + break; + case PPC::BP8: + MO.setReg(BP8Reg); + break; + } } } @@ -393,8 +406,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { BPOffset = FFI->getObjectOffset(BPIndex); } else { BPOffset = - PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI, - HasFP); + PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); } } @@ -417,7 +429,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { if (HasBP) BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) - .addReg(HasFP ? PPC::X30 : PPC::X31) + .addReg(PPC::X30) .addImm(BPOffset) .addReg(PPC::X1); @@ -448,7 +460,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { // FIXME: On PPC32 SVR4, FPOffset is negative and access to negative // offsets of R1 is not allowed. BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) - .addReg(HasFP ? PPC::R30 : PPC::R31) + .addReg(PPC::R30) .addImm(BPOffset) .addReg(PPC::R1); @@ -475,8 +487,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { if (HasBP) { // Save a copy of r1 as the base pointer. - BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), - HasFP ? PPC::R30 : PPC::R31) + BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R30) .addReg(PPC::R1) .addReg(PPC::R1); } @@ -527,8 +538,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { } else { // PPC64. if (HasBP) { // Save a copy of r1 as the base pointer. - BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), - HasFP ? PPC::X30 : PPC::X31) + BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X30) .addReg(PPC::X1) .addReg(PPC::X1); } @@ -597,8 +607,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { } if (HasBP) { - unsigned Reg = isPPC64 ? (HasFP ? PPC::X30 : PPC::X31) : - (HasFP ? PPC::R30 : PPC::R31); + unsigned Reg = isPPC64 ? PPC::X30 : PPC::R30; Reg = MRI->getDwarfRegNum(Reg, true); MMI.addFrameInst( MCCFIInstruction::createOffset(FrameLabel, Reg, BPOffset)); @@ -739,8 +748,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, BPOffset = FFI->getObjectOffset(BPIndex); } else { BPOffset = - PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI, - HasFP); + PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); } } @@ -836,7 +844,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, .addImm(FPOffset).addReg(PPC::X1); if (HasBP) - BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), HasFP ? PPC::X30 : PPC::X31) + BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X30) .addImm(BPOffset).addReg(PPC::X1); if (!MustSaveCRs.empty()) @@ -859,7 +867,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, .addImm(FPOffset).addReg(PPC::R1); if (HasBP) - BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), HasFP ? PPC::R30 : PPC::R31) + BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R30) .addImm(FPOffset).addReg(PPC::R1); if (MustSaveLR) @@ -968,7 +976,7 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, int BPSI = FI->getBasePointerSaveIndex(); if (!BPSI && RegInfo->hasBasePointer(MF)) { - int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI, needsFP(MF)); + int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI); // Allocate the frame index for the base pointer save area. BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true); // Save the result. diff --git a/lib/Target/PowerPC/PPCFrameLowering.h b/lib/Target/PowerPC/PPCFrameLowering.h index 9acf129be5b..7aab37e188f 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.h +++ b/lib/Target/PowerPC/PPCFrameLowering.h @@ -96,11 +96,7 @@ public: /// getBasePointerSaveOffset - Return the previous frame offset to save the /// base pointer. - static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI, - bool hasFP) { - if (!hasFP) - return getFramePointerSaveOffset(isPPC64, isDarwinABI); - + static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) { if (isDarwinABI) return isPPC64 ? -16U : -8U; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index a38201abd5a..fd225ccad56 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6084,6 +6084,7 @@ PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr *MI, // thisMBB: const int64_t LabelOffset = 1 * PVT.getStoreSize(); const int64_t TOCOffset = 3 * PVT.getStoreSize(); + const int64_t BPOffset = 4 * PVT.getStoreSize(); // Prepare IP either in reg. const TargetRegisterClass *PtrRC = getRegClassFor(PVT); @@ -6095,10 +6096,25 @@ PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr *MI, .addReg(PPC::X2) .addImm(TOCOffset) .addReg(BufReg); - MIB.setMemRefs(MMOBegin, MMOEnd); } + // Naked functions never have a base pointer, and so we use r1. For all + // other functions, this decision must be delayed until during PEI. + unsigned BaseReg; + if (MF->getFunction()->getAttributes().hasAttribute( + AttributeSet::FunctionIndex, Attribute::Naked)) + BaseReg = PPCSubTarget.isPPC64() ? PPC::X1 : PPC::R1; + else + BaseReg = PPCSubTarget.isPPC64() ? PPC::BP8 : PPC::BP; + + MIB = BuildMI(*thisMBB, MI, DL, + TII->get(PPCSubTarget.isPPC64() ? PPC::STD : PPC::STW)) + .addReg(BaseReg) + .addImm(BPOffset) + .addReg(BufReg); + MIB.setMemRefs(MMOBegin, MMOEnd); + // Setup MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::BCLalways)).addMBB(mainMBB); const PPCRegisterInfo *TRI = @@ -6170,12 +6186,14 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI, // 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; MachineInstrBuilder MIB; const int64_t LabelOffset = 1 * PVT.getStoreSize(); const int64_t SPOffset = 2 * PVT.getStoreSize(); const int64_t TOCOffset = 3 * PVT.getStoreSize(); + const int64_t BPOffset = 4 * PVT.getStoreSize(); unsigned BufReg = MI->getOperand(0).getReg(); @@ -6217,8 +6235,17 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI, } MIB.setMemRefs(MMOBegin, MMOEnd); - // FIXME: When we also support base pointers, that register must also be - // restored here. + // Reload BP + if (PVT == MVT::i64) { + MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), BP) + .addImm(BPOffset) + .addReg(BufReg); + } else { + MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), BP) + .addImm(BPOffset) + .addReg(BufReg); + } + MIB.setMemRefs(MMOBegin, MMOEnd); // Reload TOC if (PVT == MVT::i64 && PPCSubTarget.isSVR4ABI()) { diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 49de8da948f..fdc604a8457 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -152,6 +152,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { Reserved.set(PPC::FP); Reserved.set(PPC::FP8); + // The BP register is also not really a register, but is the representation + // of the base pointer register used by setjmp. + Reserved.set(PPC::BP); + Reserved.set(PPC::BP8); + // The counter registers must be reserved so that counter-based loops can // be correctly formed (and the mtctr instructions are not DCE'd). Reserved.set(PPC::CTR); @@ -178,14 +183,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { Reserved.set(PPC::X1); Reserved.set(PPC::X13); - if (PPCFI->needsFP(MF) || hasBasePointer(MF)) { + if (PPCFI->needsFP(MF)) Reserved.set(PPC::X31); - // If we need a base pointer, and we also have a frame pointer, then use - // r30 as the base pointer. - if (PPCFI->needsFP(MF) && hasBasePointer(MF)) - Reserved.set(PPC::X30); - } + if (hasBasePointer(MF)) + Reserved.set(PPC::X30); // The 64-bit SVR4 ABI reserves r2 for the TOC pointer. if (Subtarget.isSVR4ABI()) { @@ -193,12 +195,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { } } - if (PPCFI->needsFP(MF) || hasBasePointer(MF)) { + if (PPCFI->needsFP(MF)) Reserved.set(PPC::R31); - if (PPCFI->needsFP(MF) && hasBasePointer(MF)) - Reserved.set(PPC::R30); - } + if (hasBasePointer(MF)) + Reserved.set(PPC::R30); // Reserve Altivec registers when Altivec is unavailable. if (!Subtarget.hasAltivec()) @@ -675,15 +676,10 @@ unsigned PPCRegisterInfo::getEHHandlerRegister() const { } unsigned PPCRegisterInfo::getBaseRegister(const MachineFunction &MF) const { - const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); - if (!hasBasePointer(MF)) return getFrameRegister(MF); - if (!Subtarget.isPPC64()) - return TFI->hasFP(MF) ? PPC::R30 : PPC::R31; - else - return TFI->hasFP(MF) ? PPC::X30 : PPC::X31; + return Subtarget.isPPC64() ? PPC::X30 : PPC::R30; } bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const { diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td index 003e7c3562b..d566e2c3e52 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -94,6 +94,10 @@ def ZERO8 : GP8; def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">; def FP8 : GP8; +// Representations of the base pointer used by setjmp. +def BP : GPR<0 /* arbitrary */, "**BASE POINTER**">; +def BP8 : GP8; + // Condition register bits def CR0LT : CRBIT< 0, "0">; def CR0GT : CRBIT< 1, "1">; @@ -172,11 +176,11 @@ def RM: SPR<512, "**ROUNDING MODE**">; // then nonvolatiles in reverse order since stmw/lmw save from rN to r31 def GPRC : RegisterClass<"PPC", [i32], 32, (add (sequence "R%u", 2, 12), (sequence "R%u", 30, 13), - R31, R0, R1, FP)>; + R31, R0, R1, FP, BP)>; def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12), (sequence "X%u", 30, 14), - X31, X13, X0, X1, FP8)>; + X31, X13, X0, X1, FP8, BP8)>; // For some instructions r0 is special (representing the value 0 instead of // the value in the r0 register), and we use these register subclasses to diff --git a/test/CodeGen/PowerPC/sjlj.ll b/test/CodeGen/PowerPC/sjlj.ll index 7ea35dafc3f..571f3b2fdf8 100644 --- a/test/CodeGen/PowerPC/sjlj.ll +++ b/test/CodeGen/PowerPC/sjlj.ll @@ -20,6 +20,7 @@ entry: ; CHECK: ld [[REG2:[0-9]+]], 8([[REG]]) ; CHECK: ld 1, 16([[REG]]) ; CHECK: mtctr [[REG2]] +; CHECK: ld 30, 32([[REG]]) ; CHECK: ld 2, 24([[REG]]) ; CHECK: bctr @@ -99,6 +100,52 @@ return: ; preds = %if.end, %if.then ; CHECK-NOAV: blr } +define signext i32 @main2() #0 { +entry: + %a = alloca i8, align 64 + call void @bar(i8* %a) + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = call i8* @llvm.frameaddress(i32 0) + store i8* %0, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**) + %1 = call i8* @llvm.stacksave() + store i8* %1, i8** getelementptr (i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**), i32 2) + %2 = call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8*)) + %tobool = icmp ne i32 %2, 0 + br i1 %tobool, label %if.then, label %if.else + +if.then: ; preds = %entry + store i32 1, i32* %retval + br label %return + +if.else: ; preds = %entry + call void @foo() + br label %if.end + +if.end: ; preds = %if.else + store i32 0, i32* %retval + br label %return + +return: ; preds = %if.end, %if.then + %3 = load i32* %retval + ret i32 %3 + +; CHECK: @main2 + +; CHECK: addis [[REG:[0-9]+]], 2, env_sigill@toc@ha +; CHECK: std 31, env_sigill@toc@l([[REG]]) +; CHECK: addi [[REG]], [[REG]], env_sigill@toc@l +; CHECK: std [[REG]], [[OFF:[0-9]+]](31) # 8-byte Folded Spill +; CHECK: std 1, 16([[REG]]) +; CHECK: std 2, 24([[REG]]) +; CHECK: std 30, 32([[REG]]) +; CHECK: bcl 20, 31, + +; CHECK: blr +} + +declare void @bar(i8*) #3 + declare i8* @llvm.frameaddress(i32) #2 declare i8* @llvm.stacksave() #3 diff --git a/test/CodeGen/PowerPC/stack-realign.ll b/test/CodeGen/PowerPC/stack-realign.ll index 7bd28f6a7c2..f7b6d192c77 100644 --- a/test/CodeGen/PowerPC/stack-realign.ll +++ b/test/CodeGen/PowerPC/stack-realign.ll @@ -26,20 +26,20 @@ entry: ; CHECK-DAG: mflr 0 ; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59 -; CHECK-DAG: std 31, -8(1) -; CHECK-DAG: mr 31, 1 +; CHECK-DAG: std 30, -16(1) +; CHECK-DAG: mr 30, 1 ; CHECK-DAG: std 0, 16(1) ; CHECK-DAG: subfic 0, [[REG]], -160 ; CHECK: stdux 1, 1, 0 -; CHECK: .cfi_offset r31, -8 +; CHECK: .cfi_offset r30, -16 ; CHECK: .cfi_offset lr, 16 -; CHECK: std 3, 48(31) +; CHECK: std 3, 48(30) ; CHECK: ld 1, 0(1) ; CHECK-DAG: ld 0, 16(1) -; CHECK-DAG: ld 31, -8(1) +; CHECK-DAG: ld 30, -16(1) ; CHECK-DAG: mtlr 0 ; CHECK: blr @@ -91,8 +91,8 @@ entry: ; CHECK-DAG: rldicl [[REG3:[0-9]+]], 1, 0, 59 ; CHECK-DAG: mflr 0 ; CHECK-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51808 -; CHECK-DAG: std 31, -8(1) -; CHECK-DAG: mr 31, 1 +; CHECK-DAG: std 30, -16(1) +; CHECK-DAG: mr 30, 1 ; CHECK-DAG: std 0, 16(1) ; CHECK-DAG: subfc 0, [[REG3]], [[REG2]] ; CHECK: stdux 1, 1, 0 @@ -121,13 +121,13 @@ entry: ; CHECK-DAG: mflr 0 ; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59 -; CHECK-DAG: std 31, -24(1) -; CHECK-DAG: mr 31, 1 +; CHECK-DAG: std 30, -32(1) +; CHECK-DAG: mr 30, 1 ; CHECK-DAG: std 0, 16(1) -; CHECK-DAG: subfic 0, [[REG]], -160 +; CHECK-DAG: subfic 0, [[REG]], -192 ; CHECK: stdux 1, 1, 0 -; CHECK: stfd 30, -16(31) +; CHECK: stfd 30, -16(30) ; CHECK: blr