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