From 63eff947512b36c770c92d45e4b22cb8a18a39be Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 2 Dec 2021 15:00:57 +0000 Subject: 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. --- opcodes/aarch64-tbl.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'opcodes/aarch64-tbl.h') diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 48d2fa8..51d8532 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -2687,10 +2687,15 @@ static const aarch64_feature_set aarch64_feature_mops_memtag = OP3 (MOPS_ADDR_Rd, MOPS_ADDR_Rs, MOPS_WB_Rn), QL_I3SAMEX, \ FLAGS, CONSTRAINTS, VERIFIER (three_different_regs)) +/* These instructions must remain consecutive, since we rely on the order + when detecting invalid sequences. */ #define MOPS_CPY_OP1_OP2_INSN(NAME, SUFFIX, OPCODE, MASK) \ - MOPS_CPY_OP1_OP2_PME_INSN (NAME "p" SUFFIX, OPCODE, MASK, F_SCAN, 0), \ - MOPS_CPY_OP1_OP2_PME_INSN (NAME "m" SUFFIX, OPCODE | 0x400000, MASK, 0, 0), \ - MOPS_CPY_OP1_OP2_PME_INSN (NAME "e" SUFFIX, OPCODE | 0x800000, MASK, 0, 0) + MOPS_CPY_OP1_OP2_PME_INSN (NAME "p" SUFFIX, OPCODE, MASK, F_SCAN, \ + C_SCAN_MOPS_P), \ + MOPS_CPY_OP1_OP2_PME_INSN (NAME "m" SUFFIX, OPCODE | 0x400000, MASK, \ + 0, C_SCAN_MOPS_M), \ + MOPS_CPY_OP1_OP2_PME_INSN (NAME "e" SUFFIX, OPCODE | 0x800000, MASK, \ + 0, C_SCAN_MOPS_E) #define MOPS_CPY_OP1_INSN(NAME, SUFFIX, OPCODE, MASK) \ MOPS_CPY_OP1_OP2_INSN (NAME, SUFFIX, OPCODE, MASK), \ @@ -2709,12 +2714,15 @@ static const aarch64_feature_set aarch64_feature_mops_memtag = OP3 (MOPS_ADDR_Rd, MOPS_WB_Rn, Rm), QL_I3SAMEX, FLAGS, \ CONSTRAINTS, VERIFIER (three_different_regs)) +/* These instructions must remain consecutive, since we rely on the order + when detecting invalid sequences. */ #define MOPS_SET_OP1_OP2_INSN(NAME, SUFFIX, OPCODE, MASK, ISA) \ - MOPS_SET_OP1_OP2_PME_INSN (NAME "p" SUFFIX, OPCODE, MASK, 0, 0, ISA), \ + MOPS_SET_OP1_OP2_PME_INSN (NAME "p" SUFFIX, OPCODE, MASK, \ + F_SCAN, C_SCAN_MOPS_P, ISA), \ MOPS_SET_OP1_OP2_PME_INSN (NAME "m" SUFFIX, OPCODE | 0x4000, MASK, \ - 0, 0, ISA), \ + 0, C_SCAN_MOPS_M, ISA), \ MOPS_SET_OP1_OP2_PME_INSN (NAME "e" SUFFIX, OPCODE | 0x8000, MASK, \ - 0, 0, ISA) + 0, C_SCAN_MOPS_E, ISA) #define MOPS_SET_INSN(NAME, OPCODE, MASK, ISA) \ MOPS_SET_OP1_OP2_INSN (NAME, "", OPCODE, MASK, ISA), \ -- cgit v1.1