[llvm-commits] [llvm] r137986 - in /llvm/trunk: lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp test/CodeGen/Thumb2/thumb2-ldm.ll test/MC/ARM/basic-thumb-instructions.s test/MC/ARM/thumb-diagnostics.s test/MC/Disassembler/ARM/thumb-tests.txt

Jim Grosbach grosbach at apple.com
Thu Aug 18 14:50:53 PDT 2011


Author: grosbach
Date: Thu Aug 18 16:50:53 2011
New Revision: 137986

URL: http://llvm.org/viewvc/llvm-project?rev=137986&view=rev
Log:
Thumb assembly parsing and encoding for LDM instruction.

Fix base register type and canonicallize to the "ldm" spelling rather than
"ldmia." Add diagnostics for incorrect writeback token and out-of-range
registers.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
    llvm/trunk/test/CodeGen/Thumb2/thumb2-ldm.ll
    llvm/trunk/test/MC/ARM/basic-thumb-instructions.s
    llvm/trunk/test/MC/ARM/thumb-diagnostics.s
    llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Thu Aug 18 16:50:53 2011
@@ -683,8 +683,8 @@
                            InstrItinClass itin_upd, bits<6> T1Enc,
                            bit L_bit, string baseOpc> {
   def IA :
-    T1I<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
-        itin, !strconcat(asm, "ia${p}\t$Rn, $regs"), []>,
+    T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
+        itin, !strconcat(asm, "${p}\t$Rn, $regs"), []>,
        T1Encoding<T1Enc> {
     bits<3> Rn;
     bits<8> regs;
@@ -696,7 +696,7 @@
     InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, 
                  "$Rn = $wb", itin_upd>,
     PseudoInstExpansion<(!cast<Instruction>(!strconcat(baseOpc, "IA"))
-                       GPR:$Rn, pred:$p, reglist:$regs)> {
+                       tGPR:$Rn, pred:$p, reglist:$regs)> {
     let Size = 2;
     let OutOperandList = (outs GPR:$wb);
     let InOperandList = (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops);
@@ -720,6 +720,11 @@
 
 } // neverHasSideEffects
 
+def : InstAlias<"ldm${p} $Rn!, $regs",
+                (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)>,
+        Requires<[IsThumb, IsThumb1Only]>;
+
+
 let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
 def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
                IIC_iPop,

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Aug 18 16:50:53 2011
@@ -2988,6 +2988,29 @@
                    "bitfield width must be in range [1,32-lsb]");
     return false;
   }
+  case ARM::tLDMIA: {
+    // Thumb LDM instructions are writeback iff the base register is not
+    // in the register list.
+    unsigned Rn = Inst.getOperand(0).getReg();
+    bool doesWriteback = true;
+    for (unsigned i = 3; i < Inst.getNumOperands(); ++i) {
+      unsigned Reg = Inst.getOperand(i).getReg();
+      if (Reg == Rn)
+        doesWriteback = false;
+      // Anything other than a low register isn't legal here.
+      if (getARMRegisterNumbering(Reg) > 7)
+        return Error(Operands[4]->getStartLoc(),
+                     "registers must be in range r0-r7");
+    }
+    // If we should have writeback, then there should be a '!' token.
+    if (doesWriteback &&
+        (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
+         static_cast<ARMOperand*>(Operands[3])->getToken() != "!"))
+      return Error(Operands[2]->getStartLoc(),
+                   "writeback operator '!' expected");
+
+    break;
+  }
   }
 
   return false;

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Aug 18 16:50:53 2011
@@ -155,9 +155,9 @@
     }
 
     if (Opcode == ARM::tLDMIA)
-      O << "\tldmia";
+      O << "\tldm";
     else if (Opcode == ARM::tSTMIA)
-      O << "\tstmia";
+      O << "\tstm";
     else
       llvm_unreachable("Unknown opcode!");
 

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-ldm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-ldm.ll?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-ldm.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-ldm.ll Thu Aug 18 16:50:53 2011
@@ -15,7 +15,7 @@
 define i32 @t2() {
 ; CHECK: t2:
 ; CHECK: push {r7, lr}
-; CHECK: ldmia
+; CHECK: ldm
 ; CHECK: pop {r7, pc}
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3)           ; <i32> [#uses=1]

Modified: llvm/trunk/test/MC/ARM/basic-thumb-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-thumb-instructions.s?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/basic-thumb-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/basic-thumb-instructions.s Thu Aug 18 16:50:53 2011
@@ -162,3 +162,15 @@
         eors r4, r5
 
 @ CHECK: eors	r4, r5                  @ encoding: [0x6c,0x40]
+
+
+ at ------------------------------------------------------------------------------
+@ LDM
+ at ------------------------------------------------------------------------------
+        ldm r3, {r0, r1, r2, r3, r4, r5, r6, r7}
+        ldm r2!, {r1, r3, r4, r5, r7}
+        ldm r1, {r1}
+
+@ CHECK: ldm	r3, {r0, r1, r2, r3, r4, r5, r6, r7} @ encoding: [0xff,0xcb]
+@ CHECK: ldm	r2!, {r1, r3, r4, r5, r7} @ encoding: [0xba,0xca]
+@ CHECK: ldm	r1, {r1}                @ encoding: [0x02,0xc9]

Modified: llvm/trunk/test/MC/ARM/thumb-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-diagnostics.s?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s Thu Aug 18 16:50:53 2011
@@ -39,3 +39,13 @@
 error: invalid operand for instruction
         bkpt #-1
              ^
+
+@ Invalid writeback and register lists for LDM
+        ldm r2!, {r5, r8}
+        ldm r2, {r5, r7}
+@ CHECK-ERRORS: error: registers must be in range r0-r7
+@ CHECK-ERRORS:         ldm r2!, {r5, r8}
+@ CHECK-ERRORS:                  ^
+@ CHECK-ERRORS: error: writeback operator '!' expected
+@ CHECK-ERRORS:         ldm r2, {r5, r7}
+@ CHECK-ERRORS:             ^

Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt?rev=137986&r1=137985&r2=137986&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Thu Aug 18 16:50:53 2011
@@ -27,7 +27,7 @@
 # CHECK:	cmn.w	r0, #31
 0x10 0xf1 0x1f 0x0f
 
-# CHECK:	ldmia	r0!, {r1}
+# CHECK:	ldm	r0!, {r1}
 0x02 0xc8
 
 # CHECK:	ldr	r5, #432
@@ -112,7 +112,7 @@
 # CHECK:	lsleq	r1, r0, #28
 0x01 0x07
 
-# CHECK:	stmiane	r0!, {r1, r2, r3}
+# CHECK:	stmne	r0!, {r1, r2, r3}
 0x0e 0xc0
 
 # IT block end
@@ -146,13 +146,13 @@
 # CHECK:	stmdb.w	sp, {r0, r2, r3, r8, r11, lr}
 0x0d 0xe9 0x0d 0x49
 
-# CHECK:	stmia	r5!, {r0, r1, r2, r3, r4}
+# CHECK:	stm	r5!, {r0, r1, r2, r3, r4}
 0x1f 0xc5
 
-# CHECK:	ldmia	r5, {r0, r1, r2, r3, r4, r5}
+# CHECK:	ldm	r5, {r0, r1, r2, r3, r4, r5}
 0x3f 0xcd
 
-# CHECK:	ldmia	r5!, {r0, r1, r2, r3, r4}
+# CHECK:	ldm	r5!, {r0, r1, r2, r3, r4}
 0x1f 0xcd
 
 # CHECK:	addw	r0, pc, #1050





More information about the llvm-commits mailing list