From 70c9be77f76b795b991a92705ddb85f3b4d5d89a Mon Sep 17 00:00:00 2001 From: Tilmann Scheller Date: Fri, 1 Aug 2014 11:08:51 +0000 Subject: [PATCH] [ARM] Make the assembler reject unpredictable pre/post-indexed ARM LDR instructions. 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 | 13 +++++++++++++ test/MC/ARM/diagnostics.s | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b2c03510827..9a2745bec00 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -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]. diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index 83af10d2091..b2ba184c746 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -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: ^