133965Sjdp/* Print i386 instructions for GDB, the GNU debugger.
277298Sobrien   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
433965Sjdp
5218822Sdim   This file is part of GDB.
633965Sjdp
7218822Sdim   This program is free software; you can redistribute it and/or modify
8218822Sdim   it under the terms of the GNU General Public License as published by
9218822Sdim   the Free Software Foundation; either version 2 of the License, or
10218822Sdim   (at your option) any later version.
1133965Sjdp
12218822Sdim   This program is distributed in the hope that it will be useful,
13218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
14218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15218822Sdim   GNU General Public License for more details.
1633965Sjdp
17218822Sdim   You should have received a copy of the GNU General Public License
18218822Sdim   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2033965Sjdp
21218822Sdim/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22218822Sdim   July 1988
23218822Sdim    modified by John Hassey (hassey@dg-rtp.dg.com)
24218822Sdim    x86-64 support added by Jan Hubicka (jh@suse.cz)
25218822Sdim    VIA PadLock support by Michal Ludvig (mludvig@suse.cz).  */
2633965Sjdp
27218822Sdim/* The main tables describing the instructions is essentially a copy
28218822Sdim   of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29218822Sdim   Programmers Manual.  Usually, there is a capital letter, followed
30218822Sdim   by a small letter.  The capital letter tell the addressing mode,
31218822Sdim   and the small letter tells about the operand size.  Refer to
32218822Sdim   the Intel manual for details.  */
3333965Sjdp
3433965Sjdp#include "dis-asm.h"
3533965Sjdp#include "sysdep.h"
3660484Sobrien#include "opintl.h"
37218822Sdim#include "opcode/i386.h"
3833965Sjdp
3933965Sjdp#include <setjmp.h>
4033965Sjdp
41130561Sobrienstatic int fetch_data (struct disassemble_info *, bfd_byte *);
42130561Sobrienstatic void ckprefix (void);
43130561Sobrienstatic const char *prefix_name (int, int);
44130561Sobrienstatic int print_insn (bfd_vma, disassemble_info *);
45130561Sobrienstatic void dofloat (int);
46130561Sobrienstatic void OP_ST (int, int);
47130561Sobrienstatic void OP_STi (int, int);
48130561Sobrienstatic int putop (const char *, int);
49130561Sobrienstatic void oappend (const char *);
50130561Sobrienstatic void append_seg (void);
51130561Sobrienstatic void OP_indirE (int, int);
52130561Sobrienstatic void print_operand_value (char *, int, bfd_vma);
53218822Sdimstatic void print_displacement (char *, bfd_vma);
54130561Sobrienstatic void OP_E (int, int);
55130561Sobrienstatic void OP_G (int, int);
56130561Sobrienstatic bfd_vma get64 (void);
57130561Sobrienstatic bfd_signed_vma get32 (void);
58130561Sobrienstatic bfd_signed_vma get32s (void);
59130561Sobrienstatic int get16 (void);
60130561Sobrienstatic void set_op (bfd_vma, int);
61130561Sobrienstatic void OP_REG (int, int);
62130561Sobrienstatic void OP_IMREG (int, int);
63130561Sobrienstatic void OP_I (int, int);
64130561Sobrienstatic void OP_I64 (int, int);
65130561Sobrienstatic void OP_sI (int, int);
66130561Sobrienstatic void OP_J (int, int);
67130561Sobrienstatic void OP_SEG (int, int);
68130561Sobrienstatic void OP_DIR (int, int);
69130561Sobrienstatic void OP_OFF (int, int);
70130561Sobrienstatic void OP_OFF64 (int, int);
71130561Sobrienstatic void ptr_reg (int, int);
72130561Sobrienstatic void OP_ESreg (int, int);
73130561Sobrienstatic void OP_DSreg (int, int);
74130561Sobrienstatic void OP_C (int, int);
75130561Sobrienstatic void OP_D (int, int);
76130561Sobrienstatic void OP_T (int, int);
77218822Sdimstatic void OP_R (int, int);
78130561Sobrienstatic void OP_MMX (int, int);
79130561Sobrienstatic void OP_XMM (int, int);
80130561Sobrienstatic void OP_EM (int, int);
81130561Sobrienstatic void OP_EX (int, int);
82218822Sdimstatic void OP_EMC (int,int);
83218822Sdimstatic void OP_MXC (int,int);
84130561Sobrienstatic void OP_MS (int, int);
85130561Sobrienstatic void OP_XS (int, int);
86130561Sobrienstatic void OP_M (int, int);
87218822Sdimstatic void OP_VMX (int, int);
88130561Sobrienstatic void OP_0fae (int, int);
89130561Sobrienstatic void OP_0f07 (int, int);
90218822Sdimstatic void NOP_Fixup1 (int, int);
91218822Sdimstatic void NOP_Fixup2 (int, int);
92130561Sobrienstatic void OP_3DNowSuffix (int, int);
93130561Sobrienstatic void OP_SIMD_Suffix (int, int);
94130561Sobrienstatic void SIMD_Fixup (int, int);
95130561Sobrienstatic void PNI_Fixup (int, int);
96238123Sjhbstatic void XCR_Fixup (int, int);
97218822Sdimstatic void SVME_Fixup (int, int);
98130561Sobrienstatic void INVLPG_Fixup (int, int);
99130561Sobrienstatic void BadOp (void);
100218822Sdimstatic void VMX_Fixup (int, int);
101218822Sdimstatic void REP_Fixup (int, int);
102218822Sdimstatic void CMPXCHG8B_Fixup (int, int);
103218822Sdimstatic void XMM_Fixup (int, int);
104218822Sdimstatic void CRC32_Fixup (int, int);
10533965Sjdp
10685815Sobrienstruct dis_private {
10733965Sjdp  /* Points to first byte not fetched.  */
10833965Sjdp  bfd_byte *max_fetched;
109218822Sdim  bfd_byte the_buffer[MAX_MNEM_SIZE];
11033965Sjdp  bfd_vma insn_start;
11189857Sobrien  int orig_sizeflag;
11233965Sjdp  jmp_buf bailout;
11333965Sjdp};
11433965Sjdp
115218822Sdimenum address_mode
116218822Sdim{
117218822Sdim  mode_16bit,
118218822Sdim  mode_32bit,
119218822Sdim  mode_64bit
120218822Sdim};
12160484Sobrien
122218822Sdimenum address_mode address_mode;
12377298Sobrien
12460484Sobrien/* Flags for the prefixes for the current instruction.  See below.  */
12560484Sobrienstatic int prefixes;
12660484Sobrien
12777298Sobrien/* REX prefix the current instruction.  See below.  */
12877298Sobrienstatic int rex;
12977298Sobrien/* Bits of REX we've already used.  */
13077298Sobrienstatic int rex_used;
13177298Sobrien/* Mark parts used in the REX prefix.  When we are testing for
13277298Sobrien   empty prefix (for 8bit register REX extension), just mask it
13377298Sobrien   out.  Otherwise test for REX bit is excuse for existence of REX
13477298Sobrien   only in case value is nonzero.  */
13577298Sobrien#define USED_REX(value)					\
13677298Sobrien  {							\
13777298Sobrien    if (value)						\
138218822Sdim      {							\
139218822Sdim	if ((rex & value))				\
140218822Sdim	  rex_used |= (value) | REX_OPCODE;		\
141218822Sdim      }							\
14277298Sobrien    else						\
143218822Sdim      rex_used |= REX_OPCODE;				\
14477298Sobrien  }
14577298Sobrien
14660484Sobrien/* Flags for prefixes which we somehow handled when printing the
14760484Sobrien   current instruction.  */
14860484Sobrienstatic int used_prefixes;
14960484Sobrien
15060484Sobrien/* Flags stored in PREFIXES.  */
15160484Sobrien#define PREFIX_REPZ 1
15260484Sobrien#define PREFIX_REPNZ 2
15360484Sobrien#define PREFIX_LOCK 4
15460484Sobrien#define PREFIX_CS 8
15560484Sobrien#define PREFIX_SS 0x10
15660484Sobrien#define PREFIX_DS 0x20
15760484Sobrien#define PREFIX_ES 0x40
15860484Sobrien#define PREFIX_FS 0x80
15960484Sobrien#define PREFIX_GS 0x100
16060484Sobrien#define PREFIX_DATA 0x200
16160484Sobrien#define PREFIX_ADDR 0x400
16260484Sobrien#define PREFIX_FWAIT 0x800
16360484Sobrien
16433965Sjdp/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
16533965Sjdp   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
16633965Sjdp   on error.  */
16733965Sjdp#define FETCH_DATA(info, addr) \
16885815Sobrien  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
16933965Sjdp   ? 1 : fetch_data ((info), (addr)))
17033965Sjdp
17133965Sjdpstatic int
172130561Sobrienfetch_data (struct disassemble_info *info, bfd_byte *addr)
17333965Sjdp{
17433965Sjdp  int status;
17585815Sobrien  struct dis_private *priv = (struct dis_private *) info->private_data;
17633965Sjdp  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
17733965Sjdp
178218822Sdim  if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
179218822Sdim    status = (*info->read_memory_func) (start,
180218822Sdim					priv->max_fetched,
181218822Sdim					addr - priv->max_fetched,
182218822Sdim					info);
183218822Sdim  else
184218822Sdim    status = -1;
18533965Sjdp  if (status != 0)
18633965Sjdp    {
18760484Sobrien      /* If we did manage to read at least one byte, then
188130561Sobrien	 print_insn_i386 will do something sensible.  Otherwise, print
189130561Sobrien	 an error.  We do that here because this is where we know
190130561Sobrien	 STATUS.  */
19160484Sobrien      if (priv->max_fetched == priv->the_buffer)
19260484Sobrien	(*info->memory_error_func) (status, start, info);
19333965Sjdp      longjmp (priv->bailout, 1);
19433965Sjdp    }
19533965Sjdp  else
19633965Sjdp    priv->max_fetched = addr;
19733965Sjdp  return 1;
19833965Sjdp}
19933965Sjdp
200218822Sdim#define XX { NULL, 0 }
20160484Sobrien
202218822Sdim#define Eb { OP_E, b_mode }
203218822Sdim#define Ev { OP_E, v_mode }
204218822Sdim#define Ed { OP_E, d_mode }
205218822Sdim#define Edq { OP_E, dq_mode }
206218822Sdim#define Edqw { OP_E, dqw_mode }
207218822Sdim#define Edqb { OP_E, dqb_mode }
208218822Sdim#define Edqd { OP_E, dqd_mode }
209218822Sdim#define indirEv { OP_indirE, stack_v_mode }
210218822Sdim#define indirEp { OP_indirE, f_mode }
211218822Sdim#define stackEv { OP_E, stack_v_mode }
212218822Sdim#define Em { OP_E, m_mode }
213218822Sdim#define Ew { OP_E, w_mode }
214218822Sdim#define M { OP_M, 0 }		/* lea, lgdt, etc. */
215218822Sdim#define Ma { OP_M, v_mode }
216238167Sjhb#define Mo { OP_M, o_mode }
217218822Sdim#define Mp { OP_M, f_mode }		/* 32 or 48 bit memory operand for LDS, LES etc */
218218822Sdim#define Mq { OP_M, q_mode }
219218822Sdim#define Gb { OP_G, b_mode }
220218822Sdim#define Gv { OP_G, v_mode }
221218822Sdim#define Gd { OP_G, d_mode }
222218822Sdim#define Gdq { OP_G, dq_mode }
223218822Sdim#define Gm { OP_G, m_mode }
224218822Sdim#define Gw { OP_G, w_mode }
225218822Sdim#define Rd { OP_R, d_mode }
226218822Sdim#define Rm { OP_R, m_mode }
227218822Sdim#define Ib { OP_I, b_mode }
228218822Sdim#define sIb { OP_sI, b_mode }	/* sign extened byte */
229218822Sdim#define Iv { OP_I, v_mode }
230218822Sdim#define Iq { OP_I, q_mode }
231218822Sdim#define Iv64 { OP_I64, v_mode }
232218822Sdim#define Iw { OP_I, w_mode }
233218822Sdim#define I1 { OP_I, const_1_mode }
234218822Sdim#define Jb { OP_J, b_mode }
235218822Sdim#define Jv { OP_J, v_mode }
236218822Sdim#define Cm { OP_C, m_mode }
237218822Sdim#define Dm { OP_D, m_mode }
238218822Sdim#define Td { OP_T, d_mode }
23933965Sjdp
240218822Sdim#define RMeAX { OP_REG, eAX_reg }
241218822Sdim#define RMeBX { OP_REG, eBX_reg }
242218822Sdim#define RMeCX { OP_REG, eCX_reg }
243218822Sdim#define RMeDX { OP_REG, eDX_reg }
244218822Sdim#define RMeSP { OP_REG, eSP_reg }
245218822Sdim#define RMeBP { OP_REG, eBP_reg }
246218822Sdim#define RMeSI { OP_REG, eSI_reg }
247218822Sdim#define RMeDI { OP_REG, eDI_reg }
248218822Sdim#define RMrAX { OP_REG, rAX_reg }
249218822Sdim#define RMrBX { OP_REG, rBX_reg }
250218822Sdim#define RMrCX { OP_REG, rCX_reg }
251218822Sdim#define RMrDX { OP_REG, rDX_reg }
252218822Sdim#define RMrSP { OP_REG, rSP_reg }
253218822Sdim#define RMrBP { OP_REG, rBP_reg }
254218822Sdim#define RMrSI { OP_REG, rSI_reg }
255218822Sdim#define RMrDI { OP_REG, rDI_reg }
256218822Sdim#define RMAL { OP_REG, al_reg }
257218822Sdim#define RMAL { OP_REG, al_reg }
258218822Sdim#define RMCL { OP_REG, cl_reg }
259218822Sdim#define RMDL { OP_REG, dl_reg }
260218822Sdim#define RMBL { OP_REG, bl_reg }
261218822Sdim#define RMAH { OP_REG, ah_reg }
262218822Sdim#define RMCH { OP_REG, ch_reg }
263218822Sdim#define RMDH { OP_REG, dh_reg }
264218822Sdim#define RMBH { OP_REG, bh_reg }
265218822Sdim#define RMAX { OP_REG, ax_reg }
266218822Sdim#define RMDX { OP_REG, dx_reg }
26733965Sjdp
268218822Sdim#define eAX { OP_IMREG, eAX_reg }
269218822Sdim#define eBX { OP_IMREG, eBX_reg }
270218822Sdim#define eCX { OP_IMREG, eCX_reg }
271218822Sdim#define eDX { OP_IMREG, eDX_reg }
272218822Sdim#define eSP { OP_IMREG, eSP_reg }
273218822Sdim#define eBP { OP_IMREG, eBP_reg }
274218822Sdim#define eSI { OP_IMREG, eSI_reg }
275218822Sdim#define eDI { OP_IMREG, eDI_reg }
276218822Sdim#define AL { OP_IMREG, al_reg }
277218822Sdim#define CL { OP_IMREG, cl_reg }
278218822Sdim#define DL { OP_IMREG, dl_reg }
279218822Sdim#define BL { OP_IMREG, bl_reg }
280218822Sdim#define AH { OP_IMREG, ah_reg }
281218822Sdim#define CH { OP_IMREG, ch_reg }
282218822Sdim#define DH { OP_IMREG, dh_reg }
283218822Sdim#define BH { OP_IMREG, bh_reg }
284218822Sdim#define AX { OP_IMREG, ax_reg }
285218822Sdim#define DX { OP_IMREG, dx_reg }
286218822Sdim#define zAX { OP_IMREG, z_mode_ax_reg }
287218822Sdim#define indirDX { OP_IMREG, indir_dx_reg }
28877298Sobrien
289218822Sdim#define Sw { OP_SEG, w_mode }
290218822Sdim#define Sv { OP_SEG, v_mode }
291218822Sdim#define Ap { OP_DIR, 0 }
292218822Sdim#define Ob { OP_OFF64, b_mode }
293218822Sdim#define Ov { OP_OFF64, v_mode }
294218822Sdim#define Xb { OP_DSreg, eSI_reg }
295218822Sdim#define Xv { OP_DSreg, eSI_reg }
296218822Sdim#define Xz { OP_DSreg, eSI_reg }
297218822Sdim#define Yb { OP_ESreg, eDI_reg }
298218822Sdim#define Yv { OP_ESreg, eDI_reg }
299218822Sdim#define DSBX { OP_DSreg, eBX_reg }
30033965Sjdp
301218822Sdim#define es { OP_REG, es_reg }
302218822Sdim#define ss { OP_REG, ss_reg }
303218822Sdim#define cs { OP_REG, cs_reg }
304218822Sdim#define ds { OP_REG, ds_reg }
305218822Sdim#define fs { OP_REG, fs_reg }
306218822Sdim#define gs { OP_REG, gs_reg }
30733965Sjdp
308218822Sdim#define MX { OP_MMX, 0 }
309218822Sdim#define XM { OP_XMM, 0 }
310218822Sdim#define EM { OP_EM, v_mode }
311218822Sdim#define EMd { OP_EM, d_mode }
312218822Sdim#define EMq { OP_EM, q_mode }
313218822Sdim#define EXd { OP_EX, d_mode }
314218822Sdim#define EXq { OP_EX, q_mode }
315218822Sdim#define EXx { OP_EX, x_mode }
316218822Sdim#define MS { OP_MS, v_mode }
317218822Sdim#define XS { OP_XS, v_mode }
318218822Sdim#define EMC { OP_EMC, v_mode }
319218822Sdim#define MXC { OP_MXC, 0 }
320218822Sdim#define VM { OP_VMX, q_mode }
321218822Sdim#define OPSUF { OP_3DNowSuffix, 0 }
322218822Sdim#define OPSIMD { OP_SIMD_Suffix, 0 }
323218822Sdim#define XMM0 { XMM_Fixup, 0 }
32433965Sjdp
325218822Sdim/* Used handle "rep" prefix for string instructions.  */
326218822Sdim#define Xbr { REP_Fixup, eSI_reg }
327218822Sdim#define Xvr { REP_Fixup, eSI_reg }
328218822Sdim#define Ybr { REP_Fixup, eDI_reg }
329218822Sdim#define Yvr { REP_Fixup, eDI_reg }
330218822Sdim#define Yzr { REP_Fixup, eDI_reg }
331218822Sdim#define indirDXr { REP_Fixup, indir_dx_reg }
332218822Sdim#define ALr { REP_Fixup, al_reg }
333218822Sdim#define eAXr { REP_Fixup, eAX_reg }
33478828Sobrien
335218822Sdim#define cond_jump_flag { NULL, cond_jump_mode }
336218822Sdim#define loop_jcxz_flag { NULL, loop_jcxz_mode }
337218822Sdim
33860484Sobrien/* bits in sizeflag */
33960484Sobrien#define SUFFIX_ALWAYS 4
34060484Sobrien#define AFLAG 2
34160484Sobrien#define DFLAG 1
34233965Sjdp
34377298Sobrien#define b_mode 1  /* byte operand */
34477298Sobrien#define v_mode 2  /* operand size depends on prefixes */
34577298Sobrien#define w_mode 3  /* word operand */
34677298Sobrien#define d_mode 4  /* double word operand  */
34777298Sobrien#define q_mode 5  /* quad word operand */
348218822Sdim#define t_mode 6  /* ten-byte operand */
349218822Sdim#define x_mode 7  /* 16-byte XMM operand */
350218822Sdim#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
351218822Sdim#define cond_jump_mode 9
352218822Sdim#define loop_jcxz_mode 10
353218822Sdim#define dq_mode 11 /* operand size depends on REX prefixes.  */
354218822Sdim#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
355218822Sdim#define f_mode 13 /* 4- or 6-byte pointer operand */
356218822Sdim#define const_1_mode 14
357218822Sdim#define stack_v_mode 15 /* v_mode for stack-related opcodes.  */
358218822Sdim#define z_mode 16 /* non-quad operand size depends on prefixes */
359218822Sdim#define o_mode 17  /* 16-byte operand */
360218822Sdim#define dqb_mode 18 /* registers like dq_mode, memory like b_mode.  */
361218822Sdim#define dqd_mode 19 /* registers like dq_mode, memory like d_mode.  */
36233965Sjdp
36333965Sjdp#define es_reg 100
36433965Sjdp#define cs_reg 101
36533965Sjdp#define ss_reg 102
36633965Sjdp#define ds_reg 103
36733965Sjdp#define fs_reg 104
36833965Sjdp#define gs_reg 105
36933965Sjdp
37060484Sobrien#define eAX_reg 108
37160484Sobrien#define eCX_reg 109
37260484Sobrien#define eDX_reg 110
37360484Sobrien#define eBX_reg 111
37460484Sobrien#define eSP_reg 112
37560484Sobrien#define eBP_reg 113
37660484Sobrien#define eSI_reg 114
37760484Sobrien#define eDI_reg 115
37833965Sjdp
37933965Sjdp#define al_reg 116
38033965Sjdp#define cl_reg 117
38133965Sjdp#define dl_reg 118
38233965Sjdp#define bl_reg 119
38333965Sjdp#define ah_reg 120
38433965Sjdp#define ch_reg 121
38533965Sjdp#define dh_reg 122
38633965Sjdp#define bh_reg 123
38733965Sjdp
38833965Sjdp#define ax_reg 124
38933965Sjdp#define cx_reg 125
39033965Sjdp#define dx_reg 126
39133965Sjdp#define bx_reg 127
39233965Sjdp#define sp_reg 128
39333965Sjdp#define bp_reg 129
39433965Sjdp#define si_reg 130
39533965Sjdp#define di_reg 131
39633965Sjdp
39777298Sobrien#define rAX_reg 132
39877298Sobrien#define rCX_reg 133
39977298Sobrien#define rDX_reg 134
40077298Sobrien#define rBX_reg 135
40177298Sobrien#define rSP_reg 136
40277298Sobrien#define rBP_reg 137
40377298Sobrien#define rSI_reg 138
40477298Sobrien#define rDI_reg 139
40577298Sobrien
406218822Sdim#define z_mode_ax_reg 149
40733965Sjdp#define indir_dx_reg 150
40833965Sjdp
40985815Sobrien#define FLOATCODE 1
41085815Sobrien#define USE_GROUPS 2
41185815Sobrien#define USE_PREFIX_USER_TABLE 3
41285815Sobrien#define X86_64_SPECIAL 4
413218822Sdim#define IS_3BYTE_OPCODE 5
41433965Sjdp
415218822Sdim#define FLOAT	  NULL, { { NULL, FLOATCODE } }
41660484Sobrien
417218822Sdim#define GRP1a	  NULL, { { NULL, USE_GROUPS }, { NULL,  0 } }
418218822Sdim#define GRP1b	  NULL, { { NULL, USE_GROUPS }, { NULL,  1 } }
419218822Sdim#define GRP1S	  NULL, { { NULL, USE_GROUPS }, { NULL,  2 } }
420218822Sdim#define GRP1Ss	  NULL, { { NULL, USE_GROUPS }, { NULL,  3 } }
421218822Sdim#define GRP2b	  NULL, { { NULL, USE_GROUPS }, { NULL,  4 } }
422218822Sdim#define GRP2S	  NULL, { { NULL, USE_GROUPS }, { NULL,  5 } }
423218822Sdim#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL,  6 } }
424218822Sdim#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL,  7 } }
425218822Sdim#define GRP2b_cl  NULL, { { NULL, USE_GROUPS }, { NULL,  8 } }
426218822Sdim#define GRP2S_cl  NULL, { { NULL, USE_GROUPS }, { NULL,  9 } }
427218822Sdim#define GRP3b	  NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
428218822Sdim#define GRP3S	  NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
429218822Sdim#define GRP4	  NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
430218822Sdim#define GRP5	  NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
431218822Sdim#define GRP6	  NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
432218822Sdim#define GRP7	  NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
433218822Sdim#define GRP8	  NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
434218822Sdim#define GRP9	  NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
435218822Sdim#define GRP11_C6  NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
436218822Sdim#define GRP11_C7  NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
437218822Sdim#define GRP12	  NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
438218822Sdim#define GRP13	  NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
439218822Sdim#define GRP14	  NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
440218822Sdim#define GRP15	  NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
441218822Sdim#define GRP16	  NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
442218822Sdim#define GRPAMD	  NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
443218822Sdim#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
444218822Sdim#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
44560484Sobrien
446218822Sdim#define PREGRP0   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  0 } }
447218822Sdim#define PREGRP1   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  1 } }
448218822Sdim#define PREGRP2   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  2 } }
449218822Sdim#define PREGRP3   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  3 } }
450218822Sdim#define PREGRP4   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  4 } }
451218822Sdim#define PREGRP5   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  5 } }
452218822Sdim#define PREGRP6   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  6 } }
453218822Sdim#define PREGRP7   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  7 } }
454218822Sdim#define PREGRP8   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  8 } }
455218822Sdim#define PREGRP9   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  9 } }
456218822Sdim#define PREGRP10  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
457218822Sdim#define PREGRP11  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
458218822Sdim#define PREGRP12  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
459218822Sdim#define PREGRP13  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
460218822Sdim#define PREGRP14  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
461218822Sdim#define PREGRP15  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
462218822Sdim#define PREGRP16  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
463218822Sdim#define PREGRP17  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
464218822Sdim#define PREGRP18  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
465218822Sdim#define PREGRP19  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
466218822Sdim#define PREGRP20  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
467218822Sdim#define PREGRP21  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
468218822Sdim#define PREGRP22  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
469218822Sdim#define PREGRP23  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
470218822Sdim#define PREGRP24  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
471218822Sdim#define PREGRP25  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
472218822Sdim#define PREGRP26  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
473218822Sdim#define PREGRP27  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
474218822Sdim#define PREGRP28  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
475218822Sdim#define PREGRP29  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
476218822Sdim#define PREGRP30  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
477218822Sdim#define PREGRP31  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
478218822Sdim#define PREGRP32  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
479218822Sdim#define PREGRP33  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
480218822Sdim#define PREGRP34  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
481218822Sdim#define PREGRP35  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
482218822Sdim#define PREGRP36  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
483218822Sdim#define PREGRP37  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
484218822Sdim#define PREGRP38  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
485218822Sdim#define PREGRP39  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
486218822Sdim#define PREGRP40  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
487218822Sdim#define PREGRP41  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
488218822Sdim#define PREGRP42  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
489218822Sdim#define PREGRP43  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
490218822Sdim#define PREGRP44  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
491218822Sdim#define PREGRP45  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
492218822Sdim#define PREGRP46  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
493218822Sdim#define PREGRP47  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
494218822Sdim#define PREGRP48  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
495218822Sdim#define PREGRP49  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
496218822Sdim#define PREGRP50  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
497218822Sdim#define PREGRP51  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
498218822Sdim#define PREGRP52  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
499218822Sdim#define PREGRP53  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
500218822Sdim#define PREGRP54  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
501218822Sdim#define PREGRP55  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
502218822Sdim#define PREGRP56  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
503218822Sdim#define PREGRP57  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
504218822Sdim#define PREGRP58  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
505218822Sdim#define PREGRP59  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
506218822Sdim#define PREGRP60  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
507218822Sdim#define PREGRP61  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
508218822Sdim#define PREGRP62  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
509218822Sdim#define PREGRP63  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
510218822Sdim#define PREGRP64  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
511218822Sdim#define PREGRP65  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
512218822Sdim#define PREGRP66  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
513218822Sdim#define PREGRP67  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
514218822Sdim#define PREGRP68  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
515218822Sdim#define PREGRP69  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
516218822Sdim#define PREGRP70  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
517218822Sdim#define PREGRP71  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
518218822Sdim#define PREGRP72  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
519218822Sdim#define PREGRP73  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
520218822Sdim#define PREGRP74  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
521218822Sdim#define PREGRP75  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
522218822Sdim#define PREGRP76  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
523218822Sdim#define PREGRP77  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
524218822Sdim#define PREGRP78  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
525218822Sdim#define PREGRP79  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
526218822Sdim#define PREGRP80  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
527218822Sdim#define PREGRP81  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
528218822Sdim#define PREGRP82  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
529218822Sdim#define PREGRP83  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
530218822Sdim#define PREGRP84  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
531218822Sdim#define PREGRP85  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
532218822Sdim#define PREGRP86  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
533218822Sdim#define PREGRP87  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
534218822Sdim#define PREGRP88  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
535218822Sdim#define PREGRP89  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
536218822Sdim#define PREGRP90  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
537218822Sdim#define PREGRP91  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
538218822Sdim#define PREGRP92  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
539218822Sdim#define PREGRP93  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
540218822Sdim#define PREGRP94  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
541218822Sdim#define PREGRP95  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
542218822Sdim#define PREGRP96  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
543218822Sdim#define PREGRP97  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
544238167Sjhb#define PREGRP98  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
545238167Sjhb#define PREGRP99  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
546247012Sjmg#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
547247012Sjmg#define PREGRP101 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 101 } }
548247012Sjmg#define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
549247012Sjmg#define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
550247012Sjmg#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
551247012Sjmg#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
552247012Sjmg#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
553255192Sjhb#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } }
55433965Sjdp
55585815Sobrien
556218822Sdim#define X86_64_0  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
557218822Sdim#define X86_64_1  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
558218822Sdim#define X86_64_2  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
559218822Sdim#define X86_64_3  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
560218822Sdim
561218822Sdim#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
562218822Sdim#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
563218822Sdim
564130561Sobrientypedef void (*op_rtn) (int bytemode, int sizeflag);
56585815Sobrien
56633965Sjdpstruct dis386 {
56760484Sobrien  const char *name;
568218822Sdim  struct
569218822Sdim    {
570218822Sdim      op_rtn rtn;
571218822Sdim      int bytemode;
572218822Sdim    } op[MAX_OPERANDS];
57333965Sjdp};
57433965Sjdp
57560484Sobrien/* Upper case letters in the instruction names here are macros.
57660484Sobrien   'A' => print 'b' if no register operands or suffix_always is true
57760484Sobrien   'B' => print 'b' if suffix_always is true
578218822Sdim   'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
579218822Sdim   .      size prefix
580218822Sdim   'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
581218822Sdim   .      suffix_always is true
58260484Sobrien   'E' => print 'e' if 32-bit form of jcxz
58378828Sobrien   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
584218822Sdim   'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
58585815Sobrien   'H' => print ",pt" or ",pn" branch hint
586218822Sdim   'I' => honor following macro letter even in Intel mode (implemented only
587218822Sdim   .      for some of the macro letters)
588218822Sdim   'J' => print 'l'
589218822Sdim   'K' => print 'd' or 'q' if rex prefix is present.
59060484Sobrien   'L' => print 'l' if suffix_always is true
59160484Sobrien   'N' => print 'n' if instruction has no wait "prefix"
592218822Sdim   'O' => print 'd' or 'o' (or 'q' in Intel mode)
59377298Sobrien   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
59489857Sobrien   .      or suffix_always is true.  print 'q' if rex prefix is present.
59589857Sobrien   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
59689857Sobrien   .      is true
597218822Sdim   'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
59877298Sobrien   'S' => print 'w', 'l' or 'q' if suffix_always is true
59985815Sobrien   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
60085815Sobrien   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
601218822Sdim   'V' => print 'q' in 64bit mode and behave as 'S' otherwise
602218822Sdim   'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
60377298Sobrien   'X' => print 's', 'd' depending on data16 prefix (for XMM)
60477298Sobrien   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
605218822Sdim   'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
60660484Sobrien
60785815Sobrien   Many of the above letters print nothing in Intel mode.  See "putop"
60885815Sobrien   for the details.
60933965Sjdp
61085815Sobrien   Braces '{' and '}', and vertical bars '|', indicate alternative
61185815Sobrien   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
61285815Sobrien   modes.  In cases where there are only two alternatives, the X86_64
61385815Sobrien   instruction is reserved, and "(bad)" is printed.
61485815Sobrien*/
61560484Sobrien
61685815Sobrienstatic const struct dis386 dis386[] = {
61777298Sobrien  /* 00 */
618218822Sdim  { "addB",		{ Eb, Gb } },
619218822Sdim  { "addS",		{ Ev, Gv } },
620218822Sdim  { "addB",		{ Gb, Eb } },
621218822Sdim  { "addS",		{ Gv, Ev } },
622218822Sdim  { "addB",		{ AL, Ib } },
623218822Sdim  { "addS",		{ eAX, Iv } },
624218822Sdim  { "push{T|}",		{ es } },
625218822Sdim  { "pop{T|}",		{ es } },
62677298Sobrien  /* 08 */
627218822Sdim  { "orB",		{ Eb, Gb } },
628218822Sdim  { "orS",		{ Ev, Gv } },
629218822Sdim  { "orB",		{ Gb, Eb } },
630218822Sdim  { "orS",		{ Gv, Ev } },
631218822Sdim  { "orB",		{ AL, Ib } },
632218822Sdim  { "orS",		{ eAX, Iv } },
633218822Sdim  { "push{T|}",		{ cs } },
634218822Sdim  { "(bad)",		{ XX } },	/* 0x0f extended opcode escape */
63577298Sobrien  /* 10 */
636218822Sdim  { "adcB",		{ Eb, Gb } },
637218822Sdim  { "adcS",		{ Ev, Gv } },
638218822Sdim  { "adcB",		{ Gb, Eb } },
639218822Sdim  { "adcS",		{ Gv, Ev } },
640218822Sdim  { "adcB",		{ AL, Ib } },
641218822Sdim  { "adcS",		{ eAX, Iv } },
642218822Sdim  { "push{T|}",		{ ss } },
643218822Sdim  { "pop{T|}",		{ ss } },
64477298Sobrien  /* 18 */
645218822Sdim  { "sbbB",		{ Eb, Gb } },
646218822Sdim  { "sbbS",		{ Ev, Gv } },
647218822Sdim  { "sbbB",		{ Gb, Eb } },
648218822Sdim  { "sbbS",		{ Gv, Ev } },
649218822Sdim  { "sbbB",		{ AL, Ib } },
650218822Sdim  { "sbbS",		{ eAX, Iv } },
651218822Sdim  { "push{T|}",		{ ds } },
652218822Sdim  { "pop{T|}",		{ ds } },
65377298Sobrien  /* 20 */
654218822Sdim  { "andB",		{ Eb, Gb } },
655218822Sdim  { "andS",		{ Ev, Gv } },
656218822Sdim  { "andB",		{ Gb, Eb } },
657218822Sdim  { "andS",		{ Gv, Ev } },
658218822Sdim  { "andB",		{ AL, Ib } },
659218822Sdim  { "andS",		{ eAX, Iv } },
660218822Sdim  { "(bad)",		{ XX } },	/* SEG ES prefix */
661218822Sdim  { "daa{|}",		{ XX } },
66277298Sobrien  /* 28 */
663218822Sdim  { "subB",		{ Eb, Gb } },
664218822Sdim  { "subS",		{ Ev, Gv } },
665218822Sdim  { "subB",		{ Gb, Eb } },
666218822Sdim  { "subS",		{ Gv, Ev } },
667218822Sdim  { "subB",		{ AL, Ib } },
668218822Sdim  { "subS",		{ eAX, Iv } },
669218822Sdim  { "(bad)",		{ XX } },	/* SEG CS prefix */
670218822Sdim  { "das{|}",		{ XX } },
67177298Sobrien  /* 30 */
672218822Sdim  { "xorB",		{ Eb, Gb } },
673218822Sdim  { "xorS",		{ Ev, Gv } },
674218822Sdim  { "xorB",		{ Gb, Eb } },
675218822Sdim  { "xorS",		{ Gv, Ev } },
676218822Sdim  { "xorB",		{ AL, Ib } },
677218822Sdim  { "xorS",		{ eAX, Iv } },
678218822Sdim  { "(bad)",		{ XX } },	/* SEG SS prefix */
679218822Sdim  { "aaa{|}",		{ XX } },
68077298Sobrien  /* 38 */
681218822Sdim  { "cmpB",		{ Eb, Gb } },
682218822Sdim  { "cmpS",		{ Ev, Gv } },
683218822Sdim  { "cmpB",		{ Gb, Eb } },
684218822Sdim  { "cmpS",		{ Gv, Ev } },
685218822Sdim  { "cmpB",		{ AL, Ib } },
686218822Sdim  { "cmpS",		{ eAX, Iv } },
687218822Sdim  { "(bad)",		{ XX } },	/* SEG DS prefix */
688218822Sdim  { "aas{|}",		{ XX } },
68977298Sobrien  /* 40 */
690218822Sdim  { "inc{S|}",		{ RMeAX } },
691218822Sdim  { "inc{S|}",		{ RMeCX } },
692218822Sdim  { "inc{S|}",		{ RMeDX } },
693218822Sdim  { "inc{S|}",		{ RMeBX } },
694218822Sdim  { "inc{S|}",		{ RMeSP } },
695218822Sdim  { "inc{S|}",		{ RMeBP } },
696218822Sdim  { "inc{S|}",		{ RMeSI } },
697218822Sdim  { "inc{S|}",		{ RMeDI } },
69877298Sobrien  /* 48 */
699218822Sdim  { "dec{S|}",		{ RMeAX } },
700218822Sdim  { "dec{S|}",		{ RMeCX } },
701218822Sdim  { "dec{S|}",		{ RMeDX } },
702218822Sdim  { "dec{S|}",		{ RMeBX } },
703218822Sdim  { "dec{S|}",		{ RMeSP } },
704218822Sdim  { "dec{S|}",		{ RMeBP } },
705218822Sdim  { "dec{S|}",		{ RMeSI } },
706218822Sdim  { "dec{S|}",		{ RMeDI } },
70777298Sobrien  /* 50 */
708218822Sdim  { "pushV",		{ RMrAX } },
709218822Sdim  { "pushV",		{ RMrCX } },
710218822Sdim  { "pushV",		{ RMrDX } },
711218822Sdim  { "pushV",		{ RMrBX } },
712218822Sdim  { "pushV",		{ RMrSP } },
713218822Sdim  { "pushV",		{ RMrBP } },
714218822Sdim  { "pushV",		{ RMrSI } },
715218822Sdim  { "pushV",		{ RMrDI } },
71677298Sobrien  /* 58 */
717218822Sdim  { "popV",		{ RMrAX } },
718218822Sdim  { "popV",		{ RMrCX } },
719218822Sdim  { "popV",		{ RMrDX } },
720218822Sdim  { "popV",		{ RMrBX } },
721218822Sdim  { "popV",		{ RMrSP } },
722218822Sdim  { "popV",		{ RMrBP } },
723218822Sdim  { "popV",		{ RMrSI } },
724218822Sdim  { "popV",		{ RMrDI } },
72577298Sobrien  /* 60 */
72685815Sobrien  { X86_64_0 },
727218822Sdim  { X86_64_1 },
728218822Sdim  { X86_64_2 },
729218822Sdim  { X86_64_3 },
730218822Sdim  { "(bad)",		{ XX } },	/* seg fs */
731218822Sdim  { "(bad)",		{ XX } },	/* seg gs */
732218822Sdim  { "(bad)",		{ XX } },	/* op size prefix */
733218822Sdim  { "(bad)",		{ XX } },	/* adr size prefix */
73477298Sobrien  /* 68 */
735218822Sdim  { "pushT",		{ Iq } },
736218822Sdim  { "imulS",		{ Gv, Ev, Iv } },
737218822Sdim  { "pushT",		{ sIb } },
738218822Sdim  { "imulS",		{ Gv, Ev, sIb } },
739218822Sdim  { "ins{b||b|}",	{ Ybr, indirDX } },
740218822Sdim  { "ins{R||G|}",	{ Yzr, indirDX } },
741218822Sdim  { "outs{b||b|}",	{ indirDXr, Xb } },
742218822Sdim  { "outs{R||G|}",	{ indirDXr, Xz } },
74377298Sobrien  /* 70 */
744218822Sdim  { "joH",		{ Jb, XX, cond_jump_flag } },
745218822Sdim  { "jnoH",		{ Jb, XX, cond_jump_flag } },
746218822Sdim  { "jbH",		{ Jb, XX, cond_jump_flag } },
747218822Sdim  { "jaeH",		{ Jb, XX, cond_jump_flag } },
748218822Sdim  { "jeH",		{ Jb, XX, cond_jump_flag } },
749218822Sdim  { "jneH",		{ Jb, XX, cond_jump_flag } },
750218822Sdim  { "jbeH",		{ Jb, XX, cond_jump_flag } },
751218822Sdim  { "jaH",		{ Jb, XX, cond_jump_flag } },
75277298Sobrien  /* 78 */
753218822Sdim  { "jsH",		{ Jb, XX, cond_jump_flag } },
754218822Sdim  { "jnsH",		{ Jb, XX, cond_jump_flag } },
755218822Sdim  { "jpH",		{ Jb, XX, cond_jump_flag } },
756218822Sdim  { "jnpH",		{ Jb, XX, cond_jump_flag } },
757218822Sdim  { "jlH",		{ Jb, XX, cond_jump_flag } },
758218822Sdim  { "jgeH",		{ Jb, XX, cond_jump_flag } },
759218822Sdim  { "jleH",		{ Jb, XX, cond_jump_flag } },
760218822Sdim  { "jgH",		{ Jb, XX, cond_jump_flag } },
76177298Sobrien  /* 80 */
76277298Sobrien  { GRP1b },
76377298Sobrien  { GRP1S },
764218822Sdim  { "(bad)",		{ XX } },
76577298Sobrien  { GRP1Ss },
766218822Sdim  { "testB",		{ Eb, Gb } },
767218822Sdim  { "testS",		{ Ev, Gv } },
768218822Sdim  { "xchgB",		{ Eb, Gb } },
769218822Sdim  { "xchgS",		{ Ev, Gv } },
77077298Sobrien  /* 88 */
771218822Sdim  { "movB",		{ Eb, Gb } },
772218822Sdim  { "movS",		{ Ev, Gv } },
773218822Sdim  { "movB",		{ Gb, Eb } },
774218822Sdim  { "movS",		{ Gv, Ev } },
775218822Sdim  { "movD",		{ Sv, Sw } },
776218822Sdim  { "leaS",		{ Gv, M } },
777218822Sdim  { "movD",		{ Sw, Sv } },
778218822Sdim  { GRP1a },
77977298Sobrien  /* 90 */
780218822Sdim  { PREGRP38 },
781218822Sdim  { "xchgS",		{ RMeCX, eAX } },
782218822Sdim  { "xchgS",		{ RMeDX, eAX } },
783218822Sdim  { "xchgS",		{ RMeBX, eAX } },
784218822Sdim  { "xchgS",		{ RMeSP, eAX } },
785218822Sdim  { "xchgS",		{ RMeBP, eAX } },
786218822Sdim  { "xchgS",		{ RMeSI, eAX } },
787218822Sdim  { "xchgS",		{ RMeDI, eAX } },
78877298Sobrien  /* 98 */
789218822Sdim  { "cW{t||t|}R",	{ XX } },
790218822Sdim  { "cR{t||t|}O",	{ XX } },
791218822Sdim  { "Jcall{T|}",	{ Ap } },
792218822Sdim  { "(bad)",		{ XX } },	/* fwait */
793218822Sdim  { "pushfT",		{ XX } },
794218822Sdim  { "popfT",		{ XX } },
795218822Sdim  { "sahf{|}",		{ XX } },
796218822Sdim  { "lahf{|}",		{ XX } },
79777298Sobrien  /* a0 */
798218822Sdim  { "movB",		{ AL, Ob } },
799218822Sdim  { "movS",		{ eAX, Ov } },
800218822Sdim  { "movB",		{ Ob, AL } },
801218822Sdim  { "movS",		{ Ov, eAX } },
802218822Sdim  { "movs{b||b|}",	{ Ybr, Xb } },
803218822Sdim  { "movs{R||R|}",	{ Yvr, Xv } },
804218822Sdim  { "cmps{b||b|}",	{ Xb, Yb } },
805218822Sdim  { "cmps{R||R|}",	{ Xv, Yv } },
80677298Sobrien  /* a8 */
807218822Sdim  { "testB",		{ AL, Ib } },
808218822Sdim  { "testS",		{ eAX, Iv } },
809218822Sdim  { "stosB",		{ Ybr, AL } },
810218822Sdim  { "stosS",		{ Yvr, eAX } },
811218822Sdim  { "lodsB",		{ ALr, Xb } },
812218822Sdim  { "lodsS",		{ eAXr, Xv } },
813218822Sdim  { "scasB",		{ AL, Yb } },
814218822Sdim  { "scasS",		{ eAX, Yv } },
81577298Sobrien  /* b0 */
816218822Sdim  { "movB",		{ RMAL, Ib } },
817218822Sdim  { "movB",		{ RMCL, Ib } },
818218822Sdim  { "movB",		{ RMDL, Ib } },
819218822Sdim  { "movB",		{ RMBL, Ib } },
820218822Sdim  { "movB",		{ RMAH, Ib } },
821218822Sdim  { "movB",		{ RMCH, Ib } },
822218822Sdim  { "movB",		{ RMDH, Ib } },
823218822Sdim  { "movB",		{ RMBH, Ib } },
82477298Sobrien  /* b8 */
825218822Sdim  { "movS",		{ RMeAX, Iv64 } },
826218822Sdim  { "movS",		{ RMeCX, Iv64 } },
827218822Sdim  { "movS",		{ RMeDX, Iv64 } },
828218822Sdim  { "movS",		{ RMeBX, Iv64 } },
829218822Sdim  { "movS",		{ RMeSP, Iv64 } },
830218822Sdim  { "movS",		{ RMeBP, Iv64 } },
831218822Sdim  { "movS",		{ RMeSI, Iv64 } },
832218822Sdim  { "movS",		{ RMeDI, Iv64 } },
83377298Sobrien  /* c0 */
83477298Sobrien  { GRP2b },
83577298Sobrien  { GRP2S },
836218822Sdim  { "retT",		{ Iw } },
837218822Sdim  { "retT",		{ XX } },
838218822Sdim  { "les{S|}",		{ Gv, Mp } },
839218822Sdim  { "ldsS",		{ Gv, Mp } },
840218822Sdim  { GRP11_C6 },
841218822Sdim  { GRP11_C7 },
84277298Sobrien  /* c8 */
843218822Sdim  { "enterT",		{ Iw, Ib } },
844218822Sdim  { "leaveT",		{ XX } },
845218822Sdim  { "lretP",		{ Iw } },
846218822Sdim  { "lretP",		{ XX } },
847218822Sdim  { "int3",		{ XX } },
848218822Sdim  { "int",		{ Ib } },
849218822Sdim  { "into{|}",		{ XX } },
850218822Sdim  { "iretP",		{ XX } },
85177298Sobrien  /* d0 */
85277298Sobrien  { GRP2b_one },
85377298Sobrien  { GRP2S_one },
85477298Sobrien  { GRP2b_cl },
85577298Sobrien  { GRP2S_cl },
856218822Sdim  { "aam{|}",		{ sIb } },
857218822Sdim  { "aad{|}",		{ sIb } },
858218822Sdim  { "(bad)",		{ XX } },
859218822Sdim  { "xlat",		{ DSBX } },
86077298Sobrien  /* d8 */
86177298Sobrien  { FLOAT },
86277298Sobrien  { FLOAT },
86377298Sobrien  { FLOAT },
86477298Sobrien  { FLOAT },
86577298Sobrien  { FLOAT },
86677298Sobrien  { FLOAT },
86777298Sobrien  { FLOAT },
86877298Sobrien  { FLOAT },
86977298Sobrien  /* e0 */
870218822Sdim  { "loopneFH",		{ Jb, XX, loop_jcxz_flag } },
871218822Sdim  { "loopeFH",		{ Jb, XX, loop_jcxz_flag } },
872218822Sdim  { "loopFH",		{ Jb, XX, loop_jcxz_flag } },
873218822Sdim  { "jEcxzH",		{ Jb, XX, loop_jcxz_flag } },
874218822Sdim  { "inB",		{ AL, Ib } },
875218822Sdim  { "inG",		{ zAX, Ib } },
876218822Sdim  { "outB",		{ Ib, AL } },
877218822Sdim  { "outG",		{ Ib, zAX } },
87877298Sobrien  /* e8 */
879218822Sdim  { "callT",		{ Jv } },
880218822Sdim  { "jmpT",		{ Jv } },
881218822Sdim  { "Jjmp{T|}",		{ Ap } },
882218822Sdim  { "jmp",		{ Jb } },
883218822Sdim  { "inB",		{ AL, indirDX } },
884218822Sdim  { "inG",		{ zAX, indirDX } },
885218822Sdim  { "outB",		{ indirDX, AL } },
886218822Sdim  { "outG",		{ indirDX, zAX } },
88777298Sobrien  /* f0 */
888218822Sdim  { "(bad)",		{ XX } },	/* lock prefix */
889218822Sdim  { "icebp",		{ XX } },
890218822Sdim  { "(bad)",		{ XX } },	/* repne */
891218822Sdim  { "(bad)",		{ XX } },	/* repz */
892218822Sdim  { "hlt",		{ XX } },
893218822Sdim  { "cmc",		{ XX } },
89477298Sobrien  { GRP3b },
89577298Sobrien  { GRP3S },
89677298Sobrien  /* f8 */
897218822Sdim  { "clc",		{ XX } },
898218822Sdim  { "stc",		{ XX } },
899218822Sdim  { "cli",		{ XX } },
900218822Sdim  { "sti",		{ XX } },
901218822Sdim  { "cld",		{ XX } },
902218822Sdim  { "std",		{ XX } },
90377298Sobrien  { GRP4 },
90477298Sobrien  { GRP5 },
90577298Sobrien};
90677298Sobrien
90785815Sobrienstatic const struct dis386 dis386_twobyte[] = {
90877298Sobrien  /* 00 */
90933965Sjdp  { GRP6 },
91033965Sjdp  { GRP7 },
911218822Sdim  { "larS",		{ Gv, Ew } },
912218822Sdim  { "lslS",		{ Gv, Ew } },
913218822Sdim  { "(bad)",		{ XX } },
914218822Sdim  { "syscall",		{ XX } },
915218822Sdim  { "clts",		{ XX } },
916218822Sdim  { "sysretP",		{ XX } },
91733965Sjdp  /* 08 */
918218822Sdim  { "invd",		{ XX } },
919218822Sdim  { "wbinvd",		{ XX } },
920218822Sdim  { "(bad)",		{ XX } },
921218822Sdim  { "ud2a",		{ XX } },
922218822Sdim  { "(bad)",		{ XX } },
92360484Sobrien  { GRPAMD },
924218822Sdim  { "femms",		{ XX } },
925218822Sdim  { "",			{ MX, EM, OPSUF } }, /* See OP_3DNowSuffix.  */
92633965Sjdp  /* 10 */
92760484Sobrien  { PREGRP8 },
92860484Sobrien  { PREGRP9 },
929130561Sobrien  { PREGRP30 },
930218822Sdim  { "movlpX",		{ EXq, XM, { SIMD_Fixup, 'h' } } },
931218822Sdim  { "unpcklpX",		{ XM, EXq } },
932218822Sdim  { "unpckhpX",		{ XM, EXq } },
933130561Sobrien  { PREGRP31 },
934218822Sdim  { "movhpX",		{ EXq, XM, { SIMD_Fixup, 'l' } } },
93533965Sjdp  /* 18 */
936218822Sdim  { GRP16 },
937218822Sdim  { "(bad)",		{ XX } },
938218822Sdim  { "(bad)",		{ XX } },
939218822Sdim  { "(bad)",		{ XX } },
940218822Sdim  { "(bad)",		{ XX } },
941218822Sdim  { "(bad)",		{ XX } },
942218822Sdim  { "(bad)",		{ XX } },
943218822Sdim  { "nopQ",		{ Ev } },
94433965Sjdp  /* 20 */
945218822Sdim  { "movZ",		{ Rm, Cm } },
946218822Sdim  { "movZ",		{ Rm, Dm } },
947218822Sdim  { "movZ",		{ Cm, Rm } },
948218822Sdim  { "movZ",		{ Dm, Rm } },
949218822Sdim  { "movL",		{ Rd, Td } },
950218822Sdim  { "(bad)",		{ XX } },
951218822Sdim  { "movL",		{ Td, Rd } },
952218822Sdim  { "(bad)",		{ XX } },
95333965Sjdp  /* 28 */
954218822Sdim  { "movapX",		{ XM, EXx } },
955218822Sdim  { "movapX",		{ EXx,  XM } },
95660484Sobrien  { PREGRP2 },
957218822Sdim  { PREGRP33 },
95860484Sobrien  { PREGRP4 },
95960484Sobrien  { PREGRP3 },
960218822Sdim  { PREGRP93 },
961218822Sdim  { PREGRP94 },
96233965Sjdp  /* 30 */
963218822Sdim  { "wrmsr",		{ XX } },
964218822Sdim  { "rdtsc",		{ XX } },
965218822Sdim  { "rdmsr",		{ XX } },
966218822Sdim  { "rdpmc",		{ XX } },
967218822Sdim  { "sysenter",		{ XX } },
968218822Sdim  { "sysexit",		{ XX } },
969218822Sdim  { "(bad)",		{ XX } },
970218822Sdim  { "(bad)",		{ XX } },
97133965Sjdp  /* 38 */
972218822Sdim  { THREE_BYTE_0 },
973218822Sdim  { "(bad)",		{ XX } },
974218822Sdim  { THREE_BYTE_1 },
975218822Sdim  { "(bad)",		{ XX } },
976218822Sdim  { "(bad)",		{ XX } },
977218822Sdim  { "(bad)",		{ XX } },
978218822Sdim  { "(bad)",		{ XX } },
979218822Sdim  { "(bad)",		{ XX } },
98033965Sjdp  /* 40 */
981218822Sdim  { "cmovo",		{ Gv, Ev } },
982218822Sdim  { "cmovno",		{ Gv, Ev } },
983218822Sdim  { "cmovb",		{ Gv, Ev } },
984218822Sdim  { "cmovae",		{ Gv, Ev } },
985218822Sdim  { "cmove",		{ Gv, Ev } },
986218822Sdim  { "cmovne",		{ Gv, Ev } },
987218822Sdim  { "cmovbe",		{ Gv, Ev } },
988218822Sdim  { "cmova",		{ Gv, Ev } },
98933965Sjdp  /* 48 */
990218822Sdim  { "cmovs",		{ Gv, Ev } },
991218822Sdim  { "cmovns",		{ Gv, Ev } },
992218822Sdim  { "cmovp",		{ Gv, Ev } },
993218822Sdim  { "cmovnp",		{ Gv, Ev } },
994218822Sdim  { "cmovl",		{ Gv, Ev } },
995218822Sdim  { "cmovge",		{ Gv, Ev } },
996218822Sdim  { "cmovle",		{ Gv, Ev } },
997218822Sdim  { "cmovg",		{ Gv, Ev } },
99833965Sjdp  /* 50 */
999218822Sdim  { "movmskpX",		{ Gdq, XS } },
100060484Sobrien  { PREGRP13 },
100160484Sobrien  { PREGRP12 },
100260484Sobrien  { PREGRP11 },
1003218822Sdim  { "andpX",		{ XM, EXx } },
1004218822Sdim  { "andnpX",		{ XM, EXx } },
1005218822Sdim  { "orpX",		{ XM, EXx } },
1006218822Sdim  { "xorpX",		{ XM, EXx } },
100733965Sjdp  /* 58 */
100860484Sobrien  { PREGRP0 },
100960484Sobrien  { PREGRP10 },
101077298Sobrien  { PREGRP17 },
101177298Sobrien  { PREGRP16 },
101260484Sobrien  { PREGRP14 },
101360484Sobrien  { PREGRP7 },
101460484Sobrien  { PREGRP5 },
101560484Sobrien  { PREGRP6 },
101633965Sjdp  /* 60 */
1017218822Sdim  { PREGRP95 },
1018218822Sdim  { PREGRP96 },
1019218822Sdim  { PREGRP97 },
1020218822Sdim  { "packsswb",		{ MX, EM } },
1021218822Sdim  { "pcmpgtb",		{ MX, EM } },
1022218822Sdim  { "pcmpgtw",		{ MX, EM } },
1023218822Sdim  { "pcmpgtd",		{ MX, EM } },
1024218822Sdim  { "packuswb",		{ MX, EM } },
102533965Sjdp  /* 68 */
1026218822Sdim  { "punpckhbw",	{ MX, EM } },
1027218822Sdim  { "punpckhwd",	{ MX, EM } },
1028218822Sdim  { "punpckhdq",	{ MX, EM } },
1029218822Sdim  { "packssdw",		{ MX, EM } },
103077298Sobrien  { PREGRP26 },
103177298Sobrien  { PREGRP24 },
1032218822Sdim  { "movd",		{ MX, Edq } },
103377298Sobrien  { PREGRP19 },
103433965Sjdp  /* 70 */
103577298Sobrien  { PREGRP22 },
103633965Sjdp  { GRP12 },
1037218822Sdim  { GRP13 },
1038218822Sdim  { GRP14 },
1039218822Sdim  { "pcmpeqb",		{ MX, EM } },
1040218822Sdim  { "pcmpeqw",		{ MX, EM } },
1041218822Sdim  { "pcmpeqd",		{ MX, EM } },
1042218822Sdim  { "emms",		{ XX } },
104333965Sjdp  /* 78 */
1044218822Sdim  { PREGRP34 },
1045218822Sdim  { PREGRP35 },
1046218822Sdim  { "(bad)",		{ XX } },
1047218822Sdim  { "(bad)",		{ XX } },
1048130561Sobrien  { PREGRP28 },
1049130561Sobrien  { PREGRP29 },
105077298Sobrien  { PREGRP23 },
105177298Sobrien  { PREGRP20 },
105233965Sjdp  /* 80 */
1053218822Sdim  { "joH",		{ Jv, XX, cond_jump_flag } },
1054218822Sdim  { "jnoH",		{ Jv, XX, cond_jump_flag } },
1055218822Sdim  { "jbH",		{ Jv, XX, cond_jump_flag } },
1056218822Sdim  { "jaeH",		{ Jv, XX, cond_jump_flag } },
1057218822Sdim  { "jeH",		{ Jv, XX, cond_jump_flag } },
1058218822Sdim  { "jneH",		{ Jv, XX, cond_jump_flag } },
1059218822Sdim  { "jbeH",		{ Jv, XX, cond_jump_flag } },
1060218822Sdim  { "jaH",		{ Jv, XX, cond_jump_flag } },
106133965Sjdp  /* 88 */
1062218822Sdim  { "jsH",		{ Jv, XX, cond_jump_flag } },
1063218822Sdim  { "jnsH",		{ Jv, XX, cond_jump_flag } },
1064218822Sdim  { "jpH",		{ Jv, XX, cond_jump_flag } },
1065218822Sdim  { "jnpH",		{ Jv, XX, cond_jump_flag } },
1066218822Sdim  { "jlH",		{ Jv, XX, cond_jump_flag } },
1067218822Sdim  { "jgeH",		{ Jv, XX, cond_jump_flag } },
1068218822Sdim  { "jleH",		{ Jv, XX, cond_jump_flag } },
1069218822Sdim  { "jgH",		{ Jv, XX, cond_jump_flag } },
107033965Sjdp  /* 90 */
1071218822Sdim  { "seto",		{ Eb } },
1072218822Sdim  { "setno",		{ Eb } },
1073218822Sdim  { "setb",		{ Eb } },
1074218822Sdim  { "setae",		{ Eb } },
1075218822Sdim  { "sete",		{ Eb } },
1076218822Sdim  { "setne",		{ Eb } },
1077218822Sdim  { "setbe",		{ Eb } },
1078218822Sdim  { "seta",		{ Eb } },
107933965Sjdp  /* 98 */
1080218822Sdim  { "sets",		{ Eb } },
1081218822Sdim  { "setns",		{ Eb } },
1082218822Sdim  { "setp",		{ Eb } },
1083218822Sdim  { "setnp",		{ Eb } },
1084218822Sdim  { "setl",		{ Eb } },
1085218822Sdim  { "setge",		{ Eb } },
1086218822Sdim  { "setle",		{ Eb } },
1087218822Sdim  { "setg",		{ Eb } },
108833965Sjdp  /* a0 */
1089218822Sdim  { "pushT",		{ fs } },
1090218822Sdim  { "popT",		{ fs } },
1091218822Sdim  { "cpuid",		{ XX } },
1092218822Sdim  { "btS",		{ Ev, Gv } },
1093218822Sdim  { "shldS",		{ Ev, Gv, Ib } },
1094218822Sdim  { "shldS",		{ Ev, Gv, CL } },
1095218822Sdim  { GRPPADLCK2 },
1096218822Sdim  { GRPPADLCK1 },
109733965Sjdp  /* a8 */
1098218822Sdim  { "pushT",		{ gs } },
1099218822Sdim  { "popT",		{ gs } },
1100218822Sdim  { "rsm",		{ XX } },
1101218822Sdim  { "btsS",		{ Ev, Gv } },
1102218822Sdim  { "shrdS",		{ Ev, Gv, Ib } },
1103218822Sdim  { "shrdS",		{ Ev, Gv, CL } },
1104218822Sdim  { GRP15 },
1105218822Sdim  { "imulS",		{ Gv, Ev } },
110633965Sjdp  /* b0 */
1107218822Sdim  { "cmpxchgB",		{ Eb, Gb } },
1108218822Sdim  { "cmpxchgS",		{ Ev, Gv } },
1109218822Sdim  { "lssS",		{ Gv, Mp } },
1110218822Sdim  { "btrS",		{ Ev, Gv } },
1111218822Sdim  { "lfsS",		{ Gv, Mp } },
1112218822Sdim  { "lgsS",		{ Gv, Mp } },
1113218822Sdim  { "movz{bR|x|bR|x}",	{ Gv, Eb } },
1114218822Sdim  { "movz{wR|x|wR|x}",	{ Gv, Ew } }, /* yes, there really is movzww ! */
111533965Sjdp  /* b8 */
1116218822Sdim  { PREGRP37 },
1117218822Sdim  { "ud2b",		{ XX } },
111833965Sjdp  { GRP8 },
1119218822Sdim  { "btcS",		{ Ev, Gv } },
1120218822Sdim  { "bsfS",		{ Gv, Ev } },
1121218822Sdim  { PREGRP36 },
1122218822Sdim  { "movs{bR|x|bR|x}",	{ Gv, Eb } },
1123218822Sdim  { "movs{wR|x|wR|x}",	{ Gv, Ew } }, /* yes, there really is movsww ! */
112433965Sjdp  /* c0 */
1125218822Sdim  { "xaddB",		{ Eb, Gb } },
1126218822Sdim  { "xaddS",		{ Ev, Gv } },
112760484Sobrien  { PREGRP1 },
1128218822Sdim  { "movntiS",		{ Ev, Gv } },
1129218822Sdim  { "pinsrw",		{ MX, Edqw, Ib } },
1130218822Sdim  { "pextrw",		{ Gdq, MS, Ib } },
1131218822Sdim  { "shufpX",		{ XM, EXx, Ib } },
113260484Sobrien  { GRP9 },
113333965Sjdp  /* c8 */
1134218822Sdim  { "bswap",		{ RMeAX } },
1135218822Sdim  { "bswap",		{ RMeCX } },
1136218822Sdim  { "bswap",		{ RMeDX } },
1137218822Sdim  { "bswap",		{ RMeBX } },
1138218822Sdim  { "bswap",		{ RMeSP } },
1139218822Sdim  { "bswap",		{ RMeBP } },
1140218822Sdim  { "bswap",		{ RMeSI } },
1141218822Sdim  { "bswap",		{ RMeDI } },
114233965Sjdp  /* d0 */
1143130561Sobrien  { PREGRP27 },
1144218822Sdim  { "psrlw",		{ MX, EM } },
1145218822Sdim  { "psrld",		{ MX, EM } },
1146218822Sdim  { "psrlq",		{ MX, EM } },
1147218822Sdim  { "paddq",		{ MX, EM } },
1148218822Sdim  { "pmullw",		{ MX, EM } },
114977298Sobrien  { PREGRP21 },
1150218822Sdim  { "pmovmskb",		{ Gdq, MS } },
115133965Sjdp  /* d8 */
1152218822Sdim  { "psubusb",		{ MX, EM } },
1153218822Sdim  { "psubusw",		{ MX, EM } },
1154218822Sdim  { "pminub",		{ MX, EM } },
1155218822Sdim  { "pand",		{ MX, EM } },
1156218822Sdim  { "paddusb",		{ MX, EM } },
1157218822Sdim  { "paddusw",		{ MX, EM } },
1158218822Sdim  { "pmaxub",		{ MX, EM } },
1159218822Sdim  { "pandn",		{ MX, EM } },
116033965Sjdp  /* e0 */
1161218822Sdim  { "pavgb",		{ MX, EM } },
1162218822Sdim  { "psraw",		{ MX, EM } },
1163218822Sdim  { "psrad",		{ MX, EM } },
1164218822Sdim  { "pavgw",		{ MX, EM } },
1165218822Sdim  { "pmulhuw",		{ MX, EM } },
1166218822Sdim  { "pmulhw",		{ MX, EM } },
116777298Sobrien  { PREGRP15 },
116877298Sobrien  { PREGRP25 },
116933965Sjdp  /* e8 */
1170218822Sdim  { "psubsb",		{ MX, EM } },
1171218822Sdim  { "psubsw",		{ MX, EM } },
1172218822Sdim  { "pminsw",		{ MX, EM } },
1173218822Sdim  { "por",		{ MX, EM } },
1174218822Sdim  { "paddsb",		{ MX, EM } },
1175218822Sdim  { "paddsw",		{ MX, EM } },
1176218822Sdim  { "pmaxsw",		{ MX, EM } },
1177218822Sdim  { "pxor",		{ MX, EM } },
117833965Sjdp  /* f0 */
1179130561Sobrien  { PREGRP32 },
1180218822Sdim  { "psllw",		{ MX, EM } },
1181218822Sdim  { "pslld",		{ MX, EM } },
1182218822Sdim  { "psllq",		{ MX, EM } },
1183218822Sdim  { "pmuludq",		{ MX, EM } },
1184218822Sdim  { "pmaddwd",		{ MX, EM } },
1185218822Sdim  { "psadbw",		{ MX, EM } },
118677298Sobrien  { PREGRP18 },
118733965Sjdp  /* f8 */
1188218822Sdim  { "psubb",		{ MX, EM } },
1189218822Sdim  { "psubw",		{ MX, EM } },
1190218822Sdim  { "psubd",		{ MX, EM } },
1191218822Sdim  { "psubq",		{ MX, EM } },
1192218822Sdim  { "paddb",		{ MX, EM } },
1193218822Sdim  { "paddw",		{ MX, EM } },
1194218822Sdim  { "paddd",		{ MX, EM } },
1195218822Sdim  { "(bad)",		{ XX } },
119633965Sjdp};
119733965Sjdp
119833965Sjdpstatic const unsigned char onebyte_has_modrm[256] = {
119960484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
120060484Sobrien  /*       -------------------------------        */
120160484Sobrien  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
120260484Sobrien  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
120360484Sobrien  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
120460484Sobrien  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
120560484Sobrien  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
120660484Sobrien  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
120760484Sobrien  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
120860484Sobrien  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
120960484Sobrien  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
121060484Sobrien  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
121160484Sobrien  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
121260484Sobrien  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
121360484Sobrien  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
121460484Sobrien  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
121560484Sobrien  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
121660484Sobrien  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
121760484Sobrien  /*       -------------------------------        */
121860484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
121933965Sjdp};
122033965Sjdp
122133965Sjdpstatic const unsigned char twobyte_has_modrm[256] = {
122260484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
122360484Sobrien  /*       -------------------------------        */
122460484Sobrien  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1225218822Sdim  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
122678828Sobrien  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1227218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
122833965Sjdp  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
122978828Sobrien  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
123078828Sobrien  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1231218822Sdim  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
123233965Sjdp  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
123333965Sjdp  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1234218822Sdim  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1235218822Sdim  /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
123633965Sjdp  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1237130561Sobrien  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
123878828Sobrien  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1239130561Sobrien  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
124060484Sobrien  /*       -------------------------------        */
124160484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
124233965Sjdp};
124333965Sjdp
1244218822Sdimstatic const unsigned char twobyte_uses_DATA_prefix[256] = {
124560484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
124660484Sobrien  /*       -------------------------------        */
124760484Sobrien  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1248130561Sobrien  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1249218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1250218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
125160484Sobrien  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
125277298Sobrien  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
125377298Sobrien  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1254218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
125560484Sobrien  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
125660484Sobrien  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
125760484Sobrien  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
125860484Sobrien  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
125960484Sobrien  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1260130561Sobrien  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
126177298Sobrien  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1262130561Sobrien  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
126360484Sobrien  /*       -------------------------------        */
126460484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
126560484Sobrien};
126660484Sobrien
1267218822Sdimstatic const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1268218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1269218822Sdim  /*       -------------------------------        */
1270218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1271218822Sdim  /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1272218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1273218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1274218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1275218822Sdim  /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1276218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1277218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1278218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1279218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1280218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1281218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1282218822Sdim  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1283218822Sdim  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1284218822Sdim  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1285218822Sdim  /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1286218822Sdim  /*       -------------------------------        */
1287218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1288218822Sdim};
1289218822Sdim
1290218822Sdimstatic const unsigned char twobyte_uses_REPZ_prefix[256] = {
1291218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1292218822Sdim  /*       -------------------------------        */
1293218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1294218822Sdim  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1295218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1296218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1297218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1298218822Sdim  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1299218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1300218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1301218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1302218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1303218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1304218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1305218822Sdim  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1306218822Sdim  /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1307218822Sdim  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1308218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1309218822Sdim  /*       -------------------------------        */
1310218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1311218822Sdim};
1312218822Sdim
1313218822Sdim/* This is used to determine if opcode 0f 38 XX uses DATA prefix.  */
1314218822Sdimstatic const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1315218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1316218822Sdim  /*       -------------------------------        */
1317218822Sdim  /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1318218822Sdim  /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1319218822Sdim  /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1320218822Sdim  /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1321218822Sdim  /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1322218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1323218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1324218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1325218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1326218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1327218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1328218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1329218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1330247012Sjmg  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
1331218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1332218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1333218822Sdim  /*       -------------------------------        */
1334218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1335218822Sdim};
1336218822Sdim
1337218822Sdim/* This is used to determine if opcode 0f 38 XX uses REPNZ prefix.  */
1338218822Sdimstatic const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1339218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1340218822Sdim  /*       -------------------------------        */
1341218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1342218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1343218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1344218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1345218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1346218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1347218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1348218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1349218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1350218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1351218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1352218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1353218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1354218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1355218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1356218822Sdim  /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1357218822Sdim  /*       -------------------------------        */
1358218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1359218822Sdim};
1360218822Sdim
1361218822Sdim/* This is used to determine if opcode 0f 38 XX uses REPZ prefix.  */
1362218822Sdimstatic const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1363218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1364218822Sdim  /*       -------------------------------        */
1365218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1366218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1367218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1368218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1369218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1370218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1371218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1372218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1373218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1374218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1375218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1376218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1377218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1378218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1379218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1380218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1381218822Sdim  /*       -------------------------------        */
1382218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1383218822Sdim};
1384218822Sdim
1385218822Sdim/* This is used to determine if opcode 0f 3a XX uses DATA prefix.  */
1386218822Sdimstatic const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1387218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1388218822Sdim  /*       -------------------------------        */
1389218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1390218822Sdim  /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1391218822Sdim  /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1392218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1393247012Sjmg  /* 40 */ 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1394218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1395218822Sdim  /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1396218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1397218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1398218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1399218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1400218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1401218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1402247012Sjmg  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* df */
1403218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1404218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1405218822Sdim  /*       -------------------------------        */
1406218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1407218822Sdim};
1408218822Sdim
1409218822Sdim/* This is used to determine if opcode 0f 3a XX uses REPNZ prefix.  */
1410218822Sdimstatic const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1411218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1412218822Sdim  /*       -------------------------------        */
1413218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1414218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1415218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1416218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1417218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1418218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1419218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1420218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1421218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1422218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1423218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1424218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1425218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1426218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1427218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1428218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1429218822Sdim  /*       -------------------------------        */
1430218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1431218822Sdim};
1432218822Sdim
1433218822Sdim/* This is used to determine if opcode 0f 3a XX uses REPZ prefix.  */
1434218822Sdimstatic const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1435218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1436218822Sdim  /*       -------------------------------        */
1437218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1438218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1439218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1440218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1441218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1442218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1443218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1444218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1445218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1446218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1447218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1448218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1449218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1450218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1451218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1452218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1453218822Sdim  /*       -------------------------------        */
1454218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1455218822Sdim};
1456218822Sdim
145733965Sjdpstatic char obuf[100];
145833965Sjdpstatic char *obufp;
145933965Sjdpstatic char scratchbuf[100];
146033965Sjdpstatic unsigned char *start_codep;
146160484Sobrienstatic unsigned char *insn_codep;
146233965Sjdpstatic unsigned char *codep;
146333965Sjdpstatic disassemble_info *the_info;
1464218822Sdimstatic struct
1465218822Sdim  {
1466218822Sdim    int mod;
1467218822Sdim    int reg;
1468218822Sdim    int rm;
1469218822Sdim  }
1470218822Sdimmodrm;
147178828Sobrienstatic unsigned char need_modrm;
147233965Sjdp
147378828Sobrien/* If we are accessing mod/rm/reg without need_modrm set, then the
147478828Sobrien   values are stale.  Hitting this abort likely indicates that you
147578828Sobrien   need to update onebyte_has_modrm or twobyte_has_modrm.  */
147678828Sobrien#define MODRM_CHECK  if (!need_modrm) abort ()
147778828Sobrien
147885815Sobrienstatic const char **names64;
147985815Sobrienstatic const char **names32;
148085815Sobrienstatic const char **names16;
148185815Sobrienstatic const char **names8;
148285815Sobrienstatic const char **names8rex;
148385815Sobrienstatic const char **names_seg;
148485815Sobrienstatic const char **index16;
148585815Sobrien
148685815Sobrienstatic const char *intel_names64[] = {
148785815Sobrien  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
148885815Sobrien  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
148985815Sobrien};
149085815Sobrienstatic const char *intel_names32[] = {
149185815Sobrien  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
149285815Sobrien  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
149385815Sobrien};
149485815Sobrienstatic const char *intel_names16[] = {
149585815Sobrien  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
149685815Sobrien  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
149785815Sobrien};
149885815Sobrienstatic const char *intel_names8[] = {
149985815Sobrien  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
150085815Sobrien};
150185815Sobrienstatic const char *intel_names8rex[] = {
150285815Sobrien  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
150385815Sobrien  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
150485815Sobrien};
150585815Sobrienstatic const char *intel_names_seg[] = {
150685815Sobrien  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
150785815Sobrien};
150885815Sobrienstatic const char *intel_index16[] = {
150985815Sobrien  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
151085815Sobrien};
151185815Sobrien
151285815Sobrienstatic const char *att_names64[] = {
151385815Sobrien  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
151477298Sobrien  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
151577298Sobrien};
151685815Sobrienstatic const char *att_names32[] = {
151785815Sobrien  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
151877298Sobrien  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
151933965Sjdp};
152085815Sobrienstatic const char *att_names16[] = {
152185815Sobrien  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
152277298Sobrien  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
152333965Sjdp};
152485815Sobrienstatic const char *att_names8[] = {
152585815Sobrien  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
152633965Sjdp};
152785815Sobrienstatic const char *att_names8rex[] = {
152885815Sobrien  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
152977298Sobrien  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
153077298Sobrien};
153185815Sobrienstatic const char *att_names_seg[] = {
153285815Sobrien  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
153333965Sjdp};
153485815Sobrienstatic const char *att_index16[] = {
153585815Sobrien  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
153633965Sjdp};
153733965Sjdp
153860484Sobrienstatic const struct dis386 grps[][8] = {
1539218822Sdim  /* GRP1a */
1540218822Sdim  {
1541218822Sdim    { "popU",	{ stackEv } },
1542218822Sdim    { "(bad)",	{ XX } },
1543218822Sdim    { "(bad)",	{ XX } },
1544218822Sdim    { "(bad)",	{ XX } },
1545218822Sdim    { "(bad)",	{ XX } },
1546218822Sdim    { "(bad)",	{ XX } },
1547218822Sdim    { "(bad)",	{ XX } },
1548218822Sdim    { "(bad)",	{ XX } },
1549218822Sdim  },
155033965Sjdp  /* GRP1b */
155133965Sjdp  {
1552218822Sdim    { "addA",	{ Eb, Ib } },
1553218822Sdim    { "orA",	{ Eb, Ib } },
1554218822Sdim    { "adcA",	{ Eb, Ib } },
1555218822Sdim    { "sbbA",	{ Eb, Ib } },
1556218822Sdim    { "andA",	{ Eb, Ib } },
1557218822Sdim    { "subA",	{ Eb, Ib } },
1558218822Sdim    { "xorA",	{ Eb, Ib } },
1559218822Sdim    { "cmpA",	{ Eb, Ib } },
156033965Sjdp  },
156133965Sjdp  /* GRP1S */
156233965Sjdp  {
1563218822Sdim    { "addQ",	{ Ev, Iv } },
1564218822Sdim    { "orQ",	{ Ev, Iv } },
1565218822Sdim    { "adcQ",	{ Ev, Iv } },
1566218822Sdim    { "sbbQ",	{ Ev, Iv } },
1567218822Sdim    { "andQ",	{ Ev, Iv } },
1568218822Sdim    { "subQ",	{ Ev, Iv } },
1569218822Sdim    { "xorQ",	{ Ev, Iv } },
1570218822Sdim    { "cmpQ",	{ Ev, Iv } },
157133965Sjdp  },
157233965Sjdp  /* GRP1Ss */
157333965Sjdp  {
1574218822Sdim    { "addQ",	{ Ev, sIb } },
1575218822Sdim    { "orQ",	{ Ev, sIb } },
1576218822Sdim    { "adcQ",	{ Ev, sIb } },
1577218822Sdim    { "sbbQ",	{ Ev, sIb } },
1578218822Sdim    { "andQ",	{ Ev, sIb } },
1579218822Sdim    { "subQ",	{ Ev, sIb } },
1580218822Sdim    { "xorQ",	{ Ev, sIb } },
1581218822Sdim    { "cmpQ",	{ Ev, sIb } },
158233965Sjdp  },
158333965Sjdp  /* GRP2b */
158433965Sjdp  {
1585218822Sdim    { "rolA",	{ Eb, Ib } },
1586218822Sdim    { "rorA",	{ Eb, Ib } },
1587218822Sdim    { "rclA",	{ Eb, Ib } },
1588218822Sdim    { "rcrA",	{ Eb, Ib } },
1589218822Sdim    { "shlA",	{ Eb, Ib } },
1590218822Sdim    { "shrA",	{ Eb, Ib } },
1591218822Sdim    { "(bad)",	{ XX } },
1592218822Sdim    { "sarA",	{ Eb, Ib } },
159333965Sjdp  },
159433965Sjdp  /* GRP2S */
159533965Sjdp  {
1596218822Sdim    { "rolQ",	{ Ev, Ib } },
1597218822Sdim    { "rorQ",	{ Ev, Ib } },
1598218822Sdim    { "rclQ",	{ Ev, Ib } },
1599218822Sdim    { "rcrQ",	{ Ev, Ib } },
1600218822Sdim    { "shlQ",	{ Ev, Ib } },
1601218822Sdim    { "shrQ",	{ Ev, Ib } },
1602218822Sdim    { "(bad)",	{ XX } },
1603218822Sdim    { "sarQ",	{ Ev, Ib } },
160433965Sjdp  },
160533965Sjdp  /* GRP2b_one */
160633965Sjdp  {
1607218822Sdim    { "rolA",	{ Eb, I1 } },
1608218822Sdim    { "rorA",	{ Eb, I1 } },
1609218822Sdim    { "rclA",	{ Eb, I1 } },
1610218822Sdim    { "rcrA",	{ Eb, I1 } },
1611218822Sdim    { "shlA",	{ Eb, I1 } },
1612218822Sdim    { "shrA",	{ Eb, I1 } },
1613218822Sdim    { "(bad)",	{ XX } },
1614218822Sdim    { "sarA",	{ Eb, I1 } },
161533965Sjdp  },
161633965Sjdp  /* GRP2S_one */
161733965Sjdp  {
1618218822Sdim    { "rolQ",	{ Ev, I1 } },
1619218822Sdim    { "rorQ",	{ Ev, I1 } },
1620218822Sdim    { "rclQ",	{ Ev, I1 } },
1621218822Sdim    { "rcrQ",	{ Ev, I1 } },
1622218822Sdim    { "shlQ",	{ Ev, I1 } },
1623218822Sdim    { "shrQ",	{ Ev, I1 } },
1624218822Sdim    { "(bad)",	{ XX } },
1625218822Sdim    { "sarQ",	{ Ev, I1 } },
162633965Sjdp  },
162733965Sjdp  /* GRP2b_cl */
162833965Sjdp  {
1629218822Sdim    { "rolA",	{ Eb, CL } },
1630218822Sdim    { "rorA",	{ Eb, CL } },
1631218822Sdim    { "rclA",	{ Eb, CL } },
1632218822Sdim    { "rcrA",	{ Eb, CL } },
1633218822Sdim    { "shlA",	{ Eb, CL } },
1634218822Sdim    { "shrA",	{ Eb, CL } },
1635218822Sdim    { "(bad)",	{ XX } },
1636218822Sdim    { "sarA",	{ Eb, CL } },
163733965Sjdp  },
163833965Sjdp  /* GRP2S_cl */
163933965Sjdp  {
1640218822Sdim    { "rolQ",	{ Ev, CL } },
1641218822Sdim    { "rorQ",	{ Ev, CL } },
1642218822Sdim    { "rclQ",	{ Ev, CL } },
1643218822Sdim    { "rcrQ",	{ Ev, CL } },
1644218822Sdim    { "shlQ",	{ Ev, CL } },
1645218822Sdim    { "shrQ",	{ Ev, CL } },
1646218822Sdim    { "(bad)",	{ XX } },
1647218822Sdim    { "sarQ",	{ Ev, CL } },
164833965Sjdp  },
164933965Sjdp  /* GRP3b */
165033965Sjdp  {
1651218822Sdim    { "testA",	{ Eb, Ib } },
1652218822Sdim    { "(bad)",	{ Eb } },
1653218822Sdim    { "notA",	{ Eb } },
1654218822Sdim    { "negA",	{ Eb } },
1655218822Sdim    { "mulA",	{ Eb } },	/* Don't print the implicit %al register,  */
1656218822Sdim    { "imulA",	{ Eb } },	/* to distinguish these opcodes from other */
1657218822Sdim    { "divA",	{ Eb } },	/* mul/imul opcodes.  Do the same for div  */
1658218822Sdim    { "idivA",	{ Eb } },	/* and idiv for consistency.		   */
165933965Sjdp  },
166033965Sjdp  /* GRP3S */
166133965Sjdp  {
1662218822Sdim    { "testQ",	{ Ev, Iv } },
1663218822Sdim    { "(bad)",	{ XX } },
1664218822Sdim    { "notQ",	{ Ev } },
1665218822Sdim    { "negQ",	{ Ev } },
1666218822Sdim    { "mulQ",	{ Ev } },	/* Don't print the implicit register.  */
1667218822Sdim    { "imulQ",	{ Ev } },
1668218822Sdim    { "divQ",	{ Ev } },
1669218822Sdim    { "idivQ",	{ Ev } },
167033965Sjdp  },
167133965Sjdp  /* GRP4 */
167233965Sjdp  {
1673218822Sdim    { "incA",	{ Eb } },
1674218822Sdim    { "decA",	{ Eb } },
1675218822Sdim    { "(bad)",	{ XX } },
1676218822Sdim    { "(bad)",	{ XX } },
1677218822Sdim    { "(bad)",	{ XX } },
1678218822Sdim    { "(bad)",	{ XX } },
1679218822Sdim    { "(bad)",	{ XX } },
1680218822Sdim    { "(bad)",	{ XX } },
168133965Sjdp  },
168233965Sjdp  /* GRP5 */
168333965Sjdp  {
1684218822Sdim    { "incQ",	{ Ev } },
1685218822Sdim    { "decQ",	{ Ev } },
1686218822Sdim    { "callT",	{ indirEv } },
1687218822Sdim    { "JcallT",	{ indirEp } },
1688218822Sdim    { "jmpT",	{ indirEv } },
1689218822Sdim    { "JjmpT",	{ indirEp } },
1690218822Sdim    { "pushU",	{ stackEv } },
1691218822Sdim    { "(bad)",	{ XX } },
169233965Sjdp  },
169333965Sjdp  /* GRP6 */
169433965Sjdp  {
1695218822Sdim    { "sldtD",	{ Sv } },
1696218822Sdim    { "strD",	{ Sv } },
1697218822Sdim    { "lldt",	{ Ew } },
1698218822Sdim    { "ltr",	{ Ew } },
1699218822Sdim    { "verr",	{ Ew } },
1700218822Sdim    { "verw",	{ Ew } },
1701218822Sdim    { "(bad)",	{ XX } },
1702218822Sdim    { "(bad)",	{ XX } },
170333965Sjdp  },
170433965Sjdp  /* GRP7 */
170533965Sjdp  {
1706218822Sdim    { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1707218822Sdim    { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1708238123Sjhb    { "lgdt{Q|Q||}",	 { { XCR_Fixup, 0 }  } },
1709218822Sdim    { "lidt{Q|Q||}",	 { { SVME_Fixup, 0 } } },
1710218822Sdim    { "smswD",	{ Sv } },
1711218822Sdim    { "(bad)",	{ XX } },
1712218822Sdim    { "lmsw",	{ Ew } },
1713218822Sdim    { "invlpg",	{ { INVLPG_Fixup, w_mode } } },
171433965Sjdp  },
171533965Sjdp  /* GRP8 */
171633965Sjdp  {
1717218822Sdim    { "(bad)",	{ XX } },
1718218822Sdim    { "(bad)",	{ XX } },
1719218822Sdim    { "(bad)",	{ XX } },
1720218822Sdim    { "(bad)",	{ XX } },
1721218822Sdim    { "btQ",	{ Ev, Ib } },
1722218822Sdim    { "btsQ",	{ Ev, Ib } },
1723218822Sdim    { "btrQ",	{ Ev, Ib } },
1724218822Sdim    { "btcQ",	{ Ev, Ib } },
172533965Sjdp  },
172633965Sjdp  /* GRP9 */
172733965Sjdp  {
1728218822Sdim    { "(bad)",	{ XX } },
1729218822Sdim    { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1730218822Sdim    { "(bad)",	{ XX } },
1731218822Sdim    { "(bad)",	{ XX } },
1732218822Sdim    { "(bad)",	{ XX } },
1733218822Sdim    { "(bad)",	{ XX } },
1734218822Sdim    { "",	{ VM } },		/* See OP_VMX.  */
1735218822Sdim    { "vmptrst", { Mq } },
173633965Sjdp  },
1737218822Sdim  /* GRP11_C6 */
173833965Sjdp  {
1739218822Sdim    { "movA",	{ Eb, Ib } },
1740218822Sdim    { "(bad)",	{ XX } },
1741218822Sdim    { "(bad)",	{ XX } },
1742218822Sdim    { "(bad)",	{ XX } },
1743218822Sdim    { "(bad)",	{ XX } },
1744218822Sdim    { "(bad)",	{ XX } },
1745218822Sdim    { "(bad)",	{ XX } },
1746218822Sdim    { "(bad)",	{ XX } },
174733965Sjdp  },
1748218822Sdim  /* GRP11_C7 */
174933965Sjdp  {
1750218822Sdim    { "movQ",	{ Ev, Iv } },
1751218822Sdim    { "(bad)",	{ XX } },
1752218822Sdim    { "(bad)",	{ XX } },
1753218822Sdim    { "(bad)",	{ XX } },
1754218822Sdim    { "(bad)",	{ XX } },
1755218822Sdim    { "(bad)",	{ XX } },
1756218822Sdim    { "(bad)",	{ XX } },
1757218822Sdim    { "(bad)",  { XX } },
175833965Sjdp  },
175933965Sjdp  /* GRP12 */
176033965Sjdp  {
1761218822Sdim    { "(bad)",	{ XX } },
1762218822Sdim    { "(bad)",	{ XX } },
1763218822Sdim    { "psrlw",	{ MS, Ib } },
1764218822Sdim    { "(bad)",	{ XX } },
1765218822Sdim    { "psraw",	{ MS, Ib } },
1766218822Sdim    { "(bad)",	{ XX } },
1767218822Sdim    { "psllw",	{ MS, Ib } },
1768218822Sdim    { "(bad)",	{ XX } },
176960484Sobrien  },
177060484Sobrien  /* GRP13 */
177160484Sobrien  {
1772218822Sdim    { "(bad)",	{ XX } },
1773218822Sdim    { "(bad)",	{ XX } },
1774218822Sdim    { "psrld",	{ MS, Ib } },
1775218822Sdim    { "(bad)",	{ XX } },
1776218822Sdim    { "psrad",	{ MS, Ib } },
1777218822Sdim    { "(bad)",	{ XX } },
1778218822Sdim    { "pslld",	{ MS, Ib } },
1779218822Sdim    { "(bad)",	{ XX } },
178060484Sobrien  },
178160484Sobrien  /* GRP14 */
178260484Sobrien  {
1783218822Sdim    { "(bad)",	{ XX } },
1784218822Sdim    { "(bad)",	{ XX } },
1785218822Sdim    { "psrlq",	{ MS, Ib } },
1786218822Sdim    { "psrldq",	{ MS, Ib } },
1787218822Sdim    { "(bad)",	{ XX } },
1788218822Sdim    { "(bad)",	{ XX } },
1789218822Sdim    { "psllq",	{ MS, Ib } },
1790218822Sdim    { "pslldq",	{ MS, Ib } },
179160484Sobrien  },
1792218822Sdim  /* GRP15 */
1793218822Sdim  {
1794218822Sdim    { "fxsave",		{ Ev } },
1795218822Sdim    { "fxrstor",	{ Ev } },
1796218822Sdim    { "ldmxcsr",	{ Ev } },
1797218822Sdim    { "stmxcsr",	{ Ev } },
1798238123Sjhb    { "xsave",		{ Ev } },
1799238123Sjhb    { "xrstor",		{ { OP_0fae, v_mode } } },
1800238123Sjhb    { "xsaveopt",	{ { OP_0fae, v_mode } } },
1801218822Sdim    { "clflush",	{ { OP_0fae, 0 } } },
1802218822Sdim  },
1803218822Sdim  /* GRP16 */
1804218822Sdim  {
1805218822Sdim    { "prefetchnta",	{ Ev } },
1806218822Sdim    { "prefetcht0",	{ Ev } },
1807218822Sdim    { "prefetcht1",	{ Ev } },
1808218822Sdim    { "prefetcht2",	{ Ev } },
1809218822Sdim    { "(bad)",		{ XX } },
1810218822Sdim    { "(bad)",		{ XX } },
1811218822Sdim    { "(bad)",		{ XX } },
1812218822Sdim    { "(bad)",		{ XX } },
1813218822Sdim  },
181460484Sobrien  /* GRPAMD */
181560484Sobrien  {
1816218822Sdim    { "prefetch",	{ Eb } },
1817218822Sdim    { "prefetchw",	{ Eb } },
1818218822Sdim    { "(bad)",		{ XX } },
1819218822Sdim    { "(bad)",		{ XX } },
1820218822Sdim    { "(bad)",		{ XX } },
1821218822Sdim    { "(bad)",		{ XX } },
1822218822Sdim    { "(bad)",		{ XX } },
1823218822Sdim    { "(bad)",		{ XX } },
1824130561Sobrien  },
1825218822Sdim  /* GRPPADLCK1 */
1826130561Sobrien  {
1827218822Sdim    { "xstore-rng",	{ { OP_0f07, 0 } } },
1828218822Sdim    { "xcrypt-ecb",	{ { OP_0f07, 0 } } },
1829218822Sdim    { "xcrypt-cbc",	{ { OP_0f07, 0 } } },
1830218822Sdim    { "xcrypt-ctr",	{ { OP_0f07, 0 } } },
1831218822Sdim    { "xcrypt-cfb",	{ { OP_0f07, 0 } } },
1832218822Sdim    { "xcrypt-ofb",	{ { OP_0f07, 0 } } },
1833218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1834218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1835218822Sdim  },
1836218822Sdim  /* GRPPADLCK2 */
1837218822Sdim  {
1838218822Sdim    { "montmul",	{ { OP_0f07, 0 } } },
1839218822Sdim    { "xsha1",		{ { OP_0f07, 0 } } },
1840218822Sdim    { "xsha256",	{ { OP_0f07, 0 } } },
1841218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1842218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1843218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1844218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1845218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
184633965Sjdp  }
184733965Sjdp};
184833965Sjdp
184977298Sobrienstatic const struct dis386 prefix_user_table[][4] = {
185060484Sobrien  /* PREGRP0 */
185160484Sobrien  {
1852218822Sdim    { "addps", { XM, EXx } },
1853218822Sdim    { "addss", { XM, EXd } },
1854218822Sdim    { "addpd", { XM, EXx } },
1855218822Sdim    { "addsd", { XM, EXq } },
185660484Sobrien  },
185760484Sobrien  /* PREGRP1 */
185860484Sobrien  {
1859218822Sdim    { "", { XM, EXx, OPSIMD } },	/* See OP_SIMD_SUFFIX.  */
1860218822Sdim    { "", { XM, EXx, OPSIMD } },
1861218822Sdim    { "", { XM, EXx, OPSIMD } },
1862218822Sdim    { "", { XM, EXx, OPSIMD } },
186360484Sobrien  },
186460484Sobrien  /* PREGRP2 */
186560484Sobrien  {
1866218822Sdim    { "cvtpi2ps", { XM, EMC } },
1867218822Sdim    { "cvtsi2ssY", { XM, Ev } },
1868218822Sdim    { "cvtpi2pd", { XM, EMC } },
1869218822Sdim    { "cvtsi2sdY", { XM, Ev } },
187060484Sobrien  },
187160484Sobrien  /* PREGRP3 */
187260484Sobrien  {
1873218822Sdim    { "cvtps2pi", { MXC, EXx } },
1874218822Sdim    { "cvtss2siY", { Gv, EXx } },
1875218822Sdim    { "cvtpd2pi", { MXC, EXx } },
1876218822Sdim    { "cvtsd2siY", { Gv, EXx } },
187760484Sobrien  },
187860484Sobrien  /* PREGRP4 */
187960484Sobrien  {
1880218822Sdim    { "cvttps2pi", { MXC, EXx } },
1881218822Sdim    { "cvttss2siY", { Gv, EXx } },
1882218822Sdim    { "cvttpd2pi", { MXC, EXx } },
1883218822Sdim    { "cvttsd2siY", { Gv, EXx } },
188460484Sobrien  },
188560484Sobrien  /* PREGRP5 */
188660484Sobrien  {
1887218822Sdim    { "divps",	{ XM, EXx } },
1888218822Sdim    { "divss",	{ XM, EXx } },
1889218822Sdim    { "divpd",	{ XM, EXx } },
1890218822Sdim    { "divsd",	{ XM, EXx } },
189160484Sobrien  },
189260484Sobrien  /* PREGRP6 */
189360484Sobrien  {
1894218822Sdim    { "maxps",	{ XM, EXx } },
1895218822Sdim    { "maxss",	{ XM, EXx } },
1896218822Sdim    { "maxpd",	{ XM, EXx } },
1897218822Sdim    { "maxsd",	{ XM, EXx } },
189860484Sobrien  },
189960484Sobrien  /* PREGRP7 */
190060484Sobrien  {
1901218822Sdim    { "minps",	{ XM, EXx } },
1902218822Sdim    { "minss",	{ XM, EXx } },
1903218822Sdim    { "minpd",	{ XM, EXx } },
1904218822Sdim    { "minsd",	{ XM, EXx } },
190560484Sobrien  },
190660484Sobrien  /* PREGRP8 */
190760484Sobrien  {
1908218822Sdim    { "movups",	{ XM, EXx } },
1909218822Sdim    { "movss",	{ XM, EXx } },
1910218822Sdim    { "movupd",	{ XM, EXx } },
1911218822Sdim    { "movsd",	{ XM, EXx } },
191260484Sobrien  },
191360484Sobrien  /* PREGRP9 */
191460484Sobrien  {
1915218822Sdim    { "movups",	{ EXx,  XM } },
1916218822Sdim    { "movss",	{ EXx,  XM } },
1917218822Sdim    { "movupd",	{ EXx,  XM } },
1918218822Sdim    { "movsd",	{ EXx,  XM } },
191960484Sobrien  },
192060484Sobrien  /* PREGRP10 */
192160484Sobrien  {
1922218822Sdim    { "mulps",	{ XM, EXx } },
1923218822Sdim    { "mulss",	{ XM, EXx } },
1924218822Sdim    { "mulpd",	{ XM, EXx } },
1925218822Sdim    { "mulsd",	{ XM, EXx } },
192660484Sobrien  },
192760484Sobrien  /* PREGRP11 */
192860484Sobrien  {
1929218822Sdim    { "rcpps",	{ XM, EXx } },
1930218822Sdim    { "rcpss",	{ XM, EXx } },
1931218822Sdim    { "(bad)",	{ XM, EXx } },
1932218822Sdim    { "(bad)",	{ XM, EXx } },
193360484Sobrien  },
193460484Sobrien  /* PREGRP12 */
193560484Sobrien  {
1936218822Sdim    { "rsqrtps",{ XM, EXx } },
1937218822Sdim    { "rsqrtss",{ XM, EXx } },
1938218822Sdim    { "(bad)",	{ XM, EXx } },
1939218822Sdim    { "(bad)",	{ XM, EXx } },
194060484Sobrien  },
194160484Sobrien  /* PREGRP13 */
194260484Sobrien  {
1943218822Sdim    { "sqrtps", { XM, EXx } },
1944218822Sdim    { "sqrtss", { XM, EXx } },
1945218822Sdim    { "sqrtpd", { XM, EXx } },
1946218822Sdim    { "sqrtsd",	{ XM, EXx } },
194760484Sobrien  },
194860484Sobrien  /* PREGRP14 */
194960484Sobrien  {
1950218822Sdim    { "subps",	{ XM, EXx } },
1951218822Sdim    { "subss",	{ XM, EXx } },
1952218822Sdim    { "subpd",	{ XM, EXx } },
1953218822Sdim    { "subsd",	{ XM, EXx } },
195477298Sobrien  },
195577298Sobrien  /* PREGRP15 */
195677298Sobrien  {
1957218822Sdim    { "(bad)",	{ XM, EXx } },
1958218822Sdim    { "cvtdq2pd", { XM, EXq } },
1959218822Sdim    { "cvttpd2dq", { XM, EXx } },
1960218822Sdim    { "cvtpd2dq", { XM, EXx } },
196177298Sobrien  },
196277298Sobrien  /* PREGRP16 */
196377298Sobrien  {
1964218822Sdim    { "cvtdq2ps", { XM, EXx } },
1965218822Sdim    { "cvttps2dq", { XM, EXx } },
1966218822Sdim    { "cvtps2dq", { XM, EXx } },
1967218822Sdim    { "(bad)",	{ XM, EXx } },
196877298Sobrien  },
196977298Sobrien  /* PREGRP17 */
197077298Sobrien  {
1971218822Sdim    { "cvtps2pd", { XM, EXq } },
1972218822Sdim    { "cvtss2sd", { XM, EXx } },
1973218822Sdim    { "cvtpd2ps", { XM, EXx } },
1974218822Sdim    { "cvtsd2ss", { XM, EXx } },
197577298Sobrien  },
197677298Sobrien  /* PREGRP18 */
197777298Sobrien  {
1978218822Sdim    { "maskmovq", { MX, MS } },
1979218822Sdim    { "(bad)",	{ XM, EXx } },
1980218822Sdim    { "maskmovdqu", { XM, XS } },
1981218822Sdim    { "(bad)",	{ XM, EXx } },
198277298Sobrien  },
198377298Sobrien  /* PREGRP19 */
198477298Sobrien  {
1985218822Sdim    { "movq",	{ MX, EM } },
1986218822Sdim    { "movdqu",	{ XM, EXx } },
1987218822Sdim    { "movdqa",	{ XM, EXx } },
1988218822Sdim    { "(bad)",	{ XM, EXx } },
198977298Sobrien  },
199077298Sobrien  /* PREGRP20 */
199177298Sobrien  {
1992218822Sdim    { "movq",	{ EM, MX } },
1993218822Sdim    { "movdqu",	{ EXx,  XM } },
1994218822Sdim    { "movdqa",	{ EXx,  XM } },
1995218822Sdim    { "(bad)",	{ EXx,  XM } },
199677298Sobrien  },
199777298Sobrien  /* PREGRP21 */
199877298Sobrien  {
1999218822Sdim    { "(bad)",	{ EXx,  XM } },
2000218822Sdim    { "movq2dq",{ XM, MS } },
2001218822Sdim    { "movq",	{ EXx,  XM } },
2002218822Sdim    { "movdq2q",{ MX, XS } },
200377298Sobrien  },
200477298Sobrien  /* PREGRP22 */
200577298Sobrien  {
2006218822Sdim    { "pshufw",	{ MX, EM, Ib } },
2007218822Sdim    { "pshufhw",{ XM, EXx, Ib } },
2008218822Sdim    { "pshufd",	{ XM, EXx, Ib } },
2009218822Sdim    { "pshuflw",{ XM, EXx, Ib } },
201077298Sobrien  },
201177298Sobrien  /* PREGRP23 */
201277298Sobrien  {
2013218822Sdim    { "movd",	{ Edq, MX } },
2014218822Sdim    { "movq",	{ XM, EXx } },
2015218822Sdim    { "movd",	{ Edq, XM } },
2016218822Sdim    { "(bad)",	{ Ed, XM } },
201777298Sobrien  },
201877298Sobrien  /* PREGRP24 */
201977298Sobrien  {
2020218822Sdim    { "(bad)",	{ MX, EXx } },
2021218822Sdim    { "(bad)",	{ XM, EXx } },
2022218822Sdim    { "punpckhqdq", { XM, EXx } },
2023218822Sdim    { "(bad)",	{ XM, EXx } },
202477298Sobrien  },
202577298Sobrien  /* PREGRP25 */
202677298Sobrien  {
2027218822Sdim    { "movntq",	{ EM, MX } },
2028218822Sdim    { "(bad)",	{ EM, XM } },
2029218822Sdim    { "movntdq",{ EM, XM } },
2030218822Sdim    { "(bad)",	{ EM, XM } },
203177298Sobrien  },
203277298Sobrien  /* PREGRP26 */
203377298Sobrien  {
2034218822Sdim    { "(bad)",	{ MX, EXx } },
2035218822Sdim    { "(bad)",	{ XM, EXx } },
2036218822Sdim    { "punpcklqdq", { XM, EXx } },
2037218822Sdim    { "(bad)",	{ XM, EXx } },
203877298Sobrien  },
2039130561Sobrien  /* PREGRP27 */
2040130561Sobrien  {
2041218822Sdim    { "(bad)",	{ MX, EXx } },
2042218822Sdim    { "(bad)",	{ XM, EXx } },
2043218822Sdim    { "addsubpd", { XM, EXx } },
2044218822Sdim    { "addsubps", { XM, EXx } },
2045130561Sobrien  },
2046130561Sobrien  /* PREGRP28 */
2047130561Sobrien  {
2048218822Sdim    { "(bad)",	{ MX, EXx } },
2049218822Sdim    { "(bad)",	{ XM, EXx } },
2050218822Sdim    { "haddpd",	{ XM, EXx } },
2051218822Sdim    { "haddps",	{ XM, EXx } },
2052130561Sobrien  },
2053130561Sobrien  /* PREGRP29 */
2054130561Sobrien  {
2055218822Sdim    { "(bad)",	{ MX, EXx } },
2056218822Sdim    { "(bad)",	{ XM, EXx } },
2057218822Sdim    { "hsubpd",	{ XM, EXx } },
2058218822Sdim    { "hsubps",	{ XM, EXx } },
2059130561Sobrien  },
2060130561Sobrien  /* PREGRP30 */
2061130561Sobrien  {
2062218822Sdim    { "movlpX",	{ XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
2063218822Sdim    { "movsldup", { XM, EXx } },
2064218822Sdim    { "movlpd",	{ XM, EXq } },
2065218822Sdim    { "movddup", { XM, EXq } },
2066130561Sobrien  },
2067130561Sobrien  /* PREGRP31 */
2068130561Sobrien  {
2069218822Sdim    { "movhpX",	{ XM, EXq, { SIMD_Fixup, 'l' } } },
2070218822Sdim    { "movshdup", { XM, EXx } },
2071218822Sdim    { "movhpd",	{ XM, EXq } },
2072218822Sdim    { "(bad)",	{ XM, EXq } },
2073130561Sobrien  },
2074130561Sobrien  /* PREGRP32 */
2075130561Sobrien  {
2076218822Sdim    { "(bad)",	{ XM, EXx } },
2077218822Sdim    { "(bad)",	{ XM, EXx } },
2078218822Sdim    { "(bad)",	{ XM, EXx } },
2079218822Sdim    { "lddqu",	{ XM, M } },
2080130561Sobrien  },
2081218822Sdim  /* PREGRP33 */
2082218822Sdim  {
2083218822Sdim    {"movntps", { Ev, XM } },
2084218822Sdim    {"movntss", { Ev, XM } },
2085218822Sdim    {"movntpd", { Ev, XM } },
2086218822Sdim    {"movntsd", { Ev, XM } },
2087218822Sdim  },
2088218822Sdim
2089218822Sdim  /* PREGRP34 */
2090218822Sdim  {
2091218822Sdim    {"vmread",	{ Em, Gm } },
2092218822Sdim    {"(bad)",	{ XX } },
2093218822Sdim    {"extrq",	{ XS, Ib, Ib } },
2094218822Sdim    {"insertq",	{ XM, XS, Ib, Ib } },
2095218822Sdim  },
2096218822Sdim
2097218822Sdim /* PREGRP35 */
2098218822Sdim  {
2099218822Sdim    {"vmwrite",	{ Gm, Em } },
2100218822Sdim    {"(bad)",	{ XX } },
2101218822Sdim    {"extrq",	{ XM, XS } },
2102218822Sdim    {"insertq",	{ XM, XS } },
2103218822Sdim  },
2104218822Sdim
2105218822Sdim  /* PREGRP36 */
2106218822Sdim  {
2107218822Sdim    { "bsrS",	{ Gv, Ev } },
2108218822Sdim    { "lzcntS",	{ Gv, Ev } },
2109218822Sdim    { "bsrS",	{ Gv, Ev } },
2110218822Sdim    { "(bad)",	{ XX } },
2111218822Sdim  },
2112218822Sdim
2113218822Sdim  /* PREGRP37 */
2114218822Sdim  {
2115218822Sdim    { "(bad)", { XX } },
2116218822Sdim    { "popcntS", { Gv, Ev } },
2117218822Sdim    { "(bad)", { XX } },
2118218822Sdim    { "(bad)", { XX } },
2119218822Sdim  },
2120218822Sdim
2121218822Sdim  /* PREGRP38 */
2122218822Sdim  {
2123218822Sdim    { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2124218822Sdim    { "pause", { XX } },
2125218822Sdim    { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2126218822Sdim    { "(bad)", { XX } },
2127218822Sdim  },
2128218822Sdim
2129218822Sdim  /* PREGRP39 */
2130218822Sdim  {
2131218822Sdim    { "(bad)",	{ XX } },
2132218822Sdim    { "(bad)",	{ XX } },
2133218822Sdim    { "pblendvb", {XM, EXx, XMM0 } },
2134218822Sdim    { "(bad)",	{ XX } },
2135218822Sdim  },
2136218822Sdim
2137218822Sdim  /* PREGRP40 */
2138218822Sdim  {
2139218822Sdim    { "(bad)",	{ XX } },
2140218822Sdim    { "(bad)",	{ XX } },
2141218822Sdim    { "blendvps", {XM, EXx, XMM0 } },
2142218822Sdim    { "(bad)",	{ XX } },
2143218822Sdim  },
2144218822Sdim
2145218822Sdim  /* PREGRP41 */
2146218822Sdim  {
2147218822Sdim    { "(bad)",	{ XX } },
2148218822Sdim    { "(bad)",	{ XX } },
2149218822Sdim    { "blendvpd", { XM, EXx, XMM0 } },
2150218822Sdim    { "(bad)",	{ XX } },
2151218822Sdim  },
2152218822Sdim
2153218822Sdim  /* PREGRP42 */
2154218822Sdim  {
2155218822Sdim    { "(bad)",	{ XX } },
2156218822Sdim    { "(bad)",	{ XX } },
2157218822Sdim    { "ptest",  { XM, EXx } },
2158218822Sdim    { "(bad)",	{ XX } },
2159218822Sdim  },
2160218822Sdim
2161218822Sdim  /* PREGRP43 */
2162218822Sdim  {
2163218822Sdim    { "(bad)",	{ XX } },
2164218822Sdim    { "(bad)",	{ XX } },
2165218822Sdim    { "pmovsxbw", { XM, EXx } },
2166218822Sdim    { "(bad)",	{ XX } },
2167218822Sdim  },
2168218822Sdim
2169218822Sdim  /* PREGRP44 */
2170218822Sdim  {
2171218822Sdim    { "(bad)",	{ XX } },
2172218822Sdim    { "(bad)",	{ XX } },
2173218822Sdim    { "pmovsxbd", { XM, EXx } },
2174218822Sdim    { "(bad)",	{ XX } },
2175218822Sdim  },
2176218822Sdim
2177218822Sdim  /* PREGRP45 */
2178218822Sdim  {
2179218822Sdim    { "(bad)",	{ XX } },
2180218822Sdim    { "(bad)",	{ XX } },
2181218822Sdim    { "pmovsxbq", { XM, EXx } },
2182218822Sdim    { "(bad)",	{ XX } },
2183218822Sdim  },
2184218822Sdim
2185218822Sdim  /* PREGRP46 */
2186218822Sdim  {
2187218822Sdim    { "(bad)",	{ XX } },
2188218822Sdim    { "(bad)",	{ XX } },
2189218822Sdim    { "pmovsxwd", { XM, EXx } },
2190218822Sdim    { "(bad)",	{ XX } },
2191218822Sdim  },
2192218822Sdim
2193218822Sdim  /* PREGRP47 */
2194218822Sdim  {
2195218822Sdim    { "(bad)",	{ XX } },
2196218822Sdim    { "(bad)",	{ XX } },
2197218822Sdim    { "pmovsxwq", { XM, EXx } },
2198218822Sdim    { "(bad)",	{ XX } },
2199218822Sdim  },
2200218822Sdim
2201218822Sdim  /* PREGRP48 */
2202218822Sdim  {
2203218822Sdim    { "(bad)",	{ XX } },
2204218822Sdim    { "(bad)",	{ XX } },
2205218822Sdim    { "pmovsxdq", { XM, EXx } },
2206218822Sdim    { "(bad)",	{ XX } },
2207218822Sdim  },
2208218822Sdim
2209218822Sdim  /* PREGRP49 */
2210218822Sdim  {
2211218822Sdim    { "(bad)",	{ XX } },
2212218822Sdim    { "(bad)",	{ XX } },
2213218822Sdim    { "pmuldq", { XM, EXx } },
2214218822Sdim    { "(bad)",	{ XX } },
2215218822Sdim  },
2216218822Sdim
2217218822Sdim  /* PREGRP50 */
2218218822Sdim  {
2219218822Sdim    { "(bad)",	{ XX } },
2220218822Sdim    { "(bad)",	{ XX } },
2221218822Sdim    { "pcmpeqq", { XM, EXx } },
2222218822Sdim    { "(bad)",	{ XX } },
2223218822Sdim  },
2224218822Sdim
2225218822Sdim  /* PREGRP51 */
2226218822Sdim  {
2227218822Sdim    { "(bad)",	{ XX } },
2228218822Sdim    { "(bad)",	{ XX } },
2229218822Sdim    { "movntdqa", { XM, EM } },
2230218822Sdim    { "(bad)",	{ XX } },
2231218822Sdim  },
2232218822Sdim
2233218822Sdim  /* PREGRP52 */
2234218822Sdim  {
2235218822Sdim    { "(bad)",	{ XX } },
2236218822Sdim    { "(bad)",	{ XX } },
2237218822Sdim    { "packusdw", { XM, EXx } },
2238218822Sdim    { "(bad)",	{ XX } },
2239218822Sdim  },
2240218822Sdim
2241218822Sdim  /* PREGRP53 */
2242218822Sdim  {
2243218822Sdim    { "(bad)",	{ XX } },
2244218822Sdim    { "(bad)",	{ XX } },
2245218822Sdim    { "pmovzxbw", { XM, EXx } },
2246218822Sdim    { "(bad)",	{ XX } },
2247218822Sdim  },
2248218822Sdim
2249218822Sdim  /* PREGRP54 */
2250218822Sdim  {
2251218822Sdim    { "(bad)",	{ XX } },
2252218822Sdim    { "(bad)",	{ XX } },
2253218822Sdim    { "pmovzxbd", { XM, EXx } },
2254218822Sdim    { "(bad)",	{ XX } },
2255218822Sdim  },
2256218822Sdim
2257218822Sdim  /* PREGRP55 */
2258218822Sdim  {
2259218822Sdim    { "(bad)",	{ XX } },
2260218822Sdim    { "(bad)",	{ XX } },
2261218822Sdim    { "pmovzxbq", { XM, EXx } },
2262218822Sdim    { "(bad)",	{ XX } },
2263218822Sdim  },
2264218822Sdim
2265218822Sdim  /* PREGRP56 */
2266218822Sdim  {
2267218822Sdim    { "(bad)",	{ XX } },
2268218822Sdim    { "(bad)",	{ XX } },
2269218822Sdim    { "pmovzxwd", { XM, EXx } },
2270218822Sdim    { "(bad)",	{ XX } },
2271218822Sdim  },
2272218822Sdim
2273218822Sdim  /* PREGRP57 */
2274218822Sdim  {
2275218822Sdim    { "(bad)",	{ XX } },
2276218822Sdim    { "(bad)",	{ XX } },
2277218822Sdim    { "pmovzxwq", { XM, EXx } },
2278218822Sdim    { "(bad)",	{ XX } },
2279218822Sdim  },
2280218822Sdim
2281218822Sdim  /* PREGRP58 */
2282218822Sdim  {
2283218822Sdim    { "(bad)",	{ XX } },
2284218822Sdim    { "(bad)",	{ XX } },
2285218822Sdim    { "pmovzxdq", { XM, EXx } },
2286218822Sdim    { "(bad)",	{ XX } },
2287218822Sdim  },
2288218822Sdim
2289218822Sdim  /* PREGRP59 */
2290218822Sdim  {
2291218822Sdim    { "(bad)",	{ XX } },
2292218822Sdim    { "(bad)",	{ XX } },
2293218822Sdim    { "pminsb",	{ XM, EXx } },
2294218822Sdim    { "(bad)",	{ XX } },
2295218822Sdim  },
2296218822Sdim
2297218822Sdim  /* PREGRP60 */
2298218822Sdim  {
2299218822Sdim    { "(bad)",	{ XX } },
2300218822Sdim    { "(bad)",	{ XX } },
2301218822Sdim    { "pminsd",	{ XM, EXx } },
2302218822Sdim    { "(bad)",	{ XX } },
2303218822Sdim  },
2304218822Sdim
2305218822Sdim  /* PREGRP61 */
2306218822Sdim  {
2307218822Sdim    { "(bad)",	{ XX } },
2308218822Sdim    { "(bad)",	{ XX } },
2309218822Sdim    { "pminuw",	{ XM, EXx } },
2310218822Sdim    { "(bad)",	{ XX } },
2311218822Sdim  },
2312218822Sdim
2313218822Sdim  /* PREGRP62 */
2314218822Sdim  {
2315218822Sdim    { "(bad)",	{ XX } },
2316218822Sdim    { "(bad)",	{ XX } },
2317218822Sdim    { "pminud",	{ XM, EXx } },
2318218822Sdim    { "(bad)",	{ XX } },
2319218822Sdim  },
2320218822Sdim
2321218822Sdim  /* PREGRP63 */
2322218822Sdim  {
2323218822Sdim    { "(bad)",	{ XX } },
2324218822Sdim    { "(bad)",	{ XX } },
2325218822Sdim    { "pmaxsb",	{ XM, EXx } },
2326218822Sdim    { "(bad)",	{ XX } },
2327218822Sdim  },
2328218822Sdim
2329218822Sdim  /* PREGRP64 */
2330218822Sdim  {
2331218822Sdim    { "(bad)",	{ XX } },
2332218822Sdim    { "(bad)",	{ XX } },
2333218822Sdim    { "pmaxsd",	{ XM, EXx } },
2334218822Sdim    { "(bad)",	{ XX } },
2335218822Sdim  },
2336218822Sdim
2337218822Sdim  /* PREGRP65 */
2338218822Sdim  {
2339218822Sdim    { "(bad)",	{ XX } },
2340218822Sdim    { "(bad)",	{ XX } },
2341218822Sdim    { "pmaxuw", { XM, EXx } },
2342218822Sdim    { "(bad)",	{ XX } },
2343218822Sdim  },
2344218822Sdim
2345218822Sdim  /* PREGRP66 */
2346218822Sdim  {
2347218822Sdim    { "(bad)",	{ XX } },
2348218822Sdim    { "(bad)",	{ XX } },
2349218822Sdim    { "pmaxud", { XM, EXx } },
2350218822Sdim    { "(bad)",	{ XX } },
2351218822Sdim  },
2352218822Sdim
2353218822Sdim  /* PREGRP67 */
2354218822Sdim  {
2355218822Sdim    { "(bad)",	{ XX } },
2356218822Sdim    { "(bad)",	{ XX } },
2357218822Sdim    { "pmulld", { XM, EXx } },
2358218822Sdim    { "(bad)",	{ XX } },
2359218822Sdim  },
2360218822Sdim
2361218822Sdim  /* PREGRP68 */
2362218822Sdim  {
2363218822Sdim    { "(bad)",	{ XX } },
2364218822Sdim    { "(bad)",	{ XX } },
2365218822Sdim    { "phminposuw", { XM, EXx } },
2366218822Sdim    { "(bad)",	{ XX } },
2367218822Sdim  },
2368218822Sdim
2369218822Sdim  /* PREGRP69 */
2370218822Sdim  {
2371218822Sdim    { "(bad)",	{ XX } },
2372218822Sdim    { "(bad)",	{ XX } },
2373218822Sdim    { "roundps", { XM, EXx, Ib } },
2374218822Sdim    { "(bad)",	{ XX } },
2375218822Sdim  },
2376218822Sdim
2377218822Sdim  /* PREGRP70 */
2378218822Sdim  {
2379218822Sdim    { "(bad)",	{ XX } },
2380218822Sdim    { "(bad)",	{ XX } },
2381218822Sdim    { "roundpd", { XM, EXx, Ib } },
2382218822Sdim    { "(bad)",	{ XX } },
2383218822Sdim  },
2384218822Sdim
2385218822Sdim  /* PREGRP71 */
2386218822Sdim  {
2387218822Sdim    { "(bad)",	{ XX } },
2388218822Sdim    { "(bad)",	{ XX } },
2389218822Sdim    { "roundss", { XM, EXx, Ib } },
2390218822Sdim    { "(bad)",	{ XX } },
2391218822Sdim  },
2392218822Sdim
2393218822Sdim  /* PREGRP72 */
2394218822Sdim  {
2395218822Sdim    { "(bad)",	{ XX } },
2396218822Sdim    { "(bad)",	{ XX } },
2397218822Sdim    { "roundsd", { XM, EXx, Ib } },
2398218822Sdim    { "(bad)",	{ XX } },
2399218822Sdim  },
2400218822Sdim
2401218822Sdim  /* PREGRP73 */
2402218822Sdim  {
2403218822Sdim    { "(bad)",	{ XX } },
2404218822Sdim    { "(bad)",	{ XX } },
2405218822Sdim    { "blendps", { XM, EXx, Ib } },
2406218822Sdim    { "(bad)",	{ XX } },
2407218822Sdim  },
2408218822Sdim
2409218822Sdim  /* PREGRP74 */
2410218822Sdim  {
2411218822Sdim    { "(bad)",	{ XX } },
2412218822Sdim    { "(bad)",	{ XX } },
2413218822Sdim    { "blendpd", { XM, EXx, Ib } },
2414218822Sdim    { "(bad)",	{ XX } },
2415218822Sdim  },
2416218822Sdim
2417218822Sdim  /* PREGRP75 */
2418218822Sdim  {
2419218822Sdim    { "(bad)",	{ XX } },
2420218822Sdim    { "(bad)",	{ XX } },
2421218822Sdim    { "pblendw", { XM, EXx, Ib } },
2422218822Sdim    { "(bad)",	{ XX } },
2423218822Sdim  },
2424218822Sdim
2425218822Sdim  /* PREGRP76 */
2426218822Sdim  {
2427218822Sdim    { "(bad)",	{ XX } },
2428218822Sdim    { "(bad)",	{ XX } },
2429218822Sdim    { "pextrb",	{ Edqb, XM, Ib } },
2430218822Sdim    { "(bad)",	{ XX } },
2431218822Sdim  },
2432218822Sdim
2433218822Sdim  /* PREGRP77 */
2434218822Sdim  {
2435218822Sdim    { "(bad)",	{ XX } },
2436218822Sdim    { "(bad)",	{ XX } },
2437218822Sdim    { "pextrw",	{ Edqw, XM, Ib } },
2438218822Sdim    { "(bad)",	{ XX } },
2439218822Sdim  },
2440218822Sdim
2441218822Sdim  /* PREGRP78 */
2442218822Sdim  {
2443218822Sdim    { "(bad)",	{ XX } },
2444218822Sdim    { "(bad)",	{ XX } },
2445218822Sdim    { "pextrK",	{ Edq, XM, Ib } },
2446218822Sdim    { "(bad)",	{ XX } },
2447218822Sdim  },
2448218822Sdim
2449218822Sdim  /* PREGRP79 */
2450218822Sdim  {
2451218822Sdim    { "(bad)",	{ XX } },
2452218822Sdim    { "(bad)",	{ XX } },
2453218822Sdim    { "extractps", { Edqd, XM, Ib } },
2454218822Sdim    { "(bad)",	{ XX } },
2455218822Sdim  },
2456218822Sdim
2457218822Sdim  /* PREGRP80 */
2458218822Sdim  {
2459218822Sdim    { "(bad)",	{ XX } },
2460218822Sdim    { "(bad)",	{ XX } },
2461218822Sdim    { "pinsrb",	{ XM, Edqb, Ib } },
2462218822Sdim    { "(bad)",	{ XX } },
2463218822Sdim  },
2464218822Sdim
2465218822Sdim  /* PREGRP81 */
2466218822Sdim  {
2467218822Sdim    { "(bad)",	{ XX } },
2468218822Sdim    { "(bad)",	{ XX } },
2469218822Sdim    { "insertps", { XM, EXx, Ib } },
2470218822Sdim    { "(bad)",	{ XX } },
2471218822Sdim  },
2472218822Sdim
2473218822Sdim  /* PREGRP82 */
2474218822Sdim  {
2475218822Sdim    { "(bad)",	{ XX } },
2476218822Sdim    { "(bad)",	{ XX } },
2477218822Sdim    { "pinsrK",	{ XM, Edq, Ib } },
2478218822Sdim    { "(bad)",	{ XX } },
2479218822Sdim  },
2480218822Sdim
2481218822Sdim  /* PREGRP83 */
2482218822Sdim  {
2483218822Sdim    { "(bad)",	{ XX } },
2484218822Sdim    { "(bad)",	{ XX } },
2485218822Sdim    { "dpps",	{ XM, EXx, Ib } },
2486218822Sdim    { "(bad)",	{ XX } },
2487218822Sdim  },
2488218822Sdim
2489218822Sdim  /* PREGRP84 */
2490218822Sdim  {
2491218822Sdim    { "(bad)",	{ XX } },
2492218822Sdim    { "(bad)",	{ XX } },
2493218822Sdim    { "dppd",	{ XM, EXx, Ib } },
2494218822Sdim    { "(bad)",	{ XX } },
2495218822Sdim  },
2496218822Sdim
2497218822Sdim  /* PREGRP85 */
2498218822Sdim  {
2499218822Sdim    { "(bad)",	{ XX } },
2500218822Sdim    { "(bad)",	{ XX } },
2501218822Sdim    { "mpsadbw", { XM, EXx, Ib } },
2502218822Sdim    { "(bad)",	{ XX } },
2503218822Sdim  },
2504218822Sdim
2505218822Sdim  /* PREGRP86 */
2506218822Sdim  {
2507218822Sdim    { "(bad)",	{ XX } },
2508218822Sdim    { "(bad)",	{ XX } },
2509218822Sdim    { "pcmpgtq", { XM, EXx } },
2510218822Sdim    { "(bad)",	{ XX } },
2511218822Sdim  },
2512218822Sdim
2513218822Sdim  /* PREGRP87 */
2514218822Sdim  {
2515218822Sdim    { "(bad)",	{ XX } },
2516218822Sdim    { "(bad)",	{ XX } },
2517218822Sdim    { "(bad)",	{ XX } },
2518218822Sdim    { "crc32",	{ Gdq, { CRC32_Fixup, b_mode } } },
2519218822Sdim  },
2520218822Sdim
2521218822Sdim  /* PREGRP88 */
2522218822Sdim  {
2523218822Sdim    { "(bad)",	{ XX } },
2524218822Sdim    { "(bad)",	{ XX } },
2525218822Sdim    { "(bad)",	{ XX } },
2526218822Sdim    { "crc32",	{ Gdq, { CRC32_Fixup, v_mode } } },
2527218822Sdim  },
2528218822Sdim
2529218822Sdim  /* PREGRP89 */
2530218822Sdim  {
2531218822Sdim    { "(bad)",	{ XX } },
2532218822Sdim    { "(bad)",	{ XX } },
2533218822Sdim    { "pcmpestrm", { XM, EXx, Ib } },
2534218822Sdim    { "(bad)",	{ XX } },
2535218822Sdim  },
2536218822Sdim
2537218822Sdim  /* PREGRP90 */
2538218822Sdim  {
2539218822Sdim    { "(bad)",	{ XX } },
2540218822Sdim    { "(bad)",	{ XX } },
2541218822Sdim    { "pcmpestri", { XM, EXx, Ib } },
2542218822Sdim    { "(bad)",	{ XX } },
2543218822Sdim  },
2544218822Sdim
2545218822Sdim  /* PREGRP91 */
2546218822Sdim  {
2547218822Sdim    { "(bad)",	{ XX } },
2548218822Sdim    { "(bad)",	{ XX } },
2549218822Sdim    { "pcmpistrm", { XM, EXx, Ib } },
2550218822Sdim    { "(bad)",	{ XX } },
2551218822Sdim  },
2552218822Sdim
2553218822Sdim  /* PREGRP92 */
2554218822Sdim  {
2555218822Sdim    { "(bad)",	{ XX } },
2556218822Sdim    { "(bad)",	{ XX } },
2557218822Sdim    { "pcmpistri", { XM, EXx, Ib } },
2558218822Sdim    { "(bad)",	{ XX } },
2559218822Sdim  },
2560218822Sdim
2561218822Sdim  /* PREGRP93 */
2562218822Sdim  {
2563218822Sdim    { "ucomiss",{ XM, EXd } },
2564218822Sdim    { "(bad)",	{ XX } },
2565218822Sdim    { "ucomisd",{ XM, EXq } },
2566218822Sdim    { "(bad)",	{ XX } },
2567218822Sdim  },
2568218822Sdim
2569218822Sdim  /* PREGRP94 */
2570218822Sdim  {
2571218822Sdim    { "comiss",	{ XM, EXd } },
2572218822Sdim    { "(bad)",	{ XX } },
2573218822Sdim    { "comisd",	{ XM, EXq } },
2574218822Sdim    { "(bad)",	{ XX } },
2575218822Sdim  },
2576218822Sdim
2577218822Sdim  /* PREGRP95 */
2578218822Sdim  {
2579218822Sdim    { "punpcklbw",{ MX, EMd } },
2580218822Sdim    { "(bad)",	{ XX } },
2581218822Sdim    { "punpcklbw",{ MX, EMq } },
2582218822Sdim    { "(bad)",	{ XX } },
2583218822Sdim  },
2584218822Sdim
2585218822Sdim  /* PREGRP96 */
2586218822Sdim  {
2587218822Sdim    { "punpcklwd",{ MX, EMd } },
2588218822Sdim    { "(bad)",	{ XX } },
2589218822Sdim    { "punpcklwd",{ MX, EMq } },
2590218822Sdim    { "(bad)",	{ XX } },
2591218822Sdim  },
2592218822Sdim
2593218822Sdim  /* PREGRP97 */
2594218822Sdim  {
2595218822Sdim    { "punpckldq",{ MX, EMd } },
2596218822Sdim    { "(bad)",	{ XX } },
2597218822Sdim    { "punpckldq",{ MX, EMq } },
2598218822Sdim    { "(bad)",	{ XX } },
2599218822Sdim  },
2600238167Sjhb
2601238167Sjhb  /* PREGRP98 */
2602238167Sjhb  {
2603238167Sjhb    { "(bad)",	{ XX } },
2604238167Sjhb    { "(bad)",	{ XX } },
2605238167Sjhb    { "invept",	{ Gm, Mo } },
2606238167Sjhb    { "(bad)",	{ XX } },
2607238167Sjhb  },
2608238167Sjhb
2609238167Sjhb  /* PREGRP99 */
2610238167Sjhb  {
2611238167Sjhb    { "(bad)",	{ XX } },
2612238167Sjhb    { "(bad)",	{ XX } },
2613238167Sjhb    { "invvpid",{ Gm, Mo } },
2614238167Sjhb    { "(bad)",	{ XX } },
2615238167Sjhb  },
2616247012Sjmg
2617247012Sjmg  /* PREGRP100 */
2618247012Sjmg  {
2619247012Sjmg    { "(bad)",	{ XX } },
2620247012Sjmg    { "(bad)",	{ XX } },
2621247012Sjmg    { "aesimc", { XM, EXx } },
2622247012Sjmg    { "(bad)",	{ XX } },
2623247012Sjmg  },
2624247012Sjmg
2625247012Sjmg  /* PREGRP101 */
2626247012Sjmg  {
2627247012Sjmg    { "(bad)",	{ XX } },
2628247012Sjmg    { "(bad)",	{ XX } },
2629247012Sjmg    { "aesenc",{ XM, EXx } },
2630247012Sjmg    { "(bad)",	{ XX } },
2631247012Sjmg  },
2632247012Sjmg
2633247012Sjmg  /* PREGRP102 */
2634247012Sjmg  {
2635247012Sjmg    { "(bad)",	{ XX } },
2636247012Sjmg    { "(bad)",	{ XX } },
2637247012Sjmg    { "aesenclast", { XM, EXx } },
2638247012Sjmg    { "(bad)",	{ XX } },
2639247012Sjmg  },
2640247012Sjmg
2641247012Sjmg  /* PREGRP103 */
2642247012Sjmg  {
2643247012Sjmg    { "(bad)",	{ XX } },
2644247012Sjmg    { "(bad)",	{ XX } },
2645247012Sjmg    { "aesdec", { XM, EXx } },
2646247012Sjmg    { "(bad)",	{ XX } },
2647247012Sjmg  },
2648247012Sjmg
2649247012Sjmg  /* PREGRP104 */
2650247012Sjmg  {
2651247012Sjmg    { "(bad)",	{ XX } },
2652247012Sjmg    { "(bad)",	{ XX } },
2653247012Sjmg    { "aesdeclast", { XM, EXx } },
2654247012Sjmg    { "(bad)",	{ XX } },
2655247012Sjmg  },
2656247012Sjmg
2657247012Sjmg  /* PREGRP105 */
2658247012Sjmg  {
2659247012Sjmg    { "(bad)",	{ XX } },
2660247012Sjmg    { "(bad)",	{ XX } },
2661247012Sjmg    { "aeskeygenassist", { XM, EXx, Ib } },
2662247012Sjmg    { "(bad)",	{ XX } },
2663247012Sjmg  },
2664247012Sjmg
2665247012Sjmg  /* PREGRP106 */
2666247012Sjmg  {
2667247012Sjmg    { "(bad)",	{ XX } },
2668247012Sjmg    { "(bad)",	{ XX } },
2669247012Sjmg    { "pclmulqdq", { XM, EXx, Ib } },
2670247012Sjmg    { "(bad)",	{ XX } },
2671247012Sjmg  },
2672255192Sjhb
2673255192Sjhb  /* PREGRP107 */
2674255192Sjhb  {
2675255192Sjhb    { "(bad)",	{ XX } },
2676255192Sjhb    { "(bad)",	{ XX } },
2677255192Sjhb    { "invpcid",{ Gm, Mo } },
2678255192Sjhb    { "(bad)",	{ XX } },
2679255192Sjhb  },
268060484Sobrien};
268133965Sjdp
268285815Sobrienstatic const struct dis386 x86_64_table[][2] = {
268385815Sobrien  {
2684218822Sdim    { "pusha{P|}", { XX } },
2685218822Sdim    { "(bad)", { XX } },
268685815Sobrien  },
2687218822Sdim  {
2688218822Sdim    { "popa{P|}", { XX } },
2689218822Sdim    { "(bad)", { XX } },
2690218822Sdim  },
2691218822Sdim  {
2692218822Sdim    { "bound{S|}", { Gv, Ma } },
2693218822Sdim    { "(bad)", { XX } },
2694218822Sdim  },
2695218822Sdim  {
2696218822Sdim    { "arpl", { Ew, Gw } },
2697218822Sdim    { "movs{||lq|xd}", { Gv, Ed } },
2698218822Sdim  },
269985815Sobrien};
270085815Sobrien
2701218822Sdimstatic const struct dis386 three_byte_table[][256] = {
2702218822Sdim  /* THREE_BYTE_0 */
2703218822Sdim  {
2704218822Sdim    /* 00 */
2705218822Sdim    { "pshufb", { MX, EM } },
2706218822Sdim    { "phaddw", { MX, EM } },
2707218822Sdim    { "phaddd",	{ MX, EM } },
2708218822Sdim    { "phaddsw", { MX, EM } },
2709218822Sdim    { "pmaddubsw", { MX, EM } },
2710218822Sdim    { "phsubw", { MX, EM } },
2711218822Sdim    { "phsubd", { MX, EM } },
2712218822Sdim    { "phsubsw", { MX, EM } },
2713218822Sdim    /* 08 */
2714218822Sdim    { "psignb", { MX, EM } },
2715218822Sdim    { "psignw", { MX, EM } },
2716218822Sdim    { "psignd", { MX, EM } },
2717218822Sdim    { "pmulhrsw", { MX, EM } },
2718218822Sdim    { "(bad)", { XX } },
2719218822Sdim    { "(bad)", { XX } },
2720218822Sdim    { "(bad)", { XX } },
2721218822Sdim    { "(bad)", { XX } },
2722218822Sdim    /* 10 */
2723218822Sdim    { PREGRP39 },
2724218822Sdim    { "(bad)", { XX } },
2725218822Sdim    { "(bad)", { XX } },
2726218822Sdim    { "(bad)", { XX } },
2727218822Sdim    { PREGRP40 },
2728218822Sdim    { PREGRP41 },
2729218822Sdim    { "(bad)", { XX } },
2730218822Sdim    { PREGRP42 },
2731218822Sdim    /* 18 */
2732218822Sdim    { "(bad)", { XX } },
2733218822Sdim    { "(bad)", { XX } },
2734218822Sdim    { "(bad)", { XX } },
2735218822Sdim    { "(bad)", { XX } },
2736218822Sdim    { "pabsb", { MX, EM } },
2737218822Sdim    { "pabsw", { MX, EM } },
2738218822Sdim    { "pabsd", { MX, EM } },
2739218822Sdim    { "(bad)", { XX } },
2740218822Sdim    /* 20 */
2741218822Sdim    { PREGRP43 },
2742218822Sdim    { PREGRP44 },
2743218822Sdim    { PREGRP45 },
2744218822Sdim    { PREGRP46 },
2745218822Sdim    { PREGRP47 },
2746218822Sdim    { PREGRP48 },
2747218822Sdim    { "(bad)", { XX } },
2748218822Sdim    { "(bad)", { XX } },
2749218822Sdim    /* 28 */
2750218822Sdim    { PREGRP49 },
2751218822Sdim    { PREGRP50 },
2752218822Sdim    { PREGRP51 },
2753218822Sdim    { PREGRP52 },
2754218822Sdim    { "(bad)", { XX } },
2755218822Sdim    { "(bad)", { XX } },
2756218822Sdim    { "(bad)", { XX } },
2757218822Sdim    { "(bad)", { XX } },
2758218822Sdim    /* 30 */
2759218822Sdim    { PREGRP53 },
2760218822Sdim    { PREGRP54 },
2761218822Sdim    { PREGRP55 },
2762218822Sdim    { PREGRP56 },
2763218822Sdim    { PREGRP57 },
2764218822Sdim    { PREGRP58 },
2765218822Sdim    { "(bad)", { XX } },
2766218822Sdim    { PREGRP86 },
2767218822Sdim    /* 38 */
2768218822Sdim    { PREGRP59 },
2769218822Sdim    { PREGRP60 },
2770218822Sdim    { PREGRP61 },
2771218822Sdim    { PREGRP62 },
2772218822Sdim    { PREGRP63 },
2773218822Sdim    { PREGRP64 },
2774218822Sdim    { PREGRP65 },
2775218822Sdim    { PREGRP66 },
2776218822Sdim    /* 40 */
2777218822Sdim    { PREGRP67 },
2778218822Sdim    { PREGRP68 },
2779218822Sdim    { "(bad)", { XX } },
2780218822Sdim    { "(bad)", { XX } },
2781218822Sdim    { "(bad)", { XX } },
2782218822Sdim    { "(bad)", { XX } },
2783218822Sdim    { "(bad)", { XX } },
2784218822Sdim    { "(bad)", { XX } },
2785218822Sdim    /* 48 */
2786218822Sdim    { "(bad)", { XX } },
2787218822Sdim    { "(bad)", { XX } },
2788218822Sdim    { "(bad)", { XX } },
2789218822Sdim    { "(bad)", { XX } },
2790218822Sdim    { "(bad)", { XX } },
2791218822Sdim    { "(bad)", { XX } },
2792218822Sdim    { "(bad)", { XX } },
2793218822Sdim    { "(bad)", { XX } },
2794218822Sdim    /* 50 */
2795218822Sdim    { "(bad)", { XX } },
2796218822Sdim    { "(bad)", { XX } },
2797218822Sdim    { "(bad)", { XX } },
2798218822Sdim    { "(bad)", { XX } },
2799218822Sdim    { "(bad)", { XX } },
2800218822Sdim    { "(bad)", { XX } },
2801218822Sdim    { "(bad)", { XX } },
2802218822Sdim    { "(bad)", { XX } },
2803218822Sdim    /* 58 */
2804218822Sdim    { "(bad)", { XX } },
2805218822Sdim    { "(bad)", { XX } },
2806218822Sdim    { "(bad)", { XX } },
2807218822Sdim    { "(bad)", { XX } },
2808218822Sdim    { "(bad)", { XX } },
2809218822Sdim    { "(bad)", { XX } },
2810218822Sdim    { "(bad)", { XX } },
2811218822Sdim    { "(bad)", { XX } },
2812218822Sdim    /* 60 */
2813218822Sdim    { "(bad)", { XX } },
2814218822Sdim    { "(bad)", { XX } },
2815218822Sdim    { "(bad)", { XX } },
2816218822Sdim    { "(bad)", { XX } },
2817218822Sdim    { "(bad)", { XX } },
2818218822Sdim    { "(bad)", { XX } },
2819218822Sdim    { "(bad)", { XX } },
2820218822Sdim    { "(bad)", { XX } },
2821218822Sdim    /* 68 */
2822218822Sdim    { "(bad)", { XX } },
2823218822Sdim    { "(bad)", { XX } },
2824218822Sdim    { "(bad)", { XX } },
2825218822Sdim    { "(bad)", { XX } },
2826218822Sdim    { "(bad)", { XX } },
2827218822Sdim    { "(bad)", { XX } },
2828218822Sdim    { "(bad)", { XX } },
2829218822Sdim    { "(bad)", { XX } },
2830218822Sdim    /* 70 */
2831218822Sdim    { "(bad)", { XX } },
2832218822Sdim    { "(bad)", { XX } },
2833218822Sdim    { "(bad)", { XX } },
2834218822Sdim    { "(bad)", { XX } },
2835218822Sdim    { "(bad)", { XX } },
2836218822Sdim    { "(bad)", { XX } },
2837218822Sdim    { "(bad)", { XX } },
2838218822Sdim    { "(bad)", { XX } },
2839218822Sdim    /* 78 */
2840218822Sdim    { "(bad)", { XX } },
2841218822Sdim    { "(bad)", { XX } },
2842218822Sdim    { "(bad)", { XX } },
2843218822Sdim    { "(bad)", { XX } },
2844218822Sdim    { "(bad)", { XX } },
2845218822Sdim    { "(bad)", { XX } },
2846218822Sdim    { "(bad)", { XX } },
2847218822Sdim    { "(bad)", { XX } },
2848218822Sdim    /* 80 */
2849238167Sjhb    { PREGRP98 },
2850238167Sjhb    { PREGRP99 },
2851255192Sjhb    { PREGRP107 },
2852218822Sdim    { "(bad)", { XX } },
2853218822Sdim    { "(bad)", { XX } },
2854218822Sdim    { "(bad)", { XX } },
2855218822Sdim    { "(bad)", { XX } },
2856218822Sdim    { "(bad)", { XX } },
2857218822Sdim    /* 88 */
2858218822Sdim    { "(bad)", { XX } },
2859218822Sdim    { "(bad)", { XX } },
2860218822Sdim    { "(bad)", { XX } },
2861218822Sdim    { "(bad)", { XX } },
2862218822Sdim    { "(bad)", { XX } },
2863218822Sdim    { "(bad)", { XX } },
2864218822Sdim    { "(bad)", { XX } },
2865218822Sdim    { "(bad)", { XX } },
2866218822Sdim    /* 90 */
2867218822Sdim    { "(bad)", { XX } },
2868218822Sdim    { "(bad)", { XX } },
2869218822Sdim    { "(bad)", { XX } },
2870218822Sdim    { "(bad)", { XX } },
2871218822Sdim    { "(bad)", { XX } },
2872218822Sdim    { "(bad)", { XX } },
2873218822Sdim    { "(bad)", { XX } },
2874218822Sdim    { "(bad)", { XX } },
2875218822Sdim    /* 98 */
2876218822Sdim    { "(bad)", { XX } },
2877218822Sdim    { "(bad)", { XX } },
2878218822Sdim    { "(bad)", { XX } },
2879218822Sdim    { "(bad)", { XX } },
2880218822Sdim    { "(bad)", { XX } },
2881218822Sdim    { "(bad)", { XX } },
2882218822Sdim    { "(bad)", { XX } },
2883218822Sdim    { "(bad)", { XX } },
2884218822Sdim    /* a0 */
2885218822Sdim    { "(bad)", { XX } },
2886218822Sdim    { "(bad)", { XX } },
2887218822Sdim    { "(bad)", { XX } },
2888218822Sdim    { "(bad)", { XX } },
2889218822Sdim    { "(bad)", { XX } },
2890218822Sdim    { "(bad)", { XX } },
2891218822Sdim    { "(bad)", { XX } },
2892218822Sdim    { "(bad)", { XX } },
2893218822Sdim    /* a8 */
2894218822Sdim    { "(bad)", { XX } },
2895218822Sdim    { "(bad)", { XX } },
2896218822Sdim    { "(bad)", { XX } },
2897218822Sdim    { "(bad)", { XX } },
2898218822Sdim    { "(bad)", { XX } },
2899218822Sdim    { "(bad)", { XX } },
2900218822Sdim    { "(bad)", { XX } },
2901218822Sdim    { "(bad)", { XX } },
2902218822Sdim    /* b0 */
2903218822Sdim    { "(bad)", { XX } },
2904218822Sdim    { "(bad)", { XX } },
2905218822Sdim    { "(bad)", { XX } },
2906218822Sdim    { "(bad)", { XX } },
2907218822Sdim    { "(bad)", { XX } },
2908218822Sdim    { "(bad)", { XX } },
2909218822Sdim    { "(bad)", { XX } },
2910218822Sdim    { "(bad)", { XX } },
2911218822Sdim    /* b8 */
2912218822Sdim    { "(bad)", { XX } },
2913218822Sdim    { "(bad)", { XX } },
2914218822Sdim    { "(bad)", { XX } },
2915218822Sdim    { "(bad)", { XX } },
2916218822Sdim    { "(bad)", { XX } },
2917218822Sdim    { "(bad)", { XX } },
2918218822Sdim    { "(bad)", { XX } },
2919218822Sdim    { "(bad)", { XX } },
2920218822Sdim    /* c0 */
2921218822Sdim    { "(bad)", { XX } },
2922218822Sdim    { "(bad)", { XX } },
2923218822Sdim    { "(bad)", { XX } },
2924218822Sdim    { "(bad)", { XX } },
2925218822Sdim    { "(bad)", { XX } },
2926218822Sdim    { "(bad)", { XX } },
2927218822Sdim    { "(bad)", { XX } },
2928218822Sdim    { "(bad)", { XX } },
2929218822Sdim    /* c8 */
2930218822Sdim    { "(bad)", { XX } },
2931218822Sdim    { "(bad)", { XX } },
2932218822Sdim    { "(bad)", { XX } },
2933218822Sdim    { "(bad)", { XX } },
2934218822Sdim    { "(bad)", { XX } },
2935218822Sdim    { "(bad)", { XX } },
2936218822Sdim    { "(bad)", { XX } },
2937218822Sdim    { "(bad)", { XX } },
2938218822Sdim    /* d0 */
2939218822Sdim    { "(bad)", { XX } },
2940218822Sdim    { "(bad)", { XX } },
2941218822Sdim    { "(bad)", { XX } },
2942218822Sdim    { "(bad)", { XX } },
2943218822Sdim    { "(bad)", { XX } },
2944218822Sdim    { "(bad)", { XX } },
2945218822Sdim    { "(bad)", { XX } },
2946218822Sdim    { "(bad)", { XX } },
2947218822Sdim    /* d8 */
2948218822Sdim    { "(bad)", { XX } },
2949218822Sdim    { "(bad)", { XX } },
2950218822Sdim    { "(bad)", { XX } },
2951247012Sjmg    { PREGRP100 },
2952247012Sjmg    { PREGRP101 },
2953247012Sjmg    { PREGRP102 },
2954247012Sjmg    { PREGRP103 },
2955247012Sjmg    { PREGRP104 },
2956218822Sdim    /* e0 */
2957218822Sdim    { "(bad)", { XX } },
2958218822Sdim    { "(bad)", { XX } },
2959218822Sdim    { "(bad)", { XX } },
2960218822Sdim    { "(bad)", { XX } },
2961218822Sdim    { "(bad)", { XX } },
2962218822Sdim    { "(bad)", { XX } },
2963218822Sdim    { "(bad)", { XX } },
2964218822Sdim    { "(bad)", { XX } },
2965218822Sdim    /* e8 */
2966218822Sdim    { "(bad)", { XX } },
2967218822Sdim    { "(bad)", { XX } },
2968218822Sdim    { "(bad)", { XX } },
2969218822Sdim    { "(bad)", { XX } },
2970218822Sdim    { "(bad)", { XX } },
2971218822Sdim    { "(bad)", { XX } },
2972218822Sdim    { "(bad)", { XX } },
2973218822Sdim    { "(bad)", { XX } },
2974218822Sdim    /* f0 */
2975218822Sdim    { PREGRP87 },
2976218822Sdim    { PREGRP88 },
2977218822Sdim    { "(bad)", { XX } },
2978218822Sdim    { "(bad)", { XX } },
2979218822Sdim    { "(bad)", { XX } },
2980218822Sdim    { "(bad)", { XX } },
2981218822Sdim    { "(bad)", { XX } },
2982218822Sdim    { "(bad)", { XX } },
2983218822Sdim    /* f8 */
2984218822Sdim    { "(bad)", { XX } },
2985218822Sdim    { "(bad)", { XX } },
2986218822Sdim    { "(bad)", { XX } },
2987218822Sdim    { "(bad)", { XX } },
2988218822Sdim    { "(bad)", { XX } },
2989218822Sdim    { "(bad)", { XX } },
2990218822Sdim    { "(bad)", { XX } },
2991218822Sdim    { "(bad)", { XX } },
2992218822Sdim  },
2993218822Sdim  /* THREE_BYTE_1 */
2994218822Sdim  {
2995218822Sdim    /* 00 */
2996218822Sdim    { "(bad)", { XX } },
2997218822Sdim    { "(bad)", { XX } },
2998218822Sdim    { "(bad)", { XX } },
2999218822Sdim    { "(bad)", { XX } },
3000218822Sdim    { "(bad)", { XX } },
3001218822Sdim    { "(bad)", { XX } },
3002218822Sdim    { "(bad)", { XX } },
3003218822Sdim    { "(bad)", { XX } },
3004218822Sdim    /* 08 */
3005218822Sdim    { PREGRP69 },
3006218822Sdim    { PREGRP70 },
3007218822Sdim    { PREGRP71 },
3008218822Sdim    { PREGRP72 },
3009218822Sdim    { PREGRP73 },
3010218822Sdim    { PREGRP74 },
3011218822Sdim    { PREGRP75 },
3012218822Sdim    { "palignr", { MX, EM, Ib } },
3013218822Sdim    /* 10 */
3014218822Sdim    { "(bad)", { XX } },
3015218822Sdim    { "(bad)", { XX } },
3016218822Sdim    { "(bad)", { XX } },
3017218822Sdim    { "(bad)", { XX } },
3018218822Sdim    { PREGRP76 },
3019218822Sdim    { PREGRP77 },
3020218822Sdim    { PREGRP78 },
3021218822Sdim    { PREGRP79 },
3022218822Sdim    /* 18 */
3023218822Sdim    { "(bad)", { XX } },
3024218822Sdim    { "(bad)", { XX } },
3025218822Sdim    { "(bad)", { XX } },
3026218822Sdim    { "(bad)", { XX } },
3027218822Sdim    { "(bad)", { XX } },
3028218822Sdim    { "(bad)", { XX } },
3029218822Sdim    { "(bad)", { XX } },
3030218822Sdim    { "(bad)", { XX } },
3031218822Sdim    /* 20 */
3032218822Sdim    { PREGRP80 },
3033218822Sdim    { PREGRP81 },
3034218822Sdim    { PREGRP82 },
3035218822Sdim    { "(bad)", { XX } },
3036218822Sdim    { "(bad)", { XX } },
3037218822Sdim    { "(bad)", { XX } },
3038218822Sdim    { "(bad)", { XX } },
3039218822Sdim    { "(bad)", { XX } },
3040218822Sdim    /* 28 */
3041218822Sdim    { "(bad)", { XX } },
3042218822Sdim    { "(bad)", { XX } },
3043218822Sdim    { "(bad)", { XX } },
3044218822Sdim    { "(bad)", { XX } },
3045218822Sdim    { "(bad)", { XX } },
3046218822Sdim    { "(bad)", { XX } },
3047218822Sdim    { "(bad)", { XX } },
3048218822Sdim    { "(bad)", { XX } },
3049218822Sdim    /* 30 */
3050218822Sdim    { "(bad)", { XX } },
3051218822Sdim    { "(bad)", { XX } },
3052218822Sdim    { "(bad)", { XX } },
3053218822Sdim    { "(bad)", { XX } },
3054218822Sdim    { "(bad)", { XX } },
3055218822Sdim    { "(bad)", { XX } },
3056218822Sdim    { "(bad)", { XX } },
3057218822Sdim    { "(bad)", { XX } },
3058218822Sdim    /* 38 */
3059218822Sdim    { "(bad)", { XX } },
3060218822Sdim    { "(bad)", { XX } },
3061218822Sdim    { "(bad)", { XX } },
3062218822Sdim    { "(bad)", { XX } },
3063218822Sdim    { "(bad)", { XX } },
3064218822Sdim    { "(bad)", { XX } },
3065218822Sdim    { "(bad)", { XX } },
3066218822Sdim    { "(bad)", { XX } },
3067218822Sdim    /* 40 */
3068218822Sdim    { PREGRP83 },
3069218822Sdim    { PREGRP84 },
3070218822Sdim    { PREGRP85 },
3071218822Sdim    { "(bad)", { XX } },
3072247012Sjmg    { PREGRP106 },
3073218822Sdim    { "(bad)", { XX } },
3074218822Sdim    { "(bad)", { XX } },
3075218822Sdim    { "(bad)", { XX } },
3076218822Sdim    /* 48 */
3077218822Sdim    { "(bad)", { XX } },
3078218822Sdim    { "(bad)", { XX } },
3079218822Sdim    { "(bad)", { XX } },
3080218822Sdim    { "(bad)", { XX } },
3081218822Sdim    { "(bad)", { XX } },
3082218822Sdim    { "(bad)", { XX } },
3083218822Sdim    { "(bad)", { XX } },
3084218822Sdim    { "(bad)", { XX } },
3085218822Sdim    /* 50 */
3086218822Sdim    { "(bad)", { XX } },
3087218822Sdim    { "(bad)", { XX } },
3088218822Sdim    { "(bad)", { XX } },
3089218822Sdim    { "(bad)", { XX } },
3090218822Sdim    { "(bad)", { XX } },
3091218822Sdim    { "(bad)", { XX } },
3092218822Sdim    { "(bad)", { XX } },
3093218822Sdim    { "(bad)", { XX } },
3094218822Sdim    /* 58 */
3095218822Sdim    { "(bad)", { XX } },
3096218822Sdim    { "(bad)", { XX } },
3097218822Sdim    { "(bad)", { XX } },
3098218822Sdim    { "(bad)", { XX } },
3099218822Sdim    { "(bad)", { XX } },
3100218822Sdim    { "(bad)", { XX } },
3101218822Sdim    { "(bad)", { XX } },
3102218822Sdim    { "(bad)", { XX } },
3103218822Sdim    /* 60 */
3104218822Sdim    { PREGRP89 },
3105218822Sdim    { PREGRP90 },
3106218822Sdim    { PREGRP91 },
3107218822Sdim    { PREGRP92 },
3108218822Sdim    { "(bad)", { XX } },
3109218822Sdim    { "(bad)", { XX } },
3110218822Sdim    { "(bad)", { XX } },
3111218822Sdim    { "(bad)", { XX } },
3112218822Sdim    /* 68 */
3113218822Sdim    { "(bad)", { XX } },
3114218822Sdim    { "(bad)", { XX } },
3115218822Sdim    { "(bad)", { XX } },
3116218822Sdim    { "(bad)", { XX } },
3117218822Sdim    { "(bad)", { XX } },
3118218822Sdim    { "(bad)", { XX } },
3119218822Sdim    { "(bad)", { XX } },
3120218822Sdim    { "(bad)", { XX } },
3121218822Sdim    /* 70 */
3122218822Sdim    { "(bad)", { XX } },
3123218822Sdim    { "(bad)", { XX } },
3124218822Sdim    { "(bad)", { XX } },
3125218822Sdim    { "(bad)", { XX } },
3126218822Sdim    { "(bad)", { XX } },
3127218822Sdim    { "(bad)", { XX } },
3128218822Sdim    { "(bad)", { XX } },
3129218822Sdim    { "(bad)", { XX } },
3130218822Sdim    /* 78 */
3131218822Sdim    { "(bad)", { XX } },
3132218822Sdim    { "(bad)", { XX } },
3133218822Sdim    { "(bad)", { XX } },
3134218822Sdim    { "(bad)", { XX } },
3135218822Sdim    { "(bad)", { XX } },
3136218822Sdim    { "(bad)", { XX } },
3137218822Sdim    { "(bad)", { XX } },
3138218822Sdim    { "(bad)", { XX } },
3139218822Sdim    /* 80 */
3140218822Sdim    { "(bad)", { XX } },
3141218822Sdim    { "(bad)", { XX } },
3142218822Sdim    { "(bad)", { XX } },
3143218822Sdim    { "(bad)", { XX } },
3144218822Sdim    { "(bad)", { XX } },
3145218822Sdim    { "(bad)", { XX } },
3146218822Sdim    { "(bad)", { XX } },
3147218822Sdim    { "(bad)", { XX } },
3148218822Sdim    /* 88 */
3149218822Sdim    { "(bad)", { XX } },
3150218822Sdim    { "(bad)", { XX } },
3151218822Sdim    { "(bad)", { XX } },
3152218822Sdim    { "(bad)", { XX } },
3153218822Sdim    { "(bad)", { XX } },
3154218822Sdim    { "(bad)", { XX } },
3155218822Sdim    { "(bad)", { XX } },
3156218822Sdim    { "(bad)", { XX } },
3157218822Sdim    /* 90 */
3158218822Sdim    { "(bad)", { XX } },
3159218822Sdim    { "(bad)", { XX } },
3160218822Sdim    { "(bad)", { XX } },
3161218822Sdim    { "(bad)", { XX } },
3162218822Sdim    { "(bad)", { XX } },
3163218822Sdim    { "(bad)", { XX } },
3164218822Sdim    { "(bad)", { XX } },
3165218822Sdim    { "(bad)", { XX } },
3166218822Sdim    /* 98 */
3167218822Sdim    { "(bad)", { XX } },
3168218822Sdim    { "(bad)", { XX } },
3169218822Sdim    { "(bad)", { XX } },
3170218822Sdim    { "(bad)", { XX } },
3171218822Sdim    { "(bad)", { XX } },
3172218822Sdim    { "(bad)", { XX } },
3173218822Sdim    { "(bad)", { XX } },
3174218822Sdim    { "(bad)", { XX } },
3175218822Sdim    /* a0 */
3176218822Sdim    { "(bad)", { XX } },
3177218822Sdim    { "(bad)", { XX } },
3178218822Sdim    { "(bad)", { XX } },
3179218822Sdim    { "(bad)", { XX } },
3180218822Sdim    { "(bad)", { XX } },
3181218822Sdim    { "(bad)", { XX } },
3182218822Sdim    { "(bad)", { XX } },
3183218822Sdim    { "(bad)", { XX } },
3184218822Sdim    /* a8 */
3185218822Sdim    { "(bad)", { XX } },
3186218822Sdim    { "(bad)", { XX } },
3187218822Sdim    { "(bad)", { XX } },
3188218822Sdim    { "(bad)", { XX } },
3189218822Sdim    { "(bad)", { XX } },
3190218822Sdim    { "(bad)", { XX } },
3191218822Sdim    { "(bad)", { XX } },
3192218822Sdim    { "(bad)", { XX } },
3193218822Sdim    /* b0 */
3194218822Sdim    { "(bad)", { XX } },
3195218822Sdim    { "(bad)", { XX } },
3196218822Sdim    { "(bad)", { XX } },
3197218822Sdim    { "(bad)", { XX } },
3198218822Sdim    { "(bad)", { XX } },
3199218822Sdim    { "(bad)", { XX } },
3200218822Sdim    { "(bad)", { XX } },
3201218822Sdim    { "(bad)", { XX } },
3202218822Sdim    /* b8 */
3203218822Sdim    { "(bad)", { XX } },
3204218822Sdim    { "(bad)", { XX } },
3205218822Sdim    { "(bad)", { XX } },
3206218822Sdim    { "(bad)", { XX } },
3207218822Sdim    { "(bad)", { XX } },
3208218822Sdim    { "(bad)", { XX } },
3209218822Sdim    { "(bad)", { XX } },
3210218822Sdim    { "(bad)", { XX } },
3211218822Sdim    /* c0 */
3212218822Sdim    { "(bad)", { XX } },
3213218822Sdim    { "(bad)", { XX } },
3214218822Sdim    { "(bad)", { XX } },
3215218822Sdim    { "(bad)", { XX } },
3216218822Sdim    { "(bad)", { XX } },
3217218822Sdim    { "(bad)", { XX } },
3218218822Sdim    { "(bad)", { XX } },
3219218822Sdim    { "(bad)", { XX } },
3220218822Sdim    /* c8 */
3221218822Sdim    { "(bad)", { XX } },
3222218822Sdim    { "(bad)", { XX } },
3223218822Sdim    { "(bad)", { XX } },
3224218822Sdim    { "(bad)", { XX } },
3225218822Sdim    { "(bad)", { XX } },
3226218822Sdim    { "(bad)", { XX } },
3227218822Sdim    { "(bad)", { XX } },
3228218822Sdim    { "(bad)", { XX } },
3229218822Sdim    /* d0 */
3230218822Sdim    { "(bad)", { XX } },
3231218822Sdim    { "(bad)", { XX } },
3232218822Sdim    { "(bad)", { XX } },
3233218822Sdim    { "(bad)", { XX } },
3234218822Sdim    { "(bad)", { XX } },
3235218822Sdim    { "(bad)", { XX } },
3236218822Sdim    { "(bad)", { XX } },
3237218822Sdim    { "(bad)", { XX } },
3238218822Sdim    /* d8 */
3239218822Sdim    { "(bad)", { XX } },
3240218822Sdim    { "(bad)", { XX } },
3241218822Sdim    { "(bad)", { XX } },
3242218822Sdim    { "(bad)", { XX } },
3243218822Sdim    { "(bad)", { XX } },
3244218822Sdim    { "(bad)", { XX } },
3245218822Sdim    { "(bad)", { XX } },
3246247012Sjmg    { PREGRP105 },
3247218822Sdim    /* e0 */
3248218822Sdim    { "(bad)", { XX } },
3249218822Sdim    { "(bad)", { XX } },
3250218822Sdim    { "(bad)", { XX } },
3251218822Sdim    { "(bad)", { XX } },
3252218822Sdim    { "(bad)", { XX } },
3253218822Sdim    { "(bad)", { XX } },
3254218822Sdim    { "(bad)", { XX } },
3255218822Sdim    { "(bad)", { XX } },
3256218822Sdim    /* e8 */
3257218822Sdim    { "(bad)", { XX } },
3258218822Sdim    { "(bad)", { XX } },
3259218822Sdim    { "(bad)", { XX } },
3260218822Sdim    { "(bad)", { XX } },
3261218822Sdim    { "(bad)", { XX } },
3262218822Sdim    { "(bad)", { XX } },
3263218822Sdim    { "(bad)", { XX } },
3264218822Sdim    { "(bad)", { XX } },
3265218822Sdim    /* f0 */
3266218822Sdim    { "(bad)", { XX } },
3267218822Sdim    { "(bad)", { XX } },
3268218822Sdim    { "(bad)", { XX } },
3269218822Sdim    { "(bad)", { XX } },
3270218822Sdim    { "(bad)", { XX } },
3271218822Sdim    { "(bad)", { XX } },
3272218822Sdim    { "(bad)", { XX } },
3273218822Sdim    { "(bad)", { XX } },
3274218822Sdim    /* f8 */
3275218822Sdim    { "(bad)", { XX } },
3276218822Sdim    { "(bad)", { XX } },
3277218822Sdim    { "(bad)", { XX } },
3278218822Sdim    { "(bad)", { XX } },
3279218822Sdim    { "(bad)", { XX } },
3280218822Sdim    { "(bad)", { XX } },
3281218822Sdim    { "(bad)", { XX } },
3282218822Sdim    { "(bad)", { XX } },
3283218822Sdim  }
3284218822Sdim};
3285218822Sdim
328660484Sobrien#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
328733965Sjdp
328833965Sjdpstatic void
3289130561Sobrienckprefix (void)
329033965Sjdp{
329177298Sobrien  int newrex;
329277298Sobrien  rex = 0;
329333965Sjdp  prefixes = 0;
329460484Sobrien  used_prefixes = 0;
329577298Sobrien  rex_used = 0;
329633965Sjdp  while (1)
329733965Sjdp    {
3298223262Sbenl      (void) FETCH_DATA (the_info, codep + 1);
329977298Sobrien      newrex = 0;
330033965Sjdp      switch (*codep)
330133965Sjdp	{
330277298Sobrien	/* REX prefixes family.  */
330377298Sobrien	case 0x40:
330477298Sobrien	case 0x41:
330577298Sobrien	case 0x42:
330677298Sobrien	case 0x43:
330777298Sobrien	case 0x44:
330877298Sobrien	case 0x45:
330977298Sobrien	case 0x46:
331077298Sobrien	case 0x47:
331177298Sobrien	case 0x48:
331277298Sobrien	case 0x49:
331377298Sobrien	case 0x4a:
331477298Sobrien	case 0x4b:
331577298Sobrien	case 0x4c:
331677298Sobrien	case 0x4d:
331777298Sobrien	case 0x4e:
331877298Sobrien	case 0x4f:
3319218822Sdim	    if (address_mode == mode_64bit)
332077298Sobrien	      newrex = *codep;
332177298Sobrien	    else
332277298Sobrien	      return;
332377298Sobrien	  break;
332433965Sjdp	case 0xf3:
332533965Sjdp	  prefixes |= PREFIX_REPZ;
332633965Sjdp	  break;
332733965Sjdp	case 0xf2:
332833965Sjdp	  prefixes |= PREFIX_REPNZ;
332933965Sjdp	  break;
333033965Sjdp	case 0xf0:
333133965Sjdp	  prefixes |= PREFIX_LOCK;
333233965Sjdp	  break;
333333965Sjdp	case 0x2e:
333433965Sjdp	  prefixes |= PREFIX_CS;
333533965Sjdp	  break;
333633965Sjdp	case 0x36:
333733965Sjdp	  prefixes |= PREFIX_SS;
333833965Sjdp	  break;
333933965Sjdp	case 0x3e:
334033965Sjdp	  prefixes |= PREFIX_DS;
334133965Sjdp	  break;
334233965Sjdp	case 0x26:
334333965Sjdp	  prefixes |= PREFIX_ES;
334433965Sjdp	  break;
334533965Sjdp	case 0x64:
334633965Sjdp	  prefixes |= PREFIX_FS;
334733965Sjdp	  break;
334833965Sjdp	case 0x65:
334933965Sjdp	  prefixes |= PREFIX_GS;
335033965Sjdp	  break;
335133965Sjdp	case 0x66:
335233965Sjdp	  prefixes |= PREFIX_DATA;
335333965Sjdp	  break;
335433965Sjdp	case 0x67:
335560484Sobrien	  prefixes |= PREFIX_ADDR;
335633965Sjdp	  break;
335760484Sobrien	case FWAIT_OPCODE:
335860484Sobrien	  /* fwait is really an instruction.  If there are prefixes
335960484Sobrien	     before the fwait, they belong to the fwait, *not* to the
336060484Sobrien	     following instruction.  */
3361218822Sdim	  if (prefixes || rex)
336260484Sobrien	    {
336360484Sobrien	      prefixes |= PREFIX_FWAIT;
336460484Sobrien	      codep++;
336560484Sobrien	      return;
336660484Sobrien	    }
336760484Sobrien	  prefixes = PREFIX_FWAIT;
336833965Sjdp	  break;
336933965Sjdp	default:
337033965Sjdp	  return;
337133965Sjdp	}
337277298Sobrien      /* Rex is ignored when followed by another prefix.  */
337377298Sobrien      if (rex)
337477298Sobrien	{
3375218822Sdim	  rex_used = rex;
3376218822Sdim	  return;
337777298Sobrien	}
337877298Sobrien      rex = newrex;
337933965Sjdp      codep++;
338033965Sjdp    }
338133965Sjdp}
338233965Sjdp
338360484Sobrien/* Return the name of the prefix byte PREF, or NULL if PREF is not a
338460484Sobrien   prefix byte.  */
338560484Sobrien
338660484Sobrienstatic const char *
3387130561Sobrienprefix_name (int pref, int sizeflag)
338860484Sobrien{
3389218822Sdim  static const char *rexes [16] =
3390218822Sdim    {
3391218822Sdim      "rex",		/* 0x40 */
3392218822Sdim      "rex.B",		/* 0x41 */
3393218822Sdim      "rex.X",		/* 0x42 */
3394218822Sdim      "rex.XB",		/* 0x43 */
3395218822Sdim      "rex.R",		/* 0x44 */
3396218822Sdim      "rex.RB",		/* 0x45 */
3397218822Sdim      "rex.RX",		/* 0x46 */
3398218822Sdim      "rex.RXB",	/* 0x47 */
3399218822Sdim      "rex.W",		/* 0x48 */
3400218822Sdim      "rex.WB",		/* 0x49 */
3401218822Sdim      "rex.WX",		/* 0x4a */
3402218822Sdim      "rex.WXB",	/* 0x4b */
3403218822Sdim      "rex.WR",		/* 0x4c */
3404218822Sdim      "rex.WRB",	/* 0x4d */
3405218822Sdim      "rex.WRX",	/* 0x4e */
3406218822Sdim      "rex.WRXB",	/* 0x4f */
3407218822Sdim    };
3408218822Sdim
340960484Sobrien  switch (pref)
341060484Sobrien    {
341177298Sobrien    /* REX prefixes family.  */
341277298Sobrien    case 0x40:
341377298Sobrien    case 0x41:
341477298Sobrien    case 0x42:
341577298Sobrien    case 0x43:
341677298Sobrien    case 0x44:
341777298Sobrien    case 0x45:
341877298Sobrien    case 0x46:
341977298Sobrien    case 0x47:
342077298Sobrien    case 0x48:
342177298Sobrien    case 0x49:
342277298Sobrien    case 0x4a:
342377298Sobrien    case 0x4b:
342477298Sobrien    case 0x4c:
342577298Sobrien    case 0x4d:
342677298Sobrien    case 0x4e:
342777298Sobrien    case 0x4f:
3428218822Sdim      return rexes [pref - 0x40];
342960484Sobrien    case 0xf3:
343060484Sobrien      return "repz";
343160484Sobrien    case 0xf2:
343260484Sobrien      return "repnz";
343360484Sobrien    case 0xf0:
343460484Sobrien      return "lock";
343560484Sobrien    case 0x2e:
343660484Sobrien      return "cs";
343760484Sobrien    case 0x36:
343860484Sobrien      return "ss";
343960484Sobrien    case 0x3e:
344060484Sobrien      return "ds";
344160484Sobrien    case 0x26:
344260484Sobrien      return "es";
344360484Sobrien    case 0x64:
344460484Sobrien      return "fs";
344560484Sobrien    case 0x65:
344660484Sobrien      return "gs";
344760484Sobrien    case 0x66:
344860484Sobrien      return (sizeflag & DFLAG) ? "data16" : "data32";
344960484Sobrien    case 0x67:
3450218822Sdim      if (address_mode == mode_64bit)
3451130561Sobrien	return (sizeflag & AFLAG) ? "addr32" : "addr64";
345292828Sobrien      else
3453218822Sdim	return (sizeflag & AFLAG) ? "addr16" : "addr32";
345460484Sobrien    case FWAIT_OPCODE:
345560484Sobrien      return "fwait";
345660484Sobrien    default:
345760484Sobrien      return NULL;
345860484Sobrien    }
345960484Sobrien}
346060484Sobrien
3461218822Sdimstatic char op_out[MAX_OPERANDS][100];
3462218822Sdimstatic int op_ad, op_index[MAX_OPERANDS];
3463218822Sdimstatic int two_source_ops;
3464218822Sdimstatic bfd_vma op_address[MAX_OPERANDS];
3465218822Sdimstatic bfd_vma op_riprel[MAX_OPERANDS];
346677298Sobrienstatic bfd_vma start_pc;
3467218822Sdim
346833965Sjdp/*
346933965Sjdp *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
347033965Sjdp *   (see topic "Redundant prefixes" in the "Differences from 8086"
347133965Sjdp *   section of the "Virtual 8086 Mode" chapter.)
347233965Sjdp * 'pc' should be the address of this instruction, it will
347333965Sjdp *   be used to print the target address if this is a relative jump or call
347433965Sjdp * The function returns the length of this instruction in bytes.
347533965Sjdp */
347633965Sjdp
347760484Sobrienstatic char intel_syntax;
347860484Sobrienstatic char open_char;
347960484Sobrienstatic char close_char;
348060484Sobrienstatic char separator_char;
348160484Sobrienstatic char scale_char;
348260484Sobrien
348389857Sobrien/* Here for backwards compatibility.  When gdb stops using
348489857Sobrien   print_insn_i386_att and print_insn_i386_intel these functions can
348589857Sobrien   disappear, and print_insn_i386 be merged into print_insn.  */
348633965Sjdpint
3487130561Sobrienprint_insn_i386_att (bfd_vma pc, disassemble_info *info)
348833965Sjdp{
348960484Sobrien  intel_syntax = 0;
349060484Sobrien
349189857Sobrien  return print_insn (pc, info);
349233965Sjdp}
349333965Sjdp
349433965Sjdpint
3495130561Sobrienprint_insn_i386_intel (bfd_vma pc, disassemble_info *info)
349633965Sjdp{
349760484Sobrien  intel_syntax = 1;
349860484Sobrien
349989857Sobrien  return print_insn (pc, info);
350060484Sobrien}
350160484Sobrien
350289857Sobrienint
3503130561Sobrienprint_insn_i386 (bfd_vma pc, disassemble_info *info)
350460484Sobrien{
350589857Sobrien  intel_syntax = -1;
350689857Sobrien
350789857Sobrien  return print_insn (pc, info);
350889857Sobrien}
350989857Sobrien
3510218822Sdimvoid
3511218822Sdimprint_i386_disassembler_options (FILE *stream)
3512218822Sdim{
3513218822Sdim  fprintf (stream, _("\n\
3514218822SdimThe following i386/x86-64 specific disassembler options are supported for use\n\
3515218822Sdimwith the -M switch (multiple options should be separated by commas):\n"));
3516218822Sdim
3517218822Sdim  fprintf (stream, _("  x86-64      Disassemble in 64bit mode\n"));
3518218822Sdim  fprintf (stream, _("  i386        Disassemble in 32bit mode\n"));
3519218822Sdim  fprintf (stream, _("  i8086       Disassemble in 16bit mode\n"));
3520218822Sdim  fprintf (stream, _("  att         Display instruction in AT&T syntax\n"));
3521218822Sdim  fprintf (stream, _("  intel       Display instruction in Intel syntax\n"));
3522218822Sdim  fprintf (stream, _("  addr64      Assume 64bit address size\n"));
3523218822Sdim  fprintf (stream, _("  addr32      Assume 32bit address size\n"));
3524218822Sdim  fprintf (stream, _("  addr16      Assume 16bit address size\n"));
3525218822Sdim  fprintf (stream, _("  data32      Assume 32bit data size\n"));
3526218822Sdim  fprintf (stream, _("  data16      Assume 16bit data size\n"));
3527218822Sdim  fprintf (stream, _("  suffix      Always display instruction suffix in AT&T syntax\n"));
3528218822Sdim}
3529218822Sdim
353089857Sobrienstatic int
3531130561Sobrienprint_insn (bfd_vma pc, disassemble_info *info)
353289857Sobrien{
353360484Sobrien  const struct dis386 *dp;
353433965Sjdp  int i;
3535218822Sdim  char *op_txt[MAX_OPERANDS];
353633965Sjdp  int needcomma;
3537218822Sdim  unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3538218822Sdim  unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
353989857Sobrien  int sizeflag;
354089857Sobrien  const char *p;
354133965Sjdp  struct dis_private priv;
3542218822Sdim  unsigned char op;
354333965Sjdp
3544218822Sdim  if (info->mach == bfd_mach_x86_64_intel_syntax
3545218822Sdim      || info->mach == bfd_mach_x86_64)
3546218822Sdim    address_mode = mode_64bit;
3547218822Sdim  else
3548218822Sdim    address_mode = mode_32bit;
354977298Sobrien
3550130561Sobrien  if (intel_syntax == (char) -1)
355189857Sobrien    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
355289857Sobrien		    || info->mach == bfd_mach_x86_64_intel_syntax);
355389857Sobrien
355460484Sobrien  if (info->mach == bfd_mach_i386_i386
355577298Sobrien      || info->mach == bfd_mach_x86_64
355677298Sobrien      || info->mach == bfd_mach_i386_i386_intel_syntax
355777298Sobrien      || info->mach == bfd_mach_x86_64_intel_syntax)
355889857Sobrien    priv.orig_sizeflag = AFLAG | DFLAG;
355960484Sobrien  else if (info->mach == bfd_mach_i386_i8086)
356089857Sobrien    priv.orig_sizeflag = 0;
356160484Sobrien  else
356260484Sobrien    abort ();
356333965Sjdp
356489857Sobrien  for (p = info->disassembler_options; p != NULL; )
356589857Sobrien    {
3566218822Sdim      if (CONST_STRNEQ (p, "x86-64"))
356789857Sobrien	{
3568218822Sdim	  address_mode = mode_64bit;
356989857Sobrien	  priv.orig_sizeflag = AFLAG | DFLAG;
357089857Sobrien	}
3571218822Sdim      else if (CONST_STRNEQ (p, "i386"))
357289857Sobrien	{
3573218822Sdim	  address_mode = mode_32bit;
357489857Sobrien	  priv.orig_sizeflag = AFLAG | DFLAG;
357589857Sobrien	}
3576218822Sdim      else if (CONST_STRNEQ (p, "i8086"))
357789857Sobrien	{
3578218822Sdim	  address_mode = mode_16bit;
357989857Sobrien	  priv.orig_sizeflag = 0;
358089857Sobrien	}
3581218822Sdim      else if (CONST_STRNEQ (p, "intel"))
358289857Sobrien	{
358389857Sobrien	  intel_syntax = 1;
358489857Sobrien	}
3585218822Sdim      else if (CONST_STRNEQ (p, "att"))
358689857Sobrien	{
358789857Sobrien	  intel_syntax = 0;
358889857Sobrien	}
3589218822Sdim      else if (CONST_STRNEQ (p, "addr"))
359089857Sobrien	{
3591218822Sdim	  if (address_mode == mode_64bit)
3592218822Sdim	    {
3593218822Sdim	      if (p[4] == '3' && p[5] == '2')
3594218822Sdim		priv.orig_sizeflag &= ~AFLAG;
3595218822Sdim	      else if (p[4] == '6' && p[5] == '4')
3596218822Sdim		priv.orig_sizeflag |= AFLAG;
3597218822Sdim	    }
3598218822Sdim	  else
3599218822Sdim	    {
3600218822Sdim	      if (p[4] == '1' && p[5] == '6')
3601218822Sdim		priv.orig_sizeflag &= ~AFLAG;
3602218822Sdim	      else if (p[4] == '3' && p[5] == '2')
3603218822Sdim		priv.orig_sizeflag |= AFLAG;
3604218822Sdim	    }
360589857Sobrien	}
3606218822Sdim      else if (CONST_STRNEQ (p, "data"))
360789857Sobrien	{
360889857Sobrien	  if (p[4] == '1' && p[5] == '6')
360989857Sobrien	    priv.orig_sizeflag &= ~DFLAG;
361089857Sobrien	  else if (p[4] == '3' && p[5] == '2')
361189857Sobrien	    priv.orig_sizeflag |= DFLAG;
361289857Sobrien	}
3613218822Sdim      else if (CONST_STRNEQ (p, "suffix"))
361489857Sobrien	priv.orig_sizeflag |= SUFFIX_ALWAYS;
361589857Sobrien
361689857Sobrien      p = strchr (p, ',');
361789857Sobrien      if (p != NULL)
361889857Sobrien	p++;
361989857Sobrien    }
362089857Sobrien
362189857Sobrien  if (intel_syntax)
362289857Sobrien    {
362389857Sobrien      names64 = intel_names64;
362489857Sobrien      names32 = intel_names32;
362589857Sobrien      names16 = intel_names16;
362689857Sobrien      names8 = intel_names8;
362789857Sobrien      names8rex = intel_names8rex;
362889857Sobrien      names_seg = intel_names_seg;
362989857Sobrien      index16 = intel_index16;
363089857Sobrien      open_char = '[';
363189857Sobrien      close_char = ']';
363289857Sobrien      separator_char = '+';
363389857Sobrien      scale_char = '*';
363489857Sobrien    }
363589857Sobrien  else
363689857Sobrien    {
363789857Sobrien      names64 = att_names64;
363889857Sobrien      names32 = att_names32;
363989857Sobrien      names16 = att_names16;
364089857Sobrien      names8 = att_names8;
364189857Sobrien      names8rex = att_names8rex;
364289857Sobrien      names_seg = att_names_seg;
364389857Sobrien      index16 = att_index16;
364489857Sobrien      open_char = '(';
364589857Sobrien      close_char =  ')';
364689857Sobrien      separator_char = ',';
364789857Sobrien      scale_char = ',';
364889857Sobrien    }
364989857Sobrien
365060484Sobrien  /* The output looks better if we put 7 bytes on a line, since that
365160484Sobrien     puts most long word instructions on a single line.  */
365260484Sobrien  info->bytes_per_line = 7;
365360484Sobrien
3654130561Sobrien  info->private_data = &priv;
365533965Sjdp  priv.max_fetched = priv.the_buffer;
365633965Sjdp  priv.insn_start = pc;
365733965Sjdp
365833965Sjdp  obuf[0] = 0;
3659218822Sdim  for (i = 0; i < MAX_OPERANDS; ++i)
3660218822Sdim    {
3661218822Sdim      op_out[i][0] = 0;
3662218822Sdim      op_index[i] = -1;
3663218822Sdim    }
366433965Sjdp
366533965Sjdp  the_info = info;
366633965Sjdp  start_pc = pc;
366789857Sobrien  start_codep = priv.the_buffer;
366889857Sobrien  codep = priv.the_buffer;
366960484Sobrien
367060484Sobrien  if (setjmp (priv.bailout) != 0)
367160484Sobrien    {
367260484Sobrien      const char *name;
367360484Sobrien
367460484Sobrien      /* Getting here means we tried for data but didn't get it.  That
367589857Sobrien	 means we have an incomplete instruction of some sort.  Just
367689857Sobrien	 print the first byte as a prefix or a .byte pseudo-op.  */
367789857Sobrien      if (codep > priv.the_buffer)
367860484Sobrien	{
367989857Sobrien	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
368060484Sobrien	  if (name != NULL)
368160484Sobrien	    (*info->fprintf_func) (info->stream, "%s", name);
368260484Sobrien	  else
368360484Sobrien	    {
368460484Sobrien	      /* Just print the first byte as a .byte instruction.  */
368560484Sobrien	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
368689857Sobrien				     (unsigned int) priv.the_buffer[0]);
368760484Sobrien	    }
368860484Sobrien
368960484Sobrien	  return 1;
369060484Sobrien	}
369160484Sobrien
369260484Sobrien      return -1;
369360484Sobrien    }
369460484Sobrien
369577298Sobrien  obufp = obuf;
369633965Sjdp  ckprefix ();
369733965Sjdp
369860484Sobrien  insn_codep = codep;
369989857Sobrien  sizeflag = priv.orig_sizeflag;
370060484Sobrien
3701223262Sbenl  (void) FETCH_DATA (info, codep + 1);
370260484Sobrien  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
370360484Sobrien
3704218822Sdim  if (((prefixes & PREFIX_FWAIT)
3705218822Sdim       && ((*codep < 0xd8) || (*codep > 0xdf)))
3706218822Sdim      || (rex && rex_used))
370733965Sjdp    {
370860484Sobrien      const char *name;
370960484Sobrien
3710218822Sdim      /* fwait not followed by floating point instruction, or rex followed
3711218822Sdim	 by other prefixes.  Print the first prefix.  */
371289857Sobrien      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
371360484Sobrien      if (name == NULL)
371460484Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
371560484Sobrien      (*info->fprintf_func) (info->stream, "%s", name);
371660484Sobrien      return 1;
371733965Sjdp    }
371860484Sobrien
3719218822Sdim  op = 0;
372033965Sjdp  if (*codep == 0x0f)
372133965Sjdp    {
3722218822Sdim      unsigned char threebyte;
3723223262Sbenl      (void) FETCH_DATA (info, codep + 2);
3724218822Sdim      threebyte = *++codep;
3725218822Sdim      dp = &dis386_twobyte[threebyte];
372633965Sjdp      need_modrm = twobyte_has_modrm[*codep];
3727218822Sdim      uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3728218822Sdim      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3729218822Sdim      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3730218822Sdim      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3731218822Sdim      codep++;
3732218822Sdim      if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3733218822Sdim	{
3734223262Sbenl	  (void) FETCH_DATA (info, codep + 2);
3735218822Sdim	  op = *codep++;
3736218822Sdim	  switch (threebyte)
3737218822Sdim	    {
3738218822Sdim	    case 0x38:
3739218822Sdim	      uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3740218822Sdim	      uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3741218822Sdim	      uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3742218822Sdim	      break;
3743218822Sdim	    case 0x3a:
3744218822Sdim	      uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3745218822Sdim	      uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3746218822Sdim	      uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3747218822Sdim	      break;
3748218822Sdim	    default:
3749218822Sdim	      break;
3750218822Sdim	    }
3751218822Sdim	}
375233965Sjdp    }
375333965Sjdp  else
375433965Sjdp    {
375585815Sobrien      dp = &dis386[*codep];
375633965Sjdp      need_modrm = onebyte_has_modrm[*codep];
3757218822Sdim      uses_DATA_prefix = 0;
3758218822Sdim      uses_REPNZ_prefix = 0;
3759218822Sdim      /* pause is 0xf3 0x90.  */
3760218822Sdim      uses_REPZ_prefix = *codep == 0x90;
3761218822Sdim      uses_LOCK_prefix = 0;
3762218822Sdim      codep++;
376333965Sjdp    }
376433965Sjdp
3765218822Sdim  if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
376660484Sobrien    {
376760484Sobrien      oappend ("repz ");
376860484Sobrien      used_prefixes |= PREFIX_REPZ;
376960484Sobrien    }
3770218822Sdim  if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
377160484Sobrien    {
377260484Sobrien      oappend ("repnz ");
377360484Sobrien      used_prefixes |= PREFIX_REPNZ;
377460484Sobrien    }
3775218822Sdim
3776218822Sdim  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
377760484Sobrien    {
377860484Sobrien      oappend ("lock ");
377960484Sobrien      used_prefixes |= PREFIX_LOCK;
378060484Sobrien    }
378160484Sobrien
378260484Sobrien  if (prefixes & PREFIX_ADDR)
378360484Sobrien    {
378460484Sobrien      sizeflag ^= AFLAG;
3785218822Sdim      if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
378678828Sobrien	{
3787218822Sdim	  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
378878828Sobrien	    oappend ("addr32 ");
378978828Sobrien	  else
379078828Sobrien	    oappend ("addr16 ");
379178828Sobrien	  used_prefixes |= PREFIX_ADDR;
379278828Sobrien	}
379360484Sobrien    }
379460484Sobrien
3795218822Sdim  if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
379678828Sobrien    {
379778828Sobrien      sizeflag ^= DFLAG;
3798218822Sdim      if (dp->op[2].bytemode == cond_jump_mode
3799218822Sdim	  && dp->op[0].bytemode == v_mode
380085815Sobrien	  && !intel_syntax)
380178828Sobrien	{
380278828Sobrien	  if (sizeflag & DFLAG)
380378828Sobrien	    oappend ("data32 ");
380478828Sobrien	  else
380578828Sobrien	    oappend ("data16 ");
380678828Sobrien	  used_prefixes |= PREFIX_DATA;
380778828Sobrien	}
380878828Sobrien    }
380978828Sobrien
3810218822Sdim  if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
381133965Sjdp    {
3812218822Sdim      dp = &three_byte_table[dp->op[1].bytemode][op];
3813218822Sdim      modrm.mod = (*codep >> 6) & 3;
3814218822Sdim      modrm.reg = (*codep >> 3) & 7;
3815218822Sdim      modrm.rm = *codep & 7;
3816218822Sdim    }
3817218822Sdim  else if (need_modrm)
3818218822Sdim    {
3819223262Sbenl      (void) FETCH_DATA (info, codep + 1);
3820218822Sdim      modrm.mod = (*codep >> 6) & 3;
3821218822Sdim      modrm.reg = (*codep >> 3) & 7;
3822218822Sdim      modrm.rm = *codep & 7;
382333965Sjdp    }
382433965Sjdp
3825218822Sdim  if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
382633965Sjdp    {
382760484Sobrien      dofloat (sizeflag);
382833965Sjdp    }
382933965Sjdp  else
383033965Sjdp    {
383177298Sobrien      int index;
383233965Sjdp      if (dp->name == NULL)
383360484Sobrien	{
3834218822Sdim	  switch (dp->op[0].bytemode)
383560484Sobrien	    {
383685815Sobrien	    case USE_GROUPS:
3837218822Sdim	      dp = &grps[dp->op[1].bytemode][modrm.reg];
383885815Sobrien	      break;
383985815Sobrien
384085815Sobrien	    case USE_PREFIX_USER_TABLE:
384185815Sobrien	      index = 0;
384285815Sobrien	      used_prefixes |= (prefixes & PREFIX_REPZ);
384385815Sobrien	      if (prefixes & PREFIX_REPZ)
384485815Sobrien		index = 1;
384585815Sobrien	      else
384685815Sobrien		{
3847218822Sdim		  /* We should check PREFIX_REPNZ and PREFIX_REPZ
3848218822Sdim		     before PREFIX_DATA.  */
3849218822Sdim		  used_prefixes |= (prefixes & PREFIX_REPNZ);
3850218822Sdim		  if (prefixes & PREFIX_REPNZ)
3851218822Sdim		    index = 3;
385285815Sobrien		  else
385385815Sobrien		    {
3854218822Sdim		      used_prefixes |= (prefixes & PREFIX_DATA);
3855218822Sdim		      if (prefixes & PREFIX_DATA)
3856218822Sdim			index = 2;
385785815Sobrien		    }
385885815Sobrien		}
3859218822Sdim	      dp = &prefix_user_table[dp->op[1].bytemode][index];
386085815Sobrien	      break;
386185815Sobrien
386285815Sobrien	    case X86_64_SPECIAL:
3863218822Sdim	      index = address_mode == mode_64bit ? 1 : 0;
3864218822Sdim	      dp = &x86_64_table[dp->op[1].bytemode][index];
386585815Sobrien	      break;
386685815Sobrien
386785815Sobrien	    default:
386885815Sobrien	      oappend (INTERNAL_DISASSEMBLER_ERROR);
386985815Sobrien	      break;
387060484Sobrien	    }
387160484Sobrien	}
387260484Sobrien
387385815Sobrien      if (putop (dp->name, sizeflag) == 0)
3874218822Sdim        {
3875218822Sdim	  for (i = 0; i < MAX_OPERANDS; ++i)
3876218822Sdim	    {
3877218822Sdim	      obufp = op_out[i];
3878218822Sdim	      op_ad = MAX_OPERANDS - 1 - i;
3879218822Sdim	      if (dp->op[i].rtn)
3880218822Sdim		(*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3881218822Sdim	    }
388285815Sobrien	}
388333965Sjdp    }
388460484Sobrien
388560484Sobrien  /* See if any prefixes were not used.  If so, print the first one
388660484Sobrien     separately.  If we don't do this, we'll wind up printing an
388760484Sobrien     instruction stream which does not precisely correspond to the
388860484Sobrien     bytes we are disassembling.  */
388960484Sobrien  if ((prefixes & ~used_prefixes) != 0)
389060484Sobrien    {
389160484Sobrien      const char *name;
389260484Sobrien
389389857Sobrien      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
389460484Sobrien      if (name == NULL)
389560484Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
389660484Sobrien      (*info->fprintf_func) (info->stream, "%s", name);
389760484Sobrien      return 1;
389860484Sobrien    }
389977298Sobrien  if (rex & ~rex_used)
390077298Sobrien    {
390177298Sobrien      const char *name;
390289857Sobrien      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
390377298Sobrien      if (name == NULL)
390477298Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
390577298Sobrien      (*info->fprintf_func) (info->stream, "%s ", name);
390677298Sobrien    }
390760484Sobrien
390833965Sjdp  obufp = obuf + strlen (obuf);
390933965Sjdp  for (i = strlen (obuf); i < 6; i++)
391033965Sjdp    oappend (" ");
391133965Sjdp  oappend (" ");
391233965Sjdp  (*info->fprintf_func) (info->stream, "%s", obuf);
391360484Sobrien
391460484Sobrien  /* The enter and bound instructions are printed with operands in the same
391560484Sobrien     order as the intel book; everything else is printed in reverse order.  */
391660484Sobrien  if (intel_syntax || two_source_ops)
391733965Sjdp    {
3918218822Sdim      bfd_vma riprel;
3919218822Sdim
3920218822Sdim      for (i = 0; i < MAX_OPERANDS; ++i)
3921218822Sdim        op_txt[i] = op_out[i];
3922218822Sdim
3923218822Sdim      for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3924218822Sdim	{
3925218822Sdim          op_ad = op_index[i];
3926218822Sdim          op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3927218822Sdim          op_index[MAX_OPERANDS - 1 - i] = op_ad;
3928218822Sdim	  riprel = op_riprel[i];
3929218822Sdim	  op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
3930218822Sdim	  op_riprel[MAX_OPERANDS - 1 - i] = riprel;
3931218822Sdim	}
393233965Sjdp    }
393333965Sjdp  else
393433965Sjdp    {
3935218822Sdim      for (i = 0; i < MAX_OPERANDS; ++i)
3936218822Sdim        op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
393733965Sjdp    }
3938218822Sdim
393933965Sjdp  needcomma = 0;
3940218822Sdim  for (i = 0; i < MAX_OPERANDS; ++i)
3941218822Sdim    if (*op_txt[i])
3942218822Sdim      {
3943218822Sdim	if (needcomma)
3944218822Sdim	  (*info->fprintf_func) (info->stream, ",");
3945218822Sdim	if (op_index[i] != -1 && !op_riprel[i])
3946218822Sdim	  (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3947218822Sdim	else
3948218822Sdim	  (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3949218822Sdim	needcomma = 1;
3950218822Sdim      }
3951218822Sdim
3952218822Sdim  for (i = 0; i < MAX_OPERANDS; i++)
395377298Sobrien    if (op_index[i] != -1 && op_riprel[i])
395477298Sobrien      {
395577298Sobrien	(*info->fprintf_func) (info->stream, "        # ");
395677298Sobrien	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
395777298Sobrien						+ op_address[op_index[i]]), info);
3958218822Sdim	break;
395977298Sobrien      }
396089857Sobrien  return codep - priv.the_buffer;
396133965Sjdp}
396233965Sjdp
396385815Sobrienstatic const char *float_mem[] = {
396433965Sjdp  /* d8 */
396585815Sobrien  "fadd{s||s|}",
396685815Sobrien  "fmul{s||s|}",
396785815Sobrien  "fcom{s||s|}",
396885815Sobrien  "fcomp{s||s|}",
396985815Sobrien  "fsub{s||s|}",
397085815Sobrien  "fsubr{s||s|}",
397185815Sobrien  "fdiv{s||s|}",
397285815Sobrien  "fdivr{s||s|}",
3973130561Sobrien  /* d9 */
397485815Sobrien  "fld{s||s|}",
397533965Sjdp  "(bad)",
397685815Sobrien  "fst{s||s|}",
397785815Sobrien  "fstp{s||s|}",
3978218822Sdim  "fldenvIC",
397933965Sjdp  "fldcw",
3980218822Sdim  "fNstenvIC",
398133965Sjdp  "fNstcw",
398233965Sjdp  /* da */
398385815Sobrien  "fiadd{l||l|}",
398485815Sobrien  "fimul{l||l|}",
398585815Sobrien  "ficom{l||l|}",
398685815Sobrien  "ficomp{l||l|}",
398785815Sobrien  "fisub{l||l|}",
398885815Sobrien  "fisubr{l||l|}",
398985815Sobrien  "fidiv{l||l|}",
399085815Sobrien  "fidivr{l||l|}",
399133965Sjdp  /* db */
399285815Sobrien  "fild{l||l|}",
3993130561Sobrien  "fisttp{l||l|}",
399485815Sobrien  "fist{l||l|}",
399585815Sobrien  "fistp{l||l|}",
399633965Sjdp  "(bad)",
399785815Sobrien  "fld{t||t|}",
399833965Sjdp  "(bad)",
399985815Sobrien  "fstp{t||t|}",
400033965Sjdp  /* dc */
400185815Sobrien  "fadd{l||l|}",
400285815Sobrien  "fmul{l||l|}",
400385815Sobrien  "fcom{l||l|}",
400485815Sobrien  "fcomp{l||l|}",
400585815Sobrien  "fsub{l||l|}",
400685815Sobrien  "fsubr{l||l|}",
400785815Sobrien  "fdiv{l||l|}",
400885815Sobrien  "fdivr{l||l|}",
400933965Sjdp  /* dd */
401085815Sobrien  "fld{l||l|}",
4011218822Sdim  "fisttp{ll||ll|}",
401285815Sobrien  "fst{l||l|}",
401385815Sobrien  "fstp{l||l|}",
4014218822Sdim  "frstorIC",
401533965Sjdp  "(bad)",
4016218822Sdim  "fNsaveIC",
401733965Sjdp  "fNstsw",
401833965Sjdp  /* de */
401933965Sjdp  "fiadd",
402033965Sjdp  "fimul",
402133965Sjdp  "ficom",
402233965Sjdp  "ficomp",
402333965Sjdp  "fisub",
402433965Sjdp  "fisubr",
402533965Sjdp  "fidiv",
402633965Sjdp  "fidivr",
402733965Sjdp  /* df */
402833965Sjdp  "fild",
4029130561Sobrien  "fisttp",
403033965Sjdp  "fist",
403133965Sjdp  "fistp",
403233965Sjdp  "fbld",
403385815Sobrien  "fild{ll||ll|}",
403433965Sjdp  "fbstp",
4035218822Sdim  "fistp{ll||ll|}",
403633965Sjdp};
403733965Sjdp
4038218822Sdimstatic const unsigned char float_mem_mode[] = {
4039218822Sdim  /* d8 */
4040218822Sdim  d_mode,
4041218822Sdim  d_mode,
4042218822Sdim  d_mode,
4043218822Sdim  d_mode,
4044218822Sdim  d_mode,
4045218822Sdim  d_mode,
4046218822Sdim  d_mode,
4047218822Sdim  d_mode,
4048218822Sdim  /* d9 */
4049218822Sdim  d_mode,
4050218822Sdim  0,
4051218822Sdim  d_mode,
4052218822Sdim  d_mode,
4053218822Sdim  0,
4054218822Sdim  w_mode,
4055218822Sdim  0,
4056218822Sdim  w_mode,
4057218822Sdim  /* da */
4058218822Sdim  d_mode,
4059218822Sdim  d_mode,
4060218822Sdim  d_mode,
4061218822Sdim  d_mode,
4062218822Sdim  d_mode,
4063218822Sdim  d_mode,
4064218822Sdim  d_mode,
4065218822Sdim  d_mode,
4066218822Sdim  /* db */
4067218822Sdim  d_mode,
4068218822Sdim  d_mode,
4069218822Sdim  d_mode,
4070218822Sdim  d_mode,
4071218822Sdim  0,
4072218822Sdim  t_mode,
4073218822Sdim  0,
4074218822Sdim  t_mode,
4075218822Sdim  /* dc */
4076218822Sdim  q_mode,
4077218822Sdim  q_mode,
4078218822Sdim  q_mode,
4079218822Sdim  q_mode,
4080218822Sdim  q_mode,
4081218822Sdim  q_mode,
4082218822Sdim  q_mode,
4083218822Sdim  q_mode,
4084218822Sdim  /* dd */
4085218822Sdim  q_mode,
4086218822Sdim  q_mode,
4087218822Sdim  q_mode,
4088218822Sdim  q_mode,
4089218822Sdim  0,
4090218822Sdim  0,
4091218822Sdim  0,
4092218822Sdim  w_mode,
4093218822Sdim  /* de */
4094218822Sdim  w_mode,
4095218822Sdim  w_mode,
4096218822Sdim  w_mode,
4097218822Sdim  w_mode,
4098218822Sdim  w_mode,
4099218822Sdim  w_mode,
4100218822Sdim  w_mode,
4101218822Sdim  w_mode,
4102218822Sdim  /* df */
4103218822Sdim  w_mode,
4104218822Sdim  w_mode,
4105218822Sdim  w_mode,
4106218822Sdim  w_mode,
4107218822Sdim  t_mode,
4108218822Sdim  q_mode,
4109218822Sdim  t_mode,
4110218822Sdim  q_mode
4111218822Sdim};
411233965Sjdp
4113218822Sdim#define ST { OP_ST, 0 }
4114218822Sdim#define STi { OP_STi, 0 }
411533965Sjdp
4116218822Sdim#define FGRPd9_2 NULL, { { NULL, 0 } }
4117218822Sdim#define FGRPd9_4 NULL, { { NULL, 1 } }
4118218822Sdim#define FGRPd9_5 NULL, { { NULL, 2 } }
4119218822Sdim#define FGRPd9_6 NULL, { { NULL, 3 } }
4120218822Sdim#define FGRPd9_7 NULL, { { NULL, 4 } }
4121218822Sdim#define FGRPda_5 NULL, { { NULL, 5 } }
4122218822Sdim#define FGRPdb_4 NULL, { { NULL, 6 } }
4123218822Sdim#define FGRPde_3 NULL, { { NULL, 7 } }
4124218822Sdim#define FGRPdf_4 NULL, { { NULL, 8 } }
4125218822Sdim
412660484Sobrienstatic const struct dis386 float_reg[][8] = {
412733965Sjdp  /* d8 */
412833965Sjdp  {
4129218822Sdim    { "fadd",	{ ST, STi } },
4130218822Sdim    { "fmul",	{ ST, STi } },
4131218822Sdim    { "fcom",	{ STi } },
4132218822Sdim    { "fcomp",	{ STi } },
4133218822Sdim    { "fsub",	{ ST, STi } },
4134218822Sdim    { "fsubr",	{ ST, STi } },
4135218822Sdim    { "fdiv",	{ ST, STi } },
4136218822Sdim    { "fdivr",	{ ST, STi } },
413733965Sjdp  },
413833965Sjdp  /* d9 */
413933965Sjdp  {
4140218822Sdim    { "fld",	{ STi } },
4141218822Sdim    { "fxch",	{ STi } },
414233965Sjdp    { FGRPd9_2 },
4143218822Sdim    { "(bad)",	{ XX } },
414433965Sjdp    { FGRPd9_4 },
414533965Sjdp    { FGRPd9_5 },
414633965Sjdp    { FGRPd9_6 },
414733965Sjdp    { FGRPd9_7 },
414833965Sjdp  },
414933965Sjdp  /* da */
415033965Sjdp  {
4151218822Sdim    { "fcmovb",	{ ST, STi } },
4152218822Sdim    { "fcmove",	{ ST, STi } },
4153218822Sdim    { "fcmovbe",{ ST, STi } },
4154218822Sdim    { "fcmovu",	{ ST, STi } },
4155218822Sdim    { "(bad)",	{ XX } },
415633965Sjdp    { FGRPda_5 },
4157218822Sdim    { "(bad)",	{ XX } },
4158218822Sdim    { "(bad)",	{ XX } },
415933965Sjdp  },
416033965Sjdp  /* db */
416133965Sjdp  {
4162218822Sdim    { "fcmovnb",{ ST, STi } },
4163218822Sdim    { "fcmovne",{ ST, STi } },
4164218822Sdim    { "fcmovnbe",{ ST, STi } },
4165218822Sdim    { "fcmovnu",{ ST, STi } },
416633965Sjdp    { FGRPdb_4 },
4167218822Sdim    { "fucomi",	{ ST, STi } },
4168218822Sdim    { "fcomi",	{ ST, STi } },
4169218822Sdim    { "(bad)",	{ XX } },
417033965Sjdp  },
417133965Sjdp  /* dc */
417233965Sjdp  {
4173218822Sdim    { "fadd",	{ STi, ST } },
4174218822Sdim    { "fmul",	{ STi, ST } },
4175218822Sdim    { "(bad)",	{ XX } },
4176218822Sdim    { "(bad)",	{ XX } },
4177218822Sdim#if SYSV386_COMPAT
4178218822Sdim    { "fsub",	{ STi, ST } },
4179218822Sdim    { "fsubr",	{ STi, ST } },
4180218822Sdim    { "fdiv",	{ STi, ST } },
4181218822Sdim    { "fdivr",	{ STi, ST } },
418260484Sobrien#else
4183218822Sdim    { "fsubr",	{ STi, ST } },
4184218822Sdim    { "fsub",	{ STi, ST } },
4185218822Sdim    { "fdivr",	{ STi, ST } },
4186218822Sdim    { "fdiv",	{ STi, ST } },
418760484Sobrien#endif
418833965Sjdp  },
418933965Sjdp  /* dd */
419033965Sjdp  {
4191218822Sdim    { "ffree",	{ STi } },
4192218822Sdim    { "(bad)",	{ XX } },
4193218822Sdim    { "fst",	{ STi } },
4194218822Sdim    { "fstp",	{ STi } },
4195218822Sdim    { "fucom",	{ STi } },
4196218822Sdim    { "fucomp",	{ STi } },
4197218822Sdim    { "(bad)",	{ XX } },
4198218822Sdim    { "(bad)",	{ XX } },
419933965Sjdp  },
420033965Sjdp  /* de */
420133965Sjdp  {
4202218822Sdim    { "faddp",	{ STi, ST } },
4203218822Sdim    { "fmulp",	{ STi, ST } },
4204218822Sdim    { "(bad)",	{ XX } },
420533965Sjdp    { FGRPde_3 },
4206218822Sdim#if SYSV386_COMPAT
4207218822Sdim    { "fsubp",	{ STi, ST } },
4208218822Sdim    { "fsubrp",	{ STi, ST } },
4209218822Sdim    { "fdivp",	{ STi, ST } },
4210218822Sdim    { "fdivrp",	{ STi, ST } },
421160484Sobrien#else
4212218822Sdim    { "fsubrp",	{ STi, ST } },
4213218822Sdim    { "fsubp",	{ STi, ST } },
4214218822Sdim    { "fdivrp",	{ STi, ST } },
4215218822Sdim    { "fdivp",	{ STi, ST } },
421660484Sobrien#endif
421733965Sjdp  },
421833965Sjdp  /* df */
421933965Sjdp  {
4220218822Sdim    { "ffreep",	{ STi } },
4221218822Sdim    { "(bad)",	{ XX } },
4222218822Sdim    { "(bad)",	{ XX } },
4223218822Sdim    { "(bad)",	{ XX } },
422433965Sjdp    { FGRPdf_4 },
4225218822Sdim    { "fucomip", { ST, STi } },
4226218822Sdim    { "fcomip", { ST, STi } },
4227218822Sdim    { "(bad)",	{ XX } },
422833965Sjdp  },
422933965Sjdp};
423033965Sjdp
423133965Sjdpstatic char *fgrps[][8] = {
423233965Sjdp  /* d9_2  0 */
423333965Sjdp  {
423433965Sjdp    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
423533965Sjdp  },
423633965Sjdp
423733965Sjdp  /* d9_4  1 */
423833965Sjdp  {
423933965Sjdp    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
424033965Sjdp  },
424133965Sjdp
424233965Sjdp  /* d9_5  2 */
424333965Sjdp  {
424433965Sjdp    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
424533965Sjdp  },
424633965Sjdp
424733965Sjdp  /* d9_6  3 */
424833965Sjdp  {
424933965Sjdp    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
425033965Sjdp  },
425133965Sjdp
425233965Sjdp  /* d9_7  4 */
425333965Sjdp  {
425433965Sjdp    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
425533965Sjdp  },
425633965Sjdp
425733965Sjdp  /* da_5  5 */
425833965Sjdp  {
425933965Sjdp    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
426033965Sjdp  },
426133965Sjdp
426233965Sjdp  /* db_4  6 */
426333965Sjdp  {
426433965Sjdp    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
426533965Sjdp    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
426633965Sjdp  },
426733965Sjdp
426833965Sjdp  /* de_3  7 */
426933965Sjdp  {
427033965Sjdp    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
427133965Sjdp  },
427233965Sjdp
427333965Sjdp  /* df_4  8 */
427433965Sjdp  {
427533965Sjdp    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
427633965Sjdp  },
427733965Sjdp};
427833965Sjdp
427933965Sjdpstatic void
4280130561Sobriendofloat (int sizeflag)
428133965Sjdp{
428260484Sobrien  const struct dis386 *dp;
428333965Sjdp  unsigned char floatop;
428460484Sobrien
428533965Sjdp  floatop = codep[-1];
428660484Sobrien
4287218822Sdim  if (modrm.mod != 3)
428833965Sjdp    {
4289218822Sdim      int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
4290218822Sdim
4291218822Sdim      putop (float_mem[fp_indx], sizeflag);
4292218822Sdim      obufp = op_out[0];
4293218822Sdim      op_ad = 2;
4294218822Sdim      OP_E (float_mem_mode[fp_indx], sizeflag);
429533965Sjdp      return;
429633965Sjdp    }
429785815Sobrien  /* Skip mod/rm byte.  */
429878828Sobrien  MODRM_CHECK;
429933965Sjdp  codep++;
430060484Sobrien
4301218822Sdim  dp = &float_reg[floatop - 0xd8][modrm.reg];
430233965Sjdp  if (dp->name == NULL)
430333965Sjdp    {
4304218822Sdim      putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
430560484Sobrien
430685815Sobrien      /* Instruction fnstsw is only one with strange arg.  */
430760484Sobrien      if (floatop == 0xdf && codep[-1] == 0xe0)
4308218822Sdim	strcpy (op_out[0], names16[0]);
430933965Sjdp    }
431033965Sjdp  else
431133965Sjdp    {
431260484Sobrien      putop (dp->name, sizeflag);
431360484Sobrien
4314218822Sdim      obufp = op_out[0];
4315218822Sdim      op_ad = 2;
4316218822Sdim      if (dp->op[0].rtn)
4317218822Sdim	(*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
4318218822Sdim
4319218822Sdim      obufp = op_out[1];
4320218822Sdim      op_ad = 1;
4321218822Sdim      if (dp->op[1].rtn)
4322218822Sdim	(*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
432333965Sjdp    }
432433965Sjdp}
432533965Sjdp
432660484Sobrienstatic void
4327130561SobrienOP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
432833965Sjdp{
4329218822Sdim  oappend ("%st" + intel_syntax);
433033965Sjdp}
433133965Sjdp
433260484Sobrienstatic void
4333130561SobrienOP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
433433965Sjdp{
4335218822Sdim  sprintf (scratchbuf, "%%st(%d)", modrm.rm);
433685815Sobrien  oappend (scratchbuf + intel_syntax);
433733965Sjdp}
433833965Sjdp
433985815Sobrien/* Capital letters in template are macros.  */
434085815Sobrienstatic int
4341130561Sobrienputop (const char *template, int sizeflag)
434233965Sjdp{
434360484Sobrien  const char *p;
4344218822Sdim  int alt = 0;
434560484Sobrien
434633965Sjdp  for (p = template; *p; p++)
434733965Sjdp    {
434833965Sjdp      switch (*p)
434933965Sjdp	{
435033965Sjdp	default:
435133965Sjdp	  *obufp++ = *p;
435233965Sjdp	  break;
435385815Sobrien	case '{':
435485815Sobrien	  alt = 0;
435585815Sobrien	  if (intel_syntax)
435685815Sobrien	    alt += 1;
4357218822Sdim	  if (address_mode == mode_64bit)
435885815Sobrien	    alt += 2;
435985815Sobrien	  while (alt != 0)
436085815Sobrien	    {
436185815Sobrien	      while (*++p != '|')
436285815Sobrien		{
436385815Sobrien		  if (*p == '}')
436485815Sobrien		    {
436585815Sobrien		      /* Alternative not valid.  */
436685815Sobrien		      strcpy (obuf, "(bad)");
436785815Sobrien		      obufp = obuf + 5;
436885815Sobrien		      return 1;
436985815Sobrien		    }
437085815Sobrien		  else if (*p == '\0')
437185815Sobrien		    abort ();
437285815Sobrien		}
437385815Sobrien	      alt--;
437485815Sobrien	    }
4375218822Sdim	  /* Fall through.  */
4376218822Sdim	case 'I':
4377218822Sdim	  alt = 1;
4378218822Sdim	  continue;
437985815Sobrien	case '|':
438085815Sobrien	  while (*++p != '}')
438185815Sobrien	    {
438285815Sobrien	      if (*p == '\0')
438385815Sobrien		abort ();
438485815Sobrien	    }
438585815Sobrien	  break;
438685815Sobrien	case '}':
438785815Sobrien	  break;
438860484Sobrien	case 'A':
4389130561Sobrien	  if (intel_syntax)
4390130561Sobrien	    break;
4391218822Sdim	  if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
439260484Sobrien	    *obufp++ = 'b';
439360484Sobrien	  break;
439460484Sobrien	case 'B':
4395130561Sobrien	  if (intel_syntax)
4396130561Sobrien	    break;
439760484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
439860484Sobrien	    *obufp++ = 'b';
439960484Sobrien	  break;
4400218822Sdim	case 'C':
4401218822Sdim	  if (intel_syntax && !alt)
4402218822Sdim	    break;
4403218822Sdim	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4404218822Sdim	    {
4405218822Sdim	      if (sizeflag & DFLAG)
4406218822Sdim		*obufp++ = intel_syntax ? 'd' : 'l';
4407218822Sdim	      else
4408218822Sdim		*obufp++ = intel_syntax ? 'w' : 's';
4409218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4410218822Sdim	    }
4411218822Sdim	  break;
4412218822Sdim	case 'D':
4413218822Sdim	  if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4414218822Sdim	    break;
4415218822Sdim	  USED_REX (REX_W);
4416218822Sdim	  if (modrm.mod == 3)
4417218822Sdim	    {
4418218822Sdim	      if (rex & REX_W)
4419218822Sdim		*obufp++ = 'q';
4420218822Sdim	      else if (sizeflag & DFLAG)
4421218822Sdim		*obufp++ = intel_syntax ? 'd' : 'l';
4422218822Sdim	      else
4423218822Sdim		*obufp++ = 'w';
4424218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4425218822Sdim	    }
4426218822Sdim	  else
4427218822Sdim	    *obufp++ = 'w';
4428218822Sdim	  break;
442960484Sobrien	case 'E':		/* For jcxz/jecxz */
4430218822Sdim	  if (address_mode == mode_64bit)
443192828Sobrien	    {
443292828Sobrien	      if (sizeflag & AFLAG)
443392828Sobrien		*obufp++ = 'r';
443492828Sobrien	      else
443592828Sobrien		*obufp++ = 'e';
443692828Sobrien	    }
443792828Sobrien	  else
443892828Sobrien	    if (sizeflag & AFLAG)
443992828Sobrien	      *obufp++ = 'e';
444078828Sobrien	  used_prefixes |= (prefixes & PREFIX_ADDR);
444133965Sjdp	  break;
444278828Sobrien	case 'F':
4443130561Sobrien	  if (intel_syntax)
4444130561Sobrien	    break;
444589857Sobrien	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
444678828Sobrien	    {
444778828Sobrien	      if (sizeflag & AFLAG)
4448218822Sdim		*obufp++ = address_mode == mode_64bit ? 'q' : 'l';
444978828Sobrien	      else
4450218822Sdim		*obufp++ = address_mode == mode_64bit ? 'l' : 'w';
445178828Sobrien	      used_prefixes |= (prefixes & PREFIX_ADDR);
445278828Sobrien	    }
445378828Sobrien	  break;
4454218822Sdim	case 'G':
4455218822Sdim	  if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4456218822Sdim	    break;
4457218822Sdim	  if ((rex & REX_W) || (sizeflag & DFLAG))
4458218822Sdim	    *obufp++ = 'l';
4459218822Sdim	  else
4460218822Sdim	    *obufp++ = 'w';
4461218822Sdim	  if (!(rex & REX_W))
4462218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
4463218822Sdim	  break;
446485815Sobrien	case 'H':
4465130561Sobrien	  if (intel_syntax)
4466130561Sobrien	    break;
446785815Sobrien	  if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
446885815Sobrien	      || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
446977298Sobrien	    {
447085815Sobrien	      used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
447185815Sobrien	      *obufp++ = ',';
447285815Sobrien	      *obufp++ = 'p';
447385815Sobrien	      if (prefixes & PREFIX_DS)
447485815Sobrien		*obufp++ = 't';
447585815Sobrien	      else
447685815Sobrien		*obufp++ = 'n';
447777298Sobrien	    }
447877298Sobrien	  break;
4479218822Sdim	case 'J':
4480218822Sdim	  if (intel_syntax)
4481218822Sdim	    break;
4482218822Sdim	  *obufp++ = 'l';
4483218822Sdim	  break;
4484218822Sdim	case 'K':
4485218822Sdim	  USED_REX (REX_W);
4486218822Sdim	  if (rex & REX_W)
4487218822Sdim	    *obufp++ = 'q';
4488218822Sdim	  else
4489218822Sdim	    *obufp++ = 'd';
4490218822Sdim	  break;
4491218822Sdim	case 'Z':
4492218822Sdim	  if (intel_syntax)
4493218822Sdim	    break;
4494218822Sdim	  if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4495218822Sdim	    {
4496218822Sdim	      *obufp++ = 'q';
4497218822Sdim	      break;
4498218822Sdim	    }
4499218822Sdim	  /* Fall through.  */
450060484Sobrien	case 'L':
4501130561Sobrien	  if (intel_syntax)
4502130561Sobrien	    break;
450360484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
450460484Sobrien	    *obufp++ = 'l';
450560484Sobrien	  break;
450633965Sjdp	case 'N':
450733965Sjdp	  if ((prefixes & PREFIX_FWAIT) == 0)
450833965Sjdp	    *obufp++ = 'n';
450960484Sobrien	  else
451060484Sobrien	    used_prefixes |= PREFIX_FWAIT;
451133965Sjdp	  break;
451277298Sobrien	case 'O':
4513218822Sdim	  USED_REX (REX_W);
4514218822Sdim	  if (rex & REX_W)
451585815Sobrien	    *obufp++ = 'o';
4516218822Sdim	  else if (intel_syntax && (sizeflag & DFLAG))
4517218822Sdim	    *obufp++ = 'q';
451877298Sobrien	  else
451977298Sobrien	    *obufp++ = 'd';
4520218822Sdim	  if (!(rex & REX_W))
4521218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
452277298Sobrien	  break;
452385815Sobrien	case 'T':
4524130561Sobrien	  if (intel_syntax)
4525130561Sobrien	    break;
4526218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
452785815Sobrien	    {
452885815Sobrien	      *obufp++ = 'q';
452985815Sobrien	      break;
453085815Sobrien	    }
453185815Sobrien	  /* Fall through.  */
453260484Sobrien	case 'P':
4533130561Sobrien	  if (intel_syntax)
4534130561Sobrien	    break;
453560484Sobrien	  if ((prefixes & PREFIX_DATA)
4536218822Sdim	      || (rex & REX_W)
453789857Sobrien	      || (sizeflag & SUFFIX_ALWAYS))
453860484Sobrien	    {
4539218822Sdim	      USED_REX (REX_W);
4540218822Sdim	      if (rex & REX_W)
454177298Sobrien		*obufp++ = 'q';
454278828Sobrien	      else
454377298Sobrien		{
454477298Sobrien		   if (sizeflag & DFLAG)
454577298Sobrien		      *obufp++ = 'l';
454677298Sobrien		   else
454777298Sobrien		     *obufp++ = 'w';
454877298Sobrien		}
4549218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
455060484Sobrien	    }
455160484Sobrien	  break;
455285815Sobrien	case 'U':
4553130561Sobrien	  if (intel_syntax)
4554130561Sobrien	    break;
4555218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
455685815Sobrien	    {
4557218822Sdim	      if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4558218822Sdim		*obufp++ = 'q';
455985815Sobrien	      break;
456085815Sobrien	    }
456185815Sobrien	  /* Fall through.  */
456260484Sobrien	case 'Q':
4563218822Sdim	  if (intel_syntax && !alt)
4564130561Sobrien	    break;
4565218822Sdim	  USED_REX (REX_W);
4566218822Sdim	  if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
456760484Sobrien	    {
4568218822Sdim	      if (rex & REX_W)
456977298Sobrien		*obufp++ = 'q';
457060484Sobrien	      else
457177298Sobrien		{
457277298Sobrien		  if (sizeflag & DFLAG)
4573218822Sdim		    *obufp++ = intel_syntax ? 'd' : 'l';
457477298Sobrien		  else
457577298Sobrien		    *obufp++ = 'w';
457677298Sobrien		}
4577218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
457860484Sobrien	    }
457960484Sobrien	  break;
458060484Sobrien	case 'R':
4581218822Sdim	  USED_REX (REX_W);
4582218822Sdim	  if (rex & REX_W)
4583218822Sdim	    *obufp++ = 'q';
4584218822Sdim	  else if (sizeflag & DFLAG)
458560484Sobrien	    {
4586218822Sdim	      if (intel_syntax)
458760484Sobrien		  *obufp++ = 'd';
458860484Sobrien	      else
4589218822Sdim		  *obufp++ = 'l';
459060484Sobrien	    }
459133965Sjdp	  else
4592218822Sdim	    *obufp++ = 'w';
4593218822Sdim	  if (intel_syntax && !p[1]
4594218822Sdim	      && ((rex & REX_W) || (sizeflag & DFLAG)))
4595218822Sdim	    *obufp++ = 'e';
4596218822Sdim	  if (!(rex & REX_W))
4597218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
4598218822Sdim	  break;
4599218822Sdim	case 'V':
4600218822Sdim	  if (intel_syntax)
4601218822Sdim	    break;
4602218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
460360484Sobrien	    {
4604218822Sdim	      if (sizeflag & SUFFIX_ALWAYS)
460577298Sobrien		*obufp++ = 'q';
4606218822Sdim	      break;
460760484Sobrien	    }
4608218822Sdim	  /* Fall through.  */
460960484Sobrien	case 'S':
4610130561Sobrien	  if (intel_syntax)
4611130561Sobrien	    break;
461260484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
461360484Sobrien	    {
4614218822Sdim	      if (rex & REX_W)
461577298Sobrien		*obufp++ = 'q';
461677298Sobrien	      else
461777298Sobrien		{
461877298Sobrien		  if (sizeflag & DFLAG)
461977298Sobrien		    *obufp++ = 'l';
462077298Sobrien		  else
462177298Sobrien		    *obufp++ = 'w';
462277298Sobrien		  used_prefixes |= (prefixes & PREFIX_DATA);
462377298Sobrien		}
462477298Sobrien	    }
462577298Sobrien	  break;
462677298Sobrien	case 'X':
462777298Sobrien	  if (prefixes & PREFIX_DATA)
462877298Sobrien	    *obufp++ = 'd';
462977298Sobrien	  else
463077298Sobrien	    *obufp++ = 's';
4631130561Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
463277298Sobrien	  break;
463377298Sobrien	case 'Y':
4634130561Sobrien	  if (intel_syntax)
4635130561Sobrien	    break;
4636218822Sdim	  if (rex & REX_W)
463777298Sobrien	    {
4638218822Sdim	      USED_REX (REX_W);
463977298Sobrien	      *obufp++ = 'q';
464077298Sobrien	    }
464177298Sobrien	  break;
464277298Sobrien	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
464338889Sjdp	case 'W':
464438889Sjdp	  /* operand size flag for cwtl, cbtw */
4645218822Sdim	  USED_REX (REX_W);
4646218822Sdim	  if (rex & REX_W)
4647218822Sdim	    {
4648218822Sdim	      if (intel_syntax)
4649218822Sdim		*obufp++ = 'd';
4650218822Sdim	      else
4651218822Sdim		*obufp++ = 'l';
4652218822Sdim	    }
465377298Sobrien	  else if (sizeflag & DFLAG)
465438889Sjdp	    *obufp++ = 'w';
465538889Sjdp	  else
465638889Sjdp	    *obufp++ = 'b';
4657218822Sdim	  if (!(rex & REX_W))
465877298Sobrien	    used_prefixes |= (prefixes & PREFIX_DATA);
465938889Sjdp	  break;
466033965Sjdp	}
4661218822Sdim      alt = 0;
466233965Sjdp    }
466333965Sjdp  *obufp = 0;
466485815Sobrien  return 0;
466533965Sjdp}
466633965Sjdp
466733965Sjdpstatic void
4668130561Sobrienoappend (const char *s)
466933965Sjdp{
467033965Sjdp  strcpy (obufp, s);
467133965Sjdp  obufp += strlen (s);
467233965Sjdp}
467333965Sjdp
467433965Sjdpstatic void
4675130561Sobrienappend_seg (void)
467633965Sjdp{
467733965Sjdp  if (prefixes & PREFIX_CS)
467860484Sobrien    {
467960484Sobrien      used_prefixes |= PREFIX_CS;
468085815Sobrien      oappend ("%cs:" + intel_syntax);
468160484Sobrien    }
468233965Sjdp  if (prefixes & PREFIX_DS)
468360484Sobrien    {
468460484Sobrien      used_prefixes |= PREFIX_DS;
468585815Sobrien      oappend ("%ds:" + intel_syntax);
468660484Sobrien    }
468733965Sjdp  if (prefixes & PREFIX_SS)
468860484Sobrien    {
468960484Sobrien      used_prefixes |= PREFIX_SS;
469085815Sobrien      oappend ("%ss:" + intel_syntax);
469160484Sobrien    }
469233965Sjdp  if (prefixes & PREFIX_ES)
469360484Sobrien    {
469460484Sobrien      used_prefixes |= PREFIX_ES;
469585815Sobrien      oappend ("%es:" + intel_syntax);
469660484Sobrien    }
469733965Sjdp  if (prefixes & PREFIX_FS)
469860484Sobrien    {
469960484Sobrien      used_prefixes |= PREFIX_FS;
470085815Sobrien      oappend ("%fs:" + intel_syntax);
470160484Sobrien    }
470233965Sjdp  if (prefixes & PREFIX_GS)
470360484Sobrien    {
470460484Sobrien      used_prefixes |= PREFIX_GS;
470585815Sobrien      oappend ("%gs:" + intel_syntax);
470660484Sobrien    }
470733965Sjdp}
470833965Sjdp
470960484Sobrienstatic void
4710130561SobrienOP_indirE (int bytemode, int sizeflag)
471133965Sjdp{
471260484Sobrien  if (!intel_syntax)
471360484Sobrien    oappend ("*");
471460484Sobrien  OP_E (bytemode, sizeflag);
471533965Sjdp}
471633965Sjdp
471760484Sobrienstatic void
4718130561Sobrienprint_operand_value (char *buf, int hex, bfd_vma disp)
471977298Sobrien{
4720218822Sdim  if (address_mode == mode_64bit)
472177298Sobrien    {
472277298Sobrien      if (hex)
472377298Sobrien	{
472477298Sobrien	  char tmp[30];
472577298Sobrien	  int i;
472677298Sobrien	  buf[0] = '0';
472777298Sobrien	  buf[1] = 'x';
472877298Sobrien	  sprintf_vma (tmp, disp);
472985815Sobrien	  for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
473077298Sobrien	  strcpy (buf + 2, tmp + i);
473177298Sobrien	}
473277298Sobrien      else
473377298Sobrien	{
473477298Sobrien	  bfd_signed_vma v = disp;
473577298Sobrien	  char tmp[30];
473677298Sobrien	  int i;
473777298Sobrien	  if (v < 0)
473877298Sobrien	    {
473977298Sobrien	      *(buf++) = '-';
474077298Sobrien	      v = -disp;
474185815Sobrien	      /* Check for possible overflow on 0x8000000000000000.  */
474277298Sobrien	      if (v < 0)
474377298Sobrien		{
474477298Sobrien		  strcpy (buf, "9223372036854775808");
474577298Sobrien		  return;
474677298Sobrien		}
474777298Sobrien	    }
474877298Sobrien	  if (!v)
474977298Sobrien	    {
475077298Sobrien	      strcpy (buf, "0");
475177298Sobrien	      return;
475277298Sobrien	    }
475377298Sobrien
475477298Sobrien	  i = 0;
475577298Sobrien	  tmp[29] = 0;
475677298Sobrien	  while (v)
475777298Sobrien	    {
475885815Sobrien	      tmp[28 - i] = (v % 10) + '0';
475977298Sobrien	      v /= 10;
476077298Sobrien	      i++;
476177298Sobrien	    }
476277298Sobrien	  strcpy (buf, tmp + 29 - i);
476377298Sobrien	}
476477298Sobrien    }
476577298Sobrien  else
476677298Sobrien    {
476777298Sobrien      if (hex)
476877298Sobrien	sprintf (buf, "0x%x", (unsigned int) disp);
476977298Sobrien      else
477077298Sobrien	sprintf (buf, "%d", (int) disp);
477177298Sobrien    }
477277298Sobrien}
477377298Sobrien
4774218822Sdim/* Put DISP in BUF as signed hex number.  */
4775218822Sdim
477677298Sobrienstatic void
4777218822Sdimprint_displacement (char *buf, bfd_vma disp)
4778218822Sdim{
4779218822Sdim  bfd_signed_vma val = disp;
4780218822Sdim  char tmp[30];
4781218822Sdim  int i, j = 0;
4782218822Sdim
4783218822Sdim  if (val < 0)
4784218822Sdim    {
4785218822Sdim      buf[j++] = '-';
4786218822Sdim      val = -disp;
4787218822Sdim
4788218822Sdim      /* Check for possible overflow.  */
4789218822Sdim      if (val < 0)
4790218822Sdim	{
4791218822Sdim	  switch (address_mode)
4792218822Sdim	    {
4793218822Sdim	    case mode_64bit:
4794218822Sdim	      strcpy (buf + j, "0x8000000000000000");
4795218822Sdim	      break;
4796218822Sdim	    case mode_32bit:
4797218822Sdim	      strcpy (buf + j, "0x80000000");
4798218822Sdim	      break;
4799218822Sdim	    case mode_16bit:
4800218822Sdim	      strcpy (buf + j, "0x8000");
4801218822Sdim	      break;
4802218822Sdim	    }
4803218822Sdim	  return;
4804218822Sdim	}
4805218822Sdim    }
4806218822Sdim
4807218822Sdim  buf[j++] = '0';
4808218822Sdim  buf[j++] = 'x';
4809218822Sdim
4810218822Sdim  sprintf_vma (tmp, val);
4811218822Sdim  for (i = 0; tmp[i] == '0'; i++)
4812218822Sdim    continue;
4813218822Sdim  if (tmp[i] == '\0')
4814218822Sdim    i--;
4815218822Sdim  strcpy (buf + j, tmp + i);
4816218822Sdim}
4817218822Sdim
4818218822Sdimstatic void
4819218822Sdimintel_operand_size (int bytemode, int sizeflag)
4820218822Sdim{
4821218822Sdim  switch (bytemode)
4822218822Sdim    {
4823218822Sdim    case b_mode:
4824218822Sdim    case dqb_mode:
4825218822Sdim      oappend ("BYTE PTR ");
4826218822Sdim      break;
4827218822Sdim    case w_mode:
4828218822Sdim    case dqw_mode:
4829218822Sdim      oappend ("WORD PTR ");
4830218822Sdim      break;
4831218822Sdim    case stack_v_mode:
4832218822Sdim      if (address_mode == mode_64bit && (sizeflag & DFLAG))
4833218822Sdim	{
4834218822Sdim	  oappend ("QWORD PTR ");
4835218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
4836218822Sdim	  break;
4837218822Sdim	}
4838218822Sdim      /* FALLTHRU */
4839218822Sdim    case v_mode:
4840218822Sdim    case dq_mode:
4841218822Sdim      USED_REX (REX_W);
4842218822Sdim      if (rex & REX_W)
4843218822Sdim	oappend ("QWORD PTR ");
4844218822Sdim      else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4845218822Sdim	oappend ("DWORD PTR ");
4846218822Sdim      else
4847218822Sdim	oappend ("WORD PTR ");
4848218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
4849218822Sdim      break;
4850218822Sdim    case z_mode:
4851218822Sdim      if ((rex & REX_W) || (sizeflag & DFLAG))
4852218822Sdim	*obufp++ = 'D';
4853218822Sdim      oappend ("WORD PTR ");
4854218822Sdim      if (!(rex & REX_W))
4855218822Sdim	used_prefixes |= (prefixes & PREFIX_DATA);
4856218822Sdim      break;
4857218822Sdim    case d_mode:
4858218822Sdim    case dqd_mode:
4859218822Sdim      oappend ("DWORD PTR ");
4860218822Sdim      break;
4861218822Sdim    case q_mode:
4862218822Sdim      oappend ("QWORD PTR ");
4863218822Sdim      break;
4864218822Sdim    case m_mode:
4865218822Sdim      if (address_mode == mode_64bit)
4866218822Sdim	oappend ("QWORD PTR ");
4867218822Sdim      else
4868218822Sdim	oappend ("DWORD PTR ");
4869218822Sdim      break;
4870218822Sdim    case f_mode:
4871218822Sdim      if (sizeflag & DFLAG)
4872218822Sdim	oappend ("FWORD PTR ");
4873218822Sdim      else
4874218822Sdim	oappend ("DWORD PTR ");
4875218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
4876218822Sdim      break;
4877218822Sdim    case t_mode:
4878218822Sdim      oappend ("TBYTE PTR ");
4879218822Sdim      break;
4880218822Sdim    case x_mode:
4881218822Sdim      oappend ("XMMWORD PTR ");
4882218822Sdim      break;
4883218822Sdim    case o_mode:
4884218822Sdim      oappend ("OWORD PTR ");
4885218822Sdim      break;
4886218822Sdim    default:
4887218822Sdim      break;
4888218822Sdim    }
4889218822Sdim}
4890218822Sdim
4891218822Sdimstatic void
4892130561SobrienOP_E (int bytemode, int sizeflag)
489333965Sjdp{
489477298Sobrien  bfd_vma disp;
489577298Sobrien  int add = 0;
489677298Sobrien  int riprel = 0;
4897218822Sdim  USED_REX (REX_B);
4898218822Sdim  if (rex & REX_B)
489977298Sobrien    add += 8;
490033965Sjdp
490185815Sobrien  /* Skip mod/rm byte.  */
490278828Sobrien  MODRM_CHECK;
490333965Sjdp  codep++;
490433965Sjdp
4905218822Sdim  if (modrm.mod == 3)
490633965Sjdp    {
490733965Sjdp      switch (bytemode)
490833965Sjdp	{
490933965Sjdp	case b_mode:
491077298Sobrien	  USED_REX (0);
491177298Sobrien	  if (rex)
4912218822Sdim	    oappend (names8rex[modrm.rm + add]);
491377298Sobrien	  else
4914218822Sdim	    oappend (names8[modrm.rm + add]);
491533965Sjdp	  break;
491633965Sjdp	case w_mode:
4917218822Sdim	  oappend (names16[modrm.rm + add]);
491833965Sjdp	  break;
491960484Sobrien	case d_mode:
4920218822Sdim	  oappend (names32[modrm.rm + add]);
492160484Sobrien	  break;
492277298Sobrien	case q_mode:
4923218822Sdim	  oappend (names64[modrm.rm + add]);
492477298Sobrien	  break;
492577298Sobrien	case m_mode:
4926218822Sdim	  if (address_mode == mode_64bit)
4927218822Sdim	    oappend (names64[modrm.rm + add]);
492877298Sobrien	  else
4929218822Sdim	    oappend (names32[modrm.rm + add]);
493077298Sobrien	  break;
4931218822Sdim	case stack_v_mode:
4932218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
4933218822Sdim	    {
4934218822Sdim	      oappend (names64[modrm.rm + add]);
4935218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4936218822Sdim	      break;
4937218822Sdim	    }
4938218822Sdim	  bytemode = v_mode;
4939218822Sdim	  /* FALLTHRU */
494033965Sjdp	case v_mode:
4941130561Sobrien	case dq_mode:
4942218822Sdim	case dqb_mode:
4943218822Sdim	case dqd_mode:
4944218822Sdim	case dqw_mode:
4945218822Sdim	  USED_REX (REX_W);
4946218822Sdim	  if (rex & REX_W)
4947218822Sdim	    oappend (names64[modrm.rm + add]);
4948218822Sdim	  else if ((sizeflag & DFLAG) || bytemode != v_mode)
4949218822Sdim	    oappend (names32[modrm.rm + add]);
495033965Sjdp	  else
4951218822Sdim	    oappend (names16[modrm.rm + add]);
495260484Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
495333965Sjdp	  break;
495460484Sobrien	case 0:
495560484Sobrien	  break;
495633965Sjdp	default:
495760484Sobrien	  oappend (INTERNAL_DISASSEMBLER_ERROR);
495833965Sjdp	  break;
495933965Sjdp	}
496060484Sobrien      return;
496133965Sjdp    }
496233965Sjdp
496333965Sjdp  disp = 0;
4964218822Sdim  if (intel_syntax)
4965218822Sdim    intel_operand_size (bytemode, sizeflag);
496660484Sobrien  append_seg ();
496733965Sjdp
4968218822Sdim  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
496933965Sjdp    {
4970218822Sdim      /* 32/64 bit address mode */
4971218822Sdim      int havedisp;
497233965Sjdp      int havesib;
497333965Sjdp      int havebase;
497433965Sjdp      int base;
497538889Sjdp      int index = 0;
497638889Sjdp      int scale = 0;
497733965Sjdp
497833965Sjdp      havesib = 0;
497933965Sjdp      havebase = 1;
4980218822Sdim      base = modrm.rm;
498133965Sjdp
498233965Sjdp      if (base == 4)
498333965Sjdp	{
498433965Sjdp	  havesib = 1;
4985223262Sbenl	  (void) FETCH_DATA (the_info, codep + 1);
498633965Sjdp	  index = (*codep >> 3) & 7;
4987218822Sdim	  if (address_mode == mode_64bit || index != 0x4)
4988218822Sdim	    /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored.  */
4989218822Sdim	    scale = (*codep >> 6) & 3;
499033965Sjdp	  base = *codep & 7;
4991218822Sdim	  USED_REX (REX_X);
4992218822Sdim	  if (rex & REX_X)
499377298Sobrien	    index += 8;
499433965Sjdp	  codep++;
499533965Sjdp	}
4996218822Sdim      base += add;
499733965Sjdp
4998218822Sdim      switch (modrm.mod)
499933965Sjdp	{
500033965Sjdp	case 0:
500177298Sobrien	  if ((base & 7) == 5)
500233965Sjdp	    {
500333965Sjdp	      havebase = 0;
5004218822Sdim	      if (address_mode == mode_64bit && !havesib)
500577298Sobrien		riprel = 1;
500677298Sobrien	      disp = get32s ();
500733965Sjdp	    }
500833965Sjdp	  break;
500933965Sjdp	case 1:
501033965Sjdp	  FETCH_DATA (the_info, codep + 1);
501138889Sjdp	  disp = *codep++;
501238889Sjdp	  if ((disp & 0x80) != 0)
501338889Sjdp	    disp -= 0x100;
501433965Sjdp	  break;
501533965Sjdp	case 2:
501677298Sobrien	  disp = get32s ();
501733965Sjdp	  break;
501833965Sjdp	}
501933965Sjdp
5020218822Sdim      havedisp = havebase || (havesib && (index != 4 || scale != 0));
5021218822Sdim
502260484Sobrien      if (!intel_syntax)
5023218822Sdim	if (modrm.mod != 0 || (base & 7) == 5)
5024130561Sobrien	  {
5025218822Sdim	    if (havedisp || riprel)
5026218822Sdim	      print_displacement (scratchbuf, disp);
5027218822Sdim	    else
5028218822Sdim	      print_operand_value (scratchbuf, 1, disp);
5029130561Sobrien	    oappend (scratchbuf);
503077298Sobrien	    if (riprel)
503177298Sobrien	      {
503277298Sobrien		set_op (disp, 1);
503377298Sobrien		oappend ("(%rip)");
503477298Sobrien	      }
5035130561Sobrien	  }
503633965Sjdp
5037218822Sdim      if (havedisp || (intel_syntax && riprel))
503833965Sjdp	{
503960484Sobrien	  *obufp++ = open_char;
504077298Sobrien	  if (intel_syntax && riprel)
5041218822Sdim	    {
5042218822Sdim	      set_op (disp, 1);
5043218822Sdim	      oappend ("rip");
5044218822Sdim	    }
5045130561Sobrien	  *obufp = '\0';
504633965Sjdp	  if (havebase)
5047218822Sdim	    oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
504892828Sobrien		     ? names64[base] : names32[base]);
504933965Sjdp	  if (havesib)
505033965Sjdp	    {
505133965Sjdp	      if (index != 4)
505233965Sjdp		{
5053218822Sdim		  if (!intel_syntax || havebase)
5054130561Sobrien		    {
5055218822Sdim		      *obufp++ = separator_char;
5056218822Sdim		      *obufp = '\0';
5057130561Sobrien		    }
5058218822Sdim		  oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5059218822Sdim			   ? names64[index] : names32[index]);
506033965Sjdp		}
5061130561Sobrien	      if (scale != 0 || (!intel_syntax && index != 4))
5062130561Sobrien		{
5063130561Sobrien		  *obufp++ = scale_char;
5064130561Sobrien		  *obufp = '\0';
5065130561Sobrien		  sprintf (scratchbuf, "%d", 1 << scale);
5066130561Sobrien		  oappend (scratchbuf);
5067130561Sobrien		}
506833965Sjdp	    }
5069218822Sdim	  if (intel_syntax
5070218822Sdim	      && (disp || modrm.mod != 0 || (base & 7) == 5))
5071218822Sdim	    {
5072218822Sdim	      if ((bfd_signed_vma) disp >= 0)
5073218822Sdim		{
5074218822Sdim		  *obufp++ = '+';
5075218822Sdim		  *obufp = '\0';
5076218822Sdim		}
5077218822Sdim	      else if (modrm.mod != 1)
5078218822Sdim		{
5079218822Sdim		  *obufp++ = '-';
5080218822Sdim		  *obufp = '\0';
5081218822Sdim		  disp = - (bfd_signed_vma) disp;
5082218822Sdim		}
508385815Sobrien
5084218822Sdim	      print_displacement (scratchbuf, disp);
5085218822Sdim	      oappend (scratchbuf);
5086218822Sdim	    }
508760484Sobrien
508860484Sobrien	  *obufp++ = close_char;
5089130561Sobrien	  *obufp = '\0';
509033965Sjdp	}
509160484Sobrien      else if (intel_syntax)
5092130561Sobrien	{
5093218822Sdim	  if (modrm.mod != 0 || (base & 7) == 5)
5094130561Sobrien	    {
509560484Sobrien	      if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
509660484Sobrien			      | PREFIX_ES | PREFIX_FS | PREFIX_GS))
509760484Sobrien		;
509860484Sobrien	      else
509960484Sobrien		{
510085815Sobrien		  oappend (names_seg[ds_reg - es_reg]);
510160484Sobrien		  oappend (":");
510260484Sobrien		}
510377298Sobrien	      print_operand_value (scratchbuf, 1, disp);
5104130561Sobrien	      oappend (scratchbuf);
5105130561Sobrien	    }
5106130561Sobrien	}
510733965Sjdp    }
510833965Sjdp  else
510933965Sjdp    { /* 16 bit address mode */
5110218822Sdim      switch (modrm.mod)
511133965Sjdp	{
511233965Sjdp	case 0:
5113218822Sdim	  if (modrm.rm == 6)
511438889Sjdp	    {
511538889Sjdp	      disp = get16 ();
511638889Sjdp	      if ((disp & 0x8000) != 0)
511738889Sjdp		disp -= 0x10000;
511838889Sjdp	    }
511933965Sjdp	  break;
512033965Sjdp	case 1:
512133965Sjdp	  FETCH_DATA (the_info, codep + 1);
512238889Sjdp	  disp = *codep++;
512338889Sjdp	  if ((disp & 0x80) != 0)
512438889Sjdp	    disp -= 0x100;
512533965Sjdp	  break;
512633965Sjdp	case 2:
512738889Sjdp	  disp = get16 ();
512838889Sjdp	  if ((disp & 0x8000) != 0)
512938889Sjdp	    disp -= 0x10000;
513033965Sjdp	  break;
513133965Sjdp	}
513233965Sjdp
513360484Sobrien      if (!intel_syntax)
5134218822Sdim	if (modrm.mod != 0 || modrm.rm == 6)
5135130561Sobrien	  {
5136218822Sdim	    print_displacement (scratchbuf, disp);
5137130561Sobrien	    oappend (scratchbuf);
5138130561Sobrien	  }
513933965Sjdp
5140218822Sdim      if (modrm.mod != 0 || modrm.rm != 6)
514133965Sjdp	{
514260484Sobrien	  *obufp++ = open_char;
5143130561Sobrien	  *obufp = '\0';
5144218822Sdim	  oappend (index16[modrm.rm]);
5145218822Sdim	  if (intel_syntax
5146218822Sdim	      && (disp || modrm.mod != 0 || modrm.rm == 6))
5147218822Sdim	    {
5148218822Sdim	      if ((bfd_signed_vma) disp >= 0)
5149218822Sdim		{
5150218822Sdim		  *obufp++ = '+';
5151218822Sdim		  *obufp = '\0';
5152218822Sdim		}
5153218822Sdim	      else if (modrm.mod != 1)
5154218822Sdim		{
5155218822Sdim		  *obufp++ = '-';
5156218822Sdim		  *obufp = '\0';
5157218822Sdim		  disp = - (bfd_signed_vma) disp;
5158218822Sdim		}
5159218822Sdim
5160218822Sdim	      print_displacement (scratchbuf, disp);
5161218822Sdim	      oappend (scratchbuf);
5162218822Sdim	    }
5163218822Sdim
5164130561Sobrien	  *obufp++ = close_char;
5165130561Sobrien	  *obufp = '\0';
516633965Sjdp	}
5167218822Sdim      else if (intel_syntax)
5168218822Sdim	{
5169218822Sdim	  if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5170218822Sdim			  | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5171218822Sdim	    ;
5172218822Sdim	  else
5173218822Sdim	    {
5174218822Sdim	      oappend (names_seg[ds_reg - es_reg]);
5175218822Sdim	      oappend (":");
5176218822Sdim	    }
5177218822Sdim	  print_operand_value (scratchbuf, 1, disp & 0xffff);
5178218822Sdim	  oappend (scratchbuf);
5179218822Sdim	}
518033965Sjdp    }
518133965Sjdp}
518233965Sjdp
518360484Sobrienstatic void
5184130561SobrienOP_G (int bytemode, int sizeflag)
518533965Sjdp{
518677298Sobrien  int add = 0;
5187218822Sdim  USED_REX (REX_R);
5188218822Sdim  if (rex & REX_R)
518977298Sobrien    add += 8;
519060484Sobrien  switch (bytemode)
519133965Sjdp    {
519233965Sjdp    case b_mode:
519377298Sobrien      USED_REX (0);
519477298Sobrien      if (rex)
5195218822Sdim	oappend (names8rex[modrm.reg + add]);
519677298Sobrien      else
5197218822Sdim	oappend (names8[modrm.reg + add]);
519833965Sjdp      break;
519933965Sjdp    case w_mode:
5200218822Sdim      oappend (names16[modrm.reg + add]);
520133965Sjdp      break;
520233965Sjdp    case d_mode:
5203218822Sdim      oappend (names32[modrm.reg + add]);
520433965Sjdp      break;
520577298Sobrien    case q_mode:
5206218822Sdim      oappend (names64[modrm.reg + add]);
520777298Sobrien      break;
520833965Sjdp    case v_mode:
5209218822Sdim    case dq_mode:
5210218822Sdim    case dqb_mode:
5211218822Sdim    case dqd_mode:
5212218822Sdim    case dqw_mode:
5213218822Sdim      USED_REX (REX_W);
5214218822Sdim      if (rex & REX_W)
5215218822Sdim	oappend (names64[modrm.reg + add]);
5216218822Sdim      else if ((sizeflag & DFLAG) || bytemode != v_mode)
5217218822Sdim	oappend (names32[modrm.reg + add]);
521833965Sjdp      else
5219218822Sdim	oappend (names16[modrm.reg + add]);
522060484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
522133965Sjdp      break;
5222218822Sdim    case m_mode:
5223218822Sdim      if (address_mode == mode_64bit)
5224218822Sdim	oappend (names64[modrm.reg + add]);
5225218822Sdim      else
5226218822Sdim	oappend (names32[modrm.reg + add]);
5227218822Sdim      break;
522833965Sjdp    default:
522960484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
523033965Sjdp      break;
523133965Sjdp    }
523233965Sjdp}
523333965Sjdp
523477298Sobrienstatic bfd_vma
5235130561Sobrienget64 (void)
523677298Sobrien{
523785815Sobrien  bfd_vma x;
523885815Sobrien#ifdef BFD64
523985815Sobrien  unsigned int a;
524085815Sobrien  unsigned int b;
524177298Sobrien
5242223262Sbenl  (void) FETCH_DATA (the_info, codep + 8);
524377298Sobrien  a = *codep++ & 0xff;
524477298Sobrien  a |= (*codep++ & 0xff) << 8;
524577298Sobrien  a |= (*codep++ & 0xff) << 16;
524677298Sobrien  a |= (*codep++ & 0xff) << 24;
524785815Sobrien  b = *codep++ & 0xff;
524877298Sobrien  b |= (*codep++ & 0xff) << 8;
524977298Sobrien  b |= (*codep++ & 0xff) << 16;
525077298Sobrien  b |= (*codep++ & 0xff) << 24;
525177298Sobrien  x = a + ((bfd_vma) b << 32);
525277298Sobrien#else
525385815Sobrien  abort ();
525485815Sobrien  x = 0;
525577298Sobrien#endif
525677298Sobrien  return x;
525777298Sobrien}
525877298Sobrien
525977298Sobrienstatic bfd_signed_vma
5260130561Sobrienget32 (void)
526133965Sjdp{
526277298Sobrien  bfd_signed_vma x = 0;
526333965Sjdp
5264223262Sbenl  (void) FETCH_DATA (the_info, codep + 4);
526577298Sobrien  x = *codep++ & (bfd_signed_vma) 0xff;
526677298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
526777298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
526877298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
526960484Sobrien  return x;
527033965Sjdp}
527133965Sjdp
527277298Sobrienstatic bfd_signed_vma
5273130561Sobrienget32s (void)
527477298Sobrien{
527577298Sobrien  bfd_signed_vma x = 0;
527677298Sobrien
5277223262Sbenl  (void) FETCH_DATA (the_info, codep + 4);
527877298Sobrien  x = *codep++ & (bfd_signed_vma) 0xff;
527977298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
528077298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
528177298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
528277298Sobrien
528377298Sobrien  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
528477298Sobrien
528577298Sobrien  return x;
528677298Sobrien}
528777298Sobrien
528833965Sjdpstatic int
5289130561Sobrienget16 (void)
529033965Sjdp{
529133965Sjdp  int x = 0;
529233965Sjdp
5293223262Sbenl  (void) FETCH_DATA (the_info, codep + 2);
529433965Sjdp  x = *codep++ & 0xff;
529533965Sjdp  x |= (*codep++ & 0xff) << 8;
529660484Sobrien  return x;
529733965Sjdp}
529833965Sjdp
529933965Sjdpstatic void
5300130561Sobrienset_op (bfd_vma op, int riprel)
530133965Sjdp{
530233965Sjdp  op_index[op_ad] = op_ad;
5303218822Sdim  if (address_mode == mode_64bit)
530485815Sobrien    {
530585815Sobrien      op_address[op_ad] = op;
530685815Sobrien      op_riprel[op_ad] = riprel;
530785815Sobrien    }
530885815Sobrien  else
530985815Sobrien    {
531085815Sobrien      /* Mask to get a 32-bit address.  */
531185815Sobrien      op_address[op_ad] = op & 0xffffffff;
531285815Sobrien      op_riprel[op_ad] = riprel & 0xffffffff;
531385815Sobrien    }
531433965Sjdp}
531533965Sjdp
531660484Sobrienstatic void
5317130561SobrienOP_REG (int code, int sizeflag)
531833965Sjdp{
531960484Sobrien  const char *s;
532077298Sobrien  int add = 0;
5321218822Sdim  USED_REX (REX_B);
5322218822Sdim  if (rex & REX_B)
532377298Sobrien    add = 8;
532460484Sobrien
532560484Sobrien  switch (code)
532633965Sjdp    {
532760484Sobrien    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
532860484Sobrien    case sp_reg: case bp_reg: case si_reg: case di_reg:
532977298Sobrien      s = names16[code - ax_reg + add];
533077298Sobrien      break;
533177298Sobrien    case es_reg: case ss_reg: case cs_reg:
533277298Sobrien    case ds_reg: case fs_reg: case gs_reg:
533377298Sobrien      s = names_seg[code - es_reg + add];
533477298Sobrien      break;
533577298Sobrien    case al_reg: case ah_reg: case cl_reg: case ch_reg:
533677298Sobrien    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
533777298Sobrien      USED_REX (0);
533877298Sobrien      if (rex)
533977298Sobrien	s = names8rex[code - al_reg + add];
534077298Sobrien      else
534177298Sobrien	s = names8[code - al_reg];
534277298Sobrien      break;
534385815Sobrien    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
534485815Sobrien    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
5345218822Sdim      if (address_mode == mode_64bit && (sizeflag & DFLAG))
534685815Sobrien	{
534785815Sobrien	  s = names64[code - rAX_reg + add];
534885815Sobrien	  break;
534985815Sobrien	}
535085815Sobrien      code += eAX_reg - rAX_reg;
535185815Sobrien      /* Fall through.  */
535277298Sobrien    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
535377298Sobrien    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5354218822Sdim      USED_REX (REX_W);
5355218822Sdim      if (rex & REX_W)
535677298Sobrien	s = names64[code - eAX_reg + add];
535777298Sobrien      else if (sizeflag & DFLAG)
535877298Sobrien	s = names32[code - eAX_reg + add];
535977298Sobrien      else
536077298Sobrien	s = names16[code - eAX_reg + add];
536177298Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
536277298Sobrien      break;
536377298Sobrien    default:
536477298Sobrien      s = INTERNAL_DISASSEMBLER_ERROR;
536577298Sobrien      break;
536677298Sobrien    }
536777298Sobrien  oappend (s);
536877298Sobrien}
536977298Sobrien
537077298Sobrienstatic void
5371130561SobrienOP_IMREG (int code, int sizeflag)
537277298Sobrien{
537377298Sobrien  const char *s;
537477298Sobrien
537577298Sobrien  switch (code)
537677298Sobrien    {
537777298Sobrien    case indir_dx_reg:
537885815Sobrien      if (intel_syntax)
5379218822Sdim	s = "dx";
538085815Sobrien      else
5381130561Sobrien	s = "(%dx)";
538277298Sobrien      break;
538377298Sobrien    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
538477298Sobrien    case sp_reg: case bp_reg: case si_reg: case di_reg:
538560484Sobrien      s = names16[code - ax_reg];
538660484Sobrien      break;
538760484Sobrien    case es_reg: case ss_reg: case cs_reg:
538860484Sobrien    case ds_reg: case fs_reg: case gs_reg:
538960484Sobrien      s = names_seg[code - es_reg];
539060484Sobrien      break;
539160484Sobrien    case al_reg: case ah_reg: case cl_reg: case ch_reg:
539260484Sobrien    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
539377298Sobrien      USED_REX (0);
539477298Sobrien      if (rex)
539577298Sobrien	s = names8rex[code - al_reg];
539677298Sobrien      else
539777298Sobrien	s = names8[code - al_reg];
539860484Sobrien      break;
539960484Sobrien    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
540060484Sobrien    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5401218822Sdim      USED_REX (REX_W);
5402218822Sdim      if (rex & REX_W)
540377298Sobrien	s = names64[code - eAX_reg];
540477298Sobrien      else if (sizeflag & DFLAG)
540533965Sjdp	s = names32[code - eAX_reg];
540633965Sjdp      else
540733965Sjdp	s = names16[code - eAX_reg];
540860484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
540933965Sjdp      break;
5410218822Sdim    case z_mode_ax_reg:
5411218822Sdim      if ((rex & REX_W) || (sizeflag & DFLAG))
5412218822Sdim	s = *names32;
5413218822Sdim      else
5414218822Sdim	s = *names16;
5415218822Sdim      if (!(rex & REX_W))
5416218822Sdim	used_prefixes |= (prefixes & PREFIX_DATA);
5417218822Sdim      break;
541833965Sjdp    default:
541960484Sobrien      s = INTERNAL_DISASSEMBLER_ERROR;
542033965Sjdp      break;
542133965Sjdp    }
542233965Sjdp  oappend (s);
542333965Sjdp}
542433965Sjdp
542560484Sobrienstatic void
5426130561SobrienOP_I (int bytemode, int sizeflag)
542733965Sjdp{
542877298Sobrien  bfd_signed_vma op;
542977298Sobrien  bfd_signed_vma mask = -1;
543060484Sobrien
543160484Sobrien  switch (bytemode)
543233965Sjdp    {
543333965Sjdp    case b_mode:
543433965Sjdp      FETCH_DATA (the_info, codep + 1);
543577298Sobrien      op = *codep++;
543677298Sobrien      mask = 0xff;
543733965Sjdp      break;
543877298Sobrien    case q_mode:
5439218822Sdim      if (address_mode == mode_64bit)
544085815Sobrien	{
544185815Sobrien	  op = get32s ();
544285815Sobrien	  break;
544385815Sobrien	}
544485815Sobrien      /* Fall through.  */
544533965Sjdp    case v_mode:
5446218822Sdim      USED_REX (REX_W);
5447218822Sdim      if (rex & REX_W)
544877298Sobrien	op = get32s ();
544977298Sobrien      else if (sizeflag & DFLAG)
545077298Sobrien	{
545177298Sobrien	  op = get32 ();
545277298Sobrien	  mask = 0xffffffff;
545377298Sobrien	}
545433965Sjdp      else
545577298Sobrien	{
545677298Sobrien	  op = get16 ();
545777298Sobrien	  mask = 0xfffff;
545877298Sobrien	}
545960484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
546033965Sjdp      break;
546133965Sjdp    case w_mode:
546277298Sobrien      mask = 0xfffff;
546333965Sjdp      op = get16 ();
546433965Sjdp      break;
5465218822Sdim    case const_1_mode:
5466218822Sdim      if (intel_syntax)
5467218822Sdim        oappend ("1");
5468218822Sdim      return;
546933965Sjdp    default:
547060484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
547160484Sobrien      return;
547233965Sjdp    }
547360484Sobrien
547477298Sobrien  op &= mask;
547577298Sobrien  scratchbuf[0] = '$';
547685815Sobrien  print_operand_value (scratchbuf + 1, 1, op);
547785815Sobrien  oappend (scratchbuf + intel_syntax);
547860484Sobrien  scratchbuf[0] = '\0';
547933965Sjdp}
548033965Sjdp
548160484Sobrienstatic void
5482130561SobrienOP_I64 (int bytemode, int sizeflag)
548377298Sobrien{
548477298Sobrien  bfd_signed_vma op;
548577298Sobrien  bfd_signed_vma mask = -1;
548677298Sobrien
5487218822Sdim  if (address_mode != mode_64bit)
548885815Sobrien    {
548985815Sobrien      OP_I (bytemode, sizeflag);
549085815Sobrien      return;
549185815Sobrien    }
549285815Sobrien
549377298Sobrien  switch (bytemode)
549477298Sobrien    {
549577298Sobrien    case b_mode:
549677298Sobrien      FETCH_DATA (the_info, codep + 1);
549777298Sobrien      op = *codep++;
549877298Sobrien      mask = 0xff;
549977298Sobrien      break;
550077298Sobrien    case v_mode:
5501218822Sdim      USED_REX (REX_W);
5502218822Sdim      if (rex & REX_W)
550377298Sobrien	op = get64 ();
550477298Sobrien      else if (sizeflag & DFLAG)
550577298Sobrien	{
550677298Sobrien	  op = get32 ();
550777298Sobrien	  mask = 0xffffffff;
550877298Sobrien	}
550977298Sobrien      else
551077298Sobrien	{
551177298Sobrien	  op = get16 ();
551277298Sobrien	  mask = 0xfffff;
551377298Sobrien	}
551477298Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
551577298Sobrien      break;
551677298Sobrien    case w_mode:
551777298Sobrien      mask = 0xfffff;
551877298Sobrien      op = get16 ();
551977298Sobrien      break;
552077298Sobrien    default:
552177298Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
552277298Sobrien      return;
552377298Sobrien    }
552477298Sobrien
552577298Sobrien  op &= mask;
552677298Sobrien  scratchbuf[0] = '$';
552785815Sobrien  print_operand_value (scratchbuf + 1, 1, op);
552885815Sobrien  oappend (scratchbuf + intel_syntax);
552977298Sobrien  scratchbuf[0] = '\0';
553077298Sobrien}
553177298Sobrien
553277298Sobrienstatic void
5533130561SobrienOP_sI (int bytemode, int sizeflag)
553433965Sjdp{
553577298Sobrien  bfd_signed_vma op;
553677298Sobrien  bfd_signed_vma mask = -1;
553760484Sobrien
553860484Sobrien  switch (bytemode)
553933965Sjdp    {
554033965Sjdp    case b_mode:
554133965Sjdp      FETCH_DATA (the_info, codep + 1);
554238889Sjdp      op = *codep++;
554338889Sjdp      if ((op & 0x80) != 0)
554438889Sjdp	op -= 0x100;
554577298Sobrien      mask = 0xffffffff;
554633965Sjdp      break;
554733965Sjdp    case v_mode:
5548218822Sdim      USED_REX (REX_W);
5549218822Sdim      if (rex & REX_W)
555077298Sobrien	op = get32s ();
555177298Sobrien      else if (sizeflag & DFLAG)
555277298Sobrien	{
555377298Sobrien	  op = get32s ();
555477298Sobrien	  mask = 0xffffffff;
555577298Sobrien	}
555633965Sjdp      else
555738889Sjdp	{
555877298Sobrien	  mask = 0xffffffff;
555985815Sobrien	  op = get16 ();
556038889Sjdp	  if ((op & 0x8000) != 0)
556138889Sjdp	    op -= 0x10000;
556238889Sjdp	}
556360484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
556433965Sjdp      break;
556533965Sjdp    case w_mode:
556638889Sjdp      op = get16 ();
556777298Sobrien      mask = 0xffffffff;
556838889Sjdp      if ((op & 0x8000) != 0)
556938889Sjdp	op -= 0x10000;
557033965Sjdp      break;
557133965Sjdp    default:
557260484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
557360484Sobrien      return;
557433965Sjdp    }
557577298Sobrien
557677298Sobrien  scratchbuf[0] = '$';
557777298Sobrien  print_operand_value (scratchbuf + 1, 1, op);
557885815Sobrien  oappend (scratchbuf + intel_syntax);
557933965Sjdp}
558033965Sjdp
558160484Sobrienstatic void
5582130561SobrienOP_J (int bytemode, int sizeflag)
558333965Sjdp{
558477298Sobrien  bfd_vma disp;
558585815Sobrien  bfd_vma mask = -1;
5586218822Sdim  bfd_vma segment = 0;
558760484Sobrien
558860484Sobrien  switch (bytemode)
558933965Sjdp    {
559033965Sjdp    case b_mode:
559133965Sjdp      FETCH_DATA (the_info, codep + 1);
559238889Sjdp      disp = *codep++;
559338889Sjdp      if ((disp & 0x80) != 0)
559438889Sjdp	disp -= 0x100;
559533965Sjdp      break;
559633965Sjdp    case v_mode:
5597218822Sdim      if ((sizeflag & DFLAG) || (rex & REX_W))
559877298Sobrien	disp = get32s ();
559933965Sjdp      else
560033965Sjdp	{
560138889Sjdp	  disp = get16 ();
5602218822Sdim	  if ((disp & 0x8000) != 0)
5603218822Sdim	    disp -= 0x10000;
5604218822Sdim	  /* In 16bit mode, address is wrapped around at 64k within
5605218822Sdim	     the same segment.  Otherwise, a data16 prefix on a jump
5606218822Sdim	     instruction means that the pc is masked to 16 bits after
5607218822Sdim	     the displacement is added!  */
560833965Sjdp	  mask = 0xffff;
5609218822Sdim	  if ((prefixes & PREFIX_DATA) == 0)
5610218822Sdim	    segment = ((start_pc + codep - start_codep)
5611218822Sdim		       & ~((bfd_vma) 0xffff));
561233965Sjdp	}
5613218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
561433965Sjdp      break;
561533965Sjdp    default:
561660484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
561760484Sobrien      return;
561833965Sjdp    }
5619218822Sdim  disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
562077298Sobrien  set_op (disp, 0);
562177298Sobrien  print_operand_value (scratchbuf, 1, disp);
562233965Sjdp  oappend (scratchbuf);
562333965Sjdp}
562433965Sjdp
562560484Sobrienstatic void
5626218822SdimOP_SEG (int bytemode, int sizeflag)
562733965Sjdp{
5628218822Sdim  if (bytemode == w_mode)
5629218822Sdim    oappend (names_seg[modrm.reg]);
5630218822Sdim  else
5631218822Sdim    OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
563233965Sjdp}
563333965Sjdp
563460484Sobrienstatic void
5635130561SobrienOP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
563633965Sjdp{
563733965Sjdp  int seg, offset;
563860484Sobrien
563960484Sobrien  if (sizeflag & DFLAG)
564033965Sjdp    {
564160484Sobrien      offset = get32 ();
564260484Sobrien      seg = get16 ();
564333965Sjdp    }
564460484Sobrien  else
564560484Sobrien    {
564660484Sobrien      offset = get16 ();
564760484Sobrien      seg = get16 ();
564860484Sobrien    }
564960484Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
565085815Sobrien  if (intel_syntax)
5651218822Sdim    sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
565285815Sobrien  else
565385815Sobrien    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
565460484Sobrien  oappend (scratchbuf);
565533965Sjdp}
565633965Sjdp
565760484Sobrienstatic void
5658218822SdimOP_OFF (int bytemode, int sizeflag)
565933965Sjdp{
566077298Sobrien  bfd_vma off;
566133965Sjdp
5662218822Sdim  if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5663218822Sdim    intel_operand_size (bytemode, sizeflag);
566460484Sobrien  append_seg ();
566533965Sjdp
5666218822Sdim  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
566733965Sjdp    off = get32 ();
566833965Sjdp  else
566933965Sjdp    off = get16 ();
567060484Sobrien
567160484Sobrien  if (intel_syntax)
567260484Sobrien    {
567360484Sobrien      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5674130561Sobrien			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
567560484Sobrien	{
567685815Sobrien	  oappend (names_seg[ds_reg - es_reg]);
567760484Sobrien	  oappend (":");
567860484Sobrien	}
567960484Sobrien    }
568077298Sobrien  print_operand_value (scratchbuf, 1, off);
568133965Sjdp  oappend (scratchbuf);
568233965Sjdp}
568385815Sobrien
568477298Sobrienstatic void
5685218822SdimOP_OFF64 (int bytemode, int sizeflag)
568677298Sobrien{
568777298Sobrien  bfd_vma off;
568833965Sjdp
5689218822Sdim  if (address_mode != mode_64bit
5690218822Sdim      || (prefixes & PREFIX_ADDR))
569185815Sobrien    {
569285815Sobrien      OP_OFF (bytemode, sizeflag);
569385815Sobrien      return;
569485815Sobrien    }
569585815Sobrien
5696218822Sdim  if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5697218822Sdim    intel_operand_size (bytemode, sizeflag);
569877298Sobrien  append_seg ();
569977298Sobrien
570085815Sobrien  off = get64 ();
570177298Sobrien
570277298Sobrien  if (intel_syntax)
570377298Sobrien    {
570477298Sobrien      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5705130561Sobrien			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
570677298Sobrien	{
570785815Sobrien	  oappend (names_seg[ds_reg - es_reg]);
570877298Sobrien	  oappend (":");
570977298Sobrien	}
571077298Sobrien    }
571177298Sobrien  print_operand_value (scratchbuf, 1, off);
571277298Sobrien  oappend (scratchbuf);
571377298Sobrien}
571477298Sobrien
571560484Sobrienstatic void
5716130561Sobrienptr_reg (int code, int sizeflag)
571733965Sjdp{
571860484Sobrien  const char *s;
571985815Sobrien
5720218822Sdim  *obufp++ = open_char;
5721218822Sdim  used_prefixes |= (prefixes & PREFIX_ADDR);
5722218822Sdim  if (address_mode == mode_64bit)
572392828Sobrien    {
572492828Sobrien      if (!(sizeflag & AFLAG))
5725130561Sobrien	s = names32[code - eAX_reg];
572692828Sobrien      else
5727130561Sobrien	s = names64[code - eAX_reg];
572892828Sobrien    }
572977298Sobrien  else if (sizeflag & AFLAG)
573060484Sobrien    s = names32[code - eAX_reg];
573160484Sobrien  else
573260484Sobrien    s = names16[code - eAX_reg];
573360484Sobrien  oappend (s);
5734218822Sdim  *obufp++ = close_char;
5735218822Sdim  *obufp = 0;
573633965Sjdp}
573733965Sjdp
573860484Sobrienstatic void
5739130561SobrienOP_ESreg (int code, int sizeflag)
574033965Sjdp{
5741218822Sdim  if (intel_syntax)
5742218822Sdim    {
5743218822Sdim      switch (codep[-1])
5744218822Sdim	{
5745218822Sdim	case 0x6d:	/* insw/insl */
5746218822Sdim	  intel_operand_size (z_mode, sizeflag);
5747218822Sdim	  break;
5748218822Sdim	case 0xa5:	/* movsw/movsl/movsq */
5749218822Sdim	case 0xa7:	/* cmpsw/cmpsl/cmpsq */
5750218822Sdim	case 0xab:	/* stosw/stosl */
5751218822Sdim	case 0xaf:	/* scasw/scasl */
5752218822Sdim	  intel_operand_size (v_mode, sizeflag);
5753218822Sdim	  break;
5754218822Sdim	default:
5755218822Sdim	  intel_operand_size (b_mode, sizeflag);
5756218822Sdim	}
5757218822Sdim    }
575885815Sobrien  oappend ("%es:" + intel_syntax);
575960484Sobrien  ptr_reg (code, sizeflag);
576060484Sobrien}
576160484Sobrien
576260484Sobrienstatic void
5763130561SobrienOP_DSreg (int code, int sizeflag)
576460484Sobrien{
5765218822Sdim  if (intel_syntax)
5766218822Sdim    {
5767218822Sdim      switch (codep[-1])
5768218822Sdim	{
5769218822Sdim	case 0x6f:	/* outsw/outsl */
5770218822Sdim	  intel_operand_size (z_mode, sizeflag);
5771218822Sdim	  break;
5772218822Sdim	case 0xa5:	/* movsw/movsl/movsq */
5773218822Sdim	case 0xa7:	/* cmpsw/cmpsl/cmpsq */
5774218822Sdim	case 0xad:	/* lodsw/lodsl/lodsq */
5775218822Sdim	  intel_operand_size (v_mode, sizeflag);
5776218822Sdim	  break;
5777218822Sdim	default:
5778218822Sdim	  intel_operand_size (b_mode, sizeflag);
5779218822Sdim	}
5780218822Sdim    }
578138889Sjdp  if ((prefixes
578238889Sjdp       & (PREFIX_CS
578338889Sjdp	  | PREFIX_DS
578438889Sjdp	  | PREFIX_SS
578538889Sjdp	  | PREFIX_ES
578638889Sjdp	  | PREFIX_FS
578738889Sjdp	  | PREFIX_GS)) == 0)
578838889Sjdp    prefixes |= PREFIX_DS;
578985815Sobrien  append_seg ();
579060484Sobrien  ptr_reg (code, sizeflag);
579133965Sjdp}
579233965Sjdp
579360484Sobrienstatic void
5794130561SobrienOP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
579533965Sjdp{
579677298Sobrien  int add = 0;
5797218822Sdim  if (rex & REX_R)
5798218822Sdim    {
5799218822Sdim      USED_REX (REX_R);
5800218822Sdim      add = 8;
5801218822Sdim    }
5802218822Sdim  else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5803218822Sdim    {
5804218822Sdim      used_prefixes |= PREFIX_LOCK;
5805218822Sdim      add = 8;
5806218822Sdim    }
5807218822Sdim  sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
580885815Sobrien  oappend (scratchbuf + intel_syntax);
580933965Sjdp}
581033965Sjdp
581160484Sobrienstatic void
5812130561SobrienOP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
581333965Sjdp{
581477298Sobrien  int add = 0;
5815218822Sdim  USED_REX (REX_R);
5816218822Sdim  if (rex & REX_R)
581777298Sobrien    add = 8;
581885815Sobrien  if (intel_syntax)
5819218822Sdim    sprintf (scratchbuf, "db%d", modrm.reg + add);
582085815Sobrien  else
5821218822Sdim    sprintf (scratchbuf, "%%db%d", modrm.reg + add);
582233965Sjdp  oappend (scratchbuf);
582333965Sjdp}
582433965Sjdp
582560484Sobrienstatic void
5826130561SobrienOP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
582733965Sjdp{
5828218822Sdim  sprintf (scratchbuf, "%%tr%d", modrm.reg);
582985815Sobrien  oappend (scratchbuf + intel_syntax);
583033965Sjdp}
583133965Sjdp
583260484Sobrienstatic void
5833218822SdimOP_R (int bytemode, int sizeflag)
583433965Sjdp{
5835218822Sdim  if (modrm.mod == 3)
583660484Sobrien    OP_E (bytemode, sizeflag);
583760484Sobrien  else
583885815Sobrien    BadOp ();
583933965Sjdp}
584033965Sjdp
584160484Sobrienstatic void
5842130561SobrienOP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
584333965Sjdp{
584477298Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
584577298Sobrien  if (prefixes & PREFIX_DATA)
5846218822Sdim    {
5847218822Sdim      int add = 0;
5848218822Sdim      USED_REX (REX_R);
5849218822Sdim      if (rex & REX_R)
5850218822Sdim	add = 8;
5851218822Sdim      sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5852218822Sdim    }
585377298Sobrien  else
5854218822Sdim    sprintf (scratchbuf, "%%mm%d", modrm.reg);
585585815Sobrien  oappend (scratchbuf + intel_syntax);
585633965Sjdp}
585733965Sjdp
585860484Sobrienstatic void
5859130561SobrienOP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
586060484Sobrien{
586177298Sobrien  int add = 0;
5862218822Sdim  USED_REX (REX_R);
5863218822Sdim  if (rex & REX_R)
586477298Sobrien    add = 8;
5865218822Sdim  sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
586685815Sobrien  oappend (scratchbuf + intel_syntax);
586760484Sobrien}
586860484Sobrien
586960484Sobrienstatic void
5870130561SobrienOP_EM (int bytemode, int sizeflag)
587133965Sjdp{
5872218822Sdim  if (modrm.mod != 3)
587360484Sobrien    {
5874218822Sdim      if (intel_syntax && bytemode == v_mode)
5875218822Sdim	{
5876218822Sdim	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5877218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
5878218822Sdim 	}
587960484Sobrien      OP_E (bytemode, sizeflag);
588060484Sobrien      return;
588160484Sobrien    }
588233965Sjdp
588385815Sobrien  /* Skip mod/rm byte.  */
588478828Sobrien  MODRM_CHECK;
588533965Sjdp  codep++;
588677298Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
588777298Sobrien  if (prefixes & PREFIX_DATA)
5888218822Sdim    {
5889218822Sdim      int add = 0;
5890218822Sdim
5891218822Sdim      USED_REX (REX_B);
5892218822Sdim      if (rex & REX_B)
5893218822Sdim	add = 8;
5894218822Sdim      sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5895218822Sdim    }
589677298Sobrien  else
5897218822Sdim    sprintf (scratchbuf, "%%mm%d", modrm.rm);
589885815Sobrien  oappend (scratchbuf + intel_syntax);
589933965Sjdp}
590033965Sjdp
5901218822Sdim/* cvt* are the only instructions in sse2 which have
5902218822Sdim   both SSE and MMX operands and also have 0x66 prefix
5903218822Sdim   in their opcode. 0x66 was originally used to differentiate
5904218822Sdim   between SSE and MMX instruction(operands). So we have to handle the
5905218822Sdim   cvt* separately using OP_EMC and OP_MXC */
590660484Sobrienstatic void
5907218822SdimOP_EMC (int bytemode, int sizeflag)
5908218822Sdim{
5909218822Sdim  if (modrm.mod != 3)
5910218822Sdim    {
5911218822Sdim      if (intel_syntax && bytemode == v_mode)
5912218822Sdim	{
5913218822Sdim	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5914218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
5915218822Sdim 	}
5916218822Sdim      OP_E (bytemode, sizeflag);
5917218822Sdim      return;
5918218822Sdim    }
5919218822Sdim
5920218822Sdim  /* Skip mod/rm byte.  */
5921218822Sdim  MODRM_CHECK;
5922218822Sdim  codep++;
5923218822Sdim  used_prefixes |= (prefixes & PREFIX_DATA);
5924218822Sdim  sprintf (scratchbuf, "%%mm%d", modrm.rm);
5925218822Sdim  oappend (scratchbuf + intel_syntax);
5926218822Sdim}
5927218822Sdim
5928218822Sdimstatic void
5929218822SdimOP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5930218822Sdim{
5931218822Sdim  used_prefixes |= (prefixes & PREFIX_DATA);
5932218822Sdim  sprintf (scratchbuf, "%%mm%d", modrm.reg);
5933218822Sdim  oappend (scratchbuf + intel_syntax);
5934218822Sdim}
5935218822Sdim
5936218822Sdimstatic void
5937130561SobrienOP_EX (int bytemode, int sizeflag)
593833965Sjdp{
593977298Sobrien  int add = 0;
5940218822Sdim  if (modrm.mod != 3)
594160484Sobrien    {
594260484Sobrien      OP_E (bytemode, sizeflag);
594360484Sobrien      return;
594460484Sobrien    }
5945218822Sdim  USED_REX (REX_B);
5946218822Sdim  if (rex & REX_B)
594777298Sobrien    add = 8;
594860484Sobrien
594985815Sobrien  /* Skip mod/rm byte.  */
595078828Sobrien  MODRM_CHECK;
595160484Sobrien  codep++;
5952218822Sdim  sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
595385815Sobrien  oappend (scratchbuf + intel_syntax);
595433965Sjdp}
595560484Sobrien
595660484Sobrienstatic void
5957130561SobrienOP_MS (int bytemode, int sizeflag)
595860484Sobrien{
5959218822Sdim  if (modrm.mod == 3)
596060484Sobrien    OP_EM (bytemode, sizeflag);
596160484Sobrien  else
596285815Sobrien    BadOp ();
596360484Sobrien}
596460484Sobrien
596578828Sobrienstatic void
5966130561SobrienOP_XS (int bytemode, int sizeflag)
596778828Sobrien{
5968218822Sdim  if (modrm.mod == 3)
596978828Sobrien    OP_EX (bytemode, sizeflag);
597078828Sobrien  else
597185815Sobrien    BadOp ();
597278828Sobrien}
597378828Sobrien
5974130561Sobrienstatic void
5975130561SobrienOP_M (int bytemode, int sizeflag)
5976130561Sobrien{
5977218822Sdim  if (modrm.mod == 3)
5978238167Sjhb    /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst,invept,invvpid modrm */
5979218822Sdim    BadOp ();
5980130561Sobrien  else
5981130561Sobrien    OP_E (bytemode, sizeflag);
5982130561Sobrien}
5983130561Sobrien
5984130561Sobrienstatic void
5985130561SobrienOP_0f07 (int bytemode, int sizeflag)
5986130561Sobrien{
5987218822Sdim  if (modrm.mod != 3 || modrm.rm != 0)
5988130561Sobrien    BadOp ();
5989130561Sobrien  else
5990130561Sobrien    OP_E (bytemode, sizeflag);
5991130561Sobrien}
5992130561Sobrien
5993130561Sobrienstatic void
5994130561SobrienOP_0fae (int bytemode, int sizeflag)
5995130561Sobrien{
5996218822Sdim  if (modrm.mod == 3)
5997130561Sobrien    {
5998218822Sdim      if (modrm.reg == 7)
5999130561Sobrien	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
6000238123Sjhb      else if (modrm.reg == 6)
6001238123Sjhb	strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
6002238123Sjhb      else if (modrm.reg == 5)
6003238123Sjhb	strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
6004130561Sobrien
6005218822Sdim      if (modrm.reg < 5 || modrm.rm != 0)
6006130561Sobrien	{
6007130561Sobrien	  BadOp ();	/* bad sfence, mfence, or lfence */
6008130561Sobrien	  return;
6009130561Sobrien	}
6010238123Sjhb      bytemode = 0;
6011130561Sobrien    }
6012130561Sobrien
6013130561Sobrien  OP_E (bytemode, sizeflag);
6014130561Sobrien}
6015130561Sobrien
6016218822Sdim/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6017218822Sdim   32bit mode and "xchg %rax,%rax" in 64bit mode.  */
6018218822Sdim
6019130561Sobrienstatic void
6020218822SdimNOP_Fixup1 (int bytemode, int sizeflag)
6021130561Sobrien{
6022218822Sdim  if ((prefixes & PREFIX_DATA) != 0
6023218822Sdim      || (rex != 0
6024218822Sdim	  && rex != 0x48
6025218822Sdim	  && address_mode == mode_64bit))
6026218822Sdim    OP_REG (bytemode, sizeflag);
6027218822Sdim  else
6028218822Sdim    strcpy (obuf, "nop");
6029130561Sobrien}
6030130561Sobrien
6031218822Sdimstatic void
6032218822SdimNOP_Fixup2 (int bytemode, int sizeflag)
6033218822Sdim{
6034218822Sdim  if ((prefixes & PREFIX_DATA) != 0
6035218822Sdim      || (rex != 0
6036218822Sdim	  && rex != 0x48
6037218822Sdim	  && address_mode == mode_64bit))
6038218822Sdim    OP_IMREG (bytemode, sizeflag);
6039218822Sdim}
6040218822Sdim
6041130561Sobrienstatic const char *const Suffix3DNow[] = {
604260484Sobrien/* 00 */	NULL,		NULL,		NULL,		NULL,
604360484Sobrien/* 04 */	NULL,		NULL,		NULL,		NULL,
604460484Sobrien/* 08 */	NULL,		NULL,		NULL,		NULL,
604560484Sobrien/* 0C */	"pi2fw",	"pi2fd",	NULL,		NULL,
604660484Sobrien/* 10 */	NULL,		NULL,		NULL,		NULL,
604760484Sobrien/* 14 */	NULL,		NULL,		NULL,		NULL,
604860484Sobrien/* 18 */	NULL,		NULL,		NULL,		NULL,
604960484Sobrien/* 1C */	"pf2iw",	"pf2id",	NULL,		NULL,
605060484Sobrien/* 20 */	NULL,		NULL,		NULL,		NULL,
605160484Sobrien/* 24 */	NULL,		NULL,		NULL,		NULL,
605260484Sobrien/* 28 */	NULL,		NULL,		NULL,		NULL,
605360484Sobrien/* 2C */	NULL,		NULL,		NULL,		NULL,
605460484Sobrien/* 30 */	NULL,		NULL,		NULL,		NULL,
605560484Sobrien/* 34 */	NULL,		NULL,		NULL,		NULL,
605660484Sobrien/* 38 */	NULL,		NULL,		NULL,		NULL,
605760484Sobrien/* 3C */	NULL,		NULL,		NULL,		NULL,
605860484Sobrien/* 40 */	NULL,		NULL,		NULL,		NULL,
605960484Sobrien/* 44 */	NULL,		NULL,		NULL,		NULL,
606060484Sobrien/* 48 */	NULL,		NULL,		NULL,		NULL,
606160484Sobrien/* 4C */	NULL,		NULL,		NULL,		NULL,
606260484Sobrien/* 50 */	NULL,		NULL,		NULL,		NULL,
606360484Sobrien/* 54 */	NULL,		NULL,		NULL,		NULL,
606460484Sobrien/* 58 */	NULL,		NULL,		NULL,		NULL,
606560484Sobrien/* 5C */	NULL,		NULL,		NULL,		NULL,
606660484Sobrien/* 60 */	NULL,		NULL,		NULL,		NULL,
606760484Sobrien/* 64 */	NULL,		NULL,		NULL,		NULL,
606860484Sobrien/* 68 */	NULL,		NULL,		NULL,		NULL,
606960484Sobrien/* 6C */	NULL,		NULL,		NULL,		NULL,
607060484Sobrien/* 70 */	NULL,		NULL,		NULL,		NULL,
607160484Sobrien/* 74 */	NULL,		NULL,		NULL,		NULL,
607260484Sobrien/* 78 */	NULL,		NULL,		NULL,		NULL,
607360484Sobrien/* 7C */	NULL,		NULL,		NULL,		NULL,
607460484Sobrien/* 80 */	NULL,		NULL,		NULL,		NULL,
607560484Sobrien/* 84 */	NULL,		NULL,		NULL,		NULL,
607660484Sobrien/* 88 */	NULL,		NULL,		"pfnacc",	NULL,
607760484Sobrien/* 8C */	NULL,		NULL,		"pfpnacc",	NULL,
607860484Sobrien/* 90 */	"pfcmpge",	NULL,		NULL,		NULL,
607960484Sobrien/* 94 */	"pfmin",	NULL,		"pfrcp",	"pfrsqrt",
608060484Sobrien/* 98 */	NULL,		NULL,		"pfsub",	NULL,
608160484Sobrien/* 9C */	NULL,		NULL,		"pfadd",	NULL,
608260484Sobrien/* A0 */	"pfcmpgt",	NULL,		NULL,		NULL,
608360484Sobrien/* A4 */	"pfmax",	NULL,		"pfrcpit1",	"pfrsqit1",
608460484Sobrien/* A8 */	NULL,		NULL,		"pfsubr",	NULL,
608560484Sobrien/* AC */	NULL,		NULL,		"pfacc",	NULL,
608660484Sobrien/* B0 */	"pfcmpeq",	NULL,		NULL,		NULL,
6087218822Sdim/* B4 */	"pfmul",	NULL,		"pfrcpit2",	"pmulhrw",
608860484Sobrien/* B8 */	NULL,		NULL,		NULL,		"pswapd",
608960484Sobrien/* BC */	NULL,		NULL,		NULL,		"pavgusb",
609060484Sobrien/* C0 */	NULL,		NULL,		NULL,		NULL,
609160484Sobrien/* C4 */	NULL,		NULL,		NULL,		NULL,
609260484Sobrien/* C8 */	NULL,		NULL,		NULL,		NULL,
609360484Sobrien/* CC */	NULL,		NULL,		NULL,		NULL,
609460484Sobrien/* D0 */	NULL,		NULL,		NULL,		NULL,
609560484Sobrien/* D4 */	NULL,		NULL,		NULL,		NULL,
609660484Sobrien/* D8 */	NULL,		NULL,		NULL,		NULL,
609760484Sobrien/* DC */	NULL,		NULL,		NULL,		NULL,
609860484Sobrien/* E0 */	NULL,		NULL,		NULL,		NULL,
609960484Sobrien/* E4 */	NULL,		NULL,		NULL,		NULL,
610060484Sobrien/* E8 */	NULL,		NULL,		NULL,		NULL,
610160484Sobrien/* EC */	NULL,		NULL,		NULL,		NULL,
610260484Sobrien/* F0 */	NULL,		NULL,		NULL,		NULL,
610360484Sobrien/* F4 */	NULL,		NULL,		NULL,		NULL,
610460484Sobrien/* F8 */	NULL,		NULL,		NULL,		NULL,
610560484Sobrien/* FC */	NULL,		NULL,		NULL,		NULL,
610660484Sobrien};
610760484Sobrien
610860484Sobrienstatic void
6109130561SobrienOP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
611060484Sobrien{
611160484Sobrien  const char *mnemonic;
611260484Sobrien
6113223262Sbenl  (void) FETCH_DATA (the_info, codep + 1);
611460484Sobrien  /* AMD 3DNow! instructions are specified by an opcode suffix in the
611560484Sobrien     place where an 8-bit immediate would normally go.  ie. the last
611660484Sobrien     byte of the instruction.  */
611785815Sobrien  obufp = obuf + strlen (obuf);
611860484Sobrien  mnemonic = Suffix3DNow[*codep++ & 0xff];
611960484Sobrien  if (mnemonic)
612060484Sobrien    oappend (mnemonic);
612160484Sobrien  else
612260484Sobrien    {
612360484Sobrien      /* Since a variable sized modrm/sib chunk is between the start
612460484Sobrien	 of the opcode (0x0f0f) and the opcode suffix, we need to do
612560484Sobrien	 all the modrm processing first, and don't know until now that
612660484Sobrien	 we have a bad opcode.  This necessitates some cleaning up.  */
6127218822Sdim      op_out[0][0] = '\0';
6128218822Sdim      op_out[1][0] = '\0';
612985815Sobrien      BadOp ();
613060484Sobrien    }
613160484Sobrien}
613260484Sobrien
613385815Sobrienstatic const char *simd_cmp_op[] = {
613460484Sobrien  "eq",
613560484Sobrien  "lt",
613660484Sobrien  "le",
613760484Sobrien  "unord",
613860484Sobrien  "neq",
613960484Sobrien  "nlt",
614060484Sobrien  "nle",
614160484Sobrien  "ord"
614260484Sobrien};
614360484Sobrien
614460484Sobrienstatic void
6145130561SobrienOP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
614660484Sobrien{
614760484Sobrien  unsigned int cmp_type;
614860484Sobrien
6149223262Sbenl  (void) FETCH_DATA (the_info, codep + 1);
615085815Sobrien  obufp = obuf + strlen (obuf);
615160484Sobrien  cmp_type = *codep++ & 0xff;
615260484Sobrien  if (cmp_type < 8)
615360484Sobrien    {
615477298Sobrien      char suffix1 = 'p', suffix2 = 's';
615560484Sobrien      used_prefixes |= (prefixes & PREFIX_REPZ);
615677298Sobrien      if (prefixes & PREFIX_REPZ)
615777298Sobrien	suffix1 = 's';
615877298Sobrien      else
615977298Sobrien	{
616077298Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
616177298Sobrien	  if (prefixes & PREFIX_DATA)
616277298Sobrien	    suffix2 = 'd';
616377298Sobrien	  else
616477298Sobrien	    {
616577298Sobrien	      used_prefixes |= (prefixes & PREFIX_REPNZ);
616677298Sobrien	      if (prefixes & PREFIX_REPNZ)
616777298Sobrien		suffix1 = 's', suffix2 = 'd';
616877298Sobrien	    }
616977298Sobrien	}
617077298Sobrien      sprintf (scratchbuf, "cmp%s%c%c",
617177298Sobrien	       simd_cmp_op[cmp_type], suffix1, suffix2);
617277298Sobrien      used_prefixes |= (prefixes & PREFIX_REPZ);
617360484Sobrien      oappend (scratchbuf);
617460484Sobrien    }
617560484Sobrien  else
617660484Sobrien    {
617760484Sobrien      /* We have a bad extension byte.  Clean up.  */
6178218822Sdim      op_out[0][0] = '\0';
6179218822Sdim      op_out[1][0] = '\0';
618085815Sobrien      BadOp ();
618160484Sobrien    }
618260484Sobrien}
618360484Sobrien
618460484Sobrienstatic void
6185130561SobrienSIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
618660484Sobrien{
618760484Sobrien  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
618860484Sobrien     forms of these instructions.  */
6189218822Sdim  if (modrm.mod == 3)
619060484Sobrien    {
619185815Sobrien      char *p = obuf + strlen (obuf);
619285815Sobrien      *(p + 1) = '\0';
619385815Sobrien      *p       = *(p - 1);
619485815Sobrien      *(p - 1) = *(p - 2);
619585815Sobrien      *(p - 2) = *(p - 3);
619685815Sobrien      *(p - 3) = extrachar;
619760484Sobrien    }
619860484Sobrien}
619960484Sobrien
620085815Sobrienstatic void
6201130561SobrienPNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6202130561Sobrien{
6203218822Sdim  if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
6204130561Sobrien    {
6205218822Sdim      /* Override "sidt".  */
6206218822Sdim      size_t olen = strlen (obuf);
6207218822Sdim      char *p = obuf + olen - 4;
6208218822Sdim      const char **names = (address_mode == mode_64bit
6209218822Sdim			    ? names64 : names32);
6210130561Sobrien
6211218822Sdim      /* We might have a suffix when disassembling with -Msuffix.  */
6212218822Sdim      if (*p == 'i')
6213218822Sdim	--p;
6214218822Sdim
6215218822Sdim      /* Remove "addr16/addr32" if we aren't in Intel mode.  */
6216218822Sdim      if (!intel_syntax
6217218822Sdim	  && (prefixes & PREFIX_ADDR)
6218218822Sdim	  && olen >= (4 + 7)
6219218822Sdim	  && *(p - 1) == ' '
6220218822Sdim	  && CONST_STRNEQ (p - 7, "addr")
6221218822Sdim	  && (CONST_STRNEQ (p - 3, "16")
6222218822Sdim	      || CONST_STRNEQ (p - 3, "32")))
6223218822Sdim	p -= 7;
6224218822Sdim
6225218822Sdim      if (modrm.rm)
6226130561Sobrien	{
6227130561Sobrien	  /* mwait %eax,%ecx  */
6228218822Sdim	  strcpy (p, "mwait");
6229218822Sdim	  if (!intel_syntax)
6230218822Sdim	    strcpy (op_out[0], names[0]);
6231130561Sobrien	}
6232130561Sobrien      else
6233130561Sobrien	{
6234130561Sobrien	  /* monitor %eax,%ecx,%edx"  */
6235218822Sdim	  strcpy (p, "monitor");
6236218822Sdim	  if (!intel_syntax)
6237218822Sdim	    {
6238218822Sdim	      const char **op1_names;
6239218822Sdim	      if (!(prefixes & PREFIX_ADDR))
6240218822Sdim		op1_names = (address_mode == mode_16bit
6241218822Sdim			     ? names16 : names);
6242218822Sdim	      else
6243218822Sdim		{
6244218822Sdim		  op1_names = (address_mode != mode_32bit
6245218822Sdim			       ? names32 : names16);
6246218822Sdim		  used_prefixes |= PREFIX_ADDR;
6247218822Sdim		}
6248218822Sdim	      strcpy (op_out[0], op1_names[0]);
6249218822Sdim	      strcpy (op_out[2], names[2]);
6250218822Sdim	    }
6251130561Sobrien	}
6252218822Sdim      if (!intel_syntax)
6253218822Sdim	{
6254218822Sdim	  strcpy (op_out[1], names[1]);
6255218822Sdim	  two_source_ops = 1;
6256218822Sdim	}
6257130561Sobrien
6258130561Sobrien      codep++;
6259130561Sobrien    }
6260130561Sobrien  else
6261218822Sdim    OP_M (0, sizeflag);
6262130561Sobrien}
6263130561Sobrien
6264130561Sobrienstatic void
6265238123SjhbXCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6266238123Sjhb{
6267238123Sjhb  if (modrm.mod == 3 && modrm.reg == 2 && modrm.rm <= 1)
6268238123Sjhb    {
6269238123Sjhb      /* Override "lgdt".  */
6270238123Sjhb      size_t olen = strlen (obuf);
6271238123Sjhb      char *p = obuf + olen - 4;
6272238123Sjhb
6273238123Sjhb      /* We might have a suffix when disassembling with -Msuffix.  */
6274238123Sjhb      if (*p == 'i')
6275238123Sjhb	--p;
6276238123Sjhb
6277238123Sjhb      /* Remove "addr16/addr32" if we aren't in Intel mode.  */
6278238123Sjhb      if (!intel_syntax
6279238123Sjhb	  && (prefixes & PREFIX_ADDR)
6280238123Sjhb	  && olen >= (4 + 7)
6281238123Sjhb	  && *(p - 1) == ' '
6282238123Sjhb	  && CONST_STRNEQ (p - 7, "addr")
6283238123Sjhb	  && (CONST_STRNEQ (p - 3, "16")
6284238123Sjhb	      || CONST_STRNEQ (p - 3, "32")))
6285238123Sjhb	p -= 7;
6286238123Sjhb
6287238123Sjhb      if (modrm.rm)
6288238123Sjhb	{
6289238123Sjhb	  strcpy (p, "xsetbv");
6290238123Sjhb	}
6291238123Sjhb      else
6292238123Sjhb	{
6293238123Sjhb	  strcpy (p, "xgetbv");
6294238123Sjhb	}
6295238123Sjhb
6296238123Sjhb      codep++;
6297238123Sjhb    }
6298238123Sjhb  else
6299238123Sjhb    OP_M (0, sizeflag);
6300238123Sjhb}
6301238123Sjhbstatic void
6302218822SdimSVME_Fixup (int bytemode, int sizeflag)
6303218822Sdim{
6304218822Sdim  const char *alt;
6305218822Sdim  char *p;
6306218822Sdim
6307218822Sdim  switch (*codep)
6308218822Sdim    {
6309218822Sdim    case 0xd8:
6310218822Sdim      alt = "vmrun";
6311218822Sdim      break;
6312218822Sdim    case 0xd9:
6313218822Sdim      alt = "vmmcall";
6314218822Sdim      break;
6315218822Sdim    case 0xda:
6316218822Sdim      alt = "vmload";
6317218822Sdim      break;
6318218822Sdim    case 0xdb:
6319218822Sdim      alt = "vmsave";
6320218822Sdim      break;
6321218822Sdim    case 0xdc:
6322218822Sdim      alt = "stgi";
6323218822Sdim      break;
6324218822Sdim    case 0xdd:
6325218822Sdim      alt = "clgi";
6326218822Sdim      break;
6327218822Sdim    case 0xde:
6328218822Sdim      alt = "skinit";
6329218822Sdim      break;
6330218822Sdim    case 0xdf:
6331218822Sdim      alt = "invlpga";
6332218822Sdim      break;
6333218822Sdim    default:
6334218822Sdim      OP_M (bytemode, sizeflag);
6335218822Sdim      return;
6336218822Sdim    }
6337218822Sdim  /* Override "lidt".  */
6338218822Sdim  p = obuf + strlen (obuf) - 4;
6339218822Sdim  /* We might have a suffix.  */
6340218822Sdim  if (*p == 'i')
6341218822Sdim    --p;
6342218822Sdim  strcpy (p, alt);
6343218822Sdim  if (!(prefixes & PREFIX_ADDR))
6344218822Sdim    {
6345218822Sdim      ++codep;
6346218822Sdim      return;
6347218822Sdim    }
6348218822Sdim  used_prefixes |= PREFIX_ADDR;
6349218822Sdim  switch (*codep++)
6350218822Sdim    {
6351218822Sdim    case 0xdf:
6352218822Sdim      strcpy (op_out[1], names32[1]);
6353218822Sdim      two_source_ops = 1;
6354218822Sdim	  /* Fall through.  */
6355218822Sdim    case 0xd8:
6356218822Sdim    case 0xda:
6357218822Sdim    case 0xdb:
6358218822Sdim      *obufp++ = open_char;
6359218822Sdim      if (address_mode == mode_64bit || (sizeflag & AFLAG))
6360218822Sdim        alt = names32[0];
6361218822Sdim      else
6362218822Sdim        alt = names16[0];
6363218822Sdim      strcpy (obufp, alt);
6364218822Sdim      obufp += strlen (alt);
6365218822Sdim      *obufp++ = close_char;
6366218822Sdim      *obufp = '\0';
6367218822Sdim      break;
6368218822Sdim    }
6369218822Sdim}
6370218822Sdim
6371218822Sdimstatic void
6372130561SobrienINVLPG_Fixup (int bytemode, int sizeflag)
6373130561Sobrien{
6374218822Sdim  const char *alt;
6375218822Sdim
6376218822Sdim  switch (*codep)
6377130561Sobrien    {
6378218822Sdim    case 0xf8:
6379218822Sdim      alt = "swapgs";
6380218822Sdim      break;
6381218822Sdim    case 0xf9:
6382218822Sdim      alt = "rdtscp";
6383218822Sdim      break;
6384218822Sdim    default:
6385218822Sdim      OP_M (bytemode, sizeflag);
6386218822Sdim      return;
6387130561Sobrien    }
6388218822Sdim  /* Override "invlpg".  */
6389218822Sdim  strcpy (obuf + strlen (obuf) - 6, alt);
6390218822Sdim  codep++;
6391130561Sobrien}
6392130561Sobrien
6393130561Sobrienstatic void
639485815SobrienBadOp (void)
639560484Sobrien{
639685815Sobrien  /* Throw away prefixes and 1st. opcode byte.  */
639785815Sobrien  codep = insn_codep + 1;
639860484Sobrien  oappend ("(bad)");
639960484Sobrien}
6400218822Sdim
6401218822Sdimstatic void
6402218822SdimVMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6403218822Sdim{
6404218822Sdim  if (modrm.mod == 3
6405218822Sdim      && modrm.reg == 0
6406218822Sdim      && modrm.rm >=1
6407218822Sdim      && modrm.rm <= 4)
6408218822Sdim    {
6409218822Sdim      /* Override "sgdt".  */
6410218822Sdim      char *p = obuf + strlen (obuf) - 4;
6411218822Sdim
6412218822Sdim      /* We might have a suffix when disassembling with -Msuffix.  */
6413218822Sdim      if (*p == 'g')
6414218822Sdim	--p;
6415218822Sdim
6416218822Sdim      switch (modrm.rm)
6417218822Sdim	{
6418218822Sdim	case 1:
6419218822Sdim	  strcpy (p, "vmcall");
6420218822Sdim	  break;
6421218822Sdim	case 2:
6422218822Sdim	  strcpy (p, "vmlaunch");
6423218822Sdim	  break;
6424218822Sdim	case 3:
6425218822Sdim	  strcpy (p, "vmresume");
6426218822Sdim	  break;
6427218822Sdim	case 4:
6428218822Sdim	  strcpy (p, "vmxoff");
6429218822Sdim	  break;
6430218822Sdim	}
6431218822Sdim
6432218822Sdim      codep++;
6433218822Sdim    }
6434218822Sdim  else
6435218822Sdim    OP_E (0, sizeflag);
6436218822Sdim}
6437218822Sdim
6438218822Sdimstatic void
6439218822SdimOP_VMX (int bytemode, int sizeflag)
6440218822Sdim{
6441256112Sdim  if (modrm.mod == 3)
6442256112Sdim    {
6443256112Sdim      strcpy (obuf, "rdrand");
6444256112Sdim      OP_E (v_mode, sizeflag);
6445256112Sdim    }
6446218822Sdim  else
6447256112Sdim    {
6448256112Sdim      used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6449256112Sdim      if (prefixes & PREFIX_DATA)
6450256112Sdim	strcpy (obuf, "vmclear");
6451256112Sdim      else if (prefixes & PREFIX_REPZ)
6452256112Sdim	strcpy (obuf, "vmxon");
6453256112Sdim      else
6454256112Sdim	strcpy (obuf, "vmptrld");
6455256112Sdim      OP_E (bytemode, sizeflag);
6456256112Sdim    }
6457218822Sdim}
6458218822Sdim
6459218822Sdimstatic void
6460218822SdimREP_Fixup (int bytemode, int sizeflag)
6461218822Sdim{
6462218822Sdim  /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6463218822Sdim     lods and stos.  */
6464218822Sdim  size_t ilen = 0;
6465218822Sdim
6466218822Sdim  if (prefixes & PREFIX_REPZ)
6467218822Sdim    switch (*insn_codep)
6468218822Sdim      {
6469218822Sdim      case 0x6e:	/* outsb */
6470218822Sdim      case 0x6f:	/* outsw/outsl */
6471218822Sdim      case 0xa4:	/* movsb */
6472218822Sdim      case 0xa5:	/* movsw/movsl/movsq */
6473218822Sdim	if (!intel_syntax)
6474218822Sdim	  ilen = 5;
6475218822Sdim	else
6476218822Sdim	  ilen = 4;
6477218822Sdim	break;
6478218822Sdim      case 0xaa:	/* stosb */
6479218822Sdim      case 0xab:	/* stosw/stosl/stosq */
6480218822Sdim      case 0xac:	/* lodsb */
6481218822Sdim      case 0xad:	/* lodsw/lodsl/lodsq */
6482218822Sdim	if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6483218822Sdim	  ilen = 5;
6484218822Sdim	else
6485218822Sdim	  ilen = 4;
6486218822Sdim	break;
6487218822Sdim      case 0x6c:	/* insb */
6488218822Sdim      case 0x6d:	/* insl/insw */
6489218822Sdim	if (!intel_syntax)
6490218822Sdim	  ilen = 4;
6491218822Sdim	else
6492218822Sdim	  ilen = 3;
6493218822Sdim	break;
6494218822Sdim      default:
6495218822Sdim	abort ();
6496218822Sdim	break;
6497218822Sdim      }
6498218822Sdim
6499218822Sdim  if (ilen != 0)
6500218822Sdim    {
6501218822Sdim      size_t olen;
6502218822Sdim      char *p;
6503218822Sdim
6504218822Sdim      olen = strlen (obuf);
6505218822Sdim      p = obuf + olen - ilen - 1 - 4;
6506218822Sdim      /* Handle "repz [addr16|addr32]".  */
6507218822Sdim      if ((prefixes & PREFIX_ADDR))
6508218822Sdim	p -= 1 + 6;
6509218822Sdim
6510218822Sdim      memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6511218822Sdim    }
6512218822Sdim
6513218822Sdim  switch (bytemode)
6514218822Sdim    {
6515218822Sdim    case al_reg:
6516218822Sdim    case eAX_reg:
6517218822Sdim    case indir_dx_reg:
6518218822Sdim      OP_IMREG (bytemode, sizeflag);
6519218822Sdim      break;
6520218822Sdim    case eDI_reg:
6521218822Sdim      OP_ESreg (bytemode, sizeflag);
6522218822Sdim      break;
6523218822Sdim    case eSI_reg:
6524218822Sdim      OP_DSreg (bytemode, sizeflag);
6525218822Sdim      break;
6526218822Sdim    default:
6527218822Sdim      abort ();
6528218822Sdim      break;
6529218822Sdim    }
6530218822Sdim}
6531218822Sdim
6532218822Sdimstatic void
6533218822SdimCMPXCHG8B_Fixup (int bytemode, int sizeflag)
6534218822Sdim{
6535218822Sdim  USED_REX (REX_W);
6536218822Sdim  if (rex & REX_W)
6537218822Sdim    {
6538218822Sdim      /* Change cmpxchg8b to cmpxchg16b.  */
6539218822Sdim      char *p = obuf + strlen (obuf) - 2;
6540218822Sdim      strcpy (p, "16b");
6541218822Sdim      bytemode = o_mode;
6542218822Sdim    }
6543218822Sdim  OP_M (bytemode, sizeflag);
6544218822Sdim}
6545218822Sdim
6546218822Sdimstatic void
6547218822SdimXMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6548218822Sdim{
6549218822Sdim  sprintf (scratchbuf, "%%xmm%d", reg);
6550218822Sdim  oappend (scratchbuf + intel_syntax);
6551218822Sdim}
6552218822Sdim
6553218822Sdimstatic void
6554218822SdimCRC32_Fixup (int bytemode, int sizeflag)
6555218822Sdim{
6556218822Sdim  /* Add proper suffix to "crc32".  */
6557218822Sdim  char *p = obuf + strlen (obuf);
6558218822Sdim
6559218822Sdim  switch (bytemode)
6560218822Sdim    {
6561218822Sdim    case b_mode:
6562218822Sdim      if (intel_syntax)
6563218822Sdim	break;
6564218822Sdim
6565218822Sdim      *p++ = 'b';
6566218822Sdim      break;
6567218822Sdim    case v_mode:
6568218822Sdim      if (intel_syntax)
6569218822Sdim	break;
6570218822Sdim
6571218822Sdim      USED_REX (REX_W);
6572218822Sdim      if (rex & REX_W)
6573218822Sdim	*p++ = 'q';
6574218822Sdim      else if (sizeflag & DFLAG)
6575218822Sdim	*p++ = 'l';
6576218822Sdim      else
6577218822Sdim	*p++ = 'w';
6578218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
6579218822Sdim      break;
6580218822Sdim    default:
6581218822Sdim      oappend (INTERNAL_DISASSEMBLER_ERROR);
6582218822Sdim      break;
6583218822Sdim    }
6584218822Sdim  *p = '\0';
6585218822Sdim
6586218822Sdim  if (modrm.mod == 3)
6587218822Sdim    {
6588218822Sdim      int add;
6589218822Sdim
6590218822Sdim      /* Skip mod/rm byte.  */
6591218822Sdim      MODRM_CHECK;
6592218822Sdim      codep++;
6593218822Sdim
6594218822Sdim      USED_REX (REX_B);
6595218822Sdim      add = (rex & REX_B) ? 8 : 0;
6596218822Sdim      if (bytemode == b_mode)
6597218822Sdim	{
6598218822Sdim	  USED_REX (0);
6599218822Sdim	  if (rex)
6600218822Sdim	    oappend (names8rex[modrm.rm + add]);
6601218822Sdim	  else
6602218822Sdim	    oappend (names8[modrm.rm + add]);
6603218822Sdim	}
6604218822Sdim      else
6605218822Sdim	{
6606218822Sdim	  USED_REX (REX_W);
6607218822Sdim	  if (rex & REX_W)
6608218822Sdim	    oappend (names64[modrm.rm + add]);
6609218822Sdim	  else if ((prefixes & PREFIX_DATA))
6610218822Sdim	    oappend (names16[modrm.rm + add]);
6611218822Sdim	  else
6612218822Sdim	    oappend (names32[modrm.rm + add]);
6613218822Sdim	}
6614218822Sdim    }
6615218822Sdim  else
6616218822Sdim    OP_E (bytemode, sizeflag);
6617218822Sdim}
6618