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