From 19ffb6d2d7c2bbc8c2cb1de480bc8f1ccff52445 Mon Sep 17 00:00:00 2001 From: Richard Ball Date: Fri, 16 Jan 2026 12:35:29 +0000 Subject: [PATCH] aarch64: Add support for FEAT_CMH This patch adds the new instructions from FEAT_CMH These new instructions are hints, STCPH and SHUH. SHUH can have an operand PH or no operand. --- gas/config/tc-aarch64.c | 6 +++++- gas/testsuite/gas/aarch64/cmh-bad.d | 4 ++++ gas/testsuite/gas/aarch64/cmh-bad.l | 3 +++ gas/testsuite/gas/aarch64/cmh-bad.s | 3 +++ gas/testsuite/gas/aarch64/cmh.d | 11 +++++++++++ gas/testsuite/gas/aarch64/cmh.s | 4 ++++ gas/testsuite/gas/aarch64/system.d | 6 +++--- include/opcode/aarch64.h | 3 +++ opcodes/aarch64-asm-2.c | 3 +++ opcodes/aarch64-dis-2.c | 7 +++++++ opcodes/aarch64-opc-2.c | 1 + opcodes/aarch64-opc.c | 12 +++++++++++- opcodes/aarch64-tbl-2.h | 2 ++ opcodes/aarch64-tbl.h | 4 ++++ 14 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/cmh-bad.d create mode 100644 gas/testsuite/gas/aarch64/cmh-bad.l create mode 100644 gas/testsuite/gas/aarch64/cmh-bad.s create mode 100644 gas/testsuite/gas/aarch64/cmh.d create mode 100644 gas/testsuite/gas/aarch64/cmh.s diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 8a1638e00ae..61bd81ca0b6 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -4619,7 +4619,9 @@ parse_hint_opt (const char *name, char **str, && (o->value != HINT_OPD_C && o->value != HINT_OPD_J && o->value != HINT_OPD_JC && o->value != HINT_OPD_R)) || ((strcmp ("stshh", name) == 0) - && (o->value != HINT_OPD_KEEP && o->value != HINT_OPD_STRM))) + && (o->value != HINT_OPD_KEEP && o->value != HINT_OPD_STRM)) + || ((strcmp ("shuh", name) == 0) + && (o->value != HINT_OPD_PHINT))) return false; *str = q; @@ -6436,6 +6438,7 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode, break; case AARCH64_OPND_BTI_TARGET: + case AARCH64_OPND_SHUH_PHINT: operand->hint_option = aarch64_hint_options + default_value; break; @@ -8314,6 +8317,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) break; case AARCH64_OPND_BTI_TARGET: + case AARCH64_OPND_SHUH_PHINT: if (!parse_hint_opt (opcode->name, &str, &(info->hint_option))) goto failure; break; diff --git a/gas/testsuite/gas/aarch64/cmh-bad.d b/gas/testsuite/gas/aarch64/cmh-bad.d new file mode 100644 index 00000000000..c68620add61 --- /dev/null +++ b/gas/testsuite/gas/aarch64/cmh-bad.d @@ -0,0 +1,4 @@ +#name: Negative test of CMH instructions. +#as: -march=armv8-a +#source: cmh-bad.s +#error_output: cmh-bad.l diff --git a/gas/testsuite/gas/aarch64/cmh-bad.l b/gas/testsuite/gas/aarch64/cmh-bad.l new file mode 100644 index 00000000000..542f312bb41 --- /dev/null +++ b/gas/testsuite/gas/aarch64/cmh-bad.l @@ -0,0 +1,3 @@ +[^ :]+: Assembler messages: +[^ :]+:[0-9]+: Error: operand 1 must be an optional priority hint \(ph\) -- `shuh p' +[^ :]+:[0-9]+: Error: unexpected characters following instruction -- `stcph ph' diff --git a/gas/testsuite/gas/aarch64/cmh-bad.s b/gas/testsuite/gas/aarch64/cmh-bad.s new file mode 100644 index 00000000000..eed46a4ff06 --- /dev/null +++ b/gas/testsuite/gas/aarch64/cmh-bad.s @@ -0,0 +1,3 @@ +a: + shuh p + stcph ph diff --git a/gas/testsuite/gas/aarch64/cmh.d b/gas/testsuite/gas/aarch64/cmh.d new file mode 100644 index 00000000000..3a9f143cbde --- /dev/null +++ b/gas/testsuite/gas/aarch64/cmh.d @@ -0,0 +1,11 @@ +#as: -march=armv8-a +#objdump: -dr + +.*: file format .* + +Disassembly of section \.text: + +0+ <.*>: +.*: d503265f shuh +.*: d503267f shuh ph +.*: d503269f stcph diff --git a/gas/testsuite/gas/aarch64/cmh.s b/gas/testsuite/gas/aarch64/cmh.s new file mode 100644 index 00000000000..0045c8ade17 --- /dev/null +++ b/gas/testsuite/gas/aarch64/cmh.s @@ -0,0 +1,4 @@ +a: + shuh + shuh ph + stcph diff --git a/gas/testsuite/gas/aarch64/system.d b/gas/testsuite/gas/aarch64/system.d index 6d90420d539..11498317e66 100644 --- a/gas/testsuite/gas/aarch64/system.d +++ b/gas/testsuite/gas/aarch64/system.d @@ -68,9 +68,9 @@ Disassembly of section \.text: .*: d50325ff hint #0x2f .*: d503261f (hint #0x30|stshh keep) .*: d503263f (hint #0x31|stshh strm) -.*: d503265f hint #0x32 -.*: d503267f hint #0x33 -.*: d503269f hint #0x34 +.*: d503265f (hint #0x32|shuh) +.*: d503267f (hint #0x33|shuh ph) +.*: d503269f (hint #0x34|stcph) .*: d50326bf hint #0x35 .*: d50326df hint #0x36 .*: d50326ff hint #0x37 diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 16d8d1b9cd9..4a38953ea57 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -762,6 +762,7 @@ enum aarch64_opnd AARCH64_OPND_BARRIER_GCSB, /* Barrier operand for GCSB. */ AARCH64_OPND_BTI_TARGET, /* BTI {}. */ AARCH64_OPND_STSHH_POLICY, /* STSHH {}. */ + AARCH64_OPND_SHUH_PHINT, /* SHUH Priority Hint. */ AARCH64_OPND_BRBOP, /* BRB operation IALL or INJ in bit 5. */ AARCH64_OPND_Rt_IN_SYS_ALIASES, /* Defaulted and omitted Rt used in SYS aliases such as brb. */ AARCH64_OPND_LSE128_Rt, /* LSE128 . */ @@ -1894,6 +1895,8 @@ struct aarch64_inst #define HINT_OPD_JC 0x26 #define HINT_OPD_KEEP 0x30 #define HINT_OPD_STRM 0x31 +#define HINT_OPD_NPHINT 0x32 +#define HINT_OPD_PHINT 0x33 #define HINT_OPD_NULL 0x00 diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c index f166ca4e1a8..4dff5ea4993 100644 --- a/opcodes/aarch64-asm-2.c +++ b/opcodes/aarch64-asm-2.c @@ -543,6 +543,8 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode) case A64_OPID_d503241f_bti_BTI_TARGET: case A64_OPID_d503229f_csdb: case A64_OPID_d503201f_nop: + case A64_OPID_d503265f_shuh_SHUH_PHINT: + case A64_OPID_d503269f_stcph: case A64_OPID_d503261f_stshh_STSHH_POLICY: case A64_OPID_d503201f_hint_UIMM7: value = A64_OPID_d503201f_hint_UIMM7; @@ -1037,6 +1039,7 @@ aarch64_insert_operand (const aarch64_operand *self, return aarch64_ins_prfop (self, info, code, inst, errors); case AARCH64_OPND_BTI_TARGET: case AARCH64_OPND_STSHH_POLICY: + case AARCH64_OPND_SHUH_PHINT: return aarch64_ins_hint (self, info, code, inst, errors); case AARCH64_OPND_SVE_ADDR_RI_S4x16: case AARCH64_OPND_SVE_ADDR_RI_S4x32: diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c index 3f61936e398..0938f4a846a 100644 --- a/opcodes/aarch64-dis-2.c +++ b/opcodes/aarch64-dis-2.c @@ -37534,6 +37534,12 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode) value = A64_OPID_d503201f_nop; break; case A64_OPID_d503201f_nop: + value = A64_OPID_d503265f_shuh_SHUH_PHINT; + break; + case A64_OPID_d503265f_shuh_SHUH_PHINT: + value = A64_OPID_d503269f_stcph; + break; + case A64_OPID_d503269f_stcph: value = A64_OPID_d503261f_stshh_STSHH_POLICY; break; case A64_OPID_d503261f_stshh_STSHH_POLICY: @@ -38021,6 +38027,7 @@ aarch64_extract_operand (const aarch64_operand *self, return aarch64_ext_prfop (self, info, code, inst, errors); case AARCH64_OPND_BTI_TARGET: case AARCH64_OPND_STSHH_POLICY: + case AARCH64_OPND_SHUH_PHINT: return aarch64_ext_hint (self, info, code, inst, errors); case AARCH64_OPND_SVE_ADDR_RI_S4x16: case AARCH64_OPND_SVE_ADDR_RI_S4x32: diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c index 9c5ac08ed96..85b763f9766 100644 --- a/opcodes/aarch64-opc-2.c +++ b/opcodes/aarch64-opc-2.c @@ -155,6 +155,7 @@ const struct aarch64_operand aarch64_operands[] = {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_GCSB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the GCSB option name DSYNC"}, {AARCH64_OPND_CLASS_SYSTEM, "BTI_TARGET", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "BTI targets r/j/c/jc"}, {AARCH64_OPND_CLASS_SYSTEM, "STSHH_POLICY", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "an STSHH policy (keep/strm)"}, + {AARCH64_OPND_CLASS_SYSTEM, "SHUH_PHINT", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "an optional priority hint (ph)"}, {AARCH64_OPND_CLASS_SYSTEM, "BRBOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_brbop}, "Branch Record Buffer operation operand"}, {AARCH64_OPND_CLASS_INT_REG, "Rt_IN_SYS_ALIASES", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rt}, "Rt register with defaults for SYS aliases"}, {AARCH64_OPND_CLASS_INT_REG, "LSE128_Rt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_LSE128_Rt}, "an integer register"}, diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index df6b5fd0790..e3fbb4f5257 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -597,8 +597,11 @@ const struct aarch64_name_value_pair aarch64_barrier_dsb_nxs_options[4] = const struct aarch64_name_value_pair aarch64_hint_options[] = { - /* BTI. This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET. */ + /* BTI. This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET. + BTI R and SHUH must be the first and second entries respectively + so that F_DEFAULT refers to the correct table entries. */ { "r", HINT_OPD_R }, /* BTI R. */ + { "", HINT_OPD_NPHINT}, /* SHUH. */ { "csync", HINT_OPD_CSYNC }, /* PSB CSYNC. */ { "dsync", HINT_OPD_DSYNC }, /* GCSB DSYNC. */ { "c", HINT_OPD_C }, /* BTI C. */ @@ -606,6 +609,7 @@ const struct aarch64_name_value_pair aarch64_hint_options[] = { "jc", HINT_OPD_JC }, /* BTI JC. */ { "keep", HINT_OPD_KEEP }, /* STSHH KEEP */ { "strm", HINT_OPD_STRM }, /* STSHH STRM */ + { "ph", HINT_OPD_PHINT }, /* SHUH PH. */ { NULL, HINT_OPD_NULL }, }; @@ -5179,6 +5183,12 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name)); break; + case AARCH64_OPND_SHUH_PHINT: + if (*(opnd->hint_option->name)) + snprintf (buf, size, "%s", + style_sub_mnem (styler, opnd->hint_option->name)); + break; + case AARCH64_OPND_MOPS_ADDR_Rd: case AARCH64_OPND_MOPS_ADDR_Rs: snprintf (buf, size, "[%s]!", diff --git a/opcodes/aarch64-tbl-2.h b/opcodes/aarch64-tbl-2.h index d3399bbf5ec..ee96b332794 100644 --- a/opcodes/aarch64-tbl-2.h +++ b/opcodes/aarch64-tbl-2.h @@ -1368,6 +1368,8 @@ enum aarch64_opcode_idx A64_OPID_d503407f_smstop_SME_SM_ZA, A64_OPID_d503251f_chkfeat_X16, A64_OPID_d503261f_stshh_STSHH_POLICY, + A64_OPID_d503269f_stcph, + A64_OPID_d503265f_shuh_SHUH_PHINT, A64_OPID_d500401f_msr_PSTATEFIELD_UIMM4, A64_OPID_d503201f_hint_UIMM7, A64_OPID_d503201f_nop, diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 0451585bfc4..72d9d0ab3b3 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -5103,6 +5103,8 @@ const struct aarch64_opcode aarch64_opcode_table[] = /* System. */ CHK_INSN ("chkfeat", 0xd503251f, 0xffffffff, OP1 (X16), QL_I1X, 0), CORE_INSN ("stshh", 0xd503261f, 0xffffffdf, ic_system, 0, OP1 (STSHH_POLICY), {}, F_ALIAS), + CORE_INSN ("stcph", 0xd503269f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), + CORE_INSN ("shuh", 0xd503265f, 0xffffffdf, ic_system, 0, OP1 (SHUH_PHINT), {}, F_ALIAS | F_OPD0_OPT | F_DEFAULT (0x1)), CORE_INSN ("msr", 0xd500401f, 0xfff8f01f, ic_system, 0, OP2 (PSTATEFIELD, UIMM4), {}, F_SYS_WRITE), CORE_INSN ("hint",0xd503201f, 0xfffff01f, ic_system, 0, OP1 (UIMM7), {}, F_HAS_ALIAS), CORE_INSN ("nop", 0xd503201f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), @@ -8170,6 +8172,8 @@ const struct aarch64_opcode aarch64_opcode_table[] = "BTI targets r/j/c/jc") \ Y(SYSTEM, hint, "STSHH_POLICY", 0, F(), \ "an STSHH policy (keep/strm)") \ + Y(SYSTEM, hint, "SHUH_PHINT", 0, F(), \ + "an optional priority hint (ph)") \ Y(SYSTEM, imm, "BRBOP", 0, F(FLD_brbop), \ "Branch Record Buffer operation operand") \ Y(INT_REG, regno, "Rt_IN_SYS_ALIASES", 0, F(FLD_Rt), \