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