From owner-svn-src-head@FreeBSD.ORG Wed Jul 4 22:12:11 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1F6EF1065670; Wed, 4 Jul 2012 22:12:11 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 09C358FC15; Wed, 4 Jul 2012 22:12:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q64MCAss035456; Wed, 4 Jul 2012 22:12:10 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q64MCAvI035450; Wed, 4 Jul 2012 22:12:10 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201207042212.q64MCAvI035450@svn.freebsd.org> From: John Baldwin Date: Wed, 4 Jul 2012 22:12:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238123 - in head/contrib/binutils: gas/config opcodes X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Jul 2012 22:12:11 -0000 Author: jhb Date: Wed Jul 4 22:12:10 2012 New Revision: 238123 URL: http://svn.freebsd.org/changeset/base/238123 Log: 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. This will let us use these instructions natively with GCC rather than hardcoding the opcodes in hex. Reviewed by: kib MFC after: 1 month Modified: head/contrib/binutils/gas/config/tc-i386.c head/contrib/binutils/opcodes/i386-dis.c head/contrib/binutils/opcodes/i386-opc.h head/contrib/binutils/opcodes/i386-opc.tbl head/contrib/binutils/opcodes/i386-tbl.h Modified: head/contrib/binutils/gas/config/tc-i386.c ============================================================================== --- head/contrib/binutils/gas/config/tc-i386.c Wed Jul 4 20:59:30 2012 (r238122) +++ head/contrib/binutils/gas/config/tc-i386.c Wed Jul 4 22:12:10 2012 (r238123) @@ -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[] = Modified: head/contrib/binutils/opcodes/i386-dis.c ============================================================================== --- head/contrib/binutils/opcodes/i386-dis.c Wed Jul 4 20:59:30 2012 (r238122) +++ head/contrib/binutils/opcodes/i386-dis.c Wed Jul 4 22:12:10 2012 (r238123) @@ -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); @@ -1693,7 +1694,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 +1784,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 */ @@ -5905,17 +5906,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 +6171,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: head/contrib/binutils/opcodes/i386-opc.h ============================================================================== --- head/contrib/binutils/opcodes/i386-opc.h Wed Jul 4 20:59:30 2012 (r238122) +++ head/contrib/binutils/opcodes/i386-opc.h Wed Jul 4 22:12:10 2012 (r238123) @@ -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: head/contrib/binutils/opcodes/i386-opc.tbl ============================================================================== --- head/contrib/binutils/opcodes/i386-opc.tbl Wed Jul 4 20:59:30 2012 (r238122) +++ head/contrib/binutils/opcodes/i386-opc.tbl Wed Jul 4 22:12:10 2012 (r238123) @@ -1487,3 +1487,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: head/contrib/binutils/opcodes/i386-tbl.h ============================================================================== --- head/contrib/binutils/opcodes/i386-tbl.h Wed Jul 4 20:59:30 2012 (r238122) +++ head/contrib/binutils/opcodes/i386-tbl.h Wed Jul 4 22:12:10 2012 (r238123) @@ -4288,6 +4288,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 } } };