diff options
author | Ryan Libby <rlibby@FreeBSD.org> | 2017-09-05 19:04:07 +0000 |
---|---|---|
committer | Ryan Libby <rlibby@FreeBSD.org> | 2017-09-05 19:04:07 +0000 |
commit | 1a11bb8f76916f91b15d957a90c7ee89a3c6a710 (patch) | |
tree | e3e7758da33096cea027c3ee8e0298d781273341 /contrib/binutils | |
parent | a03d621bfa0fd0c9b4cb724ee75828f377f0cfa6 (diff) | |
download | src-1a11bb8f76916f91b15d957a90c7ee89a3c6a710.tar.gz src-1a11bb8f76916f91b15d957a90c7ee89a3c6a710.zip |
gnu binutils: FSGSBASE assembly/disassembly
Enable the in-tree binutils to assemble and disassemble amd64 FSGSBASE
instructions (rdfsbase, rdgsbase, wrfsbase, wrgsbase), used in the base
system since r322763.
This gives one last gasp for in-tree gcc, and provides a small
enhancement for in-tree binutils objdump.
Reviewed by: dim, kib
Approved by: markj (mentor)
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D12222
Notes
Notes:
svn path=/head/; revision=323192
Diffstat (limited to 'contrib/binutils')
-rw-r--r-- | contrib/binutils/opcodes/i386-dis.c | 45 | ||||
-rw-r--r-- | contrib/binutils/opcodes/i386-opc.h | 4 | ||||
-rw-r--r-- | contrib/binutils/opcodes/i386-opc.tbl | 10 | ||||
-rw-r--r-- | contrib/binutils/opcodes/i386-tbl.h | 14 |
4 files changed, 57 insertions, 16 deletions
diff --git a/contrib/binutils/opcodes/i386-dis.c b/contrib/binutils/opcodes/i386-dis.c index 073afa1a836d..04470d7dc283 100644 --- a/contrib/binutils/opcodes/i386-dis.c +++ b/contrib/binutils/opcodes/i386-dis.c @@ -1302,7 +1302,7 @@ static const unsigned char twobyte_uses_REPZ_prefix[256] = { /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ - /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* af */ /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */ /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ @@ -1793,10 +1793,10 @@ static const struct dis386 grps[][8] = { }, /* GRP15 */ { - { "fxsave", { Ev } }, - { "fxrstor", { Ev } }, - { "ldmxcsr", { Ev } }, - { "stmxcsr", { Ev } }, + { "fxsave", { { OP_0fae, v_mode } } }, + { "fxrstor", { { OP_0fae, v_mode } } }, + { "ldmxcsr", { { OP_0fae, v_mode } } }, + { "stmxcsr", { { OP_0fae, v_mode } } }, { "xsave", { Ev } }, { "xrstor", { { OP_0fae, v_mode } } }, { "xsaveopt", { { OP_0fae, v_mode } } }, @@ -5997,19 +5997,34 @@ OP_0fae (int bytemode, int sizeflag) { if (modrm.mod == 3) { - 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) + if (modrm.reg >= 5 && modrm.reg <= 7 && modrm.rm == 0) + { + 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"); + bytemode = 0; + } + else if (modrm.reg <= 3 && (prefixes & PREFIX_REPZ) != 0) + { + if (modrm.reg == 0) + strcpy (obuf + strlen (obuf) - sizeof ("fxsave") + 1, "rdfsbase"); + else if (modrm.reg == 1) + strcpy (obuf + strlen (obuf) - sizeof ("fxrstor") + 1, "rdgsbase"); + else if (modrm.reg == 2) + strcpy (obuf + strlen (obuf) - sizeof ("ldmxcsr") + 1, "wrfsbase"); + else if (modrm.reg == 3) + strcpy (obuf + strlen (obuf) - sizeof ("stmxcsr") + 1, "wrgsbase"); + used_prefixes |= PREFIX_REPZ; + bytemode = dq_mode; + } + else { - BadOp (); /* bad sfence, mfence, or lfence */ + BadOp (); return; } - bytemode = 0; } OP_E (bytemode, sizeflag); diff --git a/contrib/binutils/opcodes/i386-opc.h b/contrib/binutils/opcodes/i386-opc.h index ec8019691e37..660fdccca2df 100644 --- a/contrib/binutils/opcodes/i386-opc.h +++ b/contrib/binutils/opcodes/i386-opc.h @@ -81,6 +81,7 @@ typedef struct template #define CpuPCLMUL 0x10000000 /* Carry-less Multiplication extensions */ #define CpuRdRnd 0x20000000 /* Intel Random Number Generator extensions */ #define CpuSMAP 0x40000000 /* Intel Supervisor Mode Access Prevention */ +#define CpuFSGSBase 0x80000000 /* Read/write fs/gs segment base registers */ /* SSE4.1/4.2 Instructions required */ #define CpuSSE4 (CpuSSE4_1|CpuSSE4_2) @@ -89,7 +90,8 @@ 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|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP) + |CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP \ + |CpuFSGSBase) /* 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 diff --git a/contrib/binutils/opcodes/i386-opc.tbl b/contrib/binutils/opcodes/i386-opc.tbl index 9d7c207612bd..50c734f608af 100644 --- a/contrib/binutils/opcodes/i386-opc.tbl +++ b/contrib/binutils/opcodes/i386-opc.tbl @@ -1525,3 +1525,13 @@ pclmulhqhqdq, 2, 0x660f3a44, 0x11, CpuPCLMUL, Modrm|IgnoreSize|No_bSuf|No_wSuf|N // Intel Random Number Generator extensions rdrand, 1, 0x0fc7, 0x6, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 } rdseed, 1, 0x0fc7, 0x7, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 } + +// Intel Supervisor Mode Access Prevention extensions +clac, 0, 0x0f01, 0xca, CpuSMAP, NoSuf|ImmExt, { 0 } +stac, 0, 0x0f01, 0xcb, CpuSMAP, NoSuf|ImmExt, { 0 } + +// Read/write fs/gs segment base registers +rdfsbase, 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 } +rdgsbase, 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 } +wrfsbase, 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 } +wrgsbase, 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 } diff --git a/contrib/binutils/opcodes/i386-tbl.h b/contrib/binutils/opcodes/i386-tbl.h index d769d09f7dea..9eb313a136be 100644 --- a/contrib/binutils/opcodes/i386-tbl.h +++ b/contrib/binutils/opcodes/i386-tbl.h @@ -4400,6 +4400,20 @@ const template i386_optab[] = NoSuf|ImmExt, { 0, 0, 0 } }, {"stac", 0, 0x0f01, 0xcb, CpuSMAP, NoSuf|ImmExt, { 0, 0, 0 } }, + + /* Read/write fs/gs segment base registers */ + {"rdfsbase", 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64, + Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, + { Reg32|Reg64 } }, + {"rdgsbase", 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64, + Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, + { Reg32|Reg64 } }, + {"wrfsbase", 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64, + Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, + { Reg32|Reg64 } }, + {"wrgsbase", 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64, + Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, + { Reg32|Reg64 } }, { NULL, 0, 0, 0, 0, 0, { 0 } } }; |