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