diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 9f7d6ddea31e5..22872d9eb10b5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -252,6 +252,10 @@ def HasSVE_B16MM : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSV AssemblerPredicateWithAll<(all_of FeatureSVE_B16MM), "sve-b16mm">; def HasF16MM : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasF16MM()">, AssemblerPredicateWithAll<(all_of FeatureF16MM), "f16mm">; +def HasSVE2p3 : Predicate<"Subtarget->hasSVE2p3()">, + AssemblerPredicateWithAll<(all_of FeatureSVE2p3), "sve2p3">; +def HasSME2p3 : Predicate<"Subtarget->hasSME2p3()">, + AssemblerPredicateWithAll<(all_of FeatureSME2p3), "sme2p3">; // A subset of SVE(2) instructions are legal in Streaming SVE execution mode, // they should be enabled if either has been specified. diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index ef974df823100..86a1fb52be789 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1341,6 +1341,10 @@ def Z_q : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<128, 1>; } +def ZZ_Any : RegisterOperand"> { + let ParserMatchClass = ZPRVectorList<0, 2>; +} + def ZZ_b : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<8, 2>; } @@ -1361,6 +1365,10 @@ def ZZ_q : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<128, 2>; } +def ZZZ_Any : RegisterOperand"> { + let ParserMatchClass = ZPRVectorList<0, 3>; +} + def ZZZ_b : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<8, 3>; } diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td index e552afee0d8cf..f3411c4d95d19 100644 --- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -1173,3 +1173,14 @@ let Predicates = [HasSME_MOP4, HasSMEF64F64] in { defm FMOP4A : sme2_fmop4as_fp64_non_widening<0, "fmop4a", "int_aarch64_sme_mop4a">; defm FMOP4S : sme2_fmop4as_fp64_non_widening<1, "fmop4s", "int_aarch64_sme_mop4s">; } + +//===----------------------------------------------------------------------===// +// SME2.3 instructions +//===----------------------------------------------------------------------===// +let Predicates = [HasSME2p3] in { + def LUTI6_ZTZ : sme2_lut_single<"luti6">; + def LUTI6_4ZT3Z : sme2_luti6_zt<"luti6">; + def LUTI6_S_4ZT3Z : sme2_luti6_zt_strided<"luti6">; + def LUTI6_4Z2Z2ZI : sme2_luti6_vector_vg4<"luti6">; + def LUTI6_S_4Z2Z2ZI : sme2_luti6_vector_vg4_strided<"luti6">; +} // [HasSME2p3] diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 7af4e9c0d7972..4232eba75bad0 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4659,8 +4659,17 @@ let Predicates = [HasSVE2p3_or_SME2p3] in { defm SQSHRUN_Z2ZI_StoH : sve_multi_vec_shift_narrow<"sqshrun", 0b100, null_frag>; defm SQSHRN_Z2ZI_StoH : sve_multi_vec_shift_narrow<"sqshrn", 0b000, null_frag>; defm UQSHRN_Z2ZI_StoH : sve_multi_vec_shift_narrow<"uqshrn", 0b010, null_frag>; + + defm LUTI6_Z2ZZI : sve2_luti6_vector_index<"luti6">; } // End HasSME2p3orSVE2p3 +//===----------------------------------------------------------------------===// +// SVE2.3 instructions +//===----------------------------------------------------------------------===// +let Predicates = [HasSVE2p3] in { + def LUTI6_Z2ZZ : sve2_luti6_vector; +} + //===----------------------------------------------------------------------===// // SVE_B16MM Instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index d9f3c4ffd5226..f92badab9a1eb 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -4882,6 +4882,13 @@ ParseStatus AArch64AsmParser::tryParseVectorList(OperandVector &Operands, FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S, getLoc(), getContext())); + if (getTok().isNot(AsmToken::Comma)) { + ParseStatus Res = tryParseVectorIndex(Operands); + if (Res.isFailure()) + return ParseStatus::Failure; + return ParseStatus::Success; + } + return ParseStatus::Success; } diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td index 33f35ad98a425..d5bc5ad84323a 100644 --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -3920,6 +3920,80 @@ multiclass sme2_luti4_vector_vg4_index { def _S : sme2_luti4_vector_vg4_index<0b10, ZZZZ_s_mul_r, mnemonic>; } +// 8-bit Look up table +class sme2_lut_single + : I<(outs ZPR8:$Zd), (ins ZTR:$ZTt, ZPRAny:$Zn), + asm, "\t$Zd, $ZTt, $Zn", "", []>, Sched<[]> { + bits<0> ZTt; + bits<5> Zd; + bits<5> Zn; + let Inst{31-10} = 0b1100000011001000010000; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + +class sme2_luti6_zt + : I<(outs ZZZZ_b_mul_r:$Zd), (ins ZTR:$ZTt, ZZZ_Any:$Zn), + asm, "\t$Zd, $ZTt, $Zn", "", []>, Sched<[]> { + bits<0> ZTt; + bits<3> Zd; + bits<3> Zn; + let Inst{31-10} = 0b1100000010001010000000; + let Inst{9-7} = Zn; + let Inst{6-5} = 0b00; + let Inst{4-2} = Zd; + let Inst{1-0} = 0b00; +} + +class sme2_luti6_zt_strided + : I<(outs ZZZZ_b_strided:$Zd), (ins ZTR:$ZTt, ZZZ_Any:$Zn), + asm, "\t$Zd, $ZTt, $Zn", "", []>, Sched<[]> { + bits<0> ZTt; + bits<3> Zd; + bits<3> Zn; + let Inst{31-10} = 0b1100000010011010000000; + let Inst{9-7} = Zn; + let Inst{6-5} = 0b00; + let Inst{4} = Zd{2}; + let Inst{3-2} = 0b00; + let Inst{1-0} = Zd{1-0}; +} + +class sme2_luti6_vector_vg4 + : I<(outs ZZZZ_h_mul_r:$Zd), (ins ZZ_h:$Zn, ZZ_Any:$Zm, VectorIndexD:$i1), + asm, "\t$Zd, $Zn, $Zm$i1", "", []>, Sched<[]> { + bits<3> Zd; + bits<5> Zn; + bits<5> Zm; + bits<1> i1; + let Inst{31-23} = 0b110000010; + let Inst{22} = i1; + let Inst{21} = 0b1; + let Inst{20-16} = Zm; + let Inst{15-10} = 0b111101; + let Inst{9-5} = Zn; + let Inst{4-2} = Zd; + let Inst{1-0} = 0b00; +} + +class sme2_luti6_vector_vg4_strided + : I<(outs ZZZZ_h_strided:$Zd), (ins ZZ_h:$Zn, ZZ_Any:$Zm, VectorIndexD:$i1), + asm, "\t$Zd, $Zn, $Zm$i1", "", []>, Sched<[]> { + bits<3> Zd; + bits<5> Zn; + bits<5> Zm; + bits<1> i1; + let Inst{31-23} = 0b110000010; + let Inst{22} = i1; + let Inst{21} = 0b1; + let Inst{20-16} = Zm; + let Inst{15-10} = 0b111111; + let Inst{9-5} = Zn; + let Inst{4} = Zd{2}; + let Inst{3-2} = 0b00; + let Inst{1-0} = Zd{1-0}; +} + //===----------------------------------------------------------------------===// // SME2 MOV class sme2_mova_vec_to_tile_vg2_multi_base sz, bit v, diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 68ca454357adf..d6e4b7290346c 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -11192,7 +11192,7 @@ multiclass sve2_fp8_dot_indexed_s { def : SVE_4_Op_Pat(NAME)>; } -// FP8 Look up table +// Look up table class sve2_lut_vector_indexopc, string mnemonic> : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm, idx_ty:$idx), @@ -11211,7 +11211,7 @@ class sve2_lut_vector_index { def _B : sve2_lut_vector_index { bits<2> idx; @@ -11233,7 +11233,7 @@ multiclass sve2_luti2_vector_index { i32, timm32_0_7, !cast(NAME # _H)>; } -// FP8 Look up table read with 4-bit indices +// Look up table read with 4-bit indices multiclass sve2_luti4_vector_index { def _B : sve2_lut_vector_index { bit idx; @@ -11254,7 +11254,7 @@ multiclass sve2_luti4_vector_index { i32, timm32_0_3, !cast(NAME # _H)>; } -// FP8 Look up table read with 4-bit indices (two contiguous registers) +// Look up table read with 4-bit indices (two contiguous registers) multiclass sve2_luti4_vector_vg2_index { def NAME : sve2_lut_vector_index { bits<2> idx; @@ -11278,6 +11278,33 @@ multiclass sve2_luti4_vector_vg2_index { nxv16i8:$Op3, timm32_0_3:$Op4))>; } +// Look up table read with 6-bit indices +multiclass sve2_luti6_vector_index { + def _H : sve2_lut_vector_index { + bit idx; + let Inst{23} = idx; + } +} + +// Look up table +class sve2_luti6_vectoropc, string mnemonic> + : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm), + mnemonic, "\t$Zd, $Zn, $Zm", + "", []>, Sched<[]> { + bits<5> Zd; + bits<5> Zn; + bits<5> Zm; + let Inst{31-24} = 0b01000101; + let Inst{23-22} = opc{4-3}; + let Inst{21} = 0b1; + let Inst{20-16} = Zm; + let Inst{15-13} = 0b101; + let Inst{12-10} = opc{2-0}; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + //===----------------------------------------------------------------------===// // Checked Pointer Arithmetic (FEAT_CPA) //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AArch64/SME2p3/luti6-diagnostics.s b/llvm/test/MC/AArch64/SME2p3/luti6-diagnostics.s new file mode 100644 index 0000000000000..9e81dd72f6184 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p3/luti6-diagnostics.s @@ -0,0 +1,176 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width + +luti6 z0.h, zt0, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti6 z0.h, zt0, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 z0.s, zt0, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: luti6 z0.s, zt0, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 z0.d, zt0, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: luti6 z0.d, zt0, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 z0.b, zt0, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z0.b, zt0, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 z0.b, zt0, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z0.b, zt0, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vectors/mis-matched registers/invalid index + +luti6 { z0.h - z5.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: luti6 { z0.h - z5.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.b - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: mismatched register size suffix +// CHECK-NEXT: luti6 { z0.b - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[2] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[2] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Wrong striding/registers/index + +luti6 { z0.h, z4.h, z8.h, z13.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: registers must have the same sequential stride +// CHECK-NEXT: luti6 { z0.h, z4.h, z8.h, z13.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z1.h, z2.h, z3.h, z4.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: luti6 { z1.h, z2.h, z3.h, z4.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.b, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: mismatched register size suffix +// CHECK-NEXT: luti6 { z0.b, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[2] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[2] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid registers + +luti6 { z0.b - z5.b }, zt0, { z2 - z4 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: luti6 { z0.b - z5.b }, zt0, { z2 - z4 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.b - z3.b }, zt0, { z1 - z1 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: luti6 { z0.b - z3.b }, zt0, { z1 - z1 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z0.b - z3.b }, zt1, { z1 - z3 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid lookup table, expected zt0 +// CHECK-NEXT: luti6 { z0.b - z3.b }, zt1, { z1 - z3 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 { z0.b - z3.b }, zt0, { z1 - z3 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.b - z3.b }, zt0, { z1 - z3 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 { z0.b - z3.b }, zt0, { z1 - z3 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z0.b - z3.b }, zt0, { z1 - z3 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Wrong striding/registers + +luti6 { z1.b, z5.b, z9.b, z14.b }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: registers must have the same sequential stride +// CHECK-NEXT: luti6 { z1.b, z5.b, z9.b, z14.b }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z1.b, z2.b, z3.b, z4.b }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: luti6 { z1.b, z2.b, z3.b, z4.b }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z20.b, z24.b, z28.b, z32.b }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector register expected +// CHECK-NEXT: luti6 { z20.b, z24.b, z28.b, z32.b }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 { z1.h, z5.h, z9.h, z13.h }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti6 { z1.h, z5.h, z9.h, z13.h }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2p3/luti6.s b/llvm/test/MC/AArch64/SME2p3/luti6.s new file mode 100644 index 0000000000000..7a7872f37a73b --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p3/luti6.s @@ -0,0 +1,472 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2p3 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// ---------------------------------------------------------- +// Lookup table read with 6-bit indices (single) + +luti6 z0.b, zt0, z0 +// CHECK-INST: luti6 z0.b, zt0, z0 +// CHECK-ENCODING: encoding: [0x00,0x40,0xc8,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c0c84000 + +luti6 z31.b, zt0, z0 +// CHECK-INST: luti6 z31.b, zt0, z0 +// CHECK-ENCODING: encoding: [0x1f,0x40,0xc8,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c0c8401f + +luti6 z0.b, zt0, z31 +// CHECK-INST: luti6 z0.b, zt0, z31 +// CHECK-ENCODING: encoding: [0xe0,0x43,0xc8,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c0c843e0 + +luti6 z31.b, zt0, z31 +// CHECK-INST: luti6 z31.b, zt0, z31 +// CHECK-ENCODING: encoding: [0xff,0x43,0xc8,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c0c843ff + +// ---------------------------------------------------------- +// Lookup table read with 6-bit indices (16-bit) - consecutive + +luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z0.h - z3.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x00,0xf4,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120f400 + +luti6 { z8.h - z11.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z8.h - z11.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x08,0xf4,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120f408 + +luti6 { z20.h - z23.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z20.h - z23.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x14,0xf4,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120f414 + +luti6 { z28.h - z31.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z28.h - z31.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x1c,0xf4,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120f41c + +luti6 { z0.h - z3.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z0.h - z3.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe0,0xf7,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ff7e0 + +luti6 { z8.h - z11.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z8.h - z11.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe8,0xf7,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ff7e8 + +luti6 { z20.h - z23.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z20.h - z23.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xf4,0xf7,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ff7f4 + +luti6 { z28.h - z31.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z28.h - z31.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xfc,0xf7,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ff7fc + +// ---------------------------------------------------------- +// Lookup table read with 6-bit indices (16-bit) - strided + +luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z0.h, z4.h, z8.h, z12.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x00,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc00 + +luti6 { z1.h, z5.h, z9.h, z13.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z1.h, z5.h, z9.h, z13.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x01,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc01 + +luti6 { z2.h, z6.h, z10.h, z14.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z2.h, z6.h, z10.h, z14.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x02,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc02 + +luti6 { z3.h, z7.h, z11.h, z15.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z3.h, z7.h, z11.h, z15.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x03,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc03 + +luti6 { z16.h, z20.h, z24.h, z28.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z16.h, z20.h, z24.h, z28.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x10,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc10 + +luti6 { z17.h, z21.h, z25.h, z29.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z17.h, z21.h, z25.h, z29.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x11,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc11 + +luti6 { z18.h, z22.h, z26.h, z30.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z18.h, z22.h, z26.h, z30.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x12,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc12 + +luti6 { z19.h, z23.h, z27.h, z31.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-INST: luti6 { z19.h, z23.h, z27.h, z31.h }, { z0.h, z1.h }, { z0, z1 }[0] +// CHECK-ENCODING: encoding: [0x13,0xfc,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c120fc13 + +luti6 { z0.h, z4.h, z8.h, z12.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z0.h, z4.h, z8.h, z12.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe0,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17fffe0 + +luti6 { z1.h, z5.h, z9.h, z13.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z1.h, z5.h, z9.h, z13.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe1,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17fffe1 + +luti6 { z2.h, z6.h, z10.h, z14.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z2.h, z6.h, z10.h, z14.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe2,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17fffe2 + +luti6 { z3.h, z7.h, z11.h, z15.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z3.h, z7.h, z11.h, z15.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xe3,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17fffe3 + +luti6 { z16.h, z20.h, z24.h, z28.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z16.h, z20.h, z24.h, z28.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xf0,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ffff0 + +luti6 { z17.h, z21.h, z25.h, z29.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z17.h, z21.h, z25.h, z29.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xf1,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ffff1 + +luti6 { z18.h, z22.h, z26.h, z30.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z18.h, z22.h, z26.h, z30.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xf2,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ffff2 + +luti6 { z19.h, z23.h, z27.h, z31.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-INST: luti6 { z19.h, z23.h, z27.h, z31.h }, { z31.h, z0.h }, { z31, z0 }[1] +// CHECK-ENCODING: encoding: [0xf3,0xff,0x7f,0xc1] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c17ffff3 + +// ---------------------------------------------------------- +// Lookup table read with 6-bit indices (8-bit) - consecutive + +luti6 { z8.b - z11.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z8.b - z11.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x08,0x00,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0008 + +luti6 { z20.b - z23.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z20.b - z23.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x14,0x00,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0014 + +luti6 { z28.b - z31.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z28.b - z31.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x1c,0x00,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a001c + +luti6 { z0.b - z3.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z0.b - z3.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x00,0x01,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0100 + +luti6 { z8.b - z11.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z8.b - z11.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x08,0x01,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0108 + +luti6 { z20.b - z23.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z20.b - z23.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x14,0x01,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0114 + +luti6 { z28.b - z31.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z28.b - z31.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x1c,0x01,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a011c + +luti6 { z0.b - z3.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z0.b - z3.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x80,0x02,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0280 + +luti6 { z8.b - z11.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z8.b - z11.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x88,0x02,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0288 + +luti6 { z20.b - z23.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z20.b - z23.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x94,0x02,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0294 + +luti6 { z28.b - z31.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z28.b - z31.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x9c,0x02,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a029c + +luti6 { z0.b - z3.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z0.b - z3.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x80,0x03,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0380 + +luti6 { z8.b - z11.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z8.b - z11.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x88,0x03,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0388 + +luti6 { z20.b - z23.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z20.b - z23.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x94,0x03,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a0394 + +luti6 { z28.b - z31.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z28.b - z31.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x9c,0x03,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c08a039c + +// ---------------------------------------------------------- +// Lookup table read with 6-bit indices (8-bit) - strided + +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x01,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0001 + +luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x02,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0002 + +luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x03,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0003 + +luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x10,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0010 + +luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x11,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0011 + +luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x12,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0012 + +luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z0 - z2 } +// CHECK-INST: luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z0 - z2 } +// CHECK-ENCODING: encoding: [0x13,0x00,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0013 + +luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x00,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0100 + +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x01,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0101 + +luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x02,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0102 + +luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x03,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0103 + +luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x10,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0110 + +luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x11,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0111 + +luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x12,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0112 + +luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z2 - z4 } +// CHECK-INST: luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z2 - z4 } +// CHECK-ENCODING: encoding: [0x13,0x01,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0113 + +luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x80,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0280 + +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x81,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0281 + +luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x82,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0282 + +luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x83,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0283 + +luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x90,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0290 + +luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x91,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0291 + +luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x92,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0292 + +luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z5 - z7 } +// CHECK-INST: luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z5 - z7 } +// CHECK-ENCODING: encoding: [0x93,0x02,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0293 + +luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z0.b, z4.b, z8.b, z12.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x80,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0380 + +luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z1.b, z5.b, z9.b, z13.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x81,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0381 + +luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z2.b, z6.b, z10.b, z14.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x82,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0382 + +luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z3.b, z7.b, z11.b, z15.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x83,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0383 + +luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z16.b, z20.b, z24.b, z28.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x90,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0390 + +luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z17.b, z21.b, z25.b, z29.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x91,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0391 + +luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z18.b, z22.b, z26.b, z30.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x92,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0392 + +luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z7 - z9 } +// CHECK-INST: luti6 { z19.b, z23.b, z27.b, z31.b }, zt0, { z7 - z9 } +// CHECK-ENCODING: encoding: [0x93,0x03,0x9a,0xc0] +// CHECK-ERROR: instruction requires: sme2p3 +// CHECK-UNKNOWN: c09a0393 diff --git a/llvm/test/MC/AArch64/SVE2p3/luti6-diagnostics.s b/llvm/test/MC/AArch64/SVE2p3/luti6-diagnostics.s new file mode 100644 index 0000000000000..21abded26305c --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/luti6-diagnostics.s @@ -0,0 +1,70 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width + +luti6 z10.h, { z0.b, z1.b }, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti6 z10.h, { z0.b, z1.b }, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 z10.s, { z0.b, z1.b }, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: luti6 z10.s, { z0.b, z1.b }, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid element width + +luti6 z10.s, { z0.h, z1.h }, z0[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: luti6 z10.s, { z0.h, z1.h }, z0[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 z10.b, { z0.h, z1.h }, z0[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti6 z10.b, { z0.h, z1.h }, z0[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate range + +luti6 z10.h, { z0.h, z1.h }, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti6 z10.h, { z0.h, z1.h }, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti6 z10.h, { z0.h, z1.h }, z0[2] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti6 z10.h, { z0.h, z1.h }, z0[2] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p3/luti6.s b/llvm/test/MC/AArch64/SVE2p3/luti6.s new file mode 100644 index 0000000000000..848091ccd7dde --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/luti6.s @@ -0,0 +1,115 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=-sve2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p3 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// --------------------------------------------------------------- +// Lookup table read with 6-bit indices (8-bit) + +luti6 z0.b, { z0.b, z1.b }, z0 +// CHECK-INST: luti6 z0.b, { z0.b, z1.b }, z0 +// CHECK-ENCODING: encoding: [0x00,0xac,0x20,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 4520ac00 + +luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK-INST: luti6 z10.b, { z0.b, z1.b }, z0 +// CHECK-ENCODING: encoding: [0x0a,0xac,0x20,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 4520ac0a + +luti6 z21.b, { z0.b, z1.b }, z0 +// CHECK-INST: luti6 z21.b, { z0.b, z1.b }, z0 +// CHECK-ENCODING: encoding: [0x15,0xac,0x20,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 4520ac15 + +luti6 z31.b, { z0.b, z1.b }, z0 +// CHECK-INST: luti6 z31.b, { z0.b, z1.b }, z0 +// CHECK-ENCODING: encoding: [0x1f,0xac,0x20,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 4520ac1f + +luti6 z0.b, { z31.b, z0.b }, z31 +// CHECK-INST: luti6 z0.b, { z31.b, z0.b }, z31 +// CHECK-ENCODING: encoding: [0xe0,0xaf,0x3f,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 453fafe0 + +luti6 z10.b, { z31.b, z0.b }, z31 +// CHECK-INST: luti6 z10.b, { z31.b, z0.b }, z31 +// CHECK-ENCODING: encoding: [0xea,0xaf,0x3f,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 453fafea + +luti6 z21.b, { z31.b, z0.b }, z31 +// CHECK-INST: luti6 z21.b, { z31.b, z0.b }, z31 +// CHECK-ENCODING: encoding: [0xf5,0xaf,0x3f,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 453faff5 + +luti6 z31.b, { z31.b, z0.b }, z31 +// CHECK-INST: luti6 z31.b, { z31.b, z0.b }, z31 +// CHECK-ENCODING: encoding: [0xff,0xaf,0x3f,0x45] +// CHECK-ERROR: instruction requires: sve2p3 +// CHECK-UNKNOWN: 453fafff + +// --------------------------------------------------------------- +// Lookup table read with 6-bit indices (16-bit) + +luti6 z0.h, { z0.h, z1.h }, z0[0] +// CHECK-INST: luti6 z0.h, { z0.h, z1.h }, z0[0] +// CHECK-ENCODING: encoding: [0x00,0xac,0x60,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 4560ac00 + +luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK-INST: luti6 z10.h, { z0.h, z1.h }, z0[0] +// CHECK-ENCODING: encoding: [0x0a,0xac,0x60,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 4560ac0a + +luti6 z21.h, { z0.h, z1.h }, z0[0] +// CHECK-INST: luti6 z21.h, { z0.h, z1.h }, z0[0] +// CHECK-ENCODING: encoding: [0x15,0xac,0x60,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 4560ac15 + +luti6 z31.h, { z0.h, z1.h }, z0[0] +// CHECK-INST: luti6 z31.h, { z0.h, z1.h }, z0[0] +// CHECK-ENCODING: encoding: [0x1f,0xac,0x60,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 4560ac1f + +luti6 z0.h, { z31.h, z0.h }, z31[1] +// CHECK-INST: luti6 z0.h, { z31.h, z0.h }, z31[1] +// CHECK-ENCODING: encoding: [0xe0,0xaf,0xff,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 45ffafe0 + +luti6 z10.h, { z31.h, z0.h }, z31[1] +// CHECK-INST: luti6 z10.h, { z31.h, z0.h }, z31[1] +// CHECK-ENCODING: encoding: [0xea,0xaf,0xff,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 45ffafea + +luti6 z21.h, { z31.h, z0.h }, z31[1] +// CHECK-INST: luti6 z21.h, { z31.h, z0.h }, z31[1] +// CHECK-ENCODING: encoding: [0xf5,0xaf,0xff,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 45ffaff5 + +luti6 z31.h, { z31.h, z0.h }, z31[1] +// CHECK-INST: luti6 z31.h, { z31.h, z0.h }, z31[1] +// CHECK-ENCODING: encoding: [0xff,0xaf,0xff,0x45] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 45ffafff