[PATCH] x86: support further AMD Zen6 instructions

Shenoy, Rohan Radhesh RohanRadhesh.Shenoy@amd.com
Tue Sep 1 09:33:08 GMT 2026


AMD General

+cc'ing Borislav

-----Original Message-----
From: Shenoy, Rohan Radhesh <RohanRadhesh.Shenoy@amd.com>
Sent: 01 September 2026 14:46
To: binutils@sourceware.org
Cc: jbeulich@suse.com; haochen.jiang@intel.com; Gopalasubramanian, Ganesh <Ganesh.Gopalasubramanian@amd.com>; Kumar, Venkataramanan <Venkataramanan.Kumar@amd.com>; Shenoy, Rohan Radhesh <RohanRadhesh.Shenoy@amd.com>
Subject: [PATCH] x86: support further AMD Zen6 instructions

Changes:
- Add support for RMPOPT and RMPCHKD instructions.
- Enable FRED on znver6.
---
 gas/config/tc-i386.c                          |  2 ++
 gas/doc/c-i386.texi                           |  5 +++-
 gas/testsuite/gas/i386/rmpchkd.d              | 16 ++++++++++++
 gas/testsuite/gas/i386/rmpchkd.s              |  9 +++++++
 gas/testsuite/gas/i386/rmpopt.d               | 16 ++++++++++++
 gas/testsuite/gas/i386/rmpopt.s               |  9 +++++++
 gas/testsuite/gas/i386/x86-64-arch-6-znver6.d |  4 +++
 gas/testsuite/gas/i386/x86-64-arch-6.d        |  4 +++
 gas/testsuite/gas/i386/x86-64-arch-6.s        |  4 +++
 gas/testsuite/gas/i386/x86-64.exp             |  2 ++
 opcodes/i386-dis.c                            | 25 ++++++++++++++++++-
 opcodes/i386-gen.c                            |  8 +++++-
 opcodes/i386-opc.h                            |  6 +++++
 opcodes/i386-opc.tbl                          | 12 +++++++++
 14 files changed, 119 insertions(+), 3 deletions(-)  create mode 100644 gas/testsuite/gas/i386/rmpchkd.d  create mode 100644 gas/testsuite/gas/i386/rmpchkd.s  create mode 100644 gas/testsuite/gas/i386/rmpopt.d  create mode 100644 gas/testsuite/gas/i386/rmpopt.s

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 1b28415540a..0c418877d6d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1245,6 +1245,8 @@ static const arch_entry cpu_arch[] =
   SUBARCH (rao_int, RAO_INT, RAO_INT, false),
   SUBARCH (rmpquery, RMPQUERY, ANY_RMPQUERY, false),
   SUBARCH (rmpread, RMPREAD, ANY_RMPREAD, false),
+  SUBARCH (rmpdirty, RMPDIRTY, ANY_RMPDIRTY, false),  SUBARCH (rmpopt,
+ RMPOPT, ANY_RMPOPT, false),
   SUBARCH (fred, FRED, ANY_FRED, false),
   SUBARCH (lkgs, LKGS, ANY_LKGS, false),
   VECARCH (avx_vnni_int16, AVX_VNNI_INT16, ANY_AVX_VNNI_INT16, reset), diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index dbc905a33ef..3ce70810d4e 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -293,6 +293,8 @@ accept various extension mnemonics.  For example,  @code{tlbsync},  @code{rmpquery},  @code{rmpread},
+@code{rmpdirty},
+@code{rmpopt},
 @code{svme},
 @code{gmism2},
 @code{gmiccs},
@@ -1742,7 +1744,8 @@ supported on the CPU specified.  The choices for @var{cpu_type} are:
 @item @samp{.lwp} @tab @samp{.fma4} @tab @samp{.xop} @tab @samp{.cx16}  @item @samp{.padlock} @tab @samp{.clzero} @tab @samp{.mwaitx} @tab @samp{.rdpru}  @item @samp{.mcommit} @tab @samp{.sev_es} @tab @samp{.snp} @tab @samp{.invlpgb} -@item @samp{.tlbsync} @tab @samp{.rmpquery} @tab @samp{.rmpread} @tab @samp{.apx_f}
