[llvm] 8d38fbf - [LLVM][AArch64] Add assembly/disassembly for SVE Integer Unary Arithm… (#113670)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 29 02:09:59 PDT 2024


Author: CarolineConcatto
Date: 2024-10-29T09:09:55Z
New Revision: 8d38fbf2f027c72332c8ba03ff0ff0f83b4dcf02

URL: https://github.com/llvm/llvm-project/commit/8d38fbf2f027c72332c8ba03ff0ff0f83b4dcf02
DIFF: https://github.com/llvm/llvm-project/commit/8d38fbf2f027c72332c8ba03ff0ff0f83b4dcf02.diff

LOG: [LLVM][AArch64] Add assembly/disassembly for SVE Integer Unary Arithm… (#113670)

…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 at arm.com

Added: 
    llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z-diagnotics.s
    llvm/test/MC/AArch64/SVE2p2/unary_arithmetic_predicated_z.s

Modified: 
    llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
    llvm/lib/Target/AArch64/SVEInstrFormats.td

Removed: 
    


################################################################################
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<bits<2> sz8_64, bits<4> opc,
   let hasSideEffects = 0;
 }
 
-multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
-                                  SDPatternOperator op> {
+class sve_int_un_pred_arit_z<bits<2> 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<bits<3> opc, string asm,
+                                SDPatternOperator op> {
   def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
            SVEPseudo2Instr<NAME # _B, 1>;
   def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
@@ -4712,8 +4734,15 @@ multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
   defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
-multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
-                                    SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_z<bits<3> 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<bits<3> opc, string asm,
+                                  SDPatternOperator op> {
   def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
            SVEPseudo2Instr<NAME # _H, 1>;
   def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
@@ -4734,8 +4763,14 @@ multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
-multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
-                                    SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_h_z<bits<3> 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<bits<3> opc, string asm,
+                                  SDPatternOperator op> {
   def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
            SVEPseudo2Instr<NAME # _S, 1>;
   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
@@ -4751,8 +4786,13 @@ multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
-multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
-                                    SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_w_z<bits<3> 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<bits<3> opc, string asm,
+                                  SDPatternOperator op> {
   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
            SVEPseudo2Instr<NAME # _D, 1>;
 
@@ -4763,8 +4803,8 @@ multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
-multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
-                                  SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_bitwise<bits<3> opc, string asm,
+                                        SDPatternOperator op> {
   def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
            SVEPseudo2Instr<NAME # _B, 1>;
   def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
@@ -4790,7 +4830,15 @@ multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
   defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
-multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_bitwise_z<bits<3> 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<bits<3> opc, string asm,
+                                           SDPatternOperator op> {
   def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
            SVEPseudo2Instr<NAME # _H, 1>;
   def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
@@ -4817,6 +4865,12 @@ multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator
   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
 }
 
+multiclass sve_int_un_pred_arit_bitwise_fp_z<bits<3> 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 <unknown>
+
+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 <unknown>
+
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+//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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+// 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 <unknown>
+
+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 <unknown>


        


More information about the llvm-commits mailing list