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