[PATCH 1/1] x86: add "udb" opcode (permanent official #UD in 64-bit mode)
H. Peter Anvin
hpa@zytor.com
Mon Aug 11 17:48:40 GMT 2025
The opcode D6 has been officially reserved as a single-byte permanent
undefined (#UD) opcode in 64-bit mode with the mnemonic UDB. This is
already the behavior of all known 64-bit implementations; this is thus
merely an official statement of forward compatibility and the
assignment of a mnemonic.
This will be documented in the next version of the Intel Software
Developer's Manual; in the meantime I DO speak officially for Intel on
this issue.
The x86 Advisory Council has ratified this decision, and so it is
expected to be honored across vendors, but I obviously cannot make any
official statement on any other vendor's behalf.
I am covered by the Intel-FSF copyright assignment for binutils.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
---
gas/testsuite/gas/i386/x86-64-opcode.d | 1 +
gas/testsuite/gas/i386/x86-64-opcode.s | 1 +
opcodes/i386-dis.c | 9 ++++++++-
opcodes/i386-opc.tbl | 2 ++
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/gas/testsuite/gas/i386/x86-64-opcode.d b/gas/testsuite/gas/i386/x86-64-opcode.d
index 1b8a9fa9014c..0d7cbd2f17ba 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode.d
+++ b/gas/testsuite/gas/i386/x86-64-opcode.d
@@ -328,6 +328,7 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: f1 int1
[ ]*[a-f0-9]+: cc int3
[ ]*[a-f0-9]+: cd 90 int \$0x90
+[ ]*[a-f0-9]+: d6 udb
[ ]*[a-f0-9]+: f6 c9 01 test \$(0x)?0*1,%cl
[ ]*[a-f0-9]+: 66 f7 c9 02 00 test \$(0x)?0*2,%cx
[ ]*[a-f0-9]+: f7 c9 04 00 00 00 test \$(0x)?0*4,%ecx
diff --git a/gas/testsuite/gas/i386/x86-64-opcode.s b/gas/testsuite/gas/i386/x86-64-opcode.s
index 220998c86535..95559d7d15e5 100644
--- a/gas/testsuite/gas/i386/x86-64-opcode.s
+++ b/gas/testsuite/gas/i386/x86-64-opcode.s
@@ -457,6 +457,7 @@
int1
int3
int $0x90
+ udb
.insn 0xf6/1, $1, %cl
.insn 0xf7/1, $2{:u16}, %cx
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 703f09dbb774..e6637ab26f71 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1325,6 +1325,7 @@ enum
X86_64_CE,
X86_64_D4,
X86_64_D5,
+ X86_64_D6,
X86_64_E8,
X86_64_E9,
X86_64_EA,
@@ -2194,7 +2195,7 @@ static const struct dis386 dis386[] = {
{ REG_TABLE (REG_D3) },
{ X86_64_TABLE (X86_64_D4) },
{ X86_64_TABLE (X86_64_D5) },
- { Bad_Opcode },
+ { X86_64_TABLE (X86_64_D6) },
{ "xlat", { DSBX }, 0 },
/* d8 */
{ FLOAT },
@@ -4511,6 +4512,12 @@ static const struct dis386 x86_64_table[][2] = {
{ "aad", { Ib }, 0 },
},
+ /* X86_64_D6 */
+ {
+ { Bad_Opcode },
+ { "udb", { XX }, 0 },
+ },
+
/* X86_64_E8 */
{
{ "callP", { Jv, BND }, 0 },
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 6eadc2ebf734..b03fbc3325f5 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -993,6 +993,8 @@ ud2b, 0xfb9, i286, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|U
// 3rd official undefined instr (older CPUs don't take a ModR/M byte)
ud0, 0xfff, i286, NoSuf, {}
ud0, 0xfff, i286, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+// 4th official undefined instruction (single byte in 64-bit mode only)
+udb, 0xd6, x64, NoSuf, {}
// C (commutative) isn't quite correct here on its own; the condition also
// needs inverting when source operands are swapped in order to convert to
--
2.50.1
More information about the Binutils
mailing list