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);
88266391Sjhbstatic void OP_VMX2 (int, int);
89130561Sobrienstatic void OP_0fae (int, int);
90130561Sobrienstatic void OP_0f07 (int, int);
91218822Sdimstatic void NOP_Fixup1 (int, int);
92218822Sdimstatic void NOP_Fixup2 (int, int);
93130561Sobrienstatic void OP_3DNowSuffix (int, int);
94130561Sobrienstatic void OP_SIMD_Suffix (int, int);
95130561Sobrienstatic void SIMD_Fixup (int, int);
96130561Sobrienstatic void PNI_Fixup (int, int);
97238123Sjhbstatic void XCR_Fixup (int, int);
98218822Sdimstatic void SVME_Fixup (int, int);
99130561Sobrienstatic void INVLPG_Fixup (int, int);
100130561Sobrienstatic void BadOp (void);
101218822Sdimstatic void VMX_Fixup (int, int);
102218822Sdimstatic void REP_Fixup (int, int);
103218822Sdimstatic void CMPXCHG8B_Fixup (int, int);
104218822Sdimstatic void XMM_Fixup (int, int);
105218822Sdimstatic void CRC32_Fixup (int, int);
10633965Sjdp
10785815Sobrienstruct dis_private {
10833965Sjdp  /* Points to first byte not fetched.  */
10933965Sjdp  bfd_byte *max_fetched;
110218822Sdim  bfd_byte the_buffer[MAX_MNEM_SIZE];
11133965Sjdp  bfd_vma insn_start;
11289857Sobrien  int orig_sizeflag;
11333965Sjdp  jmp_buf bailout;
11433965Sjdp};
11533965Sjdp
116218822Sdimenum address_mode
117218822Sdim{
118218822Sdim  mode_16bit,
119218822Sdim  mode_32bit,
120218822Sdim  mode_64bit
121218822Sdim};
12260484Sobrien
123218822Sdimenum address_mode address_mode;
12477298Sobrien
12560484Sobrien/* Flags for the prefixes for the current instruction.  See below.  */
12660484Sobrienstatic int prefixes;
12760484Sobrien
12877298Sobrien/* REX prefix the current instruction.  See below.  */
12977298Sobrienstatic int rex;
13077298Sobrien/* Bits of REX we've already used.  */
13177298Sobrienstatic int rex_used;
13277298Sobrien/* Mark parts used in the REX prefix.  When we are testing for
13377298Sobrien   empty prefix (for 8bit register REX extension), just mask it
13477298Sobrien   out.  Otherwise test for REX bit is excuse for existence of REX
13577298Sobrien   only in case value is nonzero.  */
13677298Sobrien#define USED_REX(value)					\
13777298Sobrien  {							\
13877298Sobrien    if (value)						\
139218822Sdim      {							\
140218822Sdim	if ((rex & value))				\
141218822Sdim	  rex_used |= (value) | REX_OPCODE;		\
142218822Sdim      }							\
14377298Sobrien    else						\
144218822Sdim      rex_used |= REX_OPCODE;				\
14577298Sobrien  }
14677298Sobrien
14760484Sobrien/* Flags for prefixes which we somehow handled when printing the
14860484Sobrien   current instruction.  */
14960484Sobrienstatic int used_prefixes;
15060484Sobrien
15160484Sobrien/* Flags stored in PREFIXES.  */
15260484Sobrien#define PREFIX_REPZ 1
15360484Sobrien#define PREFIX_REPNZ 2
15460484Sobrien#define PREFIX_LOCK 4
15560484Sobrien#define PREFIX_CS 8
15660484Sobrien#define PREFIX_SS 0x10
15760484Sobrien#define PREFIX_DS 0x20
15860484Sobrien#define PREFIX_ES 0x40
15960484Sobrien#define PREFIX_FS 0x80
16060484Sobrien#define PREFIX_GS 0x100
16160484Sobrien#define PREFIX_DATA 0x200
16260484Sobrien#define PREFIX_ADDR 0x400
16360484Sobrien#define PREFIX_FWAIT 0x800
16460484Sobrien
16533965Sjdp/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
16633965Sjdp   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
16733965Sjdp   on error.  */
16833965Sjdp#define FETCH_DATA(info, addr) \
16985815Sobrien  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
17033965Sjdp   ? 1 : fetch_data ((info), (addr)))
17133965Sjdp
17233965Sjdpstatic int
173130561Sobrienfetch_data (struct disassemble_info *info, bfd_byte *addr)
17433965Sjdp{
17533965Sjdp  int status;
17685815Sobrien  struct dis_private *priv = (struct dis_private *) info->private_data;
17733965Sjdp  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
17833965Sjdp
179218822Sdim  if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
180218822Sdim    status = (*info->read_memory_func) (start,
181218822Sdim					priv->max_fetched,
182218822Sdim					addr - priv->max_fetched,
183218822Sdim					info);
184218822Sdim  else
185218822Sdim    status = -1;
18633965Sjdp  if (status != 0)
18733965Sjdp    {
18860484Sobrien      /* If we did manage to read at least one byte, then
189130561Sobrien	 print_insn_i386 will do something sensible.  Otherwise, print
190130561Sobrien	 an error.  We do that here because this is where we know
191130561Sobrien	 STATUS.  */
19260484Sobrien      if (priv->max_fetched == priv->the_buffer)
19360484Sobrien	(*info->memory_error_func) (status, start, info);
19433965Sjdp      longjmp (priv->bailout, 1);
19533965Sjdp    }
19633965Sjdp  else
19733965Sjdp    priv->max_fetched = addr;
19833965Sjdp  return 1;
19933965Sjdp}
20033965Sjdp
201218822Sdim#define XX { NULL, 0 }
20260484Sobrien
203218822Sdim#define Eb { OP_E, b_mode }
204218822Sdim#define Ev { OP_E, v_mode }
205218822Sdim#define Ed { OP_E, d_mode }
206218822Sdim#define Edq { OP_E, dq_mode }
207218822Sdim#define Edqw { OP_E, dqw_mode }
208218822Sdim#define Edqb { OP_E, dqb_mode }
209218822Sdim#define Edqd { OP_E, dqd_mode }
210218822Sdim#define indirEv { OP_indirE, stack_v_mode }
211218822Sdim#define indirEp { OP_indirE, f_mode }
212218822Sdim#define stackEv { OP_E, stack_v_mode }
213218822Sdim#define Em { OP_E, m_mode }
214218822Sdim#define Ew { OP_E, w_mode }
215218822Sdim#define M { OP_M, 0 }		/* lea, lgdt, etc. */
216218822Sdim#define Ma { OP_M, v_mode }
217238167Sjhb#define Mo { OP_M, o_mode }
218218822Sdim#define Mp { OP_M, f_mode }		/* 32 or 48 bit memory operand for LDS, LES etc */
219218822Sdim#define Mq { OP_M, q_mode }
220218822Sdim#define Gb { OP_G, b_mode }
221218822Sdim#define Gv { OP_G, v_mode }
222218822Sdim#define Gd { OP_G, d_mode }
223218822Sdim#define Gdq { OP_G, dq_mode }
224218822Sdim#define Gm { OP_G, m_mode }
225218822Sdim#define Gw { OP_G, w_mode }
226218822Sdim#define Rd { OP_R, d_mode }
227218822Sdim#define Rm { OP_R, m_mode }
228218822Sdim#define Ib { OP_I, b_mode }
229218822Sdim#define sIb { OP_sI, b_mode }	/* sign extened byte */
230218822Sdim#define Iv { OP_I, v_mode }
231218822Sdim#define Iq { OP_I, q_mode }
232218822Sdim#define Iv64 { OP_I64, v_mode }
233218822Sdim#define Iw { OP_I, w_mode }
234218822Sdim#define I1 { OP_I, const_1_mode }
235218822Sdim#define Jb { OP_J, b_mode }
236218822Sdim#define Jv { OP_J, v_mode }
237218822Sdim#define Cm { OP_C, m_mode }
238218822Sdim#define Dm { OP_D, m_mode }
239218822Sdim#define Td { OP_T, d_mode }
24033965Sjdp
241218822Sdim#define RMeAX { OP_REG, eAX_reg }
242218822Sdim#define RMeBX { OP_REG, eBX_reg }
243218822Sdim#define RMeCX { OP_REG, eCX_reg }
244218822Sdim#define RMeDX { OP_REG, eDX_reg }
245218822Sdim#define RMeSP { OP_REG, eSP_reg }
246218822Sdim#define RMeBP { OP_REG, eBP_reg }
247218822Sdim#define RMeSI { OP_REG, eSI_reg }
248218822Sdim#define RMeDI { OP_REG, eDI_reg }
249218822Sdim#define RMrAX { OP_REG, rAX_reg }
250218822Sdim#define RMrBX { OP_REG, rBX_reg }
251218822Sdim#define RMrCX { OP_REG, rCX_reg }
252218822Sdim#define RMrDX { OP_REG, rDX_reg }
253218822Sdim#define RMrSP { OP_REG, rSP_reg }
254218822Sdim#define RMrBP { OP_REG, rBP_reg }
255218822Sdim#define RMrSI { OP_REG, rSI_reg }
256218822Sdim#define RMrDI { OP_REG, rDI_reg }
257218822Sdim#define RMAL { OP_REG, al_reg }
258218822Sdim#define RMAL { OP_REG, al_reg }
259218822Sdim#define RMCL { OP_REG, cl_reg }
260218822Sdim#define RMDL { OP_REG, dl_reg }
261218822Sdim#define RMBL { OP_REG, bl_reg }
262218822Sdim#define RMAH { OP_REG, ah_reg }
263218822Sdim#define RMCH { OP_REG, ch_reg }
264218822Sdim#define RMDH { OP_REG, dh_reg }
265218822Sdim#define RMBH { OP_REG, bh_reg }
266218822Sdim#define RMAX { OP_REG, ax_reg }
267218822Sdim#define RMDX { OP_REG, dx_reg }
26833965Sjdp
269218822Sdim#define eAX { OP_IMREG, eAX_reg }
270218822Sdim#define eBX { OP_IMREG, eBX_reg }
271218822Sdim#define eCX { OP_IMREG, eCX_reg }
272218822Sdim#define eDX { OP_IMREG, eDX_reg }
273218822Sdim#define eSP { OP_IMREG, eSP_reg }
274218822Sdim#define eBP { OP_IMREG, eBP_reg }
275218822Sdim#define eSI { OP_IMREG, eSI_reg }
276218822Sdim#define eDI { OP_IMREG, eDI_reg }
277218822Sdim#define AL { OP_IMREG, al_reg }
278218822Sdim#define CL { OP_IMREG, cl_reg }
279218822Sdim#define DL { OP_IMREG, dl_reg }
280218822Sdim#define BL { OP_IMREG, bl_reg }
281218822Sdim#define AH { OP_IMREG, ah_reg }
282218822Sdim#define CH { OP_IMREG, ch_reg }
283218822Sdim#define DH { OP_IMREG, dh_reg }
284218822Sdim#define BH { OP_IMREG, bh_reg }
285218822Sdim#define AX { OP_IMREG, ax_reg }
286218822Sdim#define DX { OP_IMREG, dx_reg }
287218822Sdim#define zAX { OP_IMREG, z_mode_ax_reg }
288218822Sdim#define indirDX { OP_IMREG, indir_dx_reg }
28977298Sobrien
290218822Sdim#define Sw { OP_SEG, w_mode }
291218822Sdim#define Sv { OP_SEG, v_mode }
292218822Sdim#define Ap { OP_DIR, 0 }
293218822Sdim#define Ob { OP_OFF64, b_mode }
294218822Sdim#define Ov { OP_OFF64, v_mode }
295218822Sdim#define Xb { OP_DSreg, eSI_reg }
296218822Sdim#define Xv { OP_DSreg, eSI_reg }
297218822Sdim#define Xz { OP_DSreg, eSI_reg }
298218822Sdim#define Yb { OP_ESreg, eDI_reg }
299218822Sdim#define Yv { OP_ESreg, eDI_reg }
300218822Sdim#define DSBX { OP_DSreg, eBX_reg }
30133965Sjdp
302218822Sdim#define es { OP_REG, es_reg }
303218822Sdim#define ss { OP_REG, ss_reg }
304218822Sdim#define cs { OP_REG, cs_reg }
305218822Sdim#define ds { OP_REG, ds_reg }
306218822Sdim#define fs { OP_REG, fs_reg }
307218822Sdim#define gs { OP_REG, gs_reg }
30833965Sjdp
309218822Sdim#define MX { OP_MMX, 0 }
310218822Sdim#define XM { OP_XMM, 0 }
311218822Sdim#define EM { OP_EM, v_mode }
312218822Sdim#define EMd { OP_EM, d_mode }
313218822Sdim#define EMq { OP_EM, q_mode }
314218822Sdim#define EXd { OP_EX, d_mode }
315218822Sdim#define EXq { OP_EX, q_mode }
316218822Sdim#define EXx { OP_EX, x_mode }
317218822Sdim#define MS { OP_MS, v_mode }
318218822Sdim#define XS { OP_XS, v_mode }
319218822Sdim#define EMC { OP_EMC, v_mode }
320218822Sdim#define MXC { OP_MXC, 0 }
321218822Sdim#define VM { OP_VMX, q_mode }
322266391Sjhb#define VM2 { OP_VMX2, q_mode }
323218822Sdim#define OPSUF { OP_3DNowSuffix, 0 }
324218822Sdim#define OPSIMD { OP_SIMD_Suffix, 0 }
325218822Sdim#define XMM0 { XMM_Fixup, 0 }
32633965Sjdp
327218822Sdim/* Used handle "rep" prefix for string instructions.  */
328218822Sdim#define Xbr { REP_Fixup, eSI_reg }
329218822Sdim#define Xvr { REP_Fixup, eSI_reg }
330218822Sdim#define Ybr { REP_Fixup, eDI_reg }
331218822Sdim#define Yvr { REP_Fixup, eDI_reg }
332218822Sdim#define Yzr { REP_Fixup, eDI_reg }
333218822Sdim#define indirDXr { REP_Fixup, indir_dx_reg }
334218822Sdim#define ALr { REP_Fixup, al_reg }
335218822Sdim#define eAXr { REP_Fixup, eAX_reg }
33678828Sobrien
337218822Sdim#define cond_jump_flag { NULL, cond_jump_mode }
338218822Sdim#define loop_jcxz_flag { NULL, loop_jcxz_mode }
339218822Sdim
34060484Sobrien/* bits in sizeflag */
34160484Sobrien#define SUFFIX_ALWAYS 4
34260484Sobrien#define AFLAG 2
34360484Sobrien#define DFLAG 1
34433965Sjdp
34577298Sobrien#define b_mode 1  /* byte operand */
34677298Sobrien#define v_mode 2  /* operand size depends on prefixes */
34777298Sobrien#define w_mode 3  /* word operand */
34877298Sobrien#define d_mode 4  /* double word operand  */
34977298Sobrien#define q_mode 5  /* quad word operand */
350218822Sdim#define t_mode 6  /* ten-byte operand */
351218822Sdim#define x_mode 7  /* 16-byte XMM operand */
352218822Sdim#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
353218822Sdim#define cond_jump_mode 9
354218822Sdim#define loop_jcxz_mode 10
355218822Sdim#define dq_mode 11 /* operand size depends on REX prefixes.  */
356218822Sdim#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
357218822Sdim#define f_mode 13 /* 4- or 6-byte pointer operand */
358218822Sdim#define const_1_mode 14
359218822Sdim#define stack_v_mode 15 /* v_mode for stack-related opcodes.  */
360218822Sdim#define z_mode 16 /* non-quad operand size depends on prefixes */
361218822Sdim#define o_mode 17  /* 16-byte operand */
362218822Sdim#define dqb_mode 18 /* registers like dq_mode, memory like b_mode.  */
363218822Sdim#define dqd_mode 19 /* registers like dq_mode, memory like d_mode.  */
36433965Sjdp
36533965Sjdp#define es_reg 100
36633965Sjdp#define cs_reg 101
36733965Sjdp#define ss_reg 102
36833965Sjdp#define ds_reg 103
36933965Sjdp#define fs_reg 104
37033965Sjdp#define gs_reg 105
37133965Sjdp
37260484Sobrien#define eAX_reg 108
37360484Sobrien#define eCX_reg 109
37460484Sobrien#define eDX_reg 110
37560484Sobrien#define eBX_reg 111
37660484Sobrien#define eSP_reg 112
37760484Sobrien#define eBP_reg 113
37860484Sobrien#define eSI_reg 114
37960484Sobrien#define eDI_reg 115
38033965Sjdp
38133965Sjdp#define al_reg 116
38233965Sjdp#define cl_reg 117
38333965Sjdp#define dl_reg 118
38433965Sjdp#define bl_reg 119
38533965Sjdp#define ah_reg 120
38633965Sjdp#define ch_reg 121
38733965Sjdp#define dh_reg 122
38833965Sjdp#define bh_reg 123
38933965Sjdp
39033965Sjdp#define ax_reg 124
39133965Sjdp#define cx_reg 125
39233965Sjdp#define dx_reg 126
39333965Sjdp#define bx_reg 127
39433965Sjdp#define sp_reg 128
39533965Sjdp#define bp_reg 129
39633965Sjdp#define si_reg 130
39733965Sjdp#define di_reg 131
39833965Sjdp
39977298Sobrien#define rAX_reg 132
40077298Sobrien#define rCX_reg 133
40177298Sobrien#define rDX_reg 134
40277298Sobrien#define rBX_reg 135
40377298Sobrien#define rSP_reg 136
40477298Sobrien#define rBP_reg 137
40577298Sobrien#define rSI_reg 138
40677298Sobrien#define rDI_reg 139
40777298Sobrien
408218822Sdim#define z_mode_ax_reg 149
40933965Sjdp#define indir_dx_reg 150
41033965Sjdp
41185815Sobrien#define FLOATCODE 1
41285815Sobrien#define USE_GROUPS 2
41385815Sobrien#define USE_PREFIX_USER_TABLE 3
41485815Sobrien#define X86_64_SPECIAL 4
415218822Sdim#define IS_3BYTE_OPCODE 5
41633965Sjdp
417218822Sdim#define FLOAT	  NULL, { { NULL, FLOATCODE } }
41860484Sobrien
419218822Sdim#define GRP1a	  NULL, { { NULL, USE_GROUPS }, { NULL,  0 } }
420218822Sdim#define GRP1b	  NULL, { { NULL, USE_GROUPS }, { NULL,  1 } }
421218822Sdim#define GRP1S	  NULL, { { NULL, USE_GROUPS }, { NULL,  2 } }
422218822Sdim#define GRP1Ss	  NULL, { { NULL, USE_GROUPS }, { NULL,  3 } }
423218822Sdim#define GRP2b	  NULL, { { NULL, USE_GROUPS }, { NULL,  4 } }
424218822Sdim#define GRP2S	  NULL, { { NULL, USE_GROUPS }, { NULL,  5 } }
425218822Sdim#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL,  6 } }
426218822Sdim#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL,  7 } }
427218822Sdim#define GRP2b_cl  NULL, { { NULL, USE_GROUPS }, { NULL,  8 } }
428218822Sdim#define GRP2S_cl  NULL, { { NULL, USE_GROUPS }, { NULL,  9 } }
429218822Sdim#define GRP3b	  NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
430218822Sdim#define GRP3S	  NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
431218822Sdim#define GRP4	  NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
432218822Sdim#define GRP5	  NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
433218822Sdim#define GRP6	  NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
434218822Sdim#define GRP7	  NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
435218822Sdim#define GRP8	  NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
436218822Sdim#define GRP9	  NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
437218822Sdim#define GRP11_C6  NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
438218822Sdim#define GRP11_C7  NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
439218822Sdim#define GRP12	  NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
440218822Sdim#define GRP13	  NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
441218822Sdim#define GRP14	  NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
442218822Sdim#define GRP15	  NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
443218822Sdim#define GRP16	  NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
444218822Sdim#define GRPAMD	  NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
445218822Sdim#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
446218822Sdim#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
44760484Sobrien
448218822Sdim#define PREGRP0   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  0 } }
449218822Sdim#define PREGRP1   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  1 } }
450218822Sdim#define PREGRP2   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  2 } }
451218822Sdim#define PREGRP3   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  3 } }
452218822Sdim#define PREGRP4   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  4 } }
453218822Sdim#define PREGRP5   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  5 } }
454218822Sdim#define PREGRP6   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  6 } }
455218822Sdim#define PREGRP7   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  7 } }
456218822Sdim#define PREGRP8   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  8 } }
457218822Sdim#define PREGRP9   NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL,  9 } }
458218822Sdim#define PREGRP10  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
459218822Sdim#define PREGRP11  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
460218822Sdim#define PREGRP12  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
461218822Sdim#define PREGRP13  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
462218822Sdim#define PREGRP14  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
463218822Sdim#define PREGRP15  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
464218822Sdim#define PREGRP16  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
465218822Sdim#define PREGRP17  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
466218822Sdim#define PREGRP18  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
467218822Sdim#define PREGRP19  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
468218822Sdim#define PREGRP20  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
469218822Sdim#define PREGRP21  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
470218822Sdim#define PREGRP22  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
471218822Sdim#define PREGRP23  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
472218822Sdim#define PREGRP24  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
473218822Sdim#define PREGRP25  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
474218822Sdim#define PREGRP26  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
475218822Sdim#define PREGRP27  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
476218822Sdim#define PREGRP28  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
477218822Sdim#define PREGRP29  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
478218822Sdim#define PREGRP30  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
479218822Sdim#define PREGRP31  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
480218822Sdim#define PREGRP32  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
481218822Sdim#define PREGRP33  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
482218822Sdim#define PREGRP34  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
483218822Sdim#define PREGRP35  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
484218822Sdim#define PREGRP36  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
485218822Sdim#define PREGRP37  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
486218822Sdim#define PREGRP38  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
487218822Sdim#define PREGRP39  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
488218822Sdim#define PREGRP40  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
489218822Sdim#define PREGRP41  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
490218822Sdim#define PREGRP42  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
491218822Sdim#define PREGRP43  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
492218822Sdim#define PREGRP44  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
493218822Sdim#define PREGRP45  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
494218822Sdim#define PREGRP46  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
495218822Sdim#define PREGRP47  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
496218822Sdim#define PREGRP48  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
497218822Sdim#define PREGRP49  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
498218822Sdim#define PREGRP50  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
499218822Sdim#define PREGRP51  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
500218822Sdim#define PREGRP52  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
501218822Sdim#define PREGRP53  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
502218822Sdim#define PREGRP54  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
503218822Sdim#define PREGRP55  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
504218822Sdim#define PREGRP56  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
505218822Sdim#define PREGRP57  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
506218822Sdim#define PREGRP58  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
507218822Sdim#define PREGRP59  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
508218822Sdim#define PREGRP60  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
509218822Sdim#define PREGRP61  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
510218822Sdim#define PREGRP62  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
511218822Sdim#define PREGRP63  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
512218822Sdim#define PREGRP64  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
513218822Sdim#define PREGRP65  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
514218822Sdim#define PREGRP66  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
515218822Sdim#define PREGRP67  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
516218822Sdim#define PREGRP68  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
517218822Sdim#define PREGRP69  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
518218822Sdim#define PREGRP70  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
519218822Sdim#define PREGRP71  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
520218822Sdim#define PREGRP72  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
521218822Sdim#define PREGRP73  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
522218822Sdim#define PREGRP74  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
523218822Sdim#define PREGRP75  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
524218822Sdim#define PREGRP76  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
525218822Sdim#define PREGRP77  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
526218822Sdim#define PREGRP78  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
527218822Sdim#define PREGRP79  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
528218822Sdim#define PREGRP80  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
529218822Sdim#define PREGRP81  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
530218822Sdim#define PREGRP82  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
531218822Sdim#define PREGRP83  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
532218822Sdim#define PREGRP84  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
533218822Sdim#define PREGRP85  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
534218822Sdim#define PREGRP86  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
535218822Sdim#define PREGRP87  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
536218822Sdim#define PREGRP88  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
537218822Sdim#define PREGRP89  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
538218822Sdim#define PREGRP90  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
539218822Sdim#define PREGRP91  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
540218822Sdim#define PREGRP92  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
541218822Sdim#define PREGRP93  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
542218822Sdim#define PREGRP94  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
543218822Sdim#define PREGRP95  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
544218822Sdim#define PREGRP96  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
545218822Sdim#define PREGRP97  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
546238167Sjhb#define PREGRP98  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
547238167Sjhb#define PREGRP99  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
548247012Sjmg#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
549247012Sjmg#define PREGRP101 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 101 } }
550247012Sjmg#define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
551247012Sjmg#define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
552247012Sjmg#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
553247012Sjmg#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
554247012Sjmg#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
555255192Sjhb#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } }
55633965Sjdp
55785815Sobrien
558218822Sdim#define X86_64_0  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
559218822Sdim#define X86_64_1  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
560218822Sdim#define X86_64_2  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
561218822Sdim#define X86_64_3  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
562218822Sdim
563218822Sdim#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
564218822Sdim#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
565218822Sdim
566130561Sobrientypedef void (*op_rtn) (int bytemode, int sizeflag);
56785815Sobrien
56833965Sjdpstruct dis386 {
56960484Sobrien  const char *name;
570218822Sdim  struct
571218822Sdim    {
572218822Sdim      op_rtn rtn;
573218822Sdim      int bytemode;
574218822Sdim    } op[MAX_OPERANDS];
57533965Sjdp};
57633965Sjdp
57760484Sobrien/* Upper case letters in the instruction names here are macros.
57860484Sobrien   'A' => print 'b' if no register operands or suffix_always is true
57960484Sobrien   'B' => print 'b' if suffix_always is true
580218822Sdim   'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
581218822Sdim   .      size prefix
582218822Sdim   'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
583218822Sdim   .      suffix_always is true
58460484Sobrien   'E' => print 'e' if 32-bit form of jcxz
58578828Sobrien   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
586218822Sdim   'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
58785815Sobrien   'H' => print ",pt" or ",pn" branch hint
588218822Sdim   'I' => honor following macro letter even in Intel mode (implemented only
589218822Sdim   .      for some of the macro letters)
590218822Sdim   'J' => print 'l'
591218822Sdim   'K' => print 'd' or 'q' if rex prefix is present.
59260484Sobrien   'L' => print 'l' if suffix_always is true
59360484Sobrien   'N' => print 'n' if instruction has no wait "prefix"
594218822Sdim   'O' => print 'd' or 'o' (or 'q' in Intel mode)
59577298Sobrien   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
59689857Sobrien   .      or suffix_always is true.  print 'q' if rex prefix is present.
59789857Sobrien   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
59889857Sobrien   .      is true
599218822Sdim   'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
60077298Sobrien   'S' => print 'w', 'l' or 'q' if suffix_always is true
60185815Sobrien   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
60285815Sobrien   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
603218822Sdim   'V' => print 'q' in 64bit mode and behave as 'S' otherwise
604218822Sdim   'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
60577298Sobrien   'X' => print 's', 'd' depending on data16 prefix (for XMM)
60677298Sobrien   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
607218822Sdim   'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
60860484Sobrien
60985815Sobrien   Many of the above letters print nothing in Intel mode.  See "putop"
61085815Sobrien   for the details.
61133965Sjdp
61285815Sobrien   Braces '{' and '}', and vertical bars '|', indicate alternative
61385815Sobrien   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
61485815Sobrien   modes.  In cases where there are only two alternatives, the X86_64
61585815Sobrien   instruction is reserved, and "(bad)" is printed.
61685815Sobrien*/
61760484Sobrien
61885815Sobrienstatic const struct dis386 dis386[] = {
61977298Sobrien  /* 00 */
620218822Sdim  { "addB",		{ Eb, Gb } },
621218822Sdim  { "addS",		{ Ev, Gv } },
622218822Sdim  { "addB",		{ Gb, Eb } },
623218822Sdim  { "addS",		{ Gv, Ev } },
624218822Sdim  { "addB",		{ AL, Ib } },
625218822Sdim  { "addS",		{ eAX, Iv } },
626218822Sdim  { "push{T|}",		{ es } },
627218822Sdim  { "pop{T|}",		{ es } },
62877298Sobrien  /* 08 */
629218822Sdim  { "orB",		{ Eb, Gb } },
630218822Sdim  { "orS",		{ Ev, Gv } },
631218822Sdim  { "orB",		{ Gb, Eb } },
632218822Sdim  { "orS",		{ Gv, Ev } },
633218822Sdim  { "orB",		{ AL, Ib } },
634218822Sdim  { "orS",		{ eAX, Iv } },
635218822Sdim  { "push{T|}",		{ cs } },
636218822Sdim  { "(bad)",		{ XX } },	/* 0x0f extended opcode escape */
63777298Sobrien  /* 10 */
638218822Sdim  { "adcB",		{ Eb, Gb } },
639218822Sdim  { "adcS",		{ Ev, Gv } },
640218822Sdim  { "adcB",		{ Gb, Eb } },
641218822Sdim  { "adcS",		{ Gv, Ev } },
642218822Sdim  { "adcB",		{ AL, Ib } },
643218822Sdim  { "adcS",		{ eAX, Iv } },
644218822Sdim  { "push{T|}",		{ ss } },
645218822Sdim  { "pop{T|}",		{ ss } },
64677298Sobrien  /* 18 */
647218822Sdim  { "sbbB",		{ Eb, Gb } },
648218822Sdim  { "sbbS",		{ Ev, Gv } },
649218822Sdim  { "sbbB",		{ Gb, Eb } },
650218822Sdim  { "sbbS",		{ Gv, Ev } },
651218822Sdim  { "sbbB",		{ AL, Ib } },
652218822Sdim  { "sbbS",		{ eAX, Iv } },
653218822Sdim  { "push{T|}",		{ ds } },
654218822Sdim  { "pop{T|}",		{ ds } },
65577298Sobrien  /* 20 */
656218822Sdim  { "andB",		{ Eb, Gb } },
657218822Sdim  { "andS",		{ Ev, Gv } },
658218822Sdim  { "andB",		{ Gb, Eb } },
659218822Sdim  { "andS",		{ Gv, Ev } },
660218822Sdim  { "andB",		{ AL, Ib } },
661218822Sdim  { "andS",		{ eAX, Iv } },
662218822Sdim  { "(bad)",		{ XX } },	/* SEG ES prefix */
663218822Sdim  { "daa{|}",		{ XX } },
66477298Sobrien  /* 28 */
665218822Sdim  { "subB",		{ Eb, Gb } },
666218822Sdim  { "subS",		{ Ev, Gv } },
667218822Sdim  { "subB",		{ Gb, Eb } },
668218822Sdim  { "subS",		{ Gv, Ev } },
669218822Sdim  { "subB",		{ AL, Ib } },
670218822Sdim  { "subS",		{ eAX, Iv } },
671218822Sdim  { "(bad)",		{ XX } },	/* SEG CS prefix */
672218822Sdim  { "das{|}",		{ XX } },
67377298Sobrien  /* 30 */
674218822Sdim  { "xorB",		{ Eb, Gb } },
675218822Sdim  { "xorS",		{ Ev, Gv } },
676218822Sdim  { "xorB",		{ Gb, Eb } },
677218822Sdim  { "xorS",		{ Gv, Ev } },
678218822Sdim  { "xorB",		{ AL, Ib } },
679218822Sdim  { "xorS",		{ eAX, Iv } },
680218822Sdim  { "(bad)",		{ XX } },	/* SEG SS prefix */
681218822Sdim  { "aaa{|}",		{ XX } },
68277298Sobrien  /* 38 */
683218822Sdim  { "cmpB",		{ Eb, Gb } },
684218822Sdim  { "cmpS",		{ Ev, Gv } },
685218822Sdim  { "cmpB",		{ Gb, Eb } },
686218822Sdim  { "cmpS",		{ Gv, Ev } },
687218822Sdim  { "cmpB",		{ AL, Ib } },
688218822Sdim  { "cmpS",		{ eAX, Iv } },
689218822Sdim  { "(bad)",		{ XX } },	/* SEG DS prefix */
690218822Sdim  { "aas{|}",		{ XX } },
69177298Sobrien  /* 40 */
692218822Sdim  { "inc{S|}",		{ RMeAX } },
693218822Sdim  { "inc{S|}",		{ RMeCX } },
694218822Sdim  { "inc{S|}",		{ RMeDX } },
695218822Sdim  { "inc{S|}",		{ RMeBX } },
696218822Sdim  { "inc{S|}",		{ RMeSP } },
697218822Sdim  { "inc{S|}",		{ RMeBP } },
698218822Sdim  { "inc{S|}",		{ RMeSI } },
699218822Sdim  { "inc{S|}",		{ RMeDI } },
70077298Sobrien  /* 48 */
701218822Sdim  { "dec{S|}",		{ RMeAX } },
702218822Sdim  { "dec{S|}",		{ RMeCX } },
703218822Sdim  { "dec{S|}",		{ RMeDX } },
704218822Sdim  { "dec{S|}",		{ RMeBX } },
705218822Sdim  { "dec{S|}",		{ RMeSP } },
706218822Sdim  { "dec{S|}",		{ RMeBP } },
707218822Sdim  { "dec{S|}",		{ RMeSI } },
708218822Sdim  { "dec{S|}",		{ RMeDI } },
70977298Sobrien  /* 50 */
710218822Sdim  { "pushV",		{ RMrAX } },
711218822Sdim  { "pushV",		{ RMrCX } },
712218822Sdim  { "pushV",		{ RMrDX } },
713218822Sdim  { "pushV",		{ RMrBX } },
714218822Sdim  { "pushV",		{ RMrSP } },
715218822Sdim  { "pushV",		{ RMrBP } },
716218822Sdim  { "pushV",		{ RMrSI } },
717218822Sdim  { "pushV",		{ RMrDI } },
71877298Sobrien  /* 58 */
719218822Sdim  { "popV",		{ RMrAX } },
720218822Sdim  { "popV",		{ RMrCX } },
721218822Sdim  { "popV",		{ RMrDX } },
722218822Sdim  { "popV",		{ RMrBX } },
723218822Sdim  { "popV",		{ RMrSP } },
724218822Sdim  { "popV",		{ RMrBP } },
725218822Sdim  { "popV",		{ RMrSI } },
726218822Sdim  { "popV",		{ RMrDI } },
72777298Sobrien  /* 60 */
72885815Sobrien  { X86_64_0 },
729218822Sdim  { X86_64_1 },
730218822Sdim  { X86_64_2 },
731218822Sdim  { X86_64_3 },
732218822Sdim  { "(bad)",		{ XX } },	/* seg fs */
733218822Sdim  { "(bad)",		{ XX } },	/* seg gs */
734218822Sdim  { "(bad)",		{ XX } },	/* op size prefix */
735218822Sdim  { "(bad)",		{ XX } },	/* adr size prefix */
73677298Sobrien  /* 68 */
737218822Sdim  { "pushT",		{ Iq } },
738218822Sdim  { "imulS",		{ Gv, Ev, Iv } },
739218822Sdim  { "pushT",		{ sIb } },
740218822Sdim  { "imulS",		{ Gv, Ev, sIb } },
741218822Sdim  { "ins{b||b|}",	{ Ybr, indirDX } },
742218822Sdim  { "ins{R||G|}",	{ Yzr, indirDX } },
743218822Sdim  { "outs{b||b|}",	{ indirDXr, Xb } },
744218822Sdim  { "outs{R||G|}",	{ indirDXr, Xz } },
74577298Sobrien  /* 70 */
746218822Sdim  { "joH",		{ Jb, XX, cond_jump_flag } },
747218822Sdim  { "jnoH",		{ Jb, XX, cond_jump_flag } },
748218822Sdim  { "jbH",		{ Jb, XX, cond_jump_flag } },
749218822Sdim  { "jaeH",		{ Jb, XX, cond_jump_flag } },
750218822Sdim  { "jeH",		{ Jb, XX, cond_jump_flag } },
751218822Sdim  { "jneH",		{ Jb, XX, cond_jump_flag } },
752218822Sdim  { "jbeH",		{ Jb, XX, cond_jump_flag } },
753218822Sdim  { "jaH",		{ Jb, XX, cond_jump_flag } },
75477298Sobrien  /* 78 */
755218822Sdim  { "jsH",		{ Jb, XX, cond_jump_flag } },
756218822Sdim  { "jnsH",		{ Jb, XX, cond_jump_flag } },
757218822Sdim  { "jpH",		{ Jb, XX, cond_jump_flag } },
758218822Sdim  { "jnpH",		{ Jb, XX, cond_jump_flag } },
759218822Sdim  { "jlH",		{ Jb, XX, cond_jump_flag } },
760218822Sdim  { "jgeH",		{ Jb, XX, cond_jump_flag } },
761218822Sdim  { "jleH",		{ Jb, XX, cond_jump_flag } },
762218822Sdim  { "jgH",		{ Jb, XX, cond_jump_flag } },
76377298Sobrien  /* 80 */
76477298Sobrien  { GRP1b },
76577298Sobrien  { GRP1S },
766218822Sdim  { "(bad)",		{ XX } },
76777298Sobrien  { GRP1Ss },
768218822Sdim  { "testB",		{ Eb, Gb } },
769218822Sdim  { "testS",		{ Ev, Gv } },
770218822Sdim  { "xchgB",		{ Eb, Gb } },
771218822Sdim  { "xchgS",		{ Ev, Gv } },
77277298Sobrien  /* 88 */
773218822Sdim  { "movB",		{ Eb, Gb } },
774218822Sdim  { "movS",		{ Ev, Gv } },
775218822Sdim  { "movB",		{ Gb, Eb } },
776218822Sdim  { "movS",		{ Gv, Ev } },
777218822Sdim  { "movD",		{ Sv, Sw } },
778218822Sdim  { "leaS",		{ Gv, M } },
779218822Sdim  { "movD",		{ Sw, Sv } },
780218822Sdim  { GRP1a },
78177298Sobrien  /* 90 */
782218822Sdim  { PREGRP38 },
783218822Sdim  { "xchgS",		{ RMeCX, eAX } },
784218822Sdim  { "xchgS",		{ RMeDX, eAX } },
785218822Sdim  { "xchgS",		{ RMeBX, eAX } },
786218822Sdim  { "xchgS",		{ RMeSP, eAX } },
787218822Sdim  { "xchgS",		{ RMeBP, eAX } },
788218822Sdim  { "xchgS",		{ RMeSI, eAX } },
789218822Sdim  { "xchgS",		{ RMeDI, eAX } },
79077298Sobrien  /* 98 */
791218822Sdim  { "cW{t||t|}R",	{ XX } },
792218822Sdim  { "cR{t||t|}O",	{ XX } },
793218822Sdim  { "Jcall{T|}",	{ Ap } },
794218822Sdim  { "(bad)",		{ XX } },	/* fwait */
795218822Sdim  { "pushfT",		{ XX } },
796218822Sdim  { "popfT",		{ XX } },
797218822Sdim  { "sahf{|}",		{ XX } },
798218822Sdim  { "lahf{|}",		{ XX } },
79977298Sobrien  /* a0 */
800218822Sdim  { "movB",		{ AL, Ob } },
801218822Sdim  { "movS",		{ eAX, Ov } },
802218822Sdim  { "movB",		{ Ob, AL } },
803218822Sdim  { "movS",		{ Ov, eAX } },
804218822Sdim  { "movs{b||b|}",	{ Ybr, Xb } },
805218822Sdim  { "movs{R||R|}",	{ Yvr, Xv } },
806218822Sdim  { "cmps{b||b|}",	{ Xb, Yb } },
807218822Sdim  { "cmps{R||R|}",	{ Xv, Yv } },
80877298Sobrien  /* a8 */
809218822Sdim  { "testB",		{ AL, Ib } },
810218822Sdim  { "testS",		{ eAX, Iv } },
811218822Sdim  { "stosB",		{ Ybr, AL } },
812218822Sdim  { "stosS",		{ Yvr, eAX } },
813218822Sdim  { "lodsB",		{ ALr, Xb } },
814218822Sdim  { "lodsS",		{ eAXr, Xv } },
815218822Sdim  { "scasB",		{ AL, Yb } },
816218822Sdim  { "scasS",		{ eAX, Yv } },
81777298Sobrien  /* b0 */
818218822Sdim  { "movB",		{ RMAL, Ib } },
819218822Sdim  { "movB",		{ RMCL, Ib } },
820218822Sdim  { "movB",		{ RMDL, Ib } },
821218822Sdim  { "movB",		{ RMBL, Ib } },
822218822Sdim  { "movB",		{ RMAH, Ib } },
823218822Sdim  { "movB",		{ RMCH, Ib } },
824218822Sdim  { "movB",		{ RMDH, Ib } },
825218822Sdim  { "movB",		{ RMBH, Ib } },
82677298Sobrien  /* b8 */
827218822Sdim  { "movS",		{ RMeAX, Iv64 } },
828218822Sdim  { "movS",		{ RMeCX, Iv64 } },
829218822Sdim  { "movS",		{ RMeDX, Iv64 } },
830218822Sdim  { "movS",		{ RMeBX, Iv64 } },
831218822Sdim  { "movS",		{ RMeSP, Iv64 } },
832218822Sdim  { "movS",		{ RMeBP, Iv64 } },
833218822Sdim  { "movS",		{ RMeSI, Iv64 } },
834218822Sdim  { "movS",		{ RMeDI, Iv64 } },
83577298Sobrien  /* c0 */
83677298Sobrien  { GRP2b },
83777298Sobrien  { GRP2S },
838218822Sdim  { "retT",		{ Iw } },
839218822Sdim  { "retT",		{ XX } },
840218822Sdim  { "les{S|}",		{ Gv, Mp } },
841218822Sdim  { "ldsS",		{ Gv, Mp } },
842218822Sdim  { GRP11_C6 },
843218822Sdim  { GRP11_C7 },
84477298Sobrien  /* c8 */
845218822Sdim  { "enterT",		{ Iw, Ib } },
846218822Sdim  { "leaveT",		{ XX } },
847218822Sdim  { "lretP",		{ Iw } },
848218822Sdim  { "lretP",		{ XX } },
849218822Sdim  { "int3",		{ XX } },
850218822Sdim  { "int",		{ Ib } },
851218822Sdim  { "into{|}",		{ XX } },
852218822Sdim  { "iretP",		{ XX } },
85377298Sobrien  /* d0 */
85477298Sobrien  { GRP2b_one },
85577298Sobrien  { GRP2S_one },
85677298Sobrien  { GRP2b_cl },
85777298Sobrien  { GRP2S_cl },
858218822Sdim  { "aam{|}",		{ sIb } },
859218822Sdim  { "aad{|}",		{ sIb } },
860218822Sdim  { "(bad)",		{ XX } },
861218822Sdim  { "xlat",		{ DSBX } },
86277298Sobrien  /* d8 */
86377298Sobrien  { FLOAT },
86477298Sobrien  { FLOAT },
86577298Sobrien  { FLOAT },
86677298Sobrien  { FLOAT },
86777298Sobrien  { FLOAT },
86877298Sobrien  { FLOAT },
86977298Sobrien  { FLOAT },
87077298Sobrien  { FLOAT },
87177298Sobrien  /* e0 */
872218822Sdim  { "loopneFH",		{ Jb, XX, loop_jcxz_flag } },
873218822Sdim  { "loopeFH",		{ Jb, XX, loop_jcxz_flag } },
874218822Sdim  { "loopFH",		{ Jb, XX, loop_jcxz_flag } },
875218822Sdim  { "jEcxzH",		{ Jb, XX, loop_jcxz_flag } },
876218822Sdim  { "inB",		{ AL, Ib } },
877218822Sdim  { "inG",		{ zAX, Ib } },
878218822Sdim  { "outB",		{ Ib, AL } },
879218822Sdim  { "outG",		{ Ib, zAX } },
88077298Sobrien  /* e8 */
881218822Sdim  { "callT",		{ Jv } },
882218822Sdim  { "jmpT",		{ Jv } },
883218822Sdim  { "Jjmp{T|}",		{ Ap } },
884218822Sdim  { "jmp",		{ Jb } },
885218822Sdim  { "inB",		{ AL, indirDX } },
886218822Sdim  { "inG",		{ zAX, indirDX } },
887218822Sdim  { "outB",		{ indirDX, AL } },
888218822Sdim  { "outG",		{ indirDX, zAX } },
88977298Sobrien  /* f0 */
890218822Sdim  { "(bad)",		{ XX } },	/* lock prefix */
891218822Sdim  { "icebp",		{ XX } },
892218822Sdim  { "(bad)",		{ XX } },	/* repne */
893218822Sdim  { "(bad)",		{ XX } },	/* repz */
894218822Sdim  { "hlt",		{ XX } },
895218822Sdim  { "cmc",		{ XX } },
89677298Sobrien  { GRP3b },
89777298Sobrien  { GRP3S },
89877298Sobrien  /* f8 */
899218822Sdim  { "clc",		{ XX } },
900218822Sdim  { "stc",		{ XX } },
901218822Sdim  { "cli",		{ XX } },
902218822Sdim  { "sti",		{ XX } },
903218822Sdim  { "cld",		{ XX } },
904218822Sdim  { "std",		{ XX } },
90577298Sobrien  { GRP4 },
90677298Sobrien  { GRP5 },
90777298Sobrien};
90877298Sobrien
90985815Sobrienstatic const struct dis386 dis386_twobyte[] = {
91077298Sobrien  /* 00 */
91133965Sjdp  { GRP6 },
91233965Sjdp  { GRP7 },
913218822Sdim  { "larS",		{ Gv, Ew } },
914218822Sdim  { "lslS",		{ Gv, Ew } },
915218822Sdim  { "(bad)",		{ XX } },
916218822Sdim  { "syscall",		{ XX } },
917218822Sdim  { "clts",		{ XX } },
918218822Sdim  { "sysretP",		{ XX } },
91933965Sjdp  /* 08 */
920218822Sdim  { "invd",		{ XX } },
921218822Sdim  { "wbinvd",		{ XX } },
922218822Sdim  { "(bad)",		{ XX } },
923218822Sdim  { "ud2a",		{ XX } },
924218822Sdim  { "(bad)",		{ XX } },
92560484Sobrien  { GRPAMD },
926218822Sdim  { "femms",		{ XX } },
927218822Sdim  { "",			{ MX, EM, OPSUF } }, /* See OP_3DNowSuffix.  */
92833965Sjdp  /* 10 */
92960484Sobrien  { PREGRP8 },
93060484Sobrien  { PREGRP9 },
931130561Sobrien  { PREGRP30 },
932218822Sdim  { "movlpX",		{ EXq, XM, { SIMD_Fixup, 'h' } } },
933218822Sdim  { "unpcklpX",		{ XM, EXq } },
934218822Sdim  { "unpckhpX",		{ XM, EXq } },
935130561Sobrien  { PREGRP31 },
936218822Sdim  { "movhpX",		{ EXq, XM, { SIMD_Fixup, 'l' } } },
93733965Sjdp  /* 18 */
938218822Sdim  { GRP16 },
939218822Sdim  { "(bad)",		{ XX } },
940218822Sdim  { "(bad)",		{ XX } },
941218822Sdim  { "(bad)",		{ XX } },
942218822Sdim  { "(bad)",		{ XX } },
943218822Sdim  { "(bad)",		{ XX } },
944218822Sdim  { "(bad)",		{ XX } },
945218822Sdim  { "nopQ",		{ Ev } },
94633965Sjdp  /* 20 */
947218822Sdim  { "movZ",		{ Rm, Cm } },
948218822Sdim  { "movZ",		{ Rm, Dm } },
949218822Sdim  { "movZ",		{ Cm, Rm } },
950218822Sdim  { "movZ",		{ Dm, Rm } },
951218822Sdim  { "movL",		{ Rd, Td } },
952218822Sdim  { "(bad)",		{ XX } },
953218822Sdim  { "movL",		{ Td, Rd } },
954218822Sdim  { "(bad)",		{ XX } },
95533965Sjdp  /* 28 */
956218822Sdim  { "movapX",		{ XM, EXx } },
957218822Sdim  { "movapX",		{ EXx,  XM } },
95860484Sobrien  { PREGRP2 },
959218822Sdim  { PREGRP33 },
96060484Sobrien  { PREGRP4 },
96160484Sobrien  { PREGRP3 },
962218822Sdim  { PREGRP93 },
963218822Sdim  { PREGRP94 },
96433965Sjdp  /* 30 */
965218822Sdim  { "wrmsr",		{ XX } },
966218822Sdim  { "rdtsc",		{ XX } },
967218822Sdim  { "rdmsr",		{ XX } },
968218822Sdim  { "rdpmc",		{ XX } },
969218822Sdim  { "sysenter",		{ XX } },
970218822Sdim  { "sysexit",		{ XX } },
971218822Sdim  { "(bad)",		{ XX } },
972218822Sdim  { "(bad)",		{ XX } },
97333965Sjdp  /* 38 */
974218822Sdim  { THREE_BYTE_0 },
975218822Sdim  { "(bad)",		{ XX } },
976218822Sdim  { THREE_BYTE_1 },
977218822Sdim  { "(bad)",		{ XX } },
978218822Sdim  { "(bad)",		{ XX } },
979218822Sdim  { "(bad)",		{ XX } },
980218822Sdim  { "(bad)",		{ XX } },
981218822Sdim  { "(bad)",		{ XX } },
98233965Sjdp  /* 40 */
983218822Sdim  { "cmovo",		{ Gv, Ev } },
984218822Sdim  { "cmovno",		{ Gv, Ev } },
985218822Sdim  { "cmovb",		{ Gv, Ev } },
986218822Sdim  { "cmovae",		{ Gv, Ev } },
987218822Sdim  { "cmove",		{ Gv, Ev } },
988218822Sdim  { "cmovne",		{ Gv, Ev } },
989218822Sdim  { "cmovbe",		{ Gv, Ev } },
990218822Sdim  { "cmova",		{ Gv, Ev } },
99133965Sjdp  /* 48 */
992218822Sdim  { "cmovs",		{ Gv, Ev } },
993218822Sdim  { "cmovns",		{ Gv, Ev } },
994218822Sdim  { "cmovp",		{ Gv, Ev } },
995218822Sdim  { "cmovnp",		{ Gv, Ev } },
996218822Sdim  { "cmovl",		{ Gv, Ev } },
997218822Sdim  { "cmovge",		{ Gv, Ev } },
998218822Sdim  { "cmovle",		{ Gv, Ev } },
999218822Sdim  { "cmovg",		{ Gv, Ev } },
100033965Sjdp  /* 50 */
1001218822Sdim  { "movmskpX",		{ Gdq, XS } },
100260484Sobrien  { PREGRP13 },
100360484Sobrien  { PREGRP12 },
100460484Sobrien  { PREGRP11 },
1005218822Sdim  { "andpX",		{ XM, EXx } },
1006218822Sdim  { "andnpX",		{ XM, EXx } },
1007218822Sdim  { "orpX",		{ XM, EXx } },
1008218822Sdim  { "xorpX",		{ XM, EXx } },
100933965Sjdp  /* 58 */
101060484Sobrien  { PREGRP0 },
101160484Sobrien  { PREGRP10 },
101277298Sobrien  { PREGRP17 },
101377298Sobrien  { PREGRP16 },
101460484Sobrien  { PREGRP14 },
101560484Sobrien  { PREGRP7 },
101660484Sobrien  { PREGRP5 },
101760484Sobrien  { PREGRP6 },
101833965Sjdp  /* 60 */
1019218822Sdim  { PREGRP95 },
1020218822Sdim  { PREGRP96 },
1021218822Sdim  { PREGRP97 },
1022218822Sdim  { "packsswb",		{ MX, EM } },
1023218822Sdim  { "pcmpgtb",		{ MX, EM } },
1024218822Sdim  { "pcmpgtw",		{ MX, EM } },
1025218822Sdim  { "pcmpgtd",		{ MX, EM } },
1026218822Sdim  { "packuswb",		{ MX, EM } },
102733965Sjdp  /* 68 */
1028218822Sdim  { "punpckhbw",	{ MX, EM } },
1029218822Sdim  { "punpckhwd",	{ MX, EM } },
1030218822Sdim  { "punpckhdq",	{ MX, EM } },
1031218822Sdim  { "packssdw",		{ MX, EM } },
103277298Sobrien  { PREGRP26 },
103377298Sobrien  { PREGRP24 },
1034218822Sdim  { "movd",		{ MX, Edq } },
103577298Sobrien  { PREGRP19 },
103633965Sjdp  /* 70 */
103777298Sobrien  { PREGRP22 },
103833965Sjdp  { GRP12 },
1039218822Sdim  { GRP13 },
1040218822Sdim  { GRP14 },
1041218822Sdim  { "pcmpeqb",		{ MX, EM } },
1042218822Sdim  { "pcmpeqw",		{ MX, EM } },
1043218822Sdim  { "pcmpeqd",		{ MX, EM } },
1044218822Sdim  { "emms",		{ XX } },
104533965Sjdp  /* 78 */
1046218822Sdim  { PREGRP34 },
1047218822Sdim  { PREGRP35 },
1048218822Sdim  { "(bad)",		{ XX } },
1049218822Sdim  { "(bad)",		{ XX } },
1050130561Sobrien  { PREGRP28 },
1051130561Sobrien  { PREGRP29 },
105277298Sobrien  { PREGRP23 },
105377298Sobrien  { PREGRP20 },
105433965Sjdp  /* 80 */
1055218822Sdim  { "joH",		{ Jv, XX, cond_jump_flag } },
1056218822Sdim  { "jnoH",		{ Jv, XX, cond_jump_flag } },
1057218822Sdim  { "jbH",		{ Jv, XX, cond_jump_flag } },
1058218822Sdim  { "jaeH",		{ Jv, XX, cond_jump_flag } },
1059218822Sdim  { "jeH",		{ Jv, XX, cond_jump_flag } },
1060218822Sdim  { "jneH",		{ Jv, XX, cond_jump_flag } },
1061218822Sdim  { "jbeH",		{ Jv, XX, cond_jump_flag } },
1062218822Sdim  { "jaH",		{ Jv, XX, cond_jump_flag } },
106333965Sjdp  /* 88 */
1064218822Sdim  { "jsH",		{ Jv, XX, cond_jump_flag } },
1065218822Sdim  { "jnsH",		{ Jv, XX, cond_jump_flag } },
1066218822Sdim  { "jpH",		{ Jv, XX, cond_jump_flag } },
1067218822Sdim  { "jnpH",		{ Jv, XX, cond_jump_flag } },
1068218822Sdim  { "jlH",		{ Jv, XX, cond_jump_flag } },
1069218822Sdim  { "jgeH",		{ Jv, XX, cond_jump_flag } },
1070218822Sdim  { "jleH",		{ Jv, XX, cond_jump_flag } },
1071218822Sdim  { "jgH",		{ Jv, XX, cond_jump_flag } },
107233965Sjdp  /* 90 */
1073218822Sdim  { "seto",		{ Eb } },
1074218822Sdim  { "setno",		{ Eb } },
1075218822Sdim  { "setb",		{ Eb } },
1076218822Sdim  { "setae",		{ Eb } },
1077218822Sdim  { "sete",		{ Eb } },
1078218822Sdim  { "setne",		{ Eb } },
1079218822Sdim  { "setbe",		{ Eb } },
1080218822Sdim  { "seta",		{ Eb } },
108133965Sjdp  /* 98 */
1082218822Sdim  { "sets",		{ Eb } },
1083218822Sdim  { "setns",		{ Eb } },
1084218822Sdim  { "setp",		{ Eb } },
1085218822Sdim  { "setnp",		{ Eb } },
1086218822Sdim  { "setl",		{ Eb } },
1087218822Sdim  { "setge",		{ Eb } },
1088218822Sdim  { "setle",		{ Eb } },
1089218822Sdim  { "setg",		{ Eb } },
109033965Sjdp  /* a0 */
1091218822Sdim  { "pushT",		{ fs } },
1092218822Sdim  { "popT",		{ fs } },
1093218822Sdim  { "cpuid",		{ XX } },
1094218822Sdim  { "btS",		{ Ev, Gv } },
1095218822Sdim  { "shldS",		{ Ev, Gv, Ib } },
1096218822Sdim  { "shldS",		{ Ev, Gv, CL } },
1097218822Sdim  { GRPPADLCK2 },
1098218822Sdim  { GRPPADLCK1 },
109933965Sjdp  /* a8 */
1100218822Sdim  { "pushT",		{ gs } },
1101218822Sdim  { "popT",		{ gs } },
1102218822Sdim  { "rsm",		{ XX } },
1103218822Sdim  { "btsS",		{ Ev, Gv } },
1104218822Sdim  { "shrdS",		{ Ev, Gv, Ib } },
1105218822Sdim  { "shrdS",		{ Ev, Gv, CL } },
1106218822Sdim  { GRP15 },
1107218822Sdim  { "imulS",		{ Gv, Ev } },
110833965Sjdp  /* b0 */
1109218822Sdim  { "cmpxchgB",		{ Eb, Gb } },
1110218822Sdim  { "cmpxchgS",		{ Ev, Gv } },
1111218822Sdim  { "lssS",		{ Gv, Mp } },
1112218822Sdim  { "btrS",		{ Ev, Gv } },
1113218822Sdim  { "lfsS",		{ Gv, Mp } },
1114218822Sdim  { "lgsS",		{ Gv, Mp } },
1115218822Sdim  { "movz{bR|x|bR|x}",	{ Gv, Eb } },
1116218822Sdim  { "movz{wR|x|wR|x}",	{ Gv, Ew } }, /* yes, there really is movzww ! */
111733965Sjdp  /* b8 */
1118218822Sdim  { PREGRP37 },
1119218822Sdim  { "ud2b",		{ XX } },
112033965Sjdp  { GRP8 },
1121218822Sdim  { "btcS",		{ Ev, Gv } },
1122218822Sdim  { "bsfS",		{ Gv, Ev } },
1123218822Sdim  { PREGRP36 },
1124218822Sdim  { "movs{bR|x|bR|x}",	{ Gv, Eb } },
1125218822Sdim  { "movs{wR|x|wR|x}",	{ Gv, Ew } }, /* yes, there really is movsww ! */
112633965Sjdp  /* c0 */
1127218822Sdim  { "xaddB",		{ Eb, Gb } },
1128218822Sdim  { "xaddS",		{ Ev, Gv } },
112960484Sobrien  { PREGRP1 },
1130218822Sdim  { "movntiS",		{ Ev, Gv } },
1131218822Sdim  { "pinsrw",		{ MX, Edqw, Ib } },
1132218822Sdim  { "pextrw",		{ Gdq, MS, Ib } },
1133218822Sdim  { "shufpX",		{ XM, EXx, Ib } },
113460484Sobrien  { GRP9 },
113533965Sjdp  /* c8 */
1136218822Sdim  { "bswap",		{ RMeAX } },
1137218822Sdim  { "bswap",		{ RMeCX } },
1138218822Sdim  { "bswap",		{ RMeDX } },
1139218822Sdim  { "bswap",		{ RMeBX } },
1140218822Sdim  { "bswap",		{ RMeSP } },
1141218822Sdim  { "bswap",		{ RMeBP } },
1142218822Sdim  { "bswap",		{ RMeSI } },
1143218822Sdim  { "bswap",		{ RMeDI } },
114433965Sjdp  /* d0 */
1145130561Sobrien  { PREGRP27 },
1146218822Sdim  { "psrlw",		{ MX, EM } },
1147218822Sdim  { "psrld",		{ MX, EM } },
1148218822Sdim  { "psrlq",		{ MX, EM } },
1149218822Sdim  { "paddq",		{ MX, EM } },
1150218822Sdim  { "pmullw",		{ MX, EM } },
115177298Sobrien  { PREGRP21 },
1152218822Sdim  { "pmovmskb",		{ Gdq, MS } },
115333965Sjdp  /* d8 */
1154218822Sdim  { "psubusb",		{ MX, EM } },
1155218822Sdim  { "psubusw",		{ MX, EM } },
1156218822Sdim  { "pminub",		{ MX, EM } },
1157218822Sdim  { "pand",		{ MX, EM } },
1158218822Sdim  { "paddusb",		{ MX, EM } },
1159218822Sdim  { "paddusw",		{ MX, EM } },
1160218822Sdim  { "pmaxub",		{ MX, EM } },
1161218822Sdim  { "pandn",		{ MX, EM } },
116233965Sjdp  /* e0 */
1163218822Sdim  { "pavgb",		{ MX, EM } },
1164218822Sdim  { "psraw",		{ MX, EM } },
1165218822Sdim  { "psrad",		{ MX, EM } },
1166218822Sdim  { "pavgw",		{ MX, EM } },
1167218822Sdim  { "pmulhuw",		{ MX, EM } },
1168218822Sdim  { "pmulhw",		{ MX, EM } },
116977298Sobrien  { PREGRP15 },
117077298Sobrien  { PREGRP25 },
117133965Sjdp  /* e8 */
1172218822Sdim  { "psubsb",		{ MX, EM } },
1173218822Sdim  { "psubsw",		{ MX, EM } },
1174218822Sdim  { "pminsw",		{ MX, EM } },
1175218822Sdim  { "por",		{ MX, EM } },
1176218822Sdim  { "paddsb",		{ MX, EM } },
1177218822Sdim  { "paddsw",		{ MX, EM } },
1178218822Sdim  { "pmaxsw",		{ MX, EM } },
1179218822Sdim  { "pxor",		{ MX, EM } },
118033965Sjdp  /* f0 */
1181130561Sobrien  { PREGRP32 },
1182218822Sdim  { "psllw",		{ MX, EM } },
1183218822Sdim  { "pslld",		{ MX, EM } },
1184218822Sdim  { "psllq",		{ MX, EM } },
1185218822Sdim  { "pmuludq",		{ MX, EM } },
1186218822Sdim  { "pmaddwd",		{ MX, EM } },
1187218822Sdim  { "psadbw",		{ MX, EM } },
118877298Sobrien  { PREGRP18 },
118933965Sjdp  /* f8 */
1190218822Sdim  { "psubb",		{ MX, EM } },
1191218822Sdim  { "psubw",		{ MX, EM } },
1192218822Sdim  { "psubd",		{ MX, EM } },
1193218822Sdim  { "psubq",		{ MX, EM } },
1194218822Sdim  { "paddb",		{ MX, EM } },
1195218822Sdim  { "paddw",		{ MX, EM } },
1196218822Sdim  { "paddd",		{ MX, EM } },
1197218822Sdim  { "(bad)",		{ XX } },
119833965Sjdp};
119933965Sjdp
120033965Sjdpstatic const unsigned char onebyte_has_modrm[256] = {
120160484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
120260484Sobrien  /*       -------------------------------        */
120360484Sobrien  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
120460484Sobrien  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
120560484Sobrien  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
120660484Sobrien  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
120760484Sobrien  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
120860484Sobrien  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
120960484Sobrien  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
121060484Sobrien  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
121160484Sobrien  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
121260484Sobrien  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
121360484Sobrien  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
121460484Sobrien  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
121560484Sobrien  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
121660484Sobrien  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
121760484Sobrien  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
121860484Sobrien  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
121960484Sobrien  /*       -------------------------------        */
122060484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
122133965Sjdp};
122233965Sjdp
122333965Sjdpstatic const unsigned char twobyte_has_modrm[256] = {
122460484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
122560484Sobrien  /*       -------------------------------        */
122660484Sobrien  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1227218822Sdim  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
122878828Sobrien  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1229218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
123033965Sjdp  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
123178828Sobrien  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
123278828Sobrien  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1233218822Sdim  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
123433965Sjdp  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
123533965Sjdp  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1236218822Sdim  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1237218822Sdim  /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
123833965Sjdp  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1239130561Sobrien  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
124078828Sobrien  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1241130561Sobrien  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
124260484Sobrien  /*       -------------------------------        */
124360484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
124433965Sjdp};
124533965Sjdp
1246218822Sdimstatic const unsigned char twobyte_uses_DATA_prefix[256] = {
124760484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
124860484Sobrien  /*       -------------------------------        */
124960484Sobrien  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1250130561Sobrien  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1251218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1252218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
125360484Sobrien  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
125477298Sobrien  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
125577298Sobrien  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1256218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
125760484Sobrien  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
125860484Sobrien  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
125960484Sobrien  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
126060484Sobrien  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
126160484Sobrien  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1262130561Sobrien  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
126377298Sobrien  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1264130561Sobrien  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
126560484Sobrien  /*       -------------------------------        */
126660484Sobrien  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
126760484Sobrien};
126860484Sobrien
1269218822Sdimstatic const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1270218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1271218822Sdim  /*       -------------------------------        */
1272218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1273218822Sdim  /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1274218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1275218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1276218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1277218822Sdim  /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1278218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1279218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1280218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1281218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1282218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1283218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1284218822Sdim  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1285218822Sdim  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1286218822Sdim  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1287218822Sdim  /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1288218822Sdim  /*       -------------------------------        */
1289218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1290218822Sdim};
1291218822Sdim
1292218822Sdimstatic const unsigned char twobyte_uses_REPZ_prefix[256] = {
1293218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1294218822Sdim  /*       -------------------------------        */
1295218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1296218822Sdim  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1297218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1298218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1299218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1300218822Sdim  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1301218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1302218822Sdim  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1303218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1304218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1305323489Srlibby  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* af */
1306218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1307218822Sdim  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1308218822Sdim  /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1309218822Sdim  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1310218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1311218822Sdim  /*       -------------------------------        */
1312218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1313218822Sdim};
1314218822Sdim
1315218822Sdim/* This is used to determine if opcode 0f 38 XX uses DATA prefix.  */
1316218822Sdimstatic const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1317218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1318218822Sdim  /*       -------------------------------        */
1319218822Sdim  /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1320218822Sdim  /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1321218822Sdim  /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1322218822Sdim  /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1323218822Sdim  /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1324218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1325218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1326218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1327218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1328218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1329218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1330218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1331218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1332247012Sjmg  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
1333218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1334218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1335218822Sdim  /*       -------------------------------        */
1336218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1337218822Sdim};
1338218822Sdim
1339218822Sdim/* This is used to determine if opcode 0f 38 XX uses REPNZ prefix.  */
1340218822Sdimstatic const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1341218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1342218822Sdim  /*       -------------------------------        */
1343218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1344218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1345218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1346218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1347218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1348218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1349218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1350218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1351218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1352218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1353218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1354218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1355218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1356218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1357218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1358218822Sdim  /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1359218822Sdim  /*       -------------------------------        */
1360218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1361218822Sdim};
1362218822Sdim
1363218822Sdim/* This is used to determine if opcode 0f 38 XX uses REPZ prefix.  */
1364218822Sdimstatic const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1365218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1366218822Sdim  /*       -------------------------------        */
1367218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1368218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1369218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1370218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1371218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1372218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1373218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1374218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1375218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1376218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1377218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1378218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1379218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1380218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1381218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1382218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1383218822Sdim  /*       -------------------------------        */
1384218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1385218822Sdim};
1386218822Sdim
1387218822Sdim/* This is used to determine if opcode 0f 3a XX uses DATA prefix.  */
1388218822Sdimstatic const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1389218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1390218822Sdim  /*       -------------------------------        */
1391218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1392218822Sdim  /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1393218822Sdim  /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1394218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1395247012Sjmg  /* 40 */ 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1396218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1397218822Sdim  /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1398218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1399218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1400218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1401218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1402218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1403218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1404247012Sjmg  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* df */
1405218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1406218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1407218822Sdim  /*       -------------------------------        */
1408218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1409218822Sdim};
1410218822Sdim
1411218822Sdim/* This is used to determine if opcode 0f 3a XX uses REPNZ prefix.  */
1412218822Sdimstatic const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1413218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1414218822Sdim  /*       -------------------------------        */
1415218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1416218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1417218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1418218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1419218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1420218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1421218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1422218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1423218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1424218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1425218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1426218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1427218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1428218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1429218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1430218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1431218822Sdim  /*       -------------------------------        */
1432218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1433218822Sdim};
1434218822Sdim
1435218822Sdim/* This is used to determine if opcode 0f 3a XX uses REPZ prefix.  */
1436218822Sdimstatic const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1437218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1438218822Sdim  /*       -------------------------------        */
1439218822Sdim  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1440218822Sdim  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1441218822Sdim  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1442218822Sdim  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1443218822Sdim  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1444218822Sdim  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1445218822Sdim  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1446218822Sdim  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1447218822Sdim  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1448218822Sdim  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1449218822Sdim  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1450218822Sdim  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1451218822Sdim  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1452218822Sdim  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1453218822Sdim  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1454218822Sdim  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1455218822Sdim  /*       -------------------------------        */
1456218822Sdim  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1457218822Sdim};
1458218822Sdim
145933965Sjdpstatic char obuf[100];
146033965Sjdpstatic char *obufp;
146133965Sjdpstatic char scratchbuf[100];
146233965Sjdpstatic unsigned char *start_codep;
146360484Sobrienstatic unsigned char *insn_codep;
146433965Sjdpstatic unsigned char *codep;
146533965Sjdpstatic disassemble_info *the_info;
1466218822Sdimstatic struct
1467218822Sdim  {
1468218822Sdim    int mod;
1469218822Sdim    int reg;
1470218822Sdim    int rm;
1471218822Sdim  }
1472218822Sdimmodrm;
147378828Sobrienstatic unsigned char need_modrm;
147433965Sjdp
147578828Sobrien/* If we are accessing mod/rm/reg without need_modrm set, then the
147678828Sobrien   values are stale.  Hitting this abort likely indicates that you
147778828Sobrien   need to update onebyte_has_modrm or twobyte_has_modrm.  */
147878828Sobrien#define MODRM_CHECK  if (!need_modrm) abort ()
147978828Sobrien
148085815Sobrienstatic const char **names64;
148185815Sobrienstatic const char **names32;
148285815Sobrienstatic const char **names16;
148385815Sobrienstatic const char **names8;
148485815Sobrienstatic const char **names8rex;
148585815Sobrienstatic const char **names_seg;
148685815Sobrienstatic const char **index16;
148785815Sobrien
148885815Sobrienstatic const char *intel_names64[] = {
148985815Sobrien  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
149085815Sobrien  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
149185815Sobrien};
149285815Sobrienstatic const char *intel_names32[] = {
149385815Sobrien  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
149485815Sobrien  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
149585815Sobrien};
149685815Sobrienstatic const char *intel_names16[] = {
149785815Sobrien  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
149885815Sobrien  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
149985815Sobrien};
150085815Sobrienstatic const char *intel_names8[] = {
150185815Sobrien  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
150285815Sobrien};
150385815Sobrienstatic const char *intel_names8rex[] = {
150485815Sobrien  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
150585815Sobrien  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
150685815Sobrien};
150785815Sobrienstatic const char *intel_names_seg[] = {
150885815Sobrien  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
150985815Sobrien};
151085815Sobrienstatic const char *intel_index16[] = {
151185815Sobrien  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
151285815Sobrien};
151385815Sobrien
151485815Sobrienstatic const char *att_names64[] = {
151585815Sobrien  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
151677298Sobrien  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
151777298Sobrien};
151885815Sobrienstatic const char *att_names32[] = {
151985815Sobrien  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
152077298Sobrien  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
152133965Sjdp};
152285815Sobrienstatic const char *att_names16[] = {
152385815Sobrien  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
152477298Sobrien  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
152533965Sjdp};
152685815Sobrienstatic const char *att_names8[] = {
152785815Sobrien  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
152833965Sjdp};
152985815Sobrienstatic const char *att_names8rex[] = {
153085815Sobrien  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
153177298Sobrien  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
153277298Sobrien};
153385815Sobrienstatic const char *att_names_seg[] = {
153485815Sobrien  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
153533965Sjdp};
153685815Sobrienstatic const char *att_index16[] = {
153785815Sobrien  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
153833965Sjdp};
153933965Sjdp
154060484Sobrienstatic const struct dis386 grps[][8] = {
1541218822Sdim  /* GRP1a */
1542218822Sdim  {
1543218822Sdim    { "popU",	{ stackEv } },
1544218822Sdim    { "(bad)",	{ XX } },
1545218822Sdim    { "(bad)",	{ XX } },
1546218822Sdim    { "(bad)",	{ XX } },
1547218822Sdim    { "(bad)",	{ XX } },
1548218822Sdim    { "(bad)",	{ XX } },
1549218822Sdim    { "(bad)",	{ XX } },
1550218822Sdim    { "(bad)",	{ XX } },
1551218822Sdim  },
155233965Sjdp  /* GRP1b */
155333965Sjdp  {
1554218822Sdim    { "addA",	{ Eb, Ib } },
1555218822Sdim    { "orA",	{ Eb, Ib } },
1556218822Sdim    { "adcA",	{ Eb, Ib } },
1557218822Sdim    { "sbbA",	{ Eb, Ib } },
1558218822Sdim    { "andA",	{ Eb, Ib } },
1559218822Sdim    { "subA",	{ Eb, Ib } },
1560218822Sdim    { "xorA",	{ Eb, Ib } },
1561218822Sdim    { "cmpA",	{ Eb, Ib } },
156233965Sjdp  },
156333965Sjdp  /* GRP1S */
156433965Sjdp  {
1565218822Sdim    { "addQ",	{ Ev, Iv } },
1566218822Sdim    { "orQ",	{ Ev, Iv } },
1567218822Sdim    { "adcQ",	{ Ev, Iv } },
1568218822Sdim    { "sbbQ",	{ Ev, Iv } },
1569218822Sdim    { "andQ",	{ Ev, Iv } },
1570218822Sdim    { "subQ",	{ Ev, Iv } },
1571218822Sdim    { "xorQ",	{ Ev, Iv } },
1572218822Sdim    { "cmpQ",	{ Ev, Iv } },
157333965Sjdp  },
157433965Sjdp  /* GRP1Ss */
157533965Sjdp  {
1576218822Sdim    { "addQ",	{ Ev, sIb } },
1577218822Sdim    { "orQ",	{ Ev, sIb } },
1578218822Sdim    { "adcQ",	{ Ev, sIb } },
1579218822Sdim    { "sbbQ",	{ Ev, sIb } },
1580218822Sdim    { "andQ",	{ Ev, sIb } },
1581218822Sdim    { "subQ",	{ Ev, sIb } },
1582218822Sdim    { "xorQ",	{ Ev, sIb } },
1583218822Sdim    { "cmpQ",	{ Ev, sIb } },
158433965Sjdp  },
158533965Sjdp  /* GRP2b */
158633965Sjdp  {
1587218822Sdim    { "rolA",	{ Eb, Ib } },
1588218822Sdim    { "rorA",	{ Eb, Ib } },
1589218822Sdim    { "rclA",	{ Eb, Ib } },
1590218822Sdim    { "rcrA",	{ Eb, Ib } },
1591218822Sdim    { "shlA",	{ Eb, Ib } },
1592218822Sdim    { "shrA",	{ Eb, Ib } },
1593218822Sdim    { "(bad)",	{ XX } },
1594218822Sdim    { "sarA",	{ Eb, Ib } },
159533965Sjdp  },
159633965Sjdp  /* GRP2S */
159733965Sjdp  {
1598218822Sdim    { "rolQ",	{ Ev, Ib } },
1599218822Sdim    { "rorQ",	{ Ev, Ib } },
1600218822Sdim    { "rclQ",	{ Ev, Ib } },
1601218822Sdim    { "rcrQ",	{ Ev, Ib } },
1602218822Sdim    { "shlQ",	{ Ev, Ib } },
1603218822Sdim    { "shrQ",	{ Ev, Ib } },
1604218822Sdim    { "(bad)",	{ XX } },
1605218822Sdim    { "sarQ",	{ Ev, Ib } },
160633965Sjdp  },
160733965Sjdp  /* GRP2b_one */
160833965Sjdp  {
1609218822Sdim    { "rolA",	{ Eb, I1 } },
1610218822Sdim    { "rorA",	{ Eb, I1 } },
1611218822Sdim    { "rclA",	{ Eb, I1 } },
1612218822Sdim    { "rcrA",	{ Eb, I1 } },
1613218822Sdim    { "shlA",	{ Eb, I1 } },
1614218822Sdim    { "shrA",	{ Eb, I1 } },
1615218822Sdim    { "(bad)",	{ XX } },
1616218822Sdim    { "sarA",	{ Eb, I1 } },
161733965Sjdp  },
161833965Sjdp  /* GRP2S_one */
161933965Sjdp  {
1620218822Sdim    { "rolQ",	{ Ev, I1 } },
1621218822Sdim    { "rorQ",	{ Ev, I1 } },
1622218822Sdim    { "rclQ",	{ Ev, I1 } },
1623218822Sdim    { "rcrQ",	{ Ev, I1 } },
1624218822Sdim    { "shlQ",	{ Ev, I1 } },
1625218822Sdim    { "shrQ",	{ Ev, I1 } },
1626218822Sdim    { "(bad)",	{ XX } },
1627218822Sdim    { "sarQ",	{ Ev, I1 } },
162833965Sjdp  },
162933965Sjdp  /* GRP2b_cl */
163033965Sjdp  {
1631218822Sdim    { "rolA",	{ Eb, CL } },
1632218822Sdim    { "rorA",	{ Eb, CL } },
1633218822Sdim    { "rclA",	{ Eb, CL } },
1634218822Sdim    { "rcrA",	{ Eb, CL } },
1635218822Sdim    { "shlA",	{ Eb, CL } },
1636218822Sdim    { "shrA",	{ Eb, CL } },
1637218822Sdim    { "(bad)",	{ XX } },
1638218822Sdim    { "sarA",	{ Eb, CL } },
163933965Sjdp  },
164033965Sjdp  /* GRP2S_cl */
164133965Sjdp  {
1642218822Sdim    { "rolQ",	{ Ev, CL } },
1643218822Sdim    { "rorQ",	{ Ev, CL } },
1644218822Sdim    { "rclQ",	{ Ev, CL } },
1645218822Sdim    { "rcrQ",	{ Ev, CL } },
1646218822Sdim    { "shlQ",	{ Ev, CL } },
1647218822Sdim    { "shrQ",	{ Ev, CL } },
1648218822Sdim    { "(bad)",	{ XX } },
1649218822Sdim    { "sarQ",	{ Ev, CL } },
165033965Sjdp  },
165133965Sjdp  /* GRP3b */
165233965Sjdp  {
1653218822Sdim    { "testA",	{ Eb, Ib } },
1654218822Sdim    { "(bad)",	{ Eb } },
1655218822Sdim    { "notA",	{ Eb } },
1656218822Sdim    { "negA",	{ Eb } },
1657218822Sdim    { "mulA",	{ Eb } },	/* Don't print the implicit %al register,  */
1658218822Sdim    { "imulA",	{ Eb } },	/* to distinguish these opcodes from other */
1659218822Sdim    { "divA",	{ Eb } },	/* mul/imul opcodes.  Do the same for div  */
1660218822Sdim    { "idivA",	{ Eb } },	/* and idiv for consistency.		   */
166133965Sjdp  },
166233965Sjdp  /* GRP3S */
166333965Sjdp  {
1664218822Sdim    { "testQ",	{ Ev, Iv } },
1665218822Sdim    { "(bad)",	{ XX } },
1666218822Sdim    { "notQ",	{ Ev } },
1667218822Sdim    { "negQ",	{ Ev } },
1668218822Sdim    { "mulQ",	{ Ev } },	/* Don't print the implicit register.  */
1669218822Sdim    { "imulQ",	{ Ev } },
1670218822Sdim    { "divQ",	{ Ev } },
1671218822Sdim    { "idivQ",	{ Ev } },
167233965Sjdp  },
167333965Sjdp  /* GRP4 */
167433965Sjdp  {
1675218822Sdim    { "incA",	{ Eb } },
1676218822Sdim    { "decA",	{ Eb } },
1677218822Sdim    { "(bad)",	{ XX } },
1678218822Sdim    { "(bad)",	{ XX } },
1679218822Sdim    { "(bad)",	{ XX } },
1680218822Sdim    { "(bad)",	{ XX } },
1681218822Sdim    { "(bad)",	{ XX } },
1682218822Sdim    { "(bad)",	{ XX } },
168333965Sjdp  },
168433965Sjdp  /* GRP5 */
168533965Sjdp  {
1686218822Sdim    { "incQ",	{ Ev } },
1687218822Sdim    { "decQ",	{ Ev } },
1688218822Sdim    { "callT",	{ indirEv } },
1689218822Sdim    { "JcallT",	{ indirEp } },
1690218822Sdim    { "jmpT",	{ indirEv } },
1691218822Sdim    { "JjmpT",	{ indirEp } },
1692218822Sdim    { "pushU",	{ stackEv } },
1693218822Sdim    { "(bad)",	{ XX } },
169433965Sjdp  },
169533965Sjdp  /* GRP6 */
169633965Sjdp  {
1697218822Sdim    { "sldtD",	{ Sv } },
1698218822Sdim    { "strD",	{ Sv } },
1699218822Sdim    { "lldt",	{ Ew } },
1700218822Sdim    { "ltr",	{ Ew } },
1701218822Sdim    { "verr",	{ Ew } },
1702218822Sdim    { "verw",	{ Ew } },
1703218822Sdim    { "(bad)",	{ XX } },
1704218822Sdim    { "(bad)",	{ XX } },
170533965Sjdp  },
170633965Sjdp  /* GRP7 */
170733965Sjdp  {
1708218822Sdim    { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1709218822Sdim    { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1710238123Sjhb    { "lgdt{Q|Q||}",	 { { XCR_Fixup, 0 }  } },
1711218822Sdim    { "lidt{Q|Q||}",	 { { SVME_Fixup, 0 } } },
1712218822Sdim    { "smswD",	{ Sv } },
1713218822Sdim    { "(bad)",	{ XX } },
1714218822Sdim    { "lmsw",	{ Ew } },
1715218822Sdim    { "invlpg",	{ { INVLPG_Fixup, w_mode } } },
171633965Sjdp  },
171733965Sjdp  /* GRP8 */
171833965Sjdp  {
1719218822Sdim    { "(bad)",	{ XX } },
1720218822Sdim    { "(bad)",	{ XX } },
1721218822Sdim    { "(bad)",	{ XX } },
1722218822Sdim    { "(bad)",	{ XX } },
1723218822Sdim    { "btQ",	{ Ev, Ib } },
1724218822Sdim    { "btsQ",	{ Ev, Ib } },
1725218822Sdim    { "btrQ",	{ Ev, Ib } },
1726218822Sdim    { "btcQ",	{ Ev, Ib } },
172733965Sjdp  },
172833965Sjdp  /* GRP9 */
172933965Sjdp  {
1730218822Sdim    { "(bad)",	{ XX } },
1731218822Sdim    { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1732218822Sdim    { "(bad)",	{ XX } },
1733218822Sdim    { "(bad)",	{ XX } },
1734218822Sdim    { "(bad)",	{ XX } },
1735218822Sdim    { "(bad)",	{ XX } },
1736218822Sdim    { "",	{ VM } },		/* See OP_VMX.  */
1737266391Sjhb    { "",	{ VM2 } },		/* See OP_VMX2.  */
173833965Sjdp  },
1739218822Sdim  /* GRP11_C6 */
174033965Sjdp  {
1741218822Sdim    { "movA",	{ Eb, Ib } },
1742218822Sdim    { "(bad)",	{ XX } },
1743218822Sdim    { "(bad)",	{ XX } },
1744218822Sdim    { "(bad)",	{ XX } },
1745218822Sdim    { "(bad)",	{ XX } },
1746218822Sdim    { "(bad)",	{ XX } },
1747218822Sdim    { "(bad)",	{ XX } },
1748218822Sdim    { "(bad)",	{ XX } },
174933965Sjdp  },
1750218822Sdim  /* GRP11_C7 */
175133965Sjdp  {
1752218822Sdim    { "movQ",	{ Ev, Iv } },
1753218822Sdim    { "(bad)",	{ XX } },
1754218822Sdim    { "(bad)",	{ XX } },
1755218822Sdim    { "(bad)",	{ XX } },
1756218822Sdim    { "(bad)",	{ XX } },
1757218822Sdim    { "(bad)",	{ XX } },
1758218822Sdim    { "(bad)",	{ XX } },
1759218822Sdim    { "(bad)",  { XX } },
176033965Sjdp  },
176133965Sjdp  /* GRP12 */
176233965Sjdp  {
1763218822Sdim    { "(bad)",	{ XX } },
1764218822Sdim    { "(bad)",	{ XX } },
1765218822Sdim    { "psrlw",	{ MS, Ib } },
1766218822Sdim    { "(bad)",	{ XX } },
1767218822Sdim    { "psraw",	{ MS, Ib } },
1768218822Sdim    { "(bad)",	{ XX } },
1769218822Sdim    { "psllw",	{ MS, Ib } },
1770218822Sdim    { "(bad)",	{ XX } },
177160484Sobrien  },
177260484Sobrien  /* GRP13 */
177360484Sobrien  {
1774218822Sdim    { "(bad)",	{ XX } },
1775218822Sdim    { "(bad)",	{ XX } },
1776218822Sdim    { "psrld",	{ MS, Ib } },
1777218822Sdim    { "(bad)",	{ XX } },
1778218822Sdim    { "psrad",	{ MS, Ib } },
1779218822Sdim    { "(bad)",	{ XX } },
1780218822Sdim    { "pslld",	{ MS, Ib } },
1781218822Sdim    { "(bad)",	{ XX } },
178260484Sobrien  },
178360484Sobrien  /* GRP14 */
178460484Sobrien  {
1785218822Sdim    { "(bad)",	{ XX } },
1786218822Sdim    { "(bad)",	{ XX } },
1787218822Sdim    { "psrlq",	{ MS, Ib } },
1788218822Sdim    { "psrldq",	{ MS, Ib } },
1789218822Sdim    { "(bad)",	{ XX } },
1790218822Sdim    { "(bad)",	{ XX } },
1791218822Sdim    { "psllq",	{ MS, Ib } },
1792218822Sdim    { "pslldq",	{ MS, Ib } },
179360484Sobrien  },
1794218822Sdim  /* GRP15 */
1795218822Sdim  {
1796323489Srlibby    { "fxsave",		{ { OP_0fae, v_mode } } },
1797323489Srlibby    { "fxrstor",	{ { OP_0fae, v_mode } } },
1798323489Srlibby    { "ldmxcsr",	{ { OP_0fae, v_mode } } },
1799323489Srlibby    { "stmxcsr",	{ { OP_0fae, v_mode } } },
1800238123Sjhb    { "xsave",		{ Ev } },
1801238123Sjhb    { "xrstor",		{ { OP_0fae, v_mode } } },
1802238123Sjhb    { "xsaveopt",	{ { OP_0fae, v_mode } } },
1803218822Sdim    { "clflush",	{ { OP_0fae, 0 } } },
1804218822Sdim  },
1805218822Sdim  /* GRP16 */
1806218822Sdim  {
1807218822Sdim    { "prefetchnta",	{ Ev } },
1808218822Sdim    { "prefetcht0",	{ Ev } },
1809218822Sdim    { "prefetcht1",	{ Ev } },
1810218822Sdim    { "prefetcht2",	{ Ev } },
1811218822Sdim    { "(bad)",		{ XX } },
1812218822Sdim    { "(bad)",		{ XX } },
1813218822Sdim    { "(bad)",		{ XX } },
1814218822Sdim    { "(bad)",		{ XX } },
1815218822Sdim  },
181660484Sobrien  /* GRPAMD */
181760484Sobrien  {
1818218822Sdim    { "prefetch",	{ Eb } },
1819218822Sdim    { "prefetchw",	{ Eb } },
1820218822Sdim    { "(bad)",		{ XX } },
1821218822Sdim    { "(bad)",		{ XX } },
1822218822Sdim    { "(bad)",		{ XX } },
1823218822Sdim    { "(bad)",		{ XX } },
1824218822Sdim    { "(bad)",		{ XX } },
1825218822Sdim    { "(bad)",		{ XX } },
1826130561Sobrien  },
1827218822Sdim  /* GRPPADLCK1 */
1828130561Sobrien  {
1829218822Sdim    { "xstore-rng",	{ { OP_0f07, 0 } } },
1830218822Sdim    { "xcrypt-ecb",	{ { OP_0f07, 0 } } },
1831218822Sdim    { "xcrypt-cbc",	{ { OP_0f07, 0 } } },
1832218822Sdim    { "xcrypt-ctr",	{ { OP_0f07, 0 } } },
1833218822Sdim    { "xcrypt-cfb",	{ { OP_0f07, 0 } } },
1834218822Sdim    { "xcrypt-ofb",	{ { OP_0f07, 0 } } },
1835218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1836218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1837218822Sdim  },
1838218822Sdim  /* GRPPADLCK2 */
1839218822Sdim  {
1840218822Sdim    { "montmul",	{ { OP_0f07, 0 } } },
1841218822Sdim    { "xsha1",		{ { OP_0f07, 0 } } },
1842218822Sdim    { "xsha256",	{ { OP_0f07, 0 } } },
1843218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1844218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1845218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1846218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
1847218822Sdim    { "(bad)",		{ { OP_0f07, 0 } } },
184833965Sjdp  }
184933965Sjdp};
185033965Sjdp
185177298Sobrienstatic const struct dis386 prefix_user_table[][4] = {
185260484Sobrien  /* PREGRP0 */
185360484Sobrien  {
1854218822Sdim    { "addps", { XM, EXx } },
1855218822Sdim    { "addss", { XM, EXd } },
1856218822Sdim    { "addpd", { XM, EXx } },
1857218822Sdim    { "addsd", { XM, EXq } },
185860484Sobrien  },
185960484Sobrien  /* PREGRP1 */
186060484Sobrien  {
1861218822Sdim    { "", { XM, EXx, OPSIMD } },	/* See OP_SIMD_SUFFIX.  */
1862218822Sdim    { "", { XM, EXx, OPSIMD } },
1863218822Sdim    { "", { XM, EXx, OPSIMD } },
1864218822Sdim    { "", { XM, EXx, OPSIMD } },
186560484Sobrien  },
186660484Sobrien  /* PREGRP2 */
186760484Sobrien  {
1868218822Sdim    { "cvtpi2ps", { XM, EMC } },
1869218822Sdim    { "cvtsi2ssY", { XM, Ev } },
1870218822Sdim    { "cvtpi2pd", { XM, EMC } },
1871218822Sdim    { "cvtsi2sdY", { XM, Ev } },
187260484Sobrien  },
187360484Sobrien  /* PREGRP3 */
187460484Sobrien  {
1875218822Sdim    { "cvtps2pi", { MXC, EXx } },
1876218822Sdim    { "cvtss2siY", { Gv, EXx } },
1877218822Sdim    { "cvtpd2pi", { MXC, EXx } },
1878218822Sdim    { "cvtsd2siY", { Gv, EXx } },
187960484Sobrien  },
188060484Sobrien  /* PREGRP4 */
188160484Sobrien  {
1882218822Sdim    { "cvttps2pi", { MXC, EXx } },
1883218822Sdim    { "cvttss2siY", { Gv, EXx } },
1884218822Sdim    { "cvttpd2pi", { MXC, EXx } },
1885218822Sdim    { "cvttsd2siY", { Gv, EXx } },
188660484Sobrien  },
188760484Sobrien  /* PREGRP5 */
188860484Sobrien  {
1889218822Sdim    { "divps",	{ XM, EXx } },
1890218822Sdim    { "divss",	{ XM, EXx } },
1891218822Sdim    { "divpd",	{ XM, EXx } },
1892218822Sdim    { "divsd",	{ XM, EXx } },
189360484Sobrien  },
189460484Sobrien  /* PREGRP6 */
189560484Sobrien  {
1896218822Sdim    { "maxps",	{ XM, EXx } },
1897218822Sdim    { "maxss",	{ XM, EXx } },
1898218822Sdim    { "maxpd",	{ XM, EXx } },
1899218822Sdim    { "maxsd",	{ XM, EXx } },
190060484Sobrien  },
190160484Sobrien  /* PREGRP7 */
190260484Sobrien  {
1903218822Sdim    { "minps",	{ XM, EXx } },
1904218822Sdim    { "minss",	{ XM, EXx } },
1905218822Sdim    { "minpd",	{ XM, EXx } },
1906218822Sdim    { "minsd",	{ XM, EXx } },
190760484Sobrien  },
190860484Sobrien  /* PREGRP8 */
190960484Sobrien  {
1910218822Sdim    { "movups",	{ XM, EXx } },
1911218822Sdim    { "movss",	{ XM, EXx } },
1912218822Sdim    { "movupd",	{ XM, EXx } },
1913218822Sdim    { "movsd",	{ XM, EXx } },
191460484Sobrien  },
191560484Sobrien  /* PREGRP9 */
191660484Sobrien  {
1917218822Sdim    { "movups",	{ EXx,  XM } },
1918218822Sdim    { "movss",	{ EXx,  XM } },
1919218822Sdim    { "movupd",	{ EXx,  XM } },
1920218822Sdim    { "movsd",	{ EXx,  XM } },
192160484Sobrien  },
192260484Sobrien  /* PREGRP10 */
192360484Sobrien  {
1924218822Sdim    { "mulps",	{ XM, EXx } },
1925218822Sdim    { "mulss",	{ XM, EXx } },
1926218822Sdim    { "mulpd",	{ XM, EXx } },
1927218822Sdim    { "mulsd",	{ XM, EXx } },
192860484Sobrien  },
192960484Sobrien  /* PREGRP11 */
193060484Sobrien  {
1931218822Sdim    { "rcpps",	{ XM, EXx } },
1932218822Sdim    { "rcpss",	{ XM, EXx } },
1933218822Sdim    { "(bad)",	{ XM, EXx } },
1934218822Sdim    { "(bad)",	{ XM, EXx } },
193560484Sobrien  },
193660484Sobrien  /* PREGRP12 */
193760484Sobrien  {
1938218822Sdim    { "rsqrtps",{ XM, EXx } },
1939218822Sdim    { "rsqrtss",{ XM, EXx } },
1940218822Sdim    { "(bad)",	{ XM, EXx } },
1941218822Sdim    { "(bad)",	{ XM, EXx } },
194260484Sobrien  },
194360484Sobrien  /* PREGRP13 */
194460484Sobrien  {
1945218822Sdim    { "sqrtps", { XM, EXx } },
1946218822Sdim    { "sqrtss", { XM, EXx } },
1947218822Sdim    { "sqrtpd", { XM, EXx } },
1948218822Sdim    { "sqrtsd",	{ XM, EXx } },
194960484Sobrien  },
195060484Sobrien  /* PREGRP14 */
195160484Sobrien  {
1952218822Sdim    { "subps",	{ XM, EXx } },
1953218822Sdim    { "subss",	{ XM, EXx } },
1954218822Sdim    { "subpd",	{ XM, EXx } },
1955218822Sdim    { "subsd",	{ XM, EXx } },
195677298Sobrien  },
195777298Sobrien  /* PREGRP15 */
195877298Sobrien  {
1959218822Sdim    { "(bad)",	{ XM, EXx } },
1960218822Sdim    { "cvtdq2pd", { XM, EXq } },
1961218822Sdim    { "cvttpd2dq", { XM, EXx } },
1962218822Sdim    { "cvtpd2dq", { XM, EXx } },
196377298Sobrien  },
196477298Sobrien  /* PREGRP16 */
196577298Sobrien  {
1966218822Sdim    { "cvtdq2ps", { XM, EXx } },
1967218822Sdim    { "cvttps2dq", { XM, EXx } },
1968218822Sdim    { "cvtps2dq", { XM, EXx } },
1969218822Sdim    { "(bad)",	{ XM, EXx } },
197077298Sobrien  },
197177298Sobrien  /* PREGRP17 */
197277298Sobrien  {
1973218822Sdim    { "cvtps2pd", { XM, EXq } },
1974218822Sdim    { "cvtss2sd", { XM, EXx } },
1975218822Sdim    { "cvtpd2ps", { XM, EXx } },
1976218822Sdim    { "cvtsd2ss", { XM, EXx } },
197777298Sobrien  },
197877298Sobrien  /* PREGRP18 */
197977298Sobrien  {
1980218822Sdim    { "maskmovq", { MX, MS } },
1981218822Sdim    { "(bad)",	{ XM, EXx } },
1982218822Sdim    { "maskmovdqu", { XM, XS } },
1983218822Sdim    { "(bad)",	{ XM, EXx } },
198477298Sobrien  },
198577298Sobrien  /* PREGRP19 */
198677298Sobrien  {
1987218822Sdim    { "movq",	{ MX, EM } },
1988218822Sdim    { "movdqu",	{ XM, EXx } },
1989218822Sdim    { "movdqa",	{ XM, EXx } },
1990218822Sdim    { "(bad)",	{ XM, EXx } },
199177298Sobrien  },
199277298Sobrien  /* PREGRP20 */
199377298Sobrien  {
1994218822Sdim    { "movq",	{ EM, MX } },
1995218822Sdim    { "movdqu",	{ EXx,  XM } },
1996218822Sdim    { "movdqa",	{ EXx,  XM } },
1997218822Sdim    { "(bad)",	{ EXx,  XM } },
199877298Sobrien  },
199977298Sobrien  /* PREGRP21 */
200077298Sobrien  {
2001218822Sdim    { "(bad)",	{ EXx,  XM } },
2002218822Sdim    { "movq2dq",{ XM, MS } },
2003218822Sdim    { "movq",	{ EXx,  XM } },
2004218822Sdim    { "movdq2q",{ MX, XS } },
200577298Sobrien  },
200677298Sobrien  /* PREGRP22 */
200777298Sobrien  {
2008218822Sdim    { "pshufw",	{ MX, EM, Ib } },
2009218822Sdim    { "pshufhw",{ XM, EXx, Ib } },
2010218822Sdim    { "pshufd",	{ XM, EXx, Ib } },
2011218822Sdim    { "pshuflw",{ XM, EXx, Ib } },
201277298Sobrien  },
201377298Sobrien  /* PREGRP23 */
201477298Sobrien  {
2015218822Sdim    { "movd",	{ Edq, MX } },
2016218822Sdim    { "movq",	{ XM, EXx } },
2017218822Sdim    { "movd",	{ Edq, XM } },
2018218822Sdim    { "(bad)",	{ Ed, XM } },
201977298Sobrien  },
202077298Sobrien  /* PREGRP24 */
202177298Sobrien  {
2022218822Sdim    { "(bad)",	{ MX, EXx } },
2023218822Sdim    { "(bad)",	{ XM, EXx } },
2024218822Sdim    { "punpckhqdq", { XM, EXx } },
2025218822Sdim    { "(bad)",	{ XM, EXx } },
202677298Sobrien  },
202777298Sobrien  /* PREGRP25 */
202877298Sobrien  {
2029218822Sdim    { "movntq",	{ EM, MX } },
2030218822Sdim    { "(bad)",	{ EM, XM } },
2031218822Sdim    { "movntdq",{ EM, XM } },
2032218822Sdim    { "(bad)",	{ EM, XM } },
203377298Sobrien  },
203477298Sobrien  /* PREGRP26 */
203577298Sobrien  {
2036218822Sdim    { "(bad)",	{ MX, EXx } },
2037218822Sdim    { "(bad)",	{ XM, EXx } },
2038218822Sdim    { "punpcklqdq", { XM, EXx } },
2039218822Sdim    { "(bad)",	{ XM, EXx } },
204077298Sobrien  },
2041130561Sobrien  /* PREGRP27 */
2042130561Sobrien  {
2043218822Sdim    { "(bad)",	{ MX, EXx } },
2044218822Sdim    { "(bad)",	{ XM, EXx } },
2045218822Sdim    { "addsubpd", { XM, EXx } },
2046218822Sdim    { "addsubps", { XM, EXx } },
2047130561Sobrien  },
2048130561Sobrien  /* PREGRP28 */
2049130561Sobrien  {
2050218822Sdim    { "(bad)",	{ MX, EXx } },
2051218822Sdim    { "(bad)",	{ XM, EXx } },
2052218822Sdim    { "haddpd",	{ XM, EXx } },
2053218822Sdim    { "haddps",	{ XM, EXx } },
2054130561Sobrien  },
2055130561Sobrien  /* PREGRP29 */
2056130561Sobrien  {
2057218822Sdim    { "(bad)",	{ MX, EXx } },
2058218822Sdim    { "(bad)",	{ XM, EXx } },
2059218822Sdim    { "hsubpd",	{ XM, EXx } },
2060218822Sdim    { "hsubps",	{ XM, EXx } },
2061130561Sobrien  },
2062130561Sobrien  /* PREGRP30 */
2063130561Sobrien  {
2064218822Sdim    { "movlpX",	{ XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
2065218822Sdim    { "movsldup", { XM, EXx } },
2066218822Sdim    { "movlpd",	{ XM, EXq } },
2067218822Sdim    { "movddup", { XM, EXq } },
2068130561Sobrien  },
2069130561Sobrien  /* PREGRP31 */
2070130561Sobrien  {
2071218822Sdim    { "movhpX",	{ XM, EXq, { SIMD_Fixup, 'l' } } },
2072218822Sdim    { "movshdup", { XM, EXx } },
2073218822Sdim    { "movhpd",	{ XM, EXq } },
2074218822Sdim    { "(bad)",	{ XM, EXq } },
2075130561Sobrien  },
2076130561Sobrien  /* PREGRP32 */
2077130561Sobrien  {
2078218822Sdim    { "(bad)",	{ XM, EXx } },
2079218822Sdim    { "(bad)",	{ XM, EXx } },
2080218822Sdim    { "(bad)",	{ XM, EXx } },
2081218822Sdim    { "lddqu",	{ XM, M } },
2082130561Sobrien  },
2083218822Sdim  /* PREGRP33 */
2084218822Sdim  {
2085218822Sdim    {"movntps", { Ev, XM } },
2086218822Sdim    {"movntss", { Ev, XM } },
2087218822Sdim    {"movntpd", { Ev, XM } },
2088218822Sdim    {"movntsd", { Ev, XM } },
2089218822Sdim  },
2090218822Sdim
2091218822Sdim  /* PREGRP34 */
2092218822Sdim  {
2093218822Sdim    {"vmread",	{ Em, Gm } },
2094218822Sdim    {"(bad)",	{ XX } },
2095218822Sdim    {"extrq",	{ XS, Ib, Ib } },
2096218822Sdim    {"insertq",	{ XM, XS, Ib, Ib } },
2097218822Sdim  },
2098218822Sdim
2099218822Sdim /* PREGRP35 */
2100218822Sdim  {
2101218822Sdim    {"vmwrite",	{ Gm, Em } },
2102218822Sdim    {"(bad)",	{ XX } },
2103218822Sdim    {"extrq",	{ XM, XS } },
2104218822Sdim    {"insertq",	{ XM, XS } },
2105218822Sdim  },
2106218822Sdim
2107218822Sdim  /* PREGRP36 */
2108218822Sdim  {
2109218822Sdim    { "bsrS",	{ Gv, Ev } },
2110218822Sdim    { "lzcntS",	{ Gv, Ev } },
2111218822Sdim    { "bsrS",	{ Gv, Ev } },
2112218822Sdim    { "(bad)",	{ XX } },
2113218822Sdim  },
2114218822Sdim
2115218822Sdim  /* PREGRP37 */
2116218822Sdim  {
2117218822Sdim    { "(bad)", { XX } },
2118218822Sdim    { "popcntS", { Gv, Ev } },
2119218822Sdim    { "(bad)", { XX } },
2120218822Sdim    { "(bad)", { XX } },
2121218822Sdim  },
2122218822Sdim
2123218822Sdim  /* PREGRP38 */
2124218822Sdim  {
2125218822Sdim    { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2126218822Sdim    { "pause", { XX } },
2127218822Sdim    { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2128218822Sdim    { "(bad)", { XX } },
2129218822Sdim  },
2130218822Sdim
2131218822Sdim  /* PREGRP39 */
2132218822Sdim  {
2133218822Sdim    { "(bad)",	{ XX } },
2134218822Sdim    { "(bad)",	{ XX } },
2135218822Sdim    { "pblendvb", {XM, EXx, XMM0 } },
2136218822Sdim    { "(bad)",	{ XX } },
2137218822Sdim  },
2138218822Sdim
2139218822Sdim  /* PREGRP40 */
2140218822Sdim  {
2141218822Sdim    { "(bad)",	{ XX } },
2142218822Sdim    { "(bad)",	{ XX } },
2143218822Sdim    { "blendvps", {XM, EXx, XMM0 } },
2144218822Sdim    { "(bad)",	{ XX } },
2145218822Sdim  },
2146218822Sdim
2147218822Sdim  /* PREGRP41 */
2148218822Sdim  {
2149218822Sdim    { "(bad)",	{ XX } },
2150218822Sdim    { "(bad)",	{ XX } },
2151218822Sdim    { "blendvpd", { XM, EXx, XMM0 } },
2152218822Sdim    { "(bad)",	{ XX } },
2153218822Sdim  },
2154218822Sdim
2155218822Sdim  /* PREGRP42 */
2156218822Sdim  {
2157218822Sdim    { "(bad)",	{ XX } },
2158218822Sdim    { "(bad)",	{ XX } },
2159218822Sdim    { "ptest",  { XM, EXx } },
2160218822Sdim    { "(bad)",	{ XX } },
2161218822Sdim  },
2162218822Sdim
2163218822Sdim  /* PREGRP43 */
2164218822Sdim  {
2165218822Sdim    { "(bad)",	{ XX } },
2166218822Sdim    { "(bad)",	{ XX } },
2167218822Sdim    { "pmovsxbw", { XM, EXx } },
2168218822Sdim    { "(bad)",	{ XX } },
2169218822Sdim  },
2170218822Sdim
2171218822Sdim  /* PREGRP44 */
2172218822Sdim  {
2173218822Sdim    { "(bad)",	{ XX } },
2174218822Sdim    { "(bad)",	{ XX } },
2175218822Sdim    { "pmovsxbd", { XM, EXx } },
2176218822Sdim    { "(bad)",	{ XX } },
2177218822Sdim  },
2178218822Sdim
2179218822Sdim  /* PREGRP45 */
2180218822Sdim  {
2181218822Sdim    { "(bad)",	{ XX } },
2182218822Sdim    { "(bad)",	{ XX } },
2183218822Sdim    { "pmovsxbq", { XM, EXx } },
2184218822Sdim    { "(bad)",	{ XX } },
2185218822Sdim  },
2186218822Sdim
2187218822Sdim  /* PREGRP46 */
2188218822Sdim  {
2189218822Sdim    { "(bad)",	{ XX } },
2190218822Sdim    { "(bad)",	{ XX } },
2191218822Sdim    { "pmovsxwd", { XM, EXx } },
2192218822Sdim    { "(bad)",	{ XX } },
2193218822Sdim  },
2194218822Sdim
2195218822Sdim  /* PREGRP47 */
2196218822Sdim  {
2197218822Sdim    { "(bad)",	{ XX } },
2198218822Sdim    { "(bad)",	{ XX } },
2199218822Sdim    { "pmovsxwq", { XM, EXx } },
2200218822Sdim    { "(bad)",	{ XX } },
2201218822Sdim  },
2202218822Sdim
2203218822Sdim  /* PREGRP48 */
2204218822Sdim  {
2205218822Sdim    { "(bad)",	{ XX } },
2206218822Sdim    { "(bad)",	{ XX } },
2207218822Sdim    { "pmovsxdq", { XM, EXx } },
2208218822Sdim    { "(bad)",	{ XX } },
2209218822Sdim  },
2210218822Sdim
2211218822Sdim  /* PREGRP49 */
2212218822Sdim  {
2213218822Sdim    { "(bad)",	{ XX } },
2214218822Sdim    { "(bad)",	{ XX } },
2215218822Sdim    { "pmuldq", { XM, EXx } },
2216218822Sdim    { "(bad)",	{ XX } },
2217218822Sdim  },
2218218822Sdim
2219218822Sdim  /* PREGRP50 */
2220218822Sdim  {
2221218822Sdim    { "(bad)",	{ XX } },
2222218822Sdim    { "(bad)",	{ XX } },
2223218822Sdim    { "pcmpeqq", { XM, EXx } },
2224218822Sdim    { "(bad)",	{ XX } },
2225218822Sdim  },
2226218822Sdim
2227218822Sdim  /* PREGRP51 */
2228218822Sdim  {
2229218822Sdim    { "(bad)",	{ XX } },
2230218822Sdim    { "(bad)",	{ XX } },
2231218822Sdim    { "movntdqa", { XM, EM } },
2232218822Sdim    { "(bad)",	{ XX } },
2233218822Sdim  },
2234218822Sdim
2235218822Sdim  /* PREGRP52 */
2236218822Sdim  {
2237218822Sdim    { "(bad)",	{ XX } },
2238218822Sdim    { "(bad)",	{ XX } },
2239218822Sdim    { "packusdw", { XM, EXx } },
2240218822Sdim    { "(bad)",	{ XX } },
2241218822Sdim  },
2242218822Sdim
2243218822Sdim  /* PREGRP53 */
2244218822Sdim  {
2245218822Sdim    { "(bad)",	{ XX } },
2246218822Sdim    { "(bad)",	{ XX } },
2247218822Sdim    { "pmovzxbw", { XM, EXx } },
2248218822Sdim    { "(bad)",	{ XX } },
2249218822Sdim  },
2250218822Sdim
2251218822Sdim  /* PREGRP54 */
2252218822Sdim  {
2253218822Sdim    { "(bad)",	{ XX } },
2254218822Sdim    { "(bad)",	{ XX } },
2255218822Sdim    { "pmovzxbd", { XM, EXx } },
2256218822Sdim    { "(bad)",	{ XX } },
2257218822Sdim  },
2258218822Sdim
2259218822Sdim  /* PREGRP55 */
2260218822Sdim  {
2261218822Sdim    { "(bad)",	{ XX } },
2262218822Sdim    { "(bad)",	{ XX } },
2263218822Sdim    { "pmovzxbq", { XM, EXx } },
2264218822Sdim    { "(bad)",	{ XX } },
2265218822Sdim  },
2266218822Sdim
2267218822Sdim  /* PREGRP56 */
2268218822Sdim  {
2269218822Sdim    { "(bad)",	{ XX } },
2270218822Sdim    { "(bad)",	{ XX } },
2271218822Sdim    { "pmovzxwd", { XM, EXx } },
2272218822Sdim    { "(bad)",	{ XX } },
2273218822Sdim  },
2274218822Sdim
2275218822Sdim  /* PREGRP57 */
2276218822Sdim  {
2277218822Sdim    { "(bad)",	{ XX } },
2278218822Sdim    { "(bad)",	{ XX } },
2279218822Sdim    { "pmovzxwq", { XM, EXx } },
2280218822Sdim    { "(bad)",	{ XX } },
2281218822Sdim  },
2282218822Sdim
2283218822Sdim  /* PREGRP58 */
2284218822Sdim  {
2285218822Sdim    { "(bad)",	{ XX } },
2286218822Sdim    { "(bad)",	{ XX } },
2287218822Sdim    { "pmovzxdq", { XM, EXx } },
2288218822Sdim    { "(bad)",	{ XX } },
2289218822Sdim  },
2290218822Sdim
2291218822Sdim  /* PREGRP59 */
2292218822Sdim  {
2293218822Sdim    { "(bad)",	{ XX } },
2294218822Sdim    { "(bad)",	{ XX } },
2295218822Sdim    { "pminsb",	{ XM, EXx } },
2296218822Sdim    { "(bad)",	{ XX } },
2297218822Sdim  },
2298218822Sdim
2299218822Sdim  /* PREGRP60 */
2300218822Sdim  {
2301218822Sdim    { "(bad)",	{ XX } },
2302218822Sdim    { "(bad)",	{ XX } },
2303218822Sdim    { "pminsd",	{ XM, EXx } },
2304218822Sdim    { "(bad)",	{ XX } },
2305218822Sdim  },
2306218822Sdim
2307218822Sdim  /* PREGRP61 */
2308218822Sdim  {
2309218822Sdim    { "(bad)",	{ XX } },
2310218822Sdim    { "(bad)",	{ XX } },
2311218822Sdim    { "pminuw",	{ XM, EXx } },
2312218822Sdim    { "(bad)",	{ XX } },
2313218822Sdim  },
2314218822Sdim
2315218822Sdim  /* PREGRP62 */
2316218822Sdim  {
2317218822Sdim    { "(bad)",	{ XX } },
2318218822Sdim    { "(bad)",	{ XX } },
2319218822Sdim    { "pminud",	{ XM, EXx } },
2320218822Sdim    { "(bad)",	{ XX } },
2321218822Sdim  },
2322218822Sdim
2323218822Sdim  /* PREGRP63 */
2324218822Sdim  {
2325218822Sdim    { "(bad)",	{ XX } },
2326218822Sdim    { "(bad)",	{ XX } },
2327218822Sdim    { "pmaxsb",	{ XM, EXx } },
2328218822Sdim    { "(bad)",	{ XX } },
2329218822Sdim  },
2330218822Sdim
2331218822Sdim  /* PREGRP64 */
2332218822Sdim  {
2333218822Sdim    { "(bad)",	{ XX } },
2334218822Sdim    { "(bad)",	{ XX } },
2335218822Sdim    { "pmaxsd",	{ XM, EXx } },
2336218822Sdim    { "(bad)",	{ XX } },
2337218822Sdim  },
2338218822Sdim
2339218822Sdim  /* PREGRP65 */
2340218822Sdim  {
2341218822Sdim    { "(bad)",	{ XX } },
2342218822Sdim    { "(bad)",	{ XX } },
2343218822Sdim    { "pmaxuw", { XM, EXx } },
2344218822Sdim    { "(bad)",	{ XX } },
2345218822Sdim  },
2346218822Sdim
2347218822Sdim  /* PREGRP66 */
2348218822Sdim  {
2349218822Sdim    { "(bad)",	{ XX } },
2350218822Sdim    { "(bad)",	{ XX } },
2351218822Sdim    { "pmaxud", { XM, EXx } },
2352218822Sdim    { "(bad)",	{ XX } },
2353218822Sdim  },
2354218822Sdim
2355218822Sdim  /* PREGRP67 */
2356218822Sdim  {
2357218822Sdim    { "(bad)",	{ XX } },
2358218822Sdim    { "(bad)",	{ XX } },
2359218822Sdim    { "pmulld", { XM, EXx } },
2360218822Sdim    { "(bad)",	{ XX } },
2361218822Sdim  },
2362218822Sdim
2363218822Sdim  /* PREGRP68 */
2364218822Sdim  {
2365218822Sdim    { "(bad)",	{ XX } },
2366218822Sdim    { "(bad)",	{ XX } },
2367218822Sdim    { "phminposuw", { XM, EXx } },
2368218822Sdim    { "(bad)",	{ XX } },
2369218822Sdim  },
2370218822Sdim
2371218822Sdim  /* PREGRP69 */
2372218822Sdim  {
2373218822Sdim    { "(bad)",	{ XX } },
2374218822Sdim    { "(bad)",	{ XX } },
2375218822Sdim    { "roundps", { XM, EXx, Ib } },
2376218822Sdim    { "(bad)",	{ XX } },
2377218822Sdim  },
2378218822Sdim
2379218822Sdim  /* PREGRP70 */
2380218822Sdim  {
2381218822Sdim    { "(bad)",	{ XX } },
2382218822Sdim    { "(bad)",	{ XX } },
2383218822Sdim    { "roundpd", { XM, EXx, Ib } },
2384218822Sdim    { "(bad)",	{ XX } },
2385218822Sdim  },
2386218822Sdim
2387218822Sdim  /* PREGRP71 */
2388218822Sdim  {
2389218822Sdim    { "(bad)",	{ XX } },
2390218822Sdim    { "(bad)",	{ XX } },
2391218822Sdim    { "roundss", { XM, EXx, Ib } },
2392218822Sdim    { "(bad)",	{ XX } },
2393218822Sdim  },
2394218822Sdim
2395218822Sdim  /* PREGRP72 */
2396218822Sdim  {
2397218822Sdim    { "(bad)",	{ XX } },
2398218822Sdim    { "(bad)",	{ XX } },
2399218822Sdim    { "roundsd", { XM, EXx, Ib } },
2400218822Sdim    { "(bad)",	{ XX } },
2401218822Sdim  },
2402218822Sdim
2403218822Sdim  /* PREGRP73 */
2404218822Sdim  {
2405218822Sdim    { "(bad)",	{ XX } },
2406218822Sdim    { "(bad)",	{ XX } },
2407218822Sdim    { "blendps", { XM, EXx, Ib } },
2408218822Sdim    { "(bad)",	{ XX } },
2409218822Sdim  },
2410218822Sdim
2411218822Sdim  /* PREGRP74 */
2412218822Sdim  {
2413218822Sdim    { "(bad)",	{ XX } },
2414218822Sdim    { "(bad)",	{ XX } },
2415218822Sdim    { "blendpd", { XM, EXx, Ib } },
2416218822Sdim    { "(bad)",	{ XX } },
2417218822Sdim  },
2418218822Sdim
2419218822Sdim  /* PREGRP75 */
2420218822Sdim  {
2421218822Sdim    { "(bad)",	{ XX } },
2422218822Sdim    { "(bad)",	{ XX } },
2423218822Sdim    { "pblendw", { XM, EXx, Ib } },
2424218822Sdim    { "(bad)",	{ XX } },
2425218822Sdim  },
2426218822Sdim
2427218822Sdim  /* PREGRP76 */
2428218822Sdim  {
2429218822Sdim    { "(bad)",	{ XX } },
2430218822Sdim    { "(bad)",	{ XX } },
2431218822Sdim    { "pextrb",	{ Edqb, XM, Ib } },
2432218822Sdim    { "(bad)",	{ XX } },
2433218822Sdim  },
2434218822Sdim
2435218822Sdim  /* PREGRP77 */
2436218822Sdim  {
2437218822Sdim    { "(bad)",	{ XX } },
2438218822Sdim    { "(bad)",	{ XX } },
2439218822Sdim    { "pextrw",	{ Edqw, XM, Ib } },
2440218822Sdim    { "(bad)",	{ XX } },
2441218822Sdim  },
2442218822Sdim
2443218822Sdim  /* PREGRP78 */
2444218822Sdim  {
2445218822Sdim    { "(bad)",	{ XX } },
2446218822Sdim    { "(bad)",	{ XX } },
2447218822Sdim    { "pextrK",	{ Edq, XM, Ib } },
2448218822Sdim    { "(bad)",	{ XX } },
2449218822Sdim  },
2450218822Sdim
2451218822Sdim  /* PREGRP79 */
2452218822Sdim  {
2453218822Sdim    { "(bad)",	{ XX } },
2454218822Sdim    { "(bad)",	{ XX } },
2455218822Sdim    { "extractps", { Edqd, XM, Ib } },
2456218822Sdim    { "(bad)",	{ XX } },
2457218822Sdim  },
2458218822Sdim
2459218822Sdim  /* PREGRP80 */
2460218822Sdim  {
2461218822Sdim    { "(bad)",	{ XX } },
2462218822Sdim    { "(bad)",	{ XX } },
2463218822Sdim    { "pinsrb",	{ XM, Edqb, Ib } },
2464218822Sdim    { "(bad)",	{ XX } },
2465218822Sdim  },
2466218822Sdim
2467218822Sdim  /* PREGRP81 */
2468218822Sdim  {
2469218822Sdim    { "(bad)",	{ XX } },
2470218822Sdim    { "(bad)",	{ XX } },
2471218822Sdim    { "insertps", { XM, EXx, Ib } },
2472218822Sdim    { "(bad)",	{ XX } },
2473218822Sdim  },
2474218822Sdim
2475218822Sdim  /* PREGRP82 */
2476218822Sdim  {
2477218822Sdim    { "(bad)",	{ XX } },
2478218822Sdim    { "(bad)",	{ XX } },
2479218822Sdim    { "pinsrK",	{ XM, Edq, Ib } },
2480218822Sdim    { "(bad)",	{ XX } },
2481218822Sdim  },
2482218822Sdim
2483218822Sdim  /* PREGRP83 */
2484218822Sdim  {
2485218822Sdim    { "(bad)",	{ XX } },
2486218822Sdim    { "(bad)",	{ XX } },
2487218822Sdim    { "dpps",	{ XM, EXx, Ib } },
2488218822Sdim    { "(bad)",	{ XX } },
2489218822Sdim  },
2490218822Sdim
2491218822Sdim  /* PREGRP84 */
2492218822Sdim  {
2493218822Sdim    { "(bad)",	{ XX } },
2494218822Sdim    { "(bad)",	{ XX } },
2495218822Sdim    { "dppd",	{ XM, EXx, Ib } },
2496218822Sdim    { "(bad)",	{ XX } },
2497218822Sdim  },
2498218822Sdim
2499218822Sdim  /* PREGRP85 */
2500218822Sdim  {
2501218822Sdim    { "(bad)",	{ XX } },
2502218822Sdim    { "(bad)",	{ XX } },
2503218822Sdim    { "mpsadbw", { XM, EXx, Ib } },
2504218822Sdim    { "(bad)",	{ XX } },
2505218822Sdim  },
2506218822Sdim
2507218822Sdim  /* PREGRP86 */
2508218822Sdim  {
2509218822Sdim    { "(bad)",	{ XX } },
2510218822Sdim    { "(bad)",	{ XX } },
2511218822Sdim    { "pcmpgtq", { XM, EXx } },
2512218822Sdim    { "(bad)",	{ XX } },
2513218822Sdim  },
2514218822Sdim
2515218822Sdim  /* PREGRP87 */
2516218822Sdim  {
2517218822Sdim    { "(bad)",	{ XX } },
2518218822Sdim    { "(bad)",	{ XX } },
2519218822Sdim    { "(bad)",	{ XX } },
2520218822Sdim    { "crc32",	{ Gdq, { CRC32_Fixup, b_mode } } },
2521218822Sdim  },
2522218822Sdim
2523218822Sdim  /* PREGRP88 */
2524218822Sdim  {
2525218822Sdim    { "(bad)",	{ XX } },
2526218822Sdim    { "(bad)",	{ XX } },
2527218822Sdim    { "(bad)",	{ XX } },
2528218822Sdim    { "crc32",	{ Gdq, { CRC32_Fixup, v_mode } } },
2529218822Sdim  },
2530218822Sdim
2531218822Sdim  /* PREGRP89 */
2532218822Sdim  {
2533218822Sdim    { "(bad)",	{ XX } },
2534218822Sdim    { "(bad)",	{ XX } },
2535218822Sdim    { "pcmpestrm", { XM, EXx, Ib } },
2536218822Sdim    { "(bad)",	{ XX } },
2537218822Sdim  },
2538218822Sdim
2539218822Sdim  /* PREGRP90 */
2540218822Sdim  {
2541218822Sdim    { "(bad)",	{ XX } },
2542218822Sdim    { "(bad)",	{ XX } },
2543218822Sdim    { "pcmpestri", { XM, EXx, Ib } },
2544218822Sdim    { "(bad)",	{ XX } },
2545218822Sdim  },
2546218822Sdim
2547218822Sdim  /* PREGRP91 */
2548218822Sdim  {
2549218822Sdim    { "(bad)",	{ XX } },
2550218822Sdim    { "(bad)",	{ XX } },
2551218822Sdim    { "pcmpistrm", { XM, EXx, Ib } },
2552218822Sdim    { "(bad)",	{ XX } },
2553218822Sdim  },
2554218822Sdim
2555218822Sdim  /* PREGRP92 */
2556218822Sdim  {
2557218822Sdim    { "(bad)",	{ XX } },
2558218822Sdim    { "(bad)",	{ XX } },
2559218822Sdim    { "pcmpistri", { XM, EXx, Ib } },
2560218822Sdim    { "(bad)",	{ XX } },
2561218822Sdim  },
2562218822Sdim
2563218822Sdim  /* PREGRP93 */
2564218822Sdim  {
2565218822Sdim    { "ucomiss",{ XM, EXd } },
2566218822Sdim    { "(bad)",	{ XX } },
2567218822Sdim    { "ucomisd",{ XM, EXq } },
2568218822Sdim    { "(bad)",	{ XX } },
2569218822Sdim  },
2570218822Sdim
2571218822Sdim  /* PREGRP94 */
2572218822Sdim  {
2573218822Sdim    { "comiss",	{ XM, EXd } },
2574218822Sdim    { "(bad)",	{ XX } },
2575218822Sdim    { "comisd",	{ XM, EXq } },
2576218822Sdim    { "(bad)",	{ XX } },
2577218822Sdim  },
2578218822Sdim
2579218822Sdim  /* PREGRP95 */
2580218822Sdim  {
2581218822Sdim    { "punpcklbw",{ MX, EMd } },
2582218822Sdim    { "(bad)",	{ XX } },
2583218822Sdim    { "punpcklbw",{ MX, EMq } },
2584218822Sdim    { "(bad)",	{ XX } },
2585218822Sdim  },
2586218822Sdim
2587218822Sdim  /* PREGRP96 */
2588218822Sdim  {
2589218822Sdim    { "punpcklwd",{ MX, EMd } },
2590218822Sdim    { "(bad)",	{ XX } },
2591218822Sdim    { "punpcklwd",{ MX, EMq } },
2592218822Sdim    { "(bad)",	{ XX } },
2593218822Sdim  },
2594218822Sdim
2595218822Sdim  /* PREGRP97 */
2596218822Sdim  {
2597218822Sdim    { "punpckldq",{ MX, EMd } },
2598218822Sdim    { "(bad)",	{ XX } },
2599218822Sdim    { "punpckldq",{ MX, EMq } },
2600218822Sdim    { "(bad)",	{ XX } },
2601218822Sdim  },
2602238167Sjhb
2603238167Sjhb  /* PREGRP98 */
2604238167Sjhb  {
2605238167Sjhb    { "(bad)",	{ XX } },
2606238167Sjhb    { "(bad)",	{ XX } },
2607238167Sjhb    { "invept",	{ Gm, Mo } },
2608238167Sjhb    { "(bad)",	{ XX } },
2609238167Sjhb  },
2610238167Sjhb
2611238167Sjhb  /* PREGRP99 */
2612238167Sjhb  {
2613238167Sjhb    { "(bad)",	{ XX } },
2614238167Sjhb    { "(bad)",	{ XX } },
2615238167Sjhb    { "invvpid",{ Gm, Mo } },
2616238167Sjhb    { "(bad)",	{ XX } },
2617238167Sjhb  },
2618247012Sjmg
2619247012Sjmg  /* PREGRP100 */
2620247012Sjmg  {
2621247012Sjmg    { "(bad)",	{ XX } },
2622247012Sjmg    { "(bad)",	{ XX } },
2623247012Sjmg    { "aesimc", { XM, EXx } },
2624247012Sjmg    { "(bad)",	{ XX } },
2625247012Sjmg  },
2626247012Sjmg
2627247012Sjmg  /* PREGRP101 */
2628247012Sjmg  {
2629247012Sjmg    { "(bad)",	{ XX } },
2630247012Sjmg    { "(bad)",	{ XX } },
2631247012Sjmg    { "aesenc",{ XM, EXx } },
2632247012Sjmg    { "(bad)",	{ XX } },
2633247012Sjmg  },
2634247012Sjmg
2635247012Sjmg  /* PREGRP102 */
2636247012Sjmg  {
2637247012Sjmg    { "(bad)",	{ XX } },
2638247012Sjmg    { "(bad)",	{ XX } },
2639247012Sjmg    { "aesenclast", { XM, EXx } },
2640247012Sjmg    { "(bad)",	{ XX } },
2641247012Sjmg  },
2642247012Sjmg
2643247012Sjmg  /* PREGRP103 */
2644247012Sjmg  {
2645247012Sjmg    { "(bad)",	{ XX } },
2646247012Sjmg    { "(bad)",	{ XX } },
2647247012Sjmg    { "aesdec", { XM, EXx } },
2648247012Sjmg    { "(bad)",	{ XX } },
2649247012Sjmg  },
2650247012Sjmg
2651247012Sjmg  /* PREGRP104 */
2652247012Sjmg  {
2653247012Sjmg    { "(bad)",	{ XX } },
2654247012Sjmg    { "(bad)",	{ XX } },
2655247012Sjmg    { "aesdeclast", { XM, EXx } },
2656247012Sjmg    { "(bad)",	{ XX } },
2657247012Sjmg  },
2658247012Sjmg
2659247012Sjmg  /* PREGRP105 */
2660247012Sjmg  {
2661247012Sjmg    { "(bad)",	{ XX } },
2662247012Sjmg    { "(bad)",	{ XX } },
2663247012Sjmg    { "aeskeygenassist", { XM, EXx, Ib } },
2664247012Sjmg    { "(bad)",	{ XX } },
2665247012Sjmg  },
2666247012Sjmg
2667247012Sjmg  /* PREGRP106 */
2668247012Sjmg  {
2669247012Sjmg    { "(bad)",	{ XX } },
2670247012Sjmg    { "(bad)",	{ XX } },
2671247012Sjmg    { "pclmulqdq", { XM, EXx, Ib } },
2672247012Sjmg    { "(bad)",	{ XX } },
2673247012Sjmg  },
2674255192Sjhb
2675255192Sjhb  /* PREGRP107 */
2676255192Sjhb  {
2677255192Sjhb    { "(bad)",	{ XX } },
2678255192Sjhb    { "(bad)",	{ XX } },
2679255192Sjhb    { "invpcid",{ Gm, Mo } },
2680255192Sjhb    { "(bad)",	{ XX } },
2681255192Sjhb  },
268260484Sobrien};
268333965Sjdp
268485815Sobrienstatic const struct dis386 x86_64_table[][2] = {
268585815Sobrien  {
2686218822Sdim    { "pusha{P|}", { XX } },
2687218822Sdim    { "(bad)", { XX } },
268885815Sobrien  },
2689218822Sdim  {
2690218822Sdim    { "popa{P|}", { XX } },
2691218822Sdim    { "(bad)", { XX } },
2692218822Sdim  },
2693218822Sdim  {
2694218822Sdim    { "bound{S|}", { Gv, Ma } },
2695218822Sdim    { "(bad)", { XX } },
2696218822Sdim  },
2697218822Sdim  {
2698218822Sdim    { "arpl", { Ew, Gw } },
2699218822Sdim    { "movs{||lq|xd}", { Gv, Ed } },
2700218822Sdim  },
270185815Sobrien};
270285815Sobrien
2703218822Sdimstatic const struct dis386 three_byte_table[][256] = {
2704218822Sdim  /* THREE_BYTE_0 */
2705218822Sdim  {
2706218822Sdim    /* 00 */
2707218822Sdim    { "pshufb", { MX, EM } },
2708218822Sdim    { "phaddw", { MX, EM } },
2709218822Sdim    { "phaddd",	{ MX, EM } },
2710218822Sdim    { "phaddsw", { MX, EM } },
2711218822Sdim    { "pmaddubsw", { MX, EM } },
2712218822Sdim    { "phsubw", { MX, EM } },
2713218822Sdim    { "phsubd", { MX, EM } },
2714218822Sdim    { "phsubsw", { MX, EM } },
2715218822Sdim    /* 08 */
2716218822Sdim    { "psignb", { MX, EM } },
2717218822Sdim    { "psignw", { MX, EM } },
2718218822Sdim    { "psignd", { MX, EM } },
2719218822Sdim    { "pmulhrsw", { MX, EM } },
2720218822Sdim    { "(bad)", { XX } },
2721218822Sdim    { "(bad)", { XX } },
2722218822Sdim    { "(bad)", { XX } },
2723218822Sdim    { "(bad)", { XX } },
2724218822Sdim    /* 10 */
2725218822Sdim    { PREGRP39 },
2726218822Sdim    { "(bad)", { XX } },
2727218822Sdim    { "(bad)", { XX } },
2728218822Sdim    { "(bad)", { XX } },
2729218822Sdim    { PREGRP40 },
2730218822Sdim    { PREGRP41 },
2731218822Sdim    { "(bad)", { XX } },
2732218822Sdim    { PREGRP42 },
2733218822Sdim    /* 18 */
2734218822Sdim    { "(bad)", { XX } },
2735218822Sdim    { "(bad)", { XX } },
2736218822Sdim    { "(bad)", { XX } },
2737218822Sdim    { "(bad)", { XX } },
2738218822Sdim    { "pabsb", { MX, EM } },
2739218822Sdim    { "pabsw", { MX, EM } },
2740218822Sdim    { "pabsd", { MX, EM } },
2741218822Sdim    { "(bad)", { XX } },
2742218822Sdim    /* 20 */
2743218822Sdim    { PREGRP43 },
2744218822Sdim    { PREGRP44 },
2745218822Sdim    { PREGRP45 },
2746218822Sdim    { PREGRP46 },
2747218822Sdim    { PREGRP47 },
2748218822Sdim    { PREGRP48 },
2749218822Sdim    { "(bad)", { XX } },
2750218822Sdim    { "(bad)", { XX } },
2751218822Sdim    /* 28 */
2752218822Sdim    { PREGRP49 },
2753218822Sdim    { PREGRP50 },
2754218822Sdim    { PREGRP51 },
2755218822Sdim    { PREGRP52 },
2756218822Sdim    { "(bad)", { XX } },
2757218822Sdim    { "(bad)", { XX } },
2758218822Sdim    { "(bad)", { XX } },
2759218822Sdim    { "(bad)", { XX } },
2760218822Sdim    /* 30 */
2761218822Sdim    { PREGRP53 },
2762218822Sdim    { PREGRP54 },
2763218822Sdim    { PREGRP55 },
2764218822Sdim    { PREGRP56 },
2765218822Sdim    { PREGRP57 },
2766218822Sdim    { PREGRP58 },
2767218822Sdim    { "(bad)", { XX } },
2768218822Sdim    { PREGRP86 },
2769218822Sdim    /* 38 */
2770218822Sdim    { PREGRP59 },
2771218822Sdim    { PREGRP60 },
2772218822Sdim    { PREGRP61 },
2773218822Sdim    { PREGRP62 },
2774218822Sdim    { PREGRP63 },
2775218822Sdim    { PREGRP64 },
2776218822Sdim    { PREGRP65 },
2777218822Sdim    { PREGRP66 },
2778218822Sdim    /* 40 */
2779218822Sdim    { PREGRP67 },
2780218822Sdim    { PREGRP68 },
2781218822Sdim    { "(bad)", { XX } },
2782218822Sdim    { "(bad)", { XX } },
2783218822Sdim    { "(bad)", { XX } },
2784218822Sdim    { "(bad)", { XX } },
2785218822Sdim    { "(bad)", { XX } },
2786218822Sdim    { "(bad)", { XX } },
2787218822Sdim    /* 48 */
2788218822Sdim    { "(bad)", { XX } },
2789218822Sdim    { "(bad)", { XX } },
2790218822Sdim    { "(bad)", { XX } },
2791218822Sdim    { "(bad)", { XX } },
2792218822Sdim    { "(bad)", { XX } },
2793218822Sdim    { "(bad)", { XX } },
2794218822Sdim    { "(bad)", { XX } },
2795218822Sdim    { "(bad)", { XX } },
2796218822Sdim    /* 50 */
2797218822Sdim    { "(bad)", { XX } },
2798218822Sdim    { "(bad)", { XX } },
2799218822Sdim    { "(bad)", { XX } },
2800218822Sdim    { "(bad)", { XX } },
2801218822Sdim    { "(bad)", { XX } },
2802218822Sdim    { "(bad)", { XX } },
2803218822Sdim    { "(bad)", { XX } },
2804218822Sdim    { "(bad)", { XX } },
2805218822Sdim    /* 58 */
2806218822Sdim    { "(bad)", { XX } },
2807218822Sdim    { "(bad)", { XX } },
2808218822Sdim    { "(bad)", { XX } },
2809218822Sdim    { "(bad)", { XX } },
2810218822Sdim    { "(bad)", { XX } },
2811218822Sdim    { "(bad)", { XX } },
2812218822Sdim    { "(bad)", { XX } },
2813218822Sdim    { "(bad)", { XX } },
2814218822Sdim    /* 60 */
2815218822Sdim    { "(bad)", { XX } },
2816218822Sdim    { "(bad)", { XX } },
2817218822Sdim    { "(bad)", { XX } },
2818218822Sdim    { "(bad)", { XX } },
2819218822Sdim    { "(bad)", { XX } },
2820218822Sdim    { "(bad)", { XX } },
2821218822Sdim    { "(bad)", { XX } },
2822218822Sdim    { "(bad)", { XX } },
2823218822Sdim    /* 68 */
2824218822Sdim    { "(bad)", { XX } },
2825218822Sdim    { "(bad)", { XX } },
2826218822Sdim    { "(bad)", { XX } },
2827218822Sdim    { "(bad)", { XX } },
2828218822Sdim    { "(bad)", { XX } },
2829218822Sdim    { "(bad)", { XX } },
2830218822Sdim    { "(bad)", { XX } },
2831218822Sdim    { "(bad)", { XX } },
2832218822Sdim    /* 70 */
2833218822Sdim    { "(bad)", { XX } },
2834218822Sdim    { "(bad)", { XX } },
2835218822Sdim    { "(bad)", { XX } },
2836218822Sdim    { "(bad)", { XX } },
2837218822Sdim    { "(bad)", { XX } },
2838218822Sdim    { "(bad)", { XX } },
2839218822Sdim    { "(bad)", { XX } },
2840218822Sdim    { "(bad)", { XX } },
2841218822Sdim    /* 78 */
2842218822Sdim    { "(bad)", { XX } },
2843218822Sdim    { "(bad)", { XX } },
2844218822Sdim    { "(bad)", { XX } },
2845218822Sdim    { "(bad)", { XX } },
2846218822Sdim    { "(bad)", { XX } },
2847218822Sdim    { "(bad)", { XX } },
2848218822Sdim    { "(bad)", { XX } },
2849218822Sdim    { "(bad)", { XX } },
2850218822Sdim    /* 80 */
2851238167Sjhb    { PREGRP98 },
2852238167Sjhb    { PREGRP99 },
2853255192Sjhb    { PREGRP107 },
2854218822Sdim    { "(bad)", { XX } },
2855218822Sdim    { "(bad)", { XX } },
2856218822Sdim    { "(bad)", { XX } },
2857218822Sdim    { "(bad)", { XX } },
2858218822Sdim    { "(bad)", { XX } },
2859218822Sdim    /* 88 */
2860218822Sdim    { "(bad)", { XX } },
2861218822Sdim    { "(bad)", { XX } },
2862218822Sdim    { "(bad)", { XX } },
2863218822Sdim    { "(bad)", { XX } },
2864218822Sdim    { "(bad)", { XX } },
2865218822Sdim    { "(bad)", { XX } },
2866218822Sdim    { "(bad)", { XX } },
2867218822Sdim    { "(bad)", { XX } },
2868218822Sdim    /* 90 */
2869218822Sdim    { "(bad)", { XX } },
2870218822Sdim    { "(bad)", { XX } },
2871218822Sdim    { "(bad)", { XX } },
2872218822Sdim    { "(bad)", { XX } },
2873218822Sdim    { "(bad)", { XX } },
2874218822Sdim    { "(bad)", { XX } },
2875218822Sdim    { "(bad)", { XX } },
2876218822Sdim    { "(bad)", { XX } },
2877218822Sdim    /* 98 */
2878218822Sdim    { "(bad)", { XX } },
2879218822Sdim    { "(bad)", { XX } },
2880218822Sdim    { "(bad)", { XX } },
2881218822Sdim    { "(bad)", { XX } },
2882218822Sdim    { "(bad)", { XX } },
2883218822Sdim    { "(bad)", { XX } },
2884218822Sdim    { "(bad)", { XX } },
2885218822Sdim    { "(bad)", { XX } },
2886218822Sdim    /* a0 */
2887218822Sdim    { "(bad)", { XX } },
2888218822Sdim    { "(bad)", { XX } },
2889218822Sdim    { "(bad)", { XX } },
2890218822Sdim    { "(bad)", { XX } },
2891218822Sdim    { "(bad)", { XX } },
2892218822Sdim    { "(bad)", { XX } },
2893218822Sdim    { "(bad)", { XX } },
2894218822Sdim    { "(bad)", { XX } },
2895218822Sdim    /* a8 */
2896218822Sdim    { "(bad)", { XX } },
2897218822Sdim    { "(bad)", { XX } },
2898218822Sdim    { "(bad)", { XX } },
2899218822Sdim    { "(bad)", { XX } },
2900218822Sdim    { "(bad)", { XX } },
2901218822Sdim    { "(bad)", { XX } },
2902218822Sdim    { "(bad)", { XX } },
2903218822Sdim    { "(bad)", { XX } },
2904218822Sdim    /* b0 */
2905218822Sdim    { "(bad)", { XX } },
2906218822Sdim    { "(bad)", { XX } },
2907218822Sdim    { "(bad)", { XX } },
2908218822Sdim    { "(bad)", { XX } },
2909218822Sdim    { "(bad)", { XX } },
2910218822Sdim    { "(bad)", { XX } },
2911218822Sdim    { "(bad)", { XX } },
2912218822Sdim    { "(bad)", { XX } },
2913218822Sdim    /* b8 */
2914218822Sdim    { "(bad)", { XX } },
2915218822Sdim    { "(bad)", { XX } },
2916218822Sdim    { "(bad)", { XX } },
2917218822Sdim    { "(bad)", { XX } },
2918218822Sdim    { "(bad)", { XX } },
2919218822Sdim    { "(bad)", { XX } },
2920218822Sdim    { "(bad)", { XX } },
2921218822Sdim    { "(bad)", { XX } },
2922218822Sdim    /* c0 */
2923218822Sdim    { "(bad)", { XX } },
2924218822Sdim    { "(bad)", { XX } },
2925218822Sdim    { "(bad)", { XX } },
2926218822Sdim    { "(bad)", { XX } },
2927218822Sdim    { "(bad)", { XX } },
2928218822Sdim    { "(bad)", { XX } },
2929218822Sdim    { "(bad)", { XX } },
2930218822Sdim    { "(bad)", { XX } },
2931218822Sdim    /* c8 */
2932218822Sdim    { "(bad)", { XX } },
2933218822Sdim    { "(bad)", { XX } },
2934218822Sdim    { "(bad)", { XX } },
2935218822Sdim    { "(bad)", { XX } },
2936218822Sdim    { "(bad)", { XX } },
2937218822Sdim    { "(bad)", { XX } },
2938218822Sdim    { "(bad)", { XX } },
2939218822Sdim    { "(bad)", { XX } },
2940218822Sdim    /* d0 */
2941218822Sdim    { "(bad)", { XX } },
2942218822Sdim    { "(bad)", { XX } },
2943218822Sdim    { "(bad)", { XX } },
2944218822Sdim    { "(bad)", { XX } },
2945218822Sdim    { "(bad)", { XX } },
2946218822Sdim    { "(bad)", { XX } },
2947218822Sdim    { "(bad)", { XX } },
2948218822Sdim    { "(bad)", { XX } },
2949218822Sdim    /* d8 */
2950218822Sdim    { "(bad)", { XX } },
2951218822Sdim    { "(bad)", { XX } },
2952218822Sdim    { "(bad)", { XX } },
2953247012Sjmg    { PREGRP100 },
2954247012Sjmg    { PREGRP101 },
2955247012Sjmg    { PREGRP102 },
2956247012Sjmg    { PREGRP103 },
2957247012Sjmg    { PREGRP104 },
2958218822Sdim    /* e0 */
2959218822Sdim    { "(bad)", { XX } },
2960218822Sdim    { "(bad)", { XX } },
2961218822Sdim    { "(bad)", { XX } },
2962218822Sdim    { "(bad)", { XX } },
2963218822Sdim    { "(bad)", { XX } },
2964218822Sdim    { "(bad)", { XX } },
2965218822Sdim    { "(bad)", { XX } },
2966218822Sdim    { "(bad)", { XX } },
2967218822Sdim    /* e8 */
2968218822Sdim    { "(bad)", { XX } },
2969218822Sdim    { "(bad)", { XX } },
2970218822Sdim    { "(bad)", { XX } },
2971218822Sdim    { "(bad)", { XX } },
2972218822Sdim    { "(bad)", { XX } },
2973218822Sdim    { "(bad)", { XX } },
2974218822Sdim    { "(bad)", { XX } },
2975218822Sdim    { "(bad)", { XX } },
2976218822Sdim    /* f0 */
2977218822Sdim    { PREGRP87 },
2978218822Sdim    { PREGRP88 },
2979218822Sdim    { "(bad)", { XX } },
2980218822Sdim    { "(bad)", { XX } },
2981218822Sdim    { "(bad)", { XX } },
2982218822Sdim    { "(bad)", { XX } },
2983218822Sdim    { "(bad)", { XX } },
2984218822Sdim    { "(bad)", { XX } },
2985218822Sdim    /* f8 */
2986218822Sdim    { "(bad)", { XX } },
2987218822Sdim    { "(bad)", { XX } },
2988218822Sdim    { "(bad)", { XX } },
2989218822Sdim    { "(bad)", { XX } },
2990218822Sdim    { "(bad)", { XX } },
2991218822Sdim    { "(bad)", { XX } },
2992218822Sdim    { "(bad)", { XX } },
2993218822Sdim    { "(bad)", { XX } },
2994218822Sdim  },
2995218822Sdim  /* THREE_BYTE_1 */
2996218822Sdim  {
2997218822Sdim    /* 00 */
2998218822Sdim    { "(bad)", { XX } },
2999218822Sdim    { "(bad)", { XX } },
3000218822Sdim    { "(bad)", { XX } },
3001218822Sdim    { "(bad)", { XX } },
3002218822Sdim    { "(bad)", { XX } },
3003218822Sdim    { "(bad)", { XX } },
3004218822Sdim    { "(bad)", { XX } },
3005218822Sdim    { "(bad)", { XX } },
3006218822Sdim    /* 08 */
3007218822Sdim    { PREGRP69 },
3008218822Sdim    { PREGRP70 },
3009218822Sdim    { PREGRP71 },
3010218822Sdim    { PREGRP72 },
3011218822Sdim    { PREGRP73 },
3012218822Sdim    { PREGRP74 },
3013218822Sdim    { PREGRP75 },
3014218822Sdim    { "palignr", { MX, EM, Ib } },
3015218822Sdim    /* 10 */
3016218822Sdim    { "(bad)", { XX } },
3017218822Sdim    { "(bad)", { XX } },
3018218822Sdim    { "(bad)", { XX } },
3019218822Sdim    { "(bad)", { XX } },
3020218822Sdim    { PREGRP76 },
3021218822Sdim    { PREGRP77 },
3022218822Sdim    { PREGRP78 },
3023218822Sdim    { PREGRP79 },
3024218822Sdim    /* 18 */
3025218822Sdim    { "(bad)", { XX } },
3026218822Sdim    { "(bad)", { XX } },
3027218822Sdim    { "(bad)", { XX } },
3028218822Sdim    { "(bad)", { XX } },
3029218822Sdim    { "(bad)", { XX } },
3030218822Sdim    { "(bad)", { XX } },
3031218822Sdim    { "(bad)", { XX } },
3032218822Sdim    { "(bad)", { XX } },
3033218822Sdim    /* 20 */
3034218822Sdim    { PREGRP80 },
3035218822Sdim    { PREGRP81 },
3036218822Sdim    { PREGRP82 },
3037218822Sdim    { "(bad)", { XX } },
3038218822Sdim    { "(bad)", { XX } },
3039218822Sdim    { "(bad)", { XX } },
3040218822Sdim    { "(bad)", { XX } },
3041218822Sdim    { "(bad)", { XX } },
3042218822Sdim    /* 28 */
3043218822Sdim    { "(bad)", { XX } },
3044218822Sdim    { "(bad)", { XX } },
3045218822Sdim    { "(bad)", { XX } },
3046218822Sdim    { "(bad)", { XX } },
3047218822Sdim    { "(bad)", { XX } },
3048218822Sdim    { "(bad)", { XX } },
3049218822Sdim    { "(bad)", { XX } },
3050218822Sdim    { "(bad)", { XX } },
3051218822Sdim    /* 30 */
3052218822Sdim    { "(bad)", { XX } },
3053218822Sdim    { "(bad)", { XX } },
3054218822Sdim    { "(bad)", { XX } },
3055218822Sdim    { "(bad)", { XX } },
3056218822Sdim    { "(bad)", { XX } },
3057218822Sdim    { "(bad)", { XX } },
3058218822Sdim    { "(bad)", { XX } },
3059218822Sdim    { "(bad)", { XX } },
3060218822Sdim    /* 38 */
3061218822Sdim    { "(bad)", { XX } },
3062218822Sdim    { "(bad)", { XX } },
3063218822Sdim    { "(bad)", { XX } },
3064218822Sdim    { "(bad)", { XX } },
3065218822Sdim    { "(bad)", { XX } },
3066218822Sdim    { "(bad)", { XX } },
3067218822Sdim    { "(bad)", { XX } },
3068218822Sdim    { "(bad)", { XX } },
3069218822Sdim    /* 40 */
3070218822Sdim    { PREGRP83 },
3071218822Sdim    { PREGRP84 },
3072218822Sdim    { PREGRP85 },
3073218822Sdim    { "(bad)", { XX } },
3074247012Sjmg    { PREGRP106 },
3075218822Sdim    { "(bad)", { XX } },
3076218822Sdim    { "(bad)", { XX } },
3077218822Sdim    { "(bad)", { XX } },
3078218822Sdim    /* 48 */
3079218822Sdim    { "(bad)", { XX } },
3080218822Sdim    { "(bad)", { XX } },
3081218822Sdim    { "(bad)", { XX } },
3082218822Sdim    { "(bad)", { XX } },
3083218822Sdim    { "(bad)", { XX } },
3084218822Sdim    { "(bad)", { XX } },
3085218822Sdim    { "(bad)", { XX } },
3086218822Sdim    { "(bad)", { XX } },
3087218822Sdim    /* 50 */
3088218822Sdim    { "(bad)", { XX } },
3089218822Sdim    { "(bad)", { XX } },
3090218822Sdim    { "(bad)", { XX } },
3091218822Sdim    { "(bad)", { XX } },
3092218822Sdim    { "(bad)", { XX } },
3093218822Sdim    { "(bad)", { XX } },
3094218822Sdim    { "(bad)", { XX } },
3095218822Sdim    { "(bad)", { XX } },
3096218822Sdim    /* 58 */
3097218822Sdim    { "(bad)", { XX } },
3098218822Sdim    { "(bad)", { XX } },
3099218822Sdim    { "(bad)", { XX } },
3100218822Sdim    { "(bad)", { XX } },
3101218822Sdim    { "(bad)", { XX } },
3102218822Sdim    { "(bad)", { XX } },
3103218822Sdim    { "(bad)", { XX } },
3104218822Sdim    { "(bad)", { XX } },
3105218822Sdim    /* 60 */
3106218822Sdim    { PREGRP89 },
3107218822Sdim    { PREGRP90 },
3108218822Sdim    { PREGRP91 },
3109218822Sdim    { PREGRP92 },
3110218822Sdim    { "(bad)", { XX } },
3111218822Sdim    { "(bad)", { XX } },
3112218822Sdim    { "(bad)", { XX } },
3113218822Sdim    { "(bad)", { XX } },
3114218822Sdim    /* 68 */
3115218822Sdim    { "(bad)", { XX } },
3116218822Sdim    { "(bad)", { XX } },
3117218822Sdim    { "(bad)", { XX } },
3118218822Sdim    { "(bad)", { XX } },
3119218822Sdim    { "(bad)", { XX } },
3120218822Sdim    { "(bad)", { XX } },
3121218822Sdim    { "(bad)", { XX } },
3122218822Sdim    { "(bad)", { XX } },
3123218822Sdim    /* 70 */
3124218822Sdim    { "(bad)", { XX } },
3125218822Sdim    { "(bad)", { XX } },
3126218822Sdim    { "(bad)", { XX } },
3127218822Sdim    { "(bad)", { XX } },
3128218822Sdim    { "(bad)", { XX } },
3129218822Sdim    { "(bad)", { XX } },
3130218822Sdim    { "(bad)", { XX } },
3131218822Sdim    { "(bad)", { XX } },
3132218822Sdim    /* 78 */
3133218822Sdim    { "(bad)", { XX } },
3134218822Sdim    { "(bad)", { XX } },
3135218822Sdim    { "(bad)", { XX } },
3136218822Sdim    { "(bad)", { XX } },
3137218822Sdim    { "(bad)", { XX } },
3138218822Sdim    { "(bad)", { XX } },
3139218822Sdim    { "(bad)", { XX } },
3140218822Sdim    { "(bad)", { XX } },
3141218822Sdim    /* 80 */
3142218822Sdim    { "(bad)", { XX } },
3143218822Sdim    { "(bad)", { XX } },
3144218822Sdim    { "(bad)", { XX } },
3145218822Sdim    { "(bad)", { XX } },
3146218822Sdim    { "(bad)", { XX } },
3147218822Sdim    { "(bad)", { XX } },
3148218822Sdim    { "(bad)", { XX } },
3149218822Sdim    { "(bad)", { XX } },
3150218822Sdim    /* 88 */
3151218822Sdim    { "(bad)", { XX } },
3152218822Sdim    { "(bad)", { XX } },
3153218822Sdim    { "(bad)", { XX } },
3154218822Sdim    { "(bad)", { XX } },
3155218822Sdim    { "(bad)", { XX } },
3156218822Sdim    { "(bad)", { XX } },
3157218822Sdim    { "(bad)", { XX } },
3158218822Sdim    { "(bad)", { XX } },
3159218822Sdim    /* 90 */
3160218822Sdim    { "(bad)", { XX } },
3161218822Sdim    { "(bad)", { XX } },
3162218822Sdim    { "(bad)", { XX } },
3163218822Sdim    { "(bad)", { XX } },
3164218822Sdim    { "(bad)", { XX } },
3165218822Sdim    { "(bad)", { XX } },
3166218822Sdim    { "(bad)", { XX } },
3167218822Sdim    { "(bad)", { XX } },
3168218822Sdim    /* 98 */
3169218822Sdim    { "(bad)", { XX } },
3170218822Sdim    { "(bad)", { XX } },
3171218822Sdim    { "(bad)", { XX } },
3172218822Sdim    { "(bad)", { XX } },
3173218822Sdim    { "(bad)", { XX } },
3174218822Sdim    { "(bad)", { XX } },
3175218822Sdim    { "(bad)", { XX } },
3176218822Sdim    { "(bad)", { XX } },
3177218822Sdim    /* a0 */
3178218822Sdim    { "(bad)", { XX } },
3179218822Sdim    { "(bad)", { XX } },
3180218822Sdim    { "(bad)", { XX } },
3181218822Sdim    { "(bad)", { XX } },
3182218822Sdim    { "(bad)", { XX } },
3183218822Sdim    { "(bad)", { XX } },
3184218822Sdim    { "(bad)", { XX } },
3185218822Sdim    { "(bad)", { XX } },
3186218822Sdim    /* a8 */
3187218822Sdim    { "(bad)", { XX } },
3188218822Sdim    { "(bad)", { XX } },
3189218822Sdim    { "(bad)", { XX } },
3190218822Sdim    { "(bad)", { XX } },
3191218822Sdim    { "(bad)", { XX } },
3192218822Sdim    { "(bad)", { XX } },
3193218822Sdim    { "(bad)", { XX } },
3194218822Sdim    { "(bad)", { XX } },
3195218822Sdim    /* b0 */
3196218822Sdim    { "(bad)", { XX } },
3197218822Sdim    { "(bad)", { XX } },
3198218822Sdim    { "(bad)", { XX } },
3199218822Sdim    { "(bad)", { XX } },
3200218822Sdim    { "(bad)", { XX } },
3201218822Sdim    { "(bad)", { XX } },
3202218822Sdim    { "(bad)", { XX } },
3203218822Sdim    { "(bad)", { XX } },
3204218822Sdim    /* b8 */
3205218822Sdim    { "(bad)", { XX } },
3206218822Sdim    { "(bad)", { XX } },
3207218822Sdim    { "(bad)", { XX } },
3208218822Sdim    { "(bad)", { XX } },
3209218822Sdim    { "(bad)", { XX } },
3210218822Sdim    { "(bad)", { XX } },
3211218822Sdim    { "(bad)", { XX } },
3212218822Sdim    { "(bad)", { XX } },
3213218822Sdim    /* c0 */
3214218822Sdim    { "(bad)", { XX } },
3215218822Sdim    { "(bad)", { XX } },
3216218822Sdim    { "(bad)", { XX } },
3217218822Sdim    { "(bad)", { XX } },
3218218822Sdim    { "(bad)", { XX } },
3219218822Sdim    { "(bad)", { XX } },
3220218822Sdim    { "(bad)", { XX } },
3221218822Sdim    { "(bad)", { XX } },
3222218822Sdim    /* c8 */
3223218822Sdim    { "(bad)", { XX } },
3224218822Sdim    { "(bad)", { XX } },
3225218822Sdim    { "(bad)", { XX } },
3226218822Sdim    { "(bad)", { XX } },
3227218822Sdim    { "(bad)", { XX } },
3228218822Sdim    { "(bad)", { XX } },
3229218822Sdim    { "(bad)", { XX } },
3230218822Sdim    { "(bad)", { XX } },
3231218822Sdim    /* d0 */
3232218822Sdim    { "(bad)", { XX } },
3233218822Sdim    { "(bad)", { XX } },
3234218822Sdim    { "(bad)", { XX } },
3235218822Sdim    { "(bad)", { XX } },
3236218822Sdim    { "(bad)", { XX } },
3237218822Sdim    { "(bad)", { XX } },
3238218822Sdim    { "(bad)", { XX } },
3239218822Sdim    { "(bad)", { XX } },
3240218822Sdim    /* d8 */
3241218822Sdim    { "(bad)", { XX } },
3242218822Sdim    { "(bad)", { XX } },
3243218822Sdim    { "(bad)", { XX } },
3244218822Sdim    { "(bad)", { XX } },
3245218822Sdim    { "(bad)", { XX } },
3246218822Sdim    { "(bad)", { XX } },
3247218822Sdim    { "(bad)", { XX } },
3248247012Sjmg    { PREGRP105 },
3249218822Sdim    /* e0 */
3250218822Sdim    { "(bad)", { XX } },
3251218822Sdim    { "(bad)", { XX } },
3252218822Sdim    { "(bad)", { XX } },
3253218822Sdim    { "(bad)", { XX } },
3254218822Sdim    { "(bad)", { XX } },
3255218822Sdim    { "(bad)", { XX } },
3256218822Sdim    { "(bad)", { XX } },
3257218822Sdim    { "(bad)", { XX } },
3258218822Sdim    /* e8 */
3259218822Sdim    { "(bad)", { XX } },
3260218822Sdim    { "(bad)", { XX } },
3261218822Sdim    { "(bad)", { XX } },
3262218822Sdim    { "(bad)", { XX } },
3263218822Sdim    { "(bad)", { XX } },
3264218822Sdim    { "(bad)", { XX } },
3265218822Sdim    { "(bad)", { XX } },
3266218822Sdim    { "(bad)", { XX } },
3267218822Sdim    /* f0 */
3268218822Sdim    { "(bad)", { XX } },
3269218822Sdim    { "(bad)", { XX } },
3270218822Sdim    { "(bad)", { XX } },
3271218822Sdim    { "(bad)", { XX } },
3272218822Sdim    { "(bad)", { XX } },
3273218822Sdim    { "(bad)", { XX } },
3274218822Sdim    { "(bad)", { XX } },
3275218822Sdim    { "(bad)", { XX } },
3276218822Sdim    /* f8 */
3277218822Sdim    { "(bad)", { XX } },
3278218822Sdim    { "(bad)", { XX } },
3279218822Sdim    { "(bad)", { XX } },
3280218822Sdim    { "(bad)", { XX } },
3281218822Sdim    { "(bad)", { XX } },
3282218822Sdim    { "(bad)", { XX } },
3283218822Sdim    { "(bad)", { XX } },
3284218822Sdim    { "(bad)", { XX } },
3285218822Sdim  }
3286218822Sdim};
3287218822Sdim
328860484Sobrien#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
328933965Sjdp
329033965Sjdpstatic void
3291130561Sobrienckprefix (void)
329233965Sjdp{
329377298Sobrien  int newrex;
329477298Sobrien  rex = 0;
329533965Sjdp  prefixes = 0;
329660484Sobrien  used_prefixes = 0;
329777298Sobrien  rex_used = 0;
329833965Sjdp  while (1)
329933965Sjdp    {
3300223262Sbenl      (void) FETCH_DATA (the_info, codep + 1);
330177298Sobrien      newrex = 0;
330233965Sjdp      switch (*codep)
330333965Sjdp	{
330477298Sobrien	/* REX prefixes family.  */
330577298Sobrien	case 0x40:
330677298Sobrien	case 0x41:
330777298Sobrien	case 0x42:
330877298Sobrien	case 0x43:
330977298Sobrien	case 0x44:
331077298Sobrien	case 0x45:
331177298Sobrien	case 0x46:
331277298Sobrien	case 0x47:
331377298Sobrien	case 0x48:
331477298Sobrien	case 0x49:
331577298Sobrien	case 0x4a:
331677298Sobrien	case 0x4b:
331777298Sobrien	case 0x4c:
331877298Sobrien	case 0x4d:
331977298Sobrien	case 0x4e:
332077298Sobrien	case 0x4f:
3321218822Sdim	    if (address_mode == mode_64bit)
332277298Sobrien	      newrex = *codep;
332377298Sobrien	    else
332477298Sobrien	      return;
332577298Sobrien	  break;
332633965Sjdp	case 0xf3:
332733965Sjdp	  prefixes |= PREFIX_REPZ;
332833965Sjdp	  break;
332933965Sjdp	case 0xf2:
333033965Sjdp	  prefixes |= PREFIX_REPNZ;
333133965Sjdp	  break;
333233965Sjdp	case 0xf0:
333333965Sjdp	  prefixes |= PREFIX_LOCK;
333433965Sjdp	  break;
333533965Sjdp	case 0x2e:
333633965Sjdp	  prefixes |= PREFIX_CS;
333733965Sjdp	  break;
333833965Sjdp	case 0x36:
333933965Sjdp	  prefixes |= PREFIX_SS;
334033965Sjdp	  break;
334133965Sjdp	case 0x3e:
334233965Sjdp	  prefixes |= PREFIX_DS;
334333965Sjdp	  break;
334433965Sjdp	case 0x26:
334533965Sjdp	  prefixes |= PREFIX_ES;
334633965Sjdp	  break;
334733965Sjdp	case 0x64:
334833965Sjdp	  prefixes |= PREFIX_FS;
334933965Sjdp	  break;
335033965Sjdp	case 0x65:
335133965Sjdp	  prefixes |= PREFIX_GS;
335233965Sjdp	  break;
335333965Sjdp	case 0x66:
335433965Sjdp	  prefixes |= PREFIX_DATA;
335533965Sjdp	  break;
335633965Sjdp	case 0x67:
335760484Sobrien	  prefixes |= PREFIX_ADDR;
335833965Sjdp	  break;
335960484Sobrien	case FWAIT_OPCODE:
336060484Sobrien	  /* fwait is really an instruction.  If there are prefixes
336160484Sobrien	     before the fwait, they belong to the fwait, *not* to the
336260484Sobrien	     following instruction.  */
3363218822Sdim	  if (prefixes || rex)
336460484Sobrien	    {
336560484Sobrien	      prefixes |= PREFIX_FWAIT;
336660484Sobrien	      codep++;
336760484Sobrien	      return;
336860484Sobrien	    }
336960484Sobrien	  prefixes = PREFIX_FWAIT;
337033965Sjdp	  break;
337133965Sjdp	default:
337233965Sjdp	  return;
337333965Sjdp	}
337477298Sobrien      /* Rex is ignored when followed by another prefix.  */
337577298Sobrien      if (rex)
337677298Sobrien	{
3377218822Sdim	  rex_used = rex;
3378218822Sdim	  return;
337977298Sobrien	}
338077298Sobrien      rex = newrex;
338133965Sjdp      codep++;
338233965Sjdp    }
338333965Sjdp}
338433965Sjdp
338560484Sobrien/* Return the name of the prefix byte PREF, or NULL if PREF is not a
338660484Sobrien   prefix byte.  */
338760484Sobrien
338860484Sobrienstatic const char *
3389130561Sobrienprefix_name (int pref, int sizeflag)
339060484Sobrien{
3391218822Sdim  static const char *rexes [16] =
3392218822Sdim    {
3393218822Sdim      "rex",		/* 0x40 */
3394218822Sdim      "rex.B",		/* 0x41 */
3395218822Sdim      "rex.X",		/* 0x42 */
3396218822Sdim      "rex.XB",		/* 0x43 */
3397218822Sdim      "rex.R",		/* 0x44 */
3398218822Sdim      "rex.RB",		/* 0x45 */
3399218822Sdim      "rex.RX",		/* 0x46 */
3400218822Sdim      "rex.RXB",	/* 0x47 */
3401218822Sdim      "rex.W",		/* 0x48 */
3402218822Sdim      "rex.WB",		/* 0x49 */
3403218822Sdim      "rex.WX",		/* 0x4a */
3404218822Sdim      "rex.WXB",	/* 0x4b */
3405218822Sdim      "rex.WR",		/* 0x4c */
3406218822Sdim      "rex.WRB",	/* 0x4d */
3407218822Sdim      "rex.WRX",	/* 0x4e */
3408218822Sdim      "rex.WRXB",	/* 0x4f */
3409218822Sdim    };
3410218822Sdim
341160484Sobrien  switch (pref)
341260484Sobrien    {
341377298Sobrien    /* REX prefixes family.  */
341477298Sobrien    case 0x40:
341577298Sobrien    case 0x41:
341677298Sobrien    case 0x42:
341777298Sobrien    case 0x43:
341877298Sobrien    case 0x44:
341977298Sobrien    case 0x45:
342077298Sobrien    case 0x46:
342177298Sobrien    case 0x47:
342277298Sobrien    case 0x48:
342377298Sobrien    case 0x49:
342477298Sobrien    case 0x4a:
342577298Sobrien    case 0x4b:
342677298Sobrien    case 0x4c:
342777298Sobrien    case 0x4d:
342877298Sobrien    case 0x4e:
342977298Sobrien    case 0x4f:
3430218822Sdim      return rexes [pref - 0x40];
343160484Sobrien    case 0xf3:
343260484Sobrien      return "repz";
343360484Sobrien    case 0xf2:
343460484Sobrien      return "repnz";
343560484Sobrien    case 0xf0:
343660484Sobrien      return "lock";
343760484Sobrien    case 0x2e:
343860484Sobrien      return "cs";
343960484Sobrien    case 0x36:
344060484Sobrien      return "ss";
344160484Sobrien    case 0x3e:
344260484Sobrien      return "ds";
344360484Sobrien    case 0x26:
344460484Sobrien      return "es";
344560484Sobrien    case 0x64:
344660484Sobrien      return "fs";
344760484Sobrien    case 0x65:
344860484Sobrien      return "gs";
344960484Sobrien    case 0x66:
345060484Sobrien      return (sizeflag & DFLAG) ? "data16" : "data32";
345160484Sobrien    case 0x67:
3452218822Sdim      if (address_mode == mode_64bit)
3453130561Sobrien	return (sizeflag & AFLAG) ? "addr32" : "addr64";
345492828Sobrien      else
3455218822Sdim	return (sizeflag & AFLAG) ? "addr16" : "addr32";
345660484Sobrien    case FWAIT_OPCODE:
345760484Sobrien      return "fwait";
345860484Sobrien    default:
345960484Sobrien      return NULL;
346060484Sobrien    }
346160484Sobrien}
346260484Sobrien
3463218822Sdimstatic char op_out[MAX_OPERANDS][100];
3464218822Sdimstatic int op_ad, op_index[MAX_OPERANDS];
3465218822Sdimstatic int two_source_ops;
3466218822Sdimstatic bfd_vma op_address[MAX_OPERANDS];
3467218822Sdimstatic bfd_vma op_riprel[MAX_OPERANDS];
346877298Sobrienstatic bfd_vma start_pc;
3469218822Sdim
347033965Sjdp/*
347133965Sjdp *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
347233965Sjdp *   (see topic "Redundant prefixes" in the "Differences from 8086"
347333965Sjdp *   section of the "Virtual 8086 Mode" chapter.)
347433965Sjdp * 'pc' should be the address of this instruction, it will
347533965Sjdp *   be used to print the target address if this is a relative jump or call
347633965Sjdp * The function returns the length of this instruction in bytes.
347733965Sjdp */
347833965Sjdp
3479257464Ssbrunostatic int intel_syntax;
348060484Sobrienstatic char open_char;
348160484Sobrienstatic char close_char;
348260484Sobrienstatic char separator_char;
348360484Sobrienstatic char scale_char;
348460484Sobrien
348589857Sobrien/* Here for backwards compatibility.  When gdb stops using
348689857Sobrien   print_insn_i386_att and print_insn_i386_intel these functions can
348789857Sobrien   disappear, and print_insn_i386 be merged into print_insn.  */
348833965Sjdpint
3489130561Sobrienprint_insn_i386_att (bfd_vma pc, disassemble_info *info)
349033965Sjdp{
349160484Sobrien  intel_syntax = 0;
349260484Sobrien
349389857Sobrien  return print_insn (pc, info);
349433965Sjdp}
349533965Sjdp
349633965Sjdpint
3497130561Sobrienprint_insn_i386_intel (bfd_vma pc, disassemble_info *info)
349833965Sjdp{
349960484Sobrien  intel_syntax = 1;
350060484Sobrien
350189857Sobrien  return print_insn (pc, info);
350260484Sobrien}
350360484Sobrien
350489857Sobrienint
3505130561Sobrienprint_insn_i386 (bfd_vma pc, disassemble_info *info)
350660484Sobrien{
350789857Sobrien  intel_syntax = -1;
350889857Sobrien
350989857Sobrien  return print_insn (pc, info);
351089857Sobrien}
351189857Sobrien
3512218822Sdimvoid
3513218822Sdimprint_i386_disassembler_options (FILE *stream)
3514218822Sdim{
3515218822Sdim  fprintf (stream, _("\n\
3516218822SdimThe following i386/x86-64 specific disassembler options are supported for use\n\
3517218822Sdimwith the -M switch (multiple options should be separated by commas):\n"));
3518218822Sdim
3519218822Sdim  fprintf (stream, _("  x86-64      Disassemble in 64bit mode\n"));
3520218822Sdim  fprintf (stream, _("  i386        Disassemble in 32bit mode\n"));
3521218822Sdim  fprintf (stream, _("  i8086       Disassemble in 16bit mode\n"));
3522218822Sdim  fprintf (stream, _("  att         Display instruction in AT&T syntax\n"));
3523218822Sdim  fprintf (stream, _("  intel       Display instruction in Intel syntax\n"));
3524218822Sdim  fprintf (stream, _("  addr64      Assume 64bit address size\n"));
3525218822Sdim  fprintf (stream, _("  addr32      Assume 32bit address size\n"));
3526218822Sdim  fprintf (stream, _("  addr16      Assume 16bit address size\n"));
3527218822Sdim  fprintf (stream, _("  data32      Assume 32bit data size\n"));
3528218822Sdim  fprintf (stream, _("  data16      Assume 16bit data size\n"));
3529218822Sdim  fprintf (stream, _("  suffix      Always display instruction suffix in AT&T syntax\n"));
3530218822Sdim}
3531218822Sdim
353289857Sobrienstatic int
3533130561Sobrienprint_insn (bfd_vma pc, disassemble_info *info)
353489857Sobrien{
353560484Sobrien  const struct dis386 *dp;
353633965Sjdp  int i;
3537218822Sdim  char *op_txt[MAX_OPERANDS];
353833965Sjdp  int needcomma;
3539218822Sdim  unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3540218822Sdim  unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
354189857Sobrien  int sizeflag;
354289857Sobrien  const char *p;
354333965Sjdp  struct dis_private priv;
3544218822Sdim  unsigned char op;
354533965Sjdp
3546218822Sdim  if (info->mach == bfd_mach_x86_64_intel_syntax
3547218822Sdim      || info->mach == bfd_mach_x86_64)
3548218822Sdim    address_mode = mode_64bit;
3549218822Sdim  else
3550218822Sdim    address_mode = mode_32bit;
355177298Sobrien
3552257464Ssbruno  if (intel_syntax == -1)
355389857Sobrien    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
355489857Sobrien		    || info->mach == bfd_mach_x86_64_intel_syntax);
355589857Sobrien
355660484Sobrien  if (info->mach == bfd_mach_i386_i386
355777298Sobrien      || info->mach == bfd_mach_x86_64
355877298Sobrien      || info->mach == bfd_mach_i386_i386_intel_syntax
355977298Sobrien      || info->mach == bfd_mach_x86_64_intel_syntax)
356089857Sobrien    priv.orig_sizeflag = AFLAG | DFLAG;
356160484Sobrien  else if (info->mach == bfd_mach_i386_i8086)
356289857Sobrien    priv.orig_sizeflag = 0;
356360484Sobrien  else
356460484Sobrien    abort ();
356533965Sjdp
356689857Sobrien  for (p = info->disassembler_options; p != NULL; )
356789857Sobrien    {
3568218822Sdim      if (CONST_STRNEQ (p, "x86-64"))
356989857Sobrien	{
3570218822Sdim	  address_mode = mode_64bit;
357189857Sobrien	  priv.orig_sizeflag = AFLAG | DFLAG;
357289857Sobrien	}
3573218822Sdim      else if (CONST_STRNEQ (p, "i386"))
357489857Sobrien	{
3575218822Sdim	  address_mode = mode_32bit;
357689857Sobrien	  priv.orig_sizeflag = AFLAG | DFLAG;
357789857Sobrien	}
3578218822Sdim      else if (CONST_STRNEQ (p, "i8086"))
357989857Sobrien	{
3580218822Sdim	  address_mode = mode_16bit;
358189857Sobrien	  priv.orig_sizeflag = 0;
358289857Sobrien	}
3583218822Sdim      else if (CONST_STRNEQ (p, "intel"))
358489857Sobrien	{
358589857Sobrien	  intel_syntax = 1;
358689857Sobrien	}
3587218822Sdim      else if (CONST_STRNEQ (p, "att"))
358889857Sobrien	{
358989857Sobrien	  intel_syntax = 0;
359089857Sobrien	}
3591218822Sdim      else if (CONST_STRNEQ (p, "addr"))
359289857Sobrien	{
3593218822Sdim	  if (address_mode == mode_64bit)
3594218822Sdim	    {
3595218822Sdim	      if (p[4] == '3' && p[5] == '2')
3596218822Sdim		priv.orig_sizeflag &= ~AFLAG;
3597218822Sdim	      else if (p[4] == '6' && p[5] == '4')
3598218822Sdim		priv.orig_sizeflag |= AFLAG;
3599218822Sdim	    }
3600218822Sdim	  else
3601218822Sdim	    {
3602218822Sdim	      if (p[4] == '1' && p[5] == '6')
3603218822Sdim		priv.orig_sizeflag &= ~AFLAG;
3604218822Sdim	      else if (p[4] == '3' && p[5] == '2')
3605218822Sdim		priv.orig_sizeflag |= AFLAG;
3606218822Sdim	    }
360789857Sobrien	}
3608218822Sdim      else if (CONST_STRNEQ (p, "data"))
360989857Sobrien	{
361089857Sobrien	  if (p[4] == '1' && p[5] == '6')
361189857Sobrien	    priv.orig_sizeflag &= ~DFLAG;
361289857Sobrien	  else if (p[4] == '3' && p[5] == '2')
361389857Sobrien	    priv.orig_sizeflag |= DFLAG;
361489857Sobrien	}
3615218822Sdim      else if (CONST_STRNEQ (p, "suffix"))
361689857Sobrien	priv.orig_sizeflag |= SUFFIX_ALWAYS;
361789857Sobrien
361889857Sobrien      p = strchr (p, ',');
361989857Sobrien      if (p != NULL)
362089857Sobrien	p++;
362189857Sobrien    }
362289857Sobrien
362389857Sobrien  if (intel_syntax)
362489857Sobrien    {
362589857Sobrien      names64 = intel_names64;
362689857Sobrien      names32 = intel_names32;
362789857Sobrien      names16 = intel_names16;
362889857Sobrien      names8 = intel_names8;
362989857Sobrien      names8rex = intel_names8rex;
363089857Sobrien      names_seg = intel_names_seg;
363189857Sobrien      index16 = intel_index16;
363289857Sobrien      open_char = '[';
363389857Sobrien      close_char = ']';
363489857Sobrien      separator_char = '+';
363589857Sobrien      scale_char = '*';
363689857Sobrien    }
363789857Sobrien  else
363889857Sobrien    {
363989857Sobrien      names64 = att_names64;
364089857Sobrien      names32 = att_names32;
364189857Sobrien      names16 = att_names16;
364289857Sobrien      names8 = att_names8;
364389857Sobrien      names8rex = att_names8rex;
364489857Sobrien      names_seg = att_names_seg;
364589857Sobrien      index16 = att_index16;
364689857Sobrien      open_char = '(';
364789857Sobrien      close_char =  ')';
364889857Sobrien      separator_char = ',';
364989857Sobrien      scale_char = ',';
365089857Sobrien    }
365189857Sobrien
365260484Sobrien  /* The output looks better if we put 7 bytes on a line, since that
365360484Sobrien     puts most long word instructions on a single line.  */
365460484Sobrien  info->bytes_per_line = 7;
365560484Sobrien
3656130561Sobrien  info->private_data = &priv;
365733965Sjdp  priv.max_fetched = priv.the_buffer;
365833965Sjdp  priv.insn_start = pc;
365933965Sjdp
366033965Sjdp  obuf[0] = 0;
3661218822Sdim  for (i = 0; i < MAX_OPERANDS; ++i)
3662218822Sdim    {
3663218822Sdim      op_out[i][0] = 0;
3664218822Sdim      op_index[i] = -1;
3665218822Sdim    }
366633965Sjdp
366733965Sjdp  the_info = info;
366833965Sjdp  start_pc = pc;
366989857Sobrien  start_codep = priv.the_buffer;
367089857Sobrien  codep = priv.the_buffer;
367160484Sobrien
367260484Sobrien  if (setjmp (priv.bailout) != 0)
367360484Sobrien    {
367460484Sobrien      const char *name;
367560484Sobrien
367660484Sobrien      /* Getting here means we tried for data but didn't get it.  That
367789857Sobrien	 means we have an incomplete instruction of some sort.  Just
367889857Sobrien	 print the first byte as a prefix or a .byte pseudo-op.  */
367989857Sobrien      if (codep > priv.the_buffer)
368060484Sobrien	{
368189857Sobrien	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
368260484Sobrien	  if (name != NULL)
368360484Sobrien	    (*info->fprintf_func) (info->stream, "%s", name);
368460484Sobrien	  else
368560484Sobrien	    {
368660484Sobrien	      /* Just print the first byte as a .byte instruction.  */
368760484Sobrien	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
368889857Sobrien				     (unsigned int) priv.the_buffer[0]);
368960484Sobrien	    }
369060484Sobrien
369160484Sobrien	  return 1;
369260484Sobrien	}
369360484Sobrien
369460484Sobrien      return -1;
369560484Sobrien    }
369660484Sobrien
369777298Sobrien  obufp = obuf;
369833965Sjdp  ckprefix ();
369933965Sjdp
370060484Sobrien  insn_codep = codep;
370189857Sobrien  sizeflag = priv.orig_sizeflag;
370260484Sobrien
3703223262Sbenl  (void) FETCH_DATA (info, codep + 1);
370460484Sobrien  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
370560484Sobrien
3706218822Sdim  if (((prefixes & PREFIX_FWAIT)
3707218822Sdim       && ((*codep < 0xd8) || (*codep > 0xdf)))
3708218822Sdim      || (rex && rex_used))
370933965Sjdp    {
371060484Sobrien      const char *name;
371160484Sobrien
3712218822Sdim      /* fwait not followed by floating point instruction, or rex followed
3713218822Sdim	 by other prefixes.  Print the first prefix.  */
371489857Sobrien      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
371560484Sobrien      if (name == NULL)
371660484Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
371760484Sobrien      (*info->fprintf_func) (info->stream, "%s", name);
371860484Sobrien      return 1;
371933965Sjdp    }
372060484Sobrien
3721218822Sdim  op = 0;
372233965Sjdp  if (*codep == 0x0f)
372333965Sjdp    {
3724218822Sdim      unsigned char threebyte;
3725223262Sbenl      (void) FETCH_DATA (info, codep + 2);
3726218822Sdim      threebyte = *++codep;
3727218822Sdim      dp = &dis386_twobyte[threebyte];
372833965Sjdp      need_modrm = twobyte_has_modrm[*codep];
3729218822Sdim      uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3730218822Sdim      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3731218822Sdim      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3732218822Sdim      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3733218822Sdim      codep++;
3734218822Sdim      if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3735218822Sdim	{
3736223262Sbenl	  (void) FETCH_DATA (info, codep + 2);
3737218822Sdim	  op = *codep++;
3738218822Sdim	  switch (threebyte)
3739218822Sdim	    {
3740218822Sdim	    case 0x38:
3741218822Sdim	      uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3742218822Sdim	      uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3743218822Sdim	      uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3744218822Sdim	      break;
3745218822Sdim	    case 0x3a:
3746218822Sdim	      uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3747218822Sdim	      uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3748218822Sdim	      uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3749218822Sdim	      break;
3750218822Sdim	    default:
3751218822Sdim	      break;
3752218822Sdim	    }
3753218822Sdim	}
375433965Sjdp    }
375533965Sjdp  else
375633965Sjdp    {
375785815Sobrien      dp = &dis386[*codep];
375833965Sjdp      need_modrm = onebyte_has_modrm[*codep];
3759218822Sdim      uses_DATA_prefix = 0;
3760218822Sdim      uses_REPNZ_prefix = 0;
3761218822Sdim      /* pause is 0xf3 0x90.  */
3762218822Sdim      uses_REPZ_prefix = *codep == 0x90;
3763218822Sdim      uses_LOCK_prefix = 0;
3764218822Sdim      codep++;
376533965Sjdp    }
376633965Sjdp
3767218822Sdim  if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
376860484Sobrien    {
376960484Sobrien      oappend ("repz ");
377060484Sobrien      used_prefixes |= PREFIX_REPZ;
377160484Sobrien    }
3772218822Sdim  if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
377360484Sobrien    {
377460484Sobrien      oappend ("repnz ");
377560484Sobrien      used_prefixes |= PREFIX_REPNZ;
377660484Sobrien    }
3777218822Sdim
3778218822Sdim  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
377960484Sobrien    {
378060484Sobrien      oappend ("lock ");
378160484Sobrien      used_prefixes |= PREFIX_LOCK;
378260484Sobrien    }
378360484Sobrien
378460484Sobrien  if (prefixes & PREFIX_ADDR)
378560484Sobrien    {
378660484Sobrien      sizeflag ^= AFLAG;
3787218822Sdim      if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
378878828Sobrien	{
3789218822Sdim	  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
379078828Sobrien	    oappend ("addr32 ");
379178828Sobrien	  else
379278828Sobrien	    oappend ("addr16 ");
379378828Sobrien	  used_prefixes |= PREFIX_ADDR;
379478828Sobrien	}
379560484Sobrien    }
379660484Sobrien
3797218822Sdim  if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
379878828Sobrien    {
379978828Sobrien      sizeflag ^= DFLAG;
3800218822Sdim      if (dp->op[2].bytemode == cond_jump_mode
3801218822Sdim	  && dp->op[0].bytemode == v_mode
380285815Sobrien	  && !intel_syntax)
380378828Sobrien	{
380478828Sobrien	  if (sizeflag & DFLAG)
380578828Sobrien	    oappend ("data32 ");
380678828Sobrien	  else
380778828Sobrien	    oappend ("data16 ");
380878828Sobrien	  used_prefixes |= PREFIX_DATA;
380978828Sobrien	}
381078828Sobrien    }
381178828Sobrien
3812218822Sdim  if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
381333965Sjdp    {
3814218822Sdim      dp = &three_byte_table[dp->op[1].bytemode][op];
3815218822Sdim      modrm.mod = (*codep >> 6) & 3;
3816218822Sdim      modrm.reg = (*codep >> 3) & 7;
3817218822Sdim      modrm.rm = *codep & 7;
3818218822Sdim    }
3819218822Sdim  else if (need_modrm)
3820218822Sdim    {
3821223262Sbenl      (void) FETCH_DATA (info, codep + 1);
3822218822Sdim      modrm.mod = (*codep >> 6) & 3;
3823218822Sdim      modrm.reg = (*codep >> 3) & 7;
3824218822Sdim      modrm.rm = *codep & 7;
382533965Sjdp    }
382633965Sjdp
3827218822Sdim  if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
382833965Sjdp    {
382960484Sobrien      dofloat (sizeflag);
383033965Sjdp    }
383133965Sjdp  else
383233965Sjdp    {
383377298Sobrien      int index;
383433965Sjdp      if (dp->name == NULL)
383560484Sobrien	{
3836218822Sdim	  switch (dp->op[0].bytemode)
383760484Sobrien	    {
383885815Sobrien	    case USE_GROUPS:
3839218822Sdim	      dp = &grps[dp->op[1].bytemode][modrm.reg];
384085815Sobrien	      break;
384185815Sobrien
384285815Sobrien	    case USE_PREFIX_USER_TABLE:
384385815Sobrien	      index = 0;
384485815Sobrien	      used_prefixes |= (prefixes & PREFIX_REPZ);
384585815Sobrien	      if (prefixes & PREFIX_REPZ)
384685815Sobrien		index = 1;
384785815Sobrien	      else
384885815Sobrien		{
3849218822Sdim		  /* We should check PREFIX_REPNZ and PREFIX_REPZ
3850218822Sdim		     before PREFIX_DATA.  */
3851218822Sdim		  used_prefixes |= (prefixes & PREFIX_REPNZ);
3852218822Sdim		  if (prefixes & PREFIX_REPNZ)
3853218822Sdim		    index = 3;
385485815Sobrien		  else
385585815Sobrien		    {
3856218822Sdim		      used_prefixes |= (prefixes & PREFIX_DATA);
3857218822Sdim		      if (prefixes & PREFIX_DATA)
3858218822Sdim			index = 2;
385985815Sobrien		    }
386085815Sobrien		}
3861218822Sdim	      dp = &prefix_user_table[dp->op[1].bytemode][index];
386285815Sobrien	      break;
386385815Sobrien
386485815Sobrien	    case X86_64_SPECIAL:
3865218822Sdim	      index = address_mode == mode_64bit ? 1 : 0;
3866218822Sdim	      dp = &x86_64_table[dp->op[1].bytemode][index];
386785815Sobrien	      break;
386885815Sobrien
386985815Sobrien	    default:
387085815Sobrien	      oappend (INTERNAL_DISASSEMBLER_ERROR);
387185815Sobrien	      break;
387260484Sobrien	    }
387360484Sobrien	}
387460484Sobrien
387585815Sobrien      if (putop (dp->name, sizeflag) == 0)
3876218822Sdim        {
3877218822Sdim	  for (i = 0; i < MAX_OPERANDS; ++i)
3878218822Sdim	    {
3879218822Sdim	      obufp = op_out[i];
3880218822Sdim	      op_ad = MAX_OPERANDS - 1 - i;
3881218822Sdim	      if (dp->op[i].rtn)
3882218822Sdim		(*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3883218822Sdim	    }
388485815Sobrien	}
388533965Sjdp    }
388660484Sobrien
388760484Sobrien  /* See if any prefixes were not used.  If so, print the first one
388860484Sobrien     separately.  If we don't do this, we'll wind up printing an
388960484Sobrien     instruction stream which does not precisely correspond to the
389060484Sobrien     bytes we are disassembling.  */
389160484Sobrien  if ((prefixes & ~used_prefixes) != 0)
389260484Sobrien    {
389360484Sobrien      const char *name;
389460484Sobrien
389589857Sobrien      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
389660484Sobrien      if (name == NULL)
389760484Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
389860484Sobrien      (*info->fprintf_func) (info->stream, "%s", name);
389960484Sobrien      return 1;
390060484Sobrien    }
390177298Sobrien  if (rex & ~rex_used)
390277298Sobrien    {
390377298Sobrien      const char *name;
390489857Sobrien      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
390577298Sobrien      if (name == NULL)
390677298Sobrien	name = INTERNAL_DISASSEMBLER_ERROR;
390777298Sobrien      (*info->fprintf_func) (info->stream, "%s ", name);
390877298Sobrien    }
390960484Sobrien
391033965Sjdp  obufp = obuf + strlen (obuf);
391133965Sjdp  for (i = strlen (obuf); i < 6; i++)
391233965Sjdp    oappend (" ");
391333965Sjdp  oappend (" ");
391433965Sjdp  (*info->fprintf_func) (info->stream, "%s", obuf);
391560484Sobrien
391660484Sobrien  /* The enter and bound instructions are printed with operands in the same
391760484Sobrien     order as the intel book; everything else is printed in reverse order.  */
391860484Sobrien  if (intel_syntax || two_source_ops)
391933965Sjdp    {
3920218822Sdim      bfd_vma riprel;
3921218822Sdim
3922218822Sdim      for (i = 0; i < MAX_OPERANDS; ++i)
3923218822Sdim        op_txt[i] = op_out[i];
3924218822Sdim
3925218822Sdim      for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3926218822Sdim	{
3927218822Sdim          op_ad = op_index[i];
3928218822Sdim          op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3929218822Sdim          op_index[MAX_OPERANDS - 1 - i] = op_ad;
3930218822Sdim	  riprel = op_riprel[i];
3931218822Sdim	  op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
3932218822Sdim	  op_riprel[MAX_OPERANDS - 1 - i] = riprel;
3933218822Sdim	}
393433965Sjdp    }
393533965Sjdp  else
393633965Sjdp    {
3937218822Sdim      for (i = 0; i < MAX_OPERANDS; ++i)
3938218822Sdim        op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
393933965Sjdp    }
3940218822Sdim
394133965Sjdp  needcomma = 0;
3942218822Sdim  for (i = 0; i < MAX_OPERANDS; ++i)
3943218822Sdim    if (*op_txt[i])
3944218822Sdim      {
3945218822Sdim	if (needcomma)
3946218822Sdim	  (*info->fprintf_func) (info->stream, ",");
3947218822Sdim	if (op_index[i] != -1 && !op_riprel[i])
3948218822Sdim	  (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3949218822Sdim	else
3950218822Sdim	  (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3951218822Sdim	needcomma = 1;
3952218822Sdim      }
3953218822Sdim
3954218822Sdim  for (i = 0; i < MAX_OPERANDS; i++)
395577298Sobrien    if (op_index[i] != -1 && op_riprel[i])
395677298Sobrien      {
395777298Sobrien	(*info->fprintf_func) (info->stream, "        # ");
395877298Sobrien	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
395977298Sobrien						+ op_address[op_index[i]]), info);
3960218822Sdim	break;
396177298Sobrien      }
396289857Sobrien  return codep - priv.the_buffer;
396333965Sjdp}
396433965Sjdp
396585815Sobrienstatic const char *float_mem[] = {
396633965Sjdp  /* d8 */
396785815Sobrien  "fadd{s||s|}",
396885815Sobrien  "fmul{s||s|}",
396985815Sobrien  "fcom{s||s|}",
397085815Sobrien  "fcomp{s||s|}",
397185815Sobrien  "fsub{s||s|}",
397285815Sobrien  "fsubr{s||s|}",
397385815Sobrien  "fdiv{s||s|}",
397485815Sobrien  "fdivr{s||s|}",
3975130561Sobrien  /* d9 */
397685815Sobrien  "fld{s||s|}",
397733965Sjdp  "(bad)",
397885815Sobrien  "fst{s||s|}",
397985815Sobrien  "fstp{s||s|}",
3980218822Sdim  "fldenvIC",
398133965Sjdp  "fldcw",
3982218822Sdim  "fNstenvIC",
398333965Sjdp  "fNstcw",
398433965Sjdp  /* da */
398585815Sobrien  "fiadd{l||l|}",
398685815Sobrien  "fimul{l||l|}",
398785815Sobrien  "ficom{l||l|}",
398885815Sobrien  "ficomp{l||l|}",
398985815Sobrien  "fisub{l||l|}",
399085815Sobrien  "fisubr{l||l|}",
399185815Sobrien  "fidiv{l||l|}",
399285815Sobrien  "fidivr{l||l|}",
399333965Sjdp  /* db */
399485815Sobrien  "fild{l||l|}",
3995130561Sobrien  "fisttp{l||l|}",
399685815Sobrien  "fist{l||l|}",
399785815Sobrien  "fistp{l||l|}",
399833965Sjdp  "(bad)",
399985815Sobrien  "fld{t||t|}",
400033965Sjdp  "(bad)",
400185815Sobrien  "fstp{t||t|}",
400233965Sjdp  /* dc */
400385815Sobrien  "fadd{l||l|}",
400485815Sobrien  "fmul{l||l|}",
400585815Sobrien  "fcom{l||l|}",
400685815Sobrien  "fcomp{l||l|}",
400785815Sobrien  "fsub{l||l|}",
400885815Sobrien  "fsubr{l||l|}",
400985815Sobrien  "fdiv{l||l|}",
401085815Sobrien  "fdivr{l||l|}",
401133965Sjdp  /* dd */
401285815Sobrien  "fld{l||l|}",
4013218822Sdim  "fisttp{ll||ll|}",
401485815Sobrien  "fst{l||l|}",
401585815Sobrien  "fstp{l||l|}",
4016218822Sdim  "frstorIC",
401733965Sjdp  "(bad)",
4018218822Sdim  "fNsaveIC",
401933965Sjdp  "fNstsw",
402033965Sjdp  /* de */
402133965Sjdp  "fiadd",
402233965Sjdp  "fimul",
402333965Sjdp  "ficom",
402433965Sjdp  "ficomp",
402533965Sjdp  "fisub",
402633965Sjdp  "fisubr",
402733965Sjdp  "fidiv",
402833965Sjdp  "fidivr",
402933965Sjdp  /* df */
403033965Sjdp  "fild",
4031130561Sobrien  "fisttp",
403233965Sjdp  "fist",
403333965Sjdp  "fistp",
403433965Sjdp  "fbld",
403585815Sobrien  "fild{ll||ll|}",
403633965Sjdp  "fbstp",
4037218822Sdim  "fistp{ll||ll|}",
403833965Sjdp};
403933965Sjdp
4040218822Sdimstatic const unsigned char float_mem_mode[] = {
4041218822Sdim  /* d8 */
4042218822Sdim  d_mode,
4043218822Sdim  d_mode,
4044218822Sdim  d_mode,
4045218822Sdim  d_mode,
4046218822Sdim  d_mode,
4047218822Sdim  d_mode,
4048218822Sdim  d_mode,
4049218822Sdim  d_mode,
4050218822Sdim  /* d9 */
4051218822Sdim  d_mode,
4052218822Sdim  0,
4053218822Sdim  d_mode,
4054218822Sdim  d_mode,
4055218822Sdim  0,
4056218822Sdim  w_mode,
4057218822Sdim  0,
4058218822Sdim  w_mode,
4059218822Sdim  /* da */
4060218822Sdim  d_mode,
4061218822Sdim  d_mode,
4062218822Sdim  d_mode,
4063218822Sdim  d_mode,
4064218822Sdim  d_mode,
4065218822Sdim  d_mode,
4066218822Sdim  d_mode,
4067218822Sdim  d_mode,
4068218822Sdim  /* db */
4069218822Sdim  d_mode,
4070218822Sdim  d_mode,
4071218822Sdim  d_mode,
4072218822Sdim  d_mode,
4073218822Sdim  0,
4074218822Sdim  t_mode,
4075218822Sdim  0,
4076218822Sdim  t_mode,
4077218822Sdim  /* dc */
4078218822Sdim  q_mode,
4079218822Sdim  q_mode,
4080218822Sdim  q_mode,
4081218822Sdim  q_mode,
4082218822Sdim  q_mode,
4083218822Sdim  q_mode,
4084218822Sdim  q_mode,
4085218822Sdim  q_mode,
4086218822Sdim  /* dd */
4087218822Sdim  q_mode,
4088218822Sdim  q_mode,
4089218822Sdim  q_mode,
4090218822Sdim  q_mode,
4091218822Sdim  0,
4092218822Sdim  0,
4093218822Sdim  0,
4094218822Sdim  w_mode,
4095218822Sdim  /* de */
4096218822Sdim  w_mode,
4097218822Sdim  w_mode,
4098218822Sdim  w_mode,
4099218822Sdim  w_mode,
4100218822Sdim  w_mode,
4101218822Sdim  w_mode,
4102218822Sdim  w_mode,
4103218822Sdim  w_mode,
4104218822Sdim  /* df */
4105218822Sdim  w_mode,
4106218822Sdim  w_mode,
4107218822Sdim  w_mode,
4108218822Sdim  w_mode,
4109218822Sdim  t_mode,
4110218822Sdim  q_mode,
4111218822Sdim  t_mode,
4112218822Sdim  q_mode
4113218822Sdim};
411433965Sjdp
4115218822Sdim#define ST { OP_ST, 0 }
4116218822Sdim#define STi { OP_STi, 0 }
411733965Sjdp
4118218822Sdim#define FGRPd9_2 NULL, { { NULL, 0 } }
4119218822Sdim#define FGRPd9_4 NULL, { { NULL, 1 } }
4120218822Sdim#define FGRPd9_5 NULL, { { NULL, 2 } }
4121218822Sdim#define FGRPd9_6 NULL, { { NULL, 3 } }
4122218822Sdim#define FGRPd9_7 NULL, { { NULL, 4 } }
4123218822Sdim#define FGRPda_5 NULL, { { NULL, 5 } }
4124218822Sdim#define FGRPdb_4 NULL, { { NULL, 6 } }
4125218822Sdim#define FGRPde_3 NULL, { { NULL, 7 } }
4126218822Sdim#define FGRPdf_4 NULL, { { NULL, 8 } }
4127218822Sdim
412860484Sobrienstatic const struct dis386 float_reg[][8] = {
412933965Sjdp  /* d8 */
413033965Sjdp  {
4131218822Sdim    { "fadd",	{ ST, STi } },
4132218822Sdim    { "fmul",	{ ST, STi } },
4133218822Sdim    { "fcom",	{ STi } },
4134218822Sdim    { "fcomp",	{ STi } },
4135218822Sdim    { "fsub",	{ ST, STi } },
4136218822Sdim    { "fsubr",	{ ST, STi } },
4137218822Sdim    { "fdiv",	{ ST, STi } },
4138218822Sdim    { "fdivr",	{ ST, STi } },
413933965Sjdp  },
414033965Sjdp  /* d9 */
414133965Sjdp  {
4142218822Sdim    { "fld",	{ STi } },
4143218822Sdim    { "fxch",	{ STi } },
414433965Sjdp    { FGRPd9_2 },
4145218822Sdim    { "(bad)",	{ XX } },
414633965Sjdp    { FGRPd9_4 },
414733965Sjdp    { FGRPd9_5 },
414833965Sjdp    { FGRPd9_6 },
414933965Sjdp    { FGRPd9_7 },
415033965Sjdp  },
415133965Sjdp  /* da */
415233965Sjdp  {
4153218822Sdim    { "fcmovb",	{ ST, STi } },
4154218822Sdim    { "fcmove",	{ ST, STi } },
4155218822Sdim    { "fcmovbe",{ ST, STi } },
4156218822Sdim    { "fcmovu",	{ ST, STi } },
4157218822Sdim    { "(bad)",	{ XX } },
415833965Sjdp    { FGRPda_5 },
4159218822Sdim    { "(bad)",	{ XX } },
4160218822Sdim    { "(bad)",	{ XX } },
416133965Sjdp  },
416233965Sjdp  /* db */
416333965Sjdp  {
4164218822Sdim    { "fcmovnb",{ ST, STi } },
4165218822Sdim    { "fcmovne",{ ST, STi } },
4166218822Sdim    { "fcmovnbe",{ ST, STi } },
4167218822Sdim    { "fcmovnu",{ ST, STi } },
416833965Sjdp    { FGRPdb_4 },
4169218822Sdim    { "fucomi",	{ ST, STi } },
4170218822Sdim    { "fcomi",	{ ST, STi } },
4171218822Sdim    { "(bad)",	{ XX } },
417233965Sjdp  },
417333965Sjdp  /* dc */
417433965Sjdp  {
4175218822Sdim    { "fadd",	{ STi, ST } },
4176218822Sdim    { "fmul",	{ STi, ST } },
4177218822Sdim    { "(bad)",	{ XX } },
4178218822Sdim    { "(bad)",	{ XX } },
4179218822Sdim#if SYSV386_COMPAT
4180218822Sdim    { "fsub",	{ STi, ST } },
4181218822Sdim    { "fsubr",	{ STi, ST } },
4182218822Sdim    { "fdiv",	{ STi, ST } },
4183218822Sdim    { "fdivr",	{ STi, ST } },
418460484Sobrien#else
4185218822Sdim    { "fsubr",	{ STi, ST } },
4186218822Sdim    { "fsub",	{ STi, ST } },
4187218822Sdim    { "fdivr",	{ STi, ST } },
4188218822Sdim    { "fdiv",	{ STi, ST } },
418960484Sobrien#endif
419033965Sjdp  },
419133965Sjdp  /* dd */
419233965Sjdp  {
4193218822Sdim    { "ffree",	{ STi } },
4194218822Sdim    { "(bad)",	{ XX } },
4195218822Sdim    { "fst",	{ STi } },
4196218822Sdim    { "fstp",	{ STi } },
4197218822Sdim    { "fucom",	{ STi } },
4198218822Sdim    { "fucomp",	{ STi } },
4199218822Sdim    { "(bad)",	{ XX } },
4200218822Sdim    { "(bad)",	{ XX } },
420133965Sjdp  },
420233965Sjdp  /* de */
420333965Sjdp  {
4204218822Sdim    { "faddp",	{ STi, ST } },
4205218822Sdim    { "fmulp",	{ STi, ST } },
4206218822Sdim    { "(bad)",	{ XX } },
420733965Sjdp    { FGRPde_3 },
4208218822Sdim#if SYSV386_COMPAT
4209218822Sdim    { "fsubp",	{ STi, ST } },
4210218822Sdim    { "fsubrp",	{ STi, ST } },
4211218822Sdim    { "fdivp",	{ STi, ST } },
4212218822Sdim    { "fdivrp",	{ STi, ST } },
421360484Sobrien#else
4214218822Sdim    { "fsubrp",	{ STi, ST } },
4215218822Sdim    { "fsubp",	{ STi, ST } },
4216218822Sdim    { "fdivrp",	{ STi, ST } },
4217218822Sdim    { "fdivp",	{ STi, ST } },
421860484Sobrien#endif
421933965Sjdp  },
422033965Sjdp  /* df */
422133965Sjdp  {
4222218822Sdim    { "ffreep",	{ STi } },
4223218822Sdim    { "(bad)",	{ XX } },
4224218822Sdim    { "(bad)",	{ XX } },
4225218822Sdim    { "(bad)",	{ XX } },
422633965Sjdp    { FGRPdf_4 },
4227218822Sdim    { "fucomip", { ST, STi } },
4228218822Sdim    { "fcomip", { ST, STi } },
4229218822Sdim    { "(bad)",	{ XX } },
423033965Sjdp  },
423133965Sjdp};
423233965Sjdp
423333965Sjdpstatic char *fgrps[][8] = {
423433965Sjdp  /* d9_2  0 */
423533965Sjdp  {
423633965Sjdp    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
423733965Sjdp  },
423833965Sjdp
423933965Sjdp  /* d9_4  1 */
424033965Sjdp  {
424133965Sjdp    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
424233965Sjdp  },
424333965Sjdp
424433965Sjdp  /* d9_5  2 */
424533965Sjdp  {
424633965Sjdp    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
424733965Sjdp  },
424833965Sjdp
424933965Sjdp  /* d9_6  3 */
425033965Sjdp  {
425133965Sjdp    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
425233965Sjdp  },
425333965Sjdp
425433965Sjdp  /* d9_7  4 */
425533965Sjdp  {
425633965Sjdp    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
425733965Sjdp  },
425833965Sjdp
425933965Sjdp  /* da_5  5 */
426033965Sjdp  {
426133965Sjdp    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
426233965Sjdp  },
426333965Sjdp
426433965Sjdp  /* db_4  6 */
426533965Sjdp  {
426633965Sjdp    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
426733965Sjdp    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
426833965Sjdp  },
426933965Sjdp
427033965Sjdp  /* de_3  7 */
427133965Sjdp  {
427233965Sjdp    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
427333965Sjdp  },
427433965Sjdp
427533965Sjdp  /* df_4  8 */
427633965Sjdp  {
427733965Sjdp    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
427833965Sjdp  },
427933965Sjdp};
428033965Sjdp
428133965Sjdpstatic void
4282130561Sobriendofloat (int sizeflag)
428333965Sjdp{
428460484Sobrien  const struct dis386 *dp;
428533965Sjdp  unsigned char floatop;
428660484Sobrien
428733965Sjdp  floatop = codep[-1];
428860484Sobrien
4289218822Sdim  if (modrm.mod != 3)
429033965Sjdp    {
4291218822Sdim      int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
4292218822Sdim
4293218822Sdim      putop (float_mem[fp_indx], sizeflag);
4294218822Sdim      obufp = op_out[0];
4295218822Sdim      op_ad = 2;
4296218822Sdim      OP_E (float_mem_mode[fp_indx], sizeflag);
429733965Sjdp      return;
429833965Sjdp    }
429985815Sobrien  /* Skip mod/rm byte.  */
430078828Sobrien  MODRM_CHECK;
430133965Sjdp  codep++;
430260484Sobrien
4303218822Sdim  dp = &float_reg[floatop - 0xd8][modrm.reg];
430433965Sjdp  if (dp->name == NULL)
430533965Sjdp    {
4306218822Sdim      putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
430760484Sobrien
430885815Sobrien      /* Instruction fnstsw is only one with strange arg.  */
430960484Sobrien      if (floatop == 0xdf && codep[-1] == 0xe0)
4310218822Sdim	strcpy (op_out[0], names16[0]);
431133965Sjdp    }
431233965Sjdp  else
431333965Sjdp    {
431460484Sobrien      putop (dp->name, sizeflag);
431560484Sobrien
4316218822Sdim      obufp = op_out[0];
4317218822Sdim      op_ad = 2;
4318218822Sdim      if (dp->op[0].rtn)
4319218822Sdim	(*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
4320218822Sdim
4321218822Sdim      obufp = op_out[1];
4322218822Sdim      op_ad = 1;
4323218822Sdim      if (dp->op[1].rtn)
4324218822Sdim	(*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
432533965Sjdp    }
432633965Sjdp}
432733965Sjdp
432860484Sobrienstatic void
4329130561SobrienOP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
433033965Sjdp{
4331257464Ssbruno  oappend (&"%st"[intel_syntax]);
433233965Sjdp}
433333965Sjdp
433460484Sobrienstatic void
4335130561SobrienOP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
433633965Sjdp{
4337218822Sdim  sprintf (scratchbuf, "%%st(%d)", modrm.rm);
433885815Sobrien  oappend (scratchbuf + intel_syntax);
433933965Sjdp}
434033965Sjdp
434185815Sobrien/* Capital letters in template are macros.  */
434285815Sobrienstatic int
4343130561Sobrienputop (const char *template, int sizeflag)
434433965Sjdp{
434560484Sobrien  const char *p;
4346218822Sdim  int alt = 0;
434760484Sobrien
434833965Sjdp  for (p = template; *p; p++)
434933965Sjdp    {
435033965Sjdp      switch (*p)
435133965Sjdp	{
435233965Sjdp	default:
435333965Sjdp	  *obufp++ = *p;
435433965Sjdp	  break;
435585815Sobrien	case '{':
435685815Sobrien	  alt = 0;
435785815Sobrien	  if (intel_syntax)
435885815Sobrien	    alt += 1;
4359218822Sdim	  if (address_mode == mode_64bit)
436085815Sobrien	    alt += 2;
436185815Sobrien	  while (alt != 0)
436285815Sobrien	    {
436385815Sobrien	      while (*++p != '|')
436485815Sobrien		{
436585815Sobrien		  if (*p == '}')
436685815Sobrien		    {
436785815Sobrien		      /* Alternative not valid.  */
436885815Sobrien		      strcpy (obuf, "(bad)");
436985815Sobrien		      obufp = obuf + 5;
437085815Sobrien		      return 1;
437185815Sobrien		    }
437285815Sobrien		  else if (*p == '\0')
437385815Sobrien		    abort ();
437485815Sobrien		}
437585815Sobrien	      alt--;
437685815Sobrien	    }
4377218822Sdim	  /* Fall through.  */
4378218822Sdim	case 'I':
4379218822Sdim	  alt = 1;
4380218822Sdim	  continue;
438185815Sobrien	case '|':
438285815Sobrien	  while (*++p != '}')
438385815Sobrien	    {
438485815Sobrien	      if (*p == '\0')
438585815Sobrien		abort ();
438685815Sobrien	    }
438785815Sobrien	  break;
438885815Sobrien	case '}':
438985815Sobrien	  break;
439060484Sobrien	case 'A':
4391130561Sobrien	  if (intel_syntax)
4392130561Sobrien	    break;
4393218822Sdim	  if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
439460484Sobrien	    *obufp++ = 'b';
439560484Sobrien	  break;
439660484Sobrien	case 'B':
4397130561Sobrien	  if (intel_syntax)
4398130561Sobrien	    break;
439960484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
440060484Sobrien	    *obufp++ = 'b';
440160484Sobrien	  break;
4402218822Sdim	case 'C':
4403218822Sdim	  if (intel_syntax && !alt)
4404218822Sdim	    break;
4405218822Sdim	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4406218822Sdim	    {
4407218822Sdim	      if (sizeflag & DFLAG)
4408218822Sdim		*obufp++ = intel_syntax ? 'd' : 'l';
4409218822Sdim	      else
4410218822Sdim		*obufp++ = intel_syntax ? 'w' : 's';
4411218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4412218822Sdim	    }
4413218822Sdim	  break;
4414218822Sdim	case 'D':
4415218822Sdim	  if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4416218822Sdim	    break;
4417218822Sdim	  USED_REX (REX_W);
4418218822Sdim	  if (modrm.mod == 3)
4419218822Sdim	    {
4420218822Sdim	      if (rex & REX_W)
4421218822Sdim		*obufp++ = 'q';
4422218822Sdim	      else if (sizeflag & DFLAG)
4423218822Sdim		*obufp++ = intel_syntax ? 'd' : 'l';
4424218822Sdim	      else
4425218822Sdim		*obufp++ = 'w';
4426218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4427218822Sdim	    }
4428218822Sdim	  else
4429218822Sdim	    *obufp++ = 'w';
4430218822Sdim	  break;
443160484Sobrien	case 'E':		/* For jcxz/jecxz */
4432218822Sdim	  if (address_mode == mode_64bit)
443392828Sobrien	    {
443492828Sobrien	      if (sizeflag & AFLAG)
443592828Sobrien		*obufp++ = 'r';
443692828Sobrien	      else
443792828Sobrien		*obufp++ = 'e';
443892828Sobrien	    }
443992828Sobrien	  else
444092828Sobrien	    if (sizeflag & AFLAG)
444192828Sobrien	      *obufp++ = 'e';
444278828Sobrien	  used_prefixes |= (prefixes & PREFIX_ADDR);
444333965Sjdp	  break;
444478828Sobrien	case 'F':
4445130561Sobrien	  if (intel_syntax)
4446130561Sobrien	    break;
444789857Sobrien	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
444878828Sobrien	    {
444978828Sobrien	      if (sizeflag & AFLAG)
4450218822Sdim		*obufp++ = address_mode == mode_64bit ? 'q' : 'l';
445178828Sobrien	      else
4452218822Sdim		*obufp++ = address_mode == mode_64bit ? 'l' : 'w';
445378828Sobrien	      used_prefixes |= (prefixes & PREFIX_ADDR);
445478828Sobrien	    }
445578828Sobrien	  break;
4456218822Sdim	case 'G':
4457218822Sdim	  if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4458218822Sdim	    break;
4459218822Sdim	  if ((rex & REX_W) || (sizeflag & DFLAG))
4460218822Sdim	    *obufp++ = 'l';
4461218822Sdim	  else
4462218822Sdim	    *obufp++ = 'w';
4463218822Sdim	  if (!(rex & REX_W))
4464218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
4465218822Sdim	  break;
446685815Sobrien	case 'H':
4467130561Sobrien	  if (intel_syntax)
4468130561Sobrien	    break;
446985815Sobrien	  if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
447085815Sobrien	      || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
447177298Sobrien	    {
447285815Sobrien	      used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
447385815Sobrien	      *obufp++ = ',';
447485815Sobrien	      *obufp++ = 'p';
447585815Sobrien	      if (prefixes & PREFIX_DS)
447685815Sobrien		*obufp++ = 't';
447785815Sobrien	      else
447885815Sobrien		*obufp++ = 'n';
447977298Sobrien	    }
448077298Sobrien	  break;
4481218822Sdim	case 'J':
4482218822Sdim	  if (intel_syntax)
4483218822Sdim	    break;
4484218822Sdim	  *obufp++ = 'l';
4485218822Sdim	  break;
4486218822Sdim	case 'K':
4487218822Sdim	  USED_REX (REX_W);
4488218822Sdim	  if (rex & REX_W)
4489218822Sdim	    *obufp++ = 'q';
4490218822Sdim	  else
4491218822Sdim	    *obufp++ = 'd';
4492218822Sdim	  break;
4493218822Sdim	case 'Z':
4494218822Sdim	  if (intel_syntax)
4495218822Sdim	    break;
4496218822Sdim	  if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4497218822Sdim	    {
4498218822Sdim	      *obufp++ = 'q';
4499218822Sdim	      break;
4500218822Sdim	    }
4501218822Sdim	  /* Fall through.  */
450260484Sobrien	case 'L':
4503130561Sobrien	  if (intel_syntax)
4504130561Sobrien	    break;
450560484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
450660484Sobrien	    *obufp++ = 'l';
450760484Sobrien	  break;
450833965Sjdp	case 'N':
450933965Sjdp	  if ((prefixes & PREFIX_FWAIT) == 0)
451033965Sjdp	    *obufp++ = 'n';
451160484Sobrien	  else
451260484Sobrien	    used_prefixes |= PREFIX_FWAIT;
451333965Sjdp	  break;
451477298Sobrien	case 'O':
4515218822Sdim	  USED_REX (REX_W);
4516218822Sdim	  if (rex & REX_W)
451785815Sobrien	    *obufp++ = 'o';
4518218822Sdim	  else if (intel_syntax && (sizeflag & DFLAG))
4519218822Sdim	    *obufp++ = 'q';
452077298Sobrien	  else
452177298Sobrien	    *obufp++ = 'd';
4522218822Sdim	  if (!(rex & REX_W))
4523218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
452477298Sobrien	  break;
452585815Sobrien	case 'T':
4526130561Sobrien	  if (intel_syntax)
4527130561Sobrien	    break;
4528218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
452985815Sobrien	    {
453085815Sobrien	      *obufp++ = 'q';
453185815Sobrien	      break;
453285815Sobrien	    }
453385815Sobrien	  /* Fall through.  */
453460484Sobrien	case 'P':
4535130561Sobrien	  if (intel_syntax)
4536130561Sobrien	    break;
453760484Sobrien	  if ((prefixes & PREFIX_DATA)
4538218822Sdim	      || (rex & REX_W)
453989857Sobrien	      || (sizeflag & SUFFIX_ALWAYS))
454060484Sobrien	    {
4541218822Sdim	      USED_REX (REX_W);
4542218822Sdim	      if (rex & REX_W)
454377298Sobrien		*obufp++ = 'q';
454478828Sobrien	      else
454577298Sobrien		{
454677298Sobrien		   if (sizeflag & DFLAG)
454777298Sobrien		      *obufp++ = 'l';
454877298Sobrien		   else
454977298Sobrien		     *obufp++ = 'w';
455077298Sobrien		}
4551218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
455260484Sobrien	    }
455360484Sobrien	  break;
455485815Sobrien	case 'U':
4555130561Sobrien	  if (intel_syntax)
4556130561Sobrien	    break;
4557218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
455885815Sobrien	    {
4559218822Sdim	      if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4560218822Sdim		*obufp++ = 'q';
456185815Sobrien	      break;
456285815Sobrien	    }
456385815Sobrien	  /* Fall through.  */
456460484Sobrien	case 'Q':
4565218822Sdim	  if (intel_syntax && !alt)
4566130561Sobrien	    break;
4567218822Sdim	  USED_REX (REX_W);
4568218822Sdim	  if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
456960484Sobrien	    {
4570218822Sdim	      if (rex & REX_W)
457177298Sobrien		*obufp++ = 'q';
457260484Sobrien	      else
457377298Sobrien		{
457477298Sobrien		  if (sizeflag & DFLAG)
4575218822Sdim		    *obufp++ = intel_syntax ? 'd' : 'l';
457677298Sobrien		  else
457777298Sobrien		    *obufp++ = 'w';
457877298Sobrien		}
4579218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
458060484Sobrien	    }
458160484Sobrien	  break;
458260484Sobrien	case 'R':
4583218822Sdim	  USED_REX (REX_W);
4584218822Sdim	  if (rex & REX_W)
4585218822Sdim	    *obufp++ = 'q';
4586218822Sdim	  else if (sizeflag & DFLAG)
458760484Sobrien	    {
4588218822Sdim	      if (intel_syntax)
458960484Sobrien		  *obufp++ = 'd';
459060484Sobrien	      else
4591218822Sdim		  *obufp++ = 'l';
459260484Sobrien	    }
459333965Sjdp	  else
4594218822Sdim	    *obufp++ = 'w';
4595218822Sdim	  if (intel_syntax && !p[1]
4596218822Sdim	      && ((rex & REX_W) || (sizeflag & DFLAG)))
4597218822Sdim	    *obufp++ = 'e';
4598218822Sdim	  if (!(rex & REX_W))
4599218822Sdim	    used_prefixes |= (prefixes & PREFIX_DATA);
4600218822Sdim	  break;
4601218822Sdim	case 'V':
4602218822Sdim	  if (intel_syntax)
4603218822Sdim	    break;
4604218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
460560484Sobrien	    {
4606218822Sdim	      if (sizeflag & SUFFIX_ALWAYS)
460777298Sobrien		*obufp++ = 'q';
4608218822Sdim	      break;
460960484Sobrien	    }
4610218822Sdim	  /* Fall through.  */
461160484Sobrien	case 'S':
4612130561Sobrien	  if (intel_syntax)
4613130561Sobrien	    break;
461460484Sobrien	  if (sizeflag & SUFFIX_ALWAYS)
461560484Sobrien	    {
4616218822Sdim	      if (rex & REX_W)
461777298Sobrien		*obufp++ = 'q';
461877298Sobrien	      else
461977298Sobrien		{
462077298Sobrien		  if (sizeflag & DFLAG)
462177298Sobrien		    *obufp++ = 'l';
462277298Sobrien		  else
462377298Sobrien		    *obufp++ = 'w';
462477298Sobrien		  used_prefixes |= (prefixes & PREFIX_DATA);
462577298Sobrien		}
462677298Sobrien	    }
462777298Sobrien	  break;
462877298Sobrien	case 'X':
462977298Sobrien	  if (prefixes & PREFIX_DATA)
463077298Sobrien	    *obufp++ = 'd';
463177298Sobrien	  else
463277298Sobrien	    *obufp++ = 's';
4633130561Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
463477298Sobrien	  break;
463577298Sobrien	case 'Y':
4636130561Sobrien	  if (intel_syntax)
4637130561Sobrien	    break;
4638218822Sdim	  if (rex & REX_W)
463977298Sobrien	    {
4640218822Sdim	      USED_REX (REX_W);
464177298Sobrien	      *obufp++ = 'q';
464277298Sobrien	    }
464377298Sobrien	  break;
464477298Sobrien	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
464538889Sjdp	case 'W':
464638889Sjdp	  /* operand size flag for cwtl, cbtw */
4647218822Sdim	  USED_REX (REX_W);
4648218822Sdim	  if (rex & REX_W)
4649218822Sdim	    {
4650218822Sdim	      if (intel_syntax)
4651218822Sdim		*obufp++ = 'd';
4652218822Sdim	      else
4653218822Sdim		*obufp++ = 'l';
4654218822Sdim	    }
465577298Sobrien	  else if (sizeflag & DFLAG)
465638889Sjdp	    *obufp++ = 'w';
465738889Sjdp	  else
465838889Sjdp	    *obufp++ = 'b';
4659218822Sdim	  if (!(rex & REX_W))
466077298Sobrien	    used_prefixes |= (prefixes & PREFIX_DATA);
466138889Sjdp	  break;
466233965Sjdp	}
4663218822Sdim      alt = 0;
466433965Sjdp    }
466533965Sjdp  *obufp = 0;
466685815Sobrien  return 0;
466733965Sjdp}
466833965Sjdp
466933965Sjdpstatic void
4670130561Sobrienoappend (const char *s)
467133965Sjdp{
467233965Sjdp  strcpy (obufp, s);
467333965Sjdp  obufp += strlen (s);
467433965Sjdp}
467533965Sjdp
467633965Sjdpstatic void
4677130561Sobrienappend_seg (void)
467833965Sjdp{
467933965Sjdp  if (prefixes & PREFIX_CS)
468060484Sobrien    {
468160484Sobrien      used_prefixes |= PREFIX_CS;
4682257464Ssbruno      oappend (&"%cs:"[intel_syntax]);
468360484Sobrien    }
468433965Sjdp  if (prefixes & PREFIX_DS)
468560484Sobrien    {
468660484Sobrien      used_prefixes |= PREFIX_DS;
4687257464Ssbruno      oappend (&"%ds:"[intel_syntax]);
468860484Sobrien    }
468933965Sjdp  if (prefixes & PREFIX_SS)
469060484Sobrien    {
469160484Sobrien      used_prefixes |= PREFIX_SS;
4692257464Ssbruno      oappend (&"%ss:"[intel_syntax]);
469360484Sobrien    }
469433965Sjdp  if (prefixes & PREFIX_ES)
469560484Sobrien    {
469660484Sobrien      used_prefixes |= PREFIX_ES;
4697257464Ssbruno      oappend (&"%es:"[intel_syntax]);
469860484Sobrien    }
469933965Sjdp  if (prefixes & PREFIX_FS)
470060484Sobrien    {
470160484Sobrien      used_prefixes |= PREFIX_FS;
4702257464Ssbruno      oappend (&"%fs:"[intel_syntax]);
470360484Sobrien    }
470433965Sjdp  if (prefixes & PREFIX_GS)
470560484Sobrien    {
470660484Sobrien      used_prefixes |= PREFIX_GS;
4707257464Ssbruno      oappend (&"%gs:"[intel_syntax]);
470860484Sobrien    }
470933965Sjdp}
471033965Sjdp
471160484Sobrienstatic void
4712130561SobrienOP_indirE (int bytemode, int sizeflag)
471333965Sjdp{
471460484Sobrien  if (!intel_syntax)
471560484Sobrien    oappend ("*");
471660484Sobrien  OP_E (bytemode, sizeflag);
471733965Sjdp}
471833965Sjdp
471960484Sobrienstatic void
4720130561Sobrienprint_operand_value (char *buf, int hex, bfd_vma disp)
472177298Sobrien{
4722218822Sdim  if (address_mode == mode_64bit)
472377298Sobrien    {
472477298Sobrien      if (hex)
472577298Sobrien	{
472677298Sobrien	  char tmp[30];
472777298Sobrien	  int i;
472877298Sobrien	  buf[0] = '0';
472977298Sobrien	  buf[1] = 'x';
473077298Sobrien	  sprintf_vma (tmp, disp);
473185815Sobrien	  for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
473277298Sobrien	  strcpy (buf + 2, tmp + i);
473377298Sobrien	}
473477298Sobrien      else
473577298Sobrien	{
473677298Sobrien	  bfd_signed_vma v = disp;
473777298Sobrien	  char tmp[30];
473877298Sobrien	  int i;
473977298Sobrien	  if (v < 0)
474077298Sobrien	    {
474177298Sobrien	      *(buf++) = '-';
474277298Sobrien	      v = -disp;
474385815Sobrien	      /* Check for possible overflow on 0x8000000000000000.  */
474477298Sobrien	      if (v < 0)
474577298Sobrien		{
474677298Sobrien		  strcpy (buf, "9223372036854775808");
474777298Sobrien		  return;
474877298Sobrien		}
474977298Sobrien	    }
475077298Sobrien	  if (!v)
475177298Sobrien	    {
475277298Sobrien	      strcpy (buf, "0");
475377298Sobrien	      return;
475477298Sobrien	    }
475577298Sobrien
475677298Sobrien	  i = 0;
475777298Sobrien	  tmp[29] = 0;
475877298Sobrien	  while (v)
475977298Sobrien	    {
476085815Sobrien	      tmp[28 - i] = (v % 10) + '0';
476177298Sobrien	      v /= 10;
476277298Sobrien	      i++;
476377298Sobrien	    }
476477298Sobrien	  strcpy (buf, tmp + 29 - i);
476577298Sobrien	}
476677298Sobrien    }
476777298Sobrien  else
476877298Sobrien    {
476977298Sobrien      if (hex)
477077298Sobrien	sprintf (buf, "0x%x", (unsigned int) disp);
477177298Sobrien      else
477277298Sobrien	sprintf (buf, "%d", (int) disp);
477377298Sobrien    }
477477298Sobrien}
477577298Sobrien
4776218822Sdim/* Put DISP in BUF as signed hex number.  */
4777218822Sdim
477877298Sobrienstatic void
4779218822Sdimprint_displacement (char *buf, bfd_vma disp)
4780218822Sdim{
4781218822Sdim  bfd_signed_vma val = disp;
4782218822Sdim  char tmp[30];
4783218822Sdim  int i, j = 0;
4784218822Sdim
4785218822Sdim  if (val < 0)
4786218822Sdim    {
4787218822Sdim      buf[j++] = '-';
4788218822Sdim      val = -disp;
4789218822Sdim
4790218822Sdim      /* Check for possible overflow.  */
4791218822Sdim      if (val < 0)
4792218822Sdim	{
4793218822Sdim	  switch (address_mode)
4794218822Sdim	    {
4795218822Sdim	    case mode_64bit:
4796218822Sdim	      strcpy (buf + j, "0x8000000000000000");
4797218822Sdim	      break;
4798218822Sdim	    case mode_32bit:
4799218822Sdim	      strcpy (buf + j, "0x80000000");
4800218822Sdim	      break;
4801218822Sdim	    case mode_16bit:
4802218822Sdim	      strcpy (buf + j, "0x8000");
4803218822Sdim	      break;
4804218822Sdim	    }
4805218822Sdim	  return;
4806218822Sdim	}
4807218822Sdim    }
4808218822Sdim
4809218822Sdim  buf[j++] = '0';
4810218822Sdim  buf[j++] = 'x';
4811218822Sdim
4812218822Sdim  sprintf_vma (tmp, val);
4813218822Sdim  for (i = 0; tmp[i] == '0'; i++)
4814218822Sdim    continue;
4815218822Sdim  if (tmp[i] == '\0')
4816218822Sdim    i--;
4817218822Sdim  strcpy (buf + j, tmp + i);
4818218822Sdim}
4819218822Sdim
4820218822Sdimstatic void
4821218822Sdimintel_operand_size (int bytemode, int sizeflag)
4822218822Sdim{
4823218822Sdim  switch (bytemode)
4824218822Sdim    {
4825218822Sdim    case b_mode:
4826218822Sdim    case dqb_mode:
4827218822Sdim      oappend ("BYTE PTR ");
4828218822Sdim      break;
4829218822Sdim    case w_mode:
4830218822Sdim    case dqw_mode:
4831218822Sdim      oappend ("WORD PTR ");
4832218822Sdim      break;
4833218822Sdim    case stack_v_mode:
4834218822Sdim      if (address_mode == mode_64bit && (sizeflag & DFLAG))
4835218822Sdim	{
4836218822Sdim	  oappend ("QWORD PTR ");
4837218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
4838218822Sdim	  break;
4839218822Sdim	}
4840218822Sdim      /* FALLTHRU */
4841218822Sdim    case v_mode:
4842218822Sdim    case dq_mode:
4843218822Sdim      USED_REX (REX_W);
4844218822Sdim      if (rex & REX_W)
4845218822Sdim	oappend ("QWORD PTR ");
4846218822Sdim      else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4847218822Sdim	oappend ("DWORD PTR ");
4848218822Sdim      else
4849218822Sdim	oappend ("WORD PTR ");
4850218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
4851218822Sdim      break;
4852218822Sdim    case z_mode:
4853218822Sdim      if ((rex & REX_W) || (sizeflag & DFLAG))
4854218822Sdim	*obufp++ = 'D';
4855218822Sdim      oappend ("WORD PTR ");
4856218822Sdim      if (!(rex & REX_W))
4857218822Sdim	used_prefixes |= (prefixes & PREFIX_DATA);
4858218822Sdim      break;
4859218822Sdim    case d_mode:
4860218822Sdim    case dqd_mode:
4861218822Sdim      oappend ("DWORD PTR ");
4862218822Sdim      break;
4863218822Sdim    case q_mode:
4864218822Sdim      oappend ("QWORD PTR ");
4865218822Sdim      break;
4866218822Sdim    case m_mode:
4867218822Sdim      if (address_mode == mode_64bit)
4868218822Sdim	oappend ("QWORD PTR ");
4869218822Sdim      else
4870218822Sdim	oappend ("DWORD PTR ");
4871218822Sdim      break;
4872218822Sdim    case f_mode:
4873218822Sdim      if (sizeflag & DFLAG)
4874218822Sdim	oappend ("FWORD PTR ");
4875218822Sdim      else
4876218822Sdim	oappend ("DWORD PTR ");
4877218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
4878218822Sdim      break;
4879218822Sdim    case t_mode:
4880218822Sdim      oappend ("TBYTE PTR ");
4881218822Sdim      break;
4882218822Sdim    case x_mode:
4883218822Sdim      oappend ("XMMWORD PTR ");
4884218822Sdim      break;
4885218822Sdim    case o_mode:
4886218822Sdim      oappend ("OWORD PTR ");
4887218822Sdim      break;
4888218822Sdim    default:
4889218822Sdim      break;
4890218822Sdim    }
4891218822Sdim}
4892218822Sdim
4893218822Sdimstatic void
4894130561SobrienOP_E (int bytemode, int sizeflag)
489533965Sjdp{
489677298Sobrien  bfd_vma disp;
489777298Sobrien  int add = 0;
489877298Sobrien  int riprel = 0;
4899218822Sdim  USED_REX (REX_B);
4900218822Sdim  if (rex & REX_B)
490177298Sobrien    add += 8;
490233965Sjdp
490385815Sobrien  /* Skip mod/rm byte.  */
490478828Sobrien  MODRM_CHECK;
490533965Sjdp  codep++;
490633965Sjdp
4907218822Sdim  if (modrm.mod == 3)
490833965Sjdp    {
490933965Sjdp      switch (bytemode)
491033965Sjdp	{
491133965Sjdp	case b_mode:
491277298Sobrien	  USED_REX (0);
491377298Sobrien	  if (rex)
4914218822Sdim	    oappend (names8rex[modrm.rm + add]);
491577298Sobrien	  else
4916218822Sdim	    oappend (names8[modrm.rm + add]);
491733965Sjdp	  break;
491833965Sjdp	case w_mode:
4919218822Sdim	  oappend (names16[modrm.rm + add]);
492033965Sjdp	  break;
492160484Sobrien	case d_mode:
4922218822Sdim	  oappend (names32[modrm.rm + add]);
492360484Sobrien	  break;
492477298Sobrien	case q_mode:
4925218822Sdim	  oappend (names64[modrm.rm + add]);
492677298Sobrien	  break;
492777298Sobrien	case m_mode:
4928218822Sdim	  if (address_mode == mode_64bit)
4929218822Sdim	    oappend (names64[modrm.rm + add]);
493077298Sobrien	  else
4931218822Sdim	    oappend (names32[modrm.rm + add]);
493277298Sobrien	  break;
4933218822Sdim	case stack_v_mode:
4934218822Sdim	  if (address_mode == mode_64bit && (sizeflag & DFLAG))
4935218822Sdim	    {
4936218822Sdim	      oappend (names64[modrm.rm + add]);
4937218822Sdim	      used_prefixes |= (prefixes & PREFIX_DATA);
4938218822Sdim	      break;
4939218822Sdim	    }
4940218822Sdim	  bytemode = v_mode;
4941218822Sdim	  /* FALLTHRU */
494233965Sjdp	case v_mode:
4943130561Sobrien	case dq_mode:
4944218822Sdim	case dqb_mode:
4945218822Sdim	case dqd_mode:
4946218822Sdim	case dqw_mode:
4947218822Sdim	  USED_REX (REX_W);
4948218822Sdim	  if (rex & REX_W)
4949218822Sdim	    oappend (names64[modrm.rm + add]);
4950218822Sdim	  else if ((sizeflag & DFLAG) || bytemode != v_mode)
4951218822Sdim	    oappend (names32[modrm.rm + add]);
495233965Sjdp	  else
4953218822Sdim	    oappend (names16[modrm.rm + add]);
495460484Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
495533965Sjdp	  break;
495660484Sobrien	case 0:
495760484Sobrien	  break;
495833965Sjdp	default:
495960484Sobrien	  oappend (INTERNAL_DISASSEMBLER_ERROR);
496033965Sjdp	  break;
496133965Sjdp	}
496260484Sobrien      return;
496333965Sjdp    }
496433965Sjdp
496533965Sjdp  disp = 0;
4966218822Sdim  if (intel_syntax)
4967218822Sdim    intel_operand_size (bytemode, sizeflag);
496860484Sobrien  append_seg ();
496933965Sjdp
4970218822Sdim  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
497133965Sjdp    {
4972218822Sdim      /* 32/64 bit address mode */
4973218822Sdim      int havedisp;
497433965Sjdp      int havesib;
497533965Sjdp      int havebase;
497633965Sjdp      int base;
497738889Sjdp      int index = 0;
497838889Sjdp      int scale = 0;
497933965Sjdp
498033965Sjdp      havesib = 0;
498133965Sjdp      havebase = 1;
4982218822Sdim      base = modrm.rm;
498333965Sjdp
498433965Sjdp      if (base == 4)
498533965Sjdp	{
498633965Sjdp	  havesib = 1;
4987223262Sbenl	  (void) FETCH_DATA (the_info, codep + 1);
498833965Sjdp	  index = (*codep >> 3) & 7;
4989218822Sdim	  if (address_mode == mode_64bit || index != 0x4)
4990218822Sdim	    /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored.  */
4991218822Sdim	    scale = (*codep >> 6) & 3;
499233965Sjdp	  base = *codep & 7;
4993218822Sdim	  USED_REX (REX_X);
4994218822Sdim	  if (rex & REX_X)
499577298Sobrien	    index += 8;
499633965Sjdp	  codep++;
499733965Sjdp	}
4998218822Sdim      base += add;
499933965Sjdp
5000218822Sdim      switch (modrm.mod)
500133965Sjdp	{
500233965Sjdp	case 0:
500377298Sobrien	  if ((base & 7) == 5)
500433965Sjdp	    {
500533965Sjdp	      havebase = 0;
5006218822Sdim	      if (address_mode == mode_64bit && !havesib)
500777298Sobrien		riprel = 1;
500877298Sobrien	      disp = get32s ();
500933965Sjdp	    }
501033965Sjdp	  break;
501133965Sjdp	case 1:
501233965Sjdp	  FETCH_DATA (the_info, codep + 1);
501338889Sjdp	  disp = *codep++;
501438889Sjdp	  if ((disp & 0x80) != 0)
501538889Sjdp	    disp -= 0x100;
501633965Sjdp	  break;
501733965Sjdp	case 2:
501877298Sobrien	  disp = get32s ();
501933965Sjdp	  break;
502033965Sjdp	}
502133965Sjdp
5022218822Sdim      havedisp = havebase || (havesib && (index != 4 || scale != 0));
5023218822Sdim
502460484Sobrien      if (!intel_syntax)
5025218822Sdim	if (modrm.mod != 0 || (base & 7) == 5)
5026130561Sobrien	  {
5027218822Sdim	    if (havedisp || riprel)
5028218822Sdim	      print_displacement (scratchbuf, disp);
5029218822Sdim	    else
5030218822Sdim	      print_operand_value (scratchbuf, 1, disp);
5031130561Sobrien	    oappend (scratchbuf);
503277298Sobrien	    if (riprel)
503377298Sobrien	      {
503477298Sobrien		set_op (disp, 1);
503577298Sobrien		oappend ("(%rip)");
503677298Sobrien	      }
5037130561Sobrien	  }
503833965Sjdp
5039218822Sdim      if (havedisp || (intel_syntax && riprel))
504033965Sjdp	{
504160484Sobrien	  *obufp++ = open_char;
504277298Sobrien	  if (intel_syntax && riprel)
5043218822Sdim	    {
5044218822Sdim	      set_op (disp, 1);
5045218822Sdim	      oappend ("rip");
5046218822Sdim	    }
5047130561Sobrien	  *obufp = '\0';
504833965Sjdp	  if (havebase)
5049218822Sdim	    oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
505092828Sobrien		     ? names64[base] : names32[base]);
505133965Sjdp	  if (havesib)
505233965Sjdp	    {
505333965Sjdp	      if (index != 4)
505433965Sjdp		{
5055218822Sdim		  if (!intel_syntax || havebase)
5056130561Sobrien		    {
5057218822Sdim		      *obufp++ = separator_char;
5058218822Sdim		      *obufp = '\0';
5059130561Sobrien		    }
5060218822Sdim		  oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5061218822Sdim			   ? names64[index] : names32[index]);
506233965Sjdp		}
5063130561Sobrien	      if (scale != 0 || (!intel_syntax && index != 4))
5064130561Sobrien		{
5065130561Sobrien		  *obufp++ = scale_char;
5066130561Sobrien		  *obufp = '\0';
5067130561Sobrien		  sprintf (scratchbuf, "%d", 1 << scale);
5068130561Sobrien		  oappend (scratchbuf);
5069130561Sobrien		}
507033965Sjdp	    }
5071218822Sdim	  if (intel_syntax
5072218822Sdim	      && (disp || modrm.mod != 0 || (base & 7) == 5))
5073218822Sdim	    {
5074218822Sdim	      if ((bfd_signed_vma) disp >= 0)
5075218822Sdim		{
5076218822Sdim		  *obufp++ = '+';
5077218822Sdim		  *obufp = '\0';
5078218822Sdim		}
5079218822Sdim	      else if (modrm.mod != 1)
5080218822Sdim		{
5081218822Sdim		  *obufp++ = '-';
5082218822Sdim		  *obufp = '\0';
5083218822Sdim		  disp = - (bfd_signed_vma) disp;
5084218822Sdim		}
508585815Sobrien
5086218822Sdim	      print_displacement (scratchbuf, disp);
5087218822Sdim	      oappend (scratchbuf);
5088218822Sdim	    }
508960484Sobrien
509060484Sobrien	  *obufp++ = close_char;
5091130561Sobrien	  *obufp = '\0';
509233965Sjdp	}
509360484Sobrien      else if (intel_syntax)
5094130561Sobrien	{
5095218822Sdim	  if (modrm.mod != 0 || (base & 7) == 5)
5096130561Sobrien	    {
509760484Sobrien	      if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
509860484Sobrien			      | PREFIX_ES | PREFIX_FS | PREFIX_GS))
509960484Sobrien		;
510060484Sobrien	      else
510160484Sobrien		{
510285815Sobrien		  oappend (names_seg[ds_reg - es_reg]);
510360484Sobrien		  oappend (":");
510460484Sobrien		}
510577298Sobrien	      print_operand_value (scratchbuf, 1, disp);
5106130561Sobrien	      oappend (scratchbuf);
5107130561Sobrien	    }
5108130561Sobrien	}
510933965Sjdp    }
511033965Sjdp  else
511133965Sjdp    { /* 16 bit address mode */
5112218822Sdim      switch (modrm.mod)
511333965Sjdp	{
511433965Sjdp	case 0:
5115218822Sdim	  if (modrm.rm == 6)
511638889Sjdp	    {
511738889Sjdp	      disp = get16 ();
511838889Sjdp	      if ((disp & 0x8000) != 0)
511938889Sjdp		disp -= 0x10000;
512038889Sjdp	    }
512133965Sjdp	  break;
512233965Sjdp	case 1:
512333965Sjdp	  FETCH_DATA (the_info, codep + 1);
512438889Sjdp	  disp = *codep++;
512538889Sjdp	  if ((disp & 0x80) != 0)
512638889Sjdp	    disp -= 0x100;
512733965Sjdp	  break;
512833965Sjdp	case 2:
512938889Sjdp	  disp = get16 ();
513038889Sjdp	  if ((disp & 0x8000) != 0)
513138889Sjdp	    disp -= 0x10000;
513233965Sjdp	  break;
513333965Sjdp	}
513433965Sjdp
513560484Sobrien      if (!intel_syntax)
5136218822Sdim	if (modrm.mod != 0 || modrm.rm == 6)
5137130561Sobrien	  {
5138218822Sdim	    print_displacement (scratchbuf, disp);
5139130561Sobrien	    oappend (scratchbuf);
5140130561Sobrien	  }
514133965Sjdp
5142218822Sdim      if (modrm.mod != 0 || modrm.rm != 6)
514333965Sjdp	{
514460484Sobrien	  *obufp++ = open_char;
5145130561Sobrien	  *obufp = '\0';
5146218822Sdim	  oappend (index16[modrm.rm]);
5147218822Sdim	  if (intel_syntax
5148218822Sdim	      && (disp || modrm.mod != 0 || modrm.rm == 6))
5149218822Sdim	    {
5150218822Sdim	      if ((bfd_signed_vma) disp >= 0)
5151218822Sdim		{
5152218822Sdim		  *obufp++ = '+';
5153218822Sdim		  *obufp = '\0';
5154218822Sdim		}
5155218822Sdim	      else if (modrm.mod != 1)
5156218822Sdim		{
5157218822Sdim		  *obufp++ = '-';
5158218822Sdim		  *obufp = '\0';
5159218822Sdim		  disp = - (bfd_signed_vma) disp;
5160218822Sdim		}
5161218822Sdim
5162218822Sdim	      print_displacement (scratchbuf, disp);
5163218822Sdim	      oappend (scratchbuf);
5164218822Sdim	    }
5165218822Sdim
5166130561Sobrien	  *obufp++ = close_char;
5167130561Sobrien	  *obufp = '\0';
516833965Sjdp	}
5169218822Sdim      else if (intel_syntax)
5170218822Sdim	{
5171218822Sdim	  if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5172218822Sdim			  | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5173218822Sdim	    ;
5174218822Sdim	  else
5175218822Sdim	    {
5176218822Sdim	      oappend (names_seg[ds_reg - es_reg]);
5177218822Sdim	      oappend (":");
5178218822Sdim	    }
5179218822Sdim	  print_operand_value (scratchbuf, 1, disp & 0xffff);
5180218822Sdim	  oappend (scratchbuf);
5181218822Sdim	}
518233965Sjdp    }
518333965Sjdp}
518433965Sjdp
518560484Sobrienstatic void
5186130561SobrienOP_G (int bytemode, int sizeflag)
518733965Sjdp{
518877298Sobrien  int add = 0;
5189218822Sdim  USED_REX (REX_R);
5190218822Sdim  if (rex & REX_R)
519177298Sobrien    add += 8;
519260484Sobrien  switch (bytemode)
519333965Sjdp    {
519433965Sjdp    case b_mode:
519577298Sobrien      USED_REX (0);
519677298Sobrien      if (rex)
5197218822Sdim	oappend (names8rex[modrm.reg + add]);
519877298Sobrien      else
5199218822Sdim	oappend (names8[modrm.reg + add]);
520033965Sjdp      break;
520133965Sjdp    case w_mode:
5202218822Sdim      oappend (names16[modrm.reg + add]);
520333965Sjdp      break;
520433965Sjdp    case d_mode:
5205218822Sdim      oappend (names32[modrm.reg + add]);
520633965Sjdp      break;
520777298Sobrien    case q_mode:
5208218822Sdim      oappend (names64[modrm.reg + add]);
520977298Sobrien      break;
521033965Sjdp    case v_mode:
5211218822Sdim    case dq_mode:
5212218822Sdim    case dqb_mode:
5213218822Sdim    case dqd_mode:
5214218822Sdim    case dqw_mode:
5215218822Sdim      USED_REX (REX_W);
5216218822Sdim      if (rex & REX_W)
5217218822Sdim	oappend (names64[modrm.reg + add]);
5218218822Sdim      else if ((sizeflag & DFLAG) || bytemode != v_mode)
5219218822Sdim	oappend (names32[modrm.reg + add]);
522033965Sjdp      else
5221218822Sdim	oappend (names16[modrm.reg + add]);
522260484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
522333965Sjdp      break;
5224218822Sdim    case m_mode:
5225218822Sdim      if (address_mode == mode_64bit)
5226218822Sdim	oappend (names64[modrm.reg + add]);
5227218822Sdim      else
5228218822Sdim	oappend (names32[modrm.reg + add]);
5229218822Sdim      break;
523033965Sjdp    default:
523160484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
523233965Sjdp      break;
523333965Sjdp    }
523433965Sjdp}
523533965Sjdp
523677298Sobrienstatic bfd_vma
5237130561Sobrienget64 (void)
523877298Sobrien{
523985815Sobrien  bfd_vma x;
524085815Sobrien#ifdef BFD64
524185815Sobrien  unsigned int a;
524285815Sobrien  unsigned int b;
524377298Sobrien
5244223262Sbenl  (void) FETCH_DATA (the_info, codep + 8);
524577298Sobrien  a = *codep++ & 0xff;
524677298Sobrien  a |= (*codep++ & 0xff) << 8;
524777298Sobrien  a |= (*codep++ & 0xff) << 16;
524877298Sobrien  a |= (*codep++ & 0xff) << 24;
524985815Sobrien  b = *codep++ & 0xff;
525077298Sobrien  b |= (*codep++ & 0xff) << 8;
525177298Sobrien  b |= (*codep++ & 0xff) << 16;
525277298Sobrien  b |= (*codep++ & 0xff) << 24;
525377298Sobrien  x = a + ((bfd_vma) b << 32);
525477298Sobrien#else
525585815Sobrien  abort ();
525685815Sobrien  x = 0;
525777298Sobrien#endif
525877298Sobrien  return x;
525977298Sobrien}
526077298Sobrien
526177298Sobrienstatic bfd_signed_vma
5262130561Sobrienget32 (void)
526333965Sjdp{
526477298Sobrien  bfd_signed_vma x = 0;
526533965Sjdp
5266223262Sbenl  (void) FETCH_DATA (the_info, codep + 4);
526777298Sobrien  x = *codep++ & (bfd_signed_vma) 0xff;
526877298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
526977298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
527077298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
527160484Sobrien  return x;
527233965Sjdp}
527333965Sjdp
527477298Sobrienstatic bfd_signed_vma
5275130561Sobrienget32s (void)
527677298Sobrien{
527777298Sobrien  bfd_signed_vma x = 0;
527877298Sobrien
5279223262Sbenl  (void) FETCH_DATA (the_info, codep + 4);
528077298Sobrien  x = *codep++ & (bfd_signed_vma) 0xff;
528177298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
528277298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
528377298Sobrien  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
528477298Sobrien
528577298Sobrien  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
528677298Sobrien
528777298Sobrien  return x;
528877298Sobrien}
528977298Sobrien
529033965Sjdpstatic int
5291130561Sobrienget16 (void)
529233965Sjdp{
529333965Sjdp  int x = 0;
529433965Sjdp
5295223262Sbenl  (void) FETCH_DATA (the_info, codep + 2);
529633965Sjdp  x = *codep++ & 0xff;
529733965Sjdp  x |= (*codep++ & 0xff) << 8;
529860484Sobrien  return x;
529933965Sjdp}
530033965Sjdp
530133965Sjdpstatic void
5302130561Sobrienset_op (bfd_vma op, int riprel)
530333965Sjdp{
530433965Sjdp  op_index[op_ad] = op_ad;
5305218822Sdim  if (address_mode == mode_64bit)
530685815Sobrien    {
530785815Sobrien      op_address[op_ad] = op;
530885815Sobrien      op_riprel[op_ad] = riprel;
530985815Sobrien    }
531085815Sobrien  else
531185815Sobrien    {
531285815Sobrien      /* Mask to get a 32-bit address.  */
531385815Sobrien      op_address[op_ad] = op & 0xffffffff;
531485815Sobrien      op_riprel[op_ad] = riprel & 0xffffffff;
531585815Sobrien    }
531633965Sjdp}
531733965Sjdp
531860484Sobrienstatic void
5319130561SobrienOP_REG (int code, int sizeflag)
532033965Sjdp{
532160484Sobrien  const char *s;
532277298Sobrien  int add = 0;
5323218822Sdim  USED_REX (REX_B);
5324218822Sdim  if (rex & REX_B)
532577298Sobrien    add = 8;
532660484Sobrien
532760484Sobrien  switch (code)
532833965Sjdp    {
532960484Sobrien    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
533060484Sobrien    case sp_reg: case bp_reg: case si_reg: case di_reg:
533177298Sobrien      s = names16[code - ax_reg + add];
533277298Sobrien      break;
533377298Sobrien    case es_reg: case ss_reg: case cs_reg:
533477298Sobrien    case ds_reg: case fs_reg: case gs_reg:
533577298Sobrien      s = names_seg[code - es_reg + add];
533677298Sobrien      break;
533777298Sobrien    case al_reg: case ah_reg: case cl_reg: case ch_reg:
533877298Sobrien    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
533977298Sobrien      USED_REX (0);
534077298Sobrien      if (rex)
534177298Sobrien	s = names8rex[code - al_reg + add];
534277298Sobrien      else
534377298Sobrien	s = names8[code - al_reg];
534477298Sobrien      break;
534585815Sobrien    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
534685815Sobrien    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
5347218822Sdim      if (address_mode == mode_64bit && (sizeflag & DFLAG))
534885815Sobrien	{
534985815Sobrien	  s = names64[code - rAX_reg + add];
535085815Sobrien	  break;
535185815Sobrien	}
535285815Sobrien      code += eAX_reg - rAX_reg;
535385815Sobrien      /* Fall through.  */
535477298Sobrien    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
535577298Sobrien    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5356218822Sdim      USED_REX (REX_W);
5357218822Sdim      if (rex & REX_W)
535877298Sobrien	s = names64[code - eAX_reg + add];
535977298Sobrien      else if (sizeflag & DFLAG)
536077298Sobrien	s = names32[code - eAX_reg + add];
536177298Sobrien      else
536277298Sobrien	s = names16[code - eAX_reg + add];
536377298Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
536477298Sobrien      break;
536577298Sobrien    default:
536677298Sobrien      s = INTERNAL_DISASSEMBLER_ERROR;
536777298Sobrien      break;
536877298Sobrien    }
536977298Sobrien  oappend (s);
537077298Sobrien}
537177298Sobrien
537277298Sobrienstatic void
5373130561SobrienOP_IMREG (int code, int sizeflag)
537477298Sobrien{
537577298Sobrien  const char *s;
537677298Sobrien
537777298Sobrien  switch (code)
537877298Sobrien    {
537977298Sobrien    case indir_dx_reg:
538085815Sobrien      if (intel_syntax)
5381218822Sdim	s = "dx";
538285815Sobrien      else
5383130561Sobrien	s = "(%dx)";
538477298Sobrien      break;
538577298Sobrien    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
538677298Sobrien    case sp_reg: case bp_reg: case si_reg: case di_reg:
538760484Sobrien      s = names16[code - ax_reg];
538860484Sobrien      break;
538960484Sobrien    case es_reg: case ss_reg: case cs_reg:
539060484Sobrien    case ds_reg: case fs_reg: case gs_reg:
539160484Sobrien      s = names_seg[code - es_reg];
539260484Sobrien      break;
539360484Sobrien    case al_reg: case ah_reg: case cl_reg: case ch_reg:
539460484Sobrien    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
539577298Sobrien      USED_REX (0);
539677298Sobrien      if (rex)
539777298Sobrien	s = names8rex[code - al_reg];
539877298Sobrien      else
539977298Sobrien	s = names8[code - al_reg];
540060484Sobrien      break;
540160484Sobrien    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
540260484Sobrien    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5403218822Sdim      USED_REX (REX_W);
5404218822Sdim      if (rex & REX_W)
540577298Sobrien	s = names64[code - eAX_reg];
540677298Sobrien      else if (sizeflag & DFLAG)
540733965Sjdp	s = names32[code - eAX_reg];
540833965Sjdp      else
540933965Sjdp	s = names16[code - eAX_reg];
541060484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
541133965Sjdp      break;
5412218822Sdim    case z_mode_ax_reg:
5413218822Sdim      if ((rex & REX_W) || (sizeflag & DFLAG))
5414218822Sdim	s = *names32;
5415218822Sdim      else
5416218822Sdim	s = *names16;
5417218822Sdim      if (!(rex & REX_W))
5418218822Sdim	used_prefixes |= (prefixes & PREFIX_DATA);
5419218822Sdim      break;
542033965Sjdp    default:
542160484Sobrien      s = INTERNAL_DISASSEMBLER_ERROR;
542233965Sjdp      break;
542333965Sjdp    }
542433965Sjdp  oappend (s);
542533965Sjdp}
542633965Sjdp
542760484Sobrienstatic void
5428130561SobrienOP_I (int bytemode, int sizeflag)
542933965Sjdp{
543077298Sobrien  bfd_signed_vma op;
543177298Sobrien  bfd_signed_vma mask = -1;
543260484Sobrien
543360484Sobrien  switch (bytemode)
543433965Sjdp    {
543533965Sjdp    case b_mode:
543633965Sjdp      FETCH_DATA (the_info, codep + 1);
543777298Sobrien      op = *codep++;
543877298Sobrien      mask = 0xff;
543933965Sjdp      break;
544077298Sobrien    case q_mode:
5441218822Sdim      if (address_mode == mode_64bit)
544285815Sobrien	{
544385815Sobrien	  op = get32s ();
544485815Sobrien	  break;
544585815Sobrien	}
544685815Sobrien      /* Fall through.  */
544733965Sjdp    case v_mode:
5448218822Sdim      USED_REX (REX_W);
5449218822Sdim      if (rex & REX_W)
545077298Sobrien	op = get32s ();
545177298Sobrien      else if (sizeflag & DFLAG)
545277298Sobrien	{
545377298Sobrien	  op = get32 ();
545477298Sobrien	  mask = 0xffffffff;
545577298Sobrien	}
545633965Sjdp      else
545777298Sobrien	{
545877298Sobrien	  op = get16 ();
545977298Sobrien	  mask = 0xfffff;
546077298Sobrien	}
546160484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
546233965Sjdp      break;
546333965Sjdp    case w_mode:
546477298Sobrien      mask = 0xfffff;
546533965Sjdp      op = get16 ();
546633965Sjdp      break;
5467218822Sdim    case const_1_mode:
5468218822Sdim      if (intel_syntax)
5469218822Sdim        oappend ("1");
5470218822Sdim      return;
547133965Sjdp    default:
547260484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
547360484Sobrien      return;
547433965Sjdp    }
547560484Sobrien
547677298Sobrien  op &= mask;
547777298Sobrien  scratchbuf[0] = '$';
547885815Sobrien  print_operand_value (scratchbuf + 1, 1, op);
5479257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
548060484Sobrien  scratchbuf[0] = '\0';
548133965Sjdp}
548233965Sjdp
548360484Sobrienstatic void
5484130561SobrienOP_I64 (int bytemode, int sizeflag)
548577298Sobrien{
548677298Sobrien  bfd_signed_vma op;
548777298Sobrien  bfd_signed_vma mask = -1;
548877298Sobrien
5489218822Sdim  if (address_mode != mode_64bit)
549085815Sobrien    {
549185815Sobrien      OP_I (bytemode, sizeflag);
549285815Sobrien      return;
549385815Sobrien    }
549485815Sobrien
549577298Sobrien  switch (bytemode)
549677298Sobrien    {
549777298Sobrien    case b_mode:
549877298Sobrien      FETCH_DATA (the_info, codep + 1);
549977298Sobrien      op = *codep++;
550077298Sobrien      mask = 0xff;
550177298Sobrien      break;
550277298Sobrien    case v_mode:
5503218822Sdim      USED_REX (REX_W);
5504218822Sdim      if (rex & REX_W)
550577298Sobrien	op = get64 ();
550677298Sobrien      else if (sizeflag & DFLAG)
550777298Sobrien	{
550877298Sobrien	  op = get32 ();
550977298Sobrien	  mask = 0xffffffff;
551077298Sobrien	}
551177298Sobrien      else
551277298Sobrien	{
551377298Sobrien	  op = get16 ();
551477298Sobrien	  mask = 0xfffff;
551577298Sobrien	}
551677298Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
551777298Sobrien      break;
551877298Sobrien    case w_mode:
551977298Sobrien      mask = 0xfffff;
552077298Sobrien      op = get16 ();
552177298Sobrien      break;
552277298Sobrien    default:
552377298Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
552477298Sobrien      return;
552577298Sobrien    }
552677298Sobrien
552777298Sobrien  op &= mask;
552877298Sobrien  scratchbuf[0] = '$';
552985815Sobrien  print_operand_value (scratchbuf + 1, 1, op);
5530257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
553177298Sobrien  scratchbuf[0] = '\0';
553277298Sobrien}
553377298Sobrien
553477298Sobrienstatic void
5535130561SobrienOP_sI (int bytemode, int sizeflag)
553633965Sjdp{
553777298Sobrien  bfd_signed_vma op;
553877298Sobrien  bfd_signed_vma mask = -1;
553960484Sobrien
554060484Sobrien  switch (bytemode)
554133965Sjdp    {
554233965Sjdp    case b_mode:
554333965Sjdp      FETCH_DATA (the_info, codep + 1);
554438889Sjdp      op = *codep++;
554538889Sjdp      if ((op & 0x80) != 0)
554638889Sjdp	op -= 0x100;
554777298Sobrien      mask = 0xffffffff;
554833965Sjdp      break;
554933965Sjdp    case v_mode:
5550218822Sdim      USED_REX (REX_W);
5551218822Sdim      if (rex & REX_W)
555277298Sobrien	op = get32s ();
555377298Sobrien      else if (sizeflag & DFLAG)
555477298Sobrien	{
555577298Sobrien	  op = get32s ();
555677298Sobrien	  mask = 0xffffffff;
555777298Sobrien	}
555833965Sjdp      else
555938889Sjdp	{
556077298Sobrien	  mask = 0xffffffff;
556185815Sobrien	  op = get16 ();
556238889Sjdp	  if ((op & 0x8000) != 0)
556338889Sjdp	    op -= 0x10000;
556438889Sjdp	}
556560484Sobrien      used_prefixes |= (prefixes & PREFIX_DATA);
556633965Sjdp      break;
556733965Sjdp    case w_mode:
556838889Sjdp      op = get16 ();
556977298Sobrien      mask = 0xffffffff;
557038889Sjdp      if ((op & 0x8000) != 0)
557138889Sjdp	op -= 0x10000;
557233965Sjdp      break;
557333965Sjdp    default:
557460484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
557560484Sobrien      return;
557633965Sjdp    }
557777298Sobrien
557877298Sobrien  scratchbuf[0] = '$';
557977298Sobrien  print_operand_value (scratchbuf + 1, 1, op);
5580257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
558133965Sjdp}
558233965Sjdp
558360484Sobrienstatic void
5584130561SobrienOP_J (int bytemode, int sizeflag)
558533965Sjdp{
558677298Sobrien  bfd_vma disp;
558785815Sobrien  bfd_vma mask = -1;
5588218822Sdim  bfd_vma segment = 0;
558960484Sobrien
559060484Sobrien  switch (bytemode)
559133965Sjdp    {
559233965Sjdp    case b_mode:
559333965Sjdp      FETCH_DATA (the_info, codep + 1);
559438889Sjdp      disp = *codep++;
559538889Sjdp      if ((disp & 0x80) != 0)
559638889Sjdp	disp -= 0x100;
559733965Sjdp      break;
559833965Sjdp    case v_mode:
5599218822Sdim      if ((sizeflag & DFLAG) || (rex & REX_W))
560077298Sobrien	disp = get32s ();
560133965Sjdp      else
560233965Sjdp	{
560338889Sjdp	  disp = get16 ();
5604218822Sdim	  if ((disp & 0x8000) != 0)
5605218822Sdim	    disp -= 0x10000;
5606218822Sdim	  /* In 16bit mode, address is wrapped around at 64k within
5607218822Sdim	     the same segment.  Otherwise, a data16 prefix on a jump
5608218822Sdim	     instruction means that the pc is masked to 16 bits after
5609218822Sdim	     the displacement is added!  */
561033965Sjdp	  mask = 0xffff;
5611218822Sdim	  if ((prefixes & PREFIX_DATA) == 0)
5612218822Sdim	    segment = ((start_pc + codep - start_codep)
5613218822Sdim		       & ~((bfd_vma) 0xffff));
561433965Sjdp	}
5615218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
561633965Sjdp      break;
561733965Sjdp    default:
561860484Sobrien      oappend (INTERNAL_DISASSEMBLER_ERROR);
561960484Sobrien      return;
562033965Sjdp    }
5621218822Sdim  disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
562277298Sobrien  set_op (disp, 0);
562377298Sobrien  print_operand_value (scratchbuf, 1, disp);
562433965Sjdp  oappend (scratchbuf);
562533965Sjdp}
562633965Sjdp
562760484Sobrienstatic void
5628218822SdimOP_SEG (int bytemode, int sizeflag)
562933965Sjdp{
5630218822Sdim  if (bytemode == w_mode)
5631218822Sdim    oappend (names_seg[modrm.reg]);
5632218822Sdim  else
5633218822Sdim    OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
563433965Sjdp}
563533965Sjdp
563660484Sobrienstatic void
5637130561SobrienOP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
563833965Sjdp{
563933965Sjdp  int seg, offset;
564060484Sobrien
564160484Sobrien  if (sizeflag & DFLAG)
564233965Sjdp    {
564360484Sobrien      offset = get32 ();
564460484Sobrien      seg = get16 ();
564533965Sjdp    }
564660484Sobrien  else
564760484Sobrien    {
564860484Sobrien      offset = get16 ();
564960484Sobrien      seg = get16 ();
565060484Sobrien    }
565160484Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
565285815Sobrien  if (intel_syntax)
5653218822Sdim    sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
565485815Sobrien  else
565585815Sobrien    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
565660484Sobrien  oappend (scratchbuf);
565733965Sjdp}
565833965Sjdp
565960484Sobrienstatic void
5660218822SdimOP_OFF (int bytemode, int sizeflag)
566133965Sjdp{
566277298Sobrien  bfd_vma off;
566333965Sjdp
5664218822Sdim  if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5665218822Sdim    intel_operand_size (bytemode, sizeflag);
566660484Sobrien  append_seg ();
566733965Sjdp
5668218822Sdim  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
566933965Sjdp    off = get32 ();
567033965Sjdp  else
567133965Sjdp    off = get16 ();
567260484Sobrien
567360484Sobrien  if (intel_syntax)
567460484Sobrien    {
567560484Sobrien      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5676130561Sobrien			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
567760484Sobrien	{
567885815Sobrien	  oappend (names_seg[ds_reg - es_reg]);
567960484Sobrien	  oappend (":");
568060484Sobrien	}
568160484Sobrien    }
568277298Sobrien  print_operand_value (scratchbuf, 1, off);
568333965Sjdp  oappend (scratchbuf);
568433965Sjdp}
568585815Sobrien
568677298Sobrienstatic void
5687218822SdimOP_OFF64 (int bytemode, int sizeflag)
568877298Sobrien{
568977298Sobrien  bfd_vma off;
569033965Sjdp
5691218822Sdim  if (address_mode != mode_64bit
5692218822Sdim      || (prefixes & PREFIX_ADDR))
569385815Sobrien    {
569485815Sobrien      OP_OFF (bytemode, sizeflag);
569585815Sobrien      return;
569685815Sobrien    }
569785815Sobrien
5698218822Sdim  if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5699218822Sdim    intel_operand_size (bytemode, sizeflag);
570077298Sobrien  append_seg ();
570177298Sobrien
570285815Sobrien  off = get64 ();
570377298Sobrien
570477298Sobrien  if (intel_syntax)
570577298Sobrien    {
570677298Sobrien      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5707130561Sobrien			| PREFIX_ES | PREFIX_FS | PREFIX_GS)))
570877298Sobrien	{
570985815Sobrien	  oappend (names_seg[ds_reg - es_reg]);
571077298Sobrien	  oappend (":");
571177298Sobrien	}
571277298Sobrien    }
571377298Sobrien  print_operand_value (scratchbuf, 1, off);
571477298Sobrien  oappend (scratchbuf);
571577298Sobrien}
571677298Sobrien
571760484Sobrienstatic void
5718130561Sobrienptr_reg (int code, int sizeflag)
571933965Sjdp{
572060484Sobrien  const char *s;
572185815Sobrien
5722218822Sdim  *obufp++ = open_char;
5723218822Sdim  used_prefixes |= (prefixes & PREFIX_ADDR);
5724218822Sdim  if (address_mode == mode_64bit)
572592828Sobrien    {
572692828Sobrien      if (!(sizeflag & AFLAG))
5727130561Sobrien	s = names32[code - eAX_reg];
572892828Sobrien      else
5729130561Sobrien	s = names64[code - eAX_reg];
573092828Sobrien    }
573177298Sobrien  else if (sizeflag & AFLAG)
573260484Sobrien    s = names32[code - eAX_reg];
573360484Sobrien  else
573460484Sobrien    s = names16[code - eAX_reg];
573560484Sobrien  oappend (s);
5736218822Sdim  *obufp++ = close_char;
5737218822Sdim  *obufp = 0;
573833965Sjdp}
573933965Sjdp
574060484Sobrienstatic void
5741130561SobrienOP_ESreg (int code, int sizeflag)
574233965Sjdp{
5743218822Sdim  if (intel_syntax)
5744218822Sdim    {
5745218822Sdim      switch (codep[-1])
5746218822Sdim	{
5747218822Sdim	case 0x6d:	/* insw/insl */
5748218822Sdim	  intel_operand_size (z_mode, sizeflag);
5749218822Sdim	  break;
5750218822Sdim	case 0xa5:	/* movsw/movsl/movsq */
5751218822Sdim	case 0xa7:	/* cmpsw/cmpsl/cmpsq */
5752218822Sdim	case 0xab:	/* stosw/stosl */
5753218822Sdim	case 0xaf:	/* scasw/scasl */
5754218822Sdim	  intel_operand_size (v_mode, sizeflag);
5755218822Sdim	  break;
5756218822Sdim	default:
5757218822Sdim	  intel_operand_size (b_mode, sizeflag);
5758218822Sdim	}
5759218822Sdim    }
5760257464Ssbruno  oappend (&"%es:"[intel_syntax]);
576160484Sobrien  ptr_reg (code, sizeflag);
576260484Sobrien}
576360484Sobrien
576460484Sobrienstatic void
5765130561SobrienOP_DSreg (int code, int sizeflag)
576660484Sobrien{
5767218822Sdim  if (intel_syntax)
5768218822Sdim    {
5769218822Sdim      switch (codep[-1])
5770218822Sdim	{
5771218822Sdim	case 0x6f:	/* outsw/outsl */
5772218822Sdim	  intel_operand_size (z_mode, sizeflag);
5773218822Sdim	  break;
5774218822Sdim	case 0xa5:	/* movsw/movsl/movsq */
5775218822Sdim	case 0xa7:	/* cmpsw/cmpsl/cmpsq */
5776218822Sdim	case 0xad:	/* lodsw/lodsl/lodsq */
5777218822Sdim	  intel_operand_size (v_mode, sizeflag);
5778218822Sdim	  break;
5779218822Sdim	default:
5780218822Sdim	  intel_operand_size (b_mode, sizeflag);
5781218822Sdim	}
5782218822Sdim    }
578338889Sjdp  if ((prefixes
578438889Sjdp       & (PREFIX_CS
578538889Sjdp	  | PREFIX_DS
578638889Sjdp	  | PREFIX_SS
578738889Sjdp	  | PREFIX_ES
578838889Sjdp	  | PREFIX_FS
578938889Sjdp	  | PREFIX_GS)) == 0)
579038889Sjdp    prefixes |= PREFIX_DS;
579185815Sobrien  append_seg ();
579260484Sobrien  ptr_reg (code, sizeflag);
579333965Sjdp}
579433965Sjdp
579560484Sobrienstatic void
5796130561SobrienOP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
579733965Sjdp{
579877298Sobrien  int add = 0;
5799218822Sdim  if (rex & REX_R)
5800218822Sdim    {
5801218822Sdim      USED_REX (REX_R);
5802218822Sdim      add = 8;
5803218822Sdim    }
5804218822Sdim  else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5805218822Sdim    {
5806218822Sdim      used_prefixes |= PREFIX_LOCK;
5807218822Sdim      add = 8;
5808218822Sdim    }
5809218822Sdim  sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
5810257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
581133965Sjdp}
581233965Sjdp
581360484Sobrienstatic void
5814130561SobrienOP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
581533965Sjdp{
581677298Sobrien  int add = 0;
5817218822Sdim  USED_REX (REX_R);
5818218822Sdim  if (rex & REX_R)
581977298Sobrien    add = 8;
582085815Sobrien  if (intel_syntax)
5821218822Sdim    sprintf (scratchbuf, "db%d", modrm.reg + add);
582285815Sobrien  else
5823218822Sdim    sprintf (scratchbuf, "%%db%d", modrm.reg + add);
582433965Sjdp  oappend (scratchbuf);
582533965Sjdp}
582633965Sjdp
582760484Sobrienstatic void
5828130561SobrienOP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
582933965Sjdp{
5830218822Sdim  sprintf (scratchbuf, "%%tr%d", modrm.reg);
5831257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
583233965Sjdp}
583333965Sjdp
583460484Sobrienstatic void
5835218822SdimOP_R (int bytemode, int sizeflag)
583633965Sjdp{
5837218822Sdim  if (modrm.mod == 3)
583860484Sobrien    OP_E (bytemode, sizeflag);
583960484Sobrien  else
584085815Sobrien    BadOp ();
584133965Sjdp}
584233965Sjdp
584360484Sobrienstatic void
5844130561SobrienOP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
584533965Sjdp{
584677298Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
584777298Sobrien  if (prefixes & PREFIX_DATA)
5848218822Sdim    {
5849218822Sdim      int add = 0;
5850218822Sdim      USED_REX (REX_R);
5851218822Sdim      if (rex & REX_R)
5852218822Sdim	add = 8;
5853218822Sdim      sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5854218822Sdim    }
585577298Sobrien  else
5856218822Sdim    sprintf (scratchbuf, "%%mm%d", modrm.reg);
5857257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
585833965Sjdp}
585933965Sjdp
586060484Sobrienstatic void
5861130561SobrienOP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
586260484Sobrien{
586377298Sobrien  int add = 0;
5864218822Sdim  USED_REX (REX_R);
5865218822Sdim  if (rex & REX_R)
586677298Sobrien    add = 8;
5867218822Sdim  sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5868257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
586960484Sobrien}
587060484Sobrien
587160484Sobrienstatic void
5872130561SobrienOP_EM (int bytemode, int sizeflag)
587333965Sjdp{
5874218822Sdim  if (modrm.mod != 3)
587560484Sobrien    {
5876218822Sdim      if (intel_syntax && bytemode == v_mode)
5877218822Sdim	{
5878218822Sdim	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5879218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
5880218822Sdim 	}
588160484Sobrien      OP_E (bytemode, sizeflag);
588260484Sobrien      return;
588360484Sobrien    }
588433965Sjdp
588585815Sobrien  /* Skip mod/rm byte.  */
588678828Sobrien  MODRM_CHECK;
588733965Sjdp  codep++;
588877298Sobrien  used_prefixes |= (prefixes & PREFIX_DATA);
588977298Sobrien  if (prefixes & PREFIX_DATA)
5890218822Sdim    {
5891218822Sdim      int add = 0;
5892218822Sdim
5893218822Sdim      USED_REX (REX_B);
5894218822Sdim      if (rex & REX_B)
5895218822Sdim	add = 8;
5896218822Sdim      sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5897218822Sdim    }
589877298Sobrien  else
5899218822Sdim    sprintf (scratchbuf, "%%mm%d", modrm.rm);
5900257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
590133965Sjdp}
590233965Sjdp
5903218822Sdim/* cvt* are the only instructions in sse2 which have
5904218822Sdim   both SSE and MMX operands and also have 0x66 prefix
5905218822Sdim   in their opcode. 0x66 was originally used to differentiate
5906218822Sdim   between SSE and MMX instruction(operands). So we have to handle the
5907218822Sdim   cvt* separately using OP_EMC and OP_MXC */
590860484Sobrienstatic void
5909218822SdimOP_EMC (int bytemode, int sizeflag)
5910218822Sdim{
5911218822Sdim  if (modrm.mod != 3)
5912218822Sdim    {
5913218822Sdim      if (intel_syntax && bytemode == v_mode)
5914218822Sdim	{
5915218822Sdim	  bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5916218822Sdim	  used_prefixes |= (prefixes & PREFIX_DATA);
5917218822Sdim 	}
5918218822Sdim      OP_E (bytemode, sizeflag);
5919218822Sdim      return;
5920218822Sdim    }
5921218822Sdim
5922218822Sdim  /* Skip mod/rm byte.  */
5923218822Sdim  MODRM_CHECK;
5924218822Sdim  codep++;
5925218822Sdim  used_prefixes |= (prefixes & PREFIX_DATA);
5926218822Sdim  sprintf (scratchbuf, "%%mm%d", modrm.rm);
5927257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
5928218822Sdim}
5929218822Sdim
5930218822Sdimstatic void
5931218822SdimOP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5932218822Sdim{
5933218822Sdim  used_prefixes |= (prefixes & PREFIX_DATA);
5934218822Sdim  sprintf (scratchbuf, "%%mm%d", modrm.reg);
5935257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
5936218822Sdim}
5937218822Sdim
5938218822Sdimstatic void
5939130561SobrienOP_EX (int bytemode, int sizeflag)
594033965Sjdp{
594177298Sobrien  int add = 0;
5942218822Sdim  if (modrm.mod != 3)
594360484Sobrien    {
594460484Sobrien      OP_E (bytemode, sizeflag);
594560484Sobrien      return;
594660484Sobrien    }
5947218822Sdim  USED_REX (REX_B);
5948218822Sdim  if (rex & REX_B)
594977298Sobrien    add = 8;
595060484Sobrien
595185815Sobrien  /* Skip mod/rm byte.  */
595278828Sobrien  MODRM_CHECK;
595360484Sobrien  codep++;
5954218822Sdim  sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5955257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
595633965Sjdp}
595760484Sobrien
595860484Sobrienstatic void
5959130561SobrienOP_MS (int bytemode, int sizeflag)
596060484Sobrien{
5961218822Sdim  if (modrm.mod == 3)
596260484Sobrien    OP_EM (bytemode, sizeflag);
596360484Sobrien  else
596485815Sobrien    BadOp ();
596560484Sobrien}
596660484Sobrien
596778828Sobrienstatic void
5968130561SobrienOP_XS (int bytemode, int sizeflag)
596978828Sobrien{
5970218822Sdim  if (modrm.mod == 3)
597178828Sobrien    OP_EX (bytemode, sizeflag);
597278828Sobrien  else
597385815Sobrien    BadOp ();
597478828Sobrien}
597578828Sobrien
5976130561Sobrienstatic void
5977130561SobrienOP_M (int bytemode, int sizeflag)
5978130561Sobrien{
5979218822Sdim  if (modrm.mod == 3)
5980238167Sjhb    /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst,invept,invvpid modrm */
5981218822Sdim    BadOp ();
5982130561Sobrien  else
5983130561Sobrien    OP_E (bytemode, sizeflag);
5984130561Sobrien}
5985130561Sobrien
5986130561Sobrienstatic void
5987130561SobrienOP_0f07 (int bytemode, int sizeflag)
5988130561Sobrien{
5989218822Sdim  if (modrm.mod != 3 || modrm.rm != 0)
5990130561Sobrien    BadOp ();
5991130561Sobrien  else
5992130561Sobrien    OP_E (bytemode, sizeflag);
5993130561Sobrien}
5994130561Sobrien
5995130561Sobrienstatic void
5996130561SobrienOP_0fae (int bytemode, int sizeflag)
5997130561Sobrien{
5998218822Sdim  if (modrm.mod == 3)
5999130561Sobrien    {
6000323489Srlibby      if (modrm.reg >= 5 && modrm.reg <= 7 && modrm.rm == 0)
6001130561Sobrien	{
6002323489Srlibby	  if (modrm.reg == 7)
6003323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
6004323489Srlibby	  else if (modrm.reg == 6)
6005323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
6006323489Srlibby	  else if (modrm.reg == 5)
6007323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
6008323489Srlibby	  bytemode = 0;
6009323489Srlibby	}
6010323489Srlibby      else if (modrm.reg <= 3 && (prefixes & PREFIX_REPZ) != 0)
6011323489Srlibby	{
6012323489Srlibby	  if (modrm.reg == 0)
6013323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("fxsave") + 1, "rdfsbase");
6014323489Srlibby	  else if (modrm.reg == 1)
6015323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("fxrstor") + 1, "rdgsbase");
6016323489Srlibby	  else if (modrm.reg == 2)
6017323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("ldmxcsr") + 1, "wrfsbase");
6018323489Srlibby	  else if (modrm.reg == 3)
6019323489Srlibby	    strcpy (obuf + strlen (obuf) - sizeof ("stmxcsr") + 1, "wrgsbase");
6020323489Srlibby	  used_prefixes |= PREFIX_REPZ;
6021323489Srlibby	  bytemode = dq_mode;
6022323489Srlibby	}
6023323489Srlibby      else
6024323489Srlibby	{
6025323489Srlibby	  BadOp ();
6026130561Sobrien	  return;
6027130561Sobrien	}
6028130561Sobrien    }
6029130561Sobrien
6030130561Sobrien  OP_E (bytemode, sizeflag);
6031130561Sobrien}
6032130561Sobrien
6033218822Sdim/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6034218822Sdim   32bit mode and "xchg %rax,%rax" in 64bit mode.  */
6035218822Sdim
6036130561Sobrienstatic void
6037218822SdimNOP_Fixup1 (int bytemode, int sizeflag)
6038130561Sobrien{
6039218822Sdim  if ((prefixes & PREFIX_DATA) != 0
6040218822Sdim      || (rex != 0
6041218822Sdim	  && rex != 0x48
6042218822Sdim	  && address_mode == mode_64bit))
6043218822Sdim    OP_REG (bytemode, sizeflag);
6044218822Sdim  else
6045218822Sdim    strcpy (obuf, "nop");
6046130561Sobrien}
6047130561Sobrien
6048218822Sdimstatic void
6049218822SdimNOP_Fixup2 (int bytemode, int sizeflag)
6050218822Sdim{
6051218822Sdim  if ((prefixes & PREFIX_DATA) != 0
6052218822Sdim      || (rex != 0
6053218822Sdim	  && rex != 0x48
6054218822Sdim	  && address_mode == mode_64bit))
6055218822Sdim    OP_IMREG (bytemode, sizeflag);
6056218822Sdim}
6057218822Sdim
6058130561Sobrienstatic const char *const Suffix3DNow[] = {
605960484Sobrien/* 00 */	NULL,		NULL,		NULL,		NULL,
606060484Sobrien/* 04 */	NULL,		NULL,		NULL,		NULL,
606160484Sobrien/* 08 */	NULL,		NULL,		NULL,		NULL,
606260484Sobrien/* 0C */	"pi2fw",	"pi2fd",	NULL,		NULL,
606360484Sobrien/* 10 */	NULL,		NULL,		NULL,		NULL,
606460484Sobrien/* 14 */	NULL,		NULL,		NULL,		NULL,
606560484Sobrien/* 18 */	NULL,		NULL,		NULL,		NULL,
606660484Sobrien/* 1C */	"pf2iw",	"pf2id",	NULL,		NULL,
606760484Sobrien/* 20 */	NULL,		NULL,		NULL,		NULL,
606860484Sobrien/* 24 */	NULL,		NULL,		NULL,		NULL,
606960484Sobrien/* 28 */	NULL,		NULL,		NULL,		NULL,
607060484Sobrien/* 2C */	NULL,		NULL,		NULL,		NULL,
607160484Sobrien/* 30 */	NULL,		NULL,		NULL,		NULL,
607260484Sobrien/* 34 */	NULL,		NULL,		NULL,		NULL,
607360484Sobrien/* 38 */	NULL,		NULL,		NULL,		NULL,
607460484Sobrien/* 3C */	NULL,		NULL,		NULL,		NULL,
607560484Sobrien/* 40 */	NULL,		NULL,		NULL,		NULL,
607660484Sobrien/* 44 */	NULL,		NULL,		NULL,		NULL,
607760484Sobrien/* 48 */	NULL,		NULL,		NULL,		NULL,
607860484Sobrien/* 4C */	NULL,		NULL,		NULL,		NULL,
607960484Sobrien/* 50 */	NULL,		NULL,		NULL,		NULL,
608060484Sobrien/* 54 */	NULL,		NULL,		NULL,		NULL,
608160484Sobrien/* 58 */	NULL,		NULL,		NULL,		NULL,
608260484Sobrien/* 5C */	NULL,		NULL,		NULL,		NULL,
608360484Sobrien/* 60 */	NULL,		NULL,		NULL,		NULL,
608460484Sobrien/* 64 */	NULL,		NULL,		NULL,		NULL,
608560484Sobrien/* 68 */	NULL,		NULL,		NULL,		NULL,
608660484Sobrien/* 6C */	NULL,		NULL,		NULL,		NULL,
608760484Sobrien/* 70 */	NULL,		NULL,		NULL,		NULL,
608860484Sobrien/* 74 */	NULL,		NULL,		NULL,		NULL,
608960484Sobrien/* 78 */	NULL,		NULL,		NULL,		NULL,
609060484Sobrien/* 7C */	NULL,		NULL,		NULL,		NULL,
609160484Sobrien/* 80 */	NULL,		NULL,		NULL,		NULL,
609260484Sobrien/* 84 */	NULL,		NULL,		NULL,		NULL,
609360484Sobrien/* 88 */	NULL,		NULL,		"pfnacc",	NULL,
609460484Sobrien/* 8C */	NULL,		NULL,		"pfpnacc",	NULL,
609560484Sobrien/* 90 */	"pfcmpge",	NULL,		NULL,		NULL,
609660484Sobrien/* 94 */	"pfmin",	NULL,		"pfrcp",	"pfrsqrt",
609760484Sobrien/* 98 */	NULL,		NULL,		"pfsub",	NULL,
609860484Sobrien/* 9C */	NULL,		NULL,		"pfadd",	NULL,
609960484Sobrien/* A0 */	"pfcmpgt",	NULL,		NULL,		NULL,
610060484Sobrien/* A4 */	"pfmax",	NULL,		"pfrcpit1",	"pfrsqit1",
610160484Sobrien/* A8 */	NULL,		NULL,		"pfsubr",	NULL,
610260484Sobrien/* AC */	NULL,		NULL,		"pfacc",	NULL,
610360484Sobrien/* B0 */	"pfcmpeq",	NULL,		NULL,		NULL,
6104218822Sdim/* B4 */	"pfmul",	NULL,		"pfrcpit2",	"pmulhrw",
610560484Sobrien/* B8 */	NULL,		NULL,		NULL,		"pswapd",
610660484Sobrien/* BC */	NULL,		NULL,		NULL,		"pavgusb",
610760484Sobrien/* C0 */	NULL,		NULL,		NULL,		NULL,
610860484Sobrien/* C4 */	NULL,		NULL,		NULL,		NULL,
610960484Sobrien/* C8 */	NULL,		NULL,		NULL,		NULL,
611060484Sobrien/* CC */	NULL,		NULL,		NULL,		NULL,
611160484Sobrien/* D0 */	NULL,		NULL,		NULL,		NULL,
611260484Sobrien/* D4 */	NULL,		NULL,		NULL,		NULL,
611360484Sobrien/* D8 */	NULL,		NULL,		NULL,		NULL,
611460484Sobrien/* DC */	NULL,		NULL,		NULL,		NULL,
611560484Sobrien/* E0 */	NULL,		NULL,		NULL,		NULL,
611660484Sobrien/* E4 */	NULL,		NULL,		NULL,		NULL,
611760484Sobrien/* E8 */	NULL,		NULL,		NULL,		NULL,
611860484Sobrien/* EC */	NULL,		NULL,		NULL,		NULL,
611960484Sobrien/* F0 */	NULL,		NULL,		NULL,		NULL,
612060484Sobrien/* F4 */	NULL,		NULL,		NULL,		NULL,
612160484Sobrien/* F8 */	NULL,		NULL,		NULL,		NULL,
612260484Sobrien/* FC */	NULL,		NULL,		NULL,		NULL,
612360484Sobrien};
612460484Sobrien
612560484Sobrienstatic void
6126130561SobrienOP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
612760484Sobrien{
612860484Sobrien  const char *mnemonic;
612960484Sobrien
6130223262Sbenl  (void) FETCH_DATA (the_info, codep + 1);
613160484Sobrien  /* AMD 3DNow! instructions are specified by an opcode suffix in the
613260484Sobrien     place where an 8-bit immediate would normally go.  ie. the last
613360484Sobrien     byte of the instruction.  */
613485815Sobrien  obufp = obuf + strlen (obuf);
613560484Sobrien  mnemonic = Suffix3DNow[*codep++ & 0xff];
613660484Sobrien  if (mnemonic)
613760484Sobrien    oappend (mnemonic);
613860484Sobrien  else
613960484Sobrien    {
614060484Sobrien      /* Since a variable sized modrm/sib chunk is between the start
614160484Sobrien	 of the opcode (0x0f0f) and the opcode suffix, we need to do
614260484Sobrien	 all the modrm processing first, and don't know until now that
614360484Sobrien	 we have a bad opcode.  This necessitates some cleaning up.  */
6144218822Sdim      op_out[0][0] = '\0';
6145218822Sdim      op_out[1][0] = '\0';
614685815Sobrien      BadOp ();
614760484Sobrien    }
614860484Sobrien}
614960484Sobrien
615085815Sobrienstatic const char *simd_cmp_op[] = {
615160484Sobrien  "eq",
615260484Sobrien  "lt",
615360484Sobrien  "le",
615460484Sobrien  "unord",
615560484Sobrien  "neq",
615660484Sobrien  "nlt",
615760484Sobrien  "nle",
615860484Sobrien  "ord"
615960484Sobrien};
616060484Sobrien
616160484Sobrienstatic void
6162130561SobrienOP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
616360484Sobrien{
616460484Sobrien  unsigned int cmp_type;
616560484Sobrien
6166223262Sbenl  (void) FETCH_DATA (the_info, codep + 1);
616785815Sobrien  obufp = obuf + strlen (obuf);
616860484Sobrien  cmp_type = *codep++ & 0xff;
616960484Sobrien  if (cmp_type < 8)
617060484Sobrien    {
617177298Sobrien      char suffix1 = 'p', suffix2 = 's';
617260484Sobrien      used_prefixes |= (prefixes & PREFIX_REPZ);
617377298Sobrien      if (prefixes & PREFIX_REPZ)
617477298Sobrien	suffix1 = 's';
617577298Sobrien      else
617677298Sobrien	{
617777298Sobrien	  used_prefixes |= (prefixes & PREFIX_DATA);
617877298Sobrien	  if (prefixes & PREFIX_DATA)
617977298Sobrien	    suffix2 = 'd';
618077298Sobrien	  else
618177298Sobrien	    {
618277298Sobrien	      used_prefixes |= (prefixes & PREFIX_REPNZ);
618377298Sobrien	      if (prefixes & PREFIX_REPNZ)
618477298Sobrien		suffix1 = 's', suffix2 = 'd';
618577298Sobrien	    }
618677298Sobrien	}
618777298Sobrien      sprintf (scratchbuf, "cmp%s%c%c",
618877298Sobrien	       simd_cmp_op[cmp_type], suffix1, suffix2);
618977298Sobrien      used_prefixes |= (prefixes & PREFIX_REPZ);
619060484Sobrien      oappend (scratchbuf);
619160484Sobrien    }
619260484Sobrien  else
619360484Sobrien    {
619460484Sobrien      /* We have a bad extension byte.  Clean up.  */
6195218822Sdim      op_out[0][0] = '\0';
6196218822Sdim      op_out[1][0] = '\0';
619785815Sobrien      BadOp ();
619860484Sobrien    }
619960484Sobrien}
620060484Sobrien
620160484Sobrienstatic void
6202130561SobrienSIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
620360484Sobrien{
620460484Sobrien  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
620560484Sobrien     forms of these instructions.  */
6206218822Sdim  if (modrm.mod == 3)
620760484Sobrien    {
620885815Sobrien      char *p = obuf + strlen (obuf);
620985815Sobrien      *(p + 1) = '\0';
621085815Sobrien      *p       = *(p - 1);
621185815Sobrien      *(p - 1) = *(p - 2);
621285815Sobrien      *(p - 2) = *(p - 3);
621385815Sobrien      *(p - 3) = extrachar;
621460484Sobrien    }
621560484Sobrien}
621660484Sobrien
621785815Sobrienstatic void
6218130561SobrienPNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6219130561Sobrien{
6220218822Sdim  if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
6221130561Sobrien    {
6222218822Sdim      /* Override "sidt".  */
6223218822Sdim      size_t olen = strlen (obuf);
6224218822Sdim      char *p = obuf + olen - 4;
6225218822Sdim      const char **names = (address_mode == mode_64bit
6226218822Sdim			    ? names64 : names32);
6227130561Sobrien
6228218822Sdim      /* We might have a suffix when disassembling with -Msuffix.  */
6229218822Sdim      if (*p == 'i')
6230218822Sdim	--p;
6231218822Sdim
6232218822Sdim      /* Remove "addr16/addr32" if we aren't in Intel mode.  */
6233218822Sdim      if (!intel_syntax
6234218822Sdim	  && (prefixes & PREFIX_ADDR)
6235218822Sdim	  && olen >= (4 + 7)
6236218822Sdim	  && *(p - 1) == ' '
6237218822Sdim	  && CONST_STRNEQ (p - 7, "addr")
6238218822Sdim	  && (CONST_STRNEQ (p - 3, "16")
6239218822Sdim	      || CONST_STRNEQ (p - 3, "32")))
6240218822Sdim	p -= 7;
6241218822Sdim
6242218822Sdim      if (modrm.rm)
6243130561Sobrien	{
6244130561Sobrien	  /* mwait %eax,%ecx  */
6245218822Sdim	  strcpy (p, "mwait");
6246218822Sdim	  if (!intel_syntax)
6247218822Sdim	    strcpy (op_out[0], names[0]);
6248130561Sobrien	}
6249130561Sobrien      else
6250130561Sobrien	{
6251130561Sobrien	  /* monitor %eax,%ecx,%edx"  */
6252218822Sdim	  strcpy (p, "monitor");
6253218822Sdim	  if (!intel_syntax)
6254218822Sdim	    {
6255218822Sdim	      const char **op1_names;
6256218822Sdim	      if (!(prefixes & PREFIX_ADDR))
6257218822Sdim		op1_names = (address_mode == mode_16bit
6258218822Sdim			     ? names16 : names);
6259218822Sdim	      else
6260218822Sdim		{
6261218822Sdim		  op1_names = (address_mode != mode_32bit
6262218822Sdim			       ? names32 : names16);
6263218822Sdim		  used_prefixes |= PREFIX_ADDR;
6264218822Sdim		}
6265218822Sdim	      strcpy (op_out[0], op1_names[0]);
6266218822Sdim	      strcpy (op_out[2], names[2]);
6267218822Sdim	    }
6268130561Sobrien	}
6269218822Sdim      if (!intel_syntax)
6270218822Sdim	{
6271218822Sdim	  strcpy (op_out[1], names[1]);
6272218822Sdim	  two_source_ops = 1;
6273218822Sdim	}
6274130561Sobrien
6275130561Sobrien      codep++;
6276130561Sobrien    }
6277261175Spfg  else if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 3)
6278261175Spfg    {
6279261175Spfg      size_t olen = strlen (obuf);
6280261175Spfg      char *p = obuf + olen - 4;
6281261175Spfg      if (*codep == 0xca)
6282261175Spfg        strcpy (p, "clac");
6283261175Spfg      else if (*codep == 0xcb)
6284261175Spfg        strcpy (p, "stac");
6285261175Spfg      codep++;
6286261175Spfg    }
6287130561Sobrien  else
6288218822Sdim    OP_M (0, sizeflag);
6289130561Sobrien}
6290130561Sobrien
6291130561Sobrienstatic void
6292238123SjhbXCR_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6293238123Sjhb{
6294238123Sjhb  if (modrm.mod == 3 && modrm.reg == 2 && modrm.rm <= 1)
6295238123Sjhb    {
6296238123Sjhb      /* Override "lgdt".  */
6297238123Sjhb      size_t olen = strlen (obuf);
6298238123Sjhb      char *p = obuf + olen - 4;
6299238123Sjhb
6300238123Sjhb      /* We might have a suffix when disassembling with -Msuffix.  */
6301238123Sjhb      if (*p == 'i')
6302238123Sjhb	--p;
6303238123Sjhb
6304238123Sjhb      /* Remove "addr16/addr32" if we aren't in Intel mode.  */
6305238123Sjhb      if (!intel_syntax
6306238123Sjhb	  && (prefixes & PREFIX_ADDR)
6307238123Sjhb	  && olen >= (4 + 7)
6308238123Sjhb	  && *(p - 1) == ' '
6309238123Sjhb	  && CONST_STRNEQ (p - 7, "addr")
6310238123Sjhb	  && (CONST_STRNEQ (p - 3, "16")
6311238123Sjhb	      || CONST_STRNEQ (p - 3, "32")))
6312238123Sjhb	p -= 7;
6313238123Sjhb
6314238123Sjhb      if (modrm.rm)
6315238123Sjhb	{
6316238123Sjhb	  strcpy (p, "xsetbv");
6317238123Sjhb	}
6318238123Sjhb      else
6319238123Sjhb	{
6320238123Sjhb	  strcpy (p, "xgetbv");
6321238123Sjhb	}
6322238123Sjhb
6323238123Sjhb      codep++;
6324238123Sjhb    }
6325238123Sjhb  else
6326238123Sjhb    OP_M (0, sizeflag);
6327238123Sjhb}
6328238123Sjhbstatic void
6329218822SdimSVME_Fixup (int bytemode, int sizeflag)
6330218822Sdim{
6331218822Sdim  const char *alt;
6332218822Sdim  char *p;
6333218822Sdim
6334218822Sdim  switch (*codep)
6335218822Sdim    {
6336218822Sdim    case 0xd8:
6337218822Sdim      alt = "vmrun";
6338218822Sdim      break;
6339218822Sdim    case 0xd9:
6340218822Sdim      alt = "vmmcall";
6341218822Sdim      break;
6342218822Sdim    case 0xda:
6343218822Sdim      alt = "vmload";
6344218822Sdim      break;
6345218822Sdim    case 0xdb:
6346218822Sdim      alt = "vmsave";
6347218822Sdim      break;
6348218822Sdim    case 0xdc:
6349218822Sdim      alt = "stgi";
6350218822Sdim      break;
6351218822Sdim    case 0xdd:
6352218822Sdim      alt = "clgi";
6353218822Sdim      break;
6354218822Sdim    case 0xde:
6355218822Sdim      alt = "skinit";
6356218822Sdim      break;
6357218822Sdim    case 0xdf:
6358218822Sdim      alt = "invlpga";
6359218822Sdim      break;
6360218822Sdim    default:
6361218822Sdim      OP_M (bytemode, sizeflag);
6362218822Sdim      return;
6363218822Sdim    }
6364218822Sdim  /* Override "lidt".  */
6365218822Sdim  p = obuf + strlen (obuf) - 4;
6366218822Sdim  /* We might have a suffix.  */
6367218822Sdim  if (*p == 'i')
6368218822Sdim    --p;
6369218822Sdim  strcpy (p, alt);
6370218822Sdim  if (!(prefixes & PREFIX_ADDR))
6371218822Sdim    {
6372218822Sdim      ++codep;
6373218822Sdim      return;
6374218822Sdim    }
6375218822Sdim  used_prefixes |= PREFIX_ADDR;
6376218822Sdim  switch (*codep++)
6377218822Sdim    {
6378218822Sdim    case 0xdf:
6379218822Sdim      strcpy (op_out[1], names32[1]);
6380218822Sdim      two_source_ops = 1;
6381218822Sdim	  /* Fall through.  */
6382218822Sdim    case 0xd8:
6383218822Sdim    case 0xda:
6384218822Sdim    case 0xdb:
6385218822Sdim      *obufp++ = open_char;
6386218822Sdim      if (address_mode == mode_64bit || (sizeflag & AFLAG))
6387218822Sdim        alt = names32[0];
6388218822Sdim      else
6389218822Sdim        alt = names16[0];
6390218822Sdim      strcpy (obufp, alt);
6391218822Sdim      obufp += strlen (alt);
6392218822Sdim      *obufp++ = close_char;
6393218822Sdim      *obufp = '\0';
6394218822Sdim      break;
6395218822Sdim    }
6396218822Sdim}
6397218822Sdim
6398218822Sdimstatic void
6399130561SobrienINVLPG_Fixup (int bytemode, int sizeflag)
6400130561Sobrien{
6401218822Sdim  const char *alt;
6402218822Sdim
6403218822Sdim  switch (*codep)
6404130561Sobrien    {
6405218822Sdim    case 0xf8:
6406218822Sdim      alt = "swapgs";
6407218822Sdim      break;
6408218822Sdim    case 0xf9:
6409218822Sdim      alt = "rdtscp";
6410218822Sdim      break;
6411218822Sdim    default:
6412218822Sdim      OP_M (bytemode, sizeflag);
6413218822Sdim      return;
6414130561Sobrien    }
6415218822Sdim  /* Override "invlpg".  */
6416218822Sdim  strcpy (obuf + strlen (obuf) - 6, alt);
6417218822Sdim  codep++;
6418130561Sobrien}
6419130561Sobrien
6420130561Sobrienstatic void
642185815SobrienBadOp (void)
642260484Sobrien{
642385815Sobrien  /* Throw away prefixes and 1st. opcode byte.  */
642485815Sobrien  codep = insn_codep + 1;
642560484Sobrien  oappend ("(bad)");
642660484Sobrien}
6427218822Sdim
6428218822Sdimstatic void
6429218822SdimVMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6430218822Sdim{
6431218822Sdim  if (modrm.mod == 3
6432218822Sdim      && modrm.reg == 0
6433218822Sdim      && modrm.rm >=1
6434218822Sdim      && modrm.rm <= 4)
6435218822Sdim    {
6436218822Sdim      /* Override "sgdt".  */
6437218822Sdim      char *p = obuf + strlen (obuf) - 4;
6438218822Sdim
6439218822Sdim      /* We might have a suffix when disassembling with -Msuffix.  */
6440218822Sdim      if (*p == 'g')
6441218822Sdim	--p;
6442218822Sdim
6443218822Sdim      switch (modrm.rm)
6444218822Sdim	{
6445218822Sdim	case 1:
6446218822Sdim	  strcpy (p, "vmcall");
6447218822Sdim	  break;
6448218822Sdim	case 2:
6449218822Sdim	  strcpy (p, "vmlaunch");
6450218822Sdim	  break;
6451218822Sdim	case 3:
6452218822Sdim	  strcpy (p, "vmresume");
6453218822Sdim	  break;
6454218822Sdim	case 4:
6455218822Sdim	  strcpy (p, "vmxoff");
6456218822Sdim	  break;
6457218822Sdim	}
6458218822Sdim
6459218822Sdim      codep++;
6460218822Sdim    }
6461218822Sdim  else
6462218822Sdim    OP_E (0, sizeflag);
6463218822Sdim}
6464218822Sdim
6465218822Sdimstatic void
6466218822SdimOP_VMX (int bytemode, int sizeflag)
6467218822Sdim{
6468256112Sdim  if (modrm.mod == 3)
6469256112Sdim    {
6470256112Sdim      strcpy (obuf, "rdrand");
6471256112Sdim      OP_E (v_mode, sizeflag);
6472256112Sdim    }
6473218822Sdim  else
6474256112Sdim    {
6475256112Sdim      used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6476256112Sdim      if (prefixes & PREFIX_DATA)
6477256112Sdim	strcpy (obuf, "vmclear");
6478256112Sdim      else if (prefixes & PREFIX_REPZ)
6479256112Sdim	strcpy (obuf, "vmxon");
6480256112Sdim      else
6481256112Sdim	strcpy (obuf, "vmptrld");
6482256112Sdim      OP_E (bytemode, sizeflag);
6483256112Sdim    }
6484218822Sdim}
6485218822Sdim
6486218822Sdimstatic void
6487266391SjhbOP_VMX2 (int bytemode, int sizeflag)
6488266391Sjhb{
6489266391Sjhb  if (modrm.mod == 3)
6490266391Sjhb    {
6491266391Sjhb      strcpy (obuf, "rdseed");
6492266391Sjhb      OP_E (v_mode, sizeflag);
6493266391Sjhb    }
6494266391Sjhb  else
6495266391Sjhb    {
6496266391Sjhb      strcpy (obuf, "vmptrst");
6497266391Sjhb      OP_M (q_mode, sizeflag);
6498266391Sjhb    }
6499266391Sjhb}
6500266391Sjhb
6501266391Sjhbstatic void
6502218822SdimREP_Fixup (int bytemode, int sizeflag)
6503218822Sdim{
6504218822Sdim  /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6505218822Sdim     lods and stos.  */
6506218822Sdim  size_t ilen = 0;
6507218822Sdim
6508218822Sdim  if (prefixes & PREFIX_REPZ)
6509218822Sdim    switch (*insn_codep)
6510218822Sdim      {
6511218822Sdim      case 0x6e:	/* outsb */
6512218822Sdim      case 0x6f:	/* outsw/outsl */
6513218822Sdim      case 0xa4:	/* movsb */
6514218822Sdim      case 0xa5:	/* movsw/movsl/movsq */
6515218822Sdim	if (!intel_syntax)
6516218822Sdim	  ilen = 5;
6517218822Sdim	else
6518218822Sdim	  ilen = 4;
6519218822Sdim	break;
6520218822Sdim      case 0xaa:	/* stosb */
6521218822Sdim      case 0xab:	/* stosw/stosl/stosq */
6522218822Sdim      case 0xac:	/* lodsb */
6523218822Sdim      case 0xad:	/* lodsw/lodsl/lodsq */
6524218822Sdim	if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6525218822Sdim	  ilen = 5;
6526218822Sdim	else
6527218822Sdim	  ilen = 4;
6528218822Sdim	break;
6529218822Sdim      case 0x6c:	/* insb */
6530218822Sdim      case 0x6d:	/* insl/insw */
6531218822Sdim	if (!intel_syntax)
6532218822Sdim	  ilen = 4;
6533218822Sdim	else
6534218822Sdim	  ilen = 3;
6535218822Sdim	break;
6536218822Sdim      default:
6537218822Sdim	abort ();
6538218822Sdim	break;
6539218822Sdim      }
6540218822Sdim
6541218822Sdim  if (ilen != 0)
6542218822Sdim    {
6543218822Sdim      size_t olen;
6544218822Sdim      char *p;
6545218822Sdim
6546218822Sdim      olen = strlen (obuf);
6547218822Sdim      p = obuf + olen - ilen - 1 - 4;
6548218822Sdim      /* Handle "repz [addr16|addr32]".  */
6549218822Sdim      if ((prefixes & PREFIX_ADDR))
6550218822Sdim	p -= 1 + 6;
6551218822Sdim
6552218822Sdim      memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6553218822Sdim    }
6554218822Sdim
6555218822Sdim  switch (bytemode)
6556218822Sdim    {
6557218822Sdim    case al_reg:
6558218822Sdim    case eAX_reg:
6559218822Sdim    case indir_dx_reg:
6560218822Sdim      OP_IMREG (bytemode, sizeflag);
6561218822Sdim      break;
6562218822Sdim    case eDI_reg:
6563218822Sdim      OP_ESreg (bytemode, sizeflag);
6564218822Sdim      break;
6565218822Sdim    case eSI_reg:
6566218822Sdim      OP_DSreg (bytemode, sizeflag);
6567218822Sdim      break;
6568218822Sdim    default:
6569218822Sdim      abort ();
6570218822Sdim      break;
6571218822Sdim    }
6572218822Sdim}
6573218822Sdim
6574218822Sdimstatic void
6575218822SdimCMPXCHG8B_Fixup (int bytemode, int sizeflag)
6576218822Sdim{
6577218822Sdim  USED_REX (REX_W);
6578218822Sdim  if (rex & REX_W)
6579218822Sdim    {
6580218822Sdim      /* Change cmpxchg8b to cmpxchg16b.  */
6581218822Sdim      char *p = obuf + strlen (obuf) - 2;
6582218822Sdim      strcpy (p, "16b");
6583218822Sdim      bytemode = o_mode;
6584218822Sdim    }
6585218822Sdim  OP_M (bytemode, sizeflag);
6586218822Sdim}
6587218822Sdim
6588218822Sdimstatic void
6589218822SdimXMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6590218822Sdim{
6591218822Sdim  sprintf (scratchbuf, "%%xmm%d", reg);
6592257464Ssbruno  oappend (&scratchbuf[intel_syntax]);
6593218822Sdim}
6594218822Sdim
6595218822Sdimstatic void
6596218822SdimCRC32_Fixup (int bytemode, int sizeflag)
6597218822Sdim{
6598218822Sdim  /* Add proper suffix to "crc32".  */
6599218822Sdim  char *p = obuf + strlen (obuf);
6600218822Sdim
6601218822Sdim  switch (bytemode)
6602218822Sdim    {
6603218822Sdim    case b_mode:
6604218822Sdim      if (intel_syntax)
6605218822Sdim	break;
6606218822Sdim
6607218822Sdim      *p++ = 'b';
6608218822Sdim      break;
6609218822Sdim    case v_mode:
6610218822Sdim      if (intel_syntax)
6611218822Sdim	break;
6612218822Sdim
6613218822Sdim      USED_REX (REX_W);
6614218822Sdim      if (rex & REX_W)
6615218822Sdim	*p++ = 'q';
6616218822Sdim      else if (sizeflag & DFLAG)
6617218822Sdim	*p++ = 'l';
6618218822Sdim      else
6619218822Sdim	*p++ = 'w';
6620218822Sdim      used_prefixes |= (prefixes & PREFIX_DATA);
6621218822Sdim      break;
6622218822Sdim    default:
6623218822Sdim      oappend (INTERNAL_DISASSEMBLER_ERROR);
6624218822Sdim      break;
6625218822Sdim    }
6626218822Sdim  *p = '\0';
6627218822Sdim
6628218822Sdim  if (modrm.mod == 3)
6629218822Sdim    {
6630218822Sdim      int add;
6631218822Sdim
6632218822Sdim      /* Skip mod/rm byte.  */
6633218822Sdim      MODRM_CHECK;
6634218822Sdim      codep++;
6635218822Sdim
6636218822Sdim      USED_REX (REX_B);
6637218822Sdim      add = (rex & REX_B) ? 8 : 0;
6638218822Sdim      if (bytemode == b_mode)
6639218822Sdim	{
6640218822Sdim	  USED_REX (0);
6641218822Sdim	  if (rex)
6642218822Sdim	    oappend (names8rex[modrm.rm + add]);
6643218822Sdim	  else
6644218822Sdim	    oappend (names8[modrm.rm + add]);
6645218822Sdim	}
6646218822Sdim      else
6647218822Sdim	{
6648218822Sdim	  USED_REX (REX_W);
6649218822Sdim	  if (rex & REX_W)
6650218822Sdim	    oappend (names64[modrm.rm + add]);
6651218822Sdim	  else if ((prefixes & PREFIX_DATA))
6652218822Sdim	    oappend (names16[modrm.rm + add]);
6653218822Sdim	  else
6654218822Sdim	    oappend (names32[modrm.rm + add]);
6655218822Sdim	}
6656218822Sdim    }
6657218822Sdim  else
6658218822Sdim    OP_E (bytemode, sizeflag);
6659218822Sdim}
6660