diff options
-rw-r--r-- | opcodes/ChangeLog | 17 | ||||
-rw-r--r-- | opcodes/i386-dis.c | 361 |
2 files changed, 288 insertions, 90 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 0f5fecf..688049c 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,20 @@ +Wed Jan 10 15:13:21 MET 2001 Jan Hubicka <jh@suse.cz> + + * i386-dis.c (PREGRP15 - PREGRP24): New. + (dis386_twobyt): Add SSE2 instructions. + (twobyte_uses_SSE_prefix: Rename from ... ; add new SSE instructions. + (twobyte_uses_f3_prefix): ... this one. + (grps): Add SSE instructions. + (prefix_user_table): Add two new slots; add SSE2 instructions. + (print_insn_i386): Rename uses_f3_prefix to uses_SSE_prefix; + Handle the REPNZ and Data16 prefixes as well; do proper lookup + to prefix_user_table. + (OP_E): Accept mfence and lfence as well. + (OP_MMX): Data16 prefix turns MMX to SSE; support REX extensions. + (OP_XMM): Support REX extensions. + (OP_EM): Likewise. + (OP_EX): Likewise. + 2001-01-09 Nick Clifton <nickc@redhat.com> * arm-dis.c (print_insn): Set pc to zero for instructions with diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 0f44de8..ca9c39d 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -398,6 +398,16 @@ static void BadOp PARAMS ((void)); #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP15 NULL, NULL, 15, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP16 NULL, NULL, 16, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP17 NULL, NULL, 17, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP18 NULL, NULL, 18, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP19 NULL, NULL, 19, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP20 NULL, NULL, 20, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP21 NULL, NULL, 21, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP22 NULL, NULL, 22, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP23 NULL, NULL, 23, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP24 NULL, NULL, 24, NULL, USE_PREFIX_USER_TABLE, NULL, 0 #define FLOATCODE 50 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 @@ -426,6 +436,7 @@ struct dis386 { 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode) 'S' => print 'w', 'l' or 'q' if suffix_always is true + 'X' => print 's', 'd' depending on data16 prefix (for XMM) 'W' => print 'b' or 'w' ("w" or "de" in intel mode) */ @@ -594,6 +605,7 @@ static const struct dis386 dis386_att[] = { { "popQ", Ev, XX, XX }, /* 90 */ { "nop", XX, XX, XX }, + /* FIXME: NOP with REPz prefix is called PAUSE. */ { "xchgS", RMeCX, eAX, XX }, { "xchgS", RMeDX, eAX, XX }, { "xchgS", RMeBX, eAX, XX }, @@ -885,6 +897,7 @@ static const struct dis386 dis386_intel[] = { { "pop", Ev, XX, XX }, /* 90 */ { "nop", XX, XX, XX }, + /* FIXME: NOP with REPz prefix is called PAUSE. */ { "xchg", RMeCX, eAX, XX }, { "xchg", RMeDX, eAX, XX }, { "xchg", RMeBX, eAX, XX }, @@ -1178,6 +1191,7 @@ static const struct dis386 disx86_64_att[] = { { "popI", Ev, XX, XX }, /* 90 */ { "nop", XX, XX, XX }, + /* FIXME: NOP with REPz prefix is called PAUSE. */ { "xchgS", RMeCX, eAX, XX }, { "xchgS", RMeDX, eAX, XX }, { "xchgS", RMeBX, eAX, XX }, @@ -1255,7 +1269,7 @@ static const struct dis386 disx86_64_att[] = { { GRP2S_cl }, { "(bad)", XX, XX, XX }, /* reserved. */ { "(bad)", XX, XX, XX }, /* reserved. */ - { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, /* reserved. */ { "xlat", DSBX, XX, XX }, /* d8 */ { FLOAT }, @@ -1469,6 +1483,7 @@ static const struct dis386 dis386_64_intel[] = { { "pop", Ev, XX, XX }, /* 90 */ { "nop", XX, XX, XX }, + /* FIXME: NOP with REPz prefix is called PAUSE. */ { "xchg", RMeCX, eAX, XX }, { "xchg", RMeDX, eAX, XX }, { "xchg", RMeBX, eAX, XX }, @@ -1546,7 +1561,7 @@ static const struct dis386 dis386_64_intel[] = { { GRP2S_cl }, { "(bad)", XX, XX, XX }, /* Reserved. */ { "(bad)", XX, XX, XX }, /* Reserved. */ - { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, /* Reserved. */ { "xlat", DSBX, XX, XX }, /* d8 */ { FLOAT }, @@ -1617,12 +1632,12 @@ static const struct dis386 dis386_twobyte_att[] = { /* 10 */ { PREGRP8 }, { PREGRP9 }, - { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ - { "movlps", EX, XM, SIMD_Fixup, 'h' }, - { "unpcklps", XM, EX, XX }, - { "unpckhps", XM, EX, XX }, - { "movhps", XM, EX, SIMD_Fixup, 'l' }, - { "movhps", EX, XM, SIMD_Fixup, 'l' }, + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlpX", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklpX", XM, EX, XX }, + { "unpckhpX", XM, EX, XX }, + { "movhpX", XM, EX, SIMD_Fixup, 'l' }, + { "movhpX", EX, XM, SIMD_Fixup, 'l' }, /* 18 */ { GRP14 }, { "(bad)", XX, XX, XX }, @@ -1643,14 +1658,14 @@ static const struct dis386 dis386_twobyte_att[] = { { "movL", Td, Rd, XX }, { "(bad)", XX, XX, XX }, /* 28 */ - { "movaps", XM, EX, XX }, - { "movaps", EX, XM, XX }, + { "movapX", XM, EX, XX }, + { "movapX", EX, XM, XX }, { PREGRP2 }, - { "movntps", Ev, XM, XX }, + { "movntpX", Ev, XM, XX }, { PREGRP4 }, { PREGRP3 }, - { "ucomiss", XM, EX, XX }, - { "comiss", XM, EX, XX }, + { "ucomisX", XM,EX, XX }, + { "comisX", XM,EX, XX }, /* 30 */ { "wrmsr", XX, XX, XX }, { "rdtsc", XX, XX, XX }, @@ -1688,19 +1703,19 @@ static const struct dis386 dis386_twobyte_att[] = { { "cmovle", Gv, Ev, XX }, { "cmovg", Gv, Ev, XX }, /* 50 */ - { "movmskps", Gv, EX, XX }, + { "movmskpX", Gv, EX, XX }, { PREGRP13 }, { PREGRP12 }, { PREGRP11 }, - { "andps", XM, EX, XX }, - { "andnps", XM, EX, XX }, - { "orps", XM, EX, XX }, - { "xorps", XM, EX, XX }, + { "andpX", XM, EX, XX }, + { "andnpX", XM, EX, XX }, + { "orpX", XM, EX, XX }, + { "xorpX", XM, EX, XX }, /* 58 */ { PREGRP0 }, { PREGRP10 }, - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP17 }, + { PREGRP16 }, { PREGRP14 }, { PREGRP7 }, { PREGRP5 }, @@ -1720,11 +1735,11 @@ static const struct dis386 dis386_twobyte_att[] = { { "punpckhdq", MX, EM, XX }, { "packssdw", MX, EM, XX }, { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP24 }, { "movd", MX, Ed, XX }, - { "movq", MX, EM, XX }, + { PREGRP19 }, /* 70 */ - { "pshufw", MX, EM, Ib }, + { PREGRP22 }, { GRP10 }, { GRP11 }, { GRP12 }, @@ -1739,8 +1754,8 @@ static const struct dis386 dis386_twobyte_att[] = { { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, - { "movd", Ed, MX, XX }, - { "movq", EM, MX, XX }, + { PREGRP23 }, + { PREGRP20 }, /* 80 */ { "jo", Jv, XX, XX }, { "jno", Jv, XX, XX }, @@ -1817,10 +1832,10 @@ static const struct dis386 dis386_twobyte_att[] = { { "xaddB", Eb, Gb, XX }, { "xaddS", Ev, Gv, XX }, { PREGRP1 }, - { "(bad)", XX, XX, XX }, + { "movntiS", Ev, Gv, XX }, { "pinsrw", MX, Ev, Ib }, { "pextrw", Ev, MX, Ib }, - { "shufps", XM, EX, Ib }, + { "shufpX", XM, EX, Ib }, { GRP9 }, /* c8 */ { "bswap", RMeAX, XX, XX }, /* bswap doesn't support 16 bit regs */ @@ -1838,7 +1853,7 @@ static const struct dis386 dis386_twobyte_att[] = { { "psrlq", MX, EM, XX }, { "(bad)", XX, XX, XX }, { "pmullw", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP21 }, { "pmovmskb", Ev, MX, XX }, /* d8 */ { "psubusb", MX, EM, XX }, @@ -1856,7 +1871,7 @@ static const struct dis386 dis386_twobyte_att[] = { { "pavgw", MX, EM, XX }, { "pmulhuw", MX, EM, XX }, { "pmulhw", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP15 }, { "movntq", Ev, MX, XX }, /* e8 */ { "psubsb", MX, EM, XX }, @@ -1872,10 +1887,10 @@ static const struct dis386 dis386_twobyte_att[] = { { "psllw", MX, EM, XX }, { "pslld", MX, EM, XX }, { "psllq", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { "pmuludq", MX, EM, XX }, { "pmaddwd", MX, EM, XX }, { "psadbw", MX, EM, XX }, - { "maskmovq", MX, EM, XX }, + { PREGRP18 }, /* f8 */ { "psubb", MX, EM, XX }, { "psubw", MX, EM, XX }, @@ -1907,14 +1922,14 @@ static const struct dis386 dis386_twobyte_intel[] = { { "femms" , XX, XX, XX}, { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */ /* 10 */ - { PREGRP8 }, - { PREGRP9 }, - { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ - { "movlps", EX, XM, SIMD_Fixup, 'h' }, - { "unpcklps", XM, EX, XX }, - { "unpckhps", XM, EX, XX }, - { "movhps", XM, EX, SIMD_Fixup, 'l' }, - { "movhps", EX, XM, SIMD_Fixup, 'l' }, + { PREGRP8 }, + { PREGRP9 }, + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlpX", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklpX", XM, EX, XX }, + { "unpckhpX", XM, EX, XX }, + { "movhpX", XM, EX, SIMD_Fixup, 'l' }, + { "movhpX", EX, XM, SIMD_Fixup, 'l' }, /* 18 */ { GRP14 }, { "(bad)", XX, XX, XX }, @@ -1935,14 +1950,14 @@ static const struct dis386 dis386_twobyte_intel[] = { { "mov", Td, Rd, XX }, { "(bad)", XX, XX, XX }, /* 28 */ - { "movaps", XM, EX, XX }, - { "movaps", EX, XM, XX }, + { "movapX", XM, EX, XX }, + { "movapX", EX, XM, XX }, { PREGRP2 }, - { "movntps", Ev, XM, XX }, + { "movntpX", Ev, XM, XX }, { PREGRP4 }, { PREGRP3 }, - { "ucomiss", XM, EX, XX }, - { "comiss", XM, EX, XX }, + { "ucomisX", XM,EX, XX }, + { "comisX", XM,EX, XX }, /* 30 */ { "wrmsr", XX, XX, XX }, { "rdtsc", XX, XX, XX }, @@ -1980,19 +1995,19 @@ static const struct dis386 dis386_twobyte_intel[] = { { "cmovle", Gv, Ev, XX }, { "cmovg", Gv, Ev, XX }, /* 50 */ - { "movmskps", Gv, EX, XX }, + { "movmskpX", Gv, EX, XX }, { PREGRP13 }, { PREGRP12 }, { PREGRP11 }, - { "andps", XM, EX, XX }, - { "andnps", XM, EX, XX }, - { "orps", XM, EX, XX }, - { "xorps", XM, EX, XX }, + { "andpX", XM, EX, XX }, + { "andnpX", XM, EX, XX }, + { "orpX", XM, EX, XX }, + { "xorpX", XM, EX, XX }, /* 58 */ { PREGRP0 }, { PREGRP10 }, - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP17 }, + { PREGRP16 }, { PREGRP14 }, { PREGRP7 }, { PREGRP5 }, @@ -2012,11 +2027,11 @@ static const struct dis386 dis386_twobyte_intel[] = { { "punpckhdq", MX, EM, XX }, { "packssdw", MX, EM, XX }, { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP24 }, { "movd", MX, Ed, XX }, - { "movq", MX, EM, XX }, + { PREGRP19 }, /* 70 */ - { "pshufw", MX, EM, Ib }, + { PREGRP22 }, { GRP10 }, { GRP11 }, { GRP12 }, @@ -2031,8 +2046,8 @@ static const struct dis386 dis386_twobyte_intel[] = { { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, - { "movd", Ed, MX, XX }, - { "movq", EM, MX, XX }, + { PREGRP23 }, + { PREGRP20 }, /* 80 */ { "jo", Jv, XX, XX }, { "jno", Jv, XX, XX }, @@ -2109,10 +2124,10 @@ static const struct dis386 dis386_twobyte_intel[] = { { "xadd", Eb, Gb, XX }, { "xadd", Ev, Gv, XX }, { PREGRP1 }, - { "(bad)", XX, XX, XX }, + { "movnti", Ev, Gv, XX }, { "pinsrw", MX, Ev, Ib }, { "pextrw", Ev, MX, Ib }, - { "shufps", XM, EX, Ib }, + { "shufpX", XM, EX, Ib }, { GRP9 }, /* c8 */ { "bswap", RMeAX, XX, XX }, /* bswap doesn't support 16 bit regs */ @@ -2130,7 +2145,7 @@ static const struct dis386 dis386_twobyte_intel[] = { { "psrlq", MX, EM, XX }, { "(bad)", XX, XX, XX }, { "pmullw", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP21 }, { "pmovmskb", Ev, MX, XX }, /* d8 */ { "psubusb", MX, EM, XX }, @@ -2148,7 +2163,7 @@ static const struct dis386 dis386_twobyte_intel[] = { { "pavgw", MX, EM, XX }, { "pmulhuw", MX, EM, XX }, { "pmulhw", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { PREGRP15 }, { "movntq", Ev, MX, XX }, /* e8 */ { "psubsb", MX, EM, XX }, @@ -2164,10 +2179,10 @@ static const struct dis386 dis386_twobyte_intel[] = { { "psllw", MX, EM, XX }, { "pslld", MX, EM, XX }, { "psllq", MX, EM, XX }, - { "(bad)", XX, XX, XX }, + { "pmuludq", MX, EM, XX }, { "pmaddwd", MX, EM, XX }, { "psadbw", MX, EM, XX }, - { "maskmovq", MX, EM, XX }, + { PREGRP18 }, /* f8 */ { "psubb", MX, EM, XX }, { "psubw", MX, EM, XX }, @@ -2225,7 +2240,7 @@ static const unsigned char twobyte_has_modrm[256] = { /* 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] = { +static const unsigned char twobyte_uses_SSE_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 */ @@ -2233,17 +2248,17 @@ static const unsigned char twobyte_uses_f3_prefix[256] = { /* 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 */ + /* 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 */ + /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ /* 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 */ + /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ + /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */ + /* f0 */ 0,0,0,0,0,0,0,1,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 */ }; @@ -2501,11 +2516,11 @@ static const struct dis386 grps[][8] = { { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "psrlq", MS, Ib, XX }, - { "(bad)", XX, XX, XX }, + { "psrldq", MS, Ib, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "psllq", MS, Ib, XX }, - { "(bad)", XX, XX, XX }, + { "pslldq", MS, Ib, XX }, }, /* GRP13 */ { @@ -2514,9 +2529,10 @@ static const struct dis386 grps[][8] = { { "ldmxcsr", Ev, XX, XX }, { "stmxcsr", Ev, XX, XX }, { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, - { "(bad)", XX, XX, XX }, + { "lfence", None, XX, XX }, + { "mfence", None, XX, XX }, { "sfence", None, XX, XX }, + /* FIXME: the sfence with memory operand is clflush! */ }, /* GRP14 */ { @@ -2543,82 +2559,182 @@ static const struct dis386 grps[][8] = { }; -static const struct dis386 prefix_user_table[][2] = { +static const struct dis386 prefix_user_table[][4] = { /* PREGRP0 */ { { "addps", XM, EX, XX }, { "addss", XM, EX, XX }, + { "addpd", XM, EX, XX }, + { "addsd", XM, EX, XX }, }, /* PREGRP1 */ { { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */ { "", XM, EX, OPSIMD }, + { "", XM, EX, OPSIMD }, + { "", XM, EX, OPSIMD }, }, /* PREGRP2 */ { { "cvtpi2ps", XM, EM, XX }, { "cvtsi2ss", XM, Ev, XX }, + { "cvtpi2pd", XM, EM, XX }, + { "cvtsi2sd", XM, Ev, XX }, }, /* PREGRP3 */ { { "cvtps2pi", MX, EX, XX }, { "cvtss2si", Gv, EX, XX }, + { "cvtpd2pi", MX, EX, XX }, + { "cvtsd2si", Gv, EX, XX }, }, /* PREGRP4 */ { { "cvttps2pi", MX, EX, XX }, { "cvttss2si", Gv, EX, XX }, + { "cvttpd2pi", MX, EX, XX }, + { "cvttsd2si", Gv, EX, XX }, }, /* PREGRP5 */ { { "divps", XM, EX, XX }, { "divss", XM, EX, XX }, + { "divpd", XM, EX, XX }, + { "divsd", XM, EX, XX }, }, /* PREGRP6 */ { { "maxps", XM, EX, XX }, { "maxss", XM, EX, XX }, + { "maxpd", XM, EX, XX }, + { "maxsd", XM, EX, XX }, }, /* PREGRP7 */ { { "minps", XM, EX, XX }, { "minss", XM, EX, XX }, + { "minpd", XM, EX, XX }, + { "minsd", XM, EX, XX }, }, /* PREGRP8 */ { { "movups", XM, EX, XX }, { "movss", XM, EX, XX }, + { "movupd", XM, EX, XX }, + { "movsd", XM, EX, XX }, }, /* PREGRP9 */ { { "movups", EX, XM, XX }, { "movss", EX, XM, XX }, + { "movupd", EX, XM, XX }, + { "movsd", EX, XM, XX }, }, /* PREGRP10 */ { { "mulps", XM, EX, XX }, { "mulss", XM, EX, XX }, + { "mulpd", XM, EX, XX }, + { "mulsd", XM, EX, XX }, }, /* PREGRP11 */ { { "rcpps", XM, EX, XX }, { "rcpss", XM, EX, XX }, + { "(bad)", XM, EX, XX }, + { "(bad)", XM, EX, XX }, }, /* PREGRP12 */ { { "rsqrtps", XM, EX, XX }, { "rsqrtss", XM, EX, XX }, + { "(bad)", XM, EX, XX }, + { "(bad)", XM, EX, XX }, }, /* PREGRP13 */ { { "sqrtps", XM, EX, XX }, { "sqrtss", XM, EX, XX }, + { "sqrtpd", XM, EX, XX }, + { "sqrtsd", XM, EX, XX }, }, /* PREGRP14 */ { { "subps", XM, EX, XX }, { "subss", XM, EX, XX }, - } + { "subpd", XM, EX, XX }, + { "subsd", XM, EX, XX }, + }, + /* PREGRP15 */ + { + { "(bad)", XM, EX, XX }, + { "cvtdq2pd", XM, EX, XX }, + { "cvttpd2dq", XM, EX, XX }, + { "cvtpd2dq", XM, EX, XX }, + }, + /* PREGRP16 */ + { + { "cvtdq2ps", XM, EX, XX }, + { "cvttps2dq",XM, EX, XX }, + { "cvtps2dq",XM, EX, XX }, + { "(bad)", XM, EX, XX }, + }, + /* PREGRP17 */ + { + { "cvtps2pd", XM, EX, XX }, + { "cvtss2sd", XM, EX, XX }, + { "cvtpd2ps", XM, EX, XX }, + { "cvtsd2ss", XM, EX, XX }, + }, + /* PREGRP18 */ + { + { "maskmovq", MX, EM, XX }, + { "(bad)", XM, EX, XX }, + { "maskmovdqu", MX, EX, XX }, + { "(bad)", XM, EX, XX }, + }, + /* PREGRP19 */ + { + { "movq", MX, EM, XX }, + { "movdqu", XM, EX, XX }, + { "movdqa", XM, EX, XX }, + { "(bad)", XM, EX, XX }, + }, + /* PREGRP20 */ + { + { "movq", EM, MX, XX }, + { "movdqu", EX, XM, XX }, + { "movdqa", EX, XM, XX }, + { "(bad)", EX, XM, XX }, + }, + /* PREGRP21 */ + { + { "(bad)", EX, XM, XX }, + { "movq2dq", EX, EM, XX }, + { "movq", EX, XM, XX }, + { "movdq2q", EM, MX, XX }, + }, + /* PREGRP22 */ + { + { "pshufw", MX, EM, Ib }, + { "pshufhw", XM, EX, Ib }, + { "pshufd", XM, EX, Ib }, + { "pshuflw", XM, EX, Ib }, + }, + /* PREGRP23 */ + { + { "movd", Ed, MX, XX }, + { "movq", Ed, XM, XX }, + { "movd", Ed, XM, XX }, + { "(bad)", EX, XM, XX }, + }, + /* PREGRP24 */ + { + { "(bad)", EX, XM, XX }, + { "(bad)", EX, XM, XX }, + { "punpckhqdq", XM, EX, XX }, + { "(bad)", EX, XM, XX }, + }, }; #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") @@ -2854,7 +2970,7 @@ print_insn_i386 (pc, info) char *first, *second, *third; int needcomma; unsigned char need_modrm; - unsigned char uses_f3_prefix; + unsigned char uses_SSE_prefix; VOLATILE int sizeflag; VOLATILE int orig_sizeflag; @@ -2950,7 +3066,7 @@ print_insn_i386 (pc, info) else dp = &dis386_twobyte_att[*++codep]; need_modrm = twobyte_has_modrm[*codep]; - uses_f3_prefix = twobyte_uses_f3_prefix[*codep]; + uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; } else { @@ -2965,16 +3081,16 @@ print_insn_i386 (pc, info) else dp = &dis386_att[*codep]; need_modrm = onebyte_has_modrm[*codep]; - uses_f3_prefix = 0; + uses_SSE_prefix = 0; } codep++; - if (!uses_f3_prefix && (prefixes & PREFIX_REPZ)) + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) { oappend ("repz "); used_prefixes |= PREFIX_REPZ; } - if (prefixes & PREFIX_REPNZ) + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) { oappend ("repnz "); used_prefixes |= PREFIX_REPNZ; @@ -2985,7 +3101,7 @@ print_insn_i386 (pc, info) used_prefixes |= PREFIX_LOCK; } - if (prefixes & PREFIX_DATA) + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) sizeflag ^= DFLAG; if (prefixes & PREFIX_ADDR) @@ -3012,6 +3128,7 @@ print_insn_i386 (pc, info) } else { + int index; if (dp->name == NULL) { switch(dp->bytemode2) @@ -3020,8 +3137,24 @@ print_insn_i386 (pc, info) dp = &grps[dp->bytemode1][reg]; break; case USE_PREFIX_USER_TABLE: - dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0]; + index = 0; used_prefixes |= (prefixes & PREFIX_REPZ); + if (prefixes & PREFIX_REPZ) + index = 1; + else + { + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) + index = 2; + else + { + used_prefixes |= (prefixes & PREFIX_REPNZ); + if (prefixes & PREFIX_REPNZ) + index = 3; + + } + } + dp = &prefix_user_table[dp->bytemode1][index]; break; default: oappend (INTERNAL_DISASSEMBLER_ERROR); @@ -3670,6 +3803,13 @@ putop (template, sizeflag) } #endif break; + case 'X': + if (prefixes & PREFIX_DATA) + *obufp++ = 'd'; + else + *obufp++ = 's'; + used_prefixes |= (prefixes & PREFIX_DATA); + break; /* implicit operand size 'l' for i386 or 'q' for x86-64 */ case 'I': if (mode_64bit) @@ -3889,7 +4029,9 @@ OP_E (bytemode, sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); break; case 0: - if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)) + if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */) + && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */) + && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */)) BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */ break; default: @@ -4697,7 +4839,15 @@ OP_MMX (ignore, sizeflag) int ignore ATTRIBUTE_UNUSED; int sizeflag ATTRIBUTE_UNUSED; { - sprintf (scratchbuf, "%%mm%d", reg); + int add = 0; + USED_REX (REX_EXTX); + if (rex & REX_EXTX) + add = 8; + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) + sprintf (scratchbuf, "%%xmm%d", reg + add); + else + sprintf (scratchbuf, "%%mm%d", reg + add); oappend (scratchbuf); } @@ -4706,7 +4856,11 @@ OP_XMM (bytemode, sizeflag) int bytemode ATTRIBUTE_UNUSED; int sizeflag ATTRIBUTE_UNUSED; { - sprintf (scratchbuf, "%%xmm%d", reg); + int add = 0; + USED_REX (REX_EXTX); + if (rex & REX_EXTX) + add = 8; + sprintf (scratchbuf, "%%xmm%d", reg + add); oappend (scratchbuf); } @@ -4715,14 +4869,22 @@ OP_EM (bytemode, sizeflag) int bytemode; int sizeflag; { + int add = 0; if (mod != 3) { OP_E (bytemode, sizeflag); return; } + USED_REX (REX_EXTZ); + if (rex & REX_EXTZ) + add = 8; codep++; - sprintf (scratchbuf, "%%mm%d", rm); + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) + sprintf (scratchbuf, "%%xmm%d", rm + add); + else + sprintf (scratchbuf, "%%mm%d", rm + add); oappend (scratchbuf); } @@ -4731,14 +4893,18 @@ OP_EX (bytemode, sizeflag) int bytemode; int sizeflag; { + int add = 0; if (mod != 3) { OP_E (bytemode, sizeflag); return; } + USED_REX (REX_EXTZ); + if (rex & REX_EXTZ) + add = 8; codep++; - sprintf (scratchbuf, "%%xmm%d", rm); + sprintf (scratchbuf, "%%xmm%d", rm + add); oappend (scratchbuf); } @@ -4871,9 +5037,24 @@ OP_SIMD_Suffix (bytemode, sizeflag) cmp_type = *codep++ & 0xff; if (cmp_type < 8) { - sprintf (scratchbuf, "cmp%s%cs", - simd_cmp_op[cmp_type], - prefixes & PREFIX_REPZ ? 's' : 'p'); + char suffix1 = 'p', suffix2 = 's'; + used_prefixes |= (prefixes & PREFIX_REPZ); + if (prefixes & PREFIX_REPZ) + suffix1 = 's'; + else + { + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) + suffix2 = 'd'; + else + { + used_prefixes |= (prefixes & PREFIX_REPNZ); + if (prefixes & PREFIX_REPNZ) + suffix1 = 's', suffix2 = 'd'; + } + } + sprintf (scratchbuf, "cmp%s%c%c", + simd_cmp_op[cmp_type], suffix1, suffix2); used_prefixes |= (prefixes & PREFIX_REPZ); oappend (scratchbuf); } |