[v1,5/6] aarch64: Add support for sme2.1 zero instructions.

Message ID 20240708153645.1134208-6-srinath.parvathaneni@arm.com
State New
Headers
Series Binutils] aarch64: Add support for sme2p1 instructions. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Srinath Parvathaneni July 8, 2024, 3:36 p.m. UTC
  This patch adds support for following sme2.1 zero instructions and
the spec is available here [1].

1. ZERO (single-vector).
2. ZERO (double-vector).
3. ZERO (quad-vector).

The VECTOR GROUP symbols VGx2 and VGx4 are optional for the assembler
for most of the sme and sve instructions. But for few of the sme2.1
zero instruction variants VECTOR GROUP symbols VGx2 and VGx4 are mandatory.
To address this a bit "F_VG_REQ" is introduced in this patch, on setting
F_VG_REQ bit in flags of aarch64_opcode forces the assembler to accept
instruction operand only having VECTOR GROUP symbols.

[1]: https://developer.arm.com/documentation/ddi0602/2024-03/SME-Instructions?lang=en
---
 gas/testsuite/gas/aarch64/sme-4-illegal.l |   2 +-
 gas/testsuite/gas/aarch64/sme2p1-5-bad.d  |   4 +
 gas/testsuite/gas/aarch64/sme2p1-5-bad.l  | 103 ++++++++++++++++++++++
 gas/testsuite/gas/aarch64/sme2p1-5-bad.s  |  54 ++++++++++++
 gas/testsuite/gas/aarch64/sme2p1-5.d      |  54 ++++++++++++
 gas/testsuite/gas/aarch64/sme2p1-5.s      |  54 ++++++++++++
 include/opcode/aarch64.h                  |  11 ++-
 opcodes/aarch64-opc.c                     |  60 ++++++++-----
 opcodes/aarch64-tbl.h                     |  18 ++++
 9 files changed, 336 insertions(+), 24 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/sme2p1-5-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/sme2p1-5-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/sme2p1-5-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/sme2p1-5.d
 create mode 100644 gas/testsuite/gas/aarch64/sme2p1-5.s
  

Patch

diff --git a/gas/testsuite/gas/aarch64/sme-4-illegal.l b/gas/testsuite/gas/aarch64/sme-4-illegal.l
index a9e98524067..db52529e3e1 100644
--- a/gas/testsuite/gas/aarch64/sme-4-illegal.l
+++ b/gas/testsuite/gas/aarch64/sme-4-illegal.l
@@ -1,5 +1,5 @@ 
 [^:]*: Assembler messages:
-[^:]*:[0-9]+: Error: expected '{' at operand 1 -- `zero za'
+[^:]*:[0-9]+: Error: expected '\[' at operand 1 -- `zero za'
 [^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za8\.d}'
 [^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za0\.d,za8.d}'
 [^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za2\.h}'