+@item @samp{.tlbsync} @tab @samp{.rmpquery} @tab @samp{.rmpread} @tab
+@samp{.rmpdirty} @item @samp{.rmpopt} @tab @samp{.apx_f}
 @item @samp{.apx_nci} @tab @samp{.apx_ndd} @tab @samp{.apx_nf} @tab @samp{.apx_nci_ndd_nf}  @item @samp{.gmism2} @tab @samp{.gmiccs} @tab @samp{.padlockrng2} @tab @samp{.padlockphe2}  @item @samp{.padlockxmodx} diff --git a/gas/testsuite/gas/i386/rmpchkd.d b/gas/testsuite/gas/i386/rmpchkd.d
new file mode 100644
index 00000000000..6c4d19c42f9
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpchkd.d
@@ -0,0 +1,16 @@
+#as: -march=generic64+rmpdirty
+#objdump: -dw
+#name: 64-bit RMPCHKD insn
+#source: rmpchkd.s
+
+.*: +file format .*
+
+
+Disassembly of section \.text:
+
+0+ <att>:
+[      ]*[a-f0-9]+:[   ]+f3 0f 01 fc[  ]+rmpchkd[      ]*
+
+[0-9a-f]+ <intel>:
+[      ]*[a-f0-9]+:[   ]+f3 0f 01 fc[  ]+rmpchkd[      ]*
+#pass
diff --git a/gas/testsuite/gas/i386/rmpchkd.s b/gas/testsuite/gas/i386/rmpchkd.s
new file mode 100644
index 00000000000..48922efc174
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpchkd.s
@@ -0,0 +1,9 @@
+# Check RMPCHKD instruction
+
+       .text
+att:
+        rmpchkd
+
+       .intel_syntax noprefix
+intel:
+        rmpchkd
diff --git a/gas/testsuite/gas/i386/rmpopt.d b/gas/testsuite/gas/i386/rmpopt.d new file mode 100644 index 00000000000..a7cba8e5175
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpopt.d
@@ -0,0 +1,16 @@
+#as: -march=generic64+rmpopt
+#objdump: -dw
+#name: 64-bit RMPOPT insn
+#source: rmpopt.s
+
+.*: +file format .*
+
+
+Disassembly of section \.text:
+
+0+ <att>:
+[      ]*[a-f0-9]+:[   ]+f2 0f 01 fc[  ]+rmpopt[       ]*
+
+[0-9a-f]+ <intel>:
+[      ]*[a-f0-9]+:[   ]+f2 0f 01 fc[  ]+rmpopt[       ]*
+#pass
diff --git a/gas/testsuite/gas/i386/rmpopt.s b/gas/testsuite/gas/i386/rmpopt.s new file mode 100644 index 00000000000..61f0ff19605
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpopt.s
@@ -0,0 +1,9 @@
+# Check RMPOPT instruction
+
+       .text
+att:
+        rmpopt
+
+       .intel_syntax noprefix
+intel:
+        rmpopt
diff --git a/gas/testsuite/gas/i386/x86-64-arch-6-znver6.d b/gas/testsuite/gas/i386/x86-64-arch-6-znver6.d
index 54c63742fe3..d1a8c5f56d3 100644
--- a/gas/testsuite/gas/i386/x86-64-arch-6-znver6.d
+++ b/gas/testsuite/gas/i386/x86-64-arch-6-znver6.d
@@ -13,4 +13,8 @@ Disassembly of section \.text:
 [\s]*[a-f0-9]+:[\s]*c4 e2 f1 b5 d1[\s]*\{vex\} vpmadd52huq %xmm1,%xmm1,%xmm2
 [\s]*[a-f0-9]+:[\s]*c4 e2 6f 50 d9[\s]*vpdpbssd %ymm1,%ymm2,%ymm3
 [\s]*[a-f0-9]+:[\s]*62 f5 6c 48 58 d9[\s]*vaddph %zmm1,%zmm2,%zmm3
