Annotation of XNU/osfmk/i386/db_disasm.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  */
        !            25: /*
        !            26:  * HISTORY
        !            27:  * 
        !            28:  * Revision 1.1.1.1  1998/09/22 21:05:36  wsanchez
        !            29:  * Import of Mac OS X kernel (~semeria)
        !            30:  *
        !            31:  * Revision 1.1.1.1  1998/03/07 02:25:37  wsanchez
        !            32:  * Import of OSF Mach kernel (~mburg)
        !            33:  *
        !            34:  * Revision 1.2.8.3  1996/07/31  09:43:35  paire
        !            35:  *     Merged with nmk20b7_shared (1.2.11.1)
        !            36:  *     [96/06/10            paire]
        !            37:  *
        !            38:  * Revision 1.2.11.1  1996/05/14  13:49:36  paire
        !            39:  *     Added support for new cmpxchg8b, cpuid, rdtsc, rdwmr, rsm and wrmsr
        !            40:  *     Pentium instructions
        !            41:  *     [95/11/23            paire]
        !            42:  * 
        !            43:  * Revision 1.2.8.2  1994/09/23  01:50:45  ezf
        !            44:  *     change marker to not FREE
        !            45:  *     [1994/09/22  21:21:17  ezf]
        !            46:  * 
        !            47:  * Revision 1.2.8.1  1994/09/16  15:26:28  emcmanus
        !            48:  *     Only skip over GAS-inserted NOPs after branches if they are really
        !            49:  *     NOPs; this depends at least on assembler options.
        !            50:  *     [1994/09/16  15:26:03  emcmanus]
        !            51:  * 
        !            52:  * Revision 1.2.6.3  1994/02/19  15:40:34  bolinger
        !            53:  *     For load/store counting, mark all varieties of "call" as writing
        !            54:  *     memory.
        !            55:  *     [1994/02/15  20:25:18  bolinger]
        !            56:  * 
        !            57:  * Revision 1.2.6.2  1994/02/14  21:46:49  dwm
        !            58:  *     Warning repair
        !            59:  *     [1994/02/14  21:46:14  dwm]
        !            60:  * 
        !            61:  * Revision 1.2.6.1  1994/02/12  23:26:05  bolinger
        !            62:  *     Implement load/store counting for ddb "until" command.
        !            63:  *     [1994/02/12  03:34:55  bolinger]
        !            64:  * 
        !            65:  * Revision 1.2.2.3  1993/08/09  19:39:21  dswartz
        !            66:  *     Add ANSI prototypes - CR#9523
        !            67:  *     [1993/08/06  17:44:13  dswartz]
        !            68:  * 
        !            69:  * Revision 1.2.2.2  1993/06/09  02:27:29  gm
        !            70:  *     Added to OSF/1 R1.3 from NMK15.0.
        !            71:  *     [1993/06/02  21:03:54  jeffc]
        !            72:  * 
        !            73:  * Revision 1.2  1993/04/19  16:12:57  devrcs
        !            74:  *     Print file names and lineno on branch instructions.
        !            75:  *     [[email protected]]
        !            76:  *     [92/12/03            bernadat]
        !            77:  * 
        !            78:  * Revision 1.1  1992/09/30  02:02:19  robert
        !            79:  *     Initial revision
        !            80:  * 
        !            81:  * $EndLog$
        !            82:  */
        !            83: /* CMU_HIST */
        !            84: /*
        !            85:  * Revision 2.5.3.1  92/03/03  16:14:27  jeffreyh
        !            86:  *     Pick up changes from TRUNK
        !            87:  *     [92/02/26  11:05:06  jeffreyh]
        !            88:  * 
        !            89:  * Revision 2.6  92/01/03  20:05:00  dbg
        !            90:  *     Add a switch to disassemble 16-bit code.
        !            91:  *     Fix spelling of 'lods' opcodes.
        !            92:  *     [91/10/30            dbg]
        !            93:  * 
        !            94:  * Revision 2.5  91/10/09  16:05:58  af
        !            95:  *     Supported disassemble of non current task by passing task parameter.
        !            96:  *     [91/08/29            tak]
        !            97:  * 
        !            98:  * Revision 2.4  91/05/14  16:05:04  mrt
        !            99:  *     Correcting copyright
        !           100:  * 
        !           101:  * Revision 2.3  91/02/05  17:11:03  mrt
        !           102:  *     Changed to new Mach copyright
        !           103:  *     [91/02/01  17:31:03  mrt]
        !           104:  * 
        !           105:  * Revision 2.2  90/08/27  21:55:56  dbg
        !           106:  *     Fix register operand for move to/from control/test/debug
        !           107:  *     register instructions.  Add i486 instructions.
        !           108:  *     [90/08/27            dbg]
        !           109:  * 
        !           110:  *     Import db_sym.h.  Print instruction displacements in
        !           111:  *     current radix (signed).  Change calling sequence of
        !           112:  *     db_disasm.
        !           113:  *     [90/08/21            dbg]
        !           114:  *     Fix includes.
        !           115:  *     [90/08/08            dbg]
        !           116:  *     Created.
        !           117:  *     [90/07/25            dbg]
        !           118:  * 
        !           119:  */
        !           120: /* CMU_ENDHIST */
        !           121: /* 
        !           122:  * Mach Operating System
        !           123:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !           124:  * All Rights Reserved.
        !           125:  * 
        !           126:  * Permission to use, copy, modify and distribute this software and its
        !           127:  * documentation is hereby granted, provided that both the copyright
        !           128:  * notice and this permission notice appear in all copies of the
        !           129:  * software, derivative works or modified versions, and any portions
        !           130:  * thereof, and that both notices appear in supporting documentation.
        !           131:  * 
        !           132:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !           133:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !           134:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !           135:  * 
        !           136:  * Carnegie Mellon requests users of this software to return to
        !           137:  * 
        !           138:  *  Software Distribution Coordinator  or  [email protected]
        !           139:  *  School of Computer Science
        !           140:  *  Carnegie Mellon University
        !           141:  *  Pittsburgh PA 15213-3890
        !           142:  * 
        !           143:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           144:  * the rights to redistribute these changes.
        !           145:  */
        !           146: /*
        !           147:  */
        !           148: 
        !           149: /*
        !           150:  * Instruction disassembler.
        !           151:  */
        !           152: 
        !           153: #include <mach/boolean.h>
        !           154: #include <machine/db_machdep.h>
        !           155: 
        !           156: #include <ddb/db_access.h>
        !           157: #include <ddb/db_sym.h>
        !           158: #include <ddb/db_output.h>
        !           159: 
        !           160: #include <kern/task.h>
        !           161: #include <kern/misc_protos.h>
        !           162: 
        !           163: struct i_addr {
        !           164:        int             is_reg; /* if reg, reg number is in 'disp' */
        !           165:        int             disp;
        !           166:        char *          base;
        !           167:        char *          index;
        !           168:        int             ss;
        !           169: };
        !           170: 
        !           171: /* Forward */
        !           172: 
        !           173: extern db_addr_t       db_read_address(
        !           174:                                db_addr_t       loc,
        !           175:                                int             short_addr,
        !           176:                                int             regmodrm,
        !           177:                                struct i_addr   * addrp,
        !           178:                                task_t          task);
        !           179: extern void            db_print_address(
        !           180:                                char *          seg,
        !           181:                                int             size,
        !           182:                                struct i_addr   *addrp,
        !           183:                                task_t          task);
        !           184: extern db_addr_t       db_disasm_esc(
        !           185:                                db_addr_t       loc,
        !           186:                                int             inst,
        !           187:                                int             short_addr,
        !           188:                                int             size,
        !           189:                                char *          seg,
        !           190:                                task_t          task);
        !           191: 
        !           192: /*
        !           193:  * Switch to disassemble 16-bit code.
        !           194:  */
        !           195: boolean_t      db_disasm_16 = FALSE;
        !           196: 
        !           197: /*
        !           198:  * Size attributes
        !           199:  */
        !           200: #define        BYTE    0
        !           201: #define        WORD    1
        !           202: #define        LONG    2
        !           203: #define        QUAD    3
        !           204: #define        SNGL    4
        !           205: #define        DBLR    5
        !           206: #define        EXTR    6
        !           207: #define        SDEP    7
        !           208: #define        NONE    8
        !           209: 
        !           210: /*
        !           211:  * Addressing modes
        !           212:  */
        !           213: #define        E       1                       /* general effective address */
        !           214: #define        Eind    2                       /* indirect address (jump, call) */
        !           215: #define        Ew      3                       /* address, word size */
        !           216: #define        Eb      4                       /* address, byte size */
        !           217: #define        R       5                       /* register, in 'reg' field */
        !           218: #define        Rw      6                       /* word register, in 'reg' field */
        !           219: #define        Ri      7                       /* register in instruction */
        !           220: #define        S       8                       /* segment reg, in 'reg' field */
        !           221: #define        Si      9                       /* segment reg, in instruction */
        !           222: #define        A       10                      /* accumulator */
        !           223: #define        BX      11                      /* (bx) */
        !           224: #define        CL      12                      /* cl, for shifts */
        !           225: #define        DX      13                      /* dx, for IO */
        !           226: #define        SI      14                      /* si */
        !           227: #define        DI      15                      /* di */
        !           228: #define        CR      16                      /* control register */
        !           229: #define        DR      17                      /* debug register */
        !           230: #define        TR      18                      /* test register */
        !           231: #define        I       19                      /* immediate, unsigned */
        !           232: #define        Is      20                      /* immediate, signed */
        !           233: #define        Ib      21                      /* byte immediate, unsigned */
        !           234: #define        Ibs     22                      /* byte immediate, signed */
        !           235: #define        Iw      23                      /* word immediate, unsigned */
        !           236: #define        Il      24                      /* long immediate */
        !           237: #define        O       25                      /* direct address */
        !           238: #define        Db      26                      /* byte displacement from EIP */
        !           239: #define        Dl      27                      /* long displacement from EIP */
        !           240: #define        o1      28                      /* constant 1 */
        !           241: #define        o3      29                      /* constant 3 */
        !           242: #define        OS      30                      /* immediate offset/segment */
        !           243: #define        ST      31                      /* FP stack top */
        !           244: #define        STI     32                      /* FP stack */
        !           245: #define        X       33                      /* extended FP op */
        !           246: #define        XA      34                      /* for 'fstcw %ax' */
        !           247: 
        !           248: struct inst {
        !           249:        char *  i_name;                 /* name */
        !           250:        short   i_has_modrm;            /* has regmodrm byte */
        !           251:        short   i_size;                 /* operand size */
        !           252:        int     i_mode;                 /* addressing modes */
        !           253:        char *  i_extra;                /* pointer to extra opcode table */
        !           254: };
        !           255: 
        !           256: #define        op1(x)          (x)
        !           257: #define        op2(x,y)        ((x)|((y)<<8))
        !           258: #define        op3(x,y,z)      ((x)|((y)<<8)|((z)<<16))
        !           259: 
        !           260: struct finst {
        !           261:        char *  f_name;                 /* name for memory instruction */
        !           262:        int     f_size;                 /* size for memory instruction */
        !           263:        int     f_rrmode;               /* mode for rr instruction */
        !           264:        char *  f_rrname;               /* name for rr instruction
        !           265:                                           (or pointer to table) */
        !           266: };
        !           267: 
        !           268: char * db_Grp6[] = {
        !           269:        "sldt",
        !           270:        "str",
        !           271:        "lldt",
        !           272:        "ltr",
        !           273:        "verr",
        !           274:        "verw",
        !           275:        "",
        !           276:        ""
        !           277: };
        !           278: 
        !           279: char * db_Grp7[] = {
        !           280:        "sgdt",
        !           281:        "sidt",
        !           282:        "lgdt",
        !           283:        "lidt",
        !           284:        "smsw",
        !           285:        "",
        !           286:        "lmsw",
        !           287:        "invlpg"
        !           288: };
        !           289: 
        !           290: char * db_Grp8[] = {
        !           291:        "",
        !           292:        "",
        !           293:        "",
        !           294:        "",
        !           295:        "bt",
        !           296:        "bts",
        !           297:        "btr",
        !           298:        "btc"
        !           299: };
        !           300: 
        !           301: struct inst db_inst_0f0x[] = {
        !           302: /*00*/ { "",      TRUE,  NONE,  op1(Ew),     (char *)db_Grp6 },
        !           303: /*01*/ { "",      TRUE,  NONE,  op1(Ew),     (char *)db_Grp7 },
        !           304: /*02*/ { "lar",   TRUE,  LONG,  op2(E,R),    0 },
        !           305: /*03*/ { "lsl",   TRUE,  LONG,  op2(E,R),    0 },
        !           306: /*04*/ { "",      FALSE, NONE,  0,           0 },
        !           307: /*05*/ { "",      FALSE, NONE,  0,           0 },
        !           308: /*06*/ { "clts",  FALSE, NONE,  0,           0 },
        !           309: /*07*/ { "",      FALSE, NONE,  0,           0 },
        !           310: 
        !           311: /*08*/ { "invd",  FALSE, NONE,  0,           0 },
        !           312: /*09*/ { "wbinvd",FALSE, NONE,  0,           0 },
        !           313: /*0a*/ { "",      FALSE, NONE,  0,           0 },
        !           314: /*0b*/ { "",      FALSE, NONE,  0,           0 },
        !           315: /*0c*/ { "",      FALSE, NONE,  0,           0 },
        !           316: /*0d*/ { "",      FALSE, NONE,  0,           0 },
        !           317: /*0e*/ { "",      FALSE, NONE,  0,           0 },
        !           318: /*0f*/ { "",      FALSE, NONE,  0,           0 },
        !           319: };
        !           320: 
        !           321: struct inst    db_inst_0f2x[] = {
        !           322: /*20*/ { "mov",   TRUE,  LONG,  op2(CR,E),   0 }, /* use E for reg */
        !           323: /*21*/ { "mov",   TRUE,  LONG,  op2(DR,E),   0 }, /* since mod == 11 */
        !           324: /*22*/ { "mov",   TRUE,  LONG,  op2(E,CR),   0 },
        !           325: /*23*/ { "mov",   TRUE,  LONG,  op2(E,DR),   0 },
        !           326: /*24*/ { "mov",   TRUE,  LONG,  op2(TR,E),   0 },
        !           327: /*25*/ { "",      FALSE, NONE,  0,           0 },
        !           328: /*26*/ { "mov",   TRUE,  LONG,  op2(E,TR),   0 },
        !           329: /*27*/ { "",      FALSE, NONE,  0,           0 },
        !           330: 
        !           331: /*28*/ { "",      FALSE, NONE,  0,           0 },
        !           332: /*29*/ { "",      FALSE, NONE,  0,           0 },
        !           333: /*2a*/ { "",      FALSE, NONE,  0,           0 },
        !           334: /*2b*/ { "",      FALSE, NONE,  0,           0 },
        !           335: /*2c*/ { "",      FALSE, NONE,  0,           0 },
        !           336: /*2d*/ { "",      FALSE, NONE,  0,           0 },
        !           337: /*2e*/ { "",      FALSE, NONE,  0,           0 },
        !           338: /*2f*/ { "",      FALSE, NONE,  0,           0 },
        !           339: };
        !           340: struct inst    db_inst_0f3x[] = {
        !           341: /*30*/ { "rdtsc", FALSE, NONE,  0,           0 },
        !           342: /*31*/ { "rdmsr", FALSE, NONE,  0,           0 },
        !           343: /*32*/ { "wrmsr", FALSE, NONE,  0,           0 },
        !           344: /*33*/ { "",      FALSE, NONE,  0,           0 },
        !           345: /*34*/ { "",      FALSE, NONE,  0,           0 },
        !           346: /*35*/ { "",      FALSE, NONE,  0,           0 },
        !           347: /*36*/ { "",      FALSE, NONE,  0,           0 },
        !           348: /*37*/ { "",      FALSE, NONE,  0,           0 },
        !           349: 
        !           350: /*38*/ { "",      FALSE, NONE,  0,           0 },
        !           351: /*39*/ { "",      FALSE, NONE,  0,           0 },
        !           352: /*3a*/ { "",      FALSE, NONE,  0,           0 },
        !           353: /*3b*/ { "",      FALSE, NONE,  0,           0 },
        !           354: /*3c*/ { "",      FALSE, NONE,  0,           0 },
        !           355: /*3d*/ { "",      FALSE, NONE,  0,           0 },
        !           356: /*3e*/ { "",      FALSE, NONE,  0,           0 },
        !           357: /*3f*/ { "",      FALSE, NONE,  0,           0 },
        !           358: };
        !           359: 
        !           360: struct inst    db_inst_0f8x[] = {
        !           361: /*80*/ { "jo",    FALSE, NONE,  op1(Dl),     0 },
        !           362: /*81*/ { "jno",   FALSE, NONE,  op1(Dl),     0 },
        !           363: /*82*/ { "jb",    FALSE, NONE,  op1(Dl),     0 },
        !           364: /*83*/ { "jnb",   FALSE, NONE,  op1(Dl),     0 },
        !           365: /*84*/ { "jz",    FALSE, NONE,  op1(Dl),     0 },
        !           366: /*85*/ { "jnz",   FALSE, NONE,  op1(Dl),     0 },
        !           367: /*86*/ { "jbe",   FALSE, NONE,  op1(Dl),     0 },
        !           368: /*87*/ { "jnbe",  FALSE, NONE,  op1(Dl),     0 },
        !           369: 
        !           370: /*88*/ { "js",    FALSE, NONE,  op1(Dl),     0 },
        !           371: /*89*/ { "jns",   FALSE, NONE,  op1(Dl),     0 },
        !           372: /*8a*/ { "jp",    FALSE, NONE,  op1(Dl),     0 },
        !           373: /*8b*/ { "jnp",   FALSE, NONE,  op1(Dl),     0 },
        !           374: /*8c*/ { "jl",    FALSE, NONE,  op1(Dl),     0 },
        !           375: /*8d*/ { "jnl",   FALSE, NONE,  op1(Dl),     0 },
        !           376: /*8e*/ { "jle",   FALSE, NONE,  op1(Dl),     0 },
        !           377: /*8f*/ { "jnle",  FALSE, NONE,  op1(Dl),     0 },
        !           378: };
        !           379: 
        !           380: struct inst    db_inst_0f9x[] = {
        !           381: /*90*/ { "seto",  TRUE,  NONE,  op1(Eb),     0 },
        !           382: /*91*/ { "setno", TRUE,  NONE,  op1(Eb),     0 },
        !           383: /*92*/ { "setb",  TRUE,  NONE,  op1(Eb),     0 },
        !           384: /*93*/ { "setnb", TRUE,  NONE,  op1(Eb),     0 },
        !           385: /*94*/ { "setz",  TRUE,  NONE,  op1(Eb),     0 },
        !           386: /*95*/ { "setnz", TRUE,  NONE,  op1(Eb),     0 },
        !           387: /*96*/ { "setbe", TRUE,  NONE,  op1(Eb),     0 },
        !           388: /*97*/ { "setnbe",TRUE,  NONE,  op1(Eb),     0 },
        !           389: 
        !           390: /*98*/ { "sets",  TRUE,  NONE,  op1(Eb),     0 },
        !           391: /*99*/ { "setns", TRUE,  NONE,  op1(Eb),     0 },
        !           392: /*9a*/ { "setp",  TRUE,  NONE,  op1(Eb),     0 },
        !           393: /*9b*/ { "setnp", TRUE,  NONE,  op1(Eb),     0 },
        !           394: /*9c*/ { "setl",  TRUE,  NONE,  op1(Eb),     0 },
        !           395: /*9d*/ { "setnl", TRUE,  NONE,  op1(Eb),     0 },
        !           396: /*9e*/ { "setle", TRUE,  NONE,  op1(Eb),     0 },
        !           397: /*9f*/ { "setnle",TRUE,  NONE,  op1(Eb),     0 },
        !           398: };
        !           399: 
        !           400: struct inst    db_inst_0fax[] = {
        !           401: /*a0*/ { "push",  FALSE, NONE,  op1(Si),     0 },
        !           402: /*a1*/ { "pop",   FALSE, NONE,  op1(Si),     0 },
        !           403: /*a2*/ { "cpuid", FALSE, NONE,  0,           0 },
        !           404: /*a3*/ { "bt",    TRUE,  LONG,  op2(E,R),    0 },
        !           405: /*a4*/ { "shld",  TRUE,  LONG,  op3(Ib,E,R), 0 },
        !           406: /*a5*/ { "shld",  TRUE,  LONG,  op3(CL,E,R), 0 },
        !           407: /*a6*/ { "",      FALSE, NONE,  0,           0 },
        !           408: /*a7*/ { "",      FALSE, NONE,  0,           0 },
        !           409: 
        !           410: /*a8*/ { "push",  FALSE, NONE,  op1(Si),     0 },
        !           411: /*a9*/ { "pop",   FALSE, NONE,  op1(Si),     0 },
        !           412: /*aa*/ { "rsm",   FALSE, NONE,  0,           0 },
        !           413: /*ab*/ { "bts",   TRUE,  LONG,  op2(E,R),    0 },
        !           414: /*ac*/ { "shrd",  TRUE,  LONG,  op3(Ib,E,R), 0 },
        !           415: /*ad*/ { "shrd",  TRUE,  LONG,  op3(CL,E,R), 0 },
        !           416: /*a6*/ { "",      FALSE, NONE,  0,           0 },
        !           417: /*a7*/ { "imul",  TRUE,  LONG,  op2(E,R),    0 },
        !           418: };
        !           419: 
        !           420: struct inst    db_inst_0fbx[] = {
        !           421: /*b0*/ { "",      FALSE, NONE,  0,           0 },
        !           422: /*b1*/ { "",      FALSE, NONE,  0,           0 },
        !           423: /*b2*/ { "lss",   TRUE,  LONG,  op2(E, R),   0 },
        !           424: /*b3*/ { "bts",   TRUE,  LONG,  op2(R, E),   0 },
        !           425: /*b4*/ { "lfs",   TRUE,  LONG,  op2(E, R),   0 },
        !           426: /*b5*/ { "lgs",   TRUE,  LONG,  op2(E, R),   0 },
        !           427: /*b6*/ { "movzb", TRUE,  LONG,  op2(E, R),   0 },
        !           428: /*b7*/ { "movzw", TRUE,  LONG,  op2(E, R),   0 },
        !           429: 
        !           430: /*b8*/ { "",      FALSE, NONE,  0,           0 },
        !           431: /*b9*/ { "",      FALSE, NONE,  0,           0 },
        !           432: /*ba*/ { "",      TRUE,  LONG,  op2(Is, E),  (char *)db_Grp8 },
        !           433: /*bb*/ { "btc",   TRUE,  LONG,  op2(R, E),   0 },
        !           434: /*bc*/ { "bsf",   TRUE,  LONG,  op2(E, R),   0 },
        !           435: /*bd*/ { "bsr",   TRUE,  LONG,  op2(E, R),   0 },
        !           436: /*be*/ { "movsb", TRUE,  LONG,  op2(E, R),   0 },
        !           437: /*bf*/ { "movsw", TRUE,  LONG,  op2(E, R),   0 },
        !           438: };
        !           439: 
        !           440: struct inst    db_inst_0fcx[] = {
        !           441: /*c0*/ { "xadd",  TRUE,  BYTE,  op2(R, E),   0 },
        !           442: /*c1*/ { "xadd",  TRUE,  LONG,  op2(R, E),   0 },
        !           443: /*c2*/ { "",      FALSE, NONE,  0,           0 },
        !           444: /*c3*/ { "",      FALSE, NONE,  0,           0 },
        !           445: /*c4*/ { "",      FALSE, NONE,  0,           0 },
        !           446: /*c5*/ { "",      FALSE, NONE,  0,           0 },
        !           447: /*c6*/ { "",      FALSE, NONE,  0,           0 },
        !           448: /*c7*/ { "cmpxchg8b", FALSE, NONE, op1(E),   0 },
        !           449: /*c8*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           450: /*c9*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           451: /*ca*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           452: /*cb*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           453: /*cc*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           454: /*cd*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           455: /*ce*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           456: /*cf*/ { "bswap", FALSE, LONG,  op1(Ri),     0 },
        !           457: };
        !           458: 
        !           459: struct inst    db_inst_0fdx[] = {
        !           460: /*c0*/ { "cmpxchg",TRUE, BYTE,  op2(R, E),   0 },
        !           461: /*c1*/ { "cmpxchg",TRUE, LONG,  op2(R, E),   0 },
        !           462: /*c2*/ { "",      FALSE, NONE,  0,           0 },
        !           463: /*c3*/ { "",      FALSE, NONE,  0,           0 },
        !           464: /*c4*/ { "",      FALSE, NONE,  0,           0 },
        !           465: /*c5*/ { "",      FALSE, NONE,  0,           0 },
        !           466: /*c6*/ { "",      FALSE, NONE,  0,           0 },
        !           467: /*c7*/ { "",      FALSE, NONE,  0,           0 },
        !           468: /*c8*/ { "",      FALSE, NONE,  0,           0 },
        !           469: /*c9*/ { "",      FALSE, NONE,  0,           0 },
        !           470: /*ca*/ { "",      FALSE, NONE,  0,           0 },
        !           471: /*cb*/ { "",      FALSE, NONE,  0,           0 },
        !           472: /*cc*/ { "",      FALSE, NONE,  0,           0 },
        !           473: /*cd*/ { "",      FALSE, NONE,  0,           0 },
        !           474: /*ce*/ { "",      FALSE, NONE,  0,           0 },
        !           475: /*cf*/ { "",      FALSE, NONE,  0,           0 },
        !           476: };
        !           477: 
        !           478: struct inst *db_inst_0f[] = {
        !           479:        db_inst_0f0x,
        !           480:        0,
        !           481:        db_inst_0f2x,
        !           482:        db_inst_0f3x,
        !           483:        0,
        !           484:        0,
        !           485:        0,
        !           486:        0,
        !           487:        db_inst_0f8x,
        !           488:        db_inst_0f9x,
        !           489:        db_inst_0fax,
        !           490:        db_inst_0fbx,
        !           491:        db_inst_0fcx,
        !           492:        db_inst_0fdx,
        !           493:        0,
        !           494:        0
        !           495: };
        !           496: 
        !           497: char * db_Esc92[] = {
        !           498:        "fnop", "",     "",     "",     "",     "",     "",     ""
        !           499: };
        !           500: char * db_Esc93[] = {
        !           501:        "",     "",     "",     "",     "",     "",     "",     ""
        !           502: };
        !           503: char * db_Esc94[] = {
        !           504:        "fchs", "fabs", "",     "",     "ftst", "fxam", "",     ""
        !           505: };
        !           506: char * db_Esc95[] = {
        !           507:        "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
        !           508: };
        !           509: char * db_Esc96[] = {
        !           510:        "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
        !           511:        "fincstp"
        !           512: };
        !           513: char * db_Esc97[] = {
        !           514:        "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
        !           515: };
        !           516: 
        !           517: char * db_Esca4[] = {
        !           518:        "",     "fucompp","",   "",     "",     "",     "",     ""
        !           519: };
        !           520: 
        !           521: char * db_Escb4[] = {
        !           522:        "",     "",     "fnclex","fninit","",   "",     "",     ""
        !           523: };
        !           524: 
        !           525: char * db_Esce3[] = {
        !           526:        "",     "fcompp","",    "",     "",     "",     "",     ""
        !           527: };
        !           528: 
        !           529: char * db_Escf4[] = {
        !           530:        "fnstsw","",    "",     "",     "",     "",     "",     ""
        !           531: };
        !           532: 
        !           533: struct finst db_Esc8[] = {
        !           534: /*0*/  { "fadd",   SNGL,  op2(STI,ST), 0 },
        !           535: /*1*/  { "fmul",   SNGL,  op2(STI,ST), 0 },
        !           536: /*2*/  { "fcom",   SNGL,  op2(STI,ST), 0 },
        !           537: /*3*/  { "fcomp",  SNGL,  op2(STI,ST), 0 },
        !           538: /*4*/  { "fsub",   SNGL,  op2(STI,ST), 0 },
        !           539: /*5*/  { "fsubr",  SNGL,  op2(STI,ST), 0 },
        !           540: /*6*/  { "fdiv",   SNGL,  op2(STI,ST), 0 },
        !           541: /*7*/  { "fdivr",  SNGL,  op2(STI,ST), 0 },
        !           542: };
        !           543: 
        !           544: struct finst db_Esc9[] = {
        !           545: /*0*/  { "fld",    SNGL,  op1(STI),    0 },
        !           546: /*1*/  { "",       NONE,  op1(STI),    "fxch" },
        !           547: /*2*/  { "fst",    SNGL,  op1(X),      (char *)db_Esc92 },
        !           548: /*3*/  { "fstp",   SNGL,  op1(X),      (char *)db_Esc93 },
        !           549: /*4*/  { "fldenv", NONE,  op1(X),      (char *)db_Esc94 },
        !           550: /*5*/  { "fldcw",  NONE,  op1(X),      (char *)db_Esc95 },
        !           551: /*6*/  { "fnstenv",NONE,  op1(X),      (char *)db_Esc96 },
        !           552: /*7*/  { "fnstcw", NONE,  op1(X),      (char *)db_Esc97 },
        !           553: };
        !           554: 
        !           555: struct finst db_Esca[] = {
        !           556: /*0*/  { "fiadd",  WORD,  0,           0 },
        !           557: /*1*/  { "fimul",  WORD,  0,           0 },
        !           558: /*2*/  { "ficom",  WORD,  0,           0 },
        !           559: /*3*/  { "ficomp", WORD,  0,           0 },
        !           560: /*4*/  { "fisub",  WORD,  op1(X),      (char *)db_Esca4 },
        !           561: /*5*/  { "fisubr", WORD,  0,           0 },
        !           562: /*6*/  { "fidiv",  WORD,  0,           0 },
        !           563: /*7*/  { "fidivr", WORD,  0,           0 }
        !           564: };
        !           565: 
        !           566: struct finst db_Escb[] = {
        !           567: /*0*/  { "fild",   WORD,  0,           0 },
        !           568: /*1*/  { "",       NONE,  0,           0 },
        !           569: /*2*/  { "fist",   WORD,  0,           0 },
        !           570: /*3*/  { "fistp",  WORD,  0,           0 },
        !           571: /*4*/  { "",       WORD,  op1(X),      (char *)db_Escb4 },
        !           572: /*5*/  { "fld",    EXTR,  0,           0 },
        !           573: /*6*/  { "",       WORD,  0,           0 },
        !           574: /*7*/  { "fstp",   EXTR,  0,           0 },
        !           575: };
        !           576: 
        !           577: struct finst db_Escc[] = {
        !           578: /*0*/  { "fadd",   DBLR,  op2(ST,STI), 0 },
        !           579: /*1*/  { "fmul",   DBLR,  op2(ST,STI), 0 },
        !           580: /*2*/  { "fcom",   DBLR,  op2(ST,STI), 0 },
        !           581: /*3*/  { "fcomp",  DBLR,  op2(ST,STI), 0 },
        !           582: /*4*/  { "fsub",   DBLR,  op2(ST,STI), "fsubr" },
        !           583: /*5*/  { "fsubr",  DBLR,  op2(ST,STI), "fsub" },
        !           584: /*6*/  { "fdiv",   DBLR,  op2(ST,STI), "fdivr" },
        !           585: /*7*/  { "fdivr",  DBLR,  op2(ST,STI), "fdiv" },
        !           586: };
        !           587: 
        !           588: struct finst db_Escd[] = {
        !           589: /*0*/  { "fld",    DBLR,  op1(STI),    "ffree" },
        !           590: /*1*/  { "",       NONE,  0,           0 },
        !           591: /*2*/  { "fst",    DBLR,  op1(STI),    0 },
        !           592: /*3*/  { "fstp",   DBLR,  op1(STI),    0 },
        !           593: /*4*/  { "frstor", NONE,  op1(STI),    "fucom" },
        !           594: /*5*/  { "",       NONE,  op1(STI),    "fucomp" },
        !           595: /*6*/  { "fnsave", NONE,  0,           0 },
        !           596: /*7*/  { "fnstsw", NONE,  0,           0 },
        !           597: };
        !           598: 
        !           599: struct finst db_Esce[] = {
        !           600: /*0*/  { "fiadd",  LONG,  op2(ST,STI), "faddp" },
        !           601: /*1*/  { "fimul",  LONG,  op2(ST,STI), "fmulp" },
        !           602: /*2*/  { "ficom",  LONG,  0,           0 },
        !           603: /*3*/  { "ficomp", LONG,  op1(X),      (char *)db_Esce3 },
        !           604: /*4*/  { "fisub",  LONG,  op2(ST,STI), "fsubrp" },
        !           605: /*5*/  { "fisubr", LONG,  op2(ST,STI), "fsubp" },
        !           606: /*6*/  { "fidiv",  LONG,  op2(ST,STI), "fdivrp" },
        !           607: /*7*/  { "fidivr", LONG,  op2(ST,STI), "fdivp" },
        !           608: };
        !           609: 
        !           610: struct finst db_Escf[] = {
        !           611: /*0*/  { "fild",   LONG,  0,           0 },
        !           612: /*1*/  { "",       LONG,  0,           0 },
        !           613: /*2*/  { "fist",   LONG,  0,           0 },
        !           614: /*3*/  { "fistp",  LONG,  0,           0 },
        !           615: /*4*/  { "fbld",   NONE,  op1(XA),     (char *)db_Escf4 },
        !           616: /*5*/  { "fld",    QUAD,  0,           0 },
        !           617: /*6*/  { "fbstp",  NONE,  0,           0 },
        !           618: /*7*/  { "fstp",   QUAD,  0,           0 },
        !           619: };
        !           620: 
        !           621: struct finst *db_Esc_inst[] = {
        !           622:        db_Esc8, db_Esc9, db_Esca, db_Escb,
        !           623:        db_Escc, db_Escd, db_Esce, db_Escf
        !           624: };
        !           625: 
        !           626: char * db_Grp1[] = {
        !           627:        "add",
        !           628:        "or",
        !           629:        "adc",
        !           630:        "sbb",
        !           631:        "and",
        !           632:        "sub",
        !           633:        "xor",
        !           634:        "cmp"
        !           635: };
        !           636: 
        !           637: char * db_Grp2[] = {
        !           638:        "rol",
        !           639:        "ror",
        !           640:        "rcl",
        !           641:        "rcr",
        !           642:        "shl",
        !           643:        "shr",
        !           644:        "shl",
        !           645:        "sar"
        !           646: };
        !           647: 
        !           648: struct inst db_Grp3[] = {
        !           649:        { "test",  TRUE, NONE, op2(I,E), 0 },
        !           650:        { "test",  TRUE, NONE, op2(I,E), 0 },
        !           651:        { "not",   TRUE, NONE, op1(E),   0 },
        !           652:        { "neg",   TRUE, NONE, op1(E),   0 },
        !           653:        { "mul",   TRUE, NONE, op2(E,A), 0 },
        !           654:        { "imul",  TRUE, NONE, op2(E,A), 0 },
        !           655:        { "div",   TRUE, NONE, op2(E,A), 0 },
        !           656:        { "idiv",  TRUE, NONE, op2(E,A), 0 },
        !           657: };
        !           658: 
        !           659: struct inst    db_Grp4[] = {
        !           660:        { "inc",   TRUE, BYTE, op1(E),   0 },
        !           661:        { "dec",   TRUE, BYTE, op1(E),   0 },
        !           662:        { "",      TRUE, NONE, 0,        0 },
        !           663:        { "",      TRUE, NONE, 0,        0 },
        !           664:        { "",      TRUE, NONE, 0,        0 },
        !           665:        { "",      TRUE, NONE, 0,        0 },
        !           666:        { "",      TRUE, NONE, 0,        0 },
        !           667:        { "",      TRUE, NONE, 0,        0 }
        !           668: };
        !           669: 
        !           670: struct inst    db_Grp5[] = {
        !           671:        { "inc",   TRUE, LONG, op1(E),   0 },
        !           672:        { "dec",   TRUE, LONG, op1(E),   0 },
        !           673:        { "call",  TRUE, NONE, op1(Eind),0 },
        !           674:        { "lcall", TRUE, NONE, op1(Eind),0 },
        !           675:        { "jmp",   TRUE, NONE, op1(Eind),0 },
        !           676:        { "ljmp",  TRUE, NONE, op1(Eind),0 },
        !           677:        { "push",  TRUE, LONG, op1(E),   0 },
        !           678:        { "",      TRUE, NONE, 0,        0 }
        !           679: };
        !           680: 
        !           681: struct inst db_inst_table[256] = {
        !           682: /*00*/ { "add",   TRUE,  BYTE,  op2(R, E),  0 },
        !           683: /*01*/ { "add",   TRUE,  LONG,  op2(R, E),  0 },
        !           684: /*02*/ { "add",   TRUE,  BYTE,  op2(E, R),  0 },
        !           685: /*03*/ { "add",   TRUE,  LONG,  op2(E, R),  0 },
        !           686: /*04*/ { "add",   FALSE, BYTE,  op2(Is, A), 0 },
        !           687: /*05*/ { "add",   FALSE, LONG,  op2(Is, A), 0 },
        !           688: /*06*/ { "push",  FALSE, NONE,  op1(Si),    0 },
        !           689: /*07*/ { "pop",   FALSE, NONE,  op1(Si),    0 },
        !           690: 
        !           691: /*08*/ { "or",    TRUE,  BYTE,  op2(R, E),  0 },
        !           692: /*09*/ { "or",    TRUE,  LONG,  op2(R, E),  0 },
        !           693: /*0a*/ { "or",    TRUE,  BYTE,  op2(E, R),  0 },
        !           694: /*0b*/ { "or",    TRUE,  LONG,  op2(E, R),  0 },
        !           695: /*0c*/ { "or",    FALSE, BYTE,  op2(I, A),  0 },
        !           696: /*0d*/ { "or",    FALSE, LONG,  op2(I, A),  0 },
        !           697: /*0e*/ { "push",  FALSE, NONE,  op1(Si),    0 },
        !           698: /*0f*/ { "",      FALSE, NONE,  0,          0 },
        !           699: 
        !           700: /*10*/ { "adc",   TRUE,  BYTE,  op2(R, E),  0 },
        !           701: /*11*/ { "adc",   TRUE,  LONG,  op2(R, E),  0 },
        !           702: /*12*/ { "adc",   TRUE,  BYTE,  op2(E, R),  0 },
        !           703: /*13*/ { "adc",   TRUE,  LONG,  op2(E, R),  0 },
        !           704: /*14*/ { "adc",   FALSE, BYTE,  op2(Is, A), 0 },
        !           705: /*15*/ { "adc",   FALSE, LONG,  op2(Is, A), 0 },
        !           706: /*16*/ { "push",  FALSE, NONE,  op1(Si),    0 },
        !           707: /*17*/ { "pop",   FALSE, NONE,  op1(Si),    0 },
        !           708: 
        !           709: /*18*/ { "sbb",   TRUE,  BYTE,  op2(R, E),  0 },
        !           710: /*19*/ { "sbb",   TRUE,  LONG,  op2(R, E),  0 },
        !           711: /*1a*/ { "sbb",   TRUE,  BYTE,  op2(E, R),  0 },
        !           712: /*1b*/ { "sbb",   TRUE,  LONG,  op2(E, R),  0 },
        !           713: /*1c*/ { "sbb",   FALSE, BYTE,  op2(Is, A), 0 },
        !           714: /*1d*/ { "sbb",   FALSE, LONG,  op2(Is, A), 0 },
        !           715: /*1e*/ { "push",  FALSE, NONE,  op1(Si),    0 },
        !           716: /*1f*/ { "pop",   FALSE, NONE,  op1(Si),    0 },
        !           717: 
        !           718: /*20*/ { "and",   TRUE,  BYTE,  op2(R, E),  0 },
        !           719: /*21*/ { "and",   TRUE,  LONG,  op2(R, E),  0 },
        !           720: /*22*/ { "and",   TRUE,  BYTE,  op2(E, R),  0 },
        !           721: /*23*/ { "and",   TRUE,  LONG,  op2(E, R),  0 },
        !           722: /*24*/ { "and",   FALSE, BYTE,  op2(I, A),  0 },
        !           723: /*25*/ { "and",   FALSE, LONG,  op2(I, A),  0 },
        !           724: /*26*/ { "",      FALSE, NONE,  0,          0 },
        !           725: /*27*/ { "aaa",   FALSE, NONE,  0,          0 },
        !           726: 
        !           727: /*28*/ { "sub",   TRUE,  BYTE,  op2(R, E),  0 },
        !           728: /*29*/ { "sub",   TRUE,  LONG,  op2(R, E),  0 },
        !           729: /*2a*/ { "sub",   TRUE,  BYTE,  op2(E, R),  0 },
        !           730: /*2b*/ { "sub",   TRUE,  LONG,  op2(E, R),  0 },
        !           731: /*2c*/ { "sub",   FALSE, BYTE,  op2(Is, A), 0 },
        !           732: /*2d*/ { "sub",   FALSE, LONG,  op2(Is, A), 0 },
        !           733: /*2e*/ { "",      FALSE, NONE,  0,          0 },
        !           734: /*2f*/ { "das",   FALSE, NONE,  0,          0 },
        !           735: 
        !           736: /*30*/ { "xor",   TRUE,  BYTE,  op2(R, E),  0 },
        !           737: /*31*/ { "xor",   TRUE,  LONG,  op2(R, E),  0 },
        !           738: /*32*/ { "xor",   TRUE,  BYTE,  op2(E, R),  0 },
        !           739: /*33*/ { "xor",   TRUE,  LONG,  op2(E, R),  0 },
        !           740: /*34*/ { "xor",   FALSE, BYTE,  op2(I, A),  0 },
        !           741: /*35*/ { "xor",   FALSE, LONG,  op2(I, A),  0 },
        !           742: /*36*/ { "",      FALSE, NONE,  0,          0 },
        !           743: /*37*/ { "daa",   FALSE, NONE,  0,          0 },
        !           744: 
        !           745: /*38*/ { "cmp",   TRUE,  BYTE,  op2(R, E),  0 },
        !           746: /*39*/ { "cmp",   TRUE,  LONG,  op2(R, E),  0 },
        !           747: /*3a*/ { "cmp",   TRUE,  BYTE,  op2(E, R),  0 },
        !           748: /*3b*/ { "cmp",   TRUE,  LONG,  op2(E, R),  0 },
        !           749: /*3c*/ { "cmp",   FALSE, BYTE,  op2(Is, A), 0 },
        !           750: /*3d*/ { "cmp",   FALSE, LONG,  op2(Is, A), 0 },
        !           751: /*3e*/ { "",      FALSE, NONE,  0,          0 },
        !           752: /*3f*/ { "aas",   FALSE, NONE,  0,          0 },
        !           753: 
        !           754: /*40*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           755: /*41*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           756: /*42*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           757: /*43*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           758: /*44*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           759: /*45*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           760: /*46*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           761: /*47*/ { "inc",   FALSE, LONG,  op1(Ri),    0 },
        !           762: 
        !           763: /*48*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           764: /*49*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           765: /*4a*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           766: /*4b*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           767: /*4c*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           768: /*4d*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           769: /*4e*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           770: /*4f*/ { "dec",   FALSE, LONG,  op1(Ri),    0 },
        !           771: 
        !           772: /*50*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           773: /*51*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           774: /*52*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           775: /*53*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           776: /*54*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           777: /*55*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           778: /*56*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           779: /*57*/ { "push",  FALSE, LONG,  op1(Ri),    0 },
        !           780: 
        !           781: /*58*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           782: /*59*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           783: /*5a*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           784: /*5b*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           785: /*5c*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           786: /*5d*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           787: /*5e*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           788: /*5f*/ { "pop",   FALSE, LONG,  op1(Ri),    0 },
        !           789: 
        !           790: /*60*/ { "pusha", FALSE, LONG,  0,          0 },
        !           791: /*61*/ { "popa",  FALSE, LONG,  0,          0 },
        !           792: /*62*/  { "bound", TRUE,  LONG,  op2(E, R),  0 },
        !           793: /*63*/ { "arpl",  TRUE,  NONE,  op2(Ew,Rw), 0 },
        !           794: 
        !           795: /*64*/ { "",      FALSE, NONE,  0,          0 },
        !           796: /*65*/ { "",      FALSE, NONE,  0,          0 },
        !           797: /*66*/ { "",      FALSE, NONE,  0,          0 },
        !           798: /*67*/ { "",      FALSE, NONE,  0,          0 },
        !           799: 
        !           800: /*68*/ { "push",  FALSE, LONG,  op1(I),     0 },
        !           801: /*69*/  { "imul",  TRUE,  LONG,  op3(I,E,R), 0 },
        !           802: /*6a*/ { "push",  FALSE, LONG,  op1(Ib),    0 },
        !           803: /*6b*/  { "imul",  TRUE,  LONG,  op3(Ibs,E,R),0 },
        !           804: /*6c*/ { "ins",   FALSE, BYTE,  op2(DX, DI), 0 },
        !           805: /*6d*/ { "ins",   FALSE, LONG,  op2(DX, DI), 0 },
        !           806: /*6e*/ { "outs",  FALSE, BYTE,  op2(SI, DX), 0 },
        !           807: /*6f*/ { "outs",  FALSE, LONG,  op2(SI, DX), 0 },
        !           808: 
        !           809: /*70*/ { "jo",    FALSE, NONE,  op1(Db),     0 },
        !           810: /*71*/ { "jno",   FALSE, NONE,  op1(Db),     0 },
        !           811: /*72*/ { "jb",    FALSE, NONE,  op1(Db),     0 },
        !           812: /*73*/ { "jnb",   FALSE, NONE,  op1(Db),     0 },
        !           813: /*74*/ { "jz",    FALSE, NONE,  op1(Db),     0 },
        !           814: /*75*/ { "jnz",   FALSE, NONE,  op1(Db),     0 },
        !           815: /*76*/ { "jbe",   FALSE, NONE,  op1(Db),     0 },
        !           816: /*77*/ { "jnbe",  FALSE, NONE,  op1(Db),     0 },
        !           817: 
        !           818: /*78*/ { "js",    FALSE, NONE,  op1(Db),     0 },
        !           819: /*79*/ { "jns",   FALSE, NONE,  op1(Db),     0 },
        !           820: /*7a*/ { "jp",    FALSE, NONE,  op1(Db),     0 },
        !           821: /*7b*/ { "jnp",   FALSE, NONE,  op1(Db),     0 },
        !           822: /*7c*/ { "jl",    FALSE, NONE,  op1(Db),     0 },
        !           823: /*7d*/ { "jnl",   FALSE, NONE,  op1(Db),     0 },
        !           824: /*7e*/ { "jle",   FALSE, NONE,  op1(Db),     0 },
        !           825: /*7f*/ { "jnle",  FALSE, NONE,  op1(Db),     0 },
        !           826: 
        !           827: /*80*/  { "",     TRUE,  BYTE,  op2(I, E),   (char *)db_Grp1 },
        !           828: /*81*/  { "",     TRUE,  LONG,  op2(I, E),   (char *)db_Grp1 },
        !           829: /*82*/  { "",     TRUE,  BYTE,  op2(Is,E),   (char *)db_Grp1 },
        !           830: /*83*/  { "",     TRUE,  LONG,  op2(Ibs,E),  (char *)db_Grp1 },
        !           831: /*84*/ { "test",  TRUE,  BYTE,  op2(R, E),   0 },
        !           832: /*85*/ { "test",  TRUE,  LONG,  op2(R, E),   0 },
        !           833: /*86*/ { "xchg",  TRUE,  BYTE,  op2(R, E),   0 },
        !           834: /*87*/ { "xchg",  TRUE,  LONG,  op2(R, E),   0 },
        !           835: 
        !           836: /*88*/ { "mov",   TRUE,  BYTE,  op2(R, E),   0 },
        !           837: /*89*/ { "mov",   TRUE,  LONG,  op2(R, E),   0 },
        !           838: /*8a*/ { "mov",   TRUE,  BYTE,  op2(E, R),   0 },
        !           839: /*8b*/ { "mov",   TRUE,  LONG,  op2(E, R),   0 },
        !           840: /*8c*/  { "mov",   TRUE,  NONE,  op2(S, Ew),  0 },
        !           841: /*8d*/ { "lea",   TRUE,  LONG,  op2(E, R),   0 },
        !           842: /*8e*/ { "mov",   TRUE,  NONE,  op2(Ew, S),  0 },
        !           843: /*8f*/ { "pop",   TRUE,  LONG,  op1(E),      0 },
        !           844: 
        !           845: /*90*/ { "nop",   FALSE, NONE,  0,           0 },
        !           846: /*91*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           847: /*92*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           848: /*93*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           849: /*94*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           850: /*95*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           851: /*96*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           852: /*97*/ { "xchg",  FALSE, LONG,  op2(A, Ri),  0 },
        !           853: 
        !           854: /*98*/ { "cbw",   FALSE, SDEP,  0,           "cwde" }, /* cbw/cwde */
        !           855: /*99*/ { "cwd",   FALSE, SDEP,  0,           "cdq"  }, /* cwd/cdq */
        !           856: /*9a*/ { "lcall", FALSE, NONE,  op1(OS),     0 },
        !           857: /*9b*/ { "wait",  FALSE, NONE,  0,           0 },
        !           858: /*9c*/ { "pushf", FALSE, LONG,  0,           0 },
        !           859: /*9d*/ { "popf",  FALSE, LONG,  0,           0 },
        !           860: /*9e*/ { "sahf",  FALSE, NONE,  0,           0 },
        !           861: /*9f*/ { "lahf",  FALSE, NONE,  0,           0 },
        !           862: 
        !           863: /*a0*/ { "mov",   FALSE, BYTE,  op2(O, A),   0 },
        !           864: /*a1*/ { "mov",   FALSE, LONG,  op2(O, A),   0 },
        !           865: /*a2*/ { "mov",   FALSE, BYTE,  op2(A, O),   0 },
        !           866: /*a3*/ { "mov",   FALSE, LONG,  op2(A, O),   0 },
        !           867: /*a4*/ { "movs",  FALSE, BYTE,  op2(SI,DI),  0 },
        !           868: /*a5*/ { "movs",  FALSE, LONG,  op2(SI,DI),  0 },
        !           869: /*a6*/ { "cmps",  FALSE, BYTE,  op2(SI,DI),  0 },
        !           870: /*a7*/ { "cmps",  FALSE, LONG,  op2(SI,DI),  0 },
        !           871: 
        !           872: /*a8*/ { "test",  FALSE, BYTE,  op2(I, A),   0 },
        !           873: /*a9*/ { "test",  FALSE, LONG,  op2(I, A),   0 },
        !           874: /*aa*/ { "stos",  FALSE, BYTE,  op1(DI),     0 },
        !           875: /*ab*/ { "stos",  FALSE, LONG,  op1(DI),     0 },
        !           876: /*ac*/ { "lods",  FALSE, BYTE,  op1(SI),     0 },
        !           877: /*ad*/ { "lods",  FALSE, LONG,  op1(SI),     0 },
        !           878: /*ae*/ { "scas",  FALSE, BYTE,  op1(SI),     0 },
        !           879: /*af*/ { "scas",  FALSE, LONG,  op1(SI),     0 },
        !           880: 
        !           881: /*b0*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           882: /*b1*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           883: /*b2*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           884: /*b3*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           885: /*b4*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           886: /*b5*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           887: /*b6*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           888: /*b7*/ { "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
        !           889: 
        !           890: /*b8*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           891: /*b9*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           892: /*ba*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           893: /*bb*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           894: /*bc*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           895: /*bd*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           896: /*be*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           897: /*bf*/ { "mov",   FALSE, LONG,  op2(I, Ri),  0 },
        !           898: 
        !           899: /*c0*/ { "",      TRUE,  BYTE,  op2(Ib, E),  (char *)db_Grp2 },
        !           900: /*c1*/ { "",      TRUE,  LONG,  op2(Ib, E),  (char *)db_Grp2 },
        !           901: /*c2*/ { "ret",   FALSE, NONE,  op1(Iw),     0 },
        !           902: /*c3*/ { "ret",   FALSE, NONE,  0,           0 },
        !           903: /*c4*/ { "les",   TRUE,  LONG,  op2(E, R),   0 },
        !           904: /*c5*/ { "lds",   TRUE,  LONG,  op2(E, R),   0 },
        !           905: /*c6*/ { "mov",   TRUE,  BYTE,  op2(I, E),   0 },
        !           906: /*c7*/ { "mov",   TRUE,  LONG,  op2(I, E),   0 },
        !           907: 
        !           908: /*c8*/ { "enter", FALSE, NONE,  op2(Ib, Iw), 0 },
        !           909: /*c9*/ { "leave", FALSE, NONE,  0,           0 },
        !           910: /*ca*/ { "lret",  FALSE, NONE,  op1(Iw),     0 },
        !           911: /*cb*/ { "lret",  FALSE, NONE,  0,           0 },
        !           912: /*cc*/ { "int",   FALSE, NONE,  op1(o3),     0 },
        !           913: /*cd*/ { "int",   FALSE, NONE,  op1(Ib),     0 },
        !           914: /*ce*/ { "into",  FALSE, NONE,  0,           0 },
        !           915: /*cf*/ { "iret",  FALSE, NONE,  0,           0 },
        !           916: 
        !           917: /*d0*/ { "",      TRUE,  BYTE,  op2(o1, E),  (char *)db_Grp2 },
        !           918: /*d1*/ { "",      TRUE,  LONG,  op2(o1, E),  (char *)db_Grp2 },
        !           919: /*d2*/ { "",      TRUE,  BYTE,  op2(CL, E),  (char *)db_Grp2 },
        !           920: /*d3*/ { "",      TRUE,  LONG,  op2(CL, E),  (char *)db_Grp2 },
        !           921: /*d4*/ { "aam",   TRUE,  NONE,  0,           0 },
        !           922: /*d5*/ { "aad",   TRUE,  NONE,  0,           0 },
        !           923: /*d6*/ { "",      FALSE, NONE,  0,           0 },
        !           924: /*d7*/ { "xlat",  FALSE, BYTE,  op1(BX),     0 },
        !           925: 
        !           926: /*d8*/  { "",      TRUE,  NONE,  0,          (char *)db_Esc8 },
        !           927: /*d9*/  { "",      TRUE,  NONE,  0,          (char *)db_Esc9 },
        !           928: /*da*/  { "",      TRUE,  NONE,  0,          (char *)db_Esca },
        !           929: /*db*/  { "",      TRUE,  NONE,  0,          (char *)db_Escb },
        !           930: /*dc*/  { "",      TRUE,  NONE,  0,          (char *)db_Escc },
        !           931: /*dd*/  { "",      TRUE,  NONE,  0,          (char *)db_Escd },
        !           932: /*de*/  { "",      TRUE,  NONE,  0,          (char *)db_Esce },
        !           933: /*df*/  { "",      TRUE,  NONE,  0,          (char *)db_Escf },
        !           934: 
        !           935: /*e0*/ { "loopne",FALSE, NONE,  op1(Db),     0 },
        !           936: /*e1*/ { "loope", FALSE, NONE,  op1(Db),     0 },
        !           937: /*e2*/ { "loop",  FALSE, NONE,  op1(Db),     0 },
        !           938: /*e3*/ { "jcxz",  FALSE, SDEP,  op1(Db),     "jecxz" },
        !           939: /*e4*/ { "in",    FALSE, BYTE,  op2(Ib, A),  0 },
        !           940: /*e5*/ { "in",    FALSE, LONG,  op2(Ib, A) , 0 },
        !           941: /*e6*/ { "out",   FALSE, BYTE,  op2(A, Ib),  0 },
        !           942: /*e7*/ { "out",   FALSE, LONG,  op2(A, Ib) , 0 },
        !           943: 
        !           944: /*e8*/ { "call",  FALSE, NONE,  op1(Dl),     0 },
        !           945: /*e9*/ { "jmp",   FALSE, NONE,  op1(Dl),     0 },
        !           946: /*ea*/ { "ljmp",  FALSE, NONE,  op1(OS),     0 },
        !           947: /*eb*/ { "jmp",   FALSE, NONE,  op1(Db),     0 },
        !           948: /*ec*/ { "in",    FALSE, BYTE,  op2(DX, A),  0 },
        !           949: /*ed*/ { "in",    FALSE, LONG,  op2(DX, A) , 0 },
        !           950: /*ee*/ { "out",   FALSE, BYTE,  op2(A, DX),  0 },
        !           951: /*ef*/ { "out",   FALSE, LONG,  op2(A, DX) , 0 },
        !           952: 
        !           953: /*f0*/ { "",      FALSE, NONE,  0,          0 },
        !           954: /*f1*/ { "",      FALSE, NONE,  0,          0 },
        !           955: /*f2*/ { "",      FALSE, NONE,  0,          0 },
        !           956: /*f3*/ { "",      FALSE, NONE,  0,          0 },
        !           957: /*f4*/ { "hlt",   FALSE, NONE,  0,          0 },
        !           958: /*f5*/ { "cmc",   FALSE, NONE,  0,          0 },
        !           959: /*f6*/ { "",      TRUE,  BYTE,  0,          (char *)db_Grp3 },
        !           960: /*f7*/ { "",      TRUE,  LONG,  0,          (char *)db_Grp3 },
        !           961: 
        !           962: /*f8*/ { "clc",   FALSE, NONE,  0,          0 },
        !           963: /*f9*/ { "stc",   FALSE, NONE,  0,          0 },
        !           964: /*fa*/ { "cli",   FALSE, NONE,  0,          0 },
        !           965: /*fb*/ { "sti",   FALSE, NONE,  0,          0 },
        !           966: /*fc*/ { "cld",   FALSE, NONE,  0,          0 },
        !           967: /*fd*/ { "std",   FALSE, NONE,  0,          0 },
        !           968: /*fe*/ { "",      TRUE,  NONE,  0,          (char *)db_Grp4 },
        !           969: /*ff*/ { "",      TRUE,  NONE,  0,          (char *)db_Grp5 },
        !           970: };
        !           971: 
        !           972: struct inst    db_bad_inst =
        !           973:        { "???",   FALSE, NONE,  0,           0 }
        !           974: ;
        !           975: 
        !           976: #define        f_mod(byte)     ((byte)>>6)
        !           977: #define        f_reg(byte)     (((byte)>>3)&0x7)
        !           978: #define        f_rm(byte)      ((byte)&0x7)
        !           979: 
        !           980: #define        sib_ss(byte)    ((byte)>>6)
        !           981: #define        sib_index(byte) (((byte)>>3)&0x7)
        !           982: #define        sib_base(byte)  ((byte)&0x7)
        !           983: 
        !           984: char * db_index_reg_16[8] = {
        !           985:        "%bx,%si",
        !           986:        "%bx,%di",
        !           987:        "%bp,%si",
        !           988:        "%bp,%di",
        !           989:        "%si",
        !           990:        "%di",
        !           991:        "%bp",
        !           992:        "%bx"
        !           993: };
        !           994: 
        !           995: char * db_reg[3][8] = {
        !           996:        "%al",  "%cl",  "%dl",  "%bl",  "%ah",  "%ch",  "%dh",  "%bh",
        !           997:        "%ax",  "%cx",  "%dx",  "%bx",  "%sp",  "%bp",  "%si",  "%di",
        !           998:        "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
        !           999: };
        !          1000: 
        !          1001: char * db_seg_reg[8] = {
        !          1002:        "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
        !          1003: };
        !          1004: 
        !          1005: /*
        !          1006:  * lengths for size attributes
        !          1007:  */
        !          1008: int db_lengths[] = {
        !          1009:        1,      /* BYTE */
        !          1010:        2,      /* WORD */
        !          1011:        4,      /* LONG */
        !          1012:        8,      /* QUAD */
        !          1013:        4,      /* SNGL */
        !          1014:        8,      /* DBLR */
        !          1015:        10,     /* EXTR */
        !          1016: };
        !          1017: 
        !          1018: #define        get_value_inc(result, loc, size, is_signed, task) \
        !          1019:        result = db_get_task_value((loc), (size), (is_signed), (task)); \
        !          1020:        (loc) += (size);
        !          1021: 
        !          1022: /*
        !          1023:  * Read address at location and return updated location.
        !          1024:  */
        !          1025: db_addr_t
        !          1026: db_read_address(
        !          1027:        db_addr_t       loc,
        !          1028:        int             short_addr,
        !          1029:        int             regmodrm,
        !          1030:        struct i_addr   *addrp,         /* out */
        !          1031:        task_t          task)
        !          1032: {
        !          1033:        int             mod, rm, sib, index, ss, disp;
        !          1034: 
        !          1035:        mod = f_mod(regmodrm);
        !          1036:        rm  = f_rm(regmodrm);
        !          1037: 
        !          1038:        if (mod == 3) {
        !          1039:            addrp->is_reg = TRUE;
        !          1040:            addrp->disp = rm;
        !          1041:            return (loc);
        !          1042:        }
        !          1043:        addrp->is_reg = FALSE;
        !          1044:        addrp->index = 0;
        !          1045: 
        !          1046:        if (short_addr) {
        !          1047:            addrp->index = 0;
        !          1048:            addrp->ss = 0;
        !          1049:            switch (mod) {
        !          1050:                case 0:
        !          1051:                    if (rm == 6) {
        !          1052:                        get_value_inc(disp, loc, 2, TRUE, task);
        !          1053:                        addrp->disp = disp;
        !          1054:                        addrp->base = 0;
        !          1055:                    }
        !          1056:                    else {
        !          1057:                        addrp->disp = 0;
        !          1058:                        addrp->base = db_index_reg_16[rm];
        !          1059:                    }
        !          1060:                    break;
        !          1061:                case 1:
        !          1062:                    get_value_inc(disp, loc, 1, TRUE, task);
        !          1063:                    addrp->disp = disp;
        !          1064:                    addrp->base = db_index_reg_16[rm];
        !          1065:                    break;
        !          1066:                case 2:
        !          1067:                    get_value_inc(disp, loc, 2, TRUE, task);
        !          1068:                    addrp->disp = disp;
        !          1069:                    addrp->base = db_index_reg_16[rm];
        !          1070:                    break;
        !          1071:            }
        !          1072:        }
        !          1073:        else {
        !          1074:            if (mod != 3 && rm == 4) {
        !          1075:                get_value_inc(sib, loc, 1, FALSE, task);
        !          1076:                rm = sib_base(sib);
        !          1077:                index = sib_index(sib);
        !          1078:                if (index != 4)
        !          1079:                    addrp->index = db_reg[LONG][index];
        !          1080:                addrp->ss = sib_ss(sib);
        !          1081:            }
        !          1082: 
        !          1083:            switch (mod) {
        !          1084:                case 0:
        !          1085:                    if (rm == 5) {
        !          1086:                        get_value_inc(addrp->disp, loc, 4, FALSE, task);
        !          1087:                        addrp->base = 0;
        !          1088:                    }
        !          1089:                    else {
        !          1090:                        addrp->disp = 0;
        !          1091:                        addrp->base = db_reg[LONG][rm];
        !          1092:                    }
        !          1093:                    break;
        !          1094: 
        !          1095:                case 1:
        !          1096:                    get_value_inc(disp, loc, 1, TRUE, task);
        !          1097:                    addrp->disp = disp;
        !          1098:                    addrp->base = db_reg[LONG][rm];
        !          1099:                    break;
        !          1100: 
        !          1101:                case 2:
        !          1102:                    get_value_inc(disp, loc, 4, FALSE, task);
        !          1103:                    addrp->disp = disp;
        !          1104:                    addrp->base = db_reg[LONG][rm];
        !          1105:                    break;
        !          1106:            }
        !          1107:        }
        !          1108:        return (loc);
        !          1109: }
        !          1110: 
        !          1111: void
        !          1112: db_print_address(
        !          1113:        char *          seg,
        !          1114:        int             size,
        !          1115:        struct i_addr   *addrp,
        !          1116:        task_t          task)
        !          1117: {
        !          1118:        if (addrp->is_reg) {
        !          1119:            db_printf("%s", db_reg[size][addrp->disp]);
        !          1120:            return;
        !          1121:        }
        !          1122: 
        !          1123:        if (seg) {
        !          1124:            db_printf("%s:", seg);
        !          1125:        }
        !          1126: 
        !          1127:        if (addrp->base != 0 || addrp->index != 0) {
        !          1128:            db_printf("%#n", addrp->disp);
        !          1129:            db_printf("(");
        !          1130:            if (addrp->base)
        !          1131:                db_printf("%s", addrp->base);
        !          1132:            if (addrp->index)
        !          1133:                db_printf(",%s,%d", addrp->index, 1<<addrp->ss);
        !          1134:            db_printf(")");
        !          1135:        } else
        !          1136:            db_task_printsym((db_addr_t)addrp->disp, DB_STGY_ANY, task);
        !          1137: }
        !          1138: 
        !          1139: /*
        !          1140:  * Disassemble floating-point ("escape") instruction
        !          1141:  * and return updated location.
        !          1142:  */
        !          1143: db_addr_t
        !          1144: db_disasm_esc(
        !          1145:        db_addr_t       loc,
        !          1146:        int             inst,
        !          1147:        int             short_addr,
        !          1148:        int             size,
        !          1149:        char *          seg,
        !          1150:        task_t          task)
        !          1151: {
        !          1152:        int             regmodrm;
        !          1153:        struct finst    *fp;
        !          1154:        int             mod;
        !          1155:        struct i_addr   address;
        !          1156:        char *          name;
        !          1157: 
        !          1158:        get_value_inc(regmodrm, loc, 1, FALSE, task);
        !          1159:        fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)];
        !          1160:        mod = f_mod(regmodrm);
        !          1161:        if (mod != 3) {
        !          1162:            /*
        !          1163:             * Normal address modes.
        !          1164:             */
        !          1165:            loc = db_read_address(loc, short_addr, regmodrm, &address, task);
        !          1166:            db_printf(fp->f_name);
        !          1167:            switch(fp->f_size) {
        !          1168:                case SNGL:
        !          1169:                    db_printf("s");
        !          1170:                    break;
        !          1171:                case DBLR:
        !          1172:                    db_printf("l");
        !          1173:                    break;
        !          1174:                case EXTR:
        !          1175:                    db_printf("t");
        !          1176:                    break;
        !          1177:                case WORD:
        !          1178:                    db_printf("s");
        !          1179:                    break;
        !          1180:                case LONG:
        !          1181:                    db_printf("l");
        !          1182:                    break;
        !          1183:                case QUAD:
        !          1184:                    db_printf("q");
        !          1185:                    break;
        !          1186:                default:
        !          1187:                    break;
        !          1188:            }
        !          1189:            db_printf("\t");
        !          1190:            db_print_address(seg, BYTE, &address, task);
        !          1191:        }
        !          1192:        else {
        !          1193:            /*
        !          1194:             * 'reg-reg' - special formats
        !          1195:             */
        !          1196:            switch (fp->f_rrmode) {
        !          1197:                case op2(ST,STI):
        !          1198:                    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
        !          1199:                    db_printf("%s\t%%st,%%st(%d)",name,f_rm(regmodrm));
        !          1200:                    break;
        !          1201:                case op2(STI,ST):
        !          1202:                    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
        !          1203:                    db_printf("%s\t%%st(%d),%%st",name, f_rm(regmodrm));
        !          1204:                    break;
        !          1205:                case op1(STI):
        !          1206:                    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
        !          1207:                    db_printf("%s\t%%st(%d)",name, f_rm(regmodrm));
        !          1208:                    break;
        !          1209:                case op1(X):
        !          1210:                    db_printf("%s", ((char **)fp->f_rrname)[f_rm(regmodrm)]);
        !          1211:                    break;
        !          1212:                case op1(XA):
        !          1213:                    db_printf("%s\t%%ax",
        !          1214:                                 ((char **)fp->f_rrname)[f_rm(regmodrm)]);
        !          1215:                    break;
        !          1216:                default:
        !          1217:                    db_printf("<bad instruction>");
        !          1218:                    break;
        !          1219:            }
        !          1220:        }
        !          1221: 
        !          1222:        return (loc);
        !          1223: }
        !          1224: 
        !          1225: /*
        !          1226:  * Disassemble instruction at 'loc'.  'altfmt' specifies an
        !          1227:  * (optional) alternate format.  Return address of start of
        !          1228:  * next instruction.
        !          1229:  */
        !          1230: db_addr_t
        !          1231: db_disasm(
        !          1232:        db_addr_t       loc,
        !          1233:        boolean_t       altfmt,
        !          1234:        task_t          task)
        !          1235: {
        !          1236:        int     inst;
        !          1237:        int     size;
        !          1238:        int     short_addr;
        !          1239:        char *  seg;
        !          1240:        struct inst *   ip;
        !          1241:        char *  i_name;
        !          1242:        int     i_size;
        !          1243:        int     i_mode;
        !          1244:        int     regmodrm;
        !          1245:        boolean_t       first;
        !          1246:        int     displ;
        !          1247:        int     prefix;
        !          1248:        int     imm;
        !          1249:        int     imm2;
        !          1250:        int     len;
        !          1251:        struct i_addr   address;
        !          1252:        char    *filename;
        !          1253:        int     linenum;
        !          1254: 
        !          1255:        get_value_inc(inst, loc, 1, FALSE, task);
        !          1256:        if (db_disasm_16) {
        !          1257:            short_addr = TRUE;
        !          1258:            size = WORD;
        !          1259:        }
        !          1260:        else {
        !          1261:            short_addr = FALSE;
        !          1262:            size = LONG;
        !          1263:        }
        !          1264:        seg = 0;
        !          1265: 
        !          1266:        /*
        !          1267:         * Get prefixes
        !          1268:         */
        !          1269:        prefix = TRUE;
        !          1270:        do {
        !          1271:            switch (inst) {
        !          1272:                case 0x66:              /* data16 */
        !          1273:                    if (size == LONG)
        !          1274:                        size = WORD;
        !          1275:                    else
        !          1276:                        size = LONG;
        !          1277:                    break;
        !          1278:                case 0x67:
        !          1279:                    short_addr = !short_addr;
        !          1280:                    break;
        !          1281:                case 0x26:
        !          1282:                    seg = "%es";
        !          1283:                    break;
        !          1284:                case 0x36:
        !          1285:                    seg = "%ss";
        !          1286:                    break;
        !          1287:                case 0x2e:
        !          1288:                    seg = "%cs";
        !          1289:                    break;
        !          1290:                case 0x3e:
        !          1291:                    seg = "%ds";
        !          1292:                    break;
        !          1293:                case 0x64:
        !          1294:                    seg = "%fs";
        !          1295:                    break;
        !          1296:                case 0x65:
        !          1297:                    seg = "%gs";
        !          1298:                    break;
        !          1299:                case 0xf0:
        !          1300:                    db_printf("lock ");
        !          1301:                    break;
        !          1302:                case 0xf2:
        !          1303:                    db_printf("repne ");
        !          1304:                    break;
        !          1305:                case 0xf3:
        !          1306:                    db_printf("repe "); /* XXX repe VS rep */
        !          1307:                    break;
        !          1308:                default:
        !          1309:                    prefix = FALSE;
        !          1310:                    break;
        !          1311:            }
        !          1312:            if (prefix) {
        !          1313:                get_value_inc(inst, loc, 1, FALSE, task);
        !          1314:            }
        !          1315:        } while (prefix);
        !          1316: 
        !          1317:        if (inst >= 0xd8 && inst <= 0xdf) {
        !          1318:            loc = db_disasm_esc(loc, inst, short_addr, size, seg, task);
        !          1319:            db_printf("\n");
        !          1320:            return (loc);
        !          1321:        }
        !          1322: 
        !          1323:        if (inst == 0x0f) {
        !          1324:            get_value_inc(inst, loc, 1, FALSE, task);
        !          1325:            ip = db_inst_0f[inst>>4];
        !          1326:            if (ip == 0) {
        !          1327:                ip = &db_bad_inst;
        !          1328:            }
        !          1329:            else {
        !          1330:                ip = &ip[inst&0xf];
        !          1331:            }
        !          1332:        }
        !          1333:        else
        !          1334:            ip = &db_inst_table[inst];
        !          1335: 
        !          1336:        if (ip->i_has_modrm) {
        !          1337:            get_value_inc(regmodrm, loc, 1, FALSE, task);
        !          1338:            loc = db_read_address(loc, short_addr, regmodrm, &address, task);
        !          1339:        }
        !          1340: 
        !          1341:        i_name = ip->i_name;
        !          1342:        i_size = ip->i_size;
        !          1343:        i_mode = ip->i_mode;
        !          1344: 
        !          1345:        if (ip->i_extra == (char *)db_Grp1 ||
        !          1346:            ip->i_extra == (char *)db_Grp2 ||
        !          1347:            ip->i_extra == (char *)db_Grp6 ||
        !          1348:            ip->i_extra == (char *)db_Grp7 ||
        !          1349:            ip->i_extra == (char *)db_Grp8) {
        !          1350:            i_name = ((char **)ip->i_extra)[f_reg(regmodrm)];
        !          1351:        }
        !          1352:        else if (ip->i_extra == (char *)db_Grp3) {
        !          1353:            ip = (struct inst *)ip->i_extra;
        !          1354:            ip = &ip[f_reg(regmodrm)];
        !          1355:            i_name = ip->i_name;
        !          1356:            i_mode = ip->i_mode;
        !          1357:        }
        !          1358:        else if (ip->i_extra == (char *)db_Grp4 ||
        !          1359:                 ip->i_extra == (char *)db_Grp5) {
        !          1360:            ip = (struct inst *)ip->i_extra;
        !          1361:            ip = &ip[f_reg(regmodrm)];
        !          1362:            i_name = ip->i_name;
        !          1363:            i_mode = ip->i_mode;
        !          1364:            i_size = ip->i_size;
        !          1365:        }
        !          1366: 
        !          1367:        if (i_size == SDEP) {
        !          1368:            if (size == WORD)
        !          1369:                db_printf(i_name);
        !          1370:            else
        !          1371:                db_printf(ip->i_extra);
        !          1372:        }
        !          1373:        else {
        !          1374:            db_printf(i_name);
        !          1375:            if (i_size != NONE) {
        !          1376:                if (i_size == BYTE) {
        !          1377:                    db_printf("b");
        !          1378:                    size = BYTE;
        !          1379:                }
        !          1380:                else if (i_size == WORD) {
        !          1381:                    db_printf("w");
        !          1382:                    size = WORD;
        !          1383:                }
        !          1384:                else if (size == WORD)
        !          1385:                    db_printf("w");
        !          1386:                else
        !          1387:                    db_printf("l");
        !          1388:            }
        !          1389:        }
        !          1390:        db_printf("\t");
        !          1391:        for (first = TRUE;
        !          1392:             i_mode != 0;
        !          1393:             i_mode >>= 8, first = FALSE)
        !          1394:        {
        !          1395:            if (!first)
        !          1396:                db_printf(",");
        !          1397: 
        !          1398:            switch (i_mode & 0xFF) {
        !          1399: 
        !          1400:                case E:
        !          1401:                    db_print_address(seg, size, &address, task);
        !          1402:                    break;
        !          1403: 
        !          1404:                case Eind:
        !          1405:                    db_printf("*");
        !          1406:                    db_print_address(seg, size, &address, task);
        !          1407:                    break;
        !          1408: 
        !          1409:                case Ew:
        !          1410:                    db_print_address(seg, WORD, &address, task);
        !          1411:                    break;
        !          1412: 
        !          1413:                case Eb:
        !          1414:                    db_print_address(seg, BYTE, &address, task);
        !          1415:                    break;
        !          1416: 
        !          1417:                case R:
        !          1418:                    db_printf("%s", db_reg[size][f_reg(regmodrm)]);
        !          1419:                    break;
        !          1420: 
        !          1421:                case Rw:
        !          1422:                    db_printf("%s", db_reg[WORD][f_reg(regmodrm)]);
        !          1423:                    break;
        !          1424: 
        !          1425:                case Ri:
        !          1426:                    db_printf("%s", db_reg[size][f_rm(inst)]);
        !          1427:                    break;
        !          1428: 
        !          1429:                case S:
        !          1430:                    db_printf("%s", db_seg_reg[f_reg(regmodrm)]);
        !          1431:                    break;
        !          1432: 
        !          1433:                case Si:
        !          1434:                    db_printf("%s", db_seg_reg[f_reg(inst)]);
        !          1435:                    break;
        !          1436: 
        !          1437:                case A:
        !          1438:                    db_printf("%s", db_reg[size][0]);   /* acc */
        !          1439:                    break;
        !          1440: 
        !          1441:                case BX:
        !          1442:                    if (seg)
        !          1443:                        db_printf("%s:", seg);
        !          1444:                    db_printf("(%s)", short_addr ? "%bx" : "%ebx");
        !          1445:                    break;
        !          1446: 
        !          1447:                case CL:
        !          1448:                    db_printf("%%cl");
        !          1449:                    break;
        !          1450: 
        !          1451:                case DX:
        !          1452:                    db_printf("%%dx");
        !          1453:                    break;
        !          1454: 
        !          1455:                case SI:
        !          1456:                    if (seg)
        !          1457:                        db_printf("%s:", seg);
        !          1458:                    db_printf("(%s)", short_addr ? "%si" : "%esi");
        !          1459:                    break;
        !          1460: 
        !          1461:                case DI:
        !          1462:                    db_printf("%%es:(%s)", short_addr ? "%di" : "%edi");
        !          1463:                    break;
        !          1464: 
        !          1465:                case CR:
        !          1466:                    db_printf("%%cr%d", f_reg(regmodrm));
        !          1467:                    break;
        !          1468: 
        !          1469:                case DR:
        !          1470:                    db_printf("%%dr%d", f_reg(regmodrm));
        !          1471:                    break;
        !          1472: 
        !          1473:                case TR:
        !          1474:                    db_printf("%%tr%d", f_reg(regmodrm));
        !          1475:                    break;
        !          1476: 
        !          1477:                case I:
        !          1478:                    len = db_lengths[size];
        !          1479:                    get_value_inc(imm, loc, len, FALSE, task);/* unsigned */
        !          1480:                    db_printf("$%#n", imm);
        !          1481:                    break;
        !          1482: 
        !          1483:                case Is:
        !          1484:                    len = db_lengths[size];
        !          1485:                    get_value_inc(imm, loc, len, TRUE, task);   /* signed */
        !          1486:                    db_printf("$%#r", imm);
        !          1487:                    break;
        !          1488: 
        !          1489:                case Ib:
        !          1490:                    get_value_inc(imm, loc, 1, FALSE, task);    /* unsigned */
        !          1491:                    db_printf("$%#n", imm);
        !          1492:                    break;
        !          1493: 
        !          1494:                case Ibs:
        !          1495:                    get_value_inc(imm, loc, 1, TRUE, task);     /* signed */
        !          1496:                    db_printf("$%#r", imm);
        !          1497:                    break;
        !          1498: 
        !          1499:                case Iw:
        !          1500:                    get_value_inc(imm, loc, 2, FALSE, task);    /* unsigned */
        !          1501:                    db_printf("$%#n", imm);
        !          1502:                    break;
        !          1503: 
        !          1504:                case Il:
        !          1505:                    get_value_inc(imm, loc, 4, FALSE, task);
        !          1506:                    db_printf("$%#n", imm);
        !          1507:                    break;
        !          1508: 
        !          1509:                case O:
        !          1510:                    if (short_addr) {
        !          1511:                        get_value_inc(displ, loc, 2, TRUE, task);
        !          1512:                    }
        !          1513:                    else {
        !          1514:                        get_value_inc(displ, loc, 4, TRUE, task);
        !          1515:                    }
        !          1516:                    if (seg)
        !          1517:                        db_printf("%s:%#r",seg, displ);
        !          1518:                    else
        !          1519:                        db_task_printsym((db_addr_t)displ, DB_STGY_ANY, task);
        !          1520:                    break;
        !          1521: 
        !          1522:                case Db:
        !          1523:                    get_value_inc(displ, loc, 1, TRUE, task);
        !          1524:                    if (short_addr) {
        !          1525:                        /* offset only affects low 16 bits */
        !          1526:                        displ = (loc & 0xffff0000)
        !          1527:                              | ((loc + displ) & 0xffff);
        !          1528:                    }
        !          1529:                    else
        !          1530:                        displ = displ + loc;
        !          1531:                    db_task_printsym((db_addr_t)displ,DB_STGY_ANY,task);
        !          1532:                    if (db_line_at_pc(0, &filename, &linenum, displ)) {
        !          1533:                        db_printf(" [%s", filename);
        !          1534:                        if (linenum > 0)
        !          1535:                            db_printf(":%d", linenum);
        !          1536:                        db_printf("]");
        !          1537:                    }
        !          1538:                    break;
        !          1539: 
        !          1540:                case Dl:
        !          1541:                    if (short_addr) {
        !          1542:                        get_value_inc(displ, loc, 2, TRUE, task);
        !          1543:                        /* offset only affects low 16 bits */
        !          1544:                        displ = (loc & 0xffff0000)
        !          1545:                              | ((loc + displ) & 0xffff);
        !          1546:                    }
        !          1547:                    else {
        !          1548:                        get_value_inc(displ, loc, 4, TRUE, task);
        !          1549:                        displ = displ + loc;
        !          1550:                    }
        !          1551:                    db_task_printsym((db_addr_t)displ, DB_STGY_ANY, task);
        !          1552:                    if (db_line_at_pc(0, &filename, &linenum, displ)) {
        !          1553:                        db_printf(" [%s", filename);
        !          1554:                        if (linenum > 0)
        !          1555:                            db_printf(":%d", linenum);
        !          1556:                        db_printf("]");
        !          1557:                    }
        !          1558:                    break;
        !          1559: 
        !          1560:                case o1:
        !          1561:                    db_printf("$1");
        !          1562:                    break;
        !          1563: 
        !          1564:                case o3:
        !          1565:                    db_printf("$3");
        !          1566:                    break;
        !          1567: 
        !          1568:                case OS:
        !          1569:                    if (short_addr) {
        !          1570:                        get_value_inc(imm, loc, 2, FALSE, task); /* offset */
        !          1571:                    }
        !          1572:                    else {
        !          1573:                        get_value_inc(imm, loc, 4, FALSE, task); /* offset */
        !          1574:                    }
        !          1575:                    get_value_inc(imm2, loc, 2, FALSE, task);   /* segment */
        !          1576:                    db_printf("$%#n,%#n", imm2, imm);
        !          1577:                    break;
        !          1578:            }
        !          1579:        }
        !          1580: 
        !          1581:        if (altfmt == 0 && !db_disasm_16) {
        !          1582:            if (inst == 0xe9 || inst == 0xeb) { /* jmp, Dl or Db */
        !          1583:                /*
        !          1584:                 * GAS pads to longword boundary after unconditional jumps.
        !          1585:                 */
        !          1586:                while (loc & (4-1)) {
        !          1587:                    get_value_inc(inst, loc, 0, FALSE, task);
        !          1588:                    if (inst != 0x90)   /* nop */
        !          1589:                        break;
        !          1590:                    loc++;
        !          1591:                }
        !          1592:            }
        !          1593:        }
        !          1594:        db_printf("\n");
        !          1595:        return (loc);
        !          1596: }
        !          1597: 
        !          1598: /*
        !          1599:  * Classify instructions by whether they read or write memory.
        !          1600:  */
        !          1601: 
        !          1602: #define        DBLS_LOAD       0x01    /* instruction reads from memory */
        !          1603: #define        DBLS_STORE      0x02    /* instruction writes to memory */
        !          1604: 
        !          1605: #define DBLS_MODRM     0x10    /* instruction uses mod r/m byte */
        !          1606: #define        DBLS_SECOND     0x20    /* instruction does two operations */
        !          1607: #define        DBLS_ESCAPE     0x40    /* escape to two-byte opcodes */
        !          1608: #define DBLS_SWREG     0x80    /* need to switch on reg bits of mod r/m */
        !          1609: 
        !          1610: #define DBLS_MODS      0xf0
        !          1611: #define DBLS_LMASK     (DBLS_MODS|DBLS_LOAD)
        !          1612: #define DBLS_SMASK     (DBLS_MODS|DBLS_STORE)
        !          1613: 
        !          1614: char db_ldstrtab[] = {
        !          1615:        0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
        !          1616:                0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x40,
        !          1617:        0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
        !          1618:                0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
        !          1619:        0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
        !          1620:                0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
        !          1621:        0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
        !          1622:                0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
        !          1623: 
        !          1624:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1625:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1626:        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !          1627:                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        !          1628:        0x02, 0x01, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
        !          1629:                0x02, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1630:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1631:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1632: 
        !          1633:        0x12, 0x12, 0x00, 0x12, 0x11, 0x11, 0x13, 0x13,
        !          1634:                0x12, 0x12, 0x11, 0x11, 0x12, 0x00, 0x11, 0x03,
        !          1635:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1636:                0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x00,
        !          1637:        0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x21, 0x21,
        !          1638:                0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
        !          1639:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1640:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1641: 
        !          1642:        0x13, 0x13, 0x00, 0x00, 0x01, 0x01, 0x12, 0x12,
        !          1643:                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1644:        0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x01,
        !          1645:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1646:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1647:                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1648:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
        !          1649:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
        !          1650: };
        !          1651: 
        !          1652: unsigned char db_ldstrtab0f[] = {
        !          1653:        0x80, 0x80, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
        !          1654:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1655:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1656:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1657:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1658:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1659:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1660:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1661: 
        !          1662:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1663:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1664:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1665:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1666:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1667:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1668:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1669:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1670: 
        !          1671:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1672:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1673:        0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
        !          1674:                0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
        !          1675:        0x02, 0x01, 0x00, 0x11, 0x13, 0x13, 0x00, 0x00,
        !          1676:                0x02, 0x01, 0x12, 0x13, 0x13, 0x13, 0x00, 0x11,
        !          1677:        0x00, 0x00, 0x01, 0x13, 0x01, 0x01, 0x11, 0x11,
        !          1678:                0x00, 0x00, 0x80, 0x13, 0x13, 0x13, 0x11, 0x11,
        !          1679: 
        !          1680:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1681:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1682:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1683:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1684:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1685:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1686:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1687:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          1688: };
        !          1689: 
        !          1690: int db_inst_swreg(boolean_t, unsigned long, unsigned char);
        !          1691: 
        !          1692: /*
        !          1693:  * Given four bytes of instruction (stored as an int, not an
        !          1694:  * array of characters), compute if the instruction reads
        !          1695:  * memory.
        !          1696:  */
        !          1697: int
        !          1698: db_inst_load(
        !          1699:        unsigned long insw)
        !          1700: {
        !          1701:        unsigned char insb, bits;
        !          1702: 
        !          1703:        insb = insw & 0xff;
        !          1704:        insw >>= 8;
        !          1705:        bits = db_ldstrtab[insb];
        !          1706:        if (!(bits & DBLS_LOAD))
        !          1707:                return (0);
        !          1708:        while (1) {
        !          1709:                switch (bits & DBLS_MODS) {
        !          1710:                case 0:
        !          1711:                        return (1);     
        !          1712:                case DBLS_MODRM:
        !          1713:                        insb = insw & 0xff;
        !          1714:                        return ((insb & 0xc0) != 0xc0);
        !          1715:                case DBLS_SECOND|DBLS_MODRM:
        !          1716:                        insb = insw & 0xff;
        !          1717:                        return ((insb & 0xc0) != 0xc0 ? 2 : 0);
        !          1718:                case DBLS_SECOND:
        !          1719:                        return (2);
        !          1720:                case DBLS_ESCAPE:
        !          1721:                        insb = insw & 0xff;
        !          1722:                        insw >>= 8;
        !          1723:                        bits = db_ldstrtab0f[insb];
        !          1724:                        break;
        !          1725:                case DBLS_SWREG:
        !          1726:                        return (db_inst_swreg(TRUE, insw, insb));
        !          1727:                default:
        !          1728:                        panic ("db_inst_load: unknown mod bits");
        !          1729:                }
        !          1730:        }
        !          1731: }
        !          1732: 
        !          1733: /*
        !          1734:  * Given four bytes of instruction (stored as an int, not an
        !          1735:  * array of characters), compute if the instruction writes
        !          1736:  * memory.
        !          1737:  */
        !          1738: int
        !          1739: db_inst_store(
        !          1740:        unsigned long insw)
        !          1741: {
        !          1742:        unsigned char insb, bits;
        !          1743: 
        !          1744:        insb = insw & 0xff;
        !          1745:        insw >>= 8;
        !          1746:        bits = db_ldstrtab[insb];
        !          1747:        if (!(bits & DBLS_STORE))
        !          1748:                return (0);
        !          1749:        while (1) {
        !          1750:                switch (bits & DBLS_MODS) {
        !          1751:                case 0:
        !          1752:                        return (1);     
        !          1753:                case DBLS_MODRM:
        !          1754:                        insb = insw & 0xff;
        !          1755:                        return ((insb & 0xc0) != 0xc0);
        !          1756:                case DBLS_SECOND|DBLS_MODRM:
        !          1757:                        insb = insw & 0xff;
        !          1758:                        return ((insb & 0xc0) != 0xc0 ? 2 : 0);
        !          1759:                case DBLS_SECOND:
        !          1760:                        return (2);
        !          1761:                case DBLS_ESCAPE:
        !          1762:                        insb = insw & 0xff;
        !          1763:                        insw >>= 8;
        !          1764:                        bits = db_ldstrtab0f[insb];
        !          1765:                        break;
        !          1766:                case DBLS_SWREG:
        !          1767:                        return (db_inst_swreg(FALSE, insw, insb));
        !          1768:                default:
        !          1769:                        panic ("db_inst_store: unknown mod bits");
        !          1770:                }
        !          1771:        }
        !          1772: }
        !          1773: 
        !          1774: /*
        !          1775:  * Parse a mod r/m byte to see if extended opcode reads
        !          1776:  * or writes memory.
        !          1777:  */
        !          1778: int
        !          1779: db_inst_swreg(
        !          1780:        boolean_t isload,
        !          1781:        unsigned long insw,
        !          1782:        unsigned char insb)
        !          1783: {
        !          1784:        unsigned char modrm = insw & 0xff;
        !          1785: 
        !          1786:        switch (insb) {
        !          1787:        case 0x00:
        !          1788:                switch (modrm & 0x38) {
        !          1789:                case 0x00:
        !          1790:                case 0x08:
        !          1791:                case 0x10:
        !          1792:                case 0x18:
        !          1793:                        return ((modrm & 0xc0) != 0xc0);
        !          1794:                }
        !          1795:                break;
        !          1796:        case 0x01:
        !          1797:                switch (modrm & 0x38) {
        !          1798:                case 0x00:
        !          1799:                case 0x08:
        !          1800:                case 0x10:
        !          1801:                case 0x18:
        !          1802:                        return ((modrm & 0xc0) != 0xc0 ? 2 : 0);
        !          1803:                case 0x20:
        !          1804:                case 0x30:
        !          1805:                        return ((modrm & 0xc0) != 0xc0);
        !          1806:                }
        !          1807:                break;
        !          1808:        case 0xba:
        !          1809:                if (isload)
        !          1810:                        return ((modrm & 0xc0) != 0xc0);
        !          1811:                switch (modrm & 0x38) {
        !          1812:                case 0x28:
        !          1813:                case 0x30:
        !          1814:                case 0x38:
        !          1815:                        return ((modrm & 0xc0) != 0xc0);
        !          1816:                }
        !          1817:                break;
        !          1818:        }
        !          1819:        return (0);
        !          1820: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.