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 VMX_Fixup (int, int);
106 static void REP_Fixup (int, int);
109 /* Points to first byte not fetched. */
110 bfd_byte
*max_fetched
;
111 bfd_byte the_buffer
[MAXLEN
];
117 /* The opcode for the fwait instruction, which we treat as a prefix
119 #define FWAIT_OPCODE (0x9b)
128 enum address_mode address_mode
;
130 /* Flags for the prefixes for the current instruction. See below. */
133 /* REX prefix the current instruction. See below. */
135 /* Bits of REX we've already used. */
141 /* Mark parts used in the REX prefix. When we are testing for
142 empty prefix (for 8bit register REX extension), just mask it
143 out. Otherwise test for REX bit is excuse for existence of REX
144 only in case value is nonzero. */
145 #define USED_REX(value) \
148 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
153 /* Flags for prefixes which we somehow handled when printing the
154 current instruction. */
155 static int used_prefixes
;
157 /* Flags stored in PREFIXES. */
158 #define PREFIX_REPZ 1
159 #define PREFIX_REPNZ 2
160 #define PREFIX_LOCK 4
162 #define PREFIX_SS 0x10
163 #define PREFIX_DS 0x20
164 #define PREFIX_ES 0x40
165 #define PREFIX_FS 0x80
166 #define PREFIX_GS 0x100
167 #define PREFIX_DATA 0x200
168 #define PREFIX_ADDR 0x400
169 #define PREFIX_FWAIT 0x800
171 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
172 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
174 #define FETCH_DATA(info, addr) \
175 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
176 ? 1 : fetch_data ((info), (addr)))
179 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
182 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
183 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
185 if (addr
<= priv
->the_buffer
+ MAXLEN
)
186 status
= (*info
->read_memory_func
) (start
,
188 addr
- priv
->max_fetched
,
194 /* If we did manage to read at least one byte, then
195 print_insn_i386 will do something sensible. Otherwise, print
196 an error. We do that here because this is where we know
198 if (priv
->max_fetched
== priv
->the_buffer
)
199 (*info
->memory_error_func
) (status
, start
, info
);
200 longjmp (priv
->bailout
, 1);
203 priv
->max_fetched
= addr
;
209 #define Eb OP_E, b_mode
210 #define Ev OP_E, v_mode
211 #define Ed OP_E, d_mode
212 #define Edq OP_E, dq_mode
213 #define Edqw OP_E, dqw_mode
214 #define indirEv OP_indirE, stack_v_mode
215 #define indirEp OP_indirE, f_mode
216 #define stackEv OP_E, stack_v_mode
217 #define Em OP_E, m_mode
218 #define Ew OP_E, w_mode
219 #define M OP_M, 0 /* lea, lgdt, etc. */
220 #define Ma OP_M, v_mode
221 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
222 #define Mq OP_M, q_mode
223 #define Gb OP_G, b_mode
224 #define Gv OP_G, v_mode
225 #define Gd OP_G, d_mode
226 #define Gdq OP_G, dq_mode
227 #define Gm OP_G, m_mode
228 #define Gw OP_G, w_mode
229 #define Rd OP_Rd, d_mode
230 #define Rm OP_Rd, m_mode
231 #define Ib OP_I, b_mode
232 #define sIb OP_sI, b_mode /* sign extened byte */
233 #define Iv OP_I, v_mode
234 #define Iq OP_I, q_mode
235 #define Iv64 OP_I64, v_mode
236 #define Iw OP_I, w_mode
237 #define I1 OP_I, const_1_mode
238 #define Jb OP_J, b_mode
239 #define Jv OP_J, v_mode
240 #define Cm OP_C, m_mode
241 #define Dm OP_D, m_mode
242 #define Td OP_T, d_mode
244 #define RMeAX OP_REG, eAX_reg
245 #define RMeBX OP_REG, eBX_reg
246 #define RMeCX OP_REG, eCX_reg
247 #define RMeDX OP_REG, eDX_reg
248 #define RMeSP OP_REG, eSP_reg
249 #define RMeBP OP_REG, eBP_reg
250 #define RMeSI OP_REG, eSI_reg
251 #define RMeDI OP_REG, eDI_reg
252 #define RMrAX OP_REG, rAX_reg
253 #define RMrBX OP_REG, rBX_reg
254 #define RMrCX OP_REG, rCX_reg
255 #define RMrDX OP_REG, rDX_reg
256 #define RMrSP OP_REG, rSP_reg
257 #define RMrBP OP_REG, rBP_reg
258 #define RMrSI OP_REG, rSI_reg
259 #define RMrDI OP_REG, rDI_reg
260 #define RMAL OP_REG, al_reg
261 #define RMAL OP_REG, al_reg
262 #define RMCL OP_REG, cl_reg
263 #define RMDL OP_REG, dl_reg
264 #define RMBL OP_REG, bl_reg
265 #define RMAH OP_REG, ah_reg
266 #define RMCH OP_REG, ch_reg
267 #define RMDH OP_REG, dh_reg
268 #define RMBH OP_REG, bh_reg
269 #define RMAX OP_REG, ax_reg
270 #define RMDX OP_REG, dx_reg
272 #define eAX OP_IMREG, eAX_reg
273 #define eBX OP_IMREG, eBX_reg
274 #define eCX OP_IMREG, eCX_reg
275 #define eDX OP_IMREG, eDX_reg
276 #define eSP OP_IMREG, eSP_reg
277 #define eBP OP_IMREG, eBP_reg
278 #define eSI OP_IMREG, eSI_reg
279 #define eDI OP_IMREG, eDI_reg
280 #define AL OP_IMREG, al_reg
281 #define CL OP_IMREG, cl_reg
282 #define DL OP_IMREG, dl_reg
283 #define BL OP_IMREG, bl_reg
284 #define AH OP_IMREG, ah_reg
285 #define CH OP_IMREG, ch_reg
286 #define DH OP_IMREG, dh_reg
287 #define BH OP_IMREG, bh_reg
288 #define AX OP_IMREG, ax_reg
289 #define DX OP_IMREG, dx_reg
290 #define zAX OP_IMREG, z_mode_ax_reg
291 #define indirDX OP_IMREG, indir_dx_reg
293 #define Sw OP_SEG, w_mode
294 #define Sv OP_SEG, v_mode
296 #define Ob OP_OFF64, b_mode
297 #define Ov OP_OFF64, v_mode
298 #define Xb OP_DSreg, eSI_reg
299 #define Xv OP_DSreg, eSI_reg
300 #define Xz OP_DSreg, eSI_reg
301 #define Yb OP_ESreg, eDI_reg
302 #define Yv OP_ESreg, eDI_reg
303 #define DSBX OP_DSreg, eBX_reg
305 #define es OP_REG, es_reg
306 #define ss OP_REG, ss_reg
307 #define cs OP_REG, cs_reg
308 #define ds OP_REG, ds_reg
309 #define fs OP_REG, fs_reg
310 #define gs OP_REG, gs_reg
314 #define EM OP_EM, v_mode
315 #define EX OP_EX, v_mode
316 #define MS OP_MS, v_mode
317 #define XS OP_XS, v_mode
318 #define EMC OP_EMC, v_mode
319 #define MXC OP_MXC, 0
320 #define VM OP_VMX, q_mode
321 #define OPSUF OP_3DNowSuffix, 0
322 #define OPSIMD OP_SIMD_Suffix, 0
324 /* Used handle "rep" prefix for string instructions. */
325 #define Xbr REP_Fixup, eSI_reg
326 #define Xvr REP_Fixup, eSI_reg
327 #define Ybr REP_Fixup, eDI_reg
328 #define Yvr REP_Fixup, eDI_reg
329 #define Yzr REP_Fixup, eDI_reg
330 #define indirDXr REP_Fixup, indir_dx_reg
331 #define ALr REP_Fixup, al_reg
332 #define eAXr REP_Fixup, eAX_reg
334 #define cond_jump_flag NULL, cond_jump_mode
335 #define loop_jcxz_flag NULL, loop_jcxz_mode
337 /* bits in sizeflag */
338 #define SUFFIX_ALWAYS 4
342 #define b_mode 1 /* byte operand */
343 #define v_mode 2 /* operand size depends on prefixes */
344 #define w_mode 3 /* word operand */
345 #define d_mode 4 /* double word operand */
346 #define q_mode 5 /* quad word operand */
347 #define t_mode 6 /* ten-byte operand */
348 #define x_mode 7 /* 16-byte XMM operand */
349 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
350 #define cond_jump_mode 9
351 #define loop_jcxz_mode 10
352 #define dq_mode 11 /* operand size depends on REX prefixes. */
353 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
354 #define f_mode 13 /* 4- or 6-byte pointer operand */
355 #define const_1_mode 14
356 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
357 #define z_mode 16 /* non-quad operand size depends on prefixes */
402 #define z_mode_ax_reg 149
403 #define indir_dx_reg 150
407 #define USE_PREFIX_USER_TABLE 3
408 #define X86_64_SPECIAL 4
409 #define IS_3BYTE_OPCODE 5
411 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
413 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
414 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
415 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
416 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
417 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
418 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
419 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
420 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
421 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
422 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
423 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
424 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
425 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
426 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
427 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
428 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
429 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
430 #define GRP11_C6 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
431 #define GRP11_C7 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
432 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
433 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
434 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
435 #define GRP15 NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
436 #define GRP16 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
437 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
438 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
439 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
441 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
442 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
443 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
444 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
445 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
446 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
447 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
448 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
449 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
450 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
451 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
452 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
453 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
454 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
455 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
456 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
457 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
458 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
459 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
460 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
461 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
462 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
463 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
464 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
465 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
466 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
467 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
468 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
469 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
470 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
471 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
472 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
473 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
474 #define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
475 #define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
476 #define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
477 #define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
478 #define PREGRP37 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 37, NULL, 0, NULL, 0
481 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
482 #define X86_64_1 NULL, NULL, X86_64_SPECIAL, NULL, 1, NULL, 0, NULL, 0
483 #define X86_64_2 NULL, NULL, X86_64_SPECIAL, NULL, 2, NULL, 0, NULL, 0
484 #define X86_64_3 NULL, NULL, X86_64_SPECIAL, NULL, 3, NULL, 0, NULL, 0
486 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
487 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
489 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
503 /* Upper case letters in the instruction names here are macros.
504 'A' => print 'b' if no register operands or suffix_always is true
505 'B' => print 'b' if suffix_always is true
506 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
508 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
509 . suffix_always is true
510 'E' => print 'e' if 32-bit form of jcxz
511 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
512 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
513 'H' => print ",pt" or ",pn" branch hint
514 'I' => honor following macro letter even in Intel mode (implemented only
515 . for some of the macro letters)
517 'L' => print 'l' if suffix_always is true
518 'N' => print 'n' if instruction has no wait "prefix"
519 'O' => print 'd' or 'o' (or 'q' in Intel mode)
520 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
521 . or suffix_always is true. print 'q' if rex prefix is present.
522 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
524 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
525 'S' => print 'w', 'l' or 'q' if suffix_always is true
526 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
527 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
528 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
529 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
530 'X' => print 's', 'd' depending on data16 prefix (for XMM)
531 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
532 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
534 Many of the above letters print nothing in Intel mode. See "putop"
537 Braces '{' and '}', and vertical bars '|', indicate alternative
538 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
539 modes. In cases where there are only two alternatives, the X86_64
540 instruction is reserved, and "(bad)" is printed.
543 static const struct dis386 dis386
[] = {
545 { "addB", Eb
, Gb
, XX
, XX
},
546 { "addS", Ev
, Gv
, XX
, XX
},
547 { "addB", Gb
, Eb
, XX
, XX
},
548 { "addS", Gv
, Ev
, XX
, XX
},
549 { "addB", AL
, Ib
, XX
, XX
},
550 { "addS", eAX
, Iv
, XX
, XX
},
551 { "push{T|}", es
, XX
, XX
, XX
},
552 { "pop{T|}", es
, XX
, XX
, XX
},
554 { "orB", Eb
, Gb
, XX
, XX
},
555 { "orS", Ev
, Gv
, XX
, XX
},
556 { "orB", Gb
, Eb
, XX
, XX
},
557 { "orS", Gv
, Ev
, XX
, XX
},
558 { "orB", AL
, Ib
, XX
, XX
},
559 { "orS", eAX
, Iv
, XX
, XX
},
560 { "push{T|}", cs
, XX
, XX
, XX
},
561 { "(bad)", XX
, XX
, XX
, XX
}, /* 0x0f extended opcode escape */
563 { "adcB", Eb
, Gb
, XX
, XX
},
564 { "adcS", Ev
, Gv
, XX
, XX
},
565 { "adcB", Gb
, Eb
, XX
, XX
},
566 { "adcS", Gv
, Ev
, XX
, XX
},
567 { "adcB", AL
, Ib
, XX
, XX
},
568 { "adcS", eAX
, Iv
, XX
, XX
},
569 { "push{T|}", ss
, XX
, XX
, XX
},
570 { "pop{T|}", ss
, XX
, XX
, XX
},
572 { "sbbB", Eb
, Gb
, XX
, XX
},
573 { "sbbS", Ev
, Gv
, XX
, XX
},
574 { "sbbB", Gb
, Eb
, XX
, XX
},
575 { "sbbS", Gv
, Ev
, XX
, XX
},
576 { "sbbB", AL
, Ib
, XX
, XX
},
577 { "sbbS", eAX
, Iv
, XX
, XX
},
578 { "push{T|}", ds
, XX
, XX
, XX
},
579 { "pop{T|}", ds
, XX
, XX
, XX
},
581 { "andB", Eb
, Gb
, XX
, XX
},
582 { "andS", Ev
, Gv
, XX
, XX
},
583 { "andB", Gb
, Eb
, XX
, XX
},
584 { "andS", Gv
, Ev
, XX
, XX
},
585 { "andB", AL
, Ib
, XX
, XX
},
586 { "andS", eAX
, Iv
, XX
, XX
},
587 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG ES prefix */
588 { "daa{|}", XX
, XX
, XX
, XX
},
590 { "subB", Eb
, Gb
, XX
, XX
},
591 { "subS", Ev
, Gv
, XX
, XX
},
592 { "subB", Gb
, Eb
, XX
, XX
},
593 { "subS", Gv
, Ev
, XX
, XX
},
594 { "subB", AL
, Ib
, XX
, XX
},
595 { "subS", eAX
, Iv
, XX
, XX
},
596 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG CS prefix */
597 { "das{|}", XX
, XX
, XX
, XX
},
599 { "xorB", Eb
, Gb
, XX
, XX
},
600 { "xorS", Ev
, Gv
, XX
, XX
},
601 { "xorB", Gb
, Eb
, XX
, XX
},
602 { "xorS", Gv
, Ev
, XX
, XX
},
603 { "xorB", AL
, Ib
, XX
, XX
},
604 { "xorS", eAX
, Iv
, XX
, XX
},
605 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG SS prefix */
606 { "aaa{|}", XX
, XX
, XX
, XX
},
608 { "cmpB", Eb
, Gb
, XX
, XX
},
609 { "cmpS", Ev
, Gv
, XX
, XX
},
610 { "cmpB", Gb
, Eb
, XX
, XX
},
611 { "cmpS", Gv
, Ev
, XX
, XX
},
612 { "cmpB", AL
, Ib
, XX
, XX
},
613 { "cmpS", eAX
, Iv
, XX
, XX
},
614 { "(bad)", XX
, XX
, XX
, XX
}, /* SEG DS prefix */
615 { "aas{|}", XX
, XX
, XX
, XX
},
617 { "inc{S|}", RMeAX
, XX
, XX
, XX
},
618 { "inc{S|}", RMeCX
, XX
, XX
, XX
},
619 { "inc{S|}", RMeDX
, XX
, XX
, XX
},
620 { "inc{S|}", RMeBX
, XX
, XX
, XX
},
621 { "inc{S|}", RMeSP
, XX
, XX
, XX
},
622 { "inc{S|}", RMeBP
, XX
, XX
, XX
},
623 { "inc{S|}", RMeSI
, XX
, XX
, XX
},
624 { "inc{S|}", RMeDI
, XX
, XX
, XX
},
626 { "dec{S|}", RMeAX
, XX
, XX
, XX
},
627 { "dec{S|}", RMeCX
, XX
, XX
, XX
},
628 { "dec{S|}", RMeDX
, XX
, XX
, XX
},
629 { "dec{S|}", RMeBX
, XX
, XX
, XX
},
630 { "dec{S|}", RMeSP
, XX
, XX
, XX
},
631 { "dec{S|}", RMeBP
, XX
, XX
, XX
},
632 { "dec{S|}", RMeSI
, XX
, XX
, XX
},
633 { "dec{S|}", RMeDI
, XX
, XX
, XX
},
635 { "pushV", RMrAX
, XX
, XX
, XX
},
636 { "pushV", RMrCX
, XX
, XX
, XX
},
637 { "pushV", RMrDX
, XX
, XX
, XX
},
638 { "pushV", RMrBX
, XX
, XX
, XX
},
639 { "pushV", RMrSP
, XX
, XX
, XX
},
640 { "pushV", RMrBP
, XX
, XX
, XX
},
641 { "pushV", RMrSI
, XX
, XX
, XX
},
642 { "pushV", RMrDI
, XX
, XX
, XX
},
644 { "popV", RMrAX
, XX
, XX
, XX
},
645 { "popV", RMrCX
, XX
, XX
, XX
},
646 { "popV", RMrDX
, XX
, XX
, XX
},
647 { "popV", RMrBX
, XX
, XX
, XX
},
648 { "popV", RMrSP
, XX
, XX
, XX
},
649 { "popV", RMrBP
, XX
, XX
, XX
},
650 { "popV", RMrSI
, XX
, XX
, XX
},
651 { "popV", RMrDI
, XX
, XX
, XX
},
657 { "(bad)", XX
, XX
, XX
, XX
}, /* seg fs */
658 { "(bad)", XX
, XX
, XX
, XX
}, /* seg gs */
659 { "(bad)", XX
, XX
, XX
, XX
}, /* op size prefix */
660 { "(bad)", XX
, XX
, XX
, XX
}, /* adr size prefix */
662 { "pushT", Iq
, XX
, XX
, XX
},
663 { "imulS", Gv
, Ev
, Iv
, XX
},
664 { "pushT", sIb
, XX
, XX
, XX
},
665 { "imulS", Gv
, Ev
, sIb
, XX
},
666 { "ins{b||b|}", Ybr
, indirDX
, XX
, XX
},
667 { "ins{R||G|}", Yzr
, indirDX
, XX
, XX
},
668 { "outs{b||b|}", indirDXr
, Xb
, XX
, XX
},
669 { "outs{R||G|}", indirDXr
, Xz
, XX
, XX
},
671 { "joH", Jb
, XX
, cond_jump_flag
, XX
},
672 { "jnoH", Jb
, XX
, cond_jump_flag
, XX
},
673 { "jbH", Jb
, XX
, cond_jump_flag
, XX
},
674 { "jaeH", Jb
, XX
, cond_jump_flag
, XX
},
675 { "jeH", Jb
, XX
, cond_jump_flag
, XX
},
676 { "jneH", Jb
, XX
, cond_jump_flag
, XX
},
677 { "jbeH", Jb
, XX
, cond_jump_flag
, XX
},
678 { "jaH", Jb
, XX
, cond_jump_flag
, XX
},
680 { "jsH", Jb
, XX
, cond_jump_flag
, XX
},
681 { "jnsH", Jb
, XX
, cond_jump_flag
, XX
},
682 { "jpH", Jb
, XX
, cond_jump_flag
, XX
},
683 { "jnpH", Jb
, XX
, cond_jump_flag
, XX
},
684 { "jlH", Jb
, XX
, cond_jump_flag
, XX
},
685 { "jgeH", Jb
, XX
, cond_jump_flag
, XX
},
686 { "jleH", Jb
, XX
, cond_jump_flag
, XX
},
687 { "jgH", Jb
, XX
, cond_jump_flag
, XX
},
691 { "(bad)", XX
, XX
, XX
, XX
},
693 { "testB", Eb
, Gb
, XX
, XX
},
694 { "testS", Ev
, Gv
, XX
, XX
},
695 { "xchgB", Eb
, Gb
, XX
, XX
},
696 { "xchgS", Ev
, Gv
, XX
, XX
},
698 { "movB", Eb
, Gb
, XX
, XX
},
699 { "movS", Ev
, Gv
, XX
, XX
},
700 { "movB", Gb
, Eb
, XX
, XX
},
701 { "movS", Gv
, Ev
, XX
, XX
},
702 { "movD", Sv
, Sw
, XX
, XX
},
703 { "leaS", Gv
, M
, XX
, XX
},
704 { "movD", Sw
, Sv
, XX
, XX
},
705 { "popU", stackEv
, XX
, XX
, XX
},
707 { "xchgS", NOP_Fixup1
, eAX_reg
, NOP_Fixup2
, eAX_reg
, XX
, XX
},
708 { "xchgS", RMeCX
, eAX
, XX
, XX
},
709 { "xchgS", RMeDX
, eAX
, XX
, XX
},
710 { "xchgS", RMeBX
, eAX
, XX
, XX
},
711 { "xchgS", RMeSP
, eAX
, XX
, XX
},
712 { "xchgS", RMeBP
, eAX
, XX
, XX
},
713 { "xchgS", RMeSI
, eAX
, XX
, XX
},
714 { "xchgS", RMeDI
, eAX
, XX
, XX
},
716 { "cW{t||t|}R", XX
, XX
, XX
, XX
},
717 { "cR{t||t|}O", XX
, XX
, XX
, XX
},
718 { "Jcall{T|}", Ap
, XX
, XX
, XX
},
719 { "(bad)", XX
, XX
, XX
, XX
}, /* fwait */
720 { "pushfT", XX
, XX
, XX
, XX
},
721 { "popfT", XX
, XX
, XX
, XX
},
722 { "sahf{|}", XX
, XX
, XX
, XX
},
723 { "lahf{|}", XX
, XX
, XX
, XX
},
725 { "movB", AL
, Ob
, XX
, XX
},
726 { "movS", eAX
, Ov
, XX
, XX
},
727 { "movB", Ob
, AL
, XX
, XX
},
728 { "movS", Ov
, eAX
, XX
, XX
},
729 { "movs{b||b|}", Ybr
, Xb
, XX
, XX
},
730 { "movs{R||R|}", Yvr
, Xv
, XX
, XX
},
731 { "cmps{b||b|}", Xb
, Yb
, XX
, XX
},
732 { "cmps{R||R|}", Xv
, Yv
, XX
, XX
},
734 { "testB", AL
, Ib
, XX
, XX
},
735 { "testS", eAX
, Iv
, XX
, XX
},
736 { "stosB", Ybr
, AL
, XX
, XX
},
737 { "stosS", Yvr
, eAX
, XX
, XX
},
738 { "lodsB", ALr
, Xb
, XX
, XX
},
739 { "lodsS", eAXr
, Xv
, XX
, XX
},
740 { "scasB", AL
, Yb
, XX
, XX
},
741 { "scasS", eAX
, Yv
, XX
, XX
},
743 { "movB", RMAL
, Ib
, XX
, XX
},
744 { "movB", RMCL
, Ib
, XX
, XX
},
745 { "movB", RMDL
, Ib
, XX
, XX
},
746 { "movB", RMBL
, Ib
, XX
, XX
},
747 { "movB", RMAH
, Ib
, XX
, XX
},
748 { "movB", RMCH
, Ib
, XX
, XX
},
749 { "movB", RMDH
, Ib
, XX
, XX
},
750 { "movB", RMBH
, Ib
, XX
, XX
},
752 { "movS", RMeAX
, Iv64
, XX
, XX
},
753 { "movS", RMeCX
, Iv64
, XX
, XX
},
754 { "movS", RMeDX
, Iv64
, XX
, XX
},
755 { "movS", RMeBX
, Iv64
, XX
, XX
},
756 { "movS", RMeSP
, Iv64
, XX
, XX
},
757 { "movS", RMeBP
, Iv64
, XX
, XX
},
758 { "movS", RMeSI
, Iv64
, XX
, XX
},
759 { "movS", RMeDI
, Iv64
, XX
, XX
},
763 { "retT", Iw
, XX
, XX
, XX
},
764 { "retT", XX
, XX
, XX
, XX
},
765 { "les{S|}", Gv
, Mp
, XX
, XX
},
766 { "ldsS", Gv
, Mp
, XX
, XX
},
770 { "enterT", Iw
, Ib
, XX
, XX
},
771 { "leaveT", XX
, XX
, XX
, XX
},
772 { "lretP", Iw
, XX
, XX
, XX
},
773 { "lretP", XX
, XX
, XX
, XX
},
774 { "int3", XX
, XX
, XX
, XX
},
775 { "int", Ib
, XX
, XX
, XX
},
776 { "into{|}", XX
, XX
, XX
, XX
},
777 { "iretP", XX
, XX
, XX
, XX
},
783 { "aam{|}", sIb
, XX
, XX
, XX
},
784 { "aad{|}", sIb
, XX
, XX
, XX
},
785 { "(bad)", XX
, XX
, XX
, XX
},
786 { "xlat", DSBX
, XX
, XX
, XX
},
797 { "loopneFH", Jb
, XX
, loop_jcxz_flag
, XX
},
798 { "loopeFH", Jb
, XX
, loop_jcxz_flag
, XX
},
799 { "loopFH", Jb
, XX
, loop_jcxz_flag
, XX
},
800 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
, XX
},
801 { "inB", AL
, Ib
, XX
, XX
},
802 { "inG", zAX
, Ib
, XX
, XX
},
803 { "outB", Ib
, AL
, XX
, XX
},
804 { "outG", Ib
, zAX
, XX
, XX
},
806 { "callT", Jv
, XX
, XX
, XX
},
807 { "jmpT", Jv
, XX
, XX
, XX
},
808 { "Jjmp{T|}", Ap
, XX
, XX
, XX
},
809 { "jmp", Jb
, XX
, XX
, XX
},
810 { "inB", AL
, indirDX
, XX
, XX
},
811 { "inG", zAX
, indirDX
, XX
, XX
},
812 { "outB", indirDX
, AL
, XX
, XX
},
813 { "outG", indirDX
, zAX
, XX
, XX
},
815 { "(bad)", XX
, XX
, XX
, XX
}, /* lock prefix */
816 { "icebp", XX
, XX
, XX
, XX
},
817 { "(bad)", XX
, XX
, XX
, XX
}, /* repne */
818 { "(bad)", XX
, XX
, XX
, XX
}, /* repz */
819 { "hlt", XX
, XX
, XX
, XX
},
820 { "cmc", XX
, XX
, XX
, XX
},
824 { "clc", XX
, XX
, XX
, XX
},
825 { "stc", XX
, XX
, XX
, XX
},
826 { "cli", XX
, XX
, XX
, XX
},
827 { "sti", XX
, XX
, XX
, XX
},
828 { "cld", XX
, XX
, XX
, XX
},
829 { "std", XX
, XX
, XX
, XX
},
834 static const struct dis386 dis386_twobyte
[] = {
838 { "larS", Gv
, Ew
, XX
, XX
},
839 { "lslS", Gv
, Ew
, XX
, XX
},
840 { "(bad)", XX
, XX
, XX
, XX
},
841 { "syscall", XX
, XX
, XX
, XX
},
842 { "clts", XX
, XX
, XX
, XX
},
843 { "sysretP", XX
, XX
, XX
, XX
},
845 { "invd", XX
, XX
, XX
, XX
},
846 { "wbinvd", XX
, XX
, XX
, XX
},
847 { "(bad)", XX
, XX
, XX
, XX
},
848 { "ud2a", XX
, XX
, XX
, XX
},
849 { "(bad)", XX
, XX
, XX
, XX
},
851 { "femms", XX
, XX
, XX
, XX
},
852 { "", MX
, EM
, OPSUF
, XX
}, /* See OP_3DNowSuffix. */
857 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h', XX
},
858 { "unpcklpX", XM
, EX
, XX
, XX
},
859 { "unpckhpX", XM
, EX
, XX
, XX
},
861 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l', XX
},
864 { "(bad)", XX
, XX
, XX
, XX
},
865 { "(bad)", XX
, XX
, XX
, XX
},
866 { "(bad)", XX
, XX
, XX
, XX
},
867 { "(bad)", XX
, XX
, XX
, XX
},
868 { "(bad)", XX
, XX
, XX
, XX
},
869 { "(bad)", XX
, XX
, XX
, XX
},
870 { "nopQ", Ev
, XX
, XX
, XX
},
872 { "movZ", Rm
, Cm
, XX
, XX
},
873 { "movZ", Rm
, Dm
, XX
, XX
},
874 { "movZ", Cm
, Rm
, XX
, XX
},
875 { "movZ", Dm
, Rm
, XX
, XX
},
876 { "movL", Rd
, Td
, XX
, XX
},
877 { "(bad)", XX
, XX
, XX
, XX
},
878 { "movL", Td
, Rd
, XX
, XX
},
879 { "(bad)", XX
, XX
, XX
, XX
},
881 { "movapX", XM
, EX
, XX
, XX
},
882 { "movapX", EX
, XM
, XX
, XX
},
887 { "ucomisX", XM
,EX
, XX
, XX
},
888 { "comisX", XM
,EX
, XX
, XX
},
890 { "wrmsr", XX
, XX
, XX
, XX
},
891 { "rdtsc", XX
, XX
, XX
, XX
},
892 { "rdmsr", XX
, XX
, XX
, XX
},
893 { "rdpmc", XX
, XX
, XX
, XX
},
894 { "sysenter", XX
, XX
, XX
, XX
},
895 { "sysexit", XX
, XX
, XX
, XX
},
896 { "(bad)", XX
, XX
, XX
, XX
},
897 { "(bad)", XX
, XX
, XX
, XX
},
900 { "(bad)", XX
, XX
, XX
, XX
},
902 { "(bad)", XX
, XX
, XX
, XX
},
903 { "(bad)", XX
, XX
, XX
, XX
},
904 { "(bad)", XX
, XX
, XX
, XX
},
905 { "(bad)", XX
, XX
, XX
, XX
},
906 { "(bad)", XX
, XX
, XX
, XX
},
908 { "cmovo", Gv
, Ev
, XX
, XX
},
909 { "cmovno", Gv
, Ev
, XX
, XX
},
910 { "cmovb", Gv
, Ev
, XX
, XX
},
911 { "cmovae", Gv
, Ev
, XX
, XX
},
912 { "cmove", Gv
, Ev
, XX
, XX
},
913 { "cmovne", Gv
, Ev
, XX
, XX
},
914 { "cmovbe", Gv
, Ev
, XX
, XX
},
915 { "cmova", Gv
, Ev
, XX
, XX
},
917 { "cmovs", Gv
, Ev
, XX
, XX
},
918 { "cmovns", Gv
, Ev
, XX
, XX
},
919 { "cmovp", Gv
, Ev
, XX
, XX
},
920 { "cmovnp", Gv
, Ev
, XX
, XX
},
921 { "cmovl", Gv
, Ev
, XX
, XX
},
922 { "cmovge", Gv
, Ev
, XX
, XX
},
923 { "cmovle", Gv
, Ev
, XX
, XX
},
924 { "cmovg", Gv
, Ev
, XX
, XX
},
926 { "movmskpX", Gdq
, XS
, XX
, XX
},
930 { "andpX", XM
, EX
, XX
, XX
},
931 { "andnpX", XM
, EX
, XX
, XX
},
932 { "orpX", XM
, EX
, XX
, XX
},
933 { "xorpX", XM
, EX
, XX
, XX
},
944 { "punpcklbw", MX
, EM
, XX
, XX
},
945 { "punpcklwd", MX
, EM
, XX
, XX
},
946 { "punpckldq", MX
, EM
, XX
, XX
},
947 { "packsswb", MX
, EM
, XX
, XX
},
948 { "pcmpgtb", MX
, EM
, XX
, XX
},
949 { "pcmpgtw", MX
, EM
, XX
, XX
},
950 { "pcmpgtd", MX
, EM
, XX
, XX
},
951 { "packuswb", MX
, EM
, XX
, XX
},
953 { "punpckhbw", MX
, EM
, XX
, XX
},
954 { "punpckhwd", MX
, EM
, XX
, XX
},
955 { "punpckhdq", MX
, EM
, XX
, XX
},
956 { "packssdw", MX
, EM
, XX
, XX
},
959 { "movd", MX
, Edq
, XX
, XX
},
966 { "pcmpeqb", MX
, EM
, XX
, XX
},
967 { "pcmpeqw", MX
, EM
, XX
, XX
},
968 { "pcmpeqd", MX
, EM
, XX
, XX
},
969 { "emms", XX
, XX
, XX
, XX
},
973 { "(bad)", XX
, XX
, XX
, XX
},
974 { "(bad)", XX
, XX
, XX
, XX
},
980 { "joH", Jv
, XX
, cond_jump_flag
, XX
},
981 { "jnoH", Jv
, XX
, cond_jump_flag
, XX
},
982 { "jbH", Jv
, XX
, cond_jump_flag
, XX
},
983 { "jaeH", Jv
, XX
, cond_jump_flag
, XX
},
984 { "jeH", Jv
, XX
, cond_jump_flag
, XX
},
985 { "jneH", Jv
, XX
, cond_jump_flag
, XX
},
986 { "jbeH", Jv
, XX
, cond_jump_flag
, XX
},
987 { "jaH", Jv
, XX
, cond_jump_flag
, XX
},
989 { "jsH", Jv
, XX
, cond_jump_flag
, XX
},
990 { "jnsH", Jv
, XX
, cond_jump_flag
, XX
},
991 { "jpH", Jv
, XX
, cond_jump_flag
, XX
},
992 { "jnpH", Jv
, XX
, cond_jump_flag
, XX
},
993 { "jlH", Jv
, XX
, cond_jump_flag
, XX
},
994 { "jgeH", Jv
, XX
, cond_jump_flag
, XX
},
995 { "jleH", Jv
, XX
, cond_jump_flag
, XX
},
996 { "jgH", Jv
, XX
, cond_jump_flag
, XX
},
998 { "seto", Eb
, XX
, XX
, XX
},
999 { "setno", Eb
, XX
, XX
, XX
},
1000 { "setb", Eb
, XX
, XX
, XX
},
1001 { "setae", Eb
, XX
, XX
, XX
},
1002 { "sete", Eb
, XX
, XX
, XX
},
1003 { "setne", Eb
, XX
, XX
, XX
},
1004 { "setbe", Eb
, XX
, XX
, XX
},
1005 { "seta", Eb
, XX
, XX
, XX
},
1007 { "sets", Eb
, XX
, XX
, XX
},
1008 { "setns", Eb
, XX
, XX
, XX
},
1009 { "setp", Eb
, XX
, XX
, XX
},
1010 { "setnp", Eb
, XX
, XX
, XX
},
1011 { "setl", Eb
, XX
, XX
, XX
},
1012 { "setge", Eb
, XX
, XX
, XX
},
1013 { "setle", Eb
, XX
, XX
, XX
},
1014 { "setg", Eb
, XX
, XX
, XX
},
1016 { "pushT", fs
, XX
, XX
, XX
},
1017 { "popT", fs
, XX
, XX
, XX
},
1018 { "cpuid", XX
, XX
, XX
, XX
},
1019 { "btS", Ev
, Gv
, XX
, XX
},
1020 { "shldS", Ev
, Gv
, Ib
, XX
},
1021 { "shldS", Ev
, Gv
, CL
, XX
},
1025 { "pushT", gs
, XX
, XX
, XX
},
1026 { "popT", gs
, XX
, XX
, XX
},
1027 { "rsm", XX
, XX
, XX
, XX
},
1028 { "btsS", Ev
, Gv
, XX
, XX
},
1029 { "shrdS", Ev
, Gv
, Ib
, XX
},
1030 { "shrdS", Ev
, Gv
, CL
, XX
},
1032 { "imulS", Gv
, Ev
, XX
, XX
},
1034 { "cmpxchgB", Eb
, Gb
, XX
, XX
},
1035 { "cmpxchgS", Ev
, Gv
, XX
, XX
},
1036 { "lssS", Gv
, Mp
, XX
, XX
},
1037 { "btrS", Ev
, Gv
, XX
, XX
},
1038 { "lfsS", Gv
, Mp
, XX
, XX
},
1039 { "lgsS", Gv
, Mp
, XX
, XX
},
1040 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
, XX
},
1041 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
, XX
}, /* yes, there really is movzww ! */
1044 { "ud2b", XX
, XX
, XX
, XX
},
1046 { "btcS", Ev
, Gv
, XX
, XX
},
1047 { "bsfS", Gv
, Ev
, XX
, XX
},
1049 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
, XX
},
1050 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
, XX
}, /* yes, there really is movsww ! */
1052 { "xaddB", Eb
, Gb
, XX
, XX
},
1053 { "xaddS", Ev
, Gv
, XX
, XX
},
1055 { "movntiS", Ev
, Gv
, XX
, XX
},
1056 { "pinsrw", MX
, Edqw
, Ib
, XX
},
1057 { "pextrw", Gdq
, MS
, Ib
, XX
},
1058 { "shufpX", XM
, EX
, Ib
, XX
},
1061 { "bswap", RMeAX
, XX
, XX
, XX
},
1062 { "bswap", RMeCX
, XX
, XX
, XX
},
1063 { "bswap", RMeDX
, XX
, XX
, XX
},
1064 { "bswap", RMeBX
, XX
, XX
, XX
},
1065 { "bswap", RMeSP
, XX
, XX
, XX
},
1066 { "bswap", RMeBP
, XX
, XX
, XX
},
1067 { "bswap", RMeSI
, XX
, XX
, XX
},
1068 { "bswap", RMeDI
, XX
, XX
, XX
},
1071 { "psrlw", MX
, EM
, XX
, XX
},
1072 { "psrld", MX
, EM
, XX
, XX
},
1073 { "psrlq", MX
, EM
, XX
, XX
},
1074 { "paddq", MX
, EM
, XX
, XX
},
1075 { "pmullw", MX
, EM
, XX
, XX
},
1077 { "pmovmskb", Gdq
, MS
, XX
, XX
},
1079 { "psubusb", MX
, EM
, XX
, XX
},
1080 { "psubusw", MX
, EM
, XX
, XX
},
1081 { "pminub", MX
, EM
, XX
, XX
},
1082 { "pand", MX
, EM
, XX
, XX
},
1083 { "paddusb", MX
, EM
, XX
, XX
},
1084 { "paddusw", MX
, EM
, XX
, XX
},
1085 { "pmaxub", MX
, EM
, XX
, XX
},
1086 { "pandn", MX
, EM
, XX
, XX
},
1088 { "pavgb", MX
, EM
, XX
, XX
},
1089 { "psraw", MX
, EM
, XX
, XX
},
1090 { "psrad", MX
, EM
, XX
, XX
},
1091 { "pavgw", MX
, EM
, XX
, XX
},
1092 { "pmulhuw", MX
, EM
, XX
, XX
},
1093 { "pmulhw", MX
, EM
, XX
, XX
},
1097 { "psubsb", MX
, EM
, XX
, XX
},
1098 { "psubsw", MX
, EM
, XX
, XX
},
1099 { "pminsw", MX
, EM
, XX
, XX
},
1100 { "por", MX
, EM
, XX
, XX
},
1101 { "paddsb", MX
, EM
, XX
, XX
},
1102 { "paddsw", MX
, EM
, XX
, XX
},
1103 { "pmaxsw", MX
, EM
, XX
, XX
},
1104 { "pxor", MX
, EM
, XX
, XX
},
1107 { "psllw", MX
, EM
, XX
, XX
},
1108 { "pslld", MX
, EM
, XX
, XX
},
1109 { "psllq", MX
, EM
, XX
, XX
},
1110 { "pmuludq", MX
, EM
, XX
, XX
},
1111 { "pmaddwd", MX
, EM
, XX
, XX
},
1112 { "psadbw", MX
, EM
, XX
, XX
},
1115 { "psubb", MX
, EM
, XX
, XX
},
1116 { "psubw", MX
, EM
, XX
, XX
},
1117 { "psubd", MX
, EM
, XX
, XX
},
1118 { "psubq", MX
, EM
, XX
, XX
},
1119 { "paddb", MX
, EM
, XX
, XX
},
1120 { "paddw", MX
, EM
, XX
, XX
},
1121 { "paddd", MX
, EM
, XX
, XX
},
1122 { "(bad)", XX
, XX
, XX
, XX
}
1125 static const unsigned char onebyte_has_modrm
[256] = {
1126 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1127 /* ------------------------------- */
1128 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1129 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1130 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1131 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1132 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1133 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1134 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1135 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1136 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1137 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1138 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1139 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1140 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1141 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1142 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1143 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1144 /* ------------------------------- */
1145 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1148 static const unsigned char twobyte_has_modrm
[256] = {
1149 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1150 /* ------------------------------- */
1151 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1152 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1153 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1154 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1155 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1156 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1157 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1158 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1159 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1160 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1161 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1162 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1163 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1164 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1165 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1166 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1167 /* ------------------------------- */
1168 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1171 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1172 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1173 /* ------------------------------- */
1174 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1175 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1176 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1177 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1178 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1179 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1180 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1181 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1182 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1183 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1184 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1185 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1186 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1187 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1188 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1189 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1190 /* ------------------------------- */
1191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1194 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1195 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1196 /* ------------------------------- */
1197 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1198 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1199 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1200 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1201 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1202 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1203 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1204 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1205 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1206 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1207 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1208 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1209 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1210 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1211 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1212 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1213 /* ------------------------------- */
1214 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1217 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1218 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1219 /* ------------------------------- */
1220 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1221 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1222 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1223 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1224 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1225 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1226 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1227 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1228 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1229 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1230 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1231 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1232 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1233 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1234 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1235 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1236 /* ------------------------------- */
1237 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1240 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1241 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1242 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1243 /* ------------------------------- */
1244 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1245 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1246 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1247 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1248 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1249 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1250 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1251 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1252 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1253 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1254 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1255 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1256 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1257 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1258 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1259 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1260 /* ------------------------------- */
1261 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1264 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1265 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1266 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1267 /* ------------------------------- */
1268 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1269 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1270 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1271 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1272 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1273 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1274 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1275 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1276 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1277 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1278 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1279 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1280 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1281 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1282 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1283 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1284 /* ------------------------------- */
1285 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1288 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1289 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1290 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1291 /* ------------------------------- */
1292 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1293 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1294 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1295 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1296 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1297 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1298 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1299 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1300 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1301 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1302 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1303 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1304 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1305 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1306 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1307 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1308 /* ------------------------------- */
1309 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1312 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1313 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1314 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1315 /* ------------------------------- */
1316 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1317 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1318 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1319 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1320 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1321 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1322 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1323 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1324 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1325 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1326 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1327 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1328 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1329 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1330 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1331 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1332 /* ------------------------------- */
1333 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1336 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1337 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1338 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1339 /* ------------------------------- */
1340 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1341 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1342 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1343 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1344 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1345 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1346 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1347 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1348 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1349 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1350 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1351 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1352 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1353 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1354 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1355 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1356 /* ------------------------------- */
1357 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1360 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1361 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1362 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1363 /* ------------------------------- */
1364 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1365 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1366 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1367 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1368 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1369 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1370 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1371 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1372 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1373 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1374 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1375 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1376 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1377 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1378 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1379 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1380 /* ------------------------------- */
1381 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1384 static char obuf
[100];
1386 static char scratchbuf
[100];
1387 static unsigned char *start_codep
;
1388 static unsigned char *insn_codep
;
1389 static unsigned char *codep
;
1390 static disassemble_info
*the_info
;
1394 static unsigned char need_modrm
;
1396 /* If we are accessing mod/rm/reg without need_modrm set, then the
1397 values are stale. Hitting this abort likely indicates that you
1398 need to update onebyte_has_modrm or twobyte_has_modrm. */
1399 #define MODRM_CHECK if (!need_modrm) abort ()
1401 static const char **names64
;
1402 static const char **names32
;
1403 static const char **names16
;
1404 static const char **names8
;
1405 static const char **names8rex
;
1406 static const char **names_seg
;
1407 static const char **index16
;
1409 static const char *intel_names64
[] = {
1410 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1411 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1413 static const char *intel_names32
[] = {
1414 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1415 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1417 static const char *intel_names16
[] = {
1418 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1419 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1421 static const char *intel_names8
[] = {
1422 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1424 static const char *intel_names8rex
[] = {
1425 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1426 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1428 static const char *intel_names_seg
[] = {
1429 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1431 static const char *intel_index16
[] = {
1432 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1435 static const char *att_names64
[] = {
1436 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1437 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1439 static const char *att_names32
[] = {
1440 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1441 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1443 static const char *att_names16
[] = {
1444 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1445 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1447 static const char *att_names8
[] = {
1448 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1450 static const char *att_names8rex
[] = {
1451 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1452 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1454 static const char *att_names_seg
[] = {
1455 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1457 static const char *att_index16
[] = {
1458 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1461 static const struct dis386 grps
[][8] = {
1464 { "addA", Eb
, Ib
, XX
, XX
},
1465 { "orA", Eb
, Ib
, XX
, XX
},
1466 { "adcA", Eb
, Ib
, XX
, XX
},
1467 { "sbbA", Eb
, Ib
, XX
, XX
},
1468 { "andA", Eb
, Ib
, XX
, XX
},
1469 { "subA", Eb
, Ib
, XX
, XX
},
1470 { "xorA", Eb
, Ib
, XX
, XX
},
1471 { "cmpA", Eb
, Ib
, XX
, XX
}
1475 { "addQ", Ev
, Iv
, XX
, XX
},
1476 { "orQ", Ev
, Iv
, XX
, XX
},
1477 { "adcQ", Ev
, Iv
, XX
, XX
},
1478 { "sbbQ", Ev
, Iv
, XX
, XX
},
1479 { "andQ", Ev
, Iv
, XX
, XX
},
1480 { "subQ", Ev
, Iv
, XX
, XX
},
1481 { "xorQ", Ev
, Iv
, XX
, XX
},
1482 { "cmpQ", Ev
, Iv
, XX
, XX
}
1486 { "addQ", Ev
, sIb
, XX
, XX
},
1487 { "orQ", Ev
, sIb
, XX
, XX
},
1488 { "adcQ", Ev
, sIb
, XX
, XX
},
1489 { "sbbQ", Ev
, sIb
, XX
, XX
},
1490 { "andQ", Ev
, sIb
, XX
, XX
},
1491 { "subQ", Ev
, sIb
, XX
, XX
},
1492 { "xorQ", Ev
, sIb
, XX
, XX
},
1493 { "cmpQ", Ev
, sIb
, XX
, XX
}
1497 { "rolA", Eb
, Ib
, XX
, XX
},
1498 { "rorA", Eb
, Ib
, XX
, XX
},
1499 { "rclA", Eb
, Ib
, XX
, XX
},
1500 { "rcrA", Eb
, Ib
, XX
, XX
},
1501 { "shlA", Eb
, Ib
, XX
, XX
},
1502 { "shrA", Eb
, Ib
, XX
, XX
},
1503 { "(bad)", XX
, XX
, XX
, XX
},
1504 { "sarA", Eb
, Ib
, XX
, XX
},
1508 { "rolQ", Ev
, Ib
, XX
, XX
},
1509 { "rorQ", Ev
, Ib
, XX
, XX
},
1510 { "rclQ", Ev
, Ib
, XX
, XX
},
1511 { "rcrQ", Ev
, Ib
, XX
, XX
},
1512 { "shlQ", Ev
, Ib
, XX
, XX
},
1513 { "shrQ", Ev
, Ib
, XX
, XX
},
1514 { "(bad)", XX
, XX
, XX
, XX
},
1515 { "sarQ", Ev
, Ib
, XX
, XX
},
1519 { "rolA", Eb
, I1
, XX
, XX
},
1520 { "rorA", Eb
, I1
, XX
, XX
},
1521 { "rclA", Eb
, I1
, XX
, XX
},
1522 { "rcrA", Eb
, I1
, XX
, XX
},
1523 { "shlA", Eb
, I1
, XX
, XX
},
1524 { "shrA", Eb
, I1
, XX
, XX
},
1525 { "(bad)", XX
, XX
, XX
, XX
},
1526 { "sarA", Eb
, I1
, XX
, XX
},
1530 { "rolQ", Ev
, I1
, XX
, XX
},
1531 { "rorQ", Ev
, I1
, XX
, XX
},
1532 { "rclQ", Ev
, I1
, XX
, XX
},
1533 { "rcrQ", Ev
, I1
, XX
, XX
},
1534 { "shlQ", Ev
, I1
, XX
, XX
},
1535 { "shrQ", Ev
, I1
, XX
, XX
},
1536 { "(bad)", XX
, XX
, XX
, XX
},
1537 { "sarQ", Ev
, I1
, XX
, XX
},
1541 { "rolA", Eb
, CL
, XX
, XX
},
1542 { "rorA", Eb
, CL
, XX
, XX
},
1543 { "rclA", Eb
, CL
, XX
, XX
},
1544 { "rcrA", Eb
, CL
, XX
, XX
},
1545 { "shlA", Eb
, CL
, XX
, XX
},
1546 { "shrA", Eb
, CL
, XX
, XX
},
1547 { "(bad)", XX
, XX
, XX
, XX
},
1548 { "sarA", Eb
, CL
, XX
, XX
},
1552 { "rolQ", Ev
, CL
, XX
, XX
},
1553 { "rorQ", Ev
, CL
, XX
, XX
},
1554 { "rclQ", Ev
, CL
, XX
, XX
},
1555 { "rcrQ", Ev
, CL
, XX
, XX
},
1556 { "shlQ", Ev
, CL
, XX
, XX
},
1557 { "shrQ", Ev
, CL
, XX
, XX
},
1558 { "(bad)", XX
, XX
, XX
, XX
},
1559 { "sarQ", Ev
, CL
, XX
, XX
}
1563 { "testA", Eb
, Ib
, XX
, XX
},
1564 { "(bad)", Eb
, XX
, XX
, XX
},
1565 { "notA", Eb
, XX
, XX
, XX
},
1566 { "negA", Eb
, XX
, XX
, XX
},
1567 { "mulA", Eb
, XX
, XX
, XX
}, /* Don't print the implicit %al register, */
1568 { "imulA", Eb
, XX
, XX
, XX
}, /* to distinguish these opcodes from other */
1569 { "divA", Eb
, XX
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1570 { "idivA", Eb
, XX
, XX
, XX
} /* and idiv for consistency. */
1574 { "testQ", Ev
, Iv
, XX
, XX
},
1575 { "(bad)", XX
, XX
, XX
, XX
},
1576 { "notQ", Ev
, XX
, XX
, XX
},
1577 { "negQ", Ev
, XX
, XX
, XX
},
1578 { "mulQ", Ev
, XX
, XX
, XX
}, /* Don't print the implicit register. */
1579 { "imulQ", Ev
, XX
, XX
, XX
},
1580 { "divQ", Ev
, XX
, XX
, XX
},
1581 { "idivQ", Ev
, XX
, XX
, XX
},
1585 { "incA", Eb
, XX
, XX
, XX
},
1586 { "decA", Eb
, XX
, XX
, XX
},
1587 { "(bad)", XX
, XX
, XX
, XX
},
1588 { "(bad)", XX
, XX
, XX
, XX
},
1589 { "(bad)", XX
, XX
, XX
, XX
},
1590 { "(bad)", XX
, XX
, XX
, XX
},
1591 { "(bad)", XX
, XX
, XX
, XX
},
1592 { "(bad)", XX
, XX
, XX
, XX
},
1596 { "incQ", Ev
, XX
, XX
, XX
},
1597 { "decQ", Ev
, XX
, XX
, XX
},
1598 { "callT", indirEv
, XX
, XX
, XX
},
1599 { "JcallT", indirEp
, XX
, XX
, XX
},
1600 { "jmpT", indirEv
, XX
, XX
, XX
},
1601 { "JjmpT", indirEp
, XX
, XX
, XX
},
1602 { "pushU", stackEv
, XX
, XX
, XX
},
1603 { "(bad)", XX
, XX
, XX
, XX
},
1607 { "sldtD", Sv
, XX
, XX
, XX
},
1608 { "strD", Sv
, XX
, XX
, XX
},
1609 { "lldt", Ew
, XX
, XX
, XX
},
1610 { "ltr", Ew
, XX
, XX
, XX
},
1611 { "verr", Ew
, XX
, XX
, XX
},
1612 { "verw", Ew
, XX
, XX
, XX
},
1613 { "(bad)", XX
, XX
, XX
, XX
},
1614 { "(bad)", XX
, XX
, XX
, XX
}
1618 { "sgdt{Q|IQ||}", VMX_Fixup
, 0, XX
, XX
, XX
},
1619 { "sidt{Q|IQ||}", PNI_Fixup
, 0, XX
, XX
, XX
},
1620 { "lgdt{Q|Q||}", M
, XX
, XX
, XX
},
1621 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
, XX
},
1622 { "smswD", Sv
, XX
, XX
, XX
},
1623 { "(bad)", XX
, XX
, XX
, XX
},
1624 { "lmsw", Ew
, XX
, XX
, XX
},
1625 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
, XX
},
1629 { "(bad)", XX
, XX
, XX
, XX
},
1630 { "(bad)", XX
, XX
, XX
, XX
},
1631 { "(bad)", XX
, XX
, XX
, XX
},
1632 { "(bad)", XX
, XX
, XX
, XX
},
1633 { "btQ", Ev
, Ib
, XX
, XX
},
1634 { "btsQ", Ev
, Ib
, XX
, XX
},
1635 { "btrQ", Ev
, Ib
, XX
, XX
},
1636 { "btcQ", Ev
, Ib
, XX
, XX
},
1640 { "(bad)", XX
, XX
, XX
, XX
},
1641 { "cmpxchg8b", Mq
, XX
, XX
, XX
},
1642 { "(bad)", XX
, XX
, XX
, XX
},
1643 { "(bad)", XX
, XX
, XX
, XX
},
1644 { "(bad)", XX
, XX
, XX
, XX
},
1645 { "(bad)", XX
, XX
, XX
, XX
},
1646 { "", VM
, XX
, XX
, XX
}, /* See OP_VMX. */
1647 { "vmptrst", Mq
, XX
, XX
, XX
},
1651 { "movA", Eb
, Ib
, XX
, XX
},
1652 { "(bad)", XX
, XX
, XX
, XX
},
1653 { "(bad)", XX
, XX
, XX
, XX
},
1654 { "(bad)", XX
, XX
, XX
, XX
},
1655 { "(bad)", XX
, XX
, XX
, XX
},
1656 { "(bad)", XX
, XX
, XX
, XX
},
1657 { "(bad)", XX
, XX
, XX
, XX
},
1658 { "(bad)", XX
, XX
, XX
, XX
},
1662 { "movQ", Ev
, Iv
, XX
, XX
},
1663 { "(bad)", XX
, XX
, XX
, XX
},
1664 { "(bad)", XX
, XX
, XX
, XX
},
1665 { "(bad)", XX
, XX
, XX
, XX
},
1666 { "(bad)", XX
, XX
, XX
, XX
},
1667 { "(bad)", XX
, XX
, XX
, XX
},
1668 { "(bad)", XX
, XX
, XX
, XX
},
1669 { "(bad)", XX
, XX
, XX
, XX
},
1673 { "(bad)", XX
, XX
, XX
, XX
},
1674 { "(bad)", XX
, XX
, XX
, XX
},
1675 { "psrlw", MS
, Ib
, XX
, XX
},
1676 { "(bad)", XX
, XX
, XX
, XX
},
1677 { "psraw", MS
, Ib
, XX
, XX
},
1678 { "(bad)", XX
, XX
, XX
, XX
},
1679 { "psllw", MS
, Ib
, XX
, XX
},
1680 { "(bad)", XX
, XX
, XX
, XX
},
1684 { "(bad)", XX
, XX
, XX
, XX
},
1685 { "(bad)", XX
, XX
, XX
, XX
},
1686 { "psrld", MS
, Ib
, XX
, XX
},
1687 { "(bad)", XX
, XX
, XX
, XX
},
1688 { "psrad", MS
, Ib
, XX
, XX
},
1689 { "(bad)", XX
, XX
, XX
, XX
},
1690 { "pslld", MS
, Ib
, XX
, XX
},
1691 { "(bad)", XX
, XX
, XX
, XX
},
1695 { "(bad)", XX
, XX
, XX
, XX
},
1696 { "(bad)", XX
, XX
, XX
, XX
},
1697 { "psrlq", MS
, Ib
, XX
, XX
},
1698 { "psrldq", MS
, Ib
, XX
, XX
},
1699 { "(bad)", XX
, XX
, XX
, XX
},
1700 { "(bad)", XX
, XX
, XX
, XX
},
1701 { "psllq", MS
, Ib
, XX
, XX
},
1702 { "pslldq", MS
, Ib
, XX
, XX
},
1706 { "fxsave", Ev
, XX
, XX
, XX
},
1707 { "fxrstor", Ev
, XX
, XX
, XX
},
1708 { "ldmxcsr", Ev
, XX
, XX
, XX
},
1709 { "stmxcsr", Ev
, XX
, XX
, XX
},
1710 { "(bad)", XX
, XX
, XX
, XX
},
1711 { "lfence", OP_0fae
, 0, XX
, XX
, XX
},
1712 { "mfence", OP_0fae
, 0, XX
, XX
, XX
},
1713 { "clflush", OP_0fae
, 0, XX
, XX
, XX
},
1717 { "prefetchnta", Ev
, XX
, XX
, XX
},
1718 { "prefetcht0", Ev
, XX
, XX
, XX
},
1719 { "prefetcht1", Ev
, XX
, XX
, XX
},
1720 { "prefetcht2", Ev
, XX
, XX
, XX
},
1721 { "(bad)", XX
, XX
, XX
, XX
},
1722 { "(bad)", XX
, XX
, XX
, XX
},
1723 { "(bad)", XX
, XX
, XX
, XX
},
1724 { "(bad)", XX
, XX
, XX
, XX
},
1728 { "prefetch", Eb
, XX
, XX
, XX
},
1729 { "prefetchw", Eb
, XX
, XX
, XX
},
1730 { "(bad)", XX
, XX
, XX
, XX
},
1731 { "(bad)", XX
, XX
, XX
, XX
},
1732 { "(bad)", XX
, XX
, XX
, XX
},
1733 { "(bad)", XX
, XX
, XX
, XX
},
1734 { "(bad)", XX
, XX
, XX
, XX
},
1735 { "(bad)", XX
, XX
, XX
, XX
},
1739 { "xstore-rng", OP_0f07
, 0, XX
, XX
, XX
},
1740 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
, XX
},
1741 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
, XX
},
1742 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
, XX
},
1743 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
, XX
},
1744 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
, XX
},
1745 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1746 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1750 { "montmul", OP_0f07
, 0, XX
, XX
, XX
},
1751 { "xsha1", OP_0f07
, 0, XX
, XX
, XX
},
1752 { "xsha256", OP_0f07
, 0, XX
, XX
, XX
},
1753 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1754 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1755 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1756 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1757 { "(bad)", OP_0f07
, 0, XX
, XX
, XX
},
1761 static const struct dis386 prefix_user_table
[][4] = {
1764 { "addps", XM
, EX
, XX
, XX
},
1765 { "addss", XM
, EX
, XX
, XX
},
1766 { "addpd", XM
, EX
, XX
, XX
},
1767 { "addsd", XM
, EX
, XX
, XX
},
1771 { "", XM
, EX
, OPSIMD
, XX
}, /* See OP_SIMD_SUFFIX. */
1772 { "", XM
, EX
, OPSIMD
, XX
},
1773 { "", XM
, EX
, OPSIMD
, XX
},
1774 { "", XM
, EX
, OPSIMD
, XX
},
1778 { "cvtpi2ps", XM
, EMC
, XX
, XX
},
1779 { "cvtsi2ssY", XM
, Ev
, XX
, XX
},
1780 { "cvtpi2pd", XM
, EMC
, XX
, XX
},
1781 { "cvtsi2sdY", XM
, Ev
, XX
, XX
},
1785 { "cvtps2pi", MXC
, EX
, XX
, XX
},
1786 { "cvtss2siY", Gv
, EX
, XX
, XX
},
1787 { "cvtpd2pi", MXC
, EX
, XX
, XX
},
1788 { "cvtsd2siY", Gv
, EX
, XX
, XX
},
1792 { "cvttps2pi", MXC
, EX
, XX
, XX
},
1793 { "cvttss2siY", Gv
, EX
, XX
, XX
},
1794 { "cvttpd2pi", MXC
, EX
, XX
, XX
},
1795 { "cvttsd2siY", Gv
, EX
, XX
, XX
},
1799 { "divps", XM
, EX
, XX
, XX
},
1800 { "divss", XM
, EX
, XX
, XX
},
1801 { "divpd", XM
, EX
, XX
, XX
},
1802 { "divsd", XM
, EX
, XX
, XX
},
1806 { "maxps", XM
, EX
, XX
, XX
},
1807 { "maxss", XM
, EX
, XX
, XX
},
1808 { "maxpd", XM
, EX
, XX
, XX
},
1809 { "maxsd", XM
, EX
, XX
, XX
},
1813 { "minps", XM
, EX
, XX
, XX
},
1814 { "minss", XM
, EX
, XX
, XX
},
1815 { "minpd", XM
, EX
, XX
, XX
},
1816 { "minsd", XM
, EX
, XX
, XX
},
1820 { "movups", XM
, EX
, XX
, XX
},
1821 { "movss", XM
, EX
, XX
, XX
},
1822 { "movupd", XM
, EX
, XX
, XX
},
1823 { "movsd", XM
, EX
, XX
, XX
},
1827 { "movups", EX
, XM
, XX
, XX
},
1828 { "movss", EX
, XM
, XX
, XX
},
1829 { "movupd", EX
, XM
, XX
, XX
},
1830 { "movsd", EX
, XM
, XX
, XX
},
1834 { "mulps", XM
, EX
, XX
, XX
},
1835 { "mulss", XM
, EX
, XX
, XX
},
1836 { "mulpd", XM
, EX
, XX
, XX
},
1837 { "mulsd", XM
, EX
, XX
, XX
},
1841 { "rcpps", XM
, EX
, XX
, XX
},
1842 { "rcpss", XM
, EX
, XX
, XX
},
1843 { "(bad)", XM
, EX
, XX
, XX
},
1844 { "(bad)", XM
, EX
, XX
, XX
},
1848 { "rsqrtps", XM
, EX
, XX
, XX
},
1849 { "rsqrtss", XM
, EX
, XX
, XX
},
1850 { "(bad)", XM
, EX
, XX
, XX
},
1851 { "(bad)", XM
, EX
, XX
, XX
},
1855 { "sqrtps", XM
, EX
, XX
, XX
},
1856 { "sqrtss", XM
, EX
, XX
, XX
},
1857 { "sqrtpd", XM
, EX
, XX
, XX
},
1858 { "sqrtsd", XM
, EX
, XX
, XX
},
1862 { "subps", XM
, EX
, XX
, XX
},
1863 { "subss", XM
, EX
, XX
, XX
},
1864 { "subpd", XM
, EX
, XX
, XX
},
1865 { "subsd", XM
, EX
, XX
, XX
},
1869 { "(bad)", XM
, EX
, XX
, XX
},
1870 { "cvtdq2pd", XM
, EX
, XX
, XX
},
1871 { "cvttpd2dq", XM
, EX
, XX
, XX
},
1872 { "cvtpd2dq", XM
, EX
, XX
, XX
},
1876 { "cvtdq2ps", XM
, EX
, XX
, XX
},
1877 { "cvttps2dq",XM
, EX
, XX
, XX
},
1878 { "cvtps2dq",XM
, EX
, XX
, XX
},
1879 { "(bad)", XM
, EX
, XX
, XX
},
1883 { "cvtps2pd", XM
, EX
, XX
, XX
},
1884 { "cvtss2sd", XM
, EX
, XX
, XX
},
1885 { "cvtpd2ps", XM
, EX
, XX
, XX
},
1886 { "cvtsd2ss", XM
, EX
, XX
, XX
},
1890 { "maskmovq", MX
, MS
, XX
, XX
},
1891 { "(bad)", XM
, EX
, XX
, XX
},
1892 { "maskmovdqu", XM
, XS
, XX
, XX
},
1893 { "(bad)", XM
, EX
, XX
, XX
},
1897 { "movq", MX
, EM
, XX
, XX
},
1898 { "movdqu", XM
, EX
, XX
, XX
},
1899 { "movdqa", XM
, EX
, XX
, XX
},
1900 { "(bad)", XM
, EX
, XX
, XX
},
1904 { "movq", EM
, MX
, XX
, XX
},
1905 { "movdqu", EX
, XM
, XX
, XX
},
1906 { "movdqa", EX
, XM
, XX
, XX
},
1907 { "(bad)", EX
, XM
, XX
, XX
},
1911 { "(bad)", EX
, XM
, XX
, XX
},
1912 { "movq2dq", XM
, MS
, XX
, XX
},
1913 { "movq", EX
, XM
, XX
, XX
},
1914 { "movdq2q", MX
, XS
, XX
, XX
},
1918 { "pshufw", MX
, EM
, Ib
, XX
},
1919 { "pshufhw", XM
, EX
, Ib
, XX
},
1920 { "pshufd", XM
, EX
, Ib
, XX
},
1921 { "pshuflw", XM
, EX
, Ib
, XX
},
1925 { "movd", Edq
, MX
, XX
, XX
},
1926 { "movq", XM
, EX
, XX
, XX
},
1927 { "movd", Edq
, XM
, XX
, XX
},
1928 { "(bad)", Ed
, XM
, XX
, XX
},
1932 { "(bad)", MX
, EX
, XX
, XX
},
1933 { "(bad)", XM
, EX
, XX
, XX
},
1934 { "punpckhqdq", XM
, EX
, XX
, XX
},
1935 { "(bad)", XM
, EX
, XX
, XX
},
1939 { "movntq", EM
, MX
, XX
, XX
},
1940 { "(bad)", EM
, XM
, XX
, XX
},
1941 { "movntdq", EM
, XM
, XX
, XX
},
1942 { "(bad)", EM
, XM
, XX
, XX
},
1946 { "(bad)", MX
, EX
, XX
, XX
},
1947 { "(bad)", XM
, EX
, XX
, XX
},
1948 { "punpcklqdq", XM
, EX
, XX
, XX
},
1949 { "(bad)", XM
, EX
, XX
, XX
},
1953 { "(bad)", MX
, EX
, XX
, XX
},
1954 { "(bad)", XM
, EX
, XX
, XX
},
1955 { "addsubpd", XM
, EX
, XX
, XX
},
1956 { "addsubps", XM
, EX
, XX
, XX
},
1960 { "(bad)", MX
, EX
, XX
, XX
},
1961 { "(bad)", XM
, EX
, XX
, XX
},
1962 { "haddpd", XM
, EX
, XX
, XX
},
1963 { "haddps", XM
, EX
, XX
, XX
},
1967 { "(bad)", MX
, EX
, XX
, XX
},
1968 { "(bad)", XM
, EX
, XX
, XX
},
1969 { "hsubpd", XM
, EX
, XX
, XX
},
1970 { "hsubps", XM
, EX
, XX
, XX
},
1974 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h', XX
}, /* really only 2 operands */
1975 { "movsldup", XM
, EX
, XX
, XX
},
1976 { "movlpd", XM
, EX
, XX
, XX
},
1977 { "movddup", XM
, EX
, XX
, XX
},
1981 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l', XX
},
1982 { "movshdup", XM
, EX
, XX
, XX
},
1983 { "movhpd", XM
, EX
, XX
, XX
},
1984 { "(bad)", XM
, EX
, XX
, XX
},
1988 { "(bad)", XM
, EX
, XX
, XX
},
1989 { "(bad)", XM
, EX
, XX
, XX
},
1990 { "(bad)", XM
, EX
, XX
, XX
},
1991 { "lddqu", XM
, M
, XX
, XX
},
1995 {"movntps",Ev
, XM
, XX
, XX
},
1996 {"movntss",Ev
, XM
, XX
, XX
},
1997 {"movntpd",Ev
, XM
, XX
, XX
},
1998 {"movntsd",Ev
, XM
, XX
, XX
},
2003 {"vmread", Em
, Gm
, XX
, XX
},
2004 {"(bad)", XX
, XX
, XX
, XX
},
2005 {"extrq", XS
, Ib
, Ib
, XX
},
2006 {"insertq",XM
, XS
, Ib
, Ib
},
2011 {"vmwrite", Gm
, Em
, XX
, XX
},
2012 {"(bad)", XX
, XX
, XX
, XX
},
2013 {"extrq", XM
, XS
, XX
, XX
},
2014 {"insertq", XM
, XS
, XX
, XX
},
2019 { "bsrS", Gv
, Ev
, XX
, XX
},
2020 { "lzcntS", Gv
, Ev
, XX
, XX
},
2021 { "bsrS", Gv
, Ev
, XX
, XX
},
2022 { "(bad)", XX
, XX
, XX
, XX
},
2027 { "(bad)", XX
, XX
, XX
, XX
},
2028 { "popcntS",Gv
, Ev
, XX
, XX
},
2029 { "(bad)", XX
, XX
, XX
, XX
},
2030 { "(bad)", XX
, XX
, XX
, XX
},
2034 static const struct dis386 x86_64_table
[][2] = {
2036 { "pusha{P|}", XX
, XX
, XX
, XX
},
2037 { "(bad)", XX
, XX
, XX
, XX
},
2040 { "popa{P|}", XX
, XX
, XX
, XX
},
2041 { "(bad)", XX
, XX
, XX
, XX
},
2044 { "bound{S|}", Gv
, Ma
, XX
, XX
},
2045 { "(bad)", XX
, XX
, XX
, XX
},
2048 { "arpl", Ew
, Gw
, XX
, XX
},
2049 { "movs{||lq|xd}", Gv
, Ed
, XX
, XX
},
2053 static const struct dis386 three_byte_table
[][256] = {
2057 { "pshufb", MX
, EM
, XX
, XX
},
2058 { "phaddw", MX
, EM
, XX
, XX
},
2059 { "phaddd", MX
, EM
, XX
, XX
},
2060 { "phaddsw", MX
, EM
, XX
, XX
},
2061 { "pmaddubsw", MX
, EM
, XX
, XX
},
2062 { "phsubw", MX
, EM
, XX
, XX
},
2063 { "phsubd", MX
, EM
, XX
, XX
},
2064 { "phsubsw", MX
, EM
, XX
, XX
},
2066 { "psignb", MX
, EM
, XX
, XX
},
2067 { "psignw", MX
, EM
, XX
, XX
},
2068 { "psignd", MX
, EM
, XX
, XX
},
2069 { "pmulhrsw", MX
, EM
, XX
, XX
},
2070 { "(bad)", XX
, XX
, XX
, XX
},
2071 { "(bad)", XX
, XX
, XX
, XX
},
2072 { "(bad)", XX
, XX
, XX
, XX
},
2073 { "(bad)", XX
, XX
, XX
, XX
},
2075 { "(bad)", XX
, XX
, XX
, XX
},
2076 { "(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
},
2084 { "(bad)", XX
, XX
, XX
, XX
},
2085 { "(bad)", XX
, XX
, XX
, XX
},
2086 { "(bad)", XX
, XX
, XX
, XX
},
2087 { "(bad)", XX
, XX
, XX
, XX
},
2088 { "pabsb", MX
, EM
, XX
, XX
},
2089 { "pabsw", MX
, EM
, XX
, XX
},
2090 { "pabsd", MX
, EM
, XX
, XX
},
2091 { "(bad)", XX
, XX
, XX
, XX
},
2093 { "(bad)", XX
, XX
, XX
, XX
},
2094 { "(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
},
2102 { "(bad)", XX
, XX
, XX
, XX
},
2103 { "(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
},
2111 { "(bad)", XX
, XX
, XX
, XX
},
2112 { "(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
},
2120 { "(bad)", XX
, XX
, XX
, XX
},
2121 { "(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
},
2129 { "(bad)", XX
, XX
, XX
, XX
},
2130 { "(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
},
2138 { "(bad)", XX
, XX
, XX
, XX
},
2139 { "(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
},
2147 { "(bad)", XX
, XX
, XX
, XX
},
2148 { "(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
},
2156 { "(bad)", XX
, XX
, XX
, XX
},
2157 { "(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
},
2165 { "(bad)", XX
, XX
, XX
, XX
},
2166 { "(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
},
2174 { "(bad)", XX
, XX
, XX
, XX
},
2175 { "(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
},
2183 { "(bad)", XX
, XX
, XX
, XX
},
2184 { "(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
},
2192 { "(bad)", XX
, XX
, XX
, XX
},
2193 { "(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
},
2201 { "(bad)", XX
, XX
, XX
, XX
},
2202 { "(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
},
2210 { "(bad)", XX
, XX
, XX
, XX
},
2211 { "(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
},
2219 { "(bad)", XX
, XX
, XX
, XX
},
2220 { "(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
},
2228 { "(bad)", XX
, XX
, XX
, XX
},
2229 { "(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
},
2237 { "(bad)", XX
, XX
, XX
, XX
},
2238 { "(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
},
2246 { "(bad)", XX
, XX
, XX
, XX
},
2247 { "(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
},
2255 { "(bad)", XX
, XX
, XX
, XX
},
2256 { "(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
},
2264 { "(bad)", XX
, XX
, XX
, XX
},
2265 { "(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
},
2273 { "(bad)", XX
, XX
, XX
, XX
},
2274 { "(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
},
2282 { "(bad)", XX
, XX
, XX
, XX
},
2283 { "(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
},
2291 { "(bad)", XX
, XX
, XX
, XX
},
2292 { "(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
},
2300 { "(bad)", XX
, XX
, XX
, XX
},
2301 { "(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
},
2309 { "(bad)", XX
, XX
, XX
, XX
},
2310 { "(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
},
2318 { "(bad)", XX
, XX
, XX
, XX
},
2319 { "(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
},
2327 { "(bad)", XX
, XX
, XX
, XX
},
2328 { "(bad)", XX
, XX
, XX
, XX
},
2329 { "(bad)", XX
, XX
, XX
, XX
},
2330 { "(bad)", XX
, XX
, XX
, XX
},
2331 { "(bad)", XX
, XX
, XX
, XX
},
2332 { "(bad)", XX
, XX
, XX
, XX
},
2333 { "(bad)", XX
, XX
, XX
, XX
},
2334 { "(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
},
2340 { "(bad)", XX
, XX
, XX
, XX
},
2341 { "(bad)", XX
, XX
, XX
, XX
},
2342 { "(bad)", XX
, XX
, XX
, XX
},
2343 { "(bad)", XX
, XX
, XX
, XX
}
2348 { "(bad)", XX
, XX
, XX
, XX
},
2349 { "(bad)", XX
, XX
, XX
, 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
},
2357 { "(bad)", XX
, XX
, XX
, XX
},
2358 { "(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 { "palignr", MX
, EM
, Ib
, XX
},
2366 { "(bad)", XX
, XX
, XX
, XX
},
2367 { "(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
},
2375 { "(bad)", XX
, XX
, XX
, XX
},
2376 { "(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
},
2384 { "(bad)", XX
, XX
, XX
, XX
},
2385 { "(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
},
2393 { "(bad)", XX
, XX
, XX
, XX
},
2394 { "(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
},
2402 { "(bad)", XX
, XX
, XX
, XX
},
2403 { "(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
},
2411 { "(bad)", XX
, XX
, XX
, XX
},
2412 { "(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
},
2420 { "(bad)", XX
, XX
, XX
, XX
},
2421 { "(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
},
2429 { "(bad)", XX
, XX
, XX
, XX
},
2430 { "(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
},
2438 { "(bad)", XX
, XX
, XX
, XX
},
2439 { "(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
},
2447 { "(bad)", XX
, XX
, XX
, XX
},
2448 { "(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
},
2456 { "(bad)", XX
, XX
, XX
, XX
},
2457 { "(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
},
2465 { "(bad)", XX
, XX
, XX
, XX
},
2466 { "(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
},
2474 { "(bad)", XX
, XX
, XX
, XX
},
2475 { "(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
},
2483 { "(bad)", XX
, XX
, XX
, XX
},
2484 { "(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
},
2492 { "(bad)", XX
, XX
, XX
, XX
},
2493 { "(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
},
2501 { "(bad)", XX
, XX
, XX
, XX
},
2502 { "(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
},
2510 { "(bad)", XX
, XX
, XX
, XX
},
2511 { "(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
},
2519 { "(bad)", XX
, XX
, XX
, XX
},
2520 { "(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
},
2528 { "(bad)", XX
, XX
, XX
, XX
},
2529 { "(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
},
2537 { "(bad)", XX
, XX
, XX
, XX
},
2538 { "(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
},
2546 { "(bad)", XX
, XX
, XX
, XX
},
2547 { "(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
},
2555 { "(bad)", XX
, XX
, XX
, XX
},
2556 { "(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
},
2564 { "(bad)", XX
, XX
, XX
, XX
},
2565 { "(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
},
2573 { "(bad)", XX
, XX
, XX
, XX
},
2574 { "(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
},
2582 { "(bad)", XX
, XX
, XX
, XX
},
2583 { "(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
},
2591 { "(bad)", XX
, XX
, XX
, XX
},
2592 { "(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
},
2600 { "(bad)", XX
, XX
, XX
, XX
},
2601 { "(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
},
2609 { "(bad)", XX
, XX
, XX
, XX
},
2610 { "(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
},
2618 { "(bad)", XX
, XX
, XX
, XX
},
2619 { "(bad)", XX
, XX
, XX
, XX
},
2620 { "(bad)", XX
, XX
, XX
, XX
},
2621 { "(bad)", XX
, XX
, XX
, XX
},
2622 { "(bad)", XX
, XX
, XX
, XX
},
2623 { "(bad)", XX
, XX
, XX
, XX
},
2624 { "(bad)", XX
, XX
, XX
, XX
},
2625 { "(bad)", XX
, XX
, XX
, XX
},
2627 { "(bad)", XX
, XX
, XX
, XX
},
2628 { "(bad)", XX
, XX
, XX
, XX
},
2629 { "(bad)", XX
, XX
, XX
, XX
},
2630 { "(bad)", XX
, XX
, XX
, XX
},
2631 { "(bad)", XX
, XX
, XX
, XX
},
2632 { "(bad)", XX
, XX
, XX
, XX
},
2633 { "(bad)", XX
, XX
, XX
, XX
},
2634 { "(bad)", XX
, XX
, XX
, XX
}
2638 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2650 FETCH_DATA (the_info
, codep
+ 1);
2654 /* REX prefixes family. */
2671 if (address_mode
== mode_64bit
)
2677 prefixes
|= PREFIX_REPZ
;
2680 prefixes
|= PREFIX_REPNZ
;
2683 prefixes
|= PREFIX_LOCK
;
2686 prefixes
|= PREFIX_CS
;
2689 prefixes
|= PREFIX_SS
;
2692 prefixes
|= PREFIX_DS
;
2695 prefixes
|= PREFIX_ES
;
2698 prefixes
|= PREFIX_FS
;
2701 prefixes
|= PREFIX_GS
;
2704 prefixes
|= PREFIX_DATA
;
2707 prefixes
|= PREFIX_ADDR
;
2710 /* fwait is really an instruction. If there are prefixes
2711 before the fwait, they belong to the fwait, *not* to the
2712 following instruction. */
2713 if (prefixes
|| rex
)
2715 prefixes
|= PREFIX_FWAIT
;
2719 prefixes
= PREFIX_FWAIT
;
2724 /* Rex is ignored when followed by another prefix. */
2735 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2739 prefix_name (int pref
, int sizeflag
)
2743 /* REX prefixes family. */
2795 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2797 if (address_mode
== mode_64bit
)
2798 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2800 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2808 static char op1out
[100], op2out
[100], op3out
[100], op4out
[100];
2809 static int op_ad
, op_index
[4];
2810 static int two_source_ops
;
2811 static bfd_vma op_address
[4];
2812 static bfd_vma op_riprel
[4];
2813 static bfd_vma start_pc
;
2816 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2817 * (see topic "Redundant prefixes" in the "Differences from 8086"
2818 * section of the "Virtual 8086 Mode" chapter.)
2819 * 'pc' should be the address of this instruction, it will
2820 * be used to print the target address if this is a relative jump or call
2821 * The function returns the length of this instruction in bytes.
2824 static char intel_syntax
;
2825 static char open_char
;
2826 static char close_char
;
2827 static char separator_char
;
2828 static char scale_char
;
2830 /* Here for backwards compatibility. When gdb stops using
2831 print_insn_i386_att and print_insn_i386_intel these functions can
2832 disappear, and print_insn_i386 be merged into print_insn. */
2834 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2838 return print_insn (pc
, info
);
2842 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2846 return print_insn (pc
, info
);
2850 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2854 return print_insn (pc
, info
);
2858 print_insn (bfd_vma pc
, disassemble_info
*info
)
2860 const struct dis386
*dp
;
2862 char *first
, *second
, *third
, *fourth
;
2864 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
2865 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
2868 struct dis_private priv
;
2871 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2872 || info
->mach
== bfd_mach_x86_64
)
2873 address_mode
= mode_64bit
;
2875 address_mode
= mode_32bit
;
2877 if (intel_syntax
== (char) -1)
2878 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2879 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2881 if (info
->mach
== bfd_mach_i386_i386
2882 || info
->mach
== bfd_mach_x86_64
2883 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2884 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2885 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2886 else if (info
->mach
== bfd_mach_i386_i8086
)
2887 priv
.orig_sizeflag
= 0;
2891 for (p
= info
->disassembler_options
; p
!= NULL
; )
2893 if (CONST_STRNEQ (p
, "x86-64"))
2895 address_mode
= mode_64bit
;
2896 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2898 else if (CONST_STRNEQ (p
, "i386"))
2900 address_mode
= mode_32bit
;
2901 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2903 else if (CONST_STRNEQ (p
, "i8086"))
2905 address_mode
= mode_16bit
;
2906 priv
.orig_sizeflag
= 0;
2908 else if (CONST_STRNEQ (p
, "intel"))
2912 else if (CONST_STRNEQ (p
, "att"))
2916 else if (CONST_STRNEQ (p
, "addr"))
2918 if (p
[4] == '1' && p
[5] == '6')
2919 priv
.orig_sizeflag
&= ~AFLAG
;
2920 else if (p
[4] == '3' && p
[5] == '2')
2921 priv
.orig_sizeflag
|= AFLAG
;
2923 else if (CONST_STRNEQ (p
, "data"))
2925 if (p
[4] == '1' && p
[5] == '6')
2926 priv
.orig_sizeflag
&= ~DFLAG
;
2927 else if (p
[4] == '3' && p
[5] == '2')
2928 priv
.orig_sizeflag
|= DFLAG
;
2930 else if (CONST_STRNEQ (p
, "suffix"))
2931 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2933 p
= strchr (p
, ',');
2940 names64
= intel_names64
;
2941 names32
= intel_names32
;
2942 names16
= intel_names16
;
2943 names8
= intel_names8
;
2944 names8rex
= intel_names8rex
;
2945 names_seg
= intel_names_seg
;
2946 index16
= intel_index16
;
2949 separator_char
= '+';
2954 names64
= att_names64
;
2955 names32
= att_names32
;
2956 names16
= att_names16
;
2957 names8
= att_names8
;
2958 names8rex
= att_names8rex
;
2959 names_seg
= att_names_seg
;
2960 index16
= att_index16
;
2963 separator_char
= ',';
2967 /* The output looks better if we put 7 bytes on a line, since that
2968 puts most long word instructions on a single line. */
2969 info
->bytes_per_line
= 7;
2971 info
->private_data
= &priv
;
2972 priv
.max_fetched
= priv
.the_buffer
;
2973 priv
.insn_start
= pc
;
2981 op_index
[0] = op_index
[1] = op_index
[2] = op_index
[3] = -1;
2985 start_codep
= priv
.the_buffer
;
2986 codep
= priv
.the_buffer
;
2988 if (setjmp (priv
.bailout
) != 0)
2992 /* Getting here means we tried for data but didn't get it. That
2993 means we have an incomplete instruction of some sort. Just
2994 print the first byte as a prefix or a .byte pseudo-op. */
2995 if (codep
> priv
.the_buffer
)
2997 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2999 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3002 /* Just print the first byte as a .byte instruction. */
3003 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3004 (unsigned int) priv
.the_buffer
[0]);
3017 sizeflag
= priv
.orig_sizeflag
;
3019 FETCH_DATA (info
, codep
+ 1);
3020 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3022 if (((prefixes
& PREFIX_FWAIT
)
3023 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3024 || (rex
&& rex_used
))
3028 /* fwait not followed by floating point instruction, or rex followed
3029 by other prefixes. Print the first prefix. */
3030 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3032 name
= INTERNAL_DISASSEMBLER_ERROR
;
3033 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3040 unsigned char threebyte
;
3041 FETCH_DATA (info
, codep
+ 2);
3042 threebyte
= *++codep
;
3043 dp
= &dis386_twobyte
[threebyte
];
3044 need_modrm
= twobyte_has_modrm
[*codep
];
3045 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3046 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3047 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3048 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3050 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
3052 FETCH_DATA (info
, codep
+ 2);
3057 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3058 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3059 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3062 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3063 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3064 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3073 dp
= &dis386
[*codep
];
3074 need_modrm
= onebyte_has_modrm
[*codep
];
3075 uses_DATA_prefix
= 0;
3076 uses_REPNZ_prefix
= 0;
3077 uses_REPZ_prefix
= 0;
3078 uses_LOCK_prefix
= 0;
3082 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3085 used_prefixes
|= PREFIX_REPZ
;
3087 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3090 used_prefixes
|= PREFIX_REPNZ
;
3093 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3096 used_prefixes
|= PREFIX_LOCK
;
3099 if (prefixes
& PREFIX_ADDR
)
3102 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
3104 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3105 oappend ("addr32 ");
3107 oappend ("addr16 ");
3108 used_prefixes
|= PREFIX_ADDR
;
3112 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3115 if (dp
->bytemode3
== cond_jump_mode
3116 && dp
->bytemode1
== v_mode
3119 if (sizeflag
& DFLAG
)
3120 oappend ("data32 ");
3122 oappend ("data16 ");
3123 used_prefixes
|= PREFIX_DATA
;
3127 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
3129 dp
= &three_byte_table
[dp
->bytemode2
][op
];
3130 mod
= (*codep
>> 6) & 3;
3131 reg
= (*codep
>> 3) & 7;
3134 else if (need_modrm
)
3136 FETCH_DATA (info
, codep
+ 1);
3137 mod
= (*codep
>> 6) & 3;
3138 reg
= (*codep
>> 3) & 7;
3142 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
3149 if (dp
->name
== NULL
)
3151 switch (dp
->bytemode1
)
3154 dp
= &grps
[dp
->bytemode2
][reg
];
3157 case USE_PREFIX_USER_TABLE
:
3159 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3160 if (prefixes
& PREFIX_REPZ
)
3164 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3165 before PREFIX_DATA. */
3166 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3167 if (prefixes
& PREFIX_REPNZ
)
3171 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3172 if (prefixes
& PREFIX_DATA
)
3176 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
3179 case X86_64_SPECIAL
:
3180 index
= address_mode
== mode_64bit
? 1 : 0;
3181 dp
= &x86_64_table
[dp
->bytemode2
][index
];
3185 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3190 if (putop (dp
->name
, sizeflag
) == 0)
3195 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
3200 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
3205 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
3210 (*dp
->op4
) (dp
->bytemode4
, sizeflag
);
3214 /* See if any prefixes were not used. If so, print the first one
3215 separately. If we don't do this, we'll wind up printing an
3216 instruction stream which does not precisely correspond to the
3217 bytes we are disassembling. */
3218 if ((prefixes
& ~used_prefixes
) != 0)
3222 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3224 name
= INTERNAL_DISASSEMBLER_ERROR
;
3225 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3228 if (rex
& ~rex_used
)
3231 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3233 name
= INTERNAL_DISASSEMBLER_ERROR
;
3234 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3237 obufp
= obuf
+ strlen (obuf
);
3238 for (i
= strlen (obuf
); i
< 6; i
++)
3241 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3243 /* The enter and bound instructions are printed with operands in the same
3244 order as the intel book; everything else is printed in reverse order. */
3245 if (intel_syntax
|| two_source_ops
)
3251 op_ad
= op_index
[0];
3252 op_index
[0] = op_index
[3];
3253 op_index
[3] = op_ad
;
3254 op_ad
= op_index
[1];
3255 op_index
[1] = op_index
[2];
3256 op_index
[2] = op_ad
;
3269 if (op_index
[0] != -1 && !op_riprel
[0])
3270 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
3272 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
3279 (*info
->fprintf_func
) (info
->stream
, ",");
3280 if (op_index
[1] != -1 && !op_riprel
[1])
3281 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
3283 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
3290 (*info
->fprintf_func
) (info
->stream
, ",");
3291 if (op_index
[2] != -1 && !op_riprel
[2])
3292 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
3294 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
3301 (*info
->fprintf_func
) (info
->stream
, ",");
3302 if (op_index
[3] != -1 && !op_riprel
[3])
3303 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[3]], info
);
3305 (*info
->fprintf_func
) (info
->stream
, "%s", fourth
);
3308 for (i
= 0; i
< 4; i
++)
3309 if (op_index
[i
] != -1 && op_riprel
[i
])
3311 (*info
->fprintf_func
) (info
->stream
, " # ");
3312 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3313 + op_address
[op_index
[i
]]), info
);
3315 return codep
- priv
.the_buffer
;
3318 static const char *float_mem
[] = {
3393 static const unsigned char float_mem_mode
[] = {
3469 #define STi OP_STi, 0
3471 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
3472 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
3473 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
3474 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
3475 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
3476 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
3477 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
3478 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
3479 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
3481 static const struct dis386 float_reg
[][8] = {
3484 { "fadd", ST
, STi
, XX
, XX
},
3485 { "fmul", ST
, STi
, XX
, XX
},
3486 { "fcom", STi
, XX
, XX
, XX
},
3487 { "fcomp", STi
, XX
, XX
, XX
},
3488 { "fsub", ST
, STi
, XX
, XX
},
3489 { "fsubr", ST
, STi
, XX
, XX
},
3490 { "fdiv", ST
, STi
, XX
, XX
},
3491 { "fdivr", ST
, STi
, XX
, XX
},
3495 { "fld", STi
, XX
, XX
, XX
},
3496 { "fxch", STi
, XX
, XX
, XX
},
3498 { "(bad)", XX
, XX
, XX
, XX
},
3506 { "fcmovb", ST
, STi
, XX
, XX
},
3507 { "fcmove", ST
, STi
, XX
, XX
},
3508 { "fcmovbe",ST
, STi
, XX
, XX
},
3509 { "fcmovu", ST
, STi
, XX
, XX
},
3510 { "(bad)", XX
, XX
, XX
, XX
},
3512 { "(bad)", XX
, XX
, XX
, XX
},
3513 { "(bad)", XX
, XX
, XX
, XX
},
3517 { "fcmovnb",ST
, STi
, XX
, XX
},
3518 { "fcmovne",ST
, STi
, XX
, XX
},
3519 { "fcmovnbe",ST
, STi
, XX
, XX
},
3520 { "fcmovnu",ST
, STi
, XX
, XX
},
3522 { "fucomi", ST
, STi
, XX
, XX
},
3523 { "fcomi", ST
, STi
, XX
, XX
},
3524 { "(bad)", XX
, XX
, XX
, XX
},
3528 { "fadd", STi
, ST
, XX
, XX
},
3529 { "fmul", STi
, ST
, XX
, XX
},
3530 { "(bad)", XX
, XX
, XX
, XX
},
3531 { "(bad)", XX
, XX
, XX
, XX
},
3533 { "fsub", STi
, ST
, XX
, XX
},
3534 { "fsubr", STi
, ST
, XX
, XX
},
3535 { "fdiv", STi
, ST
, XX
, XX
},
3536 { "fdivr", STi
, ST
, XX
, XX
},
3538 { "fsubr", STi
, ST
, XX
, XX
},
3539 { "fsub", STi
, ST
, XX
, XX
},
3540 { "fdivr", STi
, ST
, XX
, XX
},
3541 { "fdiv", STi
, ST
, XX
, XX
},
3546 { "ffree", STi
, XX
, XX
, XX
},
3547 { "(bad)", XX
, XX
, XX
, XX
},
3548 { "fst", STi
, XX
, XX
, XX
},
3549 { "fstp", STi
, XX
, XX
, XX
},
3550 { "fucom", STi
, XX
, XX
, XX
},
3551 { "fucomp", STi
, XX
, XX
, XX
},
3552 { "(bad)", XX
, XX
, XX
, XX
},
3553 { "(bad)", XX
, XX
, XX
, XX
},
3557 { "faddp", STi
, ST
, XX
, XX
},
3558 { "fmulp", STi
, ST
, XX
, XX
},
3559 { "(bad)", XX
, XX
, XX
, XX
},
3562 { "fsubp", STi
, ST
, XX
, XX
},
3563 { "fsubrp", STi
, ST
, XX
, XX
},
3564 { "fdivp", STi
, ST
, XX
, XX
},
3565 { "fdivrp", STi
, ST
, XX
, XX
},
3567 { "fsubrp", STi
, ST
, XX
, XX
},
3568 { "fsubp", STi
, ST
, XX
, XX
},
3569 { "fdivrp", STi
, ST
, XX
, XX
},
3570 { "fdivp", STi
, ST
, XX
, XX
},
3575 { "ffreep", STi
, XX
, XX
, XX
},
3576 { "(bad)", XX
, XX
, XX
, XX
},
3577 { "(bad)", XX
, XX
, XX
, XX
},
3578 { "(bad)", XX
, XX
, XX
, XX
},
3580 { "fucomip",ST
, STi
, XX
, XX
},
3581 { "fcomip", ST
, STi
, XX
, XX
},
3582 { "(bad)", XX
, XX
, XX
, XX
},
3586 static char *fgrps
[][8] = {
3589 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3594 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3599 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3604 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3609 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3614 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3619 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3620 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3625 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3630 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3635 dofloat (int sizeflag
)
3637 const struct dis386
*dp
;
3638 unsigned char floatop
;
3640 floatop
= codep
[-1];
3644 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
3646 putop (float_mem
[fp_indx
], sizeflag
);
3649 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
3652 /* Skip mod/rm byte. */
3656 dp
= &float_reg
[floatop
- 0xd8][reg
];
3657 if (dp
->name
== NULL
)
3659 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
3661 /* Instruction fnstsw is only one with strange arg. */
3662 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3663 strcpy (op1out
, names16
[0]);
3667 putop (dp
->name
, sizeflag
);
3672 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
3677 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
3682 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3684 oappend ("%st" + intel_syntax
);
3688 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3690 sprintf (scratchbuf
, "%%st(%d)", rm
);
3691 oappend (scratchbuf
+ intel_syntax
);
3694 /* Capital letters in template are macros. */
3696 putop (const char *template, int sizeflag
)
3701 for (p
= template; *p
; p
++)
3712 if (address_mode
== mode_64bit
)
3720 /* Alternative not valid. */
3721 strcpy (obuf
, "(bad)");
3725 else if (*p
== '\0')
3746 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3752 if (sizeflag
& SUFFIX_ALWAYS
)
3756 if (intel_syntax
&& !alt
)
3758 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
3760 if (sizeflag
& DFLAG
)
3761 *obufp
++ = intel_syntax
? 'd' : 'l';
3763 *obufp
++ = intel_syntax
? 'w' : 's';
3764 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3768 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
3770 USED_REX (REX_MODE64
);
3773 if (rex
& REX_MODE64
)
3775 else if (sizeflag
& DFLAG
)
3776 *obufp
++ = intel_syntax
? 'd' : 'l';
3779 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3784 case 'E': /* For jcxz/jecxz */
3785 if (address_mode
== mode_64bit
)
3787 if (sizeflag
& AFLAG
)
3793 if (sizeflag
& AFLAG
)
3795 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3800 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
3802 if (sizeflag
& AFLAG
)
3803 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
3805 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
3806 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3810 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
3812 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
3816 if (!(rex
& REX_MODE64
))
3817 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3822 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
3823 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
3825 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
3828 if (prefixes
& PREFIX_DS
)
3842 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
3851 if (sizeflag
& SUFFIX_ALWAYS
)
3855 if ((prefixes
& PREFIX_FWAIT
) == 0)
3858 used_prefixes
|= PREFIX_FWAIT
;
3861 USED_REX (REX_MODE64
);
3862 if (rex
& REX_MODE64
)
3864 else if (intel_syntax
&& (sizeflag
& DFLAG
))
3868 if (!(rex
& REX_MODE64
))
3869 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3874 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3883 if ((prefixes
& PREFIX_DATA
)
3884 || (rex
& REX_MODE64
)
3885 || (sizeflag
& SUFFIX_ALWAYS
))
3887 USED_REX (REX_MODE64
);
3888 if (rex
& REX_MODE64
)
3892 if (sizeflag
& DFLAG
)
3897 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3903 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3905 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3911 if (intel_syntax
&& !alt
)
3913 USED_REX (REX_MODE64
);
3914 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3916 if (rex
& REX_MODE64
)
3920 if (sizeflag
& DFLAG
)
3921 *obufp
++ = intel_syntax
? 'd' : 'l';
3925 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3929 USED_REX (REX_MODE64
);
3930 if (rex
& REX_MODE64
)
3932 else if (sizeflag
& DFLAG
)
3941 if (intel_syntax
&& !p
[1]
3942 && ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
)))
3944 if (!(rex
& REX_MODE64
))
3945 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3950 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3952 if (sizeflag
& SUFFIX_ALWAYS
)
3960 if (sizeflag
& SUFFIX_ALWAYS
)
3962 if (rex
& REX_MODE64
)
3966 if (sizeflag
& DFLAG
)
3970 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3975 if (prefixes
& PREFIX_DATA
)
3979 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3984 if (rex
& REX_MODE64
)
3986 USED_REX (REX_MODE64
);
3990 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3992 /* operand size flag for cwtl, cbtw */
3993 USED_REX (REX_MODE64
);
3994 if (rex
& REX_MODE64
)
4001 else if (sizeflag
& DFLAG
)
4005 if (!(rex
& REX_MODE64
))
4006 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4016 oappend (const char *s
)
4019 obufp
+= strlen (s
);
4025 if (prefixes
& PREFIX_CS
)
4027 used_prefixes
|= PREFIX_CS
;
4028 oappend ("%cs:" + intel_syntax
);
4030 if (prefixes
& PREFIX_DS
)
4032 used_prefixes
|= PREFIX_DS
;
4033 oappend ("%ds:" + intel_syntax
);
4035 if (prefixes
& PREFIX_SS
)
4037 used_prefixes
|= PREFIX_SS
;
4038 oappend ("%ss:" + intel_syntax
);
4040 if (prefixes
& PREFIX_ES
)
4042 used_prefixes
|= PREFIX_ES
;
4043 oappend ("%es:" + intel_syntax
);
4045 if (prefixes
& PREFIX_FS
)
4047 used_prefixes
|= PREFIX_FS
;
4048 oappend ("%fs:" + intel_syntax
);
4050 if (prefixes
& PREFIX_GS
)
4052 used_prefixes
|= PREFIX_GS
;
4053 oappend ("%gs:" + intel_syntax
);
4058 OP_indirE (int bytemode
, int sizeflag
)
4062 OP_E (bytemode
, sizeflag
);
4066 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4068 if (address_mode
== mode_64bit
)
4076 sprintf_vma (tmp
, disp
);
4077 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4078 strcpy (buf
+ 2, tmp
+ i
);
4082 bfd_signed_vma v
= disp
;
4089 /* Check for possible overflow on 0x8000000000000000. */
4092 strcpy (buf
, "9223372036854775808");
4106 tmp
[28 - i
] = (v
% 10) + '0';
4110 strcpy (buf
, tmp
+ 29 - i
);
4116 sprintf (buf
, "0x%x", (unsigned int) disp
);
4118 sprintf (buf
, "%d", (int) disp
);
4123 intel_operand_size (int bytemode
, int sizeflag
)
4128 oappend ("BYTE PTR ");
4132 oappend ("WORD PTR ");
4135 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4137 oappend ("QWORD PTR ");
4138 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4144 USED_REX (REX_MODE64
);
4145 if (rex
& REX_MODE64
)
4146 oappend ("QWORD PTR ");
4147 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4148 oappend ("DWORD PTR ");
4150 oappend ("WORD PTR ");
4151 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4154 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4156 oappend ("WORD PTR ");
4157 if (!(rex
& REX_MODE64
))
4158 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4161 oappend ("DWORD PTR ");
4164 oappend ("QWORD PTR ");
4167 if (address_mode
== mode_64bit
)
4168 oappend ("QWORD PTR ");
4170 oappend ("DWORD PTR ");
4173 if (sizeflag
& DFLAG
)
4174 oappend ("FWORD PTR ");
4176 oappend ("DWORD PTR ");
4177 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4180 oappend ("TBYTE PTR ");
4183 oappend ("XMMWORD PTR ");
4191 OP_E (int bytemode
, int sizeflag
)
4196 USED_REX (REX_EXTZ
);
4200 /* Skip mod/rm byte. */
4211 oappend (names8rex
[rm
+ add
]);
4213 oappend (names8
[rm
+ add
]);
4216 oappend (names16
[rm
+ add
]);
4219 oappend (names32
[rm
+ add
]);
4222 oappend (names64
[rm
+ add
]);
4225 if (address_mode
== mode_64bit
)
4226 oappend (names64
[rm
+ add
]);
4228 oappend (names32
[rm
+ add
]);
4231 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4233 oappend (names64
[rm
+ add
]);
4234 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4242 USED_REX (REX_MODE64
);
4243 if (rex
& REX_MODE64
)
4244 oappend (names64
[rm
+ add
]);
4245 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4246 oappend (names32
[rm
+ add
]);
4248 oappend (names16
[rm
+ add
]);
4249 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4254 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4262 intel_operand_size (bytemode
, sizeflag
);
4265 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
4280 FETCH_DATA (the_info
, codep
+ 1);
4281 index
= (*codep
>> 3) & 7;
4282 if (address_mode
== mode_64bit
|| index
!= 0x4)
4283 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4284 scale
= (*codep
>> 6) & 3;
4286 USED_REX (REX_EXTY
);
4296 if ((base
& 7) == 5)
4299 if (address_mode
== mode_64bit
&& !havesib
)
4305 FETCH_DATA (the_info
, codep
+ 1);
4307 if ((disp
& 0x80) != 0)
4316 if (mod
!= 0 || (base
& 7) == 5)
4318 print_operand_value (scratchbuf
, !riprel
, disp
);
4319 oappend (scratchbuf
);
4327 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4329 *obufp
++ = open_char
;
4330 if (intel_syntax
&& riprel
)
4334 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4335 ? names64
[base
] : names32
[base
]);
4340 if (!intel_syntax
|| havebase
)
4342 *obufp
++ = separator_char
;
4345 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4346 ? names64
[index
] : names32
[index
]);
4348 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4350 *obufp
++ = scale_char
;
4352 sprintf (scratchbuf
, "%d", 1 << scale
);
4353 oappend (scratchbuf
);
4356 if (intel_syntax
&& disp
)
4358 if ((bfd_signed_vma
) disp
> 0)
4367 disp
= - (bfd_signed_vma
) disp
;
4370 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4371 oappend (scratchbuf
);
4374 *obufp
++ = close_char
;
4377 else if (intel_syntax
)
4379 if (mod
!= 0 || (base
& 7) == 5)
4381 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4382 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4386 oappend (names_seg
[ds_reg
- es_reg
]);
4389 print_operand_value (scratchbuf
, 1, disp
);
4390 oappend (scratchbuf
);
4395 { /* 16 bit address mode */
4402 if ((disp
& 0x8000) != 0)
4407 FETCH_DATA (the_info
, codep
+ 1);
4409 if ((disp
& 0x80) != 0)
4414 if ((disp
& 0x8000) != 0)
4420 if (mod
!= 0 || rm
== 6)
4422 print_operand_value (scratchbuf
, 0, disp
);
4423 oappend (scratchbuf
);
4426 if (mod
!= 0 || rm
!= 6)
4428 *obufp
++ = open_char
;
4430 oappend (index16
[rm
]);
4431 if (intel_syntax
&& disp
)
4433 if ((bfd_signed_vma
) disp
> 0)
4442 disp
= - (bfd_signed_vma
) disp
;
4445 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4446 oappend (scratchbuf
);
4449 *obufp
++ = close_char
;
4452 else if (intel_syntax
)
4454 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4455 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4459 oappend (names_seg
[ds_reg
- es_reg
]);
4462 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
4463 oappend (scratchbuf
);
4469 OP_G (int bytemode
, int sizeflag
)
4472 USED_REX (REX_EXTX
);
4480 oappend (names8rex
[reg
+ add
]);
4482 oappend (names8
[reg
+ add
]);
4485 oappend (names16
[reg
+ add
]);
4488 oappend (names32
[reg
+ add
]);
4491 oappend (names64
[reg
+ add
]);
4496 USED_REX (REX_MODE64
);
4497 if (rex
& REX_MODE64
)
4498 oappend (names64
[reg
+ add
]);
4499 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4500 oappend (names32
[reg
+ add
]);
4502 oappend (names16
[reg
+ add
]);
4503 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4506 if (address_mode
== mode_64bit
)
4507 oappend (names64
[reg
+ add
]);
4509 oappend (names32
[reg
+ add
]);
4512 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4525 FETCH_DATA (the_info
, codep
+ 8);
4526 a
= *codep
++ & 0xff;
4527 a
|= (*codep
++ & 0xff) << 8;
4528 a
|= (*codep
++ & 0xff) << 16;
4529 a
|= (*codep
++ & 0xff) << 24;
4530 b
= *codep
++ & 0xff;
4531 b
|= (*codep
++ & 0xff) << 8;
4532 b
|= (*codep
++ & 0xff) << 16;
4533 b
|= (*codep
++ & 0xff) << 24;
4534 x
= a
+ ((bfd_vma
) b
<< 32);
4542 static bfd_signed_vma
4545 bfd_signed_vma x
= 0;
4547 FETCH_DATA (the_info
, codep
+ 4);
4548 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4549 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4550 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4551 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4555 static bfd_signed_vma
4558 bfd_signed_vma x
= 0;
4560 FETCH_DATA (the_info
, codep
+ 4);
4561 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4562 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4563 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4564 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4566 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4576 FETCH_DATA (the_info
, codep
+ 2);
4577 x
= *codep
++ & 0xff;
4578 x
|= (*codep
++ & 0xff) << 8;
4583 set_op (bfd_vma op
, int riprel
)
4585 op_index
[op_ad
] = op_ad
;
4586 if (address_mode
== mode_64bit
)
4588 op_address
[op_ad
] = op
;
4589 op_riprel
[op_ad
] = riprel
;
4593 /* Mask to get a 32-bit address. */
4594 op_address
[op_ad
] = op
& 0xffffffff;
4595 op_riprel
[op_ad
] = riprel
& 0xffffffff;
4600 OP_REG (int code
, int sizeflag
)
4604 USED_REX (REX_EXTZ
);
4610 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4611 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4612 s
= names16
[code
- ax_reg
+ add
];
4614 case es_reg
: case ss_reg
: case cs_reg
:
4615 case ds_reg
: case fs_reg
: case gs_reg
:
4616 s
= names_seg
[code
- es_reg
+ add
];
4618 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4619 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4622 s
= names8rex
[code
- al_reg
+ add
];
4624 s
= names8
[code
- al_reg
];
4626 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4627 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4628 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4630 s
= names64
[code
- rAX_reg
+ add
];
4633 code
+= eAX_reg
- rAX_reg
;
4635 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4636 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4637 USED_REX (REX_MODE64
);
4638 if (rex
& REX_MODE64
)
4639 s
= names64
[code
- eAX_reg
+ add
];
4640 else if (sizeflag
& DFLAG
)
4641 s
= names32
[code
- eAX_reg
+ add
];
4643 s
= names16
[code
- eAX_reg
+ add
];
4644 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4647 s
= INTERNAL_DISASSEMBLER_ERROR
;
4654 OP_IMREG (int code
, int sizeflag
)
4666 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4667 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4668 s
= names16
[code
- ax_reg
];
4670 case es_reg
: case ss_reg
: case cs_reg
:
4671 case ds_reg
: case fs_reg
: case gs_reg
:
4672 s
= names_seg
[code
- es_reg
];
4674 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4675 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4678 s
= names8rex
[code
- al_reg
];
4680 s
= names8
[code
- al_reg
];
4682 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4683 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4684 USED_REX (REX_MODE64
);
4685 if (rex
& REX_MODE64
)
4686 s
= names64
[code
- eAX_reg
];
4687 else if (sizeflag
& DFLAG
)
4688 s
= names32
[code
- eAX_reg
];
4690 s
= names16
[code
- eAX_reg
];
4691 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4694 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4698 if (!(rex
& REX_MODE64
))
4699 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4702 s
= INTERNAL_DISASSEMBLER_ERROR
;
4709 OP_I (int bytemode
, int sizeflag
)
4712 bfd_signed_vma mask
= -1;
4717 FETCH_DATA (the_info
, codep
+ 1);
4722 if (address_mode
== mode_64bit
)
4729 USED_REX (REX_MODE64
);
4730 if (rex
& REX_MODE64
)
4732 else if (sizeflag
& DFLAG
)
4742 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4753 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4758 scratchbuf
[0] = '$';
4759 print_operand_value (scratchbuf
+ 1, 1, op
);
4760 oappend (scratchbuf
+ intel_syntax
);
4761 scratchbuf
[0] = '\0';
4765 OP_I64 (int bytemode
, int sizeflag
)
4768 bfd_signed_vma mask
= -1;
4770 if (address_mode
!= mode_64bit
)
4772 OP_I (bytemode
, sizeflag
);
4779 FETCH_DATA (the_info
, codep
+ 1);
4784 USED_REX (REX_MODE64
);
4785 if (rex
& REX_MODE64
)
4787 else if (sizeflag
& DFLAG
)
4797 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4804 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4809 scratchbuf
[0] = '$';
4810 print_operand_value (scratchbuf
+ 1, 1, op
);
4811 oappend (scratchbuf
+ intel_syntax
);
4812 scratchbuf
[0] = '\0';
4816 OP_sI (int bytemode
, int sizeflag
)
4819 bfd_signed_vma mask
= -1;
4824 FETCH_DATA (the_info
, codep
+ 1);
4826 if ((op
& 0x80) != 0)
4831 USED_REX (REX_MODE64
);
4832 if (rex
& REX_MODE64
)
4834 else if (sizeflag
& DFLAG
)
4843 if ((op
& 0x8000) != 0)
4846 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4851 if ((op
& 0x8000) != 0)
4855 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4859 scratchbuf
[0] = '$';
4860 print_operand_value (scratchbuf
+ 1, 1, op
);
4861 oappend (scratchbuf
+ intel_syntax
);
4865 OP_J (int bytemode
, int sizeflag
)
4873 FETCH_DATA (the_info
, codep
+ 1);
4875 if ((disp
& 0x80) != 0)
4879 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4884 /* For some reason, a data16 prefix on a jump instruction
4885 means that the pc is masked to 16 bits after the
4886 displacement is added! */
4889 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4892 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4895 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4897 print_operand_value (scratchbuf
, 1, disp
);
4898 oappend (scratchbuf
);
4902 OP_SEG (int bytemode
, int sizeflag
)
4904 if (bytemode
== w_mode
)
4905 oappend (names_seg
[reg
]);
4907 OP_E (mod
== 3 ? bytemode
: w_mode
, sizeflag
);
4911 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4915 if (sizeflag
& DFLAG
)
4925 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4927 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4929 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4930 oappend (scratchbuf
);
4934 OP_OFF (int bytemode
, int sizeflag
)
4938 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4939 intel_operand_size (bytemode
, sizeflag
);
4942 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4949 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4950 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4952 oappend (names_seg
[ds_reg
- es_reg
]);
4956 print_operand_value (scratchbuf
, 1, off
);
4957 oappend (scratchbuf
);
4961 OP_OFF64 (int bytemode
, int sizeflag
)
4965 if (address_mode
!= mode_64bit
4966 || (prefixes
& PREFIX_ADDR
))
4968 OP_OFF (bytemode
, sizeflag
);
4972 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4973 intel_operand_size (bytemode
, sizeflag
);
4980 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4981 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4983 oappend (names_seg
[ds_reg
- es_reg
]);
4987 print_operand_value (scratchbuf
, 1, off
);
4988 oappend (scratchbuf
);
4992 ptr_reg (int code
, int sizeflag
)
4996 *obufp
++ = open_char
;
4997 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4998 if (address_mode
== mode_64bit
)
5000 if (!(sizeflag
& AFLAG
))
5001 s
= names32
[code
- eAX_reg
];
5003 s
= names64
[code
- eAX_reg
];
5005 else if (sizeflag
& AFLAG
)
5006 s
= names32
[code
- eAX_reg
];
5008 s
= names16
[code
- eAX_reg
];
5010 *obufp
++ = close_char
;
5015 OP_ESreg (int code
, int sizeflag
)
5021 case 0x6d: /* insw/insl */
5022 intel_operand_size (z_mode
, sizeflag
);
5024 case 0xa5: /* movsw/movsl/movsq */
5025 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5026 case 0xab: /* stosw/stosl */
5027 case 0xaf: /* scasw/scasl */
5028 intel_operand_size (v_mode
, sizeflag
);
5031 intel_operand_size (b_mode
, sizeflag
);
5034 oappend ("%es:" + intel_syntax
);
5035 ptr_reg (code
, sizeflag
);
5039 OP_DSreg (int code
, int sizeflag
)
5045 case 0x6f: /* outsw/outsl */
5046 intel_operand_size (z_mode
, sizeflag
);
5048 case 0xa5: /* movsw/movsl/movsq */
5049 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5050 case 0xad: /* lodsw/lodsl/lodsq */
5051 intel_operand_size (v_mode
, sizeflag
);
5054 intel_operand_size (b_mode
, sizeflag
);
5064 prefixes
|= PREFIX_DS
;
5066 ptr_reg (code
, sizeflag
);
5070 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5075 USED_REX (REX_EXTX
);
5078 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5080 used_prefixes
|= PREFIX_LOCK
;
5083 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
5084 oappend (scratchbuf
+ intel_syntax
);
5088 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5091 USED_REX (REX_EXTX
);
5095 sprintf (scratchbuf
, "db%d", reg
+ add
);
5097 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
5098 oappend (scratchbuf
);
5102 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5104 sprintf (scratchbuf
, "%%tr%d", reg
);
5105 oappend (scratchbuf
+ intel_syntax
);
5109 OP_Rd (int bytemode
, int sizeflag
)
5112 OP_E (bytemode
, sizeflag
);
5118 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5120 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5121 if (prefixes
& PREFIX_DATA
)
5124 USED_REX (REX_EXTX
);
5127 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5130 sprintf (scratchbuf
, "%%mm%d", reg
);
5131 oappend (scratchbuf
+ intel_syntax
);
5135 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5138 USED_REX (REX_EXTX
);
5141 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5142 oappend (scratchbuf
+ intel_syntax
);
5146 OP_EM (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 if (prefixes
& PREFIX_DATA
)
5167 USED_REX (REX_EXTZ
);
5170 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5173 sprintf (scratchbuf
, "%%mm%d", rm
);
5174 oappend (scratchbuf
+ intel_syntax
);
5177 /* cvt* are the only instructions in sse2 which have
5178 both SSE and MMX operands and also have 0x66 prefix
5179 in their opcode. 0x66 was originally used to differentiate
5180 between SSE and MMX instruction(operands). So we have to handle the
5181 cvt* separately using OP_EMC and OP_MXC */
5183 OP_EMC (int bytemode
, int sizeflag
)
5187 if (intel_syntax
&& bytemode
== v_mode
)
5189 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5190 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5192 OP_E (bytemode
, sizeflag
);
5196 /* Skip mod/rm byte. */
5199 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5200 sprintf (scratchbuf
, "%%mm%d", rm
);
5201 oappend (scratchbuf
+ intel_syntax
);
5205 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5207 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5208 sprintf (scratchbuf
, "%%mm%d", reg
);
5209 oappend (scratchbuf
+ intel_syntax
);
5213 OP_EX (int bytemode
, int sizeflag
)
5218 if (intel_syntax
&& bytemode
== v_mode
)
5220 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
5222 case 0: bytemode
= x_mode
; break;
5223 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
5224 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
5225 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
5226 default: bytemode
= 0; break;
5229 OP_E (bytemode
, sizeflag
);
5232 USED_REX (REX_EXTZ
);
5236 /* Skip mod/rm byte. */
5239 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5240 oappend (scratchbuf
+ intel_syntax
);
5244 OP_MS (int bytemode
, int sizeflag
)
5247 OP_EM (bytemode
, sizeflag
);
5253 OP_XS (int bytemode
, int sizeflag
)
5256 OP_EX (bytemode
, sizeflag
);
5262 OP_M (int bytemode
, int sizeflag
)
5265 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5268 OP_E (bytemode
, sizeflag
);
5272 OP_0f07 (int bytemode
, int sizeflag
)
5274 if (mod
!= 3 || rm
!= 0)
5277 OP_E (bytemode
, sizeflag
);
5281 OP_0fae (int bytemode
, int sizeflag
)
5286 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5288 if (reg
< 5 || rm
!= 0)
5290 BadOp (); /* bad sfence, mfence, or lfence */
5296 BadOp (); /* bad clflush */
5300 OP_E (bytemode
, sizeflag
);
5303 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5304 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5305 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5309 NOP_Fixup1 (int bytemode
, int sizeflag
)
5311 if (prefixes
== PREFIX_REPZ
)
5312 strcpy (obuf
, "pause");
5313 else if (prefixes
== PREFIX_DATA
5314 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5315 OP_REG (bytemode
, sizeflag
);
5317 strcpy (obuf
, "nop");
5321 NOP_Fixup2 (int bytemode
, int sizeflag
)
5323 if (prefixes
== PREFIX_DATA
5324 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5325 OP_IMREG (bytemode
, sizeflag
);
5328 static const char *const Suffix3DNow
[] = {
5329 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5330 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5331 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5332 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5333 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5334 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5335 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5336 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5337 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5338 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5339 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5340 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5341 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5342 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5343 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5344 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5345 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5346 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5347 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5348 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5349 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5350 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5351 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5352 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5353 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5354 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5355 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5356 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5357 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5358 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5359 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5360 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5361 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5362 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5363 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5364 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5365 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5366 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5367 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5368 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5369 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5370 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5371 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5372 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5373 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5374 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5375 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5376 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5377 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5378 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5379 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5380 /* CC */ NULL
, NULL
, NULL
, NULL
,
5381 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5382 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5383 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5384 /* DC */ NULL
, NULL
, NULL
, NULL
,
5385 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5386 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5387 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5388 /* EC */ NULL
, NULL
, NULL
, NULL
,
5389 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5390 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5391 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5392 /* FC */ NULL
, NULL
, NULL
, NULL
,
5396 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5398 const char *mnemonic
;
5400 FETCH_DATA (the_info
, codep
+ 1);
5401 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5402 place where an 8-bit immediate would normally go. ie. the last
5403 byte of the instruction. */
5404 obufp
= obuf
+ strlen (obuf
);
5405 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5410 /* Since a variable sized modrm/sib chunk is between the start
5411 of the opcode (0x0f0f) and the opcode suffix, we need to do
5412 all the modrm processing first, and don't know until now that
5413 we have a bad opcode. This necessitates some cleaning up. */
5420 static const char *simd_cmp_op
[] = {
5432 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5434 unsigned int cmp_type
;
5436 FETCH_DATA (the_info
, codep
+ 1);
5437 obufp
= obuf
+ strlen (obuf
);
5438 cmp_type
= *codep
++ & 0xff;
5441 char suffix1
= 'p', suffix2
= 's';
5442 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5443 if (prefixes
& PREFIX_REPZ
)
5447 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5448 if (prefixes
& PREFIX_DATA
)
5452 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5453 if (prefixes
& PREFIX_REPNZ
)
5454 suffix1
= 's', suffix2
= 'd';
5457 sprintf (scratchbuf
, "cmp%s%c%c",
5458 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5459 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5460 oappend (scratchbuf
);
5464 /* We have a bad extension byte. Clean up. */
5472 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
5474 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5475 forms of these instructions. */
5478 char *p
= obuf
+ strlen (obuf
);
5481 *(p
- 1) = *(p
- 2);
5482 *(p
- 2) = *(p
- 3);
5483 *(p
- 3) = extrachar
;
5488 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5490 if (mod
== 3 && reg
== 1 && rm
<= 1)
5492 /* Override "sidt". */
5493 size_t olen
= strlen (obuf
);
5494 char *p
= obuf
+ olen
- 4;
5495 const char **names
= (address_mode
== mode_64bit
5496 ? names64
: names32
);
5498 /* We might have a suffix when disassembling with -Msuffix. */
5502 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5504 && (prefixes
& PREFIX_ADDR
)
5507 && CONST_STRNEQ (p
- 7, "addr")
5508 && (CONST_STRNEQ (p
- 3, "16")
5509 || CONST_STRNEQ (p
- 3, "32")))
5514 /* mwait %eax,%ecx */
5515 strcpy (p
, "mwait");
5517 strcpy (op1out
, names
[0]);
5521 /* monitor %eax,%ecx,%edx" */
5522 strcpy (p
, "monitor");
5525 const char **op1_names
;
5526 if (!(prefixes
& PREFIX_ADDR
))
5527 op1_names
= (address_mode
== mode_16bit
5531 op1_names
= (address_mode
!= mode_32bit
5532 ? names32
: names16
);
5533 used_prefixes
|= PREFIX_ADDR
;
5535 strcpy (op1out
, op1_names
[0]);
5536 strcpy (op3out
, names
[2]);
5541 strcpy (op2out
, names
[1]);
5552 SVME_Fixup (int bytemode
, int sizeflag
)
5584 OP_M (bytemode
, sizeflag
);
5587 /* Override "lidt". */
5588 p
= obuf
+ strlen (obuf
) - 4;
5589 /* We might have a suffix. */
5593 if (!(prefixes
& PREFIX_ADDR
))
5598 used_prefixes
|= PREFIX_ADDR
;
5602 strcpy (op2out
, names32
[1]);
5608 *obufp
++ = open_char
;
5609 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
5613 strcpy (obufp
, alt
);
5614 obufp
+= strlen (alt
);
5615 *obufp
++ = close_char
;
5622 INVLPG_Fixup (int bytemode
, int sizeflag
)
5635 OP_M (bytemode
, sizeflag
);
5638 /* Override "invlpg". */
5639 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
5646 /* Throw away prefixes and 1st. opcode byte. */
5647 codep
= insn_codep
+ 1;
5652 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5654 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
5656 /* Override "sgdt". */
5657 char *p
= obuf
+ strlen (obuf
) - 4;
5659 /* We might have a suffix when disassembling with -Msuffix. */
5666 strcpy (p
, "vmcall");
5669 strcpy (p
, "vmlaunch");
5672 strcpy (p
, "vmresume");
5675 strcpy (p
, "vmxoff");
5686 OP_VMX (int bytemode
, int sizeflag
)
5688 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
5689 if (prefixes
& PREFIX_DATA
)
5690 strcpy (obuf
, "vmclear");
5691 else if (prefixes
& PREFIX_REPZ
)
5692 strcpy (obuf
, "vmxon");
5694 strcpy (obuf
, "vmptrld");
5695 OP_E (bytemode
, sizeflag
);
5699 REP_Fixup (int bytemode
, int sizeflag
)
5701 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5705 if (prefixes
& PREFIX_REPZ
)
5706 switch (*insn_codep
)
5708 case 0x6e: /* outsb */
5709 case 0x6f: /* outsw/outsl */
5710 case 0xa4: /* movsb */
5711 case 0xa5: /* movsw/movsl/movsq */
5717 case 0xaa: /* stosb */
5718 case 0xab: /* stosw/stosl/stosq */
5719 case 0xac: /* lodsb */
5720 case 0xad: /* lodsw/lodsl/lodsq */
5721 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5726 case 0x6c: /* insb */
5727 case 0x6d: /* insl/insw */
5743 olen
= strlen (obuf
);
5744 p
= obuf
+ olen
- ilen
- 1 - 4;
5745 /* Handle "repz [addr16|addr32]". */
5746 if ((prefixes
& PREFIX_ADDR
))
5749 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
5757 OP_IMREG (bytemode
, sizeflag
);
5760 OP_ESreg (bytemode
, sizeflag
);
5763 OP_DSreg (bytemode
, sizeflag
);