1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/x86dasm/i386-dis.c Sun Nov 04 08:49:18 2007 +0000
1.4 +/* Print i386 instructions for GDB, the GNU debugger.
1.5 + Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
1.6 + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1.8 + This file is part of GDB.
1.10 + This program is free software; you can redistribute it and/or modify
1.11 + it under the terms of the GNU General Public License as published by
1.12 + the Free Software Foundation; either version 2 of the License, or
1.13 + (at your option) any later version.
1.15 + This program is distributed in the hope that it will be useful,
1.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.18 + GNU General Public License for more details.
1.20 + You should have received a copy of the GNU General Public License
1.21 + along with this program; if not, write to the Free Software
1.22 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
1.24 +/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
1.26 + modified by John Hassey (hassey@dg-rtp.dg.com)
1.27 + x86-64 support added by Jan Hubicka (jh@suse.cz)
1.28 + VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
1.30 +/* The main tables describing the instructions is essentially a copy
1.31 + of the "Opcode Map" chapter (Appendix A) of the Intel 80386
1.32 + Programmers Manual. Usually, there is a capital letter, followed
1.33 + by a small letter. The capital letter tell the addressing mode,
1.34 + and the small letter tells about the operand size. Refer to
1.35 + the Intel manual for details. */
1.37 +#include "dis-asm.h"
1.38 +#include "sysdep.h"
1.39 +#include "opintl.h"
1.43 +#include <setjmp.h>
1.45 +#ifndef UNIXWARE_COMPAT
1.46 +/* Set non-zero for broken, compatible instructions. Set to zero for
1.47 + non-broken opcodes. */
1.48 +#define UNIXWARE_COMPAT 1
1.51 +static int fetch_data (struct disassemble_info *, bfd_byte *);
1.52 +static void ckprefix (void);
1.53 +static const char *prefix_name (int, int);
1.54 +static int print_insn (bfd_vma, disassemble_info *);
1.55 +static void dofloat (int);
1.56 +static void OP_ST (int, int);
1.57 +static void OP_STi (int, int);
1.58 +static int putop (const char *, int);
1.59 +static void oappend (const char *);
1.60 +static void append_seg (void);
1.61 +static void OP_indirE (int, int);
1.62 +static void print_operand_value (char *, int, bfd_vma);
1.63 +static void OP_E (int, int);
1.64 +static void OP_G (int, int);
1.65 +static bfd_vma get64 (void);
1.66 +static bfd_signed_vma get32 (void);
1.67 +static bfd_signed_vma get32s (void);
1.68 +static int get16 (void);
1.69 +static void set_op (bfd_vma, int);
1.70 +static void OP_REG (int, int);
1.71 +static void OP_IMREG (int, int);
1.72 +static void OP_I (int, int);
1.73 +static void OP_I64 (int, int);
1.74 +static void OP_sI (int, int);
1.75 +static void OP_J (int, int);
1.76 +static void OP_SEG (int, int);
1.77 +static void OP_DIR (int, int);
1.78 +static void OP_OFF (int, int);
1.79 +static void OP_OFF64 (int, int);
1.80 +static void ptr_reg (int, int);
1.81 +static void OP_ESreg (int, int);
1.82 +static void OP_DSreg (int, int);
1.83 +static void OP_C (int, int);
1.84 +static void OP_D (int, int);
1.85 +static void OP_T (int, int);
1.86 +static void OP_Rd (int, int);
1.87 +static void OP_MMX (int, int);
1.88 +static void OP_XMM (int, int);
1.89 +static void OP_EM (int, int);
1.90 +static void OP_EX (int, int);
1.91 +static void OP_MS (int, int);
1.92 +static void OP_XS (int, int);
1.93 +static void OP_M (int, int);
1.94 +static void OP_0fae (int, int);
1.95 +static void OP_0f07 (int, int);
1.96 +static void NOP_Fixup (int, int);
1.97 +static void OP_3DNowSuffix (int, int);
1.98 +static void OP_SIMD_Suffix (int, int);
1.99 +static void SIMD_Fixup (int, int);
1.100 +static void PNI_Fixup (int, int);
1.101 +static void INVLPG_Fixup (int, int);
1.102 +static void BadOp (void);
1.104 +struct dis_private {
1.105 + /* Points to first byte not fetched. */
1.106 + bfd_byte *max_fetched;
1.107 + bfd_byte the_buffer[MAXLEN];
1.108 + bfd_vma insn_start;
1.109 + int orig_sizeflag;
1.113 +/* The opcode for the fwait instruction, which we treat as a prefix
1.115 +#define FWAIT_OPCODE (0x9b)
1.117 +/* Set to 1 for 64bit mode disassembly. */
1.118 +static int mode_64bit;
1.120 +/* Flags for the prefixes for the current instruction. See below. */
1.121 +static int prefixes;
1.123 +/* REX prefix the current instruction. See below. */
1.125 +/* Bits of REX we've already used. */
1.126 +static int rex_used;
1.127 +#define REX_MODE64 8
1.128 +#define REX_EXTX 4
1.129 +#define REX_EXTY 2
1.130 +#define REX_EXTZ 1
1.131 +/* Mark parts used in the REX prefix. When we are testing for
1.132 + empty prefix (for 8bit register REX extension), just mask it
1.133 + out. Otherwise test for REX bit is excuse for existence of REX
1.134 + only in case value is nonzero. */
1.135 +#define USED_REX(value) \
1.138 + rex_used |= (rex & value) ? (value) | 0x40 : 0; \
1.140 + rex_used |= 0x40; \
1.143 +/* Flags for prefixes which we somehow handled when printing the
1.144 + current instruction. */
1.145 +static int used_prefixes;
1.147 +/* Flags stored in PREFIXES. */
1.148 +#define PREFIX_REPZ 1
1.149 +#define PREFIX_REPNZ 2
1.150 +#define PREFIX_LOCK 4
1.151 +#define PREFIX_CS 8
1.152 +#define PREFIX_SS 0x10
1.153 +#define PREFIX_DS 0x20
1.154 +#define PREFIX_ES 0x40
1.155 +#define PREFIX_FS 0x80
1.156 +#define PREFIX_GS 0x100
1.157 +#define PREFIX_DATA 0x200
1.158 +#define PREFIX_ADDR 0x400
1.159 +#define PREFIX_FWAIT 0x800
1.161 +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
1.162 + to ADDR (exclusive) are valid. Returns 1 for success, longjmps
1.164 +#define FETCH_DATA(info, addr) \
1.165 + ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
1.166 + ? 1 : fetch_data ((info), (addr)))
1.169 +fetch_data (struct disassemble_info *info, bfd_byte *addr)
1.172 + struct dis_private *priv = (struct dis_private *) info->private_data;
1.173 + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
1.175 + status = (*info->read_memory_func) (start,
1.176 + priv->max_fetched,
1.177 + addr - priv->max_fetched,
1.181 + /* If we did manage to read at least one byte, then
1.182 + print_insn_i386 will do something sensible. Otherwise, print
1.183 + an error. We do that here because this is where we know
1.185 + if (priv->max_fetched == priv->the_buffer)
1.186 + (*info->memory_error_func) (status, start, info);
1.187 + longjmp (priv->bailout, 1);
1.190 + priv->max_fetched = addr;
1.194 +#define XX NULL, 0
1.196 +#define Eb OP_E, b_mode
1.197 +#define Ev OP_E, v_mode
1.198 +#define Ed OP_E, d_mode
1.199 +#define Eq OP_E, q_mode
1.200 +#define Edq OP_E, dq_mode
1.201 +#define Edqw OP_E, dqw_mode
1.202 +#define indirEv OP_indirE, v_mode
1.203 +#define indirEp OP_indirE, f_mode
1.204 +#define Ew OP_E, w_mode
1.205 +#define Ma OP_E, v_mode
1.206 +#define M OP_M, 0 /* lea, lgdt, etc. */
1.207 +#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
1.208 +#define Gb OP_G, b_mode
1.209 +#define Gv OP_G, v_mode
1.210 +#define Gd OP_G, d_mode
1.211 +#define Gdq OP_G, dq_mode
1.212 +#define Gw OP_G, w_mode
1.213 +#define Rd OP_Rd, d_mode
1.214 +#define Rm OP_Rd, m_mode
1.215 +#define Ib OP_I, b_mode
1.216 +#define sIb OP_sI, b_mode /* sign extened byte */
1.217 +#define Iv OP_I, v_mode
1.218 +#define Iq OP_I, q_mode
1.219 +#define Iv64 OP_I64, v_mode
1.220 +#define Iw OP_I, w_mode
1.221 +#define I1 OP_I, const_1_mode
1.222 +#define Jb OP_J, b_mode
1.223 +#define Jv OP_J, v_mode
1.224 +#define Cm OP_C, m_mode
1.225 +#define Dm OP_D, m_mode
1.226 +#define Td OP_T, d_mode
1.228 +#define RMeAX OP_REG, eAX_reg
1.229 +#define RMeBX OP_REG, eBX_reg
1.230 +#define RMeCX OP_REG, eCX_reg
1.231 +#define RMeDX OP_REG, eDX_reg
1.232 +#define RMeSP OP_REG, eSP_reg
1.233 +#define RMeBP OP_REG, eBP_reg
1.234 +#define RMeSI OP_REG, eSI_reg
1.235 +#define RMeDI OP_REG, eDI_reg
1.236 +#define RMrAX OP_REG, rAX_reg
1.237 +#define RMrBX OP_REG, rBX_reg
1.238 +#define RMrCX OP_REG, rCX_reg
1.239 +#define RMrDX OP_REG, rDX_reg
1.240 +#define RMrSP OP_REG, rSP_reg
1.241 +#define RMrBP OP_REG, rBP_reg
1.242 +#define RMrSI OP_REG, rSI_reg
1.243 +#define RMrDI OP_REG, rDI_reg
1.244 +#define RMAL OP_REG, al_reg
1.245 +#define RMAL OP_REG, al_reg
1.246 +#define RMCL OP_REG, cl_reg
1.247 +#define RMDL OP_REG, dl_reg
1.248 +#define RMBL OP_REG, bl_reg
1.249 +#define RMAH OP_REG, ah_reg
1.250 +#define RMCH OP_REG, ch_reg
1.251 +#define RMDH OP_REG, dh_reg
1.252 +#define RMBH OP_REG, bh_reg
1.253 +#define RMAX OP_REG, ax_reg
1.254 +#define RMDX OP_REG, dx_reg
1.256 +#define eAX OP_IMREG, eAX_reg
1.257 +#define eBX OP_IMREG, eBX_reg
1.258 +#define eCX OP_IMREG, eCX_reg
1.259 +#define eDX OP_IMREG, eDX_reg
1.260 +#define eSP OP_IMREG, eSP_reg
1.261 +#define eBP OP_IMREG, eBP_reg
1.262 +#define eSI OP_IMREG, eSI_reg
1.263 +#define eDI OP_IMREG, eDI_reg
1.264 +#define AL OP_IMREG, al_reg
1.265 +#define AL OP_IMREG, al_reg
1.266 +#define CL OP_IMREG, cl_reg
1.267 +#define DL OP_IMREG, dl_reg
1.268 +#define BL OP_IMREG, bl_reg
1.269 +#define AH OP_IMREG, ah_reg
1.270 +#define CH OP_IMREG, ch_reg
1.271 +#define DH OP_IMREG, dh_reg
1.272 +#define BH OP_IMREG, bh_reg
1.273 +#define AX OP_IMREG, ax_reg
1.274 +#define DX OP_IMREG, dx_reg
1.275 +#define indirDX OP_IMREG, indir_dx_reg
1.277 +#define Sw OP_SEG, w_mode
1.278 +#define Ap OP_DIR, 0
1.279 +#define Ob OP_OFF, b_mode
1.280 +#define Ob64 OP_OFF64, b_mode
1.281 +#define Ov OP_OFF, v_mode
1.282 +#define Ov64 OP_OFF64, v_mode
1.283 +#define Xb OP_DSreg, eSI_reg
1.284 +#define Xv OP_DSreg, eSI_reg
1.285 +#define Yb OP_ESreg, eDI_reg
1.286 +#define Yv OP_ESreg, eDI_reg
1.287 +#define DSBX OP_DSreg, eBX_reg
1.289 +#define es OP_REG, es_reg
1.290 +#define ss OP_REG, ss_reg
1.291 +#define cs OP_REG, cs_reg
1.292 +#define ds OP_REG, ds_reg
1.293 +#define fs OP_REG, fs_reg
1.294 +#define gs OP_REG, gs_reg
1.296 +#define MX OP_MMX, 0
1.297 +#define XM OP_XMM, 0
1.298 +#define EM OP_EM, v_mode
1.299 +#define EX OP_EX, v_mode
1.300 +#define MS OP_MS, v_mode
1.301 +#define XS OP_XS, v_mode
1.302 +#define OPSUF OP_3DNowSuffix, 0
1.303 +#define OPSIMD OP_SIMD_Suffix, 0
1.305 +#define cond_jump_flag NULL, cond_jump_mode
1.306 +#define loop_jcxz_flag NULL, loop_jcxz_mode
1.308 +/* bits in sizeflag */
1.309 +#define SUFFIX_ALWAYS 4
1.313 +#define b_mode 1 /* byte operand */
1.314 +#define v_mode 2 /* operand size depends on prefixes */
1.315 +#define w_mode 3 /* word operand */
1.316 +#define d_mode 4 /* double word operand */
1.317 +#define q_mode 5 /* quad word operand */
1.318 +#define t_mode 6 /* ten-byte operand */
1.319 +#define x_mode 7 /* 16-byte XMM operand */
1.320 +#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
1.321 +#define cond_jump_mode 9
1.322 +#define loop_jcxz_mode 10
1.323 +#define dq_mode 11 /* operand size depends on REX prefixes. */
1.324 +#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
1.325 +#define f_mode 13 /* 4- or 6-byte pointer operand */
1.326 +#define const_1_mode 14
1.328 +#define es_reg 100
1.329 +#define cs_reg 101
1.330 +#define ss_reg 102
1.331 +#define ds_reg 103
1.332 +#define fs_reg 104
1.333 +#define gs_reg 105
1.335 +#define eAX_reg 108
1.336 +#define eCX_reg 109
1.337 +#define eDX_reg 110
1.338 +#define eBX_reg 111
1.339 +#define eSP_reg 112
1.340 +#define eBP_reg 113
1.341 +#define eSI_reg 114
1.342 +#define eDI_reg 115
1.344 +#define al_reg 116
1.345 +#define cl_reg 117
1.346 +#define dl_reg 118
1.347 +#define bl_reg 119
1.348 +#define ah_reg 120
1.349 +#define ch_reg 121
1.350 +#define dh_reg 122
1.351 +#define bh_reg 123
1.353 +#define ax_reg 124
1.354 +#define cx_reg 125
1.355 +#define dx_reg 126
1.356 +#define bx_reg 127
1.357 +#define sp_reg 128
1.358 +#define bp_reg 129
1.359 +#define si_reg 130
1.360 +#define di_reg 131
1.362 +#define rAX_reg 132
1.363 +#define rCX_reg 133
1.364 +#define rDX_reg 134
1.365 +#define rBX_reg 135
1.366 +#define rSP_reg 136
1.367 +#define rBP_reg 137
1.368 +#define rSI_reg 138
1.369 +#define rDI_reg 139
1.371 +#define indir_dx_reg 150
1.373 +#define FLOATCODE 1
1.374 +#define USE_GROUPS 2
1.375 +#define USE_PREFIX_USER_TABLE 3
1.376 +#define X86_64_SPECIAL 4
1.378 +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
1.380 +#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
1.381 +#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
1.382 +#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
1.383 +#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
1.384 +#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
1.385 +#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
1.386 +#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
1.387 +#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
1.388 +#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
1.389 +#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
1.390 +#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
1.391 +#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
1.392 +#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
1.393 +#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
1.394 +#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
1.395 +#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
1.396 +#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
1.397 +#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
1.398 +#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
1.399 +#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
1.400 +#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
1.401 +#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
1.402 +#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
1.403 +#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
1.404 +#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
1.406 +#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
1.407 +#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
1.408 +#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
1.409 +#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
1.410 +#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
1.411 +#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
1.412 +#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
1.413 +#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
1.414 +#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
1.415 +#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
1.416 +#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
1.417 +#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
1.418 +#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
1.419 +#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
1.420 +#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
1.421 +#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
1.422 +#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
1.423 +#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
1.424 +#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
1.425 +#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
1.426 +#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
1.427 +#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
1.428 +#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
1.429 +#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
1.430 +#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
1.431 +#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
1.432 +#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
1.433 +#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
1.434 +#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
1.435 +#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
1.436 +#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
1.437 +#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
1.438 +#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
1.440 +#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
1.442 +typedef void (*op_rtn) (int bytemode, int sizeflag);
1.445 + const char *name;
1.454 +/* Upper case letters in the instruction names here are macros.
1.455 + 'A' => print 'b' if no register operands or suffix_always is true
1.456 + 'B' => print 'b' if suffix_always is true
1.457 + 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
1.459 + 'E' => print 'e' if 32-bit form of jcxz
1.460 + 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
1.461 + 'H' => print ",pt" or ",pn" branch hint
1.462 + 'I' => honor following macro letter even in Intel mode (implemented only
1.463 + . for some of the macro letters)
1.465 + 'L' => print 'l' if suffix_always is true
1.466 + 'N' => print 'n' if instruction has no wait "prefix"
1.467 + 'O' => print 'd', or 'o'
1.468 + 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
1.469 + . or suffix_always is true. print 'q' if rex prefix is present.
1.470 + 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
1.472 + 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
1.473 + 'S' => print 'w', 'l' or 'q' if suffix_always is true
1.474 + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
1.475 + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
1.476 + 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
1.477 + 'X' => print 's', 'd' depending on data16 prefix (for XMM)
1.478 + 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
1.480 + Many of the above letters print nothing in Intel mode. See "putop"
1.483 + Braces '{' and '}', and vertical bars '|', indicate alternative
1.484 + mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
1.485 + modes. In cases where there are only two alternatives, the X86_64
1.486 + instruction is reserved, and "(bad)" is printed.
1.489 +static const struct dis386 dis386[] = {
1.491 + { "addB", Eb, Gb, XX },
1.492 + { "addS", Ev, Gv, XX },
1.493 + { "addB", Gb, Eb, XX },
1.494 + { "addS", Gv, Ev, XX },
1.495 + { "addB", AL, Ib, XX },
1.496 + { "addS", eAX, Iv, XX },
1.497 + { "push{T|}", es, XX, XX },
1.498 + { "pop{T|}", es, XX, XX },
1.500 + { "orB", Eb, Gb, XX },
1.501 + { "orS", Ev, Gv, XX },
1.502 + { "orB", Gb, Eb, XX },
1.503 + { "orS", Gv, Ev, XX },
1.504 + { "orB", AL, Ib, XX },
1.505 + { "orS", eAX, Iv, XX },
1.506 + { "push{T|}", cs, XX, XX },
1.507 + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
1.509 + { "adcB", Eb, Gb, XX },
1.510 + { "adcS", Ev, Gv, XX },
1.511 + { "adcB", Gb, Eb, XX },
1.512 + { "adcS", Gv, Ev, XX },
1.513 + { "adcB", AL, Ib, XX },
1.514 + { "adcS", eAX, Iv, XX },
1.515 + { "push{T|}", ss, XX, XX },
1.516 + { "popT|}", ss, XX, XX },
1.518 + { "sbbB", Eb, Gb, XX },
1.519 + { "sbbS", Ev, Gv, XX },
1.520 + { "sbbB", Gb, Eb, XX },
1.521 + { "sbbS", Gv, Ev, XX },
1.522 + { "sbbB", AL, Ib, XX },
1.523 + { "sbbS", eAX, Iv, XX },
1.524 + { "push{T|}", ds, XX, XX },
1.525 + { "pop{T|}", ds, XX, XX },
1.527 + { "andB", Eb, Gb, XX },
1.528 + { "andS", Ev, Gv, XX },
1.529 + { "andB", Gb, Eb, XX },
1.530 + { "andS", Gv, Ev, XX },
1.531 + { "andB", AL, Ib, XX },
1.532 + { "andS", eAX, Iv, XX },
1.533 + { "(bad)", XX, XX, XX }, /* SEG ES prefix */
1.534 + { "daa{|}", XX, XX, XX },
1.536 + { "subB", Eb, Gb, XX },
1.537 + { "subS", Ev, Gv, XX },
1.538 + { "subB", Gb, Eb, XX },
1.539 + { "subS", Gv, Ev, XX },
1.540 + { "subB", AL, Ib, XX },
1.541 + { "subS", eAX, Iv, XX },
1.542 + { "(bad)", XX, XX, XX }, /* SEG CS prefix */
1.543 + { "das{|}", XX, XX, XX },
1.545 + { "xorB", Eb, Gb, XX },
1.546 + { "xorS", Ev, Gv, XX },
1.547 + { "xorB", Gb, Eb, XX },
1.548 + { "xorS", Gv, Ev, XX },
1.549 + { "xorB", AL, Ib, XX },
1.550 + { "xorS", eAX, Iv, XX },
1.551 + { "(bad)", XX, XX, XX }, /* SEG SS prefix */
1.552 + { "aaa{|}", XX, XX, XX },
1.554 + { "cmpB", Eb, Gb, XX },
1.555 + { "cmpS", Ev, Gv, XX },
1.556 + { "cmpB", Gb, Eb, XX },
1.557 + { "cmpS", Gv, Ev, XX },
1.558 + { "cmpB", AL, Ib, XX },
1.559 + { "cmpS", eAX, Iv, XX },
1.560 + { "(bad)", XX, XX, XX }, /* SEG DS prefix */
1.561 + { "aas{|}", XX, XX, XX },
1.563 + { "inc{S|}", RMeAX, XX, XX },
1.564 + { "inc{S|}", RMeCX, XX, XX },
1.565 + { "inc{S|}", RMeDX, XX, XX },
1.566 + { "inc{S|}", RMeBX, XX, XX },
1.567 + { "inc{S|}", RMeSP, XX, XX },
1.568 + { "inc{S|}", RMeBP, XX, XX },
1.569 + { "inc{S|}", RMeSI, XX, XX },
1.570 + { "inc{S|}", RMeDI, XX, XX },
1.572 + { "dec{S|}", RMeAX, XX, XX },
1.573 + { "dec{S|}", RMeCX, XX, XX },
1.574 + { "dec{S|}", RMeDX, XX, XX },
1.575 + { "dec{S|}", RMeBX, XX, XX },
1.576 + { "dec{S|}", RMeSP, XX, XX },
1.577 + { "dec{S|}", RMeBP, XX, XX },
1.578 + { "dec{S|}", RMeSI, XX, XX },
1.579 + { "dec{S|}", RMeDI, XX, XX },
1.581 + { "pushS", RMrAX, XX, XX },
1.582 + { "pushS", RMrCX, XX, XX },
1.583 + { "pushS", RMrDX, XX, XX },
1.584 + { "pushS", RMrBX, XX, XX },
1.585 + { "pushS", RMrSP, XX, XX },
1.586 + { "pushS", RMrBP, XX, XX },
1.587 + { "pushS", RMrSI, XX, XX },
1.588 + { "pushS", RMrDI, XX, XX },
1.590 + { "popS", RMrAX, XX, XX },
1.591 + { "popS", RMrCX, XX, XX },
1.592 + { "popS", RMrDX, XX, XX },
1.593 + { "popS", RMrBX, XX, XX },
1.594 + { "popS", RMrSP, XX, XX },
1.595 + { "popS", RMrBP, XX, XX },
1.596 + { "popS", RMrSI, XX, XX },
1.597 + { "popS", RMrDI, XX, XX },
1.599 + { "pusha{P|}", XX, XX, XX },
1.600 + { "popa{P|}", XX, XX, XX },
1.601 + { "bound{S|}", Gv, Ma, XX },
1.603 + { "(bad)", XX, XX, XX }, /* seg fs */
1.604 + { "(bad)", XX, XX, XX }, /* seg gs */
1.605 + { "(bad)", XX, XX, XX }, /* op size prefix */
1.606 + { "(bad)", XX, XX, XX }, /* adr size prefix */
1.608 + { "pushT", Iq, XX, XX },
1.609 + { "imulS", Gv, Ev, Iv },
1.610 + { "pushT", sIb, XX, XX },
1.611 + { "imulS", Gv, Ev, sIb },
1.612 + { "ins{b||b|}", Yb, indirDX, XX },
1.613 + { "ins{R||R|}", Yv, indirDX, XX },
1.614 + { "outs{b||b|}", indirDX, Xb, XX },
1.615 + { "outs{R||R|}", indirDX, Xv, XX },
1.617 + { "joH", Jb, XX, cond_jump_flag },
1.618 + { "jnoH", Jb, XX, cond_jump_flag },
1.619 + { "jbH", Jb, XX, cond_jump_flag },
1.620 + { "jaeH", Jb, XX, cond_jump_flag },
1.621 + { "jeH", Jb, XX, cond_jump_flag },
1.622 + { "jneH", Jb, XX, cond_jump_flag },
1.623 + { "jbeH", Jb, XX, cond_jump_flag },
1.624 + { "jaH", Jb, XX, cond_jump_flag },
1.626 + { "jsH", Jb, XX, cond_jump_flag },
1.627 + { "jnsH", Jb, XX, cond_jump_flag },
1.628 + { "jpH", Jb, XX, cond_jump_flag },
1.629 + { "jnpH", Jb, XX, cond_jump_flag },
1.630 + { "jlH", Jb, XX, cond_jump_flag },
1.631 + { "jgeH", Jb, XX, cond_jump_flag },
1.632 + { "jleH", Jb, XX, cond_jump_flag },
1.633 + { "jgH", Jb, XX, cond_jump_flag },
1.637 + { "(bad)", XX, XX, XX },
1.639 + { "testB", Eb, Gb, XX },
1.640 + { "testS", Ev, Gv, XX },
1.641 + { "xchgB", Eb, Gb, XX },
1.642 + { "xchgS", Ev, Gv, XX },
1.644 + { "movB", Eb, Gb, XX },
1.645 + { "movS", Ev, Gv, XX },
1.646 + { "movB", Gb, Eb, XX },
1.647 + { "movS", Gv, Ev, XX },
1.648 + { "movQ", Ev, Sw, XX },
1.649 + { "leaS", Gv, M, XX },
1.650 + { "movQ", Sw, Ev, XX },
1.651 + { "popU", Ev, XX, XX },
1.653 + { "nop", NOP_Fixup, 0, XX, XX },
1.654 + { "xchgS", RMeCX, eAX, XX },
1.655 + { "xchgS", RMeDX, eAX, XX },
1.656 + { "xchgS", RMeBX, eAX, XX },
1.657 + { "xchgS", RMeSP, eAX, XX },
1.658 + { "xchgS", RMeBP, eAX, XX },
1.659 + { "xchgS", RMeSI, eAX, XX },
1.660 + { "xchgS", RMeDI, eAX, XX },
1.662 + { "cW{tR||tR|}", XX, XX, XX },
1.663 + { "cR{tO||tO|}", XX, XX, XX },
1.664 + { "Jcall{T|}", Ap, XX, XX },
1.665 + { "(bad)", XX, XX, XX }, /* fwait */
1.666 + { "pushfT", XX, XX, XX },
1.667 + { "popfT", XX, XX, XX },
1.668 + { "sahf{|}", XX, XX, XX },
1.669 + { "lahf{|}", XX, XX, XX },
1.671 + { "movB", AL, Ob64, XX },
1.672 + { "movS", eAX, Ov64, XX },
1.673 + { "movB", Ob64, AL, XX },
1.674 + { "movS", Ov64, eAX, XX },
1.675 + { "movs{b||b|}", Yb, Xb, XX },
1.676 + { "movs{R||R|}", Yv, Xv, XX },
1.677 + { "cmps{b||b|}", Xb, Yb, XX },
1.678 + { "cmps{R||R|}", Xv, Yv, XX },
1.680 + { "testB", AL, Ib, XX },
1.681 + { "testS", eAX, Iv, XX },
1.682 + { "stosB", Yb, AL, XX },
1.683 + { "stosS", Yv, eAX, XX },
1.684 + { "lodsB", AL, Xb, XX },
1.685 + { "lodsS", eAX, Xv, XX },
1.686 + { "scasB", AL, Yb, XX },
1.687 + { "scasS", eAX, Yv, XX },
1.689 + { "movB", RMAL, Ib, XX },
1.690 + { "movB", RMCL, Ib, XX },
1.691 + { "movB", RMDL, Ib, XX },
1.692 + { "movB", RMBL, Ib, XX },
1.693 + { "movB", RMAH, Ib, XX },
1.694 + { "movB", RMCH, Ib, XX },
1.695 + { "movB", RMDH, Ib, XX },
1.696 + { "movB", RMBH, Ib, XX },
1.698 + { "movS", RMeAX, Iv64, XX },
1.699 + { "movS", RMeCX, Iv64, XX },
1.700 + { "movS", RMeDX, Iv64, XX },
1.701 + { "movS", RMeBX, Iv64, XX },
1.702 + { "movS", RMeSP, Iv64, XX },
1.703 + { "movS", RMeBP, Iv64, XX },
1.704 + { "movS", RMeSI, Iv64, XX },
1.705 + { "movS", RMeDI, Iv64, XX },
1.709 + { "retT", Iw, XX, XX },
1.710 + { "retT", XX, XX, XX },
1.711 + { "les{S|}", Gv, Mp, XX },
1.712 + { "ldsS", Gv, Mp, XX },
1.713 + { "movA", Eb, Ib, XX },
1.714 + { "movQ", Ev, Iv, XX },
1.716 + { "enterT", Iw, Ib, XX },
1.717 + { "leaveT", XX, XX, XX },
1.718 + { "lretP", Iw, XX, XX },
1.719 + { "lretP", XX, XX, XX },
1.720 + { "int3", XX, XX, XX },
1.721 + { "int", Ib, XX, XX },
1.722 + { "into{|}", XX, XX, XX },
1.723 + { "iretP", XX, XX, XX },
1.729 + { "aam{|}", sIb, XX, XX },
1.730 + { "aad{|}", sIb, XX, XX },
1.731 + { "(bad)", XX, XX, XX },
1.732 + { "xlat", DSBX, XX, XX },
1.743 + { "loopneFH", Jb, XX, loop_jcxz_flag },
1.744 + { "loopeFH", Jb, XX, loop_jcxz_flag },
1.745 + { "loopFH", Jb, XX, loop_jcxz_flag },
1.746 + { "jEcxzH", Jb, XX, loop_jcxz_flag },
1.747 + { "inB", AL, Ib, XX },
1.748 + { "inS", eAX, Ib, XX },
1.749 + { "outB", Ib, AL, XX },
1.750 + { "outS", Ib, eAX, XX },
1.752 + { "callT", Jv, XX, XX },
1.753 + { "jmpT", Jv, XX, XX },
1.754 + { "Jjmp{T|}", Ap, XX, XX },
1.755 + { "jmp", Jb, XX, XX },
1.756 + { "inB", AL, indirDX, XX },
1.757 + { "inS", eAX, indirDX, XX },
1.758 + { "outB", indirDX, AL, XX },
1.759 + { "outS", indirDX, eAX, XX },
1.761 + { "(bad)", XX, XX, XX }, /* lock prefix */
1.762 + { "icebp", XX, XX, XX },
1.763 + { "(bad)", XX, XX, XX }, /* repne */
1.764 + { "(bad)", XX, XX, XX }, /* repz */
1.765 + { "hlt", XX, XX, XX },
1.766 + { "cmc", XX, XX, XX },
1.770 + { "clc", XX, XX, XX },
1.771 + { "stc", XX, XX, XX },
1.772 + { "cli", XX, XX, XX },
1.773 + { "sti", XX, XX, XX },
1.774 + { "cld", XX, XX, XX },
1.775 + { "std", XX, XX, XX },
1.780 +static const struct dis386 dis386_twobyte[] = {
1.784 + { "larS", Gv, Ew, XX },
1.785 + { "lslS", Gv, Ew, XX },
1.786 + { "(bad)", XX, XX, XX },
1.787 + { "syscall", XX, XX, XX },
1.788 + { "clts", XX, XX, XX },
1.789 + { "sysretP", XX, XX, XX },
1.791 + { "invd", XX, XX, XX },
1.792 + { "wbinvd", XX, XX, XX },
1.793 + { "(bad)", XX, XX, XX },
1.794 + { "ud2a", XX, XX, XX },
1.795 + { "(bad)", XX, XX, XX },
1.797 + { "femms", XX, XX, XX },
1.798 + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
1.803 + { "movlpX", EX, XM, SIMD_Fixup, 'h' },
1.804 + { "unpcklpX", XM, EX, XX },
1.805 + { "unpckhpX", XM, EX, XX },
1.807 + { "movhpX", EX, XM, SIMD_Fixup, 'l' },
1.810 + { "(bad)", XX, XX, XX },
1.811 + { "(bad)", XX, XX, XX },
1.812 + { "(bad)", XX, XX, XX },
1.813 + { "(bad)", XX, XX, XX },
1.814 + { "(bad)", XX, XX, XX },
1.815 + { "(bad)", XX, XX, XX },
1.816 + { "(bad)", XX, XX, XX },
1.818 + { "movL", Rm, Cm, XX },
1.819 + { "movL", Rm, Dm, XX },
1.820 + { "movL", Cm, Rm, XX },
1.821 + { "movL", Dm, Rm, XX },
1.822 + { "movL", Rd, Td, XX },
1.823 + { "(bad)", XX, XX, XX },
1.824 + { "movL", Td, Rd, XX },
1.825 + { "(bad)", XX, XX, XX },
1.827 + { "movapX", XM, EX, XX },
1.828 + { "movapX", EX, XM, XX },
1.830 + { "movntpX", Ev, XM, XX },
1.833 + { "ucomisX", XM,EX, XX },
1.834 + { "comisX", XM,EX, XX },
1.836 + { "wrmsr", XX, XX, XX },
1.837 + { "rdtsc", XX, XX, XX },
1.838 + { "rdmsr", XX, XX, XX },
1.839 + { "rdpmc", XX, XX, XX },
1.840 + { "sysenter", XX, XX, XX },
1.841 + { "sysexit", XX, XX, XX },
1.842 + { "(bad)", XX, XX, XX },
1.843 + { "(bad)", XX, XX, XX },
1.845 + { "(bad)", XX, XX, XX },
1.846 + { "(bad)", XX, XX, XX },
1.847 + { "(bad)", XX, XX, XX },
1.848 + { "(bad)", XX, XX, XX },
1.849 + { "(bad)", XX, XX, XX },
1.850 + { "(bad)", XX, XX, XX },
1.851 + { "(bad)", XX, XX, XX },
1.852 + { "(bad)", XX, XX, XX },
1.854 + { "cmovo", Gv, Ev, XX },
1.855 + { "cmovno", Gv, Ev, XX },
1.856 + { "cmovb", Gv, Ev, XX },
1.857 + { "cmovae", Gv, Ev, XX },
1.858 + { "cmove", Gv, Ev, XX },
1.859 + { "cmovne", Gv, Ev, XX },
1.860 + { "cmovbe", Gv, Ev, XX },
1.861 + { "cmova", Gv, Ev, XX },
1.863 + { "cmovs", Gv, Ev, XX },
1.864 + { "cmovns", Gv, Ev, XX },
1.865 + { "cmovp", Gv, Ev, XX },
1.866 + { "cmovnp", Gv, Ev, XX },
1.867 + { "cmovl", Gv, Ev, XX },
1.868 + { "cmovge", Gv, Ev, XX },
1.869 + { "cmovle", Gv, Ev, XX },
1.870 + { "cmovg", Gv, Ev, XX },
1.872 + { "movmskpX", Gdq, XS, XX },
1.876 + { "andpX", XM, EX, XX },
1.877 + { "andnpX", XM, EX, XX },
1.878 + { "orpX", XM, EX, XX },
1.879 + { "xorpX", XM, EX, XX },
1.890 + { "punpcklbw", MX, EM, XX },
1.891 + { "punpcklwd", MX, EM, XX },
1.892 + { "punpckldq", MX, EM, XX },
1.893 + { "packsswb", MX, EM, XX },
1.894 + { "pcmpgtb", MX, EM, XX },
1.895 + { "pcmpgtw", MX, EM, XX },
1.896 + { "pcmpgtd", MX, EM, XX },
1.897 + { "packuswb", MX, EM, XX },
1.899 + { "punpckhbw", MX, EM, XX },
1.900 + { "punpckhwd", MX, EM, XX },
1.901 + { "punpckhdq", MX, EM, XX },
1.902 + { "packssdw", MX, EM, XX },
1.905 + { "movd", MX, Edq, XX },
1.912 + { "pcmpeqb", MX, EM, XX },
1.913 + { "pcmpeqw", MX, EM, XX },
1.914 + { "pcmpeqd", MX, EM, XX },
1.915 + { "emms", XX, XX, XX },
1.917 + { "(bad)", XX, XX, XX },
1.918 + { "(bad)", XX, XX, XX },
1.919 + { "(bad)", XX, XX, XX },
1.920 + { "(bad)", XX, XX, XX },
1.926 + { "joH", Jv, XX, cond_jump_flag },
1.927 + { "jnoH", Jv, XX, cond_jump_flag },
1.928 + { "jbH", Jv, XX, cond_jump_flag },
1.929 + { "jaeH", Jv, XX, cond_jump_flag },
1.930 + { "jeH", Jv, XX, cond_jump_flag },
1.931 + { "jneH", Jv, XX, cond_jump_flag },
1.932 + { "jbeH", Jv, XX, cond_jump_flag },
1.933 + { "jaH", Jv, XX, cond_jump_flag },
1.935 + { "jsH", Jv, XX, cond_jump_flag },
1.936 + { "jnsH", Jv, XX, cond_jump_flag },
1.937 + { "jpH", Jv, XX, cond_jump_flag },
1.938 + { "jnpH", Jv, XX, cond_jump_flag },
1.939 + { "jlH", Jv, XX, cond_jump_flag },
1.940 + { "jgeH", Jv, XX, cond_jump_flag },
1.941 + { "jleH", Jv, XX, cond_jump_flag },
1.942 + { "jgH", Jv, XX, cond_jump_flag },
1.944 + { "seto", Eb, XX, XX },
1.945 + { "setno", Eb, XX, XX },
1.946 + { "setb", Eb, XX, XX },
1.947 + { "setae", Eb, XX, XX },
1.948 + { "sete", Eb, XX, XX },
1.949 + { "setne", Eb, XX, XX },
1.950 + { "setbe", Eb, XX, XX },
1.951 + { "seta", Eb, XX, XX },
1.953 + { "sets", Eb, XX, XX },
1.954 + { "setns", Eb, XX, XX },
1.955 + { "setp", Eb, XX, XX },
1.956 + { "setnp", Eb, XX, XX },
1.957 + { "setl", Eb, XX, XX },
1.958 + { "setge", Eb, XX, XX },
1.959 + { "setle", Eb, XX, XX },
1.960 + { "setg", Eb, XX, XX },
1.962 + { "pushT", fs, XX, XX },
1.963 + { "popT", fs, XX, XX },
1.964 + { "cpuid", XX, XX, XX },
1.965 + { "btS", Ev, Gv, XX },
1.966 + { "shldS", Ev, Gv, Ib },
1.967 + { "shldS", Ev, Gv, CL },
1.971 + { "pushT", gs, XX, XX },
1.972 + { "popT", gs, XX, XX },
1.973 + { "rsm", XX, XX, XX },
1.974 + { "btsS", Ev, Gv, XX },
1.975 + { "shrdS", Ev, Gv, Ib },
1.976 + { "shrdS", Ev, Gv, CL },
1.978 + { "imulS", Gv, Ev, XX },
1.980 + { "cmpxchgB", Eb, Gb, XX },
1.981 + { "cmpxchgS", Ev, Gv, XX },
1.982 + { "lssS", Gv, Mp, XX },
1.983 + { "btrS", Ev, Gv, XX },
1.984 + { "lfsS", Gv, Mp, XX },
1.985 + { "lgsS", Gv, Mp, XX },
1.986 + { "movz{bR|x|bR|x}", Gv, Eb, XX },
1.987 + { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
1.989 + { "(bad)", XX, XX, XX },
1.990 + { "ud2b", XX, XX, XX },
1.992 + { "btcS", Ev, Gv, XX },
1.993 + { "bsfS", Gv, Ev, XX },
1.994 + { "bsrS", Gv, Ev, XX },
1.995 + { "movs{bR|x|bR|x}", Gv, Eb, XX },
1.996 + { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
1.998 + { "xaddB", Eb, Gb, XX },
1.999 + { "xaddS", Ev, Gv, XX },
1.1001 + { "movntiS", Ev, Gv, XX },
1.1002 + { "pinsrw", MX, Edqw, Ib },
1.1003 + { "pextrw", Gdq, MS, Ib },
1.1004 + { "shufpX", XM, EX, Ib },
1.1007 + { "bswap", RMeAX, XX, XX },
1.1008 + { "bswap", RMeCX, XX, XX },
1.1009 + { "bswap", RMeDX, XX, XX },
1.1010 + { "bswap", RMeBX, XX, XX },
1.1011 + { "bswap", RMeSP, XX, XX },
1.1012 + { "bswap", RMeBP, XX, XX },
1.1013 + { "bswap", RMeSI, XX, XX },
1.1014 + { "bswap", RMeDI, XX, XX },
1.1017 + { "psrlw", MX, EM, XX },
1.1018 + { "psrld", MX, EM, XX },
1.1019 + { "psrlq", MX, EM, XX },
1.1020 + { "paddq", MX, EM, XX },
1.1021 + { "pmullw", MX, EM, XX },
1.1023 + { "pmovmskb", Gdq, MS, XX },
1.1025 + { "psubusb", MX, EM, XX },
1.1026 + { "psubusw", MX, EM, XX },
1.1027 + { "pminub", MX, EM, XX },
1.1028 + { "pand", MX, EM, XX },
1.1029 + { "paddusb", MX, EM, XX },
1.1030 + { "paddusw", MX, EM, XX },
1.1031 + { "pmaxub", MX, EM, XX },
1.1032 + { "pandn", MX, EM, XX },
1.1034 + { "pavgb", MX, EM, XX },
1.1035 + { "psraw", MX, EM, XX },
1.1036 + { "psrad", MX, EM, XX },
1.1037 + { "pavgw", MX, EM, XX },
1.1038 + { "pmulhuw", MX, EM, XX },
1.1039 + { "pmulhw", MX, EM, XX },
1.1043 + { "psubsb", MX, EM, XX },
1.1044 + { "psubsw", MX, EM, XX },
1.1045 + { "pminsw", MX, EM, XX },
1.1046 + { "por", MX, EM, XX },
1.1047 + { "paddsb", MX, EM, XX },
1.1048 + { "paddsw", MX, EM, XX },
1.1049 + { "pmaxsw", MX, EM, XX },
1.1050 + { "pxor", MX, EM, XX },
1.1053 + { "psllw", MX, EM, XX },
1.1054 + { "pslld", MX, EM, XX },
1.1055 + { "psllq", MX, EM, XX },
1.1056 + { "pmuludq", MX, EM, XX },
1.1057 + { "pmaddwd", MX, EM, XX },
1.1058 + { "psadbw", MX, EM, XX },
1.1061 + { "psubb", MX, EM, XX },
1.1062 + { "psubw", MX, EM, XX },
1.1063 + { "psubd", MX, EM, XX },
1.1064 + { "psubq", MX, EM, XX },
1.1065 + { "paddb", MX, EM, XX },
1.1066 + { "paddw", MX, EM, XX },
1.1067 + { "paddd", MX, EM, XX },
1.1068 + { "(bad)", XX, XX, XX }
1.1071 +static const unsigned char onebyte_has_modrm[256] = {
1.1072 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1073 + /* ------------------------------- */
1.1074 + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1.1075 + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1.1076 + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1.1077 + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1.1078 + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1.1079 + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1.1080 + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1.1081 + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1.1082 + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1.1083 + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1.1084 + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1.1085 + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1.1086 + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1.1087 + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1.1088 + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1.1089 + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1.1090 + /* ------------------------------- */
1.1091 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1094 +static const unsigned char twobyte_has_modrm[256] = {
1.1095 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1096 + /* ------------------------------- */
1.1097 + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1.1098 + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1.1099 + /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1.1100 + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1.1101 + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1.1102 + /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1.1103 + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1.1104 + /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
1.1105 + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1.1106 + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1.1107 + /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1.1108 + /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1.1109 + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1.1110 + /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1.1111 + /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1.1112 + /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1.1113 + /* ------------------------------- */
1.1114 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1117 +static const unsigned char twobyte_uses_SSE_prefix[256] = {
1.1118 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1119 + /* ------------------------------- */
1.1120 + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1.1121 + /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1.1122 + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1.1123 + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1.1124 + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1.1125 + /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1.1126 + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1.1127 + /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1.1128 + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1.1129 + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1.1130 + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1.1131 + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1.1132 + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1.1133 + /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1.1134 + /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1.1135 + /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1.1136 + /* ------------------------------- */
1.1137 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1.1140 +static char obuf[100];
1.1142 +static char scratchbuf[100];
1.1143 +static unsigned char *start_codep;
1.1144 +static unsigned char *insn_codep;
1.1145 +static unsigned char *codep;
1.1146 +static disassemble_info *the_info;
1.1150 +static unsigned char need_modrm;
1.1152 +/* If we are accessing mod/rm/reg without need_modrm set, then the
1.1153 + values are stale. Hitting this abort likely indicates that you
1.1154 + need to update onebyte_has_modrm or twobyte_has_modrm. */
1.1155 +#define MODRM_CHECK if (!need_modrm) abort ()
1.1157 +static const char **names64;
1.1158 +static const char **names32;
1.1159 +static const char **names16;
1.1160 +static const char **names8;
1.1161 +static const char **names8rex;
1.1162 +static const char **names_seg;
1.1163 +static const char **index16;
1.1165 +static const char *intel_names64[] = {
1.1166 + "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1.1167 + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1.1169 +static const char *intel_names32[] = {
1.1170 + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1.1171 + "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1.1173 +static const char *intel_names16[] = {
1.1174 + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1.1175 + "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1.1177 +static const char *intel_names8[] = {
1.1178 + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1.1180 +static const char *intel_names8rex[] = {
1.1181 + "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1.1182 + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1.1184 +static const char *intel_names_seg[] = {
1.1185 + "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1.1187 +static const char *intel_index16[] = {
1.1188 + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1.1191 +static const char *att_names64[] = {
1.1192 + "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1.1193 + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1.1195 +static const char *att_names32[] = {
1.1196 + "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1.1197 + "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1.1199 +static const char *att_names16[] = {
1.1200 + "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1.1201 + "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1.1203 +static const char *att_names8[] = {
1.1204 + "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1.1206 +static const char *att_names8rex[] = {
1.1207 + "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1.1208 + "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1.1210 +static const char *att_names_seg[] = {
1.1211 + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1.1213 +static const char *att_index16[] = {
1.1214 + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1.1217 +static const struct dis386 grps[][8] = {
1.1220 + { "addA", Eb, Ib, XX },
1.1221 + { "orA", Eb, Ib, XX },
1.1222 + { "adcA", Eb, Ib, XX },
1.1223 + { "sbbA", Eb, Ib, XX },
1.1224 + { "andA", Eb, Ib, XX },
1.1225 + { "subA", Eb, Ib, XX },
1.1226 + { "xorA", Eb, Ib, XX },
1.1227 + { "cmpA", Eb, Ib, XX }
1.1231 + { "addQ", Ev, Iv, XX },
1.1232 + { "orQ", Ev, Iv, XX },
1.1233 + { "adcQ", Ev, Iv, XX },
1.1234 + { "sbbQ", Ev, Iv, XX },
1.1235 + { "andQ", Ev, Iv, XX },
1.1236 + { "subQ", Ev, Iv, XX },
1.1237 + { "xorQ", Ev, Iv, XX },
1.1238 + { "cmpQ", Ev, Iv, XX }
1.1242 + { "addQ", Ev, sIb, XX },
1.1243 + { "orQ", Ev, sIb, XX },
1.1244 + { "adcQ", Ev, sIb, XX },
1.1245 + { "sbbQ", Ev, sIb, XX },
1.1246 + { "andQ", Ev, sIb, XX },
1.1247 + { "subQ", Ev, sIb, XX },
1.1248 + { "xorQ", Ev, sIb, XX },
1.1249 + { "cmpQ", Ev, sIb, XX }
1.1253 + { "rolA", Eb, Ib, XX },
1.1254 + { "rorA", Eb, Ib, XX },
1.1255 + { "rclA", Eb, Ib, XX },
1.1256 + { "rcrA", Eb, Ib, XX },
1.1257 + { "shlA", Eb, Ib, XX },
1.1258 + { "shrA", Eb, Ib, XX },
1.1259 + { "(bad)", XX, XX, XX },
1.1260 + { "sarA", Eb, Ib, XX },
1.1264 + { "rolQ", Ev, Ib, XX },
1.1265 + { "rorQ", Ev, Ib, XX },
1.1266 + { "rclQ", Ev, Ib, XX },
1.1267 + { "rcrQ", Ev, Ib, XX },
1.1268 + { "shlQ", Ev, Ib, XX },
1.1269 + { "shrQ", Ev, Ib, XX },
1.1270 + { "(bad)", XX, XX, XX },
1.1271 + { "sarQ", Ev, Ib, XX },
1.1275 + { "rolA", Eb, I1, XX },
1.1276 + { "rorA", Eb, I1, XX },
1.1277 + { "rclA", Eb, I1, XX },
1.1278 + { "rcrA", Eb, I1, XX },
1.1279 + { "shlA", Eb, I1, XX },
1.1280 + { "shrA", Eb, I1, XX },
1.1281 + { "(bad)", XX, XX, XX },
1.1282 + { "sarA", Eb, I1, XX },
1.1286 + { "rolQ", Ev, I1, XX },
1.1287 + { "rorQ", Ev, I1, XX },
1.1288 + { "rclQ", Ev, I1, XX },
1.1289 + { "rcrQ", Ev, I1, XX },
1.1290 + { "shlQ", Ev, I1, XX },
1.1291 + { "shrQ", Ev, I1, XX },
1.1292 + { "(bad)", XX, XX, XX},
1.1293 + { "sarQ", Ev, I1, XX },
1.1297 + { "rolA", Eb, CL, XX },
1.1298 + { "rorA", Eb, CL, XX },
1.1299 + { "rclA", Eb, CL, XX },
1.1300 + { "rcrA", Eb, CL, XX },
1.1301 + { "shlA", Eb, CL, XX },
1.1302 + { "shrA", Eb, CL, XX },
1.1303 + { "(bad)", XX, XX, XX },
1.1304 + { "sarA", Eb, CL, XX },
1.1308 + { "rolQ", Ev, CL, XX },
1.1309 + { "rorQ", Ev, CL, XX },
1.1310 + { "rclQ", Ev, CL, XX },
1.1311 + { "rcrQ", Ev, CL, XX },
1.1312 + { "shlQ", Ev, CL, XX },
1.1313 + { "shrQ", Ev, CL, XX },
1.1314 + { "(bad)", XX, XX, XX },
1.1315 + { "sarQ", Ev, CL, XX }
1.1319 + { "testA", Eb, Ib, XX },
1.1320 + { "(bad)", Eb, XX, XX },
1.1321 + { "notA", Eb, XX, XX },
1.1322 + { "negA", Eb, XX, XX },
1.1323 + { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1.1324 + { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1.1325 + { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1.1326 + { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1.1330 + { "testQ", Ev, Iv, XX },
1.1331 + { "(bad)", XX, XX, XX },
1.1332 + { "notQ", Ev, XX, XX },
1.1333 + { "negQ", Ev, XX, XX },
1.1334 + { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1.1335 + { "imulQ", Ev, XX, XX },
1.1336 + { "divQ", Ev, XX, XX },
1.1337 + { "idivQ", Ev, XX, XX },
1.1341 + { "incA", Eb, XX, XX },
1.1342 + { "decA", Eb, XX, XX },
1.1343 + { "(bad)", XX, XX, XX },
1.1344 + { "(bad)", XX, XX, XX },
1.1345 + { "(bad)", XX, XX, XX },
1.1346 + { "(bad)", XX, XX, XX },
1.1347 + { "(bad)", XX, XX, XX },
1.1348 + { "(bad)", XX, XX, XX },
1.1352 + { "incQ", Ev, XX, XX },
1.1353 + { "decQ", Ev, XX, XX },
1.1354 + { "callT", indirEv, XX, XX },
1.1355 + { "JcallT", indirEp, XX, XX },
1.1356 + { "jmpT", indirEv, XX, XX },
1.1357 + { "JjmpT", indirEp, XX, XX },
1.1358 + { "pushU", Ev, XX, XX },
1.1359 + { "(bad)", XX, XX, XX },
1.1363 + { "sldtQ", Ev, XX, XX },
1.1364 + { "strQ", Ev, XX, XX },
1.1365 + { "lldt", Ew, XX, XX },
1.1366 + { "ltr", Ew, XX, XX },
1.1367 + { "verr", Ew, XX, XX },
1.1368 + { "verw", Ew, XX, XX },
1.1369 + { "(bad)", XX, XX, XX },
1.1370 + { "(bad)", XX, XX, XX }
1.1374 + { "sgdtIQ", M, XX, XX },
1.1375 + { "sidtIQ", PNI_Fixup, 0, XX, XX },
1.1376 + { "lgdt{Q|Q||}", M, XX, XX },
1.1377 + { "lidt{Q|Q||}", M, XX, XX },
1.1378 + { "smswQ", Ev, XX, XX },
1.1379 + { "(bad)", XX, XX, XX },
1.1380 + { "lmsw", Ew, XX, XX },
1.1381 + { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
1.1385 + { "(bad)", XX, XX, XX },
1.1386 + { "(bad)", XX, XX, XX },
1.1387 + { "(bad)", XX, XX, XX },
1.1388 + { "(bad)", XX, XX, XX },
1.1389 + { "btQ", Ev, Ib, XX },
1.1390 + { "btsQ", Ev, Ib, XX },
1.1391 + { "btrQ", Ev, Ib, XX },
1.1392 + { "btcQ", Ev, Ib, XX },
1.1396 + { "(bad)", XX, XX, XX },
1.1397 + { "cmpxchg8b", Eq, XX, XX },
1.1398 + { "(bad)", XX, XX, XX },
1.1399 + { "(bad)", XX, XX, XX },
1.1400 + { "(bad)", XX, XX, XX },
1.1401 + { "(bad)", XX, XX, XX },
1.1402 + { "(bad)", XX, XX, XX },
1.1403 + { "(bad)", XX, XX, XX },
1.1407 + { "(bad)", XX, XX, XX },
1.1408 + { "(bad)", XX, XX, XX },
1.1409 + { "psrlw", MS, Ib, XX },
1.1410 + { "(bad)", XX, XX, XX },
1.1411 + { "psraw", MS, Ib, XX },
1.1412 + { "(bad)", XX, XX, XX },
1.1413 + { "psllw", MS, Ib, XX },
1.1414 + { "(bad)", XX, XX, XX },
1.1418 + { "(bad)", XX, XX, XX },
1.1419 + { "(bad)", XX, XX, XX },
1.1420 + { "psrld", MS, Ib, XX },
1.1421 + { "(bad)", XX, XX, XX },
1.1422 + { "psrad", MS, Ib, XX },
1.1423 + { "(bad)", XX, XX, XX },
1.1424 + { "pslld", MS, Ib, XX },
1.1425 + { "(bad)", XX, XX, XX },
1.1429 + { "(bad)", XX, XX, XX },
1.1430 + { "(bad)", XX, XX, XX },
1.1431 + { "psrlq", MS, Ib, XX },
1.1432 + { "psrldq", MS, Ib, XX },
1.1433 + { "(bad)", XX, XX, XX },
1.1434 + { "(bad)", XX, XX, XX },
1.1435 + { "psllq", MS, Ib, XX },
1.1436 + { "pslldq", MS, Ib, XX },
1.1440 + { "fxsave", Ev, XX, XX },
1.1441 + { "fxrstor", Ev, XX, XX },
1.1442 + { "ldmxcsr", Ev, XX, XX },
1.1443 + { "stmxcsr", Ev, XX, XX },
1.1444 + { "(bad)", XX, XX, XX },
1.1445 + { "lfence", OP_0fae, 0, XX, XX },
1.1446 + { "mfence", OP_0fae, 0, XX, XX },
1.1447 + { "clflush", OP_0fae, 0, XX, XX },
1.1451 + { "prefetchnta", Ev, XX, XX },
1.1452 + { "prefetcht0", Ev, XX, XX },
1.1453 + { "prefetcht1", Ev, XX, XX },
1.1454 + { "prefetcht2", Ev, XX, XX },
1.1455 + { "(bad)", XX, XX, XX },
1.1456 + { "(bad)", XX, XX, XX },
1.1457 + { "(bad)", XX, XX, XX },
1.1458 + { "(bad)", XX, XX, XX },
1.1462 + { "prefetch", Eb, XX, XX },
1.1463 + { "prefetchw", Eb, XX, XX },
1.1464 + { "(bad)", XX, XX, XX },
1.1465 + { "(bad)", XX, XX, XX },
1.1466 + { "(bad)", XX, XX, XX },
1.1467 + { "(bad)", XX, XX, XX },
1.1468 + { "(bad)", XX, XX, XX },
1.1469 + { "(bad)", XX, XX, XX },
1.1473 + { "xstorerng", OP_0f07, 0, XX, XX },
1.1474 + { "xcryptecb", OP_0f07, 0, XX, XX },
1.1475 + { "xcryptcbc", OP_0f07, 0, XX, XX },
1.1476 + { "(bad)", OP_0f07, 0, XX, XX },
1.1477 + { "xcryptcfb", OP_0f07, 0, XX, XX },
1.1478 + { "xcryptofb", OP_0f07, 0, XX, XX },
1.1479 + { "(bad)", OP_0f07, 0, XX, XX },
1.1480 + { "(bad)", OP_0f07, 0, XX, XX },
1.1484 + { "montmul", OP_0f07, 0, XX, XX },
1.1485 + { "xsha1", OP_0f07, 0, XX, XX },
1.1486 + { "xsha256", OP_0f07, 0, XX, XX },
1.1487 + { "(bad)", OP_0f07, 0, XX, XX },
1.1488 + { "(bad)", OP_0f07, 0, XX, XX },
1.1489 + { "(bad)", OP_0f07, 0, XX, XX },
1.1490 + { "(bad)", OP_0f07, 0, XX, XX },
1.1491 + { "(bad)", OP_0f07, 0, XX, XX },
1.1495 +static const struct dis386 prefix_user_table[][4] = {
1.1498 + { "addps", XM, EX, XX },
1.1499 + { "addss", XM, EX, XX },
1.1500 + { "addpd", XM, EX, XX },
1.1501 + { "addsd", XM, EX, XX },
1.1505 + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1.1506 + { "", XM, EX, OPSIMD },
1.1507 + { "", XM, EX, OPSIMD },
1.1508 + { "", XM, EX, OPSIMD },
1.1512 + { "cvtpi2ps", XM, EM, XX },
1.1513 + { "cvtsi2ssY", XM, Ev, XX },
1.1514 + { "cvtpi2pd", XM, EM, XX },
1.1515 + { "cvtsi2sdY", XM, Ev, XX },
1.1519 + { "cvtps2pi", MX, EX, XX },
1.1520 + { "cvtss2siY", Gv, EX, XX },
1.1521 + { "cvtpd2pi", MX, EX, XX },
1.1522 + { "cvtsd2siY", Gv, EX, XX },
1.1526 + { "cvttps2pi", MX, EX, XX },
1.1527 + { "cvttss2siY", Gv, EX, XX },
1.1528 + { "cvttpd2pi", MX, EX, XX },
1.1529 + { "cvttsd2siY", Gv, EX, XX },
1.1533 + { "divps", XM, EX, XX },
1.1534 + { "divss", XM, EX, XX },
1.1535 + { "divpd", XM, EX, XX },
1.1536 + { "divsd", XM, EX, XX },
1.1540 + { "maxps", XM, EX, XX },
1.1541 + { "maxss", XM, EX, XX },
1.1542 + { "maxpd", XM, EX, XX },
1.1543 + { "maxsd", XM, EX, XX },
1.1547 + { "minps", XM, EX, XX },
1.1548 + { "minss", XM, EX, XX },
1.1549 + { "minpd", XM, EX, XX },
1.1550 + { "minsd", XM, EX, XX },
1.1554 + { "movups", XM, EX, XX },
1.1555 + { "movss", XM, EX, XX },
1.1556 + { "movupd", XM, EX, XX },
1.1557 + { "movsd", XM, EX, XX },
1.1561 + { "movups", EX, XM, XX },
1.1562 + { "movss", EX, XM, XX },
1.1563 + { "movupd", EX, XM, XX },
1.1564 + { "movsd", EX, XM, XX },
1.1568 + { "mulps", XM, EX, XX },
1.1569 + { "mulss", XM, EX, XX },
1.1570 + { "mulpd", XM, EX, XX },
1.1571 + { "mulsd", XM, EX, XX },
1.1575 + { "rcpps", XM, EX, XX },
1.1576 + { "rcpss", XM, EX, XX },
1.1577 + { "(bad)", XM, EX, XX },
1.1578 + { "(bad)", XM, EX, XX },
1.1582 + { "rsqrtps", XM, EX, XX },
1.1583 + { "rsqrtss", XM, EX, XX },
1.1584 + { "(bad)", XM, EX, XX },
1.1585 + { "(bad)", XM, EX, XX },
1.1589 + { "sqrtps", XM, EX, XX },
1.1590 + { "sqrtss", XM, EX, XX },
1.1591 + { "sqrtpd", XM, EX, XX },
1.1592 + { "sqrtsd", XM, EX, XX },
1.1596 + { "subps", XM, EX, XX },
1.1597 + { "subss", XM, EX, XX },
1.1598 + { "subpd", XM, EX, XX },
1.1599 + { "subsd", XM, EX, XX },
1.1603 + { "(bad)", XM, EX, XX },
1.1604 + { "cvtdq2pd", XM, EX, XX },
1.1605 + { "cvttpd2dq", XM, EX, XX },
1.1606 + { "cvtpd2dq", XM, EX, XX },
1.1610 + { "cvtdq2ps", XM, EX, XX },
1.1611 + { "cvttps2dq",XM, EX, XX },
1.1612 + { "cvtps2dq",XM, EX, XX },
1.1613 + { "(bad)", XM, EX, XX },
1.1617 + { "cvtps2pd", XM, EX, XX },
1.1618 + { "cvtss2sd", XM, EX, XX },
1.1619 + { "cvtpd2ps", XM, EX, XX },
1.1620 + { "cvtsd2ss", XM, EX, XX },
1.1624 + { "maskmovq", MX, MS, XX },
1.1625 + { "(bad)", XM, EX, XX },
1.1626 + { "maskmovdqu", XM, EX, XX },
1.1627 + { "(bad)", XM, EX, XX },
1.1631 + { "movq", MX, EM, XX },
1.1632 + { "movdqu", XM, EX, XX },
1.1633 + { "movdqa", XM, EX, XX },
1.1634 + { "(bad)", XM, EX, XX },
1.1638 + { "movq", EM, MX, XX },
1.1639 + { "movdqu", EX, XM, XX },
1.1640 + { "movdqa", EX, XM, XX },
1.1641 + { "(bad)", EX, XM, XX },
1.1645 + { "(bad)", EX, XM, XX },
1.1646 + { "movq2dq", XM, MS, XX },
1.1647 + { "movq", EX, XM, XX },
1.1648 + { "movdq2q", MX, XS, XX },
1.1652 + { "pshufw", MX, EM, Ib },
1.1653 + { "pshufhw", XM, EX, Ib },
1.1654 + { "pshufd", XM, EX, Ib },
1.1655 + { "pshuflw", XM, EX, Ib },
1.1659 + { "movd", Edq, MX, XX },
1.1660 + { "movq", XM, EX, XX },
1.1661 + { "movd", Edq, XM, XX },
1.1662 + { "(bad)", Ed, XM, XX },
1.1666 + { "(bad)", MX, EX, XX },
1.1667 + { "(bad)", XM, EX, XX },
1.1668 + { "punpckhqdq", XM, EX, XX },
1.1669 + { "(bad)", XM, EX, XX },
1.1673 + { "movntq", EM, MX, XX },
1.1674 + { "(bad)", EM, XM, XX },
1.1675 + { "movntdq", EM, XM, XX },
1.1676 + { "(bad)", EM, XM, XX },
1.1680 + { "(bad)", MX, EX, XX },
1.1681 + { "(bad)", XM, EX, XX },
1.1682 + { "punpcklqdq", XM, EX, XX },
1.1683 + { "(bad)", XM, EX, XX },
1.1687 + { "(bad)", MX, EX, XX },
1.1688 + { "(bad)", XM, EX, XX },
1.1689 + { "addsubpd", XM, EX, XX },
1.1690 + { "addsubps", XM, EX, XX },
1.1694 + { "(bad)", MX, EX, XX },
1.1695 + { "(bad)", XM, EX, XX },
1.1696 + { "haddpd", XM, EX, XX },
1.1697 + { "haddps", XM, EX, XX },
1.1701 + { "(bad)", MX, EX, XX },
1.1702 + { "(bad)", XM, EX, XX },
1.1703 + { "hsubpd", XM, EX, XX },
1.1704 + { "hsubps", XM, EX, XX },
1.1708 + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1.1709 + { "movsldup", XM, EX, XX },
1.1710 + { "movlpd", XM, EX, XX },
1.1711 + { "movddup", XM, EX, XX },
1.1715 + { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1.1716 + { "movshdup", XM, EX, XX },
1.1717 + { "movhpd", XM, EX, XX },
1.1718 + { "(bad)", XM, EX, XX },
1.1722 + { "(bad)", XM, EX, XX },
1.1723 + { "(bad)", XM, EX, XX },
1.1724 + { "(bad)", XM, EX, XX },
1.1725 + { "lddqu", XM, M, XX },
1.1729 +static const struct dis386 x86_64_table[][2] = {
1.1731 + { "arpl", Ew, Gw, XX },
1.1732 + { "movs{||lq|xd}", Gv, Ed, XX },
1.1736 +#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1.1748 + FETCH_DATA (the_info, codep + 1);
1.1752 + /* REX prefixes family. */
1.1775 + prefixes |= PREFIX_REPZ;
1.1778 + prefixes |= PREFIX_REPNZ;
1.1781 + prefixes |= PREFIX_LOCK;
1.1784 + prefixes |= PREFIX_CS;
1.1787 + prefixes |= PREFIX_SS;
1.1790 + prefixes |= PREFIX_DS;
1.1793 + prefixes |= PREFIX_ES;
1.1796 + prefixes |= PREFIX_FS;
1.1799 + prefixes |= PREFIX_GS;
1.1802 + prefixes |= PREFIX_DATA;
1.1805 + prefixes |= PREFIX_ADDR;
1.1808 + /* fwait is really an instruction. If there are prefixes
1.1809 + before the fwait, they belong to the fwait, *not* to the
1.1810 + following instruction. */
1.1813 + prefixes |= PREFIX_FWAIT;
1.1817 + prefixes = PREFIX_FWAIT;
1.1822 + /* Rex is ignored when followed by another prefix. */
1.1825 + oappend (prefix_name (rex, 0));
1.1833 +/* Return the name of the prefix byte PREF, or NULL if PREF is not a
1.1837 +prefix_name (int pref, int sizeflag)
1.1841 + /* REX prefixes family. */
1.1893 + return (sizeflag & DFLAG) ? "data16" : "data32";
1.1896 + return (sizeflag & AFLAG) ? "addr32" : "addr64";
1.1898 + return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1.1906 +static char op1out[100], op2out[100], op3out[100];
1.1907 +static int op_ad, op_index[3];
1.1908 +static int two_source_ops;
1.1909 +static bfd_vma op_address[3];
1.1910 +static bfd_vma op_riprel[3];
1.1911 +static bfd_vma start_pc;
1.1914 + * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1.1915 + * (see topic "Redundant prefixes" in the "Differences from 8086"
1.1916 + * section of the "Virtual 8086 Mode" chapter.)
1.1917 + * 'pc' should be the address of this instruction, it will
1.1918 + * be used to print the target address if this is a relative jump or call
1.1919 + * The function returns the length of this instruction in bytes.
1.1922 +static char intel_syntax;
1.1923 +static char open_char;
1.1924 +static char close_char;
1.1925 +static char separator_char;
1.1926 +static char scale_char;
1.1928 +/* Here for backwards compatibility. When gdb stops using
1.1929 + print_insn_i386_att and print_insn_i386_intel these functions can
1.1930 + disappear, and print_insn_i386 be merged into print_insn. */
1.1932 +print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1.1936 + return print_insn (pc, info);
1.1940 +print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1.1944 + return print_insn (pc, info);
1.1948 +print_insn_i386 (bfd_vma pc, disassemble_info *info)
1.1952 + return print_insn (pc, info);
1.1956 +print_insn (bfd_vma pc, disassemble_info *info)
1.1958 + const struct dis386 *dp;
1.1960 + char *first, *second, *third;
1.1962 + unsigned char uses_SSE_prefix, uses_LOCK_prefix;
1.1965 + struct dis_private priv;
1.1967 + mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1.1968 + || info->mach == bfd_mach_x86_64);
1.1970 + if (intel_syntax == (char) -1)
1.1971 + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1.1972 + || info->mach == bfd_mach_x86_64_intel_syntax);
1.1974 + if (info->mach == bfd_mach_i386_i386
1.1975 + || info->mach == bfd_mach_x86_64
1.1976 + || info->mach == bfd_mach_i386_i386_intel_syntax
1.1977 + || info->mach == bfd_mach_x86_64_intel_syntax)
1.1978 + priv.orig_sizeflag = AFLAG | DFLAG;
1.1979 + else if (info->mach == bfd_mach_i386_i8086)
1.1980 + priv.orig_sizeflag = 0;
1.1984 + for (p = info->disassembler_options; p != NULL; )
1.1986 + if (strncmp (p, "x86-64", 6) == 0)
1.1989 + priv.orig_sizeflag = AFLAG | DFLAG;
1.1991 + else if (strncmp (p, "i386", 4) == 0)
1.1994 + priv.orig_sizeflag = AFLAG | DFLAG;
1.1996 + else if (strncmp (p, "i8086", 5) == 0)
1.1999 + priv.orig_sizeflag = 0;
1.2001 + else if (strncmp (p, "intel", 5) == 0)
1.2005 + else if (strncmp (p, "att", 3) == 0)
1.2009 + else if (strncmp (p, "addr", 4) == 0)
1.2011 + if (p[4] == '1' && p[5] == '6')
1.2012 + priv.orig_sizeflag &= ~AFLAG;
1.2013 + else if (p[4] == '3' && p[5] == '2')
1.2014 + priv.orig_sizeflag |= AFLAG;
1.2016 + else if (strncmp (p, "data", 4) == 0)
1.2018 + if (p[4] == '1' && p[5] == '6')
1.2019 + priv.orig_sizeflag &= ~DFLAG;
1.2020 + else if (p[4] == '3' && p[5] == '2')
1.2021 + priv.orig_sizeflag |= DFLAG;
1.2023 + else if (strncmp (p, "suffix", 6) == 0)
1.2024 + priv.orig_sizeflag |= SUFFIX_ALWAYS;
1.2033 + names64 = intel_names64;
1.2034 + names32 = intel_names32;
1.2035 + names16 = intel_names16;
1.2036 + names8 = intel_names8;
1.2037 + names8rex = intel_names8rex;
1.2038 + names_seg = intel_names_seg;
1.2039 + index16 = intel_index16;
1.2042 + separator_char = '+';
1.2047 + names64 = att_names64;
1.2048 + names32 = att_names32;
1.2049 + names16 = att_names16;
1.2051 + names8rex = att_names8rex;
1.2052 + names_seg = att_names_seg;
1.2053 + index16 = att_index16;
1.2056 + separator_char = ',';
1.2060 + /* The output looks better if we put 7 bytes on a line, since that
1.2061 + puts most long word instructions on a single line. */
1.2062 + info->bytes_per_line = 7;
1.2064 + info->private_data = &priv;
1.2065 + priv.max_fetched = priv.the_buffer;
1.2066 + priv.insn_start = pc;
1.2073 + op_index[0] = op_index[1] = op_index[2] = -1;
1.2077 + start_codep = priv.the_buffer;
1.2078 + codep = priv.the_buffer;
1.2080 + if (setjmp (priv.bailout) != 0)
1.2084 + /* Getting here means we tried for data but didn't get it. That
1.2085 + means we have an incomplete instruction of some sort. Just
1.2086 + print the first byte as a prefix or a .byte pseudo-op. */
1.2087 + if (codep > priv.the_buffer)
1.2089 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
1.2091 + (*info->fprintf_func) (info->stream, "%s", name);
1.2094 + /* Just print the first byte as a .byte instruction. */
1.2095 + (*info->fprintf_func) (info->stream, ".byte 0x%x",
1.2096 + (unsigned int) priv.the_buffer[0]);
1.2109 + sizeflag = priv.orig_sizeflag;
1.2111 + FETCH_DATA (info, codep + 1);
1.2112 + two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
1.2114 + if ((prefixes & PREFIX_FWAIT)
1.2115 + && ((*codep < 0xd8) || (*codep > 0xdf)))
1.2119 + /* fwait not followed by floating point instruction. Print the
1.2120 + first prefix, which is probably fwait itself. */
1.2121 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
1.2123 + name = INTERNAL_DISASSEMBLER_ERROR;
1.2124 + (*info->fprintf_func) (info->stream, "%s", name);
1.2130 + FETCH_DATA (info, codep + 2);
1.2131 + dp = &dis386_twobyte[*++codep];
1.2132 + need_modrm = twobyte_has_modrm[*codep];
1.2133 + uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
1.2134 + uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
1.2138 + dp = &dis386[*codep];
1.2139 + need_modrm = onebyte_has_modrm[*codep];
1.2141 + uses_LOCK_prefix = 0;
1.2145 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
1.2148 + used_prefixes |= PREFIX_REPZ;
1.2150 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
1.2153 + used_prefixes |= PREFIX_REPNZ;
1.2155 + if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
1.2158 + used_prefixes |= PREFIX_LOCK;
1.2161 + if (prefixes & PREFIX_ADDR)
1.2164 + if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
1.2166 + if ((sizeflag & AFLAG) || mode_64bit)
1.2170 + used_prefixes |= PREFIX_ADDR;
1.2174 + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
1.2177 + if (dp->bytemode3 == cond_jump_mode
1.2178 + && dp->bytemode1 == v_mode
1.2181 + if (sizeflag & DFLAG)
1.2185 + used_prefixes |= PREFIX_DATA;
1.2191 + FETCH_DATA (info, codep + 1);
1.2192 + mod = (*codep >> 6) & 3;
1.2193 + reg = (*codep >> 3) & 7;
1.2197 + if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1.2204 + if (dp->name == NULL)
1.2206 + switch (dp->bytemode1)
1.2209 + dp = &grps[dp->bytemode2][reg];
1.2212 + case USE_PREFIX_USER_TABLE:
1.2214 + used_prefixes |= (prefixes & PREFIX_REPZ);
1.2215 + if (prefixes & PREFIX_REPZ)
1.2219 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2220 + if (prefixes & PREFIX_DATA)
1.2224 + used_prefixes |= (prefixes & PREFIX_REPNZ);
1.2225 + if (prefixes & PREFIX_REPNZ)
1.2229 + dp = &prefix_user_table[dp->bytemode2][index];
1.2233 + dp = &x86_64_table[dp->bytemode2][mode_64bit];
1.2237 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.2242 + if (putop (dp->name, sizeflag) == 0)
1.2247 + (*dp->op1) (dp->bytemode1, sizeflag);
1.2252 + (*dp->op2) (dp->bytemode2, sizeflag);
1.2257 + (*dp->op3) (dp->bytemode3, sizeflag);
1.2261 + /* See if any prefixes were not used. If so, print the first one
1.2262 + separately. If we don't do this, we'll wind up printing an
1.2263 + instruction stream which does not precisely correspond to the
1.2264 + bytes we are disassembling. */
1.2265 + if ((prefixes & ~used_prefixes) != 0)
1.2269 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
1.2271 + name = INTERNAL_DISASSEMBLER_ERROR;
1.2272 + (*info->fprintf_func) (info->stream, "%s", name);
1.2278 + name = prefix_name (rex | 0x40, priv.orig_sizeflag);
1.2280 + name = INTERNAL_DISASSEMBLER_ERROR;
1.2281 + (*info->fprintf_func) (info->stream, "%s ", name);
1.2284 + obufp = obuf + strlen (obuf);
1.2285 + for (i = strlen (obuf); i < 6; i++)
1.2288 + (*info->fprintf_func) (info->stream, "%s", obuf);
1.2290 + /* The enter and bound instructions are printed with operands in the same
1.2291 + order as the intel book; everything else is printed in reverse order. */
1.2292 + if (intel_syntax || two_source_ops)
1.2298 + op_index[0] = op_index[2];
1.2310 + if (op_index[0] != -1 && !op_riprel[0])
1.2311 + (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
1.2313 + (*info->fprintf_func) (info->stream, "%s", first);
1.2319 + (*info->fprintf_func) (info->stream, ",");
1.2320 + if (op_index[1] != -1 && !op_riprel[1])
1.2321 + (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
1.2323 + (*info->fprintf_func) (info->stream, "%s", second);
1.2329 + (*info->fprintf_func) (info->stream, ",");
1.2330 + if (op_index[2] != -1 && !op_riprel[2])
1.2331 + (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
1.2333 + (*info->fprintf_func) (info->stream, "%s", third);
1.2335 + for (i = 0; i < 3; i++)
1.2336 + if (op_index[i] != -1 && op_riprel[i])
1.2338 + (*info->fprintf_func) (info->stream, " # ");
1.2339 + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
1.2340 + + op_address[op_index[i]]), info);
1.2342 + return codep - priv.the_buffer;
1.2345 +static const char *float_mem[] = {
1.2420 +static const unsigned char float_mem_mode[] = {
1.2498 +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
1.2499 +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
1.2500 +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
1.2501 +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
1.2502 +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
1.2503 +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
1.2504 +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
1.2505 +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
1.2506 +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
1.2508 +static const struct dis386 float_reg[][8] = {
1.2511 + { "fadd", ST, STi, XX },
1.2512 + { "fmul", ST, STi, XX },
1.2513 + { "fcom", STi, XX, XX },
1.2514 + { "fcomp", STi, XX, XX },
1.2515 + { "fsub", ST, STi, XX },
1.2516 + { "fsubr", ST, STi, XX },
1.2517 + { "fdiv", ST, STi, XX },
1.2518 + { "fdivr", ST, STi, XX },
1.2522 + { "fld", STi, XX, XX },
1.2523 + { "fxch", STi, XX, XX },
1.2525 + { "(bad)", XX, XX, XX },
1.2533 + { "fcmovb", ST, STi, XX },
1.2534 + { "fcmove", ST, STi, XX },
1.2535 + { "fcmovbe",ST, STi, XX },
1.2536 + { "fcmovu", ST, STi, XX },
1.2537 + { "(bad)", XX, XX, XX },
1.2539 + { "(bad)", XX, XX, XX },
1.2540 + { "(bad)", XX, XX, XX },
1.2544 + { "fcmovnb",ST, STi, XX },
1.2545 + { "fcmovne",ST, STi, XX },
1.2546 + { "fcmovnbe",ST, STi, XX },
1.2547 + { "fcmovnu",ST, STi, XX },
1.2549 + { "fucomi", ST, STi, XX },
1.2550 + { "fcomi", ST, STi, XX },
1.2551 + { "(bad)", XX, XX, XX },
1.2555 + { "fadd", STi, ST, XX },
1.2556 + { "fmul", STi, ST, XX },
1.2557 + { "(bad)", XX, XX, XX },
1.2558 + { "(bad)", XX, XX, XX },
1.2560 + { "fsub", STi, ST, XX },
1.2561 + { "fsubr", STi, ST, XX },
1.2562 + { "fdiv", STi, ST, XX },
1.2563 + { "fdivr", STi, ST, XX },
1.2565 + { "fsubr", STi, ST, XX },
1.2566 + { "fsub", STi, ST, XX },
1.2567 + { "fdivr", STi, ST, XX },
1.2568 + { "fdiv", STi, ST, XX },
1.2573 + { "ffree", STi, XX, XX },
1.2574 + { "(bad)", XX, XX, XX },
1.2575 + { "fst", STi, XX, XX },
1.2576 + { "fstp", STi, XX, XX },
1.2577 + { "fucom", STi, XX, XX },
1.2578 + { "fucomp", STi, XX, XX },
1.2579 + { "(bad)", XX, XX, XX },
1.2580 + { "(bad)", XX, XX, XX },
1.2584 + { "faddp", STi, ST, XX },
1.2585 + { "fmulp", STi, ST, XX },
1.2586 + { "(bad)", XX, XX, XX },
1.2589 + { "fsubp", STi, ST, XX },
1.2590 + { "fsubrp", STi, ST, XX },
1.2591 + { "fdivp", STi, ST, XX },
1.2592 + { "fdivrp", STi, ST, XX },
1.2594 + { "fsubrp", STi, ST, XX },
1.2595 + { "fsubp", STi, ST, XX },
1.2596 + { "fdivrp", STi, ST, XX },
1.2597 + { "fdivp", STi, ST, XX },
1.2602 + { "ffreep", STi, XX, XX },
1.2603 + { "(bad)", XX, XX, XX },
1.2604 + { "(bad)", XX, XX, XX },
1.2605 + { "(bad)", XX, XX, XX },
1.2607 + { "fucomip",ST, STi, XX },
1.2608 + { "fcomip", ST, STi, XX },
1.2609 + { "(bad)", XX, XX, XX },
1.2613 +static char *fgrps[][8] = {
1.2616 + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1.2621 + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1.2626 + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1.2631 + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1.2636 + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1.2641 + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1.2646 + "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1.2647 + "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1.2652 + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1.2657 + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1.2662 +dofloat (int sizeflag)
1.2664 + const struct dis386 *dp;
1.2665 + unsigned char floatop;
1.2671 + int fp_indx = (floatop - 0xd8) * 8 + reg;
1.2673 + putop (float_mem[fp_indx], sizeflag);
1.2675 + OP_E (float_mem_mode[fp_indx], sizeflag);
1.2678 + /* Skip mod/rm byte. */
1.2682 + dp = &float_reg[floatop - 0xd8][reg];
1.2683 + if (dp->name == NULL)
1.2685 + putop (fgrps[dp->bytemode1][rm], sizeflag);
1.2687 + /* Instruction fnstsw is only one with strange arg. */
1.2688 + if (floatop == 0xdf && codep[-1] == 0xe0)
1.2689 + strcpy (op1out, names16[0]);
1.2693 + putop (dp->name, sizeflag);
1.2697 + (*dp->op1) (dp->bytemode1, sizeflag);
1.2700 + (*dp->op2) (dp->bytemode2, sizeflag);
1.2705 +OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.2711 +OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.2713 + sprintf (scratchbuf, "%%st(%d)", rm);
1.2714 + oappend (scratchbuf + intel_syntax);
1.2717 +/* Capital letters in template are macros. */
1.2719 +putop (const char *template, int sizeflag)
1.2724 + for (p = template; *p; p++)
1.2743 + /* Alternative not valid. */
1.2744 + strcpy (obuf, "(bad)");
1.2769 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
1.2775 + if (sizeflag & SUFFIX_ALWAYS)
1.2779 + if (intel_syntax && !alt)
1.2781 + if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
1.2783 + if (sizeflag & DFLAG)
1.2784 + *obufp++ = intel_syntax ? 'd' : 'l';
1.2786 + *obufp++ = intel_syntax ? 'w' : 's';
1.2787 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2790 + case 'E': /* For jcxz/jecxz */
1.2793 + if (sizeflag & AFLAG)
1.2799 + if (sizeflag & AFLAG)
1.2801 + used_prefixes |= (prefixes & PREFIX_ADDR);
1.2806 + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
1.2808 + if (sizeflag & AFLAG)
1.2809 + *obufp++ = mode_64bit ? 'q' : 'l';
1.2811 + *obufp++ = mode_64bit ? 'l' : 'w';
1.2812 + used_prefixes |= (prefixes & PREFIX_ADDR);
1.2818 + if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
1.2819 + || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
1.2821 + used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
1.2824 + if (prefixes & PREFIX_DS)
1.2838 + if (sizeflag & SUFFIX_ALWAYS)
1.2842 + if ((prefixes & PREFIX_FWAIT) == 0)
1.2845 + used_prefixes |= PREFIX_FWAIT;
1.2848 + USED_REX (REX_MODE64);
1.2849 + if (rex & REX_MODE64)
1.2866 + if ((prefixes & PREFIX_DATA)
1.2867 + || (rex & REX_MODE64)
1.2868 + || (sizeflag & SUFFIX_ALWAYS))
1.2870 + USED_REX (REX_MODE64);
1.2871 + if (rex & REX_MODE64)
1.2875 + if (sizeflag & DFLAG)
1.2879 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2893 + if (intel_syntax && !alt)
1.2895 + USED_REX (REX_MODE64);
1.2896 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
1.2898 + if (rex & REX_MODE64)
1.2902 + if (sizeflag & DFLAG)
1.2903 + *obufp++ = intel_syntax ? 'd' : 'l';
1.2906 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2911 + USED_REX (REX_MODE64);
1.2914 + if (rex & REX_MODE64)
1.2919 + else if (sizeflag & DFLAG)
1.2932 + if (rex & REX_MODE64)
1.2934 + else if (sizeflag & DFLAG)
1.2939 + if (!(rex & REX_MODE64))
1.2940 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2945 + if (sizeflag & SUFFIX_ALWAYS)
1.2947 + if (rex & REX_MODE64)
1.2951 + if (sizeflag & DFLAG)
1.2955 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2960 + if (prefixes & PREFIX_DATA)
1.2964 + used_prefixes |= (prefixes & PREFIX_DATA);
1.2969 + if (rex & REX_MODE64)
1.2971 + USED_REX (REX_MODE64);
1.2975 + /* implicit operand size 'l' for i386 or 'q' for x86-64 */
1.2977 + /* operand size flag for cwtl, cbtw */
1.2981 + else if (sizeflag & DFLAG)
1.2992 + if (sizeflag & DFLAG)
1.3003 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3013 +oappend (const char *s)
1.3022 + if (prefixes & PREFIX_CS)
1.3024 + used_prefixes |= PREFIX_CS;
1.3025 + oappend ("%cs:" + intel_syntax);
1.3027 + if (prefixes & PREFIX_DS)
1.3029 + used_prefixes |= PREFIX_DS;
1.3030 + oappend ("%ds:" + intel_syntax);
1.3032 + if (prefixes & PREFIX_SS)
1.3034 + used_prefixes |= PREFIX_SS;
1.3035 + oappend ("%ss:" + intel_syntax);
1.3037 + if (prefixes & PREFIX_ES)
1.3039 + used_prefixes |= PREFIX_ES;
1.3040 + oappend ("%es:" + intel_syntax);
1.3042 + if (prefixes & PREFIX_FS)
1.3044 + used_prefixes |= PREFIX_FS;
1.3045 + oappend ("%fs:" + intel_syntax);
1.3047 + if (prefixes & PREFIX_GS)
1.3049 + used_prefixes |= PREFIX_GS;
1.3050 + oappend ("%gs:" + intel_syntax);
1.3055 +OP_indirE (int bytemode, int sizeflag)
1.3059 + OP_E (bytemode, sizeflag);
1.3063 +print_operand_value (char *buf, int hex, bfd_vma disp)
1.3073 + sprintf_vma (tmp, disp);
1.3074 + for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
1.3075 + strcpy (buf + 2, tmp + i);
1.3079 + bfd_signed_vma v = disp;
1.3086 + /* Check for possible overflow on 0x8000000000000000. */
1.3089 + strcpy (buf, "9223372036854775808");
1.3103 + tmp[28 - i] = (v % 10) + '0';
1.3107 + strcpy (buf, tmp + 29 - i);
1.3113 + sprintf (buf, "0x%x", (unsigned int) disp);
1.3115 + sprintf (buf, "%d", (int) disp);
1.3120 +OP_E (int bytemode, int sizeflag)
1.3129 + /* Skip mod/rm byte. */
1.3140 + oappend (names8rex[rm + add]);
1.3142 + oappend (names8[rm + add]);
1.3145 + oappend (names16[rm + add]);
1.3148 + oappend (names32[rm + add]);
1.3151 + oappend (names64[rm + add]);
1.3155 + oappend (names64[rm + add]);
1.3157 + oappend (names32[rm + add]);
1.3162 + USED_REX (REX_MODE64);
1.3163 + if (rex & REX_MODE64)
1.3164 + oappend (names64[rm + add]);
1.3165 + else if ((sizeflag & DFLAG) || bytemode != v_mode)
1.3166 + oappend (names32[rm + add]);
1.3168 + oappend (names16[rm + add]);
1.3169 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3174 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3183 + if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
1.3198 + FETCH_DATA (the_info, codep + 1);
1.3199 + index = (*codep >> 3) & 7;
1.3200 + if (mode_64bit || index != 0x4)
1.3201 + /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
1.3202 + scale = (*codep >> 6) & 3;
1.3219 + if (mode_64bit && !havesib)
1.3225 + FETCH_DATA (the_info, codep + 1);
1.3227 + if ((disp & 0x80) != 0)
1.3236 + if (mod != 0 || (base & 7) == 5)
1.3238 + print_operand_value (scratchbuf, !riprel, disp);
1.3239 + oappend (scratchbuf);
1.3247 + if (havebase || (havesib && (index != 4 || scale != 0)))
1.3254 + oappend ("BYTE PTR ");
1.3258 + oappend ("WORD PTR ");
1.3262 + USED_REX (REX_MODE64);
1.3263 + if (rex & REX_MODE64)
1.3264 + oappend ("QWORD PTR ");
1.3265 + else if ((sizeflag & DFLAG) || bytemode == dq_mode)
1.3266 + oappend ("DWORD PTR ");
1.3268 + oappend ("WORD PTR ");
1.3269 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3272 + oappend ("DWORD PTR ");
1.3275 + oappend ("QWORD PTR ");
1.3279 + oappend ("QWORD PTR ");
1.3281 + oappend ("DWORD PTR ");
1.3284 + if (sizeflag & DFLAG)
1.3286 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3287 + oappend ("FWORD PTR ");
1.3290 + oappend ("DWORD PTR ");
1.3293 + oappend ("TBYTE PTR ");
1.3296 + oappend ("XMMWORD PTR ");
1.3302 + *obufp++ = open_char;
1.3303 + if (intel_syntax && riprel)
1.3307 + if (!havesib && (rex & REX_EXTZ))
1.3310 + oappend (mode_64bit && (sizeflag & AFLAG)
1.3311 + ? names64[base] : names32[base]);
1.3316 + if (!intel_syntax || havebase)
1.3318 + *obufp++ = separator_char;
1.3321 + oappend (mode_64bit && (sizeflag & AFLAG)
1.3322 + ? names64[index] : names32[index]);
1.3324 + if (scale != 0 || (!intel_syntax && index != 4))
1.3326 + *obufp++ = scale_char;
1.3328 + sprintf (scratchbuf, "%d", 1 << scale);
1.3329 + oappend (scratchbuf);
1.3333 + if (mod != 0 || (base & 7) == 5)
1.3335 + /* Don't print zero displacements. */
1.3338 + if ((bfd_signed_vma) disp > 0)
1.3344 + print_operand_value (scratchbuf, 0, disp);
1.3345 + oappend (scratchbuf);
1.3349 + *obufp++ = close_char;
1.3352 + else if (intel_syntax)
1.3354 + if (mod != 0 || (base & 7) == 5)
1.3356 + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
1.3357 + | PREFIX_ES | PREFIX_FS | PREFIX_GS))
1.3361 + oappend (names_seg[ds_reg - es_reg]);
1.3364 + print_operand_value (scratchbuf, 1, disp);
1.3365 + oappend (scratchbuf);
1.3370 + { /* 16 bit address mode */
1.3377 + if ((disp & 0x8000) != 0)
1.3382 + FETCH_DATA (the_info, codep + 1);
1.3384 + if ((disp & 0x80) != 0)
1.3389 + if ((disp & 0x8000) != 0)
1.3395 + if (mod != 0 || (rm & 7) == 6)
1.3397 + print_operand_value (scratchbuf, 0, disp);
1.3398 + oappend (scratchbuf);
1.3401 + if (mod != 0 || (rm & 7) != 6)
1.3403 + *obufp++ = open_char;
1.3405 + oappend (index16[rm + add]);
1.3406 + *obufp++ = close_char;
1.3413 +OP_G (int bytemode, int sizeflag)
1.3424 + oappend (names8rex[reg + add]);
1.3426 + oappend (names8[reg + add]);
1.3429 + oappend (names16[reg + add]);
1.3432 + oappend (names32[reg + add]);
1.3435 + oappend (names64[reg + add]);
1.3440 + USED_REX (REX_MODE64);
1.3441 + if (rex & REX_MODE64)
1.3442 + oappend (names64[reg + add]);
1.3443 + else if ((sizeflag & DFLAG) || bytemode != v_mode)
1.3444 + oappend (names32[reg + add]);
1.3446 + oappend (names16[reg + add]);
1.3447 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3450 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3463 + FETCH_DATA (the_info, codep + 8);
1.3465 + a |= (*codep++ & 0xff) << 8;
1.3466 + a |= (*codep++ & 0xff) << 16;
1.3467 + a |= (*codep++ & 0xff) << 24;
1.3469 + b |= (*codep++ & 0xff) << 8;
1.3470 + b |= (*codep++ & 0xff) << 16;
1.3471 + b |= (*codep++ & 0xff) << 24;
1.3472 + x = a + ((bfd_vma) b << 32);
1.3483 + bfd_signed_vma x = 0;
1.3485 + FETCH_DATA (the_info, codep + 4);
1.3486 + x = *codep++ & (bfd_signed_vma) 0xff;
1.3487 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
1.3488 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
1.3489 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
1.3496 + bfd_signed_vma x = 0;
1.3498 + FETCH_DATA (the_info, codep + 4);
1.3499 + x = *codep++ & (bfd_signed_vma) 0xff;
1.3500 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
1.3501 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
1.3502 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
1.3504 + x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
1.3514 + FETCH_DATA (the_info, codep + 2);
1.3516 + x |= (*codep++ & 0xff) << 8;
1.3521 +set_op (bfd_vma op, int riprel)
1.3523 + op_index[op_ad] = op_ad;
1.3526 + op_address[op_ad] = op;
1.3527 + op_riprel[op_ad] = riprel;
1.3531 + /* Mask to get a 32-bit address. */
1.3532 + op_address[op_ad] = op & 0xffffffff;
1.3533 + op_riprel[op_ad] = riprel & 0xffffffff;
1.3538 +OP_REG (int code, int sizeflag)
1.3554 + case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1.3555 + case sp_reg: case bp_reg: case si_reg: case di_reg:
1.3556 + s = names16[code - ax_reg + add];
1.3558 + case es_reg: case ss_reg: case cs_reg:
1.3559 + case ds_reg: case fs_reg: case gs_reg:
1.3560 + s = names_seg[code - es_reg + add];
1.3562 + case al_reg: case ah_reg: case cl_reg: case ch_reg:
1.3563 + case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1.3566 + s = names8rex[code - al_reg + add];
1.3568 + s = names8[code - al_reg];
1.3570 + case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
1.3571 + case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
1.3574 + s = names64[code - rAX_reg + add];
1.3577 + code += eAX_reg - rAX_reg;
1.3579 + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1.3580 + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1.3581 + USED_REX (REX_MODE64);
1.3582 + if (rex & REX_MODE64)
1.3583 + s = names64[code - eAX_reg + add];
1.3584 + else if (sizeflag & DFLAG)
1.3585 + s = names32[code - eAX_reg + add];
1.3587 + s = names16[code - eAX_reg + add];
1.3588 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3591 + s = INTERNAL_DISASSEMBLER_ERROR;
1.3598 +OP_IMREG (int code, int sizeflag)
1.3610 + case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1.3611 + case sp_reg: case bp_reg: case si_reg: case di_reg:
1.3612 + s = names16[code - ax_reg];
1.3614 + case es_reg: case ss_reg: case cs_reg:
1.3615 + case ds_reg: case fs_reg: case gs_reg:
1.3616 + s = names_seg[code - es_reg];
1.3618 + case al_reg: case ah_reg: case cl_reg: case ch_reg:
1.3619 + case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1.3622 + s = names8rex[code - al_reg];
1.3624 + s = names8[code - al_reg];
1.3626 + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1.3627 + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1.3628 + USED_REX (REX_MODE64);
1.3629 + if (rex & REX_MODE64)
1.3630 + s = names64[code - eAX_reg];
1.3631 + else if (sizeflag & DFLAG)
1.3632 + s = names32[code - eAX_reg];
1.3634 + s = names16[code - eAX_reg];
1.3635 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3638 + s = INTERNAL_DISASSEMBLER_ERROR;
1.3645 +OP_I (int bytemode, int sizeflag)
1.3648 + bfd_signed_vma mask = -1;
1.3653 + FETCH_DATA (the_info, codep + 1);
1.3665 + USED_REX (REX_MODE64);
1.3666 + if (rex & REX_MODE64)
1.3668 + else if (sizeflag & DFLAG)
1.3678 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3689 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3695 + print_operand_value (scratchbuf + 1, 1, op);
1.3696 + oappend (scratchbuf + intel_syntax);
1.3697 + scratchbuf[0] = '\0';
1.3701 +OP_I64 (int bytemode, int sizeflag)
1.3704 + bfd_signed_vma mask = -1;
1.3708 + OP_I (bytemode, sizeflag);
1.3715 + FETCH_DATA (the_info, codep + 1);
1.3720 + USED_REX (REX_MODE64);
1.3721 + if (rex & REX_MODE64)
1.3723 + else if (sizeflag & DFLAG)
1.3733 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3740 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3746 + print_operand_value (scratchbuf + 1, 1, op);
1.3747 + oappend (scratchbuf + intel_syntax);
1.3748 + scratchbuf[0] = '\0';
1.3752 +OP_sI (int bytemode, int sizeflag)
1.3755 + bfd_signed_vma mask = -1;
1.3760 + FETCH_DATA (the_info, codep + 1);
1.3762 + if ((op & 0x80) != 0)
1.3767 + USED_REX (REX_MODE64);
1.3768 + if (rex & REX_MODE64)
1.3770 + else if (sizeflag & DFLAG)
1.3779 + if ((op & 0x8000) != 0)
1.3782 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3787 + if ((op & 0x8000) != 0)
1.3791 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3796 + print_operand_value (scratchbuf + 1, 1, op);
1.3797 + oappend (scratchbuf + intel_syntax);
1.3801 +OP_J (int bytemode, int sizeflag)
1.3809 + FETCH_DATA (the_info, codep + 1);
1.3811 + if ((disp & 0x80) != 0)
1.3815 + if (sizeflag & DFLAG)
1.3820 + /* For some reason, a data16 prefix on a jump instruction
1.3821 + means that the pc is masked to 16 bits after the
1.3822 + displacement is added! */
1.3827 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1.3830 + disp = (start_pc + codep - start_codep + disp) & mask;
1.3832 + print_operand_value (scratchbuf, 1, disp);
1.3833 + oappend (scratchbuf);
1.3837 +OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.3839 + oappend (names_seg[reg]);
1.3843 +OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
1.3847 + if (sizeflag & DFLAG)
1.3857 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3859 + sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1.3861 + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
1.3862 + oappend (scratchbuf);
1.3866 +OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
1.3872 + if ((sizeflag & AFLAG) || mode_64bit)
1.3879 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
1.3880 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
1.3882 + oappend (names_seg[ds_reg - es_reg]);
1.3886 + print_operand_value (scratchbuf, 1, off);
1.3887 + oappend (scratchbuf);
1.3891 +OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.3897 + OP_OFF (bytemode, sizeflag);
1.3907 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
1.3908 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
1.3910 + oappend (names_seg[ds_reg - es_reg]);
1.3914 + print_operand_value (scratchbuf, 1, off);
1.3915 + oappend (scratchbuf);
1.3919 +ptr_reg (int code, int sizeflag)
1.3923 + *obufp++ = open_char;
1.3924 + used_prefixes |= (prefixes & PREFIX_ADDR);
1.3927 + if (!(sizeflag & AFLAG))
1.3928 + s = names32[code - eAX_reg];
1.3930 + s = names64[code - eAX_reg];
1.3932 + else if (sizeflag & AFLAG)
1.3933 + s = names32[code - eAX_reg];
1.3935 + s = names16[code - eAX_reg];
1.3937 + *obufp++ = close_char;
1.3942 +OP_ESreg (int code, int sizeflag)
1.3948 + USED_REX (REX_MODE64);
1.3949 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3950 + if (rex & REX_MODE64)
1.3951 + oappend ("QWORD PTR ");
1.3952 + else if ((sizeflag & DFLAG))
1.3953 + oappend ("DWORD PTR ");
1.3955 + oappend ("WORD PTR ");
1.3958 + oappend ("BYTE PTR ");
1.3961 + oappend ("%es:" + intel_syntax);
1.3962 + ptr_reg (code, sizeflag);
1.3966 +OP_DSreg (int code, int sizeflag)
1.3970 + if (codep[-1] != 0xd7 && (codep[-1] & 1))
1.3972 + USED_REX (REX_MODE64);
1.3973 + used_prefixes |= (prefixes & PREFIX_DATA);
1.3974 + if (rex & REX_MODE64)
1.3975 + oappend ("QWORD PTR ");
1.3976 + else if ((sizeflag & DFLAG))
1.3977 + oappend ("DWORD PTR ");
1.3979 + oappend ("WORD PTR ");
1.3982 + oappend ("BYTE PTR ");
1.3992 + prefixes |= PREFIX_DS;
1.3994 + ptr_reg (code, sizeflag);
1.3998 +OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4006 + else if (!mode_64bit && (prefixes & PREFIX_LOCK))
1.4008 + used_prefixes |= PREFIX_LOCK;
1.4011 + sprintf (scratchbuf, "%%cr%d", reg + add);
1.4012 + oappend (scratchbuf + intel_syntax);
1.4016 +OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4023 + sprintf (scratchbuf, "db%d", reg + add);
1.4025 + sprintf (scratchbuf, "%%db%d", reg + add);
1.4026 + oappend (scratchbuf);
1.4030 +OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4032 + sprintf (scratchbuf, "%%tr%d", reg);
1.4033 + oappend (scratchbuf + intel_syntax);
1.4037 +OP_Rd (int bytemode, int sizeflag)
1.4040 + OP_E (bytemode, sizeflag);
1.4046 +OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4048 + used_prefixes |= (prefixes & PREFIX_DATA);
1.4049 + if (prefixes & PREFIX_DATA)
1.4055 + sprintf (scratchbuf, "%%xmm%d", reg + add);
1.4058 + sprintf (scratchbuf, "%%mm%d", reg);
1.4059 + oappend (scratchbuf + intel_syntax);
1.4063 +OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4069 + sprintf (scratchbuf, "%%xmm%d", reg + add);
1.4070 + oappend (scratchbuf + intel_syntax);
1.4074 +OP_EM (int bytemode, int sizeflag)
1.4078 + if (intel_syntax && bytemode == v_mode)
1.4080 + bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
1.4081 + used_prefixes |= (prefixes & PREFIX_DATA);
1.4083 + OP_E (bytemode, sizeflag);
1.4087 + /* Skip mod/rm byte. */
1.4090 + used_prefixes |= (prefixes & PREFIX_DATA);
1.4091 + if (prefixes & PREFIX_DATA)
1.4098 + sprintf (scratchbuf, "%%xmm%d", rm + add);
1.4101 + sprintf (scratchbuf, "%%mm%d", rm);
1.4102 + oappend (scratchbuf + intel_syntax);
1.4106 +OP_EX (int bytemode, int sizeflag)
1.4111 + if (intel_syntax && bytemode == v_mode)
1.4113 + switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
1.4115 + case 0: bytemode = x_mode; break;
1.4116 + case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
1.4117 + case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
1.4118 + case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
1.4119 + default: bytemode = 0; break;
1.4122 + OP_E (bytemode, sizeflag);
1.4129 + /* Skip mod/rm byte. */
1.4132 + sprintf (scratchbuf, "%%xmm%d", rm + add);
1.4133 + oappend (scratchbuf + intel_syntax);
1.4137 +OP_MS (int bytemode, int sizeflag)
1.4140 + OP_EM (bytemode, sizeflag);
1.4146 +OP_XS (int bytemode, int sizeflag)
1.4149 + OP_EX (bytemode, sizeflag);
1.4155 +OP_M (int bytemode, int sizeflag)
1.4158 + BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
1.4160 + OP_E (bytemode, sizeflag);
1.4164 +OP_0f07 (int bytemode, int sizeflag)
1.4166 + if (mod != 3 || rm != 0)
1.4169 + OP_E (bytemode, sizeflag);
1.4173 +OP_0fae (int bytemode, int sizeflag)
1.4178 + strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
1.4180 + if (reg < 5 || rm != 0)
1.4182 + BadOp (); /* bad sfence, mfence, or lfence */
1.4188 + BadOp (); /* bad clflush */
1.4192 + OP_E (bytemode, sizeflag);
1.4196 +NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4198 + /* NOP with REPZ prefix is called PAUSE. */
1.4199 + if (prefixes == PREFIX_REPZ)
1.4200 + strcpy (obuf, "pause");
1.4203 +static const char *const Suffix3DNow[] = {
1.4204 +/* 00 */ NULL, NULL, NULL, NULL,
1.4205 +/* 04 */ NULL, NULL, NULL, NULL,
1.4206 +/* 08 */ NULL, NULL, NULL, NULL,
1.4207 +/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
1.4208 +/* 10 */ NULL, NULL, NULL, NULL,
1.4209 +/* 14 */ NULL, NULL, NULL, NULL,
1.4210 +/* 18 */ NULL, NULL, NULL, NULL,
1.4211 +/* 1C */ "pf2iw", "pf2id", NULL, NULL,
1.4212 +/* 20 */ NULL, NULL, NULL, NULL,
1.4213 +/* 24 */ NULL, NULL, NULL, NULL,
1.4214 +/* 28 */ NULL, NULL, NULL, NULL,
1.4215 +/* 2C */ NULL, NULL, NULL, NULL,
1.4216 +/* 30 */ NULL, NULL, NULL, NULL,
1.4217 +/* 34 */ NULL, NULL, NULL, NULL,
1.4218 +/* 38 */ NULL, NULL, NULL, NULL,
1.4219 +/* 3C */ NULL, NULL, NULL, NULL,
1.4220 +/* 40 */ NULL, NULL, NULL, NULL,
1.4221 +/* 44 */ NULL, NULL, NULL, NULL,
1.4222 +/* 48 */ NULL, NULL, NULL, NULL,
1.4223 +/* 4C */ NULL, NULL, NULL, NULL,
1.4224 +/* 50 */ NULL, NULL, NULL, NULL,
1.4225 +/* 54 */ NULL, NULL, NULL, NULL,
1.4226 +/* 58 */ NULL, NULL, NULL, NULL,
1.4227 +/* 5C */ NULL, NULL, NULL, NULL,
1.4228 +/* 60 */ NULL, NULL, NULL, NULL,
1.4229 +/* 64 */ NULL, NULL, NULL, NULL,
1.4230 +/* 68 */ NULL, NULL, NULL, NULL,
1.4231 +/* 6C */ NULL, NULL, NULL, NULL,
1.4232 +/* 70 */ NULL, NULL, NULL, NULL,
1.4233 +/* 74 */ NULL, NULL, NULL, NULL,
1.4234 +/* 78 */ NULL, NULL, NULL, NULL,
1.4235 +/* 7C */ NULL, NULL, NULL, NULL,
1.4236 +/* 80 */ NULL, NULL, NULL, NULL,
1.4237 +/* 84 */ NULL, NULL, NULL, NULL,
1.4238 +/* 88 */ NULL, NULL, "pfnacc", NULL,
1.4239 +/* 8C */ NULL, NULL, "pfpnacc", NULL,
1.4240 +/* 90 */ "pfcmpge", NULL, NULL, NULL,
1.4241 +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
1.4242 +/* 98 */ NULL, NULL, "pfsub", NULL,
1.4243 +/* 9C */ NULL, NULL, "pfadd", NULL,
1.4244 +/* A0 */ "pfcmpgt", NULL, NULL, NULL,
1.4245 +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
1.4246 +/* A8 */ NULL, NULL, "pfsubr", NULL,
1.4247 +/* AC */ NULL, NULL, "pfacc", NULL,
1.4248 +/* B0 */ "pfcmpeq", NULL, NULL, NULL,
1.4249 +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
1.4250 +/* B8 */ NULL, NULL, NULL, "pswapd",
1.4251 +/* BC */ NULL, NULL, NULL, "pavgusb",
1.4252 +/* C0 */ NULL, NULL, NULL, NULL,
1.4253 +/* C4 */ NULL, NULL, NULL, NULL,
1.4254 +/* C8 */ NULL, NULL, NULL, NULL,
1.4255 +/* CC */ NULL, NULL, NULL, NULL,
1.4256 +/* D0 */ NULL, NULL, NULL, NULL,
1.4257 +/* D4 */ NULL, NULL, NULL, NULL,
1.4258 +/* D8 */ NULL, NULL, NULL, NULL,
1.4259 +/* DC */ NULL, NULL, NULL, NULL,
1.4260 +/* E0 */ NULL, NULL, NULL, NULL,
1.4261 +/* E4 */ NULL, NULL, NULL, NULL,
1.4262 +/* E8 */ NULL, NULL, NULL, NULL,
1.4263 +/* EC */ NULL, NULL, NULL, NULL,
1.4264 +/* F0 */ NULL, NULL, NULL, NULL,
1.4265 +/* F4 */ NULL, NULL, NULL, NULL,
1.4266 +/* F8 */ NULL, NULL, NULL, NULL,
1.4267 +/* FC */ NULL, NULL, NULL, NULL,
1.4271 +OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4273 + const char *mnemonic;
1.4275 + FETCH_DATA (the_info, codep + 1);
1.4276 + /* AMD 3DNow! instructions are specified by an opcode suffix in the
1.4277 + place where an 8-bit immediate would normally go. ie. the last
1.4278 + byte of the instruction. */
1.4279 + obufp = obuf + strlen (obuf);
1.4280 + mnemonic = Suffix3DNow[*codep++ & 0xff];
1.4285 + /* Since a variable sized modrm/sib chunk is between the start
1.4286 + of the opcode (0x0f0f) and the opcode suffix, we need to do
1.4287 + all the modrm processing first, and don't know until now that
1.4288 + we have a bad opcode. This necessitates some cleaning up. */
1.4295 +static const char *simd_cmp_op[] = {
1.4307 +OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
1.4309 + unsigned int cmp_type;
1.4311 + FETCH_DATA (the_info, codep + 1);
1.4312 + obufp = obuf + strlen (obuf);
1.4313 + cmp_type = *codep++ & 0xff;
1.4316 + char suffix1 = 'p', suffix2 = 's';
1.4317 + used_prefixes |= (prefixes & PREFIX_REPZ);
1.4318 + if (prefixes & PREFIX_REPZ)
1.4322 + used_prefixes |= (prefixes & PREFIX_DATA);
1.4323 + if (prefixes & PREFIX_DATA)
1.4327 + used_prefixes |= (prefixes & PREFIX_REPNZ);
1.4328 + if (prefixes & PREFIX_REPNZ)
1.4329 + suffix1 = 's', suffix2 = 'd';
1.4332 + sprintf (scratchbuf, "cmp%s%c%c",
1.4333 + simd_cmp_op[cmp_type], suffix1, suffix2);
1.4334 + used_prefixes |= (prefixes & PREFIX_REPZ);
1.4335 + oappend (scratchbuf);
1.4339 + /* We have a bad extension byte. Clean up. */
1.4347 +SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
1.4349 + /* Change movlps/movhps to movhlps/movlhps for 2 register operand
1.4350 + forms of these instructions. */
1.4353 + char *p = obuf + strlen (obuf);
1.4358 + *(p - 3) = extrachar;
1.4363 +PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
1.4365 + if (mod == 3 && reg == 1 && rm <= 1)
1.4367 + /* Override "sidt". */
1.4368 + char *p = obuf + strlen (obuf) - 4;
1.4370 + /* We might have a suffix. */
1.4376 + /* mwait %eax,%ecx */
1.4379 + strcpy (op1out, names32[0]);
1.4383 + /* monitor %eax,%ecx,%edx" */
1.4384 + strcpy (p, "monitor");
1.4388 + strcpy (op1out, names32[0]);
1.4389 + else if (!(prefixes & PREFIX_ADDR))
1.4390 + strcpy (op1out, names64[0]);
1.4393 + strcpy (op1out, names32[0]);
1.4394 + used_prefixes |= PREFIX_ADDR;
1.4396 + strcpy (op3out, names32[2]);
1.4401 + strcpy (op2out, names32[1]);
1.4412 +INVLPG_Fixup (int bytemode, int sizeflag)
1.4425 + OP_E (bytemode, sizeflag);
1.4428 + /* Override "invlpg". */
1.4429 + strcpy (obuf + strlen (obuf) - 6, alt);
1.4436 + /* Throw away prefixes and 1st. opcode byte. */
1.4437 + codep = insn_codep + 1;