mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
add RESTORE_CR and support CR unspills
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145961 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
16588e794c
commit
d21e930eac
@ -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]);
|
||||
|
||||
|
@ -72,7 +72,7 @@ class PPCInstrInfo : public PPCGenInstrInfo {
|
||||
unsigned SrcReg, bool isKill, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
bool LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
|
@ -402,6 +402,11 @@ let usesCustomInserter = 1, // Expanded after instruction selection.
|
||||
def SPILL_CR : Pseudo<(outs), (ins GPRC:$cond, memri:$F),
|
||||
"", []>;
|
||||
|
||||
// RESTORE_CR - Indicate that we're restoring the CR register (previously
|
||||
// spilled), so we'll need to scavenge a register for it.
|
||||
def RESTORE_CR : Pseudo<(outs GPRC:$cond), (ins memri:$F),
|
||||
"", []>;
|
||||
|
||||
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
|
||||
let isReturn = 1, Uses = [LR, RM] in
|
||||
def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p),
|
||||
|
@ -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))
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
int SPAdj, RegScavenger *RS) const;
|
||||
void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex,
|
||||
int SPAdj, RegScavenger *RS) const;
|
||||
void lowerCRRestore(MachineBasicBlock::iterator II, unsigned FrameIndex,
|
||||
int SPAdj, RegScavenger *RS) const;
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS = NULL) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user