From 8478cfe5ad6173c221d9b56067968416e7c00af1 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 12 Oct 2020 10:36:01 +0800 Subject: [PATCH] x86: Support Intel UINTR gas/ * config/tc-i386.c (cpu_arch): Add .uintr. (cpu_noarch): Likewise. * doc/c-i386.texi: Document .uintr and nouintr. * testsuite/gas/i386/i386.exp: Run UINTR tests. * testsuite/gas/i386/x86-64-uintr.d: Likewise. * testsuite/gas/i386/x86-64-uintr.s: Likewise. opcodes/ * i386-dis.c (enum): Add PREFIX_MOD_3_0F01_REG_5_RM_4, PREFIX_MOD_3_0F01_REG_5_RM_5, PREFIX_MOD_3_0F01_REG_5_RM_6, PREFIX_MOD_3_0F01_REG_5_RM_7, X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1, 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_0FC7_REG_6_MOD_3_PREFIX_1. (prefix_table): New instructions (see prefixes above). (rm_table): Likewise * i386-gen.c (cpu_flag_init): Add CPU_UINTR_FLAGS, CPU_ANY_UINTR_FLAGS. (cpu_flags): Add CpuUINTR. * i386-opc.h (enum): Add CpuUINTR. (i386_cpu_flags): Add cpuuintr. * i386-opc.tbl: Add UINTR insns. * i386-init.h: Regenerate. * i386-tbl.h: Likewise. --- gas/config/tc-i386.c | 3 ++ gas/doc/c-i386.texi | 4 +- gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/x86-64-uintr.d | 17 ++++++ gas/testsuite/gas/i386/x86-64-uintr.s | 10 ++++ opcodes/i386-dis.c | 75 ++++++++++++++++++++++++--- opcodes/i386-gen.c | 5 ++ opcodes/i386-opc.h | 3 ++ opcodes/i386-opc.tbl | 10 ++++ 9 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-uintr.d create mode 100644 gas/testsuite/gas/i386/x86-64-uintr.s diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index b1e8f7cf1f..644039e5e2 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 (".uintr"), PROCESSOR_UNKNOWN, + CPU_UINTR_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 ("nouintr"), CPU_ANY_UINTR_FLAGS }, }; #ifdef I386COFF diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index 776fed8ed5..5f58b893b1 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -238,6 +238,7 @@ accept various extension mnemonics. For example, @code{noamx_bf16}, @code{amx_tile}, @code{noamx_tile}, +@code{nouintr}, @code{vmx}, @code{vmfunc}, @code{smx}, @@ -265,6 +266,7 @@ accept various extension mnemonics. For example, @code{wbnoinvd}, @code{pconfig}, @code{waitpkg}, +@code{uintr}, @code{cldemote}, @code{rdpru}, @code{mcommit}, @@ -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{.uintr} @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/i386.exp b/gas/testsuite/gas/i386/i386.exp index 8645f3061c..66366a06ce 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -1094,6 +1094,7 @@ if [gas_64_check] then { run_dump_test "x86-64-pconfig-intel" run_dump_test "x86-64-waitpkg" run_dump_test "x86-64-waitpkg-intel" + run_dump_test "x86-64-uintr" run_dump_test "x86-64-cldemote" run_dump_test "x86-64-cldemote-intel" run_dump_test "x86-64-movdir" diff --git a/gas/testsuite/gas/i386/x86-64-uintr.d b/gas/testsuite/gas/i386/x86-64-uintr.d new file mode 100644 index 0000000000..22080921bb --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-uintr.d @@ -0,0 +1,17 @@ +#as: +#objdump: -dw +#name: x86_64 UINTR insns +#source: x86-64-uintr.s + +.*: +file format .* + +Disassembly of section \.text: + +0+ <_start>: + +[a-f0-9]+: f3 0f 01 ec uiret * + +[a-f0-9]+: f3 0f 01 ed testui * + +[a-f0-9]+: f3 0f 01 ee clui * + +[a-f0-9]+: f3 0f 01 ef stui * + +[a-f0-9]+: f3 0f c7 f0 senduipi %rax + +[a-f0-9]+: f3 41 0f c7 f2 senduipi %r10 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-uintr.s b/gas/testsuite/gas/i386/x86-64-uintr.s new file mode 100644 index 0000000000..0cbda3ee74 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-uintr.s @@ -0,0 +1,10 @@ +# Check 64bit UINTR instructions. + + .text +_start: + uiret + testui + clui + stui + senduipi %rax + senduipi %r10 diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 4d8f4f4cc2..a55a629170 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -961,6 +961,10 @@ enum PREFIX_0F01_REG_5_MOD_3_RM_0, PREFIX_0F01_REG_5_MOD_3_RM_1, PREFIX_0F01_REG_5_MOD_3_RM_2, + PREFIX_0F01_REG_5_MOD_3_RM_4, + PREFIX_0F01_REG_5_MOD_3_RM_5, + 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_0F09, PREFIX_0F10, @@ -1189,7 +1193,12 @@ enum X86_64_VEX_0F3849, X86_64_VEX_0F384B, X86_64_VEX_0F385C, - X86_64_VEX_0F385E + X86_64_VEX_0F385E, + X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1, + 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_0FC7_REG_6_MOD_3_PREFIX_1 }; enum @@ -3158,6 +3167,30 @@ static const struct dis386 prefix_table[][4] = { { "saveprevssp", { Skip_MODRM }, PREFIX_OPCODE }, }, + /* PREFIX_0F01_REG_5_MOD_3_RM_4 */ + { + { Bad_Opcode }, + { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1) }, + }, + + /* PREFIX_0F01_REG_5_MOD_3_RM_5 */ + { + { Bad_Opcode }, + { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1) }, + }, + + /* PREFIX_0F01_REG_5_MOD_3_RM_6 */ + { + { "rdpkru", { Skip_MODRM }, 0 }, + { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1) }, + }, + + /* PREFIX_0F01_REG_5_MOD_3_RM_7 */ + { + { "wrpkru", { Skip_MODRM }, 0 }, + { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1) }, + }, + /* PREFIX_0F01_REG_7_MOD_3_RM_2 */ { { "monitorx", { { OP_Monitor, 0 } }, 0 }, @@ -3546,7 +3579,7 @@ static const struct dis386 prefix_table[][4] = { /* PREFIX_0FC7_REG_6_MOD_3 */ { { "rdrand", { Ev }, 0 }, - { Bad_Opcode }, + { X86_64_TABLE (X86_64_0FC7_REG_6_MOD_3_PREFIX_1) }, { "rdrand", { Ev }, 0 } }, @@ -4307,6 +4340,36 @@ static const struct dis386 x86_64_table[][2] = { { Bad_Opcode }, { PREFIX_TABLE (PREFIX_VEX_0F385E_X86_64) }, }, + + /* X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1 */ + { + { Bad_Opcode }, + { "uiret", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1 */ + { + { Bad_Opcode }, + { "testui", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1 */ + { + { Bad_Opcode }, + { "clui", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1 */ + { + { Bad_Opcode }, + { "stui", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0FC7_REG_6_MOD_3_PREFIX_1 */ + { + { Bad_Opcode }, + { "senduipi", { Eq }, 0 }, + }, }; static const struct dis386 three_byte_table[][256] = { @@ -8874,10 +8937,10 @@ static const struct dis386 rm_table[][8] = { { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_1) }, { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_2) }, { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { "rdpkru", { Skip_MODRM }, 0 }, - { "wrpkru", { Skip_MODRM }, 0 }, + { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_4) }, + { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_5) }, + { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_6) }, + { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_7) }, }, { /* RM_0F01_REG_7_MOD_3 */ diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 81c68cdf43..9232743f36 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -295,6 +295,8 @@ static initializer cpu_flag_init[] = "CpuPCONFIG" }, { "CPU_WAITPKG_FLAGS", "CpuWAITPKG" }, + { "CPU_UINTR_FLAGS", + "CpuUINTR" }, { "CPU_CLDEMOTE_FLAGS", "CpuCLDEMOTE" }, { "CPU_AMX_INT8_FLAGS", @@ -403,6 +405,8 @@ static initializer cpu_flag_init[] = "CpuAMX_TILE|CpuAMX_INT8|CpuAMX_BF16" }, { "CPU_ANY_MOVDIRI_FLAGS", "CpuMOVDIRI" }, + { "CPU_ANY_UINTR_FLAGS", + "CpuUINTR" }, { "CPU_ANY_MOVDIR64B_FLAGS", "CpuMOVDIR64B" }, { "CPU_ANY_ENQCMD_FLAGS", @@ -637,6 +641,7 @@ static bitfield cpu_flags[] = BITFIELD (CpuWBNOINVD), BITFIELD (CpuPCONFIG), BITFIELD (CpuWAITPKG), + BITFIELD (CpuUINTR), BITFIELD (CpuCLDEMOTE), BITFIELD (CpuAMX_INT8), BITFIELD (CpuAMX_BF16), diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index e783683d0c..4dbb1f426c 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -243,6 +243,8 @@ enum CpuPCONFIG, /* WAITPKG instructions required */ CpuWAITPKG, + /* UINTR instructions required */ + CpuUINTR, /* CLDEMOTE instruction required */ CpuCLDEMOTE, /* MOVDIRI instruction support required */ @@ -394,6 +396,7 @@ typedef union i386_cpu_flags unsigned int cpuwbnoinvd:1; unsigned int cpupconfig:1; unsigned int cpuwaitpkg:1; + unsigned int cpuuintr:1; unsigned int cpucldemote:1; unsigned int cpumovdiri:1; unsigned int cpumovdir64b:1; diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 2c7184b0e9..6267d980af 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -4146,3 +4146,13 @@ 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. + +// UINTR instructions. + +uiret, 0, 0x0f01ec, None, 3, CpuUINTR|Cpu64, Prefix_0XF3|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +clui, 0, 0x0f01ee, None, 3, CpuUINTR|Cpu64, Prefix_0XF3|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +stui, 0, 0x0f01ef, None, 3, CpuUINTR|Cpu64, Prefix_0XF3|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +testui, 0, 0x0f01ed, None, 3, CpuUINTR|Cpu64, Prefix_0XF3|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +senduipi, 1, 0x0fc7, 0x6, 2, CpuUINTR|Cpu64, Prefix_0XF3|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Reg64 } + +// UINTR instructions end. -- 2.17.1