[AArch64][SVE] Asm: Support for indexed DUP instructions.

Unpredicated copy of indexed SVE element to SVE vector,
along with MOV-aliases.

For example:

  dup     z0.h, z1.h[0]

duplicates the first 16-bit element from z1 to all elements in
the result vector z0.

Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D47570

llvm-svn: 333871
This commit is contained in:
Sander de Smalen 2018-06-04 06:40:55 +00:00
parent 0279feb6ed
commit 71703eae7a
8 changed files with 361 additions and 74 deletions

View File

@ -932,53 +932,48 @@ def fpimm0 : FPImmLeaf<fAny, [{
}]>;
// Vector lane operands
class AsmVectorIndex<string Suffix> : AsmOperandClass {
let Name = "VectorIndex" # Suffix;
let DiagnosticType = "InvalidIndex" # Suffix;
class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : 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<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) == 1;
}]> {
let ParserMatchClass = VectorIndex1Operand;
class AsmVectorIndexOpnd<AsmOperandClass mc, code pred>
: Operand<i64>, ImmLeaf<i64, pred> {
let ParserMatchClass = mc;
let PrintMethod = "printVectorIndex";
let MIOperandInfo = (ops i64imm);
}
def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 16;
}]> {
let ParserMatchClass = VectorIndexBOperand;
let PrintMethod = "printVectorIndex";
let MIOperandInfo = (ops i64imm);
}
def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 8;
}]> {
let ParserMatchClass = VectorIndexHOperand;
let PrintMethod = "printVectorIndex";
let MIOperandInfo = (ops i64imm);
}
def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 4;
}]> {
let ParserMatchClass = VectorIndexSOperand;
let PrintMethod = "printVectorIndex";
let MIOperandInfo = (ops i64imm);
}
def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 2;
}]> {
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<VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>;
def VectorIndexB : AsmVectorIndexOpnd<VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>;
def VectorIndexH : AsmVectorIndexOpnd<VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>;
def VectorIndexS : AsmVectorIndexOpnd<VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>;
def VectorIndexD : AsmVectorIndexOpnd<VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>;
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<SVEVectorIndexExtDupBOperand, [{ return ((uint64_t)Imm) < 64; }]>;
def sve_elm_idx_extdup_h
: AsmVectorIndexOpnd<SVEVectorIndexExtDupHOperand, [{ return ((uint64_t)Imm) < 32; }]>;
def sve_elm_idx_extdup_s
: AsmVectorIndexOpnd<SVEVectorIndexExtDupSOperand, [{ return ((uint64_t)Imm) < 16; }]>;
def sve_elm_idx_extdup_d
: AsmVectorIndexOpnd<SVEVectorIndexExtDupDOperand, [{ return ((uint64_t)Imm) < 8; }]>;
def sve_elm_idx_extdup_q
: AsmVectorIndexOpnd<SVEVectorIndexExtDupQOperand, [{ return ((uint64_t)Imm) < 4; }]>;
// 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'.

View File

@ -45,6 +45,10 @@ let Predicates = [HasSVE] in {
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 @@ let Predicates = [HasSVE] in {
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">;

View File

@ -1048,24 +1048,13 @@ public:
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 <int Min, int Max>
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 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
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 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
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 @@ AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
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;
}

View File

@ -203,6 +203,7 @@ def addsub_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "uint64_t", SVEAddSubImmOperand64
return AArch64_AM::isSVEAddSubImm<int64_t>(Imm);
}]>;
//===----------------------------------------------------------------------===//
// SVE PTrue - These are used extensively throughout the pattern matching so
// it's important we define them first.
@ -284,6 +285,57 @@ multiclass sve_int_perm_dup_r<string asm> {
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>;
}
class sve_int_perm_dup_i<bits<5> 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<string asm> {
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<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>;
def : InstAlias<"mov $Zd, $Zn$idx",
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>;
def : InstAlias<"mov $Zd, $Zn$idx",
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>;
def : InstAlias<"mov $Zd, $Zn$idx",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
def : InstAlias<"mov $Zd, $Zn$idx",
(!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
}
//===----------------------------------------------------------------------===//
// SVE Logical Mask Immediate Group
//===----------------------------------------------------------------------===//

View File

@ -136,3 +136,57 @@ dup z0.d, #128, lsl #8
// 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]+}}:

View File

@ -180,3 +180,63 @@ dup z21.d, #32512
// CHECK-ENCODING: [0xf5,0xef,0xf8,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: f5 ef f8 25 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>

View File

@ -23,17 +23,17 @@ mov z0.d, xzr
// 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 @@ mov z0.d, p0/z, #128, lsl #8
// 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]+}}:

View File

@ -401,3 +401,66 @@ mov z21.d, p15/m, #-128, lsl #8
// CHECK-ENCODING: [0x15,0x70,0xdf,0x05]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 15 70 df 05 <unknown>
// --------------------------------------------------------------------------//
// 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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>
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 <unknown>