aarch64: Add support for vgx2 and vgx4
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 30 Mar 2023 10:09:11 +0000 (11:09 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 30 Mar 2023 10:09:11 +0000 (11:09 +0100)
Many SME2 instructions operate on groups of 2 or 4 ZA vectors.
This is indicated by adding a "vgx2" or "vgx4" group size to the
ZA index.  The group size is optional in assembly but preferred
for disassembly.

There is not a binary distinction between mnemonics that have
group sizes and mnemonics that don't, nor between mnemonics that
take vgx2 and mnemonics that take vgx4.  We therefore get better
error messages if we allow any ZA index to have a group size
during parsing, and wait until constraint checking to reject
invalid sizes.

A quirk of the way errors are reported means that if an instruction
is wrong both in its qualifiers and its use of a group size, we'll
print suggested alternative instructions that also have an incorrect
group size.  But that's a general property that also applies to
things like out-of-range immediates.  It's also not obviously the
wrong thing to do.  We need to be relatively confident that we're
looking at the right opcode before reporting detailed operand-specific
errors, so doing qualifier checking first seems resonable.

15 files changed:
gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/sme-2-illegal.l
gas/testsuite/gas/aarch64/sme-2-illegal.s
gas/testsuite/gas/aarch64/sme-3-illegal.l
gas/testsuite/gas/aarch64/sme-3-illegal.s
gas/testsuite/gas/aarch64/sme-5-illegal.l
gas/testsuite/gas/aarch64/sme-5-illegal.s
gas/testsuite/gas/aarch64/sme-6-illegal.l
gas/testsuite/gas/aarch64/sme-6-illegal.s
gas/testsuite/gas/aarch64/sme-7-illegal.l
gas/testsuite/gas/aarch64/sme-7-illegal.s
gas/testsuite/gas/aarch64/sme-9-illegal.l
gas/testsuite/gas/aarch64/sme-9-illegal.s
include/opcode/aarch64.h
opcodes/aarch64-opc.c

index b4e0b937605f5a57eaca860deb253b72bfe0f1b8..2d732ea17809345db6c0b87a2c0fe9ac77a12c64 100644 (file)
@@ -4550,6 +4550,26 @@ parse_sme_za_index (char **str, struct aarch64_indexed_za *opnd)
       return false;
     }
 
+  opnd->group_size = 0;
+  if (skip_past_char (str, ','))
+    {
+      if (strncasecmp (*str, "vgx2", 4) == 0 && !ISALPHA ((*str)[4]))
+       {
+         *str += 4;
+         opnd->group_size = 2;
+       }
+      else if (strncasecmp (*str, "vgx4", 4) == 0 && !ISALPHA ((*str)[4]))
+       {
+         *str += 4;
+         opnd->group_size = 4;
+       }
+      else
+       {
+         set_syntax_error (_("invalid vector group size"));
+         return false;
+       }
+    }
+
   if (!skip_past_char (str, ']'))
     {
       set_syntax_error (_("expected ']'"));
@@ -5067,6 +5087,7 @@ const char* operand_mismatch_kind_names[] =
   "AARCH64_OPDE_SYNTAX_ERROR",
   "AARCH64_OPDE_FATAL_SYNTAX_ERROR",
   "AARCH64_OPDE_INVALID_VARIANT",
+  "AARCH64_OPDE_INVALID_VG_SIZE",
   "AARCH64_OPDE_REG_LIST_LENGTH",
   "AARCH64_OPDE_REG_LIST_STRIDE",
   "AARCH64_OPDE_UNTIED_IMMS",
@@ -5095,7 +5116,8 @@ operand_error_higher_severity_p (enum aarch64_operand_error_kind lhs,
   gas_assert (AARCH64_OPDE_SYNTAX_ERROR > AARCH64_OPDE_EXPECTED_A_AFTER_B);
   gas_assert (AARCH64_OPDE_FATAL_SYNTAX_ERROR > AARCH64_OPDE_SYNTAX_ERROR);
   gas_assert (AARCH64_OPDE_INVALID_VARIANT > AARCH64_OPDE_FATAL_SYNTAX_ERROR);
-  gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VARIANT);
+  gas_assert (AARCH64_OPDE_INVALID_VG_SIZE > AARCH64_OPDE_INVALID_VARIANT);
+  gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VG_SIZE);
   gas_assert (AARCH64_OPDE_REG_LIST_STRIDE > AARCH64_OPDE_REG_LIST_LENGTH);
   gas_assert (AARCH64_OPDE_OUT_OF_RANGE > AARCH64_OPDE_REG_LIST_STRIDE);
   gas_assert (AARCH64_OPDE_UNALIGNED > AARCH64_OPDE_OUT_OF_RANGE);
