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:
Evan Cheng 2007-02-07 09:17:36 +00:00
parent 1f253d6e97
commit 8bed6c968f
2 changed files with 32 additions and 7 deletions

View File

@ -40,6 +40,10 @@ class ARMFunctionInfo : public MachineFunctionInfo {
/// far jump.
bool LRForceSpilled;
/// R3IsLiveIn - True if R3 is live in to this function.
///
bool R3IsLiveIn;
/// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
/// spill stack offset.
unsigned FramePtrSpillOffset;
@ -75,13 +79,15 @@ class ARMFunctionInfo : public MachineFunctionInfo {
public:
ARMFunctionInfo() :
isThumb(false),
VarArgsRegSaveSize(0), HasStackFrame(false), LRForceSpilled(false),
VarArgsRegSaveSize(0), HasStackFrame(false),
LRForceSpilled(false), R3IsLiveIn(false),
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
ARMFunctionInfo(MachineFunction &MF) :
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),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
@ -96,6 +102,9 @@ public:
bool isLRForceSpilled() const { return LRForceSpilled; }
void setLRIsForceSpilled(bool s) { LRForceSpilled = s; }
bool isR3IsLiveIn() const { return R3IsLiveIn; }
void setR3IsLiveIn(bool l) { R3IsLiveIn = l; }
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }

View File

@ -401,7 +401,10 @@ void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
if (NumBytes <= 255 && NumBytes >= 0)
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);
// 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:
// r12 = r2
// Use r2 to materialize sp + offset
// str r12, r2
// str r3, r2
// r2 = r12
unsigned ValReg = MI.getOperand(0).getReg();
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);
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 (FrameReg == ARM::SP)
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.
else
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);
}
if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn())
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R3).addReg(ARM::R12);
} else
assert(false && "Unexpected opcode!");
} else {
@ -1032,6 +1039,15 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
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.
NumBytes = (NumBytes + 3) & ~3;
MFI->setStackSize(NumBytes);