* configure.in: add we32k
[deliverable/binutils-gdb.git] / binutils / i386-pinsn.c
CommitLineData
289f702d
SC
1/* Stolen from GDB on 27 mar 92 by steve chamberlain */
2/* Print i386 instructions for GDB, the GNU debugger.
3 Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/*
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 * July 1988
24 */
25
26/*
27 * The main tables describing the instructions is essentially a copy
28 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 * Programmers Manual. Usually, there is a capital letter, followed
30 * by a small letter. The capital letter tell the addressing mode,
31 * and the small letter tells about the operand size. Refer to
32 * the Intel manual for details.
33 */
34#include "bfd.h"
35#include "sysdep.h"
36
37#if 0
38#include "defs.h"
39
40#include <ctype.h>
41
42/* For the GDB interface at the bottom of the file... */
43#include "gdbcore.h"
44#endif
45
46#define Eb OP_E, b_mode
47#define indirEb OP_indirE, b_mode
48#define Gb OP_G, b_mode
49#define Ev OP_E, v_mode
50#define indirEv OP_indirE, v_mode
51#define Ew OP_E, w_mode
52#define Ma OP_E, v_mode
53#define M OP_E, 0
54#define Mp OP_E, 0 /* ? */
55#define Gv OP_G, v_mode
56#define Gw OP_G, w_mode
57#define Rw OP_rm, w_mode
58#define Rd OP_rm, d_mode
59#define Ib OP_I, b_mode
60#define sIb OP_sI, b_mode /* sign extened byte */
61#define Iv OP_I, v_mode
62#define Iw OP_I, w_mode
63#define Jb OP_J, b_mode
64#define Jv OP_J, v_mode
65#define ONE OP_ONE, 0
66#define Cd OP_C, d_mode
67#define Dd OP_D, d_mode
68#define Td OP_T, d_mode
69
70#define eAX OP_REG, eAX_reg
71#define eBX OP_REG, eBX_reg
72#define eCX OP_REG, eCX_reg
73#define eDX OP_REG, eDX_reg
74#define eSP OP_REG, eSP_reg
75#define eBP OP_REG, eBP_reg
76#define eSI OP_REG, eSI_reg
77#define eDI OP_REG, eDI_reg
78#define AL OP_REG, al_reg
79#define CL OP_REG, cl_reg
80#define DL OP_REG, dl_reg
81#define BL OP_REG, bl_reg
82#define AH OP_REG, ah_reg
83#define CH OP_REG, ch_reg
84#define DH OP_REG, dh_reg
85#define BH OP_REG, bh_reg
86#define AX OP_REG, ax_reg
87#define DX OP_REG, dx_reg
88#define indirDX OP_REG, indir_dx_reg
89
90#define Sw OP_SEG, w_mode
91#define Ap OP_DIR, lptr
92#define Av OP_DIR, v_mode
93#define Ob OP_OFF, b_mode
94#define Ov OP_OFF, v_mode
95#define Xb OP_DSSI, b_mode
96#define Xv OP_DSSI, v_mode
97#define Yb OP_ESDI, b_mode
98#define Yv OP_ESDI, v_mode
99
100#define es OP_REG, es_reg
101#define ss OP_REG, ss_reg
102#define cs OP_REG, cs_reg
103#define ds OP_REG, ds_reg
104#define fs OP_REG, fs_reg
105#define gs OP_REG, gs_reg
106
107int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
108int OP_J(), OP_SEG();
109int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
110int OP_D(), OP_T(), OP_rm();
111
112
113#define b_mode 1
114#define v_mode 2
115#define w_mode 3
116#define d_mode 4
117
118#define es_reg 100
119#define cs_reg 101
120#define ss_reg 102
121#define ds_reg 103
122#define fs_reg 104
123#define gs_reg 105
124#define eAX_reg 107
125#define eCX_reg 108
126#define eDX_reg 109
127#define eBX_reg 110
128#define eSP_reg 111
129#define eBP_reg 112
130#define eSI_reg 113
131#define eDI_reg 114
132
133#define lptr 115
134
135#define al_reg 116
136#define cl_reg 117
137#define dl_reg 118
138#define bl_reg 119
139#define ah_reg 120
140#define ch_reg 121
141#define dh_reg 122
142#define bh_reg 123
143
144#define ax_reg 124
145#define cx_reg 125
146#define dx_reg 126
147#define bx_reg 127
148#define sp_reg 128
149#define bp_reg 129
150#define si_reg 130
151#define di_reg 131
152
153#define indir_dx_reg 150
154
155#define GRP1b NULL, NULL, 0
156#define GRP1S NULL, NULL, 1
157#define GRP1Ss NULL, NULL, 2
158#define GRP2b NULL, NULL, 3
159#define GRP2S NULL, NULL, 4
160#define GRP2b_one NULL, NULL, 5
161#define GRP2S_one NULL, NULL, 6
162#define GRP2b_cl NULL, NULL, 7
163#define GRP2S_cl NULL, NULL, 8
164#define GRP3b NULL, NULL, 9
165#define GRP3S NULL, NULL, 10
166#define GRP4 NULL, NULL, 11
167#define GRP5 NULL, NULL, 12
168#define GRP6 NULL, NULL, 13
169#define GRP7 NULL, NULL, 14
170#define GRP8 NULL, NULL, 15
171
172#define FLOATCODE 50
173#define FLOAT NULL, NULL, FLOATCODE
174
175struct dis386 {
176 char *name;
177 int (*op1)();
178 int bytemode1;
179 int (*op2)();
180 int bytemode2;
181 int (*op3)();
182 int bytemode3;
183};
184
185struct dis386 dis386[] = {
186 /* 00 */
187 { "addb", Eb, Gb },
188 { "addS", Ev, Gv },
189 { "addb", Gb, Eb },
190 { "addS", Gv, Ev },
191 { "addb", AL, Ib },
192 { "addS", eAX, Iv },
193 { "pushl", es },
194 { "popl", es },
195 /* 08 */
196 { "orb", Eb, Gb },
197 { "orS", Ev, Gv },
198 { "orb", Gb, Eb },
199 { "orS", Gv, Ev },
200 { "orb", AL, Ib },
201 { "orS", eAX, Iv },
202 { "pushl", cs },
203 { "(bad)" }, /* 0x0f extended opcode escape */
204 /* 10 */
205 { "adcb", Eb, Gb },
206 { "adcS", Ev, Gv },
207 { "adcb", Gb, Eb },
208 { "adcS", Gv, Ev },
209 { "adcb", AL, Ib },
210 { "adcS", eAX, Iv },
211 { "pushl", ss },
212 { "popl", ss },
213 /* 18 */
214 { "sbbb", Eb, Gb },
215 { "sbbS", Ev, Gv },
216 { "sbbb", Gb, Eb },
217 { "sbbS", Gv, Ev },
218 { "sbbb", AL, Ib },
219 { "sbbS", eAX, Iv },
220 { "pushl", ds },
221 { "popl", ds },
222 /* 20 */
223 { "andb", Eb, Gb },
224 { "andS", Ev, Gv },
225 { "andb", Gb, Eb },
226 { "andS", Gv, Ev },
227 { "andb", AL, Ib },
228 { "andS", eAX, Iv },
229 { "(bad)" }, /* SEG ES prefix */
230 { "daa" },
231 /* 28 */
232 { "subb", Eb, Gb },
233 { "subS", Ev, Gv },
234 { "subb", Gb, Eb },
235 { "subS", Gv, Ev },
236 { "subb", AL, Ib },
237 { "subS", eAX, Iv },
238 { "(bad)" }, /* SEG CS prefix */
239 { "das" },
240 /* 30 */
241 { "xorb", Eb, Gb },
242 { "xorS", Ev, Gv },
243 { "xorb", Gb, Eb },
244 { "xorS", Gv, Ev },
245 { "xorb", AL, Ib },
246 { "xorS", eAX, Iv },
247 { "(bad)" }, /* SEG SS prefix */
248 { "aaa" },
249 /* 38 */
250 { "cmpb", Eb, Gb },
251 { "cmpS", Ev, Gv },
252 { "cmpb", Gb, Eb },
253 { "cmpS", Gv, Ev },
254 { "cmpb", AL, Ib },
255 { "cmpS", eAX, Iv },
256 { "(bad)" }, /* SEG DS prefix */
257 { "aas" },
258 /* 40 */
259 { "incS", eAX },
260 { "incS", eCX },
261 { "incS", eDX },
262 { "incS", eBX },
263 { "incS", eSP },
264 { "incS", eBP },
265 { "incS", eSI },
266 { "incS", eDI },
267 /* 48 */
268 { "decS", eAX },
269 { "decS", eCX },
270 { "decS", eDX },
271 { "decS", eBX },
272 { "decS", eSP },
273 { "decS", eBP },
274 { "decS", eSI },
275 { "decS", eDI },
276 /* 50 */
277 { "pushS", eAX },
278 { "pushS", eCX },
279 { "pushS", eDX },
280 { "pushS", eBX },
281 { "pushS", eSP },
282 { "pushS", eBP },
283 { "pushS", eSI },
284 { "pushS", eDI },
285 /* 58 */
286 { "popS", eAX },
287 { "popS", eCX },
288 { "popS", eDX },
289 { "popS", eBX },
290 { "popS", eSP },
291 { "popS", eBP },
292 { "popS", eSI },
293 { "popS", eDI },
294 /* 60 */
295 { "pusha" },
296 { "popa" },
297 { "boundS", Gv, Ma },
298 { "arpl", Ew, Gw },
299 { "(bad)" }, /* seg fs */
300 { "(bad)" }, /* seg gs */
301 { "(bad)" }, /* op size prefix */
302 { "(bad)" }, /* adr size prefix */
303 /* 68 */
304 { "pushS", Iv }, /* 386 book wrong */
305 { "imulS", Gv, Ev, Iv },
306 { "pushl", sIb }, /* push of byte really pushes 4 bytes */
307 { "imulS", Gv, Ev, Ib },
308 { "insb", Yb, indirDX },
309 { "insS", Yv, indirDX },
310 { "outsb", indirDX, Xb },
311 { "outsS", indirDX, Xv },
312 /* 70 */
313 { "jo", Jb },
314 { "jno", Jb },
315 { "jb", Jb },
316 { "jae", Jb },
317 { "je", Jb },
318 { "jne", Jb },
319 { "jbe", Jb },
320 { "ja", Jb },
321 /* 78 */
322 { "js", Jb },
323 { "jns", Jb },
324 { "jp", Jb },
325 { "jnp", Jb },
326 { "jl", Jb },
327 { "jnl", Jb },
328 { "jle", Jb },
329 { "jg", Jb },
330 /* 80 */
331 { GRP1b },
332 { GRP1S },
333 { "(bad)" },
334 { GRP1Ss },
335 { "testb", Eb, Gb },
336 { "testS", Ev, Gv },
337 { "xchgb", Eb, Gb },
338 { "xchgS", Ev, Gv },
339 /* 88 */
340 { "movb", Eb, Gb },
341 { "movS", Ev, Gv },
342 { "movb", Gb, Eb },
343 { "movS", Gv, Ev },
344 { "movw", Ew, Sw },
345 { "leaS", Gv, M },
346 { "movw", Sw, Ew },
347 { "popS", Ev },
348 /* 90 */
349 { "nop" },
350 { "xchgS", eCX, eAX },
351 { "xchgS", eDX, eAX },
352 { "xchgS", eBX, eAX },
353 { "xchgS", eSP, eAX },
354 { "xchgS", eBP, eAX },
355 { "xchgS", eSI, eAX },
356 { "xchgS", eDI, eAX },
357 /* 98 */
358 { "cwtl" },
359 { "cltd" },
360 { "lcall", Ap },
361 { "(bad)" }, /* fwait */
362 { "pushf" },
363 { "popf" },
364 { "sahf" },
365 { "lahf" },
366 /* a0 */
367 { "movb", AL, Ob },
368 { "movS", eAX, Ov },
369 { "movb", Ob, AL },
370 { "movS", Ov, eAX },
371 { "movsb", Yb, Xb },
372 { "movsS", Yv, Xv },
373 { "cmpsb", Yb, Xb },
374 { "cmpsS", Yv, Xv },
375 /* a8 */
376 { "testb", AL, Ib },
377 { "testS", eAX, Iv },
378 { "stosb", Yb, AL },
379 { "stosS", Yv, eAX },
380 { "lodsb", AL, Xb },
381 { "lodsS", eAX, Xv },
382 { "scasb", AL, Xb },
383 { "scasS", eAX, Xv },
384 /* b0 */
385 { "movb", AL, Ib },
386 { "movb", CL, Ib },
387 { "movb", DL, Ib },
388 { "movb", BL, Ib },
389 { "movb", AH, Ib },
390 { "movb", CH, Ib },
391 { "movb", DH, Ib },
392 { "movb", BH, Ib },
393 /* b8 */
394 { "movS", eAX, Iv },
395 { "movS", eCX, Iv },
396 { "movS", eDX, Iv },
397 { "movS", eBX, Iv },
398 { "movS", eSP, Iv },
399 { "movS", eBP, Iv },
400 { "movS", eSI, Iv },
401 { "movS", eDI, Iv },
402 /* c0 */
403 { GRP2b },
404 { GRP2S },
405 { "ret", Iw },
406 { "ret" },
407 { "lesS", Gv, Mp },
408 { "ldsS", Gv, Mp },
409 { "movb", Eb, Ib },
410 { "movS", Ev, Iv },
411 /* c8 */
412 { "enter", Iw, Ib },
413 { "leave" },
414 { "lret", Iw },
415 { "lret" },
416 { "int3" },
417 { "int", Ib },
418 { "into" },
419 { "iret" },
420 /* d0 */
421 { GRP2b_one },
422 { GRP2S_one },
423 { GRP2b_cl },
424 { GRP2S_cl },
425 { "aam", Ib },
426 { "aad", Ib },
427 { "(bad)" },
428 { "xlat" },
429 /* d8 */
430 { FLOAT },
431 { FLOAT },
432 { FLOAT },
433 { FLOAT },
434 { FLOAT },
435 { FLOAT },
436 { FLOAT },
437 { FLOAT },
438 /* e0 */
439 { "loopne", Jb },
440 { "loope", Jb },
441 { "loop", Jb },
442 { "jCcxz", Jb },
443 { "inb", AL, Ib },
444 { "inS", eAX, Ib },
445 { "outb", Ib, AL },
446 { "outS", Ib, eAX },
447 /* e8 */
448 { "call", Av },
449 { "jmp", Jv },
450 { "ljmp", Ap },
451 { "jmp", Jb },
452 { "inb", AL, indirDX },
453 { "inS", eAX, indirDX },
454 { "outb", indirDX, AL },
455 { "outS", indirDX, eAX },
456 /* f0 */
457 { "(bad)" }, /* lock prefix */
458 { "(bad)" },
459 { "(bad)" }, /* repne */
460 { "(bad)" }, /* repz */
461 { "hlt" },
462 { "cmc" },
463 { GRP3b },
464 { GRP3S },
465 /* f8 */
466 { "clc" },
467 { "stc" },
468 { "cli" },
469 { "sti" },
470 { "cld" },
471 { "std" },
472 { GRP4 },
473 { GRP5 },
474};
475
476struct dis386 dis386_twobyte[] = {
477 /* 00 */
478 { GRP6 },
479 { GRP7 },
480 { "larS", Gv, Ew },
481 { "lslS", Gv, Ew },
482 { "(bad)" },
483 { "(bad)" },
484 { "clts" },
485 { "(bad)" },
486 /* 08 */
487 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
488 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
489 /* 10 */
490 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
491 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
492 /* 18 */
493 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
494 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
495 /* 20 */
496 /* these are all backward in appendix A of the intel book */
497 { "movl", Rd, Cd },
498 { "movl", Rd, Dd },
499 { "movl", Cd, Rd },
500 { "movl", Dd, Rd },
501 { "movl", Rd, Td },
502 { "(bad)" },
503 { "movl", Td, Rd },
504 { "(bad)" },
505 /* 28 */
506 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
507 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
508 /* 30 */
509 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
510 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
511 /* 38 */
512 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
513 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
514 /* 40 */
515 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
516 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
517 /* 48 */
518 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
519 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
520 /* 50 */
521 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
522 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
523 /* 58 */
524 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
525 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
526 /* 60 */
527 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
528 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
529 /* 68 */
530 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
531 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
532 /* 70 */
533 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
534 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
535 /* 78 */
536 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
537 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
538 /* 80 */
539 { "jo", Jv },
540 { "jno", Jv },
541 { "jb", Jv },
542 { "jae", Jv },
543 { "je", Jv },
544 { "jne", Jv },
545 { "jbe", Jv },
546 { "ja", Jv },
547 /* 88 */
548 { "js", Jv },
549 { "jns", Jv },
550 { "jp", Jv },
551 { "jnp", Jv },
552 { "jl", Jv },
553 { "jge", Jv },
554 { "jle", Jv },
555 { "jg", Jv },
556 /* 90 */
557 { "seto", Eb },
558 { "setno", Eb },
559 { "setb", Eb },
560 { "setae", Eb },
561 { "sete", Eb },
562 { "setne", Eb },
563 { "setbe", Eb },
564 { "seta", Eb },
565 /* 98 */
566 { "sets", Eb },
567 { "setns", Eb },
568 { "setp", Eb },
569 { "setnp", Eb },
570 { "setl", Eb },
571 { "setge", Eb },
572 { "setle", Eb },
573 { "setg", Eb },
574 /* a0 */
575 { "pushl", fs },
576 { "popl", fs },
577 { "(bad)" },
578 { "btS", Ev, Gv },
579 { "shldS", Ev, Gv, Ib },
580 { "shldS", Ev, Gv, CL },
581 { "(bad)" },
582 { "(bad)" },
583 /* a8 */
584 { "pushl", gs },
585 { "popl", gs },
586 { "(bad)" },
587 { "btsS", Ev, Gv },
588 { "shrdS", Ev, Gv, Ib },
589 { "shrdS", Ev, Gv, CL },
590 { "(bad)" },
591 { "imulS", Gv, Ev },
592 /* b0 */
593 { "(bad)" },
594 { "(bad)" },
595 { "lssS", Gv, Mp }, /* 386 lists only Mp */
596 { "btrS", Ev, Gv },
597 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
598 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
599 { "movzbS", Gv, Eb },
600 { "movzwS", Gv, Ew },
601 /* b8 */
602 { "(bad)" },
603 { "(bad)" },
604 { GRP8 },
605 { "btcS", Ev, Gv },
606 { "bsfS", Gv, Ev },
607 { "bsrS", Gv, Ev },
608 { "movsbS", Gv, Eb },
609 { "movswS", Gv, Ew },
610 /* c0 */
611 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
612 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
613 /* c8 */
614 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
615 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
616 /* d0 */
617 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
618 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
619 /* d8 */
620 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
621 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
622 /* e0 */
623 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
624 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
625 /* e8 */
626 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
627 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
628 /* f0 */
629 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
630 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
631 /* f8 */
632 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
633 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
634};
635
636static char obuf[100];
637static char *obufp;
638static char scratchbuf[100];
639static unsigned char *start_codep;
640static unsigned char *codep;
641static int mod;
642static int rm;
643static int reg;
644static void oappend ();
645
646static char *names32[]={
647 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
648};
649static char *names16[] = {
650 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
651};
652static char *names8[] = {
653 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
654};
655static char *names_seg[] = {
656 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
657};
658
659struct dis386 grps[][8] = {
660 /* GRP1b */
661 {
662 { "addb", Eb, Ib },
663 { "orb", Eb, Ib },
664 { "adcb", Eb, Ib },
665 { "sbbb", Eb, Ib },
666 { "andb", Eb, Ib },
667 { "subb", Eb, Ib },
668 { "xorb", Eb, Ib },
669 { "cmpb", Eb, Ib }
670 },
671 /* GRP1S */
672 {
673 { "addS", Ev, Iv },
674 { "orS", Ev, Iv },
675 { "adcS", Ev, Iv },
676 { "sbbS", Ev, Iv },
677 { "andS", Ev, Iv },
678 { "subS", Ev, Iv },
679 { "xorS", Ev, Iv },
680 { "cmpS", Ev, Iv }
681 },
682 /* GRP1Ss */
683 {
684 { "addS", Ev, sIb },
685 { "orS", Ev, sIb },
686 { "adcS", Ev, sIb },
687 { "sbbS", Ev, sIb },
688 { "andS", Ev, sIb },
689 { "subS", Ev, sIb },
690 { "xorS", Ev, sIb },
691 { "cmpS", Ev, sIb }
692 },
693 /* GRP2b */
694 {
695 { "rolb", Eb, Ib },
696 { "rorb", Eb, Ib },
697 { "rclb", Eb, Ib },
698 { "rcrb", Eb, Ib },
699 { "shlb", Eb, Ib },
700 { "shrb", Eb, Ib },
701 { "(bad)" },
702 { "sarb", Eb, Ib },
703 },
704 /* GRP2S */
705 {
706 { "rolS", Ev, Ib },
707 { "rorS", Ev, Ib },
708 { "rclS", Ev, Ib },
709 { "rcrS", Ev, Ib },
710 { "shlS", Ev, Ib },
711 { "shrS", Ev, Ib },
712 { "(bad)" },
713 { "sarS", Ev, Ib },
714 },
715 /* GRP2b_one */
716 {
717 { "rolb", Eb },
718 { "rorb", Eb },
719 { "rclb", Eb },
720 { "rcrb", Eb },
721 { "shlb", Eb },
722 { "shrb", Eb },
723 { "(bad)" },
724 { "sarb", Eb },
725 },
726 /* GRP2S_one */
727 {
728 { "rolS", Ev },
729 { "rorS", Ev },
730 { "rclS", Ev },
731 { "rcrS", Ev },
732 { "shlS", Ev },
733 { "shrS", Ev },
734 { "(bad)" },
735 { "sarS", Ev },
736 },
737 /* GRP2b_cl */
738 {
739 { "rolb", Eb, CL },
740 { "rorb", Eb, CL },
741 { "rclb", Eb, CL },
742 { "rcrb", Eb, CL },
743 { "shlb", Eb, CL },
744 { "shrb", Eb, CL },
745 { "(bad)" },
746 { "sarb", Eb, CL },
747 },
748 /* GRP2S_cl */
749 {
750 { "rolS", Ev, CL },
751 { "rorS", Ev, CL },
752 { "rclS", Ev, CL },
753 { "rcrS", Ev, CL },
754 { "shlS", Ev, CL },
755 { "shrS", Ev, CL },
756 { "(bad)" },
757 { "sarS", Ev, CL }
758 },
759 /* GRP3b */
760 {
761 { "testb", Eb, Ib },
762 { "(bad)", Eb },
763 { "notb", Eb },
764 { "negb", Eb },
765 { "mulb", AL, Eb },
766 { "imulb", AL, Eb },
767 { "divb", AL, Eb },
768 { "idivb", AL, Eb }
769 },
770 /* GRP3S */
771 {
772 { "testS", Ev, Iv },
773 { "(bad)" },
774 { "notS", Ev },
775 { "negS", Ev },
776 { "mulS", eAX, Ev },
777 { "imulS", eAX, Ev },
778 { "divS", eAX, Ev },
779 { "idivS", eAX, Ev },
780 },
781 /* GRP4 */
782 {
783 { "incb", Eb },
784 { "decb", Eb },
785 { "(bad)" },
786 { "(bad)" },
787 { "(bad)" },
788 { "(bad)" },
789 { "(bad)" },
790 { "(bad)" },
791 },
792 /* GRP5 */
793 {
794 { "incS", Ev },
795 { "decS", Ev },
796 { "call", indirEv },
797 { "lcall", indirEv },
798 { "jmp", indirEv },
799 { "ljmp", indirEv },
800 { "pushS", Ev },
801 { "(bad)" },
802 },
803 /* GRP6 */
804 {
805 { "sldt", Ew },
806 { "str", Ew },
807 { "lldt", Ew },
808 { "ltr", Ew },
809 { "verr", Ew },
810 { "verw", Ew },
811 { "(bad)" },
812 { "(bad)" }
813 },
814 /* GRP7 */
815 {
816 { "sgdt", Ew },
817 { "sidt", Ew },
818 { "lgdt", Ew },
819 { "lidt", Ew },
820 { "smsw", Ew },
821 { "(bad)" },
822 { "lmsw", Ew },
823 { "(bad)" },
824 },
825 /* GRP8 */
826 {
827 { "(bad)" },
828 { "(bad)" },
829 { "(bad)" },
830 { "(bad)" },
831 { "btS", Ev, Ib },
832 { "btsS", Ev, Ib },
833 { "btrS", Ev, Ib },
834 { "btcS", Ev, Ib },
835 }
836};
837
838#define PREFIX_REPZ 1
839#define PREFIX_REPNZ 2
840#define PREFIX_LOCK 4
841#define PREFIX_CS 8
842#define PREFIX_SS 0x10
843#define PREFIX_DS 0x20
844#define PREFIX_ES 0x40
845#define PREFIX_FS 0x80
846#define PREFIX_GS 0x100
847#define PREFIX_DATA 0x200
848#define PREFIX_ADR 0x400
849#define PREFIX_FWAIT 0x800
850
851static int prefixes;
852
853ckprefix ()
854{
855 prefixes = 0;
856 while (1)
857 {
858 switch (*codep)
859 {
860 case 0xf3:
861 prefixes |= PREFIX_REPZ;
862 break;
863 case 0xf2:
864 prefixes |= PREFIX_REPNZ;
865 break;
866 case 0xf0:
867 prefixes |= PREFIX_LOCK;
868 break;
869 case 0x2e:
870 prefixes |= PREFIX_CS;
871 break;
872 case 0x36:
873 prefixes |= PREFIX_SS;
874 break;
875 case 0x3e:
876 prefixes |= PREFIX_DS;
877 break;
878 case 0x26:
879 prefixes |= PREFIX_ES;
880 break;
881 case 0x64:
882 prefixes |= PREFIX_FS;
883 break;
884 case 0x65:
885 prefixes |= PREFIX_GS;
886 break;
887 case 0x66:
888 prefixes |= PREFIX_DATA;
889 break;
890 case 0x67:
891 prefixes |= PREFIX_ADR;
892 break;
893 case 0x9b:
894 prefixes |= PREFIX_FWAIT;
895 break;
896 default:
897 return;
898 }
899 codep++;
900 }
901}
902
903static int dflag;
904static int aflag;
905
906static char op1out[100], op2out[100], op3out[100];
907static int op_address[3], op_ad, op_index[3];
908static int start_pc;
909
910
911/*
912 * disassemble the first instruction in 'inbuf'. You have to make
913 * sure all of the bytes of the instruction are filled in.
914 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
915 * (see topic "Redundant prefixes" in the "Differences from 8086"
916 * section of the "Virtual 8086 Mode" chapter.)
917 * 'pc' should be the address of this instruction, it will
918 * be used to print the target address if this is a relative jump or call
919 * 'outbuf' gets filled in with the disassembled instruction. it should
920 * be long enough to hold the longest disassembled instruction.
921 * 100 bytes is certainly enough, unless symbol printing is added later
922 * The function returns the length of this instruction in bytes.
923 */
924i386dis (pc, inbuf, stream)
925 int pc;
926 unsigned char *inbuf;
927 FILE *stream;
928{
929 struct dis386 *dp;
930 char *p;
931 int i;
932 int enter_instruction;
933 char *first, *second, *third;
934 int needcomma;
935
936 obuf[0] = 0;
937 op1out[0] = 0;
938 op2out[0] = 0;
939 op3out[0] = 0;
940
941 op_index[0] = op_index[1] = op_index[2] = -1;
942
943 start_pc = pc;
944 start_codep = inbuf;
945 codep = inbuf;
946
947 ckprefix ();
948
949 if (*codep == 0xc8)
950 enter_instruction = 1;
951 else
952 enter_instruction = 0;
953
954 obufp = obuf;
955
956 if (prefixes & PREFIX_REPZ)
957 oappend ("repz ");
958 if (prefixes & PREFIX_REPNZ)
959 oappend ("repnz ");
960 if (prefixes & PREFIX_LOCK)
961 oappend ("lock ");
962
963 if ((prefixes & PREFIX_FWAIT)
964 && ((*codep < 0xd8) || (*codep > 0xdf)))
965 {
966 /* fwait not followed by floating point instruction */
967 fputs ("fwait", stream);
968 return (1);
969 }
970
971 /* these would be initialized to 0 if disassembling for 8086 or 286 */
972 dflag = 1;
973 aflag = 1;
974
975 if (prefixes & PREFIX_DATA)
976 dflag ^= 1;
977
978 if (prefixes & PREFIX_ADR)
979 {
980 aflag ^= 1;
981 oappend ("addr16 ");
982 }
983
984 if (*codep == 0x0f)
985 dp = &dis386_twobyte[*++codep];
986 else
987 dp = &dis386[*codep];
988 codep++;
989 mod = (*codep >> 6) & 3;
990 reg = (*codep >> 3) & 7;
991 rm = *codep & 7;
992
993 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
994 {
995 dofloat ();
996 }
997 else
998 {
999 if (dp->name == NULL)
1000 dp = &grps[dp->bytemode1][reg];
1001
1002 putop (dp->name);
1003
1004 obufp = op1out;
1005 op_ad = 2;
1006 if (dp->op1)
1007 (*dp->op1)(dp->bytemode1);
1008
1009 obufp = op2out;
1010 op_ad = 1;
1011 if (dp->op2)
1012 (*dp->op2)(dp->bytemode2);
1013
1014 obufp = op3out;
1015 op_ad = 0;
1016 if (dp->op3)
1017 (*dp->op3)(dp->bytemode3);
1018 }
1019
1020 obufp = obuf + strlen (obuf);
1021 for (i = strlen (obuf); i < 6; i++)
1022 oappend (" ");
1023 oappend (" ");
1024 fputs (obuf, stream);
1025
1026 /* enter instruction is printed with operands in the
1027 * same order as the intel book; everything else
1028 * is printed in reverse order
1029 */
1030 if (enter_instruction)
1031 {
1032 first = op1out;
1033 second = op2out;
1034 third = op3out;
1035 op_ad = op_index[0];
1036 op_index[0] = op_index[2];
1037 op_index[2] = op_ad;
1038 }
1039 else
1040 {
1041 first = op3out;
1042 second = op2out;
1043 third = op1out;
1044 }
1045 needcomma = 0;
1046 if (*first)
1047 {
1048 if (op_index[0] != -1)
1049 print_address (op_address[op_index[0]], stream);
1050 else
1051 fputs (first, stream);
1052 needcomma = 1;
1053 }
1054 if (*second)
1055 {
1056 if (needcomma)
1057 fputs (",", stream);
1058 if (op_index[1] != -1)
1059 print_address (op_address[op_index[1]], stream);
1060 else
1061 fputs (second, stream);
1062 needcomma = 1;
1063 }
1064 if (*third)
1065 {
1066 if (needcomma)
1067 fputs (",", stream);
1068 if (op_index[2] != -1)
1069 print_address (op_address[op_index[2]], stream);
1070 else
1071 fputs (third, stream);
1072 }
1073 return (codep - inbuf);
1074}
1075
1076char *float_mem[] = {
1077 /* d8 */
1078 "fadds",
1079 "fmuls",
1080 "fcoms",
1081 "fcomps",
1082 "fsubs",
1083 "fsubrs",
1084 "fdivs",
1085 "fdivrs",
1086 /* d9 */
1087 "flds",
1088 "(bad)",
1089 "fsts",
1090 "fstps",
1091 "fldenv",
1092 "fldcw",
1093 "fNstenv",
1094 "fNstcw",
1095 /* da */
1096 "fiaddl",
1097 "fimull",
1098 "ficoml",
1099 "ficompl",
1100 "fisubl",
1101 "fisubrl",
1102 "fidivl",
1103 "fidivrl",
1104 /* db */
1105 "fildl",
1106 "(bad)",
1107 "fistl",
1108 "fistpl",
1109 "(bad)",
1110 "fldt",
1111 "(bad)",
1112 "fstpt",
1113 /* dc */
1114 "faddl",
1115 "fmull",
1116 "fcoml",
1117 "fcompl",
1118 "fsubl",
1119 "fsubrl",
1120 "fdivl",
1121 "fdivrl",
1122 /* dd */
1123 "fldl",
1124 "(bad)",
1125 "fstl",
1126 "fstpl",
1127 "frstor",
1128 "(bad)",
1129 "fNsave",
1130 "fNstsw",
1131 /* de */
1132 "fiadd",
1133 "fimul",
1134 "ficom",
1135 "ficomp",
1136 "fisub",
1137 "fisubr",
1138 "fidiv",
1139 "fidivr",
1140 /* df */
1141 "fild",
1142 "(bad)",
1143 "fist",
1144 "fistp",
1145 "fbld",
1146 "fildll",
1147 "fbstp",
1148 "fistpll",
1149};
1150
1151#define ST OP_ST, 0
1152#define STi OP_STi, 0
1153int OP_ST(), OP_STi();
1154
1155#define FGRPd9_2 NULL, NULL, 0
1156#define FGRPd9_4 NULL, NULL, 1
1157#define FGRPd9_5 NULL, NULL, 2
1158#define FGRPd9_6 NULL, NULL, 3
1159#define FGRPd9_7 NULL, NULL, 4
1160#define FGRPda_5 NULL, NULL, 5
1161#define FGRPdb_4 NULL, NULL, 6
1162#define FGRPde_3 NULL, NULL, 7
1163#define FGRPdf_4 NULL, NULL, 8
1164
1165struct dis386 float_reg[][8] = {
1166 /* d8 */
1167 {
1168 { "fadd", ST, STi },
1169 { "fmul", ST, STi },
1170 { "fcom", STi },
1171 { "fcomp", STi },
1172 { "fsub", ST, STi },
1173 { "fsubr", ST, STi },
1174 { "fdiv", ST, STi },
1175 { "fdivr", ST, STi },
1176 },
1177 /* d9 */
1178 {
1179 { "fld", STi },
1180 { "fxch", STi },
1181 { FGRPd9_2 },
1182 { "(bad)" },
1183 { FGRPd9_4 },
1184 { FGRPd9_5 },
1185 { FGRPd9_6 },
1186 { FGRPd9_7 },
1187 },
1188 /* da */
1189 {
1190 { "(bad)" },
1191 { "(bad)" },
1192 { "(bad)" },
1193 { "(bad)" },
1194 { "(bad)" },
1195 { FGRPda_5 },
1196 { "(bad)" },
1197 { "(bad)" },
1198 },
1199 /* db */
1200 {
1201 { "(bad)" },
1202 { "(bad)" },
1203 { "(bad)" },
1204 { "(bad)" },
1205 { FGRPdb_4 },
1206 { "(bad)" },
1207 { "(bad)" },
1208 { "(bad)" },
1209 },
1210 /* dc */
1211 {
1212 { "fadd", STi, ST },
1213 { "fmul", STi, ST },
1214 { "(bad)" },
1215 { "(bad)" },
1216 { "fsub", STi, ST },
1217 { "fsubr", STi, ST },
1218 { "fdiv", STi, ST },
1219 { "fdivr", STi, ST },
1220 },
1221 /* dd */
1222 {
1223 { "ffree", STi },
1224 { "(bad)" },
1225 { "fst", STi },
1226 { "fstp", STi },
1227 { "fucom", STi },
1228 { "fucomp", STi },
1229 { "(bad)" },
1230 { "(bad)" },
1231 },
1232 /* de */
1233 {
1234 { "faddp", STi, ST },
1235 { "fmulp", STi, ST },
1236 { "(bad)" },
1237 { FGRPde_3 },
1238 { "fsubp", STi, ST },
1239 { "fsubrp", STi, ST },
1240 { "fdivp", STi, ST },
1241 { "fdivrp", STi, ST },
1242 },
1243 /* df */
1244 {
1245 { "(bad)" },
1246 { "(bad)" },
1247 { "(bad)" },
1248 { "(bad)" },
1249 { FGRPdf_4 },
1250 { "(bad)" },
1251 { "(bad)" },
1252 { "(bad)" },
1253 },
1254};
1255
1256
1257char *fgrps[][8] = {
1258 /* d9_2 0 */
1259 {
1260 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1261 },
1262
1263 /* d9_4 1 */
1264 {
1265 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1266 },
1267
1268 /* d9_5 2 */
1269 {
1270 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1271 },
1272
1273 /* d9_6 3 */
1274 {
1275 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1276 },
1277
1278 /* d9_7 4 */
1279 {
1280 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1281 },
1282
1283 /* da_5 5 */
1284 {
1285 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1286 },
1287
1288 /* db_4 6 */
1289 {
1290 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1291 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1292 },
1293
1294 /* de_3 7 */
1295 {
1296 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1297 },
1298
1299 /* df_4 8 */
1300 {
1301 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1302 },
1303};
1304
1305
1306dofloat ()
1307{
1308 struct dis386 *dp;
1309 unsigned char floatop;
1310
1311 floatop = codep[-1];
1312
1313 if (mod != 3)
1314 {
1315 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1316 obufp = op1out;
1317 OP_E (v_mode);
1318 return;
1319 }
1320 codep++;
1321
1322 dp = &float_reg[floatop - 0xd8][reg];
1323 if (dp->name == NULL)
1324 {
1325 putop (fgrps[dp->bytemode1][rm]);
1326 /* instruction fnstsw is only one with strange arg */
1327 if (floatop == 0xdf && *codep == 0xe0)
1328 strcpy (op1out, "%eax");
1329 }
1330 else
1331 {
1332 putop (dp->name);
1333 obufp = op1out;
1334 if (dp->op1)
1335 (*dp->op1)(dp->bytemode1);
1336 obufp = op2out;
1337 if (dp->op2)
1338 (*dp->op2)(dp->bytemode2);
1339 }
1340}
1341
1342/* ARGSUSED */
1343OP_ST (ignore)
1344{
1345 oappend ("%st");
1346}
1347
1348/* ARGSUSED */
1349OP_STi (ignore)
1350{
1351 sprintf (scratchbuf, "%%st(%d)", rm);
1352 oappend (scratchbuf);
1353}
1354
1355
1356/* capital letters in template are macros */
1357putop (template)
1358 char *template;
1359{
1360 char *p;
1361
1362 for (p = template; *p; p++)
1363 {
1364 switch (*p)
1365 {
1366 default:
1367 *obufp++ = *p;
1368 break;
1369 case 'C': /* For jcxz/jecxz */
1370 if (aflag == 0)
1371 *obufp++ = 'e';
1372 break;
1373 case 'N':
1374 if ((prefixes & PREFIX_FWAIT) == 0)
1375 *obufp++ = 'n';
1376 break;
1377 case 'S':
1378 /* operand size flag */
1379 if (dflag)
1380 *obufp++ = 'l';
1381 else
1382 *obufp++ = 'w';
1383 break;
1384 }
1385 }
1386 *obufp = 0;
1387}
1388
1389static void
1390oappend (s)
1391char *s;
1392{
1393 strcpy (obufp, s);
1394 obufp += strlen (s);
1395 *obufp = 0;
1396}
1397
1398append_prefix ()
1399{
1400 if (prefixes & PREFIX_CS)
1401 oappend ("%cs:");
1402 if (prefixes & PREFIX_DS)
1403 oappend ("%ds:");
1404 if (prefixes & PREFIX_SS)
1405 oappend ("%ss:");
1406 if (prefixes & PREFIX_ES)
1407 oappend ("%es:");
1408 if (prefixes & PREFIX_FS)
1409 oappend ("%fs:");
1410 if (prefixes & PREFIX_GS)
1411 oappend ("%gs:");
1412}
1413
1414OP_indirE (bytemode)
1415{
1416 oappend ("*");
1417 OP_E (bytemode);
1418}
1419
1420OP_E (bytemode)
1421{
1422 int disp;
1423 int havesib;
1424 int didoutput = 0;
1425 int base;
1426 int index;
1427 int scale;
1428 int havebase;
1429
1430 /* skip mod/rm byte */
1431 codep++;
1432
1433 havesib = 0;
1434 havebase = 0;
1435 disp = 0;
1436
1437 if (mod == 3)
1438 {
1439 switch (bytemode)
1440 {
1441 case b_mode:
1442 oappend (names8[rm]);
1443 break;
1444 case w_mode:
1445 oappend (names16[rm]);
1446 break;
1447 case v_mode:
1448 if (dflag)
1449 oappend (names32[rm]);
1450 else
1451 oappend (names16[rm]);
1452 break;
1453 default:
1454 oappend ("<bad dis table>");
1455 break;
1456 }
1457 return;
1458 }
1459
1460 append_prefix ();
1461 if (rm == 4)
1462 {
1463 havesib = 1;
1464 havebase = 1;
1465 scale = (*codep >> 6) & 3;
1466 index = (*codep >> 3) & 7;
1467 base = *codep & 7;
1468 codep++;
1469 }
1470
1471 switch (mod)
1472 {
1473 case 0:
1474 switch (rm)
1475 {
1476 case 4:
1477 /* implies havesib and havebase */
1478 if (base == 5) {
1479 havebase = 0;
1480 disp = get32 ();
1481 }
1482 break;
1483 case 5:
1484 disp = get32 ();
1485 break;
1486 default:
1487 havebase = 1;
1488 base = rm;
1489 break;
1490 }
1491 break;
1492 case 1:
1493 disp = *(char *)codep++;
1494 if (rm != 4)
1495 {
1496 havebase = 1;
1497 base = rm;
1498 }
1499 break;
1500 case 2:
1501 disp = get32 ();
1502 if (rm != 4)
1503 {
1504 havebase = 1;
1505 base = rm;
1506 }
1507 break;
1508 }
1509
1510 if (mod != 0 || rm == 5 || (havesib && base == 5))
1511 {
1512 sprintf (scratchbuf, "0x%x", disp);
1513 oappend (scratchbuf);
1514 }
1515
1516 if (havebase || havesib)
1517 {
1518 oappend ("(");
1519 if (havebase)
1520 oappend (names32[base]);
1521 if (havesib)
1522 {
1523 if (index != 4)
1524 {
1525 sprintf (scratchbuf, ",%s", names32[index]);
1526 oappend (scratchbuf);
1527 }
1528 sprintf (scratchbuf, ",%d", 1 << scale);
1529 oappend (scratchbuf);
1530 }
1531 oappend (")");
1532 }
1533}
1534
1535OP_G (bytemode)
1536{
1537 switch (bytemode)
1538 {
1539 case b_mode:
1540 oappend (names8[reg]);
1541 break;
1542 case w_mode:
1543 oappend (names16[reg]);
1544 break;
1545 case d_mode:
1546 oappend (names32[reg]);
1547 break;
1548 case v_mode:
1549 if (dflag)
1550 oappend (names32[reg]);
1551 else
1552 oappend (names16[reg]);
1553 break;
1554 default:
1555 oappend ("<internal disassembler error>");
1556 break;
1557 }
1558}
1559
1560get32 ()
1561{
1562 int x = 0;
1563
1564 x = *codep++ & 0xff;
1565 x |= (*codep++ & 0xff) << 8;
1566 x |= (*codep++ & 0xff) << 16;
1567 x |= (*codep++ & 0xff) << 24;
1568 return (x);
1569}
1570
1571get16 ()
1572{
1573 int x = 0;
1574
1575 x = *codep++ & 0xff;
1576 x |= (*codep++ & 0xff) << 8;
1577 return (x);
1578}
1579
1580set_op (op)
1581int op;
1582{
1583 op_index[op_ad] = op_ad;
1584 op_address[op_ad] = op;
1585}
1586
1587OP_REG (code)
1588{
1589 char *s;
1590
1591 switch (code)
1592 {
1593 case indir_dx_reg: s = "(%dx)"; break;
1594 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1595 case sp_reg: case bp_reg: case si_reg: case di_reg:
1596 s = names16[code - ax_reg];
1597 break;
1598 case es_reg: case ss_reg: case cs_reg:
1599 case ds_reg: case fs_reg: case gs_reg:
1600 s = names_seg[code - es_reg];
1601 break;
1602 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1603 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1604 s = names8[code - al_reg];
1605 break;
1606 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1607 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1608 if (dflag)
1609 s = names32[code - eAX_reg];
1610 else
1611 s = names16[code - eAX_reg];
1612 break;
1613 default:
1614 s = "<internal disassembler error>";
1615 break;
1616 }
1617 oappend (s);
1618}
1619
1620OP_I (bytemode)
1621{
1622 int op;
1623
1624 switch (bytemode)
1625 {
1626 case b_mode:
1627 op = *codep++ & 0xff;
1628 break;
1629 case v_mode:
1630 if (dflag)
1631 op = get32 ();
1632 else
1633 op = get16 ();
1634 break;
1635 case w_mode:
1636 op = get16 ();
1637 break;
1638 default:
1639 oappend ("<internal disassembler error>");
1640 return;
1641 }
1642 sprintf (scratchbuf, "$0x%x", op);
1643 oappend (scratchbuf);
1644}
1645
1646OP_sI (bytemode)
1647{
1648 int op;
1649
1650 switch (bytemode)
1651 {
1652 case b_mode:
1653 op = *(char *)codep++;
1654 break;
1655 case v_mode:
1656 if (dflag)
1657 op = get32 ();
1658 else
1659 op = (short)get16();
1660 break;
1661 case w_mode:
1662 op = (short)get16 ();
1663 break;
1664 default:
1665 oappend ("<internal disassembler error>");
1666 return;
1667 }
1668 sprintf (scratchbuf, "$0x%x", op);
1669 oappend (scratchbuf);
1670}
1671
1672OP_J (bytemode)
1673{
1674 int disp;
1675 int mask = -1;
1676
1677 switch (bytemode)
1678 {
1679 case b_mode:
1680 disp = *(char *)codep++;
1681 break;
1682 case v_mode:
1683 if (dflag)
1684 disp = get32 ();
1685 else
1686 {
1687 disp = (short)get16 ();
1688 /* for some reason, a data16 prefix on a jump instruction
1689 means that the pc is masked to 16 bits after the
1690 displacement is added! */
1691 mask = 0xffff;
1692 }
1693 break;
1694 default:
1695 oappend ("<internal disassembler error>");
1696 return;
1697 }
1698 disp = (start_pc + codep - start_codep + disp) & mask;
1699 set_op (disp);
1700 sprintf (scratchbuf, "0x%x", disp);
1701 oappend (scratchbuf);
1702}
1703
1704/* ARGSUSED */
1705OP_SEG (dummy)
1706{
1707 static char *sreg[] = {
1708 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1709 };
1710
1711 oappend (sreg[reg]);
1712}
1713
1714OP_DIR (size)
1715{
1716 int seg, offset;
1717
1718 switch (size)
1719 {
1720 case lptr:
1721 if (aflag)
1722 {
1723 offset = get32 ();
1724 seg = get16 ();
1725 }
1726 else
1727 {
1728 offset = get16 ();
1729 seg = get16 ();
1730 }
1731 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1732 oappend (scratchbuf);
1733 break;
1734 case v_mode:
1735 if (aflag)
1736 offset = get32 ();
1737 else
1738 offset = (short)get16 ();
1739
1740 offset = start_pc + codep - start_codep + offset;
1741 set_op (offset);
1742 sprintf (scratchbuf, "0x%x", offset);
1743 oappend (scratchbuf);
1744 break;
1745 default:
1746 oappend ("<internal disassembler error>");
1747 break;
1748 }
1749}
1750
1751/* ARGSUSED */
1752OP_OFF (bytemode)
1753{
1754 int off;
1755
1756 if (aflag)
1757 off = get32 ();
1758 else
1759 off = get16 ();
1760
1761 sprintf (scratchbuf, "0x%x", off);
1762 oappend (scratchbuf);
1763}
1764
1765/* ARGSUSED */
1766OP_ESDI (dummy)
1767{
1768 oappend ("%es:(");
1769 oappend (aflag ? "%edi" : "%di");
1770 oappend (")");
1771}
1772
1773/* ARGSUSED */
1774OP_DSSI (dummy)
1775{
1776 oappend ("%ds:(");
1777 oappend (aflag ? "%esi" : "%si");
1778 oappend (")");
1779}
1780
1781/* ARGSUSED */
1782OP_ONE (dummy)
1783{
1784 oappend ("1");
1785}
1786
1787/* ARGSUSED */
1788OP_C (dummy)
1789{
1790 codep++; /* skip mod/rm */
1791 sprintf (scratchbuf, "%%cr%d", reg);
1792 oappend (scratchbuf);
1793}
1794
1795/* ARGSUSED */
1796OP_D (dummy)
1797{
1798 codep++; /* skip mod/rm */
1799 sprintf (scratchbuf, "%%db%d", reg);
1800 oappend (scratchbuf);
1801}
1802
1803/* ARGSUSED */
1804OP_T (dummy)
1805{
1806 codep++; /* skip mod/rm */
1807 sprintf (scratchbuf, "%%tr%d", reg);
1808 oappend (scratchbuf);
1809}
1810
1811OP_rm (bytemode)
1812{
1813 switch (bytemode)
1814 {
1815 case d_mode:
1816 oappend (names32[rm]);
1817 break;
1818 case w_mode:
1819 oappend (names16[rm]);
1820 break;
1821 }
1822}
1823#define MAXLEN 20
1824#if 0
1825
1826print_insn (memaddr, stream)
1827 CORE_ADDR memaddr;
1828 FILE *stream;
1829{
1830 unsigned char buffer[MAXLEN];
1831
1832 read_memory (memaddr, buffer, MAXLEN);
1833
1834 return (i386dis ((int)memaddr, buffer, stream));
1835}
1836
1837#endif
1838
1839int
1840print_insn_i386(memaddr, buffer, stream)
1841int memaddr;
1842 char *buffer;
1843 FILE *stream;
1844{
1845
1846
1847 return (i386dis ((int)memaddr, buffer, stream));
1848
1849
1850}
This page took 0.096867 seconds and 4 git commands to generate.