diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -126,6 +126,33 @@ 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 { + 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 { + let ParserMatchClass = VecList4QAsmOperand; + let PrintMethod = "printMVEVectorList<4>"; +} + class MVE_MI pattern> : Thumb2XI stage, bits<2> size, + bit load, dag Oops, dag loadIops, dag wbIops, + string iname, string ops, + string cstr, list pattern=[]> + : MVE_MI { + 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 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 s, bit b, RegisterOperand vl> { + int nvecs = n; + list stages = s; + bit bit0 = b; + RegisterOperand VecList = vl; +} + +// A third parameter class that distinguishes VLDnn.8 from .16 from .32. +class MVE_vldst24_lanesize 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 pat, bits<2> size, + MVE_vldst24_writeback wb, string iname, + list pattern=[]> + : MVE_vldst24_base; + +class MVE_vst24_base pat, bits<2> size, + MVE_vldst24_writeback wb, string iname, + list pattern=[]> + : MVE_vldst24_base; + +// 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; + + def "MVE_VST" # n.nvecs # stage # "_" # s.lanesize # wb.id_suffix + : MVE_vst24_base; +} + +// end of MVE interleaving load/store + class MVE_VPT size, dag iops, string asm, list pattern=[]> : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> { bits<3> fc; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -176,9 +176,9 @@ : 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 diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td --- a/llvm/lib/Target/ARM/ARMRegisterInfo.td +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td @@ -296,15 +296,6 @@ 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().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)> { diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1759,6 +1759,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -220,6 +220,10 @@ 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, @@ -5940,6 +5944,38 @@ 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, const void *Decoder) { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h @@ -243,6 +243,9 @@ const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template + void printMVEVectorList(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); template void printComplexRotationOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp @@ -1588,6 +1588,20 @@ O << "}"; } +template +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 void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, diff --git a/llvm/test/MC/ARM/mve-interleave.s b/llvm/test/MC/ARM/mve-interleave.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ARM/mve-interleave.s @@ -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] diff --git a/llvm/test/MC/Disassembler/ARM/mve-interleave.txt b/llvm/test/MC/Disassembler/ARM/mve-interleave.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/ARM/mve-interleave.txt @@ -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]