+[\s]*[a-f0-9]+:[\s]*f2 0f 01 ca[\s]*erets
+[\s]*[a-f0-9]+:[\s]*f3 0f 01 ca[\s]*eretu
+[\s]*[a-f0-9]+:[\s]*f3 0f 01 fc[\s]*rmpchkd
+[\s]*[a-f0-9]+:[\s]*f2 0f 01 fc[\s]*rmpopt
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-arch-6.d b/gas/testsuite/gas/i386/x86-64-arch-6.d
index 4fb1f0d31ae..350166627b7 100644
--- a/gas/testsuite/gas/i386/x86-64-arch-6.d
+++ b/gas/testsuite/gas/i386/x86-64-arch-6.d
@@ -11,4 +11,8 @@ Disassembly of section \.text:
 [\s]*[a-f0-9]+:[\s]*62 f2 f5 08 b5 d1[\s]*vpmadd52huq %xmm1,%xmm1,%xmm2
 [\s]*[a-f0-9]+:[\s]*c4 e2 6f 50 d9[\s]*vpdpbssd %ymm1,%ymm2,%ymm3
 [\s]*[a-f0-9]+:[\s]*62 f5 6c 48 58 d9[\s]*vaddph %zmm1,%zmm2,%zmm3
+[\s]*[a-f0-9]+:[\s]*f2 0f 01 ca[\s]*erets
+[\s]*[a-f0-9]+:[\s]*f3 0f 01 ca[\s]*eretu
+[\s]*[a-f0-9]+:[\s]*f3 0f 01 fc[\s]*rmpchkd
+[\s]*[a-f0-9]+:[\s]*f2 0f 01 fc[\s]*rmpopt
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-arch-6.s b/gas/testsuite/gas/i386/x86-64-arch-6.s
index f8017844bbf..74970bf508c 100644
--- a/gas/testsuite/gas/i386/x86-64-arch-6.s
+++ b/gas/testsuite/gas/i386/x86-64-arch-6.s
@@ -6,3 +6,7 @@
        vpmadd52huq %xmm1, %xmm1, %xmm2         #AVX_IFMA
        vpdpbssd %ymm1, %ymm2, %ymm3            #AVX_VNNI_INT8
        vaddph %zmm1, %zmm2, %zmm3              #AVX512-FP16
+       erets           #FRED
+       eretu           #FRED
+       rmpchkd         #RMPDIRTY
+       rmpopt          #RMPOPT
diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
index fee205b9659..eb10d9b8b9f 100644
--- a/gas/testsuite/gas/i386/x86-64.exp
+++ b/gas/testsuite/gas/i386/x86-64.exp
@@ -181,6 +181,8 @@ run_dump_test "x86-64-arch-3"
 run_dump_test "x86-64-arch-4"
 run_dump_test "x86-64-arch-4-1"
 run_dump_test "rmpquery"
+run_dump_test "rmpchkd"
+run_dump_test "rmpopt"
 run_dump_test "x86-64-arch-5"
 run_dump_test "x86-64-arch-6"
 run_dump_test "x86-64-arch-2-lzcnt"
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index fe61c6fe2f5..ec1d149d9dc 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1018,6 +1018,7 @@ enum
   PREFIX_0F01_REG_5_MOD_3_RM_6,
   PREFIX_0F01_REG_5_MOD_3_RM_7,
   PREFIX_0F01_REG_7_MOD_3_RM_2,
+  PREFIX_0F01_REG_7_MOD_3_RM_4,
   PREFIX_0F01_REG_7_MOD_3_RM_5,
   PREFIX_0F01_REG_7_MOD_3_RM_6,
   PREFIX_0F01_REG_7_MOD_3_RM_7,
@@ -1363,6 +1364,8 @@ enum
   X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1,
   X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1,
   X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1,
+  X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_1,
+  X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_3,
   X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1,
   X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_3,
   X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1,
@@ -3287,6 +3290,14 @@ static const struct dis386 prefix_table[][4] = {
     { "mcommit",       { Skip_MODRM }, 0 },
   },

