From 5517af829887ba3b19a3f372b6b60e8098bdfa29 Mon Sep 17 00:00:00 2001 From: Victor Do Nascimento Date: Mon, 20 Nov 2023 15:32:15 +0000 Subject: [PATCH] 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. --- gas/config/tc-aarch64.c | 18 +++++++++++++++++- gas/testsuite/gas/aarch64/illegal-sys128.d | 3 +++ gas/testsuite/gas/aarch64/sysp.d | 10 ++++++++++ gas/testsuite/gas/aarch64/sysp.s | 4 ++++ include/opcode/aarch64.h | 7 ++++++- opcodes/aarch64-tbl.h | 2 +- 6 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/illegal-sys128.d create mode 100644 gas/testsuite/gas/aarch64/sysp.d create mode 100644 gas/testsuite/gas/aarch64/sysp.s diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 29535e7..539bfa2 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -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; diff --git a/gas/testsuite/gas/aarch64/illegal-sys128.d b/gas/testsuite/gas/aarch64/illegal-sys128.d new file mode 100644 index 0000000..891b934 --- /dev/null +++ b/gas/testsuite/gas/aarch64/illegal-sys128.d @@ -0,0 +1,3 @@ +#name: Out-of-bounds SYSP operand tests +#source: illegal-sys128.s +#error_output: illegal-sys128.l diff --git a/gas/testsuite/gas/aarch64/sysp.d b/gas/testsuite/gas/aarch64/sysp.d new file mode 100644 index 0000000..80286c1 --- /dev/null +++ b/gas/testsuite/gas/aarch64/sysp.d @@ -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 \ No newline at end of file diff --git a/gas/testsuite/gas/aarch64/sysp.s b/gas/testsuite/gas/aarch64/sysp.s new file mode 100644 index 0000000..f50d3ab --- /dev/null +++ b/gas/testsuite/gas/aarch64/sysp.s @@ -0,0 +1,4 @@ + .arch armv9.4-a+d128 + + sysp #0, C8, C0, #0, x0, x1 + sysp #6, C9, C7, #7, x26, x27 diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 854bb74..b81475f 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -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. */ diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 739e78b..3f1b388 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -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)), -- 2.7.4