[PATCH] x86: Support BHI_CTRL instruction
Haochen Jiang
haochen.jiang@intel.com
Mon Jun 1 06:24:46 GMT 2026
Hi all,
The following patch aimed to add BHI_CTRL. The ISA has been published in a
separate tech paper last year and still missing its assembler/disassembler
support.
One tricky thing is that it utilized part of the nops encoding and we need
to keep the same behavior for the not touched one, i.e., repz nop. That is
why I added a Fixup for now since I did not have a better idea for that.
Discussions are welcomed on this.
Ok for trunk?
Thx,
Haochen
---
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.
I added a Fixup for disassembler since we need to keep the same behavior
for "repz 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: (isa_dependencies): Add BHI_CTRL.
(cpu_flags): Ditto.
* 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 | 12 +
gas/testsuite/gas/i386/x86-64-bhi-ctrl.d | 10 +
gas/testsuite/gas/i386/x86-64-bhi-ctrl.s | 9 +
gas/testsuite/gas/i386/x86-64.exp | 2 +
opcodes/i386-dis.c | 21 +-
opcodes/i386-gen.c | 3 +
opcodes/i386-init.h | 995 ++++---
opcodes/i386-mnem.h | 2639 +++++++++--------
opcodes/i386-opc.h | 3 +
opcodes/i386-opc.tbl | 6 +
opcodes/i386-tbl.h | 1241 ++++----
13 files changed, 2516 insertions(+), 2428 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 e384d1135c0..0687fd4adfc 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the x86 BHI_CTRL instruction.
+
Changes in 2.46:
* Add support for AMD Zen6 processor.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 365c2ee95f5..b67606d13ad 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1260,6 +1260,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..adc9f87a62a
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl-intel.d
@@ -0,0 +1,12 @@
+#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
+#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..164ae5e8839
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.d
@@ -0,0 +1,10 @@
+#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
+#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..41beb4210d6
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-bhi-ctrl.s
@@ -0,0 +1,9 @@
+# Check 64bit BHI_CTRL instructions
+
+ .text
+_start:
+ ibhf
+
+_intel:
+ .intel_syntax noprefix
+ ibhf
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index 8ddf05481a5..cb2334fbe75 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -550,6 +550,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 db1e4f7a7d5..ecf74840eee 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,
@@ -8750,7 +8751,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 },
@@ -14671,3 +14672,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 be580d48a18..7033517e777 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -319,6 +319,8 @@ static const dependency isa_dependencies[] =
"PadLock" },
{ "PadLockXMODX",
"PadLock" },
+ { "BHI_CTRL",
+ "64" },
};
/* This array is populated as process_i386_initializers() walks cpu_flags[]. */
@@ -451,6 +453,7 @@ static bitfield cpu_flags[] =
BITFIELD (APX_F),
BITFIELD (AVX10_2),
BITFIELD (MOVRS),
+ BITFIELD (BHI_CTRL),
BITFIELD (MWAITX),
BITFIELD (CLZERO),
BITFIELD (OSPKE),
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index 54038f90761..97eaf085dbd 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -241,6 +241,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 */
@@ -523,6 +525,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 5797a634de3..827d4b54906 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3630,3 +3630,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, BHI_CTRL, NoSuf|Size64, {}
+
+// BHI_CTRL insructions end.
--
2.31.1
More information about the Binutils
mailing list