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 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
37 #include "opcode/i386.h"
41 static int fetch_data (struct disassemble_info *, bfd_byte *);
42 static void ckprefix (void);
43 static const char *prefix_name (int, int);
44 static int print_insn (bfd_vma, disassemble_info *);
45 static void dofloat (int);
46 static void OP_ST (int, int);
47 static void OP_STi (int, int);
48 static int putop (const char *, int);
49 static void oappend (const char *);
50 static void append_seg (void);
51 static void OP_indirE (int, int);
52 static void print_operand_value (char *, int, bfd_vma);
53 static void print_displacement (char *, bfd_vma);
54 static void OP_E (int, int);
55 static void OP_G (int, int);
56 static bfd_vma get64 (void);
57 static bfd_signed_vma get32 (void);
58 static bfd_signed_vma get32s (void);
59 static int get16 (void);
60 static void set_op (bfd_vma, int);
61 static void OP_REG (int, int);
62 static void OP_IMREG (int, int);
63 static void OP_I (int, int);
64 static void OP_I64 (int, int);
65 static void OP_sI (int, int);
66 static void OP_J (int, int);
67 static void OP_SEG (int, int);
68 static void OP_DIR (int, int);
69 static void OP_OFF (int, int);
70 static void OP_OFF64 (int, int);
71 static void ptr_reg (int, int);
72 static void OP_ESreg (int, int);
73 static void OP_DSreg (int, int);
74 static void OP_C (int, int);
75 static void OP_D (int, int);
76 static void OP_T (int, int);
77 static void OP_R (int, int);
78 static void OP_MMX (int, int);
79 static void OP_XMM (int, int);
80 static void OP_EM (int, int);
81 static void OP_EX (int, int);
82 static void OP_EMC (int,int);
83 static void OP_MXC (int,int);
84 static void OP_MS (int, int);
85 static void OP_XS (int, int);
86 static void OP_M (int, int);
87 static void OP_VMX (int, int);
88 static void OP_0fae (int, int);
89 static void OP_0f07 (int, int);
90 static void NOP_Fixup1 (int, int);
91 static void NOP_Fixup2 (int, int);
92 static void OP_3DNowSuffix (int, int);
93 static void OP_SIMD_Suffix (int, int);
94 static void SIMD_Fixup (int, int);
95 static void PNI_Fixup (int, int);
96 static void XCR_Fixup (int, int);
97 static void SVME_Fixup (int, int);
98 static void INVLPG_Fixup (int, int);
99 static void BadOp (void);
100 static void VMX_Fixup (int, int);
101 static void REP_Fixup (int, int);
102 static void CMPXCHG8B_Fixup (int, int);
103 static void XMM_Fixup (int, int);
104 static void CRC32_Fixup (int, int);
107 /* Points to first byte not fetched. */
108 bfd_byte *max_fetched;
109 bfd_byte the_buffer[MAX_MNEM_SIZE];
122 enum address_mode address_mode;
124 /* Flags for the prefixes for the current instruction. See below. */
127 /* REX prefix the current instruction. See below. */
129 /* Bits of REX we've already used. */
131 /* Mark parts used in the REX prefix. When we are testing for
132 empty prefix (for 8bit register REX extension), just mask it
133 out. Otherwise test for REX bit is excuse for existence of REX
134 only in case value is nonzero. */
135 #define USED_REX(value) \
140 rex_used |= (value) | REX_OPCODE; \
143 rex_used |= REX_OPCODE; \
146 /* Flags for prefixes which we somehow handled when printing the
147 current instruction. */
148 static int used_prefixes;
150 /* Flags stored in PREFIXES. */
151 #define PREFIX_REPZ 1
152 #define PREFIX_REPNZ 2
153 #define PREFIX_LOCK 4
155 #define PREFIX_SS 0x10
156 #define PREFIX_DS 0x20
157 #define PREFIX_ES 0x40
158 #define PREFIX_FS 0x80
159 #define PREFIX_GS 0x100
160 #define PREFIX_DATA 0x200
161 #define PREFIX_ADDR 0x400
162 #define PREFIX_FWAIT 0x800
164 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
165 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
167 #define FETCH_DATA(info, addr) \
168 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
169 ? 1 : fetch_data ((info), (addr)))
172 fetch_data (struct disassemble_info *info, bfd_byte *addr)
175 struct dis_private *priv = (struct dis_private *) info->private_data;
176 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
178 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
179 status = (*info->read_memory_func) (start,
181 addr - priv->max_fetched,
187 /* If we did manage to read at least one byte, then
188 print_insn_i386 will do something sensible. Otherwise, print
189 an error. We do that here because this is where we know
191 if (priv->max_fetched == priv->the_buffer)
192 (*info->memory_error_func) (status, start, info);
193 longjmp (priv->bailout, 1);
196 priv->max_fetched = addr;
200 #define XX { NULL, 0 }
202 #define Eb { OP_E, b_mode }
203 #define Ev { OP_E, v_mode }
204 #define Ed { OP_E, d_mode }
205 #define Edq { OP_E, dq_mode }
206 #define Edqw { OP_E, dqw_mode }
207 #define Edqb { OP_E, dqb_mode }
208 #define Edqd { OP_E, dqd_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 Mo { OP_M, o_mode }
217 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
218 #define Mq { OP_M, q_mode }
219 #define Gb { OP_G, b_mode }
220 #define Gv { OP_G, v_mode }
221 #define Gd { OP_G, d_mode }
222 #define Gdq { OP_G, dq_mode }
223 #define Gm { OP_G, m_mode }
224 #define Gw { OP_G, w_mode }
225 #define Rd { OP_R, d_mode }
226 #define Rm { OP_R, m_mode }
227 #define Ib { OP_I, b_mode }
228 #define sIb { OP_sI, b_mode } /* sign extened byte */
229 #define Iv { OP_I, v_mode }
230 #define Iq { OP_I, q_mode }
231 #define Iv64 { OP_I64, v_mode }
232 #define Iw { OP_I, w_mode }
233 #define I1 { OP_I, const_1_mode }
234 #define Jb { OP_J, b_mode }
235 #define Jv { OP_J, v_mode }
236 #define Cm { OP_C, m_mode }
237 #define Dm { OP_D, m_mode }
238 #define Td { OP_T, d_mode }
240 #define RMeAX { OP_REG, eAX_reg }
241 #define RMeBX { OP_REG, eBX_reg }
242 #define RMeCX { OP_REG, eCX_reg }
243 #define RMeDX { OP_REG, eDX_reg }
244 #define RMeSP { OP_REG, eSP_reg }
245 #define RMeBP { OP_REG, eBP_reg }
246 #define RMeSI { OP_REG, eSI_reg }
247 #define RMeDI { OP_REG, eDI_reg }
248 #define RMrAX { OP_REG, rAX_reg }
249 #define RMrBX { OP_REG, rBX_reg }
250 #define RMrCX { OP_REG, rCX_reg }
251 #define RMrDX { OP_REG, rDX_reg }
252 #define RMrSP { OP_REG, rSP_reg }
253 #define RMrBP { OP_REG, rBP_reg }
254 #define RMrSI { OP_REG, rSI_reg }
255 #define RMrDI { OP_REG, rDI_reg }
256 #define RMAL { OP_REG, al_reg }
257 #define RMAL { OP_REG, al_reg }
258 #define RMCL { OP_REG, cl_reg }
259 #define RMDL { OP_REG, dl_reg }
260 #define RMBL { OP_REG, bl_reg }
261 #define RMAH { OP_REG, ah_reg }
262 #define RMCH { OP_REG, ch_reg }
263 #define RMDH { OP_REG, dh_reg }
264 #define RMBH { OP_REG, bh_reg }
265 #define RMAX { OP_REG, ax_reg }
266 #define RMDX { OP_REG, dx_reg }
268 #define eAX { OP_IMREG, eAX_reg }
269 #define eBX { OP_IMREG, eBX_reg }
270 #define eCX { OP_IMREG, eCX_reg }
271 #define eDX { OP_IMREG, eDX_reg }
272 #define eSP { OP_IMREG, eSP_reg }
273 #define eBP { OP_IMREG, eBP_reg }
274 #define eSI { OP_IMREG, eSI_reg }
275 #define eDI { OP_IMREG, eDI_reg }
276 #define AL { OP_IMREG, al_reg }
277 #define CL { OP_IMREG, cl_reg }
278 #define DL { OP_IMREG, dl_reg }
279 #define BL { OP_IMREG, bl_reg }
280 #define AH { OP_IMREG, ah_reg }
281 #define CH { OP_IMREG, ch_reg }
282 #define DH { OP_IMREG, dh_reg }
283 #define BH { OP_IMREG, bh_reg }
284 #define AX { OP_IMREG, ax_reg }
285 #define DX { OP_IMREG, dx_reg }
286 #define zAX { OP_IMREG, z_mode_ax_reg }
287 #define indirDX { OP_IMREG, indir_dx_reg }
289 #define Sw { OP_SEG, w_mode }
290 #define Sv { OP_SEG, v_mode }
291 #define Ap { OP_DIR, 0 }
292 #define Ob { OP_OFF64, b_mode }
293 #define Ov { OP_OFF64, v_mode }
294 #define Xb { OP_DSreg, eSI_reg }
295 #define Xv { OP_DSreg, eSI_reg }
296 #define Xz { OP_DSreg, eSI_reg }
297 #define Yb { OP_ESreg, eDI_reg }
298 #define Yv { OP_ESreg, eDI_reg }
299 #define DSBX { OP_DSreg, eBX_reg }
301 #define es { OP_REG, es_reg }
302 #define ss { OP_REG, ss_reg }
303 #define cs { OP_REG, cs_reg }
304 #define ds { OP_REG, ds_reg }
305 #define fs { OP_REG, fs_reg }
306 #define gs { OP_REG, gs_reg }
308 #define MX { OP_MMX, 0 }
309 #define XM { OP_XMM, 0 }
310 #define EM { OP_EM, v_mode }
311 #define EMd { OP_EM, d_mode }
312 #define EMq { OP_EM, q_mode }
313 #define EXd { OP_EX, d_mode }
314 #define EXq { OP_EX, q_mode }
315 #define EXx { OP_EX, x_mode }
316 #define MS { OP_MS, v_mode }
317 #define XS { OP_XS, v_mode }
318 #define EMC { OP_EMC, v_mode }
319 #define MXC { OP_MXC, 0 }
320 #define VM { OP_VMX, q_mode }
321 #define OPSUF { OP_3DNowSuffix, 0 }
322 #define OPSIMD { OP_SIMD_Suffix, 0 }
323 #define XMM0 { XMM_Fixup, 0 }
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr { REP_Fixup, eSI_reg }
327 #define Xvr { REP_Fixup, eSI_reg }
328 #define Ybr { REP_Fixup, eDI_reg }
329 #define Yvr { REP_Fixup, eDI_reg }
330 #define Yzr { REP_Fixup, eDI_reg }
331 #define indirDXr { REP_Fixup, indir_dx_reg }
332 #define ALr { REP_Fixup, al_reg }
333 #define eAXr { REP_Fixup, eAX_reg }
335 #define cond_jump_flag { NULL, cond_jump_mode }
336 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
359 #define o_mode 17 /* 16-byte operand */
360 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
361 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
406 #define z_mode_ax_reg 149
407 #define indir_dx_reg 150
411 #define USE_PREFIX_USER_TABLE 3
412 #define X86_64_SPECIAL 4
413 #define IS_3BYTE_OPCODE 5
415 #define FLOAT NULL, { { NULL, FLOATCODE } }
417 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
418 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
419 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
420 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
421 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
422 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
423 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
424 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
425 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
426 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
427 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
428 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
429 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
430 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
431 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
432 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
433 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
434 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
435 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
436 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
437 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
438 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
439 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
440 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
441 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
442 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
443 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
444 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
446 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
447 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
448 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
449 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
450 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
451 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
452 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
453 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
454 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
455 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
456 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
457 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
458 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
459 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
460 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
461 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
462 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
463 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
464 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
465 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
466 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
467 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
468 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
469 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
470 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
471 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
472 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
473 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
474 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
475 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
476 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
477 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
478 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
479 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
480 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
481 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
482 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
483 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
484 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
485 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
486 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
487 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
488 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
489 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
490 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
491 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
492 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
493 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
494 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
495 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
496 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
497 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
498 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
499 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
500 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
501 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
502 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
503 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
504 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
505 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
506 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
507 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
508 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
509 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
510 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
511 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
512 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
513 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
514 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
515 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
516 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
517 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
518 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
519 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
520 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
521 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
522 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
523 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
524 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
525 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
526 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
527 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
528 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
529 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
530 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
531 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
532 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
533 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
534 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
535 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
536 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
537 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
538 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
539 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
540 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
541 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
542 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
543 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
544 #define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
545 #define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
548 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
549 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
550 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
551 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
553 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
554 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
556 typedef void (*op_rtn) (int bytemode, int sizeflag);
567 /* Upper case letters in the instruction names here are macros.
568 'A' => print 'b' if no register operands or suffix_always is true
569 'B' => print 'b' if suffix_always is true
570 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
572 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
573 . suffix_always is true
574 'E' => print 'e' if 32-bit form of jcxz
575 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
576 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
577 'H' => print ",pt" or ",pn" branch hint
578 'I' => honor following macro letter even in Intel mode (implemented only
579 . for some of the macro letters)
581 'K' => print 'd' or 'q' if rex prefix is present.
582 'L' => print 'l' if suffix_always is true
583 'N' => print 'n' if instruction has no wait "prefix"
584 'O' => print 'd' or 'o' (or 'q' in Intel mode)
585 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
586 . or suffix_always is true. print 'q' if rex prefix is present.
587 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
589 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
590 'S' => print 'w', 'l' or 'q' if suffix_always is true
591 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
592 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
593 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
594 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
595 'X' => print 's', 'd' depending on data16 prefix (for XMM)
596 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
597 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
599 Many of the above letters print nothing in Intel mode. See "putop"
602 Braces '{' and '}', and vertical bars '|', indicate alternative
603 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
604 modes. In cases where there are only two alternatives, the X86_64
605 instruction is reserved, and "(bad)" is printed.
608 static const struct dis386 dis386[] = {
610 { "addB", { Eb, Gb } },
611 { "addS", { Ev, Gv } },
612 { "addB", { Gb, Eb } },
613 { "addS", { Gv, Ev } },
614 { "addB", { AL, Ib } },
615 { "addS", { eAX, Iv } },
616 { "push{T|}", { es } },
617 { "pop{T|}", { es } },
619 { "orB", { Eb, Gb } },
620 { "orS", { Ev, Gv } },
621 { "orB", { Gb, Eb } },
622 { "orS", { Gv, Ev } },
623 { "orB", { AL, Ib } },
624 { "orS", { eAX, Iv } },
625 { "push{T|}", { cs } },
626 { "(bad)", { XX } }, /* 0x0f extended opcode escape */
628 { "adcB", { Eb, Gb } },
629 { "adcS", { Ev, Gv } },
630 { "adcB", { Gb, Eb } },
631 { "adcS", { Gv, Ev } },
632 { "adcB", { AL, Ib } },
633 { "adcS", { eAX, Iv } },
634 { "push{T|}", { ss } },
635 { "pop{T|}", { ss } },
637 { "sbbB", { Eb, Gb } },
638 { "sbbS", { Ev, Gv } },
639 { "sbbB", { Gb, Eb } },
640 { "sbbS", { Gv, Ev } },
641 { "sbbB", { AL, Ib } },
642 { "sbbS", { eAX, Iv } },
643 { "push{T|}", { ds } },
644 { "pop{T|}", { ds } },
646 { "andB", { Eb, Gb } },
647 { "andS", { Ev, Gv } },
648 { "andB", { Gb, Eb } },
649 { "andS", { Gv, Ev } },
650 { "andB", { AL, Ib } },
651 { "andS", { eAX, Iv } },
652 { "(bad)", { XX } }, /* SEG ES prefix */
653 { "daa{|}", { XX } },
655 { "subB", { Eb, Gb } },
656 { "subS", { Ev, Gv } },
657 { "subB", { Gb, Eb } },
658 { "subS", { Gv, Ev } },
659 { "subB", { AL, Ib } },
660 { "subS", { eAX, Iv } },
661 { "(bad)", { XX } }, /* SEG CS prefix */
662 { "das{|}", { XX } },
664 { "xorB", { Eb, Gb } },
665 { "xorS", { Ev, Gv } },
666 { "xorB", { Gb, Eb } },
667 { "xorS", { Gv, Ev } },
668 { "xorB", { AL, Ib } },
669 { "xorS", { eAX, Iv } },
670 { "(bad)", { XX } }, /* SEG SS prefix */
671 { "aaa{|}", { XX } },
673 { "cmpB", { Eb, Gb } },
674 { "cmpS", { Ev, Gv } },
675 { "cmpB", { Gb, Eb } },
676 { "cmpS", { Gv, Ev } },
677 { "cmpB", { AL, Ib } },
678 { "cmpS", { eAX, Iv } },
679 { "(bad)", { XX } }, /* SEG DS prefix */
680 { "aas{|}", { XX } },
682 { "inc{S|}", { RMeAX } },
683 { "inc{S|}", { RMeCX } },
684 { "inc{S|}", { RMeDX } },
685 { "inc{S|}", { RMeBX } },
686 { "inc{S|}", { RMeSP } },
687 { "inc{S|}", { RMeBP } },
688 { "inc{S|}", { RMeSI } },
689 { "inc{S|}", { RMeDI } },
691 { "dec{S|}", { RMeAX } },
692 { "dec{S|}", { RMeCX } },
693 { "dec{S|}", { RMeDX } },
694 { "dec{S|}", { RMeBX } },
695 { "dec{S|}", { RMeSP } },
696 { "dec{S|}", { RMeBP } },
697 { "dec{S|}", { RMeSI } },
698 { "dec{S|}", { RMeDI } },
700 { "pushV", { RMrAX } },
701 { "pushV", { RMrCX } },
702 { "pushV", { RMrDX } },
703 { "pushV", { RMrBX } },
704 { "pushV", { RMrSP } },
705 { "pushV", { RMrBP } },
706 { "pushV", { RMrSI } },
707 { "pushV", { RMrDI } },
709 { "popV", { RMrAX } },
710 { "popV", { RMrCX } },
711 { "popV", { RMrDX } },
712 { "popV", { RMrBX } },
713 { "popV", { RMrSP } },
714 { "popV", { RMrBP } },
715 { "popV", { RMrSI } },
716 { "popV", { RMrDI } },
722 { "(bad)", { XX } }, /* seg fs */
723 { "(bad)", { XX } }, /* seg gs */
724 { "(bad)", { XX } }, /* op size prefix */
725 { "(bad)", { XX } }, /* adr size prefix */
728 { "imulS", { Gv, Ev, Iv } },
729 { "pushT", { sIb } },
730 { "imulS", { Gv, Ev, sIb } },
731 { "ins{b||b|}", { Ybr, indirDX } },
732 { "ins{R||G|}", { Yzr, indirDX } },
733 { "outs{b||b|}", { indirDXr, Xb } },
734 { "outs{R||G|}", { indirDXr, Xz } },
736 { "joH", { Jb, XX, cond_jump_flag } },
737 { "jnoH", { Jb, XX, cond_jump_flag } },
738 { "jbH", { Jb, XX, cond_jump_flag } },
739 { "jaeH", { Jb, XX, cond_jump_flag } },
740 { "jeH", { Jb, XX, cond_jump_flag } },
741 { "jneH", { Jb, XX, cond_jump_flag } },
742 { "jbeH", { Jb, XX, cond_jump_flag } },
743 { "jaH", { Jb, XX, cond_jump_flag } },
745 { "jsH", { Jb, XX, cond_jump_flag } },
746 { "jnsH", { Jb, XX, cond_jump_flag } },
747 { "jpH", { Jb, XX, cond_jump_flag } },
748 { "jnpH", { Jb, XX, cond_jump_flag } },
749 { "jlH", { Jb, XX, cond_jump_flag } },
750 { "jgeH", { Jb, XX, cond_jump_flag } },
751 { "jleH", { Jb, XX, cond_jump_flag } },
752 { "jgH", { Jb, XX, cond_jump_flag } },
758 { "testB", { Eb, Gb } },
759 { "testS", { Ev, Gv } },
760 { "xchgB", { Eb, Gb } },
761 { "xchgS", { Ev, Gv } },
763 { "movB", { Eb, Gb } },
764 { "movS", { Ev, Gv } },
765 { "movB", { Gb, Eb } },
766 { "movS", { Gv, Ev } },
767 { "movD", { Sv, Sw } },
768 { "leaS", { Gv, M } },
769 { "movD", { Sw, Sv } },
773 { "xchgS", { RMeCX, eAX } },
774 { "xchgS", { RMeDX, eAX } },
775 { "xchgS", { RMeBX, eAX } },
776 { "xchgS", { RMeSP, eAX } },
777 { "xchgS", { RMeBP, eAX } },
778 { "xchgS", { RMeSI, eAX } },
779 { "xchgS", { RMeDI, eAX } },
781 { "cW{t||t|}R", { XX } },
782 { "cR{t||t|}O", { XX } },
783 { "Jcall{T|}", { Ap } },
784 { "(bad)", { XX } }, /* fwait */
785 { "pushfT", { XX } },
787 { "sahf{|}", { XX } },
788 { "lahf{|}", { XX } },
790 { "movB", { AL, Ob } },
791 { "movS", { eAX, Ov } },
792 { "movB", { Ob, AL } },
793 { "movS", { Ov, eAX } },
794 { "movs{b||b|}", { Ybr, Xb } },
795 { "movs{R||R|}", { Yvr, Xv } },
796 { "cmps{b||b|}", { Xb, Yb } },
797 { "cmps{R||R|}", { Xv, Yv } },
799 { "testB", { AL, Ib } },
800 { "testS", { eAX, Iv } },
801 { "stosB", { Ybr, AL } },
802 { "stosS", { Yvr, eAX } },
803 { "lodsB", { ALr, Xb } },
804 { "lodsS", { eAXr, Xv } },
805 { "scasB", { AL, Yb } },
806 { "scasS", { eAX, Yv } },
808 { "movB", { RMAL, Ib } },
809 { "movB", { RMCL, Ib } },
810 { "movB", { RMDL, Ib } },
811 { "movB", { RMBL, Ib } },
812 { "movB", { RMAH, Ib } },
813 { "movB", { RMCH, Ib } },
814 { "movB", { RMDH, Ib } },
815 { "movB", { RMBH, Ib } },
817 { "movS", { RMeAX, Iv64 } },
818 { "movS", { RMeCX, Iv64 } },
819 { "movS", { RMeDX, Iv64 } },
820 { "movS", { RMeBX, Iv64 } },
821 { "movS", { RMeSP, Iv64 } },
822 { "movS", { RMeBP, Iv64 } },
823 { "movS", { RMeSI, Iv64 } },
824 { "movS", { RMeDI, Iv64 } },
830 { "les{S|}", { Gv, Mp } },
831 { "ldsS", { Gv, Mp } },
835 { "enterT", { Iw, Ib } },
836 { "leaveT", { XX } },
841 { "into{|}", { XX } },
848 { "aam{|}", { sIb } },
849 { "aad{|}", { sIb } },
851 { "xlat", { DSBX } },
862 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
863 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
864 { "loopFH", { Jb, XX, loop_jcxz_flag } },
865 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
866 { "inB", { AL, Ib } },
867 { "inG", { zAX, Ib } },
868 { "outB", { Ib, AL } },
869 { "outG", { Ib, zAX } },
873 { "Jjmp{T|}", { Ap } },
875 { "inB", { AL, indirDX } },
876 { "inG", { zAX, indirDX } },
877 { "outB", { indirDX, AL } },
878 { "outG", { indirDX, zAX } },
880 { "(bad)", { XX } }, /* lock prefix */
882 { "(bad)", { XX } }, /* repne */
883 { "(bad)", { XX } }, /* repz */
899 static const struct dis386 dis386_twobyte[] = {
903 { "larS", { Gv, Ew } },
904 { "lslS", { Gv, Ew } },
906 { "syscall", { XX } },
908 { "sysretP", { XX } },
911 { "wbinvd", { XX } },
917 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
922 { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } },
923 { "unpcklpX", { XM, EXq } },
924 { "unpckhpX", { XM, EXq } },
926 { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } },
937 { "movZ", { Rm, Cm } },
938 { "movZ", { Rm, Dm } },
939 { "movZ", { Cm, Rm } },
940 { "movZ", { Dm, Rm } },
941 { "movL", { Rd, Td } },
943 { "movL", { Td, Rd } },
946 { "movapX", { XM, EXx } },
947 { "movapX", { EXx, XM } },
959 { "sysenter", { XX } },
960 { "sysexit", { XX } },
973 { "cmovo", { Gv, Ev } },
974 { "cmovno", { Gv, Ev } },
975 { "cmovb", { Gv, Ev } },
976 { "cmovae", { Gv, Ev } },
977 { "cmove", { Gv, Ev } },
978 { "cmovne", { Gv, Ev } },
979 { "cmovbe", { Gv, Ev } },
980 { "cmova", { Gv, Ev } },
982 { "cmovs", { Gv, Ev } },
983 { "cmovns", { Gv, Ev } },
984 { "cmovp", { Gv, Ev } },
985 { "cmovnp", { Gv, Ev } },
986 { "cmovl", { Gv, Ev } },
987 { "cmovge", { Gv, Ev } },
988 { "cmovle", { Gv, Ev } },
989 { "cmovg", { Gv, Ev } },
991 { "movmskpX", { Gdq, XS } },
995 { "andpX", { XM, EXx } },
996 { "andnpX", { XM, EXx } },
997 { "orpX", { XM, EXx } },
998 { "xorpX", { XM, EXx } },
1012 { "packsswb", { MX, EM } },
1013 { "pcmpgtb", { MX, EM } },
1014 { "pcmpgtw", { MX, EM } },
1015 { "pcmpgtd", { MX, EM } },
1016 { "packuswb", { MX, EM } },
1018 { "punpckhbw", { MX, EM } },
1019 { "punpckhwd", { MX, EM } },
1020 { "punpckhdq", { MX, EM } },
1021 { "packssdw", { MX, EM } },
1024 { "movd", { MX, Edq } },
1031 { "pcmpeqb", { MX, EM } },
1032 { "pcmpeqw", { MX, EM } },
1033 { "pcmpeqd", { MX, EM } },
1038 { "(bad)", { XX } },
1039 { "(bad)", { XX } },
1045 { "joH", { Jv, XX, cond_jump_flag } },
1046 { "jnoH", { Jv, XX, cond_jump_flag } },
1047 { "jbH", { Jv, XX, cond_jump_flag } },
1048 { "jaeH", { Jv, XX, cond_jump_flag } },
1049 { "jeH", { Jv, XX, cond_jump_flag } },
1050 { "jneH", { Jv, XX, cond_jump_flag } },
1051 { "jbeH", { Jv, XX, cond_jump_flag } },
1052 { "jaH", { Jv, XX, cond_jump_flag } },
1054 { "jsH", { Jv, XX, cond_jump_flag } },
1055 { "jnsH", { Jv, XX, cond_jump_flag } },
1056 { "jpH", { Jv, XX, cond_jump_flag } },
1057 { "jnpH", { Jv, XX, cond_jump_flag } },
1058 { "jlH", { Jv, XX, cond_jump_flag } },
1059 { "jgeH", { Jv, XX, cond_jump_flag } },
1060 { "jleH", { Jv, XX, cond_jump_flag } },
1061 { "jgH", { Jv, XX, cond_jump_flag } },
1064 { "setno", { Eb } },
1066 { "setae", { Eb } },
1068 { "setne", { Eb } },
1069 { "setbe", { Eb } },
1073 { "setns", { Eb } },
1075 { "setnp", { Eb } },
1077 { "setge", { Eb } },
1078 { "setle", { Eb } },
1081 { "pushT", { fs } },
1083 { "cpuid", { XX } },
1084 { "btS", { Ev, Gv } },
1085 { "shldS", { Ev, Gv, Ib } },
1086 { "shldS", { Ev, Gv, CL } },
1090 { "pushT", { gs } },
1093 { "btsS", { Ev, Gv } },
1094 { "shrdS", { Ev, Gv, Ib } },
1095 { "shrdS", { Ev, Gv, CL } },
1097 { "imulS", { Gv, Ev } },
1099 { "cmpxchgB", { Eb, Gb } },
1100 { "cmpxchgS", { Ev, Gv } },
1101 { "lssS", { Gv, Mp } },
1102 { "btrS", { Ev, Gv } },
1103 { "lfsS", { Gv, Mp } },
1104 { "lgsS", { Gv, Mp } },
1105 { "movz{bR|x|bR|x}", { Gv, Eb } },
1106 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
1111 { "btcS", { Ev, Gv } },
1112 { "bsfS", { Gv, Ev } },
1114 { "movs{bR|x|bR|x}", { Gv, Eb } },
1115 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
1117 { "xaddB", { Eb, Gb } },
1118 { "xaddS", { Ev, Gv } },
1120 { "movntiS", { Ev, Gv } },
1121 { "pinsrw", { MX, Edqw, Ib } },
1122 { "pextrw", { Gdq, MS, Ib } },
1123 { "shufpX", { XM, EXx, Ib } },
1126 { "bswap", { RMeAX } },
1127 { "bswap", { RMeCX } },
1128 { "bswap", { RMeDX } },
1129 { "bswap", { RMeBX } },
1130 { "bswap", { RMeSP } },
1131 { "bswap", { RMeBP } },
1132 { "bswap", { RMeSI } },
1133 { "bswap", { RMeDI } },
1136 { "psrlw", { MX, EM } },
1137 { "psrld", { MX, EM } },
1138 { "psrlq", { MX, EM } },
1139 { "paddq", { MX, EM } },
1140 { "pmullw", { MX, EM } },
1142 { "pmovmskb", { Gdq, MS } },
1144 { "psubusb", { MX, EM } },
1145 { "psubusw", { MX, EM } },
1146 { "pminub", { MX, EM } },
1147 { "pand", { MX, EM } },
1148 { "paddusb", { MX, EM } },
1149 { "paddusw", { MX, EM } },
1150 { "pmaxub", { MX, EM } },
1151 { "pandn", { MX, EM } },
1153 { "pavgb", { MX, EM } },
1154 { "psraw", { MX, EM } },
1155 { "psrad", { MX, EM } },
1156 { "pavgw", { MX, EM } },
1157 { "pmulhuw", { MX, EM } },
1158 { "pmulhw", { MX, EM } },
1162 { "psubsb", { MX, EM } },
1163 { "psubsw", { MX, EM } },
1164 { "pminsw", { MX, EM } },
1165 { "por", { MX, EM } },
1166 { "paddsb", { MX, EM } },
1167 { "paddsw", { MX, EM } },
1168 { "pmaxsw", { MX, EM } },
1169 { "pxor", { MX, EM } },
1172 { "psllw", { MX, EM } },
1173 { "pslld", { MX, EM } },
1174 { "psllq", { MX, EM } },
1175 { "pmuludq", { MX, EM } },
1176 { "pmaddwd", { MX, EM } },
1177 { "psadbw", { MX, EM } },
1180 { "psubb", { MX, EM } },
1181 { "psubw", { MX, EM } },
1182 { "psubd", { MX, EM } },
1183 { "psubq", { MX, EM } },
1184 { "paddb", { MX, EM } },
1185 { "paddw", { MX, EM } },
1186 { "paddd", { MX, EM } },
1187 { "(bad)", { XX } },
1190 static const unsigned char onebyte_has_modrm[256] = {
1191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1192 /* ------------------------------- */
1193 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1194 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1195 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1196 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1197 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1198 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1199 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1200 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1201 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1202 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1203 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1204 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1205 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1206 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1207 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1208 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1209 /* ------------------------------- */
1210 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1213 static const unsigned char twobyte_has_modrm[256] = {
1214 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1215 /* ------------------------------- */
1216 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1217 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1218 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1219 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1220 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1221 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1222 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1223 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1224 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1225 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1226 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1227 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1228 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1229 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1230 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1231 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1232 /* ------------------------------- */
1233 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1236 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1237 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1238 /* ------------------------------- */
1239 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1240 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1241 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1242 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1243 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1244 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1245 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1246 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1247 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1248 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1249 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1250 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1251 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1252 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1253 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1254 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1255 /* ------------------------------- */
1256 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1259 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1260 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1261 /* ------------------------------- */
1262 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1263 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1264 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1265 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1266 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1267 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1268 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1269 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1270 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1271 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1272 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1273 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1274 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1275 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1276 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1277 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1278 /* ------------------------------- */
1279 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1282 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1283 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1284 /* ------------------------------- */
1285 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1286 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1287 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1288 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1289 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1290 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1291 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1292 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1293 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1294 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1295 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1296 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1297 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1298 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1299 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1300 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1301 /* ------------------------------- */
1302 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1305 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1306 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1307 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1308 /* ------------------------------- */
1309 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1310 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1311 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1312 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1313 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1314 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1315 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1316 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1317 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1318 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1319 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1320 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1321 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1322 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1323 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1324 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1325 /* ------------------------------- */
1326 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1329 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1330 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1331 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1332 /* ------------------------------- */
1333 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1334 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1335 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1336 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1337 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1338 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1339 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1340 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1341 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1342 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1343 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1344 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1345 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1346 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1347 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1348 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1349 /* ------------------------------- */
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1353 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1354 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1355 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1356 /* ------------------------------- */
1357 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1358 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1359 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1360 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1361 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1362 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1363 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1364 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1365 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1366 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1367 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1368 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1369 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1370 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1371 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1372 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1373 /* ------------------------------- */
1374 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1377 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1378 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1379 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1380 /* ------------------------------- */
1381 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1382 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1383 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1384 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1385 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1386 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1387 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1388 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1389 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1390 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1391 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1392 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1393 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1394 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1395 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1396 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1397 /* ------------------------------- */
1398 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1401 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1402 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1403 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1404 /* ------------------------------- */
1405 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1406 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1407 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1408 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1409 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1410 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1411 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1412 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1413 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1414 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1415 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1416 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1417 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1418 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1419 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1420 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1421 /* ------------------------------- */
1422 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1425 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1426 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1427 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1428 /* ------------------------------- */
1429 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1430 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1431 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1432 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1433 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1434 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1435 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1436 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1437 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1438 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1439 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1440 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1441 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1442 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1443 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1444 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1445 /* ------------------------------- */
1446 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1449 static char obuf[100];
1451 static char scratchbuf[100];
1452 static unsigned char *start_codep;
1453 static unsigned char *insn_codep;
1454 static unsigned char *codep;
1455 static disassemble_info *the_info;
1463 static unsigned char need_modrm;
1465 /* If we are accessing mod/rm/reg without need_modrm set, then the
1466 values are stale. Hitting this abort likely indicates that you
1467 need to update onebyte_has_modrm or twobyte_has_modrm. */
1468 #define MODRM_CHECK if (!need_modrm) abort ()
1470 static const char **names64;
1471 static const char **names32;
1472 static const char **names16;
1473 static const char **names8;
1474 static const char **names8rex;
1475 static const char **names_seg;
1476 static const char **index16;
1478 static const char *intel_names64[] = {
1479 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1480 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1482 static const char *intel_names32[] = {
1483 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1484 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1486 static const char *intel_names16[] = {
1487 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1488 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1490 static const char *intel_names8[] = {
1491 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1493 static const char *intel_names8rex[] = {
1494 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1495 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1497 static const char *intel_names_seg[] = {
1498 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1500 static const char *intel_index16[] = {
1501 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1504 static const char *att_names64[] = {
1505 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1506 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1508 static const char *att_names32[] = {
1509 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1510 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1512 static const char *att_names16[] = {
1513 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1514 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1516 static const char *att_names8[] = {
1517 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1519 static const char *att_names8rex[] = {
1520 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1521 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1523 static const char *att_names_seg[] = {
1524 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1526 static const char *att_index16[] = {
1527 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1530 static const struct dis386 grps[][8] = {
1533 { "popU", { stackEv } },
1534 { "(bad)", { XX } },
1535 { "(bad)", { XX } },
1536 { "(bad)", { XX } },
1537 { "(bad)", { XX } },
1538 { "(bad)", { XX } },
1539 { "(bad)", { XX } },
1540 { "(bad)", { XX } },
1544 { "addA", { Eb, Ib } },
1545 { "orA", { Eb, Ib } },
1546 { "adcA", { Eb, Ib } },
1547 { "sbbA", { Eb, Ib } },
1548 { "andA", { Eb, Ib } },
1549 { "subA", { Eb, Ib } },
1550 { "xorA", { Eb, Ib } },
1551 { "cmpA", { Eb, Ib } },
1555 { "addQ", { Ev, Iv } },
1556 { "orQ", { Ev, Iv } },
1557 { "adcQ", { Ev, Iv } },
1558 { "sbbQ", { Ev, Iv } },
1559 { "andQ", { Ev, Iv } },
1560 { "subQ", { Ev, Iv } },
1561 { "xorQ", { Ev, Iv } },
1562 { "cmpQ", { Ev, Iv } },
1566 { "addQ", { Ev, sIb } },
1567 { "orQ", { Ev, sIb } },
1568 { "adcQ", { Ev, sIb } },
1569 { "sbbQ", { Ev, sIb } },
1570 { "andQ", { Ev, sIb } },
1571 { "subQ", { Ev, sIb } },
1572 { "xorQ", { Ev, sIb } },
1573 { "cmpQ", { Ev, sIb } },
1577 { "rolA", { Eb, Ib } },
1578 { "rorA", { Eb, Ib } },
1579 { "rclA", { Eb, Ib } },
1580 { "rcrA", { Eb, Ib } },
1581 { "shlA", { Eb, Ib } },
1582 { "shrA", { Eb, Ib } },
1583 { "(bad)", { XX } },
1584 { "sarA", { Eb, Ib } },
1588 { "rolQ", { Ev, Ib } },
1589 { "rorQ", { Ev, Ib } },
1590 { "rclQ", { Ev, Ib } },
1591 { "rcrQ", { Ev, Ib } },
1592 { "shlQ", { Ev, Ib } },
1593 { "shrQ", { Ev, Ib } },
1594 { "(bad)", { XX } },
1595 { "sarQ", { Ev, Ib } },
1599 { "rolA", { Eb, I1 } },
1600 { "rorA", { Eb, I1 } },
1601 { "rclA", { Eb, I1 } },
1602 { "rcrA", { Eb, I1 } },
1603 { "shlA", { Eb, I1 } },
1604 { "shrA", { Eb, I1 } },
1605 { "(bad)", { XX } },
1606 { "sarA", { Eb, I1 } },
1610 { "rolQ", { Ev, I1 } },
1611 { "rorQ", { Ev, I1 } },
1612 { "rclQ", { Ev, I1 } },
1613 { "rcrQ", { Ev, I1 } },
1614 { "shlQ", { Ev, I1 } },
1615 { "shrQ", { Ev, I1 } },
1616 { "(bad)", { XX } },
1617 { "sarQ", { Ev, I1 } },
1621 { "rolA", { Eb, CL } },
1622 { "rorA", { Eb, CL } },
1623 { "rclA", { Eb, CL } },
1624 { "rcrA", { Eb, CL } },
1625 { "shlA", { Eb, CL } },
1626 { "shrA", { Eb, CL } },
1627 { "(bad)", { XX } },
1628 { "sarA", { Eb, CL } },
1632 { "rolQ", { Ev, CL } },
1633 { "rorQ", { Ev, CL } },
1634 { "rclQ", { Ev, CL } },
1635 { "rcrQ", { Ev, CL } },
1636 { "shlQ", { Ev, CL } },
1637 { "shrQ", { Ev, CL } },
1638 { "(bad)", { XX } },
1639 { "sarQ", { Ev, CL } },
1643 { "testA", { Eb, Ib } },
1644 { "(bad)", { Eb } },
1647 { "mulA", { Eb } }, /* Don't print the implicit %al register, */
1648 { "imulA", { Eb } }, /* to distinguish these opcodes from other */
1649 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */
1650 { "idivA", { Eb } }, /* and idiv for consistency. */
1654 { "testQ", { Ev, Iv } },
1655 { "(bad)", { XX } },
1658 { "mulQ", { Ev } }, /* Don't print the implicit register. */
1659 { "imulQ", { Ev } },
1661 { "idivQ", { Ev } },
1667 { "(bad)", { XX } },
1668 { "(bad)", { XX } },
1669 { "(bad)", { XX } },
1670 { "(bad)", { XX } },
1671 { "(bad)", { XX } },
1672 { "(bad)", { XX } },
1678 { "callT", { indirEv } },
1679 { "JcallT", { indirEp } },
1680 { "jmpT", { indirEv } },
1681 { "JjmpT", { indirEp } },
1682 { "pushU", { stackEv } },
1683 { "(bad)", { XX } },
1687 { "sldtD", { Sv } },
1693 { "(bad)", { XX } },
1694 { "(bad)", { XX } },
1698 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1699 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1700 { "lgdt{Q|Q||}", { { XCR_Fixup, 0 } } },
1701 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1702 { "smswD", { Sv } },
1703 { "(bad)", { XX } },
1705 { "invlpg", { { INVLPG_Fixup, w_mode } } },
1709 { "(bad)", { XX } },
1710 { "(bad)", { XX } },
1711 { "(bad)", { XX } },
1712 { "(bad)", { XX } },
1713 { "btQ", { Ev, Ib } },
1714 { "btsQ", { Ev, Ib } },
1715 { "btrQ", { Ev, Ib } },
1716 { "btcQ", { Ev, Ib } },
1720 { "(bad)", { XX } },
1721 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1722 { "(bad)", { XX } },
1723 { "(bad)", { XX } },
1724 { "(bad)", { XX } },
1725 { "(bad)", { XX } },
1726 { "", { VM } }, /* See OP_VMX. */
1727 { "vmptrst", { Mq } },
1731 { "movA", { Eb, Ib } },
1732 { "(bad)", { XX } },
1733 { "(bad)", { XX } },
1734 { "(bad)", { XX } },
1735 { "(bad)", { XX } },
1736 { "(bad)", { XX } },
1737 { "(bad)", { XX } },
1738 { "(bad)", { XX } },
1742 { "movQ", { Ev, Iv } },
1743 { "(bad)", { XX } },
1744 { "(bad)", { XX } },
1745 { "(bad)", { XX } },
1746 { "(bad)", { XX } },
1747 { "(bad)", { XX } },
1748 { "(bad)", { XX } },
1749 { "(bad)", { XX } },
1753 { "(bad)", { XX } },
1754 { "(bad)", { XX } },
1755 { "psrlw", { MS, Ib } },
1756 { "(bad)", { XX } },
1757 { "psraw", { MS, Ib } },
1758 { "(bad)", { XX } },
1759 { "psllw", { MS, Ib } },
1760 { "(bad)", { XX } },
1764 { "(bad)", { XX } },
1765 { "(bad)", { XX } },
1766 { "psrld", { MS, Ib } },
1767 { "(bad)", { XX } },
1768 { "psrad", { MS, Ib } },
1769 { "(bad)", { XX } },
1770 { "pslld", { MS, Ib } },
1771 { "(bad)", { XX } },
1775 { "(bad)", { XX } },
1776 { "(bad)", { XX } },
1777 { "psrlq", { MS, Ib } },
1778 { "psrldq", { MS, Ib } },
1779 { "(bad)", { XX } },
1780 { "(bad)", { XX } },
1781 { "psllq", { MS, Ib } },
1782 { "pslldq", { MS, Ib } },
1786 { "fxsave", { Ev } },
1787 { "fxrstor", { Ev } },
1788 { "ldmxcsr", { Ev } },
1789 { "stmxcsr", { Ev } },
1790 { "xsave", { Ev } },
1791 { "xrstor", { { OP_0fae, v_mode } } },
1792 { "xsaveopt", { { OP_0fae, v_mode } } },
1793 { "clflush", { { OP_0fae, 0 } } },
1797 { "prefetchnta", { Ev } },
1798 { "prefetcht0", { Ev } },
1799 { "prefetcht1", { Ev } },
1800 { "prefetcht2", { Ev } },
1801 { "(bad)", { XX } },
1802 { "(bad)", { XX } },
1803 { "(bad)", { XX } },
1804 { "(bad)", { XX } },
1808 { "prefetch", { Eb } },
1809 { "prefetchw", { Eb } },
1810 { "(bad)", { XX } },
1811 { "(bad)", { XX } },
1812 { "(bad)", { XX } },
1813 { "(bad)", { XX } },
1814 { "(bad)", { XX } },
1815 { "(bad)", { XX } },
1819 { "xstore-rng", { { OP_0f07, 0 } } },
1820 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1821 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1822 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1823 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1824 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1825 { "(bad)", { { OP_0f07, 0 } } },
1826 { "(bad)", { { OP_0f07, 0 } } },
1830 { "montmul", { { OP_0f07, 0 } } },
1831 { "xsha1", { { OP_0f07, 0 } } },
1832 { "xsha256", { { OP_0f07, 0 } } },
1833 { "(bad)", { { OP_0f07, 0 } } },
1834 { "(bad)", { { OP_0f07, 0 } } },
1835 { "(bad)", { { OP_0f07, 0 } } },
1836 { "(bad)", { { OP_0f07, 0 } } },
1837 { "(bad)", { { OP_0f07, 0 } } },
1841 static const struct dis386 prefix_user_table[][4] = {
1844 { "addps", { XM, EXx } },
1845 { "addss", { XM, EXd } },
1846 { "addpd", { XM, EXx } },
1847 { "addsd", { XM, EXq } },
1851 { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1852 { "", { XM, EXx, OPSIMD } },
1853 { "", { XM, EXx, OPSIMD } },
1854 { "", { XM, EXx, OPSIMD } },
1858 { "cvtpi2ps", { XM, EMC } },
1859 { "cvtsi2ssY", { XM, Ev } },
1860 { "cvtpi2pd", { XM, EMC } },
1861 { "cvtsi2sdY", { XM, Ev } },
1865 { "cvtps2pi", { MXC, EXx } },
1866 { "cvtss2siY", { Gv, EXx } },
1867 { "cvtpd2pi", { MXC, EXx } },
1868 { "cvtsd2siY", { Gv, EXx } },
1872 { "cvttps2pi", { MXC, EXx } },
1873 { "cvttss2siY", { Gv, EXx } },
1874 { "cvttpd2pi", { MXC, EXx } },
1875 { "cvttsd2siY", { Gv, EXx } },
1879 { "divps", { XM, EXx } },
1880 { "divss", { XM, EXx } },
1881 { "divpd", { XM, EXx } },
1882 { "divsd", { XM, EXx } },
1886 { "maxps", { XM, EXx } },
1887 { "maxss", { XM, EXx } },
1888 { "maxpd", { XM, EXx } },
1889 { "maxsd", { XM, EXx } },
1893 { "minps", { XM, EXx } },
1894 { "minss", { XM, EXx } },
1895 { "minpd", { XM, EXx } },
1896 { "minsd", { XM, EXx } },
1900 { "movups", { XM, EXx } },
1901 { "movss", { XM, EXx } },
1902 { "movupd", { XM, EXx } },
1903 { "movsd", { XM, EXx } },
1907 { "movups", { EXx, XM } },
1908 { "movss", { EXx, XM } },
1909 { "movupd", { EXx, XM } },
1910 { "movsd", { EXx, XM } },
1914 { "mulps", { XM, EXx } },
1915 { "mulss", { XM, EXx } },
1916 { "mulpd", { XM, EXx } },
1917 { "mulsd", { XM, EXx } },
1921 { "rcpps", { XM, EXx } },
1922 { "rcpss", { XM, EXx } },
1923 { "(bad)", { XM, EXx } },
1924 { "(bad)", { XM, EXx } },
1928 { "rsqrtps",{ XM, EXx } },
1929 { "rsqrtss",{ XM, EXx } },
1930 { "(bad)", { XM, EXx } },
1931 { "(bad)", { XM, EXx } },
1935 { "sqrtps", { XM, EXx } },
1936 { "sqrtss", { XM, EXx } },
1937 { "sqrtpd", { XM, EXx } },
1938 { "sqrtsd", { XM, EXx } },
1942 { "subps", { XM, EXx } },
1943 { "subss", { XM, EXx } },
1944 { "subpd", { XM, EXx } },
1945 { "subsd", { XM, EXx } },
1949 { "(bad)", { XM, EXx } },
1950 { "cvtdq2pd", { XM, EXq } },
1951 { "cvttpd2dq", { XM, EXx } },
1952 { "cvtpd2dq", { XM, EXx } },
1956 { "cvtdq2ps", { XM, EXx } },
1957 { "cvttps2dq", { XM, EXx } },
1958 { "cvtps2dq", { XM, EXx } },
1959 { "(bad)", { XM, EXx } },
1963 { "cvtps2pd", { XM, EXq } },
1964 { "cvtss2sd", { XM, EXx } },
1965 { "cvtpd2ps", { XM, EXx } },
1966 { "cvtsd2ss", { XM, EXx } },
1970 { "maskmovq", { MX, MS } },
1971 { "(bad)", { XM, EXx } },
1972 { "maskmovdqu", { XM, XS } },
1973 { "(bad)", { XM, EXx } },
1977 { "movq", { MX, EM } },
1978 { "movdqu", { XM, EXx } },
1979 { "movdqa", { XM, EXx } },
1980 { "(bad)", { XM, EXx } },
1984 { "movq", { EM, MX } },
1985 { "movdqu", { EXx, XM } },
1986 { "movdqa", { EXx, XM } },
1987 { "(bad)", { EXx, XM } },
1991 { "(bad)", { EXx, XM } },
1992 { "movq2dq",{ XM, MS } },
1993 { "movq", { EXx, XM } },
1994 { "movdq2q",{ MX, XS } },
1998 { "pshufw", { MX, EM, Ib } },
1999 { "pshufhw",{ XM, EXx, Ib } },
2000 { "pshufd", { XM, EXx, Ib } },
2001 { "pshuflw",{ XM, EXx, Ib } },
2005 { "movd", { Edq, MX } },
2006 { "movq", { XM, EXx } },
2007 { "movd", { Edq, XM } },
2008 { "(bad)", { Ed, XM } },
2012 { "(bad)", { MX, EXx } },
2013 { "(bad)", { XM, EXx } },
2014 { "punpckhqdq", { XM, EXx } },
2015 { "(bad)", { XM, EXx } },
2019 { "movntq", { EM, MX } },
2020 { "(bad)", { EM, XM } },
2021 { "movntdq",{ EM, XM } },
2022 { "(bad)", { EM, XM } },
2026 { "(bad)", { MX, EXx } },
2027 { "(bad)", { XM, EXx } },
2028 { "punpcklqdq", { XM, EXx } },
2029 { "(bad)", { XM, EXx } },
2033 { "(bad)", { MX, EXx } },
2034 { "(bad)", { XM, EXx } },
2035 { "addsubpd", { XM, EXx } },
2036 { "addsubps", { XM, EXx } },
2040 { "(bad)", { MX, EXx } },
2041 { "(bad)", { XM, EXx } },
2042 { "haddpd", { XM, EXx } },
2043 { "haddps", { XM, EXx } },
2047 { "(bad)", { MX, EXx } },
2048 { "(bad)", { XM, EXx } },
2049 { "hsubpd", { XM, EXx } },
2050 { "hsubps", { XM, EXx } },
2054 { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
2055 { "movsldup", { XM, EXx } },
2056 { "movlpd", { XM, EXq } },
2057 { "movddup", { XM, EXq } },
2061 { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } },
2062 { "movshdup", { XM, EXx } },
2063 { "movhpd", { XM, EXq } },
2064 { "(bad)", { XM, EXq } },
2068 { "(bad)", { XM, EXx } },
2069 { "(bad)", { XM, EXx } },
2070 { "(bad)", { XM, EXx } },
2071 { "lddqu", { XM, M } },
2075 {"movntps", { Ev, XM } },
2076 {"movntss", { Ev, XM } },
2077 {"movntpd", { Ev, XM } },
2078 {"movntsd", { Ev, XM } },
2083 {"vmread", { Em, Gm } },
2085 {"extrq", { XS, Ib, Ib } },
2086 {"insertq", { XM, XS, Ib, Ib } },
2091 {"vmwrite", { Gm, Em } },
2093 {"extrq", { XM, XS } },
2094 {"insertq", { XM, XS } },
2099 { "bsrS", { Gv, Ev } },
2100 { "lzcntS", { Gv, Ev } },
2101 { "bsrS", { Gv, Ev } },
2102 { "(bad)", { XX } },
2107 { "(bad)", { XX } },
2108 { "popcntS", { Gv, Ev } },
2109 { "(bad)", { XX } },
2110 { "(bad)", { XX } },
2115 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2116 { "pause", { XX } },
2117 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2118 { "(bad)", { XX } },
2123 { "(bad)", { XX } },
2124 { "(bad)", { XX } },
2125 { "pblendvb", {XM, EXx, XMM0 } },
2126 { "(bad)", { XX } },
2131 { "(bad)", { XX } },
2132 { "(bad)", { XX } },
2133 { "blendvps", {XM, EXx, XMM0 } },
2134 { "(bad)", { XX } },
2139 { "(bad)", { XX } },
2140 { "(bad)", { XX } },
2141 { "blendvpd", { XM, EXx, XMM0 } },
2142 { "(bad)", { XX } },
2147 { "(bad)", { XX } },
2148 { "(bad)", { XX } },
2149 { "ptest", { XM, EXx } },
2150 { "(bad)", { XX } },
2155 { "(bad)", { XX } },
2156 { "(bad)", { XX } },
2157 { "pmovsxbw", { XM, EXx } },
2158 { "(bad)", { XX } },
2163 { "(bad)", { XX } },
2164 { "(bad)", { XX } },
2165 { "pmovsxbd", { XM, EXx } },
2166 { "(bad)", { XX } },
2171 { "(bad)", { XX } },
2172 { "(bad)", { XX } },
2173 { "pmovsxbq", { XM, EXx } },
2174 { "(bad)", { XX } },
2179 { "(bad)", { XX } },
2180 { "(bad)", { XX } },
2181 { "pmovsxwd", { XM, EXx } },
2182 { "(bad)", { XX } },
2187 { "(bad)", { XX } },
2188 { "(bad)", { XX } },
2189 { "pmovsxwq", { XM, EXx } },
2190 { "(bad)", { XX } },
2195 { "(bad)", { XX } },
2196 { "(bad)", { XX } },
2197 { "pmovsxdq", { XM, EXx } },
2198 { "(bad)", { XX } },
2203 { "(bad)", { XX } },
2204 { "(bad)", { XX } },
2205 { "pmuldq", { XM, EXx } },
2206 { "(bad)", { XX } },
2211 { "(bad)", { XX } },
2212 { "(bad)", { XX } },
2213 { "pcmpeqq", { XM, EXx } },
2214 { "(bad)", { XX } },
2219 { "(bad)", { XX } },
2220 { "(bad)", { XX } },
2221 { "movntdqa", { XM, EM } },
2222 { "(bad)", { XX } },
2227 { "(bad)", { XX } },
2228 { "(bad)", { XX } },
2229 { "packusdw", { XM, EXx } },
2230 { "(bad)", { XX } },
2235 { "(bad)", { XX } },
2236 { "(bad)", { XX } },
2237 { "pmovzxbw", { XM, EXx } },
2238 { "(bad)", { XX } },
2243 { "(bad)", { XX } },
2244 { "(bad)", { XX } },
2245 { "pmovzxbd", { XM, EXx } },
2246 { "(bad)", { XX } },
2251 { "(bad)", { XX } },
2252 { "(bad)", { XX } },
2253 { "pmovzxbq", { XM, EXx } },
2254 { "(bad)", { XX } },
2259 { "(bad)", { XX } },
2260 { "(bad)", { XX } },
2261 { "pmovzxwd", { XM, EXx } },
2262 { "(bad)", { XX } },
2267 { "(bad)", { XX } },
2268 { "(bad)", { XX } },
2269 { "pmovzxwq", { XM, EXx } },
2270 { "(bad)", { XX } },
2275 { "(bad)", { XX } },
2276 { "(bad)", { XX } },
2277 { "pmovzxdq", { XM, EXx } },
2278 { "(bad)", { XX } },
2283 { "(bad)", { XX } },
2284 { "(bad)", { XX } },
2285 { "pminsb", { XM, EXx } },
2286 { "(bad)", { XX } },
2291 { "(bad)", { XX } },
2292 { "(bad)", { XX } },
2293 { "pminsd", { XM, EXx } },
2294 { "(bad)", { XX } },
2299 { "(bad)", { XX } },
2300 { "(bad)", { XX } },
2301 { "pminuw", { XM, EXx } },
2302 { "(bad)", { XX } },
2307 { "(bad)", { XX } },
2308 { "(bad)", { XX } },
2309 { "pminud", { XM, EXx } },
2310 { "(bad)", { XX } },
2315 { "(bad)", { XX } },
2316 { "(bad)", { XX } },
2317 { "pmaxsb", { XM, EXx } },
2318 { "(bad)", { XX } },
2323 { "(bad)", { XX } },
2324 { "(bad)", { XX } },
2325 { "pmaxsd", { XM, EXx } },
2326 { "(bad)", { XX } },
2331 { "(bad)", { XX } },
2332 { "(bad)", { XX } },
2333 { "pmaxuw", { XM, EXx } },
2334 { "(bad)", { XX } },
2339 { "(bad)", { XX } },
2340 { "(bad)", { XX } },
2341 { "pmaxud", { XM, EXx } },
2342 { "(bad)", { XX } },
2347 { "(bad)", { XX } },
2348 { "(bad)", { XX } },
2349 { "pmulld", { XM, EXx } },
2350 { "(bad)", { XX } },
2355 { "(bad)", { XX } },
2356 { "(bad)", { XX } },
2357 { "phminposuw", { XM, EXx } },
2358 { "(bad)", { XX } },
2363 { "(bad)", { XX } },
2364 { "(bad)", { XX } },
2365 { "roundps", { XM, EXx, Ib } },
2366 { "(bad)", { XX } },
2371 { "(bad)", { XX } },
2372 { "(bad)", { XX } },
2373 { "roundpd", { XM, EXx, Ib } },
2374 { "(bad)", { XX } },
2379 { "(bad)", { XX } },
2380 { "(bad)", { XX } },
2381 { "roundss", { XM, EXx, Ib } },
2382 { "(bad)", { XX } },
2387 { "(bad)", { XX } },
2388 { "(bad)", { XX } },
2389 { "roundsd", { XM, EXx, Ib } },
2390 { "(bad)", { XX } },
2395 { "(bad)", { XX } },
2396 { "(bad)", { XX } },
2397 { "blendps", { XM, EXx, Ib } },
2398 { "(bad)", { XX } },
2403 { "(bad)", { XX } },
2404 { "(bad)", { XX } },
2405 { "blendpd", { XM, EXx, Ib } },
2406 { "(bad)", { XX } },
2411 { "(bad)", { XX } },
2412 { "(bad)", { XX } },
2413 { "pblendw", { XM, EXx, Ib } },
2414 { "(bad)", { XX } },
2419 { "(bad)", { XX } },
2420 { "(bad)", { XX } },
2421 { "pextrb", { Edqb, XM, Ib } },
2422 { "(bad)", { XX } },
2427 { "(bad)", { XX } },
2428 { "(bad)", { XX } },
2429 { "pextrw", { Edqw, XM, Ib } },
2430 { "(bad)", { XX } },
2435 { "(bad)", { XX } },
2436 { "(bad)", { XX } },
2437 { "pextrK", { Edq, XM, Ib } },
2438 { "(bad)", { XX } },
2443 { "(bad)", { XX } },
2444 { "(bad)", { XX } },
2445 { "extractps", { Edqd, XM, Ib } },
2446 { "(bad)", { XX } },
2451 { "(bad)", { XX } },
2452 { "(bad)", { XX } },
2453 { "pinsrb", { XM, Edqb, Ib } },
2454 { "(bad)", { XX } },
2459 { "(bad)", { XX } },
2460 { "(bad)", { XX } },
2461 { "insertps", { XM, EXx, Ib } },
2462 { "(bad)", { XX } },
2467 { "(bad)", { XX } },
2468 { "(bad)", { XX } },
2469 { "pinsrK", { XM, Edq, Ib } },
2470 { "(bad)", { XX } },
2475 { "(bad)", { XX } },
2476 { "(bad)", { XX } },
2477 { "dpps", { XM, EXx, Ib } },
2478 { "(bad)", { XX } },
2483 { "(bad)", { XX } },
2484 { "(bad)", { XX } },
2485 { "dppd", { XM, EXx, Ib } },
2486 { "(bad)", { XX } },
2491 { "(bad)", { XX } },
2492 { "(bad)", { XX } },
2493 { "mpsadbw", { XM, EXx, Ib } },
2494 { "(bad)", { XX } },
2499 { "(bad)", { XX } },
2500 { "(bad)", { XX } },
2501 { "pcmpgtq", { XM, EXx } },
2502 { "(bad)", { XX } },
2507 { "(bad)", { XX } },
2508 { "(bad)", { XX } },
2509 { "(bad)", { XX } },
2510 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
2515 { "(bad)", { XX } },
2516 { "(bad)", { XX } },
2517 { "(bad)", { XX } },
2518 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
2523 { "(bad)", { XX } },
2524 { "(bad)", { XX } },
2525 { "pcmpestrm", { XM, EXx, Ib } },
2526 { "(bad)", { XX } },
2531 { "(bad)", { XX } },
2532 { "(bad)", { XX } },
2533 { "pcmpestri", { XM, EXx, Ib } },
2534 { "(bad)", { XX } },
2539 { "(bad)", { XX } },
2540 { "(bad)", { XX } },
2541 { "pcmpistrm", { XM, EXx, Ib } },
2542 { "(bad)", { XX } },
2547 { "(bad)", { XX } },
2548 { "(bad)", { XX } },
2549 { "pcmpistri", { XM, EXx, Ib } },
2550 { "(bad)", { XX } },
2555 { "ucomiss",{ XM, EXd } },
2556 { "(bad)", { XX } },
2557 { "ucomisd",{ XM, EXq } },
2558 { "(bad)", { XX } },
2563 { "comiss", { XM, EXd } },
2564 { "(bad)", { XX } },
2565 { "comisd", { XM, EXq } },
2566 { "(bad)", { XX } },
2571 { "punpcklbw",{ MX, EMd } },
2572 { "(bad)", { XX } },
2573 { "punpcklbw",{ MX, EMq } },
2574 { "(bad)", { XX } },
2579 { "punpcklwd",{ MX, EMd } },
2580 { "(bad)", { XX } },
2581 { "punpcklwd",{ MX, EMq } },
2582 { "(bad)", { XX } },
2587 { "punpckldq",{ MX, EMd } },
2588 { "(bad)", { XX } },
2589 { "punpckldq",{ MX, EMq } },
2590 { "(bad)", { XX } },
2595 { "(bad)", { XX } },
2596 { "(bad)", { XX } },
2597 { "invept", { Gm, Mo } },
2598 { "(bad)", { XX } },
2603 { "(bad)", { XX } },
2604 { "(bad)", { XX } },
2605 { "invvpid",{ Gm, Mo } },
2606 { "(bad)", { XX } },
2610 static const struct dis386 x86_64_table[][2] = {
2612 { "pusha{P|}", { XX } },
2613 { "(bad)", { XX } },
2616 { "popa{P|}", { XX } },
2617 { "(bad)", { XX } },
2620 { "bound{S|}", { Gv, Ma } },
2621 { "(bad)", { XX } },
2624 { "arpl", { Ew, Gw } },
2625 { "movs{||lq|xd}", { Gv, Ed } },
2629 static const struct dis386 three_byte_table[][256] = {
2633 { "pshufb", { MX, EM } },
2634 { "phaddw", { MX, EM } },
2635 { "phaddd", { MX, EM } },
2636 { "phaddsw", { MX, EM } },
2637 { "pmaddubsw", { MX, EM } },
2638 { "phsubw", { MX, EM } },
2639 { "phsubd", { MX, EM } },
2640 { "phsubsw", { MX, EM } },
2642 { "psignb", { MX, EM } },
2643 { "psignw", { MX, EM } },
2644 { "psignd", { MX, EM } },
2645 { "pmulhrsw", { MX, EM } },
2646 { "(bad)", { XX } },
2647 { "(bad)", { XX } },
2648 { "(bad)", { XX } },
2649 { "(bad)", { XX } },
2652 { "(bad)", { XX } },
2653 { "(bad)", { XX } },
2654 { "(bad)", { XX } },
2657 { "(bad)", { XX } },
2660 { "(bad)", { XX } },
2661 { "(bad)", { XX } },
2662 { "(bad)", { XX } },
2663 { "(bad)", { XX } },
2664 { "pabsb", { MX, EM } },
2665 { "pabsw", { MX, EM } },
2666 { "pabsd", { MX, EM } },
2667 { "(bad)", { XX } },
2675 { "(bad)", { XX } },
2676 { "(bad)", { XX } },
2682 { "(bad)", { XX } },
2683 { "(bad)", { XX } },
2684 { "(bad)", { XX } },
2685 { "(bad)", { XX } },
2693 { "(bad)", { XX } },
2707 { "(bad)", { XX } },
2708 { "(bad)", { XX } },
2709 { "(bad)", { XX } },
2710 { "(bad)", { XX } },
2711 { "(bad)", { XX } },
2712 { "(bad)", { XX } },
2714 { "(bad)", { XX } },
2715 { "(bad)", { XX } },
2716 { "(bad)", { XX } },
2717 { "(bad)", { XX } },
2718 { "(bad)", { XX } },
2719 { "(bad)", { XX } },
2720 { "(bad)", { XX } },
2721 { "(bad)", { XX } },
2723 { "(bad)", { XX } },
2724 { "(bad)", { XX } },
2725 { "(bad)", { XX } },
2726 { "(bad)", { XX } },
2727 { "(bad)", { XX } },
2728 { "(bad)", { XX } },
2729 { "(bad)", { XX } },
2730 { "(bad)", { XX } },
2732 { "(bad)", { XX } },
2733 { "(bad)", { XX } },
2734 { "(bad)", { XX } },
2735 { "(bad)", { XX } },
2736 { "(bad)", { XX } },
2737 { "(bad)", { XX } },
2738 { "(bad)", { XX } },
2739 { "(bad)", { XX } },
2741 { "(bad)", { XX } },
2742 { "(bad)", { XX } },
2743 { "(bad)", { XX } },
2744 { "(bad)", { XX } },
2745 { "(bad)", { XX } },
2746 { "(bad)", { XX } },
2747 { "(bad)", { XX } },
2748 { "(bad)", { XX } },
2750 { "(bad)", { XX } },
2751 { "(bad)", { XX } },
2752 { "(bad)", { XX } },
2753 { "(bad)", { XX } },
2754 { "(bad)", { XX } },
2755 { "(bad)", { XX } },
2756 { "(bad)", { XX } },
2757 { "(bad)", { XX } },
2759 { "(bad)", { XX } },
2760 { "(bad)", { XX } },
2761 { "(bad)", { XX } },
2762 { "(bad)", { XX } },
2763 { "(bad)", { XX } },
2764 { "(bad)", { XX } },
2765 { "(bad)", { XX } },
2766 { "(bad)", { XX } },
2768 { "(bad)", { XX } },
2769 { "(bad)", { XX } },
2770 { "(bad)", { XX } },
2771 { "(bad)", { XX } },
2772 { "(bad)", { XX } },
2773 { "(bad)", { XX } },
2774 { "(bad)", { XX } },
2775 { "(bad)", { XX } },
2779 { "(bad)", { XX } },
2780 { "(bad)", { XX } },
2781 { "(bad)", { XX } },
2782 { "(bad)", { XX } },
2783 { "(bad)", { XX } },
2784 { "(bad)", { XX } },
2786 { "(bad)", { XX } },
2787 { "(bad)", { XX } },
2788 { "(bad)", { XX } },
2789 { "(bad)", { XX } },
2790 { "(bad)", { XX } },
2791 { "(bad)", { XX } },
2792 { "(bad)", { XX } },
2793 { "(bad)", { XX } },
2795 { "(bad)", { XX } },
2796 { "(bad)", { XX } },
2797 { "(bad)", { XX } },
2798 { "(bad)", { XX } },
2799 { "(bad)", { XX } },
2800 { "(bad)", { XX } },
2801 { "(bad)", { XX } },
2802 { "(bad)", { XX } },
2804 { "(bad)", { XX } },
2805 { "(bad)", { XX } },
2806 { "(bad)", { XX } },
2807 { "(bad)", { XX } },
2808 { "(bad)", { XX } },
2809 { "(bad)", { XX } },
2810 { "(bad)", { XX } },
2811 { "(bad)", { XX } },
2813 { "(bad)", { XX } },
2814 { "(bad)", { XX } },
2815 { "(bad)", { XX } },
2816 { "(bad)", { XX } },
2817 { "(bad)", { XX } },
2818 { "(bad)", { XX } },
2819 { "(bad)", { XX } },
2820 { "(bad)", { XX } },
2822 { "(bad)", { XX } },
2823 { "(bad)", { XX } },
2824 { "(bad)", { XX } },
2825 { "(bad)", { XX } },
2826 { "(bad)", { XX } },
2827 { "(bad)", { XX } },
2828 { "(bad)", { XX } },
2829 { "(bad)", { XX } },
2831 { "(bad)", { XX } },
2832 { "(bad)", { XX } },
2833 { "(bad)", { XX } },
2834 { "(bad)", { XX } },
2835 { "(bad)", { XX } },
2836 { "(bad)", { XX } },
2837 { "(bad)", { XX } },
2838 { "(bad)", { XX } },
2840 { "(bad)", { XX } },
2841 { "(bad)", { XX } },
2842 { "(bad)", { XX } },
2843 { "(bad)", { XX } },
2844 { "(bad)", { XX } },
2845 { "(bad)", { XX } },
2846 { "(bad)", { XX } },
2847 { "(bad)", { XX } },
2849 { "(bad)", { XX } },
2850 { "(bad)", { XX } },
2851 { "(bad)", { XX } },
2852 { "(bad)", { XX } },
2853 { "(bad)", { XX } },
2854 { "(bad)", { XX } },
2855 { "(bad)", { XX } },
2856 { "(bad)", { XX } },
2858 { "(bad)", { XX } },
2859 { "(bad)", { XX } },
2860 { "(bad)", { XX } },
2861 { "(bad)", { XX } },
2862 { "(bad)", { XX } },
2863 { "(bad)", { XX } },
2864 { "(bad)", { XX } },
2865 { "(bad)", { XX } },
2867 { "(bad)", { XX } },
2868 { "(bad)", { XX } },
2869 { "(bad)", { XX } },
2870 { "(bad)", { XX } },
2871 { "(bad)", { XX } },
2872 { "(bad)", { XX } },
2873 { "(bad)", { XX } },
2874 { "(bad)", { XX } },
2876 { "(bad)", { XX } },
2877 { "(bad)", { XX } },
2878 { "(bad)", { XX } },
2879 { "(bad)", { XX } },
2880 { "(bad)", { XX } },
2881 { "(bad)", { XX } },
2882 { "(bad)", { XX } },
2883 { "(bad)", { XX } },
2885 { "(bad)", { XX } },
2886 { "(bad)", { XX } },
2887 { "(bad)", { XX } },
2888 { "(bad)", { XX } },
2889 { "(bad)", { XX } },
2890 { "(bad)", { XX } },
2891 { "(bad)", { XX } },
2892 { "(bad)", { XX } },
2894 { "(bad)", { XX } },
2895 { "(bad)", { XX } },
2896 { "(bad)", { XX } },
2897 { "(bad)", { XX } },
2898 { "(bad)", { XX } },
2899 { "(bad)", { XX } },
2900 { "(bad)", { XX } },
2901 { "(bad)", { XX } },
2905 { "(bad)", { XX } },
2906 { "(bad)", { XX } },
2907 { "(bad)", { XX } },
2908 { "(bad)", { XX } },
2909 { "(bad)", { XX } },
2910 { "(bad)", { XX } },
2912 { "(bad)", { XX } },
2913 { "(bad)", { XX } },
2914 { "(bad)", { XX } },
2915 { "(bad)", { XX } },
2916 { "(bad)", { XX } },
2917 { "(bad)", { XX } },
2918 { "(bad)", { XX } },
2919 { "(bad)", { XX } },
2924 { "(bad)", { XX } },
2925 { "(bad)", { XX } },
2926 { "(bad)", { XX } },
2927 { "(bad)", { XX } },
2928 { "(bad)", { XX } },
2929 { "(bad)", { XX } },
2930 { "(bad)", { XX } },
2931 { "(bad)", { XX } },
2940 { "palignr", { MX, EM, Ib } },
2942 { "(bad)", { XX } },
2943 { "(bad)", { XX } },
2944 { "(bad)", { XX } },
2945 { "(bad)", { XX } },
2951 { "(bad)", { XX } },
2952 { "(bad)", { XX } },
2953 { "(bad)", { XX } },
2954 { "(bad)", { XX } },
2955 { "(bad)", { XX } },
2956 { "(bad)", { XX } },
2957 { "(bad)", { XX } },
2958 { "(bad)", { XX } },
2963 { "(bad)", { XX } },
2964 { "(bad)", { XX } },
2965 { "(bad)", { XX } },
2966 { "(bad)", { XX } },
2967 { "(bad)", { XX } },
2969 { "(bad)", { XX } },
2970 { "(bad)", { XX } },
2971 { "(bad)", { XX } },
2972 { "(bad)", { XX } },
2973 { "(bad)", { XX } },
2974 { "(bad)", { XX } },
2975 { "(bad)", { XX } },
2976 { "(bad)", { XX } },
2978 { "(bad)", { XX } },
2979 { "(bad)", { XX } },
2980 { "(bad)", { XX } },
2981 { "(bad)", { XX } },
2982 { "(bad)", { XX } },
2983 { "(bad)", { XX } },
2984 { "(bad)", { XX } },
2985 { "(bad)", { XX } },
2987 { "(bad)", { XX } },
2988 { "(bad)", { XX } },
2989 { "(bad)", { XX } },
2990 { "(bad)", { XX } },
2991 { "(bad)", { XX } },
2992 { "(bad)", { XX } },
2993 { "(bad)", { XX } },
2994 { "(bad)", { XX } },
2999 { "(bad)", { XX } },
3000 { "(bad)", { XX } },
3001 { "(bad)", { XX } },
3002 { "(bad)", { XX } },
3003 { "(bad)", { XX } },
3005 { "(bad)", { XX } },
3006 { "(bad)", { XX } },
3007 { "(bad)", { XX } },
3008 { "(bad)", { XX } },
3009 { "(bad)", { XX } },
3010 { "(bad)", { XX } },
3011 { "(bad)", { XX } },
3012 { "(bad)", { XX } },
3014 { "(bad)", { XX } },
3015 { "(bad)", { XX } },
3016 { "(bad)", { XX } },
3017 { "(bad)", { XX } },
3018 { "(bad)", { XX } },
3019 { "(bad)", { XX } },
3020 { "(bad)", { XX } },
3021 { "(bad)", { XX } },
3023 { "(bad)", { XX } },
3024 { "(bad)", { XX } },
3025 { "(bad)", { XX } },
3026 { "(bad)", { XX } },
3027 { "(bad)", { XX } },
3028 { "(bad)", { XX } },
3029 { "(bad)", { XX } },
3030 { "(bad)", { XX } },
3036 { "(bad)", { XX } },
3037 { "(bad)", { XX } },
3038 { "(bad)", { XX } },
3039 { "(bad)", { XX } },
3041 { "(bad)", { XX } },
3042 { "(bad)", { XX } },
3043 { "(bad)", { XX } },
3044 { "(bad)", { XX } },
3045 { "(bad)", { XX } },
3046 { "(bad)", { XX } },
3047 { "(bad)", { XX } },
3048 { "(bad)", { XX } },
3050 { "(bad)", { XX } },
3051 { "(bad)", { XX } },
3052 { "(bad)", { XX } },
3053 { "(bad)", { XX } },
3054 { "(bad)", { XX } },
3055 { "(bad)", { XX } },
3056 { "(bad)", { XX } },
3057 { "(bad)", { XX } },
3059 { "(bad)", { XX } },
3060 { "(bad)", { XX } },
3061 { "(bad)", { XX } },
3062 { "(bad)", { XX } },
3063 { "(bad)", { XX } },
3064 { "(bad)", { XX } },
3065 { "(bad)", { XX } },
3066 { "(bad)", { XX } },
3068 { "(bad)", { XX } },
3069 { "(bad)", { XX } },
3070 { "(bad)", { XX } },
3071 { "(bad)", { XX } },
3072 { "(bad)", { XX } },
3073 { "(bad)", { XX } },
3074 { "(bad)", { XX } },
3075 { "(bad)", { XX } },
3077 { "(bad)", { XX } },
3078 { "(bad)", { XX } },
3079 { "(bad)", { XX } },
3080 { "(bad)", { XX } },
3081 { "(bad)", { XX } },
3082 { "(bad)", { XX } },
3083 { "(bad)", { XX } },
3084 { "(bad)", { XX } },
3086 { "(bad)", { XX } },
3087 { "(bad)", { XX } },
3088 { "(bad)", { XX } },
3089 { "(bad)", { XX } },
3090 { "(bad)", { XX } },
3091 { "(bad)", { XX } },
3092 { "(bad)", { XX } },
3093 { "(bad)", { XX } },
3095 { "(bad)", { XX } },
3096 { "(bad)", { XX } },
3097 { "(bad)", { XX } },
3098 { "(bad)", { XX } },
3099 { "(bad)", { XX } },
3100 { "(bad)", { XX } },
3101 { "(bad)", { XX } },
3102 { "(bad)", { XX } },
3104 { "(bad)", { XX } },
3105 { "(bad)", { XX } },
3106 { "(bad)", { XX } },
3107 { "(bad)", { XX } },
3108 { "(bad)", { XX } },
3109 { "(bad)", { XX } },
3110 { "(bad)", { XX } },
3111 { "(bad)", { XX } },
3113 { "(bad)", { XX } },
3114 { "(bad)", { XX } },
3115 { "(bad)", { XX } },
3116 { "(bad)", { XX } },
3117 { "(bad)", { XX } },
3118 { "(bad)", { XX } },
3119 { "(bad)", { XX } },
3120 { "(bad)", { XX } },
3122 { "(bad)", { XX } },
3123 { "(bad)", { XX } },
3124 { "(bad)", { XX } },
3125 { "(bad)", { XX } },
3126 { "(bad)", { XX } },
3127 { "(bad)", { XX } },
3128 { "(bad)", { XX } },
3129 { "(bad)", { XX } },
3131 { "(bad)", { XX } },
3132 { "(bad)", { XX } },
3133 { "(bad)", { XX } },
3134 { "(bad)", { XX } },
3135 { "(bad)", { XX } },
3136 { "(bad)", { XX } },
3137 { "(bad)", { XX } },
3138 { "(bad)", { XX } },
3140 { "(bad)", { XX } },
3141 { "(bad)", { XX } },
3142 { "(bad)", { XX } },
3143 { "(bad)", { XX } },
3144 { "(bad)", { XX } },
3145 { "(bad)", { XX } },
3146 { "(bad)", { XX } },
3147 { "(bad)", { XX } },
3149 { "(bad)", { XX } },
3150 { "(bad)", { XX } },
3151 { "(bad)", { XX } },
3152 { "(bad)", { XX } },
3153 { "(bad)", { XX } },
3154 { "(bad)", { XX } },
3155 { "(bad)", { XX } },
3156 { "(bad)", { XX } },
3158 { "(bad)", { XX } },
3159 { "(bad)", { XX } },
3160 { "(bad)", { XX } },
3161 { "(bad)", { XX } },
3162 { "(bad)", { XX } },
3163 { "(bad)", { XX } },
3164 { "(bad)", { XX } },
3165 { "(bad)", { XX } },
3167 { "(bad)", { XX } },
3168 { "(bad)", { XX } },
3169 { "(bad)", { XX } },
3170 { "(bad)", { XX } },
3171 { "(bad)", { XX } },
3172 { "(bad)", { XX } },
3173 { "(bad)", { XX } },
3174 { "(bad)", { XX } },
3176 { "(bad)", { XX } },
3177 { "(bad)", { XX } },
3178 { "(bad)", { XX } },
3179 { "(bad)", { XX } },
3180 { "(bad)", { XX } },
3181 { "(bad)", { XX } },
3182 { "(bad)", { XX } },
3183 { "(bad)", { XX } },
3185 { "(bad)", { XX } },
3186 { "(bad)", { XX } },
3187 { "(bad)", { XX } },
3188 { "(bad)", { XX } },
3189 { "(bad)", { XX } },
3190 { "(bad)", { XX } },
3191 { "(bad)", { XX } },
3192 { "(bad)", { XX } },
3194 { "(bad)", { XX } },
3195 { "(bad)", { XX } },
3196 { "(bad)", { XX } },
3197 { "(bad)", { XX } },
3198 { "(bad)", { XX } },
3199 { "(bad)", { XX } },
3200 { "(bad)", { XX } },
3201 { "(bad)", { XX } },
3203 { "(bad)", { XX } },
3204 { "(bad)", { XX } },
3205 { "(bad)", { XX } },
3206 { "(bad)", { XX } },
3207 { "(bad)", { XX } },
3208 { "(bad)", { XX } },
3209 { "(bad)", { XX } },
3210 { "(bad)", { XX } },
3214 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3226 (void) FETCH_DATA (the_info, codep + 1);
3230 /* REX prefixes family. */
3247 if (address_mode == mode_64bit)
3253 prefixes |= PREFIX_REPZ;
3256 prefixes |= PREFIX_REPNZ;
3259 prefixes |= PREFIX_LOCK;
3262 prefixes |= PREFIX_CS;
3265 prefixes |= PREFIX_SS;
3268 prefixes |= PREFIX_DS;
3271 prefixes |= PREFIX_ES;
3274 prefixes |= PREFIX_FS;
3277 prefixes |= PREFIX_GS;
3280 prefixes |= PREFIX_DATA;
3283 prefixes |= PREFIX_ADDR;
3286 /* fwait is really an instruction. If there are prefixes
3287 before the fwait, they belong to the fwait, *not* to the
3288 following instruction. */
3289 if (prefixes || rex)
3291 prefixes |= PREFIX_FWAIT;
3295 prefixes = PREFIX_FWAIT;
3300 /* Rex is ignored when followed by another prefix. */
3311 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3315 prefix_name (int pref, int sizeflag)
3317 static const char *rexes [16] =
3322 "rex.XB", /* 0x43 */
3324 "rex.RB", /* 0x45 */
3325 "rex.RX", /* 0x46 */
3326 "rex.RXB", /* 0x47 */
3328 "rex.WB", /* 0x49 */
3329 "rex.WX", /* 0x4a */
3330 "rex.WXB", /* 0x4b */
3331 "rex.WR", /* 0x4c */
3332 "rex.WRB", /* 0x4d */
3333 "rex.WRX", /* 0x4e */
3334 "rex.WRXB", /* 0x4f */
3339 /* REX prefixes family. */
3356 return rexes [pref - 0x40];
3376 return (sizeflag & DFLAG) ? "data16" : "data32";
3378 if (address_mode == mode_64bit)
3379 return (sizeflag & AFLAG) ? "addr32" : "addr64";
3381 return (sizeflag & AFLAG) ? "addr16" : "addr32";
3389 static char op_out[MAX_OPERANDS][100];
3390 static int op_ad, op_index[MAX_OPERANDS];
3391 static int two_source_ops;
3392 static bfd_vma op_address[MAX_OPERANDS];
3393 static bfd_vma op_riprel[MAX_OPERANDS];
3394 static bfd_vma start_pc;
3397 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3398 * (see topic "Redundant prefixes" in the "Differences from 8086"
3399 * section of the "Virtual 8086 Mode" chapter.)
3400 * 'pc' should be the address of this instruction, it will
3401 * be used to print the target address if this is a relative jump or call
3402 * The function returns the length of this instruction in bytes.
3405 static char intel_syntax;
3406 static char open_char;
3407 static char close_char;
3408 static char separator_char;
3409 static char scale_char;
3411 /* Here for backwards compatibility. When gdb stops using
3412 print_insn_i386_att and print_insn_i386_intel these functions can
3413 disappear, and print_insn_i386 be merged into print_insn. */
3415 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
3419 return print_insn (pc, info);
3423 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
3427 return print_insn (pc, info);
3431 print_insn_i386 (bfd_vma pc, disassemble_info *info)
3435 return print_insn (pc, info);
3439 print_i386_disassembler_options (FILE *stream)
3441 fprintf (stream, _("\n\
3442 The following i386/x86-64 specific disassembler options are supported for use\n\
3443 with the -M switch (multiple options should be separated by commas):\n"));
3445 fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n"));
3446 fprintf (stream, _(" i386 Disassemble in 32bit mode\n"));
3447 fprintf (stream, _(" i8086 Disassemble in 16bit mode\n"));
3448 fprintf (stream, _(" att Display instruction in AT&T syntax\n"));
3449 fprintf (stream, _(" intel Display instruction in Intel syntax\n"));
3450 fprintf (stream, _(" addr64 Assume 64bit address size\n"));
3451 fprintf (stream, _(" addr32 Assume 32bit address size\n"));
3452 fprintf (stream, _(" addr16 Assume 16bit address size\n"));
3453 fprintf (stream, _(" data32 Assume 32bit data size\n"));
3454 fprintf (stream, _(" data16 Assume 16bit data size\n"));
3455 fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3459 print_insn (bfd_vma pc, disassemble_info *info)
3461 const struct dis386 *dp;
3463 char *op_txt[MAX_OPERANDS];
3465 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3466 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
3469 struct dis_private priv;
3472 if (info->mach == bfd_mach_x86_64_intel_syntax
3473 || info->mach == bfd_mach_x86_64)
3474 address_mode = mode_64bit;
3476 address_mode = mode_32bit;
3478 if (intel_syntax == (char) -1)
3479 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
3480 || info->mach == bfd_mach_x86_64_intel_syntax);
3482 if (info->mach == bfd_mach_i386_i386
3483 || info->mach == bfd_mach_x86_64
3484 || info->mach == bfd_mach_i386_i386_intel_syntax
3485 || info->mach == bfd_mach_x86_64_intel_syntax)
3486 priv.orig_sizeflag = AFLAG | DFLAG;
3487 else if (info->mach == bfd_mach_i386_i8086)
3488 priv.orig_sizeflag = 0;
3492 for (p = info->disassembler_options; p != NULL; )
3494 if (CONST_STRNEQ (p, "x86-64"))
3496 address_mode = mode_64bit;
3497 priv.orig_sizeflag = AFLAG | DFLAG;
3499 else if (CONST_STRNEQ (p, "i386"))
3501 address_mode = mode_32bit;
3502 priv.orig_sizeflag = AFLAG | DFLAG;
3504 else if (CONST_STRNEQ (p, "i8086"))
3506 address_mode = mode_16bit;
3507 priv.orig_sizeflag = 0;
3509 else if (CONST_STRNEQ (p, "intel"))
3513 else if (CONST_STRNEQ (p, "att"))
3517 else if (CONST_STRNEQ (p, "addr"))
3519 if (address_mode == mode_64bit)
3521 if (p[4] == '3' && p[5] == '2')
3522 priv.orig_sizeflag &= ~AFLAG;
3523 else if (p[4] == '6' && p[5] == '4')
3524 priv.orig_sizeflag |= AFLAG;
3528 if (p[4] == '1' && p[5] == '6')
3529 priv.orig_sizeflag &= ~AFLAG;
3530 else if (p[4] == '3' && p[5] == '2')
3531 priv.orig_sizeflag |= AFLAG;
3534 else if (CONST_STRNEQ (p, "data"))
3536 if (p[4] == '1' && p[5] == '6')
3537 priv.orig_sizeflag &= ~DFLAG;
3538 else if (p[4] == '3' && p[5] == '2')
3539 priv.orig_sizeflag |= DFLAG;
3541 else if (CONST_STRNEQ (p, "suffix"))
3542 priv.orig_sizeflag |= SUFFIX_ALWAYS;
3544 p = strchr (p, ',');
3551 names64 = intel_names64;
3552 names32 = intel_names32;
3553 names16 = intel_names16;
3554 names8 = intel_names8;
3555 names8rex = intel_names8rex;
3556 names_seg = intel_names_seg;
3557 index16 = intel_index16;
3560 separator_char = '+';
3565 names64 = att_names64;
3566 names32 = att_names32;
3567 names16 = att_names16;
3568 names8 = att_names8;
3569 names8rex = att_names8rex;
3570 names_seg = att_names_seg;
3571 index16 = att_index16;
3574 separator_char = ',';
3578 /* The output looks better if we put 7 bytes on a line, since that
3579 puts most long word instructions on a single line. */
3580 info->bytes_per_line = 7;
3582 info->private_data = &priv;
3583 priv.max_fetched = priv.the_buffer;
3584 priv.insn_start = pc;
3587 for (i = 0; i < MAX_OPERANDS; ++i)
3595 start_codep = priv.the_buffer;
3596 codep = priv.the_buffer;
3598 if (setjmp (priv.bailout) != 0)
3602 /* Getting here means we tried for data but didn't get it. That
3603 means we have an incomplete instruction of some sort. Just
3604 print the first byte as a prefix or a .byte pseudo-op. */
3605 if (codep > priv.the_buffer)
3607 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3609 (*info->fprintf_func) (info->stream, "%s", name);
3612 /* Just print the first byte as a .byte instruction. */
3613 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3614 (unsigned int) priv.the_buffer[0]);
3627 sizeflag = priv.orig_sizeflag;
3629 (void) FETCH_DATA (info, codep + 1);
3630 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3632 if (((prefixes & PREFIX_FWAIT)
3633 && ((*codep < 0xd8) || (*codep > 0xdf)))
3634 || (rex && rex_used))
3638 /* fwait not followed by floating point instruction, or rex followed
3639 by other prefixes. Print the first prefix. */
3640 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3642 name = INTERNAL_DISASSEMBLER_ERROR;
3643 (*info->fprintf_func) (info->stream, "%s", name);
3650 unsigned char threebyte;
3651 (void) FETCH_DATA (info, codep + 2);
3652 threebyte = *++codep;
3653 dp = &dis386_twobyte[threebyte];
3654 need_modrm = twobyte_has_modrm[*codep];
3655 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3656 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3657 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3658 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3660 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3662 (void) FETCH_DATA (info, codep + 2);
3667 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3668 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3669 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3672 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3673 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3674 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3683 dp = &dis386[*codep];
3684 need_modrm = onebyte_has_modrm[*codep];
3685 uses_DATA_prefix = 0;
3686 uses_REPNZ_prefix = 0;
3687 /* pause is 0xf3 0x90. */
3688 uses_REPZ_prefix = *codep == 0x90;
3689 uses_LOCK_prefix = 0;
3693 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3696 used_prefixes |= PREFIX_REPZ;
3698 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3701 used_prefixes |= PREFIX_REPNZ;
3704 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3707 used_prefixes |= PREFIX_LOCK;
3710 if (prefixes & PREFIX_ADDR)
3713 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
3715 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3716 oappend ("addr32 ");
3718 oappend ("addr16 ");
3719 used_prefixes |= PREFIX_ADDR;
3723 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3726 if (dp->op[2].bytemode == cond_jump_mode
3727 && dp->op[0].bytemode == v_mode
3730 if (sizeflag & DFLAG)
3731 oappend ("data32 ");
3733 oappend ("data16 ");
3734 used_prefixes |= PREFIX_DATA;
3738 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3740 dp = &three_byte_table[dp->op[1].bytemode][op];
3741 modrm.mod = (*codep >> 6) & 3;
3742 modrm.reg = (*codep >> 3) & 7;
3743 modrm.rm = *codep & 7;
3745 else if (need_modrm)
3747 (void) FETCH_DATA (info, codep + 1);
3748 modrm.mod = (*codep >> 6) & 3;
3749 modrm.reg = (*codep >> 3) & 7;
3750 modrm.rm = *codep & 7;
3753 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
3760 if (dp->name == NULL)
3762 switch (dp->op[0].bytemode)
3765 dp = &grps[dp->op[1].bytemode][modrm.reg];
3768 case USE_PREFIX_USER_TABLE:
3770 used_prefixes |= (prefixes & PREFIX_REPZ);
3771 if (prefixes & PREFIX_REPZ)
3775 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3776 before PREFIX_DATA. */
3777 used_prefixes |= (prefixes & PREFIX_REPNZ);
3778 if (prefixes & PREFIX_REPNZ)
3782 used_prefixes |= (prefixes & PREFIX_DATA);
3783 if (prefixes & PREFIX_DATA)
3787 dp = &prefix_user_table[dp->op[1].bytemode][index];
3790 case X86_64_SPECIAL:
3791 index = address_mode == mode_64bit ? 1 : 0;
3792 dp = &x86_64_table[dp->op[1].bytemode][index];
3796 oappend (INTERNAL_DISASSEMBLER_ERROR);
3801 if (putop (dp->name, sizeflag) == 0)
3803 for (i = 0; i < MAX_OPERANDS; ++i)
3806 op_ad = MAX_OPERANDS - 1 - i;
3808 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3813 /* See if any prefixes were not used. If so, print the first one
3814 separately. If we don't do this, we'll wind up printing an
3815 instruction stream which does not precisely correspond to the
3816 bytes we are disassembling. */
3817 if ((prefixes & ~used_prefixes) != 0)
3821 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3823 name = INTERNAL_DISASSEMBLER_ERROR;
3824 (*info->fprintf_func) (info->stream, "%s", name);
3827 if (rex & ~rex_used)
3830 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3832 name = INTERNAL_DISASSEMBLER_ERROR;
3833 (*info->fprintf_func) (info->stream, "%s ", name);
3836 obufp = obuf + strlen (obuf);
3837 for (i = strlen (obuf); i < 6; i++)
3840 (*info->fprintf_func) (info->stream, "%s", obuf);
3842 /* The enter and bound instructions are printed with operands in the same
3843 order as the intel book; everything else is printed in reverse order. */
3844 if (intel_syntax || two_source_ops)
3848 for (i = 0; i < MAX_OPERANDS; ++i)
3849 op_txt[i] = op_out[i];
3851 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3853 op_ad = op_index[i];
3854 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3855 op_index[MAX_OPERANDS - 1 - i] = op_ad;
3856 riprel = op_riprel[i];
3857 op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
3858 op_riprel[MAX_OPERANDS - 1 - i] = riprel;
3863 for (i = 0; i < MAX_OPERANDS; ++i)
3864 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
3868 for (i = 0; i < MAX_OPERANDS; ++i)
3872 (*info->fprintf_func) (info->stream, ",");
3873 if (op_index[i] != -1 && !op_riprel[i])
3874 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3876 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3880 for (i = 0; i < MAX_OPERANDS; i++)
3881 if (op_index[i] != -1 && op_riprel[i])
3883 (*info->fprintf_func) (info->stream, " # ");
3884 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3885 + op_address[op_index[i]]), info);
3888 return codep - priv.the_buffer;
3891 static const char *float_mem[] = {
3966 static const unsigned char float_mem_mode[] = {
4041 #define ST { OP_ST, 0 }
4042 #define STi { OP_STi, 0 }
4044 #define FGRPd9_2 NULL, { { NULL, 0 } }
4045 #define FGRPd9_4 NULL, { { NULL, 1 } }
4046 #define FGRPd9_5 NULL, { { NULL, 2 } }
4047 #define FGRPd9_6 NULL, { { NULL, 3 } }
4048 #define FGRPd9_7 NULL, { { NULL, 4 } }
4049 #define FGRPda_5 NULL, { { NULL, 5 } }
4050 #define FGRPdb_4 NULL, { { NULL, 6 } }
4051 #define FGRPde_3 NULL, { { NULL, 7 } }
4052 #define FGRPdf_4 NULL, { { NULL, 8 } }
4054 static const struct dis386 float_reg[][8] = {
4057 { "fadd", { ST, STi } },
4058 { "fmul", { ST, STi } },
4059 { "fcom", { STi } },
4060 { "fcomp", { STi } },
4061 { "fsub", { ST, STi } },
4062 { "fsubr", { ST, STi } },
4063 { "fdiv", { ST, STi } },
4064 { "fdivr", { ST, STi } },
4069 { "fxch", { STi } },
4071 { "(bad)", { XX } },
4079 { "fcmovb", { ST, STi } },
4080 { "fcmove", { ST, STi } },
4081 { "fcmovbe",{ ST, STi } },
4082 { "fcmovu", { ST, STi } },
4083 { "(bad)", { XX } },
4085 { "(bad)", { XX } },
4086 { "(bad)", { XX } },
4090 { "fcmovnb",{ ST, STi } },
4091 { "fcmovne",{ ST, STi } },
4092 { "fcmovnbe",{ ST, STi } },
4093 { "fcmovnu",{ ST, STi } },
4095 { "fucomi", { ST, STi } },
4096 { "fcomi", { ST, STi } },
4097 { "(bad)", { XX } },
4101 { "fadd", { STi, ST } },
4102 { "fmul", { STi, ST } },
4103 { "(bad)", { XX } },
4104 { "(bad)", { XX } },
4106 { "fsub", { STi, ST } },
4107 { "fsubr", { STi, ST } },
4108 { "fdiv", { STi, ST } },
4109 { "fdivr", { STi, ST } },
4111 { "fsubr", { STi, ST } },
4112 { "fsub", { STi, ST } },
4113 { "fdivr", { STi, ST } },
4114 { "fdiv", { STi, ST } },
4119 { "ffree", { STi } },
4120 { "(bad)", { XX } },
4122 { "fstp", { STi } },
4123 { "fucom", { STi } },
4124 { "fucomp", { STi } },
4125 { "(bad)", { XX } },
4126 { "(bad)", { XX } },
4130 { "faddp", { STi, ST } },
4131 { "fmulp", { STi, ST } },
4132 { "(bad)", { XX } },
4135 { "fsubp", { STi, ST } },
4136 { "fsubrp", { STi, ST } },
4137 { "fdivp", { STi, ST } },
4138 { "fdivrp", { STi, ST } },
4140 { "fsubrp", { STi, ST } },
4141 { "fsubp", { STi, ST } },
4142 { "fdivrp", { STi, ST } },
4143 { "fdivp", { STi, ST } },
4148 { "ffreep", { STi } },
4149 { "(bad)", { XX } },
4150 { "(bad)", { XX } },
4151 { "(bad)", { XX } },
4153 { "fucomip", { ST, STi } },
4154 { "fcomip", { ST, STi } },
4155 { "(bad)", { XX } },
4159 static char *fgrps[][8] = {
4162 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4167 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4172 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4177 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4182 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4187 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4192 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4193 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4198 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4203 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4208 dofloat (int sizeflag)
4210 const struct dis386 *dp;
4211 unsigned char floatop;
4213 floatop = codep[-1];
4217 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
4219 putop (float_mem[fp_indx], sizeflag);
4222 OP_E (float_mem_mode[fp_indx], sizeflag);
4225 /* Skip mod/rm byte. */
4229 dp = &float_reg[floatop - 0xd8][modrm.reg];
4230 if (dp->name == NULL)
4232 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
4234 /* Instruction fnstsw is only one with strange arg. */
4235 if (floatop == 0xdf && codep[-1] == 0xe0)
4236 strcpy (op_out[0], names16[0]);
4240 putop (dp->name, sizeflag);
4245 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
4250 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
4255 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4257 oappend ("%st" + intel_syntax);
4261 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4263 sprintf (scratchbuf, "%%st(%d)", modrm.rm);
4264 oappend (scratchbuf + intel_syntax);
4267 /* Capital letters in template are macros. */
4269 putop (const char *template, int sizeflag)
4274 for (p = template; *p; p++)
4285 if (address_mode == mode_64bit)
4293 /* Alternative not valid. */
4294 strcpy (obuf, "(bad)");
4298 else if (*p == '\0')
4319 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4325 if (sizeflag & SUFFIX_ALWAYS)
4329 if (intel_syntax && !alt)
4331 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4333 if (sizeflag & DFLAG)
4334 *obufp++ = intel_syntax ? 'd' : 'l';
4336 *obufp++ = intel_syntax ? 'w' : 's';
4337 used_prefixes |= (prefixes & PREFIX_DATA);
4341 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4348 else if (sizeflag & DFLAG)
4349 *obufp++ = intel_syntax ? 'd' : 'l';
4352 used_prefixes |= (prefixes & PREFIX_DATA);
4357 case 'E': /* For jcxz/jecxz */
4358 if (address_mode == mode_64bit)
4360 if (sizeflag & AFLAG)
4366 if (sizeflag & AFLAG)
4368 used_prefixes |= (prefixes & PREFIX_ADDR);
4373 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
4375 if (sizeflag & AFLAG)
4376 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
4378 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
4379 used_prefixes |= (prefixes & PREFIX_ADDR);
4383 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4385 if ((rex & REX_W) || (sizeflag & DFLAG))
4390 used_prefixes |= (prefixes & PREFIX_DATA);
4395 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
4396 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
4398 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
4401 if (prefixes & PREFIX_DS)
4422 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4431 if (sizeflag & SUFFIX_ALWAYS)
4435 if ((prefixes & PREFIX_FWAIT) == 0)
4438 used_prefixes |= PREFIX_FWAIT;
4444 else if (intel_syntax && (sizeflag & DFLAG))
4449 used_prefixes |= (prefixes & PREFIX_DATA);
4454 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4463 if ((prefixes & PREFIX_DATA)
4465 || (sizeflag & SUFFIX_ALWAYS))
4472 if (sizeflag & DFLAG)
4477 used_prefixes |= (prefixes & PREFIX_DATA);
4483 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4485 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4491 if (intel_syntax && !alt)
4494 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4500 if (sizeflag & DFLAG)
4501 *obufp++ = intel_syntax ? 'd' : 'l';
4505 used_prefixes |= (prefixes & PREFIX_DATA);
4512 else if (sizeflag & DFLAG)
4521 if (intel_syntax && !p[1]
4522 && ((rex & REX_W) || (sizeflag & DFLAG)))
4525 used_prefixes |= (prefixes & PREFIX_DATA);
4530 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4532 if (sizeflag & SUFFIX_ALWAYS)
4540 if (sizeflag & SUFFIX_ALWAYS)
4546 if (sizeflag & DFLAG)
4550 used_prefixes |= (prefixes & PREFIX_DATA);
4555 if (prefixes & PREFIX_DATA)
4559 used_prefixes |= (prefixes & PREFIX_DATA);
4570 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4572 /* operand size flag for cwtl, cbtw */
4581 else if (sizeflag & DFLAG)
4586 used_prefixes |= (prefixes & PREFIX_DATA);
4596 oappend (const char *s)
4599 obufp += strlen (s);
4605 if (prefixes & PREFIX_CS)
4607 used_prefixes |= PREFIX_CS;
4608 oappend ("%cs:" + intel_syntax);
4610 if (prefixes & PREFIX_DS)
4612 used_prefixes |= PREFIX_DS;
4613 oappend ("%ds:" + intel_syntax);
4615 if (prefixes & PREFIX_SS)
4617 used_prefixes |= PREFIX_SS;
4618 oappend ("%ss:" + intel_syntax);
4620 if (prefixes & PREFIX_ES)
4622 used_prefixes |= PREFIX_ES;
4623 oappend ("%es:" + intel_syntax);
4625 if (prefixes & PREFIX_FS)
4627 used_prefixes |= PREFIX_FS;
4628 oappend ("%fs:" + intel_syntax);
4630 if (prefixes & PREFIX_GS)
4632 used_prefixes |= PREFIX_GS;
4633 oappend ("%gs:" + intel_syntax);
4638 OP_indirE (int bytemode, int sizeflag)
4642 OP_E (bytemode, sizeflag);
4646 print_operand_value (char *buf, int hex, bfd_vma disp)
4648 if (address_mode == mode_64bit)
4656 sprintf_vma (tmp, disp);
4657 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
4658 strcpy (buf + 2, tmp + i);
4662 bfd_signed_vma v = disp;
4669 /* Check for possible overflow on 0x8000000000000000. */
4672 strcpy (buf, "9223372036854775808");
4686 tmp[28 - i] = (v % 10) + '0';
4690 strcpy (buf, tmp + 29 - i);
4696 sprintf (buf, "0x%x", (unsigned int) disp);
4698 sprintf (buf, "%d", (int) disp);
4702 /* Put DISP in BUF as signed hex number. */
4705 print_displacement (char *buf, bfd_vma disp)
4707 bfd_signed_vma val = disp;
4716 /* Check for possible overflow. */
4719 switch (address_mode)
4722 strcpy (buf + j, "0x8000000000000000");
4725 strcpy (buf + j, "0x80000000");
4728 strcpy (buf + j, "0x8000");
4738 sprintf_vma (tmp, val);
4739 for (i = 0; tmp[i] == '0'; i++)
4743 strcpy (buf + j, tmp + i);
4747 intel_operand_size (int bytemode, int sizeflag)
4753 oappend ("BYTE PTR ");
4757 oappend ("WORD PTR ");
4760 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4762 oappend ("QWORD PTR ");
4763 used_prefixes |= (prefixes & PREFIX_DATA);
4771 oappend ("QWORD PTR ");
4772 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4773 oappend ("DWORD PTR ");
4775 oappend ("WORD PTR ");
4776 used_prefixes |= (prefixes & PREFIX_DATA);
4779 if ((rex & REX_W) || (sizeflag & DFLAG))
4781 oappend ("WORD PTR ");
4783 used_prefixes |= (prefixes & PREFIX_DATA);
4787 oappend ("DWORD PTR ");
4790 oappend ("QWORD PTR ");
4793 if (address_mode == mode_64bit)
4794 oappend ("QWORD PTR ");
4796 oappend ("DWORD PTR ");
4799 if (sizeflag & DFLAG)
4800 oappend ("FWORD PTR ");
4802 oappend ("DWORD PTR ");
4803 used_prefixes |= (prefixes & PREFIX_DATA);
4806 oappend ("TBYTE PTR ");
4809 oappend ("XMMWORD PTR ");
4812 oappend ("OWORD PTR ");
4820 OP_E (int bytemode, int sizeflag)
4829 /* Skip mod/rm byte. */
4840 oappend (names8rex[modrm.rm + add]);
4842 oappend (names8[modrm.rm + add]);
4845 oappend (names16[modrm.rm + add]);
4848 oappend (names32[modrm.rm + add]);
4851 oappend (names64[modrm.rm + add]);
4854 if (address_mode == mode_64bit)
4855 oappend (names64[modrm.rm + add]);
4857 oappend (names32[modrm.rm + add]);
4860 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4862 oappend (names64[modrm.rm + add]);
4863 used_prefixes |= (prefixes & PREFIX_DATA);
4875 oappend (names64[modrm.rm + add]);
4876 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4877 oappend (names32[modrm.rm + add]);
4879 oappend (names16[modrm.rm + add]);
4880 used_prefixes |= (prefixes & PREFIX_DATA);
4885 oappend (INTERNAL_DISASSEMBLER_ERROR);
4893 intel_operand_size (bytemode, sizeflag);
4896 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4898 /* 32/64 bit address mode */
4913 (void) FETCH_DATA (the_info, codep + 1);
4914 index = (*codep >> 3) & 7;
4915 if (address_mode == mode_64bit || index != 0x4)
4916 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4917 scale = (*codep >> 6) & 3;
4929 if ((base & 7) == 5)
4932 if (address_mode == mode_64bit && !havesib)
4938 FETCH_DATA (the_info, codep + 1);
4940 if ((disp & 0x80) != 0)
4948 havedisp = havebase || (havesib && (index != 4 || scale != 0));
4951 if (modrm.mod != 0 || (base & 7) == 5)
4953 if (havedisp || riprel)
4954 print_displacement (scratchbuf, disp);
4956 print_operand_value (scratchbuf, 1, disp);
4957 oappend (scratchbuf);
4965 if (havedisp || (intel_syntax && riprel))
4967 *obufp++ = open_char;
4968 if (intel_syntax && riprel)
4975 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4976 ? names64[base] : names32[base]);
4981 if (!intel_syntax || havebase)
4983 *obufp++ = separator_char;
4986 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4987 ? names64[index] : names32[index]);
4989 if (scale != 0 || (!intel_syntax && index != 4))
4991 *obufp++ = scale_char;
4993 sprintf (scratchbuf, "%d", 1 << scale);
4994 oappend (scratchbuf);
4998 && (disp || modrm.mod != 0 || (base & 7) == 5))
5000 if ((bfd_signed_vma) disp >= 0)
5005 else if (modrm.mod != 1)
5009 disp = - (bfd_signed_vma) disp;
5012 print_displacement (scratchbuf, disp);
5013 oappend (scratchbuf);
5016 *obufp++ = close_char;
5019 else if (intel_syntax)
5021 if (modrm.mod != 0 || (base & 7) == 5)
5023 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5024 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5028 oappend (names_seg[ds_reg - es_reg]);
5031 print_operand_value (scratchbuf, 1, disp);
5032 oappend (scratchbuf);
5037 { /* 16 bit address mode */
5044 if ((disp & 0x8000) != 0)
5049 FETCH_DATA (the_info, codep + 1);
5051 if ((disp & 0x80) != 0)
5056 if ((disp & 0x8000) != 0)
5062 if (modrm.mod != 0 || modrm.rm == 6)
5064 print_displacement (scratchbuf, disp);
5065 oappend (scratchbuf);
5068 if (modrm.mod != 0 || modrm.rm != 6)
5070 *obufp++ = open_char;
5072 oappend (index16[modrm.rm]);
5074 && (disp || modrm.mod != 0 || modrm.rm == 6))
5076 if ((bfd_signed_vma) disp >= 0)
5081 else if (modrm.mod != 1)
5085 disp = - (bfd_signed_vma) disp;
5088 print_displacement (scratchbuf, disp);
5089 oappend (scratchbuf);
5092 *obufp++ = close_char;
5095 else if (intel_syntax)
5097 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5098 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5102 oappend (names_seg[ds_reg - es_reg]);
5105 print_operand_value (scratchbuf, 1, disp & 0xffff);
5106 oappend (scratchbuf);
5112 OP_G (int bytemode, int sizeflag)
5123 oappend (names8rex[modrm.reg + add]);
5125 oappend (names8[modrm.reg + add]);
5128 oappend (names16[modrm.reg + add]);
5131 oappend (names32[modrm.reg + add]);
5134 oappend (names64[modrm.reg + add]);
5143 oappend (names64[modrm.reg + add]);
5144 else if ((sizeflag & DFLAG) || bytemode != v_mode)
5145 oappend (names32[modrm.reg + add]);
5147 oappend (names16[modrm.reg + add]);
5148 used_prefixes |= (prefixes & PREFIX_DATA);
5151 if (address_mode == mode_64bit)
5152 oappend (names64[modrm.reg + add]);
5154 oappend (names32[modrm.reg + add]);
5157 oappend (INTERNAL_DISASSEMBLER_ERROR);
5170 (void) FETCH_DATA (the_info, codep + 8);
5171 a = *codep++ & 0xff;
5172 a |= (*codep++ & 0xff) << 8;
5173 a |= (*codep++ & 0xff) << 16;
5174 a |= (*codep++ & 0xff) << 24;
5175 b = *codep++ & 0xff;
5176 b |= (*codep++ & 0xff) << 8;
5177 b |= (*codep++ & 0xff) << 16;
5178 b |= (*codep++ & 0xff) << 24;
5179 x = a + ((bfd_vma) b << 32);
5187 static bfd_signed_vma
5190 bfd_signed_vma x = 0;
5192 (void) FETCH_DATA (the_info, codep + 4);
5193 x = *codep++ & (bfd_signed_vma) 0xff;
5194 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5195 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5196 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5200 static bfd_signed_vma
5203 bfd_signed_vma x = 0;
5205 (void) FETCH_DATA (the_info, codep + 4);
5206 x = *codep++ & (bfd_signed_vma) 0xff;
5207 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5208 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5209 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5211 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
5221 (void) FETCH_DATA (the_info, codep + 2);
5222 x = *codep++ & 0xff;
5223 x |= (*codep++ & 0xff) << 8;
5228 set_op (bfd_vma op, int riprel)
5230 op_index[op_ad] = op_ad;
5231 if (address_mode == mode_64bit)
5233 op_address[op_ad] = op;
5234 op_riprel[op_ad] = riprel;
5238 /* Mask to get a 32-bit address. */
5239 op_address[op_ad] = op & 0xffffffff;
5240 op_riprel[op_ad] = riprel & 0xffffffff;
5245 OP_REG (int code, int sizeflag)
5255 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5256 case sp_reg: case bp_reg: case si_reg: case di_reg:
5257 s = names16[code - ax_reg + add];
5259 case es_reg: case ss_reg: case cs_reg:
5260 case ds_reg: case fs_reg: case gs_reg:
5261 s = names_seg[code - es_reg + add];
5263 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5264 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5267 s = names8rex[code - al_reg + add];
5269 s = names8[code - al_reg];
5271 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
5272 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
5273 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5275 s = names64[code - rAX_reg + add];
5278 code += eAX_reg - rAX_reg;
5280 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5281 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5284 s = names64[code - eAX_reg + add];
5285 else if (sizeflag & DFLAG)
5286 s = names32[code - eAX_reg + add];
5288 s = names16[code - eAX_reg + add];
5289 used_prefixes |= (prefixes & PREFIX_DATA);
5292 s = INTERNAL_DISASSEMBLER_ERROR;
5299 OP_IMREG (int code, int sizeflag)
5311 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5312 case sp_reg: case bp_reg: case si_reg: case di_reg:
5313 s = names16[code - ax_reg];
5315 case es_reg: case ss_reg: case cs_reg:
5316 case ds_reg: case fs_reg: case gs_reg:
5317 s = names_seg[code - es_reg];
5319 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5320 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5323 s = names8rex[code - al_reg];
5325 s = names8[code - al_reg];
5327 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5328 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5331 s = names64[code - eAX_reg];
5332 else if (sizeflag & DFLAG)
5333 s = names32[code - eAX_reg];
5335 s = names16[code - eAX_reg];
5336 used_prefixes |= (prefixes & PREFIX_DATA);
5339 if ((rex & REX_W) || (sizeflag & DFLAG))
5344 used_prefixes |= (prefixes & PREFIX_DATA);
5347 s = INTERNAL_DISASSEMBLER_ERROR;
5354 OP_I (int bytemode, int sizeflag)
5357 bfd_signed_vma mask = -1;
5362 FETCH_DATA (the_info, codep + 1);
5367 if (address_mode == mode_64bit)
5377 else if (sizeflag & DFLAG)
5387 used_prefixes |= (prefixes & PREFIX_DATA);
5398 oappend (INTERNAL_DISASSEMBLER_ERROR);
5403 scratchbuf[0] = '$';
5404 print_operand_value (scratchbuf + 1, 1, op);
5405 oappend (scratchbuf + intel_syntax);
5406 scratchbuf[0] = '\0';
5410 OP_I64 (int bytemode, int sizeflag)
5413 bfd_signed_vma mask = -1;
5415 if (address_mode != mode_64bit)
5417 OP_I (bytemode, sizeflag);
5424 FETCH_DATA (the_info, codep + 1);
5432 else if (sizeflag & DFLAG)
5442 used_prefixes |= (prefixes & PREFIX_DATA);
5449 oappend (INTERNAL_DISASSEMBLER_ERROR);
5454 scratchbuf[0] = '$';
5455 print_operand_value (scratchbuf + 1, 1, op);
5456 oappend (scratchbuf + intel_syntax);
5457 scratchbuf[0] = '\0';
5461 OP_sI (int bytemode, int sizeflag)
5464 bfd_signed_vma mask = -1;
5469 FETCH_DATA (the_info, codep + 1);
5471 if ((op & 0x80) != 0)
5479 else if (sizeflag & DFLAG)
5488 if ((op & 0x8000) != 0)
5491 used_prefixes |= (prefixes & PREFIX_DATA);
5496 if ((op & 0x8000) != 0)
5500 oappend (INTERNAL_DISASSEMBLER_ERROR);
5504 scratchbuf[0] = '$';
5505 print_operand_value (scratchbuf + 1, 1, op);
5506 oappend (scratchbuf + intel_syntax);
5510 OP_J (int bytemode, int sizeflag)
5514 bfd_vma segment = 0;
5519 FETCH_DATA (the_info, codep + 1);
5521 if ((disp & 0x80) != 0)
5525 if ((sizeflag & DFLAG) || (rex & REX_W))
5530 if ((disp & 0x8000) != 0)
5532 /* In 16bit mode, address is wrapped around at 64k within
5533 the same segment. Otherwise, a data16 prefix on a jump
5534 instruction means that the pc is masked to 16 bits after
5535 the displacement is added! */
5537 if ((prefixes & PREFIX_DATA) == 0)
5538 segment = ((start_pc + codep - start_codep)
5539 & ~((bfd_vma) 0xffff));
5541 used_prefixes |= (prefixes & PREFIX_DATA);
5544 oappend (INTERNAL_DISASSEMBLER_ERROR);
5547 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
5549 print_operand_value (scratchbuf, 1, disp);
5550 oappend (scratchbuf);
5554 OP_SEG (int bytemode, int sizeflag)
5556 if (bytemode == w_mode)
5557 oappend (names_seg[modrm.reg]);
5559 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
5563 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
5567 if (sizeflag & DFLAG)
5577 used_prefixes |= (prefixes & PREFIX_DATA);
5579 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
5581 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
5582 oappend (scratchbuf);
5586 OP_OFF (int bytemode, int sizeflag)
5590 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5591 intel_operand_size (bytemode, sizeflag);
5594 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5601 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5602 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5604 oappend (names_seg[ds_reg - es_reg]);
5608 print_operand_value (scratchbuf, 1, off);
5609 oappend (scratchbuf);
5613 OP_OFF64 (int bytemode, int sizeflag)
5617 if (address_mode != mode_64bit
5618 || (prefixes & PREFIX_ADDR))
5620 OP_OFF (bytemode, sizeflag);
5624 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5625 intel_operand_size (bytemode, sizeflag);
5632 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5633 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5635 oappend (names_seg[ds_reg - es_reg]);
5639 print_operand_value (scratchbuf, 1, off);
5640 oappend (scratchbuf);
5644 ptr_reg (int code, int sizeflag)
5648 *obufp++ = open_char;
5649 used_prefixes |= (prefixes & PREFIX_ADDR);
5650 if (address_mode == mode_64bit)
5652 if (!(sizeflag & AFLAG))
5653 s = names32[code - eAX_reg];
5655 s = names64[code - eAX_reg];
5657 else if (sizeflag & AFLAG)
5658 s = names32[code - eAX_reg];
5660 s = names16[code - eAX_reg];
5662 *obufp++ = close_char;
5667 OP_ESreg (int code, int sizeflag)
5673 case 0x6d: /* insw/insl */
5674 intel_operand_size (z_mode, sizeflag);
5676 case 0xa5: /* movsw/movsl/movsq */
5677 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5678 case 0xab: /* stosw/stosl */
5679 case 0xaf: /* scasw/scasl */
5680 intel_operand_size (v_mode, sizeflag);
5683 intel_operand_size (b_mode, sizeflag);
5686 oappend ("%es:" + intel_syntax);
5687 ptr_reg (code, sizeflag);
5691 OP_DSreg (int code, int sizeflag)
5697 case 0x6f: /* outsw/outsl */
5698 intel_operand_size (z_mode, sizeflag);
5700 case 0xa5: /* movsw/movsl/movsq */
5701 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5702 case 0xad: /* lodsw/lodsl/lodsq */
5703 intel_operand_size (v_mode, sizeflag);
5706 intel_operand_size (b_mode, sizeflag);
5716 prefixes |= PREFIX_DS;
5718 ptr_reg (code, sizeflag);
5722 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5730 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5732 used_prefixes |= PREFIX_LOCK;
5735 sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
5736 oappend (scratchbuf + intel_syntax);
5740 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5747 sprintf (scratchbuf, "db%d", modrm.reg + add);
5749 sprintf (scratchbuf, "%%db%d", modrm.reg + add);
5750 oappend (scratchbuf);
5754 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5756 sprintf (scratchbuf, "%%tr%d", modrm.reg);
5757 oappend (scratchbuf + intel_syntax);
5761 OP_R (int bytemode, int sizeflag)
5764 OP_E (bytemode, sizeflag);
5770 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5772 used_prefixes |= (prefixes & PREFIX_DATA);
5773 if (prefixes & PREFIX_DATA)
5779 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5782 sprintf (scratchbuf, "%%mm%d", modrm.reg);
5783 oappend (scratchbuf + intel_syntax);
5787 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5793 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5794 oappend (scratchbuf + intel_syntax);
5798 OP_EM (int bytemode, int sizeflag)
5802 if (intel_syntax && bytemode == v_mode)
5804 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5805 used_prefixes |= (prefixes & PREFIX_DATA);
5807 OP_E (bytemode, sizeflag);
5811 /* Skip mod/rm byte. */
5814 used_prefixes |= (prefixes & PREFIX_DATA);
5815 if (prefixes & PREFIX_DATA)
5822 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5825 sprintf (scratchbuf, "%%mm%d", modrm.rm);
5826 oappend (scratchbuf + intel_syntax);
5829 /* cvt* are the only instructions in sse2 which have
5830 both SSE and MMX operands and also have 0x66 prefix
5831 in their opcode. 0x66 was originally used to differentiate
5832 between SSE and MMX instruction(operands). So we have to handle the
5833 cvt* separately using OP_EMC and OP_MXC */
5835 OP_EMC (int bytemode, int sizeflag)
5839 if (intel_syntax && bytemode == v_mode)
5841 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5842 used_prefixes |= (prefixes & PREFIX_DATA);
5844 OP_E (bytemode, sizeflag);
5848 /* Skip mod/rm byte. */
5851 used_prefixes |= (prefixes & PREFIX_DATA);
5852 sprintf (scratchbuf, "%%mm%d", modrm.rm);
5853 oappend (scratchbuf + intel_syntax);
5857 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5859 used_prefixes |= (prefixes & PREFIX_DATA);
5860 sprintf (scratchbuf, "%%mm%d", modrm.reg);
5861 oappend (scratchbuf + intel_syntax);
5865 OP_EX (int bytemode, int sizeflag)
5870 OP_E (bytemode, sizeflag);
5877 /* Skip mod/rm byte. */
5880 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5881 oappend (scratchbuf + intel_syntax);
5885 OP_MS (int bytemode, int sizeflag)
5888 OP_EM (bytemode, sizeflag);
5894 OP_XS (int bytemode, int sizeflag)
5897 OP_EX (bytemode, sizeflag);
5903 OP_M (int bytemode, int sizeflag)
5906 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst,invept,invvpid modrm */
5909 OP_E (bytemode, sizeflag);
5913 OP_0f07 (int bytemode, int sizeflag)
5915 if (modrm.mod != 3 || modrm.rm != 0)
5918 OP_E (bytemode, sizeflag);
5922 OP_0fae (int bytemode, int sizeflag)
5927 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5928 else if (modrm.reg == 6)
5929 strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
5930 else if (modrm.reg == 5)
5931 strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
5933 if (modrm.reg < 5 || modrm.rm != 0)
5935 BadOp (); /* bad sfence, mfence, or lfence */
5941 OP_E (bytemode, sizeflag);
5944 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5945 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5948 NOP_Fixup1 (int bytemode, int sizeflag)
5950 if ((prefixes & PREFIX_DATA) != 0
5953 && address_mode == mode_64bit))
5954 OP_REG (bytemode, sizeflag);
5956 strcpy (obuf, "nop");
5960 NOP_Fixup2 (int bytemode, int sizeflag)
5962 if ((prefixes & PREFIX_DATA) != 0
5965 && address_mode == mode_64bit))
5966 OP_IMREG (bytemode, sizeflag);
5969 static const char *const Suffix3DNow[] = {
5970 /* 00 */ NULL, NULL, NULL, NULL,
5971 /* 04 */ NULL, NULL, NULL, NULL,
5972 /* 08 */ NULL, NULL, NULL, NULL,
5973 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
5974 /* 10 */ NULL, NULL, NULL, NULL,
5975 /* 14 */ NULL, NULL, NULL, NULL,
5976 /* 18 */ NULL, NULL, NULL, NULL,
5977 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
5978 /* 20 */ NULL, NULL, NULL, NULL,
5979 /* 24 */ NULL, NULL, NULL, NULL,
5980 /* 28 */ NULL, NULL, NULL, NULL,
5981 /* 2C */ NULL, NULL, NULL, NULL,
5982 /* 30 */ NULL, NULL, NULL, NULL,
5983 /* 34 */ NULL, NULL, NULL, NULL,
5984 /* 38 */ NULL, NULL, NULL, NULL,
5985 /* 3C */ NULL, NULL, NULL, NULL,
5986 /* 40 */ NULL, NULL, NULL, NULL,
5987 /* 44 */ NULL, NULL, NULL, NULL,
5988 /* 48 */ NULL, NULL, NULL, NULL,
5989 /* 4C */ NULL, NULL, NULL, NULL,
5990 /* 50 */ NULL, NULL, NULL, NULL,
5991 /* 54 */ NULL, NULL, NULL, NULL,
5992 /* 58 */ NULL, NULL, NULL, NULL,
5993 /* 5C */ NULL, NULL, NULL, NULL,
5994 /* 60 */ NULL, NULL, NULL, NULL,
5995 /* 64 */ NULL, NULL, NULL, NULL,
5996 /* 68 */ NULL, NULL, NULL, NULL,
5997 /* 6C */ NULL, NULL, NULL, NULL,
5998 /* 70 */ NULL, NULL, NULL, NULL,
5999 /* 74 */ NULL, NULL, NULL, NULL,
6000 /* 78 */ NULL, NULL, NULL, NULL,
6001 /* 7C */ NULL, NULL, NULL, NULL,
6002 /* 80 */ NULL, NULL, NULL, NULL,
6003 /* 84 */ NULL, NULL, NULL, NULL,
6004 /* 88 */ NULL, NULL, "pfnacc", NULL,
6005 /* 8C */ NULL, NULL, "pfpnacc", NULL,
6006 /* 90 */ "pfcmpge", NULL, NULL, NULL,
6007 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
6008 /* 98 */ NULL, NULL, "pfsub", NULL,
6009 /* 9C */ NULL, NULL, "pfadd", NULL,
6010 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
6011 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
6012 /* A8 */ NULL, NULL, "pfsubr", NULL,
6013 /* AC */ NULL, NULL, "pfacc", NULL,
6014 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
6015 /* B4 */ "pfmul", NULL, "pfrcpit2", "pmulhrw",
6016 /* B8 */ NULL, NULL, NULL, "pswapd",
6017 /* BC */ NULL, NULL, NULL, "pavgusb",
6018 /* C0 */ NULL, NULL, NULL, NULL,
6019 /* C4 */ NULL, NULL, NULL, NULL,
6020 /* C8 */ NULL, NULL, NULL, NULL,
6021 /* CC */ NULL, NULL, NULL, NULL,
6022 /* D0 */ NULL, NULL, NULL, NULL,
6023 /* D4 */ NULL, NULL, NULL, NULL,
6024 /* D8 */ NULL, NULL, NULL, NULL,
6025 /* DC */ NULL, NULL, NULL, NULL,
6026 /* E0 */ NULL, NULL, NULL, NULL,
6027 /* E4 */ NULL, NULL, NULL, NULL,
6028 /* E8 */ NULL, NULL, NULL, NULL,
6029 /* EC */ NULL, NULL, NULL, NULL,
6030 /* F0 */ NULL, NULL, NULL, NULL,
6031 /* F4 */ NULL, NULL, NULL, NULL,
6032 /* F8 */ NULL, NULL, NULL, NULL,
6033 /* FC */ NULL, NULL, NULL, NULL,
6037 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6039 const char *mnemonic;
6041 (void) FETCH_DATA (the_info, codep + 1);
6042 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6043 place where an 8-bit immediate would normally go. ie. the last
6044 byte of the instruction. */
6045 obufp = obuf + strlen (obuf);
6046 mnemonic = Suffix3DNow[*codep++ & 0xff];
6051 /* Since a variable sized modrm/sib chunk is between the start
6052 of the opcode (0x0f0f) and the opcode suffix, we need to do
6053 all the modrm processing first, and don't know until now that
6054 we have a bad opcode. This necessitates some cleaning up. */
6055 op_out[0][0] = '\0';
6056 op_out[1][0] = '\0';
6061 static const char *simd_cmp_op[] = {
6073 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6075 unsigned int cmp_type;
6077 (void) FETCH_DATA (the_info, codep + 1);
6078 obufp = obuf + strlen (obuf);
6079 cmp_type = *codep++ & 0xff;
6082 char suffix1 = 'p', suffix2 = 's';
6083 used_prefixes |= (prefixes & PREFIX_REPZ);
6084 if (prefixes & PREFIX_REPZ)
6088 used_prefixes |= (prefixes & PREFIX_DATA);
6089 if (prefixes & PREFIX_DATA)
6093 used_prefixes |= (prefixes & PREFIX_REPNZ);
6094 if (prefixes & PREFIX_REPNZ)
6095 suffix1 = 's', suffix2 = 'd';
6098 sprintf (scratchbuf, "cmp%s%c%c",
6099 simd_cmp_op[cmp_type], suffix1, suffix2);
6100 used_prefixes |= (prefixes & PREFIX_REPZ);
6101 oappend (scratchbuf);
6105 /* We have a bad extension byte. Clean up. */
6106 op_out[0][0] = '\0';
6107 op_out[1][0] = '\0';
6113 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
6115 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6116 forms of these instructions. */
6119 char *p = obuf + strlen (obuf);
6122 *(p - 1) = *(p - 2);
6123 *(p - 2) = *(p - 3);
6124 *(p - 3) = extrachar;
6129 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6131 if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
6133 /* Override "sidt". */
6134 size_t olen = strlen (obuf);
6135 char *p = obuf + olen - 4;
6136 const char **names = (address_mode == mode_64bit
6137 ? names64 : names32);
6139 /* We might have a suffix when disassembling with -Msuffix. */
6143 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6145 && (prefixes & PREFIX_ADDR)
6148 && CONST_STRNEQ (p - 7, "addr")
6149 && (CONST_STRNEQ (p - 3, "16")
6150 || CONST_STRNEQ (p - 3, "32")))
6155 /* mwait %eax,%ecx */
6156 strcpy (p, "mwait");
6158 strcpy (op_out[0], names[0]);
6162 /* monitor %eax,%ecx,%edx" */
6163 strcpy (p, "monitor");
6166 const char **op1_names;
6167 if (!(prefixes & PREFIX_ADDR))
6168 op1_names = (address_mode == mode_16bit
6172 op1_names = (address_mode != mode_32bit
6173 ? names32 : names16);
6174 used_prefixes |= PREFIX_ADDR;
6176 strcpy (op_out[0], op1_names[0]);
6177 strcpy (op_out[2], names[2]);
6182 strcpy (op_out[1], names[1]);
6193 XCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6195 if (modrm.mod == 3 && modrm.reg == 2 && modrm.rm <= 1)
6197 /* Override "lgdt". */
6198 size_t olen = strlen (obuf);
6199 char *p = obuf + olen - 4;
6201 /* We might have a suffix when disassembling with -Msuffix. */
6205 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6207 && (prefixes & PREFIX_ADDR)
6210 && CONST_STRNEQ (p - 7, "addr")
6211 && (CONST_STRNEQ (p - 3, "16")
6212 || CONST_STRNEQ (p - 3, "32")))
6217 strcpy (p, "xsetbv");
6221 strcpy (p, "xgetbv");
6230 SVME_Fixup (int bytemode, int sizeflag)
6262 OP_M (bytemode, sizeflag);
6265 /* Override "lidt". */
6266 p = obuf + strlen (obuf) - 4;
6267 /* We might have a suffix. */
6271 if (!(prefixes & PREFIX_ADDR))
6276 used_prefixes |= PREFIX_ADDR;
6280 strcpy (op_out[1], names32[1]);
6286 *obufp++ = open_char;
6287 if (address_mode == mode_64bit || (sizeflag & AFLAG))
6291 strcpy (obufp, alt);
6292 obufp += strlen (alt);
6293 *obufp++ = close_char;
6300 INVLPG_Fixup (int bytemode, int sizeflag)
6313 OP_M (bytemode, sizeflag);
6316 /* Override "invlpg". */
6317 strcpy (obuf + strlen (obuf) - 6, alt);
6324 /* Throw away prefixes and 1st. opcode byte. */
6325 codep = insn_codep + 1;
6330 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6337 /* Override "sgdt". */
6338 char *p = obuf + strlen (obuf) - 4;
6340 /* We might have a suffix when disassembling with -Msuffix. */
6347 strcpy (p, "vmcall");
6350 strcpy (p, "vmlaunch");
6353 strcpy (p, "vmresume");
6356 strcpy (p, "vmxoff");
6367 OP_VMX (int bytemode, int sizeflag)
6369 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6370 if (prefixes & PREFIX_DATA)
6371 strcpy (obuf, "vmclear");
6372 else if (prefixes & PREFIX_REPZ)
6373 strcpy (obuf, "vmxon");
6375 strcpy (obuf, "vmptrld");
6376 OP_E (bytemode, sizeflag);
6380 REP_Fixup (int bytemode, int sizeflag)
6382 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6386 if (prefixes & PREFIX_REPZ)
6387 switch (*insn_codep)
6389 case 0x6e: /* outsb */
6390 case 0x6f: /* outsw/outsl */
6391 case 0xa4: /* movsb */
6392 case 0xa5: /* movsw/movsl/movsq */
6398 case 0xaa: /* stosb */
6399 case 0xab: /* stosw/stosl/stosq */
6400 case 0xac: /* lodsb */
6401 case 0xad: /* lodsw/lodsl/lodsq */
6402 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6407 case 0x6c: /* insb */
6408 case 0x6d: /* insl/insw */
6424 olen = strlen (obuf);
6425 p = obuf + olen - ilen - 1 - 4;
6426 /* Handle "repz [addr16|addr32]". */
6427 if ((prefixes & PREFIX_ADDR))
6430 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6438 OP_IMREG (bytemode, sizeflag);
6441 OP_ESreg (bytemode, sizeflag);
6444 OP_DSreg (bytemode, sizeflag);
6453 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
6458 /* Change cmpxchg8b to cmpxchg16b. */
6459 char *p = obuf + strlen (obuf) - 2;
6463 OP_M (bytemode, sizeflag);
6467 XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6469 sprintf (scratchbuf, "%%xmm%d", reg);
6470 oappend (scratchbuf + intel_syntax);
6474 CRC32_Fixup (int bytemode, int sizeflag)
6476 /* Add proper suffix to "crc32". */
6477 char *p = obuf + strlen (obuf);
6494 else if (sizeflag & DFLAG)
6498 used_prefixes |= (prefixes & PREFIX_DATA);
6501 oappend (INTERNAL_DISASSEMBLER_ERROR);
6510 /* Skip mod/rm byte. */
6515 add = (rex & REX_B) ? 8 : 0;
6516 if (bytemode == b_mode)
6520 oappend (names8rex[modrm.rm + add]);
6522 oappend (names8[modrm.rm + add]);
6528 oappend (names64[modrm.rm + add]);
6529 else if ((prefixes & PREFIX_DATA))
6530 oappend (names16[modrm.rm + add]);
6532 oappend (names32[modrm.rm + add]);
6536 OP_E (bytemode, sizeflag);