From 2fc792f86bd43f362aa14b09535427a98cee53a2 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 6 Feb 2007 00:23:31 +0000 Subject: [PATCH] eliminateFrameIndex() bug when frame pointer is used as base register. llvm-svn: 33945 --- llvm/lib/Target/ARM/ARMRegisterInfo.cpp | 50 +++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp index be4969a68424..ef54124b1bdf 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp @@ -386,6 +386,8 @@ void emitThumbRegPlusConstPool(MachineBasicBlock &MBB, const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg); if (DestReg == ARM::SP) MIB.addReg(BaseReg).addReg(LdReg); + else if (isSub) + MIB.addReg(BaseReg).addReg(LdReg); else MIB.addReg(LdReg).addReg(BaseReg); if (DestReg == ARM::SP) @@ -647,7 +649,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{ // MI would expand into a large number of instructions. Don't try to // simplify the immediate. if (NumMIs > 2) { - emitThumbRegPlusImmediate(MBB, II, DestReg, ARM::SP, Offset, TII); + emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII); MBB.erase(II); return; } @@ -705,7 +707,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{ case ARMII::AddrModeTs: { ImmIdx = i+1; InstrOffs = MI.getOperand(ImmIdx).getImm(); - NumBits = 8; + NumBits = (FrameReg == ARM::SP) ? 8 : 5; Scale = 4; break; } @@ -722,31 +724,33 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{ isSub = true; } - MachineOperand &ImmOp = MI.getOperand(ImmIdx); - int ImmedOffset = Offset / Scale; - unsigned Mask = (1 << NumBits) - 1; - if ((unsigned)Offset <= Mask * Scale) { - // Replace the FrameIndex with sp - MI.getOperand(i).ChangeToRegister(FrameReg, false); + if (!isSub || !isThumb) { + MachineOperand &ImmOp = MI.getOperand(ImmIdx); + int ImmedOffset = Offset / Scale; + unsigned Mask = (1 << NumBits) - 1; + if ((unsigned)Offset <= Mask * Scale) { + // Replace the FrameIndex with sp + MI.getOperand(i).ChangeToRegister(FrameReg, false); + if (isSub) + ImmedOffset |= 1 << NumBits; + ImmOp.ChangeToImmediate(ImmedOffset); + return; + } + + // Otherwise, it didn't fit. Pull in what we can to simplify the immed. + if (AddrMode == ARMII::AddrModeTs) { + // Thumb tLDRspi, tSTRspi. These will change to instructions that use + // a different base register. + NumBits = 5; + Mask = (1 << NumBits) - 1; + } + + ImmedOffset = ImmedOffset & Mask; if (isSub) ImmedOffset |= 1 << NumBits; ImmOp.ChangeToImmediate(ImmedOffset); - return; + Offset &= ~(Mask*Scale); } - - // Otherwise, it didn't fit. Pull in what we can to simplify the immediate. - if (AddrMode == ARMII::AddrModeTs) { - // Thumb tLDRspi, tSTRspi. These will change to instructions that use a - // different base register. - NumBits = 5; - Mask = (1 << NumBits) - 1; - } - - ImmedOffset = ImmedOffset & Mask; - if (isSub) - ImmedOffset |= 1 << NumBits; - ImmOp.ChangeToImmediate(ImmedOffset); - Offset &= ~(Mask*Scale); } // If we get here, the immediate doesn't fit into the instruction. We folded