From dffe0dc4d2d762d7193b84053828040d383b0233 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 Sep 2013 21:21:47 +0000 Subject: [PATCH] Add support for the 'invpcid' instruction to binutils and DDB's disassembler on amd64. MFC after: 1 month --- contrib/binutils/gas/config/tc-i386.c | 6 ++++-- contrib/binutils/opcodes/i386-dis.c | 11 ++++++++++- contrib/binutils/opcodes/i386-opc.tbl | 4 ++++ contrib/binutils/opcodes/i386-tbl.h | 8 ++++++++ sys/amd64/amd64/db_disasm.c | 2 +- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/contrib/binutils/gas/config/tc-i386.c b/contrib/binutils/gas/config/tc-i386.c index 5ba2ce29c2b0..6eb51aa1d503 100644 --- a/contrib/binutils/gas/config/tc-i386.c +++ b/contrib/binutils/gas/config/tc-i386.c @@ -3990,7 +3990,8 @@ output_insn (void) goto check_prefix; } } - else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881) + else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881 + || i.tm.base_opcode == 0x660f3882) { /* invept and invvpid are 3 byte instructions with a mandatory prefix. */ @@ -4040,7 +4041,8 @@ output_insn (void) *p++ = (i.tm.base_opcode >> 16) & 0xff; } else if (i.tm.base_opcode == 0x660f3880 || - i.tm.base_opcode == 0x660f3881) + i.tm.base_opcode == 0x660f3881 || + i.tm.base_opcode == 0x660f3882) { p = frag_more (3); *p++ = (i.tm.base_opcode >> 16) & 0xff; diff --git a/contrib/binutils/opcodes/i386-dis.c b/contrib/binutils/opcodes/i386-dis.c index 6ef04348d763..eb33089a407f 100644 --- a/contrib/binutils/opcodes/i386-dis.c +++ b/contrib/binutils/opcodes/i386-dis.c @@ -550,6 +550,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } } #define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } } #define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } } +#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } } #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } } @@ -2668,6 +2669,14 @@ static const struct dis386 prefix_user_table[][4] = { { "pclmulqdq", { XM, EXx, Ib } }, { "(bad)", { XX } }, }, + + /* PREGRP107 */ + { + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "invpcid",{ Gm, Mo } }, + { "(bad)", { XX } }, + }, }; static const struct dis386 x86_64_table[][2] = { @@ -2839,7 +2848,7 @@ static const struct dis386 three_byte_table[][256] = { /* 80 */ { PREGRP98 }, { PREGRP99 }, - { "(bad)", { XX } }, + { PREGRP107 }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, diff --git a/contrib/binutils/opcodes/i386-opc.tbl b/contrib/binutils/opcodes/i386-opc.tbl index f1f5ae5fb361..6cb72199fd48 100644 --- a/contrib/binutils/opcodes/i386-opc.tbl +++ b/contrib/binutils/opcodes/i386-opc.tbl @@ -1498,3 +1498,7 @@ xsetbv, 0, 0xf01, 0xd1, CpuXSAVE, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSu xsave, 1, 0xfae, 0x4, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S } xsaveopt, 1, 0xfae, 0x6, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S } xrstor, 1, 0xfae, 0x5, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S } + +// INVPCID +invpcid, 2, 0x660f3882, None, CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 } +invpcid, 2, 0x660f3882, None, Cpu64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg64 } diff --git a/contrib/binutils/opcodes/i386-tbl.h b/contrib/binutils/opcodes/i386-tbl.h index 4ee72a4806ba..c42f56591bc3 100644 --- a/contrib/binutils/opcodes/i386-tbl.h +++ b/contrib/binutils/opcodes/i386-tbl.h @@ -3641,6 +3641,14 @@ const template i386_optab[] = Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg64 } }, + { "invpcid", 2, 0x660f3882, None, CpuNo64, + Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, + { BaseIndex|Disp8|Disp16|Disp32|Disp32S, + Reg32 } }, + { "invpcid", 2, 0x660f3882, None, Cpu64, + Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, + { BaseIndex|Disp8|Disp16|Disp32|Disp32S, + Reg64 } }, { "vmcall", 0, 0xf01, 0xc1, CpuVMX, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 } }, diff --git a/sys/amd64/amd64/db_disasm.c b/sys/amd64/amd64/db_disasm.c index 46144e0954aa..b229909c41dd 100644 --- a/sys/amd64/amd64/db_disasm.c +++ b/sys/amd64/amd64/db_disasm.c @@ -127,7 +127,7 @@ struct finst { static const struct inst db_inst_0f388x[] = { /*80*/ { "", TRUE, SDEP, op2(E, Rq), "invept" }, /*81*/ { "", TRUE, SDEP, op2(E, Rq), "invvpid" }, -/*82*/ { "", FALSE, NONE, 0, 0 }, +/*82*/ { "", TRUE, SDEP, op2(E, Rq), "invpcid" }, /*83*/ { "", FALSE, NONE, 0, 0 }, /*84*/ { "", FALSE, NONE, 0, 0 }, /*85*/ { "", FALSE, NONE, 0, 0 },