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 SVME_Fixup (int, int);
98 static void INVLPG_Fixup (int, int);
99 static void BadOp (void);
100 static void REP_Fixup (int, int);
101 static void CMPXCHG8B_Fixup (int, int);
102 static void XMM_Fixup (int, int);
103 static void CRC32_Fixup (int, int);
106 /* Points to first byte not fetched. */
107 bfd_byte
*max_fetched
;
108 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
121 enum address_mode address_mode
;
123 /* Flags for the prefixes for the current instruction. See below. */
126 /* REX prefix the current instruction. See below. */
128 /* Bits of REX we've already used. */
130 /* Mark parts used in the REX prefix. When we are testing for
131 empty prefix (for 8bit register REX extension), just mask it
132 out. Otherwise test for REX bit is excuse for existence of REX
133 only in case value is nonzero. */
134 #define USED_REX(value) \
139 rex_used |= (value) | REX_OPCODE; \
142 rex_used |= REX_OPCODE; \
145 /* Flags for prefixes which we somehow handled when printing the
146 current instruction. */
147 static int used_prefixes
;
149 /* Flags stored in PREFIXES. */
150 #define PREFIX_REPZ 1
151 #define PREFIX_REPNZ 2
152 #define PREFIX_LOCK 4
154 #define PREFIX_SS 0x10
155 #define PREFIX_DS 0x20
156 #define PREFIX_ES 0x40
157 #define PREFIX_FS 0x80
158 #define PREFIX_GS 0x100
159 #define PREFIX_DATA 0x200
160 #define PREFIX_ADDR 0x400
161 #define PREFIX_FWAIT 0x800
163 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
164 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
166 #define FETCH_DATA(info, addr) \
167 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
168 ? 1 : fetch_data ((info), (addr)))
171 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
174 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
175 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
177 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
178 status
= (*info
->read_memory_func
) (start
,
180 addr
- priv
->max_fetched
,
186 /* If we did manage to read at least one byte, then
187 print_insn_i386 will do something sensible. Otherwise, print
188 an error. We do that here because this is where we know
190 if (priv
->max_fetched
== priv
->the_buffer
)
191 (*info
->memory_error_func
) (status
, start
, info
);
192 longjmp (priv
->bailout
, 1);
195 priv
->max_fetched
= addr
;
199 #define XX { NULL, 0 }
201 #define Eb { OP_E, b_mode }
202 #define Ev { OP_E, v_mode }
203 #define Ed { OP_E, d_mode }
204 #define Edq { OP_E, dq_mode }
205 #define Edqw { OP_E, dqw_mode }
206 #define Edqb { OP_E, dqb_mode }
207 #define Edqd { OP_E, dqd_mode }
208 #define Eq { OP_E, q_mode }
209 #define indirEv { OP_indirE, stack_v_mode }
210 #define indirEp { OP_indirE, f_mode }
211 #define stackEv { OP_E, stack_v_mode }
212 #define Em { OP_E, m_mode }
213 #define Ew { OP_E, w_mode }
214 #define M { OP_M, 0 } /* lea, lgdt, etc. */
215 #define Ma { OP_M, v_mode }
216 #define Mb { OP_M, b_mode }
217 #define Md { OP_M, d_mode }
218 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
219 #define Mq { OP_M, q_mode }
220 #define Gb { OP_G, b_mode }
221 #define Gv { OP_G, v_mode }
222 #define Gd { OP_G, d_mode }
223 #define Gdq { OP_G, dq_mode }
224 #define Gm { OP_G, m_mode }
225 #define Gw { OP_G, w_mode }
226 #define Rd { OP_R, d_mode }
227 #define Rm { OP_R, m_mode }
228 #define Ib { OP_I, b_mode }
229 #define sIb { OP_sI, b_mode } /* sign extened byte */
230 #define Iv { OP_I, v_mode }
231 #define Iq { OP_I, q_mode }
232 #define Iv64 { OP_I64, v_mode }
233 #define Iw { OP_I, w_mode }
234 #define I1 { OP_I, const_1_mode }
235 #define Jb { OP_J, b_mode }
236 #define Jv { OP_J, v_mode }
237 #define Cm { OP_C, m_mode }
238 #define Dm { OP_D, m_mode }
239 #define Td { OP_T, d_mode }
240 #define Skip_MODRM { OP_Skip_MODRM, 0 }
242 #define RMeAX { OP_REG, eAX_reg }
243 #define RMeBX { OP_REG, eBX_reg }
244 #define RMeCX { OP_REG, eCX_reg }
245 #define RMeDX { OP_REG, eDX_reg }
246 #define RMeSP { OP_REG, eSP_reg }
247 #define RMeBP { OP_REG, eBP_reg }
248 #define RMeSI { OP_REG, eSI_reg }
249 #define RMeDI { OP_REG, eDI_reg }
250 #define RMrAX { OP_REG, rAX_reg }
251 #define RMrBX { OP_REG, rBX_reg }
252 #define RMrCX { OP_REG, rCX_reg }
253 #define RMrDX { OP_REG, rDX_reg }
254 #define RMrSP { OP_REG, rSP_reg }
255 #define RMrBP { OP_REG, rBP_reg }
256 #define RMrSI { OP_REG, rSI_reg }
257 #define RMrDI { OP_REG, rDI_reg }
258 #define RMAL { OP_REG, al_reg }
259 #define RMAL { OP_REG, al_reg }
260 #define RMCL { OP_REG, cl_reg }
261 #define RMDL { OP_REG, dl_reg }
262 #define RMBL { OP_REG, bl_reg }
263 #define RMAH { OP_REG, ah_reg }
264 #define RMCH { OP_REG, ch_reg }
265 #define RMDH { OP_REG, dh_reg }
266 #define RMBH { OP_REG, bh_reg }
267 #define RMAX { OP_REG, ax_reg }
268 #define RMDX { OP_REG, dx_reg }
270 #define eAX { OP_IMREG, eAX_reg }
271 #define eBX { OP_IMREG, eBX_reg }
272 #define eCX { OP_IMREG, eCX_reg }
273 #define eDX { OP_IMREG, eDX_reg }
274 #define eSP { OP_IMREG, eSP_reg }
275 #define eBP { OP_IMREG, eBP_reg }
276 #define eSI { OP_IMREG, eSI_reg }
277 #define eDI { OP_IMREG, eDI_reg }
278 #define AL { OP_IMREG, al_reg }
279 #define CL { OP_IMREG, cl_reg }
280 #define DL { OP_IMREG, dl_reg }
281 #define BL { OP_IMREG, bl_reg }
282 #define AH { OP_IMREG, ah_reg }
283 #define CH { OP_IMREG, ch_reg }
284 #define DH { OP_IMREG, dh_reg }
285 #define BH { OP_IMREG, bh_reg }
286 #define AX { OP_IMREG, ax_reg }
287 #define DX { OP_IMREG, dx_reg }
288 #define zAX { OP_IMREG, z_mode_ax_reg }
289 #define indirDX { OP_IMREG, indir_dx_reg }
291 #define Sw { OP_SEG, w_mode }
292 #define Sv { OP_SEG, v_mode }
293 #define Ap { OP_DIR, 0 }
294 #define Ob { OP_OFF64, b_mode }
295 #define Ov { OP_OFF64, v_mode }
296 #define Xb { OP_DSreg, eSI_reg }
297 #define Xv { OP_DSreg, eSI_reg }
298 #define Xz { OP_DSreg, eSI_reg }
299 #define Yb { OP_ESreg, eDI_reg }
300 #define Yv { OP_ESreg, eDI_reg }
301 #define DSBX { OP_DSreg, eBX_reg }
303 #define es { OP_REG, es_reg }
304 #define ss { OP_REG, ss_reg }
305 #define cs { OP_REG, cs_reg }
306 #define ds { OP_REG, ds_reg }
307 #define fs { OP_REG, fs_reg }
308 #define gs { OP_REG, gs_reg }
310 #define MX { OP_MMX, 0 }
311 #define XM { OP_XMM, 0 }
312 #define EM { OP_EM, v_mode }
313 #define EMd { OP_EM, d_mode }
314 #define EMx { OP_EM, x_mode }
315 #define EXw { OP_EX, w_mode }
316 #define EXd { OP_EX, d_mode }
317 #define EXq { OP_EX, q_mode }
318 #define EXx { OP_EX, x_mode }
319 #define MS { OP_MS, v_mode }
320 #define XS { OP_XS, v_mode }
321 #define EMCq { OP_EMC, q_mode }
322 #define MXC { OP_MXC, 0 }
323 #define OPSUF { OP_3DNowSuffix, 0 }
324 #define OPSIMD { OP_SIMD_Suffix, 0 }
325 #define XMM0 { XMM_Fixup, 0 }
327 /* Used handle "rep" prefix for string instructions. */
328 #define Xbr { REP_Fixup, eSI_reg }
329 #define Xvr { REP_Fixup, eSI_reg }
330 #define Ybr { REP_Fixup, eDI_reg }
331 #define Yvr { REP_Fixup, eDI_reg }
332 #define Yzr { REP_Fixup, eDI_reg }
333 #define indirDXr { REP_Fixup, indir_dx_reg }
334 #define ALr { REP_Fixup, al_reg }
335 #define eAXr { REP_Fixup, eAX_reg }
337 #define cond_jump_flag { NULL, cond_jump_mode }
338 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
340 /* bits in sizeflag */
341 #define SUFFIX_ALWAYS 4
345 #define b_mode 1 /* byte operand */
346 #define v_mode 2 /* operand size depends on prefixes */
347 #define w_mode 3 /* word operand */
348 #define d_mode 4 /* double word operand */
349 #define q_mode 5 /* quad word operand */
350 #define t_mode 6 /* ten-byte operand */
351 #define x_mode 7 /* 16-byte XMM operand */
352 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
353 #define cond_jump_mode 9
354 #define loop_jcxz_mode 10
355 #define dq_mode 11 /* operand size depends on REX prefixes. */
356 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
357 #define f_mode 13 /* 4- or 6-byte pointer operand */
358 #define const_1_mode 14
359 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
360 #define z_mode 16 /* non-quad operand size depends on prefixes */
361 #define o_mode 17 /* 16-byte operand */
362 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
363 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
408 #define z_mode_ax_reg 149
409 #define indir_dx_reg 150
413 #define USE_PREFIX_USER_TABLE 3
414 #define X86_64_SPECIAL 4
415 #define IS_3BYTE_OPCODE 5
416 #define USE_OPC_EXT_TABLE 6
417 #define USE_OPC_EXT_RM_TABLE 7
419 #define FLOAT NULL, { { NULL, FLOATCODE } }
421 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
422 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
423 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
424 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
425 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
426 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
427 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
428 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
429 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
430 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
431 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
432 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
433 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
434 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
435 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
436 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
437 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
438 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
439 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
440 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
441 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
442 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
443 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
444 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
445 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
446 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
447 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
448 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
450 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
451 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
452 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
453 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
454 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
455 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
456 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
457 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
458 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
459 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
460 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
461 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
462 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
463 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
464 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
465 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
466 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
467 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
468 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
469 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
470 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
471 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
472 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
473 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
474 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
475 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
476 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
477 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
478 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
479 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
480 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
481 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
482 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
483 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
484 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
485 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
486 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
487 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
488 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
489 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
490 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
491 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
492 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
493 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
494 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
495 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
496 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
497 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
498 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
499 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
500 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
501 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
502 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
503 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
504 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
505 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
506 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
507 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
508 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
509 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
510 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
511 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
512 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
513 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
514 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
515 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
516 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
517 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
518 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
519 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
520 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
521 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
522 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
523 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
524 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
525 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
526 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
527 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
528 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
529 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
530 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
531 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
532 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
533 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
534 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
535 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
536 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
537 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
538 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
539 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
540 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
541 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
542 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
543 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
544 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
545 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
546 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
547 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
548 #define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
549 #define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
550 #define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
553 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
554 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
555 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
556 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
558 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
559 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
561 #define OPC_EXT_0 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } }
562 #define OPC_EXT_1 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } }
563 #define OPC_EXT_2 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 2 } }
564 #define OPC_EXT_3 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 3 } }
565 #define OPC_EXT_4 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 4 } }
566 #define OPC_EXT_5 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 5 } }
567 #define OPC_EXT_6 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 6 } }
568 #define OPC_EXT_7 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 7 } }
569 #define OPC_EXT_8 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 8 } }
570 #define OPC_EXT_9 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 9 } }
571 #define OPC_EXT_10 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 10 } }
572 #define OPC_EXT_11 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 11 } }
573 #define OPC_EXT_12 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 12 } }
574 #define OPC_EXT_13 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 13 } }
575 #define OPC_EXT_14 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 14 } }
576 #define OPC_EXT_15 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 15 } }
577 #define OPC_EXT_16 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 16 } }
578 #define OPC_EXT_17 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 17 } }
579 #define OPC_EXT_18 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 18 } }
580 #define OPC_EXT_19 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 19 } }
581 #define OPC_EXT_20 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 20 } }
582 #define OPC_EXT_21 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 21 } }
583 #define OPC_EXT_22 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 22 } }
584 #define OPC_EXT_23 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 23 } }
585 #define OPC_EXT_24 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 24 } }
586 #define OPC_EXT_25 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 25 } }
587 #define OPC_EXT_26 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 26 } }
588 #define OPC_EXT_27 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 27 } }
589 #define OPC_EXT_28 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 28 } }
590 #define OPC_EXT_29 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 29 } }
591 #define OPC_EXT_30 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 30 } }
592 #define OPC_EXT_31 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 31 } }
593 #define OPC_EXT_32 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 32 } }
594 #define OPC_EXT_33 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 33 } }
595 #define OPC_EXT_34 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 34 } }
596 #define OPC_EXT_35 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 35 } }
597 #define OPC_EXT_36 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 36 } }
598 #define OPC_EXT_37 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 37 } }
600 #define OPC_EXT_RM_0 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } }
601 #define OPC_EXT_RM_1 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } }
602 #define OPC_EXT_RM_2 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 2 } }
603 #define OPC_EXT_RM_3 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } }
604 #define OPC_EXT_RM_4 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } }
606 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
617 /* Upper case letters in the instruction names here are macros.
618 'A' => print 'b' if no register operands or suffix_always is true
619 'B' => print 'b' if suffix_always is true
620 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
622 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
623 . suffix_always is true
624 'E' => print 'e' if 32-bit form of jcxz
625 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
626 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
627 'H' => print ",pt" or ",pn" branch hint
628 'I' => honor following macro letter even in Intel mode (implemented only
629 . for some of the macro letters)
631 'K' => print 'd' or 'q' if rex prefix is present.
632 'L' => print 'l' if suffix_always is true
633 'N' => print 'n' if instruction has no wait "prefix"
634 'O' => print 'd' or 'o' (or 'q' in Intel mode)
635 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
636 . or suffix_always is true. print 'q' if rex prefix is present.
637 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
639 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
640 'S' => print 'w', 'l' or 'q' if suffix_always is true
641 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
642 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
643 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
644 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
645 'X' => print 's', 'd' depending on data16 prefix (for XMM)
646 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
647 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
649 Many of the above letters print nothing in Intel mode. See "putop"
652 Braces '{' and '}', and vertical bars '|', indicate alternative
653 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
654 modes. In cases where there are only two alternatives, the X86_64
655 instruction is reserved, and "(bad)" is printed.
658 static const struct dis386 dis386
[] = {
660 { "addB", { Eb
, Gb
} },
661 { "addS", { Ev
, Gv
} },
662 { "addB", { Gb
, Eb
} },
663 { "addS", { Gv
, Ev
} },
664 { "addB", { AL
, Ib
} },
665 { "addS", { eAX
, Iv
} },
666 { "push{T|}", { es
} },
667 { "pop{T|}", { es
} },
669 { "orB", { Eb
, Gb
} },
670 { "orS", { Ev
, Gv
} },
671 { "orB", { Gb
, Eb
} },
672 { "orS", { Gv
, Ev
} },
673 { "orB", { AL
, Ib
} },
674 { "orS", { eAX
, Iv
} },
675 { "push{T|}", { cs
} },
676 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
678 { "adcB", { Eb
, Gb
} },
679 { "adcS", { Ev
, Gv
} },
680 { "adcB", { Gb
, Eb
} },
681 { "adcS", { Gv
, Ev
} },
682 { "adcB", { AL
, Ib
} },
683 { "adcS", { eAX
, Iv
} },
684 { "push{T|}", { ss
} },
685 { "pop{T|}", { ss
} },
687 { "sbbB", { Eb
, Gb
} },
688 { "sbbS", { Ev
, Gv
} },
689 { "sbbB", { Gb
, Eb
} },
690 { "sbbS", { Gv
, Ev
} },
691 { "sbbB", { AL
, Ib
} },
692 { "sbbS", { eAX
, Iv
} },
693 { "push{T|}", { ds
} },
694 { "pop{T|}", { ds
} },
696 { "andB", { Eb
, Gb
} },
697 { "andS", { Ev
, Gv
} },
698 { "andB", { Gb
, Eb
} },
699 { "andS", { Gv
, Ev
} },
700 { "andB", { AL
, Ib
} },
701 { "andS", { eAX
, Iv
} },
702 { "(bad)", { XX
} }, /* SEG ES prefix */
703 { "daa{|}", { XX
} },
705 { "subB", { Eb
, Gb
} },
706 { "subS", { Ev
, Gv
} },
707 { "subB", { Gb
, Eb
} },
708 { "subS", { Gv
, Ev
} },
709 { "subB", { AL
, Ib
} },
710 { "subS", { eAX
, Iv
} },
711 { "(bad)", { XX
} }, /* SEG CS prefix */
712 { "das{|}", { XX
} },
714 { "xorB", { Eb
, Gb
} },
715 { "xorS", { Ev
, Gv
} },
716 { "xorB", { Gb
, Eb
} },
717 { "xorS", { Gv
, Ev
} },
718 { "xorB", { AL
, Ib
} },
719 { "xorS", { eAX
, Iv
} },
720 { "(bad)", { XX
} }, /* SEG SS prefix */
721 { "aaa{|}", { XX
} },
723 { "cmpB", { Eb
, Gb
} },
724 { "cmpS", { Ev
, Gv
} },
725 { "cmpB", { Gb
, Eb
} },
726 { "cmpS", { Gv
, Ev
} },
727 { "cmpB", { AL
, Ib
} },
728 { "cmpS", { eAX
, Iv
} },
729 { "(bad)", { XX
} }, /* SEG DS prefix */
730 { "aas{|}", { XX
} },
732 { "inc{S|}", { RMeAX
} },
733 { "inc{S|}", { RMeCX
} },
734 { "inc{S|}", { RMeDX
} },
735 { "inc{S|}", { RMeBX
} },
736 { "inc{S|}", { RMeSP
} },
737 { "inc{S|}", { RMeBP
} },
738 { "inc{S|}", { RMeSI
} },
739 { "inc{S|}", { RMeDI
} },
741 { "dec{S|}", { RMeAX
} },
742 { "dec{S|}", { RMeCX
} },
743 { "dec{S|}", { RMeDX
} },
744 { "dec{S|}", { RMeBX
} },
745 { "dec{S|}", { RMeSP
} },
746 { "dec{S|}", { RMeBP
} },
747 { "dec{S|}", { RMeSI
} },
748 { "dec{S|}", { RMeDI
} },
750 { "pushV", { RMrAX
} },
751 { "pushV", { RMrCX
} },
752 { "pushV", { RMrDX
} },
753 { "pushV", { RMrBX
} },
754 { "pushV", { RMrSP
} },
755 { "pushV", { RMrBP
} },
756 { "pushV", { RMrSI
} },
757 { "pushV", { RMrDI
} },
759 { "popV", { RMrAX
} },
760 { "popV", { RMrCX
} },
761 { "popV", { RMrDX
} },
762 { "popV", { RMrBX
} },
763 { "popV", { RMrSP
} },
764 { "popV", { RMrBP
} },
765 { "popV", { RMrSI
} },
766 { "popV", { RMrDI
} },
772 { "(bad)", { XX
} }, /* seg fs */
773 { "(bad)", { XX
} }, /* seg gs */
774 { "(bad)", { XX
} }, /* op size prefix */
775 { "(bad)", { XX
} }, /* adr size prefix */
778 { "imulS", { Gv
, Ev
, Iv
} },
779 { "pushT", { sIb
} },
780 { "imulS", { Gv
, Ev
, sIb
} },
781 { "ins{b||b|}", { Ybr
, indirDX
} },
782 { "ins{R||G|}", { Yzr
, indirDX
} },
783 { "outs{b||b|}", { indirDXr
, Xb
} },
784 { "outs{R||G|}", { indirDXr
, Xz
} },
786 { "joH", { Jb
, XX
, cond_jump_flag
} },
787 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
788 { "jbH", { Jb
, XX
, cond_jump_flag
} },
789 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
790 { "jeH", { Jb
, XX
, cond_jump_flag
} },
791 { "jneH", { Jb
, XX
, cond_jump_flag
} },
792 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
793 { "jaH", { Jb
, XX
, cond_jump_flag
} },
795 { "jsH", { Jb
, XX
, cond_jump_flag
} },
796 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
797 { "jpH", { Jb
, XX
, cond_jump_flag
} },
798 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
799 { "jlH", { Jb
, XX
, cond_jump_flag
} },
800 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
801 { "jleH", { Jb
, XX
, cond_jump_flag
} },
802 { "jgH", { Jb
, XX
, cond_jump_flag
} },
808 { "testB", { Eb
, Gb
} },
809 { "testS", { Ev
, Gv
} },
810 { "xchgB", { Eb
, Gb
} },
811 { "xchgS", { Ev
, Gv
} },
813 { "movB", { Eb
, Gb
} },
814 { "movS", { Ev
, Gv
} },
815 { "movB", { Gb
, Eb
} },
816 { "movS", { Gv
, Ev
} },
817 { "movD", { Sv
, Sw
} },
819 { "movD", { Sw
, Sv
} },
823 { "xchgS", { RMeCX
, eAX
} },
824 { "xchgS", { RMeDX
, eAX
} },
825 { "xchgS", { RMeBX
, eAX
} },
826 { "xchgS", { RMeSP
, eAX
} },
827 { "xchgS", { RMeBP
, eAX
} },
828 { "xchgS", { RMeSI
, eAX
} },
829 { "xchgS", { RMeDI
, eAX
} },
831 { "cW{t||t|}R", { XX
} },
832 { "cR{t||t|}O", { XX
} },
833 { "Jcall{T|}", { Ap
} },
834 { "(bad)", { XX
} }, /* fwait */
835 { "pushfT", { XX
} },
837 { "sahf{|}", { XX
} },
838 { "lahf{|}", { XX
} },
840 { "movB", { AL
, Ob
} },
841 { "movS", { eAX
, Ov
} },
842 { "movB", { Ob
, AL
} },
843 { "movS", { Ov
, eAX
} },
844 { "movs{b||b|}", { Ybr
, Xb
} },
845 { "movs{R||R|}", { Yvr
, Xv
} },
846 { "cmps{b||b|}", { Xb
, Yb
} },
847 { "cmps{R||R|}", { Xv
, Yv
} },
849 { "testB", { AL
, Ib
} },
850 { "testS", { eAX
, Iv
} },
851 { "stosB", { Ybr
, AL
} },
852 { "stosS", { Yvr
, eAX
} },
853 { "lodsB", { ALr
, Xb
} },
854 { "lodsS", { eAXr
, Xv
} },
855 { "scasB", { AL
, Yb
} },
856 { "scasS", { eAX
, Yv
} },
858 { "movB", { RMAL
, Ib
} },
859 { "movB", { RMCL
, Ib
} },
860 { "movB", { RMDL
, Ib
} },
861 { "movB", { RMBL
, Ib
} },
862 { "movB", { RMAH
, Ib
} },
863 { "movB", { RMCH
, Ib
} },
864 { "movB", { RMDH
, Ib
} },
865 { "movB", { RMBH
, Ib
} },
867 { "movS", { RMeAX
, Iv64
} },
868 { "movS", { RMeCX
, Iv64
} },
869 { "movS", { RMeDX
, Iv64
} },
870 { "movS", { RMeBX
, Iv64
} },
871 { "movS", { RMeSP
, Iv64
} },
872 { "movS", { RMeBP
, Iv64
} },
873 { "movS", { RMeSI
, Iv64
} },
874 { "movS", { RMeDI
, Iv64
} },
885 { "enterT", { Iw
, Ib
} },
886 { "leaveT", { XX
} },
891 { "into{|}", { XX
} },
898 { "aam{|}", { sIb
} },
899 { "aad{|}", { sIb
} },
901 { "xlat", { DSBX
} },
912 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
913 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
914 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
915 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
916 { "inB", { AL
, Ib
} },
917 { "inG", { zAX
, Ib
} },
918 { "outB", { Ib
, AL
} },
919 { "outG", { Ib
, zAX
} },
923 { "Jjmp{T|}", { Ap
} },
925 { "inB", { AL
, indirDX
} },
926 { "inG", { zAX
, indirDX
} },
927 { "outB", { indirDX
, AL
} },
928 { "outG", { indirDX
, zAX
} },
930 { "(bad)", { XX
} }, /* lock prefix */
932 { "(bad)", { XX
} }, /* repne */
933 { "(bad)", { XX
} }, /* repz */
949 static const struct dis386 dis386_twobyte
[] = {
953 { "larS", { Gv
, Ew
} },
954 { "lslS", { Gv
, Ew
} },
956 { "syscall", { XX
} },
958 { "sysretP", { XX
} },
961 { "wbinvd", { XX
} },
967 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
973 { "unpcklpX", { XM
, EXq
} },
974 { "unpckhpX", { XM
, EXq
} },
987 { "movZ", { Rm
, Cm
} },
988 { "movZ", { Rm
, Dm
} },
989 { "movZ", { Cm
, Rm
} },
990 { "movZ", { Dm
, Rm
} },
991 { "movL", { Rd
, Td
} },
993 { "movL", { Td
, Rd
} },
996 { "movapX", { XM
, EXx
} },
997 { "movapX", { EXx
, XM
} },
1005 { "wrmsr", { XX
} },
1006 { "rdtsc", { XX
} },
1007 { "rdmsr", { XX
} },
1008 { "rdpmc", { XX
} },
1009 { "sysenter", { XX
} },
1010 { "sysexit", { XX
} },
1011 { "(bad)", { XX
} },
1012 { "(bad)", { XX
} },
1015 { "(bad)", { XX
} },
1017 { "(bad)", { XX
} },
1018 { "(bad)", { XX
} },
1019 { "(bad)", { XX
} },
1020 { "(bad)", { XX
} },
1021 { "(bad)", { XX
} },
1023 { "cmovo", { Gv
, Ev
} },
1024 { "cmovno", { Gv
, Ev
} },
1025 { "cmovb", { Gv
, Ev
} },
1026 { "cmovae", { Gv
, Ev
} },
1027 { "cmove", { Gv
, Ev
} },
1028 { "cmovne", { Gv
, Ev
} },
1029 { "cmovbe", { Gv
, Ev
} },
1030 { "cmova", { Gv
, Ev
} },
1032 { "cmovs", { Gv
, Ev
} },
1033 { "cmovns", { Gv
, Ev
} },
1034 { "cmovp", { Gv
, Ev
} },
1035 { "cmovnp", { Gv
, Ev
} },
1036 { "cmovl", { Gv
, Ev
} },
1037 { "cmovge", { Gv
, Ev
} },
1038 { "cmovle", { Gv
, Ev
} },
1039 { "cmovg", { Gv
, Ev
} },
1041 { "movmskpX", { Gdq
, XS
} },
1045 { "andpX", { XM
, EXx
} },
1046 { "andnpX", { XM
, EXx
} },
1047 { "orpX", { XM
, EXx
} },
1048 { "xorpX", { XM
, EXx
} },
1062 { "packsswb", { MX
, EM
} },
1063 { "pcmpgtb", { MX
, EM
} },
1064 { "pcmpgtw", { MX
, EM
} },
1065 { "pcmpgtd", { MX
, EM
} },
1066 { "packuswb", { MX
, EM
} },
1068 { "punpckhbw", { MX
, EM
} },
1069 { "punpckhwd", { MX
, EM
} },
1070 { "punpckhdq", { MX
, EM
} },
1071 { "packssdw", { MX
, EM
} },
1074 { "movK", { MX
, Edq
} },
1081 { "pcmpeqb", { MX
, EM
} },
1082 { "pcmpeqw", { MX
, EM
} },
1083 { "pcmpeqd", { MX
, EM
} },
1088 { "(bad)", { XX
} },
1089 { "(bad)", { XX
} },
1095 { "joH", { Jv
, XX
, cond_jump_flag
} },
1096 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1097 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1098 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1099 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1100 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1101 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1102 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1104 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1105 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1106 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1107 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1108 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1109 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1110 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1111 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1114 { "setno", { Eb
} },
1116 { "setae", { Eb
} },
1118 { "setne", { Eb
} },
1119 { "setbe", { Eb
} },
1123 { "setns", { Eb
} },
1125 { "setnp", { Eb
} },
1127 { "setge", { Eb
} },
1128 { "setle", { Eb
} },
1131 { "pushT", { fs
} },
1133 { "cpuid", { XX
} },
1134 { "btS", { Ev
, Gv
} },
1135 { "shldS", { Ev
, Gv
, Ib
} },
1136 { "shldS", { Ev
, Gv
, CL
} },
1140 { "pushT", { gs
} },
1143 { "btsS", { Ev
, Gv
} },
1144 { "shrdS", { Ev
, Gv
, Ib
} },
1145 { "shrdS", { Ev
, Gv
, CL
} },
1147 { "imulS", { Gv
, Ev
} },
1149 { "cmpxchgB", { Eb
, Gb
} },
1150 { "cmpxchgS", { Ev
, Gv
} },
1152 { "btrS", { Ev
, Gv
} },
1155 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1156 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1161 { "btcS", { Ev
, Gv
} },
1162 { "bsfS", { Gv
, Ev
} },
1164 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1165 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1167 { "xaddB", { Eb
, Gb
} },
1168 { "xaddS", { Ev
, Gv
} },
1170 { "movntiS", { Ev
, Gv
} },
1171 { "pinsrw", { MX
, Edqw
, Ib
} },
1172 { "pextrw", { Gdq
, MS
, Ib
} },
1173 { "shufpX", { XM
, EXx
, Ib
} },
1176 { "bswap", { RMeAX
} },
1177 { "bswap", { RMeCX
} },
1178 { "bswap", { RMeDX
} },
1179 { "bswap", { RMeBX
} },
1180 { "bswap", { RMeSP
} },
1181 { "bswap", { RMeBP
} },
1182 { "bswap", { RMeSI
} },
1183 { "bswap", { RMeDI
} },
1186 { "psrlw", { MX
, EM
} },
1187 { "psrld", { MX
, EM
} },
1188 { "psrlq", { MX
, EM
} },
1189 { "paddq", { MX
, EM
} },
1190 { "pmullw", { MX
, EM
} },
1192 { "pmovmskb", { Gdq
, MS
} },
1194 { "psubusb", { MX
, EM
} },
1195 { "psubusw", { MX
, EM
} },
1196 { "pminub", { MX
, EM
} },
1197 { "pand", { MX
, EM
} },
1198 { "paddusb", { MX
, EM
} },
1199 { "paddusw", { MX
, EM
} },
1200 { "pmaxub", { MX
, EM
} },
1201 { "pandn", { MX
, EM
} },
1203 { "pavgb", { MX
, EM
} },
1204 { "psraw", { MX
, EM
} },
1205 { "psrad", { MX
, EM
} },
1206 { "pavgw", { MX
, EM
} },
1207 { "pmulhuw", { MX
, EM
} },
1208 { "pmulhw", { MX
, EM
} },
1212 { "psubsb", { MX
, EM
} },
1213 { "psubsw", { MX
, EM
} },
1214 { "pminsw", { MX
, EM
} },
1215 { "por", { MX
, EM
} },
1216 { "paddsb", { MX
, EM
} },
1217 { "paddsw", { MX
, EM
} },
1218 { "pmaxsw", { MX
, EM
} },
1219 { "pxor", { MX
, EM
} },
1222 { "psllw", { MX
, EM
} },
1223 { "pslld", { MX
, EM
} },
1224 { "psllq", { MX
, EM
} },
1225 { "pmuludq", { MX
, EM
} },
1226 { "pmaddwd", { MX
, EM
} },
1227 { "psadbw", { MX
, EM
} },
1230 { "psubb", { MX
, EM
} },
1231 { "psubw", { MX
, EM
} },
1232 { "psubd", { MX
, EM
} },
1233 { "psubq", { MX
, EM
} },
1234 { "paddb", { MX
, EM
} },
1235 { "paddw", { MX
, EM
} },
1236 { "paddd", { MX
, EM
} },
1237 { "(bad)", { XX
} },
1240 static const unsigned char onebyte_has_modrm
[256] = {
1241 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1242 /* ------------------------------- */
1243 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1244 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1245 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1246 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1247 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1248 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1249 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1250 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1251 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1252 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1253 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1254 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1255 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1256 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1257 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1258 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1259 /* ------------------------------- */
1260 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1263 static const unsigned char twobyte_has_modrm
[256] = {
1264 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1265 /* ------------------------------- */
1266 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1267 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1268 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1269 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1270 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1271 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1272 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1273 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1274 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1275 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1276 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1277 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1278 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1279 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1280 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1281 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1282 /* ------------------------------- */
1283 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1286 static char obuf
[100];
1288 static char scratchbuf
[100];
1289 static unsigned char *start_codep
;
1290 static unsigned char *insn_codep
;
1291 static unsigned char *codep
;
1292 static const char *lock_prefix
;
1293 static const char *data_prefix
;
1294 static const char *addr_prefix
;
1295 static const char *repz_prefix
;
1296 static const char *repnz_prefix
;
1297 static disassemble_info
*the_info
;
1305 static unsigned char need_modrm
;
1307 /* If we are accessing mod/rm/reg without need_modrm set, then the
1308 values are stale. Hitting this abort likely indicates that you
1309 need to update onebyte_has_modrm or twobyte_has_modrm. */
1310 #define MODRM_CHECK if (!need_modrm) abort ()
1312 static const char **names64
;
1313 static const char **names32
;
1314 static const char **names16
;
1315 static const char **names8
;
1316 static const char **names8rex
;
1317 static const char **names_seg
;
1318 static const char **index16
;
1320 static const char *intel_names64
[] = {
1321 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1322 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1324 static const char *intel_names32
[] = {
1325 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1326 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1328 static const char *intel_names16
[] = {
1329 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1330 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1332 static const char *intel_names8
[] = {
1333 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1335 static const char *intel_names8rex
[] = {
1336 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1337 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1339 static const char *intel_names_seg
[] = {
1340 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1342 static const char *intel_index16
[] = {
1343 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1346 static const char *att_names64
[] = {
1347 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1348 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1350 static const char *att_names32
[] = {
1351 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1352 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1354 static const char *att_names16
[] = {
1355 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1356 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1358 static const char *att_names8
[] = {
1359 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1361 static const char *att_names8rex
[] = {
1362 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1363 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1365 static const char *att_names_seg
[] = {
1366 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1368 static const char *att_index16
[] = {
1369 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1372 static const struct dis386 grps
[][8] = {
1375 { "popU", { stackEv
} },
1376 { "(bad)", { XX
} },
1377 { "(bad)", { XX
} },
1378 { "(bad)", { XX
} },
1379 { "(bad)", { XX
} },
1380 { "(bad)", { XX
} },
1381 { "(bad)", { XX
} },
1382 { "(bad)", { XX
} },
1386 { "addA", { Eb
, Ib
} },
1387 { "orA", { Eb
, Ib
} },
1388 { "adcA", { Eb
, Ib
} },
1389 { "sbbA", { Eb
, Ib
} },
1390 { "andA", { Eb
, Ib
} },
1391 { "subA", { Eb
, Ib
} },
1392 { "xorA", { Eb
, Ib
} },
1393 { "cmpA", { Eb
, Ib
} },
1397 { "addQ", { Ev
, Iv
} },
1398 { "orQ", { Ev
, Iv
} },
1399 { "adcQ", { Ev
, Iv
} },
1400 { "sbbQ", { Ev
, Iv
} },
1401 { "andQ", { Ev
, Iv
} },
1402 { "subQ", { Ev
, Iv
} },
1403 { "xorQ", { Ev
, Iv
} },
1404 { "cmpQ", { Ev
, Iv
} },
1408 { "addQ", { Ev
, sIb
} },
1409 { "orQ", { Ev
, sIb
} },
1410 { "adcQ", { Ev
, sIb
} },
1411 { "sbbQ", { Ev
, sIb
} },
1412 { "andQ", { Ev
, sIb
} },
1413 { "subQ", { Ev
, sIb
} },
1414 { "xorQ", { Ev
, sIb
} },
1415 { "cmpQ", { Ev
, sIb
} },
1419 { "rolA", { Eb
, Ib
} },
1420 { "rorA", { Eb
, Ib
} },
1421 { "rclA", { Eb
, Ib
} },
1422 { "rcrA", { Eb
, Ib
} },
1423 { "shlA", { Eb
, Ib
} },
1424 { "shrA", { Eb
, Ib
} },
1425 { "(bad)", { XX
} },
1426 { "sarA", { Eb
, Ib
} },
1430 { "rolQ", { Ev
, Ib
} },
1431 { "rorQ", { Ev
, Ib
} },
1432 { "rclQ", { Ev
, Ib
} },
1433 { "rcrQ", { Ev
, Ib
} },
1434 { "shlQ", { Ev
, Ib
} },
1435 { "shrQ", { Ev
, Ib
} },
1436 { "(bad)", { XX
} },
1437 { "sarQ", { Ev
, Ib
} },
1441 { "rolA", { Eb
, I1
} },
1442 { "rorA", { Eb
, I1
} },
1443 { "rclA", { Eb
, I1
} },
1444 { "rcrA", { Eb
, I1
} },
1445 { "shlA", { Eb
, I1
} },
1446 { "shrA", { Eb
, I1
} },
1447 { "(bad)", { XX
} },
1448 { "sarA", { Eb
, I1
} },
1452 { "rolQ", { Ev
, I1
} },
1453 { "rorQ", { Ev
, I1
} },
1454 { "rclQ", { Ev
, I1
} },
1455 { "rcrQ", { Ev
, I1
} },
1456 { "shlQ", { Ev
, I1
} },
1457 { "shrQ", { Ev
, I1
} },
1458 { "(bad)", { XX
} },
1459 { "sarQ", { Ev
, I1
} },
1463 { "rolA", { Eb
, CL
} },
1464 { "rorA", { Eb
, CL
} },
1465 { "rclA", { Eb
, CL
} },
1466 { "rcrA", { Eb
, CL
} },
1467 { "shlA", { Eb
, CL
} },
1468 { "shrA", { Eb
, CL
} },
1469 { "(bad)", { XX
} },
1470 { "sarA", { Eb
, CL
} },
1474 { "rolQ", { Ev
, CL
} },
1475 { "rorQ", { Ev
, CL
} },
1476 { "rclQ", { Ev
, CL
} },
1477 { "rcrQ", { Ev
, CL
} },
1478 { "shlQ", { Ev
, CL
} },
1479 { "shrQ", { Ev
, CL
} },
1480 { "(bad)", { XX
} },
1481 { "sarQ", { Ev
, CL
} },
1485 { "testA", { Eb
, Ib
} },
1486 { "(bad)", { Eb
} },
1489 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1490 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1491 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1492 { "idivA", { Eb
} }, /* and idiv for consistency. */
1496 { "testQ", { Ev
, Iv
} },
1497 { "(bad)", { XX
} },
1500 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1501 { "imulQ", { Ev
} },
1503 { "idivQ", { Ev
} },
1509 { "(bad)", { XX
} },
1510 { "(bad)", { XX
} },
1511 { "(bad)", { XX
} },
1512 { "(bad)", { XX
} },
1513 { "(bad)", { XX
} },
1514 { "(bad)", { XX
} },
1520 { "callT", { indirEv
} },
1521 { "JcallT", { indirEp
} },
1522 { "jmpT", { indirEv
} },
1523 { "JjmpT", { indirEp
} },
1524 { "pushU", { stackEv
} },
1525 { "(bad)", { XX
} },
1529 { "sldtD", { Sv
} },
1535 { "(bad)", { XX
} },
1536 { "(bad)", { XX
} },
1543 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1544 { "smswD", { Sv
} },
1545 { "(bad)", { XX
} },
1547 { "invlpg", { { INVLPG_Fixup
, 0 } } },
1551 { "(bad)", { XX
} },
1552 { "(bad)", { XX
} },
1553 { "(bad)", { XX
} },
1554 { "(bad)", { XX
} },
1555 { "btQ", { Ev
, Ib
} },
1556 { "btsQ", { Ev
, Ib
} },
1557 { "btrQ", { Ev
, Ib
} },
1558 { "btcQ", { Ev
, Ib
} },
1562 { "(bad)", { XX
} },
1563 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1564 { "(bad)", { XX
} },
1565 { "(bad)", { XX
} },
1566 { "(bad)", { XX
} },
1567 { "(bad)", { XX
} },
1573 { "movA", { Eb
, Ib
} },
1574 { "(bad)", { XX
} },
1575 { "(bad)", { XX
} },
1576 { "(bad)", { XX
} },
1577 { "(bad)", { XX
} },
1578 { "(bad)", { XX
} },
1579 { "(bad)", { XX
} },
1580 { "(bad)", { XX
} },
1584 { "movQ", { Ev
, Iv
} },
1585 { "(bad)", { XX
} },
1586 { "(bad)", { XX
} },
1587 { "(bad)", { XX
} },
1588 { "(bad)", { XX
} },
1589 { "(bad)", { XX
} },
1590 { "(bad)", { XX
} },
1591 { "(bad)", { XX
} },
1595 { "(bad)", { XX
} },
1596 { "(bad)", { XX
} },
1598 { "(bad)", { XX
} },
1600 { "(bad)", { XX
} },
1602 { "(bad)", { XX
} },
1606 { "(bad)", { XX
} },
1607 { "(bad)", { XX
} },
1609 { "(bad)", { XX
} },
1611 { "(bad)", { XX
} },
1613 { "(bad)", { XX
} },
1617 { "(bad)", { XX
} },
1618 { "(bad)", { XX
} },
1621 { "(bad)", { XX
} },
1622 { "(bad)", { XX
} },
1632 { "(bad)", { XX
} },
1643 { "(bad)", { XX
} },
1644 { "(bad)", { XX
} },
1645 { "(bad)", { XX
} },
1646 { "(bad)", { XX
} },
1650 { "prefetch", { Eb
} },
1651 { "prefetchw", { Eb
} },
1652 { "(bad)", { XX
} },
1653 { "(bad)", { XX
} },
1654 { "(bad)", { XX
} },
1655 { "(bad)", { XX
} },
1656 { "(bad)", { XX
} },
1657 { "(bad)", { XX
} },
1661 { "xstore-rng", { { OP_0f07
, 0 } } },
1662 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1663 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1664 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1665 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1666 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1667 { "(bad)", { { OP_0f07
, 0 } } },
1668 { "(bad)", { { OP_0f07
, 0 } } },
1672 { "montmul", { { OP_0f07
, 0 } } },
1673 { "xsha1", { { OP_0f07
, 0 } } },
1674 { "xsha256", { { OP_0f07
, 0 } } },
1675 { "(bad)", { { OP_0f07
, 0 } } },
1676 { "(bad)", { { OP_0f07
, 0 } } },
1677 { "(bad)", { { OP_0f07
, 0 } } },
1678 { "(bad)", { { OP_0f07
, 0 } } },
1679 { "(bad)", { { OP_0f07
, 0 } } },
1683 static const struct dis386 prefix_user_table
[][4] = {
1686 { "addps", { XM
, EXx
} },
1687 { "addss", { XM
, EXd
} },
1688 { "addpd", { XM
, EXx
} },
1689 { "addsd", { XM
, EXq
} },
1693 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1694 { "", { XM
, EXd
, OPSIMD
} },
1695 { "", { XM
, EXx
, OPSIMD
} },
1696 { "", { XM
, EXq
, OPSIMD
} },
1700 { "cvtpi2ps", { XM
, EMCq
} },
1701 { "cvtsi2ssY", { XM
, Ev
} },
1702 { "cvtpi2pd", { XM
, EMCq
} },
1703 { "cvtsi2sdY", { XM
, Ev
} },
1707 { "cvtps2pi", { MXC
, EXq
} },
1708 { "cvtss2siY", { Gv
, EXd
} },
1709 { "cvtpd2pi", { MXC
, EXx
} },
1710 { "cvtsd2siY", { Gv
, EXq
} },
1714 { "cvttps2pi", { MXC
, EXq
} },
1715 { "cvttss2siY", { Gv
, EXd
} },
1716 { "cvttpd2pi", { MXC
, EXx
} },
1717 { "cvttsd2siY", { Gv
, EXq
} },
1721 { "divps", { XM
, EXx
} },
1722 { "divss", { XM
, EXd
} },
1723 { "divpd", { XM
, EXx
} },
1724 { "divsd", { XM
, EXq
} },
1728 { "maxps", { XM
, EXx
} },
1729 { "maxss", { XM
, EXd
} },
1730 { "maxpd", { XM
, EXx
} },
1731 { "maxsd", { XM
, EXq
} },
1735 { "minps", { XM
, EXx
} },
1736 { "minss", { XM
, EXd
} },
1737 { "minpd", { XM
, EXx
} },
1738 { "minsd", { XM
, EXq
} },
1742 { "movups", { XM
, EXx
} },
1743 { "movss", { XM
, EXd
} },
1744 { "movupd", { XM
, EXx
} },
1745 { "movsd", { XM
, EXq
} },
1749 { "movups", { EXx
, XM
} },
1750 { "movss", { EXd
, XM
} },
1751 { "movupd", { EXx
, XM
} },
1752 { "movsd", { EXq
, XM
} },
1756 { "mulps", { XM
, EXx
} },
1757 { "mulss", { XM
, EXd
} },
1758 { "mulpd", { XM
, EXx
} },
1759 { "mulsd", { XM
, EXq
} },
1763 { "rcpps", { XM
, EXx
} },
1764 { "rcpss", { XM
, EXd
} },
1765 { "(bad)", { XM
, EXx
} },
1766 { "(bad)", { XM
, EXx
} },
1770 { "rsqrtps",{ XM
, EXx
} },
1771 { "rsqrtss",{ XM
, EXd
} },
1772 { "(bad)", { XM
, EXx
} },
1773 { "(bad)", { XM
, EXx
} },
1777 { "sqrtps", { XM
, EXx
} },
1778 { "sqrtss", { XM
, EXd
} },
1779 { "sqrtpd", { XM
, EXx
} },
1780 { "sqrtsd", { XM
, EXq
} },
1784 { "subps", { XM
, EXx
} },
1785 { "subss", { XM
, EXd
} },
1786 { "subpd", { XM
, EXx
} },
1787 { "subsd", { XM
, EXq
} },
1791 { "(bad)", { XM
, EXx
} },
1792 { "cvtdq2pd", { XM
, EXq
} },
1793 { "cvttpd2dq", { XM
, EXx
} },
1794 { "cvtpd2dq", { XM
, EXx
} },
1798 { "cvtdq2ps", { XM
, EXx
} },
1799 { "cvttps2dq", { XM
, EXx
} },
1800 { "cvtps2dq", { XM
, EXx
} },
1801 { "(bad)", { XM
, EXx
} },
1805 { "cvtps2pd", { XM
, EXq
} },
1806 { "cvtss2sd", { XM
, EXd
} },
1807 { "cvtpd2ps", { XM
, EXx
} },
1808 { "cvtsd2ss", { XM
, EXq
} },
1812 { "maskmovq", { MX
, MS
} },
1813 { "(bad)", { XM
, EXx
} },
1814 { "maskmovdqu", { XM
, XS
} },
1815 { "(bad)", { XM
, EXx
} },
1819 { "movq", { MX
, EM
} },
1820 { "movdqu", { XM
, EXx
} },
1821 { "movdqa", { XM
, EXx
} },
1822 { "(bad)", { XM
, EXx
} },
1826 { "movq", { EM
, MX
} },
1827 { "movdqu", { EXx
, XM
} },
1828 { "movdqa", { EXx
, XM
} },
1829 { "(bad)", { EXx
, XM
} },
1833 { "(bad)", { EXx
, XM
} },
1834 { "movq2dq",{ XM
, MS
} },
1835 { "movq", { EXq
, XM
} },
1836 { "movdq2q",{ MX
, XS
} },
1840 { "pshufw", { MX
, EM
, Ib
} },
1841 { "pshufhw",{ XM
, EXx
, Ib
} },
1842 { "pshufd", { XM
, EXx
, Ib
} },
1843 { "pshuflw",{ XM
, EXx
, Ib
} },
1847 { "movK", { Edq
, MX
} },
1848 { "movq", { XM
, EXq
} },
1849 { "movK", { Edq
, XM
} },
1850 { "(bad)", { Ed
, XM
} },
1854 { "(bad)", { MX
, EXx
} },
1855 { "(bad)", { XM
, EXx
} },
1856 { "punpckhqdq", { XM
, EXx
} },
1857 { "(bad)", { XM
, EXx
} },
1861 { "movntq", { EM
, MX
} },
1862 { "(bad)", { EM
, XM
} },
1863 { "movntdq",{ EM
, XM
} },
1864 { "(bad)", { EM
, XM
} },
1868 { "(bad)", { MX
, EXx
} },
1869 { "(bad)", { XM
, EXx
} },
1870 { "punpcklqdq", { XM
, EXx
} },
1871 { "(bad)", { XM
, EXx
} },
1875 { "(bad)", { MX
, EXx
} },
1876 { "(bad)", { XM
, EXx
} },
1877 { "addsubpd", { XM
, EXx
} },
1878 { "addsubps", { XM
, EXx
} },
1882 { "(bad)", { MX
, EXx
} },
1883 { "(bad)", { XM
, EXx
} },
1884 { "haddpd", { XM
, EXx
} },
1885 { "haddps", { XM
, EXx
} },
1889 { "(bad)", { MX
, EXx
} },
1890 { "(bad)", { XM
, EXx
} },
1891 { "hsubpd", { XM
, EXx
} },
1892 { "hsubps", { XM
, EXx
} },
1897 { "movsldup", { XM
, EXx
} },
1898 { "movlpd", { XM
, EXq
} },
1899 { "movddup", { XM
, EXq
} },
1904 { "movshdup", { XM
, EXx
} },
1905 { "movhpd", { XM
, EXq
} },
1906 { "(bad)", { XM
, EXq
} },
1910 { "(bad)", { XM
, EXx
} },
1911 { "(bad)", { XM
, EXx
} },
1912 { "(bad)", { XM
, EXx
} },
1917 {"movntps", { Ev
, XM
} },
1918 {"movntss", { Ed
, XM
} },
1919 {"movntpd", { Ev
, XM
} },
1920 {"movntsd", { Eq
, XM
} },
1925 {"vmread", { Em
, Gm
} },
1927 {"extrq", { XS
, Ib
, Ib
} },
1928 {"insertq", { XM
, XS
, Ib
, Ib
} },
1933 {"vmwrite", { Gm
, Em
} },
1935 {"extrq", { XM
, XS
} },
1936 {"insertq", { XM
, XS
} },
1941 { "bsrS", { Gv
, Ev
} },
1942 { "lzcntS", { Gv
, Ev
} },
1943 { "bsrS", { Gv
, Ev
} },
1944 { "(bad)", { XX
} },
1949 { "(bad)", { XX
} },
1950 { "popcntS", { Gv
, Ev
} },
1951 { "(bad)", { XX
} },
1952 { "(bad)", { XX
} },
1957 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
1958 { "pause", { XX
} },
1959 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
1960 { "(bad)", { XX
} },
1965 { "(bad)", { XX
} },
1966 { "(bad)", { XX
} },
1967 { "pblendvb", {XM
, EXx
, XMM0
} },
1968 { "(bad)", { XX
} },
1973 { "(bad)", { XX
} },
1974 { "(bad)", { XX
} },
1975 { "blendvps", {XM
, EXx
, XMM0
} },
1976 { "(bad)", { XX
} },
1981 { "(bad)", { XX
} },
1982 { "(bad)", { XX
} },
1983 { "blendvpd", { XM
, EXx
, XMM0
} },
1984 { "(bad)", { XX
} },
1989 { "(bad)", { XX
} },
1990 { "(bad)", { XX
} },
1991 { "ptest", { XM
, EXx
} },
1992 { "(bad)", { XX
} },
1997 { "(bad)", { XX
} },
1998 { "(bad)", { XX
} },
1999 { "pmovsxbw", { XM
, EXq
} },
2000 { "(bad)", { XX
} },
2005 { "(bad)", { XX
} },
2006 { "(bad)", { XX
} },
2007 { "pmovsxbd", { XM
, EXd
} },
2008 { "(bad)", { XX
} },
2013 { "(bad)", { XX
} },
2014 { "(bad)", { XX
} },
2015 { "pmovsxbq", { XM
, EXw
} },
2016 { "(bad)", { XX
} },
2021 { "(bad)", { XX
} },
2022 { "(bad)", { XX
} },
2023 { "pmovsxwd", { XM
, EXq
} },
2024 { "(bad)", { XX
} },
2029 { "(bad)", { XX
} },
2030 { "(bad)", { XX
} },
2031 { "pmovsxwq", { XM
, EXd
} },
2032 { "(bad)", { XX
} },
2037 { "(bad)", { XX
} },
2038 { "(bad)", { XX
} },
2039 { "pmovsxdq", { XM
, EXq
} },
2040 { "(bad)", { XX
} },
2045 { "(bad)", { XX
} },
2046 { "(bad)", { XX
} },
2047 { "pmuldq", { XM
, EXx
} },
2048 { "(bad)", { XX
} },
2053 { "(bad)", { XX
} },
2054 { "(bad)", { XX
} },
2055 { "pcmpeqq", { XM
, EXx
} },
2056 { "(bad)", { XX
} },
2061 { "(bad)", { XX
} },
2062 { "(bad)", { XX
} },
2063 { "movntdqa", { XM
, EM
} },
2064 { "(bad)", { XX
} },
2069 { "(bad)", { XX
} },
2070 { "(bad)", { XX
} },
2071 { "packusdw", { XM
, EXx
} },
2072 { "(bad)", { XX
} },
2077 { "(bad)", { XX
} },
2078 { "(bad)", { XX
} },
2079 { "pmovzxbw", { XM
, EXq
} },
2080 { "(bad)", { XX
} },
2085 { "(bad)", { XX
} },
2086 { "(bad)", { XX
} },
2087 { "pmovzxbd", { XM
, EXd
} },
2088 { "(bad)", { XX
} },
2093 { "(bad)", { XX
} },
2094 { "(bad)", { XX
} },
2095 { "pmovzxbq", { XM
, EXw
} },
2096 { "(bad)", { XX
} },
2101 { "(bad)", { XX
} },
2102 { "(bad)", { XX
} },
2103 { "pmovzxwd", { XM
, EXq
} },
2104 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2111 { "pmovzxwq", { XM
, EXd
} },
2112 { "(bad)", { XX
} },
2117 { "(bad)", { XX
} },
2118 { "(bad)", { XX
} },
2119 { "pmovzxdq", { XM
, EXq
} },
2120 { "(bad)", { XX
} },
2125 { "(bad)", { XX
} },
2126 { "(bad)", { XX
} },
2127 { "pminsb", { XM
, EXx
} },
2128 { "(bad)", { XX
} },
2133 { "(bad)", { XX
} },
2134 { "(bad)", { XX
} },
2135 { "pminsd", { XM
, EXx
} },
2136 { "(bad)", { XX
} },
2141 { "(bad)", { XX
} },
2142 { "(bad)", { XX
} },
2143 { "pminuw", { XM
, EXx
} },
2144 { "(bad)", { XX
} },
2149 { "(bad)", { XX
} },
2150 { "(bad)", { XX
} },
2151 { "pminud", { XM
, EXx
} },
2152 { "(bad)", { XX
} },
2157 { "(bad)", { XX
} },
2158 { "(bad)", { XX
} },
2159 { "pmaxsb", { XM
, EXx
} },
2160 { "(bad)", { XX
} },
2165 { "(bad)", { XX
} },
2166 { "(bad)", { XX
} },
2167 { "pmaxsd", { XM
, EXx
} },
2168 { "(bad)", { XX
} },
2173 { "(bad)", { XX
} },
2174 { "(bad)", { XX
} },
2175 { "pmaxuw", { XM
, EXx
} },
2176 { "(bad)", { XX
} },
2181 { "(bad)", { XX
} },
2182 { "(bad)", { XX
} },
2183 { "pmaxud", { XM
, EXx
} },
2184 { "(bad)", { XX
} },
2189 { "(bad)", { XX
} },
2190 { "(bad)", { XX
} },
2191 { "pmulld", { XM
, EXx
} },
2192 { "(bad)", { XX
} },
2197 { "(bad)", { XX
} },
2198 { "(bad)", { XX
} },
2199 { "phminposuw", { XM
, EXx
} },
2200 { "(bad)", { XX
} },
2205 { "(bad)", { XX
} },
2206 { "(bad)", { XX
} },
2207 { "roundps", { XM
, EXx
, Ib
} },
2208 { "(bad)", { XX
} },
2213 { "(bad)", { XX
} },
2214 { "(bad)", { XX
} },
2215 { "roundpd", { XM
, EXx
, Ib
} },
2216 { "(bad)", { XX
} },
2221 { "(bad)", { XX
} },
2222 { "(bad)", { XX
} },
2223 { "roundss", { XM
, EXd
, Ib
} },
2224 { "(bad)", { XX
} },
2229 { "(bad)", { XX
} },
2230 { "(bad)", { XX
} },
2231 { "roundsd", { XM
, EXq
, Ib
} },
2232 { "(bad)", { XX
} },
2237 { "(bad)", { XX
} },
2238 { "(bad)", { XX
} },
2239 { "blendps", { XM
, EXx
, Ib
} },
2240 { "(bad)", { XX
} },
2245 { "(bad)", { XX
} },
2246 { "(bad)", { XX
} },
2247 { "blendpd", { XM
, EXx
, Ib
} },
2248 { "(bad)", { XX
} },
2253 { "(bad)", { XX
} },
2254 { "(bad)", { XX
} },
2255 { "pblendw", { XM
, EXx
, Ib
} },
2256 { "(bad)", { XX
} },
2261 { "(bad)", { XX
} },
2262 { "(bad)", { XX
} },
2263 { "pextrb", { Edqb
, XM
, Ib
} },
2264 { "(bad)", { XX
} },
2269 { "(bad)", { XX
} },
2270 { "(bad)", { XX
} },
2271 { "pextrw", { Edqw
, XM
, Ib
} },
2272 { "(bad)", { XX
} },
2277 { "(bad)", { XX
} },
2278 { "(bad)", { XX
} },
2279 { "pextrK", { Edq
, XM
, Ib
} },
2280 { "(bad)", { XX
} },
2285 { "(bad)", { XX
} },
2286 { "(bad)", { XX
} },
2287 { "extractps", { Edqd
, XM
, Ib
} },
2288 { "(bad)", { XX
} },
2293 { "(bad)", { XX
} },
2294 { "(bad)", { XX
} },
2295 { "pinsrb", { XM
, Edqb
, Ib
} },
2296 { "(bad)", { XX
} },
2301 { "(bad)", { XX
} },
2302 { "(bad)", { XX
} },
2303 { "insertps", { XM
, EXd
, Ib
} },
2304 { "(bad)", { XX
} },
2309 { "(bad)", { XX
} },
2310 { "(bad)", { XX
} },
2311 { "pinsrK", { XM
, Edq
, Ib
} },
2312 { "(bad)", { XX
} },
2317 { "(bad)", { XX
} },
2318 { "(bad)", { XX
} },
2319 { "dpps", { XM
, EXx
, Ib
} },
2320 { "(bad)", { XX
} },
2325 { "(bad)", { XX
} },
2326 { "(bad)", { XX
} },
2327 { "dppd", { XM
, EXx
, Ib
} },
2328 { "(bad)", { XX
} },
2333 { "(bad)", { XX
} },
2334 { "(bad)", { XX
} },
2335 { "mpsadbw", { XM
, EXx
, Ib
} },
2336 { "(bad)", { XX
} },
2341 { "(bad)", { XX
} },
2342 { "(bad)", { XX
} },
2343 { "pcmpgtq", { XM
, EXx
} },
2344 { "(bad)", { XX
} },
2349 { "(bad)", { XX
} },
2350 { "(bad)", { XX
} },
2351 { "(bad)", { XX
} },
2352 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2357 { "(bad)", { XX
} },
2358 { "(bad)", { XX
} },
2359 { "(bad)", { XX
} },
2360 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2365 { "(bad)", { XX
} },
2366 { "(bad)", { XX
} },
2367 { "pcmpestrm", { XM
, EXx
, Ib
} },
2368 { "(bad)", { XX
} },
2373 { "(bad)", { XX
} },
2374 { "(bad)", { XX
} },
2375 { "pcmpestri", { XM
, EXx
, Ib
} },
2376 { "(bad)", { XX
} },
2381 { "(bad)", { XX
} },
2382 { "(bad)", { XX
} },
2383 { "pcmpistrm", { XM
, EXx
, Ib
} },
2384 { "(bad)", { XX
} },
2389 { "(bad)", { XX
} },
2390 { "(bad)", { XX
} },
2391 { "pcmpistri", { XM
, EXx
, Ib
} },
2392 { "(bad)", { XX
} },
2397 { "ucomiss",{ XM
, EXd
} },
2398 { "(bad)", { XX
} },
2399 { "ucomisd",{ XM
, EXq
} },
2400 { "(bad)", { XX
} },
2405 { "comiss", { XM
, EXd
} },
2406 { "(bad)", { XX
} },
2407 { "comisd", { XM
, EXq
} },
2408 { "(bad)", { XX
} },
2413 { "punpcklbw",{ MX
, EMd
} },
2414 { "(bad)", { XX
} },
2415 { "punpcklbw",{ MX
, EMx
} },
2416 { "(bad)", { XX
} },
2421 { "punpcklwd",{ MX
, EMd
} },
2422 { "(bad)", { XX
} },
2423 { "punpcklwd",{ MX
, EMx
} },
2424 { "(bad)", { XX
} },
2429 { "punpckldq",{ MX
, EMd
} },
2430 { "(bad)", { XX
} },
2431 { "punpckldq",{ MX
, EMx
} },
2432 { "(bad)", { XX
} },
2437 { "vmptrld",{ Mq
} },
2438 { "vmxon", { Mq
} },
2439 { "vmclear",{ Mq
} },
2440 { "(bad)", { XX
} },
2445 { "(bad)", { XX
} },
2446 { "(bad)", { XX
} },
2447 { "psrldq", { MS
, Ib
} },
2448 { "(bad)", { XX
} },
2453 { "(bad)", { XX
} },
2454 { "(bad)", { XX
} },
2455 { "pslldq", { MS
, Ib
} },
2456 { "(bad)", { XX
} },
2460 static const struct dis386 x86_64_table
[][2] = {
2462 { "pusha{P|}", { XX
} },
2463 { "(bad)", { XX
} },
2466 { "popa{P|}", { XX
} },
2467 { "(bad)", { XX
} },
2471 { "(bad)", { XX
} },
2474 { "arpl", { Ew
, Gw
} },
2475 { "movs{||lq|xd}", { Gv
, Ed
} },
2479 static const struct dis386 three_byte_table
[][256] = {
2483 { "pshufb", { MX
, EM
} },
2484 { "phaddw", { MX
, EM
} },
2485 { "phaddd", { MX
, EM
} },
2486 { "phaddsw", { MX
, EM
} },
2487 { "pmaddubsw", { MX
, EM
} },
2488 { "phsubw", { MX
, EM
} },
2489 { "phsubd", { MX
, EM
} },
2490 { "phsubsw", { MX
, EM
} },
2492 { "psignb", { MX
, EM
} },
2493 { "psignw", { MX
, EM
} },
2494 { "psignd", { MX
, EM
} },
2495 { "pmulhrsw", { MX
, EM
} },
2496 { "(bad)", { XX
} },
2497 { "(bad)", { XX
} },
2498 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2502 { "(bad)", { XX
} },
2503 { "(bad)", { XX
} },
2504 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2510 { "(bad)", { XX
} },
2511 { "(bad)", { XX
} },
2512 { "(bad)", { XX
} },
2513 { "(bad)", { XX
} },
2514 { "pabsb", { MX
, EM
} },
2515 { "pabsw", { MX
, EM
} },
2516 { "pabsd", { MX
, EM
} },
2517 { "(bad)", { XX
} },
2525 { "(bad)", { XX
} },
2526 { "(bad)", { XX
} },
2532 { "(bad)", { XX
} },
2533 { "(bad)", { XX
} },
2534 { "(bad)", { XX
} },
2535 { "(bad)", { XX
} },
2543 { "(bad)", { XX
} },
2557 { "(bad)", { XX
} },
2558 { "(bad)", { XX
} },
2559 { "(bad)", { XX
} },
2560 { "(bad)", { XX
} },
2561 { "(bad)", { XX
} },
2562 { "(bad)", { XX
} },
2564 { "(bad)", { XX
} },
2565 { "(bad)", { XX
} },
2566 { "(bad)", { XX
} },
2567 { "(bad)", { XX
} },
2568 { "(bad)", { XX
} },
2569 { "(bad)", { XX
} },
2570 { "(bad)", { XX
} },
2571 { "(bad)", { XX
} },
2573 { "(bad)", { XX
} },
2574 { "(bad)", { XX
} },
2575 { "(bad)", { XX
} },
2576 { "(bad)", { XX
} },
2577 { "(bad)", { XX
} },
2578 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2580 { "(bad)", { XX
} },
2582 { "(bad)", { XX
} },
2583 { "(bad)", { XX
} },
2584 { "(bad)", { XX
} },
2585 { "(bad)", { XX
} },
2586 { "(bad)", { XX
} },
2587 { "(bad)", { XX
} },
2588 { "(bad)", { XX
} },
2589 { "(bad)", { XX
} },
2591 { "(bad)", { XX
} },
2592 { "(bad)", { XX
} },
2593 { "(bad)", { XX
} },
2594 { "(bad)", { XX
} },
2595 { "(bad)", { XX
} },
2596 { "(bad)", { XX
} },
2597 { "(bad)", { XX
} },
2598 { "(bad)", { XX
} },
2600 { "(bad)", { XX
} },
2601 { "(bad)", { XX
} },
2602 { "(bad)", { XX
} },
2603 { "(bad)", { XX
} },
2604 { "(bad)", { XX
} },
2605 { "(bad)", { XX
} },
2606 { "(bad)", { XX
} },
2607 { "(bad)", { XX
} },
2609 { "(bad)", { XX
} },
2610 { "(bad)", { XX
} },
2611 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "(bad)", { XX
} },
2614 { "(bad)", { XX
} },
2615 { "(bad)", { XX
} },
2616 { "(bad)", { XX
} },
2618 { "(bad)", { XX
} },
2619 { "(bad)", { XX
} },
2620 { "(bad)", { XX
} },
2621 { "(bad)", { XX
} },
2622 { "(bad)", { XX
} },
2623 { "(bad)", { XX
} },
2624 { "(bad)", { XX
} },
2625 { "(bad)", { XX
} },
2627 { "(bad)", { XX
} },
2628 { "(bad)", { XX
} },
2629 { "(bad)", { XX
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2632 { "(bad)", { XX
} },
2633 { "(bad)", { XX
} },
2634 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2637 { "(bad)", { XX
} },
2638 { "(bad)", { XX
} },
2639 { "(bad)", { XX
} },
2640 { "(bad)", { XX
} },
2641 { "(bad)", { XX
} },
2642 { "(bad)", { XX
} },
2643 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "(bad)", { XX
} },
2647 { "(bad)", { XX
} },
2648 { "(bad)", { XX
} },
2649 { "(bad)", { XX
} },
2650 { "(bad)", { XX
} },
2651 { "(bad)", { XX
} },
2652 { "(bad)", { XX
} },
2654 { "(bad)", { XX
} },
2655 { "(bad)", { XX
} },
2656 { "(bad)", { XX
} },
2657 { "(bad)", { XX
} },
2658 { "(bad)", { XX
} },
2659 { "(bad)", { XX
} },
2660 { "(bad)", { XX
} },
2661 { "(bad)", { XX
} },
2663 { "(bad)", { XX
} },
2664 { "(bad)", { XX
} },
2665 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2669 { "(bad)", { XX
} },
2670 { "(bad)", { XX
} },
2672 { "(bad)", { XX
} },
2673 { "(bad)", { XX
} },
2674 { "(bad)", { XX
} },
2675 { "(bad)", { XX
} },
2676 { "(bad)", { XX
} },
2677 { "(bad)", { XX
} },
2678 { "(bad)", { XX
} },
2679 { "(bad)", { XX
} },
2681 { "(bad)", { XX
} },
2682 { "(bad)", { XX
} },
2683 { "(bad)", { XX
} },
2684 { "(bad)", { XX
} },
2685 { "(bad)", { XX
} },
2686 { "(bad)", { XX
} },
2687 { "(bad)", { XX
} },
2688 { "(bad)", { XX
} },
2690 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2695 { "(bad)", { XX
} },
2696 { "(bad)", { XX
} },
2697 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2704 { "(bad)", { XX
} },
2705 { "(bad)", { XX
} },
2706 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2713 { "(bad)", { XX
} },
2714 { "(bad)", { XX
} },
2715 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2722 { "(bad)", { XX
} },
2723 { "(bad)", { XX
} },
2724 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2733 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2741 { "(bad)", { XX
} },
2742 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "(bad)", { XX
} },
2750 { "(bad)", { XX
} },
2751 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2758 { "(bad)", { XX
} },
2759 { "(bad)", { XX
} },
2760 { "(bad)", { XX
} },
2762 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2767 { "(bad)", { XX
} },
2768 { "(bad)", { XX
} },
2769 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2776 { "(bad)", { XX
} },
2777 { "(bad)", { XX
} },
2778 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "(bad)", { XX
} },
2790 { "palignr", { MX
, EM
, Ib
} },
2792 { "(bad)", { XX
} },
2793 { "(bad)", { XX
} },
2794 { "(bad)", { XX
} },
2795 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2803 { "(bad)", { XX
} },
2804 { "(bad)", { XX
} },
2805 { "(bad)", { XX
} },
2806 { "(bad)", { XX
} },
2807 { "(bad)", { XX
} },
2808 { "(bad)", { XX
} },
2813 { "(bad)", { XX
} },
2814 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2817 { "(bad)", { XX
} },
2819 { "(bad)", { XX
} },
2820 { "(bad)", { XX
} },
2821 { "(bad)", { XX
} },
2822 { "(bad)", { XX
} },
2823 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2826 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2830 { "(bad)", { XX
} },
2831 { "(bad)", { XX
} },
2832 { "(bad)", { XX
} },
2833 { "(bad)", { XX
} },
2834 { "(bad)", { XX
} },
2835 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2839 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2841 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2844 { "(bad)", { XX
} },
2849 { "(bad)", { XX
} },
2850 { "(bad)", { XX
} },
2851 { "(bad)", { XX
} },
2852 { "(bad)", { XX
} },
2853 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2857 { "(bad)", { XX
} },
2858 { "(bad)", { XX
} },
2859 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2862 { "(bad)", { XX
} },
2864 { "(bad)", { XX
} },
2865 { "(bad)", { XX
} },
2866 { "(bad)", { XX
} },
2867 { "(bad)", { XX
} },
2868 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2870 { "(bad)", { XX
} },
2871 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2876 { "(bad)", { XX
} },
2877 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2879 { "(bad)", { XX
} },
2880 { "(bad)", { XX
} },
2886 { "(bad)", { XX
} },
2887 { "(bad)", { XX
} },
2888 { "(bad)", { XX
} },
2889 { "(bad)", { XX
} },
2891 { "(bad)", { XX
} },
2892 { "(bad)", { XX
} },
2893 { "(bad)", { XX
} },
2894 { "(bad)", { XX
} },
2895 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2898 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2903 { "(bad)", { XX
} },
2904 { "(bad)", { XX
} },
2905 { "(bad)", { XX
} },
2906 { "(bad)", { XX
} },
2907 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2915 { "(bad)", { XX
} },
2916 { "(bad)", { XX
} },
2918 { "(bad)", { XX
} },
2919 { "(bad)", { XX
} },
2920 { "(bad)", { XX
} },
2921 { "(bad)", { XX
} },
2922 { "(bad)", { XX
} },
2923 { "(bad)", { XX
} },
2924 { "(bad)", { XX
} },
2925 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2928 { "(bad)", { XX
} },
2929 { "(bad)", { XX
} },
2930 { "(bad)", { XX
} },
2931 { "(bad)", { XX
} },
2932 { "(bad)", { XX
} },
2933 { "(bad)", { XX
} },
2934 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2942 { "(bad)", { XX
} },
2943 { "(bad)", { XX
} },
2945 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2951 { "(bad)", { XX
} },
2952 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2960 { "(bad)", { XX
} },
2961 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2969 { "(bad)", { XX
} },
2970 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2978 { "(bad)", { XX
} },
2979 { "(bad)", { XX
} },
2981 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2987 { "(bad)", { XX
} },
2988 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2996 { "(bad)", { XX
} },
2997 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3005 { "(bad)", { XX
} },
3006 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3014 { "(bad)", { XX
} },
3015 { "(bad)", { XX
} },
3017 { "(bad)", { XX
} },
3018 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3023 { "(bad)", { XX
} },
3024 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3032 { "(bad)", { XX
} },
3033 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3041 { "(bad)", { XX
} },
3042 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3050 { "(bad)", { XX
} },
3051 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3059 { "(bad)", { XX
} },
3060 { "(bad)", { XX
} },
3064 static const struct dis386 opc_ext_table
[][2] = {
3067 { "leaS", { Gv
, M
} },
3068 { "(bad)", { XX
} },
3072 { "les{S|}", { Gv
, Mp
} },
3073 { "(bad)", { XX
} },
3077 { "ldsS", { Gv
, Mp
} },
3078 { "(bad)", { XX
} },
3082 { "lssS", { Gv
, Mp
} },
3083 { "(bad)", { XX
} },
3087 { "lfsS", { Gv
, Mp
} },
3088 { "(bad)", { XX
} },
3092 { "lgsS", { Gv
, Mp
} },
3093 { "(bad)", { XX
} },
3097 { "sgdt{Q|IQ||}", { M
} },
3102 { "sidt{Q|IQ||}", { M
} },
3107 { "lgdt{Q|Q||}", { M
} },
3108 { "(bad)", { XX
} },
3113 { "(bad)", { XX
} },
3117 { "vmptrst", { Mq
} },
3118 { "(bad)", { XX
} },
3122 { "(bad)", { XX
} },
3123 { "psrlw", { MS
, Ib
} },
3127 { "(bad)", { XX
} },
3128 { "psraw", { MS
, Ib
} },
3132 { "(bad)", { XX
} },
3133 { "psllw", { MS
, Ib
} },
3137 { "(bad)", { XX
} },
3138 { "psrld", { MS
, Ib
} },
3142 { "(bad)", { XX
} },
3143 { "psrad", { MS
, Ib
} },
3147 { "(bad)", { XX
} },
3148 { "pslld", { MS
, Ib
} },
3152 { "(bad)", { XX
} },
3153 { "psrlq", { MS
, Ib
} },
3157 { "(bad)", { XX
} },
3162 { "(bad)", { XX
} },
3163 { "psllq", { MS
, Ib
} },
3167 { "(bad)", { XX
} },
3172 { "fxsave", { M
} },
3173 { "(bad)", { XX
} },
3177 { "fxrstor", { M
} },
3178 { "(bad)", { XX
} },
3182 { "ldmxcsr", { Md
} },
3183 { "(bad)", { XX
} },
3187 { "stmxcsr", { Md
} },
3188 { "(bad)", { XX
} },
3192 { "(bad)", { XX
} },
3197 { "(bad)", { XX
} },
3202 { "clflush", { Mb
} },
3207 { "prefetchnta", { Mb
} },
3208 { "(bad)", { XX
} },
3212 { "prefetcht0", { Mb
} },
3213 { "(bad)", { XX
} },
3217 { "prefetcht1", { Mb
} },
3218 { "(bad)", { XX
} },
3222 { "prefetcht2", { Mb
} },
3223 { "(bad)", { XX
} },
3227 { "lddqu", { XM
, M
} },
3228 { "(bad)", { XX
} },
3232 { "bound{S|}", { Gv
, Ma
} },
3233 { "(bad)", { XX
} },
3237 { "movlpX", { EXq
, XM
} },
3238 { "(bad)", { XX
} },
3242 { "movhpX", { EXq
, XM
} },
3243 { "(bad)", { XX
} },
3247 { "movlpX", { XM
, EXq
} },
3248 { "movhlpX", { XM
, EXq
} },
3252 { "movhpX", { XM
, EXq
} },
3253 { "movlhpX", { XM
, EXq
} },
3257 static const struct dis386 opc_ext_rm_table
[][8] = {
3260 { "(bad)", { XX
} },
3261 { "vmcall", { Skip_MODRM
} },
3262 { "vmlaunch", { Skip_MODRM
} },
3263 { "vmresume", { Skip_MODRM
} },
3264 { "vmxoff", { Skip_MODRM
} },
3265 { "(bad)", { XX
} },
3266 { "(bad)", { XX
} },
3267 { "(bad)", { XX
} },
3271 { "monitor", { { OP_Monitor
, 0 } } },
3272 { "mwait", { { OP_Mwait
, 0 } } },
3273 { "(bad)", { XX
} },
3274 { "(bad)", { XX
} },
3275 { "(bad)", { XX
} },
3276 { "(bad)", { XX
} },
3277 { "(bad)", { XX
} },
3278 { "(bad)", { XX
} },
3282 { "lfence", { Skip_MODRM
} },
3283 { "(bad)", { XX
} },
3284 { "(bad)", { XX
} },
3285 { "(bad)", { XX
} },
3286 { "(bad)", { XX
} },
3287 { "(bad)", { XX
} },
3288 { "(bad)", { XX
} },
3289 { "(bad)", { XX
} },
3293 { "mfence", { Skip_MODRM
} },
3294 { "(bad)", { XX
} },
3295 { "(bad)", { XX
} },
3296 { "(bad)", { XX
} },
3297 { "(bad)", { XX
} },
3298 { "(bad)", { XX
} },
3299 { "(bad)", { XX
} },
3300 { "(bad)", { XX
} },
3304 { "sfence", { Skip_MODRM
} },
3305 { "(bad)", { XX
} },
3306 { "(bad)", { XX
} },
3307 { "(bad)", { XX
} },
3308 { "(bad)", { XX
} },
3309 { "(bad)", { XX
} },
3310 { "(bad)", { XX
} },
3311 { "(bad)", { XX
} },
3315 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3327 FETCH_DATA (the_info
, codep
+ 1);
3331 /* REX prefixes family. */
3348 if (address_mode
== mode_64bit
)
3354 prefixes
|= PREFIX_REPZ
;
3357 prefixes
|= PREFIX_REPNZ
;
3360 prefixes
|= PREFIX_LOCK
;
3363 prefixes
|= PREFIX_CS
;
3366 prefixes
|= PREFIX_SS
;
3369 prefixes
|= PREFIX_DS
;
3372 prefixes
|= PREFIX_ES
;
3375 prefixes
|= PREFIX_FS
;
3378 prefixes
|= PREFIX_GS
;
3381 prefixes
|= PREFIX_DATA
;
3384 prefixes
|= PREFIX_ADDR
;
3387 /* fwait is really an instruction. If there are prefixes
3388 before the fwait, they belong to the fwait, *not* to the
3389 following instruction. */
3390 if (prefixes
|| rex
)
3392 prefixes
|= PREFIX_FWAIT
;
3396 prefixes
= PREFIX_FWAIT
;
3401 /* Rex is ignored when followed by another prefix. */
3412 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3416 prefix_name (int pref
, int sizeflag
)
3418 static const char *rexes
[16] =
3423 "rex.XB", /* 0x43 */
3425 "rex.RB", /* 0x45 */
3426 "rex.RX", /* 0x46 */
3427 "rex.RXB", /* 0x47 */
3429 "rex.WB", /* 0x49 */
3430 "rex.WX", /* 0x4a */
3431 "rex.WXB", /* 0x4b */
3432 "rex.WR", /* 0x4c */
3433 "rex.WRB", /* 0x4d */
3434 "rex.WRX", /* 0x4e */
3435 "rex.WRXB", /* 0x4f */
3440 /* REX prefixes family. */
3457 return rexes
[pref
- 0x40];
3477 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3479 if (address_mode
== mode_64bit
)
3480 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3482 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3490 static char op_out
[MAX_OPERANDS
][100];
3491 static int op_ad
, op_index
[MAX_OPERANDS
];
3492 static int two_source_ops
;
3493 static bfd_vma op_address
[MAX_OPERANDS
];
3494 static bfd_vma op_riprel
[MAX_OPERANDS
];
3495 static bfd_vma start_pc
;
3498 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3499 * (see topic "Redundant prefixes" in the "Differences from 8086"
3500 * section of the "Virtual 8086 Mode" chapter.)
3501 * 'pc' should be the address of this instruction, it will
3502 * be used to print the target address if this is a relative jump or call
3503 * The function returns the length of this instruction in bytes.
3506 static char intel_syntax
;
3507 static char open_char
;
3508 static char close_char
;
3509 static char separator_char
;
3510 static char scale_char
;
3512 /* Here for backwards compatibility. When gdb stops using
3513 print_insn_i386_att and print_insn_i386_intel these functions can
3514 disappear, and print_insn_i386 be merged into print_insn. */
3516 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3520 return print_insn (pc
, info
);
3524 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3528 return print_insn (pc
, info
);
3532 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3536 return print_insn (pc
, info
);
3540 print_i386_disassembler_options (FILE *stream
)
3542 fprintf (stream
, _("\n\
3543 The following i386/x86-64 specific disassembler options are supported for use\n\
3544 with the -M switch (multiple options should be separated by commas):\n"));
3546 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3547 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3548 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3549 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3550 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3551 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3552 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3553 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3554 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3555 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3556 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3559 /* Get a pointer to struct dis386 with a valid name. */
3561 static const struct dis386
*
3562 get_valid_dis386 (const struct dis386
*dp
)
3566 if (dp
->name
!= NULL
)
3569 switch (dp
->op
[0].bytemode
)
3572 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3575 case USE_PREFIX_USER_TABLE
:
3577 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3578 if (prefixes
& PREFIX_REPZ
)
3585 /* We should check PREFIX_REPNZ and PREFIX_REPZ before
3587 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3588 if (prefixes
& PREFIX_REPNZ
)
3591 repnz_prefix
= NULL
;
3595 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3596 if (prefixes
& PREFIX_DATA
)
3603 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3606 case X86_64_SPECIAL
:
3607 index
= address_mode
== mode_64bit
? 1 : 0;
3608 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3611 case USE_OPC_EXT_TABLE
:
3612 index
= modrm
.mod
== 0x3 ? 1 : 0;
3613 dp
= &opc_ext_table
[dp
->op
[1].bytemode
][index
];
3616 case USE_OPC_EXT_RM_TABLE
:
3618 dp
= &opc_ext_rm_table
[dp
->op
[1].bytemode
][index
];
3622 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3626 if (dp
->name
!= NULL
)
3629 return get_valid_dis386 (dp
);
3633 print_insn (bfd_vma pc
, disassemble_info
*info
)
3635 const struct dis386
*dp
;
3637 char *op_txt
[MAX_OPERANDS
];
3641 struct dis_private priv
;
3643 char prefix_obuf
[32];
3646 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3647 || info
->mach
== bfd_mach_x86_64
)
3648 address_mode
= mode_64bit
;
3650 address_mode
= mode_32bit
;
3652 if (intel_syntax
== (char) -1)
3653 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3654 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3656 if (info
->mach
== bfd_mach_i386_i386
3657 || info
->mach
== bfd_mach_x86_64
3658 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3659 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3660 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3661 else if (info
->mach
== bfd_mach_i386_i8086
)
3662 priv
.orig_sizeflag
= 0;
3666 for (p
= info
->disassembler_options
; p
!= NULL
; )
3668 if (CONST_STRNEQ (p
, "x86-64"))
3670 address_mode
= mode_64bit
;
3671 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3673 else if (CONST_STRNEQ (p
, "i386"))
3675 address_mode
= mode_32bit
;
3676 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3678 else if (CONST_STRNEQ (p
, "i8086"))
3680 address_mode
= mode_16bit
;
3681 priv
.orig_sizeflag
= 0;
3683 else if (CONST_STRNEQ (p
, "intel"))
3687 else if (CONST_STRNEQ (p
, "att"))
3691 else if (CONST_STRNEQ (p
, "addr"))
3693 if (address_mode
== mode_64bit
)
3695 if (p
[4] == '3' && p
[5] == '2')
3696 priv
.orig_sizeflag
&= ~AFLAG
;
3697 else if (p
[4] == '6' && p
[5] == '4')
3698 priv
.orig_sizeflag
|= AFLAG
;
3702 if (p
[4] == '1' && p
[5] == '6')
3703 priv
.orig_sizeflag
&= ~AFLAG
;
3704 else if (p
[4] == '3' && p
[5] == '2')
3705 priv
.orig_sizeflag
|= AFLAG
;
3708 else if (CONST_STRNEQ (p
, "data"))
3710 if (p
[4] == '1' && p
[5] == '6')
3711 priv
.orig_sizeflag
&= ~DFLAG
;
3712 else if (p
[4] == '3' && p
[5] == '2')
3713 priv
.orig_sizeflag
|= DFLAG
;
3715 else if (CONST_STRNEQ (p
, "suffix"))
3716 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3718 p
= strchr (p
, ',');
3725 names64
= intel_names64
;
3726 names32
= intel_names32
;
3727 names16
= intel_names16
;
3728 names8
= intel_names8
;
3729 names8rex
= intel_names8rex
;
3730 names_seg
= intel_names_seg
;
3731 index16
= intel_index16
;
3734 separator_char
= '+';
3739 names64
= att_names64
;
3740 names32
= att_names32
;
3741 names16
= att_names16
;
3742 names8
= att_names8
;
3743 names8rex
= att_names8rex
;
3744 names_seg
= att_names_seg
;
3745 index16
= att_index16
;
3748 separator_char
= ',';
3752 /* The output looks better if we put 7 bytes on a line, since that
3753 puts most long word instructions on a single line. */
3754 info
->bytes_per_line
= 7;
3756 info
->private_data
= &priv
;
3757 priv
.max_fetched
= priv
.the_buffer
;
3758 priv
.insn_start
= pc
;
3761 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3769 start_codep
= priv
.the_buffer
;
3770 codep
= priv
.the_buffer
;
3772 if (setjmp (priv
.bailout
) != 0)
3776 /* Getting here means we tried for data but didn't get it. That
3777 means we have an incomplete instruction of some sort. Just
3778 print the first byte as a prefix or a .byte pseudo-op. */
3779 if (codep
> priv
.the_buffer
)
3781 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3783 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3786 /* Just print the first byte as a .byte instruction. */
3787 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3788 (unsigned int) priv
.the_buffer
[0]);
3801 sizeflag
= priv
.orig_sizeflag
;
3803 FETCH_DATA (info
, codep
+ 1);
3804 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3806 if (((prefixes
& PREFIX_FWAIT
)
3807 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3808 || (rex
&& rex_used
))
3812 /* fwait not followed by floating point instruction, or rex followed
3813 by other prefixes. Print the first prefix. */
3814 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3816 name
= INTERNAL_DISASSEMBLER_ERROR
;
3817 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3824 unsigned char threebyte
;
3825 FETCH_DATA (info
, codep
+ 2);
3826 threebyte
= *++codep
;
3827 dp
= &dis386_twobyte
[threebyte
];
3828 need_modrm
= twobyte_has_modrm
[*codep
];
3830 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3832 FETCH_DATA (info
, codep
+ 2);
3838 dp
= &dis386
[*codep
];
3839 need_modrm
= onebyte_has_modrm
[*codep
];
3843 if ((prefixes
& PREFIX_REPZ
))
3845 repz_prefix
= "repz ";
3846 used_prefixes
|= PREFIX_REPZ
;
3851 if ((prefixes
& PREFIX_REPNZ
))
3853 repnz_prefix
= "repnz ";
3854 used_prefixes
|= PREFIX_REPNZ
;
3857 repnz_prefix
= NULL
;
3859 if ((prefixes
& PREFIX_LOCK
))
3861 lock_prefix
= "lock ";
3862 used_prefixes
|= PREFIX_LOCK
;
3868 if (prefixes
& PREFIX_ADDR
)
3871 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3873 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3874 addr_prefix
= "addr32 ";
3876 addr_prefix
= "addr16 ";
3877 used_prefixes
|= PREFIX_ADDR
;
3882 if ((prefixes
& PREFIX_DATA
))
3885 if (dp
->op
[2].bytemode
== cond_jump_mode
3886 && dp
->op
[0].bytemode
== v_mode
3889 if (sizeflag
& DFLAG
)
3890 data_prefix
= "data32 ";
3892 data_prefix
= "data16 ";
3893 used_prefixes
|= PREFIX_DATA
;
3897 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3899 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3900 modrm
.mod
= (*codep
>> 6) & 3;
3901 modrm
.reg
= (*codep
>> 3) & 7;
3902 modrm
.rm
= *codep
& 7;
3904 else if (need_modrm
)
3906 FETCH_DATA (info
, codep
+ 1);
3907 modrm
.mod
= (*codep
>> 6) & 3;
3908 modrm
.reg
= (*codep
>> 3) & 7;
3909 modrm
.rm
= *codep
& 7;
3912 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3918 dp
= get_valid_dis386 (dp
);
3919 if (dp
!= NULL
&& putop (dp
->name
, sizeflag
) == 0)
3921 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3924 op_ad
= MAX_OPERANDS
- 1 - i
;
3926 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3931 /* See if any prefixes were not used. If so, print the first one
3932 separately. If we don't do this, we'll wind up printing an
3933 instruction stream which does not precisely correspond to the
3934 bytes we are disassembling. */
3935 if ((prefixes
& ~used_prefixes
) != 0)
3939 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3941 name
= INTERNAL_DISASSEMBLER_ERROR
;
3942 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3945 if (rex
& ~rex_used
)
3948 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3950 name
= INTERNAL_DISASSEMBLER_ERROR
;
3951 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3955 prefix_obufp
= prefix_obuf
;
3957 prefix_obufp
= stpcpy (prefix_obufp
, lock_prefix
);
3959 prefix_obufp
= stpcpy (prefix_obufp
, repz_prefix
);
3961 prefix_obufp
= stpcpy (prefix_obufp
, repnz_prefix
);
3963 prefix_obufp
= stpcpy (prefix_obufp
, addr_prefix
);
3965 prefix_obufp
= stpcpy (prefix_obufp
, data_prefix
);
3967 if (prefix_obuf
[0] != 0)
3968 (*info
->fprintf_func
) (info
->stream
, "%s", prefix_obuf
);
3970 obufp
= obuf
+ strlen (obuf
);
3971 for (i
= strlen (obuf
) + strlen (prefix_obuf
); i
< 6; i
++)
3974 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3976 /* The enter and bound instructions are printed with operands in the same
3977 order as the intel book; everything else is printed in reverse order. */
3978 if (intel_syntax
|| two_source_ops
)
3982 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3983 op_txt
[i
] = op_out
[i
];
3985 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3987 op_ad
= op_index
[i
];
3988 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3989 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3990 riprel
= op_riprel
[i
];
3991 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
3992 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
3997 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3998 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
4002 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4006 (*info
->fprintf_func
) (info
->stream
, ",");
4007 if (op_index
[i
] != -1 && !op_riprel
[i
])
4008 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
4010 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
4014 for (i
= 0; i
< MAX_OPERANDS
; i
++)
4015 if (op_index
[i
] != -1 && op_riprel
[i
])
4017 (*info
->fprintf_func
) (info
->stream
, " # ");
4018 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
4019 + op_address
[op_index
[i
]]), info
);
4022 return codep
- priv
.the_buffer
;
4025 static const char *float_mem
[] = {
4100 static const unsigned char float_mem_mode
[] = {
4175 #define ST { OP_ST, 0 }
4176 #define STi { OP_STi, 0 }
4178 #define FGRPd9_2 NULL, { { NULL, 0 } }
4179 #define FGRPd9_4 NULL, { { NULL, 1 } }
4180 #define FGRPd9_5 NULL, { { NULL, 2 } }
4181 #define FGRPd9_6 NULL, { { NULL, 3 } }
4182 #define FGRPd9_7 NULL, { { NULL, 4 } }
4183 #define FGRPda_5 NULL, { { NULL, 5 } }
4184 #define FGRPdb_4 NULL, { { NULL, 6 } }
4185 #define FGRPde_3 NULL, { { NULL, 7 } }
4186 #define FGRPdf_4 NULL, { { NULL, 8 } }
4188 static const struct dis386 float_reg
[][8] = {
4191 { "fadd", { ST
, STi
} },
4192 { "fmul", { ST
, STi
} },
4193 { "fcom", { STi
} },
4194 { "fcomp", { STi
} },
4195 { "fsub", { ST
, STi
} },
4196 { "fsubr", { ST
, STi
} },
4197 { "fdiv", { ST
, STi
} },
4198 { "fdivr", { ST
, STi
} },
4203 { "fxch", { STi
} },
4205 { "(bad)", { XX
} },
4213 { "fcmovb", { ST
, STi
} },
4214 { "fcmove", { ST
, STi
} },
4215 { "fcmovbe",{ ST
, STi
} },
4216 { "fcmovu", { ST
, STi
} },
4217 { "(bad)", { XX
} },
4219 { "(bad)", { XX
} },
4220 { "(bad)", { XX
} },
4224 { "fcmovnb",{ ST
, STi
} },
4225 { "fcmovne",{ ST
, STi
} },
4226 { "fcmovnbe",{ ST
, STi
} },
4227 { "fcmovnu",{ ST
, STi
} },
4229 { "fucomi", { ST
, STi
} },
4230 { "fcomi", { ST
, STi
} },
4231 { "(bad)", { XX
} },
4235 { "fadd", { STi
, ST
} },
4236 { "fmul", { STi
, ST
} },
4237 { "(bad)", { XX
} },
4238 { "(bad)", { XX
} },
4240 { "fsub", { STi
, ST
} },
4241 { "fsubr", { STi
, ST
} },
4242 { "fdiv", { STi
, ST
} },
4243 { "fdivr", { STi
, ST
} },
4245 { "fsubr", { STi
, ST
} },
4246 { "fsub", { STi
, ST
} },
4247 { "fdivr", { STi
, ST
} },
4248 { "fdiv", { STi
, ST
} },
4253 { "ffree", { STi
} },
4254 { "(bad)", { XX
} },
4256 { "fstp", { STi
} },
4257 { "fucom", { STi
} },
4258 { "fucomp", { STi
} },
4259 { "(bad)", { XX
} },
4260 { "(bad)", { XX
} },
4264 { "faddp", { STi
, ST
} },
4265 { "fmulp", { STi
, ST
} },
4266 { "(bad)", { XX
} },
4269 { "fsubp", { STi
, ST
} },
4270 { "fsubrp", { STi
, ST
} },
4271 { "fdivp", { STi
, ST
} },
4272 { "fdivrp", { STi
, ST
} },
4274 { "fsubrp", { STi
, ST
} },
4275 { "fsubp", { STi
, ST
} },
4276 { "fdivrp", { STi
, ST
} },
4277 { "fdivp", { STi
, ST
} },
4282 { "ffreep", { STi
} },
4283 { "(bad)", { XX
} },
4284 { "(bad)", { XX
} },
4285 { "(bad)", { XX
} },
4287 { "fucomip", { ST
, STi
} },
4288 { "fcomip", { ST
, STi
} },
4289 { "(bad)", { XX
} },
4293 static char *fgrps
[][8] = {
4296 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4301 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4306 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4311 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4316 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4321 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4326 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4327 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4332 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4337 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4342 OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED
,
4343 int sizeflag ATTRIBUTE_UNUSED
)
4345 /* Skip mod/rm byte. */
4351 dofloat (int sizeflag
)
4353 const struct dis386
*dp
;
4354 unsigned char floatop
;
4356 floatop
= codep
[-1];
4360 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4362 putop (float_mem
[fp_indx
], sizeflag
);
4365 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4368 /* Skip mod/rm byte. */
4372 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4373 if (dp
->name
== NULL
)
4375 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4377 /* Instruction fnstsw is only one with strange arg. */
4378 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4379 strcpy (op_out
[0], names16
[0]);
4383 putop (dp
->name
, sizeflag
);
4388 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4393 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4398 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4400 oappend ("%st" + intel_syntax
);
4404 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4406 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4407 oappend (scratchbuf
+ intel_syntax
);
4410 /* Capital letters in template are macros. */
4412 putop (const char *template, int sizeflag
)
4417 for (p
= template; *p
; p
++)
4428 if (address_mode
== mode_64bit
)
4436 /* Alternative not valid. */
4437 strcpy (obuf
, "(bad)");
4441 else if (*p
== '\0')
4462 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4468 if (sizeflag
& SUFFIX_ALWAYS
)
4472 if (intel_syntax
&& !alt
)
4474 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4476 if (sizeflag
& DFLAG
)
4477 *obufp
++ = intel_syntax
? 'd' : 'l';
4479 *obufp
++ = intel_syntax
? 'w' : 's';
4480 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4484 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4491 else if (sizeflag
& DFLAG
)
4492 *obufp
++ = intel_syntax
? 'd' : 'l';
4495 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4500 case 'E': /* For jcxz/jecxz */
4501 if (address_mode
== mode_64bit
)
4503 if (sizeflag
& AFLAG
)
4509 if (sizeflag
& AFLAG
)
4511 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4516 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4518 if (sizeflag
& AFLAG
)
4519 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4521 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4522 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4526 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4528 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4533 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4538 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4539 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4541 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4544 if (prefixes
& PREFIX_DS
)
4565 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4574 if (sizeflag
& SUFFIX_ALWAYS
)
4578 if ((prefixes
& PREFIX_FWAIT
) == 0)
4581 used_prefixes
|= PREFIX_FWAIT
;
4587 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4592 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4597 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4606 if ((prefixes
& PREFIX_DATA
)
4608 || (sizeflag
& SUFFIX_ALWAYS
))
4615 if (sizeflag
& DFLAG
)
4620 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4626 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4628 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4634 if (intel_syntax
&& !alt
)
4637 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4643 if (sizeflag
& DFLAG
)
4644 *obufp
++ = intel_syntax
? 'd' : 'l';
4648 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4655 else if (sizeflag
& DFLAG
)
4664 if (intel_syntax
&& !p
[1]
4665 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4668 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4673 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4675 if (sizeflag
& SUFFIX_ALWAYS
)
4683 if (sizeflag
& SUFFIX_ALWAYS
)
4689 if (sizeflag
& DFLAG
)
4693 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4698 if (prefixes
& PREFIX_DATA
)
4702 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4713 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4715 /* operand size flag for cwtl, cbtw */
4724 else if (sizeflag
& DFLAG
)
4729 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4739 oappend (const char *s
)
4742 obufp
+= strlen (s
);
4748 if (prefixes
& PREFIX_CS
)
4750 used_prefixes
|= PREFIX_CS
;
4751 oappend ("%cs:" + intel_syntax
);
4753 if (prefixes
& PREFIX_DS
)
4755 used_prefixes
|= PREFIX_DS
;
4756 oappend ("%ds:" + intel_syntax
);
4758 if (prefixes
& PREFIX_SS
)
4760 used_prefixes
|= PREFIX_SS
;
4761 oappend ("%ss:" + intel_syntax
);
4763 if (prefixes
& PREFIX_ES
)
4765 used_prefixes
|= PREFIX_ES
;
4766 oappend ("%es:" + intel_syntax
);
4768 if (prefixes
& PREFIX_FS
)
4770 used_prefixes
|= PREFIX_FS
;
4771 oappend ("%fs:" + intel_syntax
);
4773 if (prefixes
& PREFIX_GS
)
4775 used_prefixes
|= PREFIX_GS
;
4776 oappend ("%gs:" + intel_syntax
);
4781 OP_indirE (int bytemode
, int sizeflag
)
4785 OP_E (bytemode
, sizeflag
);
4789 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4791 if (address_mode
== mode_64bit
)
4799 sprintf_vma (tmp
, disp
);
4800 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4801 strcpy (buf
+ 2, tmp
+ i
);
4805 bfd_signed_vma v
= disp
;
4812 /* Check for possible overflow on 0x8000000000000000. */
4815 strcpy (buf
, "9223372036854775808");
4829 tmp
[28 - i
] = (v
% 10) + '0';
4833 strcpy (buf
, tmp
+ 29 - i
);
4839 sprintf (buf
, "0x%x", (unsigned int) disp
);
4841 sprintf (buf
, "%d", (int) disp
);
4845 /* Put DISP in BUF as signed hex number. */
4848 print_displacement (char *buf
, bfd_vma disp
)
4850 bfd_signed_vma val
= disp
;
4859 /* Check for possible overflow. */
4862 switch (address_mode
)
4865 strcpy (buf
+ j
, "0x8000000000000000");
4868 strcpy (buf
+ j
, "0x80000000");
4871 strcpy (buf
+ j
, "0x8000");
4881 sprintf_vma (tmp
, val
);
4882 for (i
= 0; tmp
[i
] == '0'; i
++)
4886 strcpy (buf
+ j
, tmp
+ i
);
4890 intel_operand_size (int bytemode
, int sizeflag
)
4896 oappend ("BYTE PTR ");
4900 oappend ("WORD PTR ");
4903 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4905 oappend ("QWORD PTR ");
4906 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4914 oappend ("QWORD PTR ");
4915 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4916 oappend ("DWORD PTR ");
4918 oappend ("WORD PTR ");
4919 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4922 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4924 oappend ("WORD PTR ");
4926 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4930 oappend ("DWORD PTR ");
4933 oappend ("QWORD PTR ");
4936 if (address_mode
== mode_64bit
)
4937 oappend ("QWORD PTR ");
4939 oappend ("DWORD PTR ");
4942 if (sizeflag
& DFLAG
)
4943 oappend ("FWORD PTR ");
4945 oappend ("DWORD PTR ");
4946 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4949 oappend ("TBYTE PTR ");
4952 oappend ("XMMWORD PTR ");
4955 oappend ("OWORD PTR ");
4963 OP_E (int bytemode
, int sizeflag
)
4972 /* Skip mod/rm byte. */
4983 oappend (names8rex
[modrm
.rm
+ add
]);
4985 oappend (names8
[modrm
.rm
+ add
]);
4988 oappend (names16
[modrm
.rm
+ add
]);
4991 oappend (names32
[modrm
.rm
+ add
]);
4994 oappend (names64
[modrm
.rm
+ add
]);
4997 if (address_mode
== mode_64bit
)
4998 oappend (names64
[modrm
.rm
+ add
]);
5000 oappend (names32
[modrm
.rm
+ add
]);
5003 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5005 oappend (names64
[modrm
.rm
+ add
]);
5006 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5018 oappend (names64
[modrm
.rm
+ add
]);
5019 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5020 oappend (names32
[modrm
.rm
+ add
]);
5022 oappend (names16
[modrm
.rm
+ add
]);
5023 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5028 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5036 intel_operand_size (bytemode
, sizeflag
);
5039 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5041 /* 32/64 bit address mode */
5056 FETCH_DATA (the_info
, codep
+ 1);
5057 index
= (*codep
>> 3) & 7;
5058 if (address_mode
== mode_64bit
|| index
!= 0x4)
5059 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
5060 scale
= (*codep
>> 6) & 3;
5072 if ((base
& 7) == 5)
5075 if (address_mode
== mode_64bit
&& !havesib
)
5081 FETCH_DATA (the_info
, codep
+ 1);
5083 if ((disp
& 0x80) != 0)
5091 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
5094 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5096 if (havedisp
|| riprel
)
5097 print_displacement (scratchbuf
, disp
);
5099 print_operand_value (scratchbuf
, 1, disp
);
5100 oappend (scratchbuf
);
5108 if (havedisp
|| (intel_syntax
&& riprel
))
5110 *obufp
++ = open_char
;
5111 if (intel_syntax
&& riprel
)
5118 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5119 ? names64
[base
] : names32
[base
]);
5124 if (!intel_syntax
|| havebase
)
5126 *obufp
++ = separator_char
;
5129 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5130 ? names64
[index
] : names32
[index
]);
5132 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
5134 *obufp
++ = scale_char
;
5136 sprintf (scratchbuf
, "%d", 1 << scale
);
5137 oappend (scratchbuf
);
5141 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
5143 if ((bfd_signed_vma
) disp
>= 0)
5148 else if (modrm
.mod
!= 1)
5152 disp
= - (bfd_signed_vma
) disp
;
5155 print_displacement (scratchbuf
, disp
);
5156 oappend (scratchbuf
);
5159 *obufp
++ = close_char
;
5162 else if (intel_syntax
)
5164 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5166 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5167 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5171 oappend (names_seg
[ds_reg
- es_reg
]);
5174 print_operand_value (scratchbuf
, 1, disp
);
5175 oappend (scratchbuf
);
5180 { /* 16 bit address mode */
5187 if ((disp
& 0x8000) != 0)
5192 FETCH_DATA (the_info
, codep
+ 1);
5194 if ((disp
& 0x80) != 0)
5199 if ((disp
& 0x8000) != 0)
5205 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5207 print_displacement (scratchbuf
, disp
);
5208 oappend (scratchbuf
);
5211 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5213 *obufp
++ = open_char
;
5215 oappend (index16
[modrm
.rm
]);
5217 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5219 if ((bfd_signed_vma
) disp
>= 0)
5224 else if (modrm
.mod
!= 1)
5228 disp
= - (bfd_signed_vma
) disp
;
5231 print_displacement (scratchbuf
, disp
);
5232 oappend (scratchbuf
);
5235 *obufp
++ = close_char
;
5238 else if (intel_syntax
)
5240 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5241 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5245 oappend (names_seg
[ds_reg
- es_reg
]);
5248 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
5249 oappend (scratchbuf
);
5255 OP_G (int bytemode
, int sizeflag
)
5266 oappend (names8rex
[modrm
.reg
+ add
]);
5268 oappend (names8
[modrm
.reg
+ add
]);
5271 oappend (names16
[modrm
.reg
+ add
]);
5274 oappend (names32
[modrm
.reg
+ add
]);
5277 oappend (names64
[modrm
.reg
+ add
]);
5286 oappend (names64
[modrm
.reg
+ add
]);
5287 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5288 oappend (names32
[modrm
.reg
+ add
]);
5290 oappend (names16
[modrm
.reg
+ add
]);
5291 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5294 if (address_mode
== mode_64bit
)
5295 oappend (names64
[modrm
.reg
+ add
]);
5297 oappend (names32
[modrm
.reg
+ add
]);
5300 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5313 FETCH_DATA (the_info
, codep
+ 8);
5314 a
= *codep
++ & 0xff;
5315 a
|= (*codep
++ & 0xff) << 8;
5316 a
|= (*codep
++ & 0xff) << 16;
5317 a
|= (*codep
++ & 0xff) << 24;
5318 b
= *codep
++ & 0xff;
5319 b
|= (*codep
++ & 0xff) << 8;
5320 b
|= (*codep
++ & 0xff) << 16;
5321 b
|= (*codep
++ & 0xff) << 24;
5322 x
= a
+ ((bfd_vma
) b
<< 32);
5330 static bfd_signed_vma
5333 bfd_signed_vma x
= 0;
5335 FETCH_DATA (the_info
, codep
+ 4);
5336 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5337 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5338 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5339 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5343 static bfd_signed_vma
5346 bfd_signed_vma x
= 0;
5348 FETCH_DATA (the_info
, codep
+ 4);
5349 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5350 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5351 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5352 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5354 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5364 FETCH_DATA (the_info
, codep
+ 2);
5365 x
= *codep
++ & 0xff;
5366 x
|= (*codep
++ & 0xff) << 8;
5371 set_op (bfd_vma op
, int riprel
)
5373 op_index
[op_ad
] = op_ad
;
5374 if (address_mode
== mode_64bit
)
5376 op_address
[op_ad
] = op
;
5377 op_riprel
[op_ad
] = riprel
;
5381 /* Mask to get a 32-bit address. */
5382 op_address
[op_ad
] = op
& 0xffffffff;
5383 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5388 OP_REG (int code
, int sizeflag
)
5398 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5399 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5400 s
= names16
[code
- ax_reg
+ add
];
5402 case es_reg
: case ss_reg
: case cs_reg
:
5403 case ds_reg
: case fs_reg
: case gs_reg
:
5404 s
= names_seg
[code
- es_reg
+ add
];
5406 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5407 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5410 s
= names8rex
[code
- al_reg
+ add
];
5412 s
= names8
[code
- al_reg
];
5414 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5415 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5416 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5418 s
= names64
[code
- rAX_reg
+ add
];
5421 code
+= eAX_reg
- rAX_reg
;
5423 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5424 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5427 s
= names64
[code
- eAX_reg
+ add
];
5428 else if (sizeflag
& DFLAG
)
5429 s
= names32
[code
- eAX_reg
+ add
];
5431 s
= names16
[code
- eAX_reg
+ add
];
5432 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5435 s
= INTERNAL_DISASSEMBLER_ERROR
;
5442 OP_IMREG (int code
, int sizeflag
)
5454 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5455 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5456 s
= names16
[code
- ax_reg
];
5458 case es_reg
: case ss_reg
: case cs_reg
:
5459 case ds_reg
: case fs_reg
: case gs_reg
:
5460 s
= names_seg
[code
- es_reg
];
5462 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5463 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5466 s
= names8rex
[code
- al_reg
];
5468 s
= names8
[code
- al_reg
];
5470 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5471 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5474 s
= names64
[code
- eAX_reg
];
5475 else if (sizeflag
& DFLAG
)
5476 s
= names32
[code
- eAX_reg
];
5478 s
= names16
[code
- eAX_reg
];
5479 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5482 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5487 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5490 s
= INTERNAL_DISASSEMBLER_ERROR
;
5497 OP_I (int bytemode
, int sizeflag
)
5500 bfd_signed_vma mask
= -1;
5505 FETCH_DATA (the_info
, codep
+ 1);
5510 if (address_mode
== mode_64bit
)
5520 else if (sizeflag
& DFLAG
)
5530 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5541 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5546 scratchbuf
[0] = '$';
5547 print_operand_value (scratchbuf
+ 1, 1, op
);
5548 oappend (scratchbuf
+ intel_syntax
);
5549 scratchbuf
[0] = '\0';
5553 OP_I64 (int bytemode
, int sizeflag
)
5556 bfd_signed_vma mask
= -1;
5558 if (address_mode
!= mode_64bit
)
5560 OP_I (bytemode
, sizeflag
);
5567 FETCH_DATA (the_info
, codep
+ 1);
5575 else if (sizeflag
& DFLAG
)
5585 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5592 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5597 scratchbuf
[0] = '$';
5598 print_operand_value (scratchbuf
+ 1, 1, op
);
5599 oappend (scratchbuf
+ intel_syntax
);
5600 scratchbuf
[0] = '\0';
5604 OP_sI (int bytemode
, int sizeflag
)
5607 bfd_signed_vma mask
= -1;
5612 FETCH_DATA (the_info
, codep
+ 1);
5614 if ((op
& 0x80) != 0)
5622 else if (sizeflag
& DFLAG
)
5631 if ((op
& 0x8000) != 0)
5634 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5639 if ((op
& 0x8000) != 0)
5643 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5647 scratchbuf
[0] = '$';
5648 print_operand_value (scratchbuf
+ 1, 1, op
);
5649 oappend (scratchbuf
+ intel_syntax
);
5653 OP_J (int bytemode
, int sizeflag
)
5657 bfd_vma segment
= 0;
5662 FETCH_DATA (the_info
, codep
+ 1);
5664 if ((disp
& 0x80) != 0)
5668 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5673 if ((disp
& 0x8000) != 0)
5675 /* In 16bit mode, address is wrapped around at 64k within
5676 the same segment. Otherwise, a data16 prefix on a jump
5677 instruction means that the pc is masked to 16 bits after
5678 the displacement is added! */
5680 if ((prefixes
& PREFIX_DATA
) == 0)
5681 segment
= ((start_pc
+ codep
- start_codep
)
5682 & ~((bfd_vma
) 0xffff));
5684 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5687 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5690 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5692 print_operand_value (scratchbuf
, 1, disp
);
5693 oappend (scratchbuf
);
5697 OP_SEG (int bytemode
, int sizeflag
)
5699 if (bytemode
== w_mode
)
5700 oappend (names_seg
[modrm
.reg
]);
5702 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5706 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5710 if (sizeflag
& DFLAG
)
5720 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5722 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5724 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5725 oappend (scratchbuf
);
5729 OP_OFF (int bytemode
, int sizeflag
)
5733 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5734 intel_operand_size (bytemode
, sizeflag
);
5737 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5744 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5745 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5747 oappend (names_seg
[ds_reg
- es_reg
]);
5751 print_operand_value (scratchbuf
, 1, off
);
5752 oappend (scratchbuf
);
5756 OP_OFF64 (int bytemode
, int sizeflag
)
5760 if (address_mode
!= mode_64bit
5761 || (prefixes
& PREFIX_ADDR
))
5763 OP_OFF (bytemode
, sizeflag
);
5767 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5768 intel_operand_size (bytemode
, sizeflag
);
5775 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5776 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5778 oappend (names_seg
[ds_reg
- es_reg
]);
5782 print_operand_value (scratchbuf
, 1, off
);
5783 oappend (scratchbuf
);
5787 ptr_reg (int code
, int sizeflag
)
5791 *obufp
++ = open_char
;
5792 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5793 if (address_mode
== mode_64bit
)
5795 if (!(sizeflag
& AFLAG
))
5796 s
= names32
[code
- eAX_reg
];
5798 s
= names64
[code
- eAX_reg
];
5800 else if (sizeflag
& AFLAG
)
5801 s
= names32
[code
- eAX_reg
];
5803 s
= names16
[code
- eAX_reg
];
5805 *obufp
++ = close_char
;
5810 OP_ESreg (int code
, int sizeflag
)
5816 case 0x6d: /* insw/insl */
5817 intel_operand_size (z_mode
, sizeflag
);
5819 case 0xa5: /* movsw/movsl/movsq */
5820 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5821 case 0xab: /* stosw/stosl */
5822 case 0xaf: /* scasw/scasl */
5823 intel_operand_size (v_mode
, sizeflag
);
5826 intel_operand_size (b_mode
, sizeflag
);
5829 oappend ("%es:" + intel_syntax
);
5830 ptr_reg (code
, sizeflag
);
5834 OP_DSreg (int code
, int sizeflag
)
5840 case 0x6f: /* outsw/outsl */
5841 intel_operand_size (z_mode
, sizeflag
);
5843 case 0xa5: /* movsw/movsl/movsq */
5844 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5845 case 0xad: /* lodsw/lodsl/lodsq */
5846 intel_operand_size (v_mode
, sizeflag
);
5849 intel_operand_size (b_mode
, sizeflag
);
5859 prefixes
|= PREFIX_DS
;
5861 ptr_reg (code
, sizeflag
);
5865 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5873 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5876 used_prefixes
|= PREFIX_LOCK
;
5879 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5880 oappend (scratchbuf
+ intel_syntax
);
5884 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5891 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5893 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5894 oappend (scratchbuf
);
5898 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5900 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5901 oappend (scratchbuf
+ intel_syntax
);
5905 OP_R (int bytemode
, int sizeflag
)
5908 OP_E (bytemode
, sizeflag
);
5914 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5916 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5917 if (prefixes
& PREFIX_DATA
)
5923 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5926 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5927 oappend (scratchbuf
+ intel_syntax
);
5931 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5937 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5938 oappend (scratchbuf
+ intel_syntax
);
5942 OP_EM (int bytemode
, int sizeflag
)
5946 if (intel_syntax
&& bytemode
== v_mode
)
5948 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5949 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5951 OP_E (bytemode
, sizeflag
);
5955 /* Skip mod/rm byte. */
5958 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5959 if (prefixes
& PREFIX_DATA
)
5966 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5969 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5970 oappend (scratchbuf
+ intel_syntax
);
5973 /* cvt* are the only instructions in sse2 which have
5974 both SSE and MMX operands and also have 0x66 prefix
5975 in their opcode. 0x66 was originally used to differentiate
5976 between SSE and MMX instruction(operands). So we have to handle the
5977 cvt* separately using OP_EMC and OP_MXC */
5979 OP_EMC (int bytemode
, int sizeflag
)
5983 if (intel_syntax
&& bytemode
== v_mode
)
5985 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5986 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5988 OP_E (bytemode
, sizeflag
);
5992 /* Skip mod/rm byte. */
5995 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5996 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5997 oappend (scratchbuf
+ intel_syntax
);
6001 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6003 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6004 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
6005 oappend (scratchbuf
+ intel_syntax
);
6009 OP_EX (int bytemode
, int sizeflag
)
6014 OP_E (bytemode
, sizeflag
);
6021 /* Skip mod/rm byte. */
6024 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
6025 oappend (scratchbuf
+ intel_syntax
);
6029 OP_MS (int bytemode
, int sizeflag
)
6032 OP_EM (bytemode
, sizeflag
);
6038 OP_XS (int bytemode
, int sizeflag
)
6041 OP_EX (bytemode
, sizeflag
);
6047 OP_M (int bytemode
, int sizeflag
)
6050 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
6053 OP_E (bytemode
, sizeflag
);
6057 OP_0f07 (int bytemode
, int sizeflag
)
6059 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
6062 OP_E (bytemode
, sizeflag
);
6065 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6066 32bit mode and "xchg %rax,%rax" in 64bit mode. */
6069 NOP_Fixup1 (int bytemode
, int sizeflag
)
6071 if ((prefixes
& PREFIX_DATA
) != 0
6074 && address_mode
== mode_64bit
))
6075 OP_REG (bytemode
, sizeflag
);
6077 strcpy (obuf
, "nop");
6081 NOP_Fixup2 (int bytemode
, int sizeflag
)
6083 if ((prefixes
& PREFIX_DATA
) != 0
6086 && address_mode
== mode_64bit
))
6087 OP_IMREG (bytemode
, sizeflag
);
6090 static const char *const Suffix3DNow
[] = {
6091 /* 00 */ NULL
, NULL
, NULL
, NULL
,
6092 /* 04 */ NULL
, NULL
, NULL
, NULL
,
6093 /* 08 */ NULL
, NULL
, NULL
, NULL
,
6094 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
6095 /* 10 */ NULL
, NULL
, NULL
, NULL
,
6096 /* 14 */ NULL
, NULL
, NULL
, NULL
,
6097 /* 18 */ NULL
, NULL
, NULL
, NULL
,
6098 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
6099 /* 20 */ NULL
, NULL
, NULL
, NULL
,
6100 /* 24 */ NULL
, NULL
, NULL
, NULL
,
6101 /* 28 */ NULL
, NULL
, NULL
, NULL
,
6102 /* 2C */ NULL
, NULL
, NULL
, NULL
,
6103 /* 30 */ NULL
, NULL
, NULL
, NULL
,
6104 /* 34 */ NULL
, NULL
, NULL
, NULL
,
6105 /* 38 */ NULL
, NULL
, NULL
, NULL
,
6106 /* 3C */ NULL
, NULL
, NULL
, NULL
,
6107 /* 40 */ NULL
, NULL
, NULL
, NULL
,
6108 /* 44 */ NULL
, NULL
, NULL
, NULL
,
6109 /* 48 */ NULL
, NULL
, NULL
, NULL
,
6110 /* 4C */ NULL
, NULL
, NULL
, NULL
,
6111 /* 50 */ NULL
, NULL
, NULL
, NULL
,
6112 /* 54 */ NULL
, NULL
, NULL
, NULL
,
6113 /* 58 */ NULL
, NULL
, NULL
, NULL
,
6114 /* 5C */ NULL
, NULL
, NULL
, NULL
,
6115 /* 60 */ NULL
, NULL
, NULL
, NULL
,
6116 /* 64 */ NULL
, NULL
, NULL
, NULL
,
6117 /* 68 */ NULL
, NULL
, NULL
, NULL
,
6118 /* 6C */ NULL
, NULL
, NULL
, NULL
,
6119 /* 70 */ NULL
, NULL
, NULL
, NULL
,
6120 /* 74 */ NULL
, NULL
, NULL
, NULL
,
6121 /* 78 */ NULL
, NULL
, NULL
, NULL
,
6122 /* 7C */ NULL
, NULL
, NULL
, NULL
,
6123 /* 80 */ NULL
, NULL
, NULL
, NULL
,
6124 /* 84 */ NULL
, NULL
, NULL
, NULL
,
6125 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
6126 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
6127 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
6128 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
6129 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
6130 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
6131 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
6132 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
6133 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
6134 /* AC */ NULL
, NULL
, "pfacc", NULL
,
6135 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
6136 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
6137 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
6138 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6139 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6140 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6141 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6142 /* CC */ NULL
, NULL
, NULL
, NULL
,
6143 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6144 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6145 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6146 /* DC */ NULL
, NULL
, NULL
, NULL
,
6147 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6148 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6149 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6150 /* EC */ NULL
, NULL
, NULL
, NULL
,
6151 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6152 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6153 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6154 /* FC */ NULL
, NULL
, NULL
, NULL
,
6158 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6160 const char *mnemonic
;
6162 FETCH_DATA (the_info
, codep
+ 1);
6163 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6164 place where an 8-bit immediate would normally go. ie. the last
6165 byte of the instruction. */
6166 obufp
= obuf
+ strlen (obuf
);
6167 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6172 /* Since a variable sized modrm/sib chunk is between the start
6173 of the opcode (0x0f0f) and the opcode suffix, we need to do
6174 all the modrm processing first, and don't know until now that
6175 we have a bad opcode. This necessitates some cleaning up. */
6176 op_out
[0][0] = '\0';
6177 op_out
[1][0] = '\0';
6182 static const char *simd_cmp_op
[] = {
6194 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6196 unsigned int cmp_type
;
6198 FETCH_DATA (the_info
, codep
+ 1);
6199 obufp
= obuf
+ strlen (obuf
);
6200 cmp_type
= *codep
++ & 0xff;
6203 char suffix1
= 'p', suffix2
= 's';
6204 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6205 if (prefixes
& PREFIX_REPZ
)
6209 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6210 if (prefixes
& PREFIX_DATA
)
6214 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6215 if (prefixes
& PREFIX_REPNZ
)
6216 suffix1
= 's', suffix2
= 'd';
6219 sprintf (scratchbuf
, "cmp%s%c%c",
6220 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6221 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6222 oappend (scratchbuf
);
6226 /* We have a bad extension byte. Clean up. */
6227 op_out
[0][0] = '\0';
6228 op_out
[1][0] = '\0';
6234 OP_Mwait (int bytemode ATTRIBUTE_UNUSED
,
6235 int sizeflag ATTRIBUTE_UNUSED
)
6237 /* mwait %eax,%ecx */
6240 const char **names
= (address_mode
== mode_64bit
6241 ? names64
: names32
);
6242 strcpy (op_out
[0], names
[0]);
6243 strcpy (op_out
[1], names
[1]);
6246 /* Skip mod/rm byte. */
6252 OP_Monitor (int bytemode ATTRIBUTE_UNUSED
,
6253 int sizeflag ATTRIBUTE_UNUSED
)
6255 /* monitor %eax,%ecx,%edx" */
6258 const char **op1_names
;
6259 const char **names
= (address_mode
== mode_64bit
6260 ? names64
: names32
);
6262 if (!(prefixes
& PREFIX_ADDR
))
6263 op1_names
= (address_mode
== mode_16bit
6267 /* Remove "addr16/addr32". */
6269 op1_names
= (address_mode
!= mode_32bit
6270 ? names32
: names16
);
6271 used_prefixes
|= PREFIX_ADDR
;
6273 strcpy (op_out
[0], op1_names
[0]);
6274 strcpy (op_out
[1], names
[1]);
6275 strcpy (op_out
[2], names
[2]);
6278 /* Skip mod/rm byte. */
6284 SVME_Fixup (int bytemode
, int sizeflag
)
6316 OP_M (bytemode
, sizeflag
);
6319 /* Override "lidt". */
6320 p
= obuf
+ strlen (obuf
) - 4;
6321 /* We might have a suffix. */
6325 if (!(prefixes
& PREFIX_ADDR
))
6330 used_prefixes
|= PREFIX_ADDR
;
6334 strcpy (op_out
[1], names32
[1]);
6340 *obufp
++ = open_char
;
6341 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6345 strcpy (obufp
, alt
);
6346 obufp
+= strlen (alt
);
6347 *obufp
++ = close_char
;
6354 INVLPG_Fixup (int bytemode
, int sizeflag
)
6367 OP_M (bytemode
, sizeflag
);
6370 /* Override "invlpg". */
6371 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6378 /* Throw away prefixes and 1st. opcode byte. */
6379 codep
= insn_codep
+ 1;
6384 REP_Fixup (int bytemode
, int sizeflag
)
6386 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6388 if (prefixes
& PREFIX_REPZ
)
6389 repz_prefix
= "rep ";
6396 OP_IMREG (bytemode
, sizeflag
);
6399 OP_ESreg (bytemode
, sizeflag
);
6402 OP_DSreg (bytemode
, sizeflag
);
6411 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6416 /* Change cmpxchg8b to cmpxchg16b. */
6417 char *p
= obuf
+ strlen (obuf
) - 2;
6421 OP_M (bytemode
, sizeflag
);
6425 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6427 sprintf (scratchbuf
, "%%xmm%d", reg
);
6428 oappend (scratchbuf
+ intel_syntax
);
6432 CRC32_Fixup (int bytemode
, int sizeflag
)
6434 /* Add proper suffix to "crc32". */
6435 char *p
= obuf
+ strlen (obuf
);
6452 else if (sizeflag
& DFLAG
)
6456 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6459 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6468 /* Skip mod/rm byte. */
6473 add
= (rex
& REX_B
) ? 8 : 0;
6474 if (bytemode
== b_mode
)
6478 oappend (names8rex
[modrm
.rm
+ add
]);
6480 oappend (names8
[modrm
.rm
+ add
]);
6486 oappend (names64
[modrm
.rm
+ add
]);
6487 else if ((prefixes
& PREFIX_DATA
))
6488 oappend (names16
[modrm
.rm
+ add
]);
6490 oappend (names32
[modrm
.rm
+ add
]);
6494 OP_E (bytemode
, sizeflag
);