@@ -5749,6 +5771,15 @@ output_operand_error_record (const operand_error_record *record, char *str)
                 detail->data[0].i, idx + 1, str);
       break;
 
+    case AARCH64_OPDE_INVALID_VG_SIZE:
+      if (detail->data[0].i == 0)
+       handler (_("unexpected vector group size at operand %d -- `%s'"),
+                idx + 1, str);
+      else
+       handler (_("operand %d must have a vector group size of %d -- `%s'"),
+                idx + 1, detail->data[0].i, str);
+      break;
+
     case AARCH64_OPDE_REG_LIST_LENGTH:
       if (detail->data[0].i == (1 << 1))
        handler (_("expected a single-register list at operand %d -- `%s'"),
index 1df18ef200239b52b35670840fd57d4199ef04dc..fd36ed783813137af4146941f57a77bd5e375a09 100644 (file)
@@ -25,3 +25,6 @@
 [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a\]'
 [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a2\]'
 [^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a2\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx2\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx4\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 3 -- `mova z0.b,p0/m,za0h.b\[w12,#0,vgx8\]'
index 28eb6719c910b13f327dccdd14fb85c26de0bf71..8cc130ac9c0ba9091a76c936a451200ab188fe14 100644 (file)
@@ -30,3 +30,7 @@ mova    z0.q, p0/m, za0v.q[w12, 1a]
 mova    z0.q, p0/m, za0v.q[w12, #1a]
 mova    z0.q, p0/m, za0v.q[w12, 1a2]
 mova    z0.q, p0/m, za0v.q[w12, #1a2]
+
+mova   z0.b, p0/m, za0h.b[w12, #0, vgx2]
+mova   z0.b, p0/m, za0h.b[w12, #0, vgx4]
+mova   z0.b, p0/m, za0h.b[w12, #0, vgx8]
index 717af3b54be4c0cbb4df51de0de06e47731aa13e..f5fb169b78a93202f21bae4c1052f4a4744e1d46 100644 (file)
@@ -9,3 +9,14 @@
 [^:]*:[0-9]+: Error: immediate offset out of range 0 to 3 at operand 1 -- `mova za3v\.s\[w15,#4\],p7/m,z31.s'
 [^:]*:[0-9]+: Error: immediate offset out of range 0 to 1 at operand 1 -- `mova za7v\.d\[w15,#2\],p7/m,z31.d'
 [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `mova za15v\.q\[w15,#1\],p7/m,z31.q'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx2\],p0/m,z0\.b'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx4\],p0/m,z0\.b'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `mova za0h\.b\[w12,#0,vgx8\],p0/m,z0\.b'
+[^:]*:[0-9]+: Error: operand mismatch -- `mova za0h\.b\[w12,#0,vgx2\],p0/z,z0\.b'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            mova za0h\.b\[w12, 0, vgx2\], p0/m, z0\.b
+[^:]*:[0-9]+: Info:    other valid variant\(s\):
+[^:]*:[0-9]+: Info:            mova za0h\.h\[w12, 0, vgx2\], p0/m, z0\.h
+[^:]*:[0-9]+: Info:            mova za0h\.s\[w12, 0, vgx2\], p0/m, z0\.s
+[^:]*:[0-9]+: Info:            mova za0h\.d\[w12, 0, vgx2\], p0/m, z0\.d
+[^:]*:[0-9]+: Info:            mova za0h\.q\[w12, 0, vgx2\], p0/m, z0\.q
index 6ed58ec60a118bb18defb489ccc000f1719394e0..aeeaf549e8f2d8a779a66d4eaaa3df141a1673c5 100644 (file)
@@ -12,3 +12,9 @@ mova    za1v.h[w15, #8], p7/m, z31.h
 mova    za3v.s[w15, #4], p7/m, z31.s
 mova    za7v.d[w15, #2], p7/m, z31.d
 mova    za15v.q[w15, #1], p7/m, z31.q
+
+mova   za0h.b[w12, #0, vgx2], p0/m, z0.b
+mova   za0h.b[w12, #0, vgx4], p0/m, z0.b
+mova   za0h.b[w12, #0, vgx8], p0/m, z0.b
+
+mova   za0h.b[w12, #0, vgx2], p0/z, z0.b
index f892dcd2090c566ac49b84ad1694c5c64048fe33..f6eda9da5e22b9979de5e8ff212ccd8fa68b75e2 100644 (file)
@@ -56,3 +56,9 @@
 [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1w za0h.s\[w12,0\],p0/z,\[x0\]'
 [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1d za0h.d\[w12,0\],p0/z,\[x0\]'
 [^:]*:[0-9]+: Error: missing braces at operand 1 -- `ld1q za0h.q\[w12,0\],p0/z,\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx2\]},p0/z,\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx4\]},p0/z,\[x0\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `ld1b {za0h\.b\[w12,0,vgx8\]},p0/z,\[x0\]'
+[^:]*:[0-9]+: Error: operand mismatch -- `ld1b {za0h\.b\[w12,0,vgx4\]},p0/m,\[x0\]'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            ld1b {za0h\.b\[w12, 0, vgx4\]}, p0/z, \[x0, xzr\]
index 29f866690439396c0b90a6006c228f2b6355041d..9dbce626a6e70e8d40b6fac5e3a03da6a620b014 100644 (file)
@@ -57,3 +57,9 @@ ld1h za0h.h[w12, 0], p0/z, [x0]
 ld1w za0h.s[w12, 0], p0/z, [x0]
 ld1d za0h.d[w12, 0], p0/z, [x0]
 ld1q za0h.q[w12, 0], p0/z, [x0]
+
+ld1b {za0h.b[w12, 0, vgx2]}, p0/z, [x0]
+ld1b {za0h.b[w12, 0, vgx4]}, p0/z, [x0]
+ld1b {za0h.b[w12, 0, vgx8]}, p0/z, [x0]
+
+ld1b {za0h.b[w12, 0, vgx4]}, p0/m, [x0]
index c8141e086ababc271fc5fe2c7058202fb6ac8c6c..bc0d19417fc2f1521f1142e8ae97a4eac6415f12 100644 (file)
@@ -43,3 +43,9 @@
 [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15h.q\[w15,1\]},p7,\[sp\]'
 [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15v.q\[w15,1\]},p7,\[x0,x17,lsl#4\]'
 [^:]*:[0-9]+: Error: immediate offset must be 0 at operand 1 -- `st1q {za15h.q\[w15,1\]},p7,\[sp,x17,lsl#4\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `st1b {za0h.b\[w12,0,vgx2\]},p0,\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `st1b {za0h\.b\[w12,0,vgx4\]},p0,\[x0\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `st1b {za0h\.b\[w12,0,vgx8\]},p0,\[x0\]'
+[^:]*:[0-9]+: Error: operand mismatch -- `st1b {za0h\.b\[w12,0,vgx2\]},p0/z,\[x0\]'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            st1b {za0h\.b\[w12, 0, vgx2\]}, p0, \[x0, xzr\]
index d0de01d5a6c35fce188efd4658b3dbb8d755ac1a..04a508821bccd82bc0f2deb60ff5a672081a173f 100644 (file)
@@ -44,3 +44,9 @@ st1q {za15v.q[w15, 1]}, p7, [x17]
 st1q {za15h.q[w15, 1]}, p7, [sp]
 st1q {za15v.q[w15, 1]}, p7, [x0, x17, lsl #4]
 st1q {za15h.q[w15, 1]}, p7, [sp, x17, lsl #4]
+
+st1b {za0h.b[w12, 0, vgx2]}, p0, [x0]
+st1b {za0h.b[w12, 0, vgx4]}, p0, [x0]
+st1b {za0h.b[w12, 0, vgx8]}, p0, [x0]
+
+st1b {za0h.b[w12, 0, vgx2]}, p0/z, [x0]
index 0023a84da71a4bee0443fc3d0d04ea07abcb89be..eb0c5e6f51acae05aa37d25b3c38103b37dd57ef 100644 (file)
 [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0h.h\[w12,0\],\[x0\]'
 [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0v\[w12,0\],\[x0\]'
 [^:]*:[0-9]+: Error: expected 'za' rather than a ZA tile at operand 1 -- `ldr za0v.s\[w12,0\],\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ldr za\[w12,0,vgx2\],\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `ldr za\[w12,0,vgx4\],\[x0\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `ldr za\[w12,0,vgx8\],\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `str za\[w12,0,vgx2\],\[x0\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 1 -- `str za\[w12,0,vgx4\],\[x0\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 1 -- `str za\[w12,0,vgx8\],\[x0\]'
+[^:]*:[0-9]+: Error: operand mismatch -- `ldr za\.b\[w12,0,vgx2\],\[x0\]'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            ldr za\[w12, 0, vgx2\], \[x0\]
+[^:]*:[0-9]+: Error: operand mismatch -- `str za\.b\[w12,0,vgx4\],\[x0\]'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            str za\[w12, 0, vgx4\], \[x0\]
index 75e2810e647450f97bcdaa4bacc531cd2d350858..05d7d23fe29d5a3f0fdf9c2fc6b3922a87ee61da 100644 (file)
@@ -52,3 +52,14 @@ ldr za0h[w12, 0], [x0]
 ldr za0h.h[w12, 0], [x0]
 ldr za0v[w12, 0], [x0]
 ldr za0v.s[w12, 0], [x0]
+
+ldr za[w12, 0, vgx2], [x0]
+ldr za[w12, 0, vgx4], [x0]
+ldr za[w12, 0, vgx8], [x0]
+
+str za[w12, 0, vgx2], [x0]
+str za[w12, 0, vgx4], [x0]
+str za[w12, 0, vgx8], [x0]
+
+ldr za.b[w12, 0, vgx2], [x0]
+str za.b[w12, 0, vgx4], [x0]
index 0243c9efcdfe060cb3e8144349733013bd62c6b4..d7aff825288aa22de6c6a4c451a6181e48ceebfe 100644 (file)
 [^:]*:[0-9]+: Error: immediate offset out of range 0 to 7 at operand 3 -- `psel p1,p8,p6.h\[w14,#8\]'
 [^:]*:[0-9]+: Error: immediate offset out of range 0 to 3 at operand 3 -- `psel p8,p4,p15.s\[w13,#4\]'
 [^:]*:[0-9]+: Error: immediate offset out of range 0 to 1 at operand 3 -- `psel p1,p1,p1.d\[w12,#2\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx2\]'
+[^:]*:[0-9]+: Error: unexpected vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx4\]'
+[^:]*:[0-9]+: Error: invalid vector group size at operand 3 -- `psel p0,p0,p0\.b\[w12,#0,vgx8\]'
+[^:]*:[0-9]+: Error: operand mismatch -- `psel p0\.b,p0\.b,p0\.b\[w12,#0,vgx2\]'
+[^:]*:[0-9]+: Info:    did you mean this\?
+[^:]*:[0-9]+: Info:            psel p0, p0, p0\.b\[w12, 0\]
+[^:]*:[0-9]+: Info:    other valid variant\(s\):
+[^:]*:[0-9]+: Info:            psel p0, p0, p0\.h\[w12, 0\]
+[^:]*:[0-9]+: Info:            psel p0, p0, p0\.s\[w12, 0\]
+[^:]*:[0-9]+: Info:            psel p0, p0, p0\.d\[w12, 0\]
 [^:]*:[0-9]+: Error: operand mismatch -- `revd z0.q,p0/m,z0.b'
 [^:]*:[0-9]+: Info:    did you mean this\?
 [^:]*:[0-9]+: Info:            revd z0.q, p0/m, z0.q
index f59582eeb8b27e20456cb48bab0e46c4cd017c03..8f41298cd3c9f6e7e267f37b306da88e30d03f44 100644 (file)
@@ -17,6 +17,12 @@ psel p1, p8, p6.h[w14, #8]
 psel p8, p4, p15.s[w13, #4]
 psel p1, p1, p1.d[w12, #2]
 
+psel p0, p0, p0.b[w12, #0, vgx2]
+psel p0, p0, p0.b[w12, #0, vgx4]
+psel p0, p0, p0.b[w12, #0, vgx8]
+
+psel p0.b, p0.b, p0.b[w12, #0, vgx2]
+
 revd z0.q, p0/m, z0.b
 
 sclamp z8.b, z1.b, z31.q
index 945846685178ccb9909b0ee27d17f343525b5de0..534bdaa869f31d630f2f6c5257c7571f4c6c91b0 100644 (file)
@@ -1120,6 +1120,7 @@ struct aarch64_indexed_za
     int regno;    /* <Wv>  */
     int64_t imm;  /* <imm>  */
   } index;
+  unsigned group_size : 8;
   unsigned v : 1;      /* <HV> horizontal or vertical vector indicator.  */
 };
 
@@ -1294,6 +1295,17 @@ struct aarch64_inst
    The following errors are only reported against an asm string that is
    syntactically valid and that has valid operand qualifiers.
 
+   AARCH64_OPDE_INVALID_VG_SIZE
+     Error about a "VGx<n>" modifier in a ZA index not having the
+     correct <n>.  This error effectively forms a pair with
+     AARCH64_OPDE_REG_LIST_LENGTH, since both errors relate to the number
+     of vectors that an instruction operates on.  However, the "VGx<n>"
+     modifier is optional, whereas a register list always has a known
+     and explicit length.  It therefore seems better to place more
+     importance on the register list length when selecting an opcode table
+     entry.  This in turn means that having an incorrect register length
+     should be more severe than having an incorrect "VGx<n>".
+
    AARCH64_OPDE_REG_LIST_LENGTH
      Error about a register list operand having an unexpected number of
      registers.  This error is low severity because there might be another
@@ -1356,6 +1368,7 @@ enum aarch64_operand_error_kind
   AARCH64_OPDE_SYNTAX_ERROR,
   AARCH64_OPDE_FATAL_SYNTAX_ERROR,
   AARCH64_OPDE_INVALID_VARIANT,
+  AARCH64_OPDE_INVALID_VG_SIZE,
   AARCH64_OPDE_REG_LIST_LENGTH,
   AARCH64_OPDE_REG_LIST_STRIDE,
   AARCH64_OPDE_UNTIED_IMMS,
index e97201bb03a3160b7af9e74d55ccf1592ad1ea22..0d38ff250c474a0b2173751cf4a730653dd8323e 100644 (file)
@@ -1458,6 +1458,16 @@ set_reg_list_stride_error (aarch64_operand_error *mismatch_detail, int idx,
   mismatch_detail->data[0].i = 1 << expected_num;
 }
 
+static inline void
+set_invalid_vg_size (aarch64_operand_error *mismatch_detail,
+                    int idx, int expected)
+{
+  if (mismatch_detail == NULL)
+    return;
+  set_error (mismatch_detail, AARCH64_OPDE_INVALID_VG_SIZE, idx, NULL);
+  mismatch_detail->data[0].i = expected;
+}
+
 static inline void
 set_other_error (aarch64_operand_error *mismatch_detail, int idx,
                 const char* error)
@@ -1517,12 +1527,14 @@ check_reglist (const aarch64_opnd_info *opnd,
 
    - a selection register in the range [MIN_WREG, MIN_WREG + 3]
 
-   - an immediate offset in the range [0, MAX_VALUE].  */
+   - an immediate offset in the range [0, MAX_VALUE].
+
+   - a vector group size of GROUP_SIZE.  */
 
 static bool
 check_za_access (const aarch64_opnd_info *opnd,
                 aarch64_operand_error *mismatch_detail, int idx,
-                int min_wreg, int max_value)
+                int min_wreg, int max_value, int group_size)
 {
   if (!value_in_range_p (opnd->indexed_za.index.regno, min_wreg, min_wreg + 3))
     {
@@ -1540,6 +1552,15 @@ check_za_access (const aarch64_opnd_info *opnd,
       set_offset_out_of_range_error (mismatch_detail, idx, 0, max_value);
       return false;
     }
+
+  /* The vector group specifier is optional in assembly code.  */
+  if (opnd->indexed_za.group_size != 0
+      && opnd->indexed_za.group_size != group_size)
+    {
+      set_invalid_vg_size (mismatch_detail, idx, group_size);
+      return false;
+    }
+
   return true;
 }
 
@@ -1657,7 +1678,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        case AARCH64_OPND_SME_PnT_Wm_imm:
          size = aarch64_get_qualifier_esize (opnd->qualifier);
          max_value = 16 / size - 1;
-         if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value))
+         if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 0))
            return 0;
          break;
 
@@ -1680,12 +1701,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
          size = aarch64_get_qualifier_esize (opnd->qualifier);
          max_value = 16 / size - 1;
-         if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value))
+         if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value,
+                               get_opcode_dependent_value (opcode)))
            return 0;
          break;
 
        case AARCH64_OPND_SME_ZA_array_off4:
-         if (!check_za_access (opnd, mismatch_detail, idx, 12, 15))
+         if (!check_za_access (opnd, mismatch_detail, idx, 12, 15,
+                               get_opcode_dependent_value (opcode)))
            return 0;
          break;
 
@@ -3671,7 +3694,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_SME_ZA_HV_idx_src:
     case AARCH64_OPND_SME_ZA_HV_idx_dest:
     case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
-      snprintf (buf, size, "%s%s[%s, %s]%s",
+      snprintf (buf, size, "%s%s[%s, %s%s%s]%s",
                opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
                style_reg (styler, "za%d%c.%s",
                           opnd->indexed_za.regno,
@@ -3679,6 +3702,11 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
                           aarch64_get_qualifier_name (opnd->qualifier)),
                style_reg (styler, "w%d", opnd->indexed_za.index.regno),
                style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
+               opnd->indexed_za.group_size ? ", " : "",
+               opnd->indexed_za.group_size == 2
+               ? style_sub_mnem (styler, "vgx2")
+               : opnd->indexed_za.group_size == 4
+               ? style_sub_mnem (styler, "vgx4") : "",
                opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
       break;
 
@@ -3687,10 +3715,15 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       break;
 
     case AARCH64_OPND_SME_ZA_array_off4:
-      snprintf (buf, size, "%s[%s, %s]",
+      snprintf (buf, size, "%s[%s, %s%s%s]",
                style_reg (styler, "za"),
                style_reg (styler, "w%d", opnd->indexed_za.index.regno),
-               style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
+               style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
+               opnd->indexed_za.group_size ? ", " : "",
+               opnd->indexed_za.group_size == 2
+               ? style_sub_mnem (styler, "vgx2")
+               : opnd->indexed_za.group_size == 4
+               ? style_sub_mnem (styler, "vgx4") : "");
       break;
 
     case AARCH64_OPND_SME_SM_ZA: