[llvm] r364172 - [ARM] Add MVE interleaving load/store family.

Simon Tatham via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 24 03:00:40 PDT 2019


Author: statham
Date: Mon Jun 24 03:00:39 2019
New Revision: 364172

URL: http://llvm.org/viewvc/llvm-project?rev=364172&view=rev
Log:
[ARM] Add MVE interleaving load/store family.

This adds the family of loads and stores with names like VLD20.8 and
VST42.32, which load and store parts of multiple q-registers in such a
way that executing both VLD20 and VLD21, or all four of VLD40..VLD43,
will distribute 2 or 4 vectors' worth of memory data across the lanes
of the same number of registers but in a transposed order.

In addition to the Tablegen descriptions of the instructions
themselves, this patch also adds encode and decode support for the
QQPR and QQQQPR register classes (representing the range of loaded or
stored vector registers), and tweaks to the parsing system for lists
of vector registers to make it return the right format in this case
(since, unlike NEON, MVE regards q-registers as primitive, and not
just an alias for two d-registers).

Added:
    llvm/trunk/test/MC/ARM/mve-interleave.s   (with props)
    llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt   (with props)
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h

Modified: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrMVE.td?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td Mon Jun 24 03:00:39 2019
@@ -126,6 +126,33 @@ def pred_basic_fp : VCMPPredicateOperand
   let EncoderMethod = "getRestrictedCondCodeOpValue";
 }
 
+// Register list operands for interleaving load/stores
+def VecList2QAsmOperand : AsmOperandClass {
+  let Name = "VecListTwoMQ";
+  let ParserMethod = "parseVectorList";
+  let RenderMethod = "addMVEVecListOperands";
+  let DiagnosticString = "operand must be a list of two consecutive "#
+                         "q-registers in range [q0,q7]";
+}
+
+def VecList2Q : RegisterOperand<QQPR, "printMVEVectorListTwoQ"> {
+  let ParserMatchClass = VecList2QAsmOperand;
+  let PrintMethod = "printMVEVectorList<2>";
+}
+
+def VecList4QAsmOperand : AsmOperandClass {
+  let Name = "VecListFourMQ";
+  let ParserMethod = "parseVectorList";
+  let RenderMethod = "addMVEVecListOperands";
+  let DiagnosticString = "operand must be a list of four consecutive "#
+                         "q-registers in range [q0,q7]";
+}
+
+def VecList4Q : RegisterOperand<QQQQPR, "printMVEVectorListFourQ"> {
+  let ParserMatchClass = VecList4QAsmOperand;
+  let PrintMethod = "printMVEVectorList<4>";
+}
+
 class MVE_MI<dag oops, dag iops, InstrItinClass itin, string asm,
              string ops, string cstr, list<dag> pattern>
   : Thumb2XI<oops, iops, AddrModeNone, 4, itin, !strconcat(asm, "\t", ops), cstr,
