public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] aarch64: Treat ZA as a register
@ 2023-03-30 10:11 Richard Sandiford
  0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2023-03-30 10:11 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8

commit e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Thu Mar 30 11:09:04 2023 +0100

    aarch64: Treat ZA as a register
    
    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.

Diff:
---
 gas/config/tc-aarch64.c                   | 73 ++++++++++++++++++++-----------
 gas/testsuite/gas/aarch64/sme-4-illegal.l | 52 +++++++++++++---------
 gas/testsuite/gas/aarch64/sme-4-illegal.s | 10 +++++
 opcodes/aarch64-opc-2.c                   |  2 +-
 opcodes/aarch64-tbl.h                     |  2 +-
 5 files changed, 91 insertions(+), 48 deletions(-)

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 5fb88f75a62..26588cb4596 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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),
 
diff --git a/gas/testsuite/gas/aarch64/sme-4-illegal.l b/gas/testsuite/gas/aarch64/sme-4-illegal.l
index ae7d6543410..b61832e4223 100644
--- a/gas/testsuite/gas/aarch64/sme-4-illegal.l
+++ b/gas/testsuite/gas/aarch64/sme-4-illegal.l
@@ -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}'
diff --git a/gas/testsuite/gas/aarch64/sme-4-illegal.s b/gas/testsuite/gas/aarch64/sme-4-illegal.s
index db0fbf6c7c0..3d81942f724 100644
--- a/gas/testsuite/gas/aarch64/sme-4-illegal.s
+++ b/gas/testsuite/gas/aarch64/sme-4-illegal.s
@@ -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 }
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index 4da9fd608b9..6e22690b994 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -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}, "a 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"},
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 6c2862eacf3..ff0b04af794 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -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")	\

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-03-30 10:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-30 10:11 [binutils-gdb] aarch64: Treat ZA as a register Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).