diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index 3244b904ee6..8541e1ba5cd 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 &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 3e98dbd254d..109e595900a 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 +