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