From 998c127159d4091c5333680b13f0f1fdfaaf6c67 Mon Sep 17 00:00:00 2001 From: guenther Date: Sun, 9 Sep 2018 21:59:43 +0000 Subject: [PATCH] Teach binutils how to assemble INVPCID and how to disassemble INV{EPT,VPID,PCID} ok mlarkin@ --- .../binutils-2.17/gas/config/tc-i386.c | 7 +++--- .../binutils-2.17/include/opcode/i386.h | 4 ++++ gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c | 22 ++++++++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.c b/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.c index 70422ee6e88..d0f3bb58dea 100644 --- a/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.c +++ b/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.c @@ -3464,8 +3464,8 @@ output_insn () goto check_prefix; } } - else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881) { - /* invept and invvpid are 3 byte instructions with a + else if ((i.tm.base_opcode & ~3) == 0x660f3880) { + /* INVEPT, INVVPID, and INVPCID are 3 byte instructions with a mandatory prefix. */ prefix = (i.tm.base_opcode >> 24) & 0xff; add_prefix (prefix); @@ -3508,8 +3508,7 @@ check_prefix: p = frag_more (3); *p++ = (i.tm.base_opcode >> 16) & 0xff; } - else if (i.tm.base_opcode == 0x660f3880 || - i.tm.base_opcode == 0x660f3881) + else if ((i.tm.base_opcode & ~3) == 0x660f3880) { p = frag_more (3); *p++ = (i.tm.base_opcode >> 16) & 0xff; diff --git a/gnu/usr.bin/binutils-2.17/include/opcode/i386.h b/gnu/usr.bin/binutils-2.17/include/opcode/i386.h index 39155a55bb3..7b315144c1e 100644 --- a/gnu/usr.bin/binutils-2.17/include/opcode/i386.h +++ b/gnu/usr.bin/binutils-2.17/include/opcode/i386.h @@ -1530,6 +1530,10 @@ static const template i386_optab[] = {"xrstor", 1, 0x0fae, 5, CpuXSAVE, q_Suf|Modrm, { LLongMem, 0, 0 } }, {"xsaveopt", 1, 0x0fae, 6, CpuXSAVE, q_Suf|Modrm, { LLongMem, 0, 0 } }, +/* Intel PCID extension */ +{"invpcid", 2, 0x660f3882, X, CpuNEW|CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 } }, +{"invpcid", 2, 0x660f3882, X, CpuNEW|Cpu64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg64 } }, + /* sentinel */ {NULL, 0, 0, 0, 0, 0, { 0, 0, 0} } }; diff --git a/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c b/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c index d27a741d624..ee34ed399e0 100644 --- a/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c +++ b/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c @@ -106,6 +106,7 @@ static void VMX_Fixup (int, int); static void REP_Fixup (int, int); static void OP_0f38 (int, int); static void OP_0f3a (int, int); +static void OP_data (int, int); struct dis_private { /* Points to first byte not fetched. */ @@ -222,6 +223,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Ma OP_E, v_mode #define M OP_M, 0 /* lea, lgdt, etc. */ #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */ +#define Mq OP_M, q_mode /* 128 bit memory operand for INV{EPT,VPID,PCID} */ #define Gb OP_G, b_mode #define Gv OP_G, v_mode #define Gd OP_G, d_mode @@ -322,6 +324,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define OP0FAE OP_0fae, v_mode #define OP0F38 OP_0f38, 0 #define OP0F3A OP_0f3a, 0 +#define OPDATA OP_data, 0 /* Used handle "rep" prefix for string instructions. */ #define Xbr REP_Fixup, eSI_reg @@ -1910,9 +1913,9 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, /* 80 */ - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { "invept", OPDATA, Gm, Mq }, + { "invvpid", OPDATA, Gm, Mq }, + { "invpcid", OPDATA, Gm, Mq }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, @@ -5533,3 +5536,16 @@ OP_0f38 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) used_prefixes |= (prefixes & PREFIX_DATA); USED_REX(rex); } + +/* suppress/require a mandatory 0x66 data size prefix */ +static void +OP_data (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) +{ + if (prefixes & PREFIX_DATA) + used_prefixes |= PREFIX_DATA; + else + { + BadOp(); + return; + } +} -- 2.20.1