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