@@ -3111,6 +3138,113 @@ def MVE_VMOV_rr_q : MVE_VMOV_64bit<(outs
 
 // end of coproc mov
 
+// start of MVE interleaving load/store
+
+// Base class for the family of interleaving/deinterleaving
+// load/stores with names like VLD20.8 and VST43.32.
+class MVE_vldst24_base<bit writeback, bit fourregs, bits<2> stage, bits<2> size,
+                       bit load, dag Oops, dag loadIops, dag wbIops,
+                       string iname, string ops,
+                       string cstr, list<dag> pattern=[]>
+  : MVE_MI<Oops, !con(loadIops, wbIops), NoItinerary, iname, ops, cstr, pattern> {
+  bits<4> VQd;
+  bits<4> Rn;
+
+  let Inst{31-22} = 0b1111110010;
+  let Inst{21} = writeback;
+  let Inst{20} = load;
+  let Inst{19-16} = Rn;
+  let Inst{15-13} = VQd{2-0};
+  let Inst{12-9} = 0b1111;
+  let Inst{8-7} = size;
+  let Inst{6-5} = stage;
+  let Inst{4-1} = 0b0000;
+  let Inst{0} = fourregs;
+
+  let mayLoad = load;
+  let mayStore = !eq(load,0);
+}
+
+// A parameter class used to encapsulate all the ways the writeback
+// variants of VLD20 and friends differ from the non-writeback ones.
+class MVE_vldst24_writeback<bit b, dag Oo, dag Io,
+                            string sy="", string c="", string n=""> {
+  bit writeback = b;
+  dag Oops = Oo;
+  dag Iops = Io;
+  string syntax = sy;
+  string cstr = c;
+  string id_suffix = n;
+}
+
+// Another parameter class that encapsulates the differences between VLD2x
+// and VLD4x.
+class MVE_vldst24_nvecs<int n, list<int> s, bit b, RegisterOperand vl> {
+  int nvecs = n;
+  list<int> stages = s;
+  bit bit0 = b;
+  RegisterOperand VecList = vl;
+}
+
+// A third parameter class that distinguishes VLDnn.8 from .16 from .32.
+class MVE_vldst24_lanesize<int i, bits<2> b> {
+  int lanesize = i;
+  bits<2> sizebits = b;
+}
+
+// A base class for each direction of transfer: one for load, one for
+// store. I can't make these a fourth independent parametric tuple
+// class, because they have to take the nvecs tuple class as a
+// parameter, in order to find the right VecList operand type.
+
+class MVE_vld24_base<MVE_vldst24_nvecs n, bits<2> pat, bits<2> size,
+                     MVE_vldst24_writeback wb, string iname,
+                     list<dag> pattern=[]>
+  : MVE_vldst24_base<wb.writeback, n.bit0, pat, size, 1,
+                     !con((outs n.VecList:$VQd), wb.Oops),
+                     (ins n.VecList:$VQdSrc), wb.Iops,
+                     iname, "$VQd, $Rn" # wb.syntax,
+                     wb.cstr # ",$VQdSrc = $VQd", pattern>;
+
+class MVE_vst24_base<MVE_vldst24_nvecs n, bits<2> pat, bits<2> size,
+                     MVE_vldst24_writeback wb, string iname,
+                     list<dag> pattern=[]>
+  : MVE_vldst24_base<wb.writeback, n.bit0, pat, size, 0,
+                     wb.Oops, (ins n.VecList:$VQd), wb.Iops,
+                     iname, "$VQd, $Rn" # wb.syntax,
+                     wb.cstr, pattern>;
+
+// Actually define all the interleaving loads and stores, by a series
+// of nested foreaches over number of vectors (VLD2/VLD4); stage
+// within one of those series (VLDx0/VLDx1/VLDx2/VLDx3); size of
+// vector lane; writeback or no writeback.
+foreach n = [MVE_vldst24_nvecs<2, [0,1],     0, VecList2Q>,
+             MVE_vldst24_nvecs<4, [0,1,2,3], 1, VecList4Q>] in
+foreach stage = n.stages in
+foreach s = [MVE_vldst24_lanesize< 8, 0b00>,
+             MVE_vldst24_lanesize<16, 0b01>,
+             MVE_vldst24_lanesize<32, 0b10>] in
+foreach wb = [MVE_vldst24_writeback<
+                1, (outs rGPR:$wb), (ins t2_nosp_addr_offset_none:$Rn),
+                "!", "$Rn.base = $wb", "_wb">,
+              MVE_vldst24_writeback<0, (outs), (ins t2_addr_offset_none:$Rn)>] in {
+
+  // For each case within all of those foreaches, define the actual
+  // instructions. The def names are made by gluing together pieces
+  // from all the parameter classes, and will end up being things like
+  // MVE_VLD20_8 and MVE_VST43_16_wb.
+
+  def "MVE_VLD" # n.nvecs # stage # "_" # s.lanesize # wb.id_suffix
+    : MVE_vld24_base<n, stage, s.sizebits, wb,
+                     "vld" # n.nvecs # stage # "." # s.lanesize>;
+
+  def "MVE_VST" # n.nvecs # stage # "_" # s.lanesize # wb.id_suffix
+    : MVE_vst24_base<n, stage, s.sizebits, wb,
+                     "vst" # n.nvecs # stage # "." # s.lanesize>;
+}
+
+// end of MVE interleaving load/store
+
 class MVE_VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> pattern=[]>
   : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
   bits<3> fc;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Jun 24 03:00:39 2019
@@ -176,9 +176,9 @@ def MemNoOffsetT2NoSpAsmOperand
   : AsmOperandClass { let Name = "MemNoOffsetT2NoSp"; }
 def t2_nosp_addr_offset_none : MemOperand {
   let PrintMethod = "printAddrMode7Operand";
-  let DecoderMethod = "Decodet2rGPRRegisterClass";
+  let DecoderMethod = "DecoderGPRRegisterClass";
   let ParserMatchClass = MemNoOffsetT2NoSpAsmOperand;
-  let MIOperandInfo = (ops t2rGPR:$base);
+  let MIOperandInfo = (ops rGPR:$base);
 }
 
 // t2addrmode_imm12  := reg + imm12

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon Jun 24 03:00:39 2019
@@ -296,15 +296,6 @@ def rGPR : RegisterClass<"ARM", [i32], 3
   let DiagnosticType = "rGPR";
 }
 
