]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/db_disasm.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
31 * Revision 1.1.1.1 1998/09/22 21:05:36 wsanchez
32 * Import of Mac OS X kernel (~semeria)
34 * Revision 1.1.1.1 1998/03/07 02:25:37 wsanchez
35 * Import of OSF Mach kernel (~mburg)
37 * Revision 1.2.8.3 1996/07/31 09:43:35 paire
38 * Merged with nmk20b7_shared (1.2.11.1)
41 * Revision 1.2.11.1 1996/05/14 13:49:36 paire
42 * Added support for new cmpxchg8b, cpuid, rdtsc, rdwmr, rsm and wrmsr
43 * Pentium instructions
46 * Revision 1.2.8.2 1994/09/23 01:50:45 ezf
47 * change marker to not FREE
48 * [1994/09/22 21:21:17 ezf]
50 * Revision 1.2.8.1 1994/09/16 15:26:28 emcmanus
51 * Only skip over GAS-inserted NOPs after branches if they are really
52 * NOPs; this depends at least on assembler options.
53 * [1994/09/16 15:26:03 emcmanus]
55 * Revision 1.2.6.3 1994/02/19 15:40:34 bolinger
56 * For load/store counting, mark all varieties of "call" as writing
58 * [1994/02/15 20:25:18 bolinger]
60 * Revision 1.2.6.2 1994/02/14 21:46:49 dwm
62 * [1994/02/14 21:46:14 dwm]
64 * Revision 1.2.6.1 1994/02/12 23:26:05 bolinger
65 * Implement load/store counting for ddb "until" command.
66 * [1994/02/12 03:34:55 bolinger]
68 * Revision 1.2.2.3 1993/08/09 19:39:21 dswartz
69 * Add ANSI prototypes - CR#9523
70 * [1993/08/06 17:44:13 dswartz]
72 * Revision 1.2.2.2 1993/06/09 02:27:29 gm
73 * Added to OSF/1 R1.3 from NMK15.0.
74 * [1993/06/02 21:03:54 jeffc]
76 * Revision 1.2 1993/04/19 16:12:57 devrcs
77 * Print file names and lineno on branch instructions.
81 * Revision 1.1 1992/09/30 02:02:19 robert
88 * Revision 2.5.3.1 92/03/03 16:14:27 jeffreyh
89 * Pick up changes from TRUNK
90 * [92/02/26 11:05:06 jeffreyh]
92 * Revision 2.6 92/01/03 20:05:00 dbg
93 * Add a switch to disassemble 16-bit code.
94 * Fix spelling of 'lods' opcodes.
97 * Revision 2.5 91/10/09 16:05:58 af
98 * Supported disassemble of non current task by passing task parameter.
101 * Revision 2.4 91/05/14 16:05:04 mrt
102 * Correcting copyright
104 * Revision 2.3 91/02/05 17:11:03 mrt
105 * Changed to new Mach copyright
106 * [91/02/01 17:31:03 mrt]
108 * Revision 2.2 90/08/27 21:55:56 dbg
109 * Fix register operand for move to/from control/test/debug
110 * register instructions. Add i486 instructions.
113 * Import db_sym.h. Print instruction displacements in
114 * current radix (signed). Change calling sequence of
125 * Mach Operating System
126 * Copyright (c) 1991,1990 Carnegie Mellon University
127 * All Rights Reserved.
129 * Permission to use, copy, modify and distribute this software and its
130 * documentation is hereby granted, provided that both the copyright
131 * notice and this permission notice appear in all copies of the
132 * software, derivative works or modified versions, and any portions
133 * thereof, and that both notices appear in supporting documentation.
135 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
136 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
137 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
139 * Carnegie Mellon requests users of this software to return to
141 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
142 * School of Computer Science
143 * Carnegie Mellon University
144 * Pittsburgh PA 15213-3890
146 * any improvements or extensions that they make and grant Carnegie Mellon
147 * the rights to redistribute these changes.
153 * Instruction disassembler.
156 #include <mach/boolean.h>
157 #include <machine/db_machdep.h>
159 #include <ddb/db_access.h>
160 #include <ddb/db_sym.h>
161 #include <ddb/db_output.h>
163 #include <kern/task.h>
164 #include <kern/misc_protos.h>
167 int is_reg
; /* if reg, reg number is in 'disp' */
176 extern db_addr_t
db_read_address(
180 struct i_addr
* addrp
,
182 extern void db_print_address(
185 struct i_addr
*addrp
,
187 extern db_addr_t
db_disasm_esc(
196 * Switch to disassemble 16-bit code.
198 boolean_t db_disasm_16
= FALSE
;
216 #define E 1 /* general effective address */
217 #define Eind 2 /* indirect address (jump, call) */
218 #define Ew 3 /* address, word size */
219 #define Eb 4 /* address, byte size */
220 #define R 5 /* register, in 'reg' field */
221 #define Rw 6 /* word register, in 'reg' field */
222 #define Ri 7 /* register in instruction */
223 #define S 8 /* segment reg, in 'reg' field */
224 #define Si 9 /* segment reg, in instruction */
225 #define A 10 /* accumulator */
226 #define BX 11 /* (bx) */
227 #define CL 12 /* cl, for shifts */
228 #define DX 13 /* dx, for IO */
229 #define SI 14 /* si */
230 #define DI 15 /* di */
231 #define CR 16 /* control register */
232 #define DR 17 /* debug register */
233 #define TR 18 /* test register */
234 #define I 19 /* immediate, unsigned */
235 #define Is 20 /* immediate, signed */
236 #define Ib 21 /* byte immediate, unsigned */
237 #define Ibs 22 /* byte immediate, signed */
238 #define Iw 23 /* word immediate, unsigned */
239 #define Il 24 /* long immediate */
240 #define O 25 /* direct address */
241 #define Db 26 /* byte displacement from EIP */
242 #define Dl 27 /* long displacement from EIP */
243 #define o1 28 /* constant 1 */
244 #define o3 29 /* constant 3 */
245 #define OS 30 /* immediate offset/segment */
246 #define ST 31 /* FP stack top */
247 #define STI 32 /* FP stack */
248 #define X 33 /* extended FP op */
249 #define XA 34 /* for 'fstcw %ax' */
252 char * i_name
; /* name */
253 short i_has_modrm
; /* has regmodrm byte */
254 short i_size
; /* operand size */
255 int i_mode
; /* addressing modes */
256 char * i_extra
; /* pointer to extra opcode table */
260 #define op2(x,y) ((x)|((y)<<8))
261 #define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
264 char * f_name
; /* name for memory instruction */
265 int f_size
; /* size for memory instruction */
266 int f_rrmode
; /* mode for rr instruction */
267 char * f_rrname
; /* name for rr instruction
268 (or pointer to table) */
304 struct inst db_inst_0f0x
[] = {
305 /*00*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp6
},
306 /*01*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp7
},
307 /*02*/ { "lar", TRUE
, LONG
, op2(E
,R
), 0 },
308 /*03*/ { "lsl", TRUE
, LONG
, op2(E
,R
), 0 },
309 /*04*/ { "", FALSE
, NONE
, 0, 0 },
310 /*05*/ { "", FALSE
, NONE
, 0, 0 },
311 /*06*/ { "clts", FALSE
, NONE
, 0, 0 },
312 /*07*/ { "", FALSE
, NONE
, 0, 0 },
314 /*08*/ { "invd", FALSE
, NONE
, 0, 0 },
315 /*09*/ { "wbinvd",FALSE
, NONE
, 0, 0 },
316 /*0a*/ { "", FALSE
, NONE
, 0, 0 },
317 /*0b*/ { "", FALSE
, NONE
, 0, 0 },
318 /*0c*/ { "", FALSE
, NONE
, 0, 0 },
319 /*0d*/ { "", FALSE
, NONE
, 0, 0 },
320 /*0e*/ { "", FALSE
, NONE
, 0, 0 },
321 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
324 struct inst db_inst_0f2x
[] = {
325 /*20*/ { "mov", TRUE
, LONG
, op2(CR
,E
), 0 }, /* use E for reg */
326 /*21*/ { "mov", TRUE
, LONG
, op2(DR
,E
), 0 }, /* since mod == 11 */
327 /*22*/ { "mov", TRUE
, LONG
, op2(E
,CR
), 0 },
328 /*23*/ { "mov", TRUE
, LONG
, op2(E
,DR
), 0 },
329 /*24*/ { "mov", TRUE
, LONG
, op2(TR
,E
), 0 },
330 /*25*/ { "", FALSE
, NONE
, 0, 0 },
331 /*26*/ { "mov", TRUE
, LONG
, op2(E
,TR
), 0 },
332 /*27*/ { "", FALSE
, NONE
, 0, 0 },
334 /*28*/ { "", FALSE
, NONE
, 0, 0 },
335 /*29*/ { "", FALSE
, NONE
, 0, 0 },
336 /*2a*/ { "", FALSE
, NONE
, 0, 0 },
337 /*2b*/ { "", FALSE
, NONE
, 0, 0 },
338 /*2c*/ { "", FALSE
, NONE
, 0, 0 },
339 /*2d*/ { "", FALSE
, NONE
, 0, 0 },
340 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
341 /*2f*/ { "", FALSE
, NONE
, 0, 0 },
343 struct inst db_inst_0f3x
[] = {
344 /*30*/ { "rdtsc", FALSE
, NONE
, 0, 0 },
345 /*31*/ { "rdmsr", FALSE
, NONE
, 0, 0 },
346 /*32*/ { "wrmsr", FALSE
, NONE
, 0, 0 },
347 /*33*/ { "", FALSE
, NONE
, 0, 0 },
348 /*34*/ { "", FALSE
, NONE
, 0, 0 },
349 /*35*/ { "", FALSE
, NONE
, 0, 0 },
350 /*36*/ { "", FALSE
, NONE
, 0, 0 },
351 /*37*/ { "", FALSE
, NONE
, 0, 0 },
353 /*38*/ { "", FALSE
, NONE
, 0, 0 },
354 /*39*/ { "", FALSE
, NONE
, 0, 0 },
355 /*3a*/ { "", FALSE
, NONE
, 0, 0 },
356 /*3b*/ { "", FALSE
, NONE
, 0, 0 },
357 /*3c*/ { "", FALSE
, NONE
, 0, 0 },
358 /*3d*/ { "", FALSE
, NONE
, 0, 0 },
359 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
360 /*3f*/ { "", FALSE
, NONE
, 0, 0 },
363 struct inst db_inst_0f8x
[] = {
364 /*80*/ { "jo", FALSE
, NONE
, op1(Dl
), 0 },
365 /*81*/ { "jno", FALSE
, NONE
, op1(Dl
), 0 },
366 /*82*/ { "jb", FALSE
, NONE
, op1(Dl
), 0 },
367 /*83*/ { "jnb", FALSE
, NONE
, op1(Dl
), 0 },
368 /*84*/ { "jz", FALSE
, NONE
, op1(Dl
), 0 },
369 /*85*/ { "jnz", FALSE
, NONE
, op1(Dl
), 0 },
370 /*86*/ { "jbe", FALSE
, NONE
, op1(Dl
), 0 },
371 /*87*/ { "jnbe", FALSE
, NONE
, op1(Dl
), 0 },
373 /*88*/ { "js", FALSE
, NONE
, op1(Dl
), 0 },
374 /*89*/ { "jns", FALSE
, NONE
, op1(Dl
), 0 },
375 /*8a*/ { "jp", FALSE
, NONE
, op1(Dl
), 0 },
376 /*8b*/ { "jnp", FALSE
, NONE
, op1(Dl
), 0 },
377 /*8c*/ { "jl", FALSE
, NONE
, op1(Dl
), 0 },
378 /*8d*/ { "jnl", FALSE
, NONE
, op1(Dl
), 0 },
379 /*8e*/ { "jle", FALSE
, NONE
, op1(Dl
), 0 },
380 /*8f*/ { "jnle", FALSE
, NONE
, op1(Dl
), 0 },
383 struct inst db_inst_0f9x
[] = {
384 /*90*/ { "seto", TRUE
, NONE
, op1(Eb
), 0 },
385 /*91*/ { "setno", TRUE
, NONE
, op1(Eb
), 0 },
386 /*92*/ { "setb", TRUE
, NONE
, op1(Eb
), 0 },
387 /*93*/ { "setnb", TRUE
, NONE
, op1(Eb
), 0 },
388 /*94*/ { "setz", TRUE
, NONE
, op1(Eb
), 0 },
389 /*95*/ { "setnz", TRUE
, NONE
, op1(Eb
), 0 },
390 /*96*/ { "setbe", TRUE
, NONE
, op1(Eb
), 0 },
391 /*97*/ { "setnbe",TRUE
, NONE
, op1(Eb
), 0 },
393 /*98*/ { "sets", TRUE
, NONE
, op1(Eb
), 0 },
394 /*99*/ { "setns", TRUE
, NONE
, op1(Eb
), 0 },
395 /*9a*/ { "setp", TRUE
, NONE
, op1(Eb
), 0 },
396 /*9b*/ { "setnp", TRUE
, NONE
, op1(Eb
), 0 },
397 /*9c*/ { "setl", TRUE
, NONE
, op1(Eb
), 0 },
398 /*9d*/ { "setnl", TRUE
, NONE
, op1(Eb
), 0 },
399 /*9e*/ { "setle", TRUE
, NONE
, op1(Eb
), 0 },
400 /*9f*/ { "setnle",TRUE
, NONE
, op1(Eb
), 0 },
403 struct inst db_inst_0fax
[] = {
404 /*a0*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
405 /*a1*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
406 /*a2*/ { "cpuid", FALSE
, NONE
, 0, 0 },
407 /*a3*/ { "bt", TRUE
, LONG
, op2(E
,R
), 0 },
408 /*a4*/ { "shld", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
409 /*a5*/ { "shld", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
410 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
411 /*a7*/ { "", FALSE
, NONE
, 0, 0 },
413 /*a8*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
414 /*a9*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
415 /*aa*/ { "rsm", FALSE
, NONE
, 0, 0 },
416 /*ab*/ { "bts", TRUE
, LONG
, op2(E
,R
), 0 },
417 /*ac*/ { "shrd", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
418 /*ad*/ { "shrd", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
419 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
420 /*a7*/ { "imul", TRUE
, LONG
, op2(E
,R
), 0 },
423 struct inst db_inst_0fbx
[] = {
424 /*b0*/ { "", FALSE
, NONE
, 0, 0 },
425 /*b1*/ { "", FALSE
, NONE
, 0, 0 },
426 /*b2*/ { "lss", TRUE
, LONG
, op2(E
, R
), 0 },
427 /*b3*/ { "bts", TRUE
, LONG
, op2(R
, E
), 0 },
428 /*b4*/ { "lfs", TRUE
, LONG
, op2(E
, R
), 0 },
429 /*b5*/ { "lgs", TRUE
, LONG
, op2(E
, R
), 0 },
430 /*b6*/ { "movzb", TRUE
, LONG
, op2(E
, R
), 0 },
431 /*b7*/ { "movzw", TRUE
, LONG
, op2(E
, R
), 0 },
433 /*b8*/ { "", FALSE
, NONE
, 0, 0 },
434 /*b9*/ { "", FALSE
, NONE
, 0, 0 },
435 /*ba*/ { "", TRUE
, LONG
, op2(Is
, E
), (char *)db_Grp8
},
436 /*bb*/ { "btc", TRUE
, LONG
, op2(R
, E
), 0 },
437 /*bc*/ { "bsf", TRUE
, LONG
, op2(E
, R
), 0 },
438 /*bd*/ { "bsr", TRUE
, LONG
, op2(E
, R
), 0 },
439 /*be*/ { "movsb", TRUE
, LONG
, op2(E
, R
), 0 },
440 /*bf*/ { "movsw", TRUE
, LONG
, op2(E
, R
), 0 },
443 struct inst db_inst_0fcx
[] = {
444 /*c0*/ { "xadd", TRUE
, BYTE
, op2(R
, E
), 0 },
445 /*c1*/ { "xadd", TRUE
, LONG
, op2(R
, E
), 0 },
446 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
447 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
448 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
449 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
450 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
451 /*c7*/ { "cmpxchg8b", FALSE
, NONE
, op1(E
), 0 },
452 /*c8*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
453 /*c9*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
454 /*ca*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
455 /*cb*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
456 /*cc*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
457 /*cd*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
458 /*ce*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
459 /*cf*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
462 struct inst db_inst_0fdx
[] = {
463 /*c0*/ { "cmpxchg",TRUE
, BYTE
, op2(R
, E
), 0 },
464 /*c1*/ { "cmpxchg",TRUE
, LONG
, op2(R
, E
), 0 },
465 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
466 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
467 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
468 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
469 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
470 /*c7*/ { "", FALSE
, NONE
, 0, 0 },
471 /*c8*/ { "", FALSE
, NONE
, 0, 0 },
472 /*c9*/ { "", FALSE
, NONE
, 0, 0 },
473 /*ca*/ { "", FALSE
, NONE
, 0, 0 },
474 /*cb*/ { "", FALSE
, NONE
, 0, 0 },
475 /*cc*/ { "", FALSE
, NONE
, 0, 0 },
476 /*cd*/ { "", FALSE
, NONE
, 0, 0 },
477 /*ce*/ { "", FALSE
, NONE
, 0, 0 },
478 /*cf*/ { "", FALSE
, NONE
, 0, 0 },
481 struct inst
*db_inst_0f
[] = {
500 char * db_Esc92
[] = {
501 "fnop", "", "", "", "", "", "", ""
503 char * db_Esc93
[] = {
504 "", "", "", "", "", "", "", ""
506 char * db_Esc94
[] = {
507 "fchs", "fabs", "", "", "ftst", "fxam", "", ""
509 char * db_Esc95
[] = {
510 "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
512 char * db_Esc96
[] = {
513 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
516 char * db_Esc97
[] = {
517 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
520 char * db_Esca4
[] = {
521 "", "fucompp","", "", "", "", "", ""
524 char * db_Escb4
[] = {
525 "", "", "fnclex","fninit","", "", "", ""
528 char * db_Esce3
[] = {
529 "", "fcompp","", "", "", "", "", ""
532 char * db_Escf4
[] = {
533 "fnstsw","", "", "", "", "", "", ""
536 struct finst db_Esc8
[] = {
537 /*0*/ { "fadd", SNGL
, op2(STI
,ST
), 0 },
538 /*1*/ { "fmul", SNGL
, op2(STI
,ST
), 0 },
539 /*2*/ { "fcom", SNGL
, op2(STI
,ST
), 0 },
540 /*3*/ { "fcomp", SNGL
, op2(STI
,ST
), 0 },
541 /*4*/ { "fsub", SNGL
, op2(STI
,ST
), 0 },
542 /*5*/ { "fsubr", SNGL
, op2(STI
,ST
), 0 },
543 /*6*/ { "fdiv", SNGL
, op2(STI
,ST
), 0 },
544 /*7*/ { "fdivr", SNGL
, op2(STI
,ST
), 0 },
547 struct finst db_Esc9
[] = {
548 /*0*/ { "fld", SNGL
, op1(STI
), 0 },
549 /*1*/ { "", NONE
, op1(STI
), "fxch" },
550 /*2*/ { "fst", SNGL
, op1(X
), (char *)db_Esc92
},
551 /*3*/ { "fstp", SNGL
, op1(X
), (char *)db_Esc93
},
552 /*4*/ { "fldenv", NONE
, op1(X
), (char *)db_Esc94
},
553 /*5*/ { "fldcw", NONE
, op1(X
), (char *)db_Esc95
},
554 /*6*/ { "fnstenv",NONE
, op1(X
), (char *)db_Esc96
},
555 /*7*/ { "fnstcw", NONE
, op1(X
), (char *)db_Esc97
},
558 struct finst db_Esca
[] = {
559 /*0*/ { "fiadd", WORD
, 0, 0 },
560 /*1*/ { "fimul", WORD
, 0, 0 },
561 /*2*/ { "ficom", WORD
, 0, 0 },
562 /*3*/ { "ficomp", WORD
, 0, 0 },
563 /*4*/ { "fisub", WORD
, op1(X
), (char *)db_Esca4
},
564 /*5*/ { "fisubr", WORD
, 0, 0 },
565 /*6*/ { "fidiv", WORD
, 0, 0 },
566 /*7*/ { "fidivr", WORD
, 0, 0 }
569 struct finst db_Escb
[] = {
570 /*0*/ { "fild", WORD
, 0, 0 },
571 /*1*/ { "", NONE
, 0, 0 },
572 /*2*/ { "fist", WORD
, 0, 0 },
573 /*3*/ { "fistp", WORD
, 0, 0 },
574 /*4*/ { "", WORD
, op1(X
), (char *)db_Escb4
},
575 /*5*/ { "fld", EXTR
, 0, 0 },
576 /*6*/ { "", WORD
, 0, 0 },
577 /*7*/ { "fstp", EXTR
, 0, 0 },
580 struct finst db_Escc
[] = {
581 /*0*/ { "fadd", DBLR
, op2(ST
,STI
), 0 },
582 /*1*/ { "fmul", DBLR
, op2(ST
,STI
), 0 },
583 /*2*/ { "fcom", DBLR
, op2(ST
,STI
), 0 },
584 /*3*/ { "fcomp", DBLR
, op2(ST
,STI
), 0 },
585 /*4*/ { "fsub", DBLR
, op2(ST
,STI
), "fsubr" },
586 /*5*/ { "fsubr", DBLR
, op2(ST
,STI
), "fsub" },
587 /*6*/ { "fdiv", DBLR
, op2(ST
,STI
), "fdivr" },
588 /*7*/ { "fdivr", DBLR
, op2(ST
,STI
), "fdiv" },
591 struct finst db_Escd
[] = {
592 /*0*/ { "fld", DBLR
, op1(STI
), "ffree" },
593 /*1*/ { "", NONE
, 0, 0 },
594 /*2*/ { "fst", DBLR
, op1(STI
), 0 },
595 /*3*/ { "fstp", DBLR
, op1(STI
), 0 },
596 /*4*/ { "frstor", NONE
, op1(STI
), "fucom" },
597 /*5*/ { "", NONE
, op1(STI
), "fucomp" },
598 /*6*/ { "fnsave", NONE
, 0, 0 },
599 /*7*/ { "fnstsw", NONE
, 0, 0 },
602 struct finst db_Esce
[] = {
603 /*0*/ { "fiadd", LONG
, op2(ST
,STI
), "faddp" },
604 /*1*/ { "fimul", LONG
, op2(ST
,STI
), "fmulp" },
605 /*2*/ { "ficom", LONG
, 0, 0 },
606 /*3*/ { "ficomp", LONG
, op1(X
), (char *)db_Esce3
},
607 /*4*/ { "fisub", LONG
, op2(ST
,STI
), "fsubrp" },
608 /*5*/ { "fisubr", LONG
, op2(ST
,STI
), "fsubp" },
609 /*6*/ { "fidiv", LONG
, op2(ST
,STI
), "fdivrp" },
610 /*7*/ { "fidivr", LONG
, op2(ST
,STI
), "fdivp" },
613 struct finst db_Escf
[] = {
614 /*0*/ { "fild", LONG
, 0, 0 },
615 /*1*/ { "", LONG
, 0, 0 },
616 /*2*/ { "fist", LONG
, 0, 0 },
617 /*3*/ { "fistp", LONG
, 0, 0 },
618 /*4*/ { "fbld", NONE
, op1(XA
), (char *)db_Escf4
},
619 /*5*/ { "fld", QUAD
, 0, 0 },
620 /*6*/ { "fbstp", NONE
, 0, 0 },
621 /*7*/ { "fstp", QUAD
, 0, 0 },
624 struct finst
*db_Esc_inst
[] = {
625 db_Esc8
, db_Esc9
, db_Esca
, db_Escb
,
626 db_Escc
, db_Escd
, db_Esce
, db_Escf
651 struct inst db_Grp3
[] = {
652 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
653 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
654 { "not", TRUE
, NONE
, op1(E
), 0 },
655 { "neg", TRUE
, NONE
, op1(E
), 0 },
656 { "mul", TRUE
, NONE
, op2(E
,A
), 0 },
657 { "imul", TRUE
, NONE
, op2(E
,A
), 0 },
658 { "div", TRUE
, NONE
, op2(E
,A
), 0 },
659 { "idiv", TRUE
, NONE
, op2(E
,A
), 0 },
662 struct inst db_Grp4
[] = {
663 { "inc", TRUE
, BYTE
, op1(E
), 0 },
664 { "dec", TRUE
, BYTE
, op1(E
), 0 },
665 { "", TRUE
, NONE
, 0, 0 },
666 { "", TRUE
, NONE
, 0, 0 },
667 { "", TRUE
, NONE
, 0, 0 },
668 { "", TRUE
, NONE
, 0, 0 },
669 { "", TRUE
, NONE
, 0, 0 },
670 { "", TRUE
, NONE
, 0, 0 }
673 struct inst db_Grp5
[] = {
674 { "inc", TRUE
, LONG
, op1(E
), 0 },
675 { "dec", TRUE
, LONG
, op1(E
), 0 },
676 { "call", TRUE
, NONE
, op1(Eind
),0 },
677 { "lcall", TRUE
, NONE
, op1(Eind
),0 },
678 { "jmp", TRUE
, NONE
, op1(Eind
),0 },
679 { "ljmp", TRUE
, NONE
, op1(Eind
),0 },
680 { "push", TRUE
, LONG
, op1(E
), 0 },
681 { "", TRUE
, NONE
, 0, 0 }
684 struct inst db_inst_table
[256] = {
685 /*00*/ { "add", TRUE
, BYTE
, op2(R
, E
), 0 },
686 /*01*/ { "add", TRUE
, LONG
, op2(R
, E
), 0 },
687 /*02*/ { "add", TRUE
, BYTE
, op2(E
, R
), 0 },
688 /*03*/ { "add", TRUE
, LONG
, op2(E
, R
), 0 },
689 /*04*/ { "add", FALSE
, BYTE
, op2(Is
, A
), 0 },
690 /*05*/ { "add", FALSE
, LONG
, op2(Is
, A
), 0 },
691 /*06*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
692 /*07*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
694 /*08*/ { "or", TRUE
, BYTE
, op2(R
, E
), 0 },
695 /*09*/ { "or", TRUE
, LONG
, op2(R
, E
), 0 },
696 /*0a*/ { "or", TRUE
, BYTE
, op2(E
, R
), 0 },
697 /*0b*/ { "or", TRUE
, LONG
, op2(E
, R
), 0 },
698 /*0c*/ { "or", FALSE
, BYTE
, op2(I
, A
), 0 },
699 /*0d*/ { "or", FALSE
, LONG
, op2(I
, A
), 0 },
700 /*0e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
701 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
703 /*10*/ { "adc", TRUE
, BYTE
, op2(R
, E
), 0 },
704 /*11*/ { "adc", TRUE
, LONG
, op2(R
, E
), 0 },
705 /*12*/ { "adc", TRUE
, BYTE
, op2(E
, R
), 0 },
706 /*13*/ { "adc", TRUE
, LONG
, op2(E
, R
), 0 },
707 /*14*/ { "adc", FALSE
, BYTE
, op2(Is
, A
), 0 },
708 /*15*/ { "adc", FALSE
, LONG
, op2(Is
, A
), 0 },
709 /*16*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
710 /*17*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
712 /*18*/ { "sbb", TRUE
, BYTE
, op2(R
, E
), 0 },
713 /*19*/ { "sbb", TRUE
, LONG
, op2(R
, E
), 0 },
714 /*1a*/ { "sbb", TRUE
, BYTE
, op2(E
, R
), 0 },
715 /*1b*/ { "sbb", TRUE
, LONG
, op2(E
, R
), 0 },
716 /*1c*/ { "sbb", FALSE
, BYTE
, op2(Is
, A
), 0 },
717 /*1d*/ { "sbb", FALSE
, LONG
, op2(Is
, A
), 0 },
718 /*1e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
719 /*1f*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
721 /*20*/ { "and", TRUE
, BYTE
, op2(R
, E
), 0 },
722 /*21*/ { "and", TRUE
, LONG
, op2(R
, E
), 0 },
723 /*22*/ { "and", TRUE
, BYTE
, op2(E
, R
), 0 },
724 /*23*/ { "and", TRUE
, LONG
, op2(E
, R
), 0 },
725 /*24*/ { "and", FALSE
, BYTE
, op2(I
, A
), 0 },
726 /*25*/ { "and", FALSE
, LONG
, op2(I
, A
), 0 },
727 /*26*/ { "", FALSE
, NONE
, 0, 0 },
728 /*27*/ { "aaa", FALSE
, NONE
, 0, 0 },
730 /*28*/ { "sub", TRUE
, BYTE
, op2(R
, E
), 0 },
731 /*29*/ { "sub", TRUE
, LONG
, op2(R
, E
), 0 },
732 /*2a*/ { "sub", TRUE
, BYTE
, op2(E
, R
), 0 },
733 /*2b*/ { "sub", TRUE
, LONG
, op2(E
, R
), 0 },
734 /*2c*/ { "sub", FALSE
, BYTE
, op2(Is
, A
), 0 },
735 /*2d*/ { "sub", FALSE
, LONG
, op2(Is
, A
), 0 },
736 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
737 /*2f*/ { "das", FALSE
, NONE
, 0, 0 },
739 /*30*/ { "xor", TRUE
, BYTE
, op2(R
, E
), 0 },
740 /*31*/ { "xor", TRUE
, LONG
, op2(R
, E
), 0 },
741 /*32*/ { "xor", TRUE
, BYTE
, op2(E
, R
), 0 },
742 /*33*/ { "xor", TRUE
, LONG
, op2(E
, R
), 0 },
743 /*34*/ { "xor", FALSE
, BYTE
, op2(I
, A
), 0 },
744 /*35*/ { "xor", FALSE
, LONG
, op2(I
, A
), 0 },
745 /*36*/ { "", FALSE
, NONE
, 0, 0 },
746 /*37*/ { "daa", FALSE
, NONE
, 0, 0 },
748 /*38*/ { "cmp", TRUE
, BYTE
, op2(R
, E
), 0 },
749 /*39*/ { "cmp", TRUE
, LONG
, op2(R
, E
), 0 },
750 /*3a*/ { "cmp", TRUE
, BYTE
, op2(E
, R
), 0 },
751 /*3b*/ { "cmp", TRUE
, LONG
, op2(E
, R
), 0 },
752 /*3c*/ { "cmp", FALSE
, BYTE
, op2(Is
, A
), 0 },
753 /*3d*/ { "cmp", FALSE
, LONG
, op2(Is
, A
), 0 },
754 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
755 /*3f*/ { "aas", FALSE
, NONE
, 0, 0 },
757 /*40*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
758 /*41*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
759 /*42*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
760 /*43*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
761 /*44*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
762 /*45*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
763 /*46*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
764 /*47*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
766 /*48*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
767 /*49*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
768 /*4a*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
769 /*4b*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
770 /*4c*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
771 /*4d*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
772 /*4e*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
773 /*4f*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
775 /*50*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
776 /*51*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
777 /*52*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
778 /*53*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
779 /*54*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
780 /*55*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
781 /*56*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
782 /*57*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
784 /*58*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
785 /*59*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
786 /*5a*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
787 /*5b*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
788 /*5c*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
789 /*5d*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
790 /*5e*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
791 /*5f*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
793 /*60*/ { "pusha", FALSE
, LONG
, 0, 0 },
794 /*61*/ { "popa", FALSE
, LONG
, 0, 0 },
795 /*62*/ { "bound", TRUE
, LONG
, op2(E
, R
), 0 },
796 /*63*/ { "arpl", TRUE
, NONE
, op2(Ew
,Rw
), 0 },
798 /*64*/ { "", FALSE
, NONE
, 0, 0 },
799 /*65*/ { "", FALSE
, NONE
, 0, 0 },
800 /*66*/ { "", FALSE
, NONE
, 0, 0 },
801 /*67*/ { "", FALSE
, NONE
, 0, 0 },
803 /*68*/ { "push", FALSE
, LONG
, op1(I
), 0 },
804 /*69*/ { "imul", TRUE
, LONG
, op3(I
,E
,R
), 0 },
805 /*6a*/ { "push", FALSE
, LONG
, op1(Ib
), 0 },
806 /*6b*/ { "imul", TRUE
, LONG
, op3(Ibs
,E
,R
),0 },
807 /*6c*/ { "ins", FALSE
, BYTE
, op2(DX
, DI
), 0 },
808 /*6d*/ { "ins", FALSE
, LONG
, op2(DX
, DI
), 0 },
809 /*6e*/ { "outs", FALSE
, BYTE
, op2(SI
, DX
), 0 },
810 /*6f*/ { "outs", FALSE
, LONG
, op2(SI
, DX
), 0 },
812 /*70*/ { "jo", FALSE
, NONE
, op1(Db
), 0 },
813 /*71*/ { "jno", FALSE
, NONE
, op1(Db
), 0 },
814 /*72*/ { "jb", FALSE
, NONE
, op1(Db
), 0 },
815 /*73*/ { "jnb", FALSE
, NONE
, op1(Db
), 0 },
816 /*74*/ { "jz", FALSE
, NONE
, op1(Db
), 0 },
817 /*75*/ { "jnz", FALSE
, NONE
, op1(Db
), 0 },
818 /*76*/ { "jbe", FALSE
, NONE
, op1(Db
), 0 },
819 /*77*/ { "jnbe", FALSE
, NONE
, op1(Db
), 0 },
821 /*78*/ { "js", FALSE
, NONE
, op1(Db
), 0 },
822 /*79*/ { "jns", FALSE
, NONE
, op1(Db
), 0 },
823 /*7a*/ { "jp", FALSE
, NONE
, op1(Db
), 0 },
824 /*7b*/ { "jnp", FALSE
, NONE
, op1(Db
), 0 },
825 /*7c*/ { "jl", FALSE
, NONE
, op1(Db
), 0 },
826 /*7d*/ { "jnl", FALSE
, NONE
, op1(Db
), 0 },
827 /*7e*/ { "jle", FALSE
, NONE
, op1(Db
), 0 },
828 /*7f*/ { "jnle", FALSE
, NONE
, op1(Db
), 0 },
830 /*80*/ { "", TRUE
, BYTE
, op2(I
, E
), (char *)db_Grp1
},
831 /*81*/ { "", TRUE
, LONG
, op2(I
, E
), (char *)db_Grp1
},
832 /*82*/ { "", TRUE
, BYTE
, op2(Is
,E
), (char *)db_Grp1
},
833 /*83*/ { "", TRUE
, LONG
, op2(Ibs
,E
), (char *)db_Grp1
},
834 /*84*/ { "test", TRUE
, BYTE
, op2(R
, E
), 0 },
835 /*85*/ { "test", TRUE
, LONG
, op2(R
, E
), 0 },
836 /*86*/ { "xchg", TRUE
, BYTE
, op2(R
, E
), 0 },
837 /*87*/ { "xchg", TRUE
, LONG
, op2(R
, E
), 0 },
839 /*88*/ { "mov", TRUE
, BYTE
, op2(R
, E
), 0 },
840 /*89*/ { "mov", TRUE
, LONG
, op2(R
, E
), 0 },
841 /*8a*/ { "mov", TRUE
, BYTE
, op2(E
, R
), 0 },
842 /*8b*/ { "mov", TRUE
, LONG
, op2(E
, R
), 0 },
843 /*8c*/ { "mov", TRUE
, NONE
, op2(S
, Ew
), 0 },
844 /*8d*/ { "lea", TRUE
, LONG
, op2(E
, R
), 0 },
845 /*8e*/ { "mov", TRUE
, NONE
, op2(Ew
, S
), 0 },
846 /*8f*/ { "pop", TRUE
, LONG
, op1(E
), 0 },
848 /*90*/ { "nop", FALSE
, NONE
, 0, 0 },
849 /*91*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
850 /*92*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
851 /*93*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
852 /*94*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
853 /*95*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
854 /*96*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
855 /*97*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
857 /*98*/ { "cbw", FALSE
, SDEP
, 0, "cwde" }, /* cbw/cwde */
858 /*99*/ { "cwd", FALSE
, SDEP
, 0, "cdq" }, /* cwd/cdq */
859 /*9a*/ { "lcall", FALSE
, NONE
, op1(OS
), 0 },
860 /*9b*/ { "wait", FALSE
, NONE
, 0, 0 },
861 /*9c*/ { "pushf", FALSE
, LONG
, 0, 0 },
862 /*9d*/ { "popf", FALSE
, LONG
, 0, 0 },
863 /*9e*/ { "sahf", FALSE
, NONE
, 0, 0 },
864 /*9f*/ { "lahf", FALSE
, NONE
, 0, 0 },
866 /*a0*/ { "mov", FALSE
, BYTE
, op2(O
, A
), 0 },
867 /*a1*/ { "mov", FALSE
, LONG
, op2(O
, A
), 0 },
868 /*a2*/ { "mov", FALSE
, BYTE
, op2(A
, O
), 0 },
869 /*a3*/ { "mov", FALSE
, LONG
, op2(A
, O
), 0 },
870 /*a4*/ { "movs", FALSE
, BYTE
, op2(SI
,DI
), 0 },
871 /*a5*/ { "movs", FALSE
, LONG
, op2(SI
,DI
), 0 },
872 /*a6*/ { "cmps", FALSE
, BYTE
, op2(SI
,DI
), 0 },
873 /*a7*/ { "cmps", FALSE
, LONG
, op2(SI
,DI
), 0 },
875 /*a8*/ { "test", FALSE
, BYTE
, op2(I
, A
), 0 },
876 /*a9*/ { "test", FALSE
, LONG
, op2(I
, A
), 0 },
877 /*aa*/ { "stos", FALSE
, BYTE
, op1(DI
), 0 },
878 /*ab*/ { "stos", FALSE
, LONG
, op1(DI
), 0 },
879 /*ac*/ { "lods", FALSE
, BYTE
, op1(SI
), 0 },
880 /*ad*/ { "lods", FALSE
, LONG
, op1(SI
), 0 },
881 /*ae*/ { "scas", FALSE
, BYTE
, op1(SI
), 0 },
882 /*af*/ { "scas", FALSE
, LONG
, op1(SI
), 0 },
884 /*b0*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
885 /*b1*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
886 /*b2*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
887 /*b3*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
888 /*b4*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
889 /*b5*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
890 /*b6*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
891 /*b7*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
893 /*b8*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
894 /*b9*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
895 /*ba*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
896 /*bb*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
897 /*bc*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
898 /*bd*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
899 /*be*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
900 /*bf*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
902 /*c0*/ { "", TRUE
, BYTE
, op2(Ib
, E
), (char *)db_Grp2
},
903 /*c1*/ { "", TRUE
, LONG
, op2(Ib
, E
), (char *)db_Grp2
},
904 /*c2*/ { "ret", FALSE
, NONE
, op1(Iw
), 0 },
905 /*c3*/ { "ret", FALSE
, NONE
, 0, 0 },
906 /*c4*/ { "les", TRUE
, LONG
, op2(E
, R
), 0 },
907 /*c5*/ { "lds", TRUE
, LONG
, op2(E
, R
), 0 },
908 /*c6*/ { "mov", TRUE
, BYTE
, op2(I
, E
), 0 },
909 /*c7*/ { "mov", TRUE
, LONG
, op2(I
, E
), 0 },
911 /*c8*/ { "enter", FALSE
, NONE
, op2(Ib
, Iw
), 0 },
912 /*c9*/ { "leave", FALSE
, NONE
, 0, 0 },
913 /*ca*/ { "lret", FALSE
, NONE
, op1(Iw
), 0 },
914 /*cb*/ { "lret", FALSE
, NONE
, 0, 0 },
915 /*cc*/ { "int", FALSE
, NONE
, op1(o3
), 0 },
916 /*cd*/ { "int", FALSE
, NONE
, op1(Ib
), 0 },
917 /*ce*/ { "into", FALSE
, NONE
, 0, 0 },
918 /*cf*/ { "iret", FALSE
, NONE
, 0, 0 },
920 /*d0*/ { "", TRUE
, BYTE
, op2(o1
, E
), (char *)db_Grp2
},
921 /*d1*/ { "", TRUE
, LONG
, op2(o1
, E
), (char *)db_Grp2
},
922 /*d2*/ { "", TRUE
, BYTE
, op2(CL
, E
), (char *)db_Grp2
},
923 /*d3*/ { "", TRUE
, LONG
, op2(CL
, E
), (char *)db_Grp2
},
924 /*d4*/ { "aam", TRUE
, NONE
, 0, 0 },
925 /*d5*/ { "aad", TRUE
, NONE
, 0, 0 },
926 /*d6*/ { "", FALSE
, NONE
, 0, 0 },
927 /*d7*/ { "xlat", FALSE
, BYTE
, op1(BX
), 0 },
929 /*d8*/ { "", TRUE
, NONE
, 0, (char *)db_Esc8
},
930 /*d9*/ { "", TRUE
, NONE
, 0, (char *)db_Esc9
},
931 /*da*/ { "", TRUE
, NONE
, 0, (char *)db_Esca
},
932 /*db*/ { "", TRUE
, NONE
, 0, (char *)db_Escb
},
933 /*dc*/ { "", TRUE
, NONE
, 0, (char *)db_Escc
},
934 /*dd*/ { "", TRUE
, NONE
, 0, (char *)db_Escd
},
935 /*de*/ { "", TRUE
, NONE
, 0, (char *)db_Esce
},
936 /*df*/ { "", TRUE
, NONE
, 0, (char *)db_Escf
},
938 /*e0*/ { "loopne",FALSE
, NONE
, op1(Db
), 0 },
939 /*e1*/ { "loope", FALSE
, NONE
, op1(Db
), 0 },
940 /*e2*/ { "loop", FALSE
, NONE
, op1(Db
), 0 },
941 /*e3*/ { "jcxz", FALSE
, SDEP
, op1(Db
), "jecxz" },
942 /*e4*/ { "in", FALSE
, BYTE
, op2(Ib
, A
), 0 },
943 /*e5*/ { "in", FALSE
, LONG
, op2(Ib
, A
) , 0 },
944 /*e6*/ { "out", FALSE
, BYTE
, op2(A
, Ib
), 0 },
945 /*e7*/ { "out", FALSE
, LONG
, op2(A
, Ib
) , 0 },
947 /*e8*/ { "call", FALSE
, NONE
, op1(Dl
), 0 },
948 /*e9*/ { "jmp", FALSE
, NONE
, op1(Dl
), 0 },
949 /*ea*/ { "ljmp", FALSE
, NONE
, op1(OS
), 0 },
950 /*eb*/ { "jmp", FALSE
, NONE
, op1(Db
), 0 },
951 /*ec*/ { "in", FALSE
, BYTE
, op2(DX
, A
), 0 },
952 /*ed*/ { "in", FALSE
, LONG
, op2(DX
, A
) , 0 },
953 /*ee*/ { "out", FALSE
, BYTE
, op2(A
, DX
), 0 },
954 /*ef*/ { "out", FALSE
, LONG
, op2(A
, DX
) , 0 },
956 /*f0*/ { "", FALSE
, NONE
, 0, 0 },
957 /*f1*/ { "", FALSE
, NONE
, 0, 0 },
958 /*f2*/ { "", FALSE
, NONE
, 0, 0 },
959 /*f3*/ { "", FALSE
, NONE
, 0, 0 },
960 /*f4*/ { "hlt", FALSE
, NONE
, 0, 0 },
961 /*f5*/ { "cmc", FALSE
, NONE
, 0, 0 },
962 /*f6*/ { "", TRUE
, BYTE
, 0, (char *)db_Grp3
},
963 /*f7*/ { "", TRUE
, LONG
, 0, (char *)db_Grp3
},
965 /*f8*/ { "clc", FALSE
, NONE
, 0, 0 },
966 /*f9*/ { "stc", FALSE
, NONE
, 0, 0 },
967 /*fa*/ { "cli", FALSE
, NONE
, 0, 0 },
968 /*fb*/ { "sti", FALSE
, NONE
, 0, 0 },
969 /*fc*/ { "cld", FALSE
, NONE
, 0, 0 },
970 /*fd*/ { "std", FALSE
, NONE
, 0, 0 },
971 /*fe*/ { "", TRUE
, NONE
, 0, (char *)db_Grp4
},
972 /*ff*/ { "", TRUE
, NONE
, 0, (char *)db_Grp5
},
975 struct inst db_bad_inst
=
976 { "???", FALSE
, NONE
, 0, 0 }
979 #define f_mod(byte) ((byte)>>6)
980 #define f_reg(byte) (((byte)>>3)&0x7)
981 #define f_rm(byte) ((byte)&0x7)
983 #define sib_ss(byte) ((byte)>>6)
984 #define sib_index(byte) (((byte)>>3)&0x7)
985 #define sib_base(byte) ((byte)&0x7)
987 char * db_index_reg_16
[8] = {
998 char * db_reg
[3][8] = {
999 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1000 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1001 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
1004 char * db_seg_reg
[8] = {
1005 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
1009 * lengths for size attributes
1011 int db_lengths
[] = {
1021 #define get_value_inc(result, loc, size, is_signed, task) \
1022 result = db_get_task_value((loc), (size), (is_signed), (task)); \
1026 * Read address at location and return updated location.
1033 struct i_addr
*addrp
, /* out */
1036 int mod
, rm
, sib
, index
, ss
, disp
;
1038 mod
= f_mod(regmodrm
);
1039 rm
= f_rm(regmodrm
);
1042 addrp
->is_reg
= TRUE
;
1046 addrp
->is_reg
= FALSE
;
1055 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1061 addrp
->base
= db_index_reg_16
[rm
];
1065 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1067 addrp
->base
= db_index_reg_16
[rm
];
1070 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1072 addrp
->base
= db_index_reg_16
[rm
];
1077 if (mod
!= 3 && rm
== 4) {
1078 get_value_inc(sib
, loc
, 1, FALSE
, task
);
1080 index
= sib_index(sib
);
1082 addrp
->index
= db_reg
[LONG
][index
];
1083 addrp
->ss
= sib_ss(sib
);
1089 get_value_inc(addrp
->disp
, loc
, 4, FALSE
, task
);
1094 addrp
->base
= db_reg
[LONG
][rm
];
1099 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1101 addrp
->base
= db_reg
[LONG
][rm
];
1105 get_value_inc(disp
, loc
, 4, FALSE
, task
);
1107 addrp
->base
= db_reg
[LONG
][rm
];
1118 struct i_addr
*addrp
,
1121 if (addrp
->is_reg
) {
1122 db_printf("%s", db_reg
[size
][addrp
->disp
]);
1127 db_printf("%s:", seg
);
1130 if (addrp
->base
!= 0 || addrp
->index
!= 0) {
1131 db_printf("%#n", addrp
->disp
);
1134 db_printf("%s", addrp
->base
);
1136 db_printf(",%s,%d", addrp
->index
, 1<<addrp
->ss
);
1139 db_task_printsym((db_addr_t
)addrp
->disp
, DB_STGY_ANY
, task
);
1143 * Disassemble floating-point ("escape") instruction
1144 * and return updated location.
1158 struct i_addr address
;
1161 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1162 fp
= &db_Esc_inst
[inst
- 0xd8][f_reg(regmodrm
)];
1163 mod
= f_mod(regmodrm
);
1166 * Normal address modes.
1168 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1169 db_printf(fp
->f_name
);
1170 switch(fp
->f_size
) {
1193 db_print_address(seg
, BYTE
, &address
, task
);
1197 * 'reg-reg' - special formats
1199 switch (fp
->f_rrmode
) {
1201 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1202 db_printf("%s\t%%st,%%st(%d)",name
,f_rm(regmodrm
));
1205 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1206 db_printf("%s\t%%st(%d),%%st",name
, f_rm(regmodrm
));
1209 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1210 db_printf("%s\t%%st(%d)",name
, f_rm(regmodrm
));
1213 db_printf("%s", ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1216 db_printf("%s\t%%ax",
1217 ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1220 db_printf("<bad instruction>");
1229 * Disassemble instruction at 'loc'. 'altfmt' specifies an
1230 * (optional) alternate format. Return address of start of
1254 struct i_addr address
;
1258 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1275 case 0x66: /* data16 */
1282 short_addr
= !short_addr
;
1306 db_printf("repne ");
1309 db_printf("repe "); /* XXX repe VS rep */
1316 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1320 if (inst
>= 0xd8 && inst
<= 0xdf) {
1321 loc
= db_disasm_esc(loc
, inst
, short_addr
, size
, seg
, task
);
1327 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1328 ip
= db_inst_0f
[inst
>>4];
1337 ip
= &db_inst_table
[inst
];
1339 if (ip
->i_has_modrm
) {
1340 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1341 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1344 i_name
= ip
->i_name
;
1345 i_size
= ip
->i_size
;
1346 i_mode
= ip
->i_mode
;
1348 if (ip
->i_extra
== (char *)db_Grp1
||
1349 ip
->i_extra
== (char *)db_Grp2
||
1350 ip
->i_extra
== (char *)db_Grp6
||
1351 ip
->i_extra
== (char *)db_Grp7
||
1352 ip
->i_extra
== (char *)db_Grp8
) {
1353 i_name
= ((char **)ip
->i_extra
)[f_reg(regmodrm
)];
1355 else if (ip
->i_extra
== (char *)db_Grp3
) {
1356 ip
= (struct inst
*)ip
->i_extra
;
1357 ip
= &ip
[f_reg(regmodrm
)];
1358 i_name
= ip
->i_name
;
1359 i_mode
= ip
->i_mode
;
1361 else if (ip
->i_extra
== (char *)db_Grp4
||
1362 ip
->i_extra
== (char *)db_Grp5
) {
1363 ip
= (struct inst
*)ip
->i_extra
;
1364 ip
= &ip
[f_reg(regmodrm
)];
1365 i_name
= ip
->i_name
;
1366 i_mode
= ip
->i_mode
;
1367 i_size
= ip
->i_size
;
1370 if (i_size
== SDEP
) {
1374 db_printf(ip
->i_extra
);
1378 if (i_size
!= NONE
) {
1379 if (i_size
== BYTE
) {
1383 else if (i_size
== WORD
) {
1387 else if (size
== WORD
)
1396 i_mode
>>= 8, first
= FALSE
)
1401 switch (i_mode
& 0xFF) {
1404 db_print_address(seg
, size
, &address
, task
);
1409 db_print_address(seg
, size
, &address
, task
);
1413 db_print_address(seg
, WORD
, &address
, task
);
1417 db_print_address(seg
, BYTE
, &address
, task
);
1421 db_printf("%s", db_reg
[size
][f_reg(regmodrm
)]);
1425 db_printf("%s", db_reg
[WORD
][f_reg(regmodrm
)]);
1429 db_printf("%s", db_reg
[size
][f_rm(inst
)]);
1433 db_printf("%s", db_seg_reg
[f_reg(regmodrm
)]);
1437 db_printf("%s", db_seg_reg
[f_reg(inst
)]);
1441 db_printf("%s", db_reg
[size
][0]); /* acc */
1446 db_printf("%s:", seg
);
1447 db_printf("(%s)", short_addr
? "%bx" : "%ebx");
1460 db_printf("%s:", seg
);
1461 db_printf("(%s)", short_addr
? "%si" : "%esi");
1465 db_printf("%%es:(%s)", short_addr
? "%di" : "%edi");
1469 db_printf("%%cr%d", f_reg(regmodrm
));
1473 db_printf("%%dr%d", f_reg(regmodrm
));
1477 db_printf("%%tr%d", f_reg(regmodrm
));
1481 len
= db_lengths
[size
];
1482 get_value_inc(imm
, loc
, len
, FALSE
, task
);/* unsigned */
1483 db_printf("$%#n", imm
);
1487 len
= db_lengths
[size
];
1488 get_value_inc(imm
, loc
, len
, TRUE
, task
); /* signed */
1489 db_printf("$%#r", imm
);
1493 get_value_inc(imm
, loc
, 1, FALSE
, task
); /* unsigned */
1494 db_printf("$%#n", imm
);
1498 get_value_inc(imm
, loc
, 1, TRUE
, task
); /* signed */
1499 db_printf("$%#r", imm
);
1503 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* unsigned */
1504 db_printf("$%#n", imm
);
1508 get_value_inc(imm
, loc
, 4, FALSE
, task
);
1509 db_printf("$%#n", imm
);
1514 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1517 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1520 db_printf("%s:%#r",seg
, displ
);
1522 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1526 get_value_inc(displ
, loc
, 1, TRUE
, task
);
1528 /* offset only affects low 16 bits */
1529 displ
= (loc
& 0xffff0000)
1530 | ((loc
+ displ
) & 0xffff);
1533 displ
= displ
+ loc
;
1534 db_task_printsym((db_addr_t
)displ
,DB_STGY_ANY
,task
);
1535 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1536 db_printf(" [%s", filename
);
1538 db_printf(":%d", linenum
);
1545 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1546 /* offset only affects low 16 bits */
1547 displ
= (loc
& 0xffff0000)
1548 | ((loc
+ displ
) & 0xffff);
1551 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1552 displ
= displ
+ loc
;
1554 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1555 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1556 db_printf(" [%s", filename
);
1558 db_printf(":%d", linenum
);
1573 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* offset */
1576 get_value_inc(imm
, loc
, 4, FALSE
, task
); /* offset */
1578 get_value_inc(imm2
, loc
, 2, FALSE
, task
); /* segment */
1579 db_printf("$%#n,%#n", imm2
, imm
);
1584 if (altfmt
== 0 && !db_disasm_16
) {
1585 if (inst
== 0xe9 || inst
== 0xeb) { /* jmp, Dl or Db */
1587 * GAS pads to longword boundary after unconditional jumps.
1589 while (loc
& (4-1)) {
1590 get_value_inc(inst
, loc
, 0, FALSE
, task
);
1591 if (inst
!= 0x90) /* nop */
1602 * Classify instructions by whether they read or write memory.
1605 #define DBLS_LOAD 0x01 /* instruction reads from memory */
1606 #define DBLS_STORE 0x02 /* instruction writes to memory */
1608 #define DBLS_MODRM 0x10 /* instruction uses mod r/m byte */
1609 #define DBLS_SECOND 0x20 /* instruction does two operations */
1610 #define DBLS_ESCAPE 0x40 /* escape to two-byte opcodes */
1611 #define DBLS_SWREG 0x80 /* need to switch on reg bits of mod r/m */
1613 #define DBLS_MODS 0xf0
1614 #define DBLS_LMASK (DBLS_MODS|DBLS_LOAD)
1615 #define DBLS_SMASK (DBLS_MODS|DBLS_STORE)
1617 char db_ldstrtab
[] = {
1618 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1619 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x40,
1620 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1621 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1622 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1623 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1624 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1625 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1629 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1630 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1631 0x02, 0x01, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
1632 0x02, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636 0x12, 0x12, 0x00, 0x12, 0x11, 0x11, 0x13, 0x13,
1637 0x12, 0x12, 0x11, 0x11, 0x12, 0x00, 0x11, 0x03,
1638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1639 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x00,
1640 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x21, 0x21,
1641 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
1642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 0x13, 0x13, 0x00, 0x00, 0x01, 0x01, 0x12, 0x12,
1646 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x01,
1648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1655 unsigned char db_ldstrtab0f
[] = {
1656 0x80, 0x80, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1677 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1678 0x02, 0x01, 0x00, 0x11, 0x13, 0x13, 0x00, 0x00,
1679 0x02, 0x01, 0x12, 0x13, 0x13, 0x13, 0x00, 0x11,
1680 0x00, 0x00, 0x01, 0x13, 0x01, 0x01, 0x11, 0x11,
1681 0x00, 0x00, 0x80, 0x13, 0x13, 0x13, 0x11, 0x11,
1683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1693 int db_inst_swreg(boolean_t
, unsigned long, unsigned char);
1696 * Given four bytes of instruction (stored as an int, not an
1697 * array of characters), compute if the instruction reads
1704 unsigned char insb
, bits
;
1708 bits
= db_ldstrtab
[insb
];
1709 if (!(bits
& DBLS_LOAD
))
1712 switch (bits
& DBLS_MODS
) {
1717 return ((insb
& 0xc0) != 0xc0);
1718 case DBLS_SECOND
|DBLS_MODRM
:
1720 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1726 bits
= db_ldstrtab0f
[insb
];
1729 return (db_inst_swreg(TRUE
, insw
, insb
));
1731 panic ("db_inst_load: unknown mod bits");
1737 * Given four bytes of instruction (stored as an int, not an
1738 * array of characters), compute if the instruction writes
1745 unsigned char insb
, bits
;
1749 bits
= db_ldstrtab
[insb
];
1750 if (!(bits
& DBLS_STORE
))
1753 switch (bits
& DBLS_MODS
) {
1758 return ((insb
& 0xc0) != 0xc0);
1759 case DBLS_SECOND
|DBLS_MODRM
:
1761 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1767 bits
= db_ldstrtab0f
[insb
];
1770 return (db_inst_swreg(FALSE
, insw
, insb
));
1772 panic ("db_inst_store: unknown mod bits");
1778 * Parse a mod r/m byte to see if extended opcode reads
1787 unsigned char modrm
= insw
& 0xff;
1791 switch (modrm
& 0x38) {
1796 return ((modrm
& 0xc0) != 0xc0);
1800 switch (modrm
& 0x38) {
1805 return ((modrm
& 0xc0) != 0xc0 ? 2 : 0);
1808 return ((modrm
& 0xc0) != 0xc0);
1813 return ((modrm
& 0xc0) != 0xc0);
1814 switch (modrm
& 0x38) {
1818 return ((modrm
& 0xc0) != 0xc0);