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