mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
In thumb mode, R3 is reserved, but it can be live in to the function. If
that is the case, whenever we use it as a scratch register, save it to R12 first and then restore it after the use. This is a temporary and truly horrible workaround! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33999 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1f253d6e97
commit
8bed6c968f
@ -40,6 +40,10 @@ class ARMFunctionInfo : public MachineFunctionInfo {
|
|||||||
/// far jump.
|
/// far jump.
|
||||||
bool LRForceSpilled;
|
bool LRForceSpilled;
|
||||||
|
|
||||||
|
/// R3IsLiveIn - True if R3 is live in to this function.
|
||||||
|
///
|
||||||
|
bool R3IsLiveIn;
|
||||||
|
|
||||||
/// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
|
/// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
|
||||||
/// spill stack offset.
|
/// spill stack offset.
|
||||||
unsigned FramePtrSpillOffset;
|
unsigned FramePtrSpillOffset;
|
||||||
@ -75,13 +79,15 @@ class ARMFunctionInfo : public MachineFunctionInfo {
|
|||||||
public:
|
public:
|
||||||
ARMFunctionInfo() :
|
ARMFunctionInfo() :
|
||||||
isThumb(false),
|
isThumb(false),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), LRForceSpilled(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false),
|
||||||
|
LRForceSpilled(false), R3IsLiveIn(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
|
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
|
||||||
|
|
||||||
ARMFunctionInfo(MachineFunction &MF) :
|
ARMFunctionInfo(MachineFunction &MF) :
|
||||||
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
|
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), LRForceSpilled(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false),
|
||||||
|
LRForceSpilled(false), R3IsLiveIn(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
|
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
|
||||||
|
|
||||||
@ -96,6 +102,9 @@ public:
|
|||||||
bool isLRForceSpilled() const { return LRForceSpilled; }
|
bool isLRForceSpilled() const { return LRForceSpilled; }
|
||||||
void setLRIsForceSpilled(bool s) { LRForceSpilled = s; }
|
void setLRIsForceSpilled(bool s) { LRForceSpilled = s; }
|
||||||
|
|
||||||
|
bool isR3IsLiveIn() const { return R3IsLiveIn; }
|
||||||
|
void setR3IsLiveIn(bool l) { R3IsLiveIn = l; }
|
||||||
|
|
||||||
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
|
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
|
||||||
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
|
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
|
||||||
|
|
||||||
|
@ -401,7 +401,10 @@ void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
if (NumBytes <= 255 && NumBytes >= 0)
|
if (NumBytes <= 255 && NumBytes >= 0)
|
||||||
BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
|
BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
|
||||||
else
|
else if (NumBytes < 0 && NumBytes >= -255) {
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::tNEG), LdReg).addReg(LdReg);
|
||||||
|
} else
|
||||||
emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII);
|
emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII);
|
||||||
|
|
||||||
// Emit add / sub.
|
// Emit add / sub.
|
||||||
@ -811,7 +814,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
// being storing here. If that's the case, we do the following:
|
// being storing here. If that's the case, we do the following:
|
||||||
// r12 = r2
|
// r12 = r2
|
||||||
// Use r2 to materialize sp + offset
|
// Use r2 to materialize sp + offset
|
||||||
// str r12, r2
|
// str r3, r2
|
||||||
// r2 = r12
|
// r2 = r12
|
||||||
unsigned ValReg = MI.getOperand(0).getReg();
|
unsigned ValReg = MI.getOperand(0).getReg();
|
||||||
unsigned TmpReg = ARM::R3;
|
unsigned TmpReg = ARM::R3;
|
||||||
@ -820,6 +823,8 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
|
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
|
||||||
TmpReg = ARM::R2;
|
TmpReg = ARM::R2;
|
||||||
}
|
}
|
||||||
|
if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn())
|
||||||
|
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R3);
|
||||||
if (Opcode == ARM::tSpill) {
|
if (Opcode == ARM::tSpill) {
|
||||||
if (FrameReg == ARM::SP)
|
if (FrameReg == ARM::SP)
|
||||||
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
||||||
@ -835,10 +840,12 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode.
|
MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode.
|
||||||
else
|
else
|
||||||
MI.addRegOperand(0, false); // tSTR has an extra register operand.
|
MI.addRegOperand(0, false); // tSTR has an extra register operand.
|
||||||
if (ValReg == ARM::R3) {
|
|
||||||
MachineBasicBlock::iterator NII = next(II);
|
MachineBasicBlock::iterator NII = next(II);
|
||||||
|
if (ValReg == ARM::R3)
|
||||||
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
|
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
|
||||||
}
|
if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn())
|
||||||
|
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R3).addReg(ARM::R12);
|
||||||
} else
|
} else
|
||||||
assert(false && "Unexpected opcode!");
|
assert(false && "Unexpected opcode!");
|
||||||
} else {
|
} else {
|
||||||
@ -1032,6 +1039,15 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
||||||
|
|
||||||
if (isThumb) {
|
if (isThumb) {
|
||||||
|
// Check if R3 is live in. It might have to be used as a scratch register.
|
||||||
|
for (MachineFunction::livein_iterator I=MF.livein_begin(),E=MF.livein_end();
|
||||||
|
I != E; ++I) {
|
||||||
|
if ((*I).first == ARM::R3) {
|
||||||
|
AFI->setR3IsLiveIn(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
|
// Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
|
||||||
NumBytes = (NumBytes + 3) & ~3;
|
NumBytes = (NumBytes + 3) & ~3;
|
||||||
MFI->setStackSize(NumBytes);
|
MFI->setStackSize(NumBytes);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user