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 indirEv { OP_indirE, stack_v_mode }
211 #define indirEp { OP_indirE, f_mode }
212 #define stackEv { OP_E, stack_v_mode }
213 #define Em { OP_E, m_mode }
214 #define Ew { OP_E, w_mode }
215 #define M { OP_M, 0 } /* lea, lgdt, etc. */
216 #define Ma { OP_M, v_mode }
217 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
218 #define Mq { OP_M, q_mode }
219 #define Gb { OP_G, b_mode }
220 #define Gv { OP_G, v_mode }
221 #define Gd { OP_G, d_mode }
222 #define Gdq { OP_G, dq_mode }
223 #define Gm { OP_G, m_mode }
224 #define Gw { OP_G, w_mode }
225 #define Rd { OP_R, d_mode }
226 #define Rm { OP_R, m_mode }
227 #define Ib { OP_I, b_mode }
228 #define sIb { OP_sI, b_mode } /* sign extened byte */
229 #define Iv { OP_I, v_mode }
230 #define Iq { OP_I, q_mode }
231 #define Iv64 { OP_I64, v_mode }
232 #define Iw { OP_I, w_mode }
233 #define I1 { OP_I, const_1_mode }
234 #define Jb { OP_J, b_mode }
235 #define Jv { OP_J, v_mode }
236 #define Cm { OP_C, m_mode }
237 #define Dm { OP_D, m_mode }
238 #define Td { OP_T, d_mode }
240 #define RMeAX { OP_REG, eAX_reg }
241 #define RMeBX { OP_REG, eBX_reg }
242 #define RMeCX { OP_REG, eCX_reg }
243 #define RMeDX { OP_REG, eDX_reg }
244 #define RMeSP { OP_REG, eSP_reg }
245 #define RMeBP { OP_REG, eBP_reg }
246 #define RMeSI { OP_REG, eSI_reg }
247 #define RMeDI { OP_REG, eDI_reg }
248 #define RMrAX { OP_REG, rAX_reg }
249 #define RMrBX { OP_REG, rBX_reg }
250 #define RMrCX { OP_REG, rCX_reg }
251 #define RMrDX { OP_REG, rDX_reg }
252 #define RMrSP { OP_REG, rSP_reg }
253 #define RMrBP { OP_REG, rBP_reg }
254 #define RMrSI { OP_REG, rSI_reg }
255 #define RMrDI { OP_REG, rDI_reg }
256 #define RMAL { OP_REG, al_reg }
257 #define RMAL { OP_REG, al_reg }
258 #define RMCL { OP_REG, cl_reg }
259 #define RMDL { OP_REG, dl_reg }
260 #define RMBL { OP_REG, bl_reg }
261 #define RMAH { OP_REG, ah_reg }
262 #define RMCH { OP_REG, ch_reg }
263 #define RMDH { OP_REG, dh_reg }
264 #define RMBH { OP_REG, bh_reg }
265 #define RMAX { OP_REG, ax_reg }
266 #define RMDX { OP_REG, dx_reg }
268 #define eAX { OP_IMREG, eAX_reg }
269 #define eBX { OP_IMREG, eBX_reg }
270 #define eCX { OP_IMREG, eCX_reg }
271 #define eDX { OP_IMREG, eDX_reg }
272 #define eSP { OP_IMREG, eSP_reg }
273 #define eBP { OP_IMREG, eBP_reg }
274 #define eSI { OP_IMREG, eSI_reg }
275 #define eDI { OP_IMREG, eDI_reg }
276 #define AL { OP_IMREG, al_reg }
277 #define CL { OP_IMREG, cl_reg }
278 #define DL { OP_IMREG, dl_reg }
279 #define BL { OP_IMREG, bl_reg }
280 #define AH { OP_IMREG, ah_reg }
281 #define CH { OP_IMREG, ch_reg }
282 #define DH { OP_IMREG, dh_reg }
283 #define BH { OP_IMREG, bh_reg }
284 #define AX { OP_IMREG, ax_reg }
285 #define DX { OP_IMREG, dx_reg }
286 #define zAX { OP_IMREG, z_mode_ax_reg }
287 #define indirDX { OP_IMREG, indir_dx_reg }
289 #define Sw { OP_SEG, w_mode }
290 #define Sv { OP_SEG, v_mode }
291 #define Ap { OP_DIR, 0 }
292 #define Ob { OP_OFF64, b_mode }
293 #define Ov { OP_OFF64, v_mode }
294 #define Xb { OP_DSreg, eSI_reg }
295 #define Xv { OP_DSreg, eSI_reg }
296 #define Xz { OP_DSreg, eSI_reg }
297 #define Yb { OP_ESreg, eDI_reg }
298 #define Yv { OP_ESreg, eDI_reg }
299 #define DSBX { OP_DSreg, eBX_reg }
301 #define es { OP_REG, es_reg }
302 #define ss { OP_REG, ss_reg }
303 #define cs { OP_REG, cs_reg }
304 #define ds { OP_REG, ds_reg }
305 #define fs { OP_REG, fs_reg }
306 #define gs { OP_REG, gs_reg }
308 #define MX { OP_MMX, 0 }
309 #define XM { OP_XMM, 0 }
310 #define EM { OP_EM, v_mode }
311 #define EMd { OP_EM, d_mode }
312 #define EMq { OP_EM, q_mode }
313 #define EXd { OP_EX, d_mode }
314 #define EXq { OP_EX, q_mode }
315 #define EXx { OP_EX, x_mode }
316 #define MS { OP_MS, v_mode }
317 #define XS { OP_XS, v_mode }
318 #define EMC { OP_EMC, v_mode }
319 #define MXC { OP_MXC, 0 }
320 #define VM { OP_VMX, q_mode }
321 #define OPSUF { OP_3DNowSuffix, 0 }
322 #define OPSIMD { OP_SIMD_Suffix, 0 }
323 #define XMM0 { XMM_Fixup, 0 }
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr { REP_Fixup, eSI_reg }
327 #define Xvr { REP_Fixup, eSI_reg }
328 #define Ybr { REP_Fixup, eDI_reg }
329 #define Yvr { REP_Fixup, eDI_reg }
330 #define Yzr { REP_Fixup, eDI_reg }
331 #define indirDXr { REP_Fixup, indir_dx_reg }
332 #define ALr { REP_Fixup, al_reg }
333 #define eAXr { REP_Fixup, eAX_reg }
335 #define cond_jump_flag { NULL, cond_jump_mode }
336 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
359 #define o_mode 17 /* 16-byte operand */
360 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
361 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
406 #define z_mode_ax_reg 149
407 #define indir_dx_reg 150
411 #define USE_PREFIX_USER_TABLE 3
412 #define X86_64_SPECIAL 4
413 #define IS_3BYTE_OPCODE 5
415 #define FLOAT NULL, { { NULL, FLOATCODE } }
417 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
418 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
419 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
420 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
421 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
422 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
423 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
424 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
425 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
426 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
427 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
428 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
429 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
430 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
431 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
432 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
433 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
434 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
435 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
436 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
437 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
438 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
439 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
440 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
441 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
442 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
443 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
444 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
446 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
447 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
448 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
449 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
450 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
451 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
452 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
453 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
454 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
455 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
456 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
457 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
458 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
459 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
460 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
461 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
462 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
463 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
464 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
465 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
466 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
467 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
468 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
469 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
470 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
471 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
472 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
473 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
474 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
475 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
476 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
477 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
478 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
479 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
480 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
481 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
482 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
483 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
484 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
485 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
486 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
487 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
488 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
489 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
490 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
491 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
492 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
493 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
494 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
495 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
496 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
497 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
498 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
499 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
500 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
501 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
502 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
503 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
504 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
505 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
506 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
507 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
508 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
509 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
510 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
511 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
512 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
513 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
514 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
515 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
516 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
517 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
518 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
519 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
520 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
521 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
522 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
523 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
524 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
525 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
526 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
527 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
528 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
529 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
530 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
531 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
532 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
533 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
534 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
535 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
536 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
537 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
538 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
539 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
540 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
541 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
542 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
543 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
546 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
547 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
548 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
549 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
551 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
552 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
554 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
565 /* Upper case letters in the instruction names here are macros.
566 'A' => print 'b' if no register operands or suffix_always is true
567 'B' => print 'b' if suffix_always is true
568 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
570 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
571 . suffix_always is true
572 'E' => print 'e' if 32-bit form of jcxz
573 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
574 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
575 'H' => print ",pt" or ",pn" branch hint
576 'I' => honor following macro letter even in Intel mode (implemented only
577 . for some of the macro letters)
579 'K' => print 'd' or 'q' if rex prefix is present.
580 'L' => print 'l' if suffix_always is true
581 'N' => print 'n' if instruction has no wait "prefix"
582 'O' => print 'd' or 'o' (or 'q' in Intel mode)
583 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
584 . or suffix_always is true. print 'q' if rex prefix is present.
585 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
587 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
588 'S' => print 'w', 'l' or 'q' if suffix_always is true
589 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
590 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
591 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
592 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
593 'X' => print 's', 'd' depending on data16 prefix (for XMM)
594 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
595 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
597 Many of the above letters print nothing in Intel mode. See "putop"
600 Braces '{' and '}', and vertical bars '|', indicate alternative
601 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
602 modes. In cases where there are only two alternatives, the X86_64
603 instruction is reserved, and "(bad)" is printed.
606 static const struct dis386 dis386
[] = {
608 { "addB", { Eb
, Gb
} },
609 { "addS", { Ev
, Gv
} },
610 { "addB", { Gb
, Eb
} },
611 { "addS", { Gv
, Ev
} },
612 { "addB", { AL
, Ib
} },
613 { "addS", { eAX
, Iv
} },
614 { "push{T|}", { es
} },
615 { "pop{T|}", { es
} },
617 { "orB", { Eb
, Gb
} },
618 { "orS", { Ev
, Gv
} },
619 { "orB", { Gb
, Eb
} },
620 { "orS", { Gv
, Ev
} },
621 { "orB", { AL
, Ib
} },
622 { "orS", { eAX
, Iv
} },
623 { "push{T|}", { cs
} },
624 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
626 { "adcB", { Eb
, Gb
} },
627 { "adcS", { Ev
, Gv
} },
628 { "adcB", { Gb
, Eb
} },
629 { "adcS", { Gv
, Ev
} },
630 { "adcB", { AL
, Ib
} },
631 { "adcS", { eAX
, Iv
} },
632 { "push{T|}", { ss
} },
633 { "pop{T|}", { ss
} },
635 { "sbbB", { Eb
, Gb
} },
636 { "sbbS", { Ev
, Gv
} },
637 { "sbbB", { Gb
, Eb
} },
638 { "sbbS", { Gv
, Ev
} },
639 { "sbbB", { AL
, Ib
} },
640 { "sbbS", { eAX
, Iv
} },
641 { "push{T|}", { ds
} },
642 { "pop{T|}", { ds
} },
644 { "andB", { Eb
, Gb
} },
645 { "andS", { Ev
, Gv
} },
646 { "andB", { Gb
, Eb
} },
647 { "andS", { Gv
, Ev
} },
648 { "andB", { AL
, Ib
} },
649 { "andS", { eAX
, Iv
} },
650 { "(bad)", { XX
} }, /* SEG ES prefix */
651 { "daa{|}", { XX
} },
653 { "subB", { Eb
, Gb
} },
654 { "subS", { Ev
, Gv
} },
655 { "subB", { Gb
, Eb
} },
656 { "subS", { Gv
, Ev
} },
657 { "subB", { AL
, Ib
} },
658 { "subS", { eAX
, Iv
} },
659 { "(bad)", { XX
} }, /* SEG CS prefix */
660 { "das{|}", { XX
} },
662 { "xorB", { Eb
, Gb
} },
663 { "xorS", { Ev
, Gv
} },
664 { "xorB", { Gb
, Eb
} },
665 { "xorS", { Gv
, Ev
} },
666 { "xorB", { AL
, Ib
} },
667 { "xorS", { eAX
, Iv
} },
668 { "(bad)", { XX
} }, /* SEG SS prefix */
669 { "aaa{|}", { XX
} },
671 { "cmpB", { Eb
, Gb
} },
672 { "cmpS", { Ev
, Gv
} },
673 { "cmpB", { Gb
, Eb
} },
674 { "cmpS", { Gv
, Ev
} },
675 { "cmpB", { AL
, Ib
} },
676 { "cmpS", { eAX
, Iv
} },
677 { "(bad)", { XX
} }, /* SEG DS prefix */
678 { "aas{|}", { XX
} },
680 { "inc{S|}", { RMeAX
} },
681 { "inc{S|}", { RMeCX
} },
682 { "inc{S|}", { RMeDX
} },
683 { "inc{S|}", { RMeBX
} },
684 { "inc{S|}", { RMeSP
} },
685 { "inc{S|}", { RMeBP
} },
686 { "inc{S|}", { RMeSI
} },
687 { "inc{S|}", { RMeDI
} },
689 { "dec{S|}", { RMeAX
} },
690 { "dec{S|}", { RMeCX
} },
691 { "dec{S|}", { RMeDX
} },
692 { "dec{S|}", { RMeBX
} },
693 { "dec{S|}", { RMeSP
} },
694 { "dec{S|}", { RMeBP
} },
695 { "dec{S|}", { RMeSI
} },
696 { "dec{S|}", { RMeDI
} },
698 { "pushV", { RMrAX
} },
699 { "pushV", { RMrCX
} },
700 { "pushV", { RMrDX
} },
701 { "pushV", { RMrBX
} },
702 { "pushV", { RMrSP
} },
703 { "pushV", { RMrBP
} },
704 { "pushV", { RMrSI
} },
705 { "pushV", { RMrDI
} },
707 { "popV", { RMrAX
} },
708 { "popV", { RMrCX
} },
709 { "popV", { RMrDX
} },
710 { "popV", { RMrBX
} },
711 { "popV", { RMrSP
} },
712 { "popV", { RMrBP
} },
713 { "popV", { RMrSI
} },
714 { "popV", { RMrDI
} },
720 { "(bad)", { XX
} }, /* seg fs */
721 { "(bad)", { XX
} }, /* seg gs */
722 { "(bad)", { XX
} }, /* op size prefix */
723 { "(bad)", { XX
} }, /* adr size prefix */
726 { "imulS", { Gv
, Ev
, Iv
} },
727 { "pushT", { sIb
} },
728 { "imulS", { Gv
, Ev
, sIb
} },
729 { "ins{b||b|}", { Ybr
, indirDX
} },
730 { "ins{R||G|}", { Yzr
, indirDX
} },
731 { "outs{b||b|}", { indirDXr
, Xb
} },
732 { "outs{R||G|}", { indirDXr
, Xz
} },
734 { "joH", { Jb
, XX
, cond_jump_flag
} },
735 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
736 { "jbH", { Jb
, XX
, cond_jump_flag
} },
737 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
738 { "jeH", { Jb
, XX
, cond_jump_flag
} },
739 { "jneH", { Jb
, XX
, cond_jump_flag
} },
740 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
741 { "jaH", { Jb
, XX
, cond_jump_flag
} },
743 { "jsH", { Jb
, XX
, cond_jump_flag
} },
744 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
745 { "jpH", { Jb
, XX
, cond_jump_flag
} },
746 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
747 { "jlH", { Jb
, XX
, cond_jump_flag
} },
748 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
749 { "jleH", { Jb
, XX
, cond_jump_flag
} },
750 { "jgH", { Jb
, XX
, cond_jump_flag
} },
756 { "testB", { Eb
, Gb
} },
757 { "testS", { Ev
, Gv
} },
758 { "xchgB", { Eb
, Gb
} },
759 { "xchgS", { Ev
, Gv
} },
761 { "movB", { Eb
, Gb
} },
762 { "movS", { Ev
, Gv
} },
763 { "movB", { Gb
, Eb
} },
764 { "movS", { Gv
, Ev
} },
765 { "movD", { Sv
, Sw
} },
766 { "leaS", { Gv
, M
} },
767 { "movD", { Sw
, Sv
} },
771 { "xchgS", { RMeCX
, eAX
} },
772 { "xchgS", { RMeDX
, eAX
} },
773 { "xchgS", { RMeBX
, eAX
} },
774 { "xchgS", { RMeSP
, eAX
} },
775 { "xchgS", { RMeBP
, eAX
} },
776 { "xchgS", { RMeSI
, eAX
} },
777 { "xchgS", { RMeDI
, eAX
} },
779 { "cW{t||t|}R", { XX
} },
780 { "cR{t||t|}O", { XX
} },
781 { "Jcall{T|}", { Ap
} },
782 { "(bad)", { XX
} }, /* fwait */
783 { "pushfT", { XX
} },
785 { "sahf{|}", { XX
} },
786 { "lahf{|}", { XX
} },
788 { "movB", { AL
, Ob
} },
789 { "movS", { eAX
, Ov
} },
790 { "movB", { Ob
, AL
} },
791 { "movS", { Ov
, eAX
} },
792 { "movs{b||b|}", { Ybr
, Xb
} },
793 { "movs{R||R|}", { Yvr
, Xv
} },
794 { "cmps{b||b|}", { Xb
, Yb
} },
795 { "cmps{R||R|}", { Xv
, Yv
} },
797 { "testB", { AL
, Ib
} },
798 { "testS", { eAX
, Iv
} },
799 { "stosB", { Ybr
, AL
} },
800 { "stosS", { Yvr
, eAX
} },
801 { "lodsB", { ALr
, Xb
} },
802 { "lodsS", { eAXr
, Xv
} },
803 { "scasB", { AL
, Yb
} },
804 { "scasS", { eAX
, Yv
} },
806 { "movB", { RMAL
, Ib
} },
807 { "movB", { RMCL
, Ib
} },
808 { "movB", { RMDL
, Ib
} },
809 { "movB", { RMBL
, Ib
} },
810 { "movB", { RMAH
, Ib
} },
811 { "movB", { RMCH
, Ib
} },
812 { "movB", { RMDH
, Ib
} },
813 { "movB", { RMBH
, Ib
} },
815 { "movS", { RMeAX
, Iv64
} },
816 { "movS", { RMeCX
, Iv64
} },
817 { "movS", { RMeDX
, Iv64
} },
818 { "movS", { RMeBX
, Iv64
} },
819 { "movS", { RMeSP
, Iv64
} },
820 { "movS", { RMeBP
, Iv64
} },
821 { "movS", { RMeSI
, Iv64
} },
822 { "movS", { RMeDI
, Iv64
} },
828 { "les{S|}", { Gv
, Mp
} },
829 { "ldsS", { Gv
, Mp
} },
833 { "enterT", { Iw
, Ib
} },
834 { "leaveT", { XX
} },
839 { "into{|}", { XX
} },
846 { "aam{|}", { sIb
} },
847 { "aad{|}", { sIb
} },
849 { "xlat", { DSBX
} },
860 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
861 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
862 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
863 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
864 { "inB", { AL
, Ib
} },
865 { "inG", { zAX
, Ib
} },
866 { "outB", { Ib
, AL
} },
867 { "outG", { Ib
, zAX
} },
871 { "Jjmp{T|}", { Ap
} },
873 { "inB", { AL
, indirDX
} },
874 { "inG", { zAX
, indirDX
} },
875 { "outB", { indirDX
, AL
} },
876 { "outG", { indirDX
, zAX
} },
878 { "(bad)", { XX
} }, /* lock prefix */
880 { "(bad)", { XX
} }, /* repne */
881 { "(bad)", { XX
} }, /* repz */
897 static const struct dis386 dis386_twobyte
[] = {
901 { "larS", { Gv
, Ew
} },
902 { "lslS", { Gv
, Ew
} },
904 { "syscall", { XX
} },
906 { "sysretP", { XX
} },
909 { "wbinvd", { XX
} },
915 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
920 { "movlpX", { EXq
, XM
, { SIMD_Fixup
, 'h' } } },
921 { "unpcklpX", { XM
, EXq
} },
922 { "unpckhpX", { XM
, EXq
} },
924 { "movhpX", { EXq
, XM
, { SIMD_Fixup
, 'l' } } },
935 { "movZ", { Rm
, Cm
} },
936 { "movZ", { Rm
, Dm
} },
937 { "movZ", { Cm
, Rm
} },
938 { "movZ", { Dm
, Rm
} },
939 { "movL", { Rd
, Td
} },
941 { "movL", { Td
, Rd
} },
944 { "movapX", { XM
, EXx
} },
945 { "movapX", { EXx
, XM
} },
957 { "sysenter", { XX
} },
958 { "sysexit", { XX
} },
971 { "cmovo", { Gv
, Ev
} },
972 { "cmovno", { Gv
, Ev
} },
973 { "cmovb", { Gv
, Ev
} },
974 { "cmovae", { Gv
, Ev
} },
975 { "cmove", { Gv
, Ev
} },
976 { "cmovne", { Gv
, Ev
} },
977 { "cmovbe", { Gv
, Ev
} },
978 { "cmova", { Gv
, Ev
} },
980 { "cmovs", { Gv
, Ev
} },
981 { "cmovns", { Gv
, Ev
} },
982 { "cmovp", { Gv
, Ev
} },
983 { "cmovnp", { Gv
, Ev
} },
984 { "cmovl", { Gv
, Ev
} },
985 { "cmovge", { Gv
, Ev
} },
986 { "cmovle", { Gv
, Ev
} },
987 { "cmovg", { Gv
, Ev
} },
989 { "movmskpX", { Gdq
, XS
} },
993 { "andpX", { XM
, EXx
} },
994 { "andnpX", { XM
, EXx
} },
995 { "orpX", { XM
, EXx
} },
996 { "xorpX", { XM
, EXx
} },
1010 { "packsswb", { MX
, EM
} },
1011 { "pcmpgtb", { MX
, EM
} },
1012 { "pcmpgtw", { MX
, EM
} },
1013 { "pcmpgtd", { MX
, EM
} },
1014 { "packuswb", { MX
, EM
} },
1016 { "punpckhbw", { MX
, EM
} },
1017 { "punpckhwd", { MX
, EM
} },
1018 { "punpckhdq", { MX
, EM
} },
1019 { "packssdw", { MX
, EM
} },
1022 { "movd", { MX
, Edq
} },
1029 { "pcmpeqb", { MX
, EM
} },
1030 { "pcmpeqw", { MX
, EM
} },
1031 { "pcmpeqd", { MX
, EM
} },
1036 { "(bad)", { XX
} },
1037 { "(bad)", { XX
} },
1043 { "joH", { Jv
, XX
, cond_jump_flag
} },
1044 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1045 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1046 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1047 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1048 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1049 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1050 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1052 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1053 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1054 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1055 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1056 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1057 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1058 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1059 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1062 { "setno", { Eb
} },
1064 { "setae", { Eb
} },
1066 { "setne", { Eb
} },
1067 { "setbe", { Eb
} },
1071 { "setns", { Eb
} },
1073 { "setnp", { Eb
} },
1075 { "setge", { Eb
} },
1076 { "setle", { Eb
} },
1079 { "pushT", { fs
} },
1081 { "cpuid", { XX
} },
1082 { "btS", { Ev
, Gv
} },
1083 { "shldS", { Ev
, Gv
, Ib
} },
1084 { "shldS", { Ev
, Gv
, CL
} },
1088 { "pushT", { gs
} },
1091 { "btsS", { Ev
, Gv
} },
1092 { "shrdS", { Ev
, Gv
, Ib
} },
1093 { "shrdS", { Ev
, Gv
, CL
} },
1095 { "imulS", { Gv
, Ev
} },
1097 { "cmpxchgB", { Eb
, Gb
} },
1098 { "cmpxchgS", { Ev
, Gv
} },
1099 { "lssS", { Gv
, Mp
} },
1100 { "btrS", { Ev
, Gv
} },
1101 { "lfsS", { Gv
, Mp
} },
1102 { "lgsS", { Gv
, Mp
} },
1103 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1104 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1109 { "btcS", { Ev
, Gv
} },
1110 { "bsfS", { Gv
, Ev
} },
1112 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1113 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1115 { "xaddB", { Eb
, Gb
} },
1116 { "xaddS", { Ev
, Gv
} },
1118 { "movntiS", { Ev
, Gv
} },
1119 { "pinsrw", { MX
, Edqw
, Ib
} },
1120 { "pextrw", { Gdq
, MS
, Ib
} },
1121 { "shufpX", { XM
, EXx
, Ib
} },
1124 { "bswap", { RMeAX
} },
1125 { "bswap", { RMeCX
} },
1126 { "bswap", { RMeDX
} },
1127 { "bswap", { RMeBX
} },
1128 { "bswap", { RMeSP
} },
1129 { "bswap", { RMeBP
} },
1130 { "bswap", { RMeSI
} },
1131 { "bswap", { RMeDI
} },
1134 { "psrlw", { MX
, EM
} },
1135 { "psrld", { MX
, EM
} },
1136 { "psrlq", { MX
, EM
} },
1137 { "paddq", { MX
, EM
} },
1138 { "pmullw", { MX
, EM
} },
1140 { "pmovmskb", { Gdq
, MS
} },
1142 { "psubusb", { MX
, EM
} },
1143 { "psubusw", { MX
, EM
} },
1144 { "pminub", { MX
, EM
} },
1145 { "pand", { MX
, EM
} },
1146 { "paddusb", { MX
, EM
} },
1147 { "paddusw", { MX
, EM
} },
1148 { "pmaxub", { MX
, EM
} },
1149 { "pandn", { MX
, EM
} },
1151 { "pavgb", { MX
, EM
} },
1152 { "psraw", { MX
, EM
} },
1153 { "psrad", { MX
, EM
} },
1154 { "pavgw", { MX
, EM
} },
1155 { "pmulhuw", { MX
, EM
} },
1156 { "pmulhw", { MX
, EM
} },
1160 { "psubsb", { MX
, EM
} },
1161 { "psubsw", { MX
, EM
} },
1162 { "pminsw", { MX
, EM
} },
1163 { "por", { MX
, EM
} },
1164 { "paddsb", { MX
, EM
} },
1165 { "paddsw", { MX
, EM
} },
1166 { "pmaxsw", { MX
, EM
} },
1167 { "pxor", { MX
, EM
} },
1170 { "psllw", { MX
, EM
} },
1171 { "pslld", { MX
, EM
} },
1172 { "psllq", { MX
, EM
} },
1173 { "pmuludq", { MX
, EM
} },
1174 { "pmaddwd", { MX
, EM
} },
1175 { "psadbw", { MX
, EM
} },
1178 { "psubb", { MX
, EM
} },
1179 { "psubw", { MX
, EM
} },
1180 { "psubd", { MX
, EM
} },
1181 { "psubq", { MX
, EM
} },
1182 { "paddb", { MX
, EM
} },
1183 { "paddw", { MX
, EM
} },
1184 { "paddd", { MX
, EM
} },
1185 { "(bad)", { XX
} },
1188 static const unsigned char onebyte_has_modrm
[256] = {
1189 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1190 /* ------------------------------- */
1191 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1192 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1193 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1194 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1195 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1196 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1197 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1198 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1199 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1200 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1201 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1202 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1203 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1204 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1205 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1206 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1207 /* ------------------------------- */
1208 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1211 static const unsigned char twobyte_has_modrm
[256] = {
1212 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1213 /* ------------------------------- */
1214 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1215 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1216 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1217 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1218 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1219 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1220 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1221 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1222 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1223 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1224 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1225 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1226 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1227 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1228 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1229 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1230 /* ------------------------------- */
1231 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1234 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1235 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1236 /* ------------------------------- */
1237 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1238 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1239 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1240 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1241 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1242 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1243 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1244 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1245 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1246 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1247 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1248 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1249 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1250 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1251 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1252 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1253 /* ------------------------------- */
1254 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1257 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1258 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1259 /* ------------------------------- */
1260 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1261 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1262 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1263 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1264 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1265 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1266 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1267 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1268 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1269 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1270 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1271 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1272 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1273 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1274 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1275 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1276 /* ------------------------------- */
1277 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1280 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1281 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1282 /* ------------------------------- */
1283 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1284 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1285 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1286 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1287 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1288 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1289 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1290 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1291 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1292 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1293 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1294 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1295 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1296 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1297 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1298 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1299 /* ------------------------------- */
1300 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1303 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1304 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1305 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1306 /* ------------------------------- */
1307 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1308 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1309 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1310 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1311 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1312 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1313 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1314 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1315 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1316 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1317 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1318 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1319 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1320 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1321 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1322 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1323 /* ------------------------------- */
1324 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1327 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1328 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1329 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1330 /* ------------------------------- */
1331 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1332 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1333 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1334 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1335 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1336 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1337 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1338 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1339 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1340 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1341 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1342 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1343 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1344 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1345 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1346 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1347 /* ------------------------------- */
1348 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1351 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1352 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1353 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1354 /* ------------------------------- */
1355 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1356 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1357 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1358 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1359 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1360 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1361 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1362 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1363 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1364 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1365 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1366 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1367 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1368 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1369 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1370 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1371 /* ------------------------------- */
1372 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1375 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1376 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1377 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1378 /* ------------------------------- */
1379 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1380 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1381 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1382 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1383 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1384 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1385 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1386 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1387 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1388 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1389 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1390 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1391 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1392 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1393 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1394 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1395 /* ------------------------------- */
1396 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1399 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1400 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1401 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1402 /* ------------------------------- */
1403 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1404 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1405 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1406 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1407 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1408 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1409 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1410 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1411 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1412 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1413 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1414 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1415 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1416 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1417 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1418 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1419 /* ------------------------------- */
1420 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1423 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1424 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1425 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1426 /* ------------------------------- */
1427 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1428 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1429 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1430 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1431 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1432 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1433 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1434 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1435 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1436 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1437 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1438 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1439 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1440 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1441 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1442 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1443 /* ------------------------------- */
1444 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1447 static char obuf
[100];
1449 static char scratchbuf
[100];
1450 static unsigned char *start_codep
;
1451 static unsigned char *insn_codep
;
1452 static unsigned char *codep
;
1453 static disassemble_info
*the_info
;
1461 static unsigned char need_modrm
;
1463 /* If we are accessing mod/rm/reg without need_modrm set, then the
1464 values are stale. Hitting this abort likely indicates that you
1465 need to update onebyte_has_modrm or twobyte_has_modrm. */
1466 #define MODRM_CHECK if (!need_modrm) abort ()
1468 static const char **names64
;
1469 static const char **names32
;
1470 static const char **names16
;
1471 static const char **names8
;
1472 static const char **names8rex
;
1473 static const char **names_seg
;
1474 static const char **index16
;
1476 static const char *intel_names64
[] = {
1477 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1478 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1480 static const char *intel_names32
[] = {
1481 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1482 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1484 static const char *intel_names16
[] = {
1485 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1486 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1488 static const char *intel_names8
[] = {
1489 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1491 static const char *intel_names8rex
[] = {
1492 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1493 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1495 static const char *intel_names_seg
[] = {
1496 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1498 static const char *intel_index16
[] = {
1499 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1502 static const char *att_names64
[] = {
1503 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1504 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1506 static const char *att_names32
[] = {
1507 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1508 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1510 static const char *att_names16
[] = {
1511 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1512 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1514 static const char *att_names8
[] = {
1515 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1517 static const char *att_names8rex
[] = {
1518 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1519 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1521 static const char *att_names_seg
[] = {
1522 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1524 static const char *att_index16
[] = {
1525 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1528 static const struct dis386 grps
[][8] = {
1531 { "popU", { stackEv
} },
1532 { "(bad)", { XX
} },
1533 { "(bad)", { XX
} },
1534 { "(bad)", { XX
} },
1535 { "(bad)", { XX
} },
1536 { "(bad)", { XX
} },
1537 { "(bad)", { XX
} },
1538 { "(bad)", { XX
} },
1542 { "addA", { Eb
, Ib
} },
1543 { "orA", { Eb
, Ib
} },
1544 { "adcA", { Eb
, Ib
} },
1545 { "sbbA", { Eb
, Ib
} },
1546 { "andA", { Eb
, Ib
} },
1547 { "subA", { Eb
, Ib
} },
1548 { "xorA", { Eb
, Ib
} },
1549 { "cmpA", { Eb
, Ib
} },
1553 { "addQ", { Ev
, Iv
} },
1554 { "orQ", { Ev
, Iv
} },
1555 { "adcQ", { Ev
, Iv
} },
1556 { "sbbQ", { Ev
, Iv
} },
1557 { "andQ", { Ev
, Iv
} },
1558 { "subQ", { Ev
, Iv
} },
1559 { "xorQ", { Ev
, Iv
} },
1560 { "cmpQ", { Ev
, Iv
} },
1564 { "addQ", { Ev
, sIb
} },
1565 { "orQ", { Ev
, sIb
} },
1566 { "adcQ", { Ev
, sIb
} },
1567 { "sbbQ", { Ev
, sIb
} },
1568 { "andQ", { Ev
, sIb
} },
1569 { "subQ", { Ev
, sIb
} },
1570 { "xorQ", { Ev
, sIb
} },
1571 { "cmpQ", { Ev
, sIb
} },
1575 { "rolA", { Eb
, Ib
} },
1576 { "rorA", { Eb
, Ib
} },
1577 { "rclA", { Eb
, Ib
} },
1578 { "rcrA", { Eb
, Ib
} },
1579 { "shlA", { Eb
, Ib
} },
1580 { "shrA", { Eb
, Ib
} },
1581 { "(bad)", { XX
} },
1582 { "sarA", { Eb
, Ib
} },
1586 { "rolQ", { Ev
, Ib
} },
1587 { "rorQ", { Ev
, Ib
} },
1588 { "rclQ", { Ev
, Ib
} },
1589 { "rcrQ", { Ev
, Ib
} },
1590 { "shlQ", { Ev
, Ib
} },
1591 { "shrQ", { Ev
, Ib
} },
1592 { "(bad)", { XX
} },
1593 { "sarQ", { Ev
, Ib
} },
1597 { "rolA", { Eb
, I1
} },
1598 { "rorA", { Eb
, I1
} },
1599 { "rclA", { Eb
, I1
} },
1600 { "rcrA", { Eb
, I1
} },
1601 { "shlA", { Eb
, I1
} },
1602 { "shrA", { Eb
, I1
} },
1603 { "(bad)", { XX
} },
1604 { "sarA", { Eb
, I1
} },
1608 { "rolQ", { Ev
, I1
} },
1609 { "rorQ", { Ev
, I1
} },
1610 { "rclQ", { Ev
, I1
} },
1611 { "rcrQ", { Ev
, I1
} },
1612 { "shlQ", { Ev
, I1
} },
1613 { "shrQ", { Ev
, I1
} },
1614 { "(bad)", { XX
} },
1615 { "sarQ", { Ev
, I1
} },
1619 { "rolA", { Eb
, CL
} },
1620 { "rorA", { Eb
, CL
} },
1621 { "rclA", { Eb
, CL
} },
1622 { "rcrA", { Eb
, CL
} },
1623 { "shlA", { Eb
, CL
} },
1624 { "shrA", { Eb
, CL
} },
1625 { "(bad)", { XX
} },
1626 { "sarA", { Eb
, CL
} },
1630 { "rolQ", { Ev
, CL
} },
1631 { "rorQ", { Ev
, CL
} },
1632 { "rclQ", { Ev
, CL
} },
1633 { "rcrQ", { Ev
, CL
} },
1634 { "shlQ", { Ev
, CL
} },
1635 { "shrQ", { Ev
, CL
} },
1636 { "(bad)", { XX
} },
1637 { "sarQ", { Ev
, CL
} },
1641 { "testA", { Eb
, Ib
} },
1642 { "(bad)", { Eb
} },
1645 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1646 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1647 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1648 { "idivA", { Eb
} }, /* and idiv for consistency. */
1652 { "testQ", { Ev
, Iv
} },
1653 { "(bad)", { XX
} },
1656 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1657 { "imulQ", { Ev
} },
1659 { "idivQ", { Ev
} },
1665 { "(bad)", { XX
} },
1666 { "(bad)", { XX
} },
1667 { "(bad)", { XX
} },
1668 { "(bad)", { XX
} },
1669 { "(bad)", { XX
} },
1670 { "(bad)", { XX
} },
1676 { "callT", { indirEv
} },
1677 { "JcallT", { indirEp
} },
1678 { "jmpT", { indirEv
} },
1679 { "JjmpT", { indirEp
} },
1680 { "pushU", { stackEv
} },
1681 { "(bad)", { XX
} },
1685 { "sldtD", { Sv
} },
1691 { "(bad)", { XX
} },
1692 { "(bad)", { XX
} },
1696 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1697 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1698 { "lgdt{Q|Q||}", { M
} },
1699 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1700 { "smswD", { Sv
} },
1701 { "(bad)", { XX
} },
1703 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1707 { "(bad)", { XX
} },
1708 { "(bad)", { XX
} },
1709 { "(bad)", { XX
} },
1710 { "(bad)", { XX
} },
1711 { "btQ", { Ev
, Ib
} },
1712 { "btsQ", { Ev
, Ib
} },
1713 { "btrQ", { Ev
, Ib
} },
1714 { "btcQ", { Ev
, Ib
} },
1718 { "(bad)", { XX
} },
1719 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1720 { "(bad)", { XX
} },
1721 { "(bad)", { XX
} },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1724 { "", { VM
} }, /* See OP_VMX. */
1725 { "vmptrst", { Mq
} },
1729 { "movA", { Eb
, Ib
} },
1730 { "(bad)", { XX
} },
1731 { "(bad)", { XX
} },
1732 { "(bad)", { XX
} },
1733 { "(bad)", { XX
} },
1734 { "(bad)", { XX
} },
1735 { "(bad)", { XX
} },
1736 { "(bad)", { XX
} },
1740 { "movQ", { Ev
, Iv
} },
1741 { "(bad)", { XX
} },
1742 { "(bad)", { XX
} },
1743 { "(bad)", { XX
} },
1744 { "(bad)", { XX
} },
1745 { "(bad)", { XX
} },
1746 { "(bad)", { XX
} },
1747 { "(bad)", { XX
} },
1751 { "(bad)", { XX
} },
1752 { "(bad)", { XX
} },
1753 { "psrlw", { MS
, Ib
} },
1754 { "(bad)", { XX
} },
1755 { "psraw", { MS
, Ib
} },
1756 { "(bad)", { XX
} },
1757 { "psllw", { MS
, Ib
} },
1758 { "(bad)", { XX
} },
1762 { "(bad)", { XX
} },
1763 { "(bad)", { XX
} },
1764 { "psrld", { MS
, Ib
} },
1765 { "(bad)", { XX
} },
1766 { "psrad", { MS
, Ib
} },
1767 { "(bad)", { XX
} },
1768 { "pslld", { MS
, Ib
} },
1769 { "(bad)", { XX
} },
1773 { "(bad)", { XX
} },
1774 { "(bad)", { XX
} },
1775 { "psrlq", { MS
, Ib
} },
1776 { "psrldq", { MS
, Ib
} },
1777 { "(bad)", { XX
} },
1778 { "(bad)", { XX
} },
1779 { "psllq", { MS
, Ib
} },
1780 { "pslldq", { MS
, Ib
} },
1784 { "fxsave", { Ev
} },
1785 { "fxrstor", { Ev
} },
1786 { "ldmxcsr", { Ev
} },
1787 { "stmxcsr", { Ev
} },
1788 { "(bad)", { XX
} },
1789 { "lfence", { { OP_0fae
, 0 } } },
1790 { "mfence", { { OP_0fae
, 0 } } },
1791 { "clflush", { { OP_0fae
, 0 } } },
1795 { "prefetchnta", { Ev
} },
1796 { "prefetcht0", { Ev
} },
1797 { "prefetcht1", { Ev
} },
1798 { "prefetcht2", { Ev
} },
1799 { "(bad)", { XX
} },
1800 { "(bad)", { XX
} },
1801 { "(bad)", { XX
} },
1802 { "(bad)", { XX
} },
1806 { "prefetch", { Eb
} },
1807 { "prefetchw", { Eb
} },
1808 { "(bad)", { XX
} },
1809 { "(bad)", { XX
} },
1810 { "(bad)", { XX
} },
1811 { "(bad)", { XX
} },
1812 { "(bad)", { XX
} },
1813 { "(bad)", { XX
} },
1817 { "xstore-rng", { { OP_0f07
, 0 } } },
1818 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1819 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1820 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1821 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1822 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1823 { "(bad)", { { OP_0f07
, 0 } } },
1824 { "(bad)", { { OP_0f07
, 0 } } },
1828 { "montmul", { { OP_0f07
, 0 } } },
1829 { "xsha1", { { OP_0f07
, 0 } } },
1830 { "xsha256", { { OP_0f07
, 0 } } },
1831 { "(bad)", { { OP_0f07
, 0 } } },
1832 { "(bad)", { { OP_0f07
, 0 } } },
1833 { "(bad)", { { OP_0f07
, 0 } } },
1834 { "(bad)", { { OP_0f07
, 0 } } },
1835 { "(bad)", { { OP_0f07
, 0 } } },
1839 static const struct dis386 prefix_user_table
[][4] = {
1842 { "addps", { XM
, EXx
} },
1843 { "addss", { XM
, EXd
} },
1844 { "addpd", { XM
, EXx
} },
1845 { "addsd", { XM
, EXq
} },
1849 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1850 { "", { XM
, EXx
, OPSIMD
} },
1851 { "", { XM
, EXx
, OPSIMD
} },
1852 { "", { XM
, EXx
, OPSIMD
} },
1856 { "cvtpi2ps", { XM
, EMC
} },
1857 { "cvtsi2ssY", { XM
, Ev
} },
1858 { "cvtpi2pd", { XM
, EMC
} },
1859 { "cvtsi2sdY", { XM
, Ev
} },
1863 { "cvtps2pi", { MXC
, EXx
} },
1864 { "cvtss2siY", { Gv
, EXx
} },
1865 { "cvtpd2pi", { MXC
, EXx
} },
1866 { "cvtsd2siY", { Gv
, EXx
} },
1870 { "cvttps2pi", { MXC
, EXx
} },
1871 { "cvttss2siY", { Gv
, EXx
} },
1872 { "cvttpd2pi", { MXC
, EXx
} },
1873 { "cvttsd2siY", { Gv
, EXx
} },
1877 { "divps", { XM
, EXx
} },
1878 { "divss", { XM
, EXx
} },
1879 { "divpd", { XM
, EXx
} },
1880 { "divsd", { XM
, EXx
} },
1884 { "maxps", { XM
, EXx
} },
1885 { "maxss", { XM
, EXx
} },
1886 { "maxpd", { XM
, EXx
} },
1887 { "maxsd", { XM
, EXx
} },
1891 { "minps", { XM
, EXx
} },
1892 { "minss", { XM
, EXx
} },
1893 { "minpd", { XM
, EXx
} },
1894 { "minsd", { XM
, EXx
} },
1898 { "movups", { XM
, EXx
} },
1899 { "movss", { XM
, EXx
} },
1900 { "movupd", { XM
, EXx
} },
1901 { "movsd", { XM
, EXx
} },
1905 { "movups", { EXx
, XM
} },
1906 { "movss", { EXx
, XM
} },
1907 { "movupd", { EXx
, XM
} },
1908 { "movsd", { EXx
, XM
} },
1912 { "mulps", { XM
, EXx
} },
1913 { "mulss", { XM
, EXx
} },
1914 { "mulpd", { XM
, EXx
} },
1915 { "mulsd", { XM
, EXx
} },
1919 { "rcpps", { XM
, EXx
} },
1920 { "rcpss", { XM
, EXx
} },
1921 { "(bad)", { XM
, EXx
} },
1922 { "(bad)", { XM
, EXx
} },
1926 { "rsqrtps",{ XM
, EXx
} },
1927 { "rsqrtss",{ XM
, EXx
} },
1928 { "(bad)", { XM
, EXx
} },
1929 { "(bad)", { XM
, EXx
} },
1933 { "sqrtps", { XM
, EXx
} },
1934 { "sqrtss", { XM
, EXx
} },
1935 { "sqrtpd", { XM
, EXx
} },
1936 { "sqrtsd", { XM
, EXx
} },
1940 { "subps", { XM
, EXx
} },
1941 { "subss", { XM
, EXx
} },
1942 { "subpd", { XM
, EXx
} },
1943 { "subsd", { XM
, EXx
} },
1947 { "(bad)", { XM
, EXx
} },
1948 { "cvtdq2pd", { XM
, EXq
} },
1949 { "cvttpd2dq", { XM
, EXx
} },
1950 { "cvtpd2dq", { XM
, EXx
} },
1954 { "cvtdq2ps", { XM
, EXx
} },
1955 { "cvttps2dq", { XM
, EXx
} },
1956 { "cvtps2dq", { XM
, EXx
} },
1957 { "(bad)", { XM
, EXx
} },
1961 { "cvtps2pd", { XM
, EXq
} },
1962 { "cvtss2sd", { XM
, EXx
} },
1963 { "cvtpd2ps", { XM
, EXx
} },
1964 { "cvtsd2ss", { XM
, EXx
} },
1968 { "maskmovq", { MX
, MS
} },
1969 { "(bad)", { XM
, EXx
} },
1970 { "maskmovdqu", { XM
, XS
} },
1971 { "(bad)", { XM
, EXx
} },
1975 { "movq", { MX
, EM
} },
1976 { "movdqu", { XM
, EXx
} },
1977 { "movdqa", { XM
, EXx
} },
1978 { "(bad)", { XM
, EXx
} },
1982 { "movq", { EM
, MX
} },
1983 { "movdqu", { EXx
, XM
} },
1984 { "movdqa", { EXx
, XM
} },
1985 { "(bad)", { EXx
, XM
} },
1989 { "(bad)", { EXx
, XM
} },
1990 { "movq2dq",{ XM
, MS
} },
1991 { "movq", { EXx
, XM
} },
1992 { "movdq2q",{ MX
, XS
} },
1996 { "pshufw", { MX
, EM
, Ib
} },
1997 { "pshufhw",{ XM
, EXx
, Ib
} },
1998 { "pshufd", { XM
, EXx
, Ib
} },
1999 { "pshuflw",{ XM
, EXx
, Ib
} },
2003 { "movd", { Edq
, MX
} },
2004 { "movq", { XM
, EXx
} },
2005 { "movd", { Edq
, XM
} },
2006 { "(bad)", { Ed
, XM
} },
2010 { "(bad)", { MX
, EXx
} },
2011 { "(bad)", { XM
, EXx
} },
2012 { "punpckhqdq", { XM
, EXx
} },
2013 { "(bad)", { XM
, EXx
} },
2017 { "movntq", { EM
, MX
} },
2018 { "(bad)", { EM
, XM
} },
2019 { "movntdq",{ EM
, XM
} },
2020 { "(bad)", { EM
, XM
} },
2024 { "(bad)", { MX
, EXx
} },
2025 { "(bad)", { XM
, EXx
} },
2026 { "punpcklqdq", { XM
, EXx
} },
2027 { "(bad)", { XM
, EXx
} },
2031 { "(bad)", { MX
, EXx
} },
2032 { "(bad)", { XM
, EXx
} },
2033 { "addsubpd", { XM
, EXx
} },
2034 { "addsubps", { XM
, EXx
} },
2038 { "(bad)", { MX
, EXx
} },
2039 { "(bad)", { XM
, EXx
} },
2040 { "haddpd", { XM
, EXx
} },
2041 { "haddps", { XM
, EXx
} },
2045 { "(bad)", { MX
, EXx
} },
2046 { "(bad)", { XM
, EXx
} },
2047 { "hsubpd", { XM
, EXx
} },
2048 { "hsubps", { XM
, EXx
} },
2052 { "movlpX", { XM
, EXq
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
2053 { "movsldup", { XM
, EXx
} },
2054 { "movlpd", { XM
, EXq
} },
2055 { "movddup", { XM
, EXq
} },
2059 { "movhpX", { XM
, EXq
, { SIMD_Fixup
, 'l' } } },
2060 { "movshdup", { XM
, EXx
} },
2061 { "movhpd", { XM
, EXq
} },
2062 { "(bad)", { XM
, EXq
} },
2066 { "(bad)", { XM
, EXx
} },
2067 { "(bad)", { XM
, EXx
} },
2068 { "(bad)", { XM
, EXx
} },
2069 { "lddqu", { XM
, M
} },
2073 {"movntps", { Ev
, XM
} },
2074 {"movntss", { Ev
, XM
} },
2075 {"movntpd", { Ev
, XM
} },
2076 {"movntsd", { Ev
, XM
} },
2081 {"vmread", { Em
, Gm
} },
2083 {"extrq", { XS
, Ib
, Ib
} },
2084 {"insertq", { XM
, XS
, Ib
, Ib
} },
2089 {"vmwrite", { Gm
, Em
} },
2091 {"extrq", { XM
, XS
} },
2092 {"insertq", { XM
, XS
} },
2097 { "bsrS", { Gv
, Ev
} },
2098 { "lzcntS", { Gv
, Ev
} },
2099 { "bsrS", { Gv
, Ev
} },
2100 { "(bad)", { XX
} },
2105 { "(bad)", { XX
} },
2106 { "popcntS", { Gv
, Ev
} },
2107 { "(bad)", { XX
} },
2108 { "(bad)", { XX
} },
2113 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2114 { "pause", { XX
} },
2115 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2116 { "(bad)", { XX
} },
2121 { "(bad)", { XX
} },
2122 { "(bad)", { XX
} },
2123 { "pblendvb", {XM
, EXx
, XMM0
} },
2124 { "(bad)", { XX
} },
2129 { "(bad)", { XX
} },
2130 { "(bad)", { XX
} },
2131 { "blendvps", {XM
, EXx
, XMM0
} },
2132 { "(bad)", { XX
} },
2137 { "(bad)", { XX
} },
2138 { "(bad)", { XX
} },
2139 { "blendvpd", { XM
, EXx
, XMM0
} },
2140 { "(bad)", { XX
} },
2145 { "(bad)", { XX
} },
2146 { "(bad)", { XX
} },
2147 { "ptest", { XM
, EXx
} },
2148 { "(bad)", { XX
} },
2153 { "(bad)", { XX
} },
2154 { "(bad)", { XX
} },
2155 { "pmovsxbw", { XM
, EXx
} },
2156 { "(bad)", { XX
} },
2161 { "(bad)", { XX
} },
2162 { "(bad)", { XX
} },
2163 { "pmovsxbd", { XM
, EXx
} },
2164 { "(bad)", { XX
} },
2169 { "(bad)", { XX
} },
2170 { "(bad)", { XX
} },
2171 { "pmovsxbq", { XM
, EXx
} },
2172 { "(bad)", { XX
} },
2177 { "(bad)", { XX
} },
2178 { "(bad)", { XX
} },
2179 { "pmovsxwd", { XM
, EXx
} },
2180 { "(bad)", { XX
} },
2185 { "(bad)", { XX
} },
2186 { "(bad)", { XX
} },
2187 { "pmovsxwq", { XM
, EXx
} },
2188 { "(bad)", { XX
} },
2193 { "(bad)", { XX
} },
2194 { "(bad)", { XX
} },
2195 { "pmovsxdq", { XM
, EXx
} },
2196 { "(bad)", { XX
} },
2201 { "(bad)", { XX
} },
2202 { "(bad)", { XX
} },
2203 { "pmuldq", { XM
, EXx
} },
2204 { "(bad)", { XX
} },
2209 { "(bad)", { XX
} },
2210 { "(bad)", { XX
} },
2211 { "pcmpeqq", { XM
, EXx
} },
2212 { "(bad)", { XX
} },
2217 { "(bad)", { XX
} },
2218 { "(bad)", { XX
} },
2219 { "movntdqa", { XM
, EM
} },
2220 { "(bad)", { XX
} },
2225 { "(bad)", { XX
} },
2226 { "(bad)", { XX
} },
2227 { "packusdw", { XM
, EXx
} },
2228 { "(bad)", { XX
} },
2233 { "(bad)", { XX
} },
2234 { "(bad)", { XX
} },
2235 { "pmovzxbw", { XM
, EXx
} },
2236 { "(bad)", { XX
} },
2241 { "(bad)", { XX
} },
2242 { "(bad)", { XX
} },
2243 { "pmovzxbd", { XM
, EXx
} },
2244 { "(bad)", { XX
} },
2249 { "(bad)", { XX
} },
2250 { "(bad)", { XX
} },
2251 { "pmovzxbq", { XM
, EXx
} },
2252 { "(bad)", { XX
} },
2257 { "(bad)", { XX
} },
2258 { "(bad)", { XX
} },
2259 { "pmovzxwd", { XM
, EXx
} },
2260 { "(bad)", { XX
} },
2265 { "(bad)", { XX
} },
2266 { "(bad)", { XX
} },
2267 { "pmovzxwq", { XM
, EXx
} },
2268 { "(bad)", { XX
} },
2273 { "(bad)", { XX
} },
2274 { "(bad)", { XX
} },
2275 { "pmovzxdq", { XM
, EXx
} },
2276 { "(bad)", { XX
} },
2281 { "(bad)", { XX
} },
2282 { "(bad)", { XX
} },
2283 { "pminsb", { XM
, EXx
} },
2284 { "(bad)", { XX
} },
2289 { "(bad)", { XX
} },
2290 { "(bad)", { XX
} },
2291 { "pminsd", { XM
, EXx
} },
2292 { "(bad)", { XX
} },
2297 { "(bad)", { XX
} },
2298 { "(bad)", { XX
} },
2299 { "pminuw", { XM
, EXx
} },
2300 { "(bad)", { XX
} },
2305 { "(bad)", { XX
} },
2306 { "(bad)", { XX
} },
2307 { "pminud", { XM
, EXx
} },
2308 { "(bad)", { XX
} },
2313 { "(bad)", { XX
} },
2314 { "(bad)", { XX
} },
2315 { "pmaxsb", { XM
, EXx
} },
2316 { "(bad)", { XX
} },
2321 { "(bad)", { XX
} },
2322 { "(bad)", { XX
} },
2323 { "pmaxsd", { XM
, EXx
} },
2324 { "(bad)", { XX
} },
2329 { "(bad)", { XX
} },
2330 { "(bad)", { XX
} },
2331 { "pmaxuw", { XM
, EXx
} },
2332 { "(bad)", { XX
} },
2337 { "(bad)", { XX
} },
2338 { "(bad)", { XX
} },
2339 { "pmaxud", { XM
, EXx
} },
2340 { "(bad)", { XX
} },
2345 { "(bad)", { XX
} },
2346 { "(bad)", { XX
} },
2347 { "pmulld", { XM
, EXx
} },
2348 { "(bad)", { XX
} },
2353 { "(bad)", { XX
} },
2354 { "(bad)", { XX
} },
2355 { "phminposuw", { XM
, EXx
} },
2356 { "(bad)", { XX
} },
2361 { "(bad)", { XX
} },
2362 { "(bad)", { XX
} },
2363 { "roundps", { XM
, EXx
, Ib
} },
2364 { "(bad)", { XX
} },
2369 { "(bad)", { XX
} },
2370 { "(bad)", { XX
} },
2371 { "roundpd", { XM
, EXx
, Ib
} },
2372 { "(bad)", { XX
} },
2377 { "(bad)", { XX
} },
2378 { "(bad)", { XX
} },
2379 { "roundss", { XM
, EXx
, Ib
} },
2380 { "(bad)", { XX
} },
2385 { "(bad)", { XX
} },
2386 { "(bad)", { XX
} },
2387 { "roundsd", { XM
, EXx
, Ib
} },
2388 { "(bad)", { XX
} },
2393 { "(bad)", { XX
} },
2394 { "(bad)", { XX
} },
2395 { "blendps", { XM
, EXx
, Ib
} },
2396 { "(bad)", { XX
} },
2401 { "(bad)", { XX
} },
2402 { "(bad)", { XX
} },
2403 { "blendpd", { XM
, EXx
, Ib
} },
2404 { "(bad)", { XX
} },
2409 { "(bad)", { XX
} },
2410 { "(bad)", { XX
} },
2411 { "pblendw", { XM
, EXx
, Ib
} },
2412 { "(bad)", { XX
} },
2417 { "(bad)", { XX
} },
2418 { "(bad)", { XX
} },
2419 { "pextrb", { Edqb
, XM
, Ib
} },
2420 { "(bad)", { XX
} },
2425 { "(bad)", { XX
} },
2426 { "(bad)", { XX
} },
2427 { "pextrw", { Edqw
, XM
, Ib
} },
2428 { "(bad)", { XX
} },
2433 { "(bad)", { XX
} },
2434 { "(bad)", { XX
} },
2435 { "pextrK", { Edq
, XM
, Ib
} },
2436 { "(bad)", { XX
} },
2441 { "(bad)", { XX
} },
2442 { "(bad)", { XX
} },
2443 { "extractps", { Edqd
, XM
, Ib
} },
2444 { "(bad)", { XX
} },
2449 { "(bad)", { XX
} },
2450 { "(bad)", { XX
} },
2451 { "pinsrb", { XM
, Edqb
, Ib
} },
2452 { "(bad)", { XX
} },
2457 { "(bad)", { XX
} },
2458 { "(bad)", { XX
} },
2459 { "insertps", { XM
, EXx
, Ib
} },
2460 { "(bad)", { XX
} },
2465 { "(bad)", { XX
} },
2466 { "(bad)", { XX
} },
2467 { "pinsrK", { XM
, Edq
, Ib
} },
2468 { "(bad)", { XX
} },
2473 { "(bad)", { XX
} },
2474 { "(bad)", { XX
} },
2475 { "dpps", { XM
, EXx
, Ib
} },
2476 { "(bad)", { XX
} },
2481 { "(bad)", { XX
} },
2482 { "(bad)", { XX
} },
2483 { "dppd", { XM
, EXx
, Ib
} },
2484 { "(bad)", { XX
} },
2489 { "(bad)", { XX
} },
2490 { "(bad)", { XX
} },
2491 { "mpsadbw", { XM
, EXx
, Ib
} },
2492 { "(bad)", { XX
} },
2497 { "(bad)", { XX
} },
2498 { "(bad)", { XX
} },
2499 { "pcmpgtq", { XM
, EXx
} },
2500 { "(bad)", { XX
} },
2505 { "(bad)", { XX
} },
2506 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2513 { "(bad)", { XX
} },
2514 { "(bad)", { XX
} },
2515 { "(bad)", { XX
} },
2516 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2521 { "(bad)", { XX
} },
2522 { "(bad)", { XX
} },
2523 { "pcmpestrm", { XM
, EXx
, Ib
} },
2524 { "(bad)", { XX
} },
2529 { "(bad)", { XX
} },
2530 { "(bad)", { XX
} },
2531 { "pcmpestri", { XM
, EXx
, Ib
} },
2532 { "(bad)", { XX
} },
2537 { "(bad)", { XX
} },
2538 { "(bad)", { XX
} },
2539 { "pcmpistrm", { XM
, EXx
, Ib
} },
2540 { "(bad)", { XX
} },
2545 { "(bad)", { XX
} },
2546 { "(bad)", { XX
} },
2547 { "pcmpistri", { XM
, EXx
, Ib
} },
2548 { "(bad)", { XX
} },
2553 { "ucomiss",{ XM
, EXd
} },
2554 { "(bad)", { XX
} },
2555 { "ucomisd",{ XM
, EXq
} },
2556 { "(bad)", { XX
} },
2561 { "comiss", { XM
, EXd
} },
2562 { "(bad)", { XX
} },
2563 { "comisd", { XM
, EXq
} },
2564 { "(bad)", { XX
} },
2569 { "punpcklbw",{ MX
, EMd
} },
2570 { "(bad)", { XX
} },
2571 { "punpcklbw",{ MX
, EMq
} },
2572 { "(bad)", { XX
} },
2577 { "punpcklwd",{ MX
, EMd
} },
2578 { "(bad)", { XX
} },
2579 { "punpcklwd",{ MX
, EMq
} },
2580 { "(bad)", { XX
} },
2585 { "punpckldq",{ MX
, EMd
} },
2586 { "(bad)", { XX
} },
2587 { "punpckldq",{ MX
, EMq
} },
2588 { "(bad)", { XX
} },
2592 static const struct dis386 x86_64_table
[][2] = {
2594 { "pusha{P|}", { XX
} },
2595 { "(bad)", { XX
} },
2598 { "popa{P|}", { XX
} },
2599 { "(bad)", { XX
} },
2602 { "bound{S|}", { Gv
, Ma
} },
2603 { "(bad)", { XX
} },
2606 { "arpl", { Ew
, Gw
} },
2607 { "movs{||lq|xd}", { Gv
, Ed
} },
2611 static const struct dis386 three_byte_table
[][256] = {
2615 { "pshufb", { MX
, EM
} },
2616 { "phaddw", { MX
, EM
} },
2617 { "phaddd", { MX
, EM
} },
2618 { "phaddsw", { MX
, EM
} },
2619 { "pmaddubsw", { MX
, EM
} },
2620 { "phsubw", { MX
, EM
} },
2621 { "phsubd", { MX
, EM
} },
2622 { "phsubsw", { MX
, EM
} },
2624 { "psignb", { MX
, EM
} },
2625 { "psignw", { MX
, EM
} },
2626 { "psignd", { MX
, EM
} },
2627 { "pmulhrsw", { MX
, EM
} },
2628 { "(bad)", { XX
} },
2629 { "(bad)", { XX
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2634 { "(bad)", { XX
} },
2635 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2639 { "(bad)", { XX
} },
2642 { "(bad)", { XX
} },
2643 { "(bad)", { XX
} },
2644 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "pabsb", { MX
, EM
} },
2647 { "pabsw", { MX
, EM
} },
2648 { "pabsd", { MX
, EM
} },
2649 { "(bad)", { XX
} },
2657 { "(bad)", { XX
} },
2658 { "(bad)", { XX
} },
2664 { "(bad)", { XX
} },
2665 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2675 { "(bad)", { XX
} },
2689 { "(bad)", { XX
} },
2690 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2696 { "(bad)", { XX
} },
2697 { "(bad)", { XX
} },
2698 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2705 { "(bad)", { XX
} },
2706 { "(bad)", { XX
} },
2707 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2714 { "(bad)", { XX
} },
2715 { "(bad)", { XX
} },
2716 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2723 { "(bad)", { XX
} },
2724 { "(bad)", { XX
} },
2725 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2733 { "(bad)", { XX
} },
2734 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2741 { "(bad)", { XX
} },
2742 { "(bad)", { XX
} },
2743 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2750 { "(bad)", { XX
} },
2751 { "(bad)", { XX
} },
2752 { "(bad)", { XX
} },
2753 { "(bad)", { XX
} },
2754 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2759 { "(bad)", { XX
} },
2760 { "(bad)", { XX
} },
2761 { "(bad)", { XX
} },
2762 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2768 { "(bad)", { XX
} },
2769 { "(bad)", { XX
} },
2770 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2777 { "(bad)", { XX
} },
2778 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "(bad)", { XX
} },
2782 { "(bad)", { XX
} },
2783 { "(bad)", { XX
} },
2784 { "(bad)", { XX
} },
2786 { "(bad)", { XX
} },
2787 { "(bad)", { XX
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2790 { "(bad)", { XX
} },
2791 { "(bad)", { XX
} },
2792 { "(bad)", { XX
} },
2793 { "(bad)", { XX
} },
2795 { "(bad)", { XX
} },
2796 { "(bad)", { XX
} },
2797 { "(bad)", { XX
} },
2798 { "(bad)", { XX
} },
2799 { "(bad)", { XX
} },
2800 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2804 { "(bad)", { XX
} },
2805 { "(bad)", { XX
} },
2806 { "(bad)", { XX
} },
2807 { "(bad)", { XX
} },
2808 { "(bad)", { XX
} },
2809 { "(bad)", { XX
} },
2810 { "(bad)", { XX
} },
2811 { "(bad)", { XX
} },
2813 { "(bad)", { XX
} },
2814 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2817 { "(bad)", { XX
} },
2818 { "(bad)", { XX
} },
2819 { "(bad)", { XX
} },
2820 { "(bad)", { XX
} },
2822 { "(bad)", { XX
} },
2823 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2826 { "(bad)", { XX
} },
2827 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2831 { "(bad)", { XX
} },
2832 { "(bad)", { XX
} },
2833 { "(bad)", { XX
} },
2834 { "(bad)", { XX
} },
2835 { "(bad)", { XX
} },
2836 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2841 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2844 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2849 { "(bad)", { XX
} },
2850 { "(bad)", { XX
} },
2851 { "(bad)", { XX
} },
2852 { "(bad)", { XX
} },
2853 { "(bad)", { XX
} },
2854 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2858 { "(bad)", { XX
} },
2859 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2862 { "(bad)", { XX
} },
2863 { "(bad)", { XX
} },
2864 { "(bad)", { XX
} },
2865 { "(bad)", { XX
} },
2867 { "(bad)", { XX
} },
2868 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2870 { "(bad)", { XX
} },
2871 { "(bad)", { XX
} },
2872 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2876 { "(bad)", { XX
} },
2877 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2879 { "(bad)", { XX
} },
2880 { "(bad)", { XX
} },
2881 { "(bad)", { XX
} },
2882 { "(bad)", { XX
} },
2883 { "(bad)", { XX
} },
2887 { "(bad)", { XX
} },
2888 { "(bad)", { XX
} },
2889 { "(bad)", { XX
} },
2890 { "(bad)", { XX
} },
2891 { "(bad)", { XX
} },
2892 { "(bad)", { XX
} },
2894 { "(bad)", { XX
} },
2895 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2898 { "(bad)", { XX
} },
2899 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2906 { "(bad)", { XX
} },
2907 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2922 { "palignr", { MX
, EM
, Ib
} },
2924 { "(bad)", { XX
} },
2925 { "(bad)", { XX
} },
2926 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2933 { "(bad)", { XX
} },
2934 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2945 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2951 { "(bad)", { XX
} },
2952 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2960 { "(bad)", { XX
} },
2961 { "(bad)", { XX
} },
2962 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2969 { "(bad)", { XX
} },
2970 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2981 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2987 { "(bad)", { XX
} },
2988 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2996 { "(bad)", { XX
} },
2997 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3005 { "(bad)", { XX
} },
3006 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3018 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3023 { "(bad)", { XX
} },
3024 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3032 { "(bad)", { XX
} },
3033 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3041 { "(bad)", { XX
} },
3042 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3050 { "(bad)", { XX
} },
3051 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3059 { "(bad)", { XX
} },
3060 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3068 { "(bad)", { XX
} },
3069 { "(bad)", { XX
} },
3070 { "(bad)", { XX
} },
3071 { "(bad)", { XX
} },
3072 { "(bad)", { XX
} },
3073 { "(bad)", { XX
} },
3074 { "(bad)", { XX
} },
3075 { "(bad)", { XX
} },
3077 { "(bad)", { XX
} },
3078 { "(bad)", { XX
} },
3079 { "(bad)", { XX
} },
3080 { "(bad)", { XX
} },
3081 { "(bad)", { XX
} },
3082 { "(bad)", { XX
} },
3083 { "(bad)", { XX
} },
3084 { "(bad)", { XX
} },
3086 { "(bad)", { XX
} },
3087 { "(bad)", { XX
} },
3088 { "(bad)", { XX
} },
3089 { "(bad)", { XX
} },
3090 { "(bad)", { XX
} },
3091 { "(bad)", { XX
} },
3092 { "(bad)", { XX
} },
3093 { "(bad)", { XX
} },
3095 { "(bad)", { XX
} },
3096 { "(bad)", { XX
} },
3097 { "(bad)", { XX
} },
3098 { "(bad)", { XX
} },
3099 { "(bad)", { XX
} },
3100 { "(bad)", { XX
} },
3101 { "(bad)", { XX
} },
3102 { "(bad)", { XX
} },
3104 { "(bad)", { XX
} },
3105 { "(bad)", { XX
} },
3106 { "(bad)", { XX
} },
3107 { "(bad)", { XX
} },
3108 { "(bad)", { XX
} },
3109 { "(bad)", { XX
} },
3110 { "(bad)", { XX
} },
3111 { "(bad)", { XX
} },
3113 { "(bad)", { XX
} },
3114 { "(bad)", { XX
} },
3115 { "(bad)", { XX
} },
3116 { "(bad)", { XX
} },
3117 { "(bad)", { XX
} },
3118 { "(bad)", { XX
} },
3119 { "(bad)", { XX
} },
3120 { "(bad)", { XX
} },
3122 { "(bad)", { XX
} },
3123 { "(bad)", { XX
} },
3124 { "(bad)", { XX
} },
3125 { "(bad)", { XX
} },
3126 { "(bad)", { XX
} },
3127 { "(bad)", { XX
} },
3128 { "(bad)", { XX
} },
3129 { "(bad)", { XX
} },
3131 { "(bad)", { XX
} },
3132 { "(bad)", { XX
} },
3133 { "(bad)", { XX
} },
3134 { "(bad)", { XX
} },
3135 { "(bad)", { XX
} },
3136 { "(bad)", { XX
} },
3137 { "(bad)", { XX
} },
3138 { "(bad)", { XX
} },
3140 { "(bad)", { XX
} },
3141 { "(bad)", { XX
} },
3142 { "(bad)", { XX
} },
3143 { "(bad)", { XX
} },
3144 { "(bad)", { XX
} },
3145 { "(bad)", { XX
} },
3146 { "(bad)", { XX
} },
3147 { "(bad)", { XX
} },
3149 { "(bad)", { XX
} },
3150 { "(bad)", { XX
} },
3151 { "(bad)", { XX
} },
3152 { "(bad)", { XX
} },
3153 { "(bad)", { XX
} },
3154 { "(bad)", { XX
} },
3155 { "(bad)", { XX
} },
3156 { "(bad)", { XX
} },
3158 { "(bad)", { XX
} },
3159 { "(bad)", { XX
} },
3160 { "(bad)", { XX
} },
3161 { "(bad)", { XX
} },
3162 { "(bad)", { XX
} },
3163 { "(bad)", { XX
} },
3164 { "(bad)", { XX
} },
3165 { "(bad)", { XX
} },
3167 { "(bad)", { XX
} },
3168 { "(bad)", { XX
} },
3169 { "(bad)", { XX
} },
3170 { "(bad)", { XX
} },
3171 { "(bad)", { XX
} },
3172 { "(bad)", { XX
} },
3173 { "(bad)", { XX
} },
3174 { "(bad)", { XX
} },
3176 { "(bad)", { XX
} },
3177 { "(bad)", { XX
} },
3178 { "(bad)", { XX
} },
3179 { "(bad)", { XX
} },
3180 { "(bad)", { XX
} },
3181 { "(bad)", { XX
} },
3182 { "(bad)", { XX
} },
3183 { "(bad)", { XX
} },
3185 { "(bad)", { XX
} },
3186 { "(bad)", { XX
} },
3187 { "(bad)", { XX
} },
3188 { "(bad)", { XX
} },
3189 { "(bad)", { XX
} },
3190 { "(bad)", { XX
} },
3191 { "(bad)", { XX
} },
3192 { "(bad)", { XX
} },
3196 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3208 FETCH_DATA (the_info
, codep
+ 1);
3212 /* REX prefixes family. */
3229 if (address_mode
== mode_64bit
)
3235 prefixes
|= PREFIX_REPZ
;
3238 prefixes
|= PREFIX_REPNZ
;
3241 prefixes
|= PREFIX_LOCK
;
3244 prefixes
|= PREFIX_CS
;
3247 prefixes
|= PREFIX_SS
;
3250 prefixes
|= PREFIX_DS
;
3253 prefixes
|= PREFIX_ES
;
3256 prefixes
|= PREFIX_FS
;
3259 prefixes
|= PREFIX_GS
;
3262 prefixes
|= PREFIX_DATA
;
3265 prefixes
|= PREFIX_ADDR
;
3268 /* fwait is really an instruction. If there are prefixes
3269 before the fwait, they belong to the fwait, *not* to the
3270 following instruction. */
3271 if (prefixes
|| rex
)
3273 prefixes
|= PREFIX_FWAIT
;
3277 prefixes
= PREFIX_FWAIT
;
3282 /* Rex is ignored when followed by another prefix. */
3293 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3297 prefix_name (int pref
, int sizeflag
)
3299 static const char *rexes
[16] =
3304 "rex.XB", /* 0x43 */
3306 "rex.RB", /* 0x45 */
3307 "rex.RX", /* 0x46 */
3308 "rex.RXB", /* 0x47 */
3310 "rex.WB", /* 0x49 */
3311 "rex.WX", /* 0x4a */
3312 "rex.WXB", /* 0x4b */
3313 "rex.WR", /* 0x4c */
3314 "rex.WRB", /* 0x4d */
3315 "rex.WRX", /* 0x4e */
3316 "rex.WRXB", /* 0x4f */
3321 /* REX prefixes family. */
3338 return rexes
[pref
- 0x40];
3358 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3360 if (address_mode
== mode_64bit
)
3361 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3363 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3371 static char op_out
[MAX_OPERANDS
][100];
3372 static int op_ad
, op_index
[MAX_OPERANDS
];
3373 static int two_source_ops
;
3374 static bfd_vma op_address
[MAX_OPERANDS
];
3375 static bfd_vma op_riprel
[MAX_OPERANDS
];
3376 static bfd_vma start_pc
;
3379 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3380 * (see topic "Redundant prefixes" in the "Differences from 8086"
3381 * section of the "Virtual 8086 Mode" chapter.)
3382 * 'pc' should be the address of this instruction, it will
3383 * be used to print the target address if this is a relative jump or call
3384 * The function returns the length of this instruction in bytes.
3387 static char intel_syntax
;
3388 static char open_char
;
3389 static char close_char
;
3390 static char separator_char
;
3391 static char scale_char
;
3393 /* Here for backwards compatibility. When gdb stops using
3394 print_insn_i386_att and print_insn_i386_intel these functions can
3395 disappear, and print_insn_i386 be merged into print_insn. */
3397 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3401 return print_insn (pc
, info
);
3405 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3409 return print_insn (pc
, info
);
3413 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3417 return print_insn (pc
, info
);
3421 print_i386_disassembler_options (FILE *stream
)
3423 fprintf (stream
, _("\n\
3424 The following i386/x86-64 specific disassembler options are supported for use\n\
3425 with the -M switch (multiple options should be separated by commas):\n"));
3427 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3428 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3429 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3430 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3431 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3432 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3433 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3434 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3435 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3436 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3437 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3441 print_insn (bfd_vma pc
, disassemble_info
*info
)
3443 const struct dis386
*dp
;
3445 char *op_txt
[MAX_OPERANDS
];
3447 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
3448 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
3451 struct dis_private priv
;
3454 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3455 || info
->mach
== bfd_mach_x86_64
)
3456 address_mode
= mode_64bit
;
3458 address_mode
= mode_32bit
;
3460 if (intel_syntax
== (char) -1)
3461 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3462 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3464 if (info
->mach
== bfd_mach_i386_i386
3465 || info
->mach
== bfd_mach_x86_64
3466 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3467 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3468 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3469 else if (info
->mach
== bfd_mach_i386_i8086
)
3470 priv
.orig_sizeflag
= 0;
3474 for (p
= info
->disassembler_options
; p
!= NULL
; )
3476 if (CONST_STRNEQ (p
, "x86-64"))
3478 address_mode
= mode_64bit
;
3479 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3481 else if (CONST_STRNEQ (p
, "i386"))
3483 address_mode
= mode_32bit
;
3484 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3486 else if (CONST_STRNEQ (p
, "i8086"))
3488 address_mode
= mode_16bit
;
3489 priv
.orig_sizeflag
= 0;
3491 else if (CONST_STRNEQ (p
, "intel"))
3495 else if (CONST_STRNEQ (p
, "att"))
3499 else if (CONST_STRNEQ (p
, "addr"))
3501 if (address_mode
== mode_64bit
)
3503 if (p
[4] == '3' && p
[5] == '2')
3504 priv
.orig_sizeflag
&= ~AFLAG
;
3505 else if (p
[4] == '6' && p
[5] == '4')
3506 priv
.orig_sizeflag
|= AFLAG
;
3510 if (p
[4] == '1' && p
[5] == '6')
3511 priv
.orig_sizeflag
&= ~AFLAG
;
3512 else if (p
[4] == '3' && p
[5] == '2')
3513 priv
.orig_sizeflag
|= AFLAG
;
3516 else if (CONST_STRNEQ (p
, "data"))
3518 if (p
[4] == '1' && p
[5] == '6')
3519 priv
.orig_sizeflag
&= ~DFLAG
;
3520 else if (p
[4] == '3' && p
[5] == '2')
3521 priv
.orig_sizeflag
|= DFLAG
;
3523 else if (CONST_STRNEQ (p
, "suffix"))
3524 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3526 p
= strchr (p
, ',');
3533 names64
= intel_names64
;
3534 names32
= intel_names32
;
3535 names16
= intel_names16
;
3536 names8
= intel_names8
;
3537 names8rex
= intel_names8rex
;
3538 names_seg
= intel_names_seg
;
3539 index16
= intel_index16
;
3542 separator_char
= '+';
3547 names64
= att_names64
;
3548 names32
= att_names32
;
3549 names16
= att_names16
;
3550 names8
= att_names8
;
3551 names8rex
= att_names8rex
;
3552 names_seg
= att_names_seg
;
3553 index16
= att_index16
;
3556 separator_char
= ',';
3560 /* The output looks better if we put 7 bytes on a line, since that
3561 puts most long word instructions on a single line. */
3562 info
->bytes_per_line
= 7;
3564 info
->private_data
= &priv
;
3565 priv
.max_fetched
= priv
.the_buffer
;
3566 priv
.insn_start
= pc
;
3569 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3577 start_codep
= priv
.the_buffer
;
3578 codep
= priv
.the_buffer
;
3580 if (setjmp (priv
.bailout
) != 0)
3584 /* Getting here means we tried for data but didn't get it. That
3585 means we have an incomplete instruction of some sort. Just
3586 print the first byte as a prefix or a .byte pseudo-op. */
3587 if (codep
> priv
.the_buffer
)
3589 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3591 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3594 /* Just print the first byte as a .byte instruction. */
3595 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3596 (unsigned int) priv
.the_buffer
[0]);
3609 sizeflag
= priv
.orig_sizeflag
;
3611 FETCH_DATA (info
, codep
+ 1);
3612 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3614 if (((prefixes
& PREFIX_FWAIT
)
3615 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3616 || (rex
&& rex_used
))
3620 /* fwait not followed by floating point instruction, or rex followed
3621 by other prefixes. Print the first prefix. */
3622 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3624 name
= INTERNAL_DISASSEMBLER_ERROR
;
3625 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3632 unsigned char threebyte
;
3633 FETCH_DATA (info
, codep
+ 2);
3634 threebyte
= *++codep
;
3635 dp
= &dis386_twobyte
[threebyte
];
3636 need_modrm
= twobyte_has_modrm
[*codep
];
3637 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3638 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3639 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3640 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3642 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3644 FETCH_DATA (info
, codep
+ 2);
3649 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3650 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3651 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3654 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3655 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3656 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3665 dp
= &dis386
[*codep
];
3666 need_modrm
= onebyte_has_modrm
[*codep
];
3667 uses_DATA_prefix
= 0;
3668 uses_REPNZ_prefix
= 0;
3669 /* pause is 0xf3 0x90. */
3670 uses_REPZ_prefix
= *codep
== 0x90;
3671 uses_LOCK_prefix
= 0;
3675 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3678 used_prefixes
|= PREFIX_REPZ
;
3680 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3683 used_prefixes
|= PREFIX_REPNZ
;
3686 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3689 used_prefixes
|= PREFIX_LOCK
;
3692 if (prefixes
& PREFIX_ADDR
)
3695 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3697 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3698 oappend ("addr32 ");
3700 oappend ("addr16 ");
3701 used_prefixes
|= PREFIX_ADDR
;
3705 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3708 if (dp
->op
[2].bytemode
== cond_jump_mode
3709 && dp
->op
[0].bytemode
== v_mode
3712 if (sizeflag
& DFLAG
)
3713 oappend ("data32 ");
3715 oappend ("data16 ");
3716 used_prefixes
|= PREFIX_DATA
;
3720 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3722 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3723 modrm
.mod
= (*codep
>> 6) & 3;
3724 modrm
.reg
= (*codep
>> 3) & 7;
3725 modrm
.rm
= *codep
& 7;
3727 else if (need_modrm
)
3729 FETCH_DATA (info
, codep
+ 1);
3730 modrm
.mod
= (*codep
>> 6) & 3;
3731 modrm
.reg
= (*codep
>> 3) & 7;
3732 modrm
.rm
= *codep
& 7;
3735 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3742 if (dp
->name
== NULL
)
3744 switch (dp
->op
[0].bytemode
)
3747 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3750 case USE_PREFIX_USER_TABLE
:
3752 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3753 if (prefixes
& PREFIX_REPZ
)
3757 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3758 before PREFIX_DATA. */
3759 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3760 if (prefixes
& PREFIX_REPNZ
)
3764 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3765 if (prefixes
& PREFIX_DATA
)
3769 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3772 case X86_64_SPECIAL
:
3773 index
= address_mode
== mode_64bit
? 1 : 0;
3774 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3778 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3783 if (putop (dp
->name
, sizeflag
) == 0)
3785 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3788 op_ad
= MAX_OPERANDS
- 1 - i
;
3790 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3795 /* See if any prefixes were not used. If so, print the first one
3796 separately. If we don't do this, we'll wind up printing an
3797 instruction stream which does not precisely correspond to the
3798 bytes we are disassembling. */
3799 if ((prefixes
& ~used_prefixes
) != 0)
3803 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3805 name
= INTERNAL_DISASSEMBLER_ERROR
;
3806 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3809 if (rex
& ~rex_used
)
3812 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3814 name
= INTERNAL_DISASSEMBLER_ERROR
;
3815 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3818 obufp
= obuf
+ strlen (obuf
);
3819 for (i
= strlen (obuf
); i
< 6; i
++)
3822 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3824 /* The enter and bound instructions are printed with operands in the same
3825 order as the intel book; everything else is printed in reverse order. */
3826 if (intel_syntax
|| two_source_ops
)
3830 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3831 op_txt
[i
] = op_out
[i
];
3833 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3835 op_ad
= op_index
[i
];
3836 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3837 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3838 riprel
= op_riprel
[i
];
3839 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
3840 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
3845 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3846 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3850 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3854 (*info
->fprintf_func
) (info
->stream
, ",");
3855 if (op_index
[i
] != -1 && !op_riprel
[i
])
3856 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3858 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3862 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3863 if (op_index
[i
] != -1 && op_riprel
[i
])
3865 (*info
->fprintf_func
) (info
->stream
, " # ");
3866 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3867 + op_address
[op_index
[i
]]), info
);
3870 return codep
- priv
.the_buffer
;
3873 static const char *float_mem
[] = {
3948 static const unsigned char float_mem_mode
[] = {
4023 #define ST { OP_ST, 0 }
4024 #define STi { OP_STi, 0 }
4026 #define FGRPd9_2 NULL, { { NULL, 0 } }
4027 #define FGRPd9_4 NULL, { { NULL, 1 } }
4028 #define FGRPd9_5 NULL, { { NULL, 2 } }
4029 #define FGRPd9_6 NULL, { { NULL, 3 } }
4030 #define FGRPd9_7 NULL, { { NULL, 4 } }
4031 #define FGRPda_5 NULL, { { NULL, 5 } }
4032 #define FGRPdb_4 NULL, { { NULL, 6 } }
4033 #define FGRPde_3 NULL, { { NULL, 7 } }
4034 #define FGRPdf_4 NULL, { { NULL, 8 } }
4036 static const struct dis386 float_reg
[][8] = {
4039 { "fadd", { ST
, STi
} },
4040 { "fmul", { ST
, STi
} },
4041 { "fcom", { STi
} },
4042 { "fcomp", { STi
} },
4043 { "fsub", { ST
, STi
} },
4044 { "fsubr", { ST
, STi
} },
4045 { "fdiv", { ST
, STi
} },
4046 { "fdivr", { ST
, STi
} },
4051 { "fxch", { STi
} },
4053 { "(bad)", { XX
} },
4061 { "fcmovb", { ST
, STi
} },
4062 { "fcmove", { ST
, STi
} },
4063 { "fcmovbe",{ ST
, STi
} },
4064 { "fcmovu", { ST
, STi
} },
4065 { "(bad)", { XX
} },
4067 { "(bad)", { XX
} },
4068 { "(bad)", { XX
} },
4072 { "fcmovnb",{ ST
, STi
} },
4073 { "fcmovne",{ ST
, STi
} },
4074 { "fcmovnbe",{ ST
, STi
} },
4075 { "fcmovnu",{ ST
, STi
} },
4077 { "fucomi", { ST
, STi
} },
4078 { "fcomi", { ST
, STi
} },
4079 { "(bad)", { XX
} },
4083 { "fadd", { STi
, ST
} },
4084 { "fmul", { STi
, ST
} },
4085 { "(bad)", { XX
} },
4086 { "(bad)", { XX
} },
4088 { "fsub", { STi
, ST
} },
4089 { "fsubr", { STi
, ST
} },
4090 { "fdiv", { STi
, ST
} },
4091 { "fdivr", { STi
, ST
} },
4093 { "fsubr", { STi
, ST
} },
4094 { "fsub", { STi
, ST
} },
4095 { "fdivr", { STi
, ST
} },
4096 { "fdiv", { STi
, ST
} },
4101 { "ffree", { STi
} },
4102 { "(bad)", { XX
} },
4104 { "fstp", { STi
} },
4105 { "fucom", { STi
} },
4106 { "fucomp", { STi
} },
4107 { "(bad)", { XX
} },
4108 { "(bad)", { XX
} },
4112 { "faddp", { STi
, ST
} },
4113 { "fmulp", { STi
, ST
} },
4114 { "(bad)", { XX
} },
4117 { "fsubp", { STi
, ST
} },
4118 { "fsubrp", { STi
, ST
} },
4119 { "fdivp", { STi
, ST
} },
4120 { "fdivrp", { STi
, ST
} },
4122 { "fsubrp", { STi
, ST
} },
4123 { "fsubp", { STi
, ST
} },
4124 { "fdivrp", { STi
, ST
} },
4125 { "fdivp", { STi
, ST
} },
4130 { "ffreep", { STi
} },
4131 { "(bad)", { XX
} },
4132 { "(bad)", { XX
} },
4133 { "(bad)", { XX
} },
4135 { "fucomip", { ST
, STi
} },
4136 { "fcomip", { ST
, STi
} },
4137 { "(bad)", { XX
} },
4141 static char *fgrps
[][8] = {
4144 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4149 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4154 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4159 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4164 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4169 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4174 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4175 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4180 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4185 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4190 dofloat (int sizeflag
)
4192 const struct dis386
*dp
;
4193 unsigned char floatop
;
4195 floatop
= codep
[-1];
4199 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4201 putop (float_mem
[fp_indx
], sizeflag
);
4204 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4207 /* Skip mod/rm byte. */
4211 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4212 if (dp
->name
== NULL
)
4214 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4216 /* Instruction fnstsw is only one with strange arg. */
4217 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4218 strcpy (op_out
[0], names16
[0]);
4222 putop (dp
->name
, sizeflag
);
4227 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4232 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4237 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4239 oappend ("%st" + intel_syntax
);
4243 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4245 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4246 oappend (scratchbuf
+ intel_syntax
);
4249 /* Capital letters in template are macros. */
4251 putop (const char *template, int sizeflag
)
4256 for (p
= template; *p
; p
++)
4267 if (address_mode
== mode_64bit
)
4275 /* Alternative not valid. */
4276 strcpy (obuf
, "(bad)");
4280 else if (*p
== '\0')
4301 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4307 if (sizeflag
& SUFFIX_ALWAYS
)
4311 if (intel_syntax
&& !alt
)
4313 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4315 if (sizeflag
& DFLAG
)
4316 *obufp
++ = intel_syntax
? 'd' : 'l';
4318 *obufp
++ = intel_syntax
? 'w' : 's';
4319 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4323 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4330 else if (sizeflag
& DFLAG
)
4331 *obufp
++ = intel_syntax
? 'd' : 'l';
4334 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4339 case 'E': /* For jcxz/jecxz */
4340 if (address_mode
== mode_64bit
)
4342 if (sizeflag
& AFLAG
)
4348 if (sizeflag
& AFLAG
)
4350 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4355 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4357 if (sizeflag
& AFLAG
)
4358 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4360 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4361 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4365 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4367 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4372 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4377 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4378 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4380 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4383 if (prefixes
& PREFIX_DS
)
4404 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4413 if (sizeflag
& SUFFIX_ALWAYS
)
4417 if ((prefixes
& PREFIX_FWAIT
) == 0)
4420 used_prefixes
|= PREFIX_FWAIT
;
4426 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4431 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4436 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4445 if ((prefixes
& PREFIX_DATA
)
4447 || (sizeflag
& SUFFIX_ALWAYS
))
4454 if (sizeflag
& DFLAG
)
4459 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4465 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4467 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4473 if (intel_syntax
&& !alt
)
4476 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4482 if (sizeflag
& DFLAG
)
4483 *obufp
++ = intel_syntax
? 'd' : 'l';
4487 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4494 else if (sizeflag
& DFLAG
)
4503 if (intel_syntax
&& !p
[1]
4504 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4507 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4512 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4514 if (sizeflag
& SUFFIX_ALWAYS
)
4522 if (sizeflag
& SUFFIX_ALWAYS
)
4528 if (sizeflag
& DFLAG
)
4532 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4537 if (prefixes
& PREFIX_DATA
)
4541 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4552 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4554 /* operand size flag for cwtl, cbtw */
4563 else if (sizeflag
& DFLAG
)
4568 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4578 oappend (const char *s
)
4581 obufp
+= strlen (s
);
4587 if (prefixes
& PREFIX_CS
)
4589 used_prefixes
|= PREFIX_CS
;
4590 oappend ("%cs:" + intel_syntax
);
4592 if (prefixes
& PREFIX_DS
)
4594 used_prefixes
|= PREFIX_DS
;
4595 oappend ("%ds:" + intel_syntax
);
4597 if (prefixes
& PREFIX_SS
)
4599 used_prefixes
|= PREFIX_SS
;
4600 oappend ("%ss:" + intel_syntax
);
4602 if (prefixes
& PREFIX_ES
)
4604 used_prefixes
|= PREFIX_ES
;
4605 oappend ("%es:" + intel_syntax
);
4607 if (prefixes
& PREFIX_FS
)
4609 used_prefixes
|= PREFIX_FS
;
4610 oappend ("%fs:" + intel_syntax
);
4612 if (prefixes
& PREFIX_GS
)
4614 used_prefixes
|= PREFIX_GS
;
4615 oappend ("%gs:" + intel_syntax
);
4620 OP_indirE (int bytemode
, int sizeflag
)
4624 OP_E (bytemode
, sizeflag
);
4628 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4630 if (address_mode
== mode_64bit
)
4638 sprintf_vma (tmp
, disp
);
4639 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4640 strcpy (buf
+ 2, tmp
+ i
);
4644 bfd_signed_vma v
= disp
;
4651 /* Check for possible overflow on 0x8000000000000000. */
4654 strcpy (buf
, "9223372036854775808");
4668 tmp
[28 - i
] = (v
% 10) + '0';
4672 strcpy (buf
, tmp
+ 29 - i
);
4678 sprintf (buf
, "0x%x", (unsigned int) disp
);
4680 sprintf (buf
, "%d", (int) disp
);
4684 /* Put DISP in BUF as signed hex number. */
4687 print_displacement (char *buf
, bfd_vma disp
)
4689 bfd_signed_vma val
= disp
;
4698 /* Check for possible overflow. */
4701 switch (address_mode
)
4704 strcpy (buf
+ j
, "0x8000000000000000");
4707 strcpy (buf
+ j
, "0x80000000");
4710 strcpy (buf
+ j
, "0x8000");
4720 sprintf_vma (tmp
, val
);
4721 for (i
= 0; tmp
[i
] == '0'; i
++)
4725 strcpy (buf
+ j
, tmp
+ i
);
4729 intel_operand_size (int bytemode
, int sizeflag
)
4735 oappend ("BYTE PTR ");
4739 oappend ("WORD PTR ");
4742 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4744 oappend ("QWORD PTR ");
4745 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4753 oappend ("QWORD PTR ");
4754 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4755 oappend ("DWORD PTR ");
4757 oappend ("WORD PTR ");
4758 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4761 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4763 oappend ("WORD PTR ");
4765 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4769 oappend ("DWORD PTR ");
4772 oappend ("QWORD PTR ");
4775 if (address_mode
== mode_64bit
)
4776 oappend ("QWORD PTR ");
4778 oappend ("DWORD PTR ");
4781 if (sizeflag
& DFLAG
)
4782 oappend ("FWORD PTR ");
4784 oappend ("DWORD PTR ");
4785 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4788 oappend ("TBYTE PTR ");
4791 oappend ("XMMWORD PTR ");
4794 oappend ("OWORD PTR ");
4802 OP_E (int bytemode
, int sizeflag
)
4811 /* Skip mod/rm byte. */
4822 oappend (names8rex
[modrm
.rm
+ add
]);
4824 oappend (names8
[modrm
.rm
+ add
]);
4827 oappend (names16
[modrm
.rm
+ add
]);
4830 oappend (names32
[modrm
.rm
+ add
]);
4833 oappend (names64
[modrm
.rm
+ add
]);
4836 if (address_mode
== mode_64bit
)
4837 oappend (names64
[modrm
.rm
+ add
]);
4839 oappend (names32
[modrm
.rm
+ add
]);
4842 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4844 oappend (names64
[modrm
.rm
+ add
]);
4845 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4857 oappend (names64
[modrm
.rm
+ add
]);
4858 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4859 oappend (names32
[modrm
.rm
+ add
]);
4861 oappend (names16
[modrm
.rm
+ add
]);
4862 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4867 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4875 intel_operand_size (bytemode
, sizeflag
);
4878 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4880 /* 32/64 bit address mode */
4895 FETCH_DATA (the_info
, codep
+ 1);
4896 index
= (*codep
>> 3) & 7;
4897 if (address_mode
== mode_64bit
|| index
!= 0x4)
4898 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4899 scale
= (*codep
>> 6) & 3;
4911 if ((base
& 7) == 5)
4914 if (address_mode
== mode_64bit
&& !havesib
)
4920 FETCH_DATA (the_info
, codep
+ 1);
4922 if ((disp
& 0x80) != 0)
4930 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
4933 if (modrm
.mod
!= 0 || (base
& 7) == 5)
4935 if (havedisp
|| riprel
)
4936 print_displacement (scratchbuf
, disp
);
4938 print_operand_value (scratchbuf
, 1, disp
);
4939 oappend (scratchbuf
);
4947 if (havedisp
|| (intel_syntax
&& riprel
))
4949 *obufp
++ = open_char
;
4950 if (intel_syntax
&& riprel
)
4957 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4958 ? names64
[base
] : names32
[base
]);
4963 if (!intel_syntax
|| havebase
)
4965 *obufp
++ = separator_char
;
4968 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4969 ? names64
[index
] : names32
[index
]);
4971 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4973 *obufp
++ = scale_char
;
4975 sprintf (scratchbuf
, "%d", 1 << scale
);
4976 oappend (scratchbuf
);
4980 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
4982 if ((bfd_signed_vma
) disp
>= 0)
4987 else if (modrm
.mod
!= 1)
4991 disp
= - (bfd_signed_vma
) disp
;
4994 print_displacement (scratchbuf
, disp
);
4995 oappend (scratchbuf
);
4998 *obufp
++ = close_char
;
5001 else if (intel_syntax
)
5003 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5005 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5006 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5010 oappend (names_seg
[ds_reg
- es_reg
]);
5013 print_operand_value (scratchbuf
, 1, disp
);
5014 oappend (scratchbuf
);
5019 { /* 16 bit address mode */
5026 if ((disp
& 0x8000) != 0)
5031 FETCH_DATA (the_info
, codep
+ 1);
5033 if ((disp
& 0x80) != 0)
5038 if ((disp
& 0x8000) != 0)
5044 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5046 print_displacement (scratchbuf
, disp
);
5047 oappend (scratchbuf
);
5050 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5052 *obufp
++ = open_char
;
5054 oappend (index16
[modrm
.rm
]);
5056 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5058 if ((bfd_signed_vma
) disp
>= 0)
5063 else if (modrm
.mod
!= 1)
5067 disp
= - (bfd_signed_vma
) disp
;
5070 print_displacement (scratchbuf
, disp
);
5071 oappend (scratchbuf
);
5074 *obufp
++ = close_char
;
5077 else if (intel_syntax
)
5079 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5080 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5084 oappend (names_seg
[ds_reg
- es_reg
]);
5087 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
5088 oappend (scratchbuf
);
5094 OP_G (int bytemode
, int sizeflag
)
5105 oappend (names8rex
[modrm
.reg
+ add
]);
5107 oappend (names8
[modrm
.reg
+ add
]);
5110 oappend (names16
[modrm
.reg
+ add
]);
5113 oappend (names32
[modrm
.reg
+ add
]);
5116 oappend (names64
[modrm
.reg
+ add
]);
5125 oappend (names64
[modrm
.reg
+ add
]);
5126 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5127 oappend (names32
[modrm
.reg
+ add
]);
5129 oappend (names16
[modrm
.reg
+ add
]);
5130 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5133 if (address_mode
== mode_64bit
)
5134 oappend (names64
[modrm
.reg
+ add
]);
5136 oappend (names32
[modrm
.reg
+ add
]);
5139 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5152 FETCH_DATA (the_info
, codep
+ 8);
5153 a
= *codep
++ & 0xff;
5154 a
|= (*codep
++ & 0xff) << 8;
5155 a
|= (*codep
++ & 0xff) << 16;
5156 a
|= (*codep
++ & 0xff) << 24;
5157 b
= *codep
++ & 0xff;
5158 b
|= (*codep
++ & 0xff) << 8;
5159 b
|= (*codep
++ & 0xff) << 16;
5160 b
|= (*codep
++ & 0xff) << 24;
5161 x
= a
+ ((bfd_vma
) b
<< 32);
5169 static bfd_signed_vma
5172 bfd_signed_vma x
= 0;
5174 FETCH_DATA (the_info
, codep
+ 4);
5175 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5176 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5177 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5178 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5182 static bfd_signed_vma
5185 bfd_signed_vma x
= 0;
5187 FETCH_DATA (the_info
, codep
+ 4);
5188 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5189 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5190 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5191 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5193 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5203 FETCH_DATA (the_info
, codep
+ 2);
5204 x
= *codep
++ & 0xff;
5205 x
|= (*codep
++ & 0xff) << 8;
5210 set_op (bfd_vma op
, int riprel
)
5212 op_index
[op_ad
] = op_ad
;
5213 if (address_mode
== mode_64bit
)
5215 op_address
[op_ad
] = op
;
5216 op_riprel
[op_ad
] = riprel
;
5220 /* Mask to get a 32-bit address. */
5221 op_address
[op_ad
] = op
& 0xffffffff;
5222 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5227 OP_REG (int code
, int sizeflag
)
5237 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5238 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5239 s
= names16
[code
- ax_reg
+ add
];
5241 case es_reg
: case ss_reg
: case cs_reg
:
5242 case ds_reg
: case fs_reg
: case gs_reg
:
5243 s
= names_seg
[code
- es_reg
+ add
];
5245 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5246 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5249 s
= names8rex
[code
- al_reg
+ add
];
5251 s
= names8
[code
- al_reg
];
5253 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5254 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5255 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5257 s
= names64
[code
- rAX_reg
+ add
];
5260 code
+= eAX_reg
- rAX_reg
;
5262 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5263 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5266 s
= names64
[code
- eAX_reg
+ add
];
5267 else if (sizeflag
& DFLAG
)
5268 s
= names32
[code
- eAX_reg
+ add
];
5270 s
= names16
[code
- eAX_reg
+ add
];
5271 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5274 s
= INTERNAL_DISASSEMBLER_ERROR
;
5281 OP_IMREG (int code
, int sizeflag
)
5293 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5294 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5295 s
= names16
[code
- ax_reg
];
5297 case es_reg
: case ss_reg
: case cs_reg
:
5298 case ds_reg
: case fs_reg
: case gs_reg
:
5299 s
= names_seg
[code
- es_reg
];
5301 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5302 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5305 s
= names8rex
[code
- al_reg
];
5307 s
= names8
[code
- al_reg
];
5309 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5310 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5313 s
= names64
[code
- eAX_reg
];
5314 else if (sizeflag
& DFLAG
)
5315 s
= names32
[code
- eAX_reg
];
5317 s
= names16
[code
- eAX_reg
];
5318 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5321 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5326 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5329 s
= INTERNAL_DISASSEMBLER_ERROR
;
5336 OP_I (int bytemode
, int sizeflag
)
5339 bfd_signed_vma mask
= -1;
5344 FETCH_DATA (the_info
, codep
+ 1);
5349 if (address_mode
== mode_64bit
)
5359 else if (sizeflag
& DFLAG
)
5369 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5380 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5385 scratchbuf
[0] = '$';
5386 print_operand_value (scratchbuf
+ 1, 1, op
);
5387 oappend (scratchbuf
+ intel_syntax
);
5388 scratchbuf
[0] = '\0';
5392 OP_I64 (int bytemode
, int sizeflag
)
5395 bfd_signed_vma mask
= -1;
5397 if (address_mode
!= mode_64bit
)
5399 OP_I (bytemode
, sizeflag
);
5406 FETCH_DATA (the_info
, codep
+ 1);
5414 else if (sizeflag
& DFLAG
)
5424 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5431 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5436 scratchbuf
[0] = '$';
5437 print_operand_value (scratchbuf
+ 1, 1, op
);
5438 oappend (scratchbuf
+ intel_syntax
);
5439 scratchbuf
[0] = '\0';
5443 OP_sI (int bytemode
, int sizeflag
)
5446 bfd_signed_vma mask
= -1;
5451 FETCH_DATA (the_info
, codep
+ 1);
5453 if ((op
& 0x80) != 0)
5461 else if (sizeflag
& DFLAG
)
5470 if ((op
& 0x8000) != 0)
5473 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5478 if ((op
& 0x8000) != 0)
5482 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5486 scratchbuf
[0] = '$';
5487 print_operand_value (scratchbuf
+ 1, 1, op
);
5488 oappend (scratchbuf
+ intel_syntax
);
5492 OP_J (int bytemode
, int sizeflag
)
5496 bfd_vma segment
= 0;
5501 FETCH_DATA (the_info
, codep
+ 1);
5503 if ((disp
& 0x80) != 0)
5507 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5512 if ((disp
& 0x8000) != 0)
5514 /* In 16bit mode, address is wrapped around at 64k within
5515 the same segment. Otherwise, a data16 prefix on a jump
5516 instruction means that the pc is masked to 16 bits after
5517 the displacement is added! */
5519 if ((prefixes
& PREFIX_DATA
) == 0)
5520 segment
= ((start_pc
+ codep
- start_codep
)
5521 & ~((bfd_vma
) 0xffff));
5523 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5526 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5529 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5531 print_operand_value (scratchbuf
, 1, disp
);
5532 oappend (scratchbuf
);
5536 OP_SEG (int bytemode
, int sizeflag
)
5538 if (bytemode
== w_mode
)
5539 oappend (names_seg
[modrm
.reg
]);
5541 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5545 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5549 if (sizeflag
& DFLAG
)
5559 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5561 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5563 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5564 oappend (scratchbuf
);
5568 OP_OFF (int bytemode
, int sizeflag
)
5572 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5573 intel_operand_size (bytemode
, sizeflag
);
5576 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5583 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5584 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5586 oappend (names_seg
[ds_reg
- es_reg
]);
5590 print_operand_value (scratchbuf
, 1, off
);
5591 oappend (scratchbuf
);
5595 OP_OFF64 (int bytemode
, int sizeflag
)
5599 if (address_mode
!= mode_64bit
5600 || (prefixes
& PREFIX_ADDR
))
5602 OP_OFF (bytemode
, sizeflag
);
5606 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5607 intel_operand_size (bytemode
, sizeflag
);
5614 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5615 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5617 oappend (names_seg
[ds_reg
- es_reg
]);
5621 print_operand_value (scratchbuf
, 1, off
);
5622 oappend (scratchbuf
);
5626 ptr_reg (int code
, int sizeflag
)
5630 *obufp
++ = open_char
;
5631 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5632 if (address_mode
== mode_64bit
)
5634 if (!(sizeflag
& AFLAG
))
5635 s
= names32
[code
- eAX_reg
];
5637 s
= names64
[code
- eAX_reg
];
5639 else if (sizeflag
& AFLAG
)
5640 s
= names32
[code
- eAX_reg
];
5642 s
= names16
[code
- eAX_reg
];
5644 *obufp
++ = close_char
;
5649 OP_ESreg (int code
, int sizeflag
)
5655 case 0x6d: /* insw/insl */
5656 intel_operand_size (z_mode
, sizeflag
);
5658 case 0xa5: /* movsw/movsl/movsq */
5659 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5660 case 0xab: /* stosw/stosl */
5661 case 0xaf: /* scasw/scasl */
5662 intel_operand_size (v_mode
, sizeflag
);
5665 intel_operand_size (b_mode
, sizeflag
);
5668 oappend ("%es:" + intel_syntax
);
5669 ptr_reg (code
, sizeflag
);
5673 OP_DSreg (int code
, int sizeflag
)
5679 case 0x6f: /* outsw/outsl */
5680 intel_operand_size (z_mode
, sizeflag
);
5682 case 0xa5: /* movsw/movsl/movsq */
5683 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5684 case 0xad: /* lodsw/lodsl/lodsq */
5685 intel_operand_size (v_mode
, sizeflag
);
5688 intel_operand_size (b_mode
, sizeflag
);
5698 prefixes
|= PREFIX_DS
;
5700 ptr_reg (code
, sizeflag
);
5704 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5712 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5714 used_prefixes
|= PREFIX_LOCK
;
5717 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5718 oappend (scratchbuf
+ intel_syntax
);
5722 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5729 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5731 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5732 oappend (scratchbuf
);
5736 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5738 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5739 oappend (scratchbuf
+ intel_syntax
);
5743 OP_R (int bytemode
, int sizeflag
)
5746 OP_E (bytemode
, sizeflag
);
5752 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5754 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5755 if (prefixes
& PREFIX_DATA
)
5761 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5764 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5765 oappend (scratchbuf
+ intel_syntax
);
5769 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5775 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5776 oappend (scratchbuf
+ intel_syntax
);
5780 OP_EM (int bytemode
, int sizeflag
)
5784 if (intel_syntax
&& bytemode
== v_mode
)
5786 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5787 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5789 OP_E (bytemode
, sizeflag
);
5793 /* Skip mod/rm byte. */
5796 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5797 if (prefixes
& PREFIX_DATA
)
5804 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5807 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5808 oappend (scratchbuf
+ intel_syntax
);
5811 /* cvt* are the only instructions in sse2 which have
5812 both SSE and MMX operands and also have 0x66 prefix
5813 in their opcode. 0x66 was originally used to differentiate
5814 between SSE and MMX instruction(operands). So we have to handle the
5815 cvt* separately using OP_EMC and OP_MXC */
5817 OP_EMC (int bytemode
, int sizeflag
)
5821 if (intel_syntax
&& bytemode
== v_mode
)
5823 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5824 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5826 OP_E (bytemode
, sizeflag
);
5830 /* Skip mod/rm byte. */
5833 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5834 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5835 oappend (scratchbuf
+ intel_syntax
);
5839 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5841 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5842 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5843 oappend (scratchbuf
+ intel_syntax
);
5847 OP_EX (int bytemode
, int sizeflag
)
5852 OP_E (bytemode
, sizeflag
);
5859 /* Skip mod/rm byte. */
5862 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5863 oappend (scratchbuf
+ intel_syntax
);
5867 OP_MS (int bytemode
, int sizeflag
)
5870 OP_EM (bytemode
, sizeflag
);
5876 OP_XS (int bytemode
, int sizeflag
)
5879 OP_EX (bytemode
, sizeflag
);
5885 OP_M (int bytemode
, int sizeflag
)
5888 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5891 OP_E (bytemode
, sizeflag
);
5895 OP_0f07 (int bytemode
, int sizeflag
)
5897 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
5900 OP_E (bytemode
, sizeflag
);
5904 OP_0fae (int bytemode
, int sizeflag
)
5909 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5911 if (modrm
.reg
< 5 || modrm
.rm
!= 0)
5913 BadOp (); /* bad sfence, mfence, or lfence */
5917 else if (modrm
.reg
!= 7)
5919 BadOp (); /* bad clflush */
5923 OP_E (bytemode
, sizeflag
);
5926 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5927 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5930 NOP_Fixup1 (int bytemode
, int sizeflag
)
5932 if ((prefixes
& PREFIX_DATA
) != 0
5935 && address_mode
== mode_64bit
))
5936 OP_REG (bytemode
, sizeflag
);
5938 strcpy (obuf
, "nop");
5942 NOP_Fixup2 (int bytemode
, int sizeflag
)
5944 if ((prefixes
& PREFIX_DATA
) != 0
5947 && address_mode
== mode_64bit
))
5948 OP_IMREG (bytemode
, sizeflag
);
5951 static const char *const Suffix3DNow
[] = {
5952 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5953 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5954 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5955 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5956 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5957 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5958 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5959 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5960 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5961 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5962 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5963 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5964 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5965 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5966 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5967 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5968 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5969 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5970 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5971 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5972 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5973 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5974 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5975 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5976 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5977 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5978 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5979 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5980 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5981 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5982 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5983 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5984 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5985 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5986 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5987 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5988 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5989 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5990 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5991 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5992 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5993 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5994 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5995 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5996 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5997 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
5998 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5999 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6000 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6001 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6002 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6003 /* CC */ NULL
, NULL
, NULL
, NULL
,
6004 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6005 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6006 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6007 /* DC */ NULL
, NULL
, NULL
, NULL
,
6008 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6009 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6010 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6011 /* EC */ NULL
, NULL
, NULL
, NULL
,
6012 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6013 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6014 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6015 /* FC */ NULL
, NULL
, NULL
, NULL
,
6019 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6021 const char *mnemonic
;
6023 FETCH_DATA (the_info
, codep
+ 1);
6024 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6025 place where an 8-bit immediate would normally go. ie. the last
6026 byte of the instruction. */
6027 obufp
= obuf
+ strlen (obuf
);
6028 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6033 /* Since a variable sized modrm/sib chunk is between the start
6034 of the opcode (0x0f0f) and the opcode suffix, we need to do
6035 all the modrm processing first, and don't know until now that
6036 we have a bad opcode. This necessitates some cleaning up. */
6037 op_out
[0][0] = '\0';
6038 op_out
[1][0] = '\0';
6043 static const char *simd_cmp_op
[] = {
6055 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6057 unsigned int cmp_type
;
6059 FETCH_DATA (the_info
, codep
+ 1);
6060 obufp
= obuf
+ strlen (obuf
);
6061 cmp_type
= *codep
++ & 0xff;
6064 char suffix1
= 'p', suffix2
= 's';
6065 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6066 if (prefixes
& PREFIX_REPZ
)
6070 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6071 if (prefixes
& PREFIX_DATA
)
6075 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6076 if (prefixes
& PREFIX_REPNZ
)
6077 suffix1
= 's', suffix2
= 'd';
6080 sprintf (scratchbuf
, "cmp%s%c%c",
6081 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6082 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6083 oappend (scratchbuf
);
6087 /* We have a bad extension byte. Clean up. */
6088 op_out
[0][0] = '\0';
6089 op_out
[1][0] = '\0';
6095 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
6097 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6098 forms of these instructions. */
6101 char *p
= obuf
+ strlen (obuf
);
6104 *(p
- 1) = *(p
- 2);
6105 *(p
- 2) = *(p
- 3);
6106 *(p
- 3) = extrachar
;
6111 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6113 if (modrm
.mod
== 3 && modrm
.reg
== 1 && modrm
.rm
<= 1)
6115 /* Override "sidt". */
6116 size_t olen
= strlen (obuf
);
6117 char *p
= obuf
+ olen
- 4;
6118 const char **names
= (address_mode
== mode_64bit
6119 ? names64
: names32
);
6121 /* We might have a suffix when disassembling with -Msuffix. */
6125 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6127 && (prefixes
& PREFIX_ADDR
)
6130 && CONST_STRNEQ (p
- 7, "addr")
6131 && (CONST_STRNEQ (p
- 3, "16")
6132 || CONST_STRNEQ (p
- 3, "32")))
6137 /* mwait %eax,%ecx */
6138 strcpy (p
, "mwait");
6140 strcpy (op_out
[0], names
[0]);
6144 /* monitor %eax,%ecx,%edx" */
6145 strcpy (p
, "monitor");
6148 const char **op1_names
;
6149 if (!(prefixes
& PREFIX_ADDR
))
6150 op1_names
= (address_mode
== mode_16bit
6154 op1_names
= (address_mode
!= mode_32bit
6155 ? names32
: names16
);
6156 used_prefixes
|= PREFIX_ADDR
;
6158 strcpy (op_out
[0], op1_names
[0]);
6159 strcpy (op_out
[2], names
[2]);
6164 strcpy (op_out
[1], names
[1]);
6175 SVME_Fixup (int bytemode
, int sizeflag
)
6207 OP_M (bytemode
, sizeflag
);
6210 /* Override "lidt". */
6211 p
= obuf
+ strlen (obuf
) - 4;
6212 /* We might have a suffix. */
6216 if (!(prefixes
& PREFIX_ADDR
))
6221 used_prefixes
|= PREFIX_ADDR
;
6225 strcpy (op_out
[1], names32
[1]);
6231 *obufp
++ = open_char
;
6232 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6236 strcpy (obufp
, alt
);
6237 obufp
+= strlen (alt
);
6238 *obufp
++ = close_char
;
6245 INVLPG_Fixup (int bytemode
, int sizeflag
)
6258 OP_M (bytemode
, sizeflag
);
6261 /* Override "invlpg". */
6262 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6269 /* Throw away prefixes and 1st. opcode byte. */
6270 codep
= insn_codep
+ 1;
6275 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6282 /* Override "sgdt". */
6283 char *p
= obuf
+ strlen (obuf
) - 4;
6285 /* We might have a suffix when disassembling with -Msuffix. */
6292 strcpy (p
, "vmcall");
6295 strcpy (p
, "vmlaunch");
6298 strcpy (p
, "vmresume");
6301 strcpy (p
, "vmxoff");
6312 OP_VMX (int bytemode
, int sizeflag
)
6314 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
6315 if (prefixes
& PREFIX_DATA
)
6316 strcpy (obuf
, "vmclear");
6317 else if (prefixes
& PREFIX_REPZ
)
6318 strcpy (obuf
, "vmxon");
6320 strcpy (obuf
, "vmptrld");
6321 OP_E (bytemode
, sizeflag
);
6325 REP_Fixup (int bytemode
, int sizeflag
)
6327 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6331 if (prefixes
& PREFIX_REPZ
)
6332 switch (*insn_codep
)
6334 case 0x6e: /* outsb */
6335 case 0x6f: /* outsw/outsl */
6336 case 0xa4: /* movsb */
6337 case 0xa5: /* movsw/movsl/movsq */
6343 case 0xaa: /* stosb */
6344 case 0xab: /* stosw/stosl/stosq */
6345 case 0xac: /* lodsb */
6346 case 0xad: /* lodsw/lodsl/lodsq */
6347 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
6352 case 0x6c: /* insb */
6353 case 0x6d: /* insl/insw */
6369 olen
= strlen (obuf
);
6370 p
= obuf
+ olen
- ilen
- 1 - 4;
6371 /* Handle "repz [addr16|addr32]". */
6372 if ((prefixes
& PREFIX_ADDR
))
6375 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
6383 OP_IMREG (bytemode
, sizeflag
);
6386 OP_ESreg (bytemode
, sizeflag
);
6389 OP_DSreg (bytemode
, sizeflag
);
6398 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6403 /* Change cmpxchg8b to cmpxchg16b. */
6404 char *p
= obuf
+ strlen (obuf
) - 2;
6408 OP_M (bytemode
, sizeflag
);
6412 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6414 sprintf (scratchbuf
, "%%xmm%d", reg
);
6415 oappend (scratchbuf
+ intel_syntax
);
6419 CRC32_Fixup (int bytemode
, int sizeflag
)
6421 /* Add proper suffix to "crc32". */
6422 char *p
= obuf
+ strlen (obuf
);
6439 else if (sizeflag
& DFLAG
)
6443 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6446 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6455 /* Skip mod/rm byte. */
6460 add
= (rex
& REX_B
) ? 8 : 0;
6461 if (bytemode
== b_mode
)
6465 oappend (names8rex
[modrm
.rm
+ add
]);
6467 oappend (names8
[modrm
.rm
+ add
]);
6473 oappend (names64
[modrm
.rm
+ add
]);
6474 else if ((prefixes
& PREFIX_DATA
))
6475 oappend (names16
[modrm
.rm
+ add
]);
6477 oappend (names32
[modrm
.rm
+ add
]);
6481 OP_E (bytemode
, sizeflag
);