1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
25 modified by John Hassey (hassey@dg-rtp.dg.com)
26 x86-64 support added by Jan Hubicka (jh@suse.cz)
27 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
29 /* The main tables describing the instructions is essentially a copy
30 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
31 Programmers Manual. Usually, there is a capital letter, followed
32 by a small letter. The capital letter tell the addressing mode,
33 and the small letter tells about the operand size. Refer to
34 the Intel manual for details. */
39 #include "opcode/i386.h"
43 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
44 static void ckprefix (void);
45 static const char *prefix_name (int, int);
46 static int print_insn (bfd_vma
, disassemble_info
*);
47 static void dofloat (int);
48 static void OP_ST (int, int);
49 static void OP_STi (int, int);
50 static int putop (const char *, int);
51 static void oappend (const char *);
52 static void append_seg (void);
53 static void OP_indirE (int, int);
54 static void print_operand_value (char *, int, bfd_vma
);
55 static void print_displacement (char *, bfd_vma
);
56 static void OP_E (int, int);
57 static void OP_G (int, int);
58 static bfd_vma
get64 (void);
59 static bfd_signed_vma
get32 (void);
60 static bfd_signed_vma
get32s (void);
61 static int get16 (void);
62 static void set_op (bfd_vma
, int);
63 static void OP_REG (int, int);
64 static void OP_IMREG (int, int);
65 static void OP_I (int, int);
66 static void OP_I64 (int, int);
67 static void OP_sI (int, int);
68 static void OP_J (int, int);
69 static void OP_SEG (int, int);
70 static void OP_DIR (int, int);
71 static void OP_OFF (int, int);
72 static void OP_OFF64 (int, int);
73 static void ptr_reg (int, int);
74 static void OP_ESreg (int, int);
75 static void OP_DSreg (int, int);
76 static void OP_C (int, int);
77 static void OP_D (int, int);
78 static void OP_T (int, int);
79 static void OP_R (int, int);
80 static void OP_MMX (int, int);
81 static void OP_XMM (int, int);
82 static void OP_EM (int, int);
83 static void OP_EX (int, int);
84 static void OP_EMC (int,int);
85 static void OP_MXC (int,int);
86 static void OP_MS (int, int);
87 static void OP_XS (int, int);
88 static void OP_M (int, int);
89 static void OP_VMX (int, int);
90 static void OP_0fae (int, int);
91 static void OP_0f07 (int, int);
92 static void NOP_Fixup1 (int, int);
93 static void NOP_Fixup2 (int, int);
94 static void OP_3DNowSuffix (int, int);
95 static void OP_SIMD_Suffix (int, int);
96 static void SIMD_Fixup (int, int);
97 static void PNI_Fixup (int, int);
98 static void SVME_Fixup (int, int);
99 static void INVLPG_Fixup (int, int);
100 static void BadOp (void);
101 static void VMX_Fixup (int, int);
102 static void REP_Fixup (int, int);
103 static void CMPXCHG8B_Fixup (int, int);
104 static void XMM_Fixup (int, int);
105 static void CRC32_Fixup (int, int);
108 /* Points to first byte not fetched. */
109 bfd_byte
*max_fetched
;
110 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
123 enum address_mode address_mode
;
125 /* Flags for the prefixes for the current instruction. See below. */
128 /* REX prefix the current instruction. See below. */
130 /* Bits of REX we've already used. */
132 /* Mark parts used in the REX prefix. When we are testing for
133 empty prefix (for 8bit register REX extension), just mask it
134 out. Otherwise test for REX bit is excuse for existence of REX
135 only in case value is nonzero. */
136 #define USED_REX(value) \
141 rex_used |= (value) | REX_OPCODE; \
144 rex_used |= REX_OPCODE; \
147 /* Flags for prefixes which we somehow handled when printing the
148 current instruction. */
149 static int used_prefixes
;
151 /* Flags stored in PREFIXES. */
152 #define PREFIX_REPZ 1
153 #define PREFIX_REPNZ 2
154 #define PREFIX_LOCK 4
156 #define PREFIX_SS 0x10
157 #define PREFIX_DS 0x20
158 #define PREFIX_ES 0x40
159 #define PREFIX_FS 0x80
160 #define PREFIX_GS 0x100
161 #define PREFIX_DATA 0x200
162 #define PREFIX_ADDR 0x400
163 #define PREFIX_FWAIT 0x800
165 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
166 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
168 #define FETCH_DATA(info, addr) \
169 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
170 ? 1 : fetch_data ((info), (addr)))
173 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
176 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
177 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
179 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
180 status
= (*info
->read_memory_func
) (start
,
182 addr
- priv
->max_fetched
,
188 /* If we did manage to read at least one byte, then
189 print_insn_i386 will do something sensible. Otherwise, print
190 an error. We do that here because this is where we know
192 if (priv
->max_fetched
== priv
->the_buffer
)
193 (*info
->memory_error_func
) (status
, start
, info
);
194 longjmp (priv
->bailout
, 1);
197 priv
->max_fetched
= addr
;
201 #define XX { NULL, 0 }
203 #define Eb { OP_E, b_mode }
204 #define Ev { OP_E, v_mode }
205 #define Ed { OP_E, d_mode }
206 #define Edq { OP_E, dq_mode }
207 #define Edqw { OP_E, dqw_mode }
208 #define Edqb { OP_E, dqb_mode }
209 #define Edqd { OP_E, dqd_mode }
210 #define Eq { OP_E, q_mode }
211 #define indirEv { OP_indirE, stack_v_mode }
212 #define indirEp { OP_indirE, f_mode }
213 #define stackEv { OP_E, stack_v_mode }
214 #define Em { OP_E, m_mode }
215 #define Ew { OP_E, w_mode }
216 #define M { OP_M, 0 } /* lea, lgdt, etc. */
217 #define Ma { OP_M, v_mode }
218 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
219 #define Mq { OP_M, q_mode }
220 #define Gb { OP_G, b_mode }
221 #define Gv { OP_G, v_mode }
222 #define Gd { OP_G, d_mode }
223 #define Gdq { OP_G, dq_mode }
224 #define Gm { OP_G, m_mode }
225 #define Gw { OP_G, w_mode }
226 #define Rd { OP_R, d_mode }
227 #define Rm { OP_R, m_mode }
228 #define Ib { OP_I, b_mode }
229 #define sIb { OP_sI, b_mode } /* sign extened byte */
230 #define Iv { OP_I, v_mode }
231 #define Iq { OP_I, q_mode }
232 #define Iv64 { OP_I64, v_mode }
233 #define Iw { OP_I, w_mode }
234 #define I1 { OP_I, const_1_mode }
235 #define Jb { OP_J, b_mode }
236 #define Jv { OP_J, v_mode }
237 #define Cm { OP_C, m_mode }
238 #define Dm { OP_D, m_mode }
239 #define Td { OP_T, d_mode }
241 #define RMeAX { OP_REG, eAX_reg }
242 #define RMeBX { OP_REG, eBX_reg }
243 #define RMeCX { OP_REG, eCX_reg }
244 #define RMeDX { OP_REG, eDX_reg }
245 #define RMeSP { OP_REG, eSP_reg }
246 #define RMeBP { OP_REG, eBP_reg }
247 #define RMeSI { OP_REG, eSI_reg }
248 #define RMeDI { OP_REG, eDI_reg }
249 #define RMrAX { OP_REG, rAX_reg }
250 #define RMrBX { OP_REG, rBX_reg }
251 #define RMrCX { OP_REG, rCX_reg }
252 #define RMrDX { OP_REG, rDX_reg }
253 #define RMrSP { OP_REG, rSP_reg }
254 #define RMrBP { OP_REG, rBP_reg }
255 #define RMrSI { OP_REG, rSI_reg }
256 #define RMrDI { OP_REG, rDI_reg }
257 #define RMAL { OP_REG, al_reg }
258 #define RMAL { OP_REG, al_reg }
259 #define RMCL { OP_REG, cl_reg }
260 #define RMDL { OP_REG, dl_reg }
261 #define RMBL { OP_REG, bl_reg }
262 #define RMAH { OP_REG, ah_reg }
263 #define RMCH { OP_REG, ch_reg }
264 #define RMDH { OP_REG, dh_reg }
265 #define RMBH { OP_REG, bh_reg }
266 #define RMAX { OP_REG, ax_reg }
267 #define RMDX { OP_REG, dx_reg }
269 #define eAX { OP_IMREG, eAX_reg }
270 #define eBX { OP_IMREG, eBX_reg }
271 #define eCX { OP_IMREG, eCX_reg }
272 #define eDX { OP_IMREG, eDX_reg }
273 #define eSP { OP_IMREG, eSP_reg }
274 #define eBP { OP_IMREG, eBP_reg }
275 #define eSI { OP_IMREG, eSI_reg }
276 #define eDI { OP_IMREG, eDI_reg }
277 #define AL { OP_IMREG, al_reg }
278 #define CL { OP_IMREG, cl_reg }
279 #define DL { OP_IMREG, dl_reg }
280 #define BL { OP_IMREG, bl_reg }
281 #define AH { OP_IMREG, ah_reg }
282 #define CH { OP_IMREG, ch_reg }
283 #define DH { OP_IMREG, dh_reg }
284 #define BH { OP_IMREG, bh_reg }
285 #define AX { OP_IMREG, ax_reg }
286 #define DX { OP_IMREG, dx_reg }
287 #define zAX { OP_IMREG, z_mode_ax_reg }
288 #define indirDX { OP_IMREG, indir_dx_reg }
290 #define Sw { OP_SEG, w_mode }
291 #define Sv { OP_SEG, v_mode }
292 #define Ap { OP_DIR, 0 }
293 #define Ob { OP_OFF64, b_mode }
294 #define Ov { OP_OFF64, v_mode }
295 #define Xb { OP_DSreg, eSI_reg }
296 #define Xv { OP_DSreg, eSI_reg }
297 #define Xz { OP_DSreg, eSI_reg }
298 #define Yb { OP_ESreg, eDI_reg }
299 #define Yv { OP_ESreg, eDI_reg }
300 #define DSBX { OP_DSreg, eBX_reg }
302 #define es { OP_REG, es_reg }
303 #define ss { OP_REG, ss_reg }
304 #define cs { OP_REG, cs_reg }
305 #define ds { OP_REG, ds_reg }
306 #define fs { OP_REG, fs_reg }
307 #define gs { OP_REG, gs_reg }
309 #define MX { OP_MMX, 0 }
310 #define XM { OP_XMM, 0 }
311 #define EM { OP_EM, v_mode }
312 #define EMd { OP_EM, d_mode }
313 #define EMx { OP_EM, x_mode }
314 #define EXd { OP_EX, d_mode }
315 #define EXq { OP_EX, q_mode }
316 #define EXx { OP_EX, x_mode }
317 #define MS { OP_MS, v_mode }
318 #define XS { OP_XS, v_mode }
319 #define EMCq { OP_EMC, q_mode }
320 #define MXC { OP_MXC, 0 }
321 #define VM { OP_VMX, q_mode }
322 #define OPSUF { OP_3DNowSuffix, 0 }
323 #define OPSIMD { OP_SIMD_Suffix, 0 }
324 #define XMM0 { XMM_Fixup, 0 }
326 /* Used handle "rep" prefix for string instructions. */
327 #define Xbr { REP_Fixup, eSI_reg }
328 #define Xvr { REP_Fixup, eSI_reg }
329 #define Ybr { REP_Fixup, eDI_reg }
330 #define Yvr { REP_Fixup, eDI_reg }
331 #define Yzr { REP_Fixup, eDI_reg }
332 #define indirDXr { REP_Fixup, indir_dx_reg }
333 #define ALr { REP_Fixup, al_reg }
334 #define eAXr { REP_Fixup, eAX_reg }
336 #define cond_jump_flag { NULL, cond_jump_mode }
337 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
339 /* bits in sizeflag */
340 #define SUFFIX_ALWAYS 4
344 #define b_mode 1 /* byte operand */
345 #define v_mode 2 /* operand size depends on prefixes */
346 #define w_mode 3 /* word operand */
347 #define d_mode 4 /* double word operand */
348 #define q_mode 5 /* quad word operand */
349 #define t_mode 6 /* ten-byte operand */
350 #define x_mode 7 /* 16-byte XMM operand */
351 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
352 #define cond_jump_mode 9
353 #define loop_jcxz_mode 10
354 #define dq_mode 11 /* operand size depends on REX prefixes. */
355 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
356 #define f_mode 13 /* 4- or 6-byte pointer operand */
357 #define const_1_mode 14
358 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
359 #define z_mode 16 /* non-quad operand size depends on prefixes */
360 #define o_mode 17 /* 16-byte operand */
361 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
362 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
407 #define z_mode_ax_reg 149
408 #define indir_dx_reg 150
412 #define USE_PREFIX_USER_TABLE 3
413 #define X86_64_SPECIAL 4
414 #define IS_3BYTE_OPCODE 5
416 #define FLOAT NULL, { { NULL, FLOATCODE } }
418 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
419 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
420 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
421 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
422 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
423 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
424 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
425 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
426 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
427 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
428 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
429 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
430 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
431 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
432 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
433 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
434 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
435 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
436 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
437 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
438 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
439 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
440 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
441 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
442 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
443 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
444 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
445 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
447 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
448 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
449 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
450 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
451 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
452 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
453 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
454 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
455 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
456 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
457 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
458 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
459 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
460 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
461 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
462 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
463 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
464 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
465 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
466 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
467 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
468 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
469 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
470 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
471 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
472 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
473 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
474 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
475 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
476 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
477 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
478 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
479 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
480 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
481 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
482 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
483 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
484 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
485 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
486 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
487 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
488 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
489 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
490 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
491 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
492 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
493 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
494 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
495 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
496 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
497 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
498 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
499 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
500 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
501 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
502 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
503 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
504 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
505 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
506 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
507 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
508 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
509 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
510 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
511 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
512 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
513 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
514 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
515 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
516 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
517 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
518 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
519 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
520 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
521 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
522 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
523 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
524 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
525 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
526 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
527 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
528 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
529 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
530 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
531 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
532 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
533 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
534 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
535 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
536 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
537 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
538 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
539 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
540 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
541 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
542 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
543 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
544 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
547 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
548 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
549 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
550 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
552 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
553 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
555 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
566 /* Upper case letters in the instruction names here are macros.
567 'A' => print 'b' if no register operands or suffix_always is true
568 'B' => print 'b' if suffix_always is true
569 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
571 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
572 . suffix_always is true
573 'E' => print 'e' if 32-bit form of jcxz
574 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
575 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
576 'H' => print ",pt" or ",pn" branch hint
577 'I' => honor following macro letter even in Intel mode (implemented only
578 . for some of the macro letters)
580 'K' => print 'd' or 'q' if rex prefix is present.
581 'L' => print 'l' if suffix_always is true
582 'N' => print 'n' if instruction has no wait "prefix"
583 'O' => print 'd' or 'o' (or 'q' in Intel mode)
584 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
585 . or suffix_always is true. print 'q' if rex prefix is present.
586 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
588 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
589 'S' => print 'w', 'l' or 'q' if suffix_always is true
590 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
591 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
592 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
593 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
594 'X' => print 's', 'd' depending on data16 prefix (for XMM)
595 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
596 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
598 Many of the above letters print nothing in Intel mode. See "putop"
601 Braces '{' and '}', and vertical bars '|', indicate alternative
602 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
603 modes. In cases where there are only two alternatives, the X86_64
604 instruction is reserved, and "(bad)" is printed.
607 static const struct dis386 dis386
[] = {
609 { "addB", { Eb
, Gb
} },
610 { "addS", { Ev
, Gv
} },
611 { "addB", { Gb
, Eb
} },
612 { "addS", { Gv
, Ev
} },
613 { "addB", { AL
, Ib
} },
614 { "addS", { eAX
, Iv
} },
615 { "push{T|}", { es
} },
616 { "pop{T|}", { es
} },
618 { "orB", { Eb
, Gb
} },
619 { "orS", { Ev
, Gv
} },
620 { "orB", { Gb
, Eb
} },
621 { "orS", { Gv
, Ev
} },
622 { "orB", { AL
, Ib
} },
623 { "orS", { eAX
, Iv
} },
624 { "push{T|}", { cs
} },
625 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
627 { "adcB", { Eb
, Gb
} },
628 { "adcS", { Ev
, Gv
} },
629 { "adcB", { Gb
, Eb
} },
630 { "adcS", { Gv
, Ev
} },
631 { "adcB", { AL
, Ib
} },
632 { "adcS", { eAX
, Iv
} },
633 { "push{T|}", { ss
} },
634 { "pop{T|}", { ss
} },
636 { "sbbB", { Eb
, Gb
} },
637 { "sbbS", { Ev
, Gv
} },
638 { "sbbB", { Gb
, Eb
} },
639 { "sbbS", { Gv
, Ev
} },
640 { "sbbB", { AL
, Ib
} },
641 { "sbbS", { eAX
, Iv
} },
642 { "push{T|}", { ds
} },
643 { "pop{T|}", { ds
} },
645 { "andB", { Eb
, Gb
} },
646 { "andS", { Ev
, Gv
} },
647 { "andB", { Gb
, Eb
} },
648 { "andS", { Gv
, Ev
} },
649 { "andB", { AL
, Ib
} },
650 { "andS", { eAX
, Iv
} },
651 { "(bad)", { XX
} }, /* SEG ES prefix */
652 { "daa{|}", { XX
} },
654 { "subB", { Eb
, Gb
} },
655 { "subS", { Ev
, Gv
} },
656 { "subB", { Gb
, Eb
} },
657 { "subS", { Gv
, Ev
} },
658 { "subB", { AL
, Ib
} },
659 { "subS", { eAX
, Iv
} },
660 { "(bad)", { XX
} }, /* SEG CS prefix */
661 { "das{|}", { XX
} },
663 { "xorB", { Eb
, Gb
} },
664 { "xorS", { Ev
, Gv
} },
665 { "xorB", { Gb
, Eb
} },
666 { "xorS", { Gv
, Ev
} },
667 { "xorB", { AL
, Ib
} },
668 { "xorS", { eAX
, Iv
} },
669 { "(bad)", { XX
} }, /* SEG SS prefix */
670 { "aaa{|}", { XX
} },
672 { "cmpB", { Eb
, Gb
} },
673 { "cmpS", { Ev
, Gv
} },
674 { "cmpB", { Gb
, Eb
} },
675 { "cmpS", { Gv
, Ev
} },
676 { "cmpB", { AL
, Ib
} },
677 { "cmpS", { eAX
, Iv
} },
678 { "(bad)", { XX
} }, /* SEG DS prefix */
679 { "aas{|}", { XX
} },
681 { "inc{S|}", { RMeAX
} },
682 { "inc{S|}", { RMeCX
} },
683 { "inc{S|}", { RMeDX
} },
684 { "inc{S|}", { RMeBX
} },
685 { "inc{S|}", { RMeSP
} },
686 { "inc{S|}", { RMeBP
} },
687 { "inc{S|}", { RMeSI
} },
688 { "inc{S|}", { RMeDI
} },
690 { "dec{S|}", { RMeAX
} },
691 { "dec{S|}", { RMeCX
} },
692 { "dec{S|}", { RMeDX
} },
693 { "dec{S|}", { RMeBX
} },
694 { "dec{S|}", { RMeSP
} },
695 { "dec{S|}", { RMeBP
} },
696 { "dec{S|}", { RMeSI
} },
697 { "dec{S|}", { RMeDI
} },
699 { "pushV", { RMrAX
} },
700 { "pushV", { RMrCX
} },
701 { "pushV", { RMrDX
} },
702 { "pushV", { RMrBX
} },
703 { "pushV", { RMrSP
} },
704 { "pushV", { RMrBP
} },
705 { "pushV", { RMrSI
} },
706 { "pushV", { RMrDI
} },
708 { "popV", { RMrAX
} },
709 { "popV", { RMrCX
} },
710 { "popV", { RMrDX
} },
711 { "popV", { RMrBX
} },
712 { "popV", { RMrSP
} },
713 { "popV", { RMrBP
} },
714 { "popV", { RMrSI
} },
715 { "popV", { RMrDI
} },
721 { "(bad)", { XX
} }, /* seg fs */
722 { "(bad)", { XX
} }, /* seg gs */
723 { "(bad)", { XX
} }, /* op size prefix */
724 { "(bad)", { XX
} }, /* adr size prefix */
727 { "imulS", { Gv
, Ev
, Iv
} },
728 { "pushT", { sIb
} },
729 { "imulS", { Gv
, Ev
, sIb
} },
730 { "ins{b||b|}", { Ybr
, indirDX
} },
731 { "ins{R||G|}", { Yzr
, indirDX
} },
732 { "outs{b||b|}", { indirDXr
, Xb
} },
733 { "outs{R||G|}", { indirDXr
, Xz
} },
735 { "joH", { Jb
, XX
, cond_jump_flag
} },
736 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
737 { "jbH", { Jb
, XX
, cond_jump_flag
} },
738 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
739 { "jeH", { Jb
, XX
, cond_jump_flag
} },
740 { "jneH", { Jb
, XX
, cond_jump_flag
} },
741 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
742 { "jaH", { Jb
, XX
, cond_jump_flag
} },
744 { "jsH", { Jb
, XX
, cond_jump_flag
} },
745 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
746 { "jpH", { Jb
, XX
, cond_jump_flag
} },
747 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
748 { "jlH", { Jb
, XX
, cond_jump_flag
} },
749 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
750 { "jleH", { Jb
, XX
, cond_jump_flag
} },
751 { "jgH", { Jb
, XX
, cond_jump_flag
} },
757 { "testB", { Eb
, Gb
} },
758 { "testS", { Ev
, Gv
} },
759 { "xchgB", { Eb
, Gb
} },
760 { "xchgS", { Ev
, Gv
} },
762 { "movB", { Eb
, Gb
} },
763 { "movS", { Ev
, Gv
} },
764 { "movB", { Gb
, Eb
} },
765 { "movS", { Gv
, Ev
} },
766 { "movD", { Sv
, Sw
} },
767 { "leaS", { Gv
, M
} },
768 { "movD", { Sw
, Sv
} },
772 { "xchgS", { RMeCX
, eAX
} },
773 { "xchgS", { RMeDX
, eAX
} },
774 { "xchgS", { RMeBX
, eAX
} },
775 { "xchgS", { RMeSP
, eAX
} },
776 { "xchgS", { RMeBP
, eAX
} },
777 { "xchgS", { RMeSI
, eAX
} },
778 { "xchgS", { RMeDI
, eAX
} },
780 { "cW{t||t|}R", { XX
} },
781 { "cR{t||t|}O", { XX
} },
782 { "Jcall{T|}", { Ap
} },
783 { "(bad)", { XX
} }, /* fwait */
784 { "pushfT", { XX
} },
786 { "sahf{|}", { XX
} },
787 { "lahf{|}", { XX
} },
789 { "movB", { AL
, Ob
} },
790 { "movS", { eAX
, Ov
} },
791 { "movB", { Ob
, AL
} },
792 { "movS", { Ov
, eAX
} },
793 { "movs{b||b|}", { Ybr
, Xb
} },
794 { "movs{R||R|}", { Yvr
, Xv
} },
795 { "cmps{b||b|}", { Xb
, Yb
} },
796 { "cmps{R||R|}", { Xv
, Yv
} },
798 { "testB", { AL
, Ib
} },
799 { "testS", { eAX
, Iv
} },
800 { "stosB", { Ybr
, AL
} },
801 { "stosS", { Yvr
, eAX
} },
802 { "lodsB", { ALr
, Xb
} },
803 { "lodsS", { eAXr
, Xv
} },
804 { "scasB", { AL
, Yb
} },
805 { "scasS", { eAX
, Yv
} },
807 { "movB", { RMAL
, Ib
} },
808 { "movB", { RMCL
, Ib
} },
809 { "movB", { RMDL
, Ib
} },
810 { "movB", { RMBL
, Ib
} },
811 { "movB", { RMAH
, Ib
} },
812 { "movB", { RMCH
, Ib
} },
813 { "movB", { RMDH
, Ib
} },
814 { "movB", { RMBH
, Ib
} },
816 { "movS", { RMeAX
, Iv64
} },
817 { "movS", { RMeCX
, Iv64
} },
818 { "movS", { RMeDX
, Iv64
} },
819 { "movS", { RMeBX
, Iv64
} },
820 { "movS", { RMeSP
, Iv64
} },
821 { "movS", { RMeBP
, Iv64
} },
822 { "movS", { RMeSI
, Iv64
} },
823 { "movS", { RMeDI
, Iv64
} },
829 { "les{S|}", { Gv
, Mp
} },
830 { "ldsS", { Gv
, Mp
} },
834 { "enterT", { Iw
, Ib
} },
835 { "leaveT", { XX
} },
840 { "into{|}", { XX
} },
847 { "aam{|}", { sIb
} },
848 { "aad{|}", { sIb
} },
850 { "xlat", { DSBX
} },
861 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
862 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
863 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
864 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
865 { "inB", { AL
, Ib
} },
866 { "inG", { zAX
, Ib
} },
867 { "outB", { Ib
, AL
} },
868 { "outG", { Ib
, zAX
} },
872 { "Jjmp{T|}", { Ap
} },
874 { "inB", { AL
, indirDX
} },
875 { "inG", { zAX
, indirDX
} },
876 { "outB", { indirDX
, AL
} },
877 { "outG", { indirDX
, zAX
} },
879 { "(bad)", { XX
} }, /* lock prefix */
881 { "(bad)", { XX
} }, /* repne */
882 { "(bad)", { XX
} }, /* repz */
898 static const struct dis386 dis386_twobyte
[] = {
902 { "larS", { Gv
, Ew
} },
903 { "lslS", { Gv
, Ew
} },
905 { "syscall", { XX
} },
907 { "sysretP", { XX
} },
910 { "wbinvd", { XX
} },
916 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
921 { "movlpX", { EXq
, XM
, { SIMD_Fixup
, 'h' } } },
922 { "unpcklpX", { XM
, EXq
} },
923 { "unpckhpX", { XM
, EXq
} },
925 { "movhpX", { EXq
, XM
, { SIMD_Fixup
, 'l' } } },
936 { "movZ", { Rm
, Cm
} },
937 { "movZ", { Rm
, Dm
} },
938 { "movZ", { Cm
, Rm
} },
939 { "movZ", { Dm
, Rm
} },
940 { "movL", { Rd
, Td
} },
942 { "movL", { Td
, Rd
} },
945 { "movapX", { XM
, EXx
} },
946 { "movapX", { EXx
, XM
} },
958 { "sysenter", { XX
} },
959 { "sysexit", { XX
} },
972 { "cmovo", { Gv
, Ev
} },
973 { "cmovno", { Gv
, Ev
} },
974 { "cmovb", { Gv
, Ev
} },
975 { "cmovae", { Gv
, Ev
} },
976 { "cmove", { Gv
, Ev
} },
977 { "cmovne", { Gv
, Ev
} },
978 { "cmovbe", { Gv
, Ev
} },
979 { "cmova", { Gv
, Ev
} },
981 { "cmovs", { Gv
, Ev
} },
982 { "cmovns", { Gv
, Ev
} },
983 { "cmovp", { Gv
, Ev
} },
984 { "cmovnp", { Gv
, Ev
} },
985 { "cmovl", { Gv
, Ev
} },
986 { "cmovge", { Gv
, Ev
} },
987 { "cmovle", { Gv
, Ev
} },
988 { "cmovg", { Gv
, Ev
} },
990 { "movmskpX", { Gdq
, XS
} },
994 { "andpX", { XM
, EXx
} },
995 { "andnpX", { XM
, EXx
} },
996 { "orpX", { XM
, EXx
} },
997 { "xorpX", { XM
, EXx
} },
1011 { "packsswb", { MX
, EM
} },
1012 { "pcmpgtb", { MX
, EM
} },
1013 { "pcmpgtw", { MX
, EM
} },
1014 { "pcmpgtd", { MX
, EM
} },
1015 { "packuswb", { MX
, EM
} },
1017 { "punpckhbw", { MX
, EM
} },
1018 { "punpckhwd", { MX
, EM
} },
1019 { "punpckhdq", { MX
, EM
} },
1020 { "packssdw", { MX
, EM
} },
1023 { "movK", { MX
, Edq
} },
1030 { "pcmpeqb", { MX
, EM
} },
1031 { "pcmpeqw", { MX
, EM
} },
1032 { "pcmpeqd", { MX
, EM
} },
1037 { "(bad)", { XX
} },
1038 { "(bad)", { XX
} },
1044 { "joH", { Jv
, XX
, cond_jump_flag
} },
1045 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1046 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1047 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1048 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1049 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1050 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1051 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1053 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1054 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1055 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1056 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1057 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1058 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1059 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1060 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1063 { "setno", { Eb
} },
1065 { "setae", { Eb
} },
1067 { "setne", { Eb
} },
1068 { "setbe", { Eb
} },
1072 { "setns", { Eb
} },
1074 { "setnp", { Eb
} },
1076 { "setge", { Eb
} },
1077 { "setle", { Eb
} },
1080 { "pushT", { fs
} },
1082 { "cpuid", { XX
} },
1083 { "btS", { Ev
, Gv
} },
1084 { "shldS", { Ev
, Gv
, Ib
} },
1085 { "shldS", { Ev
, Gv
, CL
} },
1089 { "pushT", { gs
} },
1092 { "btsS", { Ev
, Gv
} },
1093 { "shrdS", { Ev
, Gv
, Ib
} },
1094 { "shrdS", { Ev
, Gv
, CL
} },
1096 { "imulS", { Gv
, Ev
} },
1098 { "cmpxchgB", { Eb
, Gb
} },
1099 { "cmpxchgS", { Ev
, Gv
} },
1100 { "lssS", { Gv
, Mp
} },
1101 { "btrS", { Ev
, Gv
} },
1102 { "lfsS", { Gv
, Mp
} },
1103 { "lgsS", { Gv
, Mp
} },
1104 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1105 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1110 { "btcS", { Ev
, Gv
} },
1111 { "bsfS", { Gv
, Ev
} },
1113 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1114 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1116 { "xaddB", { Eb
, Gb
} },
1117 { "xaddS", { Ev
, Gv
} },
1119 { "movntiS", { Ev
, Gv
} },
1120 { "pinsrw", { MX
, Edqw
, Ib
} },
1121 { "pextrw", { Gdq
, MS
, Ib
} },
1122 { "shufpX", { XM
, EXx
, Ib
} },
1125 { "bswap", { RMeAX
} },
1126 { "bswap", { RMeCX
} },
1127 { "bswap", { RMeDX
} },
1128 { "bswap", { RMeBX
} },
1129 { "bswap", { RMeSP
} },
1130 { "bswap", { RMeBP
} },
1131 { "bswap", { RMeSI
} },
1132 { "bswap", { RMeDI
} },
1135 { "psrlw", { MX
, EM
} },
1136 { "psrld", { MX
, EM
} },
1137 { "psrlq", { MX
, EM
} },
1138 { "paddq", { MX
, EM
} },
1139 { "pmullw", { MX
, EM
} },
1141 { "pmovmskb", { Gdq
, MS
} },
1143 { "psubusb", { MX
, EM
} },
1144 { "psubusw", { MX
, EM
} },
1145 { "pminub", { MX
, EM
} },
1146 { "pand", { MX
, EM
} },
1147 { "paddusb", { MX
, EM
} },
1148 { "paddusw", { MX
, EM
} },
1149 { "pmaxub", { MX
, EM
} },
1150 { "pandn", { MX
, EM
} },
1152 { "pavgb", { MX
, EM
} },
1153 { "psraw", { MX
, EM
} },
1154 { "psrad", { MX
, EM
} },
1155 { "pavgw", { MX
, EM
} },
1156 { "pmulhuw", { MX
, EM
} },
1157 { "pmulhw", { MX
, EM
} },
1161 { "psubsb", { MX
, EM
} },
1162 { "psubsw", { MX
, EM
} },
1163 { "pminsw", { MX
, EM
} },
1164 { "por", { MX
, EM
} },
1165 { "paddsb", { MX
, EM
} },
1166 { "paddsw", { MX
, EM
} },
1167 { "pmaxsw", { MX
, EM
} },
1168 { "pxor", { MX
, EM
} },
1171 { "psllw", { MX
, EM
} },
1172 { "pslld", { MX
, EM
} },
1173 { "psllq", { MX
, EM
} },
1174 { "pmuludq", { MX
, EM
} },
1175 { "pmaddwd", { MX
, EM
} },
1176 { "psadbw", { MX
, EM
} },
1179 { "psubb", { MX
, EM
} },
1180 { "psubw", { MX
, EM
} },
1181 { "psubd", { MX
, EM
} },
1182 { "psubq", { MX
, EM
} },
1183 { "paddb", { MX
, EM
} },
1184 { "paddw", { MX
, EM
} },
1185 { "paddd", { MX
, EM
} },
1186 { "(bad)", { XX
} },
1189 static const unsigned char onebyte_has_modrm
[256] = {
1190 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1191 /* ------------------------------- */
1192 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1193 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1194 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1195 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1196 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1197 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1198 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1199 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1200 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1201 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1202 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1203 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1204 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1205 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1206 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1207 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1208 /* ------------------------------- */
1209 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1212 static const unsigned char twobyte_has_modrm
[256] = {
1213 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1214 /* ------------------------------- */
1215 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1216 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1217 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1218 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1219 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1220 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1221 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1222 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1223 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1224 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1225 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1226 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1227 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1228 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1229 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1230 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1231 /* ------------------------------- */
1232 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1235 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1236 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1237 /* ------------------------------- */
1238 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1239 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1240 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1241 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1242 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1243 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1244 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1245 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1246 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1247 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1248 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1249 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1250 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1251 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1252 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1253 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1254 /* ------------------------------- */
1255 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1258 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1259 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1260 /* ------------------------------- */
1261 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1262 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1263 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1264 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1265 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1266 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1267 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1268 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1269 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1270 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1271 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1272 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1273 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1274 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1275 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1276 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1277 /* ------------------------------- */
1278 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1281 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1282 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1283 /* ------------------------------- */
1284 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1285 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1286 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1287 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1288 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1289 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1290 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1291 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1292 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1293 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1294 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1295 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1296 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1297 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1298 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1299 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1300 /* ------------------------------- */
1301 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1304 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1305 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1306 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1307 /* ------------------------------- */
1308 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1309 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1310 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1311 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1312 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1313 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1314 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1315 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1316 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1317 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1318 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1319 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1320 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1321 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1322 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1323 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1324 /* ------------------------------- */
1325 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1328 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1329 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1330 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1331 /* ------------------------------- */
1332 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1333 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1334 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1335 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1336 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1337 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1338 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1339 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1340 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1341 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1342 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1343 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1344 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1345 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1346 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1347 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1348 /* ------------------------------- */
1349 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1352 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1353 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1354 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1355 /* ------------------------------- */
1356 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1357 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1358 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1359 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1360 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1361 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1362 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1363 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1364 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1365 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1366 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1367 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1368 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1369 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1370 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1371 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1372 /* ------------------------------- */
1373 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1376 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1377 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1378 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1379 /* ------------------------------- */
1380 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1381 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1382 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1383 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1384 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1385 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1386 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1387 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1388 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1389 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1390 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1391 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1392 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1393 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1394 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1395 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1396 /* ------------------------------- */
1397 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1400 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1401 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1402 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1403 /* ------------------------------- */
1404 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1405 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1406 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1407 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1408 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1409 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1410 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1411 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1412 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1413 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1414 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1415 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1416 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1417 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1418 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1419 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1420 /* ------------------------------- */
1421 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1424 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1425 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1426 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1427 /* ------------------------------- */
1428 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1429 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1430 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1431 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1432 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1433 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1434 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1435 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1436 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1437 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1438 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1439 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1440 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1441 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1442 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1443 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1444 /* ------------------------------- */
1445 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1448 static char obuf
[100];
1450 static char scratchbuf
[100];
1451 static unsigned char *start_codep
;
1452 static unsigned char *insn_codep
;
1453 static unsigned char *codep
;
1454 static disassemble_info
*the_info
;
1462 static unsigned char need_modrm
;
1464 /* If we are accessing mod/rm/reg without need_modrm set, then the
1465 values are stale. Hitting this abort likely indicates that you
1466 need to update onebyte_has_modrm or twobyte_has_modrm. */
1467 #define MODRM_CHECK if (!need_modrm) abort ()
1469 static const char **names64
;
1470 static const char **names32
;
1471 static const char **names16
;
1472 static const char **names8
;
1473 static const char **names8rex
;
1474 static const char **names_seg
;
1475 static const char **index16
;
1477 static const char *intel_names64
[] = {
1478 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1479 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1481 static const char *intel_names32
[] = {
1482 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1483 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1485 static const char *intel_names16
[] = {
1486 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1487 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1489 static const char *intel_names8
[] = {
1490 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1492 static const char *intel_names8rex
[] = {
1493 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1494 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1496 static const char *intel_names_seg
[] = {
1497 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1499 static const char *intel_index16
[] = {
1500 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1503 static const char *att_names64
[] = {
1504 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1505 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1507 static const char *att_names32
[] = {
1508 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1509 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1511 static const char *att_names16
[] = {
1512 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1513 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1515 static const char *att_names8
[] = {
1516 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1518 static const char *att_names8rex
[] = {
1519 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1520 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1522 static const char *att_names_seg
[] = {
1523 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1525 static const char *att_index16
[] = {
1526 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1529 static const struct dis386 grps
[][8] = {
1532 { "popU", { stackEv
} },
1533 { "(bad)", { XX
} },
1534 { "(bad)", { XX
} },
1535 { "(bad)", { XX
} },
1536 { "(bad)", { XX
} },
1537 { "(bad)", { XX
} },
1538 { "(bad)", { XX
} },
1539 { "(bad)", { XX
} },
1543 { "addA", { Eb
, Ib
} },
1544 { "orA", { Eb
, Ib
} },
1545 { "adcA", { Eb
, Ib
} },
1546 { "sbbA", { Eb
, Ib
} },
1547 { "andA", { Eb
, Ib
} },
1548 { "subA", { Eb
, Ib
} },
1549 { "xorA", { Eb
, Ib
} },
1550 { "cmpA", { Eb
, Ib
} },
1554 { "addQ", { Ev
, Iv
} },
1555 { "orQ", { Ev
, Iv
} },
1556 { "adcQ", { Ev
, Iv
} },
1557 { "sbbQ", { Ev
, Iv
} },
1558 { "andQ", { Ev
, Iv
} },
1559 { "subQ", { Ev
, Iv
} },
1560 { "xorQ", { Ev
, Iv
} },
1561 { "cmpQ", { Ev
, Iv
} },
1565 { "addQ", { Ev
, sIb
} },
1566 { "orQ", { Ev
, sIb
} },
1567 { "adcQ", { Ev
, sIb
} },
1568 { "sbbQ", { Ev
, sIb
} },
1569 { "andQ", { Ev
, sIb
} },
1570 { "subQ", { Ev
, sIb
} },
1571 { "xorQ", { Ev
, sIb
} },
1572 { "cmpQ", { Ev
, sIb
} },
1576 { "rolA", { Eb
, Ib
} },
1577 { "rorA", { Eb
, Ib
} },
1578 { "rclA", { Eb
, Ib
} },
1579 { "rcrA", { Eb
, Ib
} },
1580 { "shlA", { Eb
, Ib
} },
1581 { "shrA", { Eb
, Ib
} },
1582 { "(bad)", { XX
} },
1583 { "sarA", { Eb
, Ib
} },
1587 { "rolQ", { Ev
, Ib
} },
1588 { "rorQ", { Ev
, Ib
} },
1589 { "rclQ", { Ev
, Ib
} },
1590 { "rcrQ", { Ev
, Ib
} },
1591 { "shlQ", { Ev
, Ib
} },
1592 { "shrQ", { Ev
, Ib
} },
1593 { "(bad)", { XX
} },
1594 { "sarQ", { Ev
, Ib
} },
1598 { "rolA", { Eb
, I1
} },
1599 { "rorA", { Eb
, I1
} },
1600 { "rclA", { Eb
, I1
} },
1601 { "rcrA", { Eb
, I1
} },
1602 { "shlA", { Eb
, I1
} },
1603 { "shrA", { Eb
, I1
} },
1604 { "(bad)", { XX
} },
1605 { "sarA", { Eb
, I1
} },
1609 { "rolQ", { Ev
, I1
} },
1610 { "rorQ", { Ev
, I1
} },
1611 { "rclQ", { Ev
, I1
} },
1612 { "rcrQ", { Ev
, I1
} },
1613 { "shlQ", { Ev
, I1
} },
1614 { "shrQ", { Ev
, I1
} },
1615 { "(bad)", { XX
} },
1616 { "sarQ", { Ev
, I1
} },
1620 { "rolA", { Eb
, CL
} },
1621 { "rorA", { Eb
, CL
} },
1622 { "rclA", { Eb
, CL
} },
1623 { "rcrA", { Eb
, CL
} },
1624 { "shlA", { Eb
, CL
} },
1625 { "shrA", { Eb
, CL
} },
1626 { "(bad)", { XX
} },
1627 { "sarA", { Eb
, CL
} },
1631 { "rolQ", { Ev
, CL
} },
1632 { "rorQ", { Ev
, CL
} },
1633 { "rclQ", { Ev
, CL
} },
1634 { "rcrQ", { Ev
, CL
} },
1635 { "shlQ", { Ev
, CL
} },
1636 { "shrQ", { Ev
, CL
} },
1637 { "(bad)", { XX
} },
1638 { "sarQ", { Ev
, CL
} },
1642 { "testA", { Eb
, Ib
} },
1643 { "(bad)", { Eb
} },
1646 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1647 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1648 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1649 { "idivA", { Eb
} }, /* and idiv for consistency. */
1653 { "testQ", { Ev
, Iv
} },
1654 { "(bad)", { XX
} },
1657 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1658 { "imulQ", { Ev
} },
1660 { "idivQ", { Ev
} },
1666 { "(bad)", { XX
} },
1667 { "(bad)", { XX
} },
1668 { "(bad)", { XX
} },
1669 { "(bad)", { XX
} },
1670 { "(bad)", { XX
} },
1671 { "(bad)", { XX
} },
1677 { "callT", { indirEv
} },
1678 { "JcallT", { indirEp
} },
1679 { "jmpT", { indirEv
} },
1680 { "JjmpT", { indirEp
} },
1681 { "pushU", { stackEv
} },
1682 { "(bad)", { XX
} },
1686 { "sldtD", { Sv
} },
1692 { "(bad)", { XX
} },
1693 { "(bad)", { XX
} },
1697 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1698 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1699 { "lgdt{Q|Q||}", { M
} },
1700 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1701 { "smswD", { Sv
} },
1702 { "(bad)", { XX
} },
1704 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1708 { "(bad)", { XX
} },
1709 { "(bad)", { XX
} },
1710 { "(bad)", { XX
} },
1711 { "(bad)", { XX
} },
1712 { "btQ", { Ev
, Ib
} },
1713 { "btsQ", { Ev
, Ib
} },
1714 { "btrQ", { Ev
, Ib
} },
1715 { "btcQ", { Ev
, Ib
} },
1719 { "(bad)", { XX
} },
1720 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1721 { "(bad)", { XX
} },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1724 { "(bad)", { XX
} },
1725 { "", { VM
} }, /* See OP_VMX. */
1726 { "vmptrst", { Mq
} },
1730 { "movA", { Eb
, Ib
} },
1731 { "(bad)", { XX
} },
1732 { "(bad)", { XX
} },
1733 { "(bad)", { XX
} },
1734 { "(bad)", { XX
} },
1735 { "(bad)", { XX
} },
1736 { "(bad)", { XX
} },
1737 { "(bad)", { XX
} },
1741 { "movQ", { Ev
, Iv
} },
1742 { "(bad)", { XX
} },
1743 { "(bad)", { XX
} },
1744 { "(bad)", { XX
} },
1745 { "(bad)", { XX
} },
1746 { "(bad)", { XX
} },
1747 { "(bad)", { XX
} },
1748 { "(bad)", { XX
} },
1752 { "(bad)", { XX
} },
1753 { "(bad)", { XX
} },
1754 { "psrlw", { MS
, Ib
} },
1755 { "(bad)", { XX
} },
1756 { "psraw", { MS
, Ib
} },
1757 { "(bad)", { XX
} },
1758 { "psllw", { MS
, Ib
} },
1759 { "(bad)", { XX
} },
1763 { "(bad)", { XX
} },
1764 { "(bad)", { XX
} },
1765 { "psrld", { MS
, Ib
} },
1766 { "(bad)", { XX
} },
1767 { "psrad", { MS
, Ib
} },
1768 { "(bad)", { XX
} },
1769 { "pslld", { MS
, Ib
} },
1770 { "(bad)", { XX
} },
1774 { "(bad)", { XX
} },
1775 { "(bad)", { XX
} },
1776 { "psrlq", { MS
, Ib
} },
1777 { "psrldq", { MS
, Ib
} },
1778 { "(bad)", { XX
} },
1779 { "(bad)", { XX
} },
1780 { "psllq", { MS
, Ib
} },
1781 { "pslldq", { MS
, Ib
} },
1785 { "fxsave", { Ev
} },
1786 { "fxrstor", { Ev
} },
1787 { "ldmxcsr", { Ev
} },
1788 { "stmxcsr", { Ev
} },
1789 { "(bad)", { XX
} },
1790 { "lfence", { { OP_0fae
, 0 } } },
1791 { "mfence", { { OP_0fae
, 0 } } },
1792 { "clflush", { { OP_0fae
, 0 } } },
1796 { "prefetchnta", { Ev
} },
1797 { "prefetcht0", { Ev
} },
1798 { "prefetcht1", { Ev
} },
1799 { "prefetcht2", { Ev
} },
1800 { "(bad)", { XX
} },
1801 { "(bad)", { XX
} },
1802 { "(bad)", { XX
} },
1803 { "(bad)", { XX
} },
1807 { "prefetch", { Eb
} },
1808 { "prefetchw", { Eb
} },
1809 { "(bad)", { XX
} },
1810 { "(bad)", { XX
} },
1811 { "(bad)", { XX
} },
1812 { "(bad)", { XX
} },
1813 { "(bad)", { XX
} },
1814 { "(bad)", { XX
} },
1818 { "xstore-rng", { { OP_0f07
, 0 } } },
1819 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1820 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1821 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1822 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1823 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1824 { "(bad)", { { OP_0f07
, 0 } } },
1825 { "(bad)", { { OP_0f07
, 0 } } },
1829 { "montmul", { { OP_0f07
, 0 } } },
1830 { "xsha1", { { OP_0f07
, 0 } } },
1831 { "xsha256", { { OP_0f07
, 0 } } },
1832 { "(bad)", { { OP_0f07
, 0 } } },
1833 { "(bad)", { { OP_0f07
, 0 } } },
1834 { "(bad)", { { OP_0f07
, 0 } } },
1835 { "(bad)", { { OP_0f07
, 0 } } },
1836 { "(bad)", { { OP_0f07
, 0 } } },
1840 static const struct dis386 prefix_user_table
[][4] = {
1843 { "addps", { XM
, EXx
} },
1844 { "addss", { XM
, EXd
} },
1845 { "addpd", { XM
, EXx
} },
1846 { "addsd", { XM
, EXq
} },
1850 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1851 { "", { XM
, EXd
, OPSIMD
} },
1852 { "", { XM
, EXx
, OPSIMD
} },
1853 { "", { XM
, EXq
, OPSIMD
} },
1857 { "cvtpi2ps", { XM
, EMCq
} },
1858 { "cvtsi2ssY", { XM
, Ev
} },
1859 { "cvtpi2pd", { XM
, EMCq
} },
1860 { "cvtsi2sdY", { XM
, Ev
} },
1864 { "cvtps2pi", { MXC
, EXq
} },
1865 { "cvtss2siY", { Gv
, EXd
} },
1866 { "cvtpd2pi", { MXC
, EXx
} },
1867 { "cvtsd2siY", { Gv
, EXq
} },
1871 { "cvttps2pi", { MXC
, EXq
} },
1872 { "cvttss2siY", { Gv
, EXd
} },
1873 { "cvttpd2pi", { MXC
, EXx
} },
1874 { "cvttsd2siY", { Gv
, EXq
} },
1878 { "divps", { XM
, EXx
} },
1879 { "divss", { XM
, EXd
} },
1880 { "divpd", { XM
, EXx
} },
1881 { "divsd", { XM
, EXq
} },
1885 { "maxps", { XM
, EXx
} },
1886 { "maxss", { XM
, EXd
} },
1887 { "maxpd", { XM
, EXx
} },
1888 { "maxsd", { XM
, EXq
} },
1892 { "minps", { XM
, EXx
} },
1893 { "minss", { XM
, EXd
} },
1894 { "minpd", { XM
, EXx
} },
1895 { "minsd", { XM
, EXq
} },
1899 { "movups", { XM
, EXx
} },
1900 { "movss", { XM
, EXd
} },
1901 { "movupd", { XM
, EXx
} },
1902 { "movsd", { XM
, EXq
} },
1906 { "movups", { EXx
, XM
} },
1907 { "movss", { EXd
, XM
} },
1908 { "movupd", { EXx
, XM
} },
1909 { "movsd", { EXq
, XM
} },
1913 { "mulps", { XM
, EXx
} },
1914 { "mulss", { XM
, EXd
} },
1915 { "mulpd", { XM
, EXx
} },
1916 { "mulsd", { XM
, EXq
} },
1920 { "rcpps", { XM
, EXx
} },
1921 { "rcpss", { XM
, EXd
} },
1922 { "(bad)", { XM
, EXx
} },
1923 { "(bad)", { XM
, EXx
} },
1927 { "rsqrtps",{ XM
, EXx
} },
1928 { "rsqrtss",{ XM
, EXd
} },
1929 { "(bad)", { XM
, EXx
} },
1930 { "(bad)", { XM
, EXx
} },
1934 { "sqrtps", { XM
, EXx
} },
1935 { "sqrtss", { XM
, EXd
} },
1936 { "sqrtpd", { XM
, EXx
} },
1937 { "sqrtsd", { XM
, EXq
} },
1941 { "subps", { XM
, EXx
} },
1942 { "subss", { XM
, EXd
} },
1943 { "subpd", { XM
, EXx
} },
1944 { "subsd", { XM
, EXq
} },
1948 { "(bad)", { XM
, EXx
} },
1949 { "cvtdq2pd", { XM
, EXq
} },
1950 { "cvttpd2dq", { XM
, EXx
} },
1951 { "cvtpd2dq", { XM
, EXx
} },
1955 { "cvtdq2ps", { XM
, EXx
} },
1956 { "cvttps2dq", { XM
, EXx
} },
1957 { "cvtps2dq", { XM
, EXx
} },
1958 { "(bad)", { XM
, EXx
} },
1962 { "cvtps2pd", { XM
, EXq
} },
1963 { "cvtss2sd", { XM
, EXd
} },
1964 { "cvtpd2ps", { XM
, EXx
} },
1965 { "cvtsd2ss", { XM
, EXq
} },
1969 { "maskmovq", { MX
, MS
} },
1970 { "(bad)", { XM
, EXx
} },
1971 { "maskmovdqu", { XM
, XS
} },
1972 { "(bad)", { XM
, EXx
} },
1976 { "movq", { MX
, EM
} },
1977 { "movdqu", { XM
, EXx
} },
1978 { "movdqa", { XM
, EXx
} },
1979 { "(bad)", { XM
, EXx
} },
1983 { "movq", { EM
, MX
} },
1984 { "movdqu", { EXx
, XM
} },
1985 { "movdqa", { EXx
, XM
} },
1986 { "(bad)", { EXx
, XM
} },
1990 { "(bad)", { EXx
, XM
} },
1991 { "movq2dq",{ XM
, MS
} },
1992 { "movq", { EXq
, XM
} },
1993 { "movdq2q",{ MX
, XS
} },
1997 { "pshufw", { MX
, EM
, Ib
} },
1998 { "pshufhw",{ XM
, EXx
, Ib
} },
1999 { "pshufd", { XM
, EXx
, Ib
} },
2000 { "pshuflw",{ XM
, EXx
, Ib
} },
2004 { "movK", { Edq
, MX
} },
2005 { "movq", { XM
, EXq
} },
2006 { "movK", { Edq
, XM
} },
2007 { "(bad)", { Ed
, XM
} },
2011 { "(bad)", { MX
, EXx
} },
2012 { "(bad)", { XM
, EXx
} },
2013 { "punpckhqdq", { XM
, EXx
} },
2014 { "(bad)", { XM
, EXx
} },
2018 { "movntq", { EM
, MX
} },
2019 { "(bad)", { EM
, XM
} },
2020 { "movntdq",{ EM
, XM
} },
2021 { "(bad)", { EM
, XM
} },
2025 { "(bad)", { MX
, EXx
} },
2026 { "(bad)", { XM
, EXx
} },
2027 { "punpcklqdq", { XM
, EXx
} },
2028 { "(bad)", { XM
, EXx
} },
2032 { "(bad)", { MX
, EXx
} },
2033 { "(bad)", { XM
, EXx
} },
2034 { "addsubpd", { XM
, EXx
} },
2035 { "addsubps", { XM
, EXx
} },
2039 { "(bad)", { MX
, EXx
} },
2040 { "(bad)", { XM
, EXx
} },
2041 { "haddpd", { XM
, EXx
} },
2042 { "haddps", { XM
, EXx
} },
2046 { "(bad)", { MX
, EXx
} },
2047 { "(bad)", { XM
, EXx
} },
2048 { "hsubpd", { XM
, EXx
} },
2049 { "hsubps", { XM
, EXx
} },
2053 { "movlpX", { XM
, EXq
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
2054 { "movsldup", { XM
, EXx
} },
2055 { "movlpd", { XM
, EXq
} },
2056 { "movddup", { XM
, EXq
} },
2060 { "movhpX", { XM
, EXq
, { SIMD_Fixup
, 'l' } } },
2061 { "movshdup", { XM
, EXx
} },
2062 { "movhpd", { XM
, EXq
} },
2063 { "(bad)", { XM
, EXq
} },
2067 { "(bad)", { XM
, EXx
} },
2068 { "(bad)", { XM
, EXx
} },
2069 { "(bad)", { XM
, EXx
} },
2070 { "lddqu", { XM
, M
} },
2074 {"movntps", { Ev
, XM
} },
2075 {"movntss", { Ed
, XM
} },
2076 {"movntpd", { Ev
, XM
} },
2077 {"movntsd", { Eq
, XM
} },
2082 {"vmread", { Em
, Gm
} },
2084 {"extrq", { XS
, Ib
, Ib
} },
2085 {"insertq", { XM
, XS
, Ib
, Ib
} },
2090 {"vmwrite", { Gm
, Em
} },
2092 {"extrq", { XM
, XS
} },
2093 {"insertq", { XM
, XS
} },
2098 { "bsrS", { Gv
, Ev
} },
2099 { "lzcntS", { Gv
, Ev
} },
2100 { "bsrS", { Gv
, Ev
} },
2101 { "(bad)", { XX
} },
2106 { "(bad)", { XX
} },
2107 { "popcntS", { Gv
, Ev
} },
2108 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2114 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2115 { "pause", { XX
} },
2116 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2117 { "(bad)", { XX
} },
2122 { "(bad)", { XX
} },
2123 { "(bad)", { XX
} },
2124 { "pblendvb", {XM
, EXx
, XMM0
} },
2125 { "(bad)", { XX
} },
2130 { "(bad)", { XX
} },
2131 { "(bad)", { XX
} },
2132 { "blendvps", {XM
, EXx
, XMM0
} },
2133 { "(bad)", { XX
} },
2138 { "(bad)", { XX
} },
2139 { "(bad)", { XX
} },
2140 { "blendvpd", { XM
, EXx
, XMM0
} },
2141 { "(bad)", { XX
} },
2146 { "(bad)", { XX
} },
2147 { "(bad)", { XX
} },
2148 { "ptest", { XM
, EXx
} },
2149 { "(bad)", { XX
} },
2154 { "(bad)", { XX
} },
2155 { "(bad)", { XX
} },
2156 { "pmovsxbw", { XM
, EXx
} },
2157 { "(bad)", { XX
} },
2162 { "(bad)", { XX
} },
2163 { "(bad)", { XX
} },
2164 { "pmovsxbd", { XM
, EXx
} },
2165 { "(bad)", { XX
} },
2170 { "(bad)", { XX
} },
2171 { "(bad)", { XX
} },
2172 { "pmovsxbq", { XM
, EXx
} },
2173 { "(bad)", { XX
} },
2178 { "(bad)", { XX
} },
2179 { "(bad)", { XX
} },
2180 { "pmovsxwd", { XM
, EXx
} },
2181 { "(bad)", { XX
} },
2186 { "(bad)", { XX
} },
2187 { "(bad)", { XX
} },
2188 { "pmovsxwq", { XM
, EXx
} },
2189 { "(bad)", { XX
} },
2194 { "(bad)", { XX
} },
2195 { "(bad)", { XX
} },
2196 { "pmovsxdq", { XM
, EXx
} },
2197 { "(bad)", { XX
} },
2202 { "(bad)", { XX
} },
2203 { "(bad)", { XX
} },
2204 { "pmuldq", { XM
, EXx
} },
2205 { "(bad)", { XX
} },
2210 { "(bad)", { XX
} },
2211 { "(bad)", { XX
} },
2212 { "pcmpeqq", { XM
, EXx
} },
2213 { "(bad)", { XX
} },
2218 { "(bad)", { XX
} },
2219 { "(bad)", { XX
} },
2220 { "movntdqa", { XM
, EM
} },
2221 { "(bad)", { XX
} },
2226 { "(bad)", { XX
} },
2227 { "(bad)", { XX
} },
2228 { "packusdw", { XM
, EXx
} },
2229 { "(bad)", { XX
} },
2234 { "(bad)", { XX
} },
2235 { "(bad)", { XX
} },
2236 { "pmovzxbw", { XM
, EXx
} },
2237 { "(bad)", { XX
} },
2242 { "(bad)", { XX
} },
2243 { "(bad)", { XX
} },
2244 { "pmovzxbd", { XM
, EXx
} },
2245 { "(bad)", { XX
} },
2250 { "(bad)", { XX
} },
2251 { "(bad)", { XX
} },
2252 { "pmovzxbq", { XM
, EXx
} },
2253 { "(bad)", { XX
} },
2258 { "(bad)", { XX
} },
2259 { "(bad)", { XX
} },
2260 { "pmovzxwd", { XM
, EXx
} },
2261 { "(bad)", { XX
} },
2266 { "(bad)", { XX
} },
2267 { "(bad)", { XX
} },
2268 { "pmovzxwq", { XM
, EXx
} },
2269 { "(bad)", { XX
} },
2274 { "(bad)", { XX
} },
2275 { "(bad)", { XX
} },
2276 { "pmovzxdq", { XM
, EXx
} },
2277 { "(bad)", { XX
} },
2282 { "(bad)", { XX
} },
2283 { "(bad)", { XX
} },
2284 { "pminsb", { XM
, EXx
} },
2285 { "(bad)", { XX
} },
2290 { "(bad)", { XX
} },
2291 { "(bad)", { XX
} },
2292 { "pminsd", { XM
, EXx
} },
2293 { "(bad)", { XX
} },
2298 { "(bad)", { XX
} },
2299 { "(bad)", { XX
} },
2300 { "pminuw", { XM
, EXx
} },
2301 { "(bad)", { XX
} },
2306 { "(bad)", { XX
} },
2307 { "(bad)", { XX
} },
2308 { "pminud", { XM
, EXx
} },
2309 { "(bad)", { XX
} },
2314 { "(bad)", { XX
} },
2315 { "(bad)", { XX
} },
2316 { "pmaxsb", { XM
, EXx
} },
2317 { "(bad)", { XX
} },
2322 { "(bad)", { XX
} },
2323 { "(bad)", { XX
} },
2324 { "pmaxsd", { XM
, EXx
} },
2325 { "(bad)", { XX
} },
2330 { "(bad)", { XX
} },
2331 { "(bad)", { XX
} },
2332 { "pmaxuw", { XM
, EXx
} },
2333 { "(bad)", { XX
} },
2338 { "(bad)", { XX
} },
2339 { "(bad)", { XX
} },
2340 { "pmaxud", { XM
, EXx
} },
2341 { "(bad)", { XX
} },
2346 { "(bad)", { XX
} },
2347 { "(bad)", { XX
} },
2348 { "pmulld", { XM
, EXx
} },
2349 { "(bad)", { XX
} },
2354 { "(bad)", { XX
} },
2355 { "(bad)", { XX
} },
2356 { "phminposuw", { XM
, EXx
} },
2357 { "(bad)", { XX
} },
2362 { "(bad)", { XX
} },
2363 { "(bad)", { XX
} },
2364 { "roundps", { XM
, EXx
, Ib
} },
2365 { "(bad)", { XX
} },
2370 { "(bad)", { XX
} },
2371 { "(bad)", { XX
} },
2372 { "roundpd", { XM
, EXx
, Ib
} },
2373 { "(bad)", { XX
} },
2378 { "(bad)", { XX
} },
2379 { "(bad)", { XX
} },
2380 { "roundss", { XM
, EXd
, Ib
} },
2381 { "(bad)", { XX
} },
2386 { "(bad)", { XX
} },
2387 { "(bad)", { XX
} },
2388 { "roundsd", { XM
, EXq
, Ib
} },
2389 { "(bad)", { XX
} },
2394 { "(bad)", { XX
} },
2395 { "(bad)", { XX
} },
2396 { "blendps", { XM
, EXx
, Ib
} },
2397 { "(bad)", { XX
} },
2402 { "(bad)", { XX
} },
2403 { "(bad)", { XX
} },
2404 { "blendpd", { XM
, EXx
, Ib
} },
2405 { "(bad)", { XX
} },
2410 { "(bad)", { XX
} },
2411 { "(bad)", { XX
} },
2412 { "pblendw", { XM
, EXx
, Ib
} },
2413 { "(bad)", { XX
} },
2418 { "(bad)", { XX
} },
2419 { "(bad)", { XX
} },
2420 { "pextrb", { Edqb
, XM
, Ib
} },
2421 { "(bad)", { XX
} },
2426 { "(bad)", { XX
} },
2427 { "(bad)", { XX
} },
2428 { "pextrw", { Edqw
, XM
, Ib
} },
2429 { "(bad)", { XX
} },
2434 { "(bad)", { XX
} },
2435 { "(bad)", { XX
} },
2436 { "pextrK", { Edq
, XM
, Ib
} },
2437 { "(bad)", { XX
} },
2442 { "(bad)", { XX
} },
2443 { "(bad)", { XX
} },
2444 { "extractps", { Edqd
, XM
, Ib
} },
2445 { "(bad)", { XX
} },
2450 { "(bad)", { XX
} },
2451 { "(bad)", { XX
} },
2452 { "pinsrb", { XM
, Edqb
, Ib
} },
2453 { "(bad)", { XX
} },
2458 { "(bad)", { XX
} },
2459 { "(bad)", { XX
} },
2460 { "insertps", { XM
, EXx
, Ib
} },
2461 { "(bad)", { XX
} },
2466 { "(bad)", { XX
} },
2467 { "(bad)", { XX
} },
2468 { "pinsrK", { XM
, Edq
, Ib
} },
2469 { "(bad)", { XX
} },
2474 { "(bad)", { XX
} },
2475 { "(bad)", { XX
} },
2476 { "dpps", { XM
, EXx
, Ib
} },
2477 { "(bad)", { XX
} },
2482 { "(bad)", { XX
} },
2483 { "(bad)", { XX
} },
2484 { "dppd", { XM
, EXx
, Ib
} },
2485 { "(bad)", { XX
} },
2490 { "(bad)", { XX
} },
2491 { "(bad)", { XX
} },
2492 { "mpsadbw", { XM
, EXx
, Ib
} },
2493 { "(bad)", { XX
} },
2498 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2500 { "pcmpgtq", { XM
, EXx
} },
2501 { "(bad)", { XX
} },
2506 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "(bad)", { XX
} },
2509 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2514 { "(bad)", { XX
} },
2515 { "(bad)", { XX
} },
2516 { "(bad)", { XX
} },
2517 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2522 { "(bad)", { XX
} },
2523 { "(bad)", { XX
} },
2524 { "pcmpestrm", { XM
, EXx
, Ib
} },
2525 { "(bad)", { XX
} },
2530 { "(bad)", { XX
} },
2531 { "(bad)", { XX
} },
2532 { "pcmpestri", { XM
, EXx
, Ib
} },
2533 { "(bad)", { XX
} },
2538 { "(bad)", { XX
} },
2539 { "(bad)", { XX
} },
2540 { "pcmpistrm", { XM
, EXx
, Ib
} },
2541 { "(bad)", { XX
} },
2546 { "(bad)", { XX
} },
2547 { "(bad)", { XX
} },
2548 { "pcmpistri", { XM
, EXx
, Ib
} },
2549 { "(bad)", { XX
} },
2554 { "ucomiss",{ XM
, EXd
} },
2555 { "(bad)", { XX
} },
2556 { "ucomisd",{ XM
, EXq
} },
2557 { "(bad)", { XX
} },
2562 { "comiss", { XM
, EXd
} },
2563 { "(bad)", { XX
} },
2564 { "comisd", { XM
, EXq
} },
2565 { "(bad)", { XX
} },
2570 { "punpcklbw",{ MX
, EMd
} },
2571 { "(bad)", { XX
} },
2572 { "punpcklbw",{ MX
, EMx
} },
2573 { "(bad)", { XX
} },
2578 { "punpcklwd",{ MX
, EMd
} },
2579 { "(bad)", { XX
} },
2580 { "punpcklwd",{ MX
, EMx
} },
2581 { "(bad)", { XX
} },
2586 { "punpckldq",{ MX
, EMd
} },
2587 { "(bad)", { XX
} },
2588 { "punpckldq",{ MX
, EMx
} },
2589 { "(bad)", { XX
} },
2593 static const struct dis386 x86_64_table
[][2] = {
2595 { "pusha{P|}", { XX
} },
2596 { "(bad)", { XX
} },
2599 { "popa{P|}", { XX
} },
2600 { "(bad)", { XX
} },
2603 { "bound{S|}", { Gv
, Ma
} },
2604 { "(bad)", { XX
} },
2607 { "arpl", { Ew
, Gw
} },
2608 { "movs{||lq|xd}", { Gv
, Ed
} },
2612 static const struct dis386 three_byte_table
[][256] = {
2616 { "pshufb", { MX
, EM
} },
2617 { "phaddw", { MX
, EM
} },
2618 { "phaddd", { MX
, EM
} },
2619 { "phaddsw", { MX
, EM
} },
2620 { "pmaddubsw", { MX
, EM
} },
2621 { "phsubw", { MX
, EM
} },
2622 { "phsubd", { MX
, EM
} },
2623 { "phsubsw", { MX
, EM
} },
2625 { "psignb", { MX
, EM
} },
2626 { "psignw", { MX
, EM
} },
2627 { "psignd", { MX
, EM
} },
2628 { "pmulhrsw", { MX
, EM
} },
2629 { "(bad)", { XX
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2632 { "(bad)", { XX
} },
2635 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2637 { "(bad)", { XX
} },
2640 { "(bad)", { XX
} },
2643 { "(bad)", { XX
} },
2644 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "(bad)", { XX
} },
2647 { "pabsb", { MX
, EM
} },
2648 { "pabsw", { MX
, EM
} },
2649 { "pabsd", { MX
, EM
} },
2650 { "(bad)", { XX
} },
2658 { "(bad)", { XX
} },
2659 { "(bad)", { XX
} },
2665 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2676 { "(bad)", { XX
} },
2690 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2695 { "(bad)", { XX
} },
2697 { "(bad)", { XX
} },
2698 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2704 { "(bad)", { XX
} },
2706 { "(bad)", { XX
} },
2707 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2713 { "(bad)", { XX
} },
2715 { "(bad)", { XX
} },
2716 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2722 { "(bad)", { XX
} },
2724 { "(bad)", { XX
} },
2725 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2733 { "(bad)", { XX
} },
2734 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2742 { "(bad)", { XX
} },
2743 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "(bad)", { XX
} },
2751 { "(bad)", { XX
} },
2752 { "(bad)", { XX
} },
2753 { "(bad)", { XX
} },
2754 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2758 { "(bad)", { XX
} },
2760 { "(bad)", { XX
} },
2761 { "(bad)", { XX
} },
2762 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2767 { "(bad)", { XX
} },
2769 { "(bad)", { XX
} },
2770 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2776 { "(bad)", { XX
} },
2778 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "(bad)", { XX
} },
2782 { "(bad)", { XX
} },
2783 { "(bad)", { XX
} },
2784 { "(bad)", { XX
} },
2785 { "(bad)", { XX
} },
2787 { "(bad)", { XX
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2790 { "(bad)", { XX
} },
2791 { "(bad)", { XX
} },
2792 { "(bad)", { XX
} },
2793 { "(bad)", { XX
} },
2794 { "(bad)", { XX
} },
2796 { "(bad)", { XX
} },
2797 { "(bad)", { XX
} },
2798 { "(bad)", { XX
} },
2799 { "(bad)", { XX
} },
2800 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2803 { "(bad)", { XX
} },
2805 { "(bad)", { XX
} },
2806 { "(bad)", { XX
} },
2807 { "(bad)", { XX
} },
2808 { "(bad)", { XX
} },
2809 { "(bad)", { XX
} },
2810 { "(bad)", { XX
} },
2811 { "(bad)", { XX
} },
2812 { "(bad)", { XX
} },
2814 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2817 { "(bad)", { XX
} },
2818 { "(bad)", { XX
} },
2819 { "(bad)", { XX
} },
2820 { "(bad)", { XX
} },
2821 { "(bad)", { XX
} },
2823 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2826 { "(bad)", { XX
} },
2827 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2830 { "(bad)", { XX
} },
2832 { "(bad)", { XX
} },
2833 { "(bad)", { XX
} },
2834 { "(bad)", { XX
} },
2835 { "(bad)", { XX
} },
2836 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2839 { "(bad)", { XX
} },
2841 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2844 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2848 { "(bad)", { XX
} },
2850 { "(bad)", { XX
} },
2851 { "(bad)", { XX
} },
2852 { "(bad)", { XX
} },
2853 { "(bad)", { XX
} },
2854 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2857 { "(bad)", { XX
} },
2859 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2862 { "(bad)", { XX
} },
2863 { "(bad)", { XX
} },
2864 { "(bad)", { XX
} },
2865 { "(bad)", { XX
} },
2866 { "(bad)", { XX
} },
2868 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2870 { "(bad)", { XX
} },
2871 { "(bad)", { XX
} },
2872 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2877 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2879 { "(bad)", { XX
} },
2880 { "(bad)", { XX
} },
2881 { "(bad)", { XX
} },
2882 { "(bad)", { XX
} },
2883 { "(bad)", { XX
} },
2884 { "(bad)", { XX
} },
2888 { "(bad)", { XX
} },
2889 { "(bad)", { XX
} },
2890 { "(bad)", { XX
} },
2891 { "(bad)", { XX
} },
2892 { "(bad)", { XX
} },
2893 { "(bad)", { XX
} },
2895 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2898 { "(bad)", { XX
} },
2899 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2907 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2923 { "palignr", { MX
, EM
, Ib
} },
2925 { "(bad)", { XX
} },
2926 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2928 { "(bad)", { XX
} },
2934 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2952 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2961 { "(bad)", { XX
} },
2962 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2970 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2988 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2997 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3006 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3024 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3033 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3042 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3051 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3060 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3067 { "(bad)", { XX
} },
3069 { "(bad)", { XX
} },
3070 { "(bad)", { XX
} },
3071 { "(bad)", { XX
} },
3072 { "(bad)", { XX
} },
3073 { "(bad)", { XX
} },
3074 { "(bad)", { XX
} },
3075 { "(bad)", { XX
} },
3076 { "(bad)", { XX
} },
3078 { "(bad)", { XX
} },
3079 { "(bad)", { XX
} },
3080 { "(bad)", { XX
} },
3081 { "(bad)", { XX
} },
3082 { "(bad)", { XX
} },
3083 { "(bad)", { XX
} },
3084 { "(bad)", { XX
} },
3085 { "(bad)", { XX
} },
3087 { "(bad)", { XX
} },
3088 { "(bad)", { XX
} },
3089 { "(bad)", { XX
} },
3090 { "(bad)", { XX
} },
3091 { "(bad)", { XX
} },
3092 { "(bad)", { XX
} },
3093 { "(bad)", { XX
} },
3094 { "(bad)", { XX
} },
3096 { "(bad)", { XX
} },
3097 { "(bad)", { XX
} },
3098 { "(bad)", { XX
} },
3099 { "(bad)", { XX
} },
3100 { "(bad)", { XX
} },
3101 { "(bad)", { XX
} },
3102 { "(bad)", { XX
} },
3103 { "(bad)", { XX
} },
3105 { "(bad)", { XX
} },
3106 { "(bad)", { XX
} },
3107 { "(bad)", { XX
} },
3108 { "(bad)", { XX
} },
3109 { "(bad)", { XX
} },
3110 { "(bad)", { XX
} },
3111 { "(bad)", { XX
} },
3112 { "(bad)", { XX
} },
3114 { "(bad)", { XX
} },
3115 { "(bad)", { XX
} },
3116 { "(bad)", { XX
} },
3117 { "(bad)", { XX
} },
3118 { "(bad)", { XX
} },
3119 { "(bad)", { XX
} },
3120 { "(bad)", { XX
} },
3121 { "(bad)", { XX
} },
3123 { "(bad)", { XX
} },
3124 { "(bad)", { XX
} },
3125 { "(bad)", { XX
} },
3126 { "(bad)", { XX
} },
3127 { "(bad)", { XX
} },
3128 { "(bad)", { XX
} },
3129 { "(bad)", { XX
} },
3130 { "(bad)", { XX
} },
3132 { "(bad)", { XX
} },
3133 { "(bad)", { XX
} },
3134 { "(bad)", { XX
} },
3135 { "(bad)", { XX
} },
3136 { "(bad)", { XX
} },
3137 { "(bad)", { XX
} },
3138 { "(bad)", { XX
} },
3139 { "(bad)", { XX
} },
3141 { "(bad)", { XX
} },
3142 { "(bad)", { XX
} },
3143 { "(bad)", { XX
} },
3144 { "(bad)", { XX
} },
3145 { "(bad)", { XX
} },
3146 { "(bad)", { XX
} },
3147 { "(bad)", { XX
} },
3148 { "(bad)", { XX
} },
3150 { "(bad)", { XX
} },
3151 { "(bad)", { XX
} },
3152 { "(bad)", { XX
} },
3153 { "(bad)", { XX
} },
3154 { "(bad)", { XX
} },
3155 { "(bad)", { XX
} },
3156 { "(bad)", { XX
} },
3157 { "(bad)", { XX
} },
3159 { "(bad)", { XX
} },
3160 { "(bad)", { XX
} },
3161 { "(bad)", { XX
} },
3162 { "(bad)", { XX
} },
3163 { "(bad)", { XX
} },
3164 { "(bad)", { XX
} },
3165 { "(bad)", { XX
} },
3166 { "(bad)", { XX
} },
3168 { "(bad)", { XX
} },
3169 { "(bad)", { XX
} },
3170 { "(bad)", { XX
} },
3171 { "(bad)", { XX
} },
3172 { "(bad)", { XX
} },
3173 { "(bad)", { XX
} },
3174 { "(bad)", { XX
} },
3175 { "(bad)", { XX
} },
3177 { "(bad)", { XX
} },
3178 { "(bad)", { XX
} },
3179 { "(bad)", { XX
} },
3180 { "(bad)", { XX
} },
3181 { "(bad)", { XX
} },
3182 { "(bad)", { XX
} },
3183 { "(bad)", { XX
} },
3184 { "(bad)", { XX
} },
3186 { "(bad)", { XX
} },
3187 { "(bad)", { XX
} },
3188 { "(bad)", { XX
} },
3189 { "(bad)", { XX
} },
3190 { "(bad)", { XX
} },
3191 { "(bad)", { XX
} },
3192 { "(bad)", { XX
} },
3193 { "(bad)", { XX
} },
3197 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3209 FETCH_DATA (the_info
, codep
+ 1);
3213 /* REX prefixes family. */
3230 if (address_mode
== mode_64bit
)
3236 prefixes
|= PREFIX_REPZ
;
3239 prefixes
|= PREFIX_REPNZ
;
3242 prefixes
|= PREFIX_LOCK
;
3245 prefixes
|= PREFIX_CS
;
3248 prefixes
|= PREFIX_SS
;
3251 prefixes
|= PREFIX_DS
;
3254 prefixes
|= PREFIX_ES
;
3257 prefixes
|= PREFIX_FS
;
3260 prefixes
|= PREFIX_GS
;
3263 prefixes
|= PREFIX_DATA
;
3266 prefixes
|= PREFIX_ADDR
;
3269 /* fwait is really an instruction. If there are prefixes
3270 before the fwait, they belong to the fwait, *not* to the
3271 following instruction. */
3272 if (prefixes
|| rex
)
3274 prefixes
|= PREFIX_FWAIT
;
3278 prefixes
= PREFIX_FWAIT
;
3283 /* Rex is ignored when followed by another prefix. */
3294 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3298 prefix_name (int pref
, int sizeflag
)
3300 static const char *rexes
[16] =
3305 "rex.XB", /* 0x43 */
3307 "rex.RB", /* 0x45 */
3308 "rex.RX", /* 0x46 */
3309 "rex.RXB", /* 0x47 */
3311 "rex.WB", /* 0x49 */
3312 "rex.WX", /* 0x4a */
3313 "rex.WXB", /* 0x4b */
3314 "rex.WR", /* 0x4c */
3315 "rex.WRB", /* 0x4d */
3316 "rex.WRX", /* 0x4e */
3317 "rex.WRXB", /* 0x4f */
3322 /* REX prefixes family. */
3339 return rexes
[pref
- 0x40];
3359 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3361 if (address_mode
== mode_64bit
)
3362 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3364 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3372 static char op_out
[MAX_OPERANDS
][100];
3373 static int op_ad
, op_index
[MAX_OPERANDS
];
3374 static int two_source_ops
;
3375 static bfd_vma op_address
[MAX_OPERANDS
];
3376 static bfd_vma op_riprel
[MAX_OPERANDS
];
3377 static bfd_vma start_pc
;
3380 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3381 * (see topic "Redundant prefixes" in the "Differences from 8086"
3382 * section of the "Virtual 8086 Mode" chapter.)
3383 * 'pc' should be the address of this instruction, it will
3384 * be used to print the target address if this is a relative jump or call
3385 * The function returns the length of this instruction in bytes.
3388 static char intel_syntax
;
3389 static char open_char
;
3390 static char close_char
;
3391 static char separator_char
;
3392 static char scale_char
;
3394 /* Here for backwards compatibility. When gdb stops using
3395 print_insn_i386_att and print_insn_i386_intel these functions can
3396 disappear, and print_insn_i386 be merged into print_insn. */
3398 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3402 return print_insn (pc
, info
);
3406 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3410 return print_insn (pc
, info
);
3414 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3418 return print_insn (pc
, info
);
3422 print_i386_disassembler_options (FILE *stream
)
3424 fprintf (stream
, _("\n\
3425 The following i386/x86-64 specific disassembler options are supported for use\n\
3426 with the -M switch (multiple options should be separated by commas):\n"));
3428 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3429 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3430 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3431 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3432 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3433 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3434 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3435 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3436 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3437 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3438 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3442 print_insn (bfd_vma pc
, disassemble_info
*info
)
3444 const struct dis386
*dp
;
3446 char *op_txt
[MAX_OPERANDS
];
3448 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
3449 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
3452 struct dis_private priv
;
3455 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3456 || info
->mach
== bfd_mach_x86_64
)
3457 address_mode
= mode_64bit
;
3459 address_mode
= mode_32bit
;
3461 if (intel_syntax
== (char) -1)
3462 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3463 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3465 if (info
->mach
== bfd_mach_i386_i386
3466 || info
->mach
== bfd_mach_x86_64
3467 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3468 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3469 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3470 else if (info
->mach
== bfd_mach_i386_i8086
)
3471 priv
.orig_sizeflag
= 0;
3475 for (p
= info
->disassembler_options
; p
!= NULL
; )
3477 if (CONST_STRNEQ (p
, "x86-64"))
3479 address_mode
= mode_64bit
;
3480 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3482 else if (CONST_STRNEQ (p
, "i386"))
3484 address_mode
= mode_32bit
;
3485 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3487 else if (CONST_STRNEQ (p
, "i8086"))
3489 address_mode
= mode_16bit
;
3490 priv
.orig_sizeflag
= 0;
3492 else if (CONST_STRNEQ (p
, "intel"))
3496 else if (CONST_STRNEQ (p
, "att"))
3500 else if (CONST_STRNEQ (p
, "addr"))
3502 if (address_mode
== mode_64bit
)
3504 if (p
[4] == '3' && p
[5] == '2')
3505 priv
.orig_sizeflag
&= ~AFLAG
;
3506 else if (p
[4] == '6' && p
[5] == '4')
3507 priv
.orig_sizeflag
|= AFLAG
;
3511 if (p
[4] == '1' && p
[5] == '6')
3512 priv
.orig_sizeflag
&= ~AFLAG
;
3513 else if (p
[4] == '3' && p
[5] == '2')
3514 priv
.orig_sizeflag
|= AFLAG
;
3517 else if (CONST_STRNEQ (p
, "data"))
3519 if (p
[4] == '1' && p
[5] == '6')
3520 priv
.orig_sizeflag
&= ~DFLAG
;
3521 else if (p
[4] == '3' && p
[5] == '2')
3522 priv
.orig_sizeflag
|= DFLAG
;
3524 else if (CONST_STRNEQ (p
, "suffix"))
3525 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3527 p
= strchr (p
, ',');
3534 names64
= intel_names64
;
3535 names32
= intel_names32
;
3536 names16
= intel_names16
;
3537 names8
= intel_names8
;
3538 names8rex
= intel_names8rex
;
3539 names_seg
= intel_names_seg
;
3540 index16
= intel_index16
;
3543 separator_char
= '+';
3548 names64
= att_names64
;
3549 names32
= att_names32
;
3550 names16
= att_names16
;
3551 names8
= att_names8
;
3552 names8rex
= att_names8rex
;
3553 names_seg
= att_names_seg
;
3554 index16
= att_index16
;
3557 separator_char
= ',';
3561 /* The output looks better if we put 7 bytes on a line, since that
3562 puts most long word instructions on a single line. */
3563 info
->bytes_per_line
= 7;
3565 info
->private_data
= &priv
;
3566 priv
.max_fetched
= priv
.the_buffer
;
3567 priv
.insn_start
= pc
;
3570 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3578 start_codep
= priv
.the_buffer
;
3579 codep
= priv
.the_buffer
;
3581 if (setjmp (priv
.bailout
) != 0)
3585 /* Getting here means we tried for data but didn't get it. That
3586 means we have an incomplete instruction of some sort. Just
3587 print the first byte as a prefix or a .byte pseudo-op. */
3588 if (codep
> priv
.the_buffer
)
3590 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3592 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3595 /* Just print the first byte as a .byte instruction. */
3596 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3597 (unsigned int) priv
.the_buffer
[0]);
3610 sizeflag
= priv
.orig_sizeflag
;
3612 FETCH_DATA (info
, codep
+ 1);
3613 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3615 if (((prefixes
& PREFIX_FWAIT
)
3616 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3617 || (rex
&& rex_used
))
3621 /* fwait not followed by floating point instruction, or rex followed
3622 by other prefixes. Print the first prefix. */
3623 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3625 name
= INTERNAL_DISASSEMBLER_ERROR
;
3626 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3633 unsigned char threebyte
;
3634 FETCH_DATA (info
, codep
+ 2);
3635 threebyte
= *++codep
;
3636 dp
= &dis386_twobyte
[threebyte
];
3637 need_modrm
= twobyte_has_modrm
[*codep
];
3638 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3639 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3640 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3641 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3643 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3645 FETCH_DATA (info
, codep
+ 2);
3650 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3651 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3652 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3655 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3656 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3657 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3666 dp
= &dis386
[*codep
];
3667 need_modrm
= onebyte_has_modrm
[*codep
];
3668 uses_DATA_prefix
= 0;
3669 uses_REPNZ_prefix
= 0;
3670 /* pause is 0xf3 0x90. */
3671 uses_REPZ_prefix
= *codep
== 0x90;
3672 uses_LOCK_prefix
= 0;
3676 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3679 used_prefixes
|= PREFIX_REPZ
;
3681 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3684 used_prefixes
|= PREFIX_REPNZ
;
3687 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3690 used_prefixes
|= PREFIX_LOCK
;
3693 if (prefixes
& PREFIX_ADDR
)
3696 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3698 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3699 oappend ("addr32 ");
3701 oappend ("addr16 ");
3702 used_prefixes
|= PREFIX_ADDR
;
3706 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3709 if (dp
->op
[2].bytemode
== cond_jump_mode
3710 && dp
->op
[0].bytemode
== v_mode
3713 if (sizeflag
& DFLAG
)
3714 oappend ("data32 ");
3716 oappend ("data16 ");
3717 used_prefixes
|= PREFIX_DATA
;
3721 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3723 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3724 modrm
.mod
= (*codep
>> 6) & 3;
3725 modrm
.reg
= (*codep
>> 3) & 7;
3726 modrm
.rm
= *codep
& 7;
3728 else if (need_modrm
)
3730 FETCH_DATA (info
, codep
+ 1);
3731 modrm
.mod
= (*codep
>> 6) & 3;
3732 modrm
.reg
= (*codep
>> 3) & 7;
3733 modrm
.rm
= *codep
& 7;
3736 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3743 if (dp
->name
== NULL
)
3745 switch (dp
->op
[0].bytemode
)
3748 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3751 case USE_PREFIX_USER_TABLE
:
3753 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3754 if (prefixes
& PREFIX_REPZ
)
3758 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3759 before PREFIX_DATA. */
3760 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3761 if (prefixes
& PREFIX_REPNZ
)
3765 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3766 if (prefixes
& PREFIX_DATA
)
3770 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3773 case X86_64_SPECIAL
:
3774 index
= address_mode
== mode_64bit
? 1 : 0;
3775 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3779 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3784 if (putop (dp
->name
, sizeflag
) == 0)
3786 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3789 op_ad
= MAX_OPERANDS
- 1 - i
;
3791 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3796 /* See if any prefixes were not used. If so, print the first one
3797 separately. If we don't do this, we'll wind up printing an
3798 instruction stream which does not precisely correspond to the
3799 bytes we are disassembling. */
3800 if ((prefixes
& ~used_prefixes
) != 0)
3804 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3806 name
= INTERNAL_DISASSEMBLER_ERROR
;
3807 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3810 if (rex
& ~rex_used
)
3813 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3815 name
= INTERNAL_DISASSEMBLER_ERROR
;
3816 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3819 obufp
= obuf
+ strlen (obuf
);
3820 for (i
= strlen (obuf
); i
< 6; i
++)
3823 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3825 /* The enter and bound instructions are printed with operands in the same
3826 order as the intel book; everything else is printed in reverse order. */
3827 if (intel_syntax
|| two_source_ops
)
3831 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3832 op_txt
[i
] = op_out
[i
];
3834 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3836 op_ad
= op_index
[i
];
3837 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3838 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3839 riprel
= op_riprel
[i
];
3840 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
3841 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
3846 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3847 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3851 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3855 (*info
->fprintf_func
) (info
->stream
, ",");
3856 if (op_index
[i
] != -1 && !op_riprel
[i
])
3857 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3859 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3863 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3864 if (op_index
[i
] != -1 && op_riprel
[i
])
3866 (*info
->fprintf_func
) (info
->stream
, " # ");
3867 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3868 + op_address
[op_index
[i
]]), info
);
3871 return codep
- priv
.the_buffer
;
3874 static const char *float_mem
[] = {
3949 static const unsigned char float_mem_mode
[] = {
4024 #define ST { OP_ST, 0 }
4025 #define STi { OP_STi, 0 }
4027 #define FGRPd9_2 NULL, { { NULL, 0 } }
4028 #define FGRPd9_4 NULL, { { NULL, 1 } }
4029 #define FGRPd9_5 NULL, { { NULL, 2 } }
4030 #define FGRPd9_6 NULL, { { NULL, 3 } }
4031 #define FGRPd9_7 NULL, { { NULL, 4 } }
4032 #define FGRPda_5 NULL, { { NULL, 5 } }
4033 #define FGRPdb_4 NULL, { { NULL, 6 } }
4034 #define FGRPde_3 NULL, { { NULL, 7 } }
4035 #define FGRPdf_4 NULL, { { NULL, 8 } }
4037 static const struct dis386 float_reg
[][8] = {
4040 { "fadd", { ST
, STi
} },
4041 { "fmul", { ST
, STi
} },
4042 { "fcom", { STi
} },
4043 { "fcomp", { STi
} },
4044 { "fsub", { ST
, STi
} },
4045 { "fsubr", { ST
, STi
} },
4046 { "fdiv", { ST
, STi
} },
4047 { "fdivr", { ST
, STi
} },
4052 { "fxch", { STi
} },
4054 { "(bad)", { XX
} },
4062 { "fcmovb", { ST
, STi
} },
4063 { "fcmove", { ST
, STi
} },
4064 { "fcmovbe",{ ST
, STi
} },
4065 { "fcmovu", { ST
, STi
} },
4066 { "(bad)", { XX
} },
4068 { "(bad)", { XX
} },
4069 { "(bad)", { XX
} },
4073 { "fcmovnb",{ ST
, STi
} },
4074 { "fcmovne",{ ST
, STi
} },
4075 { "fcmovnbe",{ ST
, STi
} },
4076 { "fcmovnu",{ ST
, STi
} },
4078 { "fucomi", { ST
, STi
} },
4079 { "fcomi", { ST
, STi
} },
4080 { "(bad)", { XX
} },
4084 { "fadd", { STi
, ST
} },
4085 { "fmul", { STi
, ST
} },
4086 { "(bad)", { XX
} },
4087 { "(bad)", { XX
} },
4089 { "fsub", { STi
, ST
} },
4090 { "fsubr", { STi
, ST
} },
4091 { "fdiv", { STi
, ST
} },
4092 { "fdivr", { STi
, ST
} },
4094 { "fsubr", { STi
, ST
} },
4095 { "fsub", { STi
, ST
} },
4096 { "fdivr", { STi
, ST
} },
4097 { "fdiv", { STi
, ST
} },
4102 { "ffree", { STi
} },
4103 { "(bad)", { XX
} },
4105 { "fstp", { STi
} },
4106 { "fucom", { STi
} },
4107 { "fucomp", { STi
} },
4108 { "(bad)", { XX
} },
4109 { "(bad)", { XX
} },
4113 { "faddp", { STi
, ST
} },
4114 { "fmulp", { STi
, ST
} },
4115 { "(bad)", { XX
} },
4118 { "fsubp", { STi
, ST
} },
4119 { "fsubrp", { STi
, ST
} },
4120 { "fdivp", { STi
, ST
} },
4121 { "fdivrp", { STi
, ST
} },
4123 { "fsubrp", { STi
, ST
} },
4124 { "fsubp", { STi
, ST
} },
4125 { "fdivrp", { STi
, ST
} },
4126 { "fdivp", { STi
, ST
} },
4131 { "ffreep", { STi
} },
4132 { "(bad)", { XX
} },
4133 { "(bad)", { XX
} },
4134 { "(bad)", { XX
} },
4136 { "fucomip", { ST
, STi
} },
4137 { "fcomip", { ST
, STi
} },
4138 { "(bad)", { XX
} },
4142 static char *fgrps
[][8] = {
4145 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4150 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4155 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4160 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4165 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4170 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4175 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4176 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4181 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4186 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4191 dofloat (int sizeflag
)
4193 const struct dis386
*dp
;
4194 unsigned char floatop
;
4196 floatop
= codep
[-1];
4200 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4202 putop (float_mem
[fp_indx
], sizeflag
);
4205 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4208 /* Skip mod/rm byte. */
4212 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4213 if (dp
->name
== NULL
)
4215 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4217 /* Instruction fnstsw is only one with strange arg. */
4218 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4219 strcpy (op_out
[0], names16
[0]);
4223 putop (dp
->name
, sizeflag
);
4228 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4233 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4238 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4240 oappend ("%st" + intel_syntax
);
4244 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4246 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4247 oappend (scratchbuf
+ intel_syntax
);
4250 /* Capital letters in template are macros. */
4252 putop (const char *template, int sizeflag
)
4257 for (p
= template; *p
; p
++)
4268 if (address_mode
== mode_64bit
)
4276 /* Alternative not valid. */
4277 strcpy (obuf
, "(bad)");
4281 else if (*p
== '\0')
4302 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4308 if (sizeflag
& SUFFIX_ALWAYS
)
4312 if (intel_syntax
&& !alt
)
4314 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4316 if (sizeflag
& DFLAG
)
4317 *obufp
++ = intel_syntax
? 'd' : 'l';
4319 *obufp
++ = intel_syntax
? 'w' : 's';
4320 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4324 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4331 else if (sizeflag
& DFLAG
)
4332 *obufp
++ = intel_syntax
? 'd' : 'l';
4335 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4340 case 'E': /* For jcxz/jecxz */
4341 if (address_mode
== mode_64bit
)
4343 if (sizeflag
& AFLAG
)
4349 if (sizeflag
& AFLAG
)
4351 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4356 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4358 if (sizeflag
& AFLAG
)
4359 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4361 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4362 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4366 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4368 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4373 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4378 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4379 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4381 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4384 if (prefixes
& PREFIX_DS
)
4405 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4414 if (sizeflag
& SUFFIX_ALWAYS
)
4418 if ((prefixes
& PREFIX_FWAIT
) == 0)
4421 used_prefixes
|= PREFIX_FWAIT
;
4427 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4432 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4437 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4446 if ((prefixes
& PREFIX_DATA
)
4448 || (sizeflag
& SUFFIX_ALWAYS
))
4455 if (sizeflag
& DFLAG
)
4460 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4466 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4468 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4474 if (intel_syntax
&& !alt
)
4477 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4483 if (sizeflag
& DFLAG
)
4484 *obufp
++ = intel_syntax
? 'd' : 'l';
4488 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4495 else if (sizeflag
& DFLAG
)
4504 if (intel_syntax
&& !p
[1]
4505 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4508 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4513 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4515 if (sizeflag
& SUFFIX_ALWAYS
)
4523 if (sizeflag
& SUFFIX_ALWAYS
)
4529 if (sizeflag
& DFLAG
)
4533 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4538 if (prefixes
& PREFIX_DATA
)
4542 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4553 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4555 /* operand size flag for cwtl, cbtw */
4564 else if (sizeflag
& DFLAG
)
4569 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4579 oappend (const char *s
)
4582 obufp
+= strlen (s
);
4588 if (prefixes
& PREFIX_CS
)
4590 used_prefixes
|= PREFIX_CS
;
4591 oappend ("%cs:" + intel_syntax
);
4593 if (prefixes
& PREFIX_DS
)
4595 used_prefixes
|= PREFIX_DS
;
4596 oappend ("%ds:" + intel_syntax
);
4598 if (prefixes
& PREFIX_SS
)
4600 used_prefixes
|= PREFIX_SS
;
4601 oappend ("%ss:" + intel_syntax
);
4603 if (prefixes
& PREFIX_ES
)
4605 used_prefixes
|= PREFIX_ES
;
4606 oappend ("%es:" + intel_syntax
);
4608 if (prefixes
& PREFIX_FS
)
4610 used_prefixes
|= PREFIX_FS
;
4611 oappend ("%fs:" + intel_syntax
);
4613 if (prefixes
& PREFIX_GS
)
4615 used_prefixes
|= PREFIX_GS
;
4616 oappend ("%gs:" + intel_syntax
);
4621 OP_indirE (int bytemode
, int sizeflag
)
4625 OP_E (bytemode
, sizeflag
);
4629 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4631 if (address_mode
== mode_64bit
)
4639 sprintf_vma (tmp
, disp
);
4640 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4641 strcpy (buf
+ 2, tmp
+ i
);
4645 bfd_signed_vma v
= disp
;
4652 /* Check for possible overflow on 0x8000000000000000. */
4655 strcpy (buf
, "9223372036854775808");
4669 tmp
[28 - i
] = (v
% 10) + '0';
4673 strcpy (buf
, tmp
+ 29 - i
);
4679 sprintf (buf
, "0x%x", (unsigned int) disp
);
4681 sprintf (buf
, "%d", (int) disp
);
4685 /* Put DISP in BUF as signed hex number. */
4688 print_displacement (char *buf
, bfd_vma disp
)
4690 bfd_signed_vma val
= disp
;
4699 /* Check for possible overflow. */
4702 switch (address_mode
)
4705 strcpy (buf
+ j
, "0x8000000000000000");
4708 strcpy (buf
+ j
, "0x80000000");
4711 strcpy (buf
+ j
, "0x8000");
4721 sprintf_vma (tmp
, val
);
4722 for (i
= 0; tmp
[i
] == '0'; i
++)
4726 strcpy (buf
+ j
, tmp
+ i
);
4730 intel_operand_size (int bytemode
, int sizeflag
)
4736 oappend ("BYTE PTR ");
4740 oappend ("WORD PTR ");
4743 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4745 oappend ("QWORD PTR ");
4746 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4754 oappend ("QWORD PTR ");
4755 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4756 oappend ("DWORD PTR ");
4758 oappend ("WORD PTR ");
4759 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4762 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4764 oappend ("WORD PTR ");
4766 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4770 oappend ("DWORD PTR ");
4773 oappend ("QWORD PTR ");
4776 if (address_mode
== mode_64bit
)
4777 oappend ("QWORD PTR ");
4779 oappend ("DWORD PTR ");
4782 if (sizeflag
& DFLAG
)
4783 oappend ("FWORD PTR ");
4785 oappend ("DWORD PTR ");
4786 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4789 oappend ("TBYTE PTR ");
4792 oappend ("XMMWORD PTR ");
4795 oappend ("OWORD PTR ");
4803 OP_E (int bytemode
, int sizeflag
)
4812 /* Skip mod/rm byte. */
4823 oappend (names8rex
[modrm
.rm
+ add
]);
4825 oappend (names8
[modrm
.rm
+ add
]);
4828 oappend (names16
[modrm
.rm
+ add
]);
4831 oappend (names32
[modrm
.rm
+ add
]);
4834 oappend (names64
[modrm
.rm
+ add
]);
4837 if (address_mode
== mode_64bit
)
4838 oappend (names64
[modrm
.rm
+ add
]);
4840 oappend (names32
[modrm
.rm
+ add
]);
4843 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4845 oappend (names64
[modrm
.rm
+ add
]);
4846 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4858 oappend (names64
[modrm
.rm
+ add
]);
4859 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4860 oappend (names32
[modrm
.rm
+ add
]);
4862 oappend (names16
[modrm
.rm
+ add
]);
4863 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4868 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4876 intel_operand_size (bytemode
, sizeflag
);
4879 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4881 /* 32/64 bit address mode */
4896 FETCH_DATA (the_info
, codep
+ 1);
4897 index
= (*codep
>> 3) & 7;
4898 if (address_mode
== mode_64bit
|| index
!= 0x4)
4899 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4900 scale
= (*codep
>> 6) & 3;
4912 if ((base
& 7) == 5)
4915 if (address_mode
== mode_64bit
&& !havesib
)
4921 FETCH_DATA (the_info
, codep
+ 1);
4923 if ((disp
& 0x80) != 0)
4931 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
4934 if (modrm
.mod
!= 0 || (base
& 7) == 5)
4936 if (havedisp
|| riprel
)
4937 print_displacement (scratchbuf
, disp
);
4939 print_operand_value (scratchbuf
, 1, disp
);
4940 oappend (scratchbuf
);
4948 if (havedisp
|| (intel_syntax
&& riprel
))
4950 *obufp
++ = open_char
;
4951 if (intel_syntax
&& riprel
)
4958 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4959 ? names64
[base
] : names32
[base
]);
4964 if (!intel_syntax
|| havebase
)
4966 *obufp
++ = separator_char
;
4969 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4970 ? names64
[index
] : names32
[index
]);
4972 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4974 *obufp
++ = scale_char
;
4976 sprintf (scratchbuf
, "%d", 1 << scale
);
4977 oappend (scratchbuf
);
4981 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
4983 if ((bfd_signed_vma
) disp
>= 0)
4988 else if (modrm
.mod
!= 1)
4992 disp
= - (bfd_signed_vma
) disp
;
4995 print_displacement (scratchbuf
, disp
);
4996 oappend (scratchbuf
);
4999 *obufp
++ = close_char
;
5002 else if (intel_syntax
)
5004 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5006 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5007 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5011 oappend (names_seg
[ds_reg
- es_reg
]);
5014 print_operand_value (scratchbuf
, 1, disp
);
5015 oappend (scratchbuf
);
5020 { /* 16 bit address mode */
5027 if ((disp
& 0x8000) != 0)
5032 FETCH_DATA (the_info
, codep
+ 1);
5034 if ((disp
& 0x80) != 0)
5039 if ((disp
& 0x8000) != 0)
5045 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5047 print_displacement (scratchbuf
, disp
);
5048 oappend (scratchbuf
);
5051 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5053 *obufp
++ = open_char
;
5055 oappend (index16
[modrm
.rm
]);
5057 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5059 if ((bfd_signed_vma
) disp
>= 0)
5064 else if (modrm
.mod
!= 1)
5068 disp
= - (bfd_signed_vma
) disp
;
5071 print_displacement (scratchbuf
, disp
);
5072 oappend (scratchbuf
);
5075 *obufp
++ = close_char
;
5078 else if (intel_syntax
)
5080 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5081 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5085 oappend (names_seg
[ds_reg
- es_reg
]);
5088 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
5089 oappend (scratchbuf
);
5095 OP_G (int bytemode
, int sizeflag
)
5106 oappend (names8rex
[modrm
.reg
+ add
]);
5108 oappend (names8
[modrm
.reg
+ add
]);
5111 oappend (names16
[modrm
.reg
+ add
]);
5114 oappend (names32
[modrm
.reg
+ add
]);
5117 oappend (names64
[modrm
.reg
+ add
]);
5126 oappend (names64
[modrm
.reg
+ add
]);
5127 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5128 oappend (names32
[modrm
.reg
+ add
]);
5130 oappend (names16
[modrm
.reg
+ add
]);
5131 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5134 if (address_mode
== mode_64bit
)
5135 oappend (names64
[modrm
.reg
+ add
]);
5137 oappend (names32
[modrm
.reg
+ add
]);
5140 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5153 FETCH_DATA (the_info
, codep
+ 8);
5154 a
= *codep
++ & 0xff;
5155 a
|= (*codep
++ & 0xff) << 8;
5156 a
|= (*codep
++ & 0xff) << 16;
5157 a
|= (*codep
++ & 0xff) << 24;
5158 b
= *codep
++ & 0xff;
5159 b
|= (*codep
++ & 0xff) << 8;
5160 b
|= (*codep
++ & 0xff) << 16;
5161 b
|= (*codep
++ & 0xff) << 24;
5162 x
= a
+ ((bfd_vma
) b
<< 32);
5170 static bfd_signed_vma
5173 bfd_signed_vma x
= 0;
5175 FETCH_DATA (the_info
, codep
+ 4);
5176 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5177 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5178 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5179 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5183 static bfd_signed_vma
5186 bfd_signed_vma x
= 0;
5188 FETCH_DATA (the_info
, codep
+ 4);
5189 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5190 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5191 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5192 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5194 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5204 FETCH_DATA (the_info
, codep
+ 2);
5205 x
= *codep
++ & 0xff;
5206 x
|= (*codep
++ & 0xff) << 8;
5211 set_op (bfd_vma op
, int riprel
)
5213 op_index
[op_ad
] = op_ad
;
5214 if (address_mode
== mode_64bit
)
5216 op_address
[op_ad
] = op
;
5217 op_riprel
[op_ad
] = riprel
;
5221 /* Mask to get a 32-bit address. */
5222 op_address
[op_ad
] = op
& 0xffffffff;
5223 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5228 OP_REG (int code
, int sizeflag
)
5238 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5239 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5240 s
= names16
[code
- ax_reg
+ add
];
5242 case es_reg
: case ss_reg
: case cs_reg
:
5243 case ds_reg
: case fs_reg
: case gs_reg
:
5244 s
= names_seg
[code
- es_reg
+ add
];
5246 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5247 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5250 s
= names8rex
[code
- al_reg
+ add
];
5252 s
= names8
[code
- al_reg
];
5254 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5255 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5256 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5258 s
= names64
[code
- rAX_reg
+ add
];
5261 code
+= eAX_reg
- rAX_reg
;
5263 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5264 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5267 s
= names64
[code
- eAX_reg
+ add
];
5268 else if (sizeflag
& DFLAG
)
5269 s
= names32
[code
- eAX_reg
+ add
];
5271 s
= names16
[code
- eAX_reg
+ add
];
5272 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5275 s
= INTERNAL_DISASSEMBLER_ERROR
;
5282 OP_IMREG (int code
, int sizeflag
)
5294 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5295 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5296 s
= names16
[code
- ax_reg
];
5298 case es_reg
: case ss_reg
: case cs_reg
:
5299 case ds_reg
: case fs_reg
: case gs_reg
:
5300 s
= names_seg
[code
- es_reg
];
5302 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5303 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5306 s
= names8rex
[code
- al_reg
];
5308 s
= names8
[code
- al_reg
];
5310 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5311 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5314 s
= names64
[code
- eAX_reg
];
5315 else if (sizeflag
& DFLAG
)
5316 s
= names32
[code
- eAX_reg
];
5318 s
= names16
[code
- eAX_reg
];
5319 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5322 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5327 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5330 s
= INTERNAL_DISASSEMBLER_ERROR
;
5337 OP_I (int bytemode
, int sizeflag
)
5340 bfd_signed_vma mask
= -1;
5345 FETCH_DATA (the_info
, codep
+ 1);
5350 if (address_mode
== mode_64bit
)
5360 else if (sizeflag
& DFLAG
)
5370 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5381 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5386 scratchbuf
[0] = '$';
5387 print_operand_value (scratchbuf
+ 1, 1, op
);
5388 oappend (scratchbuf
+ intel_syntax
);
5389 scratchbuf
[0] = '\0';
5393 OP_I64 (int bytemode
, int sizeflag
)
5396 bfd_signed_vma mask
= -1;
5398 if (address_mode
!= mode_64bit
)
5400 OP_I (bytemode
, sizeflag
);
5407 FETCH_DATA (the_info
, codep
+ 1);
5415 else if (sizeflag
& DFLAG
)
5425 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5432 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5437 scratchbuf
[0] = '$';
5438 print_operand_value (scratchbuf
+ 1, 1, op
);
5439 oappend (scratchbuf
+ intel_syntax
);
5440 scratchbuf
[0] = '\0';
5444 OP_sI (int bytemode
, int sizeflag
)
5447 bfd_signed_vma mask
= -1;
5452 FETCH_DATA (the_info
, codep
+ 1);
5454 if ((op
& 0x80) != 0)
5462 else if (sizeflag
& DFLAG
)
5471 if ((op
& 0x8000) != 0)
5474 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5479 if ((op
& 0x8000) != 0)
5483 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5487 scratchbuf
[0] = '$';
5488 print_operand_value (scratchbuf
+ 1, 1, op
);
5489 oappend (scratchbuf
+ intel_syntax
);
5493 OP_J (int bytemode
, int sizeflag
)
5497 bfd_vma segment
= 0;
5502 FETCH_DATA (the_info
, codep
+ 1);
5504 if ((disp
& 0x80) != 0)
5508 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5513 if ((disp
& 0x8000) != 0)
5515 /* In 16bit mode, address is wrapped around at 64k within
5516 the same segment. Otherwise, a data16 prefix on a jump
5517 instruction means that the pc is masked to 16 bits after
5518 the displacement is added! */
5520 if ((prefixes
& PREFIX_DATA
) == 0)
5521 segment
= ((start_pc
+ codep
- start_codep
)
5522 & ~((bfd_vma
) 0xffff));
5524 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5527 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5530 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5532 print_operand_value (scratchbuf
, 1, disp
);
5533 oappend (scratchbuf
);
5537 OP_SEG (int bytemode
, int sizeflag
)
5539 if (bytemode
== w_mode
)
5540 oappend (names_seg
[modrm
.reg
]);
5542 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5546 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5550 if (sizeflag
& DFLAG
)
5560 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5562 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5564 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5565 oappend (scratchbuf
);
5569 OP_OFF (int bytemode
, int sizeflag
)
5573 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5574 intel_operand_size (bytemode
, sizeflag
);
5577 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5584 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5585 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5587 oappend (names_seg
[ds_reg
- es_reg
]);
5591 print_operand_value (scratchbuf
, 1, off
);
5592 oappend (scratchbuf
);
5596 OP_OFF64 (int bytemode
, int sizeflag
)
5600 if (address_mode
!= mode_64bit
5601 || (prefixes
& PREFIX_ADDR
))
5603 OP_OFF (bytemode
, sizeflag
);
5607 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5608 intel_operand_size (bytemode
, sizeflag
);
5615 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5616 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5618 oappend (names_seg
[ds_reg
- es_reg
]);
5622 print_operand_value (scratchbuf
, 1, off
);
5623 oappend (scratchbuf
);
5627 ptr_reg (int code
, int sizeflag
)
5631 *obufp
++ = open_char
;
5632 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5633 if (address_mode
== mode_64bit
)
5635 if (!(sizeflag
& AFLAG
))
5636 s
= names32
[code
- eAX_reg
];
5638 s
= names64
[code
- eAX_reg
];
5640 else if (sizeflag
& AFLAG
)
5641 s
= names32
[code
- eAX_reg
];
5643 s
= names16
[code
- eAX_reg
];
5645 *obufp
++ = close_char
;
5650 OP_ESreg (int code
, int sizeflag
)
5656 case 0x6d: /* insw/insl */
5657 intel_operand_size (z_mode
, sizeflag
);
5659 case 0xa5: /* movsw/movsl/movsq */
5660 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5661 case 0xab: /* stosw/stosl */
5662 case 0xaf: /* scasw/scasl */
5663 intel_operand_size (v_mode
, sizeflag
);
5666 intel_operand_size (b_mode
, sizeflag
);
5669 oappend ("%es:" + intel_syntax
);
5670 ptr_reg (code
, sizeflag
);
5674 OP_DSreg (int code
, int sizeflag
)
5680 case 0x6f: /* outsw/outsl */
5681 intel_operand_size (z_mode
, sizeflag
);
5683 case 0xa5: /* movsw/movsl/movsq */
5684 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5685 case 0xad: /* lodsw/lodsl/lodsq */
5686 intel_operand_size (v_mode
, sizeflag
);
5689 intel_operand_size (b_mode
, sizeflag
);
5699 prefixes
|= PREFIX_DS
;
5701 ptr_reg (code
, sizeflag
);
5705 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5713 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5715 used_prefixes
|= PREFIX_LOCK
;
5718 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5719 oappend (scratchbuf
+ intel_syntax
);
5723 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5730 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5732 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5733 oappend (scratchbuf
);
5737 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5739 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5740 oappend (scratchbuf
+ intel_syntax
);
5744 OP_R (int bytemode
, int sizeflag
)
5747 OP_E (bytemode
, sizeflag
);
5753 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5755 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5756 if (prefixes
& PREFIX_DATA
)
5762 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5765 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5766 oappend (scratchbuf
+ intel_syntax
);
5770 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5776 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5777 oappend (scratchbuf
+ intel_syntax
);
5781 OP_EM (int bytemode
, int sizeflag
)
5785 if (intel_syntax
&& bytemode
== v_mode
)
5787 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5788 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5790 OP_E (bytemode
, sizeflag
);
5794 /* Skip mod/rm byte. */
5797 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5798 if (prefixes
& PREFIX_DATA
)
5805 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5808 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5809 oappend (scratchbuf
+ intel_syntax
);
5812 /* cvt* are the only instructions in sse2 which have
5813 both SSE and MMX operands and also have 0x66 prefix
5814 in their opcode. 0x66 was originally used to differentiate
5815 between SSE and MMX instruction(operands). So we have to handle the
5816 cvt* separately using OP_EMC and OP_MXC */
5818 OP_EMC (int bytemode
, int sizeflag
)
5822 if (intel_syntax
&& bytemode
== v_mode
)
5824 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5825 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5827 OP_E (bytemode
, sizeflag
);
5831 /* Skip mod/rm byte. */
5834 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5835 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5836 oappend (scratchbuf
+ intel_syntax
);
5840 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5842 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5843 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5844 oappend (scratchbuf
+ intel_syntax
);
5848 OP_EX (int bytemode
, int sizeflag
)
5853 OP_E (bytemode
, sizeflag
);
5860 /* Skip mod/rm byte. */
5863 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5864 oappend (scratchbuf
+ intel_syntax
);
5868 OP_MS (int bytemode
, int sizeflag
)
5871 OP_EM (bytemode
, sizeflag
);
5877 OP_XS (int bytemode
, int sizeflag
)
5880 OP_EX (bytemode
, sizeflag
);
5886 OP_M (int bytemode
, int sizeflag
)
5889 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5892 OP_E (bytemode
, sizeflag
);
5896 OP_0f07 (int bytemode
, int sizeflag
)
5898 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
5901 OP_E (bytemode
, sizeflag
);
5905 OP_0fae (int bytemode
, int sizeflag
)
5910 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5912 if (modrm
.reg
< 5 || modrm
.rm
!= 0)
5914 BadOp (); /* bad sfence, mfence, or lfence */
5918 else if (modrm
.reg
!= 7)
5920 BadOp (); /* bad clflush */
5924 OP_E (bytemode
, sizeflag
);
5927 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5928 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5931 NOP_Fixup1 (int bytemode
, int sizeflag
)
5933 if ((prefixes
& PREFIX_DATA
) != 0
5936 && address_mode
== mode_64bit
))
5937 OP_REG (bytemode
, sizeflag
);
5939 strcpy (obuf
, "nop");
5943 NOP_Fixup2 (int bytemode
, int sizeflag
)
5945 if ((prefixes
& PREFIX_DATA
) != 0
5948 && address_mode
== mode_64bit
))
5949 OP_IMREG (bytemode
, sizeflag
);
5952 static const char *const Suffix3DNow
[] = {
5953 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5954 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5955 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5956 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5957 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5958 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5959 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5960 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5961 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5962 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5963 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5964 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5965 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5966 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5967 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5968 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5969 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5970 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5971 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5972 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5973 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5974 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5975 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5976 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5977 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5978 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5979 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5980 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5981 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5982 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5983 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5984 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5985 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5986 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5987 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5988 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5989 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5990 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5991 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5992 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5993 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5994 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5995 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5996 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5997 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5998 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
5999 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
6000 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6001 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6002 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6003 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6004 /* CC */ NULL
, NULL
, NULL
, NULL
,
6005 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6006 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6007 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6008 /* DC */ NULL
, NULL
, NULL
, NULL
,
6009 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6010 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6011 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6012 /* EC */ NULL
, NULL
, NULL
, NULL
,
6013 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6014 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6015 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6016 /* FC */ NULL
, NULL
, NULL
, NULL
,
6020 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6022 const char *mnemonic
;
6024 FETCH_DATA (the_info
, codep
+ 1);
6025 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6026 place where an 8-bit immediate would normally go. ie. the last
6027 byte of the instruction. */
6028 obufp
= obuf
+ strlen (obuf
);
6029 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6034 /* Since a variable sized modrm/sib chunk is between the start
6035 of the opcode (0x0f0f) and the opcode suffix, we need to do
6036 all the modrm processing first, and don't know until now that
6037 we have a bad opcode. This necessitates some cleaning up. */
6038 op_out
[0][0] = '\0';
6039 op_out
[1][0] = '\0';
6044 static const char *simd_cmp_op
[] = {
6056 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6058 unsigned int cmp_type
;
6060 FETCH_DATA (the_info
, codep
+ 1);
6061 obufp
= obuf
+ strlen (obuf
);
6062 cmp_type
= *codep
++ & 0xff;
6065 char suffix1
= 'p', suffix2
= 's';
6066 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6067 if (prefixes
& PREFIX_REPZ
)
6071 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6072 if (prefixes
& PREFIX_DATA
)
6076 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6077 if (prefixes
& PREFIX_REPNZ
)
6078 suffix1
= 's', suffix2
= 'd';
6081 sprintf (scratchbuf
, "cmp%s%c%c",
6082 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6083 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6084 oappend (scratchbuf
);
6088 /* We have a bad extension byte. Clean up. */
6089 op_out
[0][0] = '\0';
6090 op_out
[1][0] = '\0';
6096 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
6098 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6099 forms of these instructions. */
6102 char *p
= obuf
+ strlen (obuf
);
6105 *(p
- 1) = *(p
- 2);
6106 *(p
- 2) = *(p
- 3);
6107 *(p
- 3) = extrachar
;
6112 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6114 if (modrm
.mod
== 3 && modrm
.reg
== 1 && modrm
.rm
<= 1)
6116 /* Override "sidt". */
6117 size_t olen
= strlen (obuf
);
6118 char *p
= obuf
+ olen
- 4;
6119 const char **names
= (address_mode
== mode_64bit
6120 ? names64
: names32
);
6122 /* We might have a suffix when disassembling with -Msuffix. */
6126 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6128 && (prefixes
& PREFIX_ADDR
)
6131 && CONST_STRNEQ (p
- 7, "addr")
6132 && (CONST_STRNEQ (p
- 3, "16")
6133 || CONST_STRNEQ (p
- 3, "32")))
6138 /* mwait %eax,%ecx */
6139 strcpy (p
, "mwait");
6141 strcpy (op_out
[0], names
[0]);
6145 /* monitor %eax,%ecx,%edx" */
6146 strcpy (p
, "monitor");
6149 const char **op1_names
;
6150 if (!(prefixes
& PREFIX_ADDR
))
6151 op1_names
= (address_mode
== mode_16bit
6155 op1_names
= (address_mode
!= mode_32bit
6156 ? names32
: names16
);
6157 used_prefixes
|= PREFIX_ADDR
;
6159 strcpy (op_out
[0], op1_names
[0]);
6160 strcpy (op_out
[2], names
[2]);
6165 strcpy (op_out
[1], names
[1]);
6176 SVME_Fixup (int bytemode
, int sizeflag
)
6208 OP_M (bytemode
, sizeflag
);
6211 /* Override "lidt". */
6212 p
= obuf
+ strlen (obuf
) - 4;
6213 /* We might have a suffix. */
6217 if (!(prefixes
& PREFIX_ADDR
))
6222 used_prefixes
|= PREFIX_ADDR
;
6226 strcpy (op_out
[1], names32
[1]);
6232 *obufp
++ = open_char
;
6233 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6237 strcpy (obufp
, alt
);
6238 obufp
+= strlen (alt
);
6239 *obufp
++ = close_char
;
6246 INVLPG_Fixup (int bytemode
, int sizeflag
)
6259 OP_M (bytemode
, sizeflag
);
6262 /* Override "invlpg". */
6263 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6270 /* Throw away prefixes and 1st. opcode byte. */
6271 codep
= insn_codep
+ 1;
6276 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6283 /* Override "sgdt". */
6284 char *p
= obuf
+ strlen (obuf
) - 4;
6286 /* We might have a suffix when disassembling with -Msuffix. */
6293 strcpy (p
, "vmcall");
6296 strcpy (p
, "vmlaunch");
6299 strcpy (p
, "vmresume");
6302 strcpy (p
, "vmxoff");
6313 OP_VMX (int bytemode
, int sizeflag
)
6315 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
6316 if (prefixes
& PREFIX_DATA
)
6317 strcpy (obuf
, "vmclear");
6318 else if (prefixes
& PREFIX_REPZ
)
6319 strcpy (obuf
, "vmxon");
6321 strcpy (obuf
, "vmptrld");
6322 OP_E (bytemode
, sizeflag
);
6326 REP_Fixup (int bytemode
, int sizeflag
)
6328 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6332 if (prefixes
& PREFIX_REPZ
)
6333 switch (*insn_codep
)
6335 case 0x6e: /* outsb */
6336 case 0x6f: /* outsw/outsl */
6337 case 0xa4: /* movsb */
6338 case 0xa5: /* movsw/movsl/movsq */
6344 case 0xaa: /* stosb */
6345 case 0xab: /* stosw/stosl/stosq */
6346 case 0xac: /* lodsb */
6347 case 0xad: /* lodsw/lodsl/lodsq */
6348 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
6353 case 0x6c: /* insb */
6354 case 0x6d: /* insl/insw */
6370 olen
= strlen (obuf
);
6371 p
= obuf
+ olen
- ilen
- 1 - 4;
6372 /* Handle "repz [addr16|addr32]". */
6373 if ((prefixes
& PREFIX_ADDR
))
6376 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
6384 OP_IMREG (bytemode
, sizeflag
);
6387 OP_ESreg (bytemode
, sizeflag
);
6390 OP_DSreg (bytemode
, sizeflag
);
6399 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6404 /* Change cmpxchg8b to cmpxchg16b. */
6405 char *p
= obuf
+ strlen (obuf
) - 2;
6409 OP_M (bytemode
, sizeflag
);
6413 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6415 sprintf (scratchbuf
, "%%xmm%d", reg
);
6416 oappend (scratchbuf
+ intel_syntax
);
6420 CRC32_Fixup (int bytemode
, int sizeflag
)
6422 /* Add proper suffix to "crc32". */
6423 char *p
= obuf
+ strlen (obuf
);
6440 else if (sizeflag
& DFLAG
)
6444 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6447 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6456 /* Skip mod/rm byte. */
6461 add
= (rex
& REX_B
) ? 8 : 0;
6462 if (bytemode
== b_mode
)
6466 oappend (names8rex
[modrm
.rm
+ add
]);
6468 oappend (names8
[modrm
.rm
+ add
]);
6474 oappend (names64
[modrm
.rm
+ add
]);
6475 else if ((prefixes
& PREFIX_DATA
))
6476 oappend (names16
[modrm
.rm
+ add
]);
6478 oappend (names32
[modrm
.rm
+ add
]);
6482 OP_E (bytemode
, sizeflag
);