summaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorTilmann Scheller <tilmann.scheller@googlemail.com>2013-09-30 16:11:48 +0000
committerTilmann Scheller <tilmann.scheller@googlemail.com>2013-09-30 16:11:48 +0000
commit9724873c317d2b170cfea87cdf2a402fcd7c6c7d (patch)
treebe6d0f82e9e4c6788a6b6551b7d2f5b43f4ca280 /lib/Target/ARM
parent7373265e1a2042032dfa48f1d0accca4e5b68fe1 (diff)
downloadllvm-9724873c317d2b170cfea87cdf2a402fcd7c6c7d.tar.gz
llvm-9724873c317d2b170cfea87cdf2a402fcd7c6c7d.tar.bz2
llvm-9724873c317d2b170cfea87cdf2a402fcd7c6c7d.tar.xz
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191678 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 6d6255f2cc..d360a24114 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -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: