diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-02-07 09:17:36 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-02-07 09:17:36 +0000 |
commit | 78c5a9422d07804df3ec02c7e926d1e5e05d7d24 (patch) | |
tree | 7baea785e5cbb4995f8a049cf5a37739b346c349 /llvm/lib/Target/ARM/ARMRegisterInfo.cpp | |
parent | 2ff0d3a2ab9e017553964734c20303973a4a4998 (diff) | |
download | bcm5719-llvm-78c5a9422d07804df3ec02c7e926d1e5e05d7d24.tar.gz bcm5719-llvm-78c5a9422d07804df3ec02c7e926d1e5e05d7d24.zip |
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
Diffstat (limited to 'llvm/lib/Target/ARM/ARMRegisterInfo.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMRegisterInfo.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp index 644fcec63c5..ac2ed8ebab5 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp @@ -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); |