diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2021-12-02 15:00:57 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2021-12-02 15:00:57 +0000 |
commit | 63eff947512b36c770c92d45e4b22cb8a18a39be (patch) | |
tree | 336e8d9a01ee6665d9ec7b8148155ee7cab992a0 /opcodes/aarch64-dis.c | |
parent | 6327658ee73502ffb55dfb6b28a20d1dde15a4dc (diff) | |
download | binutils-63eff947512b36c770c92d45e4b22cb8a18a39be.zip binutils-63eff947512b36c770c92d45e4b22cb8a18a39be.tar.gz binutils-63eff947512b36c770c92d45e4b22cb8a18a39be.tar.bz2 |
aarch64: Enforce P/M/E order for MOPS instructions
The MOPS instructions should be used as a triple, such as:
cpyfp [x0]!, [x1]!, x2!
cpyfm [x0]!, [x1]!, x2!
cpyfe [x0]!, [x1]!, x2!
The registers should also be the same for each writeback operand.
This patch adds a warning for code that doesn't follow this rule,
along similar lines to the warning that we already emit for
invalid uses of MOVPRFX.
include/
* opcode/aarch64.h (C_SCAN_MOPS_P, C_SCAN_MOPS_M, C_SCAN_MOPS_E)
(C_SCAN_MOPS_PME): New macros.
(AARCH64_OPDE_A_SHOULD_FOLLOW_B): New aarch64_operand_error_kind.
(AARCH64_OPDE_EXPECTED_A_AFTER_B): Likewise.
(aarch64_operand_error): Make each data value a union between
an int and a string.
opcodes/
* aarch64-tbl.h (MOPS_CPY_OP1_OP2_INSN): Add scan flags.
(MOPS_SET_OP1_OP2_INSN): Likewise.
* aarch64-opc.c (set_out_of_range_error): Update after change to
aarch64_operand_error.
(set_unaligned_error, set_reg_list_error): Likewise.
(init_insn_sequence): Use a 3-instruction sequence for
MOPS P instructions.
(verify_mops_pme_sequence): New function.
(verify_constraints): Call it.
* aarch64-dis.c (print_verifier_notes): Handle
AARCH64_OPDE_A_SHOULD_FOLLOW_B and AARCH64_OPDE_EXPECTED_A_AFTER_B.
gas/
* config/tc-aarch64.c (operand_mismatch_kind_names): Add entries
for AARCH64_OPDE_A_SHOULD_FOLLOW_B and AARCH64_OPDE_EXPECTED_A_AFTER_B.
(operand_error_higher_severity_p): Check that
AARCH64_OPDE_A_SHOULD_FOLLOW_B and AARCH64_OPDE_EXPECTED_A_AFTER_B
come between AARCH64_OPDE_RECOVERABLE and AARCH64_OPDE_SYNTAX_ERROR;
their relative order is not significant.
(record_operand_error_with_data): Update after change to
aarch64_operand_error.
(output_operand_error_record): Likewise. Handle
AARCH64_OPDE_A_SHOULD_FOLLOW_B and AARCH64_OPDE_EXPECTED_A_AFTER_B.
* testsuite/gas/aarch64/mops_invalid_2.s,
testsuite/gas/aarch64/mops_invalid_2.d,
testsuite/gas/aarch64/mops_invalid_2.l: New test.
Diffstat (limited to 'opcodes/aarch64-dis.c')
-rw-r--r-- | opcodes/aarch64-dis.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 8e6123d..fdb87b4 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -3388,10 +3388,29 @@ print_verifier_notes (aarch64_operand_error *detail, assert (detail->non_fatal); assert (detail->error); - /* If there are multiple verifier messages, concat them up to 1k. */ - (*info->fprintf_func) (info->stream, " // note: %s", detail->error); - if (detail->index >= 0) - (*info->fprintf_func) (info->stream, " at operand %d", detail->index + 1); + (*info->fprintf_func) (info->stream, " // note: "); + switch (detail->kind) + { + case AARCH64_OPDE_A_SHOULD_FOLLOW_B: + (*info->fprintf_func) (info->stream, + _("this `%s' should have an immediately" + " preceding `%s'"), + detail->data[0].s, detail->data[1].s); + break; + + case AARCH64_OPDE_EXPECTED_A_AFTER_B: + (*info->fprintf_func) (info->stream, + _("expected `%s' after previous `%s'"), + detail->data[0].s, detail->data[1].s); + break; + + default: + (*info->fprintf_func) (info->stream, "%s", detail->error); + if (detail->index >= 0) + (*info->fprintf_func) (info->stream, " at operand %d", + detail->index + 1); + break; + } } /* Print the instruction according to *INST. */ |