1 /* opcodes/i386-dis.c r1.126 */
2 /* Print i386 instructions for GDB, the GNU debugger.
3 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>. */
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. */
34 #include "qemu/osdep.h"
35 #include "disas/bfd.h"
36 /* include/opcode/i386.h r1.78 */
38 /* opcode/i386.h -- Intel 80386 opcode macros
39 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
40 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
41 Free Software Foundation, Inc.
43 This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
45 This program is free software; you can redistribute it and/or modify
46 it under the terms of the GNU General Public License as published by
47 the Free Software Foundation; either version 2 of the License, or
48 (at your option) any later version.
50 This program is distributed in the hope that it will be useful,
51 but WITHOUT ANY WARRANTY; without even the implied warranty of
52 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53 GNU General Public License for more details.
55 You should have received a copy of the GNU General Public License
56 along with this program; if not, see <http://www.gnu.org/licenses/>. */
58 /* The SystemV/386 SVR3.2 assembler, and probably all AT&T derived
59 ix86 Unix assemblers, generate floating point instructions with
60 reversed source and destination registers in certain cases.
61 Unfortunately, gcc and possibly many other programs use this
62 reversed syntax, so we're stuck with it.
64 eg. `fsub %st(3),%st' results in st = st - st(3) as expected, but
65 `fsub %st,%st(3)' results in st(3) = st - st(3), rather than
66 the expected st(3) = st(3) - st
68 This happens with all the non-commutative arithmetic floating point
69 operations with two register operands, where the source register is
70 %st, and destination register is %st(i).
72 The affected opcode map is dceX, dcfX, deeX, defX. */
74 #ifndef SYSV386_COMPAT
75 /* Set non-zero for broken, compatible instructions. Set to zero for
76 non-broken opcodes at your peril. gcc generates SystemV/386
77 compatible instructions. */
78 #define SYSV386_COMPAT 1
81 /* Set non-zero to cater for old (<= 2.8.1) versions of gcc that could
82 generate nonsense fsubp, fsubrp, fdivp and fdivrp with operands
84 #define OLDGCC_COMPAT SYSV386_COMPAT
87 #define MOV_AX_DISP32 0xa0
88 #define POP_SEG_SHORT 0x07
89 #define JUMP_PC_RELATIVE 0xeb
90 #define INT_OPCODE 0xcd
91 #define INT3_OPCODE 0xcc
92 /* The opcode for the fwait instruction, which disassembler treats as a
93 prefix when it can. */
94 #define FWAIT_OPCODE 0x9b
95 #define ADDR_PREFIX_OPCODE 0x67
96 #define DATA_PREFIX_OPCODE 0x66
97 #define LOCK_PREFIX_OPCODE 0xf0
98 #define CS_PREFIX_OPCODE 0x2e
99 #define DS_PREFIX_OPCODE 0x3e
100 #define ES_PREFIX_OPCODE 0x26
101 #define FS_PREFIX_OPCODE 0x64
102 #define GS_PREFIX_OPCODE 0x65
103 #define SS_PREFIX_OPCODE 0x36
104 #define REPNE_PREFIX_OPCODE 0xf2
105 #define REPE_PREFIX_OPCODE 0xf3
107 #define TWO_BYTE_OPCODE_ESCAPE 0x0f
108 #define NOP_OPCODE (char) 0x90
110 /* register numbers */
111 #define EBP_REG_NUM 5
112 #define ESP_REG_NUM 4
114 /* modrm_byte.regmem for twobyte escape */
115 #define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
116 /* index_base_byte.index for no index register addressing */
117 #define NO_INDEX_REGISTER ESP_REG_NUM
118 /* index_base_byte.base for no base register addressing */
119 #define NO_BASE_REGISTER EBP_REG_NUM
120 #define NO_BASE_REGISTER_16 6
122 /* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */
123 #define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */
124 #define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
126 /* x86-64 extension prefix. */
127 #define REX_OPCODE 0x40
129 /* Indicates 64 bit operand size. */
131 /* High extension to reg field of modrm byte. */
133 /* High extension to SIB index field. */
135 /* High extension to base field of modrm or SIB, or reg field of opcode. */
138 /* max operands per insn */
139 #define MAX_OPERANDS 4
141 /* max immediates per insn (lcall, ljmp, insertq, extrq) */
142 #define MAX_IMMEDIATE_OPERANDS 2
144 /* max memory refs per insn (string ops) */
145 #define MAX_MEMORY_OPERANDS 2
147 /* max size of insn mnemonics. */
148 #define MAX_MNEM_SIZE 16
150 /* max size of register name in insn mnemonics. */
151 #define MAX_REG_NAME_SIZE 8
153 /* opcodes/i386-dis.c r1.126 */
154 #include "qemu-common.h"
156 static int fetch_data2(struct disassemble_info
*, bfd_byte
*);
157 static int fetch_data(struct disassemble_info
*, bfd_byte
*);
158 static void ckprefix (void);
159 static const char *prefix_name (int, int);
160 static int print_insn (bfd_vma
, disassemble_info
*);
161 static void dofloat (int);
162 static void OP_ST (int, int);
163 static void OP_STi (int, int);
164 static int putop (const char *, int);
165 static void oappend (const char *);
166 static void append_seg (void);
167 static void OP_indirE (int, int);
168 static void print_operand_value (char *buf
, size_t bufsize
, int hex
, bfd_vma disp
);
169 static void print_displacement (char *, bfd_vma
);
170 static void OP_E (int, int);
171 static void OP_G (int, int);
172 static void OP_vvvv (int, int);
173 static bfd_vma
get64 (void);
174 static bfd_signed_vma
get32 (void);
175 static bfd_signed_vma
get32s (void);
176 static int get16 (void);
177 static void set_op (bfd_vma
, int);
178 static void OP_REG (int, int);
179 static void OP_IMREG (int, int);
180 static void OP_I (int, int);
181 static void OP_I64 (int, int);
182 static void OP_sI (int, int);
183 static void OP_J (int, int);
184 static void OP_SEG (int, int);
185 static void OP_DIR (int, int);
186 static void OP_OFF (int, int);
187 static void OP_OFF64 (int, int);
188 static void ptr_reg (int, int);
189 static void OP_ESreg (int, int);
190 static void OP_DSreg (int, int);
191 static void OP_C (int, int);
192 static void OP_D (int, int);
193 static void OP_T (int, int);
194 static void OP_R (int, int);
195 static void OP_MMX (int, int);
196 static void OP_XMM (int, int);
197 static void OP_EM (int, int);
198 static void OP_EX (int, int);
199 static void OP_EMC (int,int);
200 static void OP_MXC (int,int);
201 static void OP_MS (int, int);
202 static void OP_XS (int, int);
203 static void OP_M (int, int);
204 static void OP_VMX (int, int);
205 static void OP_0fae (int, int);
206 static void OP_0f07 (int, int);
207 static void NOP_Fixup1 (int, int);
208 static void NOP_Fixup2 (int, int);
209 static void OP_3DNowSuffix (int, int);
210 static void OP_SIMD_Suffix (int, int);
211 static void SIMD_Fixup (int, int);
212 static void PNI_Fixup (int, int);
213 static void SVME_Fixup (int, int);
214 static void INVLPG_Fixup (int, int);
215 static void BadOp (void);
216 static void VMX_Fixup (int, int);
217 static void REP_Fixup (int, int);
218 static void CMPXCHG8B_Fixup (int, int);
219 static void XMM_Fixup (int, int);
220 static void CRC32_Fixup (int, int);
223 /* Points to first byte not fetched. */
224 bfd_byte
*max_fetched
;
225 bfd_byte the_buffer
[MAX_MNEM_SIZE
];
238 static enum address_mode address_mode
;
240 /* Flags for the prefixes for the current instruction. See below. */
243 /* REX prefix the current instruction. See below. */
245 /* Bits of REX we've already used. */
247 /* Mark parts used in the REX prefix. When we are testing for
248 empty prefix (for 8bit register REX extension), just mask it
249 out. Otherwise test for REX bit is excuse for existence of REX
250 only in case value is nonzero. */
251 #define USED_REX(value) \
256 rex_used |= (value) | REX_OPCODE; \
259 rex_used |= REX_OPCODE; \
262 /* Flags for prefixes which we somehow handled when printing the
263 current instruction. */
264 static int used_prefixes
;
266 /* The VEX.vvvv register, unencoded. */
269 /* Flags stored in PREFIXES. */
270 #define PREFIX_REPZ 1
271 #define PREFIX_REPNZ 2
272 #define PREFIX_LOCK 4
274 #define PREFIX_SS 0x10
275 #define PREFIX_DS 0x20
276 #define PREFIX_ES 0x40
277 #define PREFIX_FS 0x80
278 #define PREFIX_GS 0x100
279 #define PREFIX_DATA 0x200
280 #define PREFIX_ADDR 0x400
281 #define PREFIX_FWAIT 0x800
283 #define PREFIX_VEX_0F 0x1000
284 #define PREFIX_VEX_0F38 0x2000
285 #define PREFIX_VEX_0F3A 0x4000
287 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
288 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
291 fetch_data2(struct disassemble_info
*info
, bfd_byte
*addr
)
294 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
295 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
297 if (addr
<= priv
->the_buffer
+ MAX_MNEM_SIZE
)
298 status
= (*info
->read_memory_func
) (start
,
300 addr
- priv
->max_fetched
,
306 /* If we did manage to read at least one byte, then
307 print_insn_i386 will do something sensible. Otherwise, print
308 an error. We do that here because this is where we know
310 if (priv
->max_fetched
== priv
->the_buffer
)
311 (*info
->memory_error_func
) (status
, start
, info
);
312 siglongjmp(priv
->bailout
, 1);
315 priv
->max_fetched
= addr
;
320 fetch_data(struct disassemble_info
*info
, bfd_byte
*addr
)
322 if (addr
<= ((struct dis_private
*) (info
->private_data
))->max_fetched
) {
325 return fetch_data2(info
, addr
);
330 #define XX { NULL, 0 }
332 #define Bv { OP_vvvv, v_mode }
333 #define Eb { OP_E, b_mode }
334 #define Ev { OP_E, v_mode }
335 #define Ed { OP_E, d_mode }
336 #define Edq { OP_E, dq_mode }
337 #define Edqw { OP_E, dqw_mode }
338 #define Edqb { OP_E, dqb_mode }
339 #define Edqd { OP_E, dqd_mode }
340 #define indirEv { OP_indirE, stack_v_mode }
341 #define indirEp { OP_indirE, f_mode }
342 #define stackEv { OP_E, stack_v_mode }
343 #define Em { OP_E, m_mode }
344 #define Ew { OP_E, w_mode }
345 #define M { OP_M, 0 } /* lea, lgdt, etc. */
346 #define Ma { OP_M, v_mode }
347 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
348 #define Mq { OP_M, q_mode }
349 #define Gb { OP_G, b_mode }
350 #define Gv { OP_G, v_mode }
351 #define Gd { OP_G, d_mode }
352 #define Gdq { OP_G, dq_mode }
353 #define Gm { OP_G, m_mode }
354 #define Gw { OP_G, w_mode }
355 #define Rd { OP_R, d_mode }
356 #define Rm { OP_R, m_mode }
357 #define Ib { OP_I, b_mode }
358 #define sIb { OP_sI, b_mode } /* sign extended byte */
359 #define Iv { OP_I, v_mode }
360 #define Iq { OP_I, q_mode }
361 #define Iv64 { OP_I64, v_mode }
362 #define Iw { OP_I, w_mode }
363 #define I1 { OP_I, const_1_mode }
364 #define Jb { OP_J, b_mode }
365 #define Jv { OP_J, v_mode }
366 #define Cm { OP_C, m_mode }
367 #define Dm { OP_D, m_mode }
368 #define Td { OP_T, d_mode }
370 #define RMeAX { OP_REG, eAX_reg }
371 #define RMeBX { OP_REG, eBX_reg }
372 #define RMeCX { OP_REG, eCX_reg }
373 #define RMeDX { OP_REG, eDX_reg }
374 #define RMeSP { OP_REG, eSP_reg }
375 #define RMeBP { OP_REG, eBP_reg }
376 #define RMeSI { OP_REG, eSI_reg }
377 #define RMeDI { OP_REG, eDI_reg }
378 #define RMrAX { OP_REG, rAX_reg }
379 #define RMrBX { OP_REG, rBX_reg }
380 #define RMrCX { OP_REG, rCX_reg }
381 #define RMrDX { OP_REG, rDX_reg }
382 #define RMrSP { OP_REG, rSP_reg }
383 #define RMrBP { OP_REG, rBP_reg }
384 #define RMrSI { OP_REG, rSI_reg }
385 #define RMrDI { OP_REG, rDI_reg }
386 #define RMAL { OP_REG, al_reg }
387 #define RMAL { OP_REG, al_reg }
388 #define RMCL { OP_REG, cl_reg }
389 #define RMDL { OP_REG, dl_reg }
390 #define RMBL { OP_REG, bl_reg }
391 #define RMAH { OP_REG, ah_reg }
392 #define RMCH { OP_REG, ch_reg }
393 #define RMDH { OP_REG, dh_reg }
394 #define RMBH { OP_REG, bh_reg }
395 #define RMAX { OP_REG, ax_reg }
396 #define RMDX { OP_REG, dx_reg }
398 #define eAX { OP_IMREG, eAX_reg }
399 #define eBX { OP_IMREG, eBX_reg }
400 #define eCX { OP_IMREG, eCX_reg }
401 #define eDX { OP_IMREG, eDX_reg }
402 #define eSP { OP_IMREG, eSP_reg }
403 #define eBP { OP_IMREG, eBP_reg }
404 #define eSI { OP_IMREG, eSI_reg }
405 #define eDI { OP_IMREG, eDI_reg }
406 #define AL { OP_IMREG, al_reg }
407 #define CL { OP_IMREG, cl_reg }
408 #define DL { OP_IMREG, dl_reg }
409 #define BL { OP_IMREG, bl_reg }
410 #define AH { OP_IMREG, ah_reg }
411 #define CH { OP_IMREG, ch_reg }
412 #define DH { OP_IMREG, dh_reg }
413 #define BH { OP_IMREG, bh_reg }
414 #define AX { OP_IMREG, ax_reg }
415 #define DX { OP_IMREG, dx_reg }
416 #define zAX { OP_IMREG, z_mode_ax_reg }
417 #define indirDX { OP_IMREG, indir_dx_reg }
419 #define Sw { OP_SEG, w_mode }
420 #define Sv { OP_SEG, v_mode }
421 #define Ap { OP_DIR, 0 }
422 #define Ob { OP_OFF64, b_mode }
423 #define Ov { OP_OFF64, v_mode }
424 #define Xb { OP_DSreg, eSI_reg }
425 #define Xv { OP_DSreg, eSI_reg }
426 #define Xz { OP_DSreg, eSI_reg }
427 #define Yb { OP_ESreg, eDI_reg }
428 #define Yv { OP_ESreg, eDI_reg }
429 #define DSBX { OP_DSreg, eBX_reg }
431 #define es { OP_REG, es_reg }
432 #define ss { OP_REG, ss_reg }
433 #define cs { OP_REG, cs_reg }
434 #define ds { OP_REG, ds_reg }
435 #define fs { OP_REG, fs_reg }
436 #define gs { OP_REG, gs_reg }
438 #define MX { OP_MMX, 0 }
439 #define XM { OP_XMM, 0 }
440 #define EM { OP_EM, v_mode }
441 #define EMd { OP_EM, d_mode }
442 #define EMq { OP_EM, q_mode }
443 #define EXd { OP_EX, d_mode }
444 #define EXq { OP_EX, q_mode }
445 #define EXx { OP_EX, x_mode }
446 #define MS { OP_MS, v_mode }
447 #define XS { OP_XS, v_mode }
448 #define EMC { OP_EMC, v_mode }
449 #define MXC { OP_MXC, 0 }
450 #define VM { OP_VMX, q_mode }
451 #define OPSUF { OP_3DNowSuffix, 0 }
452 #define OPSIMD { OP_SIMD_Suffix, 0 }
453 #define XMM0 { XMM_Fixup, 0 }
455 /* Used handle "rep" prefix for string instructions. */
456 #define Xbr { REP_Fixup, eSI_reg }
457 #define Xvr { REP_Fixup, eSI_reg }
458 #define Ybr { REP_Fixup, eDI_reg }
459 #define Yvr { REP_Fixup, eDI_reg }
460 #define Yzr { REP_Fixup, eDI_reg }
461 #define indirDXr { REP_Fixup, indir_dx_reg }
462 #define ALr { REP_Fixup, al_reg }
463 #define eAXr { REP_Fixup, eAX_reg }
465 #define cond_jump_flag { NULL, cond_jump_mode }
466 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
468 /* bits in sizeflag */
469 #define SUFFIX_ALWAYS 4
473 #define b_mode 1 /* byte operand */
474 #define v_mode 2 /* operand size depends on prefixes */
475 #define w_mode 3 /* word operand */
476 #define d_mode 4 /* double word operand */
477 #define q_mode 5 /* quad word operand */
478 #define t_mode 6 /* ten-byte operand */
479 #define x_mode 7 /* 16-byte XMM operand */
480 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
481 #define cond_jump_mode 9
482 #define loop_jcxz_mode 10
483 #define dq_mode 11 /* operand size depends on REX prefixes. */
484 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
485 #define f_mode 13 /* 4- or 6-byte pointer operand */
486 #define const_1_mode 14
487 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
488 #define z_mode 16 /* non-quad operand size depends on prefixes */
489 #define o_mode 17 /* 16-byte operand */
490 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
491 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
536 #define z_mode_ax_reg 149
537 #define indir_dx_reg 150
541 #define USE_PREFIX_USER_TABLE 3
542 #define X86_64_SPECIAL 4
543 #define IS_3BYTE_OPCODE 5
545 #define FLOAT NULL, { { NULL, FLOATCODE } }
547 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
548 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
549 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
550 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
551 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
552 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
553 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
554 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
555 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
556 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
557 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
558 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
559 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
560 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
561 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
562 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
563 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
564 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
565 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
566 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
567 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
568 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
569 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
570 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
571 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
572 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
573 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
574 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
576 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
577 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
578 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
579 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
580 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
581 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
582 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
583 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
584 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
585 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
586 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
587 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
588 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
589 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
590 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
591 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
592 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
593 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
594 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
595 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
596 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
597 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
598 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
599 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
600 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
601 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
602 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
603 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
604 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
605 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
606 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
607 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
608 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
609 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
610 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
611 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
612 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
613 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
614 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
615 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
616 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
617 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
618 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
619 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
620 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
621 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
622 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
623 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
624 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
625 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
626 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
627 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
628 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
629 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
630 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
631 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
632 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
633 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
634 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
635 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
636 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
637 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
638 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
639 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
640 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
641 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
642 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
643 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
644 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
645 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
646 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
647 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
648 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
649 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
650 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
651 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
652 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
653 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
654 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
655 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
656 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
657 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
658 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
659 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
660 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
661 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
662 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
663 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
664 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
665 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
666 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
667 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
668 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
669 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
670 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
671 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
672 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
673 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
674 #define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
675 #define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
676 #define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
677 #define PREGRP101 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 101 } }
678 #define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
679 #define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
680 #define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
681 #define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
682 #define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
684 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
685 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
686 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
687 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
689 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
690 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
692 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
703 /* Upper case letters in the instruction names here are macros.
704 'A' => print 'b' if no register operands or suffix_always is true
705 'B' => print 'b' if suffix_always is true
706 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
708 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
709 . suffix_always is true
710 'E' => print 'e' if 32-bit form of jcxz
711 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
712 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
713 'H' => print ",pt" or ",pn" branch hint
714 'I' => honor following macro letter even in Intel mode (implemented only
715 . for some of the macro letters)
717 'K' => print 'd' or 'q' if rex prefix is present.
718 'L' => print 'l' if suffix_always is true
719 'N' => print 'n' if instruction has no wait "prefix"
720 'O' => print 'd' or 'o' (or 'q' in Intel mode)
721 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
722 . or suffix_always is true. print 'q' if rex prefix is present.
723 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
725 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
726 'S' => print 'w', 'l' or 'q' if suffix_always is true
727 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
728 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
729 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
730 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
731 'X' => print 's', 'd' depending on data16 prefix (for XMM)
732 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
733 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
735 Many of the above letters print nothing in Intel mode. See "putop"
738 Braces '{' and '}', and vertical bars '|', indicate alternative
739 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
740 modes. In cases where there are only two alternatives, the X86_64
741 instruction is reserved, and "(bad)" is printed.
744 static const struct dis386 dis386
[] = {
746 { "addB", { Eb
, Gb
} },
747 { "addS", { Ev
, Gv
} },
748 { "addB", { Gb
, Eb
} },
749 { "addS", { Gv
, Ev
} },
750 { "addB", { AL
, Ib
} },
751 { "addS", { eAX
, Iv
} },
752 { "push{T|}", { es
} },
753 { "pop{T|}", { es
} },
755 { "orB", { Eb
, Gb
} },
756 { "orS", { Ev
, Gv
} },
757 { "orB", { Gb
, Eb
} },
758 { "orS", { Gv
, Ev
} },
759 { "orB", { AL
, Ib
} },
760 { "orS", { eAX
, Iv
} },
761 { "push{T|}", { cs
} },
762 { "(bad)", { XX
} }, /* 0x0f extended opcode escape */
764 { "adcB", { Eb
, Gb
} },
765 { "adcS", { Ev
, Gv
} },
766 { "adcB", { Gb
, Eb
} },
767 { "adcS", { Gv
, Ev
} },
768 { "adcB", { AL
, Ib
} },
769 { "adcS", { eAX
, Iv
} },
770 { "push{T|}", { ss
} },
771 { "pop{T|}", { ss
} },
773 { "sbbB", { Eb
, Gb
} },
774 { "sbbS", { Ev
, Gv
} },
775 { "sbbB", { Gb
, Eb
} },
776 { "sbbS", { Gv
, Ev
} },
777 { "sbbB", { AL
, Ib
} },
778 { "sbbS", { eAX
, Iv
} },
779 { "push{T|}", { ds
} },
780 { "pop{T|}", { ds
} },
782 { "andB", { Eb
, Gb
} },
783 { "andS", { Ev
, Gv
} },
784 { "andB", { Gb
, Eb
} },
785 { "andS", { Gv
, Ev
} },
786 { "andB", { AL
, Ib
} },
787 { "andS", { eAX
, Iv
} },
788 { "(bad)", { XX
} }, /* SEG ES prefix */
789 { "daa{|}", { XX
} },
791 { "subB", { Eb
, Gb
} },
792 { "subS", { Ev
, Gv
} },
793 { "subB", { Gb
, Eb
} },
794 { "subS", { Gv
, Ev
} },
795 { "subB", { AL
, Ib
} },
796 { "subS", { eAX
, Iv
} },
797 { "(bad)", { XX
} }, /* SEG CS prefix */
798 { "das{|}", { XX
} },
800 { "xorB", { Eb
, Gb
} },
801 { "xorS", { Ev
, Gv
} },
802 { "xorB", { Gb
, Eb
} },
803 { "xorS", { Gv
, Ev
} },
804 { "xorB", { AL
, Ib
} },
805 { "xorS", { eAX
, Iv
} },
806 { "(bad)", { XX
} }, /* SEG SS prefix */
807 { "aaa{|}", { XX
} },
809 { "cmpB", { Eb
, Gb
} },
810 { "cmpS", { Ev
, Gv
} },
811 { "cmpB", { Gb
, Eb
} },
812 { "cmpS", { Gv
, Ev
} },
813 { "cmpB", { AL
, Ib
} },
814 { "cmpS", { eAX
, Iv
} },
815 { "(bad)", { XX
} }, /* SEG DS prefix */
816 { "aas{|}", { XX
} },
818 { "inc{S|}", { RMeAX
} },
819 { "inc{S|}", { RMeCX
} },
820 { "inc{S|}", { RMeDX
} },
821 { "inc{S|}", { RMeBX
} },
822 { "inc{S|}", { RMeSP
} },
823 { "inc{S|}", { RMeBP
} },
824 { "inc{S|}", { RMeSI
} },
825 { "inc{S|}", { RMeDI
} },
827 { "dec{S|}", { RMeAX
} },
828 { "dec{S|}", { RMeCX
} },
829 { "dec{S|}", { RMeDX
} },
830 { "dec{S|}", { RMeBX
} },
831 { "dec{S|}", { RMeSP
} },
832 { "dec{S|}", { RMeBP
} },
833 { "dec{S|}", { RMeSI
} },
834 { "dec{S|}", { RMeDI
} },
836 { "pushV", { RMrAX
} },
837 { "pushV", { RMrCX
} },
838 { "pushV", { RMrDX
} },
839 { "pushV", { RMrBX
} },
840 { "pushV", { RMrSP
} },
841 { "pushV", { RMrBP
} },
842 { "pushV", { RMrSI
} },
843 { "pushV", { RMrDI
} },
845 { "popV", { RMrAX
} },
846 { "popV", { RMrCX
} },
847 { "popV", { RMrDX
} },
848 { "popV", { RMrBX
} },
849 { "popV", { RMrSP
} },
850 { "popV", { RMrBP
} },
851 { "popV", { RMrSI
} },
852 { "popV", { RMrDI
} },
858 { "(bad)", { XX
} }, /* seg fs */
859 { "(bad)", { XX
} }, /* seg gs */
860 { "(bad)", { XX
} }, /* op size prefix */
861 { "(bad)", { XX
} }, /* adr size prefix */
864 { "imulS", { Gv
, Ev
, Iv
} },
865 { "pushT", { sIb
} },
866 { "imulS", { Gv
, Ev
, sIb
} },
867 { "ins{b||b|}", { Ybr
, indirDX
} },
868 { "ins{R||G|}", { Yzr
, indirDX
} },
869 { "outs{b||b|}", { indirDXr
, Xb
} },
870 { "outs{R||G|}", { indirDXr
, Xz
} },
872 { "joH", { Jb
, XX
, cond_jump_flag
} },
873 { "jnoH", { Jb
, XX
, cond_jump_flag
} },
874 { "jbH", { Jb
, XX
, cond_jump_flag
} },
875 { "jaeH", { Jb
, XX
, cond_jump_flag
} },
876 { "jeH", { Jb
, XX
, cond_jump_flag
} },
877 { "jneH", { Jb
, XX
, cond_jump_flag
} },
878 { "jbeH", { Jb
, XX
, cond_jump_flag
} },
879 { "jaH", { Jb
, XX
, cond_jump_flag
} },
881 { "jsH", { Jb
, XX
, cond_jump_flag
} },
882 { "jnsH", { Jb
, XX
, cond_jump_flag
} },
883 { "jpH", { Jb
, XX
, cond_jump_flag
} },
884 { "jnpH", { Jb
, XX
, cond_jump_flag
} },
885 { "jlH", { Jb
, XX
, cond_jump_flag
} },
886 { "jgeH", { Jb
, XX
, cond_jump_flag
} },
887 { "jleH", { Jb
, XX
, cond_jump_flag
} },
888 { "jgH", { Jb
, XX
, cond_jump_flag
} },
894 { "testB", { Eb
, Gb
} },
895 { "testS", { Ev
, Gv
} },
896 { "xchgB", { Eb
, Gb
} },
897 { "xchgS", { Ev
, Gv
} },
899 { "movB", { Eb
, Gb
} },
900 { "movS", { Ev
, Gv
} },
901 { "movB", { Gb
, Eb
} },
902 { "movS", { Gv
, Ev
} },
903 { "movD", { Sv
, Sw
} },
904 { "leaS", { Gv
, M
} },
905 { "movD", { Sw
, Sv
} },
909 { "xchgS", { RMeCX
, eAX
} },
910 { "xchgS", { RMeDX
, eAX
} },
911 { "xchgS", { RMeBX
, eAX
} },
912 { "xchgS", { RMeSP
, eAX
} },
913 { "xchgS", { RMeBP
, eAX
} },
914 { "xchgS", { RMeSI
, eAX
} },
915 { "xchgS", { RMeDI
, eAX
} },
917 { "cW{t||t|}R", { XX
} },
918 { "cR{t||t|}O", { XX
} },
919 { "Jcall{T|}", { Ap
} },
920 { "(bad)", { XX
} }, /* fwait */
921 { "pushfT", { XX
} },
923 { "sahf{|}", { XX
} },
924 { "lahf{|}", { XX
} },
926 { "movB", { AL
, Ob
} },
927 { "movS", { eAX
, Ov
} },
928 { "movB", { Ob
, AL
} },
929 { "movS", { Ov
, eAX
} },
930 { "movs{b||b|}", { Ybr
, Xb
} },
931 { "movs{R||R|}", { Yvr
, Xv
} },
932 { "cmps{b||b|}", { Xb
, Yb
} },
933 { "cmps{R||R|}", { Xv
, Yv
} },
935 { "testB", { AL
, Ib
} },
936 { "testS", { eAX
, Iv
} },
937 { "stosB", { Ybr
, AL
} },
938 { "stosS", { Yvr
, eAX
} },
939 { "lodsB", { ALr
, Xb
} },
940 { "lodsS", { eAXr
, Xv
} },
941 { "scasB", { AL
, Yb
} },
942 { "scasS", { eAX
, Yv
} },
944 { "movB", { RMAL
, Ib
} },
945 { "movB", { RMCL
, Ib
} },
946 { "movB", { RMDL
, Ib
} },
947 { "movB", { RMBL
, Ib
} },
948 { "movB", { RMAH
, Ib
} },
949 { "movB", { RMCH
, Ib
} },
950 { "movB", { RMDH
, Ib
} },
951 { "movB", { RMBH
, Ib
} },
953 { "movS", { RMeAX
, Iv64
} },
954 { "movS", { RMeCX
, Iv64
} },
955 { "movS", { RMeDX
, Iv64
} },
956 { "movS", { RMeBX
, Iv64
} },
957 { "movS", { RMeSP
, Iv64
} },
958 { "movS", { RMeBP
, Iv64
} },
959 { "movS", { RMeSI
, Iv64
} },
960 { "movS", { RMeDI
, Iv64
} },
966 { "les{S|}", { Gv
, Mp
} },
967 { "ldsS", { Gv
, Mp
} },
971 { "enterT", { Iw
, Ib
} },
972 { "leaveT", { XX
} },
977 { "into{|}", { XX
} },
984 { "aam{|}", { sIb
} },
985 { "aad{|}", { sIb
} },
987 { "xlat", { DSBX
} },
998 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
} },
999 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
} },
1000 { "loopFH", { Jb
, XX
, loop_jcxz_flag
} },
1001 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
} },
1002 { "inB", { AL
, Ib
} },
1003 { "inG", { zAX
, Ib
} },
1004 { "outB", { Ib
, AL
} },
1005 { "outG", { Ib
, zAX
} },
1007 { "callT", { Jv
} },
1009 { "Jjmp{T|}", { Ap
} },
1011 { "inB", { AL
, indirDX
} },
1012 { "inG", { zAX
, indirDX
} },
1013 { "outB", { indirDX
, AL
} },
1014 { "outG", { indirDX
, zAX
} },
1016 { "(bad)", { XX
} }, /* lock prefix */
1017 { "icebp", { XX
} },
1018 { "(bad)", { XX
} }, /* repne */
1019 { "(bad)", { XX
} }, /* repz */
1035 static const struct dis386 dis386_twobyte
[] = {
1039 { "larS", { Gv
, Ew
} },
1040 { "lslS", { Gv
, Ew
} },
1041 { "(bad)", { XX
} },
1042 { "syscall", { XX
} },
1044 { "sysretP", { XX
} },
1047 { "wbinvd", { XX
} },
1048 { "(bad)", { XX
} },
1050 { "(bad)", { XX
} },
1052 { "femms", { XX
} },
1053 { "", { MX
, EM
, OPSUF
} }, /* See OP_3DNowSuffix. */
1058 { "movlpX", { EXq
, XM
, { SIMD_Fixup
, 'h' } } },
1059 { "unpcklpX", { XM
, EXq
} },
1060 { "unpckhpX", { XM
, EXq
} },
1062 { "movhpX", { EXq
, XM
, { SIMD_Fixup
, 'l' } } },
1065 { "(bad)", { XX
} },
1066 { "(bad)", { XX
} },
1067 { "(bad)", { XX
} },
1068 { "(bad)", { XX
} },
1069 { "(bad)", { XX
} },
1070 { "(bad)", { XX
} },
1073 { "movZ", { Rm
, Cm
} },
1074 { "movZ", { Rm
, Dm
} },
1075 { "movZ", { Cm
, Rm
} },
1076 { "movZ", { Dm
, Rm
} },
1077 { "movL", { Rd
, Td
} },
1078 { "(bad)", { XX
} },
1079 { "movL", { Td
, Rd
} },
1080 { "(bad)", { XX
} },
1082 { "movapX", { XM
, EXx
} },
1083 { "movapX", { EXx
, XM
} },
1091 { "wrmsr", { XX
} },
1092 { "rdtsc", { XX
} },
1093 { "rdmsr", { XX
} },
1094 { "rdpmc", { XX
} },
1095 { "sysenter", { XX
} },
1096 { "sysexit", { XX
} },
1097 { "(bad)", { XX
} },
1098 { "(bad)", { XX
} },
1101 { "(bad)", { XX
} },
1103 { "(bad)", { XX
} },
1104 { "(bad)", { XX
} },
1105 { "(bad)", { XX
} },
1106 { "(bad)", { XX
} },
1107 { "(bad)", { XX
} },
1109 { "cmovo", { Gv
, Ev
} },
1110 { "cmovno", { Gv
, Ev
} },
1111 { "cmovb", { Gv
, Ev
} },
1112 { "cmovae", { Gv
, Ev
} },
1113 { "cmove", { Gv
, Ev
} },
1114 { "cmovne", { Gv
, Ev
} },
1115 { "cmovbe", { Gv
, Ev
} },
1116 { "cmova", { Gv
, Ev
} },
1118 { "cmovs", { Gv
, Ev
} },
1119 { "cmovns", { Gv
, Ev
} },
1120 { "cmovp", { Gv
, Ev
} },
1121 { "cmovnp", { Gv
, Ev
} },
1122 { "cmovl", { Gv
, Ev
} },
1123 { "cmovge", { Gv
, Ev
} },
1124 { "cmovle", { Gv
, Ev
} },
1125 { "cmovg", { Gv
, Ev
} },
1127 { "movmskpX", { Gdq
, XS
} },
1131 { "andpX", { XM
, EXx
} },
1132 { "andnpX", { XM
, EXx
} },
1133 { "orpX", { XM
, EXx
} },
1134 { "xorpX", { XM
, EXx
} },
1148 { "packsswb", { MX
, EM
} },
1149 { "pcmpgtb", { MX
, EM
} },
1150 { "pcmpgtw", { MX
, EM
} },
1151 { "pcmpgtd", { MX
, EM
} },
1152 { "packuswb", { MX
, EM
} },
1154 { "punpckhbw", { MX
, EM
} },
1155 { "punpckhwd", { MX
, EM
} },
1156 { "punpckhdq", { MX
, EM
} },
1157 { "packssdw", { MX
, EM
} },
1160 { "movd", { MX
, Edq
} },
1167 { "pcmpeqb", { MX
, EM
} },
1168 { "pcmpeqw", { MX
, EM
} },
1169 { "pcmpeqd", { MX
, EM
} },
1174 { "(bad)", { XX
} },
1175 { "(bad)", { XX
} },
1181 { "joH", { Jv
, XX
, cond_jump_flag
} },
1182 { "jnoH", { Jv
, XX
, cond_jump_flag
} },
1183 { "jbH", { Jv
, XX
, cond_jump_flag
} },
1184 { "jaeH", { Jv
, XX
, cond_jump_flag
} },
1185 { "jeH", { Jv
, XX
, cond_jump_flag
} },
1186 { "jneH", { Jv
, XX
, cond_jump_flag
} },
1187 { "jbeH", { Jv
, XX
, cond_jump_flag
} },
1188 { "jaH", { Jv
, XX
, cond_jump_flag
} },
1190 { "jsH", { Jv
, XX
, cond_jump_flag
} },
1191 { "jnsH", { Jv
, XX
, cond_jump_flag
} },
1192 { "jpH", { Jv
, XX
, cond_jump_flag
} },
1193 { "jnpH", { Jv
, XX
, cond_jump_flag
} },
1194 { "jlH", { Jv
, XX
, cond_jump_flag
} },
1195 { "jgeH", { Jv
, XX
, cond_jump_flag
} },
1196 { "jleH", { Jv
, XX
, cond_jump_flag
} },
1197 { "jgH", { Jv
, XX
, cond_jump_flag
} },
1200 { "setno", { Eb
} },
1202 { "setae", { Eb
} },
1204 { "setne", { Eb
} },
1205 { "setbe", { Eb
} },
1209 { "setns", { Eb
} },
1211 { "setnp", { Eb
} },
1213 { "setge", { Eb
} },
1214 { "setle", { Eb
} },
1217 { "pushT", { fs
} },
1219 { "cpuid", { XX
} },
1220 { "btS", { Ev
, Gv
} },
1221 { "shldS", { Ev
, Gv
, Ib
} },
1222 { "shldS", { Ev
, Gv
, CL
} },
1226 { "pushT", { gs
} },
1229 { "btsS", { Ev
, Gv
} },
1230 { "shrdS", { Ev
, Gv
, Ib
} },
1231 { "shrdS", { Ev
, Gv
, CL
} },
1233 { "imulS", { Gv
, Ev
} },
1235 { "cmpxchgB", { Eb
, Gb
} },
1236 { "cmpxchgS", { Ev
, Gv
} },
1237 { "lssS", { Gv
, Mp
} },
1238 { "btrS", { Ev
, Gv
} },
1239 { "lfsS", { Gv
, Mp
} },
1240 { "lgsS", { Gv
, Mp
} },
1241 { "movz{bR|x|bR|x}", { Gv
, Eb
} },
1242 { "movz{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movzww ! */
1247 { "btcS", { Ev
, Gv
} },
1248 { "bsfS", { Gv
, Ev
} },
1250 { "movs{bR|x|bR|x}", { Gv
, Eb
} },
1251 { "movs{wR|x|wR|x}", { Gv
, Ew
} }, /* yes, there really is movsww ! */
1253 { "xaddB", { Eb
, Gb
} },
1254 { "xaddS", { Ev
, Gv
} },
1256 { "movntiS", { Ev
, Gv
} },
1257 { "pinsrw", { MX
, Edqw
, Ib
} },
1258 { "pextrw", { Gdq
, MS
, Ib
} },
1259 { "shufpX", { XM
, EXx
, Ib
} },
1262 { "bswap", { RMeAX
} },
1263 { "bswap", { RMeCX
} },
1264 { "bswap", { RMeDX
} },
1265 { "bswap", { RMeBX
} },
1266 { "bswap", { RMeSP
} },
1267 { "bswap", { RMeBP
} },
1268 { "bswap", { RMeSI
} },
1269 { "bswap", { RMeDI
} },
1272 { "psrlw", { MX
, EM
} },
1273 { "psrld", { MX
, EM
} },
1274 { "psrlq", { MX
, EM
} },
1275 { "paddq", { MX
, EM
} },
1276 { "pmullw", { MX
, EM
} },
1278 { "pmovmskb", { Gdq
, MS
} },
1280 { "psubusb", { MX
, EM
} },
1281 { "psubusw", { MX
, EM
} },
1282 { "pminub", { MX
, EM
} },
1283 { "pand", { MX
, EM
} },
1284 { "paddusb", { MX
, EM
} },
1285 { "paddusw", { MX
, EM
} },
1286 { "pmaxub", { MX
, EM
} },
1287 { "pandn", { MX
, EM
} },
1289 { "pavgb", { MX
, EM
} },
1290 { "psraw", { MX
, EM
} },
1291 { "psrad", { MX
, EM
} },
1292 { "pavgw", { MX
, EM
} },
1293 { "pmulhuw", { MX
, EM
} },
1294 { "pmulhw", { MX
, EM
} },
1298 { "psubsb", { MX
, EM
} },
1299 { "psubsw", { MX
, EM
} },
1300 { "pminsw", { MX
, EM
} },
1301 { "por", { MX
, EM
} },
1302 { "paddsb", { MX
, EM
} },
1303 { "paddsw", { MX
, EM
} },
1304 { "pmaxsw", { MX
, EM
} },
1305 { "pxor", { MX
, EM
} },
1308 { "psllw", { MX
, EM
} },
1309 { "pslld", { MX
, EM
} },
1310 { "psllq", { MX
, EM
} },
1311 { "pmuludq", { MX
, EM
} },
1312 { "pmaddwd", { MX
, EM
} },
1313 { "psadbw", { MX
, EM
} },
1316 { "psubb", { MX
, EM
} },
1317 { "psubw", { MX
, EM
} },
1318 { "psubd", { MX
, EM
} },
1319 { "psubq", { MX
, EM
} },
1320 { "paddb", { MX
, EM
} },
1321 { "paddw", { MX
, EM
} },
1322 { "paddd", { MX
, EM
} },
1323 { "(bad)", { XX
} },
1326 static const unsigned char onebyte_has_modrm
[256] = {
1327 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1328 /* ------------------------------- */
1329 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1330 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1331 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1332 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1333 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1334 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1335 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1336 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1337 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1338 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1339 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1340 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1341 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1342 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1343 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1344 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1345 /* ------------------------------- */
1346 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1349 static const unsigned char twobyte_has_modrm
[256] = {
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1351 /* ------------------------------- */
1352 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1353 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1354 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1355 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1356 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1357 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1358 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1359 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1360 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1361 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1362 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1363 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1364 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1365 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1366 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1367 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1368 /* ------------------------------- */
1369 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1372 static const unsigned char twobyte_uses_DATA_prefix
[256] = {
1373 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1374 /* ------------------------------- */
1375 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1376 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1377 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1378 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1379 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1380 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1381 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1382 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1383 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1384 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1385 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1386 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1387 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1388 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1389 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1390 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1391 /* ------------------------------- */
1392 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1395 static const unsigned char twobyte_uses_REPNZ_prefix
[256] = {
1396 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1397 /* ------------------------------- */
1398 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1399 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1400 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1401 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1402 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1403 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1404 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1405 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1406 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1407 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1408 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1409 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1410 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1411 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1412 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1413 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1414 /* ------------------------------- */
1415 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1418 static const unsigned char twobyte_uses_REPZ_prefix
[256] = {
1419 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1420 /* ------------------------------- */
1421 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1422 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1423 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1424 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1425 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1426 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1427 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1428 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1429 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1430 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1431 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1432 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1433 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1434 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1435 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1436 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1437 /* ------------------------------- */
1438 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1441 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1442 static const unsigned char threebyte_0x38_uses_DATA_prefix
[256] = {
1443 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1444 /* ------------------------------- */
1445 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1446 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1447 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1448 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1449 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1450 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1451 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1452 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1453 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1454 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1455 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1456 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1457 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1458 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
1459 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1460 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1461 /* ------------------------------- */
1462 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1465 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1466 static const unsigned char threebyte_0x38_uses_REPNZ_prefix
[256] = {
1467 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1468 /* ------------------------------- */
1469 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1470 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1471 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1472 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1473 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1474 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1475 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1476 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1477 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1478 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1479 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1480 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1481 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1482 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1483 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1484 /* f0 */ 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1485 /* ------------------------------- */
1486 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1489 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1490 static const unsigned char threebyte_0x38_uses_REPZ_prefix
[256] = {
1491 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1492 /* ------------------------------- */
1493 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1494 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1495 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1496 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1497 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1498 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1499 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1500 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1501 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1502 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1503 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1504 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1505 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1506 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1507 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1508 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1509 /* ------------------------------- */
1510 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1513 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1514 static const unsigned char threebyte_0x3a_uses_DATA_prefix
[256] = {
1515 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1516 /* ------------------------------- */
1517 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1518 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1519 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1520 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1521 /* 40 */ 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1522 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1523 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1524 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1525 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1526 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1527 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1528 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1529 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1530 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* df */
1531 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1532 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1533 /* ------------------------------- */
1534 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1537 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1538 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix
[256] = {
1539 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1540 /* ------------------------------- */
1541 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1542 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1543 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1544 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1545 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1546 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1547 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1548 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1549 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1550 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1551 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1552 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1553 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1554 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1555 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1556 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1557 /* ------------------------------- */
1558 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1561 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1562 static const unsigned char threebyte_0x3a_uses_REPZ_prefix
[256] = {
1563 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1564 /* ------------------------------- */
1565 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1566 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1567 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1568 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1569 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1570 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1571 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1572 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1573 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1574 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1575 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1576 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1577 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1578 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1579 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1580 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1581 /* ------------------------------- */
1582 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1585 static char obuf
[100];
1587 static char scratchbuf
[100];
1588 static unsigned char *start_codep
;
1589 static unsigned char *insn_codep
;
1590 static unsigned char *codep
;
1591 static disassemble_info
*the_info
;
1599 static unsigned char need_modrm
;
1601 /* If we are accessing mod/rm/reg without need_modrm set, then the
1602 values are stale. Hitting this abort likely indicates that you
1603 need to update onebyte_has_modrm or twobyte_has_modrm. */
1604 #define MODRM_CHECK if (!need_modrm) abort ()
1606 static const char * const *names64
;
1607 static const char * const *names32
;
1608 static const char * const *names16
;
1609 static const char * const *names8
;
1610 static const char * const *names8rex
;
1611 static const char * const *names_seg
;
1612 static const char * const *index16
;
1614 static const char * const intel_names64
[] = {
1615 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1616 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1618 static const char * const intel_names32
[] = {
1619 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1620 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1622 static const char * const intel_names16
[] = {
1623 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1624 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1626 static const char * const intel_names8
[] = {
1627 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1629 static const char * const intel_names8rex
[] = {
1630 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1631 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1633 static const char * const intel_names_seg
[] = {
1634 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1636 static const char * const intel_index16
[] = {
1637 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1640 static const char * const att_names64
[] = {
1641 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1642 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1644 static const char * const att_names32
[] = {
1645 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1646 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1648 static const char * const att_names16
[] = {
1649 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1650 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1652 static const char * const att_names8
[] = {
1653 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1655 static const char * const att_names8rex
[] = {
1656 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1657 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1659 static const char * const att_names_seg
[] = {
1660 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1662 static const char * const att_index16
[] = {
1663 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1666 static const struct dis386 grps
[][8] = {
1669 { "popU", { stackEv
} },
1670 { "(bad)", { XX
} },
1671 { "(bad)", { XX
} },
1672 { "(bad)", { XX
} },
1673 { "(bad)", { XX
} },
1674 { "(bad)", { XX
} },
1675 { "(bad)", { XX
} },
1676 { "(bad)", { XX
} },
1680 { "addA", { Eb
, Ib
} },
1681 { "orA", { Eb
, Ib
} },
1682 { "adcA", { Eb
, Ib
} },
1683 { "sbbA", { Eb
, Ib
} },
1684 { "andA", { Eb
, Ib
} },
1685 { "subA", { Eb
, Ib
} },
1686 { "xorA", { Eb
, Ib
} },
1687 { "cmpA", { Eb
, Ib
} },
1691 { "addQ", { Ev
, Iv
} },
1692 { "orQ", { Ev
, Iv
} },
1693 { "adcQ", { Ev
, Iv
} },
1694 { "sbbQ", { Ev
, Iv
} },
1695 { "andQ", { Ev
, Iv
} },
1696 { "subQ", { Ev
, Iv
} },
1697 { "xorQ", { Ev
, Iv
} },
1698 { "cmpQ", { Ev
, Iv
} },
1702 { "addQ", { Ev
, sIb
} },
1703 { "orQ", { Ev
, sIb
} },
1704 { "adcQ", { Ev
, sIb
} },
1705 { "sbbQ", { Ev
, sIb
} },
1706 { "andQ", { Ev
, sIb
} },
1707 { "subQ", { Ev
, sIb
} },
1708 { "xorQ", { Ev
, sIb
} },
1709 { "cmpQ", { Ev
, sIb
} },
1713 { "rolA", { Eb
, Ib
} },
1714 { "rorA", { Eb
, Ib
} },
1715 { "rclA", { Eb
, Ib
} },
1716 { "rcrA", { Eb
, Ib
} },
1717 { "shlA", { Eb
, Ib
} },
1718 { "shrA", { Eb
, Ib
} },
1719 { "(bad)", { XX
} },
1720 { "sarA", { Eb
, Ib
} },
1724 { "rolQ", { Ev
, Ib
} },
1725 { "rorQ", { Ev
, Ib
} },
1726 { "rclQ", { Ev
, Ib
} },
1727 { "rcrQ", { Ev
, Ib
} },
1728 { "shlQ", { Ev
, Ib
} },
1729 { "shrQ", { Ev
, Ib
} },
1730 { "(bad)", { XX
} },
1731 { "sarQ", { Ev
, Ib
} },
1735 { "rolA", { Eb
, I1
} },
1736 { "rorA", { Eb
, I1
} },
1737 { "rclA", { Eb
, I1
} },
1738 { "rcrA", { Eb
, I1
} },
1739 { "shlA", { Eb
, I1
} },
1740 { "shrA", { Eb
, I1
} },
1741 { "(bad)", { XX
} },
1742 { "sarA", { Eb
, I1
} },
1746 { "rolQ", { Ev
, I1
} },
1747 { "rorQ", { Ev
, I1
} },
1748 { "rclQ", { Ev
, I1
} },
1749 { "rcrQ", { Ev
, I1
} },
1750 { "shlQ", { Ev
, I1
} },
1751 { "shrQ", { Ev
, I1
} },
1752 { "(bad)", { XX
} },
1753 { "sarQ", { Ev
, I1
} },
1757 { "rolA", { Eb
, CL
} },
1758 { "rorA", { Eb
, CL
} },
1759 { "rclA", { Eb
, CL
} },
1760 { "rcrA", { Eb
, CL
} },
1761 { "shlA", { Eb
, CL
} },
1762 { "shrA", { Eb
, CL
} },
1763 { "(bad)", { XX
} },
1764 { "sarA", { Eb
, CL
} },
1768 { "rolQ", { Ev
, CL
} },
1769 { "rorQ", { Ev
, CL
} },
1770 { "rclQ", { Ev
, CL
} },
1771 { "rcrQ", { Ev
, CL
} },
1772 { "shlQ", { Ev
, CL
} },
1773 { "shrQ", { Ev
, CL
} },
1774 { "(bad)", { XX
} },
1775 { "sarQ", { Ev
, CL
} },
1779 { "testA", { Eb
, Ib
} },
1780 { "(bad)", { Eb
} },
1783 { "mulA", { Eb
} }, /* Don't print the implicit %al register, */
1784 { "imulA", { Eb
} }, /* to distinguish these opcodes from other */
1785 { "divA", { Eb
} }, /* mul/imul opcodes. Do the same for div */
1786 { "idivA", { Eb
} }, /* and idiv for consistency. */
1790 { "testQ", { Ev
, Iv
} },
1791 { "(bad)", { XX
} },
1794 { "mulQ", { Ev
} }, /* Don't print the implicit register. */
1795 { "imulQ", { Ev
} },
1797 { "idivQ", { Ev
} },
1803 { "(bad)", { XX
} },
1804 { "(bad)", { XX
} },
1805 { "(bad)", { XX
} },
1806 { "(bad)", { XX
} },
1807 { "(bad)", { XX
} },
1808 { "(bad)", { XX
} },
1814 { "callT", { indirEv
} },
1815 { "JcallT", { indirEp
} },
1816 { "jmpT", { indirEv
} },
1817 { "JjmpT", { indirEp
} },
1818 { "pushU", { stackEv
} },
1819 { "(bad)", { XX
} },
1823 { "sldtD", { Sv
} },
1829 { "(bad)", { XX
} },
1830 { "(bad)", { XX
} },
1834 { "sgdt{Q|IQ||}", { { VMX_Fixup
, 0 } } },
1835 { "sidt{Q|IQ||}", { { PNI_Fixup
, 0 } } },
1836 { "lgdt{Q|Q||}", { M
} },
1837 { "lidt{Q|Q||}", { { SVME_Fixup
, 0 } } },
1838 { "smswD", { Sv
} },
1839 { "(bad)", { XX
} },
1841 { "invlpg", { { INVLPG_Fixup
, w_mode
} } },
1845 { "(bad)", { XX
} },
1846 { "(bad)", { XX
} },
1847 { "(bad)", { XX
} },
1848 { "(bad)", { XX
} },
1849 { "btQ", { Ev
, Ib
} },
1850 { "btsQ", { Ev
, Ib
} },
1851 { "btrQ", { Ev
, Ib
} },
1852 { "btcQ", { Ev
, Ib
} },
1856 { "(bad)", { XX
} },
1857 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} } },
1858 { "(bad)", { XX
} },
1859 { "(bad)", { XX
} },
1860 { "(bad)", { XX
} },
1861 { "(bad)", { XX
} },
1862 { "", { VM
} }, /* See OP_VMX. */
1863 { "vmptrst", { Mq
} },
1867 { "movA", { Eb
, Ib
} },
1868 { "(bad)", { XX
} },
1869 { "(bad)", { XX
} },
1870 { "(bad)", { XX
} },
1871 { "(bad)", { XX
} },
1872 { "(bad)", { XX
} },
1873 { "(bad)", { XX
} },
1874 { "(bad)", { XX
} },
1878 { "movQ", { Ev
, Iv
} },
1879 { "(bad)", { XX
} },
1880 { "(bad)", { XX
} },
1881 { "(bad)", { XX
} },
1882 { "(bad)", { XX
} },
1883 { "(bad)", { XX
} },
1884 { "(bad)", { XX
} },
1885 { "(bad)", { XX
} },
1889 { "(bad)", { XX
} },
1890 { "(bad)", { XX
} },
1891 { "psrlw", { MS
, Ib
} },
1892 { "(bad)", { XX
} },
1893 { "psraw", { MS
, Ib
} },
1894 { "(bad)", { XX
} },
1895 { "psllw", { MS
, Ib
} },
1896 { "(bad)", { XX
} },
1900 { "(bad)", { XX
} },
1901 { "(bad)", { XX
} },
1902 { "psrld", { MS
, Ib
} },
1903 { "(bad)", { XX
} },
1904 { "psrad", { MS
, Ib
} },
1905 { "(bad)", { XX
} },
1906 { "pslld", { MS
, Ib
} },
1907 { "(bad)", { XX
} },
1911 { "(bad)", { XX
} },
1912 { "(bad)", { XX
} },
1913 { "psrlq", { MS
, Ib
} },
1914 { "psrldq", { MS
, Ib
} },
1915 { "(bad)", { XX
} },
1916 { "(bad)", { XX
} },
1917 { "psllq", { MS
, Ib
} },
1918 { "pslldq", { MS
, Ib
} },
1922 { "fxsave", { Ev
} },
1923 { "fxrstor", { Ev
} },
1924 { "ldmxcsr", { Ev
} },
1925 { "stmxcsr", { Ev
} },
1926 { "(bad)", { XX
} },
1927 { "lfence", { { OP_0fae
, 0 } } },
1928 { "mfence", { { OP_0fae
, 0 } } },
1929 { "clflush", { { OP_0fae
, 0 } } },
1933 { "prefetchnta", { Ev
} },
1934 { "prefetcht0", { Ev
} },
1935 { "prefetcht1", { Ev
} },
1936 { "prefetcht2", { Ev
} },
1937 { "(bad)", { XX
} },
1938 { "(bad)", { XX
} },
1939 { "(bad)", { XX
} },
1940 { "(bad)", { XX
} },
1944 { "prefetch", { Eb
} },
1945 { "prefetchw", { Eb
} },
1946 { "(bad)", { XX
} },
1947 { "(bad)", { XX
} },
1948 { "(bad)", { XX
} },
1949 { "(bad)", { XX
} },
1950 { "(bad)", { XX
} },
1951 { "(bad)", { XX
} },
1955 { "xstore-rng", { { OP_0f07
, 0 } } },
1956 { "xcrypt-ecb", { { OP_0f07
, 0 } } },
1957 { "xcrypt-cbc", { { OP_0f07
, 0 } } },
1958 { "xcrypt-ctr", { { OP_0f07
, 0 } } },
1959 { "xcrypt-cfb", { { OP_0f07
, 0 } } },
1960 { "xcrypt-ofb", { { OP_0f07
, 0 } } },
1961 { "(bad)", { { OP_0f07
, 0 } } },
1962 { "(bad)", { { OP_0f07
, 0 } } },
1966 { "montmul", { { OP_0f07
, 0 } } },
1967 { "xsha1", { { OP_0f07
, 0 } } },
1968 { "xsha256", { { OP_0f07
, 0 } } },
1969 { "(bad)", { { OP_0f07
, 0 } } },
1970 { "(bad)", { { OP_0f07
, 0 } } },
1971 { "(bad)", { { OP_0f07
, 0 } } },
1972 { "(bad)", { { OP_0f07
, 0 } } },
1973 { "(bad)", { { OP_0f07
, 0 } } },
1977 static const struct dis386 prefix_user_table
[][4] = {
1980 { "addps", { XM
, EXx
} },
1981 { "addss", { XM
, EXd
} },
1982 { "addpd", { XM
, EXx
} },
1983 { "addsd", { XM
, EXq
} },
1987 { "", { XM
, EXx
, OPSIMD
} }, /* See OP_SIMD_SUFFIX. */
1988 { "", { XM
, EXx
, OPSIMD
} },
1989 { "", { XM
, EXx
, OPSIMD
} },
1990 { "", { XM
, EXx
, OPSIMD
} },
1994 { "cvtpi2ps", { XM
, EMC
} },
1995 { "cvtsi2ssY", { XM
, Ev
} },
1996 { "cvtpi2pd", { XM
, EMC
} },
1997 { "cvtsi2sdY", { XM
, Ev
} },
2001 { "cvtps2pi", { MXC
, EXx
} },
2002 { "cvtss2siY", { Gv
, EXx
} },
2003 { "cvtpd2pi", { MXC
, EXx
} },
2004 { "cvtsd2siY", { Gv
, EXx
} },
2008 { "cvttps2pi", { MXC
, EXx
} },
2009 { "cvttss2siY", { Gv
, EXx
} },
2010 { "cvttpd2pi", { MXC
, EXx
} },
2011 { "cvttsd2siY", { Gv
, EXx
} },
2015 { "divps", { XM
, EXx
} },
2016 { "divss", { XM
, EXx
} },
2017 { "divpd", { XM
, EXx
} },
2018 { "divsd", { XM
, EXx
} },
2022 { "maxps", { XM
, EXx
} },
2023 { "maxss", { XM
, EXx
} },
2024 { "maxpd", { XM
, EXx
} },
2025 { "maxsd", { XM
, EXx
} },
2029 { "minps", { XM
, EXx
} },
2030 { "minss", { XM
, EXx
} },
2031 { "minpd", { XM
, EXx
} },
2032 { "minsd", { XM
, EXx
} },
2036 { "movups", { XM
, EXx
} },
2037 { "movss", { XM
, EXx
} },
2038 { "movupd", { XM
, EXx
} },
2039 { "movsd", { XM
, EXx
} },
2043 { "movups", { EXx
, XM
} },
2044 { "movss", { EXx
, XM
} },
2045 { "movupd", { EXx
, XM
} },
2046 { "movsd", { EXx
, XM
} },
2050 { "mulps", { XM
, EXx
} },
2051 { "mulss", { XM
, EXx
} },
2052 { "mulpd", { XM
, EXx
} },
2053 { "mulsd", { XM
, EXx
} },
2057 { "rcpps", { XM
, EXx
} },
2058 { "rcpss", { XM
, EXx
} },
2059 { "(bad)", { XM
, EXx
} },
2060 { "(bad)", { XM
, EXx
} },
2064 { "rsqrtps",{ XM
, EXx
} },
2065 { "rsqrtss",{ XM
, EXx
} },
2066 { "(bad)", { XM
, EXx
} },
2067 { "(bad)", { XM
, EXx
} },
2071 { "sqrtps", { XM
, EXx
} },
2072 { "sqrtss", { XM
, EXx
} },
2073 { "sqrtpd", { XM
, EXx
} },
2074 { "sqrtsd", { XM
, EXx
} },
2078 { "subps", { XM
, EXx
} },
2079 { "subss", { XM
, EXx
} },
2080 { "subpd", { XM
, EXx
} },
2081 { "subsd", { XM
, EXx
} },
2085 { "(bad)", { XM
, EXx
} },
2086 { "cvtdq2pd", { XM
, EXq
} },
2087 { "cvttpd2dq", { XM
, EXx
} },
2088 { "cvtpd2dq", { XM
, EXx
} },
2092 { "cvtdq2ps", { XM
, EXx
} },
2093 { "cvttps2dq", { XM
, EXx
} },
2094 { "cvtps2dq", { XM
, EXx
} },
2095 { "(bad)", { XM
, EXx
} },
2099 { "cvtps2pd", { XM
, EXq
} },
2100 { "cvtss2sd", { XM
, EXx
} },
2101 { "cvtpd2ps", { XM
, EXx
} },
2102 { "cvtsd2ss", { XM
, EXx
} },
2106 { "maskmovq", { MX
, MS
} },
2107 { "(bad)", { XM
, EXx
} },
2108 { "maskmovdqu", { XM
, XS
} },
2109 { "(bad)", { XM
, EXx
} },
2113 { "movq", { MX
, EM
} },
2114 { "movdqu", { XM
, EXx
} },
2115 { "movdqa", { XM
, EXx
} },
2116 { "(bad)", { XM
, EXx
} },
2120 { "movq", { EM
, MX
} },
2121 { "movdqu", { EXx
, XM
} },
2122 { "movdqa", { EXx
, XM
} },
2123 { "(bad)", { EXx
, XM
} },
2127 { "(bad)", { EXx
, XM
} },
2128 { "movq2dq",{ XM
, MS
} },
2129 { "movq", { EXx
, XM
} },
2130 { "movdq2q",{ MX
, XS
} },
2134 { "pshufw", { MX
, EM
, Ib
} },
2135 { "pshufhw",{ XM
, EXx
, Ib
} },
2136 { "pshufd", { XM
, EXx
, Ib
} },
2137 { "pshuflw",{ XM
, EXx
, Ib
} },
2141 { "movd", { Edq
, MX
} },
2142 { "movq", { XM
, EXx
} },
2143 { "movd", { Edq
, XM
} },
2144 { "(bad)", { Ed
, XM
} },
2148 { "(bad)", { MX
, EXx
} },
2149 { "(bad)", { XM
, EXx
} },
2150 { "punpckhqdq", { XM
, EXx
} },
2151 { "(bad)", { XM
, EXx
} },
2155 { "movntq", { EM
, MX
} },
2156 { "(bad)", { EM
, XM
} },
2157 { "movntdq",{ EM
, XM
} },
2158 { "(bad)", { EM
, XM
} },
2162 { "(bad)", { MX
, EXx
} },
2163 { "(bad)", { XM
, EXx
} },
2164 { "punpcklqdq", { XM
, EXx
} },
2165 { "(bad)", { XM
, EXx
} },
2169 { "(bad)", { MX
, EXx
} },
2170 { "(bad)", { XM
, EXx
} },
2171 { "addsubpd", { XM
, EXx
} },
2172 { "addsubps", { XM
, EXx
} },
2176 { "(bad)", { MX
, EXx
} },
2177 { "(bad)", { XM
, EXx
} },
2178 { "haddpd", { XM
, EXx
} },
2179 { "haddps", { XM
, EXx
} },
2183 { "(bad)", { MX
, EXx
} },
2184 { "(bad)", { XM
, EXx
} },
2185 { "hsubpd", { XM
, EXx
} },
2186 { "hsubps", { XM
, EXx
} },
2190 { "movlpX", { XM
, EXq
, { SIMD_Fixup
, 'h' } } }, /* really only 2 operands */
2191 { "movsldup", { XM
, EXx
} },
2192 { "movlpd", { XM
, EXq
} },
2193 { "movddup", { XM
, EXq
} },
2197 { "movhpX", { XM
, EXq
, { SIMD_Fixup
, 'l' } } },
2198 { "movshdup", { XM
, EXx
} },
2199 { "movhpd", { XM
, EXq
} },
2200 { "(bad)", { XM
, EXq
} },
2204 { "(bad)", { XM
, EXx
} },
2205 { "(bad)", { XM
, EXx
} },
2206 { "(bad)", { XM
, EXx
} },
2207 { "lddqu", { XM
, M
} },
2211 {"movntps", { Ev
, XM
} },
2212 {"movntss", { Ev
, XM
} },
2213 {"movntpd", { Ev
, XM
} },
2214 {"movntsd", { Ev
, XM
} },
2219 {"vmread", { Em
, Gm
} },
2221 {"extrq", { XS
, Ib
, Ib
} },
2222 {"insertq", { XM
, XS
, Ib
, Ib
} },
2227 {"vmwrite", { Gm
, Em
} },
2229 {"extrq", { XM
, XS
} },
2230 {"insertq", { XM
, XS
} },
2235 { "bsrS", { Gv
, Ev
} },
2236 { "lzcntS", { Gv
, Ev
} },
2237 { "bsrS", { Gv
, Ev
} },
2238 { "(bad)", { XX
} },
2243 { "(bad)", { XX
} },
2244 { "popcntS", { Gv
, Ev
} },
2245 { "(bad)", { XX
} },
2246 { "(bad)", { XX
} },
2251 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2252 { "pause", { XX
} },
2253 { "xchgS", { { NOP_Fixup1
, eAX_reg
}, { NOP_Fixup2
, eAX_reg
} } },
2254 { "(bad)", { XX
} },
2259 { "(bad)", { XX
} },
2260 { "(bad)", { XX
} },
2261 { "pblendvb", {XM
, EXx
, XMM0
} },
2262 { "(bad)", { XX
} },
2267 { "(bad)", { XX
} },
2268 { "(bad)", { XX
} },
2269 { "blendvps", {XM
, EXx
, XMM0
} },
2270 { "(bad)", { XX
} },
2275 { "(bad)", { XX
} },
2276 { "(bad)", { XX
} },
2277 { "blendvpd", { XM
, EXx
, XMM0
} },
2278 { "(bad)", { XX
} },
2283 { "(bad)", { XX
} },
2284 { "(bad)", { XX
} },
2285 { "ptest", { XM
, EXx
} },
2286 { "(bad)", { XX
} },
2291 { "(bad)", { XX
} },
2292 { "(bad)", { XX
} },
2293 { "pmovsxbw", { XM
, EXx
} },
2294 { "(bad)", { XX
} },
2299 { "(bad)", { XX
} },
2300 { "(bad)", { XX
} },
2301 { "pmovsxbd", { XM
, EXx
} },
2302 { "(bad)", { XX
} },
2307 { "(bad)", { XX
} },
2308 { "(bad)", { XX
} },
2309 { "pmovsxbq", { XM
, EXx
} },
2310 { "(bad)", { XX
} },
2315 { "(bad)", { XX
} },
2316 { "(bad)", { XX
} },
2317 { "pmovsxwd", { XM
, EXx
} },
2318 { "(bad)", { XX
} },
2323 { "(bad)", { XX
} },
2324 { "(bad)", { XX
} },
2325 { "pmovsxwq", { XM
, EXx
} },
2326 { "(bad)", { XX
} },
2331 { "(bad)", { XX
} },
2332 { "(bad)", { XX
} },
2333 { "pmovsxdq", { XM
, EXx
} },
2334 { "(bad)", { XX
} },
2339 { "(bad)", { XX
} },
2340 { "(bad)", { XX
} },
2341 { "pmuldq", { XM
, EXx
} },
2342 { "(bad)", { XX
} },
2347 { "(bad)", { XX
} },
2348 { "(bad)", { XX
} },
2349 { "pcmpeqq", { XM
, EXx
} },
2350 { "(bad)", { XX
} },
2355 { "(bad)", { XX
} },
2356 { "(bad)", { XX
} },
2357 { "movntdqa", { XM
, EM
} },
2358 { "(bad)", { XX
} },
2363 { "(bad)", { XX
} },
2364 { "(bad)", { XX
} },
2365 { "packusdw", { XM
, EXx
} },
2366 { "(bad)", { XX
} },
2371 { "(bad)", { XX
} },
2372 { "(bad)", { XX
} },
2373 { "pmovzxbw", { XM
, EXx
} },
2374 { "(bad)", { XX
} },
2379 { "(bad)", { XX
} },
2380 { "(bad)", { XX
} },
2381 { "pmovzxbd", { XM
, EXx
} },
2382 { "(bad)", { XX
} },
2387 { "(bad)", { XX
} },
2388 { "(bad)", { XX
} },
2389 { "pmovzxbq", { XM
, EXx
} },
2390 { "(bad)", { XX
} },
2395 { "(bad)", { XX
} },
2396 { "(bad)", { XX
} },
2397 { "pmovzxwd", { XM
, EXx
} },
2398 { "(bad)", { XX
} },
2403 { "(bad)", { XX
} },
2404 { "(bad)", { XX
} },
2405 { "pmovzxwq", { XM
, EXx
} },
2406 { "(bad)", { XX
} },
2411 { "(bad)", { XX
} },
2412 { "(bad)", { XX
} },
2413 { "pmovzxdq", { XM
, EXx
} },
2414 { "(bad)", { XX
} },
2419 { "(bad)", { XX
} },
2420 { "(bad)", { XX
} },
2421 { "pminsb", { XM
, EXx
} },
2422 { "(bad)", { XX
} },
2427 { "(bad)", { XX
} },
2428 { "(bad)", { XX
} },
2429 { "pminsd", { XM
, EXx
} },
2430 { "(bad)", { XX
} },
2435 { "(bad)", { XX
} },
2436 { "(bad)", { XX
} },
2437 { "pminuw", { XM
, EXx
} },
2438 { "(bad)", { XX
} },
2443 { "(bad)", { XX
} },
2444 { "(bad)", { XX
} },
2445 { "pminud", { XM
, EXx
} },
2446 { "(bad)", { XX
} },
2451 { "(bad)", { XX
} },
2452 { "(bad)", { XX
} },
2453 { "pmaxsb", { XM
, EXx
} },
2454 { "(bad)", { XX
} },
2459 { "(bad)", { XX
} },
2460 { "(bad)", { XX
} },
2461 { "pmaxsd", { XM
, EXx
} },
2462 { "(bad)", { XX
} },
2467 { "(bad)", { XX
} },
2468 { "(bad)", { XX
} },
2469 { "pmaxuw", { XM
, EXx
} },
2470 { "(bad)", { XX
} },
2475 { "(bad)", { XX
} },
2476 { "(bad)", { XX
} },
2477 { "pmaxud", { XM
, EXx
} },
2478 { "(bad)", { XX
} },
2483 { "(bad)", { XX
} },
2484 { "(bad)", { XX
} },
2485 { "pmulld", { XM
, EXx
} },
2486 { "(bad)", { XX
} },
2491 { "(bad)", { XX
} },
2492 { "(bad)", { XX
} },
2493 { "phminposuw", { XM
, EXx
} },
2494 { "(bad)", { XX
} },
2499 { "(bad)", { XX
} },
2500 { "(bad)", { XX
} },
2501 { "roundps", { XM
, EXx
, Ib
} },
2502 { "(bad)", { XX
} },
2507 { "(bad)", { XX
} },
2508 { "(bad)", { XX
} },
2509 { "roundpd", { XM
, EXx
, Ib
} },
2510 { "(bad)", { XX
} },
2515 { "(bad)", { XX
} },
2516 { "(bad)", { XX
} },
2517 { "roundss", { XM
, EXx
, Ib
} },
2518 { "(bad)", { XX
} },
2523 { "(bad)", { XX
} },
2524 { "(bad)", { XX
} },
2525 { "roundsd", { XM
, EXx
, Ib
} },
2526 { "(bad)", { XX
} },
2531 { "(bad)", { XX
} },
2532 { "(bad)", { XX
} },
2533 { "blendps", { XM
, EXx
, Ib
} },
2534 { "(bad)", { XX
} },
2539 { "(bad)", { XX
} },
2540 { "(bad)", { XX
} },
2541 { "blendpd", { XM
, EXx
, Ib
} },
2542 { "(bad)", { XX
} },
2547 { "(bad)", { XX
} },
2548 { "(bad)", { XX
} },
2549 { "pblendw", { XM
, EXx
, Ib
} },
2550 { "(bad)", { XX
} },
2555 { "(bad)", { XX
} },
2556 { "(bad)", { XX
} },
2557 { "pextrb", { Edqb
, XM
, Ib
} },
2558 { "(bad)", { XX
} },
2563 { "(bad)", { XX
} },
2564 { "(bad)", { XX
} },
2565 { "pextrw", { Edqw
, XM
, Ib
} },
2566 { "(bad)", { XX
} },
2571 { "(bad)", { XX
} },
2572 { "(bad)", { XX
} },
2573 { "pextrK", { Edq
, XM
, Ib
} },
2574 { "(bad)", { XX
} },
2579 { "(bad)", { XX
} },
2580 { "(bad)", { XX
} },
2581 { "extractps", { Edqd
, XM
, Ib
} },
2582 { "(bad)", { XX
} },
2587 { "(bad)", { XX
} },
2588 { "(bad)", { XX
} },
2589 { "pinsrb", { XM
, Edqb
, Ib
} },
2590 { "(bad)", { XX
} },
2595 { "(bad)", { XX
} },
2596 { "(bad)", { XX
} },
2597 { "insertps", { XM
, EXx
, Ib
} },
2598 { "(bad)", { XX
} },
2603 { "(bad)", { XX
} },
2604 { "(bad)", { XX
} },
2605 { "pinsrK", { XM
, Edq
, Ib
} },
2606 { "(bad)", { XX
} },
2611 { "(bad)", { XX
} },
2612 { "(bad)", { XX
} },
2613 { "dpps", { XM
, EXx
, Ib
} },
2614 { "(bad)", { XX
} },
2619 { "(bad)", { XX
} },
2620 { "(bad)", { XX
} },
2621 { "dppd", { XM
, EXx
, Ib
} },
2622 { "(bad)", { XX
} },
2627 { "(bad)", { XX
} },
2628 { "(bad)", { XX
} },
2629 { "mpsadbw", { XM
, EXx
, Ib
} },
2630 { "(bad)", { XX
} },
2635 { "(bad)", { XX
} },
2636 { "(bad)", { XX
} },
2637 { "pcmpgtq", { XM
, EXx
} },
2638 { "(bad)", { XX
} },
2643 { "movbe", { Gv
, Ev
} },
2644 { "(bad)", { XX
} },
2645 { "movbe", { Gv
, Ev
} },
2646 { "crc32", { Gdq
, { CRC32_Fixup
, b_mode
} } },
2651 { "movbe", { Ev
, Gv
} },
2652 { "(bad)", { XX
} },
2653 { "movbe", { Ev
, Gv
} },
2654 { "crc32", { Gdq
, { CRC32_Fixup
, v_mode
} } },
2659 { "(bad)", { XX
} },
2660 { "(bad)", { XX
} },
2661 { "pcmpestrm", { XM
, EXx
, Ib
} },
2662 { "(bad)", { XX
} },
2667 { "(bad)", { XX
} },
2668 { "(bad)", { XX
} },
2669 { "pcmpestri", { XM
, EXx
, Ib
} },
2670 { "(bad)", { XX
} },
2675 { "(bad)", { XX
} },
2676 { "(bad)", { XX
} },
2677 { "pcmpistrm", { XM
, EXx
, Ib
} },
2678 { "(bad)", { XX
} },
2683 { "(bad)", { XX
} },
2684 { "(bad)", { XX
} },
2685 { "pcmpistri", { XM
, EXx
, Ib
} },
2686 { "(bad)", { XX
} },
2691 { "ucomiss",{ XM
, EXd
} },
2692 { "(bad)", { XX
} },
2693 { "ucomisd",{ XM
, EXq
} },
2694 { "(bad)", { XX
} },
2699 { "comiss", { XM
, EXd
} },
2700 { "(bad)", { XX
} },
2701 { "comisd", { XM
, EXq
} },
2702 { "(bad)", { XX
} },
2707 { "punpcklbw",{ MX
, EMd
} },
2708 { "(bad)", { XX
} },
2709 { "punpcklbw",{ MX
, EMq
} },
2710 { "(bad)", { XX
} },
2715 { "punpcklwd",{ MX
, EMd
} },
2716 { "(bad)", { XX
} },
2717 { "punpcklwd",{ MX
, EMq
} },
2718 { "(bad)", { XX
} },
2723 { "punpckldq",{ MX
, EMd
} },
2724 { "(bad)", { XX
} },
2725 { "punpckldq",{ MX
, EMq
} },
2726 { "(bad)", { XX
} },
2731 { "(bad)", { XX
} },
2732 { "(bad)", { XX
} },
2733 { "pclmulqdq", { XM
, EXx
, Ib
} },
2734 { "(bad)", { XX
} },
2739 { "(bad)", { XX
} },
2740 { "(bad)", { XX
} },
2741 { "aesimc", { XM
, EXx
} },
2742 { "(bad)", { XX
} },
2747 { "(bad)", { XX
} },
2748 { "(bad)", { XX
} },
2749 { "aesenc", { XM
, EXx
} },
2750 { "(bad)", { XX
} },
2755 { "(bad)", { XX
} },
2756 { "(bad)", { XX
} },
2757 { "aesenclast", { XM
, EXx
} },
2758 { "(bad)", { XX
} },
2763 { "(bad)", { XX
} },
2764 { "(bad)", { XX
} },
2765 { "aesdec", { XM
, EXx
} },
2766 { "(bad)", { XX
} },
2771 { "(bad)", { XX
} },
2772 { "(bad)", { XX
} },
2773 { "aesdeclast", { XM
, EXx
} },
2774 { "(bad)", { XX
} },
2779 { "(bad)", { XX
} },
2780 { "(bad)", { XX
} },
2781 { "aeskeygenassist", { XM
, EXx
, Ib
} },
2782 { "(bad)", { XX
} },
2787 { "andnS", { Gv
, Bv
, Ev
} },
2788 { "(bad)", { XX
} },
2789 { "(bad)", { XX
} },
2790 { "(bad)", { XX
} },
2795 { "bextrS", { Gv
, Ev
, Bv
} },
2796 { "sarxS", { Gv
, Ev
, Bv
} },
2797 { "shlxS", { Gv
, Ev
, Bv
} },
2798 { "shrxS", { Gv
, Ev
, Bv
} },
2803 static const struct dis386 x86_64_table
[][2] = {
2805 { "pusha{P|}", { XX
} },
2806 { "(bad)", { XX
} },
2809 { "popa{P|}", { XX
} },
2810 { "(bad)", { XX
} },
2813 { "bound{S|}", { Gv
, Ma
} },
2814 { "(bad)", { XX
} },
2817 { "arpl", { Ew
, Gw
} },
2818 { "movs{||lq|xd}", { Gv
, Ed
} },
2822 static const struct dis386 three_byte_table
[][256] = {
2826 { "pshufb", { MX
, EM
} },
2827 { "phaddw", { MX
, EM
} },
2828 { "phaddd", { MX
, EM
} },
2829 { "phaddsw", { MX
, EM
} },
2830 { "pmaddubsw", { MX
, EM
} },
2831 { "phsubw", { MX
, EM
} },
2832 { "phsubd", { MX
, EM
} },
2833 { "phsubsw", { MX
, EM
} },
2835 { "psignb", { MX
, EM
} },
2836 { "psignw", { MX
, EM
} },
2837 { "psignd", { MX
, EM
} },
2838 { "pmulhrsw", { MX
, EM
} },
2839 { "(bad)", { XX
} },
2840 { "(bad)", { XX
} },
2841 { "(bad)", { XX
} },
2842 { "(bad)", { XX
} },
2845 { "(bad)", { XX
} },
2846 { "(bad)", { XX
} },
2847 { "(bad)", { XX
} },
2850 { "(bad)", { XX
} },
2853 { "(bad)", { XX
} },
2854 { "(bad)", { XX
} },
2855 { "(bad)", { XX
} },
2856 { "(bad)", { XX
} },
2857 { "pabsb", { MX
, EM
} },
2858 { "pabsw", { MX
, EM
} },
2859 { "pabsd", { MX
, EM
} },
2860 { "(bad)", { XX
} },
2868 { "(bad)", { XX
} },
2869 { "(bad)", { XX
} },
2875 { "(bad)", { XX
} },
2876 { "(bad)", { XX
} },
2877 { "(bad)", { XX
} },
2878 { "(bad)", { XX
} },
2886 { "(bad)", { XX
} },
2900 { "(bad)", { XX
} },
2901 { "(bad)", { XX
} },
2902 { "(bad)", { XX
} },
2903 { "(bad)", { XX
} },
2904 { "(bad)", { XX
} },
2905 { "(bad)", { XX
} },
2907 { "(bad)", { XX
} },
2908 { "(bad)", { XX
} },
2909 { "(bad)", { XX
} },
2910 { "(bad)", { XX
} },
2911 { "(bad)", { XX
} },
2912 { "(bad)", { XX
} },
2913 { "(bad)", { XX
} },
2914 { "(bad)", { XX
} },
2916 { "(bad)", { XX
} },
2917 { "(bad)", { XX
} },
2918 { "(bad)", { XX
} },
2919 { "(bad)", { XX
} },
2920 { "(bad)", { XX
} },
2921 { "(bad)", { XX
} },
2922 { "(bad)", { XX
} },
2923 { "(bad)", { XX
} },
2925 { "(bad)", { XX
} },
2926 { "(bad)", { XX
} },
2927 { "(bad)", { XX
} },
2928 { "(bad)", { XX
} },
2929 { "(bad)", { XX
} },
2930 { "(bad)", { XX
} },
2931 { "(bad)", { XX
} },
2932 { "(bad)", { XX
} },
2934 { "(bad)", { XX
} },
2935 { "(bad)", { XX
} },
2936 { "(bad)", { XX
} },
2937 { "(bad)", { XX
} },
2938 { "(bad)", { XX
} },
2939 { "(bad)", { XX
} },
2940 { "(bad)", { XX
} },
2941 { "(bad)", { XX
} },
2943 { "(bad)", { XX
} },
2944 { "(bad)", { XX
} },
2945 { "(bad)", { XX
} },
2946 { "(bad)", { XX
} },
2947 { "(bad)", { XX
} },
2948 { "(bad)", { XX
} },
2949 { "(bad)", { XX
} },
2950 { "(bad)", { XX
} },
2952 { "(bad)", { XX
} },
2953 { "(bad)", { XX
} },
2954 { "(bad)", { XX
} },
2955 { "(bad)", { XX
} },
2956 { "(bad)", { XX
} },
2957 { "(bad)", { XX
} },
2958 { "(bad)", { XX
} },
2959 { "(bad)", { XX
} },
2961 { "(bad)", { XX
} },
2962 { "(bad)", { XX
} },
2963 { "(bad)", { XX
} },
2964 { "(bad)", { XX
} },
2965 { "(bad)", { XX
} },
2966 { "(bad)", { XX
} },
2967 { "(bad)", { XX
} },
2968 { "(bad)", { XX
} },
2970 { "(bad)", { XX
} },
2971 { "(bad)", { XX
} },
2972 { "(bad)", { XX
} },
2973 { "(bad)", { XX
} },
2974 { "(bad)", { XX
} },
2975 { "(bad)", { XX
} },
2976 { "(bad)", { XX
} },
2977 { "(bad)", { XX
} },
2979 { "(bad)", { XX
} },
2980 { "(bad)", { XX
} },
2981 { "(bad)", { XX
} },
2982 { "(bad)", { XX
} },
2983 { "(bad)", { XX
} },
2984 { "(bad)", { XX
} },
2985 { "(bad)", { XX
} },
2986 { "(bad)", { XX
} },
2988 { "(bad)", { XX
} },
2989 { "(bad)", { XX
} },
2990 { "(bad)", { XX
} },
2991 { "(bad)", { XX
} },
2992 { "(bad)", { XX
} },
2993 { "(bad)", { XX
} },
2994 { "(bad)", { XX
} },
2995 { "(bad)", { XX
} },
2997 { "(bad)", { XX
} },
2998 { "(bad)", { XX
} },
2999 { "(bad)", { XX
} },
3000 { "(bad)", { XX
} },
3001 { "(bad)", { XX
} },
3002 { "(bad)", { XX
} },
3003 { "(bad)", { XX
} },
3004 { "(bad)", { XX
} },
3006 { "(bad)", { XX
} },
3007 { "(bad)", { XX
} },
3008 { "(bad)", { XX
} },
3009 { "(bad)", { XX
} },
3010 { "(bad)", { XX
} },
3011 { "(bad)", { XX
} },
3012 { "(bad)", { XX
} },
3013 { "(bad)", { XX
} },
3015 { "(bad)", { XX
} },
3016 { "(bad)", { XX
} },
3017 { "(bad)", { XX
} },
3018 { "(bad)", { XX
} },
3019 { "(bad)", { XX
} },
3020 { "(bad)", { XX
} },
3021 { "(bad)", { XX
} },
3022 { "(bad)", { XX
} },
3024 { "(bad)", { XX
} },
3025 { "(bad)", { XX
} },
3026 { "(bad)", { XX
} },
3027 { "(bad)", { XX
} },
3028 { "(bad)", { XX
} },
3029 { "(bad)", { XX
} },
3030 { "(bad)", { XX
} },
3031 { "(bad)", { XX
} },
3033 { "(bad)", { XX
} },
3034 { "(bad)", { XX
} },
3035 { "(bad)", { XX
} },
3036 { "(bad)", { XX
} },
3037 { "(bad)", { XX
} },
3038 { "(bad)", { XX
} },
3039 { "(bad)", { XX
} },
3040 { "(bad)", { XX
} },
3042 { "(bad)", { XX
} },
3043 { "(bad)", { XX
} },
3044 { "(bad)", { XX
} },
3045 { "(bad)", { XX
} },
3046 { "(bad)", { XX
} },
3047 { "(bad)", { XX
} },
3048 { "(bad)", { XX
} },
3049 { "(bad)", { XX
} },
3051 { "(bad)", { XX
} },
3052 { "(bad)", { XX
} },
3053 { "(bad)", { XX
} },
3054 { "(bad)", { XX
} },
3055 { "(bad)", { XX
} },
3056 { "(bad)", { XX
} },
3057 { "(bad)", { XX
} },
3058 { "(bad)", { XX
} },
3060 { "(bad)", { XX
} },
3061 { "(bad)", { XX
} },
3062 { "(bad)", { XX
} },
3063 { "(bad)", { XX
} },
3064 { "(bad)", { XX
} },
3065 { "(bad)", { XX
} },
3066 { "(bad)", { XX
} },
3067 { "(bad)", { XX
} },
3069 { "(bad)", { XX
} },
3070 { "(bad)", { XX
} },
3071 { "(bad)", { XX
} },
3078 { "(bad)", { XX
} },
3079 { "(bad)", { XX
} },
3080 { "(bad)", { XX
} },
3081 { "(bad)", { XX
} },
3082 { "(bad)", { XX
} },
3083 { "(bad)", { XX
} },
3084 { "(bad)", { XX
} },
3085 { "(bad)", { XX
} },
3087 { "(bad)", { XX
} },
3088 { "(bad)", { XX
} },
3089 { "(bad)", { XX
} },
3090 { "(bad)", { XX
} },
3091 { "(bad)", { XX
} },
3092 { "(bad)", { XX
} },
3093 { "(bad)", { XX
} },
3094 { "(bad)", { XX
} },
3099 { "(bad)", { XX
} },
3100 { "(bad)", { XX
} },
3101 { "(bad)", { XX
} },
3102 { "(bad)", { XX
} },
3105 { "(bad)", { XX
} },
3106 { "(bad)", { XX
} },
3107 { "(bad)", { XX
} },
3108 { "(bad)", { XX
} },
3109 { "(bad)", { XX
} },
3110 { "(bad)", { XX
} },
3111 { "(bad)", { XX
} },
3112 { "(bad)", { XX
} },
3117 { "(bad)", { XX
} },
3118 { "(bad)", { XX
} },
3119 { "(bad)", { XX
} },
3120 { "(bad)", { XX
} },
3121 { "(bad)", { XX
} },
3122 { "(bad)", { XX
} },
3123 { "(bad)", { XX
} },
3124 { "(bad)", { XX
} },
3133 { "palignr", { MX
, EM
, Ib
} },
3135 { "(bad)", { XX
} },
3136 { "(bad)", { XX
} },
3137 { "(bad)", { XX
} },
3138 { "(bad)", { XX
} },
3144 { "(bad)", { XX
} },
3145 { "(bad)", { XX
} },
3146 { "(bad)", { XX
} },
3147 { "(bad)", { XX
} },
3148 { "(bad)", { XX
} },
3149 { "(bad)", { XX
} },
3150 { "(bad)", { XX
} },
3151 { "(bad)", { XX
} },
3156 { "(bad)", { XX
} },
3157 { "(bad)", { XX
} },
3158 { "(bad)", { XX
} },
3159 { "(bad)", { XX
} },
3160 { "(bad)", { XX
} },
3162 { "(bad)", { XX
} },
3163 { "(bad)", { XX
} },
3164 { "(bad)", { XX
} },
3165 { "(bad)", { XX
} },
3166 { "(bad)", { XX
} },
3167 { "(bad)", { XX
} },
3168 { "(bad)", { XX
} },
3169 { "(bad)", { XX
} },
3171 { "(bad)", { XX
} },
3172 { "(bad)", { XX
} },
3173 { "(bad)", { XX
} },
3174 { "(bad)", { XX
} },
3175 { "(bad)", { XX
} },
3176 { "(bad)", { XX
} },
3177 { "(bad)", { XX
} },
3178 { "(bad)", { XX
} },
3180 { "(bad)", { XX
} },
3181 { "(bad)", { XX
} },
3182 { "(bad)", { XX
} },
3183 { "(bad)", { XX
} },
3184 { "(bad)", { XX
} },
3185 { "(bad)", { XX
} },
3186 { "(bad)", { XX
} },
3187 { "(bad)", { XX
} },
3192 { "(bad)", { XX
} },
3194 { "(bad)", { XX
} },
3195 { "(bad)", { XX
} },
3196 { "(bad)", { XX
} },
3198 { "(bad)", { XX
} },
3199 { "(bad)", { XX
} },
3200 { "(bad)", { XX
} },
3201 { "(bad)", { XX
} },
3202 { "(bad)", { XX
} },
3203 { "(bad)", { XX
} },
3204 { "(bad)", { XX
} },
3205 { "(bad)", { XX
} },
3207 { "(bad)", { XX
} },
3208 { "(bad)", { XX
} },
3209 { "(bad)", { XX
} },
3210 { "(bad)", { XX
} },
3211 { "(bad)", { XX
} },
3212 { "(bad)", { XX
} },
3213 { "(bad)", { XX
} },
3214 { "(bad)", { XX
} },
3216 { "(bad)", { XX
} },
3217 { "(bad)", { XX
} },
3218 { "(bad)", { XX
} },
3219 { "(bad)", { XX
} },
3220 { "(bad)", { XX
} },
3221 { "(bad)", { XX
} },
3222 { "(bad)", { XX
} },
3223 { "(bad)", { XX
} },
3229 { "(bad)", { XX
} },
3230 { "(bad)", { XX
} },
3231 { "(bad)", { XX
} },
3232 { "(bad)", { XX
} },
3234 { "(bad)", { XX
} },
3235 { "(bad)", { XX
} },
3236 { "(bad)", { XX
} },
3237 { "(bad)", { XX
} },
3238 { "(bad)", { XX
} },
3239 { "(bad)", { XX
} },
3240 { "(bad)", { XX
} },
3241 { "(bad)", { XX
} },
3243 { "(bad)", { XX
} },
3244 { "(bad)", { XX
} },
3245 { "(bad)", { XX
} },
3246 { "(bad)", { XX
} },
3247 { "(bad)", { XX
} },
3248 { "(bad)", { XX
} },
3249 { "(bad)", { XX
} },
3250 { "(bad)", { XX
} },
3252 { "(bad)", { XX
} },
3253 { "(bad)", { XX
} },
3254 { "(bad)", { XX
} },
3255 { "(bad)", { XX
} },
3256 { "(bad)", { XX
} },
3257 { "(bad)", { XX
} },
3258 { "(bad)", { XX
} },
3259 { "(bad)", { XX
} },
3261 { "(bad)", { XX
} },
3262 { "(bad)", { XX
} },
3263 { "(bad)", { XX
} },
3264 { "(bad)", { XX
} },
3265 { "(bad)", { XX
} },
3266 { "(bad)", { XX
} },
3267 { "(bad)", { XX
} },
3268 { "(bad)", { XX
} },
3270 { "(bad)", { XX
} },
3271 { "(bad)", { XX
} },
3272 { "(bad)", { XX
} },
3273 { "(bad)", { XX
} },
3274 { "(bad)", { XX
} },
3275 { "(bad)", { XX
} },
3276 { "(bad)", { XX
} },
3277 { "(bad)", { XX
} },
3279 { "(bad)", { XX
} },
3280 { "(bad)", { XX
} },
3281 { "(bad)", { XX
} },
3282 { "(bad)", { XX
} },
3283 { "(bad)", { XX
} },
3284 { "(bad)", { XX
} },
3285 { "(bad)", { XX
} },
3286 { "(bad)", { XX
} },
3288 { "(bad)", { XX
} },
3289 { "(bad)", { XX
} },
3290 { "(bad)", { XX
} },
3291 { "(bad)", { XX
} },
3292 { "(bad)", { XX
} },
3293 { "(bad)", { XX
} },
3294 { "(bad)", { XX
} },
3295 { "(bad)", { XX
} },
3297 { "(bad)", { XX
} },
3298 { "(bad)", { XX
} },
3299 { "(bad)", { XX
} },
3300 { "(bad)", { XX
} },
3301 { "(bad)", { XX
} },
3302 { "(bad)", { XX
} },
3303 { "(bad)", { XX
} },
3304 { "(bad)", { XX
} },
3306 { "(bad)", { XX
} },
3307 { "(bad)", { XX
} },
3308 { "(bad)", { XX
} },
3309 { "(bad)", { XX
} },
3310 { "(bad)", { XX
} },
3311 { "(bad)", { XX
} },
3312 { "(bad)", { XX
} },
3313 { "(bad)", { XX
} },
3315 { "(bad)", { XX
} },
3316 { "(bad)", { XX
} },
3317 { "(bad)", { XX
} },
3318 { "(bad)", { XX
} },
3319 { "(bad)", { XX
} },
3320 { "(bad)", { XX
} },
3321 { "(bad)", { XX
} },
3322 { "(bad)", { XX
} },
3324 { "(bad)", { XX
} },
3325 { "(bad)", { XX
} },
3326 { "(bad)", { XX
} },
3327 { "(bad)", { XX
} },
3328 { "(bad)", { XX
} },
3329 { "(bad)", { XX
} },
3330 { "(bad)", { XX
} },
3331 { "(bad)", { XX
} },
3333 { "(bad)", { XX
} },
3334 { "(bad)", { XX
} },
3335 { "(bad)", { XX
} },
3336 { "(bad)", { XX
} },
3337 { "(bad)", { XX
} },
3338 { "(bad)", { XX
} },
3339 { "(bad)", { XX
} },
3340 { "(bad)", { XX
} },
3342 { "(bad)", { XX
} },
3343 { "(bad)", { XX
} },
3344 { "(bad)", { XX
} },
3345 { "(bad)", { XX
} },
3346 { "(bad)", { XX
} },
3347 { "(bad)", { XX
} },
3348 { "(bad)", { XX
} },
3349 { "(bad)", { XX
} },
3351 { "(bad)", { XX
} },
3352 { "(bad)", { XX
} },
3353 { "(bad)", { XX
} },
3354 { "(bad)", { XX
} },
3355 { "(bad)", { XX
} },
3356 { "(bad)", { XX
} },
3357 { "(bad)", { XX
} },
3358 { "(bad)", { XX
} },
3360 { "(bad)", { XX
} },
3361 { "(bad)", { XX
} },
3362 { "(bad)", { XX
} },
3363 { "(bad)", { XX
} },
3364 { "(bad)", { XX
} },
3365 { "(bad)", { XX
} },
3366 { "(bad)", { XX
} },
3369 { "(bad)", { XX
} },
3370 { "(bad)", { XX
} },
3371 { "(bad)", { XX
} },
3372 { "(bad)", { XX
} },
3373 { "(bad)", { XX
} },
3374 { "(bad)", { XX
} },
3375 { "(bad)", { XX
} },
3376 { "(bad)", { XX
} },
3378 { "(bad)", { XX
} },
3379 { "(bad)", { XX
} },
3380 { "(bad)", { XX
} },
3381 { "(bad)", { XX
} },
3382 { "(bad)", { XX
} },
3383 { "(bad)", { XX
} },
3384 { "(bad)", { XX
} },
3385 { "(bad)", { XX
} },
3387 { "(bad)", { XX
} },
3388 { "(bad)", { XX
} },
3389 { "(bad)", { XX
} },
3390 { "(bad)", { XX
} },
3391 { "(bad)", { XX
} },
3392 { "(bad)", { XX
} },
3393 { "(bad)", { XX
} },
3394 { "(bad)", { XX
} },
3396 { "(bad)", { XX
} },
3397 { "(bad)", { XX
} },
3398 { "(bad)", { XX
} },
3399 { "(bad)", { XX
} },
3400 { "(bad)", { XX
} },
3401 { "(bad)", { XX
} },
3402 { "(bad)", { XX
} },
3403 { "(bad)", { XX
} },
3407 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3419 fetch_data(the_info
, codep
+ 1);
3423 /* REX prefixes family. */
3440 if (address_mode
== mode_64bit
)
3446 prefixes
|= PREFIX_REPZ
;
3449 prefixes
|= PREFIX_REPNZ
;
3452 prefixes
|= PREFIX_LOCK
;
3455 prefixes
|= PREFIX_CS
;
3458 prefixes
|= PREFIX_SS
;
3461 prefixes
|= PREFIX_DS
;
3464 prefixes
|= PREFIX_ES
;
3467 prefixes
|= PREFIX_FS
;
3470 prefixes
|= PREFIX_GS
;
3473 prefixes
|= PREFIX_DATA
;
3476 prefixes
|= PREFIX_ADDR
;
3479 /* fwait is really an instruction. If there are prefixes
3480 before the fwait, they belong to the fwait, *not* to the
3481 following instruction. */
3482 if (prefixes
|| rex
)
3484 prefixes
|= PREFIX_FWAIT
;
3488 prefixes
= PREFIX_FWAIT
;
3493 /* Rex is ignored when followed by another prefix. */
3507 int op
, vex2
, vex3
, newrex
= 0, newpfx
= prefixes
;
3509 if (address_mode
== mode_16bit
) {
3513 fetch_data(the_info
, codep
+ 1);
3516 if (op
!= 0xc4 && op
!= 0xc5) {
3520 fetch_data(the_info
, codep
+ 2);
3523 if (address_mode
== mode_32bit
&& (vex2
& 0xc0) != 0xc0) {
3528 /* Three byte VEX prefix. */
3529 fetch_data(the_info
, codep
+ 3);
3532 newrex
|= (vex2
& 0x80 ? 0 : REX_R
);
3533 newrex
|= (vex2
& 0x40 ? 0 : REX_X
);
3534 newrex
|= (vex2
& 0x20 ? 0 : REX_B
);
3535 newrex
|= (vex3
& 0x80 ? REX_W
: 0);
3536 switch (vex2
& 0x1f) { /* VEX.m-mmmm */
3538 newpfx
|= PREFIX_VEX_0F
;
3541 newpfx
|= PREFIX_VEX_0F
| PREFIX_VEX_0F38
;
3544 newpfx
|= PREFIX_VEX_0F
| PREFIX_VEX_0F3A
;
3550 /* Two byte VEX prefix. */
3551 newrex
|= (vex2
& 0x80 ? 0 : REX_R
);
3555 vex_reg
= (~vex2
>> 3) & 15; /* VEX.vvvv */
3556 switch (vex2
& 3) { /* VEX.pp */
3558 newpfx
|= PREFIX_DATA
; /* 0x66 */
3561 newpfx
|= PREFIX_REPZ
; /* 0xf3 */
3564 newpfx
|= PREFIX_REPNZ
; /* 0xf2 */
3572 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3576 prefix_name (int pref
, int sizeflag
)
3578 static const char * const rexes
[16] =
3583 "rex.XB", /* 0x43 */
3585 "rex.RB", /* 0x45 */
3586 "rex.RX", /* 0x46 */
3587 "rex.RXB", /* 0x47 */
3589 "rex.WB", /* 0x49 */
3590 "rex.WX", /* 0x4a */
3591 "rex.WXB", /* 0x4b */
3592 "rex.WR", /* 0x4c */
3593 "rex.WRB", /* 0x4d */
3594 "rex.WRX", /* 0x4e */
3595 "rex.WRXB", /* 0x4f */
3600 /* REX prefixes family. */
3617 return rexes
[pref
- 0x40];
3637 return (sizeflag
& DFLAG
) ? "data16" : "data32";
3639 if (address_mode
== mode_64bit
)
3640 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
3642 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
3650 static char op_out
[MAX_OPERANDS
][100];
3651 static int op_ad
, op_index
[MAX_OPERANDS
];
3652 static int two_source_ops
;
3653 static bfd_vma op_address
[MAX_OPERANDS
];
3654 static bfd_vma op_riprel
[MAX_OPERANDS
];
3655 static bfd_vma start_pc
;
3658 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3659 * (see topic "Redundant prefixes" in the "Differences from 8086"
3660 * section of the "Virtual 8086 Mode" chapter.)
3661 * 'pc' should be the address of this instruction, it will
3662 * be used to print the target address if this is a relative jump or call
3663 * The function returns the length of this instruction in bytes.
3666 static char intel_syntax
;
3667 static char open_char
;
3668 static char close_char
;
3669 static char separator_char
;
3670 static char scale_char
;
3673 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
3677 return print_insn (pc
, info
);
3681 print_insn (bfd_vma pc
, disassemble_info
*info
)
3683 const struct dis386
*dp
;
3685 char *op_txt
[MAX_OPERANDS
];
3687 unsigned char uses_DATA_prefix
, uses_LOCK_prefix
;
3688 unsigned char uses_REPNZ_prefix
, uses_REPZ_prefix
;
3691 struct dis_private priv
;
3693 unsigned char threebyte
;
3695 if (info
->mach
== bfd_mach_x86_64_intel_syntax
3696 || info
->mach
== bfd_mach_x86_64
)
3697 address_mode
= mode_64bit
;
3699 address_mode
= mode_32bit
;
3701 if (intel_syntax
== (char) -1)
3702 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
3703 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
3705 if (info
->mach
== bfd_mach_i386_i386
3706 || info
->mach
== bfd_mach_x86_64
3707 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3708 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3709 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3710 else if (info
->mach
== bfd_mach_i386_i8086
)
3711 priv
.orig_sizeflag
= 0;
3715 for (p
= info
->disassembler_options
; p
!= NULL
; )
3717 if (strncmp (p
, "x86-64", 6) == 0)
3719 address_mode
= mode_64bit
;
3720 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3722 else if (strncmp (p
, "i386", 4) == 0)
3724 address_mode
= mode_32bit
;
3725 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
3727 else if (strncmp (p
, "i8086", 5) == 0)
3729 address_mode
= mode_16bit
;
3730 priv
.orig_sizeflag
= 0;
3732 else if (strncmp (p
, "intel", 5) == 0)
3736 else if (strncmp (p
, "att", 3) == 0)
3740 else if (strncmp (p
, "addr", 4) == 0)
3742 if (address_mode
== mode_64bit
)
3744 if (p
[4] == '3' && p
[5] == '2')
3745 priv
.orig_sizeflag
&= ~AFLAG
;
3746 else if (p
[4] == '6' && p
[5] == '4')
3747 priv
.orig_sizeflag
|= AFLAG
;
3751 if (p
[4] == '1' && p
[5] == '6')
3752 priv
.orig_sizeflag
&= ~AFLAG
;
3753 else if (p
[4] == '3' && p
[5] == '2')
3754 priv
.orig_sizeflag
|= AFLAG
;
3757 else if (strncmp (p
, "data", 4) == 0)
3759 if (p
[4] == '1' && p
[5] == '6')
3760 priv
.orig_sizeflag
&= ~DFLAG
;
3761 else if (p
[4] == '3' && p
[5] == '2')
3762 priv
.orig_sizeflag
|= DFLAG
;
3764 else if (strncmp (p
, "suffix", 6) == 0)
3765 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
3767 p
= strchr (p
, ',');
3774 names64
= intel_names64
;
3775 names32
= intel_names32
;
3776 names16
= intel_names16
;
3777 names8
= intel_names8
;
3778 names8rex
= intel_names8rex
;
3779 names_seg
= intel_names_seg
;
3780 index16
= intel_index16
;
3783 separator_char
= '+';
3788 names64
= att_names64
;
3789 names32
= att_names32
;
3790 names16
= att_names16
;
3791 names8
= att_names8
;
3792 names8rex
= att_names8rex
;
3793 names_seg
= att_names_seg
;
3794 index16
= att_index16
;
3797 separator_char
= ',';
3801 /* The output looks better if we put 7 bytes on a line, since that
3802 puts most long word instructions on a single line. */
3803 info
->bytes_per_line
= 7;
3805 info
->private_data
= &priv
;
3806 priv
.max_fetched
= priv
.the_buffer
;
3807 priv
.insn_start
= pc
;
3810 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
3818 start_codep
= priv
.the_buffer
;
3819 codep
= priv
.the_buffer
;
3821 if (sigsetjmp(priv
.bailout
, 0) != 0)
3825 /* Getting here means we tried for data but didn't get it. That
3826 means we have an incomplete instruction of some sort. Just
3827 print the first byte as a prefix or a .byte pseudo-op. */
3828 if (codep
> priv
.the_buffer
)
3830 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3832 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3835 /* Just print the first byte as a .byte instruction. */
3836 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3837 (unsigned int) priv
.the_buffer
[0]);
3851 sizeflag
= priv
.orig_sizeflag
;
3853 fetch_data(info
, codep
+ 1);
3854 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3856 if (((prefixes
& PREFIX_FWAIT
)
3857 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3858 || (rex
&& rex_used
))
3862 /* fwait not followed by floating point instruction, or rex followed
3863 by other prefixes. Print the first prefix. */
3864 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
3866 name
= INTERNAL_DISASSEMBLER_ERROR
;
3867 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3872 if (prefixes
& PREFIX_VEX_0F
)
3874 used_prefixes
|= PREFIX_VEX_0F
| PREFIX_VEX_0F38
| PREFIX_VEX_0F3A
;
3875 if (prefixes
& PREFIX_VEX_0F38
)
3877 else if (prefixes
& PREFIX_VEX_0F3A
)
3880 threebyte
= *codep
++;
3885 fetch_data(info
, codep
+ 2);
3886 threebyte
= codep
[1];
3889 dp
= &dis386_twobyte
[threebyte
];
3890 need_modrm
= twobyte_has_modrm
[threebyte
];
3891 uses_DATA_prefix
= twobyte_uses_DATA_prefix
[threebyte
];
3892 uses_REPNZ_prefix
= twobyte_uses_REPNZ_prefix
[threebyte
];
3893 uses_REPZ_prefix
= twobyte_uses_REPZ_prefix
[threebyte
];
3894 uses_LOCK_prefix
= (threebyte
& ~0x02) == 0x20;
3895 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3897 fetch_data(info
, codep
+ 2);
3902 uses_DATA_prefix
= threebyte_0x38_uses_DATA_prefix
[op
];
3903 uses_REPNZ_prefix
= threebyte_0x38_uses_REPNZ_prefix
[op
];
3904 uses_REPZ_prefix
= threebyte_0x38_uses_REPZ_prefix
[op
];
3907 uses_DATA_prefix
= threebyte_0x3a_uses_DATA_prefix
[op
];
3908 uses_REPNZ_prefix
= threebyte_0x3a_uses_REPNZ_prefix
[op
];
3909 uses_REPZ_prefix
= threebyte_0x3a_uses_REPZ_prefix
[op
];
3918 dp
= &dis386
[*codep
];
3919 need_modrm
= onebyte_has_modrm
[*codep
];
3920 uses_DATA_prefix
= 0;
3921 uses_REPNZ_prefix
= 0;
3922 /* pause is 0xf3 0x90. */
3923 uses_REPZ_prefix
= *codep
== 0x90;
3924 uses_LOCK_prefix
= 0;
3928 if (!uses_REPZ_prefix
&& (prefixes
& PREFIX_REPZ
))
3931 used_prefixes
|= PREFIX_REPZ
;
3933 if (!uses_REPNZ_prefix
&& (prefixes
& PREFIX_REPNZ
))
3936 used_prefixes
|= PREFIX_REPNZ
;
3939 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
3942 used_prefixes
|= PREFIX_LOCK
;
3945 if (prefixes
& PREFIX_ADDR
)
3948 if (dp
->op
[2].bytemode
!= loop_jcxz_mode
|| intel_syntax
)
3950 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3951 oappend ("addr32 ");
3953 oappend ("addr16 ");
3954 used_prefixes
|= PREFIX_ADDR
;
3958 if (!uses_DATA_prefix
&& (prefixes
& PREFIX_DATA
))
3961 if (dp
->op
[2].bytemode
== cond_jump_mode
3962 && dp
->op
[0].bytemode
== v_mode
3965 if (sizeflag
& DFLAG
)
3966 oappend ("data32 ");
3968 oappend ("data16 ");
3969 used_prefixes
|= PREFIX_DATA
;
3973 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== IS_3BYTE_OPCODE
)
3975 dp
= &three_byte_table
[dp
->op
[1].bytemode
][op
];
3976 modrm
.mod
= (*codep
>> 6) & 3;
3977 modrm
.reg
= (*codep
>> 3) & 7;
3978 modrm
.rm
= *codep
& 7;
3980 else if (need_modrm
)
3982 fetch_data(info
, codep
+ 1);
3983 modrm
.mod
= (*codep
>> 6) & 3;
3984 modrm
.reg
= (*codep
>> 3) & 7;
3985 modrm
.rm
= *codep
& 7;
3988 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
3995 if (dp
->name
== NULL
)
3997 switch (dp
->op
[0].bytemode
)
4000 dp
= &grps
[dp
->op
[1].bytemode
][modrm
.reg
];
4003 case USE_PREFIX_USER_TABLE
:
4005 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4006 if (prefixes
& PREFIX_REPZ
)
4010 /* We should check PREFIX_REPNZ and PREFIX_REPZ
4011 before PREFIX_DATA. */
4012 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4013 if (prefixes
& PREFIX_REPNZ
)
4017 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4018 if (prefixes
& PREFIX_DATA
)
4022 dp
= &prefix_user_table
[dp
->op
[1].bytemode
][index
];
4025 case X86_64_SPECIAL
:
4026 index
= address_mode
== mode_64bit
? 1 : 0;
4027 dp
= &x86_64_table
[dp
->op
[1].bytemode
][index
];
4031 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4036 if (putop (dp
->name
, sizeflag
) == 0)
4038 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4041 op_ad
= MAX_OPERANDS
- 1 - i
;
4043 (*dp
->op
[i
].rtn
) (dp
->op
[i
].bytemode
, sizeflag
);
4048 /* See if any prefixes were not used. If so, print the first one
4049 separately. If we don't do this, we'll wind up printing an
4050 instruction stream which does not precisely correspond to the
4051 bytes we are disassembling. */
4052 if ((prefixes
& ~used_prefixes
) != 0)
4056 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
4058 name
= INTERNAL_DISASSEMBLER_ERROR
;
4059 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
4062 if (rex
& ~rex_used
)
4065 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
4067 name
= INTERNAL_DISASSEMBLER_ERROR
;
4068 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
4071 obufp
= obuf
+ strlen (obuf
);
4072 for (i
= strlen (obuf
); i
< 6; i
++)
4075 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
4077 /* The enter and bound instructions are printed with operands in the same
4078 order as the intel book; everything else is printed in reverse order. */
4079 if (intel_syntax
|| two_source_ops
)
4083 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4084 op_txt
[i
] = op_out
[i
];
4086 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
4088 op_ad
= op_index
[i
];
4089 op_index
[i
] = op_index
[MAX_OPERANDS
- 1 - i
];
4090 op_index
[MAX_OPERANDS
- 1 - i
] = op_ad
;
4091 riprel
= op_riprel
[i
];
4092 op_riprel
[i
] = op_riprel
[MAX_OPERANDS
- 1 - i
];
4093 op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
4098 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4099 op_txt
[MAX_OPERANDS
- 1 - i
] = op_out
[i
];
4103 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
4107 (*info
->fprintf_func
) (info
->stream
, ",");
4108 if (op_index
[i
] != -1 && !op_riprel
[i
])
4109 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[i
]], info
);
4111 (*info
->fprintf_func
) (info
->stream
, "%s", op_txt
[i
]);
4115 for (i
= 0; i
< MAX_OPERANDS
; i
++)
4116 if (op_index
[i
] != -1 && op_riprel
[i
])
4118 (*info
->fprintf_func
) (info
->stream
, " # ");
4119 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
4120 + op_address
[op_index
[i
]]), info
);
4123 return codep
- priv
.the_buffer
;
4126 static const char *float_mem
[] = {
4201 static const unsigned char float_mem_mode
[] = {
4276 #define ST { OP_ST, 0 }
4277 #define STi { OP_STi, 0 }
4279 #define FGRPd9_2 NULL, { { NULL, 0 } }
4280 #define FGRPd9_4 NULL, { { NULL, 1 } }
4281 #define FGRPd9_5 NULL, { { NULL, 2 } }
4282 #define FGRPd9_6 NULL, { { NULL, 3 } }
4283 #define FGRPd9_7 NULL, { { NULL, 4 } }
4284 #define FGRPda_5 NULL, { { NULL, 5 } }
4285 #define FGRPdb_4 NULL, { { NULL, 6 } }
4286 #define FGRPde_3 NULL, { { NULL, 7 } }
4287 #define FGRPdf_4 NULL, { { NULL, 8 } }
4289 static const struct dis386 float_reg
[][8] = {
4292 { "fadd", { ST
, STi
} },
4293 { "fmul", { ST
, STi
} },
4294 { "fcom", { STi
} },
4295 { "fcomp", { STi
} },
4296 { "fsub", { ST
, STi
} },
4297 { "fsubr", { ST
, STi
} },
4298 { "fdiv", { ST
, STi
} },
4299 { "fdivr", { ST
, STi
} },
4304 { "fxch", { STi
} },
4306 { "(bad)", { XX
} },
4314 { "fcmovb", { ST
, STi
} },
4315 { "fcmove", { ST
, STi
} },
4316 { "fcmovbe",{ ST
, STi
} },
4317 { "fcmovu", { ST
, STi
} },
4318 { "(bad)", { XX
} },
4320 { "(bad)", { XX
} },
4321 { "(bad)", { XX
} },
4325 { "fcmovnb",{ ST
, STi
} },
4326 { "fcmovne",{ ST
, STi
} },
4327 { "fcmovnbe",{ ST
, STi
} },
4328 { "fcmovnu",{ ST
, STi
} },
4330 { "fucomi", { ST
, STi
} },
4331 { "fcomi", { ST
, STi
} },
4332 { "(bad)", { XX
} },
4336 { "fadd", { STi
, ST
} },
4337 { "fmul", { STi
, ST
} },
4338 { "(bad)", { XX
} },
4339 { "(bad)", { XX
} },
4341 { "fsub", { STi
, ST
} },
4342 { "fsubr", { STi
, ST
} },
4343 { "fdiv", { STi
, ST
} },
4344 { "fdivr", { STi
, ST
} },
4346 { "fsubr", { STi
, ST
} },
4347 { "fsub", { STi
, ST
} },
4348 { "fdivr", { STi
, ST
} },
4349 { "fdiv", { STi
, ST
} },
4354 { "ffree", { STi
} },
4355 { "(bad)", { XX
} },
4357 { "fstp", { STi
} },
4358 { "fucom", { STi
} },
4359 { "fucomp", { STi
} },
4360 { "(bad)", { XX
} },
4361 { "(bad)", { XX
} },
4365 { "faddp", { STi
, ST
} },
4366 { "fmulp", { STi
, ST
} },
4367 { "(bad)", { XX
} },
4370 { "fsubp", { STi
, ST
} },
4371 { "fsubrp", { STi
, ST
} },
4372 { "fdivp", { STi
, ST
} },
4373 { "fdivrp", { STi
, ST
} },
4375 { "fsubrp", { STi
, ST
} },
4376 { "fsubp", { STi
, ST
} },
4377 { "fdivrp", { STi
, ST
} },
4378 { "fdivp", { STi
, ST
} },
4383 { "ffreep", { STi
} },
4384 { "(bad)", { XX
} },
4385 { "(bad)", { XX
} },
4386 { "(bad)", { XX
} },
4388 { "fucomip", { ST
, STi
} },
4389 { "fcomip", { ST
, STi
} },
4390 { "(bad)", { XX
} },
4394 static const char *fgrps
[][8] = {
4397 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4402 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4407 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4412 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4417 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4422 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4427 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4428 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4433 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4438 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4443 dofloat (int sizeflag
)
4445 const struct dis386
*dp
;
4446 unsigned char floatop
;
4448 floatop
= codep
[-1];
4452 int fp_indx
= (floatop
- 0xd8) * 8 + modrm
.reg
;
4454 putop (float_mem
[fp_indx
], sizeflag
);
4457 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
4460 /* Skip mod/rm byte. */
4464 dp
= &float_reg
[floatop
- 0xd8][modrm
.reg
];
4465 if (dp
->name
== NULL
)
4467 putop (fgrps
[dp
->op
[0].bytemode
][modrm
.rm
], sizeflag
);
4469 /* Instruction fnstsw is only one with strange arg. */
4470 if (floatop
== 0xdf && codep
[-1] == 0xe0)
4471 pstrcpy (op_out
[0], sizeof(op_out
[0]), names16
[0]);
4475 putop (dp
->name
, sizeflag
);
4480 (*dp
->op
[0].rtn
) (dp
->op
[0].bytemode
, sizeflag
);
4485 (*dp
->op
[1].rtn
) (dp
->op
[1].bytemode
, sizeflag
);
4490 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4492 oappend ("%st" + intel_syntax
);
4496 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4498 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%st(%d)", modrm
.rm
);
4499 oappend (scratchbuf
+ intel_syntax
);
4502 /* Capital letters in template are macros. */
4504 putop (const char *template, int sizeflag
)
4509 for (p
= template; *p
; p
++)
4520 if (address_mode
== mode_64bit
)
4528 /* Alternative not valid. */
4529 pstrcpy (obuf
, sizeof(obuf
), "(bad)");
4533 else if (*p
== '\0')
4554 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4560 if (sizeflag
& SUFFIX_ALWAYS
)
4564 if (intel_syntax
&& !alt
)
4566 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
4568 if (sizeflag
& DFLAG
)
4569 *obufp
++ = intel_syntax
? 'd' : 'l';
4571 *obufp
++ = intel_syntax
? 'w' : 's';
4572 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4576 if (intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
4583 else if (sizeflag
& DFLAG
)
4584 *obufp
++ = intel_syntax
? 'd' : 'l';
4587 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4592 case 'E': /* For jcxz/jecxz */
4593 if (address_mode
== mode_64bit
)
4595 if (sizeflag
& AFLAG
)
4601 if (sizeflag
& AFLAG
)
4603 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4608 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
4610 if (sizeflag
& AFLAG
)
4611 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
4613 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
4614 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4618 if (intel_syntax
|| (obufp
[-1] != 's' && !(sizeflag
& SUFFIX_ALWAYS
)))
4620 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
4625 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4630 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
4631 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
4633 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
4636 if (prefixes
& PREFIX_DS
)
4657 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
4666 if (sizeflag
& SUFFIX_ALWAYS
)
4670 if ((prefixes
& PREFIX_FWAIT
) == 0)
4673 used_prefixes
|= PREFIX_FWAIT
;
4679 else if (intel_syntax
&& (sizeflag
& DFLAG
))
4684 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4689 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4698 if ((prefixes
& PREFIX_DATA
)
4700 || (sizeflag
& SUFFIX_ALWAYS
))
4707 if (sizeflag
& DFLAG
)
4712 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4718 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4720 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4726 if (intel_syntax
&& !alt
)
4729 if (modrm
.mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
4735 if (sizeflag
& DFLAG
)
4736 *obufp
++ = intel_syntax
? 'd' : 'l';
4740 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4747 else if (sizeflag
& DFLAG
)
4756 if (intel_syntax
&& !p
[1]
4757 && ((rex
& REX_W
) || (sizeflag
& DFLAG
)))
4760 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4765 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4767 if (sizeflag
& SUFFIX_ALWAYS
)
4775 if (sizeflag
& SUFFIX_ALWAYS
)
4781 if (sizeflag
& DFLAG
)
4785 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4790 if (prefixes
& PREFIX_DATA
)
4794 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4805 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4807 /* operand size flag for cwtl, cbtw */
4816 else if (sizeflag
& DFLAG
)
4821 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4831 oappend (const char *s
)
4834 obufp
+= strlen (s
);
4840 if (prefixes
& PREFIX_CS
)
4842 used_prefixes
|= PREFIX_CS
;
4843 oappend ("%cs:" + intel_syntax
);
4845 if (prefixes
& PREFIX_DS
)
4847 used_prefixes
|= PREFIX_DS
;
4848 oappend ("%ds:" + intel_syntax
);
4850 if (prefixes
& PREFIX_SS
)
4852 used_prefixes
|= PREFIX_SS
;
4853 oappend ("%ss:" + intel_syntax
);
4855 if (prefixes
& PREFIX_ES
)
4857 used_prefixes
|= PREFIX_ES
;
4858 oappend ("%es:" + intel_syntax
);
4860 if (prefixes
& PREFIX_FS
)
4862 used_prefixes
|= PREFIX_FS
;
4863 oappend ("%fs:" + intel_syntax
);
4865 if (prefixes
& PREFIX_GS
)
4867 used_prefixes
|= PREFIX_GS
;
4868 oappend ("%gs:" + intel_syntax
);
4873 OP_indirE (int bytemode
, int sizeflag
)
4877 OP_E (bytemode
, sizeflag
);
4881 print_operand_value (char *buf
, size_t bufsize
, int hex
, bfd_vma disp
)
4883 if (address_mode
== mode_64bit
)
4891 snprintf_vma (tmp
, sizeof(tmp
), disp
);
4892 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++) {
4894 pstrcpy (buf
+ 2, bufsize
- 2, tmp
+ i
);
4898 bfd_signed_vma v
= disp
;
4905 /* Check for possible overflow on 0x8000000000000000. */
4908 pstrcpy (buf
, bufsize
, "9223372036854775808");
4914 pstrcpy (buf
, bufsize
, "0");
4922 tmp
[28 - i
] = (v
% 10) + '0';
4926 pstrcpy (buf
, bufsize
, tmp
+ 29 - i
);
4932 snprintf (buf
, bufsize
, "0x%x", (unsigned int) disp
);
4934 snprintf (buf
, bufsize
, "%d", (int) disp
);
4938 /* Put DISP in BUF as signed hex number. */
4941 print_displacement (char *buf
, bfd_vma disp
)
4943 bfd_signed_vma val
= disp
;
4952 /* Check for possible overflow. */
4955 switch (address_mode
)
4958 strcpy (buf
+ j
, "0x8000000000000000");
4961 strcpy (buf
+ j
, "0x80000000");
4964 strcpy (buf
+ j
, "0x8000");
4974 snprintf_vma (tmp
, sizeof(tmp
), val
);
4975 for (i
= 0; tmp
[i
] == '0'; i
++)
4979 strcpy (buf
+ j
, tmp
+ i
);
4983 intel_operand_size (int bytemode
, int sizeflag
)
4989 oappend ("BYTE PTR ");
4993 oappend ("WORD PTR ");
4996 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
4998 oappend ("QWORD PTR ");
4999 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5007 oappend ("QWORD PTR ");
5008 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
5009 oappend ("DWORD PTR ");
5011 oappend ("WORD PTR ");
5012 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5015 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5017 oappend ("WORD PTR ");
5019 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5023 oappend ("DWORD PTR ");
5026 oappend ("QWORD PTR ");
5029 if (address_mode
== mode_64bit
)
5030 oappend ("QWORD PTR ");
5032 oappend ("DWORD PTR ");
5035 if (sizeflag
& DFLAG
)
5036 oappend ("FWORD PTR ");
5038 oappend ("DWORD PTR ");
5039 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5042 oappend ("TBYTE PTR ");
5045 oappend ("XMMWORD PTR ");
5048 oappend ("OWORD PTR ");
5056 OP_E (int bytemode
, int sizeflag
)
5065 /* Skip mod/rm byte. */
5076 oappend (names8rex
[modrm
.rm
+ add
]);
5078 oappend (names8
[modrm
.rm
+ add
]);
5081 oappend (names16
[modrm
.rm
+ add
]);
5084 oappend (names32
[modrm
.rm
+ add
]);
5087 oappend (names64
[modrm
.rm
+ add
]);
5090 if (address_mode
== mode_64bit
)
5091 oappend (names64
[modrm
.rm
+ add
]);
5093 oappend (names32
[modrm
.rm
+ add
]);
5096 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5098 oappend (names64
[modrm
.rm
+ add
]);
5099 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5111 oappend (names64
[modrm
.rm
+ add
]);
5112 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5113 oappend (names32
[modrm
.rm
+ add
]);
5115 oappend (names16
[modrm
.rm
+ add
]);
5116 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5121 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5129 intel_operand_size (bytemode
, sizeflag
);
5132 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5134 /* 32/64 bit address mode */
5149 fetch_data(the_info
, codep
+ 1);
5150 index
= (*codep
>> 3) & 7;
5151 if (address_mode
== mode_64bit
|| index
!= 0x4)
5152 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
5153 scale
= (*codep
>> 6) & 3;
5165 if ((base
& 7) == 5)
5168 if (address_mode
== mode_64bit
&& !havesib
)
5174 fetch_data (the_info
, codep
+ 1);
5176 if ((disp
& 0x80) != 0)
5184 havedisp
= havebase
|| (havesib
&& (index
!= 4 || scale
!= 0));
5187 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5189 if (havedisp
|| riprel
)
5190 print_displacement (scratchbuf
, disp
);
5192 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, disp
);
5193 oappend (scratchbuf
);
5201 if (havedisp
|| (intel_syntax
&& riprel
))
5203 *obufp
++ = open_char
;
5204 if (intel_syntax
&& riprel
)
5211 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5212 ? names64
[base
] : names32
[base
]);
5217 if (!intel_syntax
|| havebase
)
5219 *obufp
++ = separator_char
;
5222 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
5223 ? names64
[index
] : names32
[index
]);
5225 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
5227 *obufp
++ = scale_char
;
5229 snprintf (scratchbuf
, sizeof(scratchbuf
), "%d", 1 << scale
);
5230 oappend (scratchbuf
);
5234 && (disp
|| modrm
.mod
!= 0 || (base
& 7) == 5))
5236 if ((bfd_signed_vma
) disp
>= 0)
5241 else if (modrm
.mod
!= 1)
5245 disp
= - (bfd_signed_vma
) disp
;
5248 print_displacement (scratchbuf
, disp
);
5249 oappend (scratchbuf
);
5252 *obufp
++ = close_char
;
5255 else if (intel_syntax
)
5257 if (modrm
.mod
!= 0 || (base
& 7) == 5)
5259 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5260 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5264 oappend (names_seg
[ds_reg
- es_reg
]);
5267 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, disp
);
5268 oappend (scratchbuf
);
5273 { /* 16 bit address mode */
5280 if ((disp
& 0x8000) != 0)
5285 fetch_data(the_info
, codep
+ 1);
5287 if ((disp
& 0x80) != 0)
5292 if ((disp
& 0x8000) != 0)
5298 if (modrm
.mod
!= 0 || modrm
.rm
== 6)
5300 print_displacement (scratchbuf
, disp
);
5301 oappend (scratchbuf
);
5304 if (modrm
.mod
!= 0 || modrm
.rm
!= 6)
5306 *obufp
++ = open_char
;
5308 oappend (index16
[modrm
.rm
]);
5310 && (disp
|| modrm
.mod
!= 0 || modrm
.rm
== 6))
5312 if ((bfd_signed_vma
) disp
>= 0)
5317 else if (modrm
.mod
!= 1)
5321 disp
= - (bfd_signed_vma
) disp
;
5324 print_displacement (scratchbuf
, disp
);
5325 oappend (scratchbuf
);
5328 *obufp
++ = close_char
;
5331 else if (intel_syntax
)
5333 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5334 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
5338 oappend (names_seg
[ds_reg
- es_reg
]);
5341 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1,
5343 oappend (scratchbuf
);
5349 OP_G (int bytemode
, int sizeflag
)
5360 oappend (names8rex
[modrm
.reg
+ add
]);
5362 oappend (names8
[modrm
.reg
+ add
]);
5365 oappend (names16
[modrm
.reg
+ add
]);
5368 oappend (names32
[modrm
.reg
+ add
]);
5371 oappend (names64
[modrm
.reg
+ add
]);
5380 oappend (names64
[modrm
.reg
+ add
]);
5381 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
5382 oappend (names32
[modrm
.reg
+ add
]);
5384 oappend (names16
[modrm
.reg
+ add
]);
5385 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5388 if (address_mode
== mode_64bit
)
5389 oappend (names64
[modrm
.reg
+ add
]);
5391 oappend (names32
[modrm
.reg
+ add
]);
5394 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5400 OP_vvvv (int bytemode
, int sizeflags
)
5404 oappend(names64
[vex_reg
]);
5406 oappend(names32
[vex_reg
]);
5418 fetch_data(the_info
, codep
+ 8);
5419 a
= *codep
++ & 0xff;
5420 a
|= (*codep
++ & 0xff) << 8;
5421 a
|= (*codep
++ & 0xff) << 16;
5422 a
|= (*codep
++ & 0xff) << 24;
5423 b
= *codep
++ & 0xff;
5424 b
|= (*codep
++ & 0xff) << 8;
5425 b
|= (*codep
++ & 0xff) << 16;
5426 b
|= (*codep
++ & 0xff) << 24;
5427 x
= a
+ ((bfd_vma
) b
<< 32);
5435 static bfd_signed_vma
5438 bfd_signed_vma x
= 0;
5440 fetch_data(the_info
, codep
+ 4);
5441 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5442 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5443 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5444 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5448 static bfd_signed_vma
5451 bfd_signed_vma x
= 0;
5453 fetch_data(the_info
, codep
+ 4);
5454 x
= *codep
++ & (bfd_signed_vma
) 0xff;
5455 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
5456 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
5457 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
5459 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
5469 fetch_data(the_info
, codep
+ 2);
5470 x
= *codep
++ & 0xff;
5471 x
|= (*codep
++ & 0xff) << 8;
5476 set_op (bfd_vma op
, int riprel
)
5478 op_index
[op_ad
] = op_ad
;
5479 if (address_mode
== mode_64bit
)
5481 op_address
[op_ad
] = op
;
5482 op_riprel
[op_ad
] = riprel
;
5486 /* Mask to get a 32-bit address. */
5487 op_address
[op_ad
] = op
& 0xffffffff;
5488 op_riprel
[op_ad
] = riprel
& 0xffffffff;
5493 OP_REG (int code
, int sizeflag
)
5503 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5504 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5505 s
= names16
[code
- ax_reg
+ add
];
5507 case es_reg
: case ss_reg
: case cs_reg
:
5508 case ds_reg
: case fs_reg
: case gs_reg
:
5509 s
= names_seg
[code
- es_reg
+ add
];
5511 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5512 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5515 s
= names8rex
[code
- al_reg
+ add
];
5517 s
= names8
[code
- al_reg
];
5519 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
5520 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
5521 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
5523 s
= names64
[code
- rAX_reg
+ add
];
5526 code
+= eAX_reg
- rAX_reg
;
5528 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5529 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5532 s
= names64
[code
- eAX_reg
+ add
];
5533 else if (sizeflag
& DFLAG
)
5534 s
= names32
[code
- eAX_reg
+ add
];
5536 s
= names16
[code
- eAX_reg
+ add
];
5537 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5540 s
= INTERNAL_DISASSEMBLER_ERROR
;
5547 OP_IMREG (int code
, int sizeflag
)
5559 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
5560 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
5561 s
= names16
[code
- ax_reg
];
5563 case es_reg
: case ss_reg
: case cs_reg
:
5564 case ds_reg
: case fs_reg
: case gs_reg
:
5565 s
= names_seg
[code
- es_reg
];
5567 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
5568 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
5571 s
= names8rex
[code
- al_reg
];
5573 s
= names8
[code
- al_reg
];
5575 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
5576 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
5579 s
= names64
[code
- eAX_reg
];
5580 else if (sizeflag
& DFLAG
)
5581 s
= names32
[code
- eAX_reg
];
5583 s
= names16
[code
- eAX_reg
];
5584 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5587 if ((rex
& REX_W
) || (sizeflag
& DFLAG
))
5592 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5595 s
= INTERNAL_DISASSEMBLER_ERROR
;
5602 OP_I (int bytemode
, int sizeflag
)
5605 bfd_signed_vma mask
= -1;
5610 fetch_data(the_info
, codep
+ 1);
5615 if (address_mode
== mode_64bit
)
5625 else if (sizeflag
& DFLAG
)
5635 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5646 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5651 scratchbuf
[0] = '$';
5652 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
5653 oappend (scratchbuf
+ intel_syntax
);
5654 scratchbuf
[0] = '\0';
5658 OP_I64 (int bytemode
, int sizeflag
)
5661 bfd_signed_vma mask
= -1;
5663 if (address_mode
!= mode_64bit
)
5665 OP_I (bytemode
, sizeflag
);
5672 fetch_data(the_info
, codep
+ 1);
5680 else if (sizeflag
& DFLAG
)
5690 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5697 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5702 scratchbuf
[0] = '$';
5703 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
5704 oappend (scratchbuf
+ intel_syntax
);
5705 scratchbuf
[0] = '\0';
5709 OP_sI (int bytemode
, int sizeflag
)
5716 fetch_data(the_info
, codep
+ 1);
5718 if ((op
& 0x80) != 0)
5725 else if (sizeflag
& DFLAG
)
5732 if ((op
& 0x8000) != 0)
5735 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5739 if ((op
& 0x8000) != 0)
5743 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5747 scratchbuf
[0] = '$';
5748 print_operand_value (scratchbuf
+ 1, sizeof(scratchbuf
) - 1, 1, op
);
5749 oappend (scratchbuf
+ intel_syntax
);
5753 OP_J (int bytemode
, int sizeflag
)
5757 bfd_vma segment
= 0;
5762 fetch_data(the_info
, codep
+ 1);
5764 if ((disp
& 0x80) != 0)
5768 if ((sizeflag
& DFLAG
) || (rex
& REX_W
))
5773 if ((disp
& 0x8000) != 0)
5775 /* In 16bit mode, address is wrapped around at 64k within
5776 the same segment. Otherwise, a data16 prefix on a jump
5777 instruction means that the pc is masked to 16 bits after
5778 the displacement is added! */
5780 if ((prefixes
& PREFIX_DATA
) == 0)
5781 segment
= ((start_pc
+ codep
- start_codep
)
5782 & ~((bfd_vma
) 0xffff));
5784 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5787 oappend (INTERNAL_DISASSEMBLER_ERROR
);
5790 disp
= ((start_pc
+ codep
- start_codep
+ disp
) & mask
) | segment
;
5792 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, disp
);
5793 oappend (scratchbuf
);
5797 OP_SEG (int bytemode
, int sizeflag
)
5799 if (bytemode
== w_mode
)
5800 oappend (names_seg
[modrm
.reg
]);
5802 OP_E (modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
5806 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
5810 if (sizeflag
& DFLAG
)
5820 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5822 snprintf (scratchbuf
, sizeof(scratchbuf
), "0x%x:0x%x", seg
, offset
);
5824 snprintf (scratchbuf
, sizeof(scratchbuf
), "$0x%x,$0x%x", seg
, offset
);
5825 oappend (scratchbuf
);
5829 OP_OFF (int bytemode
, int sizeflag
)
5833 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5834 intel_operand_size (bytemode
, sizeflag
);
5837 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
5844 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5845 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5847 oappend (names_seg
[ds_reg
- es_reg
]);
5851 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, off
);
5852 oappend (scratchbuf
);
5856 OP_OFF64 (int bytemode
, int sizeflag
)
5860 if (address_mode
!= mode_64bit
5861 || (prefixes
& PREFIX_ADDR
))
5863 OP_OFF (bytemode
, sizeflag
);
5867 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
5868 intel_operand_size (bytemode
, sizeflag
);
5875 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
5876 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
5878 oappend (names_seg
[ds_reg
- es_reg
]);
5882 print_operand_value (scratchbuf
, sizeof(scratchbuf
), 1, off
);
5883 oappend (scratchbuf
);
5887 ptr_reg (int code
, int sizeflag
)
5891 *obufp
++ = open_char
;
5892 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
5893 if (address_mode
== mode_64bit
)
5895 if (!(sizeflag
& AFLAG
))
5896 s
= names32
[code
- eAX_reg
];
5898 s
= names64
[code
- eAX_reg
];
5900 else if (sizeflag
& AFLAG
)
5901 s
= names32
[code
- eAX_reg
];
5903 s
= names16
[code
- eAX_reg
];
5905 *obufp
++ = close_char
;
5910 OP_ESreg (int code
, int sizeflag
)
5916 case 0x6d: /* insw/insl */
5917 intel_operand_size (z_mode
, sizeflag
);
5919 case 0xa5: /* movsw/movsl/movsq */
5920 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5921 case 0xab: /* stosw/stosl */
5922 case 0xaf: /* scasw/scasl */
5923 intel_operand_size (v_mode
, sizeflag
);
5926 intel_operand_size (b_mode
, sizeflag
);
5929 oappend ("%es:" + intel_syntax
);
5930 ptr_reg (code
, sizeflag
);
5934 OP_DSreg (int code
, int sizeflag
)
5940 case 0x6f: /* outsw/outsl */
5941 intel_operand_size (z_mode
, sizeflag
);
5943 case 0xa5: /* movsw/movsl/movsq */
5944 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5945 case 0xad: /* lodsw/lodsl/lodsq */
5946 intel_operand_size (v_mode
, sizeflag
);
5949 intel_operand_size (b_mode
, sizeflag
);
5959 prefixes
|= PREFIX_DS
;
5961 ptr_reg (code
, sizeflag
);
5965 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5973 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
5975 used_prefixes
|= PREFIX_LOCK
;
5978 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%cr%d", modrm
.reg
+ add
);
5979 oappend (scratchbuf
+ intel_syntax
);
5983 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5990 snprintf (scratchbuf
, sizeof(scratchbuf
), "db%d", modrm
.reg
+ add
);
5992 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%db%d", modrm
.reg
+ add
);
5993 oappend (scratchbuf
);
5997 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
5999 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%tr%d", modrm
.reg
);
6000 oappend (scratchbuf
+ intel_syntax
);
6004 OP_R (int bytemode
, int sizeflag
)
6007 OP_E (bytemode
, sizeflag
);
6013 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6015 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6016 if (prefixes
& PREFIX_DATA
)
6022 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", modrm
.reg
+ add
);
6025 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", modrm
.reg
);
6026 oappend (scratchbuf
+ intel_syntax
);
6030 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6036 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", modrm
.reg
+ add
);
6037 oappend (scratchbuf
+ intel_syntax
);
6041 OP_EM (int bytemode
, int sizeflag
)
6045 if (intel_syntax
&& bytemode
== v_mode
)
6047 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
6048 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6050 OP_E (bytemode
, sizeflag
);
6054 /* Skip mod/rm byte. */
6057 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6058 if (prefixes
& PREFIX_DATA
)
6065 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", modrm
.rm
+ add
);
6068 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", modrm
.rm
);
6069 oappend (scratchbuf
+ intel_syntax
);
6072 /* cvt* are the only instructions in sse2 which have
6073 both SSE and MMX operands and also have 0x66 prefix
6074 in their opcode. 0x66 was originally used to differentiate
6075 between SSE and MMX instruction(operands). So we have to handle the
6076 cvt* separately using OP_EMC and OP_MXC */
6078 OP_EMC (int bytemode
, int sizeflag
)
6082 if (intel_syntax
&& bytemode
== v_mode
)
6084 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
6085 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6087 OP_E (bytemode
, sizeflag
);
6091 /* Skip mod/rm byte. */
6094 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6095 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", modrm
.rm
);
6096 oappend (scratchbuf
+ intel_syntax
);
6100 OP_MXC (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6102 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6103 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%mm%d", modrm
.reg
);
6104 oappend (scratchbuf
+ intel_syntax
);
6108 OP_EX (int bytemode
, int sizeflag
)
6113 OP_E (bytemode
, sizeflag
);
6120 /* Skip mod/rm byte. */
6123 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", modrm
.rm
+ add
);
6124 oappend (scratchbuf
+ intel_syntax
);
6128 OP_MS (int bytemode
, int sizeflag
)
6131 OP_EM (bytemode
, sizeflag
);
6137 OP_XS (int bytemode
, int sizeflag
)
6140 OP_EX (bytemode
, sizeflag
);
6146 OP_M (int bytemode
, int sizeflag
)
6149 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
6152 OP_E (bytemode
, sizeflag
);
6156 OP_0f07 (int bytemode
, int sizeflag
)
6158 if (modrm
.mod
!= 3 || modrm
.rm
!= 0)
6161 OP_E (bytemode
, sizeflag
);
6165 OP_0fae (int bytemode
, int sizeflag
)
6170 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
6172 if (modrm
.reg
< 5 || modrm
.rm
!= 0)
6174 BadOp (); /* bad sfence, mfence, or lfence */
6178 else if (modrm
.reg
!= 7)
6180 BadOp (); /* bad clflush */
6184 OP_E (bytemode
, sizeflag
);
6187 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6188 32bit mode and "xchg %rax,%rax" in 64bit mode. */
6191 NOP_Fixup1 (int bytemode
, int sizeflag
)
6193 if ((prefixes
& PREFIX_DATA
) != 0
6196 && address_mode
== mode_64bit
))
6197 OP_REG (bytemode
, sizeflag
);
6199 strcpy (obuf
, "nop");
6203 NOP_Fixup2 (int bytemode
, int sizeflag
)
6205 if ((prefixes
& PREFIX_DATA
) != 0
6208 && address_mode
== mode_64bit
))
6209 OP_IMREG (bytemode
, sizeflag
);
6212 static const char *Suffix3DNow
[] = {
6213 /* 00 */ NULL
, NULL
, NULL
, NULL
,
6214 /* 04 */ NULL
, NULL
, NULL
, NULL
,
6215 /* 08 */ NULL
, NULL
, NULL
, NULL
,
6216 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
6217 /* 10 */ NULL
, NULL
, NULL
, NULL
,
6218 /* 14 */ NULL
, NULL
, NULL
, NULL
,
6219 /* 18 */ NULL
, NULL
, NULL
, NULL
,
6220 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
6221 /* 20 */ NULL
, NULL
, NULL
, NULL
,
6222 /* 24 */ NULL
, NULL
, NULL
, NULL
,
6223 /* 28 */ NULL
, NULL
, NULL
, NULL
,
6224 /* 2C */ NULL
, NULL
, NULL
, NULL
,
6225 /* 30 */ NULL
, NULL
, NULL
, NULL
,
6226 /* 34 */ NULL
, NULL
, NULL
, NULL
,
6227 /* 38 */ NULL
, NULL
, NULL
, NULL
,
6228 /* 3C */ NULL
, NULL
, NULL
, NULL
,
6229 /* 40 */ NULL
, NULL
, NULL
, NULL
,
6230 /* 44 */ NULL
, NULL
, NULL
, NULL
,
6231 /* 48 */ NULL
, NULL
, NULL
, NULL
,
6232 /* 4C */ NULL
, NULL
, NULL
, NULL
,
6233 /* 50 */ NULL
, NULL
, NULL
, NULL
,
6234 /* 54 */ NULL
, NULL
, NULL
, NULL
,
6235 /* 58 */ NULL
, NULL
, NULL
, NULL
,
6236 /* 5C */ NULL
, NULL
, NULL
, NULL
,
6237 /* 60 */ NULL
, NULL
, NULL
, NULL
,
6238 /* 64 */ NULL
, NULL
, NULL
, NULL
,
6239 /* 68 */ NULL
, NULL
, NULL
, NULL
,
6240 /* 6C */ NULL
, NULL
, NULL
, NULL
,
6241 /* 70 */ NULL
, NULL
, NULL
, NULL
,
6242 /* 74 */ NULL
, NULL
, NULL
, NULL
,
6243 /* 78 */ NULL
, NULL
, NULL
, NULL
,
6244 /* 7C */ NULL
, NULL
, NULL
, NULL
,
6245 /* 80 */ NULL
, NULL
, NULL
, NULL
,
6246 /* 84 */ NULL
, NULL
, NULL
, NULL
,
6247 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
6248 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
6249 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
6250 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
6251 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
6252 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
6253 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
6254 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
6255 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
6256 /* AC */ NULL
, NULL
, "pfacc", NULL
,
6257 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
6258 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
6259 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
6260 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
6261 /* C0 */ NULL
, NULL
, NULL
, NULL
,
6262 /* C4 */ NULL
, NULL
, NULL
, NULL
,
6263 /* C8 */ NULL
, NULL
, NULL
, NULL
,
6264 /* CC */ NULL
, NULL
, NULL
, NULL
,
6265 /* D0 */ NULL
, NULL
, NULL
, NULL
,
6266 /* D4 */ NULL
, NULL
, NULL
, NULL
,
6267 /* D8 */ NULL
, NULL
, NULL
, NULL
,
6268 /* DC */ NULL
, NULL
, NULL
, NULL
,
6269 /* E0 */ NULL
, NULL
, NULL
, NULL
,
6270 /* E4 */ NULL
, NULL
, NULL
, NULL
,
6271 /* E8 */ NULL
, NULL
, NULL
, NULL
,
6272 /* EC */ NULL
, NULL
, NULL
, NULL
,
6273 /* F0 */ NULL
, NULL
, NULL
, NULL
,
6274 /* F4 */ NULL
, NULL
, NULL
, NULL
,
6275 /* F8 */ NULL
, NULL
, NULL
, NULL
,
6276 /* FC */ NULL
, NULL
, NULL
, NULL
,
6280 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6282 const char *mnemonic
;
6284 fetch_data(the_info
, codep
+ 1);
6285 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6286 place where an 8-bit immediate would normally go. ie. the last
6287 byte of the instruction. */
6288 obufp
= obuf
+ strlen (obuf
);
6289 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
6294 /* Since a variable sized modrm/sib chunk is between the start
6295 of the opcode (0x0f0f) and the opcode suffix, we need to do
6296 all the modrm processing first, and don't know until now that
6297 we have a bad opcode. This necessitates some cleaning up. */
6298 op_out
[0][0] = '\0';
6299 op_out
[1][0] = '\0';
6304 static const char *simd_cmp_op
[] = {
6316 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
6318 unsigned int cmp_type
;
6320 fetch_data(the_info
, codep
+ 1);
6321 obufp
= obuf
+ strlen (obuf
);
6322 cmp_type
= *codep
++ & 0xff;
6325 char suffix1
= 'p', suffix2
= 's';
6326 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6327 if (prefixes
& PREFIX_REPZ
)
6331 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6332 if (prefixes
& PREFIX_DATA
)
6336 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
6337 if (prefixes
& PREFIX_REPNZ
)
6338 suffix1
= 's', suffix2
= 'd';
6341 snprintf (scratchbuf
, sizeof(scratchbuf
), "cmp%s%c%c",
6342 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
6343 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
6344 oappend (scratchbuf
);
6348 /* We have a bad extension byte. Clean up. */
6349 op_out
[0][0] = '\0';
6350 op_out
[1][0] = '\0';
6356 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
6358 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6359 forms of these instructions. */
6362 char *p
= obuf
+ strlen (obuf
);
6365 *(p
- 1) = *(p
- 2);
6366 *(p
- 2) = *(p
- 3);
6367 *(p
- 3) = extrachar
;
6372 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6374 if (modrm
.mod
== 3 && modrm
.reg
== 1 && modrm
.rm
<= 1)
6376 /* Override "sidt". */
6377 size_t olen
= strlen (obuf
);
6378 char *p
= obuf
+ olen
- 4;
6379 const char * const *names
= (address_mode
== mode_64bit
6380 ? names64
: names32
);
6382 /* We might have a suffix when disassembling with -Msuffix. */
6386 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6388 && (prefixes
& PREFIX_ADDR
)
6391 && strncmp (p
- 7, "addr", 4) == 0
6392 && (strncmp (p
- 3, "16", 2) == 0
6393 || strncmp (p
- 3, "32", 2) == 0))
6398 /* mwait %eax,%ecx */
6399 strcpy (p
, "mwait");
6401 strcpy (op_out
[0], names
[0]);
6405 /* monitor %eax,%ecx,%edx" */
6406 strcpy (p
, "monitor");
6409 const char * const *op1_names
;
6410 if (!(prefixes
& PREFIX_ADDR
))
6411 op1_names
= (address_mode
== mode_16bit
6415 op1_names
= (address_mode
!= mode_32bit
6416 ? names32
: names16
);
6417 used_prefixes
|= PREFIX_ADDR
;
6419 strcpy (op_out
[0], op1_names
[0]);
6420 strcpy (op_out
[2], names
[2]);
6425 strcpy (op_out
[1], names
[1]);
6436 SVME_Fixup (int bytemode
, int sizeflag
)
6468 OP_M (bytemode
, sizeflag
);
6471 /* Override "lidt". */
6472 p
= obuf
+ strlen (obuf
) - 4;
6473 /* We might have a suffix. */
6477 if (!(prefixes
& PREFIX_ADDR
))
6482 used_prefixes
|= PREFIX_ADDR
;
6486 strcpy (op_out
[1], names32
[1]);
6492 *obufp
++ = open_char
;
6493 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
6497 strcpy (obufp
, alt
);
6498 obufp
+= strlen (alt
);
6499 *obufp
++ = close_char
;
6506 INVLPG_Fixup (int bytemode
, int sizeflag
)
6519 OP_M (bytemode
, sizeflag
);
6522 /* Override "invlpg". */
6523 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
6530 /* Throw away prefixes and 1st. opcode byte. */
6531 codep
= insn_codep
+ 1;
6536 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
6543 /* Override "sgdt". */
6544 char *p
= obuf
+ strlen (obuf
) - 4;
6546 /* We might have a suffix when disassembling with -Msuffix. */
6553 strcpy (p
, "vmcall");
6556 strcpy (p
, "vmlaunch");
6559 strcpy (p
, "vmresume");
6562 strcpy (p
, "vmxoff");
6573 OP_VMX (int bytemode
, int sizeflag
)
6575 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
6576 if (prefixes
& PREFIX_DATA
)
6577 strcpy (obuf
, "vmclear");
6578 else if (prefixes
& PREFIX_REPZ
)
6579 strcpy (obuf
, "vmxon");
6581 strcpy (obuf
, "vmptrld");
6582 OP_E (bytemode
, sizeflag
);
6586 REP_Fixup (int bytemode
, int sizeflag
)
6588 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6592 if (prefixes
& PREFIX_REPZ
)
6593 switch (*insn_codep
)
6595 case 0x6e: /* outsb */
6596 case 0x6f: /* outsw/outsl */
6597 case 0xa4: /* movsb */
6598 case 0xa5: /* movsw/movsl/movsq */
6604 case 0xaa: /* stosb */
6605 case 0xab: /* stosw/stosl/stosq */
6606 case 0xac: /* lodsb */
6607 case 0xad: /* lodsw/lodsl/lodsq */
6608 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
6613 case 0x6c: /* insb */
6614 case 0x6d: /* insl/insw */
6630 olen
= strlen (obuf
);
6631 p
= obuf
+ olen
- ilen
- 1 - 4;
6632 /* Handle "repz [addr16|addr32]". */
6633 if ((prefixes
& PREFIX_ADDR
))
6636 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
6644 OP_IMREG (bytemode
, sizeflag
);
6647 OP_ESreg (bytemode
, sizeflag
);
6650 OP_DSreg (bytemode
, sizeflag
);
6659 CMPXCHG8B_Fixup (int bytemode
, int sizeflag
)
6664 /* Change cmpxchg8b to cmpxchg16b. */
6665 char *p
= obuf
+ strlen (obuf
) - 2;
6669 OP_M (bytemode
, sizeflag
);
6673 XMM_Fixup (int reg
, int sizeflag ATTRIBUTE_UNUSED
)
6675 snprintf (scratchbuf
, sizeof(scratchbuf
), "%%xmm%d", reg
);
6676 oappend (scratchbuf
+ intel_syntax
);
6680 CRC32_Fixup (int bytemode
, int sizeflag
)
6682 /* Add proper suffix to "crc32". */
6683 char *p
= obuf
+ strlen (obuf
);
6700 else if (sizeflag
& DFLAG
)
6704 used_prefixes
|= (prefixes
& PREFIX_DATA
);
6707 oappend (INTERNAL_DISASSEMBLER_ERROR
);
6716 /* Skip mod/rm byte. */
6721 add
= (rex
& REX_B
) ? 8 : 0;
6722 if (bytemode
== b_mode
)
6726 oappend (names8rex
[modrm
.rm
+ add
]);
6728 oappend (names8
[modrm
.rm
+ add
]);
6734 oappend (names64
[modrm
.rm
+ add
]);
6735 else if ((prefixes
& PREFIX_DATA
))
6736 oappend (names16
[modrm
.rm
+ add
]);
6738 oappend (names32
[modrm
.rm
+ add
]);
6742 OP_E (bytemode
, sizeflag
);