diff --git a/gas/testsuite/gas/aarch64/sme2p1-5-bad.d b/gas/testsuite/gas/aarch64/sme2p1-5-bad.d
new file mode 100644
index 00000000000..86a6834546e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-5-bad.d
@@ -0,0 +1,4 @@ 
+#name: Negative test of SME2.1 ZERO instructions.
+#as: -march=armv9.4-a+sme2p1
+#source: sme2p1-5-bad.s
+#error_output: sme2p1-5-bad.l
diff --git a/gas/testsuite/gas/aarch64/sme2p1-5-bad.l b/gas/testsuite/gas/aarch64/sme2p1-5-bad.l
new file mode 100644
index 00000000000..959864a9809
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-5-bad.l
@@ -0,0 +1,103 @@ 
+.*: Assembler messages:
+.*: Error: operand mismatch -- `zero za.s\[w8,0,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 0, vgx2\]
+.*: Error: operand mismatch -- `zero za.b\[w14,0,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w14, 0, vgx2\]
+.*: Error: expected a selection register in the range w8-w11 at operand 1 -- `zero za.d\[w2,7,vgx2\]'
+.*: Error: immediate offset out of range 0 to 7 at operand 1 -- `zero za.d\[w11,17,vgx2\]'
+.*: Error: invalid vector group size at operand 1 -- `zero za.d\[w9,4,vgx3\]'
+.*: Error: operand mismatch -- `zero za.h\[w10,3\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w10, 3\]
+.*: Error: operand mismatch -- `zero za.s\[w18,0,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0, vgx4\]
+.*: Error: operand mismatch -- `zero za.b\[w1,0,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0, vgx4\]
+.*: Error: operand mismatch -- `zero za.q\[w8,17,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 17, vgx2\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.h\[w11,7,vgx3\]'
+.*: Error: expected a constant immediate offset at operand 1 -- `zero za.s\[w9,vg\]'
+.*: Error: operand mismatch -- `zero za.b\[w10,3\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w10, 3\]
+.*: Error: operand mismatch -- `zero za.s\[w18,0:1\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0:1\]
+.*: Error: operand mismatch -- `zero za.s\[w1,0:1\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0:1\]
+.*: Error: operand mismatch -- `zero za.b\[w8,4:5\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 4:5\]
+.*: Error: operand mismatch -- `zero za.b\[w11,1:5\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w11, 1:5\]
+.*: Error: operand mismatch -- `zero za.h\[w9,2:13\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w9, 2:13\]
+.*: Error: the last offset is less than the first offset at operand 1 -- `zero za.h\[w10,16:7\]'
+.*: Error: operand mismatch -- `zero za.s\[w18,0:3,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0:3, vgx2\]
+.*: Error: operand mismatch -- `zero za.b\[w1,0:1,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0:1, vgx4\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.h\[w8,6:7,vg\]'
+.*: Error: invalid vector group size at operand 1 -- `zero za.q\[w9,12:13,vgx3\]'
+.*: Error: operand mismatch -- `zero za.s\[w18,0:1,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0:1, vgx4\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.h\[w1,0:1,vgx3\]'
+.*: Error: operand mismatch -- `zero za.b\[w8,16:17,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 16:17, vgx4\]
+.*: Error: operand mismatch -- `zero za.q\[w9,12:13\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w9, 12:13\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.s\[w18,0:3,\]'
+.*: Error: operand mismatch -- `zero za.s\[w1,0:3\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0:3\]
+.*: Error: operand mismatch -- `zero za.b\[w8,8:11\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 8:11\]
+.*: Error: the last offset is less than the first offset at operand 1 -- `zero za.b\[w11,18:1,vgx3\]'
+.*: Error: operand mismatch -- `zero za.h\[w9,4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w9, 4\]
+.*: Error: operand mismatch -- `zero za.h\[w10,10:13\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w10, 10:13\]
+.*: Error: operand mismatch -- `zero za.s\[w18,0:3,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0:3, vgx2\]
+.*: Error: operand mismatch -- `zero za.s\[w1,0:3,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0:3, vgx2\]
+.*: Error: operand mismatch -- `zero za.b\[w8,14:17,vgx2\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 14:17, vgx2\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.b\[w11,4:7,vg\]'
+.*: Error: operand mismatch -- `zero za.h\[w9,0:3\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w9, 0:3\]
+.*: Error: expected a constant immediate offset at operand 1 -- `zero za.q\[w10,vgx2\]'
+.*: Error: operand mismatch -- `zero za.s\[w18,0:3,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w18, 0:3, vgx4\]
+.*: Error: operand mismatch -- `zero za.s\[w1,0:3,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w1, 0:3, vgx4\]
+.*: Error: operand mismatch -- `zero za.b\[w8,14:17,vgx4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w8, 14:17, vgx4\]
+.*: Error: invalid vector group size at operand 1 -- `zero za.b\[w11,4:7,vg\]'
+.*: Error: invalid vector group size at operand 1 -- `zero za.h\[w9,0:3,vgx3\]'
+.*: Error: operand mismatch -- `zero za.q\[w10,4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	zero za.d\[w10, 4\]
diff --git a/gas/testsuite/gas/aarch64/sme2p1-5-bad.s b/gas/testsuite/gas/aarch64/sme2p1-5-bad.s
new file mode 100644
index 00000000000..5b69634e5b2
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-5-bad.s
@@ -0,0 +1,54 @@ 
+/* ZERO (single-vector).  */
+zero za.s[w8, 0, vgx2]
+zero za.b[w14, 0, vgx2]
+zero za.d[w2, 7, vgx2]
+zero za.d[w11, 17, vgx2]
+zero za.d[w9, 4, vgx3]
+zero za.h[w10, 3]
+
+zero za.s[w18, 0, vgx4]
+zero za.b[w1, 0, vgx4]
+zero za.q[w8, 17, vgx2]
+zero za.h[w11, 7, vgx3]
+zero za.s[w9, vg]
+zero za.b[w10, 3]
+
+/* ZERO (double-vector).  */
+zero za.s[w18, 0:1]
+zero za.s[w1, 0:1]
+zero za.b[w8, 4:5]
+zero za.b[w11, 1:5]
+zero za.h[w9, 2:13]
+zero za.h[w10, 16:7]
+
+zero za.s[w18, 0:3, vgx2]
+zero za.b[w1, 0:1, vgx4]
+zero za.h[w8, 6:7, vg]
+zero za.q[w9, 12:13, vgx3]
+
+zero za.s[w18, 0:1, vgx4]
+zero za.h[w1, 0:1, vgx3]
+zero za.b[w8, 16:17, vgx4]
+zero za.q[w9, 12:13]
+
+/* ZERO (quad-vector).  */
+zero za.s[w18, 0:3,]
+zero za.s[w1, 0:3]
+zero za.b[w8, 8:11]
+zero za.b[w11, 18:1, vgx3]
+zero za.h[w9, 4]
+zero za.h[w10, 10:13]
+
+zero za.s[w18, 0:3, vgx2]
+zero za.s[w1, 0:3, vgx2]
+zero za.b[w8, 14:17, vgx2]
+zero za.b[w11, 4:7, vg]
+zero za.h[w9, 0:3]
+zero za.q[w10, vgx2]
+
+zero za.s[w18, 0:3, vgx4]
+zero za.s[w1, 0:3, vgx4]
+zero za.b[w8, 14:17, vgx4]
+zero za.b[w11, 4:7, vg]
+zero za.h[w9, 0:3, vgx3]
+zero za.q[w10, 4]
diff --git a/gas/testsuite/gas/aarch64/sme2p1-5.d b/gas/testsuite/gas/aarch64/sme2p1-5.d
new file mode 100644
index 00000000000..f63a171d461
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-5.d
@@ -0,0 +1,54 @@ 
+#name: Test of SME2.1 ZERO instructions.
+#as: -march=armv9.4-a+sme2p1
+#objdump: -dr
+
+[^:]+:     file format .*
+
+
+[^:]+:
+
+[^:]+:
+.*:	c00c0000 	zero	za.d\[w8, 0, vgx2\]
+.*:	c00c6000 	zero	za.d\[w11, 0, vgx2\]
+.*:	c00c0007 	zero	za.d\[w8, 7, vgx2\]
+.*:	c00c6007 	zero	za.d\[w11, 7, vgx2\]
+.*:	c00c2004 	zero	za.d\[w9, 4, vgx2\]
+.*:	c00c4003 	zero	za.d\[w10, 3, vgx2\]
+.*:	c00e0000 	zero	za.d\[w8, 0, vgx4\]
+.*:	c00e6000 	zero	za.d\[w11, 0, vgx4\]
+.*:	c00e0007 	zero	za.d\[w8, 7, vgx4\]
+.*:	c00e6007 	zero	za.d\[w11, 7, vgx4\]
+.*:	c00e2004 	zero	za.d\[w9, 4, vgx4\]
+.*:	c00e4003 	zero	za.d\[w10, 3, vgx4\]
+.*:	c00c8000 	zero	za.d\[w8, 0:1\]
+.*:	c00ce000 	zero	za.d\[w11, 0:1\]
+.*:	c00c8007 	zero	za.d\[w8, 14:15\]
+.*:	c00ce007 	zero	za.d\[w11, 14:15\]
+.*:	c00ca001 	zero	za.d\[w9, 2:3\]
+.*:	c00cc003 	zero	za.d\[w10, 6:7\]
+.*:	c00d0000 	zero	za.d\[w8, 0:1, vgx2\]
+.*:	c00d6000 	zero	za.d\[w11, 0:1, vgx2\]
+.*:	c00d0003 	zero	za.d\[w8, 6:7, vgx2\]
+.*:	c00d2001 	zero	za.d\[w9, 2:3, vgx2\]
+.*:	c00d8000 	zero	za.d\[w8, 0:1, vgx4\]
+.*:	c00de000 	zero	za.d\[w11, 0:1, vgx4\]
+.*:	c00d8003 	zero	za.d\[w8, 6:7, vgx4\]
+.*:	c00da001 	zero	za.d\[w9, 2:3, vgx4\]
+.*:	c00e8000 	zero	za.d\[w8, 0:3\]
+.*:	c00ee000 	zero	za.d\[w11, 0:3\]
+.*:	c00e8002 	zero	za.d\[w8, 8:11\]
+.*:	c00ee002 	zero	za.d\[w11, 8:11\]
+.*:	c00ea001 	zero	za.d\[w9, 4:7\]
+.*:	c00ec000 	zero	za.d\[w10, 0:3\]
+.*:	c00f0000 	zero	za.d\[w8, 0:3, vgx2\]
+.*:	c00f6000 	zero	za.d\[w11, 0:3, vgx2\]
+.*:	c00f0001 	zero	za.d\[w8, 4:7, vgx2\]
+.*:	c00f6001 	zero	za.d\[w11, 4:7, vgx2\]
+.*:	c00f2000 	zero	za.d\[w9, 0:3, vgx2\]
+.*:	c00f4001 	zero	za.d\[w10, 4:7, vgx2\]
+.*:	c00f8000 	zero	za.d\[w8, 0:3, vgx4\]
+.*:	c00fe000 	zero	za.d\[w11, 0:3, vgx4\]
+.*:	c00f8001 	zero	za.d\[w8, 4:7, vgx4\]
+.*:	c00fe001 	zero	za.d\[w11, 4:7, vgx4\]
+.*:	c00fa000 	zero	za.d\[w9, 0:3, vgx4\]
+.*:	c00fc001 	zero	za.d\[w10, 4:7, vgx4\]
diff --git a/gas/testsuite/gas/aarch64/sme2p1-5.s b/gas/testsuite/gas/aarch64/sme2p1-5.s
new file mode 100644
index 00000000000..bd25682d2ef
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-5.s
@@ -0,0 +1,54 @@ 
+/* ZERO (single-vector).  */
+zero za.d[w8, 0, vgx2]
+zero za.d[w11, 0, vgx2]
+zero za.d[w8, 7, vgx2]
+zero za.d[w11, 7, vgx2]
+zero za.d[w9, 4, vgx2]
+zero za.d[w10, 3, vgx2]
+
+zero za.d[w8, 0, vgx4]
+zero za.d[w11, 0, vgx4]
+zero za.d[w8, 7, vgx4]
+zero za.d[w11, 7, vgx4]
+zero za.d[w9, 4, vgx4]
+zero za.d[w10, 3, vgx4]
+
+/* ZERO (double-vector).  */
+zero za.d[w8, 0:1]
+zero za.d[w11, 0:1]
+zero za.d[w8, 14:15]
+zero za.d[w11, 14:15]
+zero za.d[w9, 2:3]
+zero za.d[w10, 6:7]
+
+zero za.d[w8, 0:1, vgx2]
+zero za.d[w11, 0:1, vgx2]
+zero za.d[w8, 6:7, vgx2]
+zero za.d[w9, 2:3, vgx2]
+
+zero za.d[w8, 0:1, vgx4]
+zero za.d[w11, 0:1, vgx4]
+zero za.d[w8, 6:7, vgx4]
+zero za.d[w9, 2:3, vgx4]
+
+/* ZERO (quad-vector).  */
+zero za.d[w8, 0:3]
+zero za.d[w11, 0:3]
+zero za.d[w8, 8:11]
+zero za.d[w11, 8:11]
+zero za.d[w9, 4:7]
+zero za.d[w10, 0:3]
+
+zero za.d[w8, 0:3, vgx2]
+zero za.d[w11, 0:3, vgx2]
+zero za.d[w8, 4:7, vgx2]
+zero za.d[w11, 4:7, vgx2]
+zero za.d[w9, 0:3, vgx2]
+zero za.d[w10, 4:7, vgx2]
+
+zero za.d[w8, 0:3, vgx4]
+zero za.d[w11, 0:3, vgx4]
+zero za.d[w8, 4:7, vgx4]
+zero za.d[w11, 4:7, vgx4]
+zero za.d[w9, 0:3, vgx4]
+zero za.d[w10, 4:7, vgx4]
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 5a2b99d2bc5..1b01931b0cb 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -1387,7 +1387,10 @@  extern const aarch64_opcode aarch64_opcode_table[];
 #define F_OPD_SIZE (1ULL << 34)
 /* RCPC3 instruction has the field of 'size'.  */
 #define F_RCPC3_SIZE (1ULL << 35)
-/* Next bit is 36.  */
+/* This instruction need VGx2 or VGx4 mandatorily in the operand passed to
+   assembler.  */
+#define F_VG_REQ (1ULL << 36)
+/* Next bit is 37.  */
 
 /* Instruction constraints.  */
 /* This instruction has a predication constraint on the instruction at PC+4.  */
@@ -1450,6 +1453,12 @@  get_opcode_dependent_value (const aarch64_opcode *opcode)
   return (opcode->flags >> 24) & 0x7;
 }
 
+static inline bool
+get_opcode_dependent_vg_status (const aarch64_opcode *opcode)
+{
+  return (opcode->flags >> 36) & 0x1;
+}
+
 static inline bool
 opcode_has_special_coder (const aarch64_opcode *opcode)
 {
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index f65f83a0126..b71d354d4c0 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1629,13 +1629,14 @@  check_reglist (const aarch64_opnd_info *opnd,
    - an initial immediate offset that is a multiple of RANGE_SIZE
      in the range [0, MAX_VALUE * RANGE_SIZE]
 
-   - a vector group size of GROUP_SIZE.  */
+   - a vector group size of GROUP_SIZE.
 
+   - STATUS_VG for cases where VGx2 or VGx4 is mandatory.  */
 static bool
 check_za_access (const aarch64_opnd_info *opnd,
 		 aarch64_operand_error *mismatch_detail, int idx,
 		 int min_wreg, int max_value, unsigned int range_size,
-		 int group_size)
+		 int group_size, bool status_vg)
 {
   if (!value_in_range_p (opnd->indexed_za.index.regno, min_wreg, min_wreg + 3))
     {
@@ -1687,8 +1688,8 @@  check_za_access (const aarch64_opnd_info *opnd,
     }
 
   /* The vector group specifier is optional in assembly code.  */
-  if (opnd->indexed_za.group_size != 0
-      && opnd->indexed_za.group_size != group_size)
+  if (opnd->indexed_za.group_size != group_size
+      && (status_vg || opnd->indexed_za.group_size != 0 ))
     {
       set_invalid_vg_size (mismatch_detail, idx, group_size);
       return false;
@@ -1923,7 +1924,7 @@  operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
 	  max_value = 16 / size - 1;
 	  if (!check_za_access (opnd, mismatch_detail, idx,
-				12, max_value, 1, 0))
+				12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
 	    return 0;
 	  break;
 
@@ -1993,93 +1994,108 @@  operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
 	  max_value = 16 / size - 1;
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off3_0:
 	case AARCH64_OPND_SME_ZA_array_off3_5:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off1x4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off2x2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off2x4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off3x2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsb_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsh_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrss_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsd_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsb_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsh_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_ARRAY4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrss_2:
 	case AARCH64_OPND_SME_ZA_array_vrsd_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
-				get_opcode_dependent_value (opcode)))
+				get_opcode_dependent_value (opcode),
+				get_opcode_dependent_vg_status (opcode)))
 	    return 0;
 	  break;
 
@@ -2090,8 +2106,8 @@  operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  max_value = 16 / num / size;
 	  if (max_value > 0)
 	    max_value -= 1;
-	  if (!check_za_access (opnd, mismatch_detail, idx,
-				12, max_value, num, 0))
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
+				0, get_opcode_dependent_value (opcode)))
 	    return 0;
 	  break;
 
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 38be471965c..d49ad3683b5 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1606,6 +1606,10 @@ 
 {                                                       \
   QLF3(S_B,P_Z,NIL),                                    \
 }
+#define OP_SVE_D					\
+{                                                       \
+  QLF1(S_D),						\
+}
 #define OP_SVE_DD                                       \
 {                                                       \
   QLF2(S_D,S_D),                                        \
@@ -6668,6 +6672,20 @@  const struct aarch64_opcode aarch64_opcode_table[] =
   SME2p1_INSN ("movaz", 0xc0c20200, 0xffff1e00, sme2_movaz, 0, OP2 (SVE_Zd, SME_ZA_ARRAY4), OP_SVE_DD, 0, 0),
   SME2p1_INSN ("movaz", 0xc0c30200, 0xffff1e00, sme2_movaz, 0, OP2 (SVE_Zd, SME_ZA_ARRAY4), OP_SVE_QQ, 0, 0),
 
+  /* ZERO (single-vector).  */
+  SME2p1_INSN ("zero", 0xc00c0000, 0xffff9ff8, sme2_movaz, 0, OP1 (SME_ZA_array_off3_0), OP_SVE_D, F_OD (2) | F_VG_REQ, 0),
+  SME2p1_INSN ("zero", 0xc00e0000, 0xffff9ff8, sme2_movaz, 0, OP1 (SME_ZA_array_off3_0), OP_SVE_D, F_OD (4) | F_VG_REQ, 0),
+
+  /* ZERO (double-vector).  */
+  SME2p1_INSN ("zero", 0xc00c8000, 0xffff9ff8, sme2_movaz, 0, OP1 (SME_ZA_array_off3x2), OP_SVE_D, 0, 0),
+  SME2p1_INSN ("zero", 0xc00d0000, 0xffff9ffc, sme2_movaz, 0, OP1 (SME_ZA_array_off2x2), OP_SVE_D, F_OD (2) | F_VG_REQ, 0),
+  SME2p1_INSN ("zero", 0xc00d8000, 0xffff9ffc, sme2_movaz, 0, OP1 (SME_ZA_array_off2x2), OP_SVE_D, F_OD (4) | F_VG_REQ, 0),
+
+  /* ZERO (quad-vector).  */
+  SME2p1_INSN ("zero", 0xc00e8000, 0xffff9ffc, sme2_movaz, 0, OP1 (SME_ZA_array_off2x4), OP_SVE_D, 0, 0),
+  SME2p1_INSN ("zero", 0xc00f0000, 0xffff9ffe, sme2_movaz, 0, OP1 (SME_ZA_array_off1x4), OP_SVE_D, F_OD (2) | F_VG_REQ, 0),
+  SME2p1_INSN ("zero", 0xc00f8000, 0xffff9ffe, sme2_movaz, 0, OP1 (SME_ZA_array_off1x4), OP_SVE_D, F_OD (4) | F_VG_REQ, 0),
+
 /* SVE2p1 Instructions.  */
   SVE2p1_INSN("addqv",0x04052000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, 0),
   SVE2p1_INSN("andqv",0x041e2000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, 0),