]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/i386-dis.c
Update BFD_VERSION_DATE to 20040721.
[thirdparty/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 */
1d9f512f 315#define x_mode 6 /* 80 bit float operand */
52b15da3 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];
1d9f512f 1884static int two_source_ops;
7081ff04
AJ
1885static bfd_vma op_address[3];
1886static bfd_vma op_riprel[3];
52b15da3 1887static bfd_vma start_pc;
252b5132
RH
1888\f
1889/*
1890 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1891 * (see topic "Redundant prefixes" in the "Differences from 8086"
1892 * section of the "Virtual 8086 Mode" chapter.)
1893 * 'pc' should be the address of this instruction, it will
1894 * be used to print the target address if this is a relative jump or call
1895 * The function returns the length of this instruction in bytes.
1896 */
1897
252b5132
RH
1898static char intel_syntax;
1899static char open_char;
1900static char close_char;
1901static char separator_char;
1902static char scale_char;
1903
e396998b
AM
1904/* Here for backwards compatibility. When gdb stops using
1905 print_insn_i386_att and print_insn_i386_intel these functions can
1906 disappear, and print_insn_i386 be merged into print_insn. */
252b5132 1907int
26ca5450 1908print_insn_i386_att (bfd_vma pc, disassemble_info *info)
252b5132
RH
1909{
1910 intel_syntax = 0;
e396998b
AM
1911
1912 return print_insn (pc, info);
252b5132
RH
1913}
1914
1915int
26ca5450 1916print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
252b5132
RH
1917{
1918 intel_syntax = 1;
e396998b
AM
1919
1920 return print_insn (pc, info);
252b5132
RH
1921}
1922
e396998b 1923int
26ca5450 1924print_insn_i386 (bfd_vma pc, disassemble_info *info)
e396998b
AM
1925{
1926 intel_syntax = -1;
1927
1928 return print_insn (pc, info);
1929}
1930
1931static int
26ca5450 1932print_insn (bfd_vma pc, disassemble_info *info)
252b5132 1933{
2da11e11 1934 const struct dis386 *dp;
252b5132 1935 int i;
252b5132
RH
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|}",
1d9f512f 2367 "fisttp{ll||ll|}",
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 2390 "fbstp",
1d9f512f
AM
2391 "fistp{ll||ll|}",
2392};
2393
2394static const unsigned char float_mem_mode[] = {
2395 /* d8 */
2396 d_mode,
2397 d_mode,
2398 d_mode,
2399 d_mode,
2400 d_mode,
2401 d_mode,
2402 d_mode,
2403 d_mode,
2404 /* d9 */
2405 d_mode,
2406 0,
2407 d_mode,
2408 d_mode,
2409 0,
2410 w_mode,
2411 0,
2412 w_mode,
2413 /* da */
2414 d_mode,
2415 d_mode,
2416 d_mode,
2417 d_mode,
2418 d_mode,
2419 d_mode,
2420 d_mode,
2421 d_mode,
2422 /* db */
2423 d_mode,
2424 d_mode,
2425 d_mode,
2426 d_mode,
2427 0,
2428 x_mode,
2429 0,
2430 x_mode,
2431 /* dc */
2432 q_mode,
2433 q_mode,
2434 q_mode,
2435 q_mode,
2436 q_mode,
2437 q_mode,
2438 q_mode,
2439 q_mode,
2440 /* dd */
2441 q_mode,
2442 q_mode,
2443 q_mode,
2444 q_mode,
2445 0,
2446 0,
2447 0,
2448 w_mode,
2449 /* de */
2450 w_mode,
2451 w_mode,
2452 w_mode,
2453 w_mode,
2454 w_mode,
2455 w_mode,
2456 w_mode,
2457 w_mode,
2458 /* df */
2459 w_mode,
2460 w_mode,
2461 w_mode,
2462 w_mode,
2463 x_mode,
2464 q_mode,
2465 x_mode,
2466 q_mode
252b5132
RH
2467};
2468
2469#define ST OP_ST, 0
2470#define STi OP_STi, 0
2471
57d91c3c
ILT
2472#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2473#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2474#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2475#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2476#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2477#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2478#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2479#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2480#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
252b5132 2481
2da11e11 2482static const struct dis386 float_reg[][8] = {
252b5132
RH
2483 /* d8 */
2484 {
57d91c3c
ILT
2485 { "fadd", ST, STi, XX },
2486 { "fmul", ST, STi, XX },
2487 { "fcom", STi, XX, XX },
2488 { "fcomp", STi, XX, XX },
2489 { "fsub", ST, STi, XX },
2490 { "fsubr", ST, STi, XX },
2491 { "fdiv", ST, STi, XX },
2492 { "fdivr", ST, STi, XX },
252b5132
RH
2493 },
2494 /* d9 */
2495 {
57d91c3c
ILT
2496 { "fld", STi, XX, XX },
2497 { "fxch", STi, XX, XX },
252b5132 2498 { FGRPd9_2 },
57d91c3c 2499 { "(bad)", XX, XX, XX },
252b5132
RH
2500 { FGRPd9_4 },
2501 { FGRPd9_5 },
2502 { FGRPd9_6 },
2503 { FGRPd9_7 },
2504 },
2505 /* da */
2506 {
57d91c3c
ILT
2507 { "fcmovb", ST, STi, XX },
2508 { "fcmove", ST, STi, XX },
2509 { "fcmovbe",ST, STi, XX },
2510 { "fcmovu", ST, STi, XX },
2511 { "(bad)", XX, XX, XX },
252b5132 2512 { FGRPda_5 },
57d91c3c
ILT
2513 { "(bad)", XX, XX, XX },
2514 { "(bad)", XX, XX, XX },
252b5132
RH
2515 },
2516 /* db */
2517 {
57d91c3c
ILT
2518 { "fcmovnb",ST, STi, XX },
2519 { "fcmovne",ST, STi, XX },
2520 { "fcmovnbe",ST, STi, XX },
2521 { "fcmovnu",ST, STi, XX },
252b5132 2522 { FGRPdb_4 },
57d91c3c
ILT
2523 { "fucomi", ST, STi, XX },
2524 { "fcomi", ST, STi, XX },
2525 { "(bad)", XX, XX, XX },
252b5132
RH
2526 },
2527 /* dc */
2528 {
57d91c3c
ILT
2529 { "fadd", STi, ST, XX },
2530 { "fmul", STi, ST, XX },
2531 { "(bad)", XX, XX, XX },
2532 { "(bad)", XX, XX, XX },
252b5132 2533#if UNIXWARE_COMPAT
57d91c3c
ILT
2534 { "fsub", STi, ST, XX },
2535 { "fsubr", STi, ST, XX },
2536 { "fdiv", STi, ST, XX },
2537 { "fdivr", STi, ST, XX },
252b5132 2538#else
57d91c3c
ILT
2539 { "fsubr", STi, ST, XX },
2540 { "fsub", STi, ST, XX },
2541 { "fdivr", STi, ST, XX },
2542 { "fdiv", STi, ST, XX },
252b5132
RH
2543#endif
2544 },
2545 /* dd */
2546 {
57d91c3c
ILT
2547 { "ffree", STi, XX, XX },
2548 { "(bad)", XX, XX, XX },
2549 { "fst", STi, XX, XX },
2550 { "fstp", STi, XX, XX },
2551 { "fucom", STi, XX, XX },
2552 { "fucomp", STi, XX, XX },
2553 { "(bad)", XX, XX, XX },
2554 { "(bad)", XX, XX, XX },
252b5132
RH
2555 },
2556 /* de */
2557 {
57d91c3c
ILT
2558 { "faddp", STi, ST, XX },
2559 { "fmulp", STi, ST, XX },
2560 { "(bad)", XX, XX, XX },
252b5132
RH
2561 { FGRPde_3 },
2562#if UNIXWARE_COMPAT
57d91c3c
ILT
2563 { "fsubp", STi, ST, XX },
2564 { "fsubrp", STi, ST, XX },
2565 { "fdivp", STi, ST, XX },
2566 { "fdivrp", STi, ST, XX },
252b5132 2567#else
57d91c3c
ILT
2568 { "fsubrp", STi, ST, XX },
2569 { "fsubp", STi, ST, XX },
2570 { "fdivrp", STi, ST, XX },
2571 { "fdivp", STi, ST, XX },
252b5132
RH
2572#endif
2573 },
2574 /* df */
2575 {
c2419411 2576 { "ffreep", STi, XX, XX },
57d91c3c
ILT
2577 { "(bad)", XX, XX, XX },
2578 { "(bad)", XX, XX, XX },
2579 { "(bad)", XX, XX, XX },
252b5132 2580 { FGRPdf_4 },
57d91c3c
ILT
2581 { "fucomip",ST, STi, XX },
2582 { "fcomip", ST, STi, XX },
2583 { "(bad)", XX, XX, XX },
252b5132
RH
2584 },
2585};
2586
252b5132
RH
2587static char *fgrps[][8] = {
2588 /* d9_2 0 */
2589 {
2590 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2591 },
2592
2593 /* d9_4 1 */
2594 {
2595 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2596 },
2597
2598 /* d9_5 2 */
2599 {
2600 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2601 },
2602
2603 /* d9_6 3 */
2604 {
2605 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2606 },
2607
2608 /* d9_7 4 */
2609 {
2610 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2611 },
2612
2613 /* da_5 5 */
2614 {
2615 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2616 },
2617
2618 /* db_4 6 */
2619 {
2620 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2621 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2622 },
2623
2624 /* de_3 7 */
2625 {
2626 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2627 },
2628
2629 /* df_4 8 */
2630 {
2631 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2632 },
2633};
2634
2635static void
26ca5450 2636dofloat (int sizeflag)
252b5132 2637{
2da11e11 2638 const struct dis386 *dp;
252b5132
RH
2639 unsigned char floatop;
2640
2641 floatop = codep[-1];
2642
2643 if (mod != 3)
2644 {
1d9f512f
AM
2645 int fp_indx = (floatop - 0xd8) * 8 + reg;
2646
2647 putop (float_mem[fp_indx], sizeflag);
252b5132 2648 obufp = op1out;
1d9f512f 2649 OP_E (float_mem_mode[fp_indx], sizeflag);
252b5132
RH
2650 return;
2651 }
6608db57 2652 /* Skip mod/rm byte. */
4bba6815 2653 MODRM_CHECK;
252b5132
RH
2654 codep++;
2655
2656 dp = &float_reg[floatop - 0xd8][reg];
2657 if (dp->name == NULL)
2658 {
2659 putop (fgrps[dp->bytemode1][rm], sizeflag);
2660
6608db57 2661 /* Instruction fnstsw is only one with strange arg. */
252b5132
RH
2662 if (floatop == 0xdf && codep[-1] == 0xe0)
2663 strcpy (op1out, names16[0]);
2664 }
2665 else
2666 {
2667 putop (dp->name, sizeflag);
2668
2669 obufp = op1out;
2670 if (dp->op1)
6608db57 2671 (*dp->op1) (dp->bytemode1, sizeflag);
252b5132
RH
2672 obufp = op2out;
2673 if (dp->op2)
6608db57 2674 (*dp->op2) (dp->bytemode2, sizeflag);
252b5132
RH
2675 }
2676}
2677
252b5132 2678static void
26ca5450 2679OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132
RH
2680{
2681 oappend ("%st");
2682}
2683
252b5132 2684static void
26ca5450 2685OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132
RH
2686{
2687 sprintf (scratchbuf, "%%st(%d)", rm);
d708bcba 2688 oappend (scratchbuf + intel_syntax);
252b5132
RH
2689}
2690
6608db57 2691/* Capital letters in template are macros. */
6439fc28 2692static int
26ca5450 2693putop (const char *template, int sizeflag)
252b5132 2694{
2da11e11 2695 const char *p;
6439fc28 2696 int alt;
252b5132
RH
2697
2698 for (p = template; *p; p++)
2699 {
2700 switch (*p)
2701 {
2702 default:
2703 *obufp++ = *p;
2704 break;
6439fc28
AM
2705 case '{':
2706 alt = 0;
2707 if (intel_syntax)
2708 alt += 1;
2709 if (mode_64bit)
2710 alt += 2;
2711 while (alt != 0)
2712 {
2713 while (*++p != '|')
2714 {
2715 if (*p == '}')
2716 {
2717 /* Alternative not valid. */
2718 strcpy (obuf, "(bad)");
2719 obufp = obuf + 5;
2720 return 1;
2721 }
2722 else if (*p == '\0')
2723 abort ();
2724 }
2725 alt--;
2726 }
2727 break;
2728 case '|':
2729 while (*++p != '}')
2730 {
2731 if (*p == '\0')
2732 abort ();
2733 }
2734 break;
2735 case '}':
2736 break;
252b5132 2737 case 'A':
db6eb5be
AM
2738 if (intel_syntax)
2739 break;
e396998b 2740 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
252b5132
RH
2741 *obufp++ = 'b';
2742 break;
2743 case 'B':
db6eb5be
AM
2744 if (intel_syntax)
2745 break;
252b5132
RH
2746 if (sizeflag & SUFFIX_ALWAYS)
2747 *obufp++ = 'b';
252b5132
RH
2748 break;
2749 case 'E': /* For jcxz/jecxz */
c1a64871
JH
2750 if (mode_64bit)
2751 {
2752 if (sizeflag & AFLAG)
2753 *obufp++ = 'r';
2754 else
2755 *obufp++ = 'e';
2756 }
2757 else
2758 if (sizeflag & AFLAG)
2759 *obufp++ = 'e';
3ffd33cf
AM
2760 used_prefixes |= (prefixes & PREFIX_ADDR);
2761 break;
2762 case 'F':
db6eb5be
AM
2763 if (intel_syntax)
2764 break;
e396998b 2765 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3ffd33cf
AM
2766 {
2767 if (sizeflag & AFLAG)
c1a64871 2768 *obufp++ = mode_64bit ? 'q' : 'l';
3ffd33cf 2769 else
c1a64871 2770 *obufp++ = mode_64bit ? 'l' : 'w';
3ffd33cf
AM
2771 used_prefixes |= (prefixes & PREFIX_ADDR);
2772 }
252b5132 2773 break;
5dd0794d 2774 case 'H':
db6eb5be
AM
2775 if (intel_syntax)
2776 break;
5dd0794d
AM
2777 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2778 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2779 {
2780 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2781 *obufp++ = ',';
2782 *obufp++ = 'p';
2783 if (prefixes & PREFIX_DS)
2784 *obufp++ = 't';
2785 else
2786 *obufp++ = 'n';
2787 }
2788 break;
252b5132 2789 case 'L':
db6eb5be
AM
2790 if (intel_syntax)
2791 break;
252b5132
RH
2792 if (sizeflag & SUFFIX_ALWAYS)
2793 *obufp++ = 'l';
252b5132
RH
2794 break;
2795 case 'N':
2796 if ((prefixes & PREFIX_FWAIT) == 0)
2797 *obufp++ = 'n';
7d421014
ILT
2798 else
2799 used_prefixes |= PREFIX_FWAIT;
252b5132 2800 break;
52b15da3
JH
2801 case 'O':
2802 USED_REX (REX_MODE64);
2803 if (rex & REX_MODE64)
6439fc28 2804 *obufp++ = 'o';
52b15da3
JH
2805 else
2806 *obufp++ = 'd';
2807 break;
6439fc28 2808 case 'T':
db6eb5be
AM
2809 if (intel_syntax)
2810 break;
6439fc28
AM
2811 if (mode_64bit)
2812 {
2813 *obufp++ = 'q';
2814 break;
2815 }
6608db57 2816 /* Fall through. */
252b5132 2817 case 'P':
db6eb5be
AM
2818 if (intel_syntax)
2819 break;
252b5132 2820 if ((prefixes & PREFIX_DATA)
52b15da3 2821 || (rex & REX_MODE64)
e396998b 2822 || (sizeflag & SUFFIX_ALWAYS))
252b5132 2823 {
52b15da3
JH
2824 USED_REX (REX_MODE64);
2825 if (rex & REX_MODE64)
2826 *obufp++ = 'q';
c2419411 2827 else
52b15da3
JH
2828 {
2829 if (sizeflag & DFLAG)
2830 *obufp++ = 'l';
2831 else
2832 *obufp++ = 'w';
2833 used_prefixes |= (prefixes & PREFIX_DATA);
2834 }
252b5132
RH
2835 }
2836 break;
6439fc28 2837 case 'U':
db6eb5be
AM
2838 if (intel_syntax)
2839 break;
6439fc28
AM
2840 if (mode_64bit)
2841 {
2842 *obufp++ = 'q';
2843 break;
2844 }
6608db57 2845 /* Fall through. */
252b5132 2846 case 'Q':
db6eb5be
AM
2847 if (intel_syntax)
2848 break;
90530880 2849 USED_REX (REX_MODE64);
e396998b 2850 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
252b5132 2851 {
52b15da3
JH
2852 if (rex & REX_MODE64)
2853 *obufp++ = 'q';
252b5132 2854 else
52b15da3
JH
2855 {
2856 if (sizeflag & DFLAG)
2857 *obufp++ = 'l';
2858 else
2859 *obufp++ = 'w';
2860 used_prefixes |= (prefixes & PREFIX_DATA);
2861 }
252b5132
RH
2862 }
2863 break;
2864 case 'R':
52b15da3 2865 USED_REX (REX_MODE64);
db6eb5be 2866 if (intel_syntax)
c608c12e 2867 {
52b15da3
JH
2868 if (rex & REX_MODE64)
2869 {
2870 *obufp++ = 'q';
2871 *obufp++ = 't';
2872 }
2873 else if (sizeflag & DFLAG)
c608c12e
AM
2874 {
2875 *obufp++ = 'd';
2876 *obufp++ = 'q';
2877 }
2878 else
2879 {
2880 *obufp++ = 'w';
2881 *obufp++ = 'd';
2882 }
2883 }
252b5132 2884 else
c608c12e 2885 {
52b15da3
JH
2886 if (rex & REX_MODE64)
2887 *obufp++ = 'q';
2888 else if (sizeflag & DFLAG)
c608c12e
AM
2889 *obufp++ = 'l';
2890 else
2891 *obufp++ = 'w';
2892 }
52b15da3
JH
2893 if (!(rex & REX_MODE64))
2894 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2895 break;
2896 case 'S':
db6eb5be
AM
2897 if (intel_syntax)
2898 break;
252b5132
RH
2899 if (sizeflag & SUFFIX_ALWAYS)
2900 {
52b15da3
JH
2901 if (rex & REX_MODE64)
2902 *obufp++ = 'q';
252b5132 2903 else
52b15da3
JH
2904 {
2905 if (sizeflag & DFLAG)
2906 *obufp++ = 'l';
2907 else
2908 *obufp++ = 'w';
2909 used_prefixes |= (prefixes & PREFIX_DATA);
2910 }
252b5132 2911 }
252b5132 2912 break;
041bd2e0
JH
2913 case 'X':
2914 if (prefixes & PREFIX_DATA)
2915 *obufp++ = 'd';
2916 else
2917 *obufp++ = 's';
db6eb5be 2918 used_prefixes |= (prefixes & PREFIX_DATA);
041bd2e0 2919 break;
76f227a5 2920 case 'Y':
db6eb5be
AM
2921 if (intel_syntax)
2922 break;
76f227a5
JH
2923 if (rex & REX_MODE64)
2924 {
2925 USED_REX (REX_MODE64);
2926 *obufp++ = 'q';
2927 }
2928 break;
52b15da3 2929 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
252b5132 2930 case 'W':
252b5132 2931 /* operand size flag for cwtl, cbtw */
52b15da3
JH
2932 USED_REX (0);
2933 if (rex)
2934 *obufp++ = 'l';
2935 else if (sizeflag & DFLAG)
252b5132
RH
2936 *obufp++ = 'w';
2937 else
2938 *obufp++ = 'b';
db6eb5be 2939 if (intel_syntax)
c608c12e 2940 {
52b15da3
JH
2941 if (rex)
2942 {
2943 *obufp++ = 'q';
2944 *obufp++ = 'e';
2945 }
c608c12e
AM
2946 if (sizeflag & DFLAG)
2947 {
2948 *obufp++ = 'd';
2949 *obufp++ = 'e';
2950 }
2951 else
2952 {
2953 *obufp++ = 'w';
2954 }
2955 }
52b15da3
JH
2956 if (!rex)
2957 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2958 break;
2959 }
2960 }
2961 *obufp = 0;
6439fc28 2962 return 0;
252b5132
RH
2963}
2964
2965static void
26ca5450 2966oappend (const char *s)
252b5132
RH
2967{
2968 strcpy (obufp, s);
2969 obufp += strlen (s);
2970}
2971
2972static void
26ca5450 2973append_seg (void)
252b5132
RH
2974{
2975 if (prefixes & PREFIX_CS)
7d421014 2976 {
7d421014 2977 used_prefixes |= PREFIX_CS;
d708bcba 2978 oappend ("%cs:" + intel_syntax);
7d421014 2979 }
252b5132 2980 if (prefixes & PREFIX_DS)
7d421014 2981 {
7d421014 2982 used_prefixes |= PREFIX_DS;
d708bcba 2983 oappend ("%ds:" + intel_syntax);
7d421014 2984 }
252b5132 2985 if (prefixes & PREFIX_SS)
7d421014 2986 {
7d421014 2987 used_prefixes |= PREFIX_SS;
d708bcba 2988 oappend ("%ss:" + intel_syntax);
7d421014 2989 }
252b5132 2990 if (prefixes & PREFIX_ES)
7d421014 2991 {
7d421014 2992 used_prefixes |= PREFIX_ES;
d708bcba 2993 oappend ("%es:" + intel_syntax);
7d421014 2994 }
252b5132 2995 if (prefixes & PREFIX_FS)
7d421014 2996 {
7d421014 2997 used_prefixes |= PREFIX_FS;
d708bcba 2998 oappend ("%fs:" + intel_syntax);
7d421014 2999 }
252b5132 3000 if (prefixes & PREFIX_GS)
7d421014 3001 {
7d421014 3002 used_prefixes |= PREFIX_GS;
d708bcba 3003 oappend ("%gs:" + intel_syntax);
7d421014 3004 }
252b5132
RH
3005}
3006
3007static void
26ca5450 3008OP_indirE (int bytemode, int sizeflag)
252b5132
RH
3009{
3010 if (!intel_syntax)
3011 oappend ("*");
3012 OP_E (bytemode, sizeflag);
3013}
3014
52b15da3 3015static void
26ca5450 3016print_operand_value (char *buf, int hex, bfd_vma disp)
52b15da3
JH
3017{
3018 if (mode_64bit)
3019 {
3020 if (hex)
3021 {
3022 char tmp[30];
3023 int i;
3024 buf[0] = '0';
3025 buf[1] = 'x';
3026 sprintf_vma (tmp, disp);
6608db57 3027 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
52b15da3
JH
3028 strcpy (buf + 2, tmp + i);
3029 }
3030 else
3031 {
3032 bfd_signed_vma v = disp;
3033 char tmp[30];
3034 int i;
3035 if (v < 0)
3036 {
3037 *(buf++) = '-';
3038 v = -disp;
6608db57 3039 /* Check for possible overflow on 0x8000000000000000. */
52b15da3
JH
3040 if (v < 0)
3041 {
3042 strcpy (buf, "9223372036854775808");
3043 return;
3044 }
3045 }
3046 if (!v)
3047 {
3048 strcpy (buf, "0");
3049 return;
3050 }
3051
3052 i = 0;
3053 tmp[29] = 0;
3054 while (v)
3055 {
6608db57 3056 tmp[28 - i] = (v % 10) + '0';
52b15da3
JH
3057 v /= 10;
3058 i++;
3059 }
3060 strcpy (buf, tmp + 29 - i);
3061 }
3062 }
3063 else
3064 {
3065 if (hex)
3066 sprintf (buf, "0x%x", (unsigned int) disp);
3067 else
3068 sprintf (buf, "%d", (int) disp);
3069 }
3070}
3071
252b5132 3072static void
26ca5450 3073OP_E (int bytemode, int sizeflag)
252b5132 3074{
52b15da3
JH
3075 bfd_vma disp;
3076 int add = 0;
3077 int riprel = 0;
3078 USED_REX (REX_EXTZ);
3079 if (rex & REX_EXTZ)
3080 add += 8;
252b5132 3081
6608db57 3082 /* Skip mod/rm byte. */
4bba6815 3083 MODRM_CHECK;
252b5132
RH
3084 codep++;
3085
3086 if (mod == 3)
3087 {
3088 switch (bytemode)
3089 {
3090 case b_mode:
52b15da3
JH
3091 USED_REX (0);
3092 if (rex)
3093 oappend (names8rex[rm + add]);
3094 else
3095 oappend (names8[rm + add]);
252b5132
RH
3096 break;
3097 case w_mode:
52b15da3 3098 oappend (names16[rm + add]);
252b5132 3099 break;
2da11e11 3100 case d_mode:
52b15da3
JH
3101 oappend (names32[rm + add]);
3102 break;
3103 case q_mode:
3104 oappend (names64[rm + add]);
3105 break;
3106 case m_mode:
3107 if (mode_64bit)
3108 oappend (names64[rm + add]);
3109 else
3110 oappend (names32[rm + add]);
2da11e11 3111 break;
252b5132 3112 case v_mode:
db6eb5be 3113 case dq_mode:
52b15da3
JH
3114 USED_REX (REX_MODE64);
3115 if (rex & REX_MODE64)
3116 oappend (names64[rm + add]);
db6eb5be 3117 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
52b15da3 3118 oappend (names32[rm + add]);
252b5132 3119 else
52b15da3 3120 oappend (names16[rm + add]);
7d421014 3121 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132 3122 break;
2da11e11 3123 case 0:
c608c12e 3124 break;
252b5132 3125 default:
c608c12e 3126 oappend (INTERNAL_DISASSEMBLER_ERROR);
252b5132
RH
3127 break;
3128 }
3129 return;
3130 }
3131
3132 disp = 0;
3133 append_seg ();
3134
c1a64871 3135 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
252b5132
RH
3136 {
3137 int havesib;
3138 int havebase;
3139 int base;
3140 int index = 0;
3141 int scale = 0;
3142
3143 havesib = 0;
3144 havebase = 1;
3145 base = rm;
3146
3147 if (base == 4)
3148 {
3149 havesib = 1;
3150 FETCH_DATA (the_info, codep + 1);
3151 scale = (*codep >> 6) & 3;
3152 index = (*codep >> 3) & 7;
3153 base = *codep & 7;
52b15da3
JH
3154 USED_REX (REX_EXTY);
3155 USED_REX (REX_EXTZ);
3156 if (rex & REX_EXTY)
3157 index += 8;
3158 if (rex & REX_EXTZ)
3159 base += 8;
252b5132
RH
3160 codep++;
3161 }
3162
3163 switch (mod)
3164 {
3165 case 0:
52b15da3 3166 if ((base & 7) == 5)
252b5132
RH
3167 {
3168 havebase = 0;
c1a64871 3169 if (mode_64bit && !havesib && (sizeflag & AFLAG))
52b15da3
JH
3170 riprel = 1;
3171 disp = get32s ();
252b5132
RH
3172 }
3173 break;
3174 case 1:
3175 FETCH_DATA (the_info, codep + 1);
3176 disp = *codep++;
3177 if ((disp & 0x80) != 0)
3178 disp -= 0x100;
3179 break;
3180 case 2:
52b15da3 3181 disp = get32s ();
252b5132
RH
3182 break;
3183 }
3184
3185 if (!intel_syntax)
db6eb5be
AM
3186 if (mod != 0 || (base & 7) == 5)
3187 {
52b15da3 3188 print_operand_value (scratchbuf, !riprel, disp);
db6eb5be 3189 oappend (scratchbuf);
52b15da3
JH
3190 if (riprel)
3191 {
3192 set_op (disp, 1);
3193 oappend ("(%rip)");
3194 }
db6eb5be 3195 }
2da11e11 3196
252b5132
RH
3197 if (havebase || (havesib && (index != 4 || scale != 0)))
3198 {
db6eb5be
AM
3199 if (intel_syntax)
3200 {
3201 switch (bytemode)
3202 {
3203 case b_mode:
3204 oappend ("BYTE PTR ");
3205 break;
3206 case w_mode:
3207 oappend ("WORD PTR ");
3208 break;
3209 case v_mode:
1d9f512f
AM
3210 if (sizeflag & DFLAG)
3211 oappend ("DWORD PTR ");
3212 else
3213 oappend ("WORD PTR ");
db6eb5be
AM
3214 break;
3215 case d_mode:
1d9f512f
AM
3216 oappend ("DWORD PTR ");
3217 break;
3218 case q_mode:
db6eb5be
AM
3219 oappend ("QWORD PTR ");
3220 break;
3221 case m_mode:
52b15da3
JH
3222 if (mode_64bit)
3223 oappend ("DWORD PTR ");
3224 else
3225 oappend ("QWORD PTR ");
3226 break;
db6eb5be
AM
3227 case x_mode:
3228 oappend ("XWORD PTR ");
3229 break;
3230 default:
3231 break;
3232 }
3233 }
252b5132 3234 *obufp++ = open_char;
52b15da3
JH
3235 if (intel_syntax && riprel)
3236 oappend ("rip + ");
db6eb5be 3237 *obufp = '\0';
52b15da3
JH
3238 USED_REX (REX_EXTZ);
3239 if (!havesib && (rex & REX_EXTZ))
3240 base += 8;
252b5132 3241 if (havebase)
c1a64871
JH
3242 oappend (mode_64bit && (sizeflag & AFLAG)
3243 ? names64[base] : names32[base]);
252b5132
RH
3244 if (havesib)
3245 {
3246 if (index != 4)
3247 {
db6eb5be
AM
3248 if (intel_syntax)
3249 {
3250 if (havebase)
3251 {
3252 *obufp++ = separator_char;
3253 *obufp = '\0';
3254 }
3255 sprintf (scratchbuf, "%s",
c1a64871
JH
3256 mode_64bit && (sizeflag & AFLAG)
3257 ? names64[index] : names32[index]);
db6eb5be
AM
3258 }
3259 else
d708bcba 3260 sprintf (scratchbuf, ",%s",
c1a64871
JH
3261 mode_64bit && (sizeflag & AFLAG)
3262 ? names64[index] : names32[index]);
252b5132
RH
3263 oappend (scratchbuf);
3264 }
a02a862a 3265 if (scale != 0 || (!intel_syntax && index != 4))
db6eb5be
AM
3266 {
3267 *obufp++ = scale_char;
3268 *obufp = '\0';
3269 sprintf (scratchbuf, "%d", 1 << scale);
3270 oappend (scratchbuf);
3271 }
252b5132 3272 }
db6eb5be
AM
3273 if (intel_syntax)
3274 if (mod != 0 || (base & 7) == 5)
3275 {
6608db57 3276 /* Don't print zero displacements. */
db6eb5be
AM
3277 if (disp != 0)
3278 {
d708bcba
AM
3279 if ((bfd_signed_vma) disp > 0)
3280 {
3281 *obufp++ = '+';
3282 *obufp = '\0';
3283 }
3284
52b15da3 3285 print_operand_value (scratchbuf, 0, disp);
db6eb5be
AM
3286 oappend (scratchbuf);
3287 }
3288 }
252b5132
RH
3289
3290 *obufp++ = close_char;
db6eb5be 3291 *obufp = '\0';
252b5132
RH
3292 }
3293 else if (intel_syntax)
db6eb5be
AM
3294 {
3295 if (mod != 0 || (base & 7) == 5)
3296 {
252b5132
RH
3297 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3298 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3299 ;
3300 else
3301 {
d708bcba 3302 oappend (names_seg[ds_reg - es_reg]);
252b5132
RH
3303 oappend (":");
3304 }
52b15da3 3305 print_operand_value (scratchbuf, 1, disp);
db6eb5be
AM
3306 oappend (scratchbuf);
3307 }
3308 }
252b5132
RH
3309 }
3310 else
3311 { /* 16 bit address mode */
3312 switch (mod)
3313 {
3314 case 0:
52b15da3 3315 if ((rm & 7) == 6)
252b5132
RH
3316 {
3317 disp = get16 ();
3318 if ((disp & 0x8000) != 0)
3319 disp -= 0x10000;
3320 }
3321 break;
3322 case 1:
3323 FETCH_DATA (the_info, codep + 1);
3324 disp = *codep++;
3325 if ((disp & 0x80) != 0)
3326 disp -= 0x100;
3327 break;
3328 case 2:
3329 disp = get16 ();
3330 if ((disp & 0x8000) != 0)
3331 disp -= 0x10000;
3332 break;
3333 }
3334
3335 if (!intel_syntax)
db6eb5be
AM
3336 if (mod != 0 || (rm & 7) == 6)
3337 {
52b15da3 3338 print_operand_value (scratchbuf, 0, disp);
db6eb5be
AM
3339 oappend (scratchbuf);
3340 }
252b5132 3341
52b15da3 3342 if (mod != 0 || (rm & 7) != 6)
252b5132
RH
3343 {
3344 *obufp++ = open_char;
db6eb5be 3345 *obufp = '\0';
52b15da3 3346 oappend (index16[rm + add]);
db6eb5be
AM
3347 *obufp++ = close_char;
3348 *obufp = '\0';
252b5132
RH
3349 }
3350 }
3351}
3352
252b5132 3353static void
26ca5450 3354OP_G (int bytemode, int sizeflag)
252b5132 3355{
52b15da3
JH
3356 int add = 0;
3357 USED_REX (REX_EXTX);
3358 if (rex & REX_EXTX)
3359 add += 8;
252b5132
RH
3360 switch (bytemode)
3361 {
3362 case b_mode:
52b15da3
JH
3363 USED_REX (0);
3364 if (rex)
3365 oappend (names8rex[reg + add]);
3366 else
3367 oappend (names8[reg + add]);
252b5132
RH
3368 break;
3369 case w_mode:
52b15da3 3370 oappend (names16[reg + add]);
252b5132
RH
3371 break;
3372 case d_mode:
52b15da3
JH
3373 oappend (names32[reg + add]);
3374 break;
3375 case q_mode:
3376 oappend (names64[reg + add]);
252b5132
RH
3377 break;
3378 case v_mode:
52b15da3
JH
3379 USED_REX (REX_MODE64);
3380 if (rex & REX_MODE64)
3381 oappend (names64[reg + add]);
3382 else if (sizeflag & DFLAG)
3383 oappend (names32[reg + add]);
252b5132 3384 else
52b15da3 3385 oappend (names16[reg + add]);
7d421014 3386 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3387 break;
3388 default:
3389 oappend (INTERNAL_DISASSEMBLER_ERROR);
3390 break;
3391 }
3392}
3393
52b15da3 3394static bfd_vma
26ca5450 3395get64 (void)
52b15da3 3396{
5dd0794d 3397 bfd_vma x;
52b15da3 3398#ifdef BFD64
5dd0794d
AM
3399 unsigned int a;
3400 unsigned int b;
3401
52b15da3
JH
3402 FETCH_DATA (the_info, codep + 8);
3403 a = *codep++ & 0xff;
3404 a |= (*codep++ & 0xff) << 8;
3405 a |= (*codep++ & 0xff) << 16;
3406 a |= (*codep++ & 0xff) << 24;
5dd0794d 3407 b = *codep++ & 0xff;
52b15da3
JH
3408 b |= (*codep++ & 0xff) << 8;
3409 b |= (*codep++ & 0xff) << 16;
3410 b |= (*codep++ & 0xff) << 24;
3411 x = a + ((bfd_vma) b << 32);
3412#else
6608db57 3413 abort ();
5dd0794d 3414 x = 0;
52b15da3
JH
3415#endif
3416 return x;
3417}
3418
3419static bfd_signed_vma
26ca5450 3420get32 (void)
252b5132 3421{
52b15da3 3422 bfd_signed_vma x = 0;
252b5132
RH
3423
3424 FETCH_DATA (the_info, codep + 4);
52b15da3
JH
3425 x = *codep++ & (bfd_signed_vma) 0xff;
3426 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3427 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3428 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3429 return x;
3430}
3431
3432static bfd_signed_vma
26ca5450 3433get32s (void)
52b15da3
JH
3434{
3435 bfd_signed_vma x = 0;
3436
3437 FETCH_DATA (the_info, codep + 4);
3438 x = *codep++ & (bfd_signed_vma) 0xff;
3439 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3440 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3441 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3442
3443 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3444
252b5132
RH
3445 return x;
3446}
3447
3448static int
26ca5450 3449get16 (void)
252b5132
RH
3450{
3451 int x = 0;
3452
3453 FETCH_DATA (the_info, codep + 2);
3454 x = *codep++ & 0xff;
3455 x |= (*codep++ & 0xff) << 8;
3456 return x;
3457}
3458
3459static void
26ca5450 3460set_op (bfd_vma op, int riprel)
252b5132
RH
3461{
3462 op_index[op_ad] = op_ad;
7081ff04
AJ
3463 if (mode_64bit)
3464 {
3465 op_address[op_ad] = op;
3466 op_riprel[op_ad] = riprel;
3467 }
3468 else
3469 {
3470 /* Mask to get a 32-bit address. */
3471 op_address[op_ad] = op & 0xffffffff;
3472 op_riprel[op_ad] = riprel & 0xffffffff;
3473 }
252b5132
RH
3474}
3475
3476static void
26ca5450 3477OP_REG (int code, int sizeflag)
252b5132 3478{
2da11e11 3479 const char *s;
52b15da3
JH
3480 int add = 0;
3481 USED_REX (REX_EXTZ);
3482 if (rex & REX_EXTZ)
3483 add = 8;
3484
3485 switch (code)
3486 {
3487 case indir_dx_reg:
d708bcba 3488 if (intel_syntax)
db6eb5be 3489 s = "[dx]";
d708bcba 3490 else
db6eb5be 3491 s = "(%dx)";
52b15da3
JH
3492 break;
3493 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3494 case sp_reg: case bp_reg: case si_reg: case di_reg:
3495 s = names16[code - ax_reg + add];
3496 break;
3497 case es_reg: case ss_reg: case cs_reg:
3498 case ds_reg: case fs_reg: case gs_reg:
3499 s = names_seg[code - es_reg + add];
3500 break;
3501 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3502 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3503 USED_REX (0);
3504 if (rex)
3505 s = names8rex[code - al_reg + add];
3506 else
3507 s = names8[code - al_reg];
3508 break;
6439fc28
AM
3509 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3510 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3511 if (mode_64bit)
3512 {
3513 s = names64[code - rAX_reg + add];
3514 break;
3515 }
3516 code += eAX_reg - rAX_reg;
6608db57 3517 /* Fall through. */
52b15da3
JH
3518 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3519 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3520 USED_REX (REX_MODE64);
3521 if (rex & REX_MODE64)
3522 s = names64[code - eAX_reg + add];
3523 else if (sizeflag & DFLAG)
3524 s = names32[code - eAX_reg + add];
3525 else
3526 s = names16[code - eAX_reg + add];
3527 used_prefixes |= (prefixes & PREFIX_DATA);
3528 break;
52b15da3
JH
3529 default:
3530 s = INTERNAL_DISASSEMBLER_ERROR;
3531 break;
3532 }
3533 oappend (s);
3534}
3535
3536static void
26ca5450 3537OP_IMREG (int code, int sizeflag)
52b15da3
JH
3538{
3539 const char *s;
252b5132
RH
3540
3541 switch (code)
3542 {
3543 case indir_dx_reg:
d708bcba 3544 if (intel_syntax)
db6eb5be 3545 s = "[dx]";
d708bcba 3546 else
db6eb5be 3547 s = "(%dx)";
252b5132
RH
3548 break;
3549 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3550 case sp_reg: case bp_reg: case si_reg: case di_reg:
3551 s = names16[code - ax_reg];
3552 break;
3553 case es_reg: case ss_reg: case cs_reg:
3554 case ds_reg: case fs_reg: case gs_reg:
3555 s = names_seg[code - es_reg];
3556 break;
3557 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3558 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
52b15da3
JH
3559 USED_REX (0);
3560 if (rex)
3561 s = names8rex[code - al_reg];
3562 else
3563 s = names8[code - al_reg];
252b5132
RH
3564 break;
3565 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3566 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
52b15da3
JH
3567 USED_REX (REX_MODE64);
3568 if (rex & REX_MODE64)
3569 s = names64[code - eAX_reg];
3570 else if (sizeflag & DFLAG)
252b5132
RH
3571 s = names32[code - eAX_reg];
3572 else
3573 s = names16[code - eAX_reg];
7d421014 3574 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3575 break;
3576 default:
3577 s = INTERNAL_DISASSEMBLER_ERROR;
3578 break;
3579 }
3580 oappend (s);
3581}
3582
3583static void
26ca5450 3584OP_I (int bytemode, int sizeflag)
252b5132 3585{
52b15da3
JH
3586 bfd_signed_vma op;
3587 bfd_signed_vma mask = -1;
252b5132
RH
3588
3589 switch (bytemode)
3590 {
3591 case b_mode:
3592 FETCH_DATA (the_info, codep + 1);
52b15da3
JH
3593 op = *codep++;
3594 mask = 0xff;
3595 break;
3596 case q_mode:
6439fc28
AM
3597 if (mode_64bit)
3598 {
3599 op = get32s ();
3600 break;
3601 }
6608db57 3602 /* Fall through. */
252b5132 3603 case v_mode:
52b15da3
JH
3604 USED_REX (REX_MODE64);
3605 if (rex & REX_MODE64)
3606 op = get32s ();
3607 else if (sizeflag & DFLAG)
3608 {
3609 op = get32 ();
3610 mask = 0xffffffff;
3611 }
252b5132 3612 else
52b15da3
JH
3613 {
3614 op = get16 ();
3615 mask = 0xfffff;
3616 }
7d421014 3617 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3618 break;
3619 case w_mode:
52b15da3 3620 mask = 0xfffff;
252b5132
RH
3621 op = get16 ();
3622 break;
3623 default:
3624 oappend (INTERNAL_DISASSEMBLER_ERROR);
3625 return;
3626 }
3627
52b15da3
JH
3628 op &= mask;
3629 scratchbuf[0] = '$';
d708bcba
AM
3630 print_operand_value (scratchbuf + 1, 1, op);
3631 oappend (scratchbuf + intel_syntax);
52b15da3
JH
3632 scratchbuf[0] = '\0';
3633}
3634
3635static void
26ca5450 3636OP_I64 (int bytemode, int sizeflag)
52b15da3
JH
3637{
3638 bfd_signed_vma op;
3639 bfd_signed_vma mask = -1;
3640
6439fc28
AM
3641 if (!mode_64bit)
3642 {
3643 OP_I (bytemode, sizeflag);
3644 return;
3645 }
3646
52b15da3
JH
3647 switch (bytemode)
3648 {
3649 case b_mode:
3650 FETCH_DATA (the_info, codep + 1);
3651 op = *codep++;
3652 mask = 0xff;
3653 break;
3654 case v_mode:
3655 USED_REX (REX_MODE64);
3656 if (rex & REX_MODE64)
3657 op = get64 ();
3658 else if (sizeflag & DFLAG)
3659 {
3660 op = get32 ();
3661 mask = 0xffffffff;
3662 }
3663 else
3664 {
3665 op = get16 ();
3666 mask = 0xfffff;
3667 }
3668 used_prefixes |= (prefixes & PREFIX_DATA);
3669 break;
3670 case w_mode:
3671 mask = 0xfffff;
3672 op = get16 ();
3673 break;
3674 default:
3675 oappend (INTERNAL_DISASSEMBLER_ERROR);
3676 return;
3677 }
3678
3679 op &= mask;
3680 scratchbuf[0] = '$';
d708bcba
AM
3681 print_operand_value (scratchbuf + 1, 1, op);
3682 oappend (scratchbuf + intel_syntax);
252b5132
RH
3683 scratchbuf[0] = '\0';
3684}
3685
3686static void
26ca5450 3687OP_sI (int bytemode, int sizeflag)
252b5132 3688{
52b15da3
JH
3689 bfd_signed_vma op;
3690 bfd_signed_vma mask = -1;
252b5132
RH
3691
3692 switch (bytemode)
3693 {
3694 case b_mode:
3695 FETCH_DATA (the_info, codep + 1);
3696 op = *codep++;
3697 if ((op & 0x80) != 0)
3698 op -= 0x100;
52b15da3 3699 mask = 0xffffffff;
252b5132
RH
3700 break;
3701 case v_mode:
52b15da3
JH
3702 USED_REX (REX_MODE64);
3703 if (rex & REX_MODE64)
3704 op = get32s ();
3705 else if (sizeflag & DFLAG)
3706 {
3707 op = get32s ();
3708 mask = 0xffffffff;
3709 }
252b5132
RH
3710 else
3711 {
52b15da3 3712 mask = 0xffffffff;
6608db57 3713 op = get16 ();
252b5132
RH
3714 if ((op & 0x8000) != 0)
3715 op -= 0x10000;
3716 }
7d421014 3717 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3718 break;
3719 case w_mode:
3720 op = get16 ();
52b15da3 3721 mask = 0xffffffff;
252b5132
RH
3722 if ((op & 0x8000) != 0)
3723 op -= 0x10000;
3724 break;
3725 default:
3726 oappend (INTERNAL_DISASSEMBLER_ERROR);
3727 return;
3728 }
52b15da3
JH
3729
3730 scratchbuf[0] = '$';
3731 print_operand_value (scratchbuf + 1, 1, op);
d708bcba 3732 oappend (scratchbuf + intel_syntax);
252b5132
RH
3733}
3734
3735static void
26ca5450 3736OP_J (int bytemode, int sizeflag)
252b5132 3737{
52b15da3 3738 bfd_vma disp;
7081ff04 3739 bfd_vma mask = -1;
252b5132
RH
3740
3741 switch (bytemode)
3742 {
3743 case b_mode:
3744 FETCH_DATA (the_info, codep + 1);
3745 disp = *codep++;
3746 if ((disp & 0x80) != 0)
3747 disp -= 0x100;
3748 break;
3749 case v_mode:
3750 if (sizeflag & DFLAG)
52b15da3 3751 disp = get32s ();
252b5132
RH
3752 else
3753 {
3754 disp = get16 ();
6608db57 3755 /* For some reason, a data16 prefix on a jump instruction
252b5132
RH
3756 means that the pc is masked to 16 bits after the
3757 displacement is added! */
3758 mask = 0xffff;
3759 }
3760 break;
3761 default:
3762 oappend (INTERNAL_DISASSEMBLER_ERROR);
3763 return;
3764 }
3765 disp = (start_pc + codep - start_codep + disp) & mask;
52b15da3
JH
3766 set_op (disp, 0);
3767 print_operand_value (scratchbuf, 1, disp);
252b5132
RH
3768 oappend (scratchbuf);
3769}
3770
252b5132 3771static void
26ca5450 3772OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3773{
d708bcba 3774 oappend (names_seg[reg]);
252b5132
RH
3775}
3776
3777static void
26ca5450 3778OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
252b5132
RH
3779{
3780 int seg, offset;
3781
c608c12e 3782 if (sizeflag & DFLAG)
252b5132 3783 {
c608c12e
AM
3784 offset = get32 ();
3785 seg = get16 ();
252b5132 3786 }
c608c12e
AM
3787 else
3788 {
3789 offset = get16 ();
3790 seg = get16 ();
3791 }
7d421014 3792 used_prefixes |= (prefixes & PREFIX_DATA);
d708bcba
AM
3793 if (intel_syntax)
3794 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3795 else
3796 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
c608c12e 3797 oappend (scratchbuf);
252b5132
RH
3798}
3799
252b5132 3800static void
26ca5450 3801OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
252b5132 3802{
52b15da3 3803 bfd_vma off;
252b5132
RH
3804
3805 append_seg ();
3806
c1a64871 3807 if ((sizeflag & AFLAG) || mode_64bit)
252b5132
RH
3808 off = get32 ();
3809 else
3810 off = get16 ();
3811
3812 if (intel_syntax)
3813 {
3814 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
db6eb5be 3815 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
252b5132 3816 {
d708bcba 3817 oappend (names_seg[ds_reg - es_reg]);
252b5132
RH
3818 oappend (":");
3819 }
3820 }
52b15da3
JH
3821 print_operand_value (scratchbuf, 1, off);
3822 oappend (scratchbuf);
3823}
6439fc28 3824
52b15da3 3825static void
26ca5450 3826OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
52b15da3
JH
3827{
3828 bfd_vma off;
3829
6439fc28
AM
3830 if (!mode_64bit)
3831 {
3832 OP_OFF (bytemode, sizeflag);
3833 return;
3834 }
3835
52b15da3
JH
3836 append_seg ();
3837
6608db57 3838 off = get64 ();
52b15da3
JH
3839
3840 if (intel_syntax)
3841 {
3842 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
db6eb5be 3843 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
52b15da3 3844 {
d708bcba 3845 oappend (names_seg[ds_reg - es_reg]);
52b15da3
JH
3846 oappend (":");
3847 }
3848 }
3849 print_operand_value (scratchbuf, 1, off);
252b5132
RH
3850 oappend (scratchbuf);
3851}
3852
3853static void
26ca5450 3854ptr_reg (int code, int sizeflag)
252b5132 3855{
2da11e11 3856 const char *s;
d708bcba 3857
1d9f512f 3858 *obufp++ = open_char;
52b15da3
JH
3859 USED_REX (REX_MODE64);
3860 if (rex & REX_MODE64)
c1a64871
JH
3861 {
3862 if (!(sizeflag & AFLAG))
db6eb5be 3863 s = names32[code - eAX_reg];
c1a64871 3864 else
db6eb5be 3865 s = names64[code - eAX_reg];
c1a64871 3866 }
52b15da3 3867 else if (sizeflag & AFLAG)
252b5132
RH
3868 s = names32[code - eAX_reg];
3869 else
3870 s = names16[code - eAX_reg];
3871 oappend (s);
1d9f512f
AM
3872 *obufp++ = close_char;
3873 *obufp = 0;
252b5132
RH
3874}
3875
3876static void
26ca5450 3877OP_ESreg (int code, int sizeflag)
252b5132 3878{
d708bcba 3879 oappend ("%es:" + intel_syntax);
252b5132
RH
3880 ptr_reg (code, sizeflag);
3881}
3882
3883static void
26ca5450 3884OP_DSreg (int code, int sizeflag)
252b5132
RH
3885{
3886 if ((prefixes
3887 & (PREFIX_CS
3888 | PREFIX_DS
3889 | PREFIX_SS
3890 | PREFIX_ES
3891 | PREFIX_FS
3892 | PREFIX_GS)) == 0)
3893 prefixes |= PREFIX_DS;
6608db57 3894 append_seg ();
252b5132
RH
3895 ptr_reg (code, sizeflag);
3896}
3897
252b5132 3898static void
26ca5450 3899OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3900{
52b15da3
JH
3901 int add = 0;
3902 USED_REX (REX_EXTX);
3903 if (rex & REX_EXTX)
3904 add = 8;
d708bcba
AM
3905 sprintf (scratchbuf, "%%cr%d", reg + add);
3906 oappend (scratchbuf + intel_syntax);
252b5132
RH
3907}
3908
252b5132 3909static void
26ca5450 3910OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3911{
52b15da3
JH
3912 int add = 0;
3913 USED_REX (REX_EXTX);
3914 if (rex & REX_EXTX)
3915 add = 8;
d708bcba 3916 if (intel_syntax)
6608db57 3917 sprintf (scratchbuf, "db%d", reg + add);
d708bcba 3918 else
6608db57 3919 sprintf (scratchbuf, "%%db%d", reg + add);
252b5132
RH
3920 oappend (scratchbuf);
3921}
3922
252b5132 3923static void
26ca5450 3924OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3925{
252b5132 3926 sprintf (scratchbuf, "%%tr%d", reg);
d708bcba 3927 oappend (scratchbuf + intel_syntax);
252b5132
RH
3928}
3929
3930static void
26ca5450 3931OP_Rd (int bytemode, int sizeflag)
252b5132 3932{
2da11e11
AM
3933 if (mod == 3)
3934 OP_E (bytemode, sizeflag);
3935 else
6608db57 3936 BadOp ();
252b5132
RH
3937}
3938
3939static void
26ca5450 3940OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132 3941{
041bd2e0
JH
3942 int add = 0;
3943 USED_REX (REX_EXTX);
3944 if (rex & REX_EXTX)
3945 add = 8;
3946 used_prefixes |= (prefixes & PREFIX_DATA);
3947 if (prefixes & PREFIX_DATA)
3948 sprintf (scratchbuf, "%%xmm%d", reg + add);
3949 else
3950 sprintf (scratchbuf, "%%mm%d", reg + add);
d708bcba 3951 oappend (scratchbuf + intel_syntax);
252b5132
RH
3952}
3953
c608c12e 3954static void
26ca5450 3955OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
c608c12e 3956{
041bd2e0
JH
3957 int add = 0;
3958 USED_REX (REX_EXTX);
3959 if (rex & REX_EXTX)
3960 add = 8;
3961 sprintf (scratchbuf, "%%xmm%d", reg + add);
d708bcba 3962 oappend (scratchbuf + intel_syntax);
c608c12e
AM
3963}
3964
252b5132 3965static void
26ca5450 3966OP_EM (int bytemode, int sizeflag)
252b5132 3967{
041bd2e0 3968 int add = 0;
252b5132
RH
3969 if (mod != 3)
3970 {
3971 OP_E (bytemode, sizeflag);
3972 return;
3973 }
041bd2e0
JH
3974 USED_REX (REX_EXTZ);
3975 if (rex & REX_EXTZ)
3976 add = 8;
252b5132 3977
6608db57 3978 /* Skip mod/rm byte. */
4bba6815 3979 MODRM_CHECK;
252b5132 3980 codep++;
041bd2e0
JH
3981 used_prefixes |= (prefixes & PREFIX_DATA);
3982 if (prefixes & PREFIX_DATA)
3983 sprintf (scratchbuf, "%%xmm%d", rm + add);
3984 else
3985 sprintf (scratchbuf, "%%mm%d", rm + add);
d708bcba 3986 oappend (scratchbuf + intel_syntax);
252b5132
RH
3987}
3988
c608c12e 3989static void
26ca5450 3990OP_EX (int bytemode, int sizeflag)
c608c12e 3991{
041bd2e0 3992 int add = 0;
c608c12e
AM
3993 if (mod != 3)
3994 {
3995 OP_E (bytemode, sizeflag);
3996 return;
3997 }
041bd2e0
JH
3998 USED_REX (REX_EXTZ);
3999 if (rex & REX_EXTZ)
4000 add = 8;
c608c12e 4001
6608db57 4002 /* Skip mod/rm byte. */
4bba6815 4003 MODRM_CHECK;
c608c12e 4004 codep++;
041bd2e0 4005 sprintf (scratchbuf, "%%xmm%d", rm + add);
d708bcba 4006 oappend (scratchbuf + intel_syntax);
c608c12e
AM
4007}
4008
252b5132 4009static void
26ca5450 4010OP_MS (int bytemode, int sizeflag)
252b5132 4011{
2da11e11
AM
4012 if (mod == 3)
4013 OP_EM (bytemode, sizeflag);
4014 else
6608db57 4015 BadOp ();
252b5132
RH
4016}
4017
992aaec9 4018static void
26ca5450 4019OP_XS (int bytemode, int sizeflag)
992aaec9
AM
4020{
4021 if (mod == 3)
4022 OP_EX (bytemode, sizeflag);
4023 else
6608db57 4024 BadOp ();
992aaec9
AM
4025}
4026
cc0ec051
AM
4027static void
4028OP_M (int bytemode, int sizeflag)
4029{
4030 if (mod == 3)
4031 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4032 else
4033 OP_E (bytemode, sizeflag);
4034}
4035
4036static void
4037OP_0f07 (int bytemode, int sizeflag)
4038{
4039 if (mod != 3 || rm != 0)
4040 BadOp ();
4041 else
4042 OP_E (bytemode, sizeflag);
4043}
4044
4045static void
4046OP_0fae (int bytemode, int sizeflag)
4047{
4048 if (mod == 3)
4049 {
4050 if (reg == 7)
4051 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4052
4053 if (reg < 5 || rm != 0)
4054 {
4055 BadOp (); /* bad sfence, mfence, or lfence */
4056 return;
4057 }
4058 }
4059 else if (reg != 7)
4060 {
4061 BadOp (); /* bad clflush */
4062 return;
4063 }
4064
4065 OP_E (bytemode, sizeflag);
4066}
4067
4068static void
4069NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4070{
4071 /* NOP with REPZ prefix is called PAUSE. */
4072 if (prefixes == PREFIX_REPZ)
4073 strcpy (obuf, "pause");
4074}
4075
84037f8c 4076static const char *const Suffix3DNow[] = {
252b5132
RH
4077/* 00 */ NULL, NULL, NULL, NULL,
4078/* 04 */ NULL, NULL, NULL, NULL,
4079/* 08 */ NULL, NULL, NULL, NULL,
9e525108 4080/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
252b5132
RH
4081/* 10 */ NULL, NULL, NULL, NULL,
4082/* 14 */ NULL, NULL, NULL, NULL,
4083/* 18 */ NULL, NULL, NULL, NULL,
9e525108 4084/* 1C */ "pf2iw", "pf2id", NULL, NULL,
252b5132
RH
4085/* 20 */ NULL, NULL, NULL, NULL,
4086/* 24 */ NULL, NULL, NULL, NULL,
4087/* 28 */ NULL, NULL, NULL, NULL,
4088/* 2C */ NULL, NULL, NULL, NULL,
4089/* 30 */ NULL, NULL, NULL, NULL,
4090/* 34 */ NULL, NULL, NULL, NULL,
4091/* 38 */ NULL, NULL, NULL, NULL,
4092/* 3C */ NULL, NULL, NULL, NULL,
4093/* 40 */ NULL, NULL, NULL, NULL,
4094/* 44 */ NULL, NULL, NULL, NULL,
4095/* 48 */ NULL, NULL, NULL, NULL,
4096/* 4C */ NULL, NULL, NULL, NULL,
4097/* 50 */ NULL, NULL, NULL, NULL,
4098/* 54 */ NULL, NULL, NULL, NULL,
4099/* 58 */ NULL, NULL, NULL, NULL,
4100/* 5C */ NULL, NULL, NULL, NULL,
4101/* 60 */ NULL, NULL, NULL, NULL,
4102/* 64 */ NULL, NULL, NULL, NULL,
4103/* 68 */ NULL, NULL, NULL, NULL,
4104/* 6C */ NULL, NULL, NULL, NULL,
4105/* 70 */ NULL, NULL, NULL, NULL,
4106/* 74 */ NULL, NULL, NULL, NULL,
4107/* 78 */ NULL, NULL, NULL, NULL,
4108/* 7C */ NULL, NULL, NULL, NULL,
4109/* 80 */ NULL, NULL, NULL, NULL,
4110/* 84 */ NULL, NULL, NULL, NULL,
9e525108
AM
4111/* 88 */ NULL, NULL, "pfnacc", NULL,
4112/* 8C */ NULL, NULL, "pfpnacc", NULL,
252b5132
RH
4113/* 90 */ "pfcmpge", NULL, NULL, NULL,
4114/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4115/* 98 */ NULL, NULL, "pfsub", NULL,
4116/* 9C */ NULL, NULL, "pfadd", NULL,
4117/* A0 */ "pfcmpgt", NULL, NULL, NULL,
4118/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4119/* A8 */ NULL, NULL, "pfsubr", NULL,
4120/* AC */ NULL, NULL, "pfacc", NULL,
4121/* B0 */ "pfcmpeq", NULL, NULL, NULL,
4122/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
9e525108 4123/* B8 */ NULL, NULL, NULL, "pswapd",
252b5132
RH
4124/* BC */ NULL, NULL, NULL, "pavgusb",
4125/* C0 */ NULL, NULL, NULL, NULL,
4126/* C4 */ NULL, NULL, NULL, NULL,
4127/* C8 */ NULL, NULL, NULL, NULL,
4128/* CC */ NULL, NULL, NULL, NULL,
4129/* D0 */ NULL, NULL, NULL, NULL,
4130/* D4 */ NULL, NULL, NULL, NULL,
4131/* D8 */ NULL, NULL, NULL, NULL,
4132/* DC */ NULL, NULL, NULL, NULL,
4133/* E0 */ NULL, NULL, NULL, NULL,
4134/* E4 */ NULL, NULL, NULL, NULL,
4135/* E8 */ NULL, NULL, NULL, NULL,
4136/* EC */ NULL, NULL, NULL, NULL,
4137/* F0 */ NULL, NULL, NULL, NULL,
4138/* F4 */ NULL, NULL, NULL, NULL,
4139/* F8 */ NULL, NULL, NULL, NULL,
4140/* FC */ NULL, NULL, NULL, NULL,
4141};
4142
4143static void
26ca5450 4144OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
252b5132
RH
4145{
4146 const char *mnemonic;
4147
4148 FETCH_DATA (the_info, codep + 1);
4149 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4150 place where an 8-bit immediate would normally go. ie. the last
4151 byte of the instruction. */
6608db57 4152 obufp = obuf + strlen (obuf);
c608c12e 4153 mnemonic = Suffix3DNow[*codep++ & 0xff];
252b5132 4154 if (mnemonic)
2da11e11 4155 oappend (mnemonic);
252b5132
RH
4156 else
4157 {
4158 /* Since a variable sized modrm/sib chunk is between the start
4159 of the opcode (0x0f0f) and the opcode suffix, we need to do
4160 all the modrm processing first, and don't know until now that
4161 we have a bad opcode. This necessitates some cleaning up. */
2da11e11
AM
4162 op1out[0] = '\0';
4163 op2out[0] = '\0';
6608db57 4164 BadOp ();
252b5132
RH
4165 }
4166}
c608c12e 4167
6608db57 4168static const char *simd_cmp_op[] = {
c608c12e
AM
4169 "eq",
4170 "lt",
4171 "le",
4172 "unord",
4173 "neq",
4174 "nlt",
4175 "nle",
4176 "ord"
4177};
4178
4179static void
26ca5450 4180OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
c608c12e
AM
4181{
4182 unsigned int cmp_type;
4183
4184 FETCH_DATA (the_info, codep + 1);
6608db57 4185 obufp = obuf + strlen (obuf);
c608c12e
AM
4186 cmp_type = *codep++ & 0xff;
4187 if (cmp_type < 8)
4188 {
041bd2e0
JH
4189 char suffix1 = 'p', suffix2 = 's';
4190 used_prefixes |= (prefixes & PREFIX_REPZ);
4191 if (prefixes & PREFIX_REPZ)
4192 suffix1 = 's';
4193 else
4194 {
4195 used_prefixes |= (prefixes & PREFIX_DATA);
4196 if (prefixes & PREFIX_DATA)
4197 suffix2 = 'd';
4198 else
4199 {
4200 used_prefixes |= (prefixes & PREFIX_REPNZ);
4201 if (prefixes & PREFIX_REPNZ)
4202 suffix1 = 's', suffix2 = 'd';
4203 }
4204 }
4205 sprintf (scratchbuf, "cmp%s%c%c",
4206 simd_cmp_op[cmp_type], suffix1, suffix2);
7d421014 4207 used_prefixes |= (prefixes & PREFIX_REPZ);
2da11e11 4208 oappend (scratchbuf);
c608c12e
AM
4209 }
4210 else
4211 {
4212 /* We have a bad extension byte. Clean up. */
2da11e11
AM
4213 op1out[0] = '\0';
4214 op2out[0] = '\0';
6608db57 4215 BadOp ();
c608c12e
AM
4216 }
4217}
4218
4219static void
26ca5450 4220SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
c608c12e
AM
4221{
4222 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4223 forms of these instructions. */
4224 if (mod == 3)
4225 {
6608db57
KH
4226 char *p = obuf + strlen (obuf);
4227 *(p + 1) = '\0';
4228 *p = *(p - 1);
4229 *(p - 1) = *(p - 2);
4230 *(p - 2) = *(p - 3);
4231 *(p - 3) = extrachar;
c608c12e
AM
4232 }
4233}
2da11e11 4234
ca164297 4235static void
4fd61dcb 4236PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
ca164297 4237{
1d9f512f 4238 if (mod == 3 && reg == 1 && rm <= 1)
ca164297 4239 {
ca164297 4240 /* Override "sidt". */
1d9f512f
AM
4241 char *p = obuf + strlen (obuf) - 4;
4242
4243 /* We might have a suffix. */
4244 if (*p == 'i')
4245 --p;
4246
ca164297
L
4247 if (rm)
4248 {
4249 /* mwait %eax,%ecx */
1d9f512f 4250 strcpy (p, "mwait");
ca164297
L
4251 }
4252 else
4253 {
4254 /* monitor %eax,%ecx,%edx" */
1d9f512f
AM
4255 strcpy (p, "monitor");
4256 strcpy (op3out, names32[2]);
ca164297 4257 }
1d9f512f
AM
4258 strcpy (op1out, names32[0]);
4259 strcpy (op2out, names32[1]);
4260 two_source_ops = 1;
ca164297
L
4261
4262 codep++;
4263 }
4264 else
4265 OP_E (0, sizeflag);
4266}
4267
4fd61dcb
JJ
4268static void
4269INVLPG_Fixup (int bytemode, int sizeflag)
4270{
4271 if (*codep == 0xf8)
4272 {
4273 char *p = obuf + strlen (obuf);
4274
4275 /* Override "invlpg". */
4276 strcpy (p - 6, "swapgs");
4277 codep++;
4278 }
4279 else
4280 OP_E (bytemode, sizeflag);
4281}
4282
6608db57
KH
4283static void
4284BadOp (void)
2da11e11 4285{
6608db57
KH
4286 /* Throw away prefixes and 1st. opcode byte. */
4287 codep = insn_codep + 1;
2da11e11
AM
4288 oappend ("(bad)");
4289}