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