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