filename | src/x86dasm/i386-dis.c |
changeset | 362:dc40e2064dc4 |
next | 755:ab873907b00e |
author | nkeynes |
date | Fri Feb 08 00:06:56 2008 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Fix LDS/STS to FPUL/FPSCR to check the FPU disabled bit. Fixes the linux 2.4.0-test8 kernel boot (this wasn't exactly very well documented in the original manual) |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/x86dasm/i386-dis.c Fri Feb 08 00:06:56 2008 +00001.3 @@ -0,0 +1,4436 @@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.7 +1.8 + This file is part of GDB.1.9 +1.10 + This program is free software; you can redistribute it and/or modify1.11 + it under the terms of the GNU General Public License as published by1.12 + the Free Software Foundation; either version 2 of the License, or1.13 + (at your option) any later version.1.14 +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 of1.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.18 + GNU General Public License for more details.1.19 +1.20 + You should have received a copy of the GNU General Public License1.21 + along with this program; if not, write to the Free Software1.22 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */1.23 +1.24 +/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)1.25 + July 19881.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.29 +1.30 +/* The main tables describing the instructions is essentially a copy1.31 + of the "Opcode Map" chapter (Appendix A) of the Intel 803861.32 + Programmers Manual. Usually, there is a capital letter, followed1.33 + by a small letter. The capital letter tell the addressing mode,1.34 + and the small letter tells about the operand size. Refer to1.35 + the Intel manual for details. */1.36 +1.37 +#include "dis-asm.h"1.38 +#include "sysdep.h"1.39 +#include "opintl.h"1.40 +1.41 +#define MAXLEN 201.42 +1.43 +#include <setjmp.h>1.44 +1.45 +#ifndef UNIXWARE_COMPAT1.46 +/* Set non-zero for broken, compatible instructions. Set to zero for1.47 + non-broken opcodes. */1.48 +#define UNIXWARE_COMPAT 11.49 +#endif1.50 +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.103 +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.110 + jmp_buf bailout;1.111 +};1.112 +1.113 +/* The opcode for the fwait instruction, which we treat as a prefix1.114 + when we can. */1.115 +#define FWAIT_OPCODE (0x9b)1.116 +1.117 +/* Set to 1 for 64bit mode disassembly. */1.118 +static int mode_64bit;1.119 +1.120 +/* Flags for the prefixes for the current instruction. See below. */1.121 +static int prefixes;1.122 +1.123 +/* REX prefix the current instruction. See below. */1.124 +static int rex;1.125 +/* Bits of REX we've already used. */1.126 +static int rex_used;1.127 +#define REX_MODE64 81.128 +#define REX_EXTX 41.129 +#define REX_EXTY 21.130 +#define REX_EXTZ 11.131 +/* Mark parts used in the REX prefix. When we are testing for1.132 + empty prefix (for 8bit register REX extension), just mask it1.133 + out. Otherwise test for REX bit is excuse for existence of REX1.134 + only in case value is nonzero. */1.135 +#define USED_REX(value) \1.136 + { \1.137 + if (value) \1.138 + rex_used |= (rex & value) ? (value) | 0x40 : 0; \1.139 + else \1.140 + rex_used |= 0x40; \1.141 + }1.142 +1.143 +/* Flags for prefixes which we somehow handled when printing the1.144 + current instruction. */1.145 +static int used_prefixes;1.146 +1.147 +/* Flags stored in PREFIXES. */1.148 +#define PREFIX_REPZ 11.149 +#define PREFIX_REPNZ 21.150 +#define PREFIX_LOCK 41.151 +#define PREFIX_CS 81.152 +#define PREFIX_SS 0x101.153 +#define PREFIX_DS 0x201.154 +#define PREFIX_ES 0x401.155 +#define PREFIX_FS 0x801.156 +#define PREFIX_GS 0x1001.157 +#define PREFIX_DATA 0x2001.158 +#define PREFIX_ADDR 0x4001.159 +#define PREFIX_FWAIT 0x8001.160 +1.161 +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)1.162 + to ADDR (exclusive) are valid. Returns 1 for success, longjmps1.163 + on error. */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.167 +1.168 +static int1.169 +fetch_data (struct disassemble_info *info, bfd_byte *addr)1.170 +{1.171 + int status;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.174 +1.175 + status = (*info->read_memory_func) (start,1.176 + priv->max_fetched,1.177 + addr - priv->max_fetched,1.178 + info);1.179 + if (status != 0)1.180 + {1.181 + /* If we did manage to read at least one byte, then1.182 + print_insn_i386 will do something sensible. Otherwise, print1.183 + an error. We do that here because this is where we know1.184 + STATUS. */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.188 + }1.189 + else1.190 + priv->max_fetched = addr;1.191 + return 1;1.192 +}1.193 +1.194 +#define XX NULL, 01.195 +1.196 +#define Eb OP_E, b_mode1.197 +#define Ev OP_E, v_mode1.198 +#define Ed OP_E, d_mode1.199 +#define Eq OP_E, q_mode1.200 +#define Edq OP_E, dq_mode1.201 +#define Edqw OP_E, dqw_mode1.202 +#define indirEv OP_indirE, v_mode1.203 +#define indirEp OP_indirE, f_mode1.204 +#define Ew OP_E, w_mode1.205 +#define Ma OP_E, v_mode1.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_mode1.209 +#define Gv OP_G, v_mode1.210 +#define Gd OP_G, d_mode1.211 +#define Gdq OP_G, dq_mode1.212 +#define Gw OP_G, w_mode1.213 +#define Rd OP_Rd, d_mode1.214 +#define Rm OP_Rd, m_mode1.215 +#define Ib OP_I, b_mode1.216 +#define sIb OP_sI, b_mode /* sign extened byte */1.217 +#define Iv OP_I, v_mode1.218 +#define Iq OP_I, q_mode1.219 +#define Iv64 OP_I64, v_mode1.220 +#define Iw OP_I, w_mode1.221 +#define I1 OP_I, const_1_mode1.222 +#define Jb OP_J, b_mode1.223 +#define Jv OP_J, v_mode1.224 +#define Cm OP_C, m_mode1.225 +#define Dm OP_D, m_mode1.226 +#define Td OP_T, d_mode1.227 +1.228 +#define RMeAX OP_REG, eAX_reg1.229 +#define RMeBX OP_REG, eBX_reg1.230 +#define RMeCX OP_REG, eCX_reg1.231 +#define RMeDX OP_REG, eDX_reg1.232 +#define RMeSP OP_REG, eSP_reg1.233 +#define RMeBP OP_REG, eBP_reg1.234 +#define RMeSI OP_REG, eSI_reg1.235 +#define RMeDI OP_REG, eDI_reg1.236 +#define RMrAX OP_REG, rAX_reg1.237 +#define RMrBX OP_REG, rBX_reg1.238 +#define RMrCX OP_REG, rCX_reg1.239 +#define RMrDX OP_REG, rDX_reg1.240 +#define RMrSP OP_REG, rSP_reg1.241 +#define RMrBP OP_REG, rBP_reg1.242 +#define RMrSI OP_REG, rSI_reg1.243 +#define RMrDI OP_REG, rDI_reg1.244 +#define RMAL OP_REG, al_reg1.245 +#define RMAL OP_REG, al_reg1.246 +#define RMCL OP_REG, cl_reg1.247 +#define RMDL OP_REG, dl_reg1.248 +#define RMBL OP_REG, bl_reg1.249 +#define RMAH OP_REG, ah_reg1.250 +#define RMCH OP_REG, ch_reg1.251 +#define RMDH OP_REG, dh_reg1.252 +#define RMBH OP_REG, bh_reg1.253 +#define RMAX OP_REG, ax_reg1.254 +#define RMDX OP_REG, dx_reg1.255 +1.256 +#define eAX OP_IMREG, eAX_reg1.257 +#define eBX OP_IMREG, eBX_reg1.258 +#define eCX OP_IMREG, eCX_reg1.259 +#define eDX OP_IMREG, eDX_reg1.260 +#define eSP OP_IMREG, eSP_reg1.261 +#define eBP OP_IMREG, eBP_reg1.262 +#define eSI OP_IMREG, eSI_reg1.263 +#define eDI OP_IMREG, eDI_reg1.264 +#define AL OP_IMREG, al_reg1.265 +#define AL OP_IMREG, al_reg1.266 +#define CL OP_IMREG, cl_reg1.267 +#define DL OP_IMREG, dl_reg1.268 +#define BL OP_IMREG, bl_reg1.269 +#define AH OP_IMREG, ah_reg1.270 +#define CH OP_IMREG, ch_reg1.271 +#define DH OP_IMREG, dh_reg1.272 +#define BH OP_IMREG, bh_reg1.273 +#define AX OP_IMREG, ax_reg1.274 +#define DX OP_IMREG, dx_reg1.275 +#define indirDX OP_IMREG, indir_dx_reg1.276 +1.277 +#define Sw OP_SEG, w_mode1.278 +#define Ap OP_DIR, 01.279 +#define Ob OP_OFF, b_mode1.280 +#define Ob64 OP_OFF64, b_mode1.281 +#define Ov OP_OFF, v_mode1.282 +#define Ov64 OP_OFF64, v_mode1.283 +#define Xb OP_DSreg, eSI_reg1.284 +#define Xv OP_DSreg, eSI_reg1.285 +#define Yb OP_ESreg, eDI_reg1.286 +#define Yv OP_ESreg, eDI_reg1.287 +#define DSBX OP_DSreg, eBX_reg1.288 +1.289 +#define es OP_REG, es_reg1.290 +#define ss OP_REG, ss_reg1.291 +#define cs OP_REG, cs_reg1.292 +#define ds OP_REG, ds_reg1.293 +#define fs OP_REG, fs_reg1.294 +#define gs OP_REG, gs_reg1.295 +1.296 +#define MX OP_MMX, 01.297 +#define XM OP_XMM, 01.298 +#define EM OP_EM, v_mode1.299 +#define EX OP_EX, v_mode1.300 +#define MS OP_MS, v_mode1.301 +#define XS OP_XS, v_mode1.302 +#define OPSUF OP_3DNowSuffix, 01.303 +#define OPSIMD OP_SIMD_Suffix, 01.304 +1.305 +#define cond_jump_flag NULL, cond_jump_mode1.306 +#define loop_jcxz_flag NULL, loop_jcxz_mode1.307 +1.308 +/* bits in sizeflag */1.309 +#define SUFFIX_ALWAYS 41.310 +#define AFLAG 21.311 +#define DFLAG 11.312 +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 91.322 +#define loop_jcxz_mode 101.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 141.327 +1.328 +#define es_reg 1001.329 +#define cs_reg 1011.330 +#define ss_reg 1021.331 +#define ds_reg 1031.332 +#define fs_reg 1041.333 +#define gs_reg 1051.334 +1.335 +#define eAX_reg 1081.336 +#define eCX_reg 1091.337 +#define eDX_reg 1101.338 +#define eBX_reg 1111.339 +#define eSP_reg 1121.340 +#define eBP_reg 1131.341 +#define eSI_reg 1141.342 +#define eDI_reg 1151.343 +1.344 +#define al_reg 1161.345 +#define cl_reg 1171.346 +#define dl_reg 1181.347 +#define bl_reg 1191.348 +#define ah_reg 1201.349 +#define ch_reg 1211.350 +#define dh_reg 1221.351 +#define bh_reg 1231.352 +1.353 +#define ax_reg 1241.354 +#define cx_reg 1251.355 +#define dx_reg 1261.356 +#define bx_reg 1271.357 +#define sp_reg 1281.358 +#define bp_reg 1291.359 +#define si_reg 1301.360 +#define di_reg 1311.361 +1.362 +#define rAX_reg 1321.363 +#define rCX_reg 1331.364 +#define rDX_reg 1341.365 +#define rBX_reg 1351.366 +#define rSP_reg 1361.367 +#define rBP_reg 1371.368 +#define rSI_reg 1381.369 +#define rDI_reg 1391.370 +1.371 +#define indir_dx_reg 1501.372 +1.373 +#define FLOATCODE 11.374 +#define USE_GROUPS 21.375 +#define USE_PREFIX_USER_TABLE 31.376 +#define X86_64_SPECIAL 41.377 +1.378 +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 01.379 +1.380 +#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 01.381 +#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 01.382 +#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 01.383 +#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 01.384 +#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 01.385 +#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 01.386 +#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 01.387 +#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 01.388 +#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 01.389 +#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 01.390 +#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 01.391 +#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 01.392 +#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 01.393 +#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 01.394 +#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 01.395 +#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 01.396 +#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 01.397 +#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 01.398 +#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 01.399 +#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 01.400 +#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 01.401 +#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 01.402 +#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 01.403 +#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 01.404 +#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 01.405 +1.406 +#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 01.407 +#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 01.408 +#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 01.409 +#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 01.410 +#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 01.411 +#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 01.412 +#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 01.413 +#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 01.414 +#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 01.415 +#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 01.416 +#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 01.417 +#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 01.418 +#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 01.419 +#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 01.420 +#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 01.421 +#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 01.422 +#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 01.423 +#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 01.424 +#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 01.425 +#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 01.426 +#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 01.427 +#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 01.428 +#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 01.429 +#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 01.430 +#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 01.431 +#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 01.432 +#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 01.433 +#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 01.434 +#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 01.435 +#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 01.436 +#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 01.437 +#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 01.438 +#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 01.439 +1.440 +#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 01.441 +1.442 +typedef void (*op_rtn) (int bytemode, int sizeflag);1.443 +1.444 +struct dis386 {1.445 + const char *name;1.446 + op_rtn op1;1.447 + int bytemode1;1.448 + op_rtn op2;1.449 + int bytemode2;1.450 + op_rtn op3;1.451 + int bytemode3;1.452 +};1.453 +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 true1.456 + 'B' => print 'b' if suffix_always is true1.457 + 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand1.458 + . size prefix1.459 + 'E' => print 'e' if 32-bit form of jcxz1.460 + 'F' => print 'w' or 'l' depending on address size prefix (loop insns)1.461 + 'H' => print ",pt" or ",pn" branch hint1.462 + 'I' => honor following macro letter even in Intel mode (implemented only1.463 + . for some of the macro letters)1.464 + 'J' => print 'l'1.465 + 'L' => print 'l' if suffix_always is true1.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_always1.471 + . is true1.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 true1.474 + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise1.475 + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise1.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 prefix1.479 +1.480 + Many of the above letters print nothing in Intel mode. See "putop"1.481 + for the details.1.482 +1.483 + Braces '{' and '}', and vertical bars '|', indicate alternative1.484 + mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel1.485 + modes. In cases where there are only two alternatives, the X86_641.486 + instruction is reserved, and "(bad)" is printed.1.487 +*/1.488 +1.489 +static const struct dis386 dis386[] = {1.490 + /* 00 */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.499 + /* 08 */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.508 + /* 10 */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.517 + /* 18 */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.526 + /* 20 */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.535 + /* 28 */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.544 + /* 30 */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.553 + /* 38 */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.562 + /* 40 */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.571 + /* 48 */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.580 + /* 50 */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.589 + /* 58 */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.598 + /* 60 */1.599 + { "pusha{P|}", XX, XX, XX },1.600 + { "popa{P|}", XX, XX, XX },1.601 + { "bound{S|}", Gv, Ma, XX },1.602 + { X86_64_0 },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.607 + /* 68 */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.616 + /* 70 */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.625 + /* 78 */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.634 + /* 80 */1.635 + { GRP1b },1.636 + { GRP1S },1.637 + { "(bad)", XX, XX, XX },1.638 + { GRP1Ss },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.643 + /* 88 */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.652 + /* 90 */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.661 + /* 98 */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.670 + /* a0 */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.679 + /* a8 */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.688 + /* b0 */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.697 + /* b8 */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.706 + /* c0 */1.707 + { GRP2b },1.708 + { GRP2S },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.715 + /* c8 */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.724 + /* d0 */1.725 + { GRP2b_one },1.726 + { GRP2S_one },1.727 + { GRP2b_cl },1.728 + { GRP2S_cl },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.733 + /* d8 */1.734 + { FLOAT },1.735 + { FLOAT },1.736 + { FLOAT },1.737 + { FLOAT },1.738 + { FLOAT },1.739 + { FLOAT },1.740 + { FLOAT },1.741 + { FLOAT },1.742 + /* e0 */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.751 + /* e8 */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.760 + /* f0 */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.767 + { GRP3b },1.768 + { GRP3S },1.769 + /* f8 */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.776 + { GRP4 },1.777 + { GRP5 },1.778 +};1.779 +1.780 +static const struct dis386 dis386_twobyte[] = {1.781 + /* 00 */1.782 + { GRP6 },1.783 + { GRP7 },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.790 + /* 08 */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.796 + { GRPAMD },1.797 + { "femms", XX, XX, XX },1.798 + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */1.799 + /* 10 */1.800 + { PREGRP8 },1.801 + { PREGRP9 },1.802 + { PREGRP30 },1.803 + { "movlpX", EX, XM, SIMD_Fixup, 'h' },1.804 + { "unpcklpX", XM, EX, XX },1.805 + { "unpckhpX", XM, EX, XX },1.806 + { PREGRP31 },1.807 + { "movhpX", EX, XM, SIMD_Fixup, 'l' },1.808 + /* 18 */1.809 + { GRP14 },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.817 + /* 20 */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.826 + /* 28 */1.827 + { "movapX", XM, EX, XX },1.828 + { "movapX", EX, XM, XX },1.829 + { PREGRP2 },1.830 + { "movntpX", Ev, XM, XX },1.831 + { PREGRP4 },1.832 + { PREGRP3 },1.833 + { "ucomisX", XM,EX, XX },1.834 + { "comisX", XM,EX, XX },1.835 + /* 30 */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.844 + /* 38 */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.853 + /* 40 */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.862 + /* 48 */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.871 + /* 50 */1.872 + { "movmskpX", Gdq, XS, XX },1.873 + { PREGRP13 },1.874 + { PREGRP12 },1.875 + { PREGRP11 },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.880 + /* 58 */1.881 + { PREGRP0 },1.882 + { PREGRP10 },1.883 + { PREGRP17 },1.884 + { PREGRP16 },1.885 + { PREGRP14 },1.886 + { PREGRP7 },1.887 + { PREGRP5 },1.888 + { PREGRP6 },1.889 + /* 60 */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.898 + /* 68 */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.903 + { PREGRP26 },1.904 + { PREGRP24 },1.905 + { "movd", MX, Edq, XX },1.906 + { PREGRP19 },1.907 + /* 70 */1.908 + { PREGRP22 },1.909 + { GRP10 },1.910 + { GRP11 },1.911 + { GRP12 },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.916 + /* 78 */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.921 + { PREGRP28 },1.922 + { PREGRP29 },1.923 + { PREGRP23 },1.924 + { PREGRP20 },1.925 + /* 80 */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.934 + /* 88 */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.943 + /* 90 */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.952 + /* 98 */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.961 + /* a0 */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.968 + { GRPPADLCK2 },1.969 + { GRPPADLCK1 },1.970 + /* a8 */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.977 + { GRP13 },1.978 + { "imulS", Gv, Ev, XX },1.979 + /* b0 */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.988 + /* b8 */1.989 + { "(bad)", XX, XX, XX },1.990 + { "ud2b", XX, XX, XX },1.991 + { GRP8 },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.997 + /* c0 */1.998 + { "xaddB", Eb, Gb, XX },1.999 + { "xaddS", Ev, Gv, XX },1.1000 + { PREGRP1 },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.1005 + { GRP9 },1.1006 + /* c8 */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.1015 + /* d0 */1.1016 + { PREGRP27 },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.1022 + { PREGRP21 },1.1023 + { "pmovmskb", Gdq, MS, XX },1.1024 + /* d8 */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.1033 + /* e0 */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.1040 + { PREGRP15 },1.1041 + { PREGRP25 },1.1042 + /* e8 */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.1051 + /* f0 */1.1052 + { PREGRP32 },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.1059 + { PREGRP18 },1.1060 + /* f8 */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.1069 +};1.1070 +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.1092 +};1.1093 +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.1115 +};1.1116 +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.1138 +};1.1139 +1.1140 +static char obuf[100];1.1141 +static char *obufp;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.1147 +static int mod;1.1148 +static int rm;1.1149 +static int reg;1.1150 +static unsigned char need_modrm;1.1151 +1.1152 +/* If we are accessing mod/rm/reg without need_modrm set, then the1.1153 + values are stale. Hitting this abort likely indicates that you1.1154 + need to update onebyte_has_modrm or twobyte_has_modrm. */1.1155 +#define MODRM_CHECK if (!need_modrm) abort ()1.1156 +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.1164 +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.1168 +};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.1172 +};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.1176 +};1.1177 +static const char *intel_names8[] = {1.1178 + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",1.1179 +};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.1183 +};1.1184 +static const char *intel_names_seg[] = {1.1185 + "es", "cs", "ss", "ds", "fs", "gs", "?", "?",1.1186 +};1.1187 +static const char *intel_index16[] = {1.1188 + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"1.1189 +};1.1190 +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.1194 +};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.1198 +};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.1202 +};1.1203 +static const char *att_names8[] = {1.1204 + "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",1.1205 +};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.1209 +};1.1210 +static const char *att_names_seg[] = {1.1211 + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",1.1212 +};1.1213 +static const char *att_index16[] = {1.1214 + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"1.1215 +};1.1216 +1.1217 +static const struct dis386 grps[][8] = {1.1218 + /* GRP1b */1.1219 + {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.1228 + },1.1229 + /* GRP1S */1.1230 + {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.1239 + },1.1240 + /* GRP1Ss */1.1241 + {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.1250 + },1.1251 + /* GRP2b */1.1252 + {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.1261 + },1.1262 + /* GRP2S */1.1263 + {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.1272 + },1.1273 + /* GRP2b_one */1.1274 + {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.1283 + },1.1284 + /* GRP2S_one */1.1285 + {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.1294 + },1.1295 + /* GRP2b_cl */1.1296 + {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.1305 + },1.1306 + /* GRP2S_cl */1.1307 + {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.1316 + },1.1317 + /* GRP3b */1.1318 + {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.1327 + },1.1328 + /* GRP3S */1.1329 + {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.1338 + },1.1339 + /* GRP4 */1.1340 + {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.1349 + },1.1350 + /* GRP5 */1.1351 + {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.1360 + },1.1361 + /* GRP6 */1.1362 + {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.1371 + },1.1372 + /* GRP7 */1.1373 + {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.1382 + },1.1383 + /* GRP8 */1.1384 + {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.1393 + },1.1394 + /* GRP9 */1.1395 + {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.1404 + },1.1405 + /* GRP10 */1.1406 + {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.1415 + },1.1416 + /* GRP11 */1.1417 + {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.1426 + },1.1427 + /* GRP12 */1.1428 + {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.1437 + },1.1438 + /* GRP13 */1.1439 + {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.1448 + },1.1449 + /* GRP14 */1.1450 + {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.1459 + },1.1460 + /* GRPAMD */1.1461 + {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.1470 + },1.1471 + /* GRPPADLCK1 */1.1472 + {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.1481 + },1.1482 + /* GRPPADLCK2 */1.1483 + {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.1492 + }1.1493 +};1.1494 +1.1495 +static const struct dis386 prefix_user_table[][4] = {1.1496 + /* PREGRP0 */1.1497 + {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.1502 + },1.1503 + /* PREGRP1 */1.1504 + {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.1509 + },1.1510 + /* PREGRP2 */1.1511 + {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.1516 + },1.1517 + /* PREGRP3 */1.1518 + {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.1523 + },1.1524 + /* PREGRP4 */1.1525 + {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.1530 + },1.1531 + /* PREGRP5 */1.1532 + {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.1537 + },1.1538 + /* PREGRP6 */1.1539 + {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.1544 + },1.1545 + /* PREGRP7 */1.1546 + {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.1551 + },1.1552 + /* PREGRP8 */1.1553 + {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.1558 + },1.1559 + /* PREGRP9 */1.1560 + {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.1565 + },1.1566 + /* PREGRP10 */1.1567 + {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.1572 + },1.1573 + /* PREGRP11 */1.1574 + {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.1579 + },1.1580 + /* PREGRP12 */1.1581 + {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.1586 + },1.1587 + /* PREGRP13 */1.1588 + {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.1593 + },1.1594 + /* PREGRP14 */1.1595 + {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.1600 + },1.1601 + /* PREGRP15 */1.1602 + {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.1607 + },1.1608 + /* PREGRP16 */1.1609 + {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.1614 + },1.1615 + /* PREGRP17 */1.1616 + {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.1621 + },1.1622 + /* PREGRP18 */1.1623 + {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.1628 + },1.1629 + /* PREGRP19 */1.1630 + {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.1635 + },1.1636 + /* PREGRP20 */1.1637 + {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.1642 + },1.1643 + /* PREGRP21 */1.1644 + {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.1649 + },1.1650 + /* PREGRP22 */1.1651 + {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.1656 + },1.1657 + /* PREGRP23 */1.1658 + {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.1663 + },1.1664 + /* PREGRP24 */1.1665 + {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.1670 + },1.1671 + /* PREGRP25 */1.1672 + {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.1677 + },1.1678 + /* PREGRP26 */1.1679 + {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.1684 + },1.1685 + /* PREGRP27 */1.1686 + {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.1691 + },1.1692 + /* PREGRP28 */1.1693 + {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.1698 + },1.1699 + /* PREGRP29 */1.1700 + {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.1705 + },1.1706 + /* PREGRP30 */1.1707 + {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.1712 + },1.1713 + /* PREGRP31 */1.1714 + {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.1719 + },1.1720 + /* PREGRP32 */1.1721 + {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.1726 + },1.1727 +};1.1728 +1.1729 +static const struct dis386 x86_64_table[][2] = {1.1730 + {1.1731 + { "arpl", Ew, Gw, XX },1.1732 + { "movs{||lq|xd}", Gv, Ed, XX },1.1733 + },1.1734 +};1.1735 +1.1736 +#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")1.1737 +1.1738 +static void1.1739 +ckprefix (void)1.1740 +{1.1741 + int newrex;1.1742 + rex = 0;1.1743 + prefixes = 0;1.1744 + used_prefixes = 0;1.1745 + rex_used = 0;1.1746 + while (1)1.1747 + {1.1748 + FETCH_DATA (the_info, codep + 1);1.1749 + newrex = 0;1.1750 + switch (*codep)1.1751 + {1.1752 + /* REX prefixes family. */1.1753 + case 0x40:1.1754 + case 0x41:1.1755 + case 0x42:1.1756 + case 0x43:1.1757 + case 0x44:1.1758 + case 0x45:1.1759 + case 0x46:1.1760 + case 0x47:1.1761 + case 0x48:1.1762 + case 0x49:1.1763 + case 0x4a:1.1764 + case 0x4b:1.1765 + case 0x4c:1.1766 + case 0x4d:1.1767 + case 0x4e:1.1768 + case 0x4f:1.1769 + if (mode_64bit)1.1770 + newrex = *codep;1.1771 + else1.1772 + return;1.1773 + break;1.1774 + case 0xf3:1.1775 + prefixes |= PREFIX_REPZ;1.1776 + break;1.1777 + case 0xf2:1.1778 + prefixes |= PREFIX_REPNZ;1.1779 + break;1.1780 + case 0xf0:1.1781 + prefixes |= PREFIX_LOCK;1.1782 + break;1.1783 + case 0x2e:1.1784 + prefixes |= PREFIX_CS;1.1785 + break;1.1786 + case 0x36:1.1787 + prefixes |= PREFIX_SS;1.1788 + break;1.1789 + case 0x3e:1.1790 + prefixes |= PREFIX_DS;1.1791 + break;1.1792 + case 0x26:1.1793 + prefixes |= PREFIX_ES;1.1794 + break;1.1795 + case 0x64:1.1796 + prefixes |= PREFIX_FS;1.1797 + break;1.1798 + case 0x65:1.1799 + prefixes |= PREFIX_GS;1.1800 + break;1.1801 + case 0x66:1.1802 + prefixes |= PREFIX_DATA;1.1803 + break;1.1804 + case 0x67:1.1805 + prefixes |= PREFIX_ADDR;1.1806 + break;1.1807 + case FWAIT_OPCODE:1.1808 + /* fwait is really an instruction. If there are prefixes1.1809 + before the fwait, they belong to the fwait, *not* to the1.1810 + following instruction. */1.1811 + if (prefixes)1.1812 + {1.1813 + prefixes |= PREFIX_FWAIT;1.1814 + codep++;1.1815 + return;1.1816 + }1.1817 + prefixes = PREFIX_FWAIT;1.1818 + break;1.1819 + default:1.1820 + return;1.1821 + }1.1822 + /* Rex is ignored when followed by another prefix. */1.1823 + if (rex)1.1824 + {1.1825 + oappend (prefix_name (rex, 0));1.1826 + oappend (" ");1.1827 + }1.1828 + rex = newrex;1.1829 + codep++;1.1830 + }1.1831 +}1.1832 +1.1833 +/* Return the name of the prefix byte PREF, or NULL if PREF is not a1.1834 + prefix byte. */1.1835 +1.1836 +static const char *1.1837 +prefix_name (int pref, int sizeflag)1.1838 +{1.1839 + switch (pref)1.1840 + {1.1841 + /* REX prefixes family. */1.1842 + case 0x40:1.1843 + return "rex";1.1844 + case 0x41:1.1845 + return "rexZ";1.1846 + case 0x42:1.1847 + return "rexY";1.1848 + case 0x43:1.1849 + return "rexYZ";1.1850 + case 0x44:1.1851 + return "rexX";1.1852 + case 0x45:1.1853 + return "rexXZ";1.1854 + case 0x46:1.1855 + return "rexXY";1.1856 + case 0x47:1.1857 + return "rexXYZ";1.1858 + case 0x48:1.1859 + return "rex64";1.1860 + case 0x49:1.1861 + return "rex64Z";1.1862 + case 0x4a:1.1863 + return "rex64Y";1.1864 + case 0x4b:1.1865 + return "rex64YZ";1.1866 + case 0x4c:1.1867 + return "rex64X";1.1868 + case 0x4d:1.1869 + return "rex64XZ";1.1870 + case 0x4e:1.1871 + return "rex64XY";1.1872 + case 0x4f:1.1873 + return "rex64XYZ";1.1874 + case 0xf3:1.1875 + return "repz";1.1876 + case 0xf2:1.1877 + return "repnz";1.1878 + case 0xf0:1.1879 + return "lock";1.1880 + case 0x2e:1.1881 + return "cs";1.1882 + case 0x36:1.1883 + return "ss";1.1884 + case 0x3e:1.1885 + return "ds";1.1886 + case 0x26:1.1887 + return "es";1.1888 + case 0x64:1.1889 + return "fs";1.1890 + case 0x65:1.1891 + return "gs";1.1892 + case 0x66:1.1893 + return (sizeflag & DFLAG) ? "data16" : "data32";1.1894 + case 0x67:1.1895 + if (mode_64bit)1.1896 + return (sizeflag & AFLAG) ? "addr32" : "addr64";1.1897 + else1.1898 + return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";1.1899 + case FWAIT_OPCODE:1.1900 + return "fwait";1.1901 + default:1.1902 + return NULL;1.1903 + }1.1904 +}1.1905 +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.1912 +1.1913 +/*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 will1.1918 + * be used to print the target address if this is a relative jump or call1.1919 + * The function returns the length of this instruction in bytes.1.1920 + */1.1921 +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.1927 +1.1928 +/* Here for backwards compatibility. When gdb stops using1.1929 + print_insn_i386_att and print_insn_i386_intel these functions can1.1930 + disappear, and print_insn_i386 be merged into print_insn. */1.1931 +int1.1932 +print_insn_i386_att (bfd_vma pc, disassemble_info *info)1.1933 +{1.1934 + intel_syntax = 0;1.1935 +1.1936 + return print_insn (pc, info);1.1937 +}1.1938 +1.1939 +int1.1940 +print_insn_i386_intel (bfd_vma pc, disassemble_info *info)1.1941 +{1.1942 + intel_syntax = 1;1.1943 +1.1944 + return print_insn (pc, info);1.1945 +}1.1946 +1.1947 +int1.1948 +print_insn_i386 (bfd_vma pc, disassemble_info *info)1.1949 +{1.1950 + intel_syntax = -1;1.1951 +1.1952 + return print_insn (pc, info);1.1953 +}1.1954 +1.1955 +static int1.1956 +print_insn (bfd_vma pc, disassemble_info *info)1.1957 +{1.1958 + const struct dis386 *dp;1.1959 + int i;1.1960 + char *first, *second, *third;1.1961 + int needcomma;1.1962 + unsigned char uses_SSE_prefix, uses_LOCK_prefix;1.1963 + int sizeflag;1.1964 + const char *p;1.1965 + struct dis_private priv;1.1966 +1.1967 + mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax1.1968 + || info->mach == bfd_mach_x86_64);1.1969 +1.1970 + if (intel_syntax == (char) -1)1.1971 + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax1.1972 + || info->mach == bfd_mach_x86_64_intel_syntax);1.1973 +1.1974 + if (info->mach == bfd_mach_i386_i3861.1975 + || info->mach == bfd_mach_x86_641.1976 + || info->mach == bfd_mach_i386_i386_intel_syntax1.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.1981 + else1.1982 + abort ();1.1983 +1.1984 + for (p = info->disassembler_options; p != NULL; )1.1985 + {1.1986 + if (strncmp (p, "x86-64", 6) == 0)1.1987 + {1.1988 + mode_64bit = 1;1.1989 + priv.orig_sizeflag = AFLAG | DFLAG;1.1990 + }1.1991 + else if (strncmp (p, "i386", 4) == 0)1.1992 + {1.1993 + mode_64bit = 0;1.1994 + priv.orig_sizeflag = AFLAG | DFLAG;1.1995 + }1.1996 + else if (strncmp (p, "i8086", 5) == 0)1.1997 + {1.1998 + mode_64bit = 0;1.1999 + priv.orig_sizeflag = 0;1.2000 + }1.2001 + else if (strncmp (p, "intel", 5) == 0)1.2002 + {1.2003 + intel_syntax = 1;1.2004 + }1.2005 + else if (strncmp (p, "att", 3) == 0)1.2006 + {1.2007 + intel_syntax = 0;1.2008 + }1.2009 + else if (strncmp (p, "addr", 4) == 0)1.2010 + {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.2015 + }1.2016 + else if (strncmp (p, "data", 4) == 0)1.2017 + {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.2022 + }1.2023 + else if (strncmp (p, "suffix", 6) == 0)1.2024 + priv.orig_sizeflag |= SUFFIX_ALWAYS;1.2025 +1.2026 + p = strchr (p, ',');1.2027 + if (p != NULL)1.2028 + p++;1.2029 + }1.2030 +1.2031 + if (intel_syntax)1.2032 + {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.2040 + open_char = '[';1.2041 + close_char = ']';1.2042 + separator_char = '+';1.2043 + scale_char = '*';1.2044 + }1.2045 + else1.2046 + {1.2047 + names64 = att_names64;1.2048 + names32 = att_names32;1.2049 + names16 = att_names16;1.2050 + names8 = att_names8;1.2051 + names8rex = att_names8rex;1.2052 + names_seg = att_names_seg;1.2053 + index16 = att_index16;1.2054 + open_char = '(';1.2055 + close_char = ')';1.2056 + separator_char = ',';1.2057 + scale_char = ',';1.2058 + }1.2059 +1.2060 + /* The output looks better if we put 7 bytes on a line, since that1.2061 + puts most long word instructions on a single line. */1.2062 + info->bytes_per_line = 7;1.2063 +1.2064 + info->private_data = &priv;1.2065 + priv.max_fetched = priv.the_buffer;1.2066 + priv.insn_start = pc;1.2067 +1.2068 + obuf[0] = 0;1.2069 + op1out[0] = 0;1.2070 + op2out[0] = 0;1.2071 + op3out[0] = 0;1.2072 +1.2073 + op_index[0] = op_index[1] = op_index[2] = -1;1.2074 +1.2075 + the_info = info;1.2076 + start_pc = pc;1.2077 + start_codep = priv.the_buffer;1.2078 + codep = priv.the_buffer;1.2079 +1.2080 + if (setjmp (priv.bailout) != 0)1.2081 + {1.2082 + const char *name;1.2083 +1.2084 + /* Getting here means we tried for data but didn't get it. That1.2085 + means we have an incomplete instruction of some sort. Just1.2086 + print the first byte as a prefix or a .byte pseudo-op. */1.2087 + if (codep > priv.the_buffer)1.2088 + {1.2089 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);1.2090 + if (name != NULL)1.2091 + (*info->fprintf_func) (info->stream, "%s", name);1.2092 + else1.2093 + {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.2097 + }1.2098 +1.2099 + return 1;1.2100 + }1.2101 +1.2102 + return -1;1.2103 + }1.2104 +1.2105 + obufp = obuf;1.2106 + ckprefix ();1.2107 +1.2108 + insn_codep = codep;1.2109 + sizeflag = priv.orig_sizeflag;1.2110 +1.2111 + FETCH_DATA (info, codep + 1);1.2112 + two_source_ops = (*codep == 0x62) || (*codep == 0xc8);1.2113 +1.2114 + if ((prefixes & PREFIX_FWAIT)1.2115 + && ((*codep < 0xd8) || (*codep > 0xdf)))1.2116 + {1.2117 + const char *name;1.2118 +1.2119 + /* fwait not followed by floating point instruction. Print the1.2120 + first prefix, which is probably fwait itself. */1.2121 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);1.2122 + if (name == NULL)1.2123 + name = INTERNAL_DISASSEMBLER_ERROR;1.2124 + (*info->fprintf_func) (info->stream, "%s", name);1.2125 + return 1;1.2126 + }1.2127 +1.2128 + if (*codep == 0x0f)1.2129 + {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.2135 + }1.2136 + else1.2137 + {1.2138 + dp = &dis386[*codep];1.2139 + need_modrm = onebyte_has_modrm[*codep];1.2140 + uses_SSE_prefix = 0;1.2141 + uses_LOCK_prefix = 0;1.2142 + }1.2143 + codep++;1.2144 +1.2145 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))1.2146 + {1.2147 + oappend ("repz ");1.2148 + used_prefixes |= PREFIX_REPZ;1.2149 + }1.2150 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))1.2151 + {1.2152 + oappend ("repnz ");1.2153 + used_prefixes |= PREFIX_REPNZ;1.2154 + }1.2155 + if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))1.2156 + {1.2157 + oappend ("lock ");1.2158 + used_prefixes |= PREFIX_LOCK;1.2159 + }1.2160 +1.2161 + if (prefixes & PREFIX_ADDR)1.2162 + {1.2163 + sizeflag ^= AFLAG;1.2164 + if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)1.2165 + {1.2166 + if ((sizeflag & AFLAG) || mode_64bit)1.2167 + oappend ("addr32 ");1.2168 + else1.2169 + oappend ("addr16 ");1.2170 + used_prefixes |= PREFIX_ADDR;1.2171 + }1.2172 + }1.2173 +1.2174 + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))1.2175 + {1.2176 + sizeflag ^= DFLAG;1.2177 + if (dp->bytemode3 == cond_jump_mode1.2178 + && dp->bytemode1 == v_mode1.2179 + && !intel_syntax)1.2180 + {1.2181 + if (sizeflag & DFLAG)1.2182 + oappend ("data32 ");1.2183 + else1.2184 + oappend ("data16 ");1.2185 + used_prefixes |= PREFIX_DATA;1.2186 + }1.2187 + }1.2188 +1.2189 + if (need_modrm)1.2190 + {1.2191 + FETCH_DATA (info, codep + 1);1.2192 + mod = (*codep >> 6) & 3;1.2193 + reg = (*codep >> 3) & 7;1.2194 + rm = *codep & 7;1.2195 + }1.2196 +1.2197 + if (dp->name == NULL && dp->bytemode1 == FLOATCODE)1.2198 + {1.2199 + dofloat (sizeflag);1.2200 + }1.2201 + else1.2202 + {1.2203 + int index;1.2204 + if (dp->name == NULL)1.2205 + {1.2206 + switch (dp->bytemode1)1.2207 + {1.2208 + case USE_GROUPS:1.2209 + dp = &grps[dp->bytemode2][reg];1.2210 + break;1.2211 +1.2212 + case USE_PREFIX_USER_TABLE:1.2213 + index = 0;1.2214 + used_prefixes |= (prefixes & PREFIX_REPZ);1.2215 + if (prefixes & PREFIX_REPZ)1.2216 + index = 1;1.2217 + else1.2218 + {1.2219 + used_prefixes |= (prefixes & PREFIX_DATA);1.2220 + if (prefixes & PREFIX_DATA)1.2221 + index = 2;1.2222 + else1.2223 + {1.2224 + used_prefixes |= (prefixes & PREFIX_REPNZ);1.2225 + if (prefixes & PREFIX_REPNZ)1.2226 + index = 3;1.2227 + }1.2228 + }1.2229 + dp = &prefix_user_table[dp->bytemode2][index];1.2230 + break;1.2231 +1.2232 + case X86_64_SPECIAL:1.2233 + dp = &x86_64_table[dp->bytemode2][mode_64bit];1.2234 + break;1.2235 +1.2236 + default:1.2237 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.2238 + break;1.2239 + }1.2240 + }1.2241 +1.2242 + if (putop (dp->name, sizeflag) == 0)1.2243 + {1.2244 + obufp = op1out;1.2245 + op_ad = 2;1.2246 + if (dp->op1)1.2247 + (*dp->op1) (dp->bytemode1, sizeflag);1.2248 +1.2249 + obufp = op2out;1.2250 + op_ad = 1;1.2251 + if (dp->op2)1.2252 + (*dp->op2) (dp->bytemode2, sizeflag);1.2253 +1.2254 + obufp = op3out;1.2255 + op_ad = 0;1.2256 + if (dp->op3)1.2257 + (*dp->op3) (dp->bytemode3, sizeflag);1.2258 + }1.2259 + }1.2260 +1.2261 + /* See if any prefixes were not used. If so, print the first one1.2262 + separately. If we don't do this, we'll wind up printing an1.2263 + instruction stream which does not precisely correspond to the1.2264 + bytes we are disassembling. */1.2265 + if ((prefixes & ~used_prefixes) != 0)1.2266 + {1.2267 + const char *name;1.2268 +1.2269 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);1.2270 + if (name == NULL)1.2271 + name = INTERNAL_DISASSEMBLER_ERROR;1.2272 + (*info->fprintf_func) (info->stream, "%s", name);1.2273 + return 1;1.2274 + }1.2275 + if (rex & ~rex_used)1.2276 + {1.2277 + const char *name;1.2278 + name = prefix_name (rex | 0x40, priv.orig_sizeflag);1.2279 + if (name == NULL)1.2280 + name = INTERNAL_DISASSEMBLER_ERROR;1.2281 + (*info->fprintf_func) (info->stream, "%s ", name);1.2282 + }1.2283 +1.2284 + obufp = obuf + strlen (obuf);1.2285 + for (i = strlen (obuf); i < 6; i++)1.2286 + oappend (" ");1.2287 + oappend (" ");1.2288 + (*info->fprintf_func) (info->stream, "%s", obuf);1.2289 +1.2290 + /* The enter and bound instructions are printed with operands in the same1.2291 + order as the intel book; everything else is printed in reverse order. */1.2292 + if (intel_syntax || two_source_ops)1.2293 + {1.2294 + first = op1out;1.2295 + second = op2out;1.2296 + third = op3out;1.2297 + op_ad = op_index[0];1.2298 + op_index[0] = op_index[2];1.2299 + op_index[2] = op_ad;1.2300 + }1.2301 + else1.2302 + {1.2303 + first = op3out;1.2304 + second = op2out;1.2305 + third = op1out;1.2306 + }1.2307 + needcomma = 0;1.2308 + if (*first)1.2309 + {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.2312 + else1.2313 + (*info->fprintf_func) (info->stream, "%s", first);1.2314 + needcomma = 1;1.2315 + }1.2316 + if (*second)1.2317 + {1.2318 + if (needcomma)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.2322 + else1.2323 + (*info->fprintf_func) (info->stream, "%s", second);1.2324 + needcomma = 1;1.2325 + }1.2326 + if (*third)1.2327 + {1.2328 + if (needcomma)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.2332 + else1.2333 + (*info->fprintf_func) (info->stream, "%s", third);1.2334 + }1.2335 + for (i = 0; i < 3; i++)1.2336 + if (op_index[i] != -1 && op_riprel[i])1.2337 + {1.2338 + (*info->fprintf_func) (info->stream, " # ");1.2339 + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep1.2340 + + op_address[op_index[i]]), info);1.2341 + }1.2342 + return codep - priv.the_buffer;1.2343 +}1.2344 +1.2345 +static const char *float_mem[] = {1.2346 + /* d8 */1.2347 + "fadd{s||s|}",1.2348 + "fmul{s||s|}",1.2349 + "fcom{s||s|}",1.2350 + "fcomp{s||s|}",1.2351 + "fsub{s||s|}",1.2352 + "fsubr{s||s|}",1.2353 + "fdiv{s||s|}",1.2354 + "fdivr{s||s|}",1.2355 + /* d9 */1.2356 + "fld{s||s|}",1.2357 + "(bad)",1.2358 + "fst{s||s|}",1.2359 + "fstp{s||s|}",1.2360 + "fldenvIC",1.2361 + "fldcw",1.2362 + "fNstenvIC",1.2363 + "fNstcw",1.2364 + /* da */1.2365 + "fiadd{l||l|}",1.2366 + "fimul{l||l|}",1.2367 + "ficom{l||l|}",1.2368 + "ficomp{l||l|}",1.2369 + "fisub{l||l|}",1.2370 + "fisubr{l||l|}",1.2371 + "fidiv{l||l|}",1.2372 + "fidivr{l||l|}",1.2373 + /* db */1.2374 + "fild{l||l|}",1.2375 + "fisttp{l||l|}",1.2376 + "fist{l||l|}",1.2377 + "fistp{l||l|}",1.2378 + "(bad)",1.2379 + "fld{t||t|}",1.2380 + "(bad)",1.2381 + "fstp{t||t|}",1.2382 + /* dc */1.2383 + "fadd{l||l|}",1.2384 + "fmul{l||l|}",1.2385 + "fcom{l||l|}",1.2386 + "fcomp{l||l|}",1.2387 + "fsub{l||l|}",1.2388 + "fsubr{l||l|}",1.2389 + "fdiv{l||l|}",1.2390 + "fdivr{l||l|}",1.2391 + /* dd */1.2392 + "fld{l||l|}",1.2393 + "fisttp{ll||ll|}",1.2394 + "fst{l||l|}",1.2395 + "fstp{l||l|}",1.2396 + "frstorIC",1.2397 + "(bad)",1.2398 + "fNsaveIC",1.2399 + "fNstsw",1.2400 + /* de */1.2401 + "fiadd",1.2402 + "fimul",1.2403 + "ficom",1.2404 + "ficomp",1.2405 + "fisub",1.2406 + "fisubr",1.2407 + "fidiv",1.2408 + "fidivr",1.2409 + /* df */1.2410 + "fild",1.2411 + "fisttp",1.2412 + "fist",1.2413 + "fistp",1.2414 + "fbld",1.2415 + "fild{ll||ll|}",1.2416 + "fbstp",1.2417 + "fistp{ll||ll|}",1.2418 +};1.2419 +1.2420 +static const unsigned char float_mem_mode[] = {1.2421 + /* d8 */1.2422 + d_mode,1.2423 + d_mode,1.2424 + d_mode,1.2425 + d_mode,1.2426 + d_mode,1.2427 + d_mode,1.2428 + d_mode,1.2429 + d_mode,1.2430 + /* d9 */1.2431 + d_mode,1.2432 + 0,1.2433 + d_mode,1.2434 + d_mode,1.2435 + 0,1.2436 + w_mode,1.2437 + 0,1.2438 + w_mode,1.2439 + /* da */1.2440 + d_mode,1.2441 + d_mode,1.2442 + d_mode,1.2443 + d_mode,1.2444 + d_mode,1.2445 + d_mode,1.2446 + d_mode,1.2447 + d_mode,1.2448 + /* db */1.2449 + d_mode,1.2450 + d_mode,1.2451 + d_mode,1.2452 + d_mode,1.2453 + 0,1.2454 + t_mode,1.2455 + 0,1.2456 + t_mode,1.2457 + /* dc */1.2458 + q_mode,1.2459 + q_mode,1.2460 + q_mode,1.2461 + q_mode,1.2462 + q_mode,1.2463 + q_mode,1.2464 + q_mode,1.2465 + q_mode,1.2466 + /* dd */1.2467 + q_mode,1.2468 + q_mode,1.2469 + q_mode,1.2470 + q_mode,1.2471 + 0,1.2472 + 0,1.2473 + 0,1.2474 + w_mode,1.2475 + /* de */1.2476 + w_mode,1.2477 + w_mode,1.2478 + w_mode,1.2479 + w_mode,1.2480 + w_mode,1.2481 + w_mode,1.2482 + w_mode,1.2483 + w_mode,1.2484 + /* df */1.2485 + w_mode,1.2486 + w_mode,1.2487 + w_mode,1.2488 + w_mode,1.2489 + t_mode,1.2490 + q_mode,1.2491 + t_mode,1.2492 + q_mode1.2493 +};1.2494 +1.2495 +#define ST OP_ST, 01.2496 +#define STi OP_STi, 01.2497 +1.2498 +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 01.2499 +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 01.2500 +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 01.2501 +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 01.2502 +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 01.2503 +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 01.2504 +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 01.2505 +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 01.2506 +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 01.2507 +1.2508 +static const struct dis386 float_reg[][8] = {1.2509 + /* d8 */1.2510 + {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.2519 + },1.2520 + /* d9 */1.2521 + {1.2522 + { "fld", STi, XX, XX },1.2523 + { "fxch", STi, XX, XX },1.2524 + { FGRPd9_2 },1.2525 + { "(bad)", XX, XX, XX },1.2526 + { FGRPd9_4 },1.2527 + { FGRPd9_5 },1.2528 + { FGRPd9_6 },1.2529 + { FGRPd9_7 },1.2530 + },1.2531 + /* da */1.2532 + {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.2538 + { FGRPda_5 },1.2539 + { "(bad)", XX, XX, XX },1.2540 + { "(bad)", XX, XX, XX },1.2541 + },1.2542 + /* db */1.2543 + {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.2548 + { FGRPdb_4 },1.2549 + { "fucomi", ST, STi, XX },1.2550 + { "fcomi", ST, STi, XX },1.2551 + { "(bad)", XX, XX, XX },1.2552 + },1.2553 + /* dc */1.2554 + {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.2559 +#if UNIXWARE_COMPAT1.2560 + { "fsub", STi, ST, XX },1.2561 + { "fsubr", STi, ST, XX },1.2562 + { "fdiv", STi, ST, XX },1.2563 + { "fdivr", STi, ST, XX },1.2564 +#else1.2565 + { "fsubr", STi, ST, XX },1.2566 + { "fsub", STi, ST, XX },1.2567 + { "fdivr", STi, ST, XX },1.2568 + { "fdiv", STi, ST, XX },1.2569 +#endif1.2570 + },1.2571 + /* dd */1.2572 + {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.2581 + },1.2582 + /* de */1.2583 + {1.2584 + { "faddp", STi, ST, XX },1.2585 + { "fmulp", STi, ST, XX },1.2586 + { "(bad)", XX, XX, XX },1.2587 + { FGRPde_3 },1.2588 +#if UNIXWARE_COMPAT1.2589 + { "fsubp", STi, ST, XX },1.2590 + { "fsubrp", STi, ST, XX },1.2591 + { "fdivp", STi, ST, XX },1.2592 + { "fdivrp", STi, ST, XX },1.2593 +#else1.2594 + { "fsubrp", STi, ST, XX },1.2595 + { "fsubp", STi, ST, XX },1.2596 + { "fdivrp", STi, ST, XX },1.2597 + { "fdivp", STi, ST, XX },1.2598 +#endif1.2599 + },1.2600 + /* df */1.2601 + {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.2606 + { FGRPdf_4 },1.2607 + { "fucomip",ST, STi, XX },1.2608 + { "fcomip", ST, STi, XX },1.2609 + { "(bad)", XX, XX, XX },1.2610 + },1.2611 +};1.2612 +1.2613 +static char *fgrps[][8] = {1.2614 + /* d9_2 0 */1.2615 + {1.2616 + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",1.2617 + },1.2618 +1.2619 + /* d9_4 1 */1.2620 + {1.2621 + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",1.2622 + },1.2623 +1.2624 + /* d9_5 2 */1.2625 + {1.2626 + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",1.2627 + },1.2628 +1.2629 + /* d9_6 3 */1.2630 + {1.2631 + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",1.2632 + },1.2633 +1.2634 + /* d9_7 4 */1.2635 + {1.2636 + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",1.2637 + },1.2638 +1.2639 + /* da_5 5 */1.2640 + {1.2641 + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",1.2642 + },1.2643 +1.2644 + /* db_4 6 */1.2645 + {1.2646 + "feni(287 only)","fdisi(287 only)","fNclex","fNinit",1.2647 + "fNsetpm(287 only)","(bad)","(bad)","(bad)",1.2648 + },1.2649 +1.2650 + /* de_3 7 */1.2651 + {1.2652 + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",1.2653 + },1.2654 +1.2655 + /* df_4 8 */1.2656 + {1.2657 + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",1.2658 + },1.2659 +};1.2660 +1.2661 +static void1.2662 +dofloat (int sizeflag)1.2663 +{1.2664 + const struct dis386 *dp;1.2665 + unsigned char floatop;1.2666 +1.2667 + floatop = codep[-1];1.2668 +1.2669 + if (mod != 3)1.2670 + {1.2671 + int fp_indx = (floatop - 0xd8) * 8 + reg;1.2672 +1.2673 + putop (float_mem[fp_indx], sizeflag);1.2674 + obufp = op1out;1.2675 + OP_E (float_mem_mode[fp_indx], sizeflag);1.2676 + return;1.2677 + }1.2678 + /* Skip mod/rm byte. */1.2679 + MODRM_CHECK;1.2680 + codep++;1.2681 +1.2682 + dp = &float_reg[floatop - 0xd8][reg];1.2683 + if (dp->name == NULL)1.2684 + {1.2685 + putop (fgrps[dp->bytemode1][rm], sizeflag);1.2686 +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.2690 + }1.2691 + else1.2692 + {1.2693 + putop (dp->name, sizeflag);1.2694 +1.2695 + obufp = op1out;1.2696 + if (dp->op1)1.2697 + (*dp->op1) (dp->bytemode1, sizeflag);1.2698 + obufp = op2out;1.2699 + if (dp->op2)1.2700 + (*dp->op2) (dp->bytemode2, sizeflag);1.2701 + }1.2702 +}1.2703 +1.2704 +static void1.2705 +OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.2706 +{1.2707 + oappend ("%st");1.2708 +}1.2709 +1.2710 +static void1.2711 +OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.2712 +{1.2713 + sprintf (scratchbuf, "%%st(%d)", rm);1.2714 + oappend (scratchbuf + intel_syntax);1.2715 +}1.2716 +1.2717 +/* Capital letters in template are macros. */1.2718 +static int1.2719 +putop (const char *template, int sizeflag)1.2720 +{1.2721 + const char *p;1.2722 + int alt = 0;1.2723 +1.2724 + for (p = template; *p; p++)1.2725 + {1.2726 + switch (*p)1.2727 + {1.2728 + default:1.2729 + *obufp++ = *p;1.2730 + break;1.2731 + case '{':1.2732 + alt = 0;1.2733 + if (intel_syntax)1.2734 + alt += 1;1.2735 + if (mode_64bit)1.2736 + alt += 2;1.2737 + while (alt != 0)1.2738 + {1.2739 + while (*++p != '|')1.2740 + {1.2741 + if (*p == '}')1.2742 + {1.2743 + /* Alternative not valid. */1.2744 + strcpy (obuf, "(bad)");1.2745 + obufp = obuf + 5;1.2746 + return 1;1.2747 + }1.2748 + else if (*p == '\0')1.2749 + abort ();1.2750 + }1.2751 + alt--;1.2752 + }1.2753 + /* Fall through. */1.2754 + case 'I':1.2755 + alt = 1;1.2756 + continue;1.2757 + case '|':1.2758 + while (*++p != '}')1.2759 + {1.2760 + if (*p == '\0')1.2761 + abort ();1.2762 + }1.2763 + break;1.2764 + case '}':1.2765 + break;1.2766 + case 'A':1.2767 + if (intel_syntax)1.2768 + break;1.2769 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))1.2770 + *obufp++ = 'b';1.2771 + break;1.2772 + case 'B':1.2773 + if (intel_syntax)1.2774 + break;1.2775 + if (sizeflag & SUFFIX_ALWAYS)1.2776 + *obufp++ = 'b';1.2777 + break;1.2778 + case 'C':1.2779 + if (intel_syntax && !alt)1.2780 + break;1.2781 + if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))1.2782 + {1.2783 + if (sizeflag & DFLAG)1.2784 + *obufp++ = intel_syntax ? 'd' : 'l';1.2785 + else1.2786 + *obufp++ = intel_syntax ? 'w' : 's';1.2787 + used_prefixes |= (prefixes & PREFIX_DATA);1.2788 + }1.2789 + break;1.2790 + case 'E': /* For jcxz/jecxz */1.2791 + if (mode_64bit)1.2792 + {1.2793 + if (sizeflag & AFLAG)1.2794 + *obufp++ = 'r';1.2795 + else1.2796 + *obufp++ = 'e';1.2797 + }1.2798 + else1.2799 + if (sizeflag & AFLAG)1.2800 + *obufp++ = 'e';1.2801 + used_prefixes |= (prefixes & PREFIX_ADDR);1.2802 + break;1.2803 + case 'F':1.2804 + if (intel_syntax)1.2805 + break;1.2806 + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))1.2807 + {1.2808 + if (sizeflag & AFLAG)1.2809 + *obufp++ = mode_64bit ? 'q' : 'l';1.2810 + else1.2811 + *obufp++ = mode_64bit ? 'l' : 'w';1.2812 + used_prefixes |= (prefixes & PREFIX_ADDR);1.2813 + }1.2814 + break;1.2815 + case 'H':1.2816 + if (intel_syntax)1.2817 + break;1.2818 + if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS1.2819 + || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)1.2820 + {1.2821 + used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);1.2822 + *obufp++ = ',';1.2823 + *obufp++ = 'p';1.2824 + if (prefixes & PREFIX_DS)1.2825 + *obufp++ = 't';1.2826 + else1.2827 + *obufp++ = 'n';1.2828 + }1.2829 + break;1.2830 + case 'J':1.2831 + if (intel_syntax)1.2832 + break;1.2833 + *obufp++ = 'l';1.2834 + break;1.2835 + case 'L':1.2836 + if (intel_syntax)1.2837 + break;1.2838 + if (sizeflag & SUFFIX_ALWAYS)1.2839 + *obufp++ = 'l';1.2840 + break;1.2841 + case 'N':1.2842 + if ((prefixes & PREFIX_FWAIT) == 0)1.2843 + *obufp++ = 'n';1.2844 + else1.2845 + used_prefixes |= PREFIX_FWAIT;1.2846 + break;1.2847 + case 'O':1.2848 + USED_REX (REX_MODE64);1.2849 + if (rex & REX_MODE64)1.2850 + *obufp++ = 'o';1.2851 + else1.2852 + *obufp++ = 'd';1.2853 + break;1.2854 + case 'T':1.2855 + if (intel_syntax)1.2856 + break;1.2857 + if (mode_64bit)1.2858 + {1.2859 + *obufp++ = 'q';1.2860 + break;1.2861 + }1.2862 + /* Fall through. */1.2863 + case 'P':1.2864 + if (intel_syntax)1.2865 + break;1.2866 + if ((prefixes & PREFIX_DATA)1.2867 + || (rex & REX_MODE64)1.2868 + || (sizeflag & SUFFIX_ALWAYS))1.2869 + {1.2870 + USED_REX (REX_MODE64);1.2871 + if (rex & REX_MODE64)1.2872 + *obufp++ = 'q';1.2873 + else1.2874 + {1.2875 + if (sizeflag & DFLAG)1.2876 + *obufp++ = 'l';1.2877 + else1.2878 + *obufp++ = 'w';1.2879 + used_prefixes |= (prefixes & PREFIX_DATA);1.2880 + }1.2881 + }1.2882 + break;1.2883 + case 'U':1.2884 + if (intel_syntax)1.2885 + break;1.2886 + if (mode_64bit)1.2887 + {1.2888 + *obufp++ = 'q';1.2889 + break;1.2890 + }1.2891 + /* Fall through. */1.2892 + case 'Q':1.2893 + if (intel_syntax && !alt)1.2894 + break;1.2895 + USED_REX (REX_MODE64);1.2896 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))1.2897 + {1.2898 + if (rex & REX_MODE64)1.2899 + *obufp++ = 'q';1.2900 + else1.2901 + {1.2902 + if (sizeflag & DFLAG)1.2903 + *obufp++ = intel_syntax ? 'd' : 'l';1.2904 + else1.2905 + *obufp++ = 'w';1.2906 + used_prefixes |= (prefixes & PREFIX_DATA);1.2907 + }1.2908 + }1.2909 + break;1.2910 + case 'R':1.2911 + USED_REX (REX_MODE64);1.2912 + if (intel_syntax)1.2913 + {1.2914 + if (rex & REX_MODE64)1.2915 + {1.2916 + *obufp++ = 'q';1.2917 + *obufp++ = 't';1.2918 + }1.2919 + else if (sizeflag & DFLAG)1.2920 + {1.2921 + *obufp++ = 'd';1.2922 + *obufp++ = 'q';1.2923 + }1.2924 + else1.2925 + {1.2926 + *obufp++ = 'w';1.2927 + *obufp++ = 'd';1.2928 + }1.2929 + }1.2930 + else1.2931 + {1.2932 + if (rex & REX_MODE64)1.2933 + *obufp++ = 'q';1.2934 + else if (sizeflag & DFLAG)1.2935 + *obufp++ = 'l';1.2936 + else1.2937 + *obufp++ = 'w';1.2938 + }1.2939 + if (!(rex & REX_MODE64))1.2940 + used_prefixes |= (prefixes & PREFIX_DATA);1.2941 + break;1.2942 + case 'S':1.2943 + if (intel_syntax)1.2944 + break;1.2945 + if (sizeflag & SUFFIX_ALWAYS)1.2946 + {1.2947 + if (rex & REX_MODE64)1.2948 + *obufp++ = 'q';1.2949 + else1.2950 + {1.2951 + if (sizeflag & DFLAG)1.2952 + *obufp++ = 'l';1.2953 + else1.2954 + *obufp++ = 'w';1.2955 + used_prefixes |= (prefixes & PREFIX_DATA);1.2956 + }1.2957 + }1.2958 + break;1.2959 + case 'X':1.2960 + if (prefixes & PREFIX_DATA)1.2961 + *obufp++ = 'd';1.2962 + else1.2963 + *obufp++ = 's';1.2964 + used_prefixes |= (prefixes & PREFIX_DATA);1.2965 + break;1.2966 + case 'Y':1.2967 + if (intel_syntax)1.2968 + break;1.2969 + if (rex & REX_MODE64)1.2970 + {1.2971 + USED_REX (REX_MODE64);1.2972 + *obufp++ = 'q';1.2973 + }1.2974 + break;1.2975 + /* implicit operand size 'l' for i386 or 'q' for x86-64 */1.2976 + case 'W':1.2977 + /* operand size flag for cwtl, cbtw */1.2978 + USED_REX (0);1.2979 + if (rex)1.2980 + *obufp++ = 'l';1.2981 + else if (sizeflag & DFLAG)1.2982 + *obufp++ = 'w';1.2983 + else1.2984 + *obufp++ = 'b';1.2985 + if (intel_syntax)1.2986 + {1.2987 + if (rex)1.2988 + {1.2989 + *obufp++ = 'q';1.2990 + *obufp++ = 'e';1.2991 + }1.2992 + if (sizeflag & DFLAG)1.2993 + {1.2994 + *obufp++ = 'd';1.2995 + *obufp++ = 'e';1.2996 + }1.2997 + else1.2998 + {1.2999 + *obufp++ = 'w';1.3000 + }1.3001 + }1.3002 + if (!rex)1.3003 + used_prefixes |= (prefixes & PREFIX_DATA);1.3004 + break;1.3005 + }1.3006 + alt = 0;1.3007 + }1.3008 + *obufp = 0;1.3009 + return 0;1.3010 +}1.3011 +1.3012 +static void1.3013 +oappend (const char *s)1.3014 +{1.3015 + strcpy (obufp, s);1.3016 + obufp += strlen (s);1.3017 +}1.3018 +1.3019 +static void1.3020 +append_seg (void)1.3021 +{1.3022 + if (prefixes & PREFIX_CS)1.3023 + {1.3024 + used_prefixes |= PREFIX_CS;1.3025 + oappend ("%cs:" + intel_syntax);1.3026 + }1.3027 + if (prefixes & PREFIX_DS)1.3028 + {1.3029 + used_prefixes |= PREFIX_DS;1.3030 + oappend ("%ds:" + intel_syntax);1.3031 + }1.3032 + if (prefixes & PREFIX_SS)1.3033 + {1.3034 + used_prefixes |= PREFIX_SS;1.3035 + oappend ("%ss:" + intel_syntax);1.3036 + }1.3037 + if (prefixes & PREFIX_ES)1.3038 + {1.3039 + used_prefixes |= PREFIX_ES;1.3040 + oappend ("%es:" + intel_syntax);1.3041 + }1.3042 + if (prefixes & PREFIX_FS)1.3043 + {1.3044 + used_prefixes |= PREFIX_FS;1.3045 + oappend ("%fs:" + intel_syntax);1.3046 + }1.3047 + if (prefixes & PREFIX_GS)1.3048 + {1.3049 + used_prefixes |= PREFIX_GS;1.3050 + oappend ("%gs:" + intel_syntax);1.3051 + }1.3052 +}1.3053 +1.3054 +static void1.3055 +OP_indirE (int bytemode, int sizeflag)1.3056 +{1.3057 + if (!intel_syntax)1.3058 + oappend ("*");1.3059 + OP_E (bytemode, sizeflag);1.3060 +}1.3061 +1.3062 +static void1.3063 +print_operand_value (char *buf, int hex, bfd_vma disp)1.3064 +{1.3065 + if (mode_64bit)1.3066 + {1.3067 + if (hex)1.3068 + {1.3069 + char tmp[30];1.3070 + int i;1.3071 + buf[0] = '0';1.3072 + buf[1] = 'x';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.3076 + }1.3077 + else1.3078 + {1.3079 + bfd_signed_vma v = disp;1.3080 + char tmp[30];1.3081 + int i;1.3082 + if (v < 0)1.3083 + {1.3084 + *(buf++) = '-';1.3085 + v = -disp;1.3086 + /* Check for possible overflow on 0x8000000000000000. */1.3087 + if (v < 0)1.3088 + {1.3089 + strcpy (buf, "9223372036854775808");1.3090 + return;1.3091 + }1.3092 + }1.3093 + if (!v)1.3094 + {1.3095 + strcpy (buf, "0");1.3096 + return;1.3097 + }1.3098 +1.3099 + i = 0;1.3100 + tmp[29] = 0;1.3101 + while (v)1.3102 + {1.3103 + tmp[28 - i] = (v % 10) + '0';1.3104 + v /= 10;1.3105 + i++;1.3106 + }1.3107 + strcpy (buf, tmp + 29 - i);1.3108 + }1.3109 + }1.3110 + else1.3111 + {1.3112 + if (hex)1.3113 + sprintf (buf, "0x%x", (unsigned int) disp);1.3114 + else1.3115 + sprintf (buf, "%d", (int) disp);1.3116 + }1.3117 +}1.3118 +1.3119 +static void1.3120 +OP_E (int bytemode, int sizeflag)1.3121 +{1.3122 + bfd_vma disp;1.3123 + int add = 0;1.3124 + int riprel = 0;1.3125 + USED_REX (REX_EXTZ);1.3126 + if (rex & REX_EXTZ)1.3127 + add += 8;1.3128 +1.3129 + /* Skip mod/rm byte. */1.3130 + MODRM_CHECK;1.3131 + codep++;1.3132 +1.3133 + if (mod == 3)1.3134 + {1.3135 + switch (bytemode)1.3136 + {1.3137 + case b_mode:1.3138 + USED_REX (0);1.3139 + if (rex)1.3140 + oappend (names8rex[rm + add]);1.3141 + else1.3142 + oappend (names8[rm + add]);1.3143 + break;1.3144 + case w_mode:1.3145 + oappend (names16[rm + add]);1.3146 + break;1.3147 + case d_mode:1.3148 + oappend (names32[rm + add]);1.3149 + break;1.3150 + case q_mode:1.3151 + oappend (names64[rm + add]);1.3152 + break;1.3153 + case m_mode:1.3154 + if (mode_64bit)1.3155 + oappend (names64[rm + add]);1.3156 + else1.3157 + oappend (names32[rm + add]);1.3158 + break;1.3159 + case v_mode:1.3160 + case dq_mode:1.3161 + case dqw_mode: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.3167 + else1.3168 + oappend (names16[rm + add]);1.3169 + used_prefixes |= (prefixes & PREFIX_DATA);1.3170 + break;1.3171 + case 0:1.3172 + break;1.3173 + default:1.3174 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3175 + break;1.3176 + }1.3177 + return;1.3178 + }1.3179 +1.3180 + disp = 0;1.3181 + append_seg ();1.3182 +1.3183 + if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */1.3184 + {1.3185 + int havesib;1.3186 + int havebase;1.3187 + int base;1.3188 + int index = 0;1.3189 + int scale = 0;1.3190 +1.3191 + havesib = 0;1.3192 + havebase = 1;1.3193 + base = rm;1.3194 +1.3195 + if (base == 4)1.3196 + {1.3197 + havesib = 1;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.3203 + base = *codep & 7;1.3204 + USED_REX (REX_EXTY);1.3205 + USED_REX (REX_EXTZ);1.3206 + if (rex & REX_EXTY)1.3207 + index += 8;1.3208 + if (rex & REX_EXTZ)1.3209 + base += 8;1.3210 + codep++;1.3211 + }1.3212 +1.3213 + switch (mod)1.3214 + {1.3215 + case 0:1.3216 + if ((base & 7) == 5)1.3217 + {1.3218 + havebase = 0;1.3219 + if (mode_64bit && !havesib)1.3220 + riprel = 1;1.3221 + disp = get32s ();1.3222 + }1.3223 + break;1.3224 + case 1:1.3225 + FETCH_DATA (the_info, codep + 1);1.3226 + disp = *codep++;1.3227 + if ((disp & 0x80) != 0)1.3228 + disp -= 0x100;1.3229 + break;1.3230 + case 2:1.3231 + disp = get32s ();1.3232 + break;1.3233 + }1.3234 +1.3235 + if (!intel_syntax)1.3236 + if (mod != 0 || (base & 7) == 5)1.3237 + {1.3238 + print_operand_value (scratchbuf, !riprel, disp);1.3239 + oappend (scratchbuf);1.3240 + if (riprel)1.3241 + {1.3242 + set_op (disp, 1);1.3243 + oappend ("(%rip)");1.3244 + }1.3245 + }1.3246 +1.3247 + if (havebase || (havesib && (index != 4 || scale != 0)))1.3248 + {1.3249 + if (intel_syntax)1.3250 + {1.3251 + switch (bytemode)1.3252 + {1.3253 + case b_mode:1.3254 + oappend ("BYTE PTR ");1.3255 + break;1.3256 + case w_mode:1.3257 + case dqw_mode:1.3258 + oappend ("WORD PTR ");1.3259 + break;1.3260 + case v_mode:1.3261 + case dq_mode: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.3267 + else1.3268 + oappend ("WORD PTR ");1.3269 + used_prefixes |= (prefixes & PREFIX_DATA);1.3270 + break;1.3271 + case d_mode:1.3272 + oappend ("DWORD PTR ");1.3273 + break;1.3274 + case q_mode:1.3275 + oappend ("QWORD PTR ");1.3276 + break;1.3277 + case m_mode:1.3278 + if (mode_64bit)1.3279 + oappend ("QWORD PTR ");1.3280 + else1.3281 + oappend ("DWORD PTR ");1.3282 + break;1.3283 + case f_mode:1.3284 + if (sizeflag & DFLAG)1.3285 + {1.3286 + used_prefixes |= (prefixes & PREFIX_DATA);1.3287 + oappend ("FWORD PTR ");1.3288 + }1.3289 + else1.3290 + oappend ("DWORD PTR ");1.3291 + break;1.3292 + case t_mode:1.3293 + oappend ("TBYTE PTR ");1.3294 + break;1.3295 + case x_mode:1.3296 + oappend ("XMMWORD PTR ");1.3297 + break;1.3298 + default:1.3299 + break;1.3300 + }1.3301 + }1.3302 + *obufp++ = open_char;1.3303 + if (intel_syntax && riprel)1.3304 + oappend ("rip + ");1.3305 + *obufp = '\0';1.3306 + USED_REX (REX_EXTZ);1.3307 + if (!havesib && (rex & REX_EXTZ))1.3308 + base += 8;1.3309 + if (havebase)1.3310 + oappend (mode_64bit && (sizeflag & AFLAG)1.3311 + ? names64[base] : names32[base]);1.3312 + if (havesib)1.3313 + {1.3314 + if (index != 4)1.3315 + {1.3316 + if (!intel_syntax || havebase)1.3317 + {1.3318 + *obufp++ = separator_char;1.3319 + *obufp = '\0';1.3320 + }1.3321 + oappend (mode_64bit && (sizeflag & AFLAG)1.3322 + ? names64[index] : names32[index]);1.3323 + }1.3324 + if (scale != 0 || (!intel_syntax && index != 4))1.3325 + {1.3326 + *obufp++ = scale_char;1.3327 + *obufp = '\0';1.3328 + sprintf (scratchbuf, "%d", 1 << scale);1.3329 + oappend (scratchbuf);1.3330 + }1.3331 + }1.3332 + if (intel_syntax)1.3333 + if (mod != 0 || (base & 7) == 5)1.3334 + {1.3335 + /* Don't print zero displacements. */1.3336 + if (disp != 0)1.3337 + {1.3338 + if ((bfd_signed_vma) disp > 0)1.3339 + {1.3340 + *obufp++ = '+';1.3341 + *obufp = '\0';1.3342 + }1.3343 +1.3344 + print_operand_value (scratchbuf, 0, disp);1.3345 + oappend (scratchbuf);1.3346 + }1.3347 + }1.3348 +1.3349 + *obufp++ = close_char;1.3350 + *obufp = '\0';1.3351 + }1.3352 + else if (intel_syntax)1.3353 + {1.3354 + if (mod != 0 || (base & 7) == 5)1.3355 + {1.3356 + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS1.3357 + | PREFIX_ES | PREFIX_FS | PREFIX_GS))1.3358 + ;1.3359 + else1.3360 + {1.3361 + oappend (names_seg[ds_reg - es_reg]);1.3362 + oappend (":");1.3363 + }1.3364 + print_operand_value (scratchbuf, 1, disp);1.3365 + oappend (scratchbuf);1.3366 + }1.3367 + }1.3368 + }1.3369 + else1.3370 + { /* 16 bit address mode */1.3371 + switch (mod)1.3372 + {1.3373 + case 0:1.3374 + if ((rm & 7) == 6)1.3375 + {1.3376 + disp = get16 ();1.3377 + if ((disp & 0x8000) != 0)1.3378 + disp -= 0x10000;1.3379 + }1.3380 + break;1.3381 + case 1:1.3382 + FETCH_DATA (the_info, codep + 1);1.3383 + disp = *codep++;1.3384 + if ((disp & 0x80) != 0)1.3385 + disp -= 0x100;1.3386 + break;1.3387 + case 2:1.3388 + disp = get16 ();1.3389 + if ((disp & 0x8000) != 0)1.3390 + disp -= 0x10000;1.3391 + break;1.3392 + }1.3393 +1.3394 + if (!intel_syntax)1.3395 + if (mod != 0 || (rm & 7) == 6)1.3396 + {1.3397 + print_operand_value (scratchbuf, 0, disp);1.3398 + oappend (scratchbuf);1.3399 + }1.3400 +1.3401 + if (mod != 0 || (rm & 7) != 6)1.3402 + {1.3403 + *obufp++ = open_char;1.3404 + *obufp = '\0';1.3405 + oappend (index16[rm + add]);1.3406 + *obufp++ = close_char;1.3407 + *obufp = '\0';1.3408 + }1.3409 + }1.3410 +}1.3411 +1.3412 +static void1.3413 +OP_G (int bytemode, int sizeflag)1.3414 +{1.3415 + int add = 0;1.3416 + USED_REX (REX_EXTX);1.3417 + if (rex & REX_EXTX)1.3418 + add += 8;1.3419 + switch (bytemode)1.3420 + {1.3421 + case b_mode:1.3422 + USED_REX (0);1.3423 + if (rex)1.3424 + oappend (names8rex[reg + add]);1.3425 + else1.3426 + oappend (names8[reg + add]);1.3427 + break;1.3428 + case w_mode:1.3429 + oappend (names16[reg + add]);1.3430 + break;1.3431 + case d_mode:1.3432 + oappend (names32[reg + add]);1.3433 + break;1.3434 + case q_mode:1.3435 + oappend (names64[reg + add]);1.3436 + break;1.3437 + case v_mode:1.3438 + case dq_mode:1.3439 + case dqw_mode: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.3445 + else1.3446 + oappend (names16[reg + add]);1.3447 + used_prefixes |= (prefixes & PREFIX_DATA);1.3448 + break;1.3449 + default:1.3450 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3451 + break;1.3452 + }1.3453 +}1.3454 +1.3455 +static bfd_vma1.3456 +get64 (void)1.3457 +{1.3458 + bfd_vma x;1.3459 +#ifdef BFD641.3460 + unsigned int a;1.3461 + unsigned int b;1.3462 +1.3463 + FETCH_DATA (the_info, codep + 8);1.3464 + a = *codep++ & 0xff;1.3465 + a |= (*codep++ & 0xff) << 8;1.3466 + a |= (*codep++ & 0xff) << 16;1.3467 + a |= (*codep++ & 0xff) << 24;1.3468 + b = *codep++ & 0xff;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.3473 +#else1.3474 + abort ();1.3475 + x = 0;1.3476 +#endif1.3477 + return x;1.3478 +}1.3479 +1.3480 +static bfd_signed_vma1.3481 +get32 (void)1.3482 +{1.3483 + bfd_signed_vma x = 0;1.3484 +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.3490 + return x;1.3491 +}1.3492 +1.3493 +static bfd_signed_vma1.3494 +get32s (void)1.3495 +{1.3496 + bfd_signed_vma x = 0;1.3497 +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.3503 +1.3504 + x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);1.3505 +1.3506 + return x;1.3507 +}1.3508 +1.3509 +static int1.3510 +get16 (void)1.3511 +{1.3512 + int x = 0;1.3513 +1.3514 + FETCH_DATA (the_info, codep + 2);1.3515 + x = *codep++ & 0xff;1.3516 + x |= (*codep++ & 0xff) << 8;1.3517 + return x;1.3518 +}1.3519 +1.3520 +static void1.3521 +set_op (bfd_vma op, int riprel)1.3522 +{1.3523 + op_index[op_ad] = op_ad;1.3524 + if (mode_64bit)1.3525 + {1.3526 + op_address[op_ad] = op;1.3527 + op_riprel[op_ad] = riprel;1.3528 + }1.3529 + else1.3530 + {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.3534 + }1.3535 +}1.3536 +1.3537 +static void1.3538 +OP_REG (int code, int sizeflag)1.3539 +{1.3540 + const char *s;1.3541 + int add = 0;1.3542 + USED_REX (REX_EXTZ);1.3543 + if (rex & REX_EXTZ)1.3544 + add = 8;1.3545 +1.3546 + switch (code)1.3547 + {1.3548 + case indir_dx_reg:1.3549 + if (intel_syntax)1.3550 + s = "[dx]";1.3551 + else1.3552 + s = "(%dx)";1.3553 + break;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.3557 + break;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.3561 + break;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.3564 + USED_REX (0);1.3565 + if (rex)1.3566 + s = names8rex[code - al_reg + add];1.3567 + else1.3568 + s = names8[code - al_reg];1.3569 + break;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.3572 + if (mode_64bit)1.3573 + {1.3574 + s = names64[code - rAX_reg + add];1.3575 + break;1.3576 + }1.3577 + code += eAX_reg - rAX_reg;1.3578 + /* Fall through. */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.3586 + else1.3587 + s = names16[code - eAX_reg + add];1.3588 + used_prefixes |= (prefixes & PREFIX_DATA);1.3589 + break;1.3590 + default:1.3591 + s = INTERNAL_DISASSEMBLER_ERROR;1.3592 + break;1.3593 + }1.3594 + oappend (s);1.3595 +}1.3596 +1.3597 +static void1.3598 +OP_IMREG (int code, int sizeflag)1.3599 +{1.3600 + const char *s;1.3601 +1.3602 + switch (code)1.3603 + {1.3604 + case indir_dx_reg:1.3605 + if (intel_syntax)1.3606 + s = "[dx]";1.3607 + else1.3608 + s = "(%dx)";1.3609 + break;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.3613 + break;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.3617 + break;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.3620 + USED_REX (0);1.3621 + if (rex)1.3622 + s = names8rex[code - al_reg];1.3623 + else1.3624 + s = names8[code - al_reg];1.3625 + break;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.3633 + else1.3634 + s = names16[code - eAX_reg];1.3635 + used_prefixes |= (prefixes & PREFIX_DATA);1.3636 + break;1.3637 + default:1.3638 + s = INTERNAL_DISASSEMBLER_ERROR;1.3639 + break;1.3640 + }1.3641 + oappend (s);1.3642 +}1.3643 +1.3644 +static void1.3645 +OP_I (int bytemode, int sizeflag)1.3646 +{1.3647 + bfd_signed_vma op;1.3648 + bfd_signed_vma mask = -1;1.3649 +1.3650 + switch (bytemode)1.3651 + {1.3652 + case b_mode:1.3653 + FETCH_DATA (the_info, codep + 1);1.3654 + op = *codep++;1.3655 + mask = 0xff;1.3656 + break;1.3657 + case q_mode:1.3658 + if (mode_64bit)1.3659 + {1.3660 + op = get32s ();1.3661 + break;1.3662 + }1.3663 + /* Fall through. */1.3664 + case v_mode:1.3665 + USED_REX (REX_MODE64);1.3666 + if (rex & REX_MODE64)1.3667 + op = get32s ();1.3668 + else if (sizeflag & DFLAG)1.3669 + {1.3670 + op = get32 ();1.3671 + mask = 0xffffffff;1.3672 + }1.3673 + else1.3674 + {1.3675 + op = get16 ();1.3676 + mask = 0xfffff;1.3677 + }1.3678 + used_prefixes |= (prefixes & PREFIX_DATA);1.3679 + break;1.3680 + case w_mode:1.3681 + mask = 0xfffff;1.3682 + op = get16 ();1.3683 + break;1.3684 + case const_1_mode:1.3685 + if (intel_syntax)1.3686 + oappend ("1");1.3687 + return;1.3688 + default:1.3689 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3690 + return;1.3691 + }1.3692 +1.3693 + op &= mask;1.3694 + scratchbuf[0] = '$';1.3695 + print_operand_value (scratchbuf + 1, 1, op);1.3696 + oappend (scratchbuf + intel_syntax);1.3697 + scratchbuf[0] = '\0';1.3698 +}1.3699 +1.3700 +static void1.3701 +OP_I64 (int bytemode, int sizeflag)1.3702 +{1.3703 + bfd_signed_vma op;1.3704 + bfd_signed_vma mask = -1;1.3705 +1.3706 + if (!mode_64bit)1.3707 + {1.3708 + OP_I (bytemode, sizeflag);1.3709 + return;1.3710 + }1.3711 +1.3712 + switch (bytemode)1.3713 + {1.3714 + case b_mode:1.3715 + FETCH_DATA (the_info, codep + 1);1.3716 + op = *codep++;1.3717 + mask = 0xff;1.3718 + break;1.3719 + case v_mode:1.3720 + USED_REX (REX_MODE64);1.3721 + if (rex & REX_MODE64)1.3722 + op = get64 ();1.3723 + else if (sizeflag & DFLAG)1.3724 + {1.3725 + op = get32 ();1.3726 + mask = 0xffffffff;1.3727 + }1.3728 + else1.3729 + {1.3730 + op = get16 ();1.3731 + mask = 0xfffff;1.3732 + }1.3733 + used_prefixes |= (prefixes & PREFIX_DATA);1.3734 + break;1.3735 + case w_mode:1.3736 + mask = 0xfffff;1.3737 + op = get16 ();1.3738 + break;1.3739 + default:1.3740 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3741 + return;1.3742 + }1.3743 +1.3744 + op &= mask;1.3745 + scratchbuf[0] = '$';1.3746 + print_operand_value (scratchbuf + 1, 1, op);1.3747 + oappend (scratchbuf + intel_syntax);1.3748 + scratchbuf[0] = '\0';1.3749 +}1.3750 +1.3751 +static void1.3752 +OP_sI (int bytemode, int sizeflag)1.3753 +{1.3754 + bfd_signed_vma op;1.3755 + bfd_signed_vma mask = -1;1.3756 +1.3757 + switch (bytemode)1.3758 + {1.3759 + case b_mode:1.3760 + FETCH_DATA (the_info, codep + 1);1.3761 + op = *codep++;1.3762 + if ((op & 0x80) != 0)1.3763 + op -= 0x100;1.3764 + mask = 0xffffffff;1.3765 + break;1.3766 + case v_mode:1.3767 + USED_REX (REX_MODE64);1.3768 + if (rex & REX_MODE64)1.3769 + op = get32s ();1.3770 + else if (sizeflag & DFLAG)1.3771 + {1.3772 + op = get32s ();1.3773 + mask = 0xffffffff;1.3774 + }1.3775 + else1.3776 + {1.3777 + mask = 0xffffffff;1.3778 + op = get16 ();1.3779 + if ((op & 0x8000) != 0)1.3780 + op -= 0x10000;1.3781 + }1.3782 + used_prefixes |= (prefixes & PREFIX_DATA);1.3783 + break;1.3784 + case w_mode:1.3785 + op = get16 ();1.3786 + mask = 0xffffffff;1.3787 + if ((op & 0x8000) != 0)1.3788 + op -= 0x10000;1.3789 + break;1.3790 + default:1.3791 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3792 + return;1.3793 + }1.3794 +1.3795 + scratchbuf[0] = '$';1.3796 + print_operand_value (scratchbuf + 1, 1, op);1.3797 + oappend (scratchbuf + intel_syntax);1.3798 +}1.3799 +1.3800 +static void1.3801 +OP_J (int bytemode, int sizeflag)1.3802 +{1.3803 + bfd_vma disp;1.3804 + bfd_vma mask = -1;1.3805 +1.3806 + switch (bytemode)1.3807 + {1.3808 + case b_mode:1.3809 + FETCH_DATA (the_info, codep + 1);1.3810 + disp = *codep++;1.3811 + if ((disp & 0x80) != 0)1.3812 + disp -= 0x100;1.3813 + break;1.3814 + case v_mode:1.3815 + if (sizeflag & DFLAG)1.3816 + disp = get32s ();1.3817 + else1.3818 + {1.3819 + disp = get16 ();1.3820 + /* For some reason, a data16 prefix on a jump instruction1.3821 + means that the pc is masked to 16 bits after the1.3822 + displacement is added! */1.3823 + mask = 0xffff;1.3824 + }1.3825 + break;1.3826 + default:1.3827 + oappend (INTERNAL_DISASSEMBLER_ERROR);1.3828 + return;1.3829 + }1.3830 + disp = (start_pc + codep - start_codep + disp) & mask;1.3831 + set_op (disp, 0);1.3832 + print_operand_value (scratchbuf, 1, disp);1.3833 + oappend (scratchbuf);1.3834 +}1.3835 +1.3836 +static void1.3837 +OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.3838 +{1.3839 + oappend (names_seg[reg]);1.3840 +}1.3841 +1.3842 +static void1.3843 +OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)1.3844 +{1.3845 + int seg, offset;1.3846 +1.3847 + if (sizeflag & DFLAG)1.3848 + {1.3849 + offset = get32 ();1.3850 + seg = get16 ();1.3851 + }1.3852 + else1.3853 + {1.3854 + offset = get16 ();1.3855 + seg = get16 ();1.3856 + }1.3857 + used_prefixes |= (prefixes & PREFIX_DATA);1.3858 + if (intel_syntax)1.3859 + sprintf (scratchbuf, "0x%x,0x%x", seg, offset);1.3860 + else1.3861 + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);1.3862 + oappend (scratchbuf);1.3863 +}1.3864 +1.3865 +static void1.3866 +OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)1.3867 +{1.3868 + bfd_vma off;1.3869 +1.3870 + append_seg ();1.3871 +1.3872 + if ((sizeflag & AFLAG) || mode_64bit)1.3873 + off = get32 ();1.3874 + else1.3875 + off = get16 ();1.3876 +1.3877 + if (intel_syntax)1.3878 + {1.3879 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS1.3880 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))1.3881 + {1.3882 + oappend (names_seg[ds_reg - es_reg]);1.3883 + oappend (":");1.3884 + }1.3885 + }1.3886 + print_operand_value (scratchbuf, 1, off);1.3887 + oappend (scratchbuf);1.3888 +}1.3889 +1.3890 +static void1.3891 +OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.3892 +{1.3893 + bfd_vma off;1.3894 +1.3895 + if (!mode_64bit)1.3896 + {1.3897 + OP_OFF (bytemode, sizeflag);1.3898 + return;1.3899 + }1.3900 +1.3901 + append_seg ();1.3902 +1.3903 + off = get64 ();1.3904 +1.3905 + if (intel_syntax)1.3906 + {1.3907 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS1.3908 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))1.3909 + {1.3910 + oappend (names_seg[ds_reg - es_reg]);1.3911 + oappend (":");1.3912 + }1.3913 + }1.3914 + print_operand_value (scratchbuf, 1, off);1.3915 + oappend (scratchbuf);1.3916 +}1.3917 +1.3918 +static void1.3919 +ptr_reg (int code, int sizeflag)1.3920 +{1.3921 + const char *s;1.3922 +1.3923 + *obufp++ = open_char;1.3924 + used_prefixes |= (prefixes & PREFIX_ADDR);1.3925 + if (mode_64bit)1.3926 + {1.3927 + if (!(sizeflag & AFLAG))1.3928 + s = names32[code - eAX_reg];1.3929 + else1.3930 + s = names64[code - eAX_reg];1.3931 + }1.3932 + else if (sizeflag & AFLAG)1.3933 + s = names32[code - eAX_reg];1.3934 + else1.3935 + s = names16[code - eAX_reg];1.3936 + oappend (s);1.3937 + *obufp++ = close_char;1.3938 + *obufp = 0;1.3939 +}1.3940 +1.3941 +static void1.3942 +OP_ESreg (int code, int sizeflag)1.3943 +{1.3944 + if (intel_syntax)1.3945 + {1.3946 + if (codep[-1] & 1)1.3947 + {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.3954 + else1.3955 + oappend ("WORD PTR ");1.3956 + }1.3957 + else1.3958 + oappend ("BYTE PTR ");1.3959 + }1.3960 +1.3961 + oappend ("%es:" + intel_syntax);1.3962 + ptr_reg (code, sizeflag);1.3963 +}1.3964 +1.3965 +static void1.3966 +OP_DSreg (int code, int sizeflag)1.3967 +{1.3968 + if (intel_syntax)1.3969 + {1.3970 + if (codep[-1] != 0xd7 && (codep[-1] & 1))1.3971 + {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.3978 + else1.3979 + oappend ("WORD PTR ");1.3980 + }1.3981 + else1.3982 + oappend ("BYTE PTR ");1.3983 + }1.3984 +1.3985 + if ((prefixes1.3986 + & (PREFIX_CS1.3987 + | PREFIX_DS1.3988 + | PREFIX_SS1.3989 + | PREFIX_ES1.3990 + | PREFIX_FS1.3991 + | PREFIX_GS)) == 0)1.3992 + prefixes |= PREFIX_DS;1.3993 + append_seg ();1.3994 + ptr_reg (code, sizeflag);1.3995 +}1.3996 +1.3997 +static void1.3998 +OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.3999 +{1.4000 + int add = 0;1.4001 + if (rex & REX_EXTX)1.4002 + {1.4003 + USED_REX (REX_EXTX);1.4004 + add = 8;1.4005 + }1.4006 + else if (!mode_64bit && (prefixes & PREFIX_LOCK))1.4007 + {1.4008 + used_prefixes |= PREFIX_LOCK;1.4009 + add = 8;1.4010 + }1.4011 + sprintf (scratchbuf, "%%cr%d", reg + add);1.4012 + oappend (scratchbuf + intel_syntax);1.4013 +}1.4014 +1.4015 +static void1.4016 +OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4017 +{1.4018 + int add = 0;1.4019 + USED_REX (REX_EXTX);1.4020 + if (rex & REX_EXTX)1.4021 + add = 8;1.4022 + if (intel_syntax)1.4023 + sprintf (scratchbuf, "db%d", reg + add);1.4024 + else1.4025 + sprintf (scratchbuf, "%%db%d", reg + add);1.4026 + oappend (scratchbuf);1.4027 +}1.4028 +1.4029 +static void1.4030 +OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4031 +{1.4032 + sprintf (scratchbuf, "%%tr%d", reg);1.4033 + oappend (scratchbuf + intel_syntax);1.4034 +}1.4035 +1.4036 +static void1.4037 +OP_Rd (int bytemode, int sizeflag)1.4038 +{1.4039 + if (mod == 3)1.4040 + OP_E (bytemode, sizeflag);1.4041 + else1.4042 + BadOp ();1.4043 +}1.4044 +1.4045 +static void1.4046 +OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4047 +{1.4048 + used_prefixes |= (prefixes & PREFIX_DATA);1.4049 + if (prefixes & PREFIX_DATA)1.4050 + {1.4051 + int add = 0;1.4052 + USED_REX (REX_EXTX);1.4053 + if (rex & REX_EXTX)1.4054 + add = 8;1.4055 + sprintf (scratchbuf, "%%xmm%d", reg + add);1.4056 + }1.4057 + else1.4058 + sprintf (scratchbuf, "%%mm%d", reg);1.4059 + oappend (scratchbuf + intel_syntax);1.4060 +}1.4061 +1.4062 +static void1.4063 +OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4064 +{1.4065 + int add = 0;1.4066 + USED_REX (REX_EXTX);1.4067 + if (rex & REX_EXTX)1.4068 + add = 8;1.4069 + sprintf (scratchbuf, "%%xmm%d", reg + add);1.4070 + oappend (scratchbuf + intel_syntax);1.4071 +}1.4072 +1.4073 +static void1.4074 +OP_EM (int bytemode, int sizeflag)1.4075 +{1.4076 + if (mod != 3)1.4077 + {1.4078 + if (intel_syntax && bytemode == v_mode)1.4079 + {1.4080 + bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;1.4081 + used_prefixes |= (prefixes & PREFIX_DATA);1.4082 + }1.4083 + OP_E (bytemode, sizeflag);1.4084 + return;1.4085 + }1.4086 +1.4087 + /* Skip mod/rm byte. */1.4088 + MODRM_CHECK;1.4089 + codep++;1.4090 + used_prefixes |= (prefixes & PREFIX_DATA);1.4091 + if (prefixes & PREFIX_DATA)1.4092 + {1.4093 + int add = 0;1.4094 +1.4095 + USED_REX (REX_EXTZ);1.4096 + if (rex & REX_EXTZ)1.4097 + add = 8;1.4098 + sprintf (scratchbuf, "%%xmm%d", rm + add);1.4099 + }1.4100 + else1.4101 + sprintf (scratchbuf, "%%mm%d", rm);1.4102 + oappend (scratchbuf + intel_syntax);1.4103 +}1.4104 +1.4105 +static void1.4106 +OP_EX (int bytemode, int sizeflag)1.4107 +{1.4108 + int add = 0;1.4109 + if (mod != 3)1.4110 + {1.4111 + if (intel_syntax && bytemode == v_mode)1.4112 + {1.4113 + switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))1.4114 + {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.4120 + }1.4121 + }1.4122 + OP_E (bytemode, sizeflag);1.4123 + return;1.4124 + }1.4125 + USED_REX (REX_EXTZ);1.4126 + if (rex & REX_EXTZ)1.4127 + add = 8;1.4128 +1.4129 + /* Skip mod/rm byte. */1.4130 + MODRM_CHECK;1.4131 + codep++;1.4132 + sprintf (scratchbuf, "%%xmm%d", rm + add);1.4133 + oappend (scratchbuf + intel_syntax);1.4134 +}1.4135 +1.4136 +static void1.4137 +OP_MS (int bytemode, int sizeflag)1.4138 +{1.4139 + if (mod == 3)1.4140 + OP_EM (bytemode, sizeflag);1.4141 + else1.4142 + BadOp ();1.4143 +}1.4144 +1.4145 +static void1.4146 +OP_XS (int bytemode, int sizeflag)1.4147 +{1.4148 + if (mod == 3)1.4149 + OP_EX (bytemode, sizeflag);1.4150 + else1.4151 + BadOp ();1.4152 +}1.4153 +1.4154 +static void1.4155 +OP_M (int bytemode, int sizeflag)1.4156 +{1.4157 + if (mod == 3)1.4158 + BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */1.4159 + else1.4160 + OP_E (bytemode, sizeflag);1.4161 +}1.4162 +1.4163 +static void1.4164 +OP_0f07 (int bytemode, int sizeflag)1.4165 +{1.4166 + if (mod != 3 || rm != 0)1.4167 + BadOp ();1.4168 + else1.4169 + OP_E (bytemode, sizeflag);1.4170 +}1.4171 +1.4172 +static void1.4173 +OP_0fae (int bytemode, int sizeflag)1.4174 +{1.4175 + if (mod == 3)1.4176 + {1.4177 + if (reg == 7)1.4178 + strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");1.4179 +1.4180 + if (reg < 5 || rm != 0)1.4181 + {1.4182 + BadOp (); /* bad sfence, mfence, or lfence */1.4183 + return;1.4184 + }1.4185 + }1.4186 + else if (reg != 7)1.4187 + {1.4188 + BadOp (); /* bad clflush */1.4189 + return;1.4190 + }1.4191 +1.4192 + OP_E (bytemode, sizeflag);1.4193 +}1.4194 +1.4195 +static void1.4196 +NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4197 +{1.4198 + /* NOP with REPZ prefix is called PAUSE. */1.4199 + if (prefixes == PREFIX_REPZ)1.4200 + strcpy (obuf, "pause");1.4201 +}1.4202 +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.4268 +};1.4269 +1.4270 +static void1.4271 +OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4272 +{1.4273 + const char *mnemonic;1.4274 +1.4275 + FETCH_DATA (the_info, codep + 1);1.4276 + /* AMD 3DNow! instructions are specified by an opcode suffix in the1.4277 + place where an 8-bit immediate would normally go. ie. the last1.4278 + byte of the instruction. */1.4279 + obufp = obuf + strlen (obuf);1.4280 + mnemonic = Suffix3DNow[*codep++ & 0xff];1.4281 + if (mnemonic)1.4282 + oappend (mnemonic);1.4283 + else1.4284 + {1.4285 + /* Since a variable sized modrm/sib chunk is between the start1.4286 + of the opcode (0x0f0f) and the opcode suffix, we need to do1.4287 + all the modrm processing first, and don't know until now that1.4288 + we have a bad opcode. This necessitates some cleaning up. */1.4289 + op1out[0] = '\0';1.4290 + op2out[0] = '\0';1.4291 + BadOp ();1.4292 + }1.4293 +}1.4294 +1.4295 +static const char *simd_cmp_op[] = {1.4296 + "eq",1.4297 + "lt",1.4298 + "le",1.4299 + "unord",1.4300 + "neq",1.4301 + "nlt",1.4302 + "nle",1.4303 + "ord"1.4304 +};1.4305 +1.4306 +static void1.4307 +OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)1.4308 +{1.4309 + unsigned int cmp_type;1.4310 +1.4311 + FETCH_DATA (the_info, codep + 1);1.4312 + obufp = obuf + strlen (obuf);1.4313 + cmp_type = *codep++ & 0xff;1.4314 + if (cmp_type < 8)1.4315 + {1.4316 + char suffix1 = 'p', suffix2 = 's';1.4317 + used_prefixes |= (prefixes & PREFIX_REPZ);1.4318 + if (prefixes & PREFIX_REPZ)1.4319 + suffix1 = 's';1.4320 + else1.4321 + {1.4322 + used_prefixes |= (prefixes & PREFIX_DATA);1.4323 + if (prefixes & PREFIX_DATA)1.4324 + suffix2 = 'd';1.4325 + else1.4326 + {1.4327 + used_prefixes |= (prefixes & PREFIX_REPNZ);1.4328 + if (prefixes & PREFIX_REPNZ)1.4329 + suffix1 = 's', suffix2 = 'd';1.4330 + }1.4331 + }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.4336 + }1.4337 + else1.4338 + {1.4339 + /* We have a bad extension byte. Clean up. */1.4340 + op1out[0] = '\0';1.4341 + op2out[0] = '\0';1.4342 + BadOp ();1.4343 + }1.4344 +}1.4345 +1.4346 +static void1.4347 +SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)1.4348 +{1.4349 + /* Change movlps/movhps to movhlps/movlhps for 2 register operand1.4350 + forms of these instructions. */1.4351 + if (mod == 3)1.4352 + {1.4353 + char *p = obuf + strlen (obuf);1.4354 + *(p + 1) = '\0';1.4355 + *p = *(p - 1);1.4356 + *(p - 1) = *(p - 2);1.4357 + *(p - 2) = *(p - 3);1.4358 + *(p - 3) = extrachar;1.4359 + }1.4360 +}1.4361 +1.4362 +static void1.4363 +PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)1.4364 +{1.4365 + if (mod == 3 && reg == 1 && rm <= 1)1.4366 + {1.4367 + /* Override "sidt". */1.4368 + char *p = obuf + strlen (obuf) - 4;1.4369 +1.4370 + /* We might have a suffix. */1.4371 + if (*p == 'i')1.4372 + --p;1.4373 +1.4374 + if (rm)1.4375 + {1.4376 + /* mwait %eax,%ecx */1.4377 + strcpy (p, "mwait");1.4378 + if (!intel_syntax)1.4379 + strcpy (op1out, names32[0]);1.4380 + }1.4381 + else1.4382 + {1.4383 + /* monitor %eax,%ecx,%edx" */1.4384 + strcpy (p, "monitor");1.4385 + if (!intel_syntax)1.4386 + {1.4387 + if (!mode_64bit)1.4388 + strcpy (op1out, names32[0]);1.4389 + else if (!(prefixes & PREFIX_ADDR))1.4390 + strcpy (op1out, names64[0]);1.4391 + else1.4392 + {1.4393 + strcpy (op1out, names32[0]);1.4394 + used_prefixes |= PREFIX_ADDR;1.4395 + }1.4396 + strcpy (op3out, names32[2]);1.4397 + }1.4398 + }1.4399 + if (!intel_syntax)1.4400 + {1.4401 + strcpy (op2out, names32[1]);1.4402 + two_source_ops = 1;1.4403 + }1.4404 +1.4405 + codep++;1.4406 + }1.4407 + else1.4408 + OP_E (0, sizeflag);1.4409 +}1.4410 +1.4411 +static void1.4412 +INVLPG_Fixup (int bytemode, int sizeflag)1.4413 +{1.4414 + const char *alt;1.4415 +1.4416 + switch (*codep)1.4417 + {1.4418 + case 0xf8:1.4419 + alt = "swapgs";1.4420 + break;1.4421 + case 0xf9:1.4422 + alt = "rdtscp";1.4423 + break;1.4424 + default:1.4425 + OP_E (bytemode, sizeflag);1.4426 + return;1.4427 + }1.4428 + /* Override "invlpg". */1.4429 + strcpy (obuf + strlen (obuf) - 6, alt);1.4430 + codep++;1.4431 +}1.4432 +1.4433 +static void1.4434 +BadOp (void)1.4435 +{1.4436 + /* Throw away prefixes and 1st. opcode byte. */1.4437 + codep = insn_codep + 1;1.4438 + oappend ("(bad)");1.4439 +}
.