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