[PATCH v2] x86: Support BHI_CTRL instruction
Haochen Jiang
haochen.jiang@intel.com
Tue Sep 8 07:42:13 GMT 2026
Resend this since I wrongly sent it to gcc-patches.
Hi all,
I just get the clarification that for ibhf, both rex.w and rex2.w took
the same effect. Thus, it will not cause extra burden from software side.
I have added REX2 test for BHI_CTRL to explicitly show that.
The info will show up in 26'Q4 SDM, which will happen end of the year.
Since it is quite late to catch up with the 2.48 release, we will send
out the patch with that explicitly mentioned.
Ok for trunk?
Thx,
Haochen
---
Changes in v2:
- Add rex2 tests for BHI_CTRL.
- Add x64 in i386-opc.tbl instead of implying in i386-gen.c
---
BHI_CTRL is an ISA with only one instruction ibhf. The following tech paper
is published in May, 2025:
https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html#ibhf
As shown in the paper, The encoding is F3 48 0F 1E F8, showing it is
using REX.W. Actually, REX2.W is also allowed for this instruction.
Thus, it is not a fixed encoding. The info will show up in 26'Q4 SDM.
I added a Fixup for disassembler since we need to keep the same behavior
for other nop encodings.
gas/ChangeLog:
* NEWS: Mention BHI_CTRL.
* config/tc-i386.c: Add .bhi_ctrl.
* testsuite/gas/i386/x86-64.exp: Add BHI_CTRL tests.
* testsuite/gas/i386/x86-64-bhi-ctrl-intel.d: New test.
* testsuite/gas/i386/x86-64-bhi-ctrl.d: Ditto.
* testsuite/gas/i386/x86-64-bhi-ctrl.s: Ditto.
opcodes/ChangeLog:
* i386-dis.c: (RM_0F1E_P_1_MOD_3_REG_7): Adjust for ibhf.
(IBHF_Fixup): New. Revert mnemonic back to repz nop for ~REX_W.
* i386-gen.c: (cpu_flags): Add BHI_CTRL.
* i386-opc.h (enum i386_cpu): Ditto.
(i386_cpu_flags): Ditto.
* i386-opc.tbl: Add BHI_CTRL instruction.
* i386-init.h: Regenerated.
* i386-mnem.h: Ditto.
* i386-tbl.h: Ditto.
---
gas/NEWS | 2 +
gas/config/tc-i386.c | 1 +
.../gas/i386/x86-64-bhi-ctrl-intel.d | 13 +
gas/testsuite/gas/i386/x86-64-bhi-ctrl.d | 11 +
gas/testsuite/gas/i386/x86-64-bhi-ctrl.s | 11 +
gas/testsuite/gas/i386/x86-64.exp | 2 +
opcodes/i386-dis.c | 21 +-
opcodes/i386-gen.c | 1 +
opcodes/i386-init.h | 913 +++---
opcodes/i386-mnem.h | 2699 +++++++++--------
opcodes/i386-opc.h | 3 +
opcodes/i386-opc.tbl | 6 +
opcodes/i386-tbl.h | 1244 ++++----
13 files changed, 2508 insertions(+), 2419 deletions(-)
create mode 100644 gas/testsuite/gas/i386/x86-64-bhi-ctrl-intel.d
create mode 100644 gas/testsuite/gas/i386/x86-64-bhi-ctrl.d
create mode 100644 gas/testsuite/gas/i386/x86-64-bhi-ctrl.s
diff --git a/gas/NEWS b/gas/NEWS
index 8b07d86daa3..d141046a014 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the x86 BHI_CTRL instruction.
+
* Add support for the x86 AVX10_V2_AUX instructions.
* The avr target supports .gnu_attribute 4 (Tag_GNU_AVR_VTABLE_AS).
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ce9cc8236fa..16d0805d1a6 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1272,6 +1272,7 @@ static const arch_entry cpu_arch[] =
SUBARCH (padlockphe2, PADLOCKPHE2, PADLOCKPHE2, false),
SUBARCH (padlockxmodx, PADLOCKXMODX, PADLOCKXMODX, false),
SUBARCH (movrs, MOVRS, MOVRS, false),
+ SUBARCH (bhi_ctrl, BHI_CTRL, BHI_CTRL, false),
};
#undef SUBARCH
diff --git a/gas/testsuite/gas/i386/x86-64-bhi-ctrl-intel.d b/gas/testsuite/gas/i386/x86-64-bhi-ctrl-intel.d
new file mode 100644
index 00000000000..32933660014
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl-intel.d
@@ -0,0 +1,13 @@
+#objdump: -dw
+#name: x86_64 BHI_CTRL insns (Intel disassembly)
+#source: x86-64-bhi-ctrl.s
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+#...
+[a-f0-9]+ <_intel>:
+\s*[a-f0-9]+:\s*f3 48 0f 1e f8\s+ibhf
+\s*[a-f0-9]+:\s*f3 d5 88 1e f8\s+{rex2 0x88} ibhf
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-bhi-ctrl.d b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.d
new file mode 100644
index 00000000000..fae6f558210
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.d
@@ -0,0 +1,11 @@
+#objdump: -dw
+#name: x86_64 BHI_CTRL insns
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+0+ <_start>:
+\s*[a-f0-9]+:\s*f3 48 0f 1e f8\s+ibhf
+\s*[a-f0-9]+:\s*f3 d5 88 1e f8\s+{rex2 0x88} ibhf
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-bhi-ctrl.s b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.s
new file mode 100644
index 00000000000..9e1c1920ea0
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.s
@@ -0,0 +1,11 @@
+# Check 64bit BHI_CTRL instructions
+
+ .text
+_start:
+ ibhf
+ {rex2} ibhf
+
+_intel:
+ .intel_syntax noprefix
+ ibhf
+ {rex2} ibhf
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index eb10d9b8b9f..921cafbda1a 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -554,6 +554,8 @@ run_dump_test "x86-64-movrs-avx10_2-512"
run_dump_test "x86-64-movrs-avx10_2-512-intel"
run_dump_test "x86-64-movrs-avx10_2-256"
run_dump_test "x86-64-movrs-avx10_2-256-intel"
+run_dump_test "x86-64-bhi-ctrl"
+run_dump_test "x86-64-bhi-ctrl-intel"
run_dump_test "x86-64-clzero"
run_dump_test "x86-64-mwaitx-bdver4"
run_list_test "x86-64-mwaitx-reg"
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index ec1d149d9dc..12ffc597fd2 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -109,6 +109,7 @@ static bool PREFETCHI_Fixup (instr_info *, int, int);
static bool PUSH2_POP2_Fixup (instr_info *, int, int);
static bool JMPABS_Fixup (instr_info *, int, int);
static bool CFCMOV_Fixup (instr_info *, int, int);
+static bool IBHF_Fixup (instr_info *, int, int);
static void ATTRIBUTE_PRINTF_3 i386_dis_printf (const disassemble_info *,
enum disassembler_style,
@@ -8793,7 +8794,7 @@ static const struct dis386 rm_table[][8] = {
},
{
/* RM_0F1E_P_1_MOD_3_REG_7 */
- { "nopQ", { Ev }, PREFIX_IGNORED },
+ { "ibhf", { IBHF_Fixup }, 0 },
{ "nopQ", { Ev }, PREFIX_IGNORED },
{ "endbr64", { Skip_MODRM }, 0 },
{ "endbr32", { Skip_MODRM }, 0 },
@@ -14723,3 +14724,21 @@ CFCMOV_Fixup (instr_info *ins, int opnd, int sizeflag)
return OP_G (ins, v_mode, sizeflag);
return OP_E (ins, v_mode, sizeflag);
}
+
+static bool
+IBHF_Fixup (instr_info *ins, int bytemode, int sizeflag)
+{
+ if (!(ins->rex & REX_W))
+ {
+ ins->mnemonicendp = stpcpy (ins->obuf, "repz nop");
+ return OP_E (ins, v_mode, sizeflag);
+ }
+ else
+ {
+ USED_REX (REX_W);
+ MODRM_CHECK;
+ ins->codep++;
+ ins->has_skipped_modrm = true;
+ return true;
+ }
+}
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index cf37d8786e9..1691abb9bfb 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -462,6 +462,7 @@ static bitfield cpu_flags[] =
BITFIELD (AVX10_2),
BITFIELD (AVX10_V2_AUX),
BITFIELD (MOVRS),
+ BITFIELD (BHI_CTRL),
BITFIELD (MWAITX),
BITFIELD (CLZERO),
BITFIELD (OSPKE),
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index cd8f228f5a9..e449f84e00b 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -247,6 +247,8 @@ enum i386_cpu
CpuMSR_IMM,
/* Intel MOVRS Instructions support required. */
CpuMOVRS,
+ /* Intel BHI_CTRL instruction support required. */
+ CpuBHI_CTRL,
/* mwaitx instruction required */
CpuMWAITX,
/* Clzero instruction required */
@@ -536,6 +538,7 @@ typedef union i386_cpu_flags
unsigned int cpuuser_msr:1;
unsigned int cpumsr_imm:1;
unsigned int cpumovrs:1;
+ unsigned int cpubhi_ctrl:1;
unsigned int cpumwaitx:1;
unsigned int cpuclzero:1;
unsigned int cpuospke:1;
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 8ff7bf1828e..94232636b0c 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3685,3 +3685,9 @@ vmovrs<bw>, 0xf26f, AVX10_2&MOVRS&x64, Modrm|Masking|Map5|<bw:vexw>|Disp8ShiftVL
vmovrs<dq>, 0xf36f, AVX10_2&MOVRS&x64, Modrm|Masking|Map5|<dq:vexw>|Disp8ShiftVL|CheckOperandSize|NoSuf, { Xmmword|Ymmword|Zmmword|Unspecified|BaseIndex, RegXMM|RegYMM|RegZMM }
// MOVRS instructions end.
+
+// BHI_CTRL insructions.
+
+ibhf, 0xf30f1ef8, x64&BHI_CTRL, NoSuf|Size64, {}
+
+// BHI_CTRL insructions end.
--
2.31.1
More information about the Binutils
mailing list