]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
[ARM] Make the assembler reject unpredictable pre/post-indexed ARM LDR instructions.
authorTilmann Scheller <t.scheller@samsung.com>
Fri, 1 Aug 2014 11:08:51 +0000 (11:08 +0000)
committerTilmann Scheller <t.scheller@samsung.com>
Fri, 1 Aug 2014 11:08:51 +0000 (11:08 +0000)
The ARM ARM prohibits LDR instructions with writeback into the destination register. With this commit this constraint is now enforced and we stop assembling LDR instructions with unpredictable behavior.

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

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

index b2c03510827653f5ad765fec4401d2e6bb99251f..9a2745bec006518069c0234db72906e8f956b669 100644 (file)
@@ -5747,6 +5747,19 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
                    "source register and base register can't be identical");
     return false;
   }
+  case ARM::LDR_PRE_IMM:
+  case ARM::LDR_PRE_REG:
+  case ARM::LDR_POST_IMM:
+  case ARM::LDR_POST_REG: {
+    // Rt must be different from Rn.
+    const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
+    const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
+
+    if (Rt == Rn)
+      return Error(Operands[3]->getStartLoc(),
+                   "destination 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 83af10d2091d4bc526461b957e5119976c137145..b2ba184c746ec4e60f50afa1ee041ec5ea66f2fe 100644 (file)
@@ -540,3 +540,20 @@ foo2:
 @ CHECK-ERRORS: error: source register and base register can't be identical
 @ CHECK-ERRORS: strb r0, [r0], r1
 @ CHECK-ERRORS:          ^
+
+        ldr r0, [r0, #4]!
+        ldr r0, [r0, r1]!
+        ldr r0, [r0], #4
+        ldr r0, [r0], r1
+@ CHECK-ERRORS: error: destination register and base register can't be identical
+@ CHECK-ERRORS: ldr r0, [r0, #4]!
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: destination register and base register can't be identical
+@ CHECK-ERRORS: ldr r0, [r0, r1]!
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: destination register and base register can't be identical
+@ CHECK-ERRORS: ldr r0, [r0], #4
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: destination register and base register can't be identical
+@ CHECK-ERRORS: ldr r0, [r0], r1
+@ CHECK-ERRORS:         ^