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