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 OP_E (int, int);
54 static void OP_G (int, int);
55 static bfd_vma
get64 (void);
56 static bfd_signed_vma
get32 (void);
57 static bfd_signed_vma
get32s (void);
58 static int get16 (void);
59 static void set_op (bfd_vma
, int);
60 static void OP_REG (int, int);
61 static void OP_IMREG (int, int);
62 static void OP_I (int, int);
63 static void OP_I64 (int, int);
64 static void OP_sI (int, int);
65 static void OP_J (int, int);
66 static void OP_SEG (int, int);
67 static void OP_DIR (int, int);
68 static void OP_OFF (int, int);
69 static void OP_OFF64 (int, int);
70 static void ptr_reg (int, int);
71 static void OP_ESreg (int, int);
72 static void OP_DSreg (int, int);
73 static void OP_C (int, int);
74 static void OP_D (int, int);
75 static void OP_T (int, int);
76 static void OP_R (int, int);
77 static void OP_MMX (int, int);
78 static void OP_XMM (int, int);
79 static void OP_EM (int, int);
80 static void OP_EX (int, int);
81 static void OP_EMC (int,int);
82 static void OP_MXC (int,int);
83 static void OP_MS (int, int);
84 static void OP_XS (int, int);
85 static void OP_M (int, int);
86 static void OP_VMX (int, int);
87 static void OP_0fae (int, int);
88 static void OP_0f07 (int, int);
89 static void NOP_Fixup1 (int, int);
90 static void NOP_Fixup2 (int, int);
91 static void OP_3DNowSuffix (int, int);
92 static void OP_SIMD_Suffix (int, int);
93 static void SIMD_Fixup (int, int);
94 static void PNI_Fixup (int, int);
95 static void SVME_Fixup (int, int);
96 static void INVLPG_Fixup (int, int);
97 static void BadOp (void);
98 static void VMX_Fixup (int, int);
99 static void REP_Fixup (int, int);
100 static void CMPXCHG8B_Fixup (int, int);
101 static void XMM_Fixup (int, int);
102 static void CRC32_Fixup (int, int);
105 /* Points to first byte not fetched. */
106 bfd_byte
*max_fetched
;
107 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
120 enum address_mode address_mode
;
122 /* Flags for the prefixes for the current instruction. See below. */
125 /* REX prefix the current instruction. See below. */
127 /* Bits of REX we've already used. */
129 /* Mark parts used in the REX prefix. When we are testing for
130 empty prefix (for 8bit register REX extension), just mask it
131 out. Otherwise test for REX bit is excuse for existence of REX
132 only in case value is nonzero. */
133 #define USED_REX(value) \
138 rex_used |= (value) | REX_OPCODE; \
141 rex_used |= REX_OPCODE; \
144 /* Flags for prefixes which we somehow handled when printing the
145 current instruction. */
146 static int used_prefixes
;
148 /* Flags stored in PREFIXES. */
149 #define PREFIX_REPZ 1
150 #define PREFIX_REPNZ 2
151 #define PREFIX_LOCK 4
153 #define PREFIX_SS 0x10
154 #define PREFIX_DS 0x20
155 #define PREFIX_ES 0x40
156 #define PREFIX_FS 0x80
157 #define PREFIX_GS 0x100
158 #define PREFIX_DATA 0x200
159 #define PREFIX_ADDR 0x400
160 #define PREFIX_FWAIT 0x800
162 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
163 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
165 #define FETCH_DATA(info, addr) \
166 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
167 ? 1 : fetch_data ((info), (addr)))
170 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
173 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
174 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
176 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
177 status
= (*info
->read_memory_func
) (start
,
179 addr
- priv
->max_fetched
,
185 /* If we did manage to read at least one byte, then
186 print_insn_i386 will do something sensible. Otherwise, print
187 an error. We do that here because this is where we know
189 if (priv
->max_fetched
== priv
->the_buffer
)
190 (*info
->memory_error_func
) (status
, start
, info
);
191 longjmp (priv
->bailout
, 1);
194 priv
->max_fetched
= addr
;
198 #define XX { NULL, 0 }
200 #define Eb { OP_E, b_mode }
201 #define Ev { OP_E, v_mode }
202 #define Ed { OP_E, d_mode }
203 #define Edq { OP_E, dq_mode }
204 #define Edqw { OP_E, dqw_mode }
205 #define Edqb { OP_E, dqb_mode }
206 #define Edqd { OP_E, dqd_mode }
207 #define indirEv { OP_indirE, stack_v_mode }
208 #define indirEp { OP_indirE, f_mode }
209 #define stackEv { OP_E, stack_v_mode }
210 #define Em { OP_E, m_mode }
211 #define Ew { OP_E, w_mode }
212 #define M { OP_M, 0 } /* lea, lgdt, etc. */
213 #define Ma { OP_M, v_mode }
214 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
215 #define Mq { OP_M, q_mode }
216 #define Gb { OP_G, b_mode }
217 #define Gv { OP_G, v_mode }
218 #define Gd { OP_G, d_mode }
219 #define Gdq { OP_G, dq_mode }
220 #define Gm { OP_G, m_mode }
221 #define Gw { OP_G, w_mode }
222 #define Rd { OP_R, d_mode }
223 #define Rm { OP_R, m_mode }
224 #define Ib { OP_I, b_mode }
225 #define sIb { OP_sI, b_mode } /* sign extened byte */
226 #define Iv { OP_I, v_mode }
227 #define Iq { OP_I, q_mode }
228 #define Iv64 { OP_I64, v_mode }
229 #define Iw { OP_I, w_mode }
230 #define I1 { OP_I, const_1_mode }
231 #define Jb { OP_J, b_mode }
232 #define Jv { OP_J, v_mode }
233 #define Cm { OP_C, m_mode }
234 #define Dm { OP_D, m_mode }
235 #define Td { OP_T, d_mode }
237 #define RMeAX { OP_REG, eAX_reg }
238 #define RMeBX { OP_REG, eBX_reg }
239 #define RMeCX { OP_REG, eCX_reg }
240 #define RMeDX { OP_REG, eDX_reg }
241 #define RMeSP { OP_REG, eSP_reg }
242 #define RMeBP { OP_REG, eBP_reg }
243 #define RMeSI { OP_REG, eSI_reg }
244 #define RMeDI { OP_REG, eDI_reg }
245 #define RMrAX { OP_REG, rAX_reg }
246 #define RMrBX { OP_REG, rBX_reg }
247 #define RMrCX { OP_REG, rCX_reg }
248 #define RMrDX { OP_REG, rDX_reg }
249 #define RMrSP { OP_REG, rSP_reg }
250 #define RMrBP { OP_REG, rBP_reg }
251 #define RMrSI { OP_REG, rSI_reg }
252 #define RMrDI { OP_REG, rDI_reg }
253 #define RMAL { OP_REG, al_reg }
254 #define RMAL { OP_REG, al_reg }
255 #define RMCL { OP_REG, cl_reg }
256 #define RMDL { OP_REG, dl_reg }
257 #define RMBL { OP_REG, bl_reg }
258 #define RMAH { OP_REG, ah_reg }
259 #define RMCH { OP_REG, ch_reg }
260 #define RMDH { OP_REG, dh_reg }
261 #define RMBH { OP_REG, bh_reg }
262 #define RMAX { OP_REG, ax_reg }
263 #define RMDX { OP_REG, dx_reg }
265 #define eAX { OP_IMREG, eAX_reg }
266 #define eBX { OP_IMREG, eBX_reg }
267 #define eCX { OP_IMREG, eCX_reg }
268 #define eDX { OP_IMREG, eDX_reg }
269 #define eSP { OP_IMREG, eSP_reg }
270 #define eBP { OP_IMREG, eBP_reg }
271 #define eSI { OP_IMREG, eSI_reg }
272 #define eDI { OP_IMREG, eDI_reg }
273 #define AL { OP_IMREG, al_reg }
274 #define CL { OP_IMREG, cl_reg }
275 #define DL { OP_IMREG, dl_reg }
276 #define BL { OP_IMREG, bl_reg }
277 #define AH { OP_IMREG, ah_reg }
278 #define CH { OP_IMREG, ch_reg }
279 #define DH { OP_IMREG, dh_reg }
280 #define BH { OP_IMREG, bh_reg }
281 #define AX { OP_IMREG, ax_reg }
282 #define DX { OP_IMREG, dx_reg }
283 #define zAX { OP_IMREG, z_mode_ax_reg }
284 #define indirDX { OP_IMREG, indir_dx_reg }
286 #define Sw { OP_SEG, w_mode }
287 #define Sv { OP_SEG, v_mode }
288 #define Ap { OP_DIR, 0 }
289 #define Ob { OP_OFF64, b_mode }
290 #define Ov { OP_OFF64, v_mode }
291 #define Xb { OP_DSreg, eSI_reg }
292 #define Xv { OP_DSreg, eSI_reg }
293 #define Xz { OP_DSreg, eSI_reg }
294 #define Yb { OP_ESreg, eDI_reg }
295 #define Yv { OP_ESreg, eDI_reg }
296 #define DSBX { OP_DSreg, eBX_reg }
298 #define es { OP_REG, es_reg }
299 #define ss { OP_REG, ss_reg }
300 #define cs { OP_REG, cs_reg }
301 #define ds { OP_REG, ds_reg }
302 #define fs { OP_REG, fs_reg }
303 #define gs { OP_REG, gs_reg }
305 #define MX { OP_MMX, 0 }
306 #define XM { OP_XMM, 0 }
307 #define EM { OP_EM, v_mode }
308 #define EX { OP_EX, v_mode }
309 #define MS { OP_MS, v_mode }
310 #define XS { OP_XS, v_mode }
311 #define EMC { OP_EMC, v_mode }
312 #define MXC { OP_MXC, 0 }
313 #define VM { OP_VMX, q_mode }
314 #define OPSUF { OP_3DNowSuffix, 0 }
315 #define OPSIMD { OP_SIMD_Suffix, 0 }
316 #define XMM0 { XMM_Fixup, 0 }
318 /* Used handle "rep" prefix for string instructions. */
319 #define Xbr { REP_Fixup, eSI_reg }
320 #define Xvr { REP_Fixup, eSI_reg }
321 #define Ybr { REP_Fixup, eDI_reg }
322 #define Yvr { REP_Fixup, eDI_reg }
323 #define Yzr { REP_Fixup, eDI_reg }
324 #define indirDXr { REP_Fixup, indir_dx_reg }
325 #define ALr { REP_Fixup, al_reg }
326 #define eAXr { REP_Fixup, eAX_reg }
328 #define cond_jump_flag { NULL, cond_jump_mode }
329 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
331 /* bits in sizeflag */
332 #define SUFFIX_ALWAYS 4
336 #define b_mode 1 /* byte operand */
337 #define v_mode 2 /* operand size depends on prefixes */
338 #define w_mode 3 /* word operand */
339 #define d_mode 4 /* double word operand */
340 #define q_mode 5 /* quad word operand */
341 #define t_mode 6 /* ten-byte operand */
342 #define x_mode 7 /* 16-byte XMM operand */
343 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
344 #define cond_jump_mode 9
345 #define loop_jcxz_mode 10
346 #define dq_mode 11 /* operand size depends on REX prefixes. */
347 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
348 #define f_mode 13 /* 4- or 6-byte pointer operand */
349 #define const_1_mode 14
350 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
351 #define z_mode 16 /* non-quad operand size depends on prefixes */
352 #define o_mode 17 /* 16-byte operand */
353 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
354 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
399 #define z_mode_ax_reg 149
400 #define indir_dx_reg 150
404 #define USE_PREFIX_USER_TABLE 3
405 #define X86_64_SPECIAL 4
406 #define IS_3BYTE_OPCODE 5
408 #define FLOAT NULL, { { NULL, FLOATCODE } }
410 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
411 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
412 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
413 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
414 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
415 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
416 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
417 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
418 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
419 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
420 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
421 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
422 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
423 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
424 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
425 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
426 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
427 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
428 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
429 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
430 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
431 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
432 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
433 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
434 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
435 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
436 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
437 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
439 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
440 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
441 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
442 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
443 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
444 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
445 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
446 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
447 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
448 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
449 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
450 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
451 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
452 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
453 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
454 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
455 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
456 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
457 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
458 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
459 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
460 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
461 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
462 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
463 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
464 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
465 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
466 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
467 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
468 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
469 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
470 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
471 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
472 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
473 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
474 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
475 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
476 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
477 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
478 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
479 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
480 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
481 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
482 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
483 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
484 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
485 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
486 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
487 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
488 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
489 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
490 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
491 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
492 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
493 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
494 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
495 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
496 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
497 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
498 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
499 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
500 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
501 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
502 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
503 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
504 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
505 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
506 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
507 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
508 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
509 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
510 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
511 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
512 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
513 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
514 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
515 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
516 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
517 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
518 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
519 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
520 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
521 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
522 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
523 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
524 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
525 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
526 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
527 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
528 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
529 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
530 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
531 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
534 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
535 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
536 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
537 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
539 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
540 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
542 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
553 /* Upper case letters in the instruction names here are macros.
554 'A' => print 'b' if no register operands or suffix_always is true
555 'B' => print 'b' if suffix_always is true
556 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
558 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
559 . suffix_always is true
560 'E' => print 'e' if 32-bit form of jcxz
561 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
562 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
563 'H' => print ",pt" or ",pn" branch hint
564 'I' => honor following macro letter even in Intel mode (implemented only
565 . for some of the macro letters)
567 'K' => print 'd' or 'q' if rex prefix is present.
568 'L' => print 'l' if suffix_always is true
569 'N' => print 'n' if instruction has no wait "prefix"
570 'O' => print 'd' or 'o' (or 'q' in Intel mode)
571 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
572 . or suffix_always is true. print 'q' if rex prefix is present.
573 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
575 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
576 'S' => print 'w', 'l' or 'q' if suffix_always is true
577 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
578 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
579 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
580 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
581 'X' => print 's', 'd' depending on data16 prefix (for XMM)
582 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
583 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
585 Many of the above letters print nothing in Intel mode. See "putop"
588 Braces '{' and '}', and vertical bars '|', indicate alternative
589 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
590 modes. In cases where there are only two alternatives, the X86_64
591 instruction is reserved, and "(bad)" is printed.
594 static const struct dis386 dis386
[] = {
596 { "addB", { Eb
, Gb
} },
597 { "addS", { Ev
, Gv
} },
598 { "addB", { Gb
, Eb
} },
599 { "addS", { Gv
, Ev
} },
600 { "addB", { AL
, Ib
} },
601 { "addS", { eAX
, Iv
} },
602 { "push{T|}", { es
} },
603 { "pop{T|}", { es
} },
605 { "orB", { Eb
, Gb
} },
606 { "orS", { Ev
, Gv
} },
607 { "orB", { Gb
, Eb
} },
608 { "orS", { Gv
, Ev
} },
609 { "orB", { AL
, Ib
} },
610 { "orS", { eAX
, Iv
} },
611 { "push{T|}", { cs
} },
612 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
614 { "adcB", { Eb
, Gb
} },
615 { "adcS", { Ev
, Gv
} },
616 { "adcB", { Gb
, Eb
} },
617 { "adcS", { Gv
, Ev
} },
618 { "adcB", { AL
, Ib
} },
619 { "adcS", { eAX
, Iv
} },
620 { "push{T|}", { ss
} },
621 { "pop{T|}", { ss
} },
623 { "sbbB", { Eb
, Gb
} },
624 { "sbbS", { Ev
, Gv
} },
625 { "sbbB", { Gb
, Eb
} },
626 { "sbbS", { Gv
, Ev
} },
627 { "sbbB", { AL
, Ib
} },
628 { "sbbS", { eAX
, Iv
} },
629 { "push{T|}", { ds
} },
630 { "pop{T|}", { ds
} },
632 { "andB", { Eb
, Gb
} },
633 { "andS", { Ev
, Gv
} },
634 { "andB", { Gb
, Eb
} },
635 { "andS", { Gv
, Ev
} },
636 { "andB", { AL
, Ib
} },
637 { "andS", { eAX
, Iv
} },
638 { "(bad)", { XX
} }, /* SEG ES prefix */
639 { "daa{|}", { XX
} },
641 { "subB", { Eb
, Gb
} },
642 { "subS", { Ev
, Gv
} },
643 { "subB", { Gb
, Eb
} },
644 { "subS", { Gv
, Ev
} },
645 { "subB", { AL
, Ib
} },
646 { "subS", { eAX
, Iv
} },
647 { "(bad)", { XX
} }, /* SEG CS prefix */
648 { "das{|}", { XX
} },
650 { "xorB", { Eb
, Gb
} },
651 { "xorS", { Ev
, Gv
} },
652 { "xorB", { Gb
, Eb
} },
653 { "xorS", { Gv
, Ev
} },
654 { "xorB", { AL
, Ib
} },
655 { "xorS", { eAX
, Iv
} },
656 { "(bad)", { XX
} }, /* SEG SS prefix */
657 { "aaa{|}", { XX
} },
659 { "cmpB", { Eb
, Gb
} },
660 { "cmpS", { Ev
, Gv
} },
661 { "cmpB", { Gb
, Eb
} },
662 { "cmpS", { Gv
, Ev
} },
663 { "cmpB", { AL
, Ib
} },
664 { "cmpS", { eAX
, Iv
} },
665 { "(bad)", { XX
} }, /* SEG DS prefix */
666 { "aas{|}", { XX
} },
668 { "inc{S|}", { RMeAX
} },
669 { "inc{S|}", { RMeCX
} },
670 { "inc{S|}", { RMeDX
} },
671 { "inc{S|}", { RMeBX
} },
672 { "inc{S|}", { RMeSP
} },
673 { "inc{S|}", { RMeBP
} },
674 { "inc{S|}", { RMeSI
} },
675 { "inc{S|}", { RMeDI
} },
677 { "dec{S|}", { RMeAX
} },
678 { "dec{S|}", { RMeCX
} },
679 { "dec{S|}", { RMeDX
} },
680 { "dec{S|}", { RMeBX
} },
681 { "dec{S|}", { RMeSP
} },
682 { "dec{S|}", { RMeBP
} },
683 { "dec{S|}", { RMeSI
} },
684 { "dec{S|}", { RMeDI
} },
686 { "pushV", { RMrAX
} },
687 { "pushV", { RMrCX
} },
688 { "pushV", { RMrDX
} },
689 { "pushV", { RMrBX
} },
690 { "pushV", { RMrSP
} },
691 { "pushV", { RMrBP
} },
692 { "pushV", { RMrSI
} },
693 { "pushV", { RMrDI
} },
695 { "popV", { RMrAX
} },
696 { "popV", { RMrCX
} },
697 { "popV", { RMrDX
} },
698 { "popV", { RMrBX
} },
699 { "popV", { RMrSP
} },
700 { "popV", { RMrBP
} },
701 { "popV", { RMrSI
} },
702 { "popV", { RMrDI
} },
708 { "(bad)", { XX
} }, /* seg fs */
709 { "(bad)", { XX
} }, /* seg gs */
710 { "(bad)", { XX
} }, /* op size prefix */
711 { "(bad)", { XX
} }, /* adr size prefix */
714 { "imulS", { Gv
, Ev
, Iv
} },
715 { "pushT", { sIb
} },
716 { "imulS", { Gv
, Ev
, sIb
} },
717 { "ins{b||b|}", { Ybr
, indirDX
} },
718 { "ins{R||G|}", { Yzr
, indirDX
} },
719 { "outs{b||b|}", { indirDXr
, Xb
} },
720 { "outs{R||G|}", { indirDXr
, Xz
} },
722 { "joH", { Jb
, XX
, cond_jump_flag
} },
723 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
724 { "jbH", { Jb
, XX
, cond_jump_flag
} },
725 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
726 { "jeH", { Jb
, XX
, cond_jump_flag
} },
727 { "jneH", { Jb
, XX
, cond_jump_flag
} },
728 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
729 { "jaH", { Jb
, XX
, cond_jump_flag
} },
731 { "jsH", { Jb
, XX
, cond_jump_flag
} },
732 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
733 { "jpH", { Jb
, XX
, cond_jump_flag
} },
734 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
735 { "jlH", { Jb
, XX
, cond_jump_flag
} },
736 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
737 { "jleH", { Jb
, XX
, cond_jump_flag
} },
738 { "jgH", { Jb
, XX
, cond_jump_flag
} },
744 { "testB", { Eb
, Gb
} },
745 { "testS", { Ev
, Gv
} },
746 { "xchgB", { Eb
, Gb
} },
747 { "xchgS", { Ev
, Gv
} },
749 { "movB", { Eb
, Gb
} },
750 { "movS", { Ev
, Gv
} },
751 { "movB", { Gb
, Eb
} },
752 { "movS", { Gv
, Ev
} },
753 { "movD", { Sv
, Sw
} },
754 { "leaS", { Gv
, M
} },
755 { "movD", { Sw
, Sv
} },
759 { "xchgS", { RMeCX
, eAX
} },
760 { "xchgS", { RMeDX
, eAX
} },
761 { "xchgS", { RMeBX
, eAX
} },
762 { "xchgS", { RMeSP
, eAX
} },
763 { "xchgS", { RMeBP
, eAX
} },
764 { "xchgS", { RMeSI
, eAX
} },
765 { "xchgS", { RMeDI
, eAX
} },
767 { "cW{t||t|}R", { XX
} },
768 { "cR{t||t|}O", { XX
} },
769 { "Jcall{T|}", { Ap
} },
770 { "(bad)", { XX
} }, /* fwait */
771 { "pushfT", { XX
} },
773 { "sahf{|}", { XX
} },
774 { "lahf{|}", { XX
} },
776 { "movB", { AL
, Ob
} },
777 { "movS", { eAX
, Ov
} },
778 { "movB", { Ob
, AL
} },
779 { "movS", { Ov
, eAX
} },
780 { "movs{b||b|}", { Ybr
, Xb
} },
781 { "movs{R||R|}", { Yvr
, Xv
} },
782 { "cmps{b||b|}", { Xb
, Yb
} },
783 { "cmps{R||R|}", { Xv
, Yv
} },
785 { "testB", { AL
, Ib
} },
786 { "testS", { eAX
, Iv
} },
787 { "stosB", { Ybr
, AL
} },
788 { "stosS", { Yvr
, eAX
} },
789 { "lodsB", { ALr
, Xb
} },
790 { "lodsS", { eAXr
, Xv
} },
791 { "scasB", { AL
, Yb
} },
792 { "scasS", { eAX
, Yv
} },
794 { "movB", { RMAL
, Ib
} },
795 { "movB", { RMCL
, Ib
} },
796 { "movB", { RMDL
, Ib
} },
797 { "movB", { RMBL
, Ib
} },
798 { "movB", { RMAH
, Ib
} },
799 { "movB", { RMCH
, Ib
} },
800 { "movB", { RMDH
, Ib
} },
801 { "movB", { RMBH
, Ib
} },
803 { "movS", { RMeAX
, Iv64
} },
804 { "movS", { RMeCX
, Iv64
} },
805 { "movS", { RMeDX
, Iv64
} },
806 { "movS", { RMeBX
, Iv64
} },
807 { "movS", { RMeSP
, Iv64
} },
808 { "movS", { RMeBP
, Iv64
} },
809 { "movS", { RMeSI
, Iv64
} },
810 { "movS", { RMeDI
, Iv64
} },
816 { "les{S|}", { Gv
, Mp
} },
817 { "ldsS", { Gv
, Mp
} },
821 { "enterT", { Iw
, Ib
} },
822 { "leaveT", { XX
} },
827 { "into{|}", { XX
} },
834 { "aam{|}", { sIb
} },
835 { "aad{|}", { sIb
} },
837 { "xlat", { DSBX
} },
848 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
849 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
850 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
851 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
852 { "inB", { AL
, Ib
} },
853 { "inG", { zAX
, Ib
} },
854 { "outB", { Ib
, AL
} },
855 { "outG", { Ib
, zAX
} },
859 { "Jjmp{T|}", { Ap
} },
861 { "inB", { AL
, indirDX
} },
862 { "inG", { zAX
, indirDX
} },
863 { "outB", { indirDX
, AL
} },
864 { "outG", { indirDX
, zAX
} },
866 { "(bad)", { XX
} }, /* lock prefix */
868 { "(bad)", { XX
} }, /* repne */
869 { "(bad)", { XX
} }, /* repz */
885 static const struct dis386 dis386_twobyte
[] = {
889 { "larS", { Gv
, Ew
} },
890 { "lslS", { Gv
, Ew
} },
892 { "syscall", { XX
} },
894 { "sysretP", { XX
} },
897 { "wbinvd", { XX
} },
903 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
908 { "movlpX", { EX
, XM
, { SIMD_Fixup
, 'h' } } },
909 { "unpcklpX", { XM
, EX
} },
910 { "unpckhpX", { XM
, EX
} },
912 { "movhpX", { EX
, XM
, { SIMD_Fixup
, 'l' } } },
923 { "movZ", { Rm
, Cm
} },
924 { "movZ", { Rm
, Dm
} },
925 { "movZ", { Cm
, Rm
} },
926 { "movZ", { Dm
, Rm
} },
927 { "movL", { Rd
, Td
} },
929 { "movL", { Td
, Rd
} },
932 { "movapX", { XM
, EX
} },
933 { "movapX", { EX
, XM
} },
938 { "ucomisX", { XM
,EX
} },
939 { "comisX", { XM
,EX
} },
945 { "sysenter", { XX
} },
946 { "sysexit", { XX
} },
959 { "cmovo", { Gv
, Ev
} },
960 { "cmovno", { Gv
, Ev
} },
961 { "cmovb", { Gv
, Ev
} },
962 { "cmovae", { Gv
, Ev
} },
963 { "cmove", { Gv
, Ev
} },
964 { "cmovne", { Gv
, Ev
} },
965 { "cmovbe", { Gv
, Ev
} },
966 { "cmova", { Gv
, Ev
} },
968 { "cmovs", { Gv
, Ev
} },
969 { "cmovns", { Gv
, Ev
} },
970 { "cmovp", { Gv
, Ev
} },
971 { "cmovnp", { Gv
, Ev
} },
972 { "cmovl", { Gv
, Ev
} },
973 { "cmovge", { Gv
, Ev
} },
974 { "cmovle", { Gv
, Ev
} },
975 { "cmovg", { Gv
, Ev
} },
977 { "movmskpX", { Gdq
, XS
} },
981 { "andpX", { XM
, EX
} },
982 { "andnpX", { XM
, EX
} },
983 { "orpX", { XM
, EX
} },
984 { "xorpX", { XM
, EX
} },
995 { "punpcklbw", { MX
, EM
} },
996 { "punpcklwd", { MX
, EM
} },
997 { "punpckldq", { MX
, EM
} },
998 { "packsswb", { MX
, EM
} },
999 { "pcmpgtb", { MX
, EM
} },
1000 { "pcmpgtw", { MX
, EM
} },
1001 { "pcmpgtd", { MX
, EM
} },
1002 { "packuswb", { MX
, EM
} },
1004 { "punpckhbw", { MX
, EM
} },
1005 { "punpckhwd", { MX
, EM
} },
1006 { "punpckhdq", { MX
, EM
} },
1007 { "packssdw", { MX
, EM
} },
1010 { "movd", { MX
, Edq
} },
1017 { "pcmpeqb", { MX
, EM
} },
1018 { "pcmpeqw", { MX
, EM
} },
1019 { "pcmpeqd", { MX
, EM
} },
1024 { "(bad)", { XX
} },
1025 { "(bad)", { XX
} },
1031 { "joH", { Jv
, XX
, cond_jump_flag
} },
1032 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1033 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1034 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1035 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1036 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1037 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1038 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1040 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1041 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1042 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1043 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1044 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1045 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1046 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1047 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1050 { "setno", { Eb
} },
1052 { "setae", { Eb
} },
1054 { "setne", { Eb
} },
1055 { "setbe", { Eb
} },
1059 { "setns", { Eb
} },
1061 { "setnp", { Eb
} },
1063 { "setge", { Eb
} },
1064 { "setle", { Eb
} },
1067 { "pushT", { fs
} },
1069 { "cpuid", { XX
} },
1070 { "btS", { Ev
, Gv
} },
1071 { "shldS", { Ev
, Gv
, Ib
} },
1072 { "shldS", { Ev
, Gv
, CL
} },
1076 { "pushT", { gs
} },
1079 { "btsS", { Ev
, Gv
} },
1080 { "shrdS", { Ev
, Gv
, Ib
} },
1081 { "shrdS", { Ev
, Gv
, CL
} },
1083 { "imulS", { Gv
, Ev
} },
1085 { "cmpxchgB", { Eb
, Gb
} },
1086 { "cmpxchgS", { Ev
, Gv
} },
1087 { "lssS", { Gv
, Mp
} },
1088 { "btrS", { Ev
, Gv
} },
1089 { "lfsS", { Gv
, Mp
} },
1090 { "lgsS", { Gv
, Mp
} },
1091 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1092 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1097 { "btcS", { Ev
, Gv
} },
1098 { "bsfS", { Gv
, Ev
} },
1100 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1101 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1103 { "xaddB", { Eb
, Gb
} },
1104 { "xaddS", { Ev
, Gv
} },
1106 { "movntiS", { Ev
, Gv
} },
1107 { "pinsrw", { MX
, Edqw
, Ib
} },
1108 { "pextrw", { Gdq
, MS
, Ib
} },
1109 { "shufpX", { XM
, EX
, Ib
} },
1112 { "bswap", { RMeAX
} },
1113 { "bswap", { RMeCX
} },
1114 { "bswap", { RMeDX
} },
1115 { "bswap", { RMeBX
} },
1116 { "bswap", { RMeSP
} },
1117 { "bswap", { RMeBP
} },
1118 { "bswap", { RMeSI
} },
1119 { "bswap", { RMeDI
} },
1122 { "psrlw", { MX
, EM
} },
1123 { "psrld", { MX
, EM
} },
1124 { "psrlq", { MX
, EM
} },
1125 { "paddq", { MX
, EM
} },
1126 { "pmullw", { MX
, EM
} },
1128 { "pmovmskb", { Gdq
, MS
} },
1130 { "psubusb", { MX
, EM
} },
1131 { "psubusw", { MX
, EM
} },
1132 { "pminub", { MX
, EM
} },
1133 { "pand", { MX
, EM
} },
1134 { "paddusb", { MX
, EM
} },
1135 { "paddusw", { MX
, EM
} },
1136 { "pmaxub", { MX
, EM
} },
1137 { "pandn", { MX
, EM
} },
1139 { "pavgb", { MX
, EM
} },
1140 { "psraw", { MX
, EM
} },
1141 { "psrad", { MX
, EM
} },
1142 { "pavgw", { MX
, EM
} },
1143 { "pmulhuw", { MX
, EM
} },
1144 { "pmulhw", { MX
, EM
} },
1148 { "psubsb", { MX
, EM
} },
1149 { "psubsw", { MX
, EM
} },
1150 { "pminsw", { MX
, EM
} },
1151 { "por", { MX
, EM
} },
1152 { "paddsb", { MX
, EM
} },
1153 { "paddsw", { MX
, EM
} },
1154 { "pmaxsw", { MX
, EM
} },
1155 { "pxor", { MX
, EM
} },
1158 { "psllw", { MX
, EM
} },
1159 { "pslld", { MX
, EM
} },
1160 { "psllq", { MX
, EM
} },
1161 { "pmuludq", { MX
, EM
} },
1162 { "pmaddwd", { MX
, EM
} },
1163 { "psadbw", { MX
, EM
} },
1166 { "psubb", { MX
, EM
} },
1167 { "psubw", { MX
, EM
} },
1168 { "psubd", { MX
, EM
} },
1169 { "psubq", { MX
, EM
} },
1170 { "paddb", { MX
, EM
} },
1171 { "paddw", { MX
, EM
} },
1172 { "paddd", { MX
, EM
} },
1173 { "(bad)", { XX
} },
1176 static const unsigned char onebyte_has_modrm
[256] = {
1177 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1178 /* ------------------------------- */
1179 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1180 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1181 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1182 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1183 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1184 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1185 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1186 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1187 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1188 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1189 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1190 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1191 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1192 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1193 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1194 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1195 /* ------------------------------- */
1196 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1199 static const unsigned char twobyte_has_modrm
[256] = {
1200 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1201 /* ------------------------------- */
1202 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1203 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1204 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1205 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1206 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1207 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1208 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1209 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1210 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1211 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1212 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1213 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1214 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1215 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1216 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1217 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1218 /* ------------------------------- */
1219 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1222 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1223 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1224 /* ------------------------------- */
1225 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1226 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1227 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1228 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1229 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1230 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1231 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1232 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1233 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1234 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1235 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1236 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1237 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1238 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1239 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1240 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1241 /* ------------------------------- */
1242 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1245 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1246 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1247 /* ------------------------------- */
1248 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1249 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1250 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1251 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1252 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1253 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1254 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1255 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1256 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1257 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1258 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1259 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1260 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1261 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1262 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1263 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1264 /* ------------------------------- */
1265 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1268 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1269 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1270 /* ------------------------------- */
1271 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1272 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1273 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1274 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1275 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1276 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1277 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1278 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1279 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1280 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1281 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1282 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1283 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1284 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1285 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1286 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1287 /* ------------------------------- */
1288 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1291 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1292 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1293 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1294 /* ------------------------------- */
1295 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1296 /* 10 */ 0,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1297 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1298 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1299 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1300 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1301 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1302 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1303 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1304 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1305 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1306 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1307 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1308 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1309 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1310 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1311 /* ------------------------------- */
1312 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1315 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1316 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1317 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1318 /* ------------------------------- */
1319 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1320 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1321 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1322 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1323 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1324 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1325 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1326 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1327 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1328 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1329 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1330 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1331 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1332 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1333 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1334 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1335 /* ------------------------------- */
1336 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1339 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1340 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1341 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1342 /* ------------------------------- */
1343 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1344 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1345 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1346 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1347 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1348 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1349 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1350 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1351 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1352 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1353 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1354 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1355 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1356 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1357 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1358 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1359 /* ------------------------------- */
1360 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1363 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1364 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1365 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1366 /* ------------------------------- */
1367 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1368 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1369 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1370 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1371 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1372 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1373 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1374 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1375 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1376 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1377 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1378 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1379 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1380 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1381 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1382 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1383 /* ------------------------------- */
1384 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1387 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1388 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1389 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1390 /* ------------------------------- */
1391 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1392 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1393 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1394 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1395 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1396 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1397 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1398 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1399 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1400 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1401 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1402 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1403 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1404 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1405 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1406 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1407 /* ------------------------------- */
1408 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1411 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1412 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1413 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1414 /* ------------------------------- */
1415 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1416 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1417 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1418 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1419 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1420 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1421 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1422 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1423 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1424 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1425 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1426 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1427 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1428 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1429 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1430 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1431 /* ------------------------------- */
1432 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1435 static char obuf
[100];
1437 static char scratchbuf
[100];
1438 static unsigned char *start_codep
;
1439 static unsigned char *insn_codep
;
1440 static unsigned char *codep
;
1441 static disassemble_info
*the_info
;
1449 static unsigned char need_modrm
;
1451 /* If we are accessing mod/rm/reg without need_modrm set, then the
1452 values are stale. Hitting this abort likely indicates that you
1453 need to update onebyte_has_modrm or twobyte_has_modrm. */
1454 #define MODRM_CHECK if (!need_modrm) abort ()
1456 static const char **names64
;
1457 static const char **names32
;
1458 static const char **names16
;
1459 static const char **names8
;
1460 static const char **names8rex
;
1461 static const char **names_seg
;
1462 static const char **index16
;
1464 static const char *intel_names64
[] = {
1465 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1466 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1468 static const char *intel_names32
[] = {
1469 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1470 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1472 static const char *intel_names16
[] = {
1473 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1474 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1476 static const char *intel_names8
[] = {
1477 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1479 static const char *intel_names8rex
[] = {
1480 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1481 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1483 static const char *intel_names_seg
[] = {
1484 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1486 static const char *intel_index16
[] = {
1487 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1490 static const char *att_names64
[] = {
1491 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1492 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1494 static const char *att_names32
[] = {
1495 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1496 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1498 static const char *att_names16
[] = {
1499 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1500 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1502 static const char *att_names8
[] = {
1503 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1505 static const char *att_names8rex
[] = {
1506 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1507 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1509 static const char *att_names_seg
[] = {
1510 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1512 static const char *att_index16
[] = {
1513 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1516 static const struct dis386 grps
[][8] = {
1519 { "popU", { stackEv
} },
1520 { "(bad)", { XX
} },
1521 { "(bad)", { XX
} },
1522 { "(bad)", { XX
} },
1523 { "(bad)", { XX
} },
1524 { "(bad)", { XX
} },
1525 { "(bad)", { XX
} },
1526 { "(bad)", { XX
} },
1530 { "addA", { Eb
, Ib
} },
1531 { "orA", { Eb
, Ib
} },
1532 { "adcA", { Eb
, Ib
} },
1533 { "sbbA", { Eb
, Ib
} },
1534 { "andA", { Eb
, Ib
} },
1535 { "subA", { Eb
, Ib
} },
1536 { "xorA", { Eb
, Ib
} },
1537 { "cmpA", { Eb
, Ib
} },
1541 { "addQ", { Ev
, Iv
} },
1542 { "orQ", { Ev
, Iv
} },
1543 { "adcQ", { Ev
, Iv
} },
1544 { "sbbQ", { Ev
, Iv
} },
1545 { "andQ", { Ev
, Iv
} },
1546 { "subQ", { Ev
, Iv
} },
1547 { "xorQ", { Ev
, Iv
} },
1548 { "cmpQ", { Ev
, Iv
} },
1552 { "addQ", { Ev
, sIb
} },
1553 { "orQ", { Ev
, sIb
} },
1554 { "adcQ", { Ev
, sIb
} },
1555 { "sbbQ", { Ev
, sIb
} },
1556 { "andQ", { Ev
, sIb
} },
1557 { "subQ", { Ev
, sIb
} },
1558 { "xorQ", { Ev
, sIb
} },
1559 { "cmpQ", { Ev
, sIb
} },
1563 { "rolA", { Eb
, Ib
} },
1564 { "rorA", { Eb
, Ib
} },
1565 { "rclA", { Eb
, Ib
} },
1566 { "rcrA", { Eb
, Ib
} },
1567 { "shlA", { Eb
, Ib
} },
1568 { "shrA", { Eb
, Ib
} },
1569 { "(bad)", { XX
} },
1570 { "sarA", { Eb
, Ib
} },
1574 { "rolQ", { Ev
, Ib
} },
1575 { "rorQ", { Ev
, Ib
} },
1576 { "rclQ", { Ev
, Ib
} },
1577 { "rcrQ", { Ev
, Ib
} },
1578 { "shlQ", { Ev
, Ib
} },
1579 { "shrQ", { Ev
, Ib
} },
1580 { "(bad)", { XX
} },
1581 { "sarQ", { Ev
, Ib
} },
1585 { "rolA", { Eb
, I1
} },
1586 { "rorA", { Eb
, I1
} },
1587 { "rclA", { Eb
, I1
} },
1588 { "rcrA", { Eb
, I1
} },
1589 { "shlA", { Eb
, I1
} },
1590 { "shrA", { Eb
, I1
} },
1591 { "(bad)", { XX
} },
1592 { "sarA", { Eb
, I1
} },
1596 { "rolQ", { Ev
, I1
} },
1597 { "rorQ", { Ev
, I1
} },
1598 { "rclQ", { Ev
, I1
} },
1599 { "rcrQ", { Ev
, I1
} },
1600 { "shlQ", { Ev
, I1
} },
1601 { "shrQ", { Ev
, I1
} },
1602 { "(bad)", { XX
} },
1603 { "sarQ", { Ev
, I1
} },
1607 { "rolA", { Eb
, CL
} },
1608 { "rorA", { Eb
, CL
} },
1609 { "rclA", { Eb
, CL
} },
1610 { "rcrA", { Eb
, CL
} },
1611 { "shlA", { Eb
, CL
} },
1612 { "shrA", { Eb
, CL
} },
1613 { "(bad)", { XX
} },
1614 { "sarA", { Eb
, CL
} },
1618 { "rolQ", { Ev
, CL
} },
1619 { "rorQ", { Ev
, CL
} },
1620 { "rclQ", { Ev
, CL
} },
1621 { "rcrQ", { Ev
, CL
} },
1622 { "shlQ", { Ev
, CL
} },
1623 { "shrQ", { Ev
, CL
} },
1624 { "(bad)", { XX
} },
1625 { "sarQ", { Ev
, CL
} },
1629 { "testA", { Eb
, Ib
} },
1630 { "(bad)", { Eb
} },
1633 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1634 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1635 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1636 { "idivA", { Eb
} }, /* and idiv for consistency. */
1640 { "testQ", { Ev
, Iv
} },
1641 { "(bad)", { XX
} },
1644 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1645 { "imulQ", { Ev
} },
1647 { "idivQ", { Ev
} },
1653 { "(bad)", { XX
} },
1654 { "(bad)", { XX
} },
1655 { "(bad)", { XX
} },
1656 { "(bad)", { XX
} },
1657 { "(bad)", { XX
} },
1658 { "(bad)", { XX
} },
1664 { "callT", { indirEv
} },
1665 { "JcallT", { indirEp
} },
1666 { "jmpT", { indirEv
} },
1667 { "JjmpT", { indirEp
} },
1668 { "pushU", { stackEv
} },
1669 { "(bad)", { XX
} },
1673 { "sldtD", { Sv
} },
1679 { "(bad)", { XX
} },
1680 { "(bad)", { XX
} },
1684 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1685 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1686 { "lgdt{Q|Q||}", { M
} },
1687 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1688 { "smswD", { Sv
} },
1689 { "(bad)", { XX
} },
1691 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1695 { "(bad)", { XX
} },
1696 { "(bad)", { XX
} },
1697 { "(bad)", { XX
} },
1698 { "(bad)", { XX
} },
1699 { "btQ", { Ev
, Ib
} },
1700 { "btsQ", { Ev
, Ib
} },
1701 { "btrQ", { Ev
, Ib
} },
1702 { "btcQ", { Ev
, Ib
} },
1706 { "(bad)", { XX
} },
1707 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1708 { "(bad)", { XX
} },
1709 { "(bad)", { XX
} },
1710 { "(bad)", { XX
} },
1711 { "(bad)", { XX
} },
1712 { "", { VM
} }, /* See OP_VMX. */
1713 { "vmptrst", { Mq
} },
1717 { "movA", { Eb
, Ib
} },
1718 { "(bad)", { XX
} },
1719 { "(bad)", { XX
} },
1720 { "(bad)", { XX
} },
1721 { "(bad)", { XX
} },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1724 { "(bad)", { XX
} },
1728 { "movQ", { Ev
, Iv
} },
1729 { "(bad)", { XX
} },
1730 { "(bad)", { XX
} },
1731 { "(bad)", { XX
} },
1732 { "(bad)", { XX
} },
1733 { "(bad)", { XX
} },
1734 { "(bad)", { XX
} },
1735 { "(bad)", { XX
} },
1739 { "(bad)", { XX
} },
1740 { "(bad)", { XX
} },
1741 { "psrlw", { MS
, Ib
} },
1742 { "(bad)", { XX
} },
1743 { "psraw", { MS
, Ib
} },
1744 { "(bad)", { XX
} },
1745 { "psllw", { MS
, Ib
} },
1746 { "(bad)", { XX
} },
1750 { "(bad)", { XX
} },
1751 { "(bad)", { XX
} },
1752 { "psrld", { MS
, Ib
} },
1753 { "(bad)", { XX
} },
1754 { "psrad", { MS
, Ib
} },
1755 { "(bad)", { XX
} },
1756 { "pslld", { MS
, Ib
} },
1757 { "(bad)", { XX
} },
1761 { "(bad)", { XX
} },
1762 { "(bad)", { XX
} },
1763 { "psrlq", { MS
, Ib
} },
1764 { "psrldq", { MS
, Ib
} },
1765 { "(bad)", { XX
} },
1766 { "(bad)", { XX
} },
1767 { "psllq", { MS
, Ib
} },
1768 { "pslldq", { MS
, Ib
} },
1772 { "fxsave", { Ev
} },
1773 { "fxrstor", { Ev
} },
1774 { "ldmxcsr", { Ev
} },
1775 { "stmxcsr", { Ev
} },
1776 { "(bad)", { XX
} },
1777 { "lfence", { { OP_0fae
, 0 } } },
1778 { "mfence", { { OP_0fae
, 0 } } },
1779 { "clflush", { { OP_0fae
, 0 } } },
1783 { "prefetchnta", { Ev
} },
1784 { "prefetcht0", { Ev
} },
1785 { "prefetcht1", { Ev
} },
1786 { "prefetcht2", { Ev
} },
1787 { "(bad)", { XX
} },
1788 { "(bad)", { XX
} },
1789 { "(bad)", { XX
} },
1790 { "(bad)", { XX
} },
1794 { "prefetch", { Eb
} },
1795 { "prefetchw", { Eb
} },
1796 { "(bad)", { XX
} },
1797 { "(bad)", { XX
} },
1798 { "(bad)", { XX
} },
1799 { "(bad)", { XX
} },
1800 { "(bad)", { XX
} },
1801 { "(bad)", { XX
} },
1805 { "xstore-rng", { { OP_0f07
, 0 } } },
1806 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1807 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1808 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1809 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1810 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1811 { "(bad)", { { OP_0f07
, 0 } } },
1812 { "(bad)", { { OP_0f07
, 0 } } },
1816 { "montmul", { { OP_0f07
, 0 } } },
1817 { "xsha1", { { OP_0f07
, 0 } } },
1818 { "xsha256", { { OP_0f07
, 0 } } },
1819 { "(bad)", { { OP_0f07
, 0 } } },
1820 { "(bad)", { { OP_0f07
, 0 } } },
1821 { "(bad)", { { OP_0f07
, 0 } } },
1822 { "(bad)", { { OP_0f07
, 0 } } },
1823 { "(bad)", { { OP_0f07
, 0 } } },
1827 static const struct dis386 prefix_user_table
[][4] = {
1830 { "addps", { XM
, EX
} },
1831 { "addss", { XM
, EX
} },
1832 { "addpd", { XM
, EX
} },
1833 { "addsd", { XM
, EX
} },
1837 { "", { XM
, EX
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1838 { "", { XM
, EX
, OPSIMD
} },
1839 { "", { XM
, EX
, OPSIMD
} },
1840 { "", { XM
, EX
, OPSIMD
} },
1844 { "cvtpi2ps", { XM
, EMC
} },
1845 { "cvtsi2ssY", { XM
, Ev
} },
1846 { "cvtpi2pd", { XM
, EMC
} },
1847 { "cvtsi2sdY", { XM
, Ev
} },
1851 { "cvtps2pi", { MXC
, EX
} },
1852 { "cvtss2siY", { Gv
, EX
} },
1853 { "cvtpd2pi", { MXC
, EX
} },
1854 { "cvtsd2siY", { Gv
, EX
} },
1858 { "cvttps2pi", { MXC
, EX
} },
1859 { "cvttss2siY", { Gv
, EX
} },
1860 { "cvttpd2pi", { MXC
, EX
} },
1861 { "cvttsd2siY", { Gv
, EX
} },
1865 { "divps", { XM
, EX
} },
1866 { "divss", { XM
, EX
} },
1867 { "divpd", { XM
, EX
} },
1868 { "divsd", { XM
, EX
} },
1872 { "maxps", { XM
, EX
} },
1873 { "maxss", { XM
, EX
} },
1874 { "maxpd", { XM
, EX
} },
1875 { "maxsd", { XM
, EX
} },
1879 { "minps", { XM
, EX
} },
1880 { "minss", { XM
, EX
} },
1881 { "minpd", { XM
, EX
} },
1882 { "minsd", { XM
, EX
} },
1886 { "movups", { XM
, EX
} },
1887 { "movss", { XM
, EX
} },
1888 { "movupd", { XM
, EX
} },
1889 { "movsd", { XM
, EX
} },
1893 { "movups", { EX
, XM
} },
1894 { "movss", { EX
, XM
} },
1895 { "movupd", { EX
, XM
} },
1896 { "movsd", { EX
, XM
} },
1900 { "mulps", { XM
, EX
} },
1901 { "mulss", { XM
, EX
} },
1902 { "mulpd", { XM
, EX
} },
1903 { "mulsd", { XM
, EX
} },
1907 { "rcpps", { XM
, EX
} },
1908 { "rcpss", { XM
, EX
} },
1909 { "(bad)", { XM
, EX
} },
1910 { "(bad)", { XM
, EX
} },
1914 { "rsqrtps",{ XM
, EX
} },
1915 { "rsqrtss",{ XM
, EX
} },
1916 { "(bad)", { XM
, EX
} },
1917 { "(bad)", { XM
, EX
} },
1921 { "sqrtps", { XM
, EX
} },
1922 { "sqrtss", { XM
, EX
} },
1923 { "sqrtpd", { XM
, EX
} },
1924 { "sqrtsd", { XM
, EX
} },
1928 { "subps", { XM
, EX
} },
1929 { "subss", { XM
, EX
} },
1930 { "subpd", { XM
, EX
} },
1931 { "subsd", { XM
, EX
} },
1935 { "(bad)", { XM
, EX
} },
1936 { "cvtdq2pd", { XM
, EX
} },
1937 { "cvttpd2dq", { XM
, EX
} },
1938 { "cvtpd2dq", { XM
, EX
} },
1942 { "cvtdq2ps", { XM
, EX
} },
1943 { "cvttps2dq", { XM
, EX
} },
1944 { "cvtps2dq", { XM
, EX
} },
1945 { "(bad)", { XM
, EX
} },
1949 { "cvtps2pd", { XM
, EX
} },
1950 { "cvtss2sd", { XM
, EX
} },
1951 { "cvtpd2ps", { XM
, EX
} },
1952 { "cvtsd2ss", { XM
, EX
} },
1956 { "maskmovq", { MX
, MS
} },
1957 { "(bad)", { XM
, EX
} },
1958 { "maskmovdqu", { XM
, XS
} },
1959 { "(bad)", { XM
, EX
} },
1963 { "movq", { MX
, EM
} },
1964 { "movdqu", { XM
, EX
} },
1965 { "movdqa", { XM
, EX
} },
1966 { "(bad)", { XM
, EX
} },
1970 { "movq", { EM
, MX
} },
1971 { "movdqu", { EX
, XM
} },
1972 { "movdqa", { EX
, XM
} },
1973 { "(bad)", { EX
, XM
} },
1977 { "(bad)", { EX
, XM
} },
1978 { "movq2dq",{ XM
, MS
} },
1979 { "movq", { EX
, XM
} },
1980 { "movdq2q",{ MX
, XS
} },
1984 { "pshufw", { MX
, EM
, Ib
} },
1985 { "pshufhw",{ XM
, EX
, Ib
} },
1986 { "pshufd", { XM
, EX
, Ib
} },
1987 { "pshuflw",{ XM
, EX
, Ib
} },
1991 { "movd", { Edq
, MX
} },
1992 { "movq", { XM
, EX
} },
1993 { "movd", { Edq
, XM
} },
1994 { "(bad)", { Ed
, XM
} },
1998 { "(bad)", { MX
, EX
} },
1999 { "(bad)", { XM
, EX
} },
2000 { "punpckhqdq", { XM
, EX
} },
2001 { "(bad)", { XM
, EX
} },
2005 { "movntq", { EM
, MX
} },
2006 { "(bad)", { EM
, XM
} },
2007 { "movntdq",{ EM
, XM
} },
2008 { "(bad)", { EM
, XM
} },
2012 { "(bad)", { MX
, EX
} },
2013 { "(bad)", { XM
, EX
} },
2014 { "punpcklqdq", { XM
, EX
} },
2015 { "(bad)", { XM
, EX
} },
2019 { "(bad)", { MX
, EX
} },
2020 { "(bad)", { XM
, EX
} },
2021 { "addsubpd", { XM
, EX
} },
2022 { "addsubps", { XM
, EX
} },
2026 { "(bad)", { MX
, EX
} },
2027 { "(bad)", { XM
, EX
} },
2028 { "haddpd", { XM
, EX
} },
2029 { "haddps", { XM
, EX
} },
2033 { "(bad)", { MX
, EX
} },
2034 { "(bad)", { XM
, EX
} },
2035 { "hsubpd", { XM
, EX
} },
2036 { "hsubps", { XM
, EX
} },
2040 { "movlpX", { XM
, EX
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
2041 { "movsldup", { XM
, EX
} },
2042 { "movlpd", { XM
, EX
} },
2043 { "movddup", { XM
, EX
} },
2047 { "movhpX", { XM
, EX
, { SIMD_Fixup
, 'l' } } },
2048 { "movshdup", { XM
, EX
} },
2049 { "movhpd", { XM
, EX
} },
2050 { "(bad)", { XM
, EX
} },
2054 { "(bad)", { XM
, EX
} },
2055 { "(bad)", { XM
, EX
} },
2056 { "(bad)", { XM
, EX
} },
2057 { "lddqu", { XM
, M
} },
2061 {"movntps", { Ev
, XM
} },
2062 {"movntss", { Ev
, XM
} },
2063 {"movntpd", { Ev
, XM
} },
2064 {"movntsd", { Ev
, XM
} },
2069 {"vmread", { Em
, Gm
} },
2071 {"extrq", { XS
, Ib
, Ib
} },
2072 {"insertq", { XM
, XS
, Ib
, Ib
} },
2077 {"vmwrite", { Gm
, Em
} },
2079 {"extrq", { XM
, XS
} },
2080 {"insertq", { XM
, XS
} },
2085 { "bsrS", { Gv
, Ev
} },
2086 { "lzcntS", { Gv
, Ev
} },
2087 { "bsrS", { Gv
, Ev
} },
2088 { "(bad)", { XX
} },
2093 { "(bad)", { XX
} },
2094 { "popcntS", { Gv
, Ev
} },
2095 { "(bad)", { XX
} },
2096 { "(bad)", { XX
} },
2101 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2102 { "pause", { XX
} },
2103 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2104 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2111 { "pblendvb", {XM
, EX
, XMM0
} },
2112 { "(bad)", { XX
} },
2117 { "(bad)", { XX
} },
2118 { "(bad)", { XX
} },
2119 { "blendvps", {XM
, EX
, XMM0
} },
2120 { "(bad)", { XX
} },
2125 { "(bad)", { XX
} },
2126 { "(bad)", { XX
} },
2127 { "blendvpd", { XM
, EX
, XMM0
} },
2128 { "(bad)", { XX
} },
2133 { "(bad)", { XX
} },
2134 { "(bad)", { XX
} },
2135 { "ptest", { XM
, EX
} },
2136 { "(bad)", { XX
} },
2141 { "(bad)", { XX
} },
2142 { "(bad)", { XX
} },
2143 { "pmovsxbw", { XM
, EX
} },
2144 { "(bad)", { XX
} },
2149 { "(bad)", { XX
} },
2150 { "(bad)", { XX
} },
2151 { "pmovsxbd", { XM
, EX
} },
2152 { "(bad)", { XX
} },
2157 { "(bad)", { XX
} },
2158 { "(bad)", { XX
} },
2159 { "pmovsxbq", { XM
, EX
} },
2160 { "(bad)", { XX
} },
2165 { "(bad)", { XX
} },
2166 { "(bad)", { XX
} },
2167 { "pmovsxwd", { XM
, EX
} },
2168 { "(bad)", { XX
} },
2173 { "(bad)", { XX
} },
2174 { "(bad)", { XX
} },
2175 { "pmovsxwq", { XM
, EX
} },
2176 { "(bad)", { XX
} },
2181 { "(bad)", { XX
} },
2182 { "(bad)", { XX
} },
2183 { "pmovsxdq", { XM
, EX
} },
2184 { "(bad)", { XX
} },
2189 { "(bad)", { XX
} },
2190 { "(bad)", { XX
} },
2191 { "pmuldq", { XM
, EX
} },
2192 { "(bad)", { XX
} },
2197 { "(bad)", { XX
} },
2198 { "(bad)", { XX
} },
2199 { "pcmpeqq", { XM
, EX
} },
2200 { "(bad)", { XX
} },
2205 { "(bad)", { XX
} },
2206 { "(bad)", { XX
} },
2207 { "movntdqa", { XM
, EM
} },
2208 { "(bad)", { XX
} },
2213 { "(bad)", { XX
} },
2214 { "(bad)", { XX
} },
2215 { "packusdw", { XM
, EX
} },
2216 { "(bad)", { XX
} },
2221 { "(bad)", { XX
} },
2222 { "(bad)", { XX
} },
2223 { "pmovzxbw", { XM
, EX
} },
2224 { "(bad)", { XX
} },
2229 { "(bad)", { XX
} },
2230 { "(bad)", { XX
} },
2231 { "pmovzxbd", { XM
, EX
} },
2232 { "(bad)", { XX
} },
2237 { "(bad)", { XX
} },
2238 { "(bad)", { XX
} },
2239 { "pmovzxbq", { XM
, EX
} },
2240 { "(bad)", { XX
} },
2245 { "(bad)", { XX
} },
2246 { "(bad)", { XX
} },
2247 { "pmovzxwd", { XM
, EX
} },
2248 { "(bad)", { XX
} },
2253 { "(bad)", { XX
} },
2254 { "(bad)", { XX
} },
2255 { "pmovzxwq", { XM
, EX
} },
2256 { "(bad)", { XX
} },
2261 { "(bad)", { XX
} },
2262 { "(bad)", { XX
} },
2263 { "pmovzxdq", { XM
, EX
} },
2264 { "(bad)", { XX
} },
2269 { "(bad)", { XX
} },
2270 { "(bad)", { XX
} },
2271 { "pminsb", { XM
, EX
} },
2272 { "(bad)", { XX
} },
2277 { "(bad)", { XX
} },
2278 { "(bad)", { XX
} },
2279 { "pminsd", { XM
, EX
} },
2280 { "(bad)", { XX
} },
2285 { "(bad)", { XX
} },
2286 { "(bad)", { XX
} },
2287 { "pminuw", { XM
, EX
} },
2288 { "(bad)", { XX
} },
2293 { "(bad)", { XX
} },
2294 { "(bad)", { XX
} },
2295 { "pminud", { XM
, EX
} },
2296 { "(bad)", { XX
} },
2301 { "(bad)", { XX
} },
2302 { "(bad)", { XX
} },
2303 { "pmaxsb", { XM
, EX
} },
2304 { "(bad)", { XX
} },
2309 { "(bad)", { XX
} },
2310 { "(bad)", { XX
} },
2311 { "pmaxsd", { XM
, EX
} },
2312 { "(bad)", { XX
} },
2317 { "(bad)", { XX
} },
2318 { "(bad)", { XX
} },
2319 { "pmaxuw", { XM
, EX
} },
2320 { "(bad)", { XX
} },
2325 { "(bad)", { XX
} },
2326 { "(bad)", { XX
} },
2327 { "pmaxud", { XM
, EX
} },
2328 { "(bad)", { XX
} },
2333 { "(bad)", { XX
} },
2334 { "(bad)", { XX
} },
2335 { "pmulld", { XM
, EX
} },
2336 { "(bad)", { XX
} },
2341 { "(bad)", { XX
} },
2342 { "(bad)", { XX
} },
2343 { "phminposuw", { XM
, EX
} },
2344 { "(bad)", { XX
} },
2349 { "(bad)", { XX
} },
2350 { "(bad)", { XX
} },
2351 { "roundps", { XM
, EX
, Ib
} },
2352 { "(bad)", { XX
} },
2357 { "(bad)", { XX
} },
2358 { "(bad)", { XX
} },
2359 { "roundpd", { XM
, EX
, Ib
} },
2360 { "(bad)", { XX
} },
2365 { "(bad)", { XX
} },
2366 { "(bad)", { XX
} },
2367 { "roundss", { XM
, EX
, Ib
} },
2368 { "(bad)", { XX
} },
2373 { "(bad)", { XX
} },
2374 { "(bad)", { XX
} },
2375 { "roundsd", { XM
, EX
, Ib
} },
2376 { "(bad)", { XX
} },
2381 { "(bad)", { XX
} },
2382 { "(bad)", { XX
} },
2383 { "blendps", { XM
, EX
, Ib
} },
2384 { "(bad)", { XX
} },
2389 { "(bad)", { XX
} },
2390 { "(bad)", { XX
} },
2391 { "blendpd", { XM
, EX
, Ib
} },
2392 { "(bad)", { XX
} },
2397 { "(bad)", { XX
} },
2398 { "(bad)", { XX
} },
2399 { "pblendw", { XM
, EX
, Ib
} },
2400 { "(bad)", { XX
} },
2405 { "(bad)", { XX
} },
2406 { "(bad)", { XX
} },
2407 { "pextrb", { Edqb
, XM
, Ib
} },
2408 { "(bad)", { XX
} },
2413 { "(bad)", { XX
} },
2414 { "(bad)", { XX
} },
2415 { "pextrw", { Edqw
, XM
, Ib
} },
2416 { "(bad)", { XX
} },
2421 { "(bad)", { XX
} },
2422 { "(bad)", { XX
} },
2423 { "pextrK", { Edq
, XM
, Ib
} },
2424 { "(bad)", { XX
} },
2429 { "(bad)", { XX
} },
2430 { "(bad)", { XX
} },
2431 { "extractps", { Edqd
, XM
, Ib
} },
2432 { "(bad)", { XX
} },
2437 { "(bad)", { XX
} },
2438 { "(bad)", { XX
} },
2439 { "pinsrb", { XM
, Edqb
, Ib
} },
2440 { "(bad)", { XX
} },
2445 { "(bad)", { XX
} },
2446 { "(bad)", { XX
} },
2447 { "insertps", { XM
, EX
, Ib
} },
2448 { "(bad)", { XX
} },
2453 { "(bad)", { XX
} },
2454 { "(bad)", { XX
} },
2455 { "pinsrK", { XM
, Edq
, Ib
} },
2456 { "(bad)", { XX
} },
2461 { "(bad)", { XX
} },
2462 { "(bad)", { XX
} },
2463 { "dpps", { XM
, EX
, Ib
} },
2464 { "(bad)", { XX
} },
2469 { "(bad)", { XX
} },
2470 { "(bad)", { XX
} },
2471 { "dppd", { XM
, EX
, Ib
} },
2472 { "(bad)", { XX
} },
2477 { "(bad)", { XX
} },
2478 { "(bad)", { XX
} },
2479 { "mpsadbw", { XM
, EX
, Ib
} },
2480 { "(bad)", { XX
} },
2485 { "(bad)", { XX
} },
2486 { "(bad)", { XX
} },
2487 { "pcmpgtq", { XM
, EX
} },
2488 { "(bad)", { XX
} },
2493 { "(bad)", { XX
} },
2494 { "(bad)", { XX
} },
2495 { "(bad)", { XX
} },
2496 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2501 { "(bad)", { XX
} },
2502 { "(bad)", { XX
} },
2503 { "(bad)", { XX
} },
2504 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2509 { "(bad)", { XX
} },
2510 { "(bad)", { XX
} },
2511 { "pcmpestrm", { XM
, EX
, Ib
} },
2512 { "(bad)", { XX
} },
2517 { "(bad)", { XX
} },
2518 { "(bad)", { XX
} },
2519 { "pcmpestri", { XM
, EX
, Ib
} },
2520 { "(bad)", { XX
} },
2525 { "(bad)", { XX
} },
2526 { "(bad)", { XX
} },
2527 { "pcmpistrm", { XM
, EX
, Ib
} },
2528 { "(bad)", { XX
} },
2533 { "(bad)", { XX
} },
2534 { "(bad)", { XX
} },
2535 { "pcmpistri", { XM
, EX
, Ib
} },
2536 { "(bad)", { XX
} },
2540 static const struct dis386 x86_64_table
[][2] = {
2542 { "pusha{P|}", { XX
} },
2543 { "(bad)", { XX
} },
2546 { "popa{P|}", { XX
} },
2547 { "(bad)", { XX
} },
2550 { "bound{S|}", { Gv
, Ma
} },
2551 { "(bad)", { XX
} },
2554 { "arpl", { Ew
, Gw
} },
2555 { "movs{||lq|xd}", { Gv
, Ed
} },
2559 static const struct dis386 three_byte_table
[][256] = {
2563 { "pshufb", { MX
, EM
} },
2564 { "phaddw", { MX
, EM
} },
2565 { "phaddd", { MX
, EM
} },
2566 { "phaddsw", { MX
, EM
} },
2567 { "pmaddubsw", { MX
, EM
} },
2568 { "phsubw", { MX
, EM
} },
2569 { "phsubd", { MX
, EM
} },
2570 { "phsubsw", { MX
, EM
} },
2572 { "psignb", { MX
, EM
} },
2573 { "psignw", { MX
, EM
} },
2574 { "psignd", { MX
, EM
} },
2575 { "pmulhrsw", { MX
, EM
} },
2576 { "(bad)", { XX
} },
2577 { "(bad)", { XX
} },
2578 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2582 { "(bad)", { XX
} },
2583 { "(bad)", { XX
} },
2584 { "(bad)", { XX
} },
2587 { "(bad)", { XX
} },
2590 { "(bad)", { XX
} },
2591 { "(bad)", { XX
} },
2592 { "(bad)", { XX
} },
2593 { "(bad)", { XX
} },
2594 { "pabsb", { MX
, EM
} },
2595 { "pabsw", { MX
, EM
} },
2596 { "pabsd", { MX
, EM
} },
2597 { "(bad)", { XX
} },
2605 { "(bad)", { XX
} },
2606 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "(bad)", { XX
} },
2614 { "(bad)", { XX
} },
2615 { "(bad)", { XX
} },
2623 { "(bad)", { XX
} },
2637 { "(bad)", { XX
} },
2638 { "(bad)", { XX
} },
2639 { "(bad)", { XX
} },
2640 { "(bad)", { XX
} },
2641 { "(bad)", { XX
} },
2642 { "(bad)", { XX
} },
2644 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "(bad)", { XX
} },
2647 { "(bad)", { XX
} },
2648 { "(bad)", { XX
} },
2649 { "(bad)", { XX
} },
2650 { "(bad)", { XX
} },
2651 { "(bad)", { XX
} },
2653 { "(bad)", { XX
} },
2654 { "(bad)", { XX
} },
2655 { "(bad)", { XX
} },
2656 { "(bad)", { XX
} },
2657 { "(bad)", { XX
} },
2658 { "(bad)", { XX
} },
2659 { "(bad)", { XX
} },
2660 { "(bad)", { XX
} },
2662 { "(bad)", { XX
} },
2663 { "(bad)", { XX
} },
2664 { "(bad)", { XX
} },
2665 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2669 { "(bad)", { XX
} },
2671 { "(bad)", { XX
} },
2672 { "(bad)", { XX
} },
2673 { "(bad)", { XX
} },
2674 { "(bad)", { XX
} },
2675 { "(bad)", { XX
} },
2676 { "(bad)", { XX
} },
2677 { "(bad)", { XX
} },
2678 { "(bad)", { XX
} },
2680 { "(bad)", { XX
} },
2681 { "(bad)", { XX
} },
2682 { "(bad)", { XX
} },
2683 { "(bad)", { XX
} },
2684 { "(bad)", { XX
} },
2685 { "(bad)", { XX
} },
2686 { "(bad)", { XX
} },
2687 { "(bad)", { XX
} },
2689 { "(bad)", { XX
} },
2690 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2695 { "(bad)", { XX
} },
2696 { "(bad)", { XX
} },
2698 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2704 { "(bad)", { XX
} },
2705 { "(bad)", { XX
} },
2707 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2713 { "(bad)", { XX
} },
2714 { "(bad)", { XX
} },
2716 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2722 { "(bad)", { XX
} },
2723 { "(bad)", { XX
} },
2725 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2734 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2741 { "(bad)", { XX
} },
2743 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "(bad)", { XX
} },
2750 { "(bad)", { XX
} },
2752 { "(bad)", { XX
} },
2753 { "(bad)", { XX
} },
2754 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2758 { "(bad)", { XX
} },
2759 { "(bad)", { XX
} },
2761 { "(bad)", { XX
} },
2762 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2767 { "(bad)", { XX
} },
2768 { "(bad)", { XX
} },
2770 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2776 { "(bad)", { XX
} },
2777 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "(bad)", { XX
} },
2782 { "(bad)", { XX
} },
2783 { "(bad)", { XX
} },
2784 { "(bad)", { XX
} },
2785 { "(bad)", { XX
} },
2786 { "(bad)", { XX
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2790 { "(bad)", { XX
} },
2791 { "(bad)", { XX
} },
2792 { "(bad)", { XX
} },
2793 { "(bad)", { XX
} },
2794 { "(bad)", { XX
} },
2795 { "(bad)", { XX
} },
2797 { "(bad)", { XX
} },
2798 { "(bad)", { XX
} },
2799 { "(bad)", { XX
} },
2800 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2803 { "(bad)", { XX
} },
2804 { "(bad)", { XX
} },
2806 { "(bad)", { XX
} },
2807 { "(bad)", { XX
} },
2808 { "(bad)", { XX
} },
2809 { "(bad)", { XX
} },
2810 { "(bad)", { XX
} },
2811 { "(bad)", { XX
} },
2812 { "(bad)", { XX
} },
2813 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2817 { "(bad)", { XX
} },
2818 { "(bad)", { XX
} },
2819 { "(bad)", { XX
} },
2820 { "(bad)", { XX
} },
2821 { "(bad)", { XX
} },
2822 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2826 { "(bad)", { XX
} },
2827 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2830 { "(bad)", { XX
} },
2831 { "(bad)", { XX
} },
2835 { "(bad)", { XX
} },
2836 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2839 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2844 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2848 { "(bad)", { XX
} },
2849 { "(bad)", { XX
} },
2854 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2857 { "(bad)", { XX
} },
2858 { "(bad)", { XX
} },
2859 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2870 { "palignr", { MX
, EM
, Ib
} },
2872 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2881 { "(bad)", { XX
} },
2882 { "(bad)", { XX
} },
2883 { "(bad)", { XX
} },
2884 { "(bad)", { XX
} },
2885 { "(bad)", { XX
} },
2886 { "(bad)", { XX
} },
2887 { "(bad)", { XX
} },
2888 { "(bad)", { XX
} },
2893 { "(bad)", { XX
} },
2894 { "(bad)", { XX
} },
2895 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2899 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2903 { "(bad)", { XX
} },
2904 { "(bad)", { XX
} },
2905 { "(bad)", { XX
} },
2906 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2915 { "(bad)", { XX
} },
2917 { "(bad)", { XX
} },
2918 { "(bad)", { XX
} },
2919 { "(bad)", { XX
} },
2920 { "(bad)", { XX
} },
2921 { "(bad)", { XX
} },
2922 { "(bad)", { XX
} },
2923 { "(bad)", { XX
} },
2924 { "(bad)", { XX
} },
2929 { "(bad)", { XX
} },
2930 { "(bad)", { XX
} },
2931 { "(bad)", { XX
} },
2932 { "(bad)", { XX
} },
2933 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2942 { "(bad)", { XX
} },
2944 { "(bad)", { XX
} },
2945 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2951 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2960 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2969 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2978 { "(bad)", { XX
} },
2980 { "(bad)", { XX
} },
2981 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2987 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2996 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3005 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3014 { "(bad)", { XX
} },
3016 { "(bad)", { XX
} },
3017 { "(bad)", { XX
} },
3018 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3023 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3032 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3041 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3050 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3059 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3067 { "(bad)", { XX
} },
3068 { "(bad)", { XX
} },
3070 { "(bad)", { XX
} },
3071 { "(bad)", { XX
} },
3072 { "(bad)", { XX
} },
3073 { "(bad)", { XX
} },
3074 { "(bad)", { XX
} },
3075 { "(bad)", { XX
} },
3076 { "(bad)", { XX
} },
3077 { "(bad)", { XX
} },
3079 { "(bad)", { XX
} },
3080 { "(bad)", { XX
} },
3081 { "(bad)", { XX
} },
3082 { "(bad)", { XX
} },
3083 { "(bad)", { XX
} },
3084 { "(bad)", { XX
} },
3085 { "(bad)", { XX
} },
3086 { "(bad)", { XX
} },
3088 { "(bad)", { XX
} },
3089 { "(bad)", { XX
} },
3090 { "(bad)", { XX
} },
3091 { "(bad)", { XX
} },
3092 { "(bad)", { XX
} },
3093 { "(bad)", { XX
} },
3094 { "(bad)", { XX
} },
3095 { "(bad)", { XX
} },
3097 { "(bad)", { XX
} },
3098 { "(bad)", { XX
} },
3099 { "(bad)", { XX
} },
3100 { "(bad)", { XX
} },
3101 { "(bad)", { XX
} },
3102 { "(bad)", { XX
} },
3103 { "(bad)", { XX
} },
3104 { "(bad)", { XX
} },
3106 { "(bad)", { XX
} },
3107 { "(bad)", { XX
} },
3108 { "(bad)", { XX
} },
3109 { "(bad)", { XX
} },
3110 { "(bad)", { XX
} },
3111 { "(bad)", { XX
} },
3112 { "(bad)", { XX
} },
3113 { "(bad)", { XX
} },
3115 { "(bad)", { XX
} },
3116 { "(bad)", { XX
} },
3117 { "(bad)", { XX
} },
3118 { "(bad)", { XX
} },
3119 { "(bad)", { XX
} },
3120 { "(bad)", { XX
} },
3121 { "(bad)", { XX
} },
3122 { "(bad)", { XX
} },
3124 { "(bad)", { XX
} },
3125 { "(bad)", { XX
} },
3126 { "(bad)", { XX
} },
3127 { "(bad)", { XX
} },
3128 { "(bad)", { XX
} },
3129 { "(bad)", { XX
} },
3130 { "(bad)", { XX
} },
3131 { "(bad)", { XX
} },
3133 { "(bad)", { XX
} },
3134 { "(bad)", { XX
} },
3135 { "(bad)", { XX
} },
3136 { "(bad)", { XX
} },
3137 { "(bad)", { XX
} },
3138 { "(bad)", { XX
} },
3139 { "(bad)", { XX
} },
3140 { "(bad)", { XX
} },
3144 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3156 FETCH_DATA (the_info
, codep
+ 1);
3160 /* REX prefixes family. */
3177 if (address_mode
== mode_64bit
)
3183 prefixes
|= PREFIX_REPZ
;
3186 prefixes
|= PREFIX_REPNZ
;
3189 prefixes
|= PREFIX_LOCK
;
3192 prefixes
|= PREFIX_CS
;
3195 prefixes
|= PREFIX_SS
;
3198 prefixes
|= PREFIX_DS
;
3201 prefixes
|= PREFIX_ES
;
3204 prefixes
|= PREFIX_FS
;
3207 prefixes
|= PREFIX_GS
;
3210 prefixes
|= PREFIX_DATA
;
3213 prefixes
|= PREFIX_ADDR
;
3216 /* fwait is really an instruction. If there are prefixes
3217 before the fwait, they belong to the fwait, *not* to the
3218 following instruction. */
3219 if (prefixes
|| rex
)
3221 prefixes
|= PREFIX_FWAIT
;
3225 prefixes
= PREFIX_FWAIT
;
3230 /* Rex is ignored when followed by another prefix. */
3241 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3245 prefix_name (int pref
, int sizeflag
)
3247 static const char *rexes
[16] =
3252 "rex.XB", /* 0x43 */
3254 "rex.RB", /* 0x45 */
3255 "rex.RX", /* 0x46 */
3256 "rex.RXB", /* 0x47 */
3258 "rex.WB", /* 0x49 */
3259 "rex.WX", /* 0x4a */
3260 "rex.WXB", /* 0x4b */
3261 "rex.WR", /* 0x4c */
3262 "rex.WRB", /* 0x4d */
3263 "rex.WRX", /* 0x4e */
3264 "rex.WRXB", /* 0x4f */
3269 /* REX prefixes family. */
3286 return rexes
[pref
- 0x40];
3306 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3308 if (address_mode
== mode_64bit
)
3309 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3311 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3319 static char op_out
[MAX_OPERANDS
][100];
3320 static int op_ad
, op_index
[MAX_OPERANDS
];
3321 static int two_source_ops
;
3322 static bfd_vma op_address
[MAX_OPERANDS
];
3323 static bfd_vma op_riprel
[MAX_OPERANDS
];
3324 static bfd_vma start_pc
;
3327 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3328 * (see topic "Redundant prefixes" in the "Differences from 8086"
3329 * section of the "Virtual 8086 Mode" chapter.)
3330 * 'pc' should be the address of this instruction, it will
3331 * be used to print the target address if this is a relative jump or call
3332 * The function returns the length of this instruction in bytes.
3335 static char intel_syntax
;
3336 static char open_char
;
3337 static char close_char
;
3338 static char separator_char
;
3339 static char scale_char
;
3341 /* Here for backwards compatibility. When gdb stops using
3342 print_insn_i386_att and print_insn_i386_intel these functions can
3343 disappear, and print_insn_i386 be merged into print_insn. */
3345 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3349 return print_insn (pc
, info
);
3353 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3357 return print_insn (pc
, info
);
3361 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3365 return print_insn (pc
, info
);
3369 print_i386_disassembler_options (FILE *stream
)
3371 fprintf (stream
, _("\n\
3372 The following i386/x86-64 specific disassembler options are supported for use\n\
3373 with the -M switch (multiple options should be separated by commas):\n"));
3375 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3376 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3377 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3378 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3379 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3380 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3381 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3382 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3383 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3384 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3385 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3389 print_insn (bfd_vma pc
, disassemble_info
*info
)
3391 const struct dis386
*dp
;
3393 char *op_txt
[MAX_OPERANDS
];
3395 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
3396 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
3399 struct dis_private priv
;
3402 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3403 || info
->mach
== bfd_mach_x86_64
)
3404 address_mode
= mode_64bit
;
3406 address_mode
= mode_32bit
;
3408 if (intel_syntax
== (char) -1)
3409 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3410 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3412 if (info
->mach
== bfd_mach_i386_i386
3413 || info
->mach
== bfd_mach_x86_64
3414 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3415 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3416 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3417 else if (info
->mach
== bfd_mach_i386_i8086
)
3418 priv
.orig_sizeflag
= 0;
3422 for (p
= info
->disassembler_options
; p
!= NULL
; )
3424 if (CONST_STRNEQ (p
, "x86-64"))
3426 address_mode
= mode_64bit
;
3427 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3429 else if (CONST_STRNEQ (p
, "i386"))
3431 address_mode
= mode_32bit
;
3432 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3434 else if (CONST_STRNEQ (p
, "i8086"))
3436 address_mode
= mode_16bit
;
3437 priv
.orig_sizeflag
= 0;
3439 else if (CONST_STRNEQ (p
, "intel"))
3443 else if (CONST_STRNEQ (p
, "att"))
3447 else if (CONST_STRNEQ (p
, "addr"))
3449 if (address_mode
== mode_64bit
)
3451 if (p
[4] == '3' && p
[5] == '2')
3452 priv
.orig_sizeflag
&= ~AFLAG
;
3453 else if (p
[4] == '6' && p
[5] == '4')
3454 priv
.orig_sizeflag
|= AFLAG
;
3458 if (p
[4] == '1' && p
[5] == '6')
3459 priv
.orig_sizeflag
&= ~AFLAG
;
3460 else if (p
[4] == '3' && p
[5] == '2')
3461 priv
.orig_sizeflag
|= AFLAG
;
3464 else if (CONST_STRNEQ (p
, "data"))
3466 if (p
[4] == '1' && p
[5] == '6')
3467 priv
.orig_sizeflag
&= ~DFLAG
;
3468 else if (p
[4] == '3' && p
[5] == '2')
3469 priv
.orig_sizeflag
|= DFLAG
;
3471 else if (CONST_STRNEQ (p
, "suffix"))
3472 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3474 p
= strchr (p
, ',');
3481 names64
= intel_names64
;
3482 names32
= intel_names32
;
3483 names16
= intel_names16
;
3484 names8
= intel_names8
;
3485 names8rex
= intel_names8rex
;
3486 names_seg
= intel_names_seg
;
3487 index16
= intel_index16
;
3490 separator_char
= '+';
3495 names64
= att_names64
;
3496 names32
= att_names32
;
3497 names16
= att_names16
;
3498 names8
= att_names8
;
3499 names8rex
= att_names8rex
;
3500 names_seg
= att_names_seg
;
3501 index16
= att_index16
;
3504 separator_char
= ',';
3508 /* The output looks better if we put 7 bytes on a line, since that
3509 puts most long word instructions on a single line. */
3510 info
->bytes_per_line
= 7;
3512 info
->private_data
= &priv
;
3513 priv
.max_fetched
= priv
.the_buffer
;
3514 priv
.insn_start
= pc
;
3517 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3525 start_codep
= priv
.the_buffer
;
3526 codep
= priv
.the_buffer
;
3528 if (setjmp (priv
.bailout
) != 0)
3532 /* Getting here means we tried for data but didn't get it. That
3533 means we have an incomplete instruction of some sort. Just
3534 print the first byte as a prefix or a .byte pseudo-op. */
3535 if (codep
> priv
.the_buffer
)
3537 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3539 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3542 /* Just print the first byte as a .byte instruction. */
3543 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3544 (unsigned int) priv
.the_buffer
[0]);
3557 sizeflag
= priv
.orig_sizeflag
;
3559 FETCH_DATA (info
, codep
+ 1);
3560 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3562 if (((prefixes
& PREFIX_FWAIT
)
3563 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3564 || (rex
&& rex_used
))
3568 /* fwait not followed by floating point instruction, or rex followed
3569 by other prefixes. Print the first prefix. */
3570 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3572 name
= INTERNAL_DISASSEMBLER_ERROR
;
3573 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3580 unsigned char threebyte
;
3581 FETCH_DATA (info
, codep
+ 2);
3582 threebyte
= *++codep
;
3583 dp
= &dis386_twobyte
[threebyte
];
3584 need_modrm
= twobyte_has_modrm
[*codep
];
3585 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3586 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3587 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3588 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3590 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3592 FETCH_DATA (info
, codep
+ 2);
3597 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3598 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3599 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3602 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3603 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3604 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3613 dp
= &dis386
[*codep
];
3614 need_modrm
= onebyte_has_modrm
[*codep
];
3615 uses_DATA_prefix
= 0;
3616 uses_REPNZ_prefix
= 0;
3617 /* pause is 0xf3 0x90. */
3618 uses_REPZ_prefix
= *codep
== 0x90;
3619 uses_LOCK_prefix
= 0;
3623 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3626 used_prefixes
|= PREFIX_REPZ
;
3628 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3631 used_prefixes
|= PREFIX_REPNZ
;
3634 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3637 used_prefixes
|= PREFIX_LOCK
;
3640 if (prefixes
& PREFIX_ADDR
)
3643 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3645 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3646 oappend ("addr32 ");
3648 oappend ("addr16 ");
3649 used_prefixes
|= PREFIX_ADDR
;
3653 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3656 if (dp
->op
[2].bytemode
== cond_jump_mode
3657 && dp
->op
[0].bytemode
== v_mode
3660 if (sizeflag
& DFLAG
)
3661 oappend ("data32 ");
3663 oappend ("data16 ");
3664 used_prefixes
|= PREFIX_DATA
;
3668 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3670 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3671 modrm
.mod
= (*codep
>> 6) & 3;
3672 modrm
.reg
= (*codep
>> 3) & 7;
3673 modrm
.rm
= *codep
& 7;
3675 else if (need_modrm
)
3677 FETCH_DATA (info
, codep
+ 1);
3678 modrm
.mod
= (*codep
>> 6) & 3;
3679 modrm
.reg
= (*codep
>> 3) & 7;
3680 modrm
.rm
= *codep
& 7;
3683 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3690 if (dp
->name
== NULL
)
3692 switch (dp
->op
[0].bytemode
)
3695 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3698 case USE_PREFIX_USER_TABLE
:
3700 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3701 if (prefixes
& PREFIX_REPZ
)
3705 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3706 before PREFIX_DATA. */
3707 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3708 if (prefixes
& PREFIX_REPNZ
)
3712 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3713 if (prefixes
& PREFIX_DATA
)
3717 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3720 case X86_64_SPECIAL
:
3721 index
= address_mode
== mode_64bit
? 1 : 0;
3722 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3726 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3731 if (putop (dp
->name
, sizeflag
) == 0)
3733 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3736 op_ad
= MAX_OPERANDS
- 1 - i
;
3738 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3743 /* See if any prefixes were not used. If so, print the first one
3744 separately. If we don't do this, we'll wind up printing an
3745 instruction stream which does not precisely correspond to the
3746 bytes we are disassembling. */
3747 if ((prefixes
& ~used_prefixes
) != 0)
3751 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3753 name
= INTERNAL_DISASSEMBLER_ERROR
;
3754 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3757 if (rex
& ~rex_used
)
3760 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3762 name
= INTERNAL_DISASSEMBLER_ERROR
;
3763 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3766 obufp
= obuf
+ strlen (obuf
);
3767 for (i
= strlen (obuf
); i
< 6; i
++)
3770 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3772 /* The enter and bound instructions are printed with operands in the same
3773 order as the intel book; everything else is printed in reverse order. */
3774 if (intel_syntax
|| two_source_ops
)
3778 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3779 op_txt
[i
] = op_out
[i
];
3781 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3783 op_ad
= op_index
[i
];
3784 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3785 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3786 riprel
= op_riprel
[i
];
3787 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
3788 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
3793 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3794 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3798 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3802 (*info
->fprintf_func
) (info
->stream
, ",");
3803 if (op_index
[i
] != -1 && !op_riprel
[i
])
3804 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3806 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3810 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3811 if (op_index
[i
] != -1 && op_riprel
[i
])
3813 (*info
->fprintf_func
) (info
->stream
, " # ");
3814 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3815 + op_address
[op_index
[i
]]), info
);
3818 return codep
- priv
.the_buffer
;
3821 static const char *float_mem
[] = {
3896 static const unsigned char float_mem_mode
[] = {
3971 #define ST { OP_ST, 0 }
3972 #define STi { OP_STi, 0 }
3974 #define FGRPd9_2 NULL, { { NULL, 0 } }
3975 #define FGRPd9_4 NULL, { { NULL, 1 } }
3976 #define FGRPd9_5 NULL, { { NULL, 2 } }
3977 #define FGRPd9_6 NULL, { { NULL, 3 } }
3978 #define FGRPd9_7 NULL, { { NULL, 4 } }
3979 #define FGRPda_5 NULL, { { NULL, 5 } }
3980 #define FGRPdb_4 NULL, { { NULL, 6 } }
3981 #define FGRPde_3 NULL, { { NULL, 7 } }
3982 #define FGRPdf_4 NULL, { { NULL, 8 } }
3984 static const struct dis386 float_reg
[][8] = {
3987 { "fadd", { ST
, STi
} },
3988 { "fmul", { ST
, STi
} },
3989 { "fcom", { STi
} },
3990 { "fcomp", { STi
} },
3991 { "fsub", { ST
, STi
} },
3992 { "fsubr", { ST
, STi
} },
3993 { "fdiv", { ST
, STi
} },
3994 { "fdivr", { ST
, STi
} },
3999 { "fxch", { STi
} },
4001 { "(bad)", { XX
} },
4009 { "fcmovb", { ST
, STi
} },
4010 { "fcmove", { ST
, STi
} },
4011 { "fcmovbe",{ ST
, STi
} },
4012 { "fcmovu", { ST
, STi
} },
4013 { "(bad)", { XX
} },
4015 { "(bad)", { XX
} },
4016 { "(bad)", { XX
} },
4020 { "fcmovnb",{ ST
, STi
} },
4021 { "fcmovne",{ ST
, STi
} },
4022 { "fcmovnbe",{ ST
, STi
} },
4023 { "fcmovnu",{ ST
, STi
} },
4025 { "fucomi", { ST
, STi
} },
4026 { "fcomi", { ST
, STi
} },
4027 { "(bad)", { XX
} },
4031 { "fadd", { STi
, ST
} },
4032 { "fmul", { STi
, ST
} },
4033 { "(bad)", { XX
} },
4034 { "(bad)", { XX
} },
4036 { "fsub", { STi
, ST
} },
4037 { "fsubr", { STi
, ST
} },
4038 { "fdiv", { STi
, ST
} },
4039 { "fdivr", { STi
, ST
} },
4041 { "fsubr", { STi
, ST
} },
4042 { "fsub", { STi
, ST
} },
4043 { "fdivr", { STi
, ST
} },
4044 { "fdiv", { STi
, ST
} },
4049 { "ffree", { STi
} },
4050 { "(bad)", { XX
} },
4052 { "fstp", { STi
} },
4053 { "fucom", { STi
} },
4054 { "fucomp", { STi
} },
4055 { "(bad)", { XX
} },
4056 { "(bad)", { XX
} },
4060 { "faddp", { STi
, ST
} },
4061 { "fmulp", { STi
, ST
} },
4062 { "(bad)", { XX
} },
4065 { "fsubp", { STi
, ST
} },
4066 { "fsubrp", { STi
, ST
} },
4067 { "fdivp", { STi
, ST
} },
4068 { "fdivrp", { STi
, ST
} },
4070 { "fsubrp", { STi
, ST
} },
4071 { "fsubp", { STi
, ST
} },
4072 { "fdivrp", { STi
, ST
} },
4073 { "fdivp", { STi
, ST
} },
4078 { "ffreep", { STi
} },
4079 { "(bad)", { XX
} },
4080 { "(bad)", { XX
} },
4081 { "(bad)", { XX
} },
4083 { "fucomip", { ST
, STi
} },
4084 { "fcomip", { ST
, STi
} },
4085 { "(bad)", { XX
} },
4089 static char *fgrps
[][8] = {
4092 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4097 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4102 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4107 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4112 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4117 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4122 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4123 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4128 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4133 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4138 dofloat (int sizeflag
)
4140 const struct dis386
*dp
;
4141 unsigned char floatop
;
4143 floatop
= codep
[-1];
4147 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4149 putop (float_mem
[fp_indx
], sizeflag
);
4152 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4155 /* Skip mod/rm byte. */
4159 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4160 if (dp
->name
== NULL
)
4162 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4164 /* Instruction fnstsw is only one with strange arg. */
4165 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4166 strcpy (op_out
[0], names16
[0]);
4170 putop (dp
->name
, sizeflag
);
4175 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4180 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4185 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4187 oappend ("%st" + intel_syntax
);
4191 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4193 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4194 oappend (scratchbuf
+ intel_syntax
);
4197 /* Capital letters in template are macros. */
4199 putop (const char *template, int sizeflag
)
4204 for (p
= template; *p
; p
++)
4215 if (address_mode
== mode_64bit
)
4223 /* Alternative not valid. */
4224 strcpy (obuf
, "(bad)");
4228 else if (*p
== '\0')
4249 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4255 if (sizeflag
& SUFFIX_ALWAYS
)
4259 if (intel_syntax
&& !alt
)
4261 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4263 if (sizeflag
& DFLAG
)
4264 *obufp
++ = intel_syntax
? 'd' : 'l';
4266 *obufp
++ = intel_syntax
? 'w' : 's';
4267 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4271 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4278 else if (sizeflag
& DFLAG
)
4279 *obufp
++ = intel_syntax
? 'd' : 'l';
4282 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4287 case 'E': /* For jcxz/jecxz */
4288 if (address_mode
== mode_64bit
)
4290 if (sizeflag
& AFLAG
)
4296 if (sizeflag
& AFLAG
)
4298 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4303 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4305 if (sizeflag
& AFLAG
)
4306 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4308 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4309 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4313 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4315 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4320 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4325 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4326 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4328 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4331 if (prefixes
& PREFIX_DS
)
4352 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4361 if (sizeflag
& SUFFIX_ALWAYS
)
4365 if ((prefixes
& PREFIX_FWAIT
) == 0)
4368 used_prefixes
|= PREFIX_FWAIT
;
4374 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4379 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4384 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4393 if ((prefixes
& PREFIX_DATA
)
4395 || (sizeflag
& SUFFIX_ALWAYS
))
4402 if (sizeflag
& DFLAG
)
4407 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4413 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4415 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4421 if (intel_syntax
&& !alt
)
4424 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4430 if (sizeflag
& DFLAG
)
4431 *obufp
++ = intel_syntax
? 'd' : 'l';
4435 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4442 else if (sizeflag
& DFLAG
)
4451 if (intel_syntax
&& !p
[1]
4452 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4455 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4460 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4462 if (sizeflag
& SUFFIX_ALWAYS
)
4470 if (sizeflag
& SUFFIX_ALWAYS
)
4476 if (sizeflag
& DFLAG
)
4480 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4485 if (prefixes
& PREFIX_DATA
)
4489 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4500 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4502 /* operand size flag for cwtl, cbtw */
4511 else if (sizeflag
& DFLAG
)
4516 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4526 oappend (const char *s
)
4529 obufp
+= strlen (s
);
4535 if (prefixes
& PREFIX_CS
)
4537 used_prefixes
|= PREFIX_CS
;
4538 oappend ("%cs:" + intel_syntax
);
4540 if (prefixes
& PREFIX_DS
)
4542 used_prefixes
|= PREFIX_DS
;
4543 oappend ("%ds:" + intel_syntax
);
4545 if (prefixes
& PREFIX_SS
)
4547 used_prefixes
|= PREFIX_SS
;
4548 oappend ("%ss:" + intel_syntax
);
4550 if (prefixes
& PREFIX_ES
)
4552 used_prefixes
|= PREFIX_ES
;
4553 oappend ("%es:" + intel_syntax
);
4555 if (prefixes
& PREFIX_FS
)
4557 used_prefixes
|= PREFIX_FS
;
4558 oappend ("%fs:" + intel_syntax
);
4560 if (prefixes
& PREFIX_GS
)
4562 used_prefixes
|= PREFIX_GS
;
4563 oappend ("%gs:" + intel_syntax
);
4568 OP_indirE (int bytemode
, int sizeflag
)
4572 OP_E (bytemode
, sizeflag
);
4576 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4578 if (address_mode
== mode_64bit
)
4586 sprintf_vma (tmp
, disp
);
4587 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4588 strcpy (buf
+ 2, tmp
+ i
);
4592 bfd_signed_vma v
= disp
;
4599 /* Check for possible overflow on 0x8000000000000000. */
4602 strcpy (buf
, "9223372036854775808");
4616 tmp
[28 - i
] = (v
% 10) + '0';
4620 strcpy (buf
, tmp
+ 29 - i
);
4626 sprintf (buf
, "0x%x", (unsigned int) disp
);
4628 sprintf (buf
, "%d", (int) disp
);
4633 intel_operand_size (int bytemode
, int sizeflag
)
4639 oappend ("BYTE PTR ");
4643 oappend ("WORD PTR ");
4646 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4648 oappend ("QWORD PTR ");
4649 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4657 oappend ("QWORD PTR ");
4658 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4659 oappend ("DWORD PTR ");
4661 oappend ("WORD PTR ");
4662 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4665 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4667 oappend ("WORD PTR ");
4669 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4673 oappend ("DWORD PTR ");
4676 oappend ("QWORD PTR ");
4679 if (address_mode
== mode_64bit
)
4680 oappend ("QWORD PTR ");
4682 oappend ("DWORD PTR ");
4685 if (sizeflag
& DFLAG
)
4686 oappend ("FWORD PTR ");
4688 oappend ("DWORD PTR ");
4689 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4692 oappend ("TBYTE PTR ");
4695 oappend ("XMMWORD PTR ");
4698 oappend ("OWORD PTR ");
4706 OP_E (int bytemode
, int sizeflag
)
4715 /* Skip mod/rm byte. */
4726 oappend (names8rex
[modrm
.rm
+ add
]);
4728 oappend (names8
[modrm
.rm
+ add
]);
4731 oappend (names16
[modrm
.rm
+ add
]);
4734 oappend (names32
[modrm
.rm
+ add
]);
4737 oappend (names64
[modrm
.rm
+ add
]);
4740 if (address_mode
== mode_64bit
)
4741 oappend (names64
[modrm
.rm
+ add
]);
4743 oappend (names32
[modrm
.rm
+ add
]);
4746 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4748 oappend (names64
[modrm
.rm
+ add
]);
4749 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4761 oappend (names64
[modrm
.rm
+ add
]);
4762 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4763 oappend (names32
[modrm
.rm
+ add
]);
4765 oappend (names16
[modrm
.rm
+ add
]);
4766 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4771 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4779 intel_operand_size (bytemode
, sizeflag
);
4782 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
4797 FETCH_DATA (the_info
, codep
+ 1);
4798 index
= (*codep
>> 3) & 7;
4799 if (address_mode
== mode_64bit
|| index
!= 0x4)
4800 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4801 scale
= (*codep
>> 6) & 3;
4813 if ((base
& 7) == 5)
4816 if (address_mode
== mode_64bit
&& !havesib
)
4822 FETCH_DATA (the_info
, codep
+ 1);
4824 if ((disp
& 0x80) != 0)
4833 if (modrm
.mod
!= 0 || (base
& 7) == 5)
4835 print_operand_value (scratchbuf
, !riprel
, disp
);
4836 oappend (scratchbuf
);
4845 || (intel_syntax
&& riprel
)
4846 || (havesib
&& (index
!= 4 || scale
!= 0)))
4848 *obufp
++ = open_char
;
4849 if (intel_syntax
&& riprel
)
4856 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4857 ? names64
[base
] : names32
[base
]);
4862 if (!intel_syntax
|| havebase
)
4864 *obufp
++ = separator_char
;
4867 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4868 ? names64
[index
] : names32
[index
]);
4870 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4872 *obufp
++ = scale_char
;
4874 sprintf (scratchbuf
, "%d", 1 << scale
);
4875 oappend (scratchbuf
);
4879 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
4881 if ((bfd_signed_vma
) disp
>= 0)
4886 else if (modrm
.mod
!= 1)
4890 disp
= - (bfd_signed_vma
) disp
;
4893 print_operand_value (scratchbuf
, modrm
.mod
!= 1, disp
);
4894 oappend (scratchbuf
);
4897 *obufp
++ = close_char
;
4900 else if (intel_syntax
)
4902 if (modrm
.mod
!= 0 || (base
& 7) == 5)
4904 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4905 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4909 oappend (names_seg
[ds_reg
- es_reg
]);
4912 print_operand_value (scratchbuf
, 1, disp
);
4913 oappend (scratchbuf
);
4918 { /* 16 bit address mode */
4925 if ((disp
& 0x8000) != 0)
4930 FETCH_DATA (the_info
, codep
+ 1);
4932 if ((disp
& 0x80) != 0)
4937 if ((disp
& 0x8000) != 0)
4943 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
4945 print_operand_value (scratchbuf
, 0, disp
);
4946 oappend (scratchbuf
);
4949 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
4951 *obufp
++ = open_char
;
4953 oappend (index16
[modrm
.rm
]);
4954 if (intel_syntax
&& disp
)
4956 if ((bfd_signed_vma
) disp
> 0)
4961 else if (modrm
.mod
!= 1)
4965 disp
= - (bfd_signed_vma
) disp
;
4968 print_operand_value (scratchbuf
, modrm
.mod
!= 1, disp
);
4969 oappend (scratchbuf
);
4972 *obufp
++ = close_char
;
4975 else if (intel_syntax
)
4977 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4978 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4982 oappend (names_seg
[ds_reg
- es_reg
]);
4985 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
4986 oappend (scratchbuf
);
4992 OP_G (int bytemode
, int sizeflag
)
5003 oappend (names8rex
[modrm
.reg
+ add
]);
5005 oappend (names8
[modrm
.reg
+ add
]);
5008 oappend (names16
[modrm
.reg
+ add
]);
5011 oappend (names32
[modrm
.reg
+ add
]);
5014 oappend (names64
[modrm
.reg
+ add
]);
5023 oappend (names64
[modrm
.reg
+ add
]);
5024 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5025 oappend (names32
[modrm
.reg
+ add
]);
5027 oappend (names16
[modrm
.reg
+ add
]);
5028 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5031 if (address_mode
== mode_64bit
)
5032 oappend (names64
[modrm
.reg
+ add
]);
5034 oappend (names32
[modrm
.reg
+ add
]);
5037 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5050 FETCH_DATA (the_info
, codep
+ 8);
5051 a
= *codep
++ & 0xff;
5052 a
|= (*codep
++ & 0xff) << 8;
5053 a
|= (*codep
++ & 0xff) << 16;
5054 a
|= (*codep
++ & 0xff) << 24;
5055 b
= *codep
++ & 0xff;
5056 b
|= (*codep
++ & 0xff) << 8;
5057 b
|= (*codep
++ & 0xff) << 16;
5058 b
|= (*codep
++ & 0xff) << 24;
5059 x
= a
+ ((bfd_vma
) b
<< 32);
5067 static bfd_signed_vma
5070 bfd_signed_vma x
= 0;
5072 FETCH_DATA (the_info
, codep
+ 4);
5073 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5074 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5075 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5076 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5080 static bfd_signed_vma
5083 bfd_signed_vma x
= 0;
5085 FETCH_DATA (the_info
, codep
+ 4);
5086 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5087 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5088 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5089 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5091 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5101 FETCH_DATA (the_info
, codep
+ 2);
5102 x
= *codep
++ & 0xff;
5103 x
|= (*codep
++ & 0xff) << 8;
5108 set_op (bfd_vma op
, int riprel
)
5110 op_index
[op_ad
] = op_ad
;
5111 if (address_mode
== mode_64bit
)
5113 op_address
[op_ad
] = op
;
5114 op_riprel
[op_ad
] = riprel
;
5118 /* Mask to get a 32-bit address. */
5119 op_address
[op_ad
] = op
& 0xffffffff;
5120 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5125 OP_REG (int code
, int sizeflag
)
5135 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5136 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5137 s
= names16
[code
- ax_reg
+ add
];
5139 case es_reg
: case ss_reg
: case cs_reg
:
5140 case ds_reg
: case fs_reg
: case gs_reg
:
5141 s
= names_seg
[code
- es_reg
+ add
];
5143 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5144 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5147 s
= names8rex
[code
- al_reg
+ add
];
5149 s
= names8
[code
- al_reg
];
5151 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5152 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5153 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5155 s
= names64
[code
- rAX_reg
+ add
];
5158 code
+= eAX_reg
- rAX_reg
;
5160 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5161 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5164 s
= names64
[code
- eAX_reg
+ add
];
5165 else if (sizeflag
& DFLAG
)
5166 s
= names32
[code
- eAX_reg
+ add
];
5168 s
= names16
[code
- eAX_reg
+ add
];
5169 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5172 s
= INTERNAL_DISASSEMBLER_ERROR
;
5179 OP_IMREG (int code
, int sizeflag
)
5191 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5192 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5193 s
= names16
[code
- ax_reg
];
5195 case es_reg
: case ss_reg
: case cs_reg
:
5196 case ds_reg
: case fs_reg
: case gs_reg
:
5197 s
= names_seg
[code
- es_reg
];
5199 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5200 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5203 s
= names8rex
[code
- al_reg
];
5205 s
= names8
[code
- al_reg
];
5207 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5208 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5211 s
= names64
[code
- eAX_reg
];
5212 else if (sizeflag
& DFLAG
)
5213 s
= names32
[code
- eAX_reg
];
5215 s
= names16
[code
- eAX_reg
];
5216 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5219 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5224 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5227 s
= INTERNAL_DISASSEMBLER_ERROR
;
5234 OP_I (int bytemode
, int sizeflag
)
5237 bfd_signed_vma mask
= -1;
5242 FETCH_DATA (the_info
, codep
+ 1);
5247 if (address_mode
== mode_64bit
)
5257 else if (sizeflag
& DFLAG
)
5267 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5278 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5283 scratchbuf
[0] = '$';
5284 print_operand_value (scratchbuf
+ 1, 1, op
);
5285 oappend (scratchbuf
+ intel_syntax
);
5286 scratchbuf
[0] = '\0';
5290 OP_I64 (int bytemode
, int sizeflag
)
5293 bfd_signed_vma mask
= -1;
5295 if (address_mode
!= mode_64bit
)
5297 OP_I (bytemode
, sizeflag
);
5304 FETCH_DATA (the_info
, codep
+ 1);
5312 else if (sizeflag
& DFLAG
)
5322 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5329 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5334 scratchbuf
[0] = '$';
5335 print_operand_value (scratchbuf
+ 1, 1, op
);
5336 oappend (scratchbuf
+ intel_syntax
);
5337 scratchbuf
[0] = '\0';
5341 OP_sI (int bytemode
, int sizeflag
)
5344 bfd_signed_vma mask
= -1;
5349 FETCH_DATA (the_info
, codep
+ 1);
5351 if ((op
& 0x80) != 0)
5359 else if (sizeflag
& DFLAG
)
5368 if ((op
& 0x8000) != 0)
5371 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5376 if ((op
& 0x8000) != 0)
5380 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5384 scratchbuf
[0] = '$';
5385 print_operand_value (scratchbuf
+ 1, 1, op
);
5386 oappend (scratchbuf
+ intel_syntax
);
5390 OP_J (int bytemode
, int sizeflag
)
5394 bfd_vma segment
= 0;
5399 FETCH_DATA (the_info
, codep
+ 1);
5401 if ((disp
& 0x80) != 0)
5405 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5410 if ((disp
& 0x8000) != 0)
5412 /* In 16bit mode, address is wrapped around at 64k within
5413 the same segment. Otherwise, a data16 prefix on a jump
5414 instruction means that the pc is masked to 16 bits after
5415 the displacement is added! */
5417 if ((prefixes
& PREFIX_DATA
) == 0)
5418 segment
= ((start_pc
+ codep
- start_codep
)
5419 & ~((bfd_vma
) 0xffff));
5421 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5424 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5427 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5429 print_operand_value (scratchbuf
, 1, disp
);
5430 oappend (scratchbuf
);
5434 OP_SEG (int bytemode
, int sizeflag
)
5436 if (bytemode
== w_mode
)
5437 oappend (names_seg
[modrm
.reg
]);
5439 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5443 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5447 if (sizeflag
& DFLAG
)
5457 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5459 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5461 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5462 oappend (scratchbuf
);
5466 OP_OFF (int bytemode
, int sizeflag
)
5470 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5471 intel_operand_size (bytemode
, sizeflag
);
5474 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5481 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5482 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5484 oappend (names_seg
[ds_reg
- es_reg
]);
5488 print_operand_value (scratchbuf
, 1, off
);
5489 oappend (scratchbuf
);
5493 OP_OFF64 (int bytemode
, int sizeflag
)
5497 if (address_mode
!= mode_64bit
5498 || (prefixes
& PREFIX_ADDR
))
5500 OP_OFF (bytemode
, sizeflag
);
5504 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5505 intel_operand_size (bytemode
, sizeflag
);
5512 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5513 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5515 oappend (names_seg
[ds_reg
- es_reg
]);
5519 print_operand_value (scratchbuf
, 1, off
);
5520 oappend (scratchbuf
);
5524 ptr_reg (int code
, int sizeflag
)
5528 *obufp
++ = open_char
;
5529 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5530 if (address_mode
== mode_64bit
)
5532 if (!(sizeflag
& AFLAG
))
5533 s
= names32
[code
- eAX_reg
];
5535 s
= names64
[code
- eAX_reg
];
5537 else if (sizeflag
& AFLAG
)
5538 s
= names32
[code
- eAX_reg
];
5540 s
= names16
[code
- eAX_reg
];
5542 *obufp
++ = close_char
;
5547 OP_ESreg (int code
, int sizeflag
)
5553 case 0x6d: /* insw/insl */
5554 intel_operand_size (z_mode
, sizeflag
);
5556 case 0xa5: /* movsw/movsl/movsq */
5557 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5558 case 0xab: /* stosw/stosl */
5559 case 0xaf: /* scasw/scasl */
5560 intel_operand_size (v_mode
, sizeflag
);
5563 intel_operand_size (b_mode
, sizeflag
);
5566 oappend ("%es:" + intel_syntax
);
5567 ptr_reg (code
, sizeflag
);
5571 OP_DSreg (int code
, int sizeflag
)
5577 case 0x6f: /* outsw/outsl */
5578 intel_operand_size (z_mode
, sizeflag
);
5580 case 0xa5: /* movsw/movsl/movsq */
5581 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5582 case 0xad: /* lodsw/lodsl/lodsq */
5583 intel_operand_size (v_mode
, sizeflag
);
5586 intel_operand_size (b_mode
, sizeflag
);
5596 prefixes
|= PREFIX_DS
;
5598 ptr_reg (code
, sizeflag
);
5602 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5610 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5612 used_prefixes
|= PREFIX_LOCK
;
5615 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5616 oappend (scratchbuf
+ intel_syntax
);
5620 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5627 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5629 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5630 oappend (scratchbuf
);
5634 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5636 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5637 oappend (scratchbuf
+ intel_syntax
);
5641 OP_R (int bytemode
, int sizeflag
)
5644 OP_E (bytemode
, sizeflag
);
5650 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5652 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5653 if (prefixes
& PREFIX_DATA
)
5659 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5662 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5663 oappend (scratchbuf
+ intel_syntax
);
5667 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5673 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5674 oappend (scratchbuf
+ intel_syntax
);
5678 OP_EM (int bytemode
, int sizeflag
)
5682 if (intel_syntax
&& bytemode
== v_mode
)
5684 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5685 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5687 OP_E (bytemode
, sizeflag
);
5691 /* Skip mod/rm byte. */
5694 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5695 if (prefixes
& PREFIX_DATA
)
5702 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5705 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5706 oappend (scratchbuf
+ intel_syntax
);
5709 /* cvt* are the only instructions in sse2 which have
5710 both SSE and MMX operands and also have 0x66 prefix
5711 in their opcode. 0x66 was originally used to differentiate
5712 between SSE and MMX instruction(operands). So we have to handle the
5713 cvt* separately using OP_EMC and OP_MXC */
5715 OP_EMC (int bytemode
, int sizeflag
)
5719 if (intel_syntax
&& bytemode
== v_mode
)
5721 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5722 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5724 OP_E (bytemode
, sizeflag
);
5728 /* Skip mod/rm byte. */
5731 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5732 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5733 oappend (scratchbuf
+ intel_syntax
);
5737 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5739 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5740 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5741 oappend (scratchbuf
+ intel_syntax
);
5745 OP_EX (int bytemode
, int sizeflag
)
5750 if (intel_syntax
&& bytemode
== v_mode
)
5752 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
5754 case 0: bytemode
= x_mode
; break;
5755 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
5756 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
5757 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
5758 default: bytemode
= 0; break;
5761 OP_E (bytemode
, sizeflag
);
5768 /* Skip mod/rm byte. */
5771 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5772 oappend (scratchbuf
+ intel_syntax
);
5776 OP_MS (int bytemode
, int sizeflag
)
5779 OP_EM (bytemode
, sizeflag
);
5785 OP_XS (int bytemode
, int sizeflag
)
5788 OP_EX (bytemode
, sizeflag
);
5794 OP_M (int bytemode
, int sizeflag
)
5797 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5800 OP_E (bytemode
, sizeflag
);
5804 OP_0f07 (int bytemode
, int sizeflag
)
5806 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
5809 OP_E (bytemode
, sizeflag
);
5813 OP_0fae (int bytemode
, int sizeflag
)
5818 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5820 if (modrm
.reg
< 5 || modrm
.rm
!= 0)
5822 BadOp (); /* bad sfence, mfence, or lfence */
5826 else if (modrm
.reg
!= 7)
5828 BadOp (); /* bad clflush */
5832 OP_E (bytemode
, sizeflag
);
5835 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5836 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5839 NOP_Fixup1 (int bytemode
, int sizeflag
)
5841 if ((prefixes
& PREFIX_DATA
) != 0
5844 && address_mode
== mode_64bit
))
5845 OP_REG (bytemode
, sizeflag
);
5847 strcpy (obuf
, "nop");
5851 NOP_Fixup2 (int bytemode
, int sizeflag
)
5853 if ((prefixes
& PREFIX_DATA
) != 0
5856 && address_mode
== mode_64bit
))
5857 OP_IMREG (bytemode
, sizeflag
);
5860 static const char *const Suffix3DNow
[] = {
5861 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5862 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5863 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5864 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5865 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5866 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5867 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5868 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5869 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5870 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5871 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5872 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5873 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5874 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5875 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5876 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5877 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5878 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5879 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5880 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5881 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5882 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5883 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5884 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5885 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5886 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5887 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5888 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5889 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5890 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5891 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5892 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5893 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5894 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5895 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5896 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5897 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5898 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5899 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5900 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5901 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5902 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5903 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5904 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5905 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5906 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5907 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5908 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5909 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5910 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5911 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5912 /* CC */ NULL
, NULL
, NULL
, NULL
,
5913 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5914 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5915 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5916 /* DC */ NULL
, NULL
, NULL
, NULL
,
5917 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5918 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5919 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5920 /* EC */ NULL
, NULL
, NULL
, NULL
,
5921 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5922 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5923 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5924 /* FC */ NULL
, NULL
, NULL
, NULL
,
5928 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5930 const char *mnemonic
;
5932 FETCH_DATA (the_info
, codep
+ 1);
5933 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5934 place where an 8-bit immediate would normally go. ie. the last
5935 byte of the instruction. */
5936 obufp
= obuf
+ strlen (obuf
);
5937 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5942 /* Since a variable sized modrm/sib chunk is between the start
5943 of the opcode (0x0f0f) and the opcode suffix, we need to do
5944 all the modrm processing first, and don't know until now that
5945 we have a bad opcode. This necessitates some cleaning up. */
5946 op_out
[0][0] = '\0';
5947 op_out
[1][0] = '\0';
5952 static const char *simd_cmp_op
[] = {
5964 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5966 unsigned int cmp_type
;
5968 FETCH_DATA (the_info
, codep
+ 1);
5969 obufp
= obuf
+ strlen (obuf
);
5970 cmp_type
= *codep
++ & 0xff;
5973 char suffix1
= 'p', suffix2
= 's';
5974 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5975 if (prefixes
& PREFIX_REPZ
)
5979 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5980 if (prefixes
& PREFIX_DATA
)
5984 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5985 if (prefixes
& PREFIX_REPNZ
)
5986 suffix1
= 's', suffix2
= 'd';
5989 sprintf (scratchbuf
, "cmp%s%c%c",
5990 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5991 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5992 oappend (scratchbuf
);
5996 /* We have a bad extension byte. Clean up. */
5997 op_out
[0][0] = '\0';
5998 op_out
[1][0] = '\0';
6004 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
6006 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6007 forms of these instructions. */
6010 char *p
= obuf
+ strlen (obuf
);
6013 *(p
- 1) = *(p
- 2);
6014 *(p
- 2) = *(p
- 3);
6015 *(p
- 3) = extrachar
;
6020 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6022 if (modrm
.mod
== 3 && modrm
.reg
== 1 && modrm
.rm
<= 1)
6024 /* Override "sidt". */
6025 size_t olen
= strlen (obuf
);
6026 char *p
= obuf
+ olen
- 4;
6027 const char **names
= (address_mode
== mode_64bit
6028 ? names64
: names32
);
6030 /* We might have a suffix when disassembling with -Msuffix. */
6034 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6036 && (prefixes
& PREFIX_ADDR
)
6039 && CONST_STRNEQ (p
- 7, "addr")
6040 && (CONST_STRNEQ (p
- 3, "16")
6041 || CONST_STRNEQ (p
- 3, "32")))
6046 /* mwait %eax,%ecx */
6047 strcpy (p
, "mwait");
6049 strcpy (op_out
[0], names
[0]);
6053 /* monitor %eax,%ecx,%edx" */
6054 strcpy (p
, "monitor");
6057 const char **op1_names
;
6058 if (!(prefixes
& PREFIX_ADDR
))
6059 op1_names
= (address_mode
== mode_16bit
6063 op1_names
= (address_mode
!= mode_32bit
6064 ? names32
: names16
);
6065 used_prefixes
|= PREFIX_ADDR
;
6067 strcpy (op_out
[0], op1_names
[0]);
6068 strcpy (op_out
[2], names
[2]);
6073 strcpy (op_out
[1], names
[1]);
6084 SVME_Fixup (int bytemode
, int sizeflag
)
6116 OP_M (bytemode
, sizeflag
);
6119 /* Override "lidt". */
6120 p
= obuf
+ strlen (obuf
) - 4;
6121 /* We might have a suffix. */
6125 if (!(prefixes
& PREFIX_ADDR
))
6130 used_prefixes
|= PREFIX_ADDR
;
6134 strcpy (op_out
[1], names32
[1]);
6140 *obufp
++ = open_char
;
6141 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6145 strcpy (obufp
, alt
);
6146 obufp
+= strlen (alt
);
6147 *obufp
++ = close_char
;
6154 INVLPG_Fixup (int bytemode
, int sizeflag
)
6167 OP_M (bytemode
, sizeflag
);
6170 /* Override "invlpg". */
6171 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6178 /* Throw away prefixes and 1st. opcode byte. */
6179 codep
= insn_codep
+ 1;
6184 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6191 /* Override "sgdt". */
6192 char *p
= obuf
+ strlen (obuf
) - 4;
6194 /* We might have a suffix when disassembling with -Msuffix. */
6201 strcpy (p
, "vmcall");
6204 strcpy (p
, "vmlaunch");
6207 strcpy (p
, "vmresume");
6210 strcpy (p
, "vmxoff");
6221 OP_VMX (int bytemode
, int sizeflag
)
6223 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
6224 if (prefixes
& PREFIX_DATA
)
6225 strcpy (obuf
, "vmclear");
6226 else if (prefixes
& PREFIX_REPZ
)
6227 strcpy (obuf
, "vmxon");
6229 strcpy (obuf
, "vmptrld");
6230 OP_E (bytemode
, sizeflag
);
6234 REP_Fixup (int bytemode
, int sizeflag
)
6236 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6240 if (prefixes
& PREFIX_REPZ
)
6241 switch (*insn_codep
)
6243 case 0x6e: /* outsb */
6244 case 0x6f: /* outsw/outsl */
6245 case 0xa4: /* movsb */
6246 case 0xa5: /* movsw/movsl/movsq */
6252 case 0xaa: /* stosb */
6253 case 0xab: /* stosw/stosl/stosq */
6254 case 0xac: /* lodsb */
6255 case 0xad: /* lodsw/lodsl/lodsq */
6256 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
6261 case 0x6c: /* insb */
6262 case 0x6d: /* insl/insw */
6278 olen
= strlen (obuf
);
6279 p
= obuf
+ olen
- ilen
- 1 - 4;
6280 /* Handle "repz [addr16|addr32]". */
6281 if ((prefixes
& PREFIX_ADDR
))
6284 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
6292 OP_IMREG (bytemode
, sizeflag
);
6295 OP_ESreg (bytemode
, sizeflag
);
6298 OP_DSreg (bytemode
, sizeflag
);
6307 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6312 /* Change cmpxchg8b to cmpxchg16b. */
6313 char *p
= obuf
+ strlen (obuf
) - 2;
6317 OP_M (bytemode
, sizeflag
);
6321 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6323 sprintf (scratchbuf
, "%%xmm%d", reg
);
6324 oappend (scratchbuf
+ intel_syntax
);
6328 CRC32_Fixup (int bytemode
, int sizeflag
)
6330 /* Add proper suffix to "crc32". */
6331 char *p
= obuf
+ strlen (obuf
);
6342 else if ((prefixes
& PREFIX_DATA
))
6345 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6351 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6360 /* Skip mod/rm byte. */
6365 add
= (rex
& REX_B
) ? 8 : 0;
6366 if (bytemode
== b_mode
)
6370 oappend (names8rex
[modrm
.rm
+ add
]);
6372 oappend (names8
[modrm
.rm
+ add
]);
6378 oappend (names64
[modrm
.rm
+ add
]);
6379 else if ((prefixes
& PREFIX_DATA
))
6380 oappend (names16
[modrm
.rm
+ add
]);
6382 oappend (names32
[modrm
.rm
+ add
]);
6386 OP_E (v_mode
, sizeflag
);