aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-07-20 06:59:32 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-07-20 06:59:32 +0000
commitf6fe9579505be86420beea04f2c9ecb0fd7c55fd (patch)
tree856f7c6fb7784a907848f401ba68154c7e081dd7
parent401e10c4fbfcdcfade5065093e2ca97f69a1d144 (diff)
Fix PR4567. Thumb1 target was using the wrong instruction to handle sp = sub fp, #c.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76401 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/README-Thumb.txt4
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp14
2 files changed, 15 insertions, 3 deletions
diff --git a/lib/Target/ARM/README-Thumb.txt b/lib/Target/ARM/README-Thumb.txt
index cc017945d8..df94312d5f 100644
--- a/lib/Target/ARM/README-Thumb.txt
+++ b/lib/Target/ARM/README-Thumb.txt
@@ -244,3 +244,7 @@ to toggle the 's' bit since they do not set CPSR when they are inside IT blocks.
Make use of hi register variants of cmp: tCMPhir / tCMPZhir.
//===---------------------------------------------------------------------===//
+
+Thumb1 immediate field sometimes keep pre-scaled values. See
+Thumb1RegisterInfo::eliminateFrameIndex. This is inconsistent from ARM and
+Thumb2.
diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp
index dfb2774c4e..b723c853ef 100644
--- a/lib/Target/ARM/Thumb1RegisterInfo.cpp
+++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp
@@ -231,8 +231,16 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
if (DestReg != BaseReg)
DstNotEqBase = true;
NumBits = 8;
- Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
- NeedPred = NeedCC = true;
+ if (DestReg == ARM::SP) {
+ Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
+ assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
+ NumBits = 7;
+ Scale = 4;
+ } else {
+ Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
+ NumBits = 8;
+ NeedPred = NeedCC = true;
+ }
isTwoAddr = true;
}
@@ -447,7 +455,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
removeOperands(MI, i);
MachineInstrBuilder MIB(&MI);
AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
- .addImm(Offset/Scale));
+ .addImm(Offset / Scale));
} else {
MI.getOperand(i).ChangeToRegister(FrameReg, false);
MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);