Fix PR4567. Thumb1 target was using the wrong instruction to handle sp = sub fp, #c.
authorEvan Cheng <evan.cheng@apple.com>
Mon, 20 Jul 2009 06:59:32 +0000 (06:59 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 20 Jul 2009 06:59:32 +0000 (06:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76401 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/README-Thumb.txt
lib/Target/ARM/Thumb1RegisterInfo.cpp

index cc017945d80c6701d53c0363eec889252225af07..df94312d5f391fefa8eb9c72d75f81266973db8d 100644 (file)
@@ -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.
index dfb2774c4e8bb58a8cd9a408d05a9da16bdfce5f..b723c853eff06e670962c0412f346fa3a0484d20 100644 (file)
@@ -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);