[llvm] [LLVM][AARCH64] Add assembly/disassembly of zeroing convert instructions (PR #113292)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 22 03:04:55 PDT 2024


https://github.com/Lukacma created https://github.com/llvm/llvm-project/pull/113292

This patch adds the zeroing predicate forms (Pg/z) of the following instructions:
	- FCVTXNT
	- FCVNT
	- FCVTLT
	- BFCVTNT

As specified in https://developer.arm.com/documentation/ddi0602. 

Co-authored-by: Spencer Abson [spencer.abson at arm.com](mailto:spencer.abson at arm.com)

>From 9f6efeef82aaacd73fc6439f2ce4cb3383ea2264 Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Mon, 21 Oct 2024 15:34:32 +0000
Subject: [PATCH] [LLVM][AARCH64] Add assembly/disassembly of zeroing convert
 instructions

---
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 16 +++++
 llvm/lib/Target/AArch64/SVEInstrFormats.td    | 31 ++++++++++
 .../test/MC/AArch64/SVE/bfcvtnt-diagnostics.s |  2 +-
 .../test/MC/AArch64/SVE2/fcvtlt-diagnostics.s |  2 +-
 .../test/MC/AArch64/SVE2/fcvtnt-diagnostics.s |  2 +-
 .../MC/AArch64/SVE2/fcvtxnt-diagnostics.s     |  2 +-
 .../MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s | 52 ++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s       | 33 ++++++++++
 .../AArch64/SVE2p2/directive-arch-negative.s  |  7 +++
 llvm/test/MC/AArch64/SVE2p2/directive-arch.s  |  5 ++
 .../directive-arch_extension-negative.s       |  7 +++
 .../AArch64/SVE2p2/directive-arch_extension.s |  5 ++
 .../AArch64/SVE2p2/directive-cpu-negative.s   |  7 +++
 llvm/test/MC/AArch64/SVE2p2/directive-cpu.s   |  5 ++
 .../MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s  | 57 +++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s        | 33 ++++++++++
 .../MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s  | 56 +++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s        | 33 ++++++++++
 .../MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s | 62 +++++++++++++++++++
 llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z.s       | 33 ++++++++++
 20 files changed, 446 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-arch.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/directive-cpu.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z.s

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 2a857234c7d745..fb7cc7373be5ad 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4197,6 +4197,22 @@ defm TBXQ_ZZZ : sve2_int_perm_tbx<"tbxq", 0b10, int_aarch64_sve_tbxq>;
 defm TBLQ_ZZZ  : sve2p1_tblq<"tblq", int_aarch64_sve_tblq>;
 } // End HasSVE2p1_or_HasSME2p1
 
+
+//===----------------------------------------------------------------------===//
+// SME2.2 or SVE2.2 instructions
+//===----------------------------------------------------------------------===//
+let Predicates = [HasSVE2p2orSME2p2] in {
+  // SVE2p2 floating-point convert precision down (placing odd), zeroing predicate
+  defm FCVTNT_ZPzZ      : sve_fp_fcvtntz<"fcvtnt">;
+  def FCVTXNT_ZPzZ_DtoS : sve_fp_fcvt2z<0b0010, "fcvtxnt", ZPR32, ZPR64>;
+
+  // SVE2p2 floating-point convert precision up, zeroing predicate
+  defm FCVTLT_ZPzZ      : sve_fp_fcvtltz<"fcvtlt">;
+
+  // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate
+  def BFCVTNT_ZPzZ      : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>;
+} // End HasSME2p2orSVE2p2
+
 //===----------------------------------------------------------------------===//
 // SVE2 FP8 instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index f655526fa81cfe..4547fe3898e60c 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -2730,6 +2730,37 @@ multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
 }
 
