From c608c12e5e611dbf20510ccee5eda67412891476 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 13 May 1999 06:00:30 +0000 Subject: [PATCH] P i386 PIII SIMD support, remove ReverseRegRegmem kludge tidy a few things in i386 intel mode disassembly --- gas/testsuite/ChangeLog | 15 + gas/testsuite/gas/i386/amd.d | 7 +- gas/testsuite/gas/i386/amd.s | 5 +- gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/opcode.d | 2 +- gas/testsuite/gas/i386/prefix.d | 2 +- gas/testsuite/gas/i386/prefix.s | 4 +- gas/testsuite/gas/i386/reloc.d | 5 + gas/testsuite/gas/i386/reloc.s | 3 + include/opcode/ChangeLog | 11 + include/opcode/i386.h | 360 +++++++---- opcodes/ChangeLog | 48 ++ opcodes/i386-dis.c | 1067 ++++++++++++++++++++----------- 13 files changed, 1006 insertions(+), 524 deletions(-) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d8f865680e5..9349c8db9b9 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,18 @@ +1999-05-12 Alan Modra + + * gas/i386/opcode.d: Modify callw to suit disasm fix. + + * gas/i386/amd.d: Modify a '(bad)' to SIMD instruction. + + * gas/i386/amd.s: Pad to multiple of 8 + * gas/i386/amd.d: Here too. + + * gas/i386/prefix.[sd]: Align with nops + * gas/i386/reloc.[sd]: Here too. + + * gas/i386/katmai.[sd]: New for PIII SIMD + * gas/i386/i386.exp: Call it. + 1999-05-02 Nick Clifton * gas/mcore/allinsn.d: Update to match latest assembler diff --git a/gas/testsuite/gas/i386/amd.d b/gas/testsuite/gas/i386/amd.d index 2fe8b0e8b28..68f6f7728a9 100644 --- a/gas/testsuite/gas/i386/amd.d +++ b/gas/testsuite/gas/i386/amd.d @@ -29,9 +29,12 @@ Disassembly of section .text: 6b: 0f 0f ce 0d [ ]*pi2fd %mm6,%mm1 6f: 0f 0f d7 b7 [ ]*pfmulhrw %mm7,%mm2 73: 2e 0f [ ]*\(bad\) - 75: 0f 54 [ ]*\(bad\) - 77: c3 [ ]*ret + 75: 0f 54 c3 [ ]*andps %xmm3,%xmm0 78: 07 [ ]*pop %es 79: c3 [ ]*ret 7a: 90 [ ]*nop 7b: 90 [ ]*nop + 7c: 90 [ ]*nop + 7d: 90 [ ]*nop + 7e: 90 [ ]*nop + 7f: 90 [ ]*nop diff --git a/gas/testsuite/gas/i386/amd.s b/gas/testsuite/gas/i386/amd.s index 5e4d581f08e..af4cd452daa 100644 --- a/gas/testsuite/gas/i386/amd.s +++ b/gas/testsuite/gas/i386/amd.s @@ -28,6 +28,5 @@ # Everything's good bar the opcode suffix .byte 0x2e, 0x0f, 0x0f, 0x54, 0xc3, 0x07, 0xc3 -# to make us insensitive to alignment - nop - nop +# Pad out to a good alignment + .byte 0x90,0x90,0x90,0x90,0x90,0x90 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index cef1ff7ac0a..44049f75dc5 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -24,6 +24,7 @@ if [istarget "i*86-*-*"] then { run_dump_test "opcode" run_dump_test "prefix" run_dump_test "amd" + run_dump_test "katmai" # The reloc and white tests require support for 8 and 16 bit # relocs, so we only run them for ELF targets. diff --git a/gas/testsuite/gas/i386/opcode.d b/gas/testsuite/gas/i386/opcode.d index fc3c158a161..6df49d77eb6 100644 --- a/gas/testsuite/gas/i386/opcode.d +++ b/gas/testsuite/gas/i386/opcode.d @@ -526,7 +526,7 @@ Disassembly of section .text: 879: 66 d3 90 90 90 90 90 [ ]*rclw %cl,0x90909090\(%eax\) 880: 66 e5 90 [ ]*in \$0x90,%ax 883: 66 e7 90 [ ]*out %ax,\$0x90 - 886: 66 e8 8f 90 [ ]*callw (0x)?ffff9919.* + 886: 66 e8 8f 90 [ ]*callw (0x)?9919.* 88a: 66 ea 90 90 90 90 [ ]*ljmpw \$0x9090,\$0x9090 890: 66 ed [ ]*in \(%dx\),%ax 892: 66 ef [ ]*out %ax,\(%dx\) diff --git a/gas/testsuite/gas/i386/prefix.d b/gas/testsuite/gas/i386/prefix.d index 054b658a3cf..61eba812a41 100644 --- a/gas/testsuite/gas/i386/prefix.d +++ b/gas/testsuite/gas/i386/prefix.d @@ -12,4 +12,4 @@ Disassembly of section .text: b: 9b df e0 [ ]*fstsw %ax e: 9b 67 df e0 [ ]*addr16 fstsw %ax 12: f3 67 66 36 a7 [ ]*repz addr16 cmpsw %es:\(%di\),%ss:\(%si\) - ... + 17: 90 [ ]*nop diff --git a/gas/testsuite/gas/i386/prefix.s b/gas/testsuite/gas/i386/prefix.s index 043d31068ad..a998b415b1f 100644 --- a/gas/testsuite/gas/i386/prefix.s +++ b/gas/testsuite/gas/i386/prefix.s @@ -7,5 +7,5 @@ foo: addr16 fstsw %ax addr16 rep cmpsw %es:(%di),%ss:(%si) - # Get a good alignment. - .byte 0 +# Get a good alignment. + nop diff --git a/gas/testsuite/gas/i386/reloc.d b/gas/testsuite/gas/i386/reloc.d index c7903dd8d21..f0354ff0b87 100644 --- a/gas/testsuite/gas/i386/reloc.d +++ b/gas/testsuite/gas/i386/reloc.d @@ -13,3 +13,8 @@ Disassembly of section .text: 12: 69 d2 00 00 00 00 [ ]*imul \$0x0,%edx,%edx 14: R_386_32 .text 18: 9a 00 00 00 00 00 00 [ ]*lcall \$0x0,\$0x0 19: R_386_32 .text 1f: 66 68 00 00 [ ]*pushw \$0x0 21: R_386_16 .text + 23: 90 [ ]*nop + 24: 90 [ ]*nop + 25: 90 [ ]*nop + 26: 90 [ ]*nop + 27: 90 [ ]*nop diff --git a/gas/testsuite/gas/i386/reloc.s b/gas/testsuite/gas/i386/reloc.s index 13ee930db72..2bf95b69a63 100644 --- a/gas/testsuite/gas/i386/reloc.s +++ b/gas/testsuite/gas/i386/reloc.s @@ -6,3 +6,6 @@ foo: mov $foo, %bl imul $foo, %edx lcall $0, $foo pushw $foo + +# Pad out to a good alignment + .byte 0x90,0x90,0x90,0x90,0x90 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 9adf7be2259..7827ba0dc46 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,14 @@ +1999-05-12 Alan Modra + + * i386.h (ReverseModrm): Remove all occurences. + (InvMem): Add to control/debug/test mov insns, movhlps, movlhps, + movmskps, pextrw, pmovmskb, maskmovq. + Change NoSuf to FP on all MMX, XMM and AMD insns as these all + ignore the data size prefix. + + * i386.h (i386_optab, i386_regtab): Add support for PIII SIMD. + Mostly stolen from Doug Ledford + Sat May 8 23:27:35 1999 Richard Henderson * ppc.h (PPC_OPCODE_64_BRIDGE): New. diff --git a/include/opcode/i386.h b/include/opcode/i386.h index ef8fece15e1..41f2412d65f 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -42,7 +42,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static const template i386_optab[] = { #define X None -#define ReverseModrm (ReverseRegRegmem|Modrm) #define NoSuf (No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf) #define b_Suf (No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf) #define w_Suf (No_bSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf) @@ -84,26 +83,26 @@ static const template i386_optab[] = { { "mov", 2, 0x8c, X, wl_Suf|Modrm, { SReg3|SReg2, WordReg|WordMem, 0 } }, { "mov", 2, 0x8e, X, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg3|SReg2, 0 } }, /* move to/from control debug registers */ -{ "mov", 2, 0x0f20, X, l_Suf|D|Modrm|IgnoreSize, { Control, Reg32, 0} }, -{ "mov", 2, 0x0f21, X, l_Suf|D|Modrm|IgnoreSize, { Debug, Reg32, 0} }, -{ "mov", 2, 0x0f24, X, l_Suf|D|Modrm|IgnoreSize, { Test, Reg32, 0} }, +{ "mov", 2, 0x0f20, X, l_Suf|D|Modrm|IgnoreSize, { Control, Reg32|InvMem, 0} }, +{ "mov", 2, 0x0f21, X, l_Suf|D|Modrm|IgnoreSize, { Debug, Reg32|InvMem, 0} }, +{ "mov", 2, 0x0f24, X, l_Suf|D|Modrm|IgnoreSize, { Test, Reg32|InvMem, 0} }, /* move with sign extend */ /* "movsbl" & "movsbw" must not be unified into "movsb" to avoid conflict with the "movs" string move instruction. */ -{"movsbl", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg32, 0} }, -{"movsbw", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg16, 0} }, -{"movswl", 2, 0x0fbf, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} }, +{"movsbl", 2, 0x0fbe, X, NoSuf|Modrm, { Reg8|ByteMem, Reg32, 0} }, +{"movsbw", 2, 0x0fbe, X, NoSuf|Modrm, { Reg8|ByteMem, Reg16, 0} }, +{"movswl", 2, 0x0fbf, X, NoSuf|Modrm, { Reg16|ShortMem, Reg32, 0} }, /* Intel Syntax */ -{"movsx", 2, 0x0fbf, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} }, -{"movsx", 2, 0x0fbe, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} }, +{"movsx", 2, 0x0fbf, X, w_Suf|Modrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} }, +{"movsx", 2, 0x0fbe, X, b_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, /* move with zero extend */ -{"movzb", 2, 0x0fb6, X, wl_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} }, -{"movzwl", 2, 0x0fb7, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} }, +{"movzb", 2, 0x0fb6, X, wl_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, +{"movzwl", 2, 0x0fb7, X, NoSuf|Modrm, { Reg16|ShortMem, Reg32, 0} }, /* Intel Syntax */ -{"movzx", 2, 0x0fb7, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} }, -{"movzx", 2, 0x0fb6, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} }, +{"movzx", 2, 0x0fb7, X, w_Suf|Modrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} }, +{"movzx", 2, 0x0fb6, X, b_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, /* push instructions */ {"push", 1, 0x50, X, wl_Suf|ShortForm, { WordReg,0,0 } }, @@ -250,9 +249,9 @@ static const template i386_optab[] = { These multiplies can only be selected with single operand forms. */ {"mul", 1, 0xf6, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, {"imul", 1, 0xf6, 5, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, -{"imul", 2, 0x0faf, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"imul", 3, 0x6b, X, wl_Suf|ReverseModrm, { Imm8S, WordReg|WordMem, WordReg} }, -{"imul", 3, 0x69, X, wl_Suf|ReverseModrm, { Imm16|Imm32, WordReg|WordMem, WordReg} }, +{"imul", 2, 0x0faf, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"imul", 3, 0x6b, X, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, WordReg} }, +{"imul", 3, 0x69, X, wl_Suf|Modrm, { Imm16|Imm32, WordReg|WordMem, WordReg} }, /* imul with 2 operands mimics imul with 3 by putting the register in both i.rm.reg & i.rm.regmem fields. regKludge enables this transformation. */ @@ -448,8 +447,8 @@ static const template i386_optab[] = { {"xlat", 1, 0xd7, X, b_Suf|IsString, { AnyMem, 0, 0} }, /* bit manipulation */ -{"bsf", 2, 0x0fbc, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"bsr", 2, 0x0fbd, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, +{"bsf", 2, 0x0fbc, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"bsr", 2, 0x0fbd, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, {"bt", 2, 0x0fa3, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, {"bt", 2, 0x0fba, 4, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} }, {"btc", 2, 0x0fbb, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, @@ -479,12 +478,12 @@ static const template i386_optab[] = { /* protection control */ {"arpl", 2, 0x63, X, NoSuf|Modrm|IgnoreSize,{ Reg16, Reg16|ShortMem, 0} }, -{"lar", 2, 0x0f02, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, +{"lar", 2, 0x0f02, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, {"lgdt", 1, 0x0f01, 2, wl_Suf|Modrm, { WordMem, 0, 0} }, {"lidt", 1, 0x0f01, 3, wl_Suf|Modrm, { WordMem, 0, 0} }, {"lldt", 1, 0x0f00, 2, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, {"lmsw", 1, 0x0f01, 6, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, -{"lsl", 2, 0x0f03, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, +{"lsl", 2, 0x0f03, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, {"ltr", 1, 0x0f00, 3, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, {"sgdt", 1, 0x0f01, 0, wl_Suf|Modrm, { WordMem, 0, 0} }, @@ -794,34 +793,34 @@ static const template i386_optab[] = { {"ud2a", 0, 0x0f0b, X, NoSuf, { 0, 0, 0} }, /* alias for ud2 */ {"ud2b", 0, 0x0fb9, X, NoSuf, { 0, 0, 0} }, /* 2nd. official undefined instr. */ -{"cmovo", 2, 0x0f40, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovno", 2, 0x0f41, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovb", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovc", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnae", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovae", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnc", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnb", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmove", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovz", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovne", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnz", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovbe", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovna", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmova", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnbe", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovs", 2, 0x0f48, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovns", 2, 0x0f49, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovp", 2, 0x0f4a, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnp", 2, 0x0f4b, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovl", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnge", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovge", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnl", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovle", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovng", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovg", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, -{"cmovnle", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovo", 2, 0x0f40, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovno", 2, 0x0f41, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovb", 2, 0x0f42, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovc", 2, 0x0f42, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnae", 2, 0x0f42, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovae", 2, 0x0f43, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnc", 2, 0x0f43, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnb", 2, 0x0f43, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmove", 2, 0x0f44, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovz", 2, 0x0f44, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovne", 2, 0x0f45, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnz", 2, 0x0f45, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovbe", 2, 0x0f46, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovna", 2, 0x0f46, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmova", 2, 0x0f47, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnbe", 2, 0x0f47, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovs", 2, 0x0f48, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovns", 2, 0x0f49, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovp", 2, 0x0f4a, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnp", 2, 0x0f4b, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovl", 2, 0x0f4c, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnge", 2, 0x0f4c, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovge", 2, 0x0f4d, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnl", 2, 0x0f4d, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovle", 2, 0x0f4e, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovng", 2, 0x0f4e, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovg", 2, 0x0f4f, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +{"cmovnle", 2, 0x0f4f, X, wl_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, {"fcmovb", 2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} }, {"fcmovnae",2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} }, @@ -853,95 +852,182 @@ static const template i386_optab[] = { /* MMX instructions. */ -{"emms", 0, 0x0f77, X, NoSuf, { 0, 0, 0 } }, -{"movd", 2, 0x0f6e, X, NoSuf|Modrm, { Reg32|LongMem, RegMMX, 0 } }, -{"movd", 2, 0x0f7e, X, NoSuf|Modrm, { RegMMX, Reg32|LongMem, 0 } }, -{"movq", 2, 0x0f6f, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"movq", 2, 0x0f7f, X, NoSuf|Modrm, { RegMMX, RegMMX|LongMem, 0 } }, -{"packssdw", 2, 0x0f6b, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"packsswb", 2, 0x0f63, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"packuswb", 2, 0x0f67, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddb", 2, 0x0ffc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddw", 2, 0x0ffd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddd", 2, 0x0ffe, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddsb", 2, 0x0fec, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddsw", 2, 0x0fed, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddusb", 2, 0x0fdc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"paddusw", 2, 0x0fdd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pand", 2, 0x0fdb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pandn", 2, 0x0fdf, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpeqb", 2, 0x0f74, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpeqw", 2, 0x0f75, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpeqd", 2, 0x0f76, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpgtb", 2, 0x0f64, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpgtw", 2, 0x0f65, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pcmpgtd", 2, 0x0f66, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pmaddwd", 2, 0x0ff5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pmulhw", 2, 0x0fe5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pmullw", 2, 0x0fd5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"por", 2, 0x0feb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psllw", 2, 0x0ff1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psllw", 2, 0x0f71, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"pslld", 2, 0x0ff2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pslld", 2, 0x0f72, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psllq", 2, 0x0ff3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psllq", 2, 0x0f73, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psraw", 2, 0x0fe1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psraw", 2, 0x0f71, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psrad", 2, 0x0fe2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psrad", 2, 0x0f72, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psrlw", 2, 0x0fd1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psrlw", 2, 0x0f71, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psrld", 2, 0x0fd2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psrld", 2, 0x0f72, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psrlq", 2, 0x0fd3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psrlq", 2, 0x0f73, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } }, -{"psubb", 2, 0x0ff8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubw", 2, 0x0ff9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubd", 2, 0x0ffa, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubsb", 2, 0x0fe8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubsw", 2, 0x0fe9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubusb", 2, 0x0fd8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"psubusw", 2, 0x0fd9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpckhbw",2, 0x0f68, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpckhwd",2, 0x0f69, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpckhdq",2, 0x0f6a, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpcklbw",2, 0x0f60, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpcklwd",2, 0x0f61, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"punpckldq",2, 0x0f62, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pxor", 2, 0x0fef, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, - - +{"emms", 0, 0x0f77, X, FP, { 0, 0, 0 } }, +{"movd", 2, 0x0f6e, X, FP|Modrm, { Reg32|LongMem, RegMMX, 0 } }, +{"movd", 2, 0x0f7e, X, FP|Modrm, { RegMMX, Reg32|LongMem, 0 } }, +{"movq", 2, 0x0f6f, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"movq", 2, 0x0f7f, X, FP|Modrm, { RegMMX, RegMMX|LongMem, 0 } }, +{"packssdw", 2, 0x0f6b, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"packsswb", 2, 0x0f63, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"packuswb", 2, 0x0f67, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddb", 2, 0x0ffc, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddw", 2, 0x0ffd, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddd", 2, 0x0ffe, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddsb", 2, 0x0fec, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddsw", 2, 0x0fed, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddusb", 2, 0x0fdc, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"paddusw", 2, 0x0fdd, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pand", 2, 0x0fdb, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pandn", 2, 0x0fdf, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpeqb", 2, 0x0f74, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpeqw", 2, 0x0f75, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpeqd", 2, 0x0f76, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpgtb", 2, 0x0f64, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpgtw", 2, 0x0f65, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pcmpgtd", 2, 0x0f66, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmaddwd", 2, 0x0ff5, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmulhw", 2, 0x0fe5, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmullw", 2, 0x0fd5, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"por", 2, 0x0feb, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psllw", 2, 0x0ff1, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psllw", 2, 0x0f71, 6, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"pslld", 2, 0x0ff2, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pslld", 2, 0x0f72, 6, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psllq", 2, 0x0ff3, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psllq", 2, 0x0f73, 6, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psraw", 2, 0x0fe1, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psraw", 2, 0x0f71, 4, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psrad", 2, 0x0fe2, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psrad", 2, 0x0f72, 4, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psrlw", 2, 0x0fd1, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psrlw", 2, 0x0f71, 2, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psrld", 2, 0x0fd2, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psrld", 2, 0x0f72, 2, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psrlq", 2, 0x0fd3, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psrlq", 2, 0x0f73, 2, FP|Modrm, { Imm8, RegMMX, 0 } }, +{"psubb", 2, 0x0ff8, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubw", 2, 0x0ff9, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubd", 2, 0x0ffa, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubsb", 2, 0x0fe8, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubsw", 2, 0x0fe9, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubusb", 2, 0x0fd8, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"psubusw", 2, 0x0fd9, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpckhbw",2, 0x0f68, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpckhwd",2, 0x0f69, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpckhdq",2, 0x0f6a, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpcklbw",2, 0x0f60, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpcklwd",2, 0x0f61, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"punpckldq",2, 0x0f62, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +{"pxor", 2, 0x0fef, X, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, + + +/* PIII Katmai New Instructions / SIMD instructions */ + +{"addps", 2, 0x0f58, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"addss", 2, 0xf30f58, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"andnps", 2, 0x0f55, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"andps", 2, 0x0f54, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpps", 3, 0x0fc2, X, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +{"cmpss", 3, 0xf30fc2, X, FP|Modrm, { Imm8, RegXMM|WordMem, RegXMM } }, +{"cmpeqps", 2, 0x0fc2, 0, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpeqss", 2, 0xf30fc2, 0, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpltps", 2, 0x0fc2, 1, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpltss", 2, 0xf30fc2, 1, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpleps", 2, 0x0fc2, 2, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpless", 2, 0xf30fc2, 2, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpunordps",2, 0x0fc2, 3, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpunordss",2, 0xf30fc2, 3, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpneqps", 2, 0x0fc2, 4, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpneqss", 2, 0xf30fc2, 4, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpnltps", 2, 0x0fc2, 5, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpnltss", 2, 0xf30fc2, 5, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpnleps", 2, 0x0fc2, 6, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpnless", 2, 0xf30fc2, 6, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"cmpordps", 2, 0x0fc2, 7, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +{"cmpordss", 2, 0xf30fc2, 7, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +{"comiss", 2, 0x0f2f, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"cvtpi2ps", 2, 0x0f2a, X, FP|Modrm, { RegMMX|LLongMem, RegXMM, 0 } }, +{"cvtsi2ss", 2, 0xf30f2a, X, FP|Modrm, { Reg32|WordMem, RegXMM, 0 } }, +{"cvtps2pi", 2, 0x0f2d, X, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +{"cvtss2si", 2, 0xf30f2d, X, FP|Modrm, { RegXMM|WordMem, Reg32, 0 } }, +{"cvttps2pi", 2, 0x0f2c, X, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +{"cvttss2si", 2, 0xf30f2c, X, FP|Modrm, { RegXMM|WordMem, Reg32, 0 } }, +{"divps", 2, 0x0f5e, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"divss", 2, 0xf30f5e, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"ldmxcsr", 1, 0x0fae, 2, FP|Modrm, { WordMem, 0, 0 } }, +{"stmxcsr", 1, 0x0fae, 3, FP|Modrm, { WordMem, 0, 0 } }, +{"sfence", 0, 0x0faef8, X, FP, { 0, 0, 0 } }, +{"maxps", 2, 0x0f5f, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"maxss", 2, 0xf30f5f, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"minps", 2, 0x0f5d, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"minss", 2, 0xf30f5d, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"movaps", 2, 0x0f28, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"movaps", 2, 0x0f29, X, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +{"movhlps", 2, 0x0f12, X, FP|Modrm, { RegXMM|InvMem, RegXMM, 0 } }, +{"movhps", 2, 0x0f16, X, FP|Modrm, { LLongMem, RegXMM, 0 } }, +{"movhps", 2, 0x0f17, X, FP|Modrm, { RegXMM, LLongMem, 0 } }, +{"movlhps", 2, 0x0f16, X, FP|Modrm, { RegXMM|InvMem, RegXMM, 0 } }, +{"movlps", 2, 0x0f12, X, FP|Modrm, { LLongMem, RegXMM, 0 } }, +{"movlps", 2, 0x0f13, X, FP|Modrm, { RegXMM, LLongMem, 0 } }, +{"movmskps", 2, 0x0f50, X, FP|Modrm, { RegXMM|InvMem, Reg32, 0 } }, +{"movups", 2, 0x0f10, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"movups", 2, 0x0f11, X, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +{"movss", 2, 0xf30f10, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"movss", 2, 0xf30f11, X, FP|Modrm, { RegXMM, RegXMM|WordMem, 0 } }, +{"mulps", 2, 0x0f59, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"mulss", 2, 0xf30f59, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"orps", 2, 0x0f56, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"rcpps", 2, 0x0f53, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"rcpss", 2, 0xf30f53, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"rsqrtps", 2, 0x0f52, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"rsqrtss", 2, 0xf30f52, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"shufps", 3, 0x0fc6, X, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +{"sqrtps", 2, 0x0f51, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"sqrtss", 2, 0xf30f51, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"subps", 2, 0x0f5c, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"subss", 2, 0xf30f5c, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"ucomiss", 2, 0x0f2e, X, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +{"unpckhps", 2, 0x0f15, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"unpcklps", 2, 0x0f14, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"xorps", 2, 0x0f57, X, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +{"pavgb", 2, 0x0fe0, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pavgw", 2, 0x0fe3, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pextrw", 3, 0x0fc5, X, FP|Modrm, { Imm8, RegMMX, Reg32|InvMem } }, +{"pinsrw", 3, 0x0fc4, X, FP|Modrm, { Imm8, Reg32|ShortMem, RegMMX } }, +{"pmaxsw", 2, 0x0fee, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pmaxub", 2, 0x0fde, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pminsw", 2, 0x0fea, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pminub", 2, 0x0fda, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pmovmskb", 2, 0x0fd7, X, FP|Modrm, { RegMMX, Reg32|InvMem, 0 } }, +{"pmulhuw", 2, 0x0fe4, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"psadbw", 2, 0x0ff6, X, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +{"pshufw", 3, 0x0f70, X, FP|Modrm, { Imm8, RegMMX|LLongMem, RegMMX } }, +{"maskmovq", 2, 0x0ff7, X, FP|Modrm, { RegMMX|InvMem, RegMMX, 0 } }, +{"movntps", 2, 0x0f2b, X, FP|Modrm, { RegXMM, LLongMem, 0 } }, +{"movntq", 2, 0x0fe7, X, FP|Modrm, { RegMMX, LLongMem, 0 } }, +{"prefetchnta", 1, 0x0f18, 0, FP|Modrm, { LLongMem, 0, 0 } }, +{"prefetcht0", 1, 0x0f18, 1, FP|Modrm, { LLongMem, 0, 0 } }, +{"prefetcht1", 1, 0x0f18, 2, FP|Modrm, { LLongMem, 0, 0 } }, +{"prefetcht2", 1, 0x0f18, 3, FP|Modrm, { LLongMem, 0, 0 } }, + /* AMD 3DNow! instructions */ -#define AMD_3DNOW_OPCODE 0x0f0f - -{"prefetch", 1, 0x0f0d, 0, NoSuf|Modrm, { ByteMem, 0, 0 } }, -{"prefetchw",1, 0x0f0d, 1, NoSuf|Modrm, { ByteMem, 0, 0 } }, -{"femms", 0, 0x0f0e, X, NoSuf, { 0, 0, 0 } }, -{"pavgusb", 2, 0x0f0f, 0xbf, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pf2id", 2, 0x0f0f, 0x1d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfacc", 2, 0x0f0f, 0xae, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfadd", 2, 0x0f0f, 0x9e, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfcmpeq", 2, 0x0f0f, 0xb0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfcmpge", 2, 0x0f0f, 0x90, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfcmpgt", 2, 0x0f0f, 0xa0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfmax", 2, 0x0f0f, 0xa4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfmin", 2, 0x0f0f, 0x94, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfmul", 2, 0x0f0f, 0xb4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfrcp", 2, 0x0f0f, 0x96, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfrcpit1", 2, 0x0f0f, 0xa6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfrcpit2", 2, 0x0f0f, 0xb6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfrsqit1", 2, 0x0f0f, 0xa7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfrsqrt", 2, 0x0f0f, 0x97, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfsub", 2, 0x0f0f, 0x9a, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pfsubr", 2, 0x0f0f, 0xaa, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pi2fd", 2, 0x0f0f, 0x0d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, -{"pmulhrw", 2, 0x0f0f, 0xb7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, + +{"prefetch", 1, 0x0f0d, 0, FP|Modrm, { ByteMem, 0, 0 } }, +{"prefetchw",1, 0x0f0d, 1, FP|Modrm, { ByteMem, 0, 0 } }, +{"femms", 0, 0x0f0e, X, FP, { 0, 0, 0 } }, +{"pavgusb", 2, 0x0f0f, 0xbf, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pf2id", 2, 0x0f0f, 0x1d, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfacc", 2, 0x0f0f, 0xae, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfadd", 2, 0x0f0f, 0x9e, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfcmpeq", 2, 0x0f0f, 0xb0, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfcmpge", 2, 0x0f0f, 0x90, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfcmpgt", 2, 0x0f0f, 0xa0, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfmax", 2, 0x0f0f, 0xa4, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfmin", 2, 0x0f0f, 0x94, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfmul", 2, 0x0f0f, 0xb4, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfrcp", 2, 0x0f0f, 0x96, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfrcpit1", 2, 0x0f0f, 0xa6, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfrcpit2", 2, 0x0f0f, 0xb6, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfrsqit1", 2, 0x0f0f, 0xa7, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfrsqrt", 2, 0x0f0f, 0x97, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfsub", 2, 0x0f0f, 0x9a, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pfsubr", 2, 0x0f0f, 0xaa, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pi2fd", 2, 0x0f0f, 0x0d, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +{"pmulhrw", 2, 0x0f0f, 0xb7, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, {NULL, 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */ }; #undef X -#undef ReverseModrm #undef NoSuf #undef b_Suf #undef w_Suf @@ -1047,7 +1133,15 @@ static const reg_entry i386_regtab[] = { {"mm4", RegMMX, 4}, {"mm5", RegMMX, 5}, {"mm6", RegMMX, 6}, - {"mm7", RegMMX, 7} + {"mm7", RegMMX, 7}, + {"xmm0", RegXMM, 0}, + {"xmm1", RegXMM, 1}, + {"xmm2", RegXMM, 2}, + {"xmm3", RegXMM, 3}, + {"xmm4", RegXMM, 4}, + {"xmm5", RegXMM, 5}, + {"xmm6", RegXMM, 6}, + {"xmm7", RegXMM, 7} }; #define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */ diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 36b067983d8..6a444672aa7 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,51 @@ +1999-05-12 Alan Modra + + * i386-dis.c (dis386_intel): Remove macro chars, except for + jEcxz. Change cWtR and cRtd to cW and cR. + (dis386_twobyte_intel): Remove macro chars here too. + (putop): Handle R and W macros for intel mode. + + * i386-dis.c (SIMD_Fixup): New function. + (dis386_twobyte_att): Use it on movlps and movhps, and change + Ev to EX on these insns. Change movmskps Ev, XM to Gv, EX. + (dis386_twobyte_intel): Same here. + + * i386-dis.c (Av): Remove. + (Ap): remove lptr. + (lptr): Remove. + (OPSIMD): Define. + (OP_SIMD_Suffix): New function. + (OP_DIR): Remove dead code. + (eAX_reg..eDI_reg): Renumber. + (onebyte_has_modrm): Table numbering comments. + (INTERNAL_DISASSEMBLER_ERROR): Move to before print_insn_x86. + (print_insn_x86): Move all prefix oappends to after uses_f3_prefix + checks. Print error on invalid dp->bytemode2. Remove simd_cmp, + and handle SIMD cmp insns in OP_SIMD_Suffix. + (info->bytes_per_line): Bump from 5 to 6. + (OP_None): Remove. + (OP_E): Use INTERNAL_DISASSEMBLER_ERROR. Handle sfence. + (OP_3DNowSuffix): Ensure mnemonic index unsigned. + + PIII SIMD support from Doug Ledford + * i386-dis.c (XM, EX, None): Define. + (OP_XMM, OP_EX, OP_None): New functions. + (USE_GROUPS, USE_PREFIX_USER_TABLE): Define. + (GRP14): Rename to GRPAMD. + (GRP*): Add USE_GROUPS flag. + (PREGRP*): Define. + (dis386_twobyte_att, dis386_twobyte_intel): Add SIMD insns. + (twobyte_has_modrm): Add SIMD entries. + (twobyte_uses_f3_prefix, simd_cmp_op, prefix_user_table): New. + (grps): Add SIMD insns. + (print_insn_x86): New vars uses_f3_prefix and simd_cmp. Don't + oappend repz if uses_f3_prefix. Add code to handle new groups for + SIMD insns. + + From Maciej W. Rozycki + * i386-dis.c (dis386_att, dis386_intel): Change 0xE8 call insn + operand from Av to Jv. + 1999-05-07 Nick Clifton * mcore-dis.c (print_insn_mcore): Use .short to display diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 19144cb9fc5..9d36eeb8e0d 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -136,8 +136,7 @@ fetch_data (info, addr) #define indirDX OP_REG, indir_dx_reg #define Sw OP_SEG, w_mode -#define Ap OP_DIR, lptr -#define Av OP_DIR, v_mode +#define Ap OP_DIR, 0 #define Ob OP_OFF, b_mode #define Ov OP_OFF, v_mode #define Xb OP_DSreg, eSI_reg @@ -154,9 +153,13 @@ fetch_data (info, addr) #define gs OP_REG, gs_reg #define MX OP_MMX, 0 +#define XM OP_XMM, 0 #define EM OP_EM, v_mode +#define EX OP_EX, v_mode #define MS OP_MS, b_mode +#define None OP_E, 0 #define OPSUF OP_3DNowSuffix, 0 +#define OPSIMD OP_SIMD_Suffix, 0 /* bits in sizeflag */ #if 0 /* leave undefined until someone adds the extra flag to objdump */ @@ -189,9 +192,13 @@ static void OP_STi PARAMS ((int, int)); static void OP_ONE PARAMS ((int, int)); #endif static void OP_MMX PARAMS ((int, int)); +static void OP_XMM PARAMS ((int, int)); static void OP_EM PARAMS ((int, int)); +static void OP_EX PARAMS ((int, int)); static void OP_MS PARAMS ((int, int)); static void OP_3DNowSuffix PARAMS ((int, int)); +static void OP_SIMD_Suffix PARAMS ((int, int)); +static void SIMD_Fixup PARAMS ((int, int)); static void append_seg PARAMS ((void)); static void set_op PARAMS ((unsigned int op)); @@ -214,16 +221,15 @@ static void ptr_reg PARAMS ((int, int)); #define ds_reg 103 #define fs_reg 104 #define gs_reg 105 -#define eAX_reg 107 -#define eCX_reg 108 -#define eDX_reg 109 -#define eBX_reg 110 -#define eSP_reg 111 -#define eBP_reg 112 -#define eSI_reg 113 -#define eDI_reg 114 -#define lptr 115 +#define eAX_reg 108 +#define eCX_reg 109 +#define eDX_reg 110 +#define eBX_reg 111 +#define eSP_reg 112 +#define eBP_reg 113 +#define eSI_reg 114 +#define eDI_reg 115 #define al_reg 116 #define cl_reg 117 @@ -245,28 +251,48 @@ static void ptr_reg PARAMS ((int, int)); #define indir_dx_reg 150 -#define GRP1b NULL, NULL, 0 -#define GRP1S NULL, NULL, 1 -#define GRP1Ss NULL, NULL, 2 -#define GRP2b NULL, NULL, 3 -#define GRP2S NULL, NULL, 4 -#define GRP2b_one NULL, NULL, 5 -#define GRP2S_one NULL, NULL, 6 -#define GRP2b_cl NULL, NULL, 7 -#define GRP2S_cl NULL, NULL, 8 -#define GRP3b NULL, NULL, 9 -#define GRP3S NULL, NULL, 10 -#define GRP4 NULL, NULL, 11 -#define GRP5 NULL, NULL, 12 -#define GRP6 NULL, NULL, 13 -#define GRP7 NULL, NULL, 14 -#define GRP8 NULL, NULL, 15 -#define GRP9 NULL, NULL, 16 -#define GRP10 NULL, NULL, 17 -#define GRP11 NULL, NULL, 18 -#define GRP12 NULL, NULL, 19 -#define GRP13 NULL, NULL, 20 -#define GRP14 NULL, NULL, 21 +#define USE_GROUPS 1 +#define USE_PREFIX_USER_TABLE 2 + +#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS +#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS +#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS +#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS +#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS +#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS +#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS +#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS +#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS +#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS +#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS +#define GRP4 NULL, NULL, 11, NULL, USE_GROUPS +#define GRP5 NULL, NULL, 12, NULL, USE_GROUPS +#define GRP6 NULL, NULL, 13, NULL, USE_GROUPS +#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS +#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS +#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS +#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS +#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS +#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS +#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS +#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS +#define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS + +#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE +#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE +#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE +#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE +#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE +#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE +#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE +#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE +#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE +#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE +#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE +#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE +#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE +#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE +#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE #define FLOATCODE 50 #define FLOAT NULL, NULL, FLOATCODE @@ -558,7 +584,7 @@ static struct dis386 dis386_att[] = { { "outB", Ib, AL }, { "outS", Ib, eAX }, /* e8 */ - { "callP", Av }, + { "callP", Jv }, { "jmpP", Jv }, { "ljmpP", Ap }, { "jmp", Jb }, @@ -588,131 +614,131 @@ static struct dis386 dis386_att[] = { static struct dis386 dis386_intel[] = { /* 00 */ - { "addB", Eb, Gb }, - { "addS", Ev, Gv }, - { "addB", Gb, Eb }, - { "addS", Gv, Ev }, - { "addB", AL, Ib }, - { "addS", eAX, Iv }, - { "pushP", es }, - { "popP", es }, + { "add", Eb, Gb }, + { "add", Ev, Gv }, + { "add", Gb, Eb }, + { "add", Gv, Ev }, + { "add", AL, Ib }, + { "add", eAX, Iv }, + { "push", es }, + { "pop", es }, /* 08 */ - { "orB", Eb, Gb }, - { "orS", Ev, Gv }, - { "orB", Gb, Eb }, - { "orS", Gv, Ev }, - { "orB", AL, Ib }, - { "orS", eAX, Iv }, - { "pushP", cs }, + { "or", Eb, Gb }, + { "or", Ev, Gv }, + { "or", Gb, Eb }, + { "or", Gv, Ev }, + { "or", AL, Ib }, + { "or", eAX, Iv }, + { "push", cs }, { "(bad)" }, /* 0x0f extended opcode escape */ /* 10 */ - { "adcB", Eb, Gb }, - { "adcS", Ev, Gv }, - { "adcB", Gb, Eb }, - { "adcS", Gv, Ev }, - { "adcB", AL, Ib }, - { "adcS", eAX, Iv }, - { "pushP", ss }, - { "popP", ss }, + { "adc", Eb, Gb }, + { "adc", Ev, Gv }, + { "adc", Gb, Eb }, + { "adc", Gv, Ev }, + { "adc", AL, Ib }, + { "adc", eAX, Iv }, + { "push", ss }, + { "pop", ss }, /* 18 */ - { "sbbB", Eb, Gb }, - { "sbbS", Ev, Gv }, - { "sbbB", Gb, Eb }, - { "sbbS", Gv, Ev }, - { "sbbB", AL, Ib }, - { "sbbS", eAX, Iv }, - { "pushP", ds }, - { "popP", ds }, + { "sbb", Eb, Gb }, + { "sbb", Ev, Gv }, + { "sbb", Gb, Eb }, + { "sbb", Gv, Ev }, + { "sbb", AL, Ib }, + { "sbb", eAX, Iv }, + { "push", ds }, + { "pop", ds }, /* 20 */ - { "andB", Eb, Gb }, - { "andS", Ev, Gv }, - { "andB", Gb, Eb }, - { "andS", Gv, Ev }, - { "andB", AL, Ib }, - { "andS", eAX, Iv }, + { "and", Eb, Gb }, + { "and", Ev, Gv }, + { "and", Gb, Eb }, + { "and", Gv, Ev }, + { "and", AL, Ib }, + { "and", eAX, Iv }, { "(bad)" }, /* SEG ES prefix */ { "daa" }, /* 28 */ - { "subB", Eb, Gb }, - { "subS", Ev, Gv }, - { "subB", Gb, Eb }, - { "subS", Gv, Ev }, - { "subB", AL, Ib }, - { "subS", eAX, Iv }, + { "sub", Eb, Gb }, + { "sub", Ev, Gv }, + { "sub", Gb, Eb }, + { "sub", Gv, Ev }, + { "sub", AL, Ib }, + { "sub", eAX, Iv }, { "(bad)" }, /* SEG CS prefix */ { "das" }, /* 30 */ - { "xorB", Eb, Gb }, - { "xorS", Ev, Gv }, - { "xorB", Gb, Eb }, - { "xorS", Gv, Ev }, - { "xorB", AL, Ib }, - { "xorS", eAX, Iv }, + { "xor", Eb, Gb }, + { "xor", Ev, Gv }, + { "xor", Gb, Eb }, + { "xor", Gv, Ev }, + { "xor", AL, Ib }, + { "xor", eAX, Iv }, { "(bad)" }, /* SEG SS prefix */ { "aaa" }, /* 38 */ - { "cmpB", Eb, Gb }, - { "cmpS", Ev, Gv }, - { "cmpB", Gb, Eb }, - { "cmpS", Gv, Ev }, - { "cmpB", AL, Ib }, - { "cmpS", eAX, Iv }, + { "cmp", Eb, Gb }, + { "cmp", Ev, Gv }, + { "cmp", Gb, Eb }, + { "cmp", Gv, Ev }, + { "cmp", AL, Ib }, + { "cmp", eAX, Iv }, { "(bad)" }, /* SEG DS prefix */ { "aas" }, /* 40 */ - { "incS", eAX }, - { "incS", eCX }, - { "incS", eDX }, - { "incS", eBX }, - { "incS", eSP }, - { "incS", eBP }, - { "incS", eSI }, - { "incS", eDI }, + { "inc", eAX }, + { "inc", eCX }, + { "inc", eDX }, + { "inc", eBX }, + { "inc", eSP }, + { "inc", eBP }, + { "inc", eSI }, + { "inc", eDI }, /* 48 */ - { "decS", eAX }, - { "decS", eCX }, - { "decS", eDX }, - { "decS", eBX }, - { "decS", eSP }, - { "decS", eBP }, - { "decS", eSI }, - { "decS", eDI }, + { "dec", eAX }, + { "dec", eCX }, + { "dec", eDX }, + { "dec", eBX }, + { "dec", eSP }, + { "dec", eBP }, + { "dec", eSI }, + { "dec", eDI }, /* 50 */ - { "pushS", eAX }, - { "pushS", eCX }, - { "pushS", eDX }, - { "pushS", eBX }, - { "pushS", eSP }, - { "pushS", eBP }, - { "pushS", eSI }, - { "pushS", eDI }, + { "push", eAX }, + { "push", eCX }, + { "push", eDX }, + { "push", eBX }, + { "push", eSP }, + { "push", eBP }, + { "push", eSI }, + { "push", eDI }, /* 58 */ - { "popS", eAX }, - { "popS", eCX }, - { "popS", eDX }, - { "popS", eBX }, - { "popS", eSP }, - { "popS", eBP }, - { "popS", eSI }, - { "popS", eDI }, + { "pop", eAX }, + { "pop", eCX }, + { "pop", eDX }, + { "pop", eBX }, + { "pop", eSP }, + { "pop", eBP }, + { "pop", eSI }, + { "pop", eDI }, /* 60 */ - { "pushaP" }, - { "popaP" }, - { "boundS", Gv, Ma }, + { "pusha" }, + { "popa" }, + { "bound", Gv, Ma }, { "arpl", Ew, Gw }, { "(bad)" }, /* seg fs */ { "(bad)" }, /* seg gs */ { "(bad)" }, /* op size prefix */ { "(bad)" }, /* adr size prefix */ /* 68 */ - { "pushP", Iv }, /* 386 book wrong */ - { "imulS", Gv, Ev, Iv }, - { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */ - { "imulS", Gv, Ev, sIb }, - { "insb", Yb, indirDX }, - { "insR", Yv, indirDX }, - { "outsb", indirDX, Xb }, - { "outsR", indirDX, Xv }, + { "push", Iv }, /* 386 book wrong */ + { "imul", Gv, Ev, Iv }, + { "push", sIb }, /* push of byte really pushes 2 or 4 bytes */ + { "imul", Gv, Ev, sIb }, + { "ins", Yb, indirDX }, + { "ins", Yv, indirDX }, + { "outs", indirDX, Xb }, + { "outs", indirDX, Xv }, /* 70 */ { "jo", Jb }, { "jno", Jb }, @@ -736,91 +762,91 @@ static struct dis386 dis386_intel[] = { { GRP1S }, { "(bad)" }, { GRP1Ss }, - { "testB", Eb, Gb }, - { "testS", Ev, Gv }, - { "xchgB", Eb, Gb }, - { "xchgS", Ev, Gv }, + { "test", Eb, Gb }, + { "test", Ev, Gv }, + { "xchg", Eb, Gb }, + { "xchg", Ev, Gv }, /* 88 */ - { "movB", Eb, Gb }, - { "movS", Ev, Gv }, - { "movB", Gb, Eb }, - { "movS", Gv, Ev }, - { "movQ", Ev, Sw }, - { "leaS", Gv, M }, - { "movQ", Sw, Ev }, - { "popQ", Ev }, + { "mov", Eb, Gb }, + { "mov", Ev, Gv }, + { "mov", Gb, Eb }, + { "mov", Gv, Ev }, + { "mov", Ev, Sw }, + { "lea", Gv, M }, + { "mov", Sw, Ev }, + { "pop", Ev }, /* 90 */ { "nop" }, - { "xchgS", eCX, eAX }, - { "xchgS", eDX, eAX }, - { "xchgS", eBX, eAX }, - { "xchgS", eSP, eAX }, - { "xchgS", eBP, eAX }, - { "xchgS", eSI, eAX }, - { "xchgS", eDI, eAX }, + { "xchg", eCX, eAX }, + { "xchg", eDX, eAX }, + { "xchg", eBX, eAX }, + { "xchg", eSP, eAX }, + { "xchg", eBP, eAX }, + { "xchg", eSI, eAX }, + { "xchg", eDI, eAX }, /* 98 */ - { "cWtR" }, - { "cRtd" }, - { "lcallP", Ap }, + { "cW" }, /* cwde and cbw */ + { "cR" }, /* cdq and cwd */ + { "lcall", Ap }, { "(bad)" }, /* fwait */ - { "pushfP" }, - { "popfP" }, + { "pushf" }, + { "popf" }, { "sahf" }, { "lahf" }, /* a0 */ - { "movB", AL, Ob }, - { "movS", eAX, Ov }, - { "movB", Ob, AL }, - { "movS", Ov, eAX }, - { "movsb", Yb, Xb }, - { "movsR", Yv, Xv }, - { "cmpsb", Xb, Yb }, - { "cmpsR", Xv, Yv }, + { "mov", AL, Ob }, + { "mov", eAX, Ov }, + { "mov", Ob, AL }, + { "mov", Ov, eAX }, + { "movs", Yb, Xb }, + { "movs", Yv, Xv }, + { "cmps", Xb, Yb }, + { "cmps", Xv, Yv }, /* a8 */ - { "testB", AL, Ib }, - { "testS", eAX, Iv }, - { "stosB", Yb, AL }, - { "stosS", Yv, eAX }, - { "lodsB", AL, Xb }, - { "lodsS", eAX, Xv }, - { "scasB", AL, Yb }, - { "scasS", eAX, Yv }, + { "test", AL, Ib }, + { "test", eAX, Iv }, + { "stos", Yb, AL }, + { "stos", Yv, eAX }, + { "lods", AL, Xb }, + { "lods", eAX, Xv }, + { "scas", AL, Yb }, + { "scas", eAX, Yv }, /* b0 */ - { "movB", AL, Ib }, - { "movB", CL, Ib }, - { "movB", DL, Ib }, - { "movB", BL, Ib }, - { "movB", AH, Ib }, - { "movB", CH, Ib }, - { "movB", DH, Ib }, - { "movB", BH, Ib }, + { "mov", AL, Ib }, + { "mov", CL, Ib }, + { "mov", DL, Ib }, + { "mov", BL, Ib }, + { "mov", AH, Ib }, + { "mov", CH, Ib }, + { "mov", DH, Ib }, + { "mov", BH, Ib }, /* b8 */ - { "movS", eAX, Iv }, - { "movS", eCX, Iv }, - { "movS", eDX, Iv }, - { "movS", eBX, Iv }, - { "movS", eSP, Iv }, - { "movS", eBP, Iv }, - { "movS", eSI, Iv }, - { "movS", eDI, Iv }, + { "mov", eAX, Iv }, + { "mov", eCX, Iv }, + { "mov", eDX, Iv }, + { "mov", eBX, Iv }, + { "mov", eSP, Iv }, + { "mov", eBP, Iv }, + { "mov", eSI, Iv }, + { "mov", eDI, Iv }, /* c0 */ { GRP2b }, { GRP2S }, - { "retP", Iw }, - { "retP" }, - { "lesS", Gv, Mp }, - { "ldsS", Gv, Mp }, - { "movA", Eb, Ib }, - { "movQ", Ev, Iv }, + { "ret", Iw }, + { "ret" }, + { "les", Gv, Mp }, + { "lds", Gv, Mp }, + { "mov", Eb, Ib }, + { "mov", Ev, Iv }, /* c8 */ - { "enterP", Iw, Ib }, - { "leaveP" }, - { "lretP", Iw }, - { "lretP" }, + { "enter", Iw, Ib }, + { "leave" }, + { "lret", Iw }, + { "lret" }, { "int3" }, { "int", Ib }, { "into" }, - { "iretP" }, + { "iret" }, /* d0 */ { GRP2b_one }, { GRP2S_one }, @@ -844,19 +870,19 @@ static struct dis386 dis386_intel[] = { { "loope", Jb }, { "loop", Jb }, { "jEcxz", Jb }, - { "inB", AL, Ib }, - { "inS", eAX, Ib }, - { "outB", Ib, AL }, - { "outS", Ib, eAX }, + { "in", AL, Ib }, + { "in", eAX, Ib }, + { "out", Ib, AL }, + { "out", Ib, eAX }, /* e8 */ - { "callP", Av }, - { "jmpP", Jv }, - { "ljmpP", Ap }, + { "call", Jv }, + { "jmp", Jv }, + { "ljmp", Ap }, { "jmp", Jb }, - { "inB", AL, indirDX }, - { "inS", eAX, indirDX }, - { "outB", indirDX, AL }, - { "outS", indirDX, eAX }, + { "in", AL, indirDX }, + { "in", eAX, indirDX }, + { "out", indirDX, AL }, + { "out", indirDX, eAX }, /* f0 */ { "(bad)" }, /* lock prefix */ { "(bad)" }, @@ -893,14 +919,21 @@ static struct dis386 dis386_twobyte_att[] = { { "(bad)" }, { "ud2a" }, { "(bad)" }, - { GRP14 }, + { GRPAMD }, { "femms" }, { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */ /* 10 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP8 }, + { PREGRP9 }, + { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlps", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklps", XM, EX }, + { "unpckhps", XM, EX }, + { "movhps", XM, EX, SIMD_Fixup, 'l' }, + { "movhps", EX, XM, SIMD_Fixup, 'l' }, /* 18 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { GRP14 }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 20 */ /* these are all backward in appendix A of the intel book */ @@ -913,8 +946,14 @@ static struct dis386 dis386_twobyte_att[] = { { "movL", Td, Rd }, { "(bad)" }, /* 28 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movaps", XM, EX }, + { "movaps", EX, XM }, + { PREGRP2 }, + { "movntps", Ev, XM }, + { PREGRP4 }, + { PREGRP3 }, + { "ucomiss", XM, EX }, + { "comiss", XM, EX }, /* 30 */ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" }, @@ -928,11 +967,23 @@ static struct dis386 dis386_twobyte_att[] = { { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev }, { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev }, /* 50 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movmskps", Gv, EX }, + { PREGRP13 }, + { PREGRP12 }, + { PREGRP11 }, + { "andps", XM, EX }, + { "andnps", XM, EX }, + { "orps", XM, EX }, + { "xorps", XM, EX }, /* 58 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP0 }, + { PREGRP10 }, + { "(bad)" }, + { "(bad)" }, + { PREGRP14 }, + { PREGRP7 }, + { PREGRP5 }, + { PREGRP6 }, /* 60 */ { "punpcklbw", MX, EM }, { "punpcklwd", MX, EM }, @@ -951,7 +1002,7 @@ static struct dis386 dis386_twobyte_att[] = { { "movd", MX, Ev }, { "movq", MX, EM }, /* 70 */ - { "(bad)" }, + { "pshufw", MX, EM, Ib }, { GRP10 }, { GRP11 }, { GRP12 }, @@ -1039,11 +1090,11 @@ static struct dis386 dis386_twobyte_att[] = { /* c0 */ { "xaddB", Eb, Gb }, { "xaddS", Ev, Gv }, + { PREGRP1 }, { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, + { "pinsrw", MX, Ev, Ib }, + { "pextrw", Ev, MX, Ib }, + { "shufps", XM, EX, Ib }, { GRP9 }, /* c8 */ { "bswap", eAX }, /* bswap doesn't support 16 bit regs */ @@ -1061,32 +1112,34 @@ static struct dis386 dis386_twobyte_att[] = { { "psrlq", MX, EM }, { "(bad)" }, { "pmullw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "pmovmskb", Ev, MX }, /* d8 */ { "psubusb", MX, EM }, { "psubusw", MX, EM }, - { "(bad)" }, + { "pminub", MX, EM }, { "pand", MX, EM }, { "paddusb", MX, EM }, { "paddusw", MX, EM }, - { "(bad)" }, + { "pmaxub", MX, EM }, { "pandn", MX, EM }, /* e0 */ - { "(bad)" }, + { "pavgb", MX, EM }, { "psraw", MX, EM }, { "psrad", MX, EM }, - { "(bad)" }, - { "(bad)" }, + { "pavgw", MX, EM }, + { "pmulhuw", MX, EM }, { "pmulhw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "movntq", Ev, MX }, /* e8 */ { "psubsb", MX, EM }, { "psubsw", MX, EM }, - { "(bad)" }, + { "pminsw", MX, EM }, { "por", MX, EM }, { "paddsb", MX, EM }, { "paddsw", MX, EM }, - { "(bad)" }, + { "pmaxsw", MX, EM }, { "pxor", MX, EM }, /* f0 */ { "(bad)" }, @@ -1095,7 +1148,8 @@ static struct dis386 dis386_twobyte_att[] = { { "psllq", MX, EM }, { "(bad)" }, { "pmaddwd", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "psadbw", MX, EM }, + { "maskmovq", MX, EM }, /* f8 */ { "psubb", MX, EM }, { "psubw", MX, EM }, @@ -1111,8 +1165,8 @@ static struct dis386 dis386_twobyte_intel[] = { /* 00 */ { GRP6 }, { GRP7 }, - { "larS", Gv, Ew }, - { "lslS", Gv, Ew }, + { "lar", Gv, Ew }, + { "lsl", Gv, Ew }, { "(bad)" }, { "(bad)" }, { "clts" }, @@ -1123,28 +1177,41 @@ static struct dis386 dis386_twobyte_intel[] = { { "(bad)" }, { "ud2a" }, { "(bad)" }, - { GRP14 }, + { GRPAMD }, { "femms" }, { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */ /* 10 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP8 }, + { PREGRP9 }, + { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlps", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklps", XM, EX }, + { "unpckhps", XM, EX }, + { "movhps", XM, EX, SIMD_Fixup, 'l' }, + { "movhps", EX, XM, SIMD_Fixup, 'l' }, /* 18 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { GRP14 }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 20 */ /* these are all backward in appendix A of the intel book */ - { "movL", Rd, Cd }, - { "movL", Rd, Dd }, - { "movL", Cd, Rd }, - { "movL", Dd, Rd }, - { "movL", Rd, Td }, + { "mov", Rd, Cd }, + { "mov", Rd, Dd }, + { "mov", Cd, Rd }, + { "mov", Dd, Rd }, + { "mov", Rd, Td }, { "(bad)" }, - { "movL", Td, Rd }, + { "mov", Td, Rd }, { "(bad)" }, /* 28 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movaps", XM, EX }, + { "movaps", EX, XM }, + { PREGRP2 }, + { "movntps", Ev, XM }, + { PREGRP4 }, + { PREGRP3 }, + { "ucomiss", XM, EX }, + { "comiss", XM, EX }, /* 30 */ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" }, @@ -1158,11 +1225,23 @@ static struct dis386 dis386_twobyte_intel[] = { { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev }, { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev }, /* 50 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movmskps", Gv, EX }, + { PREGRP13 }, + { PREGRP12 }, + { PREGRP11 }, + { "andps", XM, EX }, + { "andnps", XM, EX }, + { "orps", XM, EX }, + { "xorps", XM, EX }, /* 58 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP0 }, + { PREGRP10 }, + { "(bad)" }, + { "(bad)" }, + { PREGRP14 }, + { PREGRP7 }, + { PREGRP5 }, + { PREGRP6 }, /* 60 */ { "punpcklbw", MX, EM }, { "punpcklwd", MX, EM }, @@ -1181,7 +1260,7 @@ static struct dis386 dis386_twobyte_intel[] = { { "movd", MX, Ev }, { "movq", MX, EM }, /* 70 */ - { "(bad)" }, + { "pshufw", MX, EM, Ib }, { GRP10 }, { GRP11 }, { GRP12 }, @@ -1231,49 +1310,49 @@ static struct dis386 dis386_twobyte_intel[] = { { "setle", Eb }, { "setg", Eb }, /* a0 */ - { "pushP", fs }, - { "popP", fs }, + { "push", fs }, + { "pop", fs }, { "cpuid" }, - { "btS", Ev, Gv }, - { "shldS", Ev, Gv, Ib }, - { "shldS", Ev, Gv, CL }, + { "bt", Ev, Gv }, + { "shld", Ev, Gv, Ib }, + { "shld", Ev, Gv, CL }, { "(bad)" }, { "(bad)" }, /* a8 */ - { "pushP", gs }, - { "popP", gs }, + { "push", gs }, + { "pop", gs }, { "rsm" }, - { "btsS", Ev, Gv }, - { "shrdS", Ev, Gv, Ib }, - { "shrdS", Ev, Gv, CL }, + { "bts", Ev, Gv }, + { "shrd", Ev, Gv, Ib }, + { "shrd", Ev, Gv, CL }, { GRP13 }, - { "imulS", Gv, Ev }, + { "imul", Gv, Ev }, /* b0 */ - { "cmpxchgB", Eb, Gb }, - { "cmpxchgS", Ev, Gv }, - { "lssS", Gv, Mp }, /* 386 lists only Mp */ - { "btrS", Ev, Gv }, - { "lfsS", Gv, Mp }, /* 386 lists only Mp */ - { "lgsS", Gv, Mp }, /* 386 lists only Mp */ + { "cmpxchg", Eb, Gb }, + { "cmpxchg", Ev, Gv }, + { "lss", Gv, Mp }, /* 386 lists only Mp */ + { "btr", Ev, Gv }, + { "lfs", Gv, Mp }, /* 386 lists only Mp */ + { "lgs", Gv, Mp }, /* 386 lists only Mp */ { "movzx", Gv, Eb }, { "movzx", Gv, Ew }, /* b8 */ { "(bad)" }, { "ud2b" }, { GRP8 }, - { "btcS", Ev, Gv }, - { "bsfS", Gv, Ev }, - { "bsrS", Gv, Ev }, + { "btc", Ev, Gv }, + { "bsf", Gv, Ev }, + { "bsr", Gv, Ev }, { "movsx", Gv, Eb }, { "movsx", Gv, Ew }, /* c0 */ - { "xaddB", Eb, Gb }, - { "xaddS", Ev, Gv }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, + { "xadd", Eb, Gb }, + { "xadd", Ev, Gv }, + { PREGRP1 }, { "(bad)" }, + { "pinsrw", MX, Ev, Ib }, + { "pextrw", Ev, MX, Ib }, + { "shufps", XM, EX, Ib }, { GRP9 }, /* c8 */ { "bswap", eAX }, /* bswap doesn't support 16 bit regs */ @@ -1291,32 +1370,34 @@ static struct dis386 dis386_twobyte_intel[] = { { "psrlq", MX, EM }, { "(bad)" }, { "pmullw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "pmovmskb", Ev, MX }, /* d8 */ { "psubusb", MX, EM }, { "psubusw", MX, EM }, - { "(bad)" }, + { "pminub", MX, EM }, { "pand", MX, EM }, { "paddusb", MX, EM }, { "paddusw", MX, EM }, - { "(bad)" }, + { "pmaxub", MX, EM }, { "pandn", MX, EM }, /* e0 */ - { "(bad)" }, + { "pavgb", MX, EM }, { "psraw", MX, EM }, { "psrad", MX, EM }, - { "(bad)" }, - { "(bad)" }, + { "pavgw", MX, EM }, + { "pmulhuw", MX, EM }, { "pmulhw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "movntq", Ev, MX }, /* e8 */ { "psubsb", MX, EM }, { "psubsw", MX, EM }, - { "(bad)" }, + { "pminsw", MX, EM }, { "por", MX, EM }, { "paddsb", MX, EM }, { "paddsw", MX, EM }, - { "(bad)" }, + { "pmaxsw", MX, EM }, { "pxor", MX, EM }, /* f0 */ { "(bad)" }, @@ -1325,7 +1406,8 @@ static struct dis386 dis386_twobyte_intel[] = { { "psllq", MX, EM }, { "(bad)" }, { "pmaddwd", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "psadbw", MX, EM }, + { "maskmovq", MX, EM }, /* f8 */ { "psubb", MX, EM }, { "psubw", MX, EM }, @@ -1338,41 +1420,72 @@ static struct dis386 dis386_twobyte_intel[] = { }; static const unsigned char onebyte_has_modrm[256] = { - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, - 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ }; static const unsigned char twobyte_has_modrm[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ - /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */ - /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */ + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ + /* 20 */ 1,1,1,1,1,1,1,1,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 */ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ - /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */ + /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */ - /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */ + /* 70 */ 1,1,1,1,1,1,1,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 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ - /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */ - /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */ - /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */ + /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */ + /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */ + /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +}; + +static const unsigned char twobyte_uses_f3_prefix[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ + /* 10 */ 1,1,0,0,0,0,0,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 */ + /* 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,0,0,1,1,1,1, /* 5f */ + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */ + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */ + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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 */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ }; static char obuf[100]; @@ -1628,14 +1741,25 @@ static struct dis386 grps[][8] = { { { "fxsave", Ev }, { "fxrstor", Ev }, + { "ldmxcsr", Ev }, + { "stmxcsr", Ev }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "sfence", None }, + }, + /* GRP14 */ + { + { "prefetchnta", Ev }, + { "prefetcht0", Ev }, + { "prefetcht1", Ev }, + { "prefetcht2", Ev }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, }, - /* GRP14 */ + /* GRPAMD */ { { "prefetch", Eb }, { "prefetchw", Eb }, @@ -1649,6 +1773,86 @@ static struct dis386 grps[][8] = { }; +static struct dis386 prefix_user_table[][2] = { + /* PREGRP0 */ + { + { "addps", XM, EX }, + { "addss", XM, EX }, + }, + /* PREGRP1 */ + { + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */ + { "", XM, EX, OPSIMD }, + }, + /* PREGRP2 */ + { + { "cvtpi2ps", XM, EM }, + { "cvtsi2ss", XM, Ev }, + }, + /* PREGRP3 */ + { + { "cvtps2pi", MX, EX }, + { "cvtss2si", Gv, EX }, + }, + /* PREGRP4 */ + { + { "cvttps2pi", MX, EX }, + { "cvttss2si", Gv, EX }, + }, + /* PREGRP5 */ + { + { "divps", XM, EX }, + { "divss", XM, EX }, + }, + /* PREGRP6 */ + { + { "maxps", XM, EX }, + { "maxss", XM, EX }, + }, + /* PREGRP7 */ + { + { "minps", XM, EX }, + { "minss", XM, EX }, + }, + /* PREGRP8 */ + { + { "movups", XM, EX }, + { "movss", XM, EX }, + }, + /* PREGRP9 */ + { + { "movups", EX, XM }, + { "movss", EX, XM }, + }, + /* PREGRP10 */ + { + { "mulps", XM, EX }, + { "mulss", XM, EX }, + }, + /* PREGRP11 */ + { + { "rcpps", XM, EX }, + { "rcpss", XM, EX }, + }, + /* PREGRP12 */ + { + { "rsqrtps", XM, EX }, + { "rsqrtss", XM, EX }, + }, + /* PREGRP13 */ + { + { "sqrtps", XM, EX }, + { "sqrtss", XM, EX }, + }, + /* PREGRP14 */ + { + { "subps", XM, EX }, + { "subss", XM, EX }, + } +}; + +#define INTERNAL_DISASSEMBLER_ERROR _("") + #define PREFIX_REPZ 1 #define PREFIX_REPNZ 2 #define PREFIX_LOCK 4 @@ -1807,13 +2011,14 @@ print_insn_x86 (pc, info, sizeflag) char *first, *second, *third; int needcomma; unsigned char need_modrm; + unsigned char uses_f3_prefix; struct dis_private priv; bfd_byte *inbuf = priv.the_buffer; - /* The output looks better if we put 5 bytes on a line, since that - puts long word instructions on a single line. */ - info->bytes_per_line = 5; + /* The output looks better if we put 6 bytes on a line, since that + puts most long word instructions on a single line. */ + info->bytes_per_line = 6; info->private_data = (PTR) &priv; priv.max_fetched = priv.the_buffer; @@ -1852,25 +2057,6 @@ print_insn_x86 (pc, info, sizeflag) return codep - inbuf; } - if (prefixes & PREFIX_REPZ) - oappend ("repz "); - if (prefixes & PREFIX_REPNZ) - oappend ("repnz "); - if (prefixes & PREFIX_LOCK) - oappend ("lock "); - - if (prefixes & PREFIX_DATA) - sizeflag ^= DFLAG; - - if (prefixes & PREFIX_ADDR) - { - sizeflag ^= AFLAG; - if (sizeflag & AFLAG) - oappend ("addr32 "); - else - oappend ("addr16 "); - } - if (*codep == 0x0f) { FETCH_DATA (info, codep + 2); @@ -1879,6 +2065,7 @@ print_insn_x86 (pc, info, sizeflag) else dp = &dis386_twobyte_att[*++codep]; need_modrm = twobyte_has_modrm[*codep]; + uses_f3_prefix = twobyte_uses_f3_prefix[*codep]; } else { @@ -1887,9 +2074,29 @@ print_insn_x86 (pc, info, sizeflag) else dp = &dis386_att[*codep]; need_modrm = onebyte_has_modrm[*codep]; + uses_f3_prefix = 0; } codep++; + if (!uses_f3_prefix && (prefixes & PREFIX_REPZ)) + oappend ("repz "); + if (prefixes & PREFIX_REPNZ) + oappend ("repnz "); + if (prefixes & PREFIX_LOCK) + oappend ("lock "); + + if (prefixes & PREFIX_DATA) + sizeflag ^= DFLAG; + + if (prefixes & PREFIX_ADDR) + { + sizeflag ^= AFLAG; + if (sizeflag & AFLAG) + oappend ("addr32 "); + else + oappend ("addr16 "); + } + if (need_modrm) { FETCH_DATA (info, codep + 1); @@ -1905,7 +2112,20 @@ print_insn_x86 (pc, info, sizeflag) else { if (dp->name == NULL) - dp = &grps[dp->bytemode1][reg]; + { + switch(dp->bytemode2) + { + case USE_GROUPS: + dp = &grps[dp->bytemode1][reg]; + break; + case USE_PREFIX_USER_TABLE: + dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0]; + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } + } putop (dp->name, sizeflag); @@ -2445,11 +2665,25 @@ putop (template, sizeflag) break; case 'R': if (intel_syntax) - break; - if (sizeflag & DFLAG) - *obufp++ = 'l'; + { + if (sizeflag & DFLAG) + { + *obufp++ = 'd'; + *obufp++ = 'q'; + } + else + { + *obufp++ = 'w'; + *obufp++ = 'd'; + } + } else - *obufp++ = 'w'; + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + } break; case 'S': if (intel_syntax) @@ -2465,13 +2699,23 @@ putop (template, sizeflag) #endif break; case 'W': - if (intel_syntax) - break; /* operand size flag for cwtl, cbtw */ if (sizeflag & DFLAG) *obufp++ = 'w'; else *obufp++ = 'b'; + if (intel_syntax) + { + if (sizeflag & DFLAG) + { + *obufp++ = 'd'; + *obufp++ = 'e'; + } + else + { + *obufp++ = 'w'; + } + } break; } } @@ -2539,8 +2783,10 @@ OP_E (bytemode, sizeflag) else oappend (names16[rm]); break; + case 0: /* sfence */ + break; default: - oappend (""); + oappend (INTERNAL_DISASSEMBLER_ERROR); break; } return; @@ -2735,8 +2981,6 @@ OP_E (bytemode, sizeflag) } } -#define INTERNAL_DISASSEMBLER_ERROR _("") - static void OP_G (bytemode, sizeflag) int bytemode; @@ -2962,48 +3206,26 @@ OP_SEG (dummy, sizeflag) oappend (sreg[reg]); } +/* ARGSUSED */ static void -OP_DIR (size, sizeflag) - int size; +OP_DIR (dummy, sizeflag) + int dummy; int sizeflag; { int seg, offset; - switch (size) + if (sizeflag & DFLAG) { - case lptr: - if (sizeflag & DFLAG) - { - offset = get32 (); - seg = get16 (); - } - else - { - offset = get16 (); - seg = get16 (); - } - sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); - oappend (scratchbuf); - break; - case v_mode: - if (sizeflag & DFLAG) - offset = get32 (); - else - { - offset = get16 (); - if ((offset & 0x8000) != 0) - offset -= 0x10000; - } - - offset = start_pc + codep - start_codep + offset; - set_op (offset); - sprintf (scratchbuf, "0x%x", offset); - oappend (scratchbuf); - break; - default: - oappend (INTERNAL_DISASSEMBLER_ERROR); - break; + offset = get32 (); + seg = get16 (); } + else + { + offset = get16 (); + seg = get16 (); + } + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); + oappend (scratchbuf); } /* ARGSUSED */ @@ -3147,6 +3369,15 @@ OP_MMX (ignore, sizeflag) oappend (scratchbuf); } +static void +OP_XMM (bytemode, sizeflag) + int bytemode; + int sizeflag; +{ + sprintf (scratchbuf, "%%xmm%d", reg); + oappend (scratchbuf); +} + static void OP_EM (bytemode, sizeflag) int bytemode; @@ -3163,6 +3394,22 @@ OP_EM (bytemode, sizeflag) oappend (scratchbuf); } +static void +OP_EX (bytemode, sizeflag) + int bytemode; + int sizeflag; +{ + if (mod != 3) + { + OP_E (bytemode, sizeflag); + return; + } + + codep++; + sprintf (scratchbuf, "%%xmm%d", rm); + oappend (scratchbuf); +} + static void OP_MS (ignore, sizeflag) int ignore; @@ -3251,7 +3498,7 @@ OP_3DNowSuffix (bytemode, sizeflag) /* AMD 3DNow! instructions are specified by an opcode suffix in the place where an 8-bit immediate would normally go. ie. the last byte of the instruction. */ - mnemonic = Suffix3DNow[*codep++]; + mnemonic = Suffix3DNow[*codep++ & 0xff]; if (mnemonic) strcat (obuf, mnemonic); else @@ -3266,3 +3513,59 @@ OP_3DNowSuffix (bytemode, sizeflag) strcat (obuf, "(bad)"); } } + + +static const char *simd_cmp_op [] = { + "eq", + "lt", + "le", + "unord", + "neq", + "nlt", + "nle", + "ord" +}; + +static void +OP_SIMD_Suffix (bytemode, sizeflag) + int bytemode; + int sizeflag; +{ + unsigned int cmp_type; + + FETCH_DATA (the_info, codep + 1); + cmp_type = *codep++ & 0xff; + if (cmp_type < 8) + { + sprintf (scratchbuf, "cmp%s%cs", + simd_cmp_op[cmp_type], + prefixes & PREFIX_REPZ ? 's' : 'p'); + strcat (obuf, scratchbuf); + } + else + { + /* We have a bad extension byte. Clean up. */ + op1out[0] = 0; + op2out[0] = 0; + codep = insn_codep + 1; + strcat (obuf, "(bad)"); + } +} + +static void +SIMD_Fixup (extrachar, sizeflag) + int extrachar; + int sizeflag; +{ + /* Change movlps/movhps to movhlps/movlhps for 2 register operand + forms of these instructions. */ + if (mod == 3) + { + char *p = obuf + strlen(obuf); + *(p+1) = '\0'; + *p = *(p-1); + *(p-1) = *(p-2); + *(p-2) = *(p-3); + *(p-3) = extrachar; + } +} -- 2.30.2