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, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of the GNU opcodes library.
7 This library 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 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 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,
20 MA 02110-1301, USA. */
23 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
25 modified by John Hassey (hassey@dg-rtp.dg.com)
26 x86-64 support added by Jan Hubicka (jh@suse.cz)
27 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
29 /* The main tables describing the instructions is essentially a copy
30 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
31 Programmers Manual. Usually, there is a capital letter, followed
32 by a small letter. The capital letter tell the addressing mode,
33 and the small letter tells about the operand size. Refer to
34 the Intel manual for details. */
39 #include "opcode/i386.h"
43 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
44 static void ckprefix (void);
45 static const char *prefix_name (int, int);
46 static int print_insn (bfd_vma
, disassemble_info
*);
47 static void dofloat (int);
48 static void OP_ST (int, int);
49 static void OP_STi (int, int);
50 static int putop (const char *, int);
51 static void oappend (const char *);
52 static void append_seg (void);
53 static void OP_indirE (int, int);
54 static void print_operand_value (char *, int, bfd_vma
);
55 static void print_displacement (char *, bfd_vma
);
56 static void OP_E (int, int);
57 static void OP_G (int, int);
58 static bfd_vma
get64 (void);
59 static bfd_signed_vma
get32 (void);
60 static bfd_signed_vma
get32s (void);
61 static int get16 (void);
62 static void set_op (bfd_vma
, int);
63 static void OP_Skip_MODRM (int, int);
64 static void OP_REG (int, int);
65 static void OP_IMREG (int, int);
66 static void OP_I (int, int);
67 static void OP_I64 (int, int);
68 static void OP_sI (int, int);
69 static void OP_J (int, int);
70 static void OP_SEG (int, int);
71 static void OP_DIR (int, int);
72 static void OP_OFF (int, int);
73 static void OP_OFF64 (int, int);
74 static void ptr_reg (int, int);
75 static void OP_ESreg (int, int);
76 static void OP_DSreg (int, int);
77 static void OP_C (int, int);
78 static void OP_D (int, int);
79 static void OP_T (int, int);
80 static void OP_R (int, int);
81 static void OP_MMX (int, int);
82 static void OP_XMM (int, int);
83 static void OP_EM (int, int);
84 static void OP_EX (int, int);
85 static void OP_EMC (int,int);
86 static void OP_MXC (int,int);
87 static void OP_MS (int, int);
88 static void OP_XS (int, int);
89 static void OP_M (int, int);
90 static void OP_0f07 (int, int);
91 static void OP_Monitor (int, int);
92 static void OP_Mwait (int, int);
93 static void NOP_Fixup1 (int, int);
94 static void NOP_Fixup2 (int, int);
95 static void OP_3DNowSuffix (int, int);
96 static void OP_SIMD_Suffix (int, int);
97 static void BadOp (void);
98 static void REP_Fixup (int, int);
99 static void CMPXCHG8B_Fixup (int, int);
100 static void XMM_Fixup (int, int);
101 static void CRC32_Fixup (int, int);
104 /* Points to first byte not fetched. */
105 bfd_byte
*max_fetched
;
106 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
119 enum address_mode address_mode
;
121 /* Flags for the prefixes for the current instruction. See below. */
124 /* REX prefix the current instruction. See below. */
126 /* Bits of REX we've already used. */
128 /* Mark parts used in the REX prefix. When we are testing for
129 empty prefix (for 8bit register REX extension), just mask it
130 out. Otherwise test for REX bit is excuse for existence of REX
131 only in case value is nonzero. */
132 #define USED_REX(value) \
137 rex_used |= (value) | REX_OPCODE; \
140 rex_used |= REX_OPCODE; \
143 /* Flags for prefixes which we somehow handled when printing the
144 current instruction. */
145 static int used_prefixes
;
147 /* Flags stored in PREFIXES. */
148 #define PREFIX_REPZ 1
149 #define PREFIX_REPNZ 2
150 #define PREFIX_LOCK 4
152 #define PREFIX_SS 0x10
153 #define PREFIX_DS 0x20
154 #define PREFIX_ES 0x40
155 #define PREFIX_FS 0x80
156 #define PREFIX_GS 0x100
157 #define PREFIX_DATA 0x200
158 #define PREFIX_ADDR 0x400
159 #define PREFIX_FWAIT 0x800
161 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
162 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
164 #define FETCH_DATA(info, addr) \
165 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
166 ? 1 : fetch_data ((info), (addr)))
169 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
172 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
173 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
175 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
176 status
= (*info
->read_memory_func
) (start
,
178 addr
- priv
->max_fetched
,
184 /* If we did manage to read at least one byte, then
185 print_insn_i386 will do something sensible. Otherwise, print
186 an error. We do that here because this is where we know
188 if (priv
->max_fetched
== priv
->the_buffer
)
189 (*info
->memory_error_func
) (status
, start
, info
);
190 longjmp (priv
->bailout
, 1);
193 priv
->max_fetched
= addr
;
197 #define XX { NULL, 0 }
199 #define Eb { OP_E, b_mode }
200 #define Ev { OP_E, v_mode }
201 #define Ed { OP_E, d_mode }
202 #define Edq { OP_E, dq_mode }
203 #define Edqw { OP_E, dqw_mode }
204 #define Edqb { OP_E, dqb_mode }
205 #define Edqd { OP_E, dqd_mode }
206 #define Eq { OP_E, q_mode }
207 #define indirEv { OP_indirE, stack_v_mode }
208 #define indirEp { OP_indirE, f_mode }
209 #define stackEv { OP_E, stack_v_mode }
210 #define Em { OP_E, m_mode }
211 #define Ew { OP_E, w_mode }
212 #define M { OP_M, 0 } /* lea, lgdt, etc. */
213 #define Ma { OP_M, v_mode }
214 #define Mb { OP_M, b_mode }
215 #define Md { OP_M, d_mode }
216 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
217 #define Mq { OP_M, q_mode }
218 #define Gb { OP_G, b_mode }
219 #define Gv { OP_G, v_mode }
220 #define Gd { OP_G, d_mode }
221 #define Gdq { OP_G, dq_mode }
222 #define Gm { OP_G, m_mode }
223 #define Gw { OP_G, w_mode }
224 #define Rd { OP_R, d_mode }
225 #define Rm { OP_R, m_mode }
226 #define Ib { OP_I, b_mode }
227 #define sIb { OP_sI, b_mode } /* sign extened byte */
228 #define Iv { OP_I, v_mode }
229 #define Iq { OP_I, q_mode }
230 #define Iv64 { OP_I64, v_mode }
231 #define Iw { OP_I, w_mode }
232 #define I1 { OP_I, const_1_mode }
233 #define Jb { OP_J, b_mode }
234 #define Jv { OP_J, v_mode }
235 #define Cm { OP_C, m_mode }
236 #define Dm { OP_D, m_mode }
237 #define Td { OP_T, d_mode }
238 #define Skip_MODRM { OP_Skip_MODRM, 0 }
240 #define RMeAX { OP_REG, eAX_reg }
241 #define RMeBX { OP_REG, eBX_reg }
242 #define RMeCX { OP_REG, eCX_reg }
243 #define RMeDX { OP_REG, eDX_reg }
244 #define RMeSP { OP_REG, eSP_reg }
245 #define RMeBP { OP_REG, eBP_reg }
246 #define RMeSI { OP_REG, eSI_reg }
247 #define RMeDI { OP_REG, eDI_reg }
248 #define RMrAX { OP_REG, rAX_reg }
249 #define RMrBX { OP_REG, rBX_reg }
250 #define RMrCX { OP_REG, rCX_reg }
251 #define RMrDX { OP_REG, rDX_reg }
252 #define RMrSP { OP_REG, rSP_reg }
253 #define RMrBP { OP_REG, rBP_reg }
254 #define RMrSI { OP_REG, rSI_reg }
255 #define RMrDI { OP_REG, rDI_reg }
256 #define RMAL { OP_REG, al_reg }
257 #define RMAL { OP_REG, al_reg }
258 #define RMCL { OP_REG, cl_reg }
259 #define RMDL { OP_REG, dl_reg }
260 #define RMBL { OP_REG, bl_reg }
261 #define RMAH { OP_REG, ah_reg }
262 #define RMCH { OP_REG, ch_reg }
263 #define RMDH { OP_REG, dh_reg }
264 #define RMBH { OP_REG, bh_reg }
265 #define RMAX { OP_REG, ax_reg }
266 #define RMDX { OP_REG, dx_reg }
268 #define eAX { OP_IMREG, eAX_reg }
269 #define eBX { OP_IMREG, eBX_reg }
270 #define eCX { OP_IMREG, eCX_reg }
271 #define eDX { OP_IMREG, eDX_reg }
272 #define eSP { OP_IMREG, eSP_reg }
273 #define eBP { OP_IMREG, eBP_reg }
274 #define eSI { OP_IMREG, eSI_reg }
275 #define eDI { OP_IMREG, eDI_reg }
276 #define AL { OP_IMREG, al_reg }
277 #define CL { OP_IMREG, cl_reg }
278 #define DL { OP_IMREG, dl_reg }
279 #define BL { OP_IMREG, bl_reg }
280 #define AH { OP_IMREG, ah_reg }
281 #define CH { OP_IMREG, ch_reg }
282 #define DH { OP_IMREG, dh_reg }
283 #define BH { OP_IMREG, bh_reg }
284 #define AX { OP_IMREG, ax_reg }
285 #define DX { OP_IMREG, dx_reg }
286 #define zAX { OP_IMREG, z_mode_ax_reg }
287 #define indirDX { OP_IMREG, indir_dx_reg }
289 #define Sw { OP_SEG, w_mode }
290 #define Sv { OP_SEG, v_mode }
291 #define Ap { OP_DIR, 0 }
292 #define Ob { OP_OFF64, b_mode }
293 #define Ov { OP_OFF64, v_mode }
294 #define Xb { OP_DSreg, eSI_reg }
295 #define Xv { OP_DSreg, eSI_reg }
296 #define Xz { 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 }
308 #define MX { OP_MMX, 0 }
309 #define XM { OP_XMM, 0 }
310 #define EM { OP_EM, v_mode }
311 #define EMd { OP_EM, d_mode }
312 #define EMx { OP_EM, x_mode }
313 #define EXw { OP_EX, w_mode }
314 #define EXd { OP_EX, d_mode }
315 #define EXq { OP_EX, q_mode }
316 #define EXx { OP_EX, x_mode }
317 #define MS { OP_MS, v_mode }
318 #define XS { OP_XS, v_mode }
319 #define EMCq { OP_EMC, q_mode }
320 #define MXC { OP_MXC, 0 }
321 #define OPSUF { OP_3DNowSuffix, 0 }
322 #define OPSIMD { OP_SIMD_Suffix, 0 }
323 #define XMM0 { XMM_Fixup, 0 }
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr { REP_Fixup, eSI_reg }
327 #define Xvr { REP_Fixup, eSI_reg }
328 #define Ybr { REP_Fixup, eDI_reg }
329 #define Yvr { REP_Fixup, eDI_reg }
330 #define Yzr { REP_Fixup, eDI_reg }
331 #define indirDXr { REP_Fixup, indir_dx_reg }
332 #define ALr { REP_Fixup, al_reg }
333 #define eAXr { REP_Fixup, eAX_reg }
335 #define cond_jump_flag { NULL, cond_jump_mode }
336 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
359 #define o_mode 17 /* 16-byte operand */
360 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
361 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
406 #define z_mode_ax_reg 149
407 #define indir_dx_reg 150
411 #define USE_PREFIX_USER_TABLE 3
412 #define X86_64_SPECIAL 4
413 #define IS_3BYTE_OPCODE 5
414 #define USE_OPC_EXT_TABLE 6
415 #define USE_OPC_EXT_RM_TABLE 7
417 #define FLOAT NULL, { { NULL, FLOATCODE } }
419 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
420 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
421 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
422 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
423 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
424 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
425 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
426 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
427 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
428 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
429 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
430 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
431 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
432 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
433 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
434 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
435 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
436 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
437 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
438 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
439 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
440 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
441 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
442 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
443 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
444 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
445 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
446 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
448 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
449 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
450 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
451 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
452 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
453 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
454 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
455 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
456 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
457 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
458 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
459 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
460 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
461 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
462 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
463 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
464 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
465 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
466 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
467 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
468 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
469 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
470 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
471 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
472 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
473 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
474 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
475 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
476 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
477 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
478 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
479 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
480 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
481 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
482 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
483 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
484 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
485 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
486 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
487 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
488 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
489 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
490 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
491 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
492 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
493 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
494 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
495 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
496 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
497 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
498 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
499 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
500 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
501 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
502 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
503 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
504 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
505 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
506 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
507 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
508 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
509 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
510 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
511 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
512 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
513 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
514 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
515 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
516 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
517 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
518 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
519 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
520 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
521 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
522 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
523 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
524 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
525 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
526 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
527 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
528 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
529 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
530 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
531 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
532 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
533 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
534 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
535 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
536 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
537 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
538 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
539 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
540 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
541 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
542 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
543 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
544 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
545 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
546 #define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
547 #define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
548 #define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
551 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
552 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
553 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
554 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
556 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
557 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
559 #define OPC_EXT_0 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } }
560 #define OPC_EXT_1 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } }
561 #define OPC_EXT_2 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 2 } }
562 #define OPC_EXT_3 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 3 } }
563 #define OPC_EXT_4 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 4 } }
564 #define OPC_EXT_5 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 5 } }
565 #define OPC_EXT_6 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 6 } }
566 #define OPC_EXT_7 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 7 } }
567 #define OPC_EXT_8 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 8 } }
568 #define OPC_EXT_9 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 9 } }
569 #define OPC_EXT_10 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 10 } }
570 #define OPC_EXT_11 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 11 } }
571 #define OPC_EXT_12 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 12 } }
572 #define OPC_EXT_13 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 13 } }
573 #define OPC_EXT_14 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 14 } }
574 #define OPC_EXT_15 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 15 } }
575 #define OPC_EXT_16 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 16 } }
576 #define OPC_EXT_17 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 17 } }
577 #define OPC_EXT_18 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 18 } }
578 #define OPC_EXT_19 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 19 } }
579 #define OPC_EXT_20 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 20 } }
580 #define OPC_EXT_21 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 21 } }
581 #define OPC_EXT_22 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 22 } }
582 #define OPC_EXT_23 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 23 } }
583 #define OPC_EXT_24 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 24 } }
584 #define OPC_EXT_25 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 25 } }
585 #define OPC_EXT_26 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 26 } }
586 #define OPC_EXT_27 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 27 } }
587 #define OPC_EXT_28 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 28 } }
588 #define OPC_EXT_29 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 29 } }
589 #define OPC_EXT_30 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 30 } }
590 #define OPC_EXT_31 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 31 } }
591 #define OPC_EXT_32 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 32 } }
592 #define OPC_EXT_33 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 33 } }
593 #define OPC_EXT_34 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 34 } }
594 #define OPC_EXT_35 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 35 } }
595 #define OPC_EXT_36 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 36 } }
596 #define OPC_EXT_37 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 37 } }
597 #define OPC_EXT_38 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 38 } }
598 #define OPC_EXT_39 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 39 } }
599 #define OPC_EXT_40 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 40 } }
600 #define OPC_EXT_41 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 41 } }
601 #define OPC_EXT_42 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 42 } }
602 #define OPC_EXT_43 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 43 } }
603 #define OPC_EXT_44 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 44 } }
604 #define OPC_EXT_45 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 45 } }
606 #define OPC_EXT_RM_0 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } }
607 #define OPC_EXT_RM_1 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } }
608 #define OPC_EXT_RM_2 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 2 } }
609 #define OPC_EXT_RM_3 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } }
610 #define OPC_EXT_RM_4 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } }
611 #define OPC_EXT_RM_5 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 5 } }
612 #define OPC_EXT_RM_6 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 6 } }
614 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
625 /* Upper case letters in the instruction names here are macros.
626 'A' => print 'b' if no register operands or suffix_always is true
627 'B' => print 'b' if suffix_always is true
628 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
630 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
631 . suffix_always is true
632 'E' => print 'e' if 32-bit form of jcxz
633 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
634 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
635 'H' => print ",pt" or ",pn" branch hint
636 'I' => honor following macro letter even in Intel mode (implemented only
637 . for some of the macro letters)
639 'K' => print 'd' or 'q' if rex prefix is present.
640 'L' => print 'l' if suffix_always is true
641 'N' => print 'n' if instruction has no wait "prefix"
642 'O' => print 'd' or 'o' (or 'q' in Intel mode)
643 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
644 . or suffix_always is true. print 'q' if rex prefix is present.
645 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
647 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
648 'S' => print 'w', 'l' or 'q' if suffix_always is true
649 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
650 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
651 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
652 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
653 'X' => print 's', 'd' depending on data16 prefix (for XMM)
654 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
655 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
657 Many of the above letters print nothing in Intel mode. See "putop"
660 Braces '{' and '}', and vertical bars '|', indicate alternative
661 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
662 modes. In cases where there are only two alternatives, the X86_64
663 instruction is reserved, and "(bad)" is printed.
666 static const struct dis386 dis386
[] = {
668 { "addB", { Eb
, Gb
} },
669 { "addS", { Ev
, Gv
} },
670 { "addB", { Gb
, Eb
} },
671 { "addS", { Gv
, Ev
} },
672 { "addB", { AL
, Ib
} },
673 { "addS", { eAX
, Iv
} },
674 { "push{T|}", { es
} },
675 { "pop{T|}", { es
} },
677 { "orB", { Eb
, Gb
} },
678 { "orS", { Ev
, Gv
} },
679 { "orB", { Gb
, Eb
} },
680 { "orS", { Gv
, Ev
} },
681 { "orB", { AL
, Ib
} },
682 { "orS", { eAX
, Iv
} },
683 { "push{T|}", { cs
} },
684 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
686 { "adcB", { Eb
, Gb
} },
687 { "adcS", { Ev
, Gv
} },
688 { "adcB", { Gb
, Eb
} },
689 { "adcS", { Gv
, Ev
} },
690 { "adcB", { AL
, Ib
} },
691 { "adcS", { eAX
, Iv
} },
692 { "push{T|}", { ss
} },
693 { "pop{T|}", { ss
} },
695 { "sbbB", { Eb
, Gb
} },
696 { "sbbS", { Ev
, Gv
} },
697 { "sbbB", { Gb
, Eb
} },
698 { "sbbS", { Gv
, Ev
} },
699 { "sbbB", { AL
, Ib
} },
700 { "sbbS", { eAX
, Iv
} },
701 { "push{T|}", { ds
} },
702 { "pop{T|}", { ds
} },
704 { "andB", { Eb
, Gb
} },
705 { "andS", { Ev
, Gv
} },
706 { "andB", { Gb
, Eb
} },
707 { "andS", { Gv
, Ev
} },
708 { "andB", { AL
, Ib
} },
709 { "andS", { eAX
, Iv
} },
710 { "(bad)", { XX
} }, /* SEG ES prefix */
711 { "daa{|}", { XX
} },
713 { "subB", { Eb
, Gb
} },
714 { "subS", { Ev
, Gv
} },
715 { "subB", { Gb
, Eb
} },
716 { "subS", { Gv
, Ev
} },
717 { "subB", { AL
, Ib
} },
718 { "subS", { eAX
, Iv
} },
719 { "(bad)", { XX
} }, /* SEG CS prefix */
720 { "das{|}", { XX
} },
722 { "xorB", { Eb
, Gb
} },
723 { "xorS", { Ev
, Gv
} },
724 { "xorB", { Gb
, Eb
} },
725 { "xorS", { Gv
, Ev
} },
726 { "xorB", { AL
, Ib
} },
727 { "xorS", { eAX
, Iv
} },
728 { "(bad)", { XX
} }, /* SEG SS prefix */
729 { "aaa{|}", { XX
} },
731 { "cmpB", { Eb
, Gb
} },
732 { "cmpS", { Ev
, Gv
} },
733 { "cmpB", { Gb
, Eb
} },
734 { "cmpS", { Gv
, Ev
} },
735 { "cmpB", { AL
, Ib
} },
736 { "cmpS", { eAX
, Iv
} },
737 { "(bad)", { XX
} }, /* SEG DS prefix */
738 { "aas{|}", { XX
} },
740 { "inc{S|}", { RMeAX
} },
741 { "inc{S|}", { RMeCX
} },
742 { "inc{S|}", { RMeDX
} },
743 { "inc{S|}", { RMeBX
} },
744 { "inc{S|}", { RMeSP
} },
745 { "inc{S|}", { RMeBP
} },
746 { "inc{S|}", { RMeSI
} },
747 { "inc{S|}", { RMeDI
} },
749 { "dec{S|}", { RMeAX
} },
750 { "dec{S|}", { RMeCX
} },
751 { "dec{S|}", { RMeDX
} },
752 { "dec{S|}", { RMeBX
} },
753 { "dec{S|}", { RMeSP
} },
754 { "dec{S|}", { RMeBP
} },
755 { "dec{S|}", { RMeSI
} },
756 { "dec{S|}", { RMeDI
} },
758 { "pushV", { RMrAX
} },
759 { "pushV", { RMrCX
} },
760 { "pushV", { RMrDX
} },
761 { "pushV", { RMrBX
} },
762 { "pushV", { RMrSP
} },
763 { "pushV", { RMrBP
} },
764 { "pushV", { RMrSI
} },
765 { "pushV", { RMrDI
} },
767 { "popV", { RMrAX
} },
768 { "popV", { RMrCX
} },
769 { "popV", { RMrDX
} },
770 { "popV", { RMrBX
} },
771 { "popV", { RMrSP
} },
772 { "popV", { RMrBP
} },
773 { "popV", { RMrSI
} },
774 { "popV", { RMrDI
} },
780 { "(bad)", { XX
} }, /* seg fs */
781 { "(bad)", { XX
} }, /* seg gs */
782 { "(bad)", { XX
} }, /* op size prefix */
783 { "(bad)", { XX
} }, /* adr size prefix */
786 { "imulS", { Gv
, Ev
, Iv
} },
787 { "pushT", { sIb
} },
788 { "imulS", { Gv
, Ev
, sIb
} },
789 { "ins{b||b|}", { Ybr
, indirDX
} },
790 { "ins{R||G|}", { Yzr
, indirDX
} },
791 { "outs{b||b|}", { indirDXr
, Xb
} },
792 { "outs{R||G|}", { indirDXr
, Xz
} },
794 { "joH", { Jb
, XX
, cond_jump_flag
} },
795 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
796 { "jbH", { Jb
, XX
, cond_jump_flag
} },
797 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
798 { "jeH", { Jb
, XX
, cond_jump_flag
} },
799 { "jneH", { Jb
, XX
, cond_jump_flag
} },
800 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
801 { "jaH", { Jb
, XX
, cond_jump_flag
} },
803 { "jsH", { Jb
, XX
, cond_jump_flag
} },
804 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
805 { "jpH", { Jb
, XX
, cond_jump_flag
} },
806 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
807 { "jlH", { Jb
, XX
, cond_jump_flag
} },
808 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
809 { "jleH", { Jb
, XX
, cond_jump_flag
} },
810 { "jgH", { Jb
, XX
, cond_jump_flag
} },
816 { "testB", { Eb
, Gb
} },
817 { "testS", { Ev
, Gv
} },
818 { "xchgB", { Eb
, Gb
} },
819 { "xchgS", { Ev
, Gv
} },
821 { "movB", { Eb
, Gb
} },
822 { "movS", { Ev
, Gv
} },
823 { "movB", { Gb
, Eb
} },
824 { "movS", { Gv
, Ev
} },
825 { "movD", { Sv
, Sw
} },
827 { "movD", { Sw
, Sv
} },
831 { "xchgS", { RMeCX
, eAX
} },
832 { "xchgS", { RMeDX
, eAX
} },
833 { "xchgS", { RMeBX
, eAX
} },
834 { "xchgS", { RMeSP
, eAX
} },
835 { "xchgS", { RMeBP
, eAX
} },
836 { "xchgS", { RMeSI
, eAX
} },
837 { "xchgS", { RMeDI
, eAX
} },
839 { "cW{t||t|}R", { XX
} },
840 { "cR{t||t|}O", { XX
} },
841 { "Jcall{T|}", { Ap
} },
842 { "(bad)", { XX
} }, /* fwait */
843 { "pushfT", { XX
} },
845 { "sahf{|}", { XX
} },
846 { "lahf{|}", { XX
} },
848 { "movB", { AL
, Ob
} },
849 { "movS", { eAX
, Ov
} },
850 { "movB", { Ob
, AL
} },
851 { "movS", { Ov
, eAX
} },
852 { "movs{b||b|}", { Ybr
, Xb
} },
853 { "movs{R||R|}", { Yvr
, Xv
} },
854 { "cmps{b||b|}", { Xb
, Yb
} },
855 { "cmps{R||R|}", { Xv
, Yv
} },
857 { "testB", { AL
, Ib
} },
858 { "testS", { eAX
, Iv
} },
859 { "stosB", { Ybr
, AL
} },
860 { "stosS", { Yvr
, eAX
} },
861 { "lodsB", { ALr
, Xb
} },
862 { "lodsS", { eAXr
, Xv
} },
863 { "scasB", { AL
, Yb
} },
864 { "scasS", { eAX
, Yv
} },
866 { "movB", { RMAL
, Ib
} },
867 { "movB", { RMCL
, Ib
} },
868 { "movB", { RMDL
, Ib
} },
869 { "movB", { RMBL
, Ib
} },
870 { "movB", { RMAH
, Ib
} },
871 { "movB", { RMCH
, Ib
} },
872 { "movB", { RMDH
, Ib
} },
873 { "movB", { RMBH
, Ib
} },
875 { "movS", { RMeAX
, Iv64
} },
876 { "movS", { RMeCX
, Iv64
} },
877 { "movS", { RMeDX
, Iv64
} },
878 { "movS", { RMeBX
, Iv64
} },
879 { "movS", { RMeSP
, Iv64
} },
880 { "movS", { RMeBP
, Iv64
} },
881 { "movS", { RMeSI
, Iv64
} },
882 { "movS", { RMeDI
, Iv64
} },
893 { "enterT", { Iw
, Ib
} },
894 { "leaveT", { XX
} },
899 { "into{|}", { XX
} },
906 { "aam{|}", { sIb
} },
907 { "aad{|}", { sIb
} },
909 { "xlat", { DSBX
} },
920 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
921 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
922 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
923 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
924 { "inB", { AL
, Ib
} },
925 { "inG", { zAX
, Ib
} },
926 { "outB", { Ib
, AL
} },
927 { "outG", { Ib
, zAX
} },
931 { "Jjmp{T|}", { Ap
} },
933 { "inB", { AL
, indirDX
} },
934 { "inG", { zAX
, indirDX
} },
935 { "outB", { indirDX
, AL
} },
936 { "outG", { indirDX
, zAX
} },
938 { "(bad)", { XX
} }, /* lock prefix */
940 { "(bad)", { XX
} }, /* repne */
941 { "(bad)", { XX
} }, /* repz */
957 static const struct dis386 dis386_twobyte
[] = {
961 { "larS", { Gv
, Ew
} },
962 { "lslS", { Gv
, Ew
} },
964 { "syscall", { XX
} },
966 { "sysretP", { XX
} },
969 { "wbinvd", { XX
} },
975 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
981 { "unpcklpX", { XM
, EXq
} },
982 { "unpckhpX", { XM
, EXq
} },
1000 { "(bad)", { XX
} },
1002 { "(bad)", { XX
} },
1004 { "movapX", { XM
, EXx
} },
1005 { "movapX", { EXx
, XM
} },
1013 { "wrmsr", { XX
} },
1014 { "rdtsc", { XX
} },
1015 { "rdmsr", { XX
} },
1016 { "rdpmc", { XX
} },
1017 { "sysenter", { XX
} },
1018 { "sysexit", { XX
} },
1019 { "(bad)", { XX
} },
1020 { "(bad)", { XX
} },
1023 { "(bad)", { XX
} },
1025 { "(bad)", { XX
} },
1026 { "(bad)", { XX
} },
1027 { "(bad)", { XX
} },
1028 { "(bad)", { XX
} },
1029 { "(bad)", { XX
} },
1031 { "cmovo", { Gv
, Ev
} },
1032 { "cmovno", { Gv
, Ev
} },
1033 { "cmovb", { Gv
, Ev
} },
1034 { "cmovae", { Gv
, Ev
} },
1035 { "cmove", { Gv
, Ev
} },
1036 { "cmovne", { Gv
, Ev
} },
1037 { "cmovbe", { Gv
, Ev
} },
1038 { "cmova", { Gv
, Ev
} },
1040 { "cmovs", { Gv
, Ev
} },
1041 { "cmovns", { Gv
, Ev
} },
1042 { "cmovp", { Gv
, Ev
} },
1043 { "cmovnp", { Gv
, Ev
} },
1044 { "cmovl", { Gv
, Ev
} },
1045 { "cmovge", { Gv
, Ev
} },
1046 { "cmovle", { Gv
, Ev
} },
1047 { "cmovg", { Gv
, Ev
} },
1049 { "movmskpX", { Gdq
, XS
} },
1053 { "andpX", { XM
, EXx
} },
1054 { "andnpX", { XM
, EXx
} },
1055 { "orpX", { XM
, EXx
} },
1056 { "xorpX", { XM
, EXx
} },
1070 { "packsswb", { MX
, EM
} },
1071 { "pcmpgtb", { MX
, EM
} },
1072 { "pcmpgtw", { MX
, EM
} },
1073 { "pcmpgtd", { MX
, EM
} },
1074 { "packuswb", { MX
, EM
} },
1076 { "punpckhbw", { MX
, EM
} },
1077 { "punpckhwd", { MX
, EM
} },
1078 { "punpckhdq", { MX
, EM
} },
1079 { "packssdw", { MX
, EM
} },
1082 { "movK", { MX
, Edq
} },
1089 { "pcmpeqb", { MX
, EM
} },
1090 { "pcmpeqw", { MX
, EM
} },
1091 { "pcmpeqd", { MX
, EM
} },
1096 { "(bad)", { XX
} },
1097 { "(bad)", { XX
} },
1103 { "joH", { Jv
, XX
, cond_jump_flag
} },
1104 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1105 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1106 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1107 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1108 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1109 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1110 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1112 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1113 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1114 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1115 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1116 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1117 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1118 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1119 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1122 { "setno", { Eb
} },
1124 { "setae", { Eb
} },
1126 { "setne", { Eb
} },
1127 { "setbe", { Eb
} },
1131 { "setns", { Eb
} },
1133 { "setnp", { Eb
} },
1135 { "setge", { Eb
} },
1136 { "setle", { Eb
} },
1139 { "pushT", { fs
} },
1141 { "cpuid", { XX
} },
1142 { "btS", { Ev
, Gv
} },
1143 { "shldS", { Ev
, Gv
, Ib
} },
1144 { "shldS", { Ev
, Gv
, CL
} },
1148 { "pushT", { gs
} },
1151 { "btsS", { Ev
, Gv
} },
1152 { "shrdS", { Ev
, Gv
, Ib
} },
1153 { "shrdS", { Ev
, Gv
, CL
} },
1155 { "imulS", { Gv
, Ev
} },
1157 { "cmpxchgB", { Eb
, Gb
} },
1158 { "cmpxchgS", { Ev
, Gv
} },
1160 { "btrS", { Ev
, Gv
} },
1163 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1164 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1169 { "btcS", { Ev
, Gv
} },
1170 { "bsfS", { Gv
, Ev
} },
1172 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1173 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1175 { "xaddB", { Eb
, Gb
} },
1176 { "xaddS", { Ev
, Gv
} },
1178 { "movntiS", { Ev
, Gv
} },
1179 { "pinsrw", { MX
, Edqw
, Ib
} },
1180 { "pextrw", { Gdq
, MS
, Ib
} },
1181 { "shufpX", { XM
, EXx
, Ib
} },
1184 { "bswap", { RMeAX
} },
1185 { "bswap", { RMeCX
} },
1186 { "bswap", { RMeDX
} },
1187 { "bswap", { RMeBX
} },
1188 { "bswap", { RMeSP
} },
1189 { "bswap", { RMeBP
} },
1190 { "bswap", { RMeSI
} },
1191 { "bswap", { RMeDI
} },
1194 { "psrlw", { MX
, EM
} },
1195 { "psrld", { MX
, EM
} },
1196 { "psrlq", { MX
, EM
} },
1197 { "paddq", { MX
, EM
} },
1198 { "pmullw", { MX
, EM
} },
1200 { "pmovmskb", { Gdq
, MS
} },
1202 { "psubusb", { MX
, EM
} },
1203 { "psubusw", { MX
, EM
} },
1204 { "pminub", { MX
, EM
} },
1205 { "pand", { MX
, EM
} },
1206 { "paddusb", { MX
, EM
} },
1207 { "paddusw", { MX
, EM
} },
1208 { "pmaxub", { MX
, EM
} },
1209 { "pandn", { MX
, EM
} },
1211 { "pavgb", { MX
, EM
} },
1212 { "psraw", { MX
, EM
} },
1213 { "psrad", { MX
, EM
} },
1214 { "pavgw", { MX
, EM
} },
1215 { "pmulhuw", { MX
, EM
} },
1216 { "pmulhw", { MX
, EM
} },
1220 { "psubsb", { MX
, EM
} },
1221 { "psubsw", { MX
, EM
} },
1222 { "pminsw", { MX
, EM
} },
1223 { "por", { MX
, EM
} },
1224 { "paddsb", { MX
, EM
} },
1225 { "paddsw", { MX
, EM
} },
1226 { "pmaxsw", { MX
, EM
} },
1227 { "pxor", { MX
, EM
} },
1230 { "psllw", { MX
, EM
} },
1231 { "pslld", { MX
, EM
} },
1232 { "psllq", { MX
, EM
} },
1233 { "pmuludq", { MX
, EM
} },
1234 { "pmaddwd", { MX
, EM
} },
1235 { "psadbw", { MX
, EM
} },
1238 { "psubb", { MX
, EM
} },
1239 { "psubw", { MX
, EM
} },
1240 { "psubd", { MX
, EM
} },
1241 { "psubq", { MX
, EM
} },
1242 { "paddb", { MX
, EM
} },
1243 { "paddw", { MX
, EM
} },
1244 { "paddd", { MX
, EM
} },
1245 { "(bad)", { XX
} },
1248 static const unsigned char onebyte_has_modrm
[256] = {
1249 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1250 /* ------------------------------- */
1251 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1252 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1253 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1254 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1255 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1256 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1257 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1258 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1259 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1260 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1261 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1262 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1263 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1264 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1265 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1266 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1267 /* ------------------------------- */
1268 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1271 static const unsigned char twobyte_has_modrm
[256] = {
1272 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1273 /* ------------------------------- */
1274 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1275 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1276 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1277 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1278 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1279 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1280 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1281 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1282 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1283 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1284 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1285 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1286 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1287 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1288 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1289 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1290 /* ------------------------------- */
1291 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1294 static char obuf
[100];
1296 static char scratchbuf
[100];
1297 static unsigned char *start_codep
;
1298 static unsigned char *insn_codep
;
1299 static unsigned char *codep
;
1300 static const char *lock_prefix
;
1301 static const char *data_prefix
;
1302 static const char *addr_prefix
;
1303 static const char *repz_prefix
;
1304 static const char *repnz_prefix
;
1305 static disassemble_info
*the_info
;
1313 static unsigned char need_modrm
;
1315 /* If we are accessing mod/rm/reg without need_modrm set, then the
1316 values are stale. Hitting this abort likely indicates that you
1317 need to update onebyte_has_modrm or twobyte_has_modrm. */
1318 #define MODRM_CHECK if (!need_modrm) abort ()
1320 static const char **names64
;
1321 static const char **names32
;
1322 static const char **names16
;
1323 static const char **names8
;
1324 static const char **names8rex
;
1325 static const char **names_seg
;
1326 static const char **index16
;
1328 static const char *intel_names64
[] = {
1329 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1330 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1332 static const char *intel_names32
[] = {
1333 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1334 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1336 static const char *intel_names16
[] = {
1337 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1338 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1340 static const char *intel_names8
[] = {
1341 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1343 static const char *intel_names8rex
[] = {
1344 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1345 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1347 static const char *intel_names_seg
[] = {
1348 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1350 static const char *intel_index16
[] = {
1351 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1354 static const char *att_names64
[] = {
1355 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1356 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1358 static const char *att_names32
[] = {
1359 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1360 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1362 static const char *att_names16
[] = {
1363 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1364 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1366 static const char *att_names8
[] = {
1367 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1369 static const char *att_names8rex
[] = {
1370 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1371 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1373 static const char *att_names_seg
[] = {
1374 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1376 static const char *att_index16
[] = {
1377 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1380 static const struct dis386 grps
[][8] = {
1383 { "popU", { stackEv
} },
1384 { "(bad)", { XX
} },
1385 { "(bad)", { XX
} },
1386 { "(bad)", { XX
} },
1387 { "(bad)", { XX
} },
1388 { "(bad)", { XX
} },
1389 { "(bad)", { XX
} },
1390 { "(bad)", { XX
} },
1394 { "addA", { Eb
, Ib
} },
1395 { "orA", { Eb
, Ib
} },
1396 { "adcA", { Eb
, Ib
} },
1397 { "sbbA", { Eb
, Ib
} },
1398 { "andA", { Eb
, Ib
} },
1399 { "subA", { Eb
, Ib
} },
1400 { "xorA", { Eb
, Ib
} },
1401 { "cmpA", { Eb
, Ib
} },
1405 { "addQ", { Ev
, Iv
} },
1406 { "orQ", { Ev
, Iv
} },
1407 { "adcQ", { Ev
, Iv
} },
1408 { "sbbQ", { Ev
, Iv
} },
1409 { "andQ", { Ev
, Iv
} },
1410 { "subQ", { Ev
, Iv
} },
1411 { "xorQ", { Ev
, Iv
} },
1412 { "cmpQ", { Ev
, Iv
} },
1416 { "addQ", { Ev
, sIb
} },
1417 { "orQ", { Ev
, sIb
} },
1418 { "adcQ", { Ev
, sIb
} },
1419 { "sbbQ", { Ev
, sIb
} },
1420 { "andQ", { Ev
, sIb
} },
1421 { "subQ", { Ev
, sIb
} },
1422 { "xorQ", { Ev
, sIb
} },
1423 { "cmpQ", { Ev
, sIb
} },
1427 { "rolA", { Eb
, Ib
} },
1428 { "rorA", { Eb
, Ib
} },
1429 { "rclA", { Eb
, Ib
} },
1430 { "rcrA", { Eb
, Ib
} },
1431 { "shlA", { Eb
, Ib
} },
1432 { "shrA", { Eb
, Ib
} },
1433 { "(bad)", { XX
} },
1434 { "sarA", { Eb
, Ib
} },
1438 { "rolQ", { Ev
, Ib
} },
1439 { "rorQ", { Ev
, Ib
} },
1440 { "rclQ", { Ev
, Ib
} },
1441 { "rcrQ", { Ev
, Ib
} },
1442 { "shlQ", { Ev
, Ib
} },
1443 { "shrQ", { Ev
, Ib
} },
1444 { "(bad)", { XX
} },
1445 { "sarQ", { Ev
, Ib
} },
1449 { "rolA", { Eb
, I1
} },
1450 { "rorA", { Eb
, I1
} },
1451 { "rclA", { Eb
, I1
} },
1452 { "rcrA", { Eb
, I1
} },
1453 { "shlA", { Eb
, I1
} },
1454 { "shrA", { Eb
, I1
} },
1455 { "(bad)", { XX
} },
1456 { "sarA", { Eb
, I1
} },
1460 { "rolQ", { Ev
, I1
} },
1461 { "rorQ", { Ev
, I1
} },
1462 { "rclQ", { Ev
, I1
} },
1463 { "rcrQ", { Ev
, I1
} },
1464 { "shlQ", { Ev
, I1
} },
1465 { "shrQ", { Ev
, I1
} },
1466 { "(bad)", { XX
} },
1467 { "sarQ", { Ev
, I1
} },
1471 { "rolA", { Eb
, CL
} },
1472 { "rorA", { Eb
, CL
} },
1473 { "rclA", { Eb
, CL
} },
1474 { "rcrA", { Eb
, CL
} },
1475 { "shlA", { Eb
, CL
} },
1476 { "shrA", { Eb
, CL
} },
1477 { "(bad)", { XX
} },
1478 { "sarA", { Eb
, CL
} },
1482 { "rolQ", { Ev
, CL
} },
1483 { "rorQ", { Ev
, CL
} },
1484 { "rclQ", { Ev
, CL
} },
1485 { "rcrQ", { Ev
, CL
} },
1486 { "shlQ", { Ev
, CL
} },
1487 { "shrQ", { Ev
, CL
} },
1488 { "(bad)", { XX
} },
1489 { "sarQ", { Ev
, CL
} },
1493 { "testA", { Eb
, Ib
} },
1494 { "(bad)", { Eb
} },
1497 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1498 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1499 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1500 { "idivA", { Eb
} }, /* and idiv for consistency. */
1504 { "testQ", { Ev
, Iv
} },
1505 { "(bad)", { XX
} },
1508 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1509 { "imulQ", { Ev
} },
1511 { "idivQ", { Ev
} },
1517 { "(bad)", { XX
} },
1518 { "(bad)", { XX
} },
1519 { "(bad)", { XX
} },
1520 { "(bad)", { XX
} },
1521 { "(bad)", { XX
} },
1522 { "(bad)", { XX
} },
1528 { "callT", { indirEv
} },
1529 { "JcallT", { indirEp
} },
1530 { "jmpT", { indirEv
} },
1531 { "JjmpT", { indirEp
} },
1532 { "pushU", { stackEv
} },
1533 { "(bad)", { XX
} },
1537 { "sldtD", { Sv
} },
1543 { "(bad)", { XX
} },
1544 { "(bad)", { XX
} },
1552 { "smswD", { Sv
} },
1553 { "(bad)", { XX
} },
1559 { "(bad)", { XX
} },
1560 { "(bad)", { XX
} },
1561 { "(bad)", { XX
} },
1562 { "(bad)", { XX
} },
1563 { "btQ", { Ev
, Ib
} },
1564 { "btsQ", { Ev
, Ib
} },
1565 { "btrQ", { Ev
, Ib
} },
1566 { "btcQ", { Ev
, Ib
} },
1570 { "(bad)", { XX
} },
1571 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1572 { "(bad)", { XX
} },
1573 { "(bad)", { XX
} },
1574 { "(bad)", { XX
} },
1575 { "(bad)", { XX
} },
1581 { "movA", { Eb
, Ib
} },
1582 { "(bad)", { XX
} },
1583 { "(bad)", { XX
} },
1584 { "(bad)", { XX
} },
1585 { "(bad)", { XX
} },
1586 { "(bad)", { XX
} },
1587 { "(bad)", { XX
} },
1588 { "(bad)", { XX
} },
1592 { "movQ", { Ev
, Iv
} },
1593 { "(bad)", { XX
} },
1594 { "(bad)", { XX
} },
1595 { "(bad)", { XX
} },
1596 { "(bad)", { XX
} },
1597 { "(bad)", { XX
} },
1598 { "(bad)", { XX
} },
1599 { "(bad)", { XX
} },
1603 { "(bad)", { XX
} },
1604 { "(bad)", { XX
} },
1606 { "(bad)", { XX
} },
1608 { "(bad)", { XX
} },
1610 { "(bad)", { XX
} },
1614 { "(bad)", { XX
} },
1615 { "(bad)", { XX
} },
1617 { "(bad)", { XX
} },
1619 { "(bad)", { XX
} },
1621 { "(bad)", { XX
} },
1625 { "(bad)", { XX
} },
1626 { "(bad)", { XX
} },
1629 { "(bad)", { XX
} },
1630 { "(bad)", { XX
} },
1640 { "(bad)", { XX
} },
1651 { "(bad)", { XX
} },
1652 { "(bad)", { XX
} },
1653 { "(bad)", { XX
} },
1654 { "(bad)", { XX
} },
1658 { "prefetch", { Eb
} },
1659 { "prefetchw", { Eb
} },
1660 { "(bad)", { XX
} },
1661 { "(bad)", { XX
} },
1662 { "(bad)", { XX
} },
1663 { "(bad)", { XX
} },
1664 { "(bad)", { XX
} },
1665 { "(bad)", { XX
} },
1669 { "xstore-rng", { { OP_0f07
, 0 } } },
1670 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1671 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1672 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1673 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1674 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1675 { "(bad)", { { OP_0f07
, 0 } } },
1676 { "(bad)", { { OP_0f07
, 0 } } },
1680 { "montmul", { { OP_0f07
, 0 } } },
1681 { "xsha1", { { OP_0f07
, 0 } } },
1682 { "xsha256", { { OP_0f07
, 0 } } },
1683 { "(bad)", { { OP_0f07
, 0 } } },
1684 { "(bad)", { { OP_0f07
, 0 } } },
1685 { "(bad)", { { OP_0f07
, 0 } } },
1686 { "(bad)", { { OP_0f07
, 0 } } },
1687 { "(bad)", { { OP_0f07
, 0 } } },
1691 static const struct dis386 prefix_user_table
[][4] = {
1694 { "addps", { XM
, EXx
} },
1695 { "addss", { XM
, EXd
} },
1696 { "addpd", { XM
, EXx
} },
1697 { "addsd", { XM
, EXq
} },
1701 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1702 { "", { XM
, EXd
, OPSIMD
} },
1703 { "", { XM
, EXx
, OPSIMD
} },
1704 { "", { XM
, EXq
, OPSIMD
} },
1708 { "cvtpi2ps", { XM
, EMCq
} },
1709 { "cvtsi2ssY", { XM
, Ev
} },
1710 { "cvtpi2pd", { XM
, EMCq
} },
1711 { "cvtsi2sdY", { XM
, Ev
} },
1715 { "cvtps2pi", { MXC
, EXq
} },
1716 { "cvtss2siY", { Gv
, EXd
} },
1717 { "cvtpd2pi", { MXC
, EXx
} },
1718 { "cvtsd2siY", { Gv
, EXq
} },
1722 { "cvttps2pi", { MXC
, EXq
} },
1723 { "cvttss2siY", { Gv
, EXd
} },
1724 { "cvttpd2pi", { MXC
, EXx
} },
1725 { "cvttsd2siY", { Gv
, EXq
} },
1729 { "divps", { XM
, EXx
} },
1730 { "divss", { XM
, EXd
} },
1731 { "divpd", { XM
, EXx
} },
1732 { "divsd", { XM
, EXq
} },
1736 { "maxps", { XM
, EXx
} },
1737 { "maxss", { XM
, EXd
} },
1738 { "maxpd", { XM
, EXx
} },
1739 { "maxsd", { XM
, EXq
} },
1743 { "minps", { XM
, EXx
} },
1744 { "minss", { XM
, EXd
} },
1745 { "minpd", { XM
, EXx
} },
1746 { "minsd", { XM
, EXq
} },
1750 { "movups", { XM
, EXx
} },
1751 { "movss", { XM
, EXd
} },
1752 { "movupd", { XM
, EXx
} },
1753 { "movsd", { XM
, EXq
} },
1757 { "movups", { EXx
, XM
} },
1758 { "movss", { EXd
, XM
} },
1759 { "movupd", { EXx
, XM
} },
1760 { "movsd", { EXq
, XM
} },
1764 { "mulps", { XM
, EXx
} },
1765 { "mulss", { XM
, EXd
} },
1766 { "mulpd", { XM
, EXx
} },
1767 { "mulsd", { XM
, EXq
} },
1771 { "rcpps", { XM
, EXx
} },
1772 { "rcpss", { XM
, EXd
} },
1773 { "(bad)", { XM
, EXx
} },
1774 { "(bad)", { XM
, EXx
} },
1778 { "rsqrtps",{ XM
, EXx
} },
1779 { "rsqrtss",{ XM
, EXd
} },
1780 { "(bad)", { XM
, EXx
} },
1781 { "(bad)", { XM
, EXx
} },
1785 { "sqrtps", { XM
, EXx
} },
1786 { "sqrtss", { XM
, EXd
} },
1787 { "sqrtpd", { XM
, EXx
} },
1788 { "sqrtsd", { XM
, EXq
} },
1792 { "subps", { XM
, EXx
} },
1793 { "subss", { XM
, EXd
} },
1794 { "subpd", { XM
, EXx
} },
1795 { "subsd", { XM
, EXq
} },
1799 { "(bad)", { XM
, EXx
} },
1800 { "cvtdq2pd", { XM
, EXq
} },
1801 { "cvttpd2dq", { XM
, EXx
} },
1802 { "cvtpd2dq", { XM
, EXx
} },
1806 { "cvtdq2ps", { XM
, EXx
} },
1807 { "cvttps2dq", { XM
, EXx
} },
1808 { "cvtps2dq", { XM
, EXx
} },
1809 { "(bad)", { XM
, EXx
} },
1813 { "cvtps2pd", { XM
, EXq
} },
1814 { "cvtss2sd", { XM
, EXd
} },
1815 { "cvtpd2ps", { XM
, EXx
} },
1816 { "cvtsd2ss", { XM
, EXq
} },
1820 { "maskmovq", { MX
, MS
} },
1821 { "(bad)", { XM
, EXx
} },
1822 { "maskmovdqu", { XM
, XS
} },
1823 { "(bad)", { XM
, EXx
} },
1827 { "movq", { MX
, EM
} },
1828 { "movdqu", { XM
, EXx
} },
1829 { "movdqa", { XM
, EXx
} },
1830 { "(bad)", { XM
, EXx
} },
1834 { "movq", { EM
, MX
} },
1835 { "movdqu", { EXx
, XM
} },
1836 { "movdqa", { EXx
, XM
} },
1837 { "(bad)", { EXx
, XM
} },
1841 { "(bad)", { EXx
, XM
} },
1842 { "movq2dq",{ XM
, MS
} },
1843 { "movq", { EXq
, XM
} },
1844 { "movdq2q",{ MX
, XS
} },
1848 { "pshufw", { MX
, EM
, Ib
} },
1849 { "pshufhw",{ XM
, EXx
, Ib
} },
1850 { "pshufd", { XM
, EXx
, Ib
} },
1851 { "pshuflw",{ XM
, EXx
, Ib
} },
1855 { "movK", { Edq
, MX
} },
1856 { "movq", { XM
, EXq
} },
1857 { "movK", { Edq
, XM
} },
1858 { "(bad)", { Ed
, XM
} },
1862 { "(bad)", { MX
, EXx
} },
1863 { "(bad)", { XM
, EXx
} },
1864 { "punpckhqdq", { XM
, EXx
} },
1865 { "(bad)", { XM
, EXx
} },
1869 { "movntq", { EM
, MX
} },
1870 { "(bad)", { EM
, XM
} },
1871 { "movntdq",{ EM
, XM
} },
1872 { "(bad)", { EM
, XM
} },
1876 { "(bad)", { MX
, EXx
} },
1877 { "(bad)", { XM
, EXx
} },
1878 { "punpcklqdq", { XM
, EXx
} },
1879 { "(bad)", { XM
, EXx
} },
1883 { "(bad)", { MX
, EXx
} },
1884 { "(bad)", { XM
, EXx
} },
1885 { "addsubpd", { XM
, EXx
} },
1886 { "addsubps", { XM
, EXx
} },
1890 { "(bad)", { MX
, EXx
} },
1891 { "(bad)", { XM
, EXx
} },
1892 { "haddpd", { XM
, EXx
} },
1893 { "haddps", { XM
, EXx
} },
1897 { "(bad)", { MX
, EXx
} },
1898 { "(bad)", { XM
, EXx
} },
1899 { "hsubpd", { XM
, EXx
} },
1900 { "hsubps", { XM
, EXx
} },
1905 { "movsldup", { XM
, EXx
} },
1906 { "movlpd", { XM
, EXq
} },
1907 { "movddup", { XM
, EXq
} },
1912 { "movshdup", { XM
, EXx
} },
1913 { "movhpd", { XM
, EXq
} },
1914 { "(bad)", { XM
, EXq
} },
1918 { "(bad)", { XM
, EXx
} },
1919 { "(bad)", { XM
, EXx
} },
1920 { "(bad)", { XM
, EXx
} },
1925 {"movntps", { Ev
, XM
} },
1926 {"movntss", { Ed
, XM
} },
1927 {"movntpd", { Ev
, XM
} },
1928 {"movntsd", { Eq
, XM
} },
1933 {"vmread", { Em
, Gm
} },
1935 {"extrq", { XS
, Ib
, Ib
} },
1936 {"insertq", { XM
, XS
, Ib
, Ib
} },
1941 {"vmwrite", { Gm
, Em
} },
1943 {"extrq", { XM
, XS
} },
1944 {"insertq", { XM
, XS
} },
1949 { "bsrS", { Gv
, Ev
} },
1950 { "lzcntS", { Gv
, Ev
} },
1951 { "bsrS", { Gv
, Ev
} },
1952 { "(bad)", { XX
} },
1957 { "(bad)", { XX
} },
1958 { "popcntS", { Gv
, Ev
} },
1959 { "(bad)", { XX
} },
1960 { "(bad)", { XX
} },
1965 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
1966 { "pause", { XX
} },
1967 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
1968 { "(bad)", { XX
} },
1973 { "(bad)", { XX
} },
1974 { "(bad)", { XX
} },
1975 { "pblendvb", {XM
, EXx
, XMM0
} },
1976 { "(bad)", { XX
} },
1981 { "(bad)", { XX
} },
1982 { "(bad)", { XX
} },
1983 { "blendvps", {XM
, EXx
, XMM0
} },
1984 { "(bad)", { XX
} },
1989 { "(bad)", { XX
} },
1990 { "(bad)", { XX
} },
1991 { "blendvpd", { XM
, EXx
, XMM0
} },
1992 { "(bad)", { XX
} },
1997 { "(bad)", { XX
} },
1998 { "(bad)", { XX
} },
1999 { "ptest", { XM
, EXx
} },
2000 { "(bad)", { XX
} },
2005 { "(bad)", { XX
} },
2006 { "(bad)", { XX
} },
2007 { "pmovsxbw", { XM
, EXq
} },
2008 { "(bad)", { XX
} },
2013 { "(bad)", { XX
} },
2014 { "(bad)", { XX
} },
2015 { "pmovsxbd", { XM
, EXd
} },
2016 { "(bad)", { XX
} },
2021 { "(bad)", { XX
} },
2022 { "(bad)", { XX
} },
2023 { "pmovsxbq", { XM
, EXw
} },
2024 { "(bad)", { XX
} },
2029 { "(bad)", { XX
} },
2030 { "(bad)", { XX
} },
2031 { "pmovsxwd", { XM
, EXq
} },
2032 { "(bad)", { XX
} },
2037 { "(bad)", { XX
} },
2038 { "(bad)", { XX
} },
2039 { "pmovsxwq", { XM
, EXd
} },
2040 { "(bad)", { XX
} },
2045 { "(bad)", { XX
} },
2046 { "(bad)", { XX
} },
2047 { "pmovsxdq", { XM
, EXq
} },
2048 { "(bad)", { XX
} },
2053 { "(bad)", { XX
} },
2054 { "(bad)", { XX
} },
2055 { "pmuldq", { XM
, EXx
} },
2056 { "(bad)", { XX
} },
2061 { "(bad)", { XX
} },
2062 { "(bad)", { XX
} },
2063 { "pcmpeqq", { XM
, EXx
} },
2064 { "(bad)", { XX
} },
2069 { "(bad)", { XX
} },
2070 { "(bad)", { XX
} },
2071 { "movntdqa", { XM
, EM
} },
2072 { "(bad)", { XX
} },
2077 { "(bad)", { XX
} },
2078 { "(bad)", { XX
} },
2079 { "packusdw", { XM
, EXx
} },
2080 { "(bad)", { XX
} },
2085 { "(bad)", { XX
} },
2086 { "(bad)", { XX
} },
2087 { "pmovzxbw", { XM
, EXq
} },
2088 { "(bad)", { XX
} },
2093 { "(bad)", { XX
} },
2094 { "(bad)", { XX
} },
2095 { "pmovzxbd", { XM
, EXd
} },
2096 { "(bad)", { XX
} },
2101 { "(bad)", { XX
} },
2102 { "(bad)", { XX
} },
2103 { "pmovzxbq", { XM
, EXw
} },
2104 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2111 { "pmovzxwd", { XM
, EXq
} },
2112 { "(bad)", { XX
} },
2117 { "(bad)", { XX
} },
2118 { "(bad)", { XX
} },
2119 { "pmovzxwq", { XM
, EXd
} },
2120 { "(bad)", { XX
} },
2125 { "(bad)", { XX
} },
2126 { "(bad)", { XX
} },
2127 { "pmovzxdq", { XM
, EXq
} },
2128 { "(bad)", { XX
} },
2133 { "(bad)", { XX
} },
2134 { "(bad)", { XX
} },
2135 { "pminsb", { XM
, EXx
} },
2136 { "(bad)", { XX
} },
2141 { "(bad)", { XX
} },
2142 { "(bad)", { XX
} },
2143 { "pminsd", { XM
, EXx
} },
2144 { "(bad)", { XX
} },
2149 { "(bad)", { XX
} },
2150 { "(bad)", { XX
} },
2151 { "pminuw", { XM
, EXx
} },
2152 { "(bad)", { XX
} },
2157 { "(bad)", { XX
} },
2158 { "(bad)", { XX
} },
2159 { "pminud", { XM
, EXx
} },
2160 { "(bad)", { XX
} },
2165 { "(bad)", { XX
} },
2166 { "(bad)", { XX
} },
2167 { "pmaxsb", { XM
, EXx
} },
2168 { "(bad)", { XX
} },
2173 { "(bad)", { XX
} },
2174 { "(bad)", { XX
} },
2175 { "pmaxsd", { XM
, EXx
} },
2176 { "(bad)", { XX
} },
2181 { "(bad)", { XX
} },
2182 { "(bad)", { XX
} },
2183 { "pmaxuw", { XM
, EXx
} },
2184 { "(bad)", { XX
} },
2189 { "(bad)", { XX
} },
2190 { "(bad)", { XX
} },
2191 { "pmaxud", { XM
, EXx
} },
2192 { "(bad)", { XX
} },
2197 { "(bad)", { XX
} },
2198 { "(bad)", { XX
} },
2199 { "pmulld", { XM
, EXx
} },
2200 { "(bad)", { XX
} },
2205 { "(bad)", { XX
} },
2206 { "(bad)", { XX
} },
2207 { "phminposuw", { XM
, EXx
} },
2208 { "(bad)", { XX
} },
2213 { "(bad)", { XX
} },
2214 { "(bad)", { XX
} },
2215 { "roundps", { XM
, EXx
, Ib
} },
2216 { "(bad)", { XX
} },
2221 { "(bad)", { XX
} },
2222 { "(bad)", { XX
} },
2223 { "roundpd", { XM
, EXx
, Ib
} },
2224 { "(bad)", { XX
} },
2229 { "(bad)", { XX
} },
2230 { "(bad)", { XX
} },
2231 { "roundss", { XM
, EXd
, Ib
} },
2232 { "(bad)", { XX
} },
2237 { "(bad)", { XX
} },
2238 { "(bad)", { XX
} },
2239 { "roundsd", { XM
, EXq
, Ib
} },
2240 { "(bad)", { XX
} },
2245 { "(bad)", { XX
} },
2246 { "(bad)", { XX
} },
2247 { "blendps", { XM
, EXx
, Ib
} },
2248 { "(bad)", { XX
} },
2253 { "(bad)", { XX
} },
2254 { "(bad)", { XX
} },
2255 { "blendpd", { XM
, EXx
, Ib
} },
2256 { "(bad)", { XX
} },
2261 { "(bad)", { XX
} },
2262 { "(bad)", { XX
} },
2263 { "pblendw", { XM
, EXx
, Ib
} },
2264 { "(bad)", { XX
} },
2269 { "(bad)", { XX
} },
2270 { "(bad)", { XX
} },
2271 { "pextrb", { Edqb
, XM
, Ib
} },
2272 { "(bad)", { XX
} },
2277 { "(bad)", { XX
} },
2278 { "(bad)", { XX
} },
2279 { "pextrw", { Edqw
, XM
, Ib
} },
2280 { "(bad)", { XX
} },
2285 { "(bad)", { XX
} },
2286 { "(bad)", { XX
} },
2287 { "pextrK", { Edq
, XM
, Ib
} },
2288 { "(bad)", { XX
} },
2293 { "(bad)", { XX
} },
2294 { "(bad)", { XX
} },
2295 { "extractps", { Edqd
, XM
, Ib
} },
2296 { "(bad)", { XX
} },
2301 { "(bad)", { XX
} },
2302 { "(bad)", { XX
} },
2303 { "pinsrb", { XM
, Edqb
, Ib
} },
2304 { "(bad)", { XX
} },
2309 { "(bad)", { XX
} },
2310 { "(bad)", { XX
} },
2311 { "insertps", { XM
, EXd
, Ib
} },
2312 { "(bad)", { XX
} },
2317 { "(bad)", { XX
} },
2318 { "(bad)", { XX
} },
2319 { "pinsrK", { XM
, Edq
, Ib
} },
2320 { "(bad)", { XX
} },
2325 { "(bad)", { XX
} },
2326 { "(bad)", { XX
} },
2327 { "dpps", { XM
, EXx
, Ib
} },
2328 { "(bad)", { XX
} },
2333 { "(bad)", { XX
} },
2334 { "(bad)", { XX
} },
2335 { "dppd", { XM
, EXx
, Ib
} },
2336 { "(bad)", { XX
} },
2341 { "(bad)", { XX
} },
2342 { "(bad)", { XX
} },
2343 { "mpsadbw", { XM
, EXx
, Ib
} },
2344 { "(bad)", { XX
} },
2349 { "(bad)", { XX
} },
2350 { "(bad)", { XX
} },
2351 { "pcmpgtq", { XM
, EXx
} },
2352 { "(bad)", { XX
} },
2357 { "(bad)", { XX
} },
2358 { "(bad)", { XX
} },
2359 { "(bad)", { XX
} },
2360 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2365 { "(bad)", { XX
} },
2366 { "(bad)", { XX
} },
2367 { "(bad)", { XX
} },
2368 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2373 { "(bad)", { XX
} },
2374 { "(bad)", { XX
} },
2375 { "pcmpestrm", { XM
, EXx
, Ib
} },
2376 { "(bad)", { XX
} },
2381 { "(bad)", { XX
} },
2382 { "(bad)", { XX
} },
2383 { "pcmpestri", { XM
, EXx
, Ib
} },
2384 { "(bad)", { XX
} },
2389 { "(bad)", { XX
} },
2390 { "(bad)", { XX
} },
2391 { "pcmpistrm", { XM
, EXx
, Ib
} },
2392 { "(bad)", { XX
} },
2397 { "(bad)", { XX
} },
2398 { "(bad)", { XX
} },
2399 { "pcmpistri", { XM
, EXx
, Ib
} },
2400 { "(bad)", { XX
} },
2405 { "ucomiss",{ XM
, EXd
} },
2406 { "(bad)", { XX
} },
2407 { "ucomisd",{ XM
, EXq
} },
2408 { "(bad)", { XX
} },
2413 { "comiss", { XM
, EXd
} },
2414 { "(bad)", { XX
} },
2415 { "comisd", { XM
, EXq
} },
2416 { "(bad)", { XX
} },
2421 { "punpcklbw",{ MX
, EMd
} },
2422 { "(bad)", { XX
} },
2423 { "punpcklbw",{ MX
, EMx
} },
2424 { "(bad)", { XX
} },
2429 { "punpcklwd",{ MX
, EMd
} },
2430 { "(bad)", { XX
} },
2431 { "punpcklwd",{ MX
, EMx
} },
2432 { "(bad)", { XX
} },
2437 { "punpckldq",{ MX
, EMd
} },
2438 { "(bad)", { XX
} },
2439 { "punpckldq",{ MX
, EMx
} },
2440 { "(bad)", { XX
} },
2445 { "vmptrld",{ Mq
} },
2446 { "vmxon", { Mq
} },
2447 { "vmclear",{ Mq
} },
2448 { "(bad)", { XX
} },
2453 { "(bad)", { XX
} },
2454 { "(bad)", { XX
} },
2455 { "psrldq", { MS
, Ib
} },
2456 { "(bad)", { XX
} },
2461 { "(bad)", { XX
} },
2462 { "(bad)", { XX
} },
2463 { "pslldq", { MS
, Ib
} },
2464 { "(bad)", { XX
} },
2468 static const struct dis386 x86_64_table
[][2] = {
2470 { "pusha{P|}", { XX
} },
2471 { "(bad)", { XX
} },
2474 { "popa{P|}", { XX
} },
2475 { "(bad)", { XX
} },
2479 { "(bad)", { XX
} },
2482 { "arpl", { Ew
, Gw
} },
2483 { "movs{||lq|xd}", { Gv
, Ed
} },
2487 static const struct dis386 three_byte_table
[][256] = {
2491 { "pshufb", { MX
, EM
} },
2492 { "phaddw", { MX
, EM
} },
2493 { "phaddd", { MX
, EM
} },
2494 { "phaddsw", { MX
, EM
} },
2495 { "pmaddubsw", { MX
, EM
} },
2496 { "phsubw", { MX
, EM
} },
2497 { "phsubd", { MX
, EM
} },
2498 { "phsubsw", { MX
, EM
} },
2500 { "psignb", { MX
, EM
} },
2501 { "psignw", { MX
, EM
} },
2502 { "psignd", { MX
, EM
} },
2503 { "pmulhrsw", { MX
, EM
} },
2504 { "(bad)", { XX
} },
2505 { "(bad)", { XX
} },
2506 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2510 { "(bad)", { XX
} },
2511 { "(bad)", { XX
} },
2512 { "(bad)", { XX
} },
2515 { "(bad)", { XX
} },
2518 { "(bad)", { XX
} },
2519 { "(bad)", { XX
} },
2520 { "(bad)", { XX
} },
2521 { "(bad)", { XX
} },
2522 { "pabsb", { MX
, EM
} },
2523 { "pabsw", { MX
, EM
} },
2524 { "pabsd", { MX
, EM
} },
2525 { "(bad)", { XX
} },
2533 { "(bad)", { XX
} },
2534 { "(bad)", { XX
} },
2540 { "(bad)", { XX
} },
2541 { "(bad)", { XX
} },
2542 { "(bad)", { XX
} },
2543 { "(bad)", { XX
} },
2551 { "(bad)", { XX
} },
2565 { "(bad)", { XX
} },
2566 { "(bad)", { XX
} },
2567 { "(bad)", { XX
} },
2568 { "(bad)", { XX
} },
2569 { "(bad)", { XX
} },
2570 { "(bad)", { XX
} },
2572 { "(bad)", { XX
} },
2573 { "(bad)", { XX
} },
2574 { "(bad)", { XX
} },
2575 { "(bad)", { XX
} },
2576 { "(bad)", { XX
} },
2577 { "(bad)", { XX
} },
2578 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2581 { "(bad)", { XX
} },
2582 { "(bad)", { XX
} },
2583 { "(bad)", { XX
} },
2584 { "(bad)", { XX
} },
2585 { "(bad)", { XX
} },
2586 { "(bad)", { XX
} },
2587 { "(bad)", { XX
} },
2588 { "(bad)", { XX
} },
2590 { "(bad)", { XX
} },
2591 { "(bad)", { XX
} },
2592 { "(bad)", { XX
} },
2593 { "(bad)", { XX
} },
2594 { "(bad)", { XX
} },
2595 { "(bad)", { XX
} },
2596 { "(bad)", { XX
} },
2597 { "(bad)", { XX
} },
2599 { "(bad)", { XX
} },
2600 { "(bad)", { XX
} },
2601 { "(bad)", { XX
} },
2602 { "(bad)", { XX
} },
2603 { "(bad)", { XX
} },
2604 { "(bad)", { XX
} },
2605 { "(bad)", { XX
} },
2606 { "(bad)", { XX
} },
2608 { "(bad)", { XX
} },
2609 { "(bad)", { XX
} },
2610 { "(bad)", { XX
} },
2611 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "(bad)", { XX
} },
2614 { "(bad)", { XX
} },
2615 { "(bad)", { XX
} },
2617 { "(bad)", { XX
} },
2618 { "(bad)", { XX
} },
2619 { "(bad)", { XX
} },
2620 { "(bad)", { XX
} },
2621 { "(bad)", { XX
} },
2622 { "(bad)", { XX
} },
2623 { "(bad)", { XX
} },
2624 { "(bad)", { XX
} },
2626 { "(bad)", { XX
} },
2627 { "(bad)", { XX
} },
2628 { "(bad)", { XX
} },
2629 { "(bad)", { XX
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2632 { "(bad)", { XX
} },
2633 { "(bad)", { XX
} },
2635 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2637 { "(bad)", { XX
} },
2638 { "(bad)", { XX
} },
2639 { "(bad)", { XX
} },
2640 { "(bad)", { XX
} },
2641 { "(bad)", { XX
} },
2642 { "(bad)", { XX
} },
2644 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "(bad)", { XX
} },
2647 { "(bad)", { XX
} },
2648 { "(bad)", { XX
} },
2649 { "(bad)", { XX
} },
2650 { "(bad)", { XX
} },
2651 { "(bad)", { XX
} },
2653 { "(bad)", { XX
} },
2654 { "(bad)", { XX
} },
2655 { "(bad)", { XX
} },
2656 { "(bad)", { XX
} },
2657 { "(bad)", { XX
} },
2658 { "(bad)", { XX
} },
2659 { "(bad)", { XX
} },
2660 { "(bad)", { XX
} },
2662 { "(bad)", { XX
} },
2663 { "(bad)", { XX
} },
2664 { "(bad)", { XX
} },
2665 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2669 { "(bad)", { XX
} },
2671 { "(bad)", { XX
} },
2672 { "(bad)", { XX
} },
2673 { "(bad)", { XX
} },
2674 { "(bad)", { XX
} },
2675 { "(bad)", { XX
} },
2676 { "(bad)", { XX
} },
2677 { "(bad)", { XX
} },
2678 { "(bad)", { XX
} },
2680 { "(bad)", { XX
} },
2681 { "(bad)", { XX
} },
2682 { "(bad)", { XX
} },
2683 { "(bad)", { XX
} },
2684 { "(bad)", { XX
} },
2685 { "(bad)", { XX
} },
2686 { "(bad)", { XX
} },
2687 { "(bad)", { XX
} },
2689 { "(bad)", { XX
} },
2690 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2695 { "(bad)", { XX
} },
2696 { "(bad)", { XX
} },
2698 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2704 { "(bad)", { XX
} },
2705 { "(bad)", { XX
} },
2707 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2713 { "(bad)", { XX
} },
2714 { "(bad)", { XX
} },
2716 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2722 { "(bad)", { XX
} },
2723 { "(bad)", { XX
} },
2725 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2734 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2741 { "(bad)", { XX
} },
2743 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "(bad)", { XX
} },
2750 { "(bad)", { XX
} },
2752 { "(bad)", { XX
} },
2753 { "(bad)", { XX
} },
2754 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2758 { "(bad)", { XX
} },
2759 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2767 { "(bad)", { XX
} },
2768 { "(bad)", { XX
} },
2770 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2776 { "(bad)", { XX
} },
2777 { "(bad)", { XX
} },
2782 { "(bad)", { XX
} },
2783 { "(bad)", { XX
} },
2784 { "(bad)", { XX
} },
2785 { "(bad)", { XX
} },
2786 { "(bad)", { XX
} },
2787 { "(bad)", { XX
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2798 { "palignr", { MX
, EM
, Ib
} },
2800 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2803 { "(bad)", { XX
} },
2809 { "(bad)", { XX
} },
2810 { "(bad)", { XX
} },
2811 { "(bad)", { XX
} },
2812 { "(bad)", { XX
} },
2813 { "(bad)", { XX
} },
2814 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2821 { "(bad)", { XX
} },
2822 { "(bad)", { XX
} },
2823 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2827 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2830 { "(bad)", { XX
} },
2831 { "(bad)", { XX
} },
2832 { "(bad)", { XX
} },
2833 { "(bad)", { XX
} },
2834 { "(bad)", { XX
} },
2836 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2839 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2841 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2848 { "(bad)", { XX
} },
2849 { "(bad)", { XX
} },
2850 { "(bad)", { XX
} },
2851 { "(bad)", { XX
} },
2852 { "(bad)", { XX
} },
2857 { "(bad)", { XX
} },
2858 { "(bad)", { XX
} },
2859 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2863 { "(bad)", { XX
} },
2864 { "(bad)", { XX
} },
2865 { "(bad)", { XX
} },
2866 { "(bad)", { XX
} },
2867 { "(bad)", { XX
} },
2868 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2870 { "(bad)", { XX
} },
2872 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2876 { "(bad)", { XX
} },
2877 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2879 { "(bad)", { XX
} },
2881 { "(bad)", { XX
} },
2882 { "(bad)", { XX
} },
2883 { "(bad)", { XX
} },
2884 { "(bad)", { XX
} },
2885 { "(bad)", { XX
} },
2886 { "(bad)", { XX
} },
2887 { "(bad)", { XX
} },
2888 { "(bad)", { XX
} },
2894 { "(bad)", { XX
} },
2895 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2899 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2903 { "(bad)", { XX
} },
2904 { "(bad)", { XX
} },
2905 { "(bad)", { XX
} },
2906 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2915 { "(bad)", { XX
} },
2917 { "(bad)", { XX
} },
2918 { "(bad)", { XX
} },
2919 { "(bad)", { XX
} },
2920 { "(bad)", { XX
} },
2921 { "(bad)", { XX
} },
2922 { "(bad)", { XX
} },
2923 { "(bad)", { XX
} },
2924 { "(bad)", { XX
} },
2926 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2928 { "(bad)", { XX
} },
2929 { "(bad)", { XX
} },
2930 { "(bad)", { XX
} },
2931 { "(bad)", { XX
} },
2932 { "(bad)", { XX
} },
2933 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2942 { "(bad)", { XX
} },
2944 { "(bad)", { XX
} },
2945 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2951 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2960 { "(bad)", { XX
} },
2962 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2969 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2978 { "(bad)", { XX
} },
2980 { "(bad)", { XX
} },
2981 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2987 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2996 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3005 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3014 { "(bad)", { XX
} },
3016 { "(bad)", { XX
} },
3017 { "(bad)", { XX
} },
3018 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3023 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3032 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3041 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3050 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3059 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3067 { "(bad)", { XX
} },
3068 { "(bad)", { XX
} },
3072 static const struct dis386 opc_ext_table
[][2] = {
3075 { "leaS", { Gv
, M
} },
3076 { "(bad)", { XX
} },
3080 { "les{S|}", { Gv
, Mp
} },
3081 { "(bad)", { XX
} },
3085 { "ldsS", { Gv
, Mp
} },
3086 { "(bad)", { XX
} },
3090 { "lssS", { Gv
, Mp
} },
3091 { "(bad)", { XX
} },
3095 { "lfsS", { Gv
, Mp
} },
3096 { "(bad)", { XX
} },
3100 { "lgsS", { Gv
, Mp
} },
3101 { "(bad)", { XX
} },
3105 { "sgdt{Q|IQ||}", { M
} },
3110 { "sidt{Q|IQ||}", { M
} },
3115 { "lgdt{Q|Q||}", { M
} },
3116 { "(bad)", { XX
} },
3121 { "(bad)", { XX
} },
3125 { "vmptrst", { Mq
} },
3126 { "(bad)", { XX
} },
3130 { "(bad)", { XX
} },
3131 { "psrlw", { MS
, Ib
} },
3135 { "(bad)", { XX
} },
3136 { "psraw", { MS
, Ib
} },
3140 { "(bad)", { XX
} },
3141 { "psllw", { MS
, Ib
} },
3145 { "(bad)", { XX
} },
3146 { "psrld", { MS
, Ib
} },
3150 { "(bad)", { XX
} },
3151 { "psrad", { MS
, Ib
} },
3155 { "(bad)", { XX
} },
3156 { "pslld", { MS
, Ib
} },
3160 { "(bad)", { XX
} },
3161 { "psrlq", { MS
, Ib
} },
3165 { "(bad)", { XX
} },
3170 { "(bad)", { XX
} },
3171 { "psllq", { MS
, Ib
} },
3175 { "(bad)", { XX
} },
3180 { "fxsave", { M
} },
3181 { "(bad)", { XX
} },
3185 { "fxrstor", { M
} },
3186 { "(bad)", { XX
} },
3190 { "ldmxcsr", { Md
} },
3191 { "(bad)", { XX
} },
3195 { "stmxcsr", { Md
} },
3196 { "(bad)", { XX
} },
3200 { "(bad)", { XX
} },
3205 { "(bad)", { XX
} },
3210 { "clflush", { Mb
} },
3215 { "prefetchnta", { Mb
} },
3216 { "(bad)", { XX
} },
3220 { "prefetcht0", { Mb
} },
3221 { "(bad)", { XX
} },
3225 { "prefetcht1", { Mb
} },
3226 { "(bad)", { XX
} },
3230 { "prefetcht2", { Mb
} },
3231 { "(bad)", { XX
} },
3235 { "lddqu", { XM
, M
} },
3236 { "(bad)", { XX
} },
3240 { "bound{S|}", { Gv
, Ma
} },
3241 { "(bad)", { XX
} },
3245 { "movlpX", { EXq
, XM
} },
3246 { "(bad)", { XX
} },
3250 { "movhpX", { EXq
, XM
} },
3251 { "(bad)", { XX
} },
3255 { "movlpX", { XM
, EXq
} },
3256 { "movhlpX", { XM
, EXq
} },
3260 { "movhpX", { XM
, EXq
} },
3261 { "movlhpX", { XM
, EXq
} },
3265 { "invlpg", { Mb
} },
3270 { "lidt{Q|Q||}", { M
} },
3275 { "(bad)", { XX
} },
3276 { "movZ", { Rm
, Cm
} },
3280 { "(bad)", { XX
} },
3281 { "movZ", { Rm
, Dm
} },
3285 { "(bad)", { XX
} },
3286 { "movZ", { Cm
, Rm
} },
3290 { "(bad)", { XX
} },
3291 { "movZ", { Dm
, Rm
} },
3295 { "(bad)", { XX
} },
3296 { "movL", { Rd
, Td
} },
3300 { "(bad)", { XX
} },
3301 { "movL", { Td
, Rd
} },
3305 static const struct dis386 opc_ext_rm_table
[][8] = {
3308 { "(bad)", { XX
} },
3309 { "vmcall", { Skip_MODRM
} },
3310 { "vmlaunch", { Skip_MODRM
} },
3311 { "vmresume", { Skip_MODRM
} },
3312 { "vmxoff", { Skip_MODRM
} },
3313 { "(bad)", { XX
} },
3314 { "(bad)", { XX
} },
3315 { "(bad)", { XX
} },
3319 { "monitor", { { OP_Monitor
, 0 } } },
3320 { "mwait", { { OP_Mwait
, 0 } } },
3321 { "(bad)", { XX
} },
3322 { "(bad)", { XX
} },
3323 { "(bad)", { XX
} },
3324 { "(bad)", { XX
} },
3325 { "(bad)", { XX
} },
3326 { "(bad)", { XX
} },
3330 { "lfence", { Skip_MODRM
} },
3331 { "(bad)", { XX
} },
3332 { "(bad)", { XX
} },
3333 { "(bad)", { XX
} },
3334 { "(bad)", { XX
} },
3335 { "(bad)", { XX
} },
3336 { "(bad)", { XX
} },
3337 { "(bad)", { XX
} },
3341 { "mfence", { Skip_MODRM
} },
3342 { "(bad)", { XX
} },
3343 { "(bad)", { XX
} },
3344 { "(bad)", { XX
} },
3345 { "(bad)", { XX
} },
3346 { "(bad)", { XX
} },
3347 { "(bad)", { XX
} },
3348 { "(bad)", { XX
} },
3352 { "sfence", { Skip_MODRM
} },
3353 { "(bad)", { XX
} },
3354 { "(bad)", { XX
} },
3355 { "(bad)", { XX
} },
3356 { "(bad)", { XX
} },
3357 { "(bad)", { XX
} },
3358 { "(bad)", { XX
} },
3359 { "(bad)", { XX
} },
3363 { "swapgs", { Skip_MODRM
} },
3364 { "rdtscp", { Skip_MODRM
} },
3365 { "(bad)", { XX
} },
3366 { "(bad)", { XX
} },
3367 { "(bad)", { XX
} },
3368 { "(bad)", { XX
} },
3369 { "(bad)", { XX
} },
3370 { "(bad)", { XX
} },
3374 { "vmrun", { Skip_MODRM
} },
3375 { "vmmcall", { Skip_MODRM
} },
3376 { "vmload", { Skip_MODRM
} },
3377 { "vmsave", { Skip_MODRM
} },
3378 { "stgi", { Skip_MODRM
} },
3379 { "clgi", { Skip_MODRM
} },
3380 { "skinit", { Skip_MODRM
} },
3381 { "invlpga", { Skip_MODRM
} },
3385 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3397 FETCH_DATA (the_info
, codep
+ 1);
3401 /* REX prefixes family. */
3418 if (address_mode
== mode_64bit
)
3424 prefixes
|= PREFIX_REPZ
;
3427 prefixes
|= PREFIX_REPNZ
;
3430 prefixes
|= PREFIX_LOCK
;
3433 prefixes
|= PREFIX_CS
;
3436 prefixes
|= PREFIX_SS
;
3439 prefixes
|= PREFIX_DS
;
3442 prefixes
|= PREFIX_ES
;
3445 prefixes
|= PREFIX_FS
;
3448 prefixes
|= PREFIX_GS
;
3451 prefixes
|= PREFIX_DATA
;
3454 prefixes
|= PREFIX_ADDR
;
3457 /* fwait is really an instruction. If there are prefixes
3458 before the fwait, they belong to the fwait, *not* to the
3459 following instruction. */
3460 if (prefixes
|| rex
)
3462 prefixes
|= PREFIX_FWAIT
;
3466 prefixes
= PREFIX_FWAIT
;
3471 /* Rex is ignored when followed by another prefix. */
3482 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3486 prefix_name (int pref
, int sizeflag
)
3488 static const char *rexes
[16] =
3493 "rex.XB", /* 0x43 */
3495 "rex.RB", /* 0x45 */
3496 "rex.RX", /* 0x46 */
3497 "rex.RXB", /* 0x47 */
3499 "rex.WB", /* 0x49 */
3500 "rex.WX", /* 0x4a */
3501 "rex.WXB", /* 0x4b */
3502 "rex.WR", /* 0x4c */
3503 "rex.WRB", /* 0x4d */
3504 "rex.WRX", /* 0x4e */
3505 "rex.WRXB", /* 0x4f */
3510 /* REX prefixes family. */
3527 return rexes
[pref
- 0x40];
3547 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3549 if (address_mode
== mode_64bit
)
3550 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3552 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3560 static char op_out
[MAX_OPERANDS
][100];
3561 static int op_ad
, op_index
[MAX_OPERANDS
];
3562 static int two_source_ops
;
3563 static bfd_vma op_address
[MAX_OPERANDS
];
3564 static bfd_vma op_riprel
[MAX_OPERANDS
];
3565 static bfd_vma start_pc
;
3568 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3569 * (see topic "Redundant prefixes" in the "Differences from 8086"
3570 * section of the "Virtual 8086 Mode" chapter.)
3571 * 'pc' should be the address of this instruction, it will
3572 * be used to print the target address if this is a relative jump or call
3573 * The function returns the length of this instruction in bytes.
3576 static char intel_syntax
;
3577 static char open_char
;
3578 static char close_char
;
3579 static char separator_char
;
3580 static char scale_char
;
3582 /* Here for backwards compatibility. When gdb stops using
3583 print_insn_i386_att and print_insn_i386_intel these functions can
3584 disappear, and print_insn_i386 be merged into print_insn. */
3586 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3590 return print_insn (pc
, info
);
3594 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3598 return print_insn (pc
, info
);
3602 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3606 return print_insn (pc
, info
);
3610 print_i386_disassembler_options (FILE *stream
)
3612 fprintf (stream
, _("\n\
3613 The following i386/x86-64 specific disassembler options are supported for use\n\
3614 with the -M switch (multiple options should be separated by commas):\n"));
3616 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3617 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3618 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3619 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3620 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3621 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3622 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3623 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3624 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3625 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3626 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3629 /* Get a pointer to struct dis386 with a valid name. */
3631 static const struct dis386
*
3632 get_valid_dis386 (const struct dis386
*dp
)
3636 if (dp
->name
!= NULL
)
3639 switch (dp
->op
[0].bytemode
)
3642 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3645 case USE_PREFIX_USER_TABLE
:
3647 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3648 if (prefixes
& PREFIX_REPZ
)
3655 /* We should check PREFIX_REPNZ and PREFIX_REPZ before
3657 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3658 if (prefixes
& PREFIX_REPNZ
)
3661 repnz_prefix
= NULL
;
3665 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3666 if (prefixes
& PREFIX_DATA
)
3673 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3676 case X86_64_SPECIAL
:
3677 index
= address_mode
== mode_64bit
? 1 : 0;
3678 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3681 case USE_OPC_EXT_TABLE
:
3682 index
= modrm
.mod
== 0x3 ? 1 : 0;
3683 dp
= &opc_ext_table
[dp
->op
[1].bytemode
][index
];
3686 case USE_OPC_EXT_RM_TABLE
:
3688 dp
= &opc_ext_rm_table
[dp
->op
[1].bytemode
][index
];
3692 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3696 if (dp
->name
!= NULL
)
3699 return get_valid_dis386 (dp
);
3703 print_insn (bfd_vma pc
, disassemble_info
*info
)
3705 const struct dis386
*dp
;
3707 char *op_txt
[MAX_OPERANDS
];
3711 struct dis_private priv
;
3713 char prefix_obuf
[32];
3716 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3717 || info
->mach
== bfd_mach_x86_64
)
3718 address_mode
= mode_64bit
;
3720 address_mode
= mode_32bit
;
3722 if (intel_syntax
== (char) -1)
3723 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3724 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3726 if (info
->mach
== bfd_mach_i386_i386
3727 || info
->mach
== bfd_mach_x86_64
3728 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3729 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3730 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3731 else if (info
->mach
== bfd_mach_i386_i8086
)
3732 priv
.orig_sizeflag
= 0;
3736 for (p
= info
->disassembler_options
; p
!= NULL
; )
3738 if (CONST_STRNEQ (p
, "x86-64"))
3740 address_mode
= mode_64bit
;
3741 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3743 else if (CONST_STRNEQ (p
, "i386"))
3745 address_mode
= mode_32bit
;
3746 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3748 else if (CONST_STRNEQ (p
, "i8086"))
3750 address_mode
= mode_16bit
;
3751 priv
.orig_sizeflag
= 0;
3753 else if (CONST_STRNEQ (p
, "intel"))
3757 else if (CONST_STRNEQ (p
, "att"))
3761 else if (CONST_STRNEQ (p
, "addr"))
3763 if (address_mode
== mode_64bit
)
3765 if (p
[4] == '3' && p
[5] == '2')
3766 priv
.orig_sizeflag
&= ~AFLAG
;
3767 else if (p
[4] == '6' && p
[5] == '4')
3768 priv
.orig_sizeflag
|= AFLAG
;
3772 if (p
[4] == '1' && p
[5] == '6')
3773 priv
.orig_sizeflag
&= ~AFLAG
;
3774 else if (p
[4] == '3' && p
[5] == '2')
3775 priv
.orig_sizeflag
|= AFLAG
;
3778 else if (CONST_STRNEQ (p
, "data"))
3780 if (p
[4] == '1' && p
[5] == '6')
3781 priv
.orig_sizeflag
&= ~DFLAG
;
3782 else if (p
[4] == '3' && p
[5] == '2')
3783 priv
.orig_sizeflag
|= DFLAG
;
3785 else if (CONST_STRNEQ (p
, "suffix"))
3786 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3788 p
= strchr (p
, ',');
3795 names64
= intel_names64
;
3796 names32
= intel_names32
;
3797 names16
= intel_names16
;
3798 names8
= intel_names8
;
3799 names8rex
= intel_names8rex
;
3800 names_seg
= intel_names_seg
;
3801 index16
= intel_index16
;
3804 separator_char
= '+';
3809 names64
= att_names64
;
3810 names32
= att_names32
;
3811 names16
= att_names16
;
3812 names8
= att_names8
;
3813 names8rex
= att_names8rex
;
3814 names_seg
= att_names_seg
;
3815 index16
= att_index16
;
3818 separator_char
= ',';
3822 /* The output looks better if we put 7 bytes on a line, since that
3823 puts most long word instructions on a single line. */
3824 info
->bytes_per_line
= 7;
3826 info
->private_data
= &priv
;
3827 priv
.max_fetched
= priv
.the_buffer
;
3828 priv
.insn_start
= pc
;
3831 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3839 start_codep
= priv
.the_buffer
;
3840 codep
= priv
.the_buffer
;
3842 if (setjmp (priv
.bailout
) != 0)
3846 /* Getting here means we tried for data but didn't get it. That
3847 means we have an incomplete instruction of some sort. Just
3848 print the first byte as a prefix or a .byte pseudo-op. */
3849 if (codep
> priv
.the_buffer
)
3851 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3853 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3856 /* Just print the first byte as a .byte instruction. */
3857 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3858 (unsigned int) priv
.the_buffer
[0]);
3871 sizeflag
= priv
.orig_sizeflag
;
3873 FETCH_DATA (info
, codep
+ 1);
3874 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3876 if (((prefixes
& PREFIX_FWAIT
)
3877 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3878 || (rex
&& rex_used
))
3882 /* fwait not followed by floating point instruction, or rex followed
3883 by other prefixes. Print the first prefix. */
3884 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3886 name
= INTERNAL_DISASSEMBLER_ERROR
;
3887 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3894 unsigned char threebyte
;
3895 FETCH_DATA (info
, codep
+ 2);
3896 threebyte
= *++codep
;
3897 dp
= &dis386_twobyte
[threebyte
];
3898 need_modrm
= twobyte_has_modrm
[*codep
];
3900 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3902 FETCH_DATA (info
, codep
+ 2);
3908 dp
= &dis386
[*codep
];
3909 need_modrm
= onebyte_has_modrm
[*codep
];
3913 if ((prefixes
& PREFIX_REPZ
))
3915 repz_prefix
= "repz ";
3916 used_prefixes
|= PREFIX_REPZ
;
3921 if ((prefixes
& PREFIX_REPNZ
))
3923 repnz_prefix
= "repnz ";
3924 used_prefixes
|= PREFIX_REPNZ
;
3927 repnz_prefix
= NULL
;
3929 if ((prefixes
& PREFIX_LOCK
))
3931 lock_prefix
= "lock ";
3932 used_prefixes
|= PREFIX_LOCK
;
3938 if (prefixes
& PREFIX_ADDR
)
3941 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3943 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3944 addr_prefix
= "addr32 ";
3946 addr_prefix
= "addr16 ";
3947 used_prefixes
|= PREFIX_ADDR
;
3952 if ((prefixes
& PREFIX_DATA
))
3955 if (dp
->op
[2].bytemode
== cond_jump_mode
3956 && dp
->op
[0].bytemode
== v_mode
3959 if (sizeflag
& DFLAG
)
3960 data_prefix
= "data32 ";
3962 data_prefix
= "data16 ";
3963 used_prefixes
|= PREFIX_DATA
;
3967 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3969 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3970 modrm
.mod
= (*codep
>> 6) & 3;
3971 modrm
.reg
= (*codep
>> 3) & 7;
3972 modrm
.rm
= *codep
& 7;
3974 else if (need_modrm
)
3976 FETCH_DATA (info
, codep
+ 1);
3977 modrm
.mod
= (*codep
>> 6) & 3;
3978 modrm
.reg
= (*codep
>> 3) & 7;
3979 modrm
.rm
= *codep
& 7;
3982 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3988 dp
= get_valid_dis386 (dp
);
3989 if (dp
!= NULL
&& putop (dp
->name
, sizeflag
) == 0)
3991 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3994 op_ad
= MAX_OPERANDS
- 1 - i
;
3996 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
4001 /* See if any prefixes were not used. If so, print the first one
4002 separately. If we don't do this, we'll wind up printing an
4003 instruction stream which does not precisely correspond to the
4004 bytes we are disassembling. */
4005 if ((prefixes
& ~used_prefixes
) != 0)
4009 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
4011 name
= INTERNAL_DISASSEMBLER_ERROR
;
4012 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
4015 if (rex
& ~rex_used
)
4018 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
4020 name
= INTERNAL_DISASSEMBLER_ERROR
;
4021 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
4025 prefix_obufp
= prefix_obuf
;
4027 prefix_obufp
= stpcpy (prefix_obufp
, lock_prefix
);
4029 prefix_obufp
= stpcpy (prefix_obufp
, repz_prefix
);
4031 prefix_obufp
= stpcpy (prefix_obufp
, repnz_prefix
);
4033 prefix_obufp
= stpcpy (prefix_obufp
, addr_prefix
);
4035 prefix_obufp
= stpcpy (prefix_obufp
, data_prefix
);
4037 if (prefix_obuf
[0] != 0)
4038 (*info
->fprintf_func
) (info
->stream
, "%s", prefix_obuf
);
4040 obufp
= obuf
+ strlen (obuf
);
4041 for (i
= strlen (obuf
) + strlen (prefix_obuf
); i
< 6; i
++)
4044 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
4046 /* The enter and bound instructions are printed with operands in the same
4047 order as the intel book; everything else is printed in reverse order. */
4048 if (intel_syntax
|| two_source_ops
)
4052 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4053 op_txt
[i
] = op_out
[i
];
4055 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
4057 op_ad
= op_index
[i
];
4058 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
4059 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
4060 riprel
= op_riprel
[i
];
4061 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
4062 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
4067 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4068 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
4072 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4076 (*info
->fprintf_func
) (info
->stream
, ",");
4077 if (op_index
[i
] != -1 && !op_riprel
[i
])
4078 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
4080 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
4084 for (i
= 0; i
< MAX_OPERANDS
; i
++)
4085 if (op_index
[i
] != -1 && op_riprel
[i
])
4087 (*info
->fprintf_func
) (info
->stream
, " # ");
4088 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
4089 + op_address
[op_index
[i
]]), info
);
4092 return codep
- priv
.the_buffer
;
4095 static const char *float_mem
[] = {
4170 static const unsigned char float_mem_mode
[] = {
4245 #define ST { OP_ST, 0 }
4246 #define STi { OP_STi, 0 }
4248 #define FGRPd9_2 NULL, { { NULL, 0 } }
4249 #define FGRPd9_4 NULL, { { NULL, 1 } }
4250 #define FGRPd9_5 NULL, { { NULL, 2 } }
4251 #define FGRPd9_6 NULL, { { NULL, 3 } }
4252 #define FGRPd9_7 NULL, { { NULL, 4 } }
4253 #define FGRPda_5 NULL, { { NULL, 5 } }
4254 #define FGRPdb_4 NULL, { { NULL, 6 } }
4255 #define FGRPde_3 NULL, { { NULL, 7 } }
4256 #define FGRPdf_4 NULL, { { NULL, 8 } }
4258 static const struct dis386 float_reg
[][8] = {
4261 { "fadd", { ST
, STi
} },
4262 { "fmul", { ST
, STi
} },
4263 { "fcom", { STi
} },
4264 { "fcomp", { STi
} },
4265 { "fsub", { ST
, STi
} },
4266 { "fsubr", { ST
, STi
} },
4267 { "fdiv", { ST
, STi
} },
4268 { "fdivr", { ST
, STi
} },
4273 { "fxch", { STi
} },
4275 { "(bad)", { XX
} },
4283 { "fcmovb", { ST
, STi
} },
4284 { "fcmove", { ST
, STi
} },
4285 { "fcmovbe",{ ST
, STi
} },
4286 { "fcmovu", { ST
, STi
} },
4287 { "(bad)", { XX
} },
4289 { "(bad)", { XX
} },
4290 { "(bad)", { XX
} },
4294 { "fcmovnb",{ ST
, STi
} },
4295 { "fcmovne",{ ST
, STi
} },
4296 { "fcmovnbe",{ ST
, STi
} },
4297 { "fcmovnu",{ ST
, STi
} },
4299 { "fucomi", { ST
, STi
} },
4300 { "fcomi", { ST
, STi
} },
4301 { "(bad)", { XX
} },
4305 { "fadd", { STi
, ST
} },
4306 { "fmul", { STi
, ST
} },
4307 { "(bad)", { XX
} },
4308 { "(bad)", { XX
} },
4310 { "fsub", { STi
, ST
} },
4311 { "fsubr", { STi
, ST
} },
4312 { "fdiv", { STi
, ST
} },
4313 { "fdivr", { STi
, ST
} },
4315 { "fsubr", { STi
, ST
} },
4316 { "fsub", { STi
, ST
} },
4317 { "fdivr", { STi
, ST
} },
4318 { "fdiv", { STi
, ST
} },
4323 { "ffree", { STi
} },
4324 { "(bad)", { XX
} },
4326 { "fstp", { STi
} },
4327 { "fucom", { STi
} },
4328 { "fucomp", { STi
} },
4329 { "(bad)", { XX
} },
4330 { "(bad)", { XX
} },
4334 { "faddp", { STi
, ST
} },
4335 { "fmulp", { STi
, ST
} },
4336 { "(bad)", { XX
} },
4339 { "fsubp", { STi
, ST
} },
4340 { "fsubrp", { STi
, ST
} },
4341 { "fdivp", { STi
, ST
} },
4342 { "fdivrp", { STi
, ST
} },
4344 { "fsubrp", { STi
, ST
} },
4345 { "fsubp", { STi
, ST
} },
4346 { "fdivrp", { STi
, ST
} },
4347 { "fdivp", { STi
, ST
} },
4352 { "ffreep", { STi
} },
4353 { "(bad)", { XX
} },
4354 { "(bad)", { XX
} },
4355 { "(bad)", { XX
} },
4357 { "fucomip", { ST
, STi
} },
4358 { "fcomip", { ST
, STi
} },
4359 { "(bad)", { XX
} },
4363 static char *fgrps
[][8] = {
4366 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4371 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4376 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4381 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4386 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4391 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4396 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4397 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4402 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4407 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4412 OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED
,
4413 int sizeflag ATTRIBUTE_UNUSED
)
4415 /* Skip mod/rm byte. */
4421 dofloat (int sizeflag
)
4423 const struct dis386
*dp
;
4424 unsigned char floatop
;
4426 floatop
= codep
[-1];
4430 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4432 putop (float_mem
[fp_indx
], sizeflag
);
4435 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4438 /* Skip mod/rm byte. */
4442 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4443 if (dp
->name
== NULL
)
4445 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4447 /* Instruction fnstsw is only one with strange arg. */
4448 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4449 strcpy (op_out
[0], names16
[0]);
4453 putop (dp
->name
, sizeflag
);
4458 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4463 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4468 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4470 oappend ("%st" + intel_syntax
);
4474 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4476 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4477 oappend (scratchbuf
+ intel_syntax
);
4480 /* Capital letters in template are macros. */
4482 putop (const char *template, int sizeflag
)
4487 for (p
= template; *p
; p
++)
4498 if (address_mode
== mode_64bit
)
4506 /* Alternative not valid. */
4507 strcpy (obuf
, "(bad)");
4511 else if (*p
== '\0')
4532 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4538 if (sizeflag
& SUFFIX_ALWAYS
)
4542 if (intel_syntax
&& !alt
)
4544 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4546 if (sizeflag
& DFLAG
)
4547 *obufp
++ = intel_syntax
? 'd' : 'l';
4549 *obufp
++ = intel_syntax
? 'w' : 's';
4550 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4554 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4561 else if (sizeflag
& DFLAG
)
4562 *obufp
++ = intel_syntax
? 'd' : 'l';
4565 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4570 case 'E': /* For jcxz/jecxz */
4571 if (address_mode
== mode_64bit
)
4573 if (sizeflag
& AFLAG
)
4579 if (sizeflag
& AFLAG
)
4581 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4586 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4588 if (sizeflag
& AFLAG
)
4589 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4591 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4592 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4596 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4598 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4603 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4608 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4609 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4611 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4614 if (prefixes
& PREFIX_DS
)
4635 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4644 if (sizeflag
& SUFFIX_ALWAYS
)
4648 if ((prefixes
& PREFIX_FWAIT
) == 0)
4651 used_prefixes
|= PREFIX_FWAIT
;
4657 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4662 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4667 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4676 if ((prefixes
& PREFIX_DATA
)
4678 || (sizeflag
& SUFFIX_ALWAYS
))
4685 if (sizeflag
& DFLAG
)
4690 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4696 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4698 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4704 if (intel_syntax
&& !alt
)
4707 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4713 if (sizeflag
& DFLAG
)
4714 *obufp
++ = intel_syntax
? 'd' : 'l';
4718 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4725 else if (sizeflag
& DFLAG
)
4734 if (intel_syntax
&& !p
[1]
4735 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4738 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4743 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4745 if (sizeflag
& SUFFIX_ALWAYS
)
4753 if (sizeflag
& SUFFIX_ALWAYS
)
4759 if (sizeflag
& DFLAG
)
4763 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4768 if (prefixes
& PREFIX_DATA
)
4772 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4783 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4785 /* operand size flag for cwtl, cbtw */
4794 else if (sizeflag
& DFLAG
)
4799 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4809 oappend (const char *s
)
4812 obufp
+= strlen (s
);
4818 if (prefixes
& PREFIX_CS
)
4820 used_prefixes
|= PREFIX_CS
;
4821 oappend ("%cs:" + intel_syntax
);
4823 if (prefixes
& PREFIX_DS
)
4825 used_prefixes
|= PREFIX_DS
;
4826 oappend ("%ds:" + intel_syntax
);
4828 if (prefixes
& PREFIX_SS
)
4830 used_prefixes
|= PREFIX_SS
;
4831 oappend ("%ss:" + intel_syntax
);
4833 if (prefixes
& PREFIX_ES
)
4835 used_prefixes
|= PREFIX_ES
;
4836 oappend ("%es:" + intel_syntax
);
4838 if (prefixes
& PREFIX_FS
)
4840 used_prefixes
|= PREFIX_FS
;
4841 oappend ("%fs:" + intel_syntax
);
4843 if (prefixes
& PREFIX_GS
)
4845 used_prefixes
|= PREFIX_GS
;
4846 oappend ("%gs:" + intel_syntax
);
4851 OP_indirE (int bytemode
, int sizeflag
)
4855 OP_E (bytemode
, sizeflag
);
4859 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4861 if (address_mode
== mode_64bit
)
4869 sprintf_vma (tmp
, disp
);
4870 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4871 strcpy (buf
+ 2, tmp
+ i
);
4875 bfd_signed_vma v
= disp
;
4882 /* Check for possible overflow on 0x8000000000000000. */
4885 strcpy (buf
, "9223372036854775808");
4899 tmp
[28 - i
] = (v
% 10) + '0';
4903 strcpy (buf
, tmp
+ 29 - i
);
4909 sprintf (buf
, "0x%x", (unsigned int) disp
);
4911 sprintf (buf
, "%d", (int) disp
);
4915 /* Put DISP in BUF as signed hex number. */
4918 print_displacement (char *buf
, bfd_vma disp
)
4920 bfd_signed_vma val
= disp
;
4929 /* Check for possible overflow. */
4932 switch (address_mode
)
4935 strcpy (buf
+ j
, "0x8000000000000000");
4938 strcpy (buf
+ j
, "0x80000000");
4941 strcpy (buf
+ j
, "0x8000");
4951 sprintf_vma (tmp
, val
);
4952 for (i
= 0; tmp
[i
] == '0'; i
++)
4956 strcpy (buf
+ j
, tmp
+ i
);
4960 intel_operand_size (int bytemode
, int sizeflag
)
4966 oappend ("BYTE PTR ");
4970 oappend ("WORD PTR ");
4973 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4975 oappend ("QWORD PTR ");
4976 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4984 oappend ("QWORD PTR ");
4985 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4986 oappend ("DWORD PTR ");
4988 oappend ("WORD PTR ");
4989 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4992 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4994 oappend ("WORD PTR ");
4996 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5000 oappend ("DWORD PTR ");
5003 oappend ("QWORD PTR ");
5006 if (address_mode
== mode_64bit
)
5007 oappend ("QWORD PTR ");
5009 oappend ("DWORD PTR ");
5012 if (sizeflag
& DFLAG
)
5013 oappend ("FWORD PTR ");
5015 oappend ("DWORD PTR ");
5016 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5019 oappend ("TBYTE PTR ");
5022 oappend ("XMMWORD PTR ");
5025 oappend ("OWORD PTR ");
5033 OP_E (int bytemode
, int sizeflag
)
5042 /* Skip mod/rm byte. */
5053 oappend (names8rex
[modrm
.rm
+ add
]);
5055 oappend (names8
[modrm
.rm
+ add
]);
5058 oappend (names16
[modrm
.rm
+ add
]);
5061 oappend (names32
[modrm
.rm
+ add
]);
5064 oappend (names64
[modrm
.rm
+ add
]);
5067 if (address_mode
== mode_64bit
)
5068 oappend (names64
[modrm
.rm
+ add
]);
5070 oappend (names32
[modrm
.rm
+ add
]);
5073 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5075 oappend (names64
[modrm
.rm
+ add
]);
5076 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5088 oappend (names64
[modrm
.rm
+ add
]);
5089 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5090 oappend (names32
[modrm
.rm
+ add
]);
5092 oappend (names16
[modrm
.rm
+ add
]);
5093 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5098 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5106 intel_operand_size (bytemode
, sizeflag
);
5109 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5111 /* 32/64 bit address mode */
5126 FETCH_DATA (the_info
, codep
+ 1);
5127 index
= (*codep
>> 3) & 7;
5128 if (address_mode
== mode_64bit
|| index
!= 0x4)
5129 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
5130 scale
= (*codep
>> 6) & 3;
5142 if ((base
& 7) == 5)
5145 if (address_mode
== mode_64bit
&& !havesib
)
5151 FETCH_DATA (the_info
, codep
+ 1);
5153 if ((disp
& 0x80) != 0)
5161 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
5164 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5166 if (havedisp
|| riprel
)
5167 print_displacement (scratchbuf
, disp
);
5169 print_operand_value (scratchbuf
, 1, disp
);
5170 oappend (scratchbuf
);
5178 if (havedisp
|| (intel_syntax
&& riprel
))
5180 *obufp
++ = open_char
;
5181 if (intel_syntax
&& riprel
)
5188 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5189 ? names64
[base
] : names32
[base
]);
5194 if (!intel_syntax
|| havebase
)
5196 *obufp
++ = separator_char
;
5199 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5200 ? names64
[index
] : names32
[index
]);
5202 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
5204 *obufp
++ = scale_char
;
5206 sprintf (scratchbuf
, "%d", 1 << scale
);
5207 oappend (scratchbuf
);
5211 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
5213 if ((bfd_signed_vma
) disp
>= 0)
5218 else if (modrm
.mod
!= 1)
5222 disp
= - (bfd_signed_vma
) disp
;
5225 print_displacement (scratchbuf
, disp
);
5226 oappend (scratchbuf
);
5229 *obufp
++ = close_char
;
5232 else if (intel_syntax
)
5234 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5236 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5237 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5241 oappend (names_seg
[ds_reg
- es_reg
]);
5244 print_operand_value (scratchbuf
, 1, disp
);
5245 oappend (scratchbuf
);
5250 { /* 16 bit address mode */
5257 if ((disp
& 0x8000) != 0)
5262 FETCH_DATA (the_info
, codep
+ 1);
5264 if ((disp
& 0x80) != 0)
5269 if ((disp
& 0x8000) != 0)
5275 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5277 print_displacement (scratchbuf
, disp
);
5278 oappend (scratchbuf
);
5281 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5283 *obufp
++ = open_char
;
5285 oappend (index16
[modrm
.rm
]);
5287 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5289 if ((bfd_signed_vma
) disp
>= 0)
5294 else if (modrm
.mod
!= 1)
5298 disp
= - (bfd_signed_vma
) disp
;
5301 print_displacement (scratchbuf
, disp
);
5302 oappend (scratchbuf
);
5305 *obufp
++ = close_char
;
5308 else if (intel_syntax
)
5310 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5311 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5315 oappend (names_seg
[ds_reg
- es_reg
]);
5318 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
5319 oappend (scratchbuf
);
5325 OP_G (int bytemode
, int sizeflag
)
5336 oappend (names8rex
[modrm
.reg
+ add
]);
5338 oappend (names8
[modrm
.reg
+ add
]);
5341 oappend (names16
[modrm
.reg
+ add
]);
5344 oappend (names32
[modrm
.reg
+ add
]);
5347 oappend (names64
[modrm
.reg
+ add
]);
5356 oappend (names64
[modrm
.reg
+ add
]);
5357 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5358 oappend (names32
[modrm
.reg
+ add
]);
5360 oappend (names16
[modrm
.reg
+ add
]);
5361 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5364 if (address_mode
== mode_64bit
)
5365 oappend (names64
[modrm
.reg
+ add
]);
5367 oappend (names32
[modrm
.reg
+ add
]);
5370 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5383 FETCH_DATA (the_info
, codep
+ 8);
5384 a
= *codep
++ & 0xff;
5385 a
|= (*codep
++ & 0xff) << 8;
5386 a
|= (*codep
++ & 0xff) << 16;
5387 a
|= (*codep
++ & 0xff) << 24;
5388 b
= *codep
++ & 0xff;
5389 b
|= (*codep
++ & 0xff) << 8;
5390 b
|= (*codep
++ & 0xff) << 16;
5391 b
|= (*codep
++ & 0xff) << 24;
5392 x
= a
+ ((bfd_vma
) b
<< 32);
5400 static bfd_signed_vma
5403 bfd_signed_vma x
= 0;
5405 FETCH_DATA (the_info
, codep
+ 4);
5406 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5407 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5408 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5409 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5413 static bfd_signed_vma
5416 bfd_signed_vma x
= 0;
5418 FETCH_DATA (the_info
, codep
+ 4);
5419 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5420 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5421 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5422 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5424 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5434 FETCH_DATA (the_info
, codep
+ 2);
5435 x
= *codep
++ & 0xff;
5436 x
|= (*codep
++ & 0xff) << 8;
5441 set_op (bfd_vma op
, int riprel
)
5443 op_index
[op_ad
] = op_ad
;
5444 if (address_mode
== mode_64bit
)
5446 op_address
[op_ad
] = op
;
5447 op_riprel
[op_ad
] = riprel
;
5451 /* Mask to get a 32-bit address. */
5452 op_address
[op_ad
] = op
& 0xffffffff;
5453 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5458 OP_REG (int code
, int sizeflag
)
5468 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5469 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5470 s
= names16
[code
- ax_reg
+ add
];
5472 case es_reg
: case ss_reg
: case cs_reg
:
5473 case ds_reg
: case fs_reg
: case gs_reg
:
5474 s
= names_seg
[code
- es_reg
+ add
];
5476 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5477 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5480 s
= names8rex
[code
- al_reg
+ add
];
5482 s
= names8
[code
- al_reg
];
5484 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5485 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5486 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5488 s
= names64
[code
- rAX_reg
+ add
];
5491 code
+= eAX_reg
- rAX_reg
;
5493 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5494 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5497 s
= names64
[code
- eAX_reg
+ add
];
5498 else if (sizeflag
& DFLAG
)
5499 s
= names32
[code
- eAX_reg
+ add
];
5501 s
= names16
[code
- eAX_reg
+ add
];
5502 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5505 s
= INTERNAL_DISASSEMBLER_ERROR
;
5512 OP_IMREG (int code
, int sizeflag
)
5524 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5525 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5526 s
= names16
[code
- ax_reg
];
5528 case es_reg
: case ss_reg
: case cs_reg
:
5529 case ds_reg
: case fs_reg
: case gs_reg
:
5530 s
= names_seg
[code
- es_reg
];
5532 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5533 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5536 s
= names8rex
[code
- al_reg
];
5538 s
= names8
[code
- al_reg
];
5540 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5541 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5544 s
= names64
[code
- eAX_reg
];
5545 else if (sizeflag
& DFLAG
)
5546 s
= names32
[code
- eAX_reg
];
5548 s
= names16
[code
- eAX_reg
];
5549 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5552 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5557 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5560 s
= INTERNAL_DISASSEMBLER_ERROR
;
5567 OP_I (int bytemode
, int sizeflag
)
5570 bfd_signed_vma mask
= -1;
5575 FETCH_DATA (the_info
, codep
+ 1);
5580 if (address_mode
== mode_64bit
)
5590 else if (sizeflag
& DFLAG
)
5600 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5611 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5616 scratchbuf
[0] = '$';
5617 print_operand_value (scratchbuf
+ 1, 1, op
);
5618 oappend (scratchbuf
+ intel_syntax
);
5619 scratchbuf
[0] = '\0';
5623 OP_I64 (int bytemode
, int sizeflag
)
5626 bfd_signed_vma mask
= -1;
5628 if (address_mode
!= mode_64bit
)
5630 OP_I (bytemode
, sizeflag
);
5637 FETCH_DATA (the_info
, codep
+ 1);
5645 else if (sizeflag
& DFLAG
)
5655 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5662 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5667 scratchbuf
[0] = '$';
5668 print_operand_value (scratchbuf
+ 1, 1, op
);
5669 oappend (scratchbuf
+ intel_syntax
);
5670 scratchbuf
[0] = '\0';
5674 OP_sI (int bytemode
, int sizeflag
)
5677 bfd_signed_vma mask
= -1;
5682 FETCH_DATA (the_info
, codep
+ 1);
5684 if ((op
& 0x80) != 0)
5692 else if (sizeflag
& DFLAG
)
5701 if ((op
& 0x8000) != 0)
5704 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5709 if ((op
& 0x8000) != 0)
5713 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5717 scratchbuf
[0] = '$';
5718 print_operand_value (scratchbuf
+ 1, 1, op
);
5719 oappend (scratchbuf
+ intel_syntax
);
5723 OP_J (int bytemode
, int sizeflag
)
5727 bfd_vma segment
= 0;
5732 FETCH_DATA (the_info
, codep
+ 1);
5734 if ((disp
& 0x80) != 0)
5738 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5743 if ((disp
& 0x8000) != 0)
5745 /* In 16bit mode, address is wrapped around at 64k within
5746 the same segment. Otherwise, a data16 prefix on a jump
5747 instruction means that the pc is masked to 16 bits after
5748 the displacement is added! */
5750 if ((prefixes
& PREFIX_DATA
) == 0)
5751 segment
= ((start_pc
+ codep
- start_codep
)
5752 & ~((bfd_vma
) 0xffff));
5754 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5757 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5760 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5762 print_operand_value (scratchbuf
, 1, disp
);
5763 oappend (scratchbuf
);
5767 OP_SEG (int bytemode
, int sizeflag
)
5769 if (bytemode
== w_mode
)
5770 oappend (names_seg
[modrm
.reg
]);
5772 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5776 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5780 if (sizeflag
& DFLAG
)
5790 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5792 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5794 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5795 oappend (scratchbuf
);
5799 OP_OFF (int bytemode
, int sizeflag
)
5803 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5804 intel_operand_size (bytemode
, sizeflag
);
5807 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5814 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5815 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5817 oappend (names_seg
[ds_reg
- es_reg
]);
5821 print_operand_value (scratchbuf
, 1, off
);
5822 oappend (scratchbuf
);
5826 OP_OFF64 (int bytemode
, int sizeflag
)
5830 if (address_mode
!= mode_64bit
5831 || (prefixes
& PREFIX_ADDR
))
5833 OP_OFF (bytemode
, sizeflag
);
5837 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5838 intel_operand_size (bytemode
, sizeflag
);
5845 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5846 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5848 oappend (names_seg
[ds_reg
- es_reg
]);
5852 print_operand_value (scratchbuf
, 1, off
);
5853 oappend (scratchbuf
);
5857 ptr_reg (int code
, int sizeflag
)
5861 *obufp
++ = open_char
;
5862 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5863 if (address_mode
== mode_64bit
)
5865 if (!(sizeflag
& AFLAG
))
5866 s
= names32
[code
- eAX_reg
];
5868 s
= names64
[code
- eAX_reg
];
5870 else if (sizeflag
& AFLAG
)
5871 s
= names32
[code
- eAX_reg
];
5873 s
= names16
[code
- eAX_reg
];
5875 *obufp
++ = close_char
;
5880 OP_ESreg (int code
, int sizeflag
)
5886 case 0x6d: /* insw/insl */
5887 intel_operand_size (z_mode
, sizeflag
);
5889 case 0xa5: /* movsw/movsl/movsq */
5890 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5891 case 0xab: /* stosw/stosl */
5892 case 0xaf: /* scasw/scasl */
5893 intel_operand_size (v_mode
, sizeflag
);
5896 intel_operand_size (b_mode
, sizeflag
);
5899 oappend ("%es:" + intel_syntax
);
5900 ptr_reg (code
, sizeflag
);
5904 OP_DSreg (int code
, int sizeflag
)
5910 case 0x6f: /* outsw/outsl */
5911 intel_operand_size (z_mode
, sizeflag
);
5913 case 0xa5: /* movsw/movsl/movsq */
5914 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5915 case 0xad: /* lodsw/lodsl/lodsq */
5916 intel_operand_size (v_mode
, sizeflag
);
5919 intel_operand_size (b_mode
, sizeflag
);
5929 prefixes
|= PREFIX_DS
;
5931 ptr_reg (code
, sizeflag
);
5935 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5943 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5946 used_prefixes
|= PREFIX_LOCK
;
5949 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5950 oappend (scratchbuf
+ intel_syntax
);
5954 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5961 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5963 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5964 oappend (scratchbuf
);
5968 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5970 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5971 oappend (scratchbuf
+ intel_syntax
);
5975 OP_R (int bytemode
, int sizeflag
)
5978 OP_E (bytemode
, sizeflag
);
5984 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5986 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5987 if (prefixes
& PREFIX_DATA
)
5993 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5996 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5997 oappend (scratchbuf
+ intel_syntax
);
6001 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6007 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
6008 oappend (scratchbuf
+ intel_syntax
);
6012 OP_EM (int bytemode
, int sizeflag
)
6016 if (intel_syntax
&& bytemode
== v_mode
)
6018 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
6019 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6021 OP_E (bytemode
, sizeflag
);
6025 /* Skip mod/rm byte. */
6028 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6029 if (prefixes
& PREFIX_DATA
)
6036 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
6039 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
6040 oappend (scratchbuf
+ intel_syntax
);
6043 /* cvt* are the only instructions in sse2 which have
6044 both SSE and MMX operands and also have 0x66 prefix
6045 in their opcode. 0x66 was originally used to differentiate
6046 between SSE and MMX instruction(operands). So we have to handle the
6047 cvt* separately using OP_EMC and OP_MXC */
6049 OP_EMC (int bytemode
, int sizeflag
)
6053 if (intel_syntax
&& bytemode
== v_mode
)
6055 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
6056 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6058 OP_E (bytemode
, sizeflag
);
6062 /* Skip mod/rm byte. */
6065 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6066 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
6067 oappend (scratchbuf
+ intel_syntax
);
6071 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6073 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6074 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
6075 oappend (scratchbuf
+ intel_syntax
);
6079 OP_EX (int bytemode
, int sizeflag
)
6084 OP_E (bytemode
, sizeflag
);
6091 /* Skip mod/rm byte. */
6094 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
6095 oappend (scratchbuf
+ intel_syntax
);
6099 OP_MS (int bytemode
, int sizeflag
)
6102 OP_EM (bytemode
, sizeflag
);
6108 OP_XS (int bytemode
, int sizeflag
)
6111 OP_EX (bytemode
, sizeflag
);
6117 OP_M (int bytemode
, int sizeflag
)
6120 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
6123 OP_E (bytemode
, sizeflag
);
6127 OP_0f07 (int bytemode
, int sizeflag
)
6129 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
6132 OP_E (bytemode
, sizeflag
);
6135 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6136 32bit mode and "xchg %rax,%rax" in 64bit mode. */
6139 NOP_Fixup1 (int bytemode
, int sizeflag
)
6141 if ((prefixes
& PREFIX_DATA
) != 0
6144 && address_mode
== mode_64bit
))
6145 OP_REG (bytemode
, sizeflag
);
6147 strcpy (obuf
, "nop");
6151 NOP_Fixup2 (int bytemode
, int sizeflag
)
6153 if ((prefixes
& PREFIX_DATA
) != 0
6156 && address_mode
== mode_64bit
))
6157 OP_IMREG (bytemode
, sizeflag
);
6160 static const char *const Suffix3DNow
[] = {
6161 /* 00 */ NULL
, NULL
, NULL
, NULL
,
6162 /* 04 */ NULL
, NULL
, NULL
, NULL
,
6163 /* 08 */ NULL
, NULL
, NULL
, NULL
,
6164 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
6165 /* 10 */ NULL
, NULL
, NULL
, NULL
,
6166 /* 14 */ NULL
, NULL
, NULL
, NULL
,
6167 /* 18 */ NULL
, NULL
, NULL
, NULL
,
6168 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
6169 /* 20 */ NULL
, NULL
, NULL
, NULL
,
6170 /* 24 */ NULL
, NULL
, NULL
, NULL
,
6171 /* 28 */ NULL
, NULL
, NULL
, NULL
,
6172 /* 2C */ NULL
, NULL
, NULL
, NULL
,
6173 /* 30 */ NULL
, NULL
, NULL
, NULL
,
6174 /* 34 */ NULL
, NULL
, NULL
, NULL
,
6175 /* 38 */ NULL
, NULL
, NULL
, NULL
,
6176 /* 3C */ NULL
, NULL
, NULL
, NULL
,
6177 /* 40 */ NULL
, NULL
, NULL
, NULL
,
6178 /* 44 */ NULL
, NULL
, NULL
, NULL
,
6179 /* 48 */ NULL
, NULL
, NULL
, NULL
,
6180 /* 4C */ NULL
, NULL
, NULL
, NULL
,
6181 /* 50 */ NULL
, NULL
, NULL
, NULL
,
6182 /* 54 */ NULL
, NULL
, NULL
, NULL
,
6183 /* 58 */ NULL
, NULL
, NULL
, NULL
,
6184 /* 5C */ NULL
, NULL
, NULL
, NULL
,
6185 /* 60 */ NULL
, NULL
, NULL
, NULL
,
6186 /* 64 */ NULL
, NULL
, NULL
, NULL
,
6187 /* 68 */ NULL
, NULL
, NULL
, NULL
,
6188 /* 6C */ NULL
, NULL
, NULL
, NULL
,
6189 /* 70 */ NULL
, NULL
, NULL
, NULL
,
6190 /* 74 */ NULL
, NULL
, NULL
, NULL
,
6191 /* 78 */ NULL
, NULL
, NULL
, NULL
,
6192 /* 7C */ NULL
, NULL
, NULL
, NULL
,
6193 /* 80 */ NULL
, NULL
, NULL
, NULL
,
6194 /* 84 */ NULL
, NULL
, NULL
, NULL
,
6195 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
6196 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
6197 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
6198 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
6199 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
6200 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
6201 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
6202 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
6203 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
6204 /* AC */ NULL
, NULL
, "pfacc", NULL
,
6205 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
6206 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
6207 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
6208 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6209 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6210 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6211 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6212 /* CC */ NULL
, NULL
, NULL
, NULL
,
6213 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6214 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6215 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6216 /* DC */ NULL
, NULL
, NULL
, NULL
,
6217 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6218 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6219 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6220 /* EC */ NULL
, NULL
, NULL
, NULL
,
6221 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6222 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6223 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6224 /* FC */ NULL
, NULL
, NULL
, NULL
,
6228 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6230 const char *mnemonic
;
6232 FETCH_DATA (the_info
, codep
+ 1);
6233 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6234 place where an 8-bit immediate would normally go. ie. the last
6235 byte of the instruction. */
6236 obufp
= obuf
+ strlen (obuf
);
6237 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6242 /* Since a variable sized modrm/sib chunk is between the start
6243 of the opcode (0x0f0f) and the opcode suffix, we need to do
6244 all the modrm processing first, and don't know until now that
6245 we have a bad opcode. This necessitates some cleaning up. */
6246 op_out
[0][0] = '\0';
6247 op_out
[1][0] = '\0';
6252 static const char *simd_cmp_op
[] = {
6264 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6266 unsigned int cmp_type
;
6268 FETCH_DATA (the_info
, codep
+ 1);
6269 obufp
= obuf
+ strlen (obuf
);
6270 cmp_type
= *codep
++ & 0xff;
6273 char suffix1
= 'p', suffix2
= 's';
6274 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6275 if (prefixes
& PREFIX_REPZ
)
6279 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6280 if (prefixes
& PREFIX_DATA
)
6284 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6285 if (prefixes
& PREFIX_REPNZ
)
6286 suffix1
= 's', suffix2
= 'd';
6289 sprintf (scratchbuf
, "cmp%s%c%c",
6290 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6291 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6292 oappend (scratchbuf
);
6296 /* We have a bad extension byte. Clean up. */
6297 op_out
[0][0] = '\0';
6298 op_out
[1][0] = '\0';
6304 OP_Mwait (int bytemode ATTRIBUTE_UNUSED
,
6305 int sizeflag ATTRIBUTE_UNUSED
)
6307 /* mwait %eax,%ecx */
6310 const char **names
= (address_mode
== mode_64bit
6311 ? names64
: names32
);
6312 strcpy (op_out
[0], names
[0]);
6313 strcpy (op_out
[1], names
[1]);
6316 /* Skip mod/rm byte. */
6322 OP_Monitor (int bytemode ATTRIBUTE_UNUSED
,
6323 int sizeflag ATTRIBUTE_UNUSED
)
6325 /* monitor %eax,%ecx,%edx" */
6328 const char **op1_names
;
6329 const char **names
= (address_mode
== mode_64bit
6330 ? names64
: names32
);
6332 if (!(prefixes
& PREFIX_ADDR
))
6333 op1_names
= (address_mode
== mode_16bit
6337 /* Remove "addr16/addr32". */
6339 op1_names
= (address_mode
!= mode_32bit
6340 ? names32
: names16
);
6341 used_prefixes
|= PREFIX_ADDR
;
6343 strcpy (op_out
[0], op1_names
[0]);
6344 strcpy (op_out
[1], names
[1]);
6345 strcpy (op_out
[2], names
[2]);
6348 /* Skip mod/rm byte. */
6356 /* Throw away prefixes and 1st. opcode byte. */
6357 codep
= insn_codep
+ 1;
6362 REP_Fixup (int bytemode
, int sizeflag
)
6364 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6366 if (prefixes
& PREFIX_REPZ
)
6367 repz_prefix
= "rep ";
6374 OP_IMREG (bytemode
, sizeflag
);
6377 OP_ESreg (bytemode
, sizeflag
);
6380 OP_DSreg (bytemode
, sizeflag
);
6389 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6394 /* Change cmpxchg8b to cmpxchg16b. */
6395 char *p
= obuf
+ strlen (obuf
) - 2;
6399 OP_M (bytemode
, sizeflag
);
6403 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6405 sprintf (scratchbuf
, "%%xmm%d", reg
);
6406 oappend (scratchbuf
+ intel_syntax
);
6410 CRC32_Fixup (int bytemode
, int sizeflag
)
6412 /* Add proper suffix to "crc32". */
6413 char *p
= obuf
+ strlen (obuf
);
6430 else if (sizeflag
& DFLAG
)
6434 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6437 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6446 /* Skip mod/rm byte. */
6451 add
= (rex
& REX_B
) ? 8 : 0;
6452 if (bytemode
== b_mode
)
6456 oappend (names8rex
[modrm
.rm
+ add
]);
6458 oappend (names8
[modrm
.rm
+ add
]);
6464 oappend (names64
[modrm
.rm
+ add
]);
6465 else if ((prefixes
& PREFIX_DATA
))
6466 oappend (names16
[modrm
.rm
+ add
]);
6468 oappend (names32
[modrm
.rm
+ add
]);
6472 OP_E (bytemode
, sizeflag
);