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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 20 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_MS (int, int); 89static void OP_XS (int, int); 90static void OP_M (int, int); 91static void OP_0fae (int, int); 92static void OP_0f07 (int, int); 93static void NOP_Fixup (int, int); 94static void OP_3DNowSuffix (int, int); 95static void OP_SIMD_Suffix (int, int); 96static void SIMD_Fixup (int, int); 97static void PNI_Fixup (int, int); 98static void INVLPG_Fixup (int, int); 99static void BadOp (void); 100 101struct dis_private { 102 /* Points to first byte not fetched. */ 103 bfd_byte *max_fetched; 104 bfd_byte the_buffer[MAXLEN]; 105 bfd_vma insn_start; 106 int orig_sizeflag; 107 jmp_buf bailout; 108}; 109 110/* The opcode for the fwait instruction, which we treat as a prefix 111 when we can. */ 112#define FWAIT_OPCODE (0x9b) 113 114/* Set to 1 for 64bit mode disassembly. */ 115static int mode_64bit; 116 117/* Flags for the prefixes for the current instruction. See below. */ 118static int prefixes; 119 120/* REX prefix the current instruction. See below. */ 121static int rex; 122/* Bits of REX we've already used. */ 123static int rex_used; 124#define REX_MODE64 8 125#define REX_EXTX 4 126#define REX_EXTY 2 127#define REX_EXTZ 1 128/* Mark parts used in the REX prefix. When we are testing for 129 empty prefix (for 8bit register REX extension), just mask it 130 out. Otherwise test for REX bit is excuse for existence of REX 131 only in case value is nonzero. */ 132#define USED_REX(value) \ 133 { \ 134 if (value) \ 135 rex_used |= (rex & value) ? (value) | 0x40 : 0; \ 136 else \ 137 rex_used |= 0x40; \ 138 } 139 140/* Flags for prefixes which we somehow handled when printing the 141 current instruction. */ 142static int used_prefixes; 143 144/* Flags stored in PREFIXES. */ 145#define PREFIX_REPZ 1 146#define PREFIX_REPNZ 2 147#define PREFIX_LOCK 4 148#define PREFIX_CS 8 149#define PREFIX_SS 0x10 150#define PREFIX_DS 0x20 151#define PREFIX_ES 0x40 152#define PREFIX_FS 0x80 153#define PREFIX_GS 0x100 154#define PREFIX_DATA 0x200 155#define PREFIX_ADDR 0x400 156#define PREFIX_FWAIT 0x800 157 158/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 159 to ADDR (exclusive) are valid. Returns 1 for success, longjmps 160 on error. */ 161#define FETCH_DATA(info, addr) \ 162 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \ 163 ? 1 : fetch_data ((info), (addr))) 164 165static int 166fetch_data (struct disassemble_info *info, bfd_byte *addr) 167{ 168 int status; 169 struct dis_private *priv = (struct dis_private *) info->private_data; 170 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); 171 172 status = (*info->read_memory_func) (start, 173 priv->max_fetched, 174 addr - priv->max_fetched, 175 info); 176 if (status != 0) 177 { 178 /* If we did manage to read at least one byte, then 179 print_insn_i386 will do something sensible. Otherwise, print 180 an error. We do that here because this is where we know 181 STATUS. */ 182 if (priv->max_fetched == priv->the_buffer) 183 (*info->memory_error_func) (status, start, info); 184 longjmp (priv->bailout, 1); 185 } 186 else 187 priv->max_fetched = addr; 188 return 1; 189} 190 191#define XX NULL, 0 192 193#define Eb OP_E, b_mode 194#define Ev OP_E, v_mode 195#define Ed OP_E, d_mode 196#define Edq OP_E, dq_mode 197#define indirEb OP_indirE, b_mode 198#define indirEv OP_indirE, v_mode 199#define Ew OP_E, w_mode 200#define Ma OP_E, v_mode 201#define M OP_M, 0 /* lea, lgdt, etc. */ 202#define Mp OP_M, 0 /* 32 or 48 bit memory operand for LDS, LES etc */ 203#define Gb OP_G, b_mode 204#define Gv OP_G, v_mode 205#define Gd OP_G, d_mode 206#define Gw OP_G, w_mode 207#define Rd OP_Rd, d_mode 208#define Rm OP_Rd, m_mode 209#define Ib OP_I, b_mode 210#define sIb OP_sI, b_mode /* sign extened byte */ 211#define Iv OP_I, v_mode 212#define Iq OP_I, q_mode 213#define Iv64 OP_I64, v_mode 214#define Iw OP_I, w_mode 215#define Jb OP_J, b_mode 216#define Jv OP_J, v_mode 217#define Cm OP_C, m_mode 218#define Dm OP_D, m_mode 219#define Td OP_T, d_mode 220 221#define RMeAX OP_REG, eAX_reg 222#define RMeBX OP_REG, eBX_reg 223#define RMeCX OP_REG, eCX_reg 224#define RMeDX OP_REG, eDX_reg 225#define RMeSP OP_REG, eSP_reg 226#define RMeBP OP_REG, eBP_reg 227#define RMeSI OP_REG, eSI_reg 228#define RMeDI OP_REG, eDI_reg 229#define RMrAX OP_REG, rAX_reg 230#define RMrBX OP_REG, rBX_reg 231#define RMrCX OP_REG, rCX_reg 232#define RMrDX OP_REG, rDX_reg 233#define RMrSP OP_REG, rSP_reg 234#define RMrBP OP_REG, rBP_reg 235#define RMrSI OP_REG, rSI_reg 236#define RMrDI OP_REG, rDI_reg 237#define RMAL OP_REG, al_reg 238#define RMAL OP_REG, al_reg 239#define RMCL OP_REG, cl_reg 240#define RMDL OP_REG, dl_reg 241#define RMBL OP_REG, bl_reg 242#define RMAH OP_REG, ah_reg 243#define RMCH OP_REG, ch_reg 244#define RMDH OP_REG, dh_reg 245#define RMBH OP_REG, bh_reg 246#define RMAX OP_REG, ax_reg 247#define RMDX OP_REG, dx_reg 248 249#define eAX OP_IMREG, eAX_reg 250#define eBX OP_IMREG, eBX_reg 251#define eCX OP_IMREG, eCX_reg 252#define eDX OP_IMREG, eDX_reg 253#define eSP OP_IMREG, eSP_reg 254#define eBP OP_IMREG, eBP_reg 255#define eSI OP_IMREG, eSI_reg 256#define eDI OP_IMREG, eDI_reg 257#define AL OP_IMREG, al_reg 258#define AL OP_IMREG, al_reg 259#define CL OP_IMREG, cl_reg 260#define DL OP_IMREG, dl_reg 261#define BL OP_IMREG, bl_reg 262#define AH OP_IMREG, ah_reg 263#define CH OP_IMREG, ch_reg 264#define DH OP_IMREG, dh_reg 265#define BH OP_IMREG, bh_reg 266#define AX OP_IMREG, ax_reg 267#define DX OP_IMREG, dx_reg 268#define indirDX OP_IMREG, indir_dx_reg 269 270#define Sw OP_SEG, w_mode 271#define Ap OP_DIR, 0 272#define Ob OP_OFF, b_mode 273#define Ob64 OP_OFF64, b_mode 274#define Ov OP_OFF, v_mode 275#define Ov64 OP_OFF64, v_mode 276#define Xb OP_DSreg, eSI_reg 277#define Xv OP_DSreg, eSI_reg 278#define Yb OP_ESreg, eDI_reg 279#define Yv OP_ESreg, eDI_reg 280#define DSBX OP_DSreg, eBX_reg 281 282#define es OP_REG, es_reg 283#define ss OP_REG, ss_reg 284#define cs OP_REG, cs_reg 285#define ds OP_REG, ds_reg 286#define fs OP_REG, fs_reg 287#define gs OP_REG, gs_reg 288 289#define MX OP_MMX, 0 290#define XM OP_XMM, 0 291#define EM OP_EM, v_mode 292#define EX OP_EX, v_mode 293#define MS OP_MS, v_mode 294#define XS OP_XS, v_mode 295#define OPSUF OP_3DNowSuffix, 0 296#define OPSIMD OP_SIMD_Suffix, 0 297 298#define cond_jump_flag NULL, cond_jump_mode 299#define loop_jcxz_flag NULL, loop_jcxz_mode 300 301/* bits in sizeflag */ 302#define SUFFIX_ALWAYS 4 303#define AFLAG 2 304#define DFLAG 1 305 306#define b_mode 1 /* byte operand */ 307#define v_mode 2 /* operand size depends on prefixes */ 308#define w_mode 3 /* word operand */ 309#define d_mode 4 /* double word operand */ 310#define q_mode 5 /* quad word operand */ 311#define x_mode 6 /* 80 bit float operand */ 312#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */ 313#define cond_jump_mode 8 314#define loop_jcxz_mode 9 315#define dq_mode 10 /* operand size depends on REX prefixes. */ 316 317#define es_reg 100 318#define cs_reg 101 319#define ss_reg 102 320#define ds_reg 103 321#define fs_reg 104 322#define gs_reg 105 323 324#define eAX_reg 108 325#define eCX_reg 109 326#define eDX_reg 110 327#define eBX_reg 111 328#define eSP_reg 112 329#define eBP_reg 113 330#define eSI_reg 114 331#define eDI_reg 115 332 333#define al_reg 116 334#define cl_reg 117 335#define dl_reg 118 336#define bl_reg 119 337#define ah_reg 120 338#define ch_reg 121 339#define dh_reg 122 340#define bh_reg 123 341 342#define ax_reg 124 343#define cx_reg 125 344#define dx_reg 126 345#define bx_reg 127 346#define sp_reg 128 347#define bp_reg 129 348#define si_reg 130 349#define di_reg 131 350 351#define rAX_reg 132 352#define rCX_reg 133 353#define rDX_reg 134 354#define rBX_reg 135 355#define rSP_reg 136 356#define rBP_reg 137 357#define rSI_reg 138 358#define rDI_reg 139 359 360#define indir_dx_reg 150 361 362#define FLOATCODE 1 363#define USE_GROUPS 2 364#define USE_PREFIX_USER_TABLE 3 365#define X86_64_SPECIAL 4 366 367#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 368 369#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0 370#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0 371#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0 372#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0 373#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0 374#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0 375#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0 376#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0 377#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0 378#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0 379#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0 380#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0 381#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0 382#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0 383#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0 384#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0 385#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0 386#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0 387#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0 388#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0 389#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0 390#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0 391#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0 392#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0 393#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0 394 395#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0 396#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0 397#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0 398#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0 399#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0 400#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0 401#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0 402#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0 403#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0 404#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0 405#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0 406#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0 407#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0 408#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0 409#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0 410#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0 411#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0 412#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0 413#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0 414#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0 415#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0 416#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0 417#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0 418#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0 419#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0 420#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0 421#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0 422#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0 423#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0 424#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0 425#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0 426#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0 427#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0 428 429#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0 430 431typedef void (*op_rtn) (int bytemode, int sizeflag); 432 433struct dis386 { 434 const char *name; 435 op_rtn op1; 436 int bytemode1; 437 op_rtn op2; 438 int bytemode2; 439 op_rtn op3; 440 int bytemode3; 441}; 442 443/* Upper case letters in the instruction names here are macros. 444 'A' => print 'b' if no register operands or suffix_always is true 445 'B' => print 'b' if suffix_always is true 446 'E' => print 'e' if 32-bit form of jcxz 447 'F' => print 'w' or 'l' depending on address size prefix (loop insns) 448 'H' => print ",pt" or ",pn" branch hint 449 'L' => print 'l' if suffix_always is true 450 'N' => print 'n' if instruction has no wait "prefix" 451 'O' => print 'd', or 'o' 452 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix, 453 . or suffix_always is true. print 'q' if rex prefix is present. 454 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always 455 . is true 456 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode) 457 'S' => print 'w', 'l' or 'q' if suffix_always is true 458 'T' => print 'q' in 64bit mode and behave as 'P' otherwise 459 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise 460 'X' => print 's', 'd' depending on data16 prefix (for XMM) 461 'W' => print 'b' or 'w' ("w" or "de" in intel mode) 462 'Y' => 'q' if instruction has an REX 64bit overwrite prefix 463 464 Many of the above letters print nothing in Intel mode. See "putop" 465 for the details. 466 467 Braces '{' and '}', and vertical bars '|', indicate alternative 468 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel 469 modes. In cases where there are only two alternatives, the X86_64 470 instruction is reserved, and "(bad)" is printed. 471*/ 472 473static const struct dis386 dis386[] = { 474 /* 00 */ 475 { "addB", Eb, Gb, XX }, 476 { "addS", Ev, Gv, XX }, 477 { "addB", Gb, Eb, XX }, 478 { "addS", Gv, Ev, XX }, 479 { "addB", AL, Ib, XX }, 480 { "addS", eAX, Iv, XX }, 481 { "push{T|}", es, XX, XX }, 482 { "pop{T|}", es, XX, XX }, 483 /* 08 */ 484 { "orB", Eb, Gb, XX }, 485 { "orS", Ev, Gv, XX }, 486 { "orB", Gb, Eb, XX }, 487 { "orS", Gv, Ev, XX }, 488 { "orB", AL, Ib, XX }, 489 { "orS", eAX, Iv, XX }, 490 { "push{T|}", cs, XX, XX }, 491 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ 492 /* 10 */ 493 { "adcB", Eb, Gb, XX }, 494 { "adcS", Ev, Gv, XX }, 495 { "adcB", Gb, Eb, XX }, 496 { "adcS", Gv, Ev, XX }, 497 { "adcB", AL, Ib, XX }, 498 { "adcS", eAX, Iv, XX }, 499 { "push{T|}", ss, XX, XX }, 500 { "popT|}", ss, XX, XX }, 501 /* 18 */ 502 { "sbbB", Eb, Gb, XX }, 503 { "sbbS", Ev, Gv, XX }, 504 { "sbbB", Gb, Eb, XX }, 505 { "sbbS", Gv, Ev, XX }, 506 { "sbbB", AL, Ib, XX }, 507 { "sbbS", eAX, Iv, XX }, 508 { "push{T|}", ds, XX, XX }, 509 { "pop{T|}", ds, XX, XX }, 510 /* 20 */ 511 { "andB", Eb, Gb, XX }, 512 { "andS", Ev, Gv, XX }, 513 { "andB", Gb, Eb, XX }, 514 { "andS", Gv, Ev, XX }, 515 { "andB", AL, Ib, XX }, 516 { "andS", eAX, Iv, XX }, 517 { "(bad)", XX, XX, XX }, /* SEG ES prefix */ 518 { "daa{|}", XX, XX, XX }, 519 /* 28 */ 520 { "subB", Eb, Gb, XX }, 521 { "subS", Ev, Gv, XX }, 522 { "subB", Gb, Eb, XX }, 523 { "subS", Gv, Ev, XX }, 524 { "subB", AL, Ib, XX }, 525 { "subS", eAX, Iv, XX }, 526 { "(bad)", XX, XX, XX }, /* SEG CS prefix */ 527 { "das{|}", XX, XX, XX }, 528 /* 30 */ 529 { "xorB", Eb, Gb, XX }, 530 { "xorS", Ev, Gv, XX }, 531 { "xorB", Gb, Eb, XX }, 532 { "xorS", Gv, Ev, XX }, 533 { "xorB", AL, Ib, XX }, 534 { "xorS", eAX, Iv, XX }, 535 { "(bad)", XX, XX, XX }, /* SEG SS prefix */ 536 { "aaa{|}", XX, XX, XX }, 537 /* 38 */ 538 { "cmpB", Eb, Gb, XX }, 539 { "cmpS", Ev, Gv, XX }, 540 { "cmpB", Gb, Eb, XX }, 541 { "cmpS", Gv, Ev, XX }, 542 { "cmpB", AL, Ib, XX }, 543 { "cmpS", eAX, Iv, XX }, 544 { "(bad)", XX, XX, XX }, /* SEG DS prefix */ 545 { "aas{|}", XX, XX, XX }, 546 /* 40 */ 547 { "inc{S|}", RMeAX, XX, XX }, 548 { "inc{S|}", RMeCX, XX, XX }, 549 { "inc{S|}", RMeDX, XX, XX }, 550 { "inc{S|}", RMeBX, XX, XX }, 551 { "inc{S|}", RMeSP, XX, XX }, 552 { "inc{S|}", RMeBP, XX, XX }, 553 { "inc{S|}", RMeSI, XX, XX }, 554 { "inc{S|}", RMeDI, XX, XX }, 555 /* 48 */ 556 { "dec{S|}", RMeAX, XX, XX }, 557 { "dec{S|}", RMeCX, XX, XX }, 558 { "dec{S|}", RMeDX, XX, XX }, 559 { "dec{S|}", RMeBX, XX, XX }, 560 { "dec{S|}", RMeSP, XX, XX }, 561 { "dec{S|}", RMeBP, XX, XX }, 562 { "dec{S|}", RMeSI, XX, XX }, 563 { "dec{S|}", RMeDI, XX, XX }, 564 /* 50 */ 565 { "pushS", RMrAX, XX, XX }, 566 { "pushS", RMrCX, XX, XX }, 567 { "pushS", RMrDX, XX, XX }, 568 { "pushS", RMrBX, XX, XX }, 569 { "pushS", RMrSP, XX, XX }, 570 { "pushS", RMrBP, XX, XX }, 571 { "pushS", RMrSI, XX, XX }, 572 { "pushS", RMrDI, XX, XX }, 573 /* 58 */ 574 { "popS", RMrAX, XX, XX }, 575 { "popS", RMrCX, XX, XX }, 576 { "popS", RMrDX, XX, XX }, 577 { "popS", RMrBX, XX, XX }, 578 { "popS", RMrSP, XX, XX }, 579 { "popS", RMrBP, XX, XX }, 580 { "popS", RMrSI, XX, XX }, 581 { "popS", RMrDI, XX, XX }, 582 /* 60 */ 583 { "pusha{P|}", XX, XX, XX }, 584 { "popa{P|}", XX, XX, XX }, 585 { "bound{S|}", Gv, Ma, XX }, 586 { X86_64_0 }, 587 { "(bad)", XX, XX, XX }, /* seg fs */ 588 { "(bad)", XX, XX, XX }, /* seg gs */ 589 { "(bad)", XX, XX, XX }, /* op size prefix */ 590 { "(bad)", XX, XX, XX }, /* adr size prefix */ 591 /* 68 */ 592 { "pushT", Iq, XX, XX }, 593 { "imulS", Gv, Ev, Iv }, 594 { "pushT", sIb, XX, XX }, 595 { "imulS", Gv, Ev, sIb }, 596 { "ins{b||b|}", Yb, indirDX, XX }, 597 { "ins{R||R|}", Yv, indirDX, XX }, 598 { "outs{b||b|}", indirDX, Xb, XX }, 599 { "outs{R||R|}", indirDX, Xv, XX }, 600 /* 70 */ 601 { "joH", Jb, XX, cond_jump_flag }, 602 { "jnoH", Jb, XX, cond_jump_flag }, 603 { "jbH", Jb, XX, cond_jump_flag }, 604 { "jaeH", Jb, XX, cond_jump_flag }, 605 { "jeH", Jb, XX, cond_jump_flag }, 606 { "jneH", Jb, XX, cond_jump_flag }, 607 { "jbeH", Jb, XX, cond_jump_flag }, 608 { "jaH", Jb, XX, cond_jump_flag }, 609 /* 78 */ 610 { "jsH", Jb, XX, cond_jump_flag }, 611 { "jnsH", Jb, XX, cond_jump_flag }, 612 { "jpH", Jb, XX, cond_jump_flag }, 613 { "jnpH", Jb, XX, cond_jump_flag }, 614 { "jlH", Jb, XX, cond_jump_flag }, 615 { "jgeH", Jb, XX, cond_jump_flag }, 616 { "jleH", Jb, XX, cond_jump_flag }, 617 { "jgH", Jb, XX, cond_jump_flag }, 618 /* 80 */ 619 { GRP1b }, 620 { GRP1S }, 621 { "(bad)", XX, XX, XX }, 622 { GRP1Ss }, 623 { "testB", Eb, Gb, XX }, 624 { "testS", Ev, Gv, XX }, 625 { "xchgB", Eb, Gb, XX }, 626 { "xchgS", Ev, Gv, XX }, 627 /* 88 */ 628 { "movB", Eb, Gb, XX }, 629 { "movS", Ev, Gv, XX }, 630 { "movB", Gb, Eb, XX }, 631 { "movS", Gv, Ev, XX }, 632 { "movQ", Ev, Sw, XX }, 633 { "leaS", Gv, M, XX }, 634 { "movQ", Sw, Ev, XX }, 635 { "popU", Ev, XX, XX }, 636 /* 90 */ 637 { "nop", NOP_Fixup, 0, XX, XX }, 638 { "xchgS", RMeCX, eAX, XX }, 639 { "xchgS", RMeDX, eAX, XX }, 640 { "xchgS", RMeBX, eAX, XX }, 641 { "xchgS", RMeSP, eAX, XX }, 642 { "xchgS", RMeBP, eAX, XX }, 643 { "xchgS", RMeSI, eAX, XX }, 644 { "xchgS", RMeDI, eAX, XX }, 645 /* 98 */ 646 { "cW{tR||tR|}", XX, XX, XX }, 647 { "cR{tO||tO|}", XX, XX, XX }, 648 { "lcall{T|}", Ap, XX, XX }, 649 { "(bad)", XX, XX, XX }, /* fwait */ 650 { "pushfT", XX, XX, XX }, 651 { "popfT", XX, XX, XX }, 652 { "sahf{|}", XX, XX, XX }, 653 { "lahf{|}", XX, XX, XX }, 654 /* a0 */ 655 { "movB", AL, Ob64, XX }, 656 { "movS", eAX, Ov64, XX }, 657 { "movB", Ob64, AL, XX }, 658 { "movS", Ov64, eAX, XX }, 659 { "movs{b||b|}", Yb, Xb, XX }, 660 { "movs{R||R|}", Yv, Xv, XX }, 661 { "cmps{b||b|}", Xb, Yb, XX }, 662 { "cmps{R||R|}", Xv, Yv, XX }, 663 /* a8 */ 664 { "testB", AL, Ib, XX }, 665 { "testS", eAX, Iv, XX }, 666 { "stosB", Yb, AL, XX }, 667 { "stosS", Yv, eAX, XX }, 668 { "lodsB", AL, Xb, XX }, 669 { "lodsS", eAX, Xv, XX }, 670 { "scasB", AL, Yb, XX }, 671 { "scasS", eAX, Yv, XX }, 672 /* b0 */ 673 { "movB", RMAL, Ib, XX }, 674 { "movB", RMCL, Ib, XX }, 675 { "movB", RMDL, Ib, XX }, 676 { "movB", RMBL, Ib, XX }, 677 { "movB", RMAH, Ib, XX }, 678 { "movB", RMCH, Ib, XX }, 679 { "movB", RMDH, Ib, XX }, 680 { "movB", RMBH, Ib, XX }, 681 /* b8 */ 682 { "movS", RMeAX, Iv64, XX }, 683 { "movS", RMeCX, Iv64, XX }, 684 { "movS", RMeDX, Iv64, XX }, 685 { "movS", RMeBX, Iv64, XX }, 686 { "movS", RMeSP, Iv64, XX }, 687 { "movS", RMeBP, Iv64, XX }, 688 { "movS", RMeSI, Iv64, XX }, 689 { "movS", RMeDI, Iv64, XX }, 690 /* c0 */ 691 { GRP2b }, 692 { GRP2S }, 693 { "retT", Iw, XX, XX }, 694 { "retT", XX, XX, XX }, 695 { "les{S|}", Gv, Mp, XX }, 696 { "ldsS", Gv, Mp, XX }, 697 { "movA", Eb, Ib, XX }, 698 { "movQ", Ev, Iv, XX }, 699 /* c8 */ 700 { "enterT", Iw, Ib, XX }, 701 { "leaveT", XX, XX, XX }, 702 { "lretP", Iw, XX, XX }, 703 { "lretP", XX, XX, XX }, 704 { "int3", XX, XX, XX }, 705 { "int", Ib, XX, XX }, 706 { "into{|}", XX, XX, XX }, 707 { "iretP", XX, XX, XX }, 708 /* d0 */ 709 { GRP2b_one }, 710 { GRP2S_one }, 711 { GRP2b_cl }, 712 { GRP2S_cl }, 713 { "aam{|}", sIb, XX, XX }, 714 { "aad{|}", sIb, XX, XX }, 715 { "(bad)", XX, XX, XX }, 716 { "xlat", DSBX, XX, XX }, 717 /* d8 */ 718 { FLOAT }, 719 { FLOAT }, 720 { FLOAT }, 721 { FLOAT }, 722 { FLOAT }, 723 { FLOAT }, 724 { FLOAT }, 725 { FLOAT }, 726 /* e0 */ 727 { "loopneFH", Jb, XX, loop_jcxz_flag }, 728 { "loopeFH", Jb, XX, loop_jcxz_flag }, 729 { "loopFH", Jb, XX, loop_jcxz_flag }, 730 { "jEcxzH", Jb, XX, loop_jcxz_flag }, 731 { "inB", AL, Ib, XX }, 732 { "inS", eAX, Ib, XX }, 733 { "outB", Ib, AL, XX }, 734 { "outS", Ib, eAX, XX }, 735 /* e8 */ 736 { "callT", Jv, XX, XX }, 737 { "jmpT", Jv, XX, XX }, 738 { "ljmp{T|}", Ap, XX, XX }, 739 { "jmp", Jb, XX, XX }, 740 { "inB", AL, indirDX, XX }, 741 { "inS", eAX, indirDX, XX }, 742 { "outB", indirDX, AL, XX }, 743 { "outS", indirDX, eAX, XX }, 744 /* f0 */ 745 { "(bad)", XX, XX, XX }, /* lock prefix */ 746 { "icebp", XX, XX, XX }, 747 { "(bad)", XX, XX, XX }, /* repne */ 748 { "(bad)", XX, XX, XX }, /* repz */ 749 { "hlt", XX, XX, XX }, 750 { "cmc", XX, XX, XX }, 751 { GRP3b }, 752 { GRP3S }, 753 /* f8 */ 754 { "clc", XX, XX, XX }, 755 { "stc", XX, XX, XX }, 756 { "cli", XX, XX, XX }, 757 { "sti", XX, XX, XX }, 758 { "cld", XX, XX, XX }, 759 { "std", XX, XX, XX }, 760 { GRP4 }, 761 { GRP5 }, 762}; 763 764static const struct dis386 dis386_twobyte[] = { 765 /* 00 */ 766 { GRP6 }, 767 { GRP7 }, 768 { "larS", Gv, Ew, XX }, 769 { "lslS", Gv, Ew, XX }, 770 { "(bad)", XX, XX, XX }, 771 { "syscall", XX, XX, XX }, 772 { "clts", XX, XX, XX }, 773 { "sysretP", XX, XX, XX }, 774 /* 08 */ 775 { "invd", XX, XX, XX }, 776 { "wbinvd", XX, XX, XX }, 777 { "(bad)", XX, XX, XX }, 778 { "ud2a", XX, XX, XX }, 779 { "(bad)", XX, XX, XX }, 780 { GRPAMD }, 781 { "femms", XX, XX, XX }, 782 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */ 783 /* 10 */ 784 { PREGRP8 }, 785 { PREGRP9 }, 786 { PREGRP30 }, 787 { "movlpX", EX, XM, SIMD_Fixup, 'h' }, 788 { "unpcklpX", XM, EX, XX }, 789 { "unpckhpX", XM, EX, XX }, 790 { PREGRP31 }, 791 { "movhpX", EX, XM, SIMD_Fixup, 'l' }, 792 /* 18 */ 793 { GRP14 }, 794 { "(bad)", XX, XX, XX }, 795 { "(bad)", XX, XX, XX }, 796 { "(bad)", XX, XX, XX }, 797 { "(bad)", XX, XX, XX }, 798 { "(bad)", XX, XX, XX }, 799 { "(bad)", XX, XX, XX }, 800 { "(bad)", XX, XX, XX }, 801 /* 20 */ 802 { "movL", Rm, Cm, XX }, 803 { "movL", Rm, Dm, XX }, 804 { "movL", Cm, Rm, XX }, 805 { "movL", Dm, Rm, XX }, 806 { "movL", Rd, Td, XX }, 807 { "(bad)", XX, XX, XX }, 808 { "movL", Td, Rd, XX }, 809 { "(bad)", XX, XX, XX }, 810 /* 28 */ 811 { "movapX", XM, EX, XX }, 812 { "movapX", EX, XM, XX }, 813 { PREGRP2 }, 814 { "movntpX", Ev, XM, XX }, 815 { PREGRP4 }, 816 { PREGRP3 }, 817 { "ucomisX", XM,EX, XX }, 818 { "comisX", XM,EX, XX }, 819 /* 30 */ 820 { "wrmsr", XX, XX, XX }, 821 { "rdtsc", XX, XX, XX }, 822 { "rdmsr", XX, XX, XX }, 823 { "rdpmc", XX, XX, XX }, 824 { "sysenter", XX, XX, XX }, 825 { "sysexit", XX, XX, XX }, 826 { "(bad)", XX, XX, XX }, 827 { "(bad)", XX, XX, XX }, 828 /* 38 */ 829 { "(bad)", XX, XX, XX }, 830 { "(bad)", XX, XX, XX }, 831 { "(bad)", XX, XX, XX }, 832 { "(bad)", XX, XX, XX }, 833 { "(bad)", XX, XX, XX }, 834 { "(bad)", XX, XX, XX }, 835 { "(bad)", XX, XX, XX }, 836 { "(bad)", XX, XX, XX }, 837 /* 40 */ 838 { "cmovo", Gv, Ev, XX }, 839 { "cmovno", Gv, Ev, XX }, 840 { "cmovb", Gv, Ev, XX }, 841 { "cmovae", Gv, Ev, XX }, 842 { "cmove", Gv, Ev, XX }, 843 { "cmovne", Gv, Ev, XX }, 844 { "cmovbe", Gv, Ev, XX }, 845 { "cmova", Gv, Ev, XX }, 846 /* 48 */ 847 { "cmovs", Gv, Ev, XX }, 848 { "cmovns", Gv, Ev, XX }, 849 { "cmovp", Gv, Ev, XX }, 850 { "cmovnp", Gv, Ev, XX }, 851 { "cmovl", Gv, Ev, XX }, 852 { "cmovge", Gv, Ev, XX }, 853 { "cmovle", Gv, Ev, XX }, 854 { "cmovg", Gv, Ev, XX }, 855 /* 50 */ 856 { "movmskpX", Gd, XS, XX }, 857 { PREGRP13 }, 858 { PREGRP12 }, 859 { PREGRP11 }, 860 { "andpX", XM, EX, XX }, 861 { "andnpX", XM, EX, XX }, 862 { "orpX", XM, EX, XX }, 863 { "xorpX", XM, EX, XX }, 864 /* 58 */ 865 { PREGRP0 }, 866 { PREGRP10 }, 867 { PREGRP17 }, 868 { PREGRP16 }, 869 { PREGRP14 }, 870 { PREGRP7 }, 871 { PREGRP5 }, 872 { PREGRP6 }, 873 /* 60 */ 874 { "punpcklbw", MX, EM, XX }, 875 { "punpcklwd", MX, EM, XX }, 876 { "punpckldq", MX, EM, XX }, 877 { "packsswb", MX, EM, XX }, 878 { "pcmpgtb", MX, EM, XX }, 879 { "pcmpgtw", MX, EM, XX }, 880 { "pcmpgtd", MX, EM, XX }, 881 { "packuswb", MX, EM, XX }, 882 /* 68 */ 883 { "punpckhbw", MX, EM, XX }, 884 { "punpckhwd", MX, EM, XX }, 885 { "punpckhdq", MX, EM, XX }, 886 { "packssdw", MX, EM, XX }, 887 { PREGRP26 }, 888 { PREGRP24 }, 889 { "movd", MX, Edq, XX }, 890 { PREGRP19 }, 891 /* 70 */ 892 { PREGRP22 }, 893 { GRP10 }, 894 { GRP11 }, 895 { GRP12 }, 896 { "pcmpeqb", MX, EM, XX }, 897 { "pcmpeqw", MX, EM, XX }, 898 { "pcmpeqd", MX, EM, XX }, 899 { "emms", XX, XX, XX }, 900 /* 78 */ 901 { "(bad)", XX, XX, XX }, 902 { "(bad)", XX, XX, XX }, 903 { "(bad)", XX, XX, XX }, 904 { "(bad)", XX, XX, XX }, 905 { PREGRP28 }, 906 { PREGRP29 }, 907 { PREGRP23 }, 908 { PREGRP20 }, 909 /* 80 */ 910 { "joH", Jv, XX, cond_jump_flag }, 911 { "jnoH", Jv, XX, cond_jump_flag }, 912 { "jbH", Jv, XX, cond_jump_flag }, 913 { "jaeH", Jv, XX, cond_jump_flag }, 914 { "jeH", Jv, XX, cond_jump_flag }, 915 { "jneH", Jv, XX, cond_jump_flag }, 916 { "jbeH", Jv, XX, cond_jump_flag }, 917 { "jaH", Jv, XX, cond_jump_flag }, 918 /* 88 */ 919 { "jsH", Jv, XX, cond_jump_flag }, 920 { "jnsH", Jv, XX, cond_jump_flag }, 921 { "jpH", Jv, XX, cond_jump_flag }, 922 { "jnpH", Jv, XX, cond_jump_flag }, 923 { "jlH", Jv, XX, cond_jump_flag }, 924 { "jgeH", Jv, XX, cond_jump_flag }, 925 { "jleH", Jv, XX, cond_jump_flag }, 926 { "jgH", Jv, XX, cond_jump_flag }, 927 /* 90 */ 928 { "seto", Eb, XX, XX }, 929 { "setno", Eb, XX, XX }, 930 { "setb", Eb, XX, XX }, 931 { "setae", Eb, XX, XX }, 932 { "sete", Eb, XX, XX }, 933 { "setne", Eb, XX, XX }, 934 { "setbe", Eb, XX, XX }, 935 { "seta", Eb, XX, XX }, 936 /* 98 */ 937 { "sets", Eb, XX, XX }, 938 { "setns", Eb, XX, XX }, 939 { "setp", Eb, XX, XX }, 940 { "setnp", Eb, XX, XX }, 941 { "setl", Eb, XX, XX }, 942 { "setge", Eb, XX, XX }, 943 { "setle", Eb, XX, XX }, 944 { "setg", Eb, XX, XX }, 945 /* a0 */ 946 { "pushT", fs, XX, XX }, 947 { "popT", fs, XX, XX }, 948 { "cpuid", XX, XX, XX }, 949 { "btS", Ev, Gv, XX }, 950 { "shldS", Ev, Gv, Ib }, 951 { "shldS", Ev, Gv, CL }, 952 { GRPPADLCK2 }, 953 { GRPPADLCK1 }, 954 /* a8 */ 955 { "pushT", gs, XX, XX }, 956 { "popT", gs, XX, XX }, 957 { "rsm", XX, XX, XX }, 958 { "btsS", Ev, Gv, XX }, 959 { "shrdS", Ev, Gv, Ib }, 960 { "shrdS", Ev, Gv, CL }, 961 { GRP13 }, 962 { "imulS", Gv, Ev, XX }, 963 /* b0 */ 964 { "cmpxchgB", Eb, Gb, XX }, 965 { "cmpxchgS", Ev, Gv, XX }, 966 { "lssS", Gv, Mp, XX }, 967 { "btrS", Ev, Gv, XX }, 968 { "lfsS", Gv, Mp, XX }, 969 { "lgsS", Gv, Mp, XX }, 970 { "movz{bR|x|bR|x}", Gv, Eb, XX }, 971 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */ 972 /* b8 */ 973 { "(bad)", XX, XX, XX }, 974 { "ud2b", XX, XX, XX }, 975 { GRP8 }, 976 { "btcS", Ev, Gv, XX }, 977 { "bsfS", Gv, Ev, XX }, 978 { "bsrS", Gv, Ev, XX }, 979 { "movs{bR|x|bR|x}", Gv, Eb, XX }, 980 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */ 981 /* c0 */ 982 { "xaddB", Eb, Gb, XX }, 983 { "xaddS", Ev, Gv, XX }, 984 { PREGRP1 }, 985 { "movntiS", Ev, Gv, XX }, 986 { "pinsrw", MX, Ed, Ib }, 987 { "pextrw", Gd, MS, Ib }, 988 { "shufpX", XM, EX, Ib }, 989 { GRP9 }, 990 /* c8 */ 991 { "bswap", RMeAX, XX, XX }, 992 { "bswap", RMeCX, XX, XX }, 993 { "bswap", RMeDX, XX, XX }, 994 { "bswap", RMeBX, XX, XX }, 995 { "bswap", RMeSP, XX, XX }, 996 { "bswap", RMeBP, XX, XX }, 997 { "bswap", RMeSI, XX, XX }, 998 { "bswap", RMeDI, XX, XX }, 999 /* d0 */ 1000 { PREGRP27 }, 1001 { "psrlw", MX, EM, XX }, 1002 { "psrld", MX, EM, XX }, 1003 { "psrlq", MX, EM, XX }, 1004 { "paddq", MX, EM, XX }, 1005 { "pmullw", MX, EM, XX }, 1006 { PREGRP21 }, 1007 { "pmovmskb", Gd, MS, XX }, 1008 /* d8 */ 1009 { "psubusb", MX, EM, XX }, 1010 { "psubusw", MX, EM, XX }, 1011 { "pminub", MX, EM, XX }, 1012 { "pand", MX, EM, XX }, 1013 { "paddusb", MX, EM, XX }, 1014 { "paddusw", MX, EM, XX }, 1015 { "pmaxub", MX, EM, XX }, 1016 { "pandn", MX, EM, XX }, 1017 /* e0 */ 1018 { "pavgb", MX, EM, XX }, 1019 { "psraw", MX, EM, XX }, 1020 { "psrad", MX, EM, XX }, 1021 { "pavgw", MX, EM, XX }, 1022 { "pmulhuw", MX, EM, XX }, 1023 { "pmulhw", MX, EM, XX }, 1024 { PREGRP15 }, 1025 { PREGRP25 }, 1026 /* e8 */ 1027 { "psubsb", MX, EM, XX }, 1028 { "psubsw", MX, EM, XX }, 1029 { "pminsw", MX, EM, XX }, 1030 { "por", MX, EM, XX }, 1031 { "paddsb", MX, EM, XX }, 1032 { "paddsw", MX, EM, XX }, 1033 { "pmaxsw", MX, EM, XX }, 1034 { "pxor", MX, EM, XX }, 1035 /* f0 */ 1036 { PREGRP32 }, 1037 { "psllw", MX, EM, XX }, 1038 { "pslld", MX, EM, XX }, 1039 { "psllq", MX, EM, XX }, 1040 { "pmuludq", MX, EM, XX }, 1041 { "pmaddwd", MX, EM, XX }, 1042 { "psadbw", MX, EM, XX }, 1043 { PREGRP18 }, 1044 /* f8 */ 1045 { "psubb", MX, EM, XX }, 1046 { "psubw", MX, EM, XX }, 1047 { "psubd", MX, EM, XX }, 1048 { "psubq", MX, EM, XX }, 1049 { "paddb", MX, EM, XX }, 1050 { "paddw", MX, EM, XX }, 1051 { "paddd", MX, EM, XX }, 1052 { "(bad)", XX, XX, XX } 1053}; 1054 1055static const unsigned char onebyte_has_modrm[256] = { 1056 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1057 /* ------------------------------- */ 1058 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ 1059 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ 1060 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ 1061 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ 1062 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ 1063 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ 1064 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ 1065 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ 1066 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ 1067 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ 1068 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ 1069 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ 1070 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ 1071 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ 1072 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ 1073 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ 1074 /* ------------------------------- */ 1075 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1076}; 1077 1078static const unsigned char twobyte_has_modrm[256] = { 1079 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1080 /* ------------------------------- */ 1081 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ 1082 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ 1083 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ 1084 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ 1085 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ 1086 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ 1087 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ 1088 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */ 1089 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ 1090 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ 1091 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ 1092 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ 1093 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ 1094 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */ 1095 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */ 1096 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */ 1097 /* ------------------------------- */ 1098 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1099}; 1100 1101static const unsigned char twobyte_uses_SSE_prefix[256] = { 1102 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1103 /* ------------------------------- */ 1104 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ 1105 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */ 1106 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ 1107 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ 1108 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ 1109 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */ 1110 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */ 1111 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */ 1112 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ 1113 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ 1114 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ 1115 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ 1116 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ 1117 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ 1118 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */ 1119 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */ 1120 /* ------------------------------- */ 1121 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 1122}; 1123 1124static char obuf[100]; 1125static char *obufp; 1126static char scratchbuf[100]; 1127static unsigned char *start_codep; 1128static unsigned char *insn_codep; 1129static unsigned char *codep; 1130static disassemble_info *the_info; 1131static int mod; 1132static int rm; 1133static int reg; 1134static unsigned char need_modrm; 1135 1136/* If we are accessing mod/rm/reg without need_modrm set, then the 1137 values are stale. Hitting this abort likely indicates that you 1138 need to update onebyte_has_modrm or twobyte_has_modrm. */ 1139#define MODRM_CHECK if (!need_modrm) abort () 1140 1141static const char **names64; 1142static const char **names32; 1143static const char **names16; 1144static const char **names8; 1145static const char **names8rex; 1146static const char **names_seg; 1147static const char **index16; 1148 1149static const char *intel_names64[] = { 1150 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", 1151 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1152}; 1153static const char *intel_names32[] = { 1154 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", 1155 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" 1156}; 1157static const char *intel_names16[] = { 1158 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", 1159 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" 1160}; 1161static const char *intel_names8[] = { 1162 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", 1163}; 1164static const char *intel_names8rex[] = { 1165 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", 1166 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" 1167}; 1168static const char *intel_names_seg[] = { 1169 "es", "cs", "ss", "ds", "fs", "gs", "?", "?", 1170}; 1171static const char *intel_index16[] = { 1172 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" 1173}; 1174 1175static const char *att_names64[] = { 1176 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 1177 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 1178}; 1179static const char *att_names32[] = { 1180 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 1181 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" 1182}; 1183static const char *att_names16[] = { 1184 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", 1185 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" 1186}; 1187static const char *att_names8[] = { 1188 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", 1189}; 1190static const char *att_names8rex[] = { 1191 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", 1192 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" 1193}; 1194static const char *att_names_seg[] = { 1195 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", 1196}; 1197static const char *att_index16[] = { 1198 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" 1199}; 1200 1201static const struct dis386 grps[][8] = { 1202 /* GRP1b */ 1203 { 1204 { "addA", Eb, Ib, XX }, 1205 { "orA", Eb, Ib, XX }, 1206 { "adcA", Eb, Ib, XX }, 1207 { "sbbA", Eb, Ib, XX }, 1208 { "andA", Eb, Ib, XX }, 1209 { "subA", Eb, Ib, XX }, 1210 { "xorA", Eb, Ib, XX }, 1211 { "cmpA", Eb, Ib, XX } 1212 }, 1213 /* GRP1S */ 1214 { 1215 { "addQ", Ev, Iv, XX }, 1216 { "orQ", Ev, Iv, XX }, 1217 { "adcQ", Ev, Iv, XX }, 1218 { "sbbQ", Ev, Iv, XX }, 1219 { "andQ", Ev, Iv, XX }, 1220 { "subQ", Ev, Iv, XX }, 1221 { "xorQ", Ev, Iv, XX }, 1222 { "cmpQ", Ev, Iv, XX } 1223 }, 1224 /* GRP1Ss */ 1225 { 1226 { "addQ", Ev, sIb, XX }, 1227 { "orQ", Ev, sIb, XX }, 1228 { "adcQ", Ev, sIb, XX }, 1229 { "sbbQ", Ev, sIb, XX }, 1230 { "andQ", Ev, sIb, XX }, 1231 { "subQ", Ev, sIb, XX }, 1232 { "xorQ", Ev, sIb, XX }, 1233 { "cmpQ", Ev, sIb, XX } 1234 }, 1235 /* GRP2b */ 1236 { 1237 { "rolA", Eb, Ib, XX }, 1238 { "rorA", Eb, Ib, XX }, 1239 { "rclA", Eb, Ib, XX }, 1240 { "rcrA", Eb, Ib, XX }, 1241 { "shlA", Eb, Ib, XX }, 1242 { "shrA", Eb, Ib, XX }, 1243 { "(bad)", XX, XX, XX }, 1244 { "sarA", Eb, Ib, XX }, 1245 }, 1246 /* GRP2S */ 1247 { 1248 { "rolQ", Ev, Ib, XX }, 1249 { "rorQ", Ev, Ib, XX }, 1250 { "rclQ", Ev, Ib, XX }, 1251 { "rcrQ", Ev, Ib, XX }, 1252 { "shlQ", Ev, Ib, XX }, 1253 { "shrQ", Ev, Ib, XX }, 1254 { "(bad)", XX, XX, XX }, 1255 { "sarQ", Ev, Ib, XX }, 1256 }, 1257 /* GRP2b_one */ 1258 { 1259 { "rolA", Eb, XX, XX }, 1260 { "rorA", Eb, XX, XX }, 1261 { "rclA", Eb, XX, XX }, 1262 { "rcrA", Eb, XX, XX }, 1263 { "shlA", Eb, XX, XX }, 1264 { "shrA", Eb, XX, XX }, 1265 { "(bad)", XX, XX, XX }, 1266 { "sarA", Eb, XX, XX }, 1267 }, 1268 /* GRP2S_one */ 1269 { 1270 { "rolQ", Ev, XX, XX }, 1271 { "rorQ", Ev, XX, XX }, 1272 { "rclQ", Ev, XX, XX }, 1273 { "rcrQ", Ev, XX, XX }, 1274 { "shlQ", Ev, XX, XX }, 1275 { "shrQ", Ev, XX, XX }, 1276 { "(bad)", XX, XX, XX}, 1277 { "sarQ", Ev, XX, XX }, 1278 }, 1279 /* GRP2b_cl */ 1280 { 1281 { "rolA", Eb, CL, XX }, 1282 { "rorA", Eb, CL, XX }, 1283 { "rclA", Eb, CL, XX }, 1284 { "rcrA", Eb, CL, XX }, 1285 { "shlA", Eb, CL, XX }, 1286 { "shrA", Eb, CL, XX }, 1287 { "(bad)", XX, XX, XX }, 1288 { "sarA", Eb, CL, XX }, 1289 }, 1290 /* GRP2S_cl */ 1291 { 1292 { "rolQ", Ev, CL, XX }, 1293 { "rorQ", Ev, CL, XX }, 1294 { "rclQ", Ev, CL, XX }, 1295 { "rcrQ", Ev, CL, XX }, 1296 { "shlQ", Ev, CL, XX }, 1297 { "shrQ", Ev, CL, XX }, 1298 { "(bad)", XX, XX, XX }, 1299 { "sarQ", Ev, CL, XX } 1300 }, 1301 /* GRP3b */ 1302 { 1303 { "testA", Eb, Ib, XX }, 1304 { "(bad)", Eb, XX, XX }, 1305 { "notA", Eb, XX, XX }, 1306 { "negA", Eb, XX, XX }, 1307 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */ 1308 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */ 1309 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */ 1310 { "idivA", Eb, XX, XX } /* and idiv for consistency. */ 1311 }, 1312 /* GRP3S */ 1313 { 1314 { "testQ", Ev, Iv, XX }, 1315 { "(bad)", XX, XX, XX }, 1316 { "notQ", Ev, XX, XX }, 1317 { "negQ", Ev, XX, XX }, 1318 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */ 1319 { "imulQ", Ev, XX, XX }, 1320 { "divQ", Ev, XX, XX }, 1321 { "idivQ", Ev, XX, XX }, 1322 }, 1323 /* GRP4 */ 1324 { 1325 { "incA", Eb, XX, XX }, 1326 { "decA", Eb, XX, XX }, 1327 { "(bad)", XX, XX, XX }, 1328 { "(bad)", XX, XX, XX }, 1329 { "(bad)", XX, XX, XX }, 1330 { "(bad)", XX, XX, XX }, 1331 { "(bad)", XX, XX, XX }, 1332 { "(bad)", XX, XX, XX }, 1333 }, 1334 /* GRP5 */ 1335 { 1336 { "incQ", Ev, XX, XX }, 1337 { "decQ", Ev, XX, XX }, 1338 { "callT", indirEv, XX, XX }, 1339 { "lcallT", indirEv, XX, XX }, 1340 { "jmpT", indirEv, XX, XX }, 1341 { "ljmpT", indirEv, XX, XX }, 1342 { "pushU", Ev, XX, XX }, 1343 { "(bad)", XX, XX, XX }, 1344 }, 1345 /* GRP6 */ 1346 { 1347 { "sldtQ", Ev, XX, XX }, 1348 { "strQ", Ev, XX, XX }, 1349 { "lldt", Ew, XX, XX }, 1350 { "ltr", Ew, XX, XX }, 1351 { "verr", Ew, XX, XX }, 1352 { "verw", Ew, XX, XX }, 1353 { "(bad)", XX, XX, XX }, 1354 { "(bad)", XX, XX, XX } 1355 }, 1356 /* GRP7 */ 1357 { 1358 { "sgdtQ", M, XX, XX }, 1359 { "sidtQ", PNI_Fixup, 0, XX, XX }, 1360 { "lgdtQ", M, XX, XX }, 1361 { "lidtQ", M, XX, XX }, 1362 { "smswQ", Ev, XX, XX }, 1363 { "(bad)", XX, XX, XX }, 1364 { "lmsw", Ew, XX, XX }, 1365 { "invlpg", INVLPG_Fixup, w_mode, XX, XX }, 1366 }, 1367 /* GRP8 */ 1368 { 1369 { "(bad)", XX, XX, XX }, 1370 { "(bad)", XX, XX, XX }, 1371 { "(bad)", XX, XX, XX }, 1372 { "(bad)", XX, XX, XX }, 1373 { "btQ", Ev, Ib, XX }, 1374 { "btsQ", Ev, Ib, XX }, 1375 { "btrQ", Ev, Ib, XX }, 1376 { "btcQ", Ev, Ib, XX }, 1377 }, 1378 /* GRP9 */ 1379 { 1380 { "(bad)", XX, XX, XX }, 1381 { "cmpxchg8b", Ev, XX, XX }, 1382 { "(bad)", XX, XX, XX }, 1383 { "(bad)", XX, XX, XX }, 1384 { "(bad)", XX, XX, XX }, 1385 { "(bad)", XX, XX, XX }, 1386 { "(bad)", XX, XX, XX }, 1387 { "(bad)", XX, XX, XX }, 1388 }, 1389 /* GRP10 */ 1390 { 1391 { "(bad)", XX, XX, XX }, 1392 { "(bad)", XX, XX, XX }, 1393 { "psrlw", MS, Ib, XX }, 1394 { "(bad)", XX, XX, XX }, 1395 { "psraw", MS, Ib, XX }, 1396 { "(bad)", XX, XX, XX }, 1397 { "psllw", MS, Ib, XX }, 1398 { "(bad)", XX, XX, XX }, 1399 }, 1400 /* GRP11 */ 1401 { 1402 { "(bad)", XX, XX, XX }, 1403 { "(bad)", XX, XX, XX }, 1404 { "psrld", MS, Ib, XX }, 1405 { "(bad)", XX, XX, XX }, 1406 { "psrad", MS, Ib, XX }, 1407 { "(bad)", XX, XX, XX }, 1408 { "pslld", MS, Ib, XX }, 1409 { "(bad)", XX, XX, XX }, 1410 }, 1411 /* GRP12 */ 1412 { 1413 { "(bad)", XX, XX, XX }, 1414 { "(bad)", XX, XX, XX }, 1415 { "psrlq", MS, Ib, XX }, 1416 { "psrldq", MS, Ib, XX }, 1417 { "(bad)", XX, XX, XX }, 1418 { "(bad)", XX, XX, XX }, 1419 { "psllq", MS, Ib, XX }, 1420 { "pslldq", MS, Ib, XX }, 1421 }, 1422 /* GRP13 */ 1423 { 1424 { "fxsave", Ev, XX, XX }, 1425 { "fxrstor", Ev, XX, XX }, 1426 { "ldmxcsr", Ev, XX, XX }, 1427 { "stmxcsr", Ev, XX, XX }, 1428 { "(bad)", XX, XX, XX }, 1429 { "lfence", OP_0fae, 0, XX, XX }, 1430 { "mfence", OP_0fae, 0, XX, XX }, 1431 { "clflush", OP_0fae, 0, XX, XX }, 1432 }, 1433 /* GRP14 */ 1434 { 1435 { "prefetchnta", Ev, XX, XX }, 1436 { "prefetcht0", Ev, XX, XX }, 1437 { "prefetcht1", Ev, XX, XX }, 1438 { "prefetcht2", Ev, XX, XX }, 1439 { "(bad)", XX, XX, XX }, 1440 { "(bad)", XX, XX, XX }, 1441 { "(bad)", XX, XX, XX }, 1442 { "(bad)", XX, XX, XX }, 1443 }, 1444 /* GRPAMD */ 1445 { 1446 { "prefetch", Eb, XX, XX }, 1447 { "prefetchw", Eb, XX, XX }, 1448 { "(bad)", XX, XX, XX }, 1449 { "(bad)", XX, XX, XX }, 1450 { "(bad)", XX, XX, XX }, 1451 { "(bad)", XX, XX, XX }, 1452 { "(bad)", XX, XX, XX }, 1453 { "(bad)", XX, XX, XX }, 1454 }, 1455 /* GRPPADLCK1 */ 1456 { 1457 { "xstorerng", OP_0f07, 0, XX, XX }, 1458 { "xcryptecb", OP_0f07, 0, XX, XX }, 1459 { "xcryptcbc", OP_0f07, 0, XX, XX }, 1460 { "(bad)", OP_0f07, 0, XX, XX }, 1461 { "xcryptcfb", OP_0f07, 0, XX, XX }, 1462 { "xcryptofb", OP_0f07, 0, XX, XX }, 1463 { "(bad)", OP_0f07, 0, XX, XX }, 1464 { "(bad)", OP_0f07, 0, XX, XX }, 1465 }, 1466 /* GRPPADLCK2 */ 1467 { 1468 { "montmul", OP_0f07, 0, XX, XX }, 1469 { "xsha1", OP_0f07, 0, XX, XX }, 1470 { "xsha256", OP_0f07, 0, XX, XX }, 1471 { "(bad)", OP_0f07, 0, XX, XX }, 1472 { "(bad)", OP_0f07, 0, XX, XX }, 1473 { "(bad)", OP_0f07, 0, XX, XX }, 1474 { "(bad)", OP_0f07, 0, XX, XX }, 1475 { "(bad)", OP_0f07, 0, XX, XX }, 1476 } 1477}; 1478 1479static const struct dis386 prefix_user_table[][4] = { 1480 /* PREGRP0 */ 1481 { 1482 { "addps", XM, EX, XX }, 1483 { "addss", XM, EX, XX }, 1484 { "addpd", XM, EX, XX }, 1485 { "addsd", XM, EX, XX }, 1486 }, 1487 /* PREGRP1 */ 1488 { 1489 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */ 1490 { "", XM, EX, OPSIMD }, 1491 { "", XM, EX, OPSIMD }, 1492 { "", XM, EX, OPSIMD }, 1493 }, 1494 /* PREGRP2 */ 1495 { 1496 { "cvtpi2ps", XM, EM, XX }, 1497 { "cvtsi2ssY", XM, Ev, XX }, 1498 { "cvtpi2pd", XM, EM, XX }, 1499 { "cvtsi2sdY", XM, Ev, XX }, 1500 }, 1501 /* PREGRP3 */ 1502 { 1503 { "cvtps2pi", MX, EX, XX }, 1504 { "cvtss2siY", Gv, EX, XX }, 1505 { "cvtpd2pi", MX, EX, XX }, 1506 { "cvtsd2siY", Gv, EX, XX }, 1507 }, 1508 /* PREGRP4 */ 1509 { 1510 { "cvttps2pi", MX, EX, XX }, 1511 { "cvttss2siY", Gv, EX, XX }, 1512 { "cvttpd2pi", MX, EX, XX }, 1513 { "cvttsd2siY", Gv, EX, XX }, 1514 }, 1515 /* PREGRP5 */ 1516 { 1517 { "divps", XM, EX, XX }, 1518 { "divss", XM, EX, XX }, 1519 { "divpd", XM, EX, XX }, 1520 { "divsd", XM, EX, XX }, 1521 }, 1522 /* PREGRP6 */ 1523 { 1524 { "maxps", XM, EX, XX }, 1525 { "maxss", XM, EX, XX }, 1526 { "maxpd", XM, EX, XX }, 1527 { "maxsd", XM, EX, XX }, 1528 }, 1529 /* PREGRP7 */ 1530 { 1531 { "minps", XM, EX, XX }, 1532 { "minss", XM, EX, XX }, 1533 { "minpd", XM, EX, XX }, 1534 { "minsd", XM, EX, XX }, 1535 }, 1536 /* PREGRP8 */ 1537 { 1538 { "movups", XM, EX, XX }, 1539 { "movss", XM, EX, XX }, 1540 { "movupd", XM, EX, XX }, 1541 { "movsd", XM, EX, XX }, 1542 }, 1543 /* PREGRP9 */ 1544 { 1545 { "movups", EX, XM, XX }, 1546 { "movss", EX, XM, XX }, 1547 { "movupd", EX, XM, XX }, 1548 { "movsd", EX, XM, XX }, 1549 }, 1550 /* PREGRP10 */ 1551 { 1552 { "mulps", XM, EX, XX }, 1553 { "mulss", XM, EX, XX }, 1554 { "mulpd", XM, EX, XX }, 1555 { "mulsd", XM, EX, XX }, 1556 }, 1557 /* PREGRP11 */ 1558 { 1559 { "rcpps", XM, EX, XX }, 1560 { "rcpss", XM, EX, XX }, 1561 { "(bad)", XM, EX, XX }, 1562 { "(bad)", XM, EX, XX }, 1563 }, 1564 /* PREGRP12 */ 1565 { 1566 { "rsqrtps", XM, EX, XX }, 1567 { "rsqrtss", XM, EX, XX }, 1568 { "(bad)", XM, EX, XX }, 1569 { "(bad)", XM, EX, XX }, 1570 }, 1571 /* PREGRP13 */ 1572 { 1573 { "sqrtps", XM, EX, XX }, 1574 { "sqrtss", XM, EX, XX }, 1575 { "sqrtpd", XM, EX, XX }, 1576 { "sqrtsd", XM, EX, XX }, 1577 }, 1578 /* PREGRP14 */ 1579 { 1580 { "subps", XM, EX, XX }, 1581 { "subss", XM, EX, XX }, 1582 { "subpd", XM, EX, XX }, 1583 { "subsd", XM, EX, XX }, 1584 }, 1585 /* PREGRP15 */ 1586 { 1587 { "(bad)", XM, EX, XX }, 1588 { "cvtdq2pd", XM, EX, XX }, 1589 { "cvttpd2dq", XM, EX, XX }, 1590 { "cvtpd2dq", XM, EX, XX }, 1591 }, 1592 /* PREGRP16 */ 1593 { 1594 { "cvtdq2ps", XM, EX, XX }, 1595 { "cvttps2dq",XM, EX, XX }, 1596 { "cvtps2dq",XM, EX, XX }, 1597 { "(bad)", XM, EX, XX }, 1598 }, 1599 /* PREGRP17 */ 1600 { 1601 { "cvtps2pd", XM, EX, XX }, 1602 { "cvtss2sd", XM, EX, XX }, 1603 { "cvtpd2ps", XM, EX, XX }, 1604 { "cvtsd2ss", XM, EX, XX }, 1605 }, 1606 /* PREGRP18 */ 1607 { 1608 { "maskmovq", MX, MS, XX }, 1609 { "(bad)", XM, EX, XX }, 1610 { "maskmovdqu", XM, EX, XX }, 1611 { "(bad)", XM, EX, XX }, 1612 }, 1613 /* PREGRP19 */ 1614 { 1615 { "movq", MX, EM, XX }, 1616 { "movdqu", XM, EX, XX }, 1617 { "movdqa", XM, EX, XX }, 1618 { "(bad)", XM, EX, XX }, 1619 }, 1620 /* PREGRP20 */ 1621 { 1622 { "movq", EM, MX, XX }, 1623 { "movdqu", EX, XM, XX }, 1624 { "movdqa", EX, XM, XX }, 1625 { "(bad)", EX, XM, XX }, 1626 }, 1627 /* PREGRP21 */ 1628 { 1629 { "(bad)", EX, XM, XX }, 1630 { "movq2dq", XM, MS, XX }, 1631 { "movq", EX, XM, XX }, 1632 { "movdq2q", MX, XS, XX }, 1633 }, 1634 /* PREGRP22 */ 1635 { 1636 { "pshufw", MX, EM, Ib }, 1637 { "pshufhw", XM, EX, Ib }, 1638 { "pshufd", XM, EX, Ib }, 1639 { "pshuflw", XM, EX, Ib }, 1640 }, 1641 /* PREGRP23 */ 1642 { 1643 { "movd", Edq, MX, XX }, 1644 { "movq", XM, EX, XX }, 1645 { "movd", Edq, XM, XX }, 1646 { "(bad)", Ed, XM, XX }, 1647 }, 1648 /* PREGRP24 */ 1649 { 1650 { "(bad)", MX, EX, XX }, 1651 { "(bad)", XM, EX, XX }, 1652 { "punpckhqdq", XM, EX, XX }, 1653 { "(bad)", XM, EX, XX }, 1654 }, 1655 /* PREGRP25 */ 1656 { 1657 { "movntq", Ev, MX, XX }, 1658 { "(bad)", Ev, XM, XX }, 1659 { "movntdq", Ev, XM, XX }, 1660 { "(bad)", Ev, XM, XX }, 1661 }, 1662 /* PREGRP26 */ 1663 { 1664 { "(bad)", MX, EX, XX }, 1665 { "(bad)", XM, EX, XX }, 1666 { "punpcklqdq", XM, EX, XX }, 1667 { "(bad)", XM, EX, XX }, 1668 }, 1669 /* PREGRP27 */ 1670 { 1671 { "(bad)", MX, EX, XX }, 1672 { "(bad)", XM, EX, XX }, 1673 { "addsubpd", XM, EX, XX }, 1674 { "addsubps", XM, EX, XX }, 1675 }, 1676 /* PREGRP28 */ 1677 { 1678 { "(bad)", MX, EX, XX }, 1679 { "(bad)", XM, EX, XX }, 1680 { "haddpd", XM, EX, XX }, 1681 { "haddps", XM, EX, XX }, 1682 }, 1683 /* PREGRP29 */ 1684 { 1685 { "(bad)", MX, EX, XX }, 1686 { "(bad)", XM, EX, XX }, 1687 { "hsubpd", XM, EX, XX }, 1688 { "hsubps", XM, EX, XX }, 1689 }, 1690 /* PREGRP30 */ 1691 { 1692 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ 1693 { "movsldup", XM, EX, XX }, 1694 { "movlpd", XM, EX, XX }, 1695 { "movddup", XM, EX, XX }, 1696 }, 1697 /* PREGRP31 */ 1698 { 1699 { "movhpX", XM, EX, SIMD_Fixup, 'l' }, 1700 { "movshdup", XM, EX, XX }, 1701 { "movhpd", XM, EX, XX }, 1702 { "(bad)", XM, EX, XX }, 1703 }, 1704 /* PREGRP32 */ 1705 { 1706 { "(bad)", XM, EX, XX }, 1707 { "(bad)", XM, EX, XX }, 1708 { "(bad)", XM, EX, XX }, 1709 { "lddqu", XM, M, XX }, 1710 }, 1711}; 1712 1713static const struct dis386 x86_64_table[][2] = { 1714 { 1715 { "arpl", Ew, Gw, XX }, 1716 { "movs{||lq|xd}", Gv, Ed, XX }, 1717 }, 1718}; 1719 1720#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") 1721 1722static void 1723ckprefix (void) 1724{ 1725 int newrex; 1726 rex = 0; 1727 prefixes = 0; 1728 used_prefixes = 0; 1729 rex_used = 0; 1730 while (1) 1731 { 1732 FETCH_DATA (the_info, codep + 1); 1733 newrex = 0; 1734 switch (*codep) 1735 { 1736 /* REX prefixes family. */ 1737 case 0x40: 1738 case 0x41: 1739 case 0x42: 1740 case 0x43: 1741 case 0x44: 1742 case 0x45: 1743 case 0x46: 1744 case 0x47: 1745 case 0x48: 1746 case 0x49: 1747 case 0x4a: 1748 case 0x4b: 1749 case 0x4c: 1750 case 0x4d: 1751 case 0x4e: 1752 case 0x4f: 1753 if (mode_64bit) 1754 newrex = *codep; 1755 else 1756 return; 1757 break; 1758 case 0xf3: 1759 prefixes |= PREFIX_REPZ; 1760 break; 1761 case 0xf2: 1762 prefixes |= PREFIX_REPNZ; 1763 break; 1764 case 0xf0: 1765 prefixes |= PREFIX_LOCK; 1766 break; 1767 case 0x2e: 1768 prefixes |= PREFIX_CS; 1769 break; 1770 case 0x36: 1771 prefixes |= PREFIX_SS; 1772 break; 1773 case 0x3e: 1774 prefixes |= PREFIX_DS; 1775 break; 1776 case 0x26: 1777 prefixes |= PREFIX_ES; 1778 break; 1779 case 0x64: 1780 prefixes |= PREFIX_FS; 1781 break; 1782 case 0x65: 1783 prefixes |= PREFIX_GS; 1784 break; 1785 case 0x66: 1786 prefixes |= PREFIX_DATA; 1787 break; 1788 case 0x67: 1789 prefixes |= PREFIX_ADDR; 1790 break; 1791 case FWAIT_OPCODE: 1792 /* fwait is really an instruction. If there are prefixes 1793 before the fwait, they belong to the fwait, *not* to the 1794 following instruction. */ 1795 if (prefixes) 1796 { 1797 prefixes |= PREFIX_FWAIT; 1798 codep++; 1799 return; 1800 } 1801 prefixes = PREFIX_FWAIT; 1802 break; 1803 default: 1804 return; 1805 } 1806 /* Rex is ignored when followed by another prefix. */ 1807 if (rex) 1808 { 1809 oappend (prefix_name (rex, 0)); 1810 oappend (" "); 1811 } 1812 rex = newrex; 1813 codep++; 1814 } 1815} 1816 1817/* Return the name of the prefix byte PREF, or NULL if PREF is not a 1818 prefix byte. */ 1819 1820static const char * 1821prefix_name (int pref, int sizeflag) 1822{ 1823 switch (pref) 1824 { 1825 /* REX prefixes family. */ 1826 case 0x40: 1827 return "rex"; 1828 case 0x41: 1829 return "rexZ"; 1830 case 0x42: 1831 return "rexY"; 1832 case 0x43: 1833 return "rexYZ"; 1834 case 0x44: 1835 return "rexX"; 1836 case 0x45: 1837 return "rexXZ"; 1838 case 0x46: 1839 return "rexXY"; 1840 case 0x47: 1841 return "rexXYZ"; 1842 case 0x48: 1843 return "rex64"; 1844 case 0x49: 1845 return "rex64Z"; 1846 case 0x4a: 1847 return "rex64Y"; 1848 case 0x4b: 1849 return "rex64YZ"; 1850 case 0x4c: 1851 return "rex64X"; 1852 case 0x4d: 1853 return "rex64XZ"; 1854 case 0x4e: 1855 return "rex64XY"; 1856 case 0x4f: 1857 return "rex64XYZ"; 1858 case 0xf3: 1859 return "repz"; 1860 case 0xf2: 1861 return "repnz"; 1862 case 0xf0: 1863 return "lock"; 1864 case 0x2e: 1865 return "cs"; 1866 case 0x36: 1867 return "ss"; 1868 case 0x3e: 1869 return "ds"; 1870 case 0x26: 1871 return "es"; 1872 case 0x64: 1873 return "fs"; 1874 case 0x65: 1875 return "gs"; 1876 case 0x66: 1877 return (sizeflag & DFLAG) ? "data16" : "data32"; 1878 case 0x67: 1879 if (mode_64bit) 1880 return (sizeflag & AFLAG) ? "addr32" : "addr64"; 1881 else 1882 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32"; 1883 case FWAIT_OPCODE: 1884 return "fwait"; 1885 default: 1886 return NULL; 1887 } 1888} 1889 1890static char op1out[100], op2out[100], op3out[100]; 1891static int op_ad, op_index[3]; 1892static int two_source_ops; 1893static bfd_vma op_address[3]; 1894static bfd_vma op_riprel[3]; 1895static bfd_vma start_pc; 1896 1897/* 1898 * On the 386's of 1988, the maximum length of an instruction is 15 bytes. 1899 * (see topic "Redundant prefixes" in the "Differences from 8086" 1900 * section of the "Virtual 8086 Mode" chapter.) 1901 * 'pc' should be the address of this instruction, it will 1902 * be used to print the target address if this is a relative jump or call 1903 * The function returns the length of this instruction in bytes. 1904 */ 1905 1906static char intel_syntax; 1907static char open_char; 1908static char close_char; 1909static char separator_char; 1910static char scale_char; 1911 1912/* Here for backwards compatibility. When gdb stops using 1913 print_insn_i386_att and print_insn_i386_intel these functions can 1914 disappear, and print_insn_i386 be merged into print_insn. */ 1915int 1916print_insn_i386_att (bfd_vma pc, disassemble_info *info) 1917{ 1918 intel_syntax = 0; 1919 1920 return print_insn (pc, info); 1921} 1922 1923int 1924print_insn_i386_intel (bfd_vma pc, disassemble_info *info) 1925{ 1926 intel_syntax = 1; 1927 1928 return print_insn (pc, info); 1929} 1930 1931int 1932print_insn_i386 (bfd_vma pc, disassemble_info *info) 1933{ 1934 intel_syntax = -1; 1935 1936 return print_insn (pc, info); 1937} 1938 1939static int 1940print_insn (bfd_vma pc, disassemble_info *info) 1941{ 1942 const struct dis386 *dp; 1943 int i; 1944 char *first, *second, *third; 1945 int needcomma; 1946 unsigned char uses_SSE_prefix; 1947 int sizeflag; 1948 const char *p; 1949 struct dis_private priv; 1950 1951 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax 1952 || info->mach == bfd_mach_x86_64); 1953 1954 if (intel_syntax == (char) -1) 1955 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax 1956 || info->mach == bfd_mach_x86_64_intel_syntax); 1957 1958 if (info->mach == bfd_mach_i386_i386 1959 || info->mach == bfd_mach_x86_64 1960 || info->mach == bfd_mach_i386_i386_intel_syntax 1961 || info->mach == bfd_mach_x86_64_intel_syntax) 1962 priv.orig_sizeflag = AFLAG | DFLAG; 1963 else if (info->mach == bfd_mach_i386_i8086) 1964 priv.orig_sizeflag = 0; 1965 else 1966 abort (); 1967 1968 for (p = info->disassembler_options; p != NULL; ) 1969 { 1970 if (strncmp (p, "x86-64", 6) == 0) 1971 { 1972 mode_64bit = 1; 1973 priv.orig_sizeflag = AFLAG | DFLAG; 1974 } 1975 else if (strncmp (p, "i386", 4) == 0) 1976 { 1977 mode_64bit = 0; 1978 priv.orig_sizeflag = AFLAG | DFLAG; 1979 } 1980 else if (strncmp (p, "i8086", 5) == 0) 1981 { 1982 mode_64bit = 0; 1983 priv.orig_sizeflag = 0; 1984 } 1985 else if (strncmp (p, "intel", 5) == 0) 1986 { 1987 intel_syntax = 1; 1988 } 1989 else if (strncmp (p, "att", 3) == 0) 1990 { 1991 intel_syntax = 0; 1992 } 1993 else if (strncmp (p, "addr", 4) == 0) 1994 { 1995 if (p[4] == '1' && p[5] == '6') 1996 priv.orig_sizeflag &= ~AFLAG; 1997 else if (p[4] == '3' && p[5] == '2') 1998 priv.orig_sizeflag |= AFLAG; 1999 } 2000 else if (strncmp (p, "data", 4) == 0) 2001 { 2002 if (p[4] == '1' && p[5] == '6') 2003 priv.orig_sizeflag &= ~DFLAG; 2004 else if (p[4] == '3' && p[5] == '2') 2005 priv.orig_sizeflag |= DFLAG; 2006 } 2007 else if (strncmp (p, "suffix", 6) == 0) 2008 priv.orig_sizeflag |= SUFFIX_ALWAYS; 2009 2010 p = strchr (p, ','); 2011 if (p != NULL) 2012 p++; 2013 } 2014 2015 if (intel_syntax) 2016 { 2017 names64 = intel_names64; 2018 names32 = intel_names32; 2019 names16 = intel_names16; 2020 names8 = intel_names8; 2021 names8rex = intel_names8rex; 2022 names_seg = intel_names_seg; 2023 index16 = intel_index16; 2024 open_char = '['; 2025 close_char = ']'; 2026 separator_char = '+'; 2027 scale_char = '*'; 2028 } 2029 else 2030 { 2031 names64 = att_names64; 2032 names32 = att_names32; 2033 names16 = att_names16; 2034 names8 = att_names8; 2035 names8rex = att_names8rex; 2036 names_seg = att_names_seg; 2037 index16 = att_index16; 2038 open_char = '('; 2039 close_char = ')'; 2040 separator_char = ','; 2041 scale_char = ','; 2042 } 2043 2044 /* The output looks better if we put 7 bytes on a line, since that 2045 puts most long word instructions on a single line. */ 2046 info->bytes_per_line = 7; 2047 2048 info->private_data = &priv; 2049 priv.max_fetched = priv.the_buffer; 2050 priv.insn_start = pc; 2051 2052 obuf[0] = 0; 2053 op1out[0] = 0; 2054 op2out[0] = 0; 2055 op3out[0] = 0; 2056 2057 op_index[0] = op_index[1] = op_index[2] = -1; 2058 2059 the_info = info; 2060 start_pc = pc; 2061 start_codep = priv.the_buffer; 2062 codep = priv.the_buffer; 2063 2064 if (setjmp (priv.bailout) != 0) 2065 { 2066 const char *name; 2067 2068 /* Getting here means we tried for data but didn't get it. That 2069 means we have an incomplete instruction of some sort. Just 2070 print the first byte as a prefix or a .byte pseudo-op. */ 2071 if (codep > priv.the_buffer) 2072 { 2073 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 2074 if (name != NULL) 2075 (*info->fprintf_func) (info->stream, "%s", name); 2076 else 2077 { 2078 /* Just print the first byte as a .byte instruction. */ 2079 (*info->fprintf_func) (info->stream, ".byte 0x%x", 2080 (unsigned int) priv.the_buffer[0]); 2081 } 2082 2083 return 1; 2084 } 2085 2086 return -1; 2087 } 2088 2089 obufp = obuf; 2090 ckprefix (); 2091 2092 insn_codep = codep; 2093 sizeflag = priv.orig_sizeflag; 2094 2095 FETCH_DATA (info, codep + 1); 2096 two_source_ops = (*codep == 0x62) || (*codep == 0xc8); 2097 2098 if ((prefixes & PREFIX_FWAIT) 2099 && ((*codep < 0xd8) || (*codep > 0xdf))) 2100 { 2101 const char *name; 2102 2103 /* fwait not followed by floating point instruction. Print the 2104 first prefix, which is probably fwait itself. */ 2105 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 2106 if (name == NULL) 2107 name = INTERNAL_DISASSEMBLER_ERROR; 2108 (*info->fprintf_func) (info->stream, "%s", name); 2109 return 1; 2110 } 2111 2112 if (*codep == 0x0f) 2113 { 2114 FETCH_DATA (info, codep + 2); 2115 dp = &dis386_twobyte[*++codep]; 2116 need_modrm = twobyte_has_modrm[*codep]; 2117 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; 2118 } 2119 else 2120 { 2121 dp = &dis386[*codep]; 2122 need_modrm = onebyte_has_modrm[*codep]; 2123 uses_SSE_prefix = 0; 2124 } 2125 codep++; 2126 2127 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) 2128 { 2129 oappend ("repz "); 2130 used_prefixes |= PREFIX_REPZ; 2131 } 2132 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) 2133 { 2134 oappend ("repnz "); 2135 used_prefixes |= PREFIX_REPNZ; 2136 } 2137 if (prefixes & PREFIX_LOCK) 2138 { 2139 oappend ("lock "); 2140 used_prefixes |= PREFIX_LOCK; 2141 } 2142 2143 if (prefixes & PREFIX_ADDR) 2144 { 2145 sizeflag ^= AFLAG; 2146 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) 2147 { 2148 if ((sizeflag & AFLAG) || mode_64bit) 2149 oappend ("addr32 "); 2150 else 2151 oappend ("addr16 "); 2152 used_prefixes |= PREFIX_ADDR; 2153 } 2154 } 2155 2156 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) 2157 { 2158 sizeflag ^= DFLAG; 2159 if (dp->bytemode3 == cond_jump_mode 2160 && dp->bytemode1 == v_mode 2161 && !intel_syntax) 2162 { 2163 if (sizeflag & DFLAG) 2164 oappend ("data32 "); 2165 else 2166 oappend ("data16 "); 2167 used_prefixes |= PREFIX_DATA; 2168 } 2169 } 2170 2171 if (need_modrm) 2172 { 2173 FETCH_DATA (info, codep + 1); 2174 mod = (*codep >> 6) & 3; 2175 reg = (*codep >> 3) & 7; 2176 rm = *codep & 7; 2177 } 2178 2179 if (dp->name == NULL && dp->bytemode1 == FLOATCODE) 2180 { 2181 dofloat (sizeflag); 2182 } 2183 else 2184 { 2185 int index; 2186 if (dp->name == NULL) 2187 { 2188 switch (dp->bytemode1) 2189 { 2190 case USE_GROUPS: 2191 dp = &grps[dp->bytemode2][reg]; 2192 break; 2193 2194 case USE_PREFIX_USER_TABLE: 2195 index = 0; 2196 used_prefixes |= (prefixes & PREFIX_REPZ); 2197 if (prefixes & PREFIX_REPZ) 2198 index = 1; 2199 else 2200 { 2201 used_prefixes |= (prefixes & PREFIX_DATA); 2202 if (prefixes & PREFIX_DATA) 2203 index = 2; 2204 else 2205 { 2206 used_prefixes |= (prefixes & PREFIX_REPNZ); 2207 if (prefixes & PREFIX_REPNZ) 2208 index = 3; 2209 } 2210 } 2211 dp = &prefix_user_table[dp->bytemode2][index]; 2212 break; 2213 2214 case X86_64_SPECIAL: 2215 dp = &x86_64_table[dp->bytemode2][mode_64bit]; 2216 break; 2217 2218 default: 2219 oappend (INTERNAL_DISASSEMBLER_ERROR); 2220 break; 2221 } 2222 } 2223 2224 if (putop (dp->name, sizeflag) == 0) 2225 { 2226 obufp = op1out; 2227 op_ad = 2; 2228 if (dp->op1) 2229 (*dp->op1) (dp->bytemode1, sizeflag); 2230 2231 obufp = op2out; 2232 op_ad = 1; 2233 if (dp->op2) 2234 (*dp->op2) (dp->bytemode2, sizeflag); 2235 2236 obufp = op3out; 2237 op_ad = 0; 2238 if (dp->op3) 2239 (*dp->op3) (dp->bytemode3, sizeflag); 2240 } 2241 } 2242 2243 /* See if any prefixes were not used. If so, print the first one 2244 separately. If we don't do this, we'll wind up printing an 2245 instruction stream which does not precisely correspond to the 2246 bytes we are disassembling. */ 2247 if ((prefixes & ~used_prefixes) != 0) 2248 { 2249 const char *name; 2250 2251 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); 2252 if (name == NULL) 2253 name = INTERNAL_DISASSEMBLER_ERROR; 2254 (*info->fprintf_func) (info->stream, "%s", name); 2255 return 1; 2256 } 2257 if (rex & ~rex_used) 2258 { 2259 const char *name; 2260 name = prefix_name (rex | 0x40, priv.orig_sizeflag); 2261 if (name == NULL) 2262 name = INTERNAL_DISASSEMBLER_ERROR; 2263 (*info->fprintf_func) (info->stream, "%s ", name); 2264 } 2265 2266 obufp = obuf + strlen (obuf); 2267 for (i = strlen (obuf); i < 6; i++) 2268 oappend (" "); 2269 oappend (" "); 2270 (*info->fprintf_func) (info->stream, "%s", obuf); 2271 2272 /* The enter and bound instructions are printed with operands in the same 2273 order as the intel book; everything else is printed in reverse order. */ 2274 if (intel_syntax || two_source_ops) 2275 { 2276 first = op1out; 2277 second = op2out; 2278 third = op3out; 2279 op_ad = op_index[0]; 2280 op_index[0] = op_index[2]; 2281 op_index[2] = op_ad; 2282 } 2283 else 2284 { 2285 first = op3out; 2286 second = op2out; 2287 third = op1out; 2288 } 2289 needcomma = 0; 2290 if (*first) 2291 { 2292 if (op_index[0] != -1 && !op_riprel[0]) 2293 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); 2294 else 2295 (*info->fprintf_func) (info->stream, "%s", first); 2296 needcomma = 1; 2297 } 2298 if (*second) 2299 { 2300 if (needcomma) 2301 (*info->fprintf_func) (info->stream, ","); 2302 if (op_index[1] != -1 && !op_riprel[1]) 2303 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); 2304 else 2305 (*info->fprintf_func) (info->stream, "%s", second); 2306 needcomma = 1; 2307 } 2308 if (*third) 2309 { 2310 if (needcomma) 2311 (*info->fprintf_func) (info->stream, ","); 2312 if (op_index[2] != -1 && !op_riprel[2]) 2313 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); 2314 else 2315 (*info->fprintf_func) (info->stream, "%s", third); 2316 } 2317 for (i = 0; i < 3; i++) 2318 if (op_index[i] != -1 && op_riprel[i]) 2319 { 2320 (*info->fprintf_func) (info->stream, " # "); 2321 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep 2322 + op_address[op_index[i]]), info); 2323 } 2324 return codep - priv.the_buffer; 2325} 2326 2327static const char *float_mem[] = { 2328 /* d8 */ 2329 "fadd{s||s|}", 2330 "fmul{s||s|}", 2331 "fcom{s||s|}", 2332 "fcomp{s||s|}", 2333 "fsub{s||s|}", 2334 "fsubr{s||s|}", 2335 "fdiv{s||s|}", 2336 "fdivr{s||s|}", 2337 /* d9 */ 2338 "fld{s||s|}", 2339 "(bad)", 2340 "fst{s||s|}", 2341 "fstp{s||s|}", 2342 "fldenv", 2343 "fldcw", 2344 "fNstenv", 2345 "fNstcw", 2346 /* da */ 2347 "fiadd{l||l|}", 2348 "fimul{l||l|}", 2349 "ficom{l||l|}", 2350 "ficomp{l||l|}", 2351 "fisub{l||l|}", 2352 "fisubr{l||l|}", 2353 "fidiv{l||l|}", 2354 "fidivr{l||l|}", 2355 /* db */ 2356 "fild{l||l|}", 2357 "fisttp{l||l|}", 2358 "fist{l||l|}", 2359 "fistp{l||l|}", 2360 "(bad)", 2361 "fld{t||t|}", 2362 "(bad)", 2363 "fstp{t||t|}", 2364 /* dc */ 2365 "fadd{l||l|}", 2366 "fmul{l||l|}", 2367 "fcom{l||l|}", 2368 "fcomp{l||l|}", 2369 "fsub{l||l|}", 2370 "fsubr{l||l|}", 2371 "fdiv{l||l|}", 2372 "fdivr{l||l|}", 2373 /* dd */ 2374 "fld{l||l|}", 2375 "fisttp{ll||ll|}", 2376 "fst{l||l|}", 2377 "fstp{l||l|}", 2378 "frstor", 2379 "(bad)", 2380 "fNsave", 2381 "fNstsw", 2382 /* de */ 2383 "fiadd", 2384 "fimul", 2385 "ficom", 2386 "ficomp", 2387 "fisub", 2388 "fisubr", 2389 "fidiv", 2390 "fidivr", 2391 /* df */ 2392 "fild", 2393 "fisttp", 2394 "fist", 2395 "fistp", 2396 "fbld", 2397 "fild{ll||ll|}", 2398 "fbstp", 2399 "fistp{ll||ll|}", 2400}; 2401 2402static const unsigned char float_mem_mode[] = { 2403 /* d8 */ 2404 d_mode, 2405 d_mode, 2406 d_mode, 2407 d_mode, 2408 d_mode, 2409 d_mode, 2410 d_mode, 2411 d_mode, 2412 /* d9 */ 2413 d_mode, 2414 0, 2415 d_mode, 2416 d_mode, 2417 0, 2418 w_mode, 2419 0, 2420 w_mode, 2421 /* da */ 2422 d_mode, 2423 d_mode, 2424 d_mode, 2425 d_mode, 2426 d_mode, 2427 d_mode, 2428 d_mode, 2429 d_mode, 2430 /* db */ 2431 d_mode, 2432 d_mode, 2433 d_mode, 2434 d_mode, 2435 0, 2436 x_mode, 2437 0, 2438 x_mode, 2439 /* dc */ 2440 q_mode, 2441 q_mode, 2442 q_mode, 2443 q_mode, 2444 q_mode, 2445 q_mode, 2446 q_mode, 2447 q_mode, 2448 /* dd */ 2449 q_mode, 2450 q_mode, 2451 q_mode, 2452 q_mode, 2453 0, 2454 0, 2455 0, 2456 w_mode, 2457 /* de */ 2458 w_mode, 2459 w_mode, 2460 w_mode, 2461 w_mode, 2462 w_mode, 2463 w_mode, 2464 w_mode, 2465 w_mode, 2466 /* df */ 2467 w_mode, 2468 w_mode, 2469 w_mode, 2470 w_mode, 2471 x_mode, 2472 q_mode, 2473 x_mode, 2474 q_mode 2475}; 2476 2477#define ST OP_ST, 0 2478#define STi OP_STi, 0 2479 2480#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0 2481#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0 2482#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0 2483#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0 2484#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0 2485#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0 2486#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0 2487#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0 2488#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0 2489 2490static const struct dis386 float_reg[][8] = { 2491 /* d8 */ 2492 { 2493 { "fadd", ST, STi, XX }, 2494 { "fmul", ST, STi, XX }, 2495 { "fcom", STi, XX, XX }, 2496 { "fcomp", STi, XX, XX }, 2497 { "fsub", ST, STi, XX }, 2498 { "fsubr", ST, STi, XX }, 2499 { "fdiv", ST, STi, XX }, 2500 { "fdivr", ST, STi, XX }, 2501 }, 2502 /* d9 */ 2503 { 2504 { "fld", STi, XX, XX }, 2505 { "fxch", STi, XX, XX }, 2506 { FGRPd9_2 }, 2507 { "(bad)", XX, XX, XX }, 2508 { FGRPd9_4 }, 2509 { FGRPd9_5 }, 2510 { FGRPd9_6 }, 2511 { FGRPd9_7 }, 2512 }, 2513 /* da */ 2514 { 2515 { "fcmovb", ST, STi, XX }, 2516 { "fcmove", ST, STi, XX }, 2517 { "fcmovbe",ST, STi, XX }, 2518 { "fcmovu", ST, STi, XX }, 2519 { "(bad)", XX, XX, XX }, 2520 { FGRPda_5 }, 2521 { "(bad)", XX, XX, XX }, 2522 { "(bad)", XX, XX, XX }, 2523 }, 2524 /* db */ 2525 { 2526 { "fcmovnb",ST, STi, XX }, 2527 { "fcmovne",ST, STi, XX }, 2528 { "fcmovnbe",ST, STi, XX }, 2529 { "fcmovnu",ST, STi, XX }, 2530 { FGRPdb_4 }, 2531 { "fucomi", ST, STi, XX }, 2532 { "fcomi", ST, STi, XX }, 2533 { "(bad)", XX, XX, XX }, 2534 }, 2535 /* dc */ 2536 { 2537 { "fadd", STi, ST, XX }, 2538 { "fmul", STi, ST, XX }, 2539 { "(bad)", XX, XX, XX }, 2540 { "(bad)", XX, XX, XX }, 2541#if UNIXWARE_COMPAT 2542 { "fsub", STi, ST, XX }, 2543 { "fsubr", STi, ST, XX }, 2544 { "fdiv", STi, ST, XX }, 2545 { "fdivr", STi, ST, XX }, 2546#else 2547 { "fsubr", STi, ST, XX }, 2548 { "fsub", STi, ST, XX }, 2549 { "fdivr", STi, ST, XX }, 2550 { "fdiv", STi, ST, XX }, 2551#endif 2552 }, 2553 /* dd */ 2554 { 2555 { "ffree", STi, XX, XX }, 2556 { "(bad)", XX, XX, XX }, 2557 { "fst", STi, XX, XX }, 2558 { "fstp", STi, XX, XX }, 2559 { "fucom", STi, XX, XX }, 2560 { "fucomp", STi, XX, XX }, 2561 { "(bad)", XX, XX, XX }, 2562 { "(bad)", XX, XX, XX }, 2563 }, 2564 /* de */ 2565 { 2566 { "faddp", STi, ST, XX }, 2567 { "fmulp", STi, ST, XX }, 2568 { "(bad)", XX, XX, XX }, 2569 { FGRPde_3 }, 2570#if UNIXWARE_COMPAT 2571 { "fsubp", STi, ST, XX }, 2572 { "fsubrp", STi, ST, XX }, 2573 { "fdivp", STi, ST, XX }, 2574 { "fdivrp", STi, ST, XX }, 2575#else 2576 { "fsubrp", STi, ST, XX }, 2577 { "fsubp", STi, ST, XX }, 2578 { "fdivrp", STi, ST, XX }, 2579 { "fdivp", STi, ST, XX }, 2580#endif 2581 }, 2582 /* df */ 2583 { 2584 { "ffreep", STi, XX, XX }, 2585 { "(bad)", XX, XX, XX }, 2586 { "(bad)", XX, XX, XX }, 2587 { "(bad)", XX, XX, XX }, 2588 { FGRPdf_4 }, 2589 { "fucomip",ST, STi, XX }, 2590 { "fcomip", ST, STi, XX }, 2591 { "(bad)", XX, XX, XX }, 2592 }, 2593}; 2594 2595static char *fgrps[][8] = { 2596 /* d9_2 0 */ 2597 { 2598 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 2599 }, 2600 2601 /* d9_4 1 */ 2602 { 2603 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", 2604 }, 2605 2606 /* d9_5 2 */ 2607 { 2608 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", 2609 }, 2610 2611 /* d9_6 3 */ 2612 { 2613 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", 2614 }, 2615 2616 /* d9_7 4 */ 2617 { 2618 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", 2619 }, 2620 2621 /* da_5 5 */ 2622 { 2623 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 2624 }, 2625 2626 /* db_4 6 */ 2627 { 2628 "feni(287 only)","fdisi(287 only)","fNclex","fNinit", 2629 "fNsetpm(287 only)","(bad)","(bad)","(bad)", 2630 }, 2631 2632 /* de_3 7 */ 2633 { 2634 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 2635 }, 2636 2637 /* df_4 8 */ 2638 { 2639 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", 2640 }, 2641}; 2642 2643static void 2644dofloat (int sizeflag) 2645{ 2646 const struct dis386 *dp; 2647 unsigned char floatop; 2648 2649 floatop = codep[-1]; 2650 2651 if (mod != 3) 2652 { 2653 int fp_indx = (floatop - 0xd8) * 8 + reg; 2654 2655 putop (float_mem[fp_indx], sizeflag); 2656 obufp = op1out; 2657 OP_E (float_mem_mode[fp_indx], sizeflag); 2658 return; 2659 } 2660 /* Skip mod/rm byte. */ 2661 MODRM_CHECK; 2662 codep++; 2663 2664 dp = &float_reg[floatop - 0xd8][reg]; 2665 if (dp->name == NULL) 2666 { 2667 putop (fgrps[dp->bytemode1][rm], sizeflag); 2668 2669 /* Instruction fnstsw is only one with strange arg. */ 2670 if (floatop == 0xdf && codep[-1] == 0xe0) 2671 strcpy (op1out, names16[0]); 2672 } 2673 else 2674 { 2675 putop (dp->name, sizeflag); 2676 2677 obufp = op1out; 2678 if (dp->op1) 2679 (*dp->op1) (dp->bytemode1, sizeflag); 2680 obufp = op2out; 2681 if (dp->op2) 2682 (*dp->op2) (dp->bytemode2, sizeflag); 2683 } 2684} 2685 2686static void 2687OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 2688{ 2689 oappend ("%st"); 2690} 2691 2692static void 2693OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 2694{ 2695 sprintf (scratchbuf, "%%st(%d)", rm); 2696 oappend (scratchbuf + intel_syntax); 2697} 2698 2699/* Capital letters in template are macros. */ 2700static int 2701putop (const char *template, int sizeflag) 2702{ 2703 const char *p; 2704 int alt; 2705 2706 for (p = template; *p; p++) 2707 { 2708 switch (*p) 2709 { 2710 default: 2711 *obufp++ = *p; 2712 break; 2713 case '{': 2714 alt = 0; 2715 if (intel_syntax) 2716 alt += 1; 2717 if (mode_64bit) 2718 alt += 2; 2719 while (alt != 0) 2720 { 2721 while (*++p != '|') 2722 { 2723 if (*p == '}') 2724 { 2725 /* Alternative not valid. */ 2726 strcpy (obuf, "(bad)"); 2727 obufp = obuf + 5; 2728 return 1; 2729 } 2730 else if (*p == '\0') 2731 abort (); 2732 } 2733 alt--; 2734 } 2735 break; 2736 case '|': 2737 while (*++p != '}') 2738 { 2739 if (*p == '\0') 2740 abort (); 2741 } 2742 break; 2743 case '}': 2744 break; 2745 case 'A': 2746 if (intel_syntax) 2747 break; 2748 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) 2749 *obufp++ = 'b'; 2750 break; 2751 case 'B': 2752 if (intel_syntax) 2753 break; 2754 if (sizeflag & SUFFIX_ALWAYS) 2755 *obufp++ = 'b'; 2756 break; 2757 case 'E': /* For jcxz/jecxz */ 2758 if (mode_64bit) 2759 { 2760 if (sizeflag & AFLAG) 2761 *obufp++ = 'r'; 2762 else 2763 *obufp++ = 'e'; 2764 } 2765 else 2766 if (sizeflag & AFLAG) 2767 *obufp++ = 'e'; 2768 used_prefixes |= (prefixes & PREFIX_ADDR); 2769 break; 2770 case 'F': 2771 if (intel_syntax) 2772 break; 2773 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) 2774 { 2775 if (sizeflag & AFLAG) 2776 *obufp++ = mode_64bit ? 'q' : 'l'; 2777 else 2778 *obufp++ = mode_64bit ? 'l' : 'w'; 2779 used_prefixes |= (prefixes & PREFIX_ADDR); 2780 } 2781 break; 2782 case 'H': 2783 if (intel_syntax) 2784 break; 2785 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS 2786 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS) 2787 { 2788 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS); 2789 *obufp++ = ','; 2790 *obufp++ = 'p'; 2791 if (prefixes & PREFIX_DS) 2792 *obufp++ = 't'; 2793 else 2794 *obufp++ = 'n'; 2795 } 2796 break; 2797 case 'L': 2798 if (intel_syntax) 2799 break; 2800 if (sizeflag & SUFFIX_ALWAYS) 2801 *obufp++ = 'l'; 2802 break; 2803 case 'N': 2804 if ((prefixes & PREFIX_FWAIT) == 0) 2805 *obufp++ = 'n'; 2806 else 2807 used_prefixes |= PREFIX_FWAIT; 2808 break; 2809 case 'O': 2810 USED_REX (REX_MODE64); 2811 if (rex & REX_MODE64) 2812 *obufp++ = 'o'; 2813 else 2814 *obufp++ = 'd'; 2815 break; 2816 case 'T': 2817 if (intel_syntax) 2818 break; 2819 if (mode_64bit) 2820 { 2821 *obufp++ = 'q'; 2822 break; 2823 } 2824 /* Fall through. */ 2825 case 'P': 2826 if (intel_syntax) 2827 break; 2828 if ((prefixes & PREFIX_DATA) 2829 || (rex & REX_MODE64) 2830 || (sizeflag & SUFFIX_ALWAYS)) 2831 { 2832 USED_REX (REX_MODE64); 2833 if (rex & REX_MODE64) 2834 *obufp++ = 'q'; 2835 else 2836 { 2837 if (sizeflag & DFLAG) 2838 *obufp++ = 'l'; 2839 else 2840 *obufp++ = 'w'; 2841 used_prefixes |= (prefixes & PREFIX_DATA); 2842 } 2843 } 2844 break; 2845 case 'U': 2846 if (intel_syntax) 2847 break; 2848 if (mode_64bit) 2849 { 2850 *obufp++ = 'q'; 2851 break; 2852 } 2853 /* Fall through. */ 2854 case 'Q': 2855 if (intel_syntax) 2856 break; 2857 USED_REX (REX_MODE64); 2858 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) 2859 { 2860 if (rex & REX_MODE64) 2861 *obufp++ = 'q'; 2862 else 2863 { 2864 if (sizeflag & DFLAG) 2865 *obufp++ = 'l'; 2866 else 2867 *obufp++ = 'w'; 2868 used_prefixes |= (prefixes & PREFIX_DATA); 2869 } 2870 } 2871 break; 2872 case 'R': 2873 USED_REX (REX_MODE64); 2874 if (intel_syntax) 2875 { 2876 if (rex & REX_MODE64) 2877 { 2878 *obufp++ = 'q'; 2879 *obufp++ = 't'; 2880 } 2881 else if (sizeflag & DFLAG) 2882 { 2883 *obufp++ = 'd'; 2884 *obufp++ = 'q'; 2885 } 2886 else 2887 { 2888 *obufp++ = 'w'; 2889 *obufp++ = 'd'; 2890 } 2891 } 2892 else 2893 { 2894 if (rex & REX_MODE64) 2895 *obufp++ = 'q'; 2896 else if (sizeflag & DFLAG) 2897 *obufp++ = 'l'; 2898 else 2899 *obufp++ = 'w'; 2900 } 2901 if (!(rex & REX_MODE64)) 2902 used_prefixes |= (prefixes & PREFIX_DATA); 2903 break; 2904 case 'S': 2905 if (intel_syntax) 2906 break; 2907 if (sizeflag & SUFFIX_ALWAYS) 2908 { 2909 if (rex & REX_MODE64) 2910 *obufp++ = 'q'; 2911 else 2912 { 2913 if (sizeflag & DFLAG) 2914 *obufp++ = 'l'; 2915 else 2916 *obufp++ = 'w'; 2917 used_prefixes |= (prefixes & PREFIX_DATA); 2918 } 2919 } 2920 break; 2921 case 'X': 2922 if (prefixes & PREFIX_DATA) 2923 *obufp++ = 'd'; 2924 else 2925 *obufp++ = 's'; 2926 used_prefixes |= (prefixes & PREFIX_DATA); 2927 break; 2928 case 'Y': 2929 if (intel_syntax) 2930 break; 2931 if (rex & REX_MODE64) 2932 { 2933 USED_REX (REX_MODE64); 2934 *obufp++ = 'q'; 2935 } 2936 break; 2937 /* implicit operand size 'l' for i386 or 'q' for x86-64 */ 2938 case 'W': 2939 /* operand size flag for cwtl, cbtw */ 2940 USED_REX (0); 2941 if (rex) 2942 *obufp++ = 'l'; 2943 else if (sizeflag & DFLAG) 2944 *obufp++ = 'w'; 2945 else 2946 *obufp++ = 'b'; 2947 if (intel_syntax) 2948 { 2949 if (rex) 2950 { 2951 *obufp++ = 'q'; 2952 *obufp++ = 'e'; 2953 } 2954 if (sizeflag & DFLAG) 2955 { 2956 *obufp++ = 'd'; 2957 *obufp++ = 'e'; 2958 } 2959 else 2960 { 2961 *obufp++ = 'w'; 2962 } 2963 } 2964 if (!rex) 2965 used_prefixes |= (prefixes & PREFIX_DATA); 2966 break; 2967 } 2968 } 2969 *obufp = 0; 2970 return 0; 2971} 2972 2973static void 2974oappend (const char *s) 2975{ 2976 strcpy (obufp, s); 2977 obufp += strlen (s); 2978} 2979 2980static void 2981append_seg (void) 2982{ 2983 if (prefixes & PREFIX_CS) 2984 { 2985 used_prefixes |= PREFIX_CS; 2986 oappend ("%cs:" + intel_syntax); 2987 } 2988 if (prefixes & PREFIX_DS) 2989 { 2990 used_prefixes |= PREFIX_DS; 2991 oappend ("%ds:" + intel_syntax); 2992 } 2993 if (prefixes & PREFIX_SS) 2994 { 2995 used_prefixes |= PREFIX_SS; 2996 oappend ("%ss:" + intel_syntax); 2997 } 2998 if (prefixes & PREFIX_ES) 2999 { 3000 used_prefixes |= PREFIX_ES; 3001 oappend ("%es:" + intel_syntax); 3002 } 3003 if (prefixes & PREFIX_FS) 3004 { 3005 used_prefixes |= PREFIX_FS; 3006 oappend ("%fs:" + intel_syntax); 3007 } 3008 if (prefixes & PREFIX_GS) 3009 { 3010 used_prefixes |= PREFIX_GS; 3011 oappend ("%gs:" + intel_syntax); 3012 } 3013} 3014 3015static void 3016OP_indirE (int bytemode, int sizeflag) 3017{ 3018 if (!intel_syntax) 3019 oappend ("*"); 3020 OP_E (bytemode, sizeflag); 3021} 3022 3023static void 3024print_operand_value (char *buf, int hex, bfd_vma disp) 3025{ 3026 if (mode_64bit) 3027 { 3028 if (hex) 3029 { 3030 char tmp[30]; 3031 int i; 3032 buf[0] = '0'; 3033 buf[1] = 'x'; 3034 sprintf_vma (tmp, disp); 3035 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++); 3036 strcpy (buf + 2, tmp + i); 3037 } 3038 else 3039 { 3040 bfd_signed_vma v = disp; 3041 char tmp[30]; 3042 int i; 3043 if (v < 0) 3044 { 3045 *(buf++) = '-'; 3046 v = -disp; 3047 /* Check for possible overflow on 0x8000000000000000. */ 3048 if (v < 0) 3049 { 3050 strcpy (buf, "9223372036854775808"); 3051 return; 3052 } 3053 } 3054 if (!v) 3055 { 3056 strcpy (buf, "0"); 3057 return; 3058 } 3059 3060 i = 0; 3061 tmp[29] = 0; 3062 while (v) 3063 { 3064 tmp[28 - i] = (v % 10) + '0'; 3065 v /= 10; 3066 i++; 3067 } 3068 strcpy (buf, tmp + 29 - i); 3069 } 3070 } 3071 else 3072 { 3073 if (hex) 3074 sprintf (buf, "0x%x", (unsigned int) disp); 3075 else 3076 sprintf (buf, "%d", (int) disp); 3077 } 3078} 3079 3080static void 3081OP_E (int bytemode, int sizeflag) 3082{ 3083 bfd_vma disp; 3084 int add = 0; 3085 int riprel = 0; 3086 USED_REX (REX_EXTZ); 3087 if (rex & REX_EXTZ) 3088 add += 8; 3089 3090 /* Skip mod/rm byte. */ 3091 MODRM_CHECK; 3092 codep++; 3093 3094 if (mod == 3) 3095 { 3096 switch (bytemode) 3097 { 3098 case b_mode: 3099 USED_REX (0); 3100 if (rex) 3101 oappend (names8rex[rm + add]); 3102 else 3103 oappend (names8[rm + add]); 3104 break; 3105 case w_mode: 3106 oappend (names16[rm + add]); 3107 break; 3108 case d_mode: 3109 oappend (names32[rm + add]); 3110 break; 3111 case q_mode: 3112 oappend (names64[rm + add]); 3113 break; 3114 case m_mode: 3115 if (mode_64bit) 3116 oappend (names64[rm + add]); 3117 else 3118 oappend (names32[rm + add]); 3119 break; 3120 case v_mode: 3121 case dq_mode: 3122 USED_REX (REX_MODE64); 3123 if (rex & REX_MODE64) 3124 oappend (names64[rm + add]); 3125 else if ((sizeflag & DFLAG) || bytemode == dq_mode) 3126 oappend (names32[rm + add]); 3127 else 3128 oappend (names16[rm + add]); 3129 used_prefixes |= (prefixes & PREFIX_DATA); 3130 break; 3131 case 0: 3132 break; 3133 default: 3134 oappend (INTERNAL_DISASSEMBLER_ERROR); 3135 break; 3136 } 3137 return; 3138 } 3139 3140 disp = 0; 3141 append_seg (); 3142 3143 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */ 3144 { 3145 int havesib; 3146 int havebase; 3147 int base; 3148 int index = 0; 3149 int scale = 0; 3150 3151 havesib = 0; 3152 havebase = 1; 3153 base = rm; 3154 3155 if (base == 4) 3156 { 3157 havesib = 1; 3158 FETCH_DATA (the_info, codep + 1); 3159 scale = (*codep >> 6) & 3; 3160 index = (*codep >> 3) & 7; 3161 base = *codep & 7; 3162 USED_REX (REX_EXTY); 3163 USED_REX (REX_EXTZ); 3164 if (rex & REX_EXTY) 3165 index += 8; 3166 if (rex & REX_EXTZ) 3167 base += 8; 3168 codep++; 3169 } 3170 3171 switch (mod) 3172 { 3173 case 0: 3174 if ((base & 7) == 5) 3175 { 3176 havebase = 0; 3177 if (mode_64bit && !havesib) 3178 riprel = 1; 3179 disp = get32s (); 3180 } 3181 break; 3182 case 1: 3183 FETCH_DATA (the_info, codep + 1); 3184 disp = *codep++; 3185 if ((disp & 0x80) != 0) 3186 disp -= 0x100; 3187 break; 3188 case 2: 3189 disp = get32s (); 3190 break; 3191 } 3192 3193 if (!intel_syntax) 3194 if (mod != 0 || (base & 7) == 5) 3195 { 3196 print_operand_value (scratchbuf, !riprel, disp); 3197 oappend (scratchbuf); 3198 if (riprel) 3199 { 3200 set_op (disp, 1); 3201 oappend ("(%rip)"); 3202 } 3203 } 3204 3205 if (havebase || (havesib && (index != 4 || scale != 0))) 3206 { 3207 if (intel_syntax) 3208 { 3209 switch (bytemode) 3210 { 3211 case b_mode: 3212 oappend ("BYTE PTR "); 3213 break; 3214 case w_mode: 3215 oappend ("WORD PTR "); 3216 break; 3217 case v_mode: 3218 if (sizeflag & DFLAG) 3219 oappend ("DWORD PTR "); 3220 else 3221 oappend ("WORD PTR "); 3222 break; 3223 case d_mode: 3224 oappend ("DWORD PTR "); 3225 break; 3226 case q_mode: 3227 oappend ("QWORD PTR "); 3228 break; 3229 case m_mode: 3230 if (mode_64bit) 3231 oappend ("DWORD PTR "); 3232 else 3233 oappend ("QWORD PTR "); 3234 break; 3235 case x_mode: 3236 oappend ("XWORD PTR "); 3237 break; 3238 default: 3239 break; 3240 } 3241 } 3242 *obufp++ = open_char; 3243 if (intel_syntax && riprel) 3244 oappend ("rip + "); 3245 *obufp = '\0'; 3246 USED_REX (REX_EXTZ); 3247 if (!havesib && (rex & REX_EXTZ)) 3248 base += 8; 3249 if (havebase) 3250 oappend (mode_64bit && (sizeflag & AFLAG) 3251 ? names64[base] : names32[base]); 3252 if (havesib) 3253 { 3254 if (index != 4) 3255 { 3256 if (intel_syntax) 3257 { 3258 if (havebase) 3259 { 3260 *obufp++ = separator_char; 3261 *obufp = '\0'; 3262 } 3263 sprintf (scratchbuf, "%s", 3264 mode_64bit && (sizeflag & AFLAG) 3265 ? names64[index] : names32[index]); 3266 } 3267 else 3268 sprintf (scratchbuf, ",%s", 3269 mode_64bit && (sizeflag & AFLAG) 3270 ? names64[index] : names32[index]); 3271 oappend (scratchbuf); 3272 } 3273 if (scale != 0 || (!intel_syntax && index != 4)) 3274 { 3275 *obufp++ = scale_char; 3276 *obufp = '\0'; 3277 sprintf (scratchbuf, "%d", 1 << scale); 3278 oappend (scratchbuf); 3279 } 3280 } 3281 if (intel_syntax) 3282 if (mod != 0 || (base & 7) == 5) 3283 { 3284 /* Don't print zero displacements. */ 3285 if (disp != 0) 3286 { 3287 if ((bfd_signed_vma) disp > 0) 3288 { 3289 *obufp++ = '+'; 3290 *obufp = '\0'; 3291 } 3292 3293 print_operand_value (scratchbuf, 0, disp); 3294 oappend (scratchbuf); 3295 } 3296 } 3297 3298 *obufp++ = close_char; 3299 *obufp = '\0'; 3300 } 3301 else if (intel_syntax) 3302 { 3303 if (mod != 0 || (base & 7) == 5) 3304 { 3305 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 3306 | PREFIX_ES | PREFIX_FS | PREFIX_GS)) 3307 ; 3308 else 3309 { 3310 oappend (names_seg[ds_reg - es_reg]); 3311 oappend (":"); 3312 } 3313 print_operand_value (scratchbuf, 1, disp); 3314 oappend (scratchbuf); 3315 } 3316 } 3317 } 3318 else 3319 { /* 16 bit address mode */ 3320 switch (mod) 3321 { 3322 case 0: 3323 if ((rm & 7) == 6) 3324 { 3325 disp = get16 (); 3326 if ((disp & 0x8000) != 0) 3327 disp -= 0x10000; 3328 } 3329 break; 3330 case 1: 3331 FETCH_DATA (the_info, codep + 1); 3332 disp = *codep++; 3333 if ((disp & 0x80) != 0) 3334 disp -= 0x100; 3335 break; 3336 case 2: 3337 disp = get16 (); 3338 if ((disp & 0x8000) != 0) 3339 disp -= 0x10000; 3340 break; 3341 } 3342 3343 if (!intel_syntax) 3344 if (mod != 0 || (rm & 7) == 6) 3345 { 3346 print_operand_value (scratchbuf, 0, disp); 3347 oappend (scratchbuf); 3348 } 3349 3350 if (mod != 0 || (rm & 7) != 6) 3351 { 3352 *obufp++ = open_char; 3353 *obufp = '\0'; 3354 oappend (index16[rm + add]); 3355 *obufp++ = close_char; 3356 *obufp = '\0'; 3357 } 3358 } 3359} 3360 3361static void 3362OP_G (int bytemode, int sizeflag) 3363{ 3364 int add = 0; 3365 USED_REX (REX_EXTX); 3366 if (rex & REX_EXTX) 3367 add += 8; 3368 switch (bytemode) 3369 { 3370 case b_mode: 3371 USED_REX (0); 3372 if (rex) 3373 oappend (names8rex[reg + add]); 3374 else 3375 oappend (names8[reg + add]); 3376 break; 3377 case w_mode: 3378 oappend (names16[reg + add]); 3379 break; 3380 case d_mode: 3381 oappend (names32[reg + add]); 3382 break; 3383 case q_mode: 3384 oappend (names64[reg + add]); 3385 break; 3386 case v_mode: 3387 USED_REX (REX_MODE64); 3388 if (rex & REX_MODE64) 3389 oappend (names64[reg + add]); 3390 else if (sizeflag & DFLAG) 3391 oappend (names32[reg + add]); 3392 else 3393 oappend (names16[reg + add]); 3394 used_prefixes |= (prefixes & PREFIX_DATA); 3395 break; 3396 default: 3397 oappend (INTERNAL_DISASSEMBLER_ERROR); 3398 break; 3399 } 3400} 3401 3402static bfd_vma 3403get64 (void) 3404{ 3405 bfd_vma x; 3406#ifdef BFD64 3407 unsigned int a; 3408 unsigned int b; 3409 3410 FETCH_DATA (the_info, codep + 8); 3411 a = *codep++ & 0xff; 3412 a |= (*codep++ & 0xff) << 8; 3413 a |= (*codep++ & 0xff) << 16; 3414 a |= (*codep++ & 0xff) << 24; 3415 b = *codep++ & 0xff; 3416 b |= (*codep++ & 0xff) << 8; 3417 b |= (*codep++ & 0xff) << 16; 3418 b |= (*codep++ & 0xff) << 24; 3419 x = a + ((bfd_vma) b << 32); 3420#else 3421 abort (); 3422 x = 0; 3423#endif 3424 return x; 3425} 3426 3427static bfd_signed_vma 3428get32 (void) 3429{ 3430 bfd_signed_vma x = 0; 3431 3432 FETCH_DATA (the_info, codep + 4); 3433 x = *codep++ & (bfd_signed_vma) 0xff; 3434 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; 3435 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; 3436 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; 3437 return x; 3438} 3439 3440static bfd_signed_vma 3441get32s (void) 3442{ 3443 bfd_signed_vma x = 0; 3444 3445 FETCH_DATA (the_info, codep + 4); 3446 x = *codep++ & (bfd_signed_vma) 0xff; 3447 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; 3448 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; 3449 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; 3450 3451 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31); 3452 3453 return x; 3454} 3455 3456static int 3457get16 (void) 3458{ 3459 int x = 0; 3460 3461 FETCH_DATA (the_info, codep + 2); 3462 x = *codep++ & 0xff; 3463 x |= (*codep++ & 0xff) << 8; 3464 return x; 3465} 3466 3467static void 3468set_op (bfd_vma op, int riprel) 3469{ 3470 op_index[op_ad] = op_ad; 3471 if (mode_64bit) 3472 { 3473 op_address[op_ad] = op; 3474 op_riprel[op_ad] = riprel; 3475 } 3476 else 3477 { 3478 /* Mask to get a 32-bit address. */ 3479 op_address[op_ad] = op & 0xffffffff; 3480 op_riprel[op_ad] = riprel & 0xffffffff; 3481 } 3482} 3483 3484static void 3485OP_REG (int code, int sizeflag) 3486{ 3487 const char *s; 3488 int add = 0; 3489 USED_REX (REX_EXTZ); 3490 if (rex & REX_EXTZ) 3491 add = 8; 3492 3493 switch (code) 3494 { 3495 case indir_dx_reg: 3496 if (intel_syntax) 3497 s = "[dx]"; 3498 else 3499 s = "(%dx)"; 3500 break; 3501 case ax_reg: case cx_reg: case dx_reg: case bx_reg: 3502 case sp_reg: case bp_reg: case si_reg: case di_reg: 3503 s = names16[code - ax_reg + add]; 3504 break; 3505 case es_reg: case ss_reg: case cs_reg: 3506 case ds_reg: case fs_reg: case gs_reg: 3507 s = names_seg[code - es_reg + add]; 3508 break; 3509 case al_reg: case ah_reg: case cl_reg: case ch_reg: 3510 case dl_reg: case dh_reg: case bl_reg: case bh_reg: 3511 USED_REX (0); 3512 if (rex) 3513 s = names8rex[code - al_reg + add]; 3514 else 3515 s = names8[code - al_reg]; 3516 break; 3517 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: 3518 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: 3519 if (mode_64bit) 3520 { 3521 s = names64[code - rAX_reg + add]; 3522 break; 3523 } 3524 code += eAX_reg - rAX_reg; 3525 /* Fall through. */ 3526 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: 3527 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: 3528 USED_REX (REX_MODE64); 3529 if (rex & REX_MODE64) 3530 s = names64[code - eAX_reg + add]; 3531 else if (sizeflag & DFLAG) 3532 s = names32[code - eAX_reg + add]; 3533 else 3534 s = names16[code - eAX_reg + add]; 3535 used_prefixes |= (prefixes & PREFIX_DATA); 3536 break; 3537 default: 3538 s = INTERNAL_DISASSEMBLER_ERROR; 3539 break; 3540 } 3541 oappend (s); 3542} 3543 3544static void 3545OP_IMREG (int code, int sizeflag) 3546{ 3547 const char *s; 3548 3549 switch (code) 3550 { 3551 case indir_dx_reg: 3552 if (intel_syntax) 3553 s = "[dx]"; 3554 else 3555 s = "(%dx)"; 3556 break; 3557 case ax_reg: case cx_reg: case dx_reg: case bx_reg: 3558 case sp_reg: case bp_reg: case si_reg: case di_reg: 3559 s = names16[code - ax_reg]; 3560 break; 3561 case es_reg: case ss_reg: case cs_reg: 3562 case ds_reg: case fs_reg: case gs_reg: 3563 s = names_seg[code - es_reg]; 3564 break; 3565 case al_reg: case ah_reg: case cl_reg: case ch_reg: 3566 case dl_reg: case dh_reg: case bl_reg: case bh_reg: 3567 USED_REX (0); 3568 if (rex) 3569 s = names8rex[code - al_reg]; 3570 else 3571 s = names8[code - al_reg]; 3572 break; 3573 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: 3574 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: 3575 USED_REX (REX_MODE64); 3576 if (rex & REX_MODE64) 3577 s = names64[code - eAX_reg]; 3578 else if (sizeflag & DFLAG) 3579 s = names32[code - eAX_reg]; 3580 else 3581 s = names16[code - eAX_reg]; 3582 used_prefixes |= (prefixes & PREFIX_DATA); 3583 break; 3584 default: 3585 s = INTERNAL_DISASSEMBLER_ERROR; 3586 break; 3587 } 3588 oappend (s); 3589} 3590 3591static void 3592OP_I (int bytemode, int sizeflag) 3593{ 3594 bfd_signed_vma op; 3595 bfd_signed_vma mask = -1; 3596 3597 switch (bytemode) 3598 { 3599 case b_mode: 3600 FETCH_DATA (the_info, codep + 1); 3601 op = *codep++; 3602 mask = 0xff; 3603 break; 3604 case q_mode: 3605 if (mode_64bit) 3606 { 3607 op = get32s (); 3608 break; 3609 } 3610 /* Fall through. */ 3611 case v_mode: 3612 USED_REX (REX_MODE64); 3613 if (rex & REX_MODE64) 3614 op = get32s (); 3615 else if (sizeflag & DFLAG) 3616 { 3617 op = get32 (); 3618 mask = 0xffffffff; 3619 } 3620 else 3621 { 3622 op = get16 (); 3623 mask = 0xfffff; 3624 } 3625 used_prefixes |= (prefixes & PREFIX_DATA); 3626 break; 3627 case w_mode: 3628 mask = 0xfffff; 3629 op = get16 (); 3630 break; 3631 default: 3632 oappend (INTERNAL_DISASSEMBLER_ERROR); 3633 return; 3634 } 3635 3636 op &= mask; 3637 scratchbuf[0] = '$'; 3638 print_operand_value (scratchbuf + 1, 1, op); 3639 oappend (scratchbuf + intel_syntax); 3640 scratchbuf[0] = '\0'; 3641} 3642 3643static void 3644OP_I64 (int bytemode, int sizeflag) 3645{ 3646 bfd_signed_vma op; 3647 bfd_signed_vma mask = -1; 3648 3649 if (!mode_64bit) 3650 { 3651 OP_I (bytemode, sizeflag); 3652 return; 3653 } 3654 3655 switch (bytemode) 3656 { 3657 case b_mode: 3658 FETCH_DATA (the_info, codep + 1); 3659 op = *codep++; 3660 mask = 0xff; 3661 break; 3662 case v_mode: 3663 USED_REX (REX_MODE64); 3664 if (rex & REX_MODE64) 3665 op = get64 (); 3666 else if (sizeflag & DFLAG) 3667 { 3668 op = get32 (); 3669 mask = 0xffffffff; 3670 } 3671 else 3672 { 3673 op = get16 (); 3674 mask = 0xfffff; 3675 } 3676 used_prefixes |= (prefixes & PREFIX_DATA); 3677 break; 3678 case w_mode: 3679 mask = 0xfffff; 3680 op = get16 (); 3681 break; 3682 default: 3683 oappend (INTERNAL_DISASSEMBLER_ERROR); 3684 return; 3685 } 3686 3687 op &= mask; 3688 scratchbuf[0] = '$'; 3689 print_operand_value (scratchbuf + 1, 1, op); 3690 oappend (scratchbuf + intel_syntax); 3691 scratchbuf[0] = '\0'; 3692} 3693 3694static void 3695OP_sI (int bytemode, int sizeflag) 3696{ 3697 bfd_signed_vma op; 3698 bfd_signed_vma mask = -1; 3699 3700 switch (bytemode) 3701 { 3702 case b_mode: 3703 FETCH_DATA (the_info, codep + 1); 3704 op = *codep++; 3705 if ((op & 0x80) != 0) 3706 op -= 0x100; 3707 mask = 0xffffffff; 3708 break; 3709 case v_mode: 3710 USED_REX (REX_MODE64); 3711 if (rex & REX_MODE64) 3712 op = get32s (); 3713 else if (sizeflag & DFLAG) 3714 { 3715 op = get32s (); 3716 mask = 0xffffffff; 3717 } 3718 else 3719 { 3720 mask = 0xffffffff; 3721 op = get16 (); 3722 if ((op & 0x8000) != 0) 3723 op -= 0x10000; 3724 } 3725 used_prefixes |= (prefixes & PREFIX_DATA); 3726 break; 3727 case w_mode: 3728 op = get16 (); 3729 mask = 0xffffffff; 3730 if ((op & 0x8000) != 0) 3731 op -= 0x10000; 3732 break; 3733 default: 3734 oappend (INTERNAL_DISASSEMBLER_ERROR); 3735 return; 3736 } 3737 3738 scratchbuf[0] = '$'; 3739 print_operand_value (scratchbuf + 1, 1, op); 3740 oappend (scratchbuf + intel_syntax); 3741} 3742 3743static void 3744OP_J (int bytemode, int sizeflag) 3745{ 3746 bfd_vma disp; 3747 bfd_vma mask = -1; 3748 3749 switch (bytemode) 3750 { 3751 case b_mode: 3752 FETCH_DATA (the_info, codep + 1); 3753 disp = *codep++; 3754 if ((disp & 0x80) != 0) 3755 disp -= 0x100; 3756 break; 3757 case v_mode: 3758 if (sizeflag & DFLAG) 3759 disp = get32s (); 3760 else 3761 { 3762 disp = get16 (); 3763 /* For some reason, a data16 prefix on a jump instruction 3764 means that the pc is masked to 16 bits after the 3765 displacement is added! */ 3766 mask = 0xffff; 3767 } 3768 break; 3769 default: 3770 oappend (INTERNAL_DISASSEMBLER_ERROR); 3771 return; 3772 } 3773 disp = (start_pc + codep - start_codep + disp) & mask; 3774 set_op (disp, 0); 3775 print_operand_value (scratchbuf, 1, disp); 3776 oappend (scratchbuf); 3777} 3778 3779static void 3780OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3781{ 3782 oappend (names_seg[reg]); 3783} 3784 3785static void 3786OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag) 3787{ 3788 int seg, offset; 3789 3790 if (sizeflag & DFLAG) 3791 { 3792 offset = get32 (); 3793 seg = get16 (); 3794 } 3795 else 3796 { 3797 offset = get16 (); 3798 seg = get16 (); 3799 } 3800 used_prefixes |= (prefixes & PREFIX_DATA); 3801 if (intel_syntax) 3802 sprintf (scratchbuf, "0x%x,0x%x", seg, offset); 3803 else 3804 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); 3805 oappend (scratchbuf); 3806} 3807 3808static void 3809OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag) 3810{ 3811 bfd_vma off; 3812 3813 append_seg (); 3814 3815 if ((sizeflag & AFLAG) || mode_64bit) 3816 off = get32 (); 3817 else 3818 off = get16 (); 3819 3820 if (intel_syntax) 3821 { 3822 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 3823 | PREFIX_ES | PREFIX_FS | PREFIX_GS))) 3824 { 3825 oappend (names_seg[ds_reg - es_reg]); 3826 oappend (":"); 3827 } 3828 } 3829 print_operand_value (scratchbuf, 1, off); 3830 oappend (scratchbuf); 3831} 3832 3833static void 3834OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3835{ 3836 bfd_vma off; 3837 3838 if (!mode_64bit) 3839 { 3840 OP_OFF (bytemode, sizeflag); 3841 return; 3842 } 3843 3844 append_seg (); 3845 3846 off = get64 (); 3847 3848 if (intel_syntax) 3849 { 3850 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS 3851 | PREFIX_ES | PREFIX_FS | PREFIX_GS))) 3852 { 3853 oappend (names_seg[ds_reg - es_reg]); 3854 oappend (":"); 3855 } 3856 } 3857 print_operand_value (scratchbuf, 1, off); 3858 oappend (scratchbuf); 3859} 3860 3861static void 3862ptr_reg (int code, int sizeflag) 3863{ 3864 const char *s; 3865 3866 *obufp++ = open_char; 3867 used_prefixes |= (prefixes & PREFIX_ADDR); 3868 if (mode_64bit) 3869 { 3870 if (!(sizeflag & AFLAG)) 3871 s = names32[code - eAX_reg]; 3872 else 3873 s = names64[code - eAX_reg]; 3874 } 3875 else if (sizeflag & AFLAG) 3876 s = names32[code - eAX_reg]; 3877 else 3878 s = names16[code - eAX_reg]; 3879 oappend (s); 3880 *obufp++ = close_char; 3881 *obufp = 0; 3882} 3883 3884static void 3885OP_ESreg (int code, int sizeflag) 3886{ 3887 oappend ("%es:" + intel_syntax); 3888 ptr_reg (code, sizeflag); 3889} 3890 3891static void 3892OP_DSreg (int code, int sizeflag) 3893{ 3894 if ((prefixes 3895 & (PREFIX_CS 3896 | PREFIX_DS 3897 | PREFIX_SS 3898 | PREFIX_ES 3899 | PREFIX_FS 3900 | PREFIX_GS)) == 0) 3901 prefixes |= PREFIX_DS; 3902 append_seg (); 3903 ptr_reg (code, sizeflag); 3904} 3905 3906static void 3907OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3908{ 3909 int add = 0; 3910 USED_REX (REX_EXTX); 3911 if (rex & REX_EXTX) 3912 add = 8; 3913 sprintf (scratchbuf, "%%cr%d", reg + add); 3914 oappend (scratchbuf + intel_syntax); 3915} 3916 3917static void 3918OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3919{ 3920 int add = 0; 3921 USED_REX (REX_EXTX); 3922 if (rex & REX_EXTX) 3923 add = 8; 3924 if (intel_syntax) 3925 sprintf (scratchbuf, "db%d", reg + add); 3926 else 3927 sprintf (scratchbuf, "%%db%d", reg + add); 3928 oappend (scratchbuf); 3929} 3930 3931static void 3932OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3933{ 3934 sprintf (scratchbuf, "%%tr%d", reg); 3935 oappend (scratchbuf + intel_syntax); 3936} 3937 3938static void 3939OP_Rd (int bytemode, int sizeflag) 3940{ 3941 if (mod == 3) 3942 OP_E (bytemode, sizeflag); 3943 else 3944 BadOp (); 3945} 3946 3947static void 3948OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3949{ 3950 used_prefixes |= (prefixes & PREFIX_DATA); 3951 if (prefixes & PREFIX_DATA) 3952 { 3953 int add = 0; 3954 USED_REX (REX_EXTX); 3955 if (rex & REX_EXTX) 3956 add = 8; 3957 sprintf (scratchbuf, "%%xmm%d", reg + add); 3958 } 3959 else 3960 sprintf (scratchbuf, "%%mm%d", reg); 3961 oappend (scratchbuf + intel_syntax); 3962} 3963 3964static void 3965OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 3966{ 3967 int add = 0; 3968 USED_REX (REX_EXTX); 3969 if (rex & REX_EXTX) 3970 add = 8; 3971 sprintf (scratchbuf, "%%xmm%d", reg + add); 3972 oappend (scratchbuf + intel_syntax); 3973} 3974 3975static void 3976OP_EM (int bytemode, int sizeflag) 3977{ 3978 if (mod != 3) 3979 { 3980 OP_E (bytemode, sizeflag); 3981 return; 3982 } 3983 3984 /* Skip mod/rm byte. */ 3985 MODRM_CHECK; 3986 codep++; 3987 used_prefixes |= (prefixes & PREFIX_DATA); 3988 if (prefixes & PREFIX_DATA) 3989 { 3990 int add = 0; 3991 3992 USED_REX (REX_EXTZ); 3993 if (rex & REX_EXTZ) 3994 add = 8; 3995 sprintf (scratchbuf, "%%xmm%d", rm + add); 3996 } 3997 else 3998 sprintf (scratchbuf, "%%mm%d", rm); 3999 oappend (scratchbuf + intel_syntax); 4000} 4001 4002static void 4003OP_EX (int bytemode, int sizeflag) 4004{ 4005 int add = 0; 4006 if (mod != 3) 4007 { 4008 OP_E (bytemode, sizeflag); 4009 return; 4010 } 4011 USED_REX (REX_EXTZ); 4012 if (rex & REX_EXTZ) 4013 add = 8; 4014 4015 /* Skip mod/rm byte. */ 4016 MODRM_CHECK; 4017 codep++; 4018 sprintf (scratchbuf, "%%xmm%d", rm + add); 4019 oappend (scratchbuf + intel_syntax); 4020} 4021 4022static void 4023OP_MS (int bytemode, int sizeflag) 4024{ 4025 if (mod == 3) 4026 OP_EM (bytemode, sizeflag); 4027 else 4028 BadOp (); 4029} 4030 4031static void 4032OP_XS (int bytemode, int sizeflag) 4033{ 4034 if (mod == 3) 4035 OP_EX (bytemode, sizeflag); 4036 else 4037 BadOp (); 4038} 4039 4040static void 4041OP_M (int bytemode, int sizeflag) 4042{ 4043 if (mod == 3) 4044 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */ 4045 else 4046 OP_E (bytemode, sizeflag); 4047} 4048 4049static void 4050OP_0f07 (int bytemode, int sizeflag) 4051{ 4052 if (mod != 3 || rm != 0) 4053 BadOp (); 4054 else 4055 OP_E (bytemode, sizeflag); 4056} 4057 4058static void 4059OP_0fae (int bytemode, int sizeflag) 4060{ 4061 if (mod == 3) 4062 { 4063 if (reg == 7) 4064 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence"); 4065 4066 if (reg < 5 || rm != 0) 4067 { 4068 BadOp (); /* bad sfence, mfence, or lfence */ 4069 return; 4070 } 4071 } 4072 else if (reg != 7) 4073 { 4074 BadOp (); /* bad clflush */ 4075 return; 4076 } 4077 4078 OP_E (bytemode, sizeflag); 4079} 4080 4081static void 4082NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 4083{ 4084 /* NOP with REPZ prefix is called PAUSE. */ 4085 if (prefixes == PREFIX_REPZ) 4086 strcpy (obuf, "pause"); 4087} 4088 4089static const char *const Suffix3DNow[] = { 4090/* 00 */ NULL, NULL, NULL, NULL, 4091/* 04 */ NULL, NULL, NULL, NULL, 4092/* 08 */ NULL, NULL, NULL, NULL, 4093/* 0C */ "pi2fw", "pi2fd", NULL, NULL, 4094/* 10 */ NULL, NULL, NULL, NULL, 4095/* 14 */ NULL, NULL, NULL, NULL, 4096/* 18 */ NULL, NULL, NULL, NULL, 4097/* 1C */ "pf2iw", "pf2id", NULL, NULL, 4098/* 20 */ NULL, NULL, NULL, NULL, 4099/* 24 */ NULL, NULL, NULL, NULL, 4100/* 28 */ NULL, NULL, NULL, NULL, 4101/* 2C */ NULL, NULL, NULL, NULL, 4102/* 30 */ NULL, NULL, NULL, NULL, 4103/* 34 */ NULL, NULL, NULL, NULL, 4104/* 38 */ NULL, NULL, NULL, NULL, 4105/* 3C */ NULL, NULL, NULL, NULL, 4106/* 40 */ NULL, NULL, NULL, NULL, 4107/* 44 */ NULL, NULL, NULL, NULL, 4108/* 48 */ NULL, NULL, NULL, NULL, 4109/* 4C */ NULL, NULL, NULL, NULL, 4110/* 50 */ NULL, NULL, NULL, NULL, 4111/* 54 */ NULL, NULL, NULL, NULL, 4112/* 58 */ NULL, NULL, NULL, NULL, 4113/* 5C */ NULL, NULL, NULL, NULL, 4114/* 60 */ NULL, NULL, NULL, NULL, 4115/* 64 */ NULL, NULL, NULL, NULL, 4116/* 68 */ NULL, NULL, NULL, NULL, 4117/* 6C */ NULL, NULL, NULL, NULL, 4118/* 70 */ NULL, NULL, NULL, NULL, 4119/* 74 */ NULL, NULL, NULL, NULL, 4120/* 78 */ NULL, NULL, NULL, NULL, 4121/* 7C */ NULL, NULL, NULL, NULL, 4122/* 80 */ NULL, NULL, NULL, NULL, 4123/* 84 */ NULL, NULL, NULL, NULL, 4124/* 88 */ NULL, NULL, "pfnacc", NULL, 4125/* 8C */ NULL, NULL, "pfpnacc", NULL, 4126/* 90 */ "pfcmpge", NULL, NULL, NULL, 4127/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", 4128/* 98 */ NULL, NULL, "pfsub", NULL, 4129/* 9C */ NULL, NULL, "pfadd", NULL, 4130/* A0 */ "pfcmpgt", NULL, NULL, NULL, 4131/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", 4132/* A8 */ NULL, NULL, "pfsubr", NULL, 4133/* AC */ NULL, NULL, "pfacc", NULL, 4134/* B0 */ "pfcmpeq", NULL, NULL, NULL, 4135/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", 4136/* B8 */ NULL, NULL, NULL, "pswapd", 4137/* BC */ NULL, NULL, NULL, "pavgusb", 4138/* C0 */ NULL, NULL, NULL, NULL, 4139/* C4 */ NULL, NULL, NULL, NULL, 4140/* C8 */ NULL, NULL, NULL, NULL, 4141/* CC */ NULL, NULL, NULL, NULL, 4142/* D0 */ NULL, NULL, NULL, NULL, 4143/* D4 */ NULL, NULL, NULL, NULL, 4144/* D8 */ NULL, NULL, NULL, NULL, 4145/* DC */ NULL, NULL, NULL, NULL, 4146/* E0 */ NULL, NULL, NULL, NULL, 4147/* E4 */ NULL, NULL, NULL, NULL, 4148/* E8 */ NULL, NULL, NULL, NULL, 4149/* EC */ NULL, NULL, NULL, NULL, 4150/* F0 */ NULL, NULL, NULL, NULL, 4151/* F4 */ NULL, NULL, NULL, NULL, 4152/* F8 */ NULL, NULL, NULL, NULL, 4153/* FC */ NULL, NULL, NULL, NULL, 4154}; 4155 4156static void 4157OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 4158{ 4159 const char *mnemonic; 4160 4161 FETCH_DATA (the_info, codep + 1); 4162 /* AMD 3DNow! instructions are specified by an opcode suffix in the 4163 place where an 8-bit immediate would normally go. ie. the last 4164 byte of the instruction. */ 4165 obufp = obuf + strlen (obuf); 4166 mnemonic = Suffix3DNow[*codep++ & 0xff]; 4167 if (mnemonic) 4168 oappend (mnemonic); 4169 else 4170 { 4171 /* Since a variable sized modrm/sib chunk is between the start 4172 of the opcode (0x0f0f) and the opcode suffix, we need to do 4173 all the modrm processing first, and don't know until now that 4174 we have a bad opcode. This necessitates some cleaning up. */ 4175 op1out[0] = '\0'; 4176 op2out[0] = '\0'; 4177 BadOp (); 4178 } 4179} 4180 4181static const char *simd_cmp_op[] = { 4182 "eq", 4183 "lt", 4184 "le", 4185 "unord", 4186 "neq", 4187 "nlt", 4188 "nle", 4189 "ord" 4190}; 4191 4192static void 4193OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) 4194{ 4195 unsigned int cmp_type; 4196 4197 FETCH_DATA (the_info, codep + 1); 4198 obufp = obuf + strlen (obuf); 4199 cmp_type = *codep++ & 0xff; 4200 if (cmp_type < 8) 4201 { 4202 char suffix1 = 'p', suffix2 = 's'; 4203 used_prefixes |= (prefixes & PREFIX_REPZ); 4204 if (prefixes & PREFIX_REPZ) 4205 suffix1 = 's'; 4206 else 4207 { 4208 used_prefixes |= (prefixes & PREFIX_DATA); 4209 if (prefixes & PREFIX_DATA) 4210 suffix2 = 'd'; 4211 else 4212 { 4213 used_prefixes |= (prefixes & PREFIX_REPNZ); 4214 if (prefixes & PREFIX_REPNZ) 4215 suffix1 = 's', suffix2 = 'd'; 4216 } 4217 } 4218 sprintf (scratchbuf, "cmp%s%c%c", 4219 simd_cmp_op[cmp_type], suffix1, suffix2); 4220 used_prefixes |= (prefixes & PREFIX_REPZ); 4221 oappend (scratchbuf); 4222 } 4223 else 4224 { 4225 /* We have a bad extension byte. Clean up. */ 4226 op1out[0] = '\0'; 4227 op2out[0] = '\0'; 4228 BadOp (); 4229 } 4230} 4231 4232static void 4233SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED) 4234{ 4235 /* Change movlps/movhps to movhlps/movlhps for 2 register operand 4236 forms of these instructions. */ 4237 if (mod == 3) 4238 { 4239 char *p = obuf + strlen (obuf); 4240 *(p + 1) = '\0'; 4241 *p = *(p - 1); 4242 *(p - 1) = *(p - 2); 4243 *(p - 2) = *(p - 3); 4244 *(p - 3) = extrachar; 4245 } 4246} 4247 4248static void 4249PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) 4250{ 4251 if (mod == 3 && reg == 1 && rm <= 1) 4252 { 4253 /* Override "sidt". */ 4254 char *p = obuf + strlen (obuf) - 4; 4255 4256 /* We might have a suffix. */ 4257 if (*p == 'i') 4258 --p; 4259 4260 if (rm) 4261 { 4262 /* mwait %eax,%ecx */ 4263 strcpy (p, "mwait"); 4264 } 4265 else 4266 { 4267 /* monitor %eax,%ecx,%edx" */ 4268 strcpy (p, "monitor"); 4269 strcpy (op3out, names32[2]); 4270 } 4271 strcpy (op1out, names32[0]); 4272 strcpy (op2out, names32[1]); 4273 two_source_ops = 1; 4274 4275 codep++; 4276 } 4277 else 4278 OP_E (0, sizeflag); 4279} 4280 4281static void 4282INVLPG_Fixup (int bytemode, int sizeflag) 4283{ 4284 if (*codep == 0xf8) 4285 { 4286 char *p = obuf + strlen (obuf); 4287 4288 /* Override "invlpg". */ 4289 strcpy (p - 6, "swapgs"); 4290 codep++; 4291 } 4292 else 4293 OP_E (bytemode, sizeflag); 4294} 4295 4296static void 4297BadOp (void) 4298{ 4299 /* Throw away prefixes and 1st. opcode byte. */ 4300 codep = insn_codep + 1; 4301 oappend ("(bad)"); 4302} 4303