Implement Read/Write constraints on system registers on AArch64

This patch adds constraints for read and write only system registers with the
msr and mrs instructions.  The code will treat having both flags set and none
set as the same.  These flags add constraints that must be matched up. e.g. a
system register with a READ only flag set, can only be used with mrs.  If The
constraint fails a warning is emitted.

Examples of the warnings generated:

test.s: Assembler messages:
test.s:5: Warning: specified register cannot be written to at operand 1 -- `msr dbgdtrrx_el0,x3'
test.s:7: Warning: specified register cannot be read from at operand 2 -- `mrs x3,dbgdtrtx_el0'
test.s:8: Warning: specified register cannot be written to at operand 1 -- `msr midr_el1,x3'

and disassembly notes:

0000000000000000 <main>:
   0:	d5130503 	msr	dbgdtrtx_el0, x3
   4:	d5130503 	msr	dbgdtrtx_el0, x3
   8:	d5330503 	mrs	x3, dbgdtrrx_el0
   c:	d5330503 	mrs	x3, dbgdtrrx_el0
  10:	d5180003 	msr	midr_el1, x3	; note: writing to a read-only register.

Note that because dbgdtrrx_el0 and dbgdtrtx_el0 have the same encoding, during
disassembly the constraints are use to disambiguate between the two.  An exact
constraint match is always prefered over partial ones if available.

As always the warnings can be suppressed with -w and also be made errors using
warnings as errors.

binutils/

	PR binutils/21446
	* doc/binutils.texi (-M): Document AArch64 options.

gas/

	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.

include/

	PR binutils/21446
	* opcode/aarch64.h (F_SYS_READ, F_SYS_WRITE): New.

opcodes/

	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).
This commit is contained in:
Tamar Christina 2018-05-15 16:37:20 +01:00
parent 7d02540ab7
commit f9830ec165
16 changed files with 247 additions and 100 deletions

View File

@ -1,3 +1,8 @@
2018-05-15 Tamar Christina <tamar.christina@arm.com>
PR binutils/21446
* doc/binutils.texi (-M): Document AArch64 options.
2018-05-15 Tamar Christina <tamar.christina@arm.com>
PR binutils/21446

View File

@ -1,3 +1,13 @@
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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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\.

View File

@ -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'

View File

@ -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

View File

@ -1,3 +1,8 @@
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

View File

@ -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)

View File

@ -1,3 +1,31 @@
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

View File

@ -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);

View File

@ -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>. */

View File

@ -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 },

View File

@ -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)
{

View File

@ -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),