summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp38
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.h6
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp33
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp28
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.td8
-rw-r--r--test/CodeGen/PowerPC/sjlj.ll47
-rw-r--r--test/CodeGen/PowerPC/stack-realign.ll22
7 files changed, 130 insertions, 52 deletions
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp
index 3b57390611..d846365112 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<const PPCRegisterInfo*>(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 9acf129be5..7aab37e188 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 a38201abd5..fd225ccad5 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 49de8da948..fdc604a845 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 003e7c3562..d566e2c3e5 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -94,6 +94,10 @@ def ZERO8 : GP8<ZERO, "0">;
def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">;
def FP8 : GP8<FP, "**FRAME POINTER**">;
+// Representations of the base pointer used by setjmp.
+def BP : GPR<0 /* arbitrary */, "**BASE POINTER**">;
+def BP8 : GP8<BP, "**BASE POINTER**">;
+
// 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 7ea35dafc3..571f3b2fdf 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 7bd28f6a7c..f7b6d192c7 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