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