X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=7133337eead730a75409f6195876dd8b1842632c;hb=33e2f5278cb2c032e4898383d44bde303d6b4747;hp=6fcc724a8fdd32f60b0b5bfb357aad4f11dc62ef;hpb=be0c8b05081049a94ae470d63846f4047f9d9a8c;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 6fcc724a8f..7133337eea 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1,5 +1,6 @@ /* Print i386 instructions for GDB, the GNU debugger. - Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 1997 + Free Software Foundation, Inc. This file is part of GDB. @@ -39,6 +40,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *)); + struct dis_private { /* Points to first byte not fetched. */ @@ -97,7 +100,9 @@ fetch_data (info, addr) #define Iw OP_I, w_mode #define Jb OP_J, b_mode #define Jv OP_J, v_mode +#if 0 #define ONE OP_ONE, 0 +#endif #define Cd OP_C, d_mode #define Dd OP_D, d_mode #define Td OP_T, d_mode @@ -139,11 +144,36 @@ fetch_data (info, addr) #define fs OP_REG, fs_reg #define gs OP_REG, gs_reg -typedef int op_rtn PARAMS ((int bytemode, int aflag, int dflag)); - -static op_rtn OP_E, OP_G, OP_I, OP_indirE, OP_sI, OP_REG, OP_J, OP_DIR, OP_OFF; -static op_rtn OP_ESDI, OP_DSSI, OP_SEG, OP_ONE, OP_C, OP_D, OP_T, OP_rm, OP_ST; -static op_rtn OP_STi; +#define MX OP_MMX, 0 +#define EM OP_EM, v_mode +#define MS OP_MS, b_mode + +typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag)); + +static int OP_E PARAMS ((int, int, int)); +static int OP_G PARAMS ((int, int, int)); +static int OP_I PARAMS ((int, int, int)); +static int OP_indirE PARAMS ((int, int, int)); +static int OP_sI PARAMS ((int, int, int)); +static int OP_REG PARAMS ((int, int, int)); +static int OP_J PARAMS ((int, int, int)); +static int OP_DIR PARAMS ((int, int, int)); +static int OP_OFF PARAMS ((int, int, int)); +static int OP_ESDI PARAMS ((int, int, int)); +static int OP_DSSI PARAMS ((int, int, int)); +static int OP_SEG PARAMS ((int, int, int)); +static int OP_C PARAMS ((int, int, int)); +static int OP_D PARAMS ((int, int, int)); +static int OP_T PARAMS ((int, int, int)); +static int OP_rm PARAMS ((int, int, int)); +static int OP_ST PARAMS ((int, int, int)); +static int OP_STi PARAMS ((int, int, int)); +#if 0 +static int OP_ONE PARAMS ((int, int, int)); +#endif +static int OP_MMX PARAMS ((int, int, int)); +static int OP_EM PARAMS ((int, int, int)); +static int OP_MS PARAMS ((int, int, int)); static void append_prefix PARAMS ((void)); static void set_op PARAMS ((int op)); @@ -212,17 +242,20 @@ static void ckprefix PARAMS ((void)); #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 FLOATCODE 50 #define FLOAT NULL, NULL, FLOATCODE struct dis386 { char *name; - op_rtn *op1; + op_rtn op1; int bytemode1; - op_rtn *op2; + op_rtn op2; int bytemode2; - op_rtn *op3; + op_rtn op3; int bytemode3; }; @@ -234,8 +267,8 @@ static struct dis386 dis386[] = { { "addS", Gv, Ev }, { "addb", AL, Ib }, { "addS", eAX, Iv }, - { "pushl", es }, - { "popl", es }, + { "pushS", es }, + { "popS", es }, /* 08 */ { "orb", Eb, Gb }, { "orS", Ev, Gv }, @@ -243,7 +276,7 @@ static struct dis386 dis386[] = { { "orS", Gv, Ev }, { "orb", AL, Ib }, { "orS", eAX, Iv }, - { "pushl", cs }, + { "pushS", cs }, { "(bad)" }, /* 0x0f extended opcode escape */ /* 10 */ { "adcb", Eb, Gb }, @@ -252,8 +285,8 @@ static struct dis386 dis386[] = { { "adcS", Gv, Ev }, { "adcb", AL, Ib }, { "adcS", eAX, Iv }, - { "pushl", ss }, - { "popl", ss }, + { "pushS", ss }, + { "popS", ss }, /* 18 */ { "sbbb", Eb, Gb }, { "sbbS", Ev, Gv }, @@ -261,8 +294,8 @@ static struct dis386 dis386[] = { { "sbbS", Gv, Ev }, { "sbbb", AL, Ib }, { "sbbS", eAX, Iv }, - { "pushl", ds }, - { "popl", ds }, + { "pushS", ds }, + { "popS", ds }, /* 20 */ { "andb", Eb, Gb }, { "andS", Ev, Gv }, @@ -347,7 +380,7 @@ static struct dis386 dis386[] = { /* 68 */ { "pushS", Iv }, /* 386 book wrong */ { "imulS", Gv, Ev, Iv }, - { "pushl", sIb }, /* push of byte really pushes 4 bytes */ + { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */ { "imulS", Gv, Ev, Ib }, { "insb", Yb, indirDX }, { "insS", Yv, indirDX }, @@ -399,8 +432,8 @@ static struct dis386 dis386[] = { { "xchgS", eSI, eAX }, { "xchgS", eDI, eAX }, /* 98 */ - { "cwtl" }, - { "cltd" }, + { "cWtS" }, + { "cStd" }, { "lcall", Ap }, { "(bad)" }, /* fwait */ { "pushf" }, @@ -570,17 +603,36 @@ static struct dis386 dis386_twobyte[] = { { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 60 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "punpcklbw", MX, EM }, + { "punpcklwd", MX, EM }, + { "punpckldq", MX, EM }, + { "packsswb", MX, EM }, + { "pcmpgtb", MX, EM }, + { "pcmpgtw", MX, EM }, + { "pcmpgtd", MX, EM }, + { "packuswb", MX, EM }, /* 68 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "punpckhbw", MX, EM }, + { "punpckhwd", MX, EM }, + { "punpckhdq", MX, EM }, + { "packssdw", MX, EM }, + { "(bad)" }, { "(bad)" }, + { "movd", MX, Ev }, + { "movq", MX, EM }, /* 70 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { GRP10 }, + { GRP11 }, + { GRP12 }, + { "pcmpeqb", MX, EM }, + { "pcmpeqw", MX, EM }, + { "pcmpeqd", MX, EM }, + { "emms" }, /* 78 */ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, + { "movd", Ev, MX }, + { "movq", EM, MX }, /* 80 */ { "jo", Jv }, { "jno", Jv }, @@ -618,8 +670,8 @@ static struct dis386 dis386_twobyte[] = { { "setle", Eb }, { "setg", Eb }, /* a0 */ - { "pushl", fs }, - { "popl", fs }, + { "pushS", fs }, + { "popS", fs }, { "cpuid" }, { "btS", Ev, Gv }, { "shldS", Ev, Gv, Ib }, @@ -627,8 +679,8 @@ static struct dis386 dis386_twobyte[] = { { "(bad)" }, { "(bad)" }, /* a8 */ - { "pushl", gs }, - { "popl", gs }, + { "pushS", gs }, + { "popS", gs }, { "rsm" }, { "btsS", Ev, Gv }, { "shrdS", Ev, Gv, Ib }, @@ -672,23 +724,56 @@ static struct dis386 dis386_twobyte[] = { { "bswap", eSI }, { "bswap", eDI }, /* d0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psrlw", MX, EM }, + { "psrld", MX, EM }, + { "psrlq", MX, EM }, + { "(bad)" }, + { "pmullw", MX, EM }, + { "(bad)" }, { "(bad)" }, /* d8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubusb", MX, EM }, + { "psubusw", MX, EM }, + { "(bad)" }, + { "pand", MX, EM }, + { "paddusb", MX, EM }, + { "paddusw", MX, EM }, + { "(bad)" }, + { "pandn", MX, EM }, /* e0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psraw", MX, EM }, + { "psrad", MX, EM }, + { "(bad)" }, + { "(bad)" }, + { "pmulhw", MX, EM }, + { "(bad)" }, { "(bad)" }, /* e8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubsb", MX, EM }, + { "psubsw", MX, EM }, + { "(bad)" }, + { "por", MX, EM }, + { "paddsb", MX, EM }, + { "paddsw", MX, EM }, + { "(bad)" }, + { "pxor", MX, EM }, /* f0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psllw", MX, EM }, + { "pslld", MX, EM }, + { "psllq", MX, EM }, + { "(bad)" }, + { "pmaddwd", MX, EM }, + { "(bad)" }, { "(bad)" }, /* f8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubb", MX, EM }, + { "psubw", MX, EM }, + { "psubd", MX, EM }, + { "(bad)" }, + { "paddb", MX, EM }, + { "paddw", MX, EM }, + { "paddd", MX, EM }, + { "(bad)" } }; static const unsigned char onebyte_has_modrm[256] = { @@ -711,22 +796,22 @@ static const unsigned char onebyte_has_modrm[256] = { }; static const unsigned char twobyte_has_modrm[256] = { - 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, - 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, - 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, - 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,1,1,1,1,1,0,0,0,1,1,1,1,1, - 1,1,1,1,1,1,1,1,0,0,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,0,0,0,0,0,0,0,0 + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */ + /* 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 */ + /* 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 */ + /* 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,1,0,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 */ }; static char obuf[100]; @@ -943,6 +1028,39 @@ static struct dis386 grps[][8] = { { "(bad)" }, { "(bad)" }, { "(bad)" }, + }, + /* GRP10 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrlw", MS, Ib }, + { "(bad)" }, + { "psraw", MS, Ib }, + { "(bad)" }, + { "psllw", MS, Ib }, + { "(bad)" }, + }, + /* GRP11 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrld", MS, Ib }, + { "(bad)" }, + { "psrad", MS, Ib }, + { "(bad)" }, + { "pslld", MS, Ib }, + { "(bad)" }, + }, + /* GRP12 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrlq", MS, Ib }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "psllq", MS, Ib }, + { "(bad)" }, } }; @@ -1034,15 +1152,12 @@ print_insn_i386 (pc, info) bfd_vma pc; disassemble_info *info; { - print_insn_x86 (pc, info, 1, 1); -} - -int -print_insn_i8086 (pc, info) - bfd_vma pc; - disassemble_info *info; -{ - print_insn_x86 (pc, info, 0, 0); + if (info->mach == bfd_mach_i386_i386) + return print_insn_x86 (pc, info, 1, 1); + else if (info->mach == bfd_mach_i386_i8086) + return print_insn_x86 (pc, info, 0, 0); + else + abort (); } int @@ -1060,6 +1175,10 @@ print_insn_x86 (pc, info, aflag, dflag) 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; + info->private_data = (PTR) &priv; priv.max_fetched = priv.the_buffer; priv.insn_start = pc; @@ -1110,7 +1229,10 @@ print_insn_x86 (pc, info, aflag, dflag) if (prefixes & PREFIX_ADR) { aflag ^= 1; - oappend ("addr16 "); + if (aflag) + oappend ("addr32 "); + else + oappend ("addr16 "); } if (*codep == 0x0f) @@ -1541,6 +1663,13 @@ putop (template, aflag, dflag) else *obufp++ = 'w'; break; + case 'W': + /* operand size flag for cwtl, cbtw */ + if (dflag) + *obufp++ = 'w'; + else + *obufp++ = 'b'; + break; } } *obufp = 0; @@ -2022,6 +2151,9 @@ OP_DSSI (dummy, aflag, dflag) return (0); } +#if 0 +/* Not used. */ + /* ARGSUSED */ static int OP_ONE (dummy, aflag, dflag) @@ -2033,6 +2165,8 @@ OP_ONE (dummy, aflag, dflag) return (0); } +#endif + /* ARGSUSED */ static int OP_C (dummy, aflag, dflag) @@ -2089,3 +2223,41 @@ OP_rm (bytemode, aflag, dflag) } return (0); } + +static int +OP_MMX (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + sprintf (scratchbuf, "%%mm%d", reg); + oappend (scratchbuf); + return 0; +} + +static int +OP_EM (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + if (mod != 3) + return OP_E (bytemode, aflag, dflag); + + codep++; + sprintf (scratchbuf, "%%mm%d", rm); + oappend (scratchbuf); + return 0; +} + +static int +OP_MS (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + ++codep; + sprintf (scratchbuf, "%%mm%d", rm); + oappend (scratchbuf); + return 0; +}