summaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2007-04-18 16:15:55 +0000
committerH.J. Lu <hjl@lucon.org>2007-04-18 16:15:55 +0000
commitb2830069a8175cd04a4ea472f306702c80d97dce (patch)
treea14b49463b4eb1b20b1df8f4eb86e1f19640e65e /opcodes
parent7eb5f813c1e70c3587f85a86d41a84aa21aba746 (diff)
downloadbinutils-redhat-b2830069a8175cd04a4ea472f306702c80d97dce.tar.gz
gas/
2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * config/tc-i386.c (cpu_arch): Add .sse4.2 and .sse4. (match_template): Handle operand size for crc32 in SSE4.2. (process_suffix): Handle operand type for crc32 in SSE4.2. (output_insn): Support SSE4.2. gas/testsuite/ 2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * gas/i386/i386.exp: Add sse4.2 and x86-64-sse4.2. * gas/i386/sse4_2.d: New file. * gas/i386/sse4_2.s: Likewise. * gas/i386/x86-64-sse4_2.d: Likewise. * gas/i386/x86-64-sse4_2.s: Likewise. opcodes/ 2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * i386-dis.c (CRC32_Fixup): New. (PREGRP85, PREGRP86, PREGRP87, PREGRP88, PREGRP89, PREGRP90, PREGRP91): New. (threebyte_0x38_uses_DATA_prefix): Updated for SSE4.2. (threebyte_0x3a_uses_DATA_prefix): Likewise. (prefix_user_table): Add PREGRP85, PREGRP86, PREGRP87, PREGRP88, PREGRP89, PREGRP90 and PREGRP91. (three_byte_table): Likewise. * i386-opc.c (i386_optab): Add SSE4.2 opcodes. * gas/config/tc-i386.h (CpuSSE4_2): New. (CpuSSE4): Likewise. (CpuUnknownFlags): Add CpuSSE4_2.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog17
-rw-r--r--opcodes/i386-dis.c144
-rw-r--r--opcodes/i386-opc.c14
-rw-r--r--opcodes/i386-opc.h6
4 files changed, 170 insertions, 11 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index e13bfd0831..d090f654cb 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,22 @@
2007-04-18 H.J. Lu <hongjiu.lu@intel.com>
+ * i386-dis.c (CRC32_Fixup): New.
+ (PREGRP85, PREGRP86, PREGRP87, PREGRP88, PREGRP89, PREGRP90,
+ PREGRP91): New.
+ (threebyte_0x38_uses_DATA_prefix): Updated for SSE4.2.
+ (threebyte_0x3a_uses_DATA_prefix): Likewise.
+ (prefix_user_table): Add PREGRP85, PREGRP86, PREGRP87,
+ PREGRP88, PREGRP89, PREGRP90 and PREGRP91.
+ (three_byte_table): Likewise.
+
+ * i386-opc.c (i386_optab): Add SSE4.2 opcodes.
+
+ * gas/config/tc-i386.h (CpuSSE4_2): New.
+ (CpuSSE4): Likewise.
+ (CpuUnknownFlags): Add CpuSSE4_2.
+
+2007-04-18 H.J. Lu <hongjiu.lu@intel.com>
+
* i386-dis.c (XMM_Fixup): New.
(Edqb): New.
(Edqd): New.
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index aae78659d4..7f73705145 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -99,6 +99,7 @@ static void VMX_Fixup (int, int);
static void REP_Fixup (int, int);
static void CMPXCHG8B_Fixup (int, int);
static void XMM_Fixup (int, int);
+static void CRC32_Fixup (int, int);
struct dis_private {
/* Points to first byte not fetched. */
@@ -521,6 +522,13 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
#define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
#define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
+#define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
+#define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
+#define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
+#define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
+#define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
+#define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
+#define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
@@ -1287,7 +1295,7 @@ static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
/* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
/* 10 */ 0,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
/* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
- /* 30 */ 1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1, /* 3f */
+ /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
/* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
/* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
/* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
@@ -1323,7 +1331,7 @@ static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+ /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
@@ -2471,6 +2479,62 @@ static const struct dis386 prefix_user_table[][4] = {
{ "mpsadbw", { XM, EX, Ib } },
{ "(bad)", { XX } },
},
+
+ /* PREGRP86 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "pcmpgtq", { XM, EX } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP87 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
+ },
+
+ /* PREGRP88 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
+ },
+
+ /* PREGRP89 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "pcmpestrm", { XM, EX, Ib } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP90 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "pcmpestri", { XM, EX, Ib } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP91 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "pcmpistrm", { XM, EX, Ib } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP92 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "pcmpistri", { XM, EX, Ib } },
+ { "(bad)", { XX } },
+ },
};
static const struct dis386 x86_64_table[][2] = {
@@ -2557,7 +2621,7 @@ static const struct dis386 three_byte_table[][256] = {
{ PREGRP57 },
{ PREGRP58 },
{ "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREGRP86 },
/* 38 */
{ PREGRP59 },
{ PREGRP60 },
@@ -2766,8 +2830,8 @@ static const struct dis386 three_byte_table[][256] = {
{ "(bad)", { XX } },
{ "(bad)", { XX } },
/* f0 */
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREGRP87 },
+ { PREGRP88 },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
@@ -2895,10 +2959,10 @@ static const struct dis386 three_byte_table[][256] = {
{ "(bad)", { XX } },
{ "(bad)", { XX } },
/* 60 */
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREGRP89 },
+ { PREGRP90 },
+ { PREGRP91 },
+ { PREGRP92 },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
@@ -6247,3 +6311,65 @@ XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
sprintf (scratchbuf, "%%xmm%d", reg);
oappend (scratchbuf + intel_syntax);
}
+
+static void
+CRC32_Fixup (int bytemode, int sizeflag)
+{
+ /* Add proper suffix to "crc32". */
+ char *p = obuf + strlen (obuf);
+
+ switch (bytemode)
+ {
+ case b_mode:
+ *p++ = 'b';
+ break;
+ case v_mode:
+ USED_REX (REX_W);
+ if (rex & REX_W)
+ *p++ = 'q';
+ else if ((prefixes & PREFIX_DATA))
+ {
+ *p++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ else
+ *p++ = 'l';
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ *p = '\0';
+
+ if (modrm.mod == 3)
+ {
+ int add;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ USED_REX (REX_B);
+ add = (rex & REX_B) ? 8 : 0;
+ if (bytemode == b_mode)
+ {
+ USED_REX (0);
+ if (rex)
+ oappend (names8rex[modrm.rm + add]);
+ else
+ oappend (names8[modrm.rm + add]);
+ }
+ else
+ {
+ USED_REX (REX_W);
+ if (rex & REX_W)
+ oappend (names64[modrm.rm + add]);
+ else if ((prefixes & PREFIX_DATA))
+ oappend (names16[modrm.rm + add]);
+ else
+ oappend (names32[modrm.rm + add]);
+ }
+ }
+ else
+ OP_E (v_mode, sizeflag);
+}
diff --git a/opcodes/i386-opc.c b/opcodes/i386-opc.c
index b1b62a6de5..191054d85a 100644
--- a/opcodes/i386-opc.c
+++ b/opcodes/i386-opc.c
@@ -1435,6 +1435,18 @@ const template i386_optab[] =
{"roundsd", 3, 0x660f3a0b,X, CpuSSE4_1, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } },
{"roundss", 3, 0x660f3a0a,X, CpuSSE4_1, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LongMem, RegXMM } },
+/* Streaming SIMD extensions 4.2 Instructions. */
+
+{"pcmpgtq", 2, 0x660f3837,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } },
+{"pcmpestri", 3, 0x660f3a61,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } },
+{"pcmpestrm", 3, 0x660f3a60,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } },
+{"pcmpistri", 3, 0x660f3a63,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } },
+{"pcmpistrm", 3, 0x660f3a62,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } },
+{"crc32b", 2, 0xf20f38f0,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Reg8|ByteMem, Reg32|Reg64, 0 } },
+{"crc32", 2, 0xf20f38f0,X, CpuSSE4_2, NoSuf|IgnoreSize|Modrm, { Reg8, Reg32|Reg64, 0 } },
+{"crc32", 2, 0xf20f38f1,X, CpuSSE4_2, wl_Suf|Modrm, { WordReg|WordMem, Reg32, 0 } },
+{"crc32", 2, 0xf20f38f1,X, CpuSSE4_2|Cpu64, q_Suf|IgnoreSize|Modrm|Rex64, { Reg64|LLongMem, Reg64, 0 } },
+
/* AMD 3DNow! instructions. */
{"prefetch", 1, 0x0f0d, 0, Cpu3dnow, NoSuf|IgnoreSize|Modrm, { ByteMem, 0, 0 } },
@@ -1497,7 +1509,7 @@ const template i386_optab[] =
{"insertq", 4, 0xf20f78, X, CpuSSE4a, NoSuf|IgnoreSize|Modrm, { Imm8, Imm8, RegXMM, RegXMM} },
/* ABM instructions */
-{"popcnt", 2, 0xf30fb8, X, CpuABM, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} },
+{"popcnt", 2, 0xf30fb8, X, CpuABM|CpuSSE4_2, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} },
{"lzcnt", 2, 0xf30fbd, X, CpuABM, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} },
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index 94ef037687..71f3892d64 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -70,6 +70,10 @@ typedef struct template
#define CpuSSE4a 0x100000 /* SSE4a New Instuctions required */
#define CpuABM 0x200000 /* ABM New Instructions required */
#define CpuSSE4_1 0x400000 /* SSE4.1 Instructions required */
+#define CpuSSE4_2 0x800000 /* SSE4.2 Instructions required */
+
+/* SSE4.1/4.2 Instructions required */
+#define CpuSSE4 (CpuSSE4_1|CpuSSE4_2)
/* These flags are set by gas depending on the flag_code. */
#define Cpu64 0x4000000 /* 64bit support required */
@@ -79,7 +83,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 \
- |CpuABM|CpuSSE4a)
+ |CpuSSE4_2|CpuABM|CpuSSE4a)
/* 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