[llvm] 78f11a3 - [AArch64][SVE2] Add the SVE2.1 quadword structured load/store instructions

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 9 01:20:19 PST 2022


Author: David Sherwood
Date: 2022-11-09T08:59:42Z
New Revision: 78f11a392301dcece0323626e6ded34a8cf0f029

URL: https://github.com/llvm/llvm-project/commit/78f11a392301dcece0323626e6ded34a8cf0f029
DIFF: https://github.com/llvm/llvm-project/commit/78f11a392301dcece0323626e6ded34a8cf0f029.diff

LOG: [AArch64][SVE2] Add the SVE2.1 quadword structured load/store instructions

This patch adds the assembly/disassembly for the following instructions:

ld2q : Contiguous load two-quadword structures to two vectors
ld3q : Contiguous load three-quadword structures to three vectors
ld4q : Contiguous load four-quadword structures to four vectors
st2q : Contiguous store two-quadword structures from two vectors
st3q : Contiguous store three-quadword structures to three vectors
st4q : Contiguous store four-quadword structures to four vectors

The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09

Differential Revision: https://reviews.llvm.org/D137554

Added: 
    llvm/test/MC/AArch64/SVE2p1/ld2q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/ld2q.s
    llvm/test/MC/AArch64/SVE2p1/ld3q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/ld3q.s
    llvm/test/MC/AArch64/SVE2p1/ld4q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/ld4q.s
    llvm/test/MC/AArch64/SVE2p1/st2q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/st2q.s
    llvm/test/MC/AArch64/SVE2p1/st3q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/st3q.s
    llvm/test/MC/AArch64/SVE2p1/st4q-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/st4q.s

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 2fae92ef93ea0..d8a320793ead4 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -1167,6 +1167,10 @@ def ZZ_d  : RegisterOperand<ZPR2, "printTypedVectorList<0,'d'>"> {
   let ParserMatchClass = ZPRVectorList<64, 2>;
 }
 
+def ZZ_q  : RegisterOperand<ZPR2, "printTypedVectorList<0,'q'>"> {
+  let ParserMatchClass = ZPRVectorList<128, 2>;
+}
+
 def ZZZ_b  : RegisterOperand<ZPR3, "printTypedVectorList<0,'b'>"> {
   let ParserMatchClass = ZPRVectorList<8, 3>;
 }
@@ -1183,6 +1187,10 @@ def ZZZ_d  : RegisterOperand<ZPR3, "printTypedVectorList<0,'d'>"> {
   let ParserMatchClass = ZPRVectorList<64, 3>;
 }
 
+def ZZZ_q  : RegisterOperand<ZPR3, "printTypedVectorList<0,'q'>"> {
+  let ParserMatchClass = ZPRVectorList<128, 3>;
+}
+
 def ZZZZ_b : RegisterOperand<ZPR4, "printTypedVectorList<0,'b'>"> {
   let ParserMatchClass = ZPRVectorList<8, 4>;
 }
@@ -1199,6 +1207,10 @@ def ZZZZ_d : RegisterOperand<ZPR4, "printTypedVectorList<0,'d'>"> {
   let ParserMatchClass = ZPRVectorList<64, 4>;
 }
 
