aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/config/tc-aarch64.c73
-rw-r--r--gas/testsuite/gas/aarch64/sme-4-illegal.l52
-rw-r--r--gas/testsuite/gas/aarch64/sme-4-illegal.s10
-rw-r--r--opcodes/aarch64-opc-2.c2
-rw-r--r--opcodes/aarch64-tbl.h2
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") \