+class sve_fp_fcvt2z<bits<4> opc, string asm, ZPRRegOp zprty1,
+                    ZPRRegOp zprty2>
+  : I<(outs zprty1:$Zd), (ins PPR3bAny:$Pg, zprty2:$Zn),
+    asm, "\t$Zd, $Pg/z, $Zn",
+    "",
+    []>, Sched<[]> {
+    bits<5> Zd;
+    bits<5> Zn;
+    bits<3> Pg;
+    let Inst{31-24} = 0b01100100;
+    let Inst{23-22} = opc{3-2};
+    let Inst{21-18} = 0b0000;
+    let Inst{17-16} = opc{1-0};
+    let Inst{15-13} = 0b101;
+    let Inst{12-10} = Pg;
+    let Inst{9-5}   = Zn;
+    let Inst{4-0}   = Zd;
+    let hasSideEffects = 0;
+    let mayRaiseFPException = 1;
+}
+
+multiclass sve_fp_fcvtntz<string asm> {
+  def _StoH : sve_fp_fcvt2z<0b1000, asm,  ZPR16, ZPR32>;
+  def _DtoS : sve_fp_fcvt2z<0b1110, asm,  ZPR32, ZPR64>;
+}
+
+multiclass sve_fp_fcvtltz<string asm> {
+  def _HtoS  : sve_fp_fcvt2z<0b1001, asm,  ZPR32, ZPR16>;
+  def _StoD  : sve_fp_fcvt2z<0b1111, asm,  ZPR64, ZPR32>;
+}
+
 //===----------------------------------------------------------------------===//
 // SVE2 Floating Point Pairwise Group
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s b/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
index 4717204fb8620e..d21a555ff87c60 100644
--- a/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE/bfcvtnt-diagnostics.s
@@ -11,7 +11,7 @@ bfcvtnt z0.h, p0/m, z1.h
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
 bfcvtnt z0.h, p0/z, z1.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
