[ARM] Make the assembler reject unpredictable pre/post-indexed ARM STR instructions.
authorTilmann Scheller <t.scheller@samsung.com>
Wed, 23 Jul 2014 12:38:17 +0000 (12:38 +0000)
committerTilmann Scheller <t.scheller@samsung.com>
Wed, 23 Jul 2014 12:38:17 +0000 (12:38 +0000)
The ARM ARM prohibits STR instructions with writeback into the source register. With this commit this constraint is now enforced and we stop assembling STR instructions with unpredictable behavior.

llvm-svn: 213745

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/test/MC/ARM/diagnostics.s

index b62706c..5e074c4 100644 (file)
@@ -5728,6 +5728,19 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
                    "source operands must be sequential");
     return false;
   }
+  case ARM::STR_PRE_IMM:
+  case ARM::STR_PRE_REG:
+  case ARM::STR_POST_IMM:
+  case ARM::STR_POST_REG: {
+    // Rt must be different from Rn.
+    const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
+    const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
+
+    if (Rt == Rn)
+      return Error(Operands[3]->getStartLoc(),
+                   "source register and base register can't be identical");
+    return false;
+  }
   case ARM::SBFX:
   case ARM::UBFX: {
     // Width must be in range [1, 32-lsb].
index 88c5fb5..e26566d 100644 (file)
@@ -491,3 +491,20 @@ foo2:
 @ CHECK-ERRORS:                 ^
 @ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
 @ CHECK-ERRORS:                  ^
+
+        str r0, [r0, #4]!
+        str r0, [r0, r1]!
+        str r0, [r0], #4
+        str r0, [r0], r1
+@ CHECK-ERRORS: error: source register and base register can't be identical
+@ CHECK-ERRORS: str r0, [r0, #4]!
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: source register and base register can't be identical
+@ CHECK-ERRORS: str r0, [r0, r1]!
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: source register and base register can't be identical
+@ CHECK-ERRORS: str r0, [r0], #4
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: source register and base register can't be identical
+@ CHECK-ERRORS: str r0, [r0], r1
+@ CHECK-ERRORS:         ^