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. */
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
48 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma
, disassemble_info
*);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *, int, bfd_vma
);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma
get64 (void);
63 static bfd_signed_vma
get32 (void);
64 static bfd_signed_vma
get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma
, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_EMC (int,int);
89 static void OP_MXC (int,int);
90 static void OP_MS (int, int);
91 static void OP_XS (int, int);
92 static void OP_M (int, int);
93 static void OP_VMX (int, int);
94 static void OP_0fae (int, int);
95 static void OP_0f07 (int, int);
96 static void NOP_Fixup1 (int, int);
97 static void NOP_Fixup2 (int, int);
98 static void OP_3DNowSuffix (int, int);
99 static void OP_SIMD_Suffix (int, int);
100 static void SIMD_Fixup (int, int);
101 static void PNI_Fixup (int, int);
102 static void SVME_Fixup (int, int);
103 static void INVLPG_Fixup (int, int);
104 static void BadOp (void);
105 static void SEG_Fixup (int, int);
106 static void VMX_Fixup (int, int);
107 static void REP_Fixup (int, int);
110 /* Points to first byte not fetched. */
111 bfd_byte
*max_fetched
;
112 bfd_byte the_buffer
[MAXLEN
];
118 /* The opcode for the fwait instruction, which we treat as a prefix
120 #define FWAIT_OPCODE (0x9b)
129 enum address_mode address_mode
;
131 /* Flags for the prefixes for the current instruction. See below. */
134 /* REX prefix the current instruction. See below. */
136 /* Bits of REX we've already used. */
142 /* Mark parts used in the REX prefix. When we are testing for
143 empty prefix (for 8bit register REX extension), just mask it
144 out. Otherwise test for REX bit is excuse for existence of REX
145 only in case value is nonzero. */
146 #define USED_REX(value) \
149 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
154 /* Flags for prefixes which we somehow handled when printing the
155 current instruction. */
156 static int used_prefixes
;
158 /* Flags stored in PREFIXES. */
159 #define PREFIX_REPZ 1
160 #define PREFIX_REPNZ 2
161 #define PREFIX_LOCK 4
163 #define PREFIX_SS 0x10
164 #define PREFIX_DS 0x20
165 #define PREFIX_ES 0x40
166 #define PREFIX_FS 0x80
167 #define PREFIX_GS 0x100
168 #define PREFIX_DATA 0x200
169 #define PREFIX_ADDR 0x400
170 #define PREFIX_FWAIT 0x800
172 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
173 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
175 #define FETCH_DATA(info, addr) \
176 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
177 ? 1 : fetch_data ((info), (addr)))
180 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
183 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
184 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
186 if (addr
<= priv
->the_buffer
+ MAXLEN
)
187 status
= (*info
->read_memory_func
) (start
,
189 addr
- priv
->max_fetched
,
195 /* If we did manage to read at least one byte, then
196 print_insn_i386 will do something sensible. Otherwise, print
197 an error. We do that here because this is where we know
199 if (priv
->max_fetched
== priv
->the_buffer
)
200 (*info
->memory_error_func
) (status
, start
, info
);
201 longjmp (priv
->bailout
, 1);
204 priv
->max_fetched
= addr
;
210 #define Eb OP_E, b_mode
211 #define Ev OP_E, v_mode
212 #define Ed OP_E, d_mode
213 #define Eq OP_E, q_mode
214 #define Edq OP_E, dq_mode
215 #define Edqw OP_E, dqw_mode
216 #define indirEv OP_indirE, stack_v_mode
217 #define indirEp OP_indirE, f_mode
218 #define stackEv OP_E, stack_v_mode
219 #define Em OP_E, m_mode
220 #define Ew OP_E, w_mode
221 #define Ma OP_E, v_mode
222 #define M OP_M, 0 /* lea, lgdt, etc. */
223 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
224 #define Gb OP_G, b_mode
225 #define Gv OP_G, v_mode
226 #define Gd OP_G, d_mode
227 #define Gdq OP_G, dq_mode
228 #define Gm OP_G, m_mode
229 #define Gw OP_G, w_mode
230 #define Rd OP_Rd, d_mode
231 #define Rm OP_Rd, m_mode
232 #define Ib OP_I, b_mode
233 #define sIb OP_sI, b_mode /* sign extened byte */
234 #define Iv OP_I, v_mode
235 #define Iq OP_I, q_mode
236 #define Iv64 OP_I64, v_mode
237 #define Iw OP_I, w_mode
238 #define I1 OP_I, const_1_mode
239 #define Jb OP_J, b_mode
240 #define Jv OP_J, v_mode
241 #define Cm OP_C, m_mode
242 #define Dm OP_D, m_mode
243 #define Td OP_T, d_mode
244 #define Sv SEG_Fixup, v_mode
246 #define RMeAX OP_REG, eAX_reg
247 #define RMeBX OP_REG, eBX_reg
248 #define RMeCX OP_REG, eCX_reg
249 #define RMeDX OP_REG, eDX_reg
250 #define RMeSP OP_REG, eSP_reg
251 #define RMeBP OP_REG, eBP_reg
252 #define RMeSI OP_REG, eSI_reg
253 #define RMeDI OP_REG, eDI_reg
254 #define RMrAX OP_REG, rAX_reg
255 #define RMrBX OP_REG, rBX_reg
256 #define RMrCX OP_REG, rCX_reg
257 #define RMrDX OP_REG, rDX_reg
258 #define RMrSP OP_REG, rSP_reg
259 #define RMrBP OP_REG, rBP_reg
260 #define RMrSI OP_REG, rSI_reg
261 #define RMrDI OP_REG, rDI_reg
262 #define RMAL OP_REG, al_reg
263 #define RMAL OP_REG, al_reg
264 #define RMCL OP_REG, cl_reg
265 #define RMDL OP_REG, dl_reg
266 #define RMBL OP_REG, bl_reg
267 #define RMAH OP_REG, ah_reg
268 #define RMCH OP_REG, ch_reg
269 #define RMDH OP_REG, dh_reg
270 #define RMBH OP_REG, bh_reg
271 #define RMAX OP_REG, ax_reg
272 #define RMDX OP_REG, dx_reg
274 #define eAX OP_IMREG, eAX_reg
275 #define eBX OP_IMREG, eBX_reg
276 #define eCX OP_IMREG, eCX_reg
277 #define eDX OP_IMREG, eDX_reg
278 #define eSP OP_IMREG, eSP_reg
279 #define eBP OP_IMREG, eBP_reg
280 #define eSI OP_IMREG, eSI_reg
281 #define eDI OP_IMREG, eDI_reg
282 #define AL OP_IMREG, al_reg
283 #define CL OP_IMREG, cl_reg
284 #define DL OP_IMREG, dl_reg
285 #define BL OP_IMREG, bl_reg
286 #define AH OP_IMREG, ah_reg
287 #define CH OP_IMREG, ch_reg
288 #define DH OP_IMREG, dh_reg
289 #define BH OP_IMREG, bh_reg
290 #define AX OP_IMREG, ax_reg
291 #define DX OP_IMREG, dx_reg
292 #define zAX OP_IMREG, z_mode_ax_reg
293 #define indirDX OP_IMREG, indir_dx_reg
295 #define Sw OP_SEG, w_mode
297 #define Ob OP_OFF64, b_mode
298 #define Ov OP_OFF64, v_mode
299 #define Xb OP_DSreg, eSI_reg
300 #define Xv OP_DSreg, eSI_reg
301 #define Xz OP_DSreg, eSI_reg
302 #define Yb OP_ESreg, eDI_reg
303 #define Yv OP_ESreg, eDI_reg
304 #define DSBX OP_DSreg, eBX_reg
306 #define es OP_REG, es_reg
307 #define ss OP_REG, ss_reg
308 #define cs OP_REG, cs_reg
309 #define ds OP_REG, ds_reg
310 #define fs OP_REG, fs_reg
311 #define gs OP_REG, gs_reg
315 #define EM OP_EM, v_mode
316 #define EX OP_EX, v_mode
317 #define MS OP_MS, v_mode
318 #define XS OP_XS, v_mode
319 #define EMC OP_EMC, v_mode
320 #define MXC OP_MXC, 0
321 #define VM OP_VMX, q_mode
322 #define OPSUF OP_3DNowSuffix, 0
323 #define OPSIMD OP_SIMD_Suffix, 0
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr REP_Fixup, eSI_reg
327 #define Xvr REP_Fixup, eSI_reg
328 #define Ybr REP_Fixup, eDI_reg
329 #define Yvr REP_Fixup, eDI_reg
330 #define Yzr REP_Fixup, eDI_reg
331 #define indirDXr REP_Fixup, indir_dx_reg
332 #define ALr REP_Fixup, al_reg
333 #define eAXr REP_Fixup, eAX_reg
335 #define cond_jump_flag NULL, cond_jump_mode
336 #define loop_jcxz_flag NULL, loop_jcxz_mode
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
403 #define z_mode_ax_reg 149
404 #define indir_dx_reg 150
408 #define USE_PREFIX_USER_TABLE 3
409 #define X86_64_SPECIAL 4
410 #define IS_3BYTE_OPCODE 5
412 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
414 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
415 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
416 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
417 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
418 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
419 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
420 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
421 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
422 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
423 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
424 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
425 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
426 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
427 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
428 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
429 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
430 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
431 #define GRP11_C6 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
432 #define GRP11_C7 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
433 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
434 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
435 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
436 #define GRP15 NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
437 #define GRP16 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
438 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
439 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
440 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
442 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
443 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
444 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
445 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
446 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
447 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
448 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
449 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
450 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
451 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
452 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
453 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
454 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
455 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
456 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
457 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
458 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
459 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
460 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
461 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
462 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
463 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
464 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
465 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
466 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
467 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
468 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
469 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
470 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
471 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
472 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
473 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
474 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
475 #define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
476 #define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
477 #define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
478 #define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
479 #define PREGRP37 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 37, NULL, 0, NULL, 0
482 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
484 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
485 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
487 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
501 /* Upper case letters in the instruction names here are macros.
502 'A' => print 'b' if no register operands or suffix_always is true
503 'B' => print 'b' if suffix_always is true
504 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
506 'E' => print 'e' if 32-bit form of jcxz
507 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
508 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
509 'H' => print ",pt" or ",pn" branch hint
510 'I' => honor following macro letter even in Intel mode (implemented only
511 . for some of the macro letters)
513 'L' => print 'l' if suffix_always is true
514 'N' => print 'n' if instruction has no wait "prefix"
515 'O' => print 'd' or 'o' (or 'q' in Intel mode)
516 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
517 . or suffix_always is true. print 'q' if rex prefix is present.
518 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
520 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
521 'S' => print 'w', 'l' or 'q' if suffix_always is true
522 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
523 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
524 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
525 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
526 'X' => print 's', 'd' depending on data16 prefix (for XMM)
527 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
528 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
530 Many of the above letters print nothing in Intel mode. See "putop"
533 Braces '{' and '}', and vertical bars '|', indicate alternative
534 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
535 modes. In cases where there are only two alternatives, the X86_64
536 instruction is reserved, and "(bad)" is printed.
539 static const struct dis386 dis386
[] = {
541 { "addB", Eb
, Gb
, XX
, XX
},
542 { "addS", Ev
, Gv
, XX
, XX
},
543 { "addB", Gb
, Eb
, XX
, XX
},
544 { "addS", Gv
, Ev
, XX
, XX
},
545 { "addB", AL
, Ib
, XX
, XX
},
546 { "addS", eAX
, Iv
, XX
, XX
},
547 { "push{T|}", es
, XX
, XX
, XX
},
548 { "pop{T|}", es
, XX
, XX
, XX
},
550 { "orB", Eb
, Gb
, XX
, XX
},
551 { "orS", Ev
, Gv
, XX
, XX
},
552 { "orB", Gb
, Eb
, XX
, XX
},
553 { "orS", Gv
, Ev
, XX
, XX
},
554 { "orB", AL
, Ib
, XX
, XX
},
555 { "orS", eAX
, Iv
, XX
, XX
},
556 { "push{T|}", cs
, XX
, XX
, XX
},
557 { "(bad)", XX
, XX
, XX
, XX
}, /* 0x0f extended opcode escape */
559 { "adcB", Eb
, Gb
, XX
, XX
},
560 { "adcS", Ev
, Gv
, XX
, XX
},
561 { "adcB", Gb
, Eb
, XX
, XX
},
562 { "adcS", Gv
, Ev
, XX
, XX
},
563 { "adcB", AL
, Ib
, XX
, XX
},
564 { "adcS", eAX
, Iv
, XX
, XX
},
565 { "push{T|}", ss
, XX
, XX
, XX
},
566 { "pop{T|}", ss
, XX
, XX
, XX
},
568 { "sbbB", Eb
, Gb
, XX
, XX
},
569 { "sbbS", Ev
, Gv
, XX
, XX
},
570 { "sbbB", Gb
, Eb
, XX
, XX
},
571 { "sbbS", Gv
, Ev
, XX
, XX
},
572 { "sbbB", AL
, Ib
, XX
, XX
},
573 { "sbbS", eAX
, Iv
, XX
, XX
},
574 { "push{T|}", ds
, XX
, XX
, XX
},
575 { "pop{T|}", ds
, XX
, XX
, XX
},
577 { "andB", Eb
, Gb
, XX
, XX
},
578 { "andS", Ev
, Gv
, XX
, XX
},
579 { "andB", Gb
, Eb
, XX
, XX
},
580 { "andS", Gv
, Ev
, XX
, XX
},
581 { "andB", AL
, Ib
, XX
, XX
},
582 { "andS", eAX
, Iv
, XX
, XX
},
583 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG ES prefix */
584 { "daa{|}", XX
, XX
, XX
, XX
},
586 { "subB", Eb
, Gb
, XX
, XX
},
587 { "subS", Ev
, Gv
, XX
, XX
},
588 { "subB", Gb
, Eb
, XX
, XX
},
589 { "subS", Gv
, Ev
, XX
, XX
},
590 { "subB", AL
, Ib
, XX
, XX
},
591 { "subS", eAX
, Iv
, XX
, XX
},
592 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG CS prefix */
593 { "das{|}", XX
, XX
, XX
, XX
},
595 { "xorB", Eb
, Gb
, XX
, XX
},
596 { "xorS", Ev
, Gv
, XX
, XX
},
597 { "xorB", Gb
, Eb
, XX
, XX
},
598 { "xorS", Gv
, Ev
, XX
, XX
},
599 { "xorB", AL
, Ib
, XX
, XX
},
600 { "xorS", eAX
, Iv
, XX
, XX
},
601 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG SS prefix */
602 { "aaa{|}", XX
, XX
, XX
, XX
},
604 { "cmpB", Eb
, Gb
, XX
, XX
},
605 { "cmpS", Ev
, Gv
, XX
, XX
},
606 { "cmpB", Gb
, Eb
, XX
, XX
},
607 { "cmpS", Gv
, Ev
, XX
, XX
},
608 { "cmpB", AL
, Ib
, XX
, XX
},
609 { "cmpS", eAX
, Iv
, XX
, XX
},
610 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG DS prefix */
611 { "aas{|}", XX
, XX
, XX
, XX
},
613 { "inc{S|}", RMeAX
, XX
, XX
, XX
},
614 { "inc{S|}", RMeCX
, XX
, XX
, XX
},
615 { "inc{S|}", RMeDX
, XX
, XX
, XX
},
616 { "inc{S|}", RMeBX
, XX
, XX
, XX
},
617 { "inc{S|}", RMeSP
, XX
, XX
, XX
},
618 { "inc{S|}", RMeBP
, XX
, XX
, XX
},
619 { "inc{S|}", RMeSI
, XX
, XX
, XX
},
620 { "inc{S|}", RMeDI
, XX
, XX
, XX
},
622 { "dec{S|}", RMeAX
, XX
, XX
, XX
},
623 { "dec{S|}", RMeCX
, XX
, XX
, XX
},
624 { "dec{S|}", RMeDX
, XX
, XX
, XX
},
625 { "dec{S|}", RMeBX
, XX
, XX
, XX
},
626 { "dec{S|}", RMeSP
, XX
, XX
, XX
},
627 { "dec{S|}", RMeBP
, XX
, XX
, XX
},
628 { "dec{S|}", RMeSI
, XX
, XX
, XX
},
629 { "dec{S|}", RMeDI
, XX
, XX
, XX
},
631 { "pushV", RMrAX
, XX
, XX
, XX
},
632 { "pushV", RMrCX
, XX
, XX
, XX
},
633 { "pushV", RMrDX
, XX
, XX
, XX
},
634 { "pushV", RMrBX
, XX
, XX
, XX
},
635 { "pushV", RMrSP
, XX
, XX
, XX
},
636 { "pushV", RMrBP
, XX
, XX
, XX
},
637 { "pushV", RMrSI
, XX
, XX
, XX
},
638 { "pushV", RMrDI
, XX
, XX
, XX
},
640 { "popV", RMrAX
, XX
, XX
, XX
},
641 { "popV", RMrCX
, XX
, XX
, XX
},
642 { "popV", RMrDX
, XX
, XX
, XX
},
643 { "popV", RMrBX
, XX
, XX
, XX
},
644 { "popV", RMrSP
, XX
, XX
, XX
},
645 { "popV", RMrBP
, XX
, XX
, XX
},
646 { "popV", RMrSI
, XX
, XX
, XX
},
647 { "popV", RMrDI
, XX
, XX
, XX
},
649 { "pusha{P|}", XX
, XX
, XX
, XX
},
650 { "popa{P|}", XX
, XX
, XX
, XX
},
651 { "bound{S|}", Gv
, Ma
, XX
, XX
},
653 { "(bad)", XX
, XX
, XX
, XX
}, /* seg fs */
654 { "(bad)", XX
, XX
, XX
, XX
}, /* seg gs */
655 { "(bad)", XX
, XX
, XX
, XX
}, /* op size prefix */
656 { "(bad)", XX
, XX
, XX
, XX
}, /* adr size prefix */
658 { "pushT", Iq
, XX
, XX
, XX
},
659 { "imulS", Gv
, Ev
, Iv
, XX
},
660 { "pushT", sIb
, XX
, XX
, XX
},
661 { "imulS", Gv
, Ev
, sIb
, XX
},
662 { "ins{b||b|}", Ybr
, indirDX
, XX
, XX
},
663 { "ins{R||G|}", Yzr
, indirDX
, XX
, XX
},
664 { "outs{b||b|}", indirDXr
, Xb
, XX
, XX
},
665 { "outs{R||G|}", indirDXr
, Xz
, XX
, XX
},
667 { "joH", Jb
, XX
, cond_jump_flag
, XX
},
668 { "jnoH", Jb
, XX
, cond_jump_flag
, XX
},
669 { "jbH", Jb
, XX
, cond_jump_flag
, XX
},
670 { "jaeH", Jb
, XX
, cond_jump_flag
, XX
},
671 { "jeH", Jb
, XX
, cond_jump_flag
, XX
},
672 { "jneH", Jb
, XX
, cond_jump_flag
, XX
},
673 { "jbeH", Jb
, XX
, cond_jump_flag
, XX
},
674 { "jaH", Jb
, XX
, cond_jump_flag
, XX
},
676 { "jsH", Jb
, XX
, cond_jump_flag
, XX
},
677 { "jnsH", Jb
, XX
, cond_jump_flag
, XX
},
678 { "jpH", Jb
, XX
, cond_jump_flag
, XX
},
679 { "jnpH", Jb
, XX
, cond_jump_flag
, XX
},
680 { "jlH", Jb
, XX
, cond_jump_flag
, XX
},
681 { "jgeH", Jb
, XX
, cond_jump_flag
, XX
},
682 { "jleH", Jb
, XX
, cond_jump_flag
, XX
},
683 { "jgH", Jb
, XX
, cond_jump_flag
, XX
},
687 { "(bad)", XX
, XX
, XX
, XX
},
689 { "testB", Eb
, Gb
, XX
, XX
},
690 { "testS", Ev
, Gv
, XX
, XX
},
691 { "xchgB", Eb
, Gb
, XX
, XX
},
692 { "xchgS", Ev
, Gv
, XX
, XX
},
694 { "movB", Eb
, Gb
, XX
, XX
},
695 { "movS", Ev
, Gv
, XX
, XX
},
696 { "movB", Gb
, Eb
, XX
, XX
},
697 { "movS", Gv
, Ev
, XX
, XX
},
698 { "movQ", Sv
, Sw
, XX
, XX
},
699 { "leaS", Gv
, M
, XX
, XX
},
700 { "movQ", Sw
, Sv
, XX
, XX
},
701 { "popU", stackEv
, XX
, XX
, XX
},
703 { "xchgS", NOP_Fixup1
, eAX_reg
, NOP_Fixup2
, eAX_reg
, XX
, XX
},
704 { "xchgS", RMeCX
, eAX
, XX
, XX
},
705 { "xchgS", RMeDX
, eAX
, XX
, XX
},
706 { "xchgS", RMeBX
, eAX
, XX
, XX
},
707 { "xchgS", RMeSP
, eAX
, XX
, XX
},
708 { "xchgS", RMeBP
, eAX
, XX
, XX
},
709 { "xchgS", RMeSI
, eAX
, XX
, XX
},
710 { "xchgS", RMeDI
, eAX
, XX
, XX
},
712 { "cW{t||t|}R", XX
, XX
, XX
, XX
},
713 { "cR{t||t|}O", XX
, XX
, XX
, XX
},
714 { "Jcall{T|}", Ap
, XX
, XX
, XX
},
715 { "(bad)", XX
, XX
, XX
, XX
}, /* fwait */
716 { "pushfT", XX
, XX
, XX
, XX
},
717 { "popfT", XX
, XX
, XX
, XX
},
718 { "sahf{|}", XX
, XX
, XX
, XX
},
719 { "lahf{|}", XX
, XX
, XX
, XX
},
721 { "movB", AL
, Ob
, XX
, XX
},
722 { "movS", eAX
, Ov
, XX
, XX
},
723 { "movB", Ob
, AL
, XX
, XX
},
724 { "movS", Ov
, eAX
, XX
, XX
},
725 { "movs{b||b|}", Ybr
, Xb
, XX
, XX
},
726 { "movs{R||R|}", Yvr
, Xv
, XX
, XX
},
727 { "cmps{b||b|}", Xb
, Yb
, XX
, XX
},
728 { "cmps{R||R|}", Xv
, Yv
, XX
, XX
},
730 { "testB", AL
, Ib
, XX
, XX
},
731 { "testS", eAX
, Iv
, XX
, XX
},
732 { "stosB", Ybr
, AL
, XX
, XX
},
733 { "stosS", Yvr
, eAX
, XX
, XX
},
734 { "lodsB", ALr
, Xb
, XX
, XX
},
735 { "lodsS", eAXr
, Xv
, XX
, XX
},
736 { "scasB", AL
, Yb
, XX
, XX
},
737 { "scasS", eAX
, Yv
, XX
, XX
},
739 { "movB", RMAL
, Ib
, XX
, XX
},
740 { "movB", RMCL
, Ib
, XX
, XX
},
741 { "movB", RMDL
, Ib
, XX
, XX
},
742 { "movB", RMBL
, Ib
, XX
, XX
},
743 { "movB", RMAH
, Ib
, XX
, XX
},
744 { "movB", RMCH
, Ib
, XX
, XX
},
745 { "movB", RMDH
, Ib
, XX
, XX
},
746 { "movB", RMBH
, Ib
, XX
, XX
},
748 { "movS", RMeAX
, Iv64
, XX
, XX
},
749 { "movS", RMeCX
, Iv64
, XX
, XX
},
750 { "movS", RMeDX
, Iv64
, XX
, XX
},
751 { "movS", RMeBX
, Iv64
, XX
, XX
},
752 { "movS", RMeSP
, Iv64
, XX
, XX
},
753 { "movS", RMeBP
, Iv64
, XX
, XX
},
754 { "movS", RMeSI
, Iv64
, XX
, XX
},
755 { "movS", RMeDI
, Iv64
, XX
, XX
},
759 { "retT", Iw
, XX
, XX
, XX
},
760 { "retT", XX
, XX
, XX
, XX
},
761 { "les{S|}", Gv
, Mp
, XX
, XX
},
762 { "ldsS", Gv
, Mp
, XX
, XX
},
766 { "enterT", Iw
, Ib
, XX
, XX
},
767 { "leaveT", XX
, XX
, XX
, XX
},
768 { "lretP", Iw
, XX
, XX
, XX
},
769 { "lretP", XX
, XX
, XX
, XX
},
770 { "int3", XX
, XX
, XX
, XX
},
771 { "int", Ib
, XX
, XX
, XX
},
772 { "into{|}", XX
, XX
, XX
, XX
},
773 { "iretP", XX
, XX
, XX
, XX
},
779 { "aam{|}", sIb
, XX
, XX
, XX
},
780 { "aad{|}", sIb
, XX
, XX
, XX
},
781 { "(bad)", XX
, XX
, XX
, XX
},
782 { "xlat", DSBX
, XX
, XX
, XX
},
793 { "loopneFH", Jb
, XX
, loop_jcxz_flag
, XX
},
794 { "loopeFH", Jb
, XX
, loop_jcxz_flag
, XX
},
795 { "loopFH", Jb
, XX
, loop_jcxz_flag
, XX
},
796 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
, XX
},
797 { "inB", AL
, Ib
, XX
, XX
},
798 { "inG", zAX
, Ib
, XX
, XX
},
799 { "outB", Ib
, AL
, XX
, XX
},
800 { "outG", Ib
, zAX
, XX
, XX
},
802 { "callT", Jv
, XX
, XX
, XX
},
803 { "jmpT", Jv
, XX
, XX
, XX
},
804 { "Jjmp{T|}", Ap
, XX
, XX
, XX
},
805 { "jmp", Jb
, XX
, XX
, XX
},
806 { "inB", AL
, indirDX
, XX
, XX
},
807 { "inG", zAX
, indirDX
, XX
, XX
},
808 { "outB", indirDX
, AL
, XX
, XX
},
809 { "outG", indirDX
, zAX
, XX
, XX
},
811 { "(bad)", XX
, XX
, XX
, XX
}, /* lock prefix */
812 { "icebp", XX
, XX
, XX
, XX
},
813 { "(bad)", XX
, XX
, XX
, XX
}, /* repne */
814 { "(bad)", XX
, XX
, XX
, XX
}, /* repz */
815 { "hlt", XX
, XX
, XX
, XX
},
816 { "cmc", XX
, XX
, XX
, XX
},
820 { "clc", XX
, XX
, XX
, XX
},
821 { "stc", XX
, XX
, XX
, XX
},
822 { "cli", XX
, XX
, XX
, XX
},
823 { "sti", XX
, XX
, XX
, XX
},
824 { "cld", XX
, XX
, XX
, XX
},
825 { "std", XX
, XX
, XX
, XX
},
830 static const struct dis386 dis386_twobyte
[] = {
834 { "larS", Gv
, Ew
, XX
, XX
},
835 { "lslS", Gv
, Ew
, XX
, XX
},
836 { "(bad)", XX
, XX
, XX
, XX
},
837 { "syscall", XX
, XX
, XX
, XX
},
838 { "clts", XX
, XX
, XX
, XX
},
839 { "sysretP", XX
, XX
, XX
, XX
},
841 { "invd", XX
, XX
, XX
, XX
},
842 { "wbinvd", XX
, XX
, XX
, XX
},
843 { "(bad)", XX
, XX
, XX
, XX
},
844 { "ud2a", XX
, XX
, XX
, XX
},
845 { "(bad)", XX
, XX
, XX
, XX
},
847 { "femms", XX
, XX
, XX
, XX
},
848 { "", MX
, EM
, OPSUF
, XX
}, /* See OP_3DNowSuffix. */
853 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h', XX
},
854 { "unpcklpX", XM
, EX
, XX
, XX
},
855 { "unpckhpX", XM
, EX
, XX
, XX
},
857 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l', XX
},
860 { "(bad)", XX
, XX
, XX
, XX
},
861 { "(bad)", XX
, XX
, XX
, XX
},
862 { "(bad)", XX
, XX
, XX
, XX
},
863 { "(bad)", XX
, XX
, XX
, XX
},
864 { "(bad)", XX
, XX
, XX
, XX
},
865 { "(bad)", XX
, XX
, XX
, XX
},
866 { "nopQ", Ev
, XX
, XX
, XX
},
868 { "movZ", Rm
, Cm
, XX
, XX
},
869 { "movZ", Rm
, Dm
, XX
, XX
},
870 { "movZ", Cm
, Rm
, XX
, XX
},
871 { "movZ", Dm
, Rm
, XX
, XX
},
872 { "movL", Rd
, Td
, XX
, XX
},
873 { "(bad)", XX
, XX
, XX
, XX
},
874 { "movL", Td
, Rd
, XX
, XX
},
875 { "(bad)", XX
, XX
, XX
, XX
},
877 { "movapX", XM
, EX
, XX
, XX
},
878 { "movapX", EX
, XM
, XX
, XX
},
883 { "ucomisX", XM
,EX
, XX
, XX
},
884 { "comisX", XM
,EX
, XX
, XX
},
886 { "wrmsr", XX
, XX
, XX
, XX
},
887 { "rdtsc", XX
, XX
, XX
, XX
},
888 { "rdmsr", XX
, XX
, XX
, XX
},
889 { "rdpmc", XX
, XX
, XX
, XX
},
890 { "sysenter", XX
, XX
, XX
, XX
},
891 { "sysexit", XX
, XX
, XX
, XX
},
892 { "(bad)", XX
, XX
, XX
, XX
},
893 { "(bad)", XX
, XX
, XX
, XX
},
896 { "(bad)", XX
, XX
, XX
, XX
},
898 { "(bad)", XX
, XX
, XX
, XX
},
899 { "(bad)", XX
, XX
, XX
, XX
},
900 { "(bad)", XX
, XX
, XX
, XX
},
901 { "(bad)", XX
, XX
, XX
, XX
},
902 { "(bad)", XX
, XX
, XX
, XX
},
904 { "cmovo", Gv
, Ev
, XX
, XX
},
905 { "cmovno", Gv
, Ev
, XX
, XX
},
906 { "cmovb", Gv
, Ev
, XX
, XX
},
907 { "cmovae", Gv
, Ev
, XX
, XX
},
908 { "cmove", Gv
, Ev
, XX
, XX
},
909 { "cmovne", Gv
, Ev
, XX
, XX
},
910 { "cmovbe", Gv
, Ev
, XX
, XX
},
911 { "cmova", Gv
, Ev
, XX
, XX
},
913 { "cmovs", Gv
, Ev
, XX
, XX
},
914 { "cmovns", Gv
, Ev
, XX
, XX
},
915 { "cmovp", Gv
, Ev
, XX
, XX
},
916 { "cmovnp", Gv
, Ev
, XX
, XX
},
917 { "cmovl", Gv
, Ev
, XX
, XX
},
918 { "cmovge", Gv
, Ev
, XX
, XX
},
919 { "cmovle", Gv
, Ev
, XX
, XX
},
920 { "cmovg", Gv
, Ev
, XX
, XX
},
922 { "movmskpX", Gdq
, XS
, XX
, XX
},
926 { "andpX", XM
, EX
, XX
, XX
},
927 { "andnpX", XM
, EX
, XX
, XX
},
928 { "orpX", XM
, EX
, XX
, XX
},
929 { "xorpX", XM
, EX
, XX
, XX
},
940 { "punpcklbw", MX
, EM
, XX
, XX
},
941 { "punpcklwd", MX
, EM
, XX
, XX
},
942 { "punpckldq", MX
, EM
, XX
, XX
},
943 { "packsswb", MX
, EM
, XX
, XX
},
944 { "pcmpgtb", MX
, EM
, XX
, XX
},
945 { "pcmpgtw", MX
, EM
, XX
, XX
},
946 { "pcmpgtd", MX
, EM
, XX
, XX
},
947 { "packuswb", MX
, EM
, XX
, XX
},
949 { "punpckhbw", MX
, EM
, XX
, XX
},
950 { "punpckhwd", MX
, EM
, XX
, XX
},
951 { "punpckhdq", MX
, EM
, XX
, XX
},
952 { "packssdw", MX
, EM
, XX
, XX
},
955 { "movd", MX
, Edq
, XX
, XX
},
962 { "pcmpeqb", MX
, EM
, XX
, XX
},
963 { "pcmpeqw", MX
, EM
, XX
, XX
},
964 { "pcmpeqd", MX
, EM
, XX
, XX
},
965 { "emms", XX
, XX
, XX
, XX
},
969 { "(bad)", XX
, XX
, XX
, XX
},
970 { "(bad)", XX
, XX
, XX
, XX
},
976 { "joH", Jv
, XX
, cond_jump_flag
, XX
},
977 { "jnoH", Jv
, XX
, cond_jump_flag
, XX
},
978 { "jbH", Jv
, XX
, cond_jump_flag
, XX
},
979 { "jaeH", Jv
, XX
, cond_jump_flag
, XX
},
980 { "jeH", Jv
, XX
, cond_jump_flag
, XX
},
981 { "jneH", Jv
, XX
, cond_jump_flag
, XX
},
982 { "jbeH", Jv
, XX
, cond_jump_flag
, XX
},
983 { "jaH", Jv
, XX
, cond_jump_flag
, XX
},
985 { "jsH", Jv
, XX
, cond_jump_flag
, XX
},
986 { "jnsH", Jv
, XX
, cond_jump_flag
, XX
},
987 { "jpH", Jv
, XX
, cond_jump_flag
, XX
},
988 { "jnpH", Jv
, XX
, cond_jump_flag
, XX
},
989 { "jlH", Jv
, XX
, cond_jump_flag
, XX
},
990 { "jgeH", Jv
, XX
, cond_jump_flag
, XX
},
991 { "jleH", Jv
, XX
, cond_jump_flag
, XX
},
992 { "jgH", Jv
, XX
, cond_jump_flag
, XX
},
994 { "seto", Eb
, XX
, XX
, XX
},
995 { "setno", Eb
, XX
, XX
, XX
},
996 { "setb", Eb
, XX
, XX
, XX
},
997 { "setae", Eb
, XX
, XX
, XX
},
998 { "sete", Eb
, XX
, XX
, XX
},
999 { "setne", Eb
, XX
, XX
, XX
},
1000 { "setbe", Eb
, XX
, XX
, XX
},
1001 { "seta", Eb
, XX
, XX
, XX
},
1003 { "sets", Eb
, XX
, XX
, XX
},
1004 { "setns", Eb
, XX
, XX
, XX
},
1005 { "setp", Eb
, XX
, XX
, XX
},
1006 { "setnp", Eb
, XX
, XX
, XX
},
1007 { "setl", Eb
, XX
, XX
, XX
},
1008 { "setge", Eb
, XX
, XX
, XX
},
1009 { "setle", Eb
, XX
, XX
, XX
},
1010 { "setg", Eb
, XX
, XX
, XX
},
1012 { "pushT", fs
, XX
, XX
, XX
},
1013 { "popT", fs
, XX
, XX
, XX
},
1014 { "cpuid", XX
, XX
, XX
, XX
},
1015 { "btS", Ev
, Gv
, XX
, XX
},
1016 { "shldS", Ev
, Gv
, Ib
, XX
},
1017 { "shldS", Ev
, Gv
, CL
, XX
},
1021 { "pushT", gs
, XX
, XX
, XX
},
1022 { "popT", gs
, XX
, XX
, XX
},
1023 { "rsm", XX
, XX
, XX
, XX
},
1024 { "btsS", Ev
, Gv
, XX
, XX
},
1025 { "shrdS", Ev
, Gv
, Ib
, XX
},
1026 { "shrdS", Ev
, Gv
, CL
, XX
},
1028 { "imulS", Gv
, Ev
, XX
, XX
},
1030 { "cmpxchgB", Eb
, Gb
, XX
, XX
},
1031 { "cmpxchgS", Ev
, Gv
, XX
, XX
},
1032 { "lssS", Gv
, Mp
, XX
, XX
},
1033 { "btrS", Ev
, Gv
, XX
, XX
},
1034 { "lfsS", Gv
, Mp
, XX
, XX
},
1035 { "lgsS", Gv
, Mp
, XX
, XX
},
1036 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
, XX
},
1037 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
, XX
}, /* yes, there really is movzww ! */
1040 { "ud2b", XX
, XX
, XX
, XX
},
1042 { "btcS", Ev
, Gv
, XX
, XX
},
1043 { "bsfS", Gv
, Ev
, XX
, XX
},
1045 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
, XX
},
1046 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
, XX
}, /* yes, there really is movsww ! */
1048 { "xaddB", Eb
, Gb
, XX
, XX
},
1049 { "xaddS", Ev
, Gv
, XX
, XX
},
1051 { "movntiS", Ev
, Gv
, XX
, XX
},
1052 { "pinsrw", MX
, Edqw
, Ib
, XX
},
1053 { "pextrw", Gdq
, MS
, Ib
, XX
},
1054 { "shufpX", XM
, EX
, Ib
, XX
},
1057 { "bswap", RMeAX
, XX
, XX
, XX
},
1058 { "bswap", RMeCX
, XX
, XX
, XX
},
1059 { "bswap", RMeDX
, XX
, XX
, XX
},
1060 { "bswap", RMeBX
, XX
, XX
, XX
},
1061 { "bswap", RMeSP
, XX
, XX
, XX
},
1062 { "bswap", RMeBP
, XX
, XX
, XX
},
1063 { "bswap", RMeSI
, XX
, XX
, XX
},
1064 { "bswap", RMeDI
, XX
, XX
, XX
},
1067 { "psrlw", MX
, EM
, XX
, XX
},
1068 { "psrld", MX
, EM
, XX
, XX
},
1069 { "psrlq", MX
, EM
, XX
, XX
},
1070 { "paddq", MX
, EM
, XX
, XX
},
1071 { "pmullw", MX
, EM
, XX
, XX
},
1073 { "pmovmskb", Gdq
, MS
, XX
, XX
},
1075 { "psubusb", MX
, EM
, XX
, XX
},
1076 { "psubusw", MX
, EM
, XX
, XX
},
1077 { "pminub", MX
, EM
, XX
, XX
},
1078 { "pand", MX
, EM
, XX
, XX
},
1079 { "paddusb", MX
, EM
, XX
, XX
},
1080 { "paddusw", MX
, EM
, XX
, XX
},
1081 { "pmaxub", MX
, EM
, XX
, XX
},
1082 { "pandn", MX
, EM
, XX
, XX
},
1084 { "pavgb", MX
, EM
, XX
, XX
},
1085 { "psraw", MX
, EM
, XX
, XX
},
1086 { "psrad", MX
, EM
, XX
, XX
},
1087 { "pavgw", MX
, EM
, XX
, XX
},
1088 { "pmulhuw", MX
, EM
, XX
, XX
},
1089 { "pmulhw", MX
, EM
, XX
, XX
},
1093 { "psubsb", MX
, EM
, XX
, XX
},
1094 { "psubsw", MX
, EM
, XX
, XX
},
1095 { "pminsw", MX
, EM
, XX
, XX
},
1096 { "por", MX
, EM
, XX
, XX
},
1097 { "paddsb", MX
, EM
, XX
, XX
},
1098 { "paddsw", MX
, EM
, XX
, XX
},
1099 { "pmaxsw", MX
, EM
, XX
, XX
},
1100 { "pxor", MX
, EM
, XX
, XX
},
1103 { "psllw", MX
, EM
, XX
, XX
},
1104 { "pslld", MX
, EM
, XX
, XX
},
1105 { "psllq", MX
, EM
, XX
, XX
},
1106 { "pmuludq", MX
, EM
, XX
, XX
},
1107 { "pmaddwd", MX
, EM
, XX
, XX
},
1108 { "psadbw", MX
, EM
, XX
, XX
},
1111 { "psubb", MX
, EM
, XX
, XX
},
1112 { "psubw", MX
, EM
, XX
, XX
},
1113 { "psubd", MX
, EM
, XX
, XX
},
1114 { "psubq", MX
, EM
, XX
, XX
},
1115 { "paddb", MX
, EM
, XX
, XX
},
1116 { "paddw", MX
, EM
, XX
, XX
},
1117 { "paddd", MX
, EM
, XX
, XX
},
1118 { "(bad)", XX
, XX
, XX
, XX
}
1121 static const unsigned char onebyte_has_modrm
[256] = {
1122 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1123 /* ------------------------------- */
1124 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1125 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1126 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1127 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1128 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1129 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1130 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1131 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1132 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1133 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1134 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1135 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1136 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1137 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1138 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1139 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1140 /* ------------------------------- */
1141 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1144 static const unsigned char twobyte_has_modrm
[256] = {
1145 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1146 /* ------------------------------- */
1147 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1148 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1149 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1150 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1151 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1152 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1153 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1154 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1155 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1156 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1157 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1158 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1159 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1160 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1161 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1162 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1163 /* ------------------------------- */
1164 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1167 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1168 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1169 /* ------------------------------- */
1170 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1171 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1172 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1173 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1174 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1175 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1176 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1177 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1178 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1179 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1180 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1181 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1182 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1183 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1184 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1185 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1186 /* ------------------------------- */
1187 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1190 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1192 /* ------------------------------- */
1193 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1194 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1195 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1196 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1197 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1198 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1199 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1200 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1201 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1202 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1203 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1204 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1205 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1206 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1207 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1208 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1209 /* ------------------------------- */
1210 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1213 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1214 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1215 /* ------------------------------- */
1216 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1217 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1218 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1219 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1220 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1221 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1222 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1223 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1224 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1225 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1226 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1227 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1228 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1229 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1230 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1231 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1232 /* ------------------------------- */
1233 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1236 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1237 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1238 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1239 /* ------------------------------- */
1240 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1241 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1242 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1243 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1244 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1245 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1246 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1247 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1248 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1249 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1250 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1251 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1252 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1253 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1254 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1255 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1256 /* ------------------------------- */
1257 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1260 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1261 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1262 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1263 /* ------------------------------- */
1264 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1265 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1266 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1267 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1268 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1269 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1270 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1271 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1272 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1273 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1274 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1275 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1276 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1277 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1278 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1279 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1280 /* ------------------------------- */
1281 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1284 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1285 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1286 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1287 /* ------------------------------- */
1288 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1289 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1290 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1291 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1292 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1293 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1294 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1295 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1296 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1297 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1298 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1299 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1300 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1301 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1302 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1303 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1304 /* ------------------------------- */
1305 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1308 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1309 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1310 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1311 /* ------------------------------- */
1312 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1313 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1314 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1315 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1316 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1317 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1318 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1319 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1320 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1321 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1322 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1323 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1324 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1325 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1326 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1327 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1328 /* ------------------------------- */
1329 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1332 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1333 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1334 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1335 /* ------------------------------- */
1336 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1337 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1338 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1339 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1340 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1341 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1342 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1343 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1344 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1345 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1346 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1347 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1348 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1349 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1350 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1351 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1352 /* ------------------------------- */
1353 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1356 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1357 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1358 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1359 /* ------------------------------- */
1360 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1361 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1362 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1363 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1364 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1365 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1366 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1367 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1368 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1369 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1370 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1371 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1372 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1373 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1374 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1375 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1376 /* ------------------------------- */
1377 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1380 static char obuf
[100];
1382 static char scratchbuf
[100];
1383 static unsigned char *start_codep
;
1384 static unsigned char *insn_codep
;
1385 static unsigned char *codep
;
1386 static disassemble_info
*the_info
;
1390 static unsigned char need_modrm
;
1392 /* If we are accessing mod/rm/reg without need_modrm set, then the
1393 values are stale. Hitting this abort likely indicates that you
1394 need to update onebyte_has_modrm or twobyte_has_modrm. */
1395 #define MODRM_CHECK if (!need_modrm) abort ()
1397 static const char **names64
;
1398 static const char **names32
;
1399 static const char **names16
;
1400 static const char **names8
;
1401 static const char **names8rex
;
1402 static const char **names_seg
;
1403 static const char **index16
;
1405 static const char *intel_names64
[] = {
1406 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1407 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1409 static const char *intel_names32
[] = {
1410 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1411 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1413 static const char *intel_names16
[] = {
1414 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1415 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1417 static const char *intel_names8
[] = {
1418 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1420 static const char *intel_names8rex
[] = {
1421 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1422 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1424 static const char *intel_names_seg
[] = {
1425 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1427 static const char *intel_index16
[] = {
1428 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1431 static const char *att_names64
[] = {
1432 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1433 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1435 static const char *att_names32
[] = {
1436 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1437 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1439 static const char *att_names16
[] = {
1440 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1441 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1443 static const char *att_names8
[] = {
1444 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1446 static const char *att_names8rex
[] = {
1447 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1448 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1450 static const char *att_names_seg
[] = {
1451 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1453 static const char *att_index16
[] = {
1454 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1457 static const struct dis386 grps
[][8] = {
1460 { "addA", Eb
, Ib
, XX
, XX
},
1461 { "orA", Eb
, Ib
, XX
, XX
},
1462 { "adcA", Eb
, Ib
, XX
, XX
},
1463 { "sbbA", Eb
, Ib
, XX
, XX
},
1464 { "andA", Eb
, Ib
, XX
, XX
},
1465 { "subA", Eb
, Ib
, XX
, XX
},
1466 { "xorA", Eb
, Ib
, XX
, XX
},
1467 { "cmpA", Eb
, Ib
, XX
, XX
}
1471 { "addQ", Ev
, Iv
, XX
, XX
},
1472 { "orQ", Ev
, Iv
, XX
, XX
},
1473 { "adcQ", Ev
, Iv
, XX
, XX
},
1474 { "sbbQ", Ev
, Iv
, XX
, XX
},
1475 { "andQ", Ev
, Iv
, XX
, XX
},
1476 { "subQ", Ev
, Iv
, XX
, XX
},
1477 { "xorQ", Ev
, Iv
, XX
, XX
},
1478 { "cmpQ", Ev
, Iv
, XX
, XX
}
1482 { "addQ", Ev
, sIb
, XX
, XX
},
1483 { "orQ", Ev
, sIb
, XX
, XX
},
1484 { "adcQ", Ev
, sIb
, XX
, XX
},
1485 { "sbbQ", Ev
, sIb
, XX
, XX
},
1486 { "andQ", Ev
, sIb
, XX
, XX
},
1487 { "subQ", Ev
, sIb
, XX
, XX
},
1488 { "xorQ", Ev
, sIb
, XX
, XX
},
1489 { "cmpQ", Ev
, sIb
, XX
, XX
}
1493 { "rolA", Eb
, Ib
, XX
, XX
},
1494 { "rorA", Eb
, Ib
, XX
, XX
},
1495 { "rclA", Eb
, Ib
, XX
, XX
},
1496 { "rcrA", Eb
, Ib
, XX
, XX
},
1497 { "shlA", Eb
, Ib
, XX
, XX
},
1498 { "shrA", Eb
, Ib
, XX
, XX
},
1499 { "(bad)", XX
, XX
, XX
, XX
},
1500 { "sarA", Eb
, Ib
, XX
, XX
},
1504 { "rolQ", Ev
, Ib
, XX
, XX
},
1505 { "rorQ", Ev
, Ib
, XX
, XX
},
1506 { "rclQ", Ev
, Ib
, XX
, XX
},
1507 { "rcrQ", Ev
, Ib
, XX
, XX
},
1508 { "shlQ", Ev
, Ib
, XX
, XX
},
1509 { "shrQ", Ev
, Ib
, XX
, XX
},
1510 { "(bad)", XX
, XX
, XX
, XX
},
1511 { "sarQ", Ev
, Ib
, XX
, XX
},
1515 { "rolA", Eb
, I1
, XX
, XX
},
1516 { "rorA", Eb
, I1
, XX
, XX
},
1517 { "rclA", Eb
, I1
, XX
, XX
},
1518 { "rcrA", Eb
, I1
, XX
, XX
},
1519 { "shlA", Eb
, I1
, XX
, XX
},
1520 { "shrA", Eb
, I1
, XX
, XX
},
1521 { "(bad)", XX
, XX
, XX
, XX
},
1522 { "sarA", Eb
, I1
, XX
, XX
},
1526 { "rolQ", Ev
, I1
, XX
, XX
},
1527 { "rorQ", Ev
, I1
, XX
, XX
},
1528 { "rclQ", Ev
, I1
, XX
, XX
},
1529 { "rcrQ", Ev
, I1
, XX
, XX
},
1530 { "shlQ", Ev
, I1
, XX
, XX
},
1531 { "shrQ", Ev
, I1
, XX
, XX
},
1532 { "(bad)", XX
, XX
, XX
, XX
},
1533 { "sarQ", Ev
, I1
, XX
, XX
},
1537 { "rolA", Eb
, CL
, XX
, XX
},
1538 { "rorA", Eb
, CL
, XX
, XX
},
1539 { "rclA", Eb
, CL
, XX
, XX
},
1540 { "rcrA", Eb
, CL
, XX
, XX
},
1541 { "shlA", Eb
, CL
, XX
, XX
},
1542 { "shrA", Eb
, CL
, XX
, XX
},
1543 { "(bad)", XX
, XX
, XX
, XX
},
1544 { "sarA", Eb
, CL
, XX
, XX
},
1548 { "rolQ", Ev
, CL
, XX
, XX
},
1549 { "rorQ", Ev
, CL
, XX
, XX
},
1550 { "rclQ", Ev
, CL
, XX
, XX
},
1551 { "rcrQ", Ev
, CL
, XX
, XX
},
1552 { "shlQ", Ev
, CL
, XX
, XX
},
1553 { "shrQ", Ev
, CL
, XX
, XX
},
1554 { "(bad)", XX
, XX
, XX
, XX
},
1555 { "sarQ", Ev
, CL
, XX
, XX
}
1559 { "testA", Eb
, Ib
, XX
, XX
},
1560 { "(bad)", Eb
, XX
, XX
, XX
},
1561 { "notA", Eb
, XX
, XX
, XX
},
1562 { "negA", Eb
, XX
, XX
, XX
},
1563 { "mulA", Eb
, XX
, XX
, XX
}, /* Don't print the implicit %al register, */
1564 { "imulA", Eb
, XX
, XX
, XX
}, /* to distinguish these opcodes from other */
1565 { "divA", Eb
, XX
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1566 { "idivA", Eb
, XX
, XX
, XX
} /* and idiv for consistency. */
1570 { "testQ", Ev
, Iv
, XX
, XX
},
1571 { "(bad)", XX
, XX
, XX
, XX
},
1572 { "notQ", Ev
, XX
, XX
, XX
},
1573 { "negQ", Ev
, XX
, XX
, XX
},
1574 { "mulQ", Ev
, XX
, XX
, XX
}, /* Don't print the implicit register. */
1575 { "imulQ", Ev
, XX
, XX
, XX
},
1576 { "divQ", Ev
, XX
, XX
, XX
},
1577 { "idivQ", Ev
, XX
, XX
, XX
},
1581 { "incA", Eb
, XX
, XX
, XX
},
1582 { "decA", Eb
, XX
, XX
, XX
},
1583 { "(bad)", XX
, XX
, XX
, XX
},
1584 { "(bad)", XX
, XX
, XX
, XX
},
1585 { "(bad)", XX
, XX
, XX
, XX
},
1586 { "(bad)", XX
, XX
, XX
, XX
},
1587 { "(bad)", XX
, XX
, XX
, XX
},
1588 { "(bad)", XX
, XX
, XX
, XX
},
1592 { "incQ", Ev
, XX
, XX
, XX
},
1593 { "decQ", Ev
, XX
, XX
, XX
},
1594 { "callT", indirEv
, XX
, XX
, XX
},
1595 { "JcallT", indirEp
, XX
, XX
, XX
},
1596 { "jmpT", indirEv
, XX
, XX
, XX
},
1597 { "JjmpT", indirEp
, XX
, XX
, XX
},
1598 { "pushU", stackEv
, XX
, XX
, XX
},
1599 { "(bad)", XX
, XX
, XX
, XX
},
1603 { "sldt", Ev
, XX
, XX
, XX
},
1604 { "str", Ev
, XX
, XX
, XX
},
1605 { "lldt", Ew
, XX
, XX
, XX
},
1606 { "ltr", Ew
, XX
, XX
, XX
},
1607 { "verr", Ew
, XX
, XX
, XX
},
1608 { "verw", Ew
, XX
, XX
, XX
},
1609 { "(bad)", XX
, XX
, XX
, XX
},
1610 { "(bad)", XX
, XX
, XX
, XX
}
1614 { "sgdt{Q|IQ||}", VMX_Fixup
, 0, XX
, XX
, XX
},
1615 { "sidt{Q|IQ||}", PNI_Fixup
, 0, XX
, XX
, XX
},
1616 { "lgdt{Q|Q||}", M
, XX
, XX
, XX
},
1617 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
, XX
},
1618 { "smsw", Ev
, XX
, XX
, XX
},
1619 { "(bad)", XX
, XX
, XX
, XX
},
1620 { "lmsw", Ew
, XX
, XX
, XX
},
1621 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
, XX
},
1625 { "(bad)", XX
, XX
, XX
, XX
},
1626 { "(bad)", XX
, XX
, XX
, XX
},
1627 { "(bad)", XX
, XX
, XX
, XX
},
1628 { "(bad)", XX
, XX
, XX
, XX
},
1629 { "btQ", Ev
, Ib
, XX
, XX
},
1630 { "btsQ", Ev
, Ib
, XX
, XX
},
1631 { "btrQ", Ev
, Ib
, XX
, XX
},
1632 { "btcQ", Ev
, Ib
, XX
, XX
},
1636 { "(bad)", XX
, XX
, XX
, XX
},
1637 { "cmpxchg8b", Eq
, XX
, XX
, XX
},
1638 { "(bad)", XX
, XX
, XX
, XX
},
1639 { "(bad)", XX
, XX
, XX
, XX
},
1640 { "(bad)", XX
, XX
, XX
, XX
},
1641 { "(bad)", XX
, XX
, XX
, XX
},
1642 { "", VM
, XX
, XX
, XX
}, /* See OP_VMX. */
1643 { "vmptrst", Eq
, XX
, XX
, XX
},
1647 { "movA", Eb
, Ib
, XX
, XX
},
1648 { "(bad)", XX
, XX
, XX
, XX
},
1649 { "(bad)", XX
, XX
, XX
, XX
},
1650 { "(bad)", XX
, XX
, XX
, XX
},
1651 { "(bad)", XX
, XX
, XX
, XX
},
1652 { "(bad)", XX
, XX
, XX
, XX
},
1653 { "(bad)", XX
, XX
, XX
, XX
},
1654 { "(bad)", XX
, XX
, XX
, XX
},
1658 { "movQ", Ev
, Iv
, XX
, XX
},
1659 { "(bad)", XX
, XX
, XX
, XX
},
1660 { "(bad)", XX
, XX
, XX
, XX
},
1661 { "(bad)", XX
, XX
, XX
, XX
},
1662 { "(bad)", XX
, XX
, XX
, XX
},
1663 { "(bad)", XX
, XX
, XX
, XX
},
1664 { "(bad)", XX
, XX
, XX
, XX
},
1665 { "(bad)", XX
, XX
, XX
, XX
},
1669 { "(bad)", XX
, XX
, XX
, XX
},
1670 { "(bad)", XX
, XX
, XX
, XX
},
1671 { "psrlw", MS
, Ib
, XX
, XX
},
1672 { "(bad)", XX
, XX
, XX
, XX
},
1673 { "psraw", MS
, Ib
, XX
, XX
},
1674 { "(bad)", XX
, XX
, XX
, XX
},
1675 { "psllw", MS
, Ib
, XX
, XX
},
1676 { "(bad)", XX
, XX
, XX
, XX
},
1680 { "(bad)", XX
, XX
, XX
, XX
},
1681 { "(bad)", XX
, XX
, XX
, XX
},
1682 { "psrld", MS
, Ib
, XX
, XX
},
1683 { "(bad)", XX
, XX
, XX
, XX
},
1684 { "psrad", MS
, Ib
, XX
, XX
},
1685 { "(bad)", XX
, XX
, XX
, XX
},
1686 { "pslld", MS
, Ib
, XX
, XX
},
1687 { "(bad)", XX
, XX
, XX
, XX
},
1691 { "(bad)", XX
, XX
, XX
, XX
},
1692 { "(bad)", XX
, XX
, XX
, XX
},
1693 { "psrlq", MS
, Ib
, XX
, XX
},
1694 { "psrldq", MS
, Ib
, XX
, XX
},
1695 { "(bad)", XX
, XX
, XX
, XX
},
1696 { "(bad)", XX
, XX
, XX
, XX
},
1697 { "psllq", MS
, Ib
, XX
, XX
},
1698 { "pslldq", MS
, Ib
, XX
, XX
},
1702 { "fxsave", Ev
, XX
, XX
, XX
},
1703 { "fxrstor", Ev
, XX
, XX
, XX
},
1704 { "ldmxcsr", Ev
, XX
, XX
, XX
},
1705 { "stmxcsr", Ev
, XX
, XX
, XX
},
1706 { "(bad)", XX
, XX
, XX
, XX
},
1707 { "lfence", OP_0fae
, 0, XX
, XX
, XX
},
1708 { "mfence", OP_0fae
, 0, XX
, XX
, XX
},
1709 { "clflush", OP_0fae
, 0, XX
, XX
, XX
},
1713 { "prefetchnta", Ev
, XX
, XX
, XX
},
1714 { "prefetcht0", Ev
, XX
, XX
, XX
},
1715 { "prefetcht1", Ev
, XX
, XX
, XX
},
1716 { "prefetcht2", Ev
, XX
, XX
, XX
},
1717 { "(bad)", XX
, XX
, XX
, XX
},
1718 { "(bad)", XX
, XX
, XX
, XX
},
1719 { "(bad)", XX
, XX
, XX
, XX
},
1720 { "(bad)", XX
, XX
, XX
, XX
},
1724 { "prefetch", Eb
, XX
, XX
, XX
},
1725 { "prefetchw", Eb
, XX
, XX
, XX
},
1726 { "(bad)", XX
, XX
, XX
, XX
},
1727 { "(bad)", XX
, XX
, XX
, XX
},
1728 { "(bad)", XX
, XX
, XX
, XX
},
1729 { "(bad)", XX
, XX
, XX
, XX
},
1730 { "(bad)", XX
, XX
, XX
, XX
},
1731 { "(bad)", XX
, XX
, XX
, XX
},
1735 { "xstore-rng", OP_0f07
, 0, XX
, XX
, XX
},
1736 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
, XX
},
1737 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
, XX
},
1738 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
, XX
},
1739 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
, XX
},
1740 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
, XX
},
1741 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1742 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1746 { "montmul", OP_0f07
, 0, XX
, XX
, XX
},
1747 { "xsha1", OP_0f07
, 0, XX
, XX
, XX
},
1748 { "xsha256", OP_0f07
, 0, XX
, XX
, XX
},
1749 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1750 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1751 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1752 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1753 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1757 static const struct dis386 prefix_user_table
[][4] = {
1760 { "addps", XM
, EX
, XX
, XX
},
1761 { "addss", XM
, EX
, XX
, XX
},
1762 { "addpd", XM
, EX
, XX
, XX
},
1763 { "addsd", XM
, EX
, XX
, XX
},
1767 { "", XM
, EX
, OPSIMD
, XX
}, /* See OP_SIMD_SUFFIX. */
1768 { "", XM
, EX
, OPSIMD
, XX
},
1769 { "", XM
, EX
, OPSIMD
, XX
},
1770 { "", XM
, EX
, OPSIMD
, XX
},
1774 { "cvtpi2ps", XM
, EMC
, XX
, XX
},
1775 { "cvtsi2ssY", XM
, Ev
, XX
, XX
},
1776 { "cvtpi2pd", XM
, EMC
, XX
, XX
},
1777 { "cvtsi2sdY", XM
, Ev
, XX
, XX
},
1781 { "cvtps2pi", MXC
, EX
, XX
, XX
},
1782 { "cvtss2siY", Gv
, EX
, XX
, XX
},
1783 { "cvtpd2pi", MXC
, EX
, XX
, XX
},
1784 { "cvtsd2siY", Gv
, EX
, XX
, XX
},
1788 { "cvttps2pi", MXC
, EX
, XX
, XX
},
1789 { "cvttss2siY", Gv
, EX
, XX
, XX
},
1790 { "cvttpd2pi", MXC
, EX
, XX
, XX
},
1791 { "cvttsd2siY", Gv
, EX
, XX
, XX
},
1795 { "divps", XM
, EX
, XX
, XX
},
1796 { "divss", XM
, EX
, XX
, XX
},
1797 { "divpd", XM
, EX
, XX
, XX
},
1798 { "divsd", XM
, EX
, XX
, XX
},
1802 { "maxps", XM
, EX
, XX
, XX
},
1803 { "maxss", XM
, EX
, XX
, XX
},
1804 { "maxpd", XM
, EX
, XX
, XX
},
1805 { "maxsd", XM
, EX
, XX
, XX
},
1809 { "minps", XM
, EX
, XX
, XX
},
1810 { "minss", XM
, EX
, XX
, XX
},
1811 { "minpd", XM
, EX
, XX
, XX
},
1812 { "minsd", XM
, EX
, XX
, XX
},
1816 { "movups", XM
, EX
, XX
, XX
},
1817 { "movss", XM
, EX
, XX
, XX
},
1818 { "movupd", XM
, EX
, XX
, XX
},
1819 { "movsd", XM
, EX
, XX
, XX
},
1823 { "movups", EX
, XM
, XX
, XX
},
1824 { "movss", EX
, XM
, XX
, XX
},
1825 { "movupd", EX
, XM
, XX
, XX
},
1826 { "movsd", EX
, XM
, XX
, XX
},
1830 { "mulps", XM
, EX
, XX
, XX
},
1831 { "mulss", XM
, EX
, XX
, XX
},
1832 { "mulpd", XM
, EX
, XX
, XX
},
1833 { "mulsd", XM
, EX
, XX
, XX
},
1837 { "rcpps", XM
, EX
, XX
, XX
},
1838 { "rcpss", XM
, EX
, XX
, XX
},
1839 { "(bad)", XM
, EX
, XX
, XX
},
1840 { "(bad)", XM
, EX
, XX
, XX
},
1844 { "rsqrtps", XM
, EX
, XX
, XX
},
1845 { "rsqrtss", XM
, EX
, XX
, XX
},
1846 { "(bad)", XM
, EX
, XX
, XX
},
1847 { "(bad)", XM
, EX
, XX
, XX
},
1851 { "sqrtps", XM
, EX
, XX
, XX
},
1852 { "sqrtss", XM
, EX
, XX
, XX
},
1853 { "sqrtpd", XM
, EX
, XX
, XX
},
1854 { "sqrtsd", XM
, EX
, XX
, XX
},
1858 { "subps", XM
, EX
, XX
, XX
},
1859 { "subss", XM
, EX
, XX
, XX
},
1860 { "subpd", XM
, EX
, XX
, XX
},
1861 { "subsd", XM
, EX
, XX
, XX
},
1865 { "(bad)", XM
, EX
, XX
, XX
},
1866 { "cvtdq2pd", XM
, EX
, XX
, XX
},
1867 { "cvttpd2dq", XM
, EX
, XX
, XX
},
1868 { "cvtpd2dq", XM
, EX
, XX
, XX
},
1872 { "cvtdq2ps", XM
, EX
, XX
, XX
},
1873 { "cvttps2dq",XM
, EX
, XX
, XX
},
1874 { "cvtps2dq",XM
, EX
, XX
, XX
},
1875 { "(bad)", XM
, EX
, XX
, XX
},
1879 { "cvtps2pd", XM
, EX
, XX
, XX
},
1880 { "cvtss2sd", XM
, EX
, XX
, XX
},
1881 { "cvtpd2ps", XM
, EX
, XX
, XX
},
1882 { "cvtsd2ss", XM
, EX
, XX
, XX
},
1886 { "maskmovq", MX
, MS
, XX
, XX
},
1887 { "(bad)", XM
, EX
, XX
, XX
},
1888 { "maskmovdqu", XM
, XS
, XX
, XX
},
1889 { "(bad)", XM
, EX
, XX
, XX
},
1893 { "movq", MX
, EM
, XX
, XX
},
1894 { "movdqu", XM
, EX
, XX
, XX
},
1895 { "movdqa", XM
, EX
, XX
, XX
},
1896 { "(bad)", XM
, EX
, XX
, XX
},
1900 { "movq", EM
, MX
, XX
, XX
},
1901 { "movdqu", EX
, XM
, XX
, XX
},
1902 { "movdqa", EX
, XM
, XX
, XX
},
1903 { "(bad)", EX
, XM
, XX
, XX
},
1907 { "(bad)", EX
, XM
, XX
, XX
},
1908 { "movq2dq", XM
, MS
, XX
, XX
},
1909 { "movq", EX
, XM
, XX
, XX
},
1910 { "movdq2q", MX
, XS
, XX
, XX
},
1914 { "pshufw", MX
, EM
, Ib
, XX
},
1915 { "pshufhw", XM
, EX
, Ib
, XX
},
1916 { "pshufd", XM
, EX
, Ib
, XX
},
1917 { "pshuflw", XM
, EX
, Ib
, XX
},
1921 { "movd", Edq
, MX
, XX
, XX
},
1922 { "movq", XM
, EX
, XX
, XX
},
1923 { "movd", Edq
, XM
, XX
, XX
},
1924 { "(bad)", Ed
, XM
, XX
, XX
},
1928 { "(bad)", MX
, EX
, XX
, XX
},
1929 { "(bad)", XM
, EX
, XX
, XX
},
1930 { "punpckhqdq", XM
, EX
, XX
, XX
},
1931 { "(bad)", XM
, EX
, XX
, XX
},
1935 { "movntq", EM
, MX
, XX
, XX
},
1936 { "(bad)", EM
, XM
, XX
, XX
},
1937 { "movntdq", EM
, XM
, XX
, XX
},
1938 { "(bad)", EM
, XM
, XX
, XX
},
1942 { "(bad)", MX
, EX
, XX
, XX
},
1943 { "(bad)", XM
, EX
, XX
, XX
},
1944 { "punpcklqdq", XM
, EX
, XX
, XX
},
1945 { "(bad)", XM
, EX
, XX
, XX
},
1949 { "(bad)", MX
, EX
, XX
, XX
},
1950 { "(bad)", XM
, EX
, XX
, XX
},
1951 { "addsubpd", XM
, EX
, XX
, XX
},
1952 { "addsubps", XM
, EX
, XX
, XX
},
1956 { "(bad)", MX
, EX
, XX
, XX
},
1957 { "(bad)", XM
, EX
, XX
, XX
},
1958 { "haddpd", XM
, EX
, XX
, XX
},
1959 { "haddps", XM
, EX
, XX
, XX
},
1963 { "(bad)", MX
, EX
, XX
, XX
},
1964 { "(bad)", XM
, EX
, XX
, XX
},
1965 { "hsubpd", XM
, EX
, XX
, XX
},
1966 { "hsubps", XM
, EX
, XX
, XX
},
1970 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h', XX
}, /* really only 2 operands */
1971 { "movsldup", XM
, EX
, XX
, XX
},
1972 { "movlpd", XM
, EX
, XX
, XX
},
1973 { "movddup", XM
, EX
, XX
, XX
},
1977 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l', XX
},
1978 { "movshdup", XM
, EX
, XX
, XX
},
1979 { "movhpd", XM
, EX
, XX
, XX
},
1980 { "(bad)", XM
, EX
, XX
, XX
},
1984 { "(bad)", XM
, EX
, XX
, XX
},
1985 { "(bad)", XM
, EX
, XX
, XX
},
1986 { "(bad)", XM
, EX
, XX
, XX
},
1987 { "lddqu", XM
, M
, XX
, XX
},
1991 {"movntps",Ev
, XM
, XX
, XX
},
1992 {"movntss",Ev
, XM
, XX
, XX
},
1993 {"movntpd",Ev
, XM
, XX
, XX
},
1994 {"movntsd",Ev
, XM
, XX
, XX
},
1999 {"vmread", Em
, Gm
, XX
, XX
},
2000 {"(bad)", XX
, XX
, XX
, XX
},
2001 {"extrq", XS
, Ib
, Ib
, XX
},
2002 {"insertq",XM
, XS
, Ib
, Ib
},
2007 {"vmwrite", Gm
, Em
, XX
, XX
},
2008 {"(bad)", XX
, XX
, XX
, XX
},
2009 {"extrq", XM
, XS
, XX
, XX
},
2010 {"insertq", XM
, XS
, XX
, XX
},
2015 { "bsrS", Gv
, Ev
, XX
, XX
},
2016 { "lzcntS", Gv
, Ev
, XX
, XX
},
2017 { "bsrS", Gv
, Ev
, XX
, XX
},
2018 { "(bad)", XX
, XX
, XX
, XX
},
2023 { "(bad)", XX
, XX
, XX
, XX
},
2024 { "popcntS",Gv
, Ev
, XX
, XX
},
2025 { "(bad)", XX
, XX
, XX
, XX
},
2026 { "(bad)", XX
, XX
, XX
, XX
},
2030 static const struct dis386 x86_64_table
[][2] = {
2032 { "arpl", Ew
, Gw
, XX
, XX
},
2033 { "movs{||lq|xd}", Gv
, Ed
, XX
, XX
},
2037 static const struct dis386 three_byte_table
[][256] = {
2041 { "pshufb", MX
, EM
, XX
, XX
},
2042 { "phaddw", MX
, EM
, XX
, XX
},
2043 { "phaddd", MX
, EM
, XX
, XX
},
2044 { "phaddsw", MX
, EM
, XX
, XX
},
2045 { "pmaddubsw", MX
, EM
, XX
, XX
},
2046 { "phsubw", MX
, EM
, XX
, XX
},
2047 { "phsubd", MX
, EM
, XX
, XX
},
2048 { "phsubsw", MX
, EM
, XX
, XX
},
2050 { "psignb", MX
, EM
, XX
, XX
},
2051 { "psignw", MX
, EM
, XX
, XX
},
2052 { "psignd", MX
, EM
, XX
, XX
},
2053 { "pmulhrsw", MX
, EM
, XX
, XX
},
2054 { "(bad)", XX
, XX
, XX
, XX
},
2055 { "(bad)", XX
, XX
, XX
, XX
},
2056 { "(bad)", XX
, XX
, XX
, XX
},
2057 { "(bad)", XX
, XX
, XX
, XX
},
2059 { "(bad)", XX
, XX
, XX
, XX
},
2060 { "(bad)", XX
, XX
, XX
, XX
},
2061 { "(bad)", XX
, XX
, XX
, XX
},
2062 { "(bad)", XX
, XX
, XX
, XX
},
2063 { "(bad)", XX
, XX
, XX
, XX
},
2064 { "(bad)", XX
, XX
, XX
, XX
},
2065 { "(bad)", XX
, XX
, XX
, XX
},
2066 { "(bad)", XX
, XX
, XX
, XX
},
2068 { "(bad)", XX
, XX
, XX
, XX
},
2069 { "(bad)", XX
, XX
, XX
, XX
},
2070 { "(bad)", XX
, XX
, XX
, XX
},
2071 { "(bad)", XX
, XX
, XX
, XX
},
2072 { "pabsb", MX
, EM
, XX
, XX
},
2073 { "pabsw", MX
, EM
, XX
, XX
},
2074 { "pabsd", MX
, EM
, XX
, XX
},
2075 { "(bad)", XX
, XX
, XX
, XX
},
2077 { "(bad)", XX
, XX
, XX
, XX
},
2078 { "(bad)", XX
, XX
, XX
, XX
},
2079 { "(bad)", XX
, XX
, XX
, XX
},
2080 { "(bad)", XX
, XX
, XX
, XX
},
2081 { "(bad)", XX
, XX
, XX
, XX
},
2082 { "(bad)", XX
, XX
, XX
, XX
},
2083 { "(bad)", XX
, XX
, XX
, XX
},
2084 { "(bad)", XX
, XX
, XX
, XX
},
2086 { "(bad)", XX
, XX
, XX
, XX
},
2087 { "(bad)", XX
, XX
, XX
, XX
},
2088 { "(bad)", XX
, XX
, XX
, XX
},
2089 { "(bad)", XX
, XX
, XX
, XX
},
2090 { "(bad)", XX
, XX
, XX
, XX
},
2091 { "(bad)", XX
, XX
, XX
, XX
},
2092 { "(bad)", XX
, XX
, XX
, XX
},
2093 { "(bad)", XX
, XX
, XX
, XX
},
2095 { "(bad)", XX
, XX
, XX
, XX
},
2096 { "(bad)", XX
, XX
, XX
, XX
},
2097 { "(bad)", XX
, XX
, XX
, XX
},
2098 { "(bad)", XX
, XX
, XX
, XX
},
2099 { "(bad)", XX
, XX
, XX
, XX
},
2100 { "(bad)", XX
, XX
, XX
, XX
},
2101 { "(bad)", XX
, XX
, XX
, XX
},
2102 { "(bad)", XX
, XX
, XX
, XX
},
2104 { "(bad)", XX
, XX
, XX
, XX
},
2105 { "(bad)", XX
, XX
, XX
, XX
},
2106 { "(bad)", XX
, XX
, XX
, XX
},
2107 { "(bad)", XX
, XX
, XX
, XX
},
2108 { "(bad)", XX
, XX
, XX
, XX
},
2109 { "(bad)", XX
, XX
, XX
, XX
},
2110 { "(bad)", XX
, XX
, XX
, XX
},
2111 { "(bad)", XX
, XX
, XX
, XX
},
2113 { "(bad)", XX
, XX
, XX
, XX
},
2114 { "(bad)", XX
, XX
, XX
, XX
},
2115 { "(bad)", XX
, XX
, XX
, XX
},
2116 { "(bad)", XX
, XX
, XX
, XX
},
2117 { "(bad)", XX
, XX
, XX
, XX
},
2118 { "(bad)", XX
, XX
, XX
, XX
},
2119 { "(bad)", XX
, XX
, XX
, XX
},
2120 { "(bad)", XX
, XX
, XX
, XX
},
2122 { "(bad)", XX
, XX
, XX
, XX
},
2123 { "(bad)", XX
, XX
, XX
, XX
},
2124 { "(bad)", XX
, XX
, XX
, XX
},
2125 { "(bad)", XX
, XX
, XX
, XX
},
2126 { "(bad)", XX
, XX
, XX
, XX
},
2127 { "(bad)", XX
, XX
, XX
, XX
},
2128 { "(bad)", XX
, XX
, XX
, XX
},
2129 { "(bad)", XX
, XX
, XX
, XX
},
2131 { "(bad)", XX
, XX
, XX
, XX
},
2132 { "(bad)", XX
, XX
, XX
, XX
},
2133 { "(bad)", XX
, XX
, XX
, XX
},
2134 { "(bad)", XX
, XX
, XX
, XX
},
2135 { "(bad)", XX
, XX
, XX
, XX
},
2136 { "(bad)", XX
, XX
, XX
, XX
},
2137 { "(bad)", XX
, XX
, XX
, XX
},
2138 { "(bad)", XX
, XX
, XX
, XX
},
2140 { "(bad)", XX
, XX
, XX
, XX
},
2141 { "(bad)", XX
, XX
, XX
, XX
},
2142 { "(bad)", XX
, XX
, XX
, XX
},
2143 { "(bad)", XX
, XX
, XX
, XX
},
2144 { "(bad)", XX
, XX
, XX
, XX
},
2145 { "(bad)", XX
, XX
, XX
, XX
},
2146 { "(bad)", XX
, XX
, XX
, XX
},
2147 { "(bad)", XX
, XX
, XX
, XX
},
2149 { "(bad)", XX
, XX
, XX
, XX
},
2150 { "(bad)", XX
, XX
, XX
, XX
},
2151 { "(bad)", XX
, XX
, XX
, XX
},
2152 { "(bad)", XX
, XX
, XX
, XX
},
2153 { "(bad)", XX
, XX
, XX
, XX
},
2154 { "(bad)", XX
, XX
, XX
, XX
},
2155 { "(bad)", XX
, XX
, XX
, XX
},
2156 { "(bad)", XX
, XX
, XX
, XX
},
2158 { "(bad)", XX
, XX
, XX
, XX
},
2159 { "(bad)", XX
, XX
, XX
, XX
},
2160 { "(bad)", XX
, XX
, XX
, XX
},
2161 { "(bad)", XX
, XX
, XX
, XX
},
2162 { "(bad)", XX
, XX
, XX
, XX
},
2163 { "(bad)", XX
, XX
, XX
, XX
},
2164 { "(bad)", XX
, XX
, XX
, XX
},
2165 { "(bad)", XX
, XX
, XX
, XX
},
2167 { "(bad)", XX
, XX
, XX
, XX
},
2168 { "(bad)", XX
, XX
, XX
, XX
},
2169 { "(bad)", XX
, XX
, XX
, XX
},
2170 { "(bad)", XX
, XX
, XX
, XX
},
2171 { "(bad)", XX
, XX
, XX
, XX
},
2172 { "(bad)", XX
, XX
, XX
, XX
},
2173 { "(bad)", XX
, XX
, XX
, XX
},
2174 { "(bad)", XX
, XX
, XX
, XX
},
2176 { "(bad)", XX
, XX
, XX
, XX
},
2177 { "(bad)", XX
, XX
, XX
, XX
},
2178 { "(bad)", XX
, XX
, XX
, XX
},
2179 { "(bad)", XX
, XX
, XX
, XX
},
2180 { "(bad)", XX
, XX
, XX
, XX
},
2181 { "(bad)", XX
, XX
, XX
, XX
},
2182 { "(bad)", XX
, XX
, XX
, XX
},
2183 { "(bad)", XX
, XX
, XX
, XX
},
2185 { "(bad)", XX
, XX
, XX
, XX
},
2186 { "(bad)", XX
, XX
, XX
, XX
},
2187 { "(bad)", XX
, XX
, XX
, XX
},
2188 { "(bad)", XX
, XX
, XX
, XX
},
2189 { "(bad)", XX
, XX
, XX
, XX
},
2190 { "(bad)", XX
, XX
, XX
, XX
},
2191 { "(bad)", XX
, XX
, XX
, XX
},
2192 { "(bad)", XX
, XX
, XX
, XX
},
2194 { "(bad)", XX
, XX
, XX
, XX
},
2195 { "(bad)", XX
, XX
, XX
, XX
},
2196 { "(bad)", XX
, XX
, XX
, XX
},
2197 { "(bad)", XX
, XX
, XX
, XX
},
2198 { "(bad)", XX
, XX
, XX
, XX
},
2199 { "(bad)", XX
, XX
, XX
, XX
},
2200 { "(bad)", XX
, XX
, XX
, XX
},
2201 { "(bad)", XX
, XX
, XX
, XX
},
2203 { "(bad)", XX
, XX
, XX
, XX
},
2204 { "(bad)", XX
, XX
, XX
, XX
},
2205 { "(bad)", XX
, XX
, XX
, XX
},
2206 { "(bad)", XX
, XX
, XX
, XX
},
2207 { "(bad)", XX
, XX
, XX
, XX
},
2208 { "(bad)", XX
, XX
, XX
, XX
},
2209 { "(bad)", XX
, XX
, XX
, XX
},
2210 { "(bad)", XX
, XX
, XX
, XX
},
2212 { "(bad)", XX
, XX
, XX
, XX
},
2213 { "(bad)", XX
, XX
, XX
, XX
},
2214 { "(bad)", XX
, XX
, XX
, XX
},
2215 { "(bad)", XX
, XX
, XX
, XX
},
2216 { "(bad)", XX
, XX
, XX
, XX
},
2217 { "(bad)", XX
, XX
, XX
, XX
},
2218 { "(bad)", XX
, XX
, XX
, XX
},
2219 { "(bad)", XX
, XX
, XX
, XX
},
2221 { "(bad)", XX
, XX
, XX
, XX
},
2222 { "(bad)", XX
, XX
, XX
, XX
},
2223 { "(bad)", XX
, XX
, XX
, XX
},
2224 { "(bad)", XX
, XX
, XX
, XX
},
2225 { "(bad)", XX
, XX
, XX
, XX
},
2226 { "(bad)", XX
, XX
, XX
, XX
},
2227 { "(bad)", XX
, XX
, XX
, XX
},
2228 { "(bad)", XX
, XX
, XX
, XX
},
2230 { "(bad)", XX
, XX
, XX
, XX
},
2231 { "(bad)", XX
, XX
, XX
, XX
},
2232 { "(bad)", XX
, XX
, XX
, XX
},
2233 { "(bad)", XX
, XX
, XX
, XX
},
2234 { "(bad)", XX
, XX
, XX
, XX
},
2235 { "(bad)", XX
, XX
, XX
, XX
},
2236 { "(bad)", XX
, XX
, XX
, XX
},
2237 { "(bad)", XX
, XX
, XX
, XX
},
2239 { "(bad)", XX
, XX
, XX
, XX
},
2240 { "(bad)", XX
, XX
, XX
, XX
},
2241 { "(bad)", XX
, XX
, XX
, XX
},
2242 { "(bad)", XX
, XX
, XX
, XX
},
2243 { "(bad)", XX
, XX
, XX
, XX
},
2244 { "(bad)", XX
, XX
, XX
, XX
},
2245 { "(bad)", XX
, XX
, XX
, XX
},
2246 { "(bad)", XX
, XX
, XX
, XX
},
2248 { "(bad)", XX
, XX
, XX
, XX
},
2249 { "(bad)", XX
, XX
, XX
, XX
},
2250 { "(bad)", XX
, XX
, XX
, XX
},
2251 { "(bad)", XX
, XX
, XX
, XX
},
2252 { "(bad)", XX
, XX
, XX
, XX
},
2253 { "(bad)", XX
, XX
, XX
, XX
},
2254 { "(bad)", XX
, XX
, XX
, XX
},
2255 { "(bad)", XX
, XX
, XX
, XX
},
2257 { "(bad)", XX
, XX
, XX
, XX
},
2258 { "(bad)", XX
, XX
, XX
, XX
},
2259 { "(bad)", XX
, XX
, XX
, XX
},
2260 { "(bad)", XX
, XX
, XX
, XX
},
2261 { "(bad)", XX
, XX
, XX
, XX
},
2262 { "(bad)", XX
, XX
, XX
, XX
},
2263 { "(bad)", XX
, XX
, XX
, XX
},
2264 { "(bad)", XX
, XX
, XX
, XX
},
2266 { "(bad)", XX
, XX
, XX
, XX
},
2267 { "(bad)", XX
, XX
, XX
, XX
},
2268 { "(bad)", XX
, XX
, XX
, XX
},
2269 { "(bad)", XX
, XX
, XX
, XX
},
2270 { "(bad)", XX
, XX
, XX
, XX
},
2271 { "(bad)", XX
, XX
, XX
, XX
},
2272 { "(bad)", XX
, XX
, XX
, XX
},
2273 { "(bad)", XX
, XX
, XX
, XX
},
2275 { "(bad)", XX
, XX
, XX
, XX
},
2276 { "(bad)", XX
, XX
, XX
, XX
},
2277 { "(bad)", XX
, XX
, XX
, XX
},
2278 { "(bad)", XX
, XX
, XX
, XX
},
2279 { "(bad)", XX
, XX
, XX
, XX
},
2280 { "(bad)", XX
, XX
, XX
, XX
},
2281 { "(bad)", XX
, XX
, XX
, XX
},
2282 { "(bad)", XX
, XX
, XX
, XX
},
2284 { "(bad)", XX
, XX
, XX
, XX
},
2285 { "(bad)", XX
, XX
, XX
, XX
},
2286 { "(bad)", XX
, XX
, XX
, XX
},
2287 { "(bad)", XX
, XX
, XX
, XX
},
2288 { "(bad)", XX
, XX
, XX
, XX
},
2289 { "(bad)", XX
, XX
, XX
, XX
},
2290 { "(bad)", XX
, XX
, XX
, XX
},
2291 { "(bad)", XX
, XX
, XX
, XX
},
2293 { "(bad)", XX
, XX
, XX
, XX
},
2294 { "(bad)", XX
, XX
, XX
, XX
},
2295 { "(bad)", XX
, XX
, XX
, XX
},
2296 { "(bad)", XX
, XX
, XX
, XX
},
2297 { "(bad)", XX
, XX
, XX
, XX
},
2298 { "(bad)", XX
, XX
, XX
, XX
},
2299 { "(bad)", XX
, XX
, XX
, XX
},
2300 { "(bad)", XX
, XX
, XX
, XX
},
2302 { "(bad)", XX
, XX
, XX
, XX
},
2303 { "(bad)", XX
, XX
, XX
, XX
},
2304 { "(bad)", XX
, XX
, XX
, XX
},
2305 { "(bad)", XX
, XX
, XX
, XX
},
2306 { "(bad)", XX
, XX
, XX
, XX
},
2307 { "(bad)", XX
, XX
, XX
, XX
},
2308 { "(bad)", XX
, XX
, XX
, XX
},
2309 { "(bad)", XX
, XX
, XX
, XX
},
2311 { "(bad)", XX
, XX
, XX
, XX
},
2312 { "(bad)", XX
, XX
, XX
, XX
},
2313 { "(bad)", XX
, XX
, XX
, XX
},
2314 { "(bad)", XX
, XX
, XX
, XX
},
2315 { "(bad)", XX
, XX
, XX
, XX
},
2316 { "(bad)", XX
, XX
, XX
, XX
},
2317 { "(bad)", XX
, XX
, XX
, XX
},
2318 { "(bad)", XX
, XX
, XX
, XX
},
2320 { "(bad)", XX
, XX
, XX
, XX
},
2321 { "(bad)", XX
, XX
, XX
, XX
},
2322 { "(bad)", XX
, XX
, XX
, XX
},
2323 { "(bad)", XX
, XX
, XX
, XX
},
2324 { "(bad)", XX
, XX
, XX
, XX
},
2325 { "(bad)", XX
, XX
, XX
, XX
},
2326 { "(bad)", XX
, XX
, XX
, XX
},
2327 { "(bad)", XX
, XX
, XX
, XX
}
2332 { "(bad)", XX
, XX
, XX
, XX
},
2333 { "(bad)", XX
, XX
, XX
, XX
},
2334 { "(bad)", XX
, XX
, XX
, XX
},
2335 { "(bad)", XX
, XX
, XX
, XX
},
2336 { "(bad)", XX
, XX
, XX
, XX
},
2337 { "(bad)", XX
, XX
, XX
, XX
},
2338 { "(bad)", XX
, XX
, XX
, XX
},
2339 { "(bad)", XX
, XX
, XX
, XX
},
2341 { "(bad)", XX
, XX
, XX
, XX
},
2342 { "(bad)", XX
, XX
, XX
, XX
},
2343 { "(bad)", XX
, XX
, XX
, XX
},
2344 { "(bad)", XX
, XX
, XX
, XX
},
2345 { "(bad)", XX
, XX
, XX
, XX
},
2346 { "(bad)", XX
, XX
, XX
, XX
},
2347 { "(bad)", XX
, XX
, XX
, XX
},
2348 { "palignr", MX
, EM
, Ib
, XX
},
2350 { "(bad)", XX
, XX
, XX
, XX
},
2351 { "(bad)", XX
, XX
, XX
, XX
},
2352 { "(bad)", XX
, XX
, XX
, XX
},
2353 { "(bad)", XX
, XX
, XX
, XX
},
2354 { "(bad)", XX
, XX
, XX
, XX
},
2355 { "(bad)", XX
, XX
, XX
, XX
},
2356 { "(bad)", XX
, XX
, XX
, XX
},
2357 { "(bad)", XX
, XX
, XX
, XX
},
2359 { "(bad)", XX
, XX
, XX
, XX
},
2360 { "(bad)", XX
, XX
, XX
, XX
},
2361 { "(bad)", XX
, XX
, XX
, XX
},
2362 { "(bad)", XX
, XX
, XX
, XX
},
2363 { "(bad)", XX
, XX
, XX
, XX
},
2364 { "(bad)", XX
, XX
, XX
, XX
},
2365 { "(bad)", XX
, XX
, XX
, XX
},
2366 { "(bad)", XX
, XX
, XX
, XX
},
2368 { "(bad)", XX
, XX
, XX
, XX
},
2369 { "(bad)", XX
, XX
, XX
, XX
},
2370 { "(bad)", XX
, XX
, XX
, XX
},
2371 { "(bad)", XX
, XX
, XX
, XX
},
2372 { "(bad)", XX
, XX
, XX
, XX
},
2373 { "(bad)", XX
, XX
, XX
, XX
},
2374 { "(bad)", XX
, XX
, XX
, XX
},
2375 { "(bad)", XX
, XX
, XX
, XX
},
2377 { "(bad)", XX
, XX
, XX
, XX
},
2378 { "(bad)", XX
, XX
, XX
, XX
},
2379 { "(bad)", XX
, XX
, XX
, XX
},
2380 { "(bad)", XX
, XX
, XX
, XX
},
2381 { "(bad)", XX
, XX
, XX
, XX
},
2382 { "(bad)", XX
, XX
, XX
, XX
},
2383 { "(bad)", XX
, XX
, XX
, XX
},
2384 { "(bad)", XX
, XX
, XX
, XX
},
2386 { "(bad)", XX
, XX
, XX
, XX
},
2387 { "(bad)", XX
, XX
, XX
, XX
},
2388 { "(bad)", XX
, XX
, XX
, XX
},
2389 { "(bad)", XX
, XX
, XX
, XX
},
2390 { "(bad)", XX
, XX
, XX
, XX
},
2391 { "(bad)", XX
, XX
, XX
, XX
},
2392 { "(bad)", XX
, XX
, XX
, XX
},
2393 { "(bad)", XX
, XX
, XX
, XX
},
2395 { "(bad)", XX
, XX
, XX
, XX
},
2396 { "(bad)", XX
, XX
, XX
, XX
},
2397 { "(bad)", XX
, XX
, XX
, XX
},
2398 { "(bad)", XX
, XX
, XX
, XX
},
2399 { "(bad)", XX
, XX
, XX
, XX
},
2400 { "(bad)", XX
, XX
, XX
, XX
},
2401 { "(bad)", XX
, XX
, XX
, XX
},
2402 { "(bad)", XX
, XX
, XX
, XX
},
2404 { "(bad)", XX
, XX
, XX
, XX
},
2405 { "(bad)", XX
, XX
, XX
, XX
},
2406 { "(bad)", XX
, XX
, XX
, XX
},
2407 { "(bad)", XX
, XX
, XX
, XX
},
2408 { "(bad)", XX
, XX
, XX
, XX
},
2409 { "(bad)", XX
, XX
, XX
, XX
},
2410 { "(bad)", XX
, XX
, XX
, XX
},
2411 { "(bad)", XX
, XX
, XX
, XX
},
2413 { "(bad)", XX
, XX
, XX
, XX
},
2414 { "(bad)", XX
, XX
, XX
, XX
},
2415 { "(bad)", XX
, XX
, XX
, XX
},
2416 { "(bad)", XX
, XX
, XX
, XX
},
2417 { "(bad)", XX
, XX
, XX
, XX
},
2418 { "(bad)", XX
, XX
, XX
, XX
},
2419 { "(bad)", XX
, XX
, XX
, XX
},
2420 { "(bad)", XX
, XX
, XX
, XX
},
2422 { "(bad)", XX
, XX
, XX
, XX
},
2423 { "(bad)", XX
, XX
, XX
, XX
},
2424 { "(bad)", XX
, XX
, XX
, XX
},
2425 { "(bad)", XX
, XX
, XX
, XX
},
2426 { "(bad)", XX
, XX
, XX
, XX
},
2427 { "(bad)", XX
, XX
, XX
, XX
},
2428 { "(bad)", XX
, XX
, XX
, XX
},
2429 { "(bad)", XX
, XX
, XX
, XX
},
2431 { "(bad)", XX
, XX
, XX
, XX
},
2432 { "(bad)", XX
, XX
, XX
, XX
},
2433 { "(bad)", XX
, XX
, XX
, XX
},
2434 { "(bad)", XX
, XX
, XX
, XX
},
2435 { "(bad)", XX
, XX
, XX
, XX
},
2436 { "(bad)", XX
, XX
, XX
, XX
},
2437 { "(bad)", XX
, XX
, XX
, XX
},
2438 { "(bad)", XX
, XX
, XX
, XX
},
2440 { "(bad)", XX
, XX
, XX
, XX
},
2441 { "(bad)", XX
, XX
, XX
, XX
},
2442 { "(bad)", XX
, XX
, XX
, XX
},
2443 { "(bad)", XX
, XX
, XX
, XX
},
2444 { "(bad)", XX
, XX
, XX
, XX
},
2445 { "(bad)", XX
, XX
, XX
, XX
},
2446 { "(bad)", XX
, XX
, XX
, XX
},
2447 { "(bad)", XX
, XX
, XX
, XX
},
2449 { "(bad)", XX
, XX
, XX
, XX
},
2450 { "(bad)", XX
, XX
, XX
, XX
},
2451 { "(bad)", XX
, XX
, XX
, XX
},
2452 { "(bad)", XX
, XX
, XX
, XX
},
2453 { "(bad)", XX
, XX
, XX
, XX
},
2454 { "(bad)", XX
, XX
, XX
, XX
},
2455 { "(bad)", XX
, XX
, XX
, XX
},
2456 { "(bad)", XX
, XX
, XX
, XX
},
2458 { "(bad)", XX
, XX
, XX
, XX
},
2459 { "(bad)", XX
, XX
, XX
, XX
},
2460 { "(bad)", XX
, XX
, XX
, XX
},
2461 { "(bad)", XX
, XX
, XX
, XX
},
2462 { "(bad)", XX
, XX
, XX
, XX
},
2463 { "(bad)", XX
, XX
, XX
, XX
},
2464 { "(bad)", XX
, XX
, XX
, XX
},
2465 { "(bad)", XX
, XX
, XX
, XX
},
2467 { "(bad)", XX
, XX
, XX
, XX
},
2468 { "(bad)", XX
, XX
, XX
, XX
},
2469 { "(bad)", XX
, XX
, XX
, XX
},
2470 { "(bad)", XX
, XX
, XX
, XX
},
2471 { "(bad)", XX
, XX
, XX
, XX
},
2472 { "(bad)", XX
, XX
, XX
, XX
},
2473 { "(bad)", XX
, XX
, XX
, XX
},
2474 { "(bad)", XX
, XX
, XX
, XX
},
2476 { "(bad)", XX
, XX
, XX
, XX
},
2477 { "(bad)", XX
, XX
, XX
, XX
},
2478 { "(bad)", XX
, XX
, XX
, XX
},
2479 { "(bad)", XX
, XX
, XX
, XX
},
2480 { "(bad)", XX
, XX
, XX
, XX
},
2481 { "(bad)", XX
, XX
, XX
, XX
},
2482 { "(bad)", XX
, XX
, XX
, XX
},
2483 { "(bad)", XX
, XX
, XX
, XX
},
2485 { "(bad)", XX
, XX
, XX
, XX
},
2486 { "(bad)", XX
, XX
, XX
, XX
},
2487 { "(bad)", XX
, XX
, XX
, XX
},
2488 { "(bad)", XX
, XX
, XX
, XX
},
2489 { "(bad)", XX
, XX
, XX
, XX
},
2490 { "(bad)", XX
, XX
, XX
, XX
},
2491 { "(bad)", XX
, XX
, XX
, XX
},
2492 { "(bad)", XX
, XX
, XX
, XX
},
2494 { "(bad)", XX
, XX
, XX
, XX
},
2495 { "(bad)", XX
, XX
, XX
, XX
},
2496 { "(bad)", XX
, XX
, XX
, XX
},
2497 { "(bad)", XX
, XX
, XX
, XX
},
2498 { "(bad)", XX
, XX
, XX
, XX
},
2499 { "(bad)", XX
, XX
, XX
, XX
},
2500 { "(bad)", XX
, XX
, XX
, XX
},
2501 { "(bad)", XX
, XX
, XX
, XX
},
2503 { "(bad)", XX
, XX
, XX
, XX
},
2504 { "(bad)", XX
, XX
, XX
, XX
},
2505 { "(bad)", XX
, XX
, XX
, XX
},
2506 { "(bad)", XX
, XX
, XX
, XX
},
2507 { "(bad)", XX
, XX
, XX
, XX
},
2508 { "(bad)", XX
, XX
, XX
, XX
},
2509 { "(bad)", XX
, XX
, XX
, XX
},
2510 { "(bad)", XX
, XX
, XX
, XX
},
2512 { "(bad)", XX
, XX
, XX
, XX
},
2513 { "(bad)", XX
, XX
, XX
, XX
},
2514 { "(bad)", XX
, XX
, XX
, XX
},
2515 { "(bad)", XX
, XX
, XX
, XX
},
2516 { "(bad)", XX
, XX
, XX
, XX
},
2517 { "(bad)", XX
, XX
, XX
, XX
},
2518 { "(bad)", XX
, XX
, XX
, XX
},
2519 { "(bad)", XX
, XX
, XX
, XX
},
2521 { "(bad)", XX
, XX
, XX
, XX
},
2522 { "(bad)", XX
, XX
, XX
, XX
},
2523 { "(bad)", XX
, XX
, XX
, XX
},
2524 { "(bad)", XX
, XX
, XX
, XX
},
2525 { "(bad)", XX
, XX
, XX
, XX
},
2526 { "(bad)", XX
, XX
, XX
, XX
},
2527 { "(bad)", XX
, XX
, XX
, XX
},
2528 { "(bad)", XX
, XX
, XX
, XX
},
2530 { "(bad)", XX
, XX
, XX
, XX
},
2531 { "(bad)", XX
, XX
, XX
, XX
},
2532 { "(bad)", XX
, XX
, XX
, XX
},
2533 { "(bad)", XX
, XX
, XX
, XX
},
2534 { "(bad)", XX
, XX
, XX
, XX
},
2535 { "(bad)", XX
, XX
, XX
, XX
},
2536 { "(bad)", XX
, XX
, XX
, XX
},
2537 { "(bad)", XX
, XX
, XX
, XX
},
2539 { "(bad)", XX
, XX
, XX
, XX
},
2540 { "(bad)", XX
, XX
, XX
, XX
},
2541 { "(bad)", XX
, XX
, XX
, XX
},
2542 { "(bad)", XX
, XX
, XX
, XX
},
2543 { "(bad)", XX
, XX
, XX
, XX
},
2544 { "(bad)", XX
, XX
, XX
, XX
},
2545 { "(bad)", XX
, XX
, XX
, XX
},
2546 { "(bad)", XX
, XX
, XX
, XX
},
2548 { "(bad)", XX
, XX
, XX
, XX
},
2549 { "(bad)", XX
, XX
, XX
, XX
},
2550 { "(bad)", XX
, XX
, XX
, XX
},
2551 { "(bad)", XX
, XX
, XX
, XX
},
2552 { "(bad)", XX
, XX
, XX
, XX
},
2553 { "(bad)", XX
, XX
, XX
, XX
},
2554 { "(bad)", XX
, XX
, XX
, XX
},
2555 { "(bad)", XX
, XX
, XX
, XX
},
2557 { "(bad)", XX
, XX
, XX
, XX
},
2558 { "(bad)", XX
, XX
, XX
, XX
},
2559 { "(bad)", XX
, XX
, XX
, XX
},
2560 { "(bad)", XX
, XX
, XX
, XX
},
2561 { "(bad)", XX
, XX
, XX
, XX
},
2562 { "(bad)", XX
, XX
, XX
, XX
},
2563 { "(bad)", XX
, XX
, XX
, XX
},
2564 { "(bad)", XX
, XX
, XX
, XX
},
2566 { "(bad)", XX
, XX
, XX
, XX
},
2567 { "(bad)", XX
, XX
, XX
, XX
},
2568 { "(bad)", XX
, XX
, XX
, XX
},
2569 { "(bad)", XX
, XX
, XX
, XX
},
2570 { "(bad)", XX
, XX
, XX
, XX
},
2571 { "(bad)", XX
, XX
, XX
, XX
},
2572 { "(bad)", XX
, XX
, XX
, XX
},
2573 { "(bad)", XX
, XX
, XX
, XX
},
2575 { "(bad)", XX
, XX
, XX
, XX
},
2576 { "(bad)", XX
, XX
, XX
, XX
},
2577 { "(bad)", XX
, XX
, XX
, XX
},
2578 { "(bad)", XX
, XX
, XX
, XX
},
2579 { "(bad)", XX
, XX
, XX
, XX
},
2580 { "(bad)", XX
, XX
, XX
, XX
},
2581 { "(bad)", XX
, XX
, XX
, XX
},
2582 { "(bad)", XX
, XX
, XX
, XX
},
2584 { "(bad)", XX
, XX
, XX
, XX
},
2585 { "(bad)", XX
, XX
, XX
, XX
},
2586 { "(bad)", XX
, XX
, XX
, XX
},
2587 { "(bad)", XX
, XX
, XX
, XX
},
2588 { "(bad)", XX
, XX
, XX
, XX
},
2589 { "(bad)", XX
, XX
, XX
, XX
},
2590 { "(bad)", XX
, XX
, XX
, XX
},
2591 { "(bad)", XX
, XX
, XX
, XX
},
2593 { "(bad)", XX
, XX
, XX
, XX
},
2594 { "(bad)", XX
, XX
, XX
, XX
},
2595 { "(bad)", XX
, XX
, XX
, XX
},
2596 { "(bad)", XX
, XX
, XX
, XX
},
2597 { "(bad)", XX
, XX
, XX
, XX
},
2598 { "(bad)", XX
, XX
, XX
, XX
},
2599 { "(bad)", XX
, XX
, XX
, XX
},
2600 { "(bad)", XX
, XX
, XX
, XX
},
2602 { "(bad)", XX
, XX
, XX
, XX
},
2603 { "(bad)", XX
, XX
, XX
, XX
},
2604 { "(bad)", XX
, XX
, XX
, XX
},
2605 { "(bad)", XX
, XX
, XX
, XX
},
2606 { "(bad)", XX
, XX
, XX
, XX
},
2607 { "(bad)", XX
, XX
, XX
, XX
},
2608 { "(bad)", XX
, XX
, XX
, XX
},
2609 { "(bad)", XX
, XX
, XX
, XX
},
2611 { "(bad)", XX
, XX
, XX
, XX
},
2612 { "(bad)", XX
, XX
, XX
, XX
},
2613 { "(bad)", XX
, XX
, XX
, XX
},
2614 { "(bad)", XX
, XX
, XX
, XX
},
2615 { "(bad)", XX
, XX
, XX
, XX
},
2616 { "(bad)", XX
, XX
, XX
, XX
},
2617 { "(bad)", XX
, XX
, XX
, XX
},
2618 { "(bad)", XX
, XX
, XX
, XX
}
2622 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2634 FETCH_DATA (the_info
, codep
+ 1);
2638 /* REX prefixes family. */
2655 if (address_mode
== mode_64bit
)
2661 prefixes
|= PREFIX_REPZ
;
2664 prefixes
|= PREFIX_REPNZ
;
2667 prefixes
|= PREFIX_LOCK
;
2670 prefixes
|= PREFIX_CS
;
2673 prefixes
|= PREFIX_SS
;
2676 prefixes
|= PREFIX_DS
;
2679 prefixes
|= PREFIX_ES
;
2682 prefixes
|= PREFIX_FS
;
2685 prefixes
|= PREFIX_GS
;
2688 prefixes
|= PREFIX_DATA
;
2691 prefixes
|= PREFIX_ADDR
;
2694 /* fwait is really an instruction. If there are prefixes
2695 before the fwait, they belong to the fwait, *not* to the
2696 following instruction. */
2697 if (prefixes
|| rex
)
2699 prefixes
|= PREFIX_FWAIT
;
2703 prefixes
= PREFIX_FWAIT
;
2708 /* Rex is ignored when followed by another prefix. */
2719 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2723 prefix_name (int pref
, int sizeflag
)
2727 /* REX prefixes family. */
2779 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2781 if (address_mode
== mode_64bit
)
2782 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2784 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2792 static char op1out
[100], op2out
[100], op3out
[100], op4out
[100];
2793 static int op_ad
, op_index
[4];
2794 static int two_source_ops
;
2795 static bfd_vma op_address
[4];
2796 static bfd_vma op_riprel
[4];
2797 static bfd_vma start_pc
;
2800 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2801 * (see topic "Redundant prefixes" in the "Differences from 8086"
2802 * section of the "Virtual 8086 Mode" chapter.)
2803 * 'pc' should be the address of this instruction, it will
2804 * be used to print the target address if this is a relative jump or call
2805 * The function returns the length of this instruction in bytes.
2808 static char intel_syntax
;
2809 static char open_char
;
2810 static char close_char
;
2811 static char separator_char
;
2812 static char scale_char
;
2814 /* Here for backwards compatibility. When gdb stops using
2815 print_insn_i386_att and print_insn_i386_intel these functions can
2816 disappear, and print_insn_i386 be merged into print_insn. */
2818 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2822 return print_insn (pc
, info
);
2826 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2830 return print_insn (pc
, info
);
2834 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2838 return print_insn (pc
, info
);
2842 print_insn (bfd_vma pc
, disassemble_info
*info
)
2844 const struct dis386
*dp
;
2846 char *first
, *second
, *third
, *fourth
;
2848 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
2849 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
2852 struct dis_private priv
;
2855 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2856 || info
->mach
== bfd_mach_x86_64
)
2857 address_mode
= mode_64bit
;
2859 address_mode
= mode_32bit
;
2861 if (intel_syntax
== (char) -1)
2862 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2863 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2865 if (info
->mach
== bfd_mach_i386_i386
2866 || info
->mach
== bfd_mach_x86_64
2867 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2868 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2869 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2870 else if (info
->mach
== bfd_mach_i386_i8086
)
2871 priv
.orig_sizeflag
= 0;
2875 for (p
= info
->disassembler_options
; p
!= NULL
; )
2877 if (CONST_STRNEQ (p
, "x86-64"))
2879 address_mode
= mode_64bit
;
2880 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2882 else if (CONST_STRNEQ (p
, "i386"))
2884 address_mode
= mode_32bit
;
2885 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2887 else if (CONST_STRNEQ (p
, "i8086"))
2889 address_mode
= mode_16bit
;
2890 priv
.orig_sizeflag
= 0;
2892 else if (CONST_STRNEQ (p
, "intel"))
2896 else if (CONST_STRNEQ (p
, "att"))
2900 else if (CONST_STRNEQ (p
, "addr"))
2902 if (p
[4] == '1' && p
[5] == '6')
2903 priv
.orig_sizeflag
&= ~AFLAG
;
2904 else if (p
[4] == '3' && p
[5] == '2')
2905 priv
.orig_sizeflag
|= AFLAG
;
2907 else if (CONST_STRNEQ (p
, "data"))
2909 if (p
[4] == '1' && p
[5] == '6')
2910 priv
.orig_sizeflag
&= ~DFLAG
;
2911 else if (p
[4] == '3' && p
[5] == '2')
2912 priv
.orig_sizeflag
|= DFLAG
;
2914 else if (CONST_STRNEQ (p
, "suffix"))
2915 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2917 p
= strchr (p
, ',');
2924 names64
= intel_names64
;
2925 names32
= intel_names32
;
2926 names16
= intel_names16
;
2927 names8
= intel_names8
;
2928 names8rex
= intel_names8rex
;
2929 names_seg
= intel_names_seg
;
2930 index16
= intel_index16
;
2933 separator_char
= '+';
2938 names64
= att_names64
;
2939 names32
= att_names32
;
2940 names16
= att_names16
;
2941 names8
= att_names8
;
2942 names8rex
= att_names8rex
;
2943 names_seg
= att_names_seg
;
2944 index16
= att_index16
;
2947 separator_char
= ',';
2951 /* The output looks better if we put 7 bytes on a line, since that
2952 puts most long word instructions on a single line. */
2953 info
->bytes_per_line
= 7;
2955 info
->private_data
= &priv
;
2956 priv
.max_fetched
= priv
.the_buffer
;
2957 priv
.insn_start
= pc
;
2965 op_index
[0] = op_index
[1] = op_index
[2] = op_index
[3] = -1;
2969 start_codep
= priv
.the_buffer
;
2970 codep
= priv
.the_buffer
;
2972 if (setjmp (priv
.bailout
) != 0)
2976 /* Getting here means we tried for data but didn't get it. That
2977 means we have an incomplete instruction of some sort. Just
2978 print the first byte as a prefix or a .byte pseudo-op. */
2979 if (codep
> priv
.the_buffer
)
2981 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2983 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2986 /* Just print the first byte as a .byte instruction. */
2987 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2988 (unsigned int) priv
.the_buffer
[0]);
3001 sizeflag
= priv
.orig_sizeflag
;
3003 FETCH_DATA (info
, codep
+ 1);
3004 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3006 if (((prefixes
& PREFIX_FWAIT
)
3007 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3008 || (rex
&& rex_used
))
3012 /* fwait not followed by floating point instruction, or rex followed
3013 by other prefixes. Print the first prefix. */
3014 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3016 name
= INTERNAL_DISASSEMBLER_ERROR
;
3017 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3024 unsigned char threebyte
;
3025 FETCH_DATA (info
, codep
+ 2);
3026 threebyte
= *++codep
;
3027 dp
= &dis386_twobyte
[threebyte
];
3028 need_modrm
= twobyte_has_modrm
[*codep
];
3029 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3030 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3031 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3032 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3034 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
3036 FETCH_DATA (info
, codep
+ 2);
3041 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3042 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3043 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3046 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3047 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3048 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3057 dp
= &dis386
[*codep
];
3058 need_modrm
= onebyte_has_modrm
[*codep
];
3059 uses_DATA_prefix
= 0;
3060 uses_REPNZ_prefix
= 0;
3061 uses_REPZ_prefix
= 0;
3062 uses_LOCK_prefix
= 0;
3066 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3069 used_prefixes
|= PREFIX_REPZ
;
3071 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3074 used_prefixes
|= PREFIX_REPNZ
;
3077 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3080 used_prefixes
|= PREFIX_LOCK
;
3083 if (prefixes
& PREFIX_ADDR
)
3086 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
3088 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3089 oappend ("addr32 ");
3091 oappend ("addr16 ");
3092 used_prefixes
|= PREFIX_ADDR
;
3096 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3099 if (dp
->bytemode3
== cond_jump_mode
3100 && dp
->bytemode1
== v_mode
3103 if (sizeflag
& DFLAG
)
3104 oappend ("data32 ");
3106 oappend ("data16 ");
3107 used_prefixes
|= PREFIX_DATA
;
3111 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
3113 dp
= &three_byte_table
[dp
->bytemode2
][op
];
3114 mod
= (*codep
>> 6) & 3;
3115 reg
= (*codep
>> 3) & 7;
3118 else if (need_modrm
)
3120 FETCH_DATA (info
, codep
+ 1);
3121 mod
= (*codep
>> 6) & 3;
3122 reg
= (*codep
>> 3) & 7;
3126 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
3133 if (dp
->name
== NULL
)
3135 switch (dp
->bytemode1
)
3138 dp
= &grps
[dp
->bytemode2
][reg
];
3141 case USE_PREFIX_USER_TABLE
:
3143 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3144 if (prefixes
& PREFIX_REPZ
)
3148 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3149 before PREFIX_DATA. */
3150 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3151 if (prefixes
& PREFIX_REPNZ
)
3155 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3156 if (prefixes
& PREFIX_DATA
)
3160 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
3163 case X86_64_SPECIAL
:
3164 index
= address_mode
== mode_64bit
? 1 : 0;
3165 dp
= &x86_64_table
[dp
->bytemode2
][index
];
3169 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3174 if (putop (dp
->name
, sizeflag
) == 0)
3179 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
3184 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
3189 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
3194 (*dp
->op4
) (dp
->bytemode4
, sizeflag
);
3198 /* See if any prefixes were not used. If so, print the first one
3199 separately. If we don't do this, we'll wind up printing an
3200 instruction stream which does not precisely correspond to the
3201 bytes we are disassembling. */
3202 if ((prefixes
& ~used_prefixes
) != 0)
3206 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3208 name
= INTERNAL_DISASSEMBLER_ERROR
;
3209 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3212 if (rex
& ~rex_used
)
3215 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3217 name
= INTERNAL_DISASSEMBLER_ERROR
;
3218 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3221 obufp
= obuf
+ strlen (obuf
);
3222 for (i
= strlen (obuf
); i
< 6; i
++)
3225 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3227 /* The enter and bound instructions are printed with operands in the same
3228 order as the intel book; everything else is printed in reverse order. */
3229 if (intel_syntax
|| two_source_ops
)
3235 op_ad
= op_index
[0];
3236 op_index
[0] = op_index
[3];
3237 op_index
[3] = op_ad
;
3238 op_ad
= op_index
[1];
3239 op_index
[1] = op_index
[2];
3240 op_index
[2] = op_ad
;
3253 if (op_index
[0] != -1 && !op_riprel
[0])
3254 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
3256 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
3263 (*info
->fprintf_func
) (info
->stream
, ",");
3264 if (op_index
[1] != -1 && !op_riprel
[1])
3265 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
3267 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
3274 (*info
->fprintf_func
) (info
->stream
, ",");
3275 if (op_index
[2] != -1 && !op_riprel
[2])
3276 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
3278 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
3285 (*info
->fprintf_func
) (info
->stream
, ",");
3286 if (op_index
[3] != -1 && !op_riprel
[3])
3287 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[3]], info
);
3289 (*info
->fprintf_func
) (info
->stream
, "%s", fourth
);
3292 for (i
= 0; i
< 4; i
++)
3293 if (op_index
[i
] != -1 && op_riprel
[i
])
3295 (*info
->fprintf_func
) (info
->stream
, " # ");
3296 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3297 + op_address
[op_index
[i
]]), info
);
3299 return codep
- priv
.the_buffer
;
3302 static const char *float_mem
[] = {
3377 static const unsigned char float_mem_mode
[] = {
3453 #define STi OP_STi, 0
3455 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
3456 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
3457 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
3458 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
3459 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
3460 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
3461 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
3462 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
3463 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
3465 static const struct dis386 float_reg
[][8] = {
3468 { "fadd", ST
, STi
, XX
, XX
},
3469 { "fmul", ST
, STi
, XX
, XX
},
3470 { "fcom", STi
, XX
, XX
, XX
},
3471 { "fcomp", STi
, XX
, XX
, XX
},
3472 { "fsub", ST
, STi
, XX
, XX
},
3473 { "fsubr", ST
, STi
, XX
, XX
},
3474 { "fdiv", ST
, STi
, XX
, XX
},
3475 { "fdivr", ST
, STi
, XX
, XX
},
3479 { "fld", STi
, XX
, XX
, XX
},
3480 { "fxch", STi
, XX
, XX
, XX
},
3482 { "(bad)", XX
, XX
, XX
, XX
},
3490 { "fcmovb", ST
, STi
, XX
, XX
},
3491 { "fcmove", ST
, STi
, XX
, XX
},
3492 { "fcmovbe",ST
, STi
, XX
, XX
},
3493 { "fcmovu", ST
, STi
, XX
, XX
},
3494 { "(bad)", XX
, XX
, XX
, XX
},
3496 { "(bad)", XX
, XX
, XX
, XX
},
3497 { "(bad)", XX
, XX
, XX
, XX
},
3501 { "fcmovnb",ST
, STi
, XX
, XX
},
3502 { "fcmovne",ST
, STi
, XX
, XX
},
3503 { "fcmovnbe",ST
, STi
, XX
, XX
},
3504 { "fcmovnu",ST
, STi
, XX
, XX
},
3506 { "fucomi", ST
, STi
, XX
, XX
},
3507 { "fcomi", ST
, STi
, XX
, XX
},
3508 { "(bad)", XX
, XX
, XX
, XX
},
3512 { "fadd", STi
, ST
, XX
, XX
},
3513 { "fmul", STi
, ST
, XX
, XX
},
3514 { "(bad)", XX
, XX
, XX
, XX
},
3515 { "(bad)", XX
, XX
, XX
, XX
},
3517 { "fsub", STi
, ST
, XX
, XX
},
3518 { "fsubr", STi
, ST
, XX
, XX
},
3519 { "fdiv", STi
, ST
, XX
, XX
},
3520 { "fdivr", STi
, ST
, XX
, XX
},
3522 { "fsubr", STi
, ST
, XX
, XX
},
3523 { "fsub", STi
, ST
, XX
, XX
},
3524 { "fdivr", STi
, ST
, XX
, XX
},
3525 { "fdiv", STi
, ST
, XX
, XX
},
3530 { "ffree", STi
, XX
, XX
, XX
},
3531 { "(bad)", XX
, XX
, XX
, XX
},
3532 { "fst", STi
, XX
, XX
, XX
},
3533 { "fstp", STi
, XX
, XX
, XX
},
3534 { "fucom", STi
, XX
, XX
, XX
},
3535 { "fucomp", STi
, XX
, XX
, XX
},
3536 { "(bad)", XX
, XX
, XX
, XX
},
3537 { "(bad)", XX
, XX
, XX
, XX
},
3541 { "faddp", STi
, ST
, XX
, XX
},
3542 { "fmulp", STi
, ST
, XX
, XX
},
3543 { "(bad)", XX
, XX
, XX
, XX
},
3546 { "fsubp", STi
, ST
, XX
, XX
},
3547 { "fsubrp", STi
, ST
, XX
, XX
},
3548 { "fdivp", STi
, ST
, XX
, XX
},
3549 { "fdivrp", STi
, ST
, XX
, XX
},
3551 { "fsubrp", STi
, ST
, XX
, XX
},
3552 { "fsubp", STi
, ST
, XX
, XX
},
3553 { "fdivrp", STi
, ST
, XX
, XX
},
3554 { "fdivp", STi
, ST
, XX
, XX
},
3559 { "ffreep", STi
, XX
, XX
, XX
},
3560 { "(bad)", XX
, XX
, XX
, XX
},
3561 { "(bad)", XX
, XX
, XX
, XX
},
3562 { "(bad)", XX
, XX
, XX
, XX
},
3564 { "fucomip",ST
, STi
, XX
, XX
},
3565 { "fcomip", ST
, STi
, XX
, XX
},
3566 { "(bad)", XX
, XX
, XX
, XX
},
3570 static char *fgrps
[][8] = {
3573 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3578 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3583 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3588 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3593 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3598 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3603 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3604 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3609 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3614 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3619 dofloat (int sizeflag
)
3621 const struct dis386
*dp
;
3622 unsigned char floatop
;
3624 floatop
= codep
[-1];
3628 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
3630 putop (float_mem
[fp_indx
], sizeflag
);
3633 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
3636 /* Skip mod/rm byte. */
3640 dp
= &float_reg
[floatop
- 0xd8][reg
];
3641 if (dp
->name
== NULL
)
3643 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
3645 /* Instruction fnstsw is only one with strange arg. */
3646 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3647 strcpy (op1out
, names16
[0]);
3651 putop (dp
->name
, sizeflag
);
3656 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
3661 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
3666 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3668 oappend ("%st" + intel_syntax
);
3672 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3674 sprintf (scratchbuf
, "%%st(%d)", rm
);
3675 oappend (scratchbuf
+ intel_syntax
);
3678 /* Capital letters in template are macros. */
3680 putop (const char *template, int sizeflag
)
3685 for (p
= template; *p
; p
++)
3696 if (address_mode
== mode_64bit
)
3704 /* Alternative not valid. */
3705 strcpy (obuf
, "(bad)");
3709 else if (*p
== '\0')
3730 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3736 if (sizeflag
& SUFFIX_ALWAYS
)
3740 if (intel_syntax
&& !alt
)
3742 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
3744 if (sizeflag
& DFLAG
)
3745 *obufp
++ = intel_syntax
? 'd' : 'l';
3747 *obufp
++ = intel_syntax
? 'w' : 's';
3748 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3751 case 'E': /* For jcxz/jecxz */
3752 if (address_mode
== mode_64bit
)
3754 if (sizeflag
& AFLAG
)
3760 if (sizeflag
& AFLAG
)
3762 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3767 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
3769 if (sizeflag
& AFLAG
)
3770 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
3772 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
3773 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3777 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
3779 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
3783 if (!(rex
& REX_MODE64
))
3784 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3789 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
3790 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
3792 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
3795 if (prefixes
& PREFIX_DS
)
3809 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
3818 if (sizeflag
& SUFFIX_ALWAYS
)
3822 if ((prefixes
& PREFIX_FWAIT
) == 0)
3825 used_prefixes
|= PREFIX_FWAIT
;
3828 USED_REX (REX_MODE64
);
3829 if (rex
& REX_MODE64
)
3831 else if (intel_syntax
&& (sizeflag
& DFLAG
))
3835 if (!(rex
& REX_MODE64
))
3836 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3841 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3850 if ((prefixes
& PREFIX_DATA
)
3851 || (rex
& REX_MODE64
)
3852 || (sizeflag
& SUFFIX_ALWAYS
))
3854 USED_REX (REX_MODE64
);
3855 if (rex
& REX_MODE64
)
3859 if (sizeflag
& DFLAG
)
3864 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3870 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3872 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3878 if (intel_syntax
&& !alt
)
3880 USED_REX (REX_MODE64
);
3881 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3883 if (rex
& REX_MODE64
)
3887 if (sizeflag
& DFLAG
)
3888 *obufp
++ = intel_syntax
? 'd' : 'l';
3892 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3896 USED_REX (REX_MODE64
);
3897 if (rex
& REX_MODE64
)
3899 else if (sizeflag
& DFLAG
)
3908 if (intel_syntax
&& !p
[1]
3909 && ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
)))
3911 if (!(rex
& REX_MODE64
))
3912 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3917 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3919 if (sizeflag
& SUFFIX_ALWAYS
)
3927 if (sizeflag
& SUFFIX_ALWAYS
)
3929 if (rex
& REX_MODE64
)
3933 if (sizeflag
& DFLAG
)
3937 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3942 if (prefixes
& PREFIX_DATA
)
3946 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3951 if (rex
& REX_MODE64
)
3953 USED_REX (REX_MODE64
);
3957 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3959 /* operand size flag for cwtl, cbtw */
3960 USED_REX (REX_MODE64
);
3961 if (rex
& REX_MODE64
)
3968 else if (sizeflag
& DFLAG
)
3972 if (!(rex
& REX_MODE64
))
3973 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3983 oappend (const char *s
)
3986 obufp
+= strlen (s
);
3992 if (prefixes
& PREFIX_CS
)
3994 used_prefixes
|= PREFIX_CS
;
3995 oappend ("%cs:" + intel_syntax
);
3997 if (prefixes
& PREFIX_DS
)
3999 used_prefixes
|= PREFIX_DS
;
4000 oappend ("%ds:" + intel_syntax
);
4002 if (prefixes
& PREFIX_SS
)
4004 used_prefixes
|= PREFIX_SS
;
4005 oappend ("%ss:" + intel_syntax
);
4007 if (prefixes
& PREFIX_ES
)
4009 used_prefixes
|= PREFIX_ES
;
4010 oappend ("%es:" + intel_syntax
);
4012 if (prefixes
& PREFIX_FS
)
4014 used_prefixes
|= PREFIX_FS
;
4015 oappend ("%fs:" + intel_syntax
);
4017 if (prefixes
& PREFIX_GS
)
4019 used_prefixes
|= PREFIX_GS
;
4020 oappend ("%gs:" + intel_syntax
);
4025 OP_indirE (int bytemode
, int sizeflag
)
4029 OP_E (bytemode
, sizeflag
);
4033 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4035 if (address_mode
== mode_64bit
)
4043 sprintf_vma (tmp
, disp
);
4044 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4045 strcpy (buf
+ 2, tmp
+ i
);
4049 bfd_signed_vma v
= disp
;
4056 /* Check for possible overflow on 0x8000000000000000. */
4059 strcpy (buf
, "9223372036854775808");
4073 tmp
[28 - i
] = (v
% 10) + '0';
4077 strcpy (buf
, tmp
+ 29 - i
);
4083 sprintf (buf
, "0x%x", (unsigned int) disp
);
4085 sprintf (buf
, "%d", (int) disp
);
4090 intel_operand_size (int bytemode
, int sizeflag
)
4095 oappend ("BYTE PTR ");
4099 oappend ("WORD PTR ");
4102 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4104 oappend ("QWORD PTR ");
4105 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4111 USED_REX (REX_MODE64
);
4112 if (rex
& REX_MODE64
)
4113 oappend ("QWORD PTR ");
4114 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4115 oappend ("DWORD PTR ");
4117 oappend ("WORD PTR ");
4118 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4121 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4123 oappend ("WORD PTR ");
4124 if (!(rex
& REX_MODE64
))
4125 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4128 oappend ("DWORD PTR ");
4131 oappend ("QWORD PTR ");
4134 if (address_mode
== mode_64bit
)
4135 oappend ("QWORD PTR ");
4137 oappend ("DWORD PTR ");
4140 if (sizeflag
& DFLAG
)
4141 oappend ("FWORD PTR ");
4143 oappend ("DWORD PTR ");
4144 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4147 oappend ("TBYTE PTR ");
4150 oappend ("XMMWORD PTR ");
4158 OP_E (int bytemode
, int sizeflag
)
4163 USED_REX (REX_EXTZ
);
4167 /* Skip mod/rm byte. */
4178 oappend (names8rex
[rm
+ add
]);
4180 oappend (names8
[rm
+ add
]);
4183 oappend (names16
[rm
+ add
]);
4186 oappend (names32
[rm
+ add
]);
4189 oappend (names64
[rm
+ add
]);
4192 if (address_mode
== mode_64bit
)
4193 oappend (names64
[rm
+ add
]);
4195 oappend (names32
[rm
+ add
]);
4198 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4200 oappend (names64
[rm
+ add
]);
4201 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4209 USED_REX (REX_MODE64
);
4210 if (rex
& REX_MODE64
)
4211 oappend (names64
[rm
+ add
]);
4212 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4213 oappend (names32
[rm
+ add
]);
4215 oappend (names16
[rm
+ add
]);
4216 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4221 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4229 intel_operand_size (bytemode
, sizeflag
);
4232 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
4247 FETCH_DATA (the_info
, codep
+ 1);
4248 index
= (*codep
>> 3) & 7;
4249 if (address_mode
== mode_64bit
|| index
!= 0x4)
4250 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4251 scale
= (*codep
>> 6) & 3;
4253 USED_REX (REX_EXTY
);
4263 if ((base
& 7) == 5)
4266 if (address_mode
== mode_64bit
&& !havesib
)
4272 FETCH_DATA (the_info
, codep
+ 1);
4274 if ((disp
& 0x80) != 0)
4283 if (mod
!= 0 || (base
& 7) == 5)
4285 print_operand_value (scratchbuf
, !riprel
, disp
);
4286 oappend (scratchbuf
);
4294 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4296 *obufp
++ = open_char
;
4297 if (intel_syntax
&& riprel
)
4301 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4302 ? names64
[base
] : names32
[base
]);
4307 if (!intel_syntax
|| havebase
)
4309 *obufp
++ = separator_char
;
4312 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4313 ? names64
[index
] : names32
[index
]);
4315 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4317 *obufp
++ = scale_char
;
4319 sprintf (scratchbuf
, "%d", 1 << scale
);
4320 oappend (scratchbuf
);
4323 if (intel_syntax
&& disp
)
4325 if ((bfd_signed_vma
) disp
> 0)
4334 disp
= - (bfd_signed_vma
) disp
;
4337 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4338 oappend (scratchbuf
);
4341 *obufp
++ = close_char
;
4344 else if (intel_syntax
)
4346 if (mod
!= 0 || (base
& 7) == 5)
4348 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4349 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4353 oappend (names_seg
[ds_reg
- es_reg
]);
4356 print_operand_value (scratchbuf
, 1, disp
);
4357 oappend (scratchbuf
);
4362 { /* 16 bit address mode */
4369 if ((disp
& 0x8000) != 0)
4374 FETCH_DATA (the_info
, codep
+ 1);
4376 if ((disp
& 0x80) != 0)
4381 if ((disp
& 0x8000) != 0)
4387 if (mod
!= 0 || rm
== 6)
4389 print_operand_value (scratchbuf
, 0, disp
);
4390 oappend (scratchbuf
);
4393 if (mod
!= 0 || rm
!= 6)
4395 *obufp
++ = open_char
;
4397 oappend (index16
[rm
]);
4398 if (intel_syntax
&& disp
)
4400 if ((bfd_signed_vma
) disp
> 0)
4409 disp
= - (bfd_signed_vma
) disp
;
4412 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4413 oappend (scratchbuf
);
4416 *obufp
++ = close_char
;
4419 else if (intel_syntax
)
4421 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4422 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4426 oappend (names_seg
[ds_reg
- es_reg
]);
4429 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
4430 oappend (scratchbuf
);
4436 OP_G (int bytemode
, int sizeflag
)
4439 USED_REX (REX_EXTX
);
4447 oappend (names8rex
[reg
+ add
]);
4449 oappend (names8
[reg
+ add
]);
4452 oappend (names16
[reg
+ add
]);
4455 oappend (names32
[reg
+ add
]);
4458 oappend (names64
[reg
+ add
]);
4463 USED_REX (REX_MODE64
);
4464 if (rex
& REX_MODE64
)
4465 oappend (names64
[reg
+ add
]);
4466 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4467 oappend (names32
[reg
+ add
]);
4469 oappend (names16
[reg
+ add
]);
4470 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4473 if (address_mode
== mode_64bit
)
4474 oappend (names64
[reg
+ add
]);
4476 oappend (names32
[reg
+ add
]);
4479 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4492 FETCH_DATA (the_info
, codep
+ 8);
4493 a
= *codep
++ & 0xff;
4494 a
|= (*codep
++ & 0xff) << 8;
4495 a
|= (*codep
++ & 0xff) << 16;
4496 a
|= (*codep
++ & 0xff) << 24;
4497 b
= *codep
++ & 0xff;
4498 b
|= (*codep
++ & 0xff) << 8;
4499 b
|= (*codep
++ & 0xff) << 16;
4500 b
|= (*codep
++ & 0xff) << 24;
4501 x
= a
+ ((bfd_vma
) b
<< 32);
4509 static bfd_signed_vma
4512 bfd_signed_vma x
= 0;
4514 FETCH_DATA (the_info
, codep
+ 4);
4515 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4516 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4517 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4518 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4522 static bfd_signed_vma
4525 bfd_signed_vma x
= 0;
4527 FETCH_DATA (the_info
, codep
+ 4);
4528 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4529 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4530 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4531 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4533 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4543 FETCH_DATA (the_info
, codep
+ 2);
4544 x
= *codep
++ & 0xff;
4545 x
|= (*codep
++ & 0xff) << 8;
4550 set_op (bfd_vma op
, int riprel
)
4552 op_index
[op_ad
] = op_ad
;
4553 if (address_mode
== mode_64bit
)
4555 op_address
[op_ad
] = op
;
4556 op_riprel
[op_ad
] = riprel
;
4560 /* Mask to get a 32-bit address. */
4561 op_address
[op_ad
] = op
& 0xffffffff;
4562 op_riprel
[op_ad
] = riprel
& 0xffffffff;
4567 OP_REG (int code
, int sizeflag
)
4571 USED_REX (REX_EXTZ
);
4577 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4578 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4579 s
= names16
[code
- ax_reg
+ add
];
4581 case es_reg
: case ss_reg
: case cs_reg
:
4582 case ds_reg
: case fs_reg
: case gs_reg
:
4583 s
= names_seg
[code
- es_reg
+ add
];
4585 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4586 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4589 s
= names8rex
[code
- al_reg
+ add
];
4591 s
= names8
[code
- al_reg
];
4593 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4594 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4595 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4597 s
= names64
[code
- rAX_reg
+ add
];
4600 code
+= eAX_reg
- rAX_reg
;
4602 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4603 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4604 USED_REX (REX_MODE64
);
4605 if (rex
& REX_MODE64
)
4606 s
= names64
[code
- eAX_reg
+ add
];
4607 else if (sizeflag
& DFLAG
)
4608 s
= names32
[code
- eAX_reg
+ add
];
4610 s
= names16
[code
- eAX_reg
+ add
];
4611 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4614 s
= INTERNAL_DISASSEMBLER_ERROR
;
4621 OP_IMREG (int code
, int sizeflag
)
4633 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4634 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4635 s
= names16
[code
- ax_reg
];
4637 case es_reg
: case ss_reg
: case cs_reg
:
4638 case ds_reg
: case fs_reg
: case gs_reg
:
4639 s
= names_seg
[code
- es_reg
];
4641 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4642 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4645 s
= names8rex
[code
- al_reg
];
4647 s
= names8
[code
- al_reg
];
4649 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4650 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4651 USED_REX (REX_MODE64
);
4652 if (rex
& REX_MODE64
)
4653 s
= names64
[code
- eAX_reg
];
4654 else if (sizeflag
& DFLAG
)
4655 s
= names32
[code
- eAX_reg
];
4657 s
= names16
[code
- eAX_reg
];
4658 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4661 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4665 if (!(rex
& REX_MODE64
))
4666 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4669 s
= INTERNAL_DISASSEMBLER_ERROR
;
4676 OP_I (int bytemode
, int sizeflag
)
4679 bfd_signed_vma mask
= -1;
4684 FETCH_DATA (the_info
, codep
+ 1);
4689 if (address_mode
== mode_64bit
)
4696 USED_REX (REX_MODE64
);
4697 if (rex
& REX_MODE64
)
4699 else if (sizeflag
& DFLAG
)
4709 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4720 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4725 scratchbuf
[0] = '$';
4726 print_operand_value (scratchbuf
+ 1, 1, op
);
4727 oappend (scratchbuf
+ intel_syntax
);
4728 scratchbuf
[0] = '\0';
4732 OP_I64 (int bytemode
, int sizeflag
)
4735 bfd_signed_vma mask
= -1;
4737 if (address_mode
!= mode_64bit
)
4739 OP_I (bytemode
, sizeflag
);
4746 FETCH_DATA (the_info
, codep
+ 1);
4751 USED_REX (REX_MODE64
);
4752 if (rex
& REX_MODE64
)
4754 else if (sizeflag
& DFLAG
)
4764 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4771 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4776 scratchbuf
[0] = '$';
4777 print_operand_value (scratchbuf
+ 1, 1, op
);
4778 oappend (scratchbuf
+ intel_syntax
);
4779 scratchbuf
[0] = '\0';
4783 OP_sI (int bytemode
, int sizeflag
)
4786 bfd_signed_vma mask
= -1;
4791 FETCH_DATA (the_info
, codep
+ 1);
4793 if ((op
& 0x80) != 0)
4798 USED_REX (REX_MODE64
);
4799 if (rex
& REX_MODE64
)
4801 else if (sizeflag
& DFLAG
)
4810 if ((op
& 0x8000) != 0)
4813 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4818 if ((op
& 0x8000) != 0)
4822 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4826 scratchbuf
[0] = '$';
4827 print_operand_value (scratchbuf
+ 1, 1, op
);
4828 oappend (scratchbuf
+ intel_syntax
);
4832 OP_J (int bytemode
, int sizeflag
)
4840 FETCH_DATA (the_info
, codep
+ 1);
4842 if ((disp
& 0x80) != 0)
4846 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4851 /* For some reason, a data16 prefix on a jump instruction
4852 means that the pc is masked to 16 bits after the
4853 displacement is added! */
4858 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4861 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4863 print_operand_value (scratchbuf
, 1, disp
);
4864 oappend (scratchbuf
);
4868 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4870 oappend (names_seg
[reg
]);
4874 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4878 if (sizeflag
& DFLAG
)
4888 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4890 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4892 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4893 oappend (scratchbuf
);
4897 OP_OFF (int bytemode
, int sizeflag
)
4901 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4902 intel_operand_size (bytemode
, sizeflag
);
4905 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4912 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4913 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4915 oappend (names_seg
[ds_reg
- es_reg
]);
4919 print_operand_value (scratchbuf
, 1, off
);
4920 oappend (scratchbuf
);
4924 OP_OFF64 (int bytemode
, int sizeflag
)
4928 if (address_mode
!= mode_64bit
4929 || (prefixes
& PREFIX_ADDR
))
4931 OP_OFF (bytemode
, sizeflag
);
4935 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4936 intel_operand_size (bytemode
, sizeflag
);
4943 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4944 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4946 oappend (names_seg
[ds_reg
- es_reg
]);
4950 print_operand_value (scratchbuf
, 1, off
);
4951 oappend (scratchbuf
);
4955 ptr_reg (int code
, int sizeflag
)
4959 *obufp
++ = open_char
;
4960 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4961 if (address_mode
== mode_64bit
)
4963 if (!(sizeflag
& AFLAG
))
4964 s
= names32
[code
- eAX_reg
];
4966 s
= names64
[code
- eAX_reg
];
4968 else if (sizeflag
& AFLAG
)
4969 s
= names32
[code
- eAX_reg
];
4971 s
= names16
[code
- eAX_reg
];
4973 *obufp
++ = close_char
;
4978 OP_ESreg (int code
, int sizeflag
)
4984 case 0x6d: /* insw/insl */
4985 intel_operand_size (z_mode
, sizeflag
);
4987 case 0xa5: /* movsw/movsl/movsq */
4988 case 0xa7: /* cmpsw/cmpsl/cmpsq */
4989 case 0xab: /* stosw/stosl */
4990 case 0xaf: /* scasw/scasl */
4991 intel_operand_size (v_mode
, sizeflag
);
4994 intel_operand_size (b_mode
, sizeflag
);
4997 oappend ("%es:" + intel_syntax
);
4998 ptr_reg (code
, sizeflag
);
5002 OP_DSreg (int code
, int sizeflag
)
5008 case 0x6f: /* outsw/outsl */
5009 intel_operand_size (z_mode
, sizeflag
);
5011 case 0xa5: /* movsw/movsl/movsq */
5012 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5013 case 0xad: /* lodsw/lodsl/lodsq */
5014 intel_operand_size (v_mode
, sizeflag
);
5017 intel_operand_size (b_mode
, sizeflag
);
5027 prefixes
|= PREFIX_DS
;
5029 ptr_reg (code
, sizeflag
);
5033 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5038 USED_REX (REX_EXTX
);
5041 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5043 used_prefixes
|= PREFIX_LOCK
;
5046 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
5047 oappend (scratchbuf
+ intel_syntax
);
5051 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5054 USED_REX (REX_EXTX
);
5058 sprintf (scratchbuf
, "db%d", reg
+ add
);
5060 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
5061 oappend (scratchbuf
);
5065 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5067 sprintf (scratchbuf
, "%%tr%d", reg
);
5068 oappend (scratchbuf
+ intel_syntax
);
5072 OP_Rd (int bytemode
, int sizeflag
)
5075 OP_E (bytemode
, sizeflag
);
5081 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5083 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5084 if (prefixes
& PREFIX_DATA
)
5087 USED_REX (REX_EXTX
);
5090 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5093 sprintf (scratchbuf
, "%%mm%d", reg
);
5094 oappend (scratchbuf
+ intel_syntax
);
5098 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5101 USED_REX (REX_EXTX
);
5104 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5105 oappend (scratchbuf
+ intel_syntax
);
5109 OP_EM (int bytemode
, int sizeflag
)
5113 if (intel_syntax
&& bytemode
== v_mode
)
5115 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5116 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5118 OP_E (bytemode
, sizeflag
);
5122 /* Skip mod/rm byte. */
5125 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5126 if (prefixes
& PREFIX_DATA
)
5130 USED_REX (REX_EXTZ
);
5133 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5136 sprintf (scratchbuf
, "%%mm%d", rm
);
5137 oappend (scratchbuf
+ intel_syntax
);
5140 /* cvt* are the only instructions in sse2 which have
5141 both SSE and MMX operands and also have 0x66 prefix
5142 in their opcode. 0x66 was originally used to differentiate
5143 between SSE and MMX instruction(operands). So we have to handle the
5144 cvt* separately using OP_EMC and OP_MXC */
5146 OP_EMC (int bytemode
, int sizeflag
)
5150 if (intel_syntax
&& bytemode
== v_mode
)
5152 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5153 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5155 OP_E (bytemode
, sizeflag
);
5159 /* Skip mod/rm byte. */
5162 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5163 sprintf (scratchbuf
, "%%mm%d", rm
);
5164 oappend (scratchbuf
+ intel_syntax
);
5168 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5170 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5171 sprintf (scratchbuf
, "%%mm%d", reg
);
5172 oappend (scratchbuf
+ intel_syntax
);
5176 OP_EX (int bytemode
, int sizeflag
)
5181 if (intel_syntax
&& bytemode
== v_mode
)
5183 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
5185 case 0: bytemode
= x_mode
; break;
5186 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
5187 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
5188 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
5189 default: bytemode
= 0; break;
5192 OP_E (bytemode
, sizeflag
);
5195 USED_REX (REX_EXTZ
);
5199 /* Skip mod/rm byte. */
5202 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5203 oappend (scratchbuf
+ intel_syntax
);
5207 OP_MS (int bytemode
, int sizeflag
)
5210 OP_EM (bytemode
, sizeflag
);
5216 OP_XS (int bytemode
, int sizeflag
)
5219 OP_EX (bytemode
, sizeflag
);
5225 OP_M (int bytemode
, int sizeflag
)
5228 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
5230 OP_E (bytemode
, sizeflag
);
5234 OP_0f07 (int bytemode
, int sizeflag
)
5236 if (mod
!= 3 || rm
!= 0)
5239 OP_E (bytemode
, sizeflag
);
5243 OP_0fae (int bytemode
, int sizeflag
)
5248 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5250 if (reg
< 5 || rm
!= 0)
5252 BadOp (); /* bad sfence, mfence, or lfence */
5258 BadOp (); /* bad clflush */
5262 OP_E (bytemode
, sizeflag
);
5265 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5266 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5267 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5271 NOP_Fixup1 (int bytemode
, int sizeflag
)
5273 if (prefixes
== PREFIX_REPZ
)
5274 strcpy (obuf
, "pause");
5275 else if (prefixes
== PREFIX_DATA
5276 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5277 OP_REG (bytemode
, sizeflag
);
5279 strcpy (obuf
, "nop");
5283 NOP_Fixup2 (int bytemode
, int sizeflag
)
5285 if (prefixes
== PREFIX_DATA
5286 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5287 OP_IMREG (bytemode
, sizeflag
);
5290 static const char *const Suffix3DNow
[] = {
5291 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5292 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5293 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5294 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5295 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5296 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5297 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5298 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5299 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5300 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5301 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5302 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5303 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5304 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5305 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5306 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5307 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5308 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5309 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5310 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5311 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5312 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5313 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5314 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5315 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5316 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5317 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5318 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5319 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5320 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5321 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5322 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5323 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5324 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5325 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5326 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5327 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5328 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5329 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5330 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5331 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5332 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5333 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5334 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5335 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5336 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5337 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5338 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5339 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5340 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5341 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5342 /* CC */ NULL
, NULL
, NULL
, NULL
,
5343 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5344 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5345 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5346 /* DC */ NULL
, NULL
, NULL
, NULL
,
5347 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5348 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5349 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5350 /* EC */ NULL
, NULL
, NULL
, NULL
,
5351 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5352 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5353 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5354 /* FC */ NULL
, NULL
, NULL
, NULL
,
5358 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5360 const char *mnemonic
;
5362 FETCH_DATA (the_info
, codep
+ 1);
5363 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5364 place where an 8-bit immediate would normally go. ie. the last
5365 byte of the instruction. */
5366 obufp
= obuf
+ strlen (obuf
);
5367 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5372 /* Since a variable sized modrm/sib chunk is between the start
5373 of the opcode (0x0f0f) and the opcode suffix, we need to do
5374 all the modrm processing first, and don't know until now that
5375 we have a bad opcode. This necessitates some cleaning up. */
5382 static const char *simd_cmp_op
[] = {
5394 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5396 unsigned int cmp_type
;
5398 FETCH_DATA (the_info
, codep
+ 1);
5399 obufp
= obuf
+ strlen (obuf
);
5400 cmp_type
= *codep
++ & 0xff;
5403 char suffix1
= 'p', suffix2
= 's';
5404 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5405 if (prefixes
& PREFIX_REPZ
)
5409 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5410 if (prefixes
& PREFIX_DATA
)
5414 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5415 if (prefixes
& PREFIX_REPNZ
)
5416 suffix1
= 's', suffix2
= 'd';
5419 sprintf (scratchbuf
, "cmp%s%c%c",
5420 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5421 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5422 oappend (scratchbuf
);
5426 /* We have a bad extension byte. Clean up. */
5434 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
5436 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5437 forms of these instructions. */
5440 char *p
= obuf
+ strlen (obuf
);
5443 *(p
- 1) = *(p
- 2);
5444 *(p
- 2) = *(p
- 3);
5445 *(p
- 3) = extrachar
;
5450 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5452 if (mod
== 3 && reg
== 1 && rm
<= 1)
5454 /* Override "sidt". */
5455 size_t olen
= strlen (obuf
);
5456 char *p
= obuf
+ olen
- 4;
5457 const char **names
= (address_mode
== mode_64bit
5458 ? names64
: names32
);
5460 /* We might have a suffix when disassembling with -Msuffix. */
5464 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5466 && (prefixes
& PREFIX_ADDR
)
5469 && CONST_STRNEQ (p
- 7, "addr")
5470 && (CONST_STRNEQ (p
- 3, "16")
5471 || CONST_STRNEQ (p
- 3, "32")))
5476 /* mwait %eax,%ecx */
5477 strcpy (p
, "mwait");
5479 strcpy (op1out
, names
[0]);
5483 /* monitor %eax,%ecx,%edx" */
5484 strcpy (p
, "monitor");
5487 const char **op1_names
;
5488 if (!(prefixes
& PREFIX_ADDR
))
5489 op1_names
= (address_mode
== mode_16bit
5493 op1_names
= (address_mode
!= mode_32bit
5494 ? names32
: names16
);
5495 used_prefixes
|= PREFIX_ADDR
;
5497 strcpy (op1out
, op1_names
[0]);
5498 strcpy (op3out
, names
[2]);
5503 strcpy (op2out
, names
[1]);
5514 SVME_Fixup (int bytemode
, int sizeflag
)
5546 OP_M (bytemode
, sizeflag
);
5549 /* Override "lidt". */
5550 p
= obuf
+ strlen (obuf
) - 4;
5551 /* We might have a suffix. */
5555 if (!(prefixes
& PREFIX_ADDR
))
5560 used_prefixes
|= PREFIX_ADDR
;
5564 strcpy (op2out
, names32
[1]);
5570 *obufp
++ = open_char
;
5571 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
5575 strcpy (obufp
, alt
);
5576 obufp
+= strlen (alt
);
5577 *obufp
++ = close_char
;
5584 INVLPG_Fixup (int bytemode
, int sizeflag
)
5597 OP_M (bytemode
, sizeflag
);
5600 /* Override "invlpg". */
5601 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
5608 /* Throw away prefixes and 1st. opcode byte. */
5609 codep
= insn_codep
+ 1;
5614 SEG_Fixup (int extrachar
, int sizeflag
)
5618 /* We need to add a proper suffix with
5629 if (prefixes
& PREFIX_DATA
)
5633 USED_REX (REX_MODE64
);
5634 if (rex
& REX_MODE64
)
5639 strcat (obuf
, suffix
);
5643 /* We need to fix the suffix for
5650 Override "mov[l|q]". */
5651 char *p
= obuf
+ strlen (obuf
) - 1;
5653 /* We might not have a suffix. */
5659 OP_E (extrachar
, sizeflag
);
5663 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5665 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
5667 /* Override "sgdt". */
5668 char *p
= obuf
+ strlen (obuf
) - 4;
5670 /* We might have a suffix when disassembling with -Msuffix. */
5677 strcpy (p
, "vmcall");
5680 strcpy (p
, "vmlaunch");
5683 strcpy (p
, "vmresume");
5686 strcpy (p
, "vmxoff");
5697 OP_VMX (int bytemode
, int sizeflag
)
5699 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
5700 if (prefixes
& PREFIX_DATA
)
5701 strcpy (obuf
, "vmclear");
5702 else if (prefixes
& PREFIX_REPZ
)
5703 strcpy (obuf
, "vmxon");
5705 strcpy (obuf
, "vmptrld");
5706 OP_E (bytemode
, sizeflag
);
5710 REP_Fixup (int bytemode
, int sizeflag
)
5712 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5716 if (prefixes
& PREFIX_REPZ
)
5717 switch (*insn_codep
)
5719 case 0x6e: /* outsb */
5720 case 0x6f: /* outsw/outsl */
5721 case 0xa4: /* movsb */
5722 case 0xa5: /* movsw/movsl/movsq */
5728 case 0xaa: /* stosb */
5729 case 0xab: /* stosw/stosl/stosq */
5730 case 0xac: /* lodsb */
5731 case 0xad: /* lodsw/lodsl/lodsq */
5732 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5737 case 0x6c: /* insb */
5738 case 0x6d: /* insl/insw */
5754 olen
= strlen (obuf
);
5755 p
= obuf
+ olen
- ilen
- 1 - 4;
5756 /* Handle "repz [addr16|addr32]". */
5757 if ((prefixes
& PREFIX_ADDR
))
5760 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
5768 OP_IMREG (bytemode
, sizeflag
);
5771 OP_ESreg (bytemode
, sizeflag
);
5774 OP_DSreg (bytemode
, sizeflag
);