-// t2rGPR : All Thumb 2 registers with the exception of SP and PC.
-def t2rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {
-  let AltOrders = [(add LR, t2rGPR), (trunc t2rGPR, 8)];
-  let AltOrderSelect = [{
-      return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
-  }];
-  let DiagnosticType = "rGPR";
-}
-
 // Thumb registers are R0-R7 normally. Some instructions can still use
 // the general GPR register class above (MOV, e.g.)
 def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)> {

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Jun 24 03:00:39 2019
@@ -1759,6 +1759,12 @@ public:
     return VectorList.Count == 1;
   }
 
+  bool isVecListTwoMQ() const {
+    return isSingleSpacedVectorList() && VectorList.Count == 2 &&
+           ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
+               VectorList.RegNum);
+  }
+
   bool isVecListDPair() const {
     if (!isSingleSpacedVectorList()) return false;
     return (ARMMCRegisterClasses[ARM::DPairRegClassID]
@@ -1792,6 +1798,12 @@ public:
     return VectorList.Count == 4;
   }
 
+  bool isVecListFourMQ() const {
+    return isSingleSpacedVectorList() && VectorList.Count == 4 &&
+           ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
+               VectorList.RegNum);
+  }
+
   bool isSingleSpacedVectorAllLanes() const {
     return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
   }
@@ -2550,6 +2562,11 @@ public:
     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
   }
 
+  void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+  }
+
   void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     int32_t Imm = Memory.OffsetImm->getValue();
@@ -2973,6 +2990,37 @@ public:
     Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
   }
 
+  void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+
+    // When we come here, the VectorList field will identify a range
+    // of q-registers by its base register and length, and it will
+    // have already been error-checked to be the expected length of
+    // range and contain only q-regs in the range q0-q7. So we can
+    // count on the base register being in the range q0-q6 (for 2
+    // regs) or q0-q4 (for 4)
+    //
+    // The MVE instructions taking a register range of this kind will
+    // need an operand in the QQPR or QQQQPR class, representing the
+    // entire range as a unit. So we must translate into that class,
+    // by finding the index of the base register in the MQPR reg
+    // class, and returning the super-register at the corresponding
+    // index in the target class.
+
+    const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
+    const MCRegisterClass *RC_out = (VectorList.Count == 2) ?
+      &ARMMCRegisterClasses[ARM::QQPRRegClassID] :
+      &ARMMCRegisterClasses[ARM::QQQQPRRegClassID];
+
+    unsigned I, E = RC_out->getNumRegs();
+    for (I = 0; I < E; I++)
+      if (RC_in->getRegister(I) == VectorList.RegNum)
+        break;
+    assert(I < E && "Invalid vector list start register!");
+
+    Inst.addOperand(MCOperand::createReg(RC_out->getRegister(I)));
+  }
+
   void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
