mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-09 13:21:30 +00:00
[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:
parent
0279feb6ed
commit
71703eae7a
@ -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'.
|
||||
|
@ -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">;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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]+}}:
|
||||
|
@ -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>
|
||||
|
@ -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]+}}:
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user