Add support for intel HRESET instructions.

Cui, Lili lili.cui@intel.com
Tue Oct 13 07:52:17 GMT 2020


Hi all,
 
This patch is about to enable binutils support for HRESET.
This feature enable a hint for the HW to reset prediction history, more details please refer to 
https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html

Make check-gas is ok.

[PATCH] Add support for intel HRESET instructions

gas/
	* config/tc-i386.c (cpu_arch): Add .hreset.
	(cpu_noarch): Likewise.
	(output_insn): Support opcode_length equal 4.
	* doc/c-i386.texi: Document .avx_hreset, noavx_hreset.
	* testsuite/gas/i386/i386.exp: Run HRESET tests
	* testsuite/gas/i386/hreset.d: New file.
	* testsuite/gas/i386/x86-64-hreset.d: Likewise.
	* testsuite/gas/i386/hreset.s: Likewise.

opcodes/
	* i386-dis.c (PREFIX_0F3A0F): New.
	(MOD_0F3A0F_PREFIX_1): Likewise.
	(REG_0F3A0F_PREFIX_1_MOD_3): Likewise.
	(RM_0F3A0F_P_1_MOD_3_REG_0): Likewise.
	(prefix_table): Add PREFIX_0F3A0F.
	(mod_table): Add MOD_0F3A0F_PREFIX_1.
	(reg_table): Add REG_0F3A0F_PREFIX_1_MOD_3.
	(rm_table): Add RM_0F3A0F_P_1_MOD_3_REG_0.
	* i386-gen.c (cpu_flag_init): Add HRESET_FLAGS,
	CPU_ANY_HRESET_FLAGS.
	(cpu_flags): Add CpuHRESET.
	* i386-opc.h (enum): Add CpuHRESET.
	(i386_cpu_flags): Add cpuhreset.
	(insn_template): Change base_opcode type to unsigned long long.
	* i386-opc.tbl: Add Intel HRESET insns.
	* i386-init.h: Regenerate.
	* i386-tbl.h: Likewise.
---
 gas/config/tc-i386.c                   | 10 ++++++++++
 gas/doc/c-i386.texi                    |  4 +++-
 gas/testsuite/gas/i386/hreset.d        | 12 ++++++++++++
 gas/testsuite/gas/i386/hreset.s        |  5 +++++
 gas/testsuite/gas/i386/i386.exp        |  2 ++
 gas/testsuite/gas/i386/x86-64-hreset.d | 12 ++++++++++++
 opcodes/i386-dis.c                     | 25 ++++++++++++++++++++++++-
 opcodes/i386-gen.c                     |  5 +++++
 opcodes/i386-opc.h                     |  5 ++++-
 opcodes/i386-opc.tbl                   |  6 ++++++
 10 files changed, 83 insertions(+), 3 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/hreset.d
 create mode 100644 gas/testsuite/gas/i386/hreset.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-hreset.d

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 64cd78c8ee..a04b83a66f 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1240,6 +1240,8 @@ static const arch_entry cpu_arch[] =
     CPU_KL_FLAGS, 0 },
   { STRING_COMMA_LEN (".widekl"), PROCESSOR_UNKNOWN,
     CPU_WIDEKL_FLAGS, 0 },
+  { STRING_COMMA_LEN (".hreset"), PROCESSOR_UNKNOWN,
+    CPU_HRESET_FLAGS, 0 },
 };
 
 static const noarch_entry cpu_noarch[] =
@@ -1292,6 +1294,7 @@ static const noarch_entry cpu_noarch[] =
   { STRING_COMMA_LEN ("notsxldtrk"), CPU_ANY_TSXLDTRK_FLAGS },
   { STRING_COMMA_LEN ("nokl"), CPU_ANY_KL_FLAGS },
   { STRING_COMMA_LEN ("nowidekl"), CPU_ANY_WIDEKL_FLAGS },
+  { STRING_COMMA_LEN ("nohreset"), CPU_ANY_HRESET_FLAGS },
 };
 
 #ifdef I386COFF
