From 8d38fbf2f027c72332c8ba03ff0ff0f83b4dcf02 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Tue, 29 Oct 2024 09:09:55 +0000 Subject: [PATCH] =?UTF-8?q?[LLVM][AArch64]=20Add=20assembly/disassembly=20?= =?UTF-8?q?for=20SVE=20Integer=20Unary=20Arithm=E2=80=A6=20(#113670)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …etic Predicated instructions This patch adds the following instructions: SVE bitwise unary operations (predicated) CLS, CLZ, CNT, CNOT, FABS, FNEG, NOT SVE integer unary operations (predicated) SXT{B,H,W}, UXT{B,H,W}, ABS ,NEG SVE2 integer unary operations (predicated) URECPE, URSQRTE, SQABS, SQNEG According to https://developer.arm.com/documentation/ddi0602 Co-authored-by: Spencer Abson Spencer.Abson@arm.com --- .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 53 ++-- llvm/lib/Target/AArch64/SVEInstrFormats.td | 76 +++++- ...unary_arithmetic_predicated_z-diagnotics.s | 249 ++++++++++++++++++ .../SVE2p2/unary_arithmetic_predicated_z.s | 225 ++++++++++++++++ 4 files changed, 576 insertions(+), 27 deletions(-) create mode 100644 llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z-diagnotics.s create mode 100644 llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z.s diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 11c64df2eb9278..2b69903b133fe3 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -647,22 +647,22 @@ let Predicates = [HasSVEorSME] in { defm SDOT_ZZZI : sve_intx_dot_by_indexed_elem<0b0, "sdot", int_aarch64_sve_sdot_lane>; defm UDOT_ZZZI : sve_intx_dot_by_indexed_elem<0b1, "udot", int_aarch64_sve_udot_lane>; - defm SXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b000, "sxtb", AArch64sxt_mt>; - defm UXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b001, "uxtb", AArch64uxt_mt>; - defm SXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b010, "sxth", AArch64sxt_mt>; - defm UXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b011, "uxth", AArch64uxt_mt>; - defm SXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b100, "sxtw", AArch64sxt_mt>; - defm UXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b101, "uxtw", AArch64uxt_mt>; - defm ABS_ZPmZ : sve_int_un_pred_arit_0< 0b110, "abs", AArch64abs_mt>; - defm NEG_ZPmZ : sve_int_un_pred_arit_0< 0b111, "neg", AArch64neg_mt>; - - defm CLS_ZPmZ : sve_int_un_pred_arit_1< 0b000, "cls", AArch64cls_mt>; - defm CLZ_ZPmZ : sve_int_un_pred_arit_1< 0b001, "clz", AArch64clz_mt>; - defm CNT_ZPmZ : sve_int_un_pred_arit_1< 0b010, "cnt", AArch64cnt_mt>; - defm CNOT_ZPmZ : sve_int_un_pred_arit_1< 0b011, "cnot", AArch64cnot_mt>; - defm NOT_ZPmZ : sve_int_un_pred_arit_1< 0b110, "not", AArch64not_mt>; - defm FABS_ZPmZ : sve_int_un_pred_arit_1_fp<0b100, "fabs", AArch64fabs_mt>; - defm FNEG_ZPmZ : sve_int_un_pred_arit_1_fp<0b101, "fneg", AArch64fneg_mt>; + defm SXTB_ZPmZ : sve_int_un_pred_arit_h<0b000, "sxtb", AArch64sxt_mt>; + defm UXTB_ZPmZ : sve_int_un_pred_arit_h<0b001, "uxtb", AArch64uxt_mt>; + defm SXTH_ZPmZ : sve_int_un_pred_arit_w<0b010, "sxth", AArch64sxt_mt>; + defm UXTH_ZPmZ : sve_int_un_pred_arit_w<0b011, "uxth", AArch64uxt_mt>; + defm SXTW_ZPmZ : sve_int_un_pred_arit_d<0b100, "sxtw", AArch64sxt_mt>; + defm UXTW_ZPmZ : sve_int_un_pred_arit_d<0b101, "uxtw", AArch64uxt_mt>; + defm ABS_ZPmZ : sve_int_un_pred_arit< 0b110, "abs", AArch64abs_mt>; + defm NEG_ZPmZ : sve_int_un_pred_arit< 0b111, "neg", AArch64neg_mt>; + + defm CLS_ZPmZ : sve_int_un_pred_arit_bitwise< 0b000, "cls", AArch64cls_mt>; + defm CLZ_ZPmZ : sve_int_un_pred_arit_bitwise< 0b001, "clz", AArch64clz_mt>; + defm CNT_ZPmZ : sve_int_un_pred_arit_bitwise< 0b010, "cnt", AArch64cnt_mt>; + defm CNOT_ZPmZ : sve_int_un_pred_arit_bitwise< 0b011, "cnot", AArch64cnot_mt>; + defm NOT_ZPmZ : sve_int_un_pred_arit_bitwise< 0b110, "not", AArch64not_mt>; + defm FABS_ZPmZ : sve_int_un_pred_arit_bitwise_fp<0b100, "fabs", AArch64fabs_mt>; + defm FNEG_ZPmZ : sve_int_un_pred_arit_bitwise_fp<0b101, "fneg", AArch64fneg_mt>; foreach VT = [nxv2bf16, nxv4bf16, nxv8bf16] in { // No dedicated instruction, so just clear the sign bit. @@ -4271,6 +4271,27 @@ let Predicates = [HasSVE2p2orSME2p2] in { // Floating-point square root, zeroing predicate defm FSQRT_ZPZz : sve_fp_z2op_p_zd_hsd<0b01101, "fsqrt">; + // SVE2p2 integer unary arithmetic (bitwise), zeroing predicate + defm CLS_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b000, "cls">; + defm CLZ_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b001, "clz">; + defm CNT_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b010, "cnt">; + defm CNOT_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b011, "cnot">; + defm NOT_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b110, "not">; + + // floating point + defm FABS_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b100, "fabs">; + defm FNEG_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b101, "fneg">; + + // SVE2p2 integer unary arithmetic, zeroing predicate + defm SXTB_ZPzZ : sve_int_un_pred_arit_h_z<0b000, "sxtb">; + defm UXTB_ZPzZ : sve_int_un_pred_arit_h_z<0b001, "uxtb">; + defm SXTH_ZPzZ : sve_int_un_pred_arit_w_z<0b010, "sxth">; + defm UXTH_ZPzZ : sve_int_un_pred_arit_w_z<0b011, "uxth">; + defm ABS_ZPzZ : sve_int_un_pred_arit_z< 0b110, "abs">; + defm NEG_ZPzZ : sve_int_un_pred_arit_z< 0b111, "neg">; + def SXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1000, "sxtw", ZPR64>; + def UXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1010, "uxtw", ZPR64>; + } // End HasSME2p2orSVE2p2 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 72cbad17bc049f..31312e00b919e2 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -4685,8 +4685,30 @@ class sve_int_un_pred_arit sz8_64, bits<4> opc, let hasSideEffects = 0; } -multiclass sve_int_un_pred_arit_0 opc, string asm, - SDPatternOperator op> { +class sve_int_un_pred_arit_z sz8_64, bits<4> opc, + string asm, ZPRRegOp zprty> +: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn), + asm, "\t$Zd, $Pg/z, $Zn", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Zd; + bits<5> Zn; + let Inst{31-24} = 0b00000100; + let Inst{23-22} = sz8_64; + let Inst{21-20} = 0b00; + let Inst{19} = opc{0}; + let Inst{18-16} = opc{3-1}; + let Inst{15-13} = 0b101; + let Inst{12-10} = Pg; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; + + let hasSideEffects = 0; +} + +multiclass sve_int_un_pred_arit opc, string asm, + SDPatternOperator op> { def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>, SVEPseudo2Instr; def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>, @@ -4712,8 +4734,15 @@ multiclass sve_int_un_pred_arit_0 opc, string asm, defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_0_h opc, string asm, - SDPatternOperator op> { +multiclass sve_int_un_pred_arit_z opc, string asm> { + def _B : sve_int_un_pred_arit_z<0b00, { opc, 0b0 }, asm, ZPR8>; + def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b0 }, asm, ZPR16>; + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>; +} + +multiclass sve_int_un_pred_arit_h opc, string asm, + SDPatternOperator op> { def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>, SVEPseudo2Instr; def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>, @@ -4734,8 +4763,14 @@ multiclass sve_int_un_pred_arit_0_h opc, string asm, defm : SVE_InReg_Extend_PassthruUndef(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_0_w opc, string asm, - SDPatternOperator op> { +multiclass sve_int_un_pred_arit_h_z opc, string asm> { + def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b0 }, asm, ZPR16>; + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>; +} + +multiclass sve_int_un_pred_arit_w opc, string asm, + SDPatternOperator op> { def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>, SVEPseudo2Instr; def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>, @@ -4751,8 +4786,13 @@ multiclass sve_int_un_pred_arit_0_w opc, string asm, defm : SVE_InReg_Extend_PassthruUndef(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_0_d opc, string asm, - SDPatternOperator op> { +multiclass sve_int_un_pred_arit_w_z opc, string asm> { + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>; +} + +multiclass sve_int_un_pred_arit_d opc, string asm, + SDPatternOperator op> { def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>, SVEPseudo2Instr; @@ -4763,8 +4803,8 @@ multiclass sve_int_un_pred_arit_0_d opc, string asm, defm : SVE_InReg_Extend_PassthruUndef(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_1 opc, string asm, - SDPatternOperator op> { +multiclass sve_int_un_pred_arit_bitwise opc, string asm, + SDPatternOperator op> { def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>, SVEPseudo2Instr; def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>, @@ -4790,7 +4830,15 @@ multiclass sve_int_un_pred_arit_1 opc, string asm, defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_1_fp opc, string asm, SDPatternOperator op> { +multiclass sve_int_un_pred_arit_bitwise_z opc, string asm> { + def _B : sve_int_un_pred_arit_z<0b00, { opc, 0b1 }, asm, ZPR8>; + def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>; + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>; +} + +multiclass sve_int_un_pred_arit_bitwise_fp opc, string asm, + SDPatternOperator op> { def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>, SVEPseudo2Instr; def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>, @@ -4817,6 +4865,12 @@ multiclass sve_int_un_pred_arit_1_fp opc, string asm, SDPatternOperator defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } +multiclass sve_int_un_pred_arit_bitwise_fp_z opc, string asm> { + def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>; + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>; +} + //===----------------------------------------------------------------------===// // SVE Integer Wide Immediate - Unpredicated Group //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z-diagnotics.s b/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z-diagnotics.s new file mode 100644 index 00000000000000..b44039fae464a9 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z-diagnotics.s @@ -0,0 +1,249 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width +abs z31.b, p7/z, z31.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: abs z31.b, p7/z, z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cls z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: cls z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +clz z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: clz z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cnot z31.b, p7/z, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: cnot z31.b, p7/z, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cnt z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: cnt z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fabs z31.h, p7/z, z31.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fabs z31.h, p7/z, z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fneg z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fneg z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +neg z31.s, p7/z, z31.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: neg z31.s, p7/z, z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +not z31.b, p7/z, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: not z31.b, p7/z, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxtb z31.h, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sxtb z31.h, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxth z31.s, p7/z, z31.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sxth z31.s, p7/z, z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxtw z31.d, p7/z, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sxtw z31.d, p7/z, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxtb z31.s, p7/z, z31.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: uxtb z31.s, p7/z, z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxth z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: uxth z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxtw z31.d, p7/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: uxtw z31.d, p7/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid predicate + +abs z31.s, p8/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: abs z31.s, p8/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cls z31.b, p8/z, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: cls z31.b, p8/z, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +clz z31.b, p8/z, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: clz z31.b, p8/z, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cnot z31.b, p8/z, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: cnot z31.b, p8/z, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +cnt z31.b, p8/z, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: cnt z31.b, p8/z, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fabs z31.h, p8/z, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: fabs z31.h, p8/z, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fneg z31.h, p8/z, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: fneg z31.h, p8/z, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +neg z31.s, p8/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: neg z31.s, p8/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +not z31.b, p8/z, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: not z31.b, p8/z, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxtb z31.s, p8/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: sxtb z31.s, p8/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxth z0.s, p8/z, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: sxth z0.s, p8/z, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sxtw z0.d, p8/z, z0.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: sxtw z0.d, p8/z, z0.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxtb z31.s, p8/z, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: uxtb z31.s, p8/z, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxth z0.s, p8/z, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: uxth z0.s, p8/z, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uxtw z0.d, p8/z, z0.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: uxtw z0.d, p8/z, z0.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.d, p0/z, z7.d +abs z0.d, p0/z, z3.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: abs z0.d, p0/z, z3.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +cls z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: cls z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/z, z7.h +clz z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: clz z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +cnot z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: cnot z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/z, z7.h +cnt z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: cnt z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +fabs z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: fabs z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/z, z7.h +fneg z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: fneg z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +neg z0.d, p0/z, z3.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: neg z0.d, p0/z, z3.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/z, z7.h +not z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: not z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +sxtb z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: sxtb z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.s, p0/z, z7.s +sxth z0.s, p0/z, z3.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: sxth z0.s, p0/z, z3.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +sxtw z0.d, p0/z, z3.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: sxtw z0.d, p0/z, z3.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +uxtb z0.h, p0/z, z3.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: uxtb z0.h, p0/z, z3.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.s, p0/z, z7.s +uxth z0.s, p0/z, z3.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: uxth z0.s, p0/z, z3.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +uxtw z0.d, p0/z, z3.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov +// CHECK-NEXT: uxtw z0.d, p0/z, z3.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z.s b/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z.s new file mode 100644 index 00000000000000..c460602f31ae64 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z.s @@ -0,0 +1,225 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// ABS + +abs z0.b, p0/z, z0.b // 00000100-00000110-10100000-00000000 +// CHECK-INST: abs z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x06,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0406a000 + +abs z31.d, p7/z, z31.d // 00000100-11000110-10111111-11111111 +// CHECK-INST: abs z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc6,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c6bfff + + +// CLS + +cls z0.b, p0/z, z0.b // 00000100-00001000-10100000-00000000 +// CHECK-INST: cls z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x08,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0408a000 + +clz z31.d, p7/z, z31.d // 00000100-11001001-10111111-11111111 +// CHECK-INST: clz z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc9,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c9bfff + +// CLZ + +clz z0.b, p0/z, z0.b // 00000100-00001001-10100000-00000000 +// CHECK-INST: clz z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x09,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0409a000 + +clz z31.d, p7/z, z31.d // 00000100-11001001-10111111-11111111 +// CHECK-INST: clz z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc9,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c9bfff + +// CNOT + +cnot z0.b, p0/z, z0.b // 00000100-00001011-10100000-00000000 +// CHECK-INST: cnot z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x0b,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 040ba000 + +cnot z31.d, p7/z, z31.d // 00000100-11001011-10111111-11111111 +// CHECK-INST: cnot z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xcb,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04cbbfff + +// CNT + +cnt z0.b, p0/z, z0.b // 00000100-00001010-10100000-00000000 +// CHECK-INST: cnt z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x0a,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 040aa000 + +cnt z31.d, p7/z, z31.d // 00000100-11001010-10111111-11111111 +// CHECK-INST: cnt z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xca,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04cabfff + + +// FABS + +fabs z0.h, p0/z, z0.h // 00000100-01001100-10100000-00000000 +// CHECK-INST: fabs z0.h, p0/z, z0.h +// CHECK-ENCODING: [0x00,0xa0,0x4c,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 044ca000 + +fabs z31.d, p7/z, z31.d // 00000100-11001100-10111111-11111111 +// CHECK-INST: fabs z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xcc,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04ccbfff + +// FNEG + +fneg z0.h, p0/z, z0.h // 00000100-01001101-10100000-00000000 +// CHECK-INST: fneg z0.h, p0/z, z0.h +// CHECK-ENCODING: [0x00,0xa0,0x4d,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 044da000 + +fneg z31.d, p7/z, z31.d // 00000100-11001101-10111111-11111111 +// CHECK-INST: fneg z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xcd,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04cdbfff + +// NEG + +neg z0.b, p0/z, z0.b // 00000100-00000111-10100000-00000000 +// CHECK-INST: neg z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x07,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0407a000 + +neg z31.d, p7/z, z31.d // 00000100-11000111-10111111-11111111 +// CHECK-INST: neg z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc7,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c7bfff + +//NOT + +not z0.b, p0/z, z0.b // 00000100-00001110-10100000-00000000 +// CHECK-INST: not z0.b, p0/z, z0.b +// CHECK-ENCODING: [0x00,0xa0,0x0e,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 040ea000 + +not z31.d, p7/z, z31.d // 00000100-11001110-10111111-11111111 +// CHECK-INST: not z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xce,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04cebfff + +// SXTB + +sxtb z0.h, p0/z, z0.h // 00000100-01000000-10100000-00000000 +// CHECK-INST: sxtb z0.h, p0/z, z0.h +// CHECK-ENCODING: [0x00,0xa0,0x40,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0440a000 + +sxtb z31.d, p7/z, z31.d // 00000100-11000000-10111111-11111111 +// CHECK-INST: sxtb z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc0,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c0bfff + +// SXTH + +sxth z0.s, p0/z, z0.s // 00000100-10000010-10100000-00000000 +// CHECK-INST: sxth z0.s, p0/z, z0.s +// CHECK-ENCODING: [0x00,0xa0,0x82,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0482a000 + +sxth z31.d, p7/z, z31.d // 00000100-11000010-10111111-11111111 +// CHECK-INST: sxth z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc2,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c2bfff + +// SXTW + +sxtw z0.d, p0/z, z0.d // 00000100-11000100-10100000-00000000 +// CHECK-INST: sxtw z0.d, p0/z, z0.d +// CHECK-ENCODING: [0x00,0xa0,0xc4,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c4a000 + +sxtw z31.d, p7/z, z31.d // 00000100-11000100-10111111-11111111 +// CHECK-INST: sxtw z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc4,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c4bfff + +// UXTB + +uxtb z0.h, p0/z, z0.h // 00000100-01000001-10100000-00000000 +// CHECK-INST: uxtb z0.h, p0/z, z0.h +// CHECK-ENCODING: [0x00,0xa0,0x41,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0441a000 + +uxtb z31.d, p7/z, z31.d // 00000100-11000001-10111111-11111111 +// CHECK-INST: uxtb z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc1,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c1bfff + +uxth z0.s, p0/z, z0.s // 00000100-10000011-10100000-00000000 +// CHECK-INST: uxth z0.s, p0/z, z0.s +// CHECK-ENCODING: [0x00,0xa0,0x83,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 0483a000 + +uxth z31.d, p7/z, z31.d // 00000100-11000011-10111111-11111111 +// CHECK-INST: uxth z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc3,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c3bfff + +// UXTW + +uxtw z0.d, p0/z, z0.d // 00000100-11000101-10100000-00000000 +// CHECK-INST: uxtw z0.d, p0/z, z0.d +// CHECK-ENCODING: [0x00,0xa0,0xc5,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c5a000 + +uxtw z31.d, p7/z, z31.d // 00000100-11000101-10111111-11111111 +// CHECK-INST: uxtw z31.d, p7/z, z31.d +// CHECK-ENCODING: [0xff,0xbf,0xc5,0x04] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 04c5bfff