[PATCH v2] x86: support further AMD Zen6 instructions

Rohan Shenoy <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
- 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

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, {}
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.