db_disasm.c revision 93017
18876Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58876Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 118876Srgrimes * 128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 158876Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178876Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228876Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 25118Srgrimes * 2650477Speter * $FreeBSD: head/sys/amd64/amd64/db_disasm.c 93017 2002-03-23 14:27:06Z bde $ 274Srgrimes */ 284Srgrimes 294Srgrimes/* 304Srgrimes * Instruction disassembler. 314Srgrimes */ 322056Swollman#include <sys/param.h> 3324494Sbde 342056Swollman#include <ddb/ddb.h> 354Srgrimes#include <ddb/db_access.h> 364Srgrimes#include <ddb/db_sym.h> 374Srgrimes 384Srgrimes/* 394Srgrimes * Size attributes 404Srgrimes */ 414Srgrimes#define BYTE 0 424Srgrimes#define WORD 1 434Srgrimes#define LONG 2 444Srgrimes#define QUAD 3 454Srgrimes#define SNGL 4 464Srgrimes#define DBLR 5 474Srgrimes#define EXTR 6 484Srgrimes#define SDEP 7 494Srgrimes#define NONE 8 504Srgrimes 514Srgrimes/* 524Srgrimes * Addressing modes 534Srgrimes */ 544Srgrimes#define E 1 /* general effective address */ 554Srgrimes#define Eind 2 /* indirect address (jump, call) */ 564Srgrimes#define Ew 3 /* address, word size */ 574Srgrimes#define Eb 4 /* address, byte size */ 584Srgrimes#define R 5 /* register, in 'reg' field */ 594Srgrimes#define Rw 6 /* word register, in 'reg' field */ 604Srgrimes#define Ri 7 /* register in instruction */ 614Srgrimes#define S 8 /* segment reg, in 'reg' field */ 624Srgrimes#define Si 9 /* segment reg, in instruction */ 634Srgrimes#define A 10 /* accumulator */ 644Srgrimes#define BX 11 /* (bx) */ 654Srgrimes#define CL 12 /* cl, for shifts */ 664Srgrimes#define DX 13 /* dx, for IO */ 674Srgrimes#define SI 14 /* si */ 684Srgrimes#define DI 15 /* di */ 694Srgrimes#define CR 16 /* control register */ 704Srgrimes#define DR 17 /* debug register */ 714Srgrimes#define TR 18 /* test register */ 724Srgrimes#define I 19 /* immediate, unsigned */ 734Srgrimes#define Is 20 /* immediate, signed */ 744Srgrimes#define Ib 21 /* byte immediate, unsigned */ 754Srgrimes#define Ibs 22 /* byte immediate, signed */ 764Srgrimes#define Iw 23 /* word immediate, unsigned */ 774Srgrimes#define O 25 /* direct address */ 784Srgrimes#define Db 26 /* byte displacement from EIP */ 794Srgrimes#define Dl 27 /* long displacement from EIP */ 804Srgrimes#define o1 28 /* constant 1 */ 814Srgrimes#define o3 29 /* constant 3 */ 824Srgrimes#define OS 30 /* immediate offset/segment */ 834Srgrimes#define ST 31 /* FP stack top */ 844Srgrimes#define STI 32 /* FP stack */ 854Srgrimes#define X 33 /* extended FP op */ 864Srgrimes#define XA 34 /* for 'fstcw %ax' */ 8721277Sbde#define El 35 /* address, long size */ 8821277Sbde#define Ril 36 /* long register in instruction */ 8921277Sbde#define Iba 37 /* byte immediate, don't print if 0xa */ 904Srgrimes 9111940Sbdestruct inst { 9214887Swollman const char * i_name; /* name */ 934Srgrimes short i_has_modrm; /* has regmodrm byte */ 944Srgrimes short i_size; /* operand size */ 954Srgrimes int i_mode; /* addressing modes */ 9617109Sbde const void * i_extra; /* pointer to extra opcode table */ 974Srgrimes}; 984Srgrimes 994Srgrimes#define op1(x) (x) 1004Srgrimes#define op2(x,y) ((x)|((y)<<8)) 1014Srgrimes#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16)) 1024Srgrimes 10311940Sbdestruct finst { 10414887Swollman const char * f_name; /* name for memory instruction */ 1054Srgrimes int f_size; /* size for memory instruction */ 1064Srgrimes int f_rrmode; /* mode for rr instruction */ 10717109Sbde const void * f_rrname; /* name for rr instruction 1084Srgrimes (or pointer to table) */ 1094Srgrimes}; 1104Srgrimes 11114887Swollmanstatic const char * const db_Grp6[] = { 1124Srgrimes "sldt", 1134Srgrimes "str", 1144Srgrimes "lldt", 1154Srgrimes "ltr", 1164Srgrimes "verr", 1174Srgrimes "verw", 1184Srgrimes "", 1194Srgrimes "" 1204Srgrimes}; 1214Srgrimes 12214887Swollmanstatic const char * const db_Grp7[] = { 1234Srgrimes "sgdt", 1244Srgrimes "sidt", 1254Srgrimes "lgdt", 1264Srgrimes "lidt", 1274Srgrimes "smsw", 1284Srgrimes "", 1294Srgrimes "lmsw", 1304Srgrimes "invlpg" 1314Srgrimes}; 1324Srgrimes 13314887Swollmanstatic const char * const db_Grp8[] = { 1344Srgrimes "", 1354Srgrimes "", 1364Srgrimes "", 1374Srgrimes "", 1384Srgrimes "bt", 1394Srgrimes "bts", 1404Srgrimes "btr", 1414Srgrimes "btc" 1424Srgrimes}; 1434Srgrimes 14421277Sbdestatic const char * const db_Grp9[] = { 14521277Sbde "", 14621277Sbde "cmpxchg8b", 14721277Sbde "", 14821277Sbde "", 14921277Sbde "", 15021277Sbde "", 15121277Sbde "", 15221277Sbde "" 15321277Sbde}; 15421277Sbde 15514887Swollmanstatic const struct inst db_inst_0f0x[] = { 15617109Sbde/*00*/ { "", TRUE, NONE, op1(Ew), db_Grp6 }, 15717109Sbde/*01*/ { "", TRUE, NONE, op1(Ew), db_Grp7 }, 1584Srgrimes/*02*/ { "lar", TRUE, LONG, op2(E,R), 0 }, 1594Srgrimes/*03*/ { "lsl", TRUE, LONG, op2(E,R), 0 }, 1604Srgrimes/*04*/ { "", FALSE, NONE, 0, 0 }, 1614Srgrimes/*05*/ { "", FALSE, NONE, 0, 0 }, 1624Srgrimes/*06*/ { "clts", FALSE, NONE, 0, 0 }, 1634Srgrimes/*07*/ { "", FALSE, NONE, 0, 0 }, 1644Srgrimes 1654Srgrimes/*08*/ { "invd", FALSE, NONE, 0, 0 }, 1664Srgrimes/*09*/ { "wbinvd",FALSE, NONE, 0, 0 }, 1674Srgrimes/*0a*/ { "", FALSE, NONE, 0, 0 }, 1684Srgrimes/*0b*/ { "", FALSE, NONE, 0, 0 }, 1694Srgrimes/*0c*/ { "", FALSE, NONE, 0, 0 }, 1704Srgrimes/*0d*/ { "", FALSE, NONE, 0, 0 }, 1714Srgrimes/*0e*/ { "", FALSE, NONE, 0, 0 }, 1724Srgrimes/*0f*/ { "", FALSE, NONE, 0, 0 }, 1734Srgrimes}; 1744Srgrimes 17517109Sbdestatic const struct inst db_inst_0f2x[] = { 17621277Sbde/*20*/ { "mov", TRUE, LONG, op2(CR,El), 0 }, 17721277Sbde/*21*/ { "mov", TRUE, LONG, op2(DR,El), 0 }, 17821277Sbde/*22*/ { "mov", TRUE, LONG, op2(El,CR), 0 }, 17921277Sbde/*23*/ { "mov", TRUE, LONG, op2(El,DR), 0 }, 18021277Sbde/*24*/ { "mov", TRUE, LONG, op2(TR,El), 0 }, 1814Srgrimes/*25*/ { "", FALSE, NONE, 0, 0 }, 18221277Sbde/*26*/ { "mov", TRUE, LONG, op2(El,TR), 0 }, 1834Srgrimes/*27*/ { "", FALSE, NONE, 0, 0 }, 1844Srgrimes 1854Srgrimes/*28*/ { "", FALSE, NONE, 0, 0 }, 1864Srgrimes/*29*/ { "", FALSE, NONE, 0, 0 }, 1874Srgrimes/*2a*/ { "", FALSE, NONE, 0, 0 }, 1884Srgrimes/*2b*/ { "", FALSE, NONE, 0, 0 }, 1894Srgrimes/*2c*/ { "", FALSE, NONE, 0, 0 }, 1904Srgrimes/*2d*/ { "", FALSE, NONE, 0, 0 }, 1914Srgrimes/*2e*/ { "", FALSE, NONE, 0, 0 }, 1924Srgrimes/*2f*/ { "", FALSE, NONE, 0, 0 }, 1934Srgrimes}; 1944Srgrimes 19514887Swollmanstatic const struct inst db_inst_0f3x[] = { 19614887Swollman/*30*/ { "wrmsr", FALSE, NONE, 0, 0 }, 19714887Swollman/*31*/ { "rdtsc", FALSE, NONE, 0, 0 }, 19814887Swollman/*32*/ { "rdmsr", FALSE, NONE, 0, 0 }, 19914887Swollman/*33*/ { "rdpmc", FALSE, NONE, 0, 0 }, 20014887Swollman/*34*/ { "", FALSE, NONE, 0, 0 }, 20114887Swollman/*35*/ { "", FALSE, NONE, 0, 0 }, 20214887Swollman/*36*/ { "", FALSE, NONE, 0, 0 }, 20314887Swollman/*37*/ { "", FALSE, NONE, 0, 0 }, 20414887Swollman 20514887Swollman/*38*/ { "", FALSE, NONE, 0, 0 }, 20614887Swollman/*39*/ { "", FALSE, NONE, 0, 0 }, 20714887Swollman/*3a*/ { "", FALSE, NONE, 0, 0 }, 20814887Swollman/*3b*/ { "", FALSE, NONE, 0, 0 }, 20914887Swollman/*3c*/ { "", FALSE, NONE, 0, 0 }, 21014887Swollman/*3d*/ { "", FALSE, NONE, 0, 0 }, 21114887Swollman/*3e*/ { "", FALSE, NONE, 0, 0 }, 21214887Swollman/*3f*/ { "", FALSE, NONE, 0, 0 }, 21314887Swollman}; 21414887Swollman 21517109Sbdestatic const struct inst db_inst_0f8x[] = { 2164Srgrimes/*80*/ { "jo", FALSE, NONE, op1(Dl), 0 }, 2174Srgrimes/*81*/ { "jno", FALSE, NONE, op1(Dl), 0 }, 2184Srgrimes/*82*/ { "jb", FALSE, NONE, op1(Dl), 0 }, 2194Srgrimes/*83*/ { "jnb", FALSE, NONE, op1(Dl), 0 }, 2204Srgrimes/*84*/ { "jz", FALSE, NONE, op1(Dl), 0 }, 2214Srgrimes/*85*/ { "jnz", FALSE, NONE, op1(Dl), 0 }, 2224Srgrimes/*86*/ { "jbe", FALSE, NONE, op1(Dl), 0 }, 2234Srgrimes/*87*/ { "jnbe", FALSE, NONE, op1(Dl), 0 }, 2244Srgrimes 2254Srgrimes/*88*/ { "js", FALSE, NONE, op1(Dl), 0 }, 2264Srgrimes/*89*/ { "jns", FALSE, NONE, op1(Dl), 0 }, 2274Srgrimes/*8a*/ { "jp", FALSE, NONE, op1(Dl), 0 }, 2284Srgrimes/*8b*/ { "jnp", FALSE, NONE, op1(Dl), 0 }, 2294Srgrimes/*8c*/ { "jl", FALSE, NONE, op1(Dl), 0 }, 2304Srgrimes/*8d*/ { "jnl", FALSE, NONE, op1(Dl), 0 }, 2314Srgrimes/*8e*/ { "jle", FALSE, NONE, op1(Dl), 0 }, 2324Srgrimes/*8f*/ { "jnle", FALSE, NONE, op1(Dl), 0 }, 2334Srgrimes}; 2344Srgrimes 23517109Sbdestatic const struct inst db_inst_0f9x[] = { 2364Srgrimes/*90*/ { "seto", TRUE, NONE, op1(Eb), 0 }, 2374Srgrimes/*91*/ { "setno", TRUE, NONE, op1(Eb), 0 }, 2384Srgrimes/*92*/ { "setb", TRUE, NONE, op1(Eb), 0 }, 2394Srgrimes/*93*/ { "setnb", TRUE, NONE, op1(Eb), 0 }, 2404Srgrimes/*94*/ { "setz", TRUE, NONE, op1(Eb), 0 }, 2414Srgrimes/*95*/ { "setnz", TRUE, NONE, op1(Eb), 0 }, 2424Srgrimes/*96*/ { "setbe", TRUE, NONE, op1(Eb), 0 }, 2434Srgrimes/*97*/ { "setnbe",TRUE, NONE, op1(Eb), 0 }, 2444Srgrimes 2454Srgrimes/*98*/ { "sets", TRUE, NONE, op1(Eb), 0 }, 2464Srgrimes/*99*/ { "setns", TRUE, NONE, op1(Eb), 0 }, 2474Srgrimes/*9a*/ { "setp", TRUE, NONE, op1(Eb), 0 }, 2484Srgrimes/*9b*/ { "setnp", TRUE, NONE, op1(Eb), 0 }, 2494Srgrimes/*9c*/ { "setl", TRUE, NONE, op1(Eb), 0 }, 2504Srgrimes/*9d*/ { "setnl", TRUE, NONE, op1(Eb), 0 }, 2514Srgrimes/*9e*/ { "setle", TRUE, NONE, op1(Eb), 0 }, 2524Srgrimes/*9f*/ { "setnle",TRUE, NONE, op1(Eb), 0 }, 2534Srgrimes}; 2544Srgrimes 25517109Sbdestatic const struct inst db_inst_0fax[] = { 2564Srgrimes/*a0*/ { "push", FALSE, NONE, op1(Si), 0 }, 2574Srgrimes/*a1*/ { "pop", FALSE, NONE, op1(Si), 0 }, 25821277Sbde/*a2*/ { "cpuid", FALSE, NONE, 0, 0 }, 25921277Sbde/*a3*/ { "bt", TRUE, LONG, op2(R,E), 0 }, 26017109Sbde/*a4*/ { "shld", TRUE, LONG, op3(Ib,R,E), 0 }, 26117109Sbde/*a5*/ { "shld", TRUE, LONG, op3(CL,R,E), 0 }, 2624Srgrimes/*a6*/ { "", FALSE, NONE, 0, 0 }, 2634Srgrimes/*a7*/ { "", FALSE, NONE, 0, 0 }, 2644Srgrimes 2654Srgrimes/*a8*/ { "push", FALSE, NONE, op1(Si), 0 }, 2664Srgrimes/*a9*/ { "pop", FALSE, NONE, op1(Si), 0 }, 26721277Sbde/*aa*/ { "rsm", FALSE, NONE, 0, 0 }, 26821277Sbde/*ab*/ { "bts", TRUE, LONG, op2(R,E), 0 }, 26917109Sbde/*ac*/ { "shrd", TRUE, LONG, op3(Ib,R,E), 0 }, 27017109Sbde/*ad*/ { "shrd", TRUE, LONG, op3(CL,R,E), 0 }, 2714Srgrimes/*a6*/ { "", FALSE, NONE, 0, 0 }, 2724Srgrimes/*a7*/ { "imul", TRUE, LONG, op2(E,R), 0 }, 2734Srgrimes}; 2744Srgrimes 27517109Sbdestatic const struct inst db_inst_0fbx[] = { 27621277Sbde/*b0*/ { "cmpxchg",TRUE, BYTE, op2(R, E), 0 }, 27721277Sbde/*b0*/ { "cmpxchg",TRUE, LONG, op2(R, E), 0 }, 2784Srgrimes/*b2*/ { "lss", TRUE, LONG, op2(E, R), 0 }, 27921277Sbde/*b3*/ { "btr", TRUE, LONG, op2(R, E), 0 }, 2804Srgrimes/*b4*/ { "lfs", TRUE, LONG, op2(E, R), 0 }, 2814Srgrimes/*b5*/ { "lgs", TRUE, LONG, op2(E, R), 0 }, 28221277Sbde/*b6*/ { "movzb", TRUE, LONG, op2(Eb, R), 0 }, 28321277Sbde/*b7*/ { "movzw", TRUE, LONG, op2(Ew, R), 0 }, 2844Srgrimes 2854Srgrimes/*b8*/ { "", FALSE, NONE, 0, 0 }, 2864Srgrimes/*b9*/ { "", FALSE, NONE, 0, 0 }, 28717109Sbde/*ba*/ { "", TRUE, LONG, op2(Ib, E), db_Grp8 }, 2884Srgrimes/*bb*/ { "btc", TRUE, LONG, op2(R, E), 0 }, 2894Srgrimes/*bc*/ { "bsf", TRUE, LONG, op2(E, R), 0 }, 2904Srgrimes/*bd*/ { "bsr", TRUE, LONG, op2(E, R), 0 }, 29121277Sbde/*be*/ { "movsb", TRUE, LONG, op2(Eb, R), 0 }, 29221277Sbde/*bf*/ { "movsw", TRUE, LONG, op2(Ew, R), 0 }, 2934Srgrimes}; 2944Srgrimes 29517109Sbdestatic const struct inst db_inst_0fcx[] = { 2964Srgrimes/*c0*/ { "xadd", TRUE, BYTE, op2(R, E), 0 }, 2974Srgrimes/*c1*/ { "xadd", TRUE, LONG, op2(R, E), 0 }, 2984Srgrimes/*c2*/ { "", FALSE, NONE, 0, 0 }, 2994Srgrimes/*c3*/ { "", FALSE, NONE, 0, 0 }, 3004Srgrimes/*c4*/ { "", FALSE, NONE, 0, 0 }, 3014Srgrimes/*c5*/ { "", FALSE, NONE, 0, 0 }, 3024Srgrimes/*c6*/ { "", FALSE, NONE, 0, 0 }, 30321277Sbde/*c7*/ { "", TRUE, NONE, op1(E), db_Grp9 }, 30421277Sbde/*c8*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 30521277Sbde/*c9*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 30621277Sbde/*ca*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 30721277Sbde/*cb*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 30821277Sbde/*cc*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 30921277Sbde/*cd*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 31021277Sbde/*ce*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 31121277Sbde/*cf*/ { "bswap", FALSE, LONG, op1(Ril), 0 }, 3124Srgrimes}; 3134Srgrimes 31414887Swollmanstatic const struct inst * const db_inst_0f[] = { 3154Srgrimes db_inst_0f0x, 3164Srgrimes 0, 3174Srgrimes db_inst_0f2x, 31814887Swollman db_inst_0f3x, 3194Srgrimes 0, 3204Srgrimes 0, 3214Srgrimes 0, 3224Srgrimes 0, 3234Srgrimes db_inst_0f8x, 3244Srgrimes db_inst_0f9x, 3254Srgrimes db_inst_0fax, 3264Srgrimes db_inst_0fbx, 3274Srgrimes db_inst_0fcx, 3284Srgrimes 0, 32921277Sbde 0, 3304Srgrimes 0 3314Srgrimes}; 3324Srgrimes 33314887Swollmanstatic const char * const db_Esc92[] = { 3344Srgrimes "fnop", "", "", "", "", "", "", "" 3354Srgrimes}; 33614887Swollmanstatic const char * const db_Esc94[] = { 3374Srgrimes "fchs", "fabs", "", "", "ftst", "fxam", "", "" 3384Srgrimes}; 33917109Sbdestatic const char * const db_Esc95[] = { 3404Srgrimes "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","" 3414Srgrimes}; 34217109Sbdestatic const char * const db_Esc96[] = { 3434Srgrimes "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp", 3444Srgrimes "fincstp" 3454Srgrimes}; 34614887Swollmanstatic const char * const db_Esc97[] = { 3474Srgrimes "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos" 3484Srgrimes}; 3494Srgrimes 35021277Sbdestatic const char * const db_Esca5[] = { 3514Srgrimes "", "fucompp","", "", "", "", "", "" 3524Srgrimes}; 3534Srgrimes 35417109Sbdestatic const char * const db_Escb4[] = { 35521277Sbde "fneni","fndisi", "fnclex","fninit","fsetpm", "", "", "" 3564Srgrimes}; 3574Srgrimes 35814887Swollmanstatic const char * const db_Esce3[] = { 3594Srgrimes "", "fcompp","", "", "", "", "", "" 3604Srgrimes}; 3614Srgrimes 36217109Sbdestatic const char * const db_Escf4[] = { 3634Srgrimes "fnstsw","", "", "", "", "", "", "" 3644Srgrimes}; 3654Srgrimes 36614887Swollmanstatic const struct finst db_Esc8[] = { 3674Srgrimes/*0*/ { "fadd", SNGL, op2(STI,ST), 0 }, 3684Srgrimes/*1*/ { "fmul", SNGL, op2(STI,ST), 0 }, 3694Srgrimes/*2*/ { "fcom", SNGL, op2(STI,ST), 0 }, 3704Srgrimes/*3*/ { "fcomp", SNGL, op2(STI,ST), 0 }, 3714Srgrimes/*4*/ { "fsub", SNGL, op2(STI,ST), 0 }, 3724Srgrimes/*5*/ { "fsubr", SNGL, op2(STI,ST), 0 }, 3734Srgrimes/*6*/ { "fdiv", SNGL, op2(STI,ST), 0 }, 3744Srgrimes/*7*/ { "fdivr", SNGL, op2(STI,ST), 0 }, 3754Srgrimes}; 3764Srgrimes 37714887Swollmanstatic const struct finst db_Esc9[] = { 3784Srgrimes/*0*/ { "fld", SNGL, op1(STI), 0 }, 3794Srgrimes/*1*/ { "", NONE, op1(STI), "fxch" }, 38017109Sbde/*2*/ { "fst", SNGL, op1(X), db_Esc92 }, 38121277Sbde/*3*/ { "fstp", SNGL, 0, 0 }, 38217109Sbde/*4*/ { "fldenv", NONE, op1(X), db_Esc94 }, 38317109Sbde/*5*/ { "fldcw", NONE, op1(X), db_Esc95 }, 38417109Sbde/*6*/ { "fnstenv",NONE, op1(X), db_Esc96 }, 38517109Sbde/*7*/ { "fnstcw", NONE, op1(X), db_Esc97 }, 3864Srgrimes}; 3874Srgrimes 38814887Swollmanstatic const struct finst db_Esca[] = { 38921277Sbde/*0*/ { "fiadd", LONG, 0, 0 }, 39021277Sbde/*1*/ { "fimul", LONG, 0, 0 }, 39121277Sbde/*2*/ { "ficom", LONG, 0, 0 }, 39221277Sbde/*3*/ { "ficomp", LONG, 0, 0 }, 39321277Sbde/*4*/ { "fisub", LONG, 0, 0 }, 39421277Sbde/*5*/ { "fisubr", LONG, op1(X), db_Esca5 }, 39521277Sbde/*6*/ { "fidiv", LONG, 0, 0 }, 39621277Sbde/*7*/ { "fidivr", LONG, 0, 0 } 3974Srgrimes}; 3984Srgrimes 39914887Swollmanstatic const struct finst db_Escb[] = { 40021277Sbde/*0*/ { "fild", LONG, 0, 0 }, 4014Srgrimes/*1*/ { "", NONE, 0, 0 }, 40221277Sbde/*2*/ { "fist", LONG, 0, 0 }, 40321277Sbde/*3*/ { "fistp", LONG, 0, 0 }, 40417109Sbde/*4*/ { "", WORD, op1(X), db_Escb4 }, 4054Srgrimes/*5*/ { "fld", EXTR, 0, 0 }, 4064Srgrimes/*6*/ { "", WORD, 0, 0 }, 4074Srgrimes/*7*/ { "fstp", EXTR, 0, 0 }, 4084Srgrimes}; 4094Srgrimes 41014887Swollmanstatic const struct finst db_Escc[] = { 4114Srgrimes/*0*/ { "fadd", DBLR, op2(ST,STI), 0 }, 4124Srgrimes/*1*/ { "fmul", DBLR, op2(ST,STI), 0 }, 41321277Sbde/*2*/ { "fcom", DBLR, 0, 0 }, 41421277Sbde/*3*/ { "fcomp", DBLR, 0, 0 }, 4154Srgrimes/*4*/ { "fsub", DBLR, op2(ST,STI), "fsubr" }, 4164Srgrimes/*5*/ { "fsubr", DBLR, op2(ST,STI), "fsub" }, 4174Srgrimes/*6*/ { "fdiv", DBLR, op2(ST,STI), "fdivr" }, 4184Srgrimes/*7*/ { "fdivr", DBLR, op2(ST,STI), "fdiv" }, 4194Srgrimes}; 4204Srgrimes 42114887Swollmanstatic const struct finst db_Escd[] = { 4224Srgrimes/*0*/ { "fld", DBLR, op1(STI), "ffree" }, 4234Srgrimes/*1*/ { "", NONE, 0, 0 }, 4244Srgrimes/*2*/ { "fst", DBLR, op1(STI), 0 }, 4254Srgrimes/*3*/ { "fstp", DBLR, op1(STI), 0 }, 4264Srgrimes/*4*/ { "frstor", NONE, op1(STI), "fucom" }, 4274Srgrimes/*5*/ { "", NONE, op1(STI), "fucomp" }, 4284Srgrimes/*6*/ { "fnsave", NONE, 0, 0 }, 4294Srgrimes/*7*/ { "fnstsw", NONE, 0, 0 }, 4304Srgrimes}; 4314Srgrimes 43214887Swollmanstatic const struct finst db_Esce[] = { 43321277Sbde/*0*/ { "fiadd", WORD, op2(ST,STI), "faddp" }, 43421277Sbde/*1*/ { "fimul", WORD, op2(ST,STI), "fmulp" }, 43521277Sbde/*2*/ { "ficom", WORD, 0, 0 }, 43621277Sbde/*3*/ { "ficomp", WORD, op1(X), db_Esce3 }, 43721277Sbde/*4*/ { "fisub", WORD, op2(ST,STI), "fsubrp" }, 43821277Sbde/*5*/ { "fisubr", WORD, op2(ST,STI), "fsubp" }, 43921277Sbde/*6*/ { "fidiv", WORD, op2(ST,STI), "fdivrp" }, 44021277Sbde/*7*/ { "fidivr", WORD, op2(ST,STI), "fdivp" }, 4414Srgrimes}; 4424Srgrimes 44314887Swollmanstatic const struct finst db_Escf[] = { 44421277Sbde/*0*/ { "fild", WORD, 0, 0 }, 44521277Sbde/*1*/ { "", NONE, 0, 0 }, 44621277Sbde/*2*/ { "fist", WORD, 0, 0 }, 44721277Sbde/*3*/ { "fistp", WORD, 0, 0 }, 44817109Sbde/*4*/ { "fbld", NONE, op1(XA), db_Escf4 }, 44921277Sbde/*5*/ { "fild", QUAD, 0, 0 }, 4504Srgrimes/*6*/ { "fbstp", NONE, 0, 0 }, 45121277Sbde/*7*/ { "fistp", QUAD, 0, 0 }, 4524Srgrimes}; 4534Srgrimes 45417109Sbdestatic const struct finst * const db_Esc_inst[] = { 4554Srgrimes db_Esc8, db_Esc9, db_Esca, db_Escb, 4564Srgrimes db_Escc, db_Escd, db_Esce, db_Escf 4574Srgrimes}; 4584Srgrimes 45914887Swollmanstatic const char * const db_Grp1[] = { 4604Srgrimes "add", 4614Srgrimes "or", 4624Srgrimes "adc", 4634Srgrimes "sbb", 4644Srgrimes "and", 4654Srgrimes "sub", 4664Srgrimes "xor", 4674Srgrimes "cmp" 4684Srgrimes}; 4694Srgrimes 47014887Swollmanstatic const char * const db_Grp2[] = { 4714Srgrimes "rol", 4724Srgrimes "ror", 4734Srgrimes "rcl", 4744Srgrimes "rcr", 4754Srgrimes "shl", 4764Srgrimes "shr", 4774Srgrimes "shl", 4784Srgrimes "sar" 4794Srgrimes}; 4804Srgrimes 48114887Swollmanstatic const struct inst db_Grp3[] = { 4824Srgrimes { "test", TRUE, NONE, op2(I,E), 0 }, 4834Srgrimes { "test", TRUE, NONE, op2(I,E), 0 }, 4844Srgrimes { "not", TRUE, NONE, op1(E), 0 }, 4854Srgrimes { "neg", TRUE, NONE, op1(E), 0 }, 4864Srgrimes { "mul", TRUE, NONE, op2(E,A), 0 }, 4874Srgrimes { "imul", TRUE, NONE, op2(E,A), 0 }, 4884Srgrimes { "div", TRUE, NONE, op2(E,A), 0 }, 4894Srgrimes { "idiv", TRUE, NONE, op2(E,A), 0 }, 4904Srgrimes}; 4914Srgrimes 49217109Sbdestatic const struct inst db_Grp4[] = { 4934Srgrimes { "inc", TRUE, BYTE, op1(E), 0 }, 4944Srgrimes { "dec", TRUE, BYTE, op1(E), 0 }, 4954Srgrimes { "", TRUE, NONE, 0, 0 }, 4964Srgrimes { "", TRUE, NONE, 0, 0 }, 4974Srgrimes { "", TRUE, NONE, 0, 0 }, 4984Srgrimes { "", TRUE, NONE, 0, 0 }, 4994Srgrimes { "", TRUE, NONE, 0, 0 }, 5004Srgrimes { "", TRUE, NONE, 0, 0 } 5014Srgrimes}; 5024Srgrimes 50317109Sbdestatic const struct inst db_Grp5[] = { 5044Srgrimes { "inc", TRUE, LONG, op1(E), 0 }, 5054Srgrimes { "dec", TRUE, LONG, op1(E), 0 }, 50621277Sbde { "call", TRUE, LONG, op1(Eind),0 }, 50721277Sbde { "lcall", TRUE, LONG, op1(Eind),0 }, 50821277Sbde { "jmp", TRUE, LONG, op1(Eind),0 }, 50921277Sbde { "ljmp", TRUE, LONG, op1(Eind),0 }, 5104Srgrimes { "push", TRUE, LONG, op1(E), 0 }, 5114Srgrimes { "", TRUE, NONE, 0, 0 } 5124Srgrimes}; 5134Srgrimes 51414887Swollmanstatic const struct inst db_inst_table[256] = { 5154Srgrimes/*00*/ { "add", TRUE, BYTE, op2(R, E), 0 }, 5164Srgrimes/*01*/ { "add", TRUE, LONG, op2(R, E), 0 }, 5174Srgrimes/*02*/ { "add", TRUE, BYTE, op2(E, R), 0 }, 5184Srgrimes/*03*/ { "add", TRUE, LONG, op2(E, R), 0 }, 51921277Sbde/*04*/ { "add", FALSE, BYTE, op2(I, A), 0 }, 5204Srgrimes/*05*/ { "add", FALSE, LONG, op2(Is, A), 0 }, 5214Srgrimes/*06*/ { "push", FALSE, NONE, op1(Si), 0 }, 5224Srgrimes/*07*/ { "pop", FALSE, NONE, op1(Si), 0 }, 5234Srgrimes 5244Srgrimes/*08*/ { "or", TRUE, BYTE, op2(R, E), 0 }, 5254Srgrimes/*09*/ { "or", TRUE, LONG, op2(R, E), 0 }, 5264Srgrimes/*0a*/ { "or", TRUE, BYTE, op2(E, R), 0 }, 5274Srgrimes/*0b*/ { "or", TRUE, LONG, op2(E, R), 0 }, 5284Srgrimes/*0c*/ { "or", FALSE, BYTE, op2(I, A), 0 }, 5294Srgrimes/*0d*/ { "or", FALSE, LONG, op2(I, A), 0 }, 5304Srgrimes/*0e*/ { "push", FALSE, NONE, op1(Si), 0 }, 5314Srgrimes/*0f*/ { "", FALSE, NONE, 0, 0 }, 5324Srgrimes 5334Srgrimes/*10*/ { "adc", TRUE, BYTE, op2(R, E), 0 }, 5344Srgrimes/*11*/ { "adc", TRUE, LONG, op2(R, E), 0 }, 5354Srgrimes/*12*/ { "adc", TRUE, BYTE, op2(E, R), 0 }, 5364Srgrimes/*13*/ { "adc", TRUE, LONG, op2(E, R), 0 }, 53721277Sbde/*14*/ { "adc", FALSE, BYTE, op2(I, A), 0 }, 5384Srgrimes/*15*/ { "adc", FALSE, LONG, op2(Is, A), 0 }, 5394Srgrimes/*16*/ { "push", FALSE, NONE, op1(Si), 0 }, 5404Srgrimes/*17*/ { "pop", FALSE, NONE, op1(Si), 0 }, 5414Srgrimes 5424Srgrimes/*18*/ { "sbb", TRUE, BYTE, op2(R, E), 0 }, 5434Srgrimes/*19*/ { "sbb", TRUE, LONG, op2(R, E), 0 }, 5444Srgrimes/*1a*/ { "sbb", TRUE, BYTE, op2(E, R), 0 }, 5454Srgrimes/*1b*/ { "sbb", TRUE, LONG, op2(E, R), 0 }, 54621277Sbde/*1c*/ { "sbb", FALSE, BYTE, op2(I, A), 0 }, 5474Srgrimes/*1d*/ { "sbb", FALSE, LONG, op2(Is, A), 0 }, 5484Srgrimes/*1e*/ { "push", FALSE, NONE, op1(Si), 0 }, 5494Srgrimes/*1f*/ { "pop", FALSE, NONE, op1(Si), 0 }, 5504Srgrimes 5514Srgrimes/*20*/ { "and", TRUE, BYTE, op2(R, E), 0 }, 5524Srgrimes/*21*/ { "and", TRUE, LONG, op2(R, E), 0 }, 5534Srgrimes/*22*/ { "and", TRUE, BYTE, op2(E, R), 0 }, 5544Srgrimes/*23*/ { "and", TRUE, LONG, op2(E, R), 0 }, 5554Srgrimes/*24*/ { "and", FALSE, BYTE, op2(I, A), 0 }, 5564Srgrimes/*25*/ { "and", FALSE, LONG, op2(I, A), 0 }, 5574Srgrimes/*26*/ { "", FALSE, NONE, 0, 0 }, 55821277Sbde/*27*/ { "daa", FALSE, NONE, 0, 0 }, 5594Srgrimes 5604Srgrimes/*28*/ { "sub", TRUE, BYTE, op2(R, E), 0 }, 5614Srgrimes/*29*/ { "sub", TRUE, LONG, op2(R, E), 0 }, 5624Srgrimes/*2a*/ { "sub", TRUE, BYTE, op2(E, R), 0 }, 5634Srgrimes/*2b*/ { "sub", TRUE, LONG, op2(E, R), 0 }, 56421277Sbde/*2c*/ { "sub", FALSE, BYTE, op2(I, A), 0 }, 5654Srgrimes/*2d*/ { "sub", FALSE, LONG, op2(Is, A), 0 }, 5664Srgrimes/*2e*/ { "", FALSE, NONE, 0, 0 }, 5674Srgrimes/*2f*/ { "das", FALSE, NONE, 0, 0 }, 5684Srgrimes 5694Srgrimes/*30*/ { "xor", TRUE, BYTE, op2(R, E), 0 }, 5704Srgrimes/*31*/ { "xor", TRUE, LONG, op2(R, E), 0 }, 5714Srgrimes/*32*/ { "xor", TRUE, BYTE, op2(E, R), 0 }, 5724Srgrimes/*33*/ { "xor", TRUE, LONG, op2(E, R), 0 }, 5734Srgrimes/*34*/ { "xor", FALSE, BYTE, op2(I, A), 0 }, 5744Srgrimes/*35*/ { "xor", FALSE, LONG, op2(I, A), 0 }, 5754Srgrimes/*36*/ { "", FALSE, NONE, 0, 0 }, 57621277Sbde/*37*/ { "aaa", FALSE, NONE, 0, 0 }, 5774Srgrimes 5784Srgrimes/*38*/ { "cmp", TRUE, BYTE, op2(R, E), 0 }, 5794Srgrimes/*39*/ { "cmp", TRUE, LONG, op2(R, E), 0 }, 5804Srgrimes/*3a*/ { "cmp", TRUE, BYTE, op2(E, R), 0 }, 5814Srgrimes/*3b*/ { "cmp", TRUE, LONG, op2(E, R), 0 }, 58221277Sbde/*3c*/ { "cmp", FALSE, BYTE, op2(I, A), 0 }, 5834Srgrimes/*3d*/ { "cmp", FALSE, LONG, op2(Is, A), 0 }, 5844Srgrimes/*3e*/ { "", FALSE, NONE, 0, 0 }, 5854Srgrimes/*3f*/ { "aas", FALSE, NONE, 0, 0 }, 5864Srgrimes 5874Srgrimes/*40*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5884Srgrimes/*41*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5894Srgrimes/*42*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5904Srgrimes/*43*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5914Srgrimes/*44*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5924Srgrimes/*45*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5934Srgrimes/*46*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5944Srgrimes/*47*/ { "inc", FALSE, LONG, op1(Ri), 0 }, 5954Srgrimes 5964Srgrimes/*48*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 5974Srgrimes/*49*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 5984Srgrimes/*4a*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 5994Srgrimes/*4b*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 6004Srgrimes/*4c*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 6014Srgrimes/*4d*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 6024Srgrimes/*4e*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 6034Srgrimes/*4f*/ { "dec", FALSE, LONG, op1(Ri), 0 }, 6044Srgrimes 6054Srgrimes/*50*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6064Srgrimes/*51*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6074Srgrimes/*52*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6084Srgrimes/*53*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6094Srgrimes/*54*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6104Srgrimes/*55*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6114Srgrimes/*56*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6124Srgrimes/*57*/ { "push", FALSE, LONG, op1(Ri), 0 }, 6134Srgrimes 6144Srgrimes/*58*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6154Srgrimes/*59*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6164Srgrimes/*5a*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6174Srgrimes/*5b*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6184Srgrimes/*5c*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6194Srgrimes/*5d*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6204Srgrimes/*5e*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6214Srgrimes/*5f*/ { "pop", FALSE, LONG, op1(Ri), 0 }, 6224Srgrimes 6234Srgrimes/*60*/ { "pusha", FALSE, LONG, 0, 0 }, 6244Srgrimes/*61*/ { "popa", FALSE, LONG, 0, 0 }, 6254Srgrimes/*62*/ { "bound", TRUE, LONG, op2(E, R), 0 }, 62621277Sbde/*63*/ { "arpl", TRUE, NONE, op2(Rw,Ew), 0 }, 6274Srgrimes 6284Srgrimes/*64*/ { "", FALSE, NONE, 0, 0 }, 6294Srgrimes/*65*/ { "", FALSE, NONE, 0, 0 }, 6304Srgrimes/*66*/ { "", FALSE, NONE, 0, 0 }, 6314Srgrimes/*67*/ { "", FALSE, NONE, 0, 0 }, 6324Srgrimes 6334Srgrimes/*68*/ { "push", FALSE, LONG, op1(I), 0 }, 6344Srgrimes/*69*/ { "imul", TRUE, LONG, op3(I,E,R), 0 }, 63521277Sbde/*6a*/ { "push", FALSE, LONG, op1(Ibs), 0 }, 6364Srgrimes/*6b*/ { "imul", TRUE, LONG, op3(Ibs,E,R),0 }, 6374Srgrimes/*6c*/ { "ins", FALSE, BYTE, op2(DX, DI), 0 }, 6384Srgrimes/*6d*/ { "ins", FALSE, LONG, op2(DX, DI), 0 }, 6394Srgrimes/*6e*/ { "outs", FALSE, BYTE, op2(SI, DX), 0 }, 6404Srgrimes/*6f*/ { "outs", FALSE, LONG, op2(SI, DX), 0 }, 6414Srgrimes 6424Srgrimes/*70*/ { "jo", FALSE, NONE, op1(Db), 0 }, 6434Srgrimes/*71*/ { "jno", FALSE, NONE, op1(Db), 0 }, 6444Srgrimes/*72*/ { "jb", FALSE, NONE, op1(Db), 0 }, 6454Srgrimes/*73*/ { "jnb", FALSE, NONE, op1(Db), 0 }, 6464Srgrimes/*74*/ { "jz", FALSE, NONE, op1(Db), 0 }, 6474Srgrimes/*75*/ { "jnz", FALSE, NONE, op1(Db), 0 }, 6484Srgrimes/*76*/ { "jbe", FALSE, NONE, op1(Db), 0 }, 6494Srgrimes/*77*/ { "jnbe", FALSE, NONE, op1(Db), 0 }, 6504Srgrimes 6514Srgrimes/*78*/ { "js", FALSE, NONE, op1(Db), 0 }, 6524Srgrimes/*79*/ { "jns", FALSE, NONE, op1(Db), 0 }, 6534Srgrimes/*7a*/ { "jp", FALSE, NONE, op1(Db), 0 }, 6544Srgrimes/*7b*/ { "jnp", FALSE, NONE, op1(Db), 0 }, 6554Srgrimes/*7c*/ { "jl", FALSE, NONE, op1(Db), 0 }, 6564Srgrimes/*7d*/ { "jnl", FALSE, NONE, op1(Db), 0 }, 6574Srgrimes/*7e*/ { "jle", FALSE, NONE, op1(Db), 0 }, 6584Srgrimes/*7f*/ { "jnle", FALSE, NONE, op1(Db), 0 }, 6594Srgrimes 66017109Sbde/*80*/ { "", TRUE, BYTE, op2(I, E), db_Grp1 }, 66117109Sbde/*81*/ { "", TRUE, LONG, op2(I, E), db_Grp1 }, 66221277Sbde/*82*/ { "", TRUE, BYTE, op2(I, E), db_Grp1 }, 66317109Sbde/*83*/ { "", TRUE, LONG, op2(Ibs,E), db_Grp1 }, 6644Srgrimes/*84*/ { "test", TRUE, BYTE, op2(R, E), 0 }, 6654Srgrimes/*85*/ { "test", TRUE, LONG, op2(R, E), 0 }, 6664Srgrimes/*86*/ { "xchg", TRUE, BYTE, op2(R, E), 0 }, 6674Srgrimes/*87*/ { "xchg", TRUE, LONG, op2(R, E), 0 }, 6684Srgrimes 6694Srgrimes/*88*/ { "mov", TRUE, BYTE, op2(R, E), 0 }, 6704Srgrimes/*89*/ { "mov", TRUE, LONG, op2(R, E), 0 }, 6714Srgrimes/*8a*/ { "mov", TRUE, BYTE, op2(E, R), 0 }, 6724Srgrimes/*8b*/ { "mov", TRUE, LONG, op2(E, R), 0 }, 6734Srgrimes/*8c*/ { "mov", TRUE, NONE, op2(S, Ew), 0 }, 6744Srgrimes/*8d*/ { "lea", TRUE, LONG, op2(E, R), 0 }, 6754Srgrimes/*8e*/ { "mov", TRUE, NONE, op2(Ew, S), 0 }, 6764Srgrimes/*8f*/ { "pop", TRUE, LONG, op1(E), 0 }, 6774Srgrimes 6784Srgrimes/*90*/ { "nop", FALSE, NONE, 0, 0 }, 6794Srgrimes/*91*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6804Srgrimes/*92*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6814Srgrimes/*93*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6824Srgrimes/*94*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6834Srgrimes/*95*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6844Srgrimes/*96*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6854Srgrimes/*97*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 }, 6864Srgrimes 6874Srgrimes/*98*/ { "cbw", FALSE, SDEP, 0, "cwde" }, /* cbw/cwde */ 6884Srgrimes/*99*/ { "cwd", FALSE, SDEP, 0, "cdq" }, /* cwd/cdq */ 6894Srgrimes/*9a*/ { "lcall", FALSE, NONE, op1(OS), 0 }, 6904Srgrimes/*9b*/ { "wait", FALSE, NONE, 0, 0 }, 6914Srgrimes/*9c*/ { "pushf", FALSE, LONG, 0, 0 }, 6924Srgrimes/*9d*/ { "popf", FALSE, LONG, 0, 0 }, 6934Srgrimes/*9e*/ { "sahf", FALSE, NONE, 0, 0 }, 6944Srgrimes/*9f*/ { "lahf", FALSE, NONE, 0, 0 }, 6954Srgrimes 6964Srgrimes/*a0*/ { "mov", FALSE, BYTE, op2(O, A), 0 }, 6974Srgrimes/*a1*/ { "mov", FALSE, LONG, op2(O, A), 0 }, 6984Srgrimes/*a2*/ { "mov", FALSE, BYTE, op2(A, O), 0 }, 6994Srgrimes/*a3*/ { "mov", FALSE, LONG, op2(A, O), 0 }, 7004Srgrimes/*a4*/ { "movs", FALSE, BYTE, op2(SI,DI), 0 }, 7014Srgrimes/*a5*/ { "movs", FALSE, LONG, op2(SI,DI), 0 }, 7024Srgrimes/*a6*/ { "cmps", FALSE, BYTE, op2(SI,DI), 0 }, 7034Srgrimes/*a7*/ { "cmps", FALSE, LONG, op2(SI,DI), 0 }, 7044Srgrimes 7054Srgrimes/*a8*/ { "test", FALSE, BYTE, op2(I, A), 0 }, 7064Srgrimes/*a9*/ { "test", FALSE, LONG, op2(I, A), 0 }, 7074Srgrimes/*aa*/ { "stos", FALSE, BYTE, op1(DI), 0 }, 7084Srgrimes/*ab*/ { "stos", FALSE, LONG, op1(DI), 0 }, 709118Srgrimes/*ac*/ { "lods", FALSE, BYTE, op1(SI), 0 }, 710118Srgrimes/*ad*/ { "lods", FALSE, LONG, op1(SI), 0 }, 7114Srgrimes/*ae*/ { "scas", FALSE, BYTE, op1(SI), 0 }, 7124Srgrimes/*af*/ { "scas", FALSE, LONG, op1(SI), 0 }, 7134Srgrimes 7144Srgrimes/*b0*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7154Srgrimes/*b1*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7164Srgrimes/*b2*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7174Srgrimes/*b3*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7184Srgrimes/*b4*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7194Srgrimes/*b5*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7204Srgrimes/*b6*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7214Srgrimes/*b7*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 }, 7224Srgrimes 7234Srgrimes/*b8*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7244Srgrimes/*b9*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7254Srgrimes/*ba*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7264Srgrimes/*bb*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7274Srgrimes/*bc*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7284Srgrimes/*bd*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7294Srgrimes/*be*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7304Srgrimes/*bf*/ { "mov", FALSE, LONG, op2(I, Ri), 0 }, 7314Srgrimes 73217109Sbde/*c0*/ { "", TRUE, BYTE, op2(Ib, E), db_Grp2 }, 73317109Sbde/*c1*/ { "", TRUE, LONG, op2(Ib, E), db_Grp2 }, 7344Srgrimes/*c2*/ { "ret", FALSE, NONE, op1(Iw), 0 }, 7354Srgrimes/*c3*/ { "ret", FALSE, NONE, 0, 0 }, 7364Srgrimes/*c4*/ { "les", TRUE, LONG, op2(E, R), 0 }, 7374Srgrimes/*c5*/ { "lds", TRUE, LONG, op2(E, R), 0 }, 7384Srgrimes/*c6*/ { "mov", TRUE, BYTE, op2(I, E), 0 }, 7394Srgrimes/*c7*/ { "mov", TRUE, LONG, op2(I, E), 0 }, 7404Srgrimes 74121277Sbde/*c8*/ { "enter", FALSE, NONE, op2(Iw, Ib), 0 }, 7424Srgrimes/*c9*/ { "leave", FALSE, NONE, 0, 0 }, 7434Srgrimes/*ca*/ { "lret", FALSE, NONE, op1(Iw), 0 }, 7444Srgrimes/*cb*/ { "lret", FALSE, NONE, 0, 0 }, 7454Srgrimes/*cc*/ { "int", FALSE, NONE, op1(o3), 0 }, 7464Srgrimes/*cd*/ { "int", FALSE, NONE, op1(Ib), 0 }, 7474Srgrimes/*ce*/ { "into", FALSE, NONE, 0, 0 }, 7484Srgrimes/*cf*/ { "iret", FALSE, NONE, 0, 0 }, 7494Srgrimes 75017109Sbde/*d0*/ { "", TRUE, BYTE, op2(o1, E), db_Grp2 }, 75117109Sbde/*d1*/ { "", TRUE, LONG, op2(o1, E), db_Grp2 }, 75217109Sbde/*d2*/ { "", TRUE, BYTE, op2(CL, E), db_Grp2 }, 75317109Sbde/*d3*/ { "", TRUE, LONG, op2(CL, E), db_Grp2 }, 75421277Sbde/*d4*/ { "aam", FALSE, NONE, op1(Iba), 0 }, 75521277Sbde/*d5*/ { "aad", FALSE, NONE, op1(Iba), 0 }, 75621277Sbde/*d6*/ { ".byte\t0xd6", FALSE, NONE, 0, 0 }, 7574Srgrimes/*d7*/ { "xlat", FALSE, BYTE, op1(BX), 0 }, 7584Srgrimes 75917109Sbde/*d8*/ { "", TRUE, NONE, 0, db_Esc8 }, 76017109Sbde/*d9*/ { "", TRUE, NONE, 0, db_Esc9 }, 76117109Sbde/*da*/ { "", TRUE, NONE, 0, db_Esca }, 76217109Sbde/*db*/ { "", TRUE, NONE, 0, db_Escb }, 76317109Sbde/*dc*/ { "", TRUE, NONE, 0, db_Escc }, 76417109Sbde/*dd*/ { "", TRUE, NONE, 0, db_Escd }, 76517109Sbde/*de*/ { "", TRUE, NONE, 0, db_Esce }, 76617109Sbde/*df*/ { "", TRUE, NONE, 0, db_Escf }, 7674Srgrimes 7684Srgrimes/*e0*/ { "loopne",FALSE, NONE, op1(Db), 0 }, 7694Srgrimes/*e1*/ { "loope", FALSE, NONE, op1(Db), 0 }, 7704Srgrimes/*e2*/ { "loop", FALSE, NONE, op1(Db), 0 }, 7714Srgrimes/*e3*/ { "jcxz", FALSE, SDEP, op1(Db), "jecxz" }, 7724Srgrimes/*e4*/ { "in", FALSE, BYTE, op2(Ib, A), 0 }, 7734Srgrimes/*e5*/ { "in", FALSE, LONG, op2(Ib, A) , 0 }, 7744Srgrimes/*e6*/ { "out", FALSE, BYTE, op2(A, Ib), 0 }, 7754Srgrimes/*e7*/ { "out", FALSE, LONG, op2(A, Ib) , 0 }, 7764Srgrimes 7774Srgrimes/*e8*/ { "call", FALSE, NONE, op1(Dl), 0 }, 7784Srgrimes/*e9*/ { "jmp", FALSE, NONE, op1(Dl), 0 }, 7794Srgrimes/*ea*/ { "ljmp", FALSE, NONE, op1(OS), 0 }, 7804Srgrimes/*eb*/ { "jmp", FALSE, NONE, op1(Db), 0 }, 7814Srgrimes/*ec*/ { "in", FALSE, BYTE, op2(DX, A), 0 }, 7824Srgrimes/*ed*/ { "in", FALSE, LONG, op2(DX, A) , 0 }, 7834Srgrimes/*ee*/ { "out", FALSE, BYTE, op2(A, DX), 0 }, 7844Srgrimes/*ef*/ { "out", FALSE, LONG, op2(A, DX) , 0 }, 7854Srgrimes 7864Srgrimes/*f0*/ { "", FALSE, NONE, 0, 0 }, 78721277Sbde/*f1*/ { ".byte\t0xf1", FALSE, NONE, 0, 0 }, 7884Srgrimes/*f2*/ { "", FALSE, NONE, 0, 0 }, 7894Srgrimes/*f3*/ { "", FALSE, NONE, 0, 0 }, 7904Srgrimes/*f4*/ { "hlt", FALSE, NONE, 0, 0 }, 7914Srgrimes/*f5*/ { "cmc", FALSE, NONE, 0, 0 }, 79217109Sbde/*f6*/ { "", TRUE, BYTE, 0, db_Grp3 }, 79317109Sbde/*f7*/ { "", TRUE, LONG, 0, db_Grp3 }, 7944Srgrimes 7954Srgrimes/*f8*/ { "clc", FALSE, NONE, 0, 0 }, 7964Srgrimes/*f9*/ { "stc", FALSE, NONE, 0, 0 }, 7974Srgrimes/*fa*/ { "cli", FALSE, NONE, 0, 0 }, 7984Srgrimes/*fb*/ { "sti", FALSE, NONE, 0, 0 }, 7994Srgrimes/*fc*/ { "cld", FALSE, NONE, 0, 0 }, 8004Srgrimes/*fd*/ { "std", FALSE, NONE, 0, 0 }, 80117109Sbde/*fe*/ { "", TRUE, NONE, 0, db_Grp4 }, 80217109Sbde/*ff*/ { "", TRUE, NONE, 0, db_Grp5 }, 8034Srgrimes}; 8044Srgrimes 80517109Sbdestatic const struct inst db_bad_inst = 8064Srgrimes { "???", FALSE, NONE, 0, 0 } 8074Srgrimes; 8084Srgrimes 8094Srgrimes#define f_mod(byte) ((byte)>>6) 8104Srgrimes#define f_reg(byte) (((byte)>>3)&0x7) 8114Srgrimes#define f_rm(byte) ((byte)&0x7) 8124Srgrimes 8134Srgrimes#define sib_ss(byte) ((byte)>>6) 8144Srgrimes#define sib_index(byte) (((byte)>>3)&0x7) 8154Srgrimes#define sib_base(byte) ((byte)&0x7) 8164Srgrimes 81711940Sbdestruct i_addr { 8184Srgrimes int is_reg; /* if reg, reg number is in 'disp' */ 8194Srgrimes int disp; 82014887Swollman const char * base; 82114887Swollman const char * index; 8224Srgrimes int ss; 8234Srgrimes}; 8244Srgrimes 82514887Swollmanstatic const char * const db_index_reg_16[8] = { 8264Srgrimes "%bx,%si", 8274Srgrimes "%bx,%di", 8284Srgrimes "%bp,%si", 8294Srgrimes "%bp,%di", 8304Srgrimes "%si", 8314Srgrimes "%di", 8324Srgrimes "%bp", 8334Srgrimes "%bx" 8344Srgrimes}; 8354Srgrimes 83614887Swollmanstatic const char * const db_reg[3][8] = { 83743314Sdillon { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" }, 83843314Sdillon { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" }, 83943314Sdillon { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" } 8404Srgrimes}; 8414Srgrimes 84217109Sbdestatic const char * const db_seg_reg[8] = { 8434Srgrimes "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", "" 8444Srgrimes}; 8454Srgrimes 8464Srgrimes/* 8474Srgrimes * lengths for size attributes 8484Srgrimes */ 84914887Swollmanstatic const int db_lengths[] = { 8504Srgrimes 1, /* BYTE */ 8514Srgrimes 2, /* WORD */ 8524Srgrimes 4, /* LONG */ 8534Srgrimes 8, /* QUAD */ 8544Srgrimes 4, /* SNGL */ 8554Srgrimes 8, /* DBLR */ 8564Srgrimes 10, /* EXTR */ 8574Srgrimes}; 8584Srgrimes 8594Srgrimes#define get_value_inc(result, loc, size, is_signed) \ 8604Srgrimes result = db_get_value((loc), (size), (is_signed)); \ 8614Srgrimes (loc) += (size); 8624Srgrimes 86311940Sbdestatic db_addr_t 86492770Salfred db_disasm_esc(db_addr_t loc, int inst, int short_addr, 86593017Sbde int size, const char *seg); 86692770Salfredstatic void db_print_address(const char *seg, int size, 86793017Sbde struct i_addr *addrp); 86811940Sbdestatic db_addr_t 86993017Sbde db_read_address(db_addr_t loc, int short_addr, int regmodrm, 87093017Sbde struct i_addr *addrp); 87111940Sbde 8724Srgrimes/* 8734Srgrimes * Read address at location and return updated location. 8744Srgrimes */ 87511921Sphkstatic db_addr_t 8764Srgrimesdb_read_address(loc, short_addr, regmodrm, addrp) 8774Srgrimes db_addr_t loc; 8784Srgrimes int short_addr; 8794Srgrimes int regmodrm; 88017109Sbde struct i_addr * addrp; /* out */ 8814Srgrimes{ 8823436Sphk int mod, rm, sib, index, disp; 8834Srgrimes 8844Srgrimes mod = f_mod(regmodrm); 8854Srgrimes rm = f_rm(regmodrm); 8864Srgrimes 8874Srgrimes if (mod == 3) { 8884Srgrimes addrp->is_reg = TRUE; 8894Srgrimes addrp->disp = rm; 8904Srgrimes return (loc); 8914Srgrimes } 8924Srgrimes addrp->is_reg = FALSE; 8934Srgrimes addrp->index = 0; 8944Srgrimes 8954Srgrimes if (short_addr) { 8964Srgrimes addrp->index = 0; 8974Srgrimes addrp->ss = 0; 8984Srgrimes switch (mod) { 8994Srgrimes case 0: 9004Srgrimes if (rm == 6) { 90121277Sbde get_value_inc(disp, loc, 2, FALSE); 9024Srgrimes addrp->disp = disp; 9034Srgrimes addrp->base = 0; 9044Srgrimes } 9054Srgrimes else { 9064Srgrimes addrp->disp = 0; 9074Srgrimes addrp->base = db_index_reg_16[rm]; 9084Srgrimes } 9094Srgrimes break; 9104Srgrimes case 1: 9114Srgrimes get_value_inc(disp, loc, 1, TRUE); 91221277Sbde disp &= 0xFFFF; 9134Srgrimes addrp->disp = disp; 9144Srgrimes addrp->base = db_index_reg_16[rm]; 9154Srgrimes break; 9164Srgrimes case 2: 91721277Sbde get_value_inc(disp, loc, 2, FALSE); 9184Srgrimes addrp->disp = disp; 9194Srgrimes addrp->base = db_index_reg_16[rm]; 9204Srgrimes break; 9214Srgrimes } 9224Srgrimes } 9234Srgrimes else { 9244Srgrimes if (mod != 3 && rm == 4) { 9254Srgrimes get_value_inc(sib, loc, 1, FALSE); 9264Srgrimes rm = sib_base(sib); 9274Srgrimes index = sib_index(sib); 9284Srgrimes if (index != 4) 9294Srgrimes addrp->index = db_reg[LONG][index]; 9304Srgrimes addrp->ss = sib_ss(sib); 9314Srgrimes } 9324Srgrimes 9334Srgrimes switch (mod) { 9344Srgrimes case 0: 9354Srgrimes if (rm == 5) { 9364Srgrimes get_value_inc(addrp->disp, loc, 4, FALSE); 9374Srgrimes addrp->base = 0; 9384Srgrimes } 9394Srgrimes else { 9404Srgrimes addrp->disp = 0; 9414Srgrimes addrp->base = db_reg[LONG][rm]; 9424Srgrimes } 9434Srgrimes break; 9444Srgrimes 9454Srgrimes case 1: 9464Srgrimes get_value_inc(disp, loc, 1, TRUE); 9474Srgrimes addrp->disp = disp; 9484Srgrimes addrp->base = db_reg[LONG][rm]; 9494Srgrimes break; 9504Srgrimes 9514Srgrimes case 2: 9524Srgrimes get_value_inc(disp, loc, 4, FALSE); 9534Srgrimes addrp->disp = disp; 9544Srgrimes addrp->base = db_reg[LONG][rm]; 9554Srgrimes break; 9564Srgrimes } 9574Srgrimes } 9584Srgrimes return (loc); 9594Srgrimes} 9604Srgrimes 96111921Sphkstatic void 9624Srgrimesdb_print_address(seg, size, addrp) 96317109Sbde const char * seg; 9644Srgrimes int size; 96517109Sbde struct i_addr * addrp; 9664Srgrimes{ 9674Srgrimes if (addrp->is_reg) { 9684Srgrimes db_printf("%s", db_reg[size][addrp->disp]); 9694Srgrimes return; 9704Srgrimes } 9714Srgrimes 9724Srgrimes if (seg) { 9734Srgrimes db_printf("%s:", seg); 9744Srgrimes } 9754Srgrimes 9764Srgrimes db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY); 9774Srgrimes if (addrp->base != 0 || addrp->index != 0) { 9784Srgrimes db_printf("("); 9794Srgrimes if (addrp->base) 9804Srgrimes db_printf("%s", addrp->base); 9814Srgrimes if (addrp->index) 9824Srgrimes db_printf(",%s,%d", addrp->index, 1<<addrp->ss); 9834Srgrimes db_printf(")"); 9844Srgrimes } 9854Srgrimes} 9864Srgrimes 9874Srgrimes/* 9884Srgrimes * Disassemble floating-point ("escape") instruction 9894Srgrimes * and return updated location. 9904Srgrimes */ 99111921Sphkstatic db_addr_t 9924Srgrimesdb_disasm_esc(loc, inst, short_addr, size, seg) 9934Srgrimes db_addr_t loc; 9944Srgrimes int inst; 9954Srgrimes int short_addr; 9964Srgrimes int size; 99717109Sbde const char * seg; 9984Srgrimes{ 9994Srgrimes int regmodrm; 100017109Sbde const struct finst * fp; 10014Srgrimes int mod; 10024Srgrimes struct i_addr address; 100317109Sbde const char * name; 10044Srgrimes 10054Srgrimes get_value_inc(regmodrm, loc, 1, FALSE); 10064Srgrimes fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)]; 10074Srgrimes mod = f_mod(regmodrm); 10084Srgrimes if (mod != 3) { 100921277Sbde if (*fp->f_name == '\0') { 101021277Sbde db_printf("<bad instruction>"); 101121277Sbde return (loc); 101221277Sbde } 10134Srgrimes /* 10144Srgrimes * Normal address modes. 10154Srgrimes */ 10164Srgrimes loc = db_read_address(loc, short_addr, regmodrm, &address); 101779885Skris db_printf("%s", fp->f_name); 10184Srgrimes switch(fp->f_size) { 10194Srgrimes case SNGL: 10204Srgrimes db_printf("s"); 10214Srgrimes break; 10224Srgrimes case DBLR: 10234Srgrimes db_printf("l"); 10244Srgrimes break; 10254Srgrimes case EXTR: 10264Srgrimes db_printf("t"); 10274Srgrimes break; 10284Srgrimes case WORD: 10294Srgrimes db_printf("s"); 10304Srgrimes break; 10314Srgrimes case LONG: 10324Srgrimes db_printf("l"); 10334Srgrimes break; 10344Srgrimes case QUAD: 10354Srgrimes db_printf("q"); 10364Srgrimes break; 10374Srgrimes default: 10384Srgrimes break; 10394Srgrimes } 10404Srgrimes db_printf("\t"); 10414Srgrimes db_print_address(seg, BYTE, &address); 10424Srgrimes } 10434Srgrimes else { 10444Srgrimes /* 10454Srgrimes * 'reg-reg' - special formats 10464Srgrimes */ 10474Srgrimes switch (fp->f_rrmode) { 10484Srgrimes case op2(ST,STI): 10494Srgrimes name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; 10504Srgrimes db_printf("%s\t%%st,%%st(%d)",name,f_rm(regmodrm)); 10514Srgrimes break; 10524Srgrimes case op2(STI,ST): 10534Srgrimes name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; 10544Srgrimes db_printf("%s\t%%st(%d),%%st",name, f_rm(regmodrm)); 10554Srgrimes break; 10564Srgrimes case op1(STI): 10574Srgrimes name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; 10584Srgrimes db_printf("%s\t%%st(%d)",name, f_rm(regmodrm)); 10594Srgrimes break; 10604Srgrimes case op1(X): 106121277Sbde name = ((const char * const *)fp->f_rrname)[f_rm(regmodrm)]; 106221277Sbde if (*name == '\0') 106321277Sbde goto bad; 106421277Sbde db_printf("%s", name); 10654Srgrimes break; 10664Srgrimes case op1(XA): 106721277Sbde name = ((const char * const *)fp->f_rrname)[f_rm(regmodrm)]; 106821277Sbde if (*name == '\0') 106921277Sbde goto bad; 107021277Sbde db_printf("%s\t%%ax", name); 10714Srgrimes break; 10724Srgrimes default: 107321277Sbde bad: 10744Srgrimes db_printf("<bad instruction>"); 10754Srgrimes break; 10764Srgrimes } 10774Srgrimes } 10784Srgrimes 10794Srgrimes return (loc); 10804Srgrimes} 10814Srgrimes 10824Srgrimes/* 10834Srgrimes * Disassemble instruction at 'loc'. 'altfmt' specifies an 10844Srgrimes * (optional) alternate format. Return address of start of 10854Srgrimes * next instruction. 10864Srgrimes */ 10874Srgrimesdb_addr_t 10884Srgrimesdb_disasm(loc, altfmt) 10894Srgrimes db_addr_t loc; 10904Srgrimes boolean_t altfmt; 10914Srgrimes{ 10924Srgrimes int inst; 10934Srgrimes int size; 10944Srgrimes int short_addr; 109517109Sbde const char * seg; 109614887Swollman const struct inst * ip; 109714887Swollman const char * i_name; 10984Srgrimes int i_size; 10994Srgrimes int i_mode; 1100798Swollman int regmodrm = 0; 11014Srgrimes boolean_t first; 11024Srgrimes int displ; 11034Srgrimes int prefix; 11044Srgrimes int imm; 11054Srgrimes int imm2; 11064Srgrimes int len; 11074Srgrimes struct i_addr address; 11084Srgrimes 11094Srgrimes get_value_inc(inst, loc, 1, FALSE); 11104Srgrimes short_addr = FALSE; 11114Srgrimes size = LONG; 11124Srgrimes seg = 0; 11134Srgrimes 11144Srgrimes /* 11154Srgrimes * Get prefixes 11164Srgrimes */ 11174Srgrimes prefix = TRUE; 11184Srgrimes do { 11194Srgrimes switch (inst) { 11204Srgrimes case 0x66: /* data16 */ 11214Srgrimes size = WORD; 11224Srgrimes break; 11234Srgrimes case 0x67: 11244Srgrimes short_addr = TRUE; 11254Srgrimes break; 11264Srgrimes case 0x26: 11274Srgrimes seg = "%es"; 11284Srgrimes break; 11294Srgrimes case 0x36: 11304Srgrimes seg = "%ss"; 11314Srgrimes break; 11324Srgrimes case 0x2e: 11334Srgrimes seg = "%cs"; 11344Srgrimes break; 11354Srgrimes case 0x3e: 11364Srgrimes seg = "%ds"; 11374Srgrimes break; 11384Srgrimes case 0x64: 11394Srgrimes seg = "%fs"; 11404Srgrimes break; 11414Srgrimes case 0x65: 11424Srgrimes seg = "%gs"; 11434Srgrimes break; 11444Srgrimes case 0xf0: 11454Srgrimes db_printf("lock "); 11464Srgrimes break; 11474Srgrimes case 0xf2: 11484Srgrimes db_printf("repne "); 11494Srgrimes break; 11504Srgrimes case 0xf3: 11514Srgrimes db_printf("repe "); /* XXX repe VS rep */ 11524Srgrimes break; 11534Srgrimes default: 11544Srgrimes prefix = FALSE; 11554Srgrimes break; 11564Srgrimes } 11574Srgrimes if (prefix) { 11584Srgrimes get_value_inc(inst, loc, 1, FALSE); 11594Srgrimes } 11604Srgrimes } while (prefix); 11614Srgrimes 11624Srgrimes if (inst >= 0xd8 && inst <= 0xdf) { 11634Srgrimes loc = db_disasm_esc(loc, inst, short_addr, size, seg); 11644Srgrimes db_printf("\n"); 11654Srgrimes return (loc); 11664Srgrimes } 11674Srgrimes 11684Srgrimes if (inst == 0x0f) { 11694Srgrimes get_value_inc(inst, loc, 1, FALSE); 11704Srgrimes ip = db_inst_0f[inst>>4]; 11714Srgrimes if (ip == 0) { 11724Srgrimes ip = &db_bad_inst; 11734Srgrimes } 11744Srgrimes else { 11754Srgrimes ip = &ip[inst&0xf]; 11764Srgrimes } 11774Srgrimes } 11784Srgrimes else 11794Srgrimes ip = &db_inst_table[inst]; 11804Srgrimes 11814Srgrimes if (ip->i_has_modrm) { 11824Srgrimes get_value_inc(regmodrm, loc, 1, FALSE); 11834Srgrimes loc = db_read_address(loc, short_addr, regmodrm, &address); 11844Srgrimes } 11854Srgrimes 11864Srgrimes i_name = ip->i_name; 11874Srgrimes i_size = ip->i_size; 11884Srgrimes i_mode = ip->i_mode; 11894Srgrimes 119017109Sbde if (ip->i_extra == db_Grp1 || ip->i_extra == db_Grp2 || 119117109Sbde ip->i_extra == db_Grp6 || ip->i_extra == db_Grp7 || 119221277Sbde ip->i_extra == db_Grp8 || ip->i_extra == db_Grp9) { 119317109Sbde i_name = ((const char * const *)ip->i_extra)[f_reg(regmodrm)]; 11944Srgrimes } 119517109Sbde else if (ip->i_extra == db_Grp3) { 119617109Sbde ip = ip->i_extra; 11974Srgrimes ip = &ip[f_reg(regmodrm)]; 11984Srgrimes i_name = ip->i_name; 11994Srgrimes i_mode = ip->i_mode; 12004Srgrimes } 120117109Sbde else if (ip->i_extra == db_Grp4 || ip->i_extra == db_Grp5) { 120217109Sbde ip = ip->i_extra; 12034Srgrimes ip = &ip[f_reg(regmodrm)]; 12044Srgrimes i_name = ip->i_name; 12054Srgrimes i_mode = ip->i_mode; 12064Srgrimes i_size = ip->i_size; 12074Srgrimes } 12084Srgrimes 12094Srgrimes if (i_size == SDEP) { 12104Srgrimes if (size == WORD) 121179885Skris db_printf("%s", i_name); 12124Srgrimes else 121379885Skris db_printf("%s", (const char *)ip->i_extra); 12144Srgrimes } 12154Srgrimes else { 121679885Skris db_printf("%s", i_name); 12174Srgrimes if (i_size != NONE) { 12184Srgrimes if (i_size == BYTE) { 12194Srgrimes db_printf("b"); 12204Srgrimes size = BYTE; 12214Srgrimes } 12224Srgrimes else if (i_size == WORD) { 12234Srgrimes db_printf("w"); 12244Srgrimes size = WORD; 12254Srgrimes } 12264Srgrimes else if (size == WORD) 12274Srgrimes db_printf("w"); 12284Srgrimes else 12294Srgrimes db_printf("l"); 12304Srgrimes } 12314Srgrimes } 12324Srgrimes db_printf("\t"); 12334Srgrimes for (first = TRUE; 12344Srgrimes i_mode != 0; 12354Srgrimes i_mode >>= 8, first = FALSE) 12364Srgrimes { 12374Srgrimes if (!first) 12384Srgrimes db_printf(","); 12394Srgrimes 12404Srgrimes switch (i_mode & 0xFF) { 12414Srgrimes 12424Srgrimes case E: 12434Srgrimes db_print_address(seg, size, &address); 12444Srgrimes break; 12454Srgrimes 12464Srgrimes case Eind: 12474Srgrimes db_printf("*"); 12484Srgrimes db_print_address(seg, size, &address); 12494Srgrimes break; 12504Srgrimes 125121277Sbde case El: 125221277Sbde db_print_address(seg, LONG, &address); 125321277Sbde break; 125421277Sbde 12554Srgrimes case Ew: 12564Srgrimes db_print_address(seg, WORD, &address); 12574Srgrimes break; 12584Srgrimes 12594Srgrimes case Eb: 12604Srgrimes db_print_address(seg, BYTE, &address); 12614Srgrimes break; 12624Srgrimes 12634Srgrimes case R: 12644Srgrimes db_printf("%s", db_reg[size][f_reg(regmodrm)]); 12654Srgrimes break; 12664Srgrimes 12674Srgrimes case Rw: 12684Srgrimes db_printf("%s", db_reg[WORD][f_reg(regmodrm)]); 12694Srgrimes break; 12704Srgrimes 12714Srgrimes case Ri: 12724Srgrimes db_printf("%s", db_reg[size][f_rm(inst)]); 12734Srgrimes break; 12744Srgrimes 127521277Sbde case Ril: 127621277Sbde db_printf("%s", db_reg[LONG][f_rm(inst)]); 127721277Sbde break; 127821277Sbde 12794Srgrimes case S: 12804Srgrimes db_printf("%s", db_seg_reg[f_reg(regmodrm)]); 12814Srgrimes break; 12824Srgrimes 12834Srgrimes case Si: 12844Srgrimes db_printf("%s", db_seg_reg[f_reg(inst)]); 12854Srgrimes break; 12864Srgrimes 12874Srgrimes case A: 12884Srgrimes db_printf("%s", db_reg[size][0]); /* acc */ 12894Srgrimes break; 12904Srgrimes 12914Srgrimes case BX: 12924Srgrimes if (seg) 12934Srgrimes db_printf("%s:", seg); 12944Srgrimes db_printf("(%s)", short_addr ? "%bx" : "%ebx"); 12954Srgrimes break; 12964Srgrimes 12974Srgrimes case CL: 12984Srgrimes db_printf("%%cl"); 12994Srgrimes break; 13004Srgrimes 13014Srgrimes case DX: 13024Srgrimes db_printf("%%dx"); 13034Srgrimes break; 13044Srgrimes 13054Srgrimes case SI: 13064Srgrimes if (seg) 13074Srgrimes db_printf("%s:", seg); 13084Srgrimes db_printf("(%s)", short_addr ? "%si" : "%esi"); 13094Srgrimes break; 13104Srgrimes 13114Srgrimes case DI: 13124Srgrimes db_printf("%%es:(%s)", short_addr ? "%di" : "%edi"); 13134Srgrimes break; 13144Srgrimes 13154Srgrimes case CR: 13164Srgrimes db_printf("%%cr%d", f_reg(regmodrm)); 13174Srgrimes break; 13184Srgrimes 13194Srgrimes case DR: 13204Srgrimes db_printf("%%dr%d", f_reg(regmodrm)); 13214Srgrimes break; 13224Srgrimes 13234Srgrimes case TR: 13244Srgrimes db_printf("%%tr%d", f_reg(regmodrm)); 13254Srgrimes break; 13264Srgrimes 13274Srgrimes case I: 13284Srgrimes len = db_lengths[size]; 132921277Sbde get_value_inc(imm, loc, len, FALSE); 133037506Sbde db_printf("$%#r", imm); 13314Srgrimes break; 13324Srgrimes 13334Srgrimes case Is: 13344Srgrimes len = db_lengths[size]; 133521277Sbde get_value_inc(imm, loc, len, FALSE); 133637506Sbde db_printf("$%+#r", imm); 13374Srgrimes break; 13384Srgrimes 13394Srgrimes case Ib: 134021277Sbde get_value_inc(imm, loc, 1, FALSE); 134137506Sbde db_printf("$%#r", imm); 13424Srgrimes break; 13434Srgrimes 134421277Sbde case Iba: 134521277Sbde get_value_inc(imm, loc, 1, FALSE); 134621277Sbde if (imm != 0x0a) 134737506Sbde db_printf("$%#r", imm); 134821277Sbde break; 134921277Sbde 13504Srgrimes case Ibs: 135121277Sbde get_value_inc(imm, loc, 1, TRUE); 135221277Sbde if (size == WORD) 135321277Sbde imm &= 0xFFFF; 135437506Sbde db_printf("$%+#r", imm); 13554Srgrimes break; 13564Srgrimes 13574Srgrimes case Iw: 135821277Sbde get_value_inc(imm, loc, 2, FALSE); 135937506Sbde db_printf("$%#r", imm); 13604Srgrimes break; 13614Srgrimes 13624Srgrimes case O: 136321277Sbde len = (short_addr ? 2 : 4); 136421277Sbde get_value_inc(displ, loc, len, FALSE); 13654Srgrimes if (seg) 136637506Sbde db_printf("%s:%+#r",seg, displ); 13674Srgrimes else 13684Srgrimes db_printsym((db_addr_t)displ, DB_STGY_ANY); 13694Srgrimes break; 13704Srgrimes 13714Srgrimes case Db: 13724Srgrimes get_value_inc(displ, loc, 1, TRUE); 137321277Sbde displ += loc; 137421277Sbde if (size == WORD) 137521277Sbde displ &= 0xFFFF; 137621277Sbde db_printsym((db_addr_t)displ, DB_STGY_XTRN); 13774Srgrimes break; 13784Srgrimes 13794Srgrimes case Dl: 138021277Sbde len = db_lengths[size]; 138121277Sbde get_value_inc(displ, loc, len, FALSE); 138221277Sbde displ += loc; 138321277Sbde if (size == WORD) 138421277Sbde displ &= 0xFFFF; 138521277Sbde db_printsym((db_addr_t)displ, DB_STGY_XTRN); 13864Srgrimes break; 13874Srgrimes 13884Srgrimes case o1: 13894Srgrimes db_printf("$1"); 13904Srgrimes break; 13914Srgrimes 13924Srgrimes case o3: 13934Srgrimes db_printf("$3"); 13944Srgrimes break; 13954Srgrimes 13964Srgrimes case OS: 139721277Sbde len = db_lengths[size]; 139821277Sbde get_value_inc(imm, loc, len, FALSE); /* offset */ 13994Srgrimes get_value_inc(imm2, loc, 2, FALSE); /* segment */ 140037506Sbde db_printf("$%#r,%#r", imm2, imm); 14014Srgrimes break; 14024Srgrimes } 14034Srgrimes } 14044Srgrimes db_printf("\n"); 14054Srgrimes return (loc); 14064Srgrimes} 1407