@@ -4257,7 +4305,7 @@ ARMAsmParser::parseVectorList(OperandVec
   // As an extension (to match gas), support a plain D register or Q register
   // (without encosing curly braces) as a single or double entry list,
   // respectively.
-  if (Parser.getTok().is(AsmToken::Identifier)) {
+  if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
     SMLoc E = Parser.getTok().getEndLoc();
     int Reg = tryParseRegister();
     if (Reg == -1)
@@ -4325,9 +4373,14 @@ ARMAsmParser::parseVectorList(OperandVec
   unsigned Count = 1;
   int Spacing = 0;
   unsigned FirstReg = Reg;
+
+  if (hasMVE() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
+      Error(Parser.getTok().getLoc(), "vector register in range Q0-Q7 expected");
+      return MatchOperand_ParseFail;
+  }
   // The list is of D registers, but we also allow Q regs and just interpret
   // them as the two D sub-registers.
-  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
+  else if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
     FirstReg = Reg = getDRegFromQReg(Reg);
     Spacing = 1; // double-spacing requires explicit D registers, otherwise
                  // it's ambiguous with four-register single spaced.
@@ -4357,14 +4410,17 @@ ARMAsmParser::parseVectorList(OperandVec
         return MatchOperand_ParseFail;
       }
       // Allow Q regs and just interpret them as the two D sub-registers.
-      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
+      if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
         EndReg = getDRegFromQReg(EndReg) + 1;
       // If the register is the same as the start reg, there's nothing
       // more to do.
       if (Reg == EndReg)
         continue;
       // The register must be in the same register class as the first.
-      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
+      if ((hasMVE() &&
+           !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(EndReg)) ||
+          (!hasMVE() &&
+           !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg))) {
         Error(AfterMinusLoc, "invalid register in register list");
         return MatchOperand_ParseFail;
       }
@@ -4397,13 +4453,21 @@ ARMAsmParser::parseVectorList(OperandVec
       Error(RegLoc, "register expected");
       return MatchOperand_ParseFail;
     }
+
+    if (hasMVE()) {
+      if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
+        Error(RegLoc, "vector register in range Q0-Q7 expected");
+        return MatchOperand_ParseFail;
+      }
+      Spacing = 1;
+    }
     // vector register lists must be contiguous.
     // It's OK to use the enumeration values directly here rather, as the
     // VFP register classes have the enum sorted properly.
     //
     // The list is of D registers, but we also allow Q regs and just interpret
     // them as the two D sub-registers.
-    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
+    else if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
       if (!Spacing)
         Spacing = 1; // Register range implies a single spaced list.
       else if (Spacing == 2) {
@@ -4464,30 +4528,20 @@ ARMAsmParser::parseVectorList(OperandVec
 
   switch (LaneKind) {
   case NoLanes:
+  case AllLanes: {
     // Two-register operands have been converted to the
     // composite register classes.
-    if (Count == 2) {
-      const MCRegisterClass *RC = (Spacing == 1) ?
-        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
-        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
-      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
-    }
-    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
-                                                    (Spacing == 2), S, E));
-    break;
-  case AllLanes:
-    // Two-register operands have been converted to the
-    // composite register classes.
-    if (Count == 2) {
+    if (Count == 2 && !hasMVE()) {
       const MCRegisterClass *RC = (Spacing == 1) ?
         &ARMMCRegisterClasses[ARM::DPairRegClassID] :
         &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
       FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
     }
-    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
-                                                            (Spacing == 2),
-                                                            S, E));
+    auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
+                   ARMOperand::CreateVectorListAllLanes);
+    Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E));
     break;
+  }
   case IndexedLane:
     Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
                                                            LaneIndex,
@@ -6127,7 +6181,10 @@ void ARMAsmParser::getMnemonicAcceptInfo
       Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
       Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
       Mnemonic == "cset" || Mnemonic == "csetm" ||
-      Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst")) {
+      Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst") ||
+      (hasMVE() &&
+       (Mnemonic.startswith("vst2") || Mnemonic.startswith("vld2") ||
+        Mnemonic.startswith("vst4") || Mnemonic.startswith("vld4")))) {
     // These mnemonics are never predicable
     CanAcceptPredicationCode = false;
   } else if (!isThumb()) {
@@ -6385,6 +6442,10 @@ bool ARMAsmParser::shouldOmitVectorPredi
   if (!hasMVE() || Operands.size() < 3)
     return true;
 
+  if (Mnemonic.startswith("vld2") || Mnemonic.startswith("vld4") ||
+      Mnemonic.startswith("vst2") || Mnemonic.startswith("vst4"))
+    return true;
+
   if (Mnemonic.startswith("vctp"))
     return false;
 

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Jun 24 03:00:39 2019
@@ -220,6 +220,10 @@ static DecodeStatus DecodeQPRRegisterCla
                                    uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                    uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                                   uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                                   uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
                                    uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
@@ -5939,6 +5943,38 @@ static DecodeStatus DecodeMQPRRegisterCl
   Inst.addOperand(MCOperand::createReg(Register));
   return MCDisassembler::Success;
 }
