diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2023-03-30 11:09:04 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2023-03-30 11:09:04 +0100 |
commit | e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8 (patch) | |
tree | 5436eae9fa8f389f817433c7e3d81375f7c9d0f8 | |
parent | 8cde0b988a9062c0d0e8d32ab3865ea9750c56e9 (diff) | |
download | binutils-e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8.zip binutils-e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8.tar.gz binutils-e9e1ddbb9894bc9eb4d091f3406e5f77c78cd7b8.tar.bz2 |
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.
-rw-r--r-- | gas/config/tc-aarch64.c | 73 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sme-4-illegal.l | 52 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sme-4-illegal.s | 10 | ||||
-rw-r--r-- | opcodes/aarch64-opc-2.c | 2 | ||||
-rw-r--r-- | 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 5fb88f7..26588cb 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 ae7d654..b61832e 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 db0fbf6..3d81942 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 4da9fd6..6e22690 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 6c2862e..ff0b04a 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") \ |