Skip to content

[AArch64] Add assembly/disassembly for zeroing FRINT and FRECPX/FSQRT #113543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2024

Conversation

SpencerAbson
Copy link
Contributor

@SpencerAbson SpencerAbson commented Oct 24, 2024

This patch adds assembly/disassembly support for the following predicated SVE2.2 instructions

- FRINT32X, FRINT32Z (zeroing)
- FRINT64X, FRINT64Z (zeroing)
- FRINT{N,P,M,Z,A,X,I} (zeroing)
- FRECPX, FSQRT (zeroing)

@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2024

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-mc

Author: None (SpencerAbson)

Changes

This patch adds assembly/disassembly support for the following predicated SVE2.2 instructions

- FRINT32X, FRINT32Z (zeroing)
- FRINT64X, FRINT64Z (zeroing)
- FRINT{N,P,M,Z,A,X,I} (zeroing)
- FRECPX, FSQRT (zeroing)
  • Updates the diagnostics tests for existing merging variants of these instructions.

Patch is 64.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113543.diff

38 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64.td (+7-2)
  • (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+20)
  • (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+38)
  • (modified) llvm/test/MC/AArch64/SVE/frecpx-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frinta-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frinti-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frintm-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frintn-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frintp-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frintx-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/frintz-diagnostics.s (+1-1)
  • (modified) llvm/test/MC/AArch64/SVE/fsqrt-diagnostics.s (+1-1)
  • (added) llvm/test/MC/AArch64/SVE2p2/frecpx_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frecpx_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint32x_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint32x_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint32z_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint32z_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint64x_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint64x_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint64z_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frint64z_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frinta_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frinta_z.s (+34)
  • (added) llvm/test/MC/AArch64/SVE2p2/frinti_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frinti_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintm_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintm_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintn_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintn_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintp_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintp_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintx_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintx_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintz_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/frintz_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/fsqrt_z-diagnostics.s (+47)
  • (added) llvm/test/MC/AArch64/SVE2p2/fsqrt_z.s (+33)
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 2262ad1dfd0cc9..9bb508b783c36a 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -73,8 +73,13 @@ def SVEUnsupported : AArch64Unsupported {
                       SVE2Unsupported.F);
 }
 
