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