From e8ef17669ea9d5c0dc5a9fb1f21e95d29bf491fb Mon Sep 17 00:00:00 2001 From: guenther Date: Mon, 25 May 2015 00:12:59 +0000 Subject: [PATCH] Teach binutils the {rd,wr}{fs,gs}base instructions. Flag bits worked out with kettenis@ ok mlarkin@ --- .../binutils-2.17/gas/config/tc-i386.h | 4 +-- .../binutils-2.17/include/opcode/i386.h | 6 +++- gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c | 36 +++++++++++-------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.h b/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.h index 073f9208c11..c77420d6b55 100644 --- a/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.h +++ b/gnu/usr.bin/binutils-2.17/gas/config/tc-i386.h @@ -188,7 +188,7 @@ typedef struct #define CpuXSAVE 0x400000 /* XSAVE Instructions required */ #define CpuAES 0x800000 /* Intel AES extensions required */ #define CpuPCLMUL 0x1000000 /* Intel Carry-less Multiplication extensions */ -#define CpuRdRnd 0x2000000 /* Intel Random Number Generator extensions */ +#define CpuNEW 0x2000000 /* Generic "new" ops w/o encoding hacks */ #define CpuSMAP 0x4000000 /* Intel Supervisor Mode Access Prevention */ /* These flags are set by gas depending on the flag_code. */ @@ -199,7 +199,7 @@ typedef struct #define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \ |CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuPNI|CpuVMX \ |Cpu3dnow|Cpu3dnowA|CpuK6|CpuAthlon|CpuPadLock|CpuSVME|CpuMNI \ - |CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP) + |CpuXSAVE|CpuAES|CpuPCLMUL|CpuNEW|CpuSMAP) /* 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/gnu/usr.bin/binutils-2.17/include/opcode/i386.h b/gnu/usr.bin/binutils-2.17/include/opcode/i386.h index ccf6746befe..602187b521c 100644 --- a/gnu/usr.bin/binutils-2.17/include/opcode/i386.h +++ b/gnu/usr.bin/binutils-2.17/include/opcode/i386.h @@ -992,6 +992,10 @@ static const template i386_optab[] = {"clflush", 1, 0x0fae, 7, CpuP4, NoSuf|Modrm|IgnoreSize, { ByteMem, 0, 0 } }, {"lfence", 0, 0x0fae, 0xe8, CpuP4, NoSuf|ImmExt, { 0, 0, 0 } }, {"mfence", 0, 0x0fae, 0xf0, CpuP4, NoSuf|ImmExt, { 0, 0, 0 } }, +{"rdfsbase", 1, 0xf30fae, 0, CpuNEW, FP|Modrm, { Reg32|Reg64, 0, 0 } }, +{"rdgsbase", 1, 0xf30fae, 1, CpuNEW, FP|Modrm, { Reg32|Reg64, 0, 0 } }, +{"wrfsbase", 1, 0xf30fae, 2, CpuNEW, FP|Modrm, { Reg32|Reg64, 0, 0 } }, +{"wrgsbase", 1, 0xf30fae, 3, CpuNEW, FP|Modrm, { Reg32|Reg64, 0, 0 } }, {"pause", 0, 0xf390, X, CpuP4, NoSuf, { 0, 0, 0 } }, /* MMX/SSE2 instructions. */ @@ -1504,7 +1508,7 @@ static const template i386_optab[] = {"pclmulhqhqdq", 2, 0x660f3a44, 0x11, CpuPCLMUL, FP|Modrm|IgnoreSize|NoSuf|ImmExt, { RegXMM|LLongMem, RegXMM } }, /* Intel Random Number Generator extensions */ -{"rdrand", 1, 0x0fc7, 0x6, CpuRdRnd, Modrm|NoSuf, { Reg16|Reg32|Reg64 } }, +{"rdrand", 1, 0x0fc7, 0x6, CpuNEW, Modrm|NoSuf, { Reg16|Reg32|Reg64 } }, /* Intel Supervisor Mode Access Prevention extensions */ {"clac", 0, 0x0f01, 0xca, CpuSMAP, NoSuf|ImmExt, { 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 e3d1e7e1a1b..f7e8e5c7219 100644 --- a/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c +++ b/gnu/usr.bin/binutils-2.17/opcodes/i386-dis.c @@ -316,6 +316,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define VM OP_VMX, q_mode #define OPSUF OP_3DNowSuffix, 0 #define OPSIMD OP_SIMD_Suffix, 0 +#define OP0FAE OP_0fae, v_mode #define OP0F3A OP_0f3a, 0 /* Used handle "rep" prefix for string instructions. */ @@ -1469,14 +1470,14 @@ static const struct dis386 grps[][8] = { }, /* GRP13 */ { - { "fxsave", Ev, XX, XX }, - { "fxrstor", Ev, XX, XX }, - { "ldmxcsr", Ev, XX, XX }, - { "stmxcsr", Ev, XX, XX }, - { "xsave", Ev, XX, XX }, - { "xrstor", OP_0fae, v_mode, XX, XX }, - { "xsaveopt", OP_0fae, v_mode, XX, XX }, - { "clflush", OP_0fae, v_mode, XX, XX }, + { "fxsave", OP0FAE, XX, XX }, + { "fxrstor", OP0FAE, XX, XX }, + { "ldmxcsr", OP0FAE, XX, XX }, + { "stmxcsr", OP0FAE, XX, XX }, + { "xsave", Ev, XX, XX }, + { "xrstor", OP0FAE, XX, XX }, + { "xsaveopt", OP0FAE, XX, XX }, + { "clflush", OP0FAE, XX, XX }, }, /* GRP14 */ { @@ -4831,19 +4832,24 @@ OP_0fae (int bytemode, int sizeflag) strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence"); else if (reg == 5) strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence"); - bytemode = 0; - if (reg < 5 || rm != 0) + if (reg < 4 && prefixes == PREFIX_REPZ) + { + if (reg == 0) + strcpy (obuf, "rdfsbase"); + else if (reg == 1) + strcpy (obuf, "rdgsbase"); + else if (reg == 2) + strcpy (obuf, "wrfsbase"); + else + strcpy (obuf, "wrgsbase"); + } + else if (reg < 5 || rm != 0) { BadOp (); /* bad sfence, mfence, or lfence */ return; } } - else if (reg < 5) - { - BadOp (); /* bad sfence, mfence, or lfence */ - return; - } OP_E (bytemode, sizeflag); } -- 2.20.1