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

Generated on Sun May 27 2012 04:37:28 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.