Skip to content

[AArch64] Add assembly/disassembly for zeroing SVE REV{B,H,W,D} and RBIT #114110

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 2 commits into from
Oct 31, 2024

Conversation

SpencerAbson
Copy link
Contributor

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

  - RBIT (zeroing)
  - REVB (zeroing)
  - REVH (zeroing)
  - REVW (zeroing)
  - REVD (zeroing)

Co-authored-by: Marian Lukac [email protected]

@llvmbot
Copy link
Member

llvmbot commented Oct 29, 2024

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-mc

Author: None (SpencerAbson)

Changes

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

  - RBIT (zeroing)
  - REVB (zeroing)
  - REVH (zeroing)
  - REVW (zeroing)
  - REVD (zeroing)

Co-authored-by: Marian Lukac [email protected]


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

14 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+6)
  • (modified) llvm/lib/Target/AArch64/SMEInstrFormats.td (+17)
  • (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+43)
  • (modified) llvm/test/MC/AArch64/SME/revd-diagnostics.s (+1-1)
  • (added) llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s (+74)
  • (added) llvm/test/MC/AArch64/SVE2p2/rbit_z.s (+45)
  • (added) llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s (+63)
  • (added) llvm/test/MC/AArch64/SVE2p2/revb_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s (+56)
  • (added) llvm/test/MC/AArch64/SVE2p2/revd_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s (+58)
  • (added) llvm/test/MC/AArch64/SVE2p2/revh_z.s (+33)
  • (added) llvm/test/MC/AArch64/SVE2p2/revw_z-diagnostics.s (+51)
  • (added) llvm/test/MC/AArch64/SVE2p2/revw_z.s (+33)
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 5c5ae898a8ac02..8cf55c1501754a 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4303,6 +4303,12 @@ let Predicates = [HasSVE2p2orSME2p2] in {
   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>;
 
+  // SVE reverse within elements, zeroing predicate
+  defm RBIT_ZPzZ : sve_int_perm_rev_rbit_z<"rbit">;
+  defm REVB_ZPzZ : sve_int_perm_rev_revb_z<"revb">;
+  defm REVH_ZPzZ : sve_int_perm_rev_revh_z<"revh">;
+  defm REVW_ZPzZ : sve_int_perm_rev_revw_z<"revw">;
+  def  REVD_ZPzZ : sve2_int_perm_revd_z<"revd">;
 } // End HasSME2p2orSVE2p2
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index e7c90b0ed14e06..211961d34b7007 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -1309,6 +1309,23 @@ multiclass sve2_int_perm_revd<string asm, SDPatternOperator op> {
 
 }
 
+class sve2_int_perm_revd_z<string asm>
+    : I<(outs ZPR128:$Zd), (ins PPR3bAny:$Pg, ZPR128:$Zn),
+        asm, "\t$Zd, $Pg/z, $Zn", "", []>,
+      Sched<[]> {
+  bits<5> Zd;
+  bits<3> Pg;
+  bits<5> Zn;
+  let Inst{31-24} = 0b00000101;
+  let Inst{23-22} = 0b00; // size
+  let Inst{21-13} = 0b101110101;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let hasSideEffects = 0;
+}
+
 class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
     : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
         asm, "\t$Zd, $Zn, $Zm", "", []>,
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 88a0983aa1480d..7c117704f6f59e 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -7375,6 +7375,49 @@ multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
 }
 
