From 331d2d0d9ce1220133395ba0172b371aec077c16 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 27 Feb 2006 15:35:37 +0000 Subject: [PATCH] gas/ 2006-02-27 H.J. Lu * gas/config/tc-i386.c (output_insn): Support Intel Merom New Instructions. * gas/config/tc-i386.h (CpuMNI): New. (CpuUnknownFlags): Add CpuMNI. gas/testsuite/ 2006-02-27 H.J. Lu * gas/i386/i386.exp: Add merom and x86-64-merom. * gas/i386/merom.d: New file. * gas/i386/merom.s: Likewise. * gas/i386/x86-64-merom.d: Likewise. * gas/i386/x86-64-merom.s: Likewise. include/opcode/ 2006-02-27 H.J. Lu * i386.h (i386_optab): Support Intel Merom New Instructions. opcodes/ 2006-02-27 H.J. Lu * i386-dis.c (IS_3BYTE_OPCODE): New for 3-byte opcodes used by Intel Merom New Instructions. (THREE_BYTE_0): Likewise. (THREE_BYTE_1): Likewise. (three_byte_table): Likewise. (dis386_twobyte): Use THREE_BYTE_0 for entry 0x38. Use THREE_BYTE_1 for entry 0x3a. (twobyte_has_modrm): Updated. (twobyte_uses_SSE_prefix): Likewise. (print_insn): Handle 3-byte opcodes used by Intel Merom New Instructions. --- gas/ChangeLog | 8 +++ gas/config/tc-i386.c | 32 ++++++++---- gas/config/tc-i386.h | 3 +- gas/testsuite/ChangeLog | 9 ++++ gas/testsuite/gas/i386/i386.exp | 2 + gas/testsuite/gas/i386/merom.d | 73 +++++++++++++++++++++++++++ gas/testsuite/gas/i386/merom.s | 70 ++++++++++++++++++++++++++ gas/testsuite/gas/i386/x86-64-merom.d | 73 +++++++++++++++++++++++++++ gas/testsuite/gas/i386/x86-64-merom.s | 70 ++++++++++++++++++++++++++ include/opcode/ChangeLog | 4 ++ include/opcode/i386.h | 35 +++++++++++++ opcodes/ChangeLog | 14 ++++++ opcodes/i386-dis.c | 95 +++++++++++++++++++++++++++++++++-- 13 files changed, 473 insertions(+), 15 deletions(-) create mode 100644 gas/testsuite/gas/i386/merom.d create mode 100644 gas/testsuite/gas/i386/merom.s create mode 100644 gas/testsuite/gas/i386/x86-64-merom.d create mode 100644 gas/testsuite/gas/i386/x86-64-merom.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 28b5575..8f51578 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2006-02-27 H.J. Lu + + * gas/config/tc-i386.c (output_insn): Support Intel Merom New + Instructions. + + * gas/config/tc-i386.h (CpuMNI): New. + (CpuUnknownFlags): Add CpuMNI. + 2006-02-24 David S. Miller * config/tc-sparc.c (priv_reg_table): Add entry for "gl". diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 337149e..f42a9a4 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -3474,23 +3474,31 @@ output_insn () /* Output normal instructions here. */ char *p; unsigned char *q; + unsigned int prefix; - /* All opcodes on i386 have either 1 or 2 bytes. We may use one - more higher byte to specify a prefix the instruction - requires. */ - if ((i.tm.base_opcode & 0xff0000) != 0) + /* All opcodes on i386 have either 1 or 2 bytes. Merom New + Instructions have 3 bytes. We may use one more higher byte + to specify a prefix the instruction requires. */ + if ((i.tm.cpu_flags & CpuMNI) != 0) { + if (i.tm.base_opcode & 0xff000000) + { + prefix = (i.tm.base_opcode >> 24) & 0xff; + goto check_prefix; + } + } + else if ((i.tm.base_opcode & 0xff0000) != 0) + { + prefix = (i.tm.base_opcode >> 16) & 0xff; if ((i.tm.cpu_flags & CpuPadLock) != 0) { - unsigned int prefix; - prefix = (i.tm.base_opcode >> 16) & 0xff; - +check_prefix: if (prefix != REPE_PREFIX_OPCODE || i.prefix[LOCKREP_PREFIX] != REPE_PREFIX_OPCODE) add_prefix (prefix); } else - add_prefix ((i.tm.base_opcode >> 16) & 0xff); + add_prefix (prefix); } /* The prefix bytes. */ @@ -3512,7 +3520,13 @@ output_insn () } else { - p = frag_more (2); + if ((i.tm.cpu_flags & CpuMNI) != 0) + { + p = frag_more (3); + *p++ = (i.tm.base_opcode >> 16) & 0xff; + } + else + p = frag_more (2); /* Put out high byte first: can't use md_number_to_chars! */ *p++ = (i.tm.base_opcode >> 8) & 0xff; diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index 0a9cd1c..9851704 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -184,6 +184,7 @@ typedef struct #define CpuPadLock 0x40000 /* VIA PadLock required */ #define CpuSVME 0x80000 /* AMD Secure Virtual Machine Ext-s required */ #define CpuVMX 0x100000 /* VMX Instructions required */ +#define CpuMNI 0x200000 /* Merom New Instructions required */ /* These flags are set by gas depending on the flag_code. */ #define Cpu64 0x4000000 /* 64bit support required */ @@ -192,7 +193,7 @@ typedef struct /* The default value for unknown CPUs - enable all features to avoid problems. */ #define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \ |CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuPNI|CpuVMX \ - |Cpu3dnow|Cpu3dnowA|CpuK6|CpuAthlon|CpuPadLock|CpuSVME) + |Cpu3dnow|Cpu3dnowA|CpuK6|CpuAthlon|CpuPadLock|CpuSVME|CpuMNI) /* 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/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index c167a21..53c6926 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-02-27 H.J. Lu + + * gas/i386/i386.exp: Add merom and x86-64-merom. + + * gas/i386/merom.d: New file. + * gas/i386/merom.s: Likewise. + * gas/i386/x86-64-merom.d: Likewise. + * gas/i386/x86-64-merom.s: Likewise. + 2006-02-24 David S. Miller * gas/sparc/rdhpr.s: New test. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 7bf4595..2138593 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -68,6 +68,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "crx" run_list_test "cr-err" "" run_dump_test "svme" + run_dump_test "merom" # These tests require support for 8 and 16 bit relocs, # so we only run them for ELF and COFF targets. @@ -136,6 +137,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-crx-suffix" run_dump_test "x86-64-drx" run_dump_test "x86-64-drx-suffix" + run_dump_test "x86-64-merom" if { ![istarget "*-*-aix*"] && ![istarget "*-*-beos*"] diff --git a/gas/testsuite/gas/i386/merom.d b/gas/testsuite/gas/i386/merom.d new file mode 100644 index 0000000..a09721c --- /dev/null +++ b/gas/testsuite/gas/i386/merom.d @@ -0,0 +1,73 @@ +#objdump: -dw +#name: i386 merom + +.*: +file format .* + +Disassembly of section .text: + +0+000 : + 0: 0f 38 01 01[ ]+phaddw \(%ecx\),%mm0 + 4: 0f 38 01 c1[ ]+phaddw %mm1,%mm0 + 8: 66 0f 38 01 01[ ]+phaddw \(%ecx\),%xmm0 + d: 66 0f 38 01 c1[ ]+phaddw %xmm1,%xmm0 + 12: 0f 38 02 01[ ]+phaddd \(%ecx\),%mm0 + 16: 0f 38 02 c1[ ]+phaddd %mm1,%mm0 + 1a: 66 0f 38 02 01[ ]+phaddd \(%ecx\),%xmm0 + 1f: 66 0f 38 02 c1[ ]+phaddd %xmm1,%xmm0 + 24: 0f 38 03 01[ ]+phaddsw \(%ecx\),%mm0 + 28: 0f 38 03 c1[ ]+phaddsw %mm1,%mm0 + 2c: 66 0f 38 03 01[ ]+phaddsw \(%ecx\),%xmm0 + 31: 66 0f 38 03 c1[ ]+phaddsw %xmm1,%xmm0 + 36: 0f 38 05 01[ ]+phsubw \(%ecx\),%mm0 + 3a: 0f 38 05 c1[ ]+phsubw %mm1,%mm0 + 3e: 66 0f 38 05 01[ ]+phsubw \(%ecx\),%xmm0 + 43: 66 0f 38 05 c1[ ]+phsubw %xmm1,%xmm0 + 48: 0f 38 06 01[ ]+phsubd \(%ecx\),%mm0 + 4c: 0f 38 06 c1[ ]+phsubd %mm1,%mm0 + 50: 66 0f 38 06 01[ ]+phsubd \(%ecx\),%xmm0 + 55: 66 0f 38 06 c1[ ]+phsubd %xmm1,%xmm0 + 5a: 0f 38 07 01[ ]+phsubsw \(%ecx\),%mm0 + 5e: 0f 38 07 c1[ ]+phsubsw %mm1,%mm0 + 62: 66 0f 38 07 01[ ]+phsubsw \(%ecx\),%xmm0 + 67: 66 0f 38 07 c1[ ]+phsubsw %xmm1,%xmm0 + 6c: 0f 38 04 01[ ]+pmaddubsw \(%ecx\),%mm0 + 70: 0f 38 04 c1[ ]+pmaddubsw %mm1,%mm0 + 74: 66 0f 38 04 01[ ]+pmaddubsw \(%ecx\),%xmm0 + 79: 66 0f 38 04 c1[ ]+pmaddubsw %xmm1,%xmm0 + 7e: 0f 38 0b 01[ ]+pmulhrsw \(%ecx\),%mm0 + 82: 0f 38 0b c1[ ]+pmulhrsw %mm1,%mm0 + 86: 66 0f 38 0b 01[ ]+pmulhrsw \(%ecx\),%xmm0 + 8b: 66 0f 38 0b c1[ ]+pmulhrsw %xmm1,%xmm0 + 90: 0f 38 00 01[ ]+pshufb \(%ecx\),%mm0 + 94: 0f 38 00 c1[ ]+pshufb %mm1,%mm0 + 98: 66 0f 38 00 01[ ]+pshufb \(%ecx\),%xmm0 + 9d: 66 0f 38 00 c1[ ]+pshufb %xmm1,%xmm0 + a2: 0f 38 08 01[ ]+psignb \(%ecx\),%mm0 + a6: 0f 38 08 c1[ ]+psignb %mm1,%mm0 + aa: 66 0f 38 08 01[ ]+psignb \(%ecx\),%xmm0 + af: 66 0f 38 08 c1[ ]+psignb %xmm1,%xmm0 + b4: 0f 38 09 01[ ]+psignw \(%ecx\),%mm0 + b8: 0f 38 09 c1[ ]+psignw %mm1,%mm0 + bc: 66 0f 38 09 01[ ]+psignw \(%ecx\),%xmm0 + c1: 66 0f 38 09 c1[ ]+psignw %xmm1,%xmm0 + c6: 0f 38 0a 01[ ]+psignd \(%ecx\),%mm0 + ca: 0f 38 0a c1[ ]+psignd %mm1,%mm0 + ce: 66 0f 38 0a 01[ ]+psignd \(%ecx\),%xmm0 + d3: 66 0f 38 0a c1[ ]+psignd %xmm1,%xmm0 + d8: 0f 3a 0f 01 02[ ]+palignr \$0x2,\(%ecx\),%mm0 + dd: 0f 3a 0f c1 02[ ]+palignr \$0x2,%mm1,%mm0 + e2: 66 0f 3a 0f 01 02[ ]+palignr \$0x2,\(%ecx\),%xmm0 + e8: 66 0f 3a 0f c1 02[ ]+palignr \$0x2,%xmm1,%xmm0 + ee: 0f 38 1c 01[ ]+pabsb \(%ecx\),%mm0 + f2: 0f 38 1c c1[ ]+pabsb %mm1,%mm0 + f6: 66 0f 38 1c 01[ ]+pabsb \(%ecx\),%xmm0 + fb: 66 0f 38 1c c1[ ]+pabsb %xmm1,%xmm0 + 100: 0f 38 1d 01[ ]+pabsw \(%ecx\),%mm0 + 104: 0f 38 1d c1[ ]+pabsw %mm1,%mm0 + 108: 66 0f 38 1d 01[ ]+pabsw \(%ecx\),%xmm0 + 10d: 66 0f 38 1d c1[ ]+pabsw %xmm1,%xmm0 + 112: 0f 38 1e 01[ ]+pabsd \(%ecx\),%mm0 + 116: 0f 38 1e c1[ ]+pabsd %mm1,%mm0 + 11a: 66 0f 38 1e 01[ ]+pabsd \(%ecx\),%xmm0 + 11f: 66 0f 38 1e c1[ ]+pabsd %xmm1,%xmm0 + ... diff --git a/gas/testsuite/gas/i386/merom.s b/gas/testsuite/gas/i386/merom.s new file mode 100644 index 0000000..154d2f8 --- /dev/null +++ b/gas/testsuite/gas/i386/merom.s @@ -0,0 +1,70 @@ +#Merom New Instructions + + .text +foo: + phaddw (%ecx),%mm0 + phaddw %mm1,%mm0 + phaddw (%ecx),%xmm0 + phaddw %xmm1,%xmm0 + phaddd (%ecx),%mm0 + phaddd %mm1,%mm0 + phaddd (%ecx),%xmm0 + phaddd %xmm1,%xmm0 + phaddsw (%ecx),%mm0 + phaddsw %mm1,%mm0 + phaddsw (%ecx),%xmm0 + phaddsw %xmm1,%xmm0 + phsubw (%ecx),%mm0 + phsubw %mm1,%mm0 + phsubw (%ecx),%xmm0 + phsubw %xmm1,%xmm0 + phsubd (%ecx),%mm0 + phsubd %mm1,%mm0 + phsubd (%ecx),%xmm0 + phsubd %xmm1,%xmm0 + phsubsw (%ecx),%mm0 + phsubsw %mm1,%mm0 + phsubsw (%ecx),%xmm0 + phsubsw %xmm1,%xmm0 + pmaddubsw (%ecx),%mm0 + pmaddubsw %mm1,%mm0 + pmaddubsw (%ecx),%xmm0 + pmaddubsw %xmm1,%xmm0 + pmulhrsw (%ecx),%mm0 + pmulhrsw %mm1,%mm0 + pmulhrsw (%ecx),%xmm0 + pmulhrsw %xmm1,%xmm0 + pshufb (%ecx),%mm0 + pshufb %mm1,%mm0 + pshufb (%ecx),%xmm0 + pshufb %xmm1,%xmm0 + psignb (%ecx),%mm0 + psignb %mm1,%mm0 + psignb (%ecx),%xmm0 + psignb %xmm1,%xmm0 + psignw (%ecx),%mm0 + psignw %mm1,%mm0 + psignw (%ecx),%xmm0 + psignw %xmm1,%xmm0 + psignd (%ecx),%mm0 + psignd %mm1,%mm0 + psignd (%ecx),%xmm0 + psignd %xmm1,%xmm0 + palignr $0x2,(%ecx),%mm0 + palignr $0x2,%mm1,%mm0 + palignr $0x2,(%ecx),%xmm0 + palignr $0x2,%xmm1,%xmm0 + pabsb (%ecx),%mm0 + pabsb %mm1,%mm0 + pabsb (%ecx),%xmm0 + pabsb %xmm1,%xmm0 + pabsw (%ecx),%mm0 + pabsw %mm1,%mm0 + pabsw (%ecx),%xmm0 + pabsw %xmm1,%xmm0 + pabsd (%ecx),%mm0 + pabsd %mm1,%mm0 + pabsd (%ecx),%xmm0 + pabsd %xmm1,%xmm0 + + .p2align 4,0 diff --git a/gas/testsuite/gas/i386/x86-64-merom.d b/gas/testsuite/gas/i386/x86-64-merom.d new file mode 100644 index 0000000..f15a6e4 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-merom.d @@ -0,0 +1,73 @@ +#objdump: -dw +#name: x86-64 merom + +.*: +file format .* + +Disassembly of section .text: + +0+000 : + 0: 0f 38 01 01[ ]+phaddw \(%rcx\),%mm0 + 4: 0f 38 01 c1[ ]+phaddw %mm1,%mm0 + 8: 66 0f 38 01 01[ ]+phaddw \(%rcx\),%xmm0 + d: 66 0f 38 01 c1[ ]+phaddw %xmm1,%xmm0 + 12: 0f 38 02 01[ ]+phaddd \(%rcx\),%mm0 + 16: 0f 38 02 c1[ ]+phaddd %mm1,%mm0 + 1a: 66 0f 38 02 01[ ]+phaddd \(%rcx\),%xmm0 + 1f: 66 0f 38 02 c1[ ]+phaddd %xmm1,%xmm0 + 24: 0f 38 03 01[ ]+phaddsw \(%rcx\),%mm0 + 28: 0f 38 03 c1[ ]+phaddsw %mm1,%mm0 + 2c: 66 0f 38 03 01[ ]+phaddsw \(%rcx\),%xmm0 + 31: 66 0f 38 03 c1[ ]+phaddsw %xmm1,%xmm0 + 36: 0f 38 05 01[ ]+phsubw \(%rcx\),%mm0 + 3a: 0f 38 05 c1[ ]+phsubw %mm1,%mm0 + 3e: 66 0f 38 05 01[ ]+phsubw \(%rcx\),%xmm0 + 43: 66 0f 38 05 c1[ ]+phsubw %xmm1,%xmm0 + 48: 0f 38 06 01[ ]+phsubd \(%rcx\),%mm0 + 4c: 0f 38 06 c1[ ]+phsubd %mm1,%mm0 + 50: 66 0f 38 06 01[ ]+phsubd \(%rcx\),%xmm0 + 55: 66 0f 38 06 c1[ ]+phsubd %xmm1,%xmm0 + 5a: 0f 38 07 01[ ]+phsubsw \(%rcx\),%mm0 + 5e: 0f 38 07 c1[ ]+phsubsw %mm1,%mm0 + 62: 66 0f 38 07 01[ ]+phsubsw \(%rcx\),%xmm0 + 67: 66 0f 38 07 c1[ ]+phsubsw %xmm1,%xmm0 + 6c: 0f 38 04 01[ ]+pmaddubsw \(%rcx\),%mm0 + 70: 0f 38 04 c1[ ]+pmaddubsw %mm1,%mm0 + 74: 66 0f 38 04 01[ ]+pmaddubsw \(%rcx\),%xmm0 + 79: 66 0f 38 04 c1[ ]+pmaddubsw %xmm1,%xmm0 + 7e: 0f 38 0b 01[ ]+pmulhrsw \(%rcx\),%mm0 + 82: 0f 38 0b c1[ ]+pmulhrsw %mm1,%mm0 + 86: 66 0f 38 0b 01[ ]+pmulhrsw \(%rcx\),%xmm0 + 8b: 66 0f 38 0b c1[ ]+pmulhrsw %xmm1,%xmm0 + 90: 0f 38 00 01[ ]+pshufb \(%rcx\),%mm0 + 94: 0f 38 00 c1[ ]+pshufb %mm1,%mm0 + 98: 66 0f 38 00 01[ ]+pshufb \(%rcx\),%xmm0 + 9d: 66 0f 38 00 c1[ ]+pshufb %xmm1,%xmm0 + a2: 0f 38 08 01[ ]+psignb \(%rcx\),%mm0 + a6: 0f 38 08 c1[ ]+psignb %mm1,%mm0 + aa: 66 0f 38 08 01[ ]+psignb \(%rcx\),%xmm0 + af: 66 0f 38 08 c1[ ]+psignb %xmm1,%xmm0 + b4: 0f 38 09 01[ ]+psignw \(%rcx\),%mm0 + b8: 0f 38 09 c1[ ]+psignw %mm1,%mm0 + bc: 66 0f 38 09 01[ ]+psignw \(%rcx\),%xmm0 + c1: 66 0f 38 09 c1[ ]+psignw %xmm1,%xmm0 + c6: 0f 38 0a 01[ ]+psignd \(%rcx\),%mm0 + ca: 0f 38 0a c1[ ]+psignd %mm1,%mm0 + ce: 66 0f 38 0a 01[ ]+psignd \(%rcx\),%xmm0 + d3: 66 0f 38 0a c1[ ]+psignd %xmm1,%xmm0 + d8: 0f 3a 0f 01 02[ ]+palignr \$0x2,\(%rcx\),%mm0 + dd: 0f 3a 0f c1 02[ ]+palignr \$0x2,%mm1,%mm0 + e2: 66 0f 3a 0f 01 02[ ]+palignr \$0x2,\(%rcx\),%xmm0 + e8: 66 0f 3a 0f c1 02[ ]+palignr \$0x2,%xmm1,%xmm0 + ee: 0f 38 1c 01[ ]+pabsb \(%rcx\),%mm0 + f2: 0f 38 1c c1[ ]+pabsb %mm1,%mm0 + f6: 66 0f 38 1c 01[ ]+pabsb \(%rcx\),%xmm0 + fb: 66 0f 38 1c c1[ ]+pabsb %xmm1,%xmm0 + 100: 0f 38 1d 01[ ]+pabsw \(%rcx\),%mm0 + 104: 0f 38 1d c1[ ]+pabsw %mm1,%mm0 + 108: 66 0f 38 1d 01[ ]+pabsw \(%rcx\),%xmm0 + 10d: 66 0f 38 1d c1[ ]+pabsw %xmm1,%xmm0 + 112: 0f 38 1e 01[ ]+pabsd \(%rcx\),%mm0 + 116: 0f 38 1e c1[ ]+pabsd %mm1,%mm0 + 11a: 66 0f 38 1e 01[ ]+pabsd \(%rcx\),%xmm0 + 11f: 66 0f 38 1e c1[ ]+pabsd %xmm1,%xmm0 + ... diff --git a/gas/testsuite/gas/i386/x86-64-merom.s b/gas/testsuite/gas/i386/x86-64-merom.s new file mode 100644 index 0000000..a70654d --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-merom.s @@ -0,0 +1,70 @@ +#Merom New Instructions + + .text +foo: + phaddw (%rcx),%mm0 + phaddw %mm1,%mm0 + phaddw (%rcx),%xmm0 + phaddw %xmm1,%xmm0 + phaddd (%rcx),%mm0 + phaddd %mm1,%mm0 + phaddd (%rcx),%xmm0 + phaddd %xmm1,%xmm0 + phaddsw (%rcx),%mm0 + phaddsw %mm1,%mm0 + phaddsw (%rcx),%xmm0 + phaddsw %xmm1,%xmm0 + phsubw (%rcx),%mm0 + phsubw %mm1,%mm0 + phsubw (%rcx),%xmm0 + phsubw %xmm1,%xmm0 + phsubd (%rcx),%mm0 + phsubd %mm1,%mm0 + phsubd (%rcx),%xmm0 + phsubd %xmm1,%xmm0 + phsubsw (%rcx),%mm0 + phsubsw %mm1,%mm0 + phsubsw (%rcx),%xmm0 + phsubsw %xmm1,%xmm0 + pmaddubsw (%rcx),%mm0 + pmaddubsw %mm1,%mm0 + pmaddubsw (%rcx),%xmm0 + pmaddubsw %xmm1,%xmm0 + pmulhrsw (%rcx),%mm0 + pmulhrsw %mm1,%mm0 + pmulhrsw (%rcx),%xmm0 + pmulhrsw %xmm1,%xmm0 + pshufb (%rcx),%mm0 + pshufb %mm1,%mm0 + pshufb (%rcx),%xmm0 + pshufb %xmm1,%xmm0 + psignb (%rcx),%mm0 + psignb %mm1,%mm0 + psignb (%rcx),%xmm0 + psignb %xmm1,%xmm0 + psignw (%rcx),%mm0 + psignw %mm1,%mm0 + psignw (%rcx),%xmm0 + psignw %xmm1,%xmm0 + psignd (%rcx),%mm0 + psignd %mm1,%mm0 + psignd (%rcx),%xmm0 + psignd %xmm1,%xmm0 + palignr $0x2,(%rcx),%mm0 + palignr $0x2,%mm1,%mm0 + palignr $0x2,(%rcx),%xmm0 + palignr $0x2,%xmm1,%xmm0 + pabsb (%rcx),%mm0 + pabsb %mm1,%mm0 + pabsb (%rcx),%xmm0 + pabsb %xmm1,%xmm0 + pabsw (%rcx),%mm0 + pabsw %mm1,%mm0 + pabsw (%rcx),%xmm0 + pabsw %xmm1,%xmm0 + pabsd (%rcx),%mm0 + pabsd %mm1,%mm0 + pabsd (%rcx),%xmm0 + pabsd %xmm1,%xmm0 + + .p2align 4,0 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 76b7978..9edfd3f 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2006-02-27 H.J. Lu + + * i386.h (i386_optab): Support Intel Merom New Instructions. + 2006-02-24 Paul Brook * arm.h: Add V7 feature bits. diff --git a/include/opcode/i386.h b/include/opcode/i386.h index 33f94cc..2b2c1e0 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -1379,6 +1379,41 @@ static const template i386_optab[] = {"vmxoff", 0, 0x0f01, 0xc4, CpuVMX, NoSuf|ImmExt, { 0, 0, 0} }, {"vmxon", 1, 0xf30fc7, 6, CpuVMX, NoSuf|IgnoreSize|Modrm|NoRex64, { LLongMem, 0, 0} }, +/* Merom New Instructions. */ + +{"phaddw", 2, 0x0f3801,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phaddw", 2, 0x660f3801,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"phaddd", 2, 0x0f3802,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phaddd", 2, 0x660f3802,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"phaddsw", 2, 0x0f3803,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phaddsw", 2, 0x660f3803,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"phsubw", 2, 0x0f3805,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phsubw", 2, 0x660f3805,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"phsubd", 2, 0x0f3806,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phsubd", 2, 0x660f3806,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"phsubsw", 2, 0x0f3807,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"phsubsw", 2, 0x660f3807,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pmaddubsw", 2, 0x0f3804,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmaddubsw", 2, 0x660f3804,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pmulhrsw", 2, 0x0f380b,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmulhrsw", 2, 0x660f380b,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pshufb", 2, 0x0f3800,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pshufb", 2, 0x660f3800,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"psignb", 2, 0x0f3808,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psignb", 2, 0x660f3808,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"psignw", 2, 0x0f3809,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psignw", 2, 0x660f3809,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"psignd", 2, 0x0f380a,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psignd", 2, 0x660f380a,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"palignr", 3, 0x0f3a0f,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { Imm8, RegMMX|LongMem, RegMMX } }, +{"palignr", 3, 0x660f3a0f,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +{"pabsb", 2, 0x0f381c,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pabsb", 2, 0x660f381c,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pabsw", 2, 0x0f381d,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pabsw", 2, 0x660f381d,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pabsd", 2, 0x0f381e,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pabsd", 2, 0x660f381e,X, CpuMNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, + /* AMD 3DNow! instructions. */ {"prefetch", 1, 0x0f0d, 0, Cpu3dnow, NoSuf|IgnoreSize|Modrm, { ByteMem, 0, 0 } }, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index d97df75..a457dd4 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,17 @@ +2006-02-27 H.J. Lu + + * i386-dis.c (IS_3BYTE_OPCODE): New for 3-byte opcodes used by + Intel Merom New Instructions. + (THREE_BYTE_0): Likewise. + (THREE_BYTE_1): Likewise. + (three_byte_table): Likewise. + (dis386_twobyte): Use THREE_BYTE_0 for entry 0x38. Use + THREE_BYTE_1 for entry 0x3a. + (twobyte_has_modrm): Updated. + (twobyte_uses_SSE_prefix): Likewise. + (print_insn): Handle 3-byte opcodes used by Intel Merom New + Instructions. + 2006-02-24 David S. Miller * sparc-dis.c (v9_priv_reg_names): Add "gl" entry. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 4fb487d..06a842e 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -388,6 +388,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define USE_GROUPS 2 #define USE_PREFIX_USER_TABLE 3 #define X86_64_SPECIAL 4 +#define IS_3BYTE_OPCODE 5 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 @@ -453,6 +454,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0 +#define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0 +#define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0 + typedef void (*op_rtn) (int bytemode, int sizeflag); struct dis386 { @@ -858,9 +862,9 @@ static const struct dis386 dis386_twobyte[] = { { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, /* 38 */ + { THREE_BYTE_0 }, { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { THREE_BYTE_1 }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, @@ -1113,7 +1117,7 @@ static const unsigned char twobyte_has_modrm[256] = { /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ - /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ + /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ @@ -1136,7 +1140,7 @@ static const unsigned char twobyte_uses_SSE_prefix[256] = { /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */ /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ - /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ + /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */ /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */ @@ -1749,6 +1753,79 @@ static const struct dis386 x86_64_table[][2] = { }, }; +static const struct dis386 three_byte_table[][32] = { + /* THREE_BYTE_0 */ + { + { "pshufb", MX, EM, XX }, + { "phaddw", MX, EM, XX }, + { "phaddd", MX, EM, XX }, + { "phaddsw", MX, EM, XX }, + { "pmaddubsw", MX, EM, XX }, + { "phsubw", MX, EM, XX }, + { "phsubd", MX, EM, XX }, + { "phsubsw", MX, EM, XX }, + { "psignb", MX, EM, XX }, + { "psignw", MX, EM, XX }, + { "psignd", MX, EM, XX }, + { "pmulhrsw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "pabsb", MX, EM, XX }, + { "pabsw", MX, EM, XX }, + { "pabsd", MX, EM, XX }, + { "(bad)", XX, XX, XX } + }, + /* THREE_BYTE_1 */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "palignr", MX, EM, Ib }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX } + }, +}; + #define INTERNAL_DISASSEMBLER_ERROR _("") static void @@ -2206,7 +2283,15 @@ print_insn (bfd_vma pc, disassemble_info *info) } } - if (need_modrm) + if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE) + { + FETCH_DATA (info, codep + 2); + dp = &three_byte_table[dp->bytemode2][*codep++]; + mod = (*codep >> 6) & 3; + reg = (*codep >> 3) & 7; + rm = *codep & 7; + } + else if (need_modrm) { FETCH_DATA (info, codep + 1); mod = (*codep >> 6) & 3; -- 2.7.4