| /* 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 */ |
|