aboutsummaryrefslogtreecommitdiff
path: root/opcodes/aarch64-dis.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2021-12-02 15:00:57 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2021-12-02 15:00:57 +0000
commit63eff947512b36c770c92d45e4b22cb8a18a39be (patch)
tree336e8d9a01ee6665d9ec7b8148155ee7cab992a0 /opcodes/aarch64-dis.c
parent6327658ee73502ffb55dfb6b28a20d1dde15a4dc (diff)
downloadbinutils-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.c27
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. */