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