@@ -9376,6 +9379,13 @@ output_insn (void)
 	{
 	  switch (i.tm.opcode_length)
 	    {
+	    case 4:
+	      if (i.tm.base_opcode & 0xff00000000)
+		{
+		  prefix = (i.tm.base_opcode >> 32) & 0xff;
+		    add_prefix (prefix);
+		}
+	      break;
 	    case 3:
 	      if (i.tm.base_opcode & 0xff000000)
 		{
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 776fed8ed5..3f3188c395 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -193,6 +193,7 @@ accept various extension mnemonics.  For example,
 @code{nokl},
 @code{widekl},
 @code{nowidekl},
+@code{hreset},
 @code{avx512f},
 @code{avx512cd},
 @code{avx512er},
@@ -238,6 +239,7 @@ accept various extension mnemonics.  For example,
 @code{noamx_bf16},
 @code{amx_tile},
 @code{noamx_tile},
+@code{nohreset},
 @code{vmx},
 @code{vmfunc},
 @code{smx},
@@ -1511,7 +1513,7 @@ supported on the CPU specified.  The choices for @var{cpu_type} are:
 @item @samp{.shstk} @tab @samp{.gfni} @tab @samp{.vaes} @tab @samp{.vpclmulqdq}
 @item @samp{.movdiri} @tab @samp{.movdir64b} @tab @samp{.enqcmd} @tab @samp{.tsxldtrk}
 @item @samp{.amx_int8} @tab @samp{.amx_bf16} @tab @samp{.amx_tile}
-@item @samp{.kl} @tab @samp{.widekl}
+@item @samp{.kl} @tab @samp{.widekl} @tab @samp{.hreset}
 @item @samp{.3dnow} @tab @samp{.3dnowa} @tab @samp{.sse4a} @tab @samp{.sse5}
 @item @samp{.syscall} @tab @samp{.rdtscp} @tab @samp{.svme}
 @item @samp{.lwp} @tab @samp{.fma4} @tab @samp{.xop} @tab @samp{.cx16}
diff --git a/gas/testsuite/gas/i386/hreset.d b/gas/testsuite/gas/i386/hreset.d
new file mode 100644
index 0000000000..02548652ca
--- /dev/null
+++ b/gas/testsuite/gas/i386/hreset.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -dw
+#name: HRESET insns
+#source: hreset.s
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:[ 	]*f3 0f 3a f0 c0 08[ 	]*hreset \$0x8
+#pass
diff --git a/gas/testsuite/gas/i386/hreset.s b/gas/testsuite/gas/i386/hreset.s
new file mode 100644
index 0000000000..ff0887c416
--- /dev/null
+++ b/gas/testsuite/gas/i386/hreset.s
@@ -0,0 +1,5 @@
+# Check HRESET instructions.
+
+	.text
+_start:
+	hreset $0x8
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 8645f3061c..64915537e9 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -493,6 +493,7 @@ if [gas_32_check] then {
     run_dump_test "serialize"
     run_dump_test "tdx"
     run_dump_test "tsxldtrk"
+    run_dump_test "hreset"
     run_dump_test "vp2intersect"
     run_dump_test "vp2intersect-intel"
     run_list_test "vp2intersect-inval-bcast"
@@ -1105,6 +1106,7 @@ if [gas_64_check] then {
     run_dump_test "x86-64-serialize"
     run_dump_test "x86-64-tdx"
     run_dump_test "x86-64-tsxldtrk"
+    run_dump_test "x86-64-hreset"
     run_dump_test "x86-64-vp2intersect"
     run_dump_test "x86-64-vp2intersect-intel"
     run_list_test "x86-64-vp2intersect-inval-bcast"
diff --git a/gas/testsuite/gas/i386/x86-64-hreset.d b/gas/testsuite/gas/i386/x86-64-hreset.d
new file mode 100644
index 0000000000..3f0b0b8f5e
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-hreset.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -dw
+#name: x86_64 HRESET insns
+#source: hreset.s
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:[ 	]*f3 0f 3a f0 c0 08[ 	]*hreset \$0x8
+#pass
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 4d8f4f4cc2..8e18df8b8b 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -692,6 +692,7 @@ enum
   REG_0F1C_P_0_MOD_0,
   REG_0F1E_P_1_MOD_3,
   REG_0F38D8_PREFIX_1,
+  REG_0F3A0F_PREFIX_1_MOD_3,
   REG_0F71,
   REG_0F72,
   REG_0F73,
@@ -799,6 +800,7 @@ enum
   MOD_0F38F9,
   MOD_0F38FA_PREFIX_1,
   MOD_0F38FB_PREFIX_1,
+  MOD_0F3A0F_PREFIX_1,
   MOD_62_32BIT,
   MOD_C4_32BIT,
   MOD_C5_32BIT,
@@ -944,6 +946,7 @@ enum
   RM_0F01_REG_5_MOD_3,
   RM_0F01_REG_7_MOD_3,
   RM_0F1E_P_1_MOD_3_REG_7,
+  RM_0F3A0F_P_1_MOD_3_REG_0,
   RM_0FAE_REG_6_MOD_3_P_0,
   RM_0FAE_REG_7_MOD_3,
   RM_VEX_0F3849_X86_64_P_0_W_0_M_1_R_0
@@ -1033,6 +1036,7 @@ enum
   PREFIX_0F38F8,
   PREFIX_0F38FA,
   PREFIX_0F38FB,
+  PREFIX_0F3A0F,
   PREFIX_VEX_0F10,
   PREFIX_VEX_0F11,
   PREFIX_VEX_0F12,
@@ -2918,6 +2922,10 @@ static const struct dis386 reg_table[][8] = {
     { "aesencwide256kl",	{ M }, 0 },
     { "aesdecwide256kl",	{ M }, 0 },
   },
+  /* REG_0F3A0F_PREFIX_1_MOD_3 */
+  {
+    { RM_TABLE (RM_0F3A0F_P_1_MOD_3_REG_0) },
+  },
   /* REG_0F71 */
   {
     { Bad_Opcode },
@@ -3680,6 +3688,12 @@ static const struct dis386 prefix_table[][4] = {
     { MOD_TABLE (MOD_0F38FB_PREFIX_1) },
   },
 
+  /* PREFIX_0F3A0F */
+  {
+    { Bad_Opcode },
+    { MOD_TABLE (MOD_0F3A0F_PREFIX_1)},
+  },
+
   /* PREFIX_VEX_0F10 */
   {
     { "vmovups",	{ XM, EXx }, 0 },
@@ -4875,7 +4889,7 @@ static const struct dis386 three_byte_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* f0 */
-    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_0F3A0F) },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
@@ -8335,6 +8349,11 @@ static const struct dis386 mod_table[][2] = {
     { Bad_Opcode },
     { "encodekey256", { Gd, Ed }, 0 },
   },
+  {
+    /* MOD_0F3A0F_PREFIX_1 */
+    { Bad_Opcode },
+    { REG_TABLE (REG_0F3A0F_PREFIX_1_MOD_3) },
+  },
   {
     /* MOD_62_32BIT */
     { "bound{S|}",	{ Gv, Ma }, 0 },
@@ -8899,6 +8918,10 @@ static const struct dis386 rm_table[][8] = {
     { "nopQ",		{ Ev }, 0 },
     { "nopQ",		{ Ev }, 0 },
   },
+  {
+    /* RM_0F3A0F_P_1_MOD_3_REG_0 */
+    { "hreset",		{ Skip_MODRM, Ib }, 0 },
+  },
   {
     /* RM_0FAE_REG_6_MOD_3 */
     { "mfence",		{ Skip_MODRM }, 0 },
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 95c5852b62..9f14bc063d 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -327,6 +327,8 @@ static initializer cpu_flag_init[] =
     "CpuKL" },
   { "CPU_WIDEKL_FLAGS",
     "CpuWideKL" },
+  { "CPU_HRESET_FLAGS",
+    "CpuHRESET"},
   { "CPU_ANY_X87_FLAGS",
     "CPU_ANY_287_FLAGS|Cpu8087" },
   { "CPU_ANY_287_FLAGS",
@@ -419,6 +421,8 @@ static initializer cpu_flag_init[] =
     "CpuKL|CpuWideKL" },
   { "CPU_ANY_WIDEKL_FLAGS",
     "CpuWideKL" },
+  { "CPU_ANY_HRESET_FLAGS",
+    "CpuHRESET" },
 };
 
 static initializer operand_type_init[] =
@@ -651,6 +655,7 @@ static bitfield cpu_flags[] =
   BITFIELD (CpuTSXLDTRK),
   BITFIELD (CpuKL),
   BITFIELD (CpuWideKL),
+  BITFIELD (CpuHRESET),
 #ifdef CpuUnused
   BITFIELD (CpuUnused),
 #endif
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index 7e8947d983..c70783d9b6 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -265,6 +265,8 @@ enum
   CpuKL,
   /* WideKL instruction support required */
   CpuWideKL,
+  /* HRESET instruction required */
+  CpuHRESET,
   /* 64bit support required  */
   Cpu64,
   /* Not supported in the 64bit mode  */
@@ -405,6 +407,7 @@ typedef union i386_cpu_flags
       unsigned int cputsxldtrk:1;
       unsigned int cpukl:1;
       unsigned int cpuwidekl:1;
+      unsigned int cpuhreset:1;
       unsigned int cpu64:1;
       unsigned int cpuno64:1;
 #ifdef CpuUnused
@@ -889,7 +892,7 @@ typedef struct insn_template
 
   /* base_opcode is the fundamental opcode byte without optional
      prefix(es).  */
-  unsigned int base_opcode;
+  unsigned long long base_opcode;
 #define Opcode_D	0x2 /* Direction bit:
 			       set if Reg --> Regmem;
 			       unset if Regmem --> Reg. */
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index c8fe65a162..c741846f77 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -4142,3 +4142,9 @@ seamops, 0, 0x660f01ce, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|N
 seamcall, 0, 0x660f01cf, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 
 // TDX instructions end.
+
+// HRESET instructions.
+
+hreset, 1, 0xf30f3af0c0, None, 4, CpuHRESET, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8 }
+
+// HRESET instructions end.
-- 
2.17.1

Thanks,
Lili.


More information about the Binutils mailing list