[v2] x86: support further AMD Zen6 instructions

Message ID 20260902082715.4025598-1-RohanRadhesh.Shenoy@amd.com
State New
Headers
Series [v2] x86: support further AMD Zen6 instructions |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Rohan Shenoy Sept. 2, 2026, 8:27 a.m. UTC
  - Add support for RMPOPT and RMPCHKD instructions.
- Enable FRED on znver6.

https://docs.amd.com/api/khub/documents/pVy9DHmRU6S3gKD2150uhg/content
https://docs.amd.com/api/khub/documents/dSDYo9rxWwNDSJkmMJCxYQ/content
---

Notes:
    Changes in V2:
    - Added explicit-operand version for rmpopt and rmpchkd.
    - Linked to documentation.

 gas/config/tc-i386.c                          |  5 +++-
 gas/doc/c-i386.texi                           |  5 +++-
 gas/testsuite/gas/i386/rmpchkd.d              | 20 +++++++++++++++
 gas/testsuite/gas/i386/rmpchkd.s              | 13 ++++++++++
 gas/testsuite/gas/i386/rmpopt.d               | 20 +++++++++++++++
 gas/testsuite/gas/i386/rmpopt.s               | 13 ++++++++++
 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                          | 14 +++++++++++
 14 files changed, 139 insertions(+), 4 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
  

Comments

Jan Beulich Sept. 2, 2026, 10:14 a.m. UTC | #1
On 02.09.2026 10:27, Rohan Shenoy wrote:
> - Add support for RMPOPT and RMPCHKD instructions.
> - Enable FRED on znver6.
> 
> https://docs.amd.com/api/khub/documents/pVy9DHmRU6S3gKD2150uhg/content
> https://docs.amd.com/api/khub/documents/dSDYo9rxWwNDSJkmMJCxYQ/content
> ---
> 
> Notes:
>     Changes in V2:
>     - Added explicit-operand version for rmpopt and rmpchkd.
>     - Linked to documentation.

Lgtm, I'll see about getting this in later in the week (unless other
comments arise which would require a v3).

Jan
  
Jiang, Haochen Sept. 3, 2026, 2:02 a.m. UTC | #2
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Wednesday, September 2, 2026 6:15 PM
> 
> On 02.09.2026 10:27, Rohan Shenoy wrote:
> > - Add support for RMPOPT and RMPCHKD instructions.
> > - Enable FRED on znver6.
> >
> >
> https://docs.amd.com/api/khub/documents/pVy9DHmRU6S3gKD2150uhg/
> content
> >
> https://docs.amd.com/api/khub/documents/dSDYo9rxWwNDSJkmMJCxYQ/
> content
> > ---
> >
> > Notes:
> >     Changes in V2:
> >     - Added explicit-operand version for rmpopt and rmpchkd.
> >     - Linked to documentation.
> 
> Lgtm, I'll see about getting this in later in the week (unless other
> comments arise which would require a v3).

Also LGTM.

Thx,
Haochen

> 
> Jan
  

Patch

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1b28415540a..ce9cc8236fa 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),
@@ -7397,7 +7399,8 @@  i386_assemble (char *line)
 
   /* All Intel opcodes have reversed operands except for "bound", "enter",
      "invlpg*", "monitor*", "mwait*", "tpause", "umwait", "pvalidate",
-     "rmpadjust", "rmpquery", and deprecated forms of "rmpupdate".
+     "rmpadjust", "rmpquery", "rmpopt", "rmpchkd", and deprecated forms of
+     "rmpupdate".
      We also don't reverse intersegment "jmp" and "call" instructions with
      2 immediate operands so that the immediate segment precedes the offset
      consistently in Intel and AT&T modes.  */
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..55bb1e9cd2a
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpchkd.d
@@ -0,0 +1,20 @@ 
+#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[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+f3 0f 01 fc[ 	]+rmpchkd[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+67 f3 0f 01 fc[ 	]+addr32 rmpchkd[ 	]*
+
+[0-9a-f]+ <intel>:
+[ 	]*[a-f0-9]+:[ 	]+f3 0f 01 fc[ 	]+rmpchkd[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+f3 0f 01 fc[ 	]+rmpchkd[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+67 f3 0f 01 fc[ 	]+addr32 rmpchkd[ 	]*
+#pass
diff --git a/gas/testsuite/gas/i386/rmpchkd.s b/gas/testsuite/gas/i386/rmpchkd.s
new file mode 100644
index 00000000000..a67faf9ca96
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpchkd.s
@@ -0,0 +1,13 @@ 
+# Check RMPCHKD instruction
+
+	.text
+att:
+        rmpchkd
+        rmpchkd %rax, %rcx
+        rmpchkd %eax, %rcx
+
+	.intel_syntax noprefix
+intel:
+        rmpchkd
+        rmpchkd rax, rcx
+        rmpchkd eax, rcx
diff --git a/gas/testsuite/gas/i386/rmpopt.d b/gas/testsuite/gas/i386/rmpopt.d
new file mode 100644
index 00000000000..c15d9adf35a
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpopt.d
@@ -0,0 +1,20 @@ 
+#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[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+f2 0f 01 fc[ 	]+rmpopt[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+67 f2 0f 01 fc[ 	]+addr32 rmpopt[ 	]*
+
+[0-9a-f]+ <intel>:
+[ 	]*[a-f0-9]+:[ 	]+f2 0f 01 fc[ 	]+rmpopt[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+f2 0f 01 fc[ 	]+rmpopt[ 	]*
+[ 	]*[a-f0-9]+:[ 	]+67 f2 0f 01 fc[ 	]+addr32 rmpopt[ 	]*
+#pass
diff --git a/gas/testsuite/gas/i386/rmpopt.s b/gas/testsuite/gas/i386/rmpopt.s
new file mode 100644
index 00000000000..7718334d0f4
--- /dev/null
+++ b/gas/testsuite/gas/i386/rmpopt.s
@@ -0,0 +1,13 @@ 
+# Check RMPOPT instruction
+
+	.text
+att:
+        rmpopt
+        rmpopt %rax, %rcx
+        rmpopt %eax, %rcx
+
+	.intel_syntax noprefix
+intel:
+        rmpopt
+        rmpopt rax, rcx
+        rmpopt eax, rcx
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|FRED|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..8ff7bf1828e 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -3205,6 +3205,20 @@  rmpread, 0xf20f01fd, RMPREAD&x64, IsString|NoSuf|NoRex64, { Acc|Qword, RegC|Unsp
 
 // RMPREAD instruction end
 
+// RMPCHKD instruction
+
+rmpchkd, 0xf30f01fc, RMPDIRTY, NoSuf, {}
+rmpchkd, 0xf30f01fc, RMPDIRTY, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword, RegC|Qword }
+
+// RMPCHKD instruction end
+
+// RMPOPT instruction
+
+rmpopt, 0xf20f01fc, RMPOPT, NoSuf, {}
+rmpopt, 0xf20f01fc, RMPOPT, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword, RegC|Qword }
+
+// RMPOPT instruction end
+
 // RDPRU instruction
 
 rdpru, 0x0f01fd, RDPRU, NoSuf, {}