aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-aarch64.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:11 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:11 +0100
commite2dc4040f30caba49d2bb7bd1d5119dd8a72cdba (patch)
tree0cfebab3ae6d8f57a7e9f44c876059922ec076d7 /gas/config/tc-aarch64.c
parent90cd80f8c24f9919a10117aa93fc570ac8b7767a (diff)
downloadgdb-e2dc4040f30caba49d2bb7bd1d5119dd8a72cdba.zip
gdb-e2dc4040f30caba49d2bb7bd1d5119dd8a72cdba.tar.gz
gdb-e2dc4040f30caba49d2bb7bd1d5119dd8a72cdba.tar.bz2
aarch64: Add support for vgx2 and vgx4
Many SME2 instructions operate on groups of 2 or 4 ZA vectors. This is indicated by adding a "vgx2" or "vgx4" group size to the ZA index. The group size is optional in assembly but preferred for disassembly. There is not a binary distinction between mnemonics that have group sizes and mnemonics that don't, nor between mnemonics that take vgx2 and mnemonics that take vgx4. We therefore get better error messages if we allow any ZA index to have a group size during parsing, and wait until constraint checking to reject invalid sizes. A quirk of the way errors are reported means that if an instruction is wrong both in its qualifiers and its use of a group size, we'll print suggested alternative instructions that also have an incorrect group size. But that's a general property that also applies to things like out-of-range immediates. It's also not obviously the wrong thing to do. We need to be relatively confident that we're looking at the right opcode before reporting detailed operand-specific errors, so doing qualifier checking first seems resonable.
Diffstat (limited to 'gas/config/tc-aarch64.c')
-rw-r--r--gas/config/tc-aarch64.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index b4e0b93..2d732ea 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -4550,6 +4550,26 @@ parse_sme_za_index (char **str, struct aarch64_indexed_za *opnd)
return false;
}
+ opnd->group_size = 0;
+ if (skip_past_char (str, ','))
+ {
+ if (strncasecmp (*str, "vgx2", 4) == 0 && !ISALPHA ((*str)[4]))
+ {
+ *str += 4;
+ opnd->group_size = 2;
+ }
+ else if (strncasecmp (*str, "vgx4", 4) == 0 && !ISALPHA ((*str)[4]))
+ {
+ *str += 4;
+ opnd->group_size = 4;
+ }
+ else
+ {
+ set_syntax_error (_("invalid vector group size"));
+ return false;
+ }
+ }
+
if (!skip_past_char (str, ']'))
{
set_syntax_error (_("expected ']'"));
@@ -5067,6 +5087,7 @@ const char* operand_mismatch_kind_names[] =
"AARCH64_OPDE_SYNTAX_ERROR",
"AARCH64_OPDE_FATAL_SYNTAX_ERROR",
"AARCH64_OPDE_INVALID_VARIANT",
+ "AARCH64_OPDE_INVALID_VG_SIZE",
"AARCH64_OPDE_REG_LIST_LENGTH",
"AARCH64_OPDE_REG_LIST_STRIDE",
"AARCH64_OPDE_UNTIED_IMMS",
@@ -5095,7 +5116,8 @@ operand_error_higher_severity_p (enum aarch64_operand_error_kind lhs,
gas_assert (AARCH64_OPDE_SYNTAX_ERROR > AARCH64_OPDE_EXPECTED_A_AFTER_B);
gas_assert (AARCH64_OPDE_FATAL_SYNTAX_ERROR > AARCH64_OPDE_SYNTAX_ERROR);
gas_assert (AARCH64_OPDE_INVALID_VARIANT > AARCH64_OPDE_FATAL_SYNTAX_ERROR);
- gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VARIANT);
+ gas_assert (AARCH64_OPDE_INVALID_VG_SIZE > AARCH64_OPDE_INVALID_VARIANT);
+ gas_assert (AARCH64_OPDE_REG_LIST_LENGTH > AARCH64_OPDE_INVALID_VG_SIZE);
gas_assert (AARCH64_OPDE_REG_LIST_STRIDE > AARCH64_OPDE_REG_LIST_LENGTH);
gas_assert (AARCH64_OPDE_OUT_OF_RANGE > AARCH64_OPDE_REG_LIST_STRIDE);
gas_assert (AARCH64_OPDE_UNALIGNED > AARCH64_OPDE_OUT_OF_RANGE);
@@ -5749,6 +5771,15 @@ output_operand_error_record (const operand_error_record *record, char *str)
detail->data[0].i, idx + 1, str);
break;
+ case AARCH64_OPDE_INVALID_VG_SIZE:
+ if (detail->data[0].i == 0)
+ handler (_("unexpected vector group size at operand %d -- `%s'"),
+ idx + 1, str);
+ else
+ handler (_("operand %d must have a vector group size of %d -- `%s'"),
+ idx + 1, detail->data[0].i, str);
+ break;
+
case AARCH64_OPDE_REG_LIST_LENGTH:
if (detail->data[0].i == (1 << 1))
handler (_("expected a single-register list at operand %d -- `%s'"),