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
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 44c7a0a..6977545 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -2988,6 +2988,29 @@
                    "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;