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