mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-30 19:55:11 +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);
|
NewMIs.back()->addMemOperand(MF, MMO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||||
unsigned DestReg, int FrameIdx,
|
unsigned DestReg, int FrameIdx,
|
||||||
const TargetRegisterClass *RC,
|
const TargetRegisterClass *RC,
|
||||||
@ -541,28 +541,36 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
|||||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg),
|
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg),
|
||||||
FrameIdx));
|
FrameIdx));
|
||||||
} else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) {
|
} else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) {
|
||||||
// FIXME: We need a scatch reg here. The trouble with using R0 is that
|
if ((!DisablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) ||
|
||||||
// it's possible for the stack frame to be so big the save location is
|
(!DisablePPC64RS && TM.getSubtargetImpl()->isPPC64())) {
|
||||||
// out of range of immediate offsets, necessitating another register.
|
NewMIs.push_back(addFrameReference(BuildMI(MF, DL,
|
||||||
// We hack this on Darwin by reserving R2. It's probably broken on Linux
|
get(PPC::RESTORE_CR), DestReg)
|
||||||
// at the moment.
|
, FrameIdx));
|
||||||
unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
|
return true;
|
||||||
PPC::R2 : PPC::R0;
|
} else {
|
||||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
|
// FIXME: We need a scatch reg here. The trouble with using R0 is that
|
||||||
ScratchReg), FrameIdx));
|
// it's possible for the stack frame to be so big the save location is
|
||||||
|
// out of range of immediate offsets, necessitating another register.
|
||||||
// If the reloaded register isn't CR0, shift the bits right so that they are
|
// We hack this on Darwin by reserving R2. It's probably broken on Linux
|
||||||
// in the right CR's slot.
|
// at the moment.
|
||||||
if (DestReg != PPC::CR0) {
|
unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
|
||||||
unsigned ShiftBits = getPPCRegisterNumbering(DestReg)*4;
|
PPC::R2 : PPC::R0;
|
||||||
// rlwinm r11, r11, 32-ShiftBits, 0, 31.
|
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
|
||||||
NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg)
|
ScratchReg), FrameIdx));
|
||||||
.addReg(ScratchReg).addImm(32-ShiftBits).addImm(0)
|
|
||||||
.addImm(31));
|
// 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)) {
|
} else if (PPC::CRBITRCRegisterClass->hasSubClassEq(RC)) {
|
||||||
|
|
||||||
unsigned Reg = 0;
|
unsigned Reg = 0;
|
||||||
@ -607,6 +615,8 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
|||||||
} else {
|
} else {
|
||||||
llvm_unreachable("Unknown regclass!");
|
llvm_unreachable("Unknown regclass!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -619,7 +629,10 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|||||||
SmallVector<MachineInstr*, 4> NewMIs;
|
SmallVector<MachineInstr*, 4> NewMIs;
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
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)
|
for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
|
||||||
MBB.insert(MI, NewMIs[i]);
|
MBB.insert(MI, NewMIs[i]);
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class PPCInstrInfo : public PPCGenInstrInfo {
|
|||||||
unsigned SrcReg, bool isKill, int FrameIdx,
|
unsigned SrcReg, bool isKill, int FrameIdx,
|
||||||
const TargetRegisterClass *RC,
|
const TargetRegisterClass *RC,
|
||||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||||
void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
bool LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||||
unsigned DestReg, int FrameIdx,
|
unsigned DestReg, int FrameIdx,
|
||||||
const TargetRegisterClass *RC,
|
const TargetRegisterClass *RC,
|
||||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
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),
|
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 isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
|
||||||
let isReturn = 1, Uses = [LR, RM] in
|
let isReturn = 1, Uses = [LR, RM] in
|
||||||
def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p),
|
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,
|
unsigned FrameIndex, int SPAdj,
|
||||||
RegScavenger *RS) const {
|
RegScavenger *RS) const {
|
||||||
// Get the instruction.
|
// Get the instruction.
|
||||||
MachineInstr &MI = *II; // ; SPILL_CR <SrcReg>, <offset>, <FI>
|
MachineInstr &MI = *II; // ; SPILL_CR <SrcReg>, <offset>
|
||||||
// Get the instruction's basic block.
|
// Get the instruction's basic block.
|
||||||
MachineBasicBlock &MBB = *MI.getParent();
|
MachineBasicBlock &MBB = *MI.getParent();
|
||||||
DebugLoc dl = MI.getDebugLoc();
|
DebugLoc dl = MI.getDebugLoc();
|
||||||
@ -494,6 +494,44 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II,
|
|||||||
MBB.erase(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
|
void
|
||||||
PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
int SPAdj, RegScavenger *RS) const {
|
int SPAdj, RegScavenger *RS) const {
|
||||||
@ -539,12 +577,16 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for pseudo-op SPILL_CR.
|
// Special case for pseudo-ops SPILL_CR and RESTORE_CR.
|
||||||
if (requiresRegisterScavenging(MF))
|
if (requiresRegisterScavenging(MF)) {
|
||||||
if (OpC == PPC::SPILL_CR) {
|
if (OpC == PPC::SPILL_CR) {
|
||||||
lowerCRSpilling(II, FrameIndex, SPAdj, RS);
|
lowerCRSpilling(II, FrameIndex, SPAdj, RS);
|
||||||
return;
|
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).
|
// Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
|
||||||
MI.getOperand(FIOperandNo).ChangeToRegister(TFI->hasFP(MF) ?
|
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
|
// The offset doesn't fit into a single register, scavenge one to build the
|
||||||
// offset in.
|
// offset in.
|
||||||
// FIXME: figure out what SPAdj is doing here.
|
|
||||||
|
|
||||||
unsigned SReg;
|
unsigned SReg;
|
||||||
if (requiresRegisterScavenging(MF))
|
if (requiresRegisterScavenging(MF))
|
||||||
|
@ -57,6 +57,8 @@ public:
|
|||||||
int SPAdj, RegScavenger *RS) const;
|
int SPAdj, RegScavenger *RS) const;
|
||||||
void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex,
|
void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex,
|
||||||
int SPAdj, RegScavenger *RS) const;
|
int SPAdj, RegScavenger *RS) const;
|
||||||
|
void lowerCRRestore(MachineBasicBlock::iterator II, unsigned FrameIndex,
|
||||||
|
int SPAdj, RegScavenger *RS) const;
|
||||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
int SPAdj, RegScavenger *RS = NULL) const;
|
int SPAdj, RegScavenger *RS = NULL) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user