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