diff options
author | Victor Do Nascimento <victor.donascimento@arm.com> | 2023-11-20 20:40:10 +0000 |
---|---|---|
committer | Victor Do Nascimento <victor.donascimento@arm.com> | 2024-01-09 10:16:41 +0000 |
commit | 9af8f6711831f2851bf88c46a1f0f2a43fb49be8 (patch) | |
tree | e43d08a9a5c8ab7dd7a04ade9d9219620d09a55c /opcodes | |
parent | 33ccb0e0dbd9707b537e385dc06eaf0a5b389d8e (diff) |
aarch64: Add support for 128-bit system register mrrs and msrr insns
With the addition of 128-bit system registers to the Arm architecture
starting with Armv9.4-a, a mechanism for manipulating their contents
is introduced with the `msrr' and `mrrs' instruction pair.
These move values from one such 128-bit system register into a pair of
contiguous general-purpose registers and vice-versa, as for example:
msrr ttlb0_el1, x0, x1
mrrs x0, x1, ttlb0_el1
This patch adds the necessary support for these instructions, adding
checks for system-register width by defining a new operand type in the
form of `AARCH64_OPND_SYSREG128' and the `aarch64_sys_reg_128bit_p'
predicate, responsible for checking whether the requested system
register table entry is marked as implemented in the 128-bit mode via
the F_REG_128 flag.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/aarch64-dis.c | 1 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 9 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 3 |
3 files changed, 12 insertions, 1 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 7eee3658fee..7e088a93c10 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -302,6 +302,7 @@ aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_op aarch64_operand_error *errors ATTRIBUTE_UNUSED) { assert (info->idx == 1 + || info->idx == 2 || info->idx == 3 || info->idx == 5); diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 70232f60e51..2e7472ac3e7 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -1710,7 +1710,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, else if (type == AARCH64_OPND_PAIRREG || type == AARCH64_OPND_PAIRREG_OR_XZR) { - assert (idx == 1 || idx == 3 || idx == 5); + assert (idx == 1 || idx == 2 || idx == 3 || idx == 5); if (opnds[idx - 1].reg.regno % 2 != 0) { set_syntax_error (mismatch_detail, idx - 1, @@ -4514,6 +4514,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_SYSREG: + case AARCH64_OPND_SYSREG128: for (i = 0; aarch64_sys_regs[i].name; ++i) { const aarch64_sys_reg *sr = aarch64_sys_regs + i; @@ -4724,6 +4725,12 @@ aarch64_sys_reg_deprecated_p (const uint32_t reg_flags) } bool +aarch64_sys_reg_128bit_p (const uint32_t reg_flags) +{ + return (reg_flags & F_REG_128) != 0; +} + +bool aarch64_sys_reg_alias_p (const uint32_t reg_flags) { return (reg_flags & F_REG_ALIAS) != 0; diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index bb8f343ffa6..288b3ddf993 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -4236,6 +4236,8 @@ const struct aarch64_opcode aarch64_opcode_table[] = CORE_INSN ("msr", 0xd5000000, 0xffe00000, ic_system, 0, OP2 (SYSREG, Rt), QL_SRC_X, F_SYS_WRITE), CORE_INSN ("sysl",0xd5280000, 0xfff80000, ic_system, 0, OP5 (Rt, UIMM3_OP1, CRn, CRm, UIMM3_OP2), QL_SYSL, 0), CORE_INSN ("mrs", 0xd5200000, 0xffe00000, ic_system, 0, OP2 (Rt, SYSREG), QL_DST_X, F_SYS_READ), + D128_INSN ("mrrs", 0xd5700000, 0xfff00000, OP3 (Rt, PAIRREG, SYSREG128), QL_DST_X2, F_SYS_READ), + D128_INSN ("msrr", 0xd5500000, 0xfff00000, OP3 (SYSREG128, Rt, PAIRREG), QL_SRC_X2, F_SYS_WRITE), CORE_INSN ("paciaz", 0xd503231f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), CORE_INSN ("paciasp", 0xd503233f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), CORE_INSN ("pacibz", 0xd503235f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), @@ -6342,6 +6344,7 @@ const struct aarch64_opcode aarch64_opcode_table[] = Y(ADDRESS, simd_addr_post, "SIMD_ADDR_POST", 0, F(), \ "a post-indexed address with immediate or register increment") \ Y(SYSTEM, sysreg, "SYSREG", 0, F(), "a system register") \ + Y(SYSTEM, sysreg, "SYSREG128", 0, F(), "a 128-bit system register") \ Y(SYSTEM, pstatefield, "PSTATEFIELD", 0, F(), \ "a PSTATE field name") \ Y(SYSTEM, sysins_op, "SYSREG_AT", 0, F(), \ |