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