1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
36 #include "qemu-common.h"
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
48 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma
, disassemble_info
*);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *buf
, size_t bufsize
, int hex
, bfd_vma disp
);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma
get64 (void);
63 static bfd_signed_vma
get32 (void);
64 static bfd_signed_vma
get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma
, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_MS (int, int);
89 static void OP_XS (int, int);
90 static void OP_M (int, int);
91 static void OP_VMX (int, int);
92 static void OP_0fae (int, int);
93 static void OP_0f07 (int, int);
94 static void NOP_Fixup (int, int);
95 static void OP_3DNowSuffix (int, int);
96 static void OP_SIMD_Suffix (int, int);
97 static void SIMD_Fixup (int, int);
98 static void PNI_Fixup (int, int);
99 static void SVME_Fixup (int, int);
100 static void INVLPG_Fixup (int, int);
101 static void BadOp (void);
102 static void SEG_Fixup (int, int);
103 static void VMX_Fixup (int, int);
104 static void REP_Fixup (int, int);
107 /* Points to first byte not fetched. */
108 bfd_byte
*max_fetched
;
109 bfd_byte the_buffer
[MAXLEN
];
115 /* The opcode for the fwait instruction, which we treat as a prefix
117 #define FWAIT_OPCODE (0x9b)
126 static enum address_mode address_mode
;
128 /* Flags for the prefixes for the current instruction. See below. */
131 /* REX prefix the current instruction. See below. */
133 /* Bits of REX we've already used. */
139 /* Mark parts used in the REX prefix. When we are testing for
140 empty prefix (for 8bit register REX extension), just mask it
141 out. Otherwise test for REX bit is excuse for existence of REX
142 only in case value is nonzero. */
143 #define USED_REX(value) \
146 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
151 /* Flags for prefixes which we somehow handled when printing the
152 current instruction. */
153 static int used_prefixes
;
155 /* Flags stored in PREFIXES. */
156 #define PREFIX_REPZ 1
157 #define PREFIX_REPNZ 2
158 #define PREFIX_LOCK 4
160 #define PREFIX_SS 0x10
161 #define PREFIX_DS 0x20
162 #define PREFIX_ES 0x40
163 #define PREFIX_FS 0x80
164 #define PREFIX_GS 0x100
165 #define PREFIX_DATA 0x200
166 #define PREFIX_ADDR 0x400
167 #define PREFIX_FWAIT 0x800
169 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
170 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
172 #define FETCH_DATA(info, addr) \
173 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
174 ? 1 : fetch_data ((info), (addr)))
177 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
180 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
181 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
183 if (addr
<= priv
->the_buffer
+ MAXLEN
)
184 status
= (*info
->read_memory_func
) (start
,
186 addr
- priv
->max_fetched
,
192 /* If we did manage to read at least one byte, then
193 print_insn_i386 will do something sensible. Otherwise, print
194 an error. We do that here because this is where we know
196 if (priv
->max_fetched
== priv
->the_buffer
)
197 (*info
->memory_error_func
) (status
, start
, info
);
198 longjmp (priv
->bailout
, 1);
201 priv
->max_fetched
= addr
;
207 #define Eb OP_E, b_mode
208 #define Ev OP_E, v_mode
209 #define Ed OP_E, d_mode
210 #define Eq OP_E, q_mode
211 #define Edq OP_E, dq_mode
212 #define Edqw OP_E, dqw_mode
213 #define indirEv OP_indirE, stack_v_mode
214 #define indirEp OP_indirE, f_mode
215 #define stackEv OP_E, stack_v_mode
216 #define Em OP_E, m_mode
217 #define Ew OP_E, w_mode
218 #define Ma OP_E, v_mode
219 #define M OP_M, 0 /* lea, lgdt, etc. */
220 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
221 #define Gb OP_G, b_mode
222 #define Gv OP_G, v_mode
223 #define Gd OP_G, d_mode
224 #define Gdq OP_G, dq_mode
225 #define Gm OP_G, m_mode
226 #define Gw OP_G, w_mode
227 #define Rd OP_Rd, d_mode
228 #define Rm OP_Rd, m_mode
229 #define Ib OP_I, b_mode
230 #define sIb OP_sI, b_mode /* sign extened byte */
231 #define Iv OP_I, v_mode
232 #define Iq OP_I, q_mode
233 #define Iv64 OP_I64, v_mode
234 #define Iw OP_I, w_mode
235 #define I1 OP_I, const_1_mode
236 #define Jb OP_J, b_mode
237 #define Jv OP_J, v_mode
238 #define Cm OP_C, m_mode
239 #define Dm OP_D, m_mode
240 #define Td OP_T, d_mode
241 #define Sv SEG_Fixup, v_mode
243 #define RMeAX OP_REG, eAX_reg
244 #define RMeBX OP_REG, eBX_reg
245 #define RMeCX OP_REG, eCX_reg
246 #define RMeDX OP_REG, eDX_reg
247 #define RMeSP OP_REG, eSP_reg
248 #define RMeBP OP_REG, eBP_reg
249 #define RMeSI OP_REG, eSI_reg
250 #define RMeDI OP_REG, eDI_reg
251 #define RMrAX OP_REG, rAX_reg
252 #define RMrBX OP_REG, rBX_reg
253 #define RMrCX OP_REG, rCX_reg
254 #define RMrDX OP_REG, rDX_reg
255 #define RMrSP OP_REG, rSP_reg
256 #define RMrBP OP_REG, rBP_reg
257 #define RMrSI OP_REG, rSI_reg
258 #define RMrDI OP_REG, rDI_reg
259 #define RMAL OP_REG, al_reg
260 #define RMAL OP_REG, al_reg
261 #define RMCL OP_REG, cl_reg
262 #define RMDL OP_REG, dl_reg
263 #define RMBL OP_REG, bl_reg
264 #define RMAH OP_REG, ah_reg
265 #define RMCH OP_REG, ch_reg
266 #define RMDH OP_REG, dh_reg
267 #define RMBH OP_REG, bh_reg
268 #define RMAX OP_REG, ax_reg
269 #define RMDX OP_REG, dx_reg
271 #define eAX OP_IMREG, eAX_reg
272 #define eBX OP_IMREG, eBX_reg
273 #define eCX OP_IMREG, eCX_reg
274 #define eDX OP_IMREG, eDX_reg
275 #define eSP OP_IMREG, eSP_reg
276 #define eBP OP_IMREG, eBP_reg
277 #define eSI OP_IMREG, eSI_reg
278 #define eDI OP_IMREG, eDI_reg
279 #define AL OP_IMREG, al_reg
280 #define CL OP_IMREG, cl_reg
281 #define DL OP_IMREG, dl_reg
282 #define BL OP_IMREG, bl_reg
283 #define AH OP_IMREG, ah_reg
284 #define CH OP_IMREG, ch_reg
285 #define DH OP_IMREG, dh_reg
286 #define BH OP_IMREG, bh_reg
287 #define AX OP_IMREG, ax_reg
288 #define DX OP_IMREG, dx_reg
289 #define indirDX OP_IMREG, indir_dx_reg
291 #define Sw OP_SEG, w_mode
293 #define Ob OP_OFF64, b_mode
294 #define Ov OP_OFF64, v_mode
295 #define Xb OP_DSreg, eSI_reg
296 #define Xv OP_DSreg, eSI_reg
297 #define Yb OP_ESreg, eDI_reg
298 #define Yv OP_ESreg, eDI_reg
299 #define DSBX OP_DSreg, eBX_reg
301 #define es OP_REG, es_reg
302 #define ss OP_REG, ss_reg
303 #define cs OP_REG, cs_reg
304 #define ds OP_REG, ds_reg
305 #define fs OP_REG, fs_reg
306 #define gs OP_REG, gs_reg
310 #define EM OP_EM, v_mode
311 #define EX OP_EX, v_mode
312 #define MS OP_MS, v_mode
313 #define XS OP_XS, v_mode
314 #define VM OP_VMX, q_mode
315 #define OPSUF OP_3DNowSuffix, 0
316 #define OPSIMD OP_SIMD_Suffix, 0
318 /* Used handle "rep" prefix for string instructions. */
319 #define Xbr REP_Fixup, eSI_reg
320 #define Xvr REP_Fixup, eSI_reg
321 #define Ybr REP_Fixup, eDI_reg
322 #define Yvr REP_Fixup, eDI_reg
323 #define indirDXr REP_Fixup, indir_dx_reg
324 #define ALr REP_Fixup, al_reg
325 #define eAXr REP_Fixup, eAX_reg
327 #define cond_jump_flag NULL, cond_jump_mode
328 #define loop_jcxz_flag NULL, loop_jcxz_mode
330 /* bits in sizeflag */
331 #define SUFFIX_ALWAYS 4
335 #define b_mode 1 /* byte operand */
336 #define v_mode 2 /* operand size depends on prefixes */
337 #define w_mode 3 /* word operand */
338 #define d_mode 4 /* double word operand */
339 #define q_mode 5 /* quad word operand */
340 #define t_mode 6 /* ten-byte operand */
341 #define x_mode 7 /* 16-byte XMM operand */
342 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
343 #define cond_jump_mode 9
344 #define loop_jcxz_mode 10
345 #define dq_mode 11 /* operand size depends on REX prefixes. */
346 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
347 #define f_mode 13 /* 4- or 6-byte pointer operand */
348 #define const_1_mode 14
349 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
394 #define indir_dx_reg 150
398 #define USE_PREFIX_USER_TABLE 3
399 #define X86_64_SPECIAL 4
400 #define IS_3BYTE_OPCODE 5
402 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
404 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
405 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
406 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
407 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
408 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
409 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
410 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
411 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
412 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
413 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
414 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
415 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
416 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
417 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
418 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
419 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
420 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
421 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
422 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
423 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
424 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
425 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
426 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
427 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
428 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
430 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
431 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
432 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
433 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
434 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
435 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
436 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
437 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
438 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
439 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
440 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
441 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
442 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
443 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
444 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
445 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
446 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
447 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
448 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
449 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
450 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
451 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
452 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
453 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
454 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
455 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
456 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
457 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
458 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
459 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
460 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
461 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
462 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
464 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
466 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0
467 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0
469 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
481 /* Upper case letters in the instruction names here are macros.
482 'A' => print 'b' if no register operands or suffix_always is true
483 'B' => print 'b' if suffix_always is true
484 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
486 'E' => print 'e' if 32-bit form of jcxz
487 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
488 'H' => print ",pt" or ",pn" branch hint
489 'I' => honor following macro letter even in Intel mode (implemented only
490 . for some of the macro letters)
492 'L' => print 'l' if suffix_always is true
493 'N' => print 'n' if instruction has no wait "prefix"
494 'O' => print 'd', or 'o'
495 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
496 . or suffix_always is true. print 'q' if rex prefix is present.
497 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
499 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
500 'S' => print 'w', 'l' or 'q' if suffix_always is true
501 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
502 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
503 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
504 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
505 'X' => print 's', 'd' depending on data16 prefix (for XMM)
506 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
507 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
509 Many of the above letters print nothing in Intel mode. See "putop"
512 Braces '{' and '}', and vertical bars '|', indicate alternative
513 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
514 modes. In cases where there are only two alternatives, the X86_64
515 instruction is reserved, and "(bad)" is printed.
518 static const struct dis386 dis386
[] = {
520 { "addB", Eb
, Gb
, XX
},
521 { "addS", Ev
, Gv
, XX
},
522 { "addB", Gb
, Eb
, XX
},
523 { "addS", Gv
, Ev
, XX
},
524 { "addB", AL
, Ib
, XX
},
525 { "addS", eAX
, Iv
, XX
},
526 { "push{T|}", es
, XX
, XX
},
527 { "pop{T|}", es
, XX
, XX
},
529 { "orB", Eb
, Gb
, XX
},
530 { "orS", Ev
, Gv
, XX
},
531 { "orB", Gb
, Eb
, XX
},
532 { "orS", Gv
, Ev
, XX
},
533 { "orB", AL
, Ib
, XX
},
534 { "orS", eAX
, Iv
, XX
},
535 { "push{T|}", cs
, XX
, XX
},
536 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
538 { "adcB", Eb
, Gb
, XX
},
539 { "adcS", Ev
, Gv
, XX
},
540 { "adcB", Gb
, Eb
, XX
},
541 { "adcS", Gv
, Ev
, XX
},
542 { "adcB", AL
, Ib
, XX
},
543 { "adcS", eAX
, Iv
, XX
},
544 { "push{T|}", ss
, XX
, XX
},
545 { "pop{T|}", ss
, XX
, XX
},
547 { "sbbB", Eb
, Gb
, XX
},
548 { "sbbS", Ev
, Gv
, XX
},
549 { "sbbB", Gb
, Eb
, XX
},
550 { "sbbS", Gv
, Ev
, XX
},
551 { "sbbB", AL
, Ib
, XX
},
552 { "sbbS", eAX
, Iv
, XX
},
553 { "push{T|}", ds
, XX
, XX
},
554 { "pop{T|}", ds
, XX
, XX
},
556 { "andB", Eb
, Gb
, XX
},
557 { "andS", Ev
, Gv
, XX
},
558 { "andB", Gb
, Eb
, XX
},
559 { "andS", Gv
, Ev
, XX
},
560 { "andB", AL
, Ib
, XX
},
561 { "andS", eAX
, Iv
, XX
},
562 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
563 { "daa{|}", XX
, XX
, XX
},
565 { "subB", Eb
, Gb
, XX
},
566 { "subS", Ev
, Gv
, XX
},
567 { "subB", Gb
, Eb
, XX
},
568 { "subS", Gv
, Ev
, XX
},
569 { "subB", AL
, Ib
, XX
},
570 { "subS", eAX
, Iv
, XX
},
571 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
572 { "das{|}", XX
, XX
, XX
},
574 { "xorB", Eb
, Gb
, XX
},
575 { "xorS", Ev
, Gv
, XX
},
576 { "xorB", Gb
, Eb
, XX
},
577 { "xorS", Gv
, Ev
, XX
},
578 { "xorB", AL
, Ib
, XX
},
579 { "xorS", eAX
, Iv
, XX
},
580 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
581 { "aaa{|}", XX
, XX
, XX
},
583 { "cmpB", Eb
, Gb
, XX
},
584 { "cmpS", Ev
, Gv
, XX
},
585 { "cmpB", Gb
, Eb
, XX
},
586 { "cmpS", Gv
, Ev
, XX
},
587 { "cmpB", AL
, Ib
, XX
},
588 { "cmpS", eAX
, Iv
, XX
},
589 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
590 { "aas{|}", XX
, XX
, XX
},
592 { "inc{S|}", RMeAX
, XX
, XX
},
593 { "inc{S|}", RMeCX
, XX
, XX
},
594 { "inc{S|}", RMeDX
, XX
, XX
},
595 { "inc{S|}", RMeBX
, XX
, XX
},
596 { "inc{S|}", RMeSP
, XX
, XX
},
597 { "inc{S|}", RMeBP
, XX
, XX
},
598 { "inc{S|}", RMeSI
, XX
, XX
},
599 { "inc{S|}", RMeDI
, XX
, XX
},
601 { "dec{S|}", RMeAX
, XX
, XX
},
602 { "dec{S|}", RMeCX
, XX
, XX
},
603 { "dec{S|}", RMeDX
, XX
, XX
},
604 { "dec{S|}", RMeBX
, XX
, XX
},
605 { "dec{S|}", RMeSP
, XX
, XX
},
606 { "dec{S|}", RMeBP
, XX
, XX
},
607 { "dec{S|}", RMeSI
, XX
, XX
},
608 { "dec{S|}", RMeDI
, XX
, XX
},
610 { "pushV", RMrAX
, XX
, XX
},
611 { "pushV", RMrCX
, XX
, XX
},
612 { "pushV", RMrDX
, XX
, XX
},
613 { "pushV", RMrBX
, XX
, XX
},
614 { "pushV", RMrSP
, XX
, XX
},
615 { "pushV", RMrBP
, XX
, XX
},
616 { "pushV", RMrSI
, XX
, XX
},
617 { "pushV", RMrDI
, XX
, XX
},
619 { "popV", RMrAX
, XX
, XX
},
620 { "popV", RMrCX
, XX
, XX
},
621 { "popV", RMrDX
, XX
, XX
},
622 { "popV", RMrBX
, XX
, XX
},
623 { "popV", RMrSP
, XX
, XX
},
624 { "popV", RMrBP
, XX
, XX
},
625 { "popV", RMrSI
, XX
, XX
},
626 { "popV", RMrDI
, XX
, XX
},
628 { "pusha{P|}", XX
, XX
, XX
},
629 { "popa{P|}", XX
, XX
, XX
},
630 { "bound{S|}", Gv
, Ma
, XX
},
632 { "(bad)", XX
, XX
, XX
}, /* seg fs */
633 { "(bad)", XX
, XX
, XX
}, /* seg gs */
634 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
635 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
637 { "pushT", Iq
, XX
, XX
},
638 { "imulS", Gv
, Ev
, Iv
},
639 { "pushT", sIb
, XX
, XX
},
640 { "imulS", Gv
, Ev
, sIb
},
641 { "ins{b||b|}", Ybr
, indirDX
, XX
},
642 { "ins{R||R|}", Yvr
, indirDX
, XX
},
643 { "outs{b||b|}", indirDXr
, Xb
, XX
},
644 { "outs{R||R|}", indirDXr
, Xv
, XX
},
646 { "joH", Jb
, XX
, cond_jump_flag
},
647 { "jnoH", Jb
, XX
, cond_jump_flag
},
648 { "jbH", Jb
, XX
, cond_jump_flag
},
649 { "jaeH", Jb
, XX
, cond_jump_flag
},
650 { "jeH", Jb
, XX
, cond_jump_flag
},
651 { "jneH", Jb
, XX
, cond_jump_flag
},
652 { "jbeH", Jb
, XX
, cond_jump_flag
},
653 { "jaH", Jb
, XX
, cond_jump_flag
},
655 { "jsH", Jb
, XX
, cond_jump_flag
},
656 { "jnsH", Jb
, XX
, cond_jump_flag
},
657 { "jpH", Jb
, XX
, cond_jump_flag
},
658 { "jnpH", Jb
, XX
, cond_jump_flag
},
659 { "jlH", Jb
, XX
, cond_jump_flag
},
660 { "jgeH", Jb
, XX
, cond_jump_flag
},
661 { "jleH", Jb
, XX
, cond_jump_flag
},
662 { "jgH", Jb
, XX
, cond_jump_flag
},
666 { "(bad)", XX
, XX
, XX
},
668 { "testB", Eb
, Gb
, XX
},
669 { "testS", Ev
, Gv
, XX
},
670 { "xchgB", Eb
, Gb
, XX
},
671 { "xchgS", Ev
, Gv
, XX
},
673 { "movB", Eb
, Gb
, XX
},
674 { "movS", Ev
, Gv
, XX
},
675 { "movB", Gb
, Eb
, XX
},
676 { "movS", Gv
, Ev
, XX
},
677 { "movQ", Sv
, Sw
, XX
},
678 { "leaS", Gv
, M
, XX
},
679 { "movQ", Sw
, Sv
, XX
},
680 { "popU", stackEv
, XX
, XX
},
682 { "nop", NOP_Fixup
, 0, XX
, XX
},
683 { "xchgS", RMeCX
, eAX
, XX
},
684 { "xchgS", RMeDX
, eAX
, XX
},
685 { "xchgS", RMeBX
, eAX
, XX
},
686 { "xchgS", RMeSP
, eAX
, XX
},
687 { "xchgS", RMeBP
, eAX
, XX
},
688 { "xchgS", RMeSI
, eAX
, XX
},
689 { "xchgS", RMeDI
, eAX
, XX
},
691 { "cW{tR||tR|}", XX
, XX
, XX
},
692 { "cR{tO||tO|}", XX
, XX
, XX
},
693 { "Jcall{T|}", Ap
, XX
, XX
},
694 { "(bad)", XX
, XX
, XX
}, /* fwait */
695 { "pushfT", XX
, XX
, XX
},
696 { "popfT", XX
, XX
, XX
},
697 { "sahf{|}", XX
, XX
, XX
},
698 { "lahf{|}", XX
, XX
, XX
},
700 { "movB", AL
, Ob
, XX
},
701 { "movS", eAX
, Ov
, XX
},
702 { "movB", Ob
, AL
, XX
},
703 { "movS", Ov
, eAX
, XX
},
704 { "movs{b||b|}", Ybr
, Xb
, XX
},
705 { "movs{R||R|}", Yvr
, Xv
, XX
},
706 { "cmps{b||b|}", Xb
, Yb
, XX
},
707 { "cmps{R||R|}", Xv
, Yv
, XX
},
709 { "testB", AL
, Ib
, XX
},
710 { "testS", eAX
, Iv
, XX
},
711 { "stosB", Ybr
, AL
, XX
},
712 { "stosS", Yvr
, eAX
, XX
},
713 { "lodsB", ALr
, Xb
, XX
},
714 { "lodsS", eAXr
, Xv
, XX
},
715 { "scasB", AL
, Yb
, XX
},
716 { "scasS", eAX
, Yv
, XX
},
718 { "movB", RMAL
, Ib
, XX
},
719 { "movB", RMCL
, Ib
, XX
},
720 { "movB", RMDL
, Ib
, XX
},
721 { "movB", RMBL
, Ib
, XX
},
722 { "movB", RMAH
, Ib
, XX
},
723 { "movB", RMCH
, Ib
, XX
},
724 { "movB", RMDH
, Ib
, XX
},
725 { "movB", RMBH
, Ib
, XX
},
727 { "movS", RMeAX
, Iv64
, XX
},
728 { "movS", RMeCX
, Iv64
, XX
},
729 { "movS", RMeDX
, Iv64
, XX
},
730 { "movS", RMeBX
, Iv64
, XX
},
731 { "movS", RMeSP
, Iv64
, XX
},
732 { "movS", RMeBP
, Iv64
, XX
},
733 { "movS", RMeSI
, Iv64
, XX
},
734 { "movS", RMeDI
, Iv64
, XX
},
738 { "retT", Iw
, XX
, XX
},
739 { "retT", XX
, XX
, XX
},
740 { "les{S|}", Gv
, Mp
, XX
},
741 { "ldsS", Gv
, Mp
, XX
},
742 { "movA", Eb
, Ib
, XX
},
743 { "movQ", Ev
, Iv
, XX
},
745 { "enterT", Iw
, Ib
, XX
},
746 { "leaveT", XX
, XX
, XX
},
747 { "lretP", Iw
, XX
, XX
},
748 { "lretP", XX
, XX
, XX
},
749 { "int3", XX
, XX
, XX
},
750 { "int", Ib
, XX
, XX
},
751 { "into{|}", XX
, XX
, XX
},
752 { "iretP", XX
, XX
, XX
},
758 { "aam{|}", sIb
, XX
, XX
},
759 { "aad{|}", sIb
, XX
, XX
},
760 { "(bad)", XX
, XX
, XX
},
761 { "xlat", DSBX
, XX
, XX
},
772 { "loopneFH", Jb
, XX
, loop_jcxz_flag
},
773 { "loopeFH", Jb
, XX
, loop_jcxz_flag
},
774 { "loopFH", Jb
, XX
, loop_jcxz_flag
},
775 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
},
776 { "inB", AL
, Ib
, XX
},
777 { "inS", eAX
, Ib
, XX
},
778 { "outB", Ib
, AL
, XX
},
779 { "outS", Ib
, eAX
, XX
},
781 { "callT", Jv
, XX
, XX
},
782 { "jmpT", Jv
, XX
, XX
},
783 { "Jjmp{T|}", Ap
, XX
, XX
},
784 { "jmp", Jb
, XX
, XX
},
785 { "inB", AL
, indirDX
, XX
},
786 { "inS", eAX
, indirDX
, XX
},
787 { "outB", indirDX
, AL
, XX
},
788 { "outS", indirDX
, eAX
, XX
},
790 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
791 { "icebp", XX
, XX
, XX
},
792 { "(bad)", XX
, XX
, XX
}, /* repne */
793 { "(bad)", XX
, XX
, XX
}, /* repz */
794 { "hlt", XX
, XX
, XX
},
795 { "cmc", XX
, XX
, XX
},
799 { "clc", XX
, XX
, XX
},
800 { "stc", XX
, XX
, XX
},
801 { "cli", XX
, XX
, XX
},
802 { "sti", XX
, XX
, XX
},
803 { "cld", XX
, XX
, XX
},
804 { "std", XX
, XX
, XX
},
809 static const struct dis386 dis386_twobyte
[] = {
813 { "larS", Gv
, Ew
, XX
},
814 { "lslS", Gv
, Ew
, XX
},
815 { "(bad)", XX
, XX
, XX
},
816 { "syscall", XX
, XX
, XX
},
817 { "clts", XX
, XX
, XX
},
818 { "sysretP", XX
, XX
, XX
},
820 { "invd", XX
, XX
, XX
},
821 { "wbinvd", XX
, XX
, XX
},
822 { "(bad)", XX
, XX
, XX
},
823 { "ud2a", XX
, XX
, XX
},
824 { "(bad)", XX
, XX
, XX
},
826 { "femms", XX
, XX
, XX
},
827 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix. */
832 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
833 { "unpcklpX", XM
, EX
, XX
},
834 { "unpckhpX", XM
, EX
, XX
},
836 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
839 { "(bad)", XX
, XX
, XX
},
840 { "(bad)", XX
, XX
, XX
},
841 { "(bad)", XX
, XX
, XX
},
842 { "(bad)", XX
, XX
, XX
},
843 { "(bad)", XX
, XX
, XX
},
844 { "(bad)", XX
, XX
, XX
},
845 { "(bad)", XX
, XX
, XX
},
847 { "movZ", Rm
, Cm
, XX
},
848 { "movZ", Rm
, Dm
, XX
},
849 { "movZ", Cm
, Rm
, XX
},
850 { "movZ", Dm
, Rm
, XX
},
851 { "movL", Rd
, Td
, XX
},
852 { "(bad)", XX
, XX
, XX
},
853 { "movL", Td
, Rd
, XX
},
854 { "(bad)", XX
, XX
, XX
},
856 { "movapX", XM
, EX
, XX
},
857 { "movapX", EX
, XM
, XX
},
859 { "movntpX", Ev
, XM
, XX
},
862 { "ucomisX", XM
,EX
, XX
},
863 { "comisX", XM
,EX
, XX
},
865 { "wrmsr", XX
, XX
, XX
},
866 { "rdtsc", XX
, XX
, XX
},
867 { "rdmsr", XX
, XX
, XX
},
868 { "rdpmc", XX
, XX
, XX
},
869 { "sysenter", XX
, XX
, XX
},
870 { "sysexit", XX
, XX
, XX
},
871 { "(bad)", XX
, XX
, XX
},
872 { "(bad)", XX
, XX
, XX
},
875 { "(bad)", XX
, XX
, XX
},
877 { "(bad)", XX
, XX
, XX
},
878 { "(bad)", XX
, XX
, XX
},
879 { "(bad)", XX
, XX
, XX
},
880 { "(bad)", XX
, XX
, XX
},
881 { "(bad)", XX
, XX
, XX
},
883 { "cmovo", Gv
, Ev
, XX
},
884 { "cmovno", Gv
, Ev
, XX
},
885 { "cmovb", Gv
, Ev
, XX
},
886 { "cmovae", Gv
, Ev
, XX
},
887 { "cmove", Gv
, Ev
, XX
},
888 { "cmovne", Gv
, Ev
, XX
},
889 { "cmovbe", Gv
, Ev
, XX
},
890 { "cmova", Gv
, Ev
, XX
},
892 { "cmovs", Gv
, Ev
, XX
},
893 { "cmovns", Gv
, Ev
, XX
},
894 { "cmovp", Gv
, Ev
, XX
},
895 { "cmovnp", Gv
, Ev
, XX
},
896 { "cmovl", Gv
, Ev
, XX
},
897 { "cmovge", Gv
, Ev
, XX
},
898 { "cmovle", Gv
, Ev
, XX
},
899 { "cmovg", Gv
, Ev
, XX
},
901 { "movmskpX", Gdq
, XS
, XX
},
905 { "andpX", XM
, EX
, XX
},
906 { "andnpX", XM
, EX
, XX
},
907 { "orpX", XM
, EX
, XX
},
908 { "xorpX", XM
, EX
, XX
},
919 { "punpcklbw", MX
, EM
, XX
},
920 { "punpcklwd", MX
, EM
, XX
},
921 { "punpckldq", MX
, EM
, XX
},
922 { "packsswb", MX
, EM
, XX
},
923 { "pcmpgtb", MX
, EM
, XX
},
924 { "pcmpgtw", MX
, EM
, XX
},
925 { "pcmpgtd", MX
, EM
, XX
},
926 { "packuswb", MX
, EM
, XX
},
928 { "punpckhbw", MX
, EM
, XX
},
929 { "punpckhwd", MX
, EM
, XX
},
930 { "punpckhdq", MX
, EM
, XX
},
931 { "packssdw", MX
, EM
, XX
},
934 { "movd", MX
, Edq
, XX
},
941 { "pcmpeqb", MX
, EM
, XX
},
942 { "pcmpeqw", MX
, EM
, XX
},
943 { "pcmpeqd", MX
, EM
, XX
},
944 { "emms", XX
, XX
, XX
},
946 { "vmread", Em
, Gm
, XX
},
947 { "vmwrite", Gm
, Em
, XX
},
948 { "(bad)", XX
, XX
, XX
},
949 { "(bad)", XX
, XX
, XX
},
955 { "joH", Jv
, XX
, cond_jump_flag
},
956 { "jnoH", Jv
, XX
, cond_jump_flag
},
957 { "jbH", Jv
, XX
, cond_jump_flag
},
958 { "jaeH", Jv
, XX
, cond_jump_flag
},
959 { "jeH", Jv
, XX
, cond_jump_flag
},
960 { "jneH", Jv
, XX
, cond_jump_flag
},
961 { "jbeH", Jv
, XX
, cond_jump_flag
},
962 { "jaH", Jv
, XX
, cond_jump_flag
},
964 { "jsH", Jv
, XX
, cond_jump_flag
},
965 { "jnsH", Jv
, XX
, cond_jump_flag
},
966 { "jpH", Jv
, XX
, cond_jump_flag
},
967 { "jnpH", Jv
, XX
, cond_jump_flag
},
968 { "jlH", Jv
, XX
, cond_jump_flag
},
969 { "jgeH", Jv
, XX
, cond_jump_flag
},
970 { "jleH", Jv
, XX
, cond_jump_flag
},
971 { "jgH", Jv
, XX
, cond_jump_flag
},
973 { "seto", Eb
, XX
, XX
},
974 { "setno", Eb
, XX
, XX
},
975 { "setb", Eb
, XX
, XX
},
976 { "setae", Eb
, XX
, XX
},
977 { "sete", Eb
, XX
, XX
},
978 { "setne", Eb
, XX
, XX
},
979 { "setbe", Eb
, XX
, XX
},
980 { "seta", Eb
, XX
, XX
},
982 { "sets", Eb
, XX
, XX
},
983 { "setns", Eb
, XX
, XX
},
984 { "setp", Eb
, XX
, XX
},
985 { "setnp", Eb
, XX
, XX
},
986 { "setl", Eb
, XX
, XX
},
987 { "setge", Eb
, XX
, XX
},
988 { "setle", Eb
, XX
, XX
},
989 { "setg", Eb
, XX
, XX
},
991 { "pushT", fs
, XX
, XX
},
992 { "popT", fs
, XX
, XX
},
993 { "cpuid", XX
, XX
, XX
},
994 { "btS", Ev
, Gv
, XX
},
995 { "shldS", Ev
, Gv
, Ib
},
996 { "shldS", Ev
, Gv
, CL
},
1000 { "pushT", gs
, XX
, XX
},
1001 { "popT", gs
, XX
, XX
},
1002 { "rsm", XX
, XX
, XX
},
1003 { "btsS", Ev
, Gv
, XX
},
1004 { "shrdS", Ev
, Gv
, Ib
},
1005 { "shrdS", Ev
, Gv
, CL
},
1007 { "imulS", Gv
, Ev
, XX
},
1009 { "cmpxchgB", Eb
, Gb
, XX
},
1010 { "cmpxchgS", Ev
, Gv
, XX
},
1011 { "lssS", Gv
, Mp
, XX
},
1012 { "btrS", Ev
, Gv
, XX
},
1013 { "lfsS", Gv
, Mp
, XX
},
1014 { "lgsS", Gv
, Mp
, XX
},
1015 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
},
1016 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1018 { "(bad)", XX
, XX
, XX
},
1019 { "ud2b", XX
, XX
, XX
},
1021 { "btcS", Ev
, Gv
, XX
},
1022 { "bsfS", Gv
, Ev
, XX
},
1023 { "bsrS", Gv
, Ev
, XX
},
1024 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
},
1025 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1027 { "xaddB", Eb
, Gb
, XX
},
1028 { "xaddS", Ev
, Gv
, XX
},
1030 { "movntiS", Ev
, Gv
, XX
},
1031 { "pinsrw", MX
, Edqw
, Ib
},
1032 { "pextrw", Gdq
, MS
, Ib
},
1033 { "shufpX", XM
, EX
, Ib
},
1036 { "bswap", RMeAX
, XX
, XX
},
1037 { "bswap", RMeCX
, XX
, XX
},
1038 { "bswap", RMeDX
, XX
, XX
},
1039 { "bswap", RMeBX
, XX
, XX
},
1040 { "bswap", RMeSP
, XX
, XX
},
1041 { "bswap", RMeBP
, XX
, XX
},
1042 { "bswap", RMeSI
, XX
, XX
},
1043 { "bswap", RMeDI
, XX
, XX
},
1046 { "psrlw", MX
, EM
, XX
},
1047 { "psrld", MX
, EM
, XX
},
1048 { "psrlq", MX
, EM
, XX
},
1049 { "paddq", MX
, EM
, XX
},
1050 { "pmullw", MX
, EM
, XX
},
1052 { "pmovmskb", Gdq
, MS
, XX
},
1054 { "psubusb", MX
, EM
, XX
},
1055 { "psubusw", MX
, EM
, XX
},
1056 { "pminub", MX
, EM
, XX
},
1057 { "pand", MX
, EM
, XX
},
1058 { "paddusb", MX
, EM
, XX
},
1059 { "paddusw", MX
, EM
, XX
},
1060 { "pmaxub", MX
, EM
, XX
},
1061 { "pandn", MX
, EM
, XX
},
1063 { "pavgb", MX
, EM
, XX
},
1064 { "psraw", MX
, EM
, XX
},
1065 { "psrad", MX
, EM
, XX
},
1066 { "pavgw", MX
, EM
, XX
},
1067 { "pmulhuw", MX
, EM
, XX
},
1068 { "pmulhw", MX
, EM
, XX
},
1072 { "psubsb", MX
, EM
, XX
},
1073 { "psubsw", MX
, EM
, XX
},
1074 { "pminsw", MX
, EM
, XX
},
1075 { "por", MX
, EM
, XX
},
1076 { "paddsb", MX
, EM
, XX
},
1077 { "paddsw", MX
, EM
, XX
},
1078 { "pmaxsw", MX
, EM
, XX
},
1079 { "pxor", MX
, EM
, XX
},
1082 { "psllw", MX
, EM
, XX
},
1083 { "pslld", MX
, EM
, XX
},
1084 { "psllq", MX
, EM
, XX
},
1085 { "pmuludq", MX
, EM
, XX
},
1086 { "pmaddwd", MX
, EM
, XX
},
1087 { "psadbw", MX
, EM
, XX
},
1090 { "psubb", MX
, EM
, XX
},
1091 { "psubw", MX
, EM
, XX
},
1092 { "psubd", MX
, EM
, XX
},
1093 { "psubq", MX
, EM
, XX
},
1094 { "paddb", MX
, EM
, XX
},
1095 { "paddw", MX
, EM
, XX
},
1096 { "paddd", MX
, EM
, XX
},
1097 { "(bad)", XX
, XX
, XX
}
1100 static const unsigned char onebyte_has_modrm
[256] = {
1101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1102 /* ------------------------------- */
1103 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1104 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1105 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1106 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1107 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1108 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1109 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1110 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1111 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1112 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1113 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1114 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1115 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1116 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1117 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1118 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1119 /* ------------------------------- */
1120 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1123 static const unsigned char twobyte_has_modrm
[256] = {
1124 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1125 /* ------------------------------- */
1126 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1127 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1128 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1129 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1130 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1131 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1132 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1133 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1134 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1135 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1136 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1137 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1138 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1139 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1140 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1141 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1142 /* ------------------------------- */
1143 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1146 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
1147 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1148 /* ------------------------------- */
1149 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1150 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1151 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1152 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1153 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1154 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1155 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1156 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1157 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1158 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1159 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1160 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1161 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1162 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1163 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1164 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1165 /* ------------------------------- */
1166 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1169 static char obuf
[100];
1171 static char scratchbuf
[100];
1172 static unsigned char *start_codep
;
1173 static unsigned char *insn_codep
;
1174 static unsigned char *codep
;
1175 static disassemble_info
*the_info
;
1179 static unsigned char need_modrm
;
1181 /* If we are accessing mod/rm/reg without need_modrm set, then the
1182 values are stale. Hitting this abort likely indicates that you
1183 need to update onebyte_has_modrm or twobyte_has_modrm. */
1184 #define MODRM_CHECK if (!need_modrm) abort ()
1186 static const char * const *names64
;
1187 static const char * const *names32
;
1188 static const char * const *names16
;
1189 static const char * const *names8
;
1190 static const char * const *names8rex
;
1191 static const char * const *names_seg
;
1192 static const char * const *index16
;
1194 static const char * const intel_names64
[] = {
1195 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1196 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1198 static const char * const intel_names32
[] = {
1199 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1200 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1202 static const char * const intel_names16
[] = {
1203 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1204 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1206 static const char * const intel_names8
[] = {
1207 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1209 static const char * const intel_names8rex
[] = {
1210 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1211 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1213 static const char * const intel_names_seg
[] = {
1214 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1216 static const char * const intel_index16
[] = {
1217 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1220 static const char * const att_names64
[] = {
1221 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1222 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1224 static const char * const att_names32
[] = {
1225 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1226 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1228 static const char * const att_names16
[] = {
1229 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1230 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1232 static const char * const att_names8
[] = {
1233 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1235 static const char * const att_names8rex
[] = {
1236 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1237 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1239 static const char * const att_names_seg
[] = {
1240 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1242 static const char * const att_index16
[] = {
1243 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1246 static const struct dis386 grps
[][8] = {
1249 { "addA", Eb
, Ib
, XX
},
1250 { "orA", Eb
, Ib
, XX
},
1251 { "adcA", Eb
, Ib
, XX
},
1252 { "sbbA", Eb
, Ib
, XX
},
1253 { "andA", Eb
, Ib
, XX
},
1254 { "subA", Eb
, Ib
, XX
},
1255 { "xorA", Eb
, Ib
, XX
},
1256 { "cmpA", Eb
, Ib
, XX
}
1260 { "addQ", Ev
, Iv
, XX
},
1261 { "orQ", Ev
, Iv
, XX
},
1262 { "adcQ", Ev
, Iv
, XX
},
1263 { "sbbQ", Ev
, Iv
, XX
},
1264 { "andQ", Ev
, Iv
, XX
},
1265 { "subQ", Ev
, Iv
, XX
},
1266 { "xorQ", Ev
, Iv
, XX
},
1267 { "cmpQ", Ev
, Iv
, XX
}
1271 { "addQ", Ev
, sIb
, XX
},
1272 { "orQ", Ev
, sIb
, XX
},
1273 { "adcQ", Ev
, sIb
, XX
},
1274 { "sbbQ", Ev
, sIb
, XX
},
1275 { "andQ", Ev
, sIb
, XX
},
1276 { "subQ", Ev
, sIb
, XX
},
1277 { "xorQ", Ev
, sIb
, XX
},
1278 { "cmpQ", Ev
, sIb
, XX
}
1282 { "rolA", Eb
, Ib
, XX
},
1283 { "rorA", Eb
, Ib
, XX
},
1284 { "rclA", Eb
, Ib
, XX
},
1285 { "rcrA", Eb
, Ib
, XX
},
1286 { "shlA", Eb
, Ib
, XX
},
1287 { "shrA", Eb
, Ib
, XX
},
1288 { "(bad)", XX
, XX
, XX
},
1289 { "sarA", Eb
, Ib
, XX
},
1293 { "rolQ", Ev
, Ib
, XX
},
1294 { "rorQ", Ev
, Ib
, XX
},
1295 { "rclQ", Ev
, Ib
, XX
},
1296 { "rcrQ", Ev
, Ib
, XX
},
1297 { "shlQ", Ev
, Ib
, XX
},
1298 { "shrQ", Ev
, Ib
, XX
},
1299 { "(bad)", XX
, XX
, XX
},
1300 { "sarQ", Ev
, Ib
, XX
},
1304 { "rolA", Eb
, I1
, XX
},
1305 { "rorA", Eb
, I1
, XX
},
1306 { "rclA", Eb
, I1
, XX
},
1307 { "rcrA", Eb
, I1
, XX
},
1308 { "shlA", Eb
, I1
, XX
},
1309 { "shrA", Eb
, I1
, XX
},
1310 { "(bad)", XX
, XX
, XX
},
1311 { "sarA", Eb
, I1
, XX
},
1315 { "rolQ", Ev
, I1
, XX
},
1316 { "rorQ", Ev
, I1
, XX
},
1317 { "rclQ", Ev
, I1
, XX
},
1318 { "rcrQ", Ev
, I1
, XX
},
1319 { "shlQ", Ev
, I1
, XX
},
1320 { "shrQ", Ev
, I1
, XX
},
1321 { "(bad)", XX
, XX
, XX
},
1322 { "sarQ", Ev
, I1
, XX
},
1326 { "rolA", Eb
, CL
, XX
},
1327 { "rorA", Eb
, CL
, XX
},
1328 { "rclA", Eb
, CL
, XX
},
1329 { "rcrA", Eb
, CL
, XX
},
1330 { "shlA", Eb
, CL
, XX
},
1331 { "shrA", Eb
, CL
, XX
},
1332 { "(bad)", XX
, XX
, XX
},
1333 { "sarA", Eb
, CL
, XX
},
1337 { "rolQ", Ev
, CL
, XX
},
1338 { "rorQ", Ev
, CL
, XX
},
1339 { "rclQ", Ev
, CL
, XX
},
1340 { "rcrQ", Ev
, CL
, XX
},
1341 { "shlQ", Ev
, CL
, XX
},
1342 { "shrQ", Ev
, CL
, XX
},
1343 { "(bad)", XX
, XX
, XX
},
1344 { "sarQ", Ev
, CL
, XX
}
1348 { "testA", Eb
, Ib
, XX
},
1349 { "(bad)", Eb
, XX
, XX
},
1350 { "notA", Eb
, XX
, XX
},
1351 { "negA", Eb
, XX
, XX
},
1352 { "mulA", Eb
, XX
, XX
}, /* Don't print the implicit %al register, */
1353 { "imulA", Eb
, XX
, XX
}, /* to distinguish these opcodes from other */
1354 { "divA", Eb
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1355 { "idivA", Eb
, XX
, XX
} /* and idiv for consistency. */
1359 { "testQ", Ev
, Iv
, XX
},
1360 { "(bad)", XX
, XX
, XX
},
1361 { "notQ", Ev
, XX
, XX
},
1362 { "negQ", Ev
, XX
, XX
},
1363 { "mulQ", Ev
, XX
, XX
}, /* Don't print the implicit register. */
1364 { "imulQ", Ev
, XX
, XX
},
1365 { "divQ", Ev
, XX
, XX
},
1366 { "idivQ", Ev
, XX
, XX
},
1370 { "incA", Eb
, XX
, XX
},
1371 { "decA", Eb
, XX
, XX
},
1372 { "(bad)", XX
, XX
, XX
},
1373 { "(bad)", XX
, XX
, XX
},
1374 { "(bad)", XX
, XX
, XX
},
1375 { "(bad)", XX
, XX
, XX
},
1376 { "(bad)", XX
, XX
, XX
},
1377 { "(bad)", XX
, XX
, XX
},
1381 { "incQ", Ev
, XX
, XX
},
1382 { "decQ", Ev
, XX
, XX
},
1383 { "callT", indirEv
, XX
, XX
},
1384 { "JcallT", indirEp
, XX
, XX
},
1385 { "jmpT", indirEv
, XX
, XX
},
1386 { "JjmpT", indirEp
, XX
, XX
},
1387 { "pushU", stackEv
, XX
, XX
},
1388 { "(bad)", XX
, XX
, XX
},
1392 { "sldtQ", Ev
, XX
, XX
},
1393 { "strQ", Ev
, XX
, XX
},
1394 { "lldt", Ew
, XX
, XX
},
1395 { "ltr", Ew
, XX
, XX
},
1396 { "verr", Ew
, XX
, XX
},
1397 { "verw", Ew
, XX
, XX
},
1398 { "(bad)", XX
, XX
, XX
},
1399 { "(bad)", XX
, XX
, XX
}
1403 { "sgdtIQ", VMX_Fixup
, 0, XX
, XX
},
1404 { "sidtIQ", PNI_Fixup
, 0, XX
, XX
},
1405 { "lgdt{Q|Q||}", M
, XX
, XX
},
1406 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
},
1407 { "smswQ", Ev
, XX
, XX
},
1408 { "(bad)", XX
, XX
, XX
},
1409 { "lmsw", Ew
, XX
, XX
},
1410 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
},
1414 { "(bad)", XX
, XX
, XX
},
1415 { "(bad)", XX
, XX
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1417 { "(bad)", XX
, XX
, XX
},
1418 { "btQ", Ev
, Ib
, XX
},
1419 { "btsQ", Ev
, Ib
, XX
},
1420 { "btrQ", Ev
, Ib
, XX
},
1421 { "btcQ", Ev
, Ib
, XX
},
1425 { "(bad)", XX
, XX
, XX
},
1426 { "cmpxchg8b", Eq
, XX
, XX
},
1427 { "(bad)", XX
, XX
, XX
},
1428 { "(bad)", XX
, XX
, XX
},
1429 { "(bad)", XX
, XX
, XX
},
1430 { "(bad)", XX
, XX
, XX
},
1431 { "", VM
, XX
, XX
}, /* See OP_VMX. */
1432 { "vmptrst", Eq
, XX
, XX
},
1436 { "(bad)", XX
, XX
, XX
},
1437 { "(bad)", XX
, XX
, XX
},
1438 { "psrlw", MS
, Ib
, XX
},
1439 { "(bad)", XX
, XX
, XX
},
1440 { "psraw", MS
, Ib
, XX
},
1441 { "(bad)", XX
, XX
, XX
},
1442 { "psllw", MS
, Ib
, XX
},
1443 { "(bad)", XX
, XX
, XX
},
1447 { "(bad)", XX
, XX
, XX
},
1448 { "(bad)", XX
, XX
, XX
},
1449 { "psrld", MS
, Ib
, XX
},
1450 { "(bad)", XX
, XX
, XX
},
1451 { "psrad", MS
, Ib
, XX
},
1452 { "(bad)", XX
, XX
, XX
},
1453 { "pslld", MS
, Ib
, XX
},
1454 { "(bad)", XX
, XX
, XX
},
1458 { "(bad)", XX
, XX
, XX
},
1459 { "(bad)", XX
, XX
, XX
},
1460 { "psrlq", MS
, Ib
, XX
},
1461 { "psrldq", MS
, Ib
, XX
},
1462 { "(bad)", XX
, XX
, XX
},
1463 { "(bad)", XX
, XX
, XX
},
1464 { "psllq", MS
, Ib
, XX
},
1465 { "pslldq", MS
, Ib
, XX
},
1469 { "fxsave", Ev
, XX
, XX
},
1470 { "fxrstor", Ev
, XX
, XX
},
1471 { "ldmxcsr", Ev
, XX
, XX
},
1472 { "stmxcsr", Ev
, XX
, XX
},
1473 { "(bad)", XX
, XX
, XX
},
1474 { "lfence", OP_0fae
, 0, XX
, XX
},
1475 { "mfence", OP_0fae
, 0, XX
, XX
},
1476 { "clflush", OP_0fae
, 0, XX
, XX
},
1480 { "prefetchnta", Ev
, XX
, XX
},
1481 { "prefetcht0", Ev
, XX
, XX
},
1482 { "prefetcht1", Ev
, XX
, XX
},
1483 { "prefetcht2", Ev
, XX
, XX
},
1484 { "(bad)", XX
, XX
, XX
},
1485 { "(bad)", XX
, XX
, XX
},
1486 { "(bad)", XX
, XX
, XX
},
1487 { "(bad)", XX
, XX
, XX
},
1491 { "prefetch", Eb
, XX
, XX
},
1492 { "prefetchw", Eb
, XX
, XX
},
1493 { "(bad)", XX
, XX
, XX
},
1494 { "(bad)", XX
, XX
, XX
},
1495 { "(bad)", XX
, XX
, XX
},
1496 { "(bad)", XX
, XX
, XX
},
1497 { "(bad)", XX
, XX
, XX
},
1498 { "(bad)", XX
, XX
, XX
},
1502 { "xstore-rng", OP_0f07
, 0, XX
, XX
},
1503 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
},
1504 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
},
1505 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
},
1506 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
},
1507 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
},
1508 { "(bad)", OP_0f07
, 0, XX
, XX
},
1509 { "(bad)", OP_0f07
, 0, XX
, XX
},
1513 { "montmul", OP_0f07
, 0, XX
, XX
},
1514 { "xsha1", OP_0f07
, 0, XX
, XX
},
1515 { "xsha256", OP_0f07
, 0, XX
, XX
},
1516 { "(bad)", OP_0f07
, 0, XX
, XX
},
1517 { "(bad)", OP_0f07
, 0, XX
, XX
},
1518 { "(bad)", OP_0f07
, 0, XX
, XX
},
1519 { "(bad)", OP_0f07
, 0, XX
, XX
},
1520 { "(bad)", OP_0f07
, 0, XX
, XX
},
1524 static const struct dis386 prefix_user_table
[][4] = {
1527 { "addps", XM
, EX
, XX
},
1528 { "addss", XM
, EX
, XX
},
1529 { "addpd", XM
, EX
, XX
},
1530 { "addsd", XM
, EX
, XX
},
1534 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX. */
1535 { "", XM
, EX
, OPSIMD
},
1536 { "", XM
, EX
, OPSIMD
},
1537 { "", XM
, EX
, OPSIMD
},
1541 { "cvtpi2ps", XM
, EM
, XX
},
1542 { "cvtsi2ssY", XM
, Ev
, XX
},
1543 { "cvtpi2pd", XM
, EM
, XX
},
1544 { "cvtsi2sdY", XM
, Ev
, XX
},
1548 { "cvtps2pi", MX
, EX
, XX
},
1549 { "cvtss2siY", Gv
, EX
, XX
},
1550 { "cvtpd2pi", MX
, EX
, XX
},
1551 { "cvtsd2siY", Gv
, EX
, XX
},
1555 { "cvttps2pi", MX
, EX
, XX
},
1556 { "cvttss2siY", Gv
, EX
, XX
},
1557 { "cvttpd2pi", MX
, EX
, XX
},
1558 { "cvttsd2siY", Gv
, EX
, XX
},
1562 { "divps", XM
, EX
, XX
},
1563 { "divss", XM
, EX
, XX
},
1564 { "divpd", XM
, EX
, XX
},
1565 { "divsd", XM
, EX
, XX
},
1569 { "maxps", XM
, EX
, XX
},
1570 { "maxss", XM
, EX
, XX
},
1571 { "maxpd", XM
, EX
, XX
},
1572 { "maxsd", XM
, EX
, XX
},
1576 { "minps", XM
, EX
, XX
},
1577 { "minss", XM
, EX
, XX
},
1578 { "minpd", XM
, EX
, XX
},
1579 { "minsd", XM
, EX
, XX
},
1583 { "movups", XM
, EX
, XX
},
1584 { "movss", XM
, EX
, XX
},
1585 { "movupd", XM
, EX
, XX
},
1586 { "movsd", XM
, EX
, XX
},
1590 { "movups", EX
, XM
, XX
},
1591 { "movss", EX
, XM
, XX
},
1592 { "movupd", EX
, XM
, XX
},
1593 { "movsd", EX
, XM
, XX
},
1597 { "mulps", XM
, EX
, XX
},
1598 { "mulss", XM
, EX
, XX
},
1599 { "mulpd", XM
, EX
, XX
},
1600 { "mulsd", XM
, EX
, XX
},
1604 { "rcpps", XM
, EX
, XX
},
1605 { "rcpss", XM
, EX
, XX
},
1606 { "(bad)", XM
, EX
, XX
},
1607 { "(bad)", XM
, EX
, XX
},
1611 { "rsqrtps", XM
, EX
, XX
},
1612 { "rsqrtss", XM
, EX
, XX
},
1613 { "(bad)", XM
, EX
, XX
},
1614 { "(bad)", XM
, EX
, XX
},
1618 { "sqrtps", XM
, EX
, XX
},
1619 { "sqrtss", XM
, EX
, XX
},
1620 { "sqrtpd", XM
, EX
, XX
},
1621 { "sqrtsd", XM
, EX
, XX
},
1625 { "subps", XM
, EX
, XX
},
1626 { "subss", XM
, EX
, XX
},
1627 { "subpd", XM
, EX
, XX
},
1628 { "subsd", XM
, EX
, XX
},
1632 { "(bad)", XM
, EX
, XX
},
1633 { "cvtdq2pd", XM
, EX
, XX
},
1634 { "cvttpd2dq", XM
, EX
, XX
},
1635 { "cvtpd2dq", XM
, EX
, XX
},
1639 { "cvtdq2ps", XM
, EX
, XX
},
1640 { "cvttps2dq",XM
, EX
, XX
},
1641 { "cvtps2dq",XM
, EX
, XX
},
1642 { "(bad)", XM
, EX
, XX
},
1646 { "cvtps2pd", XM
, EX
, XX
},
1647 { "cvtss2sd", XM
, EX
, XX
},
1648 { "cvtpd2ps", XM
, EX
, XX
},
1649 { "cvtsd2ss", XM
, EX
, XX
},
1653 { "maskmovq", MX
, MS
, XX
},
1654 { "(bad)", XM
, EX
, XX
},
1655 { "maskmovdqu", XM
, EX
, XX
},
1656 { "(bad)", XM
, EX
, XX
},
1660 { "movq", MX
, EM
, XX
},
1661 { "movdqu", XM
, EX
, XX
},
1662 { "movdqa", XM
, EX
, XX
},
1663 { "(bad)", XM
, EX
, XX
},
1667 { "movq", EM
, MX
, XX
},
1668 { "movdqu", EX
, XM
, XX
},
1669 { "movdqa", EX
, XM
, XX
},
1670 { "(bad)", EX
, XM
, XX
},
1674 { "(bad)", EX
, XM
, XX
},
1675 { "movq2dq", XM
, MS
, XX
},
1676 { "movq", EX
, XM
, XX
},
1677 { "movdq2q", MX
, XS
, XX
},
1681 { "pshufw", MX
, EM
, Ib
},
1682 { "pshufhw", XM
, EX
, Ib
},
1683 { "pshufd", XM
, EX
, Ib
},
1684 { "pshuflw", XM
, EX
, Ib
},
1688 { "movd", Edq
, MX
, XX
},
1689 { "movq", XM
, EX
, XX
},
1690 { "movd", Edq
, XM
, XX
},
1691 { "(bad)", Ed
, XM
, XX
},
1695 { "(bad)", MX
, EX
, XX
},
1696 { "(bad)", XM
, EX
, XX
},
1697 { "punpckhqdq", XM
, EX
, XX
},
1698 { "(bad)", XM
, EX
, XX
},
1702 { "movntq", EM
, MX
, XX
},
1703 { "(bad)", EM
, XM
, XX
},
1704 { "movntdq", EM
, XM
, XX
},
1705 { "(bad)", EM
, XM
, XX
},
1709 { "(bad)", MX
, EX
, XX
},
1710 { "(bad)", XM
, EX
, XX
},
1711 { "punpcklqdq", XM
, EX
, XX
},
1712 { "(bad)", XM
, EX
, XX
},
1716 { "(bad)", MX
, EX
, XX
},
1717 { "(bad)", XM
, EX
, XX
},
1718 { "addsubpd", XM
, EX
, XX
},
1719 { "addsubps", XM
, EX
, XX
},
1723 { "(bad)", MX
, EX
, XX
},
1724 { "(bad)", XM
, EX
, XX
},
1725 { "haddpd", XM
, EX
, XX
},
1726 { "haddps", XM
, EX
, XX
},
1730 { "(bad)", MX
, EX
, XX
},
1731 { "(bad)", XM
, EX
, XX
},
1732 { "hsubpd", XM
, EX
, XX
},
1733 { "hsubps", XM
, EX
, XX
},
1737 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1738 { "movsldup", XM
, EX
, XX
},
1739 { "movlpd", XM
, EX
, XX
},
1740 { "movddup", XM
, EX
, XX
},
1744 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1745 { "movshdup", XM
, EX
, XX
},
1746 { "movhpd", XM
, EX
, XX
},
1747 { "(bad)", XM
, EX
, XX
},
1751 { "(bad)", XM
, EX
, XX
},
1752 { "(bad)", XM
, EX
, XX
},
1753 { "(bad)", XM
, EX
, XX
},
1754 { "lddqu", XM
, M
, XX
},
1758 static const struct dis386 x86_64_table
[][2] = {
1760 { "arpl", Ew
, Gw
, XX
},
1761 { "movs{||lq|xd}", Gv
, Ed
, XX
},
1765 static const struct dis386 three_byte_table
[][32] = {
1768 { "pshufb", MX
, EM
, XX
},
1769 { "phaddw", MX
, EM
, XX
},
1770 { "phaddd", MX
, EM
, XX
},
1771 { "phaddsw", MX
, EM
, XX
},
1772 { "pmaddubsw", MX
, EM
, XX
},
1773 { "phsubw", MX
, EM
, XX
},
1774 { "phsubd", MX
, EM
, XX
},
1775 { "phsubsw", MX
, EM
, XX
},
1776 { "psignb", MX
, EM
, XX
},
1777 { "psignw", MX
, EM
, XX
},
1778 { "psignd", MX
, EM
, XX
},
1779 { "pmulhrsw", MX
, EM
, XX
},
1780 { "(bad)", XX
, XX
, XX
},
1781 { "(bad)", XX
, XX
, XX
},
1782 { "(bad)", XX
, XX
, XX
},
1783 { "(bad)", XX
, XX
, XX
},
1784 { "(bad)", XX
, XX
, XX
},
1785 { "(bad)", XX
, XX
, XX
},
1786 { "(bad)", XX
, XX
, XX
},
1787 { "(bad)", XX
, XX
, XX
},
1788 { "(bad)", XX
, XX
, XX
},
1789 { "(bad)", XX
, XX
, XX
},
1790 { "(bad)", XX
, XX
, XX
},
1791 { "(bad)", XX
, XX
, XX
},
1792 { "(bad)", XX
, XX
, XX
},
1793 { "(bad)", XX
, XX
, XX
},
1794 { "(bad)", XX
, XX
, XX
},
1795 { "(bad)", XX
, XX
, XX
},
1796 { "pabsb", MX
, EM
, XX
},
1797 { "pabsw", MX
, EM
, XX
},
1798 { "pabsd", MX
, EM
, XX
},
1799 { "(bad)", XX
, XX
, XX
}
1803 { "(bad)", XX
, XX
, XX
},
1804 { "(bad)", XX
, XX
, XX
},
1805 { "(bad)", XX
, XX
, XX
},
1806 { "(bad)", XX
, XX
, XX
},
1807 { "(bad)", XX
, XX
, XX
},
1808 { "(bad)", XX
, XX
, XX
},
1809 { "(bad)", XX
, XX
, XX
},
1810 { "(bad)", XX
, XX
, XX
},
1811 { "(bad)", XX
, XX
, XX
},
1812 { "(bad)", XX
, XX
, XX
},
1813 { "(bad)", XX
, XX
, XX
},
1814 { "(bad)", XX
, XX
, XX
},
1815 { "(bad)", XX
, XX
, XX
},
1816 { "(bad)", XX
, XX
, XX
},
1817 { "(bad)", XX
, XX
, XX
},
1818 { "palignr", MX
, EM
, Ib
},
1819 { "(bad)", XX
, XX
, XX
},
1820 { "(bad)", XX
, XX
, XX
},
1821 { "(bad)", XX
, XX
, XX
},
1822 { "(bad)", XX
, XX
, XX
},
1823 { "(bad)", XX
, XX
, XX
},
1824 { "(bad)", XX
, XX
, XX
},
1825 { "(bad)", XX
, XX
, XX
},
1826 { "(bad)", XX
, XX
, XX
},
1827 { "(bad)", XX
, XX
, XX
},
1828 { "(bad)", XX
, XX
, XX
},
1829 { "(bad)", XX
, XX
, XX
},
1830 { "(bad)", XX
, XX
, XX
},
1831 { "(bad)", XX
, XX
, XX
},
1832 { "(bad)", XX
, XX
, XX
},
1833 { "(bad)", XX
, XX
, XX
},
1834 { "(bad)", XX
, XX
, XX
}
1838 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1850 FETCH_DATA (the_info
, codep
+ 1);
1854 /* REX prefixes family. */
1871 if (address_mode
== mode_64bit
)
1877 prefixes
|= PREFIX_REPZ
;
1880 prefixes
|= PREFIX_REPNZ
;
1883 prefixes
|= PREFIX_LOCK
;
1886 prefixes
|= PREFIX_CS
;
1889 prefixes
|= PREFIX_SS
;
1892 prefixes
|= PREFIX_DS
;
1895 prefixes
|= PREFIX_ES
;
1898 prefixes
|= PREFIX_FS
;
1901 prefixes
|= PREFIX_GS
;
1904 prefixes
|= PREFIX_DATA
;
1907 prefixes
|= PREFIX_ADDR
;
1910 /* fwait is really an instruction. If there are prefixes
1911 before the fwait, they belong to the fwait, *not* to the
1912 following instruction. */
1913 if (prefixes
|| rex
)
1915 prefixes
|= PREFIX_FWAIT
;
1919 prefixes
= PREFIX_FWAIT
;
1924 /* Rex is ignored when followed by another prefix. */
1935 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1939 prefix_name (int pref
, int sizeflag
)
1943 /* REX prefixes family. */
1995 return (sizeflag
& DFLAG
) ? "data16" : "data32";
1997 if (address_mode
== mode_64bit
)
1998 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2000 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2008 static char op1out
[100], op2out
[100], op3out
[100];
2009 static int op_ad
, op_index
[3];
2010 static int two_source_ops
;
2011 static bfd_vma op_address
[3];
2012 static bfd_vma op_riprel
[3];
2013 static bfd_vma start_pc
;
2016 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2017 * (see topic "Redundant prefixes" in the "Differences from 8086"
2018 * section of the "Virtual 8086 Mode" chapter.)
2019 * 'pc' should be the address of this instruction, it will
2020 * be used to print the target address if this is a relative jump or call
2021 * The function returns the length of this instruction in bytes.
2024 static char intel_syntax
;
2025 static char open_char
;
2026 static char close_char
;
2027 static char separator_char
;
2028 static char scale_char
;
2031 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2035 return print_insn (pc
, info
);
2039 print_insn (bfd_vma pc
, disassemble_info
*info
)
2041 const struct dis386
*dp
;
2043 char *first
, *second
, *third
;
2045 unsigned char uses_SSE_prefix
, uses_LOCK_prefix
;
2048 struct dis_private priv
;
2050 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2051 || info
->mach
== bfd_mach_x86_64
)
2052 address_mode
= mode_64bit
;
2054 address_mode
= mode_32bit
;
2056 if (intel_syntax
== (char) -1)
2057 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2058 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2060 if (info
->mach
== bfd_mach_i386_i386
2061 || info
->mach
== bfd_mach_x86_64
2062 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2063 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2064 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2065 else if (info
->mach
== bfd_mach_i386_i8086
)
2066 priv
.orig_sizeflag
= 0;
2070 for (p
= info
->disassembler_options
; p
!= NULL
; )
2072 if (strncmp (p
, "x86-64", 6) == 0)
2074 address_mode
= mode_64bit
;
2075 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2077 else if (strncmp (p
, "i386", 4) == 0)
2079 address_mode
= mode_32bit
;
2080 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2082 else if (strncmp (p
, "i8086", 5) == 0)
2084 address_mode
= mode_16bit
;
2085 priv
.orig_sizeflag
= 0;
2087 else if (strncmp (p
, "intel", 5) == 0)
2091 else if (strncmp (p
, "att", 3) == 0)
2095 else if (strncmp (p
, "addr", 4) == 0)
2097 if (p
[4] == '1' && p
[5] == '6')
2098 priv
.orig_sizeflag
&= ~AFLAG
;
2099 else if (p
[4] == '3' && p
[5] == '2')
2100 priv
.orig_sizeflag
|= AFLAG
;
2102 else if (strncmp (p
, "data", 4) == 0)
2104 if (p
[4] == '1' && p
[5] == '6')
2105 priv
.orig_sizeflag
&= ~DFLAG
;
2106 else if (p
[4] == '3' && p
[5] == '2')
2107 priv
.orig_sizeflag
|= DFLAG
;
2109 else if (strncmp (p
, "suffix", 6) == 0)
2110 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2112 p
= strchr (p
, ',');
2119 names64
= intel_names64
;
2120 names32
= intel_names32
;
2121 names16
= intel_names16
;
2122 names8
= intel_names8
;
2123 names8rex
= intel_names8rex
;
2124 names_seg
= intel_names_seg
;
2125 index16
= intel_index16
;
2128 separator_char
= '+';
2133 names64
= att_names64
;
2134 names32
= att_names32
;
2135 names16
= att_names16
;
2136 names8
= att_names8
;
2137 names8rex
= att_names8rex
;
2138 names_seg
= att_names_seg
;
2139 index16
= att_index16
;
2142 separator_char
= ',';
2146 /* The output looks better if we put 7 bytes on a line, since that
2147 puts most long word instructions on a single line. */
2148 info
->bytes_per_line
= 7;
2150 info
->private_data
= &priv
;
2151 priv
.max_fetched
= priv
.the_buffer
;
2152 priv
.insn_start
= pc
;
2159 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2163 start_codep
= priv
.the_buffer
;
2164 codep
= priv
.the_buffer
;
2166 if (setjmp (priv
.bailout
) != 0)
2170 /* Getting here means we tried for data but didn't get it. That
2171 means we have an incomplete instruction of some sort. Just
2172 print the first byte as a prefix or a .byte pseudo-op. */
2173 if (codep
> priv
.the_buffer
)
2175 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2177 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2180 /* Just print the first byte as a .byte instruction. */
2181 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2182 (unsigned int) priv
.the_buffer
[0]);
2195 sizeflag
= priv
.orig_sizeflag
;
2197 FETCH_DATA (info
, codep
+ 1);
2198 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2200 if (((prefixes
& PREFIX_FWAIT
)
2201 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2202 || (rex
&& rex_used
))
2206 /* fwait not followed by floating point instruction, or rex followed
2207 by other prefixes. Print the first prefix. */
2208 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2210 name
= INTERNAL_DISASSEMBLER_ERROR
;
2211 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2217 FETCH_DATA (info
, codep
+ 2);
2218 dp
= &dis386_twobyte
[*++codep
];
2219 need_modrm
= twobyte_has_modrm
[*codep
];
2220 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
2221 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
2225 dp
= &dis386
[*codep
];
2226 need_modrm
= onebyte_has_modrm
[*codep
];
2227 uses_SSE_prefix
= 0;
2228 uses_LOCK_prefix
= 0;
2232 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
2235 used_prefixes
|= PREFIX_REPZ
;
2237 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
2240 used_prefixes
|= PREFIX_REPNZ
;
2242 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
2245 used_prefixes
|= PREFIX_LOCK
;
2248 if (prefixes
& PREFIX_ADDR
)
2251 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
2253 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
2254 oappend ("addr32 ");
2256 oappend ("addr16 ");
2257 used_prefixes
|= PREFIX_ADDR
;
2261 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
2264 if (dp
->bytemode3
== cond_jump_mode
2265 && dp
->bytemode1
== v_mode
2268 if (sizeflag
& DFLAG
)
2269 oappend ("data32 ");
2271 oappend ("data16 ");
2272 used_prefixes
|= PREFIX_DATA
;
2276 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
2278 FETCH_DATA (info
, codep
+ 2);
2279 dp
= &three_byte_table
[dp
->bytemode2
][*codep
++];
2280 mod
= (*codep
>> 6) & 3;
2281 reg
= (*codep
>> 3) & 7;
2284 else if (need_modrm
)
2286 FETCH_DATA (info
, codep
+ 1);
2287 mod
= (*codep
>> 6) & 3;
2288 reg
= (*codep
>> 3) & 7;
2292 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2299 if (dp
->name
== NULL
)
2301 switch (dp
->bytemode1
)
2304 dp
= &grps
[dp
->bytemode2
][reg
];
2307 case USE_PREFIX_USER_TABLE
:
2309 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
2310 if (prefixes
& PREFIX_REPZ
)
2314 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2315 if (prefixes
& PREFIX_DATA
)
2319 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
2320 if (prefixes
& PREFIX_REPNZ
)
2324 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
2327 case X86_64_SPECIAL
:
2328 index
= address_mode
== mode_64bit
? 1 : 0;
2329 dp
= &x86_64_table
[dp
->bytemode2
][index
];
2333 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2338 if (putop (dp
->name
, sizeflag
) == 0)
2343 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2348 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2353 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
2357 /* See if any prefixes were not used. If so, print the first one
2358 separately. If we don't do this, we'll wind up printing an
2359 instruction stream which does not precisely correspond to the
2360 bytes we are disassembling. */
2361 if ((prefixes
& ~used_prefixes
) != 0)
2365 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2367 name
= INTERNAL_DISASSEMBLER_ERROR
;
2368 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2371 if (rex
& ~rex_used
)
2374 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
2376 name
= INTERNAL_DISASSEMBLER_ERROR
;
2377 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
2380 obufp
= obuf
+ strlen (obuf
);
2381 for (i
= strlen (obuf
); i
< 6; i
++)
2384 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2386 /* The enter and bound instructions are printed with operands in the same
2387 order as the intel book; everything else is printed in reverse order. */
2388 if (intel_syntax
|| two_source_ops
)
2393 op_ad
= op_index
[0];
2394 op_index
[0] = op_index
[2];
2395 op_index
[2] = op_ad
;
2406 if (op_index
[0] != -1 && !op_riprel
[0])
2407 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2409 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2415 (*info
->fprintf_func
) (info
->stream
, ",");
2416 if (op_index
[1] != -1 && !op_riprel
[1])
2417 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2419 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2425 (*info
->fprintf_func
) (info
->stream
, ",");
2426 if (op_index
[2] != -1 && !op_riprel
[2])
2427 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2429 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2431 for (i
= 0; i
< 3; i
++)
2432 if (op_index
[i
] != -1 && op_riprel
[i
])
2434 (*info
->fprintf_func
) (info
->stream
, " # ");
2435 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
2436 + op_address
[op_index
[i
]]), info
);
2438 return codep
- priv
.the_buffer
;
2441 static const char *float_mem
[] = {
2516 static const unsigned char float_mem_mode
[] = {
2592 #define STi OP_STi, 0
2594 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2595 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2596 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2597 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2598 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2599 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2600 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2601 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2602 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2604 static const struct dis386 float_reg
[][8] = {
2607 { "fadd", ST
, STi
, XX
},
2608 { "fmul", ST
, STi
, XX
},
2609 { "fcom", STi
, XX
, XX
},
2610 { "fcomp", STi
, XX
, XX
},
2611 { "fsub", ST
, STi
, XX
},
2612 { "fsubr", ST
, STi
, XX
},
2613 { "fdiv", ST
, STi
, XX
},
2614 { "fdivr", ST
, STi
, XX
},
2618 { "fld", STi
, XX
, XX
},
2619 { "fxch", STi
, XX
, XX
},
2621 { "(bad)", XX
, XX
, XX
},
2629 { "fcmovb", ST
, STi
, XX
},
2630 { "fcmove", ST
, STi
, XX
},
2631 { "fcmovbe",ST
, STi
, XX
},
2632 { "fcmovu", ST
, STi
, XX
},
2633 { "(bad)", XX
, XX
, XX
},
2635 { "(bad)", XX
, XX
, XX
},
2636 { "(bad)", XX
, XX
, XX
},
2640 { "fcmovnb",ST
, STi
, XX
},
2641 { "fcmovne",ST
, STi
, XX
},
2642 { "fcmovnbe",ST
, STi
, XX
},
2643 { "fcmovnu",ST
, STi
, XX
},
2645 { "fucomi", ST
, STi
, XX
},
2646 { "fcomi", ST
, STi
, XX
},
2647 { "(bad)", XX
, XX
, XX
},
2651 { "fadd", STi
, ST
, XX
},
2652 { "fmul", STi
, ST
, XX
},
2653 { "(bad)", XX
, XX
, XX
},
2654 { "(bad)", XX
, XX
, XX
},
2656 { "fsub", STi
, ST
, XX
},
2657 { "fsubr", STi
, ST
, XX
},
2658 { "fdiv", STi
, ST
, XX
},
2659 { "fdivr", STi
, ST
, XX
},
2661 { "fsubr", STi
, ST
, XX
},
2662 { "fsub", STi
, ST
, XX
},
2663 { "fdivr", STi
, ST
, XX
},
2664 { "fdiv", STi
, ST
, XX
},
2669 { "ffree", STi
, XX
, XX
},
2670 { "(bad)", XX
, XX
, XX
},
2671 { "fst", STi
, XX
, XX
},
2672 { "fstp", STi
, XX
, XX
},
2673 { "fucom", STi
, XX
, XX
},
2674 { "fucomp", STi
, XX
, XX
},
2675 { "(bad)", XX
, XX
, XX
},
2676 { "(bad)", XX
, XX
, XX
},
2680 { "faddp", STi
, ST
, XX
},
2681 { "fmulp", STi
, ST
, XX
},
2682 { "(bad)", XX
, XX
, XX
},
2685 { "fsubp", STi
, ST
, XX
},
2686 { "fsubrp", STi
, ST
, XX
},
2687 { "fdivp", STi
, ST
, XX
},
2688 { "fdivrp", STi
, ST
, XX
},
2690 { "fsubrp", STi
, ST
, XX
},
2691 { "fsubp", STi
, ST
, XX
},
2692 { "fdivrp", STi
, ST
, XX
},
2693 { "fdivp", STi
, ST
, XX
},
2698 { "ffreep", STi
, XX
, XX
},
2699 { "(bad)", XX
, XX
, XX
},
2700 { "(bad)", XX
, XX
, XX
},
2701 { "(bad)", XX
, XX
, XX
},
2703 { "fucomip",ST
, STi
, XX
},
2704 { "fcomip", ST
, STi
, XX
},
2705 { "(bad)", XX
, XX
, XX
},
2709 static const char *fgrps
[][8] = {
2712 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2717 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2722 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2727 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2732 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2737 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2742 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2743 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2748 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2753 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2758 dofloat (int sizeflag
)
2760 const struct dis386
*dp
;
2761 unsigned char floatop
;
2763 floatop
= codep
[-1];
2767 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
2769 putop (float_mem
[fp_indx
], sizeflag
);
2772 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
2775 /* Skip mod/rm byte. */
2779 dp
= &float_reg
[floatop
- 0xd8][reg
];
2780 if (dp
->name
== NULL
)
2782 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2784 /* Instruction fnstsw is only one with strange arg. */
2785 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2786 pstrcpy (op1out
, sizeof(op1out
), names16
[0]);
2790 putop (dp
->name
, sizeflag
);
2795 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2800 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2805 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2807 oappend ("%st" + intel_syntax
);
2811 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2813 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%st(%d)", rm
);
2814 oappend (scratchbuf
+ intel_syntax
);
2817 /* Capital letters in template are macros. */
2819 putop (const char *template, int sizeflag
)
2824 for (p
= template; *p
; p
++)
2835 if (address_mode
== mode_64bit
)
2843 /* Alternative not valid. */
2844 pstrcpy (obuf
, sizeof(obuf
), "(bad)");
2848 else if (*p
== '\0')
2869 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2875 if (sizeflag
& SUFFIX_ALWAYS
)
2879 if (intel_syntax
&& !alt
)
2881 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
2883 if (sizeflag
& DFLAG
)
2884 *obufp
++ = intel_syntax
? 'd' : 'l';
2886 *obufp
++ = intel_syntax
? 'w' : 's';
2887 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2890 case 'E': /* For jcxz/jecxz */
2891 if (address_mode
== mode_64bit
)
2893 if (sizeflag
& AFLAG
)
2899 if (sizeflag
& AFLAG
)
2901 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2906 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
2908 if (sizeflag
& AFLAG
)
2909 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
2911 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
2912 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2918 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
2919 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
2921 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
2924 if (prefixes
& PREFIX_DS
)
2938 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
2947 if (sizeflag
& SUFFIX_ALWAYS
)
2951 if ((prefixes
& PREFIX_FWAIT
) == 0)
2954 used_prefixes
|= PREFIX_FWAIT
;
2957 USED_REX (REX_MODE64
);
2958 if (rex
& REX_MODE64
)
2966 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2975 if ((prefixes
& PREFIX_DATA
)
2976 || (rex
& REX_MODE64
)
2977 || (sizeflag
& SUFFIX_ALWAYS
))
2979 USED_REX (REX_MODE64
);
2980 if (rex
& REX_MODE64
)
2984 if (sizeflag
& DFLAG
)
2989 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2995 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2997 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3003 if (intel_syntax
&& !alt
)
3005 USED_REX (REX_MODE64
);
3006 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3008 if (rex
& REX_MODE64
)
3012 if (sizeflag
& DFLAG
)
3013 *obufp
++ = intel_syntax
? 'd' : 'l';
3017 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3021 USED_REX (REX_MODE64
);
3024 if (rex
& REX_MODE64
)
3029 else if (sizeflag
& DFLAG
)
3042 if (rex
& REX_MODE64
)
3044 else if (sizeflag
& DFLAG
)
3049 if (!(rex
& REX_MODE64
))
3050 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3055 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3057 if (sizeflag
& SUFFIX_ALWAYS
)
3065 if (sizeflag
& SUFFIX_ALWAYS
)
3067 if (rex
& REX_MODE64
)
3071 if (sizeflag
& DFLAG
)
3075 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3080 if (prefixes
& PREFIX_DATA
)
3084 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3089 if (rex
& REX_MODE64
)
3091 USED_REX (REX_MODE64
);
3095 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3097 /* operand size flag for cwtl, cbtw */
3101 else if (sizeflag
& DFLAG
)
3112 if (sizeflag
& DFLAG
)
3123 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3133 oappend (const char *s
)
3136 obufp
+= strlen (s
);
3142 if (prefixes
& PREFIX_CS
)
3144 used_prefixes
|= PREFIX_CS
;
3145 oappend ("%cs:" + intel_syntax
);
3147 if (prefixes
& PREFIX_DS
)
3149 used_prefixes
|= PREFIX_DS
;
3150 oappend ("%ds:" + intel_syntax
);
3152 if (prefixes
& PREFIX_SS
)
3154 used_prefixes
|= PREFIX_SS
;
3155 oappend ("%ss:" + intel_syntax
);
3157 if (prefixes
& PREFIX_ES
)
3159 used_prefixes
|= PREFIX_ES
;
3160 oappend ("%es:" + intel_syntax
);
3162 if (prefixes
& PREFIX_FS
)
3164 used_prefixes
|= PREFIX_FS
;
3165 oappend ("%fs:" + intel_syntax
);
3167 if (prefixes
& PREFIX_GS
)
3169 used_prefixes
|= PREFIX_GS
;
3170 oappend ("%gs:" + intel_syntax
);
3175 OP_indirE (int bytemode
, int sizeflag
)
3179 OP_E (bytemode
, sizeflag
);
3183 print_operand_value (char *buf
, size_t bufsize
, int hex
, bfd_vma disp
)
3185 if (address_mode
== mode_64bit
)
3193 snprintf_vma (tmp
, sizeof(tmp
), disp
);
3194 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
3195 pstrcpy (buf
+ 2, bufsize
- 2, tmp
+ i
);
3199 bfd_signed_vma v
= disp
;
3206 /* Check for possible overflow on 0x8000000000000000. */
3209 pstrcpy (buf
, bufsize
, "9223372036854775808");
3215 pstrcpy (buf
, bufsize
, "0");
3223 tmp
[28 - i
] = (v
% 10) + '0';
3227 pstrcpy (buf
, bufsize
, tmp
+ 29 - i
);
3233 snprintf (buf
, bufsize
, "0x%x", (unsigned int) disp
);
3235 snprintf (buf
, bufsize
, "%d", (int) disp
);
3240 intel_operand_size (int bytemode
, int sizeflag
)
3245 oappend ("BYTE PTR ");
3249 oappend ("WORD PTR ");
3252 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3254 oappend ("QWORD PTR ");
3255 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3261 USED_REX (REX_MODE64
);
3262 if (rex
& REX_MODE64
)
3263 oappend ("QWORD PTR ");
3264 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
3265 oappend ("DWORD PTR ");
3267 oappend ("WORD PTR ");
3268 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3271 oappend ("DWORD PTR ");
3274 oappend ("QWORD PTR ");
3277 if (address_mode
== mode_64bit
)
3278 oappend ("QWORD PTR ");
3280 oappend ("DWORD PTR ");
3283 if (sizeflag
& DFLAG
)
3284 oappend ("FWORD PTR ");
3286 oappend ("DWORD PTR ");
3287 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3290 oappend ("TBYTE PTR ");
3293 oappend ("XMMWORD PTR ");
3301 OP_E (int bytemode
, int sizeflag
)
3306 USED_REX (REX_EXTZ
);
3310 /* Skip mod/rm byte. */
3321 oappend (names8rex
[rm
+ add
]);
3323 oappend (names8
[rm
+ add
]);
3326 oappend (names16
[rm
+ add
]);
3329 oappend (names32
[rm
+ add
]);
3332 oappend (names64
[rm
+ add
]);
3335 if (address_mode
== mode_64bit
)
3336 oappend (names64
[rm
+ add
]);
3338 oappend (names32
[rm
+ add
]);
3341 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3343 oappend (names64
[rm
+ add
]);
3344 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3352 USED_REX (REX_MODE64
);
3353 if (rex
& REX_MODE64
)
3354 oappend (names64
[rm
+ add
]);
3355 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3356 oappend (names32
[rm
+ add
]);
3358 oappend (names16
[rm
+ add
]);
3359 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3364 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3372 intel_operand_size (bytemode
, sizeflag
);
3375 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
3390 FETCH_DATA (the_info
, codep
+ 1);
3391 index
= (*codep
>> 3) & 7;
3392 if (address_mode
== mode_64bit
|| index
!= 0x4)
3393 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3394 scale
= (*codep
>> 6) & 3;
3396 USED_REX (REX_EXTY
);
3406 if ((base
& 7) == 5)
3409 if (address_mode
== mode_64bit
&& !havesib
)
3415 FETCH_DATA (the_info
, codep
+ 1);
3417 if ((disp
& 0x80) != 0)
3426 if (mod
!= 0 || (base
& 7) == 5)
3428 print_operand_value (scratchbuf
, sizeof(scratchbuf
), !riprel
, disp
);
3429 oappend (scratchbuf
);
3437 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
3439 *obufp
++ = open_char
;
3440 if (intel_syntax
&& riprel
)
3444 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3445 ? names64
[base
] : names32
[base
]);
3450 if (!intel_syntax
|| havebase
)
3452 *obufp
++ = separator_char
;
3455 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3456 ? names64
[index
] : names32
[index
]);
3458 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
3460 *obufp
++ = scale_char
;
3462 snprintf (scratchbuf
, sizeof(scratchbuf
), "%d", 1 << scale
);
3463 oappend (scratchbuf
);
3466 if (intel_syntax
&& disp
)
3468 if ((bfd_signed_vma
) disp
> 0)
3477 disp
= - (bfd_signed_vma
) disp
;
3480 print_operand_value (scratchbuf
, sizeof(scratchbuf
), mod
!= 1,
3482 oappend (scratchbuf
);
3485 *obufp
++ = close_char
;
3488 else if (intel_syntax
)
3490 if (mod
!= 0 || (base
& 7) == 5)
3492 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3493 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3497 oappend (names_seg
[ds_reg
- es_reg
]);
3500 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, disp
);
3501 oappend (scratchbuf
);
3506 { /* 16 bit address mode */
3513 if ((disp
& 0x8000) != 0)
3518 FETCH_DATA (the_info
, codep
+ 1);
3520 if ((disp
& 0x80) != 0)
3525 if ((disp
& 0x8000) != 0)
3531 if (mod
!= 0 || rm
== 6)
3533 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 0, disp
);
3534 oappend (scratchbuf
);
3537 if (mod
!= 0 || rm
!= 6)
3539 *obufp
++ = open_char
;
3541 oappend (index16
[rm
]);
3542 if (intel_syntax
&& disp
)
3544 if ((bfd_signed_vma
) disp
> 0)
3553 disp
= - (bfd_signed_vma
) disp
;
3556 print_operand_value (scratchbuf
, sizeof(scratchbuf
), mod
!= 1,
3558 oappend (scratchbuf
);
3561 *obufp
++ = close_char
;
3564 else if (intel_syntax
)
3566 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3567 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3571 oappend (names_seg
[ds_reg
- es_reg
]);
3574 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1,
3576 oappend (scratchbuf
);
3582 OP_G (int bytemode
, int sizeflag
)
3585 USED_REX (REX_EXTX
);
3593 oappend (names8rex
[reg
+ add
]);
3595 oappend (names8
[reg
+ add
]);
3598 oappend (names16
[reg
+ add
]);
3601 oappend (names32
[reg
+ add
]);
3604 oappend (names64
[reg
+ add
]);
3609 USED_REX (REX_MODE64
);
3610 if (rex
& REX_MODE64
)
3611 oappend (names64
[reg
+ add
]);
3612 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3613 oappend (names32
[reg
+ add
]);
3615 oappend (names16
[reg
+ add
]);
3616 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3619 if (address_mode
== mode_64bit
)
3620 oappend (names64
[reg
+ add
]);
3622 oappend (names32
[reg
+ add
]);
3625 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3638 FETCH_DATA (the_info
, codep
+ 8);
3639 a
= *codep
++ & 0xff;
3640 a
|= (*codep
++ & 0xff) << 8;
3641 a
|= (*codep
++ & 0xff) << 16;
3642 a
|= (*codep
++ & 0xff) << 24;
3643 b
= *codep
++ & 0xff;
3644 b
|= (*codep
++ & 0xff) << 8;
3645 b
|= (*codep
++ & 0xff) << 16;
3646 b
|= (*codep
++ & 0xff) << 24;
3647 x
= a
+ ((bfd_vma
) b
<< 32);
3655 static bfd_signed_vma
3658 bfd_signed_vma x
= 0;
3660 FETCH_DATA (the_info
, codep
+ 4);
3661 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3662 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3663 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3664 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3668 static bfd_signed_vma
3671 bfd_signed_vma x
= 0;
3673 FETCH_DATA (the_info
, codep
+ 4);
3674 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3675 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3676 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3677 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3679 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
3689 FETCH_DATA (the_info
, codep
+ 2);
3690 x
= *codep
++ & 0xff;
3691 x
|= (*codep
++ & 0xff) << 8;
3696 set_op (bfd_vma op
, int riprel
)
3698 op_index
[op_ad
] = op_ad
;
3699 if (address_mode
== mode_64bit
)
3701 op_address
[op_ad
] = op
;
3702 op_riprel
[op_ad
] = riprel
;
3706 /* Mask to get a 32-bit address. */
3707 op_address
[op_ad
] = op
& 0xffffffff;
3708 op_riprel
[op_ad
] = riprel
& 0xffffffff;
3713 OP_REG (int code
, int sizeflag
)
3717 USED_REX (REX_EXTZ
);
3729 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3730 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3731 s
= names16
[code
- ax_reg
+ add
];
3733 case es_reg
: case ss_reg
: case cs_reg
:
3734 case ds_reg
: case fs_reg
: case gs_reg
:
3735 s
= names_seg
[code
- es_reg
+ add
];
3737 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3738 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3741 s
= names8rex
[code
- al_reg
+ add
];
3743 s
= names8
[code
- al_reg
];
3745 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
3746 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
3747 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3749 s
= names64
[code
- rAX_reg
+ add
];
3752 code
+= eAX_reg
- rAX_reg
;
3754 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3755 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3756 USED_REX (REX_MODE64
);
3757 if (rex
& REX_MODE64
)
3758 s
= names64
[code
- eAX_reg
+ add
];
3759 else if (sizeflag
& DFLAG
)
3760 s
= names32
[code
- eAX_reg
+ add
];
3762 s
= names16
[code
- eAX_reg
+ add
];
3763 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3766 s
= INTERNAL_DISASSEMBLER_ERROR
;
3773 OP_IMREG (int code
, int sizeflag
)
3785 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3786 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3787 s
= names16
[code
- ax_reg
];
3789 case es_reg
: case ss_reg
: case cs_reg
:
3790 case ds_reg
: case fs_reg
: case gs_reg
:
3791 s
= names_seg
[code
- es_reg
];
3793 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3794 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3797 s
= names8rex
[code
- al_reg
];
3799 s
= names8
[code
- al_reg
];
3801 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3802 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3803 USED_REX (REX_MODE64
);
3804 if (rex
& REX_MODE64
)
3805 s
= names64
[code
- eAX_reg
];
3806 else if (sizeflag
& DFLAG
)
3807 s
= names32
[code
- eAX_reg
];
3809 s
= names16
[code
- eAX_reg
];
3810 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3813 s
= INTERNAL_DISASSEMBLER_ERROR
;
3820 OP_I (int bytemode
, int sizeflag
)
3823 bfd_signed_vma mask
= -1;
3828 FETCH_DATA (the_info
, codep
+ 1);
3833 if (address_mode
== mode_64bit
)
3840 USED_REX (REX_MODE64
);
3841 if (rex
& REX_MODE64
)
3843 else if (sizeflag
& DFLAG
)
3853 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3864 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3869 scratchbuf
[0] = '$';
3870 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
3871 oappend (scratchbuf
+ intel_syntax
);
3872 scratchbuf
[0] = '\0';
3876 OP_I64 (int bytemode
, int sizeflag
)
3879 bfd_signed_vma mask
= -1;
3881 if (address_mode
!= mode_64bit
)
3883 OP_I (bytemode
, sizeflag
);
3890 FETCH_DATA (the_info
, codep
+ 1);
3895 USED_REX (REX_MODE64
);
3896 if (rex
& REX_MODE64
)
3898 else if (sizeflag
& DFLAG
)
3908 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3915 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3920 scratchbuf
[0] = '$';
3921 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
3922 oappend (scratchbuf
+ intel_syntax
);
3923 scratchbuf
[0] = '\0';
3927 OP_sI (int bytemode
, int sizeflag
)
3930 bfd_signed_vma mask
= -1;
3935 FETCH_DATA (the_info
, codep
+ 1);
3937 if ((op
& 0x80) != 0)
3942 USED_REX (REX_MODE64
);
3943 if (rex
& REX_MODE64
)
3945 else if (sizeflag
& DFLAG
)
3954 if ((op
& 0x8000) != 0)
3957 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3962 if ((op
& 0x8000) != 0)
3966 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3970 scratchbuf
[0] = '$';
3971 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
3972 oappend (scratchbuf
+ intel_syntax
);
3976 OP_J (int bytemode
, int sizeflag
)
3984 FETCH_DATA (the_info
, codep
+ 1);
3986 if ((disp
& 0x80) != 0)
3990 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
3995 /* For some reason, a data16 prefix on a jump instruction
3996 means that the pc is masked to 16 bits after the
3997 displacement is added! */
4002 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4005 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4007 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, disp
);
4008 oappend (scratchbuf
);
4012 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4014 oappend (names_seg
[reg
]);
4018 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4022 if (sizeflag
& DFLAG
)
4032 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4034 snprintf (scratchbuf
, sizeof(scratchbuf
), "0x%x:0x%x", seg
, offset
);
4036 snprintf (scratchbuf
, sizeof(scratchbuf
), "$0x%x,$0x%x", seg
, offset
);
4037 oappend (scratchbuf
);
4041 OP_OFF (int bytemode
, int sizeflag
)
4045 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4046 intel_operand_size (bytemode
, sizeflag
);
4049 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4056 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4057 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4059 oappend (names_seg
[ds_reg
- es_reg
]);
4063 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, off
);
4064 oappend (scratchbuf
);
4068 OP_OFF64 (int bytemode
, int sizeflag
)
4072 if (address_mode
!= mode_64bit
)
4074 OP_OFF (bytemode
, sizeflag
);
4078 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4079 intel_operand_size (bytemode
, sizeflag
);
4086 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4087 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4089 oappend (names_seg
[ds_reg
- es_reg
]);
4093 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, off
);
4094 oappend (scratchbuf
);
4098 ptr_reg (int code
, int sizeflag
)
4102 *obufp
++ = open_char
;
4103 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4104 if (address_mode
== mode_64bit
)
4106 if (!(sizeflag
& AFLAG
))
4107 s
= names32
[code
- eAX_reg
];
4109 s
= names64
[code
- eAX_reg
];
4111 else if (sizeflag
& AFLAG
)
4112 s
= names32
[code
- eAX_reg
];
4114 s
= names16
[code
- eAX_reg
];
4116 *obufp
++ = close_char
;
4121 OP_ESreg (int code
, int sizeflag
)
4124 intel_operand_size (codep
[-1] & 1 ? v_mode
: b_mode
, sizeflag
);
4125 oappend ("%es:" + intel_syntax
);
4126 ptr_reg (code
, sizeflag
);
4130 OP_DSreg (int code
, int sizeflag
)
4133 intel_operand_size (codep
[-1] != 0xd7 && (codep
[-1] & 1)
4144 prefixes
|= PREFIX_DS
;
4146 ptr_reg (code
, sizeflag
);
4150 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4155 USED_REX (REX_EXTX
);
4158 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
4160 used_prefixes
|= PREFIX_LOCK
;
4163 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%cr%d", reg
+ add
);
4164 oappend (scratchbuf
+ intel_syntax
);
4168 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4171 USED_REX (REX_EXTX
);
4175 snprintf (scratchbuf
, sizeof(scratchbuf
), "db%d", reg
+ add
);
4177 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%db%d", reg
+ add
);
4178 oappend (scratchbuf
);
4182 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4184 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%tr%d", reg
);
4185 oappend (scratchbuf
+ intel_syntax
);
4189 OP_Rd (int bytemode
, int sizeflag
)
4192 OP_E (bytemode
, sizeflag
);
4198 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4200 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4201 if (prefixes
& PREFIX_DATA
)
4204 USED_REX (REX_EXTX
);
4207 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", reg
+ add
);
4210 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", reg
);
4211 oappend (scratchbuf
+ intel_syntax
);
4215 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4218 USED_REX (REX_EXTX
);
4221 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", reg
+ add
);
4222 oappend (scratchbuf
+ intel_syntax
);
4226 OP_EM (int bytemode
, int sizeflag
)
4230 if (intel_syntax
&& bytemode
== v_mode
)
4232 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
4233 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4235 OP_E (bytemode
, sizeflag
);
4239 /* Skip mod/rm byte. */
4242 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4243 if (prefixes
& PREFIX_DATA
)
4247 USED_REX (REX_EXTZ
);
4250 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", rm
+ add
);
4253 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", rm
);
4254 oappend (scratchbuf
+ intel_syntax
);
4258 OP_EX (int bytemode
, int sizeflag
)
4263 if (intel_syntax
&& bytemode
== v_mode
)
4265 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
4267 case 0: bytemode
= x_mode
; break;
4268 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
4269 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
4270 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
4271 default: bytemode
= 0; break;
4274 OP_E (bytemode
, sizeflag
);
4277 USED_REX (REX_EXTZ
);
4281 /* Skip mod/rm byte. */
4284 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", rm
+ add
);
4285 oappend (scratchbuf
+ intel_syntax
);
4289 OP_MS (int bytemode
, int sizeflag
)
4292 OP_EM (bytemode
, sizeflag
);
4298 OP_XS (int bytemode
, int sizeflag
)
4301 OP_EX (bytemode
, sizeflag
);
4307 OP_M (int bytemode
, int sizeflag
)
4310 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4312 OP_E (bytemode
, sizeflag
);
4316 OP_0f07 (int bytemode
, int sizeflag
)
4318 if (mod
!= 3 || rm
!= 0)
4321 OP_E (bytemode
, sizeflag
);
4325 OP_0fae (int bytemode
, int sizeflag
)
4330 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
4332 if (reg
< 5 || rm
!= 0)
4334 BadOp (); /* bad sfence, mfence, or lfence */
4340 BadOp (); /* bad clflush */
4344 OP_E (bytemode
, sizeflag
);
4348 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4350 /* NOP with REPZ prefix is called PAUSE. */
4351 if (prefixes
== PREFIX_REPZ
)
4352 strcpy (obuf
, "pause");
4355 static const char *Suffix3DNow
[] = {
4356 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4357 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4358 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4359 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4360 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4361 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4362 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4363 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4364 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4365 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4366 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4367 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4368 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4369 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4370 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4371 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4372 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4373 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4374 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4375 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4376 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4377 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4378 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4379 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4380 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4381 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4382 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4383 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4384 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4385 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4386 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4387 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4388 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4389 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4390 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4391 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4392 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4393 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4394 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4395 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4396 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4397 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4398 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4399 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4400 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4401 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4402 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4403 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4404 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4405 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4406 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4407 /* CC */ NULL
, NULL
, NULL
, NULL
,
4408 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4409 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4410 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4411 /* DC */ NULL
, NULL
, NULL
, NULL
,
4412 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4413 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4414 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4415 /* EC */ NULL
, NULL
, NULL
, NULL
,
4416 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4417 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4418 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4419 /* FC */ NULL
, NULL
, NULL
, NULL
,
4423 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4425 const char *mnemonic
;
4427 FETCH_DATA (the_info
, codep
+ 1);
4428 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4429 place where an 8-bit immediate would normally go. ie. the last
4430 byte of the instruction. */
4431 obufp
= obuf
+ strlen (obuf
);
4432 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
4437 /* Since a variable sized modrm/sib chunk is between the start
4438 of the opcode (0x0f0f) and the opcode suffix, we need to do
4439 all the modrm processing first, and don't know until now that
4440 we have a bad opcode. This necessitates some cleaning up. */
4447 static const char *simd_cmp_op
[] = {
4459 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4461 unsigned int cmp_type
;
4463 FETCH_DATA (the_info
, codep
+ 1);
4464 obufp
= obuf
+ strlen (obuf
);
4465 cmp_type
= *codep
++ & 0xff;
4468 char suffix1
= 'p', suffix2
= 's';
4469 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4470 if (prefixes
& PREFIX_REPZ
)
4474 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4475 if (prefixes
& PREFIX_DATA
)
4479 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4480 if (prefixes
& PREFIX_REPNZ
)
4481 suffix1
= 's', suffix2
= 'd';
4484 snprintf (scratchbuf
, sizeof(scratchbuf
), "cmp%s%c%c",
4485 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
4486 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4487 oappend (scratchbuf
);
4491 /* We have a bad extension byte. Clean up. */
4499 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
4501 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4502 forms of these instructions. */
4505 char *p
= obuf
+ strlen (obuf
);
4508 *(p
- 1) = *(p
- 2);
4509 *(p
- 2) = *(p
- 3);
4510 *(p
- 3) = extrachar
;
4515 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4517 if (mod
== 3 && reg
== 1 && rm
<= 1)
4519 /* Override "sidt". */
4520 size_t olen
= strlen (obuf
);
4521 char *p
= obuf
+ olen
- 4;
4522 const char * const *names
= (address_mode
== mode_64bit
4523 ? names64
: names32
);
4525 /* We might have a suffix when disassembling with -Msuffix. */
4529 /* Remove "addr16/addr32" if we aren't in Intel mode. */
4531 && (prefixes
& PREFIX_ADDR
)
4534 && strncmp (p
- 7, "addr", 4) == 0
4535 && (strncmp (p
- 3, "16", 2) == 0
4536 || strncmp (p
- 3, "32", 2) == 0))
4541 /* mwait %eax,%ecx */
4542 strcpy (p
, "mwait");
4544 strcpy (op1out
, names
[0]);
4548 /* monitor %eax,%ecx,%edx" */
4549 strcpy (p
, "monitor");
4552 const char * const *op1_names
;
4553 if (!(prefixes
& PREFIX_ADDR
))
4554 op1_names
= (address_mode
== mode_16bit
4558 op1_names
= (address_mode
!= mode_32bit
4559 ? names32
: names16
);
4560 used_prefixes
|= PREFIX_ADDR
;
4562 strcpy (op1out
, op1_names
[0]);
4563 strcpy (op3out
, names
[2]);
4568 strcpy (op2out
, names
[1]);
4579 SVME_Fixup (int bytemode
, int sizeflag
)
4611 OP_M (bytemode
, sizeflag
);
4614 /* Override "lidt". */
4615 p
= obuf
+ strlen (obuf
) - 4;
4616 /* We might have a suffix. */
4620 if (!(prefixes
& PREFIX_ADDR
))
4625 used_prefixes
|= PREFIX_ADDR
;
4629 strcpy (op2out
, names32
[1]);
4635 *obufp
++ = open_char
;
4636 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
4640 strcpy (obufp
, alt
);
4641 obufp
+= strlen (alt
);
4642 *obufp
++ = close_char
;
4649 INVLPG_Fixup (int bytemode
, int sizeflag
)
4662 OP_M (bytemode
, sizeflag
);
4665 /* Override "invlpg". */
4666 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
4673 /* Throw away prefixes and 1st. opcode byte. */
4674 codep
= insn_codep
+ 1;
4679 SEG_Fixup (int extrachar
, int sizeflag
)
4683 /* We need to add a proper suffix with
4694 if (prefixes
& PREFIX_DATA
)
4698 USED_REX (REX_MODE64
);
4699 if (rex
& REX_MODE64
)
4704 strcat (obuf
, suffix
);
4708 /* We need to fix the suffix for
4715 Override "mov[l|q]". */
4716 char *p
= obuf
+ strlen (obuf
) - 1;
4718 /* We might not have a suffix. */
4724 OP_E (extrachar
, sizeflag
);
4728 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4730 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
4732 /* Override "sgdt". */
4733 char *p
= obuf
+ strlen (obuf
) - 4;
4735 /* We might have a suffix when disassembling with -Msuffix. */
4742 strcpy (p
, "vmcall");
4745 strcpy (p
, "vmlaunch");
4748 strcpy (p
, "vmresume");
4751 strcpy (p
, "vmxoff");
4762 OP_VMX (int bytemode
, int sizeflag
)
4764 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
4765 if (prefixes
& PREFIX_DATA
)
4766 strcpy (obuf
, "vmclear");
4767 else if (prefixes
& PREFIX_REPZ
)
4768 strcpy (obuf
, "vmxon");
4770 strcpy (obuf
, "vmptrld");
4771 OP_E (bytemode
, sizeflag
);
4775 REP_Fixup (int bytemode
, int sizeflag
)
4777 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
4781 if (prefixes
& PREFIX_REPZ
)
4782 switch (*insn_codep
)
4784 case 0x6e: /* outsb */
4785 case 0x6f: /* outsw/outsl */
4786 case 0xa4: /* movsb */
4787 case 0xa5: /* movsw/movsl/movsq */
4793 case 0xaa: /* stosb */
4794 case 0xab: /* stosw/stosl/stosq */
4795 case 0xac: /* lodsb */
4796 case 0xad: /* lodsw/lodsl/lodsq */
4797 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4802 case 0x6c: /* insb */
4803 case 0x6d: /* insl/insw */
4819 olen
= strlen (obuf
);
4820 p
= obuf
+ olen
- ilen
- 1 - 4;
4821 /* Handle "repz [addr16|addr32]". */
4822 if ((prefixes
& PREFIX_ADDR
))
4825 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
4833 OP_IMREG (bytemode
, sizeflag
);
4836 OP_ESreg (bytemode
, sizeflag
);
4839 OP_DSreg (bytemode
, sizeflag
);