+
+static const uint16_t QQPRDecoderTable[] = {
+     ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
+     ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
+};
+
+static DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                              uint64_t Address,
+                              const void *Decoder) {
+  if (RegNo > 6)
+    return MCDisassembler::Fail;
+
+  unsigned Register = QQPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Register));
+  return MCDisassembler::Success;
+}
+
+static const uint16_t QQQQPRDecoderTable[] = {
+     ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
+     ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
+};
+
+static DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
+                              uint64_t Address,
+                              const void *Decoder) {
+  if (RegNo > 4)
+    return MCDisassembler::Fail;
+
+  unsigned Register = QQQQPRDecoderTable[RegNo];
+  Inst.addOperand(MCOperand::createReg(Register));
+  return MCDisassembler::Success;
+}
 
 static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
                                          uint64_t Address,

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp Mon Jun 24 03:00:39 2019
@@ -1588,6 +1588,20 @@ void ARMInstPrinter::printVectorListFour
   O << "}";
 }
 
+template<unsigned NumRegs>
+void ARMInstPrinter::printMVEVectorList(const MCInst *MI, unsigned OpNum,
+                                        const MCSubtargetInfo &STI,
+                                        raw_ostream &O) {
+  unsigned Reg = MI->getOperand(OpNum).getReg();
+  const char *Prefix = "{";
+  for (unsigned i = 0; i < NumRegs; i++) {
+    O << Prefix;
+    printRegName(O, MRI.getSubReg(Reg, ARM::qsub_0 + i));
+    Prefix = ", ";
+  }
+  O << "}";
+}
+
 template<int64_t Angle, int64_t Remainder>
 void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
                                             const MCSubtargetInfo &STI,

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h?rev=364172&r1=364171&r2=364172&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h Mon Jun 24 03:00:39 2019
@@ -243,6 +243,9 @@ public:
                                   const MCSubtargetInfo &STI, raw_ostream &O);
   void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI, raw_ostream &O);
+  template<unsigned NumRegs>
+  void printMVEVectorList(const MCInst *MI, unsigned OpNum,
+                          const MCSubtargetInfo &STI, raw_ostream &O);
   template<int64_t Angle, int64_t Remainder>
   void printComplexRotationOp(const MCInst *MI, unsigned OpNum,
                               const MCSubtargetInfo &STI, raw_ostream &O);

