aboutsummaryrefslogtreecommitdiff
path: root/opcodes/aarch64-dis.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:12 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:12 +0100
commitb408ebbf526e7293f08825d04b34c7d2ad7fc753 (patch)
tree3331d54d3c7cafb02746194a07d78646b65f5c73 /opcodes/aarch64-dis.c
parentd8773a8a5f5614f508d9919cb7626ae0497b8141 (diff)
downloadbinutils-b408ebbf526e7293f08825d04b34c7d2ad7fc753.zip
binutils-b408ebbf526e7293f08825d04b34c7d2ad7fc753.tar.gz
binutils-b408ebbf526e7293f08825d04b34c7d2ad7fc753.tar.bz2
aarch64: Add the SME2 multivector LD1 and ST1 instructions
SME2 adds LD1 and ST1 variants for lists of 2 and 4 registers. The registers can be consecutive or strided. In the strided case, 2-register lists have a stride of 8, starting at register x0xxx. 4-register lists have a stride of 4, starting at register x00xx. The instructions are predicated on a predicate-as-counter register in the range pn8-pn15. Although we already had register fields with upper bounds of 7 and 15, this is the first plain register operand to have a nonzero lower bound. The patch uses the operand-specific data field to record the minimum value, rather than having separate inserters and extractors for each lower bound. This in turn required adding an extra bit to the field.
Diffstat (limited to 'opcodes/aarch64-dis.c')
-rw-r--r--opcodes/aarch64-dis.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index 7b2cf31..29b12d2 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -279,7 +279,8 @@ aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
const aarch64_inst *inst ATTRIBUTE_UNUSED,
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
- info->reg.regno = extract_field (self->fields[0], code, 0);
+ info->reg.regno = (extract_field (self->fields[0], code, 0)
+ + get_operand_specific_data (self));
return true;
}
@@ -2039,6 +2040,24 @@ aarch64_ext_sve_reglist (const aarch64_operand *self,
return true;
}
+/* Decode a strided register list. The first field holds the top bit
+ (0 or 16) and the second field holds the lower bits. The stride is
+ 16 divided by the list length. */
+bool
+aarch64_ext_sve_strided_reglist (const aarch64_operand *self,
+ aarch64_opnd_info *info, aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors
+ ATTRIBUTE_UNUSED)
+{
+ unsigned int upper = extract_field (self->fields[0], code, 0);
+ unsigned int lower = extract_field (self->fields[1], code, 0);
+ info->reglist.first_regno = upper * 16 + lower;
+ info->reglist.num_regs = get_operand_specific_data (self);
+ info->reglist.stride = 16 / info->reglist.num_regs;
+ return true;
+}
+
/* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
field. */