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