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-dis.c | |
parent | b408ebbf526e7293f08825d04b34c7d2ad7fc753 (diff) | |
download | binutils-99e01a66b4c619fb8c7d6f978038eb7a3661c160.zip binutils-99e01a66b4c619fb8c7d6f978038eb7a3661c160.tar.gz binutils-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-dis.c')
-rw-r--r-- | opcodes/aarch64-dis.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 29b12d2..a2f6918 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -168,18 +168,20 @@ extract_fields (aarch64_insn code, aarch64_insn mask, ...) return value; } -/* Extract the value of all fields in SELF->fields from instruction CODE. - The least significant bit comes from the final field. */ +/* Extract the value of all fields in SELF->fields after START from + instruction CODE. The least significant bit comes from the final field. */ static aarch64_insn -extract_all_fields (const aarch64_operand *self, aarch64_insn code) +extract_all_fields_after (const aarch64_operand *self, unsigned int start, + aarch64_insn code) { aarch64_insn value; unsigned int i; enum aarch64_field_kind kind; value = 0; - for (i = 0; i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i) + for (i = start; + i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i) { kind = self->fields[i]; value <<= fields[kind].width; @@ -188,6 +190,15 @@ extract_all_fields (const aarch64_operand *self, aarch64_insn code) return value; } +/* Extract the value of all fields in SELF->fields from instruction CODE. + The least significant bit comes from the final field. */ + +static aarch64_insn +extract_all_fields (const aarch64_operand *self, aarch64_insn code) +{ + return extract_all_fields_after (self, 0, code); +} + /* Sign-extend bit I of VALUE. */ static inline uint64_t sign_extend (aarch64_insn value, unsigned i) @@ -2126,6 +2137,20 @@ aarch64_ext_x0_to_x30 (const aarch64_operand *self, aarch64_opnd_info *info, info->reg.regno = extract_field (self->fields[0], code, 0); return info->reg.regno <= 30; } + +/* Decode an indexed register, with the first field being the register + number and the remaining fields being the index. */ +bool +aarch64_ext_simple_index (const aarch64_operand *self, aarch64_opnd_info *info, + const aarch64_insn code, + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) +{ + int bias = get_operand_specific_data (self); + info->reglane.regno = extract_field (self->fields[0], code, 0) + bias; + info->reglane.index = extract_all_fields_after (self, 1, code); + return true; +} /* Bitfields that are commonly used to encode certain operands' information may be partially used as part of the base opcode in some instructions. |