aarch64: Apply narrowing of allowed immediate values for SYSP

While CRn and CRm fields in the SYSP instruction are 4-bit wide and
are thus able to accommodate values in the range 0-15, the
specifications for the SYSP instructions limit their ranges to 8-9 for
CRm and 0-7 in the case of CRn.

This led to the need to signal in some way to the operand parser that
a given operand is under special restrictions regarding its use.  This
is done via the new `F_OPD_NARROW' flag, indicating a narrowing in the
range of operand values for fields in the instruction tagged with the
flag.

The flag is then used in `parse_operands' when the instruction is
assembled, but needs not be taken into consideration during
disassembly.
This commit is contained in:
Victor Do Nascimento 2023-11-20 15:32:15 +00:00
parent 3521a28f10
commit 5517af8298
6 changed files with 41 additions and 3 deletions

View File

@ -6474,6 +6474,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
int i;
char *backtrack_pos = 0;
const enum aarch64_opnd *operands = opcode->operands;
const uint64_t flags = opcode->flags;
aarch64_reg_type imm_reg_type;
clear_error ();
@ -6822,7 +6823,22 @@ parse_operands (char *str, const aarch64_opcode *opcode)
goto failure;
po_imm_nc_or_fail ();
if (val > 15)
if (flags & F_OPD_NARROW)
{
if ((operands[i] == AARCH64_OPND_CRn)
&& (val < 8 || val > 9))
{
set_fatal_syntax_error (_(N_ ("C8 - C9 expected")));
goto failure;
}
else if ((operands[i] == AARCH64_OPND_CRm)
&& (val > 7))
{
set_fatal_syntax_error (_(N_ ("C0 - C7 expected")));
goto failure;
}
}
else if (val > 15)
{
set_fatal_syntax_error (_(N_ ("C0 - C15 expected")));
goto failure;

View File

@ -0,0 +1,3 @@
#name: Out-of-bounds SYSP operand tests
#source: illegal-sys128.s
#error_output: illegal-sys128.l

View File

@ -0,0 +1,10 @@
#objdump: -dr
.*
Disassembly of section \.text:
0+ <\.text>:
[^:]*: d5488000 sysp #0, C8, C0, #0, x0, x1
[^:]*: d54e97fa sysp #6, C9, C7, #7, x26, x27

View File

@ -0,0 +1,4 @@
.arch armv9.4-a+d128
sysp #0, C8, C0, #0, x0, x1
sysp #6, C9, C7, #7, x26, x27

View File

@ -1224,7 +1224,12 @@ extern const aarch64_opcode aarch64_opcode_table[];
to be optional, then we also implicitly specify (N+1)th operand to also be
optional. */
#define F_OPD_PAIR_OPT (1ULL << 32)
/* Next bit is 33. */
/* This instruction does not allow the full range of values that the
width of fields in the assembler instruction would theoretically
allow. This impacts the constraintts on assembly but yelds no
impact on disassembly. */
#define F_OPD_NARROW (1ULL << 33)
/* Next bit is 34. */
/* Instruction constraints. */
/* This instruction has a predication constraint on the instruction at PC+4. */

View File

@ -4201,7 +4201,7 @@ const struct aarch64_opcode aarch64_opcode_table[] =
GCS_INSN ("gcssttr", 0xd91f1c00, 0xfffffc00, OP2 (Rt, Rn_SP), QL_I2SAMEX, 0),
CORE_INSN ("gcsb", 0xd503227f, 0xffffffff, ic_system, 0, OP1 (BARRIER_GCSB), {}, F_ALIAS),
CORE_INSN ("sys", 0xd5080000, 0xfff80000, ic_system, 0, OP5 (UIMM3_OP1, CRn, CRm, UIMM3_OP2, Rt), QL_SYS, F_HAS_ALIAS | F_OPD4_OPT | F_DEFAULT (0x1F)),
D128_INSN ("sysp", 0xd5480000, 0xfff80000, OP6 (UIMM3_OP1, CRn, CRm, UIMM3_OP2, Rt, PAIRREG_OR_XZR), QL_SYSP, F_HAS_ALIAS | F_OPD4_OPT | F_OPD_PAIR_OPT | F_DEFAULT (0x1f)),
D128_INSN ("sysp", 0xd5480000, 0xfff80000, OP6 (UIMM3_OP1, CRn, CRm, UIMM3_OP2, Rt, PAIRREG_OR_XZR), QL_SYSP, F_HAS_ALIAS | F_OPD_NARROW | F_OPD4_OPT | F_OPD_PAIR_OPT | F_DEFAULT (0x1f)),
CORE_INSN ("at", 0xd5080000, 0xfff80000, ic_system, 0, OP2 (SYSREG_AT, Rt), QL_SRC_X, F_ALIAS),
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)),