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