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