Hi all, This patch is about to enable binutils support for Intel TDX. Intel Trust Domains Extensions(Intel TDX), more details please refer to https://software.intel.com/content/dam/develop/external/us/en/documents/intel-tdx-cpu-architectural-specification.pdf Make check-gas is ok. Add support for Intel TDX instructions. gas/ * NEWS: Add TDX. * config/tc-i386.c (cpu_arch): Add .tdx. (cpu_noarch): Likewise. * doc/c-i386.texi: Document tdx. * testsuite/gas/i386/i386.exp: Run tdx tests. * testsuite/gas/i386/tdx.d: Likewise. * testsuite/gas/i386/tdx.s: Likewise. * testsuite/gas/i386/x86-64-tdx.d: Likewise. * testsuite/gas/i386/x86-64-tdx.s: Likewise. opcodes/ * i386-dis.c (enum): Add PREFIX_0F01_REG_1_RM_5, PREFIX_0F01_REG_1_RM_6, PREFIX_0F01_REG_1_RM_7, X86_64_0F01_REG_1_RM_5_P_2, X86_64_0F01_REG_1_RM_6_P_2, X86_64_0F01_REG_1_RM_7_P_2. (prefix_table): Likewise. (x86_64_table): Likewise. (rm_table): Likewise. * i386-gen.c (cpu_flag_init): Add CPU_TDX_FLAGS and CPU_ANY_TDX_FLAGS. (cpu_flags): Add CpuTDX. * i386-opc.h (enum): Add CpuTDX. (i386_cpu_flags): Add cputdx. * i386-opc.tbl: Add TDX insns. * i386-init.h: Regenerate. * i386-tbl.h: Likewise. --- gas/NEWS | 2 + gas/config/tc-i386.c | 3 ++ gas/doc/c-i386.texi | 3 ++ gas/testsuite/gas/i386/i386.exp | 2 + gas/testsuite/gas/i386/tdx.d | 12 ++++++ gas/testsuite/gas/i386/tdx.s | 5 +++ gas/testsuite/gas/i386/x86-64-tdx.d | 15 +++++++ gas/testsuite/gas/i386/x86-64-tdx.s | 8 ++++ opcodes/i386-dis.c | 65 +++++++++++++++++++++++++++-- opcodes/i386-gen.c | 5 +++ opcodes/i386-opc.h | 3 ++ opcodes/i386-opc.tbl | 9 ++++ 12 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/i386/tdx.d create mode 100644 gas/testsuite/gas/i386/tdx.s create mode 100644 gas/testsuite/gas/i386/x86-64-tdx.d create mode 100644 gas/testsuite/gas/i386/x86-64-tdx.s diff --git a/gas/NEWS b/gas/NEWS index d709edf9b5..8c9b925005 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for Intel TDX instructions. + * Added a .nop directive to generate a single no-op instruction in a target neutral manner. This instruction does have an effect on DWARF line number generation, if that is active. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d237352fbe..b7934ba8ee 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1220,6 +1220,8 @@ static const arch_entry cpu_arch[] = CPU_AVX512_BF16_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512_vp2intersect"), PROCESSOR_UNKNOWN, CPU_AVX512_VP2INTERSECT_FLAGS, 0 }, + { STRING_COMMA_LEN (".tdx"), PROCESSOR_UNKNOWN, + CPU_TDX_FLAGS, 0 }, { STRING_COMMA_LEN (".enqcmd"), PROCESSOR_UNKNOWN, CPU_ENQCMD_FLAGS, 0 }, { STRING_COMMA_LEN (".serialize"), PROCESSOR_UNKNOWN, @@ -1278,6 +1280,7 @@ static const noarch_entry cpu_noarch[] = { STRING_COMMA_LEN ("noavx512_bf16"), CPU_ANY_AVX512_BF16_FLAGS }, { STRING_COMMA_LEN ("noavx512_vp2intersect"), CPU_ANY_AVX512_VP2INTERSECT_FLAGS }, + { STRING_COMMA_LEN ("notdx"), CPU_ANY_TDX_FLAGS }, { STRING_COMMA_LEN ("noenqcmd"), CPU_ANY_ENQCMD_FLAGS }, { STRING_COMMA_LEN ("noserialize"), CPU_ANY_SERIALIZE_FLAGS }, { STRING_COMMA_LEN ("notsxldtrk"), CPU_ANY_TSXLDTRK_FLAGS }, diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index 64a563aacb..d079c8e3bb 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -205,6 +205,7 @@ accept various extension mnemonics. For example, @code{avx512_vnni}, @code{avx512_bitalg}, @code{avx512_vp2intersect}, +@code{tdx}, @code{avx512_bf16}, @code{noavx512f}, @code{noavx512cd}, @@ -222,6 +223,7 @@ accept various extension mnemonics. For example, @code{noavx512_vnni}, @code{noavx512_bitalg}, @code{noavx512_vp2intersect}, +@code{notdx}, @code{noavx512_bf16}, @code{noenqcmd}, @code{noserialize}, @@ -1499,6 +1501,7 @@ supported on the CPU specified. The choices for @var{cpu_type} are: @item @samp{.avx512vbmi} @tab @samp{.avx512_4fmaps} @tab @samp{.avx512_4vnniw} @item @samp{.avx512_vpopcntdq} @tab @samp{.avx512_vbmi2} @tab @samp{.avx512_vnni} @item @samp{.avx512_bitalg} @tab @samp{.avx512_bf16} @tab @samp{.avx512_vp2intersect} +@item @samp{.tdx} @item @samp{.clwb} @tab @samp{.rdpid} @tab @samp{.ptwrite} @tab @item @samp{.ibt} @item @samp{.wbnoinvd} @tab @samp{.pconfig} @tab @samp{.waitpkg} @tab @samp{.cldemote} @item @samp{.shstk} @tab @samp{.gfni} @tab @samp{.vaes} @tab @samp{.vpclmulqdq} diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 132e5d7834..285d26e231 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -489,6 +489,7 @@ if [gas_32_check] then { run_dump_test "enqcmd-intel" run_list_test "enqcmd-inval" run_dump_test "serialize" + run_dump_test "tdx" run_dump_test "tsxldtrk" run_dump_test "vp2intersect" run_dump_test "vp2intersect-intel" @@ -1094,6 +1095,7 @@ if [gas_64_check] then { run_dump_test "x86-64-enqcmd-intel" run_list_test "x86-64-enqcmd-inval" run_dump_test "x86-64-serialize" + run_dump_test "x86-64-tdx" run_dump_test "x86-64-tsxldtrk" run_dump_test "x86-64-vp2intersect" run_dump_test "x86-64-vp2intersect-intel" diff --git a/gas/testsuite/gas/i386/tdx.d b/gas/testsuite/gas/i386/tdx.d new file mode 100644 index 0000000000..35263be397 --- /dev/null +++ b/gas/testsuite/gas/i386/tdx.d @@ -0,0 +1,12 @@ +#as: +#objdump: -dw +#name: TDX insns +#source: tdx.s + +.*: +file format .* + +Disassembly of section \.text: + +0+ <_start>: +[ ]*[a-f0-9]+: 66 0f 01 cc + tdcall * +#pass diff --git a/gas/testsuite/gas/i386/tdx.s b/gas/testsuite/gas/i386/tdx.s new file mode 100644 index 0000000000..6097fe3a76 --- /dev/null +++ b/gas/testsuite/gas/i386/tdx.s @@ -0,0 +1,5 @@ +# Check TDX instructions. + + .text +_start: + tdcall diff --git a/gas/testsuite/gas/i386/x86-64-tdx.d b/gas/testsuite/gas/i386/x86-64-tdx.d new file mode 100644 index 0000000000..ea3e83cde6 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-tdx.d @@ -0,0 +1,15 @@ +#as: +#objdump: -dw +#name: x86_64 TDX insns +#source: x86-64-tdx.s + +.*: +file format .* + +Disassembly of section \.text: + +0+ <_start>: +[ ]*[a-f0-9]+: 66 0f 01 cc + tdcall * +[ ]*[a-f0-9]+: 66 0f 01 cd + seamret * +[ ]*[a-f0-9]+: 66 0f 01 ce + seamops * +[ ]*[a-f0-9]+: 66 0f 01 cf + seamcall * +#pass diff --git a/gas/testsuite/gas/i386/x86-64-tdx.s b/gas/testsuite/gas/i386/x86-64-tdx.s new file mode 100644 index 0000000000..1cf4035475 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-tdx.s @@ -0,0 +1,8 @@ +# Check TDX instructions. + + .text +_start: + tdcall + seamret + seamops + seamcall diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 6d803258ef..89d8fc64fc 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -945,6 +945,10 @@ enum enum { PREFIX_90 = 0, + PREFIX_0F01_REG_1_RM_4, + PREFIX_0F01_REG_1_RM_5, + PREFIX_0F01_REG_1_RM_6, + PREFIX_0F01_REG_1_RM_7, PREFIX_0F01_REG_3_RM_1, PREFIX_0F01_REG_5_MOD_0, PREFIX_0F01_REG_5_MOD_3_RM_0, @@ -1161,6 +1165,9 @@ enum X86_64_EA, X86_64_0F01_REG_0, X86_64_0F01_REG_1, + X86_64_0F01_REG_1_RM_5_PREFIX_2, + X86_64_0F01_REG_1_RM_6_PREFIX_2, + X86_64_0F01_REG_1_RM_7_PREFIX_2, X86_64_0F01_REG_2, X86_64_0F01_REG_3, X86_64_0F24, @@ -3062,6 +3069,38 @@ static const struct dis386 prefix_table[][4] = { { NULL, { { NULL, 0 } }, PREFIX_IGNORED } }, + /* PREFIX_0F01_REG_1_RM_4 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { "tdcall", { Skip_MODRM }, 0 }, + { Bad_Opcode }, + }, + + /* PREFIX_0F01_REG_1_RM_5 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { X86_64_TABLE (X86_64_0F01_REG_1_RM_5_PREFIX_2) }, + { Bad_Opcode }, + }, + + /* PREFIX_0F01_REG_1_RM_6 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { X86_64_TABLE (X86_64_0F01_REG_1_RM_6_PREFIX_2) }, + { Bad_Opcode }, + }, + + /* PREFIX_0F01_REG_1_RM_7 */ + { + { "encls", { Skip_MODRM }, 0 }, + { Bad_Opcode }, + { X86_64_TABLE (X86_64_0F01_REG_1_RM_7_PREFIX_2) }, + { Bad_Opcode }, + }, + /* PREFIX_0F01_REG_3_RM_1 */ { { "vmmcall", { Skip_MODRM }, 0 }, @@ -4139,6 +4178,24 @@ static const struct dis386 x86_64_table[][2] = { { "sidt", { M }, 0 }, }, + /* X86_64_0F01_REG_1_RM_5_PREFIX_2 */ + { + { Bad_Opcode }, + { "seamret", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0F01_REG_1_RM_6_PREFIX_2 */ + { + { Bad_Opcode }, + { "seamops", { Skip_MODRM }, 0 }, + }, + + /* X86_64_0F01_REG_1_RM_7_PREFIX_2 */ + { + { Bad_Opcode }, + { "seamcall", { Skip_MODRM }, 0 }, + }, + /* X86_64_0F01_REG_2 */ { { "lgdt{Q|Q}", { M }, 0 }, @@ -8691,10 +8748,10 @@ static const struct dis386 rm_table[][8] = { { "mwait", { { OP_Mwait, 0 } }, 0 }, { "clac", { Skip_MODRM }, 0 }, { "stac", { Skip_MODRM }, 0 }, - { Bad_Opcode }, - { Bad_Opcode }, - { Bad_Opcode }, - { "encls", { Skip_MODRM }, 0 }, + { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_4) }, + { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_5) }, + { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_6) }, + { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_7) }, }, { /* RM_0F01_REG_2 */ diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 3334155071..642297518f 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -313,6 +313,8 @@ static initializer cpu_flag_init[] = "CpuSERIALIZE" }, { "CPU_AVX512_VP2INTERSECT_FLAGS", "CpuAVX512_VP2INTERSECT" }, + { "CPU_TDX_FLAGS", + "CpuTDX" }, { "CPU_RDPRU_FLAGS", "CpuRDPRU" }, { "CPU_MCOMMIT_FLAGS", @@ -405,6 +407,8 @@ static initializer cpu_flag_init[] = "CpuSERIALIZE" }, { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS", "CpuAVX512_VP2INTERSECT" }, + { "CPU_ANY_TDX_FLAGS", + "CpuTDX" }, { "CPU_ANY_TSXLDTRK_FLAGS", "CpuTSXLDTRK" }, }; @@ -611,6 +615,7 @@ static bitfield cpu_flags[] = BITFIELD (CpuAVX512_BITALG), BITFIELD (CpuAVX512_BF16), BITFIELD (CpuAVX512_VP2INTERSECT), + BITFIELD (CpuTDX), BITFIELD (CpuMWAITX), BITFIELD (CpuCLZERO), BITFIELD (CpuOSPKE), diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index 09ee615db1..3a2e260ff2 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -210,6 +210,8 @@ enum CpuAVX512_BF16, /* Intel AVX-512 VP2INTERSECT Instructions support required. */ CpuAVX512_VP2INTERSECT, + /* TDX Instructions support required. */ + CpuTDX, /* mwaitx instruction required */ CpuMWAITX, /* Clzero instruction required */ @@ -371,6 +373,7 @@ typedef union i386_cpu_flags unsigned int cpuavx512_bitalg:1; unsigned int cpuavx512_bf16:1; unsigned int cpuavx512_vp2intersect:1; + unsigned int cputdx:1; unsigned int cpumwaitx:1; unsigned int cpuclzero:1; unsigned int cpuospke:1; diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 181d0df1ce..c51d5ea14d 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -4117,3 +4117,12 @@ tilerelease, 0, 0x49c0, None, 2, CpuAMX_TILE|Cpu64, Vex128|VexOpcode=1|VexW0|No_ tilezero, 1, 0xf249, None, 1, CpuAMX_TILE|Cpu64, Modrm|Vex128|VexOpcode=1|VexW0|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegTMM } // AMX instructions end. + +// TDX instructions. + +tdcall, 0, 0x660f01cc, None, 3, CpuTDX, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +seamret, 0, 0x660f01cd, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +seamops, 0, 0x660f01ce, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } +seamcall, 0, 0x660f01cf, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 } + +// TDX instructions end. -- 2.17.1 Thanks, Lili.