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