ARM assembler should accept shift-by-zero for any shifted-immediate operand.
authorJim Grosbach <grosbach@apple.com>
Thu, 22 Dec 2011 18:04:04 +0000 (18:04 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 22 Dec 2011 18:04:04 +0000 (18:04 +0000)
Just treat it as-if the shift wasn't there at all. 'as' compatibility.

rdar://10604767

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147153 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/arm-aliases.s [new file with mode: 0644]

index d70511ff556da3132045c77d355864e23190fc9a..3cb7818b0bed95d6aa6d3bca82feeefe336f7c2b 100644 (file)
@@ -6201,6 +6201,39 @@ processInstruction(MCInst &Inst,
     }
     return false;
   }
+  case ARM::ANDrsi:
+  case ARM::ORRrsi:
+  case ARM::EORrsi:
+  case ARM::BICrsi:
+  case ARM::SUBrsi:
+  case ARM::ADDrsi: {
+    unsigned newOpc;
+    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
+    if (SOpc == ARM_AM::rrx) return false;
+    switch (Inst.getOpcode()) {
+    default: assert("unexpected opcode!");
+    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
+    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
+    case ARM::EORrsi: newOpc = ARM::EORrr; break;
+    case ARM::BICrsi: newOpc = ARM::BICrr; break;
+    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
+    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
+    }
+    // If the shift is by zero, use the non-shifted instruction definition.
+    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) {
+      MCInst TmpInst;
+      TmpInst.setOpcode(newOpc);
+      TmpInst.addOperand(Inst.getOperand(0));
+      TmpInst.addOperand(Inst.getOperand(1));
+      TmpInst.addOperand(Inst.getOperand(2));
+      TmpInst.addOperand(Inst.getOperand(4));
+      TmpInst.addOperand(Inst.getOperand(5));
+      TmpInst.addOperand(Inst.getOperand(6));
+      Inst = TmpInst;
+      return true;
+    }
+    return false;
+  }
   case ARM::t2IT: {
     // The mask bits for all but the first condition are represented as
     // the low bit of the condition code value implies 't'. We currently
diff --git a/test/MC/ARM/arm-aliases.s b/test/MC/ARM/arm-aliases.s
new file mode 100644 (file)
index 0000000..d4ea0df
--- /dev/null
@@ -0,0 +1,17 @@
+@ RUN: llvm-mc -triple=armv7-apple-darwin -show-encoding < %s | FileCheck %s
+  .syntax unified
+
+@ Shift-by-zero should canonicalize to no shift at all (lsl #0 encoding)
+        add r1, r2, r3, lsl #0
+        sub r1, r2, r3, ror #0
+        eor r1, r2, r3, lsr #0
+        orr r1, r2, r3, asr #0
+        and r1, r2, r3, ror #0
+        bic r1, r2, r3, lsl #0
+
+@ CHECK: add   r1, r2, r3              @ encoding: [0x03,0x10,0x82,0xe0]
+@ CHECK: sub   r1, r2, r3              @ encoding: [0x03,0x10,0x42,0xe0]
+@ CHECK: eor   r1, r2, r3              @ encoding: [0x03,0x10,0x22,0xe0]
+@ CHECK: orr   r1, r2, r3              @ encoding: [0x03,0x10,0x82,0xe1]
+@ CHECK: and   r1, r2, r3              @ encoding: [0x03,0x10,0x02,0xe0]
+@ CHECK: bic   r1, r2, r3              @ encoding: [0x03,0x10,0xc2,0xe1]