Added: llvm/trunk/test/MC/ARM/mve-interleave.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/mve-interleave.s?rev=364172&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/mve-interleave.s (added)
+++ llvm/trunk/test/MC/ARM/mve-interleave.s Mon Jun 24 03:00:39 2019
@@ -0,0 +1,270 @@
+# RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding  < %s 2> %t \
+# RUN:   | FileCheck --check-prefix=CHECK %s
+# RUN:     FileCheck --check-prefix=ERROR < %t %s
+
+# CHECK: vld20.8 {q0, q1}, [sp] @ encoding: [0x9d,0xfc,0x00,0x1e]
+vld20.8 {q0, q1}, [sp]
+
+# CHECK: vld20.8 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x00,0x1e]
+vld20.8 {q0, q1}, [r0]
+
+# CHECK: vld20.8 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x00,0x1e]
+vld20.8 {q0, q1}, [r0]!
+
+# CHECK: vld20.8 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x00,0x1e]
+vld20.8 {q0, q1}, [r11]
+
+# CHECK: vld20.8 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x00,0xbe]
+vld20.8 {q5, q6}, [r0]!
+
+# CHECK: vld21.8 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x20,0x1e]
+vld21.8 {q0, q1}, [r0]
+
+# CHECK: vld21.8 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0x20,0x7e]
+vld21.8 {q3, q4}, [r0]!
+
+# CHECK: vld20.16 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x80,0x1e]
+vld20.16 {q0, q1}, [r0]
+
+# CHECK: vld20.16 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x80,0x1e]
+vld20.16 {q0, q1}, [r0]!
+
+# CHECK: vld20.16 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x80,0x1e]
+vld20.16 {q0, q1}, [r11]
+
+# CHECK: vld20.16 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x80,0xbe]
+vld20.16 {q5, q6}, [r0]!
+
+# CHECK: vld21.16 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0xa0,0x1e]
+vld21.16 {q0, q1}, [r0]
+
+# CHECK: vld21.16 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0xa0,0x7e]
+vld21.16 {q3, q4}, [r0]!
+
+# CHECK: vld20.32 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x00,0x1f]
+vld20.32 {q0, q1}, [r0]
+
+# CHECK: vld20.32 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x00,0x1f]
+vld20.32 {q0, q1}, [r0]!
+
+# CHECK: vld20.32 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x00,0x1f]
+vld20.32 {q0, q1}, [r11]
+
+# CHECK: vld20.32 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x00,0xbf]
+vld20.32 {q5, q6}, [r0]!
+
+# CHECK: vld21.32 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x20,0x1f]
+vld21.32 {q0, q1}, [r0]
+
+# CHECK: vld21.32 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0x20,0x7f]
+vld21.32 {q3, q4}, [r0]!
+
+# CHECK: vst20.8 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x00,0x1e]
+vst20.8 {q0, q1}, [r0]
+
+# CHECK: vst20.8 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x00,0x1e]
+vst20.8 {q0, q1}, [r0]!
+
+# CHECK: vst20.8 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x00,0x1e]
+vst20.8 {q0, q1}, [r11]
+
+# CHECK: vst20.8 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x00,0xbe]
+vst20.8 {q5, q6}, [r0]!
+
+# CHECK: vst21.8 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x20,0x1e]
+vst21.8 {q0, q1}, [r0]
+
+# CHECK: vst21.8 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0x20,0x7e]
+vst21.8 {q3, q4}, [r0]!
+
+# CHECK: vst20.16 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x80,0x1e]
+vst20.16 {q0, q1}, [r0]
+
+# CHECK: vst20.16 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x80,0x1e]
+vst20.16 {q0, q1}, [r0]!
+
+# CHECK: vst20.16 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x80,0x1e]
+vst20.16 {q0, q1}, [r11]
+
+# CHECK: vst20.16 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x80,0xbe]
+vst20.16 {q5, q6}, [r0]!
+
+# CHECK: vst21.16 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0xa0,0x1e]
+vst21.16 {q0, q1}, [r0]
+
+# CHECK: vst21.16 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0xa0,0x7e]
+vst21.16 {q3, q4}, [r0]!
+
+# CHECK: vst20.32 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x00,0x1f]
+vst20.32 {q0, q1}, [r0]
+
+# CHECK: vst20.32 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x00,0x1f]
+vst20.32 {q0, q1}, [r0]!
+
+# CHECK: vst20.32 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x00,0x1f]
+vst20.32 {q0, q1}, [r11]
+
+# CHECK: vst20.32 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x00,0xbf]
+vst20.32 {q5, q6}, [r0]!
+
+# CHECK: vst21.32 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x20,0x1f]
+vst21.32 {q0, q1}, [r0]
+
+# CHECK: vst21.32 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0x20,0x7f]
+vst21.32 {q3, q4}, [r0]!
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld20.8 {q0, q1}, [sp]!
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld20.64 {q0, q1}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: non-contiguous register range
+vld20.32 {q0, q2}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be a list of two consecutive q-registers in range [q0,q7]
+vld20.32 {q0, q1, q2}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be a list of two consecutive q-registers in range [q0,q7]
+vld20.32 {q0}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction
+vld20.32 q0, q1, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: vector register in range Q0-Q7 expected
+vld20.32 {q7, q8}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: vector register in range Q0-Q7 expected
+vld20.32 {d0, d1}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction
+vld22.32 {q0, q1}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld20.32 {q0, q1}, [pc]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld20.32 {q0, q1}, [r0, #4]
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x01,0x1e]
+vld40.8 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x1e]
+vld40.8 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x01,0x1e]
+vld40.8 {q0, q1, q2, q3}, [r11]
+
+# CHECK: vld40.8 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x7e]
+vld40.8 {q3, q4, q5, q6}, [r0]!
+
+# CHECK: vld41.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x21,0x1e]
+vld41.8 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld41.8 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x21,0x9e]
+vld41.8 {q4, q5, q6, q7}, [r0]!
+
+# CHECK: vld42.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x41,0x1e]
+vld42.8 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld42.8 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x41,0x1e]
+vld42.8 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld43.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x61,0x1e]
+vld43.8 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld43.8 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x61,0x9e]
+vld43.8 {q4, q5, q6, q7}, [r0]!
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x81,0x1e]
+vld40.16 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x81,0x1e]
+vld40.16 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x81,0x1e]
+vld40.16 {q0, q1, q2, q3}, [r11]
+
+# CHECK: vld40.16 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x81,0x7e]
+vld40.16 {q3, q4, q5, q6}, [r0]!
+
+# CHECK: vld41.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xa1,0x1e]
+vld41.16 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld41.16 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0xa1,0x9e]
+vld41.16 {q4, q5, q6, q7}, [r0]!
+
+# CHECK: vld42.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xc1,0x1e]
+vld42.16 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld42.16 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0xc1,0x1e]
+vld42.16 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld43.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xe1,0x1e]
+vld43.16 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld43.16 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0xe1,0x9e]
+vld43.16 {q4, q5, q6, q7}, [r0]!
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x01,0x1f]
+vld40.32 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x1f]
+vld40.32 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x01,0x1f]
+vld40.32 {q0, q1, q2, q3}, [r11]
+
+# CHECK: vld40.32 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x7f]
+vld40.32 {q3, q4, q5, q6}, [r0]!
+
+# CHECK: vld41.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x21,0x1f]
+vld41.32 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld41.32 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x21,0x9f]
+vld41.32 {q4, q5, q6, q7}, [r0]!
+
+# CHECK: vld42.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x41,0x1f]
+vld42.32 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld42.32 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x41,0x1f]
+vld42.32 {q0, q1, q2, q3}, [r0]!
+
+# CHECK: vld43.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x61,0x1f]
+vld43.32 {q0, q1, q2, q3}, [r0]
+
+# CHECK: vld43.32 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x61,0x9f]
+vld43.32 {q4, q5, q6, q7}, [r0]!
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld40.64 {q0, q1, q2, q3}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: non-contiguous register range
+vld40.32 {q0, q2, q3, q4}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be a list of four consecutive q-registers in range [q0,q7]
+vld40.32 {q0, q1, q2, q3, q4}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be a list of four consecutive q-registers in range [q0,q7]
+vld40.32 {q0, q1}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: operand must be a list of four consecutive q-registers in range [q0,q7]
+vld40.32 {q0, q1, q2}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction
+vld40.32 q0, q1, q2, q3, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: vector register in range Q0-Q7 expected
+vld40.32 {q5, q6, q7, q8}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: vector register in range Q0-Q7 expected
+vld40.32 {d0, d1, d2, d3}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction
+vld44.32 {q0, q1, q2, q3}, [r0]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld40.32 {q0, q1, q2, q3}, [pc]
+
+# ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
+vld40.32 {q0, q1, q2, q3}, [r0, #4]

Propchange: llvm/trunk/test/MC/ARM/mve-interleave.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/test/MC/ARM/mve-interleave.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt?rev=364172&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt (added)
+++ llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt Mon Jun 24 03:00:39 2019
@@ -0,0 +1,267 @@
+# RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding %s | FileCheck %s
+# RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s &> %t
+# RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s
+
+# CHECK: vld20.8 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x00,0x1e]
+
+# CHECK: vld20.8 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x00,0x1e]
+
+# CHECK: vld20.8 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x00,0x1e]
+
+# CHECK: vld20.8 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x00,0xbe]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x00,0xbe]
+
+# CHECK: vld21.8 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x20,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x20,0x1e]
+
+# CHECK: vld21.8 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0x20,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x20,0x7e]
+
+# CHECK: vld20.16 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x80,0x1e]
+
+# CHECK: vld20.16 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x80,0x1e]
+
+# CHECK: vld20.16 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x80,0x1e]
+
+# CHECK: vld20.16 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x80,0xbe]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x80,0xbe]
+
+# CHECK: vld21.16 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0xa0,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0xa0,0x1e]
+
+# CHECK: vld21.16 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0xa0,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0xa0,0x7e]
+
+# CHECK: vld20.32 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x00,0x1f]
+
+# CHECK: vld20.32 {q0, q1}, [r0]! @ encoding: [0xb0,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x00,0x1f]
+
+# CHECK: vld20.32 {q0, q1}, [r11] @ encoding: [0x9b,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x00,0x1f]
+
+# CHECK: vld20.32 {q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x00,0xbf]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x00,0xbf]
+
+# CHECK: vld21.32 {q0, q1}, [r0] @ encoding: [0x90,0xfc,0x20,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x20,0x1f]
+
+# CHECK: vld21.32 {q3, q4}, [r0]! @ encoding: [0xb0,0xfc,0x20,0x7f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x20,0x7f]
+
+# CHECK: vst20.8 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0x00,0x1e]
+
+# CHECK: vst20.8 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x00,0x1e]
+
+# CHECK: vst20.8 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x00,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x8b,0xfc,0x00,0x1e]
+
+# CHECK: vst20.8 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x00,0xbe]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x00,0xbe]
+
+# CHECK: vst21.8 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x20,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0x20,0x1e]
+
+# CHECK: vst21.8 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0x20,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x20,0x7e]
+
+# CHECK: vst20.16 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0x80,0x1e]
+
+# CHECK: vst20.16 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x80,0x1e]
+
+# CHECK: vst20.16 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x80,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x8b,0xfc,0x80,0x1e]
+
+# CHECK: vst20.16 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x80,0xbe]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x80,0xbe]
+
+# CHECK: vst21.16 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0xa0,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0xa0,0x1e]
+
+# CHECK: vst21.16 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0xa0,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0xa0,0x7e]
+
+# CHECK: vst20.32 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0x00,0x1f]
+
+# CHECK: vst20.32 {q0, q1}, [r0]! @ encoding: [0xa0,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x00,0x1f]
+
+# CHECK: vst20.32 {q0, q1}, [r11] @ encoding: [0x8b,0xfc,0x00,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x8b,0xfc,0x00,0x1f]
+
+# CHECK: vst20.32 {q5, q6}, [r0]! @ encoding: [0xa0,0xfc,0x00,0xbf]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x00,0xbf]
+
+# CHECK: vst21.32 {q0, q1}, [r0] @ encoding: [0x80,0xfc,0x20,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x80,0xfc,0x20,0x1f]
+
+# CHECK: vst21.32 {q3, q4}, [r0]! @ encoding: [0xa0,0xfc,0x20,0x7f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xa0,0xfc,0x20,0x7f]
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x01,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x01,0x1e]
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x01,0x1e]
+
+# CHECK: vld40.8 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x01,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x01,0x1e]
+
+# CHECK: vld40.8 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x01,0x7e]
+
+# CHECK: vld41.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x21,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x21,0x1e]
+
+# CHECK: vld41.8 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x21,0x9e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x21,0x9e]
+
+# CHECK: vld42.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x41,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x41,0x1e]
+
+# CHECK: vld42.8 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x41,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x41,0x1e]
+
+# CHECK: vld43.8 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x61,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x61,0x1e]
+
+# CHECK: vld43.8 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x61,0x9e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x61,0x9e]
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x81,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x81,0x1e]
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x81,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x81,0x1e]
+
+# CHECK: vld40.16 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x81,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x81,0x1e]
+
+# CHECK: vld40.16 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x81,0x7e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x81,0x7e]
+
+# CHECK: vld41.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xa1,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0xa1,0x1e]
+
+# CHECK: vld41.16 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0xa1,0x9e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0xa1,0x9e]
+
+# CHECK: vld42.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xc1,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0xc1,0x1e]
+
+# CHECK: vld42.16 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0xc1,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0xc1,0x1e]
+
+# CHECK: vld43.16 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0xe1,0x1e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0xe1,0x1e]
+
+# CHECK: vld43.16 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0xe1,0x9e]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0xe1,0x9e]
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x01,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x01,0x1f]
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x01,0x1f]
+
+# CHECK: vld40.32 {q0, q1, q2, q3}, [r11] @ encoding: [0x9b,0xfc,0x01,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x9b,0xfc,0x01,0x1f]
+
+# CHECK: vld40.32 {q3, q4, q5, q6}, [r0]! @ encoding: [0xb0,0xfc,0x01,0x7f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x01,0x7f]
+
+# CHECK: vld41.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x21,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x21,0x1f]
+
+# CHECK: vld41.32 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x21,0x9f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x21,0x9f]
+
+# CHECK: vld42.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x41,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x41,0x1f]
+
+# CHECK: vld42.32 {q0, q1, q2, q3}, [r0]! @ encoding: [0xb0,0xfc,0x41,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x41,0x1f]
+
+# CHECK: vld43.32 {q0, q1, q2, q3}, [r0] @ encoding: [0x90,0xfc,0x61,0x1f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0x90,0xfc,0x61,0x1f]
+
+# CHECK: vld43.32 {q4, q5, q6, q7}, [r0]! @ encoding: [0xb0,0xfc,0x61,0x9f]
+# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
+[0xb0,0xfc,0x61,0x9f]

Propchange: llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/test/MC/Disassembler/ARM/mve-interleave.txt
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id




More information about the llvm-commits mailing list