1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
25 * modified by John Hassey (hassey@dg-rtp.dg.com)
26 * x86-64 support added by Jan Hubicka (jh@suse.cz)
30 * The main tables describing the instructions is essentially a copy
31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
32 * Programmers Manual. Usually, there is a capital letter, followed
33 * by a small letter. The capital letter tell the addressing mode,
34 * and the small letter tells about the operand size. Refer to
35 * the Intel manual for details.
39 /* #include "sysdep.h" */
40 /* #include "opintl.h" */
49 #ifndef UNIXWARE_COMPAT
50 /* Set non-zero for broken, compatible instructions. Set to zero for
51 non-broken opcodes. */
52 #define UNIXWARE_COMPAT 1
55 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
56 static void ckprefix PARAMS ((void));
57 static const char *prefix_name PARAMS ((int, int));
58 static int print_insn PARAMS ((bfd_vma, disassemble_info *));
59 static void dofloat PARAMS ((int));
60 static void OP_ST PARAMS ((int, int));
61 static void OP_STi PARAMS ((int, int));
62 static int putop PARAMS ((const char *, int));
63 static void oappend PARAMS ((const char *));
64 static void append_seg PARAMS ((void));
65 static void OP_indirE PARAMS ((int, int));
66 static void print_operand_value PARAMS ((char *, int, bfd_vma));
67 static void OP_E PARAMS ((int, int));
68 static void OP_G PARAMS ((int, int));
69 static bfd_vma get64 PARAMS ((void));
70 static bfd_signed_vma get32 PARAMS ((void));
71 static bfd_signed_vma get32s PARAMS ((void));
72 static int get16 PARAMS ((void));
73 static void set_op PARAMS ((bfd_vma, int));
74 static void OP_REG PARAMS ((int, int));
75 static void OP_IMREG PARAMS ((int, int));
76 static void OP_I PARAMS ((int, int));
77 static void OP_I64 PARAMS ((int, int));
78 static void OP_sI PARAMS ((int, int));
79 static void OP_J PARAMS ((int, int));
80 static void OP_SEG PARAMS ((int, int));
81 static void OP_DIR PARAMS ((int, int));
82 static void OP_OFF PARAMS ((int, int));
83 static void OP_OFF64 PARAMS ((int, int));
84 static void ptr_reg PARAMS ((int, int));
85 static void OP_ESreg PARAMS ((int, int));
86 static void OP_DSreg PARAMS ((int, int));
87 static void OP_C PARAMS ((int, int));
88 static void OP_D PARAMS ((int, int));
89 static void OP_T PARAMS ((int, int));
90 static void OP_Rd PARAMS ((int, int));
91 static void OP_MMX PARAMS ((int, int));
92 static void OP_XMM PARAMS ((int, int));
93 static void OP_EM PARAMS ((int, int));
94 static void OP_EX PARAMS ((int, int));
95 static void OP_MS PARAMS ((int, int));
96 static void OP_XS PARAMS ((int, int));
97 static void OP_3DNowSuffix PARAMS ((int, int));
98 static void OP_SIMD_Suffix PARAMS ((int, int));
99 static void SIMD_Fixup PARAMS ((int, int));
100 static void BadOp PARAMS ((void));
103 /* Points to first byte not fetched. */
104 bfd_byte *max_fetched;
105 bfd_byte the_buffer[MAXLEN];
111 /* The opcode for the fwait instruction, which we treat as a prefix
113 #define FWAIT_OPCODE (0x9b)
115 /* Set to 1 for 64bit mode disassembly. */
116 static int mode_64bit;
118 /* Flags for the prefixes for the current instruction. See below. */
121 /* REX prefix the current instruction. See below. */
123 /* Bits of REX we've already used. */
129 /* Mark parts used in the REX prefix. When we are testing for
130 empty prefix (for 8bit register REX extension), just mask it
131 out. Otherwise test for REX bit is excuse for existence of REX
132 only in case value is nonzero. */
133 #define USED_REX(value) \
136 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
141 /* Flags for prefixes which we somehow handled when printing the
142 current instruction. */
143 static int used_prefixes;
145 /* Flags stored in PREFIXES. */
146 #define PREFIX_REPZ 1
147 #define PREFIX_REPNZ 2
148 #define PREFIX_LOCK 4
150 #define PREFIX_SS 0x10
151 #define PREFIX_DS 0x20
152 #define PREFIX_ES 0x40
153 #define PREFIX_FS 0x80
154 #define PREFIX_GS 0x100
155 #define PREFIX_DATA 0x200
156 #define PREFIX_ADDR 0x400
157 #define PREFIX_FWAIT 0x800
159 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
160 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
162 #define FETCH_DATA(info, addr) \
163 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
164 ? 1 : fetch_data ((info), (addr)))
167 fetch_data (info, addr)
168 struct disassemble_info *info;
172 struct dis_private *priv = (struct dis_private *) info->private_data;
173 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
175 status = (*info->read_memory_func) (start,
177 addr - priv->max_fetched,
181 /* If we did manage to read at least one byte, then
182 print_insn_i386 will do something sensible. Otherwise, print
183 an error. We do that here because this is where we know
185 if (priv->max_fetched == priv->the_buffer)
186 (*info->memory_error_func) (status, start, info);
187 longjmp (priv->bailout, 1);
190 priv->max_fetched = addr;
196 #define Eb OP_E, b_mode
197 #define Ev OP_E, v_mode
198 #define Ed OP_E, d_mode
199 #define indirEb OP_indirE, b_mode
200 #define indirEv OP_indirE, v_mode
201 #define Ew OP_E, w_mode
202 #define Ma OP_E, v_mode
203 #define M OP_E, 0 /* lea, lgdt, etc. */
204 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
205 #define Gb OP_G, b_mode
206 #define Gv OP_G, v_mode
207 #define Gd OP_G, d_mode
208 #define Gw OP_G, w_mode
209 #define Rd OP_Rd, d_mode
210 #define Rm OP_Rd, m_mode
211 #define Ib OP_I, b_mode
212 #define sIb OP_sI, b_mode /* sign extened byte */
213 #define Iv OP_I, v_mode
214 #define Iq OP_I, q_mode
215 #define Iv64 OP_I64, v_mode
216 #define Iw OP_I, w_mode
217 #define Jb OP_J, b_mode
218 #define Jv OP_J, v_mode
219 #define Cm OP_C, m_mode
220 #define Dm OP_D, m_mode
221 #define Td OP_T, d_mode
223 #define RMeAX OP_REG, eAX_reg
224 #define RMeBX OP_REG, eBX_reg
225 #define RMeCX OP_REG, eCX_reg
226 #define RMeDX OP_REG, eDX_reg
227 #define RMeSP OP_REG, eSP_reg
228 #define RMeBP OP_REG, eBP_reg
229 #define RMeSI OP_REG, eSI_reg
230 #define RMeDI OP_REG, eDI_reg
231 #define RMrAX OP_REG, rAX_reg
232 #define RMrBX OP_REG, rBX_reg
233 #define RMrCX OP_REG, rCX_reg
234 #define RMrDX OP_REG, rDX_reg
235 #define RMrSP OP_REG, rSP_reg
236 #define RMrBP OP_REG, rBP_reg
237 #define RMrSI OP_REG, rSI_reg
238 #define RMrDI OP_REG, rDI_reg
239 #define RMAL OP_REG, al_reg
240 #define RMAL OP_REG, al_reg
241 #define RMCL OP_REG, cl_reg
242 #define RMDL OP_REG, dl_reg
243 #define RMBL OP_REG, bl_reg
244 #define RMAH OP_REG, ah_reg
245 #define RMCH OP_REG, ch_reg
246 #define RMDH OP_REG, dh_reg
247 #define RMBH OP_REG, bh_reg
248 #define RMAX OP_REG, ax_reg
249 #define RMDX OP_REG, dx_reg
251 #define eAX OP_IMREG, eAX_reg
252 #define eBX OP_IMREG, eBX_reg
253 #define eCX OP_IMREG, eCX_reg
254 #define eDX OP_IMREG, eDX_reg
255 #define eSP OP_IMREG, eSP_reg
256 #define eBP OP_IMREG, eBP_reg
257 #define eSI OP_IMREG, eSI_reg
258 #define eDI OP_IMREG, eDI_reg
259 #define AL OP_IMREG, al_reg
260 #define AL OP_IMREG, al_reg
261 #define CL OP_IMREG, cl_reg
262 #define DL OP_IMREG, dl_reg
263 #define BL OP_IMREG, bl_reg
264 #define AH OP_IMREG, ah_reg
265 #define CH OP_IMREG, ch_reg
266 #define DH OP_IMREG, dh_reg
267 #define BH OP_IMREG, bh_reg
268 #define AX OP_IMREG, ax_reg
269 #define DX OP_IMREG, dx_reg
270 #define indirDX OP_IMREG, indir_dx_reg
272 #define Sw OP_SEG, w_mode
274 #define Ob OP_OFF, b_mode
275 #define Ob64 OP_OFF64, b_mode
276 #define Ov OP_OFF, v_mode
277 #define Ov64 OP_OFF64, v_mode
278 #define Xb OP_DSreg, eSI_reg
279 #define Xv OP_DSreg, eSI_reg
280 #define Yb OP_ESreg, eDI_reg
281 #define Yv OP_ESreg, eDI_reg
282 #define DSBX OP_DSreg, eBX_reg
284 #define es OP_REG, es_reg
285 #define ss OP_REG, ss_reg
286 #define cs OP_REG, cs_reg
287 #define ds OP_REG, ds_reg
288 #define fs OP_REG, fs_reg
289 #define gs OP_REG, gs_reg
293 #define EM OP_EM, v_mode
294 #define EX OP_EX, v_mode
295 #define MS OP_MS, v_mode
296 #define XS OP_XS, v_mode
298 #define OPSUF OP_3DNowSuffix, 0
299 #define OPSIMD OP_SIMD_Suffix, 0
301 #define cond_jump_flag NULL, cond_jump_mode
302 #define loop_jcxz_flag NULL, loop_jcxz_mode
304 /* bits in sizeflag */
305 #define SUFFIX_ALWAYS 4
309 #define b_mode 1 /* byte operand */
310 #define v_mode 2 /* operand size depends on prefixes */
311 #define w_mode 3 /* word operand */
312 #define d_mode 4 /* double word operand */
313 #define q_mode 5 /* quad word operand */
315 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
316 #define cond_jump_mode 8
317 #define loop_jcxz_mode 9
362 #define indir_dx_reg 150
366 #define USE_PREFIX_USER_TABLE 3
367 #define X86_64_SPECIAL 4
369 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
371 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
372 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
373 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
374 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
375 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
376 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
377 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
378 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
379 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
380 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
381 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
382 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
383 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
384 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
385 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
386 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
387 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
388 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
389 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
390 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
391 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
392 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
393 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
395 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
396 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
397 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
398 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
399 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
400 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
401 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
402 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
403 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
404 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
405 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
406 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
407 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
408 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
409 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
410 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
411 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
412 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
413 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
414 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
415 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
416 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
417 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
418 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
419 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
420 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
421 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
423 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
425 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
437 /* Upper case letters in the instruction names here are macros.
438 'A' => print 'b' if no register operands or suffix_always is true
439 'B' => print 'b' if suffix_always is true
440 'E' => print 'e' if 32-bit form of jcxz
441 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
442 'H' => print ",pt" or ",pn" branch hint
443 'L' => print 'l' if suffix_always is true
444 'N' => print 'n' if instruction has no wait "prefix"
445 'O' => print 'd', or 'o'
446 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
447 . or suffix_always is true. print 'q' if rex prefix is present.
448 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
450 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
451 'S' => print 'w', 'l' or 'q' if suffix_always is true
452 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
453 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
454 'X' => print 's', 'd' depending on data16 prefix (for XMM)
455 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
456 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
458 Many of the above letters print nothing in Intel mode. See "putop"
461 Braces '{' and '}', and vertical bars '|', indicate alternative
462 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
463 modes. In cases where there are only two alternatives, the X86_64
464 instruction is reserved, and "(bad)" is printed.
467 static const struct dis386 dis386[] = {
469 { "addB", Eb, Gb, XX },
470 { "addS", Ev, Gv, XX },
471 { "addB", Gb, Eb, XX },
472 { "addS", Gv, Ev, XX },
473 { "addB", AL, Ib, XX },
474 { "addS", eAX, Iv, XX },
475 { "push{T|}", es, XX, XX },
476 { "pop{T|}", es, XX, XX },
478 { "orB", Eb, Gb, XX },
479 { "orS", Ev, Gv, XX },
480 { "orB", Gb, Eb, XX },
481 { "orS", Gv, Ev, XX },
482 { "orB", AL, Ib, XX },
483 { "orS", eAX, Iv, XX },
484 { "push{T|}", cs, XX, XX },
485 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
487 { "adcB", Eb, Gb, XX },
488 { "adcS", Ev, Gv, XX },
489 { "adcB", Gb, Eb, XX },
490 { "adcS", Gv, Ev, XX },
491 { "adcB", AL, Ib, XX },
492 { "adcS", eAX, Iv, XX },
493 { "push{T|}", ss, XX, XX },
494 { "popT|}", ss, XX, XX },
496 { "sbbB", Eb, Gb, XX },
497 { "sbbS", Ev, Gv, XX },
498 { "sbbB", Gb, Eb, XX },
499 { "sbbS", Gv, Ev, XX },
500 { "sbbB", AL, Ib, XX },
501 { "sbbS", eAX, Iv, XX },
502 { "push{T|}", ds, XX, XX },
503 { "pop{T|}", ds, XX, XX },
505 { "andB", Eb, Gb, XX },
506 { "andS", Ev, Gv, XX },
507 { "andB", Gb, Eb, XX },
508 { "andS", Gv, Ev, XX },
509 { "andB", AL, Ib, XX },
510 { "andS", eAX, Iv, XX },
511 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
512 { "daa{|}", XX, XX, XX },
514 { "subB", Eb, Gb, XX },
515 { "subS", Ev, Gv, XX },
516 { "subB", Gb, Eb, XX },
517 { "subS", Gv, Ev, XX },
518 { "subB", AL, Ib, XX },
519 { "subS", eAX, Iv, XX },
520 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
521 { "das{|}", XX, XX, XX },
523 { "xorB", Eb, Gb, XX },
524 { "xorS", Ev, Gv, XX },
525 { "xorB", Gb, Eb, XX },
526 { "xorS", Gv, Ev, XX },
527 { "xorB", AL, Ib, XX },
528 { "xorS", eAX, Iv, XX },
529 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
530 { "aaa{|}", XX, XX, XX },
532 { "cmpB", Eb, Gb, XX },
533 { "cmpS", Ev, Gv, XX },
534 { "cmpB", Gb, Eb, XX },
535 { "cmpS", Gv, Ev, XX },
536 { "cmpB", AL, Ib, XX },
537 { "cmpS", eAX, Iv, XX },
538 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
539 { "aas{|}", XX, XX, XX },
541 { "inc{S|}", RMeAX, XX, XX },
542 { "inc{S|}", RMeCX, XX, XX },
543 { "inc{S|}", RMeDX, XX, XX },
544 { "inc{S|}", RMeBX, XX, XX },
545 { "inc{S|}", RMeSP, XX, XX },
546 { "inc{S|}", RMeBP, XX, XX },
547 { "inc{S|}", RMeSI, XX, XX },
548 { "inc{S|}", RMeDI, XX, XX },
550 { "dec{S|}", RMeAX, XX, XX },
551 { "dec{S|}", RMeCX, XX, XX },
552 { "dec{S|}", RMeDX, XX, XX },
553 { "dec{S|}", RMeBX, XX, XX },
554 { "dec{S|}", RMeSP, XX, XX },
555 { "dec{S|}", RMeBP, XX, XX },
556 { "dec{S|}", RMeSI, XX, XX },
557 { "dec{S|}", RMeDI, XX, XX },
559 { "pushS", RMrAX, XX, XX },
560 { "pushS", RMrCX, XX, XX },
561 { "pushS", RMrDX, XX, XX },
562 { "pushS", RMrBX, XX, XX },
563 { "pushS", RMrSP, XX, XX },
564 { "pushS", RMrBP, XX, XX },
565 { "pushS", RMrSI, XX, XX },
566 { "pushS", RMrDI, XX, XX },
568 { "popS", RMrAX, XX, XX },
569 { "popS", RMrCX, XX, XX },
570 { "popS", RMrDX, XX, XX },
571 { "popS", RMrBX, XX, XX },
572 { "popS", RMrSP, XX, XX },
573 { "popS", RMrBP, XX, XX },
574 { "popS", RMrSI, XX, XX },
575 { "popS", RMrDI, XX, XX },
577 { "pusha{P|}", XX, XX, XX },
578 { "popa{P|}", XX, XX, XX },
579 { "bound{S|}", Gv, Ma, XX },
581 { "(bad)", XX, XX, XX }, /* seg fs */
582 { "(bad)", XX, XX, XX }, /* seg gs */
583 { "(bad)", XX, XX, XX }, /* op size prefix */
584 { "(bad)", XX, XX, XX }, /* adr size prefix */
586 { "pushT", Iq, XX, XX },
587 { "imulS", Gv, Ev, Iv },
588 { "pushT", sIb, XX, XX },
589 { "imulS", Gv, Ev, sIb },
590 { "ins{b||b|}", Yb, indirDX, XX },
591 { "ins{R||R|}", Yv, indirDX, XX },
592 { "outs{b||b|}", indirDX, Xb, XX },
593 { "outs{R||R|}", indirDX, Xv, XX },
595 { "joH", Jb, XX, cond_jump_flag },
596 { "jnoH", Jb, XX, cond_jump_flag },
597 { "jbH", Jb, XX, cond_jump_flag },
598 { "jaeH", Jb, XX, cond_jump_flag },
599 { "jeH", Jb, XX, cond_jump_flag },
600 { "jneH", Jb, XX, cond_jump_flag },
601 { "jbeH", Jb, XX, cond_jump_flag },
602 { "jaH", Jb, XX, cond_jump_flag },
604 { "jsH", Jb, XX, cond_jump_flag },
605 { "jnsH", Jb, XX, cond_jump_flag },
606 { "jpH", Jb, XX, cond_jump_flag },
607 { "jnpH", Jb, XX, cond_jump_flag },
608 { "jlH", Jb, XX, cond_jump_flag },
609 { "jgeH", Jb, XX, cond_jump_flag },
610 { "jleH", Jb, XX, cond_jump_flag },
611 { "jgH", Jb, XX, cond_jump_flag },
615 { "(bad)", XX, XX, XX },
617 { "testB", Eb, Gb, XX },
618 { "testS", Ev, Gv, XX },
619 { "xchgB", Eb, Gb, XX },
620 { "xchgS", Ev, Gv, XX },
622 { "movB", Eb, Gb, XX },
623 { "movS", Ev, Gv, XX },
624 { "movB", Gb, Eb, XX },
625 { "movS", Gv, Ev, XX },
626 { "movQ", Ev, Sw, XX },
627 { "leaS", Gv, M, XX },
628 { "movQ", Sw, Ev, XX },
629 { "popU", Ev, XX, XX },
631 { "nop", XX, XX, XX },
632 /* FIXME: NOP with REPz prefix is called PAUSE. */
633 { "xchgS", RMeCX, eAX, XX },
634 { "xchgS", RMeDX, eAX, XX },
635 { "xchgS", RMeBX, eAX, XX },
636 { "xchgS", RMeSP, eAX, XX },
637 { "xchgS", RMeBP, eAX, XX },
638 { "xchgS", RMeSI, eAX, XX },
639 { "xchgS", RMeDI, eAX, XX },
641 { "cW{tR||tR|}", XX, XX, XX },
642 { "cR{tO||tO|}", XX, XX, XX },
643 { "lcall{T|}", Ap, XX, XX },
644 { "(bad)", XX, XX, XX }, /* fwait */
645 { "pushfT", XX, XX, XX },
646 { "popfT", XX, XX, XX },
647 { "sahf{|}", XX, XX, XX },
648 { "lahf{|}", XX, XX, XX },
650 { "movB", AL, Ob64, XX },
651 { "movS", eAX, Ov64, XX },
652 { "movB", Ob64, AL, XX },
653 { "movS", Ov64, eAX, XX },
654 { "movs{b||b|}", Yb, Xb, XX },
655 { "movs{R||R|}", Yv, Xv, XX },
656 { "cmps{b||b|}", Xb, Yb, XX },
657 { "cmps{R||R|}", Xv, Yv, XX },
659 { "testB", AL, Ib, XX },
660 { "testS", eAX, Iv, XX },
661 { "stosB", Yb, AL, XX },
662 { "stosS", Yv, eAX, XX },
663 { "lodsB", AL, Xb, XX },
664 { "lodsS", eAX, Xv, XX },
665 { "scasB", AL, Yb, XX },
666 { "scasS", eAX, Yv, XX },
668 { "movB", RMAL, Ib, XX },
669 { "movB", RMCL, Ib, XX },
670 { "movB", RMDL, Ib, XX },
671 { "movB", RMBL, Ib, XX },
672 { "movB", RMAH, Ib, XX },
673 { "movB", RMCH, Ib, XX },
674 { "movB", RMDH, Ib, XX },
675 { "movB", RMBH, Ib, XX },
677 { "movS", RMeAX, Iv64, XX },
678 { "movS", RMeCX, Iv64, XX },
679 { "movS", RMeDX, Iv64, XX },
680 { "movS", RMeBX, Iv64, XX },
681 { "movS", RMeSP, Iv64, XX },
682 { "movS", RMeBP, Iv64, XX },
683 { "movS", RMeSI, Iv64, XX },
684 { "movS", RMeDI, Iv64, XX },
688 { "retT", Iw, XX, XX },
689 { "retT", XX, XX, XX },
690 { "les{S|}", Gv, Mp, XX },
691 { "ldsS", Gv, Mp, XX },
692 { "movA", Eb, Ib, XX },
693 { "movQ", Ev, Iv, XX },
695 { "enterT", Iw, Ib, XX },
696 { "leaveT", XX, XX, XX },
697 { "lretP", Iw, XX, XX },
698 { "lretP", XX, XX, XX },
699 { "int3", XX, XX, XX },
700 { "int", Ib, XX, XX },
701 { "into{|}", XX, XX, XX },
702 { "iretP", XX, XX, XX },
708 { "aam{|}", sIb, XX, XX },
709 { "aad{|}", sIb, XX, XX },
710 { "(bad)", XX, XX, XX },
711 { "xlat", DSBX, XX, XX },
722 { "loopneFH", Jb, XX, loop_jcxz_flag },
723 { "loopeFH", Jb, XX, loop_jcxz_flag },
724 { "loopFH", Jb, XX, loop_jcxz_flag },
725 { "jEcxzH", Jb, XX, loop_jcxz_flag },
726 { "inB", AL, Ib, XX },
727 { "inS", eAX, Ib, XX },
728 { "outB", Ib, AL, XX },
729 { "outS", Ib, eAX, XX },
731 { "callT", Jv, XX, XX },
732 { "jmpT", Jv, XX, XX },
733 { "ljmp{T|}", Ap, XX, XX },
734 { "jmp", Jb, XX, XX },
735 { "inB", AL, indirDX, XX },
736 { "inS", eAX, indirDX, XX },
737 { "outB", indirDX, AL, XX },
738 { "outS", indirDX, eAX, XX },
740 { "(bad)", XX, XX, XX }, /* lock prefix */
741 { "(bad)", XX, XX, XX },
742 { "(bad)", XX, XX, XX }, /* repne */
743 { "(bad)", XX, XX, XX }, /* repz */
744 { "hlt", XX, XX, XX },
745 { "cmc", XX, XX, XX },
749 { "clc", XX, XX, XX },
750 { "stc", XX, XX, XX },
751 { "cli", XX, XX, XX },
752 { "sti", XX, XX, XX },
753 { "cld", XX, XX, XX },
754 { "std", XX, XX, XX },
759 static const struct dis386 dis386_twobyte[] = {
763 { "larS", Gv, Ew, XX },
764 { "lslS", Gv, Ew, XX },
765 { "(bad)", XX, XX, XX },
766 { "syscall", XX, XX, XX },
767 { "clts", XX, XX, XX },
768 { "sysretP", XX, XX, XX },
770 { "invd", XX, XX, XX },
771 { "wbinvd", XX, XX, XX },
772 { "(bad)", XX, XX, XX },
773 { "ud2a", XX, XX, XX },
774 { "(bad)", XX, XX, XX },
776 { "femms", XX, XX, XX },
777 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
781 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
782 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
783 { "unpcklpX", XM, EX, XX },
784 { "unpckhpX", XM, EX, XX },
785 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
786 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
789 { "(bad)", XX, XX, XX },
790 { "(bad)", XX, XX, XX },
791 { "(bad)", XX, XX, XX },
792 { "(bad)", XX, XX, XX },
793 { "(bad)", XX, XX, XX },
794 { "(bad)", XX, XX, XX },
795 { "(bad)", XX, XX, XX },
797 { "movL", Rm, Cm, XX },
798 { "movL", Rm, Dm, XX },
799 { "movL", Cm, Rm, XX },
800 { "movL", Dm, Rm, XX },
801 { "movL", Rd, Td, XX },
802 { "(bad)", XX, XX, XX },
803 { "movL", Td, Rd, XX },
804 { "(bad)", XX, XX, XX },
806 { "movapX", XM, EX, XX },
807 { "movapX", EX, XM, XX },
809 { "movntpX", Ev, XM, XX },
812 { "ucomisX", XM,EX, XX },
813 { "comisX", XM,EX, XX },
815 { "wrmsr", XX, XX, XX },
816 { "rdtsc", XX, XX, XX },
817 { "rdmsr", XX, XX, XX },
818 { "rdpmc", XX, XX, XX },
819 { "sysenter", XX, XX, XX },
820 { "sysexit", XX, XX, XX },
821 { "(bad)", XX, XX, XX },
822 { "(bad)", XX, XX, XX },
824 { "(bad)", XX, XX, XX },
825 { "(bad)", XX, XX, XX },
826 { "(bad)", XX, XX, XX },
827 { "(bad)", XX, XX, XX },
828 { "(bad)", XX, XX, XX },
829 { "(bad)", XX, XX, XX },
830 { "(bad)", XX, XX, XX },
831 { "(bad)", XX, XX, XX },
833 { "cmovo", Gv, Ev, XX },
834 { "cmovno", Gv, Ev, XX },
835 { "cmovb", Gv, Ev, XX },
836 { "cmovae", Gv, Ev, XX },
837 { "cmove", Gv, Ev, XX },
838 { "cmovne", Gv, Ev, XX },
839 { "cmovbe", Gv, Ev, XX },
840 { "cmova", Gv, Ev, XX },
842 { "cmovs", Gv, Ev, XX },
843 { "cmovns", Gv, Ev, XX },
844 { "cmovp", Gv, Ev, XX },
845 { "cmovnp", Gv, Ev, XX },
846 { "cmovl", Gv, Ev, XX },
847 { "cmovge", Gv, Ev, XX },
848 { "cmovle", Gv, Ev, XX },
849 { "cmovg", Gv, Ev, XX },
851 { "movmskpX", Gd, XS, XX },
855 { "andpX", XM, EX, XX },
856 { "andnpX", XM, EX, XX },
857 { "orpX", XM, EX, XX },
858 { "xorpX", XM, EX, XX },
869 { "punpcklbw", MX, EM, XX },
870 { "punpcklwd", MX, EM, XX },
871 { "punpckldq", MX, EM, XX },
872 { "packsswb", MX, EM, XX },
873 { "pcmpgtb", MX, EM, XX },
874 { "pcmpgtw", MX, EM, XX },
875 { "pcmpgtd", MX, EM, XX },
876 { "packuswb", MX, EM, XX },
878 { "punpckhbw", MX, EM, XX },
879 { "punpckhwd", MX, EM, XX },
880 { "punpckhdq", MX, EM, XX },
881 { "packssdw", MX, EM, XX },
884 { "movd", MX, Ed, XX },
891 { "pcmpeqb", MX, EM, XX },
892 { "pcmpeqw", MX, EM, XX },
893 { "pcmpeqd", MX, EM, XX },
894 { "emms", XX, XX, XX },
896 { "(bad)", XX, XX, XX },
897 { "(bad)", XX, XX, XX },
898 { "(bad)", XX, XX, XX },
899 { "(bad)", XX, XX, XX },
900 { "(bad)", XX, XX, XX },
901 { "(bad)", XX, XX, XX },
905 { "joH", Jv, XX, cond_jump_flag },
906 { "jnoH", Jv, XX, cond_jump_flag },
907 { "jbH", Jv, XX, cond_jump_flag },
908 { "jaeH", Jv, XX, cond_jump_flag },
909 { "jeH", Jv, XX, cond_jump_flag },
910 { "jneH", Jv, XX, cond_jump_flag },
911 { "jbeH", Jv, XX, cond_jump_flag },
912 { "jaH", Jv, XX, cond_jump_flag },
914 { "jsH", Jv, XX, cond_jump_flag },
915 { "jnsH", Jv, XX, cond_jump_flag },
916 { "jpH", Jv, XX, cond_jump_flag },
917 { "jnpH", Jv, XX, cond_jump_flag },
918 { "jlH", Jv, XX, cond_jump_flag },
919 { "jgeH", Jv, XX, cond_jump_flag },
920 { "jleH", Jv, XX, cond_jump_flag },
921 { "jgH", Jv, XX, cond_jump_flag },
923 { "seto", Eb, XX, XX },
924 { "setno", Eb, XX, XX },
925 { "setb", Eb, XX, XX },
926 { "setae", Eb, XX, XX },
927 { "sete", Eb, XX, XX },
928 { "setne", Eb, XX, XX },
929 { "setbe", Eb, XX, XX },
930 { "seta", Eb, XX, XX },
932 { "sets", Eb, XX, XX },
933 { "setns", Eb, XX, XX },
934 { "setp", Eb, XX, XX },
935 { "setnp", Eb, XX, XX },
936 { "setl", Eb, XX, XX },
937 { "setge", Eb, XX, XX },
938 { "setle", Eb, XX, XX },
939 { "setg", Eb, XX, XX },
941 { "pushT", fs, XX, XX },
942 { "popT", fs, XX, XX },
943 { "cpuid", XX, XX, XX },
944 { "btS", Ev, Gv, XX },
945 { "shldS", Ev, Gv, Ib },
946 { "shldS", Ev, Gv, CL },
947 { "(bad)", XX, XX, XX },
948 { "(bad)", XX, XX, XX },
950 { "pushT", gs, XX, XX },
951 { "popT", gs, XX, XX },
952 { "rsm", XX, XX, XX },
953 { "btsS", Ev, Gv, XX },
954 { "shrdS", Ev, Gv, Ib },
955 { "shrdS", Ev, Gv, CL },
957 { "imulS", Gv, Ev, XX },
959 { "cmpxchgB", Eb, Gb, XX },
960 { "cmpxchgS", Ev, Gv, XX },
961 { "lssS", Gv, Mp, XX },
962 { "btrS", Ev, Gv, XX },
963 { "lfsS", Gv, Mp, XX },
964 { "lgsS", Gv, Mp, XX },
965 { "movz{bR|x|bR|x}", Gv, Eb, XX },
966 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
968 { "(bad)", XX, XX, XX },
969 { "ud2b", XX, XX, XX },
971 { "btcS", Ev, Gv, XX },
972 { "bsfS", Gv, Ev, XX },
973 { "bsrS", Gv, Ev, XX },
974 { "movs{bR|x|bR|x}", Gv, Eb, XX },
975 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
977 { "xaddB", Eb, Gb, XX },
978 { "xaddS", Ev, Gv, XX },
980 { "movntiS", Ev, Gv, XX },
981 { "pinsrw", MX, Ed, Ib },
982 { "pextrw", Gd, MS, Ib },
983 { "shufpX", XM, EX, Ib },
986 { "bswap", RMeAX, XX, XX },
987 { "bswap", RMeCX, XX, XX },
988 { "bswap", RMeDX, XX, XX },
989 { "bswap", RMeBX, XX, XX },
990 { "bswap", RMeSP, XX, XX },
991 { "bswap", RMeBP, XX, XX },
992 { "bswap", RMeSI, XX, XX },
993 { "bswap", RMeDI, XX, XX },
995 { "(bad)", XX, XX, XX },
996 { "psrlw", MX, EM, XX },
997 { "psrld", MX, EM, XX },
998 { "psrlq", MX, EM, XX },
999 { "paddq", MX, EM, XX },
1000 { "pmullw", MX, EM, XX },
1002 { "pmovmskb", Gd, MS, XX },
1004 { "psubusb", MX, EM, XX },
1005 { "psubusw", MX, EM, XX },
1006 { "pminub", MX, EM, XX },
1007 { "pand", MX, EM, XX },
1008 { "paddusb", MX, EM, XX },
1009 { "paddusw", MX, EM, XX },
1010 { "pmaxub", MX, EM, XX },
1011 { "pandn", MX, EM, XX },
1013 { "pavgb", MX, EM, XX },
1014 { "psraw", MX, EM, XX },
1015 { "psrad", MX, EM, XX },
1016 { "pavgw", MX, EM, XX },
1017 { "pmulhuw", MX, EM, XX },
1018 { "pmulhw", MX, EM, XX },
1022 { "psubsb", MX, EM, XX },
1023 { "psubsw", MX, EM, XX },
1024 { "pminsw", MX, EM, XX },
1025 { "por", MX, EM, XX },
1026 { "paddsb", MX, EM, XX },
1027 { "paddsw", MX, EM, XX },
1028 { "pmaxsw", MX, EM, XX },
1029 { "pxor", MX, EM, XX },
1031 { "(bad)", XX, XX, XX },
1032 { "psllw", MX, EM, XX },
1033 { "pslld", MX, EM, XX },
1034 { "psllq", MX, EM, XX },
1035 { "pmuludq", MX, EM, XX },
1036 { "pmaddwd", MX, EM, XX },
1037 { "psadbw", MX, EM, XX },
1040 { "psubb", MX, EM, XX },
1041 { "psubw", MX, EM, XX },
1042 { "psubd", MX, EM, XX },
1043 { "psubq", MX, EM, XX },
1044 { "paddb", MX, EM, XX },
1045 { "paddw", MX, EM, XX },
1046 { "paddd", MX, EM, XX },
1047 { "(bad)", XX, XX, XX }
1050 static const unsigned char onebyte_has_modrm[256] = {
1051 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1052 /* ------------------------------- */
1053 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1054 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1055 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1056 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1057 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1058 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1059 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1060 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1061 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1062 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1063 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1064 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1065 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1066 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1067 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1068 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1069 /* ------------------------------- */
1070 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1073 static const unsigned char twobyte_has_modrm[256] = {
1074 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1075 /* ------------------------------- */
1076 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1077 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1078 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1079 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1080 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1081 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1082 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1083 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1084 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1085 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1086 /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
1087 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1088 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1089 /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1090 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1091 /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1092 /* ------------------------------- */
1093 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1096 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1097 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1098 /* ------------------------------- */
1099 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1100 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1101 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1102 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1103 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1104 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1105 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1106 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1107 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1108 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1109 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1110 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1111 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1112 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1113 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1114 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1115 /* ------------------------------- */
1116 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1119 static char obuf[100];
1121 static char scratchbuf[100];
1122 static unsigned char *start_codep;
1123 static unsigned char *insn_codep;
1124 static unsigned char *codep;
1125 static disassemble_info *the_info;
1129 static unsigned char need_modrm;
1131 /* If we are accessing mod/rm/reg without need_modrm set, then the
1132 values are stale. Hitting this abort likely indicates that you
1133 need to update onebyte_has_modrm or twobyte_has_modrm. */
1134 #define MODRM_CHECK if (!need_modrm) abort ()
1136 static const char **names64;
1137 static const char **names32;
1138 static const char **names16;
1139 static const char **names8;
1140 static const char **names8rex;
1141 static const char **names_seg;
1142 static const char **index16;
1144 static const char *intel_names64[] = {
1145 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1146 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1148 static const char *intel_names32[] = {
1149 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1150 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1152 static const char *intel_names16[] = {
1153 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1154 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1156 static const char *intel_names8[] = {
1157 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1159 static const char *intel_names8rex[] = {
1160 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1161 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1163 static const char *intel_names_seg[] = {
1164 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1166 static const char *intel_index16[] = {
1167 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1170 static const char *att_names64[] = {
1171 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1172 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1174 static const char *att_names32[] = {
1175 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1176 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1178 static const char *att_names16[] = {
1179 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1180 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1182 static const char *att_names8[] = {
1183 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1185 static const char *att_names8rex[] = {
1186 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1187 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1189 static const char *att_names_seg[] = {
1190 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1192 static const char *att_index16[] = {
1193 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1196 static const struct dis386 grps[][8] = {
1199 { "addA", Eb, Ib, XX },
1200 { "orA", Eb, Ib, XX },
1201 { "adcA", Eb, Ib, XX },
1202 { "sbbA", Eb, Ib, XX },
1203 { "andA", Eb, Ib, XX },
1204 { "subA", Eb, Ib, XX },
1205 { "xorA", Eb, Ib, XX },
1206 { "cmpA", Eb, Ib, XX }
1210 { "addQ", Ev, Iv, XX },
1211 { "orQ", Ev, Iv, XX },
1212 { "adcQ", Ev, Iv, XX },
1213 { "sbbQ", Ev, Iv, XX },
1214 { "andQ", Ev, Iv, XX },
1215 { "subQ", Ev, Iv, XX },
1216 { "xorQ", Ev, Iv, XX },
1217 { "cmpQ", Ev, Iv, XX }
1221 { "addQ", Ev, sIb, XX },
1222 { "orQ", Ev, sIb, XX },
1223 { "adcQ", Ev, sIb, XX },
1224 { "sbbQ", Ev, sIb, XX },
1225 { "andQ", Ev, sIb, XX },
1226 { "subQ", Ev, sIb, XX },
1227 { "xorQ", Ev, sIb, XX },
1228 { "cmpQ", Ev, sIb, XX }
1232 { "rolA", Eb, Ib, XX },
1233 { "rorA", Eb, Ib, XX },
1234 { "rclA", Eb, Ib, XX },
1235 { "rcrA", Eb, Ib, XX },
1236 { "shlA", Eb, Ib, XX },
1237 { "shrA", Eb, Ib, XX },
1238 { "(bad)", XX, XX, XX },
1239 { "sarA", Eb, Ib, XX },
1243 { "rolQ", Ev, Ib, XX },
1244 { "rorQ", Ev, Ib, XX },
1245 { "rclQ", Ev, Ib, XX },
1246 { "rcrQ", Ev, Ib, XX },
1247 { "shlQ", Ev, Ib, XX },
1248 { "shrQ", Ev, Ib, XX },
1249 { "(bad)", XX, XX, XX },
1250 { "sarQ", Ev, Ib, XX },
1254 { "rolA", Eb, XX, XX },
1255 { "rorA", Eb, XX, XX },
1256 { "rclA", Eb, XX, XX },
1257 { "rcrA", Eb, XX, XX },
1258 { "shlA", Eb, XX, XX },
1259 { "shrA", Eb, XX, XX },
1260 { "(bad)", XX, XX, XX },
1261 { "sarA", Eb, XX, XX },
1265 { "rolQ", Ev, XX, XX },
1266 { "rorQ", Ev, XX, XX },
1267 { "rclQ", Ev, XX, XX },
1268 { "rcrQ", Ev, XX, XX },
1269 { "shlQ", Ev, XX, XX },
1270 { "shrQ", Ev, XX, XX },
1271 { "(bad)", XX, XX, XX},
1272 { "sarQ", Ev, XX, XX },
1276 { "rolA", Eb, CL, XX },
1277 { "rorA", Eb, CL, XX },
1278 { "rclA", Eb, CL, XX },
1279 { "rcrA", Eb, CL, XX },
1280 { "shlA", Eb, CL, XX },
1281 { "shrA", Eb, CL, XX },
1282 { "(bad)", XX, XX, XX },
1283 { "sarA", Eb, CL, XX },
1287 { "rolQ", Ev, CL, XX },
1288 { "rorQ", Ev, CL, XX },
1289 { "rclQ", Ev, CL, XX },
1290 { "rcrQ", Ev, CL, XX },
1291 { "shlQ", Ev, CL, XX },
1292 { "shrQ", Ev, CL, XX },
1293 { "(bad)", XX, XX, XX },
1294 { "sarQ", Ev, CL, XX }
1298 { "testA", Eb, Ib, XX },
1299 { "(bad)", Eb, XX, XX },
1300 { "notA", Eb, XX, XX },
1301 { "negA", Eb, XX, XX },
1302 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1303 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1304 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1305 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1309 { "testQ", Ev, Iv, XX },
1310 { "(bad)", XX, XX, XX },
1311 { "notQ", Ev, XX, XX },
1312 { "negQ", Ev, XX, XX },
1313 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1314 { "imulQ", Ev, XX, XX },
1315 { "divQ", Ev, XX, XX },
1316 { "idivQ", Ev, XX, XX },
1320 { "incA", Eb, XX, XX },
1321 { "decA", Eb, XX, XX },
1322 { "(bad)", XX, XX, XX },
1323 { "(bad)", XX, XX, XX },
1324 { "(bad)", XX, XX, XX },
1325 { "(bad)", XX, XX, XX },
1326 { "(bad)", XX, XX, XX },
1327 { "(bad)", XX, XX, XX },
1331 { "incQ", Ev, XX, XX },
1332 { "decQ", Ev, XX, XX },
1333 { "callT", indirEv, XX, XX },
1334 { "lcallT", indirEv, XX, XX },
1335 { "jmpT", indirEv, XX, XX },
1336 { "ljmpT", indirEv, XX, XX },
1337 { "pushU", Ev, XX, XX },
1338 { "(bad)", XX, XX, XX },
1342 { "sldtQ", Ev, XX, XX },
1343 { "strQ", Ev, XX, XX },
1344 { "lldt", Ew, XX, XX },
1345 { "ltr", Ew, XX, XX },
1346 { "verr", Ew, XX, XX },
1347 { "verw", Ew, XX, XX },
1348 { "(bad)", XX, XX, XX },
1349 { "(bad)", XX, XX, XX }
1353 { "sgdtQ", M, XX, XX },
1354 { "sidtQ", M, XX, XX },
1355 { "lgdtQ", M, XX, XX },
1356 { "lidtQ", M, XX, XX },
1357 { "smswQ", Ev, XX, XX },
1358 { "(bad)", XX, XX, XX },
1359 { "lmsw", Ew, XX, XX },
1360 { "invlpg", Ew, XX, XX },
1364 { "(bad)", XX, XX, XX },
1365 { "(bad)", XX, XX, XX },
1366 { "(bad)", XX, XX, XX },
1367 { "(bad)", XX, XX, XX },
1368 { "btQ", Ev, Ib, XX },
1369 { "btsQ", Ev, Ib, XX },
1370 { "btrQ", Ev, Ib, XX },
1371 { "btcQ", Ev, Ib, XX },
1375 { "(bad)", XX, XX, XX },
1376 { "cmpxchg8b", Ev, XX, XX },
1377 { "(bad)", XX, XX, XX },
1378 { "(bad)", XX, XX, XX },
1379 { "(bad)", XX, XX, XX },
1380 { "(bad)", XX, XX, XX },
1381 { "(bad)", XX, XX, XX },
1382 { "(bad)", XX, XX, XX },
1386 { "(bad)", XX, XX, XX },
1387 { "(bad)", XX, XX, XX },
1388 { "psrlw", MS, Ib, XX },
1389 { "(bad)", XX, XX, XX },
1390 { "psraw", MS, Ib, XX },
1391 { "(bad)", XX, XX, XX },
1392 { "psllw", MS, Ib, XX },
1393 { "(bad)", XX, XX, XX },
1397 { "(bad)", XX, XX, XX },
1398 { "(bad)", XX, XX, XX },
1399 { "psrld", MS, Ib, XX },
1400 { "(bad)", XX, XX, XX },
1401 { "psrad", MS, Ib, XX },
1402 { "(bad)", XX, XX, XX },
1403 { "pslld", MS, Ib, XX },
1404 { "(bad)", XX, XX, XX },
1408 { "(bad)", XX, XX, XX },
1409 { "(bad)", XX, XX, XX },
1410 { "psrlq", MS, Ib, XX },
1411 { "psrldq", MS, Ib, XX },
1412 { "(bad)", XX, XX, XX },
1413 { "(bad)", XX, XX, XX },
1414 { "psllq", MS, Ib, XX },
1415 { "pslldq", MS, Ib, XX },
1419 { "fxsave", Ev, XX, XX },
1420 { "fxrstor", Ev, XX, XX },
1421 { "ldmxcsr", Ev, XX, XX },
1422 { "stmxcsr", Ev, XX, XX },
1423 { "(bad)", XX, XX, XX },
1424 { "lfence", None, XX, XX },
1425 { "mfence", None, XX, XX },
1426 { "sfence", None, XX, XX },
1427 /* FIXME: the sfence with memory operand is clflush! */
1431 { "prefetchnta", Ev, XX, XX },
1432 { "prefetcht0", Ev, XX, XX },
1433 { "prefetcht1", Ev, XX, XX },
1434 { "prefetcht2", Ev, XX, XX },
1435 { "(bad)", XX, XX, XX },
1436 { "(bad)", XX, XX, XX },
1437 { "(bad)", XX, XX, XX },
1438 { "(bad)", XX, XX, XX },
1442 { "prefetch", Eb, XX, XX },
1443 { "prefetchw", Eb, XX, XX },
1444 { "(bad)", XX, XX, XX },
1445 { "(bad)", XX, XX, XX },
1446 { "(bad)", XX, XX, XX },
1447 { "(bad)", XX, XX, XX },
1448 { "(bad)", XX, XX, XX },
1449 { "(bad)", XX, XX, XX },
1453 static const struct dis386 prefix_user_table[][4] = {
1456 { "addps", XM, EX, XX },
1457 { "addss", XM, EX, XX },
1458 { "addpd", XM, EX, XX },
1459 { "addsd", XM, EX, XX },
1463 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1464 { "", XM, EX, OPSIMD },
1465 { "", XM, EX, OPSIMD },
1466 { "", XM, EX, OPSIMD },
1470 { "cvtpi2ps", XM, EM, XX },
1471 { "cvtsi2ssY", XM, Ev, XX },
1472 { "cvtpi2pd", XM, EM, XX },
1473 { "cvtsi2sdY", XM, Ev, XX },
1477 { "cvtps2pi", MX, EX, XX },
1478 { "cvtss2siY", Gv, EX, XX },
1479 { "cvtpd2pi", MX, EX, XX },
1480 { "cvtsd2siY", Gv, EX, XX },
1484 { "cvttps2pi", MX, EX, XX },
1485 { "cvttss2siY", Gv, EX, XX },
1486 { "cvttpd2pi", MX, EX, XX },
1487 { "cvttsd2siY", Gv, EX, XX },
1491 { "divps", XM, EX, XX },
1492 { "divss", XM, EX, XX },
1493 { "divpd", XM, EX, XX },
1494 { "divsd", XM, EX, XX },
1498 { "maxps", XM, EX, XX },
1499 { "maxss", XM, EX, XX },
1500 { "maxpd", XM, EX, XX },
1501 { "maxsd", XM, EX, XX },
1505 { "minps", XM, EX, XX },
1506 { "minss", XM, EX, XX },
1507 { "minpd", XM, EX, XX },
1508 { "minsd", XM, EX, XX },
1512 { "movups", XM, EX, XX },
1513 { "movss", XM, EX, XX },
1514 { "movupd", XM, EX, XX },
1515 { "movsd", XM, EX, XX },
1519 { "movups", EX, XM, XX },
1520 { "movss", EX, XM, XX },
1521 { "movupd", EX, XM, XX },
1522 { "movsd", EX, XM, XX },
1526 { "mulps", XM, EX, XX },
1527 { "mulss", XM, EX, XX },
1528 { "mulpd", XM, EX, XX },
1529 { "mulsd", XM, EX, XX },
1533 { "rcpps", XM, EX, XX },
1534 { "rcpss", XM, EX, XX },
1535 { "(bad)", XM, EX, XX },
1536 { "(bad)", XM, EX, XX },
1540 { "rsqrtps", XM, EX, XX },
1541 { "rsqrtss", XM, EX, XX },
1542 { "(bad)", XM, EX, XX },
1543 { "(bad)", XM, EX, XX },
1547 { "sqrtps", XM, EX, XX },
1548 { "sqrtss", XM, EX, XX },
1549 { "sqrtpd", XM, EX, XX },
1550 { "sqrtsd", XM, EX, XX },
1554 { "subps", XM, EX, XX },
1555 { "subss", XM, EX, XX },
1556 { "subpd", XM, EX, XX },
1557 { "subsd", XM, EX, XX },
1561 { "(bad)", XM, EX, XX },
1562 { "cvtdq2pd", XM, EX, XX },
1563 { "cvttpd2dq", XM, EX, XX },
1564 { "cvtpd2dq", XM, EX, XX },
1568 { "cvtdq2ps", XM, EX, XX },
1569 { "cvttps2dq",XM, EX, XX },
1570 { "cvtps2dq",XM, EX, XX },
1571 { "(bad)", XM, EX, XX },
1575 { "cvtps2pd", XM, EX, XX },
1576 { "cvtss2sd", XM, EX, XX },
1577 { "cvtpd2ps", XM, EX, XX },
1578 { "cvtsd2ss", XM, EX, XX },
1582 { "maskmovq", MX, MS, XX },
1583 { "(bad)", XM, EX, XX },
1584 { "maskmovdqu", XM, EX, XX },
1585 { "(bad)", XM, EX, XX },
1589 { "movq", MX, EM, XX },
1590 { "movdqu", XM, EX, XX },
1591 { "movdqa", XM, EX, XX },
1592 { "(bad)", XM, EX, XX },
1596 { "movq", EM, MX, XX },
1597 { "movdqu", EX, XM, XX },
1598 { "movdqa", EX, XM, XX },
1599 { "(bad)", EX, XM, XX },
1603 { "(bad)", EX, XM, XX },
1604 { "movq2dq", XM, MS, XX },
1605 { "movq", EX, XM, XX },
1606 { "movdq2q", MX, XS, XX },
1610 { "pshufw", MX, EM, Ib },
1611 { "pshufhw", XM, EX, Ib },
1612 { "pshufd", XM, EX, Ib },
1613 { "pshuflw", XM, EX, Ib },
1617 { "movd", Ed, MX, XX },
1618 { "movq", XM, EX, XX },
1619 { "movd", Ed, XM, XX },
1620 { "(bad)", Ed, XM, XX },
1624 { "(bad)", MX, EX, XX },
1625 { "(bad)", XM, EX, XX },
1626 { "punpckhqdq", XM, EX, XX },
1627 { "(bad)", XM, EX, XX },
1631 { "movntq", Ev, MX, XX },
1632 { "(bad)", Ev, XM, XX },
1633 { "movntdq", Ev, XM, XX },
1634 { "(bad)", Ev, XM, XX },
1638 { "(bad)", MX, EX, XX },
1639 { "(bad)", XM, EX, XX },
1640 { "punpcklqdq", XM, EX, XX },
1641 { "(bad)", XM, EX, XX },
1645 static const struct dis386 x86_64_table[][2] = {
1647 { "arpl", Ew, Gw, XX },
1648 { "movs{||lq|xd}", Gv, Ed, XX },
1652 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1664 FETCH_DATA (the_info, codep + 1);
1668 /* REX prefixes family. */
1691 prefixes |= PREFIX_REPZ;
1694 prefixes |= PREFIX_REPNZ;
1697 prefixes |= PREFIX_LOCK;
1700 prefixes |= PREFIX_CS;
1703 prefixes |= PREFIX_SS;
1706 prefixes |= PREFIX_DS;
1709 prefixes |= PREFIX_ES;
1712 prefixes |= PREFIX_FS;
1715 prefixes |= PREFIX_GS;
1718 prefixes |= PREFIX_DATA;
1721 prefixes |= PREFIX_ADDR;
1724 /* fwait is really an instruction. If there are prefixes
1725 before the fwait, they belong to the fwait, *not* to the
1726 following instruction. */
1729 prefixes |= PREFIX_FWAIT;
1733 prefixes = PREFIX_FWAIT;
1738 /* Rex is ignored when followed by another prefix. */
1741 oappend (prefix_name (rex, 0));
1749 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1753 prefix_name (pref, sizeflag)
1759 /* REX prefixes family. */
1811 return (sizeflag & DFLAG) ? "data16" : "data32";
1814 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1816 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1824 static char op1out[100], op2out[100], op3out[100];
1825 static int op_ad, op_index[3];
1826 static bfd_vma op_address[3];
1827 static bfd_vma op_riprel[3];
1828 static bfd_vma start_pc;
1831 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1832 * (see topic "Redundant prefixes" in the "Differences from 8086"
1833 * section of the "Virtual 8086 Mode" chapter.)
1834 * 'pc' should be the address of this instruction, it will
1835 * be used to print the target address if this is a relative jump or call
1836 * The function returns the length of this instruction in bytes.
1839 static char intel_syntax;
1840 static char open_char;
1841 static char close_char;
1842 static char separator_char;
1843 static char scale_char;
1845 /* Here for backwards compatibility. When gdb stops using
1846 print_insn_i386_att and print_insn_i386_intel these functions can
1847 disappear, and print_insn_i386 be merged into print_insn. */
1849 print_insn_i386_att (pc, info)
1851 disassemble_info *info;
1855 return print_insn (pc, info);
1859 print_insn_i386_intel (pc, info)
1861 disassemble_info *info;
1865 return print_insn (pc, info);
1869 print_insn_i386 (pc, info)
1871 disassemble_info *info;
1875 return print_insn (pc, info);
1879 print_insn (pc, info)
1881 disassemble_info *info;
1883 const struct dis386 *dp;
1886 char *first, *second, *third;
1888 unsigned char uses_SSE_prefix;
1891 struct dis_private priv;
1893 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1894 || info->mach == bfd_mach_x86_64);
1896 if (intel_syntax == -1)
1897 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1898 || info->mach == bfd_mach_x86_64_intel_syntax);
1900 if (info->mach == bfd_mach_i386_i386
1901 || info->mach == bfd_mach_x86_64
1902 || info->mach == bfd_mach_i386_i386_intel_syntax
1903 || info->mach == bfd_mach_x86_64_intel_syntax)
1904 priv.orig_sizeflag = AFLAG | DFLAG;
1905 else if (info->mach == bfd_mach_i386_i8086)
1906 priv.orig_sizeflag = 0;
1910 for (p = info->disassembler_options; p != NULL; )
1912 if (strncmp (p, "x86-64", 6) == 0)
1915 priv.orig_sizeflag = AFLAG | DFLAG;
1917 else if (strncmp (p, "i386", 4) == 0)
1920 priv.orig_sizeflag = AFLAG | DFLAG;
1922 else if (strncmp (p, "i8086", 5) == 0)
1925 priv.orig_sizeflag = 0;
1927 else if (strncmp (p, "intel", 5) == 0)
1931 else if (strncmp (p, "att", 3) == 0)
1935 else if (strncmp (p, "addr", 4) == 0)
1937 if (p[4] == '1' && p[5] == '6')
1938 priv.orig_sizeflag &= ~AFLAG;
1939 else if (p[4] == '3' && p[5] == '2')
1940 priv.orig_sizeflag |= AFLAG;
1942 else if (strncmp (p, "data", 4) == 0)
1944 if (p[4] == '1' && p[5] == '6')
1945 priv.orig_sizeflag &= ~DFLAG;
1946 else if (p[4] == '3' && p[5] == '2')
1947 priv.orig_sizeflag |= DFLAG;
1949 else if (strncmp (p, "suffix", 6) == 0)
1950 priv.orig_sizeflag |= SUFFIX_ALWAYS;
1952 p = strchr (p, ',');
1959 names64 = intel_names64;
1960 names32 = intel_names32;
1961 names16 = intel_names16;
1962 names8 = intel_names8;
1963 names8rex = intel_names8rex;
1964 names_seg = intel_names_seg;
1965 index16 = intel_index16;
1968 separator_char = '+';
1973 names64 = att_names64;
1974 names32 = att_names32;
1975 names16 = att_names16;
1976 names8 = att_names8;
1977 names8rex = att_names8rex;
1978 names_seg = att_names_seg;
1979 index16 = att_index16;
1982 separator_char = ',';
1986 /* The output looks better if we put 7 bytes on a line, since that
1987 puts most long word instructions on a single line. */
1988 info->bytes_per_line = 7;
1990 info->private_data = (PTR) &priv;
1991 priv.max_fetched = priv.the_buffer;
1992 priv.insn_start = pc;
1999 op_index[0] = op_index[1] = op_index[2] = -1;
2003 start_codep = priv.the_buffer;
2004 codep = priv.the_buffer;
2006 if (setjmp (priv.bailout) != 0)
2010 /* Getting here means we tried for data but didn't get it. That
2011 means we have an incomplete instruction of some sort. Just
2012 print the first byte as a prefix or a .byte pseudo-op. */
2013 if (codep > priv.the_buffer)
2015 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2017 (*info->fprintf_func) (info->stream, "%s", name);
2020 /* Just print the first byte as a .byte instruction. */
2021 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2022 (unsigned int) priv.the_buffer[0]);
2035 sizeflag = priv.orig_sizeflag;
2037 FETCH_DATA (info, codep + 1);
2038 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2040 if ((prefixes & PREFIX_FWAIT)
2041 && ((*codep < 0xd8) || (*codep > 0xdf)))
2045 /* fwait not followed by floating point instruction. Print the
2046 first prefix, which is probably fwait itself. */
2047 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2049 name = INTERNAL_DISASSEMBLER_ERROR;
2050 (*info->fprintf_func) (info->stream, "%s", name);
2056 FETCH_DATA (info, codep + 2);
2057 dp = &dis386_twobyte[*++codep];
2058 need_modrm = twobyte_has_modrm[*codep];
2059 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2063 dp = &dis386[*codep];
2064 need_modrm = onebyte_has_modrm[*codep];
2065 uses_SSE_prefix = 0;
2069 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2072 used_prefixes |= PREFIX_REPZ;
2074 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2077 used_prefixes |= PREFIX_REPNZ;
2079 if (prefixes & PREFIX_LOCK)
2082 used_prefixes |= PREFIX_LOCK;
2085 if (prefixes & PREFIX_ADDR)
2088 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2090 if ((sizeflag & AFLAG) || mode_64bit)
2091 oappend ("addr32 ");
2093 oappend ("addr16 ");
2094 used_prefixes |= PREFIX_ADDR;
2098 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2101 if (dp->bytemode3 == cond_jump_mode
2102 && dp->bytemode1 == v_mode
2105 if (sizeflag & DFLAG)
2106 oappend ("data32 ");
2108 oappend ("data16 ");
2109 used_prefixes |= PREFIX_DATA;
2115 FETCH_DATA (info, codep + 1);
2116 mod = (*codep >> 6) & 3;
2117 reg = (*codep >> 3) & 7;
2121 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2128 if (dp->name == NULL)
2130 switch (dp->bytemode1)
2133 dp = &grps[dp->bytemode2][reg];
2136 case USE_PREFIX_USER_TABLE:
2138 used_prefixes |= (prefixes & PREFIX_REPZ);
2139 if (prefixes & PREFIX_REPZ)
2143 used_prefixes |= (prefixes & PREFIX_DATA);
2144 if (prefixes & PREFIX_DATA)
2148 used_prefixes |= (prefixes & PREFIX_REPNZ);
2149 if (prefixes & PREFIX_REPNZ)
2153 dp = &prefix_user_table[dp->bytemode2][index];
2156 case X86_64_SPECIAL:
2157 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2161 oappend (INTERNAL_DISASSEMBLER_ERROR);
2166 if (putop (dp->name, sizeflag) == 0)
2171 (*dp->op1) (dp->bytemode1, sizeflag);
2176 (*dp->op2) (dp->bytemode2, sizeflag);
2181 (*dp->op3) (dp->bytemode3, sizeflag);
2185 /* See if any prefixes were not used. If so, print the first one
2186 separately. If we don't do this, we'll wind up printing an
2187 instruction stream which does not precisely correspond to the
2188 bytes we are disassembling. */
2189 if ((prefixes & ~used_prefixes) != 0)
2193 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2195 name = INTERNAL_DISASSEMBLER_ERROR;
2196 (*info->fprintf_func) (info->stream, "%s", name);
2199 if (rex & ~rex_used)
2202 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2204 name = INTERNAL_DISASSEMBLER_ERROR;
2205 (*info->fprintf_func) (info->stream, "%s ", name);
2208 obufp = obuf + strlen (obuf);
2209 for (i = strlen (obuf); i < 6; i++)
2212 (*info->fprintf_func) (info->stream, "%s", obuf);
2214 /* The enter and bound instructions are printed with operands in the same
2215 order as the intel book; everything else is printed in reverse order. */
2216 if (intel_syntax || two_source_ops)
2221 op_ad = op_index[0];
2222 op_index[0] = op_index[2];
2223 op_index[2] = op_ad;
2234 if (op_index[0] != -1 && !op_riprel[0])
2235 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2237 (*info->fprintf_func) (info->stream, "%s", first);
2243 (*info->fprintf_func) (info->stream, ",");
2244 if (op_index[1] != -1 && !op_riprel[1])
2245 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2247 (*info->fprintf_func) (info->stream, "%s", second);
2253 (*info->fprintf_func) (info->stream, ",");
2254 if (op_index[2] != -1 && !op_riprel[2])
2255 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2257 (*info->fprintf_func) (info->stream, "%s", third);
2259 for (i = 0; i < 3; i++)
2260 if (op_index[i] != -1 && op_riprel[i])
2262 (*info->fprintf_func) (info->stream, " # ");
2263 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2264 + op_address[op_index[i]]), info);
2266 return codep - priv.the_buffer;
2269 static const char *float_mem[] = {
2345 #define STi OP_STi, 0
2347 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2348 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2349 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2350 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2351 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2352 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2353 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2354 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2355 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2357 static const struct dis386 float_reg[][8] = {
2360 { "fadd", ST, STi, XX },
2361 { "fmul", ST, STi, XX },
2362 { "fcom", STi, XX, XX },
2363 { "fcomp", STi, XX, XX },
2364 { "fsub", ST, STi, XX },
2365 { "fsubr", ST, STi, XX },
2366 { "fdiv", ST, STi, XX },
2367 { "fdivr", ST, STi, XX },
2371 { "fld", STi, XX, XX },
2372 { "fxch", STi, XX, XX },
2374 { "(bad)", XX, XX, XX },
2382 { "fcmovb", ST, STi, XX },
2383 { "fcmove", ST, STi, XX },
2384 { "fcmovbe",ST, STi, XX },
2385 { "fcmovu", ST, STi, XX },
2386 { "(bad)", XX, XX, XX },
2388 { "(bad)", XX, XX, XX },
2389 { "(bad)", XX, XX, XX },
2393 { "fcmovnb",ST, STi, XX },
2394 { "fcmovne",ST, STi, XX },
2395 { "fcmovnbe",ST, STi, XX },
2396 { "fcmovnu",ST, STi, XX },
2398 { "fucomi", ST, STi, XX },
2399 { "fcomi", ST, STi, XX },
2400 { "(bad)", XX, XX, XX },
2404 { "fadd", STi, ST, XX },
2405 { "fmul", STi, ST, XX },
2406 { "(bad)", XX, XX, XX },
2407 { "(bad)", XX, XX, XX },
2409 { "fsub", STi, ST, XX },
2410 { "fsubr", STi, ST, XX },
2411 { "fdiv", STi, ST, XX },
2412 { "fdivr", STi, ST, XX },
2414 { "fsubr", STi, ST, XX },
2415 { "fsub", STi, ST, XX },
2416 { "fdivr", STi, ST, XX },
2417 { "fdiv", STi, ST, XX },
2422 { "ffree", STi, XX, XX },
2423 { "(bad)", XX, XX, XX },
2424 { "fst", STi, XX, XX },
2425 { "fstp", STi, XX, XX },
2426 { "fucom", STi, XX, XX },
2427 { "fucomp", STi, XX, XX },
2428 { "(bad)", XX, XX, XX },
2429 { "(bad)", XX, XX, XX },
2433 { "faddp", STi, ST, XX },
2434 { "fmulp", STi, ST, XX },
2435 { "(bad)", XX, XX, XX },
2438 { "fsubp", STi, ST, XX },
2439 { "fsubrp", STi, ST, XX },
2440 { "fdivp", STi, ST, XX },
2441 { "fdivrp", STi, ST, XX },
2443 { "fsubrp", STi, ST, XX },
2444 { "fsubp", STi, ST, XX },
2445 { "fdivrp", STi, ST, XX },
2446 { "fdivp", STi, ST, XX },
2451 { "ffreep", STi, XX, XX },
2452 { "(bad)", XX, XX, XX },
2453 { "(bad)", XX, XX, XX },
2454 { "(bad)", XX, XX, XX },
2456 { "fucomip",ST, STi, XX },
2457 { "fcomip", ST, STi, XX },
2458 { "(bad)", XX, XX, XX },
2462 static char *fgrps[][8] = {
2465 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2470 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2475 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2480 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2485 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2490 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2495 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2496 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2501 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2506 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2514 const struct dis386 *dp;
2515 unsigned char floatop;
2517 floatop = codep[-1];
2521 putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
2523 if (floatop == 0xdb)
2524 OP_E (x_mode, sizeflag);
2525 else if (floatop == 0xdd)
2526 OP_E (d_mode, sizeflag);
2528 OP_E (v_mode, sizeflag);
2531 /* Skip mod/rm byte. */
2535 dp = &float_reg[floatop - 0xd8][reg];
2536 if (dp->name == NULL)
2538 putop (fgrps[dp->bytemode1][rm], sizeflag);
2540 /* Instruction fnstsw is only one with strange arg. */
2541 if (floatop == 0xdf && codep[-1] == 0xe0)
2542 strcpy (op1out, names16[0]);
2546 putop (dp->name, sizeflag);
2550 (*dp->op1) (dp->bytemode1, sizeflag);
2553 (*dp->op2) (dp->bytemode2, sizeflag);
2558 OP_ST (bytemode, sizeflag)
2559 int bytemode ATTRIBUTE_UNUSED;
2560 int sizeflag ATTRIBUTE_UNUSED;
2566 OP_STi (bytemode, sizeflag)
2567 int bytemode ATTRIBUTE_UNUSED;
2568 int sizeflag ATTRIBUTE_UNUSED;
2570 sprintf (scratchbuf, "%%st(%d)", rm);
2571 oappend (scratchbuf + intel_syntax);
2574 /* Capital letters in template are macros. */
2576 putop (template, sizeflag)
2577 const char *template;
2583 for (p = template; *p; p++)
2602 /* Alternative not valid. */
2603 strcpy (obuf, "(bad)");
2607 else if (*p == '\0')
2625 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2631 if (sizeflag & SUFFIX_ALWAYS)
2634 case 'E': /* For jcxz/jecxz */
2637 if (sizeflag & AFLAG)
2643 if (sizeflag & AFLAG)
2645 used_prefixes |= (prefixes & PREFIX_ADDR);
2650 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2652 if (sizeflag & AFLAG)
2653 *obufp++ = mode_64bit ? 'q' : 'l';
2655 *obufp++ = mode_64bit ? 'l' : 'w';
2656 used_prefixes |= (prefixes & PREFIX_ADDR);
2662 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2663 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2665 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2668 if (prefixes & PREFIX_DS)
2677 if (sizeflag & SUFFIX_ALWAYS)
2681 if ((prefixes & PREFIX_FWAIT) == 0)
2684 used_prefixes |= PREFIX_FWAIT;
2687 USED_REX (REX_MODE64);
2688 if (rex & REX_MODE64)
2705 if ((prefixes & PREFIX_DATA)
2706 || (rex & REX_MODE64)
2707 || (sizeflag & SUFFIX_ALWAYS))
2709 USED_REX (REX_MODE64);
2710 if (rex & REX_MODE64)
2714 if (sizeflag & DFLAG)
2718 used_prefixes |= (prefixes & PREFIX_DATA);
2734 USED_REX (REX_MODE64);
2735 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2737 if (rex & REX_MODE64)
2741 if (sizeflag & DFLAG)
2745 used_prefixes |= (prefixes & PREFIX_DATA);
2750 USED_REX (REX_MODE64);
2753 if (rex & REX_MODE64)
2758 else if (sizeflag & DFLAG)
2771 if (rex & REX_MODE64)
2773 else if (sizeflag & DFLAG)
2778 if (!(rex & REX_MODE64))
2779 used_prefixes |= (prefixes & PREFIX_DATA);
2784 if (sizeflag & SUFFIX_ALWAYS)
2786 if (rex & REX_MODE64)
2790 if (sizeflag & DFLAG)
2794 used_prefixes |= (prefixes & PREFIX_DATA);
2799 if (prefixes & PREFIX_DATA)
2803 used_prefixes |= (prefixes & PREFIX_DATA);
2808 if (rex & REX_MODE64)
2810 USED_REX (REX_MODE64);
2814 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2816 /* operand size flag for cwtl, cbtw */
2820 else if (sizeflag & DFLAG)
2831 if (sizeflag & DFLAG)
2842 used_prefixes |= (prefixes & PREFIX_DATA);
2855 obufp += strlen (s);
2861 if (prefixes & PREFIX_CS)
2863 used_prefixes |= PREFIX_CS;
2864 oappend ("%cs:" + intel_syntax);
2866 if (prefixes & PREFIX_DS)
2868 used_prefixes |= PREFIX_DS;
2869 oappend ("%ds:" + intel_syntax);
2871 if (prefixes & PREFIX_SS)
2873 used_prefixes |= PREFIX_SS;
2874 oappend ("%ss:" + intel_syntax);
2876 if (prefixes & PREFIX_ES)
2878 used_prefixes |= PREFIX_ES;
2879 oappend ("%es:" + intel_syntax);
2881 if (prefixes & PREFIX_FS)
2883 used_prefixes |= PREFIX_FS;
2884 oappend ("%fs:" + intel_syntax);
2886 if (prefixes & PREFIX_GS)
2888 used_prefixes |= PREFIX_GS;
2889 oappend ("%gs:" + intel_syntax);
2894 OP_indirE (bytemode, sizeflag)
2900 OP_E (bytemode, sizeflag);
2904 print_operand_value (buf, hex, disp)
2917 sprintf_vma (tmp, disp);
2918 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
2919 strcpy (buf + 2, tmp + i);
2923 bfd_signed_vma v = disp;
2930 /* Check for possible overflow on 0x8000000000000000. */
2933 strcpy (buf, "9223372036854775808");
2947 tmp[28 - i] = (v % 10) + '0';
2951 strcpy (buf, tmp + 29 - i);
2957 sprintf (buf, "0x%x", (unsigned int) disp);
2959 sprintf (buf, "%d", (int) disp);
2964 OP_E (bytemode, sizeflag)
2971 USED_REX (REX_EXTZ);
2975 /* Skip mod/rm byte. */
2986 oappend (names8rex[rm + add]);
2988 oappend (names8[rm + add]);
2991 oappend (names16[rm + add]);
2994 oappend (names32[rm + add]);
2997 oappend (names64[rm + add]);
3001 oappend (names64[rm + add]);
3003 oappend (names32[rm + add]);
3006 USED_REX (REX_MODE64);
3007 if (rex & REX_MODE64)
3008 oappend (names64[rm + add]);
3009 else if (sizeflag & DFLAG)
3010 oappend (names32[rm + add]);
3012 oappend (names16[rm + add]);
3013 used_prefixes |= (prefixes & PREFIX_DATA);
3016 if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
3017 && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
3018 && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
3019 BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
3022 oappend (INTERNAL_DISASSEMBLER_ERROR);
3031 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3046 FETCH_DATA (the_info, codep + 1);
3047 scale = (*codep >> 6) & 3;
3048 index = (*codep >> 3) & 7;
3050 USED_REX (REX_EXTY);
3051 USED_REX (REX_EXTZ);
3062 if ((base & 7) == 5)
3065 if (mode_64bit && !havesib && (sizeflag & AFLAG))
3071 FETCH_DATA (the_info, codep + 1);
3073 if ((disp & 0x80) != 0)
3082 if (mod != 0 || (base & 7) == 5)
3084 print_operand_value (scratchbuf, !riprel, disp);
3085 oappend (scratchbuf);
3093 if (havebase || (havesib && (index != 4 || scale != 0)))
3100 oappend ("BYTE PTR ");
3103 oappend ("WORD PTR ");
3106 oappend ("DWORD PTR ");
3109 oappend ("QWORD PTR ");
3113 oappend ("DWORD PTR ");
3115 oappend ("QWORD PTR ");
3118 oappend ("XWORD PTR ");
3124 *obufp++ = open_char;
3125 if (intel_syntax && riprel)
3128 USED_REX (REX_EXTZ);
3129 if (!havesib && (rex & REX_EXTZ))
3132 oappend (mode_64bit && (sizeflag & AFLAG)
3133 ? names64[base] : names32[base]);
3142 *obufp++ = separator_char;
3145 sprintf (scratchbuf, "%s",
3146 mode_64bit && (sizeflag & AFLAG)
3147 ? names64[index] : names32[index]);
3150 sprintf (scratchbuf, ",%s",
3151 mode_64bit && (sizeflag & AFLAG)
3152 ? names64[index] : names32[index]);
3153 oappend (scratchbuf);
3157 && bytemode != b_mode
3158 && bytemode != w_mode
3159 && bytemode != v_mode))
3161 *obufp++ = scale_char;
3163 sprintf (scratchbuf, "%d", 1 << scale);
3164 oappend (scratchbuf);
3168 if (mod != 0 || (base & 7) == 5)
3170 /* Don't print zero displacements. */
3173 if ((bfd_signed_vma) disp > 0)
3179 print_operand_value (scratchbuf, 0, disp);
3180 oappend (scratchbuf);
3184 *obufp++ = close_char;
3187 else if (intel_syntax)
3189 if (mod != 0 || (base & 7) == 5)
3191 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3192 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3196 oappend (names_seg[ds_reg - es_reg]);
3199 print_operand_value (scratchbuf, 1, disp);
3200 oappend (scratchbuf);
3205 { /* 16 bit address mode */
3212 if ((disp & 0x8000) != 0)
3217 FETCH_DATA (the_info, codep + 1);
3219 if ((disp & 0x80) != 0)
3224 if ((disp & 0x8000) != 0)
3230 if (mod != 0 || (rm & 7) == 6)
3232 print_operand_value (scratchbuf, 0, disp);
3233 oappend (scratchbuf);
3236 if (mod != 0 || (rm & 7) != 6)
3238 *obufp++ = open_char;
3240 oappend (index16[rm + add]);
3241 *obufp++ = close_char;
3248 OP_G (bytemode, sizeflag)
3253 USED_REX (REX_EXTX);
3261 oappend (names8rex[reg + add]);
3263 oappend (names8[reg + add]);
3266 oappend (names16[reg + add]);
3269 oappend (names32[reg + add]);
3272 oappend (names64[reg + add]);
3275 USED_REX (REX_MODE64);
3276 if (rex & REX_MODE64)
3277 oappend (names64[reg + add]);
3278 else if (sizeflag & DFLAG)
3279 oappend (names32[reg + add]);
3281 oappend (names16[reg + add]);
3282 used_prefixes |= (prefixes & PREFIX_DATA);
3285 oappend (INTERNAL_DISASSEMBLER_ERROR);
3298 FETCH_DATA (the_info, codep + 8);
3299 a = *codep++ & 0xff;
3300 a |= (*codep++ & 0xff) << 8;
3301 a |= (*codep++ & 0xff) << 16;
3302 a |= (*codep++ & 0xff) << 24;
3303 b = *codep++ & 0xff;
3304 b |= (*codep++ & 0xff) << 8;
3305 b |= (*codep++ & 0xff) << 16;
3306 b |= (*codep++ & 0xff) << 24;
3307 x = a + ((bfd_vma) b << 32);
3315 static bfd_signed_vma
3318 bfd_signed_vma x = 0;
3320 FETCH_DATA (the_info, codep + 4);
3321 x = *codep++ & (bfd_signed_vma) 0xff;
3322 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3323 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3324 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3328 static bfd_signed_vma
3331 bfd_signed_vma x = 0;
3333 FETCH_DATA (the_info, codep + 4);
3334 x = *codep++ & (bfd_signed_vma) 0xff;
3335 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3336 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3337 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3339 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3349 FETCH_DATA (the_info, codep + 2);
3350 x = *codep++ & 0xff;
3351 x |= (*codep++ & 0xff) << 8;
3360 op_index[op_ad] = op_ad;
3363 op_address[op_ad] = op;
3364 op_riprel[op_ad] = riprel;
3368 /* Mask to get a 32-bit address. */
3369 op_address[op_ad] = op & 0xffffffff;
3370 op_riprel[op_ad] = riprel & 0xffffffff;
3375 OP_REG (code, sizeflag)
3381 USED_REX (REX_EXTZ);
3393 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3394 case sp_reg: case bp_reg: case si_reg: case di_reg:
3395 s = names16[code - ax_reg + add];
3397 case es_reg: case ss_reg: case cs_reg:
3398 case ds_reg: case fs_reg: case gs_reg:
3399 s = names_seg[code - es_reg + add];
3401 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3402 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3405 s = names8rex[code - al_reg + add];
3407 s = names8[code - al_reg];
3409 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3410 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3413 s = names64[code - rAX_reg + add];
3416 code += eAX_reg - rAX_reg;
3418 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3419 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3420 USED_REX (REX_MODE64);
3421 if (rex & REX_MODE64)
3422 s = names64[code - eAX_reg + add];
3423 else if (sizeflag & DFLAG)
3424 s = names32[code - eAX_reg + add];
3426 s = names16[code - eAX_reg + add];
3427 used_prefixes |= (prefixes & PREFIX_DATA);
3430 s = INTERNAL_DISASSEMBLER_ERROR;
3437 OP_IMREG (code, sizeflag)
3451 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3452 case sp_reg: case bp_reg: case si_reg: case di_reg:
3453 s = names16[code - ax_reg];
3455 case es_reg: case ss_reg: case cs_reg:
3456 case ds_reg: case fs_reg: case gs_reg:
3457 s = names_seg[code - es_reg];
3459 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3460 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3463 s = names8rex[code - al_reg];
3465 s = names8[code - al_reg];
3467 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3468 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3469 USED_REX (REX_MODE64);
3470 if (rex & REX_MODE64)
3471 s = names64[code - eAX_reg];
3472 else if (sizeflag & DFLAG)
3473 s = names32[code - eAX_reg];
3475 s = names16[code - eAX_reg];
3476 used_prefixes |= (prefixes & PREFIX_DATA);
3479 s = INTERNAL_DISASSEMBLER_ERROR;
3486 OP_I (bytemode, sizeflag)
3491 bfd_signed_vma mask = -1;
3496 FETCH_DATA (the_info, codep + 1);
3508 USED_REX (REX_MODE64);
3509 if (rex & REX_MODE64)
3511 else if (sizeflag & DFLAG)
3521 used_prefixes |= (prefixes & PREFIX_DATA);
3528 oappend (INTERNAL_DISASSEMBLER_ERROR);
3533 scratchbuf[0] = '$';
3534 print_operand_value (scratchbuf + 1, 1, op);
3535 oappend (scratchbuf + intel_syntax);
3536 scratchbuf[0] = '\0';
3540 OP_I64 (bytemode, sizeflag)
3545 bfd_signed_vma mask = -1;
3549 OP_I (bytemode, sizeflag);
3556 FETCH_DATA (the_info, codep + 1);
3561 USED_REX (REX_MODE64);
3562 if (rex & REX_MODE64)
3564 else if (sizeflag & DFLAG)
3574 used_prefixes |= (prefixes & PREFIX_DATA);
3581 oappend (INTERNAL_DISASSEMBLER_ERROR);
3586 scratchbuf[0] = '$';
3587 print_operand_value (scratchbuf + 1, 1, op);
3588 oappend (scratchbuf + intel_syntax);
3589 scratchbuf[0] = '\0';
3593 OP_sI (bytemode, sizeflag)
3598 bfd_signed_vma mask = -1;
3603 FETCH_DATA (the_info, codep + 1);
3605 if ((op & 0x80) != 0)
3610 USED_REX (REX_MODE64);
3611 if (rex & REX_MODE64)
3613 else if (sizeflag & DFLAG)
3622 if ((op & 0x8000) != 0)
3625 used_prefixes |= (prefixes & PREFIX_DATA);
3630 if ((op & 0x8000) != 0)
3634 oappend (INTERNAL_DISASSEMBLER_ERROR);
3638 scratchbuf[0] = '$';
3639 print_operand_value (scratchbuf + 1, 1, op);
3640 oappend (scratchbuf + intel_syntax);
3644 OP_J (bytemode, sizeflag)
3654 FETCH_DATA (the_info, codep + 1);
3656 if ((disp & 0x80) != 0)
3660 if (sizeflag & DFLAG)
3665 /* For some reason, a data16 prefix on a jump instruction
3666 means that the pc is masked to 16 bits after the
3667 displacement is added! */
3672 oappend (INTERNAL_DISASSEMBLER_ERROR);
3675 disp = (start_pc + codep - start_codep + disp) & mask;
3677 print_operand_value (scratchbuf, 1, disp);
3678 oappend (scratchbuf);
3682 OP_SEG (dummy, sizeflag)
3683 int dummy ATTRIBUTE_UNUSED;
3684 int sizeflag ATTRIBUTE_UNUSED;
3686 oappend (names_seg[reg]);
3690 OP_DIR (dummy, sizeflag)
3691 int dummy ATTRIBUTE_UNUSED;
3696 if (sizeflag & DFLAG)
3706 used_prefixes |= (prefixes & PREFIX_DATA);
3708 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3710 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3711 oappend (scratchbuf);
3715 OP_OFF (bytemode, sizeflag)
3716 int bytemode ATTRIBUTE_UNUSED;
3723 if ((sizeflag & AFLAG) || mode_64bit)
3730 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3731 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3733 oappend (names_seg[ds_reg - es_reg]);
3737 print_operand_value (scratchbuf, 1, off);
3738 oappend (scratchbuf);
3742 OP_OFF64 (bytemode, sizeflag)
3743 int bytemode ATTRIBUTE_UNUSED;
3744 int sizeflag ATTRIBUTE_UNUSED;
3750 OP_OFF (bytemode, sizeflag);
3760 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3761 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3763 oappend (names_seg[ds_reg - es_reg]);
3767 print_operand_value (scratchbuf, 1, off);
3768 oappend (scratchbuf);
3772 ptr_reg (code, sizeflag)
3782 USED_REX (REX_MODE64);
3783 if (rex & REX_MODE64)
3785 if (!(sizeflag & AFLAG))
3786 s = names32[code - eAX_reg];
3788 s = names64[code - eAX_reg];
3790 else if (sizeflag & AFLAG)
3791 s = names32[code - eAX_reg];
3793 s = names16[code - eAX_reg];
3802 OP_ESreg (code, sizeflag)
3806 oappend ("%es:" + intel_syntax);
3807 ptr_reg (code, sizeflag);
3811 OP_DSreg (code, sizeflag)
3822 prefixes |= PREFIX_DS;
3824 ptr_reg (code, sizeflag);
3828 OP_C (dummy, sizeflag)
3829 int dummy ATTRIBUTE_UNUSED;
3830 int sizeflag ATTRIBUTE_UNUSED;
3833 USED_REX (REX_EXTX);
3836 sprintf (scratchbuf, "%%cr%d", reg + add);
3837 oappend (scratchbuf + intel_syntax);
3841 OP_D (dummy, sizeflag)
3842 int dummy ATTRIBUTE_UNUSED;
3843 int sizeflag ATTRIBUTE_UNUSED;
3846 USED_REX (REX_EXTX);
3850 sprintf (scratchbuf, "db%d", reg + add);
3852 sprintf (scratchbuf, "%%db%d", reg + add);
3853 oappend (scratchbuf);
3857 OP_T (dummy, sizeflag)
3858 int dummy ATTRIBUTE_UNUSED;
3859 int sizeflag ATTRIBUTE_UNUSED;
3861 sprintf (scratchbuf, "%%tr%d", reg);
3862 oappend (scratchbuf + intel_syntax);
3866 OP_Rd (bytemode, sizeflag)
3871 OP_E (bytemode, sizeflag);
3877 OP_MMX (bytemode, sizeflag)
3878 int bytemode ATTRIBUTE_UNUSED;
3879 int sizeflag ATTRIBUTE_UNUSED;
3882 USED_REX (REX_EXTX);
3885 used_prefixes |= (prefixes & PREFIX_DATA);
3886 if (prefixes & PREFIX_DATA)
3887 sprintf (scratchbuf, "%%xmm%d", reg + add);
3889 sprintf (scratchbuf, "%%mm%d", reg + add);
3890 oappend (scratchbuf + intel_syntax);
3894 OP_XMM (bytemode, sizeflag)
3895 int bytemode ATTRIBUTE_UNUSED;
3896 int sizeflag ATTRIBUTE_UNUSED;
3899 USED_REX (REX_EXTX);
3902 sprintf (scratchbuf, "%%xmm%d", reg + add);
3903 oappend (scratchbuf + intel_syntax);
3907 OP_EM (bytemode, sizeflag)
3914 OP_E (bytemode, sizeflag);
3917 USED_REX (REX_EXTZ);
3921 /* Skip mod/rm byte. */
3924 used_prefixes |= (prefixes & PREFIX_DATA);
3925 if (prefixes & PREFIX_DATA)
3926 sprintf (scratchbuf, "%%xmm%d", rm + add);
3928 sprintf (scratchbuf, "%%mm%d", rm + add);
3929 oappend (scratchbuf + intel_syntax);
3933 OP_EX (bytemode, sizeflag)
3940 OP_E (bytemode, sizeflag);
3943 USED_REX (REX_EXTZ);
3947 /* Skip mod/rm byte. */
3950 sprintf (scratchbuf, "%%xmm%d", rm + add);
3951 oappend (scratchbuf + intel_syntax);
3955 OP_MS (bytemode, sizeflag)
3960 OP_EM (bytemode, sizeflag);
3966 OP_XS (bytemode, sizeflag)
3971 OP_EX (bytemode, sizeflag);
3976 static const char *Suffix3DNow[] = {
3977 /* 00 */ NULL, NULL, NULL, NULL,
3978 /* 04 */ NULL, NULL, NULL, NULL,
3979 /* 08 */ NULL, NULL, NULL, NULL,
3980 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
3981 /* 10 */ NULL, NULL, NULL, NULL,
3982 /* 14 */ NULL, NULL, NULL, NULL,
3983 /* 18 */ NULL, NULL, NULL, NULL,
3984 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
3985 /* 20 */ NULL, NULL, NULL, NULL,
3986 /* 24 */ NULL, NULL, NULL, NULL,
3987 /* 28 */ NULL, NULL, NULL, NULL,
3988 /* 2C */ NULL, NULL, NULL, NULL,
3989 /* 30 */ NULL, NULL, NULL, NULL,
3990 /* 34 */ NULL, NULL, NULL, NULL,
3991 /* 38 */ NULL, NULL, NULL, NULL,
3992 /* 3C */ NULL, NULL, NULL, NULL,
3993 /* 40 */ NULL, NULL, NULL, NULL,
3994 /* 44 */ NULL, NULL, NULL, NULL,
3995 /* 48 */ NULL, NULL, NULL, NULL,
3996 /* 4C */ NULL, NULL, NULL, NULL,
3997 /* 50 */ NULL, NULL, NULL, NULL,
3998 /* 54 */ NULL, NULL, NULL, NULL,
3999 /* 58 */ NULL, NULL, NULL, NULL,
4000 /* 5C */ NULL, NULL, NULL, NULL,
4001 /* 60 */ NULL, NULL, NULL, NULL,
4002 /* 64 */ NULL, NULL, NULL, NULL,
4003 /* 68 */ NULL, NULL, NULL, NULL,
4004 /* 6C */ NULL, NULL, NULL, NULL,
4005 /* 70 */ NULL, NULL, NULL, NULL,
4006 /* 74 */ NULL, NULL, NULL, NULL,
4007 /* 78 */ NULL, NULL, NULL, NULL,
4008 /* 7C */ NULL, NULL, NULL, NULL,
4009 /* 80 */ NULL, NULL, NULL, NULL,
4010 /* 84 */ NULL, NULL, NULL, NULL,
4011 /* 88 */ NULL, NULL, "pfnacc", NULL,
4012 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4013 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4014 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4015 /* 98 */ NULL, NULL, "pfsub", NULL,
4016 /* 9C */ NULL, NULL, "pfadd", NULL,
4017 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4018 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4019 /* A8 */ NULL, NULL, "pfsubr", NULL,
4020 /* AC */ NULL, NULL, "pfacc", NULL,
4021 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4022 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4023 /* B8 */ NULL, NULL, NULL, "pswapd",
4024 /* BC */ NULL, NULL, NULL, "pavgusb",
4025 /* C0 */ NULL, NULL, NULL, NULL,
4026 /* C4 */ NULL, NULL, NULL, NULL,
4027 /* C8 */ NULL, NULL, NULL, NULL,
4028 /* CC */ NULL, NULL, NULL, NULL,
4029 /* D0 */ NULL, NULL, NULL, NULL,
4030 /* D4 */ NULL, NULL, NULL, NULL,
4031 /* D8 */ NULL, NULL, NULL, NULL,
4032 /* DC */ NULL, NULL, NULL, NULL,
4033 /* E0 */ NULL, NULL, NULL, NULL,
4034 /* E4 */ NULL, NULL, NULL, NULL,
4035 /* E8 */ NULL, NULL, NULL, NULL,
4036 /* EC */ NULL, NULL, NULL, NULL,
4037 /* F0 */ NULL, NULL, NULL, NULL,
4038 /* F4 */ NULL, NULL, NULL, NULL,
4039 /* F8 */ NULL, NULL, NULL, NULL,
4040 /* FC */ NULL, NULL, NULL, NULL,
4044 OP_3DNowSuffix (bytemode, sizeflag)
4045 int bytemode ATTRIBUTE_UNUSED;
4046 int sizeflag ATTRIBUTE_UNUSED;
4048 const char *mnemonic;
4050 FETCH_DATA (the_info, codep + 1);
4051 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4052 place where an 8-bit immediate would normally go. ie. the last
4053 byte of the instruction. */
4054 obufp = obuf + strlen (obuf);
4055 mnemonic = Suffix3DNow[*codep++ & 0xff];
4060 /* Since a variable sized modrm/sib chunk is between the start
4061 of the opcode (0x0f0f) and the opcode suffix, we need to do
4062 all the modrm processing first, and don't know until now that
4063 we have a bad opcode. This necessitates some cleaning up. */
4070 static const char *simd_cmp_op[] = {
4082 OP_SIMD_Suffix (bytemode, sizeflag)
4083 int bytemode ATTRIBUTE_UNUSED;
4084 int sizeflag ATTRIBUTE_UNUSED;
4086 unsigned int cmp_type;
4088 FETCH_DATA (the_info, codep + 1);
4089 obufp = obuf + strlen (obuf);
4090 cmp_type = *codep++ & 0xff;
4093 char suffix1 = 'p', suffix2 = 's';
4094 used_prefixes |= (prefixes & PREFIX_REPZ);
4095 if (prefixes & PREFIX_REPZ)
4099 used_prefixes |= (prefixes & PREFIX_DATA);
4100 if (prefixes & PREFIX_DATA)
4104 used_prefixes |= (prefixes & PREFIX_REPNZ);
4105 if (prefixes & PREFIX_REPNZ)
4106 suffix1 = 's', suffix2 = 'd';
4109 sprintf (scratchbuf, "cmp%s%c%c",
4110 simd_cmp_op[cmp_type], suffix1, suffix2);
4111 used_prefixes |= (prefixes & PREFIX_REPZ);
4112 oappend (scratchbuf);
4116 /* We have a bad extension byte. Clean up. */
4124 SIMD_Fixup (extrachar, sizeflag)
4126 int sizeflag ATTRIBUTE_UNUSED;
4128 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4129 forms of these instructions. */
4132 char *p = obuf + strlen (obuf);
4135 *(p - 1) = *(p - 2);
4136 *(p - 2) = *(p - 3);
4137 *(p - 3) = extrachar;
4144 /* Throw away prefixes and 1st. opcode byte. */
4145 codep = insn_codep + 1;