[PATCH v2] aarch64: Add support for FEAT_CMH
richard.ball@arm.com
richard.ball@arm.com
Thu Jan 15 15:33:32 GMT 2026
From: Richard Ball <Richard.Ball@arm.com>
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 7b0d5d22b0c..2017f86727d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -4618,7 +4618,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;
@@ -6435,6 +6437,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;
@@ -8308,6 +8311,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 b885a06f526..dff8e927bc8 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -759,6 +759,7 @@ enum aarch64_opnd
AARCH64_OPND_BARRIER_GCSB, /* Barrier operand for GCSB. */
AARCH64_OPND_BTI_TARGET, /* BTI {<target>}. */
AARCH64_OPND_STSHH_POLICY, /* STSHH {<policy>}. */
+ 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 <Xt1>. */
@@ -1890,6 +1891,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 ca2c939d5b2..8e8cbf43d18 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;
@@ -1035,6 +1037,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 9dcb83fefac..9aeb3df19b2 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:
@@ -38017,6 +38023,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 4f447aef78f..439ddda65ab 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -154,6 +154,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 e4ce347bdc9..d42f37c0134 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 },
};
@@ -5178,6 +5182,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 (strcmp(opnd->hint_option->name, " ") != 0)
+ 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 e9bc188c69f..64e79d709d5 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 82b3e9dd2ce..bc456ccbd41 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -5098,6 +5098,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),
@@ -8162,6 +8164,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), \
--
2.34.1
More information about the Binutils
mailing list