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 | bde7f8ffe2ab7608ad9cb0e8cecff0fb97733d8f (patch) | |
tree | fcbe6d52c54bfac63d5fce129490e7859df4ae0d /llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | |
parent | 4ec02b02ac3e58576903b6202f97006f6e0f4942 (diff) | |
download | bcm5719-llvm-bde7f8ffe2ab7608ad9cb0e8cecff0fb97733d8f.tar.gz bcm5719-llvm-bde7f8ffe2ab7608ad9cb0e8cecff0fb97733d8f.zip |
add RESTORE_CR and support CR unspills
llvm-svn: 145961
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCInstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index f28d07c8a61..fe103c65771 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -511,7 +511,7 @@ PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, NewMIs.back()->addMemOperand(MF, MMO); } -void +bool PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, @@ -541,28 +541,36 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), FrameIdx)); } else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) { - // FIXME: We need a scatch reg here. The trouble with using R0 is that - // it's possible for the stack frame to be so big the save location is - // out of range of immediate offsets, necessitating another register. - // We hack this on Darwin by reserving R2. It's probably broken on Linux - // at the moment. - unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? - PPC::R2 : PPC::R0; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), - ScratchReg), FrameIdx)); - - // 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. - NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) - .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) - .addImm(31)); + if ((!DisablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || + (!DisablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, + get(PPC::RESTORE_CR), DestReg) + , FrameIdx)); + return true; + } else { + // FIXME: We need a scatch reg here. The trouble with using R0 is that + // it's possible for the stack frame to be so big the save location is + // out of range of immediate offsets, necessitating another register. + // We hack this on Darwin by reserving R2. It's probably broken on Linux + // at the moment. + unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? + PPC::R2 : PPC::R0; + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), + ScratchReg), FrameIdx)); + + // 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. + NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) + .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) + .addImm(31)); + } + + NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg) + .addReg(ScratchReg)); } - - NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg) - .addReg(ScratchReg)); } else if (PPC::CRBITRCRegisterClass->hasSubClassEq(RC)) { unsigned Reg = 0; @@ -607,6 +615,8 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, } else { llvm_unreachable("Unknown regclass!"); } + + return false; } void @@ -619,7 +629,10 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, SmallVector<MachineInstr*, 4> NewMIs; DebugLoc DL; if (MI != MBB.end()) DL = MI->getDebugLoc(); - LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs); + if (LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs)) { + PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); + FuncInfo->setSpillsCR(); + } for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); |