mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01: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! llvm-svn: 33999
This commit is contained in:
parent
8f5c613d03
commit
d5921e8a32
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user