diff options
-rw-r--r-- | gas/config/tc-aarch64.c | 18 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/illegal-sys128.d | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysp.d | 10 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/sysp.s | 4 | ||||
-rw-r--r-- | include/opcode/aarch64.h | 7 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 2 |
6 files changed, 41 insertions, 3 deletions
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)), |