aboutsummaryrefslogtreecommitdiff
path: root/opcodes/aarch64-opc.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/aarch64-opc.c')
-rw-r--r--opcodes/aarch64-opc.c189
1 files changed, 99 insertions, 90 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 9d7f941..365cf15 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -3556,11 +3556,38 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SYSREG:
for (i = 0; aarch64_sys_regs[i].name; ++i)
- if (aarch64_sys_regs[i].value == opnd->sysreg.value
- && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
- break;
- if (aarch64_sys_regs[i].name)
- snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
+ {
+ bfd_boolean exact_match
+ = (aarch64_sys_regs[i].flags & opnd->sysreg.flags)
+ == opnd->sysreg.flags;
+
+ /* Try and find an exact match, But if that fails, return the first
+ partial match that was found. */
+ if (aarch64_sys_regs[i].value == opnd->sysreg.value
+ && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i])
+ && (name == NULL || exact_match))
+ {
+ name = aarch64_sys_regs[i].name;
+ if (exact_match)
+ {
+ if (notes)
+ *notes = NULL;
+ break;
+ }
+
+ /* If we didn't match exactly, that means the presense of a flag
+ indicates what we didn't want for this instruction. e.g. If
+ F_REG_READ is there, that means we were looking for a write
+ register. See aarch64_ext_sysreg. */
+ if (aarch64_sys_regs[i].flags & F_REG_WRITE)
+ *notes = _("reading from a write-only register.");
+ else if (aarch64_sys_regs[i].flags & F_REG_READ)
+ *notes = _("writing to a read-only register.");
+ }
+ }
+
+ if (name)
+ snprintf (buf, size, "%s", name);
else
{
/* Implementation defined system register. */
@@ -3638,26 +3665,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
#define C14 14
#define C15 15
-#ifdef F_DEPRECATED
-#undef F_DEPRECATED
-#endif
-#define F_DEPRECATED 0x1 /* Deprecated system register. */
-
-#ifdef F_ARCHEXT
-#undef F_ARCHEXT
-#endif
-#define F_ARCHEXT 0x2 /* Architecture dependent system register. */
-
-#ifdef F_HASXT
-#undef F_HASXT
-#endif
-#define F_HASXT 0x4 /* System instruction register <Xt>
- operand. */
-
-
-/* TODO there are two more issues need to be resolved
- 1. handle read-only and write-only system registers
- 2. handle cpu-implementation-defined system registers. */
+/* TODO there is one more issues need to be resolved
+ 1. handle cpu-implementation-defined system registers. */
const aarch64_sys_reg aarch64_sys_regs [] =
{
{ "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
@@ -3667,7 +3676,7 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "sp_el0", CPEN_(0,C1,0), 0 },
{ "spsel", CPEN_(0,C2,0), 0 },
{ "daif", CPEN_(3,C2,1), 0 },
- { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
+ { "currentel", CPEN_(0,C2,2), F_REG_READ }, /* RO */
{ "pan", CPEN_(0,C2,3), F_ARCHEXT },
{ "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
{ "nzcv", CPEN_(3,C2,0), 0 },
@@ -3687,45 +3696,45 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "sp_el2", CPEN_(6,C1,0), 0 },
{ "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
{ "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
- { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
- { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
- { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
- { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
- { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
- { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
- { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
- { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
- { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
- { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
- { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
- { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
- { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
- { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
- { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
- { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
- { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
- { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
- { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
- { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
- { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
- { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
- { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
- { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
- { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
- { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
- { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
- { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
- { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
- { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
- { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
- { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
- { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
- { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
- { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
- { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
- { "id_aa64zfr0_el1", CPENC (3, 0, C0, C4, 4), F_ARCHEXT }, /* RO */
- { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
- { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
+ { "midr_el1", CPENC(3,0,C0,C0,0), F_REG_READ }, /* RO */
+ { "ctr_el0", CPENC(3,3,C0,C0,1), F_REG_READ }, /* RO */
+ { "mpidr_el1", CPENC(3,0,C0,C0,5), F_REG_READ }, /* RO */
+ { "revidr_el1", CPENC(3,0,C0,C0,6), F_REG_READ }, /* RO */
+ { "aidr_el1", CPENC(3,1,C0,C0,7), F_REG_READ }, /* RO */
+ { "dczid_el0", CPENC(3,3,C0,C0,7), F_REG_READ }, /* RO */
+ { "id_dfr0_el1", CPENC(3,0,C0,C1,2), F_REG_READ }, /* RO */
+ { "id_pfr0_el1", CPENC(3,0,C0,C1,0), F_REG_READ }, /* RO */
+ { "id_pfr1_el1", CPENC(3,0,C0,C1,1), F_REG_READ }, /* RO */
+ { "id_afr0_el1", CPENC(3,0,C0,C1,3), F_REG_READ }, /* RO */
+ { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), F_REG_READ }, /* RO */
+ { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), F_REG_READ }, /* RO */
+ { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), F_REG_READ }, /* RO */
+ { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), F_REG_READ }, /* RO */
+ { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), F_REG_READ }, /* RO */
+ { "id_isar0_el1", CPENC(3,0,C0,C2,0), F_REG_READ }, /* RO */
+ { "id_isar1_el1", CPENC(3,0,C0,C2,1), F_REG_READ }, /* RO */
+ { "id_isar2_el1", CPENC(3,0,C0,C2,2), F_REG_READ }, /* RO */
+ { "id_isar3_el1", CPENC(3,0,C0,C2,3), F_REG_READ }, /* RO */
+ { "id_isar4_el1", CPENC(3,0,C0,C2,4), F_REG_READ }, /* RO */
+ { "id_isar5_el1", CPENC(3,0,C0,C2,5), F_REG_READ }, /* RO */
+ { "mvfr0_el1", CPENC(3,0,C0,C3,0), F_REG_READ }, /* RO */
+ { "mvfr1_el1", CPENC(3,0,C0,C3,1), F_REG_READ }, /* RO */
+ { "mvfr2_el1", CPENC(3,0,C0,C3,2), F_REG_READ }, /* RO */
+ { "ccsidr_el1", CPENC(3,1,C0,C0,0), F_REG_READ }, /* RO */
+ { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), F_REG_READ }, /* RO */
+ { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), F_REG_READ }, /* RO */
+ { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), F_REG_READ }, /* RO */
+ { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), F_REG_READ }, /* RO */
+ { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), F_REG_READ }, /* RO */
+ { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), F_REG_READ }, /* RO */
+ { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), F_REG_READ }, /* RO */
+ { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), F_REG_READ }, /* RO */
+ { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT | F_REG_READ }, /* RO */
+ { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), F_REG_READ }, /* RO */
+ { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), F_REG_READ }, /* RO */
+ { "id_aa64zfr0_el1", CPENC (3, 0, C0, C4, 4), F_ARCHEXT | F_REG_READ }, /* RO */
+ { "clidr_el1", CPENC(3,1,C0,C0,1), F_REG_READ }, /* RO */
+ { "csselr_el1", CPENC(3,2,C0,C0,0), F_REG_READ }, /* RO */
{ "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
{ "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
{ "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
@@ -3785,11 +3794,11 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "esr_el2", CPENC(3,4,C5,C2,0), 0 },
{ "esr_el3", CPENC(3,6,C5,C2,0), 0 },
{ "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
- { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
+ { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT | F_REG_READ }, /* RO */
{ "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
- { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
+ { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT | F_REG_READ }, /* RO */
{ "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
- { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
+ { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT | F_REG_READ }, /* RO */
{ "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
{ "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
{ "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
@@ -3813,27 +3822,27 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
{ "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
{ "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
- { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
- { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
- { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
+ { "rvbar_el1", CPENC(3,0,C12,C0,1), F_REG_READ }, /* RO */
+ { "rvbar_el2", CPENC(3,4,C12,C0,1), F_REG_READ }, /* RO */
+ { "rvbar_el3", CPENC(3,6,C12,C0,1), F_REG_READ }, /* RO */
{ "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
{ "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
{ "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
- { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
+ { "isr_el1", CPENC(3,0,C12,C1,0), F_REG_READ }, /* RO */
{ "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
{ "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
{ "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
{ "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
{ "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
{ "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
- { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
+ { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RW */
{ "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
{ "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
{ "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
{ "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
- { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
- { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
- { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
+ { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RW */
+ { "cntpct_el0", CPENC(3,3,C14,C0,1), F_REG_READ }, /* RO */
+ { "cntvct_el0", CPENC(3,3,C14,C0,2), F_REG_READ }, /* RO */
{ "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
{ "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
{ "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
@@ -3864,13 +3873,13 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
{ "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
{ "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
- { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
+ { "mdccsr_el0", CPENC(2,3,C0, C1, 0), F_REG_READ }, /* r */
{ "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
{ "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
- { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
- { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
- { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
- { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
+ { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), F_REG_READ }, /* r */
+ { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), F_REG_WRITE }, /* w */
+ { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), F_REG_READ }, /* r */
+ { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), F_REG_WRITE }, /* w */
{ "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
{ "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
{ "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
@@ -3937,35 +3946,35 @@ const aarch64_sys_reg aarch64_sys_regs [] =
{ "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
{ "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
{ "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
- { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
- { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
- { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
+ { "mdrar_el1", CPENC(2,0,C1, C0, 0), F_REG_READ }, /* r */
+ { "oslar_el1", CPENC(2,0,C1, C0, 4), F_REG_WRITE }, /* w */
+ { "oslsr_el1", CPENC(2,0,C1, C1, 4), F_REG_READ }, /* r */
{ "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
{ "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
{ "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
{ "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
- { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
+ { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), F_REG_READ }, /* r */
{ "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
{ "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
{ "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
- { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
+ { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT | F_REG_READ }, /* ro */
{ "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
{ "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
{ "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
{ "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
{ "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
{ "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
- { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
+ { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT | F_REG_READ }, /* ro */
{ "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
{ "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
{ "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
{ "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
{ "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
{ "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
- { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
+ { "pmswinc_el0", CPENC(3,3,C9,C12, 4), F_REG_WRITE }, /* w */
{ "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
- { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
- { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
+ { "pmceid0_el0", CPENC(3,3,C9,C12, 6), F_REG_READ }, /* r */
+ { "pmceid1_el0", CPENC(3,3,C9,C12, 7), F_REG_READ }, /* r */
{ "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
{ "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
{ "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },