[llvm] [AArch64] Add assembly/disassembly for {S,SU,US,U}MOP4{A,S} instructions (PR #113349)

Momchil Velikov via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 22 10:40:47 PDT 2024


https://github.com/momchil-velikov created https://github.com/llvm/llvm-project/pull/113349

Co-Authored-By:  Marian Lukac <Marian.Lukac at arm.com>


>From d02becc15fd9487d7f87d0b7dbd39b4a1ed3f84b Mon Sep 17 00:00:00 2001
From: Momchil Velikov <momchil.velikov at arm.com>
Date: Tue, 22 Oct 2024 18:13:06 +0100
Subject: [PATCH] [AArch64] Add assembly/disassembly for {S,SU,US,U}MOP4{A,S}
 instructions

---
 .../lib/Target/AArch64/AArch64SMEInstrInfo.td |  27 +++++
 llvm/lib/Target/AArch64/SMEInstrFormats.td    | 110 ++++++++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4a-16to32.s   |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4a-64.s       |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4a-8to32.s    |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/smop4a-diagnostics.s    |  82 +++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4s-16to32.s   |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4s-64.s       |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/smop4s-8to32.s    |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/smop4s-diagnostics.s    |  82 +++++++++++++
 llvm/test/MC/AArch64/SME2p2/sumop4a-32.s      |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/sumop4a-64.s      |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/sumop4a-diagnostics.s   |  68 +++++++++++
 llvm/test/MC/AArch64/SME2p2/sumop4s-32.s      |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/sumop4s-64.s      |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/sumop4s-diagnostics.s   |  68 +++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4a-16to32.s   |  86 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4a-64.s       |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4a-8to32.s    |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/umop4a-diagnostics.s    |  82 +++++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4s-16to32.s   |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4s-64.s       |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/umop4s-8to32.s    |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/umop4s-diagnostics.s    |  82 +++++++++++++
 llvm/test/MC/AArch64/SME2p2/usmop4a-32.s      |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/usmop4a-64.s      |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/usmop4a-diagnostics.s   |  68 +++++++++++
 llvm/test/MC/AArch64/SME2p2/usmop4s-32.s      |  85 ++++++++++++++
 llvm/test/MC/AArch64/SME2p2/usmop4s-64.s      |  85 ++++++++++++++
 .../MC/AArch64/SME2p2/usmop4s-diagnostics.s   |  68 +++++++++++
 30 files changed, 2438 insertions(+)
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4a-16to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4a-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4a-8to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4a-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4s-16to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4s-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4s-8to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/smop4s-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4a-32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4a-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4a-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4s-32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4s-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/sumop4s-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4a-16to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4a-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4a-8to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4a-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4s-16to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4s-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4s-8to32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/umop4s-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4a-32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4a-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4a-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4s-32.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4s-64.s
 create mode 100644 llvm/test/MC/AArch64/SME2p2/usmop4s-diagnostics.s

diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 802797a14ee42d..2cefdd5341036a 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -131,6 +131,33 @@ defm USMOPA_MPPZZ_D : sme_int_outer_product_i64<0b100, "usmopa", int_aarch64_sme
 defm USMOPS_MPPZZ_D : sme_int_outer_product_i64<0b101, "usmops", int_aarch64_sme_usmops_wide>;
 }
 
+let Predicates = [HasSME2p2] in {
+  defm SMOP4A : sme_quarter_outer_product_i8_i32<0b0, 0b0, 0b0, "smop4a">;
+  defm SMOP4S : sme_quarter_outer_product_i8_i32<0b0, 0b0, 0b1, "smop4s">;
+  defm SUMOP4A : sme_quarter_outer_product_i8_i32<0b0, 0b1, 0b0, "sumop4a">;
+  defm SUMOP4S : sme_quarter_outer_product_i8_i32<0b0, 0b1, 0b1, "sumop4s">;
+  defm UMOP4A : sme_quarter_outer_product_i8_i32<0b1, 0b1, 0b0, "umop4a">;
+  defm UMOP4S : sme_quarter_outer_product_i8_i32<0b1, 0b1, 0b1, "umop4s">;
+  defm USMOP4A : sme_quarter_outer_product_i8_i32<0b1, 0b0, 0b0, "usmop4a">;
+  defm USMOP4S : sme_quarter_outer_product_i8_i32<0b1, 0b0, 0b1, "usmop4s">;
+
+  defm SMOP4A : sme_quarter_outer_product_i16_i32<0b0, 0b0, "smop4a">;
+  defm SMOP4S : sme_quarter_outer_product_i16_i32<0b0, 0b1, "smop4s">;
+  defm UMOP4A : sme_quarter_outer_product_i16_i32<0b1, 0b0, "umop4a">;
+  defm UMOP4S : sme_quarter_outer_product_i16_i32<0b1, 0b1, "umop4s">;
+}
+
+let Predicates = [HasSME2p2, HasSMEI16I64] in {
+  defm SMOP4A : sme_quarter_outer_product_i64<0b0, 0b0, 0b0, "smop4a">;
+  defm SMOP4S : sme_quarter_outer_product_i64<0b0, 0b0, 0b1, "smop4s">;
+  defm SUMOP4A : sme_quarter_outer_product_i64<0b0, 0b1, 0b0, "sumop4a">;
+  defm SUMOP4S : sme_quarter_outer_product_i64<0b0, 0b1, 0b1, "sumop4s">;
+  defm UMOP4A : sme_quarter_outer_product_i64<0b1, 0b1, 0b0, "umop4a">;
+  defm UMOP4S : sme_quarter_outer_product_i64<0b1, 0b1, 0b1, "umop4s">;
+  defm USMOP4A : sme_quarter_outer_product_i64<0b1, 0b0, 0b0, "usmop4a">;
+  defm USMOP4S : sme_quarter_outer_product_i64<0b1, 0b0, 0b1, "usmop4s">;
+}
+
 let Predicates = [HasSME] in {
 //===----------------------------------------------------------------------===//
 // Loads and stores
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 38d256c8234118..ef252eab009021 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -433,6 +433,116 @@ multiclass sme_f16_outer_product<bits<3> opc, string mnemonic, SDPatternOperator
   def : SME_ZA_Tile_TwoPred_TwoVec_Pat<NAME, op, timm32_0_3, nxv8i1, nxv8f16>;
 }
 
