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);
107 static void CMPXCHG8B_Fixup (int, int);
110 /* Points to first byte not fetched. */
111 bfd_byte
*max_fetched
;
112 bfd_byte the_buffer
[MAXLEN
];
118 /* The opcode for the fwait instruction, which we treat as a prefix
120 #define FWAIT_OPCODE (0x9b)
129 enum address_mode address_mode
;
131 /* Flags for the prefixes for the current instruction. See below. */
134 /* REX prefix the current instruction. See below. */
136 /* Bits of REX we've already used. */
142 /* Mark parts used in the REX prefix. When we are testing for
143 empty prefix (for 8bit register REX extension), just mask it
144 out. Otherwise test for REX bit is excuse for existence of REX
145 only in case value is nonzero. */
146 #define USED_REX(value) \
149 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
154 /* Flags for prefixes which we somehow handled when printing the
155 current instruction. */
156 static int used_prefixes
;
158 /* Flags stored in PREFIXES. */
159 #define PREFIX_REPZ 1
160 #define PREFIX_REPNZ 2
161 #define PREFIX_LOCK 4
163 #define PREFIX_SS 0x10
164 #define PREFIX_DS 0x20
165 #define PREFIX_ES 0x40
166 #define PREFIX_FS 0x80
167 #define PREFIX_GS 0x100
168 #define PREFIX_DATA 0x200
169 #define PREFIX_ADDR 0x400
170 #define PREFIX_FWAIT 0x800
172 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
173 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
175 #define FETCH_DATA(info, addr) \
176 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
177 ? 1 : fetch_data ((info), (addr)))
180 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
183 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
184 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
186 if (addr
<= priv
->the_buffer
+ MAXLEN
)
187 status
= (*info
->read_memory_func
) (start
,
189 addr
- priv
->max_fetched
,
195 /* If we did manage to read at least one byte, then
196 print_insn_i386 will do something sensible. Otherwise, print
197 an error. We do that here because this is where we know
199 if (priv
->max_fetched
== priv
->the_buffer
)
200 (*info
->memory_error_func
) (status
, start
, info
);
201 longjmp (priv
->bailout
, 1);
204 priv
->max_fetched
= addr
;
208 #define XX { NULL, 0 }
210 #define Eb { OP_E, b_mode }
211 #define Ev { OP_E, v_mode }
212 #define Ed { OP_E, d_mode }
213 #define Edq { OP_E, dq_mode }
214 #define Edqw { OP_E, dqw_mode }
215 #define indirEv { OP_indirE, stack_v_mode }
216 #define indirEp { OP_indirE, f_mode }
217 #define stackEv { OP_E, stack_v_mode }
218 #define Em { OP_E, m_mode }
219 #define Ew { OP_E, w_mode }
220 #define M { OP_M, 0 } /* lea, lgdt, etc. */
221 #define Ma { OP_M, v_mode }
222 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
223 #define Mq { OP_M, q_mode }
224 #define Gb { OP_G, b_mode }
225 #define Gv { OP_G, v_mode }
226 #define Gd { OP_G, d_mode }
227 #define Gdq { OP_G, dq_mode }
228 #define Gm { OP_G, m_mode }
229 #define Gw { OP_G, w_mode }
230 #define Rd { OP_Rd, d_mode }
231 #define Rm { OP_Rd, m_mode }
232 #define Ib { OP_I, b_mode }
233 #define sIb { OP_sI, b_mode } /* sign extened byte */
234 #define Iv { OP_I, v_mode }
235 #define Iq { OP_I, q_mode }
236 #define Iv64 { OP_I64, v_mode }
237 #define Iw { OP_I, w_mode }
238 #define I1 { OP_I, const_1_mode }
239 #define Jb { OP_J, b_mode }
240 #define Jv { OP_J, v_mode }
241 #define Cm { OP_C, m_mode }
242 #define Dm { OP_D, m_mode }
243 #define Td { OP_T, d_mode }
245 #define RMeAX { OP_REG, eAX_reg }
246 #define RMeBX { OP_REG, eBX_reg }
247 #define RMeCX { OP_REG, eCX_reg }
248 #define RMeDX { OP_REG, eDX_reg }
249 #define RMeSP { OP_REG, eSP_reg }
250 #define RMeBP { OP_REG, eBP_reg }
251 #define RMeSI { OP_REG, eSI_reg }
252 #define RMeDI { OP_REG, eDI_reg }
253 #define RMrAX { OP_REG, rAX_reg }
254 #define RMrBX { OP_REG, rBX_reg }
255 #define RMrCX { OP_REG, rCX_reg }
256 #define RMrDX { OP_REG, rDX_reg }
257 #define RMrSP { OP_REG, rSP_reg }
258 #define RMrBP { OP_REG, rBP_reg }
259 #define RMrSI { OP_REG, rSI_reg }
260 #define RMrDI { OP_REG, rDI_reg }
261 #define RMAL { OP_REG, al_reg }
262 #define RMAL { OP_REG, al_reg }
263 #define RMCL { OP_REG, cl_reg }
264 #define RMDL { OP_REG, dl_reg }
265 #define RMBL { OP_REG, bl_reg }
266 #define RMAH { OP_REG, ah_reg }
267 #define RMCH { OP_REG, ch_reg }
268 #define RMDH { OP_REG, dh_reg }
269 #define RMBH { OP_REG, bh_reg }
270 #define RMAX { OP_REG, ax_reg }
271 #define RMDX { OP_REG, dx_reg }
273 #define eAX { OP_IMREG, eAX_reg }
274 #define eBX { OP_IMREG, eBX_reg }
275 #define eCX { OP_IMREG, eCX_reg }
276 #define eDX { OP_IMREG, eDX_reg }
277 #define eSP { OP_IMREG, eSP_reg }
278 #define eBP { OP_IMREG, eBP_reg }
279 #define eSI { OP_IMREG, eSI_reg }
280 #define eDI { OP_IMREG, eDI_reg }
281 #define AL { OP_IMREG, al_reg }
282 #define CL { OP_IMREG, cl_reg }
283 #define DL { OP_IMREG, dl_reg }
284 #define BL { OP_IMREG, bl_reg }
285 #define AH { OP_IMREG, ah_reg }
286 #define CH { OP_IMREG, ch_reg }
287 #define DH { OP_IMREG, dh_reg }
288 #define BH { OP_IMREG, bh_reg }
289 #define AX { OP_IMREG, ax_reg }
290 #define DX { OP_IMREG, dx_reg }
291 #define zAX { OP_IMREG, z_mode_ax_reg }
292 #define indirDX { OP_IMREG, indir_dx_reg }
294 #define Sw { OP_SEG, w_mode }
295 #define Sv { OP_SEG, v_mode }
296 #define Ap { OP_DIR, 0 }
297 #define Ob { OP_OFF64, b_mode }
298 #define Ov { OP_OFF64, v_mode }
299 #define Xb { OP_DSreg, eSI_reg }
300 #define Xv { OP_DSreg, eSI_reg }
301 #define Xz { OP_DSreg, eSI_reg }
302 #define Yb { OP_ESreg, eDI_reg }
303 #define Yv { OP_ESreg, eDI_reg }
304 #define DSBX { OP_DSreg, eBX_reg }
306 #define es { OP_REG, es_reg }
307 #define ss { OP_REG, ss_reg }
308 #define cs { OP_REG, cs_reg }
309 #define ds { OP_REG, ds_reg }
310 #define fs { OP_REG, fs_reg }
311 #define gs { OP_REG, gs_reg }
313 #define MX { OP_MMX, 0 }
314 #define XM { OP_XMM, 0 }
315 #define EM { OP_EM, v_mode }
316 #define EX { OP_EX, v_mode }
317 #define MS { OP_MS, v_mode }
318 #define XS { OP_XS, v_mode }
319 #define EMC { OP_EMC, v_mode }
320 #define MXC { OP_MXC, 0 }
321 #define VM { OP_VMX, q_mode }
322 #define OPSUF { OP_3DNowSuffix, 0 }
323 #define OPSIMD { OP_SIMD_Suffix, 0 }
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr { REP_Fixup, eSI_reg }
327 #define Xvr { REP_Fixup, eSI_reg }
328 #define Ybr { REP_Fixup, eDI_reg }
329 #define Yvr { REP_Fixup, eDI_reg }
330 #define Yzr { REP_Fixup, eDI_reg }
331 #define indirDXr { REP_Fixup, indir_dx_reg }
332 #define ALr { REP_Fixup, al_reg }
333 #define eAXr { REP_Fixup, eAX_reg }
335 #define cond_jump_flag { NULL, cond_jump_mode }
336 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
359 #define o_mode 17 /* 16-byte operand */
404 #define z_mode_ax_reg 149
405 #define indir_dx_reg 150
409 #define USE_PREFIX_USER_TABLE 3
410 #define X86_64_SPECIAL 4
411 #define IS_3BYTE_OPCODE 5
413 #define FLOAT NULL, { { NULL, FLOATCODE } }
415 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
416 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
417 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
418 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
419 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
420 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
421 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
422 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
423 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
424 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
425 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
426 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
427 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
428 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
429 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
430 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
431 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
432 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
433 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
434 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
435 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
436 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
437 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
438 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
439 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
440 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
441 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
443 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
444 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
445 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
446 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
447 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
448 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
449 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
450 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
451 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
452 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
453 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
454 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
455 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
456 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
457 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
458 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
459 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
460 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
461 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
462 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
463 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
464 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
465 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
466 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
467 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
468 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
469 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
470 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
471 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
472 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
473 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
474 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
475 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
476 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
477 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
478 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
479 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
480 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
483 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
484 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
485 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
486 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
488 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
489 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
491 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
493 #define MAX_OPERANDS 4
504 /* Upper case letters in the instruction names here are macros.
505 'A' => print 'b' if no register operands or suffix_always is true
506 'B' => print 'b' if suffix_always is true
507 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
509 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
510 . suffix_always is true
511 'E' => print 'e' if 32-bit form of jcxz
512 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
513 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
514 'H' => print ",pt" or ",pn" branch hint
515 'I' => honor following macro letter even in Intel mode (implemented only
516 . for some of the macro letters)
518 'L' => print 'l' if suffix_always is true
519 'N' => print 'n' if instruction has no wait "prefix"
520 'O' => print 'd' or 'o' (or 'q' in Intel mode)
521 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
522 . or suffix_always is true. print 'q' if rex prefix is present.
523 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
525 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
526 'S' => print 'w', 'l' or 'q' if suffix_always is true
527 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
528 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
529 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
530 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
531 'X' => print 's', 'd' depending on data16 prefix (for XMM)
532 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
533 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
535 Many of the above letters print nothing in Intel mode. See "putop"
538 Braces '{' and '}', and vertical bars '|', indicate alternative
539 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
540 modes. In cases where there are only two alternatives, the X86_64
541 instruction is reserved, and "(bad)" is printed.
544 static const struct dis386 dis386
[] = {
546 { "addB", { Eb
, Gb
} },
547 { "addS", { Ev
, Gv
} },
548 { "addB", { Gb
, Eb
} },
549 { "addS", { Gv
, Ev
} },
550 { "addB", { AL
, Ib
} },
551 { "addS", { eAX
, Iv
} },
552 { "push{T|}", { es
} },
553 { "pop{T|}", { es
} },
555 { "orB", { Eb
, Gb
} },
556 { "orS", { Ev
, Gv
} },
557 { "orB", { Gb
, Eb
} },
558 { "orS", { Gv
, Ev
} },
559 { "orB", { AL
, Ib
} },
560 { "orS", { eAX
, Iv
} },
561 { "push{T|}", { cs
} },
562 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
564 { "adcB", { Eb
, Gb
} },
565 { "adcS", { Ev
, Gv
} },
566 { "adcB", { Gb
, Eb
} },
567 { "adcS", { Gv
, Ev
} },
568 { "adcB", { AL
, Ib
} },
569 { "adcS", { eAX
, Iv
} },
570 { "push{T|}", { ss
} },
571 { "pop{T|}", { ss
} },
573 { "sbbB", { Eb
, Gb
} },
574 { "sbbS", { Ev
, Gv
} },
575 { "sbbB", { Gb
, Eb
} },
576 { "sbbS", { Gv
, Ev
} },
577 { "sbbB", { AL
, Ib
} },
578 { "sbbS", { eAX
, Iv
} },
579 { "push{T|}", { ds
} },
580 { "pop{T|}", { ds
} },
582 { "andB", { Eb
, Gb
} },
583 { "andS", { Ev
, Gv
} },
584 { "andB", { Gb
, Eb
} },
585 { "andS", { Gv
, Ev
} },
586 { "andB", { AL
, Ib
} },
587 { "andS", { eAX
, Iv
} },
588 { "(bad)", { XX
} }, /* SEG ES prefix */
589 { "daa{|}", { XX
} },
591 { "subB", { Eb
, Gb
} },
592 { "subS", { Ev
, Gv
} },
593 { "subB", { Gb
, Eb
} },
594 { "subS", { Gv
, Ev
} },
595 { "subB", { AL
, Ib
} },
596 { "subS", { eAX
, Iv
} },
597 { "(bad)", { XX
} }, /* SEG CS prefix */
598 { "das{|}", { XX
} },
600 { "xorB", { Eb
, Gb
} },
601 { "xorS", { Ev
, Gv
} },
602 { "xorB", { Gb
, Eb
} },
603 { "xorS", { Gv
, Ev
} },
604 { "xorB", { AL
, Ib
} },
605 { "xorS", { eAX
, Iv
} },
606 { "(bad)", { XX
} }, /* SEG SS prefix */
607 { "aaa{|}", { XX
} },
609 { "cmpB", { Eb
, Gb
} },
610 { "cmpS", { Ev
, Gv
} },
611 { "cmpB", { Gb
, Eb
} },
612 { "cmpS", { Gv
, Ev
} },
613 { "cmpB", { AL
, Ib
} },
614 { "cmpS", { eAX
, Iv
} },
615 { "(bad)", { XX
} }, /* SEG DS prefix */
616 { "aas{|}", { XX
} },
618 { "inc{S|}", { RMeAX
} },
619 { "inc{S|}", { RMeCX
} },
620 { "inc{S|}", { RMeDX
} },
621 { "inc{S|}", { RMeBX
} },
622 { "inc{S|}", { RMeSP
} },
623 { "inc{S|}", { RMeBP
} },
624 { "inc{S|}", { RMeSI
} },
625 { "inc{S|}", { RMeDI
} },
627 { "dec{S|}", { RMeAX
} },
628 { "dec{S|}", { RMeCX
} },
629 { "dec{S|}", { RMeDX
} },
630 { "dec{S|}", { RMeBX
} },
631 { "dec{S|}", { RMeSP
} },
632 { "dec{S|}", { RMeBP
} },
633 { "dec{S|}", { RMeSI
} },
634 { "dec{S|}", { RMeDI
} },
636 { "pushV", { RMrAX
} },
637 { "pushV", { RMrCX
} },
638 { "pushV", { RMrDX
} },
639 { "pushV", { RMrBX
} },
640 { "pushV", { RMrSP
} },
641 { "pushV", { RMrBP
} },
642 { "pushV", { RMrSI
} },
643 { "pushV", { RMrDI
} },
645 { "popV", { RMrAX
} },
646 { "popV", { RMrCX
} },
647 { "popV", { RMrDX
} },
648 { "popV", { RMrBX
} },
649 { "popV", { RMrSP
} },
650 { "popV", { RMrBP
} },
651 { "popV", { RMrSI
} },
652 { "popV", { RMrDI
} },
658 { "(bad)", { XX
} }, /* seg fs */
659 { "(bad)", { XX
} }, /* seg gs */
660 { "(bad)", { XX
} }, /* op size prefix */
661 { "(bad)", { XX
} }, /* adr size prefix */
664 { "imulS", { Gv
, Ev
, Iv
} },
665 { "pushT", { sIb
} },
666 { "imulS", { Gv
, Ev
, sIb
} },
667 { "ins{b||b|}", { Ybr
, indirDX
} },
668 { "ins{R||G|}", { Yzr
, indirDX
} },
669 { "outs{b||b|}", { indirDXr
, Xb
} },
670 { "outs{R||G|}", { indirDXr
, Xz
} },
672 { "joH", { Jb
, XX
, cond_jump_flag
} },
673 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
674 { "jbH", { Jb
, XX
, cond_jump_flag
} },
675 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
676 { "jeH", { Jb
, XX
, cond_jump_flag
} },
677 { "jneH", { Jb
, XX
, cond_jump_flag
} },
678 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
679 { "jaH", { Jb
, XX
, cond_jump_flag
} },
681 { "jsH", { Jb
, XX
, cond_jump_flag
} },
682 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
683 { "jpH", { Jb
, XX
, cond_jump_flag
} },
684 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
685 { "jlH", { Jb
, XX
, cond_jump_flag
} },
686 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
687 { "jleH", { Jb
, XX
, cond_jump_flag
} },
688 { "jgH", { Jb
, XX
, cond_jump_flag
} },
694 { "testB", { Eb
, Gb
} },
695 { "testS", { Ev
, Gv
} },
696 { "xchgB", { Eb
, Gb
} },
697 { "xchgS", { Ev
, Gv
} },
699 { "movB", { Eb
, Gb
} },
700 { "movS", { Ev
, Gv
} },
701 { "movB", { Gb
, Eb
} },
702 { "movS", { Gv
, Ev
} },
703 { "movD", { Sv
, Sw
} },
704 { "leaS", { Gv
, M
} },
705 { "movD", { Sw
, Sv
} },
706 { "popU", { stackEv
} },
708 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
709 { "xchgS", { RMeCX
, eAX
} },
710 { "xchgS", { RMeDX
, eAX
} },
711 { "xchgS", { RMeBX
, eAX
} },
712 { "xchgS", { RMeSP
, eAX
} },
713 { "xchgS", { RMeBP
, eAX
} },
714 { "xchgS", { RMeSI
, eAX
} },
715 { "xchgS", { RMeDI
, eAX
} },
717 { "cW{t||t|}R", { XX
} },
718 { "cR{t||t|}O", { XX
} },
719 { "Jcall{T|}", { Ap
} },
720 { "(bad)", { XX
} }, /* fwait */
721 { "pushfT", { XX
} },
723 { "sahf{|}", { XX
} },
724 { "lahf{|}", { XX
} },
726 { "movB", { AL
, Ob
} },
727 { "movS", { eAX
, Ov
} },
728 { "movB", { Ob
, AL
} },
729 { "movS", { Ov
, eAX
} },
730 { "movs{b||b|}", { Ybr
, Xb
} },
731 { "movs{R||R|}", { Yvr
, Xv
} },
732 { "cmps{b||b|}", { Xb
, Yb
} },
733 { "cmps{R||R|}", { Xv
, Yv
} },
735 { "testB", { AL
, Ib
} },
736 { "testS", { eAX
, Iv
} },
737 { "stosB", { Ybr
, AL
} },
738 { "stosS", { Yvr
, eAX
} },
739 { "lodsB", { ALr
, Xb
} },
740 { "lodsS", { eAXr
, Xv
} },
741 { "scasB", { AL
, Yb
} },
742 { "scasS", { eAX
, Yv
} },
744 { "movB", { RMAL
, Ib
} },
745 { "movB", { RMCL
, Ib
} },
746 { "movB", { RMDL
, Ib
} },
747 { "movB", { RMBL
, Ib
} },
748 { "movB", { RMAH
, Ib
} },
749 { "movB", { RMCH
, Ib
} },
750 { "movB", { RMDH
, Ib
} },
751 { "movB", { RMBH
, Ib
} },
753 { "movS", { RMeAX
, Iv64
} },
754 { "movS", { RMeCX
, Iv64
} },
755 { "movS", { RMeDX
, Iv64
} },
756 { "movS", { RMeBX
, Iv64
} },
757 { "movS", { RMeSP
, Iv64
} },
758 { "movS", { RMeBP
, Iv64
} },
759 { "movS", { RMeSI
, Iv64
} },
760 { "movS", { RMeDI
, Iv64
} },
766 { "les{S|}", { Gv
, Mp
} },
767 { "ldsS", { Gv
, Mp
} },
771 { "enterT", { Iw
, Ib
} },
772 { "leaveT", { XX
} },
777 { "into{|}", { XX
} },
784 { "aam{|}", { sIb
} },
785 { "aad{|}", { sIb
} },
787 { "xlat", { DSBX
} },
798 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
799 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
800 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
801 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
802 { "inB", { AL
, Ib
} },
803 { "inG", { zAX
, Ib
} },
804 { "outB", { Ib
, AL
} },
805 { "outG", { Ib
, zAX
} },
809 { "Jjmp{T|}", { Ap
} },
811 { "inB", { AL
, indirDX
} },
812 { "inG", { zAX
, indirDX
} },
813 { "outB", { indirDX
, AL
} },
814 { "outG", { indirDX
, zAX
} },
816 { "(bad)", { XX
} }, /* lock prefix */
818 { "(bad)", { XX
} }, /* repne */
819 { "(bad)", { XX
} }, /* repz */
835 static const struct dis386 dis386_twobyte
[] = {
839 { "larS", { Gv
, Ew
} },
840 { "lslS", { Gv
, Ew
} },
842 { "syscall", { XX
} },
844 { "sysretP", { XX
} },
847 { "wbinvd", { XX
} },
853 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
858 { "movlpX", { EX
, XM
, { SIMD_Fixup
, 'h' } } },
859 { "unpcklpX", { XM
, EX
} },
860 { "unpckhpX", { XM
, EX
} },
862 { "movhpX", { EX
, XM
, { SIMD_Fixup
, 'l' } } },
873 { "movZ", { Rm
, Cm
} },
874 { "movZ", { Rm
, Dm
} },
875 { "movZ", { Cm
, Rm
} },
876 { "movZ", { Dm
, Rm
} },
877 { "movL", { Rd
, Td
} },
879 { "movL", { Td
, Rd
} },
882 { "movapX", { XM
, EX
} },
883 { "movapX", { EX
, XM
} },
888 { "ucomisX", { XM
,EX
} },
889 { "comisX", { XM
,EX
} },
895 { "sysenter", { XX
} },
896 { "sysexit", { XX
} },
909 { "cmovo", { Gv
, Ev
} },
910 { "cmovno", { Gv
, Ev
} },
911 { "cmovb", { Gv
, Ev
} },
912 { "cmovae", { Gv
, Ev
} },
913 { "cmove", { Gv
, Ev
} },
914 { "cmovne", { Gv
, Ev
} },
915 { "cmovbe", { Gv
, Ev
} },
916 { "cmova", { Gv
, Ev
} },
918 { "cmovs", { Gv
, Ev
} },
919 { "cmovns", { Gv
, Ev
} },
920 { "cmovp", { Gv
, Ev
} },
921 { "cmovnp", { Gv
, Ev
} },
922 { "cmovl", { Gv
, Ev
} },
923 { "cmovge", { Gv
, Ev
} },
924 { "cmovle", { Gv
, Ev
} },
925 { "cmovg", { Gv
, Ev
} },
927 { "movmskpX", { Gdq
, XS
} },
931 { "andpX", { XM
, EX
} },
932 { "andnpX", { XM
, EX
} },
933 { "orpX", { XM
, EX
} },
934 { "xorpX", { XM
, EX
} },
945 { "punpcklbw", { MX
, EM
} },
946 { "punpcklwd", { MX
, EM
} },
947 { "punpckldq", { MX
, EM
} },
948 { "packsswb", { MX
, EM
} },
949 { "pcmpgtb", { MX
, EM
} },
950 { "pcmpgtw", { MX
, EM
} },
951 { "pcmpgtd", { MX
, EM
} },
952 { "packuswb", { MX
, EM
} },
954 { "punpckhbw", { MX
, EM
} },
955 { "punpckhwd", { MX
, EM
} },
956 { "punpckhdq", { MX
, EM
} },
957 { "packssdw", { MX
, EM
} },
960 { "movd", { MX
, Edq
} },
967 { "pcmpeqb", { MX
, EM
} },
968 { "pcmpeqw", { MX
, EM
} },
969 { "pcmpeqd", { MX
, EM
} },
981 { "joH", { Jv
, XX
, cond_jump_flag
} },
982 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
983 { "jbH", { Jv
, XX
, cond_jump_flag
} },
984 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
985 { "jeH", { Jv
, XX
, cond_jump_flag
} },
986 { "jneH", { Jv
, XX
, cond_jump_flag
} },
987 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
988 { "jaH", { Jv
, XX
, cond_jump_flag
} },
990 { "jsH", { Jv
, XX
, cond_jump_flag
} },
991 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
992 { "jpH", { Jv
, XX
, cond_jump_flag
} },
993 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
994 { "jlH", { Jv
, XX
, cond_jump_flag
} },
995 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
996 { "jleH", { Jv
, XX
, cond_jump_flag
} },
997 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1000 { "setno", { Eb
} },
1002 { "setae", { Eb
} },
1004 { "setne", { Eb
} },
1005 { "setbe", { Eb
} },
1009 { "setns", { Eb
} },
1011 { "setnp", { Eb
} },
1013 { "setge", { Eb
} },
1014 { "setle", { Eb
} },
1017 { "pushT", { fs
} },
1019 { "cpuid", { XX
} },
1020 { "btS", { Ev
, Gv
} },
1021 { "shldS", { Ev
, Gv
, Ib
} },
1022 { "shldS", { Ev
, Gv
, CL
} },
1026 { "pushT", { gs
} },
1029 { "btsS", { Ev
, Gv
} },
1030 { "shrdS", { Ev
, Gv
, Ib
} },
1031 { "shrdS", { Ev
, Gv
, CL
} },
1033 { "imulS", { Gv
, Ev
} },
1035 { "cmpxchgB", { Eb
, Gb
} },
1036 { "cmpxchgS", { Ev
, Gv
} },
1037 { "lssS", { Gv
, Mp
} },
1038 { "btrS", { Ev
, Gv
} },
1039 { "lfsS", { Gv
, Mp
} },
1040 { "lgsS", { Gv
, Mp
} },
1041 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1042 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1047 { "btcS", { Ev
, Gv
} },
1048 { "bsfS", { Gv
, Ev
} },
1050 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1051 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1053 { "xaddB", { Eb
, Gb
} },
1054 { "xaddS", { Ev
, Gv
} },
1056 { "movntiS", { Ev
, Gv
} },
1057 { "pinsrw", { MX
, Edqw
, Ib
} },
1058 { "pextrw", { Gdq
, MS
, Ib
} },
1059 { "shufpX", { XM
, EX
, Ib
} },
1062 { "bswap", { RMeAX
} },
1063 { "bswap", { RMeCX
} },
1064 { "bswap", { RMeDX
} },
1065 { "bswap", { RMeBX
} },
1066 { "bswap", { RMeSP
} },
1067 { "bswap", { RMeBP
} },
1068 { "bswap", { RMeSI
} },
1069 { "bswap", { RMeDI
} },
1072 { "psrlw", { MX
, EM
} },
1073 { "psrld", { MX
, EM
} },
1074 { "psrlq", { MX
, EM
} },
1075 { "paddq", { MX
, EM
} },
1076 { "pmullw", { MX
, EM
} },
1078 { "pmovmskb", { Gdq
, MS
} },
1080 { "psubusb", { MX
, EM
} },
1081 { "psubusw", { MX
, EM
} },
1082 { "pminub", { MX
, EM
} },
1083 { "pand", { MX
, EM
} },
1084 { "paddusb", { MX
, EM
} },
1085 { "paddusw", { MX
, EM
} },
1086 { "pmaxub", { MX
, EM
} },
1087 { "pandn", { MX
, EM
} },
1089 { "pavgb", { MX
, EM
} },
1090 { "psraw", { MX
, EM
} },
1091 { "psrad", { MX
, EM
} },
1092 { "pavgw", { MX
, EM
} },
1093 { "pmulhuw", { MX
, EM
} },
1094 { "pmulhw", { MX
, EM
} },
1098 { "psubsb", { MX
, EM
} },
1099 { "psubsw", { MX
, EM
} },
1100 { "pminsw", { MX
, EM
} },
1101 { "por", { MX
, EM
} },
1102 { "paddsb", { MX
, EM
} },
1103 { "paddsw", { MX
, EM
} },
1104 { "pmaxsw", { MX
, EM
} },
1105 { "pxor", { MX
, EM
} },
1108 { "psllw", { MX
, EM
} },
1109 { "pslld", { MX
, EM
} },
1110 { "psllq", { MX
, EM
} },
1111 { "pmuludq", { MX
, EM
} },
1112 { "pmaddwd", { MX
, EM
} },
1113 { "psadbw", { MX
, EM
} },
1116 { "psubb", { MX
, EM
} },
1117 { "psubw", { MX
, EM
} },
1118 { "psubd", { MX
, EM
} },
1119 { "psubq", { MX
, EM
} },
1120 { "paddb", { MX
, EM
} },
1121 { "paddw", { MX
, EM
} },
1122 { "paddd", { MX
, EM
} },
1123 { "(bad)", { XX
} },
1126 static const unsigned char onebyte_has_modrm
[256] = {
1127 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1128 /* ------------------------------- */
1129 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1130 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1131 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1132 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1133 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1134 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1135 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1136 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1137 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1138 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1139 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1140 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1141 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1142 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1143 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1144 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1145 /* ------------------------------- */
1146 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1149 static const unsigned char twobyte_has_modrm
[256] = {
1150 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1151 /* ------------------------------- */
1152 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1153 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1154 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1155 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1156 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1157 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1158 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1159 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1160 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1161 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1162 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1163 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1164 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1165 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1166 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1167 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1168 /* ------------------------------- */
1169 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1172 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1173 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1174 /* ------------------------------- */
1175 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1176 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1177 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1178 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1179 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1180 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1181 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1182 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1183 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1184 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1185 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1186 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1187 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1188 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1189 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1190 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1191 /* ------------------------------- */
1192 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1195 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1196 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1197 /* ------------------------------- */
1198 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1199 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1200 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1201 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1202 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1203 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1204 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1205 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1206 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1207 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1208 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1209 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1210 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1211 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1212 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1213 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1214 /* ------------------------------- */
1215 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1218 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1219 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1220 /* ------------------------------- */
1221 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1222 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1223 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1224 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1225 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1226 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1227 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1228 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1229 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1230 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1231 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1232 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1233 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1234 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1235 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1236 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1237 /* ------------------------------- */
1238 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1241 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1242 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1243 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1244 /* ------------------------------- */
1245 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1246 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1247 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1248 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1249 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1250 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1251 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1252 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1253 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1254 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1255 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1256 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1257 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1258 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1259 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1260 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1261 /* ------------------------------- */
1262 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1265 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1266 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1267 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1268 /* ------------------------------- */
1269 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1270 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1271 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1272 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1273 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1274 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1275 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1276 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1277 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1278 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1279 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1280 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1281 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1282 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1283 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1284 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1285 /* ------------------------------- */
1286 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1289 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1290 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1291 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1292 /* ------------------------------- */
1293 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1294 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1295 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1296 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1297 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1298 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1299 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1300 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1301 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1302 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1303 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1304 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1305 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1306 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1307 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1308 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1309 /* ------------------------------- */
1310 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1313 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1314 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1315 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1316 /* ------------------------------- */
1317 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1318 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1319 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1320 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1321 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1322 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1323 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1324 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1325 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1326 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1327 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1328 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1329 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1330 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1331 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1332 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1333 /* ------------------------------- */
1334 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1337 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1338 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1339 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1340 /* ------------------------------- */
1341 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1342 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1343 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1344 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1345 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1346 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1347 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1348 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1349 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1350 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1351 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1352 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1353 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1354 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1355 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1356 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1357 /* ------------------------------- */
1358 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1361 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1362 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1363 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1364 /* ------------------------------- */
1365 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1366 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1367 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1368 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1369 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1370 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1371 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1372 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1373 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1374 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1375 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1376 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1377 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1378 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1379 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1380 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1381 /* ------------------------------- */
1382 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1385 static char obuf
[100];
1387 static char scratchbuf
[100];
1388 static unsigned char *start_codep
;
1389 static unsigned char *insn_codep
;
1390 static unsigned char *codep
;
1391 static disassemble_info
*the_info
;
1395 static unsigned char need_modrm
;
1397 /* If we are accessing mod/rm/reg without need_modrm set, then the
1398 values are stale. Hitting this abort likely indicates that you
1399 need to update onebyte_has_modrm or twobyte_has_modrm. */
1400 #define MODRM_CHECK if (!need_modrm) abort ()
1402 static const char **names64
;
1403 static const char **names32
;
1404 static const char **names16
;
1405 static const char **names8
;
1406 static const char **names8rex
;
1407 static const char **names_seg
;
1408 static const char **index16
;
1410 static const char *intel_names64
[] = {
1411 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1412 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1414 static const char *intel_names32
[] = {
1415 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1416 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1418 static const char *intel_names16
[] = {
1419 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1420 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1422 static const char *intel_names8
[] = {
1423 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1425 static const char *intel_names8rex
[] = {
1426 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1427 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1429 static const char *intel_names_seg
[] = {
1430 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1432 static const char *intel_index16
[] = {
1433 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1436 static const char *att_names64
[] = {
1437 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1438 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1440 static const char *att_names32
[] = {
1441 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1442 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1444 static const char *att_names16
[] = {
1445 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1446 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1448 static const char *att_names8
[] = {
1449 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1451 static const char *att_names8rex
[] = {
1452 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1453 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1455 static const char *att_names_seg
[] = {
1456 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1458 static const char *att_index16
[] = {
1459 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1462 static const struct dis386 grps
[][8] = {
1465 { "addA", { Eb
, Ib
} },
1466 { "orA", { Eb
, Ib
} },
1467 { "adcA", { Eb
, Ib
} },
1468 { "sbbA", { Eb
, Ib
} },
1469 { "andA", { Eb
, Ib
} },
1470 { "subA", { Eb
, Ib
} },
1471 { "xorA", { Eb
, Ib
} },
1472 { "cmpA", { Eb
, Ib
} },
1476 { "addQ", { Ev
, Iv
} },
1477 { "orQ", { Ev
, Iv
} },
1478 { "adcQ", { Ev
, Iv
} },
1479 { "sbbQ", { Ev
, Iv
} },
1480 { "andQ", { Ev
, Iv
} },
1481 { "subQ", { Ev
, Iv
} },
1482 { "xorQ", { Ev
, Iv
} },
1483 { "cmpQ", { Ev
, Iv
} },
1487 { "addQ", { Ev
, sIb
} },
1488 { "orQ", { Ev
, sIb
} },
1489 { "adcQ", { Ev
, sIb
} },
1490 { "sbbQ", { Ev
, sIb
} },
1491 { "andQ", { Ev
, sIb
} },
1492 { "subQ", { Ev
, sIb
} },
1493 { "xorQ", { Ev
, sIb
} },
1494 { "cmpQ", { Ev
, sIb
} },
1498 { "rolA", { Eb
, Ib
} },
1499 { "rorA", { Eb
, Ib
} },
1500 { "rclA", { Eb
, Ib
} },
1501 { "rcrA", { Eb
, Ib
} },
1502 { "shlA", { Eb
, Ib
} },
1503 { "shrA", { Eb
, Ib
} },
1504 { "(bad)", { XX
} },
1505 { "sarA", { Eb
, Ib
} },
1509 { "rolQ", { Ev
, Ib
} },
1510 { "rorQ", { Ev
, Ib
} },
1511 { "rclQ", { Ev
, Ib
} },
1512 { "rcrQ", { Ev
, Ib
} },
1513 { "shlQ", { Ev
, Ib
} },
1514 { "shrQ", { Ev
, Ib
} },
1515 { "(bad)", { XX
} },
1516 { "sarQ", { Ev
, Ib
} },
1520 { "rolA", { Eb
, I1
} },
1521 { "rorA", { Eb
, I1
} },
1522 { "rclA", { Eb
, I1
} },
1523 { "rcrA", { Eb
, I1
} },
1524 { "shlA", { Eb
, I1
} },
1525 { "shrA", { Eb
, I1
} },
1526 { "(bad)", { XX
} },
1527 { "sarA", { Eb
, I1
} },
1531 { "rolQ", { Ev
, I1
} },
1532 { "rorQ", { Ev
, I1
} },
1533 { "rclQ", { Ev
, I1
} },
1534 { "rcrQ", { Ev
, I1
} },
1535 { "shlQ", { Ev
, I1
} },
1536 { "shrQ", { Ev
, I1
} },
1537 { "(bad)", { XX
} },
1538 { "sarQ", { Ev
, I1
} },
1542 { "rolA", { Eb
, CL
} },
1543 { "rorA", { Eb
, CL
} },
1544 { "rclA", { Eb
, CL
} },
1545 { "rcrA", { Eb
, CL
} },
1546 { "shlA", { Eb
, CL
} },
1547 { "shrA", { Eb
, CL
} },
1548 { "(bad)", { XX
} },
1549 { "sarA", { Eb
, CL
} },
1553 { "rolQ", { Ev
, CL
} },
1554 { "rorQ", { Ev
, CL
} },
1555 { "rclQ", { Ev
, CL
} },
1556 { "rcrQ", { Ev
, CL
} },
1557 { "shlQ", { Ev
, CL
} },
1558 { "shrQ", { Ev
, CL
} },
1559 { "(bad)", { XX
} },
1560 { "sarQ", { Ev
, CL
} },
1564 { "testA", { Eb
, Ib
} },
1565 { "(bad)", { Eb
} },
1568 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1569 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1570 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1571 { "idivA", { Eb
} }, /* and idiv for consistency. */
1575 { "testQ", { Ev
, Iv
} },
1576 { "(bad)", { XX
} },
1579 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1580 { "imulQ", { Ev
} },
1582 { "idivQ", { Ev
} },
1588 { "(bad)", { XX
} },
1589 { "(bad)", { XX
} },
1590 { "(bad)", { XX
} },
1591 { "(bad)", { XX
} },
1592 { "(bad)", { XX
} },
1593 { "(bad)", { XX
} },
1599 { "callT", { indirEv
} },
1600 { "JcallT", { indirEp
} },
1601 { "jmpT", { indirEv
} },
1602 { "JjmpT", { indirEp
} },
1603 { "pushU", { stackEv
} },
1604 { "(bad)", { XX
} },
1608 { "sldtD", { Sv
} },
1614 { "(bad)", { XX
} },
1615 { "(bad)", { XX
} },
1619 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1620 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1621 { "lgdt{Q|Q||}", { M
} },
1622 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1623 { "smswD", { Sv
} },
1624 { "(bad)", { XX
} },
1626 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1630 { "(bad)", { XX
} },
1631 { "(bad)", { XX
} },
1632 { "(bad)", { XX
} },
1633 { "(bad)", { XX
} },
1634 { "btQ", { Ev
, Ib
} },
1635 { "btsQ", { Ev
, Ib
} },
1636 { "btrQ", { Ev
, Ib
} },
1637 { "btcQ", { Ev
, Ib
} },
1641 { "(bad)", { XX
} },
1642 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1643 { "(bad)", { XX
} },
1644 { "(bad)", { XX
} },
1645 { "(bad)", { XX
} },
1646 { "(bad)", { XX
} },
1647 { "", { VM
} }, /* See OP_VMX. */
1648 { "vmptrst", { Mq
} },
1652 { "movA", { Eb
, Ib
} },
1653 { "(bad)", { XX
} },
1654 { "(bad)", { XX
} },
1655 { "(bad)", { XX
} },
1656 { "(bad)", { XX
} },
1657 { "(bad)", { XX
} },
1658 { "(bad)", { XX
} },
1659 { "(bad)", { XX
} },
1663 { "movQ", { Ev
, Iv
} },
1664 { "(bad)", { XX
} },
1665 { "(bad)", { XX
} },
1666 { "(bad)", { XX
} },
1667 { "(bad)", { XX
} },
1668 { "(bad)", { XX
} },
1669 { "(bad)", { XX
} },
1670 { "(bad)", { XX
} },
1674 { "(bad)", { XX
} },
1675 { "(bad)", { XX
} },
1676 { "psrlw", { MS
, Ib
} },
1677 { "(bad)", { XX
} },
1678 { "psraw", { MS
, Ib
} },
1679 { "(bad)", { XX
} },
1680 { "psllw", { MS
, Ib
} },
1681 { "(bad)", { XX
} },
1685 { "(bad)", { XX
} },
1686 { "(bad)", { XX
} },
1687 { "psrld", { MS
, Ib
} },
1688 { "(bad)", { XX
} },
1689 { "psrad", { MS
, Ib
} },
1690 { "(bad)", { XX
} },
1691 { "pslld", { MS
, Ib
} },
1692 { "(bad)", { XX
} },
1696 { "(bad)", { XX
} },
1697 { "(bad)", { XX
} },
1698 { "psrlq", { MS
, Ib
} },
1699 { "psrldq", { MS
, Ib
} },
1700 { "(bad)", { XX
} },
1701 { "(bad)", { XX
} },
1702 { "psllq", { MS
, Ib
} },
1703 { "pslldq", { MS
, Ib
} },
1707 { "fxsave", { Ev
} },
1708 { "fxrstor", { Ev
} },
1709 { "ldmxcsr", { Ev
} },
1710 { "stmxcsr", { Ev
} },
1711 { "(bad)", { XX
} },
1712 { "lfence", { { OP_0fae
, 0 } } },
1713 { "mfence", { { OP_0fae
, 0 } } },
1714 { "clflush", { { OP_0fae
, 0 } } },
1718 { "prefetchnta", { Ev
} },
1719 { "prefetcht0", { Ev
} },
1720 { "prefetcht1", { Ev
} },
1721 { "prefetcht2", { Ev
} },
1722 { "(bad)", { XX
} },
1723 { "(bad)", { XX
} },
1724 { "(bad)", { XX
} },
1725 { "(bad)", { XX
} },
1729 { "prefetch", { Eb
} },
1730 { "prefetchw", { Eb
} },
1731 { "(bad)", { XX
} },
1732 { "(bad)", { XX
} },
1733 { "(bad)", { XX
} },
1734 { "(bad)", { XX
} },
1735 { "(bad)", { XX
} },
1736 { "(bad)", { XX
} },
1740 { "xstore-rng", { { OP_0f07
, 0 } } },
1741 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1742 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1743 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1744 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1745 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1746 { "(bad)", { { OP_0f07
, 0 } } },
1747 { "(bad)", { { OP_0f07
, 0 } } },
1751 { "montmul", { { OP_0f07
, 0 } } },
1752 { "xsha1", { { OP_0f07
, 0 } } },
1753 { "xsha256", { { OP_0f07
, 0 } } },
1754 { "(bad)", { { OP_0f07
, 0 } } },
1755 { "(bad)", { { OP_0f07
, 0 } } },
1756 { "(bad)", { { OP_0f07
, 0 } } },
1757 { "(bad)", { { OP_0f07
, 0 } } },
1758 { "(bad)", { { OP_0f07
, 0 } } },
1762 static const struct dis386 prefix_user_table
[][4] = {
1765 { "addps", { XM
, EX
} },
1766 { "addss", { XM
, EX
} },
1767 { "addpd", { XM
, EX
} },
1768 { "addsd", { XM
, EX
} },
1772 { "", { XM
, EX
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1773 { "", { XM
, EX
, OPSIMD
} },
1774 { "", { XM
, EX
, OPSIMD
} },
1775 { "", { XM
, EX
, OPSIMD
} },
1779 { "cvtpi2ps", { XM
, EMC
} },
1780 { "cvtsi2ssY", { XM
, Ev
} },
1781 { "cvtpi2pd", { XM
, EMC
} },
1782 { "cvtsi2sdY", { XM
, Ev
} },
1786 { "cvtps2pi", { MXC
, EX
} },
1787 { "cvtss2siY", { Gv
, EX
} },
1788 { "cvtpd2pi", { MXC
, EX
} },
1789 { "cvtsd2siY", { Gv
, EX
} },
1793 { "cvttps2pi", { MXC
, EX
} },
1794 { "cvttss2siY", { Gv
, EX
} },
1795 { "cvttpd2pi", { MXC
, EX
} },
1796 { "cvttsd2siY", { Gv
, EX
} },
1800 { "divps", { XM
, EX
} },
1801 { "divss", { XM
, EX
} },
1802 { "divpd", { XM
, EX
} },
1803 { "divsd", { XM
, EX
} },
1807 { "maxps", { XM
, EX
} },
1808 { "maxss", { XM
, EX
} },
1809 { "maxpd", { XM
, EX
} },
1810 { "maxsd", { XM
, EX
} },
1814 { "minps", { XM
, EX
} },
1815 { "minss", { XM
, EX
} },
1816 { "minpd", { XM
, EX
} },
1817 { "minsd", { XM
, EX
} },
1821 { "movups", { XM
, EX
} },
1822 { "movss", { XM
, EX
} },
1823 { "movupd", { XM
, EX
} },
1824 { "movsd", { XM
, EX
} },
1828 { "movups", { EX
, XM
} },
1829 { "movss", { EX
, XM
} },
1830 { "movupd", { EX
, XM
} },
1831 { "movsd", { EX
, XM
} },
1835 { "mulps", { XM
, EX
} },
1836 { "mulss", { XM
, EX
} },
1837 { "mulpd", { XM
, EX
} },
1838 { "mulsd", { XM
, EX
} },
1842 { "rcpps", { XM
, EX
} },
1843 { "rcpss", { XM
, EX
} },
1844 { "(bad)", { XM
, EX
} },
1845 { "(bad)", { XM
, EX
} },
1849 { "rsqrtps",{ XM
, EX
} },
1850 { "rsqrtss",{ XM
, EX
} },
1851 { "(bad)", { XM
, EX
} },
1852 { "(bad)", { XM
, EX
} },
1856 { "sqrtps", { XM
, EX
} },
1857 { "sqrtss", { XM
, EX
} },
1858 { "sqrtpd", { XM
, EX
} },
1859 { "sqrtsd", { XM
, EX
} },
1863 { "subps", { XM
, EX
} },
1864 { "subss", { XM
, EX
} },
1865 { "subpd", { XM
, EX
} },
1866 { "subsd", { XM
, EX
} },
1870 { "(bad)", { XM
, EX
} },
1871 { "cvtdq2pd", { XM
, EX
} },
1872 { "cvttpd2dq", { XM
, EX
} },
1873 { "cvtpd2dq", { XM
, EX
} },
1877 { "cvtdq2ps", { XM
, EX
} },
1878 { "cvttps2dq", { XM
, EX
} },
1879 { "cvtps2dq", { XM
, EX
} },
1880 { "(bad)", { XM
, EX
} },
1884 { "cvtps2pd", { XM
, EX
} },
1885 { "cvtss2sd", { XM
, EX
} },
1886 { "cvtpd2ps", { XM
, EX
} },
1887 { "cvtsd2ss", { XM
, EX
} },
1891 { "maskmovq", { MX
, MS
} },
1892 { "(bad)", { XM
, EX
} },
1893 { "maskmovdqu", { XM
, XS
} },
1894 { "(bad)", { XM
, EX
} },
1898 { "movq", { MX
, EM
} },
1899 { "movdqu", { XM
, EX
} },
1900 { "movdqa", { XM
, EX
} },
1901 { "(bad)", { XM
, EX
} },
1905 { "movq", { EM
, MX
} },
1906 { "movdqu", { EX
, XM
} },
1907 { "movdqa", { EX
, XM
} },
1908 { "(bad)", { EX
, XM
} },
1912 { "(bad)", { EX
, XM
} },
1913 { "movq2dq",{ XM
, MS
} },
1914 { "movq", { EX
, XM
} },
1915 { "movdq2q",{ MX
, XS
} },
1919 { "pshufw", { MX
, EM
, Ib
} },
1920 { "pshufhw",{ XM
, EX
, Ib
} },
1921 { "pshufd", { XM
, EX
, Ib
} },
1922 { "pshuflw",{ XM
, EX
, Ib
} },
1926 { "movd", { Edq
, MX
} },
1927 { "movq", { XM
, EX
} },
1928 { "movd", { Edq
, XM
} },
1929 { "(bad)", { Ed
, XM
} },
1933 { "(bad)", { MX
, EX
} },
1934 { "(bad)", { XM
, EX
} },
1935 { "punpckhqdq", { XM
, EX
} },
1936 { "(bad)", { XM
, EX
} },
1940 { "movntq", { EM
, MX
} },
1941 { "(bad)", { EM
, XM
} },
1942 { "movntdq",{ EM
, XM
} },
1943 { "(bad)", { EM
, XM
} },
1947 { "(bad)", { MX
, EX
} },
1948 { "(bad)", { XM
, EX
} },
1949 { "punpcklqdq", { XM
, EX
} },
1950 { "(bad)", { XM
, EX
} },
1954 { "(bad)", { MX
, EX
} },
1955 { "(bad)", { XM
, EX
} },
1956 { "addsubpd", { XM
, EX
} },
1957 { "addsubps", { XM
, EX
} },
1961 { "(bad)", { MX
, EX
} },
1962 { "(bad)", { XM
, EX
} },
1963 { "haddpd", { XM
, EX
} },
1964 { "haddps", { XM
, EX
} },
1968 { "(bad)", { MX
, EX
} },
1969 { "(bad)", { XM
, EX
} },
1970 { "hsubpd", { XM
, EX
} },
1971 { "hsubps", { XM
, EX
} },
1975 { "movlpX", { XM
, EX
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
1976 { "movsldup", { XM
, EX
} },
1977 { "movlpd", { XM
, EX
} },
1978 { "movddup", { XM
, EX
} },
1982 { "movhpX", { XM
, EX
, { SIMD_Fixup
, 'l' } } },
1983 { "movshdup", { XM
, EX
} },
1984 { "movhpd", { XM
, EX
} },
1985 { "(bad)", { XM
, EX
} },
1989 { "(bad)", { XM
, EX
} },
1990 { "(bad)", { XM
, EX
} },
1991 { "(bad)", { XM
, EX
} },
1992 { "lddqu", { XM
, M
} },
1996 {"movntps", { Ev
, XM
} },
1997 {"movntss", { Ev
, XM
} },
1998 {"movntpd", { Ev
, XM
} },
1999 {"movntsd", { Ev
, XM
} },
2004 {"vmread", { Em
, Gm
} },
2006 {"extrq", { XS
, Ib
, Ib
} },
2007 {"insertq", { XM
, XS
, Ib
, Ib
} },
2012 {"vmwrite", { Gm
, Em
} },
2014 {"extrq", { XM
, XS
} },
2015 {"insertq", { XM
, XS
} },
2020 { "bsrS", { Gv
, Ev
} },
2021 { "lzcntS", { Gv
, Ev
} },
2022 { "bsrS", { Gv
, Ev
} },
2023 { "(bad)", { XX
} },
2028 { "(bad)", { XX
} },
2029 { "popcntS", { Gv
, Ev
} },
2030 { "(bad)", { XX
} },
2031 { "(bad)", { XX
} },
2035 static const struct dis386 x86_64_table
[][2] = {
2037 { "pusha{P|}", { XX
} },
2038 { "(bad)", { XX
} },
2041 { "popa{P|}", { XX
} },
2042 { "(bad)", { XX
} },
2045 { "bound{S|}", { Gv
, Ma
} },
2046 { "(bad)", { XX
} },
2049 { "arpl", { Ew
, Gw
} },
2050 { "movs{||lq|xd}", { Gv
, Ed
} },
2054 static const struct dis386 three_byte_table
[][256] = {
2058 { "pshufb", { MX
, EM
} },
2059 { "phaddw", { MX
, EM
} },
2060 { "phaddd", { MX
, EM
} },
2061 { "phaddsw", { MX
, EM
} },
2062 { "pmaddubsw", { MX
, EM
} },
2063 { "phsubw", { MX
, EM
} },
2064 { "phsubd", { MX
, EM
} },
2065 { "phsubsw", { MX
, EM
} },
2067 { "psignb", { MX
, EM
} },
2068 { "psignw", { MX
, EM
} },
2069 { "psignd", { MX
, EM
} },
2070 { "pmulhrsw", { MX
, EM
} },
2071 { "(bad)", { XX
} },
2072 { "(bad)", { XX
} },
2073 { "(bad)", { XX
} },
2074 { "(bad)", { XX
} },
2076 { "(bad)", { XX
} },
2077 { "(bad)", { XX
} },
2078 { "(bad)", { XX
} },
2079 { "(bad)", { XX
} },
2080 { "(bad)", { XX
} },
2081 { "(bad)", { XX
} },
2082 { "(bad)", { XX
} },
2083 { "(bad)", { XX
} },
2085 { "(bad)", { XX
} },
2086 { "(bad)", { XX
} },
2087 { "(bad)", { XX
} },
2088 { "(bad)", { XX
} },
2089 { "pabsb", { MX
, EM
} },
2090 { "pabsw", { MX
, EM
} },
2091 { "pabsd", { MX
, EM
} },
2092 { "(bad)", { XX
} },
2094 { "(bad)", { XX
} },
2095 { "(bad)", { XX
} },
2096 { "(bad)", { XX
} },
2097 { "(bad)", { XX
} },
2098 { "(bad)", { XX
} },
2099 { "(bad)", { XX
} },
2100 { "(bad)", { XX
} },
2101 { "(bad)", { XX
} },
2103 { "(bad)", { XX
} },
2104 { "(bad)", { XX
} },
2105 { "(bad)", { XX
} },
2106 { "(bad)", { XX
} },
2107 { "(bad)", { XX
} },
2108 { "(bad)", { XX
} },
2109 { "(bad)", { XX
} },
2110 { "(bad)", { XX
} },
2112 { "(bad)", { XX
} },
2113 { "(bad)", { XX
} },
2114 { "(bad)", { XX
} },
2115 { "(bad)", { XX
} },
2116 { "(bad)", { XX
} },
2117 { "(bad)", { XX
} },
2118 { "(bad)", { XX
} },
2119 { "(bad)", { XX
} },
2121 { "(bad)", { XX
} },
2122 { "(bad)", { XX
} },
2123 { "(bad)", { XX
} },
2124 { "(bad)", { XX
} },
2125 { "(bad)", { XX
} },
2126 { "(bad)", { XX
} },
2127 { "(bad)", { XX
} },
2128 { "(bad)", { XX
} },
2130 { "(bad)", { XX
} },
2131 { "(bad)", { XX
} },
2132 { "(bad)", { XX
} },
2133 { "(bad)", { XX
} },
2134 { "(bad)", { XX
} },
2135 { "(bad)", { XX
} },
2136 { "(bad)", { XX
} },
2137 { "(bad)", { XX
} },
2139 { "(bad)", { XX
} },
2140 { "(bad)", { XX
} },
2141 { "(bad)", { XX
} },
2142 { "(bad)", { XX
} },
2143 { "(bad)", { XX
} },
2144 { "(bad)", { XX
} },
2145 { "(bad)", { XX
} },
2146 { "(bad)", { XX
} },
2148 { "(bad)", { XX
} },
2149 { "(bad)", { XX
} },
2150 { "(bad)", { XX
} },
2151 { "(bad)", { XX
} },
2152 { "(bad)", { XX
} },
2153 { "(bad)", { XX
} },
2154 { "(bad)", { XX
} },
2155 { "(bad)", { XX
} },
2157 { "(bad)", { XX
} },
2158 { "(bad)", { XX
} },
2159 { "(bad)", { XX
} },
2160 { "(bad)", { XX
} },
2161 { "(bad)", { XX
} },
2162 { "(bad)", { XX
} },
2163 { "(bad)", { XX
} },
2164 { "(bad)", { XX
} },
2166 { "(bad)", { XX
} },
2167 { "(bad)", { XX
} },
2168 { "(bad)", { XX
} },
2169 { "(bad)", { XX
} },
2170 { "(bad)", { XX
} },
2171 { "(bad)", { XX
} },
2172 { "(bad)", { XX
} },
2173 { "(bad)", { XX
} },
2175 { "(bad)", { XX
} },
2176 { "(bad)", { XX
} },
2177 { "(bad)", { XX
} },
2178 { "(bad)", { XX
} },
2179 { "(bad)", { XX
} },
2180 { "(bad)", { XX
} },
2181 { "(bad)", { XX
} },
2182 { "(bad)", { XX
} },
2184 { "(bad)", { XX
} },
2185 { "(bad)", { XX
} },
2186 { "(bad)", { XX
} },
2187 { "(bad)", { XX
} },
2188 { "(bad)", { XX
} },
2189 { "(bad)", { XX
} },
2190 { "(bad)", { XX
} },
2191 { "(bad)", { XX
} },
2193 { "(bad)", { XX
} },
2194 { "(bad)", { XX
} },
2195 { "(bad)", { XX
} },
2196 { "(bad)", { XX
} },
2197 { "(bad)", { XX
} },
2198 { "(bad)", { XX
} },
2199 { "(bad)", { XX
} },
2200 { "(bad)", { XX
} },
2202 { "(bad)", { XX
} },
2203 { "(bad)", { XX
} },
2204 { "(bad)", { XX
} },
2205 { "(bad)", { XX
} },
2206 { "(bad)", { XX
} },
2207 { "(bad)", { XX
} },
2208 { "(bad)", { XX
} },
2209 { "(bad)", { XX
} },
2211 { "(bad)", { XX
} },
2212 { "(bad)", { XX
} },
2213 { "(bad)", { XX
} },
2214 { "(bad)", { XX
} },
2215 { "(bad)", { XX
} },
2216 { "(bad)", { XX
} },
2217 { "(bad)", { XX
} },
2218 { "(bad)", { XX
} },
2220 { "(bad)", { XX
} },
2221 { "(bad)", { XX
} },
2222 { "(bad)", { XX
} },
2223 { "(bad)", { XX
} },
2224 { "(bad)", { XX
} },
2225 { "(bad)", { XX
} },
2226 { "(bad)", { XX
} },
2227 { "(bad)", { XX
} },
2229 { "(bad)", { XX
} },
2230 { "(bad)", { XX
} },
2231 { "(bad)", { XX
} },
2232 { "(bad)", { XX
} },
2233 { "(bad)", { XX
} },
2234 { "(bad)", { XX
} },
2235 { "(bad)", { XX
} },
2236 { "(bad)", { XX
} },
2238 { "(bad)", { XX
} },
2239 { "(bad)", { XX
} },
2240 { "(bad)", { XX
} },
2241 { "(bad)", { XX
} },
2242 { "(bad)", { XX
} },
2243 { "(bad)", { XX
} },
2244 { "(bad)", { XX
} },
2245 { "(bad)", { XX
} },
2247 { "(bad)", { XX
} },
2248 { "(bad)", { XX
} },
2249 { "(bad)", { XX
} },
2250 { "(bad)", { XX
} },
2251 { "(bad)", { XX
} },
2252 { "(bad)", { XX
} },
2253 { "(bad)", { XX
} },
2254 { "(bad)", { XX
} },
2256 { "(bad)", { XX
} },
2257 { "(bad)", { XX
} },
2258 { "(bad)", { XX
} },
2259 { "(bad)", { XX
} },
2260 { "(bad)", { XX
} },
2261 { "(bad)", { XX
} },
2262 { "(bad)", { XX
} },
2263 { "(bad)", { XX
} },
2265 { "(bad)", { XX
} },
2266 { "(bad)", { XX
} },
2267 { "(bad)", { XX
} },
2268 { "(bad)", { XX
} },
2269 { "(bad)", { XX
} },
2270 { "(bad)", { XX
} },
2271 { "(bad)", { XX
} },
2272 { "(bad)", { XX
} },
2274 { "(bad)", { XX
} },
2275 { "(bad)", { XX
} },
2276 { "(bad)", { XX
} },
2277 { "(bad)", { XX
} },
2278 { "(bad)", { XX
} },
2279 { "(bad)", { XX
} },
2280 { "(bad)", { XX
} },
2281 { "(bad)", { XX
} },
2283 { "(bad)", { XX
} },
2284 { "(bad)", { XX
} },
2285 { "(bad)", { XX
} },
2286 { "(bad)", { XX
} },
2287 { "(bad)", { XX
} },
2288 { "(bad)", { XX
} },
2289 { "(bad)", { XX
} },
2290 { "(bad)", { XX
} },
2292 { "(bad)", { XX
} },
2293 { "(bad)", { XX
} },
2294 { "(bad)", { XX
} },
2295 { "(bad)", { XX
} },
2296 { "(bad)", { XX
} },
2297 { "(bad)", { XX
} },
2298 { "(bad)", { XX
} },
2299 { "(bad)", { XX
} },
2301 { "(bad)", { XX
} },
2302 { "(bad)", { XX
} },
2303 { "(bad)", { XX
} },
2304 { "(bad)", { XX
} },
2305 { "(bad)", { XX
} },
2306 { "(bad)", { XX
} },
2307 { "(bad)", { XX
} },
2308 { "(bad)", { XX
} },
2310 { "(bad)", { XX
} },
2311 { "(bad)", { XX
} },
2312 { "(bad)", { XX
} },
2313 { "(bad)", { XX
} },
2314 { "(bad)", { XX
} },
2315 { "(bad)", { XX
} },
2316 { "(bad)", { XX
} },
2317 { "(bad)", { XX
} },
2319 { "(bad)", { XX
} },
2320 { "(bad)", { XX
} },
2321 { "(bad)", { XX
} },
2322 { "(bad)", { XX
} },
2323 { "(bad)", { XX
} },
2324 { "(bad)", { XX
} },
2325 { "(bad)", { XX
} },
2326 { "(bad)", { XX
} },
2328 { "(bad)", { XX
} },
2329 { "(bad)", { XX
} },
2330 { "(bad)", { XX
} },
2331 { "(bad)", { XX
} },
2332 { "(bad)", { XX
} },
2333 { "(bad)", { XX
} },
2334 { "(bad)", { XX
} },
2335 { "(bad)", { XX
} },
2337 { "(bad)", { XX
} },
2338 { "(bad)", { XX
} },
2339 { "(bad)", { XX
} },
2340 { "(bad)", { XX
} },
2341 { "(bad)", { XX
} },
2342 { "(bad)", { XX
} },
2343 { "(bad)", { XX
} },
2344 { "(bad)", { XX
} },
2349 { "(bad)", { XX
} },
2350 { "(bad)", { XX
} },
2351 { "(bad)", { XX
} },
2352 { "(bad)", { XX
} },
2353 { "(bad)", { XX
} },
2354 { "(bad)", { XX
} },
2355 { "(bad)", { XX
} },
2356 { "(bad)", { XX
} },
2358 { "(bad)", { XX
} },
2359 { "(bad)", { XX
} },
2360 { "(bad)", { XX
} },
2361 { "(bad)", { XX
} },
2362 { "(bad)", { XX
} },
2363 { "(bad)", { XX
} },
2364 { "(bad)", { XX
} },
2365 { "palignr", { MX
, EM
, Ib
} },
2367 { "(bad)", { XX
} },
2368 { "(bad)", { XX
} },
2369 { "(bad)", { XX
} },
2370 { "(bad)", { XX
} },
2371 { "(bad)", { XX
} },
2372 { "(bad)", { XX
} },
2373 { "(bad)", { XX
} },
2374 { "(bad)", { XX
} },
2376 { "(bad)", { XX
} },
2377 { "(bad)", { XX
} },
2378 { "(bad)", { XX
} },
2379 { "(bad)", { XX
} },
2380 { "(bad)", { XX
} },
2381 { "(bad)", { XX
} },
2382 { "(bad)", { XX
} },
2383 { "(bad)", { XX
} },
2385 { "(bad)", { XX
} },
2386 { "(bad)", { XX
} },
2387 { "(bad)", { XX
} },
2388 { "(bad)", { XX
} },
2389 { "(bad)", { XX
} },
2390 { "(bad)", { XX
} },
2391 { "(bad)", { XX
} },
2392 { "(bad)", { XX
} },
2394 { "(bad)", { XX
} },
2395 { "(bad)", { XX
} },
2396 { "(bad)", { XX
} },
2397 { "(bad)", { XX
} },
2398 { "(bad)", { XX
} },
2399 { "(bad)", { XX
} },
2400 { "(bad)", { XX
} },
2401 { "(bad)", { XX
} },
2403 { "(bad)", { XX
} },
2404 { "(bad)", { XX
} },
2405 { "(bad)", { XX
} },
2406 { "(bad)", { XX
} },
2407 { "(bad)", { XX
} },
2408 { "(bad)", { XX
} },
2409 { "(bad)", { XX
} },
2410 { "(bad)", { XX
} },
2412 { "(bad)", { XX
} },
2413 { "(bad)", { XX
} },
2414 { "(bad)", { XX
} },
2415 { "(bad)", { XX
} },
2416 { "(bad)", { XX
} },
2417 { "(bad)", { XX
} },
2418 { "(bad)", { XX
} },
2419 { "(bad)", { XX
} },
2421 { "(bad)", { XX
} },
2422 { "(bad)", { XX
} },
2423 { "(bad)", { XX
} },
2424 { "(bad)", { XX
} },
2425 { "(bad)", { XX
} },
2426 { "(bad)", { XX
} },
2427 { "(bad)", { XX
} },
2428 { "(bad)", { XX
} },
2430 { "(bad)", { XX
} },
2431 { "(bad)", { XX
} },
2432 { "(bad)", { XX
} },
2433 { "(bad)", { XX
} },
2434 { "(bad)", { XX
} },
2435 { "(bad)", { XX
} },
2436 { "(bad)", { XX
} },
2437 { "(bad)", { XX
} },
2439 { "(bad)", { XX
} },
2440 { "(bad)", { XX
} },
2441 { "(bad)", { XX
} },
2442 { "(bad)", { XX
} },
2443 { "(bad)", { XX
} },
2444 { "(bad)", { XX
} },
2445 { "(bad)", { XX
} },
2446 { "(bad)", { XX
} },
2448 { "(bad)", { XX
} },
2449 { "(bad)", { XX
} },
2450 { "(bad)", { XX
} },
2451 { "(bad)", { XX
} },
2452 { "(bad)", { XX
} },
2453 { "(bad)", { XX
} },
2454 { "(bad)", { XX
} },
2455 { "(bad)", { XX
} },
2457 { "(bad)", { XX
} },
2458 { "(bad)", { XX
} },
2459 { "(bad)", { XX
} },
2460 { "(bad)", { XX
} },
2461 { "(bad)", { XX
} },
2462 { "(bad)", { XX
} },
2463 { "(bad)", { XX
} },
2464 { "(bad)", { XX
} },
2466 { "(bad)", { XX
} },
2467 { "(bad)", { XX
} },
2468 { "(bad)", { XX
} },
2469 { "(bad)", { XX
} },
2470 { "(bad)", { XX
} },
2471 { "(bad)", { XX
} },
2472 { "(bad)", { XX
} },
2473 { "(bad)", { XX
} },
2475 { "(bad)", { XX
} },
2476 { "(bad)", { XX
} },
2477 { "(bad)", { XX
} },
2478 { "(bad)", { XX
} },
2479 { "(bad)", { XX
} },
2480 { "(bad)", { XX
} },
2481 { "(bad)", { XX
} },
2482 { "(bad)", { XX
} },
2484 { "(bad)", { XX
} },
2485 { "(bad)", { XX
} },
2486 { "(bad)", { XX
} },
2487 { "(bad)", { XX
} },
2488 { "(bad)", { XX
} },
2489 { "(bad)", { XX
} },
2490 { "(bad)", { XX
} },
2491 { "(bad)", { XX
} },
2493 { "(bad)", { XX
} },
2494 { "(bad)", { XX
} },
2495 { "(bad)", { XX
} },
2496 { "(bad)", { XX
} },
2497 { "(bad)", { XX
} },
2498 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2500 { "(bad)", { XX
} },
2502 { "(bad)", { XX
} },
2503 { "(bad)", { XX
} },
2504 { "(bad)", { XX
} },
2505 { "(bad)", { XX
} },
2506 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "(bad)", { XX
} },
2509 { "(bad)", { XX
} },
2511 { "(bad)", { XX
} },
2512 { "(bad)", { XX
} },
2513 { "(bad)", { XX
} },
2514 { "(bad)", { XX
} },
2515 { "(bad)", { XX
} },
2516 { "(bad)", { XX
} },
2517 { "(bad)", { XX
} },
2518 { "(bad)", { XX
} },
2520 { "(bad)", { XX
} },
2521 { "(bad)", { XX
} },
2522 { "(bad)", { XX
} },
2523 { "(bad)", { XX
} },
2524 { "(bad)", { XX
} },
2525 { "(bad)", { XX
} },
2526 { "(bad)", { XX
} },
2527 { "(bad)", { XX
} },
2529 { "(bad)", { XX
} },
2530 { "(bad)", { XX
} },
2531 { "(bad)", { XX
} },
2532 { "(bad)", { XX
} },
2533 { "(bad)", { XX
} },
2534 { "(bad)", { XX
} },
2535 { "(bad)", { XX
} },
2536 { "(bad)", { XX
} },
2538 { "(bad)", { XX
} },
2539 { "(bad)", { XX
} },
2540 { "(bad)", { XX
} },
2541 { "(bad)", { XX
} },
2542 { "(bad)", { XX
} },
2543 { "(bad)", { XX
} },
2544 { "(bad)", { XX
} },
2545 { "(bad)", { XX
} },
2547 { "(bad)", { XX
} },
2548 { "(bad)", { XX
} },
2549 { "(bad)", { XX
} },
2550 { "(bad)", { XX
} },
2551 { "(bad)", { XX
} },
2552 { "(bad)", { XX
} },
2553 { "(bad)", { XX
} },
2554 { "(bad)", { XX
} },
2556 { "(bad)", { XX
} },
2557 { "(bad)", { XX
} },
2558 { "(bad)", { XX
} },
2559 { "(bad)", { XX
} },
2560 { "(bad)", { XX
} },
2561 { "(bad)", { XX
} },
2562 { "(bad)", { XX
} },
2563 { "(bad)", { XX
} },
2565 { "(bad)", { XX
} },
2566 { "(bad)", { XX
} },
2567 { "(bad)", { XX
} },
2568 { "(bad)", { XX
} },
2569 { "(bad)", { XX
} },
2570 { "(bad)", { XX
} },
2571 { "(bad)", { XX
} },
2572 { "(bad)", { XX
} },
2574 { "(bad)", { XX
} },
2575 { "(bad)", { XX
} },
2576 { "(bad)", { XX
} },
2577 { "(bad)", { XX
} },
2578 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2580 { "(bad)", { XX
} },
2581 { "(bad)", { XX
} },
2583 { "(bad)", { XX
} },
2584 { "(bad)", { XX
} },
2585 { "(bad)", { XX
} },
2586 { "(bad)", { XX
} },
2587 { "(bad)", { XX
} },
2588 { "(bad)", { XX
} },
2589 { "(bad)", { XX
} },
2590 { "(bad)", { XX
} },
2592 { "(bad)", { XX
} },
2593 { "(bad)", { XX
} },
2594 { "(bad)", { XX
} },
2595 { "(bad)", { XX
} },
2596 { "(bad)", { XX
} },
2597 { "(bad)", { XX
} },
2598 { "(bad)", { XX
} },
2599 { "(bad)", { XX
} },
2601 { "(bad)", { XX
} },
2602 { "(bad)", { XX
} },
2603 { "(bad)", { XX
} },
2604 { "(bad)", { XX
} },
2605 { "(bad)", { XX
} },
2606 { "(bad)", { XX
} },
2607 { "(bad)", { XX
} },
2608 { "(bad)", { XX
} },
2610 { "(bad)", { XX
} },
2611 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "(bad)", { XX
} },
2614 { "(bad)", { XX
} },
2615 { "(bad)", { XX
} },
2616 { "(bad)", { XX
} },
2617 { "(bad)", { XX
} },
2619 { "(bad)", { XX
} },
2620 { "(bad)", { XX
} },
2621 { "(bad)", { XX
} },
2622 { "(bad)", { XX
} },
2623 { "(bad)", { XX
} },
2624 { "(bad)", { XX
} },
2625 { "(bad)", { XX
} },
2626 { "(bad)", { XX
} },
2628 { "(bad)", { XX
} },
2629 { "(bad)", { XX
} },
2630 { "(bad)", { XX
} },
2631 { "(bad)", { XX
} },
2632 { "(bad)", { XX
} },
2633 { "(bad)", { XX
} },
2634 { "(bad)", { XX
} },
2635 { "(bad)", { XX
} },
2639 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2651 FETCH_DATA (the_info
, codep
+ 1);
2655 /* REX prefixes family. */
2672 if (address_mode
== mode_64bit
)
2678 prefixes
|= PREFIX_REPZ
;
2681 prefixes
|= PREFIX_REPNZ
;
2684 prefixes
|= PREFIX_LOCK
;
2687 prefixes
|= PREFIX_CS
;
2690 prefixes
|= PREFIX_SS
;
2693 prefixes
|= PREFIX_DS
;
2696 prefixes
|= PREFIX_ES
;
2699 prefixes
|= PREFIX_FS
;
2702 prefixes
|= PREFIX_GS
;
2705 prefixes
|= PREFIX_DATA
;
2708 prefixes
|= PREFIX_ADDR
;
2711 /* fwait is really an instruction. If there are prefixes
2712 before the fwait, they belong to the fwait, *not* to the
2713 following instruction. */
2714 if (prefixes
|| rex
)
2716 prefixes
|= PREFIX_FWAIT
;
2720 prefixes
= PREFIX_FWAIT
;
2725 /* Rex is ignored when followed by another prefix. */
2736 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2740 prefix_name (int pref
, int sizeflag
)
2744 /* REX prefixes family. */
2796 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2798 if (address_mode
== mode_64bit
)
2799 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2801 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2809 static char op_out
[MAX_OPERANDS
][100];
2810 static int op_ad
, op_index
[MAX_OPERANDS
];
2811 static int two_source_ops
;
2812 static bfd_vma op_address
[MAX_OPERANDS
];
2813 static bfd_vma op_riprel
[MAX_OPERANDS
];
2814 static bfd_vma start_pc
;
2817 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2818 * (see topic "Redundant prefixes" in the "Differences from 8086"
2819 * section of the "Virtual 8086 Mode" chapter.)
2820 * 'pc' should be the address of this instruction, it will
2821 * be used to print the target address if this is a relative jump or call
2822 * The function returns the length of this instruction in bytes.
2825 static char intel_syntax
;
2826 static char open_char
;
2827 static char close_char
;
2828 static char separator_char
;
2829 static char scale_char
;
2831 /* Here for backwards compatibility. When gdb stops using
2832 print_insn_i386_att and print_insn_i386_intel these functions can
2833 disappear, and print_insn_i386 be merged into print_insn. */
2835 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2839 return print_insn (pc
, info
);
2843 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2847 return print_insn (pc
, info
);
2851 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2855 return print_insn (pc
, info
);
2859 print_i386_disassembler_options (FILE *stream
)
2861 fprintf (stream
, _("\n\
2862 The following i386/x86-64 specific disassembler options are supported for use\n\
2863 with the -M switch (multiple options should be separated by commas):\n"));
2865 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
2866 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
2867 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
2868 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
2869 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
2870 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
2871 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
2872 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
2873 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
2874 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
2875 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
2879 print_insn (bfd_vma pc
, disassemble_info
*info
)
2881 const struct dis386
*dp
;
2883 char *op_txt
[MAX_OPERANDS
];
2885 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
2886 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
2889 struct dis_private priv
;
2892 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2893 || info
->mach
== bfd_mach_x86_64
)
2894 address_mode
= mode_64bit
;
2896 address_mode
= mode_32bit
;
2898 if (intel_syntax
== (char) -1)
2899 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2900 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2902 if (info
->mach
== bfd_mach_i386_i386
2903 || info
->mach
== bfd_mach_x86_64
2904 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2905 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2906 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2907 else if (info
->mach
== bfd_mach_i386_i8086
)
2908 priv
.orig_sizeflag
= 0;
2912 for (p
= info
->disassembler_options
; p
!= NULL
; )
2914 if (CONST_STRNEQ (p
, "x86-64"))
2916 address_mode
= mode_64bit
;
2917 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2919 else if (CONST_STRNEQ (p
, "i386"))
2921 address_mode
= mode_32bit
;
2922 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2924 else if (CONST_STRNEQ (p
, "i8086"))
2926 address_mode
= mode_16bit
;
2927 priv
.orig_sizeflag
= 0;
2929 else if (CONST_STRNEQ (p
, "intel"))
2933 else if (CONST_STRNEQ (p
, "att"))
2937 else if (CONST_STRNEQ (p
, "addr"))
2939 if (address_mode
== mode_64bit
)
2941 if (p
[4] == '3' && p
[5] == '2')
2942 priv
.orig_sizeflag
&= ~AFLAG
;
2943 else if (p
[4] == '6' && p
[5] == '4')
2944 priv
.orig_sizeflag
|= AFLAG
;
2948 if (p
[4] == '1' && p
[5] == '6')
2949 priv
.orig_sizeflag
&= ~AFLAG
;
2950 else if (p
[4] == '3' && p
[5] == '2')
2951 priv
.orig_sizeflag
|= AFLAG
;
2954 else if (CONST_STRNEQ (p
, "data"))
2956 if (p
[4] == '1' && p
[5] == '6')
2957 priv
.orig_sizeflag
&= ~DFLAG
;
2958 else if (p
[4] == '3' && p
[5] == '2')
2959 priv
.orig_sizeflag
|= DFLAG
;
2961 else if (CONST_STRNEQ (p
, "suffix"))
2962 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2964 p
= strchr (p
, ',');
2971 names64
= intel_names64
;
2972 names32
= intel_names32
;
2973 names16
= intel_names16
;
2974 names8
= intel_names8
;
2975 names8rex
= intel_names8rex
;
2976 names_seg
= intel_names_seg
;
2977 index16
= intel_index16
;
2980 separator_char
= '+';
2985 names64
= att_names64
;
2986 names32
= att_names32
;
2987 names16
= att_names16
;
2988 names8
= att_names8
;
2989 names8rex
= att_names8rex
;
2990 names_seg
= att_names_seg
;
2991 index16
= att_index16
;
2994 separator_char
= ',';
2998 /* The output looks better if we put 7 bytes on a line, since that
2999 puts most long word instructions on a single line. */
3000 info
->bytes_per_line
= 7;
3002 info
->private_data
= &priv
;
3003 priv
.max_fetched
= priv
.the_buffer
;
3004 priv
.insn_start
= pc
;
3007 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3015 start_codep
= priv
.the_buffer
;
3016 codep
= priv
.the_buffer
;
3018 if (setjmp (priv
.bailout
) != 0)
3022 /* Getting here means we tried for data but didn't get it. That
3023 means we have an incomplete instruction of some sort. Just
3024 print the first byte as a prefix or a .byte pseudo-op. */
3025 if (codep
> priv
.the_buffer
)
3027 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3029 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3032 /* Just print the first byte as a .byte instruction. */
3033 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3034 (unsigned int) priv
.the_buffer
[0]);
3047 sizeflag
= priv
.orig_sizeflag
;
3049 FETCH_DATA (info
, codep
+ 1);
3050 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3052 if (((prefixes
& PREFIX_FWAIT
)
3053 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3054 || (rex
&& rex_used
))
3058 /* fwait not followed by floating point instruction, or rex followed
3059 by other prefixes. Print the first prefix. */
3060 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3062 name
= INTERNAL_DISASSEMBLER_ERROR
;
3063 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3070 unsigned char threebyte
;
3071 FETCH_DATA (info
, codep
+ 2);
3072 threebyte
= *++codep
;
3073 dp
= &dis386_twobyte
[threebyte
];
3074 need_modrm
= twobyte_has_modrm
[*codep
];
3075 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[*codep
];
3076 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[*codep
];
3077 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[*codep
];
3078 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
3080 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3082 FETCH_DATA (info
, codep
+ 2);
3087 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3088 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3089 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3092 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3093 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3094 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3103 dp
= &dis386
[*codep
];
3104 need_modrm
= onebyte_has_modrm
[*codep
];
3105 uses_DATA_prefix
= 0;
3106 uses_REPNZ_prefix
= 0;
3107 uses_REPZ_prefix
= 0;
3108 uses_LOCK_prefix
= 0;
3112 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3115 used_prefixes
|= PREFIX_REPZ
;
3117 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3120 used_prefixes
|= PREFIX_REPNZ
;
3123 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3126 used_prefixes
|= PREFIX_LOCK
;
3129 if (prefixes
& PREFIX_ADDR
)
3132 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3134 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3135 oappend ("addr32 ");
3137 oappend ("addr16 ");
3138 used_prefixes
|= PREFIX_ADDR
;
3142 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3145 if (dp
->op
[2].bytemode
== cond_jump_mode
3146 && dp
->op
[0].bytemode
== v_mode
3149 if (sizeflag
& DFLAG
)
3150 oappend ("data32 ");
3152 oappend ("data16 ");
3153 used_prefixes
|= PREFIX_DATA
;
3157 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3159 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3160 mod
= (*codep
>> 6) & 3;
3161 reg
= (*codep
>> 3) & 7;
3164 else if (need_modrm
)
3166 FETCH_DATA (info
, codep
+ 1);
3167 mod
= (*codep
>> 6) & 3;
3168 reg
= (*codep
>> 3) & 7;
3172 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3179 if (dp
->name
== NULL
)
3181 switch (dp
->op
[0].bytemode
)
3184 dp
= &grps
[dp
->op
[1].bytemode
][reg
];
3187 case USE_PREFIX_USER_TABLE
:
3189 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3190 if (prefixes
& PREFIX_REPZ
)
3194 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3195 before PREFIX_DATA. */
3196 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3197 if (prefixes
& PREFIX_REPNZ
)
3201 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3202 if (prefixes
& PREFIX_DATA
)
3206 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
3209 case X86_64_SPECIAL
:
3210 index
= address_mode
== mode_64bit
? 1 : 0;
3211 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
3215 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3220 if (putop (dp
->name
, sizeflag
) == 0)
3222 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3225 op_ad
= MAX_OPERANDS
- 1 - i
;
3227 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
3232 /* See if any prefixes were not used. If so, print the first one
3233 separately. If we don't do this, we'll wind up printing an
3234 instruction stream which does not precisely correspond to the
3235 bytes we are disassembling. */
3236 if ((prefixes
& ~used_prefixes
) != 0)
3240 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3242 name
= INTERNAL_DISASSEMBLER_ERROR
;
3243 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3246 if (rex
& ~rex_used
)
3249 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
3251 name
= INTERNAL_DISASSEMBLER_ERROR
;
3252 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3255 obufp
= obuf
+ strlen (obuf
);
3256 for (i
= strlen (obuf
); i
< 6; i
++)
3259 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3261 /* The enter and bound instructions are printed with operands in the same
3262 order as the intel book; everything else is printed in reverse order. */
3263 if (intel_syntax
|| two_source_ops
)
3265 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3266 op_txt
[i
] = op_out
[i
];
3268 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
3270 op_ad
= op_index
[i
];
3271 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
3272 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
3277 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3278 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
3282 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3286 (*info
->fprintf_func
) (info
->stream
, ",");
3287 if (op_index
[i
] != -1 && !op_riprel
[i
])
3288 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
3290 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
3294 for (i
= 0; i
< MAX_OPERANDS
; i
++)
3295 if (op_index
[i
] != -1 && op_riprel
[i
])
3297 (*info
->fprintf_func
) (info
->stream
, " # ");
3298 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3299 + op_address
[op_index
[i
]]), info
);
3301 return codep
- priv
.the_buffer
;
3304 static const char *float_mem
[] = {
3379 static const unsigned char float_mem_mode
[] = {
3454 #define ST { OP_ST, 0 }
3455 #define STi { OP_STi, 0 }
3457 #define FGRPd9_2 NULL, { { NULL, 0 } }
3458 #define FGRPd9_4 NULL, { { NULL, 1 } }
3459 #define FGRPd9_5 NULL, { { NULL, 2 } }
3460 #define FGRPd9_6 NULL, { { NULL, 3 } }
3461 #define FGRPd9_7 NULL, { { NULL, 4 } }
3462 #define FGRPda_5 NULL, { { NULL, 5 } }
3463 #define FGRPdb_4 NULL, { { NULL, 6 } }
3464 #define FGRPde_3 NULL, { { NULL, 7 } }
3465 #define FGRPdf_4 NULL, { { NULL, 8 } }
3467 static const struct dis386 float_reg
[][8] = {
3470 { "fadd", { ST
, STi
} },
3471 { "fmul", { ST
, STi
} },
3472 { "fcom", { STi
} },
3473 { "fcomp", { STi
} },
3474 { "fsub", { ST
, STi
} },
3475 { "fsubr", { ST
, STi
} },
3476 { "fdiv", { ST
, STi
} },
3477 { "fdivr", { ST
, STi
} },
3482 { "fxch", { STi
} },
3484 { "(bad)", { XX
} },
3492 { "fcmovb", { ST
, STi
} },
3493 { "fcmove", { ST
, STi
} },
3494 { "fcmovbe",{ ST
, STi
} },
3495 { "fcmovu", { ST
, STi
} },
3496 { "(bad)", { XX
} },
3498 { "(bad)", { XX
} },
3499 { "(bad)", { XX
} },
3503 { "fcmovnb",{ ST
, STi
} },
3504 { "fcmovne",{ ST
, STi
} },
3505 { "fcmovnbe",{ ST
, STi
} },
3506 { "fcmovnu",{ ST
, STi
} },
3508 { "fucomi", { ST
, STi
} },
3509 { "fcomi", { ST
, STi
} },
3510 { "(bad)", { XX
} },
3514 { "fadd", { STi
, ST
} },
3515 { "fmul", { STi
, ST
} },
3516 { "(bad)", { XX
} },
3517 { "(bad)", { XX
} },
3519 { "fsub", { STi
, ST
} },
3520 { "fsubr", { STi
, ST
} },
3521 { "fdiv", { STi
, ST
} },
3522 { "fdivr", { STi
, ST
} },
3524 { "fsubr", { STi
, ST
} },
3525 { "fsub", { STi
, ST
} },
3526 { "fdivr", { STi
, ST
} },
3527 { "fdiv", { STi
, ST
} },
3532 { "ffree", { STi
} },
3533 { "(bad)", { XX
} },
3535 { "fstp", { STi
} },
3536 { "fucom", { STi
} },
3537 { "fucomp", { STi
} },
3538 { "(bad)", { XX
} },
3539 { "(bad)", { XX
} },
3543 { "faddp", { STi
, ST
} },
3544 { "fmulp", { STi
, ST
} },
3545 { "(bad)", { XX
} },
3548 { "fsubp", { STi
, ST
} },
3549 { "fsubrp", { STi
, ST
} },
3550 { "fdivp", { STi
, ST
} },
3551 { "fdivrp", { STi
, ST
} },
3553 { "fsubrp", { STi
, ST
} },
3554 { "fsubp", { STi
, ST
} },
3555 { "fdivrp", { STi
, ST
} },
3556 { "fdivp", { STi
, ST
} },
3561 { "ffreep", { STi
} },
3562 { "(bad)", { XX
} },
3563 { "(bad)", { XX
} },
3564 { "(bad)", { XX
} },
3566 { "fucomip", { ST
, STi
} },
3567 { "fcomip", { ST
, STi
} },
3568 { "(bad)", { XX
} },
3572 static char *fgrps
[][8] = {
3575 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3580 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3585 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3590 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3595 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3600 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3605 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3606 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3611 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3616 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3621 dofloat (int sizeflag
)
3623 const struct dis386
*dp
;
3624 unsigned char floatop
;
3626 floatop
= codep
[-1];
3630 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
3632 putop (float_mem
[fp_indx
], sizeflag
);
3635 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
3638 /* Skip mod/rm byte. */
3642 dp
= &float_reg
[floatop
- 0xd8][reg
];
3643 if (dp
->name
== NULL
)
3645 putop (fgrps
[dp
->op
[0].bytemode
][rm
], sizeflag
);
3647 /* Instruction fnstsw is only one with strange arg. */
3648 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3649 strcpy (op_out
[0], names16
[0]);
3653 putop (dp
->name
, sizeflag
);
3658 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
3663 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
3668 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3670 oappend ("%st" + intel_syntax
);
3674 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3676 sprintf (scratchbuf
, "%%st(%d)", rm
);
3677 oappend (scratchbuf
+ intel_syntax
);
3680 /* Capital letters in template are macros. */
3682 putop (const char *template, int sizeflag
)
3687 for (p
= template; *p
; p
++)
3698 if (address_mode
== mode_64bit
)
3706 /* Alternative not valid. */
3707 strcpy (obuf
, "(bad)");
3711 else if (*p
== '\0')
3732 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3738 if (sizeflag
& SUFFIX_ALWAYS
)
3742 if (intel_syntax
&& !alt
)
3744 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
3746 if (sizeflag
& DFLAG
)
3747 *obufp
++ = intel_syntax
? 'd' : 'l';
3749 *obufp
++ = intel_syntax
? 'w' : 's';
3750 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3754 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
3756 USED_REX (REX_MODE64
);
3759 if (rex
& REX_MODE64
)
3761 else if (sizeflag
& DFLAG
)
3762 *obufp
++ = intel_syntax
? 'd' : 'l';
3765 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3770 case 'E': /* For jcxz/jecxz */
3771 if (address_mode
== mode_64bit
)
3773 if (sizeflag
& AFLAG
)
3779 if (sizeflag
& AFLAG
)
3781 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3786 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
3788 if (sizeflag
& AFLAG
)
3789 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
3791 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
3792 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
3796 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
3798 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
3802 if (!(rex
& REX_MODE64
))
3803 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3808 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
3809 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
3811 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
3814 if (prefixes
& PREFIX_DS
)
3828 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
3837 if (sizeflag
& SUFFIX_ALWAYS
)
3841 if ((prefixes
& PREFIX_FWAIT
) == 0)
3844 used_prefixes
|= PREFIX_FWAIT
;
3847 USED_REX (REX_MODE64
);
3848 if (rex
& REX_MODE64
)
3850 else if (intel_syntax
&& (sizeflag
& DFLAG
))
3854 if (!(rex
& REX_MODE64
))
3855 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3860 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3869 if ((prefixes
& PREFIX_DATA
)
3870 || (rex
& REX_MODE64
)
3871 || (sizeflag
& SUFFIX_ALWAYS
))
3873 USED_REX (REX_MODE64
);
3874 if (rex
& REX_MODE64
)
3878 if (sizeflag
& DFLAG
)
3883 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3889 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3891 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3897 if (intel_syntax
&& !alt
)
3899 USED_REX (REX_MODE64
);
3900 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3902 if (rex
& REX_MODE64
)
3906 if (sizeflag
& DFLAG
)
3907 *obufp
++ = intel_syntax
? 'd' : 'l';
3911 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3915 USED_REX (REX_MODE64
);
3916 if (rex
& REX_MODE64
)
3918 else if (sizeflag
& DFLAG
)
3927 if (intel_syntax
&& !p
[1]
3928 && ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
)))
3930 if (!(rex
& REX_MODE64
))
3931 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3936 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3938 if (sizeflag
& SUFFIX_ALWAYS
)
3946 if (sizeflag
& SUFFIX_ALWAYS
)
3948 if (rex
& REX_MODE64
)
3952 if (sizeflag
& DFLAG
)
3956 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3961 if (prefixes
& PREFIX_DATA
)
3965 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3970 if (rex
& REX_MODE64
)
3972 USED_REX (REX_MODE64
);
3976 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3978 /* operand size flag for cwtl, cbtw */
3979 USED_REX (REX_MODE64
);
3980 if (rex
& REX_MODE64
)
3987 else if (sizeflag
& DFLAG
)
3991 if (!(rex
& REX_MODE64
))
3992 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4002 oappend (const char *s
)
4005 obufp
+= strlen (s
);
4011 if (prefixes
& PREFIX_CS
)
4013 used_prefixes
|= PREFIX_CS
;
4014 oappend ("%cs:" + intel_syntax
);
4016 if (prefixes
& PREFIX_DS
)
4018 used_prefixes
|= PREFIX_DS
;
4019 oappend ("%ds:" + intel_syntax
);
4021 if (prefixes
& PREFIX_SS
)
4023 used_prefixes
|= PREFIX_SS
;
4024 oappend ("%ss:" + intel_syntax
);
4026 if (prefixes
& PREFIX_ES
)
4028 used_prefixes
|= PREFIX_ES
;
4029 oappend ("%es:" + intel_syntax
);
4031 if (prefixes
& PREFIX_FS
)
4033 used_prefixes
|= PREFIX_FS
;
4034 oappend ("%fs:" + intel_syntax
);
4036 if (prefixes
& PREFIX_GS
)
4038 used_prefixes
|= PREFIX_GS
;
4039 oappend ("%gs:" + intel_syntax
);
4044 OP_indirE (int bytemode
, int sizeflag
)
4048 OP_E (bytemode
, sizeflag
);
4052 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
4054 if (address_mode
== mode_64bit
)
4062 sprintf_vma (tmp
, disp
);
4063 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
4064 strcpy (buf
+ 2, tmp
+ i
);
4068 bfd_signed_vma v
= disp
;
4075 /* Check for possible overflow on 0x8000000000000000. */
4078 strcpy (buf
, "9223372036854775808");
4092 tmp
[28 - i
] = (v
% 10) + '0';
4096 strcpy (buf
, tmp
+ 29 - i
);
4102 sprintf (buf
, "0x%x", (unsigned int) disp
);
4104 sprintf (buf
, "%d", (int) disp
);
4109 intel_operand_size (int bytemode
, int sizeflag
)
4114 oappend ("BYTE PTR ");
4118 oappend ("WORD PTR ");
4121 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4123 oappend ("QWORD PTR ");
4124 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4130 USED_REX (REX_MODE64
);
4131 if (rex
& REX_MODE64
)
4132 oappend ("QWORD PTR ");
4133 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
4134 oappend ("DWORD PTR ");
4136 oappend ("WORD PTR ");
4137 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4140 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4142 oappend ("WORD PTR ");
4143 if (!(rex
& REX_MODE64
))
4144 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4147 oappend ("DWORD PTR ");
4150 oappend ("QWORD PTR ");
4153 if (address_mode
== mode_64bit
)
4154 oappend ("QWORD PTR ");
4156 oappend ("DWORD PTR ");
4159 if (sizeflag
& DFLAG
)
4160 oappend ("FWORD PTR ");
4162 oappend ("DWORD PTR ");
4163 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4166 oappend ("TBYTE PTR ");
4169 oappend ("XMMWORD PTR ");
4172 oappend ("OWORD PTR ");
4180 OP_E (int bytemode
, int sizeflag
)
4185 USED_REX (REX_EXTZ
);
4189 /* Skip mod/rm byte. */
4200 oappend (names8rex
[rm
+ add
]);
4202 oappend (names8
[rm
+ add
]);
4205 oappend (names16
[rm
+ add
]);
4208 oappend (names32
[rm
+ add
]);
4211 oappend (names64
[rm
+ add
]);
4214 if (address_mode
== mode_64bit
)
4215 oappend (names64
[rm
+ add
]);
4217 oappend (names32
[rm
+ add
]);
4220 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4222 oappend (names64
[rm
+ add
]);
4223 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4231 USED_REX (REX_MODE64
);
4232 if (rex
& REX_MODE64
)
4233 oappend (names64
[rm
+ add
]);
4234 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4235 oappend (names32
[rm
+ add
]);
4237 oappend (names16
[rm
+ add
]);
4238 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4243 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4251 intel_operand_size (bytemode
, sizeflag
);
4254 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
4269 FETCH_DATA (the_info
, codep
+ 1);
4270 index
= (*codep
>> 3) & 7;
4271 if (address_mode
== mode_64bit
|| index
!= 0x4)
4272 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4273 scale
= (*codep
>> 6) & 3;
4275 USED_REX (REX_EXTY
);
4285 if ((base
& 7) == 5)
4288 if (address_mode
== mode_64bit
&& !havesib
)
4294 FETCH_DATA (the_info
, codep
+ 1);
4296 if ((disp
& 0x80) != 0)
4305 if (mod
!= 0 || (base
& 7) == 5)
4307 print_operand_value (scratchbuf
, !riprel
, disp
);
4308 oappend (scratchbuf
);
4316 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4318 *obufp
++ = open_char
;
4319 if (intel_syntax
&& riprel
)
4323 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4324 ? names64
[base
] : names32
[base
]);
4329 if (!intel_syntax
|| havebase
)
4331 *obufp
++ = separator_char
;
4334 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
4335 ? names64
[index
] : names32
[index
]);
4337 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
4339 *obufp
++ = scale_char
;
4341 sprintf (scratchbuf
, "%d", 1 << scale
);
4342 oappend (scratchbuf
);
4345 if (intel_syntax
&& disp
)
4347 if ((bfd_signed_vma
) disp
> 0)
4356 disp
= - (bfd_signed_vma
) disp
;
4359 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4360 oappend (scratchbuf
);
4363 *obufp
++ = close_char
;
4366 else if (intel_syntax
)
4368 if (mod
!= 0 || (base
& 7) == 5)
4370 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4371 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4375 oappend (names_seg
[ds_reg
- es_reg
]);
4378 print_operand_value (scratchbuf
, 1, disp
);
4379 oappend (scratchbuf
);
4384 { /* 16 bit address mode */
4391 if ((disp
& 0x8000) != 0)
4396 FETCH_DATA (the_info
, codep
+ 1);
4398 if ((disp
& 0x80) != 0)
4403 if ((disp
& 0x8000) != 0)
4409 if (mod
!= 0 || rm
== 6)
4411 print_operand_value (scratchbuf
, 0, disp
);
4412 oappend (scratchbuf
);
4415 if (mod
!= 0 || rm
!= 6)
4417 *obufp
++ = open_char
;
4419 oappend (index16
[rm
]);
4420 if (intel_syntax
&& disp
)
4422 if ((bfd_signed_vma
) disp
> 0)
4431 disp
= - (bfd_signed_vma
) disp
;
4434 print_operand_value (scratchbuf
, mod
!= 1, disp
);
4435 oappend (scratchbuf
);
4438 *obufp
++ = close_char
;
4441 else if (intel_syntax
)
4443 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4444 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4448 oappend (names_seg
[ds_reg
- es_reg
]);
4451 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
4452 oappend (scratchbuf
);
4458 OP_G (int bytemode
, int sizeflag
)
4461 USED_REX (REX_EXTX
);
4469 oappend (names8rex
[reg
+ add
]);
4471 oappend (names8
[reg
+ add
]);
4474 oappend (names16
[reg
+ add
]);
4477 oappend (names32
[reg
+ add
]);
4480 oappend (names64
[reg
+ add
]);
4485 USED_REX (REX_MODE64
);
4486 if (rex
& REX_MODE64
)
4487 oappend (names64
[reg
+ add
]);
4488 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
4489 oappend (names32
[reg
+ add
]);
4491 oappend (names16
[reg
+ add
]);
4492 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4495 if (address_mode
== mode_64bit
)
4496 oappend (names64
[reg
+ add
]);
4498 oappend (names32
[reg
+ add
]);
4501 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4514 FETCH_DATA (the_info
, codep
+ 8);
4515 a
= *codep
++ & 0xff;
4516 a
|= (*codep
++ & 0xff) << 8;
4517 a
|= (*codep
++ & 0xff) << 16;
4518 a
|= (*codep
++ & 0xff) << 24;
4519 b
= *codep
++ & 0xff;
4520 b
|= (*codep
++ & 0xff) << 8;
4521 b
|= (*codep
++ & 0xff) << 16;
4522 b
|= (*codep
++ & 0xff) << 24;
4523 x
= a
+ ((bfd_vma
) b
<< 32);
4531 static bfd_signed_vma
4534 bfd_signed_vma x
= 0;
4536 FETCH_DATA (the_info
, codep
+ 4);
4537 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4538 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4539 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4540 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4544 static bfd_signed_vma
4547 bfd_signed_vma x
= 0;
4549 FETCH_DATA (the_info
, codep
+ 4);
4550 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4551 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4552 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4553 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4555 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4565 FETCH_DATA (the_info
, codep
+ 2);
4566 x
= *codep
++ & 0xff;
4567 x
|= (*codep
++ & 0xff) << 8;
4572 set_op (bfd_vma op
, int riprel
)
4574 op_index
[op_ad
] = op_ad
;
4575 if (address_mode
== mode_64bit
)
4577 op_address
[op_ad
] = op
;
4578 op_riprel
[op_ad
] = riprel
;
4582 /* Mask to get a 32-bit address. */
4583 op_address
[op_ad
] = op
& 0xffffffff;
4584 op_riprel
[op_ad
] = riprel
& 0xffffffff;
4589 OP_REG (int code
, int sizeflag
)
4593 USED_REX (REX_EXTZ
);
4599 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4600 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4601 s
= names16
[code
- ax_reg
+ add
];
4603 case es_reg
: case ss_reg
: case cs_reg
:
4604 case ds_reg
: case fs_reg
: case gs_reg
:
4605 s
= names_seg
[code
- es_reg
+ add
];
4607 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4608 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4611 s
= names8rex
[code
- al_reg
+ add
];
4613 s
= names8
[code
- al_reg
];
4615 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4616 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4617 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4619 s
= names64
[code
- rAX_reg
+ add
];
4622 code
+= eAX_reg
- rAX_reg
;
4624 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4625 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4626 USED_REX (REX_MODE64
);
4627 if (rex
& REX_MODE64
)
4628 s
= names64
[code
- eAX_reg
+ add
];
4629 else if (sizeflag
& DFLAG
)
4630 s
= names32
[code
- eAX_reg
+ add
];
4632 s
= names16
[code
- eAX_reg
+ add
];
4633 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4636 s
= INTERNAL_DISASSEMBLER_ERROR
;
4643 OP_IMREG (int code
, int sizeflag
)
4655 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4656 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4657 s
= names16
[code
- ax_reg
];
4659 case es_reg
: case ss_reg
: case cs_reg
:
4660 case ds_reg
: case fs_reg
: case gs_reg
:
4661 s
= names_seg
[code
- es_reg
];
4663 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4664 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4667 s
= names8rex
[code
- al_reg
];
4669 s
= names8
[code
- al_reg
];
4671 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4672 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4673 USED_REX (REX_MODE64
);
4674 if (rex
& REX_MODE64
)
4675 s
= names64
[code
- eAX_reg
];
4676 else if (sizeflag
& DFLAG
)
4677 s
= names32
[code
- eAX_reg
];
4679 s
= names16
[code
- eAX_reg
];
4680 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4683 if ((rex
& REX_MODE64
) || (sizeflag
& DFLAG
))
4687 if (!(rex
& REX_MODE64
))
4688 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4691 s
= INTERNAL_DISASSEMBLER_ERROR
;
4698 OP_I (int bytemode
, int sizeflag
)
4701 bfd_signed_vma mask
= -1;
4706 FETCH_DATA (the_info
, codep
+ 1);
4711 if (address_mode
== mode_64bit
)
4718 USED_REX (REX_MODE64
);
4719 if (rex
& REX_MODE64
)
4721 else if (sizeflag
& DFLAG
)
4731 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4742 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4747 scratchbuf
[0] = '$';
4748 print_operand_value (scratchbuf
+ 1, 1, op
);
4749 oappend (scratchbuf
+ intel_syntax
);
4750 scratchbuf
[0] = '\0';
4754 OP_I64 (int bytemode
, int sizeflag
)
4757 bfd_signed_vma mask
= -1;
4759 if (address_mode
!= mode_64bit
)
4761 OP_I (bytemode
, sizeflag
);
4768 FETCH_DATA (the_info
, codep
+ 1);
4773 USED_REX (REX_MODE64
);
4774 if (rex
& REX_MODE64
)
4776 else if (sizeflag
& DFLAG
)
4786 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4793 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4798 scratchbuf
[0] = '$';
4799 print_operand_value (scratchbuf
+ 1, 1, op
);
4800 oappend (scratchbuf
+ intel_syntax
);
4801 scratchbuf
[0] = '\0';
4805 OP_sI (int bytemode
, int sizeflag
)
4808 bfd_signed_vma mask
= -1;
4813 FETCH_DATA (the_info
, codep
+ 1);
4815 if ((op
& 0x80) != 0)
4820 USED_REX (REX_MODE64
);
4821 if (rex
& REX_MODE64
)
4823 else if (sizeflag
& DFLAG
)
4832 if ((op
& 0x8000) != 0)
4835 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4840 if ((op
& 0x8000) != 0)
4844 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4848 scratchbuf
[0] = '$';
4849 print_operand_value (scratchbuf
+ 1, 1, op
);
4850 oappend (scratchbuf
+ intel_syntax
);
4854 OP_J (int bytemode
, int sizeflag
)
4858 bfd_vma segment
= 0;
4863 FETCH_DATA (the_info
, codep
+ 1);
4865 if ((disp
& 0x80) != 0)
4869 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4874 if ((disp
& 0x8000) != 0)
4876 /* In 16bit mode, address is wrapped around at 64k within
4877 the same segment. Otherwise, a data16 prefix on a jump
4878 instruction means that the pc is masked to 16 bits after
4879 the displacement is added! */
4881 if ((prefixes
& PREFIX_DATA
) == 0)
4882 segment
= ((start_pc
+ codep
- start_codep
)
4883 & ~((bfd_vma
) 0xffff));
4885 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4888 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4891 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
4893 print_operand_value (scratchbuf
, 1, disp
);
4894 oappend (scratchbuf
);
4898 OP_SEG (int bytemode
, int sizeflag
)
4900 if (bytemode
== w_mode
)
4901 oappend (names_seg
[reg
]);
4903 OP_E (mod
== 3 ? bytemode
: w_mode
, sizeflag
);
4907 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4911 if (sizeflag
& DFLAG
)
4921 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4923 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4925 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4926 oappend (scratchbuf
);
4930 OP_OFF (int bytemode
, int sizeflag
)
4934 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4935 intel_operand_size (bytemode
, sizeflag
);
4938 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4945 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4946 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4948 oappend (names_seg
[ds_reg
- es_reg
]);
4952 print_operand_value (scratchbuf
, 1, off
);
4953 oappend (scratchbuf
);
4957 OP_OFF64 (int bytemode
, int sizeflag
)
4961 if (address_mode
!= mode_64bit
4962 || (prefixes
& PREFIX_ADDR
))
4964 OP_OFF (bytemode
, sizeflag
);
4968 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4969 intel_operand_size (bytemode
, sizeflag
);
4976 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4977 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4979 oappend (names_seg
[ds_reg
- es_reg
]);
4983 print_operand_value (scratchbuf
, 1, off
);
4984 oappend (scratchbuf
);
4988 ptr_reg (int code
, int sizeflag
)
4992 *obufp
++ = open_char
;
4993 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4994 if (address_mode
== mode_64bit
)
4996 if (!(sizeflag
& AFLAG
))
4997 s
= names32
[code
- eAX_reg
];
4999 s
= names64
[code
- eAX_reg
];
5001 else if (sizeflag
& AFLAG
)
5002 s
= names32
[code
- eAX_reg
];
5004 s
= names16
[code
- eAX_reg
];
5006 *obufp
++ = close_char
;
5011 OP_ESreg (int code
, int sizeflag
)
5017 case 0x6d: /* insw/insl */
5018 intel_operand_size (z_mode
, sizeflag
);
5020 case 0xa5: /* movsw/movsl/movsq */
5021 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5022 case 0xab: /* stosw/stosl */
5023 case 0xaf: /* scasw/scasl */
5024 intel_operand_size (v_mode
, sizeflag
);
5027 intel_operand_size (b_mode
, sizeflag
);
5030 oappend ("%es:" + intel_syntax
);
5031 ptr_reg (code
, sizeflag
);
5035 OP_DSreg (int code
, int sizeflag
)
5041 case 0x6f: /* outsw/outsl */
5042 intel_operand_size (z_mode
, sizeflag
);
5044 case 0xa5: /* movsw/movsl/movsq */
5045 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5046 case 0xad: /* lodsw/lodsl/lodsq */
5047 intel_operand_size (v_mode
, sizeflag
);
5050 intel_operand_size (b_mode
, sizeflag
);
5060 prefixes
|= PREFIX_DS
;
5062 ptr_reg (code
, sizeflag
);
5066 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5071 USED_REX (REX_EXTX
);
5074 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5076 used_prefixes
|= PREFIX_LOCK
;
5079 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
5080 oappend (scratchbuf
+ intel_syntax
);
5084 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5087 USED_REX (REX_EXTX
);
5091 sprintf (scratchbuf
, "db%d", reg
+ add
);
5093 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
5094 oappend (scratchbuf
);
5098 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5100 sprintf (scratchbuf
, "%%tr%d", reg
);
5101 oappend (scratchbuf
+ intel_syntax
);
5105 OP_Rd (int bytemode
, int sizeflag
)
5108 OP_E (bytemode
, sizeflag
);
5114 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5116 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5117 if (prefixes
& PREFIX_DATA
)
5120 USED_REX (REX_EXTX
);
5123 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5126 sprintf (scratchbuf
, "%%mm%d", reg
);
5127 oappend (scratchbuf
+ intel_syntax
);
5131 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5134 USED_REX (REX_EXTX
);
5137 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
5138 oappend (scratchbuf
+ intel_syntax
);
5142 OP_EM (int bytemode
, int sizeflag
)
5146 if (intel_syntax
&& bytemode
== v_mode
)
5148 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5149 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5151 OP_E (bytemode
, sizeflag
);
5155 /* Skip mod/rm byte. */
5158 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5159 if (prefixes
& PREFIX_DATA
)
5163 USED_REX (REX_EXTZ
);
5166 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5169 sprintf (scratchbuf
, "%%mm%d", rm
);
5170 oappend (scratchbuf
+ intel_syntax
);
5173 /* cvt* are the only instructions in sse2 which have
5174 both SSE and MMX operands and also have 0x66 prefix
5175 in their opcode. 0x66 was originally used to differentiate
5176 between SSE and MMX instruction(operands). So we have to handle the
5177 cvt* separately using OP_EMC and OP_MXC */
5179 OP_EMC (int bytemode
, int sizeflag
)
5183 if (intel_syntax
&& bytemode
== v_mode
)
5185 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
5186 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5188 OP_E (bytemode
, sizeflag
);
5192 /* Skip mod/rm byte. */
5195 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5196 sprintf (scratchbuf
, "%%mm%d", rm
);
5197 oappend (scratchbuf
+ intel_syntax
);
5201 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5203 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5204 sprintf (scratchbuf
, "%%mm%d", reg
);
5205 oappend (scratchbuf
+ intel_syntax
);
5209 OP_EX (int bytemode
, int sizeflag
)
5214 if (intel_syntax
&& bytemode
== v_mode
)
5216 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
5218 case 0: bytemode
= x_mode
; break;
5219 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
5220 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
5221 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
5222 default: bytemode
= 0; break;
5225 OP_E (bytemode
, sizeflag
);
5228 USED_REX (REX_EXTZ
);
5232 /* Skip mod/rm byte. */
5235 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
5236 oappend (scratchbuf
+ intel_syntax
);
5240 OP_MS (int bytemode
, int sizeflag
)
5243 OP_EM (bytemode
, sizeflag
);
5249 OP_XS (int bytemode
, int sizeflag
)
5252 OP_EX (bytemode
, sizeflag
);
5258 OP_M (int bytemode
, int sizeflag
)
5261 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5264 OP_E (bytemode
, sizeflag
);
5268 OP_0f07 (int bytemode
, int sizeflag
)
5270 if (mod
!= 3 || rm
!= 0)
5273 OP_E (bytemode
, sizeflag
);
5277 OP_0fae (int bytemode
, int sizeflag
)
5282 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
5284 if (reg
< 5 || rm
!= 0)
5286 BadOp (); /* bad sfence, mfence, or lfence */
5292 BadOp (); /* bad clflush */
5296 OP_E (bytemode
, sizeflag
);
5299 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5300 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5301 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5305 NOP_Fixup1 (int bytemode
, int sizeflag
)
5307 if (prefixes
== PREFIX_REPZ
)
5308 strcpy (obuf
, "pause");
5309 else if (prefixes
== PREFIX_DATA
5310 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5311 OP_REG (bytemode
, sizeflag
);
5313 strcpy (obuf
, "nop");
5317 NOP_Fixup2 (int bytemode
, int sizeflag
)
5319 if (prefixes
== PREFIX_DATA
5320 || ((rex
& REX_MODE64
) && rex
!= 0x48))
5321 OP_IMREG (bytemode
, sizeflag
);
5324 static const char *const Suffix3DNow
[] = {
5325 /* 00 */ NULL
, NULL
, NULL
, NULL
,
5326 /* 04 */ NULL
, NULL
, NULL
, NULL
,
5327 /* 08 */ NULL
, NULL
, NULL
, NULL
,
5328 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
5329 /* 10 */ NULL
, NULL
, NULL
, NULL
,
5330 /* 14 */ NULL
, NULL
, NULL
, NULL
,
5331 /* 18 */ NULL
, NULL
, NULL
, NULL
,
5332 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
5333 /* 20 */ NULL
, NULL
, NULL
, NULL
,
5334 /* 24 */ NULL
, NULL
, NULL
, NULL
,
5335 /* 28 */ NULL
, NULL
, NULL
, NULL
,
5336 /* 2C */ NULL
, NULL
, NULL
, NULL
,
5337 /* 30 */ NULL
, NULL
, NULL
, NULL
,
5338 /* 34 */ NULL
, NULL
, NULL
, NULL
,
5339 /* 38 */ NULL
, NULL
, NULL
, NULL
,
5340 /* 3C */ NULL
, NULL
, NULL
, NULL
,
5341 /* 40 */ NULL
, NULL
, NULL
, NULL
,
5342 /* 44 */ NULL
, NULL
, NULL
, NULL
,
5343 /* 48 */ NULL
, NULL
, NULL
, NULL
,
5344 /* 4C */ NULL
, NULL
, NULL
, NULL
,
5345 /* 50 */ NULL
, NULL
, NULL
, NULL
,
5346 /* 54 */ NULL
, NULL
, NULL
, NULL
,
5347 /* 58 */ NULL
, NULL
, NULL
, NULL
,
5348 /* 5C */ NULL
, NULL
, NULL
, NULL
,
5349 /* 60 */ NULL
, NULL
, NULL
, NULL
,
5350 /* 64 */ NULL
, NULL
, NULL
, NULL
,
5351 /* 68 */ NULL
, NULL
, NULL
, NULL
,
5352 /* 6C */ NULL
, NULL
, NULL
, NULL
,
5353 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5354 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5355 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5356 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5357 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5358 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5359 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5360 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5361 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5362 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5363 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5364 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5365 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5366 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5367 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5368 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5369 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5370 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5371 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5372 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5373 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5374 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5375 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5376 /* CC */ NULL
, NULL
, NULL
, NULL
,
5377 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5378 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5379 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5380 /* DC */ NULL
, NULL
, NULL
, NULL
,
5381 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5382 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5383 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5384 /* EC */ NULL
, NULL
, NULL
, NULL
,
5385 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5386 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5387 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5388 /* FC */ NULL
, NULL
, NULL
, NULL
,
5392 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5394 const char *mnemonic
;
5396 FETCH_DATA (the_info
, codep
+ 1);
5397 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5398 place where an 8-bit immediate would normally go. ie. the last
5399 byte of the instruction. */
5400 obufp
= obuf
+ strlen (obuf
);
5401 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5406 /* Since a variable sized modrm/sib chunk is between the start
5407 of the opcode (0x0f0f) and the opcode suffix, we need to do
5408 all the modrm processing first, and don't know until now that
5409 we have a bad opcode. This necessitates some cleaning up. */
5410 op_out
[0][0] = '\0';
5411 op_out
[1][0] = '\0';
5416 static const char *simd_cmp_op
[] = {
5428 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5430 unsigned int cmp_type
;
5432 FETCH_DATA (the_info
, codep
+ 1);
5433 obufp
= obuf
+ strlen (obuf
);
5434 cmp_type
= *codep
++ & 0xff;
5437 char suffix1
= 'p', suffix2
= 's';
5438 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5439 if (prefixes
& PREFIX_REPZ
)
5443 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5444 if (prefixes
& PREFIX_DATA
)
5448 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5449 if (prefixes
& PREFIX_REPNZ
)
5450 suffix1
= 's', suffix2
= 'd';
5453 sprintf (scratchbuf
, "cmp%s%c%c",
5454 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5455 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5456 oappend (scratchbuf
);
5460 /* We have a bad extension byte. Clean up. */
5461 op_out
[0][0] = '\0';
5462 op_out
[1][0] = '\0';
5468 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
5470 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5471 forms of these instructions. */
5474 char *p
= obuf
+ strlen (obuf
);
5477 *(p
- 1) = *(p
- 2);
5478 *(p
- 2) = *(p
- 3);
5479 *(p
- 3) = extrachar
;
5484 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5486 if (mod
== 3 && reg
== 1 && rm
<= 1)
5488 /* Override "sidt". */
5489 size_t olen
= strlen (obuf
);
5490 char *p
= obuf
+ olen
- 4;
5491 const char **names
= (address_mode
== mode_64bit
5492 ? names64
: names32
);
5494 /* We might have a suffix when disassembling with -Msuffix. */
5498 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5500 && (prefixes
& PREFIX_ADDR
)
5503 && CONST_STRNEQ (p
- 7, "addr")
5504 && (CONST_STRNEQ (p
- 3, "16")
5505 || CONST_STRNEQ (p
- 3, "32")))
5510 /* mwait %eax,%ecx */
5511 strcpy (p
, "mwait");
5513 strcpy (op_out
[0], names
[0]);
5517 /* monitor %eax,%ecx,%edx" */
5518 strcpy (p
, "monitor");
5521 const char **op1_names
;
5522 if (!(prefixes
& PREFIX_ADDR
))
5523 op1_names
= (address_mode
== mode_16bit
5527 op1_names
= (address_mode
!= mode_32bit
5528 ? names32
: names16
);
5529 used_prefixes
|= PREFIX_ADDR
;
5531 strcpy (op_out
[0], op1_names
[0]);
5532 strcpy (op_out
[2], names
[2]);
5537 strcpy (op_out
[1], names
[1]);
5548 SVME_Fixup (int bytemode
, int sizeflag
)
5580 OP_M (bytemode
, sizeflag
);
5583 /* Override "lidt". */
5584 p
= obuf
+ strlen (obuf
) - 4;
5585 /* We might have a suffix. */
5589 if (!(prefixes
& PREFIX_ADDR
))
5594 used_prefixes
|= PREFIX_ADDR
;
5598 strcpy (op_out
[1], names32
[1]);
5604 *obufp
++ = open_char
;
5605 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
5609 strcpy (obufp
, alt
);
5610 obufp
+= strlen (alt
);
5611 *obufp
++ = close_char
;
5618 INVLPG_Fixup (int bytemode
, int sizeflag
)
5631 OP_M (bytemode
, sizeflag
);
5634 /* Override "invlpg". */
5635 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
5642 /* Throw away prefixes and 1st. opcode byte. */
5643 codep
= insn_codep
+ 1;
5648 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
5650 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
5652 /* Override "sgdt". */
5653 char *p
= obuf
+ strlen (obuf
) - 4;
5655 /* We might have a suffix when disassembling with -Msuffix. */
5662 strcpy (p
, "vmcall");
5665 strcpy (p
, "vmlaunch");
5668 strcpy (p
, "vmresume");
5671 strcpy (p
, "vmxoff");
5682 OP_VMX (int bytemode
, int sizeflag
)
5684 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
5685 if (prefixes
& PREFIX_DATA
)
5686 strcpy (obuf
, "vmclear");
5687 else if (prefixes
& PREFIX_REPZ
)
5688 strcpy (obuf
, "vmxon");
5690 strcpy (obuf
, "vmptrld");
5691 OP_E (bytemode
, sizeflag
);
5695 REP_Fixup (int bytemode
, int sizeflag
)
5697 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5701 if (prefixes
& PREFIX_REPZ
)
5702 switch (*insn_codep
)
5704 case 0x6e: /* outsb */
5705 case 0x6f: /* outsw/outsl */
5706 case 0xa4: /* movsb */
5707 case 0xa5: /* movsw/movsl/movsq */
5713 case 0xaa: /* stosb */
5714 case 0xab: /* stosw/stosl/stosq */
5715 case 0xac: /* lodsb */
5716 case 0xad: /* lodsw/lodsl/lodsq */
5717 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5722 case 0x6c: /* insb */
5723 case 0x6d: /* insl/insw */
5739 olen
= strlen (obuf
);
5740 p
= obuf
+ olen
- ilen
- 1 - 4;
5741 /* Handle "repz [addr16|addr32]". */
5742 if ((prefixes
& PREFIX_ADDR
))
5745 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
5753 OP_IMREG (bytemode
, sizeflag
);
5756 OP_ESreg (bytemode
, sizeflag
);
5759 OP_DSreg (bytemode
, sizeflag
);
5768 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
5770 USED_REX (REX_MODE64
);
5771 if (rex
& REX_MODE64
)
5773 /* Change cmpxchg8b to cmpxchg16b. */
5774 char *p
= obuf
+ strlen (obuf
) - 2;
5778 OP_M (bytemode
, sizeflag
);