ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

i386-dis.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS kernel
00004  * FILE:            ntoskrnl/kdbg/i386/i386-dis.c
00005  * PURPOSE:         No purpose listed.
00006  *
00007  * PROGRAMMERS:     No programmer listed.
00008  */
00009 
00010 #include <ntoskrnl.h>
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 /* ReactOS compatibility stuff. */
00015 #define PARAMS(X) X
00016 #define PTR void*
00017 typedef enum bfd_flavour
00018 {
00019   bfd_target_unknown_flavour,
00020 } bfd_flavour;
00021 typedef enum bfd_architecture
00022 {
00023   bfd_arch_i386,
00024 } bfd_arch;
00025 typedef ULONG_PTR bfd_vma;
00026 typedef unsigned char bfd_byte;
00027 enum bfd_endian { BFD_ENDIAN_BIG, BIG_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
00028 typedef void* bfd;
00029 typedef LONG_PTR bfd_signed_vma;
00030 #define bfd_mach_x86_64_intel_syntax 0
00031 #define bfd_mach_x86_64 1
00032 #define bfd_mach_i386_i386_intel_syntax 2
00033 #define bfd_mach_i386_i386 3
00034 #define bfd_mach_i386_i8086 4
00035 #define abort() DbgBreakPoint();
00036 #define _(X) X
00037 #define ATTRIBUTE_UNUSED
00038 extern int sprintf(char *str, const char *format, ...);
00039 #define sprintf_vma(BUF, VMA) sprintf(BUF, "%p", VMA)
00040 #include <setjmp.h>
00041 #define _INC_SETJMPEX
00042 struct disassemble_info;
00043 
00044 int
00045 print_insn_i386 (bfd_vma pc, struct disassemble_info *info);
00046 
00047 int
00048 KdbpPrintDisasm(void* Ignored, const char* fmt, ...)
00049 {
00050   va_list ap;
00051   static char buffer[256];
00052   int ret;
00053 
00054   va_start(ap, fmt);
00055   ret = vsprintf(buffer, fmt, ap);
00056   DbgPrint("%s", buffer);
00057   va_end(ap);
00058   return(ret);
00059 }
00060 
00061 int
00062 KdbpNopPrintDisasm(void* Ignored, const char* fmt, ...)
00063 {
00064   return(0);
00065 }
00066 
00067 static int
00068 KdbpReadMemory(ULONG_PTR Addr, unsigned char* Data, unsigned int Length,
00069            struct disassemble_info * Ignored)
00070 {
00071   return KdbpSafeReadMemory(Data, (void *)Addr, Length); /* 0 means no error */
00072 }
00073 
00074 static void
00075 KdbpMemoryError(int Status, ULONG_PTR Addr,
00076             struct disassemble_info * Ignored)
00077 {
00078 }
00079 
00080 static void
00081 KdbpPrintAddressInCode(ULONG_PTR Addr, struct disassemble_info * Ignored)
00082 {
00083   if (!KdbSymPrintAddress((void*)Addr))
00084     {
00085       DbgPrint("<%p>", Addr);
00086     }
00087 }
00088 
00089 static void
00090 KdbpNopPrintAddress(ULONG_PTR Addr, struct disassemble_info * Ignored)
00091 {
00092 }
00093 
00094 #include "dis-asm.h"
00095 
00096 LONG
00097 KdbpGetInstLength(IN ULONG_PTR Address)
00098 {
00099   disassemble_info info;
00100 
00101   info.fprintf_func = KdbpNopPrintDisasm;
00102   info.stream = NULL;
00103   info.application_data = NULL;
00104   info.flavour = bfd_target_unknown_flavour;
00105   info.arch = bfd_arch_i386;
00106   info.mach = bfd_mach_x86_64;
00107   info.insn_sets = 0;
00108   info.flags = 0;
00109   info.read_memory_func = KdbpReadMemory;
00110   info.memory_error_func = KdbpMemoryError;
00111   info.print_address_func = KdbpNopPrintAddress;
00112   info.symbol_at_address_func = NULL;
00113   info.buffer = NULL;
00114   info.buffer_vma = info.buffer_length = 0;
00115   info.bytes_per_chunk = 0;
00116   info.display_endian = BIG_ENDIAN_LITTLE;
00117   info.disassembler_options = NULL;
00118 
00119   return(print_insn_i386(Address, &info));
00120 }
00121 
00122 LONG
00123 KdbpDisassemble(IN ULONG_PTR Address, IN ULONG IntelSyntax)
00124 {
00125   disassemble_info info;
00126 
00127   info.fprintf_func = KdbpPrintDisasm;
00128   info.stream = NULL;
00129   info.application_data = NULL;
00130   info.flavour = bfd_target_unknown_flavour;
00131   info.arch = bfd_arch_i386;
00132   info.mach = IntelSyntax ? bfd_mach_i386_i386_intel_syntax : bfd_mach_i386_i386;
00133   info.insn_sets = 0;
00134   info.flags = 0;
00135   info.read_memory_func = KdbpReadMemory;
00136   info.memory_error_func = KdbpMemoryError;
00137   info.print_address_func = KdbpPrintAddressInCode;
00138   info.symbol_at_address_func = NULL;
00139   info.buffer = NULL;
00140   info.buffer_vma = info.buffer_length = 0;
00141   info.bytes_per_chunk = 0;
00142   info.display_endian = BIG_ENDIAN_LITTLE;
00143   info.disassembler_options = NULL;
00144 
00145   return(print_insn_i386(Address, &info));
00146 }
00147 
00148 /* Print i386 instructions for GDB, the GNU debugger.
00149    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00150    2001
00151    Free Software Foundation, Inc.
00152 
00153 This file is part of GDB.
00154 
00155 This program is free software; you can redistribute it and/or modify
00156 it under the terms of the GNU General Public License as published by
00157 the Free Software Foundation; either version 2 of the License, or
00158 (at your option) any later version.
00159 
00160 This program is distributed in the hope that it will be useful,
00161 but WITHOUT ANY WARRANTY; without even the implied warranty of
00162 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00163 GNU General Public License for more details.
00164 
00165 You should have received a copy of the GNU General Public License along
00166 with this program; if not, write to the Free Software Foundation, Inc.,
00167 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00168 */
00169 
00170 /*
00171  * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
00172  * July 1988
00173  *  modified by John Hassey (hassey@dg-rtp.dg.com)
00174  *  x86-64 support added by Jan Hubicka (jh@suse.cz)
00175  */
00176 
00177 /*
00178  * The main tables describing the instructions is essentially a copy
00179  * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
00180  * Programmers Manual.  Usually, there is a capital letter, followed
00181  * by a small letter.  The capital letter tell the addressing mode,
00182  * and the small letter tells about the operand size.  Refer to
00183  * the Intel manual for details.
00184  */
00185 
00186 #include "dis-asm.h"
00187 #if 0
00188 #include "sysdep.h"
00189 #include "opintl.h"
00190 #endif
00191 
00192 #define MAXLEN 20
00193 
00194 #include <setjmp.h>
00195 
00196 #ifndef UNIXWARE_COMPAT
00197 /* Set non-zero for broken, compatible instructions.  Set to zero for
00198    non-broken opcodes.  */
00199 #define UNIXWARE_COMPAT 1
00200 #endif
00201 
00202 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
00203 static void ckprefix PARAMS ((void));
00204 static const char *prefix_name PARAMS ((int, int));
00205 static int print_insn PARAMS ((bfd_vma, disassemble_info *));
00206 static void dofloat PARAMS ((int));
00207 static void OP_ST PARAMS ((int, int));
00208 static void OP_STi  PARAMS ((int, int));
00209 static int putop PARAMS ((const char *, int));
00210 static void oappend PARAMS ((const char *));
00211 static void append_seg PARAMS ((void));
00212 static void OP_indirE PARAMS ((int, int));
00213 static void print_operand_value PARAMS ((char *, int, bfd_vma));
00214 static void OP_E PARAMS ((int, int));
00215 static void OP_G PARAMS ((int, int));
00216 static bfd_vma get64 PARAMS ((void));
00217 static bfd_signed_vma get32 PARAMS ((void));
00218 static bfd_signed_vma get32s PARAMS ((void));
00219 static int get16 PARAMS ((void));
00220 static void set_op PARAMS ((bfd_vma, int));
00221 static void OP_REG PARAMS ((int, int));
00222 static void OP_IMREG PARAMS ((int, int));
00223 static void OP_I PARAMS ((int, int));
00224 static void OP_I64 PARAMS ((int, int));
00225 static void OP_sI PARAMS ((int, int));
00226 static void OP_J PARAMS ((int, int));
00227 static void OP_SEG PARAMS ((int, int));
00228 static void OP_DIR PARAMS ((int, int));
00229 static void OP_OFF PARAMS ((int, int));
00230 static void OP_OFF64 PARAMS ((int, int));
00231 static void ptr_reg PARAMS ((int, int));
00232 static void OP_ESreg PARAMS ((int, int));
00233 static void OP_DSreg PARAMS ((int, int));
00234 static void OP_C PARAMS ((int, int));
00235 static void OP_D PARAMS ((int, int));
00236 static void OP_T PARAMS ((int, int));
00237 static void OP_Rd PARAMS ((int, int));
00238 static void OP_MMX PARAMS ((int, int));
00239 static void OP_XMM PARAMS ((int, int));
00240 static void OP_EM PARAMS ((int, int));
00241 static void OP_EX PARAMS ((int, int));
00242 static void OP_MS PARAMS ((int, int));
00243 static void OP_XS PARAMS ((int, int));
00244 static void OP_3DNowSuffix PARAMS ((int, int));
00245 static void OP_SIMD_Suffix PARAMS ((int, int));
00246 static void SIMD_Fixup PARAMS ((int, int));
00247 static void BadOp PARAMS ((void));
00248 
00249 struct dis_private {
00250   /* Points to first byte not fetched.  */
00251   bfd_byte *max_fetched;
00252   bfd_byte the_buffer[MAXLEN];
00253   bfd_vma insn_start;
00254   int orig_sizeflag;
00255   jmp_buf bailout;
00256 };
00257 
00258 /* The opcode for the fwait instruction, which we treat as a prefix
00259    when we can.  */
00260 #define FWAIT_OPCODE (0x9b)
00261 
00262 /* Set to 1 for 64bit mode disassembly.  */
00263 static int mode_64bit = 1;
00264 
00265 /* Flags for the prefixes for the current instruction.  See below.  */
00266 static int prefixes;
00267 
00268 /* REX prefix the current instruction.  See below.  */
00269 static int rex;
00270 /* Bits of REX we've already used.  */
00271 static int rex_used;
00272 #define REX_MODE64  8
00273 #define REX_EXTX    4
00274 #define REX_EXTY    2
00275 #define REX_EXTZ    1
00276 /* Mark parts used in the REX prefix.  When we are testing for
00277    empty prefix (for 8bit register REX extension), just mask it
00278    out.  Otherwise test for REX bit is excuse for existence of REX
00279    only in case value is nonzero.  */
00280 #define USED_REX(value)                 \
00281   {                         \
00282     if (value)                      \
00283       rex_used |= (rex & value) ? (value) | 0x40 : 0;   \
00284     else                        \
00285       rex_used |= 0x40;                 \
00286   }
00287 
00288 /* Flags for prefixes which we somehow handled when printing the
00289    current instruction.  */
00290 static int used_prefixes;
00291 
00292 /* Flags stored in PREFIXES.  */
00293 #define PREFIX_REPZ 1
00294 #define PREFIX_REPNZ 2
00295 #define PREFIX_LOCK 4
00296 #define PREFIX_CS 8
00297 #define PREFIX_SS 0x10
00298 #define PREFIX_DS 0x20
00299 #define PREFIX_ES 0x40
00300 #define PREFIX_FS 0x80
00301 #define PREFIX_GS 0x100
00302 #define PREFIX_DATA 0x200
00303 #define PREFIX_ADDR 0x400
00304 #define PREFIX_FWAIT 0x800
00305 
00306 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
00307    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
00308    on error.  */
00309 #define FETCH_DATA(info, addr) \
00310   ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
00311    ? 1 : fetch_data ((info), (addr)))
00312 
00313 static int
00314 fetch_data (info, addr)
00315      struct disassemble_info *info;
00316      bfd_byte *addr;
00317 {
00318   int status;
00319   struct dis_private *priv = (struct dis_private *) info->private_data;
00320   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
00321 
00322   status = (*info->read_memory_func) (start,
00323                       priv->max_fetched,
00324                       addr - priv->max_fetched,
00325                       info);
00326   if (status != 0)
00327     {
00328       /* If we did manage to read at least one byte, then
00329          print_insn_i386 will do something sensible.  Otherwise, print
00330          an error.  We do that here because this is where we know
00331          STATUS.  */
00332       if (priv->max_fetched == priv->the_buffer)
00333     (*info->memory_error_func) (status, start, info);
00334       longjmp (priv->bailout, 1);
00335     }
00336   else
00337     priv->max_fetched = addr;
00338   return 1;
00339 }
00340 
00341 #define XX NULL, 0
00342 
00343 #define Eb OP_E, b_mode
00344 #define Ev OP_E, v_mode
00345 #define Ed OP_E, d_mode
00346 #define indirEb OP_indirE, b_mode
00347 #define indirEv OP_indirE, v_mode
00348 #define Ew OP_E, w_mode
00349 #define Ma OP_E, v_mode
00350 #define M OP_E, 0       /* lea, lgdt, etc. */
00351 #define Mp OP_E, 0      /* 32 or 48 bit memory operand for LDS, LES etc */
00352 #define Gb OP_G, b_mode
00353 #define Gv OP_G, v_mode
00354 #define Gd OP_G, d_mode
00355 #define Gw OP_G, w_mode
00356 #define Rd OP_Rd, d_mode
00357 #define Rm OP_Rd, m_mode
00358 #define Ib OP_I, b_mode
00359 #define sIb OP_sI, b_mode   /* sign extened byte */
00360 #define Iv OP_I, v_mode
00361 #define Iq OP_I, q_mode
00362 #define Iv64 OP_I64, v_mode
00363 #define Iw OP_I, w_mode
00364 #define Jb OP_J, b_mode
00365 #define Jv OP_J, v_mode
00366 #define Cm OP_C, m_mode
00367 #define Dm OP_D, m_mode
00368 #define Td OP_T, d_mode
00369 
00370 #define RMeAX OP_REG, eAX_reg
00371 #define RMeBX OP_REG, eBX_reg
00372 #define RMeCX OP_REG, eCX_reg
00373 #define RMeDX OP_REG, eDX_reg
00374 #define RMeSP OP_REG, eSP_reg
00375 #define RMeBP OP_REG, eBP_reg
00376 #define RMeSI OP_REG, eSI_reg
00377 #define RMeDI OP_REG, eDI_reg
00378 #define RMrAX OP_REG, rAX_reg
00379 #define RMrBX OP_REG, rBX_reg
00380 #define RMrCX OP_REG, rCX_reg
00381 #define RMrDX OP_REG, rDX_reg
00382 #define RMrSP OP_REG, rSP_reg
00383 #define RMrBP OP_REG, rBP_reg
00384 #define RMrSI OP_REG, rSI_reg
00385 #define RMrDI OP_REG, rDI_reg
00386 #define RMAL OP_REG, al_reg
00387 #define RMAL OP_REG, al_reg
00388 #define RMCL OP_REG, cl_reg
00389 #define RMDL OP_REG, dl_reg
00390 #define RMBL OP_REG, bl_reg
00391 #define RMAH OP_REG, ah_reg
00392 #define RMCH OP_REG, ch_reg
00393 #define RMDH OP_REG, dh_reg
00394 #define RMBH OP_REG, bh_reg
00395 #define RMAX OP_REG, ax_reg
00396 #define RMDX OP_REG, dx_reg
00397 
00398 #define eAX OP_IMREG, eAX_reg
00399 #define eBX OP_IMREG, eBX_reg
00400 #define eCX OP_IMREG, eCX_reg
00401 #define eDX OP_IMREG, eDX_reg
00402 #define eSP OP_IMREG, eSP_reg
00403 #define eBP OP_IMREG, eBP_reg
00404 #define eSI OP_IMREG, eSI_reg
00405 #define eDI OP_IMREG, eDI_reg
00406 #define AL OP_IMREG, al_reg
00407 #define AL OP_IMREG, al_reg
00408 #define CL OP_IMREG, cl_reg
00409 #define DL OP_IMREG, dl_reg
00410 #define BL OP_IMREG, bl_reg
00411 #define AH OP_IMREG, ah_reg
00412 #define CH OP_IMREG, ch_reg
00413 #define DH OP_IMREG, dh_reg
00414 #define BH OP_IMREG, bh_reg
00415 #define AX OP_IMREG, ax_reg
00416 #define DX OP_IMREG, dx_reg
00417 #define indirDX OP_IMREG, indir_dx_reg
00418 
00419 #define Sw OP_SEG, w_mode
00420 #define Ap OP_DIR, 0
00421 #define Ob OP_OFF, b_mode
00422 #define Ob64 OP_OFF64, b_mode
00423 #define Ov OP_OFF, v_mode
00424 #define Ov64 OP_OFF64, v_mode
00425 #define Xb OP_DSreg, eSI_reg
00426 #define Xv OP_DSreg, eSI_reg
00427 #define Yb OP_ESreg, eDI_reg
00428 #define Yv OP_ESreg, eDI_reg
00429 #define DSBX OP_DSreg, eBX_reg
00430 
00431 #define es OP_REG, es_reg
00432 #define ss OP_REG, ss_reg
00433 #define cs OP_REG, cs_reg
00434 #define ds OP_REG, ds_reg
00435 #define fs OP_REG, fs_reg
00436 #define gs OP_REG, gs_reg
00437 
00438 #define MX OP_MMX, 0
00439 #define XM OP_XMM, 0
00440 #define EM OP_EM, v_mode
00441 #define EX OP_EX, v_mode
00442 #define MS OP_MS, v_mode
00443 #define XS OP_XS, v_mode
00444 #define None OP_E, 0
00445 #define OPSUF OP_3DNowSuffix, 0
00446 #define OPSIMD OP_SIMD_Suffix, 0
00447 
00448 #define cond_jump_flag NULL, cond_jump_mode
00449 #define loop_jcxz_flag NULL, loop_jcxz_mode
00450 
00451 /* bits in sizeflag */
00452 #define SUFFIX_ALWAYS 4
00453 #define AFLAG 2
00454 #define DFLAG 1
00455 
00456 #define b_mode 1  /* byte operand */
00457 #define v_mode 2  /* operand size depends on prefixes */
00458 #define w_mode 3  /* word operand */
00459 #define d_mode 4  /* double word operand  */
00460 #define q_mode 5  /* quad word operand */
00461 #define x_mode 6
00462 #define m_mode 7  /* d_mode in 32bit, q_mode in 64bit mode.  */
00463 #define cond_jump_mode 8
00464 #define loop_jcxz_mode 9
00465 
00466 #define es_reg 100
00467 #define cs_reg 101
00468 #define ss_reg 102
00469 #define ds_reg 103
00470 #define fs_reg 104
00471 #define gs_reg 105
00472 
00473 #define eAX_reg 108
00474 #define eCX_reg 109
00475 #define eDX_reg 110
00476 #define eBX_reg 111
00477 #define eSP_reg 112
00478 #define eBP_reg 113
00479 #define eSI_reg 114
00480 #define eDI_reg 115
00481 
00482 #define al_reg 116
00483 #define cl_reg 117
00484 #define dl_reg 118
00485 #define bl_reg 119
00486 #define ah_reg 120
00487 #define ch_reg 121
00488 #define dh_reg 122
00489 #define bh_reg 123
00490 
00491 #define ax_reg 124
00492 #define cx_reg 125
00493 #define dx_reg 126
00494 #define bx_reg 127
00495 #define sp_reg 128
00496 #define bp_reg 129
00497 #define si_reg 130
00498 #define di_reg 131
00499 
00500 #define rAX_reg 132
00501 #define rCX_reg 133
00502 #define rDX_reg 134
00503 #define rBX_reg 135
00504 #define rSP_reg 136
00505 #define rBP_reg 137
00506 #define rSI_reg 138
00507 #define rDI_reg 139
00508 
00509 #define indir_dx_reg 150
00510 
00511 #define FLOATCODE 1
00512 #define USE_GROUPS 2
00513 #define USE_PREFIX_USER_TABLE 3
00514 #define X86_64_SPECIAL 4
00515 
00516 #define FLOAT     NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
00517 
00518 #define GRP1b     NULL, NULL, USE_GROUPS, NULL,  0, NULL, 0
00519 #define GRP1S     NULL, NULL, USE_GROUPS, NULL,  1, NULL, 0
00520 #define GRP1Ss    NULL, NULL, USE_GROUPS, NULL,  2, NULL, 0
00521 #define GRP2b     NULL, NULL, USE_GROUPS, NULL,  3, NULL, 0
00522 #define GRP2S     NULL, NULL, USE_GROUPS, NULL,  4, NULL, 0
00523 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL,  5, NULL, 0
00524 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL,  6, NULL, 0
00525 #define GRP2b_cl  NULL, NULL, USE_GROUPS, NULL,  7, NULL, 0
00526 #define GRP2S_cl  NULL, NULL, USE_GROUPS, NULL,  8, NULL, 0
00527 #define GRP3b     NULL, NULL, USE_GROUPS, NULL,  9, NULL, 0
00528 #define GRP3S     NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
00529 #define GRP4      NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
00530 #define GRP5      NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
00531 #define GRP6      NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
00532 #define GRP7      NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
00533 #define GRP8      NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
00534 #define GRP9      NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
00535 #define GRP10     NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
00536 #define GRP11     NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
00537 #define GRP12     NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
00538 #define GRP13     NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
00539 #define GRP14     NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
00540 #define GRPAMD    NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
00541 
00542 #define PREGRP0   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
00543 #define PREGRP1   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
00544 #define PREGRP2   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  2, NULL, 0
00545 #define PREGRP3   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  3, NULL, 0
00546 #define PREGRP4   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  4, NULL, 0
00547 #define PREGRP5   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  5, NULL, 0
00548 #define PREGRP6   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  6, NULL, 0
00549 #define PREGRP7   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  7, NULL, 0
00550 #define PREGRP8   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  8, NULL, 0
00551 #define PREGRP9   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  9, NULL, 0
00552 #define PREGRP10  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
00553 #define PREGRP11  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
00554 #define PREGRP12  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
00555 #define PREGRP13  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
00556 #define PREGRP14  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
00557 #define PREGRP15  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
00558 #define PREGRP16  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
00559 #define PREGRP17  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
00560 #define PREGRP18  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
00561 #define PREGRP19  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
00562 #define PREGRP20  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
00563 #define PREGRP21  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
00564 #define PREGRP22  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
00565 #define PREGRP23  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
00566 #define PREGRP24  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
00567 #define PREGRP25  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
00568 #define PREGRP26  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
00569 
00570 #define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
00571 
00572 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
00573 
00574 struct dis386 {
00575   const char *name;
00576   op_rtn op1;
00577   int bytemode1;
00578   op_rtn op2;
00579   int bytemode2;
00580   op_rtn op3;
00581   int bytemode3;
00582 };
00583 
00584 /* Upper case letters in the instruction names here are macros.
00585    'A' => print 'b' if no register operands or suffix_always is true
00586    'B' => print 'b' if suffix_always is true
00587    'E' => print 'e' if 32-bit form of jcxz
00588    'F' => print 'w' or 'l' depending on address size prefix (loop insns)
00589    'H' => print ",pt" or ",pn" branch hint
00590    'L' => print 'l' if suffix_always is true
00591    'N' => print 'n' if instruction has no wait "prefix"
00592    'O' => print 'd', or 'o'
00593    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
00594    .      or suffix_always is true.  print 'q' if rex prefix is present.
00595    'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
00596    .      is true
00597    'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
00598    'S' => print 'w', 'l' or 'q' if suffix_always is true
00599    'T' => print 'q' in 64bit mode and behave as 'P' otherwise
00600    'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
00601    'X' => print 's', 'd' depending on data16 prefix (for XMM)
00602    'W' => print 'b' or 'w' ("w" or "de" in intel mode)
00603    'Y' => 'q' if instruction has an REX 64bit overwrite prefix
00604 
00605    Many of the above letters print nothing in Intel mode.  See "putop"
00606    for the details.
00607 
00608    Braces '{' and '}', and vertical bars '|', indicate alternative
00609    mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
00610    modes.  In cases where there are only two alternatives, the X86_64
00611    instruction is reserved, and "(bad)" is printed.
00612 */
00613 
00614 static const struct dis386 dis386[] = {
00615   /* 00 */
00616   { "addB",     Eb, Gb, XX },
00617   { "addS",     Ev, Gv, XX },
00618   { "addB",     Gb, Eb, XX },
00619   { "addS",     Gv, Ev, XX },
00620   { "addB",     AL, Ib, XX },
00621   { "addS",     eAX, Iv, XX },
00622   { "push{T|}",     es, XX, XX },
00623   { "pop{T|}",      es, XX, XX },
00624   /* 08 */
00625   { "orB",      Eb, Gb, XX },
00626   { "orS",      Ev, Gv, XX },
00627   { "orB",      Gb, Eb, XX },
00628   { "orS",      Gv, Ev, XX },
00629   { "orB",      AL, Ib, XX },
00630   { "orS",      eAX, Iv, XX },
00631   { "push{T|}",     cs, XX, XX },
00632   { "(bad)",        XX, XX, XX },   /* 0x0f extended opcode escape */
00633   /* 10 */
00634   { "adcB",     Eb, Gb, XX },
00635   { "adcS",     Ev, Gv, XX },
00636   { "adcB",     Gb, Eb, XX },
00637   { "adcS",     Gv, Ev, XX },
00638   { "adcB",     AL, Ib, XX },
00639   { "adcS",     eAX, Iv, XX },
00640   { "push{T|}",     ss, XX, XX },
00641   { "popT|}",       ss, XX, XX },
00642   /* 18 */
00643   { "sbbB",     Eb, Gb, XX },
00644   { "sbbS",     Ev, Gv, XX },
00645   { "sbbB",     Gb, Eb, XX },
00646   { "sbbS",     Gv, Ev, XX },
00647   { "sbbB",     AL, Ib, XX },
00648   { "sbbS",     eAX, Iv, XX },
00649   { "push{T|}",     ds, XX, XX },
00650   { "pop{T|}",      ds, XX, XX },
00651   /* 20 */
00652   { "andB",     Eb, Gb, XX },
00653   { "andS",     Ev, Gv, XX },
00654   { "andB",     Gb, Eb, XX },
00655   { "andS",     Gv, Ev, XX },
00656   { "andB",     AL, Ib, XX },
00657   { "andS",     eAX, Iv, XX },
00658   { "(bad)",        XX, XX, XX },   /* SEG ES prefix */
00659   { "daa{|}",       XX, XX, XX },
00660   /* 28 */
00661   { "subB",     Eb, Gb, XX },
00662   { "subS",     Ev, Gv, XX },
00663   { "subB",     Gb, Eb, XX },
00664   { "subS",     Gv, Ev, XX },
00665   { "subB",     AL, Ib, XX },
00666   { "subS",     eAX, Iv, XX },
00667   { "(bad)",        XX, XX, XX },   /* SEG CS prefix */
00668   { "das{|}",       XX, XX, XX },
00669   /* 30 */
00670   { "xorB",     Eb, Gb, XX },
00671   { "xorS",     Ev, Gv, XX },
00672   { "xorB",     Gb, Eb, XX },
00673   { "xorS",     Gv, Ev, XX },
00674   { "xorB",     AL, Ib, XX },
00675   { "xorS",     eAX, Iv, XX },
00676   { "(bad)",        XX, XX, XX },   /* SEG SS prefix */
00677   { "aaa{|}",       XX, XX, XX },
00678   /* 38 */
00679   { "cmpB",     Eb, Gb, XX },
00680   { "cmpS",     Ev, Gv, XX },
00681   { "cmpB",     Gb, Eb, XX },
00682   { "cmpS",     Gv, Ev, XX },
00683   { "cmpB",     AL, Ib, XX },
00684   { "cmpS",     eAX, Iv, XX },
00685   { "(bad)",        XX, XX, XX },   /* SEG DS prefix */
00686   { "aas{|}",       XX, XX, XX },
00687   /* 40 */
00688   { "inc{S|}",      RMeAX, XX, XX },
00689   { "inc{S|}",      RMeCX, XX, XX },
00690   { "inc{S|}",      RMeDX, XX, XX },
00691   { "inc{S|}",      RMeBX, XX, XX },
00692   { "inc{S|}",      RMeSP, XX, XX },
00693   { "inc{S|}",      RMeBP, XX, XX },
00694   { "inc{S|}",      RMeSI, XX, XX },
00695   { "inc{S|}",      RMeDI, XX, XX },
00696   /* 48 */
00697   { "dec{S|}",      RMeAX, XX, XX },
00698   { "dec{S|}",      RMeCX, XX, XX },
00699   { "dec{S|}",      RMeDX, XX, XX },
00700   { "dec{S|}",      RMeBX, XX, XX },
00701   { "dec{S|}",      RMeSP, XX, XX },
00702   { "dec{S|}",      RMeBP, XX, XX },
00703   { "dec{S|}",      RMeSI, XX, XX },
00704   { "dec{S|}",      RMeDI, XX, XX },
00705   /* 50 */
00706   { "pushS",        RMrAX, XX, XX },
00707   { "pushS",        RMrCX, XX, XX },
00708   { "pushS",        RMrDX, XX, XX },
00709   { "pushS",        RMrBX, XX, XX },
00710   { "pushS",        RMrSP, XX, XX },
00711   { "pushS",        RMrBP, XX, XX },
00712   { "pushS",        RMrSI, XX, XX },
00713   { "pushS",        RMrDI, XX, XX },
00714   /* 58 */
00715   { "popS",     RMrAX, XX, XX },
00716   { "popS",     RMrCX, XX, XX },
00717   { "popS",     RMrDX, XX, XX },
00718   { "popS",     RMrBX, XX, XX },
00719   { "popS",     RMrSP, XX, XX },
00720   { "popS",     RMrBP, XX, XX },
00721   { "popS",     RMrSI, XX, XX },
00722   { "popS",     RMrDI, XX, XX },
00723   /* 60 */
00724   { "pusha{P|}",    XX, XX, XX },
00725   { "popa{P|}",     XX, XX, XX },
00726   { "bound{S|}",    Gv, Ma, XX },
00727   { X86_64_0 },
00728   { "(bad)",        XX, XX, XX },   /* seg fs */
00729   { "(bad)",        XX, XX, XX },   /* seg gs */
00730   { "(bad)",        XX, XX, XX },   /* op size prefix */
00731   { "(bad)",        XX, XX, XX },   /* adr size prefix */
00732   /* 68 */
00733   { "pushT",        Iq, XX, XX },
00734   { "imulS",        Gv, Ev, Iv },
00735   { "pushT",        sIb, XX, XX },
00736   { "imulS",        Gv, Ev, sIb },
00737   { "ins{b||b|}",   Yb, indirDX, XX },
00738   { "ins{R||R|}",   Yv, indirDX, XX },
00739   { "outs{b||b|}",  indirDX, Xb, XX },
00740   { "outs{R||R|}",  indirDX, Xv, XX },
00741   /* 70 */
00742   { "joH",      Jb, XX, cond_jump_flag },
00743   { "jnoH",     Jb, XX, cond_jump_flag },
00744   { "jbH",      Jb, XX, cond_jump_flag },
00745   { "jaeH",     Jb, XX, cond_jump_flag },
00746   { "jeH",      Jb, XX, cond_jump_flag },
00747   { "jneH",     Jb, XX, cond_jump_flag },
00748   { "jbeH",     Jb, XX, cond_jump_flag },
00749   { "jaH",      Jb, XX, cond_jump_flag },
00750   /* 78 */
00751   { "jsH",      Jb, XX, cond_jump_flag },
00752   { "jnsH",     Jb, XX, cond_jump_flag },
00753   { "jpH",      Jb, XX, cond_jump_flag },
00754   { "jnpH",     Jb, XX, cond_jump_flag },
00755   { "jlH",      Jb, XX, cond_jump_flag },
00756   { "jgeH",     Jb, XX, cond_jump_flag },
00757   { "jleH",     Jb, XX, cond_jump_flag },
00758   { "jgH",      Jb, XX, cond_jump_flag },
00759   /* 80 */
00760   { GRP1b },
00761   { GRP1S },
00762   { "(bad)",        XX, XX, XX },
00763   { GRP1Ss },
00764   { "testB",        Eb, Gb, XX },
00765   { "testS",        Ev, Gv, XX },
00766   { "xchgB",        Eb, Gb, XX },
00767   { "xchgS",        Ev, Gv, XX },
00768   /* 88 */
00769   { "movB",     Eb, Gb, XX },
00770   { "movS",     Ev, Gv, XX },
00771   { "movB",     Gb, Eb, XX },
00772   { "movS",     Gv, Ev, XX },
00773   { "movQ",     Ev, Sw, XX },
00774   { "leaS",     Gv, M, XX },
00775   { "movQ",     Sw, Ev, XX },
00776   { "popU",     Ev, XX, XX },
00777   /* 90 */
00778   { "nop",      XX, XX, XX },
00779   /* FIXME: NOP with REPz prefix is called PAUSE.  */
00780   { "xchgS",        RMeCX, eAX, XX },
00781   { "xchgS",        RMeDX, eAX, XX },
00782   { "xchgS",        RMeBX, eAX, XX },
00783   { "xchgS",        RMeSP, eAX, XX },
00784   { "xchgS",        RMeBP, eAX, XX },
00785   { "xchgS",        RMeSI, eAX, XX },
00786   { "xchgS",        RMeDI, eAX, XX },
00787   /* 98 */
00788   { "cW{tR||tR|}",  XX, XX, XX },
00789   { "cR{tO||tO|}",  XX, XX, XX },
00790   { "lcall{T|}",    Ap, XX, XX },
00791   { "(bad)",        XX, XX, XX },   /* fwait */
00792   { "pushfT",       XX, XX, XX },
00793   { "popfT",        XX, XX, XX },
00794   { "sahf{|}",      XX, XX, XX },
00795   { "lahf{|}",      XX, XX, XX },
00796   /* a0 */
00797   { "movB",     AL, Ob64, XX },
00798   { "movS",     eAX, Ov64, XX },
00799   { "movB",     Ob64, AL, XX },
00800   { "movS",     Ov64, eAX, XX },
00801   { "movs{b||b|}",  Yb, Xb, XX },
00802   { "movs{R||R|}",  Yv, Xv, XX },
00803   { "cmps{b||b|}",  Xb, Yb, XX },
00804   { "cmps{R||R|}",  Xv, Yv, XX },
00805   /* a8 */
00806   { "testB",        AL, Ib, XX },
00807   { "testS",        eAX, Iv, XX },
00808   { "stosB",        Yb, AL, XX },
00809   { "stosS",        Yv, eAX, XX },
00810   { "lodsB",        AL, Xb, XX },
00811   { "lodsS",        eAX, Xv, XX },
00812   { "scasB",        AL, Yb, XX },
00813   { "scasS",        eAX, Yv, XX },
00814   /* b0 */
00815   { "movB",     RMAL, Ib, XX },
00816   { "movB",     RMCL, Ib, XX },
00817   { "movB",     RMDL, Ib, XX },
00818   { "movB",     RMBL, Ib, XX },
00819   { "movB",     RMAH, Ib, XX },
00820   { "movB",     RMCH, Ib, XX },
00821   { "movB",     RMDH, Ib, XX },
00822   { "movB",     RMBH, Ib, XX },
00823   /* b8 */
00824   { "movS",     RMeAX, Iv64, XX },
00825   { "movS",     RMeCX, Iv64, XX },
00826   { "movS",     RMeDX, Iv64, XX },
00827   { "movS",     RMeBX, Iv64, XX },
00828   { "movS",     RMeSP, Iv64, XX },
00829   { "movS",     RMeBP, Iv64, XX },
00830   { "movS",     RMeSI, Iv64, XX },
00831   { "movS",     RMeDI, Iv64, XX },
00832   /* c0 */
00833   { GRP2b },
00834   { GRP2S },
00835   { "retT",     Iw, XX, XX },
00836   { "retT",     XX, XX, XX },
00837   { "les{S|}",      Gv, Mp, XX },
00838   { "ldsS",     Gv, Mp, XX },
00839   { "movA",     Eb, Ib, XX },
00840   { "movQ",     Ev, Iv, XX },
00841   /* c8 */
00842   { "enterT",       Iw, Ib, XX },
00843   { "leaveT",       XX, XX, XX },
00844   { "lretP",        Iw, XX, XX },
00845   { "lretP",        XX, XX, XX },
00846   { "int3",     XX, XX, XX },
00847   { "int",      Ib, XX, XX },
00848   { "into{|}",      XX, XX, XX },
00849   { "iretP",        XX, XX, XX },
00850   /* d0 */
00851   { GRP2b_one },
00852   { GRP2S_one },
00853   { GRP2b_cl },
00854   { GRP2S_cl },
00855   { "aam{|}",       sIb, XX, XX },
00856   { "aad{|}",       sIb, XX, XX },
00857   { "(bad)",        XX, XX, XX },
00858   { "xlat",     DSBX, XX, XX },
00859   /* d8 */
00860   { FLOAT },
00861   { FLOAT },
00862   { FLOAT },
00863   { FLOAT },
00864   { FLOAT },
00865   { FLOAT },
00866   { FLOAT },
00867   { FLOAT },
00868   /* e0 */
00869   { "loopneFH",     Jb, XX, loop_jcxz_flag },
00870   { "loopeFH",      Jb, XX, loop_jcxz_flag },
00871   { "loopFH",       Jb, XX, loop_jcxz_flag },
00872   { "jEcxzH",       Jb, XX, loop_jcxz_flag },
00873   { "inB",      AL, Ib, XX },
00874   { "inS",      eAX, Ib, XX },
00875   { "outB",     Ib, AL, XX },
00876   { "outS",     Ib, eAX, XX },
00877   /* e8 */
00878   { "callT",        Jv, XX, XX },
00879   { "jmpT",     Jv, XX, XX },
00880   { "ljmp{T|}",     Ap, XX, XX },
00881   { "jmp",      Jb, XX, XX },
00882   { "inB",      AL, indirDX, XX },
00883   { "inS",      eAX, indirDX, XX },
00884   { "outB",     indirDX, AL, XX },
00885   { "outS",     indirDX, eAX, XX },
00886   /* f0 */
00887   { "(bad)",        XX, XX, XX },   /* lock prefix */
00888   { "(bad)",        XX, XX, XX },
00889   { "(bad)",        XX, XX, XX },   /* repne */
00890   { "(bad)",        XX, XX, XX },   /* repz */
00891   { "hlt",      XX, XX, XX },
00892   { "cmc",      XX, XX, XX },
00893   { GRP3b },
00894   { GRP3S },
00895   /* f8 */
00896   { "clc",      XX, XX, XX },
00897   { "stc",      XX, XX, XX },
00898   { "cli",      XX, XX, XX },
00899   { "sti",      XX, XX, XX },
00900   { "cld",      XX, XX, XX },
00901   { "std",      XX, XX, XX },
00902   { GRP4 },
00903   { GRP5 },
00904 };
00905 
00906 static const struct dis386 dis386_twobyte[] = {
00907   /* 00 */
00908   { GRP6 },
00909   { GRP7 },
00910   { "larS",     Gv, Ew, XX },
00911   { "lslS",     Gv, Ew, XX },
00912   { "(bad)",        XX, XX, XX },
00913   { "syscall",      XX, XX, XX },
00914   { "clts",     XX, XX, XX },
00915   { "sysretP",      XX, XX, XX },
00916   /* 08 */
00917   { "invd",     XX, XX, XX },
00918   { "wbinvd",       XX, XX, XX },
00919   { "(bad)",        XX, XX, XX },
00920   { "ud2a",     XX, XX, XX },
00921   { "(bad)",        XX, XX, XX },
00922   { GRPAMD },
00923   { "femms",        XX, XX, XX },
00924   { "",         MX, EM, OPSUF }, /* See OP_3DNowSuffix.  */
00925   /* 10 */
00926   { PREGRP8 },
00927   { PREGRP9 },
00928   { "movlpX",       XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
00929   { "movlpX",       EX, XM, SIMD_Fixup, 'h' },
00930   { "unpcklpX",     XM, EX, XX },
00931   { "unpckhpX",     XM, EX, XX },
00932   { "movhpX",       XM, EX, SIMD_Fixup, 'l' },
00933   { "movhpX",       EX, XM, SIMD_Fixup, 'l' },
00934   /* 18 */
00935   { GRP14 },
00936   { "(bad)",        XX, XX, XX },
00937   { "(bad)",        XX, XX, XX },
00938   { "(bad)",        XX, XX, XX },
00939   { "(bad)",        XX, XX, XX },
00940   { "(bad)",        XX, XX, XX },
00941   { "(bad)",        XX, XX, XX },
00942   { "(bad)",        XX, XX, XX },
00943   /* 20 */
00944   { "movL",     Rm, Cm, XX },
00945   { "movL",     Rm, Dm, XX },
00946   { "movL",     Cm, Rm, XX },
00947   { "movL",     Dm, Rm, XX },
00948   { "movL",     Rd, Td, XX },
00949   { "(bad)",        XX, XX, XX },
00950   { "movL",     Td, Rd, XX },
00951   { "(bad)",        XX, XX, XX },
00952   /* 28 */
00953   { "movapX",       XM, EX, XX },
00954   { "movapX",       EX, XM, XX },
00955   { PREGRP2 },
00956   { "movntpX",      Ev, XM, XX },
00957   { PREGRP4 },
00958   { PREGRP3 },
00959   { "ucomisX",      XM,EX, XX },
00960   { "comisX",       XM,EX, XX },
00961   /* 30 */
00962   { "wrmsr",        XX, XX, XX },
00963   { "rdtsc",        XX, XX, XX },
00964   { "rdmsr",        XX, XX, XX },
00965   { "rdpmc",        XX, XX, XX },
00966   { "sysenter",     XX, XX, XX },
00967   { "sysexit",      XX, XX, XX },
00968   { "(bad)",        XX, XX, XX },
00969   { "(bad)",        XX, XX, XX },
00970   /* 38 */
00971   { "(bad)",        XX, XX, XX },
00972   { "(bad)",        XX, XX, XX },
00973   { "(bad)",        XX, XX, XX },
00974   { "(bad)",        XX, XX, XX },
00975   { "(bad)",        XX, XX, XX },
00976   { "(bad)",        XX, XX, XX },
00977   { "(bad)",        XX, XX, XX },
00978   { "(bad)",        XX, XX, XX },
00979   /* 40 */
00980   { "cmovo",        Gv, Ev, XX },
00981   { "cmovno",       Gv, Ev, XX },
00982   { "cmovb",        Gv, Ev, XX },
00983   { "cmovae",       Gv, Ev, XX },
00984   { "cmove",        Gv, Ev, XX },
00985   { "cmovne",       Gv, Ev, XX },
00986   { "cmovbe",       Gv, Ev, XX },
00987   { "cmova",        Gv, Ev, XX },
00988   /* 48 */
00989   { "cmovs",        Gv, Ev, XX },
00990   { "cmovns",       Gv, Ev, XX },
00991   { "cmovp",        Gv, Ev, XX },
00992   { "cmovnp",       Gv, Ev, XX },
00993   { "cmovl",        Gv, Ev, XX },
00994   { "cmovge",       Gv, Ev, XX },
00995   { "cmovle",       Gv, Ev, XX },
00996   { "cmovg",        Gv, Ev, XX },
00997   /* 50 */
00998   { "movmskpX",     Gd, XS, XX },
00999   { PREGRP13 },
01000   { PREGRP12 },
01001   { PREGRP11 },
01002   { "andpX",        XM, EX, XX },
01003   { "andnpX",       XM, EX, XX },
01004   { "orpX",     XM, EX, XX },
01005   { "xorpX",        XM, EX, XX },
01006   /* 58 */
01007   { PREGRP0 },
01008   { PREGRP10 },
01009   { PREGRP17 },
01010   { PREGRP16 },
01011   { PREGRP14 },
01012   { PREGRP7 },
01013   { PREGRP5 },
01014   { PREGRP6 },
01015   /* 60 */
01016   { "punpcklbw",    MX, EM, XX },
01017   { "punpcklwd",    MX, EM, XX },
01018   { "punpckldq",    MX, EM, XX },
01019   { "packsswb",     MX, EM, XX },
01020   { "pcmpgtb",      MX, EM, XX },
01021   { "pcmpgtw",      MX, EM, XX },
01022   { "pcmpgtd",      MX, EM, XX },
01023   { "packuswb",     MX, EM, XX },
01024   /* 68 */
01025   { "punpckhbw",    MX, EM, XX },
01026   { "punpckhwd",    MX, EM, XX },
01027   { "punpckhdq",    MX, EM, XX },
01028   { "packssdw",     MX, EM, XX },
01029   { PREGRP26 },
01030   { PREGRP24 },
01031   { "movd",     MX, Ed, XX },
01032   { PREGRP19 },
01033   /* 70 */
01034   { PREGRP22 },
01035   { GRP10 },
01036   { GRP11 },
01037   { GRP12 },
01038   { "pcmpeqb",      MX, EM, XX },
01039   { "pcmpeqw",      MX, EM, XX },
01040   { "pcmpeqd",      MX, EM, XX },
01041   { "emms",     XX, XX, XX },
01042   /* 78 */
01043   { "(bad)",        XX, XX, XX },
01044   { "(bad)",        XX, XX, XX },
01045   { "(bad)",        XX, XX, XX },
01046   { "(bad)",        XX, XX, XX },
01047   { "(bad)",        XX, XX, XX },
01048   { "(bad)",        XX, XX, XX },
01049   { PREGRP23 },
01050   { PREGRP20 },
01051   /* 80 */
01052   { "joH",      Jv, XX, cond_jump_flag },
01053   { "jnoH",     Jv, XX, cond_jump_flag },
01054   { "jbH",      Jv, XX, cond_jump_flag },
01055   { "jaeH",     Jv, XX, cond_jump_flag },
01056   { "jeH",      Jv, XX, cond_jump_flag },
01057   { "jneH",     Jv, XX, cond_jump_flag },
01058   { "jbeH",     Jv, XX, cond_jump_flag },
01059   { "jaH",      Jv, XX, cond_jump_flag },
01060   /* 88 */
01061   { "jsH",      Jv, XX, cond_jump_flag },
01062   { "jnsH",     Jv, XX, cond_jump_flag },
01063   { "jpH",      Jv, XX, cond_jump_flag },
01064   { "jnpH",     Jv, XX, cond_jump_flag },
01065   { "jlH",      Jv, XX, cond_jump_flag },
01066   { "jgeH",     Jv, XX, cond_jump_flag },
01067   { "jleH",     Jv, XX, cond_jump_flag },
01068   { "jgH",      Jv, XX, cond_jump_flag },
01069   /* 90 */
01070   { "seto",     Eb, XX, XX },
01071   { "setno",        Eb, XX, XX },
01072   { "setb",     Eb, XX, XX },
01073   { "setae",        Eb, XX, XX },
01074   { "sete",     Eb, XX, XX },
01075   { "setne",        Eb, XX, XX },
01076   { "setbe",        Eb, XX, XX },
01077   { "seta",     Eb, XX, XX },
01078   /* 98 */
01079   { "sets",     Eb, XX, XX },
01080   { "setns",        Eb, XX, XX },
01081   { "setp",     Eb, XX, XX },
01082   { "setnp",        Eb, XX, XX },
01083   { "setl",     Eb, XX, XX },
01084   { "setge",        Eb, XX, XX },
01085   { "setle",        Eb, XX, XX },
01086   { "setg",     Eb, XX, XX },
01087   /* a0 */
01088   { "pushT",        fs, XX, XX },
01089   { "popT",     fs, XX, XX },
01090   { "cpuid",        XX, XX, XX },
01091   { "btS",      Ev, Gv, XX },
01092   { "shldS",        Ev, Gv, Ib },
01093   { "shldS",        Ev, Gv, CL },
01094   { "(bad)",        XX, XX, XX },
01095   { "(bad)",        XX, XX, XX },
01096   /* a8 */
01097   { "pushT",        gs, XX, XX },
01098   { "popT",     gs, XX, XX },
01099   { "rsm",      XX, XX, XX },
01100   { "btsS",     Ev, Gv, XX },
01101   { "shrdS",        Ev, Gv, Ib },
01102   { "shrdS",        Ev, Gv, CL },
01103   { GRP13 },
01104   { "imulS",        Gv, Ev, XX },
01105   /* b0 */
01106   { "cmpxchgB",     Eb, Gb, XX },
01107   { "cmpxchgS",     Ev, Gv, XX },
01108   { "lssS",     Gv, Mp, XX },
01109   { "btrS",     Ev, Gv, XX },
01110   { "lfsS",     Gv, Mp, XX },
01111   { "lgsS",     Gv, Mp, XX },
01112   { "movz{bR|x|bR|x}",  Gv, Eb, XX },
01113   { "movz{wR|x|wR|x}",  Gv, Ew, XX }, /* yes, there really is movzww ! */
01114   /* b8 */
01115   { "(bad)",        XX, XX, XX },
01116   { "ud2b",     XX, XX, XX },
01117   { GRP8 },
01118   { "btcS",     Ev, Gv, XX },
01119   { "bsfS",     Gv, Ev, XX },
01120   { "bsrS",     Gv, Ev, XX },
01121   { "movs{bR|x|bR|x}",  Gv, Eb, XX },
01122   { "movs{wR|x|wR|x}",  Gv, Ew, XX }, /* yes, there really is movsww ! */
01123   /* c0 */
01124   { "xaddB",        Eb, Gb, XX },
01125   { "xaddS",        Ev, Gv, XX },
01126   { PREGRP1 },
01127   { "movntiS",      Ev, Gv, XX },
01128   { "pinsrw",       MX, Ed, Ib },
01129   { "pextrw",       Gd, MS, Ib },
01130   { "shufpX",       XM, EX, Ib },
01131   { GRP9 },
01132   /* c8 */
01133   { "bswap",        RMeAX, XX, XX },
01134   { "bswap",        RMeCX, XX, XX },
01135   { "bswap",        RMeDX, XX, XX },
01136   { "bswap",        RMeBX, XX, XX },
01137   { "bswap",        RMeSP, XX, XX },
01138   { "bswap",        RMeBP, XX, XX },
01139   { "bswap",        RMeSI, XX, XX },
01140   { "bswap",        RMeDI, XX, XX },
01141   /* d0 */
01142   { "(bad)",        XX, XX, XX },
01143   { "psrlw",        MX, EM, XX },
01144   { "psrld",        MX, EM, XX },
01145   { "psrlq",        MX, EM, XX },
01146   { "paddq",        MX, EM, XX },
01147   { "pmullw",       MX, EM, XX },
01148   { PREGRP21 },
01149   { "pmovmskb",     Gd, MS, XX },
01150   /* d8 */
01151   { "psubusb",      MX, EM, XX },
01152   { "psubusw",      MX, EM, XX },
01153   { "pminub",       MX, EM, XX },
01154   { "pand",     MX, EM, XX },
01155   { "paddusb",      MX, EM, XX },
01156   { "paddusw",      MX, EM, XX },
01157   { "pmaxub",       MX, EM, XX },
01158   { "pandn",        MX, EM, XX },
01159   /* e0 */
01160   { "pavgb",        MX, EM, XX },
01161   { "psraw",        MX, EM, XX },
01162   { "psrad",        MX, EM, XX },
01163   { "pavgw",        MX, EM, XX },
01164   { "pmulhuw",      MX, EM, XX },
01165   { "pmulhw",       MX, EM, XX },
01166   { PREGRP15 },
01167   { PREGRP25 },
01168   /* e8 */
01169   { "psubsb",       MX, EM, XX },
01170   { "psubsw",       MX, EM, XX },
01171   { "pminsw",       MX, EM, XX },
01172   { "por",      MX, EM, XX },
01173   { "paddsb",       MX, EM, XX },
01174   { "paddsw",       MX, EM, XX },
01175   { "pmaxsw",       MX, EM, XX },
01176   { "pxor",     MX, EM, XX },
01177   /* f0 */
01178   { "(bad)",        XX, XX, XX },
01179   { "psllw",        MX, EM, XX },
01180   { "pslld",        MX, EM, XX },
01181   { "psllq",        MX, EM, XX },
01182   { "pmuludq",      MX, EM, XX },
01183   { "pmaddwd",      MX, EM, XX },
01184   { "psadbw",       MX, EM, XX },
01185   { PREGRP18 },
01186   /* f8 */
01187   { "psubb",        MX, EM, XX },
01188   { "psubw",        MX, EM, XX },
01189   { "psubd",        MX, EM, XX },
01190   { "psubq",        MX, EM, XX },
01191   { "paddb",        MX, EM, XX },
01192   { "paddw",        MX, EM, XX },
01193   { "paddd",        MX, EM, XX },
01194   { "(bad)",        XX, XX, XX }
01195 };
01196 
01197 static const unsigned char onebyte_has_modrm[256] = {
01198   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01199   /*       -------------------------------        */
01200   /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
01201   /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
01202   /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
01203   /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
01204   /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
01205   /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
01206   /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
01207   /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
01208   /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
01209   /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
01210   /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
01211   /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
01212   /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
01213   /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
01214   /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
01215   /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
01216   /*       -------------------------------        */
01217   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01218 };
01219 
01220 static const unsigned char twobyte_has_modrm[256] = {
01221   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01222   /*       -------------------------------        */
01223   /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
01224   /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
01225   /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
01226   /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
01227   /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
01228   /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
01229   /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
01230   /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
01231   /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
01232   /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
01233   /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
01234   /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
01235   /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
01236   /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
01237   /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
01238   /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
01239   /*       -------------------------------        */
01240   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01241 };
01242 
01243 static const unsigned char twobyte_uses_SSE_prefix[256] = {
01244   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01245   /*       -------------------------------        */
01246   /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
01247   /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
01248   /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
01249   /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
01250   /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
01251   /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
01252   /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
01253   /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
01254   /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
01255   /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
01256   /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
01257   /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
01258   /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
01259   /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
01260   /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
01261   /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
01262   /*       -------------------------------        */
01263   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
01264 };
01265 
01266 static char obuf[100];
01267 static char *obufp;
01268 static char scratchbuf[100];
01269 static unsigned char *start_codep;
01270 static unsigned char *insn_codep;
01271 static unsigned char *codep;
01272 static disassemble_info *the_info;
01273 static int mod;
01274 static int rm;
01275 static int reg;
01276 static unsigned char need_modrm;
01277 
01278 /* If we are accessing mod/rm/reg without need_modrm set, then the
01279    values are stale.  Hitting this abort likely indicates that you
01280    need to update onebyte_has_modrm or twobyte_has_modrm.  */
01281 #define MODRM_CHECK  if (!need_modrm) abort ()
01282 
01283 static const char **names64;
01284 static const char **names32;
01285 static const char **names16;
01286 static const char **names8;
01287 static const char **names8rex;
01288 static const char **names_seg;
01289 static const char **index16;
01290 
01291 static const char *intel_names64[] = {
01292   "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
01293   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
01294 };
01295 static const char *intel_names32[] = {
01296   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
01297   "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
01298 };
01299 static const char *intel_names16[] = {
01300   "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
01301   "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
01302 };
01303 static const char *intel_names8[] = {
01304   "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
01305 };
01306 static const char *intel_names8rex[] = {
01307   "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
01308   "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
01309 };
01310 static const char *intel_names_seg[] = {
01311   "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
01312 };
01313 static const char *intel_index16[] = {
01314   "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
01315 };
01316 
01317 static const char *att_names64[] = {
01318   "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
01319   "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
01320 };
01321 static const char *att_names32[] = {
01322   "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
01323   "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
01324 };
01325 static const char *att_names16[] = {
01326   "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
01327   "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
01328 };
01329 static const char *att_names8[] = {
01330   "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
01331 };
01332 static const char *att_names8rex[] = {
01333   "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
01334   "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
01335 };
01336 static const char *att_names_seg[] = {
01337   "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
01338 };
01339 static const char *att_index16[] = {
01340   "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
01341 };
01342 
01343 static const struct dis386 grps[][8] = {
01344   /* GRP1b */
01345   {
01346     { "addA",   Eb, Ib, XX },
01347     { "orA",    Eb, Ib, XX },
01348     { "adcA",   Eb, Ib, XX },
01349     { "sbbA",   Eb, Ib, XX },
01350     { "andA",   Eb, Ib, XX },
01351     { "subA",   Eb, Ib, XX },
01352     { "xorA",   Eb, Ib, XX },
01353     { "cmpA",   Eb, Ib, XX }
01354   },
01355   /* GRP1S */
01356   {
01357     { "addQ",   Ev, Iv, XX },
01358     { "orQ",    Ev, Iv, XX },
01359     { "adcQ",   Ev, Iv, XX },
01360     { "sbbQ",   Ev, Iv, XX },
01361     { "andQ",   Ev, Iv, XX },
01362     { "subQ",   Ev, Iv, XX },
01363     { "xorQ",   Ev, Iv, XX },
01364     { "cmpQ",   Ev, Iv, XX }
01365   },
01366   /* GRP1Ss */
01367   {
01368     { "addQ",   Ev, sIb, XX },
01369     { "orQ",    Ev, sIb, XX },
01370     { "adcQ",   Ev, sIb, XX },
01371     { "sbbQ",   Ev, sIb, XX },
01372     { "andQ",   Ev, sIb, XX },
01373     { "subQ",   Ev, sIb, XX },
01374     { "xorQ",   Ev, sIb, XX },
01375     { "cmpQ",   Ev, sIb, XX }
01376   },
01377   /* GRP2b */
01378   {
01379     { "rolA",   Eb, Ib, XX },
01380     { "rorA",   Eb, Ib, XX },
01381     { "rclA",   Eb, Ib, XX },
01382     { "rcrA",   Eb, Ib, XX },
01383     { "shlA",   Eb, Ib, XX },
01384     { "shrA",   Eb, Ib, XX },
01385     { "(bad)",  XX, XX, XX },
01386     { "sarA",   Eb, Ib, XX },
01387   },
01388   /* GRP2S */
01389   {
01390     { "rolQ",   Ev, Ib, XX },
01391     { "rorQ",   Ev, Ib, XX },
01392     { "rclQ",   Ev, Ib, XX },
01393     { "rcrQ",   Ev, Ib, XX },
01394     { "shlQ",   Ev, Ib, XX },
01395     { "shrQ",   Ev, Ib, XX },
01396     { "(bad)",  XX, XX, XX },
01397     { "sarQ",   Ev, Ib, XX },
01398   },
01399   /* GRP2b_one */
01400   {
01401     { "rolA",   Eb, XX, XX },
01402     { "rorA",   Eb, XX, XX },
01403     { "rclA",   Eb, XX, XX },
01404     { "rcrA",   Eb, XX, XX },
01405     { "shlA",   Eb, XX, XX },
01406     { "shrA",   Eb, XX, XX },
01407     { "(bad)",  XX, XX, XX },
01408     { "sarA",   Eb, XX, XX },
01409   },
01410   /* GRP2S_one */
01411   {
01412     { "rolQ",   Ev, XX, XX },
01413     { "rorQ",   Ev, XX, XX },
01414     { "rclQ",   Ev, XX, XX },
01415     { "rcrQ",   Ev, XX, XX },
01416     { "shlQ",   Ev, XX, XX },
01417     { "shrQ",   Ev, XX, XX },
01418     { "(bad)",  XX, XX, XX},
01419     { "sarQ",   Ev, XX, XX },
01420   },
01421   /* GRP2b_cl */
01422   {
01423     { "rolA",   Eb, CL, XX },
01424     { "rorA",   Eb, CL, XX },
01425     { "rclA",   Eb, CL, XX },
01426     { "rcrA",   Eb, CL, XX },
01427     { "shlA",   Eb, CL, XX },
01428     { "shrA",   Eb, CL, XX },
01429     { "(bad)",  XX, XX, XX },
01430     { "sarA",   Eb, CL, XX },
01431   },
01432   /* GRP2S_cl */
01433   {
01434     { "rolQ",   Ev, CL, XX },
01435     { "rorQ",   Ev, CL, XX },
01436     { "rclQ",   Ev, CL, XX },
01437     { "rcrQ",   Ev, CL, XX },
01438     { "shlQ",   Ev, CL, XX },
01439     { "shrQ",   Ev, CL, XX },
01440     { "(bad)",  XX, XX, XX },
01441     { "sarQ",   Ev, CL, XX }
01442   },
01443   /* GRP3b */
01444   {
01445     { "testA",  Eb, Ib, XX },
01446     { "(bad)",  Eb, XX, XX },
01447     { "notA",   Eb, XX, XX },
01448     { "negA",   Eb, XX, XX },
01449     { "mulA",   Eb, XX, XX },   /* Don't print the implicit %al register,  */
01450     { "imulA",  Eb, XX, XX },   /* to distinguish these opcodes from other */
01451     { "divA",   Eb, XX, XX },   /* mul/imul opcodes.  Do the same for div  */
01452     { "idivA",  Eb, XX, XX }    /* and idiv for consistency.           */
01453   },
01454   /* GRP3S */
01455   {
01456     { "testQ",  Ev, Iv, XX },
01457     { "(bad)",  XX, XX, XX },
01458     { "notQ",   Ev, XX, XX },
01459     { "negQ",   Ev, XX, XX },
01460     { "mulQ",   Ev, XX, XX },   /* Don't print the implicit register.  */
01461     { "imulQ",  Ev, XX, XX },
01462     { "divQ",   Ev, XX, XX },
01463     { "idivQ",  Ev, XX, XX },
01464   },
01465   /* GRP4 */
01466   {
01467     { "incA",   Eb, XX, XX },
01468     { "decA",   Eb, XX, XX },
01469     { "(bad)",  XX, XX, XX },
01470     { "(bad)",  XX, XX, XX },
01471     { "(bad)",  XX, XX, XX },
01472     { "(bad)",  XX, XX, XX },
01473     { "(bad)",  XX, XX, XX },
01474     { "(bad)",  XX, XX, XX },
01475   },
01476   /* GRP5 */
01477   {
01478     { "incQ",   Ev, XX, XX },
01479     { "decQ",   Ev, XX, XX },
01480     { "callT",  indirEv, XX, XX },
01481     { "lcallT", indirEv, XX, XX },
01482     { "jmpT",   indirEv, XX, XX },
01483     { "ljmpT",  indirEv, XX, XX },
01484     { "pushU",  Ev, XX, XX },
01485     { "(bad)",  XX, XX, XX },
01486   },
01487   /* GRP6 */
01488   {
01489     { "sldtQ",  Ev, XX, XX },
01490     { "strQ",   Ev, XX, XX },
01491     { "lldt",   Ew, XX, XX },
01492     { "ltr",    Ew, XX, XX },
01493     { "verr",   Ew, XX, XX },
01494     { "verw",   Ew, XX, XX },
01495     { "(bad)",  XX, XX, XX },
01496     { "(bad)",  XX, XX, XX }
01497   },
01498   /* GRP7 */
01499   {
01500     { "sgdtQ",   M, XX, XX },
01501     { "sidtQ",   M, XX, XX },
01502     { "lgdtQ",   M, XX, XX },
01503     { "lidtQ",   M, XX, XX },
01504     { "smswQ",  Ev, XX, XX },
01505     { "(bad)",  XX, XX, XX },
01506     { "lmsw",   Ew, XX, XX },
01507     { "invlpg", Ew, XX, XX },
01508   },
01509   /* GRP8 */
01510   {
01511     { "(bad)",  XX, XX, XX },
01512     { "(bad)",  XX, XX, XX },
01513     { "(bad)",  XX, XX, XX },
01514     { "(bad)",  XX, XX, XX },
01515     { "btQ",    Ev, Ib, XX },
01516     { "btsQ",   Ev, Ib, XX },
01517     { "btrQ",   Ev, Ib, XX },
01518     { "btcQ",   Ev, Ib, XX },
01519   },
01520   /* GRP9 */
01521   {
01522     { "(bad)",  XX, XX, XX },
01523     { "cmpxchg8b", Ev, XX, XX },
01524     { "(bad)",  XX, XX, XX },
01525     { "(bad)",  XX, XX, XX },
01526     { "(bad)",  XX, XX, XX },
01527     { "(bad)",  XX, XX, XX },
01528     { "(bad)",  XX, XX, XX },
01529     { "(bad)",  XX, XX, XX },
01530   },
01531   /* GRP10 */
01532   {
01533     { "(bad)",  XX, XX, XX },
01534     { "(bad)",  XX, XX, XX },
01535     { "psrlw",  MS, Ib, XX },
01536     { "(bad)",  XX, XX, XX },
01537     { "psraw",  MS, Ib, XX },
01538     { "(bad)",  XX, XX, XX },
01539     { "psllw",  MS, Ib, XX },
01540     { "(bad)",  XX, XX, XX },
01541   },
01542   /* GRP11 */
01543   {
01544     { "(bad)",  XX, XX, XX },
01545     { "(bad)",  XX, XX, XX },
01546     { "psrld",  MS, Ib, XX },
01547     { "(bad)",  XX, XX, XX },
01548     { "psrad",  MS, Ib, XX },
01549     { "(bad)",  XX, XX, XX },
01550     { "pslld",  MS, Ib, XX },
01551     { "(bad)",  XX, XX, XX },
01552   },
01553   /* GRP12 */
01554   {
01555     { "(bad)",  XX, XX, XX },
01556     { "(bad)",  XX, XX, XX },
01557     { "psrlq",  MS, Ib, XX },
01558     { "psrldq", MS, Ib, XX },
01559     { "(bad)",  XX, XX, XX },
01560     { "(bad)",  XX, XX, XX },
01561     { "psllq",  MS, Ib, XX },
01562     { "pslldq", MS, Ib, XX },
01563   },
01564   /* GRP13 */
01565   {
01566     { "fxsave", Ev, XX, XX },
01567     { "fxrstor", Ev, XX, XX },
01568     { "ldmxcsr", Ev, XX, XX },
01569     { "stmxcsr", Ev, XX, XX },
01570     { "(bad)",  XX, XX, XX },
01571     { "lfence", None, XX, XX },
01572     { "mfence", None, XX, XX },
01573     { "sfence", None, XX, XX },
01574     /* FIXME: the sfence with memory operand is clflush!  */
01575   },
01576   /* GRP14 */
01577   {
01578     { "prefetchnta", Ev, XX, XX },
01579     { "prefetcht0", Ev, XX, XX },
01580     { "prefetcht1", Ev, XX, XX },
01581     { "prefetcht2", Ev, XX, XX },
01582     { "(bad)",  XX, XX, XX },
01583     { "(bad)",  XX, XX, XX },
01584     { "(bad)",  XX, XX, XX },
01585     { "(bad)",  XX, XX, XX },
01586   },
01587   /* GRPAMD */
01588   {
01589     { "prefetch", Eb, XX, XX },
01590     { "prefetchw", Eb, XX, XX },
01591     { "(bad)",  XX, XX, XX },
01592     { "(bad)",  XX, XX, XX },
01593     { "(bad)",  XX, XX, XX },
01594     { "(bad)",  XX, XX, XX },
01595     { "(bad)",  XX, XX, XX },
01596     { "(bad)",  XX, XX, XX },
01597   }
01598 };
01599 
01600 static const struct dis386 prefix_user_table[][4] = {
01601   /* PREGRP0 */
01602   {
01603     { "addps", XM, EX, XX },
01604     { "addss", XM, EX, XX },
01605     { "addpd", XM, EX, XX },
01606     { "addsd", XM, EX, XX },
01607   },
01608   /* PREGRP1 */
01609   {
01610     { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX.  */
01611     { "", XM, EX, OPSIMD },
01612     { "", XM, EX, OPSIMD },
01613     { "", XM, EX, OPSIMD },
01614   },
01615   /* PREGRP2 */
01616   {
01617     { "cvtpi2ps", XM, EM, XX },
01618     { "cvtsi2ssY", XM, Ev, XX },
01619     { "cvtpi2pd", XM, EM, XX },
01620     { "cvtsi2sdY", XM, Ev, XX },
01621   },
01622   /* PREGRP3 */
01623   {
01624     { "cvtps2pi", MX, EX, XX },
01625     { "cvtss2siY", Gv, EX, XX },
01626     { "cvtpd2pi", MX, EX, XX },
01627     { "cvtsd2siY", Gv, EX, XX },
01628   },
01629   /* PREGRP4 */
01630   {
01631     { "cvttps2pi", MX, EX, XX },
01632     { "cvttss2siY", Gv, EX, XX },
01633     { "cvttpd2pi", MX, EX, XX },
01634     { "cvttsd2siY", Gv, EX, XX },
01635   },
01636   /* PREGRP5 */
01637   {
01638     { "divps", XM, EX, XX },
01639     { "divss", XM, EX, XX },
01640     { "divpd", XM, EX, XX },
01641     { "divsd", XM, EX, XX },
01642   },
01643   /* PREGRP6 */
01644   {
01645     { "maxps", XM, EX, XX },
01646     { "maxss", XM, EX, XX },
01647     { "maxpd", XM, EX, XX },
01648     { "maxsd", XM, EX, XX },
01649   },
01650   /* PREGRP7 */
01651   {
01652     { "minps", XM, EX, XX },
01653     { "minss", XM, EX, XX },
01654     { "minpd", XM, EX, XX },
01655     { "minsd", XM, EX, XX },
01656   },
01657   /* PREGRP8 */
01658   {
01659     { "movups", XM, EX, XX },
01660     { "movss", XM, EX, XX },
01661     { "movupd", XM, EX, XX },
01662     { "movsd", XM, EX, XX },
01663   },
01664   /* PREGRP9 */
01665   {
01666     { "movups", EX, XM, XX },
01667     { "movss", EX, XM, XX },
01668     { "movupd", EX, XM, XX },
01669     { "movsd", EX, XM, XX },
01670   },
01671   /* PREGRP10 */
01672   {
01673     { "mulps", XM, EX, XX },
01674     { "mulss", XM, EX, XX },
01675     { "mulpd", XM, EX, XX },
01676     { "mulsd", XM, EX, XX },
01677   },
01678   /* PREGRP11 */
01679   {
01680     { "rcpps", XM, EX, XX },
01681     { "rcpss", XM, EX, XX },
01682     { "(bad)", XM, EX, XX },
01683     { "(bad)", XM, EX, XX },
01684   },
01685   /* PREGRP12 */
01686   {
01687     { "rsqrtps", XM, EX, XX },
01688     { "rsqrtss", XM, EX, XX },
01689     { "(bad)", XM, EX, XX },
01690     { "(bad)", XM, EX, XX },
01691   },
01692   /* PREGRP13 */
01693   {
01694     { "sqrtps", XM, EX, XX },
01695     { "sqrtss", XM, EX, XX },
01696     { "sqrtpd", XM, EX, XX },
01697     { "sqrtsd", XM, EX, XX },
01698   },
01699   /* PREGRP14 */
01700   {
01701     { "subps", XM, EX, XX },
01702     { "subss", XM, EX, XX },
01703     { "subpd", XM, EX, XX },
01704     { "subsd", XM, EX, XX },
01705   },
01706   /* PREGRP15 */
01707   {
01708     { "(bad)", XM, EX, XX },
01709     { "cvtdq2pd", XM, EX, XX },
01710     { "cvttpd2dq", XM, EX, XX },
01711     { "cvtpd2dq", XM, EX, XX },
01712   },
01713   /* PREGRP16 */
01714   {
01715     { "cvtdq2ps", XM, EX, XX },
01716     { "cvttps2dq",XM, EX, XX },
01717     { "cvtps2dq",XM, EX, XX },
01718     { "(bad)", XM, EX, XX },
01719   },
01720   /* PREGRP17 */
01721   {
01722     { "cvtps2pd", XM, EX, XX },
01723     { "cvtss2sd", XM, EX, XX },
01724     { "cvtpd2ps", XM, EX, XX },
01725     { "cvtsd2ss", XM, EX, XX },
01726   },
01727   /* PREGRP18 */
01728   {
01729     { "maskmovq", MX, MS, XX },
01730     { "(bad)", XM, EX, XX },
01731     { "maskmovdqu", XM, EX, XX },
01732     { "(bad)", XM, EX, XX },
01733   },
01734   /* PREGRP19 */
01735   {
01736     { "movq", MX, EM, XX },
01737     { "movdqu", XM, EX, XX },
01738     { "movdqa", XM, EX, XX },
01739     { "(bad)", XM, EX, XX },
01740   },
01741   /* PREGRP20 */
01742   {
01743     { "movq", EM, MX, XX },
01744     { "movdqu", EX, XM, XX },
01745     { "movdqa", EX, XM, XX },
01746     { "(bad)", EX, XM, XX },
01747   },
01748   /* PREGRP21 */
01749   {
01750     { "(bad)", EX, XM, XX },
01751     { "movq2dq", XM, MS, XX },
01752     { "movq", EX, XM, XX },
01753     { "movdq2q", MX, XS, XX },
01754   },
01755   /* PREGRP22 */
01756   {
01757     { "pshufw", MX, EM, Ib },
01758     { "pshufhw", XM, EX, Ib },
01759     { "pshufd", XM, EX, Ib },
01760     { "pshuflw", XM, EX, Ib },
01761   },
01762   /* PREGRP23 */
01763   {
01764     { "movd", Ed, MX, XX },
01765     { "movq", XM, EX, XX },
01766     { "movd", Ed, XM, XX },
01767     { "(bad)", Ed, XM, XX },
01768   },
01769   /* PREGRP24 */
01770   {
01771     { "(bad)", MX, EX, XX },
01772     { "(bad)", XM, EX, XX },
01773     { "punpckhqdq", XM, EX, XX },
01774     { "(bad)", XM, EX, XX },
01775   },
01776   /* PREGRP25 */
01777   {
01778   { "movntq", Ev, MX, XX },
01779   { "(bad)", Ev, XM, XX },
01780   { "movntdq", Ev, XM, XX },
01781   { "(bad)", Ev, XM, XX },
01782   },
01783   /* PREGRP26 */
01784   {
01785     { "(bad)", MX, EX, XX },
01786     { "(bad)", XM, EX, XX },
01787     { "punpcklqdq", XM, EX, XX },
01788     { "(bad)", XM, EX, XX },
01789   },
01790 };
01791 
01792 static const struct dis386 x86_64_table[][2] = {
01793   {
01794     { "arpl", Ew, Gw, XX },
01795     { "movs{||lq|xd}", Gv, Ed, XX },
01796   },
01797 };
01798 
01799 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
01800 
01801 static void
01802 ckprefix ()
01803 {
01804   int newrex;
01805   rex = 0;
01806   prefixes = 0;
01807   used_prefixes = 0;
01808   rex_used = 0;
01809   while (1)
01810     {
01811       FETCH_DATA (the_info, codep + 1);
01812       newrex = 0;
01813       switch (*codep)
01814     {
01815     /* REX prefixes family.  */
01816     case 0x40:
01817     case 0x41:
01818     case 0x42:
01819     case 0x43:
01820     case 0x44:
01821     case 0x45:
01822     case 0x46:
01823     case 0x47:
01824     case 0x48:
01825     case 0x49:
01826     case 0x4a:
01827     case 0x4b:
01828     case 0x4c:
01829     case 0x4d:
01830     case 0x4e:
01831     case 0x4f:
01832         if (mode_64bit)
01833           newrex = *codep;
01834         else
01835           return;
01836       break;
01837     case 0xf3:
01838       prefixes |= PREFIX_REPZ;
01839       break;
01840     case 0xf2:
01841       prefixes |= PREFIX_REPNZ;
01842       break;
01843     case 0xf0:
01844       prefixes |= PREFIX_LOCK;
01845       break;
01846     case 0x2e:
01847       prefixes |= PREFIX_CS;
01848       break;
01849     case 0x36:
01850       prefixes |= PREFIX_SS;
01851       break;
01852     case 0x3e:
01853       prefixes |= PREFIX_DS;
01854       break;
01855     case 0x26:
01856       prefixes |= PREFIX_ES;
01857       break;
01858     case 0x64:
01859       prefixes |= PREFIX_FS;
01860       break;
01861     case 0x65:
01862       prefixes |= PREFIX_GS;
01863       break;
01864     case 0x66:
01865       prefixes |= PREFIX_DATA;
01866       break;
01867     case 0x67:
01868       prefixes |= PREFIX_ADDR;
01869       break;
01870     case FWAIT_OPCODE:
01871       /* fwait is really an instruction.  If there are prefixes
01872          before the fwait, they belong to the fwait, *not* to the
01873          following instruction.  */
01874       if (prefixes)
01875         {
01876           prefixes |= PREFIX_FWAIT;
01877           codep++;
01878           return;
01879         }
01880       prefixes = PREFIX_FWAIT;
01881       break;
01882     default:
01883       return;
01884     }
01885       /* Rex is ignored when followed by another prefix.  */
01886       if (rex)
01887     {
01888       oappend (prefix_name (rex, 0));
01889       oappend (" ");
01890     }
01891       rex = newrex;
01892       codep++;
01893     }
01894 }
01895 
01896 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
01897    prefix byte.  */
01898 
01899 static const char *
01900 prefix_name (pref, sizeflag)
01901      int pref;
01902      int sizeflag;
01903 {
01904   switch (pref)
01905     {
01906     /* REX prefixes family.  */
01907     case 0x40:
01908       return "rex";
01909     case 0x41:
01910       return "rexZ";
01911     case 0x42:
01912       return "rexY";
01913     case 0x43:
01914       return "rexYZ";
01915     case 0x44:
01916       return "rexX";
01917     case 0x45:
01918       return "rexXZ";
01919     case 0x46:
01920       return "rexXY";
01921     case 0x47:
01922       return "rexXYZ";
01923     case 0x48:
01924       return "rex64";
01925     case 0x49:
01926       return "rex64Z";
01927     case 0x4a:
01928       return "rex64Y";
01929     case 0x4b:
01930       return "rex64YZ";
01931     case 0x4c:
01932       return "rex64X";
01933     case 0x4d:
01934       return "rex64XZ";
01935     case 0x4e:
01936       return "rex64XY";
01937     case 0x4f:
01938       return "rex64XYZ";
01939     case 0xf3:
01940       return "repz";
01941     case 0xf2:
01942       return "repnz";
01943     case 0xf0:
01944       return "lock";
01945     case 0x2e:
01946       return "cs";
01947     case 0x36:
01948       return "ss";
01949     case 0x3e:
01950       return "ds";
01951     case 0x26:
01952       return "es";
01953     case 0x64:
01954       return "fs";
01955     case 0x65:
01956       return "gs";
01957     case 0x66:
01958       return (sizeflag & DFLAG) ? "data16" : "data32";
01959     case 0x67:
01960       if (mode_64bit)
01961         return (sizeflag & AFLAG) ? "addr32" : "addr64";
01962       else
01963         return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
01964     case FWAIT_OPCODE:
01965       return "fwait";
01966     default:
01967       return NULL;
01968     }
01969 }
01970 
01971 static char op1out[100], op2out[100], op3out[100];
01972 static int op_ad, op_index[3];
01973 static bfd_vma op_address[3];
01974 static bfd_vma op_riprel[3];
01975 static bfd_vma start_pc;
01976 
01977 /*
01978  *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
01979  *   (see topic "Redundant prefixes" in the "Differences from 8086"
01980  *   section of the "Virtual 8086 Mode" chapter.)
01981  * 'pc' should be the address of this instruction, it will
01982  *   be used to print the target address if this is a relative jump or call
01983  * The function returns the length of this instruction in bytes.
01984  */
01985 
01986 static char intel_syntax;
01987 static char open_char;
01988 static char close_char;
01989 static char separator_char;
01990 static char scale_char;
01991 
01992 /* Here for backwards compatibility.  When gdb stops using
01993    print_insn_i386_att and print_insn_i386_intel these functions can
01994    disappear, and print_insn_i386 be merged into print_insn.  */
01995 int
01996 print_insn_i386_att (pc, info)
01997      bfd_vma pc;
01998      disassemble_info *info;
01999 {
02000   intel_syntax = 0;
02001 
02002   return print_insn (pc, info);
02003 }
02004 
02005 int
02006 print_insn_i386_intel (pc, info)
02007      bfd_vma pc;
02008      disassemble_info *info;
02009 {
02010   intel_syntax = 1;
02011 
02012   return print_insn (pc, info);
02013 }
02014 
02015 int
02016 print_insn_i386 (pc, info)
02017      bfd_vma pc;
02018      disassemble_info *info;
02019 {
02020   intel_syntax = -1;
02021 
02022   return print_insn (pc, info);
02023 }
02024 
02025 static int
02026 print_insn (pc, info)
02027      bfd_vma pc;
02028      disassemble_info *info;
02029 {
02030   const struct dis386 *dp;
02031   int i;
02032   int two_source_ops;
02033   char *first, *second, *third;
02034   int needcomma;
02035   unsigned char uses_SSE_prefix;
02036   int sizeflag;
02037   /*const char *p;*/
02038   struct dis_private priv;
02039 
02040   mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
02041         || info->mach == bfd_mach_x86_64);
02042 
02043   if (intel_syntax == -1)
02044     intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
02045             || info->mach == bfd_mach_x86_64_intel_syntax);
02046 
02047   if (info->mach == bfd_mach_i386_i386
02048       || info->mach == bfd_mach_x86_64
02049       || info->mach == bfd_mach_i386_i386_intel_syntax
02050       || info->mach == bfd_mach_x86_64_intel_syntax)
02051     priv.orig_sizeflag = AFLAG | DFLAG;
02052   else if (info->mach == bfd_mach_i386_i8086)
02053     priv.orig_sizeflag = 0;
02054   else
02055     abort ();
02056 
02057 #if 0
02058   for (p = info->disassembler_options; p != NULL; )
02059     {
02060       if (strncmp (p, "x86-64", 6) == 0)
02061     {
02062       mode_64bit = 1;
02063       priv.orig_sizeflag = AFLAG | DFLAG;
02064     }
02065       else if (strncmp (p, "i386", 4) == 0)
02066     {
02067       mode_64bit = 0;
02068       priv.orig_sizeflag = AFLAG | DFLAG;
02069     }
02070       else if (strncmp (p, "i8086", 5) == 0)
02071     {
02072       mode_64bit = 0;
02073       priv.orig_sizeflag = 0;
02074     }
02075       else if (strncmp (p, "intel", 5) == 0)
02076     {
02077       intel_syntax = 1;
02078     }
02079       else if (strncmp (p, "att", 3) == 0)
02080     {
02081       intel_syntax = 0;
02082     }
02083       else if (strncmp (p, "addr", 4) == 0)
02084     {
02085       if (p[4] == '1' && p[5] == '6')
02086         priv.orig_sizeflag &= ~AFLAG;
02087       else if (p[4] == '3' && p[5] == '2')
02088         priv.orig_sizeflag |= AFLAG;
02089     }
02090       else if (strncmp (p, "data", 4) == 0)
02091     {
02092       if (p[4] == '1' && p[5] == '6')
02093         priv.orig_sizeflag &= ~DFLAG;
02094       else if (p[4] == '3' && p[5] == '2')
02095         priv.orig_sizeflag |= DFLAG;
02096     }
02097       else if (strncmp (p, "suffix", 6) == 0)
02098     priv.orig_sizeflag |= SUFFIX_ALWAYS;
02099 
02100       p = strchr (p, ',');
02101       if (p != NULL)
02102     p++;
02103     }
02104 #else
02105   mode_64bit = 1;
02106   priv.orig_sizeflag = AFLAG | DFLAG;
02107   intel_syntax = 1;
02108 #endif
02109 
02110   if (intel_syntax)
02111     {
02112       names64 = intel_names64;
02113       names32 = intel_names32;
02114       names16 = intel_names16;
02115       names8 = intel_names8;
02116       names8rex = intel_names8rex;
02117       names_seg = intel_names_seg;
02118       index16 = intel_index16;
02119       open_char = '[';
02120       close_char = ']';
02121       separator_char = '+';
02122       scale_char = '*';
02123     }
02124   else
02125     {
02126       names64 = att_names64;
02127       names32 = att_names32;
02128       names16 = att_names16;
02129       names8 = att_names8;
02130       names8rex = att_names8rex;
02131       names_seg = att_names_seg;
02132       index16 = att_index16;
02133       open_char = '(';
02134       close_char =  ')';
02135       separator_char = ',';
02136       scale_char = ',';
02137     }
02138 
02139   /* The output looks better if we put 7 bytes on a line, since that
02140      puts most long word instructions on a single line.  */
02141   info->bytes_per_line = 7;
02142 
02143   info->private_data = (PTR) &priv;
02144   priv.max_fetched = priv.the_buffer;
02145   priv.insn_start = pc;
02146 
02147   obuf[0] = 0;
02148   op1out[0] = 0;
02149   op2out[0] = 0;
02150   op3out[0] = 0;
02151 
02152   op_index[0] = op_index[1] = op_index[2] = -1;
02153 
02154   the_info = info;
02155   start_pc = pc;
02156   start_codep = priv.the_buffer;
02157   codep = priv.the_buffer;
02158 
02159   if (_setjmp (priv.bailout) != 0)
02160     {
02161       const char *name;
02162 
02163       /* Getting here means we tried for data but didn't get it.  That
02164      means we have an incomplete instruction of some sort.  Just
02165      print the first byte as a prefix or a .byte pseudo-op.  */
02166       if (codep > priv.the_buffer)
02167     {
02168       name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
02169       if (name != NULL)
02170         (*info->fprintf_func) (info->stream, "%s", name);
02171       else
02172         {
02173           /* Just print the first byte as a .byte instruction.  */
02174           (*info->fprintf_func) (info->stream, ".byte 0x%x",
02175                      (unsigned int) priv.the_buffer[0]);
02176         }
02177 
02178       return 1;
02179     }
02180 
02181       return -1;
02182     }
02183 
02184   obufp = obuf;
02185   ckprefix ();
02186 
02187   insn_codep = codep;
02188   sizeflag = priv.orig_sizeflag;
02189 
02190   FETCH_DATA (info, codep + 1);
02191   two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
02192 
02193   if ((prefixes & PREFIX_FWAIT)
02194       && ((*codep < 0xd8) || (*codep > 0xdf)))
02195     {
02196       const char *name;
02197 
02198       /* fwait not followed by floating point instruction.  Print the
02199          first prefix, which is probably fwait itself.  */
02200       name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
02201       if (name == NULL)
02202     name = INTERNAL_DISASSEMBLER_ERROR;
02203       (*info->fprintf_func) (info->stream, "%s", name);
02204       return 1;
02205     }
02206 
02207   if (*codep == 0x0f)
02208     {
02209       FETCH_DATA (info, codep + 2);
02210       dp = &dis386_twobyte[*++codep];
02211       need_modrm = twobyte_has_modrm[*codep];
02212       uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
02213     }
02214   else
02215     {
02216       dp = &dis386[*codep];
02217       need_modrm = onebyte_has_modrm[*codep];
02218       uses_SSE_prefix = 0;
02219     }
02220   codep++;
02221 
02222   if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
02223     {
02224       oappend ("repz ");
02225       used_prefixes |= PREFIX_REPZ;
02226     }
02227   if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
02228     {
02229       oappend ("repnz ");
02230       used_prefixes |= PREFIX_REPNZ;
02231     }
02232   if (prefixes & PREFIX_LOCK)
02233     {
02234       oappend ("lock ");
02235       used_prefixes |= PREFIX_LOCK;
02236     }
02237 
02238   if (prefixes & PREFIX_ADDR)
02239     {
02240       sizeflag ^= AFLAG;
02241       if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
02242     {
02243       if ((sizeflag & AFLAG) || mode_64bit)
02244         oappend ("addr32 ");
02245       else
02246         oappend ("addr16 ");
02247       used_prefixes |= PREFIX_ADDR;
02248     }
02249     }
02250 
02251   if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
02252     {
02253       sizeflag ^= DFLAG;
02254       if (dp->bytemode3 == cond_jump_mode
02255       && dp->bytemode1 == v_mode
02256       && !intel_syntax)
02257     {
02258       if (sizeflag & DFLAG)
02259         oappend ("data32 ");
02260       else
02261         oappend ("data16 ");
02262       used_prefixes |= PREFIX_DATA;
02263     }
02264     }
02265 
02266   if (need_modrm)
02267     {
02268       FETCH_DATA (info, codep + 1);
02269       mod = (*codep >> 6) & 3;
02270       reg = (*codep >> 3) & 7;
02271       rm = *codep & 7;
02272     }
02273 
02274   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
02275     {
02276       dofloat (sizeflag);
02277     }
02278   else
02279     {
02280       int index;
02281       if (dp->name == NULL)
02282     {
02283       switch (dp->bytemode1)
02284         {
02285         case USE_GROUPS:
02286           dp = &grps[dp->bytemode2][reg];
02287           break;
02288 
02289         case USE_PREFIX_USER_TABLE:
02290           index = 0;
02291           used_prefixes |= (prefixes & PREFIX_REPZ);
02292           if (prefixes & PREFIX_REPZ)
02293         index = 1;
02294           else
02295         {
02296           used_prefixes |= (prefixes & PREFIX_DATA);
02297           if (prefixes & PREFIX_DATA)
02298             index = 2;
02299           else
02300             {
02301               used_prefixes |= (prefixes & PREFIX_REPNZ);
02302               if (prefixes & PREFIX_REPNZ)
02303             index = 3;
02304             }
02305         }
02306           dp = &prefix_user_table[dp->bytemode2][index];
02307           break;
02308 
02309         case X86_64_SPECIAL:
02310           dp = &x86_64_table[dp->bytemode2][mode_64bit];
02311           break;
02312 
02313         default:
02314           oappend (INTERNAL_DISASSEMBLER_ERROR);
02315           break;
02316         }
02317     }
02318 
02319       if (putop (dp->name, sizeflag) == 0)
02320     {
02321       obufp = op1out;
02322       op_ad = 2;
02323       if (dp->op1)
02324         (*dp->op1) (dp->bytemode1, sizeflag);
02325 
02326       obufp = op2out;
02327       op_ad = 1;
02328       if (dp->op2)
02329         (*dp->op2) (dp->bytemode2, sizeflag);
02330 
02331       obufp = op3out;
02332       op_ad = 0;
02333       if (dp->op3)
02334         (*dp->op3) (dp->bytemode3, sizeflag);
02335     }
02336     }
02337 
02338   /* See if any prefixes were not used.  If so, print the first one
02339      separately.  If we don't do this, we'll wind up printing an
02340      instruction stream which does not precisely correspond to the
02341      bytes we are disassembling.  */
02342   if ((prefixes & ~used_prefixes) != 0)
02343     {
02344       const char *name;
02345 
02346       name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
02347       if (name == NULL)
02348     name = INTERNAL_DISASSEMBLER_ERROR;
02349       (*info->fprintf_func) (info->stream, "%s", name);
02350       return 1;
02351     }
02352   if (rex & ~rex_used)
02353     {
02354       const char *name;
02355       name = prefix_name (rex | 0x40, priv.orig_sizeflag);
02356       if (name == NULL)
02357     name = INTERNAL_DISASSEMBLER_ERROR;
02358       (*info->fprintf_func) (info->stream, "%s ", name);
02359     }
02360 
02361   obufp = obuf + strlen (obuf);
02362   for (i = strlen (obuf); i < 6; i++)
02363     oappend (" ");
02364   oappend (" ");
02365   (*info->fprintf_func) (info->stream, "%s", obuf);
02366 
02367   /* The enter and bound instructions are printed with operands in the same
02368      order as the intel book; everything else is printed in reverse order.  */
02369   if (intel_syntax || two_source_ops)
02370     {
02371       first = op1out;
02372       second = op2out;
02373       third = op3out;
02374       op_ad = op_index[0];
02375       op_index[0] = op_index[2];
02376       op_index[2] = op_ad;
02377     }
02378   else
02379     {
02380       first = op3out;
02381       second = op2out;
02382       third = op1out;
02383     }
02384   needcomma = 0;
02385   if (*first)
02386     {
02387       if (op_index[0] != -1 && !op_riprel[0])
02388     (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
02389       else
02390     (*info->fprintf_func) (info->stream, "%s", first);
02391       needcomma = 1;
02392     }
02393   if (*second)
02394     {
02395       if (needcomma)
02396     (*info->fprintf_func) (info->stream, ",");
02397       if (op_index[1] != -1 && !op_riprel[1])
02398     (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
02399       else
02400     (*info->fprintf_func) (info->stream, "%s", second);
02401       needcomma = 1;
02402     }
02403   if (*third)
02404     {
02405       if (needcomma)
02406     (*info->fprintf_func) (info->stream, ",");
02407       if (op_index[2] != -1 && !op_riprel[2])
02408     (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
02409       else
02410     (*info->fprintf_func) (info->stream, "%s", third);
02411     }
02412   for (i = 0; i < 3; i++)
02413     if (op_index[i] != -1 && op_riprel[i])
02414       {
02415     (*info->fprintf_func) (info->stream, "        # ");
02416     (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
02417                         + op_address[op_index[i]]), info);
02418       }
02419   return codep - priv.the_buffer;
02420 }
02421 
02422 static const char *float_mem[] = {
02423   /* d8 */
02424   "fadd{s||s|}",
02425   "fmul{s||s|}",
02426   "fcom{s||s|}",
02427   "fcomp{s||s|}",
02428   "fsub{s||s|}",
02429   "fsubr{s||s|}",
02430   "fdiv{s||s|}",
02431   "fdivr{s||s|}",
02432   /*  d9 */
02433   "fld{s||s|}",
02434   "(bad)",
02435   "fst{s||s|}",
02436   "fstp{s||s|}",
02437   "fldenv",
02438   "fldcw",
02439   "fNstenv",
02440   "fNstcw",
02441   /* da */
02442   "fiadd{l||l|}",
02443   "fimul{l||l|}",
02444   "ficom{l||l|}",
02445   "ficomp{l||l|}",
02446   "fisub{l||l|}",
02447   "fisubr{l||l|}",
02448   "fidiv{l||l|}",
02449   "fidivr{l||l|}",
02450   /* db */
02451   "fild{l||l|}",
02452   "(bad)",
02453   "fist{l||l|}",
02454   "fistp{l||l|}",
02455   "(bad)",
02456   "fld{t||t|}",
02457   "(bad)",
02458   "fstp{t||t|}",
02459   /* dc */
02460   "fadd{l||l|}",
02461   "fmul{l||l|}",
02462   "fcom{l||l|}",
02463   "fcomp{l||l|}",
02464   "fsub{l||l|}",
02465   "fsubr{l||l|}",
02466   "fdiv{l||l|}",
02467   "fdivr{l||l|}",
02468   /* dd */
02469   "fld{l||l|}",
02470   "(bad)",
02471   "fst{l||l|}",
02472   "fstp{l||l|}",
02473   "frstor",
02474   "(bad)",
02475   "fNsave",
02476   "fNstsw",
02477   /* de */
02478   "fiadd",
02479   "fimul",
02480   "ficom",
02481   "ficomp",
02482   "fisub",
02483   "fisubr",
02484   "fidiv",
02485   "fidivr",
02486   /* df */
02487   "fild",
02488   "(bad)",
02489   "fist",
02490   "fistp",
02491   "fbld",
02492   "fild{ll||ll|}",
02493   "fbstp",
02494   "fistpll",
02495 };
02496 
02497 #define ST OP_ST, 0
02498 #define STi OP_STi, 0
02499 
02500 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
02501 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
02502 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
02503 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
02504 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
02505 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
02506 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
02507 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
02508 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
02509 
02510 static const struct dis386 float_reg[][8] = {
02511   /* d8 */
02512   {
02513     { "fadd",   ST, STi, XX },
02514     { "fmul",   ST, STi, XX },
02515     { "fcom",   STi, XX, XX },
02516     { "fcomp",  STi, XX, XX },
02517     { "fsub",   ST, STi, XX },
02518     { "fsubr",  ST, STi, XX },
02519     { "fdiv",   ST, STi, XX },
02520     { "fdivr",  ST, STi, XX },
02521   },
02522   /* d9 */
02523   {
02524     { "fld",    STi, XX, XX },
02525     { "fxch",   STi, XX, XX },
02526     { FGRPd9_2 },
02527     { "(bad)",  XX, XX, XX },
02528     { FGRPd9_4 },
02529     { FGRPd9_5 },
02530     { FGRPd9_6 },
02531     { FGRPd9_7 },
02532   },
02533   /* da */
02534   {
02535     { "fcmovb", ST, STi, XX },
02536     { "fcmove", ST, STi, XX },
02537     { "fcmovbe",ST, STi, XX },
02538     { "fcmovu", ST, STi, XX },
02539     { "(bad)",  XX, XX, XX },
02540     { FGRPda_5 },
02541     { "(bad)",  XX, XX, XX },
02542     { "(bad)",  XX, XX, XX },
02543   },
02544   /* db */
02545   {
02546     { "fcmovnb",ST, STi, XX },
02547     { "fcmovne",ST, STi, XX },
02548     { "fcmovnbe",ST, STi, XX },
02549     { "fcmovnu",ST, STi, XX },
02550     { FGRPdb_4 },
02551     { "fucomi", ST, STi, XX },
02552     { "fcomi",  ST, STi, XX },
02553     { "(bad)",  XX, XX, XX },
02554   },
02555   /* dc */
02556   {
02557     { "fadd",   STi, ST, XX },
02558     { "fmul",   STi, ST, XX },
02559     { "(bad)",  XX, XX, XX },
02560     { "(bad)",  XX, XX, XX },
02561 #if UNIXWARE_COMPAT
02562     { "fsub",   STi, ST, XX },
02563     { "fsubr",  STi, ST, XX },
02564     { "fdiv",   STi, ST, XX },
02565     { "fdivr",  STi, ST, XX },
02566 #else
02567     { "fsubr",  STi, ST, XX },
02568     { "fsub",   STi, ST, XX },
02569     { "fdivr",  STi, ST, XX },
02570     { "fdiv",   STi, ST, XX },
02571 #endif
02572   },
02573   /* dd */
02574   {
02575     { "ffree",  STi, XX, XX },
02576     { "(bad)",  XX, XX, XX },
02577     { "fst",    STi, XX, XX },
02578     { "fstp",   STi, XX, XX },
02579     { "fucom",  STi, XX, XX },
02580     { "fucomp", STi, XX, XX },
02581     { "(bad)",  XX, XX, XX },
02582     { "(bad)",  XX, XX, XX },
02583   },
02584   /* de */
02585   {
02586     { "faddp",  STi, ST, XX },
02587     { "fmulp",  STi, ST, XX },
02588     { "(bad)",  XX, XX, XX },
02589     { FGRPde_3 },
02590 #if UNIXWARE_COMPAT
02591     { "fsubp",  STi, ST, XX },
02592     { "fsubrp", STi, ST, XX },
02593     { "fdivp",  STi, ST, XX },
02594     { "fdivrp", STi, ST, XX },
02595 #else
02596     { "fsubrp", STi, ST, XX },
02597     { "fsubp",  STi, ST, XX },
02598     { "fdivrp", STi, ST, XX },
02599     { "fdivp",  STi, ST, XX },
02600 #endif
02601   },
02602   /* df */
02603   {
02604     { "ffreep", STi, XX, XX },
02605     { "(bad)",  XX, XX, XX },
02606     { "(bad)",  XX, XX, XX },
02607     { "(bad)",  XX, XX, XX },
02608     { FGRPdf_4 },
02609     { "fucomip",ST, STi, XX },
02610     { "fcomip", ST, STi, XX },
02611     { "(bad)",  XX, XX, XX },
02612   },
02613 };
02614 
02615 static char *fgrps[][8] = {
02616   /* d9_2  0 */
02617   {
02618     "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
02619   },
02620 
02621   /* d9_4  1 */
02622   {
02623     "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
02624   },
02625 
02626   /* d9_5  2 */
02627   {
02628     "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
02629   },
02630 
02631   /* d9_6  3 */
02632   {
02633     "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
02634   },
02635 
02636   /* d9_7  4 */
02637   {
02638     "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
02639   },
02640 
02641   /* da_5  5 */
02642   {
02643     "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
02644   },
02645 
02646   /* db_4  6 */
02647   {
02648     "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
02649     "fNsetpm(287 only)","(bad)","(bad)","(bad)",
02650   },
02651 
02652   /* de_3  7 */
02653   {
02654     "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
02655   },
02656 
02657   /* df_4  8 */
02658   {
02659     "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
02660   },
02661 };
02662 
02663 static void
02664 dofloat (sizeflag)
02665      int sizeflag;
02666 {
02667   const struct dis386 *dp;
02668   unsigned char floatop;
02669 
02670   floatop = codep[-1];
02671 
02672   if (mod != 3)
02673     {
02674       putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
02675       obufp = op1out;
02676       if (floatop == 0xdb)
02677         OP_E (x_mode, sizeflag);
02678       else if (floatop == 0xdd)
02679         OP_E (d_mode, sizeflag);
02680       else
02681         OP_E (v_mode, sizeflag);
02682       return;
02683     }
02684   /* Skip mod/rm byte.  */
02685   MODRM_CHECK;
02686   codep++;
02687 
02688   dp = &float_reg[floatop - 0xd8][reg];
02689   if (dp->name == NULL)
02690     {
02691       putop (fgrps[dp->bytemode1][rm], sizeflag);
02692 
02693       /* Instruction fnstsw is only one with strange arg.  */
02694       if (floatop == 0xdf && codep[-1] == 0xe0)
02695     strcpy (op1out, names16[0]);
02696     }
02697   else
02698     {
02699       putop (dp->name, sizeflag);
02700 
02701       obufp = op1out;
02702       if (dp->op1)
02703     (*dp->op1) (dp->bytemode1, sizeflag);
02704       obufp = op2out;
02705       if (dp->op2)
02706     (*dp->op2) (dp->bytemode2, sizeflag);
02707     }
02708 }
02709 
02710 static void
02711 OP_ST (bytemode, sizeflag)
02712      int bytemode ATTRIBUTE_UNUSED;
02713      int sizeflag ATTRIBUTE_UNUSED;
02714 {
02715   oappend ("%st");
02716 }
02717 
02718 static void
02719 OP_STi (bytemode, sizeflag)
02720      int bytemode ATTRIBUTE_UNUSED;
02721      int sizeflag ATTRIBUTE_UNUSED;
02722 {
02723   sprintf (scratchbuf, "%%st(%d)", rm);
02724   oappend (scratchbuf + intel_syntax);
02725 }
02726 
02727 /* Capital letters in template are macros.  */
02728 static int
02729 putop (template, sizeflag)
02730      const char *template;
02731      int sizeflag;
02732 {
02733   const char *p;
02734   int alt;
02735 
02736   for (p = template; *p; p++)
02737     {
02738       switch (*p)
02739     {
02740     default:
02741       *obufp++ = *p;
02742       break;
02743     case '{':
02744       alt = 0;
02745       if (intel_syntax)
02746         alt += 1;
02747       if (mode_64bit)
02748         alt += 2;
02749       while (alt != 0)
02750         {
02751           while (*++p != '|')
02752         {
02753           if (*p == '}')
02754             {
02755               /* Alternative not valid.  */
02756               strcpy (obuf, "(bad)");
02757               obufp = obuf + 5;
02758               return 1;
02759             }
02760           else if (*p == '\0')
02761             abort ();
02762         }
02763           alt--;
02764         }
02765       break;
02766     case '|':
02767       while (*++p != '}')
02768         {
02769           if (*p == '\0')
02770         abort ();
02771         }
02772       break;
02773     case '}':
02774       break;
02775     case 'A':
02776           if (intel_syntax)
02777             break;
02778       if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
02779         *obufp++ = 'b';
02780       break;
02781     case 'B':
02782           if (intel_syntax)
02783             break;
02784       if (sizeflag & SUFFIX_ALWAYS)
02785         *obufp++ = 'b';
02786       break;
02787     case 'E':       /* For jcxz/jecxz */
02788       if (mode_64bit)
02789         {
02790           if (sizeflag & AFLAG)
02791         *obufp++ = 'r';
02792           else
02793         *obufp++ = 'e';
02794         }
02795       else
02796         if (sizeflag & AFLAG)
02797           *obufp++ = 'e';
02798       used_prefixes |= (prefixes & PREFIX_ADDR);
02799       break;
02800     case 'F':
02801           if (intel_syntax)
02802             break;
02803       if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
02804         {
02805           if (sizeflag & AFLAG)
02806         *obufp++ = mode_64bit ? 'q' : 'l';
02807           else
02808         *obufp++ = mode_64bit ? 'l' : 'w';
02809           used_prefixes |= (prefixes & PREFIX_ADDR);
02810         }
02811       break;
02812     case 'H':
02813           if (intel_syntax)
02814             break;
02815       if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
02816           || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
02817         {
02818           used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
02819           *obufp++ = ',';
02820           *obufp++ = 'p';
02821           if (prefixes & PREFIX_DS)
02822         *obufp++ = 't';
02823           else
02824         *obufp++ = 'n';
02825         }
02826       break;
02827     case 'L':
02828           if (intel_syntax)
02829             break;
02830       if (sizeflag & SUFFIX_ALWAYS)
02831         *obufp++ = 'l';
02832       break;
02833     case 'N':
02834       if ((prefixes & PREFIX_FWAIT) == 0)
02835         *obufp++ = 'n';
02836       else
02837         used_prefixes |= PREFIX_FWAIT;
02838       break;
02839     case 'O':
02840       USED_REX (REX_MODE64);
02841       if (rex & REX_MODE64)
02842         *obufp++ = 'o';
02843       else
02844         *obufp++ = 'd';
02845       break;
02846     case 'T':
02847           if (intel_syntax)
02848             break;
02849       if (mode_64bit)
02850         {
02851           *obufp++ = 'q';
02852           break;
02853         }
02854       /* Fall through.  */
02855     case 'P':
02856           if (intel_syntax)
02857             break;
02858       if ((prefixes & PREFIX_DATA)
02859           || (rex & REX_MODE64)
02860           || (sizeflag & SUFFIX_ALWAYS))
02861         {
02862           USED_REX (REX_MODE64);
02863           if (rex & REX_MODE64)
02864         *obufp++ = 'q';
02865           else
02866         {
02867            if (sizeflag & DFLAG)
02868               *obufp++ = 'l';
02869            else
02870              *obufp++ = 'w';
02871            used_prefixes |= (prefixes & PREFIX_DATA);
02872         }
02873         }
02874       break;
02875     case 'U':
02876           if (intel_syntax)
02877             break;
02878       if (mode_64bit)
02879         {
02880           *obufp++ = 'q';
02881           break;
02882         }
02883       /* Fall through.  */
02884     case 'Q':
02885           if (intel_syntax)
02886             break;
02887       USED_REX (REX_MODE64);
02888       if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
02889         {
02890           if (rex & REX_MODE64)
02891         *obufp++ = 'q';
02892           else
02893         {
02894           if (sizeflag & DFLAG)
02895             *obufp++ = 'l';
02896           else
02897             *obufp++ = 'w';
02898           used_prefixes |= (prefixes & PREFIX_DATA);
02899         }
02900         }
02901       break;
02902     case 'R':
02903       USED_REX (REX_MODE64);
02904           if (intel_syntax)
02905         {
02906           if (rex & REX_MODE64)
02907         {
02908           *obufp++ = 'q';
02909           *obufp++ = 't';
02910         }
02911           else if (sizeflag & DFLAG)
02912         {
02913           *obufp++ = 'd';
02914           *obufp++ = 'q';
02915         }
02916           else
02917         {
02918           *obufp++ = 'w';
02919           *obufp++ = 'd';
02920         }
02921         }
02922       else
02923         {
02924           if (rex & REX_MODE64)
02925         *obufp++ = 'q';
02926           else if (sizeflag & DFLAG)
02927         *obufp++ = 'l';
02928           else
02929         *obufp++ = 'w';
02930         }
02931       if (!(rex & REX_MODE64))
02932         used_prefixes |= (prefixes & PREFIX_DATA);
02933       break;
02934     case 'S':
02935           if (intel_syntax)
02936             break;
02937       if (sizeflag & SUFFIX_ALWAYS)
02938         {
02939           if (rex & REX_MODE64)
02940         *obufp++ = 'q';
02941           else
02942         {
02943           if (sizeflag & DFLAG)
02944             *obufp++ = 'l';
02945           else
02946             *obufp++ = 'w';
02947           used_prefixes |= (prefixes & PREFIX_DATA);
02948         }
02949         }
02950       break;
02951     case 'X':
02952       if (prefixes & PREFIX_DATA)
02953         *obufp++ = 'd';
02954       else
02955         *obufp++ = 's';
02956           used_prefixes |= (prefixes & PREFIX_DATA);
02957       break;
02958     case 'Y':
02959           if (intel_syntax)
02960             break;
02961       if (rex & REX_MODE64)
02962         {
02963           USED_REX (REX_MODE64);
02964           *obufp++ = 'q';
02965         }
02966       break;
02967       /* implicit operand size 'l' for i386 or 'q' for x86-64 */
02968     case 'W':
02969       /* operand size flag for cwtl, cbtw */
02970       USED_REX (0);
02971       if (rex)
02972         *obufp++ = 'l';
02973       else if (sizeflag & DFLAG)
02974         *obufp++ = 'w';
02975       else
02976         *obufp++ = 'b';
02977           if (intel_syntax)
02978         {
02979           if (rex)
02980         {
02981           *obufp++ = 'q';
02982           *obufp++ = 'e';
02983         }
02984           if (sizeflag & DFLAG)
02985         {
02986           *obufp++ = 'd';
02987           *obufp++ = 'e';
02988         }
02989           else
02990         {
02991           *obufp++ = 'w';
02992         }
02993         }
02994       if (!rex)
02995         used_prefixes |= (prefixes & PREFIX_DATA);
02996       break;
02997     }
02998     }
02999   *obufp = 0;
03000   return 0;
03001 }
03002 
03003 static void
03004 oappend (s)
03005      const char *s;
03006 {
03007   strcpy (obufp, s);
03008   obufp += strlen (s);
03009 }
03010 
03011 static void
03012 append_seg ()
03013 {
03014   if (prefixes & PREFIX_CS)
03015     {
03016       used_prefixes |= PREFIX_CS;
03017       oappend ("%cs:" + intel_syntax);
03018     }
03019   if (prefixes & PREFIX_DS)
03020     {
03021       used_prefixes |= PREFIX_DS;
03022       oappend ("%ds:" + intel_syntax);
03023     }
03024   if (prefixes & PREFIX_SS)
03025     {
03026       used_prefixes |= PREFIX_SS;
03027       oappend ("%ss:" + intel_syntax);
03028     }
03029   if (prefixes & PREFIX_ES)
03030     {
03031       used_prefixes |= PREFIX_ES;
03032       oappend ("%es:" + intel_syntax);
03033     }
03034   if (prefixes & PREFIX_FS)
03035     {
03036       used_prefixes |= PREFIX_FS;
03037       oappend ("%fs:" + intel_syntax);
03038     }
03039   if (prefixes & PREFIX_GS)
03040     {
03041       used_prefixes |= PREFIX_GS;
03042       oappend ("%gs:" + intel_syntax);
03043     }
03044 }
03045 
03046 static void
03047 OP_indirE (bytemode, sizeflag)
03048      int bytemode;
03049      int sizeflag;
03050 {
03051   if (!intel_syntax)
03052     oappend ("*");
03053   OP_E (bytemode, sizeflag);
03054 }
03055 
03056 static void
03057 print_operand_value (buf, hex, disp)
03058   char *buf;
03059   int hex;
03060   bfd_vma disp;
03061 {
03062   if (mode_64bit)
03063     {
03064       if (hex)
03065     {
03066       char tmp[30];
03067       int i;
03068       buf[0] = '0';
03069       buf[1] = 'x';
03070       sprintf_vma (tmp, disp);
03071       for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
03072       strcpy (buf + 2, tmp + i);
03073     }
03074       else
03075     {
03076       bfd_signed_vma v = disp;
03077       char tmp[30];
03078       int i;
03079       if (v < 0)
03080         {
03081           *(buf++) = '-';
03082           v = -disp;
03083           /* Check for possible overflow on 0x8000000000000000.  */
03084           if (v < 0)
03085         {
03086           strcpy (buf, "9223372036854775808");
03087           return;
03088         }
03089         }
03090       if (!v)
03091         {
03092           strcpy (buf, "0");
03093           return;
03094         }
03095 
03096       i = 0;
03097       tmp[29] = 0;
03098       while (v)
03099         {
03100           tmp[28 - i] = (v % 10) + '0';
03101           v /= 10;
03102           i++;
03103         }
03104       strcpy (buf, tmp + 29 - i);
03105     }
03106     }
03107   else
03108     {
03109       if (hex)
03110     sprintf (buf, "0x%x", (unsigned int) disp);
03111       else
03112     sprintf (buf, "%d", (int) disp);
03113     }
03114 }
03115 
03116 static void
03117 OP_E (bytemode, sizeflag)
03118      int bytemode;
03119      int sizeflag;
03120 {
03121   bfd_vma disp;
03122   int add = 0;
03123   int riprel = 0;
03124   USED_REX (REX_EXTZ);
03125   if (rex & REX_EXTZ)
03126     add += 8;
03127 
03128   /* Skip mod/rm byte.  */
03129   MODRM_CHECK;
03130   codep++;
03131 
03132   if (mod == 3)
03133     {
03134       switch (bytemode)
03135     {
03136     case b_mode:
03137       USED_REX (0);
03138       if (rex)
03139         oappend (names8rex[rm + add]);
03140       else
03141         oappend (names8[rm + add]);
03142       break;
03143     case w_mode:
03144       oappend (names16[rm + add]);
03145       break;
03146     case d_mode:
03147       oappend (names32[rm + add]);
03148       break;
03149     case q_mode:
03150       oappend (names64[rm + add]);
03151       break;
03152     case m_mode:
03153       if (mode_64bit)
03154         oappend (names64[rm + add]);
03155       else
03156         oappend (names32[rm + add]);
03157       break;
03158     case v_mode:
03159       USED_REX (REX_MODE64);
03160       if (rex & REX_MODE64)
03161         oappend (names64[rm + add]);
03162       else if (sizeflag & DFLAG)
03163         oappend (names32[rm + add]);
03164       else
03165         oappend (names16[rm + add]);
03166       used_prefixes |= (prefixes & PREFIX_DATA);
03167       break;
03168     case 0:
03169       if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
03170           && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
03171           && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
03172         BadOp ();   /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
03173       break;
03174     default:
03175       oappend (INTERNAL_DISASSEMBLER_ERROR);
03176       break;
03177     }
03178       return;
03179     }
03180 
03181   disp = 0;
03182   append_seg ();
03183 
03184   if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
03185     {
03186       int havesib;
03187       int havebase;
03188       int base;
03189       int index = 0;
03190       int scale = 0;
03191 
03192       havesib = 0;
03193       havebase = 1;
03194       base = rm;
03195 
03196       if (base == 4)
03197     {
03198       havesib = 1;
03199       FETCH_DATA (the_info, codep + 1);
03200       scale = (*codep >> 6) & 3;
03201       index = (*codep >> 3) & 7;
03202       base = *codep & 7;
03203       USED_REX (REX_EXTY);
03204       USED_REX (REX_EXTZ);
03205       if (rex & REX_EXTY)
03206         index += 8;
03207       if (rex & REX_EXTZ)
03208         base += 8;
03209       codep++;
03210     }
03211 
03212       switch (mod)
03213     {
03214     case 0:
03215       if ((base & 7) == 5)
03216         {
03217           havebase = 0;
03218           if (mode_64bit && !havesib && (sizeflag & AFLAG))
03219         riprel = 1;
03220           disp = get32s ();
03221         }
03222       break;
03223     case 1:
03224       FETCH_DATA (the_info, codep + 1);
03225       disp = *codep++;
03226       if ((disp & 0x80) != 0)
03227         disp -= 0x100;
03228       break;
03229     case 2:
03230       disp = get32s ();
03231       break;
03232     }
03233 
03234       if (!intel_syntax)
03235         if (mod != 0 || (base & 7) == 5)
03236           {
03237         print_operand_value (scratchbuf, !riprel, disp);
03238             oappend (scratchbuf);
03239         if (riprel)
03240           {
03241         set_op (disp, 1);
03242         oappend ("(%rip)");
03243           }
03244           }
03245 
03246       if (havebase || (havesib && (index != 4 || scale != 0)))
03247     {
03248           if (intel_syntax)
03249             {
03250               switch (bytemode)
03251                 {
03252                 case b_mode:
03253                   oappend ("BYTE PTR ");
03254                   break;
03255                 case w_mode:
03256                   oappend ("WORD PTR ");
03257                   break;
03258                 case v_mode:
03259                   oappend ("DWORD PTR ");
03260                   break;
03261                 case d_mode:
03262                   oappend ("QWORD PTR ");
03263                   break;
03264                 case m_mode:
03265           if (mode_64bit)
03266             oappend ("DWORD PTR ");
03267           else
03268             oappend ("QWORD PTR ");
03269           break;
03270                 case x_mode:
03271                   oappend ("XWORD PTR ");
03272                   break;
03273                 default:
03274                   break;
03275                 }
03276              }
03277       *obufp++ = open_char;
03278       if (intel_syntax && riprel)
03279         oappend ("rip + ");
03280           *obufp = '\0';
03281       USED_REX (REX_EXTZ);
03282       if (!havesib && (rex & REX_EXTZ))
03283         base += 8;
03284       if (havebase)
03285         oappend (mode_64bit && (sizeflag & AFLAG)
03286              ? names64[base] : names32[base]);
03287       if (havesib)
03288         {
03289           if (index != 4)
03290         {
03291                   if (intel_syntax)
03292                     {
03293                       if (havebase)
03294                         {
03295                           *obufp++ = separator_char;
03296                           *obufp = '\0';
03297                         }
03298                       sprintf (scratchbuf, "%s",
03299                    mode_64bit && (sizeflag & AFLAG)
03300                    ? names64[index] : names32[index]);
03301                     }
03302                   else
03303             sprintf (scratchbuf, ",%s",
03304                  mode_64bit && (sizeflag & AFLAG)
03305                  ? names64[index] : names32[index]);
03306           oappend (scratchbuf);
03307         }
03308               if (!intel_syntax
03309                   || (intel_syntax
03310                       && bytemode != b_mode
03311                       && bytemode != w_mode
03312                       && bytemode != v_mode))
03313                 {
03314                   *obufp++ = scale_char;
03315                   *obufp = '\0';
03316               sprintf (scratchbuf, "%d", 1 << scale);
03317               oappend (scratchbuf);
03318                 }
03319         }
03320           if (intel_syntax)
03321             if (mod != 0 || (base & 7) == 5)
03322               {
03323         /* Don't print zero displacements.  */
03324                 if (disp != 0)
03325                   {
03326             if ((bfd_signed_vma) disp > 0)
03327               {
03328             *obufp++ = '+';
03329             *obufp = '\0';
03330               }
03331 
03332             print_operand_value (scratchbuf, 0, disp);
03333                     oappend (scratchbuf);
03334                   }
03335               }
03336 
03337       *obufp++ = close_char;
03338           *obufp = '\0';
03339     }
03340       else if (intel_syntax)
03341         {
03342           if (mod != 0 || (base & 7) == 5)
03343             {
03344           if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
03345                   | PREFIX_ES | PREFIX_FS | PREFIX_GS))
03346         ;
03347           else
03348         {
03349           oappend (names_seg[ds_reg - es_reg]);
03350           oappend (":");
03351         }
03352           print_operand_value (scratchbuf, 1, disp);
03353               oappend (scratchbuf);
03354             }
03355         }
03356     }
03357   else
03358     { /* 16 bit address mode */
03359       switch (mod)
03360     {
03361     case 0:
03362       if ((rm & 7) == 6)
03363         {
03364           disp = get16 ();
03365           if ((disp & 0x8000) != 0)
03366         disp -= 0x10000;
03367         }
03368       break;
03369     case 1:
03370       FETCH_DATA (the_info, codep + 1);
03371       disp = *codep++;
03372       if ((disp & 0x80) != 0)
03373         disp -= 0x100;
03374       break;
03375     case 2:
03376       disp = get16 ();
03377       if ((disp & 0x8000) != 0)
03378         disp -= 0x10000;
03379       break;
03380     }
03381 
03382       if (!intel_syntax)
03383         if (mod != 0 || (rm & 7) == 6)
03384           {
03385         print_operand_value (scratchbuf, 0, disp);
03386             oappend (scratchbuf);
03387           }
03388 
03389       if (mod != 0 || (rm & 7) != 6)
03390     {
03391       *obufp++ = open_char;
03392           *obufp = '\0';
03393       oappend (index16[rm + add]);
03394           *obufp++ = close_char;
03395           *obufp = '\0';
03396     }
03397     }
03398 }
03399 
03400 static void
03401 OP_G (bytemode, sizeflag)
03402      int bytemode;
03403      int sizeflag;
03404 {
03405   int add = 0;
03406   USED_REX (REX_EXTX);
03407   if (rex & REX_EXTX)
03408     add += 8;
03409   switch (bytemode)
03410     {
03411     case b_mode:
03412       USED_REX (0);
03413       if (rex)
03414     oappend (names8rex[reg + add]);
03415       else
03416     oappend (names8[reg + add]);
03417       break;
03418     case w_mode:
03419       oappend (names16[reg + add]);
03420       break;
03421     case d_mode:
03422       oappend (names32[reg + add]);
03423       break;
03424     case q_mode:
03425       oappend (names64[reg + add]);
03426       break;
03427     case v_mode:
03428       USED_REX (REX_MODE64);
03429       if (rex & REX_MODE64)
03430     oappend (names64[reg + add]);
03431       else if (sizeflag & DFLAG)
03432     oappend (names32[reg + add]);
03433       else
03434     oappend (names16[reg + add]);
03435       used_prefixes |= (prefixes & PREFIX_DATA);
03436       break;
03437     default:
03438       oappend (INTERNAL_DISASSEMBLER_ERROR);
03439       break;
03440     }
03441 }
03442 
03443 static bfd_vma
03444 get64 ()
03445 {
03446   bfd_vma x;
03447 #ifdef BFD64
03448   unsigned int a;
03449   unsigned int b;
03450 
03451   FETCH_DATA (the_info, codep + 8);
03452   a = *codep++ & 0xff;
03453   a |= (*codep++ & 0xff) << 8;
03454   a |= (*codep++ & 0xff) << 16;
03455   a |= (*codep++ & 0xff) << 24;
03456   b = *codep++ & 0xff;
03457   b |= (*codep++ & 0xff) << 8;
03458   b |= (*codep++ & 0xff) << 16;
03459   b |= (*codep++ & 0xff) << 24;
03460   x = a + ((bfd_vma) b << 32);
03461 #else
03462   abort ();
03463   x = 0;
03464 #endif
03465   return x;
03466 }
03467 
03468 static bfd_signed_vma
03469 get32 ()
03470 {
03471   bfd_signed_vma x = 0;
03472 
03473   FETCH_DATA (the_info, codep + 4);
03474   x = *codep++ & (bfd_signed_vma) 0xff;
03475   x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
03476   x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
03477   x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
03478   return x;
03479 }
03480 
03481 static bfd_signed_vma
03482 get32s ()
03483 {
03484   bfd_signed_vma x = 0;
03485 
03486   FETCH_DATA (the_info, codep + 4);
03487   x = *codep++ & (bfd_signed_vma) 0xff;
03488   x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
03489   x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
03490   x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
03491 
03492   x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
03493 
03494   return x;
03495 }
03496 
03497 static int
03498 get16 ()
03499 {
03500   int x = 0;
03501 
03502   FETCH_DATA (the_info, codep + 2);
03503   x = *codep++ & 0xff;
03504   x |= (*codep++ & 0xff) << 8;
03505   return x;
03506 }
03507 
03508 static void
03509 set_op (op, riprel)
03510      bfd_vma op;
03511      int riprel;
03512 {
03513   op_index[op_ad] = op_ad;
03514   if (mode_64bit)
03515     {
03516       op_address[op_ad] = op;
03517       op_riprel[op_ad] = riprel;
03518     }
03519   else
03520     {
03521       /* Mask to get a 32-bit address.  */
03522       op_address[op_ad] = op & 0xffffffff;
03523       op_riprel[op_ad] = riprel & 0xffffffff;
03524     }
03525 }
03526 
03527 static void
03528 OP_REG (code, sizeflag)
03529      int code;
03530      int sizeflag;
03531 {
03532   const char *s;
03533   int add = 0;
03534   USED_REX (REX_EXTZ);
03535   if (rex & REX_EXTZ)
03536     add = 8;
03537 
03538   switch (code)
03539     {
03540     case indir_dx_reg:
03541       if (intel_syntax)
03542         s = "[dx]";
03543       else
03544         s = "(%dx)";
03545       break;
03546     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
03547     case sp_reg: case bp_reg: case si_reg: case di_reg:
03548       s = names16[code - ax_reg + add];
03549       break;
03550     case es_reg: case ss_reg: case cs_reg:
03551     case ds_reg: case fs_reg: case gs_reg:
03552       s = names_seg[code - es_reg + add];
03553       break;
03554     case al_reg: case ah_reg: case cl_reg: case ch_reg:
03555     case dl_reg: case dh_reg: case bl_reg: case bh_reg:
03556       USED_REX (0);
03557       if (rex)
03558     s = names8rex[code - al_reg + add];
03559       else
03560     s = names8[code - al_reg];
03561       break;
03562     case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
03563     case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
03564       if (mode_64bit)
03565     {
03566       s = names64[code - rAX_reg + add];
03567       break;
03568     }
03569       code += eAX_reg - rAX_reg;
03570       /* Fall through.  */
03571     case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
03572     case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
03573       USED_REX (REX_MODE64);
03574       if (rex & REX_MODE64)
03575     s = names64[code - eAX_reg + add];
03576       else if (sizeflag & DFLAG)
03577     s = names32[code - eAX_reg + add];
03578       else
03579     s = names16[code - eAX_reg + add];
03580       used_prefixes |= (prefixes & PREFIX_DATA);
03581       break;
03582     default:
03583       s = INTERNAL_DISASSEMBLER_ERROR;
03584       break;
03585     }
03586   oappend (s);
03587 }
03588 
03589 static void
03590 OP_IMREG (code, sizeflag)
03591      int code;
03592      int sizeflag;
03593 {
03594   const char *s;
03595 
03596   switch (code)
03597     {
03598     case indir_dx_reg:
03599       if (intel_syntax)
03600         s = "[dx]";
03601       else
03602         s = "(%dx)";
03603       break;
03604     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
03605     case sp_reg: case bp_reg: case si_reg: case di_reg:
03606       s = names16[code - ax_reg];
03607       break;
03608     case es_reg: case ss_reg: case cs_reg:
03609     case ds_reg: case fs_reg: case gs_reg:
03610       s = names_seg[code - es_reg];
03611       break;
03612     case al_reg: case ah_reg: case cl_reg: case ch_reg:
03613     case dl_reg: case dh_reg: case bl_reg: case bh_reg:
03614       USED_REX (0);
03615       if (rex)
03616     s = names8rex[code - al_reg];
03617       else
03618     s = names8[code - al_reg];
03619       break;
03620     case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
03621     case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
03622       USED_REX (REX_MODE64);
03623       if (rex & REX_MODE64)
03624     s = names64[code - eAX_reg];
03625       else if (sizeflag & DFLAG)
03626     s = names32[code - eAX_reg];
03627       else
03628     s = names16[code - eAX_reg];
03629       used_prefixes |= (prefixes & PREFIX_DATA);
03630       break;
03631     default:
03632       s = INTERNAL_DISASSEMBLER_ERROR;
03633       break;
03634     }
03635   oappend (s);
03636 }
03637 
03638 static void
03639 OP_I (bytemode, sizeflag)
03640      int bytemode;
03641      int sizeflag;
03642 {
03643   bfd_signed_vma op;
03644   bfd_signed_vma mask = -1;
03645 
03646   switch (bytemode)
03647     {
03648     case b_mode:
03649       FETCH_DATA (the_info, codep + 1);
03650       op = *codep++;
03651       mask = 0xff;
03652       break;
03653     case q_mode:
03654       if (mode_64bit)
03655     {
03656       op = get32s ();
03657       break;
03658     }
03659       /* Fall through.  */
03660     case v_mode:
03661       USED_REX (REX_MODE64);
03662       if (rex & REX_MODE64)
03663     op = get32s ();
03664       else if (sizeflag & DFLAG)
03665     {
03666       op = get32 ();
03667       mask = 0xffffffff;
03668     }
03669       else
03670     {
03671       op = get16 ();
03672       mask = 0xfffff;
03673     }
03674       used_prefixes |= (prefixes & PREFIX_DATA);
03675       break;
03676     case w_mode:
03677       mask = 0xfffff;
03678       op = get16 ();
03679       break;
03680     default:
03681       oappend (INTERNAL_DISASSEMBLER_ERROR);
03682       return;
03683     }
03684 
03685   op &= mask;
03686   scratchbuf[0] = '$';
03687   print_operand_value (scratchbuf + 1, 1, op);
03688   oappend (scratchbuf + intel_syntax);
03689   scratchbuf[0] = '\0';
03690 }
03691 
03692 static void
03693 OP_I64 (bytemode, sizeflag)
03694      int bytemode;
03695      int sizeflag;
03696 {
03697   bfd_signed_vma op;
03698   bfd_signed_vma mask = -1;
03699 
03700   if (!mode_64bit)
03701     {
03702       OP_I (bytemode, sizeflag);
03703       return;
03704     }
03705 
03706   switch (bytemode)
03707     {
03708     case b_mode:
03709       FETCH_DATA (the_info, codep + 1);
03710       op = *codep++;
03711       mask = 0xff;
03712       break;
03713     case v_mode:
03714       USED_REX (REX_MODE64);
03715       if (rex & REX_MODE64)
03716     op = get64 ();
03717       else if (sizeflag & DFLAG)
03718     {
03719       op = get32 ();
03720       mask = 0xffffffff;
03721     }
03722       else
03723     {
03724       op = get16 ();
03725       mask = 0xfffff;
03726     }
03727       used_prefixes |= (prefixes & PREFIX_DATA);
03728       break;
03729     case w_mode:
03730       mask = 0xfffff;
03731       op = get16 ();
03732       break;
03733     default:
03734       oappend (INTERNAL_DISASSEMBLER_ERROR);
03735       return;
03736     }
03737 
03738   op &= mask;
03739   scratchbuf[0] = '$';
03740   print_operand_value (scratchbuf + 1, 1, op);
03741   oappend (scratchbuf + intel_syntax);
03742   scratchbuf[0] = '\0';
03743 }
03744 
03745 static void
03746 OP_sI (bytemode, sizeflag)
03747      int bytemode;
03748      int sizeflag;
03749 {
03750   bfd_signed_vma op;
03751   bfd_signed_vma mask = -1;
03752 
03753   switch (bytemode)
03754     {
03755     case b_mode:
03756       FETCH_DATA (the_info, codep + 1);
03757       op = *codep++;
03758       if ((op & 0x80) != 0)
03759     op -= 0x100;
03760       mask = 0xffffffff;
03761       break;
03762     case v_mode:
03763       USED_REX (REX_MODE64);
03764       if (rex & REX_MODE64)
03765     op = get32s ();
03766       else if (sizeflag & DFLAG)
03767     {
03768       op = get32s ();
03769       mask = 0xffffffff;
03770     }
03771       else
03772     {
03773       mask = 0xffffffff;
03774       op = get16 ();
03775       if ((op & 0x8000) != 0)
03776         op -= 0x10000;
03777     }
03778       used_prefixes |= (prefixes & PREFIX_DATA);
03779       break;
03780     case w_mode:
03781       op = get16 ();
03782       mask = 0xffffffff;
03783       if ((op & 0x8000) != 0)
03784     op -= 0x10000;
03785       break;
03786     default:
03787       oappend (INTERNAL_DISASSEMBLER_ERROR);
03788       return;
03789     }
03790 
03791   scratchbuf[0] = '$';
03792   print_operand_value (scratchbuf + 1, 1, op);
03793   oappend (scratchbuf + intel_syntax);
03794 }
03795 
03796 static void
03797 OP_J (bytemode, sizeflag)
03798      int bytemode;
03799      int sizeflag;
03800 {
03801   bfd_vma disp;
03802   bfd_vma mask = -1;
03803 
03804   switch (bytemode)
03805     {
03806     case b_mode:
03807       FETCH_DATA (the_info, codep + 1);
03808       disp = *codep++;
03809       if ((disp & 0x80) != 0)
03810     disp -= 0x100;
03811       break;
03812     case v_mode:
03813       if (sizeflag & DFLAG)
03814     disp = get32s ();
03815       else
03816     {
03817       disp = get16 ();
03818       /* For some reason, a data16 prefix on a jump instruction
03819          means that the pc is masked to 16 bits after the
03820          displacement is added!  */
03821       mask = 0xffff;
03822     }
03823       break;
03824     default:
03825       oappend (INTERNAL_DISASSEMBLER_ERROR);
03826       return;
03827     }
03828   disp = (start_pc + codep - start_codep + disp) & mask;
03829   set_op (disp, 0);
03830   print_operand_value (scratchbuf, 1, disp);
03831   oappend (scratchbuf);
03832 }
03833 
03834 static void
03835 OP_SEG (dummy, sizeflag)
03836      int dummy ATTRIBUTE_UNUSED;
03837      int sizeflag ATTRIBUTE_UNUSED;
03838 {
03839   oappend (names_seg[reg]);
03840 }
03841 
03842 static void
03843 OP_DIR (dummy, sizeflag)
03844      int dummy ATTRIBUTE_UNUSED;
03845      int sizeflag;
03846 {
03847   int seg, offset;
03848 
03849   if (sizeflag & DFLAG)
03850     {
03851       offset = get32 ();
03852       seg = get16 ();
03853     }
03854   else
03855     {
03856       offset = get16 ();
03857       seg = get16 ();
03858     }
03859   used_prefixes |= (prefixes & PREFIX_DATA);
03860   if (intel_syntax)
03861     sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
03862   else
03863     sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
03864   oappend (scratchbuf);
03865 }
03866 
03867 static void
03868 OP_OFF (bytemode, sizeflag)
03869      int bytemode ATTRIBUTE_UNUSED;
03870      int sizeflag;
03871 {
03872   bfd_vma off;
03873 
03874   append_seg ();
03875 
03876   if ((sizeflag & AFLAG) || mode_64bit)
03877     off = get32 ();
03878   else
03879     off = get16 ();
03880 
03881   if (intel_syntax)
03882     {
03883       if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
03884                 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
03885     {
03886       oappend (names_seg[ds_reg - es_reg]);
03887       oappend (":");
03888     }
03889     }
03890   print_operand_value (scratchbuf, 1, off);
03891   oappend (scratchbuf);
03892 }
03893 
03894 static void
03895 OP_OFF64 (bytemode, sizeflag)
03896      int bytemode ATTRIBUTE_UNUSED;
03897      int sizeflag ATTRIBUTE_UNUSED;
03898 {
03899   bfd_vma off;
03900 
03901   if (!mode_64bit)
03902     {
03903       OP_OFF (bytemode, sizeflag);
03904       return;
03905     }
03906 
03907   append_seg ();
03908 
03909   off = get64 ();
03910 
03911   if (intel_syntax)
03912     {
03913       if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
03914                 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
03915     {
03916       oappend (names_seg[ds_reg - es_reg]);
03917       oappend (":");
03918     }
03919     }
03920   print_operand_value (scratchbuf, 1, off);
03921   oappend (scratchbuf);
03922 }
03923 
03924 static void
03925 ptr_reg (code, sizeflag)
03926      int code;
03927      int sizeflag;
03928 {
03929   const char *s;
03930   if (intel_syntax)
03931     oappend ("[");
03932   else
03933     oappend ("(");
03934 
03935   USED_REX (REX_MODE64);
03936   if (rex & REX_MODE64)
03937     {
03938       if (!(sizeflag & AFLAG))
03939         s = names32[code - eAX_reg];
03940       else
03941         s = names64[code - eAX_reg];
03942     }
03943   else if (sizeflag & AFLAG)
03944     s = names32[code - eAX_reg];
03945   else
03946     s = names16[code - eAX_reg];
03947   oappend (s);
03948   if (intel_syntax)
03949     oappend ("]");
03950   else
03951     oappend (")");
03952 }
03953 
03954 static void
03955 OP_ESreg (code, sizeflag)
03956      int code;
03957      int sizeflag;
03958 {
03959   oappend ("%es:" + intel_syntax);
03960   ptr_reg (code, sizeflag);
03961 }
03962 
03963 static void
03964 OP_DSreg (code, sizeflag)
03965      int code;
03966      int sizeflag;
03967 {
03968   if ((prefixes
03969        & (PREFIX_CS
03970       | PREFIX_DS
03971       | PREFIX_SS
03972       | PREFIX_ES
03973       | PREFIX_FS
03974       | PREFIX_GS)) == 0)
03975     prefixes |= PREFIX_DS;
03976   append_seg ();
03977   ptr_reg (code, sizeflag);
03978 }
03979 
03980 static void
03981 OP_C (dummy, sizeflag)
03982      int dummy ATTRIBUTE_UNUSED;
03983      int sizeflag ATTRIBUTE_UNUSED;
03984 {
03985   int add = 0;
03986   USED_REX (REX_EXTX);
03987   if (rex & REX_EXTX)
03988     add = 8;
03989   sprintf (scratchbuf, "%%cr%d", reg + add);
03990   oappend (scratchbuf + intel_syntax);
03991 }
03992 
03993 static void
03994 OP_D (dummy, sizeflag)
03995      int dummy ATTRIBUTE_UNUSED;
03996      int sizeflag ATTRIBUTE_UNUSED;
03997 {
03998   int add = 0;
03999   USED_REX (REX_EXTX);
04000   if (rex & REX_EXTX)
04001     add = 8;
04002   if (intel_syntax)
04003     sprintf (scratchbuf, "db%d", reg + add);
04004   else
04005     sprintf (scratchbuf, "%%db%d", reg + add);
04006   oappend (scratchbuf);
04007 }
04008 
04009 static void
04010 OP_T (dummy, sizeflag)
04011      int dummy ATTRIBUTE_UNUSED;
04012      int sizeflag ATTRIBUTE_UNUSED;
04013 {
04014   sprintf (scratchbuf, "%%tr%d", reg);
04015   oappend (scratchbuf + intel_syntax);
04016 }
04017 
04018 static void
04019 OP_Rd (bytemode, sizeflag)
04020      int bytemode;
04021      int sizeflag;
04022 {
04023   if (mod == 3)
04024     OP_E (bytemode, sizeflag);
04025   else
04026     BadOp ();
04027 }
04028 
04029 static void
04030 OP_MMX (bytemode, sizeflag)
04031      int bytemode ATTRIBUTE_UNUSED;
04032      int sizeflag ATTRIBUTE_UNUSED;
04033 {
04034   int add = 0;
04035   USED_REX (REX_EXTX);
04036   if (rex & REX_EXTX)
04037     add = 8;
04038   used_prefixes |= (prefixes & PREFIX_DATA);
04039   if (prefixes & PREFIX_DATA)
04040     sprintf (scratchbuf, "%%xmm%d", reg + add);
04041   else
04042     sprintf (scratchbuf, "%%mm%d", reg + add);
04043   oappend (scratchbuf + intel_syntax);
04044 }
04045 
04046 static void
04047 OP_XMM (bytemode, sizeflag)
04048      int bytemode ATTRIBUTE_UNUSED;
04049      int sizeflag ATTRIBUTE_UNUSED;
04050 {
04051   int add = 0;
04052   USED_REX (REX_EXTX);
04053   if (rex & REX_EXTX)
04054     add = 8;
04055   sprintf (scratchbuf, "%%xmm%d", reg + add);
04056   oappend (scratchbuf + intel_syntax);
04057 }
04058 
04059 static void
04060 OP_EM (bytemode, sizeflag)
04061      int bytemode;
04062      int sizeflag;
04063 {
04064   int add = 0;
04065   if (mod != 3)
04066     {
04067       OP_E (bytemode, sizeflag);
04068       return;
04069     }
04070   USED_REX (REX_EXTZ);
04071   if (rex & REX_EXTZ)
04072     add = 8;
04073 
04074   /* Skip mod/rm byte.  */
04075   MODRM_CHECK;
04076   codep++;
04077   used_prefixes |= (prefixes & PREFIX_DATA);
04078   if (prefixes & PREFIX_DATA)
04079     sprintf (scratchbuf, "%%xmm%d", rm + add);
04080   else
04081     sprintf (scratchbuf, "%%mm%d", rm + add);
04082   oappend (scratchbuf + intel_syntax);
04083 }
04084 
04085 static void
04086 OP_EX (bytemode, sizeflag)
04087      int bytemode;
04088      int sizeflag;
04089 {
04090   int add = 0;
04091   if (mod != 3)
04092     {
04093       OP_E (bytemode, sizeflag);
04094       return;
04095     }
04096   USED_REX (REX_EXTZ);
04097   if (rex & REX_EXTZ)
04098     add = 8;
04099 
04100   /* Skip mod/rm byte.  */
04101   MODRM_CHECK;
04102   codep++;
04103   sprintf (scratchbuf, "%%xmm%d", rm + add);
04104   oappend (scratchbuf + intel_syntax);
04105 }
04106 
04107 static void
04108 OP_MS (bytemode, sizeflag)
04109      int bytemode;
04110      int sizeflag;
04111 {
04112   if (mod == 3)
04113     OP_EM (bytemode, sizeflag);
04114   else
04115     BadOp ();
04116 }
04117 
04118 static void
04119 OP_XS (bytemode, sizeflag)
04120      int bytemode;
04121      int sizeflag;
04122 {
04123   if (mod == 3)
04124     OP_EX (bytemode, sizeflag);
04125   else
04126     BadOp ();
04127 }
04128 
04129 static const char *Suffix3DNow[] = {
04130 /* 00 */    NULL,       NULL,       NULL,       NULL,
04131 /* 04 */    NULL,       NULL,       NULL,       NULL,
04132 /* 08 */    NULL,       NULL,       NULL,       NULL,
04133 /* 0C */    "pi2fw",    "pi2fd",    NULL,       NULL,
04134 /* 10 */    NULL,       NULL,       NULL,       NULL,
04135 /* 14 */    NULL,       NULL,       NULL,       NULL,
04136 /* 18 */    NULL,       NULL,       NULL,       NULL,
04137 /* 1C */    "pf2iw",    "pf2id",    NULL,       NULL,
04138 /* 20 */    NULL,       NULL,       NULL,       NULL,
04139 /* 24 */    NULL,       NULL,       NULL,       NULL,
04140 /* 28 */    NULL,       NULL,       NULL,       NULL,
04141 /* 2C */    NULL,       NULL,       NULL,       NULL,
04142 /* 30 */    NULL,       NULL,       NULL,       NULL,
04143 /* 34 */    NULL,       NULL,       NULL,       NULL,
04144 /* 38 */    NULL,       NULL,       NULL,       NULL,
04145 /* 3C */    NULL,       NULL,       NULL,       NULL,
04146 /* 40 */    NULL,       NULL,       NULL,       NULL,
04147 /* 44 */    NULL,       NULL,       NULL,       NULL,
04148 /* 48 */    NULL,       NULL,       NULL,       NULL,
04149 /* 4C */    NULL,       NULL,       NULL,       NULL,
04150 /* 50 */    NULL,       NULL,       NULL,       NULL,
04151 /* 54 */    NULL,       NULL,       NULL,       NULL,
04152 /* 58 */    NULL,       NULL,       NULL,       NULL,
04153 /* 5C */    NULL,       NULL,       NULL,       NULL,
04154 /* 60 */    NULL,       NULL,       NULL,       NULL,
04155 /* 64 */    NULL,       NULL,       NULL,       NULL,
04156 /* 68 */    NULL,       NULL,       NULL,       NULL,
04157 /* 6C */    NULL,       NULL,       NULL,       NULL,
04158 /* 70 */    NULL,       NULL,       NULL,       NULL,
04159 /* 74 */    NULL,       NULL,       NULL,       NULL,
04160 /* 78 */    NULL,       NULL,       NULL,       NULL,
04161 /* 7C */    NULL,       NULL,       NULL,       NULL,
04162 /* 80 */    NULL,       NULL,       NULL,       NULL,
04163 /* 84 */    NULL,       NULL,       NULL,       NULL,
04164 /* 88 */    NULL,       NULL,       "pfnacc",   NULL,
04165 /* 8C */    NULL,       NULL,       "pfpnacc",  NULL,
04166 /* 90 */    "pfcmpge",  NULL,       NULL,       NULL,
04167 /* 94 */    "pfmin",    NULL,       "pfrcp",    "pfrsqrt",
04168 /* 98 */    NULL,       NULL,       "pfsub",    NULL,
04169 /* 9C */    NULL,       NULL,       "pfadd",    NULL,
04170 /* A0 */    "pfcmpgt",  NULL,       NULL,       NULL,
04171 /* A4 */    "pfmax",    NULL,       "pfrcpit1", "pfrsqit1",
04172 /* A8 */    NULL,       NULL,       "pfsubr",   NULL,
04173 /* AC */    NULL,       NULL,       "pfacc",    NULL,
04174 /* B0 */    "pfcmpeq",  NULL,       NULL,       NULL,
04175 /* B4 */    "pfmul",    NULL,       "pfrcpit2", "pfmulhrw",
04176 /* B8 */    NULL,       NULL,       NULL,       "pswapd",
04177 /* BC */    NULL,       NULL,       NULL,       "pavgusb",
04178 /* C0 */    NULL,       NULL,       NULL,       NULL,
04179 /* C4 */    NULL,       NULL,       NULL,       NULL,
04180 /* C8 */    NULL,       NULL,       NULL,       NULL,
04181 /* CC */    NULL,       NULL,       NULL,       NULL,
04182 /* D0 */    NULL,       NULL,       NULL,       NULL,
04183 /* D4 */    NULL,       NULL,       NULL,       NULL,
04184 /* D8 */    NULL,       NULL,       NULL,       NULL,
04185 /* DC */    NULL,       NULL,       NULL,       NULL,
04186 /* E0 */    NULL,       NULL,       NULL,       NULL,
04187 /* E4 */    NULL,       NULL,       NULL,       NULL,
04188 /* E8 */    NULL,       NULL,       NULL,       NULL,
04189 /* EC */    NULL,       NULL,       NULL,       NULL,
04190 /* F0 */    NULL,       NULL,       NULL,       NULL,
04191 /* F4 */    NULL,       NULL,       NULL,       NULL,
04192 /* F8 */    NULL,       NULL,       NULL,       NULL,
04193 /* FC */    NULL,       NULL,       NULL,       NULL,
04194 };
04195 
04196 static void
04197 OP_3DNowSuffix (bytemode, sizeflag)
04198      int bytemode ATTRIBUTE_UNUSED;
04199      int sizeflag ATTRIBUTE_UNUSED;
04200 {
04201   const char *mnemonic;
04202 
04203   FETCH_DATA (the_info, codep + 1);
04204   /* AMD 3DNow! instructions are specified by an opcode suffix in the
04205      place where an 8-bit immediate would normally go.  ie. the last
04206      byte of the instruction.  */
04207   obufp = obuf + strlen (obuf);
04208   mnemonic = Suffix3DNow[*codep++ & 0xff];
04209   if (mnemonic)
04210     oappend (mnemonic);
04211   else
04212     {
04213       /* Since a variable sized modrm/sib chunk is between the start
04214      of the opcode (0x0f0f) and the opcode suffix, we need to do
04215      all the modrm processing first, and don't know until now that
04216      we have a bad opcode.  This necessitates some cleaning up.  */
04217       op1out[0] = '\0';
04218       op2out[0] = '\0';
04219       BadOp ();
04220     }
04221 }
04222 
04223 static const char *simd_cmp_op[] = {
04224   "eq",
04225   "lt",
04226   "le",
04227   "unord",
04228   "neq",
04229   "nlt",
04230   "nle",
04231   "ord"
04232 };
04233 
04234 static void
04235 OP_SIMD_Suffix (bytemode, sizeflag)
04236      int bytemode ATTRIBUTE_UNUSED;
04237      int sizeflag ATTRIBUTE_UNUSED;
04238 {
04239   unsigned int cmp_type;
04240 
04241   FETCH_DATA (the_info, codep + 1);
04242   obufp = obuf + strlen (obuf);
04243   cmp_type = *codep++ & 0xff;
04244   if (cmp_type < 8)
04245     {
04246       char suffix1 = 'p', suffix2 = 's';
04247       used_prefixes |= (prefixes & PREFIX_REPZ);
04248       if (prefixes & PREFIX_REPZ)
04249     suffix1 = 's';
04250       else
04251     {
04252       used_prefixes |= (prefixes & PREFIX_DATA);
04253       if (prefixes & PREFIX_DATA)
04254         suffix2 = 'd';
04255       else
04256         {
04257           used_prefixes |= (prefixes & PREFIX_REPNZ);
04258           if (prefixes & PREFIX_REPNZ)
04259         suffix1 = 's', suffix2 = 'd';
04260         }
04261     }
04262       sprintf (scratchbuf, "cmp%s%c%c",
04263            simd_cmp_op[cmp_type], suffix1, suffix2);
04264       used_prefixes |= (prefixes & PREFIX_REPZ);
04265       oappend (scratchbuf);
04266     }
04267   else
04268     {
04269       /* We have a bad extension byte.  Clean up.  */
04270       op1out[0] = '\0';
04271       op2out[0] = '\0';
04272       BadOp ();
04273     }
04274 }
04275 
04276 static void
04277 SIMD_Fixup (extrachar, sizeflag)
04278      int extrachar;
04279      int sizeflag ATTRIBUTE_UNUSED;
04280 {
04281   /* Change movlps/movhps to movhlps/movlhps for 2 register operand
04282      forms of these instructions.  */
04283   if (mod == 3)
04284     {
04285       char *p = obuf + strlen (obuf);
04286       *(p + 1) = '\0';
04287       *p       = *(p - 1);
04288       *(p - 1) = *(p - 2);
04289       *(p - 2) = *(p - 3);
04290       *(p - 3) = extrachar;
04291     }
04292 }
04293 
04294 static void
04295 BadOp (void)
04296 {
04297   /* Throw away prefixes and 1st. opcode byte.  */
04298   codep = insn_codep + 1;
04299   oappend ("(bad)");
04300 }

Generated on Sat May 26 2012 04:36:16 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.