svn commit: r239878 - in stable/9/contrib/binutils: gas/config
opcodes
John Baldwin
jhb at FreeBSD.org
Wed Aug 29 19:34:47 UTC 2012
Author: jhb
Date: Wed Aug 29 19:34:46 2012
New Revision: 239878
URL: http://svn.freebsd.org/changeset/base/239878
Log:
MFC 238123,238167:
- Add support for the 'xsave', 'xrstor', 'xsaveopt', 'xgetbv', and 'xsetbv'
instructions. I reimplemented this from scratch based on the Intel
manuals and the existing support for handling the fxsave and fxrstor
instructions.
- Add support for the 'invept' and 'invvpid' instructions. Beyond simply
adding appropriate table entries, the assembler had to be adjusted as
these are the first non-SSE instructions to use a 3-byte opcode (and a
mandatory prefix to boot).
Modified:
stable/9/contrib/binutils/gas/config/tc-i386.c
stable/9/contrib/binutils/opcodes/i386-dis.c
stable/9/contrib/binutils/opcodes/i386-opc.h
stable/9/contrib/binutils/opcodes/i386-opc.tbl
stable/9/contrib/binutils/opcodes/i386-tbl.h
Directory Properties:
stable/9/contrib/binutils/ (props changed)
Modified: stable/9/contrib/binutils/gas/config/tc-i386.c
==============================================================================
--- stable/9/contrib/binutils/gas/config/tc-i386.c Wed Aug 29 19:17:35 2012 (r239877)
+++ stable/9/contrib/binutils/gas/config/tc-i386.c Wed Aug 29 19:34:46 2012 (r239878)
@@ -517,7 +517,9 @@ static const arch_entry cpu_arch[] =
{".sse4a", PROCESSOR_UNKNOWN,
CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a},
{".abm", PROCESSOR_UNKNOWN,
- CpuABM}
+ CpuABM},
+ {".xsave", PROCESSOR_UNKNOWN,
+ CpuXSAVE}
};
const pseudo_typeS md_pseudo_table[] =
@@ -3988,6 +3990,16 @@ output_insn (void)
goto check_prefix;
}
}
+ else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881)
+ {
+ /* invept and invvpid are 3 byte instructions with a
+ mandatory prefix. */
+ if (i.tm.base_opcode & 0xff000000)
+ {
+ prefix = (i.tm.base_opcode >> 24) & 0xff;
+ add_prefix (prefix);
+ }
+ }
else if ((i.tm.base_opcode & 0xff0000) != 0)
{
prefix = (i.tm.base_opcode >> 16) & 0xff;
@@ -4027,6 +4039,12 @@ output_insn (void)
p = frag_more (3);
*p++ = (i.tm.base_opcode >> 16) & 0xff;
}
+ else if (i.tm.base_opcode == 0x660f3880 ||
+ i.tm.base_opcode == 0x660f3881)
+ {
+ p = frag_more (3);
+ *p++ = (i.tm.base_opcode >> 16) & 0xff;
+ }
else
p = frag_more (2);
Modified: stable/9/contrib/binutils/opcodes/i386-dis.c
==============================================================================
--- stable/9/contrib/binutils/opcodes/i386-dis.c Wed Aug 29 19:17:35 2012 (r239877)
+++ stable/9/contrib/binutils/opcodes/i386-dis.c Wed Aug 29 19:34:46 2012 (r239878)
@@ -93,6 +93,7 @@ static void OP_3DNowSuffix (int, int);
static void OP_SIMD_Suffix (int, int);
static void SIMD_Fixup (int, int);
static void PNI_Fixup (int, int);
+static void XCR_Fixup (int, int);
static void SVME_Fixup (int, int);
static void INVLPG_Fixup (int, int);
static void BadOp (void);
@@ -212,6 +213,7 @@ fetch_data (struct disassemble_info *inf
#define Ew { OP_E, w_mode }
#define M { OP_M, 0 } /* lea, lgdt, etc. */
#define Ma { OP_M, v_mode }
+#define Mo { OP_M, o_mode }
#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
#define Mq { OP_M, q_mode }
#define Gb { OP_G, b_mode }
@@ -539,6 +541,8 @@ fetch_data (struct disassemble_info *inf
#define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
#define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
#define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
+#define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
+#define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
@@ -1693,7 +1697,7 @@ static const struct dis386 grps[][8] = {
{
{ "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
{ "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
- { "lgdt{Q|Q||}", { M } },
+ { "lgdt{Q|Q||}", { { XCR_Fixup, 0 } } },
{ "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
{ "smswD", { Sv } },
{ "(bad)", { XX } },
@@ -1783,9 +1787,9 @@ static const struct dis386 grps[][8] = {
{ "fxrstor", { Ev } },
{ "ldmxcsr", { Ev } },
{ "stmxcsr", { Ev } },
- { "(bad)", { XX } },
- { "lfence", { { OP_0fae, 0 } } },
- { "mfence", { { OP_0fae, 0 } } },
+ { "xsave", { Ev } },
+ { "xrstor", { { OP_0fae, v_mode } } },
+ { "xsaveopt", { { OP_0fae, v_mode } } },
{ "clflush", { { OP_0fae, 0 } } },
},
/* GRP16 */
@@ -2585,6 +2589,22 @@ static const struct dis386 prefix_user_t
{ "punpckldq",{ MX, EMq } },
{ "(bad)", { XX } },
},
+
+ /* PREGRP98 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "invept", { Gm, Mo } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP99 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "invvpid",{ Gm, Mo } },
+ { "(bad)", { XX } },
+ },
};
static const struct dis386 x86_64_table[][2] = {
@@ -2754,8 +2774,8 @@ static const struct dis386 three_byte_ta
{ "(bad)", { XX } },
{ "(bad)", { XX } },
/* 80 */
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREGRP98 },
+ { PREGRP99 },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
@@ -5883,7 +5903,7 @@ static void
OP_M (int bytemode, int sizeflag)
{
if (modrm.mod == 3)
- /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
+ /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst,invept,invvpid modrm */
BadOp ();
else
OP_E (bytemode, sizeflag);
@@ -5905,17 +5925,17 @@ OP_0fae (int bytemode, int sizeflag)
{
if (modrm.reg == 7)
strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+ else if (modrm.reg == 6)
+ strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
+ else if (modrm.reg == 5)
+ strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
if (modrm.reg < 5 || modrm.rm != 0)
{
BadOp (); /* bad sfence, mfence, or lfence */
return;
}
- }
- else if (modrm.reg != 7)
- {
- BadOp (); /* bad clflush */
- return;
+ bytemode = 0;
}
OP_E (bytemode, sizeflag);
@@ -6170,6 +6190,43 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSE
}
static void
+XCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+ if (modrm.mod == 3 && modrm.reg == 2 && modrm.rm <= 1)
+ {
+ /* Override "lgdt". */
+ size_t olen = strlen (obuf);
+ char *p = obuf + olen - 4;
+
+ /* We might have a suffix when disassembling with -Msuffix. */
+ if (*p == 'i')
+ --p;
+
+ /* Remove "addr16/addr32" if we aren't in Intel mode. */
+ if (!intel_syntax
+ && (prefixes & PREFIX_ADDR)
+ && olen >= (4 + 7)
+ && *(p - 1) == ' '
+ && CONST_STRNEQ (p - 7, "addr")
+ && (CONST_STRNEQ (p - 3, "16")
+ || CONST_STRNEQ (p - 3, "32")))
+ p -= 7;
+
+ if (modrm.rm)
+ {
+ strcpy (p, "xsetbv");
+ }
+ else
+ {
+ strcpy (p, "xgetbv");
+ }
+
+ codep++;
+ }
+ else
+ OP_M (0, sizeflag);
+}
+static void
SVME_Fixup (int bytemode, int sizeflag)
{
const char *alt;
Modified: stable/9/contrib/binutils/opcodes/i386-opc.h
==============================================================================
--- stable/9/contrib/binutils/opcodes/i386-opc.h Wed Aug 29 19:17:35 2012 (r239877)
+++ stable/9/contrib/binutils/opcodes/i386-opc.h Wed Aug 29 19:34:46 2012 (r239878)
@@ -71,6 +71,7 @@ typedef struct template
#define CpuABM 0x200000 /* ABM New Instructions required */
#define CpuSSE4_1 0x400000 /* SSE4.1 Instructions required */
#define CpuSSE4_2 0x800000 /* SSE4.2 Instructions required */
+#define CpuXSAVE 0x1000000 /* XSAVE Instructions required */
/* SSE4.1/4.2 Instructions required */
#define CpuSSE4 (CpuSSE4_1|CpuSSE4_2)
@@ -83,7 +84,7 @@ typedef struct template
#define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \
|Cpu3dnow|Cpu3dnowA|CpuK6|CpuPadLock|CpuSVME|CpuSSSE3|CpuSSE4_1 \
- |CpuSSE4_2|CpuABM|CpuSSE4a)
+ |CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE)
/* the bits in opcode_modifier are used to generate the final opcode from
the base_opcode. These bits also are used to detect alternate forms of
Modified: stable/9/contrib/binutils/opcodes/i386-opc.tbl
==============================================================================
--- stable/9/contrib/binutils/opcodes/i386-opc.tbl Wed Aug 29 19:17:35 2012 (r239877)
+++ stable/9/contrib/binutils/opcodes/i386-opc.tbl Wed Aug 29 19:34:46 2012 (r239878)
@@ -1289,6 +1289,10 @@ mwait, 2, 0xf01, 0xc9, CpuSSE3|CpuNo64,
mwait, 2, 0xf01, 0xc9, CpuSSE3|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64, { Reg64, Reg64 }
// VMX instructions.
+invept, 2, 0x660f3880, None, CpuVMX|CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 }
+invept, 2, 0x660f3880, None, CpuVMX|Cpu64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg64 }
+invvpid, 2, 0x660f3881, None, CpuVMX|CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 }
+invvpid, 2, 0x660f3881, None, CpuVMX|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 }
vmclear, 1, 0x660fc7, 0x6, CpuVMX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
vmlaunch, 0, 0xf01, 0xc2, CpuVMX, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
@@ -1487,3 +1491,10 @@ xcryptcfb, 0, 0xf30fa7, 0xe0, Cpu686|Cpu
xcryptofb, 0, 0xf30fa7, 0xe8, Cpu686|CpuPadLock, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|IsString|ImmExt, { 0 }
// Alias for xstore-rng.
xstore, 0, 0xfa7, 0xc0, Cpu686|CpuPadLock, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|IsString|ImmExt, { 0 }
+
+// XSAVE/XRSTOR related instructions
+xgetbv, 0, 0xf01, 0xd0, CpuXSAVE, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
+xsetbv, 0, 0xf01, 0xd1, CpuXSAVE, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
+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 }
Modified: stable/9/contrib/binutils/opcodes/i386-tbl.h
==============================================================================
--- stable/9/contrib/binutils/opcodes/i386-tbl.h Wed Aug 29 19:17:35 2012 (r239877)
+++ stable/9/contrib/binutils/opcodes/i386-tbl.h Wed Aug 29 19:34:46 2012 (r239878)
@@ -3625,6 +3625,22 @@ const template i386_optab[] =
No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64,
{ Reg64,
Reg64 } },
+ { "invept", 2, 0x660f3880, None, CpuVMX|CpuNo64,
+ Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
+ { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+ Reg32 } },
+ { "invept", 2, 0x660f3880, None, CpuVMX|Cpu64,
+ Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
+ { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+ Reg64 } },
+ { "invvpid", 2, 0x660f3881, None, CpuVMX|CpuNo64,
+ Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
+ { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+ Reg32 } },
+ { "invvpid", 2, 0x660f3881, None, CpuVMX|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 } },
@@ -4288,6 +4304,21 @@ const template i386_optab[] =
{ "xstore", 0, 0xfa7, 0xc0, Cpu686|CpuPadLock,
No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|IsString|ImmExt,
{ 0 } },
+ { "xgetbv", 0, 0xf01, 0xd0, CpuXSAVE,
+ No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
+ { 0 } },
+ { "xsetbv", 0, 0xf01, 0xd1, CpuXSAVE,
+ No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
+ { 0 } },
+ { "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 } },
{ NULL, 0, 0, 0, 0, 0, { 0 } }
};
More information about the svn-src-stable-9
mailing list