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