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