From: Richard Sandiford Date: Thu, 30 Mar 2023 10:09:04 +0000 (+0100) Subject: aarch64: Treat ZA as a register X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8;p=binutils-gdb.git 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." 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 --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") \