File:  [Qemu by Fabrice Bellard] / qemu / i386-dis.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:50:54 2018 UTC (2 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.0

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

unix.superglobalmegacorp.com