aarch64: Treat ZA as a register
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 30 Mar 2023 10:09:04 +0000 (11:09 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 30 Mar 2023 10:09:04 +0000 (11:09 +0100)
We already treat the ZA tiles ZA0-ZA15 as registers.  This patch
does the same for ZA itself.  parse_sme_zero_mask can then parse
ZA tiles and ZA in the same way, through parsed_type_reg.

One important effect of going through parsed_type_reg (in general)
is that it allows ZA to take qualifiers.  This is necessary for many
SME2 instructions.

However, to support existing unqualified uses of ZA, parse_reg_with_qual
needs to treat the qualiier as optional.  Hopefully the net effect is
to give better error messages, since now that SME2 makes "za.<T>"
valid in some contexts, it might be natural to use it (incorrectly)
in ZERO too.

While there, the patch also tweaks the error messages for invalid
ZA tiles, to try to make some cases more specific.

For now, parse_sme_za_array just uses parse_reg, rather than
parse_typed_reg/parse_reg_with_qual.  A later patch consolidates
the parsing further.

gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/sme-4-illegal.l
gas/testsuite/gas/aarch64/sme-4-illegal.s
opcodes/aarch64-opc-2.c
opcodes/aarch64-tbl.h

index 5fb88f75a62776874580eb29b9e90ca2869e35d0..26588cb45969d05236917874e58647a6c6cdb01f 100644 (file)
@@ -284,6 +284,7 @@ struct reloc_entry
   BASIC_REG_TYPE(VN)   /* v[0-31] */   \
   BASIC_REG_TYPE(ZN)   /* z[0-31] */   \
   BASIC_REG_TYPE(PN)   /* p[0-15] */   \
+  BASIC_REG_TYPE(ZA)   /* za */        \
   BASIC_REG_TYPE(ZAT)  /* za[0-15] (ZA tile) */                        \
   BASIC_REG_TYPE(ZATH) /* za[0-15]h (ZA tile horizontal slice) */      \
   BASIC_REG_TYPE(ZATV) /* za[0-15]v (ZA tile vertical slice) */        \
@@ -327,6 +328,8 @@ struct reloc_entry
   MULTI_REG_TYPE(R_N, REG_TYPE(R_32) | REG_TYPE(R_64)                  \
                 | REG_TYPE(SP_32) | REG_TYPE(SP_64)                    \
                 | REG_TYPE(Z_32) | REG_TYPE(Z_64))                     \
+  /* The whole of ZA or a single tile.  */                             \
+  MULTI_REG_TYPE(ZA_ZAT, REG_TYPE(ZA) | REG_TYPE(ZAT))                 \
   /* A horizontal or vertical slice of a ZA tile.  */                  \
   MULTI_REG_TYPE(ZATHV, REG_TYPE(ZATH) | REG_TYPE(ZATV))               \
   /* Pseudo type to mark the end of the enumerator sequence.  */       \
@@ -1016,6 +1019,7 @@ aarch64_valid_suffix_char_p (aarch64_reg_type type, char ch)
     {
     case REG_TYPE_VN:
     case REG_TYPE_ZN:
+    case REG_TYPE_ZA:
     case REG_TYPE_ZAT:
     case REG_TYPE_ZATH:
     case REG_TYPE_ZATV:
@@ -4349,9 +4353,14 @@ parse_reg_with_qual (char **str, aarch64_reg_type reg_type,
   if (!reg)
     return NULL;
 
-  *qualifier = vectype_to_qualifier (&vectype);
-  if (*qualifier == AARCH64_OPND_QLF_NIL)
-    return NULL;
+  if (vectype.type == NT_invtype)
+    *qualifier = AARCH64_OPND_QLF_NIL;
+  else
+    {
+      *qualifier = vectype_to_qualifier (&vectype);
+      if (*qualifier == AARCH64_OPND_QLF_NIL)
+       return NULL;
+    }
 
   return reg;
 }
@@ -4558,10 +4567,23 @@ parse_sme_zero_mask(char **str)
   q = *str;
   do
     {
-      const reg_entry *reg = parse_reg_with_qual (&q, REG_TYPE_ZAT,
+      const reg_entry *reg = parse_reg_with_qual (&q, REG_TYPE_ZA_ZAT,
                                                  &qualifier);
-      if (reg)
-        {
+      if (!reg)
+       return PARSE_FAIL;
+
+      if (reg->type == REG_TYPE_ZA)
+       {
+         if (qualifier != AARCH64_OPND_QLF_NIL)
+           {
+             set_syntax_error ("ZA should not have a size suffix");
+             return PARSE_FAIL;
+           }
+          /* { ZA } is assembled as all-ones immediate.  */
+          mask = 0xff;
+       }
+      else
+       {
           int regno = reg->number;
           if (qualifier == AARCH64_OPND_QLF_S_B)
             {
@@ -4574,24 +4596,23 @@ parse_sme_zero_mask(char **str)
             mask |= 0x11 << regno;
           else if (qualifier == AARCH64_OPND_QLF_S_D)
             mask |= 0x01 << regno;
+         else if (qualifier == AARCH64_OPND_QLF_S_Q)
+           {
+              set_syntax_error (_("ZA tile masks do not operate at .Q"
+                                 " granularity"));
+              return PARSE_FAIL;
+           }
+         else if (qualifier == AARCH64_OPND_QLF_NIL)
+           {
+              set_syntax_error (_("missing ZA tile size"));
+              return PARSE_FAIL;
+           }
           else
             {
-              set_syntax_error (_("wrong ZA tile element format"));
+              set_syntax_error (_("invalid ZA tile"));
               return PARSE_FAIL;
             }
-          continue;
-        }
-      clear_error ();
-      if (strncasecmp (q, "za", 2) == 0 && !ISALNUM (q[2]))
-        {
-          /* { ZA } is assembled as all-ones immediate.  */
-          mask = 0xff;
-          q += 2;
-          continue;
         }
-
-      set_syntax_error (_("wrong ZA tile element format"));
-      return PARSE_FAIL;
     }
   while (skip_past_char (&q, ','));
 
@@ -4646,15 +4667,13 @@ parse_sme_list_of_64bit_tiles (char **str)
 static int
 parse_sme_za_array (char **str, int *imm)
 {
-  char *p, *q;
+  char *q;
   int regno;
   int64_t imm_value;
 
-  p = q = *str;
-  while (ISALPHA (*q))
-    q++;
-
-  if ((q - p != 2) || strncasecmp ("za", p, q - p) != 0)
+  q = *str;
+  const reg_entry *reg = parse_reg (&q);
+  if (!reg || reg->type != REG_TYPE_ZA)
     {
       set_syntax_error (_("expected ZA array"));
       return PARSE_FAIL;
@@ -8181,6 +8200,10 @@ static const reg_entry reg_names[] = {
   /* SVE predicate registers.  */
   REGSET16 (p, PN), REGSET16 (P, PN),
 
+  /* SME ZA.  We model this as a register because it acts syntactically
+     like ZA0H, supporting qualifier suffixes and indexing.  */
+  REGDEF (za, 0, ZA), REGDEF (ZA, 0, ZA),
+
   /* SME ZA tile registers.  */
   REGSET16 (za, ZAT), REGSET16 (ZA, ZAT),
 
index ae7d6543410ed81f64c8ad0a95f4201c59d6dfaf..b61832e42230c2b7b51246ae3dccc44cbfaa3e03 100644 (file)
@@ -1,29 +1,39 @@
 [^:]*: Assembler messages:
 [^:]*:[0-9]+: Error: expected '{' at operand 1 -- `zero za'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za8\.d}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0\.d,za8.d}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za2\.h}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za4\.s}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za1\.s,za4.s}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0\.d,za3.s,za2.h}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za1.b}'
+[^:]*:[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}'
+[^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za4\.s}'
+[^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za1\.s,za4.s}'
+[^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za0\.d,za3.s,za2.h}'
+[^:]*:[0-9]+: Error: ZA tile number out of range at operand 1 -- `zero {za1.b}'
 [^:]*:[0-9]+: Error: unexpected comma after the mnemonic name `zero' -- `zero ,'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {,'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {,'
 [^:]*:[0-9]+: Error: expected '{' at operand 1 -- `zero }'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {,}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {,,}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {,za0.d}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0.d,}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0.d,za1.d,}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za,}'
-[^:]*:[0-9]+: Error: expected '}' at operand 1 -- `zero {za.}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {,}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {,,}'
+[^:]*:[0-9]+: Error: missing ZA tile size at operand 1 -- `zero {za0}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {,za0.d}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za0.d,}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za0.d,za1.d,}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za,}'
+[^:]*:[0-9]+: Error: unexpected character `}' in element size at operand 1 -- `zero {za.}'
 [^:]*:[0-9]+: Error: expected '}' at operand 1 -- `zero {za-}'
-[^:]*:[0-9]+: Error: expected '}' at operand 1 -- `zero {za_}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za_}'
 [^:]*:[0-9]+: Error: expected '}' at operand 1 -- `zero {za#}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {zaX}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {za0}'
-[^:]*:[0-9]+: Error: wrong ZA tile element format at operand 1 -- `zero {zax}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {zaX}'
+[^:]*:[0-9]+: Error: missing ZA tile size at operand 1 -- `zero {za0}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {zax}'
 [^:]*:[0-9]+: Error: expected '}' at operand 1 -- `zero {za{}'
 [^:]*:[0-9]+: Error: unexpected characters following instruction at operand 1 -- `zero {za}}'
+[^:]*:[0-9]+: Error: ZA tile masks do not operate at .Q granularity at operand 1 -- `zero {za0\.q}'
+[^:]*:[0-9]+: Error: ZA should not have a size suffix at operand 1 -- `zero {za\.b}'
+[^:]*:[0-9]+: Error: ZA should not have a size suffix at operand 1 -- `zero {za\.h}'
+[^:]*:[0-9]+: Error: ZA should not have a size suffix at operand 1 -- `zero {za\.s}'
+[^:]*:[0-9]+: Error: ZA should not have a size suffix at operand 1 -- `zero {za\.d}'
+[^:]*:[0-9]+: Error: ZA should not have a size suffix at operand 1 -- `zero {za\.q}'
+[^:]*:[0-9]+: Error: unexpected character `2' in element size at operand 1 -- `zero {za.2d}'
+[^:]*:[0-9]+: Error: unexpected character `2' in element size at operand 1 -- `zero {za0.2d}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za0h\.b}'
+[^:]*:[0-9]+: Error: operand 1 must be a list of 64-bit ZA element tiles -- `zero {za0v\.b}'
index db0fbf6c7c0ce4c98b293dd819062b28bdf9ec1f..3d81942f7242dded29d4b906fef57c5074d7b6fc 100644 (file)
@@ -30,3 +30,13 @@ zero { za0 }
 zero { zax }
 zero { za{ }
 zero { za} }
+zero { za0.q }
+zero { za.b }
+zero { za.h }
+zero { za.s }
+zero { za.d }
+zero { za.q }
+zero { za.2d }
+zero { za0.2d }
+zero { za0h.b }
+zero { za0v.b }
index 4da9fd608b9cb35d422c631c0cd64d617d192cae..6e22690b994b09eb84c32ca4bac4ea3bd7a10a87 100644 (file)
@@ -239,7 +239,7 @@ const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_src", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5}, "an SME horizontal or vertical vector access register"},
   {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_dest", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
   {AARCH64_OPND_CLASS_PRED_REG, "SME_Pm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Pm}, "an SVE predicate register"},
-  {AARCH64_OPND_CLASS_SVE_REG, "SME_list_of_64bit_tiles", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_zero_mask}, "list of 64-bit ZA element tiles"},
+  {AARCH64_OPND_CLASS_SVE_REG, "SME_list_of_64bit_tiles", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_zero_mask}, "list of 64-bit ZA element tiles"},
   {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_ldstr", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
   {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_array", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Rv,FLD_imm4_2}, "ZA array"},
   {AARCH64_OPND_CLASS_ADDRESS, "SME_ADDR_RI_U4xVL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_imm4_2}, "memory offset"},
index 6c2862eacf35834dec5f188fc453ed8d5d6a5e00..ff0b04af794584c8aa79f185ea267174de4f8837 100644 (file)
@@ -5921,7 +5921,7 @@ const struct aarch64_opcode aarch64_opcode_table[] =
     Y(PRED_REG, regno, "SME_Pm", 0, F(FLD_SME_Pm),                     \
       "an SVE predicate register")                                     \
     Y(SVE_REG, imm, "SME_list_of_64bit_tiles", 0,      \
-      F(FLD_SME_zero_mask), "list of 64-bit ZA element tiles")                                 \
+      F(FLD_SME_zero_mask), "a list of 64-bit ZA element tiles")                                       \
     Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_ldstr", 0,                              \
       F(FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2),   \
       "an SME horizontal or vertical vector access register")  \