Initial revision
[binutils.git] / opcodes / i386-dis.c
blob19144cb9fc559612fb5e89f6fb153da81afad871
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
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)
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.
36 #include "dis-asm.h"
37 #include "sysdep.h"
38 #include "opintl.h"
40 #define MAXLEN 20
42 #include <setjmp.h>
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
51 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
53 struct dis_private
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;
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)))
69 static int
70 fetch_data (info, addr)
71 struct disassemble_info *info;
72 bfd_byte *addr;
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);
78 status = (*info->read_memory_func) (start,
79 priv->max_fetched,
80 addr - priv->max_fetched,
81 info);
82 if (status != 0)
84 (*info->memory_error_func) (status, start, info);
85 longjmp (priv->bailout, 1);
87 else
88 priv->max_fetched = addr;
89 return 1;
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
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
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
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
156 #define MX OP_MMX, 0
157 #define EM OP_EM, v_mode
158 #define MS OP_MS, b_mode
159 #define OPSUF OP_3DNowSuffix, 0
161 /* bits in sizeflag */
162 #if 0 /* leave undefined until someone adds the extra flag to objdump */
163 #define SUFFIX_ALWAYS 4
164 #endif
165 #define AFLAG 2
166 #define DFLAG 1
168 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag ));
170 static void OP_E PARAMS ((int, int));
171 static void OP_G PARAMS ((int, int));
172 static void OP_I PARAMS ((int, int));
173 static void OP_indirE PARAMS ((int, int));
174 static void OP_sI PARAMS ((int, int));
175 static void OP_REG PARAMS ((int, int));
176 static void OP_J PARAMS ((int, int));
177 static void OP_DIR PARAMS ((int, int));
178 static void OP_OFF PARAMS ((int, int));
179 static void OP_ESreg PARAMS ((int, int));
180 static void OP_DSreg PARAMS ((int, int));
181 static void OP_SEG PARAMS ((int, int));
182 static void OP_C PARAMS ((int, int));
183 static void OP_D PARAMS ((int, int));
184 static void OP_T PARAMS ((int, int));
185 static void OP_rm PARAMS ((int, int));
186 static void OP_ST PARAMS ((int, int));
187 static void OP_STi PARAMS ((int, int));
188 #if 0
189 static void OP_ONE PARAMS ((int, int));
190 #endif
191 static void OP_MMX PARAMS ((int, int));
192 static void OP_EM PARAMS ((int, int));
193 static void OP_MS PARAMS ((int, int));
194 static void OP_3DNowSuffix PARAMS ((int, int));
196 static void append_seg PARAMS ((void));
197 static void set_op PARAMS ((unsigned int op));
198 static void putop PARAMS ((char *template, int sizeflag));
199 static void dofloat PARAMS ((int sizeflag));
200 static int get16 PARAMS ((void));
201 static int get32 PARAMS ((void));
202 static void ckprefix PARAMS ((void));
203 static void ptr_reg PARAMS ((int, int));
205 #define b_mode 1
206 #define v_mode 2
207 #define w_mode 3
208 #define d_mode 4
209 #define x_mode 5
211 #define es_reg 100
212 #define cs_reg 101
213 #define ss_reg 102
214 #define ds_reg 103
215 #define fs_reg 104
216 #define gs_reg 105
217 #define eAX_reg 107
218 #define eCX_reg 108
219 #define eDX_reg 109
220 #define eBX_reg 110
221 #define eSP_reg 111
222 #define eBP_reg 112
223 #define eSI_reg 113
224 #define eDI_reg 114
226 #define lptr 115
228 #define al_reg 116
229 #define cl_reg 117
230 #define dl_reg 118
231 #define bl_reg 119
232 #define ah_reg 120
233 #define ch_reg 121
234 #define dh_reg 122
235 #define bh_reg 123
237 #define ax_reg 124
238 #define cx_reg 125
239 #define dx_reg 126
240 #define bx_reg 127
241 #define sp_reg 128
242 #define bp_reg 129
243 #define si_reg 130
244 #define di_reg 131
246 #define indir_dx_reg 150
248 #define GRP1b NULL, NULL, 0
249 #define GRP1S NULL, NULL, 1
250 #define GRP1Ss NULL, NULL, 2
251 #define GRP2b NULL, NULL, 3
252 #define GRP2S NULL, NULL, 4
253 #define GRP2b_one NULL, NULL, 5
254 #define GRP2S_one NULL, NULL, 6
255 #define GRP2b_cl NULL, NULL, 7
256 #define GRP2S_cl NULL, NULL, 8
257 #define GRP3b NULL, NULL, 9
258 #define GRP3S NULL, NULL, 10
259 #define GRP4 NULL, NULL, 11
260 #define GRP5 NULL, NULL, 12
261 #define GRP6 NULL, NULL, 13
262 #define GRP7 NULL, NULL, 14
263 #define GRP8 NULL, NULL, 15
264 #define GRP9 NULL, NULL, 16
265 #define GRP10 NULL, NULL, 17
266 #define GRP11 NULL, NULL, 18
267 #define GRP12 NULL, NULL, 19
268 #define GRP13 NULL, NULL, 20
269 #define GRP14 NULL, NULL, 21
271 #define FLOATCODE 50
272 #define FLOAT NULL, NULL, FLOATCODE
274 struct dis386 {
275 char *name;
276 op_rtn op1;
277 int bytemode1;
278 op_rtn op2;
279 int bytemode2;
280 op_rtn op3;
281 int bytemode3;
284 /* Upper case letters in the instruction names here are macros.
285 'A' => print 'b' if no register operands or suffix_always is true
286 'B' => print 'b' if suffix_always is true
287 'E' => print 'e' if 32-bit form of jcxz
288 'L' => print 'l' if suffix_always is true
289 'N' => print 'n' if instruction has no wait "prefix"
290 'P' => print 'w' or 'l' if instruction has an operand size prefix,
291 or suffix_always is true
292 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
293 'R' => print 'w' or 'l'
294 'S' => print 'w' or 'l' if suffix_always is true
295 'W' => print 'b' or 'w'
298 static struct dis386 dis386_att[] = {
299 /* 00 */
300 { "addB", Eb, Gb },
301 { "addS", Ev, Gv },
302 { "addB", Gb, Eb },
303 { "addS", Gv, Ev },
304 { "addB", AL, Ib },
305 { "addS", eAX, Iv },
306 { "pushP", es },
307 { "popP", es },
308 /* 08 */
309 { "orB", Eb, Gb },
310 { "orS", Ev, Gv },
311 { "orB", Gb, Eb },
312 { "orS", Gv, Ev },
313 { "orB", AL, Ib },
314 { "orS", eAX, Iv },
315 { "pushP", cs },
316 { "(bad)" }, /* 0x0f extended opcode escape */
317 /* 10 */
318 { "adcB", Eb, Gb },
319 { "adcS", Ev, Gv },
320 { "adcB", Gb, Eb },
321 { "adcS", Gv, Ev },
322 { "adcB", AL, Ib },
323 { "adcS", eAX, Iv },
324 { "pushP", ss },
325 { "popP", ss },
326 /* 18 */
327 { "sbbB", Eb, Gb },
328 { "sbbS", Ev, Gv },
329 { "sbbB", Gb, Eb },
330 { "sbbS", Gv, Ev },
331 { "sbbB", AL, Ib },
332 { "sbbS", eAX, Iv },
333 { "pushP", ds },
334 { "popP", ds },
335 /* 20 */
336 { "andB", Eb, Gb },
337 { "andS", Ev, Gv },
338 { "andB", Gb, Eb },
339 { "andS", Gv, Ev },
340 { "andB", AL, Ib },
341 { "andS", eAX, Iv },
342 { "(bad)" }, /* SEG ES prefix */
343 { "daa" },
344 /* 28 */
345 { "subB", Eb, Gb },
346 { "subS", Ev, Gv },
347 { "subB", Gb, Eb },
348 { "subS", Gv, Ev },
349 { "subB", AL, Ib },
350 { "subS", eAX, Iv },
351 { "(bad)" }, /* SEG CS prefix */
352 { "das" },
353 /* 30 */
354 { "xorB", Eb, Gb },
355 { "xorS", Ev, Gv },
356 { "xorB", Gb, Eb },
357 { "xorS", Gv, Ev },
358 { "xorB", AL, Ib },
359 { "xorS", eAX, Iv },
360 { "(bad)" }, /* SEG SS prefix */
361 { "aaa" },
362 /* 38 */
363 { "cmpB", Eb, Gb },
364 { "cmpS", Ev, Gv },
365 { "cmpB", Gb, Eb },
366 { "cmpS", Gv, Ev },
367 { "cmpB", AL, Ib },
368 { "cmpS", eAX, Iv },
369 { "(bad)" }, /* SEG DS prefix */
370 { "aas" },
371 /* 40 */
372 { "incS", eAX },
373 { "incS", eCX },
374 { "incS", eDX },
375 { "incS", eBX },
376 { "incS", eSP },
377 { "incS", eBP },
378 { "incS", eSI },
379 { "incS", eDI },
380 /* 48 */
381 { "decS", eAX },
382 { "decS", eCX },
383 { "decS", eDX },
384 { "decS", eBX },
385 { "decS", eSP },
386 { "decS", eBP },
387 { "decS", eSI },
388 { "decS", eDI },
389 /* 50 */
390 { "pushS", eAX },
391 { "pushS", eCX },
392 { "pushS", eDX },
393 { "pushS", eBX },
394 { "pushS", eSP },
395 { "pushS", eBP },
396 { "pushS", eSI },
397 { "pushS", eDI },
398 /* 58 */
399 { "popS", eAX },
400 { "popS", eCX },
401 { "popS", eDX },
402 { "popS", eBX },
403 { "popS", eSP },
404 { "popS", eBP },
405 { "popS", eSI },
406 { "popS", eDI },
407 /* 60 */
408 { "pushaP" },
409 { "popaP" },
410 { "boundS", Gv, Ma },
411 { "arpl", Ew, Gw },
412 { "(bad)" }, /* seg fs */
413 { "(bad)" }, /* seg gs */
414 { "(bad)" }, /* op size prefix */
415 { "(bad)" }, /* adr size prefix */
416 /* 68 */
417 { "pushP", Iv }, /* 386 book wrong */
418 { "imulS", Gv, Ev, Iv },
419 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
420 { "imulS", Gv, Ev, sIb },
421 { "insb", Yb, indirDX },
422 { "insR", Yv, indirDX },
423 { "outsb", indirDX, Xb },
424 { "outsR", indirDX, Xv },
425 /* 70 */
426 { "jo", Jb },
427 { "jno", Jb },
428 { "jb", Jb },
429 { "jae", Jb },
430 { "je", Jb },
431 { "jne", Jb },
432 { "jbe", Jb },
433 { "ja", Jb },
434 /* 78 */
435 { "js", Jb },
436 { "jns", Jb },
437 { "jp", Jb },
438 { "jnp", Jb },
439 { "jl", Jb },
440 { "jge", Jb },
441 { "jle", Jb },
442 { "jg", Jb },
443 /* 80 */
444 { GRP1b },
445 { GRP1S },
446 { "(bad)" },
447 { GRP1Ss },
448 { "testB", Eb, Gb },
449 { "testS", Ev, Gv },
450 { "xchgB", Eb, Gb },
451 { "xchgS", Ev, Gv },
452 /* 88 */
453 { "movB", Eb, Gb },
454 { "movS", Ev, Gv },
455 { "movB", Gb, Eb },
456 { "movS", Gv, Ev },
457 { "movQ", Ev, Sw },
458 { "leaS", Gv, M },
459 { "movQ", Sw, Ev },
460 { "popQ", Ev },
461 /* 90 */
462 { "nop" },
463 { "xchgS", eCX, eAX },
464 { "xchgS", eDX, eAX },
465 { "xchgS", eBX, eAX },
466 { "xchgS", eSP, eAX },
467 { "xchgS", eBP, eAX },
468 { "xchgS", eSI, eAX },
469 { "xchgS", eDI, eAX },
470 /* 98 */
471 { "cWtR" },
472 { "cRtd" },
473 { "lcallP", Ap },
474 { "(bad)" }, /* fwait */
475 { "pushfP" },
476 { "popfP" },
477 { "sahf" },
478 { "lahf" },
479 /* a0 */
480 { "movB", AL, Ob },
481 { "movS", eAX, Ov },
482 { "movB", Ob, AL },
483 { "movS", Ov, eAX },
484 { "movsb", Yb, Xb },
485 { "movsR", Yv, Xv },
486 { "cmpsb", Xb, Yb },
487 { "cmpsR", Xv, Yv },
488 /* a8 */
489 { "testB", AL, Ib },
490 { "testS", eAX, Iv },
491 { "stosB", Yb, AL },
492 { "stosS", Yv, eAX },
493 { "lodsB", AL, Xb },
494 { "lodsS", eAX, Xv },
495 { "scasB", AL, Yb },
496 { "scasS", eAX, Yv },
497 /* b0 */
498 { "movB", AL, Ib },
499 { "movB", CL, Ib },
500 { "movB", DL, Ib },
501 { "movB", BL, Ib },
502 { "movB", AH, Ib },
503 { "movB", CH, Ib },
504 { "movB", DH, Ib },
505 { "movB", BH, Ib },
506 /* b8 */
507 { "movS", eAX, Iv },
508 { "movS", eCX, Iv },
509 { "movS", eDX, Iv },
510 { "movS", eBX, Iv },
511 { "movS", eSP, Iv },
512 { "movS", eBP, Iv },
513 { "movS", eSI, Iv },
514 { "movS", eDI, Iv },
515 /* c0 */
516 { GRP2b },
517 { GRP2S },
518 { "retP", Iw },
519 { "retP" },
520 { "lesS", Gv, Mp },
521 { "ldsS", Gv, Mp },
522 { "movA", Eb, Ib },
523 { "movQ", Ev, Iv },
524 /* c8 */
525 { "enterP", Iw, Ib },
526 { "leaveP" },
527 { "lretP", Iw },
528 { "lretP" },
529 { "int3" },
530 { "int", Ib },
531 { "into" },
532 { "iretP" },
533 /* d0 */
534 { GRP2b_one },
535 { GRP2S_one },
536 { GRP2b_cl },
537 { GRP2S_cl },
538 { "aam", sIb },
539 { "aad", sIb },
540 { "(bad)" },
541 { "xlat", DSBX },
542 /* d8 */
543 { FLOAT },
544 { FLOAT },
545 { FLOAT },
546 { FLOAT },
547 { FLOAT },
548 { FLOAT },
549 { FLOAT },
550 { FLOAT },
551 /* e0 */
552 { "loopne", Jb },
553 { "loope", Jb },
554 { "loop", Jb },
555 { "jEcxz", Jb },
556 { "inB", AL, Ib },
557 { "inS", eAX, Ib },
558 { "outB", Ib, AL },
559 { "outS", Ib, eAX },
560 /* e8 */
561 { "callP", Av },
562 { "jmpP", Jv },
563 { "ljmpP", Ap },
564 { "jmp", Jb },
565 { "inB", AL, indirDX },
566 { "inS", eAX, indirDX },
567 { "outB", indirDX, AL },
568 { "outS", indirDX, eAX },
569 /* f0 */
570 { "(bad)" }, /* lock prefix */
571 { "(bad)" },
572 { "(bad)" }, /* repne */
573 { "(bad)" }, /* repz */
574 { "hlt" },
575 { "cmc" },
576 { GRP3b },
577 { GRP3S },
578 /* f8 */
579 { "clc" },
580 { "stc" },
581 { "cli" },
582 { "sti" },
583 { "cld" },
584 { "std" },
585 { GRP4 },
586 { GRP5 },
589 static struct dis386 dis386_intel[] = {
590 /* 00 */
591 { "addB", Eb, Gb },
592 { "addS", Ev, Gv },
593 { "addB", Gb, Eb },
594 { "addS", Gv, Ev },
595 { "addB", AL, Ib },
596 { "addS", eAX, Iv },
597 { "pushP", es },
598 { "popP", es },
599 /* 08 */
600 { "orB", Eb, Gb },
601 { "orS", Ev, Gv },
602 { "orB", Gb, Eb },
603 { "orS", Gv, Ev },
604 { "orB", AL, Ib },
605 { "orS", eAX, Iv },
606 { "pushP", cs },
607 { "(bad)" }, /* 0x0f extended opcode escape */
608 /* 10 */
609 { "adcB", Eb, Gb },
610 { "adcS", Ev, Gv },
611 { "adcB", Gb, Eb },
612 { "adcS", Gv, Ev },
613 { "adcB", AL, Ib },
614 { "adcS", eAX, Iv },
615 { "pushP", ss },
616 { "popP", ss },
617 /* 18 */
618 { "sbbB", Eb, Gb },
619 { "sbbS", Ev, Gv },
620 { "sbbB", Gb, Eb },
621 { "sbbS", Gv, Ev },
622 { "sbbB", AL, Ib },
623 { "sbbS", eAX, Iv },
624 { "pushP", ds },
625 { "popP", ds },
626 /* 20 */
627 { "andB", Eb, Gb },
628 { "andS", Ev, Gv },
629 { "andB", Gb, Eb },
630 { "andS", Gv, Ev },
631 { "andB", AL, Ib },
632 { "andS", eAX, Iv },
633 { "(bad)" }, /* SEG ES prefix */
634 { "daa" },
635 /* 28 */
636 { "subB", Eb, Gb },
637 { "subS", Ev, Gv },
638 { "subB", Gb, Eb },
639 { "subS", Gv, Ev },
640 { "subB", AL, Ib },
641 { "subS", eAX, Iv },
642 { "(bad)" }, /* SEG CS prefix */
643 { "das" },
644 /* 30 */
645 { "xorB", Eb, Gb },
646 { "xorS", Ev, Gv },
647 { "xorB", Gb, Eb },
648 { "xorS", Gv, Ev },
649 { "xorB", AL, Ib },
650 { "xorS", eAX, Iv },
651 { "(bad)" }, /* SEG SS prefix */
652 { "aaa" },
653 /* 38 */
654 { "cmpB", Eb, Gb },
655 { "cmpS", Ev, Gv },
656 { "cmpB", Gb, Eb },
657 { "cmpS", Gv, Ev },
658 { "cmpB", AL, Ib },
659 { "cmpS", eAX, Iv },
660 { "(bad)" }, /* SEG DS prefix */
661 { "aas" },
662 /* 40 */
663 { "incS", eAX },
664 { "incS", eCX },
665 { "incS", eDX },
666 { "incS", eBX },
667 { "incS", eSP },
668 { "incS", eBP },
669 { "incS", eSI },
670 { "incS", eDI },
671 /* 48 */
672 { "decS", eAX },
673 { "decS", eCX },
674 { "decS", eDX },
675 { "decS", eBX },
676 { "decS", eSP },
677 { "decS", eBP },
678 { "decS", eSI },
679 { "decS", eDI },
680 /* 50 */
681 { "pushS", eAX },
682 { "pushS", eCX },
683 { "pushS", eDX },
684 { "pushS", eBX },
685 { "pushS", eSP },
686 { "pushS", eBP },
687 { "pushS", eSI },
688 { "pushS", eDI },
689 /* 58 */
690 { "popS", eAX },
691 { "popS", eCX },
692 { "popS", eDX },
693 { "popS", eBX },
694 { "popS", eSP },
695 { "popS", eBP },
696 { "popS", eSI },
697 { "popS", eDI },
698 /* 60 */
699 { "pushaP" },
700 { "popaP" },
701 { "boundS", Gv, Ma },
702 { "arpl", Ew, Gw },
703 { "(bad)" }, /* seg fs */
704 { "(bad)" }, /* seg gs */
705 { "(bad)" }, /* op size prefix */
706 { "(bad)" }, /* adr size prefix */
707 /* 68 */
708 { "pushP", Iv }, /* 386 book wrong */
709 { "imulS", Gv, Ev, Iv },
710 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
711 { "imulS", Gv, Ev, sIb },
712 { "insb", Yb, indirDX },
713 { "insR", Yv, indirDX },
714 { "outsb", indirDX, Xb },
715 { "outsR", indirDX, Xv },
716 /* 70 */
717 { "jo", Jb },
718 { "jno", Jb },
719 { "jb", Jb },
720 { "jae", Jb },
721 { "je", Jb },
722 { "jne", Jb },
723 { "jbe", Jb },
724 { "ja", Jb },
725 /* 78 */
726 { "js", Jb },
727 { "jns", Jb },
728 { "jp", Jb },
729 { "jnp", Jb },
730 { "jl", Jb },
731 { "jge", Jb },
732 { "jle", Jb },
733 { "jg", Jb },
734 /* 80 */
735 { GRP1b },
736 { GRP1S },
737 { "(bad)" },
738 { GRP1Ss },
739 { "testB", Eb, Gb },
740 { "testS", Ev, Gv },
741 { "xchgB", Eb, Gb },
742 { "xchgS", Ev, Gv },
743 /* 88 */
744 { "movB", Eb, Gb },
745 { "movS", Ev, Gv },
746 { "movB", Gb, Eb },
747 { "movS", Gv, Ev },
748 { "movQ", Ev, Sw },
749 { "leaS", Gv, M },
750 { "movQ", Sw, Ev },
751 { "popQ", Ev },
752 /* 90 */
753 { "nop" },
754 { "xchgS", eCX, eAX },
755 { "xchgS", eDX, eAX },
756 { "xchgS", eBX, eAX },
757 { "xchgS", eSP, eAX },
758 { "xchgS", eBP, eAX },
759 { "xchgS", eSI, eAX },
760 { "xchgS", eDI, eAX },
761 /* 98 */
762 { "cWtR" },
763 { "cRtd" },
764 { "lcallP", Ap },
765 { "(bad)" }, /* fwait */
766 { "pushfP" },
767 { "popfP" },
768 { "sahf" },
769 { "lahf" },
770 /* a0 */
771 { "movB", AL, Ob },
772 { "movS", eAX, Ov },
773 { "movB", Ob, AL },
774 { "movS", Ov, eAX },
775 { "movsb", Yb, Xb },
776 { "movsR", Yv, Xv },
777 { "cmpsb", Xb, Yb },
778 { "cmpsR", Xv, Yv },
779 /* a8 */
780 { "testB", AL, Ib },
781 { "testS", eAX, Iv },
782 { "stosB", Yb, AL },
783 { "stosS", Yv, eAX },
784 { "lodsB", AL, Xb },
785 { "lodsS", eAX, Xv },
786 { "scasB", AL, Yb },
787 { "scasS", eAX, Yv },
788 /* b0 */
789 { "movB", AL, Ib },
790 { "movB", CL, Ib },
791 { "movB", DL, Ib },
792 { "movB", BL, Ib },
793 { "movB", AH, Ib },
794 { "movB", CH, Ib },
795 { "movB", DH, Ib },
796 { "movB", BH, Ib },
797 /* b8 */
798 { "movS", eAX, Iv },
799 { "movS", eCX, Iv },
800 { "movS", eDX, Iv },
801 { "movS", eBX, Iv },
802 { "movS", eSP, Iv },
803 { "movS", eBP, Iv },
804 { "movS", eSI, Iv },
805 { "movS", eDI, Iv },
806 /* c0 */
807 { GRP2b },
808 { GRP2S },
809 { "retP", Iw },
810 { "retP" },
811 { "lesS", Gv, Mp },
812 { "ldsS", Gv, Mp },
813 { "movA", Eb, Ib },
814 { "movQ", Ev, Iv },
815 /* c8 */
816 { "enterP", Iw, Ib },
817 { "leaveP" },
818 { "lretP", Iw },
819 { "lretP" },
820 { "int3" },
821 { "int", Ib },
822 { "into" },
823 { "iretP" },
824 /* d0 */
825 { GRP2b_one },
826 { GRP2S_one },
827 { GRP2b_cl },
828 { GRP2S_cl },
829 { "aam", sIb },
830 { "aad", sIb },
831 { "(bad)" },
832 { "xlat", DSBX },
833 /* d8 */
834 { FLOAT },
835 { FLOAT },
836 { FLOAT },
837 { FLOAT },
838 { FLOAT },
839 { FLOAT },
840 { FLOAT },
841 { FLOAT },
842 /* e0 */
843 { "loopne", Jb },
844 { "loope", Jb },
845 { "loop", Jb },
846 { "jEcxz", Jb },
847 { "inB", AL, Ib },
848 { "inS", eAX, Ib },
849 { "outB", Ib, AL },
850 { "outS", Ib, eAX },
851 /* e8 */
852 { "callP", Av },
853 { "jmpP", Jv },
854 { "ljmpP", Ap },
855 { "jmp", Jb },
856 { "inB", AL, indirDX },
857 { "inS", eAX, indirDX },
858 { "outB", indirDX, AL },
859 { "outS", indirDX, eAX },
860 /* f0 */
861 { "(bad)" }, /* lock prefix */
862 { "(bad)" },
863 { "(bad)" }, /* repne */
864 { "(bad)" }, /* repz */
865 { "hlt" },
866 { "cmc" },
867 { GRP3b },
868 { GRP3S },
869 /* f8 */
870 { "clc" },
871 { "stc" },
872 { "cli" },
873 { "sti" },
874 { "cld" },
875 { "std" },
876 { GRP4 },
877 { GRP5 },
880 static struct dis386 dis386_twobyte_att[] = {
881 /* 00 */
882 { GRP6 },
883 { GRP7 },
884 { "larS", Gv, Ew },
885 { "lslS", Gv, Ew },
886 { "(bad)" },
887 { "(bad)" },
888 { "clts" },
889 { "(bad)" },
890 /* 08 */
891 { "invd" },
892 { "wbinvd" },
893 { "(bad)" },
894 { "ud2a" },
895 { "(bad)" },
896 { GRP14 },
897 { "femms" },
898 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
899 /* 10 */
900 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
901 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
902 /* 18 */
903 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
904 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
905 /* 20 */
906 /* these are all backward in appendix A of the intel book */
907 { "movL", Rd, Cd },
908 { "movL", Rd, Dd },
909 { "movL", Cd, Rd },
910 { "movL", Dd, Rd },
911 { "movL", Rd, Td },
912 { "(bad)" },
913 { "movL", Td, Rd },
914 { "(bad)" },
915 /* 28 */
916 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
917 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
918 /* 30 */
919 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
920 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
921 /* 38 */
922 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
923 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
924 /* 40 */
925 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
926 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
927 /* 48 */
928 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
929 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
930 /* 50 */
931 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
932 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
933 /* 58 */
934 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
935 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
936 /* 60 */
937 { "punpcklbw", MX, EM },
938 { "punpcklwd", MX, EM },
939 { "punpckldq", MX, EM },
940 { "packsswb", MX, EM },
941 { "pcmpgtb", MX, EM },
942 { "pcmpgtw", MX, EM },
943 { "pcmpgtd", MX, EM },
944 { "packuswb", MX, EM },
945 /* 68 */
946 { "punpckhbw", MX, EM },
947 { "punpckhwd", MX, EM },
948 { "punpckhdq", MX, EM },
949 { "packssdw", MX, EM },
950 { "(bad)" }, { "(bad)" },
951 { "movd", MX, Ev },
952 { "movq", MX, EM },
953 /* 70 */
954 { "(bad)" },
955 { GRP10 },
956 { GRP11 },
957 { GRP12 },
958 { "pcmpeqb", MX, EM },
959 { "pcmpeqw", MX, EM },
960 { "pcmpeqd", MX, EM },
961 { "emms" },
962 /* 78 */
963 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
964 { "(bad)" }, { "(bad)" },
965 { "movd", Ev, MX },
966 { "movq", EM, MX },
967 /* 80 */
968 { "jo", Jv },
969 { "jno", Jv },
970 { "jb", Jv },
971 { "jae", Jv },
972 { "je", Jv },
973 { "jne", Jv },
974 { "jbe", Jv },
975 { "ja", Jv },
976 /* 88 */
977 { "js", Jv },
978 { "jns", Jv },
979 { "jp", Jv },
980 { "jnp", Jv },
981 { "jl", Jv },
982 { "jge", Jv },
983 { "jle", Jv },
984 { "jg", Jv },
985 /* 90 */
986 { "seto", Eb },
987 { "setno", Eb },
988 { "setb", Eb },
989 { "setae", Eb },
990 { "sete", Eb },
991 { "setne", Eb },
992 { "setbe", Eb },
993 { "seta", Eb },
994 /* 98 */
995 { "sets", Eb },
996 { "setns", Eb },
997 { "setp", Eb },
998 { "setnp", Eb },
999 { "setl", Eb },
1000 { "setge", Eb },
1001 { "setle", Eb },
1002 { "setg", Eb },
1003 /* a0 */
1004 { "pushP", fs },
1005 { "popP", fs },
1006 { "cpuid" },
1007 { "btS", Ev, Gv },
1008 { "shldS", Ev, Gv, Ib },
1009 { "shldS", Ev, Gv, CL },
1010 { "(bad)" },
1011 { "(bad)" },
1012 /* a8 */
1013 { "pushP", gs },
1014 { "popP", gs },
1015 { "rsm" },
1016 { "btsS", Ev, Gv },
1017 { "shrdS", Ev, Gv, Ib },
1018 { "shrdS", Ev, Gv, CL },
1019 { GRP13 },
1020 { "imulS", Gv, Ev },
1021 /* b0 */
1022 { "cmpxchgB", Eb, Gb },
1023 { "cmpxchgS", Ev, Gv },
1024 { "lssS", Gv, Mp }, /* 386 lists only Mp */
1025 { "btrS", Ev, Gv },
1026 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
1027 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
1028 { "movzbR", Gv, Eb },
1029 { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
1030 /* b8 */
1031 { "(bad)" },
1032 { "ud2b" },
1033 { GRP8 },
1034 { "btcS", Ev, Gv },
1035 { "bsfS", Gv, Ev },
1036 { "bsrS", Gv, Ev },
1037 { "movsbR", Gv, Eb },
1038 { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
1039 /* c0 */
1040 { "xaddB", Eb, Gb },
1041 { "xaddS", Ev, Gv },
1042 { "(bad)" },
1043 { "(bad)" },
1044 { "(bad)" },
1045 { "(bad)" },
1046 { "(bad)" },
1047 { GRP9 },
1048 /* c8 */
1049 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1050 { "bswap", eCX },
1051 { "bswap", eDX },
1052 { "bswap", eBX },
1053 { "bswap", eSP },
1054 { "bswap", eBP },
1055 { "bswap", eSI },
1056 { "bswap", eDI },
1057 /* d0 */
1058 { "(bad)" },
1059 { "psrlw", MX, EM },
1060 { "psrld", MX, EM },
1061 { "psrlq", MX, EM },
1062 { "(bad)" },
1063 { "pmullw", MX, EM },
1064 { "(bad)" }, { "(bad)" },
1065 /* d8 */
1066 { "psubusb", MX, EM },
1067 { "psubusw", MX, EM },
1068 { "(bad)" },
1069 { "pand", MX, EM },
1070 { "paddusb", MX, EM },
1071 { "paddusw", MX, EM },
1072 { "(bad)" },
1073 { "pandn", MX, EM },
1074 /* e0 */
1075 { "(bad)" },
1076 { "psraw", MX, EM },
1077 { "psrad", MX, EM },
1078 { "(bad)" },
1079 { "(bad)" },
1080 { "pmulhw", MX, EM },
1081 { "(bad)" }, { "(bad)" },
1082 /* e8 */
1083 { "psubsb", MX, EM },
1084 { "psubsw", MX, EM },
1085 { "(bad)" },
1086 { "por", MX, EM },
1087 { "paddsb", MX, EM },
1088 { "paddsw", MX, EM },
1089 { "(bad)" },
1090 { "pxor", MX, EM },
1091 /* f0 */
1092 { "(bad)" },
1093 { "psllw", MX, EM },
1094 { "pslld", MX, EM },
1095 { "psllq", MX, EM },
1096 { "(bad)" },
1097 { "pmaddwd", MX, EM },
1098 { "(bad)" }, { "(bad)" },
1099 /* f8 */
1100 { "psubb", MX, EM },
1101 { "psubw", MX, EM },
1102 { "psubd", MX, EM },
1103 { "(bad)" },
1104 { "paddb", MX, EM },
1105 { "paddw", MX, EM },
1106 { "paddd", MX, EM },
1107 { "(bad)" }
1110 static struct dis386 dis386_twobyte_intel[] = {
1111 /* 00 */
1112 { GRP6 },
1113 { GRP7 },
1114 { "larS", Gv, Ew },
1115 { "lslS", Gv, Ew },
1116 { "(bad)" },
1117 { "(bad)" },
1118 { "clts" },
1119 { "(bad)" },
1120 /* 08 */
1121 { "invd" },
1122 { "wbinvd" },
1123 { "(bad)" },
1124 { "ud2a" },
1125 { "(bad)" },
1126 { GRP14 },
1127 { "femms" },
1128 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1129 /* 10 */
1130 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1131 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1132 /* 18 */
1133 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1134 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1135 /* 20 */
1136 /* these are all backward in appendix A of the intel book */
1137 { "movL", Rd, Cd },
1138 { "movL", Rd, Dd },
1139 { "movL", Cd, Rd },
1140 { "movL", Dd, Rd },
1141 { "movL", Rd, Td },
1142 { "(bad)" },
1143 { "movL", Td, Rd },
1144 { "(bad)" },
1145 /* 28 */
1146 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1147 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1148 /* 30 */
1149 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1150 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1151 /* 38 */
1152 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1153 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1154 /* 40 */
1155 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
1156 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
1157 /* 48 */
1158 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
1159 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
1160 /* 50 */
1161 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1162 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1163 /* 58 */
1164 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1165 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1166 /* 60 */
1167 { "punpcklbw", MX, EM },
1168 { "punpcklwd", MX, EM },
1169 { "punpckldq", MX, EM },
1170 { "packsswb", MX, EM },
1171 { "pcmpgtb", MX, EM },
1172 { "pcmpgtw", MX, EM },
1173 { "pcmpgtd", MX, EM },
1174 { "packuswb", MX, EM },
1175 /* 68 */
1176 { "punpckhbw", MX, EM },
1177 { "punpckhwd", MX, EM },
1178 { "punpckhdq", MX, EM },
1179 { "packssdw", MX, EM },
1180 { "(bad)" }, { "(bad)" },
1181 { "movd", MX, Ev },
1182 { "movq", MX, EM },
1183 /* 70 */
1184 { "(bad)" },
1185 { GRP10 },
1186 { GRP11 },
1187 { GRP12 },
1188 { "pcmpeqb", MX, EM },
1189 { "pcmpeqw", MX, EM },
1190 { "pcmpeqd", MX, EM },
1191 { "emms" },
1192 /* 78 */
1193 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1194 { "(bad)" }, { "(bad)" },
1195 { "movd", Ev, MX },
1196 { "movq", EM, MX },
1197 /* 80 */
1198 { "jo", Jv },
1199 { "jno", Jv },
1200 { "jb", Jv },
1201 { "jae", Jv },
1202 { "je", Jv },
1203 { "jne", Jv },
1204 { "jbe", Jv },
1205 { "ja", Jv },
1206 /* 88 */
1207 { "js", Jv },
1208 { "jns", Jv },
1209 { "jp", Jv },
1210 { "jnp", Jv },
1211 { "jl", Jv },
1212 { "jge", Jv },
1213 { "jle", Jv },
1214 { "jg", Jv },
1215 /* 90 */
1216 { "seto", Eb },
1217 { "setno", Eb },
1218 { "setb", Eb },
1219 { "setae", Eb },
1220 { "sete", Eb },
1221 { "setne", Eb },
1222 { "setbe", Eb },
1223 { "seta", Eb },
1224 /* 98 */
1225 { "sets", Eb },
1226 { "setns", Eb },
1227 { "setp", Eb },
1228 { "setnp", Eb },
1229 { "setl", Eb },
1230 { "setge", Eb },
1231 { "setle", Eb },
1232 { "setg", Eb },
1233 /* a0 */
1234 { "pushP", fs },
1235 { "popP", fs },
1236 { "cpuid" },
1237 { "btS", Ev, Gv },
1238 { "shldS", Ev, Gv, Ib },
1239 { "shldS", Ev, Gv, CL },
1240 { "(bad)" },
1241 { "(bad)" },
1242 /* a8 */
1243 { "pushP", gs },
1244 { "popP", gs },
1245 { "rsm" },
1246 { "btsS", Ev, Gv },
1247 { "shrdS", Ev, Gv, Ib },
1248 { "shrdS", Ev, Gv, CL },
1249 { GRP13 },
1250 { "imulS", Gv, Ev },
1251 /* b0 */
1252 { "cmpxchgB", Eb, Gb },
1253 { "cmpxchgS", Ev, Gv },
1254 { "lssS", Gv, Mp }, /* 386 lists only Mp */
1255 { "btrS", Ev, Gv },
1256 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
1257 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
1258 { "movzx", Gv, Eb },
1259 { "movzx", Gv, Ew },
1260 /* b8 */
1261 { "(bad)" },
1262 { "ud2b" },
1263 { GRP8 },
1264 { "btcS", Ev, Gv },
1265 { "bsfS", Gv, Ev },
1266 { "bsrS", Gv, Ev },
1267 { "movsx", Gv, Eb },
1268 { "movsx", Gv, Ew },
1269 /* c0 */
1270 { "xaddB", Eb, Gb },
1271 { "xaddS", Ev, Gv },
1272 { "(bad)" },
1273 { "(bad)" },
1274 { "(bad)" },
1275 { "(bad)" },
1276 { "(bad)" },
1277 { GRP9 },
1278 /* c8 */
1279 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1280 { "bswap", eCX },
1281 { "bswap", eDX },
1282 { "bswap", eBX },
1283 { "bswap", eSP },
1284 { "bswap", eBP },
1285 { "bswap", eSI },
1286 { "bswap", eDI },
1287 /* d0 */
1288 { "(bad)" },
1289 { "psrlw", MX, EM },
1290 { "psrld", MX, EM },
1291 { "psrlq", MX, EM },
1292 { "(bad)" },
1293 { "pmullw", MX, EM },
1294 { "(bad)" }, { "(bad)" },
1295 /* d8 */
1296 { "psubusb", MX, EM },
1297 { "psubusw", MX, EM },
1298 { "(bad)" },
1299 { "pand", MX, EM },
1300 { "paddusb", MX, EM },
1301 { "paddusw", MX, EM },
1302 { "(bad)" },
1303 { "pandn", MX, EM },
1304 /* e0 */
1305 { "(bad)" },
1306 { "psraw", MX, EM },
1307 { "psrad", MX, EM },
1308 { "(bad)" },
1309 { "(bad)" },
1310 { "pmulhw", MX, EM },
1311 { "(bad)" }, { "(bad)" },
1312 /* e8 */
1313 { "psubsb", MX, EM },
1314 { "psubsw", MX, EM },
1315 { "(bad)" },
1316 { "por", MX, EM },
1317 { "paddsb", MX, EM },
1318 { "paddsw", MX, EM },
1319 { "(bad)" },
1320 { "pxor", MX, EM },
1321 /* f0 */
1322 { "(bad)" },
1323 { "psllw", MX, EM },
1324 { "pslld", MX, EM },
1325 { "psllq", MX, EM },
1326 { "(bad)" },
1327 { "pmaddwd", MX, EM },
1328 { "(bad)" }, { "(bad)" },
1329 /* f8 */
1330 { "psubb", MX, EM },
1331 { "psubw", MX, EM },
1332 { "psubd", MX, EM },
1333 { "(bad)" },
1334 { "paddb", MX, EM },
1335 { "paddw", MX, EM },
1336 { "paddd", MX, EM },
1337 { "(bad)" }
1340 static const unsigned char onebyte_has_modrm[256] = {
1341 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1342 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1343 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1344 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1345 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1347 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
1348 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1349 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1350 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1351 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1352 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1353 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
1354 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1355 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1356 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
1359 static const unsigned char twobyte_has_modrm[256] = {
1360 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1361 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1362 /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
1363 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1364 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1365 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1366 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1367 /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1368 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1369 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1370 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1371 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1372 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1373 /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
1374 /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
1375 /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
1378 static char obuf[100];
1379 static char *obufp;
1380 static char scratchbuf[100];
1381 static unsigned char *start_codep;
1382 static unsigned char *insn_codep;
1383 static unsigned char *codep;
1384 static disassemble_info *the_info;
1385 static int mod;
1386 static int rm;
1387 static int reg;
1388 static void oappend PARAMS ((char *s));
1390 static char *names32[]={
1391 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1393 static char *names16[] = {
1394 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1396 static char *names8[] = {
1397 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1399 static char *names_seg[] = {
1400 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1402 static char *index16[] = {
1403 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1406 static struct dis386 grps[][8] = {
1407 /* GRP1b */
1409 { "addA", Eb, Ib },
1410 { "orA", Eb, Ib },
1411 { "adcA", Eb, Ib },
1412 { "sbbA", Eb, Ib },
1413 { "andA", Eb, Ib },
1414 { "subA", Eb, Ib },
1415 { "xorA", Eb, Ib },
1416 { "cmpA", Eb, Ib }
1418 /* GRP1S */
1420 { "addQ", Ev, Iv },
1421 { "orQ", Ev, Iv },
1422 { "adcQ", Ev, Iv },
1423 { "sbbQ", Ev, Iv },
1424 { "andQ", Ev, Iv },
1425 { "subQ", Ev, Iv },
1426 { "xorQ", Ev, Iv },
1427 { "cmpQ", Ev, Iv }
1429 /* GRP1Ss */
1431 { "addQ", Ev, sIb },
1432 { "orQ", Ev, sIb },
1433 { "adcQ", Ev, sIb },
1434 { "sbbQ", Ev, sIb },
1435 { "andQ", Ev, sIb },
1436 { "subQ", Ev, sIb },
1437 { "xorQ", Ev, sIb },
1438 { "cmpQ", Ev, sIb }
1440 /* GRP2b */
1442 { "rolA", Eb, Ib },
1443 { "rorA", Eb, Ib },
1444 { "rclA", Eb, Ib },
1445 { "rcrA", Eb, Ib },
1446 { "shlA", Eb, Ib },
1447 { "shrA", Eb, Ib },
1448 { "(bad)" },
1449 { "sarA", Eb, Ib },
1451 /* GRP2S */
1453 { "rolQ", Ev, Ib },
1454 { "rorQ", Ev, Ib },
1455 { "rclQ", Ev, Ib },
1456 { "rcrQ", Ev, Ib },
1457 { "shlQ", Ev, Ib },
1458 { "shrQ", Ev, Ib },
1459 { "(bad)" },
1460 { "sarQ", Ev, Ib },
1462 /* GRP2b_one */
1464 { "rolA", Eb },
1465 { "rorA", Eb },
1466 { "rclA", Eb },
1467 { "rcrA", Eb },
1468 { "shlA", Eb },
1469 { "shrA", Eb },
1470 { "(bad)" },
1471 { "sarA", Eb },
1473 /* GRP2S_one */
1475 { "rolQ", Ev },
1476 { "rorQ", Ev },
1477 { "rclQ", Ev },
1478 { "rcrQ", Ev },
1479 { "shlQ", Ev },
1480 { "shrQ", Ev },
1481 { "(bad)" },
1482 { "sarQ", Ev },
1484 /* GRP2b_cl */
1486 { "rolA", Eb, CL },
1487 { "rorA", Eb, CL },
1488 { "rclA", Eb, CL },
1489 { "rcrA", Eb, CL },
1490 { "shlA", Eb, CL },
1491 { "shrA", Eb, CL },
1492 { "(bad)" },
1493 { "sarA", Eb, CL },
1495 /* GRP2S_cl */
1497 { "rolQ", Ev, CL },
1498 { "rorQ", Ev, CL },
1499 { "rclQ", Ev, CL },
1500 { "rcrQ", Ev, CL },
1501 { "shlQ", Ev, CL },
1502 { "shrQ", Ev, CL },
1503 { "(bad)" },
1504 { "sarQ", Ev, CL }
1506 /* GRP3b */
1508 { "testA", Eb, Ib },
1509 { "(bad)", Eb },
1510 { "notA", Eb },
1511 { "negA", Eb },
1512 { "mulB", AL, Eb },
1513 { "imulB", AL, Eb },
1514 { "divB", AL, Eb },
1515 { "idivB", AL, Eb }
1517 /* GRP3S */
1519 { "testQ", Ev, Iv },
1520 { "(bad)" },
1521 { "notQ", Ev },
1522 { "negQ", Ev },
1523 { "mulS", eAX, Ev },
1524 { "imulS", eAX, Ev },
1525 { "divS", eAX, Ev },
1526 { "idivS", eAX, Ev },
1528 /* GRP4 */
1530 { "incA", Eb },
1531 { "decA", Eb },
1532 { "(bad)" },
1533 { "(bad)" },
1534 { "(bad)" },
1535 { "(bad)" },
1536 { "(bad)" },
1537 { "(bad)" },
1539 /* GRP5 */
1541 { "incQ", Ev },
1542 { "decQ", Ev },
1543 { "callP", indirEv },
1544 { "callP", indirEv },
1545 { "jmpP", indirEv },
1546 { "ljmpP", indirEv },
1547 { "pushQ", Ev },
1548 { "(bad)" },
1550 /* GRP6 */
1552 { "sldt", Ew },
1553 { "str", Ew },
1554 { "lldt", Ew },
1555 { "ltr", Ew },
1556 { "verr", Ew },
1557 { "verw", Ew },
1558 { "(bad)" },
1559 { "(bad)" }
1561 /* GRP7 */
1563 { "sgdt", Ew },
1564 { "sidt", Ew },
1565 { "lgdt", Ew },
1566 { "lidt", Ew },
1567 { "smsw", Ew },
1568 { "(bad)" },
1569 { "lmsw", Ew },
1570 { "invlpg", Ew },
1572 /* GRP8 */
1574 { "(bad)" },
1575 { "(bad)" },
1576 { "(bad)" },
1577 { "(bad)" },
1578 { "btQ", Ev, Ib },
1579 { "btsQ", Ev, Ib },
1580 { "btrQ", Ev, Ib },
1581 { "btcQ", Ev, Ib },
1583 /* GRP9 */
1585 { "(bad)" },
1586 { "cmpxchg8b", Ev },
1587 { "(bad)" },
1588 { "(bad)" },
1589 { "(bad)" },
1590 { "(bad)" },
1591 { "(bad)" },
1592 { "(bad)" },
1594 /* GRP10 */
1596 { "(bad)" },
1597 { "(bad)" },
1598 { "psrlw", MS, Ib },
1599 { "(bad)" },
1600 { "psraw", MS, Ib },
1601 { "(bad)" },
1602 { "psllw", MS, Ib },
1603 { "(bad)" },
1605 /* GRP11 */
1607 { "(bad)" },
1608 { "(bad)" },
1609 { "psrld", MS, Ib },
1610 { "(bad)" },
1611 { "psrad", MS, Ib },
1612 { "(bad)" },
1613 { "pslld", MS, Ib },
1614 { "(bad)" },
1616 /* GRP12 */
1618 { "(bad)" },
1619 { "(bad)" },
1620 { "psrlq", MS, Ib },
1621 { "(bad)" },
1622 { "(bad)" },
1623 { "(bad)" },
1624 { "psllq", MS, Ib },
1625 { "(bad)" },
1627 /* GRP13 */
1629 { "fxsave", Ev },
1630 { "fxrstor", Ev },
1631 { "(bad)" },
1632 { "(bad)" },
1633 { "(bad)" },
1634 { "(bad)" },
1635 { "(bad)" },
1636 { "(bad)" },
1638 /* GRP14 */
1640 { "prefetch", Eb },
1641 { "prefetchw", Eb },
1642 { "(bad)" },
1643 { "(bad)" },
1644 { "(bad)" },
1645 { "(bad)" },
1646 { "(bad)" },
1647 { "(bad)" },
1652 #define PREFIX_REPZ 1
1653 #define PREFIX_REPNZ 2
1654 #define PREFIX_LOCK 4
1655 #define PREFIX_CS 8
1656 #define PREFIX_SS 0x10
1657 #define PREFIX_DS 0x20
1658 #define PREFIX_ES 0x40
1659 #define PREFIX_FS 0x80
1660 #define PREFIX_GS 0x100
1661 #define PREFIX_DATA 0x200
1662 #define PREFIX_ADDR 0x400
1663 #define PREFIX_FWAIT 0x800
1665 static int prefixes;
1667 static void
1668 ckprefix ()
1670 prefixes = 0;
1671 while (1)
1673 FETCH_DATA (the_info, codep + 1);
1674 switch (*codep)
1676 case 0xf3:
1677 prefixes |= PREFIX_REPZ;
1678 break;
1679 case 0xf2:
1680 prefixes |= PREFIX_REPNZ;
1681 break;
1682 case 0xf0:
1683 prefixes |= PREFIX_LOCK;
1684 break;
1685 case 0x2e:
1686 prefixes |= PREFIX_CS;
1687 break;
1688 case 0x36:
1689 prefixes |= PREFIX_SS;
1690 break;
1691 case 0x3e:
1692 prefixes |= PREFIX_DS;
1693 break;
1694 case 0x26:
1695 prefixes |= PREFIX_ES;
1696 break;
1697 case 0x64:
1698 prefixes |= PREFIX_FS;
1699 break;
1700 case 0x65:
1701 prefixes |= PREFIX_GS;
1702 break;
1703 case 0x66:
1704 prefixes |= PREFIX_DATA;
1705 break;
1706 case 0x67:
1707 prefixes |= PREFIX_ADDR;
1708 break;
1709 case 0x9b:
1710 /* fwait is really an instruction. If there are prefixes
1711 before the fwait, they belong to the fwait, *not* to the
1712 following instruction. */
1713 if (prefixes)
1715 prefixes |= PREFIX_FWAIT;
1716 codep++;
1717 return;
1719 prefixes = PREFIX_FWAIT;
1720 break;
1721 default:
1722 return;
1724 codep++;
1728 static char op1out[100], op2out[100], op3out[100];
1729 static int op_ad, op_index[3];
1730 static unsigned int op_address[3];
1731 static unsigned int start_pc;
1735 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1736 * (see topic "Redundant prefixes" in the "Differences from 8086"
1737 * section of the "Virtual 8086 Mode" chapter.)
1738 * 'pc' should be the address of this instruction, it will
1739 * be used to print the target address if this is a relative jump or call
1740 * The function returns the length of this instruction in bytes.
1743 static int print_insn_x86
1744 PARAMS ((bfd_vma pc, disassemble_info *info, int sizeflag));
1745 static int print_insn_i386
1746 PARAMS ((bfd_vma pc, disassemble_info *info));
1748 static char intel_syntax;
1749 static char open_char;
1750 static char close_char;
1751 static char separator_char;
1752 static char scale_char;
1755 print_insn_i386_att (pc, info)
1756 bfd_vma pc;
1757 disassemble_info *info;
1759 intel_syntax = 0;
1760 open_char = '(';
1761 close_char = ')';
1762 separator_char = ',';
1763 scale_char = ',';
1765 return print_insn_i386 (pc, info);
1769 print_insn_i386_intel (pc, info)
1770 bfd_vma pc;
1771 disassemble_info *info;
1773 intel_syntax = 1;
1774 open_char = '[';
1775 close_char = ']';
1776 separator_char = '+';
1777 scale_char = '*';
1779 return print_insn_i386 (pc, info);
1782 static int
1783 print_insn_i386 (pc, info)
1784 bfd_vma pc;
1785 disassemble_info *info;
1787 int flags;
1788 if (info->mach == bfd_mach_i386_i386
1789 || info->mach == bfd_mach_i386_i386_intel_syntax)
1790 flags = AFLAG|DFLAG;
1791 else if (info->mach == bfd_mach_i386_i8086)
1792 flags = 0;
1793 else
1794 abort ();
1795 return print_insn_x86 (pc, info, flags);
1798 static int
1799 print_insn_x86 (pc, info, sizeflag)
1800 bfd_vma pc;
1801 disassemble_info *info;
1802 int sizeflag;
1804 struct dis386 *dp;
1805 int i;
1806 int two_source_ops;
1807 char *first, *second, *third;
1808 int needcomma;
1809 unsigned char need_modrm;
1811 struct dis_private priv;
1812 bfd_byte *inbuf = priv.the_buffer;
1814 /* The output looks better if we put 5 bytes on a line, since that
1815 puts long word instructions on a single line. */
1816 info->bytes_per_line = 5;
1818 info->private_data = (PTR) &priv;
1819 priv.max_fetched = priv.the_buffer;
1820 priv.insn_start = pc;
1821 if (setjmp (priv.bailout) != 0)
1822 /* Error return. */
1823 return -1;
1825 obuf[0] = 0;
1826 op1out[0] = 0;
1827 op2out[0] = 0;
1828 op3out[0] = 0;
1830 op_index[0] = op_index[1] = op_index[2] = -1;
1832 the_info = info;
1833 start_pc = pc;
1834 start_codep = inbuf;
1835 codep = inbuf;
1837 ckprefix ();
1839 insn_codep = codep;
1841 FETCH_DATA (info, codep + 1);
1842 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
1844 obufp = obuf;
1846 if ((prefixes & PREFIX_FWAIT)
1847 && ((*codep < 0xd8) || (*codep > 0xdf)))
1849 /* fwait not followed by floating point instruction. */
1850 (*info->fprintf_func) (info->stream, "fwait");
1851 /* There may be other prefixes. Skip any before the fwait. */
1852 return codep - inbuf;
1855 if (prefixes & PREFIX_REPZ)
1856 oappend ("repz ");
1857 if (prefixes & PREFIX_REPNZ)
1858 oappend ("repnz ");
1859 if (prefixes & PREFIX_LOCK)
1860 oappend ("lock ");
1862 if (prefixes & PREFIX_DATA)
1863 sizeflag ^= DFLAG;
1865 if (prefixes & PREFIX_ADDR)
1867 sizeflag ^= AFLAG;
1868 if (sizeflag & AFLAG)
1869 oappend ("addr32 ");
1870 else
1871 oappend ("addr16 ");
1874 if (*codep == 0x0f)
1876 FETCH_DATA (info, codep + 2);
1877 if (intel_syntax)
1878 dp = &dis386_twobyte_intel[*++codep];
1879 else
1880 dp = &dis386_twobyte_att[*++codep];
1881 need_modrm = twobyte_has_modrm[*codep];
1883 else
1885 if (intel_syntax)
1886 dp = &dis386_intel[*codep];
1887 else
1888 dp = &dis386_att[*codep];
1889 need_modrm = onebyte_has_modrm[*codep];
1891 codep++;
1893 if (need_modrm)
1895 FETCH_DATA (info, codep + 1);
1896 mod = (*codep >> 6) & 3;
1897 reg = (*codep >> 3) & 7;
1898 rm = *codep & 7;
1901 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1903 dofloat (sizeflag);
1905 else
1907 if (dp->name == NULL)
1908 dp = &grps[dp->bytemode1][reg];
1910 putop (dp->name, sizeflag);
1912 obufp = op1out;
1913 op_ad = 2;
1914 if (dp->op1)
1915 (*dp->op1)(dp->bytemode1, sizeflag);
1917 obufp = op2out;
1918 op_ad = 1;
1919 if (dp->op2)
1920 (*dp->op2)(dp->bytemode2, sizeflag);
1922 obufp = op3out;
1923 op_ad = 0;
1924 if (dp->op3)
1925 (*dp->op3)(dp->bytemode3, sizeflag);
1928 obufp = obuf + strlen (obuf);
1929 for (i = strlen (obuf); i < 6; i++)
1930 oappend (" ");
1931 oappend (" ");
1932 (*info->fprintf_func) (info->stream, "%s", obuf);
1934 /* The enter and bound instructions are printed with operands in the same
1935 order as the intel book; everything else is printed in reverse order. */
1936 if (intel_syntax || two_source_ops)
1938 first = op1out;
1939 second = op2out;
1940 third = op3out;
1941 op_ad = op_index[0];
1942 op_index[0] = op_index[2];
1943 op_index[2] = op_ad;
1945 else
1947 first = op3out;
1948 second = op2out;
1949 third = op1out;
1951 needcomma = 0;
1952 if (*first)
1954 if (op_index[0] != -1)
1955 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
1956 else
1957 (*info->fprintf_func) (info->stream, "%s", first);
1958 needcomma = 1;
1960 if (*second)
1962 if (needcomma)
1963 (*info->fprintf_func) (info->stream, ",");
1964 if (op_index[1] != -1)
1965 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
1966 else
1967 (*info->fprintf_func) (info->stream, "%s", second);
1968 needcomma = 1;
1970 if (*third)
1972 if (needcomma)
1973 (*info->fprintf_func) (info->stream, ",");
1974 if (op_index[2] != -1)
1975 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
1976 else
1977 (*info->fprintf_func) (info->stream, "%s", third);
1979 return codep - inbuf;
1982 static char *float_mem_att[] = {
1983 /* d8 */
1984 "fadds",
1985 "fmuls",
1986 "fcoms",
1987 "fcomps",
1988 "fsubs",
1989 "fsubrs",
1990 "fdivs",
1991 "fdivrs",
1992 /* d9 */
1993 "flds",
1994 "(bad)",
1995 "fsts",
1996 "fstps",
1997 "fldenv",
1998 "fldcw",
1999 "fNstenv",
2000 "fNstcw",
2001 /* da */
2002 "fiaddl",
2003 "fimull",
2004 "ficoml",
2005 "ficompl",
2006 "fisubl",
2007 "fisubrl",
2008 "fidivl",
2009 "fidivrl",
2010 /* db */
2011 "fildl",
2012 "(bad)",
2013 "fistl",
2014 "fistpl",
2015 "(bad)",
2016 "fldt",
2017 "(bad)",
2018 "fstpt",
2019 /* dc */
2020 "faddl",
2021 "fmull",
2022 "fcoml",
2023 "fcompl",
2024 "fsubl",
2025 "fsubrl",
2026 "fdivl",
2027 "fdivrl",
2028 /* dd */
2029 "fldl",
2030 "(bad)",
2031 "fstl",
2032 "fstpl",
2033 "frstor",
2034 "(bad)",
2035 "fNsave",
2036 "fNstsw",
2037 /* de */
2038 "fiadd",
2039 "fimul",
2040 "ficom",
2041 "ficomp",
2042 "fisub",
2043 "fisubr",
2044 "fidiv",
2045 "fidivr",
2046 /* df */
2047 "fild",
2048 "(bad)",
2049 "fist",
2050 "fistp",
2051 "fbld",
2052 "fildll",
2053 "fbstp",
2054 "fistpll",
2057 static char *float_mem_intel[] = {
2058 /* d8 */
2059 "fadd",
2060 "fmul",
2061 "fcom",
2062 "fcomp",
2063 "fsub",
2064 "fsubr",
2065 "fdiv",
2066 "fdivr",
2067 /* d9 */
2068 "fld",
2069 "(bad)",
2070 "fst",
2071 "fstp",
2072 "fldenv",
2073 "fldcw",
2074 "fNstenv",
2075 "fNstcw",
2076 /* da */
2077 "fiadd",
2078 "fimul",
2079 "ficom",
2080 "ficomp",
2081 "fisub",
2082 "fisubr",
2083 "fidiv",
2084 "fidivr",
2085 /* db */
2086 "fild",
2087 "(bad)",
2088 "fist",
2089 "fistp",
2090 "(bad)",
2091 "fld",
2092 "(bad)",
2093 "fstp",
2094 /* dc */
2095 "fadd",
2096 "fmul",
2097 "fcom",
2098 "fcomp",
2099 "fsub",
2100 "fsubr",
2101 "fdiv",
2102 "fdivr",
2103 /* dd */
2104 "fld",
2105 "(bad)",
2106 "fst",
2107 "fstp",
2108 "frstor",
2109 "(bad)",
2110 "fNsave",
2111 "fNstsw",
2112 /* de */
2113 "fiadd",
2114 "fimul",
2115 "ficom",
2116 "ficomp",
2117 "fisub",
2118 "fisubr",
2119 "fidiv",
2120 "fidivr",
2121 /* df */
2122 "fild",
2123 "(bad)",
2124 "fist",
2125 "fistp",
2126 "fbld",
2127 "fild",
2128 "fbstp",
2129 "fistpll",
2132 #define ST OP_ST, 0
2133 #define STi OP_STi, 0
2135 #define FGRPd9_2 NULL, NULL, 0
2136 #define FGRPd9_4 NULL, NULL, 1
2137 #define FGRPd9_5 NULL, NULL, 2
2138 #define FGRPd9_6 NULL, NULL, 3
2139 #define FGRPd9_7 NULL, NULL, 4
2140 #define FGRPda_5 NULL, NULL, 5
2141 #define FGRPdb_4 NULL, NULL, 6
2142 #define FGRPde_3 NULL, NULL, 7
2143 #define FGRPdf_4 NULL, NULL, 8
2145 static struct dis386 float_reg[][8] = {
2146 /* d8 */
2148 { "fadd", ST, STi },
2149 { "fmul", ST, STi },
2150 { "fcom", STi },
2151 { "fcomp", STi },
2152 { "fsub", ST, STi },
2153 { "fsubr", ST, STi },
2154 { "fdiv", ST, STi },
2155 { "fdivr", ST, STi },
2157 /* d9 */
2159 { "fld", STi },
2160 { "fxch", STi },
2161 { FGRPd9_2 },
2162 { "(bad)" },
2163 { FGRPd9_4 },
2164 { FGRPd9_5 },
2165 { FGRPd9_6 },
2166 { FGRPd9_7 },
2168 /* da */
2170 { "fcmovb", ST, STi },
2171 { "fcmove", ST, STi },
2172 { "fcmovbe",ST, STi },
2173 { "fcmovu", ST, STi },
2174 { "(bad)" },
2175 { FGRPda_5 },
2176 { "(bad)" },
2177 { "(bad)" },
2179 /* db */
2181 { "fcmovnb",ST, STi },
2182 { "fcmovne",ST, STi },
2183 { "fcmovnbe",ST, STi },
2184 { "fcmovnu",ST, STi },
2185 { FGRPdb_4 },
2186 { "fucomi", ST, STi },
2187 { "fcomi", ST, STi },
2188 { "(bad)" },
2190 /* dc */
2192 { "fadd", STi, ST },
2193 { "fmul", STi, ST },
2194 { "(bad)" },
2195 { "(bad)" },
2196 #if UNIXWARE_COMPAT
2197 { "fsub", STi, ST },
2198 { "fsubr", STi, ST },
2199 { "fdiv", STi, ST },
2200 { "fdivr", STi, ST },
2201 #else
2202 { "fsubr", STi, ST },
2203 { "fsub", STi, ST },
2204 { "fdivr", STi, ST },
2205 { "fdiv", STi, ST },
2206 #endif
2208 /* dd */
2210 { "ffree", STi },
2211 { "(bad)" },
2212 { "fst", STi },
2213 { "fstp", STi },
2214 { "fucom", STi },
2215 { "fucomp", STi },
2216 { "(bad)" },
2217 { "(bad)" },
2219 /* de */
2221 { "faddp", STi, ST },
2222 { "fmulp", STi, ST },
2223 { "(bad)" },
2224 { FGRPde_3 },
2225 #if UNIXWARE_COMPAT
2226 { "fsubp", STi, ST },
2227 { "fsubrp", STi, ST },
2228 { "fdivp", STi, ST },
2229 { "fdivrp", STi, ST },
2230 #else
2231 { "fsubrp", STi, ST },
2232 { "fsubp", STi, ST },
2233 { "fdivrp", STi, ST },
2234 { "fdivp", STi, ST },
2235 #endif
2237 /* df */
2239 { "(bad)" },
2240 { "(bad)" },
2241 { "(bad)" },
2242 { "(bad)" },
2243 { FGRPdf_4 },
2244 { "fucomip",ST, STi },
2245 { "fcomip", ST, STi },
2246 { "(bad)" },
2251 static char *fgrps[][8] = {
2252 /* d9_2 0 */
2254 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2257 /* d9_4 1 */
2259 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2262 /* d9_5 2 */
2264 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2267 /* d9_6 3 */
2269 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2272 /* d9_7 4 */
2274 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2277 /* da_5 5 */
2279 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2282 /* db_4 6 */
2284 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2285 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2288 /* de_3 7 */
2290 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2293 /* df_4 8 */
2295 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2299 static void
2300 dofloat (sizeflag)
2301 int sizeflag;
2303 struct dis386 *dp;
2304 unsigned char floatop;
2306 floatop = codep[-1];
2308 if (mod != 3)
2310 if (intel_syntax)
2311 putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2312 else
2313 putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2314 obufp = op1out;
2315 if (floatop == 0xdb)
2316 OP_E (x_mode, sizeflag);
2317 else if (floatop == 0xdd)
2318 OP_E (d_mode, sizeflag);
2319 else
2320 OP_E (v_mode, sizeflag);
2321 return;
2323 codep++;
2325 dp = &float_reg[floatop - 0xd8][reg];
2326 if (dp->name == NULL)
2328 putop (fgrps[dp->bytemode1][rm], sizeflag);
2330 /* instruction fnstsw is only one with strange arg */
2331 if (floatop == 0xdf && codep[-1] == 0xe0)
2332 strcpy (op1out, names16[0]);
2334 else
2336 putop (dp->name, sizeflag);
2338 obufp = op1out;
2339 if (dp->op1)
2340 (*dp->op1)(dp->bytemode1, sizeflag);
2341 obufp = op2out;
2342 if (dp->op2)
2343 (*dp->op2)(dp->bytemode2, sizeflag);
2347 /* ARGSUSED */
2348 static void
2349 OP_ST (ignore, sizeflag)
2350 int ignore;
2351 int sizeflag;
2353 oappend ("%st");
2356 /* ARGSUSED */
2357 static void
2358 OP_STi (ignore, sizeflag)
2359 int ignore;
2360 int sizeflag;
2362 sprintf (scratchbuf, "%%st(%d)", rm);
2363 oappend (scratchbuf);
2367 /* capital letters in template are macros */
2368 static void
2369 putop (template, sizeflag)
2370 char *template;
2371 int sizeflag;
2373 char *p;
2375 for (p = template; *p; p++)
2377 switch (*p)
2379 default:
2380 *obufp++ = *p;
2381 break;
2382 case 'A':
2383 if (intel_syntax)
2384 break;
2385 if (mod != 3
2386 #ifdef SUFFIX_ALWAYS
2387 || (sizeflag & SUFFIX_ALWAYS)
2388 #endif
2390 *obufp++ = 'b';
2391 break;
2392 case 'B':
2393 if (intel_syntax)
2394 break;
2395 #ifdef SUFFIX_ALWAYS
2396 if (sizeflag & SUFFIX_ALWAYS)
2397 *obufp++ = 'b';
2398 #endif
2399 break;
2400 case 'E': /* For jcxz/jecxz */
2401 if (sizeflag & AFLAG)
2402 *obufp++ = 'e';
2403 break;
2404 case 'L':
2405 if (intel_syntax)
2406 break;
2407 #ifdef SUFFIX_ALWAYS
2408 if (sizeflag & SUFFIX_ALWAYS)
2409 *obufp++ = 'l';
2410 #endif
2411 break;
2412 case 'N':
2413 if ((prefixes & PREFIX_FWAIT) == 0)
2414 *obufp++ = 'n';
2415 break;
2416 case 'P':
2417 if (intel_syntax)
2418 break;
2419 if ((prefixes & PREFIX_DATA)
2420 #ifdef SUFFIX_ALWAYS
2421 || (sizeflag & SUFFIX_ALWAYS)
2422 #endif
2425 if (sizeflag & DFLAG)
2426 *obufp++ = 'l';
2427 else
2428 *obufp++ = 'w';
2430 break;
2431 case 'Q':
2432 if (intel_syntax)
2433 break;
2434 if (mod != 3
2435 #ifdef SUFFIX_ALWAYS
2436 || (sizeflag & SUFFIX_ALWAYS)
2437 #endif
2440 if (sizeflag & DFLAG)
2441 *obufp++ = 'l';
2442 else
2443 *obufp++ = 'w';
2445 break;
2446 case 'R':
2447 if (intel_syntax)
2448 break;
2449 if (sizeflag & DFLAG)
2450 *obufp++ = 'l';
2451 else
2452 *obufp++ = 'w';
2453 break;
2454 case 'S':
2455 if (intel_syntax)
2456 break;
2457 #ifdef SUFFIX_ALWAYS
2458 if (sizeflag & SUFFIX_ALWAYS)
2460 if (sizeflag & DFLAG)
2461 *obufp++ = 'l';
2462 else
2463 *obufp++ = 'w';
2465 #endif
2466 break;
2467 case 'W':
2468 if (intel_syntax)
2469 break;
2470 /* operand size flag for cwtl, cbtw */
2471 if (sizeflag & DFLAG)
2472 *obufp++ = 'w';
2473 else
2474 *obufp++ = 'b';
2475 break;
2478 *obufp = 0;
2481 static void
2482 oappend (s)
2483 char *s;
2485 strcpy (obufp, s);
2486 obufp += strlen (s);
2489 static void
2490 append_seg ()
2492 if (prefixes & PREFIX_CS)
2493 oappend ("%cs:");
2494 if (prefixes & PREFIX_DS)
2495 oappend ("%ds:");
2496 if (prefixes & PREFIX_SS)
2497 oappend ("%ss:");
2498 if (prefixes & PREFIX_ES)
2499 oappend ("%es:");
2500 if (prefixes & PREFIX_FS)
2501 oappend ("%fs:");
2502 if (prefixes & PREFIX_GS)
2503 oappend ("%gs:");
2506 static void
2507 OP_indirE (bytemode, sizeflag)
2508 int bytemode;
2509 int sizeflag;
2511 if (!intel_syntax)
2512 oappend ("*");
2513 OP_E (bytemode, sizeflag);
2516 static void
2517 OP_E (bytemode, sizeflag)
2518 int bytemode;
2519 int sizeflag;
2521 int disp;
2523 /* skip mod/rm byte */
2524 codep++;
2526 if (mod == 3)
2528 switch (bytemode)
2530 case b_mode:
2531 oappend (names8[rm]);
2532 break;
2533 case w_mode:
2534 oappend (names16[rm]);
2535 break;
2536 case v_mode:
2537 if (sizeflag & DFLAG)
2538 oappend (names32[rm]);
2539 else
2540 oappend (names16[rm]);
2541 break;
2542 default:
2543 oappend ("<bad dis table>");
2544 break;
2546 return;
2549 disp = 0;
2550 append_seg ();
2552 if (sizeflag & AFLAG) /* 32 bit address mode */
2554 int havesib;
2555 int havebase;
2556 int base;
2557 int index = 0;
2558 int scale = 0;
2560 havesib = 0;
2561 havebase = 1;
2562 base = rm;
2564 if (base == 4)
2566 havesib = 1;
2567 FETCH_DATA (the_info, codep + 1);
2568 scale = (*codep >> 6) & 3;
2569 index = (*codep >> 3) & 7;
2570 base = *codep & 7;
2571 codep++;
2574 switch (mod)
2576 case 0:
2577 if (base == 5)
2579 havebase = 0;
2580 disp = get32 ();
2582 break;
2583 case 1:
2584 FETCH_DATA (the_info, codep + 1);
2585 disp = *codep++;
2586 if ((disp & 0x80) != 0)
2587 disp -= 0x100;
2588 break;
2589 case 2:
2590 disp = get32 ();
2591 break;
2594 if (!intel_syntax)
2595 if (mod != 0 || base == 5)
2597 sprintf (scratchbuf, "0x%x", disp);
2598 oappend (scratchbuf);
2601 if (havebase || (havesib && (index != 4 || scale != 0)))
2603 if (intel_syntax)
2605 switch (bytemode)
2607 case b_mode:
2608 oappend("BYTE PTR ");
2609 break;
2610 case w_mode:
2611 oappend("WORD PTR ");
2612 break;
2613 case v_mode:
2614 oappend("DWORD PTR ");
2615 break;
2616 case d_mode:
2617 oappend("QWORD PTR ");
2618 break;
2619 case x_mode:
2620 oappend("XWORD PTR ");
2621 break;
2622 default:
2623 break;
2626 *obufp++ = open_char;
2627 *obufp = '\0';
2628 if (havebase)
2629 oappend (names32[base]);
2630 if (havesib)
2632 if (index != 4)
2634 if (intel_syntax)
2636 if (havebase)
2638 *obufp++ = separator_char;
2639 *obufp = '\0';
2641 sprintf (scratchbuf, "%s", names32[index]);
2643 else
2644 sprintf (scratchbuf, ",%s", names32[index]);
2645 oappend (scratchbuf);
2647 if (!intel_syntax
2648 || (intel_syntax
2649 && bytemode != b_mode
2650 && bytemode != w_mode
2651 && bytemode != v_mode))
2653 *obufp++ = scale_char;
2654 *obufp = '\0';
2655 sprintf (scratchbuf, "%d", 1 << scale);
2656 oappend (scratchbuf);
2659 if (intel_syntax)
2660 if (mod != 0 || base == 5)
2662 /* Don't print zero displacements */
2663 if (disp > 0)
2665 sprintf (scratchbuf, "+%d", disp);
2666 oappend (scratchbuf);
2668 else if (disp < 0)
2670 sprintf (scratchbuf, "%d", disp);
2671 oappend (scratchbuf);
2675 *obufp++ = close_char;
2676 *obufp = '\0';
2678 else if (intel_syntax)
2680 if (mod != 0 || base == 5)
2682 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
2683 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
2685 else
2687 oappend (names_seg[3]);
2688 oappend (":");
2690 sprintf (scratchbuf, "0x%x", disp);
2691 oappend (scratchbuf);
2695 else
2696 { /* 16 bit address mode */
2697 switch (mod)
2699 case 0:
2700 if (rm == 6)
2702 disp = get16 ();
2703 if ((disp & 0x8000) != 0)
2704 disp -= 0x10000;
2706 break;
2707 case 1:
2708 FETCH_DATA (the_info, codep + 1);
2709 disp = *codep++;
2710 if ((disp & 0x80) != 0)
2711 disp -= 0x100;
2712 break;
2713 case 2:
2714 disp = get16 ();
2715 if ((disp & 0x8000) != 0)
2716 disp -= 0x10000;
2717 break;
2720 if (!intel_syntax)
2721 if (mod != 0 || rm == 6)
2723 sprintf (scratchbuf, "%d", disp);
2724 oappend (scratchbuf);
2727 if (mod != 0 || rm != 6)
2729 *obufp++ = open_char;
2730 *obufp = '\0';
2731 oappend (index16[rm]);
2732 *obufp++ = close_char;
2733 *obufp = '\0';
2738 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2740 static void
2741 OP_G (bytemode, sizeflag)
2742 int bytemode;
2743 int sizeflag;
2745 switch (bytemode)
2747 case b_mode:
2748 oappend (names8[reg]);
2749 break;
2750 case w_mode:
2751 oappend (names16[reg]);
2752 break;
2753 case d_mode:
2754 oappend (names32[reg]);
2755 break;
2756 case v_mode:
2757 if (sizeflag & DFLAG)
2758 oappend (names32[reg]);
2759 else
2760 oappend (names16[reg]);
2761 break;
2762 default:
2763 oappend (INTERNAL_DISASSEMBLER_ERROR);
2764 break;
2768 static int
2769 get32 ()
2771 int x = 0;
2773 FETCH_DATA (the_info, codep + 4);
2774 x = *codep++ & 0xff;
2775 x |= (*codep++ & 0xff) << 8;
2776 x |= (*codep++ & 0xff) << 16;
2777 x |= (*codep++ & 0xff) << 24;
2778 return x;
2781 static int
2782 get16 ()
2784 int x = 0;
2786 FETCH_DATA (the_info, codep + 2);
2787 x = *codep++ & 0xff;
2788 x |= (*codep++ & 0xff) << 8;
2789 return x;
2792 static void
2793 set_op (op)
2794 unsigned int op;
2796 op_index[op_ad] = op_ad;
2797 op_address[op_ad] = op;
2800 static void
2801 OP_REG (code, sizeflag)
2802 int code;
2803 int sizeflag;
2805 char *s;
2807 switch (code)
2809 case indir_dx_reg:
2810 s = "(%dx)";
2811 break;
2812 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
2813 case sp_reg: case bp_reg: case si_reg: case di_reg:
2814 s = names16[code - ax_reg];
2815 break;
2816 case es_reg: case ss_reg: case cs_reg:
2817 case ds_reg: case fs_reg: case gs_reg:
2818 s = names_seg[code - es_reg];
2819 break;
2820 case al_reg: case ah_reg: case cl_reg: case ch_reg:
2821 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
2822 s = names8[code - al_reg];
2823 break;
2824 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
2825 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
2826 if (sizeflag & DFLAG)
2827 s = names32[code - eAX_reg];
2828 else
2829 s = names16[code - eAX_reg];
2830 break;
2831 default:
2832 s = INTERNAL_DISASSEMBLER_ERROR;
2833 break;
2835 oappend (s);
2838 static void
2839 OP_I (bytemode, sizeflag)
2840 int bytemode;
2841 int sizeflag;
2843 int op;
2845 switch (bytemode)
2847 case b_mode:
2848 FETCH_DATA (the_info, codep + 1);
2849 op = *codep++ & 0xff;
2850 break;
2851 case v_mode:
2852 if (sizeflag & DFLAG)
2853 op = get32 ();
2854 else
2855 op = get16 ();
2856 break;
2857 case w_mode:
2858 op = get16 ();
2859 break;
2860 default:
2861 oappend (INTERNAL_DISASSEMBLER_ERROR);
2862 return;
2865 if (intel_syntax)
2866 sprintf (scratchbuf, "0x%x", op);
2867 else
2868 sprintf (scratchbuf, "$0x%x", op);
2869 oappend (scratchbuf);
2870 scratchbuf[0] = '\0';
2873 static void
2874 OP_sI (bytemode, sizeflag)
2875 int bytemode;
2876 int sizeflag;
2878 int op;
2880 switch (bytemode)
2882 case b_mode:
2883 FETCH_DATA (the_info, codep + 1);
2884 op = *codep++;
2885 if ((op & 0x80) != 0)
2886 op -= 0x100;
2887 break;
2888 case v_mode:
2889 if (sizeflag & DFLAG)
2890 op = get32 ();
2891 else
2893 op = get16();
2894 if ((op & 0x8000) != 0)
2895 op -= 0x10000;
2897 break;
2898 case w_mode:
2899 op = get16 ();
2900 if ((op & 0x8000) != 0)
2901 op -= 0x10000;
2902 break;
2903 default:
2904 oappend (INTERNAL_DISASSEMBLER_ERROR);
2905 return;
2907 if (intel_syntax)
2908 sprintf (scratchbuf, "%d", op);
2909 else
2910 sprintf (scratchbuf, "$0x%x", op);
2911 oappend (scratchbuf);
2914 static void
2915 OP_J (bytemode, sizeflag)
2916 int bytemode;
2917 int sizeflag;
2919 int disp;
2920 int mask = -1;
2922 switch (bytemode)
2924 case b_mode:
2925 FETCH_DATA (the_info, codep + 1);
2926 disp = *codep++;
2927 if ((disp & 0x80) != 0)
2928 disp -= 0x100;
2929 break;
2930 case v_mode:
2931 if (sizeflag & DFLAG)
2932 disp = get32 ();
2933 else
2935 disp = get16 ();
2936 /* for some reason, a data16 prefix on a jump instruction
2937 means that the pc is masked to 16 bits after the
2938 displacement is added! */
2939 mask = 0xffff;
2941 break;
2942 default:
2943 oappend (INTERNAL_DISASSEMBLER_ERROR);
2944 return;
2946 disp = (start_pc + codep - start_codep + disp) & mask;
2947 set_op (disp);
2948 sprintf (scratchbuf, "0x%x", disp);
2949 oappend (scratchbuf);
2952 /* ARGSUSED */
2953 static void
2954 OP_SEG (dummy, sizeflag)
2955 int dummy;
2956 int sizeflag;
2958 static char *sreg[] = {
2959 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2962 oappend (sreg[reg]);
2965 static void
2966 OP_DIR (size, sizeflag)
2967 int size;
2968 int sizeflag;
2970 int seg, offset;
2972 switch (size)
2974 case lptr:
2975 if (sizeflag & DFLAG)
2977 offset = get32 ();
2978 seg = get16 ();
2980 else
2982 offset = get16 ();
2983 seg = get16 ();
2985 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
2986 oappend (scratchbuf);
2987 break;
2988 case v_mode:
2989 if (sizeflag & DFLAG)
2990 offset = get32 ();
2991 else
2993 offset = get16 ();
2994 if ((offset & 0x8000) != 0)
2995 offset -= 0x10000;
2998 offset = start_pc + codep - start_codep + offset;
2999 set_op (offset);
3000 sprintf (scratchbuf, "0x%x", offset);
3001 oappend (scratchbuf);
3002 break;
3003 default:
3004 oappend (INTERNAL_DISASSEMBLER_ERROR);
3005 break;
3009 /* ARGSUSED */
3010 static void
3011 OP_OFF (ignore, sizeflag)
3012 int ignore;
3013 int sizeflag;
3015 int off;
3017 append_seg ();
3019 if (sizeflag & AFLAG)
3020 off = get32 ();
3021 else
3022 off = get16 ();
3024 if (intel_syntax)
3026 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3027 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3029 oappend (names_seg[3]);
3030 oappend (":");
3033 sprintf (scratchbuf, "0x%x", off);
3034 oappend (scratchbuf);
3037 static void
3038 ptr_reg (code, sizeflag)
3039 int code;
3040 int sizeflag;
3042 char *s;
3043 oappend ("(");
3044 if (sizeflag & AFLAG)
3045 s = names32[code - eAX_reg];
3046 else
3047 s = names16[code - eAX_reg];
3048 oappend (s);
3049 oappend (")");
3052 static void
3053 OP_ESreg (code, sizeflag)
3054 int code;
3055 int sizeflag;
3057 oappend ("%es:");
3058 ptr_reg (code, sizeflag);
3061 static void
3062 OP_DSreg (code, sizeflag)
3063 int code;
3064 int sizeflag;
3066 if ((prefixes
3067 & (PREFIX_CS
3068 | PREFIX_DS
3069 | PREFIX_SS
3070 | PREFIX_ES
3071 | PREFIX_FS
3072 | PREFIX_GS)) == 0)
3073 prefixes |= PREFIX_DS;
3074 append_seg();
3075 ptr_reg (code, sizeflag);
3078 #if 0
3079 /* Not used. */
3081 /* ARGSUSED */
3082 static void
3083 OP_ONE (dummy, sizeflag)
3084 int dummy;
3085 int sizeflag;
3087 oappend ("1");
3090 #endif
3092 /* ARGSUSED */
3093 static void
3094 OP_C (dummy, sizeflag)
3095 int dummy;
3096 int sizeflag;
3098 codep++; /* skip mod/rm */
3099 sprintf (scratchbuf, "%%cr%d", reg);
3100 oappend (scratchbuf);
3103 /* ARGSUSED */
3104 static void
3105 OP_D (dummy, sizeflag)
3106 int dummy;
3107 int sizeflag;
3109 codep++; /* skip mod/rm */
3110 sprintf (scratchbuf, "%%db%d", reg);
3111 oappend (scratchbuf);
3114 /* ARGSUSED */
3115 static void
3116 OP_T (dummy, sizeflag)
3117 int dummy;
3118 int sizeflag;
3120 codep++; /* skip mod/rm */
3121 sprintf (scratchbuf, "%%tr%d", reg);
3122 oappend (scratchbuf);
3125 static void
3126 OP_rm (bytemode, sizeflag)
3127 int bytemode;
3128 int sizeflag;
3130 switch (bytemode)
3132 case d_mode:
3133 oappend (names32[rm]);
3134 break;
3135 case w_mode:
3136 oappend (names16[rm]);
3137 break;
3141 static void
3142 OP_MMX (ignore, sizeflag)
3143 int ignore;
3144 int sizeflag;
3146 sprintf (scratchbuf, "%%mm%d", reg);
3147 oappend (scratchbuf);
3150 static void
3151 OP_EM (bytemode, sizeflag)
3152 int bytemode;
3153 int sizeflag;
3155 if (mod != 3)
3157 OP_E (bytemode, sizeflag);
3158 return;
3161 codep++;
3162 sprintf (scratchbuf, "%%mm%d", rm);
3163 oappend (scratchbuf);
3166 static void
3167 OP_MS (ignore, sizeflag)
3168 int ignore;
3169 int sizeflag;
3171 ++codep;
3172 sprintf (scratchbuf, "%%mm%d", rm);
3173 oappend (scratchbuf);
3176 static const char *Suffix3DNow[] = {
3177 /* 00 */ NULL, NULL, NULL, NULL,
3178 /* 04 */ NULL, NULL, NULL, NULL,
3179 /* 08 */ NULL, NULL, NULL, NULL,
3180 /* 0C */ NULL, "pi2fd", NULL, NULL,
3181 /* 10 */ NULL, NULL, NULL, NULL,
3182 /* 14 */ NULL, NULL, NULL, NULL,
3183 /* 18 */ NULL, NULL, NULL, NULL,
3184 /* 1C */ NULL, "pf2id", NULL, NULL,
3185 /* 20 */ NULL, NULL, NULL, NULL,
3186 /* 24 */ NULL, NULL, NULL, NULL,
3187 /* 28 */ NULL, NULL, NULL, NULL,
3188 /* 2C */ NULL, NULL, NULL, NULL,
3189 /* 30 */ NULL, NULL, NULL, NULL,
3190 /* 34 */ NULL, NULL, NULL, NULL,
3191 /* 38 */ NULL, NULL, NULL, NULL,
3192 /* 3C */ NULL, NULL, NULL, NULL,
3193 /* 40 */ NULL, NULL, NULL, NULL,
3194 /* 44 */ NULL, NULL, NULL, NULL,
3195 /* 48 */ NULL, NULL, NULL, NULL,
3196 /* 4C */ NULL, NULL, NULL, NULL,
3197 /* 50 */ NULL, NULL, NULL, NULL,
3198 /* 54 */ NULL, NULL, NULL, NULL,
3199 /* 58 */ NULL, NULL, NULL, NULL,
3200 /* 5C */ NULL, NULL, NULL, NULL,
3201 /* 60 */ NULL, NULL, NULL, NULL,
3202 /* 64 */ NULL, NULL, NULL, NULL,
3203 /* 68 */ NULL, NULL, NULL, NULL,
3204 /* 6C */ NULL, NULL, NULL, NULL,
3205 /* 70 */ NULL, NULL, NULL, NULL,
3206 /* 74 */ NULL, NULL, NULL, NULL,
3207 /* 78 */ NULL, NULL, NULL, NULL,
3208 /* 7C */ NULL, NULL, NULL, NULL,
3209 /* 80 */ NULL, NULL, NULL, NULL,
3210 /* 84 */ NULL, NULL, NULL, NULL,
3211 /* 88 */ NULL, NULL, NULL, NULL,
3212 /* 8C */ NULL, NULL, NULL, NULL,
3213 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3214 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3215 /* 98 */ NULL, NULL, "pfsub", NULL,
3216 /* 9C */ NULL, NULL, "pfadd", NULL,
3217 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3218 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3219 /* A8 */ NULL, NULL, "pfsubr", NULL,
3220 /* AC */ NULL, NULL, "pfacc", NULL,
3221 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3222 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3223 /* B8 */ NULL, NULL, NULL, NULL,
3224 /* BC */ NULL, NULL, NULL, "pavgusb",
3225 /* C0 */ NULL, NULL, NULL, NULL,
3226 /* C4 */ NULL, NULL, NULL, NULL,
3227 /* C8 */ NULL, NULL, NULL, NULL,
3228 /* CC */ NULL, NULL, NULL, NULL,
3229 /* D0 */ NULL, NULL, NULL, NULL,
3230 /* D4 */ NULL, NULL, NULL, NULL,
3231 /* D8 */ NULL, NULL, NULL, NULL,
3232 /* DC */ NULL, NULL, NULL, NULL,
3233 /* E0 */ NULL, NULL, NULL, NULL,
3234 /* E4 */ NULL, NULL, NULL, NULL,
3235 /* E8 */ NULL, NULL, NULL, NULL,
3236 /* EC */ NULL, NULL, NULL, NULL,
3237 /* F0 */ NULL, NULL, NULL, NULL,
3238 /* F4 */ NULL, NULL, NULL, NULL,
3239 /* F8 */ NULL, NULL, NULL, NULL,
3240 /* FC */ NULL, NULL, NULL, NULL,
3243 static void
3244 OP_3DNowSuffix (bytemode, sizeflag)
3245 int bytemode;
3246 int sizeflag;
3248 const char *mnemonic;
3250 FETCH_DATA (the_info, codep + 1);
3251 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3252 place where an 8-bit immediate would normally go. ie. the last
3253 byte of the instruction. */
3254 mnemonic = Suffix3DNow[*codep++];
3255 if (mnemonic)
3256 strcat (obuf, mnemonic);
3257 else
3259 /* Since a variable sized modrm/sib chunk is between the start
3260 of the opcode (0x0f0f) and the opcode suffix, we need to do
3261 all the modrm processing first, and don't know until now that
3262 we have a bad opcode. This necessitates some cleaning up. */
3263 op1out[0] = 0;
3264 op2out[0] = 0;
3265 codep = insn_codep + 1;
3266 strcat (obuf, "(bad)");