aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp20
-rw-r--r--test/CodeGen/PowerPC/crsave.ll15
2 files changed, 28 insertions, 7 deletions
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp
index 3244b904ee..8541e1ba5c 100644
--- a/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -1141,12 +1141,14 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
// save slot via GPR12 (available in the prolog for 32- and 64-bit).
if (Subtarget.isPPC64()) {
// 64-bit: SP+8
+ bool is31 = needsFP(*MF);
+ unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MFCR8), PPC::X12));
MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::STW8))
.addReg(PPC::X12,
getKillRegState(true))
.addImm(8)
- .addReg(PPC::X1));
+ .addReg(FP8Reg));
} else {
// 32-bit: FP-relative. Note that we made sure CR2-CR4 all have
// the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
@@ -1170,7 +1172,8 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
}
static void
-restoreCRs(bool isPPC64, bool CR2Spilled, bool CR3Spilled, bool CR4Spilled,
+restoreCRs(bool isPPC64, bool is31,
+ bool CR2Spilled, bool CR3Spilled, bool CR4Spilled,
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI, unsigned CSIIndex) {
@@ -1182,9 +1185,10 @@ restoreCRs(bool isPPC64, bool CR2Spilled, bool CR3Spilled, bool CR4Spilled,
if (isPPC64) {
// 64-bit: SP+8
+ unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::LWZ8), PPC::X12)
.addImm(8)
- .addReg(PPC::X1));
+ .addReg(FP8Reg));
RestoreOp = PPC::MTCRF8;
MoveReg = PPC::X12;
} else {
@@ -1297,7 +1301,9 @@ PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
// least one CR register, restore all spilled CRs together.
if ((CR2Spilled || CR3Spilled || CR4Spilled)
&& !(PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
- restoreCRs(Subtarget.isPPC64(), CR2Spilled, CR3Spilled, CR4Spilled,
+ bool is31 = needsFP(*MF);
+ restoreCRs(Subtarget.isPPC64(), is31,
+ CR2Spilled, CR3Spilled, CR4Spilled,
MBB, I, CSI, CSIIndex);
CR2Spilled = CR3Spilled = CR4Spilled = false;
}
@@ -1320,9 +1326,11 @@ PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
}
// If we haven't yet spilled the CRs, do so now.
- if (CR2Spilled || CR3Spilled || CR4Spilled)
- restoreCRs(Subtarget.isPPC64(), CR2Spilled, CR3Spilled, CR4Spilled,
+ if (CR2Spilled || CR3Spilled || CR4Spilled) {
+ bool is31 = needsFP(*MF);
+ restoreCRs(Subtarget.isPPC64(), is31, CR2Spilled, CR3Spilled, CR4Spilled,
MBB, I, CSI, CSIIndex);
+ }
return true;
}
diff --git a/test/CodeGen/PowerPC/crsave.ll b/test/CodeGen/PowerPC/crsave.ll
index 3e98dbd254..109e595900 100644
--- a/test/CodeGen/PowerPC/crsave.ll
+++ b/test/CodeGen/PowerPC/crsave.ll
@@ -1,5 +1,6 @@
; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC32
-; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64
+; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64-FP
+; RUN: llc -O0 -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64
declare void @foo()
@@ -23,6 +24,11 @@ entry:
; PPC64: lwz 12, 8(1)
; PPC64-NEXT: mtcrf 32, 12
+; PPC64-FP: mfcr 12
+; PPC64-FP-NEXT: stw 12, 8(31)
+; PPC64-FP: lwz 12, 8(31)
+; PPC64-FP-NEXT: mtcrf 32, 12
+
define i32 @test_cr234() nounwind {
entry:
%ret = alloca i32, align 4
@@ -47,3 +53,10 @@ entry:
; PPC64-NEXT: mtcrf 16, 12
; PPC64-NEXT: mtcrf 8, 12
+; PPC64-FP: mfcr 12
+; PPC64-FP-NEXT: stw 12, 8(31)
+; PPC64-FP: lwz 12, 8(31)
+; PPC64-FP-NEXT: mtcrf 32, 12
+; PPC64-FP-NEXT: mtcrf 16, 12
+; PPC64-FP-NEXT: mtcrf 8, 12
+