blob: fcbd6d3884ffeb0ef7c921bdbf53bbe7e8ca7c28 [file] [log] [blame]
Alexandre Julliard18506551995-01-24 16:21:01 +00001/*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26/*
27 * HISTORY
Alexandre Julliarda845b881998-06-01 10:44:35 +000028 *
Alexandre Julliard18506551995-01-24 16:21:01 +000029 * Revision 2.6 92/01/03 20:05:00 dbg
30 * Add a switch to disassemble 16-bit code.
31 * Fix spelling of 'lods' opcodes.
32 * [91/10/30 dbg]
33 *
34 * Revision 2.5 91/10/09 16:05:58 af
35 * Supported disassemble of non current task by passing task parameter.
36 * [91/08/29 tak]
37 *
38 * Revision 2.4 91/05/14 16:05:04 mrt
39 * Correcting copyright
40 *
41 * Revision 2.3 91/02/05 17:11:03 mrt
42 * Changed to new Mach copyright
43 * [91/02/01 17:31:03 mrt]
44 *
45 * Revision 2.2 90/08/27 21:55:56 dbg
46 * Fix register operand for move to/from control/test/debug
47 * register instructions. Add i486 instructions.
48 * [90/08/27 dbg]
49 *
50 * Import db_sym.h. Print instruction displacements in
51 * current radix (signed). Change calling sequence of
52 * db_disasm.
53 * [90/08/21 dbg]
54 * Fix includes.
55 * [90/08/08 dbg]
56 * Created.
57 * [90/07/25 dbg]
58 *
59 */
60
61/*
62 * Instruction disassembler.
63 */
Alexandre Julliard18506551995-01-24 16:21:01 +000064
Alexandre Julliard808cb041995-08-17 17:11:36 +000065#include "debugger.h"
Alexandre Julliard18506551995-01-24 16:21:01 +000066
Ulrich Weigandb3ec4b91999-11-13 20:58:45 +000067#ifdef __i386__
68
Alexandre Julliard18506551995-01-24 16:21:01 +000069/*
70 * Switch to disassemble 16-bit code.
71 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000072static BOOL db_disasm_16 = FALSE;
Alexandre Julliard18506551995-01-24 16:21:01 +000073
74/*
Alexandre Julliardc6c09441997-01-12 18:32:19 +000075 * Flag to indicate whether we need to display instruction,
76 * or whether we just need to know the address of the next
77 * instruction.
78 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000079static BOOL db_display = FALSE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +000080
81/*
Alexandre Julliard18506551995-01-24 16:21:01 +000082 * Size attributes
83 */
84#define BYTE 0
85#define WORD 1
86#define LONG 2
87#define QUAD 3
88#define SNGL 4
89#define DBLR 5
90#define EXTR 6
91#define SDEP 7
92#define NONE 8
93
94/*
95 * Addressing modes
96 */
97#define E 1 /* general effective address */
98#define Eind 2 /* indirect address (jump, call) */
99#define Ew 3 /* address, word size */
100#define Eb 4 /* address, byte size */
101#define R 5 /* register, in 'reg' field */
102#define Rw 6 /* word register, in 'reg' field */
103#define Ri 7 /* register in instruction */
104#define S 8 /* segment reg, in 'reg' field */
105#define Si 9 /* segment reg, in instruction */
106#define A 10 /* accumulator */
107#define BX 11 /* (bx) */
108#define CL 12 /* cl, for shifts */
109#define DX 13 /* dx, for IO */
110#define SI 14 /* si */
111#define DI 15 /* di */
112#define CR 16 /* control register */
113#define DR 17 /* debug register */
114#define TR 18 /* test register */
115#define I 19 /* immediate, unsigned */
116#define Is 20 /* immediate, signed */
117#define Ib 21 /* byte immediate, unsigned */
118#define Ibs 22 /* byte immediate, signed */
119#define Iw 23 /* word immediate, unsigned */
120#define Il 24 /* long immediate */
121#define O 25 /* direct address */
122#define Db 26 /* byte displacement from EIP */
123#define Dl 27 /* long displacement from EIP */
124#define o1 28 /* constant 1 */
125#define o3 29 /* constant 3 */
126#define OS 30 /* immediate offset/segment */
127#define ST 31 /* FP stack top */
128#define STI 32 /* FP stack */
129#define X 33 /* extended FP op */
130#define XA 34 /* for 'fstcw %ax' */
Alexandre Julliard9107c6b2001-07-11 17:33:47 +0000131#define MX 35 /* special register (MMX reg %mm0-7) */
132#define EMX 36 /* special register (MMX reg %mm0-7) */
133#define XMM 37 /* special register (floating point reg %xmm0-7) */
134#define EXMM 38 /* special register (floating point reg %xmm0-7) */
Alexandre Julliard18506551995-01-24 16:21:01 +0000135
136struct inst {
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000137 const char *i_name; /* name */
138 short i_has_modrm; /* has regmodrm byte */
139 short i_size; /* operand size */
140 int i_mode; /* addressing modes */
141 const char *i_extra; /* pointer to extra opcode table */
Alexandre Julliard18506551995-01-24 16:21:01 +0000142};
143
144#define op1(x) (x)
145#define op2(x,y) ((x)|((y)<<8))
146#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
147
148struct finst {
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000149 const char *f_name; /* name for memory instruction */
150 int f_size; /* size for memory instruction */
151 int f_rrmode; /* mode for rr instruction */
152 const char *f_rrname; /* name for rr instruction
Alexandre Julliard18506551995-01-24 16:21:01 +0000153 (or pointer to table) */
154};
155
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000156static const char * const db_Grp6[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000157 "sldt",
158 "str",
159 "lldt",
160 "ltr",
161 "verr",
162 "verw",
163 "",
164 ""
165};
166
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000167static const char * const db_Grp7[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000168 "sgdt",
169 "sidt",
170 "lgdt",
171 "lidt",
172 "smsw",
173 "",
174 "lmsw",
175 "invlpg"
176};
177
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000178static const char * const db_Grp8[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000179 "",
180 "",
181 "",
182 "",
183 "bt",
184 "bts",
185 "btr",
186 "btc"
187};
188
Marcus Meissnerea1576b2001-04-23 18:11:17 +0000189static const char * const db_Grp10[] = {
190 "(bad)",
191 "(bad)",
192 "psrlw",
193 "(bad)",
194 "psraw",
195 "(bad)",
196 "psllw",
197 "(bad)"
198};
199
200static const char * const db_Grp11[] = {
201 "(bad)",
202 "(bad)",
203 "psrld",
204 "(bad)",
205 "psrad",
206 "(bad)",
207 "pslld",
208 "(bad)"
209};
210
211static const char * const db_Grp12[] = {
212 "(bad)",
213 "(bad)",
214 "psrlq",
215 "(bad)",
216 "psraq",
217 "(bad)",
218 "psllq",
219 "(bad)"
220};
221
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000222static const struct inst db_inst_0f0x[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000223/*00*/ { "", TRUE, NONE, op1(Ew), (char *)db_Grp6 },
224/*01*/ { "", TRUE, NONE, op1(Ew), (char *)db_Grp7 },
225/*02*/ { "lar", TRUE, LONG, op2(E,R), 0 },
226/*03*/ { "lsl", TRUE, LONG, op2(E,R), 0 },
227/*04*/ { "", FALSE, NONE, 0, 0 },
228/*05*/ { "", FALSE, NONE, 0, 0 },
229/*06*/ { "clts", FALSE, NONE, 0, 0 },
230/*07*/ { "", FALSE, NONE, 0, 0 },
231
232/*08*/ { "invd", FALSE, NONE, 0, 0 },
233/*09*/ { "wbinvd",FALSE, NONE, 0, 0 },
234/*0a*/ { "", FALSE, NONE, 0, 0 },
235/*0b*/ { "", FALSE, NONE, 0, 0 },
236/*0c*/ { "", FALSE, NONE, 0, 0 },
237/*0d*/ { "", FALSE, NONE, 0, 0 },
238/*0e*/ { "", FALSE, NONE, 0, 0 },
239/*0f*/ { "", FALSE, NONE, 0, 0 },
240};
241
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000242static const struct inst db_inst_0f2x[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000243/*20*/ { "mov", TRUE, LONG, op2(CR,E), 0 }, /* use E for reg */
244/*21*/ { "mov", TRUE, LONG, op2(DR,E), 0 }, /* since mod == 11 */
245/*22*/ { "mov", TRUE, LONG, op2(E,CR), 0 },
246/*23*/ { "mov", TRUE, LONG, op2(E,DR), 0 },
247/*24*/ { "mov", TRUE, LONG, op2(TR,E), 0 },
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000248/*25*/ { "(bad)", FALSE, NONE, 0, 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000249/*26*/ { "mov", TRUE, LONG, op2(E,TR), 0 },
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000250/*27*/ { "(bad)", FALSE, NONE, 0, 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000251
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000252/*28*/ { "", FALSE, NONE, 0, 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000253/*29*/ { "", FALSE, NONE, 0, 0 },
254/*2a*/ { "", FALSE, NONE, 0, 0 },
255/*2b*/ { "", FALSE, NONE, 0, 0 },
256/*2c*/ { "", FALSE, NONE, 0, 0 },
257/*2d*/ { "", FALSE, NONE, 0, 0 },
258/*2e*/ { "", FALSE, NONE, 0, 0 },
259/*2f*/ { "", FALSE, NONE, 0, 0 },
260};
261
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000262static const struct inst db_inst_0f3x[] = {
Alexandre Julliard9107c6b2001-07-11 17:33:47 +0000263/*30*/ { "wrmsr", FALSE, NONE, 0, 0 },
264/*31*/ { "rdtsc", FALSE, NONE, 0, 0 },
265/*32*/ { "rdmsr", FALSE, NONE, 0, 0 },
266/*33*/ { "rdpmc", FALSE, NONE, 0, 0 },
267/*34*/ { "sysenter",FALSE,NONE, 0, 0 },
268/*35*/ { "sysexit",FALSE,NONE, 0, 0 },
269/*36*/ { "(bad)", FALSE, NONE, 0, 0 },
270/*37*/ { "(bad)", FALSE, NONE, 0, 0 },
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000271
Alexandre Julliard9107c6b2001-07-11 17:33:47 +0000272/*38*/ { "(bad)",FALSE, NONE, 0, 0 },
273/*39*/ { "(bad)",FALSE, NONE, 0, 0 },
274/*3a*/ { "(bad)",FALSE, NONE, 0, 0 },
275/*3b*/ { "(bad)",FALSE, NONE, 0, 0 },
276/*3c*/ { "(bad)",FALSE, NONE, 0, 0 },
277/*3d*/ { "(bad)",FALSE, NONE, 0, 0 },
278/*3e*/ { "(bad)",FALSE, NONE, 0, 0 },
279/*3f*/ { "(bad)",FALSE, NONE, 0, 0 },
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000280};
281
Ian Schmidt4474b6e2000-07-15 14:57:13 +0000282static const struct inst db_inst_0f4x[] = {
283/*40*/ { "cmovo", TRUE, NONE, op2(E, R), 0 },
284/*41*/ { "cmovno", TRUE, NONE, op2(E, R), 0 },
285/*42*/ { "cmovnae",TRUE, NONE, op2(E, R), 0 },
286/*43*/ { "cmovnb", TRUE, NONE, op2(E, R), 0 },
287/*44*/ { "cmove", TRUE, NONE, op2(E, R), 0 },
288/*45*/ { "cmovne", TRUE, NONE, op2(E, R), 0 },
289/*46*/ { "cmovna", TRUE, NONE, op2(E, R), 0 },
290/*47*/ { "cmova", TRUE, NONE, op2(E, R), 0 },
291
292/*48*/ { "cmovs", TRUE, NONE, op2(E, R), 0 },
293/*49*/ { "cmovns", TRUE, NONE, op2(E, R), 0 },
294/*4a*/ { "cmovpe", TRUE, NONE, op2(E, R), 0 },
295/*4b*/ { "cmovpo", TRUE, NONE, op2(E, R), 0 },
296/*4c*/ { "cmovl", TRUE, NONE, op2(E, R), 0 },
297/*4d*/ { "cmovge", TRUE, NONE, op2(E, R), 0 },
298/*4e*/ { "cmovle", TRUE, NONE, op2(E, R), 0 },
299/*4f*/ { "cmovnle",TRUE, NONE, op2(E, R), 0 },
300};
301
Alexandre Julliard9107c6b2001-07-11 17:33:47 +0000302static const struct inst db_inst_0f5x[] = {
303/*50*/ { "movmskps",TRUE, NONE, op2(E, XMM), 0 },
304/*51*/ { "sqrtps", TRUE, NONE, op2(XMM, EXMM), 0 },
305/*52*/ { "rsqrtps", TRUE, NONE, op2(XMM, EXMM), 0 },
306/*53*/ { "rcpps", TRUE, NONE, op2(XMM, EXMM), 0 },
307/*54*/ { "andps", TRUE, NONE, op2(XMM, EXMM), 0 },
308/*55*/ { "andnps", TRUE, NONE, op2(XMM, EXMM), 0 },
309/*56*/ { "orps", TRUE, NONE, op2(XMM, EXMM), 0 },
310/*57*/ { "xorps", TRUE, NONE, op2(XMM, EXMM), 0 },
311
312/*58*/ { "addps", TRUE, NONE, op2(XMM, EXMM), 0 },
313/*59*/ { "mulps", TRUE, NONE, op2(XMM, EXMM), 0 },
314/*5a*/ { "(bad)", FALSE, NONE, 0, 0 },
315/*5b*/ { "(bad)", FALSE, NONE, 0, 0 },
316/*5c*/ { "subps", TRUE, NONE, op2(XMM, EXMM), 0 },
317/*5d*/ { "minps", TRUE, NONE, op2(XMM, EXMM), 0 },
318/*5e*/ { "divps", TRUE, NONE, op2(XMM, EXMM), 0 },
319/*5f*/ { "maxps", TRUE, NONE, op2(XMM, EXMM), 0 },
320};
321
Marcus Meissnerea1576b2001-04-23 18:11:17 +0000322static const struct inst db_inst_0f6x[] = {
323/*60*/ { "punpcklbw", TRUE, NONE, op2(E, MX), 0 },
324/*61*/ { "punpcklwd", TRUE, NONE, op2(E, MX), 0 },
325/*62*/ { "punpckldq", TRUE, NONE, op2(E, MX), 0 },
326/*63*/ { "packsswb", TRUE, NONE, op2(E, MX), 0 },
327/*64*/ { "pcmpgtb", TRUE, NONE, op2(E, MX), 0 },
328/*65*/ { "pcmpgtw", TRUE, NONE, op2(E, MX), 0 },
329/*66*/ { "pcmpgtd", TRUE, NONE, op2(E, MX), 0 },
330/*67*/ { "packuswb", TRUE, NONE, op2(E, MX), 0 },
331
332/*68*/ { "punpckhbw", TRUE, NONE, op2(E, MX), 0 },
333/*69*/ { "punpckhwd", TRUE, NONE, op2(E, MX), 0 },
334/*6a*/ { "punpckhdq", TRUE, NONE, op2(E, MX), 0 },
335/*6b*/ { "packssdw", TRUE, NONE, op2(E, MX), 0 },
336/*6c*/ { "(bad)", TRUE, NONE, 0, 0 },
337/*6d*/ { "(bad)", TRUE, NONE, 0, 0 },
338/*6e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
339/*6f*/ { "movq", TRUE, NONE, op2(E, MX), 0 },
340};
341
342static const struct inst db_inst_0f7x[] = {
343/*70*/ { "pshufw", TRUE, NONE, op2(MX, EMX), 0 },
344/*71*/ { "(grp10)", TRUE, BYTE, op2(EMX, I), (char*)db_Grp10 },
345/*72*/ { "(grp11)", TRUE, BYTE, op2(EMX, I), (char*)db_Grp11 },
346/*73*/ { "(grp12)", TRUE, BYTE, op2(EMX, I), (char*)db_Grp12 },
347/*74*/ { "pcmpeqb", TRUE, NONE, op2(E, MX), 0 },
348/*75*/ { "pcmpeqw", TRUE, NONE, op2(E, MX), 0 },
349/*76*/ { "pcmpeqd", TRUE, NONE, op2(E, MX), 0 },
350/*77*/ { "emms", FALSE,NONE, 0, 0 },
351
352/*78*/ { "(bad)", TRUE, NONE, 0, 0 },
353/*79*/ { "(bad)", TRUE, NONE, 0, 0 },
354/*7a*/ { "(bad)", TRUE, NONE, 0, 0 },
355/*7b*/ { "(bad)", TRUE, NONE, 0, 0 },
356/*7c*/ { "(bad)", TRUE, NONE, 0, 0 },
357/*7d*/ { "(bad)", TRUE, NONE, 0, 0 },
358/*7e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
359/*7f*/ { "movq", TRUE, NONE, op2(EMX, MX), 0 },
360};
361
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000362static const struct inst db_inst_0f8x[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000363/*80*/ { "jo", FALSE, NONE, op1(Dl), 0 },
364/*81*/ { "jno", FALSE, NONE, op1(Dl), 0 },
365/*82*/ { "jb", FALSE, NONE, op1(Dl), 0 },
366/*83*/ { "jnb", FALSE, NONE, op1(Dl), 0 },
367/*84*/ { "jz", FALSE, NONE, op1(Dl), 0 },
368/*85*/ { "jnz", FALSE, NONE, op1(Dl), 0 },
369/*86*/ { "jbe", FALSE, NONE, op1(Dl), 0 },
370/*87*/ { "jnbe", FALSE, NONE, op1(Dl), 0 },
371
372/*88*/ { "js", FALSE, NONE, op1(Dl), 0 },
373/*89*/ { "jns", FALSE, NONE, op1(Dl), 0 },
374/*8a*/ { "jp", FALSE, NONE, op1(Dl), 0 },
375/*8b*/ { "jnp", FALSE, NONE, op1(Dl), 0 },
376/*8c*/ { "jl", FALSE, NONE, op1(Dl), 0 },
377/*8d*/ { "jnl", FALSE, NONE, op1(Dl), 0 },
378/*8e*/ { "jle", FALSE, NONE, op1(Dl), 0 },
379/*8f*/ { "jnle", FALSE, NONE, op1(Dl), 0 },
380};
381
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000382static const struct inst db_inst_0f9x[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000383/*90*/ { "seto", TRUE, NONE, op1(Eb), 0 },
384/*91*/ { "setno", TRUE, NONE, op1(Eb), 0 },
385/*92*/ { "setb", TRUE, NONE, op1(Eb), 0 },
386/*93*/ { "setnb", TRUE, NONE, op1(Eb), 0 },
387/*94*/ { "setz", TRUE, NONE, op1(Eb), 0 },
388/*95*/ { "setnz", TRUE, NONE, op1(Eb), 0 },
389/*96*/ { "setbe", TRUE, NONE, op1(Eb), 0 },
390/*97*/ { "setnbe",TRUE, NONE, op1(Eb), 0 },
391
392/*98*/ { "sets", TRUE, NONE, op1(Eb), 0 },
393/*99*/ { "setns", TRUE, NONE, op1(Eb), 0 },
394/*9a*/ { "setp", TRUE, NONE, op1(Eb), 0 },
395/*9b*/ { "setnp", TRUE, NONE, op1(Eb), 0 },
396/*9c*/ { "setl", TRUE, NONE, op1(Eb), 0 },
397/*9d*/ { "setnl", TRUE, NONE, op1(Eb), 0 },
398/*9e*/ { "setle", TRUE, NONE, op1(Eb), 0 },
399/*9f*/ { "setnle",TRUE, NONE, op1(Eb), 0 },
400};
401
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000402static const struct inst db_inst_0fax[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000403/*a0*/ { "push", FALSE, NONE, op1(Si), 0 },
404/*a1*/ { "pop", FALSE, NONE, op1(Si), 0 },
Alexandre Julliard02e90081998-01-04 17:49:09 +0000405/*a2*/ { "cpuid", FALSE, NONE, 0, 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000406/*a3*/ { "bt", TRUE, LONG, op2(E,R), 0 },
407/*a4*/ { "shld", TRUE, LONG, op3(Ib,E,R), 0 },
408/*a5*/ { "shld", TRUE, LONG, op3(CL,E,R), 0 },
409/*a6*/ { "", FALSE, NONE, 0, 0 },
410/*a7*/ { "", FALSE, NONE, 0, 0 },
411
412/*a8*/ { "push", FALSE, NONE, op1(Si), 0 },
413/*a9*/ { "pop", FALSE, NONE, op1(Si), 0 },
414/*aa*/ { "", FALSE, NONE, 0, 0 },
415/*ab*/ { "bts", TRUE, LONG, op2(E,R), 0 },
416/*ac*/ { "shrd", TRUE, LONG, op3(Ib,E,R), 0 },
417/*ad*/ { "shrd", TRUE, LONG, op3(CL,E,R), 0 },
418/*a6*/ { "", FALSE, NONE, 0, 0 },
419/*a7*/ { "imul", TRUE, LONG, op2(E,R), 0 },
420};
421
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000422static const struct inst db_inst_0fbx[] = {
Alexandre Julliard02e90081998-01-04 17:49:09 +0000423/*b0*/ { "cmpxchg",TRUE, BYTE, op2(E, R), 0 },
424/*b1*/ { "cmpxchg",TRUE, LONG, op2(E, R), 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000425/*b2*/ { "lss", TRUE, LONG, op2(E, R), 0 },
426/*b3*/ { "bts", TRUE, LONG, op2(R, E), 0 },
427/*b4*/ { "lfs", TRUE, LONG, op2(E, R), 0 },
428/*b5*/ { "lgs", TRUE, LONG, op2(E, R), 0 },
429/*b6*/ { "movzb", TRUE, LONG, op2(E, R), 0 },
430/*b7*/ { "movzw", TRUE, LONG, op2(E, R), 0 },
431
432/*b8*/ { "", FALSE, NONE, 0, 0 },
433/*b9*/ { "", FALSE, NONE, 0, 0 },
Ulrich Weigandd47cdaf1999-06-27 15:29:43 +0000434/*ba*/ { "", TRUE, LONG, op2(Ib, E), (char *)db_Grp8 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000435/*bb*/ { "btc", TRUE, LONG, op2(R, E), 0 },
436/*bc*/ { "bsf", TRUE, LONG, op2(E, R), 0 },
437/*bd*/ { "bsr", TRUE, LONG, op2(E, R), 0 },
438/*be*/ { "movsb", TRUE, LONG, op2(E, R), 0 },
439/*bf*/ { "movsw", TRUE, LONG, op2(E, R), 0 },
440};
441
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000442static const struct inst db_inst_0fcx[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000443/*c0*/ { "xadd", TRUE, BYTE, op2(R, E), 0 },
444/*c1*/ { "xadd", TRUE, LONG, op2(R, E), 0 },
445/*c2*/ { "", FALSE, NONE, 0, 0 },
446/*c3*/ { "", FALSE, NONE, 0, 0 },
447/*c4*/ { "", FALSE, NONE, 0, 0 },
448/*c5*/ { "", FALSE, NONE, 0, 0 },
449/*c6*/ { "", FALSE, NONE, 0, 0 },
450/*c7*/ { "", FALSE, NONE, 0, 0 },
451/*c8*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
452/*c9*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
453/*ca*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
454/*cb*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
455/*cc*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
456/*cd*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
457/*ce*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
458/*cf*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
459};
460
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000461static const struct inst db_inst_0fdx[] = {
Marcus Meissnerea1576b2001-04-23 18:11:17 +0000462/*d0*/ { "(bad)", FALSE, NONE,0, 0 },
463/*d1*/ { "psrlw", TRUE, NONE,op2(MX,EMX), 0 },
464/*d2*/ { "psrld", TRUE, NONE,op2(MX,EMX), 0 },
465/*d3*/ { "psrld", TRUE, NONE,op2(MX,EMX), 0 },
466/*d4*/ { "(bad)", FALSE, NONE,0, 0 },
467/*d5*/ { "pmulww", TRUE, NONE,op2(MX,EMX), 0 },
468/*d6*/ { "(bad)", FALSE, NONE,0, 0 },
469/*d7*/ { "pmovmskb",FALSE, NONE,op2(MX,EMX),0 },
470/*d8*/ { "psubusb", TRUE, NONE,op2(MX,EMX), 0 },
471/*d9*/ { "psubusw", TRUE, NONE,op2(MX,EMX), 0 },
472/*da*/ { "pminub", TRUE, NONE,op2(MX,EMX), 0 },
473/*db*/ { "pand", TRUE, NONE,op2(MX,EMX), 0 },
474/*dc*/ { "paddusb", TRUE, NONE,op2(MX,EMX), 0 },
475/*dd*/ { "paddusw", TRUE, NONE,op2(MX,EMX), 0 },
476/*de*/ { "pmaxub", TRUE, NONE,op2(MX,EMX), 0 },
477/*df*/ { "pandn", TRUE, NONE,op2(MX,EMX), 0 },
478};
479
480static const struct inst db_inst_0fex[] = {
481/*e0*/ { "pavgb", TRUE, NONE, op2(MX, EMX), 0 },
482/*e1*/ { "psraw", TRUE, NONE, op2(MX, EMX), 0 },
483/*e2*/ { "psrad", TRUE, NONE, op2(MX, EMX), 0 },
484/*e3*/ { "pavgw", TRUE, NONE, op2(MX, EMX), 0 },
485/*e4*/ { "pmulhuw",TRUE, NONE, op2(MX, EMX), 0 },
486/*e5*/ { "pmulhw", TRUE, NONE, op2(MX, EMX), 0 },
487/*e6*/ { "(bad)", FALSE,NONE, 0, 0 },
488/*e7*/ { "movntq", TRUE, NONE, op2(MX, EMX), 0 },
489/*e8*/ { "psubsb", TRUE, NONE, op2(MX, EMX), 0 },
490/*e9*/ { "psubsw", TRUE, NONE, op2(MX, EMX), 0 },
491/*ea*/ { "pminsw", TRUE, NONE, op2(MX, EMX), 0 },
492/*eb*/ { "por", TRUE, NONE, op2(MX, EMX), 0 },
493/*ec*/ { "paddsb", TRUE, NONE, op2(MX, EMX), 0 },
494/*ed*/ { "paddsw", TRUE, NONE, op2(MX, EMX), 0 },
495/*ee*/ { "pmaxsw", TRUE, NONE, op2(MX, EMX), 0 },
496/*ef*/ { "pxor", TRUE, NONE, op2(MX, EMX), 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000497};
498
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000499static const struct inst db_inst_0ffx[] = {
500/*f0*/ { "(bad)", FALSE,NONE, 0, 0 },
501/*f1*/ { "psllw", TRUE, NONE, op2(MX, EMX), 0 },
502/*f2*/ { "pslld", TRUE, NONE, op2(MX, EMX), 0 },
503/*f3*/ { "psllq", TRUE, NONE, op2(MX, EMX), 0 },
504/*f4*/ { "(bad)", FALSE,NONE, 0, 0 },
505/*f5*/ { "pmaddwd",TRUE, NONE, op2(MX, EMX), 0 },
506/*f6*/ { "psadbw", TRUE, NONE, op2(MX, EMX), 0 },
507/*f7*/ { "maskmovq",TRUE,NONE, op2(MX, EMX), 0 },
508/*f8*/ { "psubb", TRUE, NONE, op2(MX, EMX), 0 },
509/*f9*/ { "psubw", TRUE, NONE, op2(MX, EMX), 0 },
510/*fa*/ { "psubd", TRUE, NONE, op2(MX, EMX), 0 },
511/*fb*/ { "(bad)", FALSE,NONE, 0, 0 },
512/*fc*/ { "paddb", TRUE, NONE, op2(MX, EMX), 0 },
513/*fd*/ { "paddw", TRUE, NONE, op2(MX, EMX), 0 },
514/*fe*/ { "paddd", TRUE, NONE, op2(MX, EMX), 0 },
515/*ff*/ { "(bad)", FALSE, NONE, 0, 0 },
516};
517
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000518static const struct inst * const db_inst_0f[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000519 db_inst_0f0x,
520 0,
521 db_inst_0f2x,
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000522 db_inst_0f3x,
Ian Schmidt4474b6e2000-07-15 14:57:13 +0000523 db_inst_0f4x,
Alexandre Julliard9107c6b2001-07-11 17:33:47 +0000524 db_inst_0f5x,
Marcus Meissnerea1576b2001-04-23 18:11:17 +0000525 db_inst_0f6x,
526 db_inst_0f7x,
Alexandre Julliard18506551995-01-24 16:21:01 +0000527 db_inst_0f8x,
528 db_inst_0f9x,
529 db_inst_0fax,
530 db_inst_0fbx,
531 db_inst_0fcx,
532 db_inst_0fdx,
Marcus Meissnerea1576b2001-04-23 18:11:17 +0000533 db_inst_0fex,
Marcus Meissner5e2eeb62001-04-24 23:16:16 +0000534 db_inst_0ffx
Alexandre Julliard18506551995-01-24 16:21:01 +0000535};
536
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000537static const char * const db_Esc92[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000538 "fnop", "", "", "", "", "", "", ""
539};
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000540static const char * const db_Esc93[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000541 "", "", "", "", "", "", "", ""
542};
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000543static const char * const db_Esc94[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000544 "fchs", "fabs", "", "", "ftst", "fxam", "", ""
545};
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000546static const char * const db_Esc95[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000547 "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
548};
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000549static const char * const db_Esc96[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000550 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
551 "fincstp"
552};
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000553static const char * const db_Esc97[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000554 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
555};
556
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000557static const char * const db_Esca4[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000558 "", "fucompp","", "", "", "", "", ""
559};
560
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000561static const char * const db_Escb4[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000562 "", "", "fnclex","fninit","", "", "", ""
563};
564
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000565static const char * const db_Esce3[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000566 "", "fcompp","", "", "", "", "", ""
567};
568
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000569static const char * const db_Escf4[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000570 "fnstsw","", "", "", "", "", "", ""
571};
572
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000573static const struct finst db_Esc8[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000574/*0*/ { "fadd", SNGL, op2(STI,ST), 0 },
575/*1*/ { "fmul", SNGL, op2(STI,ST), 0 },
576/*2*/ { "fcom", SNGL, op2(STI,ST), 0 },
577/*3*/ { "fcomp", SNGL, op2(STI,ST), 0 },
578/*4*/ { "fsub", SNGL, op2(STI,ST), 0 },
579/*5*/ { "fsubr", SNGL, op2(STI,ST), 0 },
580/*6*/ { "fdiv", SNGL, op2(STI,ST), 0 },
581/*7*/ { "fdivr", SNGL, op2(STI,ST), 0 },
582};
583
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000584static const struct finst db_Esc9[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000585/*0*/ { "fld", SNGL, op1(STI), 0 },
586/*1*/ { "", NONE, op1(STI), "fxch" },
587/*2*/ { "fst", SNGL, op1(X), (char *)db_Esc92 },
588/*3*/ { "fstp", SNGL, op1(X), (char *)db_Esc93 },
589/*4*/ { "fldenv", NONE, op1(X), (char *)db_Esc94 },
590/*5*/ { "fldcw", NONE, op1(X), (char *)db_Esc95 },
591/*6*/ { "fnstenv",NONE, op1(X), (char *)db_Esc96 },
592/*7*/ { "fnstcw", NONE, op1(X), (char *)db_Esc97 },
593};
594
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000595static const struct finst db_Esca[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000596/*0*/ { "fiadd", WORD, 0, 0 },
597/*1*/ { "fimul", WORD, 0, 0 },
598/*2*/ { "ficom", WORD, 0, 0 },
599/*3*/ { "ficomp", WORD, 0, 0 },
600/*4*/ { "fisub", WORD, op1(X), (char *)db_Esca4 },
601/*5*/ { "fisubr", WORD, 0, 0 },
602/*6*/ { "fidiv", WORD, 0, 0 },
603/*7*/ { "fidivr", WORD, 0, 0 }
604};
605
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000606static const struct finst db_Escb[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000607/*0*/ { "fild", WORD, 0, 0 },
608/*1*/ { "", NONE, 0, 0 },
609/*2*/ { "fist", WORD, 0, 0 },
610/*3*/ { "fistp", WORD, 0, 0 },
611/*4*/ { "", WORD, op1(X), (char *)db_Escb4 },
612/*5*/ { "fld", EXTR, 0, 0 },
613/*6*/ { "", WORD, 0, 0 },
614/*7*/ { "fstp", EXTR, 0, 0 },
615};
616
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000617static const struct finst db_Escc[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000618/*0*/ { "fadd", DBLR, op2(ST,STI), 0 },
619/*1*/ { "fmul", DBLR, op2(ST,STI), 0 },
620/*2*/ { "fcom", DBLR, op2(ST,STI), 0 },
621/*3*/ { "fcomp", DBLR, op2(ST,STI), 0 },
622/*4*/ { "fsub", DBLR, op2(ST,STI), "fsubr" },
623/*5*/ { "fsubr", DBLR, op2(ST,STI), "fsub" },
624/*6*/ { "fdiv", DBLR, op2(ST,STI), "fdivr" },
625/*7*/ { "fdivr", DBLR, op2(ST,STI), "fdiv" },
626};
627
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000628static const struct finst db_Escd[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000629/*0*/ { "fld", DBLR, op1(STI), "ffree" },
630/*1*/ { "", NONE, 0, 0 },
631/*2*/ { "fst", DBLR, op1(STI), 0 },
632/*3*/ { "fstp", DBLR, op1(STI), 0 },
633/*4*/ { "frstor", NONE, op1(STI), "fucom" },
634/*5*/ { "", NONE, op1(STI), "fucomp" },
635/*6*/ { "fnsave", NONE, 0, 0 },
636/*7*/ { "fnstsw", NONE, 0, 0 },
637};
638
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000639static const struct finst db_Esce[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000640/*0*/ { "fiadd", LONG, op2(ST,STI), "faddp" },
641/*1*/ { "fimul", LONG, op2(ST,STI), "fmulp" },
642/*2*/ { "ficom", LONG, 0, 0 },
643/*3*/ { "ficomp", LONG, op1(X), (char *)db_Esce3 },
644/*4*/ { "fisub", LONG, op2(ST,STI), "fsubrp" },
645/*5*/ { "fisubr", LONG, op2(ST,STI), "fsubp" },
646/*6*/ { "fidiv", LONG, op2(ST,STI), "fdivrp" },
647/*7*/ { "fidivr", LONG, op2(ST,STI), "fdivp" },
648};
649
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000650static const struct finst db_Escf[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000651/*0*/ { "fild", LONG, 0, 0 },
652/*1*/ { "", LONG, 0, 0 },
653/*2*/ { "fist", LONG, 0, 0 },
654/*3*/ { "fistp", LONG, 0, 0 },
655/*4*/ { "fbld", NONE, op1(XA), (char *)db_Escf4 },
656/*5*/ { "fld", QUAD, 0, 0 },
657/*6*/ { "fbstp", NONE, 0, 0 },
658/*7*/ { "fstp", QUAD, 0, 0 },
659};
660
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000661static const struct finst * const db_Esc_inst[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000662 db_Esc8, db_Esc9, db_Esca, db_Escb,
663 db_Escc, db_Escd, db_Esce, db_Escf
664};
665
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000666static const char * const db_Grp1[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000667 "add",
668 "or",
669 "adc",
670 "sbb",
671 "and",
672 "sub",
673 "xor",
674 "cmp"
675};
676
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000677static const char * const db_Grp2[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000678 "rol",
679 "ror",
680 "rcl",
681 "rcr",
682 "shl",
683 "shr",
684 "shl",
685 "sar"
686};
687
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000688static const struct inst db_Grp3[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000689 { "test", TRUE, NONE, op2(I,E), 0 },
690 { "test", TRUE, NONE, op2(I,E), 0 },
691 { "not", TRUE, NONE, op1(E), 0 },
692 { "neg", TRUE, NONE, op1(E), 0 },
693 { "mul", TRUE, NONE, op2(E,A), 0 },
694 { "imul", TRUE, NONE, op2(E,A), 0 },
695 { "div", TRUE, NONE, op2(E,A), 0 },
696 { "idiv", TRUE, NONE, op2(E,A), 0 },
697};
698
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000699static const struct inst db_Grp4[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000700 { "inc", TRUE, BYTE, op1(E), 0 },
701 { "dec", TRUE, BYTE, op1(E), 0 },
702 { "", TRUE, NONE, 0, 0 },
703 { "", TRUE, NONE, 0, 0 },
704 { "", TRUE, NONE, 0, 0 },
705 { "", TRUE, NONE, 0, 0 },
706 { "", TRUE, NONE, 0, 0 },
707 { "", TRUE, NONE, 0, 0 }
708};
709
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000710static const struct inst db_Grp5[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000711 { "inc", TRUE, LONG, op1(E), 0 },
712 { "dec", TRUE, LONG, op1(E), 0 },
713 { "call", TRUE, NONE, op1(Eind),0 },
714 { "lcall", TRUE, NONE, op1(Eind),0 },
715 { "jmp", TRUE, NONE, op1(Eind),0 },
716 { "ljmp", TRUE, NONE, op1(Eind),0 },
717 { "push", TRUE, LONG, op1(E), 0 },
718 { "", TRUE, NONE, 0, 0 }
719};
720
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000721static const struct inst db_inst_table[256] = {
Alexandre Julliard18506551995-01-24 16:21:01 +0000722/*00*/ { "add", TRUE, BYTE, op2(R, E), 0 },
723/*01*/ { "add", TRUE, LONG, op2(R, E), 0 },
724/*02*/ { "add", TRUE, BYTE, op2(E, R), 0 },
725/*03*/ { "add", TRUE, LONG, op2(E, R), 0 },
726/*04*/ { "add", FALSE, BYTE, op2(Is, A), 0 },
727/*05*/ { "add", FALSE, LONG, op2(Is, A), 0 },
728/*06*/ { "push", FALSE, NONE, op1(Si), 0 },
729/*07*/ { "pop", FALSE, NONE, op1(Si), 0 },
730
731/*08*/ { "or", TRUE, BYTE, op2(R, E), 0 },
732/*09*/ { "or", TRUE, LONG, op2(R, E), 0 },
733/*0a*/ { "or", TRUE, BYTE, op2(E, R), 0 },
734/*0b*/ { "or", TRUE, LONG, op2(E, R), 0 },
735/*0c*/ { "or", FALSE, BYTE, op2(I, A), 0 },
736/*0d*/ { "or", FALSE, LONG, op2(I, A), 0 },
737/*0e*/ { "push", FALSE, NONE, op1(Si), 0 },
738/*0f*/ { "", FALSE, NONE, 0, 0 },
739
740/*10*/ { "adc", TRUE, BYTE, op2(R, E), 0 },
741/*11*/ { "adc", TRUE, LONG, op2(R, E), 0 },
742/*12*/ { "adc", TRUE, BYTE, op2(E, R), 0 },
743/*13*/ { "adc", TRUE, LONG, op2(E, R), 0 },
744/*14*/ { "adc", FALSE, BYTE, op2(Is, A), 0 },
745/*15*/ { "adc", FALSE, LONG, op2(Is, A), 0 },
746/*16*/ { "push", FALSE, NONE, op1(Si), 0 },
747/*17*/ { "pop", FALSE, NONE, op1(Si), 0 },
748
749/*18*/ { "sbb", TRUE, BYTE, op2(R, E), 0 },
750/*19*/ { "sbb", TRUE, LONG, op2(R, E), 0 },
751/*1a*/ { "sbb", TRUE, BYTE, op2(E, R), 0 },
752/*1b*/ { "sbb", TRUE, LONG, op2(E, R), 0 },
753/*1c*/ { "sbb", FALSE, BYTE, op2(Is, A), 0 },
754/*1d*/ { "sbb", FALSE, LONG, op2(Is, A), 0 },
755/*1e*/ { "push", FALSE, NONE, op1(Si), 0 },
756/*1f*/ { "pop", FALSE, NONE, op1(Si), 0 },
757
758/*20*/ { "and", TRUE, BYTE, op2(R, E), 0 },
759/*21*/ { "and", TRUE, LONG, op2(R, E), 0 },
760/*22*/ { "and", TRUE, BYTE, op2(E, R), 0 },
761/*23*/ { "and", TRUE, LONG, op2(E, R), 0 },
762/*24*/ { "and", FALSE, BYTE, op2(I, A), 0 },
763/*25*/ { "and", FALSE, LONG, op2(I, A), 0 },
764/*26*/ { "", FALSE, NONE, 0, 0 },
765/*27*/ { "aaa", FALSE, NONE, 0, 0 },
766
767/*28*/ { "sub", TRUE, BYTE, op2(R, E), 0 },
768/*29*/ { "sub", TRUE, LONG, op2(R, E), 0 },
769/*2a*/ { "sub", TRUE, BYTE, op2(E, R), 0 },
770/*2b*/ { "sub", TRUE, LONG, op2(E, R), 0 },
771/*2c*/ { "sub", FALSE, BYTE, op2(Is, A), 0 },
772/*2d*/ { "sub", FALSE, LONG, op2(Is, A), 0 },
773/*2e*/ { "", FALSE, NONE, 0, 0 },
774/*2f*/ { "das", FALSE, NONE, 0, 0 },
775
776/*30*/ { "xor", TRUE, BYTE, op2(R, E), 0 },
777/*31*/ { "xor", TRUE, LONG, op2(R, E), 0 },
778/*32*/ { "xor", TRUE, BYTE, op2(E, R), 0 },
779/*33*/ { "xor", TRUE, LONG, op2(E, R), 0 },
780/*34*/ { "xor", FALSE, BYTE, op2(I, A), 0 },
781/*35*/ { "xor", FALSE, LONG, op2(I, A), 0 },
782/*36*/ { "", FALSE, NONE, 0, 0 },
783/*37*/ { "daa", FALSE, NONE, 0, 0 },
784
785/*38*/ { "cmp", TRUE, BYTE, op2(R, E), 0 },
786/*39*/ { "cmp", TRUE, LONG, op2(R, E), 0 },
787/*3a*/ { "cmp", TRUE, BYTE, op2(E, R), 0 },
788/*3b*/ { "cmp", TRUE, LONG, op2(E, R), 0 },
789/*3c*/ { "cmp", FALSE, BYTE, op2(Is, A), 0 },
790/*3d*/ { "cmp", FALSE, LONG, op2(Is, A), 0 },
791/*3e*/ { "", FALSE, NONE, 0, 0 },
792/*3f*/ { "aas", FALSE, NONE, 0, 0 },
793
794/*40*/ { "inc", FALSE, LONG, op1(Ri), 0 },
795/*41*/ { "inc", FALSE, LONG, op1(Ri), 0 },
796/*42*/ { "inc", FALSE, LONG, op1(Ri), 0 },
797/*43*/ { "inc", FALSE, LONG, op1(Ri), 0 },
798/*44*/ { "inc", FALSE, LONG, op1(Ri), 0 },
799/*45*/ { "inc", FALSE, LONG, op1(Ri), 0 },
800/*46*/ { "inc", FALSE, LONG, op1(Ri), 0 },
801/*47*/ { "inc", FALSE, LONG, op1(Ri), 0 },
802
803/*48*/ { "dec", FALSE, LONG, op1(Ri), 0 },
804/*49*/ { "dec", FALSE, LONG, op1(Ri), 0 },
805/*4a*/ { "dec", FALSE, LONG, op1(Ri), 0 },
806/*4b*/ { "dec", FALSE, LONG, op1(Ri), 0 },
807/*4c*/ { "dec", FALSE, LONG, op1(Ri), 0 },
808/*4d*/ { "dec", FALSE, LONG, op1(Ri), 0 },
809/*4e*/ { "dec", FALSE, LONG, op1(Ri), 0 },
810/*4f*/ { "dec", FALSE, LONG, op1(Ri), 0 },
811
812/*50*/ { "push", FALSE, LONG, op1(Ri), 0 },
813/*51*/ { "push", FALSE, LONG, op1(Ri), 0 },
814/*52*/ { "push", FALSE, LONG, op1(Ri), 0 },
815/*53*/ { "push", FALSE, LONG, op1(Ri), 0 },
816/*54*/ { "push", FALSE, LONG, op1(Ri), 0 },
817/*55*/ { "push", FALSE, LONG, op1(Ri), 0 },
818/*56*/ { "push", FALSE, LONG, op1(Ri), 0 },
819/*57*/ { "push", FALSE, LONG, op1(Ri), 0 },
820
821/*58*/ { "pop", FALSE, LONG, op1(Ri), 0 },
822/*59*/ { "pop", FALSE, LONG, op1(Ri), 0 },
823/*5a*/ { "pop", FALSE, LONG, op1(Ri), 0 },
824/*5b*/ { "pop", FALSE, LONG, op1(Ri), 0 },
825/*5c*/ { "pop", FALSE, LONG, op1(Ri), 0 },
826/*5d*/ { "pop", FALSE, LONG, op1(Ri), 0 },
827/*5e*/ { "pop", FALSE, LONG, op1(Ri), 0 },
828/*5f*/ { "pop", FALSE, LONG, op1(Ri), 0 },
829
830/*60*/ { "pusha", FALSE, LONG, 0, 0 },
831/*61*/ { "popa", FALSE, LONG, 0, 0 },
832/*62*/ { "bound", TRUE, LONG, op2(E, R), 0 },
833/*63*/ { "arpl", TRUE, NONE, op2(Ew,Rw), 0 },
834
835/*64*/ { "", FALSE, NONE, 0, 0 },
836/*65*/ { "", FALSE, NONE, 0, 0 },
837/*66*/ { "", FALSE, NONE, 0, 0 },
838/*67*/ { "", FALSE, NONE, 0, 0 },
839
840/*68*/ { "push", FALSE, LONG, op1(I), 0 },
841/*69*/ { "imul", TRUE, LONG, op3(I,E,R), 0 },
842/*6a*/ { "push", FALSE, LONG, op1(Ib), 0 },
843/*6b*/ { "imul", TRUE, LONG, op3(Ibs,E,R),0 },
844/*6c*/ { "ins", FALSE, BYTE, op2(DX, DI), 0 },
845/*6d*/ { "ins", FALSE, LONG, op2(DX, DI), 0 },
846/*6e*/ { "outs", FALSE, BYTE, op2(SI, DX), 0 },
847/*6f*/ { "outs", FALSE, LONG, op2(SI, DX), 0 },
848
849/*70*/ { "jo", FALSE, NONE, op1(Db), 0 },
850/*71*/ { "jno", FALSE, NONE, op1(Db), 0 },
851/*72*/ { "jb", FALSE, NONE, op1(Db), 0 },
852/*73*/ { "jnb", FALSE, NONE, op1(Db), 0 },
853/*74*/ { "jz", FALSE, NONE, op1(Db), 0 },
854/*75*/ { "jnz", FALSE, NONE, op1(Db), 0 },
855/*76*/ { "jbe", FALSE, NONE, op1(Db), 0 },
856/*77*/ { "jnbe", FALSE, NONE, op1(Db), 0 },
857
858/*78*/ { "js", FALSE, NONE, op1(Db), 0 },
859/*79*/ { "jns", FALSE, NONE, op1(Db), 0 },
860/*7a*/ { "jp", FALSE, NONE, op1(Db), 0 },
861/*7b*/ { "jnp", FALSE, NONE, op1(Db), 0 },
862/*7c*/ { "jl", FALSE, NONE, op1(Db), 0 },
863/*7d*/ { "jnl", FALSE, NONE, op1(Db), 0 },
864/*7e*/ { "jle", FALSE, NONE, op1(Db), 0 },
865/*7f*/ { "jnle", FALSE, NONE, op1(Db), 0 },
866
867/*80*/ { "", TRUE, BYTE, op2(I, E), (char *)db_Grp1 },
868/*81*/ { "", TRUE, LONG, op2(I, E), (char *)db_Grp1 },
869/*82*/ { "", TRUE, BYTE, op2(Is,E), (char *)db_Grp1 },
870/*83*/ { "", TRUE, LONG, op2(Ibs,E), (char *)db_Grp1 },
871/*84*/ { "test", TRUE, BYTE, op2(R, E), 0 },
872/*85*/ { "test", TRUE, LONG, op2(R, E), 0 },
873/*86*/ { "xchg", TRUE, BYTE, op2(R, E), 0 },
874/*87*/ { "xchg", TRUE, LONG, op2(R, E), 0 },
875
876/*88*/ { "mov", TRUE, BYTE, op2(R, E), 0 },
877/*89*/ { "mov", TRUE, LONG, op2(R, E), 0 },
878/*8a*/ { "mov", TRUE, BYTE, op2(E, R), 0 },
879/*8b*/ { "mov", TRUE, LONG, op2(E, R), 0 },
880/*8c*/ { "mov", TRUE, NONE, op2(S, Ew), 0 },
881/*8d*/ { "lea", TRUE, LONG, op2(E, R), 0 },
882/*8e*/ { "mov", TRUE, NONE, op2(Ew, S), 0 },
883/*8f*/ { "pop", TRUE, LONG, op1(E), 0 },
884
885/*90*/ { "nop", FALSE, NONE, 0, 0 },
886/*91*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
887/*92*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
888/*93*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
889/*94*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
890/*95*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
891/*96*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
892/*97*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
893
894/*98*/ { "cbw", FALSE, SDEP, 0, "cwde" }, /* cbw/cwde */
895/*99*/ { "cwd", FALSE, SDEP, 0, "cdq" }, /* cwd/cdq */
896/*9a*/ { "lcall", FALSE, NONE, op1(OS), 0 },
897/*9b*/ { "wait", FALSE, NONE, 0, 0 },
898/*9c*/ { "pushf", FALSE, LONG, 0, 0 },
899/*9d*/ { "popf", FALSE, LONG, 0, 0 },
900/*9e*/ { "sahf", FALSE, NONE, 0, 0 },
901/*9f*/ { "lahf", FALSE, NONE, 0, 0 },
902
903/*a0*/ { "mov", FALSE, BYTE, op2(O, A), 0 },
904/*a1*/ { "mov", FALSE, LONG, op2(O, A), 0 },
905/*a2*/ { "mov", FALSE, BYTE, op2(A, O), 0 },
906/*a3*/ { "mov", FALSE, LONG, op2(A, O), 0 },
907/*a4*/ { "movs", FALSE, BYTE, op2(SI,DI), 0 },
908/*a5*/ { "movs", FALSE, LONG, op2(SI,DI), 0 },
909/*a6*/ { "cmps", FALSE, BYTE, op2(SI,DI), 0 },
910/*a7*/ { "cmps", FALSE, LONG, op2(SI,DI), 0 },
911
912/*a8*/ { "test", FALSE, BYTE, op2(I, A), 0 },
913/*a9*/ { "test", FALSE, LONG, op2(I, A), 0 },
914/*aa*/ { "stos", FALSE, BYTE, op1(DI), 0 },
915/*ab*/ { "stos", FALSE, LONG, op1(DI), 0 },
916/*ac*/ { "lods", FALSE, BYTE, op1(SI), 0 },
917/*ad*/ { "lods", FALSE, LONG, op1(SI), 0 },
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000918/*ae*/ { "scas", FALSE, BYTE, op1(DI), 0 },
919/*af*/ { "scas", FALSE, LONG, op1(DI), 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000920
921/*b0*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
922/*b1*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
923/*b2*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
924/*b3*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
925/*b4*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
926/*b5*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
927/*b6*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
928/*b7*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
929
930/*b8*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
931/*b9*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
932/*ba*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
933/*bb*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
934/*bc*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
935/*bd*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
936/*be*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
937/*bf*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
938
939/*c0*/ { "", TRUE, BYTE, op2(Ib, E), (char *)db_Grp2 },
940/*c1*/ { "", TRUE, LONG, op2(Ib, E), (char *)db_Grp2 },
941/*c2*/ { "ret", FALSE, NONE, op1(Iw), 0 },
942/*c3*/ { "ret", FALSE, NONE, 0, 0 },
943/*c4*/ { "les", TRUE, LONG, op2(E, R), 0 },
944/*c5*/ { "lds", TRUE, LONG, op2(E, R), 0 },
945/*c6*/ { "mov", TRUE, BYTE, op2(I, E), 0 },
946/*c7*/ { "mov", TRUE, LONG, op2(I, E), 0 },
947
Rein Klazes68c78e71999-10-31 21:25:11 +0000948/*c8*/ { "enter", FALSE, NONE, op2(Iw, Ib), 0 },
Alexandre Julliard18506551995-01-24 16:21:01 +0000949/*c9*/ { "leave", FALSE, NONE, 0, 0 },
950/*ca*/ { "lret", FALSE, NONE, op1(Iw), 0 },
951/*cb*/ { "lret", FALSE, NONE, 0, 0 },
952/*cc*/ { "int", FALSE, NONE, op1(o3), 0 },
953/*cd*/ { "int", FALSE, NONE, op1(Ib), 0 },
954/*ce*/ { "into", FALSE, NONE, 0, 0 },
955/*cf*/ { "iret", FALSE, NONE, 0, 0 },
956
957/*d0*/ { "", TRUE, BYTE, op2(o1, E), (char *)db_Grp2 },
958/*d1*/ { "", TRUE, LONG, op2(o1, E), (char *)db_Grp2 },
959/*d2*/ { "", TRUE, BYTE, op2(CL, E), (char *)db_Grp2 },
960/*d3*/ { "", TRUE, LONG, op2(CL, E), (char *)db_Grp2 },
961/*d4*/ { "aam", TRUE, NONE, 0, 0 },
962/*d5*/ { "aad", TRUE, NONE, 0, 0 },
963/*d6*/ { "", FALSE, NONE, 0, 0 },
964/*d7*/ { "xlat", FALSE, BYTE, op1(BX), 0 },
965
966/*d8*/ { "", TRUE, NONE, 0, (char *)db_Esc8 },
967/*d9*/ { "", TRUE, NONE, 0, (char *)db_Esc9 },
968/*da*/ { "", TRUE, NONE, 0, (char *)db_Esca },
969/*db*/ { "", TRUE, NONE, 0, (char *)db_Escb },
970/*dc*/ { "", TRUE, NONE, 0, (char *)db_Escc },
971/*dd*/ { "", TRUE, NONE, 0, (char *)db_Escd },
972/*de*/ { "", TRUE, NONE, 0, (char *)db_Esce },
973/*df*/ { "", TRUE, NONE, 0, (char *)db_Escf },
974
975/*e0*/ { "loopne",FALSE, NONE, op1(Db), 0 },
976/*e1*/ { "loope", FALSE, NONE, op1(Db), 0 },
977/*e2*/ { "loop", FALSE, NONE, op1(Db), 0 },
978/*e3*/ { "jcxz", FALSE, SDEP, op1(Db), "jecxz" },
979/*e4*/ { "in", FALSE, BYTE, op2(Ib, A), 0 },
980/*e5*/ { "in", FALSE, LONG, op2(Ib, A) , 0 },
981/*e6*/ { "out", FALSE, BYTE, op2(A, Ib), 0 },
982/*e7*/ { "out", FALSE, LONG, op2(A, Ib) , 0 },
983
984/*e8*/ { "call", FALSE, NONE, op1(Dl), 0 },
985/*e9*/ { "jmp", FALSE, NONE, op1(Dl), 0 },
986/*ea*/ { "ljmp", FALSE, NONE, op1(OS), 0 },
987/*eb*/ { "jmp", FALSE, NONE, op1(Db), 0 },
988/*ec*/ { "in", FALSE, BYTE, op2(DX, A), 0 },
989/*ed*/ { "in", FALSE, LONG, op2(DX, A) , 0 },
990/*ee*/ { "out", FALSE, BYTE, op2(A, DX), 0 },
991/*ef*/ { "out", FALSE, LONG, op2(A, DX) , 0 },
992
993/*f0*/ { "", FALSE, NONE, 0, 0 },
994/*f1*/ { "", FALSE, NONE, 0, 0 },
995/*f2*/ { "", FALSE, NONE, 0, 0 },
996/*f3*/ { "", FALSE, NONE, 0, 0 },
997/*f4*/ { "hlt", FALSE, NONE, 0, 0 },
998/*f5*/ { "cmc", FALSE, NONE, 0, 0 },
999/*f6*/ { "", TRUE, BYTE, 0, (char *)db_Grp3 },
1000/*f7*/ { "", TRUE, LONG, 0, (char *)db_Grp3 },
1001
1002/*f8*/ { "clc", FALSE, NONE, 0, 0 },
1003/*f9*/ { "stc", FALSE, NONE, 0, 0 },
1004/*fa*/ { "cli", FALSE, NONE, 0, 0 },
1005/*fb*/ { "sti", FALSE, NONE, 0, 0 },
1006/*fc*/ { "cld", FALSE, NONE, 0, 0 },
1007/*fd*/ { "std", FALSE, NONE, 0, 0 },
1008/*fe*/ { "", TRUE, NONE, 0, (char *)db_Grp4 },
1009/*ff*/ { "", TRUE, NONE, 0, (char *)db_Grp5 },
1010};
1011
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001012static const struct inst db_bad_inst =
Alexandre Julliard18506551995-01-24 16:21:01 +00001013 { "???", FALSE, NONE, 0, 0 }
1014;
1015
1016#define f_mod(byte) ((byte)>>6)
1017#define f_reg(byte) (((byte)>>3)&0x7)
1018#define f_rm(byte) ((byte)&0x7)
1019
1020#define sib_ss(byte) ((byte)>>6)
1021#define sib_index(byte) (((byte)>>3)&0x7)
1022#define sib_base(byte) ((byte)&0x7)
1023
1024struct i_addr {
1025 int is_reg; /* if reg, reg number is in 'disp' */
1026 int disp;
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001027 const char * base;
1028 const char * index;
Alexandre Julliard18506551995-01-24 16:21:01 +00001029 int ss;
1030};
1031
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001032static const char * const db_index_reg_16[8] = {
Alexandre Julliard18506551995-01-24 16:21:01 +00001033 "%bx,%si",
1034 "%bx,%di",
1035 "%bp,%si",
1036 "%bp,%di",
1037 "%si",
1038 "%di",
1039 "%bp",
1040 "%bx"
1041};
1042
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001043static const char * const db_reg[3][8] = {
Alexandre Julliard18506551995-01-24 16:21:01 +00001044 { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" },
1045 { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" },
1046 { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" }
1047};
1048
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001049static const char * const db_seg_reg[8] = {
Alexandre Julliard18506551995-01-24 16:21:01 +00001050 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
1051};
1052
1053/*
1054 * lengths for size attributes
1055 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001056static const int db_lengths[] = {
Alexandre Julliard18506551995-01-24 16:21:01 +00001057 1, /* BYTE */
1058 2, /* WORD */
1059 4, /* LONG */
1060 8, /* QUAD */
1061 4, /* SNGL */
1062 8, /* DBLR */
1063 10, /* EXTR */
1064};
1065
Alexandre Julliard808cb041995-08-17 17:11:36 +00001066static unsigned int db_get_task_value( const DBG_ADDR *addr,
1067 int size, int is_signed )
Alexandre Julliard18506551995-01-24 16:21:01 +00001068{
Eric Pouech527eea92000-03-08 16:44:54 +00001069 unsigned int result = 0;
1070 char buffer[4];
Alexandre Julliard808cb041995-08-17 17:11:36 +00001071
Eric Pouech527eea92000-03-08 16:44:54 +00001072 if (size != 1 && size != 2 && size != 4) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001073 DEBUG_Printf(DBG_CHN_MESG, "Illegal size specified\n");
Eric Pouech527eea92000-03-08 16:44:54 +00001074 } else {
1075 DEBUG_READ_MEM((void*)DEBUG_ToLinear( addr ), buffer, size);
1076
1077 switch(size)
1078 {
1079 case 4:
1080 if (is_signed) result = (unsigned int) *(int *)buffer;
1081 else result = *(unsigned int *)buffer;
1082 break;
1083 case 2:
1084 if (is_signed) result = (unsigned int) *(short int *)buffer;
1085 else result = *(unsigned short int *)buffer;
1086 break;
1087 case 1:
1088 if (is_signed) result = (unsigned int) *(char *)buffer;
1089 else result = *(unsigned char *)buffer;
1090 break;
1091 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001092 }
Alexandre Julliard808cb041995-08-17 17:11:36 +00001093 return result;
Alexandre Julliard18506551995-01-24 16:21:01 +00001094}
1095
Alexandre Julliard808cb041995-08-17 17:11:36 +00001096#define get_value_inc(result, addr, size, is_signed) \
1097 result = db_get_task_value((addr), (size), (is_signed)); \
1098 if (!db_disasm_16) (addr)->off += (size); \
1099 else (addr)->off = ((addr)->off + (size)) & 0xffff;
Alexandre Julliard18506551995-01-24 16:21:01 +00001100
1101/*
1102 * Read address at location and return updated location.
1103 */
Alexandre Julliard808cb041995-08-17 17:11:36 +00001104void db_read_address( DBG_ADDR *addr, int short_addr, int regmodrm,
1105 struct i_addr *addrp )
Alexandre Julliard18506551995-01-24 16:21:01 +00001106{
Alexandre Julliard808cb041995-08-17 17:11:36 +00001107 int mod, rm, sib, index, disp;
Alexandre Julliard18506551995-01-24 16:21:01 +00001108
1109 mod = f_mod(regmodrm);
1110 rm = f_rm(regmodrm);
1111
1112 if (mod == 3) {
1113 addrp->is_reg = TRUE;
1114 addrp->disp = rm;
Alexandre Julliard808cb041995-08-17 17:11:36 +00001115 return;
Alexandre Julliard18506551995-01-24 16:21:01 +00001116 }
1117 addrp->is_reg = FALSE;
1118 addrp->index = 0;
1119
1120 if (short_addr) {
1121 addrp->index = 0;
1122 addrp->ss = 0;
1123 switch (mod) {
1124 case 0:
1125 if (rm == 6) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001126 get_value_inc(disp, addr, 2, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001127 addrp->disp = disp;
1128 addrp->base = 0;
1129 }
1130 else {
1131 addrp->disp = 0;
1132 addrp->base = db_index_reg_16[rm];
1133 }
1134 break;
1135 case 1:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001136 get_value_inc(disp, addr, 1, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001137 addrp->disp = disp;
1138 addrp->base = db_index_reg_16[rm];
1139 break;
1140 case 2:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001141 get_value_inc(disp, addr, 2, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001142 addrp->disp = disp;
1143 addrp->base = db_index_reg_16[rm];
1144 break;
1145 }
1146 }
1147 else {
1148 if (mod != 3 && rm == 4) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001149 get_value_inc(sib, addr, 1, FALSE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001150 rm = sib_base(sib);
1151 index = sib_index(sib);
1152 if (index != 4)
1153 addrp->index = db_reg[LONG][index];
1154 addrp->ss = sib_ss(sib);
1155 }
1156
1157 switch (mod) {
1158 case 0:
1159 if (rm == 5) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001160 get_value_inc(addrp->disp, addr, 4, FALSE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001161 addrp->base = 0;
1162 }
1163 else {
1164 addrp->disp = 0;
1165 addrp->base = db_reg[LONG][rm];
1166 }
1167 break;
1168
1169 case 1:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001170 get_value_inc(disp, addr, 1, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001171 addrp->disp = disp;
1172 addrp->base = db_reg[LONG][rm];
1173 break;
1174
1175 case 2:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001176 get_value_inc(disp, addr, 4, FALSE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001177 addrp->disp = disp;
1178 addrp->base = db_reg[LONG][rm];
1179 break;
1180 }
1181 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001182}
1183
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001184static void db_task_printsym(unsigned int addr, int size)
1185{
Patrik Stridvall0f8bc5b1999-04-22 16:27:50 +00001186 DBG_ADDR address;
1187
Patrik Stridvall0f8bc5b1999-04-22 16:27:50 +00001188 address.seg = 0;
1189 address.off = addr;
1190
Alexandre Julliard954a4132000-09-24 03:15:50 +00001191 DEBUG_PrintAddress( &address, db_disasm_16 ? MODE_16 : MODE_32, TRUE );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001192}
1193
Patrik Stridvalle22a4e51999-06-12 06:38:22 +00001194void db_print_address(char *seg, int size, struct i_addr *addrp, int byref)
Alexandre Julliard18506551995-01-24 16:21:01 +00001195{
1196 if (addrp->is_reg) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001197 DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][addrp->disp]);
Alexandre Julliard18506551995-01-24 16:21:01 +00001198 return;
1199 }
1200
1201 if (seg) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001202 DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
Alexandre Julliard18506551995-01-24 16:21:01 +00001203 }
1204
1205 if (addrp->base != 0 || addrp->index != 0) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001206 DEBUG_Printf(DBG_CHN_MESG,"0x%x(", addrp->disp);
Alexandre Julliard18506551995-01-24 16:21:01 +00001207 if (addrp->base)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001208 DEBUG_Printf(DBG_CHN_MESG,"%s", addrp->base);
Alexandre Julliard18506551995-01-24 16:21:01 +00001209 if (addrp->index)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001210 DEBUG_Printf(DBG_CHN_MESG,",%s,%d", addrp->index, 1<<addrp->ss);
1211 DEBUG_Printf(DBG_CHN_MESG,")");
Juergen Schmied36358801999-02-14 13:30:18 +00001212 }
1213 else {
1214
Eric Pouech15ca6c41999-04-03 11:10:54 +00001215 /* try to get destination of indirect call
1216 does not work for segmented adresses */
Juergen Schmied36358801999-02-14 13:30:18 +00001217 if (!seg && byref) {
Eric Pouech527eea92000-03-08 16:44:54 +00001218 void* a1;
1219 void* a2;
Eric Pouech15ca6c41999-04-03 11:10:54 +00001220
Eric Poueche5efa0c2000-04-13 19:31:58 +00001221 DEBUG_Printf(DBG_CHN_MESG,"0x%x -> ", addrp->disp);
Eric Pouech527eea92000-03-08 16:44:54 +00001222 if (!DEBUG_READ_MEM((void*)addrp->disp, &a1, sizeof(a1))) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001223 DEBUG_Printf(DBG_CHN_MESG, "(invalid source)");
Eric Pouech527eea92000-03-08 16:44:54 +00001224 } else if (!DEBUG_READ_MEM(a1, &a2, sizeof(a2))) {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001225 DEBUG_Printf(DBG_CHN_MESG, "(invalid destination)");
Eric Pouech527eea92000-03-08 16:44:54 +00001226 } else {
1227 db_task_printsym((unsigned long)a1, 0);
Eric Pouech15ca6c41999-04-03 11:10:54 +00001228 }
Juergen Schmied36358801999-02-14 13:30:18 +00001229 }
1230 else
1231 db_task_printsym(addrp->disp, size);
1232 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001233}
1234
1235/*
1236 * Disassemble floating-point ("escape") instruction
1237 * and return updated location.
1238 */
Alexandre Julliard808cb041995-08-17 17:11:36 +00001239void db_disasm_esc( DBG_ADDR *addr, int inst, int short_addr,
1240 int size, char *seg )
Alexandre Julliard18506551995-01-24 16:21:01 +00001241{
1242 int regmodrm;
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001243 const struct finst *fp;
Alexandre Julliard18506551995-01-24 16:21:01 +00001244 int mod;
1245 struct i_addr address;
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001246 const char * name;
Alexandre Julliard18506551995-01-24 16:21:01 +00001247
Alexandre Julliard808cb041995-08-17 17:11:36 +00001248 get_value_inc(regmodrm, addr, 1, FALSE);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001249 if( !db_display )
1250 {
1251 return;
1252 }
1253
Alexandre Julliard18506551995-01-24 16:21:01 +00001254 fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)];
1255 mod = f_mod(regmodrm);
1256 if (mod != 3) {
1257 /*
1258 * Normal address modes.
1259 */
Alexandre Julliard808cb041995-08-17 17:11:36 +00001260 db_read_address( addr, short_addr, regmodrm, &address);
Eric Poueche5efa0c2000-04-13 19:31:58 +00001261 DEBUG_Printf(DBG_CHN_MESG,fp->f_name);
Alexandre Julliard18506551995-01-24 16:21:01 +00001262 switch(fp->f_size) {
1263 case SNGL:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001264 DEBUG_Printf(DBG_CHN_MESG,"s");
Alexandre Julliard18506551995-01-24 16:21:01 +00001265 break;
1266 case DBLR:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001267 DEBUG_Printf(DBG_CHN_MESG,"l");
Alexandre Julliard18506551995-01-24 16:21:01 +00001268 break;
1269 case EXTR:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001270 DEBUG_Printf(DBG_CHN_MESG,"t");
Alexandre Julliard18506551995-01-24 16:21:01 +00001271 break;
1272 case WORD:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001273 DEBUG_Printf(DBG_CHN_MESG,"s");
Alexandre Julliard18506551995-01-24 16:21:01 +00001274 break;
1275 case LONG:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001276 DEBUG_Printf(DBG_CHN_MESG,"l");
Alexandre Julliard18506551995-01-24 16:21:01 +00001277 break;
1278 case QUAD:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001279 DEBUG_Printf(DBG_CHN_MESG,"q");
Alexandre Julliard18506551995-01-24 16:21:01 +00001280 break;
1281 default:
1282 break;
1283 }
Eric Poueche5efa0c2000-04-13 19:31:58 +00001284 DEBUG_Printf(DBG_CHN_MESG,"\t");
Juergen Schmied36358801999-02-14 13:30:18 +00001285 db_print_address(seg, BYTE, &address, 0);
Alexandre Julliard18506551995-01-24 16:21:01 +00001286 }
1287 else {
1288 /*
1289 * 'reg-reg' - special formats
1290 */
1291 switch (fp->f_rrmode) {
1292 case op2(ST,STI):
1293 name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
Eric Poueche5efa0c2000-04-13 19:31:58 +00001294 DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st,%%st(%d)",name,f_rm(regmodrm));
Alexandre Julliard18506551995-01-24 16:21:01 +00001295 break;
1296 case op2(STI,ST):
1297 name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
Eric Poueche5efa0c2000-04-13 19:31:58 +00001298 DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st(%d),%%st",name, f_rm(regmodrm));
Alexandre Julliard18506551995-01-24 16:21:01 +00001299 break;
1300 case op1(STI):
1301 name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
Eric Poueche5efa0c2000-04-13 19:31:58 +00001302 DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st(%d)",name, f_rm(regmodrm));
Alexandre Julliard18506551995-01-24 16:21:01 +00001303 break;
1304 case op1(X):
Eric Poueche5efa0c2000-04-13 19:31:58 +00001305 DEBUG_Printf(DBG_CHN_MESG,"%s", ((char **)fp->f_rrname)[f_rm(regmodrm)]);
Alexandre Julliard18506551995-01-24 16:21:01 +00001306 break;
1307 case op1(XA):
Eric Poueche5efa0c2000-04-13 19:31:58 +00001308 DEBUG_Printf(DBG_CHN_MESG,"%s\t%%ax",
Alexandre Julliard18506551995-01-24 16:21:01 +00001309 ((char **)fp->f_rrname)[f_rm(regmodrm)]);
1310 break;
1311 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00001312 DEBUG_Printf(DBG_CHN_MESG,"<bad instruction>");
Alexandre Julliard18506551995-01-24 16:21:01 +00001313 break;
1314 }
1315 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001316}
1317
Alexandre Julliard808cb041995-08-17 17:11:36 +00001318
1319/***********************************************************************
1320 * DEBUG_Disasm
1321 *
1322 * Disassemble instruction at 'addr'. addr is changed to point to the
1323 * start of the next instruction.
Alexandre Julliard18506551995-01-24 16:21:01 +00001324 */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001325void DEBUG_Disasm( DBG_ADDR *addr, int display )
Alexandre Julliard18506551995-01-24 16:21:01 +00001326{
1327 int inst;
1328 int size;
1329 int short_addr;
1330 char * seg;
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001331 const struct inst *ip;
1332 const char *i_name;
Alexandre Julliard18506551995-01-24 16:21:01 +00001333 int i_size;
1334 int i_mode;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001335 int regmodrm = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001336 BOOL first;
Alexandre Julliard18506551995-01-24 16:21:01 +00001337 int displ;
1338 int prefix;
1339 int imm;
Alexandre Julliard18506551995-01-24 16:21:01 +00001340 int len;
1341 struct i_addr address;
1342
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001343 /*
1344 * Set this so we get can supress the printout if we need to.
1345 */
1346 db_display = display;
Alexandre Julliard954a4132000-09-24 03:15:50 +00001347 switch (DEBUG_GetSelectorType(addr->seg))
1348 {
1349 case MODE_VM86:
1350 case MODE_16: db_disasm_16 = 1; break;
1351 case MODE_32: db_disasm_16 = 0; break;
1352 default: DEBUG_Printf(DBG_CHN_MESG, "Bad selector %lx\n", addr->seg); return;
Eric Pouech527eea92000-03-08 16:44:54 +00001353 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001354
Alexandre Julliard808cb041995-08-17 17:11:36 +00001355 get_value_inc( inst, addr, 1, FALSE );
Alexandre Julliard18506551995-01-24 16:21:01 +00001356
1357 if (db_disasm_16) {
1358 short_addr = TRUE;
1359 size = WORD;
1360 }
1361 else {
1362 short_addr = FALSE;
1363 size = LONG;
1364 }
1365 seg = 0;
1366
1367 /*
1368 * Get prefixes
1369 */
1370 prefix = TRUE;
1371 do {
1372 switch (inst) {
1373 case 0x66: /* data16 */
1374 if (size == LONG)
1375 size = WORD;
1376 else
1377 size = LONG;
1378 break;
1379 case 0x67:
1380 short_addr = !short_addr;
1381 break;
1382 case 0x26:
1383 seg = "%es";
1384 break;
1385 case 0x36:
1386 seg = "%ss";
1387 break;
1388 case 0x2e:
1389 seg = "%cs";
1390 break;
1391 case 0x3e:
1392 seg = "%ds";
1393 break;
1394 case 0x64:
1395 seg = "%fs";
1396 break;
1397 case 0x65:
1398 seg = "%gs";
1399 break;
1400 case 0xf0:
Alexandre Julliard46ea8b31998-05-03 19:01:20 +00001401 if( db_display )
Eric Poueche5efa0c2000-04-13 19:31:58 +00001402 DEBUG_Printf(DBG_CHN_MESG,"lock ");
Alexandre Julliard18506551995-01-24 16:21:01 +00001403 break;
1404 case 0xf2:
Alexandre Julliard46ea8b31998-05-03 19:01:20 +00001405 if( db_display )
Eric Poueche5efa0c2000-04-13 19:31:58 +00001406 DEBUG_Printf(DBG_CHN_MESG,"repne ");
Alexandre Julliard18506551995-01-24 16:21:01 +00001407 break;
1408 case 0xf3:
Alexandre Julliard46ea8b31998-05-03 19:01:20 +00001409 if( db_display )
Eric Poueche5efa0c2000-04-13 19:31:58 +00001410 DEBUG_Printf(DBG_CHN_MESG,"repe "); /* XXX repe VS rep */
Alexandre Julliard18506551995-01-24 16:21:01 +00001411 break;
1412 default:
1413 prefix = FALSE;
1414 break;
1415 }
1416 if (prefix) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001417 get_value_inc(inst, addr, 1, FALSE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001418 }
1419 } while (prefix);
1420
Alexandre Julliard808cb041995-08-17 17:11:36 +00001421 if (inst >= 0xd8 && inst <= 0xdf)
1422 {
1423 db_disasm_esc( addr, inst, short_addr, size, seg);
1424 return;
1425 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001426
1427 if (inst == 0x0f) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001428 get_value_inc(inst, addr, 1, FALSE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001429 ip = db_inst_0f[inst>>4];
1430 if (ip == 0) {
1431 ip = &db_bad_inst;
1432 }
1433 else {
1434 ip = &ip[inst&0xf];
1435 }
1436 }
1437 else
1438 ip = &db_inst_table[inst];
1439
1440 if (ip->i_has_modrm) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001441 get_value_inc(regmodrm, addr, 1, FALSE);
1442 db_read_address( addr, short_addr, regmodrm, &address);
Alexandre Julliard18506551995-01-24 16:21:01 +00001443 }
1444
1445 i_name = ip->i_name;
1446 i_size = ip->i_size;
1447 i_mode = ip->i_mode;
1448
1449 if (ip->i_extra == (char *)db_Grp1 ||
1450 ip->i_extra == (char *)db_Grp2 ||
1451 ip->i_extra == (char *)db_Grp6 ||
1452 ip->i_extra == (char *)db_Grp7 ||
Marcus Meissnerea1576b2001-04-23 18:11:17 +00001453 ip->i_extra == (char *)db_Grp8 ||
1454 ip->i_extra == (char *)db_Grp10 ||
1455 ip->i_extra == (char *)db_Grp11 ||
1456 ip->i_extra == (char *)db_Grp12) {
Alexandre Julliard18506551995-01-24 16:21:01 +00001457 i_name = ((char **)ip->i_extra)[f_reg(regmodrm)];
1458 }
1459 else if (ip->i_extra == (char *)db_Grp3) {
1460 ip = (struct inst *)ip->i_extra;
1461 ip = &ip[f_reg(regmodrm)];
1462 i_name = ip->i_name;
1463 i_mode = ip->i_mode;
1464 }
1465 else if (ip->i_extra == (char *)db_Grp4 ||
1466 ip->i_extra == (char *)db_Grp5) {
1467 ip = (struct inst *)ip->i_extra;
1468 ip = &ip[f_reg(regmodrm)];
1469 i_name = ip->i_name;
1470 i_mode = ip->i_mode;
1471 i_size = ip->i_size;
1472 }
1473
1474 if (i_size == SDEP) {
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001475 if( db_display )
1476 {
1477 if (size == WORD)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001478 DEBUG_Printf(DBG_CHN_MESG,i_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001479 else
Eric Poueche5efa0c2000-04-13 19:31:58 +00001480 DEBUG_Printf(DBG_CHN_MESG,ip->i_extra);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001481 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001482 }
1483 else {
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001484 if( db_display )
1485 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001486 DEBUG_Printf(DBG_CHN_MESG,i_name);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001487 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001488 if (i_size != NONE) {
1489 if (i_size == BYTE) {
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001490 if( db_display )
1491 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001492 DEBUG_Printf(DBG_CHN_MESG,"b");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001493 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001494 size = BYTE;
1495 }
1496 else if (i_size == WORD) {
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001497 if( db_display )
1498 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001499 DEBUG_Printf(DBG_CHN_MESG,"w");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001500 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001501 size = WORD;
1502 }
1503 else if (size == WORD)
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001504 {
1505 if( db_display )
1506 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001507 DEBUG_Printf(DBG_CHN_MESG,"w");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001508 }
1509 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001510 else
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001511 {
1512 if( db_display )
1513 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001514 DEBUG_Printf(DBG_CHN_MESG,"l");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001515 }
1516 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001517 }
1518 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001519 if( db_display )
1520 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001521 DEBUG_Printf(DBG_CHN_MESG,"\t");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001522 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001523 for (first = TRUE;
1524 i_mode != 0;
1525 i_mode >>= 8, first = FALSE)
1526 {
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001527 if (!first && db_display)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001528 DEBUG_Printf(DBG_CHN_MESG,",");
Alexandre Julliard18506551995-01-24 16:21:01 +00001529
1530 switch (i_mode & 0xFF) {
1531
1532 case E:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001533 if( db_display )
1534 {
Juergen Schmied36358801999-02-14 13:30:18 +00001535 db_print_address(seg, size, &address, 0);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001536 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001537 break;
1538
1539 case Eind:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001540 if( db_display )
1541 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001542 DEBUG_Printf(DBG_CHN_MESG,"*");
Juergen Schmied36358801999-02-14 13:30:18 +00001543 db_print_address(seg, size, &address, 1);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001544 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001545 break;
1546
1547 case Ew:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001548 if( db_display )
1549 {
Juergen Schmied36358801999-02-14 13:30:18 +00001550 db_print_address(seg, WORD, &address, 0);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001551 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001552 break;
1553
1554 case Eb:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001555 if( db_display )
1556 {
Juergen Schmied36358801999-02-14 13:30:18 +00001557 db_print_address(seg, BYTE, &address, 0);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001558 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001559 break;
1560
1561 case R:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001562 if( db_display )
1563 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001564 DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][f_reg(regmodrm)]);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001565 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001566 break;
Marcus Meissnerea1576b2001-04-23 18:11:17 +00001567 case MX:
1568 if( db_display )
1569 {
1570 DEBUG_Printf(DBG_CHN_MESG,"%%mm%d", f_reg(regmodrm));
1571 }
1572 break;
1573 case EMX:
1574 if( db_display )
1575 {
1576 DEBUG_Printf(DBG_CHN_MESG,"%%mm%d", f_rm(regmodrm));
1577 }
1578 break;
Alexandre Julliard9107c6b2001-07-11 17:33:47 +00001579 case XMM:
1580 if( db_display )
1581 {
1582 DEBUG_Printf(DBG_CHN_MESG,"%%xmm%d", f_reg(regmodrm));
1583 }
1584 break;
1585 case EXMM:
1586 if( db_display )
1587 {
1588 DEBUG_Printf(DBG_CHN_MESG,"%%xmm%d", f_rm(regmodrm));
1589 }
1590 break;
Marcus Meissnerea1576b2001-04-23 18:11:17 +00001591
Alexandre Julliard18506551995-01-24 16:21:01 +00001592
1593 case Rw:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001594 if( db_display )
1595 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001596 DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[WORD][f_reg(regmodrm)]);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001597 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001598 break;
1599
1600 case Ri:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001601 if( db_display )
1602 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001603 DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][f_rm(inst)]);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001604 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001605 break;
1606
1607 case S:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001608 if( db_display )
1609 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001610 DEBUG_Printf(DBG_CHN_MESG,"%s", db_seg_reg[f_reg(regmodrm)]);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001611 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001612 break;
1613
1614 case Si:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001615 if( db_display )
1616 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001617 DEBUG_Printf(DBG_CHN_MESG,"%s", db_seg_reg[f_reg(inst)]);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001618 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001619 break;
1620
1621 case A:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001622 if( db_display )
1623 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001624 DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][0]); /* acc */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001625 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001626 break;
1627
1628 case BX:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001629 if( db_display )
1630 {
1631 if (seg)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001632 DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
1633 DEBUG_Printf(DBG_CHN_MESG,"(%s)", short_addr ? "%bx" : "%ebx");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001634 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001635 break;
1636
1637 case CL:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001638 if( db_display )
1639 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001640 DEBUG_Printf(DBG_CHN_MESG,"%%cl");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001641 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001642 break;
1643
1644 case DX:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001645 if( db_display )
1646 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001647 DEBUG_Printf(DBG_CHN_MESG,"%%dx");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001648 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001649 break;
1650
1651 case SI:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001652 if( db_display )
1653 {
1654 if (seg)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001655 DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
1656 DEBUG_Printf(DBG_CHN_MESG,"(%s)", short_addr ? "%si" : "%esi");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001657 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001658 break;
1659
1660 case DI:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001661 if( db_display )
1662 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001663 DEBUG_Printf(DBG_CHN_MESG,"%%es:(%s)", short_addr ? "%di" : "%edi");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001664 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001665 break;
1666
1667 case CR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001668 if( db_display )
1669 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001670 DEBUG_Printf(DBG_CHN_MESG,"%%cr%d", f_reg(regmodrm));
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001671 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001672 break;
1673
1674 case DR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001675 if( db_display )
1676 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001677 DEBUG_Printf(DBG_CHN_MESG,"%%dr%d", f_reg(regmodrm));
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001678 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001679 break;
1680
1681 case TR:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001682 if( db_display )
1683 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001684 DEBUG_Printf(DBG_CHN_MESG,"%%tr%d", f_reg(regmodrm));
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001685 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001686 break;
1687
1688 case I:
1689 len = db_lengths[size];
Alexandre Julliard808cb041995-08-17 17:11:36 +00001690 get_value_inc(imm, addr, len, FALSE);/* unsigned */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001691 if( db_display )
1692 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001693 DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001694 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001695 break;
1696
1697 case Is:
1698 len = db_lengths[size];
Alexandre Julliard808cb041995-08-17 17:11:36 +00001699 get_value_inc(imm, addr, len, TRUE); /* signed */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001700 if( db_display )
1701 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001702 DEBUG_Printf(DBG_CHN_MESG,"$%d", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001703 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001704 break;
1705
1706 case Ib:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001707 get_value_inc(imm, addr, 1, FALSE); /* unsigned */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001708 if( db_display )
1709 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001710 DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001711 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001712 break;
1713
1714 case Ibs:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001715 get_value_inc(imm, addr, 1, TRUE); /* signed */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001716 if( db_display )
1717 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001718 DEBUG_Printf(DBG_CHN_MESG,"$%d", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001719 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001720 break;
1721
1722 case Iw:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001723 get_value_inc(imm, addr, 2, FALSE); /* unsigned */
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001724 if( db_display )
1725 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001726 DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001727 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001728 break;
1729
1730 case Il:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001731 get_value_inc(imm, addr, 4, FALSE);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001732 if( db_display )
1733 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001734 DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001735 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001736 break;
1737
1738 case O:
1739 if (short_addr) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001740 get_value_inc(displ, addr, 2, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001741 }
1742 else {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001743 get_value_inc(displ, addr, 4, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001744 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001745 if( !db_display )
1746 {
1747 break;
1748 }
1749
Alexandre Julliard18506551995-01-24 16:21:01 +00001750 if (seg)
Eric Poueche5efa0c2000-04-13 19:31:58 +00001751 DEBUG_Printf(DBG_CHN_MESG,"%s:0x%x",seg, displ);
Alexandre Julliard18506551995-01-24 16:21:01 +00001752 else
Alexandre Julliardded30381995-07-06 17:18:27 +00001753 db_task_printsym(displ, short_addr ? WORD : LONG);
Alexandre Julliard18506551995-01-24 16:21:01 +00001754 break;
1755
1756 case Db:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001757 get_value_inc(displ, addr, 1, TRUE);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001758 if( !db_display )
1759 {
1760 break;
1761 }
1762
Ulrich Weigand233cb061999-09-19 12:10:03 +00001763 if (size == WORD) {
Alexandre Julliard18506551995-01-24 16:21:01 +00001764 /* offset only affects low 16 bits */
Alexandre Julliard808cb041995-08-17 17:11:36 +00001765 displ = (addr->off & 0xffff0000)
1766 | ((addr->off + displ) & 0xffff);
Alexandre Julliard18506551995-01-24 16:21:01 +00001767 }
Alexandre Julliard808cb041995-08-17 17:11:36 +00001768 else displ += addr->off;
Ulrich Weigand233cb061999-09-19 12:10:03 +00001769 db_task_printsym(displ, size);
Alexandre Julliard18506551995-01-24 16:21:01 +00001770 break;
1771
1772 case Dl:
Ulrich Weigand233cb061999-09-19 12:10:03 +00001773 if (size == WORD) {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001774 get_value_inc(displ, addr, 2, TRUE);
Alexandre Julliard18506551995-01-24 16:21:01 +00001775 /* offset only affects low 16 bits */
Alexandre Julliard808cb041995-08-17 17:11:36 +00001776 displ = (addr->off & 0xffff0000)
1777 | ((addr->off + displ) & 0xffff);
Alexandre Julliard18506551995-01-24 16:21:01 +00001778 }
1779 else {
Alexandre Julliard808cb041995-08-17 17:11:36 +00001780 get_value_inc(displ, addr, 4, TRUE);
1781 displ += addr->off;
Alexandre Julliard18506551995-01-24 16:21:01 +00001782 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001783 if( !db_display )
1784 {
1785 break;
1786 }
Ulrich Weigand233cb061999-09-19 12:10:03 +00001787 db_task_printsym( displ, size );
Alexandre Julliard18506551995-01-24 16:21:01 +00001788 break;
1789
1790 case o1:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001791 if( db_display )
1792 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001793 DEBUG_Printf(DBG_CHN_MESG,"$1");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001794 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001795 break;
1796
1797 case o3:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001798 if( db_display )
1799 {
Eric Poueche5efa0c2000-04-13 19:31:58 +00001800 DEBUG_Printf(DBG_CHN_MESG,"$3");
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001801 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001802 break;
1803
1804 case OS:
Alexandre Julliard808cb041995-08-17 17:11:36 +00001805 {
1806 DBG_ADDR address;
1807 get_value_inc( address.off, addr, /* offset */
1808 short_addr ? 2 : 4, FALSE );
1809 get_value_inc( address.seg, addr, /* segment */
1810 2, FALSE );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001811 if( db_display )
1812 {
Alexandre Julliard954a4132000-09-24 03:15:50 +00001813 DEBUG_PrintAddress( &address, short_addr ? MODE_16 : MODE_32, TRUE );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001814 }
1815
Alexandre Julliard808cb041995-08-17 17:11:36 +00001816 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001817 break;
1818 }
1819 }
Alexandre Julliard18506551995-01-24 16:21:01 +00001820}
Ulrich Weigandb3ec4b91999-11-13 20:58:45 +00001821
1822#else /* __i386__ */
1823
1824void DEBUG_Disasm( DBG_ADDR *addr, int display )
1825{
1826}
1827
1828#endif /* __i386__ */
1829