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