diff options
author | Hal Finkel <hfinkel@anl.gov> | 2011-12-06 20:55:36 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2011-12-06 20:55:36 +0000 |
commit | d21e930eac3d99dd77ee33ea5826700b4bc97ae8 (patch) | |
tree | b16564f71be4419178b3f51f51232fc028515054 /lib/Target/PowerPC/PPCRegisterInfo.cpp | |
parent | 16588e794c7528c24fb15ee8e28653bffe78c3da (diff) |
add RESTORE_CR and support CR unspills
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145961 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCRegisterInfo.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCRegisterInfo.cpp | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index f6c4a3d06b..e47f65e243 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -459,7 +459,7 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex, int SPAdj, RegScavenger *RS) const { // Get the instruction. - MachineInstr &MI = *II; // ; SPILL_CR <SrcReg>, <offset>, <FI> + MachineInstr &MI = *II; // ; SPILL_CR <SrcReg>, <offset> // Get the instruction's basic block. MachineBasicBlock &MBB = *MI.getParent(); DebugLoc dl = MI.getDebugLoc(); @@ -494,6 +494,44 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II, MBB.erase(II); } +void PPCRegisterInfo::lowerCRRestore(MachineBasicBlock::iterator II, + unsigned FrameIndex, int SPAdj, + RegScavenger *RS) const { + // Get the instruction. + MachineInstr &MI = *II; // ; <DestReg> = RESTORE_CR <offset> + // Get the instruction's basic block. + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc dl = MI.getDebugLoc(); + + const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; + const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; + const TargetRegisterClass *RC = Subtarget.isPPC64() ? G8RC : GPRC; + unsigned Reg = findScratchRegister(II, RS, RC, SPAdj); + unsigned DestReg = MI.getOperand(0).getReg(); + assert(MI.definesRegister(DestReg) && + "RESTORE_CR does not define its destination"); + bool LP64 = Subtarget.isPPC64(); + + addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::LWZ8 : PPC::LWZ), + Reg), FrameIndex); + + // If the reloaded register isn't CR0, shift the bits right so that they are + // in the right CR's slot. + if (DestReg != PPC::CR0) { + unsigned ShiftBits = getPPCRegisterNumbering(DestReg)*4; + // rlwinm r11, r11, 32-ShiftBits, 0, 31. + BuildMI(MBB, II, dl, TII.get(PPC::RLWINM), Reg) + .addReg(Reg).addImm(32-ShiftBits).addImm(0) + .addImm(31); + } + + BuildMI(MBB, II, dl, TII.get(PPC::MTCRF), DestReg) + .addReg(Reg); + + // Discard the pseudo instruction. + MBB.erase(II); +} + void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, RegScavenger *RS) const { @@ -539,12 +577,16 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, return; } - // Special case for pseudo-op SPILL_CR. - if (requiresRegisterScavenging(MF)) + // Special case for pseudo-ops SPILL_CR and RESTORE_CR. + if (requiresRegisterScavenging(MF)) { if (OpC == PPC::SPILL_CR) { lowerCRSpilling(II, FrameIndex, SPAdj, RS); return; + } else if (OpC == PPC::RESTORE_CR) { + lowerCRRestore(II, FrameIndex, SPAdj, RS); + return; } + } // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). MI.getOperand(FIOperandNo).ChangeToRegister(TFI->hasFP(MF) ? @@ -594,7 +636,6 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // The offset doesn't fit into a single register, scavenge one to build the // offset in. - // FIXME: figure out what SPAdj is doing here. unsigned SReg; if (requiresRegisterScavenging(MF)) |