+class sve_int_perm_rev_z<bits<2> sz8_64, bits<2> opc, string asm,
+                       ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
+  asm, "\t$Zd, $Pg/z, $Zn",
+  "",
+  []>, Sched<[]> {
+  bits<5> Zd;
+  bits<3> Pg;
+  bits<5> Zn;
+  let Inst{31-24} = 0b00000101;
+  let Inst{23-22} = sz8_64;
+  let Inst{21-18} = 0b1001;
+  let Inst{17-16} = opc;
+  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_perm_rev_rbit_z<string asm> {
+  def _B : sve_int_perm_rev_z<0b00, 0b11, asm, ZPR8>;
+  def _H : sve_int_perm_rev_z<0b01, 0b11, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b11, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b11, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revb_z<string asm> {
+  def _H : sve_int_perm_rev_z<0b01, 0b00, asm, ZPR16>;
+  def _S : sve_int_perm_rev_z<0b10, 0b00, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b00, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revh_z<string asm> {
+  def _S : sve_int_perm_rev_z<0b10, 0b01, asm, ZPR32>;
+  def _D : sve_int_perm_rev_z<0b11, 0b01, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revw_z<string asm> {
+  def _D : sve_int_perm_rev_z<0b11, 0b10, asm, ZPR64>;
+}
+
 class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
                          RegisterClass srcRegType>
 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
diff --git a/llvm/test/MC/AArch64/SME/revd-diagnostics.s b/llvm/test/MC/AArch64/SME/revd-diagnostics.s
index 42205c26ce93fe..e7242e5dc1bbb3 100644
--- a/llvm/test/MC/AArch64/SME/revd-diagnostics.s
+++ b/llvm/test/MC/AArch64/SME/revd-diagnostics.s
@@ -11,7 +11,7 @@ revd z0.q, p8/m, z0.q
 
 // wrong predication qualifier, expected /m.
 revd z0.q, p0/z, z0.q
-// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction requires: sme2p2 or sve2p2
 // CHECK-NEXT: revd z0.q, p0/z, z0.q
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s
new file mode 100644
index 00000000000000..e20d8c4c1b97f8
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/rbit_z-diagnostics.s
@@ -0,0 +1,74 @@
+/ RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+rbit  z0.b, p8/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.b, p8/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.h, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.h, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: rbit  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+rbit  z0.b, p7/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.b, p7/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+rbit  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: rbit  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.b, p0/z, z7.b
+rbit  z0.b, p0/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.b, p0/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+rbit  z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0.s, p0/z, z7.s
+rbit  z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+rbit  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: rbit  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/rbit_z.s b/llvm/test/MC/AArch64/SVE2p2/rbit_z.s
new file mode 100644
index 00000000000000..3eb9c2d79306f3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/rbit_z.s
@@ -0,0 +1,45 @@
+// 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=-sve - | 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
+
+rbit    z0.b, p0/z, z0.b  // 00000101-00100111-10100000-00000000
+// CHECK-INST: rbit    z0.b, p0/z, z0.b
+// CHECK-ENCODING: [0x00,0xa0,0x27,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0527a000 <unknown>
+
+rbit    z21.b, p5/z, z10.b  // 00000101-00100111-10110101-01010101
+// CHECK-INST: rbit    z21.b, p5/z, z10.b
+// CHECK-ENCODING: [0x55,0xb5,0x27,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0527b555 <unknown>
+
+rbit    z23.h, p3/z, z13.h  // 00000101-01100111-10101101-10110111
+// CHECK-INST: rbit    z23.h, p3/z, z13.h
+// CHECK-ENCODING: [0xb7,0xad,0x67,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0567adb7 <unknown>
+
+rbit    z23.s, p3/z, z13.s  // 00000101-10100111-10101101-10110111
+// CHECK-INST: rbit    z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xa7,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a7adb7 <unknown>
+
+rbit    z31.d, p7/z, z31.d  // 00000101-11100111-10111111-11111111
+// CHECK-INST: rbit    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe7,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e7bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s
new file mode 100644
index 00000000000000..4cf40f8fd7923d
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revb_z-diagnostics.s
@@ -0,0 +1,63 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revb  z0.h, p8/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.h, p8/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revb  z0.d, p8/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revb  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revb  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0, z7
+revb  z0.h, p0/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.h, p0/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0.s, p0/z, z7.s
+revb  z0.s, p0/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.s, p0/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+revb  z0.d, p0/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revb  z0.d, p0/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revb_z.s b/llvm/test/MC/AArch64/SVE2p2/revb_z.s
new file mode 100644
index 00000000000000..16dee586bd1d17
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revb_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=-sve - | 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
+
+revb    z0.h, p0/z, z0.h  // 00000101-01100100-10100000-00000000
+// CHECK-INST: revb    z0.h, p0/z, z0.h
+// CHECK-ENCODING: [0x00,0xa0,0x64,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 0564a000 <unknown>
+
+revb    z23.s, p3/z, z13.s  // 00000101-10100100-10101101-10110111
+// CHECK-INST: revb    z23.s, p3/z, z13.s
+// CHECK-ENCODING: [0xb7,0xad,0xa4,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05a4adb7 <unknown>
+
+revb    z31.d, p7/z, z31.d  // 00000101-11100100-10111111-11111111
+// CHECK-INST: revb    z31.d, p7/z, z31.d
+// CHECK-ENCODING: [0xff,0xbf,0xe4,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 05e4bfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s
new file mode 100644
index 00000000000000..ed031e4a8763d4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revd_z-diagnostics.s
@@ -0,0 +1,56 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revd  z0.q, p8/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revd  z0.q, p8/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+revd  z0.b, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.b, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.h, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.h, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.s, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.s, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.h, p7/z, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.h, p7/z, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.s, p7/z, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.s, p7/z, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.d, p7/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.d, p7/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd  z0.q, p7/z, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd  z0.q, p7/z, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0, z7
+revd  z0.q, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: revd  z0.q, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revd_z.s b/llvm/test/MC/AArch64/SVE2p2/revd_z.s
new file mode 100644
index 00000000000000..b8675f02686792
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revd_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=-sve - | 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
+
+revd    z0.q, p0/z, z0.q  // 00000101-00101110-10100000-00000000
+// CHECK-INST: revd    z0.q, p0/z, z0.q
+// CHECK-ENCODING: [0x00,0xa0,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052ea000 <unknown>
+
+revd    z23.q, p3/z, z13.q  // 00000101-00101110-10101101-10110111
+// CHECK-INST: revd    z23.q, p3/z, z13.q
+// CHECK-ENCODING: [0xb7,0xad,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052eadb7 <unknown>
+
+revd    z31.q, p7/z, z31.q  // 00000101-00101110-10111111-11111111
+// CHECK-INST: revd    z31.q, p7/z, z31.q
+// CHECK-ENCODING: [0xff,0xbf,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme2p2 or sve2p2
+// CHECK-UNKNOWN: 052ebfff <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s
new file mode 100644
index 00000000000000..c7b83bdf229ec6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p2/revh_z-diagnostics.s
@@ -0,0 +1,58 @@
+
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2  2>&1 < %s| FileCheck %s
+// ------------------------------------------------------------------------- //
+
+// Invalid predicate
+
+revh  z0.s, p8/z, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revh  z0.s, p8/z, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh  z0.d, p8/z, z0.d
+// CHECK: [[@LINE-1]]:{{[...
[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 support for the following SVE2.2 instructions
	- RBIT (zeroing)
	- REVB (zeroing)
	- REVH (zeroing)
	- REVW (zeroing)
	- REVD (zeroing)

Co-authored-by: Marian Lukac [email protected]
Copy link
Contributor

@Lukacma Lukacma left a comment

Choose a reason for hiding this comment

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

LGTM

@SpencerAbson SpencerAbson merged commit c485ee1 into llvm:main Oct 31, 2024
8 checks passed
smallp-o-p pushed a commit to smallp-o-p/llvm-project that referenced this pull request Nov 3, 2024
…BIT (llvm#114110)

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

      - RBIT (zeroing)
      - REVB (zeroing)
      - REVH (zeroing)
      - REVW (zeroing)
      - REVD (zeroing)

- In accordance with:
https://developer.arm.com/documentation/ddi0602/2024-09/SVE-Instructions

Co-authored-by: Marian Lukac [email protected]
NoumanAmir657 pushed a commit to NoumanAmir657/llvm-project that referenced this pull request Nov 4, 2024
…BIT (llvm#114110)

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

      - RBIT (zeroing)
      - REVB (zeroing)
      - REVH (zeroing)
      - REVW (zeroing)
      - REVD (zeroing)

- In accordance with:
https://developer.arm.com/documentation/ddi0602/2024-09/SVE-Instructions

Co-authored-by: Marian Lukac [email protected]
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.

4 participants