+def ZZZZ_q : RegisterOperand<ZPR4, "printTypedVectorList<0,'q'>"> {
+  let ParserMatchClass = ZPRVectorList<128, 4>;
+}
+
 // SME2 multiple-of-2 or 4 multi-vector operands
 def ZPR2Mul2 : RegisterClass<"AArch64", [untyped], 128, (add (decimate ZSeqPairs, 2))> {
   let Size = 256;

diff  --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 310740ce3c109..8779ec5493c2f 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -1023,32 +1023,42 @@ let Predicates = [HasSVE] in {
 
 let Predicates = [HasSVEorSME] in {
   // LD(2|3|4) structured loads with reg+immediate
-  defm LD2B_IMM : sve_mem_eld_si<0b00, 0b01, ZZ_b,   "ld2b", simm4s2>;
-  defm LD3B_IMM : sve_mem_eld_si<0b00, 0b10, ZZZ_b,  "ld3b", simm4s3>;
-  defm LD4B_IMM : sve_mem_eld_si<0b00, 0b11, ZZZZ_b, "ld4b", simm4s4>;
-  defm LD2H_IMM : sve_mem_eld_si<0b01, 0b01, ZZ_h,   "ld2h", simm4s2>;
-  defm LD3H_IMM : sve_mem_eld_si<0b01, 0b10, ZZZ_h,  "ld3h", simm4s3>;
-  defm LD4H_IMM : sve_mem_eld_si<0b01, 0b11, ZZZZ_h, "ld4h", simm4s4>;
-  defm LD2W_IMM : sve_mem_eld_si<0b10, 0b01, ZZ_s,   "ld2w", simm4s2>;
-  defm LD3W_IMM : sve_mem_eld_si<0b10, 0b10, ZZZ_s,  "ld3w", simm4s3>;
-  defm LD4W_IMM : sve_mem_eld_si<0b10, 0b11, ZZZZ_s, "ld4w", simm4s4>;
-  defm LD2D_IMM : sve_mem_eld_si<0b11, 0b01, ZZ_d,   "ld2d", simm4s2>;
-  defm LD3D_IMM : sve_mem_eld_si<0b11, 0b10, ZZZ_d,  "ld3d", simm4s3>;
-  defm LD4D_IMM : sve_mem_eld_si<0b11, 0b11, ZZZZ_d, "ld4d", simm4s4>;
+  defm LD2B_IMM : sve_mem_eld_si<0b00, 0b001, ZZ_b,   "ld2b", simm4s2>;
+  defm LD3B_IMM : sve_mem_eld_si<0b00, 0b010, ZZZ_b,  "ld3b", simm4s3>;
+  defm LD4B_IMM : sve_mem_eld_si<0b00, 0b011, ZZZZ_b, "ld4b", simm4s4>;
+  defm LD2H_IMM : sve_mem_eld_si<0b01, 0b001, ZZ_h,   "ld2h", simm4s2>;
+  defm LD3H_IMM : sve_mem_eld_si<0b01, 0b010, ZZZ_h,  "ld3h", simm4s3>;
+  defm LD4H_IMM : sve_mem_eld_si<0b01, 0b011, ZZZZ_h, "ld4h", simm4s4>;
+  defm LD2W_IMM : sve_mem_eld_si<0b10, 0b001, ZZ_s,   "ld2w", simm4s2>;
+  defm LD3W_IMM : sve_mem_eld_si<0b10, 0b010, ZZZ_s,  "ld3w", simm4s3>;
+  defm LD4W_IMM : sve_mem_eld_si<0b10, 0b011, ZZZZ_s, "ld4w", simm4s4>;
+  defm LD2D_IMM : sve_mem_eld_si<0b11, 0b001, ZZ_d,   "ld2d", simm4s2>;
+  defm LD3D_IMM : sve_mem_eld_si<0b11, 0b010, ZZZ_d,  "ld3d", simm4s3>;
+  defm LD4D_IMM : sve_mem_eld_si<0b11, 0b011, ZZZZ_d, "ld4d", simm4s4>;
+  let Predicates = [HasSVE2p1_or_HasSME2p1] in {
+  defm LD2Q_IMM : sve_mem_eld_si<0b01, 0b100, ZZ_q,   "ld2q", simm4s2>;
+  defm LD3Q_IMM : sve_mem_eld_si<0b10, 0b100, ZZZ_q,  "ld3q", simm4s3>;
+  defm LD4Q_IMM : sve_mem_eld_si<0b11, 0b100, ZZZZ_q, "ld4q", simm4s4>;
+  }
 
   // LD(2|3|4) structured loads (register + register)
-  def LD2B : sve_mem_eld_ss<0b00, 0b01, ZZ_b,   "ld2b", GPR64NoXZRshifted8>;
-  def LD3B : sve_mem_eld_ss<0b00, 0b10, ZZZ_b,  "ld3b", GPR64NoXZRshifted8>;
-  def LD4B : sve_mem_eld_ss<0b00, 0b11, ZZZZ_b, "ld4b", GPR64NoXZRshifted8>;
-  def LD2H : sve_mem_eld_ss<0b01, 0b01, ZZ_h,   "ld2h", GPR64NoXZRshifted16>;
-  def LD3H : sve_mem_eld_ss<0b01, 0b10, ZZZ_h,  "ld3h", GPR64NoXZRshifted16>;
-  def LD4H : sve_mem_eld_ss<0b01, 0b11, ZZZZ_h, "ld4h", GPR64NoXZRshifted16>;
-  def LD2W : sve_mem_eld_ss<0b10, 0b01, ZZ_s,   "ld2w", GPR64NoXZRshifted32>;
-  def LD3W : sve_mem_eld_ss<0b10, 0b10, ZZZ_s,  "ld3w", GPR64NoXZRshifted32>;
-  def LD4W : sve_mem_eld_ss<0b10, 0b11, ZZZZ_s, "ld4w", GPR64NoXZRshifted32>;
-  def LD2D : sve_mem_eld_ss<0b11, 0b01, ZZ_d,   "ld2d", GPR64NoXZRshifted64>;
-  def LD3D : sve_mem_eld_ss<0b11, 0b10, ZZZ_d,  "ld3d", GPR64NoXZRshifted64>;
-  def LD4D : sve_mem_eld_ss<0b11, 0b11, ZZZZ_d, "ld4d", GPR64NoXZRshifted64>;
+  def LD2B : sve_mem_eld_ss<0b00, 0b101, ZZ_b,   "ld2b", GPR64NoXZRshifted8>;
+  def LD3B : sve_mem_eld_ss<0b00, 0b110, ZZZ_b,  "ld3b", GPR64NoXZRshifted8>;
+  def LD4B : sve_mem_eld_ss<0b00, 0b111, ZZZZ_b, "ld4b", GPR64NoXZRshifted8>;
+  def LD2H : sve_mem_eld_ss<0b01, 0b101, ZZ_h,   "ld2h", GPR64NoXZRshifted16>;
+  def LD3H : sve_mem_eld_ss<0b01, 0b110, ZZZ_h,  "ld3h", GPR64NoXZRshifted16>;
+  def LD4H : sve_mem_eld_ss<0b01, 0b111, ZZZZ_h, "ld4h", GPR64NoXZRshifted16>;
+  def LD2W : sve_mem_eld_ss<0b10, 0b101, ZZ_s,   "ld2w", GPR64NoXZRshifted32>;
+  def LD3W : sve_mem_eld_ss<0b10, 0b110, ZZZ_s,  "ld3w", GPR64NoXZRshifted32>;
+  def LD4W : sve_mem_eld_ss<0b10, 0b111, ZZZZ_s, "ld4w", GPR64NoXZRshifted32>;
+  def LD2D : sve_mem_eld_ss<0b11, 0b101, ZZ_d,   "ld2d", GPR64NoXZRshifted64>;
+  def LD3D : sve_mem_eld_ss<0b11, 0b110, ZZZ_d,  "ld3d", GPR64NoXZRshifted64>;
+  def LD4D : sve_mem_eld_ss<0b11, 0b111, ZZZZ_d, "ld4d", GPR64NoXZRshifted64>;
+  let Predicates = [HasSVE2p1_or_HasSME2p1] in {
+  def LD2Q : sve_mem_eld_ss<0b01, 0b001, ZZ_q,   "ld2q", GPR64NoXZRshifted128>;
+  def LD3Q : sve_mem_eld_ss<0b10, 0b001, ZZZ_q,  "ld3q", GPR64NoXZRshifted128>;
+  def LD4Q : sve_mem_eld_ss<0b11, 0b001, ZZZZ_q, "ld4q", GPR64NoXZRshifted128>;
+  }
 } // End HasSVEorSME
 
 let Predicates = [HasSVE] in {
@@ -1448,6 +1458,11 @@ let Predicates = [HasSVEorSME] in {
   defm ST2D_IMM : sve_mem_est_si<0b11, 0b01, ZZ_d,   "st2d", simm4s2>;
   defm ST3D_IMM : sve_mem_est_si<0b11, 0b10, ZZZ_d,  "st3d", simm4s3>;
   defm ST4D_IMM : sve_mem_est_si<0b11, 0b11, ZZZZ_d, "st4d", simm4s4>;
+  let Predicates = [HasSVE2p1_or_HasSME2p1] in {
+  defm ST2Q_IMM : sve_mem_128b_est_si<0b01, ZZ_q,    "st2q", simm4s2>;
+  defm ST3Q_IMM : sve_mem_128b_est_si<0b10, ZZZ_q,   "st3q", simm4s3>;
+  defm ST4Q_IMM : sve_mem_128b_est_si<0b11, ZZZZ_q,  "st4q", simm4s4>;
+  }
 
   // ST(2|3|4) structured stores (register + register)
   def ST2B : sve_mem_est_ss<0b00, 0b01, ZZ_b,   "st2b", GPR64NoXZRshifted8>;
@@ -1462,7 +1477,11 @@ let Predicates = [HasSVEorSME] in {
   def ST2D : sve_mem_est_ss<0b11, 0b01, ZZ_d,   "st2d", GPR64NoXZRshifted64>;
   def ST3D : sve_mem_est_ss<0b11, 0b10, ZZZ_d,  "st3d", GPR64NoXZRshifted64>;
   def ST4D : sve_mem_est_ss<0b11, 0b11, ZZZZ_d, "st4d", GPR64NoXZRshifted64>;
-
+  let Predicates = [HasSVE2p1_or_HasSME2p1] in {
+  def ST2Q : sve_mem_128b_est_ss<0b01, ZZ_q,    "st2q", GPR64NoXZRshifted128>;
+  def ST3Q : sve_mem_128b_est_ss<0b10, ZZZ_q,   "st3q", GPR64NoXZRshifted128>;
+  def ST4Q : sve_mem_128b_est_ss<0b11, ZZZZ_q,  "st4q", GPR64NoXZRshifted128>;
+  }
   // Non-temporal contiguous stores (register + immediate)
   defm STNT1B_ZRI : sve_mem_cstnt_si<0b00, "stnt1b", Z_b, ZPR8>;
   defm STNT1H_ZRI : sve_mem_cstnt_si<0b01, "stnt1h", Z_h, ZPR16>;

diff  --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 676771447a58d..31678ec92485d 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -5810,6 +5810,38 @@ multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
                   (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
 }
 
+
+// SVE store multiple structures (quadwords, scalar plus immediate)
+class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
+                          string asm, Operand immtype>
+    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
+        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
+        "", []>, Sched<[]> {
+  bits<5> Zt;
+  bits<5> Rn;
+  bits<3> Pg;
+  bits<4> imm4;
+  let Inst{31-24} = 0b11100100;
+  let Inst{23-22} = nregs;
+  let Inst{21-20} = 0b00;
+  let Inst{19-16} = imm4;
+  let Inst{15-13} = 0b000;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Rn;
+  let Inst{4-0}   = Zt;
+
+  let mayStore = 1;
+}
+
+multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
+                               string asm, Operand immtype> {
+  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
+
+  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
+                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
+}
+
+
 class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
                      string asm, RegisterOperand gprty>
 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
@@ -5832,6 +5864,30 @@ class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
   let mayStore = 1;
 }
 
+
+// SVE store multiple structures (quadwords, scalar plus scalar)
+class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
+                          string asm, RegisterOperand gprty>
+    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
+        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
+        "", []>, Sched<[]> {
+  bits<5> Zt;
+  bits<5> Rn;
+  bits<3> Pg;
+  bits<5> Rm;
+  let Inst{31-24} = 0b11100100;
+  let Inst{23-22} = nregs;
+  let Inst{21}    = 0b1;
+  let Inst{20-16} = Rm;
+  let Inst{15-13} = 0b000;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Rn;
+  let Inst{4-0}   = Zt;
+
+  let mayStore = 1;
+}
+
+
 class sve_mem_cst_ss_base<bits<4> dtype, string asm,
                           RegisterOperand listty, RegisterOperand gprty>
 : I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
@@ -7060,7 +7116,7 @@ multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
                             ZPRRegOp zprty>
 : sve_mem_cld_si_base<dtype, 1, asm, listty, zprty>;
 
-class sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
+class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
                      string asm, Operand immtype>
 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
   asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
@@ -7072,8 +7128,8 @@ class sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
   bits<4> imm4;
   let Inst{31-25} = 0b1010010;
   let Inst{24-23} = sz;
-  let Inst{22-21} = nregs;
-  let Inst{20}    = 0;
+  let Inst{22-21} = nregs{1-0};
+  let Inst{20}    = nregs{2};
   let Inst{19-16} = imm4;
   let Inst{15-13} = 0b111;
   let Inst{12-10} = Pg;
@@ -7083,7 +7139,7 @@ class sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
   let mayLoad = 1;
 }
 
-multiclass sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
+multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
                           string asm, Operand immtype> {
   def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
 
@@ -7091,7 +7147,8 @@ multiclass sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
                   (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
 }
 
-class sve_mem_eld_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
+
+class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
                      string asm, RegisterOperand gprty>
 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
@@ -7103,9 +7160,11 @@ class sve_mem_eld_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
   bits<5> Zt;
   let Inst{31-25} = 0b1010010;
   let Inst{24-23} = sz;
-  let Inst{22-21} = nregs;
+  let Inst{22-21} = nregs{1-0};
   let Inst{20-16} = Rm;
-  let Inst{15-13} = 0b110;
+  let Inst{15}    = 0b1;
+  let Inst{14}    = nregs{2};
+  let Inst{13}    = 0b0;
   let Inst{12-10} = Pg;
   let Inst{9-5}   = Rn;
   let Inst{4-0}   = Zt;

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld2q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/ld2q-diagnostics.s
new file mode 100644
index 0000000000000..ad8c7b263c7f5
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld2q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+ld2q {z0.q, z1.q}, p8/z, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld2q {z0.q, z1.q}, p8/z, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld2q {z23.q, z24.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ld2q {z23.q, z24.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld2q {z21.q, z22.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld2q {z21.q, z22.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+ld2q {z23.q, z24.q}, p3/z, [x13, #-17, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 2 in range [-16, 14].
+// CHECK-NEXT: ld2q {z23.q, z24.q}, p3/z, [x13, #-17, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld2q {z23.q, z24.q}, p3/z, [x13, #15, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 2 in range [-16, 14].
+// CHECK-NEXT: ld2q {z23.q, z24.q}, p3/z, [x13, #15, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld2q.s b/llvm/test/MC/AArch64/SVE2p1/ld2q.s
new file mode 100644
index 0000000000000..985508cbd9afb
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld2q.s
@@ -0,0 +1,56 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+ld2q    {z0.q, z1.q}, p0/z, [x0, x0, lsl #4]  // 10100100-10100000-10000000-00000000
+// CHECK-INST: ld2q    { z0.q, z1.q }, p0/z, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x80,0xa0,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a4a08000 <unknown>
+
+ld2q    {z21.q, z22.q}, p5/z, [x10, x21, lsl #4]  // 10100100-10110101-10010101-01010101
+// CHECK-INST: ld2q    { z21.q, z22.q }, p5/z, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x95,0xb5,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a4b59555 <unknown>
+
+ld2q    {z23.q, z24.q}, p3/z, [x13, x8, lsl #4]  // 10100100-10101000-10001101-10110111
+// CHECK-INST: ld2q    { z23.q, z24.q }, p3/z, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x8d,0xa8,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a4a88db7 <unknown>
+
+ld2q    {z0.q, z1.q}, p0/z, [x0]  // 10100100-10010000-11100000-00000000
+// CHECK-INST: ld2q    { z0.q, z1.q }, p0/z, [x0]
+// CHECK-ENCODING: [0x00,0xe0,0x90,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a490e000 <unknown>
+
+ld2q    {z21.q, z22.q}, p5/z, [x10, #10, mul vl]  // 10100100-10010101-11110101-01010101
+// CHECK-INST: ld2q    { z21.q, z22.q }, p5/z, [x10, #10, mul vl]
+// CHECK-ENCODING: [0x55,0xf5,0x95,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a495f555 <unknown>
+
+ld2q    {z23.q, z24.q}, p3/z, [x13, #-16, mul vl]  // 10100100-10011000-11101101-10110111
+// CHECK-INST: ld2q    { z23.q, z24.q }, p3/z, [x13, #-16, mul vl]
+// CHECK-ENCODING: [0xb7,0xed,0x98,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a498edb7 <unknown>
+
+ld2q    {z31.q, z0.q}, p7/z, [sp, #-2, mul vl]  // 10100100-10011111-11111111-11111111
+// CHECK-INST: ld2q    { z31.q, z0.q }, p7/z, [sp, #-2, mul vl]
+// CHECK-ENCODING: [0xff,0xff,0x9f,0xa4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a49fffff <unknown>

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld3q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/ld3q-diagnostics.s
new file mode 100644
index 0000000000000..8a612e61dc860
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld3q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+ld3q {z0.q, z1.q, z2.q}, p8/z, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld3q {z0.q, z1.q, z2.q}, p8/z, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld3q {z23.q, z24.q, z25.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ld3q {z23.q, z24.q, z25.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld3q {z21.q, z22.q, z23.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld3q {z21.q, z22.q, z23.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+ld3q {z23.q, z24.q, z25.q}, p3/z, [x13, #-25, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 3 in range [-24, 21].
+// CHECK-NEXT: ld3q {z23.q, z24.q, z25.q}, p3/z, [x13, #-25, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld3q {z23.q, z24.q, z25.q}, p3/z, [x13, #22, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 3 in range [-24, 21].
+// CHECK-NEXT: ld3q {z23.q, z24.q, z25.q}, p3/z, [x13, #22, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld3q.s b/llvm/test/MC/AArch64/SVE2p1/ld3q.s
new file mode 100644
index 0000000000000..b538e1b2fe124
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld3q.s
@@ -0,0 +1,56 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+ld3q    {z0.q, z1.q, z2.q}, p0/z, [x0, x0, lsl #4]  // 10100101-00100000-10000000-00000000
+// CHECK-INST: ld3q    { z0.q - z2.q }, p0/z, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x80,0x20,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5208000 <unknown>
+
+ld3q    {z21.q, z22.q, z23.q}, p5/z, [x10, x21, lsl #4]  // 10100101-00110101-10010101-01010101
+// CHECK-INST: ld3q    { z21.q - z23.q }, p5/z, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x95,0x35,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5359555 <unknown>
+
+ld3q    {z23.q, z24.q, z25.q}, p3/z, [x13, x8, lsl #4]  // 10100101-00101000-10001101-10110111
+// CHECK-INST: ld3q    { z23.q - z25.q }, p3/z, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x8d,0x28,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5288db7 <unknown>
+
+ld3q    {z0.q, z1.q, z2.q}, p0/z, [x0]  // 10100101-00010000-11100000-00000000
+// CHECK-INST: ld3q    { z0.q - z2.q }, p0/z, [x0]
+// CHECK-ENCODING: [0x00,0xe0,0x10,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a510e000 <unknown>
+
+ld3q    {z21.q, z22.q, z23.q}, p5/z, [x10, #15, mul vl]  // 10100101-00010101-11110101-01010101
+// CHECK-INST: ld3q    { z21.q - z23.q }, p5/z, [x10, #15, mul vl]
+// CHECK-ENCODING: [0x55,0xf5,0x15,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a515f555 <unknown>
+
+ld3q    {z23.q, z24.q, z25.q}, p3/z, [x13, #-24, mul vl]  // 10100101-00011000-11101101-10110111
+// CHECK-INST: ld3q    { z23.q - z25.q }, p3/z, [x13, #-24, mul vl]
+// CHECK-ENCODING: [0xb7,0xed,0x18,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a518edb7 <unknown>
+
+ld3q    {z31.q, z0.q, z1.q}, p7/z, [sp, #-3, mul vl]  // 10100101-00011111-11111111-11111111
+// CHECK-INST: ld3q    { z31.q, z0.q, z1.q }, p7/z, [sp, #-3, mul vl]
+// CHECK-ENCODING: [0xff,0xff,0x1f,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a51fffff <unknown>

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld4q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/ld4q-diagnostics.s
new file mode 100644
index 0000000000000..183cccc9fa3b4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld4q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+ld4q {z0.q, z1.q, z2.q, z3.q}, p8/z, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld4q {z0.q, z1.q, z2.q, z3.q}, p8/z, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld4q {z23.q, z24.q, z25.q, z26.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ld4q {z23.q, z24.q, z25.q, z26.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld4q {z21.q, z22.q, z23.q, z24.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: ld4q {z21.q, z22.q, z23.q, z24.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+ld4q {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, #-33, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 4 in range [-32, 28].
+// CHECK-NEXT: ld4q {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, #-33, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ld4q {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, #29, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 4 in range [-32, 28].
+// CHECK-NEXT: ld4q {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, #29, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ld4q.s b/llvm/test/MC/AArch64/SVE2p1/ld4q.s
new file mode 100644
index 0000000000000..43d43bd764519
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ld4q.s
@@ -0,0 +1,56 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+ld4q    {z0.q, z1.q, z2.q, z3.q}, p0/z, [x0, x0, lsl #4]  // 10100101-10100000-10000000-00000000
+// CHECK-INST: ld4q    { z0.q - z3.q }, p0/z, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x80,0xa0,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5a08000 <unknown>
+
+ld4q    {z21.q, z22.q, z23.q, z24.q}, p5/z, [x10, x21, lsl #4]  // 10100101-10110101-10010101-01010101
+// CHECK-INST: ld4q    { z21.q - z24.q }, p5/z, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x95,0xb5,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5b59555 <unknown>
+
+ld4q    {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, x8, lsl #4]  // 10100101-10101000-10001101-10110111
+// CHECK-INST: ld4q    { z23.q - z26.q }, p3/z, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x8d,0xa8,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a5a88db7 <unknown>
+
+ld4q    {z0.q, z1.q, z2.q, z3.q}, p0/z, [x0]  // 10100101-10010000-11100000-00000000
+// CHECK-INST: ld4q    { z0.q - z3.q }, p0/z, [x0]
+// CHECK-ENCODING: [0x00,0xe0,0x90,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a590e000 <unknown>
+
+ld4q    {z21.q, z22.q, z23.q, z24.q}, p5/z, [x10, #20, mul vl]  // 10100101-10010101-11110101-01010101
+// CHECK-INST: ld4q    { z21.q - z24.q }, p5/z, [x10, #20, mul vl]
+// CHECK-ENCODING: [0x55,0xf5,0x95,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a595f555 <unknown>
+
+ld4q    {z23.q, z24.q, z25.q, z26.q}, p3/z, [x13, #-32, mul vl]  // 10100101-10011000-11101101-10110111
+// CHECK-INST: ld4q    { z23.q - z26.q }, p3/z, [x13, #-32, mul vl]
+// CHECK-ENCODING: [0xb7,0xed,0x98,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a598edb7 <unknown>
+
+ld4q    {z31.q, z0.q, z1.q, z2.q}, p7/z, [sp, #-4, mul vl]  // 10100101-10011111-11111111-11111111
+// CHECK-INST: ld4q    { z31.q, z0.q, z1.q, z2.q }, p7/z, [sp, #-4, mul vl]
+// CHECK-ENCODING: [0xff,0xff,0x9f,0xa5]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: a59fffff <unknown>

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st2q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/st2q-diagnostics.s
new file mode 100644
index 0000000000000..aa728371ca004
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st2q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+st2q {z0.q, z1.q}, p8, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st2q {z0.q, z1.q}, p8, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st2q {z23.q, z24.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: st2q {z23.q, z24.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st2q {z21.q, z22.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st2q {z21.q, z22.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+st2q {z23.q, z24.q}, p3, [x13, #-17, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 2 in range [-16, 14].
+// CHECK-NEXT: st2q {z23.q, z24.q}, p3, [x13, #-17, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st2q {z23.q, z24.q}, p3, [x13, #15, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 2 in range [-16, 14].
+// CHECK-NEXT: st2q {z23.q, z24.q}, p3, [x13, #15, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st2q.s b/llvm/test/MC/AArch64/SVE2p1/st2q.s
new file mode 100644
index 0000000000000..cefb919719077
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st2q.s
@@ -0,0 +1,57 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+st2q    {z0.q, z1.q}, p0, [x0, x0, lsl #4]  // 11100100-01100000-00000000-00000000
+// CHECK-INST: st2q    { z0.q, z1.q }, p0, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x00,0x60,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4600000 <unknown>
+
+st2q    {z21.q, z22.q}, p5, [x10, x21, lsl #4]  // 11100100-01110101-00010101-01010101
+// CHECK-INST: st2q    { z21.q, z22.q }, p5, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x15,0x75,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4751555 <unknown>
+
+st2q    {z23.q, z24.q}, p3, [x13, x8, lsl #4]  // 11100100-01101000-00001101-10110111
+// CHECK-INST: st2q    { z23.q, z24.q }, p3, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x0d,0x68,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4680db7 <unknown>
+
+st2q    {z0.q, z1.q}, p0, [x0]  // 11100100-01000000-00000000-00000000
+// CHECK-INST: st2q    { z0.q, z1.q }, p0, [x0]
+// CHECK-ENCODING: [0x00,0x00,0x40,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4400000 <unknown>
+
+st2q    {z21.q, z22.q}, p5, [x10, #10, mul vl]  // 11100100-01000101-00010101-01010101
+// CHECK-INST: st2q    { z21.q, z22.q }, p5, [x10, #10, mul vl]
+// CHECK-ENCODING: [0x55,0x15,0x45,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4451555 <unknown>
+
+st2q    {z23.q, z24.q}, p3, [x13, #-16, mul vl]  // 11100100-01001000-00001101-10110111
+// CHECK-INST: st2q    { z23.q, z24.q }, p3, [x13, #-16, mul vl]
+// CHECK-ENCODING: [0xb7,0x0d,0x48,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4480db7 <unknown>
+
+st2q    {z31.q, z0.q}, p7, [sp, #-2, mul vl]  // 11100100-01001111-00011111-11111111
+// CHECK-INST: st2q    { z31.q, z0.q }, p7, [sp, #-2, mul vl]
+// CHECK-ENCODING: [0xff,0x1f,0x4f,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e44f1fff <unknown>
+

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st3q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/st3q-diagnostics.s
new file mode 100644
index 0000000000000..57ba2a0ed9d3c
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st3q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+st3q {z0.q, z1.q, z2.q}, p8/z, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st3q {z0.q, z1.q, z2.q}, p8/z, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st3q {z23.q, z24.q, z25.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: st3q {z23.q, z24.q, z25.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st3q {z21.q, z22.q, z23.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st3q {z21.q, z22.q, z23.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+st3q {z23.q, z24.q, z25.q}, p3, [x13, #-25, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 3 in range [-24, 21].
+// CHECK-NEXT: st3q {z23.q, z24.q, z25.q}, p3, [x13, #-25, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st3q {z23.q, z24.q, z25.q}, p3, [x13, #22, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 3 in range [-24, 21].
+// CHECK-NEXT: st3q {z23.q, z24.q, z25.q}, p3, [x13, #22, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st3q.s b/llvm/test/MC/AArch64/SVE2p1/st3q.s
new file mode 100644
index 0000000000000..05b4a01c051a1
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st3q.s
@@ -0,0 +1,56 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+st3q    {z0.q, z1.q, z2.q}, p0, [x0, x0, lsl #4]  // 11100100-10100000-00000000-00000000
+// CHECK-INST: st3q    { z0.q - z2.q }, p0, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x00,0xa0,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4a00000 <unknown>
+
+st3q    {z21.q, z22.q, z23.q}, p5, [x10, x21, lsl #4]  // 11100100-10110101-00010101-01010101
+// CHECK-INST: st3q    { z21.q - z23.q }, p5, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x15,0xb5,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4b51555 <unknown>
+
+st3q    {z23.q, z24.q, z25.q}, p3, [x13, x8, lsl #4]  // 11100100-10101000-00001101-10110111
+// CHECK-INST: st3q    { z23.q - z25.q }, p3, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x0d,0xa8,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4a80db7 <unknown>
+
+st3q    {z0.q, z1.q, z2.q}, p0, [x0]  // 11100100-10000000-00000000-00000000
+// CHECK-INST: st3q    { z0.q - z2.q }, p0, [x0]
+// CHECK-ENCODING: [0x00,0x00,0x80,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4800000 <unknown>
+
+st3q    {z21.q, z22.q, z23.q}, p5, [x10, #15, mul vl]  // 11100100-10000101-00010101-01010101
+// CHECK-INST: st3q    { z21.q - z23.q }, p5, [x10, #15, mul vl]
+// CHECK-ENCODING: [0x55,0x15,0x85,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4851555 <unknown>
+
+st3q    {z23.q, z24.q, z25.q}, p3, [x13, #-24, mul vl]  // 11100100-10001000-00001101-10110111
+// CHECK-INST: st3q    { z23.q - z25.q }, p3, [x13, #-24, mul vl]
+// CHECK-ENCODING: [0xb7,0x0d,0x88,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4880db7 <unknown>
+
+st3q    {z31.q, z0.q, z1.q}, p7, [sp, #-3, mul vl]  // 11100100-10001111-00011111-11111111
+// CHECK-INST: st3q    { z31.q, z0.q, z1.q }, p7, [sp, #-3, mul vl]
+// CHECK-ENCODING: [0xff,0x1f,0x8f,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e48f1fff <unknown>

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st4q-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/st4q-diagnostics.s
new file mode 100644
index 0000000000000..2fcef04b0c1d6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st4q-diagnostics.s
@@ -0,0 +1,32 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+st4q {z0.q, z1.q, z2.q, z3.q}, p8/z, [z0.d, x0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st4q {z0.q, z1.q, z2.q, z3.q}, p8/z, [z0.d, x0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st4q {z23.q, z24.q, z25.q, z26.q}, p2/m, [x0, x0, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: st4q {z23.q, z24.q, z25.q, z26.q}, p2/m, [x0, x0, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st4q {z21.q, z22.q, z23.q, z24.q}, p2.q, [x10, x21, lsl #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: st4q {z21.q, z22.q, z23.q, z24.q}, p2.q, [x10, x21, lsl #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate offset
+
+st4q {z23.q, z24.q, z25.q, z26.q}, p3, [x13, #-33, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 4 in range [-32, 28].
+// CHECK-NEXT: st4q {z23.q, z24.q, z25.q, z26.q}, p3, [x13, #-33, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+st4q {z23.q, z24.q, z25.q, z26.q}, p3, [x13, #29, mul vl]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 4 in range [-32, 28].
+// CHECK-NEXT: st4q {z23.q, z24.q, z25.q, z26.q}, p3, [x13, #29, mul vl]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/st4q.s b/llvm/test/MC/AArch64/SVE2p1/st4q.s
new file mode 100644
index 0000000000000..00c05b2ec40cf
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/st4q.s
@@ -0,0 +1,57 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+sme2p1 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p1 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p1,-sve2p1 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p1 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p1 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+st4q    {z0.q, z1.q, z2.q, z3.q}, p0, [x0, x0, lsl #4]  // 11100100-11100000-00000000-00000000
+// CHECK-INST: st4q    { z0.q - z3.q }, p0, [x0, x0, lsl #4]
+// CHECK-ENCODING: [0x00,0x00,0xe0,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4e00000 <unknown>
+
+st4q    {z21.q, z22.q, z23.q, z24.q}, p5, [x10, x21, lsl #4]  // 11100100-11110101-00010101-01010101
+// CHECK-INST: st4q    { z21.q - z24.q }, p5, [x10, x21, lsl #4]
+// CHECK-ENCODING: [0x55,0x15,0xf5,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4f51555 <unknown>
+
+st4q    {z23.q, z24.q, z25.q, z26.q}, p3, [x13, x8, lsl #4]  // 11100100-11101000-00001101-10110111
+// CHECK-INST: st4q    { z23.q - z26.q }, p3, [x13, x8, lsl #4]
+// CHECK-ENCODING: [0xb7,0x0d,0xe8,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4e80db7 <unknown>
+
+st4q    {z0.q, z1.q, z2.q, z3.q}, p0, [x0]  // 11100100-11000000-00000000-00000000
+// CHECK-INST: st4q    { z0.q - z3.q }, p0, [x0]
+// CHECK-ENCODING: [0x00,0x00,0xc0,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4c00000 <unknown>
+
+st4q    {z21.q, z22.q, z23.q, z24.q}, p5, [x10, #20, mul vl]  // 11100100-11000101-00010101-01010101
+// CHECK-INST: st4q    { z21.q - z24.q }, p5, [x10, #20, mul vl]
+// CHECK-ENCODING: [0x55,0x15,0xc5,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4c51555 <unknown>
+
+st4q    {z23.q, z24.q, z25.q, z26.q}, p3, [x13, #-32, mul vl]  // 11100100-11001000-00001101-10110111
+// CHECK-INST: st4q    { z23.q - z26.q }, p3, [x13, #-32, mul vl]
+// CHECK-ENCODING: [0xb7,0x0d,0xc8,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4c80db7 <unknown>
+
+st4q    {z31.q, z0.q, z1.q, z2.q}, p7, [sp, #-4, mul vl]  // 11100100-11001111-00011111-11111111
+// CHECK-INST: st4q    { z31.q, z0.q, z1.q, z2.q }, p7, [sp, #-4, mul vl]
+// CHECK-ENCODING: [0xff,0x1f,0xcf,0xe4]
+// CHECK-ERROR: instruction requires: sme2p1 or sve2p1
+// CHECK-UNKNOWN: e4cf1fff <unknown>
+


        


More information about the llvm-commits mailing list