1/* Print i386 instructions for GDB, the GNU debugger. 2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 23/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) 24 July 1988 25 modified by John Hassey (hassey@dg-rtp.dg.com) 26 x86-64 support added by Jan Hubicka (jh@suse.cz) 27 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */ 28 29/* The main tables describing the instructions is essentially a copy 30 of the "Opcode Map" chapter (Appendix A) of the Intel 80386 31 Programmers Manual. Usually, there is a capital letter, followed 32 by a small letter. The capital letter tell the addressing mode, 33 and the small letter tells about the operand size. Refer to 34 the Intel manual for details. */ 35 36#include "sysdep.h" 37#include "dis-asm.h" 38#include "opintl.h" 39#include "opcode/i386.h" 40 41#include <setjmp.h> 42 43static int fetch_data (struct disassemble_info *, bfd_byte *); 44static void ckprefix (void); 45static const char *prefix_name (int, int); 46static int print_insn (bfd_vma, disassemble_info *); 47static void dofloat (int); 48static void OP_ST (int, int); 49static void OP_STi (int, int); 50static int putop (const char *, int); 51static void oappend (const char *); 52static void append_seg (void); 53static void OP_indirE (int, int); 54static void print_operand_value (char *, int, bfd_vma); 55static void print_displacement (char *, bfd_vma); 56static void OP_E (int, int); 57static void OP_G (int, int); 58static bfd_vma get64 (void); 59static bfd_signed_vma get32 (void); 60static bfd_signed_vma get32s (void); 61static int get16 (void); 62static void set_op (bfd_vma, int); 63static void OP_Skip_MODRM (int, int); 64static void OP_REG (int, int); 65static void OP_IMREG (int, int); 66static void OP_I (int, int); 67static void OP_I64 (int, int); 68static void OP_sI (int, int); 69static void OP_J (int, int); 70static void OP_SEG (int, int); 71static void OP_DIR (int, int); 72static void OP_OFF (int, int); 73static void OP_OFF64 (int, int); 74static void ptr_reg (int, int); 75static void OP_ESreg (int, int); 76static void OP_DSreg (int, int); 77static void OP_C (int, int); 78static void OP_D (int, int); 79static void OP_T (int, int); 80static void OP_R (int, int); 81static void OP_MMX (int, int); 82static void OP_XMM (int, int); 83static void OP_EM (int, int); 84static void OP_EX (int, int); 85static void OP_EMC (int,int); 86static void OP_MXC (int,int); 87static void OP_MS (int, int); 88static void OP_XS (int, int); 89static void OP_M (int, int); 90static void OP_0f07 (int, int); 91static void OP_Monitor (int, int); 92static void OP_Mwait (int, int); 93static void NOP_Fixup1 (int, int); 94static void NOP_Fixup2 (int, int); 95static void OP_3DNowSuffix (int, int); 96static void OP_SIMD_Suffix (int, int); 97static void BadOp (void); 98static void REP_Fixup (int, int); 99static void CMPXCHG8B_Fixup (int, int); 100static void XMM_Fixup (int, int); 101static void CRC32_Fixup (int, int); 102 103struct dis_private { 104 /* Points to first byte not fetched. */ 105 bfd_byte *max_fetched; 106 bfd_byte the_buffer[MAX_MNEM_SIZE]; 107 bfd_vma insn_start; 108 int orig_sizeflag; 109 jmp_buf bailout; 110}; 111 112enum address_mode 113{ 114 mode_16bit, 115 mode_32bit, 116 mode_64bit 117}; 118 119enum address_mode address_mode; 120 121/* Flags for the prefixes for the current instruction. See below. */ 122static int prefixes; 123 124/* REX prefix the current instruction. See below. */ 125static int rex; 126/* Bits of REX we've already used. */ 127static int rex_used; 128/* Mark parts used in the REX prefix. When we are testing for 129 empty prefix (for 8bit register REX extension), just mask it 130 out. Otherwise test for REX bit is excuse for existence of REX 131 only in case value is nonzero. */ 132#define USED_REX(value) \ 133 { \ 134 if (value) \ 135 { \ 136 if ((rex & value)) \ 137 rex_used |= (value) | REX_OPCODE; \ 138 } \ 139 else \ 140 rex_used |= REX_OPCODE; \ 141 } 142 143/* Flags for prefixes which we somehow handled when printing the 144 current instruction. */ 145static int used_prefixes; 146 147/* Flags stored in PREFIXES. */ 148#define PREFIX_REPZ 1 149#define PREFIX_REPNZ 2 150#define PREFIX_LOCK 4 151#define PREFIX_CS 8 152#define PREFIX_SS 0x10 153#define PREFIX_DS 0x20 154#define PREFIX_ES 0x40 155#define PREFIX_FS 0x80 156#define PREFIX_GS 0x100 157#define PREFIX_DATA 0x200 158#define PREFIX_ADDR 0x400 159#define PREFIX_FWAIT 0x800 160 161/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 162 to ADDR (exclusive) are valid. Returns 1 for success, longjmps 163 on error. */ 164#define FETCH_DATA(info, addr) \ 165 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \ 166 ? 1 : fetch_data ((info), (addr))) 167 168static int 169fetch_data (struct disassemble_info *info, bfd_byte *addr) 170{ 171 int status; 172 struct dis_private *priv = (struct dis_private *) info->private_data; 173 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); 174 175 if (addr <= priv->the_buffer + MAX_MNEM_SIZE) 176 status = (*info->read_memory_func) (start, 177 priv->max_fetched, 178 addr - priv->max_fetched, 179 info); 180 else 181 status = -1; 182 if (status != 0) 183 { 184 /* If we did manage to read at least one byte, then 185 print_insn_i386 will do something sensible. Otherwise, print 186 an error. We do that here because this is where we know 187 STATUS. */ 188 if (priv->max_fetched == priv->the_buffer) 189 (*info->memory_error_func) (status, start, info); 190 longjmp (priv->bailout, 1); 191 } 192 else 193 priv->max_fetched = addr; 194 return 1; 195} 196 197#define XX { NULL, 0 } 198 199#define Eb { OP_E, b_mode } 200#define Ev { OP_E, v_mode } 201#define Ed { OP_E, d_mode } 202#define Edq { OP_E, dq_mode } 203#define Edqw { OP_E, dqw_mode } 204#define Edqb { OP_E, dqb_mode } 205#define Edqd { OP_E, dqd_mode } 206#define Eq { OP_E, q_mode } 207#define indirEv { OP_indirE, stack_v_mode } 208#define indirEp { OP_indirE, f_mode } 209#define stackEv { OP_E, stack_v_mode } 210#define Em { OP_E, m_mode } 211#define Ew { OP_E, w_mode } 212#define M { OP_M, 0 } /* lea, lgdt, etc. */ 213#define Ma { OP_M, v_mode } 214#define Mb { OP_M, b_mode } 215#define Md { OP_M, d_mode } 216#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */ 217#define Mq { OP_M, q_mode } 218#define Gb { OP_G, b_mode } 219#define Gv { OP_G, v_mode } 220#define Gd { OP_G, d_mode } 221#define Gdq { OP_G, dq_mode } 222#define Gm { OP_G, m_mode } 223#define Gw { OP_G, w_mode } 224#define Rd { OP_R, d_mode } 225#define Rm { OP_R, m_mode } 226#define Ib { OP_I, b_mode } 227#define sIb { OP_sI, b_mode } /* sign extened byte */ 228#define Iv { OP_I, v_mode } 229#define Iq { OP_I, q_mode } 230#define Iv64 { OP_I64, v_mode } 231#define Iw { OP_I, w_mode } 232#define I1 { OP_I, const_1_mode } 233#define Jb { OP_J, b_mode } 234#define Jv { OP_J, v_mode } 235#define Cm { OP_C, m_mode } 236#define Dm { OP_D, m_mode } 237#define Td { OP_T, d_mode } 238#define Skip_MODRM { OP_Skip_MODRM, 0 } 239 240#define RMeAX { OP_REG, eAX_reg } 241#define RMeBX { OP_REG, eBX_reg } 242#define RMeCX { OP_REG, eCX_reg } 243#define RMeDX { OP_REG, eDX_reg } 244#define RMeSP { OP_REG, eSP_reg } 245#define RMeBP { OP_REG, eBP_reg } 246#define RMeSI { OP_REG, eSI_reg } 247#define RMeDI { OP_REG, eDI_reg } 248#define RMrAX { OP_REG, rAX_reg } 249#define RMrBX { OP_REG, rBX_reg } 250#define RMrCX { OP_REG, rCX_reg } 251#define RMrDX { OP_REG, rDX_reg } 252#define RMrSP { OP_REG, rSP_reg } 253#define RMrBP { OP_REG, rBP_reg } 254#define RMrSI { OP_REG, rSI_reg } 255#define RMrDI { OP_REG, rDI_reg } 256#define RMAL { OP_REG, al_reg } 257#define RMAL { OP_REG, al_reg } 258#define RMCL { OP_REG, cl_reg } 259#define RMDL { OP_REG, dl_reg } 260#define RMBL { OP_REG, bl_reg } 261#define RMAH { OP_REG, ah_reg } 262#define RMCH { OP_REG, ch_reg } 263#define RMDH { OP_REG, dh_reg } 264#define RMBH { OP_REG, bh_reg } 265#define RMAX { OP_REG, ax_reg } 266#define RMDX { OP_REG, dx_reg } 267 268#define eAX { OP_IMREG, eAX_reg } 269#define eBX { OP_IMREG, eBX_reg } 270#define eCX { OP_IMREG, eCX_reg } 271#define eDX { OP_IMREG, eDX_reg } 272#define eSP { OP_IMREG, eSP_reg } 273#define eBP { OP_IMREG, eBP_reg } 274#define eSI { OP_IMREG, eSI_reg } 275#define eDI { OP_IMREG, eDI_reg } 276#define AL { OP_IMREG, al_reg } 277#define CL { OP_IMREG, cl_reg } 278#define DL { OP_IMREG, dl_reg } 279#define BL { OP_IMREG, bl_reg } 280#define AH { OP_IMREG, ah_reg } 281#define CH { OP_IMREG, ch_reg } 282#define DH { OP_IMREG, dh_reg } 283#define BH { OP_IMREG, bh_reg } 284#define AX { OP_IMREG, ax_reg } 285#define DX { OP_IMREG, dx_reg } 286#define zAX { OP_IMREG, z_mode_ax_reg } 287#define indirDX { OP_IMREG, indir_dx_reg } 288 289#define Sw { OP_SEG, w_mode } 290#define Sv { OP_SEG, v_mode } 291#define Ap { OP_DIR, 0 } 292#define Ob { OP_OFF64, b_mode } 293#define Ov { OP_OFF64, v_mode } 294#define Xb { OP_DSreg, eSI_reg } 295#define Xv { OP_DSreg, eSI_reg } 296#define Xz { OP_DSreg, eSI_reg } 297#define Yb { OP_ESreg, eDI_reg } 298#define Yv { OP_ESreg, eDI_reg } 299#define DSBX { OP_DSreg, eBX_reg } 300 301#define es { OP_REG, es_reg } 302#define ss { OP_REG, ss_reg } 303#define cs { OP_REG, cs_reg } 304#define ds { OP_REG, ds_reg } 305#define fs { OP_REG, fs_reg } 306#define gs { OP_REG, gs_reg } 307 308#define MX { OP_MMX, 0 } 309#define XM { OP_XMM, 0 } 310#define EM { OP_EM, v_mode } 311#define EMd { OP_EM, d_mode } 312#define EMx { OP_EM, x_mode } 313#define EXw { OP_EX, w_mode } 314#define EXd { OP_EX, d_mode } 315#define EXq { OP_EX, q_mode } 316#define EXx { OP_EX, x_mode } 317#define MS { OP_MS, v_mode } 318#define XS { OP_XS, v_mode } 319#define EMCq { OP_EMC, q_mode } 320#define MXC { OP_MXC, 0 } 321#define OPSUF { OP_3DNowSuffix, 0 } 322#define OPSIMD { OP_SIMD_Suffix, 0 } 323#define XMM0 { XMM_Fixup, 0 } 324 325/* Used handle "rep" prefix for string instructions. */ 326#define Xbr { REP_Fixup, eSI_reg } 327#define Xvr { REP_Fixup, eSI_reg } 328#define Ybr { REP_Fixup, eDI_reg } 329#define Yvr { REP_Fixup, eDI_reg } 330#define Yzr { REP_Fixup, eDI_reg } 331#define indirDXr { REP_Fixup, indir_dx_reg } 332#define ALr { REP_Fixup, al_reg } 333#define eAXr { REP_Fixup, eAX_reg } 334 335#define cond_jump_flag { NULL, cond_jump_mode } 336#define loop_jcxz_flag { NULL, loop_jcxz_mode } 337 338/* bits in sizeflag */ 339#define SUFFIX_ALWAYS 4 340#define AFLAG 2 341#define DFLAG 1 342 343#define b_mode 1 /* byte operand */ 344#define v_mode 2 /* operand size depends on prefixes */ 345#define w_mode 3 /* word operand */ 346#define d_mode 4 /* double word operand */ 347#define q_mode 5 /* quad word operand */ 348#define t_mode 6 /* ten-byte operand */ 349#define x_mode 7 /* 16-byte XMM operand */ 350#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */ 351#define cond_jump_mode 9 352#define loop_jcxz_mode 10 353#define dq_mode 11 /* operand size depends on REX prefixes. */ 354#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */ 355#define f_mode 13 /* 4- or 6-byte pointer operand */ 356#define const_1_mode 14 357#define stack_v_mode 15 /* v_mode for stack-related opcodes. */ 358#define z_mode 16 /* non-quad operand size depends on prefixes */ 359#define o_mode 17 /* 16-byte operand */ 360#define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */ 361#define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */ 362 363#define es_reg 100 364#define cs_reg 101 365#define ss_reg 102 366#define ds_reg 103 367#define fs_reg 104 368#define gs_reg 105 369 370#define eAX_reg 108 371#define eCX_reg 109 372#define eDX_reg 110 373#define eBX_reg 111 374#define eSP_reg 112 375#define eBP_reg 113 376#define eSI_reg 114 377#define eDI_reg 115 378 379#define al_reg 116 380#define cl_reg 117 381#define dl_reg 118 382#define bl_reg 119 383#define ah_reg 120 384#define ch_reg 121 385#define dh_reg 122 386#define bh_reg 123 387 388#define ax_reg 124 389#define cx_reg 125 390#define dx_reg 126 391#define bx_reg 127 392#define sp_reg 128 393#define bp_reg 129 394#define si_reg 130 395#define di_reg 131 396 397#define rAX_reg 132 398#define rCX_reg 133 399#define rDX_reg 134 400#define rBX_reg 135 401#define rSP_reg 136 402#define rBP_reg 137 403#define rSI_reg 138 404#define rDI_reg 139 405 406#define z_mode_ax_reg 149 407#define indir_dx_reg 150 408 409#define FLOATCODE 1 410#define USE_GROUPS 2 411#define USE_PREFIX_USER_TABLE 3 412#define X86_64_SPECIAL 4 413#define IS_3BYTE_OPCODE 5 414#define USE_OPC_EXT_TABLE 6 415#define USE_OPC_EXT_RM_TABLE 7 416 417#define FLOAT NULL, { { NULL, FLOATCODE } } 418 419#define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } } 420#define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } } 421#define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } } 422#define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } } 423#define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } } 424#define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } } 425#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } } 426#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } } 427#define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } } 428#define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } } 429#define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } } 430#define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } } 431#define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } } 432#define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } } 433#define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } } 434#define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } } 435#define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } } 436#define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } } 437#define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } } 438#define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } } 439#define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } } 440#define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } } 441#define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } } 442#define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } } 443#define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } } 444#define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } } 445#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } } 446#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } } 447 448#define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } } 449#define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } } 450#define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } } 451#define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } } 452#define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } } 453#define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } } 454#define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } } 455#define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } } 456#define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } } 457#define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } } 458#define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } } 459#define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } } 460#define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } } 461#define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } } 462#define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } } 463#define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } } 464#define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } } 465#define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } } 466#define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } } 467#define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } } 468#define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } } 469#define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } } 470#define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } } 471#define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } } 472#define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } } 473#define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } } 474#define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } } 475#define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } } 476#define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } } 477#define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } } 478#define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } } 479#define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } } 480#define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } } 481#define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } } 482#define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } } 483#define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } } 484#define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } } 485#define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } } 486#define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } } 487#define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } } 488#define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } } 489#define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } } 490#define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } } 491#define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } } 492#define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } } 493#define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } } 494#define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } } 495#define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } } 496#define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } } 497#define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } } 498#define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } } 499#define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } } 500#define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } } 501#define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } } 502#define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } } 503#define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } } 504#define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } } 505#define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } } 506#define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } } 507#define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } } 508#define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } } 509#define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } } 510#define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } } 511#define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } } 512#define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } } 513#define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } } 514#define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } } 515#define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } } 516#define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } } 517#define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } } 518#define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } } 519#define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } } 520#define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } } 521#define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } } 522#define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } } 523#define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } } 524#define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } } 525#define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } } 526#define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } } 527#define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } } 528#define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } } 529#define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } } 530#define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } } 531#define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } } 532#define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } } 533#define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } } 534#define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } } 535#define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } } 536#define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } } 537#define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } } 538#define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } } 539#define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } } 540#define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } } 541#define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } } 542#define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } } 543#define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } } 544#define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } } 545#define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } } 546#define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } } 547#define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } } 548#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } } 549 550 551#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } } 552#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } } 553#define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } } 554#define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } } 555 556#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } } 557#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } } 558 559#define OPC_EXT_0 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } } 560#define OPC_EXT_1 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } } 561#define OPC_EXT_2 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 2 } } 562#define OPC_EXT_3 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 3 } } 563#define OPC_EXT_4 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 4 } } 564#define OPC_EXT_5 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 5 } } 565#define OPC_EXT_6 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 6 } } 566#define OPC_EXT_7 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 7 } } 567#define OPC_EXT_8 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 8 } } 568#define OPC_EXT_9 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 9 } } 569#define OPC_EXT_10 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 10 } } 570#define OPC_EXT_11 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 11 } } 571#define OPC_EXT_12 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 12 } } 572#define OPC_EXT_13 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 13 } } 573#define OPC_EXT_14 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 14 } } 574#define OPC_EXT_15 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 15 } } 575#define OPC_EXT_16 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 16 } } 576#define OPC_EXT_17 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 17 } } 577#define OPC_EXT_18 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 18 } } 578#define OPC_EXT_19 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 19 } } 579#define OPC_EXT_20 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 20 } } 580#define OPC_EXT_21 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 21 } } 581#define OPC_EXT_22 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 22 } } 582#define OPC_EXT_23 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 23 } } 583#define OPC_EXT_24 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 24 } } 584#define OPC_EXT_25 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 25 } } 585#define OPC_EXT_26 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 26 } } 586#define OPC_EXT_27 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 27 } } 587#define OPC_EXT_28 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 28 } } 588#define OPC_EXT_29 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 29 } } 589#define OPC_EXT_30 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 30 } } 590#define OPC_EXT_31 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 31 } } 591#define OPC_EXT_32 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 32 } } 592#define OPC_EXT_33 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 33 } } 593#define OPC_EXT_34 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 34 } } 594#define OPC_EXT_35 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 35 } } 595#define OPC_EXT_36 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 36 } } 596#define OPC_EXT_37 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 37 } } 597#define OPC_EXT_38 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 38 } } 598#define OPC_EXT_39 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 39 } } 599#define OPC_EXT_40 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 40 } } 600#define OPC_EXT_41 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 41 } } 601#define OPC_EXT_42 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 42 } } 602#define OPC_EXT_43 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 43 } } 603#define OPC_EXT_44 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 44 } } 604#define OPC_EXT_45 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 45 } } 605 606#define OPC_EXT_RM_0 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } } 607#define OPC_EXT_RM_1 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } } 608#define OPC_EXT_RM_2 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 2 } } 609#define OPC_EXT_RM_3 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } } 610#define OPC_EXT_RM_4 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } } 611#define OPC_EXT_RM_5 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 5 } } 612#define OPC_EXT_RM_6 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 6 } } 613 614typedef void (*op_rtn) (int bytemode, int sizeflag); 615 616struct dis386 { 617 const char *name; 618 struct 619 { 620 op_rtn rtn; 621 int bytemode; 622 } op[MAX_OPERANDS]; 623}; 624 625/* Upper case letters in the instruction names here are macros. 626 'A' => print 'b' if no register operands or suffix_always is true 627 'B' => print 'b' if suffix_always is true 628 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand 629 . size prefix 630 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if 631 . suffix_always is true 632 'E' => print 'e' if 32-bit form of jcxz 633 'F' => print 'w' or 'l' depending on address size prefix (loop insns) 634 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns) 635 'H' => print ",pt" or ",pn" branch hint 636 'I' => honor following macro letter even in Intel mode (implemented only 637 . for some of the macro letters) 638 'J' => print 'l' 639 'K' => print 'd' or 'q' if rex prefix is present. 640 'L' => print 'l' if suffix_always is true 641 'N' => print 'n' if instruction has no wait "prefix" 642 'O' => print 'd' or 'o' (or 'q' in Intel mode) 643 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix, 644 . or suffix_always is true. print 'q' if rex prefix is present. 645 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always 646 . is true 647 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode) 648 'S' => print 'w', 'l' or 'q' if suffix_always is true 649 'T' => print 'q' in 64bit mode and behave as 'P' otherwise 650 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise 651 'V' => print 'q' in 64bit mode and behave as 'S' otherwise 652 'W' => print 'b', 'w' or 'l' ('d' in Intel mode) 653 'X' => print 's', 'd' depending on data16 prefix (for XMM) 654 'Y' => 'q' if instruction has an REX 64bit overwrite prefix 655 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise 656 657 Many of the above letters print nothing in Intel mode. See "putop" 658 for the details. 659 660 Braces '{' and '}', and vertical bars '|', indicate alternative 661 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel 662 modes. In cases where there are only two alternatives, the X86_64 663 instruction is reserved, and "(bad)" is printed. 664*/ 665 666static const struct dis386 dis386[] = { 667 /* 00 */ 668 { "addB", { Eb, Gb } }, 669 { "addS", { Ev, Gv } }, 670 { "addB", { Gb, Eb } }, 671 { "addS", { Gv, Ev } }, 672 { "addB", { AL, Ib } }, 673 { "addS", { eAX, Iv } }, 674 { "push{T|}", { es } }, 675 { "pop{T|}", { es } }, 676 /* 08 */ 677 { "orB", { Eb, Gb } }, 678 { "orS", { Ev, Gv } }, 679 { "orB", { Gb, Eb } }, 680 { "orS", { Gv, Ev } }, 681 { "orB", { AL, Ib } }, 682 { "orS", { eAX, Iv } }, 683 { "push{T|}", { cs } }, 684 { "(bad)", { XX } }, /* 0x0f extended opcode escape */ 685 /* 10 */ 686 { "adcB", { Eb, Gb } }, 687 { "adcS", { Ev, Gv } }, 688 { "adcB", { Gb, Eb } }, 689 { "adcS", { Gv, Ev } }, 690 { "adcB", { AL, Ib } }, 691 { "adcS", { eAX, Iv } }, 692 { "push{T|}", { ss } }, 693 { "pop{T|}", { ss } }, 694 /* 18 */ 695 { "sbbB", { Eb, Gb } }, 696 { "sbbS", { Ev, Gv } }, 697 { "sbbB", { Gb, Eb } }, 698 { "sbbS", { Gv, Ev } }, 699 { "sbbB", { AL, Ib } }, 700 { "sbbS", { eAX, Iv } }, 701 { "push{T|}", { ds } }, 702 { "pop{T|}", { ds } }, 703 /* 20 */ 704 { "andB", { Eb, Gb } }, 705 { "andS", { Ev, Gv } }, 706 { "andB", { Gb, Eb } }, 707 { "andS", { Gv, Ev } }, 708 { "andB", { AL, Ib } }, 709 { "andS", { eAX, Iv } }, 710 { "(bad)", { XX } }, /* SEG ES prefix */ 711 { "daa{|}", { XX } }, 712 /* 28 */ 713 { "subB", { Eb, Gb } }, 714 { "subS", { Ev, Gv } }, 715 { "subB", { Gb, Eb } }, 716 { "subS", { Gv, Ev } }, 717 { "subB", { AL, Ib } }, 718 { "subS", { eAX, Iv } }, 719 { "(bad)", { XX } }, /* SEG CS prefix */ 720 { "das{|}", { XX } }, 721 /* 30 */ 722 { "xorB", { Eb, Gb } }, 723 { "xorS", { Ev, Gv } }, 724 { "xorB", { Gb, Eb } }, 725 { "xorS", { Gv, Ev } }, 726 { "xorB", { AL, Ib } }, 727 { "xorS", { eAX, Iv } }, 728 { "(bad)", { XX } }, /* SEG SS prefix */ 729 { "aaa{|}", { XX } }, 730 /* 38 */ 731 { "cmpB", { Eb, Gb } }, 732 { "cmpS", { Ev, Gv } }, 733 { "cmpB", { Gb, Eb } }, 734 { "cmpS", { Gv, Ev } }, 735 { "cmpB", { AL, Ib } }, 736 { "cmpS", { eAX, Iv } }, 737 { "(bad)", { XX } }, /* SEG DS prefix */ 738 { "aas{|}", { XX } }, 739 /* 40 */ 740 { "inc{S|}", { RMeAX } }, 741 { "inc{S|}", { RMeCX } }, 742 { "inc{S|}", { RMeDX } }, 743 { "inc{S|}", { RMeBX } }, 744 { "inc{S|}", { RMeSP } }, 745 { "inc{S|}", { RMeBP } }, 746 { "inc{S|}", { RMeSI } }, 747 { "inc{S|}", { RMeDI } }, 748 /* 48 */ 749 { "dec{S|}", { RMeAX } }, 750 { "dec{S|}", { RMeCX } }, 751 { "dec{S|}", { RMeDX } }, 752 { "dec{S|}", { RMeBX } }, 753 { "dec{S|}", { RMeSP } }, 754 { "dec{S|}", { RMeBP } }, 755 { "dec{S|}", { RMeSI } }, 756 { "dec{S|}", { RMeDI } }, 757 /* 50 */ 758 { "pushV", { RMrAX } }, 759 { "pushV", { RMrCX } }, 760 { "pushV", { RMrDX } }, 761 { "pushV", { RMrBX } }, 762 { "pushV", { RMrSP } }, 763 { "pushV", { RMrBP } }, 764 { "pushV", { RMrSI } }, 765 { "pushV", { RMrDI } }, 766 /* 58 */ 767 { "popV", { RMrAX } }, 768 { "popV", { RMrCX } }, 769 { "popV", { RMrDX } }, 770 { "popV", { RMrBX } }, 771 { "popV", { RMrSP } }, 772 { "popV", { RMrBP } }, 773 { "popV", { RMrSI } }, 774 { "popV", { RMrDI } }, 775 /* 60 */ 776 { X86_64_0 }, 777 { X86_64_1 }, 778 { X86_64_2 }, 779 { X86_64_3 }, 780 { "(bad)", { XX } }, /* seg fs */ 781 { "(bad)", { XX } }, /* seg gs */ 782 { "(bad)", { XX } }, /* op size prefix */ 783 { "(bad)", { XX } }, /* adr size prefix */ 784 /* 68 */ 785 { "pushT", { Iq } }, 786 { "imulS", { Gv, Ev, Iv } }, 787 { "pushT", { sIb } }, 788 { "imulS", { Gv, Ev, sIb } }, 789 { "ins{b||b|}", { Ybr, indirDX } }, 790 { "ins{R||G|}", { Yzr, indirDX } }, 791 { "outs{b||b|}", { indirDXr, Xb } }, 792 { "outs{R||G|}", { indirDXr, Xz } }, 793 /* 70 */ 794 { "joH", { Jb, XX, cond_jump_flag } }, 795 { "jnoH", { Jb, XX, cond_jump_flag } }, 796 { "jbH", { Jb, XX, cond_jump_flag } }, 797 { "jaeH", { Jb, XX, cond_jump_flag } }, 798 { "jeH", { Jb, XX, cond_jump_flag } }, 799 { "jneH", { Jb, XX, cond_jump_flag } }, 800 { "jbeH", { Jb, XX, cond_jump_flag } }, 801 { "jaH", { Jb, XX, cond_jump_flag } }, 802 /* 78 */ 803 { "jsH", { Jb, XX, cond_jump_flag } }, 804 { "jnsH", { Jb, XX, cond_jump_flag } }, 805 { "jpH", { Jb, XX, cond_jump_flag } }, 806 { "jnpH", { Jb, XX, cond_jump_flag } }, 807 { "jlH", { Jb, XX, cond_jump_flag } }, 808 { "jgeH", { Jb, XX, cond_jump_flag } }, 809 { "jleH", { Jb, XX, cond_jump_flag } }, 810 { "jgH", { Jb, XX, cond_jump_flag } }, 811 /* 80 */ 812 { GRP1b }, 813 { GRP1S }, 814 { "(bad)", { XX } }, 815 { GRP1Ss }, 816 { "testB", { Eb, Gb } }, 817 { "testS", { Ev, Gv } }, 818 { "xchgB", { Eb, Gb } }, 819 { "xchgS", { Ev, Gv } }, 820 /* 88 */ 821 { "movB", { Eb, Gb } }, 822 { "movS", { Ev, Gv } }, 823 { "movB", { Gb, Eb } }, 824 { "movS", { Gv, Ev } }, 825 { "movD", { Sv, Sw } }, 826 { OPC_EXT_0 }, 827 { "movD", { Sw, Sv } }, 828 { GRP1a }, 829 /* 90 */ 830 { PREGRP38 }, 831 { "xchgS", { RMeCX, eAX } }, 832 { "xchgS", { RMeDX, eAX } }, 833 { "xchgS", { RMeBX, eAX } }, 834 { "xchgS", { RMeSP, eAX } }, 835 { "xchgS", { RMeBP, eAX } }, 836 { "xchgS", { RMeSI, eAX } }, 837 { "xchgS", { RMeDI, eAX } }, 838 /* 98 */ 839 { "cW{t||t|}R", { XX } }, 840 { "cR{t||t|}O", { XX } }, 841 { "Jcall{T|}", { Ap } }, 842 { "(bad)", { XX } }, /* fwait */ 843 { "pushfT", { XX } }, 844 { "popfT", { XX } }, 845 { "sahf{|}", { XX } }, 846 { "lahf{|}", { XX } }, 847 /* a0 */ 848 { "movB", { AL, Ob } }, 849 { "movS", { eAX, Ov } }, 850 { "movB", { Ob, AL } }, 851 { "movS", { Ov, eAX } }, 852 { "movs{b||b|}", { Ybr, Xb } }, 853 { "movs{R||R|}", { Yvr, Xv } }, 854 { "cmps{b||b|}", { Xb, Yb } }, 855 { "cmps{R||R|}", { Xv, Yv } }, 856 /* a8 */ 857 { "testB", { AL, Ib } }, 858 { "testS", { eAX, Iv } }, 859 { "stosB", { Ybr, AL } }, 860 { "stosS", { Yvr, eAX } }, 861 { "lodsB", { ALr, Xb } }, 862 { "lodsS", { eAXr, Xv } }, 863 { "scasB", { AL, Yb } }, 864 { "scasS", { eAX, Yv } }, 865 /* b0 */ 866 { "movB", { RMAL, Ib } }, 867 { "movB", { RMCL, Ib } }, 868 { "movB", { RMDL, Ib } }, 869 { "movB", { RMBL, Ib } }, 870 { "movB", { RMAH, Ib } }, 871 { "movB", { RMCH, Ib } }, 872 { "movB", { RMDH, Ib } }, 873 { "movB", { RMBH, Ib } }, 874 /* b8 */ 875 { "movS", { RMeAX, Iv64 } }, 876 { "movS", { RMeCX, Iv64 } }, 877 { "movS", { RMeDX, Iv64 } }, 878 { "movS", { RMeBX, Iv64 } }, 879 { "movS", { RMeSP, Iv64 } }, 880 { "movS", { RMeBP, Iv64 } }, 881 { "movS", { RMeSI, Iv64 } }, 882 { "movS", { RMeDI, Iv64 } }, 883 /* c0 */ 884 { GRP2b }, 885 { GRP2S }, 886 { "retT", { Iw } }, 887 { "retT", { XX } }, 888 { OPC_EXT_1 }, 889 { OPC_EXT_2 }, 890 { GRP11_C6 }, 891 { GRP11_C7 }, 892 /* c8 */ 893 { "enterT", { Iw, Ib } }, 894 { "leaveT", { XX } }, 895 { "lretP", { Iw } }, 896 { "lretP", { XX } }, 897 { "int3", { XX } }, 898 { "int", { Ib } }, 899 { "into{|}", { XX } }, 900 { "iretP", { XX } }, 901 /* d0 */ 902 { GRP2b_one }, 903 { GRP2S_one }, 904 { GRP2b_cl }, 905 { GRP2S_cl }, 906 { "aam{|}", { sIb } }, 907 { "aad{|}", { sIb } }, 908 { "(bad)", { XX } }, 909 { "xlat", { DSBX } }, 910 /* d8 */ 911 { FLOAT }, 912 { FLOAT }, 913 { FLOAT }, 914 { FLOAT }, 915 { FLOAT }, 916 { FLOAT }, 917 { FLOAT }, 918 { FLOAT }, 919 /* e0 */ 920 { "loopneFH", { Jb, XX, loop_jcxz_flag } }, 921 { "loopeFH", { Jb, XX, loop_jcxz_flag } }, 922 { "loopFH", { Jb, XX, loop_jcxz_flag } }, 923 { "jEcxzH", { Jb, XX, loop_jcxz_flag } }, 924 { "inB", { AL, Ib } }, 925 { "inG", { zAX, Ib } }, 926 { "outB", { Ib, AL } }, 927 { "outG", { Ib, zAX } }, 928 /* e8 */ 929 { "callT", { Jv } }, 930 { "jmpT", { Jv } }, 931 { "Jjmp{T|}", { Ap } }, 932 { "jmp", { Jb } }, 933 { "inB", { AL, indirDX } }, 934 { "inG", { zAX, indirDX } }, 935 { "outB", { indirDX, AL } }, 936 { "outG", { indirDX, zAX } }, 937 /* f0 */ 938 { "(bad)", { XX } }, /* lock prefix */ 939 { "icebp", { XX } }, 940 { "(bad)", { XX } }, /* repne */ 941 { "(bad)", { XX } }, /* repz */ 942 { "hlt", { XX } }, 943 { "cmc", { XX } }, 944 { GRP3b }, 945 { GRP3S }, 946 /* f8 */ 947 { "clc", { XX } }, 948 { "stc", { XX } }, 949 { "cli", { XX } }, 950 { "sti", { XX } }, 951 { "cld", { XX } }, 952 { "std", { XX } }, 953 { GRP4 }, 954 { GRP5 }, 955}; 956 957static const struct dis386 dis386_twobyte[] = { 958 /* 00 */ 959 { GRP6 }, 960 { GRP7 }, 961 { "larS", { Gv, Ew } }, 962 { "lslS", { Gv, Ew } }, 963 { "(bad)", { XX } }, 964 { "syscall", { XX } }, 965 { "clts", { XX } }, 966 { "sysretP", { XX } }, 967 /* 08 */ 968 { "invd", { XX } }, 969 { "wbinvd", { XX } }, 970 { "(bad)", { XX } }, 971 { "ud2a", { XX } }, 972 { "(bad)", { XX } }, 973 { GRPAMD }, 974 { "femms", { XX } }, 975 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */ 976 /* 10 */ 977 { PREGRP8 }, 978 { PREGRP9 }, 979 { PREGRP30 }, 980 { OPC_EXT_34 }, 981 { "unpcklpX", { XM, EXq } }, 982 { "unpckhpX", { XM, EXq } }, 983 { PREGRP31 }, 984 { OPC_EXT_35 }, 985 /* 18 */ 986 { GRP16 }, 987 { "(bad)", { XX } }, 988 { "(bad)", { XX } }, 989 { "(bad)", { XX } }, 990 { "(bad)", { XX } }, 991 { "(bad)", { XX } }, 992 { "(bad)", { XX } }, 993 { "nopQ", { Ev } }, 994 /* 20 */ 995 { OPC_EXT_40 }, 996 { OPC_EXT_41 }, 997 { OPC_EXT_42 }, 998 { OPC_EXT_43 }, 999 { OPC_EXT_44 }, 1000 { "(bad)", { XX } }, 1001 { OPC_EXT_45 }, 1002 { "(bad)", { XX } }, 1003 /* 28 */ 1004 { "movapX", { XM, EXx } }, 1005 { "movapX", { EXx, XM } }, 1006 { PREGRP2 }, 1007 { PREGRP33 }, 1008 { PREGRP4 }, 1009 { PREGRP3 }, 1010 { PREGRP93 }, 1011 { PREGRP94 }, 1012 /* 30 */ 1013 { "wrmsr", { XX } }, 1014 { "rdtsc", { XX } }, 1015 { "rdmsr", { XX } }, 1016 { "rdpmc", { XX } }, 1017 { "sysenter", { XX } }, 1018 { "sysexit", { XX } }, 1019 { "(bad)", { XX } }, 1020 { "(bad)", { XX } }, 1021 /* 38 */ 1022 { THREE_BYTE_0 }, 1023 { "(bad)", { XX } }, 1024 { THREE_BYTE_1 }, 1025 { "(bad)", { XX } }, 1026 { "(bad)", { XX } }, 1027 { "(bad)", { XX } }, 1028 { "(bad)", { XX } }, 1029 { "(bad)", { XX } }, 1030 /* 40 */ 1031 { "cmovo", { Gv, Ev } }, 1032 { "cmovno", { Gv, Ev } }, 1033 { "cmovb", { Gv, Ev } }, 1034 { "cmovae", { Gv, Ev } }, 1035 { "cmove", { Gv, Ev } }, 1036 { "cmovne", { Gv, Ev } }, 1037 { "cmovbe", { Gv, Ev } }, 1038 { "cmova", { Gv, Ev } }, 1039 /* 48 */ 1040 { "cmovs", { Gv, Ev } }, 1041 { "cmovns", { Gv, Ev } }, 1042 { "cmovp", { Gv, Ev } }, 1043 { "cmovnp", { Gv, Ev } }, 1044 { "cmovl", { Gv, Ev } }, 1045 { "cmovge", { Gv, Ev } }, 1046 { "cmovle", { Gv, Ev } }, 1047 { "cmovg", { Gv, Ev } }, 1048 /* 50 */ 1049 { "movmskpX", { Gdq, XS } }, 1050 { PREGRP13 }, 1051 { PREGRP12 }, 1052 { PREGRP11 }, 1053 { "andpX", { XM, EXx } }, 1054 { "andnpX", { XM, EXx } }, 1055 { "orpX", { XM, EXx } }, 1056 { "xorpX", { XM, EXx } }, 1057 /* 58 */ 1058 { PREGRP0 }, 1059 { PREGRP10 }, 1060 { PREGRP17 }, 1061 { PREGRP16 }, 1062 { PREGRP14 }, 1063 { PREGRP7 }, 1064 { PREGRP5 }, 1065 { PREGRP6 }, 1066 /* 60 */ 1067 { PREGRP95 }, 1068 { PREGRP96 }, 1069 { PREGRP97 }, 1070 { "packsswb", { MX, EM } }, 1071 { "pcmpgtb", { MX, EM } }, 1072 { "pcmpgtw", { MX, EM } }, 1073 { "pcmpgtd", { MX, EM } }, 1074 { "packuswb", { MX, EM } }, 1075 /* 68 */ 1076 { "punpckhbw", { MX, EM } }, 1077 { "punpckhwd", { MX, EM } }, 1078 { "punpckhdq", { MX, EM } }, 1079 { "packssdw", { MX, EM } }, 1080 { PREGRP26 }, 1081 { PREGRP24 }, 1082 { "movK", { MX, Edq } }, 1083 { PREGRP19 }, 1084 /* 70 */ 1085 { PREGRP22 }, 1086 { GRP12 }, 1087 { GRP13 }, 1088 { GRP14 }, 1089 { "pcmpeqb", { MX, EM } }, 1090 { "pcmpeqw", { MX, EM } }, 1091 { "pcmpeqd", { MX, EM } }, 1092 { "emms", { XX } }, 1093 /* 78 */ 1094 { PREGRP34 }, 1095 { PREGRP35 }, 1096 { "(bad)", { XX } }, 1097 { "(bad)", { XX } }, 1098 { PREGRP28 }, 1099 { PREGRP29 }, 1100 { PREGRP23 }, 1101 { PREGRP20 }, 1102 /* 80 */ 1103 { "joH", { Jv, XX, cond_jump_flag } }, 1104 { "jnoH", { Jv, XX, cond_jump_flag } }, 1105 { "jbH", { Jv, XX, cond_jump_flag } }, 1106 { "jaeH", { Jv, XX, cond_jump_flag } }, 1107 { "jeH", { Jv, XX, cond_jump_flag } }, 1108 { "jneH", { Jv, XX, cond_jump_flag } }, 1109 { "jbeH", { Jv, XX, cond_jump_flag } }, 1110 { "jaH", { Jv, XX, cond_jump_flag } }, 1111 /* 88 */ 1112 { "jsH", { Jv, XX, cond_jump_flag } }, 1113 { "jnsH", { Jv, XX, cond_jump_flag } }, 1114 { "jpH", { Jv, XX, cond_jump_flag } }, 1115 { "jnpH", { Jv, XX, cond_jump_flag } }, 1116 { "jlH", { Jv, XX, cond_jump_flag } }, 1117 { "jgeH", { Jv, XX, cond_jump_flag } }, 1118 { "jleH", { Jv, XX, cond_jump_flag } }, 1119 { "jgH", { Jv, XX, cond_jump_flag } }, 1120 /* 90 */ 1121 { "seto", { Eb } }, 1122 { "setno", { Eb } }, 1123 { "setb", { Eb } }, 1124 { "setae", { Eb } }, 1125 { "sete", { Eb } }, 1126 { "setne", { Eb } }, 1127 { "setbe", { Eb } }, 1128 { "seta", { Eb } }, 1129 /* 98 */ 1130 { "sets", { Eb } }, 1131 { "setns", { Eb } }, 1132 { "setp", { Eb } }, 1133 { "setnp", { Eb } }, 1134 { "setl", { Eb } }, 1135 { "setge", { Eb } }, 1136 { "setle", { Eb } }, 1137 { "setg", { Eb } }, 1138 /* a0 */ 1139 { "pushT", { fs } }, 1140 { "popT", { fs } }, 1141 { "cpuid", { XX } }, 1142 { "btS", { Ev, Gv } }, 1143 { "shldS", { Ev, Gv, Ib } }, 1144 { "shldS", { Ev, Gv, CL } }, 1145 { GRPPADLCK2 }, 1146 { GRPPADLCK1 }, 1147 /* a8 */ 1148 { "pushT", { gs } }, 1149 { "popT", { gs } }, 1150 { "rsm", { XX } }, 1151 { "btsS", { Ev, Gv } }, 1152 { "shrdS", { Ev, Gv, Ib } }, 1153 { "shrdS", { Ev, Gv, CL } }, 1154 { GRP15 }, 1155 { "imulS", { Gv, Ev } }, 1156 /* b0 */ 1157 { "cmpxchgB", { Eb, Gb } }, 1158 { "cmpxchgS", { Ev, Gv } }, 1159 { OPC_EXT_3 }, 1160 { "btrS", { Ev, Gv } }, 1161 { OPC_EXT_4 }, 1162 { OPC_EXT_5 }, 1163 { "movz{bR|x|bR|x}", { Gv, Eb } }, 1164 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */ 1165 /* b8 */ 1166 { PREGRP37 }, 1167 { "ud2b", { XX } }, 1168 { GRP8 }, 1169 { "btcS", { Ev, Gv } }, 1170 { "bsfS", { Gv, Ev } }, 1171 { PREGRP36 }, 1172 { "movs{bR|x|bR|x}", { Gv, Eb } }, 1173 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */ 1174 /* c0 */ 1175 { "xaddB", { Eb, Gb } }, 1176 { "xaddS", { Ev, Gv } }, 1177 { PREGRP1 }, 1178 { "movntiS", { Ev, Gv } }, 1179 { "pinsrw", { MX, Edqw, Ib } }, 1180 { "pextrw", { Gdq, MS, Ib } }, 1181 { "shufpX", { XM, EXx, Ib } }, 1182 { GRP9 }, 1183 /* c8 */ 1184 { "bswap", { RMeAX } }, 1185 { "bswap", { RMeCX } }, 1186 { "bswap", { RMeDX } }, 1187 { "bswap", { RMeBX } }, 1188 { "bswap", { RMeSP } }, 1189 { "bswap", { RMeBP } }, 1190 { "bswap", { RMeSI } }, 1191 { "bswap", { RMeDI } }, 1192 /* d0 */ 1193 { PREGRP27 }, 1194 { "psrlw", { MX, EM } }, 1195 { "psrld", { MX, EM } }, 1196 { "psrlq", { MX, EM } }, 1197 { "paddq", { MX, EM } }, 1198 { "pmullw", { MX, EM } }, 1199 { PREGRP21 }, 1200 { "pmovmskb", { Gdq, MS } }, 1201 /* d8 */ 1202 { "psubusb", { MX, EM } }, 1203 { "psubusw", { MX, EM } }, 1204 { "pminub", { MX, EM } }, 1205 { "pand", { MX, EM } }, 1206 { "paddusb", { MX, EM } }, 1207 { "paddusw", { MX, EM } }, 1208 { "pmaxub", { MX, EM } }, 1209 { "pandn", { MX, EM } }, 1210 /* e0 */ 1211 { "pavgb", { MX, EM } }, 1212 { "psraw", { MX, EM } }, 1213 { "psrad", { MX, EM } }, 1214 { "pavgw", { MX, EM } }, 1215 { "pmulhuw", { MX, EM } }, 1216 { "pmulhw", { MX, EM } }, 1217 { PREGRP15 }, 1218 { PREGRP25 }, 1219 /* e8 */ 1220 { "psubsb", { MX, EM } }, 1221 { "psubsw", { MX, EM } }, 1222 { "pminsw", { MX, EM } }, 1223 { "por", { MX, EM } }, 1224 { "paddsb", { MX, EM } }, 1225 { "paddsw", { MX, EM } }, 1226 { "pmaxsw", { MX, EM } }, 1227 { "pxor", { MX, EM } }, 1228 /* f0 */ 1229 { PREGRP32 }, 1230 { "psllw", { MX, EM } }, 1231 { "pslld", { MX, EM } }, 1232 { "psllq", { MX, EM } }, 1233 { "pmuludq", { MX, EM } }, 1234 { "pmaddwd", { MX, EM } }, 1235 { "psadbw", { MX, EM } }, 1236 { PREGRP18 }, 1237 /* f8 */ 1238 { "psubb", { MX, EM } }, 1239 { "psubw", { MX, EM } }, 1240 { "psubd", { MX, EM } }, 1241 { "psubq", { MX, EM } }, 1242 { "paddb", { MX, EM } }, 1243 { "paddw", { MX, EM } }, 1244 { "paddd", { MX, EM } }, 1245 { "(bad)", { XX } }, 1246}; 1247 1248static const unsigned char onebyte_has_modrm[256] = { 1249 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1250 /* ------------------------------- */ 1251 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ 1252 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ 1253 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ 1254 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ 1255 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ 1256 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ 1257 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ 1258 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ 1259 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ 1260 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ 1261 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ 1262 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ 1263 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ 1264 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ 1265 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ 1266 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ 1267 /* ------------------------------- */ 1268 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1269}; 1270 1271static const unsigned char twobyte_has_modrm[256] = { 1272 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1273 /* ------------------------------- */ 1274 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ 1275 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */ 1276 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ 1277 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */ 1278 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ 1279 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ 1280 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ 1281 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */ 1282 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ 1283 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ 1284 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ 1285 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */ 1286 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ 1287 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */ 1288 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */ 1289 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */ 1290 /* ------------------------------- */ 1291 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1292}; 1293 1294static char obuf[100]; 1295static char *obufp; 1296static char scratchbuf[100]; 1297static unsigned char *start_codep; 1298static unsigned char *insn_codep; 1299static unsigned char *codep; 1300static const char *lock_prefix; 1301static const char *data_prefix; 1302static const char *addr_prefix; 1303static const char *repz_prefix; 1304static const char *repnz_prefix; 1305static disassemble_info *the_info; 1306static struct 1307 { 1308 int mod; 1309 int reg; 1310 int rm; 1311 } 1312modrm; 1313static unsigned char need_modrm; 1314 1315/* If we are accessing mod/rm/reg without need_modrm set, then the 1316 values are stale. Hitting this abort likely indicates that you 1317 need to update onebyte_has_modrm or twobyte_has_modrm. */ 1318#define MODRM_CHECK if (!need_modrm) abort () 1319 1320static const char **names64; 1321static const char **names32; 1322static const char **names16; 1323static const char **names8; 1324static const char **names8rex; 1325static const char **names_seg; 1326static const char **index16; 1327 1328static const char *intel_names64[] = { 1329 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", 1330 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1331}; 1332static const char *intel_names32[] = { 1333 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", 1334 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" 1335}; 1336static const char *intel_names16[] = { 1337 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", 1338 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" 1339}; 1340static const char *intel_names8[] = { 1341 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", 1342}; 1343static const char *intel_names8rex[] = { 1344 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", 1345 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" 1346}; 1347static const char *intel_names_seg[] = { 1348 "es", "cs", "ss", "ds", "fs", "gs", "?", "?", 1349}; 1350static const char *intel_index16[] = { 1351 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" 1352}; 1353 1354static const char *att_names64[] = { 1355 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 1356 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 1357}; 1358static const char *att_names32[] = { 1359 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 1360 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" 1361}; 1362static const char *att_names16[] = { 1363 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", 1364 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" 1365}; 1366static const char *att_names8[] = { 1367 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", 1368}; 1369static const char *att_names8rex[] = { 1370 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", 1371 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 1372}; 1373static const char *att_names_seg[] = { 1374 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", 1375}; 1376static const char *att_index16[] = { 1377 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" 1378}; 1379 1380static const struct dis386 grps[][8] = { 1381 /* GRP1a */ 1382 { 1383 { "popU", { stackEv } }, 1384 { "(bad)", { XX } }, 1385 { "(bad)", { XX } }, 1386 { "(bad)", { XX } }, 1387 { "(bad)", { XX } }, 1388 { "(bad)", { XX } }, 1389 { "(bad)", { XX } }, 1390 { "(bad)", { XX } }, 1391 }, 1392 /* GRP1b */ 1393 { 1394 { "addA", { Eb, Ib } }, 1395 { "orA", { Eb, Ib } }, 1396 { "adcA", { Eb, Ib } }, 1397 { "sbbA", { Eb, Ib } }, 1398 { "andA", { Eb, Ib } }, 1399 { "subA", { Eb, Ib } }, 1400 { "xorA", { Eb, Ib } }, 1401 { "cmpA", { Eb, Ib } }, 1402 }, 1403 /* GRP1S */ 1404 { 1405 { "addQ", { Ev, Iv } }, 1406 { "orQ", { Ev, Iv } }, 1407 { "adcQ", { Ev, Iv } }, 1408 { "sbbQ", { Ev, Iv } }, 1409 { "andQ", { Ev, Iv } }, 1410 { "subQ", { Ev, Iv } }, 1411 { "xorQ", { Ev, Iv } }, 1412 { "cmpQ", { Ev, Iv } }, 1413 }, 1414 /* GRP1Ss */ 1415 { 1416 { "addQ", { Ev, sIb } }, 1417 { "orQ", { Ev, sIb } }, 1418 { "adcQ", { Ev, sIb } }, 1419 { "sbbQ", { Ev, sIb } }, 1420 { "andQ", { Ev, sIb } }, 1421 { "subQ", { Ev, sIb } }, 1422 { "xorQ", { Ev, sIb } }, 1423 { "cmpQ", { Ev, sIb } }, 1424 }, 1425 /* GRP2b */ 1426 { 1427 { "rolA", { Eb, Ib } }, 1428 { "rorA", { Eb, Ib } }, 1429 { "rclA", { Eb, Ib } }, 1430 { "rcrA", { Eb, Ib } }, 1431 { "shlA", { Eb, Ib } }, 1432 { "shrA", { Eb, Ib } }, 1433 { "(bad)", { XX } }, 1434 { "sarA", { Eb, Ib } }, 1435 }, 1436 /* GRP2S */ 1437 { 1438 { "rolQ", { Ev, Ib } }, 1439 { "rorQ", { Ev, Ib } }, 1440 { "rclQ", { Ev, Ib } }, 1441 { "rcrQ", { Ev, Ib } }, 1442 { "shlQ", { Ev, Ib } }, 1443 { "shrQ", { Ev, Ib } }, 1444 { "(bad)", { XX } }, 1445 { "sarQ", { Ev, Ib } }, 1446 }, 1447 /* GRP2b_one */ 1448 { 1449 { "rolA", { Eb, I1 } }, 1450 { "rorA", { Eb, I1 } }, 1451 { "rclA", { Eb, I1 } }, 1452 { "rcrA", { Eb, I1 } }, 1453 { "shlA", { Eb, I1 } }, 1454 { "shrA", { Eb, I1 } }, 1455 { "(bad)", { XX } }, 1456 { "sarA", { Eb, I1 } }, 1457 }, 1458 /* GRP2S_one */ 1459 { 1460 { "rolQ", { Ev, I1 } }, 1461 { "rorQ", { Ev, I1 } }, 1462 { "rclQ", { Ev, I1 } }, 1463 { "rcrQ", { Ev, I1 } }, 1464 { "shlQ", { Ev, I1 } }, 1465 { "shrQ", { Ev, I1 } }, 1466 { "(bad)", { XX } }, 1467 { "sarQ", { Ev, I1 } }, 1468 }, 1469 /* GRP2b_cl */ 1470 { 1471 { "rolA", { Eb, CL } }, 1472 { "rorA", { Eb, CL } }, 1473 { "rclA", { Eb, CL } }, 1474 { "rcrA", { Eb, CL } }, 1475 { "shlA", { Eb, CL } }, 1476 { "shrA", { Eb, CL } }, 1477 { "(bad)", { XX } }, 1478 { "sarA", { Eb, CL } }, 1479 }, 1480 /* GRP2S_cl */ 1481 { 1482 { "rolQ", { Ev, CL } }, 1483 { "rorQ", { Ev, CL } }, 1484 { "rclQ", { Ev, CL } }, 1485 { "rcrQ", { Ev, CL } }, 1486 { "shlQ", { Ev, CL } }, 1487 { "shrQ", { Ev, CL } }, 1488 { "(bad)", { XX } }, 1489 { "sarQ", { Ev, CL } }, 1490 }, 1491 /* GRP3b */ 1492 { 1493 { "testA", { Eb, Ib } }, 1494 { "(bad)", { Eb } }, 1495 { "notA", { Eb } }, 1496 { "negA", { Eb } }, 1497 { "mulA", { Eb } }, /* Don't print the implicit %al register, */ 1498 { "imulA", { Eb } }, /* to distinguish these opcodes from other */ 1499 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */ 1500 { "idivA", { Eb } }, /* and idiv for consistency. */ 1501 }, 1502 /* GRP3S */ 1503 { 1504 { "testQ", { Ev, Iv } }, 1505 { "(bad)", { XX } }, 1506 { "notQ", { Ev } }, 1507 { "negQ", { Ev } }, 1508 { "mulQ", { Ev } }, /* Don't print the implicit register. */ 1509 { "imulQ", { Ev } }, 1510 { "divQ", { Ev } }, 1511 { "idivQ", { Ev } }, 1512 }, 1513 /* GRP4 */ 1514 { 1515 { "incA", { Eb } }, 1516 { "decA", { Eb } }, 1517 { "(bad)", { XX } }, 1518 { "(bad)", { XX } }, 1519 { "(bad)", { XX } }, 1520 { "(bad)", { XX } }, 1521 { "(bad)", { XX } }, 1522 { "(bad)", { XX } }, 1523 }, 1524 /* GRP5 */ 1525 { 1526 { "incQ", { Ev } }, 1527 { "decQ", { Ev } }, 1528 { "callT", { indirEv } }, 1529 { "JcallT", { indirEp } }, 1530 { "jmpT", { indirEv } }, 1531 { "JjmpT", { indirEp } }, 1532 { "pushU", { stackEv } }, 1533 { "(bad)", { XX } }, 1534 }, 1535 /* GRP6 */ 1536 { 1537 { "sldtD", { Sv } }, 1538 { "strD", { Sv } }, 1539 { "lldt", { Ew } }, 1540 { "ltr", { Ew } }, 1541 { "verr", { Ew } }, 1542 { "verw", { Ew } }, 1543 { "(bad)", { XX } }, 1544 { "(bad)", { XX } }, 1545 }, 1546 /* GRP7 */ 1547 { 1548 { OPC_EXT_6 }, 1549 { OPC_EXT_7 }, 1550 { OPC_EXT_8 }, 1551 { OPC_EXT_39 }, 1552 { "smswD", { Sv } }, 1553 { "(bad)", { XX } }, 1554 { "lmsw", { Ew } }, 1555 { OPC_EXT_38 }, 1556 }, 1557 /* GRP8 */ 1558 { 1559 { "(bad)", { XX } }, 1560 { "(bad)", { XX } }, 1561 { "(bad)", { XX } }, 1562 { "(bad)", { XX } }, 1563 { "btQ", { Ev, Ib } }, 1564 { "btsQ", { Ev, Ib } }, 1565 { "btrQ", { Ev, Ib } }, 1566 { "btcQ", { Ev, Ib } }, 1567 }, 1568 /* GRP9 */ 1569 { 1570 { "(bad)", { XX } }, 1571 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } }, 1572 { "(bad)", { XX } }, 1573 { "(bad)", { XX } }, 1574 { "(bad)", { XX } }, 1575 { "(bad)", { XX } }, 1576 { OPC_EXT_9 }, 1577 { OPC_EXT_10 }, 1578 }, 1579 /* GRP11_C6 */ 1580 { 1581 { "movA", { Eb, Ib } }, 1582 { "(bad)", { XX } }, 1583 { "(bad)", { XX } }, 1584 { "(bad)", { XX } }, 1585 { "(bad)", { XX } }, 1586 { "(bad)", { XX } }, 1587 { "(bad)", { XX } }, 1588 { "(bad)", { XX } }, 1589 }, 1590 /* GRP11_C7 */ 1591 { 1592 { "movQ", { Ev, Iv } }, 1593 { "(bad)", { XX } }, 1594 { "(bad)", { XX } }, 1595 { "(bad)", { XX } }, 1596 { "(bad)", { XX } }, 1597 { "(bad)", { XX } }, 1598 { "(bad)", { XX } }, 1599 { "(bad)", { XX } }, 1600 }, 1601 /* GRP12 */ 1602 { 1603 { "(bad)", { XX } }, 1604 { "(bad)", { XX } }, 1605 { OPC_EXT_11 }, 1606 { "(bad)", { XX } }, 1607 { OPC_EXT_12 }, 1608 { "(bad)", { XX } }, 1609 { OPC_EXT_13 }, 1610 { "(bad)", { XX } }, 1611 }, 1612 /* GRP13 */ 1613 { 1614 { "(bad)", { XX } }, 1615 { "(bad)", { XX } }, 1616 { OPC_EXT_14 }, 1617 { "(bad)", { XX } }, 1618 { OPC_EXT_15 }, 1619 { "(bad)", { XX } }, 1620 { OPC_EXT_16 }, 1621 { "(bad)", { XX } }, 1622 }, 1623 /* GRP14 */ 1624 { 1625 { "(bad)", { XX } }, 1626 { "(bad)", { XX } }, 1627 { OPC_EXT_17 }, 1628 { OPC_EXT_18 }, 1629 { "(bad)", { XX } }, 1630 { "(bad)", { XX } }, 1631 { OPC_EXT_19 }, 1632 { OPC_EXT_20 }, 1633 }, 1634 /* GRP15 */ 1635 { 1636 { OPC_EXT_21 }, 1637 { OPC_EXT_22 }, 1638 { OPC_EXT_23 }, 1639 { OPC_EXT_24 }, 1640 { "(bad)", { XX } }, 1641 { OPC_EXT_25 }, 1642 { OPC_EXT_26 }, 1643 { OPC_EXT_27 }, 1644 }, 1645 /* GRP16 */ 1646 { 1647 { OPC_EXT_28 }, 1648 { OPC_EXT_29 }, 1649 { OPC_EXT_30 }, 1650 { OPC_EXT_31 }, 1651 { "(bad)", { XX } }, 1652 { "(bad)", { XX } }, 1653 { "(bad)", { XX } }, 1654 { "(bad)", { XX } }, 1655 }, 1656 /* GRPAMD */ 1657 { 1658 { "prefetch", { Eb } }, 1659 { "prefetchw", { Eb } }, 1660 { "(bad)", { XX } }, 1661 { "(bad)", { XX } }, 1662 { "(bad)", { XX } }, 1663 { "(bad)", { XX } }, 1664 { "(bad)", { XX } }, 1665 { "(bad)", { XX } }, 1666 }, 1667 /* GRPPADLCK1 */ 1668 { 1669 { "xstore-rng", { { OP_0f07, 0 } } }, 1670 { "xcrypt-ecb", { { OP_0f07, 0 } } }, 1671 { "xcrypt-cbc", { { OP_0f07, 0 } } }, 1672 { "xcrypt-ctr", { { OP_0f07, 0 } } }, 1673 { "xcrypt-cfb", { { OP_0f07, 0 } } }, 1674 { "xcrypt-ofb", { { OP_0f07, 0 } } }, 1675 { "(bad)", { { OP_0f07, 0 } } }, 1676 { "(bad)", { { OP_0f07, 0 } } }, 1677 }, 1678 /* GRPPADLCK2 */ 1679 { 1680 { "montmul", { { OP_0f07, 0 } } }, 1681 { "xsha1", { { OP_0f07, 0 } } }, 1682 { "xsha256", { { OP_0f07, 0 } } }, 1683 { "(bad)", { { OP_0f07, 0 } } }, 1684 { "(bad)", { { OP_0f07, 0 } } }, 1685 { "(bad)", { { OP_0f07, 0 } } }, 1686 { "(bad)", { { OP_0f07, 0 } } }, 1687 { "(bad)", { { OP_0f07, 0 } } }, 1688 } 1689}; 1690 1691static const struct dis386 prefix_user_table[][4] = { 1692 /* PREGRP0 */ 1693 { 1694 { "addps", { XM, EXx } }, 1695 { "addss", { XM, EXd } }, 1696 { "addpd", { XM, EXx } }, 1697 { "addsd", { XM, EXq } }, 1698 }, 1699 /* PREGRP1 */ 1700 { 1701 { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */ 1702 { "", { XM, EXd, OPSIMD } }, 1703 { "", { XM, EXx, OPSIMD } }, 1704 { "", { XM, EXq, OPSIMD } }, 1705 }, 1706 /* PREGRP2 */ 1707 { 1708 { "cvtpi2ps", { XM, EMCq } }, 1709 { "cvtsi2ssY", { XM, Ev } }, 1710 { "cvtpi2pd", { XM, EMCq } }, 1711 { "cvtsi2sdY", { XM, Ev } }, 1712 }, 1713 /* PREGRP3 */ 1714 { 1715 { "cvtps2pi", { MXC, EXq } }, 1716 { "cvtss2siY", { Gv, EXd } }, 1717 { "cvtpd2pi", { MXC, EXx } }, 1718 { "cvtsd2siY", { Gv, EXq } }, 1719 }, 1720 /* PREGRP4 */ 1721 { 1722 { "cvttps2pi", { MXC, EXq } }, 1723 { "cvttss2siY", { Gv, EXd } }, 1724 { "cvttpd2pi", { MXC, EXx } }, 1725 { "cvttsd2siY", { Gv, EXq } }, 1726 }, 1727 /* PREGRP5 */ 1728 { 1729 { "divps", { XM, EXx } }, 1730 { "divss", { XM, EXd } }, 1731 { "divpd", { XM, EXx } }, 1732 { "divsd", { XM, EXq } }, 1733 }, 1734 /* PREGRP6 */ 1735 { 1736 { "maxps", { XM, EXx } }, 1737 { "maxss", { XM, EXd } }, 1738 { "maxpd", { XM, EXx } }, 1739 { "maxsd", { XM, EXq } }, 1740 }, 1741 /* PREGRP7 */ 1742 { 1743 { "minps", { XM, EXx } }, 1744 { "minss", { XM, EXd } }, 1745 { "minpd", { XM, EXx } }, 1746 { "minsd", { XM, EXq } }, 1747 }, 1748 /* PREGRP8 */ 1749 { 1750 { "movups", { XM, EXx } }, 1751 { "movss", { XM, EXd } }, 1752 { "movupd", { XM, EXx } }, 1753 { "movsd", { XM, EXq } }, 1754 }, 1755 /* PREGRP9 */ 1756 { 1757 { "movups", { EXx, XM } }, 1758 { "movss", { EXd, XM } }, 1759 { "movupd", { EXx, XM } }, 1760 { "movsd", { EXq, XM } }, 1761 }, 1762 /* PREGRP10 */ 1763 { 1764 { "mulps", { XM, EXx } }, 1765 { "mulss", { XM, EXd } }, 1766 { "mulpd", { XM, EXx } }, 1767 { "mulsd", { XM, EXq } }, 1768 }, 1769 /* PREGRP11 */ 1770 { 1771 { "rcpps", { XM, EXx } }, 1772 { "rcpss", { XM, EXd } }, 1773 { "(bad)", { XM, EXx } }, 1774 { "(bad)", { XM, EXx } }, 1775 }, 1776 /* PREGRP12 */ 1777 { 1778 { "rsqrtps",{ XM, EXx } }, 1779 { "rsqrtss",{ XM, EXd } }, 1780 { "(bad)", { XM, EXx } }, 1781 { "(bad)", { XM, EXx } }, 1782 }, 1783 /* PREGRP13 */ 1784 { 1785 { "sqrtps", { XM, EXx } }, 1786 { "sqrtss", { XM, EXd } }, 1787 { "sqrtpd", { XM, EXx } }, 1788 { "sqrtsd", { XM, EXq } }, 1789 }, 1790 /* PREGRP14 */ 1791 { 1792 { "subps", { XM, EXx } }, 1793 { "subss", { XM, EXd } }, 1794 { "subpd", { XM, EXx } }, 1795 { "subsd", { XM, EXq } }, 1796 }, 1797 /* PREGRP15 */ 1798 { 1799 { "(bad)", { XM, EXx } }, 1800 { "cvtdq2pd", { XM, EXq } }, 1801 { "cvttpd2dq", { XM, EXx } }, 1802 { "cvtpd2dq", { XM, EXx } }, 1803 }, 1804 /* PREGRP16 */ 1805 { 1806 { "cvtdq2ps", { XM, EXx } }, 1807 { "cvttps2dq", { XM, EXx } }, 1808 { "cvtps2dq", { XM, EXx } }, 1809 { "(bad)", { XM, EXx } }, 1810 }, 1811 /* PREGRP17 */ 1812 { 1813 { "cvtps2pd", { XM, EXq } }, 1814 { "cvtss2sd", { XM, EXd } }, 1815 { "cvtpd2ps", { XM, EXx } }, 1816 { "cvtsd2ss", { XM, EXq } }, 1817 }, 1818 /* PREGRP18 */ 1819 { 1820 { "maskmovq", { MX, MS } }, 1821 { "(bad)", { XM, EXx } }, 1822 { "maskmovdqu", { XM, XS } }, 1823 { "(bad)", { XM, EXx } }, 1824 }, 1825 /* PREGRP19 */ 1826 { 1827 { "movq", { MX, EM } }, 1828 { "movdqu", { XM, EXx } }, 1829 { "movdqa", { XM, EXx } }, 1830 { "(bad)", { XM, EXx } }, 1831 }, 1832 /* PREGRP20 */ 1833 { 1834 { "movq", { EM, MX } }, 1835 { "movdqu", { EXx, XM } }, 1836 { "movdqa", { EXx, XM } }, 1837 { "(bad)", { EXx, XM } }, 1838 }, 1839 /* PREGRP21 */ 1840 { 1841 { "(bad)", { EXx, XM } }, 1842 { "movq2dq",{ XM, MS } }, 1843 { "movq", { EXq, XM } }, 1844 { "movdq2q",{ MX, XS } }, 1845 }, 1846 /* PREGRP22 */ 1847 { 1848 { "pshufw", { MX, EM, Ib } }, 1849 { "pshufhw",{ XM, EXx, Ib } }, 1850 { "pshufd", { XM, EXx, Ib } }, 1851 { "pshuflw",{ XM, EXx, Ib } }, 1852 }, 1853 /* PREGRP23 */ 1854 { 1855 { "movK", { Edq, MX } }, 1856 { "movq", { XM, EXq } }, 1857 { "movK", { Edq, XM } }, 1858 { "(bad)", { Ed, XM } }, 1859 }, 1860 /* PREGRP24 */ 1861 { 1862 { "(bad)", { MX, EXx } }, 1863 { "(bad)", { XM, EXx } }, 1864 { "punpckhqdq", { XM, EXx } }, 1865 { "(bad)", { XM, EXx } }, 1866 }, 1867 /* PREGRP25 */ 1868 { 1869 { "movntq", { EM, MX } }, 1870 { "(bad)", { EM, XM } }, 1871 { "movntdq",{ EM, XM } }, 1872 { "(bad)", { EM, XM } }, 1873 }, 1874 /* PREGRP26 */ 1875 { 1876 { "(bad)", { MX, EXx } }, 1877 { "(bad)", { XM, EXx } }, 1878 { "punpcklqdq", { XM, EXx } }, 1879 { "(bad)", { XM, EXx } }, 1880 }, 1881 /* PREGRP27 */ 1882 { 1883 { "(bad)", { MX, EXx } }, 1884 { "(bad)", { XM, EXx } }, 1885 { "addsubpd", { XM, EXx } }, 1886 { "addsubps", { XM, EXx } }, 1887 }, 1888 /* PREGRP28 */ 1889 { 1890 { "(bad)", { MX, EXx } }, 1891 { "(bad)", { XM, EXx } }, 1892 { "haddpd", { XM, EXx } }, 1893 { "haddps", { XM, EXx } }, 1894 }, 1895 /* PREGRP29 */ 1896 { 1897 { "(bad)", { MX, EXx } }, 1898 { "(bad)", { XM, EXx } }, 1899 { "hsubpd", { XM, EXx } }, 1900 { "hsubps", { XM, EXx } }, 1901 }, 1902 /* PREGRP30 */ 1903 { 1904 { OPC_EXT_36 }, 1905 { "movsldup", { XM, EXx } }, 1906 { "movlpd", { XM, EXq } }, 1907 { "movddup", { XM, EXq } }, 1908 }, 1909 /* PREGRP31 */ 1910 { 1911 { OPC_EXT_37 }, 1912 { "movshdup", { XM, EXx } }, 1913 { "movhpd", { XM, EXq } }, 1914 { "(bad)", { XM, EXq } }, 1915 }, 1916 /* PREGRP32 */ 1917 { 1918 { "(bad)", { XM, EXx } }, 1919 { "(bad)", { XM, EXx } }, 1920 { "(bad)", { XM, EXx } }, 1921 { OPC_EXT_32 }, 1922 }, 1923 /* PREGRP33 */ 1924 { 1925 {"movntps", { Ev, XM } }, 1926 {"movntss", { Ed, XM } }, 1927 {"movntpd", { Ev, XM } }, 1928 {"movntsd", { Eq, XM } }, 1929 }, 1930 1931 /* PREGRP34 */ 1932 { 1933 {"vmread", { Em, Gm } }, 1934 {"(bad)", { XX } }, 1935 {"extrq", { XS, Ib, Ib } }, 1936 {"insertq", { XM, XS, Ib, Ib } }, 1937 }, 1938 1939 /* PREGRP35 */ 1940 { 1941 {"vmwrite", { Gm, Em } }, 1942 {"(bad)", { XX } }, 1943 {"extrq", { XM, XS } }, 1944 {"insertq", { XM, XS } }, 1945 }, 1946 1947 /* PREGRP36 */ 1948 { 1949 { "bsrS", { Gv, Ev } }, 1950 { "lzcntS", { Gv, Ev } }, 1951 { "bsrS", { Gv, Ev } }, 1952 { "(bad)", { XX } }, 1953 }, 1954 1955 /* PREGRP37 */ 1956 { 1957 { "(bad)", { XX } }, 1958 { "popcntS", { Gv, Ev } }, 1959 { "(bad)", { XX } }, 1960 { "(bad)", { XX } }, 1961 }, 1962 1963 /* PREGRP38 */ 1964 { 1965 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, 1966 { "pause", { XX } }, 1967 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, 1968 { "(bad)", { XX } }, 1969 }, 1970 1971 /* PREGRP39 */ 1972 { 1973 { "(bad)", { XX } }, 1974 { "(bad)", { XX } }, 1975 { "pblendvb", {XM, EXx, XMM0 } }, 1976 { "(bad)", { XX } }, 1977 }, 1978 1979 /* PREGRP40 */ 1980 { 1981 { "(bad)", { XX } }, 1982 { "(bad)", { XX } }, 1983 { "blendvps", {XM, EXx, XMM0 } }, 1984 { "(bad)", { XX } }, 1985 }, 1986 1987 /* PREGRP41 */ 1988 { 1989 { "(bad)", { XX } }, 1990 { "(bad)", { XX } }, 1991 { "blendvpd", { XM, EXx, XMM0 } }, 1992 { "(bad)", { XX } }, 1993 }, 1994 1995 /* PREGRP42 */ 1996 { 1997 { "(bad)", { XX } }, 1998 { "(bad)", { XX } }, 1999 { "ptest", { XM, EXx } }, 2000 { "(bad)", { XX } }, 2001 }, 2002 2003 /* PREGRP43 */ 2004 { 2005 { "(bad)", { XX } }, 2006 { "(bad)", { XX } }, 2007 { "pmovsxbw", { XM, EXq } }, 2008 { "(bad)", { XX } }, 2009 }, 2010 2011 /* PREGRP44 */ 2012 { 2013 { "(bad)", { XX } }, 2014 { "(bad)", { XX } }, 2015 { "pmovsxbd", { XM, EXd } }, 2016 { "(bad)", { XX } }, 2017 }, 2018 2019 /* PREGRP45 */ 2020 { 2021 { "(bad)", { XX } }, 2022 { "(bad)", { XX } }, 2023 { "pmovsxbq", { XM, EXw } }, 2024 { "(bad)", { XX } }, 2025 }, 2026 2027 /* PREGRP46 */ 2028 { 2029 { "(bad)", { XX } }, 2030 { "(bad)", { XX } }, 2031 { "pmovsxwd", { XM, EXq } }, 2032 { "(bad)", { XX } }, 2033 }, 2034 2035 /* PREGRP47 */ 2036 { 2037 { "(bad)", { XX } }, 2038 { "(bad)", { XX } }, 2039 { "pmovsxwq", { XM, EXd } }, 2040 { "(bad)", { XX } }, 2041 }, 2042 2043 /* PREGRP48 */ 2044 { 2045 { "(bad)", { XX } }, 2046 { "(bad)", { XX } }, 2047 { "pmovsxdq", { XM, EXq } }, 2048 { "(bad)", { XX } }, 2049 }, 2050 2051 /* PREGRP49 */ 2052 { 2053 { "(bad)", { XX } }, 2054 { "(bad)", { XX } }, 2055 { "pmuldq", { XM, EXx } }, 2056 { "(bad)", { XX } }, 2057 }, 2058 2059 /* PREGRP50 */ 2060 { 2061 { "(bad)", { XX } }, 2062 { "(bad)", { XX } }, 2063 { "pcmpeqq", { XM, EXx } }, 2064 { "(bad)", { XX } }, 2065 }, 2066 2067 /* PREGRP51 */ 2068 { 2069 { "(bad)", { XX } }, 2070 { "(bad)", { XX } }, 2071 { "movntdqa", { XM, EM } }, 2072 { "(bad)", { XX } }, 2073 }, 2074 2075 /* PREGRP52 */ 2076 { 2077 { "(bad)", { XX } }, 2078 { "(bad)", { XX } }, 2079 { "packusdw", { XM, EXx } }, 2080 { "(bad)", { XX } }, 2081 }, 2082 2083 /* PREGRP53 */ 2084 { 2085 { "(bad)", { XX } }, 2086 { "(bad)", { XX } }, 2087 { "pmovzxbw", { XM, EXq } }, 2088 { "(bad)", { XX } }, 2089 }, 2090 2091 /* PREGRP54 */ 2092 { 2093 { "(bad)", { XX } }, 2094 { "(bad)", { XX } }, 2095 { "pmovzxbd", { XM, EXd } }, 2096 { "(bad)", { XX } }, 2097 }, 2098 2099 /* PREGRP55 */ 2100 { 2101 { "(bad)", { XX } }, 2102 { "(bad)", { XX } }, 2103 { "pmovzxbq", { XM, EXw } }, 2104 { "(bad)", { XX } }, 2105 }, 2106 2107 /* PREGRP56 */ 2108 { 2109 { "(bad)", { XX } }, 2110 { "(bad)", { XX } }, 2111 { "pmovzxwd", { XM, EXq } }, 2112 { "(bad)", { XX } }, 2113 }, 2114 2115 /* PREGRP57 */ 2116 { 2117 { "(bad)", { XX } }, 2118 { "(bad)", { XX } }, 2119 { "pmovzxwq", { XM, EXd } }, 2120 { "(bad)", { XX } }, 2121 }, 2122 2123 /* PREGRP58 */ 2124 { 2125 { "(bad)", { XX } }, 2126 { "(bad)", { XX } }, 2127 { "pmovzxdq", { XM, EXq } }, 2128 { "(bad)", { XX } }, 2129 }, 2130 2131 /* PREGRP59 */ 2132 { 2133 { "(bad)", { XX } }, 2134 { "(bad)", { XX } }, 2135 { "pminsb", { XM, EXx } }, 2136 { "(bad)", { XX } }, 2137 }, 2138 2139 /* PREGRP60 */ 2140 { 2141 { "(bad)", { XX } }, 2142 { "(bad)", { XX } }, 2143 { "pminsd", { XM, EXx } }, 2144 { "(bad)", { XX } }, 2145 }, 2146 2147 /* PREGRP61 */ 2148 { 2149 { "(bad)", { XX } }, 2150 { "(bad)", { XX } }, 2151 { "pminuw", { XM, EXx } }, 2152 { "(bad)", { XX } }, 2153 }, 2154 2155 /* PREGRP62 */ 2156 { 2157 { "(bad)", { XX } }, 2158 { "(bad)", { XX } }, 2159 { "pminud", { XM, EXx } }, 2160 { "(bad)", { XX } }, 2161 }, 2162 2163 /* PREGRP63 */ 2164 { 2165 { "(bad)", { XX } }, 2166 { "(bad)", { XX } }, 2167 { "pmaxsb", { XM, EXx } }, 2168 { "(bad)", { XX } }, 2169 }, 2170 2171 /* PREGRP64 */ 2172 { 2173 { "(bad)", { XX } }, 2174 { "(bad)", { XX } }, 2175 { "pmaxsd", { XM, EXx } }, 2176 { "(bad)", { XX } }, 2177 }, 2178 2179 /* PREGRP65 */ 2180 { 2181 { "(bad)", { XX } }, 2182 { "(bad)", { XX } }, 2183 { "pmaxuw", { XM, EXx } }, 2184 { "(bad)", { XX } }, 2185 }, 2186 2187 /* PREGRP66 */ 2188 { 2189 { "(bad)", { XX } }, 2190 { "(bad)", { XX } }, 2191 { "pmaxud", { XM, EXx } }, 2192 { "(bad)", { XX } }, 2193 }, 2194 2195 /* PREGRP67 */ 2196 { 2197 { "(bad)", { XX } }, 2198 { "(bad)", { XX } }, 2199 { "pmulld", { XM, EXx } }, 2200 { "(bad)", { XX } }, 2201 }, 2202 2203 /* PREGRP68 */ 2204 { 2205 { "(bad)", { XX } }, 2206 { "(bad)", { XX } }, 2207 { "phminposuw", { XM, EXx } }, 2208 { "(bad)", { XX } }, 2209 }, 2210 2211 /* PREGRP69 */ 2212 { 2213 { "(bad)", { XX } }, 2214 { "(bad)", { XX } }, 2215 { "roundps", { XM, EXx, Ib } }, 2216 { "(bad)", { XX } }, 2217 }, 2218 2219 /* PREGRP70 */ 2220 { 2221 { "(bad)", { XX } }, 2222 { "(bad)", { XX } }, 2223 { "roundpd", { XM, EXx, Ib } }, 2224 { "(bad)", { XX } }, 2225 }, 2226 2227 /* PREGRP71 */ 2228 { 2229 { "(bad)", { XX } }, 2230 { "(bad)", { XX } }, 2231 { "roundss", { XM, EXd, Ib } }, 2232 { "(bad)", { XX } }, 2233 }, 2234 2235 /* PREGRP72 */ 2236 { 2237 { "(bad)", { XX } }, 2238 { "(bad)", { XX } }, 2239 { "roundsd", { XM, EXq, Ib } }, 2240 { "(bad)", { XX } }, 2241 }, 2242 2243 /* PREGRP73 */ 2244 { 2245 { "(bad)", { XX } }, 2246 { "(bad)", { XX } }, 2247 { "blendps", { XM, EXx, Ib } }, 2248 { "(bad)", { XX } }, 2249 }, 2250 2251 /* PREGRP74 */ 2252 { 2253 { "(bad)", { XX } }, 2254 { "(bad)", { XX } }, 2255 { "blendpd", { XM, EXx, Ib } }, 2256 { "(bad)", { XX } }, 2257 }, 2258 2259 /* PREGRP75 */ 2260 { 2261 { "(bad)", { XX } }, 2262 { "(bad)", { XX } }, 2263 { "pblendw", { XM, EXx, Ib } }, 2264 { "(bad)", { XX } }, 2265 }, 2266 2267 /* PREGRP76 */ 2268 { 2269 { "(bad)", { XX } }, 2270 { "(bad)", { XX } }, 2271 { "pextrb", { Edqb, XM, Ib } }, 2272 { "(bad)", { XX } }, 2273 }, 2274 2275 /* PREGRP77 */ 2276 { 2277 { "(bad)", { XX } }, 2278 { "(bad)", { XX } }, 2279 { "pextrw", { Edqw, XM, Ib } }, 2280 { "(bad)", { XX } }, 2281 }, 2282 2283 /* PREGRP78 */ 2284 { 2285 { "(bad)", { XX } }, 2286 { "(bad)", { XX } }, 2287 { "pextrK", { Edq, XM, Ib } }, 2288 { "(bad)", { XX } }, 2289 }, 2290 2291 /* PREGRP79 */ 2292 { 2293 { "(bad)", { XX } }, 2294 { "(bad)", { XX } }, 2295 { "extractps", { Edqd, XM, Ib } }, 2296 { "(bad)", { XX } }, 2297 }, 2298 2299 /* PREGRP80 */ 2300 { 2301 { "(bad)", { XX } }, 2302 { "(bad)", { XX } }, 2303 { "pinsrb", { XM, Edqb, Ib } }, 2304 { "(bad)", { XX } }, 2305 }, 2306 2307 /* PREGRP81 */ 2308 { 2309 { "(bad)", { XX } }, 2310 { "(bad)", { XX } }, 2311 { "insertps", { XM, EXd, Ib } }, 2312 { "(bad)", { XX } }, 2313 }, 2314 2315 /* PREGRP82 */ 2316 { 2317 { "(bad)", { XX } }, 2318 { "(bad)", { XX } }, 2319 { "pinsrK", { XM, Edq, Ib } }, 2320 { "(bad)", { XX } }, 2321 }, 2322 2323 /* PREGRP83 */ 2324 { 2325 { "(bad)", { XX } }, 2326 { "(bad)", { XX } }, 2327 { "dpps", { XM, EXx, Ib } }, 2328 { "(bad)", { XX } }, 2329 }, 2330 2331 /* PREGRP84 */ 2332 { 2333 { "(bad)", { XX } }, 2334 { "(bad)", { XX } }, 2335 { "dppd", { XM, EXx, Ib } }, 2336 { "(bad)", { XX } }, 2337 }, 2338 2339 /* PREGRP85 */ 2340 { 2341 { "(bad)", { XX } }, 2342 { "(bad)", { XX } }, 2343 { "mpsadbw", { XM, EXx, Ib } }, 2344 { "(bad)", { XX } }, 2345 }, 2346 2347 /* PREGRP86 */ 2348 { 2349 { "(bad)", { XX } }, 2350 { "(bad)", { XX } }, 2351 { "pcmpgtq", { XM, EXx } }, 2352 { "(bad)", { XX } }, 2353 }, 2354 2355 /* PREGRP87 */ 2356 { 2357 { "(bad)", { XX } }, 2358 { "(bad)", { XX } }, 2359 { "(bad)", { XX } }, 2360 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } }, 2361 }, 2362 2363 /* PREGRP88 */ 2364 { 2365 { "(bad)", { XX } }, 2366 { "(bad)", { XX } }, 2367 { "(bad)", { XX } }, 2368 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } }, 2369 }, 2370 2371 /* PREGRP89 */ 2372 { 2373 { "(bad)", { XX } }, 2374 { "(bad)", { XX } }, 2375 { "pcmpestrm", { XM, EXx, Ib } }, 2376 { "(bad)", { XX } }, 2377 }, 2378 2379 /* PREGRP90 */ 2380 { 2381 { "(bad)", { XX } }, 2382 { "(bad)", { XX } }, 2383 { "pcmpestri", { XM, EXx, Ib } }, 2384 { "(bad)", { XX } }, 2385 }, 2386 2387 /* PREGRP91 */ 2388 { 2389 { "(bad)", { XX } }, 2390 { "(bad)", { XX } }, 2391 { "pcmpistrm", { XM, EXx, Ib } }, 2392 { "(bad)", { XX } }, 2393 }, 2394 2395 /* PREGRP92 */ 2396 { 2397 { "(bad)", { XX } }, 2398 { "(bad)", { XX } }, 2399 { "pcmpistri", { XM, EXx, Ib } }, 2400 { "(bad)", { XX } }, 2401 }, 2402 2403 /* PREGRP93 */ 2404 { 2405 { "ucomiss",{ XM, EXd } }, 2406 { "(bad)", { XX } }, 2407 { "ucomisd",{ XM, EXq } }, 2408 { "(bad)", { XX } }, 2409 }, 2410 2411 /* PREGRP94 */ 2412 { 2413 { "comiss", { XM, EXd } }, 2414 { "(bad)", { XX } }, 2415 { "comisd", { XM, EXq } }, 2416 { "(bad)", { XX } }, 2417 }, 2418 2419 /* PREGRP95 */ 2420 { 2421 { "punpcklbw",{ MX, EMd } }, 2422 { "(bad)", { XX } }, 2423 { "punpcklbw",{ MX, EMx } }, 2424 { "(bad)", { XX } }, 2425 }, 2426 2427 /* PREGRP96 */ 2428 { 2429 { "punpcklwd",{ MX, EMd } }, 2430 { "(bad)", { XX } }, 2431 { "punpcklwd",{ MX, EMx } }, 2432 { "(bad)", { XX } }, 2433 }, 2434 2435 /* PREGRP97 */ 2436 { 2437 { "punpckldq",{ MX, EMd } }, 2438 { "(bad)", { XX } }, 2439 { "punpckldq",{ MX, EMx } }, 2440 { "(bad)", { XX } }, 2441 }, 2442 2443 /* PREGRP98 */ 2444 { 2445 { "vmptrld",{ Mq } }, 2446 { "vmxon", { Mq } }, 2447 { "vmclear",{ Mq } }, 2448 { "(bad)", { XX } }, 2449 }, 2450 2451 /* PREGRP99 */ 2452 { 2453 { "(bad)", { XX } }, 2454 { "(bad)", { XX } }, 2455 { "psrldq", { MS, Ib } }, 2456 { "(bad)", { XX } }, 2457 }, 2458 2459 /* PREGRP100 */ 2460 { 2461 { "(bad)", { XX } }, 2462 { "(bad)", { XX } }, 2463 { "pslldq", { MS, Ib } }, 2464 { "(bad)", { XX } }, 2465 }, 2466}; 2467 2468static const struct dis386 x86_64_table[][2] = { 2469 { 2470 { "pusha{P|}", { XX } }, 2471 { "(bad)", { XX } }, 2472 }, 2473 { 2474 { "popa{P|}", { XX } }, 2475 { "(bad)", { XX } }, 2476 }, 2477 { 2478 { OPC_EXT_33 }, 2479 { "(bad)", { XX } }, 2480 }, 2481 { 2482 { "arpl", { Ew, Gw } }, 2483 { "movs{||lq|xd}", { Gv, Ed } }, 2484 }, 2485}; 2486 2487static const struct dis386 three_byte_table[][256] = { 2488 /* THREE_BYTE_0 */ 2489 { 2490 /* 00 */ 2491 { "pshufb", { MX, EM } }, 2492 { "phaddw", { MX, EM } }, 2493 { "phaddd", { MX, EM } }, 2494 { "phaddsw", { MX, EM } }, 2495 { "pmaddubsw", { MX, EM } }, 2496 { "phsubw", { MX, EM } }, 2497 { "phsubd", { MX, EM } }, 2498 { "phsubsw", { MX, EM } }, 2499 /* 08 */ 2500 { "psignb", { MX, EM } }, 2501 { "psignw", { MX, EM } }, 2502 { "psignd", { MX, EM } }, 2503 { "pmulhrsw", { MX, EM } }, 2504 { "(bad)", { XX } }, 2505 { "(bad)", { XX } }, 2506 { "(bad)", { XX } }, 2507 { "(bad)", { XX } }, 2508 /* 10 */ 2509 { PREGRP39 }, 2510 { "(bad)", { XX } }, 2511 { "(bad)", { XX } }, 2512 { "(bad)", { XX } }, 2513 { PREGRP40 }, 2514 { PREGRP41 }, 2515 { "(bad)", { XX } }, 2516 { PREGRP42 }, 2517 /* 18 */ 2518 { "(bad)", { XX } }, 2519 { "(bad)", { XX } }, 2520 { "(bad)", { XX } }, 2521 { "(bad)", { XX } }, 2522 { "pabsb", { MX, EM } }, 2523 { "pabsw", { MX, EM } }, 2524 { "pabsd", { MX, EM } }, 2525 { "(bad)", { XX } }, 2526 /* 20 */ 2527 { PREGRP43 }, 2528 { PREGRP44 }, 2529 { PREGRP45 }, 2530 { PREGRP46 }, 2531 { PREGRP47 }, 2532 { PREGRP48 }, 2533 { "(bad)", { XX } }, 2534 { "(bad)", { XX } }, 2535 /* 28 */ 2536 { PREGRP49 }, 2537 { PREGRP50 }, 2538 { PREGRP51 }, 2539 { PREGRP52 }, 2540 { "(bad)", { XX } }, 2541 { "(bad)", { XX } }, 2542 { "(bad)", { XX } }, 2543 { "(bad)", { XX } }, 2544 /* 30 */ 2545 { PREGRP53 }, 2546 { PREGRP54 }, 2547 { PREGRP55 }, 2548 { PREGRP56 }, 2549 { PREGRP57 }, 2550 { PREGRP58 }, 2551 { "(bad)", { XX } }, 2552 { PREGRP86 }, 2553 /* 38 */ 2554 { PREGRP59 }, 2555 { PREGRP60 }, 2556 { PREGRP61 }, 2557 { PREGRP62 }, 2558 { PREGRP63 }, 2559 { PREGRP64 }, 2560 { PREGRP65 }, 2561 { PREGRP66 }, 2562 /* 40 */ 2563 { PREGRP67 }, 2564 { PREGRP68 }, 2565 { "(bad)", { XX } }, 2566 { "(bad)", { XX } }, 2567 { "(bad)", { XX } }, 2568 { "(bad)", { XX } }, 2569 { "(bad)", { XX } }, 2570 { "(bad)", { XX } }, 2571 /* 48 */ 2572 { "(bad)", { XX } }, 2573 { "(bad)", { XX } }, 2574 { "(bad)", { XX } }, 2575 { "(bad)", { XX } }, 2576 { "(bad)", { XX } }, 2577 { "(bad)", { XX } }, 2578 { "(bad)", { XX } }, 2579 { "(bad)", { XX } }, 2580 /* 50 */ 2581 { "(bad)", { XX } }, 2582 { "(bad)", { XX } }, 2583 { "(bad)", { XX } }, 2584 { "(bad)", { XX } }, 2585 { "(bad)", { XX } }, 2586 { "(bad)", { XX } }, 2587 { "(bad)", { XX } }, 2588 { "(bad)", { XX } }, 2589 /* 58 */ 2590 { "(bad)", { XX } }, 2591 { "(bad)", { XX } }, 2592 { "(bad)", { XX } }, 2593 { "(bad)", { XX } }, 2594 { "(bad)", { XX } }, 2595 { "(bad)", { XX } }, 2596 { "(bad)", { XX } }, 2597 { "(bad)", { XX } }, 2598 /* 60 */ 2599 { "(bad)", { XX } }, 2600 { "(bad)", { XX } }, 2601 { "(bad)", { XX } }, 2602 { "(bad)", { XX } }, 2603 { "(bad)", { XX } }, 2604 { "(bad)", { XX } }, 2605 { "(bad)", { XX } }, 2606 { "(bad)", { XX } }, 2607 /* 68 */ 2608 { "(bad)", { XX } }, 2609 { "(bad)", { XX } }, 2610 { "(bad)", { XX } }, 2611 { "(bad)", { XX } }, 2612 { "(bad)", { XX } }, 2613 { "(bad)", { XX } }, 2614 { "(bad)", { XX } }, 2615 { "(bad)", { XX } }, 2616 /* 70 */ 2617 { "(bad)", { XX } }, 2618 { "(bad)", { XX } }, 2619 { "(bad)", { XX } }, 2620 { "(bad)", { XX } }, 2621 { "(bad)", { XX } }, 2622 { "(bad)", { XX } }, 2623 { "(bad)", { XX } }, 2624 { "(bad)", { XX } }, 2625 /* 78 */ 2626 { "(bad)", { XX } }, 2627 { "(bad)", { XX } }, 2628 { "(bad)", { XX } }, 2629 { "(bad)", { XX } }, 2630 { "(bad)", { XX } }, 2631 { "(bad)", { XX } }, 2632 { "(bad)", { XX } }, 2633 { "(bad)", { XX } }, 2634 /* 80 */ 2635 { "(bad)", { XX } }, 2636 { "(bad)", { XX } }, 2637 { "(bad)", { XX } }, 2638 { "(bad)", { XX } }, 2639 { "(bad)", { XX } }, 2640 { "(bad)", { XX } }, 2641 { "(bad)", { XX } }, 2642 { "(bad)", { XX } }, 2643 /* 88 */ 2644 { "(bad)", { XX } }, 2645 { "(bad)", { XX } }, 2646 { "(bad)", { XX } }, 2647 { "(bad)", { XX } }, 2648 { "(bad)", { XX } }, 2649 { "(bad)", { XX } }, 2650 { "(bad)", { XX } }, 2651 { "(bad)", { XX } }, 2652 /* 90 */ 2653 { "(bad)", { XX } }, 2654 { "(bad)", { XX } }, 2655 { "(bad)", { XX } }, 2656 { "(bad)", { XX } }, 2657 { "(bad)", { XX } }, 2658 { "(bad)", { XX } }, 2659 { "(bad)", { XX } }, 2660 { "(bad)", { XX } }, 2661 /* 98 */ 2662 { "(bad)", { XX } }, 2663 { "(bad)", { XX } }, 2664 { "(bad)", { XX } }, 2665 { "(bad)", { XX } }, 2666 { "(bad)", { XX } }, 2667 { "(bad)", { XX } }, 2668 { "(bad)", { XX } }, 2669 { "(bad)", { XX } }, 2670 /* a0 */ 2671 { "(bad)", { XX } }, 2672 { "(bad)", { XX } }, 2673 { "(bad)", { XX } }, 2674 { "(bad)", { XX } }, 2675 { "(bad)", { XX } }, 2676 { "(bad)", { XX } }, 2677 { "(bad)", { XX } }, 2678 { "(bad)", { XX } }, 2679 /* a8 */ 2680 { "(bad)", { XX } }, 2681 { "(bad)", { XX } }, 2682 { "(bad)", { XX } }, 2683 { "(bad)", { XX } }, 2684 { "(bad)", { XX } }, 2685 { "(bad)", { XX } }, 2686 { "(bad)", { XX } }, 2687 { "(bad)", { XX } }, 2688 /* b0 */ 2689 { "(bad)", { XX } }, 2690 { "(bad)", { XX } }, 2691 { "(bad)", { XX } }, 2692 { "(bad)", { XX } }, 2693 { "(bad)", { XX } }, 2694 { "(bad)", { XX } }, 2695 { "(bad)", { XX } }, 2696 { "(bad)", { XX } }, 2697 /* b8 */ 2698 { "(bad)", { XX } }, 2699 { "(bad)", { XX } }, 2700 { "(bad)", { XX } }, 2701 { "(bad)", { XX } }, 2702 { "(bad)", { XX } }, 2703 { "(bad)", { XX } }, 2704 { "(bad)", { XX } }, 2705 { "(bad)", { XX } }, 2706 /* c0 */ 2707 { "(bad)", { XX } }, 2708 { "(bad)", { XX } }, 2709 { "(bad)", { XX } }, 2710 { "(bad)", { XX } }, 2711 { "(bad)", { XX } }, 2712 { "(bad)", { XX } }, 2713 { "(bad)", { XX } }, 2714 { "(bad)", { XX } }, 2715 /* c8 */ 2716 { "(bad)", { XX } }, 2717 { "(bad)", { XX } }, 2718 { "(bad)", { XX } }, 2719 { "(bad)", { XX } }, 2720 { "(bad)", { XX } }, 2721 { "(bad)", { XX } }, 2722 { "(bad)", { XX } }, 2723 { "(bad)", { XX } }, 2724 /* d0 */ 2725 { "(bad)", { XX } }, 2726 { "(bad)", { XX } }, 2727 { "(bad)", { XX } }, 2728 { "(bad)", { XX } }, 2729 { "(bad)", { XX } }, 2730 { "(bad)", { XX } }, 2731 { "(bad)", { XX } }, 2732 { "(bad)", { XX } }, 2733 /* d8 */ 2734 { "(bad)", { XX } }, 2735 { "(bad)", { XX } }, 2736 { "(bad)", { XX } }, 2737 { "(bad)", { XX } }, 2738 { "(bad)", { XX } }, 2739 { "(bad)", { XX } }, 2740 { "(bad)", { XX } }, 2741 { "(bad)", { XX } }, 2742 /* e0 */ 2743 { "(bad)", { XX } }, 2744 { "(bad)", { XX } }, 2745 { "(bad)", { XX } }, 2746 { "(bad)", { XX } }, 2747 { "(bad)", { XX } }, 2748 { "(bad)", { XX } }, 2749 { "(bad)", { XX } }, 2750 { "(bad)", { XX } }, 2751 /* e8 */ 2752 { "(bad)", { XX } }, 2753 { "(bad)", { XX } }, 2754 { "(bad)", { XX } }, 2755 { "(bad)", { XX } }, 2756 { "(bad)", { XX } }, 2757 { "(bad)", { XX } }, 2758 { "(bad)", { XX } }, 2759 { "(bad)", { XX } }, 2760 /* f0 */ 2761 { PREGRP87 }, 2762 { PREGRP88 }, 2763 { "(bad)", { XX } }, 2764 { "(bad)", { XX } }, 2765 { "(bad)", { XX } }, 2766 { "(bad)", { XX } }, 2767 { "(bad)", { XX } }, 2768 { "(bad)", { XX } }, 2769 /* f8 */ 2770 { "(bad)", { XX } }, 2771 { "(bad)", { XX } }, 2772 { "(bad)", { XX } }, 2773 { "(bad)", { XX } }, 2774 { "(bad)", { XX } }, 2775 { "(bad)", { XX } }, 2776 { "(bad)", { XX } }, 2777 { "(bad)", { XX } }, 2778 }, 2779 /* THREE_BYTE_1 */ 2780 { 2781 /* 00 */ 2782 { "(bad)", { XX } }, 2783 { "(bad)", { XX } }, 2784 { "(bad)", { XX } }, 2785 { "(bad)", { XX } }, 2786 { "(bad)", { XX } }, 2787 { "(bad)", { XX } }, 2788 { "(bad)", { XX } }, 2789 { "(bad)", { XX } }, 2790 /* 08 */ 2791 { PREGRP69 }, 2792 { PREGRP70 }, 2793 { PREGRP71 }, 2794 { PREGRP72 }, 2795 { PREGRP73 }, 2796 { PREGRP74 }, 2797 { PREGRP75 }, 2798 { "palignr", { MX, EM, Ib } }, 2799 /* 10 */ 2800 { "(bad)", { XX } }, 2801 { "(bad)", { XX } }, 2802 { "(bad)", { XX } }, 2803 { "(bad)", { XX } }, 2804 { PREGRP76 }, 2805 { PREGRP77 }, 2806 { PREGRP78 }, 2807 { PREGRP79 }, 2808 /* 18 */ 2809 { "(bad)", { XX } }, 2810 { "(bad)", { XX } }, 2811 { "(bad)", { XX } }, 2812 { "(bad)", { XX } }, 2813 { "(bad)", { XX } }, 2814 { "(bad)", { XX } }, 2815 { "(bad)", { XX } }, 2816 { "(bad)", { XX } }, 2817 /* 20 */ 2818 { PREGRP80 }, 2819 { PREGRP81 }, 2820 { PREGRP82 }, 2821 { "(bad)", { XX } }, 2822 { "(bad)", { XX } }, 2823 { "(bad)", { XX } }, 2824 { "(bad)", { XX } }, 2825 { "(bad)", { XX } }, 2826 /* 28 */ 2827 { "(bad)", { XX } }, 2828 { "(bad)", { XX } }, 2829 { "(bad)", { XX } }, 2830 { "(bad)", { XX } }, 2831 { "(bad)", { XX } }, 2832 { "(bad)", { XX } }, 2833 { "(bad)", { XX } }, 2834 { "(bad)", { XX } }, 2835 /* 30 */ 2836 { "(bad)", { XX } }, 2837 { "(bad)", { XX } }, 2838 { "(bad)", { XX } }, 2839 { "(bad)", { XX } }, 2840 { "(bad)", { XX } }, 2841 { "(bad)", { XX } }, 2842 { "(bad)", { XX } }, 2843 { "(bad)", { XX } }, 2844 /* 38 */ 2845 { "(bad)", { XX } }, 2846 { "(bad)", { XX } }, 2847 { "(bad)", { XX } }, 2848 { "(bad)", { XX } }, 2849 { "(bad)", { XX } }, 2850 { "(bad)", { XX } }, 2851 { "(bad)", { XX } }, 2852 { "(bad)", { XX } }, 2853 /* 40 */ 2854 { PREGRP83 }, 2855 { PREGRP84 }, 2856 { PREGRP85 }, 2857 { "(bad)", { XX } }, 2858 { "(bad)", { XX } }, 2859 { "(bad)", { XX } }, 2860 { "(bad)", { XX } }, 2861 { "(bad)", { XX } }, 2862 /* 48 */ 2863 { "(bad)", { XX } }, 2864 { "(bad)", { XX } }, 2865 { "(bad)", { XX } }, 2866 { "(bad)", { XX } }, 2867 { "(bad)", { XX } }, 2868 { "(bad)", { XX } }, 2869 { "(bad)", { XX } }, 2870 { "(bad)", { XX } }, 2871 /* 50 */ 2872 { "(bad)", { XX } }, 2873 { "(bad)", { XX } }, 2874 { "(bad)", { XX } }, 2875 { "(bad)", { XX } }, 2876 { "(bad)", { XX } }, 2877 { "(bad)", { XX } }, 2878 { "(bad)", { XX } }, 2879 { "(bad)", { XX } }, 2880 /* 58 */ 2881 { "(bad)", { XX } }, 2882 { "(bad)", { XX } }, 2883 { "(bad)", { XX } }, 2884 { "(bad)", { XX } }, 2885 { "(bad)", { XX } }, 2886 { "(bad)", { XX } }, 2887 { "(bad)", { XX } }, 2888 { "(bad)", { XX } }, 2889 /* 60 */ 2890 { PREGRP89 }, 2891 { PREGRP90 }, 2892 { PREGRP91 }, 2893 { PREGRP92 }, 2894 { "(bad)", { XX } }, 2895 { "(bad)", { XX } }, 2896 { "(bad)", { XX } }, 2897 { "(bad)", { XX } }, 2898 /* 68 */ 2899 { "(bad)", { XX } }, 2900 { "(bad)", { XX } }, 2901 { "(bad)", { XX } }, 2902 { "(bad)", { XX } }, 2903 { "(bad)", { XX } }, 2904 { "(bad)", { XX } }, 2905 { "(bad)", { XX } }, 2906 { "(bad)", { XX } }, 2907 /* 70 */ 2908 { "(bad)", { XX } }, 2909 { "(bad)", { XX } }, 2910 { "(bad)", { XX } }, 2911 { "(bad)", { XX } }, 2912 { "(bad)", { XX } }, 2913 { "(bad)", { XX } }, 2914 { "(bad)", { XX } }, 2915 { "(bad)", { XX } }, 2916 /* 78 */ 2917 { "(bad)", { XX } }, 2918 { "(bad)", { XX } }, 2919 { "(bad)", { XX } }, 2920 { "(bad)", { XX } }, 2921 { "(bad)", { XX } }, 2922 { "(bad)", { XX } }, 2923 { "(bad)", { XX } }, 2924 { "(bad)", { XX } }, 2925 /* 80 */ 2926 { "(bad)", { XX } }, 2927 { "(bad)", { XX } }, 2928 { "(bad)", { XX } }, 2929 { "(bad)", { XX } }, 2930 { "(bad)", { XX } }, 2931 { "(bad)", { XX } }, 2932 { "(bad)", { XX } }, 2933 { "(bad)", { XX } }, 2934 /* 88 */ 2935 { "(bad)", { XX } }, 2936 { "(bad)", { XX } }, 2937 { "(bad)", { XX } }, 2938 { "(bad)", { XX } }, 2939 { "(bad)", { XX } }, 2940 { "(bad)", { XX } }, 2941 { "(bad)", { XX } }, 2942 { "(bad)", { XX } }, 2943 /* 90 */ 2944 { "(bad)", { XX } }, 2945 { "(bad)", { XX } }, 2946 { "(bad)", { XX } }, 2947 { "(bad)", { XX } }, 2948 { "(bad)", { XX } }, 2949 { "(bad)", { XX } }, 2950 { "(bad)", { XX } }, 2951 { "(bad)", { XX } }, 2952 /* 98 */ 2953 { "(bad)", { XX } }, 2954 { "(bad)", { XX } }, 2955 { "(bad)", { XX } }, 2956 { "(bad)", { XX } }, 2957 { "(bad)", { XX } }, 2958 { "(bad)", { XX } }, 2959 { "(bad)", { XX } }, 2960 { "(bad)", { XX } }, 2961 /* a0 */ 2962 { "(bad)", { XX } }, 2963 { "(bad)", { XX } }, 2964 { "(bad)", { XX } }, 2965 { "(bad)", { XX } }, 2966 { "(bad)", { XX } }, 2967 { "(bad)", { XX } }, 2968 { "(bad)", { XX } }, 2969 { "(bad)", { XX } }, 2970 /* a8 */ 2971 { "(bad)", { XX } }, 2972 { "(bad)", { XX } }, 2973 { "(bad)", { XX } }, 2974 { "(bad)", { XX } }, 2975 { "(bad)", { XX } }, 2976 { "(bad)", { XX } }, 2977 { "(bad)", { XX } }, 2978 { "(bad)", { XX } }, 2979 /* b0 */ 2980 { "(bad)", { XX } }, 2981 { "(bad)", { XX } }, 2982 { "(bad)", { XX } }, 2983 { "(bad)", { XX } }, 2984 { "(bad)", { XX } }, 2985 { "(bad)", { XX } }, 2986 { "(bad)", { XX } }, 2987 { "(bad)", { XX } }, 2988 /* b8 */ 2989 { "(bad)", { XX } }, 2990 { "(bad)", { XX } }, 2991 { "(bad)", { XX } }, 2992 { "(bad)", { XX } }, 2993 { "(bad)", { XX } }, 2994 { "(bad)", { XX } }, 2995 { "(bad)", { XX } }, 2996 { "(bad)", { XX } }, 2997 /* c0 */ 2998 { "(bad)", { XX } }, 2999 { "(bad)", { XX } }, 3000 { "(bad)", { XX } }, 3001 { "(bad)", { XX } }, 3002 { "(bad)", { XX } }, 3003 { "(bad)", { XX } }, 3004 { "(bad)", { XX } }, 3005 { "(bad)", { XX } }, 3006 /* c8 */ 3007 { "(bad)", { XX } }, 3008 { "(bad)", { XX } }, 3009 { "(bad)", { XX } }, 3010 { "(bad)", { XX } }, 3011 { "(bad)", { XX } }, 3012 { "(bad)", { XX } }, 3013 { "(bad)", { XX } }, 3014 { "(bad)", { XX } }, 3015 /* d0 */ 3016 { "(bad)", { XX } }, 3017 { "(bad)", { XX } }, 3018 { "(bad)", { XX } }, 3019 { "(bad)", { XX } }, 3020 { "(bad)", { XX } }, 3021 { "(bad)", { XX } }, 3022 { "(bad)", { XX } }, 3023 { "(bad)", { XX } }, 3024 /* d8 */ 3025 { "(bad)", { XX } }, 3026 { "(bad)", { XX } }, 3027 { "(bad)", { XX } }, 3028 { "(bad)", { XX } }, 3029 { "(bad)", { XX } }, 3030 { "(bad)", { XX } }, 3031 { "(bad)", { XX } }, 3032 { "(bad)", { XX } }, 3033 /* e0 */ 3034 { "(bad)", { XX } }, 3035 { "(bad)", { XX } }, 3036 { "(bad)", { XX } }, 3037 { "(bad)", { XX } }, 3038 { "(bad)", { XX } }, 3039 { "(bad)", { XX } }, 3040 { "(bad)", { XX } }, 3041 { "(bad)", { XX } }, 3042 /* e8 */ 3043 { "(bad)", { XX } }, 3044 { "(bad)", { XX } }, 3045 { "(bad)", { XX } }, 3046 { "(bad)", { XX } }, 3047 { "(bad)", { XX } }, 3048 { "(bad)", { XX } }, 3049 { "(bad)", { XX } }, 3050 { "(bad)", { XX } }, 3051 /* f0 */ 3052 { "(bad)", { XX } }, 3053 { "(bad)", { XX } }, 3054 { "(bad)", { XX } }, 3055 { "(bad)", { XX } }, 3056 { "(bad)", { XX } }, 3057 { "(bad)", { XX } }, 3058 { "(bad)", { XX } }, 3059 { "(bad)", { XX } }, 3060 /* f8 */ 3061 { "(bad)", { XX } }, 3062 { "(bad)", { XX } }, 3063 { "(bad)", { XX } }, 3064 { "(bad)", { XX } }, 3065 { "(bad)", { XX } }, 3066 { "(bad)", { XX } }, 3067 { "(bad)", { XX } }, 3068 { "(bad)", { XX } }, 3069 } 3070}; 3071 3072static const struct dis386 opc_ext_table[][2] = { 3073 { 3074 /* OPC_EXT_0 */ 3075 { "leaS", { Gv, M } }, 3076 { "(bad)", { XX } }, 3077 }, 3078 { 3079 /* OPC_EXT_1 */ 3080 { "les{S|}", { Gv, Mp } }, 3081 { "(bad)", { XX } }, 3082 }, 3083 { 3084 /* OPC_EXT_2 */ 3085 { "ldsS", { Gv, Mp } }, 3086 { "(bad)", { XX } }, 3087 }, 3088 { 3089 /* OPC_EXT_3 */ 3090 { "lssS", { Gv, Mp } }, 3091 { "(bad)", { XX } }, 3092 }, 3093 { 3094 /* OPC_EXT_4 */ 3095 { "lfsS", { Gv, Mp } }, 3096 { "(bad)", { XX } }, 3097 }, 3098 { 3099 /* OPC_EXT_5 */ 3100 { "lgsS", { Gv, Mp } }, 3101 { "(bad)", { XX } }, 3102 }, 3103 { 3104 /* OPC_EXT_6 */ 3105 { "sgdt{Q|IQ||}", { M } }, 3106 { OPC_EXT_RM_0 }, 3107 }, 3108 { 3109 /* OPC_EXT_7 */ 3110 { "sidt{Q|IQ||}", { M } }, 3111 { OPC_EXT_RM_1 }, 3112 }, 3113 { 3114 /* OPC_EXT_8 */ 3115 { "lgdt{Q|Q||}", { M } }, 3116 { "(bad)", { XX } }, 3117 }, 3118 { 3119 /* OPC_EXT_9 */ 3120 { PREGRP98 }, 3121 { "(bad)", { XX } }, 3122 }, 3123 { 3124 /* OPC_EXT_10 */ 3125 { "vmptrst", { Mq } }, 3126 { "(bad)", { XX } }, 3127 }, 3128 { 3129 /* OPC_EXT_11 */ 3130 { "(bad)", { XX } }, 3131 { "psrlw", { MS, Ib } }, 3132 }, 3133 { 3134 /* OPC_EXT_12 */ 3135 { "(bad)", { XX } }, 3136 { "psraw", { MS, Ib } }, 3137 }, 3138 { 3139 /* OPC_EXT_13 */ 3140 { "(bad)", { XX } }, 3141 { "psllw", { MS, Ib } }, 3142 }, 3143 { 3144 /* OPC_EXT_14 */ 3145 { "(bad)", { XX } }, 3146 { "psrld", { MS, Ib } }, 3147 }, 3148 { 3149 /* OPC_EXT_15 */ 3150 { "(bad)", { XX } }, 3151 { "psrad", { MS, Ib } }, 3152 }, 3153 { 3154 /* OPC_EXT_16 */ 3155 { "(bad)", { XX } }, 3156 { "pslld", { MS, Ib } }, 3157 }, 3158 { 3159 /* OPC_EXT_17 */ 3160 { "(bad)", { XX } }, 3161 { "psrlq", { MS, Ib } }, 3162 }, 3163 { 3164 /* OPC_EXT_18 */ 3165 { "(bad)", { XX } }, 3166 { PREGRP99 }, 3167 }, 3168 { 3169 /* OPC_EXT_19 */ 3170 { "(bad)", { XX } }, 3171 { "psllq", { MS, Ib } }, 3172 }, 3173 { 3174 /* OPC_EXT_20 */ 3175 { "(bad)", { XX } }, 3176 { PREGRP100 }, 3177 }, 3178 { 3179 /* OPC_EXT_21 */ 3180 { "fxsave", { M } }, 3181 { "(bad)", { XX } }, 3182 }, 3183 { 3184 /* OPC_EXT_22 */ 3185 { "fxrstor", { M } }, 3186 { "(bad)", { XX } }, 3187 }, 3188 { 3189 /* OPC_EXT_23 */ 3190 { "ldmxcsr", { Md } }, 3191 { "(bad)", { XX } }, 3192 }, 3193 { 3194 /* OPC_EXT_24 */ 3195 { "stmxcsr", { Md } }, 3196 { "(bad)", { XX } }, 3197 }, 3198 { 3199 /* OPC_EXT_25 */ 3200 { "(bad)", { XX } }, 3201 { OPC_EXT_RM_2 }, 3202 }, 3203 { 3204 /* OPC_EXT_26 */ 3205 { "(bad)", { XX } }, 3206 { OPC_EXT_RM_3 }, 3207 }, 3208 { 3209 /* OPC_EXT_27 */ 3210 { "clflush", { Mb } }, 3211 { OPC_EXT_RM_4 }, 3212 }, 3213 { 3214 /* OPC_EXT_28 */ 3215 { "prefetchnta", { Mb } }, 3216 { "(bad)", { XX } }, 3217 }, 3218 { 3219 /* OPC_EXT_29 */ 3220 { "prefetcht0", { Mb } }, 3221 { "(bad)", { XX } }, 3222 }, 3223 { 3224 /* OPC_EXT_30 */ 3225 { "prefetcht1", { Mb } }, 3226 { "(bad)", { XX } }, 3227 }, 3228 { 3229 /* OPC_EXT_31 */ 3230 { "prefetcht2", { Mb } }, 3231 { "(bad)", { XX } }, 3232 }, 3233 { 3234 /* OPC_EXT_32 */ 3235 { "lddqu", { XM, M } }, 3236 { "(bad)", { XX } }, 3237 }, 3238 { 3239 /* OPC_EXT_33 */ 3240 { "bound{S|}", { Gv, Ma } }, 3241 { "(bad)", { XX } }, 3242 }, 3243 { 3244 /* OPC_EXT_34 */ 3245 { "movlpX", { EXq, XM } }, 3246 { "(bad)", { XX } }, 3247 }, 3248 { 3249 /* OPC_EXT_35 */ 3250 { "movhpX", { EXq, XM } }, 3251 { "(bad)", { XX } }, 3252 }, 3253 { 3254 /* OPC_EXT_36 */ 3255 { "movlpX", { XM, EXq } }, 3256 { "movhlpX", { XM, EXq } }, 3257 }, 3258 { 3259 /* OPC_EXT_37 */ 3260 { "movhpX", { XM, EXq } }, 3261 { "movlhpX", { XM, EXq } }, 3262 }, 3263 { 3264 /* OPC_EXT_38 */ 3265 { "invlpg", { Mb } }, 3266 { OPC_EXT_RM_5 }, 3267 }, 3268 { 3269 /* OPC_EXT_39 */ 3270 { "lidt{Q|Q||}", { M } }, 3271 { OPC_EXT_RM_6 }, 3272 }, 3273 { 3274 /* OPC_EXT_40 */ 3275 { "(bad)", { XX } }, 3276 { "movZ", { Rm, Cm } }, 3277 }, 3278 { 3279 /* OPC_EXT_41 */ 3280 { "(bad)", { XX } }, 3281 { "movZ", { Rm, Dm } }, 3282 }, 3283 { 3284 /* OPC_EXT_42 */ 3285 { "(bad)", { XX } }, 3286 { "movZ", { Cm, Rm } }, 3287 }, 3288 { 3289 /* OPC_EXT_43 */ 3290 { "(bad)", { XX } }, 3291 { "movZ", { Dm, Rm } }, 3292 }, 3293 { 3294 /* OPC_EXT_44 */ 3295 { "(bad)", { XX } }, 3296 { "movL", { Rd, Td } }, 3297 }, 3298 { 3299 /* OPC_EXT_45 */ 3300 { "(bad)", { XX } }, 3301 { "movL", { Td, Rd } }, 3302 }, 3303}; 3304 3305static const struct dis386 opc_ext_rm_table[][8] = { 3306 { 3307 /* OPC_EXT_RM_0 */ 3308 { "(bad)", { XX } }, 3309 { "vmcall", { Skip_MODRM } }, 3310 { "vmlaunch", { Skip_MODRM } }, 3311 { "vmresume", { Skip_MODRM } }, 3312 { "vmxoff", { Skip_MODRM } }, 3313 { "(bad)", { XX } }, 3314 { "(bad)", { XX } }, 3315 { "(bad)", { XX } }, 3316 }, 3317 { 3318 /* OPC_EXT_RM_1 */ 3319 { "monitor", { { OP_Monitor, 0 } } }, 3320 { "mwait", { { OP_Mwait, 0 } } }, 3321 { "(bad)", { XX } }, 3322 { "(bad)", { XX } }, 3323 { "(bad)", { XX } }, 3324 { "(bad)", { XX } }, 3325 { "(bad)", { XX } }, 3326 { "(bad)", { XX } }, 3327 }, 3328 { 3329 /* OPC_EXT_RM_2 */ 3330 { "lfence", { Skip_MODRM } }, 3331 { "(bad)", { XX } }, 3332 { "(bad)", { XX } }, 3333 { "(bad)", { XX } }, 3334 { "(bad)", { XX } }, 3335 { "(bad)", { XX } }, 3336 { "(bad)", { XX } }, 3337 { "(bad)", { XX } }, 3338 }, 3339 { 3340 /* OPC_EXT_RM_3 */ 3341 { "mfence", { Skip_MODRM } }, 3342 { "(bad)", { XX } }, 3343 { "(bad)", { XX } }, 3344 { "(bad)", { XX } }, 3345 { "(bad)", { XX } }, 3346 { "(bad)", { XX } }, 3347 { "(bad)", { XX } }, 3348 { "(bad)", { XX } }, 3349 }, 3350 { 3351 /* OPC_EXT_RM_4 */ 3352 { "sfence", { Skip_MODRM } }, 3353 { "(bad)", { XX } }, 3354 { "(bad)", { XX } }, 3355 { "(bad)", { XX } }, 3356 { "(bad)", { XX } }, 3357 { "(bad)", { XX } }, 3358 { "(bad)", { XX } }, 3359 { "(bad)", { XX } }, 3360 }, 3361 { 3362 /* OPC_EXT_RM_5 */ 3363 { "swapgs", { Skip_MODRM } }, 3364 { "rdtscp", { Skip_MODRM } }, 3365 { "(bad)", { XX } }, 3366 { "(bad)", { XX } }, 3367 { "(bad)", { XX } }, 3368 { "(bad)", { XX } }, 3369 { "(bad)", { XX } }, 3370 { "(bad)", { XX } }, 3371 }, 3372 { 3373 /* OPC_EXT_RM_6 */ 3374 { "vmrun", { Skip_MODRM } }, 3375 { "vmmcall", { Skip_MODRM } }, 3376 { "vmload", { Skip_MODRM } }, 3377 { "vmsave", { Skip_MODRM } }, 3378 { "stgi", { Skip_MODRM } }, 3379 { "clgi", { Skip_MODRM } }, 3380 { "skinit", { Skip_MODRM } }, 3381 { "invlpga", { Skip_MODRM } }, 3382 }, 3383}; 3384 3385#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") 3386 3387static void 3388ckprefix (void) 3389{ 3390 int newrex; 3391 rex = 0; 3392 prefixes = 0; 3393 used_prefixes = 0; 3394 rex_used = 0; 3395 while (1) 3396 { 3397 FETCH_DATA (the_info, codep + 1); 3398 newrex = 0; 3399 switch (*codep) 3400 { 3401 /* REX prefixes family. */ 3402 case 0x40: 3403 case 0x41: 3404 case 0x42: 3405 case 0x43: 3406 case 0x44: 3407 case 0x45: 3408 case 0x46: 3409 case 0x47: 3410 case 0x48: 3411 case 0x49: 3412 case 0x4a: 3413 case 0x4b: 3414 case 0x4c: 3415 case 0x4d: 3416 case 0x4e: 3417 case 0x4f: 3418 if (address_mode == mode_64bit) 3419 newrex = *codep; 3420 else 3421 return; 3422 break; 3423 case 0xf3: 3424 prefixes |= PREFIX_REPZ; 3425 break; 3426 case 0xf2: 3427 prefixes |= PREFIX_REPNZ; 3428 break; 3429 case 0xf0: 3430 prefixes |= PREFIX_LOCK; 3431 break; 3432 case 0x2e: 3433 prefixes |= PREFIX_CS; 3434 break; 3435 case 0x36: 3436 prefixes |= PREFIX_SS; 3437 break; 3438 case 0x3e: 3439 prefixes |= PREFIX_DS; 3440 break; 3441 case 0x26: 3442 prefixes |= PREFIX_ES; 3443 break; 3444 case 0x64: 3445 prefixes |= PREFIX_FS; 3446 break; 3447 case 0x65: 3448 prefixes |= PREFIX_GS; 3449 break; 3450 case 0x66: 3451 prefixes |= PREFIX_DATA; 3452 break; 3453 case 0x67: 3454 prefixes |= PREFIX_ADDR; 3455 break; 3456 case FWAIT_OPCODE: 3457 /* fwait is really an instruction. If there are prefixes 3458 before the fwait, they belong to the fwait, *not* to the 3459 following instruction. */ 3460 if (prefixes || rex) 3461 { 3462 prefixes |= PREFIX_FWAIT; 3463 codep++; 3464 return; 3465 } 3466 prefixes = PREFIX_FWAIT; 3467 break; 3468 default: 3469 return; 3470 } 3471 /* Rex is ignored when followed by another prefix. */ 3472 if (rex) 3473 { 3474 rex_used = rex; 3475 return; 3476 } 3477 rex = newrex; 3478 codep++; 3479 } 3480} 3481 3482/* Return the name of the prefix byte PREF, or NULL if PREF is not a 3483 prefix byte. */ 3484 3485static const char * 3486prefix_name (int pref, int sizeflag) 3487{ 3488 static const char *rexes [16] = 3489 { 3490 "rex", /* 0x40 */ 3491 "rex.B", /* 0x41 */ 3492 "rex.X", /* 0x42 */ 3493 "rex.XB", /* 0x43 */ 3494 "rex.R", /* 0x44 */ 3495 "rex.RB", /* 0x45 */ 3496 "rex.RX", /* 0x46 */ 3497 "rex.RXB", /* 0x47 */ 3498 "rex.W", /* 0x48 */ 3499 "rex.WB", /* 0x49 */ 3500 "rex.WX", /* 0x4a */ 3501 "rex.WXB", /* 0x4b */ 3502 "rex.WR", /* 0x4c */ 3503 "rex.WRB", /* 0x4d */ 3504 "rex.WRX", /* 0x4e */ 3505 "rex.WRXB", /* 0x4f */ 3506 }; 3507 3508 switch (pref) 3509 { 3510 /* REX prefixes family. */ 3511 case 0x40: 3512 case 0x41: 3513 case 0x42: 3514 case 0x43: 3515 case 0x44: 3516 case 0x45: 3517 case 0x46: 3518 case 0x47: 3519 case 0x48: 3520 case 0x49: 3521 case 0x4a: 3522 case 0x4b: 3523 case 0x4c: 3524 case 0x4d: 3525 case 0x4e: 3526 case 0x4f: 3527 return rexes [pref - 0x40]; 3528 case 0xf3: 3529 return "repz"; 3530 case 0xf2: 3531 return "repnz"; 3532 case 0xf0: 3533 return "lock"; 3534 case 0x2e: 3535 return "cs"; 3536 case 0x36: 3537 return "ss"; 3538 case 0x3e: 3539 return "ds"; 3540 case 0x26: 3541 return "es"; 3542 case 0x64: 3543 return "fs"; 3544 case 0x65: 3545 return "gs"; 3546 case 0x66: 3547 return (sizeflag & DFLAG) ? "data16" : "data32"; 3548 case 0x67: 3549 if (address_mode == mode_64bit) 3550 return (sizeflag & AFLAG) ? "addr32" : "addr64"; 3551 else 3552 return (sizeflag & AFLAG) ? "addr16" : "addr32"; 3553 case FWAIT_OPCODE: 3554 return "fwait"; 3555 default: 3556 return NULL; 3557 } 3558} 3559 3560static char op_out[MAX_OPERANDS][100]; 3561static int op_ad, op_index[MAX_OPERANDS]; 3562static int two_source_ops; 3563static bfd_vma op_address[MAX_OPERANDS]; 3564static bfd_vma op_riprel[MAX_OPERANDS]; 3565static bfd_vma start_pc; 3566 3567/* 3568 * On the 386's of 1988, the maximum length of an instruction is 15 bytes. 3569 * (see topic "Redundant prefixes" in the "Differences from 8086" 3570 * section of the "Virtual 8086 Mode" chapter.) 3571 * 'pc' should be the address of this instruction, it will 3572 * be used to print the target address if this is a relative jump or call 3573 * The function returns the length of this instruction in bytes. 3574 */ 3575 3576static char intel_syntax; 3577static char open_char; 3578static char close_char; 3579static char separator_char; 3580static char scale_char; 3581 3582/* Here for backwards compatibility. When gdb stops using 3583 print_insn_i386_att and print_insn_i386_intel these functions can 3584 disappear, and print_insn_i386 be merged into print_insn. */ 3585int 3586print_insn_i386_att (bfd_vma pc, disassemble_info *info) 3587{ 3588 intel_syntax = 0; 3589 3590 return print_insn (pc, info); 3591} 3592 3593int 3594print_insn_i386_intel (bfd_vma pc, disassemble_info *info) 3595{ 3596 intel_syntax = 1; 3597 3598 return print_insn (pc, info); 3599} 3600 3601int 3602print_insn_i386 (bfd_vma pc, disassemble_info *info) 3603{ 3604 intel_syntax = -1; 3605 3606 return print_insn (pc, info); 3607} 3608 3609void 3610print_i386_disassembler_options (FILE *stream) 3611{ 3612 fprintf (stream, _("\n\ 3613The following i386/x86-64 specific disassembler options are supported for use\n\ 3614with the -M switch (multiple options should be separated by commas):\n")); 3615 3616 fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n")); 3617 fprintf (stream, _(" i386 Disassemble in 32bit mode\n")); 3618 fprintf (stream, _(" i8086 Disassemble in 16bit mode\n")); 3619 fprintf (stream, _(" att Display instruction in AT&T syntax\n")); 3620 fprintf (stream, _(" intel Display instruction in Intel syntax\n")); 3621 fprintf (stream, _(" addr64 Assume 64bit address size\n")); 3622 fprintf (stream, _(" addr32 Assume 32bit address size\n")); 3623 fprintf (stream, _(" addr16 Assume 16bit address size\n")); 3624 fprintf (stream, _(" data32 Assume 32bit data size\n")); 3625 fprintf (stream, _(" data16 Assume 16bit data size\n")); 3626 fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n")); 3627} 3628 3629/* Get a pointer to struct dis386 with a valid name. */ 3630 3631static const struct dis386 * 3632get_valid_dis386 (const struct dis386 *dp) 3633{ 3634 int index; 3635 3636 if (dp->name != NULL) 3637 return dp; 3638 3639 switch (dp->op[0].bytemode) 3640 { 3641 case USE_GROUPS: 3642 dp = &grps[dp->op[1].bytemode][modrm.reg]; 3643 break; 3644 3645 case USE_PREFIX_USER_TABLE: 3646 index = 0; 3647 used_prefixes |= (prefixes & PREFIX_REPZ); 3648 if (prefixes & PREFIX_REPZ) 3649 { 3650 index = 1; 3651 repz_prefix = NULL; 3652 } 3653 else 3654 { 3655 /* We should check PREFIX_REPNZ and PREFIX_REPZ before 3656 PREFIX_DATA. */ 3657 used_prefixes |= (prefixes & PREFIX_REPNZ); 3658 if (prefixes & PREFIX_REPNZ) 3659 { 3660 index = 3; 3661 repnz_prefix = NULL; 3662 } 3663 else 3664 { 3665 used_prefixes |= (prefixes & PREFIX_DATA); 3666 if (prefixes & PREFIX_DATA) 3667 { 3668 index = 2; 3669 data_prefix = NULL; 3670 } 3671 } 3672 } 3673 dp = &prefix_user_table[dp->op[1].bytemode][index]; 3674 break; 3675 3676 case X86_64_SPECIAL: 3677 index = address_mode == mode_64bit ? 1 : 0; 3678 dp = &x86_64_table[dp->op[1].bytemode][index]; 3679 break; 3680 3681 case USE_OPC_EXT_TABLE: 3682 index = modrm.mod == 0x3 ? 1 : 0; 3683 dp = &opc_ext_table[dp->op[1].bytemode][index]; 3684 break; 3685 3686 case USE_OPC_EXT_RM_TABLE: 3687 index = modrm.rm; 3688 dp = &opc_ext_rm_table[dp->op[1].bytemode][index]; 3689 break; 3690 3691 default: 3692 oappend (INTERNAL_DISASSEMBLER_ERROR); 3693 return NULL; 3694 } 3695 3696 if (dp->name != NULL) 3697 return dp; 3698 else 3699 return get_valid_dis386 (dp); 3700} 3701 3702static int 3703print_insn (bfd_vma pc, disassemble_info *info) 3704{ 3705 const struct dis386 *dp; 3706 int i; 3707 char *op_txt[MAX_OPERANDS]; 3708 int needcomma; 3709 int sizeflag; 3710 const char *p; 3711 struct dis_private priv; 3712 unsigned char op; 3713 char prefix_obuf[32]; 3714 char *prefix_obufp; 3715 3716 if (info->mach == bfd_mach_x86_64_intel_syntax 3717 || info->mach == bfd_mach_x86_64) 3718 address_mode = mode_64bit; 3719 else 3720 address_mode = mode_32bit; 3721 3722 if (intel_syntax == (char) -1) 3723 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax 3724 || info->mach == bfd_mach_x86_64_intel_syntax); 3725 3726 if (info->mach == bfd_mach_i386_i386 3727 || info->mach == bfd_mach_x86_64 3728 || info->mach == bfd_mach_i386_i386_intel_syntax 3729 || info->mach == bfd_mach_x86_64_intel_syntax) 3730 priv.orig_sizeflag = AFLAG | DFLAG; 3731 else if (info->mach == bfd_mach_i386_i8086) 3732 priv.orig_sizeflag = 0; 3733 else 3734 abort (); 3735 3736 for (p = info->disassembler_options; p != NULL; ) 3737 { 3738 if (CONST_STRNEQ (p, "x86-64")) 3739 { 3740 address_mode = mode_64bit; 3741 priv.orig_sizeflag = AFLAG | DFLAG; 3742 } 3743 else if (CONST_STRNEQ (p, "i386")) 3744 { 3745 address_mode = mode_32bit; 3746 priv.orig_sizeflag = AFLAG | DFLAG; 3747 } 3748 else if (CONST_STRNEQ (p, "i8086")) 3749 { 3750 address_mode = mode_16bit; 3751 priv.orig_sizeflag = 0; 3752 } 3753 else if (CONST_STRNEQ (p, "intel")) 3754 { 3755 intel_syntax = 1; 3756 } 3757 else if (CONST_STRNEQ (p, "att")) 3758 { 3759 intel_syntax = 0; 3760 } 3761 else if (CONST_STRNEQ (p, "addr")) 3762 { 3763 if (address_mode == mode_64bit) 3764 { 3765 if (p[4] == '3' && p[5] == '2') 3766 priv.orig_sizeflag &= ~AFLAG; 3767 else if (p[4] == '6' && p[5] == '4') 3768 priv.orig_sizeflag |= AFLAG; 3769 } 3770 else 3771 { 3772 if (p[4] == '1' && p[5] == '6') 3773 priv.orig_sizeflag &= ~AFLAG; 3774 else if (p[4] == '3' && p[5] == '2') 3775 priv.orig_sizeflag |= AFLAG; 3776 } 3777 } 3778 else if (CONST_STRNEQ (p, "data")) 3779 { 3780 if (p[4] == '1' && p[5] == '6') 3781 priv.orig_sizeflag &= ~DFLAG; 3782 else if (p[4] == '3' && p[5] == '2') 3783 priv.orig_sizeflag |= DFLAG; 3784 } 3785 else if (CONST_STRNEQ (p, "suffix")) 3786 priv.orig_sizeflag |= SUFFIX_ALWAYS; 3787 3788 p = strchr (p, ','); 3789 if (p != NULL) 3790 p++; 3791 } 3792 3793 if (intel_syntax) 3794 { 3795 names64 = intel_names64; 3796 names32 = intel_names32; 3797 names16 = intel_names16; 3798 names8 = intel_names8; 3799 names8rex = intel_names8rex; 3800 names_seg = intel_names_seg; 3801 index16 = intel_index16; 3802 open_char = '['; 3803 close_char = ']'; 3804 separator_char = '+'; 3805 scale_char = '*'; 3806 } 3807 else 3808 { 3809 names64 = att_names64; 3810 names32 = att_names32; 3811 names16 = att_names16; 3812 names8 = att_names8; 3813 names8rex = att_names8rex; 3814 names_seg = att_names_seg; 3815 index16 = att_index16; 3816 open_char = '('; 3817 close_char = ')'; 3818 separator_char = ','; 3819 scale_char = ','; 3820 } 3821 3822 /* The output looks better if we put 7 bytes on a line, since that 3823 puts most long word instructions on a single line. */ 3824 info->bytes_per_line = 7; 3825 3826 info->private_data = &priv; 3827 priv.max_fetched = priv.the_buffer; 3828 priv.insn_start = pc; 3829 3830 obuf[0] = 0; 3831 for (i = 0; i < MAX_OPERANDS; ++i) 3832 { 3833 op_out[i][0] = 0; 3834 op_index[i] = -1; 3835 } 3836 3837 the_info = info; 3838 start_pc = pc; 3839 start_codep = priv.the_buffer; 3840 codep = priv.the_buffer; 3841 3842 if (setjmp (priv.bailout) != 0) 3843 { 3844 const char *name; 3845 3846 /* Getting here means we tried for data but didn't get it. That 3847 means we have an incomplete instruction of some sort. Just 3848 print the first byte as a prefix or a .byte pseudo-op. */ 3849 if (codep > priv.the_buffer) 3850 { 3851 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 3852 if (name != NULL) 3853 (*info->fprintf_func) (info->stream, "%s", name); 3854 else 3855 { 3856 /* Just print the first byte as a .byte instruction. */ 3857 (*info->fprintf_func) (info->stream, ".byte 0x%x", 3858 (unsigned int) priv.the_buffer[0]); 3859 } 3860 3861 return 1; 3862 } 3863 3864 return -1; 3865 } 3866 3867 obufp = obuf; 3868 ckprefix (); 3869 3870 insn_codep = codep; 3871 sizeflag = priv.orig_sizeflag; 3872 3873 FETCH_DATA (info, codep + 1); 3874 two_source_ops = (*codep == 0x62) || (*codep == 0xc8); 3875 3876 if (((prefixes & PREFIX_FWAIT) 3877 && ((*codep < 0xd8) || (*codep > 0xdf))) 3878 || (rex && rex_used)) 3879 { 3880 const char *name; 3881 3882 /* fwait not followed by floating point instruction, or rex followed 3883 by other prefixes. Print the first prefix. */ 3884 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 3885 if (name == NULL) 3886 name = INTERNAL_DISASSEMBLER_ERROR; 3887 (*info->fprintf_func) (info->stream, "%s", name); 3888 return 1; 3889 } 3890 3891 op = 0; 3892 if (*codep == 0x0f) 3893 { 3894 unsigned char threebyte; 3895 FETCH_DATA (info, codep + 2); 3896 threebyte = *++codep; 3897 dp = &dis386_twobyte[threebyte]; 3898 need_modrm = twobyte_has_modrm[*codep]; 3899 codep++; 3900 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE) 3901 { 3902 FETCH_DATA (info, codep + 2); 3903 op = *codep++; 3904 } 3905 } 3906 else 3907 { 3908 dp = &dis386[*codep]; 3909 need_modrm = onebyte_has_modrm[*codep]; 3910 codep++; 3911 } 3912 3913 if ((prefixes & PREFIX_REPZ)) 3914 { 3915 repz_prefix = "repz "; 3916 used_prefixes |= PREFIX_REPZ; 3917 } 3918 else 3919 repz_prefix = NULL; 3920 3921 if ((prefixes & PREFIX_REPNZ)) 3922 { 3923 repnz_prefix = "repnz "; 3924 used_prefixes |= PREFIX_REPNZ; 3925 } 3926 else 3927 repnz_prefix = NULL; 3928 3929 if ((prefixes & PREFIX_LOCK)) 3930 { 3931 lock_prefix = "lock "; 3932 used_prefixes |= PREFIX_LOCK; 3933 } 3934 else 3935 lock_prefix = NULL; 3936 3937 addr_prefix = NULL; 3938 if (prefixes & PREFIX_ADDR) 3939 { 3940 sizeflag ^= AFLAG; 3941 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax) 3942 { 3943 if ((sizeflag & AFLAG) || address_mode == mode_64bit) 3944 addr_prefix = "addr32 "; 3945 else 3946 addr_prefix = "addr16 "; 3947 used_prefixes |= PREFIX_ADDR; 3948 } 3949 } 3950 3951 data_prefix = NULL; 3952 if ((prefixes & PREFIX_DATA)) 3953 { 3954 sizeflag ^= DFLAG; 3955 if (dp->op[2].bytemode == cond_jump_mode 3956 && dp->op[0].bytemode == v_mode 3957 && !intel_syntax) 3958 { 3959 if (sizeflag & DFLAG) 3960 data_prefix = "data32 "; 3961 else 3962 data_prefix = "data16 "; 3963 used_prefixes |= PREFIX_DATA; 3964 } 3965 } 3966 3967 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE) 3968 { 3969 dp = &three_byte_table[dp->op[1].bytemode][op]; 3970 modrm.mod = (*codep >> 6) & 3; 3971 modrm.reg = (*codep >> 3) & 7; 3972 modrm.rm = *codep & 7; 3973 } 3974 else if (need_modrm) 3975 { 3976 FETCH_DATA (info, codep + 1); 3977 modrm.mod = (*codep >> 6) & 3; 3978 modrm.reg = (*codep >> 3) & 7; 3979 modrm.rm = *codep & 7; 3980 } 3981 3982 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE) 3983 { 3984 dofloat (sizeflag); 3985 } 3986 else 3987 { 3988 dp = get_valid_dis386 (dp); 3989 if (dp != NULL && putop (dp->name, sizeflag) == 0) 3990 { 3991 for (i = 0; i < MAX_OPERANDS; ++i) 3992 { 3993 obufp = op_out[i]; 3994 op_ad = MAX_OPERANDS - 1 - i; 3995 if (dp->op[i].rtn) 3996 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag); 3997 } 3998 } 3999 } 4000 4001 /* See if any prefixes were not used. If so, print the first one 4002 separately. If we don't do this, we'll wind up printing an 4003 instruction stream which does not precisely correspond to the 4004 bytes we are disassembling. */ 4005 if ((prefixes & ~used_prefixes) != 0) 4006 { 4007 const char *name; 4008 4009 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 4010 if (name == NULL) 4011 name = INTERNAL_DISASSEMBLER_ERROR; 4012 (*info->fprintf_func) (info->stream, "%s", name); 4013 return 1; 4014 } 4015 if (rex & ~rex_used) 4016 { 4017 const char *name; 4018 name = prefix_name (rex | 0x40, priv.orig_sizeflag); 4019 if (name == NULL) 4020 name = INTERNAL_DISASSEMBLER_ERROR; 4021 (*info->fprintf_func) (info->stream, "%s ", name); 4022 } 4023 4024 prefix_obuf[0] = 0; 4025 prefix_obufp = prefix_obuf; 4026 if (lock_prefix) 4027 prefix_obufp = stpcpy (prefix_obufp, lock_prefix); 4028 if (repz_prefix) 4029 prefix_obufp = stpcpy (prefix_obufp, repz_prefix); 4030 if (repnz_prefix) 4031 prefix_obufp = stpcpy (prefix_obufp, repnz_prefix); 4032 if (addr_prefix) 4033 prefix_obufp = stpcpy (prefix_obufp, addr_prefix); 4034 if (data_prefix) 4035 prefix_obufp = stpcpy (prefix_obufp, data_prefix); 4036 4037 if (prefix_obuf[0] != 0) 4038 (*info->fprintf_func) (info->stream, "%s", prefix_obuf); 4039 4040 obufp = obuf + strlen (obuf); 4041 for (i = strlen (obuf) + strlen (prefix_obuf); i < 6; i++) 4042 oappend (" "); 4043 oappend (" "); 4044 (*info->fprintf_func) (info->stream, "%s", obuf); 4045 4046 /* The enter and bound instructions are printed with operands in the same 4047 order as the intel book; everything else is printed in reverse order. */ 4048 if (intel_syntax || two_source_ops) 4049 { 4050 bfd_vma riprel; 4051 4052 for (i = 0; i < MAX_OPERANDS; ++i) 4053 op_txt[i] = op_out[i]; 4054 4055 for (i = 0; i < (MAX_OPERANDS >> 1); ++i) 4056 { 4057 op_ad = op_index[i]; 4058 op_index[i] = op_index[MAX_OPERANDS - 1 - i]; 4059 op_index[MAX_OPERANDS - 1 - i] = op_ad; 4060 riprel = op_riprel[i]; 4061 op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i]; 4062 op_riprel[MAX_OPERANDS - 1 - i] = riprel; 4063 } 4064 } 4065 else 4066 { 4067 for (i = 0; i < MAX_OPERANDS; ++i) 4068 op_txt[MAX_OPERANDS - 1 - i] = op_out[i]; 4069 } 4070 4071 needcomma = 0; 4072 for (i = 0; i < MAX_OPERANDS; ++i) 4073 if (*op_txt[i]) 4074 { 4075 if (needcomma) 4076 (*info->fprintf_func) (info->stream, ","); 4077 if (op_index[i] != -1 && !op_riprel[i]) 4078 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info); 4079 else 4080 (*info->fprintf_func) (info->stream, "%s", op_txt[i]); 4081 needcomma = 1; 4082 } 4083 4084 for (i = 0; i < MAX_OPERANDS; i++) 4085 if (op_index[i] != -1 && op_riprel[i]) 4086 { 4087 (*info->fprintf_func) (info->stream, " # "); 4088 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep 4089 + op_address[op_index[i]]), info); 4090 break; 4091 } 4092 return codep - priv.the_buffer; 4093} 4094 4095static const char *float_mem[] = { 4096 /* d8 */ 4097 "fadd{s||s|}", 4098 "fmul{s||s|}", 4099 "fcom{s||s|}", 4100 "fcomp{s||s|}", 4101 "fsub{s||s|}", 4102 "fsubr{s||s|}", 4103 "fdiv{s||s|}", 4104 "fdivr{s||s|}", 4105 /* d9 */ 4106 "fld{s||s|}", 4107 "(bad)", 4108 "fst{s||s|}", 4109 "fstp{s||s|}", 4110 "fldenvIC", 4111 "fldcw", 4112 "fNstenvIC", 4113 "fNstcw", 4114 /* da */ 4115 "fiadd{l||l|}", 4116 "fimul{l||l|}", 4117 "ficom{l||l|}", 4118 "ficomp{l||l|}", 4119 "fisub{l||l|}", 4120 "fisubr{l||l|}", 4121 "fidiv{l||l|}", 4122 "fidivr{l||l|}", 4123 /* db */ 4124 "fild{l||l|}", 4125 "fisttp{l||l|}", 4126 "fist{l||l|}", 4127 "fistp{l||l|}", 4128 "(bad)", 4129 "fld{t||t|}", 4130 "(bad)", 4131 "fstp{t||t|}", 4132 /* dc */ 4133 "fadd{l||l|}", 4134 "fmul{l||l|}", 4135 "fcom{l||l|}", 4136 "fcomp{l||l|}", 4137 "fsub{l||l|}", 4138 "fsubr{l||l|}", 4139 "fdiv{l||l|}", 4140 "fdivr{l||l|}", 4141 /* dd */ 4142 "fld{l||l|}", 4143 "fisttp{ll||ll|}", 4144 "fst{l||l|}", 4145 "fstp{l||l|}", 4146 "frstorIC", 4147 "(bad)", 4148 "fNsaveIC", 4149 "fNstsw", 4150 /* de */ 4151 "fiadd", 4152 "fimul", 4153 "ficom", 4154 "ficomp", 4155 "fisub", 4156 "fisubr", 4157 "fidiv", 4158 "fidivr", 4159 /* df */ 4160 "fild", 4161 "fisttp", 4162 "fist", 4163 "fistp", 4164 "fbld", 4165 "fild{ll||ll|}", 4166 "fbstp", 4167 "fistp{ll||ll|}", 4168}; 4169 4170static const unsigned char float_mem_mode[] = { 4171 /* d8 */ 4172 d_mode, 4173 d_mode, 4174 d_mode, 4175 d_mode, 4176 d_mode, 4177 d_mode, 4178 d_mode, 4179 d_mode, 4180 /* d9 */ 4181 d_mode, 4182 0, 4183 d_mode, 4184 d_mode, 4185 0, 4186 w_mode, 4187 0, 4188 w_mode, 4189 /* da */ 4190 d_mode, 4191 d_mode, 4192 d_mode, 4193 d_mode, 4194 d_mode, 4195 d_mode, 4196 d_mode, 4197 d_mode, 4198 /* db */ 4199 d_mode, 4200 d_mode, 4201 d_mode, 4202 d_mode, 4203 0, 4204 t_mode, 4205 0, 4206 t_mode, 4207 /* dc */ 4208 q_mode, 4209 q_mode, 4210 q_mode, 4211 q_mode, 4212 q_mode, 4213 q_mode, 4214 q_mode, 4215 q_mode, 4216 /* dd */ 4217 q_mode, 4218 q_mode, 4219 q_mode, 4220 q_mode, 4221 0, 4222 0, 4223 0, 4224 w_mode, 4225 /* de */ 4226 w_mode, 4227 w_mode, 4228 w_mode, 4229 w_mode, 4230 w_mode, 4231 w_mode, 4232 w_mode, 4233 w_mode, 4234 /* df */ 4235 w_mode, 4236 w_mode, 4237 w_mode, 4238 w_mode, 4239 t_mode, 4240 q_mode, 4241 t_mode, 4242 q_mode 4243}; 4244 4245#define ST { OP_ST, 0 } 4246#define STi { OP_STi, 0 } 4247 4248#define FGRPd9_2 NULL, { { NULL, 0 } } 4249#define FGRPd9_4 NULL, { { NULL, 1 } } 4250#define FGRPd9_5 NULL, { { NULL, 2 } } 4251#define FGRPd9_6 NULL, { { NULL, 3 } } 4252#define FGRPd9_7 NULL, { { NULL, 4 } } 4253#define FGRPda_5 NULL, { { NULL, 5 } } 4254#define FGRPdb_4 NULL, { { NULL, 6 } } 4255#define FGRPde_3 NULL, { { NULL, 7 } } 4256#define FGRPdf_4 NULL, { { NULL, 8 } } 4257 4258static const struct dis386 float_reg[][8] = { 4259 /* d8 */ 4260 { 4261 { "fadd", { ST, STi } }, 4262 { "fmul", { ST, STi } }, 4263 { "fcom", { STi } }, 4264 { "fcomp", { STi } }, 4265 { "fsub", { ST, STi } }, 4266 { "fsubr", { ST, STi } }, 4267 { "fdiv", { ST, STi } }, 4268 { "fdivr", { ST, STi } }, 4269 }, 4270 /* d9 */ 4271 { 4272 { "fld", { STi } }, 4273 { "fxch", { STi } }, 4274 { FGRPd9_2 }, 4275 { "(bad)", { XX } }, 4276 { FGRPd9_4 }, 4277 { FGRPd9_5 }, 4278 { FGRPd9_6 }, 4279 { FGRPd9_7 }, 4280 }, 4281 /* da */ 4282 { 4283 { "fcmovb", { ST, STi } }, 4284 { "fcmove", { ST, STi } }, 4285 { "fcmovbe",{ ST, STi } }, 4286 { "fcmovu", { ST, STi } }, 4287 { "(bad)", { XX } }, 4288 { FGRPda_5 }, 4289 { "(bad)", { XX } }, 4290 { "(bad)", { XX } }, 4291 }, 4292 /* db */ 4293 { 4294 { "fcmovnb",{ ST, STi } }, 4295 { "fcmovne",{ ST, STi } }, 4296 { "fcmovnbe",{ ST, STi } }, 4297 { "fcmovnu",{ ST, STi } }, 4298 { FGRPdb_4 }, 4299 { "fucomi", { ST, STi } }, 4300 { "fcomi", { ST, STi } }, 4301 { "(bad)", { XX } }, 4302 }, 4303 /* dc */ 4304 { 4305 { "fadd", { STi, ST } }, 4306 { "fmul", { STi, ST } }, 4307 { "(bad)", { XX } }, 4308 { "(bad)", { XX } }, 4309#if SYSV386_COMPAT 4310 { "fsub", { STi, ST } }, 4311 { "fsubr", { STi, ST } }, 4312 { "fdiv", { STi, ST } }, 4313 { "fdivr", { STi, ST } }, 4314#else 4315 { "fsubr", { STi, ST } }, 4316 { "fsub", { STi, ST } }, 4317 { "fdivr", { STi, ST } }, 4318 { "fdiv", { STi, ST } }, 4319#endif 4320 }, 4321 /* dd */ 4322 { 4323 { "ffree", { STi } }, 4324 { "(bad)", { XX } }, 4325 { "fst", { STi } }, 4326 { "fstp", { STi } }, 4327 { "fucom", { STi } }, 4328 { "fucomp", { STi } }, 4329 { "(bad)", { XX } }, 4330 { "(bad)", { XX } }, 4331 }, 4332 /* de */ 4333 { 4334 { "faddp", { STi, ST } }, 4335 { "fmulp", { STi, ST } }, 4336 { "(bad)", { XX } }, 4337 { FGRPde_3 }, 4338#if SYSV386_COMPAT 4339 { "fsubp", { STi, ST } }, 4340 { "fsubrp", { STi, ST } }, 4341 { "fdivp", { STi, ST } }, 4342 { "fdivrp", { STi, ST } }, 4343#else 4344 { "fsubrp", { STi, ST } }, 4345 { "fsubp", { STi, ST } }, 4346 { "fdivrp", { STi, ST } }, 4347 { "fdivp", { STi, ST } }, 4348#endif 4349 }, 4350 /* df */ 4351 { 4352 { "ffreep", { STi } }, 4353 { "(bad)", { XX } }, 4354 { "(bad)", { XX } }, 4355 { "(bad)", { XX } }, 4356 { FGRPdf_4 }, 4357 { "fucomip", { ST, STi } }, 4358 { "fcomip", { ST, STi } }, 4359 { "(bad)", { XX } }, 4360 }, 4361}; 4362 4363static char *fgrps[][8] = { 4364 /* d9_2 0 */ 4365 { 4366 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 4367 }, 4368 4369 /* d9_4 1 */ 4370 { 4371 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", 4372 }, 4373 4374 /* d9_5 2 */ 4375 { 4376 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", 4377 }, 4378 4379 /* d9_6 3 */ 4380 { 4381 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", 4382 }, 4383 4384 /* d9_7 4 */ 4385 { 4386 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", 4387 }, 4388 4389 /* da_5 5 */ 4390 { 4391 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 4392 }, 4393 4394 /* db_4 6 */ 4395 { 4396 "feni(287 only)","fdisi(287 only)","fNclex","fNinit", 4397 "fNsetpm(287 only)","(bad)","(bad)","(bad)", 4398 }, 4399 4400 /* de_3 7 */ 4401 { 4402 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 4403 }, 4404 4405 /* df_4 8 */ 4406 { 4407 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 4408 }, 4409}; 4410 4411static void 4412OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED, 4413 int sizeflag ATTRIBUTE_UNUSED) 4414{ 4415 /* Skip mod/rm byte. */ 4416 MODRM_CHECK; 4417 codep++; 4418} 4419 4420static void 4421dofloat (int sizeflag) 4422{ 4423 const struct dis386 *dp; 4424 unsigned char floatop; 4425 4426 floatop = codep[-1]; 4427 4428 if (modrm.mod != 3) 4429 { 4430 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg; 4431 4432 putop (float_mem[fp_indx], sizeflag); 4433 obufp = op_out[0]; 4434 op_ad = 2; 4435 OP_E (float_mem_mode[fp_indx], sizeflag); 4436 return; 4437 } 4438 /* Skip mod/rm byte. */ 4439 MODRM_CHECK; 4440 codep++; 4441 4442 dp = &float_reg[floatop - 0xd8][modrm.reg]; 4443 if (dp->name == NULL) 4444 { 4445 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag); 4446 4447 /* Instruction fnstsw is only one with strange arg. */ 4448 if (floatop == 0xdf && codep[-1] == 0xe0) 4449 strcpy (op_out[0], names16[0]); 4450 } 4451 else 4452 { 4453 putop (dp->name, sizeflag); 4454 4455 obufp = op_out[0]; 4456 op_ad = 2; 4457 if (dp->op[0].rtn) 4458 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag); 4459 4460 obufp = op_out[1]; 4461 op_ad = 1; 4462 if (dp->op[1].rtn) 4463 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag); 4464 } 4465} 4466 4467static void 4468OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 4469{ 4470 oappend ("%st" + intel_syntax); 4471} 4472 4473static void 4474OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 4475{ 4476 sprintf (scratchbuf, "%%st(%d)", modrm.rm); 4477 oappend (scratchbuf + intel_syntax); 4478} 4479 4480/* Capital letters in template are macros. */ 4481static int 4482putop (const char *template, int sizeflag) 4483{ 4484 const char *p; 4485 int alt = 0; 4486 4487 for (p = template; *p; p++) 4488 { 4489 switch (*p) 4490 { 4491 default: 4492 *obufp++ = *p; 4493 break; 4494 case '{': 4495 alt = 0; 4496 if (intel_syntax) 4497 alt += 1; 4498 if (address_mode == mode_64bit) 4499 alt += 2; 4500 while (alt != 0) 4501 { 4502 while (*++p != '|') 4503 { 4504 if (*p == '}') 4505 { 4506 /* Alternative not valid. */ 4507 strcpy (obuf, "(bad)"); 4508 obufp = obuf + 5; 4509 return 1; 4510 } 4511 else if (*p == '\0') 4512 abort (); 4513 } 4514 alt--; 4515 } 4516 /* Fall through. */ 4517 case 'I': 4518 alt = 1; 4519 continue; 4520 case '|': 4521 while (*++p != '}') 4522 { 4523 if (*p == '\0') 4524 abort (); 4525 } 4526 break; 4527 case '}': 4528 break; 4529 case 'A': 4530 if (intel_syntax) 4531 break; 4532 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) 4533 *obufp++ = 'b'; 4534 break; 4535 case 'B': 4536 if (intel_syntax) 4537 break; 4538 if (sizeflag & SUFFIX_ALWAYS) 4539 *obufp++ = 'b'; 4540 break; 4541 case 'C': 4542 if (intel_syntax && !alt) 4543 break; 4544 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) 4545 { 4546 if (sizeflag & DFLAG) 4547 *obufp++ = intel_syntax ? 'd' : 'l'; 4548 else 4549 *obufp++ = intel_syntax ? 'w' : 's'; 4550 used_prefixes |= (prefixes & PREFIX_DATA); 4551 } 4552 break; 4553 case 'D': 4554 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS)) 4555 break; 4556 USED_REX (REX_W); 4557 if (modrm.mod == 3) 4558 { 4559 if (rex & REX_W) 4560 *obufp++ = 'q'; 4561 else if (sizeflag & DFLAG) 4562 *obufp++ = intel_syntax ? 'd' : 'l'; 4563 else 4564 *obufp++ = 'w'; 4565 used_prefixes |= (prefixes & PREFIX_DATA); 4566 } 4567 else 4568 *obufp++ = 'w'; 4569 break; 4570 case 'E': /* For jcxz/jecxz */ 4571 if (address_mode == mode_64bit) 4572 { 4573 if (sizeflag & AFLAG) 4574 *obufp++ = 'r'; 4575 else 4576 *obufp++ = 'e'; 4577 } 4578 else 4579 if (sizeflag & AFLAG) 4580 *obufp++ = 'e'; 4581 used_prefixes |= (prefixes & PREFIX_ADDR); 4582 break; 4583 case 'F': 4584 if (intel_syntax) 4585 break; 4586 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) 4587 { 4588 if (sizeflag & AFLAG) 4589 *obufp++ = address_mode == mode_64bit ? 'q' : 'l'; 4590 else 4591 *obufp++ = address_mode == mode_64bit ? 'l' : 'w'; 4592 used_prefixes |= (prefixes & PREFIX_ADDR); 4593 } 4594 break; 4595 case 'G': 4596 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS))) 4597 break; 4598 if ((rex & REX_W) || (sizeflag & DFLAG)) 4599 *obufp++ = 'l'; 4600 else 4601 *obufp++ = 'w'; 4602 if (!(rex & REX_W)) 4603 used_prefixes |= (prefixes & PREFIX_DATA); 4604 break; 4605 case 'H': 4606 if (intel_syntax) 4607 break; 4608 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS 4609 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS) 4610 { 4611 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS); 4612 *obufp++ = ','; 4613 *obufp++ = 'p'; 4614 if (prefixes & PREFIX_DS) 4615 *obufp++ = 't'; 4616 else 4617 *obufp++ = 'n'; 4618 } 4619 break; 4620 case 'J': 4621 if (intel_syntax) 4622 break; 4623 *obufp++ = 'l'; 4624 break; 4625 case 'K': 4626 USED_REX (REX_W); 4627 if (rex & REX_W) 4628 *obufp++ = 'q'; 4629 else 4630 *obufp++ = 'd'; 4631 break; 4632 case 'Z': 4633 if (intel_syntax) 4634 break; 4635 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS)) 4636 { 4637 *obufp++ = 'q'; 4638 break; 4639 } 4640 /* Fall through. */ 4641 case 'L': 4642 if (intel_syntax) 4643 break; 4644 if (sizeflag & SUFFIX_ALWAYS) 4645 *obufp++ = 'l'; 4646 break; 4647 case 'N': 4648 if ((prefixes & PREFIX_FWAIT) == 0) 4649 *obufp++ = 'n'; 4650 else 4651 used_prefixes |= PREFIX_FWAIT; 4652 break; 4653 case 'O': 4654 USED_REX (REX_W); 4655 if (rex & REX_W) 4656 *obufp++ = 'o'; 4657 else if (intel_syntax && (sizeflag & DFLAG)) 4658 *obufp++ = 'q'; 4659 else 4660 *obufp++ = 'd'; 4661 if (!(rex & REX_W)) 4662 used_prefixes |= (prefixes & PREFIX_DATA); 4663 break; 4664 case 'T': 4665 if (intel_syntax) 4666 break; 4667 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 4668 { 4669 *obufp++ = 'q'; 4670 break; 4671 } 4672 /* Fall through. */ 4673 case 'P': 4674 if (intel_syntax) 4675 break; 4676 if ((prefixes & PREFIX_DATA) 4677 || (rex & REX_W) 4678 || (sizeflag & SUFFIX_ALWAYS)) 4679 { 4680 USED_REX (REX_W); 4681 if (rex & REX_W) 4682 *obufp++ = 'q'; 4683 else 4684 { 4685 if (sizeflag & DFLAG) 4686 *obufp++ = 'l'; 4687 else 4688 *obufp++ = 'w'; 4689 } 4690 used_prefixes |= (prefixes & PREFIX_DATA); 4691 } 4692 break; 4693 case 'U': 4694 if (intel_syntax) 4695 break; 4696 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 4697 { 4698 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) 4699 *obufp++ = 'q'; 4700 break; 4701 } 4702 /* Fall through. */ 4703 case 'Q': 4704 if (intel_syntax && !alt) 4705 break; 4706 USED_REX (REX_W); 4707 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) 4708 { 4709 if (rex & REX_W) 4710 *obufp++ = 'q'; 4711 else 4712 { 4713 if (sizeflag & DFLAG) 4714 *obufp++ = intel_syntax ? 'd' : 'l'; 4715 else 4716 *obufp++ = 'w'; 4717 } 4718 used_prefixes |= (prefixes & PREFIX_DATA); 4719 } 4720 break; 4721 case 'R': 4722 USED_REX (REX_W); 4723 if (rex & REX_W) 4724 *obufp++ = 'q'; 4725 else if (sizeflag & DFLAG) 4726 { 4727 if (intel_syntax) 4728 *obufp++ = 'd'; 4729 else 4730 *obufp++ = 'l'; 4731 } 4732 else 4733 *obufp++ = 'w'; 4734 if (intel_syntax && !p[1] 4735 && ((rex & REX_W) || (sizeflag & DFLAG))) 4736 *obufp++ = 'e'; 4737 if (!(rex & REX_W)) 4738 used_prefixes |= (prefixes & PREFIX_DATA); 4739 break; 4740 case 'V': 4741 if (intel_syntax) 4742 break; 4743 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 4744 { 4745 if (sizeflag & SUFFIX_ALWAYS) 4746 *obufp++ = 'q'; 4747 break; 4748 } 4749 /* Fall through. */ 4750 case 'S': 4751 if (intel_syntax) 4752 break; 4753 if (sizeflag & SUFFIX_ALWAYS) 4754 { 4755 if (rex & REX_W) 4756 *obufp++ = 'q'; 4757 else 4758 { 4759 if (sizeflag & DFLAG) 4760 *obufp++ = 'l'; 4761 else 4762 *obufp++ = 'w'; 4763 used_prefixes |= (prefixes & PREFIX_DATA); 4764 } 4765 } 4766 break; 4767 case 'X': 4768 if (prefixes & PREFIX_DATA) 4769 *obufp++ = 'd'; 4770 else 4771 *obufp++ = 's'; 4772 used_prefixes |= (prefixes & PREFIX_DATA); 4773 break; 4774 case 'Y': 4775 if (intel_syntax) 4776 break; 4777 if (rex & REX_W) 4778 { 4779 USED_REX (REX_W); 4780 *obufp++ = 'q'; 4781 } 4782 break; 4783 /* implicit operand size 'l' for i386 or 'q' for x86-64 */ 4784 case 'W': 4785 /* operand size flag for cwtl, cbtw */ 4786 USED_REX (REX_W); 4787 if (rex & REX_W) 4788 { 4789 if (intel_syntax) 4790 *obufp++ = 'd'; 4791 else 4792 *obufp++ = 'l'; 4793 } 4794 else if (sizeflag & DFLAG) 4795 *obufp++ = 'w'; 4796 else 4797 *obufp++ = 'b'; 4798 if (!(rex & REX_W)) 4799 used_prefixes |= (prefixes & PREFIX_DATA); 4800 break; 4801 } 4802 alt = 0; 4803 } 4804 *obufp = 0; 4805 return 0; 4806} 4807 4808static void 4809oappend (const char *s) 4810{ 4811 strcpy (obufp, s); 4812 obufp += strlen (s); 4813} 4814 4815static void 4816append_seg (void) 4817{ 4818 if (prefixes & PREFIX_CS) 4819 { 4820 used_prefixes |= PREFIX_CS; 4821 oappend ("%cs:" + intel_syntax); 4822 } 4823 if (prefixes & PREFIX_DS) 4824 { 4825 used_prefixes |= PREFIX_DS; 4826 oappend ("%ds:" + intel_syntax); 4827 } 4828 if (prefixes & PREFIX_SS) 4829 { 4830 used_prefixes |= PREFIX_SS; 4831 oappend ("%ss:" + intel_syntax); 4832 } 4833 if (prefixes & PREFIX_ES) 4834 { 4835 used_prefixes |= PREFIX_ES; 4836 oappend ("%es:" + intel_syntax); 4837 } 4838 if (prefixes & PREFIX_FS) 4839 { 4840 used_prefixes |= PREFIX_FS; 4841 oappend ("%fs:" + intel_syntax); 4842 } 4843 if (prefixes & PREFIX_GS) 4844 { 4845 used_prefixes |= PREFIX_GS; 4846 oappend ("%gs:" + intel_syntax); 4847 } 4848} 4849 4850static void 4851OP_indirE (int bytemode, int sizeflag) 4852{ 4853 if (!intel_syntax) 4854 oappend ("*"); 4855 OP_E (bytemode, sizeflag); 4856} 4857 4858static void 4859print_operand_value (char *buf, int hex, bfd_vma disp) 4860{ 4861 if (address_mode == mode_64bit) 4862 { 4863 if (hex) 4864 { 4865 char tmp[30]; 4866 int i; 4867 buf[0] = '0'; 4868 buf[1] = 'x'; 4869 sprintf_vma (tmp, disp); 4870 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++); 4871 strcpy (buf + 2, tmp + i); 4872 } 4873 else 4874 { 4875 bfd_signed_vma v = disp; 4876 char tmp[30]; 4877 int i; 4878 if (v < 0) 4879 { 4880 *(buf++) = '-'; 4881 v = -disp; 4882 /* Check for possible overflow on 0x8000000000000000. */ 4883 if (v < 0) 4884 { 4885 strcpy (buf, "9223372036854775808"); 4886 return; 4887 } 4888 } 4889 if (!v) 4890 { 4891 strcpy (buf, "0"); 4892 return; 4893 } 4894 4895 i = 0; 4896 tmp[29] = 0; 4897 while (v) 4898 { 4899 tmp[28 - i] = (v % 10) + '0'; 4900 v /= 10; 4901 i++; 4902 } 4903 strcpy (buf, tmp + 29 - i); 4904 } 4905 } 4906 else 4907 { 4908 if (hex) 4909 sprintf (buf, "0x%x", (unsigned int) disp); 4910 else 4911 sprintf (buf, "%d", (int) disp); 4912 } 4913} 4914 4915/* Put DISP in BUF as signed hex number. */ 4916 4917static void 4918print_displacement (char *buf, bfd_vma disp) 4919{ 4920 bfd_signed_vma val = disp; 4921 char tmp[30]; 4922 int i, j = 0; 4923 4924 if (val < 0) 4925 { 4926 buf[j++] = '-'; 4927 val = -disp; 4928 4929 /* Check for possible overflow. */ 4930 if (val < 0) 4931 { 4932 switch (address_mode) 4933 { 4934 case mode_64bit: 4935 strcpy (buf + j, "0x8000000000000000"); 4936 break; 4937 case mode_32bit: 4938 strcpy (buf + j, "0x80000000"); 4939 break; 4940 case mode_16bit: 4941 strcpy (buf + j, "0x8000"); 4942 break; 4943 } 4944 return; 4945 } 4946 } 4947 4948 buf[j++] = '0'; 4949 buf[j++] = 'x'; 4950 4951 sprintf_vma (tmp, val); 4952 for (i = 0; tmp[i] == '0'; i++) 4953 continue; 4954 if (tmp[i] == '\0') 4955 i--; 4956 strcpy (buf + j, tmp + i); 4957} 4958 4959static void 4960intel_operand_size (int bytemode, int sizeflag) 4961{ 4962 switch (bytemode) 4963 { 4964 case b_mode: 4965 case dqb_mode: 4966 oappend ("BYTE PTR "); 4967 break; 4968 case w_mode: 4969 case dqw_mode: 4970 oappend ("WORD PTR "); 4971 break; 4972 case stack_v_mode: 4973 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 4974 { 4975 oappend ("QWORD PTR "); 4976 used_prefixes |= (prefixes & PREFIX_DATA); 4977 break; 4978 } 4979 /* FALLTHRU */ 4980 case v_mode: 4981 case dq_mode: 4982 USED_REX (REX_W); 4983 if (rex & REX_W) 4984 oappend ("QWORD PTR "); 4985 else if ((sizeflag & DFLAG) || bytemode == dq_mode) 4986 oappend ("DWORD PTR "); 4987 else 4988 oappend ("WORD PTR "); 4989 used_prefixes |= (prefixes & PREFIX_DATA); 4990 break; 4991 case z_mode: 4992 if ((rex & REX_W) || (sizeflag & DFLAG)) 4993 *obufp++ = 'D'; 4994 oappend ("WORD PTR "); 4995 if (!(rex & REX_W)) 4996 used_prefixes |= (prefixes & PREFIX_DATA); 4997 break; 4998 case d_mode: 4999 case dqd_mode: 5000 oappend ("DWORD PTR "); 5001 break; 5002 case q_mode: 5003 oappend ("QWORD PTR "); 5004 break; 5005 case m_mode: 5006 if (address_mode == mode_64bit) 5007 oappend ("QWORD PTR "); 5008 else 5009 oappend ("DWORD PTR "); 5010 break; 5011 case f_mode: 5012 if (sizeflag & DFLAG) 5013 oappend ("FWORD PTR "); 5014 else 5015 oappend ("DWORD PTR "); 5016 used_prefixes |= (prefixes & PREFIX_DATA); 5017 break; 5018 case t_mode: 5019 oappend ("TBYTE PTR "); 5020 break; 5021 case x_mode: 5022 oappend ("XMMWORD PTR "); 5023 break; 5024 case o_mode: 5025 oappend ("OWORD PTR "); 5026 break; 5027 default: 5028 break; 5029 } 5030} 5031 5032static void 5033OP_E (int bytemode, int sizeflag) 5034{ 5035 bfd_vma disp; 5036 int add = 0; 5037 int riprel = 0; 5038 USED_REX (REX_B); 5039 if (rex & REX_B) 5040 add += 8; 5041 5042 /* Skip mod/rm byte. */ 5043 MODRM_CHECK; 5044 codep++; 5045 5046 if (modrm.mod == 3) 5047 { 5048 switch (bytemode) 5049 { 5050 case b_mode: 5051 USED_REX (0); 5052 if (rex) 5053 oappend (names8rex[modrm.rm + add]); 5054 else 5055 oappend (names8[modrm.rm + add]); 5056 break; 5057 case w_mode: 5058 oappend (names16[modrm.rm + add]); 5059 break; 5060 case d_mode: 5061 oappend (names32[modrm.rm + add]); 5062 break; 5063 case q_mode: 5064 oappend (names64[modrm.rm + add]); 5065 break; 5066 case m_mode: 5067 if (address_mode == mode_64bit) 5068 oappend (names64[modrm.rm + add]); 5069 else 5070 oappend (names32[modrm.rm + add]); 5071 break; 5072 case stack_v_mode: 5073 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 5074 { 5075 oappend (names64[modrm.rm + add]); 5076 used_prefixes |= (prefixes & PREFIX_DATA); 5077 break; 5078 } 5079 bytemode = v_mode; 5080 /* FALLTHRU */ 5081 case v_mode: 5082 case dq_mode: 5083 case dqb_mode: 5084 case dqd_mode: 5085 case dqw_mode: 5086 USED_REX (REX_W); 5087 if (rex & REX_W) 5088 oappend (names64[modrm.rm + add]); 5089 else if ((sizeflag & DFLAG) || bytemode != v_mode) 5090 oappend (names32[modrm.rm + add]); 5091 else 5092 oappend (names16[modrm.rm + add]); 5093 used_prefixes |= (prefixes & PREFIX_DATA); 5094 break; 5095 case 0: 5096 break; 5097 default: 5098 oappend (INTERNAL_DISASSEMBLER_ERROR); 5099 break; 5100 } 5101 return; 5102 } 5103 5104 disp = 0; 5105 if (intel_syntax) 5106 intel_operand_size (bytemode, sizeflag); 5107 append_seg (); 5108 5109 if ((sizeflag & AFLAG) || address_mode == mode_64bit) 5110 { 5111 /* 32/64 bit address mode */ 5112 int havedisp; 5113 int havesib; 5114 int havebase; 5115 int base; 5116 int index = 0; 5117 int scale = 0; 5118 5119 havesib = 0; 5120 havebase = 1; 5121 base = modrm.rm; 5122 5123 if (base == 4) 5124 { 5125 havesib = 1; 5126 FETCH_DATA (the_info, codep + 1); 5127 index = (*codep >> 3) & 7; 5128 if (address_mode == mode_64bit || index != 0x4) 5129 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */ 5130 scale = (*codep >> 6) & 3; 5131 base = *codep & 7; 5132 USED_REX (REX_X); 5133 if (rex & REX_X) 5134 index += 8; 5135 codep++; 5136 } 5137 base += add; 5138 5139 switch (modrm.mod) 5140 { 5141 case 0: 5142 if ((base & 7) == 5) 5143 { 5144 havebase = 0; 5145 if (address_mode == mode_64bit && !havesib) 5146 riprel = 1; 5147 disp = get32s (); 5148 } 5149 break; 5150 case 1: 5151 FETCH_DATA (the_info, codep + 1); 5152 disp = *codep++; 5153 if ((disp & 0x80) != 0) 5154 disp -= 0x100; 5155 break; 5156 case 2: 5157 disp = get32s (); 5158 break; 5159 } 5160 5161 havedisp = havebase || (havesib && (index != 4 || scale != 0)); 5162 5163 if (!intel_syntax) 5164 if (modrm.mod != 0 || (base & 7) == 5) 5165 { 5166 if (havedisp || riprel) 5167 print_displacement (scratchbuf, disp); 5168 else 5169 print_operand_value (scratchbuf, 1, disp); 5170 oappend (scratchbuf); 5171 if (riprel) 5172 { 5173 set_op (disp, 1); 5174 oappend ("(%rip)"); 5175 } 5176 } 5177 5178 if (havedisp || (intel_syntax && riprel)) 5179 { 5180 *obufp++ = open_char; 5181 if (intel_syntax && riprel) 5182 { 5183 set_op (disp, 1); 5184 oappend ("rip"); 5185 } 5186 *obufp = '\0'; 5187 if (havebase) 5188 oappend (address_mode == mode_64bit && (sizeflag & AFLAG) 5189 ? names64[base] : names32[base]); 5190 if (havesib) 5191 { 5192 if (index != 4) 5193 { 5194 if (!intel_syntax || havebase) 5195 { 5196 *obufp++ = separator_char; 5197 *obufp = '\0'; 5198 } 5199 oappend (address_mode == mode_64bit && (sizeflag & AFLAG) 5200 ? names64[index] : names32[index]); 5201 } 5202 if (scale != 0 || (!intel_syntax && index != 4)) 5203 { 5204 *obufp++ = scale_char; 5205 *obufp = '\0'; 5206 sprintf (scratchbuf, "%d", 1 << scale); 5207 oappend (scratchbuf); 5208 } 5209 } 5210 if (intel_syntax 5211 && (disp || modrm.mod != 0 || (base & 7) == 5)) 5212 { 5213 if ((bfd_signed_vma) disp >= 0) 5214 { 5215 *obufp++ = '+'; 5216 *obufp = '\0'; 5217 } 5218 else if (modrm.mod != 1) 5219 { 5220 *obufp++ = '-'; 5221 *obufp = '\0'; 5222 disp = - (bfd_signed_vma) disp; 5223 } 5224 5225 print_displacement (scratchbuf, disp); 5226 oappend (scratchbuf); 5227 } 5228 5229 *obufp++ = close_char; 5230 *obufp = '\0'; 5231 } 5232 else if (intel_syntax) 5233 { 5234 if (modrm.mod != 0 || (base & 7) == 5) 5235 { 5236 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 5237 | PREFIX_ES | PREFIX_FS | PREFIX_GS)) 5238 ; 5239 else 5240 { 5241 oappend (names_seg[ds_reg - es_reg]); 5242 oappend (":"); 5243 } 5244 print_operand_value (scratchbuf, 1, disp); 5245 oappend (scratchbuf); 5246 } 5247 } 5248 } 5249 else 5250 { /* 16 bit address mode */ 5251 switch (modrm.mod) 5252 { 5253 case 0: 5254 if (modrm.rm == 6) 5255 { 5256 disp = get16 (); 5257 if ((disp & 0x8000) != 0) 5258 disp -= 0x10000; 5259 } 5260 break; 5261 case 1: 5262 FETCH_DATA (the_info, codep + 1); 5263 disp = *codep++; 5264 if ((disp & 0x80) != 0) 5265 disp -= 0x100; 5266 break; 5267 case 2: 5268 disp = get16 (); 5269 if ((disp & 0x8000) != 0) 5270 disp -= 0x10000; 5271 break; 5272 } 5273 5274 if (!intel_syntax) 5275 if (modrm.mod != 0 || modrm.rm == 6) 5276 { 5277 print_displacement (scratchbuf, disp); 5278 oappend (scratchbuf); 5279 } 5280 5281 if (modrm.mod != 0 || modrm.rm != 6) 5282 { 5283 *obufp++ = open_char; 5284 *obufp = '\0'; 5285 oappend (index16[modrm.rm]); 5286 if (intel_syntax 5287 && (disp || modrm.mod != 0 || modrm.rm == 6)) 5288 { 5289 if ((bfd_signed_vma) disp >= 0) 5290 { 5291 *obufp++ = '+'; 5292 *obufp = '\0'; 5293 } 5294 else if (modrm.mod != 1) 5295 { 5296 *obufp++ = '-'; 5297 *obufp = '\0'; 5298 disp = - (bfd_signed_vma) disp; 5299 } 5300 5301 print_displacement (scratchbuf, disp); 5302 oappend (scratchbuf); 5303 } 5304 5305 *obufp++ = close_char; 5306 *obufp = '\0'; 5307 } 5308 else if (intel_syntax) 5309 { 5310 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 5311 | PREFIX_ES | PREFIX_FS | PREFIX_GS)) 5312 ; 5313 else 5314 { 5315 oappend (names_seg[ds_reg - es_reg]); 5316 oappend (":"); 5317 } 5318 print_operand_value (scratchbuf, 1, disp & 0xffff); 5319 oappend (scratchbuf); 5320 } 5321 } 5322} 5323 5324static void 5325OP_G (int bytemode, int sizeflag) 5326{ 5327 int add = 0; 5328 USED_REX (REX_R); 5329 if (rex & REX_R) 5330 add += 8; 5331 switch (bytemode) 5332 { 5333 case b_mode: 5334 USED_REX (0); 5335 if (rex) 5336 oappend (names8rex[modrm.reg + add]); 5337 else 5338 oappend (names8[modrm.reg + add]); 5339 break; 5340 case w_mode: 5341 oappend (names16[modrm.reg + add]); 5342 break; 5343 case d_mode: 5344 oappend (names32[modrm.reg + add]); 5345 break; 5346 case q_mode: 5347 oappend (names64[modrm.reg + add]); 5348 break; 5349 case v_mode: 5350 case dq_mode: 5351 case dqb_mode: 5352 case dqd_mode: 5353 case dqw_mode: 5354 USED_REX (REX_W); 5355 if (rex & REX_W) 5356 oappend (names64[modrm.reg + add]); 5357 else if ((sizeflag & DFLAG) || bytemode != v_mode) 5358 oappend (names32[modrm.reg + add]); 5359 else 5360 oappend (names16[modrm.reg + add]); 5361 used_prefixes |= (prefixes & PREFIX_DATA); 5362 break; 5363 case m_mode: 5364 if (address_mode == mode_64bit) 5365 oappend (names64[modrm.reg + add]); 5366 else 5367 oappend (names32[modrm.reg + add]); 5368 break; 5369 default: 5370 oappend (INTERNAL_DISASSEMBLER_ERROR); 5371 break; 5372 } 5373} 5374 5375static bfd_vma 5376get64 (void) 5377{ 5378 bfd_vma x; 5379#ifdef BFD64 5380 unsigned int a; 5381 unsigned int b; 5382 5383 FETCH_DATA (the_info, codep + 8); 5384 a = *codep++ & 0xff; 5385 a |= (*codep++ & 0xff) << 8; 5386 a |= (*codep++ & 0xff) << 16; 5387 a |= (*codep++ & 0xff) << 24; 5388 b = *codep++ & 0xff; 5389 b |= (*codep++ & 0xff) << 8; 5390 b |= (*codep++ & 0xff) << 16; 5391 b |= (*codep++ & 0xff) << 24; 5392 x = a + ((bfd_vma) b << 32); 5393#else 5394 abort (); 5395 x = 0; 5396#endif 5397 return x; 5398} 5399 5400static bfd_signed_vma 5401get32 (void) 5402{ 5403 bfd_signed_vma x = 0; 5404 5405 FETCH_DATA (the_info, codep + 4); 5406 x = *codep++ & (bfd_signed_vma) 0xff; 5407 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; 5408 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; 5409 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; 5410 return x; 5411} 5412 5413static bfd_signed_vma 5414get32s (void) 5415{ 5416 bfd_signed_vma x = 0; 5417 5418 FETCH_DATA (the_info, codep + 4); 5419 x = *codep++ & (bfd_signed_vma) 0xff; 5420 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; 5421 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; 5422 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; 5423 5424 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31); 5425 5426 return x; 5427} 5428 5429static int 5430get16 (void) 5431{ 5432 int x = 0; 5433 5434 FETCH_DATA (the_info, codep + 2); 5435 x = *codep++ & 0xff; 5436 x |= (*codep++ & 0xff) << 8; 5437 return x; 5438} 5439 5440static void 5441set_op (bfd_vma op, int riprel) 5442{ 5443 op_index[op_ad] = op_ad; 5444 if (address_mode == mode_64bit) 5445 { 5446 op_address[op_ad] = op; 5447 op_riprel[op_ad] = riprel; 5448 } 5449 else 5450 { 5451 /* Mask to get a 32-bit address. */ 5452 op_address[op_ad] = op & 0xffffffff; 5453 op_riprel[op_ad] = riprel & 0xffffffff; 5454 } 5455} 5456 5457static void 5458OP_REG (int code, int sizeflag) 5459{ 5460 const char *s; 5461 int add = 0; 5462 USED_REX (REX_B); 5463 if (rex & REX_B) 5464 add = 8; 5465 5466 switch (code) 5467 { 5468 case ax_reg: case cx_reg: case dx_reg: case bx_reg: 5469 case sp_reg: case bp_reg: case si_reg: case di_reg: 5470 s = names16[code - ax_reg + add]; 5471 break; 5472 case es_reg: case ss_reg: case cs_reg: 5473 case ds_reg: case fs_reg: case gs_reg: 5474 s = names_seg[code - es_reg + add]; 5475 break; 5476 case al_reg: case ah_reg: case cl_reg: case ch_reg: 5477 case dl_reg: case dh_reg: case bl_reg: case bh_reg: 5478 USED_REX (0); 5479 if (rex) 5480 s = names8rex[code - al_reg + add]; 5481 else 5482 s = names8[code - al_reg]; 5483 break; 5484 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: 5485 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: 5486 if (address_mode == mode_64bit && (sizeflag & DFLAG)) 5487 { 5488 s = names64[code - rAX_reg + add]; 5489 break; 5490 } 5491 code += eAX_reg - rAX_reg; 5492 /* Fall through. */ 5493 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: 5494 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: 5495 USED_REX (REX_W); 5496 if (rex & REX_W) 5497 s = names64[code - eAX_reg + add]; 5498 else if (sizeflag & DFLAG) 5499 s = names32[code - eAX_reg + add]; 5500 else 5501 s = names16[code - eAX_reg + add]; 5502 used_prefixes |= (prefixes & PREFIX_DATA); 5503 break; 5504 default: 5505 s = INTERNAL_DISASSEMBLER_ERROR; 5506 break; 5507 } 5508 oappend (s); 5509} 5510 5511static void 5512OP_IMREG (int code, int sizeflag) 5513{ 5514 const char *s; 5515 5516 switch (code) 5517 { 5518 case indir_dx_reg: 5519 if (intel_syntax) 5520 s = "dx"; 5521 else 5522 s = "(%dx)"; 5523 break; 5524 case ax_reg: case cx_reg: case dx_reg: case bx_reg: 5525 case sp_reg: case bp_reg: case si_reg: case di_reg: 5526 s = names16[code - ax_reg]; 5527 break; 5528 case es_reg: case ss_reg: case cs_reg: 5529 case ds_reg: case fs_reg: case gs_reg: 5530 s = names_seg[code - es_reg]; 5531 break; 5532 case al_reg: case ah_reg: case cl_reg: case ch_reg: 5533 case dl_reg: case dh_reg: case bl_reg: case bh_reg: 5534 USED_REX (0); 5535 if (rex) 5536 s = names8rex[code - al_reg]; 5537 else 5538 s = names8[code - al_reg]; 5539 break; 5540 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: 5541 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: 5542 USED_REX (REX_W); 5543 if (rex & REX_W) 5544 s = names64[code - eAX_reg]; 5545 else if (sizeflag & DFLAG) 5546 s = names32[code - eAX_reg]; 5547 else 5548 s = names16[code - eAX_reg]; 5549 used_prefixes |= (prefixes & PREFIX_DATA); 5550 break; 5551 case z_mode_ax_reg: 5552 if ((rex & REX_W) || (sizeflag & DFLAG)) 5553 s = *names32; 5554 else 5555 s = *names16; 5556 if (!(rex & REX_W)) 5557 used_prefixes |= (prefixes & PREFIX_DATA); 5558 break; 5559 default: 5560 s = INTERNAL_DISASSEMBLER_ERROR; 5561 break; 5562 } 5563 oappend (s); 5564} 5565 5566static void 5567OP_I (int bytemode, int sizeflag) 5568{ 5569 bfd_signed_vma op; 5570 bfd_signed_vma mask = -1; 5571 5572 switch (bytemode) 5573 { 5574 case b_mode: 5575 FETCH_DATA (the_info, codep + 1); 5576 op = *codep++; 5577 mask = 0xff; 5578 break; 5579 case q_mode: 5580 if (address_mode == mode_64bit) 5581 { 5582 op = get32s (); 5583 break; 5584 } 5585 /* Fall through. */ 5586 case v_mode: 5587 USED_REX (REX_W); 5588 if (rex & REX_W) 5589 op = get32s (); 5590 else if (sizeflag & DFLAG) 5591 { 5592 op = get32 (); 5593 mask = 0xffffffff; 5594 } 5595 else 5596 { 5597 op = get16 (); 5598 mask = 0xfffff; 5599 } 5600 used_prefixes |= (prefixes & PREFIX_DATA); 5601 break; 5602 case w_mode: 5603 mask = 0xfffff; 5604 op = get16 (); 5605 break; 5606 case const_1_mode: 5607 if (intel_syntax) 5608 oappend ("1"); 5609 return; 5610 default: 5611 oappend (INTERNAL_DISASSEMBLER_ERROR); 5612 return; 5613 } 5614 5615 op &= mask; 5616 scratchbuf[0] = '$'; 5617 print_operand_value (scratchbuf + 1, 1, op); 5618 oappend (scratchbuf + intel_syntax); 5619 scratchbuf[0] = '\0'; 5620} 5621 5622static void 5623OP_I64 (int bytemode, int sizeflag) 5624{ 5625 bfd_signed_vma op; 5626 bfd_signed_vma mask = -1; 5627 5628 if (address_mode != mode_64bit) 5629 { 5630 OP_I (bytemode, sizeflag); 5631 return; 5632 } 5633 5634 switch (bytemode) 5635 { 5636 case b_mode: 5637 FETCH_DATA (the_info, codep + 1); 5638 op = *codep++; 5639 mask = 0xff; 5640 break; 5641 case v_mode: 5642 USED_REX (REX_W); 5643 if (rex & REX_W) 5644 op = get64 (); 5645 else if (sizeflag & DFLAG) 5646 { 5647 op = get32 (); 5648 mask = 0xffffffff; 5649 } 5650 else 5651 { 5652 op = get16 (); 5653 mask = 0xfffff; 5654 } 5655 used_prefixes |= (prefixes & PREFIX_DATA); 5656 break; 5657 case w_mode: 5658 mask = 0xfffff; 5659 op = get16 (); 5660 break; 5661 default: 5662 oappend (INTERNAL_DISASSEMBLER_ERROR); 5663 return; 5664 } 5665 5666 op &= mask; 5667 scratchbuf[0] = '$'; 5668 print_operand_value (scratchbuf + 1, 1, op); 5669 oappend (scratchbuf + intel_syntax); 5670 scratchbuf[0] = '\0'; 5671} 5672 5673static void 5674OP_sI (int bytemode, int sizeflag) 5675{ 5676 bfd_signed_vma op; 5677 bfd_signed_vma mask = -1; 5678 5679 switch (bytemode) 5680 { 5681 case b_mode: 5682 FETCH_DATA (the_info, codep + 1); 5683 op = *codep++; 5684 if ((op & 0x80) != 0) 5685 op -= 0x100; 5686 mask = 0xffffffff; 5687 break; 5688 case v_mode: 5689 USED_REX (REX_W); 5690 if (rex & REX_W) 5691 op = get32s (); 5692 else if (sizeflag & DFLAG) 5693 { 5694 op = get32s (); 5695 mask = 0xffffffff; 5696 } 5697 else 5698 { 5699 mask = 0xffffffff; 5700 op = get16 (); 5701 if ((op & 0x8000) != 0) 5702 op -= 0x10000; 5703 } 5704 used_prefixes |= (prefixes & PREFIX_DATA); 5705 break; 5706 case w_mode: 5707 op = get16 (); 5708 mask = 0xffffffff; 5709 if ((op & 0x8000) != 0) 5710 op -= 0x10000; 5711 break; 5712 default: 5713 oappend (INTERNAL_DISASSEMBLER_ERROR); 5714 return; 5715 } 5716 5717 scratchbuf[0] = '$'; 5718 print_operand_value (scratchbuf + 1, 1, op); 5719 oappend (scratchbuf + intel_syntax); 5720} 5721 5722static void 5723OP_J (int bytemode, int sizeflag) 5724{ 5725 bfd_vma disp; 5726 bfd_vma mask = -1; 5727 bfd_vma segment = 0; 5728 5729 switch (bytemode) 5730 { 5731 case b_mode: 5732 FETCH_DATA (the_info, codep + 1); 5733 disp = *codep++; 5734 if ((disp & 0x80) != 0) 5735 disp -= 0x100; 5736 break; 5737 case v_mode: 5738 if ((sizeflag & DFLAG) || (rex & REX_W)) 5739 disp = get32s (); 5740 else 5741 { 5742 disp = get16 (); 5743 if ((disp & 0x8000) != 0) 5744 disp -= 0x10000; 5745 /* In 16bit mode, address is wrapped around at 64k within 5746 the same segment. Otherwise, a data16 prefix on a jump 5747 instruction means that the pc is masked to 16 bits after 5748 the displacement is added! */ 5749 mask = 0xffff; 5750 if ((prefixes & PREFIX_DATA) == 0) 5751 segment = ((start_pc + codep - start_codep) 5752 & ~((bfd_vma) 0xffff)); 5753 } 5754 used_prefixes |= (prefixes & PREFIX_DATA); 5755 break; 5756 default: 5757 oappend (INTERNAL_DISASSEMBLER_ERROR); 5758 return; 5759 } 5760 disp = ((start_pc + codep - start_codep + disp) & mask) | segment; 5761 set_op (disp, 0); 5762 print_operand_value (scratchbuf, 1, disp); 5763 oappend (scratchbuf); 5764} 5765 5766static void 5767OP_SEG (int bytemode, int sizeflag) 5768{ 5769 if (bytemode == w_mode) 5770 oappend (names_seg[modrm.reg]); 5771 else 5772 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag); 5773} 5774 5775static void 5776OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag) 5777{ 5778 int seg, offset; 5779 5780 if (sizeflag & DFLAG) 5781 { 5782 offset = get32 (); 5783 seg = get16 (); 5784 } 5785 else 5786 { 5787 offset = get16 (); 5788 seg = get16 (); 5789 } 5790 used_prefixes |= (prefixes & PREFIX_DATA); 5791 if (intel_syntax) 5792 sprintf (scratchbuf, "0x%x:0x%x", seg, offset); 5793 else 5794 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); 5795 oappend (scratchbuf); 5796} 5797 5798static void 5799OP_OFF (int bytemode, int sizeflag) 5800{ 5801 bfd_vma off; 5802 5803 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS)) 5804 intel_operand_size (bytemode, sizeflag); 5805 append_seg (); 5806 5807 if ((sizeflag & AFLAG) || address_mode == mode_64bit) 5808 off = get32 (); 5809 else 5810 off = get16 (); 5811 5812 if (intel_syntax) 5813 { 5814 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 5815 | PREFIX_ES | PREFIX_FS | PREFIX_GS))) 5816 { 5817 oappend (names_seg[ds_reg - es_reg]); 5818 oappend (":"); 5819 } 5820 } 5821 print_operand_value (scratchbuf, 1, off); 5822 oappend (scratchbuf); 5823} 5824 5825static void 5826OP_OFF64 (int bytemode, int sizeflag) 5827{ 5828 bfd_vma off; 5829 5830 if (address_mode != mode_64bit 5831 || (prefixes & PREFIX_ADDR)) 5832 { 5833 OP_OFF (bytemode, sizeflag); 5834 return; 5835 } 5836 5837 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS)) 5838 intel_operand_size (bytemode, sizeflag); 5839 append_seg (); 5840 5841 off = get64 (); 5842 5843 if (intel_syntax) 5844 { 5845 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 5846 | PREFIX_ES | PREFIX_FS | PREFIX_GS))) 5847 { 5848 oappend (names_seg[ds_reg - es_reg]); 5849 oappend (":"); 5850 } 5851 } 5852 print_operand_value (scratchbuf, 1, off); 5853 oappend (scratchbuf); 5854} 5855 5856static void 5857ptr_reg (int code, int sizeflag) 5858{ 5859 const char *s; 5860 5861 *obufp++ = open_char; 5862 used_prefixes |= (prefixes & PREFIX_ADDR); 5863 if (address_mode == mode_64bit) 5864 { 5865 if (!(sizeflag & AFLAG)) 5866 s = names32[code - eAX_reg]; 5867 else 5868 s = names64[code - eAX_reg]; 5869 } 5870 else if (sizeflag & AFLAG) 5871 s = names32[code - eAX_reg]; 5872 else 5873 s = names16[code - eAX_reg]; 5874 oappend (s); 5875 *obufp++ = close_char; 5876 *obufp = 0; 5877} 5878 5879static void 5880OP_ESreg (int code, int sizeflag) 5881{ 5882 if (intel_syntax) 5883 { 5884 switch (codep[-1]) 5885 { 5886 case 0x6d: /* insw/insl */ 5887 intel_operand_size (z_mode, sizeflag); 5888 break; 5889 case 0xa5: /* movsw/movsl/movsq */ 5890 case 0xa7: /* cmpsw/cmpsl/cmpsq */ 5891 case 0xab: /* stosw/stosl */ 5892 case 0xaf: /* scasw/scasl */ 5893 intel_operand_size (v_mode, sizeflag); 5894 break; 5895 default: 5896 intel_operand_size (b_mode, sizeflag); 5897 } 5898 } 5899 oappend ("%es:" + intel_syntax); 5900 ptr_reg (code, sizeflag); 5901} 5902 5903static void 5904OP_DSreg (int code, int sizeflag) 5905{ 5906 if (intel_syntax) 5907 { 5908 switch (codep[-1]) 5909 { 5910 case 0x6f: /* outsw/outsl */ 5911 intel_operand_size (z_mode, sizeflag); 5912 break; 5913 case 0xa5: /* movsw/movsl/movsq */ 5914 case 0xa7: /* cmpsw/cmpsl/cmpsq */ 5915 case 0xad: /* lodsw/lodsl/lodsq */ 5916 intel_operand_size (v_mode, sizeflag); 5917 break; 5918 default: 5919 intel_operand_size (b_mode, sizeflag); 5920 } 5921 } 5922 if ((prefixes 5923 & (PREFIX_CS 5924 | PREFIX_DS 5925 | PREFIX_SS 5926 | PREFIX_ES 5927 | PREFIX_FS 5928 | PREFIX_GS)) == 0) 5929 prefixes |= PREFIX_DS; 5930 append_seg (); 5931 ptr_reg (code, sizeflag); 5932} 5933 5934static void 5935OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 5936{ 5937 int add = 0; 5938 if (rex & REX_R) 5939 { 5940 USED_REX (REX_R); 5941 add = 8; 5942 } 5943 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK)) 5944 { 5945 lock_prefix = NULL; 5946 used_prefixes |= PREFIX_LOCK; 5947 add = 8; 5948 } 5949 sprintf (scratchbuf, "%%cr%d", modrm.reg + add); 5950 oappend (scratchbuf + intel_syntax); 5951} 5952 5953static void 5954OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 5955{ 5956 int add = 0; 5957 USED_REX (REX_R); 5958 if (rex & REX_R) 5959 add = 8; 5960 if (intel_syntax) 5961 sprintf (scratchbuf, "db%d", modrm.reg + add); 5962 else 5963 sprintf (scratchbuf, "%%db%d", modrm.reg + add); 5964 oappend (scratchbuf); 5965} 5966 5967static void 5968OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 5969{ 5970 sprintf (scratchbuf, "%%tr%d", modrm.reg); 5971 oappend (scratchbuf + intel_syntax); 5972} 5973 5974static void 5975OP_R (int bytemode, int sizeflag) 5976{ 5977 if (modrm.mod == 3) 5978 OP_E (bytemode, sizeflag); 5979 else 5980 BadOp (); 5981} 5982 5983static void 5984OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 5985{ 5986 used_prefixes |= (prefixes & PREFIX_DATA); 5987 if (prefixes & PREFIX_DATA) 5988 { 5989 int add = 0; 5990 USED_REX (REX_R); 5991 if (rex & REX_R) 5992 add = 8; 5993 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); 5994 } 5995 else 5996 sprintf (scratchbuf, "%%mm%d", modrm.reg); 5997 oappend (scratchbuf + intel_syntax); 5998} 5999 6000static void 6001OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 6002{ 6003 int add = 0; 6004 USED_REX (REX_R); 6005 if (rex & REX_R) 6006 add = 8; 6007 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); 6008 oappend (scratchbuf + intel_syntax); 6009} 6010 6011static void 6012OP_EM (int bytemode, int sizeflag) 6013{ 6014 if (modrm.mod != 3) 6015 { 6016 if (intel_syntax && bytemode == v_mode) 6017 { 6018 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; 6019 used_prefixes |= (prefixes & PREFIX_DATA); 6020 } 6021 OP_E (bytemode, sizeflag); 6022 return; 6023 } 6024 6025 /* Skip mod/rm byte. */ 6026 MODRM_CHECK; 6027 codep++; 6028 used_prefixes |= (prefixes & PREFIX_DATA); 6029 if (prefixes & PREFIX_DATA) 6030 { 6031 int add = 0; 6032 6033 USED_REX (REX_B); 6034 if (rex & REX_B) 6035 add = 8; 6036 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); 6037 } 6038 else 6039 sprintf (scratchbuf, "%%mm%d", modrm.rm); 6040 oappend (scratchbuf + intel_syntax); 6041} 6042 6043/* cvt* are the only instructions in sse2 which have 6044 both SSE and MMX operands and also have 0x66 prefix 6045 in their opcode. 0x66 was originally used to differentiate 6046 between SSE and MMX instruction(operands). So we have to handle the 6047 cvt* separately using OP_EMC and OP_MXC */ 6048static void 6049OP_EMC (int bytemode, int sizeflag) 6050{ 6051 if (modrm.mod != 3) 6052 { 6053 if (intel_syntax && bytemode == v_mode) 6054 { 6055 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; 6056 used_prefixes |= (prefixes & PREFIX_DATA); 6057 } 6058 OP_E (bytemode, sizeflag); 6059 return; 6060 } 6061 6062 /* Skip mod/rm byte. */ 6063 MODRM_CHECK; 6064 codep++; 6065 used_prefixes |= (prefixes & PREFIX_DATA); 6066 sprintf (scratchbuf, "%%mm%d", modrm.rm); 6067 oappend (scratchbuf + intel_syntax); 6068} 6069 6070static void 6071OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 6072{ 6073 used_prefixes |= (prefixes & PREFIX_DATA); 6074 sprintf (scratchbuf, "%%mm%d", modrm.reg); 6075 oappend (scratchbuf + intel_syntax); 6076} 6077 6078static void 6079OP_EX (int bytemode, int sizeflag) 6080{ 6081 int add = 0; 6082 if (modrm.mod != 3) 6083 { 6084 OP_E (bytemode, sizeflag); 6085 return; 6086 } 6087 USED_REX (REX_B); 6088 if (rex & REX_B) 6089 add = 8; 6090 6091 /* Skip mod/rm byte. */ 6092 MODRM_CHECK; 6093 codep++; 6094 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); 6095 oappend (scratchbuf + intel_syntax); 6096} 6097 6098static void 6099OP_MS (int bytemode, int sizeflag) 6100{ 6101 if (modrm.mod == 3) 6102 OP_EM (bytemode, sizeflag); 6103 else 6104 BadOp (); 6105} 6106 6107static void 6108OP_XS (int bytemode, int sizeflag) 6109{ 6110 if (modrm.mod == 3) 6111 OP_EX (bytemode, sizeflag); 6112 else 6113 BadOp (); 6114} 6115 6116static void 6117OP_M (int bytemode, int sizeflag) 6118{ 6119 if (modrm.mod == 3) 6120 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */ 6121 BadOp (); 6122 else 6123 OP_E (bytemode, sizeflag); 6124} 6125 6126static void 6127OP_0f07 (int bytemode, int sizeflag) 6128{ 6129 if (modrm.mod != 3 || modrm.rm != 0) 6130 BadOp (); 6131 else 6132 OP_E (bytemode, sizeflag); 6133} 6134 6135/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in 6136 32bit mode and "xchg %rax,%rax" in 64bit mode. */ 6137 6138static void 6139NOP_Fixup1 (int bytemode, int sizeflag) 6140{ 6141 if ((prefixes & PREFIX_DATA) != 0 6142 || (rex != 0 6143 && rex != 0x48 6144 && address_mode == mode_64bit)) 6145 OP_REG (bytemode, sizeflag); 6146 else 6147 strcpy (obuf, "nop"); 6148} 6149 6150static void 6151NOP_Fixup2 (int bytemode, int sizeflag) 6152{ 6153 if ((prefixes & PREFIX_DATA) != 0 6154 || (rex != 0 6155 && rex != 0x48 6156 && address_mode == mode_64bit)) 6157 OP_IMREG (bytemode, sizeflag); 6158} 6159 6160static const char *const Suffix3DNow[] = { 6161/* 00 */ NULL, NULL, NULL, NULL, 6162/* 04 */ NULL, NULL, NULL, NULL, 6163/* 08 */ NULL, NULL, NULL, NULL, 6164/* 0C */ "pi2fw", "pi2fd", NULL, NULL, 6165/* 10 */ NULL, NULL, NULL, NULL, 6166/* 14 */ NULL, NULL, NULL, NULL, 6167/* 18 */ NULL, NULL, NULL, NULL, 6168/* 1C */ "pf2iw", "pf2id", NULL, NULL, 6169/* 20 */ NULL, NULL, NULL, NULL, 6170/* 24 */ NULL, NULL, NULL, NULL, 6171/* 28 */ NULL, NULL, NULL, NULL, 6172/* 2C */ NULL, NULL, NULL, NULL, 6173/* 30 */ NULL, NULL, NULL, NULL, 6174/* 34 */ NULL, NULL, NULL, NULL, 6175/* 38 */ NULL, NULL, NULL, NULL, 6176/* 3C */ NULL, NULL, NULL, NULL, 6177/* 40 */ NULL, NULL, NULL, NULL, 6178/* 44 */ NULL, NULL, NULL, NULL, 6179/* 48 */ NULL, NULL, NULL, NULL, 6180/* 4C */ NULL, NULL, NULL, NULL, 6181/* 50 */ NULL, NULL, NULL, NULL, 6182/* 54 */ NULL, NULL, NULL, NULL, 6183/* 58 */ NULL, NULL, NULL, NULL, 6184/* 5C */ NULL, NULL, NULL, NULL, 6185/* 60 */ NULL, NULL, NULL, NULL, 6186/* 64 */ NULL, NULL, NULL, NULL, 6187/* 68 */ NULL, NULL, NULL, NULL, 6188/* 6C */ NULL, NULL, NULL, NULL, 6189/* 70 */ NULL, NULL, NULL, NULL, 6190/* 74 */ NULL, NULL, NULL, NULL, 6191/* 78 */ NULL, NULL, NULL, NULL, 6192/* 7C */ NULL, NULL, NULL, NULL, 6193/* 80 */ NULL, NULL, NULL, NULL, 6194/* 84 */ NULL, NULL, NULL, NULL, 6195/* 88 */ NULL, NULL, "pfnacc", NULL, 6196/* 8C */ NULL, NULL, "pfpnacc", NULL, 6197/* 90 */ "pfcmpge", NULL, NULL, NULL, 6198/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", 6199/* 98 */ NULL, NULL, "pfsub", NULL, 6200/* 9C */ NULL, NULL, "pfadd", NULL, 6201/* A0 */ "pfcmpgt", NULL, NULL, NULL, 6202/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", 6203/* A8 */ NULL, NULL, "pfsubr", NULL, 6204/* AC */ NULL, NULL, "pfacc", NULL, 6205/* B0 */ "pfcmpeq", NULL, NULL, NULL, 6206/* B4 */ "pfmul", NULL, "pfrcpit2", "pmulhrw", 6207/* B8 */ NULL, NULL, NULL, "pswapd", 6208/* BC */ NULL, NULL, NULL, "pavgusb", 6209/* C0 */ NULL, NULL, NULL, NULL, 6210/* C4 */ NULL, NULL, NULL, NULL, 6211/* C8 */ NULL, NULL, NULL, NULL, 6212/* CC */ NULL, NULL, NULL, NULL, 6213/* D0 */ NULL, NULL, NULL, NULL, 6214/* D4 */ NULL, NULL, NULL, NULL, 6215/* D8 */ NULL, NULL, NULL, NULL, 6216/* DC */ NULL, NULL, NULL, NULL, 6217/* E0 */ NULL, NULL, NULL, NULL, 6218/* E4 */ NULL, NULL, NULL, NULL, 6219/* E8 */ NULL, NULL, NULL, NULL, 6220/* EC */ NULL, NULL, NULL, NULL, 6221/* F0 */ NULL, NULL, NULL, NULL, 6222/* F4 */ NULL, NULL, NULL, NULL, 6223/* F8 */ NULL, NULL, NULL, NULL, 6224/* FC */ NULL, NULL, NULL, NULL, 6225}; 6226 6227static void 6228OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 6229{ 6230 const char *mnemonic; 6231 6232 FETCH_DATA (the_info, codep + 1); 6233 /* AMD 3DNow! instructions are specified by an opcode suffix in the 6234 place where an 8-bit immediate would normally go. ie. the last 6235 byte of the instruction. */ 6236 obufp = obuf + strlen (obuf); 6237 mnemonic = Suffix3DNow[*codep++ & 0xff]; 6238 if (mnemonic) 6239 oappend (mnemonic); 6240 else 6241 { 6242 /* Since a variable sized modrm/sib chunk is between the start 6243 of the opcode (0x0f0f) and the opcode suffix, we need to do 6244 all the modrm processing first, and don't know until now that 6245 we have a bad opcode. This necessitates some cleaning up. */ 6246 op_out[0][0] = '\0'; 6247 op_out[1][0] = '\0'; 6248 BadOp (); 6249 } 6250} 6251 6252static const char *simd_cmp_op[] = { 6253 "eq", 6254 "lt", 6255 "le", 6256 "unord", 6257 "neq", 6258 "nlt", 6259 "nle", 6260 "ord" 6261}; 6262 6263static void 6264OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 6265{ 6266 unsigned int cmp_type; 6267 6268 FETCH_DATA (the_info, codep + 1); 6269 obufp = obuf + strlen (obuf); 6270 cmp_type = *codep++ & 0xff; 6271 if (cmp_type < 8) 6272 { 6273 char suffix1 = 'p', suffix2 = 's'; 6274 used_prefixes |= (prefixes & PREFIX_REPZ); 6275 if (prefixes & PREFIX_REPZ) 6276 suffix1 = 's'; 6277 else 6278 { 6279 used_prefixes |= (prefixes & PREFIX_DATA); 6280 if (prefixes & PREFIX_DATA) 6281 suffix2 = 'd'; 6282 else 6283 { 6284 used_prefixes |= (prefixes & PREFIX_REPNZ); 6285 if (prefixes & PREFIX_REPNZ) 6286 suffix1 = 's', suffix2 = 'd'; 6287 } 6288 } 6289 sprintf (scratchbuf, "cmp%s%c%c", 6290 simd_cmp_op[cmp_type], suffix1, suffix2); 6291 used_prefixes |= (prefixes & PREFIX_REPZ); 6292 oappend (scratchbuf); 6293 } 6294 else 6295 { 6296 /* We have a bad extension byte. Clean up. */ 6297 op_out[0][0] = '\0'; 6298 op_out[1][0] = '\0'; 6299 BadOp (); 6300 } 6301} 6302 6303static void 6304OP_Mwait (int bytemode ATTRIBUTE_UNUSED, 6305 int sizeflag ATTRIBUTE_UNUSED) 6306{ 6307 /* mwait %eax,%ecx */ 6308 if (!intel_syntax) 6309 { 6310 const char **names = (address_mode == mode_64bit 6311 ? names64 : names32); 6312 strcpy (op_out[0], names[0]); 6313 strcpy (op_out[1], names[1]); 6314 two_source_ops = 1; 6315 } 6316 /* Skip mod/rm byte. */ 6317 MODRM_CHECK; 6318 codep++; 6319} 6320 6321static void 6322OP_Monitor (int bytemode ATTRIBUTE_UNUSED, 6323 int sizeflag ATTRIBUTE_UNUSED) 6324{ 6325 /* monitor %eax,%ecx,%edx" */ 6326 if (!intel_syntax) 6327 { 6328 const char **op1_names; 6329 const char **names = (address_mode == mode_64bit 6330 ? names64 : names32); 6331 6332 if (!(prefixes & PREFIX_ADDR)) 6333 op1_names = (address_mode == mode_16bit 6334 ? names16 : names); 6335 else 6336 { 6337 /* Remove "addr16/addr32". */ 6338 addr_prefix = NULL; 6339 op1_names = (address_mode != mode_32bit 6340 ? names32 : names16); 6341 used_prefixes |= PREFIX_ADDR; 6342 } 6343 strcpy (op_out[0], op1_names[0]); 6344 strcpy (op_out[1], names[1]); 6345 strcpy (op_out[2], names[2]); 6346 two_source_ops = 1; 6347 } 6348 /* Skip mod/rm byte. */ 6349 MODRM_CHECK; 6350 codep++; 6351} 6352 6353static void 6354BadOp (void) 6355{ 6356 /* Throw away prefixes and 1st. opcode byte. */ 6357 codep = insn_codep + 1; 6358 oappend ("(bad)"); 6359} 6360 6361static void 6362REP_Fixup (int bytemode, int sizeflag) 6363{ 6364 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs, 6365 lods and stos. */ 6366 if (prefixes & PREFIX_REPZ) 6367 repz_prefix = "rep "; 6368 6369 switch (bytemode) 6370 { 6371 case al_reg: 6372 case eAX_reg: 6373 case indir_dx_reg: 6374 OP_IMREG (bytemode, sizeflag); 6375 break; 6376 case eDI_reg: 6377 OP_ESreg (bytemode, sizeflag); 6378 break; 6379 case eSI_reg: 6380 OP_DSreg (bytemode, sizeflag); 6381 break; 6382 default: 6383 abort (); 6384 break; 6385 } 6386} 6387 6388static void 6389CMPXCHG8B_Fixup (int bytemode, int sizeflag) 6390{ 6391 USED_REX (REX_W); 6392 if (rex & REX_W) 6393 { 6394 /* Change cmpxchg8b to cmpxchg16b. */ 6395 char *p = obuf + strlen (obuf) - 2; 6396 strcpy (p, "16b"); 6397 bytemode = o_mode; 6398 } 6399 OP_M (bytemode, sizeflag); 6400} 6401 6402static void 6403XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED) 6404{ 6405 sprintf (scratchbuf, "%%xmm%d", reg); 6406 oappend (scratchbuf + intel_syntax); 6407} 6408 6409static void 6410CRC32_Fixup (int bytemode, int sizeflag) 6411{ 6412 /* Add proper suffix to "crc32". */ 6413 char *p = obuf + strlen (obuf); 6414 6415 switch (bytemode) 6416 { 6417 case b_mode: 6418 if (intel_syntax) 6419 break; 6420 6421 *p++ = 'b'; 6422 break; 6423 case v_mode: 6424 if (intel_syntax) 6425 break; 6426 6427 USED_REX (REX_W); 6428 if (rex & REX_W) 6429 *p++ = 'q'; 6430 else if (sizeflag & DFLAG) 6431 *p++ = 'l'; 6432 else 6433 *p++ = 'w'; 6434 used_prefixes |= (prefixes & PREFIX_DATA); 6435 break; 6436 default: 6437 oappend (INTERNAL_DISASSEMBLER_ERROR); 6438 break; 6439 } 6440 *p = '\0'; 6441 6442 if (modrm.mod == 3) 6443 { 6444 int add; 6445 6446 /* Skip mod/rm byte. */ 6447 MODRM_CHECK; 6448 codep++; 6449 6450 USED_REX (REX_B); 6451 add = (rex & REX_B) ? 8 : 0; 6452 if (bytemode == b_mode) 6453 { 6454 USED_REX (0); 6455 if (rex) 6456 oappend (names8rex[modrm.rm + add]); 6457 else 6458 oappend (names8[modrm.rm + add]); 6459 } 6460 else 6461 { 6462 USED_REX (REX_W); 6463 if (rex & REX_W) 6464 oappend (names64[modrm.rm + add]); 6465 else if ((prefixes & PREFIX_DATA)) 6466 oappend (names16[modrm.rm + add]); 6467 else 6468 oappend (names32[modrm.rm + add]); 6469 } 6470 } 6471 else 6472 OP_E (bytemode, sizeflag); 6473} 6474