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