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