Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -932,53 +932,48 @@ }]>; // Vector lane operands -class AsmVectorIndex : AsmOperandClass { - let Name = "VectorIndex" # Suffix; - let DiagnosticType = "InvalidIndex" # Suffix; +class AsmVectorIndex : AsmOperandClass { + let Name = NamePrefix # "IndexRange" # Min # "_" # Max; + let DiagnosticType = "Invalid" # Name; + let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; let RenderMethod = "addVectorIndexOperands"; } -def VectorIndex1Operand : AsmVectorIndex<"1">; -def VectorIndexBOperand : AsmVectorIndex<"B">; -def VectorIndexHOperand : AsmVectorIndex<"H">; -def VectorIndexSOperand : AsmVectorIndex<"S">; -def VectorIndexDOperand : AsmVectorIndex<"D">; -def VectorIndex1 : Operand, ImmLeaf { - let ParserMatchClass = VectorIndex1Operand; - let PrintMethod = "printVectorIndex"; - let MIOperandInfo = (ops i64imm); -} -def VectorIndexB : Operand, ImmLeaf { - let ParserMatchClass = VectorIndexBOperand; - let PrintMethod = "printVectorIndex"; - let MIOperandInfo = (ops i64imm); -} -def VectorIndexH : Operand, ImmLeaf { - let ParserMatchClass = VectorIndexHOperand; +class AsmVectorIndexOpnd + : Operand, ImmLeaf { + let ParserMatchClass = mc; let PrintMethod = "printVectorIndex"; - let MIOperandInfo = (ops i64imm); -} -def VectorIndexS : Operand, ImmLeaf { - let ParserMatchClass = VectorIndexSOperand; - let PrintMethod = "printVectorIndex"; - let MIOperandInfo = (ops i64imm); -} -def VectorIndexD : Operand, ImmLeaf { - let ParserMatchClass = VectorIndexDOperand; - let PrintMethod = "printVectorIndex"; - let MIOperandInfo = (ops i64imm); } +def VectorIndex1Operand : AsmVectorIndex<1, 1>; +def VectorIndexBOperand : AsmVectorIndex<0, 15>; +def VectorIndexHOperand : AsmVectorIndex<0, 7>; +def VectorIndexSOperand : AsmVectorIndex<0, 3>; +def VectorIndexDOperand : AsmVectorIndex<0, 1>; + +def VectorIndex1 : AsmVectorIndexOpnd; +def VectorIndexB : AsmVectorIndexOpnd; +def VectorIndexH : AsmVectorIndexOpnd; +def VectorIndexS : AsmVectorIndexOpnd; +def VectorIndexD : AsmVectorIndexOpnd; + +def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; +def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; +def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; +def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; +def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; + +def sve_elm_idx_extdup_b + : AsmVectorIndexOpnd; +def sve_elm_idx_extdup_h + : AsmVectorIndexOpnd; +def sve_elm_idx_extdup_s + : AsmVectorIndexOpnd; +def sve_elm_idx_extdup_d + : AsmVectorIndexOpnd; +def sve_elm_idx_extdup_q + : AsmVectorIndexOpnd; + // 8-bit immediate for AdvSIMD where 64-bit values of the form: // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh // are encoded as the eight bit value 'abcdefgh'. Index: llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -45,6 +45,10 @@ defm CPY_ZPzI : sve_int_dup_imm_pred_zero<"cpy">; defm FCPY_ZPmI : sve_int_dup_fpimm_pred<"fcpy">; + // Splat scalar register (unpredicated, GPR or vector + element index) + defm DUP_ZR : sve_int_perm_dup_r<"dup">; + defm DUP_ZZI : sve_int_perm_dup_i<"dup">; + // continuous load with reg+immediate defm LD1B_IMM : sve_mem_cld_si<0b0000, "ld1b", Z_b, ZPR8>; defm LD1B_H_IMM : sve_mem_cld_si<0b0001, "ld1b", Z_h, ZPR16>; @@ -465,8 +469,6 @@ defm ZIP1_PPP : sve_int_perm_bin_perm_pp<0b000, "zip1">; defm ZIP2_PPP : sve_int_perm_bin_perm_pp<0b001, "zip2">; - defm DUP_ZR : sve_int_perm_dup_r<"dup">; - def RDVLI_XI : sve_int_read_vl_a<0b0, 0b11111, "rdvl">; def ADDVL_XXI : sve_int_arith_vl<0b0, "addvl">; def ADDPL_XXI : sve_int_arith_vl<0b1, "addpl">; Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1048,24 +1048,13 @@ return VectorList.NumElements == NumElements; } - bool isVectorIndex1() const { - return Kind == k_VectorIndex && VectorIndex.Val == 1; - } - - bool isVectorIndexB() const { - return Kind == k_VectorIndex && VectorIndex.Val < 16; - } - - bool isVectorIndexH() const { - return Kind == k_VectorIndex && VectorIndex.Val < 8; - } - - bool isVectorIndexS() const { - return Kind == k_VectorIndex && VectorIndex.Val < 4; - } - - bool isVectorIndexD() const { - return Kind == k_VectorIndex && VectorIndex.Val < 2; + template + DiagnosticPredicate isVectorIndex() const { + if (Kind != k_VectorIndex) + return DiagnosticPredicateTy::NoMatch; + if (VectorIndex.Val >= Min && VectorIndex.Val <= Max) + return DiagnosticPredicateTy::Match; + return DiagnosticPredicateTy::NearMatch; } bool isToken() const override { return Kind == k_Token; } @@ -3839,16 +3828,26 @@ case Match_InvalidSVECpyImm64: return Error(Loc, "immediate must be an integer in range [-128, 127] or a " "multiple of 256 in range [-32768, 32512]"); - case Match_InvalidIndex1: + case Match_InvalidIndexRange1_1: return Error(Loc, "expected lane specifier '[1]'"); - case Match_InvalidIndexB: + case Match_InvalidIndexRange0_15: return Error(Loc, "vector lane must be an integer in range [0, 15]."); - case Match_InvalidIndexH: + case Match_InvalidIndexRange0_7: return Error(Loc, "vector lane must be an integer in range [0, 7]."); - case Match_InvalidIndexS: + case Match_InvalidIndexRange0_3: return Error(Loc, "vector lane must be an integer in range [0, 3]."); - case Match_InvalidIndexD: + case Match_InvalidIndexRange0_1: return Error(Loc, "vector lane must be an integer in range [0, 1]."); + case Match_InvalidSVEIndexRange0_63: + return Error(Loc, "vector lane must be an integer in range [0, 63]."); + case Match_InvalidSVEIndexRange0_31: + return Error(Loc, "vector lane must be an integer in range [0, 31]."); + case Match_InvalidSVEIndexRange0_15: + return Error(Loc, "vector lane must be an integer in range [0, 15]."); + case Match_InvalidSVEIndexRange0_7: + return Error(Loc, "vector lane must be an integer in range [0, 7]."); + case Match_InvalidSVEIndexRange0_3: + return Error(Loc, "vector lane must be an integer in range [0, 3]."); case Match_InvalidLabel: return Error(Loc, "expected label or encodable integer pc offset"); case Match_MRS: @@ -4375,11 +4374,16 @@ case Match_InvalidSVECpyImm16: case Match_InvalidSVECpyImm32: case Match_InvalidSVECpyImm64: - case Match_InvalidIndex1: - case Match_InvalidIndexB: - case Match_InvalidIndexH: - case Match_InvalidIndexS: - case Match_InvalidIndexD: + case Match_InvalidIndexRange1_1: + case Match_InvalidIndexRange0_15: + case Match_InvalidIndexRange0_7: + case Match_InvalidIndexRange0_3: + case Match_InvalidIndexRange0_1: + case Match_InvalidSVEIndexRange0_63: + case Match_InvalidSVEIndexRange0_31: + case Match_InvalidSVEIndexRange0_15: + case Match_InvalidSVEIndexRange0_7: + case Match_InvalidSVEIndexRange0_3: case Match_InvalidLabel: case Match_InvalidComplexRotationEven: case Match_InvalidComplexRotationOdd: @@ -5028,6 +5032,9 @@ Operands.push_back(AArch64Operand::CreateVectorReg( RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext())); + OperandMatchResultTy Res = tryParseVectorIndex(Operands); + if (Res == MatchOperand_ParseFail) + return MatchOperand_ParseFail; return MatchOperand_Success; } Index: llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td @@ -203,6 +203,7 @@ return AArch64_AM::isSVEAddSubImm(Imm); }]>; + //===----------------------------------------------------------------------===// // SVE PTrue - These are used extensively throughout the pattern matching so // it's important we define them first. @@ -284,6 +285,57 @@ (!cast(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>; } +class sve_int_perm_dup_i tsz, Operand immtype, string asm, + ZPRRegOp zprty> +: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$idx), + asm, "\t$Zd, $Zn$idx", + "", + []>, Sched<[]> { + bits<5> Zd; + bits<5> Zn; + bits<7> idx; + let Inst{31-24} = 0b00000101; + let Inst{23-22} = {?,?}; // imm3h + let Inst{21} = 0b1; + let Inst{20-16} = tsz; + let Inst{15-10} = 0b001000; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + +multiclass sve_int_perm_dup_i { + def _B : sve_int_perm_dup_i<{?,?,?,?,1}, sve_elm_idx_extdup_b, asm, ZPR8> { + let Inst{23-22} = idx{5-4}; + let Inst{20-17} = idx{3-0}; + } + def _H : sve_int_perm_dup_i<{?,?,?,1,0}, sve_elm_idx_extdup_h, asm, ZPR16> { + let Inst{23-22} = idx{4-3}; + let Inst{20-18} = idx{2-0}; + } + def _S : sve_int_perm_dup_i<{?,?,1,0,0}, sve_elm_idx_extdup_s, asm, ZPR32> { + let Inst{23-22} = idx{3-2}; + let Inst{20-19} = idx{1-0}; + } + def _D : sve_int_perm_dup_i<{?,1,0,0,0}, sve_elm_idx_extdup_d, asm, ZPR64> { + let Inst{23-22} = idx{2-1}; + let Inst{20} = idx{0}; + } + def _Q : sve_int_perm_dup_i<{1,0,0,0,0}, sve_elm_idx_extdup_q, asm, ZPR128> { + let Inst{23-22} = idx{1-0}; + } + + def : InstAlias<"mov $Zd, $Zn$idx", + (!cast(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>; + def : InstAlias<"mov $Zd, $Zn$idx", + (!cast(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>; + def : InstAlias<"mov $Zd, $Zn$idx", + (!cast(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>; + def : InstAlias<"mov $Zd, $Zn$idx", + (!cast(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>; + def : InstAlias<"mov $Zd, $Zn$idx", + (!cast(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>; +} + //===----------------------------------------------------------------------===// // SVE Logical Mask Immediate Group //===----------------------------------------------------------------------===// Index: llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s +++ llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s @@ -136,3 +136,57 @@ // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512] // CHECK-NEXT: dup z0.d, #128, lsl #8 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// --------------------------------------------------------------------------// +// Immediate not compatible with encode/decode function. + +dup z24.b, z17.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 63]. +// CHECK-NEXT: dup z24.b, z17.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z17.b, z5.b[64] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 63]. +// CHECK-NEXT: dup z17.b, z5.b[64] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z16.h, z30.h[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 31]. +// CHECK-NEXT: dup z16.h, z30.h[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z19.h, z23.h[32] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 31]. +// CHECK-NEXT: dup z19.h, z23.h[32] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z1.s, z6.s[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: dup z1.s, z6.s[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z24.s, z3.s[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: dup z24.s, z3.s[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z5.d, z25.d[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: dup z5.d, z25.d[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z12.d, z28.d[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: dup z12.d, z28.d[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z22.q, z7.q[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: dup z22.q, z7.q[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup z24.q, z21.q[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: dup z24.q, z21.q[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: llvm/trunk/test/MC/AArch64/SVE/dup.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/dup.s +++ llvm/trunk/test/MC/AArch64/SVE/dup.s @@ -180,3 +180,63 @@ // CHECK-ENCODING: [0xf5,0xef,0xf8,0x25] // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: f5 ef f8 25 + +dup z0.b, z0.b[0] +// CHECK-INST: mov z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0x20,0x21,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 21 05 + +dup z0.h, z0.h[0] +// CHECK-INST: mov z0.h, z0.h[0] +// CHECK-ENCODING: [0x00,0x20,0x22,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 22 05 + +dup z0.s, z0.s[0] +// CHECK-INST: mov z0.s, z0.s[0] +// CHECK-ENCODING: [0x00,0x20,0x24,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 24 05 + +dup z0.d, z0.d[0] +// CHECK-INST: mov z0.d, z0.d[0] +// CHECK-ENCODING: [0x00,0x20,0x28,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 28 05 + +dup z0.q, z0.q[0] +// CHECK-INST: mov z0.q, z0.q[0] +// CHECK-ENCODING: [0x00,0x20,0x30,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 30 05 + +dup z31.b, z31.b[63] +// CHECK-INST: mov z31.b, z31.b[63] +// CHECK-ENCODING: [0xff,0x23,0xff,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 ff 05 + +dup z31.h, z31.h[31] +// CHECK-INST: mov z31.h, z31.h[31] +// CHECK-ENCODING: [0xff,0x23,0xfe,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 fe 05 + +dup z31.s, z31.s[15] +// CHECK-INST: mov z31.s, z31.s[15] +// CHECK-ENCODING: [0xff,0x23,0xfc,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 fc 05 + +dup z31.d, z31.d[7] +// CHECK-INST: mov z31.d, z31.d[7] +// CHECK-ENCODING: [0xff,0x23,0xf8,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 f8 05 + +dup z5.q, z17.q[3] +// CHECK-INST: mov z5.q, z17.q[3] +// CHECK-ENCODING: [0x25,0x22,0xf0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 25 22 f0 05 Index: llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s +++ llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s @@ -23,17 +23,17 @@ // Unpredicated mov of Z register only allowed for .d mov z0.b, z1.b -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: too few operands for instruction // CHECK-NEXT: mov z0.b, z1.b // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: mov z0.h, z1.h -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: too few operands for instruction // CHECK-NEXT: mov z0.h, z1.h // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: mov z0.s, z1.s -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: too few operands for instruction // CHECK-NEXT: mov z0.s, z1.s // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: @@ -269,3 +269,57 @@ // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512] // CHECK-NEXT: mov z0.d, p0/z, #128, lsl #8 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// --------------------------------------------------------------------------// +// Immediate not compatible with encode/decode function. + +mov z24.b, z17.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 63]. +// CHECK-NEXT: mov z24.b, z17.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z17.b, z5.b[64] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 63]. +// CHECK-NEXT: mov z17.b, z5.b[64] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z16.h, z30.h[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 31]. +// CHECK-NEXT: mov z16.h, z30.h[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z19.h, z23.h[32] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 31]. +// CHECK-NEXT: mov z19.h, z23.h[32] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z1.s, z6.s[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: mov z1.s, z6.s[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z24.s, z3.s[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: mov z24.s, z3.s[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z5.d, z25.d[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: mov z5.d, z25.d[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z12.d, z28.d[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: mov z12.d, z28.d[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z22.q, z7.q[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: mov z22.q, z7.q[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z24.q, z21.q[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: mov z24.q, z21.q[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: llvm/trunk/test/MC/AArch64/SVE/mov.s =================================================================== --- llvm/trunk/test/MC/AArch64/SVE/mov.s +++ llvm/trunk/test/MC/AArch64/SVE/mov.s @@ -401,3 +401,66 @@ // CHECK-ENCODING: [0x15,0x70,0xdf,0x05] // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: 15 70 df 05 + +// --------------------------------------------------------------------------// +// Tests for indexed variant + +mov z0.b, z0.b[0] +// CHECK-INST: mov z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0x20,0x21,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 21 05 + +mov z0.h, z0.h[0] +// CHECK-INST: mov z0.h, z0.h[0] +// CHECK-ENCODING: [0x00,0x20,0x22,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 22 05 + +mov z0.s, z0.s[0] +// CHECK-INST: mov z0.s, z0.s[0] +// CHECK-ENCODING: [0x00,0x20,0x24,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 24 05 + +mov z0.d, z0.d[0] +// CHECK-INST: mov z0.d, z0.d[0] +// CHECK-ENCODING: [0x00,0x20,0x28,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 28 05 + +mov z0.q, z0.q[0] +// CHECK-INST: mov z0.q, z0.q[0] +// CHECK-ENCODING: [0x00,0x20,0x30,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 20 30 05 + +mov z31.b, z31.b[63] +// CHECK-INST: mov z31.b, z31.b[63] +// CHECK-ENCODING: [0xff,0x23,0xff,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 ff 05 + +mov z31.h, z31.h[31] +// CHECK-INST: mov z31.h, z31.h[31] +// CHECK-ENCODING: [0xff,0x23,0xfe,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 fe 05 + +mov z31.s, z31.s[15] +// CHECK-INST: mov z31.s, z31.s[15] +// CHECK-ENCODING: [0xff,0x23,0xfc,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 fc 05 + +mov z31.d, z31.d[7] +// CHECK-INST: mov z31.d, z31.d[7] +// CHECK-ENCODING: [0xff,0x23,0xf8,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 23 f8 05 + +mov z5.q, z17.q[3] +// CHECK-INST: mov z5.q, z17.q[3] +// CHECK-ENCODING: [0x25,0x22,0xf0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 25 22 f0 05