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