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