index 01ff152191fc48..95c69b84057d54 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtlt-diagnostics.s
@@ -39,7 +39,7 @@ fcvtlt z0.q, p0/m, z0.d
 // Invalid predicate operation
 
 fcvtlt z0.s, p0/z, z0.h
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtlt z0.s, p0/z, z0.h
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
index ae287b94ec01b8..c42b8f56e62002 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtnt-diagnostics.s
@@ -39,7 +39,7 @@ fcvtnt z0.d, p0/m, z0.q
 // Invalid predicate operation
 
 fcvtnt z0.h, p0/z, z0.s
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtnt z0.h, p0/z, z0.s
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s b/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
index e5903fdd379624..3b3a24a52055d9 100644
--- a/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
+++ b/llvm/test/MC/AArch64/SVE2/fcvtxnt-diagnostics.s
@@ -44,7 +44,7 @@ fcvtxnt z0.d, p0/m, z0.q
 // Invalid predicate operation
 
 fcvtxnt z0.s, p0/z, z0.d
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: fcvtxnt z0.s, p0/z, z0.d
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s
new file mode 100644
index 00000000000000..9a43f1f9e7c605
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z-diagnostics.s
@@ -0,0 +1,52 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+bfcvtnt z0.s, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.s, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.d, p0/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.d, p0/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+bfcvtnt z0.h, p0/z, z1.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+bfcvtnt z0.h, p8/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: bfcvtnt z0.h, p8/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.h, p0/m, z7.h
+bfcvtnt z0.h, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+bfcvtnt z0.h, p0/z, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_z.s
new file mode 100644
index 00000000000000..6e4ab9d6ced902
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/bfcvtnt_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
+
+bfcvtnt z0.h, p0/z, z0.s  // 01100100-10000010-10100000-00000000
+// CHECK-INST: bfcvtnt z0.h, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482a000 <unknown>
+
+bfcvtnt z23.h, p3/z, z13.s  // 01100100-10000010-10101101-10110111
+// CHECK-INST: bfcvtnt z23.h, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482adb7 <unknown>
+
+bfcvtnt z31.h, p7/z, z31.s  // 01100100-10000010-10111111-11111111
+// CHECK-INST: bfcvtnt z31.h, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x82,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6482bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s
new file mode 100644
index 00000000000000..6d5837eddec2cd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p2
+.arch armv9-a+nosve2p2
+bfcvtnt z23.h, p3/z, z13.s
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: bfcvtnt z23.h, p3/z, z13.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch.s
new file mode 100644
index 00000000000000..e7a5c6efd9d7e3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p2
+bfcvtnt z23.h, p3/z, z13.s
+// CHECK: bfcvtnt z23.h, p3/z, z13.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s
new file mode 100644
index 00000000000000..14b4cd722d04db
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p2
+.arch_extension nosve2p2
+bfcvtnt z0.h, p0/z, z0.s
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: bfcvtnt z0.h, p0/z, z0.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s
new file mode 100644
index 00000000000000..d18ac8081b3e08
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-arch_extension.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p2
+bfcvtnt z0.h, p0/z, z0.s
+// CHECK: bfcvtnt z0.h, p0/z, z0.s
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s b/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s
new file mode 100644
index 00000000000000..fc172bbf756dbd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-cpu-negative.s
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.cpu generic+sve2p2
+.cpu generic+nosve2p2
+fcvtnt  z0.s, p0/z, z0.d
+// CHECK: error: instruction requires: sme2p2 or sve2p2
+// CHECK-NEXT: fcvtnt  z0.s, p0/z, z0.d
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s b/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s
new file mode 100644
index 00000000000000..7874fa10f393c5
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/directive-cpu.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.cpu generic+sve2p2
+fcvtnt  z0.s, p0/z, z0.d
+// CHECK: fcvtnt  z0.s, p0/z, z0.d
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s
new file mode 100644
index 00000000000000..14deea93ce946f
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z-diagnostics.s
@@ -0,0 +1,57 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+fcvtlt z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.h, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.h, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtlt z0.q, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtlt z0.q, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+fcvtlt z0.s, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fcvtlt z0.s, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+fcvtlt z0.s, p7/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtlt z0.s, p7/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcvtlt z0.s, p7/z, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtlt z0.s, p7/z, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_z.s
new file mode 100644
index 00000000000000..00028de3208dfd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtlt_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
+
+fcvtlt  z0.d, p0/z, z0.s  // 01100100-11000011-10100000-00000000
+// CHECK-INST: fcvtlt  z0.d, p0/z, z0.s
+// CHECK-ENCODING: [0x00,0xa0,0xc3,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c3a000 <unknown>
+
+fcvtlt  z23.d, p3/z, z13.s  // 01100100-11000011-10101101-10110111
+// CHECK-INST: fcvtlt  z23.d, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xc3,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c3adb7 <unknown>
+
+fcvtlt  z31.s, p7/z, z31.h  // 01100100-10000001-10111111-11111111
+// CHECK-INST: fcvtlt  z31.s, p7/z, z31.h
+// CHECK-ENCODING: [0xff,0xbf,0x81,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6481bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s
new file mode 100644
index 00000000000000..317eae1e3f6ea2
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z-diagnostics.s
@@ -0,0 +1,56 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+fcvtnt z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.d, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtnt z0.d, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid operand for instruction
+
+fcvtnt z0.b, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fcvtnt z0.b, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtnt z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fcvtnt z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+fcvtnt z0.h, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fcvtnt z0.h, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z7.s
+fcvtnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcvtnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_z.s
new file mode 100644
index 00000000000000..6c86c6d15e76b3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtnt_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
+
+fcvtnt  z0.s, p0/z, z0.d  // 01100100-11000010-10100000-00000000
+// CHECK-INST: fcvtnt  z0.s, p0/z, z0.d
+// CHECK-ENCODING: [0x00,0xa0,0xc2,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c2a000 <unknown>
+
+fcvtnt  z23.s, p3/z, z13.d  // 01100100-11000010-10101101-10110111
+// CHECK-INST: fcvtnt  z23.s, p3/z, z13.d
+// CHECK-ENCODING: [0xb7,0xad,0xc2,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 64c2adb7 <unknown>
+
+fcvtnt  z31.h, p7/z, z31.s  // 01100100-10000000-10111111-11111111
+// CHECK-INST: fcvtnt  z31.h, p7/z, z31.s
+// CHECK-ENCODING: [0xff,0xbf,0x80,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6480bfff <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s
new file mode 100644
index 00000000000000..108c958880836e
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z-diagnostics.s
@@ -0,0 +1,62 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid element width
+
+fcvtxnt z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.h, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.h, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.b, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.b, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcvtxnt z0.d, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcvtxnt z0.d, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Predicate not in restricted predicate range
+
+fcvtxnt z0.s, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fcvtxnt z0.s, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/m, z7.s
+fcvtxnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtxnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcvtxnt z0.s, p7/z, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcvtxnt z0.s, p7/z, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z.s b/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_z.s
new file mode 100644
index 00000000000000..b1ffe1a6a3991b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/fcvtxnt_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
+
+fcvtxnt z0.s, p0/z, z0.d  // 01100100-00000010-10100000-00000000
+// CHECK-INST: fcvtxnt z0.s, p0/z, z0.d
+// CHECK-ENCODING: [0x00,0xa0,0x02,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6402a000 <unknown>
+
+fcvtxnt z23.s, p3/z, z13.d  // 01100100-00000010-10101101-10110111
+// CHECK-INST: fcvtxnt z23.s, p3/z, z13.d
+// CHECK-ENCODING: [0xb7,0xad,0x02,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6402adb7 <unknown>
+
+fcvtxnt z31.s, p7/z, z31.d  // 01100100-00000010-10111111-11111111
+// CHECK-INST: fcvtxnt z31.s, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0x02,0x64]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 6402bfff <unknown>



More information about the llvm-commits mailing list