* symbols.c (copy_symbol_attributes): Convert local symbols to
[binutils.git] / opcodes / i386-dis.c
blob7cda14e8d782b2a1bdfe277a01e73d00268dc1cc
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 Ed OP_E, d_mode
97 #define indirEv OP_indirE, v_mode
98 #define Ew OP_E, w_mode
99 #define Ma OP_E, v_mode
100 #define M OP_E, 0 /* lea */
101 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
102 #define Gv OP_G, v_mode
103 #define Gw OP_G, w_mode
104 #define Rd OP_Rd, 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 #define Cd OP_C, d_mode
112 #define Dd OP_D, d_mode
113 #define Td OP_T, d_mode
115 #define eAX OP_REG, eAX_reg
116 #define eBX OP_REG, eBX_reg
117 #define eCX OP_REG, eCX_reg
118 #define eDX OP_REG, eDX_reg
119 #define eSP OP_REG, eSP_reg
120 #define eBP OP_REG, eBP_reg
121 #define eSI OP_REG, eSI_reg
122 #define eDI OP_REG, eDI_reg
123 #define AL OP_REG, al_reg
124 #define CL OP_REG, cl_reg
125 #define DL OP_REG, dl_reg
126 #define BL OP_REG, bl_reg
127 #define AH OP_REG, ah_reg
128 #define CH OP_REG, ch_reg
129 #define DH OP_REG, dh_reg
130 #define BH OP_REG, bh_reg
131 #define AX OP_REG, ax_reg
132 #define DX OP_REG, dx_reg
133 #define indirDX OP_REG, indir_dx_reg
135 #define Sw OP_SEG, w_mode
136 #define Ap OP_DIR, 0
137 #define Ob OP_OFF, b_mode
138 #define Ov OP_OFF, v_mode
139 #define Xb OP_DSreg, eSI_reg
140 #define Xv OP_DSreg, eSI_reg
141 #define Yb OP_ESreg, eDI_reg
142 #define Yv OP_ESreg, eDI_reg
143 #define DSBX OP_DSreg, eBX_reg
145 #define es OP_REG, es_reg
146 #define ss OP_REG, ss_reg
147 #define cs OP_REG, cs_reg
148 #define ds OP_REG, ds_reg
149 #define fs OP_REG, fs_reg
150 #define gs OP_REG, gs_reg
152 #define MX OP_MMX, 0
153 #define XM OP_XMM, 0
154 #define EM OP_EM, v_mode
155 #define EX OP_EX, v_mode
156 #define MS OP_MS, v_mode
157 #define None OP_E, 0
158 #define OPSUF OP_3DNowSuffix, 0
159 #define OPSIMD OP_SIMD_Suffix, 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_Rd PARAMS ((int, int));
186 static void OP_ST PARAMS ((int, int));
187 static void OP_STi PARAMS ((int, int));
188 static void OP_MMX PARAMS ((int, int));
189 static void OP_XMM PARAMS ((int, int));
190 static void OP_EM PARAMS ((int, int));
191 static void OP_EX PARAMS ((int, int));
192 static void OP_MS PARAMS ((int, int));
193 static void OP_3DNowSuffix PARAMS ((int, int));
194 static void OP_SIMD_Suffix PARAMS ((int, int));
195 static void SIMD_Fixup PARAMS ((int, int));
197 static void append_seg PARAMS ((void));
198 static void set_op PARAMS ((unsigned int op));
199 static void putop PARAMS ((const char *template, int sizeflag));
200 static void dofloat PARAMS ((int sizeflag));
201 static int get16 PARAMS ((void));
202 static int get32 PARAMS ((void));
203 static void ckprefix PARAMS ((void));
204 static void ptr_reg PARAMS ((int, int));
205 static void BadOp PARAMS ((void));
207 #define b_mode 1
208 #define v_mode 2
209 #define w_mode 3
210 #define d_mode 4
211 #define x_mode 5
213 #define es_reg 100
214 #define cs_reg 101
215 #define ss_reg 102
216 #define ds_reg 103
217 #define fs_reg 104
218 #define gs_reg 105
220 #define eAX_reg 108
221 #define eCX_reg 109
222 #define eDX_reg 110
223 #define eBX_reg 111
224 #define eSP_reg 112
225 #define eBP_reg 113
226 #define eSI_reg 114
227 #define eDI_reg 115
229 #define al_reg 116
230 #define cl_reg 117
231 #define dl_reg 118
232 #define bl_reg 119
233 #define ah_reg 120
234 #define ch_reg 121
235 #define dh_reg 122
236 #define bh_reg 123
238 #define ax_reg 124
239 #define cx_reg 125
240 #define dx_reg 126
241 #define bx_reg 127
242 #define sp_reg 128
243 #define bp_reg 129
244 #define si_reg 130
245 #define di_reg 131
247 #define indir_dx_reg 150
249 #define USE_GROUPS 1
250 #define USE_PREFIX_USER_TABLE 2
252 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
253 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
254 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
255 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
256 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
257 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
258 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
259 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
260 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
261 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
262 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
263 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
264 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
265 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
266 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
267 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
268 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
269 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
270 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
271 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
272 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
273 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
274 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
276 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
277 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
278 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
279 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
280 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
281 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
282 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
283 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
284 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
285 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
286 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
287 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
288 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
289 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
290 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
292 #define FLOATCODE 50
293 #define FLOAT NULL, NULL, FLOATCODE
295 struct dis386 {
296 const char *name;
297 op_rtn op1;
298 int bytemode1;
299 op_rtn op2;
300 int bytemode2;
301 op_rtn op3;
302 int bytemode3;
305 /* Upper case letters in the instruction names here are macros.
306 'A' => print 'b' if no register operands or suffix_always is true
307 'B' => print 'b' if suffix_always is true
308 'E' => print 'e' if 32-bit form of jcxz
309 'L' => print 'l' if suffix_always is true
310 'N' => print 'n' if instruction has no wait "prefix"
311 'P' => print 'w' or 'l' if instruction has an operand size prefix,
312 or suffix_always is true
313 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
314 'R' => print 'w' or 'l'
315 'S' => print 'w' or 'l' if suffix_always is true
316 'W' => print 'b' or 'w'
319 static const struct dis386 dis386_att[] = {
320 /* 00 */
321 { "addB", Eb, Gb },
322 { "addS", Ev, Gv },
323 { "addB", Gb, Eb },
324 { "addS", Gv, Ev },
325 { "addB", AL, Ib },
326 { "addS", eAX, Iv },
327 { "pushP", es },
328 { "popP", es },
329 /* 08 */
330 { "orB", Eb, Gb },
331 { "orS", Ev, Gv },
332 { "orB", Gb, Eb },
333 { "orS", Gv, Ev },
334 { "orB", AL, Ib },
335 { "orS", eAX, Iv },
336 { "pushP", cs },
337 { "(bad)" }, /* 0x0f extended opcode escape */
338 /* 10 */
339 { "adcB", Eb, Gb },
340 { "adcS", Ev, Gv },
341 { "adcB", Gb, Eb },
342 { "adcS", Gv, Ev },
343 { "adcB", AL, Ib },
344 { "adcS", eAX, Iv },
345 { "pushP", ss },
346 { "popP", ss },
347 /* 18 */
348 { "sbbB", Eb, Gb },
349 { "sbbS", Ev, Gv },
350 { "sbbB", Gb, Eb },
351 { "sbbS", Gv, Ev },
352 { "sbbB", AL, Ib },
353 { "sbbS", eAX, Iv },
354 { "pushP", ds },
355 { "popP", ds },
356 /* 20 */
357 { "andB", Eb, Gb },
358 { "andS", Ev, Gv },
359 { "andB", Gb, Eb },
360 { "andS", Gv, Ev },
361 { "andB", AL, Ib },
362 { "andS", eAX, Iv },
363 { "(bad)" }, /* SEG ES prefix */
364 { "daa" },
365 /* 28 */
366 { "subB", Eb, Gb },
367 { "subS", Ev, Gv },
368 { "subB", Gb, Eb },
369 { "subS", Gv, Ev },
370 { "subB", AL, Ib },
371 { "subS", eAX, Iv },
372 { "(bad)" }, /* SEG CS prefix */
373 { "das" },
374 /* 30 */
375 { "xorB", Eb, Gb },
376 { "xorS", Ev, Gv },
377 { "xorB", Gb, Eb },
378 { "xorS", Gv, Ev },
379 { "xorB", AL, Ib },
380 { "xorS", eAX, Iv },
381 { "(bad)" }, /* SEG SS prefix */
382 { "aaa" },
383 /* 38 */
384 { "cmpB", Eb, Gb },
385 { "cmpS", Ev, Gv },
386 { "cmpB", Gb, Eb },
387 { "cmpS", Gv, Ev },
388 { "cmpB", AL, Ib },
389 { "cmpS", eAX, Iv },
390 { "(bad)" }, /* SEG DS prefix */
391 { "aas" },
392 /* 40 */
393 { "incS", eAX },
394 { "incS", eCX },
395 { "incS", eDX },
396 { "incS", eBX },
397 { "incS", eSP },
398 { "incS", eBP },
399 { "incS", eSI },
400 { "incS", eDI },
401 /* 48 */
402 { "decS", eAX },
403 { "decS", eCX },
404 { "decS", eDX },
405 { "decS", eBX },
406 { "decS", eSP },
407 { "decS", eBP },
408 { "decS", eSI },
409 { "decS", eDI },
410 /* 50 */
411 { "pushS", eAX },
412 { "pushS", eCX },
413 { "pushS", eDX },
414 { "pushS", eBX },
415 { "pushS", eSP },
416 { "pushS", eBP },
417 { "pushS", eSI },
418 { "pushS", eDI },
419 /* 58 */
420 { "popS", eAX },
421 { "popS", eCX },
422 { "popS", eDX },
423 { "popS", eBX },
424 { "popS", eSP },
425 { "popS", eBP },
426 { "popS", eSI },
427 { "popS", eDI },
428 /* 60 */
429 { "pushaP" },
430 { "popaP" },
431 { "boundS", Gv, Ma },
432 { "arpl", Ew, Gw },
433 { "(bad)" }, /* seg fs */
434 { "(bad)" }, /* seg gs */
435 { "(bad)" }, /* op size prefix */
436 { "(bad)" }, /* adr size prefix */
437 /* 68 */
438 { "pushP", Iv }, /* 386 book wrong */
439 { "imulS", Gv, Ev, Iv },
440 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
441 { "imulS", Gv, Ev, sIb },
442 { "insb", Yb, indirDX },
443 { "insR", Yv, indirDX },
444 { "outsb", indirDX, Xb },
445 { "outsR", indirDX, Xv },
446 /* 70 */
447 { "jo", Jb },
448 { "jno", Jb },
449 { "jb", Jb },
450 { "jae", Jb },
451 { "je", Jb },
452 { "jne", Jb },
453 { "jbe", Jb },
454 { "ja", Jb },
455 /* 78 */
456 { "js", Jb },
457 { "jns", Jb },
458 { "jp", Jb },
459 { "jnp", Jb },
460 { "jl", Jb },
461 { "jge", Jb },
462 { "jle", Jb },
463 { "jg", Jb },
464 /* 80 */
465 { GRP1b },
466 { GRP1S },
467 { "(bad)" },
468 { GRP1Ss },
469 { "testB", Eb, Gb },
470 { "testS", Ev, Gv },
471 { "xchgB", Eb, Gb },
472 { "xchgS", Ev, Gv },
473 /* 88 */
474 { "movB", Eb, Gb },
475 { "movS", Ev, Gv },
476 { "movB", Gb, Eb },
477 { "movS", Gv, Ev },
478 { "movQ", Ev, Sw },
479 { "leaS", Gv, M },
480 { "movQ", Sw, Ev },
481 { "popQ", Ev },
482 /* 90 */
483 { "nop" },
484 { "xchgS", eCX, eAX },
485 { "xchgS", eDX, eAX },
486 { "xchgS", eBX, eAX },
487 { "xchgS", eSP, eAX },
488 { "xchgS", eBP, eAX },
489 { "xchgS", eSI, eAX },
490 { "xchgS", eDI, eAX },
491 /* 98 */
492 { "cWtR" },
493 { "cRtd" },
494 { "lcallP", Ap },
495 { "(bad)" }, /* fwait */
496 { "pushfP" },
497 { "popfP" },
498 { "sahf" },
499 { "lahf" },
500 /* a0 */
501 { "movB", AL, Ob },
502 { "movS", eAX, Ov },
503 { "movB", Ob, AL },
504 { "movS", Ov, eAX },
505 { "movsb", Yb, Xb },
506 { "movsR", Yv, Xv },
507 { "cmpsb", Xb, Yb },
508 { "cmpsR", Xv, Yv },
509 /* a8 */
510 { "testB", AL, Ib },
511 { "testS", eAX, Iv },
512 { "stosB", Yb, AL },
513 { "stosS", Yv, eAX },
514 { "lodsB", AL, Xb },
515 { "lodsS", eAX, Xv },
516 { "scasB", AL, Yb },
517 { "scasS", eAX, Yv },
518 /* b0 */
519 { "movB", AL, Ib },
520 { "movB", CL, Ib },
521 { "movB", DL, Ib },
522 { "movB", BL, Ib },
523 { "movB", AH, Ib },
524 { "movB", CH, Ib },
525 { "movB", DH, Ib },
526 { "movB", BH, Ib },
527 /* b8 */
528 { "movS", eAX, Iv },
529 { "movS", eCX, Iv },
530 { "movS", eDX, Iv },
531 { "movS", eBX, Iv },
532 { "movS", eSP, Iv },
533 { "movS", eBP, Iv },
534 { "movS", eSI, Iv },
535 { "movS", eDI, Iv },
536 /* c0 */
537 { GRP2b },
538 { GRP2S },
539 { "retP", Iw },
540 { "retP" },
541 { "lesS", Gv, Mp },
542 { "ldsS", Gv, Mp },
543 { "movA", Eb, Ib },
544 { "movQ", Ev, Iv },
545 /* c8 */
546 { "enterP", Iw, Ib },
547 { "leaveP" },
548 { "lretP", Iw },
549 { "lretP" },
550 { "int3" },
551 { "int", Ib },
552 { "into" },
553 { "iretP" },
554 /* d0 */
555 { GRP2b_one },
556 { GRP2S_one },
557 { GRP2b_cl },
558 { GRP2S_cl },
559 { "aam", sIb },
560 { "aad", sIb },
561 { "(bad)" },
562 { "xlat", DSBX },
563 /* d8 */
564 { FLOAT },
565 { FLOAT },
566 { FLOAT },
567 { FLOAT },
568 { FLOAT },
569 { FLOAT },
570 { FLOAT },
571 { FLOAT },
572 /* e0 */
573 { "loopne", Jb },
574 { "loope", Jb },
575 { "loop", Jb },
576 { "jEcxz", Jb },
577 { "inB", AL, Ib },
578 { "inS", eAX, Ib },
579 { "outB", Ib, AL },
580 { "outS", Ib, eAX },
581 /* e8 */
582 { "callP", Jv },
583 { "jmpP", Jv },
584 { "ljmpP", Ap },
585 { "jmp", Jb },
586 { "inB", AL, indirDX },
587 { "inS", eAX, indirDX },
588 { "outB", indirDX, AL },
589 { "outS", indirDX, eAX },
590 /* f0 */
591 { "(bad)" }, /* lock prefix */
592 { "(bad)" },
593 { "(bad)" }, /* repne */
594 { "(bad)" }, /* repz */
595 { "hlt" },
596 { "cmc" },
597 { GRP3b },
598 { GRP3S },
599 /* f8 */
600 { "clc" },
601 { "stc" },
602 { "cli" },
603 { "sti" },
604 { "cld" },
605 { "std" },
606 { GRP4 },
607 { GRP5 },
610 static const struct dis386 dis386_intel[] = {
611 /* 00 */
612 { "add", Eb, Gb },
613 { "add", Ev, Gv },
614 { "add", Gb, Eb },
615 { "add", Gv, Ev },
616 { "add", AL, Ib },
617 { "add", eAX, Iv },
618 { "push", es },
619 { "pop", es },
620 /* 08 */
621 { "or", Eb, Gb },
622 { "or", Ev, Gv },
623 { "or", Gb, Eb },
624 { "or", Gv, Ev },
625 { "or", AL, Ib },
626 { "or", eAX, Iv },
627 { "push", cs },
628 { "(bad)" }, /* 0x0f extended opcode escape */
629 /* 10 */
630 { "adc", Eb, Gb },
631 { "adc", Ev, Gv },
632 { "adc", Gb, Eb },
633 { "adc", Gv, Ev },
634 { "adc", AL, Ib },
635 { "adc", eAX, Iv },
636 { "push", ss },
637 { "pop", ss },
638 /* 18 */
639 { "sbb", Eb, Gb },
640 { "sbb", Ev, Gv },
641 { "sbb", Gb, Eb },
642 { "sbb", Gv, Ev },
643 { "sbb", AL, Ib },
644 { "sbb", eAX, Iv },
645 { "push", ds },
646 { "pop", ds },
647 /* 20 */
648 { "and", Eb, Gb },
649 { "and", Ev, Gv },
650 { "and", Gb, Eb },
651 { "and", Gv, Ev },
652 { "and", AL, Ib },
653 { "and", eAX, Iv },
654 { "(bad)" }, /* SEG ES prefix */
655 { "daa" },
656 /* 28 */
657 { "sub", Eb, Gb },
658 { "sub", Ev, Gv },
659 { "sub", Gb, Eb },
660 { "sub", Gv, Ev },
661 { "sub", AL, Ib },
662 { "sub", eAX, Iv },
663 { "(bad)" }, /* SEG CS prefix */
664 { "das" },
665 /* 30 */
666 { "xor", Eb, Gb },
667 { "xor", Ev, Gv },
668 { "xor", Gb, Eb },
669 { "xor", Gv, Ev },
670 { "xor", AL, Ib },
671 { "xor", eAX, Iv },
672 { "(bad)" }, /* SEG SS prefix */
673 { "aaa" },
674 /* 38 */
675 { "cmp", Eb, Gb },
676 { "cmp", Ev, Gv },
677 { "cmp", Gb, Eb },
678 { "cmp", Gv, Ev },
679 { "cmp", AL, Ib },
680 { "cmp", eAX, Iv },
681 { "(bad)" }, /* SEG DS prefix */
682 { "aas" },
683 /* 40 */
684 { "inc", eAX },
685 { "inc", eCX },
686 { "inc", eDX },
687 { "inc", eBX },
688 { "inc", eSP },
689 { "inc", eBP },
690 { "inc", eSI },
691 { "inc", eDI },
692 /* 48 */
693 { "dec", eAX },
694 { "dec", eCX },
695 { "dec", eDX },
696 { "dec", eBX },
697 { "dec", eSP },
698 { "dec", eBP },
699 { "dec", eSI },
700 { "dec", eDI },
701 /* 50 */
702 { "push", eAX },
703 { "push", eCX },
704 { "push", eDX },
705 { "push", eBX },
706 { "push", eSP },
707 { "push", eBP },
708 { "push", eSI },
709 { "push", eDI },
710 /* 58 */
711 { "pop", eAX },
712 { "pop", eCX },
713 { "pop", eDX },
714 { "pop", eBX },
715 { "pop", eSP },
716 { "pop", eBP },
717 { "pop", eSI },
718 { "pop", eDI },
719 /* 60 */
720 { "pusha" },
721 { "popa" },
722 { "bound", Gv, Ma },
723 { "arpl", Ew, Gw },
724 { "(bad)" }, /* seg fs */
725 { "(bad)" }, /* seg gs */
726 { "(bad)" }, /* op size prefix */
727 { "(bad)" }, /* adr size prefix */
728 /* 68 */
729 { "push", Iv }, /* 386 book wrong */
730 { "imul", Gv, Ev, Iv },
731 { "push", sIb }, /* push of byte really pushes 2 or 4 bytes */
732 { "imul", Gv, Ev, sIb },
733 { "ins", Yb, indirDX },
734 { "ins", Yv, indirDX },
735 { "outs", indirDX, Xb },
736 { "outs", indirDX, Xv },
737 /* 70 */
738 { "jo", Jb },
739 { "jno", Jb },
740 { "jb", Jb },
741 { "jae", Jb },
742 { "je", Jb },
743 { "jne", Jb },
744 { "jbe", Jb },
745 { "ja", Jb },
746 /* 78 */
747 { "js", Jb },
748 { "jns", Jb },
749 { "jp", Jb },
750 { "jnp", Jb },
751 { "jl", Jb },
752 { "jge", Jb },
753 { "jle", Jb },
754 { "jg", Jb },
755 /* 80 */
756 { GRP1b },
757 { GRP1S },
758 { "(bad)" },
759 { GRP1Ss },
760 { "test", Eb, Gb },
761 { "test", Ev, Gv },
762 { "xchg", Eb, Gb },
763 { "xchg", Ev, Gv },
764 /* 88 */
765 { "mov", Eb, Gb },
766 { "mov", Ev, Gv },
767 { "mov", Gb, Eb },
768 { "mov", Gv, Ev },
769 { "mov", Ev, Sw },
770 { "lea", Gv, M },
771 { "mov", Sw, Ev },
772 { "pop", Ev },
773 /* 90 */
774 { "nop" },
775 { "xchg", eCX, eAX },
776 { "xchg", eDX, eAX },
777 { "xchg", eBX, eAX },
778 { "xchg", eSP, eAX },
779 { "xchg", eBP, eAX },
780 { "xchg", eSI, eAX },
781 { "xchg", eDI, eAX },
782 /* 98 */
783 { "cW" }, /* cwde and cbw */
784 { "cR" }, /* cdq and cwd */
785 { "lcall", Ap },
786 { "(bad)" }, /* fwait */
787 { "pushf" },
788 { "popf" },
789 { "sahf" },
790 { "lahf" },
791 /* a0 */
792 { "mov", AL, Ob },
793 { "mov", eAX, Ov },
794 { "mov", Ob, AL },
795 { "mov", Ov, eAX },
796 { "movs", Yb, Xb },
797 { "movs", Yv, Xv },
798 { "cmps", Xb, Yb },
799 { "cmps", Xv, Yv },
800 /* a8 */
801 { "test", AL, Ib },
802 { "test", eAX, Iv },
803 { "stos", Yb, AL },
804 { "stos", Yv, eAX },
805 { "lods", AL, Xb },
806 { "lods", eAX, Xv },
807 { "scas", AL, Yb },
808 { "scas", eAX, Yv },
809 /* b0 */
810 { "mov", AL, Ib },
811 { "mov", CL, Ib },
812 { "mov", DL, Ib },
813 { "mov", BL, Ib },
814 { "mov", AH, Ib },
815 { "mov", CH, Ib },
816 { "mov", DH, Ib },
817 { "mov", BH, Ib },
818 /* b8 */
819 { "mov", eAX, Iv },
820 { "mov", eCX, Iv },
821 { "mov", eDX, Iv },
822 { "mov", eBX, Iv },
823 { "mov", eSP, Iv },
824 { "mov", eBP, Iv },
825 { "mov", eSI, Iv },
826 { "mov", eDI, Iv },
827 /* c0 */
828 { GRP2b },
829 { GRP2S },
830 { "ret", Iw },
831 { "ret" },
832 { "les", Gv, Mp },
833 { "lds", Gv, Mp },
834 { "mov", Eb, Ib },
835 { "mov", Ev, Iv },
836 /* c8 */
837 { "enter", Iw, Ib },
838 { "leave" },
839 { "lret", Iw },
840 { "lret" },
841 { "int3" },
842 { "int", Ib },
843 { "into" },
844 { "iret" },
845 /* d0 */
846 { GRP2b_one },
847 { GRP2S_one },
848 { GRP2b_cl },
849 { GRP2S_cl },
850 { "aam", sIb },
851 { "aad", sIb },
852 { "(bad)" },
853 { "xlat", DSBX },
854 /* d8 */
855 { FLOAT },
856 { FLOAT },
857 { FLOAT },
858 { FLOAT },
859 { FLOAT },
860 { FLOAT },
861 { FLOAT },
862 { FLOAT },
863 /* e0 */
864 { "loopne", Jb },
865 { "loope", Jb },
866 { "loop", Jb },
867 { "jEcxz", Jb },
868 { "in", AL, Ib },
869 { "in", eAX, Ib },
870 { "out", Ib, AL },
871 { "out", Ib, eAX },
872 /* e8 */
873 { "call", Jv },
874 { "jmp", Jv },
875 { "ljmp", Ap },
876 { "jmp", Jb },
877 { "in", AL, indirDX },
878 { "in", eAX, indirDX },
879 { "out", indirDX, AL },
880 { "out", indirDX, eAX },
881 /* f0 */
882 { "(bad)" }, /* lock prefix */
883 { "(bad)" },
884 { "(bad)" }, /* repne */
885 { "(bad)" }, /* repz */
886 { "hlt" },
887 { "cmc" },
888 { GRP3b },
889 { GRP3S },
890 /* f8 */
891 { "clc" },
892 { "stc" },
893 { "cli" },
894 { "sti" },
895 { "cld" },
896 { "std" },
897 { GRP4 },
898 { GRP5 },
901 static const struct dis386 dis386_twobyte_att[] = {
902 /* 00 */
903 { GRP6 },
904 { GRP7 },
905 { "larS", Gv, Ew },
906 { "lslS", Gv, Ew },
907 { "(bad)" },
908 { "(bad)" },
909 { "clts" },
910 { "(bad)" },
911 /* 08 */
912 { "invd" },
913 { "wbinvd" },
914 { "(bad)" },
915 { "ud2a" },
916 { "(bad)" },
917 { GRPAMD },
918 { "femms" },
919 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
920 /* 10 */
921 { PREGRP8 },
922 { PREGRP9 },
923 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
924 { "movlps", EX, XM, SIMD_Fixup, 'h' },
925 { "unpcklps", XM, EX },
926 { "unpckhps", XM, EX },
927 { "movhps", XM, EX, SIMD_Fixup, 'l' },
928 { "movhps", EX, XM, SIMD_Fixup, 'l' },
929 /* 18 */
930 { GRP14 },
931 { "(bad)" }, { "(bad)" }, { "(bad)" },
932 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
933 /* 20 */
934 /* these are all backward in appendix A of the intel book */
935 { "movL", Rd, Cd },
936 { "movL", Rd, Dd },
937 { "movL", Cd, Rd },
938 { "movL", Dd, Rd },
939 { "movL", Rd, Td },
940 { "(bad)" },
941 { "movL", Td, Rd },
942 { "(bad)" },
943 /* 28 */
944 { "movaps", XM, EX },
945 { "movaps", EX, XM },
946 { PREGRP2 },
947 { "movntps", Ev, XM },
948 { PREGRP4 },
949 { PREGRP3 },
950 { "ucomiss", XM, EX },
951 { "comiss", XM, EX },
952 /* 30 */
953 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
954 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
955 /* 38 */
956 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
957 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
958 /* 40 */
959 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
960 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
961 /* 48 */
962 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
963 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
964 /* 50 */
965 { "movmskps", Gv, EX },
966 { PREGRP13 },
967 { PREGRP12 },
968 { PREGRP11 },
969 { "andps", XM, EX },
970 { "andnps", XM, EX },
971 { "orps", XM, EX },
972 { "xorps", XM, EX },
973 /* 58 */
974 { PREGRP0 },
975 { PREGRP10 },
976 { "(bad)" },
977 { "(bad)" },
978 { PREGRP14 },
979 { PREGRP7 },
980 { PREGRP5 },
981 { PREGRP6 },
982 /* 60 */
983 { "punpcklbw", MX, EM },
984 { "punpcklwd", MX, EM },
985 { "punpckldq", MX, EM },
986 { "packsswb", MX, EM },
987 { "pcmpgtb", MX, EM },
988 { "pcmpgtw", MX, EM },
989 { "pcmpgtd", MX, EM },
990 { "packuswb", MX, EM },
991 /* 68 */
992 { "punpckhbw", MX, EM },
993 { "punpckhwd", MX, EM },
994 { "punpckhdq", MX, EM },
995 { "packssdw", MX, EM },
996 { "(bad)" }, { "(bad)" },
997 { "movd", MX, Ed },
998 { "movq", MX, EM },
999 /* 70 */
1000 { "pshufw", MX, EM, Ib },
1001 { GRP10 },
1002 { GRP11 },
1003 { GRP12 },
1004 { "pcmpeqb", MX, EM },
1005 { "pcmpeqw", MX, EM },
1006 { "pcmpeqd", MX, EM },
1007 { "emms" },
1008 /* 78 */
1009 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1010 { "(bad)" }, { "(bad)" },
1011 { "movd", Ed, MX },
1012 { "movq", EM, MX },
1013 /* 80 */
1014 { "jo", Jv },
1015 { "jno", Jv },
1016 { "jb", Jv },
1017 { "jae", Jv },
1018 { "je", Jv },
1019 { "jne", Jv },
1020 { "jbe", Jv },
1021 { "ja", Jv },
1022 /* 88 */
1023 { "js", Jv },
1024 { "jns", Jv },
1025 { "jp", Jv },
1026 { "jnp", Jv },
1027 { "jl", Jv },
1028 { "jge", Jv },
1029 { "jle", Jv },
1030 { "jg", Jv },
1031 /* 90 */
1032 { "seto", Eb },
1033 { "setno", Eb },
1034 { "setb", Eb },
1035 { "setae", Eb },
1036 { "sete", Eb },
1037 { "setne", Eb },
1038 { "setbe", Eb },
1039 { "seta", Eb },
1040 /* 98 */
1041 { "sets", Eb },
1042 { "setns", Eb },
1043 { "setp", Eb },
1044 { "setnp", Eb },
1045 { "setl", Eb },
1046 { "setge", Eb },
1047 { "setle", Eb },
1048 { "setg", Eb },
1049 /* a0 */
1050 { "pushP", fs },
1051 { "popP", fs },
1052 { "cpuid" },
1053 { "btS", Ev, Gv },
1054 { "shldS", Ev, Gv, Ib },
1055 { "shldS", Ev, Gv, CL },
1056 { "(bad)" },
1057 { "(bad)" },
1058 /* a8 */
1059 { "pushP", gs },
1060 { "popP", gs },
1061 { "rsm" },
1062 { "btsS", Ev, Gv },
1063 { "shrdS", Ev, Gv, Ib },
1064 { "shrdS", Ev, Gv, CL },
1065 { GRP13 },
1066 { "imulS", Gv, Ev },
1067 /* b0 */
1068 { "cmpxchgB", Eb, Gb },
1069 { "cmpxchgS", Ev, Gv },
1070 { "lssS", Gv, Mp },
1071 { "btrS", Ev, Gv },
1072 { "lfsS", Gv, Mp },
1073 { "lgsS", Gv, Mp },
1074 { "movzbR", Gv, Eb },
1075 { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
1076 /* b8 */
1077 { "(bad)" },
1078 { "ud2b" },
1079 { GRP8 },
1080 { "btcS", Ev, Gv },
1081 { "bsfS", Gv, Ev },
1082 { "bsrS", Gv, Ev },
1083 { "movsbR", Gv, Eb },
1084 { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
1085 /* c0 */
1086 { "xaddB", Eb, Gb },
1087 { "xaddS", Ev, Gv },
1088 { PREGRP1 },
1089 { "(bad)" },
1090 { "pinsrw", MX, Ev, Ib },
1091 { "pextrw", Ev, MX, Ib },
1092 { "shufps", XM, EX, Ib },
1093 { GRP9 },
1094 /* c8 */
1095 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1096 { "bswap", eCX },
1097 { "bswap", eDX },
1098 { "bswap", eBX },
1099 { "bswap", eSP },
1100 { "bswap", eBP },
1101 { "bswap", eSI },
1102 { "bswap", eDI },
1103 /* d0 */
1104 { "(bad)" },
1105 { "psrlw", MX, EM },
1106 { "psrld", MX, EM },
1107 { "psrlq", MX, EM },
1108 { "(bad)" },
1109 { "pmullw", MX, EM },
1110 { "(bad)" },
1111 { "pmovmskb", Ev, MX },
1112 /* d8 */
1113 { "psubusb", MX, EM },
1114 { "psubusw", MX, EM },
1115 { "pminub", MX, EM },
1116 { "pand", MX, EM },
1117 { "paddusb", MX, EM },
1118 { "paddusw", MX, EM },
1119 { "pmaxub", MX, EM },
1120 { "pandn", MX, EM },
1121 /* e0 */
1122 { "pavgb", MX, EM },
1123 { "psraw", MX, EM },
1124 { "psrad", MX, EM },
1125 { "pavgw", MX, EM },
1126 { "pmulhuw", MX, EM },
1127 { "pmulhw", MX, EM },
1128 { "(bad)" },
1129 { "movntq", Ev, MX },
1130 /* e8 */
1131 { "psubsb", MX, EM },
1132 { "psubsw", MX, EM },
1133 { "pminsw", MX, EM },
1134 { "por", MX, EM },
1135 { "paddsb", MX, EM },
1136 { "paddsw", MX, EM },
1137 { "pmaxsw", MX, EM },
1138 { "pxor", MX, EM },
1139 /* f0 */
1140 { "(bad)" },
1141 { "psllw", MX, EM },
1142 { "pslld", MX, EM },
1143 { "psllq", MX, EM },
1144 { "(bad)" },
1145 { "pmaddwd", MX, EM },
1146 { "psadbw", MX, EM },
1147 { "maskmovq", MX, EM },
1148 /* f8 */
1149 { "psubb", MX, EM },
1150 { "psubw", MX, EM },
1151 { "psubd", MX, EM },
1152 { "(bad)" },
1153 { "paddb", MX, EM },
1154 { "paddw", MX, EM },
1155 { "paddd", MX, EM },
1156 { "(bad)" }
1159 static const struct dis386 dis386_twobyte_intel[] = {
1160 /* 00 */
1161 { GRP6 },
1162 { GRP7 },
1163 { "lar", Gv, Ew },
1164 { "lsl", Gv, Ew },
1165 { "(bad)" },
1166 { "(bad)" },
1167 { "clts" },
1168 { "(bad)" },
1169 /* 08 */
1170 { "invd" },
1171 { "wbinvd" },
1172 { "(bad)" },
1173 { "ud2a" },
1174 { "(bad)" },
1175 { GRPAMD },
1176 { "femms" },
1177 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1178 /* 10 */
1179 { PREGRP8 },
1180 { PREGRP9 },
1181 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1182 { "movlps", EX, XM, SIMD_Fixup, 'h' },
1183 { "unpcklps", XM, EX },
1184 { "unpckhps", XM, EX },
1185 { "movhps", XM, EX, SIMD_Fixup, 'l' },
1186 { "movhps", EX, XM, SIMD_Fixup, 'l' },
1187 /* 18 */
1188 { GRP14 },
1189 { "(bad)" }, { "(bad)" }, { "(bad)" },
1190 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1191 /* 20 */
1192 /* these are all backward in appendix A of the intel book */
1193 { "mov", Rd, Cd },
1194 { "mov", Rd, Dd },
1195 { "mov", Cd, Rd },
1196 { "mov", Dd, Rd },
1197 { "mov", Rd, Td },
1198 { "(bad)" },
1199 { "mov", Td, Rd },
1200 { "(bad)" },
1201 /* 28 */
1202 { "movaps", XM, EX },
1203 { "movaps", EX, XM },
1204 { PREGRP2 },
1205 { "movntps", Ev, XM },
1206 { PREGRP4 },
1207 { PREGRP3 },
1208 { "ucomiss", XM, EX },
1209 { "comiss", XM, EX },
1210 /* 30 */
1211 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1212 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1213 /* 38 */
1214 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1215 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1216 /* 40 */
1217 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
1218 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
1219 /* 48 */
1220 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
1221 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
1222 /* 50 */
1223 { "movmskps", Gv, EX },
1224 { PREGRP13 },
1225 { PREGRP12 },
1226 { PREGRP11 },
1227 { "andps", XM, EX },
1228 { "andnps", XM, EX },
1229 { "orps", XM, EX },
1230 { "xorps", XM, EX },
1231 /* 58 */
1232 { PREGRP0 },
1233 { PREGRP10 },
1234 { "(bad)" },
1235 { "(bad)" },
1236 { PREGRP14 },
1237 { PREGRP7 },
1238 { PREGRP5 },
1239 { PREGRP6 },
1240 /* 60 */
1241 { "punpcklbw", MX, EM },
1242 { "punpcklwd", MX, EM },
1243 { "punpckldq", MX, EM },
1244 { "packsswb", MX, EM },
1245 { "pcmpgtb", MX, EM },
1246 { "pcmpgtw", MX, EM },
1247 { "pcmpgtd", MX, EM },
1248 { "packuswb", MX, EM },
1249 /* 68 */
1250 { "punpckhbw", MX, EM },
1251 { "punpckhwd", MX, EM },
1252 { "punpckhdq", MX, EM },
1253 { "packssdw", MX, EM },
1254 { "(bad)" }, { "(bad)" },
1255 { "movd", MX, Ed },
1256 { "movq", MX, EM },
1257 /* 70 */
1258 { "pshufw", MX, EM, Ib },
1259 { GRP10 },
1260 { GRP11 },
1261 { GRP12 },
1262 { "pcmpeqb", MX, EM },
1263 { "pcmpeqw", MX, EM },
1264 { "pcmpeqd", MX, EM },
1265 { "emms" },
1266 /* 78 */
1267 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1268 { "(bad)" }, { "(bad)" },
1269 { "movd", Ed, MX },
1270 { "movq", EM, MX },
1271 /* 80 */
1272 { "jo", Jv },
1273 { "jno", Jv },
1274 { "jb", Jv },
1275 { "jae", Jv },
1276 { "je", Jv },
1277 { "jne", Jv },
1278 { "jbe", Jv },
1279 { "ja", Jv },
1280 /* 88 */
1281 { "js", Jv },
1282 { "jns", Jv },
1283 { "jp", Jv },
1284 { "jnp", Jv },
1285 { "jl", Jv },
1286 { "jge", Jv },
1287 { "jle", Jv },
1288 { "jg", Jv },
1289 /* 90 */
1290 { "seto", Eb },
1291 { "setno", Eb },
1292 { "setb", Eb },
1293 { "setae", Eb },
1294 { "sete", Eb },
1295 { "setne", Eb },
1296 { "setbe", Eb },
1297 { "seta", Eb },
1298 /* 98 */
1299 { "sets", Eb },
1300 { "setns", Eb },
1301 { "setp", Eb },
1302 { "setnp", Eb },
1303 { "setl", Eb },
1304 { "setge", Eb },
1305 { "setle", Eb },
1306 { "setg", Eb },
1307 /* a0 */
1308 { "push", fs },
1309 { "pop", fs },
1310 { "cpuid" },
1311 { "bt", Ev, Gv },
1312 { "shld", Ev, Gv, Ib },
1313 { "shld", Ev, Gv, CL },
1314 { "(bad)" },
1315 { "(bad)" },
1316 /* a8 */
1317 { "push", gs },
1318 { "pop", gs },
1319 { "rsm" },
1320 { "bts", Ev, Gv },
1321 { "shrd", Ev, Gv, Ib },
1322 { "shrd", Ev, Gv, CL },
1323 { GRP13 },
1324 { "imul", Gv, Ev },
1325 /* b0 */
1326 { "cmpxchg", Eb, Gb },
1327 { "cmpxchg", Ev, Gv },
1328 { "lss", Gv, Mp },
1329 { "btr", Ev, Gv },
1330 { "lfs", Gv, Mp },
1331 { "lgs", Gv, Mp },
1332 { "movzx", Gv, Eb },
1333 { "movzx", Gv, Ew },
1334 /* b8 */
1335 { "(bad)" },
1336 { "ud2b" },
1337 { GRP8 },
1338 { "btc", Ev, Gv },
1339 { "bsf", Gv, Ev },
1340 { "bsr", Gv, Ev },
1341 { "movsx", Gv, Eb },
1342 { "movsx", Gv, Ew },
1343 /* c0 */
1344 { "xadd", Eb, Gb },
1345 { "xadd", Ev, Gv },
1346 { PREGRP1 },
1347 { "(bad)" },
1348 { "pinsrw", MX, Ev, Ib },
1349 { "pextrw", Ev, MX, Ib },
1350 { "shufps", XM, EX, Ib },
1351 { GRP9 },
1352 /* c8 */
1353 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1354 { "bswap", eCX },
1355 { "bswap", eDX },
1356 { "bswap", eBX },
1357 { "bswap", eSP },
1358 { "bswap", eBP },
1359 { "bswap", eSI },
1360 { "bswap", eDI },
1361 /* d0 */
1362 { "(bad)" },
1363 { "psrlw", MX, EM },
1364 { "psrld", MX, EM },
1365 { "psrlq", MX, EM },
1366 { "(bad)" },
1367 { "pmullw", MX, EM },
1368 { "(bad)" },
1369 { "pmovmskb", Ev, MX },
1370 /* d8 */
1371 { "psubusb", MX, EM },
1372 { "psubusw", MX, EM },
1373 { "pminub", MX, EM },
1374 { "pand", MX, EM },
1375 { "paddusb", MX, EM },
1376 { "paddusw", MX, EM },
1377 { "pmaxub", MX, EM },
1378 { "pandn", MX, EM },
1379 /* e0 */
1380 { "pavgb", MX, EM },
1381 { "psraw", MX, EM },
1382 { "psrad", MX, EM },
1383 { "pavgw", MX, EM },
1384 { "pmulhuw", MX, EM },
1385 { "pmulhw", MX, EM },
1386 { "(bad)" },
1387 { "movntq", Ev, MX },
1388 /* e8 */
1389 { "psubsb", MX, EM },
1390 { "psubsw", MX, EM },
1391 { "pminsw", MX, EM },
1392 { "por", MX, EM },
1393 { "paddsb", MX, EM },
1394 { "paddsw", MX, EM },
1395 { "pmaxsw", MX, EM },
1396 { "pxor", MX, EM },
1397 /* f0 */
1398 { "(bad)" },
1399 { "psllw", MX, EM },
1400 { "pslld", MX, EM },
1401 { "psllq", MX, EM },
1402 { "(bad)" },
1403 { "pmaddwd", MX, EM },
1404 { "psadbw", MX, EM },
1405 { "maskmovq", MX, EM },
1406 /* f8 */
1407 { "psubb", MX, EM },
1408 { "psubw", MX, EM },
1409 { "psubd", MX, EM },
1410 { "(bad)" },
1411 { "paddb", MX, EM },
1412 { "paddw", MX, EM },
1413 { "paddd", MX, EM },
1414 { "(bad)" }
1417 static const unsigned char onebyte_has_modrm[256] = {
1418 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1419 /* ------------------------------- */
1420 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1421 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1422 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1423 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1424 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1425 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1426 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1427 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1428 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1429 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1430 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1431 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1432 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1433 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1434 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1435 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1436 /* ------------------------------- */
1437 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1440 static const unsigned char twobyte_has_modrm[256] = {
1441 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1442 /* ------------------------------- */
1443 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1444 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1445 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1446 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1447 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1448 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1449 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1450 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1451 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1452 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1453 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1454 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1455 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1456 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1457 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1458 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1459 /* ------------------------------- */
1460 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1463 static const unsigned char twobyte_uses_f3_prefix[256] = {
1464 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1465 /* ------------------------------- */
1466 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1467 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1468 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1469 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1470 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1471 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1472 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1473 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1474 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1475 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1476 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1477 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1478 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1479 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1480 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1481 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1482 /* ------------------------------- */
1483 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1486 static char obuf[100];
1487 static char *obufp;
1488 static char scratchbuf[100];
1489 static unsigned char *start_codep;
1490 static unsigned char *insn_codep;
1491 static unsigned char *codep;
1492 static disassemble_info *the_info;
1493 static int mod;
1494 static int rm;
1495 static int reg;
1496 static void oappend PARAMS ((const char *s));
1498 static const char *names32[]={
1499 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1501 static const char *names16[] = {
1502 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1504 static const char *names8[] = {
1505 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1507 static const char *names_seg[] = {
1508 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1510 static const char *index16[] = {
1511 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1514 static const struct dis386 grps[][8] = {
1515 /* GRP1b */
1517 { "addA", Eb, Ib },
1518 { "orA", Eb, Ib },
1519 { "adcA", Eb, Ib },
1520 { "sbbA", Eb, Ib },
1521 { "andA", Eb, Ib },
1522 { "subA", Eb, Ib },
1523 { "xorA", Eb, Ib },
1524 { "cmpA", Eb, Ib }
1526 /* GRP1S */
1528 { "addQ", Ev, Iv },
1529 { "orQ", Ev, Iv },
1530 { "adcQ", Ev, Iv },
1531 { "sbbQ", Ev, Iv },
1532 { "andQ", Ev, Iv },
1533 { "subQ", Ev, Iv },
1534 { "xorQ", Ev, Iv },
1535 { "cmpQ", Ev, Iv }
1537 /* GRP1Ss */
1539 { "addQ", Ev, sIb },
1540 { "orQ", Ev, sIb },
1541 { "adcQ", Ev, sIb },
1542 { "sbbQ", Ev, sIb },
1543 { "andQ", Ev, sIb },
1544 { "subQ", Ev, sIb },
1545 { "xorQ", Ev, sIb },
1546 { "cmpQ", Ev, sIb }
1548 /* GRP2b */
1550 { "rolA", Eb, Ib },
1551 { "rorA", Eb, Ib },
1552 { "rclA", Eb, Ib },
1553 { "rcrA", Eb, Ib },
1554 { "shlA", Eb, Ib },
1555 { "shrA", Eb, Ib },
1556 { "(bad)" },
1557 { "sarA", Eb, Ib },
1559 /* GRP2S */
1561 { "rolQ", Ev, Ib },
1562 { "rorQ", Ev, Ib },
1563 { "rclQ", Ev, Ib },
1564 { "rcrQ", Ev, Ib },
1565 { "shlQ", Ev, Ib },
1566 { "shrQ", Ev, Ib },
1567 { "(bad)" },
1568 { "sarQ", Ev, Ib },
1570 /* GRP2b_one */
1572 { "rolA", Eb },
1573 { "rorA", Eb },
1574 { "rclA", Eb },
1575 { "rcrA", Eb },
1576 { "shlA", Eb },
1577 { "shrA", Eb },
1578 { "(bad)" },
1579 { "sarA", Eb },
1581 /* GRP2S_one */
1583 { "rolQ", Ev },
1584 { "rorQ", Ev },
1585 { "rclQ", Ev },
1586 { "rcrQ", Ev },
1587 { "shlQ", Ev },
1588 { "shrQ", Ev },
1589 { "(bad)" },
1590 { "sarQ", Ev },
1592 /* GRP2b_cl */
1594 { "rolA", Eb, CL },
1595 { "rorA", Eb, CL },
1596 { "rclA", Eb, CL },
1597 { "rcrA", Eb, CL },
1598 { "shlA", Eb, CL },
1599 { "shrA", Eb, CL },
1600 { "(bad)" },
1601 { "sarA", Eb, CL },
1603 /* GRP2S_cl */
1605 { "rolQ", Ev, CL },
1606 { "rorQ", Ev, CL },
1607 { "rclQ", Ev, CL },
1608 { "rcrQ", Ev, CL },
1609 { "shlQ", Ev, CL },
1610 { "shrQ", Ev, CL },
1611 { "(bad)" },
1612 { "sarQ", Ev, CL }
1614 /* GRP3b */
1616 { "testA", Eb, Ib },
1617 { "(bad)", Eb },
1618 { "notA", Eb },
1619 { "negA", Eb },
1620 { "mulB", AL, Eb },
1621 { "imulB", AL, Eb },
1622 { "divB", AL, Eb },
1623 { "idivB", AL, Eb }
1625 /* GRP3S */
1627 { "testQ", Ev, Iv },
1628 { "(bad)" },
1629 { "notQ", Ev },
1630 { "negQ", Ev },
1631 { "mulS", eAX, Ev },
1632 { "imulS", eAX, Ev },
1633 { "divS", eAX, Ev },
1634 { "idivS", eAX, Ev },
1636 /* GRP4 */
1638 { "incA", Eb },
1639 { "decA", Eb },
1640 { "(bad)" },
1641 { "(bad)" },
1642 { "(bad)" },
1643 { "(bad)" },
1644 { "(bad)" },
1645 { "(bad)" },
1647 /* GRP5 */
1649 { "incQ", Ev },
1650 { "decQ", Ev },
1651 { "callP", indirEv },
1652 { "callP", indirEv },
1653 { "jmpP", indirEv },
1654 { "ljmpP", indirEv },
1655 { "pushQ", Ev },
1656 { "(bad)" },
1658 /* GRP6 */
1660 { "sldt", Ew },
1661 { "str", Ew },
1662 { "lldt", Ew },
1663 { "ltr", Ew },
1664 { "verr", Ew },
1665 { "verw", Ew },
1666 { "(bad)" },
1667 { "(bad)" }
1669 /* GRP7 */
1671 { "sgdt", Ew },
1672 { "sidt", Ew },
1673 { "lgdt", Ew },
1674 { "lidt", Ew },
1675 { "smsw", Ew },
1676 { "(bad)" },
1677 { "lmsw", Ew },
1678 { "invlpg", Ew },
1680 /* GRP8 */
1682 { "(bad)" },
1683 { "(bad)" },
1684 { "(bad)" },
1685 { "(bad)" },
1686 { "btQ", Ev, Ib },
1687 { "btsQ", Ev, Ib },
1688 { "btrQ", Ev, Ib },
1689 { "btcQ", Ev, Ib },
1691 /* GRP9 */
1693 { "(bad)" },
1694 { "cmpxchg8b", Ev },
1695 { "(bad)" },
1696 { "(bad)" },
1697 { "(bad)" },
1698 { "(bad)" },
1699 { "(bad)" },
1700 { "(bad)" },
1702 /* GRP10 */
1704 { "(bad)" },
1705 { "(bad)" },
1706 { "psrlw", MS, Ib },
1707 { "(bad)" },
1708 { "psraw", MS, Ib },
1709 { "(bad)" },
1710 { "psllw", MS, Ib },
1711 { "(bad)" },
1713 /* GRP11 */
1715 { "(bad)" },
1716 { "(bad)" },
1717 { "psrld", MS, Ib },
1718 { "(bad)" },
1719 { "psrad", MS, Ib },
1720 { "(bad)" },
1721 { "pslld", MS, Ib },
1722 { "(bad)" },
1724 /* GRP12 */
1726 { "(bad)" },
1727 { "(bad)" },
1728 { "psrlq", MS, Ib },
1729 { "(bad)" },
1730 { "(bad)" },
1731 { "(bad)" },
1732 { "psllq", MS, Ib },
1733 { "(bad)" },
1735 /* GRP13 */
1737 { "fxsave", Ev },
1738 { "fxrstor", Ev },
1739 { "ldmxcsr", Ev },
1740 { "stmxcsr", Ev },
1741 { "(bad)" },
1742 { "(bad)" },
1743 { "(bad)" },
1744 { "sfence", None },
1746 /* GRP14 */
1748 { "prefetchnta", Ev },
1749 { "prefetcht0", Ev },
1750 { "prefetcht1", Ev },
1751 { "prefetcht2", Ev },
1752 { "(bad)" },
1753 { "(bad)" },
1754 { "(bad)" },
1755 { "(bad)" },
1757 /* GRPAMD */
1759 { "prefetch", Eb },
1760 { "prefetchw", Eb },
1761 { "(bad)" },
1762 { "(bad)" },
1763 { "(bad)" },
1764 { "(bad)" },
1765 { "(bad)" },
1766 { "(bad)" },
1771 static const struct dis386 prefix_user_table[][2] = {
1772 /* PREGRP0 */
1774 { "addps", XM, EX },
1775 { "addss", XM, EX },
1777 /* PREGRP1 */
1779 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
1780 { "", XM, EX, OPSIMD },
1782 /* PREGRP2 */
1784 { "cvtpi2ps", XM, EM },
1785 { "cvtsi2ss", XM, Ev },
1787 /* PREGRP3 */
1789 { "cvtps2pi", MX, EX },
1790 { "cvtss2si", Gv, EX },
1792 /* PREGRP4 */
1794 { "cvttps2pi", MX, EX },
1795 { "cvttss2si", Gv, EX },
1797 /* PREGRP5 */
1799 { "divps", XM, EX },
1800 { "divss", XM, EX },
1802 /* PREGRP6 */
1804 { "maxps", XM, EX },
1805 { "maxss", XM, EX },
1807 /* PREGRP7 */
1809 { "minps", XM, EX },
1810 { "minss", XM, EX },
1812 /* PREGRP8 */
1814 { "movups", XM, EX },
1815 { "movss", XM, EX },
1817 /* PREGRP9 */
1819 { "movups", EX, XM },
1820 { "movss", EX, XM },
1822 /* PREGRP10 */
1824 { "mulps", XM, EX },
1825 { "mulss", XM, EX },
1827 /* PREGRP11 */
1829 { "rcpps", XM, EX },
1830 { "rcpss", XM, EX },
1832 /* PREGRP12 */
1834 { "rsqrtps", XM, EX },
1835 { "rsqrtss", XM, EX },
1837 /* PREGRP13 */
1839 { "sqrtps", XM, EX },
1840 { "sqrtss", XM, EX },
1842 /* PREGRP14 */
1844 { "subps", XM, EX },
1845 { "subss", XM, EX },
1849 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1851 #define PREFIX_REPZ 1
1852 #define PREFIX_REPNZ 2
1853 #define PREFIX_LOCK 4
1854 #define PREFIX_CS 8
1855 #define PREFIX_SS 0x10
1856 #define PREFIX_DS 0x20
1857 #define PREFIX_ES 0x40
1858 #define PREFIX_FS 0x80
1859 #define PREFIX_GS 0x100
1860 #define PREFIX_DATA 0x200
1861 #define PREFIX_ADDR 0x400
1862 #define PREFIX_FWAIT 0x800
1864 static int prefixes;
1866 static void
1867 ckprefix ()
1869 prefixes = 0;
1870 while (1)
1872 FETCH_DATA (the_info, codep + 1);
1873 switch (*codep)
1875 case 0xf3:
1876 prefixes |= PREFIX_REPZ;
1877 break;
1878 case 0xf2:
1879 prefixes |= PREFIX_REPNZ;
1880 break;
1881 case 0xf0:
1882 prefixes |= PREFIX_LOCK;
1883 break;
1884 case 0x2e:
1885 prefixes |= PREFIX_CS;
1886 break;
1887 case 0x36:
1888 prefixes |= PREFIX_SS;
1889 break;
1890 case 0x3e:
1891 prefixes |= PREFIX_DS;
1892 break;
1893 case 0x26:
1894 prefixes |= PREFIX_ES;
1895 break;
1896 case 0x64:
1897 prefixes |= PREFIX_FS;
1898 break;
1899 case 0x65:
1900 prefixes |= PREFIX_GS;
1901 break;
1902 case 0x66:
1903 prefixes |= PREFIX_DATA;
1904 break;
1905 case 0x67:
1906 prefixes |= PREFIX_ADDR;
1907 break;
1908 case 0x9b:
1909 /* fwait is really an instruction. If there are prefixes
1910 before the fwait, they belong to the fwait, *not* to the
1911 following instruction. */
1912 if (prefixes)
1914 prefixes |= PREFIX_FWAIT;
1915 codep++;
1916 return;
1918 prefixes = PREFIX_FWAIT;
1919 break;
1920 default:
1921 return;
1923 codep++;
1927 static char op1out[100], op2out[100], op3out[100];
1928 static int op_ad, op_index[3];
1929 static unsigned int op_address[3];
1930 static unsigned int start_pc;
1934 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1935 * (see topic "Redundant prefixes" in the "Differences from 8086"
1936 * section of the "Virtual 8086 Mode" chapter.)
1937 * 'pc' should be the address of this instruction, it will
1938 * be used to print the target address if this is a relative jump or call
1939 * The function returns the length of this instruction in bytes.
1942 static int print_insn_i386
1943 PARAMS ((bfd_vma pc, disassemble_info *info));
1945 static char intel_syntax;
1946 static char open_char;
1947 static char close_char;
1948 static char separator_char;
1949 static char scale_char;
1952 print_insn_i386_att (pc, info)
1953 bfd_vma pc;
1954 disassemble_info *info;
1956 intel_syntax = 0;
1957 open_char = '(';
1958 close_char = ')';
1959 separator_char = ',';
1960 scale_char = ',';
1962 return print_insn_i386 (pc, info);
1966 print_insn_i386_intel (pc, info)
1967 bfd_vma pc;
1968 disassemble_info *info;
1970 intel_syntax = 1;
1971 open_char = '[';
1972 close_char = ']';
1973 separator_char = '+';
1974 scale_char = '*';
1976 return print_insn_i386 (pc, info);
1979 static int
1980 print_insn_i386 (pc, info)
1981 bfd_vma pc;
1982 disassemble_info *info;
1984 const struct dis386 *dp;
1985 int i;
1986 int two_source_ops;
1987 char *first, *second, *third;
1988 int needcomma;
1989 unsigned char need_modrm;
1990 unsigned char uses_f3_prefix;
1991 int sizeflag;
1993 struct dis_private priv;
1994 bfd_byte *inbuf = priv.the_buffer;
1996 if (info->mach == bfd_mach_i386_i386
1997 || info->mach == bfd_mach_i386_i386_intel_syntax)
1998 sizeflag = AFLAG|DFLAG;
1999 else if (info->mach == bfd_mach_i386_i8086)
2000 sizeflag = 0;
2001 else
2002 abort ();
2004 /* The output looks better if we put 6 bytes on a line, since that
2005 puts most long word instructions on a single line. */
2006 info->bytes_per_line = 6;
2008 info->private_data = (PTR) &priv;
2009 priv.max_fetched = priv.the_buffer;
2010 priv.insn_start = pc;
2011 if (setjmp (priv.bailout) != 0)
2012 /* Error return. */
2013 return -1;
2015 obuf[0] = 0;
2016 op1out[0] = 0;
2017 op2out[0] = 0;
2018 op3out[0] = 0;
2020 op_index[0] = op_index[1] = op_index[2] = -1;
2022 the_info = info;
2023 start_pc = pc;
2024 start_codep = inbuf;
2025 codep = inbuf;
2027 ckprefix ();
2029 insn_codep = codep;
2031 FETCH_DATA (info, codep + 1);
2032 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2034 obufp = obuf;
2036 if ((prefixes & PREFIX_FWAIT)
2037 && ((*codep < 0xd8) || (*codep > 0xdf)))
2039 /* fwait not followed by floating point instruction. */
2040 (*info->fprintf_func) (info->stream, "fwait");
2041 /* There may be other prefixes. Skip any before the fwait. */
2042 return codep - inbuf;
2045 if (*codep == 0x0f)
2047 FETCH_DATA (info, codep + 2);
2048 if (intel_syntax)
2049 dp = &dis386_twobyte_intel[*++codep];
2050 else
2051 dp = &dis386_twobyte_att[*++codep];
2052 need_modrm = twobyte_has_modrm[*codep];
2053 uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
2055 else
2057 if (intel_syntax)
2058 dp = &dis386_intel[*codep];
2059 else
2060 dp = &dis386_att[*codep];
2061 need_modrm = onebyte_has_modrm[*codep];
2062 uses_f3_prefix = 0;
2064 codep++;
2066 if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
2067 oappend ("repz ");
2068 if (prefixes & PREFIX_REPNZ)
2069 oappend ("repnz ");
2070 if (prefixes & PREFIX_LOCK)
2071 oappend ("lock ");
2073 if (prefixes & PREFIX_DATA)
2074 sizeflag ^= DFLAG;
2076 if (prefixes & PREFIX_ADDR)
2078 sizeflag ^= AFLAG;
2079 if (sizeflag & AFLAG)
2080 oappend ("addr32 ");
2081 else
2082 oappend ("addr16 ");
2085 if (need_modrm)
2087 FETCH_DATA (info, codep + 1);
2088 mod = (*codep >> 6) & 3;
2089 reg = (*codep >> 3) & 7;
2090 rm = *codep & 7;
2093 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2095 dofloat (sizeflag);
2097 else
2099 if (dp->name == NULL)
2101 switch(dp->bytemode2)
2103 case USE_GROUPS:
2104 dp = &grps[dp->bytemode1][reg];
2105 break;
2106 case USE_PREFIX_USER_TABLE:
2107 dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
2108 break;
2109 default:
2110 oappend (INTERNAL_DISASSEMBLER_ERROR);
2111 break;
2115 putop (dp->name, sizeflag);
2117 obufp = op1out;
2118 op_ad = 2;
2119 if (dp->op1)
2120 (*dp->op1)(dp->bytemode1, sizeflag);
2122 obufp = op2out;
2123 op_ad = 1;
2124 if (dp->op2)
2125 (*dp->op2)(dp->bytemode2, sizeflag);
2127 obufp = op3out;
2128 op_ad = 0;
2129 if (dp->op3)
2130 (*dp->op3)(dp->bytemode3, sizeflag);
2133 obufp = obuf + strlen (obuf);
2134 for (i = strlen (obuf); i < 6; i++)
2135 oappend (" ");
2136 oappend (" ");
2137 (*info->fprintf_func) (info->stream, "%s", obuf);
2139 /* The enter and bound instructions are printed with operands in the same
2140 order as the intel book; everything else is printed in reverse order. */
2141 if (intel_syntax || two_source_ops)
2143 first = op1out;
2144 second = op2out;
2145 third = op3out;
2146 op_ad = op_index[0];
2147 op_index[0] = op_index[2];
2148 op_index[2] = op_ad;
2150 else
2152 first = op3out;
2153 second = op2out;
2154 third = op1out;
2156 needcomma = 0;
2157 if (*first)
2159 if (op_index[0] != -1)
2160 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2161 else
2162 (*info->fprintf_func) (info->stream, "%s", first);
2163 needcomma = 1;
2165 if (*second)
2167 if (needcomma)
2168 (*info->fprintf_func) (info->stream, ",");
2169 if (op_index[1] != -1)
2170 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2171 else
2172 (*info->fprintf_func) (info->stream, "%s", second);
2173 needcomma = 1;
2175 if (*third)
2177 if (needcomma)
2178 (*info->fprintf_func) (info->stream, ",");
2179 if (op_index[2] != -1)
2180 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2181 else
2182 (*info->fprintf_func) (info->stream, "%s", third);
2184 return codep - inbuf;
2187 static const char *float_mem_att[] = {
2188 /* d8 */
2189 "fadds",
2190 "fmuls",
2191 "fcoms",
2192 "fcomps",
2193 "fsubs",
2194 "fsubrs",
2195 "fdivs",
2196 "fdivrs",
2197 /* d9 */
2198 "flds",
2199 "(bad)",
2200 "fsts",
2201 "fstps",
2202 "fldenv",
2203 "fldcw",
2204 "fNstenv",
2205 "fNstcw",
2206 /* da */
2207 "fiaddl",
2208 "fimull",
2209 "ficoml",
2210 "ficompl",
2211 "fisubl",
2212 "fisubrl",
2213 "fidivl",
2214 "fidivrl",
2215 /* db */
2216 "fildl",
2217 "(bad)",
2218 "fistl",
2219 "fistpl",
2220 "(bad)",
2221 "fldt",
2222 "(bad)",
2223 "fstpt",
2224 /* dc */
2225 "faddl",
2226 "fmull",
2227 "fcoml",
2228 "fcompl",
2229 "fsubl",
2230 "fsubrl",
2231 "fdivl",
2232 "fdivrl",
2233 /* dd */
2234 "fldl",
2235 "(bad)",
2236 "fstl",
2237 "fstpl",
2238 "frstor",
2239 "(bad)",
2240 "fNsave",
2241 "fNstsw",
2242 /* de */
2243 "fiadd",
2244 "fimul",
2245 "ficom",
2246 "ficomp",
2247 "fisub",
2248 "fisubr",
2249 "fidiv",
2250 "fidivr",
2251 /* df */
2252 "fild",
2253 "(bad)",
2254 "fist",
2255 "fistp",
2256 "fbld",
2257 "fildll",
2258 "fbstp",
2259 "fistpll",
2262 static const char *float_mem_intel[] = {
2263 /* d8 */
2264 "fadd",
2265 "fmul",
2266 "fcom",
2267 "fcomp",
2268 "fsub",
2269 "fsubr",
2270 "fdiv",
2271 "fdivr",
2272 /* d9 */
2273 "fld",
2274 "(bad)",
2275 "fst",
2276 "fstp",
2277 "fldenv",
2278 "fldcw",
2279 "fNstenv",
2280 "fNstcw",
2281 /* da */
2282 "fiadd",
2283 "fimul",
2284 "ficom",
2285 "ficomp",
2286 "fisub",
2287 "fisubr",
2288 "fidiv",
2289 "fidivr",
2290 /* db */
2291 "fild",
2292 "(bad)",
2293 "fist",
2294 "fistp",
2295 "(bad)",
2296 "fld",
2297 "(bad)",
2298 "fstp",
2299 /* dc */
2300 "fadd",
2301 "fmul",
2302 "fcom",
2303 "fcomp",
2304 "fsub",
2305 "fsubr",
2306 "fdiv",
2307 "fdivr",
2308 /* dd */
2309 "fld",
2310 "(bad)",
2311 "fst",
2312 "fstp",
2313 "frstor",
2314 "(bad)",
2315 "fNsave",
2316 "fNstsw",
2317 /* de */
2318 "fiadd",
2319 "fimul",
2320 "ficom",
2321 "ficomp",
2322 "fisub",
2323 "fisubr",
2324 "fidiv",
2325 "fidivr",
2326 /* df */
2327 "fild",
2328 "(bad)",
2329 "fist",
2330 "fistp",
2331 "fbld",
2332 "fild",
2333 "fbstp",
2334 "fistpll",
2337 #define ST OP_ST, 0
2338 #define STi OP_STi, 0
2340 #define FGRPd9_2 NULL, NULL, 0
2341 #define FGRPd9_4 NULL, NULL, 1
2342 #define FGRPd9_5 NULL, NULL, 2
2343 #define FGRPd9_6 NULL, NULL, 3
2344 #define FGRPd9_7 NULL, NULL, 4
2345 #define FGRPda_5 NULL, NULL, 5
2346 #define FGRPdb_4 NULL, NULL, 6
2347 #define FGRPde_3 NULL, NULL, 7
2348 #define FGRPdf_4 NULL, NULL, 8
2350 static const struct dis386 float_reg[][8] = {
2351 /* d8 */
2353 { "fadd", ST, STi },
2354 { "fmul", ST, STi },
2355 { "fcom", STi },
2356 { "fcomp", STi },
2357 { "fsub", ST, STi },
2358 { "fsubr", ST, STi },
2359 { "fdiv", ST, STi },
2360 { "fdivr", ST, STi },
2362 /* d9 */
2364 { "fld", STi },
2365 { "fxch", STi },
2366 { FGRPd9_2 },
2367 { "(bad)" },
2368 { FGRPd9_4 },
2369 { FGRPd9_5 },
2370 { FGRPd9_6 },
2371 { FGRPd9_7 },
2373 /* da */
2375 { "fcmovb", ST, STi },
2376 { "fcmove", ST, STi },
2377 { "fcmovbe",ST, STi },
2378 { "fcmovu", ST, STi },
2379 { "(bad)" },
2380 { FGRPda_5 },
2381 { "(bad)" },
2382 { "(bad)" },
2384 /* db */
2386 { "fcmovnb",ST, STi },
2387 { "fcmovne",ST, STi },
2388 { "fcmovnbe",ST, STi },
2389 { "fcmovnu",ST, STi },
2390 { FGRPdb_4 },
2391 { "fucomi", ST, STi },
2392 { "fcomi", ST, STi },
2393 { "(bad)" },
2395 /* dc */
2397 { "fadd", STi, ST },
2398 { "fmul", STi, ST },
2399 { "(bad)" },
2400 { "(bad)" },
2401 #if UNIXWARE_COMPAT
2402 { "fsub", STi, ST },
2403 { "fsubr", STi, ST },
2404 { "fdiv", STi, ST },
2405 { "fdivr", STi, ST },
2406 #else
2407 { "fsubr", STi, ST },
2408 { "fsub", STi, ST },
2409 { "fdivr", STi, ST },
2410 { "fdiv", STi, ST },
2411 #endif
2413 /* dd */
2415 { "ffree", STi },
2416 { "(bad)" },
2417 { "fst", STi },
2418 { "fstp", STi },
2419 { "fucom", STi },
2420 { "fucomp", STi },
2421 { "(bad)" },
2422 { "(bad)" },
2424 /* de */
2426 { "faddp", STi, ST },
2427 { "fmulp", STi, ST },
2428 { "(bad)" },
2429 { FGRPde_3 },
2430 #if UNIXWARE_COMPAT
2431 { "fsubp", STi, ST },
2432 { "fsubrp", STi, ST },
2433 { "fdivp", STi, ST },
2434 { "fdivrp", STi, ST },
2435 #else
2436 { "fsubrp", STi, ST },
2437 { "fsubp", STi, ST },
2438 { "fdivrp", STi, ST },
2439 { "fdivp", STi, ST },
2440 #endif
2442 /* df */
2444 { "(bad)" },
2445 { "(bad)" },
2446 { "(bad)" },
2447 { "(bad)" },
2448 { FGRPdf_4 },
2449 { "fucomip",ST, STi },
2450 { "fcomip", ST, STi },
2451 { "(bad)" },
2456 static char *fgrps[][8] = {
2457 /* d9_2 0 */
2459 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2462 /* d9_4 1 */
2464 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2467 /* d9_5 2 */
2469 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2472 /* d9_6 3 */
2474 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2477 /* d9_7 4 */
2479 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2482 /* da_5 5 */
2484 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2487 /* db_4 6 */
2489 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2490 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2493 /* de_3 7 */
2495 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2498 /* df_4 8 */
2500 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2504 static void
2505 dofloat (sizeflag)
2506 int sizeflag;
2508 const struct dis386 *dp;
2509 unsigned char floatop;
2511 floatop = codep[-1];
2513 if (mod != 3)
2515 if (intel_syntax)
2516 putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2517 else
2518 putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2519 obufp = op1out;
2520 if (floatop == 0xdb)
2521 OP_E (x_mode, sizeflag);
2522 else if (floatop == 0xdd)
2523 OP_E (d_mode, sizeflag);
2524 else
2525 OP_E (v_mode, sizeflag);
2526 return;
2528 codep++;
2530 dp = &float_reg[floatop - 0xd8][reg];
2531 if (dp->name == NULL)
2533 putop (fgrps[dp->bytemode1][rm], sizeflag);
2535 /* instruction fnstsw is only one with strange arg */
2536 if (floatop == 0xdf && codep[-1] == 0xe0)
2537 strcpy (op1out, names16[0]);
2539 else
2541 putop (dp->name, sizeflag);
2543 obufp = op1out;
2544 if (dp->op1)
2545 (*dp->op1)(dp->bytemode1, sizeflag);
2546 obufp = op2out;
2547 if (dp->op2)
2548 (*dp->op2)(dp->bytemode2, sizeflag);
2552 /* ARGSUSED */
2553 static void
2554 OP_ST (ignore, sizeflag)
2555 int ignore;
2556 int sizeflag;
2558 oappend ("%st");
2561 /* ARGSUSED */
2562 static void
2563 OP_STi (ignore, sizeflag)
2564 int ignore;
2565 int sizeflag;
2567 sprintf (scratchbuf, "%%st(%d)", rm);
2568 oappend (scratchbuf);
2572 /* capital letters in template are macros */
2573 static void
2574 putop (template, sizeflag)
2575 const char *template;
2576 int sizeflag;
2578 const char *p;
2580 for (p = template; *p; p++)
2582 switch (*p)
2584 default:
2585 *obufp++ = *p;
2586 break;
2587 case 'A':
2588 if (intel_syntax)
2589 break;
2590 if (mod != 3
2591 #ifdef SUFFIX_ALWAYS
2592 || (sizeflag & SUFFIX_ALWAYS)
2593 #endif
2595 *obufp++ = 'b';
2596 break;
2597 case 'B':
2598 if (intel_syntax)
2599 break;
2600 #ifdef SUFFIX_ALWAYS
2601 if (sizeflag & SUFFIX_ALWAYS)
2602 *obufp++ = 'b';
2603 #endif
2604 break;
2605 case 'E': /* For jcxz/jecxz */
2606 if (sizeflag & AFLAG)
2607 *obufp++ = 'e';
2608 break;
2609 case 'L':
2610 if (intel_syntax)
2611 break;
2612 #ifdef SUFFIX_ALWAYS
2613 if (sizeflag & SUFFIX_ALWAYS)
2614 *obufp++ = 'l';
2615 #endif
2616 break;
2617 case 'N':
2618 if ((prefixes & PREFIX_FWAIT) == 0)
2619 *obufp++ = 'n';
2620 break;
2621 case 'P':
2622 if (intel_syntax)
2623 break;
2624 if ((prefixes & PREFIX_DATA)
2625 #ifdef SUFFIX_ALWAYS
2626 || (sizeflag & SUFFIX_ALWAYS)
2627 #endif
2630 if (sizeflag & DFLAG)
2631 *obufp++ = 'l';
2632 else
2633 *obufp++ = 'w';
2635 break;
2636 case 'Q':
2637 if (intel_syntax)
2638 break;
2639 if (mod != 3
2640 #ifdef SUFFIX_ALWAYS
2641 || (sizeflag & SUFFIX_ALWAYS)
2642 #endif
2645 if (sizeflag & DFLAG)
2646 *obufp++ = 'l';
2647 else
2648 *obufp++ = 'w';
2650 break;
2651 case 'R':
2652 if (intel_syntax)
2654 if (sizeflag & DFLAG)
2656 *obufp++ = 'd';
2657 *obufp++ = 'q';
2659 else
2661 *obufp++ = 'w';
2662 *obufp++ = 'd';
2665 else
2667 if (sizeflag & DFLAG)
2668 *obufp++ = 'l';
2669 else
2670 *obufp++ = 'w';
2672 break;
2673 case 'S':
2674 if (intel_syntax)
2675 break;
2676 #ifdef SUFFIX_ALWAYS
2677 if (sizeflag & SUFFIX_ALWAYS)
2679 if (sizeflag & DFLAG)
2680 *obufp++ = 'l';
2681 else
2682 *obufp++ = 'w';
2684 #endif
2685 break;
2686 case 'W':
2687 /* operand size flag for cwtl, cbtw */
2688 if (sizeflag & DFLAG)
2689 *obufp++ = 'w';
2690 else
2691 *obufp++ = 'b';
2692 if (intel_syntax)
2694 if (sizeflag & DFLAG)
2696 *obufp++ = 'd';
2697 *obufp++ = 'e';
2699 else
2701 *obufp++ = 'w';
2704 break;
2707 *obufp = 0;
2710 static void
2711 oappend (s)
2712 const char *s;
2714 strcpy (obufp, s);
2715 obufp += strlen (s);
2718 static void
2719 append_seg ()
2721 if (prefixes & PREFIX_CS)
2722 oappend ("%cs:");
2723 if (prefixes & PREFIX_DS)
2724 oappend ("%ds:");
2725 if (prefixes & PREFIX_SS)
2726 oappend ("%ss:");
2727 if (prefixes & PREFIX_ES)
2728 oappend ("%es:");
2729 if (prefixes & PREFIX_FS)
2730 oappend ("%fs:");
2731 if (prefixes & PREFIX_GS)
2732 oappend ("%gs:");
2735 static void
2736 OP_indirE (bytemode, sizeflag)
2737 int bytemode;
2738 int sizeflag;
2740 if (!intel_syntax)
2741 oappend ("*");
2742 OP_E (bytemode, sizeflag);
2745 static void
2746 OP_E (bytemode, sizeflag)
2747 int bytemode;
2748 int sizeflag;
2750 int disp;
2752 /* skip mod/rm byte */
2753 codep++;
2755 if (mod == 3)
2757 switch (bytemode)
2759 case b_mode:
2760 oappend (names8[rm]);
2761 break;
2762 case w_mode:
2763 oappend (names16[rm]);
2764 break;
2765 case d_mode:
2766 oappend (names32[rm]);
2767 break;
2768 case v_mode:
2769 if (sizeflag & DFLAG)
2770 oappend (names32[rm]);
2771 else
2772 oappend (names16[rm]);
2773 break;
2774 case 0:
2775 if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */))
2776 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
2777 break;
2778 default:
2779 oappend (INTERNAL_DISASSEMBLER_ERROR);
2780 break;
2782 return;
2785 disp = 0;
2786 append_seg ();
2788 if (sizeflag & AFLAG) /* 32 bit address mode */
2790 int havesib;
2791 int havebase;
2792 int base;
2793 int index = 0;
2794 int scale = 0;
2796 havesib = 0;
2797 havebase = 1;
2798 base = rm;
2800 if (base == 4)
2802 havesib = 1;
2803 FETCH_DATA (the_info, codep + 1);
2804 scale = (*codep >> 6) & 3;
2805 index = (*codep >> 3) & 7;
2806 base = *codep & 7;
2807 codep++;
2810 switch (mod)
2812 case 0:
2813 if (base == 5)
2815 havebase = 0;
2816 disp = get32 ();
2818 break;
2819 case 1:
2820 FETCH_DATA (the_info, codep + 1);
2821 disp = *codep++;
2822 if ((disp & 0x80) != 0)
2823 disp -= 0x100;
2824 break;
2825 case 2:
2826 disp = get32 ();
2827 break;
2830 if (!intel_syntax)
2831 if (mod != 0 || base == 5)
2833 sprintf (scratchbuf, "0x%x", disp);
2834 oappend (scratchbuf);
2837 if (havebase || (havesib && (index != 4 || scale != 0)))
2839 if (intel_syntax)
2841 switch (bytemode)
2843 case b_mode:
2844 oappend("BYTE PTR ");
2845 break;
2846 case w_mode:
2847 oappend("WORD PTR ");
2848 break;
2849 case v_mode:
2850 oappend("DWORD PTR ");
2851 break;
2852 case d_mode:
2853 oappend("QWORD PTR ");
2854 break;
2855 case x_mode:
2856 oappend("XWORD PTR ");
2857 break;
2858 default:
2859 break;
2862 *obufp++ = open_char;
2863 *obufp = '\0';
2864 if (havebase)
2865 oappend (names32[base]);
2866 if (havesib)
2868 if (index != 4)
2870 if (intel_syntax)
2872 if (havebase)
2874 *obufp++ = separator_char;
2875 *obufp = '\0';
2877 sprintf (scratchbuf, "%s", names32[index]);
2879 else
2880 sprintf (scratchbuf, ",%s", names32[index]);
2881 oappend (scratchbuf);
2883 if (!intel_syntax
2884 || (intel_syntax
2885 && bytemode != b_mode
2886 && bytemode != w_mode
2887 && bytemode != v_mode))
2889 *obufp++ = scale_char;
2890 *obufp = '\0';
2891 sprintf (scratchbuf, "%d", 1 << scale);
2892 oappend (scratchbuf);
2895 if (intel_syntax)
2896 if (mod != 0 || base == 5)
2898 /* Don't print zero displacements */
2899 if (disp > 0)
2901 sprintf (scratchbuf, "+%d", disp);
2902 oappend (scratchbuf);
2904 else if (disp < 0)
2906 sprintf (scratchbuf, "%d", disp);
2907 oappend (scratchbuf);
2911 *obufp++ = close_char;
2912 *obufp = '\0';
2914 else if (intel_syntax)
2916 if (mod != 0 || base == 5)
2918 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
2919 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
2921 else
2923 oappend (names_seg[3]);
2924 oappend (":");
2926 sprintf (scratchbuf, "0x%x", disp);
2927 oappend (scratchbuf);
2931 else
2932 { /* 16 bit address mode */
2933 switch (mod)
2935 case 0:
2936 if (rm == 6)
2938 disp = get16 ();
2939 if ((disp & 0x8000) != 0)
2940 disp -= 0x10000;
2942 break;
2943 case 1:
2944 FETCH_DATA (the_info, codep + 1);
2945 disp = *codep++;
2946 if ((disp & 0x80) != 0)
2947 disp -= 0x100;
2948 break;
2949 case 2:
2950 disp = get16 ();
2951 if ((disp & 0x8000) != 0)
2952 disp -= 0x10000;
2953 break;
2956 if (!intel_syntax)
2957 if (mod != 0 || rm == 6)
2959 sprintf (scratchbuf, "%d", disp);
2960 oappend (scratchbuf);
2963 if (mod != 0 || rm != 6)
2965 *obufp++ = open_char;
2966 *obufp = '\0';
2967 oappend (index16[rm]);
2968 *obufp++ = close_char;
2969 *obufp = '\0';
2974 static void
2975 OP_G (bytemode, sizeflag)
2976 int bytemode;
2977 int sizeflag;
2979 switch (bytemode)
2981 case b_mode:
2982 oappend (names8[reg]);
2983 break;
2984 case w_mode:
2985 oappend (names16[reg]);
2986 break;
2987 case d_mode:
2988 oappend (names32[reg]);
2989 break;
2990 case v_mode:
2991 if (sizeflag & DFLAG)
2992 oappend (names32[reg]);
2993 else
2994 oappend (names16[reg]);
2995 break;
2996 default:
2997 oappend (INTERNAL_DISASSEMBLER_ERROR);
2998 break;
3002 static int
3003 get32 ()
3005 int x = 0;
3007 FETCH_DATA (the_info, codep + 4);
3008 x = *codep++ & 0xff;
3009 x |= (*codep++ & 0xff) << 8;
3010 x |= (*codep++ & 0xff) << 16;
3011 x |= (*codep++ & 0xff) << 24;
3012 return x;
3015 static int
3016 get16 ()
3018 int x = 0;
3020 FETCH_DATA (the_info, codep + 2);
3021 x = *codep++ & 0xff;
3022 x |= (*codep++ & 0xff) << 8;
3023 return x;
3026 static void
3027 set_op (op)
3028 unsigned int op;
3030 op_index[op_ad] = op_ad;
3031 op_address[op_ad] = op;
3034 static void
3035 OP_REG (code, sizeflag)
3036 int code;
3037 int sizeflag;
3039 const char *s;
3041 switch (code)
3043 case indir_dx_reg:
3044 s = "(%dx)";
3045 break;
3046 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3047 case sp_reg: case bp_reg: case si_reg: case di_reg:
3048 s = names16[code - ax_reg];
3049 break;
3050 case es_reg: case ss_reg: case cs_reg:
3051 case ds_reg: case fs_reg: case gs_reg:
3052 s = names_seg[code - es_reg];
3053 break;
3054 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3055 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3056 s = names8[code - al_reg];
3057 break;
3058 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3059 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3060 if (sizeflag & DFLAG)
3061 s = names32[code - eAX_reg];
3062 else
3063 s = names16[code - eAX_reg];
3064 break;
3065 default:
3066 s = INTERNAL_DISASSEMBLER_ERROR;
3067 break;
3069 oappend (s);
3072 static void
3073 OP_I (bytemode, sizeflag)
3074 int bytemode;
3075 int sizeflag;
3077 int op;
3079 switch (bytemode)
3081 case b_mode:
3082 FETCH_DATA (the_info, codep + 1);
3083 op = *codep++ & 0xff;
3084 break;
3085 case v_mode:
3086 if (sizeflag & DFLAG)
3087 op = get32 ();
3088 else
3089 op = get16 ();
3090 break;
3091 case w_mode:
3092 op = get16 ();
3093 break;
3094 default:
3095 oappend (INTERNAL_DISASSEMBLER_ERROR);
3096 return;
3099 if (intel_syntax)
3100 sprintf (scratchbuf, "0x%x", op);
3101 else
3102 sprintf (scratchbuf, "$0x%x", op);
3103 oappend (scratchbuf);
3104 scratchbuf[0] = '\0';
3107 static void
3108 OP_sI (bytemode, sizeflag)
3109 int bytemode;
3110 int sizeflag;
3112 int op;
3114 switch (bytemode)
3116 case b_mode:
3117 FETCH_DATA (the_info, codep + 1);
3118 op = *codep++;
3119 if ((op & 0x80) != 0)
3120 op -= 0x100;
3121 break;
3122 case v_mode:
3123 if (sizeflag & DFLAG)
3124 op = get32 ();
3125 else
3127 op = get16();
3128 if ((op & 0x8000) != 0)
3129 op -= 0x10000;
3131 break;
3132 case w_mode:
3133 op = get16 ();
3134 if ((op & 0x8000) != 0)
3135 op -= 0x10000;
3136 break;
3137 default:
3138 oappend (INTERNAL_DISASSEMBLER_ERROR);
3139 return;
3141 if (intel_syntax)
3142 sprintf (scratchbuf, "%d", op);
3143 else
3144 sprintf (scratchbuf, "$0x%x", op);
3145 oappend (scratchbuf);
3148 static void
3149 OP_J (bytemode, sizeflag)
3150 int bytemode;
3151 int sizeflag;
3153 int disp;
3154 int mask = -1;
3156 switch (bytemode)
3158 case b_mode:
3159 FETCH_DATA (the_info, codep + 1);
3160 disp = *codep++;
3161 if ((disp & 0x80) != 0)
3162 disp -= 0x100;
3163 break;
3164 case v_mode:
3165 if (sizeflag & DFLAG)
3166 disp = get32 ();
3167 else
3169 disp = get16 ();
3170 /* for some reason, a data16 prefix on a jump instruction
3171 means that the pc is masked to 16 bits after the
3172 displacement is added! */
3173 mask = 0xffff;
3175 break;
3176 default:
3177 oappend (INTERNAL_DISASSEMBLER_ERROR);
3178 return;
3180 disp = (start_pc + codep - start_codep + disp) & mask;
3181 set_op (disp);
3182 sprintf (scratchbuf, "0x%x", disp);
3183 oappend (scratchbuf);
3186 /* ARGSUSED */
3187 static void
3188 OP_SEG (dummy, sizeflag)
3189 int dummy;
3190 int sizeflag;
3192 static char *sreg[] = {
3193 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3196 oappend (sreg[reg]);
3199 /* ARGSUSED */
3200 static void
3201 OP_DIR (dummy, sizeflag)
3202 int dummy;
3203 int sizeflag;
3205 int seg, offset;
3207 if (sizeflag & DFLAG)
3209 offset = get32 ();
3210 seg = get16 ();
3212 else
3214 offset = get16 ();
3215 seg = get16 ();
3217 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3218 oappend (scratchbuf);
3221 /* ARGSUSED */
3222 static void
3223 OP_OFF (ignore, sizeflag)
3224 int ignore;
3225 int sizeflag;
3227 int off;
3229 append_seg ();
3231 if (sizeflag & AFLAG)
3232 off = get32 ();
3233 else
3234 off = get16 ();
3236 if (intel_syntax)
3238 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3239 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3241 oappend (names_seg[3]);
3242 oappend (":");
3245 sprintf (scratchbuf, "0x%x", off);
3246 oappend (scratchbuf);
3249 static void
3250 ptr_reg (code, sizeflag)
3251 int code;
3252 int sizeflag;
3254 const char *s;
3255 oappend ("(");
3256 if (sizeflag & AFLAG)
3257 s = names32[code - eAX_reg];
3258 else
3259 s = names16[code - eAX_reg];
3260 oappend (s);
3261 oappend (")");
3264 static void
3265 OP_ESreg (code, sizeflag)
3266 int code;
3267 int sizeflag;
3269 oappend ("%es:");
3270 ptr_reg (code, sizeflag);
3273 static void
3274 OP_DSreg (code, sizeflag)
3275 int code;
3276 int sizeflag;
3278 if ((prefixes
3279 & (PREFIX_CS
3280 | PREFIX_DS
3281 | PREFIX_SS
3282 | PREFIX_ES
3283 | PREFIX_FS
3284 | PREFIX_GS)) == 0)
3285 prefixes |= PREFIX_DS;
3286 append_seg();
3287 ptr_reg (code, sizeflag);
3290 /* ARGSUSED */
3291 static void
3292 OP_C (dummy, sizeflag)
3293 int dummy;
3294 int sizeflag;
3296 sprintf (scratchbuf, "%%cr%d", reg);
3297 oappend (scratchbuf);
3300 /* ARGSUSED */
3301 static void
3302 OP_D (dummy, sizeflag)
3303 int dummy;
3304 int sizeflag;
3306 sprintf (scratchbuf, "%%db%d", reg);
3307 oappend (scratchbuf);
3310 /* ARGSUSED */
3311 static void
3312 OP_T (dummy, sizeflag)
3313 int dummy;
3314 int sizeflag;
3316 sprintf (scratchbuf, "%%tr%d", reg);
3317 oappend (scratchbuf);
3320 static void
3321 OP_Rd (bytemode, sizeflag)
3322 int bytemode;
3323 int sizeflag;
3325 if (mod == 3)
3326 OP_E (bytemode, sizeflag);
3327 else
3328 BadOp();
3331 static void
3332 OP_MMX (ignore, sizeflag)
3333 int ignore;
3334 int sizeflag;
3336 sprintf (scratchbuf, "%%mm%d", reg);
3337 oappend (scratchbuf);
3340 static void
3341 OP_XMM (bytemode, sizeflag)
3342 int bytemode;
3343 int sizeflag;
3345 sprintf (scratchbuf, "%%xmm%d", reg);
3346 oappend (scratchbuf);
3349 static void
3350 OP_EM (bytemode, sizeflag)
3351 int bytemode;
3352 int sizeflag;
3354 if (mod != 3)
3356 OP_E (bytemode, sizeflag);
3357 return;
3360 codep++;
3361 sprintf (scratchbuf, "%%mm%d", rm);
3362 oappend (scratchbuf);
3365 static void
3366 OP_EX (bytemode, sizeflag)
3367 int bytemode;
3368 int sizeflag;
3370 if (mod != 3)
3372 OP_E (bytemode, sizeflag);
3373 return;
3376 codep++;
3377 sprintf (scratchbuf, "%%xmm%d", rm);
3378 oappend (scratchbuf);
3381 static void
3382 OP_MS (bytemode, sizeflag)
3383 int bytemode;
3384 int sizeflag;
3386 if (mod == 3)
3387 OP_EM (bytemode, sizeflag);
3388 else
3389 BadOp();
3392 static const char *Suffix3DNow[] = {
3393 /* 00 */ NULL, NULL, NULL, NULL,
3394 /* 04 */ NULL, NULL, NULL, NULL,
3395 /* 08 */ NULL, NULL, NULL, NULL,
3396 /* 0C */ NULL, "pi2fd", NULL, NULL,
3397 /* 10 */ NULL, NULL, NULL, NULL,
3398 /* 14 */ NULL, NULL, NULL, NULL,
3399 /* 18 */ NULL, NULL, NULL, NULL,
3400 /* 1C */ NULL, "pf2id", NULL, NULL,
3401 /* 20 */ NULL, NULL, NULL, NULL,
3402 /* 24 */ NULL, NULL, NULL, NULL,
3403 /* 28 */ NULL, NULL, NULL, NULL,
3404 /* 2C */ NULL, NULL, NULL, NULL,
3405 /* 30 */ NULL, NULL, NULL, NULL,
3406 /* 34 */ NULL, NULL, NULL, NULL,
3407 /* 38 */ NULL, NULL, NULL, NULL,
3408 /* 3C */ NULL, NULL, NULL, NULL,
3409 /* 40 */ NULL, NULL, NULL, NULL,
3410 /* 44 */ NULL, NULL, NULL, NULL,
3411 /* 48 */ NULL, NULL, NULL, NULL,
3412 /* 4C */ NULL, NULL, NULL, NULL,
3413 /* 50 */ NULL, NULL, NULL, NULL,
3414 /* 54 */ NULL, NULL, NULL, NULL,
3415 /* 58 */ NULL, NULL, NULL, NULL,
3416 /* 5C */ NULL, NULL, NULL, NULL,
3417 /* 60 */ NULL, NULL, NULL, NULL,
3418 /* 64 */ NULL, NULL, NULL, NULL,
3419 /* 68 */ NULL, NULL, NULL, NULL,
3420 /* 6C */ NULL, NULL, NULL, NULL,
3421 /* 70 */ NULL, NULL, NULL, NULL,
3422 /* 74 */ NULL, NULL, NULL, NULL,
3423 /* 78 */ NULL, NULL, NULL, NULL,
3424 /* 7C */ NULL, NULL, NULL, NULL,
3425 /* 80 */ NULL, NULL, NULL, NULL,
3426 /* 84 */ NULL, NULL, NULL, NULL,
3427 /* 88 */ NULL, NULL, NULL, NULL,
3428 /* 8C */ NULL, NULL, NULL, NULL,
3429 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3430 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3431 /* 98 */ NULL, NULL, "pfsub", NULL,
3432 /* 9C */ NULL, NULL, "pfadd", NULL,
3433 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3434 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3435 /* A8 */ NULL, NULL, "pfsubr", NULL,
3436 /* AC */ NULL, NULL, "pfacc", NULL,
3437 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3438 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3439 /* B8 */ NULL, NULL, NULL, NULL,
3440 /* BC */ NULL, NULL, NULL, "pavgusb",
3441 /* C0 */ NULL, NULL, NULL, NULL,
3442 /* C4 */ NULL, NULL, NULL, NULL,
3443 /* C8 */ NULL, NULL, NULL, NULL,
3444 /* CC */ NULL, NULL, NULL, NULL,
3445 /* D0 */ NULL, NULL, NULL, NULL,
3446 /* D4 */ NULL, NULL, NULL, NULL,
3447 /* D8 */ NULL, NULL, NULL, NULL,
3448 /* DC */ NULL, NULL, NULL, NULL,
3449 /* E0 */ NULL, NULL, NULL, NULL,
3450 /* E4 */ NULL, NULL, NULL, NULL,
3451 /* E8 */ NULL, NULL, NULL, NULL,
3452 /* EC */ NULL, NULL, NULL, NULL,
3453 /* F0 */ NULL, NULL, NULL, NULL,
3454 /* F4 */ NULL, NULL, NULL, NULL,
3455 /* F8 */ NULL, NULL, NULL, NULL,
3456 /* FC */ NULL, NULL, NULL, NULL,
3459 static void
3460 OP_3DNowSuffix (bytemode, sizeflag)
3461 int bytemode;
3462 int sizeflag;
3464 const char *mnemonic;
3466 FETCH_DATA (the_info, codep + 1);
3467 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3468 place where an 8-bit immediate would normally go. ie. the last
3469 byte of the instruction. */
3470 obufp = obuf + strlen(obuf);
3471 mnemonic = Suffix3DNow[*codep++ & 0xff];
3472 if (mnemonic)
3473 oappend (mnemonic);
3474 else
3476 /* Since a variable sized modrm/sib chunk is between the start
3477 of the opcode (0x0f0f) and the opcode suffix, we need to do
3478 all the modrm processing first, and don't know until now that
3479 we have a bad opcode. This necessitates some cleaning up. */
3480 op1out[0] = '\0';
3481 op2out[0] = '\0';
3482 BadOp();
3487 static const char *simd_cmp_op [] = {
3488 "eq",
3489 "lt",
3490 "le",
3491 "unord",
3492 "neq",
3493 "nlt",
3494 "nle",
3495 "ord"
3498 static void
3499 OP_SIMD_Suffix (bytemode, sizeflag)
3500 int bytemode;
3501 int sizeflag;
3503 unsigned int cmp_type;
3505 FETCH_DATA (the_info, codep + 1);
3506 obufp = obuf + strlen(obuf);
3507 cmp_type = *codep++ & 0xff;
3508 if (cmp_type < 8)
3510 sprintf (scratchbuf, "cmp%s%cs",
3511 simd_cmp_op[cmp_type],
3512 prefixes & PREFIX_REPZ ? 's' : 'p');
3513 oappend (scratchbuf);
3515 else
3517 /* We have a bad extension byte. Clean up. */
3518 op1out[0] = '\0';
3519 op2out[0] = '\0';
3520 BadOp();
3524 static void
3525 SIMD_Fixup (extrachar, sizeflag)
3526 int extrachar;
3527 int sizeflag;
3529 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3530 forms of these instructions. */
3531 if (mod == 3)
3533 char *p = obuf + strlen(obuf);
3534 *(p+1) = '\0';
3535 *p = *(p-1);
3536 *(p-1) = *(p-2);
3537 *(p-2) = *(p-3);
3538 *(p-3) = extrachar;
3542 static void BadOp (void)
3544 codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */
3545 oappend ("(bad)");