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