diff options
-rw-r--r-- | binutils/ChangeLog | 5 | ||||
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/illegal-sysreg-2.l | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysreg-2.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysreg-2.s | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysreg-diagnostic.d | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysreg-diagnostic.l | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysreg-diagnostic.s | 6 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/opcode/aarch64.h | 6 | ||||
-rw-r--r-- | opcodes/ChangeLog | 28 | ||||
-rw-r--r-- | opcodes/aarch64-asm.c | 31 | ||||
-rw-r--r-- | opcodes/aarch64-dis.c | 17 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 189 | ||||
-rw-r--r-- | opcodes/aarch64-opc.h | 20 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 6 |
16 files changed, 247 insertions, 100 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 8f139a5..3d90103 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -2,6 +2,11 @@ PR binutils/21446 * doc/binutils.texi (-M): Document AArch64 options. + +2018-05-15 Tamar Christina <tamar.christina@arm.com> + + PR binutils/21446 + * doc/binutils.texi (-M): Document AArch64 options. * NEWS: Document notes and warnings. 2018-05-15 Alan Modra <amodra@gmail.com> diff --git a/gas/ChangeLog b/gas/ChangeLog index 84bba4b..a89ffe1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,6 +1,16 @@ 2018-05-15 Tamar Christina <tamar.christina@arm.com> PR binutils/21446 + * testsuite/gas/aarch64/illegal-sysreg-2.s: Fix pmbidr_el1 test. + * testsuite/gas/aarch64/illegal-sysreg-2.l: Likewise. + * testsuite/gas/aarch64/illegal-sysreg-2.d: Likewise. + * testsuite/gas/aarch64/sysreg-diagnostic.s: New. + * testsuite/gas/aarch64/sysreg-diagnostic.l: New. + * testsuite/gas/aarch64/sysreg-diagnostic.d: New. + +2018-05-15 Tamar Christina <tamar.christina@arm.com> + + PR binutils/21446 * config/tc-aarch64.c (print_operands): Indicate no notes. (output_operand_error_record): Support non-fatal errors. (output_operand_error_report, warn_unpredictable_ldst, md_assemble): diff --git a/gas/testsuite/gas/aarch64/illegal-sysreg-2.l b/gas/testsuite/gas/aarch64/illegal-sysreg-2.l index f059611..1204056 100644 --- a/gas/testsuite/gas/aarch64/illegal-sysreg-2.l +++ b/gas/testsuite/gas/aarch64/illegal-sysreg-2.l @@ -27,8 +27,6 @@ [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmbptr_el1' [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmbsr_el1' [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmbsr_el1' -[^:]*:[0-9]+: Error: selected processor does not support system register name 'pmbidr_el1' -[^:]*:[0-9]+: Error: selected processor does not support system register name 'pmbidr_el1' [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmscr_el1' [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmscr_el1' [^:]*:[0-9]+: Error: selected processor does not support system register name 'pmsicr_el1' diff --git a/gas/testsuite/gas/aarch64/sysreg-2.d b/gas/testsuite/gas/aarch64/sysreg-2.d index a0539db..097f272 100644 --- a/gas/testsuite/gas/aarch64/sysreg-2.d +++ b/gas/testsuite/gas/aarch64/sysreg-2.d @@ -38,8 +38,6 @@ Disassembly of section .text: [0-9a-f]+: d5389a27 mrs x7, pmbptr_el1 [0-9a-f]+: d5189a67 msr pmbsr_el1, x7 [0-9a-f]+: d5389a67 mrs x7, pmbsr_el1 - [0-9a-f]+: d5189ae7 msr pmbidr_el1, x7 - [0-9a-f]+: d5389ae7 mrs x7, pmbidr_el1 [0-9a-f]+: d5189907 msr pmscr_el1, x7 [0-9a-f]+: d5389907 mrs x7, pmscr_el1 [0-9a-f]+: d5189947 msr pmsicr_el1, x7 diff --git a/gas/testsuite/gas/aarch64/sysreg-2.s b/gas/testsuite/gas/aarch64/sysreg-2.s index 2f6ea70..57eb08f 100644 --- a/gas/testsuite/gas/aarch64/sysreg-2.s +++ b/gas/testsuite/gas/aarch64/sysreg-2.s @@ -44,7 +44,7 @@ /* Statistical profiling. */ - .irp reg, pmblimitr_el1, pmbptr_el1, pmbsr_el1 pmbidr_el1 + .irp reg, pmblimitr_el1, pmbptr_el1, pmbsr_el1 rw_sys_reg sys_reg=\reg xreg=x7 r=1 w=1 .endr diff --git a/gas/testsuite/gas/aarch64/sysreg-diagnostic.d b/gas/testsuite/gas/aarch64/sysreg-diagnostic.d new file mode 100644 index 0000000..2f52f36 --- /dev/null +++ b/gas/testsuite/gas/aarch64/sysreg-diagnostic.d @@ -0,0 +1,14 @@ +#objdump: -dr -M notes +#as: -march=armv8-a +#error-output: sysreg-diagnostic.l + +.*: file format .* + +Disassembly of section \.text: + +.* <.*>: +.*: d5130503 msr dbgdtrtx_el0, x3 +.*: d5130503 msr dbgdtrtx_el0, x3 +.*: d5330503 mrs x3, dbgdtrrx_el0 +.*: d5330503 mrs x3, dbgdtrrx_el0 +.*: d5180003 msr midr_el1, x3 ; note: writing to a read-only register\. diff --git a/gas/testsuite/gas/aarch64/sysreg-diagnostic.l b/gas/testsuite/gas/aarch64/sysreg-diagnostic.l new file mode 100644 index 0000000..4566652 --- /dev/null +++ b/gas/testsuite/gas/aarch64/sysreg-diagnostic.l @@ -0,0 +1,4 @@ +.*: Assembler messages: +.*:3: Warning: specified register cannot be written to at operand 1 -- `msr dbgdtrrx_el0,x3' +.*:5: Warning: specified register cannot be read from at operand 2 -- `mrs x3,dbgdtrtx_el0' +.*:6: Warning: specified register cannot be written to at operand 1 -- `msr midr_el1,x3' diff --git a/gas/testsuite/gas/aarch64/sysreg-diagnostic.s b/gas/testsuite/gas/aarch64/sysreg-diagnostic.s new file mode 100644 index 0000000..5f68fe6 --- /dev/null +++ b/gas/testsuite/gas/aarch64/sysreg-diagnostic.s @@ -0,0 +1,6 @@ +.text + msr dbgdtrtx_el0, x3 + msr dbgdtrrx_el0, x3 + mrs x3, dbgdtrrx_el0 + mrs x3, dbgdtrtx_el0 + msr midr_el1, x3 diff --git a/include/ChangeLog b/include/ChangeLog index f9868a2..fe9cad6 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,6 +1,11 @@ 2018-05-15 Tamar Christina <tamar.christina@arm.com> PR binutils/21446 + * opcode/aarch64.h (F_SYS_READ, F_SYS_WRITE): New. + +2018-05-15 Tamar Christina <tamar.christina@arm.com> + + PR binutils/21446 * opcode/aarch64.h (aarch64_operand_error): Add non_fatal. (aarch64_print_operand): Support notes. diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 1c0013e..dc16fe4 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -765,7 +765,11 @@ extern aarch64_opcode aarch64_opcode_table[]; #define F_LSE_SZ (1 << 27) /* Require an exact qualifier match, even for NIL qualifiers. */ #define F_STRICT (1ULL << 28) -/* Next bit is 29. */ +/* This system instruction is used to read system registers. */ +#define F_SYS_READ (1ULL << 29) +/* This system instruction is used to write system registers. */ +#define F_SYS_WRITE (1ULL << 30) +/* Next bit is 31. */ static inline bfd_boolean alias_opcode_p (const aarch64_opcode *opcode) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index a9656a3..6baa67e 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,6 +1,34 @@ 2018-05-15 Tamar Christina <tamar.christina@arm.com> PR binutils/21446 + * aarch64-asm.c (opintl.h): Include. + (aarch64_ins_sysreg): Enforce read/write constraints. + * aarch64-dis.c (aarch64_ext_sysreg): Likewise. + * aarch64-opc.h (F_DEPRECATED, F_ARCHEXT, F_HASXT): Moved here. + (F_REG_READ, F_REG_WRITE): New. + * aarch64-opc.c (aarch64_print_operand): Generate notes for + AARCH64_OPND_SYSREG. + (F_DEPRECATED, F_ARCHEXT, F_HASXT): Move to aarch64-opc.h. + (aarch64_sys_regs): Add constraints to currentel, midr_el1, ctr_el0, + mpidr_el1, revidr_el1, aidr_el1, dczid_el0, id_dfr0_el1, id_pfr0_el1, + id_pfr1_el1, id_afr0_el1, id_mmfr0_el1, id_mmfr1_el1, id_mmfr2_el1, + id_mmfr3_el1, id_mmfr4_el1, id_isar0_el1, id_isar1_el1, id_isar2_el1, + id_isar3_el1, id_isar4_el1, id_isar5_el1, mvfr0_el1, mvfr1_el1, + mvfr2_el1, ccsidr_el1, id_aa64pfr0_el1, id_aa64pfr1_el1, + id_aa64dfr0_el1, id_aa64dfr1_el1, id_aa64isar0_el1, id_aa64isar1_el1, + id_aa64mmfr0_el1, id_aa64mmfr1_el1, id_aa64mmfr2_el1, id_aa64afr0_el1, + id_aa64afr0_el1, id_aa64afr1_el1, id_aa64zfr0_el1, clidr_el1, + csselr_el1, vsesr_el2, erridr_el1, erxfr_el1, rvbar_el1, rvbar_el2, + rvbar_el3, isr_el1, tpidrro_el0, cntfrq_el0, cntpct_el0, cntvct_el0, + mdccsr_el0, dbgdtrrx_el0, dbgdtrtx_el0, osdtrrx_el1, osdtrtx_el1, + mdrar_el1, oslar_el1, oslsr_el1, dbgauthstatus_el1, pmbidr_el1, + pmsidr_el1, pmswinc_el0, pmceid0_el0, pmceid1_el0. + * aarch64-tbl.h (aarch64_opcode_table): Add constraints to + msr (F_SYS_WRITE), mrs (F_SYS_READ). + +2018-05-15 Tamar Christina <tamar.christina@arm.com> + + PR binutils/21446 * aarch64-dis.c (no_notes: New. (parse_aarch64_dis_option): Support notes. (aarch64_decode_insn, print_operands): Likewise. diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c index 67c9b6e..06d428b 100644 --- a/opcodes/aarch64-asm.c +++ b/opcodes/aarch64-asm.c @@ -22,6 +22,7 @@ #include <stdarg.h> #include "libiberty.h" #include "aarch64-asm.h" +#include "opintl.h" /* Utilities. */ @@ -785,6 +786,36 @@ aarch64_ins_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED, const aarch64_inst *inst, aarch64_operand_error *detail ATTRIBUTE_UNUSED) { + /* If a system instruction check if we have any restrictions on which + registers it can use. */ + if (inst->opcode->iclass == ic_system) + { + uint64_t opcode_flags + = inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE); + uint32_t sysreg_flags + = info->sysreg.flags & (F_REG_READ | F_REG_WRITE); + + /* Check to see if it's read-only, else check if it's write only. + if it's both or unspecified don't care. */ + if (opcode_flags == F_SYS_READ + && sysreg_flags + && sysreg_flags != F_REG_READ) + { + detail->kind = AARCH64_OPDE_SYNTAX_ERROR; + detail->error = _("specified register cannot be read from"); + detail->index = info->idx; + detail->non_fatal = TRUE; + } + else if (opcode_flags == F_SYS_WRITE + && sysreg_flags + && sysreg_flags != F_REG_WRITE) + { + detail->kind = AARCH64_OPDE_SYNTAX_ERROR; + detail->error = _("specified register cannot be written to"); + detail->index = info->idx; + detail->non_fatal = TRUE; + } + } /* op0:op1:CRn:CRm:op2 */ insert_fields (code, info->sysreg.value, inst->opcode->mask, 5, FLD_op2, FLD_CRm, FLD_CRn, FLD_op1, FLD_op0); diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index ae53e49..b9c1559 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -1179,7 +1179,22 @@ aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED, /* op0:op1:CRn:CRm:op2 */ info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn, FLD_CRm, FLD_op2); - return 1; + info->sysreg.flags = 0; + + /* If a system instruction, check which restrictions should be on the register + value during decoding, these will be enforced then. */ + if (inst->opcode->iclass == ic_system) + { + /* Check to see if it's read-only, else check if it's write only. + if it's both or unspecified don't care. */ + if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ) + info->sysreg.flags = F_REG_READ; + else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) + == F_SYS_WRITE) + info->sysreg.flags = F_REG_WRITE; + } + + return TRUE; } /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */ 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 }, diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h index 81d045e..f741dea 100644 --- a/opcodes/aarch64-opc.h +++ b/opcodes/aarch64-opc.h @@ -196,6 +196,26 @@ extern const aarch64_operand aarch64_operands[]; #define OPD_F_OD_LSB 5 #define OPD_F_NO_ZR 0x00000100 /* ZR index not allowed. */ +/* Register flags. */ + +#undef F_DEPRECATED +#define F_DEPRECATED (1 << 0) /* Deprecated system register. */ + +#undef F_ARCHEXT +#define F_ARCHEXT (1 << 1) /* Architecture dependent system register. */ + +#undef F_HASXT +#define F_HASXT (1 << 2) /* System instruction register <Xt> + operand. */ + +#undef F_REG_READ +#define F_REG_READ (1 << 3) /* Register can only be used to read values + out of. */ + +#undef F_REG_WRITE +#define F_REG_WRITE (1 << 4) /* Register can only be written to but not + read from. */ + static inline bfd_boolean operand_has_inserter (const aarch64_operand *operand) { diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 36afdd1..1e1b2e4 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -3452,7 +3452,7 @@ struct aarch64_opcode aarch64_opcode_table[] = CORE_INSN ("adr", 0x10000000, 0x9f000000, pcreladdr, 0, OP2 (Rd, ADDR_PCREL21), QL_ADRP, 0), CORE_INSN ("adrp", 0x90000000, 0x9f000000, pcreladdr, 0, OP2 (Rd, ADDR_ADRP), QL_ADRP, 0), /* System. */ - CORE_INSN ("msr", 0xd500401f, 0xfff8f01f, ic_system, 0, OP2 (PSTATEFIELD, UIMM4), {}, 0), + CORE_INSN ("msr", 0xd500401f, 0xfff8f01f, ic_system, 0, OP2 (PSTATEFIELD, UIMM4), {}, F_SYS_WRITE), CORE_INSN ("hint",0xd503201f, 0xfffff01f, ic_system, 0, OP1 (UIMM7), {}, F_HAS_ALIAS), CORE_INSN ("nop", 0xd503201f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), CORE_INSN ("csdb",0xd503229f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), @@ -3477,9 +3477,9 @@ struct aarch64_opcode aarch64_opcode_table[] = CORE_INSN ("dc", 0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_DC, Rt), QL_SRC_X, F_ALIAS), CORE_INSN ("ic", 0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_IC, Rt_SYS), QL_SRC_X, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)), CORE_INSN ("tlbi",0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_TLBI, Rt_SYS), QL_SRC_X, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)), - CORE_INSN ("msr", 0xd5000000, 0xffe00000, ic_system, 0, OP2 (SYSREG, Rt), QL_SRC_X, 0), + 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, 0), + CORE_INSN ("mrs", 0xd5200000, 0xffe00000, ic_system, 0, OP2 (Rt, SYSREG), QL_DST_X, F_SYS_READ), V8_3_INSN ("paciaz", 0xd503231f, 0xffffffff, ic_system, OP0 (), {}, F_ALIAS), V8_3_INSN ("paciasp", 0xd503233f, 0xffffffff, ic_system, OP0 (), {}, F_ALIAS), V8_3_INSN ("pacibz", 0xd503235f, 0xffffffff, ic_system, OP0 (), {}, F_ALIAS), |