1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
37 #include "opcode/i386.h"
41 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
42 static void ckprefix (void);
43 static const char *prefix_name (int, int);
44 static int print_insn (bfd_vma
, disassemble_info
*);
45 static void dofloat (int);
46 static void OP_ST (int, int);
47 static void OP_STi (int, int);
48 static int putop (const char *, int);
49 static void oappend (const char *);
50 static void append_seg (void);
51 static void OP_indirE (int, int);
52 static void print_operand_value (char *, int, bfd_vma
);
53 static void OP_E (int, int);
54 static void OP_G (int, int);
55 static bfd_vma
get64 (void);
56 static bfd_signed_vma
get32 (void);
57 static bfd_signed_vma
get32s (void);
58 static int get16 (void);
59 static void set_op (bfd_vma
, int);
60 static void OP_REG (int, int);
61 static void OP_IMREG (int, int);
62 static void OP_I (int, int);
63 static void OP_I64 (int, int);
64 static void OP_sI (int, int);
65 static void OP_J (int, int);
66 static void OP_SEG (int, int);
67 static void OP_DIR (int, int);
68 static void OP_OFF (int, int);
69 static void OP_OFF64 (int, int);
70 static void ptr_reg (int, int);
71 static void OP_ESreg (int, int);
72 static void OP_DSreg (int, int);
73 static void OP_C (int, int);
74 static void OP_D (int, int);
75 static void OP_T (int, int);
76 static void OP_R (int, int);
77 static void OP_MMX (int, int);
78 static void OP_XMM (int, int);
79 static void OP_EM (int, int);
80 static void OP_EX (int, int);
81 static void OP_EMC (int,int);
82 static void OP_MXC (int,int);
83 static void OP_MS (int, int);
84 static void OP_XS (int, int);
85 static void OP_M (int, int);
86 static void OP_VMX (int, int);
87 static void OP_0fae (int, int);
88 static void OP_0f07 (int, int);
89 static void NOP_Fixup1 (int, int);
90 static void NOP_Fixup2 (int, int);
91 static void OP_3DNowSuffix (int, int);
92 static void OP_SIMD_Suffix (int, int);
93 static void SIMD_Fixup (int, int);
94 static void PNI_Fixup (int, int);
95 static void SVME_Fixup (int, int);
96 static void INVLPG_Fixup (int, int);
97 static void BadOp (void);
98 static void VMX_Fixup (int, int);
99 static void REP_Fixup (int, int);
100 static void CMPXCHG8B_Fixup (int, int);
103 /* Points to first byte not fetched. */
104 bfd_byte
*max_fetched
;
105 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
118 enum address_mode address_mode
;
120 /* Flags for the prefixes for the current instruction. See below. */
123 /* REX prefix the current instruction. See below. */
125 /* Bits of REX we've already used. */
131 /* Mark parts used in the REX prefix. When we are testing for
132 empty prefix (for 8bit register REX extension), just mask it
133 out. Otherwise test for REX bit is excuse for existence of REX
134 only in case value is nonzero. */
135 #define USED_REX(value) \
138 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
143 /* Flags for prefixes which we somehow handled when printing the
144 current instruction. */
145 static int used_prefixes
;
147 /* Flags stored in PREFIXES. */
148 #define PREFIX_REPZ 1
149 #define PREFIX_REPNZ 2
150 #define PREFIX_LOCK 4
152 #define PREFIX_SS 0x10
153 #define PREFIX_DS 0x20
154 #define PREFIX_ES 0x40
155 #define PREFIX_FS 0x80
156 #define PREFIX_GS 0x100
157 #define PREFIX_DATA 0x200
158 #define PREFIX_ADDR 0x400
159 #define PREFIX_FWAIT 0x800
161 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
162 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
164 #define FETCH_DATA(info, addr) \
165 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
166 ? 1 : fetch_data ((info), (addr)))
169 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
172 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
173 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
175 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
176 status
= (*info
->read_memory_func
) (start
,
178 addr
- priv
->max_fetched
,
184 /* If we did manage to read at least one byte, then
185 print_insn_i386 will do something sensible. Otherwise, print
186 an error. We do that here because this is where we know
188 if (priv
->max_fetched
== priv
->the_buffer
)
189 (*info
->memory_error_func
) (status
, start
, info
);
190 longjmp (priv
->bailout
, 1);
193 priv
->max_fetched
= addr
;
197 #define XX { NULL, 0 }
199 #define Eb { OP_E, b_mode }
200 #define Ev { OP_E, v_mode }
201 #define Ed { OP_E, d_mode }
202 #define Edq { OP_E, dq_mode }
203 #define Edqw { OP_E, dqw_mode }
204 #define indirEv { OP_indirE, stack_v_mode }
205 #define indirEp { OP_indirE, f_mode }
206 #define stackEv { OP_E, stack_v_mode }
207 #define Em { OP_E, m_mode }
208 #define Ew { OP_E, w_mode }
209 #define M { OP_M, 0 } /* lea, lgdt, etc. */
210 #define Ma { OP_M, v_mode }
211 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
212 #define Mq { OP_M, q_mode }
213 #define Gb { OP_G, b_mode }
214 #define Gv { OP_G, v_mode }
215 #define Gd { OP_G, d_mode }
216 #define Gdq { OP_G, dq_mode }
217 #define Gm { OP_G, m_mode }
218 #define Gw { OP_G, w_mode }
219 #define Rd { OP_R, d_mode }
220 #define Rm { OP_R, m_mode }
221 #define Ib { OP_I, b_mode }
222 #define sIb { OP_sI, b_mode } /* sign extened byte */
223 #define Iv { OP_I, v_mode }
224 #define Iq { OP_I, q_mode }
225 #define Iv64 { OP_I64, v_mode }
226 #define Iw { OP_I, w_mode }
227 #define I1 { OP_I, const_1_mode }
228 #define Jb { OP_J, b_mode }
229 #define Jv { OP_J, v_mode }
230 #define Cm { OP_C, m_mode }
231 #define Dm { OP_D, m_mode }
232 #define Td { OP_T, d_mode }
234 #define RMeAX { OP_REG, eAX_reg }
235 #define RMeBX { OP_REG, eBX_reg }
236 #define RMeCX { OP_REG, eCX_reg }
237 #define RMeDX { OP_REG, eDX_reg }
238 #define RMeSP { OP_REG, eSP_reg }
239 #define RMeBP { OP_REG, eBP_reg }
240 #define RMeSI { OP_REG, eSI_reg }
241 #define RMeDI { OP_REG, eDI_reg }
242 #define RMrAX { OP_REG, rAX_reg }
243 #define RMrBX { OP_REG, rBX_reg }
244 #define RMrCX { OP_REG, rCX_reg }
245 #define RMrDX { OP_REG, rDX_reg }
246 #define RMrSP { OP_REG, rSP_reg }
247 #define RMrBP { OP_REG, rBP_reg }
248 #define RMrSI { OP_REG, rSI_reg }
249 #define RMrDI { OP_REG, rDI_reg }
250 #define RMAL { OP_REG, al_reg }
251 #define RMAL { OP_REG, al_reg }
252 #define RMCL { OP_REG, cl_reg }
253 #define RMDL { OP_REG, dl_reg }
254 #define RMBL { OP_REG, bl_reg }
255 #define RMAH { OP_REG, ah_reg }
256 #define RMCH { OP_REG, ch_reg }
257 #define RMDH { OP_REG, dh_reg }
258 #define RMBH { OP_REG, bh_reg }
259 #define RMAX { OP_REG, ax_reg }
260 #define RMDX { OP_REG, dx_reg }
262 #define eAX { OP_IMREG, eAX_reg }
263 #define eBX { OP_IMREG, eBX_reg }
264 #define eCX { OP_IMREG, eCX_reg }
265 #define eDX { OP_IMREG, eDX_reg }
266 #define eSP { OP_IMREG, eSP_reg }
267 #define eBP { OP_IMREG, eBP_reg }
268 #define eSI { OP_IMREG, eSI_reg }
269 #define eDI { OP_IMREG, eDI_reg }
270 #define AL { OP_IMREG, al_reg }
271 #define CL { OP_IMREG, cl_reg }
272 #define DL { OP_IMREG, dl_reg }
273 #define BL { OP_IMREG, bl_reg }
274 #define AH { OP_IMREG, ah_reg }
275 #define CH { OP_IMREG, ch_reg }
276 #define DH { OP_IMREG, dh_reg }
277 #define BH { OP_IMREG, bh_reg }
278 #define AX { OP_IMREG, ax_reg }
279 #define DX { OP_IMREG, dx_reg }
280 #define zAX { OP_IMREG, z_mode_ax_reg }
281 #define indirDX { OP_IMREG, indir_dx_reg }
283 #define Sw { OP_SEG, w_mode }
284 #define Sv { OP_SEG, v_mode }
285 #define Ap { OP_DIR, 0 }
286 #define Ob { OP_OFF64, b_mode }
287 #define Ov { OP_OFF64, v_mode }
288 #define Xb { OP_DSreg, eSI_reg }
289 #define Xv { OP_DSreg, eSI_reg }
290 #define Xz { OP_DSreg, eSI_reg }
291 #define Yb { OP_ESreg, eDI_reg }
292 #define Yv { OP_ESreg, eDI_reg }
293 #define DSBX { OP_DSreg, eBX_reg }
295 #define es { OP_REG, es_reg }
296 #define ss { OP_REG, ss_reg }
297 #define cs { OP_REG, cs_reg }
298 #define ds { OP_REG, ds_reg }
299 #define fs { OP_REG, fs_reg }
300 #define gs { OP_REG, gs_reg }
302 #define MX { OP_MMX, 0 }
303 #define XM { OP_XMM, 0 }
304 #define EM { OP_EM, v_mode }
305 #define EX { OP_EX, v_mode }
306 #define MS { OP_MS, v_mode }
307 #define XS { OP_XS, v_mode }
308 #define EMC { OP_EMC, v_mode }
309 #define MXC { OP_MXC, 0 }
310 #define VM { OP_VMX, q_mode }
311 #define OPSUF { OP_3DNowSuffix, 0 }
312 #define OPSIMD { OP_SIMD_Suffix, 0 }
314 /* Used handle "rep" prefix for string instructions. */
315 #define Xbr { REP_Fixup, eSI_reg }
316 #define Xvr { REP_Fixup, eSI_reg }
317 #define Ybr { REP_Fixup, eDI_reg }
318 #define Yvr { REP_Fixup, eDI_reg }
319 #define Yzr { REP_Fixup, eDI_reg }
320 #define indirDXr { REP_Fixup, indir_dx_reg }
321 #define ALr { REP_Fixup, al_reg }
322 #define eAXr { REP_Fixup, eAX_reg }
324 #define cond_jump_flag { NULL, cond_jump_mode }
325 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
327 /* bits in sizeflag */
328 #define SUFFIX_ALWAYS 4
332 #define b_mode 1 /* byte operand */
333 #define v_mode 2 /* operand size depends on prefixes */
334 #define w_mode 3 /* word operand */
335 #define d_mode 4 /* double word operand */
336 #define q_mode 5 /* quad word operand */
337 #define t_mode 6 /* ten-byte operand */
338 #define x_mode 7 /* 16-byte XMM operand */
339 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
340 #define cond_jump_mode 9
341 #define loop_jcxz_mode 10
342 #define dq_mode 11 /* operand size depends on REX prefixes. */
343 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
344 #define f_mode 13 /* 4- or 6-byte pointer operand */
345 #define const_1_mode 14
346 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
347 #define z_mode 16 /* non-quad operand size depends on prefixes */
348 #define o_mode 17 /* 16-byte operand */
393 #define z_mode_ax_reg 149
394 #define indir_dx_reg 150
398 #define USE_PREFIX_USER_TABLE 3
399 #define X86_64_SPECIAL 4
400 #define IS_3BYTE_OPCODE 5
402 #define FLOAT NULL, { { NULL, FLOATCODE } }
404 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
405 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
406 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
407 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
408 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
409 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
410 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
411 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
412 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
413 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
414 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
415 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
416 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
417 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
418 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
419 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
420 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
421 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
422 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
423 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
424 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
425 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
426 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
427 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
428 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
429 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
430 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
432 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
433 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
434 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
435 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
436 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
437 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
438 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
439 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
440 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
441 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
442 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
443 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
444 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
445 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
446 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
447 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
448 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
449 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
450 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
451 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
452 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
453 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
454 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
455 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
456 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
457 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
458 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
459 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
460 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
461 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
462 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
463 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
464 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
465 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
466 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
467 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
468 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
469 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
472 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
473 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
474 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
475 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
477 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
478 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
480 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
491 /* Upper case letters in the instruction names here are macros.
492 'A' => print 'b' if no register operands or suffix_always is true
493 'B' => print 'b' if suffix_always is true
494 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
496 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
497 . suffix_always is true
498 'E' => print 'e' if 32-bit form of jcxz
499 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
500 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
501 'H' => print ",pt" or ",pn" branch hint
502 'I' => honor following macro letter even in Intel mode (implemented only
503 . for some of the macro letters)
505 'L' => print 'l' if suffix_always is true
506 'N' => print 'n' if instruction has no wait "prefix"
507 'O' => print 'd' or 'o' (or 'q' in Intel mode)
508 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
509 . or suffix_always is true. print 'q' if rex prefix is present.
510 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
512 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
513 'S' => print 'w', 'l' or 'q' if suffix_always is true
514 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
515 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
516 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
517 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
518 'X' => print 's', 'd' depending on data16 prefix (for XMM)
519 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
520 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
522 Many of the above letters print nothing in Intel mode. See "putop"
525 Braces '{' and '}', and vertical bars '|', indicate alternative
526 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
527 modes. In cases where there are only two alternatives, the X86_64
528 instruction is reserved, and "(bad)" is printed.
531 static const struct dis386 dis386
[] = {
533 { "addB", { Eb
, Gb
} },
534 { "addS", { Ev
, Gv
} },
535 { "addB", { Gb
, Eb
} },
536 { "addS", { Gv
, Ev
} },
537 { "addB", { AL
, Ib
} },
538 { "addS", { eAX
, Iv
} },
539 { "push{T|}", { es
} },
540 { "pop{T|}", { es
} },
542 { "orB", { Eb
, Gb
} },
543 { "orS", { Ev
, Gv
} },
544 { "orB", { Gb
, Eb
} },
545 { "orS", { Gv
, Ev
} },
546 { "orB", { AL
, Ib
} },
547 { "orS", { eAX
, Iv
} },
548 { "push{T|}", { cs
} },
549 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
551 { "adcB", { Eb
, Gb
} },
552 { "adcS", { Ev
, Gv
} },
553 { "adcB", { Gb
, Eb
} },
554 { "adcS", { Gv
, Ev
} },
555 { "adcB", { AL
, Ib
} },
556 { "adcS", { eAX
, Iv
} },
557 { "push{T|}", { ss
} },
558 { "pop{T|}", { ss
} },
560 { "sbbB", { Eb
, Gb
} },
561 { "sbbS", { Ev
, Gv
} },
562 { "sbbB", { Gb
, Eb
} },
563 { "sbbS", { Gv
, Ev
} },
564 { "sbbB", { AL
, Ib
} },
565 { "sbbS", { eAX
, Iv
} },
566 { "push{T|}", { ds
} },
567 { "pop{T|}", { ds
} },
569 { "andB", { Eb
, Gb
} },
570 { "andS", { Ev
, Gv
} },
571 { "andB", { Gb
, Eb
} },
572 { "andS", { Gv
, Ev
} },
573 { "andB", { AL
, Ib
} },
574 { "andS", { eAX
, Iv
} },
575 { "(bad)", { XX
} }, /* SEG ES prefix */
576 { "daa{|}", { XX
} },
578 { "subB", { Eb
, Gb
} },
579 { "subS", { Ev
, Gv
} },
580 { "subB", { Gb
, Eb
} },
581 { "subS", { Gv
, Ev
} },
582 { "subB", { AL
, Ib
} },
583 { "subS", { eAX
, Iv
} },
584 { "(bad)", { XX
} }, /* SEG CS prefix */
585 { "das{|}", { XX
} },
587 { "xorB", { Eb
, Gb
} },
588 { "xorS", { Ev
, Gv
} },
589 { "xorB", { Gb
, Eb
} },
590 { "xorS", { Gv
, Ev
} },
591 { "xorB", { AL
, Ib
} },
592 { "xorS", { eAX
, Iv
} },
593 { "(bad)", { XX
} }, /* SEG SS prefix */
594 { "aaa{|}", { XX
} },
596 { "cmpB", { Eb
, Gb
} },
597 { "cmpS", { Ev
, Gv
} },
598 { "cmpB", { Gb
, Eb
} },
599 { "cmpS", { Gv
, Ev
} },
600 { "cmpB", { AL
, Ib
} },
601 { "cmpS", { eAX
, Iv
} },
602 { "(bad)", { XX
} }, /* SEG DS prefix */
603 { "aas{|}", { XX
} },
605 { "inc{S|}", { RMeAX
} },
606 { "inc{S|}", { RMeCX
} },
607 { "inc{S|}", { RMeDX
} },
608 { "inc{S|}", { RMeBX
} },
609 { "inc{S|}", { RMeSP
} },
610 { "inc{S|}", { RMeBP
} },
611 { "inc{S|}", { RMeSI
} },
612 { "inc{S|}", { RMeDI
} },
614 { "dec{S|}", { RMeAX
} },
615 { "dec{S|}", { RMeCX
} },
616 { "dec{S|}", { RMeDX
} },
617 { "dec{S|}", { RMeBX
} },
618 { "dec{S|}", { RMeSP
} },
619 { "dec{S|}", { RMeBP
} },
620 { "dec{S|}", { RMeSI
} },
621 { "dec{S|}", { RMeDI
} },
623 { "pushV", { RMrAX
} },
624 { "pushV", { RMrCX
} },
625 { "pushV", { RMrDX
} },
626 { "pushV", { RMrBX
} },
627 { "pushV", { RMrSP
} },
628 { "pushV", { RMrBP
} },
629 { "pushV", { RMrSI
} },
630 { "pushV", { RMrDI
} },
632 { "popV", { RMrAX
} },
633 { "popV", { RMrCX
} },
634 { "popV", { RMrDX
} },
635 { "popV", { RMrBX
} },
636 { "popV", { RMrSP
} },
637 { "popV", { RMrBP
} },
638 { "popV", { RMrSI
} },
639 { "popV", { RMrDI
} },
645 { "(bad)", { XX
} }, /* seg fs */
646 { "(bad)", { XX
} }, /* seg gs */
647 { "(bad)", { XX
} }, /* op size prefix */
648 { "(bad)", { XX
} }, /* adr size prefix */
651 { "imulS", { Gv
, Ev
, Iv
} },
652 { "pushT", { sIb
} },
653 { "imulS", { Gv
, Ev
, sIb
} },
654 { "ins{b||b|}", { Ybr
, indirDX
} },
655 { "ins{R||G|}", { Yzr
, indirDX
} },
656 { "outs{b||b|}", { indirDXr
, Xb
} },
657 { "outs{R||G|}", { indirDXr
, Xz
} },
659 { "joH", { Jb
, XX
, cond_jump_flag
} },
660 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
661 { "jbH", { Jb
, XX
, cond_jump_flag
} },
662 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
663 { "jeH", { Jb
, XX
, cond_jump_flag
} },
664 { "jneH", { Jb
, XX
, cond_jump_flag
} },
665 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
666 { "jaH", { Jb
, XX
, cond_jump_flag
} },
668 { "jsH", { Jb
, XX
, cond_jump_flag
} },
669 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
670 { "jpH", { Jb
, XX
, cond_jump_flag
} },
671 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
672 { "jlH", { Jb
, XX
, cond_jump_flag
} },
673 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
674 { "jleH", { Jb
, XX
, cond_jump_flag
} },
675 { "jgH", { Jb
, XX
, cond_jump_flag
} },
681 { "testB", { Eb
, Gb
} },
682 { "testS", { Ev
, Gv
} },
683 { "xchgB", { Eb
, Gb
} },
684 { "xchgS", { Ev
, Gv
} },
686 { "movB", { Eb
, Gb
} },
687 { "movS", { Ev
, Gv
} },
688 { "movB", { Gb
, Eb
} },
689 { "movS", { Gv
, Ev
} },
690 { "movD", { Sv
, Sw
} },
691 { "leaS", { Gv
, M
} },
692 { "movD", { Sw
, Sv
} },
693 { "popU", { stackEv
} },
695 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
696 { "xchgS", { RMeCX
, eAX
} },
697 { "xchgS", { RMeDX
, eAX
} },
698 { "xchgS", { RMeBX
, eAX
} },
699 { "xchgS", { RMeSP
, eAX
} },
700 { "xchgS", { RMeBP
, eAX
} },
701 { "xchgS", { RMeSI
, eAX
} },
702 { "xchgS", { RMeDI
, eAX
} },
704 { "cW{t||t|}R", { XX
} },
705 { "cR{t||t|}O", { XX
} },
706 { "Jcall{T|}", { Ap
} },
707 { "(bad)", { XX
} }, /* fwait */
708 { "pushfT", { XX
} },
710 { "sahf{|}", { XX
} },
711 { "lahf{|}", { XX
} },
713 { "movB", { AL
, Ob
} },
714 { "movS", { eAX
, Ov
} },
715 { "movB", { Ob
, AL
} },
716 { "movS", { Ov
, eAX
} },
717 { "movs{b||b|}", { Ybr
, Xb
} },
718 { "movs{R||R|}", { Yvr
, Xv
} },
719 { "cmps{b||b|}", { Xb
, Yb
} },
720 { "cmps{R||R|}", { Xv
, Yv
} },
722 { "testB", { AL
, Ib
} },
723 { "testS", { eAX
, Iv
} },
724 { "stosB", { Ybr
, AL
} },
725 { "stosS", { Yvr
, eAX
} },
726 { "lodsB", { ALr
, Xb
} },
727 { "lodsS", { eAXr
, Xv
} },
728 { "scasB", { AL
, Yb
} },
729 { "scasS", { eAX
, Yv
} },
731 { "movB", { RMAL
, Ib
} },
732 { "movB", { RMCL
, Ib
} },
733 { "movB", { RMDL
, Ib
} },
734 { "movB", { RMBL
, Ib
} },
735 { "movB", { RMAH
, Ib
} },
736 { "movB", { RMCH
, Ib
} },
737 { "movB", { RMDH
, Ib
} },
738 { "movB", { RMBH
, Ib
} },
740 { "movS", { RMeAX
, Iv64
} },
741 { "movS", { RMeCX
, Iv64
} },
742 { "movS", { RMeDX
, Iv64
} },
743 { "movS", { RMeBX
, Iv64
} },
744 { "movS", { RMeSP
, Iv64
} },
745 { "movS", { RMeBP
, Iv64
} },
746 { "movS", { RMeSI
, Iv64
} },
747 { "movS", { RMeDI
, Iv64
} },
753 { "les{S|}", { Gv
, Mp
} },
754 { "ldsS", { Gv
, Mp
} },
758 { "enterT", { Iw
, Ib
} },
759 { "leaveT", { XX
} },
764 { "into{|}", { XX
} },
771 { "aam{|}", { sIb
} },
772 { "aad{|}", { sIb
} },
774 { "xlat", { DSBX
} },
785 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
786 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
787 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
788 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
789 { "inB", { AL
, Ib
} },
790 { "inG", { zAX
, Ib
} },
791 { "outB", { Ib
, AL
} },
792 { "outG", { Ib
, zAX
} },
796 { "Jjmp{T|}", { Ap
} },
798 { "inB", { AL
, indirDX
} },
799 { "inG", { zAX
, indirDX
} },
800 { "outB", { indirDX
, AL
} },
801 { "outG", { indirDX
, zAX
} },
803 { "(bad)", { XX
} }, /* lock prefix */
805 { "(bad)", { XX
} }, /* repne */
806 { "(bad)", { XX
} }, /* repz */
822 static const struct dis386 dis386_twobyte
[] = {
826 { "larS", { Gv
, Ew
} },
827 { "lslS", { Gv
, Ew
} },
829 { "syscall", { XX
} },
831 { "sysretP", { XX
} },
834 { "wbinvd", { XX
} },
840 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
845 { "movlpX", { EX
, XM
, { SIMD_Fixup
, 'h' } } },
846 { "unpcklpX", { XM
, EX
} },
847 { "unpckhpX", { XM
, EX
} },
849 { "movhpX", { EX
, XM
, { SIMD_Fixup
, 'l' } } },
860 { "movZ", { Rm
, Cm
} },
861 { "movZ", { Rm
, Dm
} },
862 { "movZ", { Cm
, Rm
} },
863 { "movZ", { Dm
, Rm
} },
864 { "movL", { Rd
, Td
} },
866 { "movL", { Td
, Rd
} },
869 { "movapX", { XM
, EX
} },
870 { "movapX", { EX
, XM
} },
875 { "ucomisX", { XM
,EX
} },
876 { "comisX", { XM
,EX
} },
882 { "sysenter", { XX
} },
883 { "sysexit", { XX
} },
896 { "cmovo", { Gv
, Ev
} },
897 { "cmovno", { Gv
, Ev
} },
898 { "cmovb", { Gv
, Ev
} },
899 { "cmovae", { Gv
, Ev
} },
900 { "cmove", { Gv
, Ev
} },
901 { "cmovne", { Gv
, Ev
} },
902 { "cmovbe", { Gv
, Ev
} },
903 { "cmova", { Gv
, Ev
} },
905 { "cmovs", { Gv
, Ev
} },
906 { "cmovns", { Gv
, Ev
} },
907 { "cmovp", { Gv
, Ev
} },
908 { "cmovnp", { Gv
, Ev
} },
909 { "cmovl", { Gv
, Ev
} },
910 { "cmovge", { Gv
, Ev
} },
911 { "cmovle", { Gv
, Ev
} },
912 { "cmovg", { Gv
, Ev
} },
914 { "movmskpX", { Gdq
, XS
} },
918 { "andpX", { XM
, EX
} },
919 { "andnpX", { XM
, EX
} },
920 { "orpX", { XM
, EX
} },
921 { "xorpX", { XM
, EX
} },
932 { "punpcklbw", { MX
, EM
} },
933 { "punpcklwd", { MX
, EM
} },
934 { "punpckldq", { MX
, EM
} },
935 { "packsswb", { MX
, EM
} },
936 { "pcmpgtb", { MX
, EM
} },
937 { "pcmpgtw", { MX
, EM
} },
938 { "pcmpgtd", { MX
, EM
} },
939 { "packuswb", { MX
, EM
} },
941 { "punpckhbw", { MX
, EM
} },
942 { "punpckhwd", { MX
, EM
} },
943 { "punpckhdq", { MX
, EM
} },
944 { "packssdw", { MX
, EM
} },
947 { "movd", { MX
, Edq
} },
954 { "pcmpeqb", { MX
, EM
} },
955 { "pcmpeqw", { MX
, EM
} },
956 { "pcmpeqd", { MX
, EM
} },
968 { "joH", { Jv
, XX
, cond_jump_flag
} },
969 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
970 { "jbH", { Jv
, XX
, cond_jump_flag
} },
971 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
972 { "jeH", { Jv
, XX
, cond_jump_flag
} },
973 { "jneH", { Jv
, XX
, cond_jump_flag
} },
974 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
975 { "jaH", { Jv
, XX
, cond_jump_flag
} },
977 { "jsH", { Jv
, XX
, cond_jump_flag
} },
978 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
979 { "jpH", { Jv
, XX
, cond_jump_flag
} },
980 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
981 { "jlH", { Jv
, XX
, cond_jump_flag
} },
982 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
983 { "jleH", { Jv
, XX
, cond_jump_flag
} },
984 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1000 { "setge", { Eb
} },
1001 { "setle", { Eb
} },
1004 { "pushT", { fs
} },
1006 { "cpuid", { XX
} },
1007 { "btS", { Ev
, Gv
} },
1008 { "shldS", { Ev
, Gv
, Ib
} },
1009 { "shldS", { Ev
, Gv
, CL
} },
1013 { "pushT", { gs
} },
1016 { "btsS", { Ev
, Gv
} },
1017 { "shrdS", { Ev
, Gv
, Ib
} },
1018 { "shrdS", { Ev
, Gv
, CL
} },
1020 { "imulS", { Gv
, Ev
} },
1022 { "cmpxchgB", { Eb
, Gb
} },
1023 { "cmpxchgS", { Ev
, Gv
} },
1024 { "lssS", { Gv
, Mp
} },
1025 { "btrS", { Ev
, Gv
} },
1026 { "lfsS", { Gv
, Mp
} },
1027 { "lgsS", { Gv
, Mp
} },
1028 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1029 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1034 { "btcS", { Ev
, Gv
} },
1035 { "bsfS", { Gv
, Ev
} },
1037 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1038 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1040 { "xaddB", { Eb
, Gb
} },
1041 { "xaddS", { Ev
, Gv
} },
1043 { "movntiS", { Ev
, Gv
} },
1044 { "pinsrw", { MX
, Edqw
, Ib
} },
1045 { "pextrw", { Gdq
, MS
, Ib
} },
1046 { "shufpX", { XM
, EX
, Ib
} },
1049 { "bswap", { RMeAX
} },
1050 { "bswap", { RMeCX
} },
1051 { "bswap", { RMeDX
} },
1052 { "bswap", { RMeBX
} },
1053 { "bswap", { RMeSP
} },
1054 { "bswap", { RMeBP
} },
1055 { "bswap", { RMeSI
} },
1056 { "bswap", { RMeDI
} },
1059 { "psrlw", { MX
, EM
} },
1060 { "psrld", { MX
, EM
} },
1061 { "psrlq", { MX
, EM
} },
1062 { "paddq", { MX
, EM
} },
1063 { "pmullw", { MX
, EM
} },
1065 { "pmovmskb", { Gdq
, MS
} },
1067 { "psubusb", { MX
, EM
} },
1068 { "psubusw", { MX
, EM
} },
1069 { "pminub", { MX
, EM
} },
1070 { "pand", { MX
, EM
} },
1071 { "paddusb", { MX
, EM
} },
1072 { "paddusw", { MX
, EM
} },
1073 { "pmaxub", { MX
, EM
} },
1074 { "pandn", { MX
, EM
} },
1076 { "pavgb", { MX
, EM
} },
1077 { "psraw", { MX
, EM
} },
1078 { "psrad", { MX
, EM
} },
1079 { "pavgw", { MX
, EM
} },
1080 { "pmulhuw", { MX
, EM
} },
1081 { "pmulhw", { MX
, EM
} },
1085 { "psubsb", { MX
, EM
} },
1086 { "psubsw", { MX
, EM
} },
1087 { "pminsw", { MX
, EM
} },
1088 { "por", { MX
, EM
} },
1089 { "paddsb", { MX
, EM
} },
1090 { "paddsw", { MX
, EM
} },
1091 { "pmaxsw", { MX
, EM
} },
1092 { "pxor", { MX
, EM
} },
1095 { "psllw", { MX
, EM
} },
1096 { "pslld", { MX
, EM
} },
1097 { "psllq", { MX
, EM
} },
1098 { "pmuludq", { MX
, EM
} },
1099 { "pmaddwd", { MX
, EM
} },
1100 { "psadbw", { MX
, EM
} },
1103 { "psubb", { MX
, EM
} },
1104 { "psubw", { MX
, EM
} },
1105 { "psubd", { MX
, EM
} },
1106 { "psubq", { MX
, EM
} },
1107 { "paddb", { MX
, EM
} },
1108 { "paddw", { MX
, EM
} },
1109 { "paddd", { MX
, EM
} },
1110 { "(bad)", { XX
} },
1113 static const unsigned char onebyte_has_modrm
[256] = {
1114 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1115 /* ------------------------------- */
1116 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1117 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1118 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1119 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1120 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1121 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1122 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1123 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1124 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1125 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1126 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1127 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1128 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1129 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1130 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1131 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1132 /* ------------------------------- */
1133 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1136 static const unsigned char twobyte_has_modrm
[256] = {
1137 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1138 /* ------------------------------- */
1139 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1140 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1141 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1142 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1143 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1144 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1145 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1146 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1147 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1148 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1149 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1150 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1151 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1152 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1153 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1154 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1155 /* ------------------------------- */
1156 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1159 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1160 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1161 /* ------------------------------- */
1162 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1163 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1164 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1165 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1166 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1167 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1168 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1169 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1170 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1171 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1172 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1173 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1174 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1175 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1176 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1177 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1178 /* ------------------------------- */
1179 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1182 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1183 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1184 /* ------------------------------- */
1185 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1186 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1187 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1188 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1189 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1190 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1191 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1192 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1193 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1194 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1195 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1196 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1197 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1198 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1199 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1200 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1201 /* ------------------------------- */
1202 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1205 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1206 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1207 /* ------------------------------- */
1208 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1209 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1210 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1211 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1212 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1213 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1214 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1215 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1216 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1217 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1218 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1219 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1220 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1221 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1222 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1223 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1224 /* ------------------------------- */
1225 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1228 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1229 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1230 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1231 /* ------------------------------- */
1232 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1233 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1234 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1235 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1236 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1237 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1238 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1239 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1240 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1241 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1242 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1243 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1244 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1245 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1246 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1247 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1248 /* ------------------------------- */
1249 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1252 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1253 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1254 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1255 /* ------------------------------- */
1256 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1257 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1258 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1259 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1260 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1261 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1262 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1263 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1264 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1265 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1266 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1267 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1268 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1269 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1270 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1271 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1272 /* ------------------------------- */
1273 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1276 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1277 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1278 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1279 /* ------------------------------- */
1280 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1281 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1282 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1283 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1284 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1285 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1286 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1287 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1288 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1289 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1290 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1291 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1292 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1293 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1294 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1295 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1296 /* ------------------------------- */
1297 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1300 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1301 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1302 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1303 /* ------------------------------- */
1304 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1305 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1306 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1307 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1308 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1309 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1310 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1311 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1312 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1313 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1314 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1315 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1316 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1317 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1318 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1319 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1320 /* ------------------------------- */
1321 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1324 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1325 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1326 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1327 /* ------------------------------- */
1328 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1329 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1330 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1331 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1332 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1333 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1334 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1335 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1336 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1337 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1338 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1339 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1340 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1341 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1342 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1343 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1344 /* ------------------------------- */
1345 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1348 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1349 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1351 /* ------------------------------- */
1352 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1353 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1354 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1355 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1356 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1357 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1358 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1359 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1360 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1361 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1362 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1363 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1364 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1365 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1366 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1367 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1368 /* ------------------------------- */
1369 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1372 static char obuf
[100];
1374 static char scratchbuf
[100];
1375 static unsigned char *start_codep
;
1376 static unsigned char *insn_codep
;
1377 static unsigned char *codep
;
1378 static disassemble_info
*the_info
;
1382 static unsigned char need_modrm
;
1384 /* If we are accessing mod/rm/reg without need_modrm set, then the
1385 values are stale. Hitting this abort likely indicates that you
1386 need to update onebyte_has_modrm or twobyte_has_modrm. */
1387 #define MODRM_CHECK if (!need_modrm) abort ()
1389 static const char **names64
;
1390 static const char **names32
;
1391 static const char **names16
;
1392 static const char **names8
;
1393 static const char **names8rex
;
1394 static const char **names_seg
;
1395 static const char **index16
;
1397 static const char *intel_names64
[] = {
1398 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1399 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1401 static const char *intel_names32
[] = {
1402 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1403 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1405 static const char *intel_names16
[] = {
1406 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1407 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1409 static const char *intel_names8
[] = {
1410 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1412 static const char *intel_names8rex
[] = {
1413 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1414 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1416 static const char *intel_names_seg
[] = {
1417 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1419 static const char *intel_index16
[] = {
1420 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1423 static const char *att_names64
[] = {
1424 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1425 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1427 static const char *att_names32
[] = {
1428 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1429 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1431 static const char *att_names16
[] = {
1432 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1433 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1435 static const char *att_names8
[] = {
1436 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1438 static const char *att_names8rex
[] = {
1439 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1440 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1442 static const char *att_names_seg
[] = {
1443 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1445 static const char *att_index16
[] = {
1446 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1449 static const struct dis386 grps
[][8] = {
1452 { "addA", { Eb
, Ib
} },
1453 { "orA", { Eb
, Ib
} },
1454 { "adcA", { Eb
, Ib
} },
1455 { "sbbA", { Eb
, Ib
} },
1456 { "andA", { Eb
, Ib
} },
1457 { "subA", { Eb
, Ib
} },
1458 { "xorA", { Eb
, Ib
} },
1459 { "cmpA", { Eb
, Ib
} },
1463 { "addQ", { Ev
, Iv
} },
1464 { "orQ", { Ev
, Iv
} },
1465 { "adcQ", { Ev
, Iv
} },
1466 { "sbbQ", { Ev
, Iv
} },
1467 { "andQ", { Ev
, Iv
} },
1468 { "subQ", { Ev
, Iv
} },
1469 { "xorQ", { Ev
, Iv
} },
1470 { "cmpQ", { Ev
, Iv
} },
1474 { "addQ", { Ev
, sIb
} },
1475 { "orQ", { Ev
, sIb
} },
1476 { "adcQ", { Ev
, sIb
} },
1477 { "sbbQ", { Ev
, sIb
} },
1478 { "andQ", { Ev
, sIb
} },
1479 { "subQ", { Ev
, sIb
} },
1480 { "xorQ", { Ev
, sIb
} },
1481 { "cmpQ", { Ev
, sIb
} },
1485 { "rolA", { Eb
, Ib
} },
1486 { "rorA", { Eb
, Ib
} },
1487 { "rclA", { Eb
, Ib
} },
1488 { "rcrA", { Eb
, Ib
} },
1489 { "shlA", { Eb
, Ib
} },
1490 { "shrA", { Eb
, Ib
} },
1491 { "(bad)", { XX
} },
1492 { "sarA", { Eb
, Ib
} },
1496 { "rolQ", { Ev
, Ib
} },
1497 { "rorQ", { Ev
, Ib
} },
1498 { "rclQ", { Ev
, Ib
} },
1499 { "rcrQ", { Ev
, Ib
} },
1500 { "shlQ", { Ev
, Ib
} },
1501 { "shrQ", { Ev
, Ib
} },
1502 { "(bad)", { XX
} },
1503 { "sarQ", { Ev
, Ib
} },
1507 { "rolA", { Eb
, I1
} },
1508 { "rorA", { Eb
, I1
} },
1509 { "rclA", { Eb
, I1
} },
1510 { "rcrA", { Eb
, I1
} },
1511 { "shlA", { Eb
, I1
} },
1512 { "shrA", { Eb
, I1
} },
1513 { "(bad)", { XX
} },
1514 { "sarA", { Eb
, I1
} },
1518 { "rolQ", { Ev
, I1
} },
1519 { "rorQ", { Ev
, I1
} },
1520 { "rclQ", { Ev
, I1
} },
1521 { "rcrQ", { Ev
, I1
} },
1522 { "shlQ", { Ev
, I1
} },
1523 { "shrQ", { Ev
, I1
} },
1524 { "(bad)", { XX
} },
1525 { "sarQ", { Ev
, I1
} },
1529 { "rolA", { Eb
, CL
} },
1530 { "rorA", { Eb
, CL
} },
1531 { "rclA", { Eb
, CL
} },
1532 { "rcrA", { Eb
, CL
} },
1533 { "shlA", { Eb
, CL
} },
1534 { "shrA", { Eb
, CL
} },
1535 { "(bad)", { XX
} },
1536 { "sarA", { Eb
, CL
} },
1540 { "rolQ", { Ev
, CL
} },
1541 { "rorQ", { Ev
, CL
} },
1542 { "rclQ", { Ev
, CL
} },
1543 { "rcrQ", { Ev
, CL
} },
1544 { "shlQ", { Ev
, CL
} },
1545 { "shrQ", { Ev
, CL
} },
1546 { "(bad)", { XX
} },
1547 { "sarQ", { Ev
, CL
} },
1551 { "testA", { Eb
, Ib
} },
1552 { "(bad)", { Eb
} },
1555 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1556 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1557 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1558 { "idivA", { Eb
} }, /* and idiv for consistency. */
1562 { "testQ", { Ev
, Iv
} },
1563 { "(bad)", { XX
} },
1566 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1567 { "imulQ", { Ev
} },
1569 { "idivQ", { Ev
} },
1575 { "(bad)", { XX
} },
1576 { "(bad)", { XX
} },
1577 { "(bad)", { XX
} },
1578 { "(bad)", { XX
} },
1579 { "(bad)", { XX
} },
1580 { "(bad)", { XX
} },
1586 { "callT", { indirEv
} },
1587 { "JcallT", { indirEp
} },
1588 { "jmpT", { indirEv
} },
1589 { "JjmpT", { indirEp
} },
1590 { "pushU", { stackEv
} },
1591 { "(bad)", { XX
} },
1595 { "sldtD", { Sv
} },
1601 { "(bad)", { XX
} },
1602 { "(bad)", { XX
} },
1606 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1607 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1608 { "lgdt{Q|Q||}", { M
} },
1609 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1610 { "smswD", { Sv
} },
1611 { "(bad)", { XX
} },
1613 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1617 { "(bad)", { XX
} },
1618 { "(bad)", { XX
} },
1619 { "(bad)", { XX
} },
1620 { "(bad)", { XX
} },
1621 { "btQ", { Ev
, Ib
} },
1622 { "btsQ", { Ev
, Ib
} },
1623 { "btrQ", { Ev
, Ib
} },
1624 { "btcQ", { Ev
, Ib
} },
1628 { "(bad)", { XX
} },
1629 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1630 { "(bad)", { XX
} },
1631 { "(bad)", { XX
} },
1632 { "(bad)", { XX
} },
1633 { "(bad)", { XX
} },
1634 { "", { VM
} }, /* See OP_VMX. */
1635 { "vmptrst", { Mq
} },
1639 { "movA", { Eb
, Ib
} },
1640 { "(bad)", { XX
} },
1641 { "(bad)", { XX
} },
1642 { "(bad)", { XX
} },
1643 { "(bad)", { XX
} },
1644 { "(bad)", { XX
} },
1645 { "(bad)", { XX
} },
1646 { "(bad)", { XX
} },
1650 { "movQ", { Ev
, Iv
} },
1651 { "(bad)", { XX
} },
1652 { "(bad)", { XX
} },
1653 { "(bad)", { XX
} },
1654 { "(bad)", { XX
} },
1655 { "(bad)", { XX
} },
1656 { "(bad)", { XX
} },
1657 { "(bad)", { XX
} },
1661 { "(bad)", { XX
} },
1662 { "(bad)", { XX
} },
1663 { "psrlw", { MS
, Ib
} },
1664 { "(bad)", { XX
} },
1665 { "psraw", { MS
, Ib
} },
1666 { "(bad)", { XX
} },
1667 { "psllw", { MS
, Ib
} },
1668 { "(bad)", { XX
} },
1672 { "(bad)", { XX
} },
1673 { "(bad)", { XX
} },
1674 { "psrld", { MS
, Ib
} },
1675 { "(bad)", { XX
} },
1676 { "psrad", { MS
, Ib
} },
1677 { "(bad)", { XX
} },
1678 { "pslld", { MS
, Ib
} },
1679 { "(bad)", { XX
} },
1683 { "(bad)", { XX
} },
1684 { "(bad)", { XX
} },
1685 { "psrlq", { MS
, Ib
} },
1686 { "psrldq", { MS
, Ib
} },
1687 { "(bad)", { XX
} },
1688 { "(bad)", { XX
} },
1689 { "psllq", { MS
, Ib
} },
1690 { "pslldq", { MS
, Ib
} },
1694 { "fxsave", { Ev
} },
1695 { "fxrstor", { Ev
} },
1696 { "ldmxcsr", { Ev
} },
1697 { "stmxcsr", { Ev
} },
1698 { "(bad)", { XX
} },
1699 { "lfence", { { OP_0fae
, 0 } } },
1700 { "mfence", { { OP_0fae
, 0 } } },
1701 { "clflush", { { OP_0fae
, 0 } } },
1705 { "prefetchnta", { Ev
} },
1706 { "prefetcht0", { Ev
} },
1707 { "prefetcht1", { Ev
} },
1708 { "prefetcht2", { Ev
} },
1709 { "(bad)", { XX
} },
1710 { "(bad)", { XX
} },
1711 { "(bad)", { XX
} },
1712 { "(bad)", { XX
} },
1716 { "prefetch", { Eb
} },
1717 { "prefetchw", { Eb
} },
1718 { "(bad)", { XX
} },
1719 { "(bad)", { XX
} },
1720 { "(bad)", { XX
} },
1721 { "(bad)", { XX
} },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1727 { "xstore-rng", { { OP_0f07
, 0 } } },
1728 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1729 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1730 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1731 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1732 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1733 { "(bad)", { { OP_0f07
, 0 } } },
1734 { "(bad)", { { OP_0f07
, 0 } } },
1738 { "montmul", { { OP_0f07
, 0 } } },
1739 { "xsha1", { { OP_0f07
, 0 } } },
1740 { "xsha256", { { OP_0f07
, 0 } } },
1741 { "(bad)", { { OP_0f07
, 0 } } },
1742 { "(bad)", { { OP_0f07
, 0 } } },
1743 { "(bad)", { { OP_0f07
, 0 } } },
1744 { "(bad)", { { OP_0f07
, 0 } } },
1745 { "(bad)", { { OP_0f07
, 0 } } },
1749 static const struct dis386 prefix_user_table
[][4] = {
1752 { "addps", { XM
, EX
} },
1753 { "addss", { XM
, EX
} },
1754 { "addpd", { XM
, EX
} },
1755 { "addsd", { XM
, EX
} },
1759 { "", { XM
, EX
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1760 { "", { XM
, EX
, OPSIMD
} },
1761 { "", { XM
, EX
, OPSIMD
} },
1762 { "", { XM
, EX
, OPSIMD
} },
1766 { "cvtpi2ps", { XM
, EMC
} },
1767 { "cvtsi2ssY", { XM
, Ev
} },
1768 { "cvtpi2pd", { XM
, EMC
} },
1769 { "cvtsi2sdY", { XM
, Ev
} },
1773 { "cvtps2pi", { MXC
, EX
} },
1774 { "cvtss2siY", { Gv
, EX
} },
1775 { "cvtpd2pi", { MXC
, EX
} },
1776 { "cvtsd2siY", { Gv
, EX
} },
1780 { "cvttps2pi", { MXC
, EX
} },
1781 { "cvttss2siY", { Gv
, EX
} },
1782 { "cvttpd2pi", { MXC
, EX
} },
1783 { "cvttsd2siY", { Gv
, EX
} },
1787 { "divps", { XM
, EX
} },
1788 { "divss", { XM
, EX
} },
1789 { "divpd", { XM
, EX
} },
1790 { "divsd", { XM
, EX
} },
1794 { "maxps", { XM
, EX
} },
1795 { "maxss", { XM
, EX
} },
1796 { "maxpd", { XM
, EX
} },
1797 { "maxsd", { XM
, EX
} },
1801 { "minps", { XM
, EX
} },
1802 { "minss", { XM
, EX
} },
1803 { "minpd", { XM
, EX
} },
1804 { "minsd", { XM
, EX
} },
1808 { "movups", { XM
, EX
} },
1809 { "movss", { XM
, EX
} },
1810 { "movupd", { XM
, EX
} },
1811 { "movsd", { XM
, EX
} },
1815 { "movups", { EX
, XM
} },
1816 { "movss", { EX
, XM
} },
1817 { "movupd", { EX
, XM
} },
1818 { "movsd", { EX
, XM
} },
1822 { "mulps", { XM
, EX
} },
1823 { "mulss", { XM
, EX
} },
1824 { "mulpd", { XM
, EX
} },
1825 { "mulsd", { XM
, EX
} },
1829 { "rcpps", { XM
, EX
} },
1830 { "rcpss", { XM
, EX
} },
1831 { "(bad)", { XM
, EX
} },
1832 { "(bad)", { XM
, EX
} },
1836 { "rsqrtps",{ XM
, EX
} },
1837 { "rsqrtss",{ XM
, EX
} },
1838 { "(bad)", { XM
, EX
} },
1839 { "(bad)", { XM
, EX
} },
1843 { "sqrtps", { XM
, EX
} },
1844 { "sqrtss", { XM
, EX
} },
1845 { "sqrtpd", { XM
, EX
} },
1846 { "sqrtsd", { XM
, EX
} },
1850 { "subps", { XM
, EX
} },
1851 { "subss", { XM
, EX
} },
1852 { "subpd", { XM
, EX
} },
1853 { "subsd", { XM
, EX
} },
1857 { "(bad)", { XM
, EX
} },
1858 { "cvtdq2pd", { XM
, EX
} },
1859 { "cvttpd2dq", { XM
, EX
} },
1860 { "cvtpd2dq", { XM
, EX
} },
1864 { "cvtdq2ps", { XM
, EX
} },
1865 { "cvttps2dq", { XM
, EX
} },
1866 { "cvtps2dq", { XM
, EX
} },
1867 { "(bad)", { XM
, EX
} },
1871 { "cvtps2pd", { XM
, EX
} },
1872 { "cvtss2sd", { XM
, EX
} },
1873 { "cvtpd2ps", { XM
, EX
} },
1874 { "cvtsd2ss", { XM
, EX
} },
1878 { "maskmovq", { MX
, MS
} },
1879 { "(bad)", { XM
, EX
} },
1880 { "maskmovdqu", { XM
, XS
} },
1881 { "(bad)", { XM
, EX
} },
1885 { "movq", { MX
, EM
} },
1886 { "movdqu", { XM
, EX
} },
1887 { "movdqa", { XM
, EX
} },
1888 { "(bad)", { XM
, EX
} },
1892 { "movq", { EM
, MX
} },
1893 { "movdqu", { EX
, XM
} },
1894 { "movdqa", { EX
, XM
} },
1895 { "(bad)", { EX
, XM
} },
1899 { "(bad)", { EX
, XM
} },
1900 { "movq2dq",{ XM
, MS
} },
1901 { "movq", { EX
, XM
} },
1902 { "movdq2q",{ MX
, XS
} },
1906 { "pshufw", { MX
, EM
, Ib
} },
1907 { "pshufhw",{ XM
, EX
, Ib
} },
1908 { "pshufd", { XM
, EX
, Ib
} },
1909 { "pshuflw",{ XM
, EX
, Ib
} },
1913 { "movd", { Edq
, MX
} },
1914 { "movq", { XM
, EX
} },
1915 { "movd", { Edq
, XM
} },
1916 { "(bad)", { Ed
, XM
} },
1920 { "(bad)", { MX
, EX
} },
1921 { "(bad)", { XM
, EX
} },
1922 { "punpckhqdq", { XM
, EX
} },
1923 { "(bad)", { XM
, EX
} },
1927 { "movntq", { EM
, MX
} },
1928 { "(bad)", { EM
, XM
} },
1929 { "movntdq",{ EM
, XM
} },
1930 { "(bad)", { EM
, XM
} },
1934 { "(bad)", { MX
, EX
} },
1935 { "(bad)", { XM
, EX
} },
1936 { "punpcklqdq", { XM
, EX
} },
1937 { "(bad)", { XM
, EX
} },
1941 { "(bad)", { MX
, EX
} },
1942 { "(bad)", { XM
, EX
} },
1943 { "addsubpd", { XM
, EX
} },
1944 { "addsubps", { XM
, EX
} },
1948 { "(bad)", { MX
, EX
} },
1949 { "(bad)", { XM
, EX
} },
1950 { "haddpd", { XM
, EX
} },
1951 { "haddps", { XM
, EX
} },
1955 { "(bad)", { MX
, EX
} },
1956 { "(bad)", { XM
, EX
} },
1957 { "hsubpd", { XM
, EX
} },
1958 { "hsubps", { XM
, EX
} },
1962 { "movlpX", { XM
, EX
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
1963 { "movsldup", { XM
, EX
} },
1964 { "movlpd", { XM
, EX
} },
1965 { "movddup", { XM
, EX
} },
1969 { "movhpX", { XM
, EX
, { SIMD_Fixup
, 'l' } } },
1970 { "movshdup", { XM
, EX
} },
1971 { "movhpd", { XM
, EX
} },
1972 { "(bad)", { XM
, EX
} },
1976 { "(bad)", { XM
, EX
} },
1977 { "(bad)", { XM
, EX
} },
1978 { "(bad)", { XM
, EX
} },
1979 { "lddqu", { XM
, M
} },
1983 {"movntps", { Ev
, XM
} },
1984 {"movntss", { Ev
, XM
} },
1985 {"movntpd", { Ev
, XM
} },
1986 {"movntsd", { Ev
, XM
} },
1991 {"vmread", { Em
, Gm
} },
1993 {"extrq", { XS
, Ib
, Ib
} },
1994 {"insertq", { XM
, XS
, Ib
, Ib
} },
1999 {"vmwrite", { Gm
, Em
} },
2001 {"extrq", { XM
, XS
} },
2002 {"insertq", { XM
, XS
} },
2007 { "bsrS", { Gv
, Ev
} },
2008 { "lzcntS", { Gv
, Ev
} },
2009 { "bsrS", { Gv
, Ev
} },
2010 { "(bad)", { XX
} },
2015 { "(bad)", { XX
} },
2016 { "popcntS", { Gv
, Ev
} },
2017 { "(bad)", { XX
} },
2018 { "(bad)", { XX
} },
2022 static const struct dis386 x86_64_table
[][2] = {
2024 { "pusha{P|}", { XX
} },
2025 { "(bad)", { XX
} },
2028 { "popa{P|}", { XX
} },
2029 { "(bad)", { XX
} },
2032 { "bound{S|}", { Gv
, Ma
} },
2033 { "(bad)", { XX
} },
2036 { "arpl", { Ew
, Gw
} },
2037 { "movs{||lq|xd}", { Gv
, Ed
} },
2041 static const struct dis386 three_byte_table
[][256] = {
2045 { "pshufb", { MX
, EM
} },
2046 { "phaddw", { MX
, EM
} },
2047 { "phaddd", { MX
, EM
} },
2048 { "phaddsw", { MX
, EM
} },
2049 { "pmaddubsw", { MX
, EM
} },
2050 { "phsubw", { MX
, EM
} },
2051 { "phsubd", { MX
, EM
} },
2052 { "phsubsw", { MX
, EM
} },
2054 { "psignb", { MX
, EM
} },
2055 { "psignw", { MX
, EM
} },
2056 { "psignd", { MX
, EM
} },
2057 { "pmulhrsw", { MX
, EM
} },
2058 { "(bad)", { XX
} },
2059 { "(bad)", { XX
} },
2060 { "(bad)", { XX
} },
2061 { "(bad)", { XX
} },
2063 { "(bad)", { XX
} },
2064 { "(bad)", { XX
} },
2065 { "(bad)", { XX
} },
2066 { "(bad)", { XX
} },
2067 { "(bad)", { XX
} },
2068 { "(bad)", { XX
} },
2069 { "(bad)", { XX
} },
2070 { "(bad)", { XX
} },
2072 { "(bad)", { XX
} },
2073 { "(bad)", { XX
} },
2074 { "(bad)", { XX
} },
2075 { "(bad)", { XX
} },
2076 { "pabsb", { MX
, EM
} },
2077 { "pabsw", { MX
, EM
} },
2078 { "pabsd", { MX
, EM
} },
2079 { "(bad)", { XX
} },
2081 { "(bad)", { XX
} },
2082 { "(bad)", { XX
} },
2083 { "(bad)", { XX
} },
2084 { "(bad)", { XX
} },
2085 { "(bad)", { XX
} },
2086 { "(bad)", { XX
} },
2087 { "(bad)", { XX
} },
2088 { "(bad)", { XX
} },
2090 { "(bad)", { XX
} },
2091 { "(bad)", { XX
} },
2092 { "(bad)", { XX
} },
2093 { "(bad)", { XX
} },
2094 { "(bad)", { XX
} },
2095 { "(bad)", { XX
} },
2096 { "(bad)", { XX
} },
2097 { "(bad)", { XX
} },
2099 { "(bad)", { XX
} },
2100 { "(bad)", { XX
} },
2101 { "(bad)", { XX
} },
2102 { "(bad)", { XX
} },
2103 { "(bad)", { XX
} },
2104 { "(bad)", { XX
} },
2105 { "(bad)", { XX
} },
2106 { "(bad)", { XX
} },
2108 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2111 { "(bad)", { XX
} },
2112 { "(bad)", { XX
} },
2113 { "(bad)", { XX
} },
2114 { "(bad)", { XX
} },
2115 { "(bad)", { XX
} },
2117 { "(bad)", { XX
} },
2118 { "(bad)", { XX
} },
2119 { "(bad)", { XX
} },
2120 { "(bad)", { XX
} },
2121 { "(bad)", { XX
} },
2122 { "(bad)", { XX
} },
2123 { "(bad)", { XX
} },
2124 { "(bad)", { XX
} },
2126 { "(bad)", { XX
} },
2127 { "(bad)", { XX
} },
2128 { "(bad)", { XX
} },
2129 { "(bad)", { XX
} },
2130 { "(bad)", { XX
} },
2131 { "(bad)", { XX
} },
2132 { "(bad)", { XX
} },
2133 { "(bad)", { XX
} },
2135 { "(bad)", { XX
} },
2136 { "(bad)", { XX
} },
2137 { "(bad)", { XX
} },
2138 { "(bad)", { XX
} },
2139 { "(bad)", { XX
} },
2140 { "(bad)", { XX
} },
2141 { "(bad)", { XX
} },
2142 { "(bad)", { XX
} },
2144 { "(bad)", { XX
} },
2145 { "(bad)", { XX
} },
2146 { "(bad)", { XX
} },
2147 { "(bad)", { XX
} },
2148 { "(bad)", { XX
} },
2149 { "(bad)", { XX
} },
2150 { "(bad)", { XX
} },
2151 { "(bad)", { XX
} },
2153 { "(bad)", { XX
} },
2154 { "(bad)", { XX
} },
2155 { "(bad)", { XX
} },
2156 { "(bad)", { XX
} },
2157 { "(bad)", { XX
} },
2158 { "(bad)", { XX
} },
2159 { "(bad)", { XX
} },
2160 { "(bad)", { XX
} },
2162 { "(bad)", { XX
} },
2163 { "(bad)", { XX
} },
2164 { "(bad)", { XX
} },
2165 { "(bad)", { XX
} },
2166 { "(bad)", { XX
} },
2167 { "(bad)", { XX
} },
2168 { "(bad)", { XX
} },
2169 { "(bad)", { XX
} },
2171 { "(bad)", { XX
} },
2172 { "(bad)", { XX
} },
2173 { "(bad)", { XX
} },
2174 { "(bad)", { XX
} },
2175 { "(bad)", { XX
} },
2176 { "(bad)", { XX
} },
2177 { "(bad)", { XX
} },
2178 { "(bad)", { XX
} },
2180 { "(bad)", { XX
} },
2181 { "(bad)", { XX
} },
2182 { "(bad)", { XX
} },
2183 { "(bad)", { XX
} },
2184 { "(bad)", { XX
} },
2185 { "(bad)", { XX
} },
2186 { "(bad)", { XX
} },
2187 { "(bad)", { XX
} },
2189 { "(bad)", { XX
} },
2190 { "(bad)", { XX
} },
2191 { "(bad)", { XX
} },
2192 { "(bad)", { XX
} },
2193 { "(bad)", { XX
} },
2194 { "(bad)", { XX
} },
2195 { "(bad)", { XX
} },
2196 { "(bad)", { XX
} },
2198 { "(bad)", { XX
} },
2199 { "(bad)", { XX
} },
2200 { "(bad)", { XX
} },
2201 { "(bad)", { XX
} },
2202 { "(bad)", { XX
} },
2203 { "(bad)", { XX
} },
2204 { "(bad)", { XX
} },
2205 { "(bad)", { XX
} },
2207 { "(bad)", { XX
} },
2208 { "(bad)", { XX
} },
2209 { "(bad)", { XX
} },
2210 { "(bad)", { XX
} },
2211 { "(bad)", { XX
} },
2212 { "(bad)", { XX
} },
2213 { "(bad)", { XX
} },
2214 { "(bad)", { XX
} },
2216 { "(bad)", { XX
} },
2217 { "(bad)", { XX
} },
2218 { "(bad)", { XX
} },
2219 { "(bad)", { XX
} },
2220 { "(bad)", { XX
} },
2221 { "(bad)", { XX
} },
2222 { "(bad)", { XX
} },
2223 { "(bad)", { XX
} },
2225 { "(bad)", { XX
} },
2226 { "(bad)", { XX
} },
2227 { "(bad)", { XX
} },
2228 { "(bad)", { XX
} },
2229 { "(bad)", { XX
} },
2230 { "(bad)", { XX
} },
2231 { "(bad)", { XX
} },
2232 { "(bad)", { XX
} },
2234 { "(bad)", { XX
} },
2235 { "(bad)", { XX
} },
2236 { "(bad)", { XX
} },
2237 { "(bad)", { XX
} },
2238 { "(bad)", { XX
} },
2239 { "(bad)", { XX
} },
2240 { "(bad)", { XX
} },
2241 { "(bad)", { XX
} },
2243 { "(bad)", { XX
} },
2244 { "(bad)", { XX
} },
2245 { "(bad)", { XX
} },
2246 { "(bad)", { XX
} },
2247 { "(bad)", { XX
} },
2248 { "(bad)", { XX
} },
2249 { "(bad)", { XX
} },
2250 { "(bad)", { XX
} },
2252 { "(bad)", { XX
} },
2253 { "(bad)", { XX
} },
2254 { "(bad)", { XX
} },
2255 { "(bad)", { XX
} },
2256 { "(bad)", { XX
} },
2257 { "(bad)", { XX
} },
2258 { "(bad)", { XX
} },
2259 { "(bad)", { XX
} },
2261 { "(bad)", { XX
} },
2262 { "(bad)", { XX
} },
2263 { "(bad)", { XX
} },
2264 { "(bad)", { XX
} },
2265 { "(bad)", { XX
} },
2266 { "(bad)", { XX
} },
2267 { "(bad)", { XX
} },
2268 { "(bad)", { XX
} },
2270 { "(bad)", { XX
} },
2271 { "(bad)", { XX
} },
2272 { "(bad)", { XX
} },
2273 { "(bad)", { XX
} },
2274 { "(bad)", { XX
} },
2275 { "(bad)", { XX
} },
2276 { "(bad)", { XX
} },
2277 { "(bad)", { XX
} },
2279 { "(bad)", { XX
} },
2280 { "(bad)", { XX
} },
2281 { "(bad)", { XX
} },
2282 { "(bad)", { XX
} },
2283 { "(bad)", { XX
} },
2284 { "(bad)", { XX
} },
2285 { "(bad)", { XX
} },
2286 { "(bad)", { XX
} },
2288 { "(bad)", { XX
} },
2289 { "(bad)", { XX
} },
2290 { "(bad)", { XX
} },
2291 { "(bad)", { XX
} },
2292 { "(bad)", { XX
} },
2293 { "(bad)", { XX
} },
2294 { "(bad)", { XX
} },
2295 { "(bad)", { XX
} },
2297 { "(bad)", { XX
} },
2298 { "(bad)", { XX
} },
2299 { "(bad)", { XX
} },
2300 { "(bad)", { XX
} },
2301 { "(bad)", { XX
} },
2302 { "(bad)", { XX
} },
2303 { "(bad)", { XX
} },
2304 { "(bad)", { XX
} },
2306 { "(bad)", { XX
} },
2307 { "(bad)", { XX
} },
2308 { "(bad)", { XX
} },
2309 { "(bad)", { XX
} },
2310 { "(bad)", { XX
} },
2311 { "(bad)", { XX
} },
2312 { "(bad)", { XX
} },
2313 { "(bad)", { XX
} },
2315 { "(bad)", { XX
} },
2316 { "(bad)", { XX
} },
2317 { "(bad)", { XX
} },
2318 { "(bad)", { XX
} },
2319 { "(bad)", { XX
} },
2320 { "(bad)", { XX
} },
2321 { "(bad)", { XX
} },
2322 { "(bad)", { XX
} },
2324 { "(bad)", { XX
} },
2325 { "(bad)", { XX
} },
2326 { "(bad)", { XX
} },
2327 { "(bad)", { XX
} },
2328 { "(bad)", { XX
} },
2329 { "(bad)", { XX
} },
2330 { "(bad)", { XX
} },
2331 { "(bad)", { XX
} },
2336 { "(bad)", { XX
} },
2337 { "(bad)", { XX
} },
2338 { "(bad)", { XX
} },
2339 { "(bad)", { XX
} },
2340 { "(bad)", { XX
} },
2341 { "(bad)", { XX
} },
2342 { "(bad)", { XX
} },
2343 { "(bad)", { XX
} },
2345 { "(bad)", { XX
} },
2346 { "(bad)", { XX
} },
2347 { "(bad)", { XX
} },
2348 { "(bad)", { XX
} },
2349 { "(bad)", { XX
} },
2350 { "(bad)", { XX
} },
2351 { "(bad)", { XX
} },
2352 { "palignr", { MX
, EM
, Ib
} },
2354 { "(bad)", { XX
} },
2355 { "(bad)", { XX
} },
2356 { "(bad)", { XX
} },
2357 { "(bad)", { XX
} },
2358 { "(bad)", { XX
} },
2359 { "(bad)", { XX
} },
2360 { "(bad)", { XX
} },
2361 { "(bad)", { XX
} },
2363 { "(bad)", { XX
} },
2364 { "(bad)", { XX
} },
2365 { "(bad)", { XX
} },
2366 { "(bad)", { XX
} },
2367 { "(bad)", { XX
} },
2368 { "(bad)", { XX
} },
2369 { "(bad)", { XX
} },
2370 { "(bad)", { XX
} },
2372 { "(bad)", { XX
} },
2373 { "(bad)", { XX
} },
2374 { "(bad)", { XX
} },
2375 { "(bad)", { XX
} },
2376 { "(bad)", { XX
} },
2377 { "(bad)", { XX
} },
2378 { "(bad)", { XX
} },
2379 { "(bad)", { XX
} },
2381 { "(bad)", { XX
} },
2382 { "(bad)", { XX
} },
2383 { "(bad)", { XX
} },
2384 { "(bad)", { XX
} },
2385 { "(bad)", { XX
} },
2386 { "(bad)", { XX
} },
2387 { "(bad)", { XX
} },
2388 { "(bad)", { XX
} },
2390 { "(bad)", { XX
} },
2391 { "(bad)", { XX
} },
2392 { "(bad)", { XX
} },
2393 { "(bad)", { XX
} },
2394 { "(bad)", { XX
} },
2395 { "(bad)", { XX
} },
2396 { "(bad)", { XX
} },
2397 { "(bad)", { XX
} },
2399 { "(bad)", { XX
} },
2400 { "(bad)", { XX
} },
2401 { "(bad)", { XX
} },
2402 { "(bad)", { XX
} },
2403 { "(bad)", { XX
} },
2404 { "(bad)", { XX
} },
2405 { "(bad)", { XX
} },
2406 { "(bad)", { XX
} },
2408 { "(bad)", { XX
} },
2409 { "(bad)", { XX
} },
2410 { "(bad)", { XX
} },
2411 { "(bad)", { XX
} },
2412 { "(bad)", { XX
} },
2413 { "(bad)", { XX
} },
2414 { "(bad)", { XX
} },
2415 { "(bad)", { XX
} },
2417 { "(bad)", { XX
} },
2418 { "(bad)", { XX
} },
2419 { "(bad)", { XX
} },
2420 { "(bad)", { XX
} },
2421 { "(bad)", { XX
} },
2422 { "(bad)", { XX
} },
2423 { "(bad)", { XX
} },
2424 { "(bad)", { XX
} },
2426 { "(bad)", { XX
} },
2427 { "(bad)", { XX
} },
2428 { "(bad)", { XX
} },
2429 { "(bad)", { XX
} },
2430 { "(bad)", { XX
} },
2431 { "(bad)", { XX
} },
2432 { "(bad)", { XX
} },
2433 { "(bad)", { XX
} },
2435 { "(bad)", { XX
} },
2436 { "(bad)", { XX
} },
2437 { "(bad)", { XX
} },
2438 { "(bad)", { XX
} },
2439 { "(bad)", { XX
} },
2440 { "(bad)", { XX
} },
2441 { "(bad)", { XX
} },
2442 { "(bad)", { XX
} },
2444 { "(bad)", { XX
} },
2445 { "(bad)", { XX
} },
2446 { "(bad)", { XX
} },
2447 { "(bad)", { XX
} },
2448 { "(bad)", { XX
} },
2449 { "(bad)", { XX
} },
2450 { "(bad)", { XX
} },
2451 { "(bad)", { XX
} },
2453 { "(bad)", { XX
} },
2454 { "(bad)", { XX
} },
2455 { "(bad)", { XX
} },
2456 { "(bad)", { XX
} },
2457 { "(bad)", { XX
} },
2458 { "(bad)", { XX
} },
2459 { "(bad)", { XX
} },
2460 { "(bad)", { XX
} },
2462 { "(bad)", { XX
} },
2463 { "(bad)", { XX
} },
2464 { "(bad)", { XX
} },
2465 { "(bad)", { XX
} },
2466 { "(bad)", { XX
} },
2467 { "(bad)", { XX
} },
2468 { "(bad)", { XX
} },
2469 { "(bad)", { XX
} },
2471 { "(bad)", { XX
} },
2472 { "(bad)", { XX
} },
2473 { "(bad)", { XX
} },
2474 { "(bad)", { XX
} },
2475 { "(bad)", { XX
} },
2476 { "(bad)", { XX
} },
2477 { "(bad)", { XX
} },
2478 { "(bad)", { XX
} },
2480 { "(bad)", { XX
} },
2481 { "(bad)", { XX
} },
2482 { "(bad)", { XX
} },
2483 { "(bad)", { XX
} },
2484 { "(bad)", { XX
} },
2485 { "(bad)", { XX
} },
2486 { "(bad)", { XX
} },
2487 { "(bad)", { XX
} },
2489 { "(bad)", { XX
} },
2490 { "(bad)", { XX
} },
2491 { "(bad)", { XX
} },
2492 { "(bad)", { XX
} },
2493 { "(bad)", { XX
} },
2494 { "(bad)", { XX
} },
2495 { "(bad)", { XX
} },
2496 { "(bad)", { XX
} },
2498 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2500 { "(bad)", { XX
} },
2501 { "(bad)", { XX
} },
2502 { "(bad)", { XX
} },
2503 { "(bad)", { XX
} },
2504 { "(bad)", { XX
} },
2505 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "(bad)", { XX
} },
2509 { "(bad)", { XX
} },
2510 { "(bad)", { XX
} },
2511 { "(bad)", { XX
} },
2512 { "(bad)", { XX
} },
2513 { "(bad)", { XX
} },
2514 { "(bad)", { XX
} },
2516 { "(bad)", { XX
} },
2517 { "(bad)", { XX
} },
2518 { "(bad)", { XX
} },
2519 { "(bad)", { XX
} },
2520 { "(bad)", { XX
} },
2521 { "(bad)", { XX
} },
2522 { "(bad)", { XX
} },
2523 { "(bad)", { XX
} },
2525 { "(bad)", { XX
} },
2526 { "(bad)", { XX
} },
2527 { "(bad)", { XX
} },
2528 { "(bad)", { XX
} },
2529 { "(bad)", { XX
} },
2530 { "(bad)", { XX
} },
2531 { "(bad)", { XX
} },
2532 { "(bad)", { XX
} },
2534 { "(bad)", { XX
} },
2535 { "(bad)", { XX
} },
2536 { "(bad)", { XX
} },
2537 { "(bad)", { XX
} },
2538 { "(bad)", { XX
} },
2539 { "(bad)", { XX
} },
2540 { "(bad)", { XX
} },
2541 { "(bad)", { XX
} },
2543 { "(bad)", { XX
} },
2544 { "(bad)", { XX
} },
2545 { "(bad)", { XX
} },
2546 { "(bad)", { XX
} },
2547 { "(bad)", { XX
} },
2548 { "(bad)", { XX
} },
2549 { "(bad)", { XX
} },
2550 { "(bad)", { XX
} },
2552 { "(bad)", { XX
} },
2553 { "(bad)", { XX
} },
2554 { "(bad)", { XX
} },
2555 { "(bad)", { XX
} },
2556 { "(bad)", { XX
} },
2557 { "(bad)", { XX
} },
2558 { "(bad)", { XX
} },
2559 { "(bad)", { XX
} },
2561 { "(bad)", { XX
} },
2562 { "(bad)", { XX
} },
2563 { "(bad)", { XX
} },
2564 { "(bad)", { XX
} },
2565 { "(bad)", { XX
} },
2566 { "(bad)", { XX
} },
2567 { "(bad)", { XX
} },
2568 { "(bad)", { XX
} },
2570 { "(bad)", { XX
} },
2571 { "(bad)", { XX
} },
2572 { "(bad)", { XX
} },
2573 { "(bad)", { XX
} },
2574 { "(bad)", { XX
} },
2575 { "(bad)", { XX
} },
2576 { "(bad)", { XX
} },
2577 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2580 { "(bad)", { XX
} },
2581 { "(bad)", { XX
} },
2582 { "(bad)", { XX
} },
2583 { "(bad)", { XX
} },
2584 { "(bad)", { XX
} },
2585 { "(bad)", { XX
} },
2586 { "(bad)", { XX
} },
2588 { "(bad)", { XX
} },
2589 { "(bad)", { XX
} },
2590 { "(bad)", { XX
} },
2591 { "(bad)", { XX
} },
2592 { "(bad)", { XX
} },
2593 { "(bad)", { XX
} },
2594 { "(bad)", { XX
} },
2595 { "(bad)", { XX
} },
2597 { "(bad)", { XX
} },
2598 { "(bad)", { XX
} },
2599 { "(bad)", { XX
} },
2600 { "(bad)", { XX
} },
2601 { "(bad)", { XX
} },
2602 { "(bad)", { XX
} },
2603 { "(bad)", { XX
} },
2604 { "(bad)", { XX
} },
2606 { "(bad)", { XX
} },
2607 { "(bad)", { XX
} },
2608 { "(bad)", { XX
} },
2609 { "(bad)", { XX
} },
2610 { "(bad)", { XX
} },
2611 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "(bad)", { XX
} },
2615 { "(bad)", { XX
} },
2616 { "(bad)", { XX
} },
2617 { "(bad)", { XX
} },
2618 { "(bad)", { XX
} },
2619 { "(bad)", { XX
} },
2620 { "(bad)", { XX
} },
2621 { "(bad)", { XX
} },
2622 { "(bad)", { XX
} },
2626 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2638 FETCH_DATA (the_info
, codep
+ 1);
2642 /* REX prefixes family. */
2659 if (address_mode
== mode_64bit
)
2665 prefixes
|= PREFIX_REPZ
;
2668 prefixes
|= PREFIX_REPNZ
;
2671 prefixes
|= PREFIX_LOCK
;
2674 prefixes
|= PREFIX_CS
;
2677 prefixes
|= PREFIX_SS
;
2680 prefixes
|= PREFIX_DS
;
2683 prefixes
|= PREFIX_ES
;
2686 prefixes
|= PREFIX_FS
;
2689 prefixes
|= PREFIX_GS
;
2692 prefixes
|= PREFIX_DATA
;
2695 prefixes
|= PREFIX_ADDR
;
2698 /* fwait is really an instruction. If there are prefixes
2699 before the fwait, they belong to the fwait, *not* to the
2700 following instruction. */
2701 if (prefixes
|| rex
)
2703 prefixes
|= PREFIX_FWAIT
;
2707 prefixes
= PREFIX_FWAIT
;
2712 /* Rex is ignored when followed by another prefix. */
2723 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2727 prefix_name (int pref
, int sizeflag
)
2731 /* REX prefixes family. */
2783 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2785 if (address_mode
== mode_64bit
)
2786 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2788 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2796 static char op_out
[MAX_OPERANDS
][100];
2797 static int op_ad
, op_index
[MAX_OPERANDS
];
2798 static int two_source_ops
;
2799 static bfd_vma op_address
[MAX_OPERANDS
];
2800 static bfd_vma op_riprel
[MAX_OPERANDS
];
2801 static bfd_vma start_pc
;
2804 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2805 * (see topic "Redundant prefixes" in the "Differences from 8086"
2806 * section of the "Virtual 8086 Mode" chapter.)
2807 * 'pc' should be the address of this instruction, it will
2808 * be used to print the target address if this is a relative jump or call
2809 * The function returns the length of this instruction in bytes.
2812 static char intel_syntax
;
2813 static char open_char
;
2814 static char close_char
;
2815 static char separator_char
;
2816 static char scale_char
;
2818 /* Here for backwards compatibility. When gdb stops using
2819 print_insn_i386_att and print_insn_i386_intel these functions can
2820 disappear, and print_insn_i386 be merged into print_insn. */
2822 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2826 return print_insn (pc
, info
);
2830 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2834 return print_insn (pc
, info
);
2838 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2842 return print_insn (pc
, info
);
2846 print_i386_disassembler_options (FILE *stream
)
2848 fprintf (stream
, _("\n\
2849 The following i386/x86-64 specific disassembler options are supported for use\n\
2850 with the -M switch (multiple options should be separated by commas):\n"));
2852 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
2853 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
2854 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
2855 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
2856 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
2857 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
2858 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
2859 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
2860 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
2861 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
2862 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
2866 print_insn (bfd_vma pc
, disassemble_info
*info
)
2868 const struct dis386
*dp
;
2870 char *op_txt
[MAX_OPERANDS
];
2872 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
2873 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
2876 struct dis_private priv
;
2879 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2880 || info
->mach
== bfd_mach_x86_64
)
2881 address_mode
= mode_64bit
;
2883 address_mode
= mode_32bit
;
2885 if (intel_syntax
== (char) -1)
2886 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2887 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2889 if (info
->mach
== bfd_mach_i386_i386
2890 || info
->mach
== bfd_mach_x86_64
2891 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2892 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2893 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2894 else if (info
->mach
== bfd_mach_i386_i8086
)
2895 priv
.orig_sizeflag
= 0;
2899 for (p
= info
->disassembler_options
; p
!= NULL
; )
2901 if (CONST_STRNEQ (p
, "x86-64"))
2903 address_mode
= mode_64bit
;
2904 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2906 else if (CONST_STRNEQ (p
, "i386"))
2908 address_mode
= mode_32bit
;
2909 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2911 else if (CONST_STRNEQ (p
, "i8086"))
2913 address_mode
= mode_16bit
;
2914 priv
.orig_sizeflag
= 0;
2916 else if (CONST_STRNEQ (p
, "intel"))
2920 else if (CONST_STRNEQ (p
, "att"))
2924 else if (CONST_STRNEQ (p
, "addr"))
2926 if (address_mode
== mode_64bit
)
2928 if (p
[4] == '3' && p
[5] == '2')
2929 priv
.orig_sizeflag
&= ~AFLAG
;
2930 else if (p
[4] == '6' && p
[5] == '4')
2931 priv
.orig_sizeflag
|= AFLAG
;
2935 if (p
[4] == '1' && p
[5] == '6')
2936 priv
.orig_sizeflag
&= ~AFLAG
;
2937 else if (p
[4] == '3' && p
[5] == '2')
2938 priv
.orig_sizeflag
|= AFLAG
;
2941 else if (CONST_STRNEQ (p
, "data"))
2943 if (p
[4] == '1' && p
[5] == '6')
2944 priv
.orig_sizeflag
&= ~DFLAG
;
2945 else if (p
[4] == '3' && p
[5] == '2')
2946 priv
.orig_sizeflag
|= DFLAG
;
2948 else if (CONST_STRNEQ (p
, "suffix"))
2949 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2951 p
= strchr (p
, ',');
2958 names64
= intel_names64
;
2959 names32
= intel_names32
;
2960 names16
= intel_names16
;
2961 names8
= intel_names8
;
2962 names8rex
= intel_names8rex
;
2963 names_seg
= intel_names_seg
;
2964 index16
= intel_index16
;
2967 separator_char
= '+';
2972 names64
= att_names64
;
2973 names32
= att_names32
;
2974 names16
= att_names16
;
2975 names8
= att_names8
;
2976 names8rex
= att_names8rex
;
2977 names_seg
= att_names_seg
;
2978 index16
= att_index16
;
2981 separator_char
= ',';
2985 /* The output looks better if we put 7 bytes on a line, since that
2986 puts most long word instructions on a single line. */
2987 info
->bytes_per_line
= 7;
2989 info
->private_data
= &priv
;
2990 priv
.max_fetched
= priv
.the_buffer
;
2991 priv
.insn_start
= pc
;
2994 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3002 start_codep
= priv
.the_buffer
;
3003 codep
= priv
.the_buffer
;
3005 if (setjmp (priv
.bailout
) != 0)
3009 /* Getting here means we tried for data but didn't get it. That
3010 means we have an incomplete instruction of some sort. Just
3011 print the first byte as a prefix or a .byte pseudo-op. */
3012 if (codep
> priv
.the_buffer
)
3014 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3016 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3019 /* Just print the first byte as a .byte instruction. */
3020 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3021 (unsigned int) priv
.the_buffer
[0]);
3034 sizeflag
= priv
.orig_sizeflag
;
3036 FETCH_DATA (info
, codep
+ 1);
3037 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3039 if (((prefixes
& PREFIX_FWAIT
)
3040 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3041 || (rex
&& rex_used
))
3045 /* fwait not followed by floating point instruction, or rex followed
3046 by other prefixes. Print the first prefix. */
3047 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3049 name
= INTERNAL_DISASSEMBLER_ERROR
;
3050 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3057 unsigned char threebyte
;
3058 FETCH_DATA (info
, codep
+ 2);
3059 threebyte
= *++codep
;
3060 dp
= &dis386_twobyte
[threebyte
];
3061 need_modrm
= twobyte_has_modrm
[*codep
];
3062 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3063 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3064 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3065 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3067 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3069 FETCH_DATA (info
, codep
+ 2);
3074 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3075 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3076 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3079 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3080 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3081 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3090 dp
= &dis386
[*codep
];
3091 need_modrm
= onebyte_has_modrm
[*codep
];
3092 uses_DATA_prefix
= 0;
3093 uses_REPNZ_prefix
= 0;
3094 uses_REPZ_prefix
= 0;
3095 uses_LOCK_prefix
= 0;
3099 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3102 used_prefixes
|= PREFIX_REPZ
;
3104 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3107 used_prefixes
|= PREFIX_REPNZ
;
3110 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3113 used_prefixes
|= PREFIX_LOCK
;
3116 if (prefixes
& PREFIX_ADDR
)
3119 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3121 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3122 oappend ("addr32 ");
3124 oappend ("addr16 ");
3125 used_prefixes
|= PREFIX_ADDR
;
3129 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3132 if (dp
->op
[2].bytemode
== cond_jump_mode
3133 && dp
->op
[0].bytemode
== v_mode
3136 if (sizeflag
& DFLAG
)
3137 oappend ("data32 ");
3139 oappend ("data16 ");
3140 used_prefixes
|= PREFIX_DATA
;
3144 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3146 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3147 mod
= (*codep
>> 6) & 3;
3148 reg
= (*codep
>> 3) & 7;
3151 else if (need_modrm
)
3153 FETCH_DATA (info
, codep
+ 1);
3154 mod
= (*codep
>> 6) & 3;
3155 reg
= (*codep
>> 3) & 7;
3159 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3166 if (dp
->name
== NULL
)
3168 switch (dp
->op
[0].bytemode
)
3171 dp
= &grps
[dp
->op
[1].bytemode
][reg
];
3174 case USE_PREFIX_USER_TABLE
:
3176 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3177 if (prefixes
& PREFIX_REPZ
)
3181 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3182 before PREFIX_DATA. */
3183 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3184 if (prefixes
& PREFIX_REPNZ
)
3188 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3189 if (prefixes
& PREFIX_DATA
)
3193 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3196 case X86_64_SPECIAL
:
3197 index
= address_mode
== mode_64bit
? 1 : 0;
3198 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3202 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3207 if (putop (dp
->name
, sizeflag
) == 0)
3209 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3212 op_ad
= MAX_OPERANDS
- 1 - i
;
3214 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3219 /* See if any prefixes were not used. If so, print the first one
3220 separately. If we don't do this, we'll wind up printing an
3221 instruction stream which does not precisely correspond to the
3222 bytes we are disassembling. */
3223 if ((prefixes
& ~used_prefixes
) != 0)
3227 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3229 name
= INTERNAL_DISASSEMBLER_ERROR
;
3230 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3233 if (rex
& ~rex_used
)
3236 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3238 name
= INTERNAL_DISASSEMBLER_ERROR
;
3239 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3242 obufp
= obuf
+ strlen (obuf
);
3243 for (i
= strlen (obuf
); i
< 6; i
++)
3246 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3248 /* The enter and bound instructions are printed with operands in the same
3249 order as the intel book; everything else is printed in reverse order. */
3250 if (intel_syntax
|| two_source_ops
)
3252 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3253 op_txt
[i
] = op_out
[i
];
3255 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3257 op_ad
= op_index
[i
];
3258 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3259 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3264 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3265 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3269 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3273 (*info
->fprintf_func
) (info
->stream
, ",");
3274 if (op_index
[i
] != -1 && !op_riprel
[i
])
3275 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3277 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3281 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3282 if (op_index
[i
] != -1 && op_riprel
[i
])
3284 (*info
->fprintf_func
) (info
->stream
, " # ");
3285 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3286 + op_address
[op_index
[i
]]), info
);
3288 return codep
- priv
.the_buffer
;
3291 static const char *float_mem
[] = {
3366 static const unsigned char float_mem_mode
[] = {
3441 #define ST { OP_ST, 0 }
3442 #define STi { OP_STi, 0 }
3444 #define FGRPd9_2 NULL, { { NULL, 0 } }
3445 #define FGRPd9_4 NULL, { { NULL, 1 } }
3446 #define FGRPd9_5 NULL, { { NULL, 2 } }
3447 #define FGRPd9_6 NULL, { { NULL, 3 } }
3448 #define FGRPd9_7 NULL, { { NULL, 4 } }
3449 #define FGRPda_5 NULL, { { NULL, 5 } }
3450 #define FGRPdb_4 NULL, { { NULL, 6 } }
3451 #define FGRPde_3 NULL, { { NULL, 7 } }
3452 #define FGRPdf_4 NULL, { { NULL, 8 } }
3454 static const struct dis386 float_reg
[][8] = {
3457 { "fadd", { ST
, STi
} },
3458 { "fmul", { ST
, STi
} },
3459 { "fcom", { STi
} },
3460 { "fcomp", { STi
} },
3461 { "fsub", { ST
, STi
} },
3462 { "fsubr", { ST
, STi
} },
3463 { "fdiv", { ST
, STi
} },
3464 { "fdivr", { ST
, STi
} },
3469 { "fxch", { STi
} },
3471 { "(bad)", { XX
} },
3479 { "fcmovb", { ST
, STi
} },
3480 { "fcmove", { ST
, STi
} },
3481 { "fcmovbe",{ ST
, STi
} },
3482 { "fcmovu", { ST
, STi
} },
3483 { "(bad)", { XX
} },
3485 { "(bad)", { XX
} },
3486 { "(bad)", { XX
} },
3490 { "fcmovnb",{ ST
, STi
} },
3491 { "fcmovne",{ ST
, STi
} },
3492 { "fcmovnbe",{ ST
, STi
} },
3493 { "fcmovnu",{ ST
, STi
} },
3495 { "fucomi", { ST
, STi
} },
3496 { "fcomi", { ST
, STi
} },
3497 { "(bad)", { XX
} },
3501 { "fadd", { STi
, ST
} },
3502 { "fmul", { STi
, ST
} },
3503 { "(bad)", { XX
} },
3504 { "(bad)", { XX
} },
3506 { "fsub", { STi
, ST
} },
3507 { "fsubr", { STi
, ST
} },
3508 { "fdiv", { STi
, ST
} },
3509 { "fdivr", { STi
, ST
} },
3511 { "fsubr", { STi
, ST
} },
3512 { "fsub", { STi
, ST
} },
3513 { "fdivr", { STi
, ST
} },
3514 { "fdiv", { STi
, ST
} },
3519 { "ffree", { STi
} },
3520 { "(bad)", { XX
} },
3522 { "fstp", { STi
} },
3523 { "fucom", { STi
} },
3524 { "fucomp", { STi
} },
3525 { "(bad)", { XX
} },
3526 { "(bad)", { XX
} },
3530 { "faddp", { STi
, ST
} },
3531 { "fmulp", { STi
, ST
} },
3532 { "(bad)", { XX
} },
3535 { "fsubp", { STi
, ST
} },
3536 { "fsubrp", { STi
, ST
} },
3537 { "fdivp", { STi
, ST
} },
3538 { "fdivrp", { STi
, ST
} },
3540 { "fsubrp", { STi
, ST
} },
3541 { "fsubp", { STi
, ST
} },
3542 { "fdivrp", { STi
, ST
} },
3543 { "fdivp", { STi
, ST
} },
3548 { "ffreep", { STi
} },
3549 { "(bad)", { XX
} },
3550 { "(bad)", { XX
} },
3551 { "(bad)", { XX
} },
3553 { "fucomip", { ST
, STi
} },
3554 { "fcomip", { ST
, STi
} },
3555 { "(bad)", { XX
} },
3559 static char *fgrps
[][8] = {
3562 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3567 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3572 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3577 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3582 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3587 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3592 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3593 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3598 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3603 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3608 dofloat (int sizeflag
)
3610 const struct dis386
*dp
;
3611 unsigned char floatop
;
3613 floatop
= codep
[-1];
3617 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
3619 putop (float_mem
[fp_indx
], sizeflag
);
3622 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
3625 /* Skip mod/rm byte. */
3629 dp
= &float_reg
[floatop
- 0xd8][reg
];
3630 if (dp
->name
== NULL
)
3632 putop (fgrps
[dp
->op
[0].bytemode
][rm
], sizeflag
);
3634 /* Instruction fnstsw is only one with strange arg. */
3635 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3636 strcpy (op_out
[0], names16
[0]);
3640 putop (dp
->name
, sizeflag
);
3645 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
3650 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
3655 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3657 oappend ("%st" + intel_syntax
);
3661 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3663 sprintf (scratchbuf
, "%%st(%d)", rm
);
3664 oappend (scratchbuf
+ intel_syntax
);
3667 /* Capital letters in template are macros. */
3669 putop (const char *template, int sizeflag
)
3674 for (p
= template; *p
; p
++)
3685 if (address_mode
== mode_64bit
)
3693 /* Alternative not valid. */
3694 strcpy (obuf
, "(bad)");
3698 else if (*p
== '\0')
3719 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3725 if (sizeflag
& SUFFIX_ALWAYS
)
3729 if (intel_syntax
&& !alt
)
3731 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
3733 if (sizeflag
& DFLAG
)
3734 *obufp
++ = intel_syntax
? 'd' : 'l';
3736 *obufp
++ = intel_syntax
? 'w' : 's';
3737 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3741 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
3743 USED_REX (REX_MODE64
);
3746 if (rex
& REX_MODE64
)
3748 else if (sizeflag
& DFLAG
)
3749 *obufp
++ = intel_syntax
? 'd' : 'l';
3752 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3757 case 'E': /* For jcxz/jecxz */
3758 if (address_mode
== mode_64bit
)
3760 if (sizeflag
& AFLAG
)
3766 if (sizeflag
& AFLAG
)
3768 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3773 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
3775 if (sizeflag
& AFLAG
)
3776 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
3778 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
3779 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3783 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
3785 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
3789 if (!(rex
& REX_MODE64
))
3790 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3795 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
3796 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
3798 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
3801 if (prefixes
& PREFIX_DS
)
3815 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
3824 if (sizeflag
& SUFFIX_ALWAYS
)
3828 if ((prefixes
& PREFIX_FWAIT
) == 0)
3831 used_prefixes
|= PREFIX_FWAIT
;
3834 USED_REX (REX_MODE64
);
3835 if (rex
& REX_MODE64
)
3837 else if (intel_syntax
&& (sizeflag
& DFLAG
))
3841 if (!(rex
& REX_MODE64
))
3842 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3847 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3856 if ((prefixes
& PREFIX_DATA
)
3857 || (rex
& REX_MODE64
)
3858 || (sizeflag
& SUFFIX_ALWAYS
))
3860 USED_REX (REX_MODE64
);
3861 if (rex
& REX_MODE64
)
3865 if (sizeflag
& DFLAG
)
3870 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3876 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3878 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3884 if (intel_syntax
&& !alt
)
3886 USED_REX (REX_MODE64
);
3887 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3889 if (rex
& REX_MODE64
)
3893 if (sizeflag
& DFLAG
)
3894 *obufp
++ = intel_syntax
? 'd' : 'l';
3898 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3902 USED_REX (REX_MODE64
);
3903 if (rex
& REX_MODE64
)
3905 else if (sizeflag
& DFLAG
)
3914 if (intel_syntax
&& !p
[1]
3915 && ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
)))
3917 if (!(rex
& REX_MODE64
))
3918 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3923 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3925 if (sizeflag
& SUFFIX_ALWAYS
)
3933 if (sizeflag
& SUFFIX_ALWAYS
)
3935 if (rex
& REX_MODE64
)
3939 if (sizeflag
& DFLAG
)
3943 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3948 if (prefixes
& PREFIX_DATA
)
3952 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3957 if (rex
& REX_MODE64
)
3959 USED_REX (REX_MODE64
);
3963 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3965 /* operand size flag for cwtl, cbtw */
3966 USED_REX (REX_MODE64
);
3967 if (rex
& REX_MODE64
)
3974 else if (sizeflag
& DFLAG
)
3978 if (!(rex
& REX_MODE64
))
3979 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3989 oappend (const char *s
)
3992 obufp
+= strlen (s
);
3998 if (prefixes
& PREFIX_CS
)
4000 used_prefixes
|= PREFIX_CS
;
4001 oappend ("%cs:" + intel_syntax
);
4003 if (prefixes
& PREFIX_DS
)
4005 used_prefixes
|= PREFIX_DS
;
4006 oappend ("%ds:" + intel_syntax
);
4008 if (prefixes
& PREFIX_SS
)
4010 used_prefixes
|= PREFIX_SS
;
4011 oappend ("%ss:" + intel_syntax
);
4013 if (prefixes
& PREFIX_ES
)
4015 used_prefixes
|= PREFIX_ES
;
4016 oappend ("%es:" + intel_syntax
);
4018 if (prefixes
& PREFIX_FS
)
4020 used_prefixes
|= PREFIX_FS
;
4021 oappend ("%fs:" + intel_syntax
);
4023 if (prefixes
& PREFIX_GS
)
4025 used_prefixes
|= PREFIX_GS
;
4026 oappend ("%gs:" + intel_syntax
);
4031 OP_indirE (int bytemode
, int sizeflag
)
4035 OP_E (bytemode
, sizeflag
);
4039 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4041 if (address_mode
== mode_64bit
)
4049 sprintf_vma (tmp
, disp
);
4050 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4051 strcpy (buf
+ 2, tmp
+ i
);
4055 bfd_signed_vma v
= disp
;
4062 /* Check for possible overflow on 0x8000000000000000. */
4065 strcpy (buf
, "9223372036854775808");
4079 tmp
[28 - i
] = (v
% 10) + '0';
4083 strcpy (buf
, tmp
+ 29 - i
);
4089 sprintf (buf
, "0x%x", (unsigned int) disp
);
4091 sprintf (buf
, "%d", (int) disp
);
4096 intel_operand_size (int bytemode
, int sizeflag
)
4101 oappend ("BYTE PTR ");
4105 oappend ("WORD PTR ");
4108 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4110 oappend ("QWORD PTR ");
4111 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4117 USED_REX (REX_MODE64
);
4118 if (rex
& REX_MODE64
)
4119 oappend ("QWORD PTR ");
4120 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4121 oappend ("DWORD PTR ");
4123 oappend ("WORD PTR ");
4124 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4127 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4129 oappend ("WORD PTR ");
4130 if (!(rex
& REX_MODE64
))
4131 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4134 oappend ("DWORD PTR ");
4137 oappend ("QWORD PTR ");
4140 if (address_mode
== mode_64bit
)
4141 oappend ("QWORD PTR ");
4143 oappend ("DWORD PTR ");
4146 if (sizeflag
& DFLAG
)
4147 oappend ("FWORD PTR ");
4149 oappend ("DWORD PTR ");
4150 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4153 oappend ("TBYTE PTR ");
4156 oappend ("XMMWORD PTR ");
4159 oappend ("OWORD PTR ");
4167 OP_E (int bytemode
, int sizeflag
)
4172 USED_REX (REX_EXTZ
);
4176 /* Skip mod/rm byte. */
4187 oappend (names8rex
[rm
+ add
]);
4189 oappend (names8
[rm
+ add
]);
4192 oappend (names16
[rm
+ add
]);
4195 oappend (names32
[rm
+ add
]);
4198 oappend (names64
[rm
+ add
]);
4201 if (address_mode
== mode_64bit
)
4202 oappend (names64
[rm
+ add
]);
4204 oappend (names32
[rm
+ add
]);
4207 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4209 oappend (names64
[rm
+ add
]);
4210 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4218 USED_REX (REX_MODE64
);
4219 if (rex
& REX_MODE64
)
4220 oappend (names64
[rm
+ add
]);
4221 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4222 oappend (names32
[rm
+ add
]);
4224 oappend (names16
[rm
+ add
]);
4225 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4230 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4238 intel_operand_size (bytemode
, sizeflag
);
4241 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
4256 FETCH_DATA (the_info
, codep
+ 1);
4257 index
= (*codep
>> 3) & 7;
4258 if (address_mode
== mode_64bit
|| index
!= 0x4)
4259 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4260 scale
= (*codep
>> 6) & 3;
4262 USED_REX (REX_EXTY
);
4272 if ((base
& 7) == 5)
4275 if (address_mode
== mode_64bit
&& !havesib
)
4281 FETCH_DATA (the_info
, codep
+ 1);
4283 if ((disp
& 0x80) != 0)
4292 if (mod
!= 0 || (base
& 7) == 5)
4294 print_operand_value (scratchbuf
, !riprel
, disp
);
4295 oappend (scratchbuf
);
4303 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4305 *obufp
++ = open_char
;
4306 if (intel_syntax
&& riprel
)
4310 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4311 ? names64
[base
] : names32
[base
]);
4316 if (!intel_syntax
|| havebase
)
4318 *obufp
++ = separator_char
;
4321 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4322 ? names64
[index
] : names32
[index
]);
4324 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4326 *obufp
++ = scale_char
;
4328 sprintf (scratchbuf
, "%d", 1 << scale
);
4329 oappend (scratchbuf
);
4332 if (intel_syntax
&& disp
)
4334 if ((bfd_signed_vma
) disp
> 0)
4343 disp
= - (bfd_signed_vma
) disp
;
4346 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4347 oappend (scratchbuf
);
4350 *obufp
++ = close_char
;
4353 else if (intel_syntax
)
4355 if (mod
!= 0 || (base
& 7) == 5)
4357 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4358 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4362 oappend (names_seg
[ds_reg
- es_reg
]);
4365 print_operand_value (scratchbuf
, 1, disp
);
4366 oappend (scratchbuf
);
4371 { /* 16 bit address mode */
4378 if ((disp
& 0x8000) != 0)
4383 FETCH_DATA (the_info
, codep
+ 1);
4385 if ((disp
& 0x80) != 0)
4390 if ((disp
& 0x8000) != 0)
4396 if (mod
!= 0 || rm
== 6)
4398 print_operand_value (scratchbuf
, 0, disp
);
4399 oappend (scratchbuf
);
4402 if (mod
!= 0 || rm
!= 6)
4404 *obufp
++ = open_char
;
4406 oappend (index16
[rm
]);
4407 if (intel_syntax
&& disp
)
4409 if ((bfd_signed_vma
) disp
> 0)
4418 disp
= - (bfd_signed_vma
) disp
;
4421 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4422 oappend (scratchbuf
);
4425 *obufp
++ = close_char
;
4428 else if (intel_syntax
)
4430 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4431 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4435 oappend (names_seg
[ds_reg
- es_reg
]);
4438 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
4439 oappend (scratchbuf
);
4445 OP_G (int bytemode
, int sizeflag
)
4448 USED_REX (REX_EXTX
);
4456 oappend (names8rex
[reg
+ add
]);
4458 oappend (names8
[reg
+ add
]);
4461 oappend (names16
[reg
+ add
]);
4464 oappend (names32
[reg
+ add
]);
4467 oappend (names64
[reg
+ add
]);
4472 USED_REX (REX_MODE64
);
4473 if (rex
& REX_MODE64
)
4474 oappend (names64
[reg
+ add
]);
4475 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4476 oappend (names32
[reg
+ add
]);
4478 oappend (names16
[reg
+ add
]);
4479 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4482 if (address_mode
== mode_64bit
)
4483 oappend (names64
[reg
+ add
]);
4485 oappend (names32
[reg
+ add
]);
4488 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4501 FETCH_DATA (the_info
, codep
+ 8);
4502 a
= *codep
++ & 0xff;
4503 a
|= (*codep
++ & 0xff) << 8;
4504 a
|= (*codep
++ & 0xff) << 16;
4505 a
|= (*codep
++ & 0xff) << 24;
4506 b
= *codep
++ & 0xff;
4507 b
|= (*codep
++ & 0xff) << 8;
4508 b
|= (*codep
++ & 0xff) << 16;
4509 b
|= (*codep
++ & 0xff) << 24;
4510 x
= a
+ ((bfd_vma
) b
<< 32);
4518 static bfd_signed_vma
4521 bfd_signed_vma x
= 0;
4523 FETCH_DATA (the_info
, codep
+ 4);
4524 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4525 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4526 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4527 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4531 static bfd_signed_vma
4534 bfd_signed_vma x
= 0;
4536 FETCH_DATA (the_info
, codep
+ 4);
4537 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4538 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4539 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4540 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4542 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4552 FETCH_DATA (the_info
, codep
+ 2);
4553 x
= *codep
++ & 0xff;
4554 x
|= (*codep
++ & 0xff) << 8;
4559 set_op (bfd_vma op
, int riprel
)
4561 op_index
[op_ad
] = op_ad
;
4562 if (address_mode
== mode_64bit
)
4564 op_address
[op_ad
] = op
;
4565 op_riprel
[op_ad
] = riprel
;
4569 /* Mask to get a 32-bit address. */
4570 op_address
[op_ad
] = op
& 0xffffffff;
4571 op_riprel
[op_ad
] = riprel
& 0xffffffff;
4576 OP_REG (int code
, int sizeflag
)
4580 USED_REX (REX_EXTZ
);
4586 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4587 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4588 s
= names16
[code
- ax_reg
+ add
];
4590 case es_reg
: case ss_reg
: case cs_reg
:
4591 case ds_reg
: case fs_reg
: case gs_reg
:
4592 s
= names_seg
[code
- es_reg
+ add
];
4594 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4595 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4598 s
= names8rex
[code
- al_reg
+ add
];
4600 s
= names8
[code
- al_reg
];
4602 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4603 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4604 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4606 s
= names64
[code
- rAX_reg
+ add
];
4609 code
+= eAX_reg
- rAX_reg
;
4611 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4612 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4613 USED_REX (REX_MODE64
);
4614 if (rex
& REX_MODE64
)
4615 s
= names64
[code
- eAX_reg
+ add
];
4616 else if (sizeflag
& DFLAG
)
4617 s
= names32
[code
- eAX_reg
+ add
];
4619 s
= names16
[code
- eAX_reg
+ add
];
4620 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4623 s
= INTERNAL_DISASSEMBLER_ERROR
;
4630 OP_IMREG (int code
, int sizeflag
)
4642 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4643 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4644 s
= names16
[code
- ax_reg
];
4646 case es_reg
: case ss_reg
: case cs_reg
:
4647 case ds_reg
: case fs_reg
: case gs_reg
:
4648 s
= names_seg
[code
- es_reg
];
4650 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4651 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4654 s
= names8rex
[code
- al_reg
];
4656 s
= names8
[code
- al_reg
];
4658 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4659 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4660 USED_REX (REX_MODE64
);
4661 if (rex
& REX_MODE64
)
4662 s
= names64
[code
- eAX_reg
];
4663 else if (sizeflag
& DFLAG
)
4664 s
= names32
[code
- eAX_reg
];
4666 s
= names16
[code
- eAX_reg
];
4667 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4670 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4674 if (!(rex
& REX_MODE64
))
4675 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4678 s
= INTERNAL_DISASSEMBLER_ERROR
;
4685 OP_I (int bytemode
, int sizeflag
)
4688 bfd_signed_vma mask
= -1;
4693 FETCH_DATA (the_info
, codep
+ 1);
4698 if (address_mode
== mode_64bit
)
4705 USED_REX (REX_MODE64
);
4706 if (rex
& REX_MODE64
)
4708 else if (sizeflag
& DFLAG
)
4718 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4729 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4734 scratchbuf
[0] = '$';
4735 print_operand_value (scratchbuf
+ 1, 1, op
);
4736 oappend (scratchbuf
+ intel_syntax
);
4737 scratchbuf
[0] = '\0';
4741 OP_I64 (int bytemode
, int sizeflag
)
4744 bfd_signed_vma mask
= -1;
4746 if (address_mode
!= mode_64bit
)
4748 OP_I (bytemode
, sizeflag
);
4755 FETCH_DATA (the_info
, codep
+ 1);
4760 USED_REX (REX_MODE64
);
4761 if (rex
& REX_MODE64
)
4763 else if (sizeflag
& DFLAG
)
4773 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4780 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4785 scratchbuf
[0] = '$';
4786 print_operand_value (scratchbuf
+ 1, 1, op
);
4787 oappend (scratchbuf
+ intel_syntax
);
4788 scratchbuf
[0] = '\0';
4792 OP_sI (int bytemode
, int sizeflag
)
4795 bfd_signed_vma mask
= -1;
4800 FETCH_DATA (the_info
, codep
+ 1);
4802 if ((op
& 0x80) != 0)
4807 USED_REX (REX_MODE64
);
4808 if (rex
& REX_MODE64
)
4810 else if (sizeflag
& DFLAG
)
4819 if ((op
& 0x8000) != 0)
4822 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4827 if ((op
& 0x8000) != 0)
4831 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4835 scratchbuf
[0] = '$';
4836 print_operand_value (scratchbuf
+ 1, 1, op
);
4837 oappend (scratchbuf
+ intel_syntax
);
4841 OP_J (int bytemode
, int sizeflag
)
4845 bfd_vma segment
= 0;
4850 FETCH_DATA (the_info
, codep
+ 1);
4852 if ((disp
& 0x80) != 0)
4856 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4861 if ((disp
& 0x8000) != 0)
4863 /* In 16bit mode, address is wrapped around at 64k within
4864 the same segment. Otherwise, a data16 prefix on a jump
4865 instruction means that the pc is masked to 16 bits after
4866 the displacement is added! */
4868 if ((prefixes
& PREFIX_DATA
) == 0)
4869 segment
= ((start_pc
+ codep
- start_codep
)
4870 & ~((bfd_vma
) 0xffff));
4872 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4875 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4878 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
4880 print_operand_value (scratchbuf
, 1, disp
);
4881 oappend (scratchbuf
);
4885 OP_SEG (int bytemode
, int sizeflag
)
4887 if (bytemode
== w_mode
)
4888 oappend (names_seg
[reg
]);
4890 OP_E (mod
== 3 ? bytemode
: w_mode
, sizeflag
);
4894 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4898 if (sizeflag
& DFLAG
)
4908 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4910 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4912 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4913 oappend (scratchbuf
);
4917 OP_OFF (int bytemode
, int sizeflag
)
4921 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4922 intel_operand_size (bytemode
, sizeflag
);
4925 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4932 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4933 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4935 oappend (names_seg
[ds_reg
- es_reg
]);
4939 print_operand_value (scratchbuf
, 1, off
);
4940 oappend (scratchbuf
);
4944 OP_OFF64 (int bytemode
, int sizeflag
)
4948 if (address_mode
!= mode_64bit
4949 || (prefixes
& PREFIX_ADDR
))
4951 OP_OFF (bytemode
, sizeflag
);
4955 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4956 intel_operand_size (bytemode
, sizeflag
);
4963 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4964 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4966 oappend (names_seg
[ds_reg
- es_reg
]);
4970 print_operand_value (scratchbuf
, 1, off
);
4971 oappend (scratchbuf
);
4975 ptr_reg (int code
, int sizeflag
)
4979 *obufp
++ = open_char
;
4980 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4981 if (address_mode
== mode_64bit
)
4983 if (!(sizeflag
& AFLAG
))
4984 s
= names32
[code
- eAX_reg
];
4986 s
= names64
[code
- eAX_reg
];
4988 else if (sizeflag
& AFLAG
)
4989 s
= names32
[code
- eAX_reg
];
4991 s
= names16
[code
- eAX_reg
];
4993 *obufp
++ = close_char
;
4998 OP_ESreg (int code
, int sizeflag
)
5004 case 0x6d: /* insw/insl */
5005 intel_operand_size (z_mode
, sizeflag
);
5007 case 0xa5: /* movsw/movsl/movsq */
5008 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5009 case 0xab: /* stosw/stosl */
5010 case 0xaf: /* scasw/scasl */
5011 intel_operand_size (v_mode
, sizeflag
);
5014 intel_operand_size (b_mode
, sizeflag
);
5017 oappend ("%es:" + intel_syntax
);
5018 ptr_reg (code
, sizeflag
);
5022 OP_DSreg (int code
, int sizeflag
)
5028 case 0x6f: /* outsw/outsl */
5029 intel_operand_size (z_mode
, sizeflag
);
5031 case 0xa5: /* movsw/movsl/movsq */
5032 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5033 case 0xad: /* lodsw/lodsl/lodsq */
5034 intel_operand_size (v_mode
, sizeflag
);
5037 intel_operand_size (b_mode
, sizeflag
);
5047 prefixes
|= PREFIX_DS
;
5049 ptr_reg (code
, sizeflag
);
5053 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5058 USED_REX (REX_EXTX
);
5061 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5063 used_prefixes
|= PREFIX_LOCK
;
5066 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
5067 oappend (scratchbuf
+ intel_syntax
);
5071 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5074 USED_REX (REX_EXTX
);
5078 sprintf (scratchbuf
, "db%d", reg
+ add
);
5080 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
5081 oappend (scratchbuf
);
5085 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5087 sprintf (scratchbuf
, "%%tr%d", reg
);
5088 oappend (scratchbuf
+ intel_syntax
);
5092 OP_R (int bytemode
, int sizeflag
)
5095 OP_E (bytemode
, sizeflag
);
5101 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5103 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5104 if (prefixes
& PREFIX_DATA
)
5107 USED_REX (REX_EXTX
);
5110 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5113 sprintf (scratchbuf
, "%%mm%d", reg
);
5114 oappend (scratchbuf
+ intel_syntax
);
5118 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5121 USED_REX (REX_EXTX
);
5124 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5125 oappend (scratchbuf
+ intel_syntax
);
5129 OP_EM (int bytemode
, int sizeflag
)
5133 if (intel_syntax
&& bytemode
== v_mode
)
5135 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5136 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5138 OP_E (bytemode
, sizeflag
);
5142 /* Skip mod/rm byte. */
5145 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5146 if (prefixes
& PREFIX_DATA
)
5150 USED_REX (REX_EXTZ
);
5153 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5156 sprintf (scratchbuf
, "%%mm%d", rm
);
5157 oappend (scratchbuf
+ intel_syntax
);
5160 /* cvt* are the only instructions in sse2 which have
5161 both SSE and MMX operands and also have 0x66 prefix
5162 in their opcode. 0x66 was originally used to differentiate
5163 between SSE and MMX instruction(operands). So we have to handle the
5164 cvt* separately using OP_EMC and OP_MXC */
5166 OP_EMC (int bytemode
, int sizeflag
)
5170 if (intel_syntax
&& bytemode
== v_mode
)
5172 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5173 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5175 OP_E (bytemode
, sizeflag
);
5179 /* Skip mod/rm byte. */
5182 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5183 sprintf (scratchbuf
, "%%mm%d", rm
);
5184 oappend (scratchbuf
+ intel_syntax
);
5188 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5190 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5191 sprintf (scratchbuf
, "%%mm%d", reg
);
5192 oappend (scratchbuf
+ intel_syntax
);
5196 OP_EX (int bytemode
, int sizeflag
)
5201 if (intel_syntax
&& bytemode
== v_mode
)
5203 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
5205 case 0: bytemode
= x_mode
; break;
5206 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
5207 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
5208 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
5209 default: bytemode
= 0; break;
5212 OP_E (bytemode
, sizeflag
);
5215 USED_REX (REX_EXTZ
);
5219 /* Skip mod/rm byte. */
5222 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5223 oappend (scratchbuf
+ intel_syntax
);
5227 OP_MS (int bytemode
, int sizeflag
)
5230 OP_EM (bytemode
, sizeflag
);
5236 OP_XS (int bytemode
, int sizeflag
)
5239 OP_EX (bytemode
, sizeflag
);
5245 OP_M (int bytemode
, int sizeflag
)
5248 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5251 OP_E (bytemode
, sizeflag
);
5255 OP_0f07 (int bytemode
, int sizeflag
)
5257 if (mod
!= 3 || rm
!= 0)
5260 OP_E (bytemode
, sizeflag
);
5264 OP_0fae (int bytemode
, int sizeflag
)
5269 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5271 if (reg
< 5 || rm
!= 0)
5273 BadOp (); /* bad sfence, mfence, or lfence */
5279 BadOp (); /* bad clflush */
5283 OP_E (bytemode
, sizeflag
);
5286 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5287 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5288 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5292 NOP_Fixup1 (int bytemode
, int sizeflag
)
5294 if (prefixes
== PREFIX_REPZ
)
5295 strcpy (obuf
, "pause");
5296 else if (prefixes
== PREFIX_DATA
5297 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5298 OP_REG (bytemode
, sizeflag
);
5300 strcpy (obuf
, "nop");
5304 NOP_Fixup2 (int bytemode
, int sizeflag
)
5306 if (prefixes
== PREFIX_DATA
5307 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5308 OP_IMREG (bytemode
, sizeflag
);
5311 static const char *const Suffix3DNow
[] = {
5312 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5313 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5314 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5315 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5316 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5317 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5318 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5319 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5320 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5321 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5322 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5323 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5324 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5325 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5326 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5327 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5328 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5329 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5330 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5331 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5332 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5333 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5334 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5335 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5336 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5337 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5338 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5339 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5340 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5341 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5342 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5343 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5344 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5345 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5346 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5347 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5348 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5349 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5350 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5351 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5352 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5353 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5354 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5355 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5356 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5357 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5358 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5359 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5360 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5361 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5362 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5363 /* CC */ NULL
, NULL
, NULL
, NULL
,
5364 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5365 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5366 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5367 /* DC */ NULL
, NULL
, NULL
, NULL
,
5368 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5369 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5370 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5371 /* EC */ NULL
, NULL
, NULL
, NULL
,
5372 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5373 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5374 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5375 /* FC */ NULL
, NULL
, NULL
, NULL
,
5379 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5381 const char *mnemonic
;
5383 FETCH_DATA (the_info
, codep
+ 1);
5384 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5385 place where an 8-bit immediate would normally go. ie. the last
5386 byte of the instruction. */
5387 obufp
= obuf
+ strlen (obuf
);
5388 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5393 /* Since a variable sized modrm/sib chunk is between the start
5394 of the opcode (0x0f0f) and the opcode suffix, we need to do
5395 all the modrm processing first, and don't know until now that
5396 we have a bad opcode. This necessitates some cleaning up. */
5397 op_out
[0][0] = '\0';
5398 op_out
[1][0] = '\0';
5403 static const char *simd_cmp_op
[] = {
5415 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5417 unsigned int cmp_type
;
5419 FETCH_DATA (the_info
, codep
+ 1);
5420 obufp
= obuf
+ strlen (obuf
);
5421 cmp_type
= *codep
++ & 0xff;
5424 char suffix1
= 'p', suffix2
= 's';
5425 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5426 if (prefixes
& PREFIX_REPZ
)
5430 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5431 if (prefixes
& PREFIX_DATA
)
5435 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5436 if (prefixes
& PREFIX_REPNZ
)
5437 suffix1
= 's', suffix2
= 'd';
5440 sprintf (scratchbuf
, "cmp%s%c%c",
5441 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5442 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5443 oappend (scratchbuf
);
5447 /* We have a bad extension byte. Clean up. */
5448 op_out
[0][0] = '\0';
5449 op_out
[1][0] = '\0';
5455 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
5457 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5458 forms of these instructions. */
5461 char *p
= obuf
+ strlen (obuf
);
5464 *(p
- 1) = *(p
- 2);
5465 *(p
- 2) = *(p
- 3);
5466 *(p
- 3) = extrachar
;
5471 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5473 if (mod
== 3 && reg
== 1 && rm
<= 1)
5475 /* Override "sidt". */
5476 size_t olen
= strlen (obuf
);
5477 char *p
= obuf
+ olen
- 4;
5478 const char **names
= (address_mode
== mode_64bit
5479 ? names64
: names32
);
5481 /* We might have a suffix when disassembling with -Msuffix. */
5485 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5487 && (prefixes
& PREFIX_ADDR
)
5490 && CONST_STRNEQ (p
- 7, "addr")
5491 && (CONST_STRNEQ (p
- 3, "16")
5492 || CONST_STRNEQ (p
- 3, "32")))
5497 /* mwait %eax,%ecx */
5498 strcpy (p
, "mwait");
5500 strcpy (op_out
[0], names
[0]);
5504 /* monitor %eax,%ecx,%edx" */
5505 strcpy (p
, "monitor");
5508 const char **op1_names
;
5509 if (!(prefixes
& PREFIX_ADDR
))
5510 op1_names
= (address_mode
== mode_16bit
5514 op1_names
= (address_mode
!= mode_32bit
5515 ? names32
: names16
);
5516 used_prefixes
|= PREFIX_ADDR
;
5518 strcpy (op_out
[0], op1_names
[0]);
5519 strcpy (op_out
[2], names
[2]);
5524 strcpy (op_out
[1], names
[1]);
5535 SVME_Fixup (int bytemode
, int sizeflag
)
5567 OP_M (bytemode
, sizeflag
);
5570 /* Override "lidt". */
5571 p
= obuf
+ strlen (obuf
) - 4;
5572 /* We might have a suffix. */
5576 if (!(prefixes
& PREFIX_ADDR
))
5581 used_prefixes
|= PREFIX_ADDR
;
5585 strcpy (op_out
[1], names32
[1]);
5591 *obufp
++ = open_char
;
5592 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
5596 strcpy (obufp
, alt
);
5597 obufp
+= strlen (alt
);
5598 *obufp
++ = close_char
;
5605 INVLPG_Fixup (int bytemode
, int sizeflag
)
5618 OP_M (bytemode
, sizeflag
);
5621 /* Override "invlpg". */
5622 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
5629 /* Throw away prefixes and 1st. opcode byte. */
5630 codep
= insn_codep
+ 1;
5635 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5637 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
5639 /* Override "sgdt". */
5640 char *p
= obuf
+ strlen (obuf
) - 4;
5642 /* We might have a suffix when disassembling with -Msuffix. */
5649 strcpy (p
, "vmcall");
5652 strcpy (p
, "vmlaunch");
5655 strcpy (p
, "vmresume");
5658 strcpy (p
, "vmxoff");
5669 OP_VMX (int bytemode
, int sizeflag
)
5671 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
5672 if (prefixes
& PREFIX_DATA
)
5673 strcpy (obuf
, "vmclear");
5674 else if (prefixes
& PREFIX_REPZ
)
5675 strcpy (obuf
, "vmxon");
5677 strcpy (obuf
, "vmptrld");
5678 OP_E (bytemode
, sizeflag
);
5682 REP_Fixup (int bytemode
, int sizeflag
)
5684 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5688 if (prefixes
& PREFIX_REPZ
)
5689 switch (*insn_codep
)
5691 case 0x6e: /* outsb */
5692 case 0x6f: /* outsw/outsl */
5693 case 0xa4: /* movsb */
5694 case 0xa5: /* movsw/movsl/movsq */
5700 case 0xaa: /* stosb */
5701 case 0xab: /* stosw/stosl/stosq */
5702 case 0xac: /* lodsb */
5703 case 0xad: /* lodsw/lodsl/lodsq */
5704 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5709 case 0x6c: /* insb */
5710 case 0x6d: /* insl/insw */
5726 olen
= strlen (obuf
);
5727 p
= obuf
+ olen
- ilen
- 1 - 4;
5728 /* Handle "repz [addr16|addr32]". */
5729 if ((prefixes
& PREFIX_ADDR
))
5732 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
5740 OP_IMREG (bytemode
, sizeflag
);
5743 OP_ESreg (bytemode
, sizeflag
);
5746 OP_DSreg (bytemode
, sizeflag
);
5755 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
5757 USED_REX (REX_MODE64
);
5758 if (rex
& REX_MODE64
)
5760 /* Change cmpxchg8b to cmpxchg16b. */
5761 char *p
= obuf
+ strlen (obuf
) - 2;
5765 OP_M (bytemode
, sizeflag
);