]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/i386-dis.c
2006-09-16 Paul Brook <paul@codesourcery.com>
[thirdparty/binutils-gdb.git] / opcodes / i386-dis.c
CommitLineData
252b5132 1/* Print i386 instructions for GDB, the GNU debugger.
060d22b0 2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
aef6203b 3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
252b5132 4
20f0a1fc
NC
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
f4321104 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20f0a1fc
NC
20
21/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 July 1988
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
26
27/* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
252b5132
RH
33
34#include "dis-asm.h"
35#include "sysdep.h"
36#include "opintl.h"
37
272c9217 38#define MAXLEN 15
252b5132
RH
39
40#include <setjmp.h>
41
42#ifndef UNIXWARE_COMPAT
43/* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45#define UNIXWARE_COMPAT 1
46#endif
47
26ca5450
AJ
48static int fetch_data (struct disassemble_info *, bfd_byte *);
49static void ckprefix (void);
50static const char *prefix_name (int, int);
51static int print_insn (bfd_vma, disassemble_info *);
52static void dofloat (int);
53static void OP_ST (int, int);
54static void OP_STi (int, int);
55static int putop (const char *, int);
56static void oappend (const char *);
57static void append_seg (void);
58static void OP_indirE (int, int);
59static void print_operand_value (char *, int, bfd_vma);
60static void OP_E (int, int);
61static void OP_G (int, int);
62static bfd_vma get64 (void);
63static bfd_signed_vma get32 (void);
64static bfd_signed_vma get32s (void);
65static int get16 (void);
66static void set_op (bfd_vma, int);
67static void OP_REG (int, int);
68static void OP_IMREG (int, int);
69static void OP_I (int, int);
70static void OP_I64 (int, int);
71static void OP_sI (int, int);
72static void OP_J (int, int);
73static void OP_SEG (int, int);
74static void OP_DIR (int, int);
75static void OP_OFF (int, int);
76static void OP_OFF64 (int, int);
77static void ptr_reg (int, int);
78static void OP_ESreg (int, int);
79static void OP_DSreg (int, int);
80static void OP_C (int, int);
81static void OP_D (int, int);
82static void OP_T (int, int);
83static void OP_Rd (int, int);
84static void OP_MMX (int, int);
85static void OP_XMM (int, int);
86static void OP_EM (int, int);
87static void OP_EX (int, int);
4d9567e0
MM
88static void OP_EMC (int,int);
89static void OP_MXC (int,int);
26ca5450
AJ
90static void OP_MS (int, int);
91static void OP_XS (int, int);
cc0ec051 92static void OP_M (int, int);
90700ea2 93static void OP_VMX (int, int);
cc0ec051
AM
94static void OP_0fae (int, int);
95static void OP_0f07 (int, int);
46e883c5
L
96static void NOP_Fixup1 (int, int);
97static void NOP_Fixup2 (int, int);
26ca5450
AJ
98static void OP_3DNowSuffix (int, int);
99static void OP_SIMD_Suffix (int, int);
100static void SIMD_Fixup (int, int);
101static void PNI_Fixup (int, int);
30123838 102static void SVME_Fixup (int, int);
4fd61dcb 103static void INVLPG_Fixup (int, int);
26ca5450 104static void BadOp (void);
4cc91dba 105static void SEG_Fixup (int, int);
90700ea2 106static void VMX_Fixup (int, int);
35c52694 107static void REP_Fixup (int, int);
252b5132 108
6608db57 109struct dis_private {
252b5132
RH
110 /* Points to first byte not fetched. */
111 bfd_byte *max_fetched;
112 bfd_byte the_buffer[MAXLEN];
113 bfd_vma insn_start;
e396998b 114 int orig_sizeflag;
252b5132
RH
115 jmp_buf bailout;
116};
117
5076851f
ILT
118/* The opcode for the fwait instruction, which we treat as a prefix
119 when we can. */
120#define FWAIT_OPCODE (0x9b)
121
cb712a9e
L
122enum address_mode
123{
124 mode_16bit,
125 mode_32bit,
126 mode_64bit
127};
128
129enum address_mode address_mode;
52b15da3 130
5076851f
ILT
131/* Flags for the prefixes for the current instruction. See below. */
132static int prefixes;
133
52b15da3
JH
134/* REX prefix the current instruction. See below. */
135static int rex;
136/* Bits of REX we've already used. */
137static int rex_used;
138#define REX_MODE64 8
139#define REX_EXTX 4
140#define REX_EXTY 2
141#define REX_EXTZ 1
142/* Mark parts used in the REX prefix. When we are testing for
143 empty prefix (for 8bit register REX extension), just mask it
144 out. Otherwise test for REX bit is excuse for existence of REX
145 only in case value is nonzero. */
146#define USED_REX(value) \
147 { \
148 if (value) \
149 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
150 else \
151 rex_used |= 0x40; \
152 }
153
7d421014
ILT
154/* Flags for prefixes which we somehow handled when printing the
155 current instruction. */
156static int used_prefixes;
157
5076851f
ILT
158/* Flags stored in PREFIXES. */
159#define PREFIX_REPZ 1
160#define PREFIX_REPNZ 2
161#define PREFIX_LOCK 4
162#define PREFIX_CS 8
163#define PREFIX_SS 0x10
164#define PREFIX_DS 0x20
165#define PREFIX_ES 0x40
166#define PREFIX_FS 0x80
167#define PREFIX_GS 0x100
168#define PREFIX_DATA 0x200
169#define PREFIX_ADDR 0x400
170#define PREFIX_FWAIT 0x800
171
252b5132
RH
172/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
173 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
174 on error. */
175#define FETCH_DATA(info, addr) \
6608db57 176 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
252b5132
RH
177 ? 1 : fetch_data ((info), (addr)))
178
179static int
26ca5450 180fetch_data (struct disassemble_info *info, bfd_byte *addr)
252b5132
RH
181{
182 int status;
6608db57 183 struct dis_private *priv = (struct dis_private *) info->private_data;
252b5132
RH
184 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
185
272c9217
JB
186 if (addr <= priv->the_buffer + MAXLEN)
187 status = (*info->read_memory_func) (start,
188 priv->max_fetched,
189 addr - priv->max_fetched,
190 info);
191 else
192 status = -1;
252b5132
RH
193 if (status != 0)
194 {
7d421014 195 /* If we did manage to read at least one byte, then
db6eb5be
AM
196 print_insn_i386 will do something sensible. Otherwise, print
197 an error. We do that here because this is where we know
198 STATUS. */
7d421014 199 if (priv->max_fetched == priv->the_buffer)
5076851f 200 (*info->memory_error_func) (status, start, info);
252b5132
RH
201 longjmp (priv->bailout, 1);
202 }
203 else
204 priv->max_fetched = addr;
205 return 1;
206}
207
57d91c3c
ILT
208#define XX NULL, 0
209
252b5132 210#define Eb OP_E, b_mode
52b15da3
JH
211#define Ev OP_E, v_mode
212#define Ed OP_E, d_mode
9306ca4a 213#define Eq OP_E, q_mode
db6eb5be 214#define Edq OP_E, dq_mode
9306ca4a 215#define Edqw OP_E, dqw_mode
1a114b12 216#define indirEv OP_indirE, stack_v_mode
9306ca4a 217#define indirEp OP_indirE, f_mode
1a114b12 218#define stackEv OP_E, stack_v_mode
90700ea2 219#define Em OP_E, m_mode
252b5132
RH
220#define Ew OP_E, w_mode
221#define Ma OP_E, v_mode
cc0ec051 222#define M OP_M, 0 /* lea, lgdt, etc. */
9306ca4a 223#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
992aaec9 224#define Gb OP_G, b_mode
252b5132 225#define Gv OP_G, v_mode
992aaec9 226#define Gd OP_G, d_mode
9306ca4a 227#define Gdq OP_G, dq_mode
90700ea2 228#define Gm OP_G, m_mode
252b5132 229#define Gw OP_G, w_mode
2da11e11 230#define Rd OP_Rd, d_mode
52b15da3 231#define Rm OP_Rd, m_mode
252b5132
RH
232#define Ib OP_I, b_mode
233#define sIb OP_sI, b_mode /* sign extened byte */
234#define Iv OP_I, v_mode
52b15da3
JH
235#define Iq OP_I, q_mode
236#define Iv64 OP_I64, v_mode
252b5132 237#define Iw OP_I, w_mode
9306ca4a 238#define I1 OP_I, const_1_mode
252b5132
RH
239#define Jb OP_J, b_mode
240#define Jv OP_J, v_mode
52b15da3
JH
241#define Cm OP_C, m_mode
242#define Dm OP_D, m_mode
252b5132 243#define Td OP_T, d_mode
4cc91dba 244#define Sv SEG_Fixup, v_mode
252b5132 245
52b15da3
JH
246#define RMeAX OP_REG, eAX_reg
247#define RMeBX OP_REG, eBX_reg
248#define RMeCX OP_REG, eCX_reg
249#define RMeDX OP_REG, eDX_reg
250#define RMeSP OP_REG, eSP_reg
251#define RMeBP OP_REG, eBP_reg
252#define RMeSI OP_REG, eSI_reg
253#define RMeDI OP_REG, eDI_reg
254#define RMrAX OP_REG, rAX_reg
255#define RMrBX OP_REG, rBX_reg
256#define RMrCX OP_REG, rCX_reg
257#define RMrDX OP_REG, rDX_reg
258#define RMrSP OP_REG, rSP_reg
259#define RMrBP OP_REG, rBP_reg
260#define RMrSI OP_REG, rSI_reg
261#define RMrDI OP_REG, rDI_reg
262#define RMAL OP_REG, al_reg
263#define RMAL OP_REG, al_reg
264#define RMCL OP_REG, cl_reg
265#define RMDL OP_REG, dl_reg
266#define RMBL OP_REG, bl_reg
267#define RMAH OP_REG, ah_reg
268#define RMCH OP_REG, ch_reg
269#define RMDH OP_REG, dh_reg
270#define RMBH OP_REG, bh_reg
271#define RMAX OP_REG, ax_reg
272#define RMDX OP_REG, dx_reg
273
274#define eAX OP_IMREG, eAX_reg
275#define eBX OP_IMREG, eBX_reg
276#define eCX OP_IMREG, eCX_reg
277#define eDX OP_IMREG, eDX_reg
278#define eSP OP_IMREG, eSP_reg
279#define eBP OP_IMREG, eBP_reg
280#define eSI OP_IMREG, eSI_reg
281#define eDI OP_IMREG, eDI_reg
282#define AL OP_IMREG, al_reg
52b15da3
JH
283#define CL OP_IMREG, cl_reg
284#define DL OP_IMREG, dl_reg
285#define BL OP_IMREG, bl_reg
286#define AH OP_IMREG, ah_reg
287#define CH OP_IMREG, ch_reg
288#define DH OP_IMREG, dh_reg
289#define BH OP_IMREG, bh_reg
290#define AX OP_IMREG, ax_reg
291#define DX OP_IMREG, dx_reg
292#define indirDX OP_IMREG, indir_dx_reg
252b5132
RH
293
294#define Sw OP_SEG, w_mode
c608c12e 295#define Ap OP_DIR, 0
1a114b12
JB
296#define Ob OP_OFF64, b_mode
297#define Ov OP_OFF64, v_mode
252b5132
RH
298#define Xb OP_DSreg, eSI_reg
299#define Xv OP_DSreg, eSI_reg
300#define Yb OP_ESreg, eDI_reg
301#define Yv OP_ESreg, eDI_reg
302#define DSBX OP_DSreg, eBX_reg
303
304#define es OP_REG, es_reg
305#define ss OP_REG, ss_reg
306#define cs OP_REG, cs_reg
307#define ds OP_REG, ds_reg
308#define fs OP_REG, fs_reg
309#define gs OP_REG, gs_reg
310
311#define MX OP_MMX, 0
c608c12e 312#define XM OP_XMM, 0
252b5132 313#define EM OP_EM, v_mode
c608c12e 314#define EX OP_EX, v_mode
2da11e11 315#define MS OP_MS, v_mode
992aaec9 316#define XS OP_XS, v_mode
4d9567e0
MM
317#define EMC OP_EMC, v_mode
318#define MXC OP_MXC, 0
90700ea2 319#define VM OP_VMX, q_mode
252b5132 320#define OPSUF OP_3DNowSuffix, 0
c608c12e 321#define OPSIMD OP_SIMD_Suffix, 0
252b5132 322
35c52694
L
323/* Used handle "rep" prefix for string instructions. */
324#define Xbr REP_Fixup, eSI_reg
325#define Xvr REP_Fixup, eSI_reg
326#define Ybr REP_Fixup, eDI_reg
327#define Yvr REP_Fixup, eDI_reg
328#define indirDXr REP_Fixup, indir_dx_reg
329#define ALr REP_Fixup, al_reg
330#define eAXr REP_Fixup, eAX_reg
331
3ffd33cf
AM
332#define cond_jump_flag NULL, cond_jump_mode
333#define loop_jcxz_flag NULL, loop_jcxz_mode
334
252b5132 335/* bits in sizeflag */
252b5132 336#define SUFFIX_ALWAYS 4
252b5132
RH
337#define AFLAG 2
338#define DFLAG 1
339
52b15da3
JH
340#define b_mode 1 /* byte operand */
341#define v_mode 2 /* operand size depends on prefixes */
342#define w_mode 3 /* word operand */
343#define d_mode 4 /* double word operand */
344#define q_mode 5 /* quad word operand */
9306ca4a
JB
345#define t_mode 6 /* ten-byte operand */
346#define x_mode 7 /* 16-byte XMM operand */
347#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
348#define cond_jump_mode 9
349#define loop_jcxz_mode 10
350#define dq_mode 11 /* operand size depends on REX prefixes. */
351#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
352#define f_mode 13 /* 4- or 6-byte pointer operand */
353#define const_1_mode 14
1a114b12 354#define stack_v_mode 15 /* v_mode for stack-related opcodes. */
252b5132
RH
355
356#define es_reg 100
357#define cs_reg 101
358#define ss_reg 102
359#define ds_reg 103
360#define fs_reg 104
361#define gs_reg 105
252b5132 362
c608c12e
AM
363#define eAX_reg 108
364#define eCX_reg 109
365#define eDX_reg 110
366#define eBX_reg 111
367#define eSP_reg 112
368#define eBP_reg 113
369#define eSI_reg 114
370#define eDI_reg 115
252b5132
RH
371
372#define al_reg 116
373#define cl_reg 117
374#define dl_reg 118
375#define bl_reg 119
376#define ah_reg 120
377#define ch_reg 121
378#define dh_reg 122
379#define bh_reg 123
380
381#define ax_reg 124
382#define cx_reg 125
383#define dx_reg 126
384#define bx_reg 127
385#define sp_reg 128
386#define bp_reg 129
387#define si_reg 130
388#define di_reg 131
389
52b15da3
JH
390#define rAX_reg 132
391#define rCX_reg 133
392#define rDX_reg 134
393#define rBX_reg 135
394#define rSP_reg 136
395#define rBP_reg 137
396#define rSI_reg 138
397#define rDI_reg 139
398
252b5132
RH
399#define indir_dx_reg 150
400
6439fc28
AM
401#define FLOATCODE 1
402#define USE_GROUPS 2
403#define USE_PREFIX_USER_TABLE 3
404#define X86_64_SPECIAL 4
331d2d0d 405#define IS_3BYTE_OPCODE 5
6439fc28 406
050dfa73
MM
407#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
408
409#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
410#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
411#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
412#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
413#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
414#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
415#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
416#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
417#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
418#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
419#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
420#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
421#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
422#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
423#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
424#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
425#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
a6bd098c
L
426#define GRP11_C6 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
427#define GRP11_C7 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
428#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
429#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
430#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
431#define GRP15 NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
432#define GRP16 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
433#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
434#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
435#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
050dfa73
MM
436
437#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
438#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
439#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
440#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
441#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
442#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
443#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
444#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
445#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
446#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
447#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
448#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
449#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
450#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
451#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
452#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
453#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
454#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
455#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
456#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
457#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
458#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
459#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
460#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
461#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
462#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
463#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
464#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
465#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
466#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
467#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
468#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
469#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
470#define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
471#define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
472#define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
473#define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
474
475#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
476
477#define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
478#define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
331d2d0d 479
26ca5450 480typedef void (*op_rtn) (int bytemode, int sizeflag);
252b5132
RH
481
482struct dis386 {
2da11e11 483 const char *name;
252b5132
RH
484 op_rtn op1;
485 int bytemode1;
486 op_rtn op2;
487 int bytemode2;
488 op_rtn op3;
489 int bytemode3;
050dfa73
MM
490 op_rtn op4;
491 int bytemode4;
252b5132
RH
492};
493
494/* Upper case letters in the instruction names here are macros.
495 'A' => print 'b' if no register operands or suffix_always is true
496 'B' => print 'b' if suffix_always is true
9306ca4a
JB
497 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
498 . size prefix
252b5132 499 'E' => print 'e' if 32-bit form of jcxz
3ffd33cf 500 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
5dd0794d 501 'H' => print ",pt" or ",pn" branch hint
9306ca4a
JB
502 'I' => honor following macro letter even in Intel mode (implemented only
503 . for some of the macro letters)
504 'J' => print 'l'
252b5132
RH
505 'L' => print 'l' if suffix_always is true
506 'N' => print 'n' if instruction has no wait "prefix"
52b15da3
JH
507 'O' => print 'd', or 'o'
508 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
e396998b
AM
509 . or suffix_always is true. print 'q' if rex prefix is present.
510 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
511 . is true
52b15da3
JH
512 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
513 'S' => print 'w', 'l' or 'q' if suffix_always is true
6439fc28
AM
514 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
515 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
1a114b12 516 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
10084519 517 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
9306ca4a 518 'X' => print 's', 'd' depending on data16 prefix (for XMM)
76f227a5 519 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
6dd5059a 520 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
52b15da3 521
6439fc28
AM
522 Many of the above letters print nothing in Intel mode. See "putop"
523 for the details.
52b15da3 524
6439fc28
AM
525 Braces '{' and '}', and vertical bars '|', indicate alternative
526 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
527 modes. In cases where there are only two alternatives, the X86_64
528 instruction is reserved, and "(bad)" is printed.
529*/
252b5132 530
6439fc28 531static const struct dis386 dis386[] = {
252b5132 532 /* 00 */
050dfa73
MM
533 { "addB", Eb, Gb, XX, XX },
534 { "addS", Ev, Gv, XX, XX },
535 { "addB", Gb, Eb, XX, XX },
536 { "addS", Gv, Ev, XX, XX },
537 { "addB", AL, Ib, XX, XX },
538 { "addS", eAX, Iv, XX, XX },
539 { "push{T|}", es, XX, XX, XX },
540 { "pop{T|}", es, XX, XX, XX },
252b5132 541 /* 08 */
050dfa73
MM
542 { "orB", Eb, Gb, XX, XX },
543 { "orS", Ev, Gv, XX, XX },
544 { "orB", Gb, Eb, XX, XX },
545 { "orS", Gv, Ev, XX , XX},
546 { "orB", AL, Ib, XX, XX },
547 { "orS", eAX, Iv, XX, XX },
548 { "push{T|}", cs, XX, XX, XX },
549 { "(bad)", XX, XX, XX, XX }, /* 0x0f extended opcode escape */
252b5132 550 /* 10 */
050dfa73
MM
551 { "adcB", Eb, Gb, XX, XX },
552 { "adcS", Ev, Gv, XX, XX },
553 { "adcB", Gb, Eb, XX, XX },
554 { "adcS", Gv, Ev, XX, XX },
555 { "adcB", AL, Ib, XX, XX },
556 { "adcS", eAX, Iv, XX, XX },
557 { "push{T|}", ss, XX, XX, XX },
558 { "pop{T|}", ss, XX, XX, XX },
252b5132 559 /* 18 */
050dfa73
MM
560 { "sbbB", Eb, Gb, XX, XX },
561 { "sbbS", Ev, Gv, XX, XX },
562 { "sbbB", Gb, Eb, XX, XX },
563 { "sbbS", Gv, Ev, XX, XX },
564 { "sbbB", AL, Ib, XX, XX },
565 { "sbbS", eAX, Iv, XX, XX },
566 { "push{T|}", ds, XX, XX, XX },
567 { "pop{T|}", ds, XX, XX, XX },
252b5132 568 /* 20 */
050dfa73
MM
569 { "andB", Eb, Gb, XX, XX },
570 { "andS", Ev, Gv, XX, XX },
571 { "andB", Gb, Eb, XX, XX },
572 { "andS", Gv, Ev, XX, XX },
573 { "andB", AL, Ib, XX, XX },
574 { "andS", eAX, Iv, XX, XX },
575 { "(bad)", XX, XX, XX, XX }, /* SEG ES prefix */
576 { "daa{|}", XX, XX, XX, XX },
252b5132 577 /* 28 */
050dfa73
MM
578 { "subB", Eb, Gb, XX, XX },
579 { "subS", Ev, Gv, XX, XX},
580 { "subB", Gb, Eb, XX, XX },
581 { "subS", Gv, Ev, XX, XX },
582 { "subB", AL, Ib, XX, XX },
583 { "subS", eAX, Iv, XX, XX },
584 { "(bad)", XX, XX, XX, XX }, /* SEG CS prefix */
585 { "das{|}", XX, XX, XX, XX },
252b5132 586 /* 30 */
050dfa73
MM
587 { "xorB", Eb, Gb, XX, XX },
588 { "xorS", Ev, Gv, XX, XX },
589 { "xorB", Gb, Eb, XX, XX },
590 { "xorS", Gv, Ev, XX, XX },
591 { "xorB", AL, Ib, XX, XX },
592 { "xorS", eAX, Iv, XX, XX },
593 { "(bad)", XX, XX, XX, XX }, /* SEG SS prefix */
594 { "aaa{|}", XX, XX, XX, XX },
252b5132 595 /* 38 */
050dfa73
MM
596 { "cmpB", Eb, Gb, XX, XX },
597 { "cmpS", Ev, Gv, XX, XX },
598 { "cmpB", Gb, Eb, XX, XX },
599 { "cmpS", Gv, Ev, XX, XX },
600 { "cmpB", AL, Ib, XX, XX },
601 { "cmpS", eAX, Iv, XX, XX },
602 { "(bad)", XX, XX, XX, XX }, /* SEG DS prefix */
603 { "aas{|}", XX, XX, XX, XX },
252b5132 604 /* 40 */
050dfa73
MM
605 { "inc{S|}", RMeAX, XX, XX, XX },
606 { "inc{S|}", RMeCX, XX, XX, XX },
607 { "inc{S|}", RMeDX, XX, XX, XX },
608 { "inc{S|}", RMeBX, XX, XX, XX },
609 { "inc{S|}", RMeSP, XX, XX, XX },
610 { "inc{S|}", RMeBP, XX, XX, XX },
611 { "inc{S|}", RMeSI, XX, XX, XX },
612 { "inc{S|}", RMeDI, XX, XX, XX },
252b5132 613 /* 48 */
050dfa73
MM
614 { "dec{S|}", RMeAX, XX, XX, XX },
615 { "dec{S|}", RMeCX, XX, XX, XX },
616 { "dec{S|}", RMeDX, XX, XX, XX },
617 { "dec{S|}", RMeBX, XX, XX, XX },
618 { "dec{S|}", RMeSP, XX, XX, XX },
619 { "dec{S|}", RMeBP, XX, XX, XX },
620 { "dec{S|}", RMeSI, XX, XX, XX },
621 { "dec{S|}", RMeDI, XX, XX, XX },
252b5132 622 /* 50 */
050dfa73
MM
623 { "pushV", RMrAX, XX, XX, XX },
624 { "pushV", RMrCX, XX, XX, XX },
625 { "pushV", RMrDX, XX, XX, XX },
626 { "pushV", RMrBX, XX, XX, XX },
627 { "pushV", RMrSP, XX, XX, XX },
628 { "pushV", RMrBP, XX, XX, XX },
629 { "pushV", RMrSI, XX, XX, XX },
630 { "pushV", RMrDI, XX, XX, XX },
252b5132 631 /* 58 */
050dfa73
MM
632 { "popV", RMrAX, XX, XX, XX },
633 { "popV", RMrCX, XX, XX, XX },
634 { "popV", RMrDX, XX, XX, XX },
635 { "popV", RMrBX, XX, XX, XX },
636 { "popV", RMrSP, XX, XX, XX },
637 { "popV", RMrBP, XX, XX, XX },
638 { "popV", RMrSI, XX, XX, XX },
639 { "popV", RMrDI, XX, XX, XX },
252b5132 640 /* 60 */
050dfa73
MM
641 { "pusha{P|}", XX, XX, XX, XX},
642 { "popa{P|}", XX, XX, XX, XX },
643 { "bound{S|}", Gv, Ma, XX, XX },
6439fc28 644 { X86_64_0 },
050dfa73
MM
645 { "(bad)", XX, XX, XX, XX }, /* seg fs */
646 { "(bad)", XX, XX, XX, XX }, /* seg gs */
647 { "(bad)", XX, XX, XX, XX }, /* op size prefix */
648 { "(bad)", XX, XX, XX, XX }, /* adr size prefix */
252b5132 649 /* 68 */
050dfa73
MM
650 { "pushT", Iq, XX, XX, XX },
651 { "imulS", Gv, Ev, Iv, XX },
652 { "pushT", sIb, XX, XX, XX },
653 { "imulS", Gv, Ev, sIb, XX },
654 { "ins{b||b|}", Ybr, indirDX, XX, XX },
655 { "ins{R||R|}", Yvr, indirDX, XX, XX },
656 { "outs{b||b|}", indirDXr, Xb, XX, XX },
657 { "outs{R||R|}", indirDXr, Xv, XX, XX },
252b5132 658 /* 70 */
050dfa73
MM
659 { "joH", Jb, XX, cond_jump_flag, XX },
660 { "jnoH", Jb, XX, cond_jump_flag, XX },
661 { "jbH", Jb, XX, cond_jump_flag, XX },
662 { "jaeH", Jb, XX, cond_jump_flag, XX },
663 { "jeH", Jb, XX, cond_jump_flag, XX },
664 { "jneH", Jb, XX, cond_jump_flag, XX },
665 { "jbeH", Jb, XX, cond_jump_flag, XX },
666 { "jaH", Jb, XX, cond_jump_flag, XX },
252b5132 667 /* 78 */
050dfa73
MM
668 { "jsH", Jb, XX, cond_jump_flag, XX },
669 { "jnsH", Jb, XX, cond_jump_flag, XX },
670 { "jpH", Jb, XX, cond_jump_flag, XX },
671 { "jnpH", Jb, XX, cond_jump_flag, XX },
672 { "jlH", Jb, XX, cond_jump_flag, XX },
673 { "jgeH", Jb, XX, cond_jump_flag, XX },
674 { "jleH", Jb, XX, cond_jump_flag, XX },
675 { "jgH", Jb, XX, cond_jump_flag, XX },
252b5132
RH
676 /* 80 */
677 { GRP1b },
678 { GRP1S },
050dfa73 679 { "(bad)", XX, XX, XX, XX },
252b5132 680 { GRP1Ss },
050dfa73
MM
681 { "testB", Eb, Gb, XX, XX },
682 { "testS", Ev, Gv, XX, XX },
683 { "xchgB", Eb, Gb, XX, XX },
684 { "xchgS", Ev, Gv, XX, XX },
252b5132 685 /* 88 */
050dfa73
MM
686 { "movB", Eb, Gb, XX, XX },
687 { "movS", Ev, Gv, XX, XX },
688 { "movB", Gb, Eb, XX, XX },
689 { "movS", Gv, Ev, XX, XX },
690 { "movQ", Sv, Sw, XX, XX },
691 { "leaS", Gv, M, XX, XX },
692 { "movQ", Sw, Sv, XX, XX },
693 { "popU", stackEv, XX, XX, XX },
252b5132 694 /* 90 */
050dfa73
MM
695 { "xchgS", NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
696 { "xchgS", RMeCX, eAX, XX, XX },
697 { "xchgS", RMeDX, eAX, XX, XX },
698 { "xchgS", RMeBX, eAX, XX, XX },
699 { "xchgS", RMeSP, eAX, XX, XX },
700 { "xchgS", RMeBP, eAX, XX, XX },
701 { "xchgS", RMeSI, eAX, XX, XX },
702 { "xchgS", RMeDI, eAX, XX, XX },
252b5132 703 /* 98 */
050dfa73
MM
704 { "cW{tR||tR|}", XX, XX, XX, XX },
705 { "cR{tO||tO|}", XX, XX, XX, XX },
706 { "Jcall{T|}", Ap, XX, XX, XX },
707 { "(bad)", XX, XX, XX, XX }, /* fwait */
708 { "pushfT", XX, XX, XX, XX },
709 { "popfT", XX, XX, XX, XX },
710 { "sahf{|}", XX, XX, XX, XX },
711 { "lahf{|}", XX, XX, XX, XX },
252b5132 712 /* a0 */
050dfa73
MM
713 { "movB", AL, Ob, XX, XX },
714 { "movS", eAX, Ov, XX, XX },
715 { "movB", Ob, AL, XX, XX },
716 { "movS", Ov, eAX, XX, XX },
717 { "movs{b||b|}", Ybr, Xb, XX, XX },
718 { "movs{R||R|}", Yvr, Xv, XX, XX },
719 { "cmps{b||b|}", Xb, Yb, XX, XX },
720 { "cmps{R||R|}", Xv, Yv, XX, XX },
252b5132 721 /* a8 */
050dfa73
MM
722 { "testB", AL, Ib, XX, XX },
723 { "testS", eAX, Iv, XX, XX },
724 { "stosB", Ybr, AL, XX, XX },
725 { "stosS", Yvr, eAX, XX, XX },
726 { "lodsB", ALr, Xb, XX, XX },
727 { "lodsS", eAXr, Xv, XX, XX },
728 { "scasB", AL, Yb, XX, XX },
729 { "scasS", eAX, Yv, XX, XX },
252b5132 730 /* b0 */
050dfa73
MM
731 { "movB", RMAL, Ib, XX, XX },
732 { "movB", RMCL, Ib, XX, XX },
733 { "movB", RMDL, Ib, XX, XX },
734 { "movB", RMBL, Ib, XX, XX },
735 { "movB", RMAH, Ib, XX, XX },
736 { "movB", RMCH, Ib, XX, XX },
737 { "movB", RMDH, Ib, XX, XX },
738 { "movB", RMBH, Ib, XX, XX },
252b5132 739 /* b8 */
050dfa73
MM
740 { "movS", RMeAX, Iv64, XX, XX },
741 { "movS", RMeCX, Iv64, XX, XX },
742 { "movS", RMeDX, Iv64, XX, XX },
743 { "movS", RMeBX, Iv64, XX, XX },
744 { "movS", RMeSP, Iv64, XX, XX },
745 { "movS", RMeBP, Iv64, XX, XX },
746 { "movS", RMeSI, Iv64, XX, XX },
747 { "movS", RMeDI, Iv64, XX, XX },
252b5132
RH
748 /* c0 */
749 { GRP2b },
750 { GRP2S },
050dfa73
MM
751 { "retT", Iw, XX, XX, XX },
752 { "retT", XX, XX, XX, XX },
753 { "les{S|}", Gv, Mp, XX, XX },
754 { "ldsS", Gv, Mp, XX, XX },
a6bd098c
L
755 { GRP11_C6 },
756 { GRP11_C7 },
252b5132 757 /* c8 */
050dfa73
MM
758 { "enterT", Iw, Ib, XX, XX },
759 { "leaveT", XX, XX, XX, XX },
760 { "lretP", Iw, XX, XX, XX },
761 { "lretP", XX, XX, XX, XX },
762 { "int3", XX, XX, XX, XX },
763 { "int", Ib, XX, XX, XX },
764 { "into{|}", XX, XX, XX, XX },
765 { "iretP", XX, XX, XX, XX },
252b5132
RH
766 /* d0 */
767 { GRP2b_one },
768 { GRP2S_one },
769 { GRP2b_cl },
770 { GRP2S_cl },
050dfa73
MM
771 { "aam{|}", sIb, XX, XX, XX },
772 { "aad{|}", sIb, XX, XX, XX },
773 { "(bad)", XX, XX, XX, XX },
774 { "xlat", DSBX, XX, XX, XX },
252b5132
RH
775 /* d8 */
776 { FLOAT },
777 { FLOAT },
778 { FLOAT },
779 { FLOAT },
780 { FLOAT },
781 { FLOAT },
782 { FLOAT },
783 { FLOAT },
784 /* e0 */
050dfa73
MM
785 { "loopneFH", Jb, XX, loop_jcxz_flag, XX },
786 { "loopeFH", Jb, XX, loop_jcxz_flag, XX },
787 { "loopFH", Jb, XX, loop_jcxz_flag, XX },
788 { "jEcxzH", Jb, XX, loop_jcxz_flag, XX },
789 { "inB", AL, Ib, XX, XX },
790 { "inS", eAX, Ib, XX, XX },
791 { "outB", Ib, AL, XX, XX },
792 { "outS", Ib, eAX, XX, XX },
252b5132 793 /* e8 */
050dfa73
MM
794 { "callT", Jv, XX, XX, XX },
795 { "jmpT", Jv, XX, XX, XX },
796 { "Jjmp{T|}", Ap, XX, XX, XX },
797 { "jmp", Jb, XX, XX, XX },
798 { "inB", AL, indirDX, XX, XX },
799 { "inS", eAX, indirDX, XX, XX },
800 { "outB", indirDX, AL, XX, XX },
801 { "outS", indirDX, eAX, XX, XX },
252b5132 802 /* f0 */
050dfa73
MM
803 { "(bad)", XX, XX, XX, XX }, /* lock prefix */
804 { "icebp", XX, XX, XX, XX },
805 { "(bad)", XX, XX, XX, XX }, /* repne */
806 { "(bad)", XX, XX, XX, XX }, /* repz */
807 { "hlt", XX, XX, XX, XX },
808 { "cmc", XX, XX, XX, XX },
252b5132
RH
809 { GRP3b },
810 { GRP3S },
811 /* f8 */
050dfa73
MM
812 { "clc", XX, XX, XX, XX },
813 { "stc", XX, XX, XX, XX },
814 { "cli", XX, XX, XX, XX },
815 { "sti", XX, XX, XX, XX },
816 { "cld", XX, XX, XX, XX },
817 { "std", XX, XX, XX, XX },
252b5132
RH
818 { GRP4 },
819 { GRP5 },
820};
821
6439fc28 822static const struct dis386 dis386_twobyte[] = {
252b5132
RH
823 /* 00 */
824 { GRP6 },
825 { GRP7 },
050dfa73
MM
826 { "larS", Gv, Ew, XX, XX },
827 { "lslS", Gv, Ew, XX, XX },
828 { "(bad)", XX, XX, XX, XX },
829 { "syscall", XX, XX, XX, XX },
830 { "clts", XX, XX, XX, XX },
831 { "sysretP", XX, XX, XX, XX },
252b5132 832 /* 08 */
050dfa73
MM
833 { "invd", XX, XX, XX, XX},
834 { "wbinvd", XX, XX, XX, XX },
835 { "(bad)", XX, XX, XX, XX },
836 { "ud2a", XX, XX, XX, XX },
837 { "(bad)", XX, XX, XX, XX },
c608c12e 838 { GRPAMD },
050dfa73
MM
839 { "femms", XX, XX, XX, XX },
840 { "", MX, EM, OPSUF, XX }, /* See OP_3DNowSuffix. */
252b5132 841 /* 10 */
c608c12e
AM
842 { PREGRP8 },
843 { PREGRP9 },
ca164297 844 { PREGRP30 },
050dfa73
MM
845 { "movlpX", EX, XM, SIMD_Fixup, 'h', XX },
846 { "unpcklpX", XM, EX, XX, XX },
847 { "unpckhpX", XM, EX, XX, XX },
ca164297 848 { PREGRP31 },
050dfa73 849 { "movhpX", EX, XM, SIMD_Fixup, 'l', XX },
252b5132 850 /* 18 */
b3882df9 851 { GRP16 },
050dfa73
MM
852 { "(bad)", XX, XX, XX, XX },
853 { "(bad)", XX, XX, XX, XX },
854 { "(bad)", XX, XX, XX, XX },
855 { "(bad)", XX, XX, XX, XX },
856 { "(bad)", XX, XX, XX, XX },
857 { "(bad)", XX, XX, XX, XX },
858 { "nopQ", Ev, XX, XX, XX },
252b5132 859 /* 20 */
050dfa73
MM
860 { "movZ", Rm, Cm, XX, XX },
861 { "movZ", Rm, Dm, XX, XX },
862 { "movZ", Cm, Rm, XX, XX },
863 { "movZ", Dm, Rm, XX, XX },
864 { "movL", Rd, Td, XX, XX },
865 { "(bad)", XX, XX, XX, XX },
866 { "movL", Td, Rd, XX, XX },
867 { "(bad)", XX, XX, XX, XX },
252b5132 868 /* 28 */
050dfa73
MM
869 { "movapX", XM, EX, XX, XX },
870 { "movapX", EX, XM, XX, XX },
c608c12e 871 { PREGRP2 },
050dfa73 872 { PREGRP33 },
2da11e11 873 { PREGRP4 },
c608c12e 874 { PREGRP3 },
050dfa73
MM
875 { "ucomisX", XM,EX, XX, XX },
876 { "comisX", XM,EX, XX, XX },
252b5132 877 /* 30 */
050dfa73
MM
878 { "wrmsr", XX, XX, XX, XX },
879 { "rdtsc", XX, XX, XX, XX },
880 { "rdmsr", XX, XX, XX, XX },
881 { "rdpmc", XX, XX, XX, XX },
882 { "sysenter", XX, XX, XX, XX },
883 { "sysexit", XX, XX, XX, XX },
884 { "(bad)", XX, XX, XX, XX },
885 { "(bad)", XX, XX, XX, XX },
252b5132 886 /* 38 */
331d2d0d 887 { THREE_BYTE_0 },
050dfa73 888 { "(bad)", XX, XX, XX, XX },
331d2d0d 889 { THREE_BYTE_1 },
050dfa73
MM
890 { "(bad)", XX, XX, XX, XX },
891 { "(bad)", XX, XX, XX, XX },
892 { "(bad)", XX, XX, XX, XX },
893 { "(bad)", XX, XX, XX, XX },
894 { "(bad)", XX, XX, XX, XX },
252b5132 895 /* 40 */
050dfa73
MM
896 { "cmovo", Gv, Ev, XX, XX },
897 { "cmovno", Gv, Ev, XX, XX },
898 { "cmovb", Gv, Ev, XX, XX },
899 { "cmovae", Gv, Ev, XX, XX },
900 { "cmove", Gv, Ev, XX, XX },
901 { "cmovne", Gv, Ev, XX, XX },
902 { "cmovbe", Gv, Ev, XX, XX },
903 { "cmova", Gv, Ev, XX, XX },
252b5132 904 /* 48 */
050dfa73
MM
905 { "cmovs", Gv, Ev, XX, XX },
906 { "cmovns", Gv, Ev, XX, XX },
907 { "cmovp", Gv, Ev, XX, XX },
908 { "cmovnp", Gv, Ev, XX, XX },
909 { "cmovl", Gv, Ev, XX, XX },
910 { "cmovge", Gv, Ev, XX, XX },
911 { "cmovle", Gv, Ev, XX, XX },
912 { "cmovg", Gv, Ev, XX, XX },
252b5132 913 /* 50 */
050dfa73 914 { "movmskpX", Gdq, XS, XX, XX },
c608c12e
AM
915 { PREGRP13 },
916 { PREGRP12 },
917 { PREGRP11 },
050dfa73
MM
918 { "andpX", XM, EX, XX, XX },
919 { "andnpX", XM, EX, XX, XX },
920 { "orpX", XM, EX, XX, XX },
921 { "xorpX", XM, EX, XX, XX },
252b5132 922 /* 58 */
c608c12e
AM
923 { PREGRP0 },
924 { PREGRP10 },
041bd2e0
JH
925 { PREGRP17 },
926 { PREGRP16 },
c608c12e
AM
927 { PREGRP14 },
928 { PREGRP7 },
929 { PREGRP5 },
2da11e11 930 { PREGRP6 },
252b5132 931 /* 60 */
050dfa73
MM
932 { "punpcklbw", MX, EM, XX, XX },
933 { "punpcklwd", MX, EM, XX, XX },
934 { "punpckldq", MX, EM, XX, XX },
935 { "packsswb", MX, EM, XX, XX },
936 { "pcmpgtb", MX, EM, XX, XX },
937 { "pcmpgtw", MX, EM, XX, XX },
938 { "pcmpgtd", MX, EM, XX, XX },
939 { "packuswb", MX, EM, XX, XX },
252b5132 940 /* 68 */
050dfa73
MM
941 { "punpckhbw", MX, EM, XX, XX },
942 { "punpckhwd", MX, EM, XX, XX },
943 { "punpckhdq", MX, EM, XX, XX },
944 { "packssdw", MX, EM, XX, XX },
0f17484f 945 { PREGRP26 },
041bd2e0 946 { PREGRP24 },
050dfa73 947 { "movd", MX, Edq, XX, XX },
041bd2e0 948 { PREGRP19 },
252b5132 949 /* 70 */
041bd2e0 950 { PREGRP22 },
252b5132 951 { GRP12 },
b3882df9
L
952 { GRP13 },
953 { GRP14 },
050dfa73
MM
954 { "pcmpeqb", MX, EM, XX, XX },
955 { "pcmpeqw", MX, EM, XX, XX },
956 { "pcmpeqd", MX, EM, XX, XX },
957 { "emms", XX, XX, XX, XX },
252b5132 958 /* 78 */
050dfa73
MM
959 { PREGRP34 },
960 { PREGRP35 },
961 { "(bad)", XX, XX, XX, XX },
962 { "(bad)", XX, XX, XX, XX },
ca164297
L
963 { PREGRP28 },
964 { PREGRP29 },
041bd2e0
JH
965 { PREGRP23 },
966 { PREGRP20 },
252b5132 967 /* 80 */
050dfa73
MM
968 { "joH", Jv, XX, cond_jump_flag, XX },
969 { "jnoH", Jv, XX, cond_jump_flag, XX },
970 { "jbH", Jv, XX, cond_jump_flag, XX },
971 { "jaeH", Jv, XX, cond_jump_flag, XX },
972 { "jeH", Jv, XX, cond_jump_flag, XX },
973 { "jneH", Jv, XX, cond_jump_flag, XX },
974 { "jbeH", Jv, XX, cond_jump_flag, XX },
975 { "jaH", Jv, XX, cond_jump_flag, XX },
252b5132 976 /* 88 */
050dfa73
MM
977 { "jsH", Jv, XX, cond_jump_flag, XX },
978 { "jnsH", Jv, XX, cond_jump_flag, XX },
979 { "jpH", Jv, XX, cond_jump_flag, XX },
980 { "jnpH", Jv, XX, cond_jump_flag, XX },
981 { "jlH", Jv, XX, cond_jump_flag, XX },
982 { "jgeH", Jv, XX, cond_jump_flag, XX },
983 { "jleH", Jv, XX, cond_jump_flag, XX },
984 { "jgH", Jv, XX, cond_jump_flag, XX },
252b5132 985 /* 90 */
050dfa73
MM
986 { "seto", Eb, XX, XX, XX },
987 { "setno", Eb, XX, XX, XX },
988 { "setb", Eb, XX, XX, XX },
989 { "setae", Eb, XX, XX, XX },
990 { "sete", Eb, XX, XX, XX },
991 { "setne", Eb, XX, XX, XX },
992 { "setbe", Eb, XX, XX, XX },
993 { "seta", Eb, XX, XX, XX },
252b5132 994 /* 98 */
050dfa73
MM
995 { "sets", Eb, XX, XX, XX },
996 { "setns", Eb, XX, XX, XX },
997 { "setp", Eb, XX, XX, XX },
998 { "setnp", Eb, XX, XX, XX },
999 { "setl", Eb, XX, XX, XX },
1000 { "setge", Eb, XX, XX, XX },
1001 { "setle", Eb, XX, XX, XX },
1002 { "setg", Eb, XX, XX, XX },
252b5132 1003 /* a0 */
050dfa73
MM
1004 { "pushT", fs, XX, XX, XX },
1005 { "popT", fs, XX, XX, XX },
1006 { "cpuid", XX, XX, XX, XX },
1007 { "btS", Ev, Gv, XX, XX },
1008 { "shldS", Ev, Gv, Ib, XX },
1009 { "shldS", Ev, Gv, CL, XX },
30d1c836
ML
1010 { GRPPADLCK2 },
1011 { GRPPADLCK1 },
252b5132 1012 /* a8 */
050dfa73
MM
1013 { "pushT", gs, XX, XX, XX },
1014 { "popT", gs, XX, XX, XX },
1015 { "rsm", XX, XX, XX, XX },
1016 { "btsS", Ev, Gv, XX, XX },
1017 { "shrdS", Ev, Gv, Ib, XX },
1018 { "shrdS", Ev, Gv, CL, XX },
b3882df9 1019 { GRP15 },
050dfa73 1020 { "imulS", Gv, Ev, XX, XX },
252b5132 1021 /* b0 */
050dfa73
MM
1022 { "cmpxchgB", Eb, Gb, XX, XX },
1023 { "cmpxchgS", Ev, Gv, XX, XX },
1024 { "lssS", Gv, Mp, XX, XX },
1025 { "btrS", Ev, Gv, XX, XX },
1026 { "lfsS", Gv, Mp, XX, XX },
1027 { "lgsS", Gv, Mp, XX, XX },
1028 { "movz{bR|x|bR|x}", Gv, Eb, XX, XX },
1029 { "movz{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movzww ! */
252b5132 1030 /* b8 */
050dfa73
MM
1031 { "popcntS", Gv, Ev, XX, XX },
1032 { "ud2b", XX, XX, XX, XX },
252b5132 1033 { GRP8 },
050dfa73
MM
1034 { "btcS", Ev, Gv, XX, XX },
1035 { "bsfS", Gv, Ev, XX, XX },
1036 { PREGRP36 },
1037 { "movs{bR|x|bR|x}", Gv, Eb, XX, XX },
1038 { "movs{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movsww ! */
252b5132 1039 /* c0 */
050dfa73
MM
1040 { "xaddB", Eb, Gb, XX, XX },
1041 { "xaddS", Ev, Gv, XX, XX },
c608c12e 1042 { PREGRP1 },
050dfa73
MM
1043 { "movntiS", Ev, Gv, XX, XX },
1044 { "pinsrw", MX, Edqw, Ib, XX },
1045 { "pextrw", Gdq, MS, Ib, XX },
1046 { "shufpX", XM, EX, Ib, XX },
252b5132
RH
1047 { GRP9 },
1048 /* c8 */
050dfa73
MM
1049 { "bswap", RMeAX, XX, XX, XX },
1050 { "bswap", RMeCX, XX, XX, XX },
1051 { "bswap", RMeDX, XX, XX, XX },
1052 { "bswap", RMeBX, XX, XX, XX },
1053 { "bswap", RMeSP, XX, XX, XX },
1054 { "bswap", RMeBP, XX, XX, XX },
1055 { "bswap", RMeSI, XX, XX, XX },
1056 { "bswap", RMeDI, XX, XX, XX },
252b5132 1057 /* d0 */
ca164297 1058 { PREGRP27 },
050dfa73
MM
1059 { "psrlw", MX, EM, XX, XX },
1060 { "psrld", MX, EM, XX, XX },
1061 { "psrlq", MX, EM, XX, XX },
1062 { "paddq", MX, EM, XX, XX },
1063 { "pmullw", MX, EM, XX, XX },
041bd2e0 1064 { PREGRP21 },
050dfa73 1065 { "pmovmskb", Gdq, MS, XX, XX },
252b5132 1066 /* d8 */
050dfa73
MM
1067 { "psubusb", MX, EM, XX, XX },
1068 { "psubusw", MX, EM, XX, XX },
1069 { "pminub", MX, EM, XX, XX },
1070 { "pand", MX, EM, XX, XX },
1071 { "paddusb", MX, EM, XX, XX },
1072 { "paddusw", MX, EM, XX, XX },
1073 { "pmaxub", MX, EM, XX, XX },
1074 { "pandn", MX, EM, XX, XX },
252b5132 1075 /* e0 */
050dfa73
MM
1076 { "pavgb", MX, EM, XX, XX },
1077 { "psraw", MX, EM, XX, XX },
1078 { "psrad", MX, EM, XX, XX },
1079 { "pavgw", MX, EM, XX, XX },
1080 { "pmulhuw", MX, EM, XX, XX },
1081 { "pmulhw", MX, EM, XX, XX },
041bd2e0 1082 { PREGRP15 },
0f17484f 1083 { PREGRP25 },
252b5132 1084 /* e8 */
050dfa73
MM
1085 { "psubsb", MX, EM, XX, XX },
1086 { "psubsw", MX, EM, XX, XX },
1087 { "pminsw", MX, EM, XX, XX },
1088 { "por", MX, EM, XX, XX },
1089 { "paddsb", MX, EM, XX, XX },
1090 { "paddsw", MX, EM, XX, XX },
1091 { "pmaxsw", MX, EM, XX, XX },
1092 { "pxor", MX, EM, XX, XX },
252b5132 1093 /* f0 */
ca164297 1094 { PREGRP32 },
050dfa73
MM
1095 { "psllw", MX, EM, XX, XX },
1096 { "pslld", MX, EM, XX, XX },
1097 { "psllq", MX, EM, XX, XX },
1098 { "pmuludq", MX, EM, XX, XX },
1099 { "pmaddwd", MX, EM, XX, XX },
1100 { "psadbw", MX, EM, XX, XX },
041bd2e0 1101 { PREGRP18 },
252b5132 1102 /* f8 */
050dfa73
MM
1103 { "psubb", MX, EM, XX, XX },
1104 { "psubw", MX, EM, XX, XX },
1105 { "psubd", MX, EM, XX, XX },
1106 { "psubq", MX, EM, XX, XX },
1107 { "paddb", MX, EM, XX, XX },
1108 { "paddw", MX, EM, XX, XX },
1109 { "paddd", MX, EM, XX, XX },
1110 { "(bad)", XX, XX, XX, XX }
252b5132
RH
1111};
1112
1113static const unsigned char onebyte_has_modrm[256] = {
c608c12e
AM
1114 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1115 /* ------------------------------- */
1116 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1117 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1118 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1119 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1120 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1121 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1122 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1123 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1124 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1125 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1126 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1127 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1128 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1129 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1130 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1131 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1132 /* ------------------------------- */
1133 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
252b5132
RH
1134};
1135
1136static const unsigned char twobyte_has_modrm[256] = {
c608c12e
AM
1137 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1138 /* ------------------------------- */
252b5132 1139 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
15965411 1140 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
4bba6815 1141 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
331d2d0d 1142 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
252b5132 1143 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
4bba6815
AM
1144 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1145 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
90700ea2 1146 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
252b5132
RH
1147 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1148 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
30d1c836 1149 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
050dfa73 1150 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
252b5132 1151 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
ca164297 1152 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
4bba6815 1153 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
ca164297 1154 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
c608c12e
AM
1155 /* ------------------------------- */
1156 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1157};
1158
041bd2e0 1159static const unsigned char twobyte_uses_SSE_prefix[256] = {
c608c12e
AM
1160 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1161 /* ------------------------------- */
1162 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
ca164297 1163 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
050dfa73 1164 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
331d2d0d 1165 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
c608c12e 1166 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
041bd2e0
JH
1167 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1168 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
050dfa73 1169 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
c608c12e
AM
1170 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1171 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1172 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1173 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1174 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
ca164297 1175 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
041bd2e0 1176 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
ca164297 1177 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
c608c12e
AM
1178 /* ------------------------------- */
1179 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
252b5132
RH
1180};
1181
1182static char obuf[100];
1183static char *obufp;
1184static char scratchbuf[100];
1185static unsigned char *start_codep;
1186static unsigned char *insn_codep;
1187static unsigned char *codep;
1188static disassemble_info *the_info;
1189static int mod;
1190static int rm;
1191static int reg;
4bba6815 1192static unsigned char need_modrm;
252b5132 1193
4bba6815
AM
1194/* If we are accessing mod/rm/reg without need_modrm set, then the
1195 values are stale. Hitting this abort likely indicates that you
1196 need to update onebyte_has_modrm or twobyte_has_modrm. */
1197#define MODRM_CHECK if (!need_modrm) abort ()
1198
d708bcba
AM
1199static const char **names64;
1200static const char **names32;
1201static const char **names16;
1202static const char **names8;
1203static const char **names8rex;
1204static const char **names_seg;
1205static const char **index16;
1206
1207static const char *intel_names64[] = {
1208 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1209 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1210};
1211static const char *intel_names32[] = {
1212 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1213 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1214};
1215static const char *intel_names16[] = {
1216 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1217 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1218};
1219static const char *intel_names8[] = {
1220 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1221};
1222static const char *intel_names8rex[] = {
1223 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1224 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1225};
1226static const char *intel_names_seg[] = {
1227 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1228};
1229static const char *intel_index16[] = {
1230 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1231};
1232
1233static const char *att_names64[] = {
1234 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
52b15da3
JH
1235 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1236};
d708bcba
AM
1237static const char *att_names32[] = {
1238 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
52b15da3 1239 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
252b5132 1240};
d708bcba
AM
1241static const char *att_names16[] = {
1242 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
52b15da3 1243 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
252b5132 1244};
d708bcba
AM
1245static const char *att_names8[] = {
1246 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
252b5132 1247};
d708bcba
AM
1248static const char *att_names8rex[] = {
1249 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
52b15da3
JH
1250 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1251};
d708bcba
AM
1252static const char *att_names_seg[] = {
1253 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
252b5132 1254};
d708bcba
AM
1255static const char *att_index16[] = {
1256 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
252b5132
RH
1257};
1258
2da11e11 1259static const struct dis386 grps[][8] = {
252b5132
RH
1260 /* GRP1b */
1261 {
050dfa73
MM
1262 { "addA", Eb, Ib, XX, XX },
1263 { "orA", Eb, Ib, XX, XX },
1264 { "adcA", Eb, Ib, XX, XX },
1265 { "sbbA", Eb, Ib, XX, XX },
1266 { "andA", Eb, Ib, XX, XX },
1267 { "subA", Eb, Ib, XX, XX },
1268 { "xorA", Eb, Ib, XX, XX },
1269 { "cmpA", Eb, Ib, XX, XX }
252b5132
RH
1270 },
1271 /* GRP1S */
1272 {
050dfa73
MM
1273 { "addQ", Ev, Iv, XX, XX },
1274 { "orQ", Ev, Iv, XX, XX },
1275 { "adcQ", Ev, Iv, XX, XX },
1276 { "sbbQ", Ev, Iv, XX, XX },
1277 { "andQ", Ev, Iv, XX, XX },
1278 { "subQ", Ev, Iv, XX, XX },
1279 { "xorQ", Ev, Iv, XX, XX },
1280 { "cmpQ", Ev, Iv, XX, XX }
252b5132
RH
1281 },
1282 /* GRP1Ss */
1283 {
050dfa73
MM
1284 { "addQ", Ev, sIb, XX, XX },
1285 { "orQ", Ev, sIb, XX, XX },
1286 { "adcQ", Ev, sIb, XX, XX },
1287 { "sbbQ", Ev, sIb, XX, XX },
1288 { "andQ", Ev, sIb, XX, XX },
1289 { "subQ", Ev, sIb, XX, XX },
1290 { "xorQ", Ev, sIb, XX, XX },
1291 { "cmpQ", Ev, sIb, XX, XX }
252b5132
RH
1292 },
1293 /* GRP2b */
1294 {
050dfa73
MM
1295 { "rolA", Eb, Ib, XX, XX },
1296 { "rorA", Eb, Ib, XX, XX },
1297 { "rclA", Eb, Ib, XX, XX },
1298 { "rcrA", Eb, Ib, XX, XX },
1299 { "shlA", Eb, Ib, XX, XX },
1300 { "shrA", Eb, Ib, XX, XX },
1301 { "(bad)", XX, XX, XX, XX },
1302 { "sarA", Eb, Ib, XX, XX },
252b5132
RH
1303 },
1304 /* GRP2S */
1305 {
050dfa73
MM
1306 { "rolQ", Ev, Ib, XX, XX },
1307 { "rorQ", Ev, Ib, XX, XX },
1308 { "rclQ", Ev, Ib, XX, XX },
1309 { "rcrQ", Ev, Ib, XX, XX },
1310 { "shlQ", Ev, Ib, XX, XX },
1311 { "shrQ", Ev, Ib, XX, XX },
1312 { "(bad)", XX, XX, XX, XX },
1313 { "sarQ", Ev, Ib, XX, XX },
252b5132
RH
1314 },
1315 /* GRP2b_one */
1316 {
050dfa73
MM
1317 { "rolA", Eb, I1, XX, XX },
1318 { "rorA", Eb, I1, XX, XX },
1319 { "rclA", Eb, I1, XX, XX },
1320 { "rcrA", Eb, I1, XX, XX },
1321 { "shlA", Eb, I1, XX, XX },
1322 { "shrA", Eb, I1, XX, XX },
1323 { "(bad)", XX, XX, XX, XX },
1324 { "sarA", Eb, I1, XX, XX },
252b5132
RH
1325 },
1326 /* GRP2S_one */
1327 {
050dfa73
MM
1328 { "rolQ", Ev, I1, XX, XX },
1329 { "rorQ", Ev, I1, XX, XX },
1330 { "rclQ", Ev, I1, XX, XX },
1331 { "rcrQ", Ev, I1, XX, XX },
1332 { "shlQ", Ev, I1, XX, XX },
1333 { "shrQ", Ev, I1, XX, XX },
1334 { "(bad)", XX, XX, XX, XX },
1335 { "sarQ", Ev, I1, XX, XX },
252b5132
RH
1336 },
1337 /* GRP2b_cl */
1338 {
050dfa73
MM
1339 { "rolA", Eb, CL, XX, XX },
1340 { "rorA", Eb, CL, XX, XX },
1341 { "rclA", Eb, CL, XX, XX },
1342 { "rcrA", Eb, CL, XX, XX },
1343 { "shlA", Eb, CL, XX, XX },
1344 { "shrA", Eb, CL, XX, XX },
1345 { "(bad)", XX, XX, XX, XX },
1346 { "sarA", Eb, CL, XX, XX },
252b5132
RH
1347 },
1348 /* GRP2S_cl */
1349 {
050dfa73
MM
1350 { "rolQ", Ev, CL, XX, XX },
1351 { "rorQ", Ev, CL, XX, XX },
1352 { "rclQ", Ev, CL, XX, XX },
1353 { "rcrQ", Ev, CL, XX, XX },
1354 { "shlQ", Ev, CL, XX, XX },
1355 { "shrQ", Ev, CL, XX, XX },
1356 { "(bad)", XX, XX, XX, XX },
1357 { "sarQ", Ev, CL, XX, XX }
252b5132
RH
1358 },
1359 /* GRP3b */
1360 {
050dfa73
MM
1361 { "testA", Eb, Ib, XX, XX },
1362 { "(bad)", Eb, XX, XX, XX },
1363 { "notA", Eb, XX, XX, XX },
1364 { "negA", Eb, XX, XX, XX },
1365 { "mulA", Eb, XX, XX, XX }, /* Don't print the implicit %al register, */
1366 { "imulA", Eb, XX, XX, XX }, /* to distinguish these opcodes from other */
1367 { "divA", Eb, XX, XX, XX }, /* mul/imul opcodes. Do the same for div */
1368 { "idivA", Eb, XX, XX, XX } /* and idiv for consistency. */
252b5132
RH
1369 },
1370 /* GRP3S */
1371 {
050dfa73
MM
1372 { "testQ", Ev, Iv, XX, XX },
1373 { "(bad)", XX, XX, XX, XX },
1374 { "notQ", Ev, XX, XX, XX },
1375 { "negQ", Ev, XX, XX, XX },
1376 { "mulQ", Ev, XX, XX, XX }, /* Don't print the implicit register. */
1377 { "imulQ", Ev, XX, XX, XX },
1378 { "divQ", Ev, XX, XX, XX },
1379 { "idivQ", Ev, XX, XX, XX },
252b5132
RH
1380 },
1381 /* GRP4 */
1382 {
050dfa73
MM
1383 { "incA", Eb, XX, XX, XX },
1384 { "decA", Eb, XX, XX, XX },
1385 { "(bad)", XX, XX, XX, XX },
1386 { "(bad)", XX, XX, XX, XX },
1387 { "(bad)", XX, XX, XX, XX },
1388 { "(bad)", XX, XX, XX, XX },
1389 { "(bad)", XX, XX, XX, XX },
1390 { "(bad)", XX, XX, XX, XX },
252b5132
RH
1391 },
1392 /* GRP5 */
1393 {
050dfa73
MM
1394 { "incQ", Ev, XX, XX, XX },
1395 { "decQ", Ev, XX, XX, XX },
1396 { "callT", indirEv, XX, XX, XX },
1397 { "JcallT", indirEp, XX, XX, XX },
1398 { "jmpT", indirEv, XX, XX, XX },
1399 { "JjmpT", indirEp, XX, XX, XX },
1400 { "pushU", stackEv, XX, XX, XX },
1401 { "(bad)", XX, XX, XX, XX },
252b5132
RH
1402 },
1403 /* GRP6 */
1404 {
2b516b72
L
1405 { "sldt", Ev, XX, XX, XX },
1406 { "str", Ev, XX, XX, XX },
050dfa73
MM
1407 { "lldt", Ew, XX, XX, XX },
1408 { "ltr", Ew, XX, XX, XX },
1409 { "verr", Ew, XX, XX, XX },
1410 { "verw", Ew, XX, XX, XX },
1411 { "(bad)", XX, XX, XX, XX },
1412 { "(bad)", XX, XX, XX, XX }
252b5132
RH
1413 },
1414 /* GRP7 */
1415 {
050dfa73
MM
1416 { "sgdt{Q|IQ||}", VMX_Fixup, 0, XX, XX, XX },
1417 { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
1418 { "lgdt{Q|Q||}", M, XX, XX, XX },
1419 { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX, XX },
2b516b72 1420 { "smsw", Ev, XX, XX, XX },
050dfa73
MM
1421 { "(bad)", XX, XX, XX, XX },
1422 { "lmsw", Ew, XX, XX, XX },
1423 { "invlpg", INVLPG_Fixup, w_mode, XX, XX, XX },
252b5132
RH
1424 },
1425 /* GRP8 */
1426 {
050dfa73
MM
1427 { "(bad)", XX, XX, XX, XX },
1428 { "(bad)", XX, XX, XX, XX },
1429 { "(bad)", XX, XX, XX, XX },
1430 { "(bad)", XX, XX, XX, XX },
1431 { "btQ", Ev, Ib, XX, XX },
1432 { "btsQ", Ev, Ib, XX, XX },
1433 { "btrQ", Ev, Ib, XX, XX },
1434 { "btcQ", Ev, Ib, XX, XX },
252b5132
RH
1435 },
1436 /* GRP9 */
1437 {
050dfa73
MM
1438 { "(bad)", XX, XX, XX, XX },
1439 { "cmpxchg8b", Eq, XX, XX, XX },
1440 { "(bad)", XX, XX, XX, XX },
1441 { "(bad)", XX, XX, XX, XX },
1442 { "(bad)", XX, XX, XX, XX },
1443 { "(bad)", XX, XX, XX, XX },
1444 { "", VM, XX, XX, XX }, /* See OP_VMX. */
1445 { "vmptrst", Eq, XX, XX, XX },
252b5132 1446 },
a6bd098c
L
1447 /* GRP11_C6 */
1448 {
1449 { "movA", Eb, Ib, XX, XX },
1450 { "(bad)", XX, XX, XX, XX },
1451 { "(bad)", XX, XX, XX, XX },
1452 { "(bad)", XX, XX, XX, XX },
1453 { "(bad)", XX, XX, XX, XX },
1454 { "(bad)", XX, XX, XX, XX },
1455 { "(bad)", XX, XX, XX, XX },
1456 { "(bad)", XX, XX, XX, XX },
1457 },
1458 /* GRP11_C7 */
1459 {
1460 { "movQ", Ev, Iv, XX, XX },
1461 { "(bad)", XX, XX, XX, XX },
1462 { "(bad)", XX, XX, XX, XX },
1463 { "(bad)", XX, XX, XX, XX },
1464 { "(bad)", XX, XX, XX, XX },
1465 { "(bad)", XX, XX, XX, XX },
1466 { "(bad)", XX, XX, XX, XX },
1467 { "(bad)", XX, XX, XX, XX },
1468 },
b3882df9 1469 /* GRP12 */
252b5132 1470 {
050dfa73
MM
1471 { "(bad)", XX, XX, XX, XX },
1472 { "(bad)", XX, XX, XX, XX },
1473 { "psrlw", MS, Ib, XX, XX },
1474 { "(bad)", XX, XX, XX, XX },
1475 { "psraw", MS, Ib, XX, XX },
1476 { "(bad)", XX, XX, XX, XX },
1477 { "psllw", MS, Ib, XX, XX },
1478 { "(bad)", XX, XX, XX, XX },
252b5132 1479 },
b3882df9 1480 /* GRP13 */
252b5132 1481 {
050dfa73
MM
1482 { "(bad)", XX, XX, XX, XX },
1483 { "(bad)", XX, XX, XX, XX },
1484 { "psrld", MS, Ib, XX, XX },
1485 { "(bad)", XX, XX, XX, XX },
1486 { "psrad", MS, Ib, XX, XX },
1487 { "(bad)", XX, XX, XX, XX },
1488 { "pslld", MS, Ib, XX, XX },
1489 { "(bad)", XX, XX, XX, XX },
252b5132 1490 },
b3882df9 1491 /* GRP14 */
252b5132 1492 {
050dfa73
MM
1493 { "(bad)", XX, XX, XX, XX },
1494 { "(bad)", XX, XX, XX, XX },
1495 { "psrlq", MS, Ib, XX, XX },
1496 { "psrldq", MS, Ib, XX, XX },
1497 { "(bad)", XX, XX, XX, XX },
1498 { "(bad)", XX, XX, XX, XX },
1499 { "psllq", MS, Ib, XX, XX },
1500 { "pslldq", MS, Ib, XX, XX },
252b5132 1501 },
b3882df9 1502 /* GRP15 */
252b5132 1503 {
050dfa73
MM
1504 { "fxsave", Ev, XX, XX, XX },
1505 { "fxrstor", Ev, XX, XX, XX },
1506 { "ldmxcsr", Ev, XX, XX, XX },
1507 { "stmxcsr", Ev, XX, XX, XX },
1508 { "(bad)", XX, XX, XX, XX },
1509 { "lfence", OP_0fae, 0, XX, XX, XX },
1510 { "mfence", OP_0fae, 0, XX, XX, XX },
1511 { "clflush", OP_0fae, 0, XX, XX, XX },
c608c12e 1512 },
b3882df9 1513 /* GRP16 */
c608c12e 1514 {
050dfa73
MM
1515 { "prefetchnta", Ev, XX, XX, XX },
1516 { "prefetcht0", Ev, XX, XX, XX },
1517 { "prefetcht1", Ev, XX, XX, XX },
1518 { "prefetcht2", Ev, XX, XX, XX },
1519 { "(bad)", XX, XX, XX, XX },
1520 { "(bad)", XX, XX, XX, XX },
1521 { "(bad)", XX, XX, XX, XX },
1522 { "(bad)", XX, XX, XX, XX },
252b5132 1523 },
c608c12e 1524 /* GRPAMD */
252b5132 1525 {
050dfa73
MM
1526 { "prefetch", Eb, XX, XX, XX },
1527 { "prefetchw", Eb, XX, XX, XX },
1528 { "(bad)", XX, XX, XX, XX },
1529 { "(bad)", XX, XX, XX, XX },
1530 { "(bad)", XX, XX, XX, XX },
1531 { "(bad)", XX, XX, XX, XX },
1532 { "(bad)", XX, XX, XX, XX },
1533 { "(bad)", XX, XX, XX, XX },
0f10071e 1534 },
30d1c836 1535 /* GRPPADLCK1 */
cc0ec051 1536 {
050dfa73
MM
1537 { "xstore-rng", OP_0f07, 0, XX, XX, XX },
1538 { "xcrypt-ecb", OP_0f07, 0, XX, XX, XX },
1539 { "xcrypt-cbc", OP_0f07, 0, XX, XX, XX },
1540 { "xcrypt-ctr", OP_0f07, 0, XX, XX, XX },
1541 { "xcrypt-cfb", OP_0f07, 0, XX, XX, XX },
1542 { "xcrypt-ofb", OP_0f07, 0, XX, XX, XX },
1543 { "(bad)", OP_0f07, 0, XX, XX, XX },
1544 { "(bad)", OP_0f07, 0, XX, XX, XX },
30d1c836
ML
1545 },
1546 /* GRPPADLCK2 */
1547 {
050dfa73
MM
1548 { "montmul", OP_0f07, 0, XX, XX, XX },
1549 { "xsha1", OP_0f07, 0, XX, XX, XX },
1550 { "xsha256", OP_0f07, 0, XX, XX, XX },
1551 { "(bad)", OP_0f07, 0, XX, XX, XX },
1552 { "(bad)", OP_0f07, 0, XX, XX, XX },
1553 { "(bad)", OP_0f07, 0, XX, XX, XX },
1554 { "(bad)", OP_0f07, 0, XX, XX, XX },
1555 { "(bad)", OP_0f07, 0, XX, XX, XX },
252b5132 1556 }
252b5132
RH
1557};
1558
041bd2e0 1559static const struct dis386 prefix_user_table[][4] = {
c608c12e
AM
1560 /* PREGRP0 */
1561 {
050dfa73
MM
1562 { "addps", XM, EX, XX, XX },
1563 { "addss", XM, EX, XX, XX },
1564 { "addpd", XM, EX, XX, XX },
1565 { "addsd", XM, EX, XX, XX },
c608c12e
AM
1566 },
1567 /* PREGRP1 */
1568 {
050dfa73
MM
1569 { "", XM, EX, OPSIMD, XX }, /* See OP_SIMD_SUFFIX. */
1570 { "", XM, EX, OPSIMD, XX },
1571 { "", XM, EX, OPSIMD, XX },
1572 { "", XM, EX, OPSIMD, XX },
c608c12e
AM
1573 },
1574 /* PREGRP2 */
1575 {
4d9567e0 1576 { "cvtpi2ps", XM, EMC, XX, XX },
050dfa73 1577 { "cvtsi2ssY", XM, Ev, XX, XX },
4d9567e0 1578 { "cvtpi2pd", XM, EMC, XX, XX },
050dfa73 1579 { "cvtsi2sdY", XM, Ev, XX, XX },
c608c12e
AM
1580 },
1581 /* PREGRP3 */
1582 {
4d9567e0 1583 { "cvtps2pi", MXC, EX, XX, XX },
050dfa73 1584 { "cvtss2siY", Gv, EX, XX, XX },
4d9567e0 1585 { "cvtpd2pi", MXC, EX, XX, XX },
050dfa73 1586 { "cvtsd2siY", Gv, EX, XX, XX },
c608c12e
AM
1587 },
1588 /* PREGRP4 */
1589 {
4d9567e0 1590 { "cvttps2pi", MXC, EX, XX, XX },
050dfa73 1591 { "cvttss2siY", Gv, EX, XX, XX },
4d9567e0 1592 { "cvttpd2pi", MXC, EX, XX, XX },
050dfa73 1593 { "cvttsd2siY", Gv, EX, XX, XX },
c608c12e
AM
1594 },
1595 /* PREGRP5 */
1596 {
050dfa73
MM
1597 { "divps", XM, EX, XX, XX },
1598 { "divss", XM, EX, XX, XX },
1599 { "divpd", XM, EX, XX, XX },
1600 { "divsd", XM, EX, XX, XX },
c608c12e
AM
1601 },
1602 /* PREGRP6 */
1603 {
050dfa73
MM
1604 { "maxps", XM, EX, XX, XX },
1605 { "maxss", XM, EX, XX, XX },
1606 { "maxpd", XM, EX, XX, XX },
1607 { "maxsd", XM, EX, XX, XX },
c608c12e
AM
1608 },
1609 /* PREGRP7 */
1610 {
050dfa73
MM
1611 { "minps", XM, EX, XX, XX },
1612 { "minss", XM, EX, XX, XX },
1613 { "minpd", XM, EX, XX, XX },
1614 { "minsd", XM, EX, XX, XX },
c608c12e
AM
1615 },
1616 /* PREGRP8 */
1617 {
050dfa73
MM
1618 { "movups", XM, EX, XX, XX },
1619 { "movss", XM, EX, XX, XX },
1620 { "movupd", XM, EX, XX, XX },
1621 { "movsd", XM, EX, XX, XX },
c608c12e
AM
1622 },
1623 /* PREGRP9 */
1624 {
050dfa73
MM
1625 { "movups", EX, XM, XX, XX },
1626 { "movss", EX, XM, XX, XX },
1627 { "movupd", EX, XM, XX, XX },
1628 { "movsd", EX, XM, XX, XX },
c608c12e
AM
1629 },
1630 /* PREGRP10 */
1631 {
050dfa73
MM
1632 { "mulps", XM, EX, XX, XX },
1633 { "mulss", XM, EX, XX, XX },
1634 { "mulpd", XM, EX, XX, XX },
1635 { "mulsd", XM, EX, XX, XX },
c608c12e
AM
1636 },
1637 /* PREGRP11 */
1638 {
050dfa73
MM
1639 { "rcpps", XM, EX, XX, XX },
1640 { "rcpss", XM, EX, XX, XX },
1641 { "(bad)", XM, EX, XX, XX },
1642 { "(bad)", XM, EX, XX, XX },
c608c12e
AM
1643 },
1644 /* PREGRP12 */
1645 {
050dfa73
MM
1646 { "rsqrtps", XM, EX, XX, XX },
1647 { "rsqrtss", XM, EX, XX, XX },
1648 { "(bad)", XM, EX, XX, XX },
1649 { "(bad)", XM, EX, XX, XX },
c608c12e
AM
1650 },
1651 /* PREGRP13 */
1652 {
050dfa73
MM
1653 { "sqrtps", XM, EX, XX, XX },
1654 { "sqrtss", XM, EX, XX, XX },
1655 { "sqrtpd", XM, EX, XX, XX },
1656 { "sqrtsd", XM, EX, XX, XX },
c608c12e
AM
1657 },
1658 /* PREGRP14 */
1659 {
050dfa73
MM
1660 { "subps", XM, EX, XX, XX },
1661 { "subss", XM, EX, XX, XX },
1662 { "subpd", XM, EX, XX, XX },
1663 { "subsd", XM, EX, XX, XX },
041bd2e0
JH
1664 },
1665 /* PREGRP15 */
1666 {
050dfa73
MM
1667 { "(bad)", XM, EX, XX, XX},
1668 { "cvtdq2pd", XM, EX, XX, XX },
1669 { "cvttpd2dq", XM, EX, XX, XX },
1670 { "cvtpd2dq", XM, EX, XX, XX },
041bd2e0
JH
1671 },
1672 /* PREGRP16 */
1673 {
050dfa73
MM
1674 { "cvtdq2ps", XM, EX, XX, XX },
1675 { "cvttps2dq",XM, EX, XX, XX },
1676 { "cvtps2dq",XM, EX, XX, XX },
1677 { "(bad)", XM, EX, XX, XX },
041bd2e0
JH
1678 },
1679 /* PREGRP17 */
1680 {
050dfa73
MM
1681 { "cvtps2pd", XM, EX, XX, XX },
1682 { "cvtss2sd", XM, EX, XX, XX },
1683 { "cvtpd2ps", XM, EX, XX, XX },
1684 { "cvtsd2ss", XM, EX, XX, XX },
041bd2e0
JH
1685 },
1686 /* PREGRP18 */
1687 {
050dfa73
MM
1688 { "maskmovq", MX, MS, XX, XX },
1689 { "(bad)", XM, EX, XX, XX },
1690 { "maskmovdqu", XM, EX, XX, XX },
1691 { "(bad)", XM, EX, XX, XX },
041bd2e0
JH
1692 },
1693 /* PREGRP19 */
1694 {
050dfa73
MM
1695 { "movq", MX, EM, XX, XX },
1696 { "movdqu", XM, EX, XX, XX },
1697 { "movdqa", XM, EX, XX, XX },
1698 { "(bad)", XM, EX, XX, XX },
041bd2e0
JH
1699 },
1700 /* PREGRP20 */
1701 {
050dfa73
MM
1702 { "movq", EM, MX, XX, XX },
1703 { "movdqu", EX, XM, XX, XX },
1704 { "movdqa", EX, XM, XX, XX },
1705 { "(bad)", EX, XM, XX, XX },
041bd2e0
JH
1706 },
1707 /* PREGRP21 */
1708 {
050dfa73
MM
1709 { "(bad)", EX, XM, XX, XX },
1710 { "movq2dq", XM, MS, XX, XX },
1711 { "movq", EX, XM, XX, XX },
1712 { "movdq2q", MX, XS, XX, XX },
041bd2e0
JH
1713 },
1714 /* PREGRP22 */
1715 {
050dfa73
MM
1716 { "pshufw", MX, EM, Ib, XX },
1717 { "pshufhw", XM, EX, Ib, XX },
1718 { "pshufd", XM, EX, Ib, XX },
1719 { "pshuflw", XM, EX, Ib, XX},
041bd2e0
JH
1720 },
1721 /* PREGRP23 */
1722 {
050dfa73
MM
1723 { "movd", Edq, MX, XX, XX },
1724 { "movq", XM, EX, XX, XX },
1725 { "movd", Edq, XM, XX, XX },
1726 { "(bad)", Ed, XM, XX, XX },
041bd2e0
JH
1727 },
1728 /* PREGRP24 */
1729 {
050dfa73
MM
1730 { "(bad)", MX, EX, XX, XX },
1731 { "(bad)", XM, EX, XX, XX },
1732 { "punpckhqdq", XM, EX, XX, XX },
1733 { "(bad)", XM, EX, XX, XX },
0f17484f
AM
1734 },
1735 /* PREGRP25 */
1736 {
050dfa73
MM
1737 { "movntq", EM, MX, XX, XX },
1738 { "(bad)", EM, XM, XX, XX },
1739 { "movntdq", EM, XM, XX, XX },
1740 { "(bad)", EM, XM, XX, XX },
0f17484f
AM
1741 },
1742 /* PREGRP26 */
1743 {
050dfa73
MM
1744 { "(bad)", MX, EX, XX, XX },
1745 { "(bad)", XM, EX, XX, XX },
1746 { "punpcklqdq", XM, EX, XX, XX },
1747 { "(bad)", XM, EX, XX, XX },
041bd2e0 1748 },
ca164297
L
1749 /* PREGRP27 */
1750 {
050dfa73
MM
1751 { "(bad)", MX, EX, XX, XX },
1752 { "(bad)", XM, EX, XX, XX },
1753 { "addsubpd", XM, EX, XX, XX },
1754 { "addsubps", XM, EX, XX, XX },
ca164297
L
1755 },
1756 /* PREGRP28 */
1757 {
050dfa73
MM
1758 { "(bad)", MX, EX, XX, XX },
1759 { "(bad)", XM, EX, XX, XX },
1760 { "haddpd", XM, EX, XX, XX },
1761 { "haddps", XM, EX, XX, XX },
ca164297
L
1762 },
1763 /* PREGRP29 */
1764 {
050dfa73
MM
1765 { "(bad)", MX, EX, XX, XX },
1766 { "(bad)", XM, EX, XX, XX },
1767 { "hsubpd", XM, EX, XX, XX },
1768 { "hsubps", XM, EX, XX, XX },
ca164297
L
1769 },
1770 /* PREGRP30 */
1771 {
050dfa73
MM
1772 { "movlpX", XM, EX, SIMD_Fixup, 'h', XX }, /* really only 2 operands */
1773 { "movsldup", XM, EX, XX, XX },
1774 { "movlpd", XM, EX, XX, XX },
1775 { "movddup", XM, EX, XX, XX },
ca164297
L
1776 },
1777 /* PREGRP31 */
1778 {
050dfa73
MM
1779 { "movhpX", XM, EX, SIMD_Fixup, 'l', XX },
1780 { "movshdup", XM, EX, XX, XX },
1781 { "movhpd", XM, EX, XX, XX },
1782 { "(bad)", XM, EX, XX, XX },
ca164297
L
1783 },
1784 /* PREGRP32 */
1785 {
050dfa73
MM
1786 { "(bad)", XM, EX, XX, XX },
1787 { "(bad)", XM, EX, XX, XX },
1788 { "(bad)", XM, EX, XX, XX },
1789 { "lddqu", XM, M, XX, XX },
ca164297 1790 },
050dfa73
MM
1791 /* PREGRP33 */
1792 {
1793 {"movntps",Ev, XM, XX, XX},
1794 {"movntss",Ev, XM, XX, XX},
1795 {"movntpd",Ev, XM, XX, XX},
1796 {"movntsd",Ev, XM, XX, XX},
1797 },
1798
1799 /* PREGRP34 */
1800 {
1801 {"vmread", Em, Gm, XX, XX},
1802 {"(bad)", XX, XX, XX, XX},
1803 {"extrq", XS, Ib, Ib, XX},
1804 {"insertq",XM, XS, Ib, Ib},
1805 },
1806
1807 /* PREGRP35 */
1808 {
1809 {"vmwrite", Gm, Em, XX, XX},
1810 {"(bad)", XX, XX, XX, XX},
1811 {"extrq", XM, XS, XX, XX},
1812 {"insertq", XM, XS, XX, XX},
1813 },
1814
1815 /* PREGRP36 */
1816 {
1817 { "bsrS", Gv, Ev, XX, XX },
1818 { "lzcntS", Gv, Ev, XX, XX },
1819 { "bsrS", Gv, Ev, XX, XX },
1820 { "(bad)", XX, XX, XX, XX },
1821 },
1822
c608c12e
AM
1823};
1824
6439fc28
AM
1825static const struct dis386 x86_64_table[][2] = {
1826 {
050dfa73
MM
1827 { "arpl", Ew, Gw, XX, XX },
1828 { "movs{||lq|xd}", Gv, Ed, XX, XX },
6439fc28
AM
1829 },
1830};
1831
96fbad73 1832static const struct dis386 three_byte_table[][256] = {
331d2d0d
L
1833 /* THREE_BYTE_0 */
1834 {
96fbad73 1835 /* 00 */
050dfa73
MM
1836 { "pshufb", MX, EM, XX, XX },
1837 { "phaddw", MX, EM, XX, XX },
1838 { "phaddd", MX, EM, XX, XX },
1839 { "phaddsw", MX, EM, XX, XX },
1840 { "pmaddubsw", MX, EM, XX, XX },
1841 { "phsubw", MX, EM, XX, XX },
1842 { "phsubd", MX, EM, XX, XX },
1843 { "phsubsw", MX, EM, XX, XX },
96fbad73 1844 /* 08 */
050dfa73
MM
1845 { "psignb", MX, EM, XX, XX },
1846 { "psignw", MX, EM, XX, XX },
1847 { "psignd", MX, EM, XX, XX },
1848 { "pmulhrsw", MX, EM, XX, XX },
1849 { "(bad)", XX, XX, XX, XX },
1850 { "(bad)", XX, XX, XX, XX },
1851 { "(bad)", XX, XX, XX, XX },
1852 { "(bad)", XX, XX, XX, XX },
96fbad73 1853 /* 10 */
050dfa73
MM
1854 { "(bad)", XX, XX, XX, XX },
1855 { "(bad)", XX, XX, XX, XX },
1856 { "(bad)", XX, XX, XX, XX },
1857 { "(bad)", XX, XX, XX, XX },
1858 { "(bad)", XX, XX, XX, XX },
1859 { "(bad)", XX, XX, XX, XX },
1860 { "(bad)", XX, XX, XX, XX },
1861 { "(bad)", XX, XX, XX, XX },
96fbad73 1862 /* 18 */
050dfa73
MM
1863 { "(bad)", XX, XX, XX, XX },
1864 { "(bad)", XX, XX, XX, XX },
1865 { "(bad)", XX, XX, XX, XX },
1866 { "(bad)", XX, XX, XX, XX },
1867 { "pabsb", MX, EM, XX, XX },
1868 { "pabsw", MX, EM, XX, XX },
1869 { "pabsd", MX, EM, XX, XX },
96fbad73
L
1870 { "(bad)", XX, XX, XX, XX },
1871 /* 20 */
1872 { "(bad)", XX, XX, XX, XX },
1873 { "(bad)", XX, XX, XX, XX },
1874 { "(bad)", XX, XX, XX, XX },
1875 { "(bad)", XX, XX, XX, XX },
1876 { "(bad)", XX, XX, XX, XX },
1877 { "(bad)", XX, XX, XX, XX },
1878 { "(bad)", XX, XX, XX, XX },
1879 { "(bad)", XX, XX, XX, XX },
1880 /* 28 */
1881 { "(bad)", XX, XX, XX, XX },
1882 { "(bad)", XX, XX, XX, XX },
1883 { "(bad)", XX, XX, XX, XX },
1884 { "(bad)", XX, XX, XX, XX },
1885 { "(bad)", XX, XX, XX, XX },
1886 { "(bad)", XX, XX, XX, XX },
1887 { "(bad)", XX, XX, XX, XX },
1888 { "(bad)", XX, XX, XX, XX },
1889 /* 30 */
1890 { "(bad)", XX, XX, XX, XX },
1891 { "(bad)", XX, XX, XX, XX },
1892 { "(bad)", XX, XX, XX, XX },
1893 { "(bad)", XX, XX, XX, XX },
1894 { "(bad)", XX, XX, XX, XX },
1895 { "(bad)", XX, XX, XX, XX },
1896 { "(bad)", XX, XX, XX, XX },
1897 { "(bad)", XX, XX, XX, XX },
1898 /* 38 */
1899 { "(bad)", XX, XX, XX, XX },
1900 { "(bad)", XX, XX, XX, XX },
1901 { "(bad)", XX, XX, XX, XX },
1902 { "(bad)", XX, XX, XX, XX },
1903 { "(bad)", XX, XX, XX, XX },
1904 { "(bad)", XX, XX, XX, XX },
1905 { "(bad)", XX, XX, XX, XX },
1906 { "(bad)", XX, XX, XX, XX },
1907 /* 40 */
1908 { "(bad)", XX, XX, XX, XX },
1909 { "(bad)", XX, XX, XX, XX },
1910 { "(bad)", XX, XX, XX, XX },
1911 { "(bad)", XX, XX, XX, XX },
1912 { "(bad)", XX, XX, XX, XX },
1913 { "(bad)", XX, XX, XX, XX },
1914 { "(bad)", XX, XX, XX, XX },
1915 { "(bad)", XX, XX, XX, XX },
1916 /* 48 */
1917 { "(bad)", XX, XX, XX, XX },
1918 { "(bad)", XX, XX, XX, XX },
1919 { "(bad)", XX, XX, XX, XX },
1920 { "(bad)", XX, XX, XX, XX },
1921 { "(bad)", XX, XX, XX, XX },
1922 { "(bad)", XX, XX, XX, XX },
1923 { "(bad)", XX, XX, XX, XX },
1924 { "(bad)", XX, XX, XX, XX },
1925 /* 50 */
1926 { "(bad)", XX, XX, XX, XX },
1927 { "(bad)", XX, XX, XX, XX },
1928 { "(bad)", XX, XX, XX, XX },
1929 { "(bad)", XX, XX, XX, XX },
1930 { "(bad)", XX, XX, XX, XX },
1931 { "(bad)", XX, XX, XX, XX },
1932 { "(bad)", XX, XX, XX, XX },
1933 { "(bad)", XX, XX, XX, XX },
1934 /* 58 */
1935 { "(bad)", XX, XX, XX, XX },
1936 { "(bad)", XX, XX, XX, XX },
1937 { "(bad)", XX, XX, XX, XX },
1938 { "(bad)", XX, XX, XX, XX },
1939 { "(bad)", XX, XX, XX, XX },
1940 { "(bad)", XX, XX, XX, XX },
1941 { "(bad)", XX, XX, XX, XX },
1942 { "(bad)", XX, XX, XX, XX },
1943 /* 60 */
1944 { "(bad)", XX, XX, XX, XX },
1945 { "(bad)", XX, XX, XX, XX },
1946 { "(bad)", XX, XX, XX, XX },
1947 { "(bad)", XX, XX, XX, XX },
1948 { "(bad)", XX, XX, XX, XX },
1949 { "(bad)", XX, XX, XX, XX },
1950 { "(bad)", XX, XX, XX, XX },
1951 { "(bad)", XX, XX, XX, XX },
1952 /* 68 */
1953 { "(bad)", XX, XX, XX, XX },
1954 { "(bad)", XX, XX, XX, XX },
1955 { "(bad)", XX, XX, XX, XX },
1956 { "(bad)", XX, XX, XX, XX },
1957 { "(bad)", XX, XX, XX, XX },
1958 { "(bad)", XX, XX, XX, XX },
1959 { "(bad)", XX, XX, XX, XX },
1960 { "(bad)", XX, XX, XX, XX },
1961 /* 70 */
1962 { "(bad)", XX, XX, XX, XX },
1963 { "(bad)", XX, XX, XX, XX },
1964 { "(bad)", XX, XX, XX, XX },
1965 { "(bad)", XX, XX, XX, XX },
1966 { "(bad)", XX, XX, XX, XX },
1967 { "(bad)", XX, XX, XX, XX },
1968 { "(bad)", XX, XX, XX, XX },
1969 { "(bad)", XX, XX, XX, XX },
1970 /* 78 */
1971 { "(bad)", XX, XX, XX, XX },
1972 { "(bad)", XX, XX, XX, XX },
1973 { "(bad)", XX, XX, XX, XX },
1974 { "(bad)", XX, XX, XX, XX },
1975 { "(bad)", XX, XX, XX, XX },
1976 { "(bad)", XX, XX, XX, XX },
1977 { "(bad)", XX, XX, XX, XX },
1978 { "(bad)", XX, XX, XX, XX },
1979 /* 80 */
1980 { "(bad)", XX, XX, XX, XX },
1981 { "(bad)", XX, XX, XX, XX },
1982 { "(bad)", XX, XX, XX, XX },
1983 { "(bad)", XX, XX, XX, XX },
1984 { "(bad)", XX, XX, XX, XX },
1985 { "(bad)", XX, XX, XX, XX },
1986 { "(bad)", XX, XX, XX, XX },
1987 { "(bad)", XX, XX, XX, XX },
1988 /* 88 */
1989 { "(bad)", XX, XX, XX, XX },
1990 { "(bad)", XX, XX, XX, XX },
1991 { "(bad)", XX, XX, XX, XX },
1992 { "(bad)", XX, XX, XX, XX },
1993 { "(bad)", XX, XX, XX, XX },
1994 { "(bad)", XX, XX, XX, XX },
1995 { "(bad)", XX, XX, XX, XX },
1996 { "(bad)", XX, XX, XX, XX },
1997 /* 90 */
1998 { "(bad)", XX, XX, XX, XX },
1999 { "(bad)", XX, XX, XX, XX },
2000 { "(bad)", XX, XX, XX, XX },
2001 { "(bad)", XX, XX, XX, XX },
2002 { "(bad)", XX, XX, XX, XX },
2003 { "(bad)", XX, XX, XX, XX },
2004 { "(bad)", XX, XX, XX, XX },
2005 { "(bad)", XX, XX, XX, XX },
2006 /* 98 */
2007 { "(bad)", XX, XX, XX, XX },
2008 { "(bad)", XX, XX, XX, XX },
2009 { "(bad)", XX, XX, XX, XX },
2010 { "(bad)", XX, XX, XX, XX },
2011 { "(bad)", XX, XX, XX, XX },
2012 { "(bad)", XX, XX, XX, XX },
2013 { "(bad)", XX, XX, XX, XX },
2014 { "(bad)", XX, XX, XX, XX },
2015 /* a0 */
2016 { "(bad)", XX, XX, XX, XX },
2017 { "(bad)", XX, XX, XX, XX },
2018 { "(bad)", XX, XX, XX, XX },
2019 { "(bad)", XX, XX, XX, XX },
2020 { "(bad)", XX, XX, XX, XX },
2021 { "(bad)", XX, XX, XX, XX },
2022 { "(bad)", XX, XX, XX, XX },
2023 { "(bad)", XX, XX, XX, XX },
2024 /* a8 */
2025 { "(bad)", XX, XX, XX, XX },
2026 { "(bad)", XX, XX, XX, XX },
2027 { "(bad)", XX, XX, XX, XX },
2028 { "(bad)", XX, XX, XX, XX },
2029 { "(bad)", XX, XX, XX, XX },
2030 { "(bad)", XX, XX, XX, XX },
2031 { "(bad)", XX, XX, XX, XX },
2032 { "(bad)", XX, XX, XX, XX },
2033 /* b0 */
2034 { "(bad)", XX, XX, XX, XX },
2035 { "(bad)", XX, XX, XX, XX },
2036 { "(bad)", XX, XX, XX, XX },
2037 { "(bad)", XX, XX, XX, XX },
2038 { "(bad)", XX, XX, XX, XX },
2039 { "(bad)", XX, XX, XX, XX },
2040 { "(bad)", XX, XX, XX, XX },
2041 { "(bad)", XX, XX, XX, XX },
2042 /* b8 */
2043 { "(bad)", XX, XX, XX, XX },
2044 { "(bad)", XX, XX, XX, XX },
2045 { "(bad)", XX, XX, XX, XX },
2046 { "(bad)", XX, XX, XX, XX },
2047 { "(bad)", XX, XX, XX, XX },
2048 { "(bad)", XX, XX, XX, XX },
2049 { "(bad)", XX, XX, XX, XX },
2050 { "(bad)", XX, XX, XX, XX },
2051 /* c0 */
2052 { "(bad)", XX, XX, XX, XX },
2053 { "(bad)", XX, XX, XX, XX },
2054 { "(bad)", XX, XX, XX, XX },
2055 { "(bad)", XX, XX, XX, XX },
2056 { "(bad)", XX, XX, XX, XX },
2057 { "(bad)", XX, XX, XX, XX },
2058 { "(bad)", XX, XX, XX, XX },
2059 { "(bad)", XX, XX, XX, XX },
2060 /* c8 */
2061 { "(bad)", XX, XX, XX, XX },
2062 { "(bad)", XX, XX, XX, XX },
2063 { "(bad)", XX, XX, XX, XX },
2064 { "(bad)", XX, XX, XX, XX },
2065 { "(bad)", XX, XX, XX, XX },
2066 { "(bad)", XX, XX, XX, XX },
2067 { "(bad)", XX, XX, XX, XX },
2068 { "(bad)", XX, XX, XX, XX },
2069 /* d0 */
2070 { "(bad)", XX, XX, XX, XX },
2071 { "(bad)", XX, XX, XX, XX },
2072 { "(bad)", XX, XX, XX, XX },
2073 { "(bad)", XX, XX, XX, XX },
2074 { "(bad)", XX, XX, XX, XX },
2075 { "(bad)", XX, XX, XX, XX },
2076 { "(bad)", XX, XX, XX, XX },
2077 { "(bad)", XX, XX, XX, XX },
2078 /* d8 */
2079 { "(bad)", XX, XX, XX, XX },
2080 { "(bad)", XX, XX, XX, XX },
2081 { "(bad)", XX, XX, XX, XX },
2082 { "(bad)", XX, XX, XX, XX },
2083 { "(bad)", XX, XX, XX, XX },
2084 { "(bad)", XX, XX, XX, XX },
2085 { "(bad)", XX, XX, XX, XX },
2086 { "(bad)", XX, XX, XX, XX },
2087 /* e0 */
2088 { "(bad)", XX, XX, XX, XX },
2089 { "(bad)", XX, XX, XX, XX },
2090 { "(bad)", XX, XX, XX, XX },
2091 { "(bad)", XX, XX, XX, XX },
2092 { "(bad)", XX, XX, XX, XX },
2093 { "(bad)", XX, XX, XX, XX },
2094 { "(bad)", XX, XX, XX, XX },
2095 { "(bad)", XX, XX, XX, XX },
2096 /* e8 */
2097 { "(bad)", XX, XX, XX, XX },
2098 { "(bad)", XX, XX, XX, XX },
2099 { "(bad)", XX, XX, XX, XX },
2100 { "(bad)", XX, XX, XX, XX },
2101 { "(bad)", XX, XX, XX, XX },
2102 { "(bad)", XX, XX, XX, XX },
2103 { "(bad)", XX, XX, XX, XX },
2104 { "(bad)", XX, XX, XX, XX },
2105 /* f0 */
2106 { "(bad)", XX, XX, XX, XX },
2107 { "(bad)", XX, XX, XX, XX },
2108 { "(bad)", XX, XX, XX, XX },
2109 { "(bad)", XX, XX, XX, XX },
2110 { "(bad)", XX, XX, XX, XX },
2111 { "(bad)", XX, XX, XX, XX },
2112 { "(bad)", XX, XX, XX, XX },
2113 { "(bad)", XX, XX, XX, XX },
2114 /* f8 */
2115 { "(bad)", XX, XX, XX, XX },
2116 { "(bad)", XX, XX, XX, XX },
2117 { "(bad)", XX, XX, XX, XX },
2118 { "(bad)", XX, XX, XX, XX },
2119 { "(bad)", XX, XX, XX, XX },
2120 { "(bad)", XX, XX, XX, XX },
2121 { "(bad)", XX, XX, XX, XX },
050dfa73 2122 { "(bad)", XX, XX, XX, XX }
331d2d0d
L
2123 },
2124 /* THREE_BYTE_1 */
2125 {
96fbad73 2126 /* 00 */
050dfa73
MM
2127 { "(bad)", XX, XX, XX, XX },
2128 { "(bad)", XX, XX, XX, XX },
2129 { "(bad)", XX, XX, XX, XX },
2130 { "(bad)", XX, XX, XX, XX },
2131 { "(bad)", XX, XX, XX, XX },
2132 { "(bad)", XX, XX, XX, XX },
2133 { "(bad)", XX, XX, XX, XX },
2134 { "(bad)", XX, XX, XX, XX },
96fbad73 2135 /* 08 */
050dfa73
MM
2136 { "(bad)", XX, XX, XX, XX },
2137 { "(bad)", XX, XX, XX, XX },
2138 { "(bad)", XX, XX, XX, XX },
2139 { "(bad)", XX, XX, XX, XX },
2140 { "(bad)", XX, XX, XX, XX },
2141 { "(bad)", XX, XX, XX, XX },
2142 { "(bad)", XX, XX, XX, XX },
2143 { "palignr", MX, EM, Ib, XX },
96fbad73
L
2144 /* 10 */
2145 { "(bad)", XX, XX, XX, XX },
2146 { "(bad)", XX, XX, XX, XX },
2147 { "(bad)", XX, XX, XX, XX },
2148 { "(bad)", XX, XX, XX, XX },
2149 { "(bad)", XX, XX, XX, XX },
2150 { "(bad)", XX, XX, XX, XX },
2151 { "(bad)", XX, XX, XX, XX },
2152 { "(bad)", XX, XX, XX, XX },
2153 /* 18 */
2154 { "(bad)", XX, XX, XX, XX },
2155 { "(bad)", XX, XX, XX, XX },
2156 { "(bad)", XX, XX, XX, XX },
2157 { "(bad)", XX, XX, XX, XX },
2158 { "(bad)", XX, XX, XX, XX },
2159 { "(bad)", XX, XX, XX, XX },
2160 { "(bad)", XX, XX, XX, XX },
2161 { "(bad)", XX, XX, XX, XX },
2162 /* 20 */
2163 { "(bad)", XX, XX, XX, XX },
2164 { "(bad)", XX, XX, XX, XX },
2165 { "(bad)", XX, XX, XX, XX },
2166 { "(bad)", XX, XX, XX, XX },
2167 { "(bad)", XX, XX, XX, XX },
2168 { "(bad)", XX, XX, XX, XX },
2169 { "(bad)", XX, XX, XX, XX },
2170 { "(bad)", XX, XX, XX, XX },
2171 /* 28 */
2172 { "(bad)", XX, XX, XX, XX },
2173 { "(bad)", XX, XX, XX, XX },
2174 { "(bad)", XX, XX, XX, XX },
2175 { "(bad)", XX, XX, XX, XX },
2176 { "(bad)", XX, XX, XX, XX },
2177 { "(bad)", XX, XX, XX, XX },
2178 { "(bad)", XX, XX, XX, XX },
2179 { "(bad)", XX, XX, XX, XX },
2180 /* 30 */
2181 { "(bad)", XX, XX, XX, XX },
2182 { "(bad)", XX, XX, XX, XX },
2183 { "(bad)", XX, XX, XX, XX },
2184 { "(bad)", XX, XX, XX, XX },
2185 { "(bad)", XX, XX, XX, XX },
2186 { "(bad)", XX, XX, XX, XX },
2187 { "(bad)", XX, XX, XX, XX },
2188 { "(bad)", XX, XX, XX, XX },
2189 /* 38 */
2190 { "(bad)", XX, XX, XX, XX },
2191 { "(bad)", XX, XX, XX, XX },
2192 { "(bad)", XX, XX, XX, XX },
2193 { "(bad)", XX, XX, XX, XX },
2194 { "(bad)", XX, XX, XX, XX },
2195 { "(bad)", XX, XX, XX, XX },
2196 { "(bad)", XX, XX, XX, XX },
2197 { "(bad)", XX, XX, XX, XX },
2198 /* 40 */
2199 { "(bad)", XX, XX, XX, XX },
2200 { "(bad)", XX, XX, XX, XX },
2201 { "(bad)", XX, XX, XX, XX },
2202 { "(bad)", XX, XX, XX, XX },
2203 { "(bad)", XX, XX, XX, XX },
2204 { "(bad)", XX, XX, XX, XX },
2205 { "(bad)", XX, XX, XX, XX },
2206 { "(bad)", XX, XX, XX, XX },
2207 /* 48 */
2208 { "(bad)", XX, XX, XX, XX },
2209 { "(bad)", XX, XX, XX, XX },
2210 { "(bad)", XX, XX, XX, XX },
2211 { "(bad)", XX, XX, XX, XX },
2212 { "(bad)", XX, XX, XX, XX },
2213 { "(bad)", XX, XX, XX, XX },
2214 { "(bad)", XX, XX, XX, XX },
2215 { "(bad)", XX, XX, XX, XX },
2216 /* 50 */
2217 { "(bad)", XX, XX, XX, XX },
2218 { "(bad)", XX, XX, XX, XX },
2219 { "(bad)", XX, XX, XX, XX },
2220 { "(bad)", XX, XX, XX, XX },
2221 { "(bad)", XX, XX, XX, XX },
2222 { "(bad)", XX, XX, XX, XX },
2223 { "(bad)", XX, XX, XX, XX },
2224 { "(bad)", XX, XX, XX, XX },
2225 /* 58 */
2226 { "(bad)", XX, XX, XX, XX },
2227 { "(bad)", XX, XX, XX, XX },
2228 { "(bad)", XX, XX, XX, XX },
2229 { "(bad)", XX, XX, XX, XX },
2230 { "(bad)", XX, XX, XX, XX },
2231 { "(bad)", XX, XX, XX, XX },
2232 { "(bad)", XX, XX, XX, XX },
2233 { "(bad)", XX, XX, XX, XX },
2234 /* 60 */
2235 { "(bad)", XX, XX, XX, XX },
2236 { "(bad)", XX, XX, XX, XX },
2237 { "(bad)", XX, XX, XX, XX },
2238 { "(bad)", XX, XX, XX, XX },
2239 { "(bad)", XX, XX, XX, XX },
2240 { "(bad)", XX, XX, XX, XX },
2241 { "(bad)", XX, XX, XX, XX },
2242 { "(bad)", XX, XX, XX, XX },
2243 /* 68 */
2244 { "(bad)", XX, XX, XX, XX },
2245 { "(bad)", XX, XX, XX, XX },
2246 { "(bad)", XX, XX, XX, XX },
2247 { "(bad)", XX, XX, XX, XX },
2248 { "(bad)", XX, XX, XX, XX },
2249 { "(bad)", XX, XX, XX, XX },
2250 { "(bad)", XX, XX, XX, XX },
2251 { "(bad)", XX, XX, XX, XX },
2252 /* 70 */
2253 { "(bad)", XX, XX, XX, XX },
2254 { "(bad)", XX, XX, XX, XX },
2255 { "(bad)", XX, XX, XX, XX },
2256 { "(bad)", XX, XX, XX, XX },
2257 { "(bad)", XX, XX, XX, XX },
2258 { "(bad)", XX, XX, XX, XX },
2259 { "(bad)", XX, XX, XX, XX },
2260 { "(bad)", XX, XX, XX, XX },
2261 /* 78 */
2262 { "(bad)", XX, XX, XX, XX },
2263 { "(bad)", XX, XX, XX, XX },
2264 { "(bad)", XX, XX, XX, XX },
2265 { "(bad)", XX, XX, XX, XX },
2266 { "(bad)", XX, XX, XX, XX },
2267 { "(bad)", XX, XX, XX, XX },
2268 { "(bad)", XX, XX, XX, XX },
2269 { "(bad)", XX, XX, XX, XX },
2270 /* 80 */
2271 { "(bad)", XX, XX, XX, XX },
2272 { "(bad)", XX, XX, XX, XX },
2273 { "(bad)", XX, XX, XX, XX },
2274 { "(bad)", XX, XX, XX, XX },
2275 { "(bad)", XX, XX, XX, XX },
2276 { "(bad)", XX, XX, XX, XX },
2277 { "(bad)", XX, XX, XX, XX },
2278 { "(bad)", XX, XX, XX, XX },
2279 /* 88 */
2280 { "(bad)", XX, XX, XX, XX },
2281 { "(bad)", XX, XX, XX, XX },
2282 { "(bad)", XX, XX, XX, XX },
2283 { "(bad)", XX, XX, XX, XX },
2284 { "(bad)", XX, XX, XX, XX },
2285 { "(bad)", XX, XX, XX, XX },
2286 { "(bad)", XX, XX, XX, XX },
2287 { "(bad)", XX, XX, XX, XX },
2288 /* 90 */
2289 { "(bad)", XX, XX, XX, XX },
2290 { "(bad)", XX, XX, XX, XX },
2291 { "(bad)", XX, XX, XX, XX },
2292 { "(bad)", XX, XX, XX, XX },
2293 { "(bad)", XX, XX, XX, XX },
2294 { "(bad)", XX, XX, XX, XX },
2295 { "(bad)", XX, XX, XX, XX },
2296 { "(bad)", XX, XX, XX, XX },
2297 /* 98 */
2298 { "(bad)", XX, XX, XX, XX },
2299 { "(bad)", XX, XX, XX, XX },
2300 { "(bad)", XX, XX, XX, XX },
2301 { "(bad)", XX, XX, XX, XX },
2302 { "(bad)", XX, XX, XX, XX },
2303 { "(bad)", XX, XX, XX, XX },
2304 { "(bad)", XX, XX, XX, XX },
2305 { "(bad)", XX, XX, XX, XX },
2306 /* a0 */
2307 { "(bad)", XX, XX, XX, XX },
2308 { "(bad)", XX, XX, XX, XX },
2309 { "(bad)", XX, XX, XX, XX },
2310 { "(bad)", XX, XX, XX, XX },
2311 { "(bad)", XX, XX, XX, XX },
2312 { "(bad)", XX, XX, XX, XX },
2313 { "(bad)", XX, XX, XX, XX },
2314 { "(bad)", XX, XX, XX, XX },
2315 /* a8 */
2316 { "(bad)", XX, XX, XX, XX },
2317 { "(bad)", XX, XX, XX, XX },
2318 { "(bad)", XX, XX, XX, XX },
2319 { "(bad)", XX, XX, XX, XX },
2320 { "(bad)", XX, XX, XX, XX },
2321 { "(bad)", XX, XX, XX, XX },
2322 { "(bad)", XX, XX, XX, XX },
2323 { "(bad)", XX, XX, XX, XX },
2324 /* b0 */
2325 { "(bad)", XX, XX, XX, XX },
2326 { "(bad)", XX, XX, XX, XX },
2327 { "(bad)", XX, XX, XX, XX },
2328 { "(bad)", XX, XX, XX, XX },
2329 { "(bad)", XX, XX, XX, XX },
2330 { "(bad)", XX, XX, XX, XX },
2331 { "(bad)", XX, XX, XX, XX },
2332 { "(bad)", XX, XX, XX, XX },
2333 /* b8 */
2334 { "(bad)", XX, XX, XX, XX },
2335 { "(bad)", XX, XX, XX, XX },
2336 { "(bad)", XX, XX, XX, XX },
2337 { "(bad)", XX, XX, XX, XX },
2338 { "(bad)", XX, XX, XX, XX },
2339 { "(bad)", XX, XX, XX, XX },
2340 { "(bad)", XX, XX, XX, XX },
2341 { "(bad)", XX, XX, XX, XX },
2342 /* c0 */
2343 { "(bad)", XX, XX, XX, XX },
2344 { "(bad)", XX, XX, XX, XX },
2345 { "(bad)", XX, XX, XX, XX },
2346 { "(bad)", XX, XX, XX, XX },
2347 { "(bad)", XX, XX, XX, XX },
2348 { "(bad)", XX, XX, XX, XX },
2349 { "(bad)", XX, XX, XX, XX },
2350 { "(bad)", XX, XX, XX, XX },
2351 /* c8 */
2352 { "(bad)", XX, XX, XX, XX },
2353 { "(bad)", XX, XX, XX, XX },
2354 { "(bad)", XX, XX, XX, XX },
2355 { "(bad)", XX, XX, XX, XX },
2356 { "(bad)", XX, XX, XX, XX },
2357 { "(bad)", XX, XX, XX, XX },
2358 { "(bad)", XX, XX, XX, XX },
2359 { "(bad)", XX, XX, XX, XX },
2360 /* d0 */
2361 { "(bad)", XX, XX, XX, XX },
2362 { "(bad)", XX, XX, XX, XX },
2363 { "(bad)", XX, XX, XX, XX },
2364 { "(bad)", XX, XX, XX, XX },
2365 { "(bad)", XX, XX, XX, XX },
2366 { "(bad)", XX, XX, XX, XX },
2367 { "(bad)", XX, XX, XX, XX },
2368 { "(bad)", XX, XX, XX, XX },
2369 /* d8 */
2370 { "(bad)", XX, XX, XX, XX },
2371 { "(bad)", XX, XX, XX, XX },
2372 { "(bad)", XX, XX, XX, XX },
2373 { "(bad)", XX, XX, XX, XX },
2374 { "(bad)", XX, XX, XX, XX },
2375 { "(bad)", XX, XX, XX, XX },
2376 { "(bad)", XX, XX, XX, XX },
2377 { "(bad)", XX, XX, XX, XX },
2378 /* e0 */
2379 { "(bad)", XX, XX, XX, XX },
2380 { "(bad)", XX, XX, XX, XX },
2381 { "(bad)", XX, XX, XX, XX },
2382 { "(bad)", XX, XX, XX, XX },
2383 { "(bad)", XX, XX, XX, XX },
2384 { "(bad)", XX, XX, XX, XX },
2385 { "(bad)", XX, XX, XX, XX },
2386 { "(bad)", XX, XX, XX, XX },
2387 /* e8 */
2388 { "(bad)", XX, XX, XX, XX },
2389 { "(bad)", XX, XX, XX, XX },
2390 { "(bad)", XX, XX, XX, XX },
2391 { "(bad)", XX, XX, XX, XX },
2392 { "(bad)", XX, XX, XX, XX },
2393 { "(bad)", XX, XX, XX, XX },
2394 { "(bad)", XX, XX, XX, XX },
2395 { "(bad)", XX, XX, XX, XX },
2396 /* f0 */
050dfa73
MM
2397 { "(bad)", XX, XX, XX, XX },
2398 { "(bad)", XX, XX, XX, XX },
2399 { "(bad)", XX, XX, XX, XX },
2400 { "(bad)", XX, XX, XX, XX },
2401 { "(bad)", XX, XX, XX, XX },
2402 { "(bad)", XX, XX, XX, XX },
2403 { "(bad)", XX, XX, XX, XX },
2404 { "(bad)", XX, XX, XX, XX },
96fbad73 2405 /* f8 */
050dfa73
MM
2406 { "(bad)", XX, XX, XX, XX },
2407 { "(bad)", XX, XX, XX, XX },
2408 { "(bad)", XX, XX, XX, XX },
2409 { "(bad)", XX, XX, XX, XX },
2410 { "(bad)", XX, XX, XX, XX },
2411 { "(bad)", XX, XX, XX, XX },
2412 { "(bad)", XX, XX, XX, XX },
2413 { "(bad)", XX, XX, XX, XX }
331d2d0d
L
2414 },
2415};
2416
c608c12e
AM
2417#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2418
252b5132 2419static void
26ca5450 2420ckprefix (void)
252b5132 2421{
52b15da3
JH
2422 int newrex;
2423 rex = 0;
252b5132 2424 prefixes = 0;
7d421014 2425 used_prefixes = 0;
52b15da3 2426 rex_used = 0;
252b5132
RH
2427 while (1)
2428 {
2429 FETCH_DATA (the_info, codep + 1);
52b15da3 2430 newrex = 0;
252b5132
RH
2431 switch (*codep)
2432 {
52b15da3
JH
2433 /* REX prefixes family. */
2434 case 0x40:
2435 case 0x41:
2436 case 0x42:
2437 case 0x43:
2438 case 0x44:
2439 case 0x45:
2440 case 0x46:
2441 case 0x47:
2442 case 0x48:
2443 case 0x49:
2444 case 0x4a:
2445 case 0x4b:
2446 case 0x4c:
2447 case 0x4d:
2448 case 0x4e:
2449 case 0x4f:
cb712a9e 2450 if (address_mode == mode_64bit)
52b15da3
JH
2451 newrex = *codep;
2452 else
2453 return;
2454 break;
252b5132
RH
2455 case 0xf3:
2456 prefixes |= PREFIX_REPZ;
2457 break;
2458 case 0xf2:
2459 prefixes |= PREFIX_REPNZ;
2460 break;
2461 case 0xf0:
2462 prefixes |= PREFIX_LOCK;
2463 break;
2464 case 0x2e:
2465 prefixes |= PREFIX_CS;
2466 break;
2467 case 0x36:
2468 prefixes |= PREFIX_SS;
2469 break;
2470 case 0x3e:
2471 prefixes |= PREFIX_DS;
2472 break;
2473 case 0x26:
2474 prefixes |= PREFIX_ES;
2475 break;
2476 case 0x64:
2477 prefixes |= PREFIX_FS;
2478 break;
2479 case 0x65:
2480 prefixes |= PREFIX_GS;
2481 break;
2482 case 0x66:
2483 prefixes |= PREFIX_DATA;
2484 break;
2485 case 0x67:
2486 prefixes |= PREFIX_ADDR;
2487 break;
5076851f 2488 case FWAIT_OPCODE:
252b5132
RH
2489 /* fwait is really an instruction. If there are prefixes
2490 before the fwait, they belong to the fwait, *not* to the
2491 following instruction. */
3e7d61b2 2492 if (prefixes || rex)
252b5132
RH
2493 {
2494 prefixes |= PREFIX_FWAIT;
2495 codep++;
2496 return;
2497 }
2498 prefixes = PREFIX_FWAIT;
2499 break;
2500 default:
2501 return;
2502 }
52b15da3
JH
2503 /* Rex is ignored when followed by another prefix. */
2504 if (rex)
2505 {
3e7d61b2
AM
2506 rex_used = rex;
2507 return;
52b15da3
JH
2508 }
2509 rex = newrex;
252b5132
RH
2510 codep++;
2511 }
2512}
2513
7d421014
ILT
2514/* Return the name of the prefix byte PREF, or NULL if PREF is not a
2515 prefix byte. */
2516
2517static const char *
26ca5450 2518prefix_name (int pref, int sizeflag)
7d421014
ILT
2519{
2520 switch (pref)
2521 {
52b15da3
JH
2522 /* REX prefixes family. */
2523 case 0x40:
2524 return "rex";
2525 case 0x41:
2526 return "rexZ";
2527 case 0x42:
2528 return "rexY";
2529 case 0x43:
2530 return "rexYZ";
2531 case 0x44:
2532 return "rexX";
2533 case 0x45:
2534 return "rexXZ";
2535 case 0x46:
2536 return "rexXY";
2537 case 0x47:
2538 return "rexXYZ";
2539 case 0x48:
2540 return "rex64";
2541 case 0x49:
2542 return "rex64Z";
2543 case 0x4a:
2544 return "rex64Y";
2545 case 0x4b:
2546 return "rex64YZ";
2547 case 0x4c:
2548 return "rex64X";
2549 case 0x4d:
2550 return "rex64XZ";
2551 case 0x4e:
2552 return "rex64XY";
2553 case 0x4f:
2554 return "rex64XYZ";
7d421014
ILT
2555 case 0xf3:
2556 return "repz";
2557 case 0xf2:
2558 return "repnz";
2559 case 0xf0:
2560 return "lock";
2561 case 0x2e:
2562 return "cs";
2563 case 0x36:
2564 return "ss";
2565 case 0x3e:
2566 return "ds";
2567 case 0x26:
2568 return "es";
2569 case 0x64:
2570 return "fs";
2571 case 0x65:
2572 return "gs";
2573 case 0x66:
2574 return (sizeflag & DFLAG) ? "data16" : "data32";
2575 case 0x67:
cb712a9e 2576 if (address_mode == mode_64bit)
db6eb5be 2577 return (sizeflag & AFLAG) ? "addr32" : "addr64";
c1a64871 2578 else
2888cb7a 2579 return (sizeflag & AFLAG) ? "addr16" : "addr32";
7d421014
ILT
2580 case FWAIT_OPCODE:
2581 return "fwait";
2582 default:
2583 return NULL;
2584 }
2585}
2586
050dfa73
MM
2587static char op1out[100], op2out[100], op3out[100], op4out[100];
2588static int op_ad, op_index[4];
1d9f512f 2589static int two_source_ops;
050dfa73
MM
2590static bfd_vma op_address[4];
2591static bfd_vma op_riprel[4];
52b15da3 2592static bfd_vma start_pc;
252b5132
RH
2593\f
2594/*
2595 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2596 * (see topic "Redundant prefixes" in the "Differences from 8086"
2597 * section of the "Virtual 8086 Mode" chapter.)
2598 * 'pc' should be the address of this instruction, it will
2599 * be used to print the target address if this is a relative jump or call
2600 * The function returns the length of this instruction in bytes.
2601 */
2602
252b5132
RH
2603static char intel_syntax;
2604static char open_char;
2605static char close_char;
2606static char separator_char;
2607static char scale_char;
2608
e396998b
AM
2609/* Here for backwards compatibility. When gdb stops using
2610 print_insn_i386_att and print_insn_i386_intel these functions can
2611 disappear, and print_insn_i386 be merged into print_insn. */
252b5132 2612int
26ca5450 2613print_insn_i386_att (bfd_vma pc, disassemble_info *info)
252b5132
RH
2614{
2615 intel_syntax = 0;
e396998b
AM
2616
2617 return print_insn (pc, info);
252b5132
RH
2618}
2619
2620int
26ca5450 2621print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
252b5132
RH
2622{
2623 intel_syntax = 1;
e396998b
AM
2624
2625 return print_insn (pc, info);
252b5132
RH
2626}
2627
e396998b 2628int
26ca5450 2629print_insn_i386 (bfd_vma pc, disassemble_info *info)
e396998b
AM
2630{
2631 intel_syntax = -1;
2632
2633 return print_insn (pc, info);
2634}
2635
2636static int
26ca5450 2637print_insn (bfd_vma pc, disassemble_info *info)
252b5132 2638{
2da11e11 2639 const struct dis386 *dp;
252b5132 2640 int i;
050dfa73 2641 char *first, *second, *third, *fourth;
252b5132 2642 int needcomma;
c4a530c5 2643 unsigned char uses_SSE_prefix, uses_LOCK_prefix;
e396998b
AM
2644 int sizeflag;
2645 const char *p;
252b5132 2646 struct dis_private priv;
252b5132 2647
cb712a9e
L
2648 if (info->mach == bfd_mach_x86_64_intel_syntax
2649 || info->mach == bfd_mach_x86_64)
2650 address_mode = mode_64bit;
2651 else
2652 address_mode = mode_32bit;
52b15da3 2653
8373f971 2654 if (intel_syntax == (char) -1)
e396998b
AM
2655 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2656 || info->mach == bfd_mach_x86_64_intel_syntax);
2657
2da11e11 2658 if (info->mach == bfd_mach_i386_i386
52b15da3
JH
2659 || info->mach == bfd_mach_x86_64
2660 || info->mach == bfd_mach_i386_i386_intel_syntax
2661 || info->mach == bfd_mach_x86_64_intel_syntax)
e396998b 2662 priv.orig_sizeflag = AFLAG | DFLAG;
2da11e11 2663 else if (info->mach == bfd_mach_i386_i8086)
e396998b 2664 priv.orig_sizeflag = 0;
2da11e11
AM
2665 else
2666 abort ();
e396998b
AM
2667
2668 for (p = info->disassembler_options; p != NULL; )
2669 {
fa405d97 2670 if (strncmp (p, "x86-64", 6) == 0)
e396998b 2671 {
cb712a9e 2672 address_mode = mode_64bit;
e396998b
AM
2673 priv.orig_sizeflag = AFLAG | DFLAG;
2674 }
2675 else if (strncmp (p, "i386", 4) == 0)
2676 {
cb712a9e 2677 address_mode = mode_32bit;
e396998b
AM
2678 priv.orig_sizeflag = AFLAG | DFLAG;
2679 }
2680 else if (strncmp (p, "i8086", 5) == 0)
2681 {
cb712a9e 2682 address_mode = mode_16bit;
e396998b
AM
2683 priv.orig_sizeflag = 0;
2684 }
2685 else if (strncmp (p, "intel", 5) == 0)
2686 {
2687 intel_syntax = 1;
2688 }
2689 else if (strncmp (p, "att", 3) == 0)
2690 {
2691 intel_syntax = 0;
2692 }
2693 else if (strncmp (p, "addr", 4) == 0)
2694 {
2695 if (p[4] == '1' && p[5] == '6')
2696 priv.orig_sizeflag &= ~AFLAG;
2697 else if (p[4] == '3' && p[5] == '2')
2698 priv.orig_sizeflag |= AFLAG;
2699 }
2700 else if (strncmp (p, "data", 4) == 0)
2701 {
2702 if (p[4] == '1' && p[5] == '6')
2703 priv.orig_sizeflag &= ~DFLAG;
2704 else if (p[4] == '3' && p[5] == '2')
2705 priv.orig_sizeflag |= DFLAG;
2706 }
2707 else if (strncmp (p, "suffix", 6) == 0)
2708 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2709
2710 p = strchr (p, ',');
2711 if (p != NULL)
2712 p++;
2713 }
2714
2715 if (intel_syntax)
2716 {
2717 names64 = intel_names64;
2718 names32 = intel_names32;
2719 names16 = intel_names16;
2720 names8 = intel_names8;
2721 names8rex = intel_names8rex;
2722 names_seg = intel_names_seg;
2723 index16 = intel_index16;
2724 open_char = '[';
2725 close_char = ']';
2726 separator_char = '+';
2727 scale_char = '*';
2728 }
2729 else
2730 {
2731 names64 = att_names64;
2732 names32 = att_names32;
2733 names16 = att_names16;
2734 names8 = att_names8;
2735 names8rex = att_names8rex;
2736 names_seg = att_names_seg;
2737 index16 = att_index16;
2738 open_char = '(';
2739 close_char = ')';
2740 separator_char = ',';
2741 scale_char = ',';
2742 }
2da11e11 2743
4fe53c98 2744 /* The output looks better if we put 7 bytes on a line, since that
c608c12e 2745 puts most long word instructions on a single line. */
4fe53c98 2746 info->bytes_per_line = 7;
252b5132 2747
26ca5450 2748 info->private_data = &priv;
252b5132
RH
2749 priv.max_fetched = priv.the_buffer;
2750 priv.insn_start = pc;
252b5132
RH
2751
2752 obuf[0] = 0;
2753 op1out[0] = 0;
2754 op2out[0] = 0;
2755 op3out[0] = 0;
050dfa73 2756 op4out[0] = 0;
252b5132 2757
050dfa73 2758 op_index[0] = op_index[1] = op_index[2] = op_index[3] = -1;
252b5132
RH
2759
2760 the_info = info;
2761 start_pc = pc;
e396998b
AM
2762 start_codep = priv.the_buffer;
2763 codep = priv.the_buffer;
252b5132 2764
5076851f
ILT
2765 if (setjmp (priv.bailout) != 0)
2766 {
7d421014
ILT
2767 const char *name;
2768
5076851f 2769 /* Getting here means we tried for data but didn't get it. That
e396998b
AM
2770 means we have an incomplete instruction of some sort. Just
2771 print the first byte as a prefix or a .byte pseudo-op. */
2772 if (codep > priv.the_buffer)
5076851f 2773 {
e396998b 2774 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
7d421014
ILT
2775 if (name != NULL)
2776 (*info->fprintf_func) (info->stream, "%s", name);
2777 else
5076851f 2778 {
7d421014
ILT
2779 /* Just print the first byte as a .byte instruction. */
2780 (*info->fprintf_func) (info->stream, ".byte 0x%x",
e396998b 2781 (unsigned int) priv.the_buffer[0]);
5076851f 2782 }
5076851f 2783
7d421014 2784 return 1;
5076851f
ILT
2785 }
2786
2787 return -1;
2788 }
2789
52b15da3 2790 obufp = obuf;
252b5132
RH
2791 ckprefix ();
2792
2793 insn_codep = codep;
e396998b 2794 sizeflag = priv.orig_sizeflag;
252b5132
RH
2795
2796 FETCH_DATA (info, codep + 1);
2797 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2798
3e7d61b2
AM
2799 if (((prefixes & PREFIX_FWAIT)
2800 && ((*codep < 0xd8) || (*codep > 0xdf)))
2801 || (rex && rex_used))
252b5132 2802 {
7d421014
ILT
2803 const char *name;
2804
3e7d61b2
AM
2805 /* fwait not followed by floating point instruction, or rex followed
2806 by other prefixes. Print the first prefix. */
e396998b 2807 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
7d421014
ILT
2808 if (name == NULL)
2809 name = INTERNAL_DISASSEMBLER_ERROR;
2810 (*info->fprintf_func) (info->stream, "%s", name);
2811 return 1;
252b5132
RH
2812 }
2813
252b5132
RH
2814 if (*codep == 0x0f)
2815 {
2816 FETCH_DATA (info, codep + 2);
6439fc28 2817 dp = &dis386_twobyte[*++codep];
252b5132 2818 need_modrm = twobyte_has_modrm[*codep];
041bd2e0 2819 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
c4a530c5 2820 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
252b5132
RH
2821 }
2822 else
2823 {
6439fc28 2824 dp = &dis386[*codep];
252b5132 2825 need_modrm = onebyte_has_modrm[*codep];
041bd2e0 2826 uses_SSE_prefix = 0;
c4a530c5 2827 uses_LOCK_prefix = 0;
252b5132 2828 }
050dfa73
MM
2829
2830 /*"lzcnt"=0xBD is the only non-sse instruction which uses F3 in the opcode without any "rep(z|nz)"*/
2831 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ) && *codep !=0xBD)
7d421014
ILT
2832 {
2833 oappend ("repz ");
2834 used_prefixes |= PREFIX_REPZ;
2835 }
050dfa73 2836 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ) && *codep !=0xBD)
7d421014
ILT
2837 {
2838 oappend ("repnz ");
2839 used_prefixes |= PREFIX_REPNZ;
2840 }
050dfa73
MM
2841
2842 codep++;
2843
c4a530c5 2844 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
7d421014
ILT
2845 {
2846 oappend ("lock ");
2847 used_prefixes |= PREFIX_LOCK;
2848 }
c608c12e 2849
c608c12e
AM
2850 if (prefixes & PREFIX_ADDR)
2851 {
2852 sizeflag ^= AFLAG;
6439fc28 2853 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
3ffd33cf 2854 {
cb712a9e 2855 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3ffd33cf
AM
2856 oappend ("addr32 ");
2857 else
2858 oappend ("addr16 ");
2859 used_prefixes |= PREFIX_ADDR;
2860 }
2861 }
2862
2863 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2864 {
2865 sizeflag ^= DFLAG;
6439fc28
AM
2866 if (dp->bytemode3 == cond_jump_mode
2867 && dp->bytemode1 == v_mode
2868 && !intel_syntax)
3ffd33cf
AM
2869 {
2870 if (sizeflag & DFLAG)
2871 oappend ("data32 ");
2872 else
2873 oappend ("data16 ");
2874 used_prefixes |= PREFIX_DATA;
2875 }
2876 }
2877
331d2d0d
L
2878 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
2879 {
2880 FETCH_DATA (info, codep + 2);
2881 dp = &three_byte_table[dp->bytemode2][*codep++];
2882 mod = (*codep >> 6) & 3;
2883 reg = (*codep >> 3) & 7;
2884 rm = *codep & 7;
2885 }
2886 else if (need_modrm)
252b5132
RH
2887 {
2888 FETCH_DATA (info, codep + 1);
2889 mod = (*codep >> 6) & 3;
2890 reg = (*codep >> 3) & 7;
2891 rm = *codep & 7;
2892 }
2893
2894 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2895 {
2896 dofloat (sizeflag);
2897 }
2898 else
2899 {
041bd2e0 2900 int index;
252b5132 2901 if (dp->name == NULL)
c608c12e 2902 {
6439fc28 2903 switch (dp->bytemode1)
c608c12e 2904 {
6439fc28
AM
2905 case USE_GROUPS:
2906 dp = &grps[dp->bytemode2][reg];
2907 break;
2908
2909 case USE_PREFIX_USER_TABLE:
2910 index = 0;
2911 used_prefixes |= (prefixes & PREFIX_REPZ);
2912 if (prefixes & PREFIX_REPZ)
2913 index = 1;
2914 else
2915 {
2916 used_prefixes |= (prefixes & PREFIX_DATA);
2917 if (prefixes & PREFIX_DATA)
2918 index = 2;
2919 else
2920 {
2921 used_prefixes |= (prefixes & PREFIX_REPNZ);
2922 if (prefixes & PREFIX_REPNZ)
2923 index = 3;
2924 }
2925 }
2926 dp = &prefix_user_table[dp->bytemode2][index];
2927 break;
252b5132 2928
6439fc28 2929 case X86_64_SPECIAL:
cb712a9e
L
2930 index = address_mode == mode_64bit ? 1 : 0;
2931 dp = &x86_64_table[dp->bytemode2][index];
6439fc28 2932 break;
252b5132 2933
6439fc28
AM
2934 default:
2935 oappend (INTERNAL_DISASSEMBLER_ERROR);
2936 break;
2937 }
2938 }
252b5132 2939
6439fc28
AM
2940 if (putop (dp->name, sizeflag) == 0)
2941 {
2942 obufp = op1out;
050dfa73 2943 op_ad = 3;
6439fc28 2944 if (dp->op1)
6608db57 2945 (*dp->op1) (dp->bytemode1, sizeflag);
6439fc28
AM
2946
2947 obufp = op2out;
050dfa73 2948 op_ad = 2;
6439fc28 2949 if (dp->op2)
6608db57 2950 (*dp->op2) (dp->bytemode2, sizeflag);
6439fc28
AM
2951
2952 obufp = op3out;
050dfa73 2953 op_ad = 1;
6439fc28 2954 if (dp->op3)
6608db57 2955 (*dp->op3) (dp->bytemode3, sizeflag);
050dfa73
MM
2956
2957 obufp = op4out;
2958 op_ad = 0;
2959 if (dp->op4)
2960 (*dp->op4) (dp->bytemode4, sizeflag);
6439fc28 2961 }
252b5132
RH
2962 }
2963
7d421014
ILT
2964 /* See if any prefixes were not used. If so, print the first one
2965 separately. If we don't do this, we'll wind up printing an
2966 instruction stream which does not precisely correspond to the
2967 bytes we are disassembling. */
2968 if ((prefixes & ~used_prefixes) != 0)
2969 {
2970 const char *name;
2971
e396998b 2972 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
7d421014
ILT
2973 if (name == NULL)
2974 name = INTERNAL_DISASSEMBLER_ERROR;
2975 (*info->fprintf_func) (info->stream, "%s", name);
2976 return 1;
2977 }
52b15da3
JH
2978 if (rex & ~rex_used)
2979 {
2980 const char *name;
e396998b 2981 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
52b15da3
JH
2982 if (name == NULL)
2983 name = INTERNAL_DISASSEMBLER_ERROR;
2984 (*info->fprintf_func) (info->stream, "%s ", name);
2985 }
7d421014 2986
252b5132
RH
2987 obufp = obuf + strlen (obuf);
2988 for (i = strlen (obuf); i < 6; i++)
2989 oappend (" ");
2990 oappend (" ");
2991 (*info->fprintf_func) (info->stream, "%s", obuf);
2992
2993 /* The enter and bound instructions are printed with operands in the same
2994 order as the intel book; everything else is printed in reverse order. */
2da11e11 2995 if (intel_syntax || two_source_ops)
252b5132
RH
2996 {
2997 first = op1out;
2998 second = op2out;
2999 third = op3out;
050dfa73 3000 fourth = op4out;
252b5132 3001 op_ad = op_index[0];
050dfa73
MM
3002 op_index[0] = op_index[3];
3003 op_index[3] = op_ad;
3004 op_ad = op_index[1];
3005 op_index[1] = op_index[2];
252b5132 3006 op_index[2] = op_ad;
050dfa73 3007
252b5132
RH
3008 }
3009 else
3010 {
050dfa73
MM
3011 first = op4out;
3012 second = op3out;
3013 third = op2out;
3014 fourth = op1out;
252b5132
RH
3015 }
3016 needcomma = 0;
3017 if (*first)
3018 {
52b15da3 3019 if (op_index[0] != -1 && !op_riprel[0])
252b5132
RH
3020 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
3021 else
3022 (*info->fprintf_func) (info->stream, "%s", first);
3023 needcomma = 1;
3024 }
050dfa73 3025
252b5132
RH
3026 if (*second)
3027 {
3028 if (needcomma)
3029 (*info->fprintf_func) (info->stream, ",");
52b15da3 3030 if (op_index[1] != -1 && !op_riprel[1])
252b5132
RH
3031 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
3032 else
3033 (*info->fprintf_func) (info->stream, "%s", second);
3034 needcomma = 1;
3035 }
050dfa73 3036
252b5132
RH
3037 if (*third)
3038 {
3039 if (needcomma)
3040 (*info->fprintf_func) (info->stream, ",");
52b15da3 3041 if (op_index[2] != -1 && !op_riprel[2])
252b5132
RH
3042 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
3043 else
3044 (*info->fprintf_func) (info->stream, "%s", third);
050dfa73
MM
3045 needcomma = 1;
3046 }
3047
3048 if (*fourth)
3049 {
3050 if (needcomma)
3051 (*info->fprintf_func) (info->stream, ",");
3052 if (op_index[3] != -1 && !op_riprel[3])
3053 (*info->print_address_func) ((bfd_vma) op_address[op_index[3]], info);
3054 else
3055 (*info->fprintf_func) (info->stream, "%s", fourth);
252b5132 3056 }
050dfa73
MM
3057
3058 for (i = 0; i < 4; i++)
52b15da3
JH
3059 if (op_index[i] != -1 && op_riprel[i])
3060 {
3061 (*info->fprintf_func) (info->stream, " # ");
3062 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3063 + op_address[op_index[i]]), info);
3064 }
e396998b 3065 return codep - priv.the_buffer;
252b5132
RH
3066}
3067
6439fc28 3068static const char *float_mem[] = {
252b5132 3069 /* d8 */
6439fc28
AM
3070 "fadd{s||s|}",
3071 "fmul{s||s|}",
3072 "fcom{s||s|}",
3073 "fcomp{s||s|}",
3074 "fsub{s||s|}",
3075 "fsubr{s||s|}",
3076 "fdiv{s||s|}",
3077 "fdivr{s||s|}",
db6eb5be 3078 /* d9 */
6439fc28 3079 "fld{s||s|}",
252b5132 3080 "(bad)",
6439fc28
AM
3081 "fst{s||s|}",
3082 "fstp{s||s|}",
9306ca4a 3083 "fldenvIC",
252b5132 3084 "fldcw",
9306ca4a 3085 "fNstenvIC",
252b5132
RH
3086 "fNstcw",
3087 /* da */
6439fc28
AM
3088 "fiadd{l||l|}",
3089 "fimul{l||l|}",
3090 "ficom{l||l|}",
3091 "ficomp{l||l|}",
3092 "fisub{l||l|}",
3093 "fisubr{l||l|}",
3094 "fidiv{l||l|}",
3095 "fidivr{l||l|}",
252b5132 3096 /* db */
6439fc28 3097 "fild{l||l|}",
ca164297 3098 "fisttp{l||l|}",
6439fc28
AM
3099 "fist{l||l|}",
3100 "fistp{l||l|}",
252b5132 3101 "(bad)",
6439fc28 3102 "fld{t||t|}",
252b5132 3103 "(bad)",
6439fc28 3104 "fstp{t||t|}",
252b5132 3105 /* dc */
6439fc28
AM
3106 "fadd{l||l|}",
3107 "fmul{l||l|}",
3108 "fcom{l||l|}",
3109 "fcomp{l||l|}",
3110 "fsub{l||l|}",
3111 "fsubr{l||l|}",
3112 "fdiv{l||l|}",
3113 "fdivr{l||l|}",
252b5132 3114 /* dd */
6439fc28 3115 "fld{l||l|}",
1d9f512f 3116 "fisttp{ll||ll|}",
6439fc28
AM
3117 "fst{l||l|}",
3118 "fstp{l||l|}",
9306ca4a 3119 "frstorIC",
252b5132 3120 "(bad)",
9306ca4a 3121 "fNsaveIC",
252b5132
RH
3122 "fNstsw",
3123 /* de */
3124 "fiadd",
3125 "fimul",
3126 "ficom",
3127 "ficomp",
3128 "fisub",
3129 "fisubr",
3130 "fidiv",
3131 "fidivr",
3132 /* df */
3133 "fild",
ca164297 3134 "fisttp",
252b5132
RH
3135 "fist",
3136 "fistp",
3137 "fbld",
6439fc28 3138 "fild{ll||ll|}",
252b5132 3139 "fbstp",
1d9f512f
AM
3140 "fistp{ll||ll|}",
3141};
3142
3143static const unsigned char float_mem_mode[] = {
3144 /* d8 */
3145 d_mode,
3146 d_mode,
3147 d_mode,
3148 d_mode,
3149 d_mode,
3150 d_mode,
3151 d_mode,
3152 d_mode,
3153 /* d9 */
3154 d_mode,
3155 0,
3156 d_mode,
3157 d_mode,
3158 0,
3159 w_mode,
3160 0,
3161 w_mode,
3162 /* da */
3163 d_mode,
3164 d_mode,
3165 d_mode,
3166 d_mode,
3167 d_mode,
3168 d_mode,
3169 d_mode,
3170 d_mode,
3171 /* db */
3172 d_mode,
3173 d_mode,
3174 d_mode,
3175 d_mode,
3176 0,
9306ca4a 3177 t_mode,
1d9f512f 3178 0,
9306ca4a 3179 t_mode,
1d9f512f
AM
3180 /* dc */
3181 q_mode,
3182 q_mode,
3183 q_mode,
3184 q_mode,
3185 q_mode,
3186 q_mode,
3187 q_mode,
3188 q_mode,
3189 /* dd */
3190 q_mode,
3191 q_mode,
3192 q_mode,
3193 q_mode,
3194 0,
3195 0,
3196 0,
3197 w_mode,
3198 /* de */
3199 w_mode,
3200 w_mode,
3201 w_mode,
3202 w_mode,
3203 w_mode,
3204 w_mode,
3205 w_mode,
3206 w_mode,
3207 /* df */
3208 w_mode,
3209 w_mode,
3210 w_mode,
3211 w_mode,
9306ca4a 3212 t_mode,
1d9f512f 3213 q_mode,
9306ca4a 3214 t_mode,
1d9f512f 3215 q_mode
252b5132
RH
3216};
3217
3218#define ST OP_ST, 0
3219#define STi OP_STi, 0
3220
050dfa73
MM
3221#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
3222#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
3223#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
3224#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
3225#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
3226#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
3227#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
3228#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
3229#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
252b5132 3230
2da11e11 3231static const struct dis386 float_reg[][8] = {
252b5132
RH
3232 /* d8 */
3233 {
050dfa73
MM
3234 { "fadd", ST, STi, XX, XX },
3235 { "fmul", ST, STi, XX, XX },
3236 { "fcom", STi, XX, XX, XX },
3237 { "fcomp", STi, XX, XX, XX },
3238 { "fsub", ST, STi, XX, XX },
3239 { "fsubr", ST, STi, XX, XX },
3240 { "fdiv", ST, STi, XX, XX },
3241 { "fdivr", ST, STi, XX, XX },
252b5132
RH
3242 },
3243 /* d9 */
3244 {
050dfa73
MM
3245 { "fld", STi, XX, XX, XX },
3246 { "fxch", STi, XX, XX, XX },
252b5132 3247 { FGRPd9_2 },
050dfa73 3248 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3249 { FGRPd9_4 },
3250 { FGRPd9_5 },
3251 { FGRPd9_6 },
3252 { FGRPd9_7 },
3253 },
3254 /* da */
3255 {
050dfa73
MM
3256 { "fcmovb", ST, STi, XX, XX },
3257 { "fcmove", ST, STi, XX, XX },
3258 { "fcmovbe",ST, STi, XX, XX },
3259 { "fcmovu", ST, STi, XX, XX },
3260 { "(bad)", XX, XX, XX, XX },
252b5132 3261 { FGRPda_5 },
050dfa73
MM
3262 { "(bad)", XX, XX, XX, XX },
3263 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3264 },
3265 /* db */
3266 {
050dfa73
MM
3267 { "fcmovnb",ST, STi, XX, XX },
3268 { "fcmovne",ST, STi, XX, XX },
3269 { "fcmovnbe",ST, STi, XX, XX },
3270 { "fcmovnu",ST, STi, XX, XX },
252b5132 3271 { FGRPdb_4 },
050dfa73
MM
3272 { "fucomi", ST, STi, XX, XX },
3273 { "fcomi", ST, STi, XX, XX },
3274 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3275 },
3276 /* dc */
3277 {
050dfa73
MM
3278 { "fadd", STi, ST, XX, XX },
3279 { "fmul", STi, ST, XX, XX },
3280 { "(bad)", XX, XX, XX, XX },
3281 { "(bad)", XX, XX, XX, XX },
252b5132 3282#if UNIXWARE_COMPAT
050dfa73
MM
3283 { "fsub", STi, ST, XX, XX },
3284 { "fsubr", STi, ST, XX, XX },
3285 { "fdiv", STi, ST, XX, XX },
3286 { "fdivr", STi, ST, XX, XX },
252b5132 3287#else
050dfa73
MM
3288 { "fsubr", STi, ST, XX, XX },
3289 { "fsub", STi, ST, XX, XX },
3290 { "fdivr", STi, ST, XX, XX },
3291 { "fdiv", STi, ST, XX, XX },
252b5132
RH
3292#endif
3293 },
3294 /* dd */
3295 {
050dfa73
MM
3296 { "ffree", STi, XX, XX, XX },
3297 { "(bad)", XX, XX, XX, XX },
3298 { "fst", STi, XX, XX, XX },
3299 { "fstp", STi, XX, XX, XX },
3300 { "fucom", STi, XX, XX, XX },
3301 { "fucomp", STi, XX, XX, XX },
3302 { "(bad)", XX, XX, XX, XX },
3303 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3304 },
3305 /* de */
3306 {
050dfa73
MM
3307 { "faddp", STi, ST, XX, XX },
3308 { "fmulp", STi, ST, XX, XX },
3309 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3310 { FGRPde_3 },
3311#if UNIXWARE_COMPAT
050dfa73
MM
3312 { "fsubp", STi, ST, XX, XX },
3313 { "fsubrp", STi, ST, XX, XX },
3314 { "fdivp", STi, ST, XX, XX },
3315 { "fdivrp", STi, ST, XX, XX },
252b5132 3316#else
050dfa73
MM
3317 { "fsubrp", STi, ST, XX, XX },
3318 { "fsubp", STi, ST, XX, XX },
3319 { "fdivrp", STi, ST, XX, XX },
3320 { "fdivp", STi, ST, XX, XX },
252b5132
RH
3321#endif
3322 },
3323 /* df */
3324 {
050dfa73
MM
3325 { "ffreep", STi, XX, XX, XX },
3326 { "(bad)", XX, XX, XX, XX },
3327 { "(bad)", XX, XX, XX, XX },
3328 { "(bad)", XX, XX, XX, XX },
252b5132 3329 { FGRPdf_4 },
050dfa73
MM
3330 { "fucomip",ST, STi, XX, XX },
3331 { "fcomip", ST, STi, XX, XX },
3332 { "(bad)", XX, XX, XX, XX },
252b5132
RH
3333 },
3334};
3335
252b5132
RH
3336static char *fgrps[][8] = {
3337 /* d9_2 0 */
3338 {
3339 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3340 },
3341
3342 /* d9_4 1 */
3343 {
3344 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3345 },
3346
3347 /* d9_5 2 */
3348 {
3349 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3350 },
3351
3352 /* d9_6 3 */
3353 {
3354 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3355 },
3356
3357 /* d9_7 4 */
3358 {
3359 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3360 },
3361
3362 /* da_5 5 */
3363 {
3364 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3365 },
3366
3367 /* db_4 6 */
3368 {
3369 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3370 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3371 },
3372
3373 /* de_3 7 */
3374 {
3375 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3376 },
3377
3378 /* df_4 8 */
3379 {
3380 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3381 },
3382};
3383
3384static void
26ca5450 3385dofloat (int sizeflag)
252b5132 3386{
2da11e11 3387 const struct dis386 *dp;
252b5132
RH
3388 unsigned char floatop;
3389
3390 floatop = codep[-1];
3391
3392 if (mod != 3)
3393 {
1d9f512f
AM
3394 int fp_indx = (floatop - 0xd8) * 8 + reg;
3395
3396 putop (float_mem[fp_indx], sizeflag);
252b5132 3397 obufp = op1out;
6e50d963 3398 op_ad = 2;
1d9f512f 3399 OP_E (float_mem_mode[fp_indx], sizeflag);
252b5132
RH
3400 return;
3401 }
6608db57 3402 /* Skip mod/rm byte. */
4bba6815 3403 MODRM_CHECK;
252b5132
RH
3404 codep++;
3405
3406 dp = &float_reg[floatop - 0xd8][reg];
3407 if (dp->name == NULL)
3408 {
3409 putop (fgrps[dp->bytemode1][rm], sizeflag);
3410
6608db57 3411 /* Instruction fnstsw is only one with strange arg. */
252b5132
RH
3412 if (floatop == 0xdf && codep[-1] == 0xe0)
3413 strcpy (op1out, names16[0]);
3414 }
3415 else
3416 {
3417 putop (dp->name, sizeflag);
3418
3419 obufp = op1out;
6e50d963 3420 op_ad = 2;
252b5132 3421 if (dp->op1)
6608db57 3422 (*dp->op1) (dp->bytemode1, sizeflag);
6e50d963 3423
252b5132 3424 obufp = op2out;
6e50d963 3425 op_ad = 1;
252b5132 3426 if (dp->op2)
6608db57 3427 (*dp->op2) (dp->bytemode2, sizeflag);
252b5132
RH
3428 }
3429}
3430
252b5132 3431static void
26ca5450 3432OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3433{
422673a9 3434 oappend ("%st" + intel_syntax);
252b5132
RH
3435}
3436
252b5132 3437static void
26ca5450 3438OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132
RH
3439{
3440 sprintf (scratchbuf, "%%st(%d)", rm);
d708bcba 3441 oappend (scratchbuf + intel_syntax);
252b5132
RH
3442}
3443
6608db57 3444/* Capital letters in template are macros. */
6439fc28 3445static int
26ca5450 3446putop (const char *template, int sizeflag)
252b5132 3447{
2da11e11 3448 const char *p;
9306ca4a 3449 int alt = 0;
252b5132
RH
3450
3451 for (p = template; *p; p++)
3452 {
3453 switch (*p)
3454 {
3455 default:
3456 *obufp++ = *p;
3457 break;
6439fc28
AM
3458 case '{':
3459 alt = 0;
3460 if (intel_syntax)
3461 alt += 1;
cb712a9e 3462 if (address_mode == mode_64bit)
6439fc28
AM
3463 alt += 2;
3464 while (alt != 0)
3465 {
3466 while (*++p != '|')
3467 {
3468 if (*p == '}')
3469 {
3470 /* Alternative not valid. */
3471 strcpy (obuf, "(bad)");
3472 obufp = obuf + 5;
3473 return 1;
3474 }
3475 else if (*p == '\0')
3476 abort ();
3477 }
3478 alt--;
3479 }
9306ca4a
JB
3480 /* Fall through. */
3481 case 'I':
3482 alt = 1;
3483 continue;
6439fc28
AM
3484 case '|':
3485 while (*++p != '}')
3486 {
3487 if (*p == '\0')
3488 abort ();
3489 }
3490 break;
3491 case '}':
3492 break;
252b5132 3493 case 'A':
db6eb5be
AM
3494 if (intel_syntax)
3495 break;
e396998b 3496 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
252b5132
RH
3497 *obufp++ = 'b';
3498 break;
3499 case 'B':
db6eb5be
AM
3500 if (intel_syntax)
3501 break;
252b5132
RH
3502 if (sizeflag & SUFFIX_ALWAYS)
3503 *obufp++ = 'b';
252b5132 3504 break;
9306ca4a
JB
3505 case 'C':
3506 if (intel_syntax && !alt)
3507 break;
3508 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
3509 {
3510 if (sizeflag & DFLAG)
3511 *obufp++ = intel_syntax ? 'd' : 'l';
3512 else
3513 *obufp++ = intel_syntax ? 'w' : 's';
3514 used_prefixes |= (prefixes & PREFIX_DATA);
3515 }
3516 break;
252b5132 3517 case 'E': /* For jcxz/jecxz */
cb712a9e 3518 if (address_mode == mode_64bit)
c1a64871
JH
3519 {
3520 if (sizeflag & AFLAG)
3521 *obufp++ = 'r';
3522 else
3523 *obufp++ = 'e';
3524 }
3525 else
3526 if (sizeflag & AFLAG)
3527 *obufp++ = 'e';
3ffd33cf
AM
3528 used_prefixes |= (prefixes & PREFIX_ADDR);
3529 break;
3530 case 'F':
db6eb5be
AM
3531 if (intel_syntax)
3532 break;
e396998b 3533 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3ffd33cf
AM
3534 {
3535 if (sizeflag & AFLAG)
cb712a9e 3536 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
3ffd33cf 3537 else
cb712a9e 3538 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
3ffd33cf
AM
3539 used_prefixes |= (prefixes & PREFIX_ADDR);
3540 }
252b5132 3541 break;
5dd0794d 3542 case 'H':
db6eb5be
AM
3543 if (intel_syntax)
3544 break;
5dd0794d
AM
3545 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3546 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3547 {
3548 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3549 *obufp++ = ',';
3550 *obufp++ = 'p';
3551 if (prefixes & PREFIX_DS)
3552 *obufp++ = 't';
3553 else
3554 *obufp++ = 'n';
3555 }
3556 break;
9306ca4a
JB
3557 case 'J':
3558 if (intel_syntax)
3559 break;
3560 *obufp++ = 'l';
3561 break;
6dd5059a
L
3562 case 'Z':
3563 if (intel_syntax)
3564 break;
3565 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3566 {
3567 *obufp++ = 'q';
3568 break;
3569 }
3570 /* Fall through. */
252b5132 3571 case 'L':
db6eb5be
AM
3572 if (intel_syntax)
3573 break;
252b5132
RH
3574 if (sizeflag & SUFFIX_ALWAYS)
3575 *obufp++ = 'l';
252b5132
RH
3576 break;
3577 case 'N':
3578 if ((prefixes & PREFIX_FWAIT) == 0)
3579 *obufp++ = 'n';
7d421014
ILT
3580 else
3581 used_prefixes |= PREFIX_FWAIT;
252b5132 3582 break;
52b15da3
JH
3583 case 'O':
3584 USED_REX (REX_MODE64);
3585 if (rex & REX_MODE64)
6439fc28 3586 *obufp++ = 'o';
52b15da3
JH
3587 else
3588 *obufp++ = 'd';
3589 break;
6439fc28 3590 case 'T':
db6eb5be
AM
3591 if (intel_syntax)
3592 break;
cb712a9e 3593 if (address_mode == mode_64bit && (sizeflag & DFLAG))
6439fc28
AM
3594 {
3595 *obufp++ = 'q';
3596 break;
3597 }
6608db57 3598 /* Fall through. */
252b5132 3599 case 'P':
db6eb5be
AM
3600 if (intel_syntax)
3601 break;
252b5132 3602 if ((prefixes & PREFIX_DATA)
52b15da3 3603 || (rex & REX_MODE64)
e396998b 3604 || (sizeflag & SUFFIX_ALWAYS))
252b5132 3605 {
52b15da3
JH
3606 USED_REX (REX_MODE64);
3607 if (rex & REX_MODE64)
3608 *obufp++ = 'q';
c2419411 3609 else
52b15da3
JH
3610 {
3611 if (sizeflag & DFLAG)
3612 *obufp++ = 'l';
3613 else
3614 *obufp++ = 'w';
52b15da3 3615 }
1a114b12 3616 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3617 }
3618 break;
6439fc28 3619 case 'U':
db6eb5be
AM
3620 if (intel_syntax)
3621 break;
cb712a9e 3622 if (address_mode == mode_64bit && (sizeflag & DFLAG))
6439fc28 3623 {
1a114b12
JB
3624 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3625 *obufp++ = 'q';
6439fc28
AM
3626 break;
3627 }
6608db57 3628 /* Fall through. */
252b5132 3629 case 'Q':
9306ca4a 3630 if (intel_syntax && !alt)
db6eb5be 3631 break;
90530880 3632 USED_REX (REX_MODE64);
e396998b 3633 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
252b5132 3634 {
52b15da3
JH
3635 if (rex & REX_MODE64)
3636 *obufp++ = 'q';
252b5132 3637 else
52b15da3
JH
3638 {
3639 if (sizeflag & DFLAG)
9306ca4a 3640 *obufp++ = intel_syntax ? 'd' : 'l';
52b15da3
JH
3641 else
3642 *obufp++ = 'w';
52b15da3 3643 }
1a114b12 3644 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3645 }
3646 break;
3647 case 'R':
52b15da3 3648 USED_REX (REX_MODE64);
db6eb5be 3649 if (intel_syntax)
c608c12e 3650 {
52b15da3
JH
3651 if (rex & REX_MODE64)
3652 {
3653 *obufp++ = 'q';
3654 *obufp++ = 't';
3655 }
3656 else if (sizeflag & DFLAG)
c608c12e
AM
3657 {
3658 *obufp++ = 'd';
3659 *obufp++ = 'q';
3660 }
3661 else
3662 {
3663 *obufp++ = 'w';
3664 *obufp++ = 'd';
3665 }
3666 }
252b5132 3667 else
c608c12e 3668 {
52b15da3
JH
3669 if (rex & REX_MODE64)
3670 *obufp++ = 'q';
3671 else if (sizeflag & DFLAG)
c608c12e
AM
3672 *obufp++ = 'l';
3673 else
3674 *obufp++ = 'w';
3675 }
52b15da3
JH
3676 if (!(rex & REX_MODE64))
3677 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132 3678 break;
1a114b12
JB
3679 case 'V':
3680 if (intel_syntax)
3681 break;
cb712a9e 3682 if (address_mode == mode_64bit && (sizeflag & DFLAG))
1a114b12
JB
3683 {
3684 if (sizeflag & SUFFIX_ALWAYS)
3685 *obufp++ = 'q';
3686 break;
3687 }
3688 /* Fall through. */
252b5132 3689 case 'S':
db6eb5be
AM
3690 if (intel_syntax)
3691 break;
252b5132
RH
3692 if (sizeflag & SUFFIX_ALWAYS)
3693 {
52b15da3
JH
3694 if (rex & REX_MODE64)
3695 *obufp++ = 'q';
252b5132 3696 else
52b15da3
JH
3697 {
3698 if (sizeflag & DFLAG)
3699 *obufp++ = 'l';
3700 else
3701 *obufp++ = 'w';
3702 used_prefixes |= (prefixes & PREFIX_DATA);
3703 }
252b5132 3704 }
252b5132 3705 break;
041bd2e0
JH
3706 case 'X':
3707 if (prefixes & PREFIX_DATA)
3708 *obufp++ = 'd';
3709 else
3710 *obufp++ = 's';
db6eb5be 3711 used_prefixes |= (prefixes & PREFIX_DATA);
041bd2e0 3712 break;
76f227a5 3713 case 'Y':
db6eb5be
AM
3714 if (intel_syntax)
3715 break;
76f227a5
JH
3716 if (rex & REX_MODE64)
3717 {
3718 USED_REX (REX_MODE64);
3719 *obufp++ = 'q';
3720 }
3721 break;
52b15da3 3722 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
252b5132 3723 case 'W':
252b5132 3724 /* operand size flag for cwtl, cbtw */
52b15da3
JH
3725 USED_REX (0);
3726 if (rex)
3727 *obufp++ = 'l';
3728 else if (sizeflag & DFLAG)
252b5132
RH
3729 *obufp++ = 'w';
3730 else
3731 *obufp++ = 'b';
db6eb5be 3732 if (intel_syntax)
c608c12e 3733 {
52b15da3
JH
3734 if (rex)
3735 {
3736 *obufp++ = 'q';
3737 *obufp++ = 'e';
3738 }
c608c12e
AM
3739 if (sizeflag & DFLAG)
3740 {
3741 *obufp++ = 'd';
3742 *obufp++ = 'e';
3743 }
3744 else
3745 {
3746 *obufp++ = 'w';
3747 }
3748 }
52b15da3
JH
3749 if (!rex)
3750 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3751 break;
3752 }
9306ca4a 3753 alt = 0;
252b5132
RH
3754 }
3755 *obufp = 0;
6439fc28 3756 return 0;
252b5132
RH
3757}
3758
3759static void
26ca5450 3760oappend (const char *s)
252b5132
RH
3761{
3762 strcpy (obufp, s);
3763 obufp += strlen (s);
3764}
3765
3766static void
26ca5450 3767append_seg (void)
252b5132
RH
3768{
3769 if (prefixes & PREFIX_CS)
7d421014 3770 {
7d421014 3771 used_prefixes |= PREFIX_CS;
d708bcba 3772 oappend ("%cs:" + intel_syntax);
7d421014 3773 }
252b5132 3774 if (prefixes & PREFIX_DS)
7d421014 3775 {
7d421014 3776 used_prefixes |= PREFIX_DS;
d708bcba 3777 oappend ("%ds:" + intel_syntax);
7d421014 3778 }
252b5132 3779 if (prefixes & PREFIX_SS)
7d421014 3780 {
7d421014 3781 used_prefixes |= PREFIX_SS;
d708bcba 3782 oappend ("%ss:" + intel_syntax);
7d421014 3783 }
252b5132 3784 if (prefixes & PREFIX_ES)
7d421014 3785 {
7d421014 3786 used_prefixes |= PREFIX_ES;
d708bcba 3787 oappend ("%es:" + intel_syntax);
7d421014 3788 }
252b5132 3789 if (prefixes & PREFIX_FS)
7d421014 3790 {
7d421014 3791 used_prefixes |= PREFIX_FS;
d708bcba 3792 oappend ("%fs:" + intel_syntax);
7d421014 3793 }
252b5132 3794 if (prefixes & PREFIX_GS)
7d421014 3795 {
7d421014 3796 used_prefixes |= PREFIX_GS;
d708bcba 3797 oappend ("%gs:" + intel_syntax);
7d421014 3798 }
252b5132
RH
3799}
3800
3801static void
26ca5450 3802OP_indirE (int bytemode, int sizeflag)
252b5132
RH
3803{
3804 if (!intel_syntax)
3805 oappend ("*");
3806 OP_E (bytemode, sizeflag);
3807}
3808
52b15da3 3809static void
26ca5450 3810print_operand_value (char *buf, int hex, bfd_vma disp)
52b15da3 3811{
cb712a9e 3812 if (address_mode == mode_64bit)
52b15da3
JH
3813 {
3814 if (hex)
3815 {
3816 char tmp[30];
3817 int i;
3818 buf[0] = '0';
3819 buf[1] = 'x';
3820 sprintf_vma (tmp, disp);
6608db57 3821 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
52b15da3
JH
3822 strcpy (buf + 2, tmp + i);
3823 }
3824 else
3825 {
3826 bfd_signed_vma v = disp;
3827 char tmp[30];
3828 int i;
3829 if (v < 0)
3830 {
3831 *(buf++) = '-';
3832 v = -disp;
6608db57 3833 /* Check for possible overflow on 0x8000000000000000. */
52b15da3
JH
3834 if (v < 0)
3835 {
3836 strcpy (buf, "9223372036854775808");
3837 return;
3838 }
3839 }
3840 if (!v)
3841 {
3842 strcpy (buf, "0");
3843 return;
3844 }
3845
3846 i = 0;
3847 tmp[29] = 0;
3848 while (v)
3849 {
6608db57 3850 tmp[28 - i] = (v % 10) + '0';
52b15da3
JH
3851 v /= 10;
3852 i++;
3853 }
3854 strcpy (buf, tmp + 29 - i);
3855 }
3856 }
3857 else
3858 {
3859 if (hex)
3860 sprintf (buf, "0x%x", (unsigned int) disp);
3861 else
3862 sprintf (buf, "%d", (int) disp);
3863 }
3864}
3865
3f31e633
JB
3866static void
3867intel_operand_size (int bytemode, int sizeflag)
3868{
3869 switch (bytemode)
3870 {
3871 case b_mode:
3872 oappend ("BYTE PTR ");
3873 break;
3874 case w_mode:
3875 case dqw_mode:
3876 oappend ("WORD PTR ");
3877 break;
1a114b12 3878 case stack_v_mode:
cb712a9e 3879 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3f31e633
JB
3880 {
3881 oappend ("QWORD PTR ");
3882 used_prefixes |= (prefixes & PREFIX_DATA);
3883 break;
3884 }
3885 /* FALLTHRU */
3886 case v_mode:
3887 case dq_mode:
3888 USED_REX (REX_MODE64);
3889 if (rex & REX_MODE64)
3890 oappend ("QWORD PTR ");
3891 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3892 oappend ("DWORD PTR ");
3893 else
3894 oappend ("WORD PTR ");
3895 used_prefixes |= (prefixes & PREFIX_DATA);
3896 break;
3897 case d_mode:
3898 oappend ("DWORD PTR ");
3899 break;
3900 case q_mode:
3901 oappend ("QWORD PTR ");
3902 break;
3903 case m_mode:
cb712a9e 3904 if (address_mode == mode_64bit)
3f31e633
JB
3905 oappend ("QWORD PTR ");
3906 else
3907 oappend ("DWORD PTR ");
3908 break;
3909 case f_mode:
3910 if (sizeflag & DFLAG)
3911 oappend ("FWORD PTR ");
3912 else
3913 oappend ("DWORD PTR ");
3914 used_prefixes |= (prefixes & PREFIX_DATA);
3915 break;
3916 case t_mode:
3917 oappend ("TBYTE PTR ");
3918 break;
3919 case x_mode:
3920 oappend ("XMMWORD PTR ");
3921 break;
3922 default:
3923 break;
3924 }
3925}
3926
252b5132 3927static void
26ca5450 3928OP_E (int bytemode, int sizeflag)
252b5132 3929{
52b15da3
JH
3930 bfd_vma disp;
3931 int add = 0;
3932 int riprel = 0;
3933 USED_REX (REX_EXTZ);
3934 if (rex & REX_EXTZ)
3935 add += 8;
252b5132 3936
6608db57 3937 /* Skip mod/rm byte. */
4bba6815 3938 MODRM_CHECK;
252b5132
RH
3939 codep++;
3940
3941 if (mod == 3)
3942 {
3943 switch (bytemode)
3944 {
3945 case b_mode:
52b15da3
JH
3946 USED_REX (0);
3947 if (rex)
3948 oappend (names8rex[rm + add]);
3949 else
3950 oappend (names8[rm + add]);
252b5132
RH
3951 break;
3952 case w_mode:
52b15da3 3953 oappend (names16[rm + add]);
252b5132 3954 break;
2da11e11 3955 case d_mode:
52b15da3
JH
3956 oappend (names32[rm + add]);
3957 break;
3958 case q_mode:
3959 oappend (names64[rm + add]);
3960 break;
3961 case m_mode:
cb712a9e 3962 if (address_mode == mode_64bit)
52b15da3
JH
3963 oappend (names64[rm + add]);
3964 else
3965 oappend (names32[rm + add]);
2da11e11 3966 break;
1a114b12 3967 case stack_v_mode:
cb712a9e 3968 if (address_mode == mode_64bit && (sizeflag & DFLAG))
003519a7 3969 {
1a114b12 3970 oappend (names64[rm + add]);
003519a7 3971 used_prefixes |= (prefixes & PREFIX_DATA);
1a114b12 3972 break;
003519a7 3973 }
1a114b12
JB
3974 bytemode = v_mode;
3975 /* FALLTHRU */
252b5132 3976 case v_mode:
db6eb5be 3977 case dq_mode:
9306ca4a 3978 case dqw_mode:
52b15da3
JH
3979 USED_REX (REX_MODE64);
3980 if (rex & REX_MODE64)
3981 oappend (names64[rm + add]);
9306ca4a 3982 else if ((sizeflag & DFLAG) || bytemode != v_mode)
52b15da3 3983 oappend (names32[rm + add]);
252b5132 3984 else
52b15da3 3985 oappend (names16[rm + add]);
7d421014 3986 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132 3987 break;
2da11e11 3988 case 0:
c608c12e 3989 break;
252b5132 3990 default:
c608c12e 3991 oappend (INTERNAL_DISASSEMBLER_ERROR);
252b5132
RH
3992 break;
3993 }
3994 return;
3995 }
3996
3997 disp = 0;
3f31e633
JB
3998 if (intel_syntax)
3999 intel_operand_size (bytemode, sizeflag);
252b5132
RH
4000 append_seg ();
4001
cb712a9e 4002 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
252b5132
RH
4003 {
4004 int havesib;
4005 int havebase;
4006 int base;
4007 int index = 0;
4008 int scale = 0;
4009
4010 havesib = 0;
4011 havebase = 1;
4012 base = rm;
4013
4014 if (base == 4)
4015 {
4016 havesib = 1;
4017 FETCH_DATA (the_info, codep + 1);
252b5132 4018 index = (*codep >> 3) & 7;
cb712a9e 4019 if (address_mode == mode_64bit || index != 0x4)
9df48ba9 4020 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
2033b4b9 4021 scale = (*codep >> 6) & 3;
252b5132 4022 base = *codep & 7;
52b15da3 4023 USED_REX (REX_EXTY);
52b15da3
JH
4024 if (rex & REX_EXTY)
4025 index += 8;
252b5132
RH
4026 codep++;
4027 }
2888cb7a 4028 base += add;
252b5132
RH
4029
4030 switch (mod)
4031 {
4032 case 0:
52b15da3 4033 if ((base & 7) == 5)
252b5132
RH
4034 {
4035 havebase = 0;
cb712a9e 4036 if (address_mode == mode_64bit && !havesib)
52b15da3
JH
4037 riprel = 1;
4038 disp = get32s ();
252b5132
RH
4039 }
4040 break;
4041 case 1:
4042 FETCH_DATA (the_info, codep + 1);
4043 disp = *codep++;
4044 if ((disp & 0x80) != 0)
4045 disp -= 0x100;
4046 break;
4047 case 2:
52b15da3 4048 disp = get32s ();
252b5132
RH
4049 break;
4050 }
4051
4052 if (!intel_syntax)
db6eb5be
AM
4053 if (mod != 0 || (base & 7) == 5)
4054 {
52b15da3 4055 print_operand_value (scratchbuf, !riprel, disp);
db6eb5be 4056 oappend (scratchbuf);
52b15da3
JH
4057 if (riprel)
4058 {
4059 set_op (disp, 1);
4060 oappend ("(%rip)");
4061 }
db6eb5be 4062 }
2da11e11 4063
252b5132
RH
4064 if (havebase || (havesib && (index != 4 || scale != 0)))
4065 {
252b5132 4066 *obufp++ = open_char;
52b15da3
JH
4067 if (intel_syntax && riprel)
4068 oappend ("rip + ");
db6eb5be 4069 *obufp = '\0';
252b5132 4070 if (havebase)
cb712a9e 4071 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
c1a64871 4072 ? names64[base] : names32[base]);
252b5132
RH
4073 if (havesib)
4074 {
4075 if (index != 4)
4076 {
9306ca4a 4077 if (!intel_syntax || havebase)
db6eb5be 4078 {
9306ca4a
JB
4079 *obufp++ = separator_char;
4080 *obufp = '\0';
db6eb5be 4081 }
cb712a9e 4082 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
9306ca4a 4083 ? names64[index] : names32[index]);
252b5132 4084 }
a02a862a 4085 if (scale != 0 || (!intel_syntax && index != 4))
db6eb5be
AM
4086 {
4087 *obufp++ = scale_char;
4088 *obufp = '\0';
4089 sprintf (scratchbuf, "%d", 1 << scale);
4090 oappend (scratchbuf);
4091 }
252b5132 4092 }
3d456fa1
JB
4093 if (intel_syntax && disp)
4094 {
4095 if ((bfd_signed_vma) disp > 0)
4096 {
4097 *obufp++ = '+';
4098 *obufp = '\0';
4099 }
4100 else if (mod != 1)
4101 {
4102 *obufp++ = '-';
4103 *obufp = '\0';
4104 disp = - (bfd_signed_vma) disp;
4105 }
4106
4107 print_operand_value (scratchbuf, mod != 1, disp);
4108 oappend (scratchbuf);
4109 }
252b5132
RH
4110
4111 *obufp++ = close_char;
db6eb5be 4112 *obufp = '\0';
252b5132
RH
4113 }
4114 else if (intel_syntax)
db6eb5be
AM
4115 {
4116 if (mod != 0 || (base & 7) == 5)
4117 {
252b5132
RH
4118 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4119 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4120 ;
4121 else
4122 {
d708bcba 4123 oappend (names_seg[ds_reg - es_reg]);
252b5132
RH
4124 oappend (":");
4125 }
52b15da3 4126 print_operand_value (scratchbuf, 1, disp);
db6eb5be
AM
4127 oappend (scratchbuf);
4128 }
4129 }
252b5132
RH
4130 }
4131 else
4132 { /* 16 bit address mode */
4133 switch (mod)
4134 {
4135 case 0:
2888cb7a 4136 if (rm == 6)
252b5132
RH
4137 {
4138 disp = get16 ();
4139 if ((disp & 0x8000) != 0)
4140 disp -= 0x10000;
4141 }
4142 break;
4143 case 1:
4144 FETCH_DATA (the_info, codep + 1);
4145 disp = *codep++;
4146 if ((disp & 0x80) != 0)
4147 disp -= 0x100;
4148 break;
4149 case 2:
4150 disp = get16 ();
4151 if ((disp & 0x8000) != 0)
4152 disp -= 0x10000;
4153 break;
4154 }
4155
4156 if (!intel_syntax)
2888cb7a 4157 if (mod != 0 || rm == 6)
db6eb5be 4158 {
52b15da3 4159 print_operand_value (scratchbuf, 0, disp);
db6eb5be
AM
4160 oappend (scratchbuf);
4161 }
252b5132 4162
2888cb7a 4163 if (mod != 0 || rm != 6)
252b5132
RH
4164 {
4165 *obufp++ = open_char;
db6eb5be 4166 *obufp = '\0';
3d456fa1
JB
4167 oappend (index16[rm]);
4168 if (intel_syntax && disp)
4169 {
4170 if ((bfd_signed_vma) disp > 0)
4171 {
4172 *obufp++ = '+';
4173 *obufp = '\0';
4174 }
4175 else if (mod != 1)
4176 {
4177 *obufp++ = '-';
4178 *obufp = '\0';
4179 disp = - (bfd_signed_vma) disp;
4180 }
4181
4182 print_operand_value (scratchbuf, mod != 1, disp);
4183 oappend (scratchbuf);
4184 }
4185
db6eb5be
AM
4186 *obufp++ = close_char;
4187 *obufp = '\0';
252b5132 4188 }
3d456fa1
JB
4189 else if (intel_syntax)
4190 {
4191 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4192 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4193 ;
4194 else
4195 {
4196 oappend (names_seg[ds_reg - es_reg]);
4197 oappend (":");
4198 }
4199 print_operand_value (scratchbuf, 1, disp & 0xffff);
4200 oappend (scratchbuf);
4201 }
252b5132
RH
4202 }
4203}
4204
252b5132 4205static void
26ca5450 4206OP_G (int bytemode, int sizeflag)
252b5132 4207{
52b15da3
JH
4208 int add = 0;
4209 USED_REX (REX_EXTX);
4210 if (rex & REX_EXTX)
4211 add += 8;
252b5132
RH
4212 switch (bytemode)
4213 {
4214 case b_mode:
52b15da3
JH
4215 USED_REX (0);
4216 if (rex)
4217 oappend (names8rex[reg + add]);
4218 else
4219 oappend (names8[reg + add]);
252b5132
RH
4220 break;
4221 case w_mode:
52b15da3 4222 oappend (names16[reg + add]);
252b5132
RH
4223 break;
4224 case d_mode:
52b15da3
JH
4225 oappend (names32[reg + add]);
4226 break;
4227 case q_mode:
4228 oappend (names64[reg + add]);
252b5132
RH
4229 break;
4230 case v_mode:
9306ca4a
JB
4231 case dq_mode:
4232 case dqw_mode:
52b15da3
JH
4233 USED_REX (REX_MODE64);
4234 if (rex & REX_MODE64)
4235 oappend (names64[reg + add]);
9306ca4a 4236 else if ((sizeflag & DFLAG) || bytemode != v_mode)
52b15da3 4237 oappend (names32[reg + add]);
252b5132 4238 else
52b15da3 4239 oappend (names16[reg + add]);
7d421014 4240 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132 4241 break;
90700ea2 4242 case m_mode:
cb712a9e 4243 if (address_mode == mode_64bit)
90700ea2
L
4244 oappend (names64[reg + add]);
4245 else
4246 oappend (names32[reg + add]);
4247 break;
252b5132
RH
4248 default:
4249 oappend (INTERNAL_DISASSEMBLER_ERROR);
4250 break;
4251 }
4252}
4253
52b15da3 4254static bfd_vma
26ca5450 4255get64 (void)
52b15da3 4256{
5dd0794d 4257 bfd_vma x;
52b15da3 4258#ifdef BFD64
5dd0794d
AM
4259 unsigned int a;
4260 unsigned int b;
4261
52b15da3
JH
4262 FETCH_DATA (the_info, codep + 8);
4263 a = *codep++ & 0xff;
4264 a |= (*codep++ & 0xff) << 8;
4265 a |= (*codep++ & 0xff) << 16;
4266 a |= (*codep++ & 0xff) << 24;
5dd0794d 4267 b = *codep++ & 0xff;
52b15da3
JH
4268 b |= (*codep++ & 0xff) << 8;
4269 b |= (*codep++ & 0xff) << 16;
4270 b |= (*codep++ & 0xff) << 24;
4271 x = a + ((bfd_vma) b << 32);
4272#else
6608db57 4273 abort ();
5dd0794d 4274 x = 0;
52b15da3
JH
4275#endif
4276 return x;
4277}
4278
4279static bfd_signed_vma
26ca5450 4280get32 (void)
252b5132 4281{
52b15da3 4282 bfd_signed_vma x = 0;
252b5132
RH
4283
4284 FETCH_DATA (the_info, codep + 4);
52b15da3
JH
4285 x = *codep++ & (bfd_signed_vma) 0xff;
4286 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4287 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4288 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4289 return x;
4290}
4291
4292static bfd_signed_vma
26ca5450 4293get32s (void)
52b15da3
JH
4294{
4295 bfd_signed_vma x = 0;
4296
4297 FETCH_DATA (the_info, codep + 4);
4298 x = *codep++ & (bfd_signed_vma) 0xff;
4299 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4300 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4301 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4302
4303 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
4304
252b5132
RH
4305 return x;
4306}
4307
4308static int
26ca5450 4309get16 (void)
252b5132
RH
4310{
4311 int x = 0;
4312
4313 FETCH_DATA (the_info, codep + 2);
4314 x = *codep++ & 0xff;
4315 x |= (*codep++ & 0xff) << 8;
4316 return x;
4317}
4318
4319static void
26ca5450 4320set_op (bfd_vma op, int riprel)
252b5132
RH
4321{
4322 op_index[op_ad] = op_ad;
cb712a9e 4323 if (address_mode == mode_64bit)
7081ff04
AJ
4324 {
4325 op_address[op_ad] = op;
4326 op_riprel[op_ad] = riprel;
4327 }
4328 else
4329 {
4330 /* Mask to get a 32-bit address. */
4331 op_address[op_ad] = op & 0xffffffff;
4332 op_riprel[op_ad] = riprel & 0xffffffff;
4333 }
252b5132
RH
4334}
4335
4336static void
26ca5450 4337OP_REG (int code, int sizeflag)
252b5132 4338{
2da11e11 4339 const char *s;
52b15da3
JH
4340 int add = 0;
4341 USED_REX (REX_EXTZ);
4342 if (rex & REX_EXTZ)
4343 add = 8;
4344
4345 switch (code)
4346 {
4347 case indir_dx_reg:
d708bcba 4348 if (intel_syntax)
db6eb5be 4349 s = "[dx]";
d708bcba 4350 else
db6eb5be 4351 s = "(%dx)";
52b15da3
JH
4352 break;
4353 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4354 case sp_reg: case bp_reg: case si_reg: case di_reg:
4355 s = names16[code - ax_reg + add];
4356 break;
4357 case es_reg: case ss_reg: case cs_reg:
4358 case ds_reg: case fs_reg: case gs_reg:
4359 s = names_seg[code - es_reg + add];
4360 break;
4361 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4362 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4363 USED_REX (0);
4364 if (rex)
4365 s = names8rex[code - al_reg + add];
4366 else
4367 s = names8[code - al_reg];
4368 break;
6439fc28
AM
4369 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
4370 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
cb712a9e 4371 if (address_mode == mode_64bit && (sizeflag & DFLAG))
6439fc28
AM
4372 {
4373 s = names64[code - rAX_reg + add];
4374 break;
4375 }
4376 code += eAX_reg - rAX_reg;
6608db57 4377 /* Fall through. */
52b15da3
JH
4378 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4379 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4380 USED_REX (REX_MODE64);
4381 if (rex & REX_MODE64)
4382 s = names64[code - eAX_reg + add];
4383 else if (sizeflag & DFLAG)
4384 s = names32[code - eAX_reg + add];
4385 else
4386 s = names16[code - eAX_reg + add];
4387 used_prefixes |= (prefixes & PREFIX_DATA);
4388 break;
52b15da3
JH
4389 default:
4390 s = INTERNAL_DISASSEMBLER_ERROR;
4391 break;
4392 }
4393 oappend (s);
4394}
4395
4396static void
26ca5450 4397OP_IMREG (int code, int sizeflag)
52b15da3
JH
4398{
4399 const char *s;
252b5132
RH
4400
4401 switch (code)
4402 {
4403 case indir_dx_reg:
d708bcba 4404 if (intel_syntax)
db6eb5be 4405 s = "[dx]";
d708bcba 4406 else
db6eb5be 4407 s = "(%dx)";
252b5132
RH
4408 break;
4409 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4410 case sp_reg: case bp_reg: case si_reg: case di_reg:
4411 s = names16[code - ax_reg];
4412 break;
4413 case es_reg: case ss_reg: case cs_reg:
4414 case ds_reg: case fs_reg: case gs_reg:
4415 s = names_seg[code - es_reg];
4416 break;
4417 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4418 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
52b15da3
JH
4419 USED_REX (0);
4420 if (rex)
4421 s = names8rex[code - al_reg];
4422 else
4423 s = names8[code - al_reg];
252b5132
RH
4424 break;
4425 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4426 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
52b15da3
JH
4427 USED_REX (REX_MODE64);
4428 if (rex & REX_MODE64)
4429 s = names64[code - eAX_reg];
4430 else if (sizeflag & DFLAG)
252b5132
RH
4431 s = names32[code - eAX_reg];
4432 else
4433 s = names16[code - eAX_reg];
7d421014 4434 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
4435 break;
4436 default:
4437 s = INTERNAL_DISASSEMBLER_ERROR;
4438 break;
4439 }
4440 oappend (s);
4441}
4442
4443static void
26ca5450 4444OP_I (int bytemode, int sizeflag)
252b5132 4445{
52b15da3
JH
4446 bfd_signed_vma op;
4447 bfd_signed_vma mask = -1;
252b5132
RH
4448
4449 switch (bytemode)
4450 {
4451 case b_mode:
4452 FETCH_DATA (the_info, codep + 1);
52b15da3
JH
4453 op = *codep++;
4454 mask = 0xff;
4455 break;
4456 case q_mode:
cb712a9e 4457 if (address_mode == mode_64bit)
6439fc28
AM
4458 {
4459 op = get32s ();
4460 break;
4461 }
6608db57 4462 /* Fall through. */
252b5132 4463 case v_mode:
52b15da3
JH
4464 USED_REX (REX_MODE64);
4465 if (rex & REX_MODE64)
4466 op = get32s ();
4467 else if (sizeflag & DFLAG)
4468 {
4469 op = get32 ();
4470 mask = 0xffffffff;
4471 }
252b5132 4472 else
52b15da3
JH
4473 {
4474 op = get16 ();
4475 mask = 0xfffff;
4476 }
7d421014 4477 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
4478 break;
4479 case w_mode:
52b15da3 4480 mask = 0xfffff;
252b5132
RH
4481 op = get16 ();
4482 break;
9306ca4a
JB
4483 case const_1_mode:
4484 if (intel_syntax)
4485 oappend ("1");
4486 return;
252b5132
RH
4487 default:
4488 oappend (INTERNAL_DISASSEMBLER_ERROR);
4489 return;
4490 }
4491
52b15da3
JH
4492 op &= mask;
4493 scratchbuf[0] = '$';
d708bcba
AM
4494 print_operand_value (scratchbuf + 1, 1, op);
4495 oappend (scratchbuf + intel_syntax);
52b15da3
JH
4496 scratchbuf[0] = '\0';
4497}
4498
4499static void
26ca5450 4500OP_I64 (int bytemode, int sizeflag)
52b15da3
JH
4501{
4502 bfd_signed_vma op;
4503 bfd_signed_vma mask = -1;
4504
cb712a9e 4505 if (address_mode != mode_64bit)
6439fc28
AM
4506 {
4507 OP_I (bytemode, sizeflag);
4508 return;
4509 }
4510
52b15da3
JH
4511 switch (bytemode)
4512 {
4513 case b_mode:
4514 FETCH_DATA (the_info, codep + 1);
4515 op = *codep++;
4516 mask = 0xff;
4517 break;
4518 case v_mode:
4519 USED_REX (REX_MODE64);
4520 if (rex & REX_MODE64)
4521 op = get64 ();
4522 else if (sizeflag & DFLAG)
4523 {
4524 op = get32 ();
4525 mask = 0xffffffff;
4526 }
4527 else
4528 {
4529 op = get16 ();
4530 mask = 0xfffff;
4531 }
4532 used_prefixes |= (prefixes & PREFIX_DATA);
4533 break;
4534 case w_mode:
4535 mask = 0xfffff;
4536 op = get16 ();
4537 break;
4538 default:
4539 oappend (INTERNAL_DISASSEMBLER_ERROR);
4540 return;
4541 }
4542
4543 op &= mask;
4544 scratchbuf[0] = '$';
d708bcba
AM
4545 print_operand_value (scratchbuf + 1, 1, op);
4546 oappend (scratchbuf + intel_syntax);
252b5132
RH
4547 scratchbuf[0] = '\0';
4548}
4549
4550static void
26ca5450 4551OP_sI (int bytemode, int sizeflag)
252b5132 4552{
52b15da3
JH
4553 bfd_signed_vma op;
4554 bfd_signed_vma mask = -1;
252b5132
RH
4555
4556 switch (bytemode)
4557 {
4558 case b_mode:
4559 FETCH_DATA (the_info, codep + 1);
4560 op = *codep++;
4561 if ((op & 0x80) != 0)
4562 op -= 0x100;
52b15da3 4563 mask = 0xffffffff;
252b5132
RH
4564 break;
4565 case v_mode:
52b15da3
JH
4566 USED_REX (REX_MODE64);
4567 if (rex & REX_MODE64)
4568 op = get32s ();
4569 else if (sizeflag & DFLAG)
4570 {
4571 op = get32s ();
4572 mask = 0xffffffff;
4573 }
252b5132
RH
4574 else
4575 {
52b15da3 4576 mask = 0xffffffff;
6608db57 4577 op = get16 ();
252b5132
RH
4578 if ((op & 0x8000) != 0)
4579 op -= 0x10000;
4580 }
7d421014 4581 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
4582 break;
4583 case w_mode:
4584 op = get16 ();
52b15da3 4585 mask = 0xffffffff;
252b5132
RH
4586 if ((op & 0x8000) != 0)
4587 op -= 0x10000;
4588 break;
4589 default:
4590 oappend (INTERNAL_DISASSEMBLER_ERROR);
4591 return;
4592 }
52b15da3
JH
4593
4594 scratchbuf[0] = '$';
4595 print_operand_value (scratchbuf + 1, 1, op);
d708bcba 4596 oappend (scratchbuf + intel_syntax);
252b5132
RH
4597}
4598
4599static void
26ca5450 4600OP_J (int bytemode, int sizeflag)
252b5132 4601{
52b15da3 4602 bfd_vma disp;
7081ff04 4603 bfd_vma mask = -1;
252b5132
RH
4604
4605 switch (bytemode)
4606 {
4607 case b_mode:
4608 FETCH_DATA (the_info, codep + 1);
4609 disp = *codep++;
4610 if ((disp & 0x80) != 0)
4611 disp -= 0x100;
4612 break;
4613 case v_mode:
1a114b12 4614 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
52b15da3 4615 disp = get32s ();
252b5132
RH
4616 else
4617 {
4618 disp = get16 ();
6608db57 4619 /* For some reason, a data16 prefix on a jump instruction
252b5132
RH
4620 means that the pc is masked to 16 bits after the
4621 displacement is added! */
4622 mask = 0xffff;
4623 }
4624 break;
4625 default:
4626 oappend (INTERNAL_DISASSEMBLER_ERROR);
4627 return;
4628 }
4629 disp = (start_pc + codep - start_codep + disp) & mask;
52b15da3
JH
4630 set_op (disp, 0);
4631 print_operand_value (scratchbuf, 1, disp);
252b5132
RH
4632 oappend (scratchbuf);
4633}
4634
252b5132 4635static void
26ca5450 4636OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 4637{
d708bcba 4638 oappend (names_seg[reg]);
252b5132
RH
4639}
4640
4641static void
26ca5450 4642OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
252b5132
RH
4643{
4644 int seg, offset;
4645
c608c12e 4646 if (sizeflag & DFLAG)
252b5132 4647 {
c608c12e
AM
4648 offset = get32 ();
4649 seg = get16 ();
252b5132 4650 }
c608c12e
AM
4651 else
4652 {
4653 offset = get16 ();
4654 seg = get16 ();
4655 }
7d421014 4656 used_prefixes |= (prefixes & PREFIX_DATA);
d708bcba 4657 if (intel_syntax)
3f31e633 4658 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
d708bcba
AM
4659 else
4660 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
c608c12e 4661 oappend (scratchbuf);
252b5132
RH
4662}
4663
252b5132 4664static void
3f31e633 4665OP_OFF (int bytemode, int sizeflag)
252b5132 4666{
52b15da3 4667 bfd_vma off;
252b5132 4668
3f31e633
JB
4669 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4670 intel_operand_size (bytemode, sizeflag);
252b5132
RH
4671 append_seg ();
4672
cb712a9e 4673 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
252b5132
RH
4674 off = get32 ();
4675 else
4676 off = get16 ();
4677
4678 if (intel_syntax)
4679 {
4680 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
db6eb5be 4681 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
252b5132 4682 {
d708bcba 4683 oappend (names_seg[ds_reg - es_reg]);
252b5132
RH
4684 oappend (":");
4685 }
4686 }
52b15da3
JH
4687 print_operand_value (scratchbuf, 1, off);
4688 oappend (scratchbuf);
4689}
6439fc28 4690
52b15da3 4691static void
3f31e633 4692OP_OFF64 (int bytemode, int sizeflag)
52b15da3
JH
4693{
4694 bfd_vma off;
4695
cb712a9e 4696 if (address_mode != mode_64bit)
6439fc28
AM
4697 {
4698 OP_OFF (bytemode, sizeflag);
4699 return;
4700 }
4701
3f31e633
JB
4702 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4703 intel_operand_size (bytemode, sizeflag);
52b15da3
JH
4704 append_seg ();
4705
6608db57 4706 off = get64 ();
52b15da3
JH
4707
4708 if (intel_syntax)
4709 {
4710 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
db6eb5be 4711 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
52b15da3 4712 {
d708bcba 4713 oappend (names_seg[ds_reg - es_reg]);
52b15da3
JH
4714 oappend (":");
4715 }
4716 }
4717 print_operand_value (scratchbuf, 1, off);
252b5132
RH
4718 oappend (scratchbuf);
4719}
4720
4721static void
26ca5450 4722ptr_reg (int code, int sizeflag)
252b5132 4723{
2da11e11 4724 const char *s;
d708bcba 4725
1d9f512f 4726 *obufp++ = open_char;
20f0a1fc 4727 used_prefixes |= (prefixes & PREFIX_ADDR);
cb712a9e 4728 if (address_mode == mode_64bit)
c1a64871
JH
4729 {
4730 if (!(sizeflag & AFLAG))
db6eb5be 4731 s = names32[code - eAX_reg];
c1a64871 4732 else
db6eb5be 4733 s = names64[code - eAX_reg];
c1a64871 4734 }
52b15da3 4735 else if (sizeflag & AFLAG)
252b5132
RH
4736 s = names32[code - eAX_reg];
4737 else
4738 s = names16[code - eAX_reg];
4739 oappend (s);
1d9f512f
AM
4740 *obufp++ = close_char;
4741 *obufp = 0;
252b5132
RH
4742}
4743
4744static void
26ca5450 4745OP_ESreg (int code, int sizeflag)
252b5132 4746{
9306ca4a 4747 if (intel_syntax)
3f31e633 4748 intel_operand_size (codep[-1] & 1 ? v_mode : b_mode, sizeflag);
d708bcba 4749 oappend ("%es:" + intel_syntax);
252b5132
RH
4750 ptr_reg (code, sizeflag);
4751}
4752
4753static void
26ca5450 4754OP_DSreg (int code, int sizeflag)
252b5132 4755{
9306ca4a 4756 if (intel_syntax)
3f31e633
JB
4757 intel_operand_size (codep[-1] != 0xd7 && (codep[-1] & 1)
4758 ? v_mode
4759 : b_mode,
4760 sizeflag);
252b5132
RH
4761 if ((prefixes
4762 & (PREFIX_CS
4763 | PREFIX_DS
4764 | PREFIX_SS
4765 | PREFIX_ES
4766 | PREFIX_FS
4767 | PREFIX_GS)) == 0)
4768 prefixes |= PREFIX_DS;
6608db57 4769 append_seg ();
252b5132
RH
4770 ptr_reg (code, sizeflag);
4771}
4772
252b5132 4773static void
26ca5450 4774OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 4775{
52b15da3 4776 int add = 0;
52b15da3 4777 if (rex & REX_EXTX)
c4a530c5
JB
4778 {
4779 USED_REX (REX_EXTX);
4780 add = 8;
4781 }
cb712a9e 4782 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
c4a530c5
JB
4783 {
4784 used_prefixes |= PREFIX_LOCK;
4785 add = 8;
4786 }
d708bcba
AM
4787 sprintf (scratchbuf, "%%cr%d", reg + add);
4788 oappend (scratchbuf + intel_syntax);
252b5132
RH
4789}
4790
252b5132 4791static void
26ca5450 4792OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 4793{
52b15da3
JH
4794 int add = 0;
4795 USED_REX (REX_EXTX);
4796 if (rex & REX_EXTX)
4797 add = 8;
d708bcba 4798 if (intel_syntax)
6608db57 4799 sprintf (scratchbuf, "db%d", reg + add);
d708bcba 4800 else
6608db57 4801 sprintf (scratchbuf, "%%db%d", reg + add);
252b5132
RH
4802 oappend (scratchbuf);
4803}
4804
252b5132 4805static void
26ca5450 4806OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 4807{
252b5132 4808 sprintf (scratchbuf, "%%tr%d", reg);
d708bcba 4809 oappend (scratchbuf + intel_syntax);
252b5132
RH
4810}
4811
4812static void
26ca5450 4813OP_Rd (int bytemode, int sizeflag)
252b5132 4814{
2da11e11
AM
4815 if (mod == 3)
4816 OP_E (bytemode, sizeflag);
4817 else
6608db57 4818 BadOp ();
252b5132
RH
4819}
4820
4821static void
26ca5450 4822OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 4823{
041bd2e0
JH
4824 used_prefixes |= (prefixes & PREFIX_DATA);
4825 if (prefixes & PREFIX_DATA)
20f0a1fc
NC
4826 {
4827 int add = 0;
4828 USED_REX (REX_EXTX);
4829 if (rex & REX_EXTX)
4830 add = 8;
4831 sprintf (scratchbuf, "%%xmm%d", reg + add);
4832 }
041bd2e0 4833 else
20f0a1fc 4834 sprintf (scratchbuf, "%%mm%d", reg);
d708bcba 4835 oappend (scratchbuf + intel_syntax);
252b5132
RH
4836}
4837
c608c12e 4838static void
26ca5450 4839OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
c608c12e 4840{
041bd2e0
JH
4841 int add = 0;
4842 USED_REX (REX_EXTX);
4843 if (rex & REX_EXTX)
4844 add = 8;
4845 sprintf (scratchbuf, "%%xmm%d", reg + add);
d708bcba 4846 oappend (scratchbuf + intel_syntax);
c608c12e
AM
4847}
4848
252b5132 4849static void
26ca5450 4850OP_EM (int bytemode, int sizeflag)
252b5132
RH
4851{
4852 if (mod != 3)
4853 {
9306ca4a
JB
4854 if (intel_syntax && bytemode == v_mode)
4855 {
4856 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
4857 used_prefixes |= (prefixes & PREFIX_DATA);
4858 }
252b5132
RH
4859 OP_E (bytemode, sizeflag);
4860 return;
4861 }
4862
6608db57 4863 /* Skip mod/rm byte. */
4bba6815 4864 MODRM_CHECK;
252b5132 4865 codep++;
041bd2e0
JH
4866 used_prefixes |= (prefixes & PREFIX_DATA);
4867 if (prefixes & PREFIX_DATA)
20f0a1fc
NC
4868 {
4869 int add = 0;
4870
4871 USED_REX (REX_EXTZ);
4872 if (rex & REX_EXTZ)
4873 add = 8;
4874 sprintf (scratchbuf, "%%xmm%d", rm + add);
4875 }
041bd2e0 4876 else
20f0a1fc 4877 sprintf (scratchbuf, "%%mm%d", rm);
d708bcba 4878 oappend (scratchbuf + intel_syntax);
252b5132
RH
4879}
4880
4d9567e0
MM
4881/* cvt* are the only instructions in sse2 which have
4882 both SSE and MMX operands and also have 0x66 prefix
4883 in their opcode. 0x66 was originally used to differentiate
4884 between SSE and MMX instruction(operands). So we have to handle the
4885 cvt* separately using OP_EMC and OP_MXC */
4886static void
4887OP_EMC (int bytemode, int sizeflag)
4888{
4889 if (mod != 3)
4890 {
4891 if (intel_syntax && bytemode == v_mode)
4892 {
4893 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
4894 used_prefixes |= (prefixes & PREFIX_DATA);
4895 }
4896 OP_E (bytemode, sizeflag);
4897 return;
4898 }
4899
4900 /* Skip mod/rm byte. */
4901 MODRM_CHECK;
4902 codep++;
4903 used_prefixes |= (prefixes & PREFIX_DATA);
4904 sprintf (scratchbuf, "%%mm%d", rm);
4905 oappend (scratchbuf + intel_syntax);
4906}
4907
4908static void
4909OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4910{
4911 used_prefixes |= (prefixes & PREFIX_DATA);
4912 sprintf (scratchbuf, "%%mm%d", reg);
4913 oappend (scratchbuf + intel_syntax);
4914}
4915
c608c12e 4916static void
26ca5450 4917OP_EX (int bytemode, int sizeflag)
c608c12e 4918{
041bd2e0 4919 int add = 0;
c608c12e
AM
4920 if (mod != 3)
4921 {
9306ca4a
JB
4922 if (intel_syntax && bytemode == v_mode)
4923 {
4924 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
4925 {
4926 case 0: bytemode = x_mode; break;
4927 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
4928 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
4929 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
4930 default: bytemode = 0; break;
4931 }
4932 }
c608c12e
AM
4933 OP_E (bytemode, sizeflag);
4934 return;
4935 }
041bd2e0
JH
4936 USED_REX (REX_EXTZ);
4937 if (rex & REX_EXTZ)
4938 add = 8;
c608c12e 4939
6608db57 4940 /* Skip mod/rm byte. */
4bba6815 4941 MODRM_CHECK;
c608c12e 4942 codep++;
041bd2e0 4943 sprintf (scratchbuf, "%%xmm%d", rm + add);
d708bcba 4944 oappend (scratchbuf + intel_syntax);
c608c12e
AM
4945}
4946
252b5132 4947static void
26ca5450 4948OP_MS (int bytemode, int sizeflag)
252b5132 4949{
2da11e11
AM
4950 if (mod == 3)
4951 OP_EM (bytemode, sizeflag);
4952 else
6608db57 4953 BadOp ();
252b5132
RH
4954}
4955
992aaec9 4956static void
26ca5450 4957OP_XS (int bytemode, int sizeflag)
992aaec9
AM
4958{
4959 if (mod == 3)
4960 OP_EX (bytemode, sizeflag);
4961 else
6608db57 4962 BadOp ();
992aaec9
AM
4963}
4964
cc0ec051
AM
4965static void
4966OP_M (int bytemode, int sizeflag)
4967{
4968 if (mod == 3)
4969 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4970 else
4971 OP_E (bytemode, sizeflag);
4972}
4973
4974static void
4975OP_0f07 (int bytemode, int sizeflag)
4976{
4977 if (mod != 3 || rm != 0)
4978 BadOp ();
4979 else
4980 OP_E (bytemode, sizeflag);
4981}
4982
4983static void
4984OP_0fae (int bytemode, int sizeflag)
4985{
4986 if (mod == 3)
4987 {
4988 if (reg == 7)
4989 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4990
4991 if (reg < 5 || rm != 0)
4992 {
4993 BadOp (); /* bad sfence, mfence, or lfence */
4994 return;
4995 }
4996 }
4997 else if (reg != 7)
4998 {
4999 BadOp (); /* bad clflush */
5000 return;
5001 }
5002
5003 OP_E (bytemode, sizeflag);
5004}
5005
46e883c5
L
5006/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5007 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5008 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5009 */
5010
cc0ec051 5011static void
46e883c5 5012NOP_Fixup1 (int bytemode, int sizeflag)
cc0ec051 5013{
cc0ec051
AM
5014 if (prefixes == PREFIX_REPZ)
5015 strcpy (obuf, "pause");
46e883c5
L
5016 else if (prefixes == PREFIX_DATA
5017 || ((rex & REX_MODE64) && rex != 0x48))
5018 OP_REG (bytemode, sizeflag);
5019 else
5020 strcpy (obuf, "nop");
5021}
5022
5023static void
5024NOP_Fixup2 (int bytemode, int sizeflag)
5025{
5026 if (prefixes == PREFIX_DATA
5027 || ((rex & REX_MODE64) && rex != 0x48))
5028 OP_IMREG (bytemode, sizeflag);
cc0ec051
AM
5029}
5030
84037f8c 5031static const char *const Suffix3DNow[] = {
252b5132
RH
5032/* 00 */ NULL, NULL, NULL, NULL,
5033/* 04 */ NULL, NULL, NULL, NULL,
5034/* 08 */ NULL, NULL, NULL, NULL,
9e525108 5035/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
252b5132
RH
5036/* 10 */ NULL, NULL, NULL, NULL,
5037/* 14 */ NULL, NULL, NULL, NULL,
5038/* 18 */ NULL, NULL, NULL, NULL,
9e525108 5039/* 1C */ "pf2iw", "pf2id", NULL, NULL,
252b5132
RH
5040/* 20 */ NULL, NULL, NULL, NULL,
5041/* 24 */ NULL, NULL, NULL, NULL,
5042/* 28 */ NULL, NULL, NULL, NULL,
5043/* 2C */ NULL, NULL, NULL, NULL,
5044/* 30 */ NULL, NULL, NULL, NULL,
5045/* 34 */ NULL, NULL, NULL, NULL,
5046/* 38 */ NULL, NULL, NULL, NULL,
5047/* 3C */ NULL, NULL, NULL, NULL,
5048/* 40 */ NULL, NULL, NULL, NULL,
5049/* 44 */ NULL, NULL, NULL, NULL,
5050/* 48 */ NULL, NULL, NULL, NULL,
5051/* 4C */ NULL, NULL, NULL, NULL,
5052/* 50 */ NULL, NULL, NULL, NULL,
5053/* 54 */ NULL, NULL, NULL, NULL,
5054/* 58 */ NULL, NULL, NULL, NULL,
5055/* 5C */ NULL, NULL, NULL, NULL,
5056/* 60 */ NULL, NULL, NULL, NULL,
5057/* 64 */ NULL, NULL, NULL, NULL,
5058/* 68 */ NULL, NULL, NULL, NULL,
5059/* 6C */ NULL, NULL, NULL, NULL,
5060/* 70 */ NULL, NULL, NULL, NULL,
5061/* 74 */ NULL, NULL, NULL, NULL,
5062/* 78 */ NULL, NULL, NULL, NULL,
5063/* 7C */ NULL, NULL, NULL, NULL,
5064/* 80 */ NULL, NULL, NULL, NULL,
5065/* 84 */ NULL, NULL, NULL, NULL,
9e525108
AM
5066/* 88 */ NULL, NULL, "pfnacc", NULL,
5067/* 8C */ NULL, NULL, "pfpnacc", NULL,
252b5132
RH
5068/* 90 */ "pfcmpge", NULL, NULL, NULL,
5069/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
5070/* 98 */ NULL, NULL, "pfsub", NULL,
5071/* 9C */ NULL, NULL, "pfadd", NULL,
5072/* A0 */ "pfcmpgt", NULL, NULL, NULL,
5073/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
5074/* A8 */ NULL, NULL, "pfsubr", NULL,
5075/* AC */ NULL, NULL, "pfacc", NULL,
5076/* B0 */ "pfcmpeq", NULL, NULL, NULL,
5077/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
9e525108 5078/* B8 */ NULL, NULL, NULL, "pswapd",
252b5132
RH
5079/* BC */ NULL, NULL, NULL, "pavgusb",
5080/* C0 */ NULL, NULL, NULL, NULL,
5081/* C4 */ NULL, NULL, NULL, NULL,
5082/* C8 */ NULL, NULL, NULL, NULL,
5083/* CC */ NULL, NULL, NULL, NULL,
5084/* D0 */ NULL, NULL, NULL, NULL,
5085/* D4 */ NULL, NULL, NULL, NULL,
5086/* D8 */ NULL, NULL, NULL, NULL,
5087/* DC */ NULL, NULL, NULL, NULL,
5088/* E0 */ NULL, NULL, NULL, NULL,
5089/* E4 */ NULL, NULL, NULL, NULL,
5090/* E8 */ NULL, NULL, NULL, NULL,
5091/* EC */ NULL, NULL, NULL, NULL,
5092/* F0 */ NULL, NULL, NULL, NULL,
5093/* F4 */ NULL, NULL, NULL, NULL,
5094/* F8 */ NULL, NULL, NULL, NULL,
5095/* FC */ NULL, NULL, NULL, NULL,
5096};
5097
5098static void
26ca5450 5099OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132
RH
5100{
5101 const char *mnemonic;
5102
5103 FETCH_DATA (the_info, codep + 1);
5104 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5105 place where an 8-bit immediate would normally go. ie. the last
5106 byte of the instruction. */
6608db57 5107 obufp = obuf + strlen (obuf);
c608c12e 5108 mnemonic = Suffix3DNow[*codep++ & 0xff];
252b5132 5109 if (mnemonic)
2da11e11 5110 oappend (mnemonic);
252b5132
RH
5111 else
5112 {
5113 /* Since a variable sized modrm/sib chunk is between the start
5114 of the opcode (0x0f0f) and the opcode suffix, we need to do
5115 all the modrm processing first, and don't know until now that
5116 we have a bad opcode. This necessitates some cleaning up. */
2da11e11
AM
5117 op1out[0] = '\0';
5118 op2out[0] = '\0';
6608db57 5119 BadOp ();
252b5132
RH
5120 }
5121}
c608c12e 5122
6608db57 5123static const char *simd_cmp_op[] = {
c608c12e
AM
5124 "eq",
5125 "lt",
5126 "le",
5127 "unord",
5128 "neq",
5129 "nlt",
5130 "nle",
5131 "ord"
5132};
5133
5134static void
26ca5450 5135OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
c608c12e
AM
5136{
5137 unsigned int cmp_type;
5138
5139 FETCH_DATA (the_info, codep + 1);
6608db57 5140 obufp = obuf + strlen (obuf);
c608c12e
AM
5141 cmp_type = *codep++ & 0xff;
5142 if (cmp_type < 8)
5143 {
041bd2e0
JH
5144 char suffix1 = 'p', suffix2 = 's';
5145 used_prefixes |= (prefixes & PREFIX_REPZ);
5146 if (prefixes & PREFIX_REPZ)
5147 suffix1 = 's';
5148 else
5149 {
5150 used_prefixes |= (prefixes & PREFIX_DATA);
5151 if (prefixes & PREFIX_DATA)
5152 suffix2 = 'd';
5153 else
5154 {
5155 used_prefixes |= (prefixes & PREFIX_REPNZ);
5156 if (prefixes & PREFIX_REPNZ)
5157 suffix1 = 's', suffix2 = 'd';
5158 }
5159 }
5160 sprintf (scratchbuf, "cmp%s%c%c",
5161 simd_cmp_op[cmp_type], suffix1, suffix2);
7d421014 5162 used_prefixes |= (prefixes & PREFIX_REPZ);
2da11e11 5163 oappend (scratchbuf);
c608c12e
AM
5164 }
5165 else
5166 {
5167 /* We have a bad extension byte. Clean up. */
2da11e11
AM
5168 op1out[0] = '\0';
5169 op2out[0] = '\0';
6608db57 5170 BadOp ();
c608c12e
AM
5171 }
5172}
5173
5174static void
26ca5450 5175SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
c608c12e
AM
5176{
5177 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5178 forms of these instructions. */
5179 if (mod == 3)
5180 {
6608db57
KH
5181 char *p = obuf + strlen (obuf);
5182 *(p + 1) = '\0';
5183 *p = *(p - 1);
5184 *(p - 1) = *(p - 2);
5185 *(p - 2) = *(p - 3);
5186 *(p - 3) = extrachar;
c608c12e
AM
5187 }
5188}
2da11e11 5189
ca164297 5190static void
4fd61dcb 5191PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
ca164297 5192{
1d9f512f 5193 if (mod == 3 && reg == 1 && rm <= 1)
ca164297 5194 {
ca164297 5195 /* Override "sidt". */
cb712a9e
L
5196 size_t olen = strlen (obuf);
5197 char *p = obuf + olen - 4;
5198 const char **names = (address_mode == mode_64bit
5199 ? names64 : names32);
1d9f512f 5200
22cbf2e7 5201 /* We might have a suffix when disassembling with -Msuffix. */
1d9f512f
AM
5202 if (*p == 'i')
5203 --p;
5204
cb712a9e
L
5205 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5206 if (!intel_syntax
5207 && (prefixes & PREFIX_ADDR)
5208 && olen >= (4 + 7)
5209 && *(p - 1) == ' '
5210 && strncmp (p - 7, "addr", 4) == 0
5211 && (strncmp (p - 3, "16", 2) == 0
5212 || strncmp (p - 3, "32", 2) == 0))
5213 p -= 7;
5214
ca164297
L
5215 if (rm)
5216 {
5217 /* mwait %eax,%ecx */
1d9f512f 5218 strcpy (p, "mwait");
6128c599 5219 if (!intel_syntax)
cb712a9e 5220 strcpy (op1out, names[0]);
ca164297
L
5221 }
5222 else
5223 {
5224 /* monitor %eax,%ecx,%edx" */
1d9f512f 5225 strcpy (p, "monitor");
6128c599
JB
5226 if (!intel_syntax)
5227 {
cb712a9e
L
5228 const char **op1_names;
5229 if (!(prefixes & PREFIX_ADDR))
5230 op1_names = (address_mode == mode_16bit
5231 ? names16 : names);
6128c599
JB
5232 else
5233 {
cb712a9e
L
5234 op1_names = (address_mode != mode_32bit
5235 ? names32 : names16);
6128c599
JB
5236 used_prefixes |= PREFIX_ADDR;
5237 }
cb712a9e
L
5238 strcpy (op1out, op1_names[0]);
5239 strcpy (op3out, names[2]);
6128c599
JB
5240 }
5241 }
5242 if (!intel_syntax)
5243 {
cb712a9e 5244 strcpy (op2out, names[1]);
6128c599 5245 two_source_ops = 1;
ca164297
L
5246 }
5247
5248 codep++;
5249 }
5250 else
30123838
JB
5251 OP_M (0, sizeflag);
5252}
5253
5254static void
5255SVME_Fixup (int bytemode, int sizeflag)
5256{
5257 const char *alt;
5258 char *p;
5259
5260 switch (*codep)
5261 {
5262 case 0xd8:
5263 alt = "vmrun";
5264 break;
5265 case 0xd9:
5266 alt = "vmmcall";
5267 break;
5268 case 0xda:
5269 alt = "vmload";
5270 break;
5271 case 0xdb:
5272 alt = "vmsave";
5273 break;
5274 case 0xdc:
5275 alt = "stgi";
5276 break;
5277 case 0xdd:
5278 alt = "clgi";
5279 break;
5280 case 0xde:
5281 alt = "skinit";
5282 break;
5283 case 0xdf:
5284 alt = "invlpga";
5285 break;
5286 default:
5287 OP_M (bytemode, sizeflag);
5288 return;
5289 }
5290 /* Override "lidt". */
5291 p = obuf + strlen (obuf) - 4;
5292 /* We might have a suffix. */
5293 if (*p == 'i')
5294 --p;
5295 strcpy (p, alt);
5296 if (!(prefixes & PREFIX_ADDR))
5297 {
5298 ++codep;
5299 return;
5300 }
5301 used_prefixes |= PREFIX_ADDR;
5302 switch (*codep++)
5303 {
5304 case 0xdf:
5305 strcpy (op2out, names32[1]);
5306 two_source_ops = 1;
5307 /* Fall through. */
5308 case 0xd8:
5309 case 0xda:
5310 case 0xdb:
5311 *obufp++ = open_char;
cb712a9e 5312 if (address_mode == mode_64bit || (sizeflag & AFLAG))
30123838
JB
5313 alt = names32[0];
5314 else
5315 alt = names16[0];
5316 strcpy (obufp, alt);
5317 obufp += strlen (alt);
5318 *obufp++ = close_char;
5319 *obufp = '\0';
5320 break;
5321 }
ca164297
L
5322}
5323
4fd61dcb
JJ
5324static void
5325INVLPG_Fixup (int bytemode, int sizeflag)
5326{
373ff435 5327 const char *alt;
4fd61dcb 5328
373ff435
JB
5329 switch (*codep)
5330 {
5331 case 0xf8:
5332 alt = "swapgs";
5333 break;
5334 case 0xf9:
5335 alt = "rdtscp";
5336 break;
5337 default:
30123838 5338 OP_M (bytemode, sizeflag);
373ff435 5339 return;
4fd61dcb 5340 }
373ff435
JB
5341 /* Override "invlpg". */
5342 strcpy (obuf + strlen (obuf) - 6, alt);
5343 codep++;
4fd61dcb
JJ
5344}
5345
6608db57
KH
5346static void
5347BadOp (void)
2da11e11 5348{
6608db57
KH
5349 /* Throw away prefixes and 1st. opcode byte. */
5350 codep = insn_codep + 1;
2da11e11
AM
5351 oappend ("(bad)");
5352}
4cc91dba
L
5353
5354static void
5355SEG_Fixup (int extrachar, int sizeflag)
5356{
5357 if (mod == 3)
5358 {
5359 /* We need to add a proper suffix with
5360
5361 movw %ds,%ax
5362 movl %ds,%eax
5363 movq %ds,%rax
5364 movw %ax,%ds
5365 movl %eax,%ds
5366 movq %rax,%ds
5367 */
5368 const char *suffix;
5369
5370 if (prefixes & PREFIX_DATA)
5371 suffix = "w";
5372 else
5373 {
5374 USED_REX (REX_MODE64);
5375 if (rex & REX_MODE64)
5376 suffix = "q";
5377 else
5378 suffix = "l";
5379 }
5380 strcat (obuf, suffix);
5381 }
5382 else
5383 {
5384 /* We need to fix the suffix for
5385
5386 movw %ds,(%eax)
5387 movw %ds,(%rax)
5388 movw (%eax),%ds
5389 movw (%rax),%ds
5390
5391 Override "mov[l|q]". */
5392 char *p = obuf + strlen (obuf) - 1;
5393
5394 /* We might not have a suffix. */
5395 if (*p == 'v')
5396 ++p;
5397 *p = 'w';
5398 }
5399
5400 OP_E (extrachar, sizeflag);
5401}
90700ea2
L
5402
5403static void
5404VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5405{
5406 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
5407 {
5408 /* Override "sgdt". */
5409 char *p = obuf + strlen (obuf) - 4;
5410
22cbf2e7
L
5411 /* We might have a suffix when disassembling with -Msuffix. */
5412 if (*p == 'g')
90700ea2
L
5413 --p;
5414
5415 switch (rm)
5416 {
5417 case 1:
5418 strcpy (p, "vmcall");
5419 break;
5420 case 2:
5421 strcpy (p, "vmlaunch");
5422 break;
5423 case 3:
5424 strcpy (p, "vmresume");
5425 break;
5426 case 4:
5427 strcpy (p, "vmxoff");
5428 break;
5429 }
5430
5431 codep++;
5432 }
5433 else
5434 OP_E (0, sizeflag);
5435}
5436
5437static void
5438OP_VMX (int bytemode, int sizeflag)
5439{
5440 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
5441 if (prefixes & PREFIX_DATA)
5442 strcpy (obuf, "vmclear");
5443 else if (prefixes & PREFIX_REPZ)
5444 strcpy (obuf, "vmxon");
5445 else
5446 strcpy (obuf, "vmptrld");
5447 OP_E (bytemode, sizeflag);
5448}
35c52694
L
5449
5450static void
5451REP_Fixup (int bytemode, int sizeflag)
5452{
5453 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5454 lods and stos. */
5455 size_t ilen = 0;
5456
5457 if (prefixes & PREFIX_REPZ)
5458 switch (*insn_codep)
5459 {
5460 case 0x6e: /* outsb */
5461 case 0x6f: /* outsw/outsl */
5462 case 0xa4: /* movsb */
5463 case 0xa5: /* movsw/movsl/movsq */
5464 if (!intel_syntax)
5465 ilen = 5;
5466 else
5467 ilen = 4;
5468 break;
5469 case 0xaa: /* stosb */
5470 case 0xab: /* stosw/stosl/stosq */
5471 case 0xac: /* lodsb */
5472 case 0xad: /* lodsw/lodsl/lodsq */
5473 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5474 ilen = 5;
5475 else
5476 ilen = 4;
5477 break;
5478 case 0x6c: /* insb */
5479 case 0x6d: /* insl/insw */
5480 if (!intel_syntax)
5481 ilen = 4;
5482 else
5483 ilen = 3;
5484 break;
5485 default:
5486 abort ();
5487 break;
5488 }
5489
5490 if (ilen != 0)
5491 {
5492 size_t olen;
5493 char *p;
5494
5495 olen = strlen (obuf);
5496 p = obuf + olen - ilen - 1 - 4;
5497 /* Handle "repz [addr16|addr32]". */
5498 if ((prefixes & PREFIX_ADDR))
5499 p -= 1 + 6;
5500
5501 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
5502 }
5503
5504 switch (bytemode)
5505 {
5506 case al_reg:
5507 case eAX_reg:
5508 case indir_dx_reg:
5509 OP_IMREG (bytemode, sizeflag);
5510 break;
5511 case eDI_reg:
5512 OP_ESreg (bytemode, sizeflag);
5513 break;
5514 case eSI_reg:
5515 OP_DSreg (bytemode, sizeflag);
5516 break;
5517 default:
5518 abort ();
5519 break;
5520 }
5521}