+class sme_quarter_outer_product_i64<bits<2> zn_u_pair, bits<2> zm_u_pair, bit subtr, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic>
+    : I<(outs TileOp64:$ZAda),
+        (ins  TileOp64:$_ZAda, zn_ty:$Zn, zm_ty:$Zm),
+        mnemonic, "\t$ZAda, $Zn, $Zm",
+        "", []>,
+      Sched<[]> {
+  bits<3> ZAda;
+  bits<3> Zn;
+  bits<3> Zm;
+  let Inst{31-25} = 0b1010000;
+  let Inst{24}    = zn_u_pair{1}; // u0
+  let Inst{23-22} = 0b11;
+  let Inst{21}    = zm_u_pair{1}; // u1
+  let Inst{20}    = zm_u_pair{0}; // M
+  let Inst{19-17} = Zm;
+  let Inst{16-10} = 0b0000000;
+  let Inst{9}     = zn_u_pair{0}; // N
+  let Inst{8-6}   = Zn;
+  let Inst{5}     = 0;
+  let Inst{4}     = subtr;
+  let Inst{3}     = 0b1;
+  let Inst{2-0}   = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+}
+
+class sme_quarter_outer_product_i8_i32<bits<2> zn_u_pair, bits<2> zm_u_pair, bit subtr, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic>
+    : I<(outs TileOp32:$ZAda),
+        (ins  TileOp32:$_ZAda, zn_ty:$Zn, zm_ty:$Zm),
+        mnemonic, "\t$ZAda, $Zn, $Zm",
+        "", []>,
+      Sched<[]> {
+  bits<2> ZAda;
+  bits<3> Zn;
+  bits<3> Zm;
+  let Inst{31-25} = 0b1000000;
+  let Inst{24}    = zn_u_pair{1}; // u0
+  let Inst{23-22} = 0b00;
+  let Inst{21}    = zm_u_pair{1}; // u1
+  let Inst{20}    = zm_u_pair{0}; // M
+  let Inst{19-17} = Zm;
+  let Inst{16-10} = 0b0100000;
+  let Inst{9}     = zn_u_pair{0}; // N
+  let Inst{8-6}   = Zn;
+  let Inst{5}     = 0;
+  let Inst{4}     = subtr;
+  let Inst{3-2}   = 0b00;
+  let Inst{1-0}   = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+}
+
+class sme_quarter_outer_product_i16_i32<bit unsigned, bit N, bit M, bit subtr, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic>
+    : I<(outs TileOp32:$ZAda),
+        (ins  TileOp32:$_ZAda, zn_ty:$Zn, zm_ty:$Zm),
+        mnemonic, "\t$ZAda, $Zn, $Zm",
+        "", []>,
+      Sched<[]> {
+  bits<2> ZAda;
+  bits<3> Zn;
+  bits<3> Zm;
+  let Inst{31-25} = 0b1000000;
+  let Inst{24}    = unsigned; // u0
+  let Inst{23-21} = 0b000;
+  let Inst{20}    = M;
+  let Inst{19-17} = Zm;
+  let Inst{16-10} = 0b0100000;
+  let Inst{9}     = N;
+  let Inst{8-6}   = Zn;
+  let Inst{5}     = 0;
+  let Inst{4}     = subtr;
+  let Inst{3-2}   = 0b10;
+  let Inst{1-0}   = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+}
+
+multiclass sme_quarter_outer_product_i8_i32<bit zn_u, bit zm_u, bit subtr, string mnemonic>{
+  def _MZZ_BToS   : sme_quarter_outer_product_i8_i32<{zn_u, 0}, {zm_u, 0}, subtr,
+                                                        ZPR8Mul2_Lo, ZPR8Mul2_Hi, mnemonic>;
+  def _M2ZZ_BToS  : sme_quarter_outer_product_i8_i32<{zn_u, 1}, {zm_u, 0}, subtr,
+                                                         ZZ_b_mul_r_Lo, ZPR8Mul2_Hi, mnemonic>;
+  def _MZ2Z_BToS  : sme_quarter_outer_product_i8_i32<{zn_u, 0}, {zm_u, 1}, subtr,
+                                                         ZPR8Mul2_Lo, ZZ_b_mul_r_Hi, mnemonic>;
+  def _M2Z2Z_BToS : sme_quarter_outer_product_i8_i32<{zn_u, 1}, {zm_u, 1}, subtr,
+                                                          ZZ_b_mul_r_Lo, ZZ_b_mul_r_Hi, mnemonic>;
+}
+
+multiclass sme_quarter_outer_product_i16_i32<bit unsigned, bit subtr, string mnemonic>{
+  def _MZZ_HToS   : sme_quarter_outer_product_i16_i32<unsigned, 0b0, 0b0, subtr,
+                                                        ZPR16Mul2_Lo, ZPR16Mul2_Hi, mnemonic>;
+  def _M2ZZ_HToS  : sme_quarter_outer_product_i16_i32<unsigned, 0b1, 0b0, subtr,
+                                                         ZZ_h_mul_r_Lo, ZPR16Mul2_Hi, mnemonic>;
+  def _MZ2Z_HToS  : sme_quarter_outer_product_i16_i32<unsigned, 0b0, 0b1, subtr,
+                                                         ZPR16Mul2_Lo, ZZ_h_mul_r_Hi, mnemonic>;
+  def _M2Z2Z_HToS : sme_quarter_outer_product_i16_i32<unsigned, 0b1, 0b1, subtr,
+                                                          ZZ_h_mul_r_Lo, ZZ_h_mul_r_Hi, mnemonic>;
+}
+
+multiclass sme_quarter_outer_product_i64<bit zn_u, bit zm_u, bit subtr, string mnemonic>{
+  def _MZZ_HtoD   : sme_quarter_outer_product_i64<{zn_u, 0}, {zm_u, 0}, subtr,
+                                                        ZPR16Mul2_Lo, ZPR16Mul2_Hi, mnemonic>;
+  def _M2ZZ_HtoD  : sme_quarter_outer_product_i64<{zn_u, 1}, {zm_u, 0}, subtr,
+                                                         ZZ_h_mul_r_Lo, ZPR16Mul2_Hi, mnemonic>;
+  def _MZ2Z_HtoD  : sme_quarter_outer_product_i64<{zn_u, 0}, {zm_u, 1}, subtr,
+                                                         ZPR16Mul2_Lo, ZZ_h_mul_r_Hi, mnemonic>;
+  def _M2Z2Z_HtoD : sme_quarter_outer_product_i64<{zn_u, 1}, {zm_u, 1}, subtr,
+                                                          ZZ_h_mul_r_Lo, ZZ_h_mul_r_Hi, mnemonic>;
+}
+
 //===----------------------------------------------------------------------===//
 // SME Add Vector to Tile
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4a-16to32.s b/llvm/test/MC/AArch64/SME2p2/smop4a-16to32.s
new file mode 100644
index 00000000000000..fe4de7307ec50b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4a-16to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4a  za0.s, z0.h, z16.h  // 10000000-00000000-10000000-00001000
+// CHECK-INST: smop4a  za0.s, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x80,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008008 <unknown>
+
+smop4a  za3.s, z12.h, z24.h  // 10000000-00001000-10000001-10001011
+// CHECK-INST: smop4a  za3.s, z12.h, z24.h
+// CHECK-ENCODING: [0x8b,0x81,0x08,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8008818b <unknown>
+
+smop4a  za3.s, z14.h, z30.h  // 10000000-00001110-10000001-11001011
+// CHECK-INST: smop4a  za3.s, z14.h, z30.h
+// CHECK-ENCODING: [0xcb,0x81,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e81cb <unknown>
+
+smop4a  za0.s, z0.h, {z16.h-z17.h}  // 10000000-00010000-10000000-00001000
+// CHECK-INST: smop4a  za0.s, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x80,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108008 <unknown>
+
+smop4a  za3.s, z12.h, {z24.h-z25.h}  // 10000000-00011000-10000001-10001011
+// CHECK-INST: smop4a  za3.s, z12.h, { z24.h, z25.h }
+// CHECK-ENCODING: [0x8b,0x81,0x18,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8018818b <unknown>
+
+smop4a  za3.s, z14.h, {z30.h-z31.h}  // 10000000-00011110-10000001-11001011
+// CHECK-INST: smop4a  za3.s, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcb,0x81,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e81cb <unknown>
+
+smop4a  za0.s, {z0.h-z1.h}, z16.h  // 10000000-00000000-10000010-00001000
+// CHECK-INST: smop4a  za0.s, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x82,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008208 <unknown>
+
+smop4a  za3.s, {z12.h-z13.h}, z24.h  // 10000000-00001000-10000011-10001011
+// CHECK-INST: smop4a  za3.s, { z12.h, z13.h }, z24.h
+// CHECK-ENCODING: [0x8b,0x83,0x08,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8008838b <unknown>
+
+smop4a  za3.s, {z14.h-z15.h}, z30.h  // 10000000-00001110-10000011-11001011
+// CHECK-INST: smop4a  za3.s, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcb,0x83,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e83cb <unknown>
+
+smop4a  za0.s, {z0.h-z1.h}, {z16.h-z17.h}  // 10000000-00010000-10000010-00001000
+// CHECK-INST: smop4a  za0.s, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x82,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108208 <unknown>
+
+smop4a  za3.s, {z12.h-z13.h}, {z24.h-z25.h}  // 10000000-00011000-10000011-10001011
+// CHECK-INST: smop4a  za3.s, { z12.h, z13.h }, { z24.h, z25.h }
+// CHECK-ENCODING: [0x8b,0x83,0x18,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8018838b <unknown>
+
+smop4a  za3.s, {z14.h-z15.h}, {z30.h-z31.h}  // 10000000-00011110-10000011-11001011
+// CHECK-INST: smop4a  za3.s, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcb,0x83,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e83cb <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4a-64.s b/llvm/test/MC/AArch64/SME2p2/smop4a-64.s
new file mode 100644
index 00000000000000..c3f2e780fc0144
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4a-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4a  za0.d, z0.h, z16.h  // 10100000-11000000-00000000-00001000
+// CHECK-INST: smop4a  za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x00,0xc0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c00008 <unknown>
+
+smop4a  za5.d, z10.h, z20.h  // 10100000-11000100-00000001-01001101
+// CHECK-INST: smop4a  za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x4d,0x01,0xc4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c4014d <unknown>
+
+smop4a  za7.d, z14.h, z30.h  // 10100000-11001110-00000001-11001111
+// CHECK-INST: smop4a  za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xcf,0x01,0xce,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ce01cf <unknown>
+
+smop4a  za0.d, z0.h, {z16.h-z17.h}  // 10100000-11010000-00000000-00001000
+// CHECK-INST: smop4a  za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x00,0xd0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d00008 <unknown>
+
+smop4a  za5.d, z10.h, {z20.h-z21.h}  // 10100000-11010100-00000001-01001101
+// CHECK-INST: smop4a  za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x01,0xd4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d4014d <unknown>
+
+smop4a  za7.d, z14.h, {z30.h-z31.h}  // 10100000-11011110-00000001-11001111
+// CHECK-INST: smop4a  za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x01,0xde,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0de01cf <unknown>
+
+smop4a  za0.d, {z0.h-z1.h}, z16.h  // 10100000-11000000-00000010-00001000
+// CHECK-INST: smop4a  za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x02,0xc0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c00208 <unknown>
+
+smop4a  za5.d, {z10.h-z11.h}, z20.h  // 10100000-11000100-00000011-01001101
+// CHECK-INST: smop4a  za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x4d,0x03,0xc4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c4034d <unknown>
+
+smop4a  za7.d, {z14.h-z15.h}, z30.h  // 10100000-11001110-00000011-11001111
+// CHECK-INST: smop4a  za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcf,0x03,0xce,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ce03cf <unknown>
+
+smop4a  za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100000-11010000-00000010-00001000
+// CHECK-INST: smop4a  za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x02,0xd0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d00208 <unknown>
+
+smop4a  za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100000-11010100-00000011-01001101
+// CHECK-INST: smop4a  za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x03,0xd4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d4034d <unknown>
+
+smop4a  za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100000-11011110-00000011-11001111
+// CHECK-INST: smop4a  za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x03,0xde,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0de03cf <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4a-8to32.s b/llvm/test/MC/AArch64/SME2p2/smop4a-8to32.s
new file mode 100644
index 00000000000000..0615c8fc690d8d
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4a-8to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4a  za0.s, z0.b, z16.b  // 10000000-00000000-10000000-00000000
+// CHECK-INST: smop4a  za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x00,0x80,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008000 <unknown>
+
+smop4a  za1.s, z10.b, z20.b  // 10000000-00000100-10000001-01000001
+// CHECK-INST: smop4a  za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x41,0x81,0x04,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80048141 <unknown>
+
+smop4a  za3.s, z14.b, z30.b  // 10000000-00001110-10000001-11000011
+// CHECK-INST: smop4a  za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xc3,0x81,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e81c3 <unknown>
+
+smop4a  za0.s, z0.b, {z16.b-z17.b}  // 10000000-00010000-10000000-00000000
+// CHECK-INST: smop4a  za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x80,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108000 <unknown>
+
+smop4a  za3.s, z12.b, {z24.b-z25.b}  // 10000000-00011000-10000001-10000011
+// CHECK-INST: smop4a  za3.s, z12.b, { z24.b, z25.b }
+// CHECK-ENCODING: [0x83,0x81,0x18,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80188183 <unknown>
+
+smop4a  za3.s, z14.b, {z30.b-z31.b}  // 10000000-00011110-10000001-11000011
+// CHECK-INST: smop4a  za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x81,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e81c3 <unknown>
+
+smop4a  za0.s, {z0.b-z1.b}, z16.b  // 10000000-00000000-10000010-00000000
+// CHECK-INST: smop4a  za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x00,0x82,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008200 <unknown>
+
+smop4a  za1.s, {z10.b-z11.b}, z20.b  // 10000000-00000100-10000011-01000001
+// CHECK-INST: smop4a  za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x41,0x83,0x04,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80048341 <unknown>
+
+smop4a  za3.s, {z14.b-z15.b}, z30.b  // 10000000-00001110-10000011-11000011
+// CHECK-INST: smop4a  za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xc3,0x83,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e83c3 <unknown>
+
+smop4a  za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000000-00010000-10000010-00000000
+// CHECK-INST: smop4a  za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x82,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108200 <unknown>
+
+smop4a  za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000000-00010100-10000011-01000001
+// CHECK-INST: smop4a  za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x83,0x14,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80148341 <unknown>
+
+smop4a  za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000000-00011110-10000011-11000011
+// CHECK-INST: smop4a  za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x83,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e83c3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4a-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/smop4a-diagnostics.s
new file mode 100644
index 00000000000000..01ddbe135c9487
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4a-diagnostics.s
@@ -0,0 +1,82 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+smop4a za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4a za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za4.s, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4a za4.s, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4a za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+smop4a za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: smop4a za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za0.s, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: smop4a za0.s, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za0.s, z16.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: smop4a za0.s, z16.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+smop4a za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4a za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za0.s, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: smop4a za0.s, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za0.s, z14.b, z14.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: smop4a za0.s, z14.b, z14.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, .s => .h, .d => .h
+
+smop4a za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4a za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: smop4a za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4a za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4a za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: smop4a za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4s-16to32.s b/llvm/test/MC/AArch64/SME2p2/smop4s-16to32.s
new file mode 100644
index 00000000000000..41828c97321a81
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4s-16to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4s  za0.s, z0.h, z16.h  // 10000000-00000000-10000000-00011000
+// CHECK-INST: smop4s  za0.s, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x80,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008018 <unknown>
+
+smop4s  za3.s, z12.h, z24.h  // 10000000-00001000-10000001-10011011
+// CHECK-INST: smop4s  za3.s, z12.h, z24.h
+// CHECK-ENCODING: [0x9b,0x81,0x08,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8008819b <unknown>
+
+smop4s  za3.s, z14.h, z30.h  // 10000000-00001110-10000001-11011011
+// CHECK-INST: smop4s  za3.s, z14.h, z30.h
+// CHECK-ENCODING: [0xdb,0x81,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e81db <unknown>
+
+smop4s  za0.s, z0.h, {z16.h-z17.h}  // 10000000-00010000-10000000-00011000
+// CHECK-INST: smop4s  za0.s, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x80,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108018 <unknown>
+
+smop4s  za3.s, z12.h, {z24.h-z25.h}  // 10000000-00011000-10000001-10011011
+// CHECK-INST: smop4s  za3.s, z12.h, { z24.h, z25.h }
+// CHECK-ENCODING: [0x9b,0x81,0x18,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8018819b <unknown>
+
+smop4s  za3.s, z14.h, {z30.h-z31.h}  // 10000000-00011110-10000001-11011011
+// CHECK-INST: smop4s  za3.s, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdb,0x81,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e81db <unknown>
+
+smop4s  za0.s, {z0.h-z1.h}, z16.h  // 10000000-00000000-10000010-00011000
+// CHECK-INST: smop4s  za0.s, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x82,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008218 <unknown>
+
+smop4s  za3.s, {z12.h-z13.h}, z24.h  // 10000000-00001000-10000011-10011011
+// CHECK-INST: smop4s  za3.s, { z12.h, z13.h }, z24.h
+// CHECK-ENCODING: [0x9b,0x83,0x08,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8008839b <unknown>
+
+smop4s  za3.s, {z14.h-z15.h}, z30.h  // 10000000-00001110-10000011-11011011
+// CHECK-INST: smop4s  za3.s, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdb,0x83,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e83db <unknown>
+
+smop4s  za0.s, {z0.h-z1.h}, {z16.h-z17.h}  // 10000000-00010000-10000010-00011000
+// CHECK-INST: smop4s  za0.s, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x82,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108218 <unknown>
+
+smop4s  za3.s, {z12.h-z13.h}, {z24.h-z25.h}  // 10000000-00011000-10000011-10011011
+// CHECK-INST: smop4s  za3.s, { z12.h, z13.h }, { z24.h, z25.h }
+// CHECK-ENCODING: [0x9b,0x83,0x18,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8018839b <unknown>
+
+smop4s  za3.s, {z14.h-z15.h}, {z30.h-z31.h}  // 10000000-00011110-10000011-11011011
+// CHECK-INST: smop4s  za3.s, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdb,0x83,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e83db <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4s-64.s b/llvm/test/MC/AArch64/SME2p2/smop4s-64.s
new file mode 100644
index 00000000000000..68dde0cd5d6af4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4s-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4s  za0.d, z0.h, z16.h  // 10100000-11000000-00000000-00011000
+// CHECK-INST: smop4s  za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x00,0xc0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c00018 <unknown>
+
+smop4s  za5.d, z10.h, z20.h  // 10100000-11000100-00000001-01011101
+// CHECK-INST: smop4s  za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x5d,0x01,0xc4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c4015d <unknown>
+
+smop4s  za7.d, z14.h, z30.h  // 10100000-11001110-00000001-11011111
+// CHECK-INST: smop4s  za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xdf,0x01,0xce,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ce01df <unknown>
+
+smop4s  za0.d, z0.h, {z16.h-z17.h}  // 10100000-11010000-00000000-00011000
+// CHECK-INST: smop4s  za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x00,0xd0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d00018 <unknown>
+
+smop4s  za5.d, z10.h, {z20.h-z21.h}  // 10100000-11010100-00000001-01011101
+// CHECK-INST: smop4s  za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x01,0xd4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d4015d <unknown>
+
+smop4s  za7.d, z14.h, {z30.h-z31.h}  // 10100000-11011110-00000001-11011111
+// CHECK-INST: smop4s  za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x01,0xde,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0de01df <unknown>
+
+smop4s  za0.d, {z0.h-z1.h}, z16.h  // 10100000-11000000-00000010-00011000
+// CHECK-INST: smop4s  za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x02,0xc0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c00218 <unknown>
+
+smop4s  za5.d, {z10.h-z11.h}, z20.h  // 10100000-11000100-00000011-01011101
+// CHECK-INST: smop4s  za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x5d,0x03,0xc4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0c4035d <unknown>
+
+smop4s  za7.d, {z14.h-z15.h}, z30.h  // 10100000-11001110-00000011-11011111
+// CHECK-INST: smop4s  za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdf,0x03,0xce,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ce03df <unknown>
+
+smop4s  za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100000-11010000-00000010-00011000
+// CHECK-INST: smop4s  za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x02,0xd0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d00218 <unknown>
+
+smop4s  za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100000-11010100-00000011-01011101
+// CHECK-INST: smop4s  za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x03,0xd4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0d4035d <unknown>
+
+smop4s  za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100000-11011110-00000011-11011111
+// CHECK-INST: smop4s  za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x03,0xde,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0de03df <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4s-8to32.s b/llvm/test/MC/AArch64/SME2p2/smop4s-8to32.s
new file mode 100644
index 00000000000000..43fbda91728668
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4s-8to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+smop4s  za0.s, z0.b, z16.b  // 10000000-00000000-10000000-00010000
+// CHECK-INST: smop4s  za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x10,0x80,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008010 <unknown>
+
+smop4s  za1.s, z10.b, z20.b  // 10000000-00000100-10000001-01010001
+// CHECK-INST: smop4s  za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x51,0x81,0x04,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80048151 <unknown>
+
+smop4s  za3.s, z14.b, z30.b  // 10000000-00001110-10000001-11010011
+// CHECK-INST: smop4s  za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xd3,0x81,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e81d3 <unknown>
+
+smop4s  za0.s, z0.b, {z16.b-z17.b}  // 10000000-00010000-10000000-00010000
+// CHECK-INST: smop4s  za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x80,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108010 <unknown>
+
+smop4s  za1.s, z10.b, {z20.b-z21.b}  // 10000000-00010100-10000001-01010001
+// CHECK-INST: smop4s  za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x81,0x14,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80148151 <unknown>
+
+smop4s  za3.s, z14.b, {z30.b-z31.b}  // 10000000-00011110-10000001-11010011
+// CHECK-INST: smop4s  za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x81,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e81d3 <unknown>
+
+smop4s  za0.s, {z0.b-z1.b}, z16.b  // 10000000-00000000-10000010-00010000
+// CHECK-INST: smop4s  za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x10,0x82,0x00,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80008210 <unknown>
+
+smop4s  za1.s, {z10.b-z11.b}, z20.b  // 10000000-00000100-10000011-01010001
+// CHECK-INST: smop4s  za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x51,0x83,0x04,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80048351 <unknown>
+
+smop4s  za3.s, {z14.b-z15.b}, z30.b  // 10000000-00001110-10000011-11010011
+// CHECK-INST: smop4s  za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xd3,0x83,0x0e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 800e83d3 <unknown>
+
+smop4s  za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000000-00010000-10000010-00010000
+// CHECK-INST: smop4s  za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x82,0x10,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80108210 <unknown>
+
+smop4s  za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000000-00010100-10000011-01010001
+// CHECK-INST: smop4s  za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x83,0x14,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80148351 <unknown>
+
+smop4s  za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000000-00011110-10000011-11010011
+// CHECK-INST: smop4s  za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x83,0x1e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 801e83d3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/smop4s-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/smop4s-diagnostics.s
new file mode 100644
index 00000000000000..a11402c8c7be6c
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/smop4s-diagnostics.s
@@ -0,0 +1,82 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+smop4s za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4s za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za4.s, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4s za4.s, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: smop4s za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+smop4s za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: smop4s za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za0.s, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: smop4s za0.s, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za0.s, z16.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: smop4s za0.s, z16.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+smop4s za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4s za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za0.s, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: smop4s za0.s, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za0.s, z14.b, z14.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: smop4s za0.s, z14.b, z14.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, s => .h, .d => .h
+
+smop4s za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4s za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: smop4s za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: smop4s za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+smop4s za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: smop4s za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4a-32.s b/llvm/test/MC/AArch64/SME2p2/sumop4a-32.s
new file mode 100644
index 00000000000000..8633eae24f4982
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4a-32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sumop4a za0.s, z0.b, z16.b  // 10000000-00100000-10000000-00000000
+// CHECK-INST: sumop4a za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x00,0x80,0x20,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80208000 <unknown>
+
+sumop4a za1.s, z10.b, z20.b  // 10000000-00100100-10000001-01000001
+// CHECK-INST: sumop4a za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x41,0x81,0x24,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80248141 <unknown>
+
+sumop4a za3.s, z14.b, z30.b  // 10000000-00101110-10000001-11000011
+// CHECK-INST: sumop4a za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xc3,0x81,0x2e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 802e81c3 <unknown>
+
+sumop4a za0.s, z0.b, {z16.b-z17.b}  // 10000000-00110000-10000000-00000000
+// CHECK-INST: sumop4a za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x80,0x30,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80308000 <unknown>
+
+sumop4a za1.s, z10.b, {z20.b-z21.b}  // 10000000-00110100-10000001-01000001
+// CHECK-INST: sumop4a za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x81,0x34,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80348141 <unknown>
+
+sumop4a za3.s, z14.b, {z30.b-z31.b}  // 10000000-00111110-10000001-11000011
+// CHECK-INST: sumop4a za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x81,0x3e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 803e81c3 <unknown>
+
+sumop4a za0.s, {z0.b-z1.b}, z16.b  // 10000000-00100000-10000010-00000000
+// CHECK-INST: sumop4a za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x00,0x82,0x20,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80208200 <unknown>
+
+sumop4a za1.s, {z10.b-z11.b}, z20.b  // 10000000-00100100-10000011-01000001
+// CHECK-INST: sumop4a za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x41,0x83,0x24,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80248341 <unknown>
+
+sumop4a za3.s, {z14.b-z15.b}, z30.b  // 10000000-00101110-10000011-11000011
+// CHECK-INST: sumop4a za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xc3,0x83,0x2e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 802e83c3 <unknown>
+
+sumop4a za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000000-00110000-10000010-00000000
+// CHECK-INST: sumop4a za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x82,0x30,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80308200 <unknown>
+
+sumop4a za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000000-00110100-10000011-01000001
+// CHECK-INST: sumop4a za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x83,0x34,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80348341 <unknown>
+
+sumop4a za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000000-00111110-10000011-11000011
+// CHECK-INST: sumop4a za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x83,0x3e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 803e83c3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4a-64.s b/llvm/test/MC/AArch64/SME2p2/sumop4a-64.s
new file mode 100644
index 00000000000000..e3a0843b12c7e2
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4a-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sumop4a za0.d, z0.h, z16.h  // 10100000-11100000-00000000-00001000
+// CHECK-INST: sumop4a za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x00,0xe0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e00008 <unknown>
+
+sumop4a za5.d, z10.h, z20.h  // 10100000-11100100-00000001-01001101
+// CHECK-INST: sumop4a za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x4d,0x01,0xe4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e4014d <unknown>
+
+sumop4a za7.d, z14.h, z30.h  // 10100000-11101110-00000001-11001111
+// CHECK-INST: sumop4a za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xcf,0x01,0xee,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ee01cf <unknown>
+
+sumop4a za0.d, z0.h, {z16.h-z17.h}  // 10100000-11110000-00000000-00001000
+// CHECK-INST: sumop4a za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x00,0xf0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f00008 <unknown>
+
+sumop4a za5.d, z10.h, {z20.h-z21.h}  // 10100000-11110100-00000001-01001101
+// CHECK-INST: sumop4a za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x01,0xf4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f4014d <unknown>
+
+sumop4a za7.d, z14.h, {z30.h-z31.h}  // 10100000-11111110-00000001-11001111
+// CHECK-INST: sumop4a za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x01,0xfe,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0fe01cf <unknown>
+
+sumop4a za0.d, {z0.h-z1.h}, z16.h  // 10100000-11100000-00000010-00001000
+// CHECK-INST: sumop4a za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x02,0xe0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e00208 <unknown>
+
+sumop4a za5.d, {z10.h-z11.h}, z20.h  // 10100000-11100100-00000011-01001101
+// CHECK-INST: sumop4a za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x4d,0x03,0xe4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e4034d <unknown>
+
+sumop4a za7.d, {z14.h-z15.h}, z30.h  // 10100000-11101110-00000011-11001111
+// CHECK-INST: sumop4a za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcf,0x03,0xee,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ee03cf <unknown>
+
+sumop4a za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100000-11110000-00000010-00001000
+// CHECK-INST: sumop4a za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x02,0xf0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f00208 <unknown>
+
+sumop4a za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100000-11110100-00000011-01001101
+// CHECK-INST: sumop4a za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x03,0xf4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f4034d <unknown>
+
+sumop4a za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100000-11111110-00000011-11001111
+// CHECK-INST: sumop4a za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x03,0xfe,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0fe03cf <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4a-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/sumop4a-diagnostics.s
new file mode 100644
index 00000000000000..456aa1ad713104
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4a-diagnostics.s
@@ -0,0 +1,68 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+sumop4a za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sumop4a za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sumop4a za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+sumop4a za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: sumop4a za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za0.d, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: sumop4a za0.d, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+sumop4a za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: sumop4a za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za0.d, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: sumop4a za0.d, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, .d => .h
+
+sumop4a za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: sumop4a za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: sumop4a za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: sumop4a za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4a za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: sumop4a za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4s-32.s b/llvm/test/MC/AArch64/SME2p2/sumop4s-32.s
new file mode 100644
index 00000000000000..be9a25d85a0153
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4s-32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sumop4s za0.s, z0.b, z16.b  // 10000000-00100000-10000000-00010000
+// CHECK-INST: sumop4s za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x10,0x80,0x20,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80208010 <unknown>
+
+sumop4s za1.s, z10.b, z20.b  // 10000000-00100100-10000001-01010001
+// CHECK-INST: sumop4s za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x51,0x81,0x24,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80248151 <unknown>
+
+sumop4s za3.s, z14.b, z30.b  // 10000000-00101110-10000001-11010011
+// CHECK-INST: sumop4s za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xd3,0x81,0x2e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 802e81d3 <unknown>
+
+sumop4s za0.s, z0.b, {z16.b-z17.b}  // 10000000-00110000-10000000-00010000
+// CHECK-INST: sumop4s za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x80,0x30,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80308010 <unknown>
+
+sumop4s za1.s, z10.b, {z20.b-z21.b}  // 10000000-00110100-10000001-01010001
+// CHECK-INST: sumop4s za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x81,0x34,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80348151 <unknown>
+
+sumop4s za3.s, z14.b, {z30.b-z31.b}  // 10000000-00111110-10000001-11010011
+// CHECK-INST: sumop4s za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x81,0x3e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 803e81d3 <unknown>
+
+sumop4s za0.s, {z0.b-z1.b}, z16.b  // 10000000-00100000-10000010-00010000
+// CHECK-INST: sumop4s za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x10,0x82,0x20,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80208210 <unknown>
+
+sumop4s za1.s, {z10.b-z11.b}, z20.b  // 10000000-00100100-10000011-01010001
+// CHECK-INST: sumop4s za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x51,0x83,0x24,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80248351 <unknown>
+
+sumop4s za3.s, {z14.b-z15.b}, z30.b  // 10000000-00101110-10000011-11010011
+// CHECK-INST: sumop4s za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xd3,0x83,0x2e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 802e83d3 <unknown>
+
+sumop4s za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000000-00110000-10000010-00010000
+// CHECK-INST: sumop4s za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x82,0x30,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80308210 <unknown>
+
+sumop4s za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000000-00110100-10000011-01010001
+// CHECK-INST: sumop4s za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x83,0x34,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80348351 <unknown>
+
+sumop4s za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000000-00111110-10000011-11010011
+// CHECK-INST: sumop4s za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x83,0x3e,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 803e83d3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4s-64.s b/llvm/test/MC/AArch64/SME2p2/sumop4s-64.s
new file mode 100644
index 00000000000000..4eb0140ad6a76b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4s-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sumop4s za0.d, z0.h, z16.h  // 10100000-11100000-00000000-00011000
+// CHECK-INST: sumop4s za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x00,0xe0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e00018 <unknown>
+
+sumop4s za5.d, z10.h, z20.h  // 10100000-11100100-00000001-01011101
+// CHECK-INST: sumop4s za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x5d,0x01,0xe4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e4015d <unknown>
+
+sumop4s za7.d, z14.h, z30.h  // 10100000-11101110-00000001-11011111
+// CHECK-INST: sumop4s za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xdf,0x01,0xee,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ee01df <unknown>
+
+sumop4s za0.d, z0.h, {z16.h-z17.h}  // 10100000-11110000-00000000-00011000
+// CHECK-INST: sumop4s za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x00,0xf0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f00018 <unknown>
+
+sumop4s za5.d, z10.h, {z20.h-z21.h}  // 10100000-11110100-00000001-01011101
+// CHECK-INST: sumop4s za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x01,0xf4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f4015d <unknown>
+
+sumop4s za7.d, z14.h, {z30.h-z31.h}  // 10100000-11111110-00000001-11011111
+// CHECK-INST: sumop4s za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x01,0xfe,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0fe01df <unknown>
+
+sumop4s za0.d, {z0.h-z1.h}, z16.h  // 10100000-11100000-00000010-00011000
+// CHECK-INST: sumop4s za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x02,0xe0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e00218 <unknown>
+
+sumop4s za5.d, {z10.h-z11.h}, z20.h  // 10100000-11100100-00000011-01011101
+// CHECK-INST: sumop4s za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x5d,0x03,0xe4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0e4035d <unknown>
+
+sumop4s za7.d, {z14.h-z15.h}, z30.h  // 10100000-11101110-00000011-11011111
+// CHECK-INST: sumop4s za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdf,0x03,0xee,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0ee03df <unknown>
+
+sumop4s za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100000-11110000-00000010-00011000
+// CHECK-INST: sumop4s za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x02,0xf0,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f00218 <unknown>
+
+sumop4s za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100000-11110100-00000011-01011101
+// CHECK-INST: sumop4s za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x03,0xf4,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0f4035d <unknown>
+
+sumop4s za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100000-11111110-00000011-11011111
+// CHECK-INST: sumop4s za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x03,0xfe,0xa0]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a0fe03df <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sumop4s-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/sumop4s-diagnostics.s
new file mode 100644
index 00000000000000..39a397d7b56718
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sumop4s-diagnostics.s
@@ -0,0 +1,68 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+sumop4s za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sumop4s za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sumop4s za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+sumop4s za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: sumop4s za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za0.d, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: sumop4s za0.d, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+sumop4s za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: sumop4s za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za0.d, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: sumop4s za0.d, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, .d => .h
+
+sumop4s za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: sumop4s za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: sumop4s za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: sumop4s za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sumop4s za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: sumop4s za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4a-16to32.s b/llvm/test/MC/AArch64/SME2p2/umop4a-16to32.s
new file mode 100644
index 00000000000000..15490565f8ecfe
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4a-16to32.s
@@ -0,0 +1,86 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+
+umop4a  za0.s, z0.h, z16.h  // 10000001-00000000-10000000-00001000
+// CHECK-INST: umop4a  za0.s, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x80,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008008 <unknown>
+
+umop4a  za3.s, z12.h, z24.h  // 10000001-00001000-10000001-10001011
+// CHECK-INST: umop4a  za3.s, z12.h, z24.h
+// CHECK-ENCODING: [0x8b,0x81,0x08,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8108818b <unknown>
+
+umop4a  za3.s, z14.h, z30.h  // 10000001-00001110-10000001-11001011
+// CHECK-INST: umop4a  za3.s, z14.h, z30.h
+// CHECK-ENCODING: [0xcb,0x81,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e81cb <unknown>
+
+umop4a  za0.s, z0.h, {z16.h-z17.h}  // 10000001-00010000-10000000-00001000
+// CHECK-INST: umop4a  za0.s, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x80,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108008 <unknown>
+
+umop4a  za3.s, z12.h, {z24.h-z25.h}  // 10000001-00011000-10000001-10001011
+// CHECK-INST: umop4a  za3.s, z12.h, { z24.h, z25.h }
+// CHECK-ENCODING: [0x8b,0x81,0x18,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8118818b <unknown>
+
+umop4a  za3.s, z14.h, {z30.h-z31.h}  // 10000001-00011110-10000001-11001011
+// CHECK-INST: umop4a  za3.s, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcb,0x81,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e81cb <unknown>
+
+umop4a  za0.s, {z0.h-z1.h}, z16.h  // 10000001-00000000-10000010-00001000
+// CHECK-INST: umop4a  za0.s, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x82,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008208 <unknown>
+
+umop4a  za3.s, {z12.h-z13.h}, z24.h  // 10000001-00001000-10000011-10001011
+// CHECK-INST: umop4a  za3.s, { z12.h, z13.h }, z24.h
+// CHECK-ENCODING: [0x8b,0x83,0x08,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8108838b <unknown>
+
+umop4a  za3.s, {z14.h-z15.h}, z30.h  // 10000001-00001110-10000011-11001011
+// CHECK-INST: umop4a  za3.s, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcb,0x83,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e83cb <unknown>
+
+umop4a  za0.s, {z0.h-z1.h}, {z16.h-z17.h}  // 10000001-00010000-10000010-00001000
+// CHECK-INST: umop4a  za0.s, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x82,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108208 <unknown>
+
+umop4a  za3.s, {z12.h-z13.h}, {z24.h-z25.h}  // 10000001-00011000-10000011-10001011
+// CHECK-INST: umop4a  za3.s, { z12.h, z13.h }, { z24.h, z25.h }
+// CHECK-ENCODING: [0x8b,0x83,0x18,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8118838b <unknown>
+
+umop4a  za3.s, {z14.h-z15.h}, {z30.h-z31.h}  // 10000001-00011110-10000011-11001011
+// CHECK-INST: umop4a  za3.s, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcb,0x83,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e83cb <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4a-64.s b/llvm/test/MC/AArch64/SME2p2/umop4a-64.s
new file mode 100644
index 00000000000000..fb4f32a34ef973
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4a-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+umop4a  za0.d, z0.h, z16.h  // 10100001-11100000-00000000-00001000
+// CHECK-INST: umop4a  za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x00,0xe0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e00008 <unknown>
+
+umop4a  za5.d, z10.h, z20.h  // 10100001-11100100-00000001-01001101
+// CHECK-INST: umop4a  za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x4d,0x01,0xe4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e4014d <unknown>
+
+umop4a  za7.d, z14.h, z30.h  // 10100001-11101110-00000001-11001111
+// CHECK-INST: umop4a  za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xcf,0x01,0xee,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ee01cf <unknown>
+
+umop4a  za0.d, z0.h, {z16.h-z17.h}  // 10100001-11110000-00000000-00001000
+// CHECK-INST: umop4a  za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x00,0xf0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f00008 <unknown>
+
+umop4a  za5.d, z10.h, {z20.h-z21.h}  // 10100001-11110100-00000001-01001101
+// CHECK-INST: umop4a  za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x01,0xf4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f4014d <unknown>
+
+umop4a  za7.d, z14.h, {z30.h-z31.h}  // 10100001-11111110-00000001-11001111
+// CHECK-INST: umop4a  za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x01,0xfe,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1fe01cf <unknown>
+
+umop4a  za0.d, {z0.h-z1.h}, z16.h  // 10100001-11100000-00000010-00001000
+// CHECK-INST: umop4a  za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x02,0xe0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e00208 <unknown>
+
+umop4a  za5.d, {z10.h-z11.h}, z20.h  // 10100001-11100100-00000011-01001101
+// CHECK-INST: umop4a  za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x4d,0x03,0xe4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e4034d <unknown>
+
+umop4a  za7.d, {z14.h-z15.h}, z30.h  // 10100001-11101110-00000011-11001111
+// CHECK-INST: umop4a  za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcf,0x03,0xee,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ee03cf <unknown>
+
+umop4a  za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100001-11110000-00000010-00001000
+// CHECK-INST: umop4a  za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x02,0xf0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f00208 <unknown>
+
+umop4a  za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100001-11110100-00000011-01001101
+// CHECK-INST: umop4a  za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x03,0xf4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f4034d <unknown>
+
+umop4a  za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100001-11111110-00000011-11001111
+// CHECK-INST: umop4a  za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x03,0xfe,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1fe03cf <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4a-8to32.s b/llvm/test/MC/AArch64/SME2p2/umop4a-8to32.s
new file mode 100644
index 00000000000000..d22d2249709be8
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4a-8to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+umop4a  za0.s, z0.b, z16.b  // 10000001-00100000-10000000-00000000
+// CHECK-INST: umop4a  za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x00,0x80,0x20,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81208000 <unknown>
+
+umop4a  za1.s, z10.b, z20.b  // 10000001-00100100-10000001-01000001
+// CHECK-INST: umop4a  za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x41,0x81,0x24,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81248141 <unknown>
+
+umop4a  za3.s, z14.b, z30.b  // 10000001-00101110-10000001-11000011
+// CHECK-INST: umop4a  za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xc3,0x81,0x2e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 812e81c3 <unknown>
+
+umop4a  za0.s, z0.b, {z16.b-z17.b}  // 10000001-00110000-10000000-00000000
+// CHECK-INST: umop4a  za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x80,0x30,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81308000 <unknown>
+
+umop4a  za1.s, z10.b, {z20.b-z21.b}  // 10000001-00110100-10000001-01000001
+// CHECK-INST: umop4a  za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x81,0x34,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81348141 <unknown>
+
+umop4a  za3.s, z14.b, {z30.b-z31.b}  // 10000001-00111110-10000001-11000011
+// CHECK-INST: umop4a  za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x81,0x3e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 813e81c3 <unknown>
+
+umop4a  za0.s, {z0.b-z1.b}, z16.b  // 10000001-00100000-10000010-00000000
+// CHECK-INST: umop4a  za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x00,0x82,0x20,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81208200 <unknown>
+
+umop4a  za1.s, {z10.b-z11.b}, z20.b  // 10000001-00100100-10000011-01000001
+// CHECK-INST: umop4a  za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x41,0x83,0x24,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81248341 <unknown>
+
+umop4a  za3.s, {z14.b-z15.b}, z30.b  // 10000001-00101110-10000011-11000011
+// CHECK-INST: umop4a  za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xc3,0x83,0x2e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 812e83c3 <unknown>
+
+umop4a  za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000001-00110000-10000010-00000000
+// CHECK-INST: umop4a  za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x82,0x30,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81308200 <unknown>
+
+umop4a  za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000001-00110100-10000011-01000001
+// CHECK-INST: umop4a  za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x83,0x34,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81348341 <unknown>
+
+umop4a  za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000001-00111110-10000011-11000011
+// CHECK-INST: umop4a  za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x83,0x3e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 813e83c3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4a-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/umop4a-diagnostics.s
new file mode 100644
index 00000000000000..a522ab1baacda5
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4a-diagnostics.s
@@ -0,0 +1,82 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+umop4a za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4a za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za4.s, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4a za4.s, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4a za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+umop4a za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: umop4a za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za0.s, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: umop4a za0.s, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za0.s, z16.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: umop4a za0.s, z16.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+umop4a za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4a za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za0.s, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: umop4a za0.s, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za0.s, z14.b, z14.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: umop4a za0.s, z14.b, z14.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, s => .h, .d => .h
+
+umop4a za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4a za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: umop4a za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4a za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4a za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: umop4a za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4s-16to32.s b/llvm/test/MC/AArch64/SME2p2/umop4s-16to32.s
new file mode 100644
index 00000000000000..c83925737005e0
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4s-16to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+umop4s  za0.s, z0.h, z16.h  // 10000001-00000000-10000000-00011000
+// CHECK-INST: umop4s  za0.s, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x80,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008018 <unknown>
+
+umop4s  za3.s, z12.h, z24.h  // 10000001-00001000-10000001-10011011
+// CHECK-INST: umop4s  za3.s, z12.h, z24.h
+// CHECK-ENCODING: [0x9b,0x81,0x08,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8108819b <unknown>
+
+umop4s  za3.s, z14.h, z30.h  // 10000001-00001110-10000001-11011011
+// CHECK-INST: umop4s  za3.s, z14.h, z30.h
+// CHECK-ENCODING: [0xdb,0x81,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e81db <unknown>
+
+umop4s  za0.s, z0.h, {z16.h-z17.h}  // 10000001-00010000-10000000-00011000
+// CHECK-INST: umop4s  za0.s, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x80,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108018 <unknown>
+
+umop4s  za3.s, z12.h, {z24.h-z25.h}  // 10000001-00011000-10000001-10011011
+// CHECK-INST: umop4s  za3.s, z12.h, { z24.h, z25.h }
+// CHECK-ENCODING: [0x9b,0x81,0x18,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8118819b <unknown>
+
+umop4s  za3.s, z14.h, {z30.h-z31.h}  // 10000001-00011110-10000001-11011011
+// CHECK-INST: umop4s  za3.s, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdb,0x81,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e81db <unknown>
+
+umop4s  za0.s, {z0.h-z1.h}, z16.h  // 10000001-00000000-10000010-00011000
+// CHECK-INST: umop4s  za0.s, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x82,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008218 <unknown>
+
+umop4s  za3.s, {z12.h-z13.h}, z24.h  // 10000001-00001000-10000011-10011011
+// CHECK-INST: umop4s  za3.s, { z12.h, z13.h }, z24.h
+// CHECK-ENCODING: [0x9b,0x83,0x08,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8108839b <unknown>
+
+umop4s  za3.s, {z14.h-z15.h}, z30.h  // 10000001-00001110-10000011-11011011
+// CHECK-INST: umop4s  za3.s, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdb,0x83,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e83db <unknown>
+
+umop4s  za0.s, {z0.h-z1.h}, {z16.h-z17.h}  // 10000001-00010000-10000010-00011000
+// CHECK-INST: umop4s  za0.s, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x82,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108218 <unknown>
+
+umop4s  za3.s, {z12.h-z13.h}, {z24.h-z25.h}  // 10000001-00011000-10000011-10011011
+// CHECK-INST: umop4s  za3.s, { z12.h, z13.h }, { z24.h, z25.h }
+// CHECK-ENCODING: [0x9b,0x83,0x18,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 8118839b <unknown>
+
+umop4s  za3.s, {z14.h-z15.h}, {z30.h-z31.h}  // 10000001-00011110-10000011-11011011
+// CHECK-INST: umop4s  za3.s, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdb,0x83,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e83db <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4s-64.s b/llvm/test/MC/AArch64/SME2p2/umop4s-64.s
new file mode 100644
index 00000000000000..b18ad15f105950
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4s-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+umop4s  za0.d, z0.h, z16.h  // 10100001-11100000-00000000-00011000
+// CHECK-INST: umop4s  za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x00,0xe0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e00018 <unknown>
+
+umop4s  za5.d, z10.h, z20.h  // 10100001-11100100-00000001-01011101
+// CHECK-INST: umop4s  za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x5d,0x01,0xe4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e4015d <unknown>
+
+umop4s  za7.d, z14.h, z30.h  // 10100001-11101110-00000001-11011111
+// CHECK-INST: umop4s  za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xdf,0x01,0xee,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ee01df <unknown>
+
+umop4s  za0.d, z0.h, {z16.h-z17.h}  // 10100001-11110000-00000000-00011000
+// CHECK-INST: umop4s  za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x00,0xf0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f00018 <unknown>
+
+umop4s  za5.d, z10.h, {z20.h-z21.h}  // 10100001-11110100-00000001-01011101
+// CHECK-INST: umop4s  za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x01,0xf4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f4015d <unknown>
+
+umop4s  za7.d, z14.h, {z30.h-z31.h}  // 10100001-11111110-00000001-11011111
+// CHECK-INST: umop4s  za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x01,0xfe,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1fe01df <unknown>
+
+umop4s  za0.d, {z0.h-z1.h}, z16.h  // 10100001-11100000-00000010-00011000
+// CHECK-INST: umop4s  za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x02,0xe0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e00218 <unknown>
+
+umop4s  za5.d, {z10.h-z11.h}, z20.h  // 10100001-11100100-00000011-01011101
+// CHECK-INST: umop4s  za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x5d,0x03,0xe4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1e4035d <unknown>
+
+umop4s  za7.d, {z14.h-z15.h}, z30.h  // 10100001-11101110-00000011-11011111
+// CHECK-INST: umop4s  za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdf,0x03,0xee,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ee03df <unknown>
+
+umop4s  za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100001-11110000-00000010-00011000
+// CHECK-INST: umop4s  za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x02,0xf0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f00218 <unknown>
+
+umop4s  za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100001-11110100-00000011-01011101
+// CHECK-INST: umop4s  za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x03,0xf4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1f4035d <unknown>
+
+umop4s  za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100001-11111110-00000011-11011111
+// CHECK-INST: umop4s  za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x03,0xfe,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1fe03df <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4s-8to32.s b/llvm/test/MC/AArch64/SME2p2/umop4s-8to32.s
new file mode 100644
index 00000000000000..74cbffc5ef01dc
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4s-8to32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+umop4s  za0.s, z0.b, z16.b  // 10000001-00100000-10000000-00010000
+// CHECK-INST: umop4s  za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x10,0x80,0x20,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81208010 <unknown>
+
+umop4s  za1.s, z10.b, z20.b  // 10000001-00100100-10000001-01010001
+// CHECK-INST: umop4s  za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x51,0x81,0x24,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81248151 <unknown>
+
+umop4s  za3.s, z14.b, z30.b  // 10000001-00101110-10000001-11010011
+// CHECK-INST: umop4s  za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xd3,0x81,0x2e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 812e81d3 <unknown>
+
+umop4s  za0.s, z0.b, {z16.b-z17.b}  // 10000001-00110000-10000000-00010000
+// CHECK-INST: umop4s  za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x80,0x30,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81308010 <unknown>
+
+umop4s  za1.s, z10.b, {z20.b-z21.b}  // 10000001-00110100-10000001-01010001
+// CHECK-INST: umop4s  za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x81,0x34,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81348151 <unknown>
+
+umop4s  za3.s, z14.b, {z30.b-z31.b}  // 10000001-00111110-10000001-11010011
+// CHECK-INST: umop4s  za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x81,0x3e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 813e81d3 <unknown>
+
+umop4s  za0.s, {z0.b-z1.b}, z16.b  // 10000001-00100000-10000010-00010000
+// CHECK-INST: umop4s  za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x10,0x82,0x20,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81208210 <unknown>
+
+umop4s  za1.s, {z10.b-z11.b}, z20.b  // 10000001-00100100-10000011-01010001
+// CHECK-INST: umop4s  za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x51,0x83,0x24,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81248351 <unknown>
+
+umop4s  za3.s, {z14.b-z15.b}, z30.b  // 10000001-00101110-10000011-11010011
+// CHECK-INST: umop4s  za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xd3,0x83,0x2e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 812e83d3 <unknown>
+
+umop4s  za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000001-00110000-10000010-00010000
+// CHECK-INST: umop4s  za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x82,0x30,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81308210 <unknown>
+
+umop4s  za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000001-00110100-10000011-01010001
+// CHECK-INST: umop4s  za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x83,0x34,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81348351 <unknown>
+
+umop4s  za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000001-00111110-10000011-11010011
+// CHECK-INST: umop4s  za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x83,0x3e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 813e83d3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/umop4s-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/umop4s-diagnostics.s
new file mode 100644
index 00000000000000..c5f9877522e3d4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/umop4s-diagnostics.s
@@ -0,0 +1,82 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+umop4s za4.s, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4s za4.s, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4s za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: umop4s za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+umop4s za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: umop4s za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za0.s, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: umop4s za0.s, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za0.s, z16.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: umop4s za0.s, z16.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+umop4s za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4s za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za0.s, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: umop4s za0.s, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za0.s, z14.b, z14.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: umop4s za0.s, z14.b, z14.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, s => .h, .d => .h
+
+umop4s za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4s za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: umop4s za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: umop4s za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+umop4s za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: umop4s za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4a-32.s b/llvm/test/MC/AArch64/SME2p2/usmop4a-32.s
new file mode 100644
index 00000000000000..2bbddfd1e64e09
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4a-32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+usmop4a za0.s, z0.b, z16.b  // 10000001-00000000-10000000-00000000
+// CHECK-INST: usmop4a za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x00,0x80,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008000 <unknown>
+
+usmop4a za1.s, z10.b, z20.b  // 10000001-00000100-10000001-01000001
+// CHECK-INST: usmop4a za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x41,0x81,0x04,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81048141 <unknown>
+
+usmop4a za3.s, z14.b, z30.b  // 10000001-00001110-10000001-11000011
+// CHECK-INST: usmop4a za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xc3,0x81,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e81c3 <unknown>
+
+usmop4a za0.s, z0.b, {z16.b-z17.b}  // 10000001-00010000-10000000-00000000
+// CHECK-INST: usmop4a za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x80,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108000 <unknown>
+
+usmop4a za1.s, z10.b, {z20.b-z21.b}  // 10000001-00010100-10000001-01000001
+// CHECK-INST: usmop4a za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x81,0x14,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81148141 <unknown>
+
+usmop4a za3.s, z14.b, {z30.b-z31.b}  // 10000001-00011110-10000001-11000011
+// CHECK-INST: usmop4a za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x81,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e81c3 <unknown>
+
+usmop4a za0.s, {z0.b-z1.b}, z16.b  // 10000001-00000000-10000010-00000000
+// CHECK-INST: usmop4a za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x00,0x82,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008200 <unknown>
+
+usmop4a za1.s, {z10.b-z11.b}, z20.b  // 10000001-00000100-10000011-01000001
+// CHECK-INST: usmop4a za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x41,0x83,0x04,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81048341 <unknown>
+
+usmop4a za3.s, {z14.b-z15.b}, z30.b  // 10000001-00001110-10000011-11000011
+// CHECK-INST: usmop4a za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xc3,0x83,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e83c3 <unknown>
+
+usmop4a za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000001-00010000-10000010-00000000
+// CHECK-INST: usmop4a za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x00,0x82,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108200 <unknown>
+
+usmop4a za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000001-00010100-10000011-01000001
+// CHECK-INST: usmop4a za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x41,0x83,0x14,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81148341 <unknown>
+
+usmop4a za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000001-00011110-10000011-11000011
+// CHECK-INST: usmop4a za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xc3,0x83,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e83c3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4a-64.s b/llvm/test/MC/AArch64/SME2p2/usmop4a-64.s
new file mode 100644
index 00000000000000..b94d0aa74cec47
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4a-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+usmop4a za0.d, z0.h, z16.h  // 10100001-11000000-00000000-00001000
+// CHECK-INST: usmop4a za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x08,0x00,0xc0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c00008 <unknown>
+
+usmop4a za5.d, z10.h, z20.h  // 10100001-11000100-00000001-01001101
+// CHECK-INST: usmop4a za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x4d,0x01,0xc4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c4014d <unknown>
+
+usmop4a za7.d, z14.h, z30.h  // 10100001-11001110-00000001-11001111
+// CHECK-INST: usmop4a za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xcf,0x01,0xce,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ce01cf <unknown>
+
+usmop4a za0.d, z0.h, {z16.h-z17.h}  // 10100001-11010000-00000000-00001000
+// CHECK-INST: usmop4a za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x00,0xd0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d00008 <unknown>
+
+usmop4a za5.d, z10.h, {z20.h-z21.h}  // 10100001-11010100-00000001-01001101
+// CHECK-INST: usmop4a za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x01,0xd4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d4014d <unknown>
+
+usmop4a za7.d, z14.h, {z30.h-z31.h}  // 10100001-11011110-00000001-11001111
+// CHECK-INST: usmop4a za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x01,0xde,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1de01cf <unknown>
+
+usmop4a za0.d, {z0.h-z1.h}, z16.h  // 10100001-11000000-00000010-00001000
+// CHECK-INST: usmop4a za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x08,0x02,0xc0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c00208 <unknown>
+
+usmop4a za5.d, {z10.h-z11.h}, z20.h  // 10100001-11000100-00000011-01001101
+// CHECK-INST: usmop4a za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x4d,0x03,0xc4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c4034d <unknown>
+
+usmop4a za7.d, {z14.h-z15.h}, z30.h  // 10100001-11001110-00000011-11001111
+// CHECK-INST: usmop4a za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xcf,0x03,0xce,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ce03cf <unknown>
+
+usmop4a za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100001-11010000-00000010-00001000
+// CHECK-INST: usmop4a za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x08,0x02,0xd0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d00208 <unknown>
+
+usmop4a za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100001-11010100-00000011-01001101
+// CHECK-INST: usmop4a za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x4d,0x03,0xd4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d4034d <unknown>
+
+usmop4a za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100001-11011110-00000011-11001111
+// CHECK-INST: usmop4a za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xcf,0x03,0xde,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1de03cf <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4a-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/usmop4a-diagnostics.s
new file mode 100644
index 00000000000000..18d9963a3274fa
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4a-diagnostics.s
@@ -0,0 +1,68 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+usmop4a za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: usmop4a za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: usmop4a za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+usmop4a za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: usmop4a za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za0.d, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: usmop4a za0.d, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+usmop4a za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: usmop4a za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za0.d, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: usmop4a za0.d, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, .d => .h
+
+usmop4a za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: usmop4a za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: usmop4a za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: usmop4a za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4a za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: usmop4a za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4s-32.s b/llvm/test/MC/AArch64/SME2p2/usmop4s-32.s
new file mode 100644
index 00000000000000..e8cc918e55d029
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4s-32.s
@@ -0,0 +1,85 @@
+// 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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+usmop4s za0.s, z0.b, z16.b  // 10000001-00000000-10000000-00010000
+// CHECK-INST: usmop4s za0.s, z0.b, z16.b
+// CHECK-ENCODING: [0x10,0x80,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008010 <unknown>
+
+usmop4s za1.s, z10.b, z20.b  // 10000001-00000100-10000001-01010001
+// CHECK-INST: usmop4s za1.s, z10.b, z20.b
+// CHECK-ENCODING: [0x51,0x81,0x04,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81048151 <unknown>
+
+usmop4s za3.s, z14.b, z30.b  // 10000001-00001110-10000001-11010011
+// CHECK-INST: usmop4s za3.s, z14.b, z30.b
+// CHECK-ENCODING: [0xd3,0x81,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e81d3 <unknown>
+
+usmop4s za0.s, z0.b, {z16.b-z17.b}  // 10000001-00010000-10000000-00010000
+// CHECK-INST: usmop4s za0.s, z0.b, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x80,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108010 <unknown>
+
+usmop4s za1.s, z10.b, {z20.b-z21.b}  // 10000001-00010100-10000001-01010001
+// CHECK-INST: usmop4s za1.s, z10.b, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x81,0x14,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81148151 <unknown>
+
+usmop4s za3.s, z14.b, {z30.b-z31.b}  // 10000001-00011110-10000001-11010011
+// CHECK-INST: usmop4s za3.s, z14.b, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x81,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e81d3 <unknown>
+
+usmop4s za0.s, {z0.b-z1.b}, z16.b  // 10000001-00000000-10000010-00010000
+// CHECK-INST: usmop4s za0.s, { z0.b, z1.b }, z16.b
+// CHECK-ENCODING: [0x10,0x82,0x00,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81008210 <unknown>
+
+usmop4s za1.s, {z10.b-z11.b}, z20.b  // 10000001-00000100-10000011-01010001
+// CHECK-INST: usmop4s za1.s, { z10.b, z11.b }, z20.b
+// CHECK-ENCODING: [0x51,0x83,0x04,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81048351 <unknown>
+
+usmop4s za3.s, {z14.b-z15.b}, z30.b  // 10000001-00001110-10000011-11010011
+// CHECK-INST: usmop4s za3.s, { z14.b, z15.b }, z30.b
+// CHECK-ENCODING: [0xd3,0x83,0x0e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 810e83d3 <unknown>
+
+usmop4s za0.s, {z0.b-z1.b}, {z16.b-z17.b}  // 10000001-00010000-10000010-00010000
+// CHECK-INST: usmop4s za0.s, { z0.b, z1.b }, { z16.b, z17.b }
+// CHECK-ENCODING: [0x10,0x82,0x10,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81108210 <unknown>
+
+usmop4s za1.s, {z10.b-z11.b}, {z20.b-z21.b}  // 10000001-00010100-10000011-01010001
+// CHECK-INST: usmop4s za1.s, { z10.b, z11.b }, { z20.b, z21.b }
+// CHECK-ENCODING: [0x51,0x83,0x14,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 81148351 <unknown>
+
+usmop4s za3.s, {z14.b-z15.b}, {z30.b-z31.b}  // 10000001-00011110-10000011-11010011
+// CHECK-INST: usmop4s za3.s, { z14.b, z15.b }, { z30.b, z31.b }
+// CHECK-ENCODING: [0xd3,0x83,0x1e,0x81]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 811e83d3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4s-64.s b/llvm/test/MC/AArch64/SME2p2/usmop4s-64.s
new file mode 100644
index 00000000000000..73d59c77370cec
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4s-64.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2,+sme-i16i64 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-i16i64 < %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=+sme2p2,+sme-i16i64 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-i16i64 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+usmop4s za0.d, z0.h, z16.h  // 10100001-11000000-00000000-00011000
+// CHECK-INST: usmop4s za0.d, z0.h, z16.h
+// CHECK-ENCODING: [0x18,0x00,0xc0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c00018 <unknown>
+
+usmop4s za5.d, z10.h, z20.h  // 10100001-11000100-00000001-01011101
+// CHECK-INST: usmop4s za5.d, z10.h, z20.h
+// CHECK-ENCODING: [0x5d,0x01,0xc4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c4015d <unknown>
+
+usmop4s za7.d, z14.h, z30.h  // 10100001-11001110-00000001-11011111
+// CHECK-INST: usmop4s za7.d, z14.h, z30.h
+// CHECK-ENCODING: [0xdf,0x01,0xce,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ce01df <unknown>
+
+usmop4s za0.d, z0.h, {z16.h-z17.h}  // 10100001-11010000-00000000-00011000
+// CHECK-INST: usmop4s za0.d, z0.h, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x00,0xd0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d00018 <unknown>
+
+usmop4s za5.d, z10.h, {z20.h-z21.h}  // 10100001-11010100-00000001-01011101
+// CHECK-INST: usmop4s za5.d, z10.h, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x01,0xd4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d4015d <unknown>
+
+usmop4s za7.d, z14.h, {z30.h-z31.h}  // 10100001-11011110-00000001-11011111
+// CHECK-INST: usmop4s za7.d, z14.h, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x01,0xde,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1de01df <unknown>
+
+usmop4s za0.d, {z0.h-z1.h}, z16.h  // 10100001-11000000-00000010-00011000
+// CHECK-INST: usmop4s za0.d, { z0.h, z1.h }, z16.h
+// CHECK-ENCODING: [0x18,0x02,0xc0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c00218 <unknown>
+
+usmop4s za5.d, {z10.h-z11.h}, z20.h  // 10100001-11000100-00000011-01011101
+// CHECK-INST: usmop4s za5.d, { z10.h, z11.h }, z20.h
+// CHECK-ENCODING: [0x5d,0x03,0xc4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1c4035d <unknown>
+
+usmop4s za7.d, {z14.h-z15.h}, z30.h  // 10100001-11001110-00000011-11011111
+// CHECK-INST: usmop4s za7.d, { z14.h, z15.h }, z30.h
+// CHECK-ENCODING: [0xdf,0x03,0xce,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1ce03df <unknown>
+
+usmop4s za0.d, {z0.h-z1.h}, {z16.h-z17.h}  // 10100001-11010000-00000010-00011000
+// CHECK-INST: usmop4s za0.d, { z0.h, z1.h }, { z16.h, z17.h }
+// CHECK-ENCODING: [0x18,0x02,0xd0,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d00218 <unknown>
+
+usmop4s za5.d, {z10.h-z11.h}, {z20.h-z21.h}  // 10100001-11010100-00000011-01011101
+// CHECK-INST: usmop4s za5.d, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x5d,0x03,0xd4,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1d4035d <unknown>
+
+usmop4s za7.d, {z14.h-z15.h}, {z30.h-z31.h}  // 10100001-11011110-00000011-11011111
+// CHECK-INST: usmop4s za7.d, { z14.h, z15.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xdf,0x03,0xde,0xa1]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: a1de03df <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/usmop4s-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/usmop4s-diagnostics.s
new file mode 100644
index 00000000000000..07353b63501498
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/usmop4s-diagnostics.s
@@ -0,0 +1,68 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-i16i64 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid tile
+//
+// expected: .s => za0-za3, .d => za0-za7
+
+usmop4s za4.s, z0.b, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: usmop4s za4.s, z0.b, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za8.d, z0.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: usmop4s za8.d, z0.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid first operand (expected z0..z15)
+
+usmop4s za0.d, z16.h, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: usmop4s za0.d, z16.h, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za0.d, {z16.h-z17.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z0-z14, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: usmop4s za0.d, {z16.h-z17.h}, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid second operand (expected z16..z31)
+
+usmop4s za0.d, z14.h, z14.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: usmop4s za0.d, z14.h, z14.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za0.d, z14.h, {z14.h-z15.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors in the range z16-z30, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: usmop4s za0.d, z14.h, {z14.h-z15.h}
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR type suffix
+//
+// expected: .s => .b, .d => .h
+
+usmop4s za3.s, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.b..z14.b
+// CHECK-NEXT: usmop4s za3.s, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za3.s, z0.b, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.b..z30.b
+// CHECK-NEXT: usmop4s za3.s, z0.b, z16.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za3.d, z0.h, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z16.h..z30.h
+// CHECK-NEXT: usmop4s za3.d, z0.h, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+usmop4s za3.d, z0.s, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected even register in z0.h..z14.h
+// CHECK-NEXT: usmop4s za3.d, z0.s, z16.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:



More information about the llvm-commits mailing list