blob: 926f776de88a79c1a2a90fc0d65f94c6ca08ac66 [file] [log] [blame]
/* Print i386 instructions for GDB, the GNU debugger.
Copyright (C) 1988-2021 Free Software Foundation, Inc.
This file is part of the GNU opcodes library.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
July 1988
modified by John Hassey (hassey@dg-rtp.dg.com)
x86-64 support added by Jan Hubicka (jh@suse.cz)
VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
/* The main tables describing the instructions is essentially a copy
of the "Opcode Map" chapter (Appendix A) of the Intel 80386
Programmers Manual. Usually, there is a capital letter, followed
by a small letter. The capital letter tell the addressing mode,
and the small letter tells about the operand size. Refer to
the Intel manual for details. */
#include "sysdep.h"
#include "disassemble.h"
#include "opintl.h"
#include "opcode/i386.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include <setjmp.h>
static int print_insn (bfd_vma, disassemble_info *);
static void dofloat (int);
static void OP_ST (int, int);
static void OP_STi (int, int);
static int putop (const char *, int);
static void oappend (const char *);
static void append_seg (void);
static void OP_indirE (int, int);
static void print_operand_value (char *, int, bfd_vma);
static void OP_E_memory (int, int);
static void print_displacement (char *, bfd_vma);
static void OP_E (int, int);
static void OP_G (int, int);
static bfd_vma get64 (void);
static bfd_signed_vma get32 (void);
static bfd_signed_vma get32s (void);
static int get16 (void);
static void set_op (bfd_vma, int);
static void OP_Skip_MODRM (int, int);
static void OP_REG (int, int);
static void OP_IMREG (int, int);
static void OP_I (int, int);
static void OP_I64 (int, int);
static void OP_sI (int, int);
static void OP_J (int, int);
static void OP_SEG (int, int);
static void OP_DIR (int, int);
static void OP_OFF (int, int);
static void OP_OFF64 (int, int);
static void ptr_reg (int, int);
static void OP_ESreg (int, int);
static void OP_DSreg (int, int);
static void OP_C (int, int);
static void OP_D (int, int);
static void OP_T (int, int);
static void OP_MMX (int, int);
static void OP_XMM (int, int);
static void OP_EM (int, int);
static void OP_EX (int, int);
static void OP_EMC (int,int);
static void OP_MXC (int,int);
static void OP_MS (int, int);
static void OP_XS (int, int);
static void OP_M (int, int);
static void OP_VEX (int, int);
static void OP_VexR (int, int);
static void OP_VexW (int, int);
static void OP_Rounding (int, int);
static void OP_REG_VexI4 (int, int);
static void OP_VexI4 (int, int);
static void PCLMUL_Fixup (int, int);
static void VPCMP_Fixup (int, int);
static void VPCOM_Fixup (int, int);
static void OP_0f07 (int, int);
static void OP_Monitor (int, int);
static void OP_Mwait (int, int);
static void NOP_Fixup1 (int, int);
static void NOP_Fixup2 (int, int);
static void OP_3DNowSuffix (int, int);
static void CMP_Fixup (int, int);
static void BadOp (void);
static void REP_Fixup (int, int);
static void SEP_Fixup (int, int);
static void BND_Fixup (int, int);
static void NOTRACK_Fixup (int, int);
static void HLE_Fixup1 (int, int);
static void HLE_Fixup2 (int, int);
static void HLE_Fixup3 (int, int);
static void CMPXCHG8B_Fixup (int, int);
static void XMM_Fixup (int, int);
static void FXSAVE_Fixup (int, int);
static void MOVSXD_Fixup (int, int);
static void DistinctDest_Fixup (int, int);
struct dis_private {
/* Points to first byte not fetched. */
bfd_byte *max_fetched;
bfd_byte the_buffer[MAX_MNEM_SIZE];
bfd_vma insn_start;
int orig_sizeflag;
OPCODES_SIGJMP_BUF bailout;
};
enum address_mode
{
mode_16bit,
mode_32bit,
mode_64bit
};
enum address_mode address_mode;
/* Flags for the prefixes for the current instruction. See below. */
static int prefixes;
/* REX prefix the current instruction. See below. */
static int rex;
/* Bits of REX we've already used. */
static int rex_used;
/* Mark parts used in the REX prefix. When we are testing for
empty prefix (for 8bit register REX extension), just mask it
out. Otherwise test for REX bit is excuse for existence of REX
only in case value is nonzero. */
#define USED_REX(value) \
{ \
if (value) \
{ \
if ((rex & value)) \
rex_used |= (value) | REX_OPCODE; \
} \
else \
rex_used |= REX_OPCODE; \
}
/* Flags for prefixes which we somehow handled when printing the
current instruction. */
static int used_prefixes;
/* Flags for EVEX bits which we somehow handled when printing the
current instruction. */
#define EVEX_b_used 1
static int evex_used;
/* Flags stored in PREFIXES. */
#define PREFIX_REPZ 1
#define PREFIX_REPNZ 2
#define PREFIX_LOCK 4
#define PREFIX_CS 8
#define PREFIX_SS 0x10
#define PREFIX_DS 0x20
#define PREFIX_ES 0x40
#define PREFIX_FS 0x80
#define PREFIX_GS 0x100
#define PREFIX_DATA 0x200
#define PREFIX_ADDR 0x400
#define PREFIX_FWAIT 0x800
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */
#define FETCH_DATA(info, addr) \
((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
? 1 : fetch_data ((info), (addr)))
static int
fetch_data (struct disassemble_info *info, bfd_byte *addr)
{
int status;
struct dis_private *priv = (struct dis_private *) info->private_data;
bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
status = (*info->read_memory_func) (start,
priv->max_fetched,
addr - priv->max_fetched,
info);
else
status = -1;
if (status != 0)
{
/* If we did manage to read at least one byte, then
print_insn_i386 will do something sensible. Otherwise, print
an error. We do that here because this is where we know
STATUS. */
if (priv->max_fetched == priv->the_buffer)
(*info->memory_error_func) (status, start, info);
OPCODES_SIGLONGJMP (priv->bailout, 1);
}
else
priv->max_fetched = addr;
return 1;
}
/* Possible values for prefix requirement. */
#define PREFIX_IGNORED_SHIFT 16
#define PREFIX_IGNORED_REPZ (PREFIX_REPZ << PREFIX_IGNORED_SHIFT)
#define PREFIX_IGNORED_REPNZ (PREFIX_REPNZ << PREFIX_IGNORED_SHIFT)
#define PREFIX_IGNORED_DATA (PREFIX_DATA << PREFIX_IGNORED_SHIFT)
#define PREFIX_IGNORED_ADDR (PREFIX_ADDR << PREFIX_IGNORED_SHIFT)
#define PREFIX_IGNORED_LOCK (PREFIX_LOCK << PREFIX_IGNORED_SHIFT)
/* Opcode prefixes. */
#define PREFIX_OPCODE (PREFIX_REPZ \
| PREFIX_REPNZ \
| PREFIX_DATA)
/* Prefixes ignored. */
#define PREFIX_IGNORED (PREFIX_IGNORED_REPZ \
| PREFIX_IGNORED_REPNZ \
| PREFIX_IGNORED_DATA)
#define XX { NULL, 0 }
#define Bad_Opcode NULL, { { NULL, 0 } }, 0
#define Eb { OP_E, b_mode }
#define Ebnd { OP_E, bnd_mode }
#define EbS { OP_E, b_swap_mode }
#define EbndS { OP_E, bnd_swap_mode }
#define Ev { OP_E, v_mode }
#define Eva { OP_E, va_mode }
#define Ev_bnd { OP_E, v_bnd_mode }
#define EvS { OP_E, v_swap_mode }
#define Ed { OP_E, d_mode }
#define Edq { OP_E, dq_mode }
#define Edb { OP_E, db_mode }
#define Edw { OP_E, dw_mode }
#define Eq { OP_E, q_mode }
#define indirEv { OP_indirE, indir_v_mode }
#define indirEp { OP_indirE, f_mode }
#define stackEv { OP_E, stack_v_mode }
#define Em { OP_E, m_mode }
#define Ew { OP_E, w_mode }
#define M { OP_M, 0 } /* lea, lgdt, etc. */
#define Ma { OP_M, a_mode }
#define Mb { OP_M, b_mode }
#define Md { OP_M, d_mode }
#define Mo { OP_M, o_mode }
#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
#define Mq { OP_M, q_mode }
#define Mv { OP_M, v_mode }
#define Mv_bnd { OP_M, v_bndmk_mode }
#define Mx { OP_M, x_mode }
#define Mxmm { OP_M, xmm_mode }
#define Gb { OP_G, b_mode }
#define Gbnd { OP_G, bnd_mode }
#define Gv { OP_G, v_mode }
#define Gd { OP_G, d_mode }
#define Gdq { OP_G, dq_mode }
#define Gm { OP_G, m_mode }
#define Gva { OP_G, va_mode }
#define Gw { OP_G, w_mode }
#define Ib { OP_I, b_mode }
#define sIb { OP_sI, b_mode } /* sign extened byte */
#define sIbT { OP_sI, b_T_mode } /* sign extened byte like 'T' */
#define Iv { OP_I, v_mode }
#define sIv { OP_sI, v_mode }
#define Iv64 { OP_I64, v_mode }
#define Id { OP_I, d_mode }
#define Iw { OP_I, w_mode }
#define I1 { OP_I, const_1_mode }
#define Jb { OP_J, b_mode }
#define Jv { OP_J, v_mode }
#define Jdqw { OP_J, dqw_mode }
#define Cm { OP_C, m_mode }
#define Dm { OP_D, m_mode }
#define Td { OP_T, d_mode }
#define Skip_MODRM { OP_Skip_MODRM, 0 }
#define RMeAX { OP_REG, eAX_reg }
#define RMeBX { OP_REG, eBX_reg }
#define RMeCX { OP_REG, eCX_reg }
#define RMeDX { OP_REG, eDX_reg }
#define RMeSP { OP_REG, eSP_reg }
#define RMeBP { OP_REG, eBP_reg }
#define RMeSI { OP_REG, eSI_reg }
#define RMeDI { OP_REG, eDI_reg }
#define RMrAX { OP_REG, rAX_reg }
#define RMrBX { OP_REG, rBX_reg }
#define RMrCX { OP_REG, rCX_reg }
#define RMrDX { OP_REG, rDX_reg }
#define RMrSP { OP_REG, rSP_reg }
#define RMrBP { OP_REG, rBP_reg }
#define RMrSI { OP_REG, rSI_reg }
#define RMrDI { OP_REG, rDI_reg }
#define RMAL { OP_REG, al_reg }
#define RMCL { OP_REG, cl_reg }
#define RMDL { OP_REG, dl_reg }
#define RMBL { OP_REG, bl_reg }
#define RMAH { OP_REG, ah_reg }
#define RMCH { OP_REG, ch_reg }
#define RMDH { OP_REG, dh_reg }
#define RMBH { OP_REG, bh_reg }
#define RMAX { OP_REG, ax_reg }
#define RMDX { OP_REG, dx_reg }
#define eAX { OP_IMREG, eAX_reg }
#define AL { OP_IMREG, al_reg }
#define CL { OP_IMREG, cl_reg }
#define zAX { OP_IMREG, z_mode_ax_reg }
#define indirDX { OP_IMREG, indir_dx_reg }
#define Sw { OP_SEG, w_mode }
#define Sv { OP_SEG, v_mode }
#define Ap { OP_DIR, 0 }
#define Ob { OP_OFF64, b_mode }
#define Ov { OP_OFF64, v_mode }
#define Xb { OP_DSreg, eSI_reg }
#define Xv { OP_DSreg, eSI_reg }
#define Xz { OP_DSreg, eSI_reg }
#define Yb { OP_ESreg, eDI_reg }
#define Yv { OP_ESreg, eDI_reg }
#define DSBX { OP_DSreg, eBX_reg }
#define es { OP_REG, es_reg }
#define ss { OP_REG, ss_reg }
#define cs { OP_REG, cs_reg }
#define ds { OP_REG, ds_reg }
#define fs { OP_REG, fs_reg }
#define gs { OP_REG, gs_reg }
#define MX { OP_MMX, 0 }
#define XM { OP_XMM, 0 }
#define XMScalar { OP_XMM, scalar_mode }
#define XMGatherD { OP_XMM, vex_vsib_d_w_dq_mode }
#define XMGatherQ { OP_XMM, vex_vsib_q_w_dq_mode }
#define XMM { OP_XMM, xmm_mode }
#define TMM { OP_XMM, tmm_mode }
#define XMxmmq { OP_XMM, xmmq_mode }
#define EM { OP_EM, v_mode }
#define EMS { OP_EM, v_swap_mode }
#define EMd { OP_EM, d_mode }
#define EMx { OP_EM, x_mode }
#define EXbwUnit { OP_EX, bw_unit_mode }
#define EXb { OP_EX, b_mode }
#define EXw { OP_EX, w_mode }
#define EXd { OP_EX, d_mode }
#define EXdS { OP_EX, d_swap_mode }
#define EXwS { OP_EX, w_swap_mode }
#define EXq { OP_EX, q_mode }
#define EXqS { OP_EX, q_swap_mode }
#define EXdq { OP_EX, dq_mode }
#define EXx { OP_EX, x_mode }
#define EXxh { OP_EX, xh_mode }
#define EXxS { OP_EX, x_swap_mode }
#define EXxmm { OP_EX, xmm_mode }
#define EXymm { OP_EX, ymm_mode }
#define EXtmm { OP_EX, tmm_mode }
#define EXxmmq { OP_EX, xmmq_mode }
#define EXxmmqh { OP_EX, evex_half_bcst_xmmqh_mode }
#define EXEvexHalfBcstXmmq { OP_EX, evex_half_bcst_xmmq_mode }
#define EXxmmdw { OP_EX, xmmdw_mode }
#define EXxmmqd { OP_EX, xmmqd_mode }
#define EXxmmqdh { OP_EX, evex_half_bcst_xmmqdh_mode }
#define EXymmq { OP_EX, ymmq_mode }
#define EXEvexXGscat { OP_EX, evex_x_gscat_mode }
#define EXEvexXNoBcst { OP_EX, evex_x_nobcst_mode }
#define MS { OP_MS, v_mode }
#define XS { OP_XS, v_mode }
#define EMCq { OP_EMC, q_mode }
#define MXC { OP_MXC, 0 }
#define OPSUF { OP_3DNowSuffix, 0 }
#define SEP { SEP_Fixup, 0 }
#define CMP { CMP_Fixup, 0 }
#define XMM0 { XMM_Fixup, 0 }
#define FXSAVE { FXSAVE_Fixup, 0 }
#define Vex { OP_VEX, x_mode }
#define VexW { OP_VexW, x_mode }
#define VexScalar { OP_VEX, scalar_mode }
#define VexScalarR { OP_VexR, scalar_mode }
#define VexGatherD { OP_VEX, vex_vsib_d_w_dq_mode }
#define VexGatherQ { OP_VEX, vex_vsib_q_w_dq_mode }
#define VexGdq { OP_VEX, dq_mode }
#define VexTmm { OP_VEX, tmm_mode }
#define XMVexI4 { OP_REG_VexI4, x_mode }
#define XMVexScalarI4 { OP_REG_VexI4, scalar_mode }
#define VexI4 { OP_VexI4, 0 }
#define PCLMUL { PCLMUL_Fixup, 0 }
#define VPCMP { VPCMP_Fixup, 0 }
#define VPCOM { VPCOM_Fixup, 0 }
#define EXxEVexR { OP_Rounding, evex_rounding_mode }
#define EXxEVexR64 { OP_Rounding, evex_rounding_64_mode }
#define EXxEVexS { OP_Rounding, evex_sae_mode }
#define MaskG { OP_G, mask_mode }
#define MaskE { OP_E, mask_mode }
#define MaskBDE { OP_E, mask_bd_mode }
#define MaskVex { OP_VEX, mask_mode }
#define MVexVSIBDWpX { OP_M, vex_vsib_d_w_dq_mode }
#define MVexVSIBQWpX { OP_M, vex_vsib_q_w_dq_mode }
#define MVexSIBMEM { OP_M, vex_sibmem_mode }
/* Used handle "rep" prefix for string instructions. */
#define Xbr { REP_Fixup, eSI_reg }
#define Xvr { REP_Fixup, eSI_reg }
#define Ybr { REP_Fixup, eDI_reg }
#define Yvr { REP_Fixup, eDI_reg }
#define Yzr { REP_Fixup, eDI_reg }
#define indirDXr { REP_Fixup, indir_dx_reg }
#define ALr { REP_Fixup, al_reg }
#define eAXr { REP_Fixup, eAX_reg }
/* Used handle HLE prefix for lockable instructions. */
#define Ebh1 { HLE_Fixup1, b_mode }
#define Evh1 { HLE_Fixup1, v_mode }
#define Ebh2 { HLE_Fixup2, b_mode }
#define Evh2 { HLE_Fixup2, v_mode }
#define Ebh3 { HLE_Fixup3, b_mode }
#define Evh3 { HLE_Fixup3, v_mode }
#define BND { BND_Fixup, 0 }
#define NOTRACK { NOTRACK_Fixup, 0 }
#define cond_jump_flag { NULL, cond_jump_mode }
#define loop_jcxz_flag { NULL, loop_jcxz_mode }
/* bits in sizeflag */
#define SUFFIX_ALWAYS 4
#define AFLAG 2
#define DFLAG 1
enum
{
/* byte operand */
b_mode = 1,
/* byte operand with operand swapped */
b_swap_mode,
/* byte operand, sign extend like 'T' suffix */
b_T_mode,
/* operand size depends on prefixes */
v_mode,
/* operand size depends on prefixes with operand swapped */
v_swap_mode,
/* operand size depends on address prefix */
va_mode,
/* word operand */
w_mode,
/* double word operand */
d_mode,
/* word operand with operand swapped */
w_swap_mode,
/* double word operand with operand swapped */
d_swap_mode,
/* quad word operand */
q_mode,
/* quad word operand with operand swapped */
q_swap_mode,
/* ten-byte operand */
t_mode,
/* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
broadcast enabled. */
x_mode,
/* Similar to x_mode, but with different EVEX mem shifts. */
evex_x_gscat_mode,
/* Similar to x_mode, but with yet different EVEX mem shifts. */
bw_unit_mode,
/* Similar to x_mode, but with disabled broadcast. */
evex_x_nobcst_mode,
/* Similar to x_mode, but with operands swapped and disabled broadcast
in EVEX. */
x_swap_mode,
/* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
broadcast of 16bit enabled. */
xh_mode,
/* 16-byte XMM operand */
xmm_mode,
/* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
memory operand (depending on vector length). Broadcast isn't
allowed. */
xmmq_mode,
/* Same as xmmq_mode, but broadcast is allowed. */
evex_half_bcst_xmmq_mode,
/* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
memory operand (depending on vector length). 16bit broadcast. */
evex_half_bcst_xmmqh_mode,
/* 16-byte XMM, word, double word or quad word operand. */
xmmdw_mode,
/* 16-byte XMM, double word, quad word operand or xmm word operand. */
xmmqd_mode,
/* 16-byte XMM, double word, quad word operand or xmm word operand.
16bit broadcast. */
evex_half_bcst_xmmqdh_mode,
/* 32-byte YMM operand */
ymm_mode,
/* quad word, ymmword or zmmword memory operand. */
ymmq_mode,
/* 32-byte YMM or 16-byte word operand */
ymmxmm_mode,
/* TMM operand */
tmm_mode,
/* d_mode in 32bit, q_mode in 64bit mode. */
m_mode,
/* pair of v_mode operands */
a_mode,
cond_jump_mode,
loop_jcxz_mode,
movsxd_mode,
v_bnd_mode,
/* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */
v_bndmk_mode,
/* operand size depends on REX.W / VEX.W. */
dq_mode,
/* Displacements like v_mode without considering Intel64 ISA. */
dqw_mode,
/* bounds operand */
bnd_mode,
/* bounds operand with operand swapped */
bnd_swap_mode,
/* 4- or 6-byte pointer operand */
f_mode,
const_1_mode,
/* v_mode for indirect branch opcodes. */
indir_v_mode,
/* v_mode for stack-related opcodes. */
stack_v_mode,
/* non-quad operand size depends on prefixes */
z_mode,
/* 16-byte operand */
o_mode,
/* registers like d_mode, memory like b_mode. */
db_mode,
/* registers like d_mode, memory like w_mode. */
dw_mode,
/* Operand size depends on the VEX.W bit, with VSIB dword indices. */
vex_vsib_d_w_dq_mode,
/* Operand size depends on the VEX.W bit, with VSIB qword indices. */
vex_vsib_q_w_dq_mode,
/* mandatory non-vector SIB. */
vex_sibmem_mode,
/* scalar, ignore vector length. */
scalar_mode,
/* Static rounding. */
evex_rounding_mode,
/* Static rounding, 64-bit mode only. */
evex_rounding_64_mode,
/* Supress all exceptions. */
evex_sae_mode,
/* Mask register operand. */
mask_mode,
/* Mask register operand. */
mask_bd_mode,
es_reg,
cs_reg,
ss_reg,
ds_reg,
fs_reg,
gs_reg,
eAX_reg,
eCX_reg,
eDX_reg,
eBX_reg,
eSP_reg,
eBP_reg,
eSI_reg,
eDI_reg,
al_reg,
cl_reg,
dl_reg,
bl_reg,
ah_reg,
ch_reg,
dh_reg,
bh_reg,
ax_reg,
cx_reg,
dx_reg,
bx_reg,
sp_reg,
bp_reg,
si_reg,
di_reg,
rAX_reg,
rCX_reg,
rDX_reg,
rBX_reg,
rSP_reg,
rBP_reg,
rSI_reg,
rDI_reg,
z_mode_ax_reg,
indir_dx_reg
};
enum
{
FLOATCODE = 1,
USE_REG_TABLE,
USE_MOD_TABLE,
USE_RM_TABLE,
USE_PREFIX_TABLE,
USE_X86_64_TABLE,
USE_3BYTE_TABLE,
USE_XOP_8F_TABLE,
USE_VEX_C4_TABLE,
USE_VEX_C5_TABLE,
USE_VEX_LEN_TABLE,
USE_VEX_W_TABLE,
USE_EVEX_TABLE,
USE_EVEX_LEN_TABLE
};
#define FLOAT NULL, { { NULL, FLOATCODE } }, 0
#define DIS386(T, I) NULL, { { NULL, (T)}, { NULL, (I) } }, 0
#define DIS386_PREFIX(T, I, P) NULL, { { NULL, (T)}, { NULL, (I) } }, P
#define REG_TABLE(I) DIS386 (USE_REG_TABLE, (I))
#define MOD_TABLE(I) DIS386 (USE_MOD_TABLE, (I))
#define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I))
#define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I))
#define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I))
#define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I))
#define THREE_BYTE_TABLE_PREFIX(I, P) DIS386_PREFIX (USE_3BYTE_TABLE, (I), P)
#define XOP_8F_TABLE(I) DIS386 (USE_XOP_8F_TABLE, (I))
#define VEX_C4_TABLE(I) DIS386 (USE_VEX_C4_TABLE, (I))
#define VEX_C5_TABLE(I) DIS386 (USE_VEX_C5_TABLE, (I))
#define VEX_LEN_TABLE(I) DIS386 (USE_VEX_LEN_TABLE, (I))
#define VEX_W_TABLE(I) DIS386 (USE_VEX_W_TABLE, (I))
#define EVEX_TABLE(I) DIS386 (USE_EVEX_TABLE, (I))
#define EVEX_LEN_TABLE(I) DIS386 (USE_EVEX_LEN_TABLE, (I))
enum
{
REG_80 = 0,
REG_81,
REG_83,
REG_8F,
REG_C0,
REG_C1,
REG_C6,
REG_C7,
REG_D0,
REG_D1,
REG_D2,
REG_D3,
REG_F6,
REG_F7,
REG_FE,
REG_FF,
REG_0F00,
REG_0F01,
REG_0F0D,
REG_0F18,
REG_0F1C_P_0_MOD_0,
REG_0F1E_P_1_MOD_3,
REG_0F38D8_PREFIX_1,
REG_0F3A0F_PREFIX_1_MOD_3,
REG_0F71_MOD_0,
REG_0F72_MOD_0,
REG_0F73_MOD_0,
REG_0FA6,
REG_0FA7,
REG_0FAE,
REG_0FBA,
REG_0FC7,
REG_VEX_0F71_M_0,
REG_VEX_0F72_M_0,
REG_VEX_0F73_M_0,
REG_VEX_0FAE,
REG_VEX_0F3849_X86_64_P_0_W_0_M_1,
REG_VEX_0F38F3_L_0,
REG_XOP_09_01_L_0,
REG_XOP_09_02_L_0,
REG_XOP_09_12_M_1_L_0,
REG_XOP_0A_12_L_0,
REG_EVEX_0F71,
REG_EVEX_0F72,
REG_EVEX_0F73,
REG_EVEX_0F38C6_M_0_L_2,
REG_EVEX_0F38C7_M_0_L_2
};
enum
{
MOD_62_32BIT = 0,
MOD_8D,
MOD_C4_32BIT,
MOD_C5_32BIT,
MOD_C6_REG_7,
MOD_C7_REG_7,
MOD_FF_REG_3,
MOD_FF_REG_5,
MOD_0F01_REG_0,
MOD_0F01_REG_1,
MOD_0F01_REG_2,
MOD_0F01_REG_3,
MOD_0F01_REG_5,
MOD_0F01_REG_7,
MOD_0F12_PREFIX_0,
MOD_0F12_PREFIX_2,
MOD_0F13,
MOD_0F16_PREFIX_0,
MOD_0F16_PREFIX_2,
MOD_0F17,
MOD_0F18_REG_0,
MOD_0F18_REG_1,
MOD_0F18_REG_2,
MOD_0F18_REG_3,
MOD_0F1A_PREFIX_0,
MOD_0F1B_PREFIX_0,
MOD_0F1B_PREFIX_1,
MOD_0F1C_PREFIX_0,
MOD_0F1E_PREFIX_1,
MOD_0F2B_PREFIX_0,
MOD_0F2B_PREFIX_1,
MOD_0F2B_PREFIX_2,
MOD_0F2B_PREFIX_3,
MOD_0F50,
MOD_0F71,
MOD_0F72,
MOD_0F73,
MOD_0FAE_REG_0,
MOD_0FAE_REG_1,
MOD_0FAE_REG_2,
MOD_0FAE_REG_3,
MOD_0FAE_REG_4,
MOD_0FAE_REG_5,
MOD_0FAE_REG_6,
MOD_0FAE_REG_7,
MOD_0FB2,
MOD_0FB4,
MOD_0FB5,
MOD_0FC3,
MOD_0FC7_REG_3,
MOD_0FC7_REG_4,
MOD_0FC7_REG_5,
MOD_0FC7_REG_6,
MOD_0FC7_REG_7,
MOD_0FD7,
MOD_0FE7_PREFIX_2,
MOD_0FF0_PREFIX_3,
MOD_0F382A,
MOD_0F38DC_PREFIX_1,
MOD_0F38DD_PREFIX_1,
MOD_0F38DE_PREFIX_1,
MOD_0F38DF_PREFIX_1,
MOD_0F38F5,
MOD_0F38F6_PREFIX_0,
MOD_0F38F8_PREFIX_1,
MOD_0F38F8_PREFIX_2,
MOD_0F38F8_PREFIX_3,
MOD_0F38F9,
MOD_0F38FA_PREFIX_1,
MOD_0F38FB_PREFIX_1,
MOD_0F3A0F_PREFIX_1,
MOD_VEX_0F12_PREFIX_0,
MOD_VEX_0F12_PREFIX_2,
MOD_VEX_0F13,
MOD_VEX_0F16_PREFIX_0,
MOD_VEX_0F16_PREFIX_2,
MOD_VEX_0F17,
MOD_VEX_0F2B,
MOD_VEX_0F41_L_1,
MOD_VEX_0F42_L_1,
MOD_VEX_0F44_L_0,
MOD_VEX_0F45_L_1,
MOD_VEX_0F46_L_1,
MOD_VEX_0F47_L_1,
MOD_VEX_0F4A_L_1,
MOD_VEX_0F4B_L_1,
MOD_VEX_0F50,
MOD_VEX_0F71,
MOD_VEX_0F72,
MOD_VEX_0F73,
MOD_VEX_0F91_L_0,
MOD_VEX_0F92_L_0,
MOD_VEX_0F93_L_0,
MOD_VEX_0F98_L_0,
MOD_VEX_0F99_L_0,
MOD_VEX_0FAE_REG_2,
MOD_VEX_0FAE_REG_3,
MOD_VEX_0FD7,
MOD_VEX_0FE7,
MOD_VEX_0FF0_PREFIX_3,
MOD_VEX_0F381A,
MOD_VEX_0F382A,
MOD_VEX_0F382C,
MOD_VEX_0F382D,
MOD_VEX_0F382E,
MOD_VEX_0F382F,
MOD_VEX_0F3849_X86_64_P_0_W_0,
MOD_VEX_0F3849_X86_64_P_2_W_0,
MOD_VEX_0F3849_X86_64_P_3_W_0,
MOD_VEX_0F384B_X86_64_P_1_W_0,
MOD_VEX_0F384B_X86_64_P_2_W_0,
MOD_VEX_0F384B_X86_64_P_3_W_0,
MOD_VEX_0F385A,
MOD_VEX_0F385C_X86_64_P_1_W_0,
MOD_VEX_0F385E_X86_64_P_0_W_0,
MOD_VEX_0F385E_X86_64_P_1_W_0,
MOD_VEX_0F385E_X86_64_P_2_W_0,
MOD_VEX_0F385E_X86_64_P_3_W_0,
MOD_VEX_0F388C,
MOD_VEX_0F388E,
MOD_VEX_0F3A30_L_0,
MOD_VEX_0F3A31_L_0,
MOD_VEX_0F3A32_L_0,
MOD_VEX_0F3A33_L_0,
MOD_XOP_09_12,
MOD_EVEX_0F12_PREFIX_0,
MOD_EVEX_0F12_PREFIX_2,
MOD_EVEX_0F13,
MOD_EVEX_0F16_PREFIX_0,
MOD_EVEX_0F16_PREFIX_2,
MOD_EVEX_0F17,
MOD_EVEX_0F2B,
MOD_EVEX_0F381A,
MOD_EVEX_0F381B,
MOD_EVEX_0F3828_P_1,
MOD_EVEX_0F382A_P_1_W_1,
MOD_EVEX_0F3838_P_1,
MOD_EVEX_0F383A_P_1_W_0,
MOD_EVEX_0F385A,
MOD_EVEX_0F385B,
MOD_EVEX_0F387A_W_0,
MOD_EVEX_0F387B_W_0,
MOD_EVEX_0F387C,
MOD_EVEX_0F38C6,
MOD_EVEX_0F38C7,
};
enum
{
RM_C6_REG_7 = 0,
RM_C7_REG_7,
RM_0F01_REG_0,
RM_0F01_REG_1,
RM_0F01_REG_2,
RM_0F01_REG_3,
RM_0F01_REG_5_MOD_3,
RM_0F01_REG_7_MOD_3,
RM_0F1E_P_1_MOD_3_REG_7,
RM_0FAE_REG_6_MOD_3_P_0,
RM_0FAE_REG_7_MOD_3,
RM_0F3A0F_P_1_MOD_3_REG_0,
RM_VEX_0F3849_X86_64_P_0_W_0_M_1_R_0
};
enum
{
PREFIX_90 = 0,
PREFIX_0F01_REG_1_RM_4,
PREFIX_0F01_REG_1_RM_5,
PREFIX_0F01_REG_1_RM_6,
PREFIX_0F01_REG_1_RM_7,
PREFIX_0F01_REG_3_RM_1,
PREFIX_0F01_REG_5_MOD_0,
PREFIX_0F01_REG_5_MOD_3_RM_0,
PREFIX_0F01_REG_5_MOD_3_RM_1,
PREFIX_0F01_REG_5_MOD_3_RM_2,
PREFIX_0F01_REG_5_MOD_3_RM_4,
PREFIX_0F01_REG_5_MOD_3_RM_5,
PREFIX_0F01_REG_5_MOD_3_RM_6,
PREFIX_0F01_REG_5_MOD_3_RM_7,
PREFIX_0F01_REG_7_MOD_3_RM_2,
PREFIX_0F01_REG_7_MOD_3_RM_6,
PREFIX_0F01_REG_7_MOD_3_RM_7,
PREFIX_0F09,
PREFIX_0F10,
PREFIX_0F11,
PREFIX_0F12,
PREFIX_0F16,
PREFIX_0F1A,
PREFIX_0F1B,
PREFIX_0F1C,
PREFIX_0F1E,
PREFIX_0F2A,
PREFIX_0F2B,
PREFIX_0F2C,
PREFIX_0F2D,
PREFIX_0F2E,
PREFIX_0F2F,
PREFIX_0F51,
PREFIX_0F52,
PREFIX_0F53,
PREFIX_0F58,
PREFIX_0F59,
PREFIX_0F5A,
PREFIX_0F5B,
PREFIX_0F5C,
PREFIX_0F5D,
PREFIX_0F5E,
PREFIX_0F5F,
PREFIX_0F60,
PREFIX_0F61,
PREFIX_0F62,
PREFIX_0F6F,
PREFIX_0F70,
PREFIX_0F78,
PREFIX_0F79,
PREFIX_0F7C,
PREFIX_0F7D,
PREFIX_0F7E,
PREFIX_0F7F,
PREFIX_0FAE_REG_0_MOD_3,
PREFIX_0FAE_REG_1_MOD_3,
PREFIX_0FAE_REG_2_MOD_3,
PREFIX_0FAE_REG_3_MOD_3,
PREFIX_0FAE_REG_4_MOD_0,
PREFIX_0FAE_REG_4_MOD_3,
PREFIX_0FAE_REG_5_MOD_3,
PREFIX_0FAE_REG_6_MOD_0,
PREFIX_0FAE_REG_6_MOD_3,
PREFIX_0FAE_REG_7_MOD_0,
PREFIX_0FB8,
PREFIX_0FBC,
PREFIX_0FBD,
PREFIX_0FC2,
PREFIX_0FC7_REG_6_MOD_0,
PREFIX_0FC7_REG_6_MOD_3,
PREFIX_0FC7_REG_7_MOD_3,
PREFIX_0FD0,
PREFIX_0FD6,
PREFIX_0FE6,
PREFIX_0FE7,
PREFIX_0FF0,
PREFIX_0FF7,
PREFIX_0F38D8,
PREFIX_0F38DC,
PREFIX_0F38DD,
PREFIX_0F38DE,
PREFIX_0F38DF,
PREFIX_0F38F0,
PREFIX_0F38F1,
PREFIX_0F38F6,
PREFIX_0F38F8,
PREFIX_0F38FA,
PREFIX_0F38FB,
PREFIX_0F3A0F,
PREFIX_VEX_0F10,
PREFIX_VEX_0F11,
PREFIX_VEX_0F12,
PREFIX_VEX_0F16,
PREFIX_VEX_0F2A,
PREFIX_VEX_0F2C,
PREFIX_VEX_0F2D,
PREFIX_VEX_0F2E,
PREFIX_VEX_0F2F,
PREFIX_VEX_0F41_L_1_M_1_W_0,
PREFIX_VEX_0F41_L_1_M_1_W_1,
PREFIX_VEX_0F42_L_1_M_1_W_0,
PREFIX_VEX_0F42_L_1_M_1_W_1,
PREFIX_VEX_0F44_L_0_M_1_W_0,
PREFIX_VEX_0F44_L_0_M_1_W_1,
PREFIX_VEX_0F45_L_1_M_1_W_0,
PREFIX_VEX_0F45_L_1_M_1_W_1,
PREFIX_VEX_0F46_L_1_M_1_W_0,
PREFIX_VEX_0F46_L_1_M_1_W_1,
PREFIX_VEX_0F47_L_1_M_1_W_0,
PREFIX_VEX_0F47_L_1_M_1_W_1,
PREFIX_VEX_0F4A_L_1_M_1_W_0,
PREFIX_VEX_0F4A_L_1_M_1_W_1,
PREFIX_VEX_0F4B_L_1_M_1_W_0,
PREFIX_VEX_0F4B_L_1_M_1_W_1,
PREFIX_VEX_0F51,
PREFIX_VEX_0F52,
PREFIX_VEX_0F53,
PREFIX_VEX_0F58,
PREFIX_VEX_0F59,
PREFIX_VEX_0F5A,
PREFIX_VEX_0F5B,
PREFIX_VEX_0F5C,
PREFIX_VEX_0F5D,
PREFIX_VEX_0F5E,
PREFIX_VEX_0F5F,
PREFIX_VEX_0F6F,
PREFIX_VEX_0F70,
PREFIX_VEX_0F7C,
PREFIX_VEX_0F7D,
PREFIX_VEX_0F7E,
PREFIX_VEX_0F7F,
PREFIX_VEX_0F90_L_0_W_0,
PREFIX_VEX_0F90_L_0_W_1,
PREFIX_VEX_0F91_L_0_M_0_W_0,
PREFIX_VEX_0F91_L_0_M_0_W_1,
PREFIX_VEX_0F92_L_0_M_1_W_0,
PREFIX_VEX_0F92_L_0_M_1_W_1,
PREFIX_VEX_0F93_L_0_M_1_W_0,
PREFIX_VEX_0F93_L_0_M_1_W_1,
PREFIX_VEX_0F98_L_0_M_1_W_0,
PREFIX_VEX_0F98_L_0_M_1_W_1,
PREFIX_VEX_0F99_L_0_M_1_W_0,
PREFIX_VEX_0F99_L_0_M_1_W_1,
PREFIX_VEX_0FC2,
PREFIX_VEX_0FD0,
PREFIX_VEX_0FE6,
PREFIX_VEX_0FF0,
PREFIX_VEX_0F3849_X86_64,
PREFIX_VEX_0F384B_X86_64,
PREFIX_VEX_0F385C_X86_64,
PREFIX_VEX_0F385E_X86_64,
PREFIX_VEX_0F38F5_L_0,
PREFIX_VEX_0F38F6_L_0,
PREFIX_VEX_0F38F7_L_0,
PREFIX_VEX_0F3AF0_L_0,
PREFIX_EVEX_0F10,
PREFIX_EVEX_0F11,
PREFIX_EVEX_0F12,
PREFIX_EVEX_0F16,
PREFIX_EVEX_0F2A,
PREFIX_EVEX_0F51,
PREFIX_EVEX_0F58,
PREFIX_EVEX_0F59,
PREFIX_EVEX_0F5A,
PREFIX_EVEX_0F5B,
PREFIX_EVEX_0F5C,
PREFIX_EVEX_0F5D,
PREFIX_EVEX_0F5E,
PREFIX_EVEX_0F5F,
PREFIX_EVEX_0F6F,
PREFIX_EVEX_0F70,
PREFIX_EVEX_0F78,
PREFIX_EVEX_0F79,
PREFIX_EVEX_0F7A,
PREFIX_EVEX_0F7B,
PREFIX_EVEX_0F7E,
PREFIX_EVEX_0F7F,
PREFIX_EVEX_0FC2,
PREFIX_EVEX_0FE6,
PREFIX_EVEX_0F3810,
PREFIX_EVEX_0F3811,
PREFIX_EVEX_0F3812,
PREFIX_EVEX_0F3813,
PREFIX_EVEX_0F3814,
PREFIX_EVEX_0F3815,
PREFIX_EVEX_0F3820,
PREFIX_EVEX_0F3821,
PREFIX_EVEX_0F3822,
PREFIX_EVEX_0F3823,
PREFIX_EVEX_0F3824,
PREFIX_EVEX_0F3825,
PREFIX_EVEX_0F3826,
PREFIX_EVEX_0F3827,
PREFIX_EVEX_0F3828,
PREFIX_EVEX_0F3829,
PREFIX_EVEX_0F382A,
PREFIX_EVEX_0F3830,
PREFIX_EVEX_0F3831,
PREFIX_EVEX_0F3832,
PREFIX_EVEX_0F3833,
PREFIX_EVEX_0F3834,
PREFIX_EVEX_0F3835,
PREFIX_EVEX_0F3838,
PREFIX_EVEX_0F3839,
PREFIX_EVEX_0F383A,
PREFIX_EVEX_0F3852,
PREFIX_EVEX_0F3853,
PREFIX_EVEX_0F3868,
PREFIX_EVEX_0F3872,
PREFIX_EVEX_0F389A,
PREFIX_EVEX_0F389B,
PREFIX_EVEX_0F38AA,
PREFIX_EVEX_0F38AB,
PREFIX_EVEX_0F3A08_W_0,
PREFIX_EVEX_0F3A0A_W_0,
PREFIX_EVEX_0F3A26,
PREFIX_EVEX_0F3A27,
PREFIX_EVEX_0F3A56,
PREFIX_EVEX_0F3A57,
PREFIX_EVEX_0F3A66,
PREFIX_EVEX_0F3A67,
PREFIX_EVEX_0F3AC2,
PREFIX_EVEX_MAP5_10,
PREFIX_EVEX_MAP5_11,
PREFIX_EVEX_MAP5_1D,
PREFIX_EVEX_MAP5_2A,
PREFIX_EVEX_MAP5_2C,
PREFIX_EVEX_MAP5_2D,
PREFIX_EVEX_MAP5_2E,
PREFIX_EVEX_MAP5_2F,
PREFIX_EVEX_MAP5_51,
PREFIX_EVEX_MAP5_58,
PREFIX_EVEX_MAP5_59,
PREFIX_EVEX_MAP5_5A_W_0,
PREFIX_EVEX_MAP5_5A_W_1,
PREFIX_EVEX_MAP5_5B_W_0,
PREFIX_EVEX_MAP5_5B_W_1,
PREFIX_EVEX_MAP5_5C,
PREFIX_EVEX_MAP5_5D,
PREFIX_EVEX_MAP5_5E,
PREFIX_EVEX_MAP5_5F,
PREFIX_EVEX_MAP5_78,
PREFIX_EVEX_MAP5_79,
PREFIX_EVEX_MAP5_7A,
PREFIX_EVEX_MAP5_7B,
PREFIX_EVEX_MAP5_7C,
PREFIX_EVEX_MAP5_7D_W_0,
PREFIX_EVEX_MAP6_13,
PREFIX_EVEX_MAP6_56,
PREFIX_EVEX_MAP6_57,
PREFIX_EVEX_MAP6_D6,
PREFIX_EVEX_MAP6_D7,
};
enum
{
X86_64_06 = 0,
X86_64_07,
X86_64_0E,
X86_64_16,
X86_64_17,
X86_64_1E,
X86_64_1F,
X86_64_27,
X86_64_2F,
X86_64_37,
X86_64_3F,
X86_64_60,
X86_64_61,
X86_64_62,
X86_64_63,
X86_64_6D,
X86_64_6F,
X86_64_82,
X86_64_9A,
X86_64_C2,
X86_64_C3,
X86_64_C4,
X86_64_C5,
X86_64_CE,
X86_64_D4,
X86_64_D5,
X86_64_E8,
X86_64_E9,
X86_64_EA,
X86_64_0F01_REG_0,
X86_64_0F01_REG_1,
X86_64_0F01_REG_1_RM_5_PREFIX_2,
X86_64_0F01_REG_1_RM_6_PREFIX_2,
X86_64_0F01_REG_1_RM_7_PREFIX_2,
X86_64_0F01_REG_2,
X86_64_0F01_REG_3,
X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1,
X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1,
X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1,
X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1,
X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1,
X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3,
X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1,
X86_64_0F24,
X86_64_0F26,
X86_64_0FC7_REG_6_MOD_3_PREFIX_1,
X86_64_VEX_0F3849,
X86_64_VEX_0F384B,
X86_64_VEX_0F385C,
X86_64_VEX_0F385E
};
enum
{
THREE_BYTE_0F38 = 0,
THREE_BYTE_0F3A
};
enum
{
XOP_08 = 0,
XOP_09,
XOP_0A
};
enum
{
VEX_0F = 0,
VEX_0F38,
VEX_0F3A
};
enum
{
EVEX_0F = 0,
EVEX_0F38,
EVEX_0F3A,
EVEX_MAP5,
EVEX_MAP6,
};
enum
{
VEX_LEN_0F12_P_0_M_0 = 0,
VEX_LEN_0F12_P_0_M_1,
#define VEX_LEN_0F12_P_2_M_0 VEX_LEN_0F12_P_0_M_0
VEX_LEN_0F13_M_0,
VEX_LEN_0F16_P_0_M_0,
VEX_LEN_0F16_P_0_M_1,
#define VEX_LEN_0F16_P_2_M_0 VEX_LEN_0F16_P_0_M_0
VEX_LEN_0F17_M_0,
VEX_LEN_0F41,
VEX_LEN_0F42,
VEX_LEN_0F44,
VEX_LEN_0F45,
VEX_LEN_0F46,
VEX_LEN_0F47,
VEX_LEN_0F4A,
VEX_LEN_0F4B,
VEX_LEN_0F6E,
VEX_LEN_0F77,
VEX_LEN_0F7E_P_1,
VEX_LEN_0F7E_P_2,
VEX_LEN_0F90,
VEX_LEN_0F91,
VEX_LEN_0F92,
VEX_LEN_0F93,
VEX_LEN_0F98,
VEX_LEN_0F99,
VEX_LEN_0FAE_R_2_M_0,
VEX_LEN_0FAE_R_3_M_0,
VEX_LEN_0FC4,
VEX_LEN_0FC5,
VEX_LEN_0FD6,
VEX_LEN_0FF7,
VEX_LEN_0F3816,
VEX_LEN_0F3819,
VEX_LEN_0F381A_M_0,
VEX_LEN_0F3836,
VEX_LEN_0F3841,
VEX_LEN_0F3849_X86_64_P_0_W_0_M_0,
VEX_LEN_0F3849_X86_64_P_0_W_0_M_1_REG_0_RM_0,
VEX_LEN_0F3849_X86_64_P_2_W_0_M_0,
VEX_LEN_0F3849_X86_64_P_3_W_0_M_0,
VEX_LEN_0F384B_X86_64_P_1_W_0_M_0,
VEX_LEN_0F384B_X86_64_P_2_W_0_M_0,
VEX_LEN_0F384B_X86_64_P_3_W_0_M_0,
VEX_LEN_0F385A_M_0,
VEX_LEN_0F385C_X86_64_P_1_W_0_M_0,
VEX_LEN_0F385E_X86_64_P_0_W_0_M_0,
VEX_LEN_0F385E_X86_64_P_1_W_0_M_0,
VEX_LEN_0F385E_X86_64_P_2_W_0_M_0,
VEX_LEN_0F385E_X86_64_P_3_W_0_M_0,
VEX_LEN_0F38DB,
VEX_LEN_0F38F2,
VEX_LEN_0F38F3,
VEX_LEN_0F38F5,
VEX_LEN_0F38F6,
VEX_LEN_0F38F7,
VEX_LEN_0F3A00,
VEX_LEN_0F3A01,
VEX_LEN_0F3A06,
VEX_LEN_0F3A14,
VEX_LEN_0F3A15,
VEX_LEN_0F3A16,
VEX_LEN_0F3A17,
VEX_LEN_0F3A18,
VEX_LEN_0F3A19,
VEX_LEN_0F3A20,
VEX_LEN_0F3A21,
VEX_LEN_0F3A22,
VEX_LEN_0F3A30,
VEX_LEN_0F3A31,
VEX_LEN_0F3A32,
VEX_LEN_0F3A33,
VEX_LEN_0F3A38,
VEX_LEN_0F3A39,
VEX_LEN_0F3A41,
VEX_LEN_0F3A46,
VEX_LEN_0F3A60,
VEX_LEN_0F3A61,
VEX_LEN_0F3A62,
VEX_LEN_0F3A63,
VEX_LEN_0F3ADF,
VEX_LEN_0F3AF0,
VEX_LEN_0FXOP_08_85,
VEX_LEN_0FXOP_08_86,
VEX_LEN_0FXOP_08_87,
VEX_LEN_0FXOP_08_8E,
VEX_LEN_0FXOP_08_8F,
VEX_LEN_0FXOP_08_95,
VEX_LEN_0FXOP_08_96,
VEX_LEN_0FXOP_08_97,
VEX_LEN_0FXOP_08_9E,
VEX_LEN_0FXOP_08_9F,
VEX_LEN_0FXOP_08_A3,
VEX_LEN_0FXOP_08_A6,
VEX_LEN_0FXOP_08_B6,
VEX_LEN_0FXOP_08_C0,
VEX_LEN_0FXOP_08_C1,
VEX_LEN_0FXOP_08_C2,
VEX_LEN_0FXOP_08_C3,
VEX_LEN_0FXOP_08_CC,
VEX_LEN_0FXOP_08_CD,
VEX_LEN_0FXOP_08_CE,
VEX_LEN_0FXOP_08_CF,
VEX_LEN_0FXOP_08_EC,
VEX_LEN_0FXOP_08_ED,
VEX_LEN_0FXOP_08_EE,
VEX_LEN_0FXOP_08_EF,
VEX_LEN_0FXOP_09_01,
VEX_LEN_0FXOP_09_02,
VEX_LEN_0FXOP_09_12_M_1,
VEX_LEN_0FXOP_09_82_W_0,
VEX_LEN_0FXOP_09_83_W_0,
VEX_LEN_0FXOP_09_90,
VEX_LEN_0FXOP_09_91,
VEX_LEN_0FXOP_09_92,
VEX_LEN_0FXOP_09_93,
VEX_LEN_0FXOP_09_94,
VEX_LEN_0FXOP_09_95,
VEX_LEN_0FXOP_09_96,
VEX_LEN_0FXOP_09_97,
VEX_LEN_0FXOP_09_98,
VEX_LEN_0FXOP_09_99,
VEX_LEN_0FXOP_09_9A,
VEX_LEN_0FXOP_09_9B,
VEX_LEN_0FXOP_09_C1,
VEX_LEN_0FXOP_09_C2,
VEX_LEN_0FXOP_09_C3,
VEX_LEN_0FXOP_09_C6,
VEX_LEN_0FXOP_09_C7,
VEX_LEN_0FXOP_09_CB,
VEX_LEN_0FXOP_09_D1,
VEX_LEN_0FXOP_09_D2,
VEX_LEN_0FXOP_09_D3,
VEX_LEN_0FXOP_09_D6,
VEX_LEN_0FXOP_09_D7,
VEX_LEN_0FXOP_09_DB,
VEX_LEN_0FXOP_09_E1,
VEX_LEN_0FXOP_09_E2,
VEX_LEN_0FXOP_09_E3,
VEX_LEN_0FXOP_0A_12,
};
enum
{
EVEX_LEN_0F3816 = 0,
EVEX_LEN_0F3819,
EVEX_LEN_0F381A_M_0,
EVEX_LEN_0F381B_M_0,
EVEX_LEN_0F3836,
EVEX_LEN_0F385A_M_0,
EVEX_LEN_0F385B_M_0,
EVEX_LEN_0F38C6_M_0,
EVEX_LEN_0F38C7_M_0,
EVEX_LEN_0F3A00,
EVEX_LEN_0F3A01,
EVEX_LEN_0F3A18,
EVEX_LEN_0F3A19,
EVEX_LEN_0F3A1A,
EVEX_LEN_0F3A1B,
EVEX_LEN_0F3A23,
EVEX_LEN_0F3A38,
EVEX_LEN_0F3A39,
EVEX_LEN_0F3A3A,
EVEX_LEN_0F3A3B,
EVEX_LEN_0F3A43
};
enum
{
VEX_W_0F41_L_1_M_1 = 0,
VEX_W_0F42_L_1_M_1,
VEX_W_0F44_L_0_M_1,
VEX_W_0F45_L_1_M_1,
VEX_W_0F46_L_1_M_1,
VEX_W_0F47_L_1_M_1,
VEX_W_0F4A_L_1_M_1,
VEX_W_0F4B_L_1_M_1,
VEX_W_0F90_L_0,
VEX_W_0F91_L_0_M_0,
VEX_W_0F92_L_0_M_1,
VEX_W_0F93_L_0_M_1,
VEX_W_0F98_L_0_M_1,
VEX_W_0F99_L_0_M_1,
VEX_W_0F380C,
VEX_W_0F380D,
VEX_W_0F380E,
VEX_W_0F380F,
VEX_W_0F3813,
VEX_W_0F3816_L_1,
VEX_W_0F3818,
VEX_W_0F3819_L_1,
VEX_W_0F381A_M_0_L_1,
VEX_W_0F382C_M_0,
VEX_W_0F382D_M_0,
VEX_W_0F382E_M_0,
VEX_W_0F382F_M_0,
VEX_W_0F3836,
VEX_W_0F3846,
VEX_W_0F3849_X86_64_P_0,
VEX_W_0F3849_X86_64_P_2,
VEX_W_0F3849_X86_64_P_3,
VEX_W_0F384B_X86_64_P_1,
VEX_W_0F384B_X86_64_P_2,
VEX_W_0F384B_X86_64_P_3,
VEX_W_0F3850,
VEX_W_0F3851,
VEX_W_0F3852,
VEX_W_0F3853,
VEX_W_0F3858,
VEX_W_0F3859,
VEX_W_0F385A_M_0_L_0,
VEX_W_0F385C_X86_64_P_1,
VEX_W_0F385E_X86_64_P_0,
VEX_W_0F385E_X86_64_P_1,
VEX_W_0F385E_X86_64_P_2,
VEX_W_0F385E_X86_64_P_3,
VEX_W_0F3878,
VEX_W_0F3879,
VEX_W_0F38CF,
VEX_W_0F3A00_L_1,
VEX_W_0F3A01_L_1,
VEX_W_0F3A02,
VEX_W_0F3A04,
VEX_W_0F3A05,
VEX_W_0F3A06_L_1,
VEX_W_0F3A18_L_1,
VEX_W_0F3A19_L_1,
VEX_W_0F3A1D,
VEX_W_0F3A38_L_1,
VEX_W_0F3A39_L_1,
VEX_W_0F3A46_L_1,
VEX_W_0F3A4A,
VEX_W_0F3A4B,
VEX_W_0F3A4C,
VEX_W_0F3ACE,
VEX_W_0F3ACF,
VEX_W_0FXOP_08_85_L_0,
VEX_W_0FXOP_08_86_L_0,
VEX_W_0FXOP_08_87_L_0,
VEX_W_0FXOP_08_8E_L_0,
VEX_W_0FXOP_08_8F_L_0,
VEX_W_0FXOP_08_95_L_0,
VEX_W_0FXOP_08_96_L_0,
VEX_W_0FXOP_08_97_L_0,
VEX_W_0FXOP_08_9E_L_0,
VEX_W_0FXOP_08_9F_L_0,
VEX_W_0FXOP_08_A6_L_0,
VEX_W_0FXOP_08_B6_L_0,
VEX_W_0FXOP_08_C0_L_0,
VEX_W_0FXOP_08_C1_L_0,
VEX_W_0FXOP_08_C2_L_0,
VEX_W_0FXOP_08_C3_L_0,
VEX_W_0FXOP_08_CC_L_0,
VEX_W_0FXOP_08_CD_L_0,
VEX_W_0FXOP_08_CE_L_0,
VEX_W_0FXOP_08_CF_L_0,
VEX_W_0FXOP_08_EC_L_0,
VEX_W_0FXOP_08_ED_L_0,
VEX_W_0FXOP_08_EE_L_0,
VEX_W_0FXOP_08_EF_L_0,
VEX_W_0FXOP_09_80,
VEX_W_0FXOP_09_81,
VEX_W_0FXOP_09_82,
VEX_W_0FXOP_09_83,
VEX_W_0FXOP_09_C1_L_0,
VEX_W_0FXOP_09_C2_L_0,
VEX_W_0FXOP_09_C3_L_0,
VEX_W_0FXOP_09_C6_L_0,
VEX_W_0FXOP_09_C7_L_0,
VEX_W_0FXOP_09_CB_L_0,
VEX_W_0FXOP_09_D1_L_0,
VEX_W_0FXOP_09_D2_L_0,
VEX_W_0FXOP_09_D3_L_0,
VEX_W_0FXOP_09_D6_L_0,
VEX_W_0FXOP_09_D7_L_0,
VEX_W_0FXOP_09_DB_L_0,
VEX_W_0FXOP_09_E1_L_0,
VEX_W_0FXOP_09_E2_L_0,
VEX_W_0FXOP_09_E3_L_0,
EVEX_W_0F10_P_1,
EVEX_W_0F10_P_3,
EVEX_W_0F11_P_1,
EVEX_W_0F11_P_3,
EVEX_W_0F12_P_0_M_1,
EVEX_W_0F12_P_1,
EVEX_W_0F12_P_3,
EVEX_W_0F16_P_0_M_1,
EVEX_W_0F16_P_1,
EVEX_W_0F51_P_1,
EVEX_W_0F51_P_3,
EVEX_W_0F58_P_1,
EVEX_W_0F58_P_3,
EVEX_W_0F59_P_1,
EVEX_W_0F59_P_3,
EVEX_W_0F5A_P_0,
EVEX_W_0F5A_P_1,
EVEX_W_0F5A_P_2,
EVEX_W_0F5A_P_3,
EVEX_W_0F5B_P_0,
EVEX_W_0F5B_P_1,
EVEX_W_0F5B_P_2,
EVEX_W_0F5C_P_1,
EVEX_W_0F5C_P_3,
EVEX_W_0F5D_P_1,
EVEX_W_0F5D_P_3,
EVEX_W_0F5E_P_1,
EVEX_W_0F5E_P_3,
EVEX_W_0F5F_P_1,
EVEX_W_0F5F_P_3,
EVEX_W_0F62,
EVEX_W_0F66,
EVEX_W_0F6A,
EVEX_W_0F6B,
EVEX_W_0F6C,
EVEX_W_0F6D,
EVEX_W_0F6F_P_1,
EVEX_W_0F6F_P_2,
EVEX_W_0F6F_P_3,
EVEX_W_0F70_P_2,
EVEX_W_0F72_R_2,
EVEX_W_0F72_R_6,
EVEX_W_0F73_R_2,
EVEX_W_0F73_R_6,
EVEX_W_0F76,
EVEX_W_0F78_P_0,
EVEX_W_0F78_P_2,
EVEX_W_0F79_P_0,
EVEX_W_0F79_P_2,
EVEX_W_0F7A_P_1,
EVEX_W_0F7A_P_2,
EVEX_W_0F7A_P_3,
EVEX_W_0F7B_P_2,
EVEX_W_0F7E_P_1,
EVEX_W_0F7F_P_1,
EVEX_W_0F7F_P_2,
EVEX_W_0F7F_P_3,
EVEX_W_0FC2_P_1,
EVEX_W_0FC2_P_3,
EVEX_W_0FD2,
EVEX_W_0FD3,
EVEX_W_0FD4,
EVEX_W_0FD6,
EVEX_W_0FE6_P_1,
EVEX_W_0FE6_P_2,
EVEX_W_0FE6_P_3,
EVEX_W_0FE7,
EVEX_W_0FF2,
EVEX_W_0FF3,
EVEX_W_0FF4,
EVEX_W_0FFA,
EVEX_W_0FFB,
EVEX_W_0FFE,
EVEX_W_0F380D,
EVEX_W_0F3810_P_1,
EVEX_W_0F3810_P_2,
EVEX_W_0F3811_P_1,
EVEX_W_0F3811_P_2,
EVEX_W_0F3812_P_1,
EVEX_W_0F3812_P_2,
EVEX_W_0F3813_P_1,
EVEX_W_0F3813_P_2,
EVEX_W_0F3814_P_1,
EVEX_W_0F3815_P_1,
EVEX_W_0F3819_L_n,
EVEX_W_0F381A_M_0_L_n,
EVEX_W_0F381B_M_0_L_2,
EVEX_W_0F381E,
EVEX_W_0F381F,
EVEX_W_0F3820_P_1,
EVEX_W_0F3821_P_1,
EVEX_W_0F3822_P_1,
EVEX_W_0F3823_P_1,
EVEX_W_0F3824_P_1,
EVEX_W_0F3825_P_1,
EVEX_W_0F3825_P_2,
EVEX_W_0F3828_P_2,
EVEX_W_0F3829_P_2,
EVEX_W_0F382A_P_1,
EVEX_W_0F382A_P_2,
EVEX_W_0F382B,
EVEX_W_0F3830_P_1,
EVEX_W_0F3831_P_1,
EVEX_W_0F3832_P_1,
EVEX_W_0F3833_P_1,
EVEX_W_0F3834_P_1,
EVEX_W_0F3835_P_1,
EVEX_W_0F3835_P_2,
EVEX_W_0F3837,
EVEX_W_0F383A_P_1,
EVEX_W_0F3852_P_1,
EVEX_W_0F3859,
EVEX_W_0F385A_M_0_L_n,
EVEX_W_0F385B_M_0_L_2,
EVEX_W_0F3870,
EVEX_W_0F3872_P_1,
EVEX_W_0F3872_P_2,
EVEX_W_0F3872_P_3,
EVEX_W_0F387A,
EVEX_W_0F387B,
EVEX_W_0F3883,
EVEX_W_0F3A05,
EVEX_W_0F3A08,
EVEX_W_0F3A09,
EVEX_W_0F3A0A,
EVEX_W_0F3A0B,
EVEX_W_0F3A18_L_n,
EVEX_W_0F3A19_L_n,
EVEX_W_0F3A1A_L_2,
EVEX_W_0F3A1B_L_2,
EVEX_W_0F3A21,
EVEX_W_0F3A23_L_n,
EVEX_W_0F3A38_L_n,
EVEX_W_0F3A39_L_n,
EVEX_W_0F3A3A_L_2,
EVEX_W_0F3A3B_L_2,
EVEX_W_0F3A42,
EVEX_W_0F3A43_L_n,
EVEX_W_0F3A70,
EVEX_W_0F3A72,
EVEX_W_MAP5_5A,
EVEX_W_MAP5_5B,
EVEX_W_MAP5_78_P_0,
EVEX_W_MAP5_78_P_2,
EVEX_W_MAP5_79_P_0,
EVEX_W_MAP5_79_P_2,
EVEX_W_MAP5_7A_P_2,
EVEX_W_MAP5_7A_P_3,
EVEX_W_MAP5_7B_P_2,
EVEX_W_MAP5_7C_P_0,
EVEX_W_MAP5_7C_P_2,
EVEX_W_MAP5_7D,
EVEX_W_MAP6_13_P_0,
EVEX_W_MAP6_13_P_2,
};
typedef void (*op_rtn) (int bytemode, int sizeflag);
struct dis386 {
const char *name;
struct
{
op_rtn rtn;
int bytemode;
} op[MAX_OPERANDS];
unsigned int prefix_requirement;
};
/* Upper case letters in the instruction names here are macros.
'A' => print 'b' if no register operands or suffix_always is true
'B' => print 'b' if suffix_always is true
'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
size prefix
'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
suffix_always is true
'E' => print 'e' if 32-bit form of jcxz
'F' => print 'w' or 'l' depending on address size prefix (loop insns)
'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
'H' => print ",pt" or ",pn" branch hint
'I' unused.
'J' unused.
'K' => print 'd' or 'q' if rex prefix is present.
'L' unused.
'M' => print 'r' if intel_mnemonic is false.
'N' => print 'n' if instruction has no wait "prefix"
'O' => print 'd' or 'o' (or 'q' in Intel mode)
'P' => behave as 'T' except with register operand outside of suffix_always
mode
'Q' => print 'w', 'l' or 'q' for memory operand or suffix_always
is true
'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
'S' => print 'w', 'l' or 'q' if suffix_always is true
'T' => print 'w', 'l'/'d', or 'q' if instruction has an operand size
prefix or if suffix_always is true.
'U' unused.
'V' unused.
'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
'X' => print 's', 'd' depending on data16 prefix (for XMM)
'Y' unused.
'Z' => print 'q' in 64bit mode and 'l' otherwise, if suffix_always is true.
'!' => change condition from true to false or from false to true.
'%' => add 1 upper case letter to the macro.
'^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
prefix or suffix_always is true (lcall/ljmp).
'@' => in 64bit mode for Intel64 ISA or if instruction
has no operand sizing prefix, print 'q' if suffix_always is true or
nothing otherwise; behave as 'P' in all other cases
2 upper case letter macros:
"XY" => print 'x' or 'y' if suffix_always is true or no register
operands and no broadcast.
"XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
register operands and no broadcast.
"XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
"XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
"XV" => print "{vex3}" pseudo prefix
"LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
being false, or no operand at all in 64bit mode, or if suffix_always
is true.
"LB" => print "abs" in 64bit mode and behave as 'B' otherwise
"LS" => print "abs" in 64bit mode and behave as 'S' otherwise
"LV" => print "abs" for 64bit operand and behave as 'S' otherwise
"DQ" => print 'd' or 'q' depending on the VEX.W bit
"BW" => print 'b' or 'w' depending on the VEX.W bit
"LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has
an operand size prefix, or suffix_always is true. print
'q' if rex prefix is present.
Many of the above letters print nothing in Intel mode. See "putop"
for the details.
Braces '{' and '}', and vertical bars '|', indicate alternative
mnemonic strings for AT&T and Intel. */
static const struct dis386 dis386[] = {
/* 00 */
{ "addB", { Ebh1, Gb }, 0 },
{ "addS", { Evh1, Gv }, 0 },
{ "addB", { Gb, EbS }, 0 },
{ "addS", { Gv, EvS }, 0 },
{ "addB", { AL, Ib }, 0 },
{ "addS", { eAX, Iv }, 0 },
{ X86_64_TABLE (X86_64_06) },
{ X86_64_TABLE (X86_64_07) },
/* 08 */
{ "orB", { Ebh1, Gb }, 0 },
{ "orS", { Evh1, Gv }, 0 },
{ "orB", { Gb, EbS }, 0 },
{ "orS", { Gv, EvS }, 0 },
{ "orB", { AL, Ib }, 0 },
{ "orS", { eAX, Iv }, 0 },
{ X86_64_TABLE (X86_64_0E) },
{ Bad_Opcode }, /* 0x0f extended opcode escape */
/* 10 */
{ "adcB", { Ebh1, Gb }, 0 },
{ "adcS", { Evh1, Gv }, 0 },
{ "adcB", { Gb, EbS }, 0 },
{ "adcS", { Gv, EvS }, 0 },
{ "adcB", { AL, Ib }, 0 },
{ "adcS", { eAX, Iv }, 0 },
{ X86_64_TABLE (X86_64_16) },
{ X86_64_TABLE (X86_64_17) },
/* 18 */
{ "sbbB", { Ebh1, Gb }, 0 },
{ "sbbS", { Evh1, Gv }, 0 },
{ "sbbB", { Gb, EbS }, 0 },
{ "sbbS", { Gv, EvS }, 0 },
{ "sbbB", { AL, Ib }, 0 },
{ "sbbS", { eAX, Iv }, 0 },
{ X86_64_TABLE (X86_64_1E) },
{ X86_64_TABLE (X86_64_1F) },
/* 20 */
{ "andB", { Ebh1, Gb }, 0 },
{ "andS", { Evh1, Gv }, 0 },
{ "andB", { Gb, EbS }, 0 },
{ "andS", { Gv, EvS }, 0 },
{ "andB", { AL, Ib }, 0 },
{ "andS", { eAX, Iv }, 0 },
{ Bad_Opcode }, /* SEG ES prefix */
{ X86_64_TABLE (X86_64_27) },
/* 28 */
{ "subB", { Ebh1, Gb }, 0 },
{ "subS", { Evh1, Gv }, 0 },
{ "subB", { Gb, EbS }, 0 },
{ "subS", { Gv, EvS }, 0 },
{ "subB", { AL, Ib }, 0 },
{ "subS", { eAX, Iv }, 0 },
{ Bad_Opcode }, /* SEG CS prefix */
{ X86_64_TABLE (X86_64_2F) },
/* 30 */
{ "xorB", { Ebh1, Gb }, 0 },
{ "xorS", { Evh1, Gv }, 0 },
{ "xorB", { Gb, EbS }, 0 },
{ "xorS", { Gv, EvS }, 0 },
{ "xorB", { AL, Ib }, 0 },
{ "xorS", { eAX, Iv }, 0 },
{ Bad_Opcode }, /* SEG SS prefix */
{ X86_64_TABLE (X86_64_37) },
/* 38 */
{ "cmpB", { Eb, Gb }, 0 },
{ "cmpS", { Ev, Gv }, 0 },
{ "cmpB", { Gb, EbS }, 0 },
{ "cmpS", { Gv, EvS }, 0 },
{ "cmpB", { AL, Ib }, 0 },
{ "cmpS", { eAX, Iv }, 0 },
{ Bad_Opcode }, /* SEG DS prefix */
{ X86_64_TABLE (X86_64_3F) },
/* 40 */
{ "inc{S|}", { RMeAX }, 0 },
{ "inc{S|}", { RMeCX }, 0 },
{ "inc{S|}", { RMeDX }, 0 },
{ "inc{S|}", { RMeBX }, 0 },
{ "inc{S|}", { RMeSP }, 0 },
{ "inc{S|}", { RMeBP }, 0 },
{ "inc{S|}", { RMeSI }, 0 },
{ "inc{S|}", { RMeDI }, 0 },
/* 48 */
{ "dec{S|}", { RMeAX }, 0 },
{ "dec{S|}", { RMeCX }, 0 },
{ "dec{S|}", { RMeDX }, 0 },
{ "dec{S|}", { RMeBX }, 0 },
{ "dec{S|}", { RMeSP }, 0 },
{ "dec{S|}", { RMeBP }, 0 },
{ "dec{S|}", { RMeSI }, 0 },
{ "dec{S|}", { RMeDI }, 0 },
/* 50 */
{ "push{!P|}", { RMrAX }, 0 },
{ "push{!P|}", { RMrCX }, 0 },
{ "push{!P|}", { RMrDX }, 0 },
{ "push{!P|}", { RMrBX }, 0 },
{ "push{!P|}", { RMrSP }, 0 },
{ "push{!P|}", { RMrBP }, 0 },
{ "push{!P|}", { RMrSI }, 0 },
{ "push{!P|}", { RMrDI }, 0 },
/* 58 */
{ "pop{!P|}", { RMrAX }, 0 },
{ "pop{!P|}", { RMrCX }, 0 },
{ "pop{!P|}", { RMrDX }, 0 },
{ "pop{!P|}", { RMrBX }, 0 },
{ "pop{!P|}", { RMrSP }, 0 },
{ "pop{!P|}", { RMrBP }, 0 },
{ "pop{!P|}", { RMrSI }, 0 },
{ "pop{!P|}", { RMrDI }, 0 },
/* 60 */
{ X86_64_TABLE (X86_64_60) },
{ X86_64_TABLE (X86_64_61) },
{ X86_64_TABLE (X86_64_62) },
{ X86_64_TABLE (X86_64_63) },
{ Bad_Opcode }, /* seg fs */
{ Bad_Opcode }, /* seg gs */
{ Bad_Opcode }, /* op size prefix */
{ Bad_Opcode }, /* adr size prefix */
/* 68 */
{ "pushP", { sIv }, 0 },
{ "imulS", { Gv, Ev, Iv }, 0 },
{ "pushP", { sIbT }, 0 },
{ "imulS", { Gv, Ev, sIb }, 0 },
{ "ins{b|}", { Ybr, indirDX }, 0 },
{ X86_64_TABLE (X86_64_6D) },
{ "outs{b|}", { indirDXr, Xb }, 0 },
{ X86_64_TABLE (X86_64_6F) },
/* 70 */
{ "joH", { Jb, BND, cond_jump_flag }, 0 },
{ "jnoH", { Jb, BND, cond_jump_flag }, 0 },
{ "jbH", { Jb, BND, cond_jump_flag }, 0 },
{ "jaeH", { Jb, BND, cond_jump_flag }, 0 },
{ "jeH", { Jb, BND, cond_jump_flag }, 0 },
{ "jneH", { Jb, BND, cond_jump_flag }, 0 },
{ "jbeH", { Jb, BND, cond_jump_flag }, 0 },
{ "jaH", { Jb, BND, cond_jump_flag }, 0 },
/* 78 */
{ "jsH", { Jb, BND, cond_jump_flag }, 0 },
{ "jnsH", { Jb, BND, cond_jump_flag }, 0 },
{ "jpH", { Jb, BND, cond_jump_flag }, 0 },
{ "jnpH", { Jb, BND, cond_jump_flag }, 0 },
{ "jlH", { Jb, BND, cond_jump_flag }, 0 },
{ "jgeH", { Jb, BND, cond_jump_flag }, 0 },
{ "jleH", { Jb, BND, cond_jump_flag }, 0 },
{ "jgH", { Jb, BND, cond_jump_flag }, 0 },
/* 80 */
{ REG_TABLE (REG_80) },
{ REG_TABLE (REG_81) },
{ X86_64_TABLE (X86_64_82) },
{ REG_TABLE (REG_83) },
{ "testB", { Eb, Gb }, 0 },
{ "testS", { Ev, Gv }, 0 },
{ "xchgB", { Ebh2, Gb }, 0 },
{ "xchgS", { Evh2, Gv }, 0 },
/* 88 */
{ "movB", { Ebh3, Gb }, 0 },
{ "movS", { Evh3, Gv }, 0 },
{ "movB", { Gb, EbS }, 0 },
{ "movS", { Gv, EvS }, 0 },
{ "movD", { Sv, Sw }, 0 },
{ MOD_TABLE (MOD_8D) },
{ "movD", { Sw, Sv }, 0 },
{ REG_TABLE (REG_8F) },
/* 90 */
{ PREFIX_TABLE (PREFIX_90) },
{ "xchgS", { RMeCX, eAX }, 0 },
{ "xchgS", { RMeDX, eAX }, 0 },
{ "xchgS", { RMeBX, eAX }, 0 },
{ "xchgS", { RMeSP, eAX }, 0 },
{ "xchgS", { RMeBP, eAX }, 0 },
{ "xchgS", { RMeSI, eAX }, 0 },
{ "xchgS", { RMeDI, eAX }, 0 },
/* 98 */
{ "cW{t|}R", { XX }, 0 },
{ "cR{t|}O", { XX }, 0 },
{ X86_64_TABLE (X86_64_9A) },
{ Bad_Opcode }, /* fwait */
{ "pushfP", { XX }, 0 },
{ "popfP", { XX }, 0 },
{ "sahf", { XX }, 0 },
{ "lahf", { XX }, 0 },
/* a0 */
{ "mov%LB", { AL, Ob }, 0 },
{ "mov%LS", { eAX, Ov }, 0 },
{ "mov%LB", { Ob, AL }, 0 },
{ "mov%LS", { Ov, eAX }, 0 },
{ "movs{b|}", { Ybr, Xb }, 0 },
{ "movs{R|}", { Yvr, Xv }, 0 },
{ "cmps{b|}", { Xb, Yb }, 0 },
{ "cmps{R|}", { Xv, Yv }, 0 },
/* a8 */
{ "testB", { AL, Ib }, 0 },
{ "testS", { eAX, Iv }, 0 },
{ "stosB", { Ybr, AL }, 0 },
{ "stosS", { Yvr, eAX }, 0 },
{ "lodsB", { ALr, Xb }, 0 },
{ "lodsS", { eAXr, Xv }, 0 },
{ "scasB", { AL, Yb }, 0 },
{ "scasS", { eAX, Yv }, 0 },
/* b0 */
{ "movB", { RMAL, Ib }, 0 },
{ "movB", { RMCL, Ib }, 0 },
{ "movB", { RMDL, Ib }, 0 },
{ "movB", { RMBL, Ib }, 0 },
{ "movB", { RMAH, Ib }, 0 },
{ "movB", { RMCH, Ib }, 0 },
{ "movB", { RMDH, Ib }, 0 },
{ "movB", { RMBH, Ib }, 0 },
/* b8 */
{ "mov%LV", { RMeAX, Iv64 }, 0 },
{ "mov%LV", { RMeCX, Iv64 }, 0 },
{ "mov%LV", { RMeDX, Iv64 }, 0 },
{ "mov%LV", { RMeBX, Iv64 }, 0 },
{ "mov%LV", { RMeSP, Iv64 }, 0 },
{ "mov%LV", { RMeBP, Iv64 }, 0 },
{ "mov%LV", { RMeSI, Iv64 }, 0 },
{ "mov%LV", { RMeDI, Iv64 }, 0 },
/* c0 */
{ REG_TABLE (REG_C0) },
{ REG_TABLE (REG_C1) },
{ X86_64_TABLE (X86_64_C2) },
{ X86_64_TABLE (X86_64_C3) },
{ X86_64_TABLE (X86_64_C4) },
{ X86_64_TABLE (X86_64_C5) },
{ REG_TABLE (REG_C6) },
{ REG_TABLE (REG_C7) },
/* c8 */
{ "enterP", { Iw, Ib }, 0 },
{ "leaveP", { XX }, 0 },
{ "{l|}ret{|f}%LP", { Iw }, 0 },
{ "{l|}ret{|f}%LP", { XX }, 0 },
{ "int3", { XX }, 0 },
{ "int", { Ib }, 0 },
{ X86_64_TABLE (X86_64_CE) },
{ "iret%LP", { XX }, 0 },
/* d0 */
{ REG_TABLE (REG_D0) },
{ REG_TABLE (REG_D1) },
{ REG_TABLE (REG_D2) },
{ REG_TABLE (REG_D3) },
{ X86_64_TABLE (X86_64_D4) },
{ X86_64_TABLE (X86_64_D5) },
{ Bad_Opcode },
{ "xlat", { DSBX }, 0 },
/* d8 */
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
/* e0 */
{ "loopneFH", { Jb, XX, loop_jcxz_flag }, 0 },
{ "loopeFH", { Jb, XX, loop_jcxz_flag }, 0 },
{ "loopFH", { Jb, XX, loop_jcxz_flag }, 0 },
{ "jEcxzH", { Jb, XX, loop_jcxz_flag }, 0 },
{ "inB", { AL, Ib }, 0 },
{ "inG", { zAX, Ib }, 0 },
{ "outB", { Ib, AL }, 0 },
{ "outG", { Ib, zAX }, 0 },
/* e8 */
{ X86_64_TABLE (X86_64_E8) },
{ X86_64_TABLE (X86_64_E9) },
{ X86_64_TABLE (X86_64_EA) },
{ "jmp", { Jb, BND }, 0 },
{ "inB", { AL, indirDX }, 0 },
{ "inG", { zAX, indirDX }, 0 },
{ "outB", { indirDX, AL }, 0 },
{ "outG", { indirDX, zAX }, 0 },
/* f0 */
{ Bad_Opcode }, /* lock prefix */
{ "int1", { XX }, 0 },
{ Bad_Opcode }, /* repne */
{ Bad_Opcode }, /* repz */
{ "hlt", { XX }, 0 },
{ "cmc", { XX }, 0 },
{ REG_TABLE (REG_F6) },
{ REG_TABLE (REG_F7) },
/* f8 */
{ "clc", { XX }, 0 },
{ "stc", { XX }, 0 },
{ "cli", { XX }, 0 },
{ "sti", { XX }, 0 },
{ "cld", { XX }, 0 },
{ "std", { XX }, 0 },
{ REG_TABLE (REG_FE) },
{ REG_TABLE (REG_FF) },
};
static const struct dis386 dis386_twobyte[] = {
/* 00 */
{ REG_TABLE (REG_0F00 ) },
{ REG_TABLE (REG_0F01 ) },
{ "larS", { Gv, Ew }, 0 },
{ "lslS", { Gv, Ew }, 0 },
{ Bad_Opcode },
{ "syscall", { XX }, 0 },
{ "clts", { XX }, 0 },
{ "sysret%LQ", { XX }, 0 },
/* 08 */
{ "invd", { XX }, 0 },
{ PREFIX_TABLE (PREFIX_0F09) },
{ Bad_Opcode },
{ "ud2", { XX }, 0 },
{ Bad_Opcode },
{ REG_TABLE (REG_0F0D) },
{ "femms", { XX }, 0 },
{ "", { MX, EM, OPSUF }, 0 }, /* See OP_3DNowSuffix. */
/* 10 */
{ PREFIX_TABLE (PREFIX_0F10) },
{ PREFIX_TABLE (PREFIX_0F11) },
{ PREFIX_TABLE (PREFIX_0F12) },
{ MOD_TABLE (MOD_0F13) },
{ "unpcklpX", { XM, EXx }, PREFIX_OPCODE },
{ "unpckhpX", { XM, EXx }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0F16) },
{ MOD_TABLE (MOD_0F17) },
/* 18 */
{ REG_TABLE (REG_0F18) },
{ "nopQ", { Ev }, 0 },
{ PREFIX_TABLE (PREFIX_0F1A) },
{ PREFIX_TABLE (PREFIX_0F1B) },
{ PREFIX_TABLE (PREFIX_0F1C) },
{ "nopQ", { Ev }, 0 },
{ PREFIX_TABLE (PREFIX_0F1E) },
{ "nopQ", { Ev }, 0 },
/* 20 */
{ "movZ", { Em, Cm }, 0 },
{ "movZ", { Em, Dm }, 0 },
{ "movZ", { Cm, Em }, 0 },
{ "movZ", { Dm, Em }, 0 },
{ X86_64_TABLE (X86_64_0F24) },
{ Bad_Opcode },
{ X86_64_TABLE (X86_64_0F26) },
{ Bad_Opcode },
/* 28 */
{ "movapX", { XM, EXx }, PREFIX_OPCODE },
{ "movapX", { EXxS, XM }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0F2A) },
{ PREFIX_TABLE (PREFIX_0F2B) },
{ PREFIX_TABLE (PREFIX_0F2C) },
{ PREFIX_TABLE (PREFIX_0F2D) },
{ PREFIX_TABLE (PREFIX_0F2E) },
{ PREFIX_TABLE (PREFIX_0F2F) },
/* 30 */
{ "wrmsr", { XX }, 0 },
{ "rdtsc", { XX }, 0 },
{ "rdmsr", { XX }, 0 },
{ "rdpmc", { XX }, 0 },
{ "sysenter", { SEP }, 0 },
{ "sysexit%LQ", { SEP }, 0 },
{ Bad_Opcode },
{ "getsec", { XX }, 0 },
/* 38 */
{ THREE_BYTE_TABLE_PREFIX (THREE_BYTE_0F38, PREFIX_OPCODE) },
{ Bad_Opcode },
{ THREE_BYTE_TABLE_PREFIX (THREE_BYTE_0F3A, PREFIX_OPCODE) },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
/* 40 */
{ "cmovoS", { Gv, Ev }, 0 },
{ "cmovnoS", { Gv, Ev }, 0 },
{ "cmovbS", { Gv, Ev }, 0 },
{ "cmovaeS", { Gv, Ev }, 0 },
{ "cmoveS", { Gv, Ev }, 0 },
{ "cmovneS", { Gv, Ev }, 0 },
{ "cmovbeS", { Gv, Ev }, 0 },
{ "cmovaS", { Gv, Ev }, 0 },
/* 48 */
{ "cmovsS", { Gv, Ev }, 0 },
{ "cmovnsS", { Gv, Ev }, 0 },
{ "cmovpS", { Gv, Ev }, 0 },
{ "cmovnpS", { Gv, Ev }, 0 },
{ "cmovlS", { Gv, Ev }, 0 },
{ "cmovgeS", { Gv, Ev }, 0 },
{ "cmovleS", { Gv, Ev }, 0 },
{ "cmovgS", { Gv, Ev }, 0 },
/* 50 */
{ MOD_TABLE (MOD_0F50) },
{ PREFIX_TABLE (PREFIX_0F51) },
{ PREFIX_TABLE (PREFIX_0F52) },
{ PREFIX_TABLE (PREFIX_0F53) },
{ "andpX", { XM, EXx }, PREFIX_OPCODE },
{ "andnpX", { XM, EXx }, PREFIX_OPCODE },
{ "orpX", { XM, EXx }, PREFIX_OPCODE },
{ "xorpX", { XM, EXx }, PREFIX_OPCODE },
/* 58 */
{ PREFIX_TABLE (PREFIX_0F58) },
{ PREFIX_TABLE (PREFIX_0F59) },
{ PREFIX_TABLE (PREFIX_0F5A) },
{ PREFIX_TABLE (PREFIX_0F5B) },
{ PREFIX_TABLE (PREFIX_0F5C) },
{ PREFIX_TABLE (PREFIX_0F5D) },
{ PREFIX_TABLE (PREFIX_0F5E) },
{ PREFIX_TABLE (PREFIX_0F5F) },
/* 60 */
{ PREFIX_TABLE (PREFIX_0F60) },
{ PREFIX_TABLE (PREFIX_0F61) },
{ PREFIX_TABLE (PREFIX_0F62) },
{ "packsswb", { MX, EM }, PREFIX_OPCODE },
{ "pcmpgtb", { MX, EM }, PREFIX_OPCODE },
{ "pcmpgtw", { MX, EM }, PREFIX_OPCODE },
{ "pcmpgtd", { MX, EM }, PREFIX_OPCODE },
{ "packuswb", { MX, EM }, PREFIX_OPCODE },
/* 68 */
{ "punpckhbw", { MX, EM }, PREFIX_OPCODE },
{ "punpckhwd", { MX, EM }, PREFIX_OPCODE },
{ "punpckhdq", { MX, EM }, PREFIX_OPCODE },
{ "packssdw", { MX, EM }, PREFIX_OPCODE },
{ "punpcklqdq", { XM, EXx }, PREFIX_DATA },
{ "punpckhqdq", { XM, EXx }, PREFIX_DATA },
{ "movK", { MX, Edq }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0F6F) },
/* 70 */
{ PREFIX_TABLE (PREFIX_0F70) },
{ MOD_TABLE (MOD_0F71) },
{ MOD_TABLE (MOD_0F72) },
{ MOD_TABLE (MOD_0F73) },
{ "pcmpeqb", { MX, EM }, PREFIX_OPCODE },
{ "pcmpeqw", { MX, EM }, PREFIX_OPCODE },
{ "pcmpeqd", { MX, EM }, PREFIX_OPCODE },
{ "emms", { XX }, PREFIX_OPCODE },
/* 78 */
{ PREFIX_TABLE (PREFIX_0F78) },
{ PREFIX_TABLE (PREFIX_0F79) },
{ Bad_Opcode },
{ Bad_Opcode },
{ PREFIX_TABLE (PREFIX_0F7C) },
{ PREFIX_TABLE (PREFIX_0F7D) },
{ PREFIX_TABLE (PREFIX_0F7E) },
{ PREFIX_TABLE (PREFIX_0F7F) },
/* 80 */
{ "joH", { Jv, BND, cond_jump_flag }, 0 },
{ "jnoH", { Jv, BND, cond_jump_flag }, 0 },
{ "jbH", { Jv, BND, cond_jump_flag }, 0 },
{ "jaeH", { Jv, BND, cond_jump_flag }, 0 },
{ "jeH", { Jv, BND, cond_jump_flag }, 0 },
{ "jneH", { Jv, BND, cond_jump_flag }, 0 },
{ "jbeH", { Jv, BND, cond_jump_flag }, 0 },
{ "jaH", { Jv, BND, cond_jump_flag }, 0 },
/* 88 */
{ "jsH", { Jv, BND, cond_jump_flag }, 0 },
{ "jnsH", { Jv, BND, cond_jump_flag }, 0 },
{ "jpH", { Jv, BND, cond_jump_flag }, 0 },
{ "jnpH", { Jv, BND, cond_jump_flag }, 0 },
{ "jlH", { Jv, BND, cond_jump_flag }, 0 },
{ "jgeH", { Jv, BND, cond_jump_flag }, 0 },
{ "jleH", { Jv, BND, cond_jump_flag }, 0 },
{ "jgH", { Jv, BND, cond_jump_flag }, 0 },
/* 90 */
{ "seto", { Eb }, 0 },
{ "setno", { Eb }, 0 },
{ "setb", { Eb }, 0 },
{ "setae", { Eb }, 0 },
{ "sete", { Eb }, 0 },
{ "setne", { Eb }, 0 },
{ "setbe", { Eb }, 0 },
{ "seta", { Eb }, 0 },
/* 98 */
{ "sets", { Eb }, 0 },
{ "setns", { Eb }, 0 },
{ "setp", { Eb }, 0 },
{ "setnp", { Eb }, 0 },
{ "setl", { Eb }, 0 },
{ "setge", { Eb }, 0 },
{ "setle", { Eb }, 0 },
{ "setg", { Eb }, 0 },
/* a0 */
{ "pushP", { fs }, 0 },
{ "popP", { fs }, 0 },
{ "cpuid", { XX }, 0 },
{ "btS", { Ev, Gv }, 0 },
{ "shldS", { Ev, Gv, Ib }, 0 },
{ "shldS", { Ev, Gv, CL }, 0 },
{ REG_TABLE (REG_0FA6) },
{ REG_TABLE (REG_0FA7) },
/* a8 */
{ "pushP", { gs }, 0 },
{ "popP", { gs }, 0 },
{ "rsm", { XX }, 0 },
{ "btsS", { Evh1, Gv }, 0 },
{ "shrdS", { Ev, Gv, Ib }, 0 },
{ "shrdS", { Ev, Gv, CL }, 0 },
{ REG_TABLE (REG_0FAE) },
{ "imulS", { Gv, Ev }, 0 },
/* b0 */
{ "cmpxchgB", { Ebh1, Gb }, 0 },
{ "cmpxchgS", { Evh1, Gv }, 0 },
{ MOD_TABLE (MOD_0FB2) },
{ "btrS", { Evh1, Gv }, 0 },
{ MOD_TABLE (MOD_0FB4) },
{ MOD_TABLE (MOD_0FB5) },
{ "movz{bR|x}", { Gv, Eb }, 0 },
{ "movz{wR|x}", { Gv, Ew }, 0 }, /* yes, there really is movzww ! */
/* b8 */
{ PREFIX_TABLE (PREFIX_0FB8) },
{ "ud1S", { Gv, Ev }, 0 },
{ REG_TABLE (REG_0FBA) },
{ "btcS", { Evh1, Gv }, 0 },
{ PREFIX_TABLE (PREFIX_0FBC) },
{ PREFIX_TABLE (PREFIX_0FBD) },
{ "movs{bR|x}", { Gv, Eb }, 0 },
{ "movs{wR|x}", { Gv, Ew }, 0 }, /* yes, there really is movsww ! */
/* c0 */
{ "xaddB", { Ebh1, Gb }, 0 },
{ "xaddS", { Evh1, Gv }, 0 },
{ PREFIX_TABLE (PREFIX_0FC2) },
{ MOD_TABLE (MOD_0FC3) },
{ "pinsrw", { MX, Edw, Ib }, PREFIX_OPCODE },
{ "pextrw", { Gd, MS, Ib }, PREFIX_OPCODE },
{ "shufpX", { XM, EXx, Ib }, PREFIX_OPCODE },
{ REG_TABLE (REG_0FC7) },
/* c8 */
{ "bswap", { RMeAX }, 0 },
{ "bswap", { RMeCX }, 0 },
{ "bswap", { RMeDX }, 0 },
{ "bswap", { RMeBX }, 0 },
{ "bswap", { RMeSP }, 0 },
{ "bswap", { RMeBP }, 0 },
{ "bswap", { RMeSI }, 0 },
{ "bswap", { RMeDI }, 0 },
/* d0 */
{ PREFIX_TABLE (PREFIX_0FD0) },
{ "psrlw", { MX, EM }, PREFIX_OPCODE },
{ "psrld", { MX, EM }, PREFIX_OPCODE },
{ "psrlq", { MX, EM }, PREFIX_OPCODE },
{ "paddq", { MX, EM }, PREFIX_OPCODE },
{ "pmullw", { MX, EM }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0FD6) },
{ MOD_TABLE (MOD_0FD7) },
/* d8 */
{ "psubusb", { MX, EM }, PREFIX_OPCODE },
{ "psubusw", { MX, EM }, PREFIX_OPCODE },
{ "pminub", { MX, EM }, PREFIX_OPCODE },
{ "pand", { MX, EM }, PREFIX_OPCODE },
{ "paddusb", { MX, EM }, PREFIX_OPCODE },
{ "paddusw", { MX, EM }, PREFIX_OPCODE },
{ "pmaxub", { MX, EM }, PREFIX_OPCODE },
{ "pandn", { MX, EM }, PREFIX_OPCODE },
/* e0 */
{ "pavgb", { MX, EM }, PREFIX_OPCODE },
{ "psraw", { MX, EM }, PREFIX_OPCODE },
{ "psrad", { MX, EM }, PREFIX_OPCODE },
{ "pavgw", { MX, EM }, PREFIX_OPCODE },
{ "pmulhuw", { MX, EM }, PREFIX_OPCODE },
{ "pmulhw", { MX, EM }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0FE6) },
{ PREFIX_TABLE (PREFIX_0FE7) },
/* e8 */
{ "psubsb", { MX, EM }, PREFIX_OPCODE },
{ "psubsw", { MX, EM }, PREFIX_OPCODE },
{ "pminsw", { MX, EM }, PREFIX_OPCODE },
{ "por", { MX, EM }, PREFIX_OPCODE },
{ "paddsb", { MX, EM }, PREFIX_OPCODE },
{ "paddsw", { MX, EM }, PREFIX_OPCODE },
{ "pmaxsw", { MX, EM }, PREFIX_OPCODE },
{ "pxor", { MX, EM }, PREFIX_OPCODE },
/* f0 */
{ PREFIX_TABLE (PREFIX_0FF0) },
{ "psllw", { MX, EM }, PREFIX_OPCODE },
{ "pslld", { MX, EM }, PREFIX_OPCODE },
{ "psllq", { MX, EM }, PREFIX_OPCODE },
{ "pmuludq", { MX, EM }, PREFIX_OPCODE },
{ "pmaddwd", { MX, EM }, PREFIX_OPCODE },
{ "psadbw", { MX, EM }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_0FF7) },
/* f8 */
{ "psubb", { MX, EM }, PREFIX_OPCODE },
{ "psubw", { MX, EM }, PREFIX_OPCODE },
{ "psubd", { MX, EM }, PREFIX_OPCODE },
{ "psubq", { MX, EM }, PREFIX_OPCODE },
{ "paddb", { MX, EM }, PREFIX_OPCODE },
{ "paddw", { MX, EM }, PREFIX_OPCODE },
{ "paddd", { MX, EM }, PREFIX_OPCODE },
{ "ud0S", { Gv, Ev }, 0 },
};
static const unsigned char onebyte_has_modrm[256] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
/* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
/* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
/* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
/* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
/* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
/* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
/* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
/* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
/* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
/* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
/* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
/* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
static const unsigned char twobyte_has_modrm[256] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
/* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
/* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
/* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
/* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
/* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
/* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
/* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
/* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
/* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
/* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
/* b0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bf */
/* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
/* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
/* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /* ff */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
static char obuf[100];
static char *obufp;
static char *mnemonicendp;
static char scratchbuf[100];
static unsigned char *start_codep;
static unsigned char *insn_codep;
static unsigned char *codep;
static unsigned char *end_codep;
static int last_lock_prefix;
static int last_repz_prefix;
static int last_repnz_prefix;
static int last_data_prefix;
static int last_addr_prefix;
static int last_rex_prefix;
static int last_seg_prefix;
static int fwait_prefix;
/* The active segment register prefix. */
static int active_seg_prefix;
#define MAX_CODE_LENGTH 15
/* We can up to 14 prefixes since the maximum instruction length is
15bytes. */
static int all_prefixes[MAX_CODE_LENGTH - 1];
static disassemble_info *the_info;
static struct
{
int mod;
int reg;
int rm;
}
modrm;
static unsigned char need_modrm;
static struct
{
int scale;
int index;
int base;
}
sib;
static struct
{
int register_specifier;
int length;
int prefix;
int w;
int evex;
int r;
int v;
int mask_register_specifier;
int zeroing;
int ll;
int b;
int no_broadcast;
}
vex;
static unsigned char need_vex;
struct op
{
const char *name;
unsigned int len;
};
/* If we are accessing mod/rm/reg without need_modrm set, then the
values are stale. Hitting this abort likely indicates that you
need to update onebyte_has_modrm or twobyte_has_modrm. */
#define MODRM_CHECK if (!need_modrm) abort ()
static const char **names64;
static const char **names32;
static const char **names16;
static const char **names8;
static const char **names8rex;
static const char **names_seg;
static const char *index64;
static const char *index32;
static const char **index16;
static const char **names_bnd;
static const char *intel_names64[] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};
static const char *intel_names32[] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
};
static const char *intel_names16[] = {
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
};
static const char *intel_names8[] = {
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
};
static const char *intel_names8rex[] = {
"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
};
static const char *intel_names_seg[] = {
"es", "cs", "ss", "ds", "fs", "gs", "?", "?",
};
static const char *intel_index64 = "riz";
static const char *intel_index32 = "eiz";
static const char *intel_index16[] = {
"bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
};
static const char *att_names64[] = {
"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
};
static const char *att_names32[] = {
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
};
static const char *att_names16[] = {
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
};
static const char *att_names8[] = {
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
};
static const char *att_names8rex[] = {
"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
};
static const char *att_names_seg[] = {
"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
};
static const char *att_index64 = "%riz";
static const char *att_index32 = "%eiz";
static const char *att_index16[] = {
"%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
};
static const char **names_mm;
static const char *intel_names_mm[] = {
"mm0", "mm1", "mm2", "mm3",
"mm4", "mm5", "mm6", "mm7"
};
static const char *att_names_mm[] = {
"%mm0", "%mm1", "%mm2", "%mm3",
"%mm4", "%mm5", "%mm6", "%mm7"
};
static const char *intel_names_bnd[] = {
"bnd0", "bnd1", "bnd2", "bnd3"
};
static const char *att_names_bnd[] = {
"%bnd0", "%bnd1", "%bnd2", "%bnd3"
};
static const char **names_xmm;
static const char *intel_names_xmm[] = {
"xmm0", "xmm1", "xmm2", "xmm3",
"xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11",
"xmm12", "xmm13", "xmm14", "xmm15",
"xmm16", "xmm17", "xmm18", "xmm19",
"xmm20", "xmm21", "xmm22", "xmm23",
"xmm24", "xmm25", "xmm26", "xmm27",
"xmm28", "xmm29", "xmm30", "xmm31"
};
static const char *att_names_xmm[] = {
"%xmm0", "%xmm1", "%xmm2", "%xmm3",
"%xmm4", "%xmm5", "%xmm6", "%xmm7",
"%xmm8", "%xmm9", "%xmm10", "%xmm11",
"%xmm12", "%xmm13", "%xmm14", "%xmm15",
"%xmm16", "%xmm17", "%xmm18", "%xmm19",
"%xmm20", "%xmm21", "%xmm22", "%xmm23",
"%xmm24", "%xmm25", "%xmm26", "%xmm27",
"%xmm28", "%xmm29", "%xmm30", "%xmm31"
};
static const char **names_ymm;
static const char *intel_names_ymm[] = {
"ymm0", "ymm1", "ymm2", "ymm3",
"ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11",
"ymm12", "ymm13", "ymm14", "ymm15",
"ymm16", "ymm17", "ymm18", "ymm19",
"ymm20", "ymm21", "ymm22", "ymm23",
"ymm24", "ymm25", "ymm26", "ymm27",
"ymm28", "ymm29", "ymm30", "ymm31"
};
static const char *att_names_ymm[] = {
"%ymm0", "%ymm1", "%ymm2", "%ymm3",
"%ymm4", "%ymm5", "%ymm6", "%ymm7",
"%ymm8", "%ymm9", "%ymm10", "%ymm11",
"%ymm12", "%ymm13", "%ymm14", "%ymm15",
"%ymm16", "%ymm17", "%ymm18", "%ymm19",
"%ymm20", "%ymm21", "%ymm22", "%ymm23",
"%ymm24", "%ymm25", "%ymm26", "%ymm27",
"%ymm28", "%ymm29", "%ymm30", "%ymm31"
};
static const char **names_zmm;
static const char *intel_names_zmm[] = {
"zmm0", "zmm1", "zmm2", "zmm3",
"zmm4", "zmm5", "zmm6", "zmm7",
"zmm8", "zmm9", "zmm10", "zmm11",
"zmm12", "zmm13", "zmm14", "zmm15",
"zmm16", "zmm17", "zmm18", "zmm19",
"zmm20", "zmm21", "zmm22", "zmm23",
"zmm24", "zmm25", "zmm26", "zmm27",
"zmm28", "zmm29", "zmm30", "zmm31"
};
static const char *att_names_zmm[] = {
"%zmm0", "%zmm1", "%zmm2", "%zmm3",
"%zmm4", "%zmm5", "%zmm6", "%zmm7",
"%zmm8", "%zmm9", "%zmm10", "%zmm11",
"%zmm12", "%zmm13", "%zmm14", "%zmm15",
"%zmm16", "%zmm17", "%zmm18", "%zmm19",
"%zmm20", "%zmm21", "%zmm22", "%zmm23",
"%zmm24", "%zmm25", "%zmm26", "%zmm27",
"%zmm28", "%zmm29", "%zmm30", "%zmm31"
};
static const char **names_tmm;
static const char *intel_names_tmm[] = {
"tmm0", "tmm1", "tmm2", "tmm3",
"tmm4", "tmm5", "tmm6", "tmm7"
};
static const char *att_names_tmm[] = {
"%tmm0", "%tmm1", "%tmm2", "%tmm3",
"%tmm4", "%tmm5", "%tmm6", "%tmm7"
};
static const char **names_mask;
static const char *intel_names_mask[] = {
"k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7"
};
static const char *att_names_mask[] = {
"%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
};
static const char *const names_rounding[] =
{
"{rn-",
"{rd-",
"{ru-",
"{rz-"
};
static const struct dis386 reg_table[][8] = {
/* REG_80 */
{
{ "addA", { Ebh1, Ib }, 0 },
{ "orA", { Ebh1, Ib }, 0 },
{ "adcA", { Ebh1, Ib }, 0 },
{ "sbbA", { Ebh1, Ib }, 0 },
{ "andA", { Ebh1, Ib }, 0 },
{ "subA", { Ebh1, Ib }, 0 },
{ "xorA", { Ebh1, Ib }, 0 },
{ "cmpA", { Eb, Ib }, 0 },
},
/* REG_81 */
{
{ "addQ", { Evh1, Iv }, 0 },
{ "orQ", { Evh1, Iv }, 0 },
{ "adcQ", { Evh1, Iv }, 0 },
{ "sbbQ", { Evh1, Iv }, 0 },
{ "andQ", { Evh1, Iv }, 0 },
{ "subQ", { Evh1, Iv }, 0 },
{ "xorQ", { Evh1, Iv }, 0 },
{ "cmpQ", { Ev, Iv }, 0 },
},
/* REG_83 */
{
{ "addQ", { Evh1, sIb }, 0 },
{ "orQ", { Evh1, sIb }, 0 },
{ "adcQ", { Evh1, sIb }, 0 },
{ "sbbQ", { Evh1, sIb }, 0 },
{ "andQ", { Evh1, sIb }, 0 },
{ "subQ", { Evh1, sIb }, 0 },
{ "xorQ", { Evh1, sIb }, 0 },
{ "cmpQ", { Ev, sIb }, 0 },
},
/* REG_8F */
{
{ "pop{P|}", { stackEv }, 0 },
{ XOP_8F_TABLE (XOP_09) },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ XOP_8F_TABLE (XOP_09) },
},
/* REG_C0 */
{
{ "rolA", { Eb, Ib }, 0 },
{ "rorA", { Eb, Ib }, 0 },
{ "rclA", { Eb, Ib }, 0 },
{ "rcrA", { Eb, Ib }, 0 },
{ "shlA", { Eb, Ib }, 0 },
{ "shrA", { Eb, Ib }, 0 },
{ "shlA", { Eb, Ib }, 0 },
{ "sarA", { Eb, Ib }, 0 },
},
/* REG_C1 */
{
{ "rolQ", { Ev, Ib }, 0 },
{ "rorQ", { Ev, Ib }, 0 },
{ "rclQ", { Ev, Ib }, 0 },
{ "rcrQ", { Ev, Ib }, 0 },
{ "shlQ", { Ev, Ib }, 0 },
{ "shrQ", { Ev, Ib }, 0 },
{ "shlQ", { Ev, Ib }, 0 },
{ "sarQ", { Ev, Ib }, 0 },
},
/* REG_C6 */
{
{ "movA", { Ebh3, Ib }, 0 },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ MOD_TABLE (MOD_C6_REG_7) },
},
/* REG_C7 */
{
{ "movQ", { Evh3, Iv }, 0 },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ MOD_TABLE (MOD_C7_REG_7) },
},
/* REG_D0 */
{
{ "rolA", { Eb, I1 }, 0 },
{ "rorA", { Eb, I1 }, 0 },
{ "rclA", { Eb, I1 }, 0 },
{ "rcrA", { Eb, I1 }, 0 },
{ "shlA", { Eb, I1 }, 0 },
{ "shrA", { Eb, I1 }, 0 },
{ "shlA", { Eb, I1 }, 0 },
{ "sarA", { Eb, I1 }, 0 },
},
/* REG_D1 */
{
{ "rolQ", { Ev, I1 }, 0 },
{ "rorQ", { Ev, I1 }, 0 },
{ "rclQ", { Ev, I1 }, 0 },
{ "rcrQ", { Ev, I1 }, 0 },
{ "shlQ", { Ev, I1 }, 0 },
{ "shrQ", { Ev, I1 }, 0 },
{ "shlQ", { Ev, I1 }, 0 },
{ "sarQ", { Ev, I1 }, 0 },
},
/* REG_D2 */
{
{ "rolA", { Eb, CL }, 0 },
{ "rorA", { Eb, CL }, 0 },
{ "rclA", { Eb, CL }, 0 },
{ "rcrA", { Eb, CL }, 0 },
{ "shlA", { Eb, CL }, 0 },
{ "shrA", { Eb, CL }, 0 },
{ "shlA", { Eb, CL }, 0 },
{ "sarA", { Eb, CL }, 0 },
},
/* REG_D3 */
{
{ "rolQ", { Ev, CL }, 0 },
{ "rorQ", { Ev, CL }, 0 },
{ "rclQ", { Ev, CL }, 0 },
{ "rcrQ", { Ev, CL }, 0 },
{ "shlQ", { Ev, CL }, 0 },
{ "shrQ", { Ev, CL }, 0 },
{ "shlQ", { Ev, CL }, 0 },
{ "sarQ", { Ev, CL }, 0 },
},
/* REG_F6 */
{
{ "testA", { Eb, Ib }, 0 },
{ "testA", { Eb, Ib }, 0 },
{ "notA", { Ebh1 }, 0 },
{ "negA", { Ebh1 }, 0 },
{ "mulA", { Eb }, 0 }, /* Don't print the implicit %al register, */
{ "imulA", { Eb }, 0 }, /* to distinguish these opcodes from other */
{ "divA", { Eb }, 0 }, /* mul/imul opcodes. Do the same for div */
{ "idivA", { Eb }, 0 }, /* and idiv for consistency. */
},
/* REG_F7 */
{
{ "testQ", { Ev, Iv }, 0 },
{ "testQ", { Ev, Iv }, 0 },
{ "notQ", { Evh1 }, 0 },
{ "negQ", { Evh1 }, 0 },
{ "mulQ", { Ev }, 0 }, /* Don't print the implicit register. */
{ "imulQ", { Ev }, 0 },
{ "divQ", { Ev }, 0 },
{ "idivQ", { Ev }, 0 },
},
/* REG_FE */
{
{ "incA", { Ebh1 }, 0 },
{ "decA", { Ebh1 }, 0 },
},
/* REG_FF */