+  /* PREFIX_0F01_REG_7_MOD_3_RM_4 */
+  {
+    { "clzero",        { Skip_MODRM }, 0 },
+    { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_1) },
+    { Bad_Opcode },
+    { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_3) },  },
+
   /* PREFIX_0F01_REG_7_MOD_3_RM_5 */
   {
     { "rdpru", { Skip_MODRM }, 0 },
@@ -4672,6 +4683,18 @@ static const struct dis386 x86_64_table[][2] = {
     { "stui",  { Skip_MODRM }, 0 },
   },

+  /* X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_1 */  {
+    { Bad_Opcode },
+    { "rmpchkd",       { Skip_MODRM }, 0 },
+  },
+
+  /* X86_64_0F01_REG_7_MOD_3_RM_4_PREFIX_3 */  {
+    { Bad_Opcode },
+    { "rmpopt",        { Skip_MODRM }, 0 },
+  },
+
   /* X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1 */
   {
     { Bad_Opcode },
@@ -8763,7 +8786,7 @@ static const struct dis386 rm_table[][8] = {
     { "rdtscp",                { Skip_MODRM }, 0  },
     { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_2) },
     { "mwaitx",                { { OP_Mwait, eBX_reg } }, PREFIX_OPCODE },
-    { "clzero",                { Skip_MODRM }, 0  },
+    { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_4) },
     { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_5) },
     { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_6) },
     { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_7) }, diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index b8d7ad2b0b1..cf37d8786e9 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -99,7 +99,7 @@ static const dependency isa_dependencies[] =
   { "ZNVER5",
     "ZNVER4|AVX_VNNI|MOVDIRI|MOVDIR64B|AVX512_VP2INTERSECT|PREFETCHI" },
   { "ZNVER6",
-    "ZNVER5|AVX512_BMM|AVX_NE_CONVERT|AVX_IFMA|AVX_VNNI_INT8|AVX512_FP16" },
+
+ "ZNVER5|AVX512_BMM|AVX_NE_CONVERT|AVX_IFMA|AVX_VNNI_INT8|AVX512_FP16|F
+ RED|RMPDIRTY|RMPOPT" },
   { "BTVER1",
     "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
   { "BTVER2",
@@ -261,6 +261,10 @@ static const dependency isa_dependencies[] =
     "SNP|64" },
   { "RMPREAD",
     "SNP|64" },
+  { "RMPDIRTY",
+    "SNP|64" },
+  { "RMPOPT",
+    "SNP|64" },
   { "TSX",
     "RTM|HLE" },
   { "TSXLDTRK",
@@ -500,6 +504,8 @@ static bitfield cpu_flags[] =
   BITFIELD (SNP),
   BITFIELD (RMPQUERY),
   BITFIELD (RMPREAD),
+  BITFIELD (RMPDIRTY),
+  BITFIELD (RMPOPT),
   BITFIELD (APX_NCI),
   BITFIELD (APX_NDD),
   BITFIELD (APX_NF),
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index 4da0ceffa96..cd8f228f5a9 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -328,6 +328,10 @@ enum i386_cpu
   CpuRMPQUERY,
   /* RMPREAD instruction required */
   CpuRMPREAD,
+  /* RMPDIRTY instruction required */
+  CpuRMPDIRTY,
+  /* RMPOPT instruction required */
+  CpuRMPOPT,
   /* Intel APX New Conditional Instructions support required.  */
   CpuAPX_NCI,
   /* Intel APX Non-Destructive Destination support required.  */ @@ -573,6 +577,8 @@ typedef union i386_cpu_flags
       unsigned int cpusnp:1;
       unsigned int cpurmpquery:1;
       unsigned int cpurmpread:1;
+      unsigned int cpurmpdirty:1;
+      unsigned int cpurmpopt:1;
       unsigned int cpuapx_nci:1;
       unsigned int cpuapx_ndd:1;
       unsigned int cpuapx_nf:1;
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 413ad4f2879..9a32636d0e5 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3205,6 +3205,18 @@ rmpread, 0xf20f01fd, RMPREAD&x64, IsString|NoSuf|NoRex64, { Acc|Qword, RegC|Unsp

 // RMPREAD instruction end

+// RMPCHKD instruction
+
+rmpchkd, 0xf30f01fc, RMPDIRTY&x64, NoSuf, {}
+
+// RMPCHKD instruction end
+
+// RMPOPT instruction
+
+rmpopt, 0xf20f01fc, RMPOPT&x64, NoSuf, {}
+
+// RMPOPT instruction end
+
 // RDPRU instruction

 rdpru, 0x0f01fd, RDPRU, NoSuf, {}
--
2.34.1



More information about the Binutils mailing list