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