1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
25 modified by John Hassey (hassey@dg-rtp.dg.com)
26 x86-64 support added by Jan Hubicka (jh@suse.cz)
27 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
29 /* The main tables describing the instructions is essentially a copy
30 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
31 Programmers Manual. Usually, there is a capital letter, followed
32 by a small letter. The capital letter tell the addressing mode,
33 and the small letter tells about the operand size. Refer to
34 the Intel manual for details. */
39 #include "opcode/i386.h"
43 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
44 static void ckprefix (void);
45 static const char *prefix_name (int, int);
46 static int print_insn (bfd_vma
, disassemble_info
*);
47 static void dofloat (int);
48 static void OP_ST (int, int);
49 static void OP_STi (int, int);
50 static int putop (const char *, int);
51 static void oappend (const char *);
52 static void append_seg (void);
53 static void OP_indirE (int, int);
54 static void print_operand_value (char *, int, bfd_vma
);
55 static void print_displacement (char *, bfd_vma
);
56 static void OP_E (int, int);
57 static void OP_G (int, int);
58 static bfd_vma
get64 (void);
59 static bfd_signed_vma
get32 (void);
60 static bfd_signed_vma
get32s (void);
61 static int get16 (void);
62 static void set_op (bfd_vma
, int);
63 static void OP_REG (int, int);
64 static void OP_IMREG (int, int);
65 static void OP_I (int, int);
66 static void OP_I64 (int, int);
67 static void OP_sI (int, int);
68 static void OP_J (int, int);
69 static void OP_SEG (int, int);
70 static void OP_DIR (int, int);
71 static void OP_OFF (int, int);
72 static void OP_OFF64 (int, int);
73 static void ptr_reg (int, int);
74 static void OP_ESreg (int, int);
75 static void OP_DSreg (int, int);
76 static void OP_C (int, int);
77 static void OP_D (int, int);
78 static void OP_T (int, int);
79 static void OP_R (int, int);
80 static void OP_MMX (int, int);
81 static void OP_XMM (int, int);
82 static void OP_EM (int, int);
83 static void OP_EX (int, int);
84 static void OP_EMC (int,int);
85 static void OP_MXC (int,int);
86 static void OP_MS (int, int);
87 static void OP_XS (int, int);
88 static void OP_M (int, int);
89 static void OP_VMX (int, int);
90 static void OP_0fae (int, int);
91 static void OP_0f07 (int, int);
92 static void NOP_Fixup1 (int, int);
93 static void NOP_Fixup2 (int, int);
94 static void OP_3DNowSuffix (int, int);
95 static void OP_SIMD_Suffix (int, int);
96 static void SIMD_Fixup (int, int);
97 static void PNI_Fixup (int, int);
98 static void SVME_Fixup (int, int);
99 static void INVLPG_Fixup (int, int);
100 static void BadOp (void);
101 static void VMX_Fixup (int, int);
102 static void REP_Fixup (int, int);
103 static void CMPXCHG8B_Fixup (int, int);
104 static void XMM_Fixup (int, int);
105 static void CRC32_Fixup (int, int);
108 /* Points to first byte not fetched. */
109 bfd_byte
*max_fetched
;
110 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
123 enum address_mode address_mode
;
125 /* Flags for the prefixes for the current instruction. See below. */
128 /* REX prefix the current instruction. See below. */
130 /* Bits of REX we've already used. */
132 /* Mark parts used in the REX prefix. When we are testing for
133 empty prefix (for 8bit register REX extension), just mask it
134 out. Otherwise test for REX bit is excuse for existence of REX
135 only in case value is nonzero. */
136 #define USED_REX(value) \
141 rex_used |= (value) | REX_OPCODE; \
144 rex_used |= REX_OPCODE; \
147 /* Flags for prefixes which we somehow handled when printing the
148 current instruction. */
149 static int used_prefixes
;
151 /* Flags stored in PREFIXES. */
152 #define PREFIX_REPZ 1
153 #define PREFIX_REPNZ 2
154 #define PREFIX_LOCK 4
156 #define PREFIX_SS 0x10
157 #define PREFIX_DS 0x20
158 #define PREFIX_ES 0x40
159 #define PREFIX_FS 0x80
160 #define PREFIX_GS 0x100
161 #define PREFIX_DATA 0x200
162 #define PREFIX_ADDR 0x400
163 #define PREFIX_FWAIT 0x800
165 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
166 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
168 #define FETCH_DATA(info, addr) \
169 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
170 ? 1 : fetch_data ((info), (addr)))
173 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
176 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
177 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
179 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
180 status
= (*info
->read_memory_func
) (start
,
182 addr
- priv
->max_fetched
,
188 /* If we did manage to read at least one byte, then
189 print_insn_i386 will do something sensible. Otherwise, print
190 an error. We do that here because this is where we know
192 if (priv
->max_fetched
== priv
->the_buffer
)
193 (*info
->memory_error_func
) (status
, start
, info
);
194 longjmp (priv
->bailout
, 1);
197 priv
->max_fetched
= addr
;
201 #define XX { NULL, 0 }
203 #define Eb { OP_E, b_mode }
204 #define Ev { OP_E, v_mode }
205 #define Ed { OP_E, d_mode }
206 #define Edq { OP_E, dq_mode }
207 #define Edqw { OP_E, dqw_mode }
208 #define Edqb { OP_E, dqb_mode }
209 #define Edqd { OP_E, dqd_mode }
210 #define Eq { OP_E, q_mode }
211 #define indirEv { OP_indirE, stack_v_mode }
212 #define indirEp { OP_indirE, f_mode }
213 #define stackEv { OP_E, stack_v_mode }
214 #define Em { OP_E, m_mode }
215 #define Ew { OP_E, w_mode }
216 #define M { OP_M, 0 } /* lea, lgdt, etc. */
217 #define Ma { OP_M, v_mode }
218 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
219 #define Mq { OP_M, q_mode }
220 #define Gb { OP_G, b_mode }
221 #define Gv { OP_G, v_mode }
222 #define Gd { OP_G, d_mode }
223 #define Gdq { OP_G, dq_mode }
224 #define Gm { OP_G, m_mode }
225 #define Gw { OP_G, w_mode }
226 #define Rd { OP_R, d_mode }
227 #define Rm { OP_R, m_mode }
228 #define Ib { OP_I, b_mode }
229 #define sIb { OP_sI, b_mode } /* sign extened byte */
230 #define Iv { OP_I, v_mode }
231 #define Iq { OP_I, q_mode }
232 #define Iv64 { OP_I64, v_mode }
233 #define Iw { OP_I, w_mode }
234 #define I1 { OP_I, const_1_mode }
235 #define Jb { OP_J, b_mode }
236 #define Jv { OP_J, v_mode }
237 #define Cm { OP_C, m_mode }
238 #define Dm { OP_D, m_mode }
239 #define Td { OP_T, d_mode }
241 #define RMeAX { OP_REG, eAX_reg }
242 #define RMeBX { OP_REG, eBX_reg }
243 #define RMeCX { OP_REG, eCX_reg }
244 #define RMeDX { OP_REG, eDX_reg }
245 #define RMeSP { OP_REG, eSP_reg }
246 #define RMeBP { OP_REG, eBP_reg }
247 #define RMeSI { OP_REG, eSI_reg }
248 #define RMeDI { OP_REG, eDI_reg }
249 #define RMrAX { OP_REG, rAX_reg }
250 #define RMrBX { OP_REG, rBX_reg }
251 #define RMrCX { OP_REG, rCX_reg }
252 #define RMrDX { OP_REG, rDX_reg }
253 #define RMrSP { OP_REG, rSP_reg }
254 #define RMrBP { OP_REG, rBP_reg }
255 #define RMrSI { OP_REG, rSI_reg }
256 #define RMrDI { OP_REG, rDI_reg }
257 #define RMAL { OP_REG, al_reg }
258 #define RMAL { OP_REG, al_reg }
259 #define RMCL { OP_REG, cl_reg }
260 #define RMDL { OP_REG, dl_reg }
261 #define RMBL { OP_REG, bl_reg }
262 #define RMAH { OP_REG, ah_reg }
263 #define RMCH { OP_REG, ch_reg }
264 #define RMDH { OP_REG, dh_reg }
265 #define RMBH { OP_REG, bh_reg }
266 #define RMAX { OP_REG, ax_reg }
267 #define RMDX { OP_REG, dx_reg }
269 #define eAX { OP_IMREG, eAX_reg }
270 #define eBX { OP_IMREG, eBX_reg }
271 #define eCX { OP_IMREG, eCX_reg }
272 #define eDX { OP_IMREG, eDX_reg }
273 #define eSP { OP_IMREG, eSP_reg }
274 #define eBP { OP_IMREG, eBP_reg }
275 #define eSI { OP_IMREG, eSI_reg }
276 #define eDI { OP_IMREG, eDI_reg }
277 #define AL { OP_IMREG, al_reg }
278 #define CL { OP_IMREG, cl_reg }
279 #define DL { OP_IMREG, dl_reg }
280 #define BL { OP_IMREG, bl_reg }
281 #define AH { OP_IMREG, ah_reg }
282 #define CH { OP_IMREG, ch_reg }
283 #define DH { OP_IMREG, dh_reg }
284 #define BH { OP_IMREG, bh_reg }
285 #define AX { OP_IMREG, ax_reg }
286 #define DX { OP_IMREG, dx_reg }
287 #define zAX { OP_IMREG, z_mode_ax_reg }
288 #define indirDX { OP_IMREG, indir_dx_reg }
290 #define Sw { OP_SEG, w_mode }
291 #define Sv { OP_SEG, v_mode }
292 #define Ap { OP_DIR, 0 }
293 #define Ob { OP_OFF64, b_mode }
294 #define Ov { OP_OFF64, v_mode }
295 #define Xb { OP_DSreg, eSI_reg }
296 #define Xv { OP_DSreg, eSI_reg }
297 #define Xz { OP_DSreg, eSI_reg }
298 #define Yb { OP_ESreg, eDI_reg }
299 #define Yv { OP_ESreg, eDI_reg }
300 #define DSBX { OP_DSreg, eBX_reg }
302 #define es { OP_REG, es_reg }
303 #define ss { OP_REG, ss_reg }
304 #define cs { OP_REG, cs_reg }
305 #define ds { OP_REG, ds_reg }
306 #define fs { OP_REG, fs_reg }
307 #define gs { OP_REG, gs_reg }
309 #define MX { OP_MMX, 0 }
310 #define XM { OP_XMM, 0 }
311 #define EM { OP_EM, v_mode }
312 #define EMd { OP_EM, d_mode }
313 #define EMx { OP_EM, x_mode }
314 #define EXw { OP_EX, w_mode }
315 #define EXd { OP_EX, d_mode }
316 #define EXq { OP_EX, q_mode }
317 #define EXx { OP_EX, x_mode }
318 #define MS { OP_MS, v_mode }
319 #define XS { OP_XS, v_mode }
320 #define EMCq { OP_EMC, q_mode }
321 #define MXC { OP_MXC, 0 }
322 #define VM { OP_VMX, q_mode }
323 #define OPSUF { OP_3DNowSuffix, 0 }
324 #define OPSIMD { OP_SIMD_Suffix, 0 }
325 #define XMM0 { XMM_Fixup, 0 }
327 /* Used handle "rep" prefix for string instructions. */
328 #define Xbr { REP_Fixup, eSI_reg }
329 #define Xvr { REP_Fixup, eSI_reg }
330 #define Ybr { REP_Fixup, eDI_reg }
331 #define Yvr { REP_Fixup, eDI_reg }
332 #define Yzr { REP_Fixup, eDI_reg }
333 #define indirDXr { REP_Fixup, indir_dx_reg }
334 #define ALr { REP_Fixup, al_reg }
335 #define eAXr { REP_Fixup, eAX_reg }
337 #define cond_jump_flag { NULL, cond_jump_mode }
338 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
340 /* bits in sizeflag */
341 #define SUFFIX_ALWAYS 4
345 #define b_mode 1 /* byte operand */
346 #define v_mode 2 /* operand size depends on prefixes */
347 #define w_mode 3 /* word operand */
348 #define d_mode 4 /* double word operand */
349 #define q_mode 5 /* quad word operand */
350 #define t_mode 6 /* ten-byte operand */
351 #define x_mode 7 /* 16-byte XMM operand */
352 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
353 #define cond_jump_mode 9
354 #define loop_jcxz_mode 10
355 #define dq_mode 11 /* operand size depends on REX prefixes. */
356 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
357 #define f_mode 13 /* 4- or 6-byte pointer operand */
358 #define const_1_mode 14
359 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
360 #define z_mode 16 /* non-quad operand size depends on prefixes */
361 #define o_mode 17 /* 16-byte operand */
362 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
363 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
408 #define z_mode_ax_reg 149
409 #define indir_dx_reg 150
413 #define USE_PREFIX_USER_TABLE 3
414 #define X86_64_SPECIAL 4
415 #define IS_3BYTE_OPCODE 5
417 #define FLOAT NULL, { { NULL, FLOATCODE } }
419 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
420 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
421 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
422 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
423 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
424 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
425 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
426 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
427 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
428 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
429 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
430 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
431 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
432 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
433 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
434 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
435 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
436 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
437 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
438 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
439 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
440 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
441 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
442 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
443 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
444 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
445 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
446 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
448 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
449 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
450 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
451 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
452 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
453 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
454 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
455 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
456 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
457 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
458 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
459 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
460 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
461 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
462 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
463 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
464 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
465 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
466 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
467 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
468 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
469 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
470 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
471 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
472 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
473 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
474 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
475 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
476 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
477 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
478 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
479 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
480 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
481 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
482 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
483 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
484 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
485 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
486 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
487 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
488 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
489 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
490 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
491 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
492 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
493 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
494 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
495 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
496 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
497 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
498 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
499 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
500 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
501 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
502 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
503 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
504 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
505 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
506 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
507 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
508 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
509 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
510 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
511 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
512 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
513 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
514 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
515 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
516 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
517 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
518 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
519 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
520 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
521 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
522 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
523 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
524 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
525 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
526 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
527 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
528 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
529 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
530 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
531 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
532 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
533 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
534 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
535 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
536 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
537 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
538 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
539 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
540 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
541 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
542 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
543 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
544 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
545 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
548 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
549 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
550 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
551 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
553 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
554 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
556 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
567 /* Upper case letters in the instruction names here are macros.
568 'A' => print 'b' if no register operands or suffix_always is true
569 'B' => print 'b' if suffix_always is true
570 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
572 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
573 . suffix_always is true
574 'E' => print 'e' if 32-bit form of jcxz
575 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
576 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
577 'H' => print ",pt" or ",pn" branch hint
578 'I' => honor following macro letter even in Intel mode (implemented only
579 . for some of the macro letters)
581 'K' => print 'd' or 'q' if rex prefix is present.
582 'L' => print 'l' if suffix_always is true
583 'N' => print 'n' if instruction has no wait "prefix"
584 'O' => print 'd' or 'o' (or 'q' in Intel mode)
585 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
586 . or suffix_always is true. print 'q' if rex prefix is present.
587 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
589 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
590 'S' => print 'w', 'l' or 'q' if suffix_always is true
591 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
592 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
593 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
594 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
595 'X' => print 's', 'd' depending on data16 prefix (for XMM)
596 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
597 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
599 Many of the above letters print nothing in Intel mode. See "putop"
602 Braces '{' and '}', and vertical bars '|', indicate alternative
603 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
604 modes. In cases where there are only two alternatives, the X86_64
605 instruction is reserved, and "(bad)" is printed.
608 static const struct dis386 dis386
[] = {
610 { "addB", { Eb
, Gb
} },
611 { "addS", { Ev
, Gv
} },
612 { "addB", { Gb
, Eb
} },
613 { "addS", { Gv
, Ev
} },
614 { "addB", { AL
, Ib
} },
615 { "addS", { eAX
, Iv
} },
616 { "push{T|}", { es
} },
617 { "pop{T|}", { es
} },
619 { "orB", { Eb
, Gb
} },
620 { "orS", { Ev
, Gv
} },
621 { "orB", { Gb
, Eb
} },
622 { "orS", { Gv
, Ev
} },
623 { "orB", { AL
, Ib
} },
624 { "orS", { eAX
, Iv
} },
625 { "push{T|}", { cs
} },
626 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
628 { "adcB", { Eb
, Gb
} },
629 { "adcS", { Ev
, Gv
} },
630 { "adcB", { Gb
, Eb
} },
631 { "adcS", { Gv
, Ev
} },
632 { "adcB", { AL
, Ib
} },
633 { "adcS", { eAX
, Iv
} },
634 { "push{T|}", { ss
} },
635 { "pop{T|}", { ss
} },
637 { "sbbB", { Eb
, Gb
} },
638 { "sbbS", { Ev
, Gv
} },
639 { "sbbB", { Gb
, Eb
} },
640 { "sbbS", { Gv
, Ev
} },
641 { "sbbB", { AL
, Ib
} },
642 { "sbbS", { eAX
, Iv
} },
643 { "push{T|}", { ds
} },
644 { "pop{T|}", { ds
} },
646 { "andB", { Eb
, Gb
} },
647 { "andS", { Ev
, Gv
} },
648 { "andB", { Gb
, Eb
} },
649 { "andS", { Gv
, Ev
} },
650 { "andB", { AL
, Ib
} },
651 { "andS", { eAX
, Iv
} },
652 { "(bad)", { XX
} }, /* SEG ES prefix */
653 { "daa{|}", { XX
} },
655 { "subB", { Eb
, Gb
} },
656 { "subS", { Ev
, Gv
} },
657 { "subB", { Gb
, Eb
} },
658 { "subS", { Gv
, Ev
} },
659 { "subB", { AL
, Ib
} },
660 { "subS", { eAX
, Iv
} },
661 { "(bad)", { XX
} }, /* SEG CS prefix */
662 { "das{|}", { XX
} },
664 { "xorB", { Eb
, Gb
} },
665 { "xorS", { Ev
, Gv
} },
666 { "xorB", { Gb
, Eb
} },
667 { "xorS", { Gv
, Ev
} },
668 { "xorB", { AL
, Ib
} },
669 { "xorS", { eAX
, Iv
} },
670 { "(bad)", { XX
} }, /* SEG SS prefix */
671 { "aaa{|}", { XX
} },
673 { "cmpB", { Eb
, Gb
} },
674 { "cmpS", { Ev
, Gv
} },
675 { "cmpB", { Gb
, Eb
} },
676 { "cmpS", { Gv
, Ev
} },
677 { "cmpB", { AL
, Ib
} },
678 { "cmpS", { eAX
, Iv
} },
679 { "(bad)", { XX
} }, /* SEG DS prefix */
680 { "aas{|}", { XX
} },
682 { "inc{S|}", { RMeAX
} },
683 { "inc{S|}", { RMeCX
} },
684 { "inc{S|}", { RMeDX
} },
685 { "inc{S|}", { RMeBX
} },
686 { "inc{S|}", { RMeSP
} },
687 { "inc{S|}", { RMeBP
} },
688 { "inc{S|}", { RMeSI
} },
689 { "inc{S|}", { RMeDI
} },
691 { "dec{S|}", { RMeAX
} },
692 { "dec{S|}", { RMeCX
} },
693 { "dec{S|}", { RMeDX
} },
694 { "dec{S|}", { RMeBX
} },
695 { "dec{S|}", { RMeSP
} },
696 { "dec{S|}", { RMeBP
} },
697 { "dec{S|}", { RMeSI
} },
698 { "dec{S|}", { RMeDI
} },
700 { "pushV", { RMrAX
} },
701 { "pushV", { RMrCX
} },
702 { "pushV", { RMrDX
} },
703 { "pushV", { RMrBX
} },
704 { "pushV", { RMrSP
} },
705 { "pushV", { RMrBP
} },
706 { "pushV", { RMrSI
} },
707 { "pushV", { RMrDI
} },
709 { "popV", { RMrAX
} },
710 { "popV", { RMrCX
} },
711 { "popV", { RMrDX
} },
712 { "popV", { RMrBX
} },
713 { "popV", { RMrSP
} },
714 { "popV", { RMrBP
} },
715 { "popV", { RMrSI
} },
716 { "popV", { RMrDI
} },
722 { "(bad)", { XX
} }, /* seg fs */
723 { "(bad)", { XX
} }, /* seg gs */
724 { "(bad)", { XX
} }, /* op size prefix */
725 { "(bad)", { XX
} }, /* adr size prefix */
728 { "imulS", { Gv
, Ev
, Iv
} },
729 { "pushT", { sIb
} },
730 { "imulS", { Gv
, Ev
, sIb
} },
731 { "ins{b||b|}", { Ybr
, indirDX
} },
732 { "ins{R||G|}", { Yzr
, indirDX
} },
733 { "outs{b||b|}", { indirDXr
, Xb
} },
734 { "outs{R||G|}", { indirDXr
, Xz
} },
736 { "joH", { Jb
, XX
, cond_jump_flag
} },
737 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
738 { "jbH", { Jb
, XX
, cond_jump_flag
} },
739 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
740 { "jeH", { Jb
, XX
, cond_jump_flag
} },
741 { "jneH", { Jb
, XX
, cond_jump_flag
} },
742 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
743 { "jaH", { Jb
, XX
, cond_jump_flag
} },
745 { "jsH", { Jb
, XX
, cond_jump_flag
} },
746 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
747 { "jpH", { Jb
, XX
, cond_jump_flag
} },
748 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
749 { "jlH", { Jb
, XX
, cond_jump_flag
} },
750 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
751 { "jleH", { Jb
, XX
, cond_jump_flag
} },
752 { "jgH", { Jb
, XX
, cond_jump_flag
} },
758 { "testB", { Eb
, Gb
} },
759 { "testS", { Ev
, Gv
} },
760 { "xchgB", { Eb
, Gb
} },
761 { "xchgS", { Ev
, Gv
} },
763 { "movB", { Eb
, Gb
} },
764 { "movS", { Ev
, Gv
} },
765 { "movB", { Gb
, Eb
} },
766 { "movS", { Gv
, Ev
} },
767 { "movD", { Sv
, Sw
} },
768 { "leaS", { Gv
, M
} },
769 { "movD", { Sw
, Sv
} },
773 { "xchgS", { RMeCX
, eAX
} },
774 { "xchgS", { RMeDX
, eAX
} },
775 { "xchgS", { RMeBX
, eAX
} },
776 { "xchgS", { RMeSP
, eAX
} },
777 { "xchgS", { RMeBP
, eAX
} },
778 { "xchgS", { RMeSI
, eAX
} },
779 { "xchgS", { RMeDI
, eAX
} },
781 { "cW{t||t|}R", { XX
} },
782 { "cR{t||t|}O", { XX
} },
783 { "Jcall{T|}", { Ap
} },
784 { "(bad)", { XX
} }, /* fwait */
785 { "pushfT", { XX
} },
787 { "sahf{|}", { XX
} },
788 { "lahf{|}", { XX
} },
790 { "movB", { AL
, Ob
} },
791 { "movS", { eAX
, Ov
} },
792 { "movB", { Ob
, AL
} },
793 { "movS", { Ov
, eAX
} },
794 { "movs{b||b|}", { Ybr
, Xb
} },
795 { "movs{R||R|}", { Yvr
, Xv
} },
796 { "cmps{b||b|}", { Xb
, Yb
} },
797 { "cmps{R||R|}", { Xv
, Yv
} },
799 { "testB", { AL
, Ib
} },
800 { "testS", { eAX
, Iv
} },
801 { "stosB", { Ybr
, AL
} },
802 { "stosS", { Yvr
, eAX
} },
803 { "lodsB", { ALr
, Xb
} },
804 { "lodsS", { eAXr
, Xv
} },
805 { "scasB", { AL
, Yb
} },
806 { "scasS", { eAX
, Yv
} },
808 { "movB", { RMAL
, Ib
} },
809 { "movB", { RMCL
, Ib
} },
810 { "movB", { RMDL
, Ib
} },
811 { "movB", { RMBL
, Ib
} },
812 { "movB", { RMAH
, Ib
} },
813 { "movB", { RMCH
, Ib
} },
814 { "movB", { RMDH
, Ib
} },
815 { "movB", { RMBH
, Ib
} },
817 { "movS", { RMeAX
, Iv64
} },
818 { "movS", { RMeCX
, Iv64
} },
819 { "movS", { RMeDX
, Iv64
} },
820 { "movS", { RMeBX
, Iv64
} },
821 { "movS", { RMeSP
, Iv64
} },
822 { "movS", { RMeBP
, Iv64
} },
823 { "movS", { RMeSI
, Iv64
} },
824 { "movS", { RMeDI
, Iv64
} },
830 { "les{S|}", { Gv
, Mp
} },
831 { "ldsS", { Gv
, Mp
} },
835 { "enterT", { Iw
, Ib
} },
836 { "leaveT", { XX
} },
841 { "into{|}", { XX
} },
848 { "aam{|}", { sIb
} },
849 { "aad{|}", { sIb
} },
851 { "xlat", { DSBX
} },
862 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
863 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
864 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
865 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
866 { "inB", { AL
, Ib
} },
867 { "inG", { zAX
, Ib
} },
868 { "outB", { Ib
, AL
} },
869 { "outG", { Ib
, zAX
} },
873 { "Jjmp{T|}", { Ap
} },
875 { "inB", { AL
, indirDX
} },
876 { "inG", { zAX
, indirDX
} },
877 { "outB", { indirDX
, AL
} },
878 { "outG", { indirDX
, zAX
} },
880 { "(bad)", { XX
} }, /* lock prefix */
882 { "(bad)", { XX
} }, /* repne */
883 { "(bad)", { XX
} }, /* repz */
899 static const struct dis386 dis386_twobyte
[] = {
903 { "larS", { Gv
, Ew
} },
904 { "lslS", { Gv
, Ew
} },
906 { "syscall", { XX
} },
908 { "sysretP", { XX
} },
911 { "wbinvd", { XX
} },
917 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
922 { "movlpX", { EXq
, XM
, { SIMD_Fixup
, 'h' } } },
923 { "unpcklpX", { XM
, EXq
} },
924 { "unpckhpX", { XM
, EXq
} },
926 { "movhpX", { EXq
, XM
, { SIMD_Fixup
, 'l' } } },
937 { "movZ", { Rm
, Cm
} },
938 { "movZ", { Rm
, Dm
} },
939 { "movZ", { Cm
, Rm
} },
940 { "movZ", { Dm
, Rm
} },
941 { "movL", { Rd
, Td
} },
943 { "movL", { Td
, Rd
} },
946 { "movapX", { XM
, EXx
} },
947 { "movapX", { EXx
, XM
} },
959 { "sysenter", { XX
} },
960 { "sysexit", { XX
} },
973 { "cmovo", { Gv
, Ev
} },
974 { "cmovno", { Gv
, Ev
} },
975 { "cmovb", { Gv
, Ev
} },
976 { "cmovae", { Gv
, Ev
} },
977 { "cmove", { Gv
, Ev
} },
978 { "cmovne", { Gv
, Ev
} },
979 { "cmovbe", { Gv
, Ev
} },
980 { "cmova", { Gv
, Ev
} },
982 { "cmovs", { Gv
, Ev
} },
983 { "cmovns", { Gv
, Ev
} },
984 { "cmovp", { Gv
, Ev
} },
985 { "cmovnp", { Gv
, Ev
} },
986 { "cmovl", { Gv
, Ev
} },
987 { "cmovge", { Gv
, Ev
} },
988 { "cmovle", { Gv
, Ev
} },
989 { "cmovg", { Gv
, Ev
} },
991 { "movmskpX", { Gdq
, XS
} },
995 { "andpX", { XM
, EXx
} },
996 { "andnpX", { XM
, EXx
} },
997 { "orpX", { XM
, EXx
} },
998 { "xorpX", { XM
, EXx
} },
1012 { "packsswb", { MX
, EM
} },
1013 { "pcmpgtb", { MX
, EM
} },
1014 { "pcmpgtw", { MX
, EM
} },
1015 { "pcmpgtd", { MX
, EM
} },
1016 { "packuswb", { MX
, EM
} },
1018 { "punpckhbw", { MX
, EM
} },
1019 { "punpckhwd", { MX
, EM
} },
1020 { "punpckhdq", { MX
, EM
} },
1021 { "packssdw", { MX
, EM
} },
1024 { "movK", { MX
, Edq
} },
1031 { "pcmpeqb", { MX
, EM
} },
1032 { "pcmpeqw", { MX
, EM
} },
1033 { "pcmpeqd", { MX
, EM
} },
1038 { "(bad)", { XX
} },
1039 { "(bad)", { XX
} },
1045 { "joH", { Jv
, XX
, cond_jump_flag
} },
1046 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1047 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1048 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1049 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1050 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1051 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1052 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1054 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1055 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1056 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1057 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1058 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1059 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1060 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1061 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1064 { "setno", { Eb
} },
1066 { "setae", { Eb
} },
1068 { "setne", { Eb
} },
1069 { "setbe", { Eb
} },
1073 { "setns", { Eb
} },
1075 { "setnp", { Eb
} },
1077 { "setge", { Eb
} },
1078 { "setle", { Eb
} },
1081 { "pushT", { fs
} },
1083 { "cpuid", { XX
} },
1084 { "btS", { Ev
, Gv
} },
1085 { "shldS", { Ev
, Gv
, Ib
} },
1086 { "shldS", { Ev
, Gv
, CL
} },
1090 { "pushT", { gs
} },
1093 { "btsS", { Ev
, Gv
} },
1094 { "shrdS", { Ev
, Gv
, Ib
} },
1095 { "shrdS", { Ev
, Gv
, CL
} },
1097 { "imulS", { Gv
, Ev
} },
1099 { "cmpxchgB", { Eb
, Gb
} },
1100 { "cmpxchgS", { Ev
, Gv
} },
1101 { "lssS", { Gv
, Mp
} },
1102 { "btrS", { Ev
, Gv
} },
1103 { "lfsS", { Gv
, Mp
} },
1104 { "lgsS", { Gv
, Mp
} },
1105 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1106 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1111 { "btcS", { Ev
, Gv
} },
1112 { "bsfS", { Gv
, Ev
} },
1114 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1115 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1117 { "xaddB", { Eb
, Gb
} },
1118 { "xaddS", { Ev
, Gv
} },
1120 { "movntiS", { Ev
, Gv
} },
1121 { "pinsrw", { MX
, Edqw
, Ib
} },
1122 { "pextrw", { Gdq
, MS
, Ib
} },
1123 { "shufpX", { XM
, EXx
, Ib
} },
1126 { "bswap", { RMeAX
} },
1127 { "bswap", { RMeCX
} },
1128 { "bswap", { RMeDX
} },
1129 { "bswap", { RMeBX
} },
1130 { "bswap", { RMeSP
} },
1131 { "bswap", { RMeBP
} },
1132 { "bswap", { RMeSI
} },
1133 { "bswap", { RMeDI
} },
1136 { "psrlw", { MX
, EM
} },
1137 { "psrld", { MX
, EM
} },
1138 { "psrlq", { MX
, EM
} },
1139 { "paddq", { MX
, EM
} },
1140 { "pmullw", { MX
, EM
} },
1142 { "pmovmskb", { Gdq
, MS
} },
1144 { "psubusb", { MX
, EM
} },
1145 { "psubusw", { MX
, EM
} },
1146 { "pminub", { MX
, EM
} },
1147 { "pand", { MX
, EM
} },
1148 { "paddusb", { MX
, EM
} },
1149 { "paddusw", { MX
, EM
} },
1150 { "pmaxub", { MX
, EM
} },
1151 { "pandn", { MX
, EM
} },
1153 { "pavgb", { MX
, EM
} },
1154 { "psraw", { MX
, EM
} },
1155 { "psrad", { MX
, EM
} },
1156 { "pavgw", { MX
, EM
} },
1157 { "pmulhuw", { MX
, EM
} },
1158 { "pmulhw", { MX
, EM
} },
1162 { "psubsb", { MX
, EM
} },
1163 { "psubsw", { MX
, EM
} },
1164 { "pminsw", { MX
, EM
} },
1165 { "por", { MX
, EM
} },
1166 { "paddsb", { MX
, EM
} },
1167 { "paddsw", { MX
, EM
} },
1168 { "pmaxsw", { MX
, EM
} },
1169 { "pxor", { MX
, EM
} },
1172 { "psllw", { MX
, EM
} },
1173 { "pslld", { MX
, EM
} },
1174 { "psllq", { MX
, EM
} },
1175 { "pmuludq", { MX
, EM
} },
1176 { "pmaddwd", { MX
, EM
} },
1177 { "psadbw", { MX
, EM
} },
1180 { "psubb", { MX
, EM
} },
1181 { "psubw", { MX
, EM
} },
1182 { "psubd", { MX
, EM
} },
1183 { "psubq", { MX
, EM
} },
1184 { "paddb", { MX
, EM
} },
1185 { "paddw", { MX
, EM
} },
1186 { "paddd", { MX
, EM
} },
1187 { "(bad)", { XX
} },
1190 static const unsigned char onebyte_has_modrm
[256] = {
1191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1192 /* ------------------------------- */
1193 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1194 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1195 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1196 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1197 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1198 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1199 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1200 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1201 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1202 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1203 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1204 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1205 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1206 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1207 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1208 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1209 /* ------------------------------- */
1210 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1213 static const unsigned char twobyte_has_modrm
[256] = {
1214 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1215 /* ------------------------------- */
1216 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1217 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1218 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1219 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1220 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1221 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1222 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1223 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1224 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1225 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1226 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1227 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1228 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1229 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1230 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1231 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1232 /* ------------------------------- */
1233 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1236 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1237 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1238 /* ------------------------------- */
1239 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1240 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1241 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1242 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1243 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1244 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1245 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1246 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1247 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1248 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1249 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1250 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1251 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1252 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1253 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1254 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1255 /* ------------------------------- */
1256 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1259 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1260 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1261 /* ------------------------------- */
1262 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1263 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1264 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1265 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1266 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1267 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1268 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1269 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1270 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1271 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1272 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1273 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1274 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1275 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1276 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1277 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1278 /* ------------------------------- */
1279 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1282 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1283 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1284 /* ------------------------------- */
1285 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1286 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1287 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1288 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1289 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1290 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1291 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1292 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1293 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1294 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1295 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1296 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1297 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1298 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1299 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1300 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1301 /* ------------------------------- */
1302 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1305 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1306 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1307 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1308 /* ------------------------------- */
1309 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1310 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1311 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1312 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1313 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1314 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1315 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1316 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1317 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1318 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1319 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1320 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1321 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1322 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1323 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1324 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1325 /* ------------------------------- */
1326 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1329 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1330 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1331 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1332 /* ------------------------------- */
1333 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1334 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1335 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1336 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1337 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1338 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1339 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1340 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1341 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1342 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1343 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1344 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1345 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1346 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1347 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1348 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1349 /* ------------------------------- */
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1353 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1354 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1355 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1356 /* ------------------------------- */
1357 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1358 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1359 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1360 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1361 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1362 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1363 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1364 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1365 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1366 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1367 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1368 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1369 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1370 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1371 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1372 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1373 /* ------------------------------- */
1374 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1377 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1378 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1379 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1380 /* ------------------------------- */
1381 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1382 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1383 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1384 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1385 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1386 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1387 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1388 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1389 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1390 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1391 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1392 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1393 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1394 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1395 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1396 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1397 /* ------------------------------- */
1398 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1401 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1402 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1403 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1404 /* ------------------------------- */
1405 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1406 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1407 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1408 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1409 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1410 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1411 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1412 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1413 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1414 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1415 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1416 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1417 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1418 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1419 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1420 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1421 /* ------------------------------- */
1422 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1425 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1426 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1427 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1428 /* ------------------------------- */
1429 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1430 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1431 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1432 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1433 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1434 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1435 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1436 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1437 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1438 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1439 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1440 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1441 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1442 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1443 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1444 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1445 /* ------------------------------- */
1446 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1449 static char obuf
[100];
1451 static char scratchbuf
[100];
1452 static unsigned char *start_codep
;
1453 static unsigned char *insn_codep
;
1454 static unsigned char *codep
;
1455 static disassemble_info
*the_info
;
1463 static unsigned char need_modrm
;
1465 /* If we are accessing mod/rm/reg without need_modrm set, then the
1466 values are stale. Hitting this abort likely indicates that you
1467 need to update onebyte_has_modrm or twobyte_has_modrm. */
1468 #define MODRM_CHECK if (!need_modrm) abort ()
1470 static const char **names64
;
1471 static const char **names32
;
1472 static const char **names16
;
1473 static const char **names8
;
1474 static const char **names8rex
;
1475 static const char **names_seg
;
1476 static const char **index16
;
1478 static const char *intel_names64
[] = {
1479 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1480 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1482 static const char *intel_names32
[] = {
1483 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1484 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1486 static const char *intel_names16
[] = {
1487 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1488 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1490 static const char *intel_names8
[] = {
1491 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1493 static const char *intel_names8rex
[] = {
1494 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1495 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1497 static const char *intel_names_seg
[] = {
1498 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1500 static const char *intel_index16
[] = {
1501 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1504 static const char *att_names64
[] = {
1505 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1506 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1508 static const char *att_names32
[] = {
1509 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1510 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1512 static const char *att_names16
[] = {
1513 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1514 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1516 static const char *att_names8
[] = {
1517 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1519 static const char *att_names8rex
[] = {
1520 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1521 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1523 static const char *att_names_seg
[] = {
1524 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1526 static const char *att_index16
[] = {
1527 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1530 static const struct dis386 grps
[][8] = {
1533 { "popU", { stackEv
} },
1534 { "(bad)", { XX
} },
1535 { "(bad)", { XX
} },
1536 { "(bad)", { XX
} },
1537 { "(bad)", { XX
} },
1538 { "(bad)", { XX
} },
1539 { "(bad)", { XX
} },
1540 { "(bad)", { XX
} },
1544 { "addA", { Eb
, Ib
} },
1545 { "orA", { Eb
, Ib
} },
1546 { "adcA", { Eb
, Ib
} },
1547 { "sbbA", { Eb
, Ib
} },
1548 { "andA", { Eb
, Ib
} },
1549 { "subA", { Eb
, Ib
} },
1550 { "xorA", { Eb
, Ib
} },
1551 { "cmpA", { Eb
, Ib
} },
1555 { "addQ", { Ev
, Iv
} },
1556 { "orQ", { Ev
, Iv
} },
1557 { "adcQ", { Ev
, Iv
} },
1558 { "sbbQ", { Ev
, Iv
} },
1559 { "andQ", { Ev
, Iv
} },
1560 { "subQ", { Ev
, Iv
} },
1561 { "xorQ", { Ev
, Iv
} },
1562 { "cmpQ", { Ev
, Iv
} },
1566 { "addQ", { Ev
, sIb
} },
1567 { "orQ", { Ev
, sIb
} },
1568 { "adcQ", { Ev
, sIb
} },
1569 { "sbbQ", { Ev
, sIb
} },
1570 { "andQ", { Ev
, sIb
} },
1571 { "subQ", { Ev
, sIb
} },
1572 { "xorQ", { Ev
, sIb
} },
1573 { "cmpQ", { Ev
, sIb
} },
1577 { "rolA", { Eb
, Ib
} },
1578 { "rorA", { Eb
, Ib
} },
1579 { "rclA", { Eb
, Ib
} },
1580 { "rcrA", { Eb
, Ib
} },
1581 { "shlA", { Eb
, Ib
} },
1582 { "shrA", { Eb
, Ib
} },
1583 { "(bad)", { XX
} },
1584 { "sarA", { Eb
, Ib
} },
1588 { "rolQ", { Ev
, Ib
} },
1589 { "rorQ", { Ev
, Ib
} },
1590 { "rclQ", { Ev
, Ib
} },
1591 { "rcrQ", { Ev
, Ib
} },
1592 { "shlQ", { Ev
, Ib
} },
1593 { "shrQ", { Ev
, Ib
} },
1594 { "(bad)", { XX
} },
1595 { "sarQ", { Ev
, Ib
} },
1599 { "rolA", { Eb
, I1
} },
1600 { "rorA", { Eb
, I1
} },
1601 { "rclA", { Eb
, I1
} },
1602 { "rcrA", { Eb
, I1
} },
1603 { "shlA", { Eb
, I1
} },
1604 { "shrA", { Eb
, I1
} },
1605 { "(bad)", { XX
} },
1606 { "sarA", { Eb
, I1
} },
1610 { "rolQ", { Ev
, I1
} },
1611 { "rorQ", { Ev
, I1
} },
1612 { "rclQ", { Ev
, I1
} },
1613 { "rcrQ", { Ev
, I1
} },
1614 { "shlQ", { Ev
, I1
} },
1615 { "shrQ", { Ev
, I1
} },
1616 { "(bad)", { XX
} },
1617 { "sarQ", { Ev
, I1
} },
1621 { "rolA", { Eb
, CL
} },
1622 { "rorA", { Eb
, CL
} },
1623 { "rclA", { Eb
, CL
} },
1624 { "rcrA", { Eb
, CL
} },
1625 { "shlA", { Eb
, CL
} },
1626 { "shrA", { Eb
, CL
} },
1627 { "(bad)", { XX
} },
1628 { "sarA", { Eb
, CL
} },
1632 { "rolQ", { Ev
, CL
} },
1633 { "rorQ", { Ev
, CL
} },
1634 { "rclQ", { Ev
, CL
} },
1635 { "rcrQ", { Ev
, CL
} },
1636 { "shlQ", { Ev
, CL
} },
1637 { "shrQ", { Ev
, CL
} },
1638 { "(bad)", { XX
} },
1639 { "sarQ", { Ev
, CL
} },
1643 { "testA", { Eb
, Ib
} },
1644 { "(bad)", { Eb
} },
1647 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1648 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1649 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1650 { "idivA", { Eb
} }, /* and idiv for consistency. */
1654 { "testQ", { Ev
, Iv
} },
1655 { "(bad)", { XX
} },
1658 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1659 { "imulQ", { Ev
} },
1661 { "idivQ", { Ev
} },
1667 { "(bad)", { XX
} },
1668 { "(bad)", { XX
} },
1669 { "(bad)", { XX
} },
1670 { "(bad)", { XX
} },
1671 { "(bad)", { XX
} },
1672 { "(bad)", { XX
} },
1678 { "callT", { indirEv
} },
1679 { "JcallT", { indirEp
} },
1680 { "jmpT", { indirEv
} },
1681 { "JjmpT", { indirEp
} },
1682 { "pushU", { stackEv
} },
1683 { "(bad)", { XX
} },
1687 { "sldtD", { Sv
} },
1693 { "(bad)", { XX
} },
1694 { "(bad)", { XX
} },
1698 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1699 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1700 { "lgdt{Q|Q||}", { M
} },
1701 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1702 { "smswD", { Sv
} },
1703 { "(bad)", { XX
} },
1705 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1709 { "(bad)", { XX
} },
1710 { "(bad)", { XX
} },
1711 { "(bad)", { XX
} },
1712 { "(bad)", { XX
} },
1713 { "btQ", { Ev
, Ib
} },
1714 { "btsQ", { Ev
, Ib
} },
1715 { "btrQ", { Ev
, Ib
} },
1716 { "btcQ", { Ev
, Ib
} },
1720 { "(bad)", { XX
} },
1721 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1724 { "(bad)", { XX
} },
1725 { "(bad)", { XX
} },
1726 { "", { VM
} }, /* See OP_VMX. */
1727 { "vmptrst", { Mq
} },
1731 { "movA", { Eb
, Ib
} },
1732 { "(bad)", { XX
} },
1733 { "(bad)", { XX
} },
1734 { "(bad)", { XX
} },
1735 { "(bad)", { XX
} },
1736 { "(bad)", { XX
} },
1737 { "(bad)", { XX
} },
1738 { "(bad)", { XX
} },
1742 { "movQ", { Ev
, Iv
} },
1743 { "(bad)", { XX
} },
1744 { "(bad)", { XX
} },
1745 { "(bad)", { XX
} },
1746 { "(bad)", { XX
} },
1747 { "(bad)", { XX
} },
1748 { "(bad)", { XX
} },
1749 { "(bad)", { XX
} },
1753 { "(bad)", { XX
} },
1754 { "(bad)", { XX
} },
1755 { "psrlw", { MS
, Ib
} },
1756 { "(bad)", { XX
} },
1757 { "psraw", { MS
, Ib
} },
1758 { "(bad)", { XX
} },
1759 { "psllw", { MS
, Ib
} },
1760 { "(bad)", { XX
} },
1764 { "(bad)", { XX
} },
1765 { "(bad)", { XX
} },
1766 { "psrld", { MS
, Ib
} },
1767 { "(bad)", { XX
} },
1768 { "psrad", { MS
, Ib
} },
1769 { "(bad)", { XX
} },
1770 { "pslld", { MS
, Ib
} },
1771 { "(bad)", { XX
} },
1775 { "(bad)", { XX
} },
1776 { "(bad)", { XX
} },
1777 { "psrlq", { MS
, Ib
} },
1778 { "psrldq", { MS
, Ib
} },
1779 { "(bad)", { XX
} },
1780 { "(bad)", { XX
} },
1781 { "psllq", { MS
, Ib
} },
1782 { "pslldq", { MS
, Ib
} },
1786 { "fxsave", { Ev
} },
1787 { "fxrstor", { Ev
} },
1788 { "ldmxcsr", { Ev
} },
1789 { "stmxcsr", { Ev
} },
1790 { "(bad)", { XX
} },
1791 { "lfence", { { OP_0fae
, 0 } } },
1792 { "mfence", { { OP_0fae
, 0 } } },
1793 { "clflush", { { OP_0fae
, 0 } } },
1797 { "prefetchnta", { Ev
} },
1798 { "prefetcht0", { Ev
} },
1799 { "prefetcht1", { Ev
} },
1800 { "prefetcht2", { Ev
} },
1801 { "(bad)", { XX
} },
1802 { "(bad)", { XX
} },
1803 { "(bad)", { XX
} },
1804 { "(bad)", { XX
} },
1808 { "prefetch", { Eb
} },
1809 { "prefetchw", { Eb
} },
1810 { "(bad)", { XX
} },
1811 { "(bad)", { XX
} },
1812 { "(bad)", { XX
} },
1813 { "(bad)", { XX
} },
1814 { "(bad)", { XX
} },
1815 { "(bad)", { XX
} },
1819 { "xstore-rng", { { OP_0f07
, 0 } } },
1820 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1821 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1822 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1823 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1824 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1825 { "(bad)", { { OP_0f07
, 0 } } },
1826 { "(bad)", { { OP_0f07
, 0 } } },
1830 { "montmul", { { OP_0f07
, 0 } } },
1831 { "xsha1", { { OP_0f07
, 0 } } },
1832 { "xsha256", { { OP_0f07
, 0 } } },
1833 { "(bad)", { { OP_0f07
, 0 } } },
1834 { "(bad)", { { OP_0f07
, 0 } } },
1835 { "(bad)", { { OP_0f07
, 0 } } },
1836 { "(bad)", { { OP_0f07
, 0 } } },
1837 { "(bad)", { { OP_0f07
, 0 } } },
1841 static const struct dis386 prefix_user_table
[][4] = {
1844 { "addps", { XM
, EXx
} },
1845 { "addss", { XM
, EXd
} },
1846 { "addpd", { XM
, EXx
} },
1847 { "addsd", { XM
, EXq
} },
1851 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1852 { "", { XM
, EXd
, OPSIMD
} },
1853 { "", { XM
, EXx
, OPSIMD
} },
1854 { "", { XM
, EXq
, OPSIMD
} },
1858 { "cvtpi2ps", { XM
, EMCq
} },
1859 { "cvtsi2ssY", { XM
, Ev
} },
1860 { "cvtpi2pd", { XM
, EMCq
} },
1861 { "cvtsi2sdY", { XM
, Ev
} },
1865 { "cvtps2pi", { MXC
, EXq
} },
1866 { "cvtss2siY", { Gv
, EXd
} },
1867 { "cvtpd2pi", { MXC
, EXx
} },
1868 { "cvtsd2siY", { Gv
, EXq
} },
1872 { "cvttps2pi", { MXC
, EXq
} },
1873 { "cvttss2siY", { Gv
, EXd
} },
1874 { "cvttpd2pi", { MXC
, EXx
} },
1875 { "cvttsd2siY", { Gv
, EXq
} },
1879 { "divps", { XM
, EXx
} },
1880 { "divss", { XM
, EXd
} },
1881 { "divpd", { XM
, EXx
} },
1882 { "divsd", { XM
, EXq
} },
1886 { "maxps", { XM
, EXx
} },
1887 { "maxss", { XM
, EXd
} },
1888 { "maxpd", { XM
, EXx
} },
1889 { "maxsd", { XM
, EXq
} },
1893 { "minps", { XM
, EXx
} },
1894 { "minss", { XM
, EXd
} },
1895 { "minpd", { XM
, EXx
} },
1896 { "minsd", { XM
, EXq
} },
1900 { "movups", { XM
, EXx
} },
1901 { "movss", { XM
, EXd
} },
1902 { "movupd", { XM
, EXx
} },
1903 { "movsd", { XM
, EXq
} },
1907 { "movups", { EXx
, XM
} },
1908 { "movss", { EXd
, XM
} },
1909 { "movupd", { EXx
, XM
} },
1910 { "movsd", { EXq
, XM
} },
1914 { "mulps", { XM
, EXx
} },
1915 { "mulss", { XM
, EXd
} },
1916 { "mulpd", { XM
, EXx
} },
1917 { "mulsd", { XM
, EXq
} },
1921 { "rcpps", { XM
, EXx
} },
1922 { "rcpss", { XM
, EXd
} },
1923 { "(bad)", { XM
, EXx
} },
1924 { "(bad)", { XM
, EXx
} },
1928 { "rsqrtps",{ XM
, EXx
} },
1929 { "rsqrtss",{ XM
, EXd
} },
1930 { "(bad)", { XM
, EXx
} },
1931 { "(bad)", { XM
, EXx
} },
1935 { "sqrtps", { XM
, EXx
} },
1936 { "sqrtss", { XM
, EXd
} },
1937 { "sqrtpd", { XM
, EXx
} },
1938 { "sqrtsd", { XM
, EXq
} },
1942 { "subps", { XM
, EXx
} },
1943 { "subss", { XM
, EXd
} },
1944 { "subpd", { XM
, EXx
} },
1945 { "subsd", { XM
, EXq
} },
1949 { "(bad)", { XM
, EXx
} },
1950 { "cvtdq2pd", { XM
, EXq
} },
1951 { "cvttpd2dq", { XM
, EXx
} },
1952 { "cvtpd2dq", { XM
, EXx
} },
1956 { "cvtdq2ps", { XM
, EXx
} },
1957 { "cvttps2dq", { XM
, EXx
} },
1958 { "cvtps2dq", { XM
, EXx
} },
1959 { "(bad)", { XM
, EXx
} },
1963 { "cvtps2pd", { XM
, EXq
} },
1964 { "cvtss2sd", { XM
, EXd
} },
1965 { "cvtpd2ps", { XM
, EXx
} },
1966 { "cvtsd2ss", { XM
, EXq
} },
1970 { "maskmovq", { MX
, MS
} },
1971 { "(bad)", { XM
, EXx
} },
1972 { "maskmovdqu", { XM
, XS
} },
1973 { "(bad)", { XM
, EXx
} },
1977 { "movq", { MX
, EM
} },
1978 { "movdqu", { XM
, EXx
} },
1979 { "movdqa", { XM
, EXx
} },
1980 { "(bad)", { XM
, EXx
} },
1984 { "movq", { EM
, MX
} },
1985 { "movdqu", { EXx
, XM
} },
1986 { "movdqa", { EXx
, XM
} },
1987 { "(bad)", { EXx
, XM
} },
1991 { "(bad)", { EXx
, XM
} },
1992 { "movq2dq",{ XM
, MS
} },
1993 { "movq", { EXq
, XM
} },
1994 { "movdq2q",{ MX
, XS
} },
1998 { "pshufw", { MX
, EM
, Ib
} },
1999 { "pshufhw",{ XM
, EXx
, Ib
} },
2000 { "pshufd", { XM
, EXx
, Ib
} },
2001 { "pshuflw",{ XM
, EXx
, Ib
} },
2005 { "movK", { Edq
, MX
} },
2006 { "movq", { XM
, EXq
} },
2007 { "movK", { Edq
, XM
} },
2008 { "(bad)", { Ed
, XM
} },
2012 { "(bad)", { MX
, EXx
} },
2013 { "(bad)", { XM
, EXx
} },
2014 { "punpckhqdq", { XM
, EXx
} },
2015 { "(bad)", { XM
, EXx
} },
2019 { "movntq", { EM
, MX
} },
2020 { "(bad)", { EM
, XM
} },
2021 { "movntdq",{ EM
, XM
} },
2022 { "(bad)", { EM
, XM
} },
2026 { "(bad)", { MX
, EXx
} },
2027 { "(bad)", { XM
, EXx
} },
2028 { "punpcklqdq", { XM
, EXx
} },
2029 { "(bad)", { XM
, EXx
} },
2033 { "(bad)", { MX
, EXx
} },
2034 { "(bad)", { XM
, EXx
} },
2035 { "addsubpd", { XM
, EXx
} },
2036 { "addsubps", { XM
, EXx
} },
2040 { "(bad)", { MX
, EXx
} },
2041 { "(bad)", { XM
, EXx
} },
2042 { "haddpd", { XM
, EXx
} },
2043 { "haddps", { XM
, EXx
} },
2047 { "(bad)", { MX
, EXx
} },
2048 { "(bad)", { XM
, EXx
} },
2049 { "hsubpd", { XM
, EXx
} },
2050 { "hsubps", { XM
, EXx
} },
2054 { "movlpX", { XM
, EXq
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
2055 { "movsldup", { XM
, EXx
} },
2056 { "movlpd", { XM
, EXq
} },
2057 { "movddup", { XM
, EXq
} },
2061 { "movhpX", { XM
, EXq
, { SIMD_Fixup
, 'l' } } },
2062 { "movshdup", { XM
, EXx
} },
2063 { "movhpd", { XM
, EXq
} },
2064 { "(bad)", { XM
, EXq
} },
2068 { "(bad)", { XM
, EXx
} },
2069 { "(bad)", { XM
, EXx
} },
2070 { "(bad)", { XM
, EXx
} },
2071 { "lddqu", { XM
, M
} },
2075 {"movntps", { Ev
, XM
} },
2076 {"movntss", { Ed
, XM
} },
2077 {"movntpd", { Ev
, XM
} },
2078 {"movntsd", { Eq
, XM
} },
2083 {"vmread", { Em
, Gm
} },
2085 {"extrq", { XS
, Ib
, Ib
} },
2086 {"insertq", { XM
, XS
, Ib
, Ib
} },
2091 {"vmwrite", { Gm
, Em
} },
2093 {"extrq", { XM
, XS
} },
2094 {"insertq", { XM
, XS
} },
2099 { "bsrS", { Gv
, Ev
} },
2100 { "lzcntS", { Gv
, Ev
} },
2101 { "bsrS", { Gv
, Ev
} },
2102 { "(bad)", { XX
} },
2107 { "(bad)", { XX
} },
2108 { "popcntS", { Gv
, Ev
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2115 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2116 { "pause", { XX
} },
2117 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2118 { "(bad)", { XX
} },
2123 { "(bad)", { XX
} },
2124 { "(bad)", { XX
} },
2125 { "pblendvb", {XM
, EXx
, XMM0
} },
2126 { "(bad)", { XX
} },
2131 { "(bad)", { XX
} },
2132 { "(bad)", { XX
} },
2133 { "blendvps", {XM
, EXx
, XMM0
} },
2134 { "(bad)", { XX
} },
2139 { "(bad)", { XX
} },
2140 { "(bad)", { XX
} },
2141 { "blendvpd", { XM
, EXx
, XMM0
} },
2142 { "(bad)", { XX
} },
2147 { "(bad)", { XX
} },
2148 { "(bad)", { XX
} },
2149 { "ptest", { XM
, EXx
} },
2150 { "(bad)", { XX
} },
2155 { "(bad)", { XX
} },
2156 { "(bad)", { XX
} },
2157 { "pmovsxbw", { XM
, EXq
} },
2158 { "(bad)", { XX
} },
2163 { "(bad)", { XX
} },
2164 { "(bad)", { XX
} },
2165 { "pmovsxbd", { XM
, EXd
} },
2166 { "(bad)", { XX
} },
2171 { "(bad)", { XX
} },
2172 { "(bad)", { XX
} },
2173 { "pmovsxbq", { XM
, EXw
} },
2174 { "(bad)", { XX
} },
2179 { "(bad)", { XX
} },
2180 { "(bad)", { XX
} },
2181 { "pmovsxwd", { XM
, EXq
} },
2182 { "(bad)", { XX
} },
2187 { "(bad)", { XX
} },
2188 { "(bad)", { XX
} },
2189 { "pmovsxwq", { XM
, EXd
} },
2190 { "(bad)", { XX
} },
2195 { "(bad)", { XX
} },
2196 { "(bad)", { XX
} },
2197 { "pmovsxdq", { XM
, EXq
} },
2198 { "(bad)", { XX
} },
2203 { "(bad)", { XX
} },
2204 { "(bad)", { XX
} },
2205 { "pmuldq", { XM
, EXx
} },
2206 { "(bad)", { XX
} },
2211 { "(bad)", { XX
} },
2212 { "(bad)", { XX
} },
2213 { "pcmpeqq", { XM
, EXx
} },
2214 { "(bad)", { XX
} },
2219 { "(bad)", { XX
} },
2220 { "(bad)", { XX
} },
2221 { "movntdqa", { XM
, EM
} },
2222 { "(bad)", { XX
} },
2227 { "(bad)", { XX
} },
2228 { "(bad)", { XX
} },
2229 { "packusdw", { XM
, EXx
} },
2230 { "(bad)", { XX
} },
2235 { "(bad)", { XX
} },
2236 { "(bad)", { XX
} },
2237 { "pmovzxbw", { XM
, EXq
} },
2238 { "(bad)", { XX
} },
2243 { "(bad)", { XX
} },
2244 { "(bad)", { XX
} },
2245 { "pmovzxbd", { XM
, EXd
} },
2246 { "(bad)", { XX
} },
2251 { "(bad)", { XX
} },
2252 { "(bad)", { XX
} },
2253 { "pmovzxbq", { XM
, EXw
} },
2254 { "(bad)", { XX
} },
2259 { "(bad)", { XX
} },
2260 { "(bad)", { XX
} },
2261 { "pmovzxwd", { XM
, EXq
} },
2262 { "(bad)", { XX
} },
2267 { "(bad)", { XX
} },
2268 { "(bad)", { XX
} },
2269 { "pmovzxwq", { XM
, EXd
} },
2270 { "(bad)", { XX
} },
2275 { "(bad)", { XX
} },
2276 { "(bad)", { XX
} },
2277 { "pmovzxdq", { XM
, EXq
} },
2278 { "(bad)", { XX
} },
2283 { "(bad)", { XX
} },
2284 { "(bad)", { XX
} },
2285 { "pminsb", { XM
, EXx
} },
2286 { "(bad)", { XX
} },
2291 { "(bad)", { XX
} },
2292 { "(bad)", { XX
} },
2293 { "pminsd", { XM
, EXx
} },
2294 { "(bad)", { XX
} },
2299 { "(bad)", { XX
} },
2300 { "(bad)", { XX
} },
2301 { "pminuw", { XM
, EXx
} },
2302 { "(bad)", { XX
} },
2307 { "(bad)", { XX
} },
2308 { "(bad)", { XX
} },
2309 { "pminud", { XM
, EXx
} },
2310 { "(bad)", { XX
} },
2315 { "(bad)", { XX
} },
2316 { "(bad)", { XX
} },
2317 { "pmaxsb", { XM
, EXx
} },
2318 { "(bad)", { XX
} },
2323 { "(bad)", { XX
} },
2324 { "(bad)", { XX
} },
2325 { "pmaxsd", { XM
, EXx
} },
2326 { "(bad)", { XX
} },
2331 { "(bad)", { XX
} },
2332 { "(bad)", { XX
} },
2333 { "pmaxuw", { XM
, EXx
} },
2334 { "(bad)", { XX
} },
2339 { "(bad)", { XX
} },
2340 { "(bad)", { XX
} },
2341 { "pmaxud", { XM
, EXx
} },
2342 { "(bad)", { XX
} },
2347 { "(bad)", { XX
} },
2348 { "(bad)", { XX
} },
2349 { "pmulld", { XM
, EXx
} },
2350 { "(bad)", { XX
} },
2355 { "(bad)", { XX
} },
2356 { "(bad)", { XX
} },
2357 { "phminposuw", { XM
, EXx
} },
2358 { "(bad)", { XX
} },
2363 { "(bad)", { XX
} },
2364 { "(bad)", { XX
} },
2365 { "roundps", { XM
, EXx
, Ib
} },
2366 { "(bad)", { XX
} },
2371 { "(bad)", { XX
} },
2372 { "(bad)", { XX
} },
2373 { "roundpd", { XM
, EXx
, Ib
} },
2374 { "(bad)", { XX
} },
2379 { "(bad)", { XX
} },
2380 { "(bad)", { XX
} },
2381 { "roundss", { XM
, EXd
, Ib
} },
2382 { "(bad)", { XX
} },
2387 { "(bad)", { XX
} },
2388 { "(bad)", { XX
} },
2389 { "roundsd", { XM
, EXq
, Ib
} },
2390 { "(bad)", { XX
} },
2395 { "(bad)", { XX
} },
2396 { "(bad)", { XX
} },
2397 { "blendps", { XM
, EXx
, Ib
} },
2398 { "(bad)", { XX
} },
2403 { "(bad)", { XX
} },
2404 { "(bad)", { XX
} },
2405 { "blendpd", { XM
, EXx
, Ib
} },
2406 { "(bad)", { XX
} },
2411 { "(bad)", { XX
} },
2412 { "(bad)", { XX
} },
2413 { "pblendw", { XM
, EXx
, Ib
} },
2414 { "(bad)", { XX
} },
2419 { "(bad)", { XX
} },
2420 { "(bad)", { XX
} },
2421 { "pextrb", { Edqb
, XM
, Ib
} },
2422 { "(bad)", { XX
} },
2427 { "(bad)", { XX
} },
2428 { "(bad)", { XX
} },
2429 { "pextrw", { Edqw
, XM
, Ib
} },
2430 { "(bad)", { XX
} },
2435 { "(bad)", { XX
} },
2436 { "(bad)", { XX
} },
2437 { "pextrK", { Edq
, XM
, Ib
} },
2438 { "(bad)", { XX
} },
2443 { "(bad)", { XX
} },
2444 { "(bad)", { XX
} },
2445 { "extractps", { Edqd
, XM
, Ib
} },
2446 { "(bad)", { XX
} },
2451 { "(bad)", { XX
} },
2452 { "(bad)", { XX
} },
2453 { "pinsrb", { XM
, Edqb
, Ib
} },
2454 { "(bad)", { XX
} },
2459 { "(bad)", { XX
} },
2460 { "(bad)", { XX
} },
2461 { "insertps", { XM
, EXd
, Ib
} },
2462 { "(bad)", { XX
} },
2467 { "(bad)", { XX
} },
2468 { "(bad)", { XX
} },
2469 { "pinsrK", { XM
, Edq
, Ib
} },
2470 { "(bad)", { XX
} },
2475 { "(bad)", { XX
} },
2476 { "(bad)", { XX
} },
2477 { "dpps", { XM
, EXx
, Ib
} },
2478 { "(bad)", { XX
} },
2483 { "(bad)", { XX
} },
2484 { "(bad)", { XX
} },
2485 { "dppd", { XM
, EXx
, Ib
} },
2486 { "(bad)", { XX
} },
2491 { "(bad)", { XX
} },
2492 { "(bad)", { XX
} },
2493 { "mpsadbw", { XM
, EXx
, Ib
} },
2494 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2500 { "(bad)", { XX
} },
2501 { "pcmpgtq", { XM
, EXx
} },
2502 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "(bad)", { XX
} },
2509 { "(bad)", { XX
} },
2510 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2515 { "(bad)", { XX
} },
2516 { "(bad)", { XX
} },
2517 { "(bad)", { XX
} },
2518 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2523 { "(bad)", { XX
} },
2524 { "(bad)", { XX
} },
2525 { "pcmpestrm", { XM
, EXx
, Ib
} },
2526 { "(bad)", { XX
} },
2531 { "(bad)", { XX
} },
2532 { "(bad)", { XX
} },
2533 { "pcmpestri", { XM
, EXx
, Ib
} },
2534 { "(bad)", { XX
} },
2539 { "(bad)", { XX
} },
2540 { "(bad)", { XX
} },
2541 { "pcmpistrm", { XM
, EXx
, Ib
} },
2542 { "(bad)", { XX
} },
2547 { "(bad)", { XX
} },
2548 { "(bad)", { XX
} },
2549 { "pcmpistri", { XM
, EXx
, Ib
} },
2550 { "(bad)", { XX
} },
2555 { "ucomiss",{ XM
, EXd
} },
2556 { "(bad)", { XX
} },
2557 { "ucomisd",{ XM
, EXq
} },
2558 { "(bad)", { XX
} },
2563 { "comiss", { XM
, EXd
} },
2564 { "(bad)", { XX
} },
2565 { "comisd", { XM
, EXq
} },
2566 { "(bad)", { XX
} },
2571 { "punpcklbw",{ MX
, EMd
} },
2572 { "(bad)", { XX
} },
2573 { "punpcklbw",{ MX
, EMx
} },
2574 { "(bad)", { XX
} },
2579 { "punpcklwd",{ MX
, EMd
} },
2580 { "(bad)", { XX
} },
2581 { "punpcklwd",{ MX
, EMx
} },
2582 { "(bad)", { XX
} },
2587 { "punpckldq",{ MX
, EMd
} },
2588 { "(bad)", { XX
} },
2589 { "punpckldq",{ MX
, EMx
} },
2590 { "(bad)", { XX
} },
2594 static const struct dis386 x86_64_table
[][2] = {
2596 { "pusha{P|}", { XX
} },
2597 { "(bad)", { XX
} },
2600 { "popa{P|}", { XX
} },
2601 { "(bad)", { XX
} },
2604 { "bound{S|}", { Gv
, Ma
} },
2605 { "(bad)", { XX
} },
2608 { "arpl", { Ew
, Gw
} },
2609 { "movs{||lq|xd}", { Gv
, Ed
} },
2613 static const struct dis386 three_byte_table
[][256] = {
2617 { "pshufb", { MX
, EM
} },
2618 { "phaddw", { MX
, EM
} },
2619 { "phaddd", { MX
, EM
} },
2620 { "phaddsw", { MX
, EM
} },
2621 { "pmaddubsw", { MX
, EM
} },
2622 { "phsubw", { MX
, EM
} },
2623 { "phsubd", { MX
, EM
} },
2624 { "phsubsw", { MX
, EM
} },
2626 { "psignb", { MX
, EM
} },
2627 { "psignw", { MX
, EM
} },
2628 { "psignd", { MX
, EM
} },
2629 { "pmulhrsw", { MX
, EM
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2632 { "(bad)", { XX
} },
2633 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2637 { "(bad)", { XX
} },
2638 { "(bad)", { XX
} },
2641 { "(bad)", { XX
} },
2644 { "(bad)", { XX
} },
2645 { "(bad)", { XX
} },
2646 { "(bad)", { XX
} },
2647 { "(bad)", { XX
} },
2648 { "pabsb", { MX
, EM
} },
2649 { "pabsw", { MX
, EM
} },
2650 { "pabsd", { MX
, EM
} },
2651 { "(bad)", { XX
} },
2659 { "(bad)", { XX
} },
2660 { "(bad)", { XX
} },
2666 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2669 { "(bad)", { XX
} },
2677 { "(bad)", { XX
} },
2691 { "(bad)", { XX
} },
2692 { "(bad)", { XX
} },
2693 { "(bad)", { XX
} },
2694 { "(bad)", { XX
} },
2695 { "(bad)", { XX
} },
2696 { "(bad)", { XX
} },
2698 { "(bad)", { XX
} },
2699 { "(bad)", { XX
} },
2700 { "(bad)", { XX
} },
2701 { "(bad)", { XX
} },
2702 { "(bad)", { XX
} },
2703 { "(bad)", { XX
} },
2704 { "(bad)", { XX
} },
2705 { "(bad)", { XX
} },
2707 { "(bad)", { XX
} },
2708 { "(bad)", { XX
} },
2709 { "(bad)", { XX
} },
2710 { "(bad)", { XX
} },
2711 { "(bad)", { XX
} },
2712 { "(bad)", { XX
} },
2713 { "(bad)", { XX
} },
2714 { "(bad)", { XX
} },
2716 { "(bad)", { XX
} },
2717 { "(bad)", { XX
} },
2718 { "(bad)", { XX
} },
2719 { "(bad)", { XX
} },
2720 { "(bad)", { XX
} },
2721 { "(bad)", { XX
} },
2722 { "(bad)", { XX
} },
2723 { "(bad)", { XX
} },
2725 { "(bad)", { XX
} },
2726 { "(bad)", { XX
} },
2727 { "(bad)", { XX
} },
2728 { "(bad)", { XX
} },
2729 { "(bad)", { XX
} },
2730 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2734 { "(bad)", { XX
} },
2735 { "(bad)", { XX
} },
2736 { "(bad)", { XX
} },
2737 { "(bad)", { XX
} },
2738 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2741 { "(bad)", { XX
} },
2743 { "(bad)", { XX
} },
2744 { "(bad)", { XX
} },
2745 { "(bad)", { XX
} },
2746 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "(bad)", { XX
} },
2750 { "(bad)", { XX
} },
2752 { "(bad)", { XX
} },
2753 { "(bad)", { XX
} },
2754 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "(bad)", { XX
} },
2758 { "(bad)", { XX
} },
2759 { "(bad)", { XX
} },
2761 { "(bad)", { XX
} },
2762 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "(bad)", { XX
} },
2766 { "(bad)", { XX
} },
2767 { "(bad)", { XX
} },
2768 { "(bad)", { XX
} },
2770 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "(bad)", { XX
} },
2774 { "(bad)", { XX
} },
2775 { "(bad)", { XX
} },
2776 { "(bad)", { XX
} },
2777 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "(bad)", { XX
} },
2782 { "(bad)", { XX
} },
2783 { "(bad)", { XX
} },
2784 { "(bad)", { XX
} },
2785 { "(bad)", { XX
} },
2786 { "(bad)", { XX
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2790 { "(bad)", { XX
} },
2791 { "(bad)", { XX
} },
2792 { "(bad)", { XX
} },
2793 { "(bad)", { XX
} },
2794 { "(bad)", { XX
} },
2795 { "(bad)", { XX
} },
2797 { "(bad)", { XX
} },
2798 { "(bad)", { XX
} },
2799 { "(bad)", { XX
} },
2800 { "(bad)", { XX
} },
2801 { "(bad)", { XX
} },
2802 { "(bad)", { XX
} },
2803 { "(bad)", { XX
} },
2804 { "(bad)", { XX
} },
2806 { "(bad)", { XX
} },
2807 { "(bad)", { XX
} },
2808 { "(bad)", { XX
} },
2809 { "(bad)", { XX
} },
2810 { "(bad)", { XX
} },
2811 { "(bad)", { XX
} },
2812 { "(bad)", { XX
} },
2813 { "(bad)", { XX
} },
2815 { "(bad)", { XX
} },
2816 { "(bad)", { XX
} },
2817 { "(bad)", { XX
} },
2818 { "(bad)", { XX
} },
2819 { "(bad)", { XX
} },
2820 { "(bad)", { XX
} },
2821 { "(bad)", { XX
} },
2822 { "(bad)", { XX
} },
2824 { "(bad)", { XX
} },
2825 { "(bad)", { XX
} },
2826 { "(bad)", { XX
} },
2827 { "(bad)", { XX
} },
2828 { "(bad)", { XX
} },
2829 { "(bad)", { XX
} },
2830 { "(bad)", { XX
} },
2831 { "(bad)", { XX
} },
2833 { "(bad)", { XX
} },
2834 { "(bad)", { XX
} },
2835 { "(bad)", { XX
} },
2836 { "(bad)", { XX
} },
2837 { "(bad)", { XX
} },
2838 { "(bad)", { XX
} },
2839 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2843 { "(bad)", { XX
} },
2844 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2848 { "(bad)", { XX
} },
2849 { "(bad)", { XX
} },
2851 { "(bad)", { XX
} },
2852 { "(bad)", { XX
} },
2853 { "(bad)", { XX
} },
2854 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2857 { "(bad)", { XX
} },
2858 { "(bad)", { XX
} },
2860 { "(bad)", { XX
} },
2861 { "(bad)", { XX
} },
2862 { "(bad)", { XX
} },
2863 { "(bad)", { XX
} },
2864 { "(bad)", { XX
} },
2865 { "(bad)", { XX
} },
2866 { "(bad)", { XX
} },
2867 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2870 { "(bad)", { XX
} },
2871 { "(bad)", { XX
} },
2872 { "(bad)", { XX
} },
2873 { "(bad)", { XX
} },
2874 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2876 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2879 { "(bad)", { XX
} },
2880 { "(bad)", { XX
} },
2881 { "(bad)", { XX
} },
2882 { "(bad)", { XX
} },
2883 { "(bad)", { XX
} },
2884 { "(bad)", { XX
} },
2885 { "(bad)", { XX
} },
2889 { "(bad)", { XX
} },
2890 { "(bad)", { XX
} },
2891 { "(bad)", { XX
} },
2892 { "(bad)", { XX
} },
2893 { "(bad)", { XX
} },
2894 { "(bad)", { XX
} },
2896 { "(bad)", { XX
} },
2897 { "(bad)", { XX
} },
2898 { "(bad)", { XX
} },
2899 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2903 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2915 { "(bad)", { XX
} },
2924 { "palignr", { MX
, EM
, Ib
} },
2926 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2928 { "(bad)", { XX
} },
2929 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2942 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2951 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2960 { "(bad)", { XX
} },
2962 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2969 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2978 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2987 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2996 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3005 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3014 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3023 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3032 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3041 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3050 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3059 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3067 { "(bad)", { XX
} },
3068 { "(bad)", { XX
} },
3070 { "(bad)", { XX
} },
3071 { "(bad)", { XX
} },
3072 { "(bad)", { XX
} },
3073 { "(bad)", { XX
} },
3074 { "(bad)", { XX
} },
3075 { "(bad)", { XX
} },
3076 { "(bad)", { XX
} },
3077 { "(bad)", { XX
} },
3079 { "(bad)", { XX
} },
3080 { "(bad)", { XX
} },
3081 { "(bad)", { XX
} },
3082 { "(bad)", { XX
} },
3083 { "(bad)", { XX
} },
3084 { "(bad)", { XX
} },
3085 { "(bad)", { XX
} },
3086 { "(bad)", { XX
} },
3088 { "(bad)", { XX
} },
3089 { "(bad)", { XX
} },
3090 { "(bad)", { XX
} },
3091 { "(bad)", { XX
} },
3092 { "(bad)", { XX
} },
3093 { "(bad)", { XX
} },
3094 { "(bad)", { XX
} },
3095 { "(bad)", { XX
} },
3097 { "(bad)", { XX
} },
3098 { "(bad)", { XX
} },
3099 { "(bad)", { XX
} },
3100 { "(bad)", { XX
} },
3101 { "(bad)", { XX
} },
3102 { "(bad)", { XX
} },
3103 { "(bad)", { XX
} },
3104 { "(bad)", { XX
} },
3106 { "(bad)", { XX
} },
3107 { "(bad)", { XX
} },
3108 { "(bad)", { XX
} },
3109 { "(bad)", { XX
} },
3110 { "(bad)", { XX
} },
3111 { "(bad)", { XX
} },
3112 { "(bad)", { XX
} },
3113 { "(bad)", { XX
} },
3115 { "(bad)", { XX
} },
3116 { "(bad)", { XX
} },
3117 { "(bad)", { XX
} },
3118 { "(bad)", { XX
} },
3119 { "(bad)", { XX
} },
3120 { "(bad)", { XX
} },
3121 { "(bad)", { XX
} },
3122 { "(bad)", { XX
} },
3124 { "(bad)", { XX
} },
3125 { "(bad)", { XX
} },
3126 { "(bad)", { XX
} },
3127 { "(bad)", { XX
} },
3128 { "(bad)", { XX
} },
3129 { "(bad)", { XX
} },
3130 { "(bad)", { XX
} },
3131 { "(bad)", { XX
} },
3133 { "(bad)", { XX
} },
3134 { "(bad)", { XX
} },
3135 { "(bad)", { XX
} },
3136 { "(bad)", { XX
} },
3137 { "(bad)", { XX
} },
3138 { "(bad)", { XX
} },
3139 { "(bad)", { XX
} },
3140 { "(bad)", { XX
} },
3142 { "(bad)", { XX
} },
3143 { "(bad)", { XX
} },
3144 { "(bad)", { XX
} },
3145 { "(bad)", { XX
} },
3146 { "(bad)", { XX
} },
3147 { "(bad)", { XX
} },
3148 { "(bad)", { XX
} },
3149 { "(bad)", { XX
} },
3151 { "(bad)", { XX
} },
3152 { "(bad)", { XX
} },
3153 { "(bad)", { XX
} },
3154 { "(bad)", { XX
} },
3155 { "(bad)", { XX
} },
3156 { "(bad)", { XX
} },
3157 { "(bad)", { XX
} },
3158 { "(bad)", { XX
} },
3160 { "(bad)", { XX
} },
3161 { "(bad)", { XX
} },
3162 { "(bad)", { XX
} },
3163 { "(bad)", { XX
} },
3164 { "(bad)", { XX
} },
3165 { "(bad)", { XX
} },
3166 { "(bad)", { XX
} },
3167 { "(bad)", { XX
} },
3169 { "(bad)", { XX
} },
3170 { "(bad)", { XX
} },
3171 { "(bad)", { XX
} },
3172 { "(bad)", { XX
} },
3173 { "(bad)", { XX
} },
3174 { "(bad)", { XX
} },
3175 { "(bad)", { XX
} },
3176 { "(bad)", { XX
} },
3178 { "(bad)", { XX
} },
3179 { "(bad)", { XX
} },
3180 { "(bad)", { XX
} },
3181 { "(bad)", { XX
} },
3182 { "(bad)", { XX
} },
3183 { "(bad)", { XX
} },
3184 { "(bad)", { XX
} },
3185 { "(bad)", { XX
} },
3187 { "(bad)", { XX
} },
3188 { "(bad)", { XX
} },
3189 { "(bad)", { XX
} },
3190 { "(bad)", { XX
} },
3191 { "(bad)", { XX
} },
3192 { "(bad)", { XX
} },
3193 { "(bad)", { XX
} },
3194 { "(bad)", { XX
} },
3198 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3210 FETCH_DATA (the_info
, codep
+ 1);
3214 /* REX prefixes family. */
3231 if (address_mode
== mode_64bit
)
3237 prefixes
|= PREFIX_REPZ
;
3240 prefixes
|= PREFIX_REPNZ
;
3243 prefixes
|= PREFIX_LOCK
;
3246 prefixes
|= PREFIX_CS
;
3249 prefixes
|= PREFIX_SS
;
3252 prefixes
|= PREFIX_DS
;
3255 prefixes
|= PREFIX_ES
;
3258 prefixes
|= PREFIX_FS
;
3261 prefixes
|= PREFIX_GS
;
3264 prefixes
|= PREFIX_DATA
;
3267 prefixes
|= PREFIX_ADDR
;
3270 /* fwait is really an instruction. If there are prefixes
3271 before the fwait, they belong to the fwait, *not* to the
3272 following instruction. */
3273 if (prefixes
|| rex
)
3275 prefixes
|= PREFIX_FWAIT
;
3279 prefixes
= PREFIX_FWAIT
;
3284 /* Rex is ignored when followed by another prefix. */
3295 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3299 prefix_name (int pref
, int sizeflag
)
3301 static const char *rexes
[16] =
3306 "rex.XB", /* 0x43 */
3308 "rex.RB", /* 0x45 */
3309 "rex.RX", /* 0x46 */
3310 "rex.RXB", /* 0x47 */
3312 "rex.WB", /* 0x49 */
3313 "rex.WX", /* 0x4a */
3314 "rex.WXB", /* 0x4b */
3315 "rex.WR", /* 0x4c */
3316 "rex.WRB", /* 0x4d */
3317 "rex.WRX", /* 0x4e */
3318 "rex.WRXB", /* 0x4f */
3323 /* REX prefixes family. */
3340 return rexes
[pref
- 0x40];
3360 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3362 if (address_mode
== mode_64bit
)
3363 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3365 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3373 static char op_out
[MAX_OPERANDS
][100];
3374 static int op_ad
, op_index
[MAX_OPERANDS
];
3375 static int two_source_ops
;
3376 static bfd_vma op_address
[MAX_OPERANDS
];
3377 static bfd_vma op_riprel
[MAX_OPERANDS
];
3378 static bfd_vma start_pc
;
3381 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3382 * (see topic "Redundant prefixes" in the "Differences from 8086"
3383 * section of the "Virtual 8086 Mode" chapter.)
3384 * 'pc' should be the address of this instruction, it will
3385 * be used to print the target address if this is a relative jump or call
3386 * The function returns the length of this instruction in bytes.
3389 static char intel_syntax
;
3390 static char open_char
;
3391 static char close_char
;
3392 static char separator_char
;
3393 static char scale_char
;
3395 /* Here for backwards compatibility. When gdb stops using
3396 print_insn_i386_att and print_insn_i386_intel these functions can
3397 disappear, and print_insn_i386 be merged into print_insn. */
3399 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
3403 return print_insn (pc
, info
);
3407 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
3411 return print_insn (pc
, info
);
3415 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3419 return print_insn (pc
, info
);
3423 print_i386_disassembler_options (FILE *stream
)
3425 fprintf (stream
, _("\n\
3426 The following i386/x86-64 specific disassembler options are supported for use\n\
3427 with the -M switch (multiple options should be separated by commas):\n"));
3429 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
3430 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
3431 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
3432 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
3433 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
3434 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
3435 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
3436 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
3437 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
3438 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
3439 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
3443 print_insn (bfd_vma pc
, disassemble_info
*info
)
3445 const struct dis386
*dp
;
3447 char *op_txt
[MAX_OPERANDS
];
3449 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
3450 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
3453 struct dis_private priv
;
3456 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3457 || info
->mach
== bfd_mach_x86_64
)
3458 address_mode
= mode_64bit
;
3460 address_mode
= mode_32bit
;
3462 if (intel_syntax
== (char) -1)
3463 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3464 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3466 if (info
->mach
== bfd_mach_i386_i386
3467 || info
->mach
== bfd_mach_x86_64
3468 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3469 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3470 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3471 else if (info
->mach
== bfd_mach_i386_i8086
)
3472 priv
.orig_sizeflag
= 0;
3476 for (p
= info
->disassembler_options
; p
!= NULL
; )
3478 if (CONST_STRNEQ (p
, "x86-64"))
3480 address_mode
= mode_64bit
;
3481 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3483 else if (CONST_STRNEQ (p
, "i386"))
3485 address_mode
= mode_32bit
;
3486 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3488 else if (CONST_STRNEQ (p
, "i8086"))
3490 address_mode
= mode_16bit
;
3491 priv
.orig_sizeflag
= 0;
3493 else if (CONST_STRNEQ (p
, "intel"))
3497 else if (CONST_STRNEQ (p
, "att"))
3501 else if (CONST_STRNEQ (p
, "addr"))
3503 if (address_mode
== mode_64bit
)
3505 if (p
[4] == '3' && p
[5] == '2')
3506 priv
.orig_sizeflag
&= ~AFLAG
;
3507 else if (p
[4] == '6' && p
[5] == '4')
3508 priv
.orig_sizeflag
|= AFLAG
;
3512 if (p
[4] == '1' && p
[5] == '6')
3513 priv
.orig_sizeflag
&= ~AFLAG
;
3514 else if (p
[4] == '3' && p
[5] == '2')
3515 priv
.orig_sizeflag
|= AFLAG
;
3518 else if (CONST_STRNEQ (p
, "data"))
3520 if (p
[4] == '1' && p
[5] == '6')
3521 priv
.orig_sizeflag
&= ~DFLAG
;
3522 else if (p
[4] == '3' && p
[5] == '2')
3523 priv
.orig_sizeflag
|= DFLAG
;
3525 else if (CONST_STRNEQ (p
, "suffix"))
3526 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3528 p
= strchr (p
, ',');
3535 names64
= intel_names64
;
3536 names32
= intel_names32
;
3537 names16
= intel_names16
;
3538 names8
= intel_names8
;
3539 names8rex
= intel_names8rex
;
3540 names_seg
= intel_names_seg
;
3541 index16
= intel_index16
;
3544 separator_char
= '+';
3549 names64
= att_names64
;
3550 names32
= att_names32
;
3551 names16
= att_names16
;
3552 names8
= att_names8
;
3553 names8rex
= att_names8rex
;
3554 names_seg
= att_names_seg
;
3555 index16
= att_index16
;
3558 separator_char
= ',';
3562 /* The output looks better if we put 7 bytes on a line, since that
3563 puts most long word instructions on a single line. */
3564 info
->bytes_per_line
= 7;
3566 info
->private_data
= &priv
;
3567 priv
.max_fetched
= priv
.the_buffer
;
3568 priv
.insn_start
= pc
;
3571 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3579 start_codep
= priv
.the_buffer
;
3580 codep
= priv
.the_buffer
;
3582 if (setjmp (priv
.bailout
) != 0)
3586 /* Getting here means we tried for data but didn't get it. That
3587 means we have an incomplete instruction of some sort. Just
3588 print the first byte as a prefix or a .byte pseudo-op. */
3589 if (codep
> priv
.the_buffer
)
3591 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3593 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3596 /* Just print the first byte as a .byte instruction. */
3597 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3598 (unsigned int) priv
.the_buffer
[0]);
3611 sizeflag
= priv
.orig_sizeflag
;
3613 FETCH_DATA (info
, codep
+ 1);
3614 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3616 if (((prefixes
& PREFIX_FWAIT
)
3617 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3618 || (rex
&& rex_used
))
3622 /* fwait not followed by floating point instruction, or rex followed
3623 by other prefixes. Print the first prefix. */
3624 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3626 name
= INTERNAL_DISASSEMBLER_ERROR
;
3627 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3634 unsigned char threebyte
;
3635 FETCH_DATA (info
, codep
+ 2);
3636 threebyte
= *++codep
;
3637 dp
= &dis386_twobyte
[threebyte
];
3638 need_modrm
= twobyte_has_modrm
[*codep
];
3639 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3640 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3641 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3642 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3644 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3646 FETCH_DATA (info
, codep
+ 2);
3651 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3652 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3653 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3656 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3657 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3658 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3667 dp
= &dis386
[*codep
];
3668 need_modrm
= onebyte_has_modrm
[*codep
];
3669 uses_DATA_prefix
= 0;
3670 uses_REPNZ_prefix
= 0;
3671 /* pause is 0xf3 0x90. */
3672 uses_REPZ_prefix
= *codep
== 0x90;
3673 uses_LOCK_prefix
= 0;
3677 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3680 used_prefixes
|= PREFIX_REPZ
;
3682 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3685 used_prefixes
|= PREFIX_REPNZ
;
3688 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3691 used_prefixes
|= PREFIX_LOCK
;
3694 if (prefixes
& PREFIX_ADDR
)
3697 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3699 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3700 oappend ("addr32 ");
3702 oappend ("addr16 ");
3703 used_prefixes
|= PREFIX_ADDR
;
3707 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3710 if (dp
->op
[2].bytemode
== cond_jump_mode
3711 && dp
->op
[0].bytemode
== v_mode
3714 if (sizeflag
& DFLAG
)
3715 oappend ("data32 ");
3717 oappend ("data16 ");
3718 used_prefixes
|= PREFIX_DATA
;
3722 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3724 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3725 modrm
.mod
= (*codep
>> 6) & 3;
3726 modrm
.reg
= (*codep
>> 3) & 7;
3727 modrm
.rm
= *codep
& 7;
3729 else if (need_modrm
)
3731 FETCH_DATA (info
, codep
+ 1);
3732 modrm
.mod
= (*codep
>> 6) & 3;
3733 modrm
.reg
= (*codep
>> 3) & 7;
3734 modrm
.rm
= *codep
& 7;
3737 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3744 if (dp
->name
== NULL
)
3746 switch (dp
->op
[0].bytemode
)
3749 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
3752 case USE_PREFIX_USER_TABLE
:
3754 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3755 if (prefixes
& PREFIX_REPZ
)
3759 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3760 before PREFIX_DATA. */
3761 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3762 if (prefixes
& PREFIX_REPNZ
)
3766 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3767 if (prefixes
& PREFIX_DATA
)
3771 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3774 case X86_64_SPECIAL
:
3775 index
= address_mode
== mode_64bit
? 1 : 0;
3776 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3780 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3785 if (dp
->name
!= NULL
&& putop (dp
->name
, sizeflag
) == 0)
3787 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3790 op_ad
= MAX_OPERANDS
- 1 - i
;
3792 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3797 /* See if any prefixes were not used. If so, print the first one
3798 separately. If we don't do this, we'll wind up printing an
3799 instruction stream which does not precisely correspond to the
3800 bytes we are disassembling. */
3801 if ((prefixes
& ~used_prefixes
) != 0)
3805 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3807 name
= INTERNAL_DISASSEMBLER_ERROR
;
3808 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3811 if (rex
& ~rex_used
)
3814 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3816 name
= INTERNAL_DISASSEMBLER_ERROR
;
3817 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3820 obufp
= obuf
+ strlen (obuf
);
3821 for (i
= strlen (obuf
); i
< 6; i
++)
3824 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3826 /* The enter and bound instructions are printed with operands in the same
3827 order as the intel book; everything else is printed in reverse order. */
3828 if (intel_syntax
|| two_source_ops
)
3832 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3833 op_txt
[i
] = op_out
[i
];
3835 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3837 op_ad
= op_index
[i
];
3838 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3839 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3840 riprel
= op_riprel
[i
];
3841 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
3842 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
3847 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3848 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3852 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3856 (*info
->fprintf_func
) (info
->stream
, ",");
3857 if (op_index
[i
] != -1 && !op_riprel
[i
])
3858 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3860 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3864 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3865 if (op_index
[i
] != -1 && op_riprel
[i
])
3867 (*info
->fprintf_func
) (info
->stream
, " # ");
3868 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3869 + op_address
[op_index
[i
]]), info
);
3872 return codep
- priv
.the_buffer
;
3875 static const char *float_mem
[] = {
3950 static const unsigned char float_mem_mode
[] = {
4025 #define ST { OP_ST, 0 }
4026 #define STi { OP_STi, 0 }
4028 #define FGRPd9_2 NULL, { { NULL, 0 } }
4029 #define FGRPd9_4 NULL, { { NULL, 1 } }
4030 #define FGRPd9_5 NULL, { { NULL, 2 } }
4031 #define FGRPd9_6 NULL, { { NULL, 3 } }
4032 #define FGRPd9_7 NULL, { { NULL, 4 } }
4033 #define FGRPda_5 NULL, { { NULL, 5 } }
4034 #define FGRPdb_4 NULL, { { NULL, 6 } }
4035 #define FGRPde_3 NULL, { { NULL, 7 } }
4036 #define FGRPdf_4 NULL, { { NULL, 8 } }
4038 static const struct dis386 float_reg
[][8] = {
4041 { "fadd", { ST
, STi
} },
4042 { "fmul", { ST
, STi
} },
4043 { "fcom", { STi
} },
4044 { "fcomp", { STi
} },
4045 { "fsub", { ST
, STi
} },
4046 { "fsubr", { ST
, STi
} },
4047 { "fdiv", { ST
, STi
} },
4048 { "fdivr", { ST
, STi
} },
4053 { "fxch", { STi
} },
4055 { "(bad)", { XX
} },
4063 { "fcmovb", { ST
, STi
} },
4064 { "fcmove", { ST
, STi
} },
4065 { "fcmovbe",{ ST
, STi
} },
4066 { "fcmovu", { ST
, STi
} },
4067 { "(bad)", { XX
} },
4069 { "(bad)", { XX
} },
4070 { "(bad)", { XX
} },
4074 { "fcmovnb",{ ST
, STi
} },
4075 { "fcmovne",{ ST
, STi
} },
4076 { "fcmovnbe",{ ST
, STi
} },
4077 { "fcmovnu",{ ST
, STi
} },
4079 { "fucomi", { ST
, STi
} },
4080 { "fcomi", { ST
, STi
} },
4081 { "(bad)", { XX
} },
4085 { "fadd", { STi
, ST
} },
4086 { "fmul", { STi
, ST
} },
4087 { "(bad)", { XX
} },
4088 { "(bad)", { XX
} },
4090 { "fsub", { STi
, ST
} },
4091 { "fsubr", { STi
, ST
} },
4092 { "fdiv", { STi
, ST
} },
4093 { "fdivr", { STi
, ST
} },
4095 { "fsubr", { STi
, ST
} },
4096 { "fsub", { STi
, ST
} },
4097 { "fdivr", { STi
, ST
} },
4098 { "fdiv", { STi
, ST
} },
4103 { "ffree", { STi
} },
4104 { "(bad)", { XX
} },
4106 { "fstp", { STi
} },
4107 { "fucom", { STi
} },
4108 { "fucomp", { STi
} },
4109 { "(bad)", { XX
} },
4110 { "(bad)", { XX
} },
4114 { "faddp", { STi
, ST
} },
4115 { "fmulp", { STi
, ST
} },
4116 { "(bad)", { XX
} },
4119 { "fsubp", { STi
, ST
} },
4120 { "fsubrp", { STi
, ST
} },
4121 { "fdivp", { STi
, ST
} },
4122 { "fdivrp", { STi
, ST
} },
4124 { "fsubrp", { STi
, ST
} },
4125 { "fsubp", { STi
, ST
} },
4126 { "fdivrp", { STi
, ST
} },
4127 { "fdivp", { STi
, ST
} },
4132 { "ffreep", { STi
} },
4133 { "(bad)", { XX
} },
4134 { "(bad)", { XX
} },
4135 { "(bad)", { XX
} },
4137 { "fucomip", { ST
, STi
} },
4138 { "fcomip", { ST
, STi
} },
4139 { "(bad)", { XX
} },
4143 static char *fgrps
[][8] = {
4146 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4151 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4156 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4161 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4166 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4171 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4176 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4177 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4182 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4187 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4192 dofloat (int sizeflag
)
4194 const struct dis386
*dp
;
4195 unsigned char floatop
;
4197 floatop
= codep
[-1];
4201 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4203 putop (float_mem
[fp_indx
], sizeflag
);
4206 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4209 /* Skip mod/rm byte. */
4213 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4214 if (dp
->name
== NULL
)
4216 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4218 /* Instruction fnstsw is only one with strange arg. */
4219 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4220 strcpy (op_out
[0], names16
[0]);
4224 putop (dp
->name
, sizeflag
);
4229 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4234 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4239 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4241 oappend ("%st" + intel_syntax
);
4245 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4247 sprintf (scratchbuf
, "%%st(%d)", modrm
.rm
);
4248 oappend (scratchbuf
+ intel_syntax
);
4251 /* Capital letters in template are macros. */
4253 putop (const char *template, int sizeflag
)
4258 for (p
= template; *p
; p
++)
4269 if (address_mode
== mode_64bit
)
4277 /* Alternative not valid. */
4278 strcpy (obuf
, "(bad)");
4282 else if (*p
== '\0')
4303 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4309 if (sizeflag
& SUFFIX_ALWAYS
)
4313 if (intel_syntax
&& !alt
)
4315 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4317 if (sizeflag
& DFLAG
)
4318 *obufp
++ = intel_syntax
? 'd' : 'l';
4320 *obufp
++ = intel_syntax
? 'w' : 's';
4321 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4325 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4332 else if (sizeflag
& DFLAG
)
4333 *obufp
++ = intel_syntax
? 'd' : 'l';
4336 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4341 case 'E': /* For jcxz/jecxz */
4342 if (address_mode
== mode_64bit
)
4344 if (sizeflag
& AFLAG
)
4350 if (sizeflag
& AFLAG
)
4352 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4357 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4359 if (sizeflag
& AFLAG
)
4360 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4362 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4363 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4367 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4369 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4374 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4379 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4380 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4382 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4385 if (prefixes
& PREFIX_DS
)
4406 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4415 if (sizeflag
& SUFFIX_ALWAYS
)
4419 if ((prefixes
& PREFIX_FWAIT
) == 0)
4422 used_prefixes
|= PREFIX_FWAIT
;
4428 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4433 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4438 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4447 if ((prefixes
& PREFIX_DATA
)
4449 || (sizeflag
& SUFFIX_ALWAYS
))
4456 if (sizeflag
& DFLAG
)
4461 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4467 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4469 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4475 if (intel_syntax
&& !alt
)
4478 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4484 if (sizeflag
& DFLAG
)
4485 *obufp
++ = intel_syntax
? 'd' : 'l';
4489 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4496 else if (sizeflag
& DFLAG
)
4505 if (intel_syntax
&& !p
[1]
4506 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4509 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4514 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4516 if (sizeflag
& SUFFIX_ALWAYS
)
4524 if (sizeflag
& SUFFIX_ALWAYS
)
4530 if (sizeflag
& DFLAG
)
4534 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4539 if (prefixes
& PREFIX_DATA
)
4543 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4554 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4556 /* operand size flag for cwtl, cbtw */
4565 else if (sizeflag
& DFLAG
)
4570 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4580 oappend (const char *s
)
4583 obufp
+= strlen (s
);
4589 if (prefixes
& PREFIX_CS
)
4591 used_prefixes
|= PREFIX_CS
;
4592 oappend ("%cs:" + intel_syntax
);
4594 if (prefixes
& PREFIX_DS
)
4596 used_prefixes
|= PREFIX_DS
;
4597 oappend ("%ds:" + intel_syntax
);
4599 if (prefixes
& PREFIX_SS
)
4601 used_prefixes
|= PREFIX_SS
;
4602 oappend ("%ss:" + intel_syntax
);
4604 if (prefixes
& PREFIX_ES
)
4606 used_prefixes
|= PREFIX_ES
;
4607 oappend ("%es:" + intel_syntax
);
4609 if (prefixes
& PREFIX_FS
)
4611 used_prefixes
|= PREFIX_FS
;
4612 oappend ("%fs:" + intel_syntax
);
4614 if (prefixes
& PREFIX_GS
)
4616 used_prefixes
|= PREFIX_GS
;
4617 oappend ("%gs:" + intel_syntax
);
4622 OP_indirE (int bytemode
, int sizeflag
)
4626 OP_E (bytemode
, sizeflag
);
4630 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4632 if (address_mode
== mode_64bit
)
4640 sprintf_vma (tmp
, disp
);
4641 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4642 strcpy (buf
+ 2, tmp
+ i
);
4646 bfd_signed_vma v
= disp
;
4653 /* Check for possible overflow on 0x8000000000000000. */
4656 strcpy (buf
, "9223372036854775808");
4670 tmp
[28 - i
] = (v
% 10) + '0';
4674 strcpy (buf
, tmp
+ 29 - i
);
4680 sprintf (buf
, "0x%x", (unsigned int) disp
);
4682 sprintf (buf
, "%d", (int) disp
);
4686 /* Put DISP in BUF as signed hex number. */
4689 print_displacement (char *buf
, bfd_vma disp
)
4691 bfd_signed_vma val
= disp
;
4700 /* Check for possible overflow. */
4703 switch (address_mode
)
4706 strcpy (buf
+ j
, "0x8000000000000000");
4709 strcpy (buf
+ j
, "0x80000000");
4712 strcpy (buf
+ j
, "0x8000");
4722 sprintf_vma (tmp
, val
);
4723 for (i
= 0; tmp
[i
] == '0'; i
++)
4727 strcpy (buf
+ j
, tmp
+ i
);
4731 intel_operand_size (int bytemode
, int sizeflag
)
4737 oappend ("BYTE PTR ");
4741 oappend ("WORD PTR ");
4744 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4746 oappend ("QWORD PTR ");
4747 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4755 oappend ("QWORD PTR ");
4756 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4757 oappend ("DWORD PTR ");
4759 oappend ("WORD PTR ");
4760 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4763 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4765 oappend ("WORD PTR ");
4767 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4771 oappend ("DWORD PTR ");
4774 oappend ("QWORD PTR ");
4777 if (address_mode
== mode_64bit
)
4778 oappend ("QWORD PTR ");
4780 oappend ("DWORD PTR ");
4783 if (sizeflag
& DFLAG
)
4784 oappend ("FWORD PTR ");
4786 oappend ("DWORD PTR ");
4787 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4790 oappend ("TBYTE PTR ");
4793 oappend ("XMMWORD PTR ");
4796 oappend ("OWORD PTR ");
4804 OP_E (int bytemode
, int sizeflag
)
4813 /* Skip mod/rm byte. */
4824 oappend (names8rex
[modrm
.rm
+ add
]);
4826 oappend (names8
[modrm
.rm
+ add
]);
4829 oappend (names16
[modrm
.rm
+ add
]);
4832 oappend (names32
[modrm
.rm
+ add
]);
4835 oappend (names64
[modrm
.rm
+ add
]);
4838 if (address_mode
== mode_64bit
)
4839 oappend (names64
[modrm
.rm
+ add
]);
4841 oappend (names32
[modrm
.rm
+ add
]);
4844 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4846 oappend (names64
[modrm
.rm
+ add
]);
4847 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4859 oappend (names64
[modrm
.rm
+ add
]);
4860 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4861 oappend (names32
[modrm
.rm
+ add
]);
4863 oappend (names16
[modrm
.rm
+ add
]);
4864 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4869 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4877 intel_operand_size (bytemode
, sizeflag
);
4880 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4882 /* 32/64 bit address mode */
4897 FETCH_DATA (the_info
, codep
+ 1);
4898 index
= (*codep
>> 3) & 7;
4899 if (address_mode
== mode_64bit
|| index
!= 0x4)
4900 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4901 scale
= (*codep
>> 6) & 3;
4913 if ((base
& 7) == 5)
4916 if (address_mode
== mode_64bit
&& !havesib
)
4922 FETCH_DATA (the_info
, codep
+ 1);
4924 if ((disp
& 0x80) != 0)
4932 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
4935 if (modrm
.mod
!= 0 || (base
& 7) == 5)
4937 if (havedisp
|| riprel
)
4938 print_displacement (scratchbuf
, disp
);
4940 print_operand_value (scratchbuf
, 1, disp
);
4941 oappend (scratchbuf
);
4949 if (havedisp
|| (intel_syntax
&& riprel
))
4951 *obufp
++ = open_char
;
4952 if (intel_syntax
&& riprel
)
4959 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4960 ? names64
[base
] : names32
[base
]);
4965 if (!intel_syntax
|| havebase
)
4967 *obufp
++ = separator_char
;
4970 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4971 ? names64
[index
] : names32
[index
]);
4973 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4975 *obufp
++ = scale_char
;
4977 sprintf (scratchbuf
, "%d", 1 << scale
);
4978 oappend (scratchbuf
);
4982 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
4984 if ((bfd_signed_vma
) disp
>= 0)
4989 else if (modrm
.mod
!= 1)
4993 disp
= - (bfd_signed_vma
) disp
;
4996 print_displacement (scratchbuf
, disp
);
4997 oappend (scratchbuf
);
5000 *obufp
++ = close_char
;
5003 else if (intel_syntax
)
5005 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5007 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5008 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5012 oappend (names_seg
[ds_reg
- es_reg
]);
5015 print_operand_value (scratchbuf
, 1, disp
);
5016 oappend (scratchbuf
);
5021 { /* 16 bit address mode */
5028 if ((disp
& 0x8000) != 0)
5033 FETCH_DATA (the_info
, codep
+ 1);
5035 if ((disp
& 0x80) != 0)
5040 if ((disp
& 0x8000) != 0)
5046 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5048 print_displacement (scratchbuf
, disp
);
5049 oappend (scratchbuf
);
5052 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5054 *obufp
++ = open_char
;
5056 oappend (index16
[modrm
.rm
]);
5058 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5060 if ((bfd_signed_vma
) disp
>= 0)
5065 else if (modrm
.mod
!= 1)
5069 disp
= - (bfd_signed_vma
) disp
;
5072 print_displacement (scratchbuf
, disp
);
5073 oappend (scratchbuf
);
5076 *obufp
++ = close_char
;
5079 else if (intel_syntax
)
5081 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5082 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5086 oappend (names_seg
[ds_reg
- es_reg
]);
5089 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
5090 oappend (scratchbuf
);
5096 OP_G (int bytemode
, int sizeflag
)
5107 oappend (names8rex
[modrm
.reg
+ add
]);
5109 oappend (names8
[modrm
.reg
+ add
]);
5112 oappend (names16
[modrm
.reg
+ add
]);
5115 oappend (names32
[modrm
.reg
+ add
]);
5118 oappend (names64
[modrm
.reg
+ add
]);
5127 oappend (names64
[modrm
.reg
+ add
]);
5128 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5129 oappend (names32
[modrm
.reg
+ add
]);
5131 oappend (names16
[modrm
.reg
+ add
]);
5132 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5135 if (address_mode
== mode_64bit
)
5136 oappend (names64
[modrm
.reg
+ add
]);
5138 oappend (names32
[modrm
.reg
+ add
]);
5141 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5154 FETCH_DATA (the_info
, codep
+ 8);
5155 a
= *codep
++ & 0xff;
5156 a
|= (*codep
++ & 0xff) << 8;
5157 a
|= (*codep
++ & 0xff) << 16;
5158 a
|= (*codep
++ & 0xff) << 24;
5159 b
= *codep
++ & 0xff;
5160 b
|= (*codep
++ & 0xff) << 8;
5161 b
|= (*codep
++ & 0xff) << 16;
5162 b
|= (*codep
++ & 0xff) << 24;
5163 x
= a
+ ((bfd_vma
) b
<< 32);
5171 static bfd_signed_vma
5174 bfd_signed_vma x
= 0;
5176 FETCH_DATA (the_info
, codep
+ 4);
5177 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5178 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5179 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5180 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5184 static bfd_signed_vma
5187 bfd_signed_vma x
= 0;
5189 FETCH_DATA (the_info
, codep
+ 4);
5190 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5191 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5192 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5193 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5195 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5205 FETCH_DATA (the_info
, codep
+ 2);
5206 x
= *codep
++ & 0xff;
5207 x
|= (*codep
++ & 0xff) << 8;
5212 set_op (bfd_vma op
, int riprel
)
5214 op_index
[op_ad
] = op_ad
;
5215 if (address_mode
== mode_64bit
)
5217 op_address
[op_ad
] = op
;
5218 op_riprel
[op_ad
] = riprel
;
5222 /* Mask to get a 32-bit address. */
5223 op_address
[op_ad
] = op
& 0xffffffff;
5224 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5229 OP_REG (int code
, int sizeflag
)
5239 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5240 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5241 s
= names16
[code
- ax_reg
+ add
];
5243 case es_reg
: case ss_reg
: case cs_reg
:
5244 case ds_reg
: case fs_reg
: case gs_reg
:
5245 s
= names_seg
[code
- es_reg
+ add
];
5247 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5248 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5251 s
= names8rex
[code
- al_reg
+ add
];
5253 s
= names8
[code
- al_reg
];
5255 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5256 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5257 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5259 s
= names64
[code
- rAX_reg
+ add
];
5262 code
+= eAX_reg
- rAX_reg
;
5264 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5265 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5268 s
= names64
[code
- eAX_reg
+ add
];
5269 else if (sizeflag
& DFLAG
)
5270 s
= names32
[code
- eAX_reg
+ add
];
5272 s
= names16
[code
- eAX_reg
+ add
];
5273 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5276 s
= INTERNAL_DISASSEMBLER_ERROR
;
5283 OP_IMREG (int code
, int sizeflag
)
5295 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5296 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5297 s
= names16
[code
- ax_reg
];
5299 case es_reg
: case ss_reg
: case cs_reg
:
5300 case ds_reg
: case fs_reg
: case gs_reg
:
5301 s
= names_seg
[code
- es_reg
];
5303 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5304 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5307 s
= names8rex
[code
- al_reg
];
5309 s
= names8
[code
- al_reg
];
5311 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5312 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5315 s
= names64
[code
- eAX_reg
];
5316 else if (sizeflag
& DFLAG
)
5317 s
= names32
[code
- eAX_reg
];
5319 s
= names16
[code
- eAX_reg
];
5320 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5323 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5328 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5331 s
= INTERNAL_DISASSEMBLER_ERROR
;
5338 OP_I (int bytemode
, int sizeflag
)
5341 bfd_signed_vma mask
= -1;
5346 FETCH_DATA (the_info
, codep
+ 1);
5351 if (address_mode
== mode_64bit
)
5361 else if (sizeflag
& DFLAG
)
5371 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5382 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5387 scratchbuf
[0] = '$';
5388 print_operand_value (scratchbuf
+ 1, 1, op
);
5389 oappend (scratchbuf
+ intel_syntax
);
5390 scratchbuf
[0] = '\0';
5394 OP_I64 (int bytemode
, int sizeflag
)
5397 bfd_signed_vma mask
= -1;
5399 if (address_mode
!= mode_64bit
)
5401 OP_I (bytemode
, sizeflag
);
5408 FETCH_DATA (the_info
, codep
+ 1);
5416 else if (sizeflag
& DFLAG
)
5426 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5433 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5438 scratchbuf
[0] = '$';
5439 print_operand_value (scratchbuf
+ 1, 1, op
);
5440 oappend (scratchbuf
+ intel_syntax
);
5441 scratchbuf
[0] = '\0';
5445 OP_sI (int bytemode
, int sizeflag
)
5448 bfd_signed_vma mask
= -1;
5453 FETCH_DATA (the_info
, codep
+ 1);
5455 if ((op
& 0x80) != 0)
5463 else if (sizeflag
& DFLAG
)
5472 if ((op
& 0x8000) != 0)
5475 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5480 if ((op
& 0x8000) != 0)
5484 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5488 scratchbuf
[0] = '$';
5489 print_operand_value (scratchbuf
+ 1, 1, op
);
5490 oappend (scratchbuf
+ intel_syntax
);
5494 OP_J (int bytemode
, int sizeflag
)
5498 bfd_vma segment
= 0;
5503 FETCH_DATA (the_info
, codep
+ 1);
5505 if ((disp
& 0x80) != 0)
5509 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5514 if ((disp
& 0x8000) != 0)
5516 /* In 16bit mode, address is wrapped around at 64k within
5517 the same segment. Otherwise, a data16 prefix on a jump
5518 instruction means that the pc is masked to 16 bits after
5519 the displacement is added! */
5521 if ((prefixes
& PREFIX_DATA
) == 0)
5522 segment
= ((start_pc
+ codep
- start_codep
)
5523 & ~((bfd_vma
) 0xffff));
5525 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5528 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5531 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5533 print_operand_value (scratchbuf
, 1, disp
);
5534 oappend (scratchbuf
);
5538 OP_SEG (int bytemode
, int sizeflag
)
5540 if (bytemode
== w_mode
)
5541 oappend (names_seg
[modrm
.reg
]);
5543 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5547 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5551 if (sizeflag
& DFLAG
)
5561 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5563 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
5565 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
5566 oappend (scratchbuf
);
5570 OP_OFF (int bytemode
, int sizeflag
)
5574 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5575 intel_operand_size (bytemode
, sizeflag
);
5578 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5585 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5586 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5588 oappend (names_seg
[ds_reg
- es_reg
]);
5592 print_operand_value (scratchbuf
, 1, off
);
5593 oappend (scratchbuf
);
5597 OP_OFF64 (int bytemode
, int sizeflag
)
5601 if (address_mode
!= mode_64bit
5602 || (prefixes
& PREFIX_ADDR
))
5604 OP_OFF (bytemode
, sizeflag
);
5608 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5609 intel_operand_size (bytemode
, sizeflag
);
5616 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5617 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5619 oappend (names_seg
[ds_reg
- es_reg
]);
5623 print_operand_value (scratchbuf
, 1, off
);
5624 oappend (scratchbuf
);
5628 ptr_reg (int code
, int sizeflag
)
5632 *obufp
++ = open_char
;
5633 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5634 if (address_mode
== mode_64bit
)
5636 if (!(sizeflag
& AFLAG
))
5637 s
= names32
[code
- eAX_reg
];
5639 s
= names64
[code
- eAX_reg
];
5641 else if (sizeflag
& AFLAG
)
5642 s
= names32
[code
- eAX_reg
];
5644 s
= names16
[code
- eAX_reg
];
5646 *obufp
++ = close_char
;
5651 OP_ESreg (int code
, int sizeflag
)
5657 case 0x6d: /* insw/insl */
5658 intel_operand_size (z_mode
, sizeflag
);
5660 case 0xa5: /* movsw/movsl/movsq */
5661 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5662 case 0xab: /* stosw/stosl */
5663 case 0xaf: /* scasw/scasl */
5664 intel_operand_size (v_mode
, sizeflag
);
5667 intel_operand_size (b_mode
, sizeflag
);
5670 oappend ("%es:" + intel_syntax
);
5671 ptr_reg (code
, sizeflag
);
5675 OP_DSreg (int code
, int sizeflag
)
5681 case 0x6f: /* outsw/outsl */
5682 intel_operand_size (z_mode
, sizeflag
);
5684 case 0xa5: /* movsw/movsl/movsq */
5685 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5686 case 0xad: /* lodsw/lodsl/lodsq */
5687 intel_operand_size (v_mode
, sizeflag
);
5690 intel_operand_size (b_mode
, sizeflag
);
5700 prefixes
|= PREFIX_DS
;
5702 ptr_reg (code
, sizeflag
);
5706 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5714 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5716 used_prefixes
|= PREFIX_LOCK
;
5719 sprintf (scratchbuf
, "%%cr%d", modrm
.reg
+ add
);
5720 oappend (scratchbuf
+ intel_syntax
);
5724 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5731 sprintf (scratchbuf
, "db%d", modrm
.reg
+ add
);
5733 sprintf (scratchbuf
, "%%db%d", modrm
.reg
+ add
);
5734 oappend (scratchbuf
);
5738 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5740 sprintf (scratchbuf
, "%%tr%d", modrm
.reg
);
5741 oappend (scratchbuf
+ intel_syntax
);
5745 OP_R (int bytemode
, int sizeflag
)
5748 OP_E (bytemode
, sizeflag
);
5754 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5756 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5757 if (prefixes
& PREFIX_DATA
)
5763 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5766 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5767 oappend (scratchbuf
+ intel_syntax
);
5771 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5777 sprintf (scratchbuf
, "%%xmm%d", modrm
.reg
+ add
);
5778 oappend (scratchbuf
+ intel_syntax
);
5782 OP_EM (int bytemode
, int sizeflag
)
5786 if (intel_syntax
&& bytemode
== v_mode
)
5788 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5789 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5791 OP_E (bytemode
, sizeflag
);
5795 /* Skip mod/rm byte. */
5798 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5799 if (prefixes
& PREFIX_DATA
)
5806 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5809 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5810 oappend (scratchbuf
+ intel_syntax
);
5813 /* cvt* are the only instructions in sse2 which have
5814 both SSE and MMX operands and also have 0x66 prefix
5815 in their opcode. 0x66 was originally used to differentiate
5816 between SSE and MMX instruction(operands). So we have to handle the
5817 cvt* separately using OP_EMC and OP_MXC */
5819 OP_EMC (int bytemode
, int sizeflag
)
5823 if (intel_syntax
&& bytemode
== v_mode
)
5825 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5826 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5828 OP_E (bytemode
, sizeflag
);
5832 /* Skip mod/rm byte. */
5835 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5836 sprintf (scratchbuf
, "%%mm%d", modrm
.rm
);
5837 oappend (scratchbuf
+ intel_syntax
);
5841 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5843 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5844 sprintf (scratchbuf
, "%%mm%d", modrm
.reg
);
5845 oappend (scratchbuf
+ intel_syntax
);
5849 OP_EX (int bytemode
, int sizeflag
)
5854 OP_E (bytemode
, sizeflag
);
5861 /* Skip mod/rm byte. */
5864 sprintf (scratchbuf
, "%%xmm%d", modrm
.rm
+ add
);
5865 oappend (scratchbuf
+ intel_syntax
);
5869 OP_MS (int bytemode
, int sizeflag
)
5872 OP_EM (bytemode
, sizeflag
);
5878 OP_XS (int bytemode
, int sizeflag
)
5881 OP_EX (bytemode
, sizeflag
);
5887 OP_M (int bytemode
, int sizeflag
)
5890 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5893 OP_E (bytemode
, sizeflag
);
5897 OP_0f07 (int bytemode
, int sizeflag
)
5899 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
5902 OP_E (bytemode
, sizeflag
);
5906 OP_0fae (int bytemode
, int sizeflag
)
5911 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5913 if (modrm
.reg
< 5 || modrm
.rm
!= 0)
5915 BadOp (); /* bad sfence, mfence, or lfence */
5919 else if (modrm
.reg
!= 7)
5921 BadOp (); /* bad clflush */
5925 OP_E (bytemode
, sizeflag
);
5928 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5929 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5932 NOP_Fixup1 (int bytemode
, int sizeflag
)
5934 if ((prefixes
& PREFIX_DATA
) != 0
5937 && address_mode
== mode_64bit
))
5938 OP_REG (bytemode
, sizeflag
);
5940 strcpy (obuf
, "nop");
5944 NOP_Fixup2 (int bytemode
, int sizeflag
)
5946 if ((prefixes
& PREFIX_DATA
) != 0
5949 && address_mode
== mode_64bit
))
5950 OP_IMREG (bytemode
, sizeflag
);
5953 static const char *const Suffix3DNow
[] = {
5954 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5955 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5956 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5957 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5958 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5959 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5960 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5961 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5962 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5963 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5964 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5965 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5966 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5967 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5968 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5969 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5970 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5971 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5972 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5973 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5974 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5975 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5976 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5977 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5978 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5979 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5980 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5981 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5982 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5983 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5984 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5985 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5986 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5987 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5988 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5989 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5990 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5991 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5992 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5993 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5994 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5995 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5996 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5997 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5998 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5999 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
6000 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
6001 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6002 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6003 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6004 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6005 /* CC */ NULL
, NULL
, NULL
, NULL
,
6006 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6007 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6008 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6009 /* DC */ NULL
, NULL
, NULL
, NULL
,
6010 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6011 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6012 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6013 /* EC */ NULL
, NULL
, NULL
, NULL
,
6014 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6015 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6016 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6017 /* FC */ NULL
, NULL
, NULL
, NULL
,
6021 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6023 const char *mnemonic
;
6025 FETCH_DATA (the_info
, codep
+ 1);
6026 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6027 place where an 8-bit immediate would normally go. ie. the last
6028 byte of the instruction. */
6029 obufp
= obuf
+ strlen (obuf
);
6030 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6035 /* Since a variable sized modrm/sib chunk is between the start
6036 of the opcode (0x0f0f) and the opcode suffix, we need to do
6037 all the modrm processing first, and don't know until now that
6038 we have a bad opcode. This necessitates some cleaning up. */
6039 op_out
[0][0] = '\0';
6040 op_out
[1][0] = '\0';
6045 static const char *simd_cmp_op
[] = {
6057 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6059 unsigned int cmp_type
;
6061 FETCH_DATA (the_info
, codep
+ 1);
6062 obufp
= obuf
+ strlen (obuf
);
6063 cmp_type
= *codep
++ & 0xff;
6066 char suffix1
= 'p', suffix2
= 's';
6067 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6068 if (prefixes
& PREFIX_REPZ
)
6072 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6073 if (prefixes
& PREFIX_DATA
)
6077 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6078 if (prefixes
& PREFIX_REPNZ
)
6079 suffix1
= 's', suffix2
= 'd';
6082 sprintf (scratchbuf
, "cmp%s%c%c",
6083 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6084 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6085 oappend (scratchbuf
);
6089 /* We have a bad extension byte. Clean up. */
6090 op_out
[0][0] = '\0';
6091 op_out
[1][0] = '\0';
6097 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
6099 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6100 forms of these instructions. */
6103 char *p
= obuf
+ strlen (obuf
);
6106 *(p
- 1) = *(p
- 2);
6107 *(p
- 2) = *(p
- 3);
6108 *(p
- 3) = extrachar
;
6113 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6115 if (modrm
.mod
== 3 && modrm
.reg
== 1 && modrm
.rm
<= 1)
6117 /* Override "sidt". */
6118 size_t olen
= strlen (obuf
);
6119 char *p
= obuf
+ olen
- 4;
6120 const char **names
= (address_mode
== mode_64bit
6121 ? names64
: names32
);
6123 /* We might have a suffix when disassembling with -Msuffix. */
6127 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6129 && (prefixes
& PREFIX_ADDR
)
6132 && CONST_STRNEQ (p
- 7, "addr")
6133 && (CONST_STRNEQ (p
- 3, "16")
6134 || CONST_STRNEQ (p
- 3, "32")))
6139 /* mwait %eax,%ecx */
6140 strcpy (p
, "mwait");
6142 strcpy (op_out
[0], names
[0]);
6146 /* monitor %eax,%ecx,%edx" */
6147 strcpy (p
, "monitor");
6150 const char **op1_names
;
6151 if (!(prefixes
& PREFIX_ADDR
))
6152 op1_names
= (address_mode
== mode_16bit
6156 op1_names
= (address_mode
!= mode_32bit
6157 ? names32
: names16
);
6158 used_prefixes
|= PREFIX_ADDR
;
6160 strcpy (op_out
[0], op1_names
[0]);
6161 strcpy (op_out
[2], names
[2]);
6166 strcpy (op_out
[1], names
[1]);
6177 SVME_Fixup (int bytemode
, int sizeflag
)
6209 OP_M (bytemode
, sizeflag
);
6212 /* Override "lidt". */
6213 p
= obuf
+ strlen (obuf
) - 4;
6214 /* We might have a suffix. */
6218 if (!(prefixes
& PREFIX_ADDR
))
6223 used_prefixes
|= PREFIX_ADDR
;
6227 strcpy (op_out
[1], names32
[1]);
6233 *obufp
++ = open_char
;
6234 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6238 strcpy (obufp
, alt
);
6239 obufp
+= strlen (alt
);
6240 *obufp
++ = close_char
;
6247 INVLPG_Fixup (int bytemode
, int sizeflag
)
6260 OP_M (bytemode
, sizeflag
);
6263 /* Override "invlpg". */
6264 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6271 /* Throw away prefixes and 1st. opcode byte. */
6272 codep
= insn_codep
+ 1;
6277 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6284 /* Override "sgdt". */
6285 char *p
= obuf
+ strlen (obuf
) - 4;
6287 /* We might have a suffix when disassembling with -Msuffix. */
6294 strcpy (p
, "vmcall");
6297 strcpy (p
, "vmlaunch");
6300 strcpy (p
, "vmresume");
6303 strcpy (p
, "vmxoff");
6314 OP_VMX (int bytemode
, int sizeflag
)
6316 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
6317 if (prefixes
& PREFIX_DATA
)
6318 strcpy (obuf
, "vmclear");
6319 else if (prefixes
& PREFIX_REPZ
)
6320 strcpy (obuf
, "vmxon");
6322 strcpy (obuf
, "vmptrld");
6323 OP_E (bytemode
, sizeflag
);
6327 REP_Fixup (int bytemode
, int sizeflag
)
6329 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6333 if (prefixes
& PREFIX_REPZ
)
6334 switch (*insn_codep
)
6336 case 0x6e: /* outsb */
6337 case 0x6f: /* outsw/outsl */
6338 case 0xa4: /* movsb */
6339 case 0xa5: /* movsw/movsl/movsq */
6345 case 0xaa: /* stosb */
6346 case 0xab: /* stosw/stosl/stosq */
6347 case 0xac: /* lodsb */
6348 case 0xad: /* lodsw/lodsl/lodsq */
6349 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
6354 case 0x6c: /* insb */
6355 case 0x6d: /* insl/insw */
6371 olen
= strlen (obuf
);
6372 p
= obuf
+ olen
- ilen
- 1 - 4;
6373 /* Handle "repz [addr16|addr32]". */
6374 if ((prefixes
& PREFIX_ADDR
))
6377 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
6385 OP_IMREG (bytemode
, sizeflag
);
6388 OP_ESreg (bytemode
, sizeflag
);
6391 OP_DSreg (bytemode
, sizeflag
);
6400 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6405 /* Change cmpxchg8b to cmpxchg16b. */
6406 char *p
= obuf
+ strlen (obuf
) - 2;
6410 OP_M (bytemode
, sizeflag
);
6414 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6416 sprintf (scratchbuf
, "%%xmm%d", reg
);
6417 oappend (scratchbuf
+ intel_syntax
);
6421 CRC32_Fixup (int bytemode
, int sizeflag
)
6423 /* Add proper suffix to "crc32". */
6424 char *p
= obuf
+ strlen (obuf
);
6441 else if (sizeflag
& DFLAG
)
6445 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6448 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6457 /* Skip mod/rm byte. */
6462 add
= (rex
& REX_B
) ? 8 : 0;
6463 if (bytemode
== b_mode
)
6467 oappend (names8rex
[modrm
.rm
+ add
]);
6469 oappend (names8
[modrm
.rm
+ add
]);
6475 oappend (names64
[modrm
.rm
+ add
]);
6476 else if ((prefixes
& PREFIX_DATA
))
6477 oappend (names16
[modrm
.rm
+ add
]);
6479 oappend (names32
[modrm
.rm
+ add
]);
6483 OP_E (bytemode
, sizeflag
);