diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2023-03-30 11:09:12 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2023-03-30 11:09:12 +0100 |
commit | 99e01a66b4c619fb8c7d6f978038eb7a3661c160 (patch) | |
tree | 7493699028bd43202975111c09e89213f1dd8df7 /opcodes/aarch64-asm.c | |
parent | b408ebbf526e7293f08825d04b34c7d2ad7fc753 (diff) | |
download | gdb-99e01a66b4c619fb8c7d6f978038eb7a3661c160.zip gdb-99e01a66b4c619fb8c7d6f978038eb7a3661c160.tar.gz gdb-99e01a66b4c619fb8c7d6f978038eb7a3661c160.tar.bz2 |
aarch64: Add the SME2 predicate-related instructions
Implementation-wise, the main things to note here are:
- the WHILE* instructions have forms that return a pair of predicate
registers. This is the first time that we've had lists of predicate
registers, and they wrap around after register 15 rather than after
register 31.
- the predicate-as-counter WHILE* instructions have a fourth operand
that specifies the vector length. We can treat this as an enumeration,
except that immediate values aren't allowed.
- PEXT takes an unsuffixed predicate index of the form PN<n>[<imm>].
This is the first instance of a vector/predicate index having
no suffix.
Diffstat (limited to 'opcodes/aarch64-asm.c')
-rw-r--r-- | opcodes/aarch64-asm.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c index 42cc6f7..acfec37 100644 --- a/opcodes/aarch64-asm.c +++ b/opcodes/aarch64-asm.c @@ -57,17 +57,17 @@ insert_fields (aarch64_insn *code, aarch64_insn value, aarch64_insn mask, ...) va_end (va); } -/* Insert a raw field value VALUE into all fields in SELF->fields. +/* Insert a raw field value VALUE into all fields in SELF->fields after START. The least significant bit goes in the final field. */ static void -insert_all_fields (const aarch64_operand *self, aarch64_insn *code, - aarch64_insn value) +insert_all_fields_after (const aarch64_operand *self, unsigned int start, + aarch64_insn *code, aarch64_insn value) { unsigned int i; enum aarch64_field_kind kind; - for (i = ARRAY_SIZE (self->fields); i-- > 0; ) + for (i = ARRAY_SIZE (self->fields); i-- > start; ) if (self->fields[i] != FLD_NIL) { kind = self->fields[i]; @@ -76,6 +76,16 @@ insert_all_fields (const aarch64_operand *self, aarch64_insn *code, } } +/* Insert a raw field value VALUE into all fields in SELF->fields. + The least significant bit goes in the final field. */ + +static void +insert_all_fields (const aarch64_operand *self, aarch64_insn *code, + aarch64_insn value) +{ + return insert_all_fields_after (self, 0, code, value); +} + /* Operand inserters. */ /* Insert nothing. */ @@ -1595,6 +1605,21 @@ aarch64_ins_x0_to_x30 (const aarch64_operand *self, return true; } +/* Insert an indexed register, with the first field being the register + number and the remaining fields being the index. */ +bool +aarch64_ins_simple_index (const aarch64_operand *self, + const aarch64_opnd_info *info, + aarch64_insn *code, + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) +{ + int bias = get_operand_specific_data (self); + insert_field (self->fields[0], code, info->reglane.regno - bias, 0); + insert_all_fields_after (self, 1, code, info->reglane.index); + return true; +} + /* Miscellaneous encoding functions. */ /* Encode size[0], i.e. bit 22, for |