summaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2018-09-09 21:59:44 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2018-09-09 21:59:44 +0000
commit5521731e156dcd43760afa91e52643926d0a947f (patch)
tree4036fcf8511cad4a67792b2df8e0024d6924a2da /gnu/usr.bin
parented06c3f6f1407f753689f7842e2c879ce1d029ee (diff)
Teach binutils how to assemble INVPCID and how to disassemble
INV{EPT,VPID,PCID} ok mlarkin@
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/binutils-2.17/gas/config/tc-i386.c7
-rw-r--r--gnu/usr.bin/binutils-2.17/include/opcode/i386.h4
-rw-r--r--gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c22
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;
+ }
+}