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