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