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