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