[llvm] r191678 - [ARM] Assembler: ARM LDRD with writeback requires the base register to be different from the destination registers.
Tilmann Scheller
tilmann.scheller at googlemail.com
Mon Sep 30 09:11:48 PDT 2013
Author: tilmann
Date: Mon Sep 30 11:11:48 2013
New Revision: 191678
URL: http://llvm.org/viewvc/llvm-project?rev=191678&view=rev
Log:
[ARM] Assembler: ARM LDRD with writeback requires the base register to be different from the destination registers.
See ARM ARM A8.8.72.
Violating this constraint results in unpredictable behavior.
Modified:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/arm-ldrd.s
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=191678&r1=191677&r2=191678&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Sep 30 11:11:48 2013
@@ -5343,25 +5343,40 @@ validateInstruction(MCInst &Inst,
Inst.getOpcode() != ARM::t2Bcc)
return Error(Loc, "predicated instructions must be in IT block");
- switch (Inst.getOpcode()) {
+ const unsigned Opcode = Inst.getOpcode();
+ switch (Opcode) {
case ARM::LDRD:
case ARM::LDRD_PRE:
case ARM::LDRD_POST: {
- unsigned RtReg = Inst.getOperand(0).getReg();
+ const unsigned RtReg = Inst.getOperand(0).getReg();
+
// Rt can't be R14.
if (RtReg == ARM::LR)
return Error(Operands[3]->getStartLoc(),
"Rt can't be R14");
- unsigned Rt = MRI->getEncodingValue(RtReg);
+
+ const unsigned Rt = MRI->getEncodingValue(RtReg);
// Rt must be even-numbered.
if ((Rt & 1) == 1)
return Error(Operands[3]->getStartLoc(),
"Rt must be even-numbered");
+
// Rt2 must be Rt + 1.
- unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
+ const unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
if (Rt2 != Rt + 1)
return Error(Operands[3]->getStartLoc(),
"destination operands must be sequential");
+
+ if (Opcode == ARM::LDRD_PRE || Opcode == ARM::LDRD_POST) {
+ const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
+ // For addressing modes with writeback, the base register needs to be
+ // different from the destination registers.
+ if (Rn == Rt || Rn == Rt2)
+ return Error(Operands[3]->getStartLoc(),
+ "base register needs to be different from destination "
+ "registers");
+ }
+
return false;
}
case ARM::t2LDRDi8:
Modified: llvm/trunk/test/MC/ARM/arm-ldrd.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm-ldrd.s?rev=191678&r1=191677&r2=191678&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm-ldrd.s (original)
+++ llvm/trunk/test/MC/ARM/arm-ldrd.s Mon Sep 30 11:11:48 2013
@@ -3,6 +3,7 @@
// RUN: grep "error: Rt must be even-numbered" %t | count 7
// RUN: grep "error: Rt can't be R14" %t | count 7
// RUN: grep "error: destination operands must be sequential" %t | count 7
+// RUN: grep "error: base register needs to be different from destination registers" %t | count 4
// rdar://14479793
ldrd r1, r2, [pc, #0]
@@ -26,3 +27,8 @@ ldrd r0, r3, [r4, r5]
ldrd r1, r2, [r3], r4
ldrd lr, pc, [r3], r4
ldrd r0, r3, [r4], r5
+
+ldrd r0, r1, [r0], #4
+ldrd r0, r1, [r1], #4
+ldrd r0, r1, [r0, #4]!
+ldrd r0, r1, [r1, #4]!
More information about the llvm-commits
mailing list