diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-08-18 21:50:53 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-08-18 21:50:53 +0000 |
commit | 93b3eff62322803a520e183fdc294bffd6d99bfa (patch) | |
tree | 4cd6de7ba49f9322993c3f4ca1c4f30c6fa27920 /lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | b48ef3a3ec7f527b0c76e7fbb37bbaac63b7c6aa (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.cpp | 23 |
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; |