aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-08-18 21:50:53 +0000
committerJim Grosbach <grosbach@apple.com>2011-08-18 21:50:53 +0000
commit93b3eff62322803a520e183fdc294bffd6d99bfa (patch)
tree4cd6de7ba49f9322993c3f4ca1c4f30c6fa27920 /lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parentb48ef3a3ec7f527b0c76e7fbb37bbaac63b7c6aa (diff)
Thumb assembly parsing and encoding for LDM instruction.
Fix base register type and canonicallize to the "ldm" spelling rather than "ldmia." Add diagnostics for incorrect writeback token and out-of-range registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 44c7a0a8d6..6977545511 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -2988,6 +2988,29 @@ validateInstruction(MCInst &Inst,
"bitfield width must be in range [1,32-lsb]");
return false;
}
+ case ARM::tLDMIA: {
+ // Thumb LDM instructions are writeback iff the base register is not
+ // in the register list.
+ unsigned Rn = Inst.getOperand(0).getReg();
+ bool doesWriteback = true;
+ for (unsigned i = 3; i < Inst.getNumOperands(); ++i) {
+ unsigned Reg = Inst.getOperand(i).getReg();
+ if (Reg == Rn)
+ doesWriteback = false;
+ // Anything other than a low register isn't legal here.
+ if (getARMRegisterNumbering(Reg) > 7)
+ return Error(Operands[4]->getStartLoc(),
+ "registers must be in range r0-r7");
+ }
+ // If we should have writeback, then there should be a '!' token.
+ if (doesWriteback &&
+ (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
+ static_cast<ARMOperand*>(Operands[3])->getToken() != "!"))
+ return Error(Operands[2]->getStartLoc(),
+ "writeback operator '!' expected");
+
+ break;
+ }
}
return false;