Proper encoding for VLDM and VSTM instructions. The register lists for these
instructions have to distinguish between lists of single- and double-precision
registers in order for the ASM matcher to do a proper job. In all other
respects, a list of single- or double-precision registers are the same as a list
of GPR registers.

llvm-svn: 119460
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index e00ced2..b07fb64 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -107,6 +107,8 @@
     Memory,
     Register,
     RegisterList,
+    DPRRegisterList,
+    SPRRegisterList,
     Token
   } Kind;
 
@@ -168,6 +170,8 @@
       Reg = o.Reg;
       break;
     case RegisterList:
+    case DPRRegisterList:
+    case SPRRegisterList:
       RegList = o.RegList;
       break;
     case Immediate:
@@ -204,7 +208,8 @@
   }
 
   const SmallVectorImpl<unsigned> &getRegList() const {
-    assert(Kind == RegisterList && "Invalid access!");
+    assert((Kind == RegisterList || Kind == DPRRegisterList ||
+            Kind == SPRRegisterList) && "Invalid access!");
     return *RegList.Registers;
   }
 
@@ -217,6 +222,8 @@
   bool isImm() const { return Kind == Immediate; }
   bool isReg() const { return Kind == Register; }
   bool isRegList() const { return Kind == RegisterList; }
+  bool isDPRRegList() const { return Kind == DPRRegisterList; }
+  bool isSPRRegList() const { return Kind == SPRRegisterList; }
   bool isToken() const { return Kind == Token; }
   bool isMemory() const { return Kind == Memory; }
   bool isMemMode5() const {
@@ -264,6 +271,14 @@
       Inst.addOperand(MCOperand::CreateReg(*I));
   }
 
+  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
+    addRegListOperands(Inst, N);
+  }
+
+  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
+    addRegListOperands(Inst, N);
+  }
+
   void addImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     addExpr(Inst, getImm());
@@ -327,7 +342,14 @@
   static ARMOperand *
   CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
                 SMLoc StartLoc, SMLoc EndLoc) {
-    ARMOperand *Op = new ARMOperand(RegisterList);
+    KindTy Kind = RegisterList;
+
+    if (ARM::DPRRegClass.contains(Regs.front().first))
+      Kind = DPRRegisterList;
+    else if (ARM::SPRRegClass.contains(Regs.front().first))
+      Kind = SPRRegisterList;
+
+    ARMOperand *Op = new ARMOperand(Kind);
     Op->RegList.Registers = new SmallVector<unsigned, 32>();
     for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
            I = Regs.begin(), E = Regs.end(); I != E; ++I)
@@ -387,7 +409,9 @@
   case Register:
     OS << "<register " << getReg() << (!Reg.Writeback ? ">" : "!>");
     break;
-  case RegisterList: {
+  case RegisterList:
+  case DPRRegisterList:
+  case SPRRegisterList: {
     OS << "<register_list ";
 
     const SmallVectorImpl<unsigned> &RegList = getRegList();