-let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES] in
-def SME2p1Unsupported : AArch64Unsupported;
+let F = [HasSME2p2, HasSVE2p2orSME2p2] in
+def SME2p2Unsupported : AArch64Unsupported;
+
+def SME2p1Unsupported : AArch64Unsupported {
+  let F = !listconcat([HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES],
+                      SME2p2Unsupported.F);
+}
 
 def SME2Unsupported : AArch64Unsupported {
   let F = !listconcat([HasSME2, HasSVE2orSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA,
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index a097c138c5d6af..e1b9151b41b1b3 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4226,6 +4226,26 @@ let Predicates = [HasSVE2p2orSME2p2] in {
 
   // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate
   def BFCVTNT_ZPzZ      : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>;
+
+  // Floating-point round to integral fp value, zeroing predicate
+  defm FRINTN_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00000, "frintn">;
+  defm FRINTP_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00001, "frintp">;
+  defm FRINTM_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00010, "frintm">;
+  defm FRINTZ_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00011, "frintz">;
+  defm FRINTA_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00100, "frinta">;
+  defm FRINTX_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00110, "frintx">;
+  defm FRINTI_ZPzZ : sve_fp_z2op_p_zd_hsd<0b00111, "frinti">;
+  // Floating-point invert exponent, zeroing predicate
+  defm FRECPX_ZPzZ : sve_fp_z2op_p_zd_hsd<0b01100, "frecpx">;
+  // Floating-point square root, zeroing predicate
+  defm FSQRT_ZPZz  : sve_fp_z2op_p_zd_hsd<0b01101, "fsqrt">;
+
+  // Floating point round to integral fp value in integer size range
+  // Zeroing
+  defm FRINT32Z_ZPzZ : sve_fp_z2op_p_zd_frint<0b00, "frint32z">;
+  defm FRINT32X_ZPzZ : sve_fp_z2op_p_zd_frint<0b01, "frint32x">;
+  defm FRINT64Z_ZPzZ : sve_fp_z2op_p_zd_frint<0b10, "frint64z">;
+  defm FRINT64X_ZPzZ : sve_fp_z2op_p_zd_frint<0b11, "frint64x">;
 } // End HasSME2p2orSVE2p2
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 42e00b53400816..c24fe647bc3ff6 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -3138,6 +3138,44 @@ multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
   def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
 }
 
+//===----------------------------------------------------------------------===//
+// SVE Floating Point Unary Operations - Zeroing Predicate Group
+//===----------------------------------------------------------------------===//
+
+class sve_fp_z2op_p_zd<bits<7> opc,string asm, RegisterOperand i_zprtype,
+                       RegisterOperand o_zprtype>
+: I<(outs o_zprtype:$Zd), (ins PPR3bAny:$Pg, i_zprtype:$Zn),
+  asm, "\t$Zd, $Pg/z, $Zn",
+  "",
+  []>, Sched<[]> {
+  bits<3> Pg;
+  bits<5> Zd;
+  bits<5> Zn;
+  let Inst{31-24} = 0b01100100;
+  let Inst{23-22} = opc{6-5};
+  let Inst{21-19} = 0b011;
+  let Inst{18-16} = opc{4-2};
+  let Inst{15}    = 0b1;
+  let Inst{14-13} = opc{1-0};
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let hasSideEffects = 0;
+  let mayRaiseFPException = 1;
+}
+
+multiclass sve_fp_z2op_p_zd_hsd<bits<5> opc, string asm> {
+  def _H : sve_fp_z2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16>;
+  def _S : sve_fp_z2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32>;
+  def _D : sve_fp_z2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64>;
+}
+
+multiclass sve_fp_z2op_p_zd_frint<bits<2> opc, string asm> {
+  def _S : sve_fp_z2op_p_zd<{ 0b0010, opc{1}, 0, opc{0} }, asm, ZPR32, ZPR32>;
+  def _D : sve_fp_z2op_p_zd<{ 0b0010, opc{1}, 1, opc{0} }, asm, ZPR64, ZPR64>;
+}
+
 //===----------------------------------------------------------------------===//
 // SVE Integer Arithmetic - Binary Predicated Group
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SVE/frecpx-diagnostics.s b/llvm/test/MC/AArch64/SVE/frecpx-diagnostics.s
index a24f9c4a74c883..9b8d6889e5ff86 100644
--- a/llvm/test/MC/AArch64/SVE/frecpx-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frecpx-diagnostics.s
@@ -6,7 +6,7 @@ frecpx  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frecpx  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frecpx  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frinta-diagnostics.s b/llvm/test/MC/AArch64/SVE/frinta-diagnostics.s
index 136e123cb7eb3d..9ed088e9e9d1ac 100644
--- a/llvm/test/MC/AArch64/SVE/frinta-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frinta-diagnostics.s
@@ -6,7 +6,7 @@ frinta  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frinta  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frinta  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frinti-diagnostics.s b/llvm/test/MC/AArch64/SVE/frinti-diagnostics.s
index 8c619214c64d81..c8dda15a2cbd12 100644
--- a/llvm/test/MC/AArch64/SVE/frinti-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frinti-diagnostics.s
@@ -6,7 +6,7 @@ frinti  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frinti  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frinti  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frintm-diagnostics.s b/llvm/test/MC/AArch64/SVE/frintm-diagnostics.s
index a8ba48d353d029..cc6e72523464ab 100644
--- a/llvm/test/MC/AArch64/SVE/frintm-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frintm-diagnostics.s
@@ -6,7 +6,7 @@ frintm  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frintm  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frintm  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frintn-diagnostics.s b/llvm/test/MC/AArch64/SVE/frintn-diagnostics.s
index f5fb0705243643..09f64fc1ad6cf0 100644
--- a/llvm/test/MC/AArch64/SVE/frintn-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frintn-diagnostics.s
@@ -6,7 +6,7 @@ frintn  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frintn  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frintn  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frintp-diagnostics.s b/llvm/test/MC/AArch64/SVE/frintp-diagnostics.s
index 2766299d4c9b8b..ce7b7eafd83921 100644
--- a/llvm/test/MC/AArch64/SVE/frintp-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frintp-diagnostics.s
@@ -6,7 +6,7 @@ frintp  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frintp  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frintp  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frintx-diagnostics.s b/llvm/test/MC/AArch64/SVE/frintx-diagnostics.s
index 98620898cde935..edfa713ca00ac3 100644
--- a/llvm/test/MC/AArch64/SVE/frintx-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frintx-diagnostics.s
@@ -6,7 +6,7 @@ frintx  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frintx  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frintx  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/frintz-diagnostics.s b/llvm/test/MC/AArch64/SVE/frintz-diagnostics.s
index 8bb6717ce3ac70..ec974446bed38f 100644
--- a/llvm/test/MC/AArch64/SVE/frintz-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/frintz-diagnostics.s
@@ -6,7 +6,7 @@ frintz  z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 frintz  z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: frintz  z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE/fsqrt-diagnostics.s b/llvm/test/MC/AArch64/SVE/fsqrt-diagnostics.s
index 8b1abedb752cd7..4eb14ec3430418 100644
--- a/llvm/test/MC/AArch64/SVE/fsqrt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/fsqrt-diagnostics.s
@@ -6,7 +6,7 @@ fsqrt   z0.b, p0/m, z0.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 fsqrt   z0.s, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fsqrt   z0.s, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/frecpx_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/frecpx_z-diagnostics.s
new file mode 100644
index 00000000000000..b2aed8c7d59251
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/frecpx_z-diagnostics.s
@@ -0,0 +1,47 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+frecpx     z31.b, p7/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frecpx     z31.b, p7/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frecpx     z31.h, p7/z, z31.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frecpx     z31.h, p7/z, z31.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frecpx     z31.s, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frecpx     z31.s, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frecpx     z31.d, p7/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frecpx     z31.d, p7/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+frecpx     z31.h, p8/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: frecpx     z31.h, p8/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.h, p0/z, z7.h
+frecpx 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: frecpx z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+frecpx 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: frecpx z0.h, p0/z, z3.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/frecpx_z.s b/llvm/test/MC/AArch64/SVE2p2/frecpx_z.s
new file mode 100644
index 00000000000000..c089c8d623bae5
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/frecpx_z.s
@@ -0,0 +1,33 @@
+// 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
+
+frecpx  z0.h, p0/z, z0.h  // 01100100-01011011-10000000-00000000
+// CHECK-INST: frecpx  z0.h, p0/z, z0.h
+// CHECK-ENCODING: [0x00,0x80,0x5b,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 645b8000 <unknown>
+
+frecpx  z23.s, p3/z, z13.s  // 01100100-10011011-10001101-10110111
+// CHECK-INST: frecpx  z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0x8d,0x9b,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 649b8db7 <unknown>
+
+frecpx  z31.d, p7/z, z31.d  // 01100100-11011011-10011111-11111111
+// CHECK-INST: frecpx  z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0x9f,0xdb,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64db9fff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/frint32x_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/frint32x_z-diagnostics.s
new file mode 100644
index 00000000000000..a01eb73d508228
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/frint32x_z-diagnostics.s
@@ -0,0 +1,47 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+frint32x     z31.b, p7/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32x     z31.b, p7/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32x     z31.h, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32x     z31.h, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32x     z31.s, p7/z, z31.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32x     z31.s, p7/z, z31.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32x     z31.d, p7/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32x     z31.d, p7/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+frint32x     z31.s, p8/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: frint32x     z31.s, p8/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+frint32x 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: frint32x z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+frint32x 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: frint32x z0.d, p0/z, z3.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/frint32x_z.s b/llvm/test/MC/AArch64/SVE2p2/frint32x_z.s
new file mode 100644
index 00000000000000..abb0f78fb1e67e
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/frint32x_z.s
@@ -0,0 +1,33 @@
+// 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
+
+frint32x z0.d, p0/z, z0.d  // 01100100-00011100-11100000-00000000
+// CHECK-INST: frint32x z0.d, p0/z, z0.d
+// CHECK-ENCODING: [0x00,0xe0,0x1c,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 641ce000 <unknown>
+
+frint32x z23.d, p3/z, z13.d  // 01100100-00011100-11101101-10110111
+// CHECK-INST: frint32x z23.d, p3/z, z13.d
+// CHECK-ENCODING: [0xb7,0xed,0x1c,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 641cedb7 <unknown>
+
+frint32x z31.s, p7/z, z31.s  // 01100100-00011100-10111111-11111111
+// CHECK-INST: frint32x z31.s, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x1c,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 641cbfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/frint32z_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/frint32z_z-diagnostics.s
new file mode 100644
index 00000000000000..29bcfeca145a48
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/frint32z_z-diagnostics.s
@@ -0,0 +1,47 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+frint32z     z31.b, p7/z, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32z     z31.b, p7/z, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32z     z31.h, p7/z, z31.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32z     z31.h, p7/z, z31.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32z     z31.s, p7/z, z31.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32z     z31.s, p7/z, z31.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+frint32z     z31.d, p7/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: frint32z     z31.d, p7/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+frint32z     z31.s, p8/z, z31.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: frint32z     z31.s, p8/z, z31.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+frint32z 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: frint32z z0.s, p0/z, z3.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+frint32z z0.d, p0/...
[truncated]

Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Add assembly/disassembly for the following predicated SVE2.2 instructions
	- FRINT32X, FRINT32Z (zeroing)
	- FRINT64X, FRINT64Z (zeroing)
	- FRINT{N,P,M,Z,A,X,I} (zeroing)
	- FRECPX, FSQRT (zeroing)
@SpencerAbson SpencerAbson merged commit 87b3c07 into llvm:main Oct 24, 2024
8 checks passed
@frobtech frobtech mentioned this pull request Oct 25, 2024
NoumanAmir657 pushed a commit to NoumanAmir657/llvm-project that referenced this pull request Nov 4, 2024
…llvm#113543)

This patch adds assembly/disassembly support for the following
predicated SVE2.2 instructions

    - FRINT32X, FRINT32Z (zeroing)
    - FRINT64X, FRINT64Z (zeroing)
    - FRINT{N,P,M,Z,A,X,I} (zeroing)
    - FRECPX, FSQRT (zeroing)

- Updates the diagnostics tests for existing merging variants of these
instructions.
- In accordance with:
https://developer.arm.com/documentation/ddi0602/latest/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants