]> git.proxmox.com Git - qemu.git/blame - i386-dis.c
Sparc32: convert slavio interrupt controller to qdev
[qemu.git] / i386-dis.c
CommitLineData
88103cfe 1/* opcodes/i386-dis.c r1.126 */
dc99065b 2/* Print i386 instructions for GDB, the GNU debugger.
bc51c5c9 3 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
88103cfe 4 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
dc99065b 5
c2c73b42 6 This file is part of GDB.
dc99065b 7
c2c73b42
BS
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
dc99065b 12
c2c73b42
BS
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
dc99065b 17
c2c73b42
BS
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
dc99065b 21
c2c73b42
BS
22/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 July 1988
24 modified by John Hassey (hassey@dg-rtp.dg.com)
25 x86-64 support added by Jan Hubicka (jh@suse.cz)
26 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
dc99065b 27
c2c73b42
BS
28/* The main tables describing the instructions is essentially a copy
29 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 Programmers Manual. Usually, there is a capital letter, followed
31 by a small letter. The capital letter tell the addressing mode,
32 and the small letter tells about the operand size. Refer to
33 the Intel manual for details. */
dc99065b 34
bb0ebb1f 35#include <stdlib.h>
dc99065b 36#include "dis-asm.h"
88103cfe 37/* include/opcode/i386.h r1.78 */
dc99065b 38
88103cfe
BS
39/* opcode/i386.h -- Intel 80386 opcode macros
40 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
41 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
42 Free Software Foundation, Inc.
dc99065b 43
88103cfe
BS
44 This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
45
46 This program is free software; you can redistribute it and/or modify
47 it under the terms of the GNU General Public License as published by
48 the Free Software Foundation; either version 2 of the License, or
49 (at your option) any later version.
50
51 This program is distributed in the hope that it will be useful,
52 but WITHOUT ANY WARRANTY; without even the implied warranty of
53 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 GNU General Public License for more details.
bc51c5c9 55
88103cfe
BS
56 You should have received a copy of the GNU General Public License
57 along with this program; if not, write to the Free Software
58 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
59
60/* The SystemV/386 SVR3.2 assembler, and probably all AT&T derived
61 ix86 Unix assemblers, generate floating point instructions with
62 reversed source and destination registers in certain cases.
63 Unfortunately, gcc and possibly many other programs use this
64 reversed syntax, so we're stuck with it.
65
66 eg. `fsub %st(3),%st' results in st = st - st(3) as expected, but
67 `fsub %st,%st(3)' results in st(3) = st - st(3), rather than
68 the expected st(3) = st(3) - st
69
70 This happens with all the non-commutative arithmetic floating point
71 operations with two register operands, where the source register is
72 %st, and destination register is %st(i).
73
74 The affected opcode map is dceX, dcfX, deeX, defX. */
75
76#ifndef SYSV386_COMPAT
bc51c5c9 77/* Set non-zero for broken, compatible instructions. Set to zero for
88103cfe
BS
78 non-broken opcodes at your peril. gcc generates SystemV/386
79 compatible instructions. */
80#define SYSV386_COMPAT 1
81#endif
82#ifndef OLDGCC_COMPAT
83/* Set non-zero to cater for old (<= 2.8.1) versions of gcc that could
84 generate nonsense fsubp, fsubrp, fdivp and fdivrp with operands
85 reversed. */
86#define OLDGCC_COMPAT SYSV386_COMPAT
bc51c5c9
FB
87#endif
88
88103cfe
BS
89#define MOV_AX_DISP32 0xa0
90#define POP_SEG_SHORT 0x07
91#define JUMP_PC_RELATIVE 0xeb
92#define INT_OPCODE 0xcd
93#define INT3_OPCODE 0xcc
94/* The opcode for the fwait instruction, which disassembler treats as a
95 prefix when it can. */
96#define FWAIT_OPCODE 0x9b
97#define ADDR_PREFIX_OPCODE 0x67
98#define DATA_PREFIX_OPCODE 0x66
99#define LOCK_PREFIX_OPCODE 0xf0
100#define CS_PREFIX_OPCODE 0x2e
101#define DS_PREFIX_OPCODE 0x3e
102#define ES_PREFIX_OPCODE 0x26
103#define FS_PREFIX_OPCODE 0x64
104#define GS_PREFIX_OPCODE 0x65
105#define SS_PREFIX_OPCODE 0x36
106#define REPNE_PREFIX_OPCODE 0xf2
107#define REPE_PREFIX_OPCODE 0xf3
108
109#define TWO_BYTE_OPCODE_ESCAPE 0x0f
110#define NOP_OPCODE (char) 0x90
111
112/* register numbers */
113#define EBP_REG_NUM 5
114#define ESP_REG_NUM 4
115
116/* modrm_byte.regmem for twobyte escape */
117#define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
118/* index_base_byte.index for no index register addressing */
119#define NO_INDEX_REGISTER ESP_REG_NUM
120/* index_base_byte.base for no base register addressing */
121#define NO_BASE_REGISTER EBP_REG_NUM
122#define NO_BASE_REGISTER_16 6
123
124/* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */
125#define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */
126#define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
127
128/* x86-64 extension prefix. */
129#define REX_OPCODE 0x40
130
131/* Indicates 64 bit operand size. */
132#define REX_W 8
133/* High extension to reg field of modrm byte. */
134#define REX_R 4
135/* High extension to SIB index field. */
136#define REX_X 2
137/* High extension to base field of modrm or SIB, or reg field of opcode. */
138#define REX_B 1
139
140/* max operands per insn */
141#define MAX_OPERANDS 4
142
143/* max immediates per insn (lcall, ljmp, insertq, extrq) */
144#define MAX_IMMEDIATE_OPERANDS 2
145
146/* max memory refs per insn (string ops) */
147#define MAX_MEMORY_OPERANDS 2
148
149/* max size of insn mnemonics. */
150#define MAX_MNEM_SIZE 16
151
152/* max size of register name in insn mnemonics. */
153#define MAX_REG_NAME_SIZE 8
154
155/* opcodes/i386-dis.c r1.126 */
156#include "qemu-common.h"
157
158#include <setjmp.h>
159
c2c73b42
BS
160static int fetch_data (struct disassemble_info *, bfd_byte *);
161static void ckprefix (void);
162static const char *prefix_name (int, int);
163static int print_insn (bfd_vma, disassemble_info *);
164static void dofloat (int);
165static void OP_ST (int, int);
166static void OP_STi (int, int);
167static int putop (const char *, int);
168static void oappend (const char *);
169static void append_seg (void);
170static void OP_indirE (int, int);
171static void print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp);
88103cfe 172static void print_displacement (char *, bfd_vma);
c2c73b42
BS
173static void OP_E (int, int);
174static void OP_G (int, int);
175static bfd_vma get64 (void);
176static bfd_signed_vma get32 (void);
177static bfd_signed_vma get32s (void);
178static int get16 (void);
179static void set_op (bfd_vma, int);
180static void OP_REG (int, int);
181static void OP_IMREG (int, int);
182static void OP_I (int, int);
183static void OP_I64 (int, int);
184static void OP_sI (int, int);
185static void OP_J (int, int);
186static void OP_SEG (int, int);
187static void OP_DIR (int, int);
188static void OP_OFF (int, int);
189static void OP_OFF64 (int, int);
190static void ptr_reg (int, int);
191static void OP_ESreg (int, int);
192static void OP_DSreg (int, int);
193static void OP_C (int, int);
194static void OP_D (int, int);
195static void OP_T (int, int);
88103cfe 196static void OP_R (int, int);
c2c73b42
BS
197static void OP_MMX (int, int);
198static void OP_XMM (int, int);
199static void OP_EM (int, int);
200static void OP_EX (int, int);
88103cfe
BS
201static void OP_EMC (int,int);
202static void OP_MXC (int,int);
c2c73b42
BS
203static void OP_MS (int, int);
204static void OP_XS (int, int);
205static void OP_M (int, int);
206static void OP_VMX (int, int);
207static void OP_0fae (int, int);
208static void OP_0f07 (int, int);
88103cfe
BS
209static void NOP_Fixup1 (int, int);
210static void NOP_Fixup2 (int, int);
c2c73b42
BS
211static void OP_3DNowSuffix (int, int);
212static void OP_SIMD_Suffix (int, int);
213static void SIMD_Fixup (int, int);
214static void PNI_Fixup (int, int);
215static void SVME_Fixup (int, int);
216static void INVLPG_Fixup (int, int);
217static void BadOp (void);
c2c73b42
BS
218static void VMX_Fixup (int, int);
219static void REP_Fixup (int, int);
88103cfe
BS
220static void CMPXCHG8B_Fixup (int, int);
221static void XMM_Fixup (int, int);
222static void CRC32_Fixup (int, int);
dc99065b 223
bc51c5c9 224struct dis_private {
dc99065b
FB
225 /* Points to first byte not fetched. */
226 bfd_byte *max_fetched;
88103cfe 227 bfd_byte the_buffer[MAX_MNEM_SIZE];
dc99065b 228 bfd_vma insn_start;
bc51c5c9 229 int orig_sizeflag;
dc99065b
FB
230 jmp_buf bailout;
231};
232
c2c73b42
BS
233enum address_mode
234{
235 mode_16bit,
236 mode_32bit,
237 mode_64bit
238};
239
240static enum address_mode address_mode;
bc51c5c9
FB
241
242/* Flags for the prefixes for the current instruction. See below. */
243static int prefixes;
244
245/* REX prefix the current instruction. See below. */
246static int rex;
247/* Bits of REX we've already used. */
248static int rex_used;
bc51c5c9
FB
249/* Mark parts used in the REX prefix. When we are testing for
250 empty prefix (for 8bit register REX extension), just mask it
251 out. Otherwise test for REX bit is excuse for existence of REX
252 only in case value is nonzero. */
253#define USED_REX(value) \
254 { \
255 if (value) \
88103cfe
BS
256 { \
257 if ((rex & value)) \
258 rex_used |= (value) | REX_OPCODE; \
259 } \
bc51c5c9 260 else \
88103cfe 261 rex_used |= REX_OPCODE; \
bc51c5c9
FB
262 }
263
264/* Flags for prefixes which we somehow handled when printing the
265 current instruction. */
266static int used_prefixes;
267
268/* Flags stored in PREFIXES. */
269#define PREFIX_REPZ 1
270#define PREFIX_REPNZ 2
271#define PREFIX_LOCK 4
272#define PREFIX_CS 8
273#define PREFIX_SS 0x10
274#define PREFIX_DS 0x20
275#define PREFIX_ES 0x40
276#define PREFIX_FS 0x80
277#define PREFIX_GS 0x100
278#define PREFIX_DATA 0x200
279#define PREFIX_ADDR 0x400
280#define PREFIX_FWAIT 0x800
281
dc99065b
FB
282/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
283 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
284 on error. */
285#define FETCH_DATA(info, addr) \
bc51c5c9 286 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
dc99065b
FB
287 ? 1 : fetch_data ((info), (addr)))
288
289static int
c2c73b42 290fetch_data (struct disassemble_info *info, bfd_byte *addr)
dc99065b
FB
291{
292 int status;
bc51c5c9 293 struct dis_private *priv = (struct dis_private *) info->private_data;
dc99065b
FB
294 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
295
88103cfe 296 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
c2c73b42
BS
297 status = (*info->read_memory_func) (start,
298 priv->max_fetched,
299 addr - priv->max_fetched,
300 info);
301 else
302 status = -1;
dc99065b
FB
303 if (status != 0)
304 {
bc51c5c9 305 /* If we did manage to read at least one byte, then
c2c73b42
BS
306 print_insn_i386 will do something sensible. Otherwise, print
307 an error. We do that here because this is where we know
308 STATUS. */
bc51c5c9
FB
309 if (priv->max_fetched == priv->the_buffer)
310 (*info->memory_error_func) (status, start, info);
dc99065b
FB
311 longjmp (priv->bailout, 1);
312 }
313 else
314 priv->max_fetched = addr;
315 return 1;
316}
317
88103cfe
BS
318#define XX { NULL, 0 }
319
320#define Eb { OP_E, b_mode }
321#define Ev { OP_E, v_mode }
322#define Ed { OP_E, d_mode }
323#define Edq { OP_E, dq_mode }
324#define Edqw { OP_E, dqw_mode }
325#define Edqb { OP_E, dqb_mode }
326#define Edqd { OP_E, dqd_mode }
327#define indirEv { OP_indirE, stack_v_mode }
328#define indirEp { OP_indirE, f_mode }
329#define stackEv { OP_E, stack_v_mode }
330#define Em { OP_E, m_mode }
331#define Ew { OP_E, w_mode }
332#define M { OP_M, 0 } /* lea, lgdt, etc. */
333#define Ma { OP_M, v_mode }
334#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
335#define Mq { OP_M, q_mode }
336#define Gb { OP_G, b_mode }
337#define Gv { OP_G, v_mode }
338#define Gd { OP_G, d_mode }
339#define Gdq { OP_G, dq_mode }
340#define Gm { OP_G, m_mode }
341#define Gw { OP_G, w_mode }
342#define Rd { OP_R, d_mode }
343#define Rm { OP_R, m_mode }
344#define Ib { OP_I, b_mode }
345#define sIb { OP_sI, b_mode } /* sign extened byte */
346#define Iv { OP_I, v_mode }
347#define Iq { OP_I, q_mode }
348#define Iv64 { OP_I64, v_mode }
349#define Iw { OP_I, w_mode }
350#define I1 { OP_I, const_1_mode }
351#define Jb { OP_J, b_mode }
352#define Jv { OP_J, v_mode }
353#define Cm { OP_C, m_mode }
354#define Dm { OP_D, m_mode }
355#define Td { OP_T, d_mode }
356
357#define RMeAX { OP_REG, eAX_reg }
358#define RMeBX { OP_REG, eBX_reg }
359#define RMeCX { OP_REG, eCX_reg }
360#define RMeDX { OP_REG, eDX_reg }
361#define RMeSP { OP_REG, eSP_reg }
362#define RMeBP { OP_REG, eBP_reg }
363#define RMeSI { OP_REG, eSI_reg }
364#define RMeDI { OP_REG, eDI_reg }
365#define RMrAX { OP_REG, rAX_reg }
366#define RMrBX { OP_REG, rBX_reg }
367#define RMrCX { OP_REG, rCX_reg }
368#define RMrDX { OP_REG, rDX_reg }
369#define RMrSP { OP_REG, rSP_reg }
370#define RMrBP { OP_REG, rBP_reg }
371#define RMrSI { OP_REG, rSI_reg }
372#define RMrDI { OP_REG, rDI_reg }
373#define RMAL { OP_REG, al_reg }
374#define RMAL { OP_REG, al_reg }
375#define RMCL { OP_REG, cl_reg }
376#define RMDL { OP_REG, dl_reg }
377#define RMBL { OP_REG, bl_reg }
378#define RMAH { OP_REG, ah_reg }
379#define RMCH { OP_REG, ch_reg }
380#define RMDH { OP_REG, dh_reg }
381#define RMBH { OP_REG, bh_reg }
382#define RMAX { OP_REG, ax_reg }
383#define RMDX { OP_REG, dx_reg }
384
385#define eAX { OP_IMREG, eAX_reg }
386#define eBX { OP_IMREG, eBX_reg }
387#define eCX { OP_IMREG, eCX_reg }
388#define eDX { OP_IMREG, eDX_reg }
389#define eSP { OP_IMREG, eSP_reg }
390#define eBP { OP_IMREG, eBP_reg }
391#define eSI { OP_IMREG, eSI_reg }
392#define eDI { OP_IMREG, eDI_reg }
393#define AL { OP_IMREG, al_reg }
394#define CL { OP_IMREG, cl_reg }
395#define DL { OP_IMREG, dl_reg }
396#define BL { OP_IMREG, bl_reg }
397#define AH { OP_IMREG, ah_reg }
398#define CH { OP_IMREG, ch_reg }
399#define DH { OP_IMREG, dh_reg }
400#define BH { OP_IMREG, bh_reg }
401#define AX { OP_IMREG, ax_reg }
402#define DX { OP_IMREG, dx_reg }
403#define zAX { OP_IMREG, z_mode_ax_reg }
404#define indirDX { OP_IMREG, indir_dx_reg }
405
406#define Sw { OP_SEG, w_mode }
407#define Sv { OP_SEG, v_mode }
408#define Ap { OP_DIR, 0 }
409#define Ob { OP_OFF64, b_mode }
410#define Ov { OP_OFF64, v_mode }
411#define Xb { OP_DSreg, eSI_reg }
412#define Xv { OP_DSreg, eSI_reg }
413#define Xz { OP_DSreg, eSI_reg }
414#define Yb { OP_ESreg, eDI_reg }
415#define Yv { OP_ESreg, eDI_reg }
416#define DSBX { OP_DSreg, eBX_reg }
417
418#define es { OP_REG, es_reg }
419#define ss { OP_REG, ss_reg }
420#define cs { OP_REG, cs_reg }
421#define ds { OP_REG, ds_reg }
422#define fs { OP_REG, fs_reg }
423#define gs { OP_REG, gs_reg }
424
425#define MX { OP_MMX, 0 }
426#define XM { OP_XMM, 0 }
427#define EM { OP_EM, v_mode }
428#define EMd { OP_EM, d_mode }
429#define EMq { OP_EM, q_mode }
430#define EXd { OP_EX, d_mode }
431#define EXq { OP_EX, q_mode }
432#define EXx { OP_EX, x_mode }
433#define MS { OP_MS, v_mode }
434#define XS { OP_XS, v_mode }
435#define EMC { OP_EMC, v_mode }
436#define MXC { OP_MXC, 0 }
437#define VM { OP_VMX, q_mode }
438#define OPSUF { OP_3DNowSuffix, 0 }
439#define OPSIMD { OP_SIMD_Suffix, 0 }
440#define XMM0 { XMM_Fixup, 0 }
bc51c5c9 441
c2c73b42 442/* Used handle "rep" prefix for string instructions. */
88103cfe
BS
443#define Xbr { REP_Fixup, eSI_reg }
444#define Xvr { REP_Fixup, eSI_reg }
445#define Ybr { REP_Fixup, eDI_reg }
446#define Yvr { REP_Fixup, eDI_reg }
447#define Yzr { REP_Fixup, eDI_reg }
448#define indirDXr { REP_Fixup, indir_dx_reg }
449#define ALr { REP_Fixup, al_reg }
450#define eAXr { REP_Fixup, eAX_reg }
451
452#define cond_jump_flag { NULL, cond_jump_mode }
453#define loop_jcxz_flag { NULL, loop_jcxz_mode }
bc51c5c9
FB
454
455/* bits in sizeflag */
456#define SUFFIX_ALWAYS 4
457#define AFLAG 2
458#define DFLAG 1
dc99065b 459
bc51c5c9
FB
460#define b_mode 1 /* byte operand */
461#define v_mode 2 /* operand size depends on prefixes */
462#define w_mode 3 /* word operand */
463#define d_mode 4 /* double word operand */
464#define q_mode 5 /* quad word operand */
c2c73b42
BS
465#define t_mode 6 /* ten-byte operand */
466#define x_mode 7 /* 16-byte XMM operand */
467#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
468#define cond_jump_mode 9
469#define loop_jcxz_mode 10
470#define dq_mode 11 /* operand size depends on REX prefixes. */
471#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
472#define f_mode 13 /* 4- or 6-byte pointer operand */
473#define const_1_mode 14
474#define stack_v_mode 15 /* v_mode for stack-related opcodes. */
88103cfe
BS
475#define z_mode 16 /* non-quad operand size depends on prefixes */
476#define o_mode 17 /* 16-byte operand */
477#define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
478#define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
dc99065b
FB
479
480#define es_reg 100
481#define cs_reg 101
482#define ss_reg 102
483#define ds_reg 103
484#define fs_reg 104
485#define gs_reg 105
dc99065b 486
bc51c5c9
FB
487#define eAX_reg 108
488#define eCX_reg 109
489#define eDX_reg 110
490#define eBX_reg 111
491#define eSP_reg 112
492#define eBP_reg 113
493#define eSI_reg 114
494#define eDI_reg 115
dc99065b
FB
495
496#define al_reg 116
497#define cl_reg 117
498#define dl_reg 118
499#define bl_reg 119
500#define ah_reg 120
501#define ch_reg 121
502#define dh_reg 122
503#define bh_reg 123
504
505#define ax_reg 124
506#define cx_reg 125
507#define dx_reg 126
508#define bx_reg 127
509#define sp_reg 128
510#define bp_reg 129
511#define si_reg 130
512#define di_reg 131
513
bc51c5c9
FB
514#define rAX_reg 132
515#define rCX_reg 133
516#define rDX_reg 134
517#define rBX_reg 135
518#define rSP_reg 136
519#define rBP_reg 137
520#define rSI_reg 138
521#define rDI_reg 139
522
88103cfe 523#define z_mode_ax_reg 149
dc99065b
FB
524#define indir_dx_reg 150
525
bc51c5c9
FB
526#define FLOATCODE 1
527#define USE_GROUPS 2
528#define USE_PREFIX_USER_TABLE 3
529#define X86_64_SPECIAL 4
c2c73b42 530#define IS_3BYTE_OPCODE 5
bc51c5c9 531
88103cfe
BS
532#define FLOAT NULL, { { NULL, FLOATCODE } }
533
534#define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
535#define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
536#define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
537#define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
538#define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
539#define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
540#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
541#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
542#define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
543#define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
544#define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
545#define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
546#define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
547#define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
548#define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
549#define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
550#define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
551#define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
552#define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
553#define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
554#define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
555#define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
556#define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
557#define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
558#define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
559#define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
560#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
561#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
562
563#define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
564#define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
565#define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
566#define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
567#define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
568#define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
569#define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
570#define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
571#define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
572#define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
573#define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
574#define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
575#define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
576#define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
577#define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
578#define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
579#define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
580#define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
581#define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
582#define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
583#define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
584#define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
585#define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
586#define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
587#define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
588#define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
589#define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
590#define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
591#define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
592#define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
593#define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
594#define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
595#define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
596#define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
597#define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
598#define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
599#define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
600#define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
601#define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
602#define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
603#define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
604#define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
605#define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
606#define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
607#define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
608#define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
609#define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
610#define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
611#define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
612#define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
613#define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
614#define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
615#define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
616#define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
617#define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
618#define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
619#define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
620#define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
621#define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
622#define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
623#define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
624#define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
625#define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
626#define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
627#define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
628#define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
629#define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
630#define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
631#define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
632#define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
633#define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
634#define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
635#define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
636#define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
637#define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
638#define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
639#define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
640#define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
641#define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
642#define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
643#define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
644#define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
645#define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
646#define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
647#define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
648#define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
649#define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
650#define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
651#define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
652#define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
653#define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
654#define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
655#define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
656#define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
657#define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
658#define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
659#define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
660#define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
661
662
663#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
664#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
665#define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
666#define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
667
668#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
669#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
c2c73b42
BS
670
671typedef void (*op_rtn) (int bytemode, int sizeflag);
dc99065b
FB
672
673struct dis386 {
bc51c5c9 674 const char *name;
88103cfe
BS
675 struct
676 {
677 op_rtn rtn;
678 int bytemode;
679 } op[MAX_OPERANDS];
dc99065b
FB
680};
681
bc51c5c9
FB
682/* Upper case letters in the instruction names here are macros.
683 'A' => print 'b' if no register operands or suffix_always is true
684 'B' => print 'b' if suffix_always is true
c2c73b42
BS
685 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
686 . size prefix
88103cfe
BS
687 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
688 . suffix_always is true
bc51c5c9
FB
689 'E' => print 'e' if 32-bit form of jcxz
690 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
88103cfe 691 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
bc51c5c9 692 'H' => print ",pt" or ",pn" branch hint
c2c73b42
BS
693 'I' => honor following macro letter even in Intel mode (implemented only
694 . for some of the macro letters)
695 'J' => print 'l'
88103cfe 696 'K' => print 'd' or 'q' if rex prefix is present.
bc51c5c9
FB
697 'L' => print 'l' if suffix_always is true
698 'N' => print 'n' if instruction has no wait "prefix"
88103cfe 699 'O' => print 'd' or 'o' (or 'q' in Intel mode)
bc51c5c9
FB
700 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
701 . or suffix_always is true. print 'q' if rex prefix is present.
702 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
703 . is true
88103cfe 704 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
bc51c5c9
FB
705 'S' => print 'w', 'l' or 'q' if suffix_always is true
706 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
707 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
c2c73b42 708 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
88103cfe 709 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
c2c73b42 710 'X' => print 's', 'd' depending on data16 prefix (for XMM)
bc51c5c9 711 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
c2c73b42 712 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
bc51c5c9
FB
713
714 Many of the above letters print nothing in Intel mode. See "putop"
715 for the details.
716
717 Braces '{' and '}', and vertical bars '|', indicate alternative
718 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
719 modes. In cases where there are only two alternatives, the X86_64
720 instruction is reserved, and "(bad)" is printed.
721*/
722
723static const struct dis386 dis386[] = {
dc99065b 724 /* 00 */
88103cfe
BS
725 { "addB", { Eb, Gb } },
726 { "addS", { Ev, Gv } },
727 { "addB", { Gb, Eb } },
728 { "addS", { Gv, Ev } },
729 { "addB", { AL, Ib } },
730 { "addS", { eAX, Iv } },
731 { "push{T|}", { es } },
732 { "pop{T|}", { es } },
dc99065b 733 /* 08 */
88103cfe
BS
734 { "orB", { Eb, Gb } },
735 { "orS", { Ev, Gv } },
736 { "orB", { Gb, Eb } },
737 { "orS", { Gv, Ev } },
738 { "orB", { AL, Ib } },
739 { "orS", { eAX, Iv } },
740 { "push{T|}", { cs } },
741 { "(bad)", { XX } }, /* 0x0f extended opcode escape */
dc99065b 742 /* 10 */
88103cfe
BS
743 { "adcB", { Eb, Gb } },
744 { "adcS", { Ev, Gv } },
745 { "adcB", { Gb, Eb } },
746 { "adcS", { Gv, Ev } },
747 { "adcB", { AL, Ib } },
748 { "adcS", { eAX, Iv } },
749 { "push{T|}", { ss } },
750 { "pop{T|}", { ss } },
dc99065b 751 /* 18 */
88103cfe
BS
752 { "sbbB", { Eb, Gb } },
753 { "sbbS", { Ev, Gv } },
754 { "sbbB", { Gb, Eb } },
755 { "sbbS", { Gv, Ev } },
756 { "sbbB", { AL, Ib } },
757 { "sbbS", { eAX, Iv } },
758 { "push{T|}", { ds } },
759 { "pop{T|}", { ds } },
dc99065b 760 /* 20 */
88103cfe
BS
761 { "andB", { Eb, Gb } },
762 { "andS", { Ev, Gv } },
763 { "andB", { Gb, Eb } },
764 { "andS", { Gv, Ev } },
765 { "andB", { AL, Ib } },
766 { "andS", { eAX, Iv } },
767 { "(bad)", { XX } }, /* SEG ES prefix */
768 { "daa{|}", { XX } },
dc99065b 769 /* 28 */
88103cfe
BS
770 { "subB", { Eb, Gb } },
771 { "subS", { Ev, Gv } },
772 { "subB", { Gb, Eb } },
773 { "subS", { Gv, Ev } },
774 { "subB", { AL, Ib } },
775 { "subS", { eAX, Iv } },
776 { "(bad)", { XX } }, /* SEG CS prefix */
777 { "das{|}", { XX } },
dc99065b 778 /* 30 */
88103cfe
BS
779 { "xorB", { Eb, Gb } },
780 { "xorS", { Ev, Gv } },
781 { "xorB", { Gb, Eb } },
782 { "xorS", { Gv, Ev } },
783 { "xorB", { AL, Ib } },
784 { "xorS", { eAX, Iv } },
785 { "(bad)", { XX } }, /* SEG SS prefix */
786 { "aaa{|}", { XX } },
dc99065b 787 /* 38 */
88103cfe
BS
788 { "cmpB", { Eb, Gb } },
789 { "cmpS", { Ev, Gv } },
790 { "cmpB", { Gb, Eb } },
791 { "cmpS", { Gv, Ev } },
792 { "cmpB", { AL, Ib } },
793 { "cmpS", { eAX, Iv } },
794 { "(bad)", { XX } }, /* SEG DS prefix */
795 { "aas{|}", { XX } },
dc99065b 796 /* 40 */
88103cfe
BS
797 { "inc{S|}", { RMeAX } },
798 { "inc{S|}", { RMeCX } },
799 { "inc{S|}", { RMeDX } },
800 { "inc{S|}", { RMeBX } },
801 { "inc{S|}", { RMeSP } },
802 { "inc{S|}", { RMeBP } },
803 { "inc{S|}", { RMeSI } },
804 { "inc{S|}", { RMeDI } },
dc99065b 805 /* 48 */
88103cfe
BS
806 { "dec{S|}", { RMeAX } },
807 { "dec{S|}", { RMeCX } },
808 { "dec{S|}", { RMeDX } },
809 { "dec{S|}", { RMeBX } },
810 { "dec{S|}", { RMeSP } },
811 { "dec{S|}", { RMeBP } },
812 { "dec{S|}", { RMeSI } },
813 { "dec{S|}", { RMeDI } },
dc99065b 814 /* 50 */
88103cfe
BS
815 { "pushV", { RMrAX } },
816 { "pushV", { RMrCX } },
817 { "pushV", { RMrDX } },
818 { "pushV", { RMrBX } },
819 { "pushV", { RMrSP } },
820 { "pushV", { RMrBP } },
821 { "pushV", { RMrSI } },
822 { "pushV", { RMrDI } },
dc99065b 823 /* 58 */
88103cfe
BS
824 { "popV", { RMrAX } },
825 { "popV", { RMrCX } },
826 { "popV", { RMrDX } },
827 { "popV", { RMrBX } },
828 { "popV", { RMrSP } },
829 { "popV", { RMrBP } },
830 { "popV", { RMrSI } },
831 { "popV", { RMrDI } },
dc99065b 832 /* 60 */
bc51c5c9 833 { X86_64_0 },
88103cfe
BS
834 { X86_64_1 },
835 { X86_64_2 },
836 { X86_64_3 },
837 { "(bad)", { XX } }, /* seg fs */
838 { "(bad)", { XX } }, /* seg gs */
839 { "(bad)", { XX } }, /* op size prefix */
840 { "(bad)", { XX } }, /* adr size prefix */
dc99065b 841 /* 68 */
88103cfe
BS
842 { "pushT", { Iq } },
843 { "imulS", { Gv, Ev, Iv } },
844 { "pushT", { sIb } },
845 { "imulS", { Gv, Ev, sIb } },
846 { "ins{b||b|}", { Ybr, indirDX } },
847 { "ins{R||G|}", { Yzr, indirDX } },
848 { "outs{b||b|}", { indirDXr, Xb } },
849 { "outs{R||G|}", { indirDXr, Xz } },
dc99065b 850 /* 70 */
88103cfe
BS
851 { "joH", { Jb, XX, cond_jump_flag } },
852 { "jnoH", { Jb, XX, cond_jump_flag } },
853 { "jbH", { Jb, XX, cond_jump_flag } },
854 { "jaeH", { Jb, XX, cond_jump_flag } },
855 { "jeH", { Jb, XX, cond_jump_flag } },
856 { "jneH", { Jb, XX, cond_jump_flag } },
857 { "jbeH", { Jb, XX, cond_jump_flag } },
858 { "jaH", { Jb, XX, cond_jump_flag } },
dc99065b 859 /* 78 */
88103cfe
BS
860 { "jsH", { Jb, XX, cond_jump_flag } },
861 { "jnsH", { Jb, XX, cond_jump_flag } },
862 { "jpH", { Jb, XX, cond_jump_flag } },
863 { "jnpH", { Jb, XX, cond_jump_flag } },
864 { "jlH", { Jb, XX, cond_jump_flag } },
865 { "jgeH", { Jb, XX, cond_jump_flag } },
866 { "jleH", { Jb, XX, cond_jump_flag } },
867 { "jgH", { Jb, XX, cond_jump_flag } },
dc99065b
FB
868 /* 80 */
869 { GRP1b },
870 { GRP1S },
88103cfe 871 { "(bad)", { XX } },
dc99065b 872 { GRP1Ss },
88103cfe
BS
873 { "testB", { Eb, Gb } },
874 { "testS", { Ev, Gv } },
875 { "xchgB", { Eb, Gb } },
876 { "xchgS", { Ev, Gv } },
dc99065b 877 /* 88 */
88103cfe
BS
878 { "movB", { Eb, Gb } },
879 { "movS", { Ev, Gv } },
880 { "movB", { Gb, Eb } },
881 { "movS", { Gv, Ev } },
882 { "movD", { Sv, Sw } },
883 { "leaS", { Gv, M } },
884 { "movD", { Sw, Sv } },
885 { GRP1a },
dc99065b 886 /* 90 */
88103cfe
BS
887 { PREGRP38 },
888 { "xchgS", { RMeCX, eAX } },
889 { "xchgS", { RMeDX, eAX } },
890 { "xchgS", { RMeBX, eAX } },
891 { "xchgS", { RMeSP, eAX } },
892 { "xchgS", { RMeBP, eAX } },
893 { "xchgS", { RMeSI, eAX } },
894 { "xchgS", { RMeDI, eAX } },
dc99065b 895 /* 98 */
88103cfe
BS
896 { "cW{t||t|}R", { XX } },
897 { "cR{t||t|}O", { XX } },
898 { "Jcall{T|}", { Ap } },
899 { "(bad)", { XX } }, /* fwait */
900 { "pushfT", { XX } },
901 { "popfT", { XX } },
902 { "sahf{|}", { XX } },
903 { "lahf{|}", { XX } },
dc99065b 904 /* a0 */
88103cfe
BS
905 { "movB", { AL, Ob } },
906 { "movS", { eAX, Ov } },
907 { "movB", { Ob, AL } },
908 { "movS", { Ov, eAX } },
909 { "movs{b||b|}", { Ybr, Xb } },
910 { "movs{R||R|}", { Yvr, Xv } },
911 { "cmps{b||b|}", { Xb, Yb } },
912 { "cmps{R||R|}", { Xv, Yv } },
dc99065b 913 /* a8 */
88103cfe
BS
914 { "testB", { AL, Ib } },
915 { "testS", { eAX, Iv } },
916 { "stosB", { Ybr, AL } },
917 { "stosS", { Yvr, eAX } },
918 { "lodsB", { ALr, Xb } },
919 { "lodsS", { eAXr, Xv } },
920 { "scasB", { AL, Yb } },
921 { "scasS", { eAX, Yv } },
dc99065b 922 /* b0 */
88103cfe
BS
923 { "movB", { RMAL, Ib } },
924 { "movB", { RMCL, Ib } },
925 { "movB", { RMDL, Ib } },
926 { "movB", { RMBL, Ib } },
927 { "movB", { RMAH, Ib } },
928 { "movB", { RMCH, Ib } },
929 { "movB", { RMDH, Ib } },
930 { "movB", { RMBH, Ib } },
dc99065b 931 /* b8 */
88103cfe
BS
932 { "movS", { RMeAX, Iv64 } },
933 { "movS", { RMeCX, Iv64 } },
934 { "movS", { RMeDX, Iv64 } },
935 { "movS", { RMeBX, Iv64 } },
936 { "movS", { RMeSP, Iv64 } },
937 { "movS", { RMeBP, Iv64 } },
938 { "movS", { RMeSI, Iv64 } },
939 { "movS", { RMeDI, Iv64 } },
dc99065b
FB
940 /* c0 */
941 { GRP2b },
942 { GRP2S },
88103cfe
BS
943 { "retT", { Iw } },
944 { "retT", { XX } },
945 { "les{S|}", { Gv, Mp } },
946 { "ldsS", { Gv, Mp } },
947 { GRP11_C6 },
948 { GRP11_C7 },
dc99065b 949 /* c8 */
88103cfe
BS
950 { "enterT", { Iw, Ib } },
951 { "leaveT", { XX } },
952 { "lretP", { Iw } },
953 { "lretP", { XX } },
954 { "int3", { XX } },
955 { "int", { Ib } },
956 { "into{|}", { XX } },
957 { "iretP", { XX } },
dc99065b
FB
958 /* d0 */
959 { GRP2b_one },
960 { GRP2S_one },
961 { GRP2b_cl },
962 { GRP2S_cl },
88103cfe
BS
963 { "aam{|}", { sIb } },
964 { "aad{|}", { sIb } },
965 { "(bad)", { XX } },
966 { "xlat", { DSBX } },
dc99065b
FB
967 /* d8 */
968 { FLOAT },
969 { FLOAT },
970 { FLOAT },
971 { FLOAT },
972 { FLOAT },
973 { FLOAT },
974 { FLOAT },
975 { FLOAT },
976 /* e0 */
88103cfe
BS
977 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
978 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
979 { "loopFH", { Jb, XX, loop_jcxz_flag } },
980 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
981 { "inB", { AL, Ib } },
982 { "inG", { zAX, Ib } },
983 { "outB", { Ib, AL } },
984 { "outG", { Ib, zAX } },
dc99065b 985 /* e8 */
88103cfe
BS
986 { "callT", { Jv } },
987 { "jmpT", { Jv } },
988 { "Jjmp{T|}", { Ap } },
989 { "jmp", { Jb } },
990 { "inB", { AL, indirDX } },
991 { "inG", { zAX, indirDX } },
992 { "outB", { indirDX, AL } },
993 { "outG", { indirDX, zAX } },
dc99065b 994 /* f0 */
88103cfe
BS
995 { "(bad)", { XX } }, /* lock prefix */
996 { "icebp", { XX } },
997 { "(bad)", { XX } }, /* repne */
998 { "(bad)", { XX } }, /* repz */
999 { "hlt", { XX } },
1000 { "cmc", { XX } },
dc99065b
FB
1001 { GRP3b },
1002 { GRP3S },
1003 /* f8 */
88103cfe
BS
1004 { "clc", { XX } },
1005 { "stc", { XX } },
1006 { "cli", { XX } },
1007 { "sti", { XX } },
1008 { "cld", { XX } },
1009 { "std", { XX } },
dc99065b
FB
1010 { GRP4 },
1011 { GRP5 },
1012};
1013
bc51c5c9 1014static const struct dis386 dis386_twobyte[] = {
dc99065b
FB
1015 /* 00 */
1016 { GRP6 },
1017 { GRP7 },
88103cfe
BS
1018 { "larS", { Gv, Ew } },
1019 { "lslS", { Gv, Ew } },
1020 { "(bad)", { XX } },
1021 { "syscall", { XX } },
1022 { "clts", { XX } },
1023 { "sysretP", { XX } },
dc99065b 1024 /* 08 */
88103cfe
BS
1025 { "invd", { XX } },
1026 { "wbinvd", { XX } },
1027 { "(bad)", { XX } },
1028 { "ud2a", { XX } },
1029 { "(bad)", { XX } },
bc51c5c9 1030 { GRPAMD },
88103cfe
BS
1031 { "femms", { XX } },
1032 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
dc99065b 1033 /* 10 */
bc51c5c9
FB
1034 { PREGRP8 },
1035 { PREGRP9 },
c2c73b42 1036 { PREGRP30 },
88103cfe
BS
1037 { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } },
1038 { "unpcklpX", { XM, EXq } },
1039 { "unpckhpX", { XM, EXq } },
c2c73b42 1040 { PREGRP31 },
88103cfe 1041 { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } },
dc99065b 1042 /* 18 */
88103cfe
BS
1043 { GRP16 },
1044 { "(bad)", { XX } },
1045 { "(bad)", { XX } },
1046 { "(bad)", { XX } },
1047 { "(bad)", { XX } },
1048 { "(bad)", { XX } },
1049 { "(bad)", { XX } },
1050 { "nopQ", { Ev } },
dc99065b 1051 /* 20 */
88103cfe
BS
1052 { "movZ", { Rm, Cm } },
1053 { "movZ", { Rm, Dm } },
1054 { "movZ", { Cm, Rm } },
1055 { "movZ", { Dm, Rm } },
1056 { "movL", { Rd, Td } },
1057 { "(bad)", { XX } },
1058 { "movL", { Td, Rd } },
1059 { "(bad)", { XX } },
dc99065b 1060 /* 28 */
88103cfe
BS
1061 { "movapX", { XM, EXx } },
1062 { "movapX", { EXx, XM } },
bc51c5c9 1063 { PREGRP2 },
88103cfe 1064 { PREGRP33 },
bc51c5c9
FB
1065 { PREGRP4 },
1066 { PREGRP3 },
88103cfe
BS
1067 { PREGRP93 },
1068 { PREGRP94 },
dc99065b 1069 /* 30 */
88103cfe
BS
1070 { "wrmsr", { XX } },
1071 { "rdtsc", { XX } },
1072 { "rdmsr", { XX } },
1073 { "rdpmc", { XX } },
1074 { "sysenter", { XX } },
1075 { "sysexit", { XX } },
1076 { "(bad)", { XX } },
1077 { "(bad)", { XX } },
dc99065b 1078 /* 38 */
c2c73b42 1079 { THREE_BYTE_0 },
88103cfe 1080 { "(bad)", { XX } },
c2c73b42 1081 { THREE_BYTE_1 },
88103cfe
BS
1082 { "(bad)", { XX } },
1083 { "(bad)", { XX } },
1084 { "(bad)", { XX } },
1085 { "(bad)", { XX } },
1086 { "(bad)", { XX } },
dc99065b 1087 /* 40 */
88103cfe
BS
1088 { "cmovo", { Gv, Ev } },
1089 { "cmovno", { Gv, Ev } },
1090 { "cmovb", { Gv, Ev } },
1091 { "cmovae", { Gv, Ev } },
1092 { "cmove", { Gv, Ev } },
1093 { "cmovne", { Gv, Ev } },
1094 { "cmovbe", { Gv, Ev } },
1095 { "cmova", { Gv, Ev } },
dc99065b 1096 /* 48 */
88103cfe
BS
1097 { "cmovs", { Gv, Ev } },
1098 { "cmovns", { Gv, Ev } },
1099 { "cmovp", { Gv, Ev } },
1100 { "cmovnp", { Gv, Ev } },
1101 { "cmovl", { Gv, Ev } },
1102 { "cmovge", { Gv, Ev } },
1103 { "cmovle", { Gv, Ev } },
1104 { "cmovg", { Gv, Ev } },
dc99065b 1105 /* 50 */
88103cfe 1106 { "movmskpX", { Gdq, XS } },
bc51c5c9
FB
1107 { PREGRP13 },
1108 { PREGRP12 },
1109 { PREGRP11 },
88103cfe
BS
1110 { "andpX", { XM, EXx } },
1111 { "andnpX", { XM, EXx } },
1112 { "orpX", { XM, EXx } },
1113 { "xorpX", { XM, EXx } },
dc99065b 1114 /* 58 */
bc51c5c9
FB
1115 { PREGRP0 },
1116 { PREGRP10 },
1117 { PREGRP17 },
1118 { PREGRP16 },
1119 { PREGRP14 },
1120 { PREGRP7 },
1121 { PREGRP5 },
1122 { PREGRP6 },
dc99065b 1123 /* 60 */
88103cfe
BS
1124 { PREGRP95 },
1125 { PREGRP96 },
1126 { PREGRP97 },
1127 { "packsswb", { MX, EM } },
1128 { "pcmpgtb", { MX, EM } },
1129 { "pcmpgtw", { MX, EM } },
1130 { "pcmpgtd", { MX, EM } },
1131 { "packuswb", { MX, EM } },
dc99065b 1132 /* 68 */
88103cfe
BS
1133 { "punpckhbw", { MX, EM } },
1134 { "punpckhwd", { MX, EM } },
1135 { "punpckhdq", { MX, EM } },
1136 { "packssdw", { MX, EM } },
bc51c5c9
FB
1137 { PREGRP26 },
1138 { PREGRP24 },
88103cfe 1139 { "movd", { MX, Edq } },
bc51c5c9 1140 { PREGRP19 },
dc99065b 1141 /* 70 */
bc51c5c9 1142 { PREGRP22 },
dc99065b 1143 { GRP12 },
88103cfe
BS
1144 { GRP13 },
1145 { GRP14 },
1146 { "pcmpeqb", { MX, EM } },
1147 { "pcmpeqw", { MX, EM } },
1148 { "pcmpeqd", { MX, EM } },
1149 { "emms", { XX } },
dc99065b 1150 /* 78 */
88103cfe
BS
1151 { PREGRP34 },
1152 { PREGRP35 },
1153 { "(bad)", { XX } },
1154 { "(bad)", { XX } },
c2c73b42
BS
1155 { PREGRP28 },
1156 { PREGRP29 },
bc51c5c9
FB
1157 { PREGRP23 },
1158 { PREGRP20 },
dc99065b 1159 /* 80 */
88103cfe
BS
1160 { "joH", { Jv, XX, cond_jump_flag } },
1161 { "jnoH", { Jv, XX, cond_jump_flag } },
1162 { "jbH", { Jv, XX, cond_jump_flag } },
1163 { "jaeH", { Jv, XX, cond_jump_flag } },
1164 { "jeH", { Jv, XX, cond_jump_flag } },
1165 { "jneH", { Jv, XX, cond_jump_flag } },
1166 { "jbeH", { Jv, XX, cond_jump_flag } },
1167 { "jaH", { Jv, XX, cond_jump_flag } },
dc99065b 1168 /* 88 */
88103cfe
BS
1169 { "jsH", { Jv, XX, cond_jump_flag } },
1170 { "jnsH", { Jv, XX, cond_jump_flag } },
1171 { "jpH", { Jv, XX, cond_jump_flag } },
1172 { "jnpH", { Jv, XX, cond_jump_flag } },
1173 { "jlH", { Jv, XX, cond_jump_flag } },
1174 { "jgeH", { Jv, XX, cond_jump_flag } },
1175 { "jleH", { Jv, XX, cond_jump_flag } },
1176 { "jgH", { Jv, XX, cond_jump_flag } },
dc99065b 1177 /* 90 */
88103cfe
BS
1178 { "seto", { Eb } },
1179 { "setno", { Eb } },
1180 { "setb", { Eb } },
1181 { "setae", { Eb } },
1182 { "sete", { Eb } },
1183 { "setne", { Eb } },
1184 { "setbe", { Eb } },
1185 { "seta", { Eb } },
dc99065b 1186 /* 98 */
88103cfe
BS
1187 { "sets", { Eb } },
1188 { "setns", { Eb } },
1189 { "setp", { Eb } },
1190 { "setnp", { Eb } },
1191 { "setl", { Eb } },
1192 { "setge", { Eb } },
1193 { "setle", { Eb } },
1194 { "setg", { Eb } },
dc99065b 1195 /* a0 */
88103cfe
BS
1196 { "pushT", { fs } },
1197 { "popT", { fs } },
1198 { "cpuid", { XX } },
1199 { "btS", { Ev, Gv } },
1200 { "shldS", { Ev, Gv, Ib } },
1201 { "shldS", { Ev, Gv, CL } },
c2c73b42
BS
1202 { GRPPADLCK2 },
1203 { GRPPADLCK1 },
dc99065b 1204 /* a8 */
88103cfe
BS
1205 { "pushT", { gs } },
1206 { "popT", { gs } },
1207 { "rsm", { XX } },
1208 { "btsS", { Ev, Gv } },
1209 { "shrdS", { Ev, Gv, Ib } },
1210 { "shrdS", { Ev, Gv, CL } },
1211 { GRP15 },
1212 { "imulS", { Gv, Ev } },
dc99065b 1213 /* b0 */
88103cfe
BS
1214 { "cmpxchgB", { Eb, Gb } },
1215 { "cmpxchgS", { Ev, Gv } },
1216 { "lssS", { Gv, Mp } },
1217 { "btrS", { Ev, Gv } },
1218 { "lfsS", { Gv, Mp } },
1219 { "lgsS", { Gv, Mp } },
1220 { "movz{bR|x|bR|x}", { Gv, Eb } },
1221 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
dc99065b 1222 /* b8 */
88103cfe
BS
1223 { PREGRP37 },
1224 { "ud2b", { XX } },
dc99065b 1225 { GRP8 },
88103cfe
BS
1226 { "btcS", { Ev, Gv } },
1227 { "bsfS", { Gv, Ev } },
1228 { PREGRP36 },
1229 { "movs{bR|x|bR|x}", { Gv, Eb } },
1230 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
dc99065b 1231 /* c0 */
88103cfe
BS
1232 { "xaddB", { Eb, Gb } },
1233 { "xaddS", { Ev, Gv } },
bc51c5c9 1234 { PREGRP1 },
88103cfe
BS
1235 { "movntiS", { Ev, Gv } },
1236 { "pinsrw", { MX, Edqw, Ib } },
1237 { "pextrw", { Gdq, MS, Ib } },
1238 { "shufpX", { XM, EXx, Ib } },
bc51c5c9 1239 { GRP9 },
dc99065b 1240 /* c8 */
88103cfe
BS
1241 { "bswap", { RMeAX } },
1242 { "bswap", { RMeCX } },
1243 { "bswap", { RMeDX } },
1244 { "bswap", { RMeBX } },
1245 { "bswap", { RMeSP } },
1246 { "bswap", { RMeBP } },
1247 { "bswap", { RMeSI } },
1248 { "bswap", { RMeDI } },
dc99065b 1249 /* d0 */
c2c73b42 1250 { PREGRP27 },
88103cfe
BS
1251 { "psrlw", { MX, EM } },
1252 { "psrld", { MX, EM } },
1253 { "psrlq", { MX, EM } },
1254 { "paddq", { MX, EM } },
1255 { "pmullw", { MX, EM } },
bc51c5c9 1256 { PREGRP21 },
88103cfe 1257 { "pmovmskb", { Gdq, MS } },
dc99065b 1258 /* d8 */
88103cfe
BS
1259 { "psubusb", { MX, EM } },
1260 { "psubusw", { MX, EM } },
1261 { "pminub", { MX, EM } },
1262 { "pand", { MX, EM } },
1263 { "paddusb", { MX, EM } },
1264 { "paddusw", { MX, EM } },
1265 { "pmaxub", { MX, EM } },
1266 { "pandn", { MX, EM } },
dc99065b 1267 /* e0 */
88103cfe
BS
1268 { "pavgb", { MX, EM } },
1269 { "psraw", { MX, EM } },
1270 { "psrad", { MX, EM } },
1271 { "pavgw", { MX, EM } },
1272 { "pmulhuw", { MX, EM } },
1273 { "pmulhw", { MX, EM } },
bc51c5c9
FB
1274 { PREGRP15 },
1275 { PREGRP25 },
dc99065b 1276 /* e8 */
88103cfe
BS
1277 { "psubsb", { MX, EM } },
1278 { "psubsw", { MX, EM } },
1279 { "pminsw", { MX, EM } },
1280 { "por", { MX, EM } },
1281 { "paddsb", { MX, EM } },
1282 { "paddsw", { MX, EM } },
1283 { "pmaxsw", { MX, EM } },
1284 { "pxor", { MX, EM } },
dc99065b 1285 /* f0 */
c2c73b42 1286 { PREGRP32 },
88103cfe
BS
1287 { "psllw", { MX, EM } },
1288 { "pslld", { MX, EM } },
1289 { "psllq", { MX, EM } },
1290 { "pmuludq", { MX, EM } },
1291 { "pmaddwd", { MX, EM } },
1292 { "psadbw", { MX, EM } },
bc51c5c9 1293 { PREGRP18 },
dc99065b 1294 /* f8 */
88103cfe
BS
1295 { "psubb", { MX, EM } },
1296 { "psubw", { MX, EM } },
1297 { "psubd", { MX, EM } },
1298 { "psubq", { MX, EM } },
1299 { "paddb", { MX, EM } },
1300 { "paddw", { MX, EM } },
1301 { "paddd", { MX, EM } },
1302 { "(bad)", { XX } },
dc99065b
FB
1303};
1304
1305static const unsigned char onebyte_has_modrm[256] = {
bc51c5c9
FB
1306 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1307 /* ------------------------------- */
1308 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1309 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1310 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1311 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1312 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1313 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1314 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1315 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1316 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1317 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1318 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1319 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1320 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1321 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1322 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1323 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1324 /* ------------------------------- */
1325 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
dc99065b
FB
1326};
1327
1328static const unsigned char twobyte_has_modrm[256] = {
bc51c5c9
FB
1329 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1330 /* ------------------------------- */
1331 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
88103cfe 1332 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
bc51c5c9 1333 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
c2c73b42 1334 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
dc99065b 1335 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
bc51c5c9
FB
1336 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1337 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
c2c73b42 1338 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
dc99065b
FB
1339 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1340 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
c2c73b42 1341 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
88103cfe 1342 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
dc99065b 1343 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
c2c73b42 1344 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
bc51c5c9 1345 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
c2c73b42 1346 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
bc51c5c9
FB
1347 /* ------------------------------- */
1348 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1349};
1350
88103cfe 1351static const unsigned char twobyte_uses_DATA_prefix[256] = {
bc51c5c9
FB
1352 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1353 /* ------------------------------- */
1354 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
c2c73b42 1355 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
88103cfe 1356 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
c2c73b42 1357 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
bc51c5c9
FB
1358 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1359 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1360 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
88103cfe 1361 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
bc51c5c9
FB
1362 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1363 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1364 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1365 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1366 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
c2c73b42 1367 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
bc51c5c9 1368 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
c2c73b42 1369 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
bc51c5c9
FB
1370 /* ------------------------------- */
1371 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
dc99065b
FB
1372};
1373
88103cfe
BS
1374static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1375 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1376 /* ------------------------------- */
1377 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1378 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1379 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1380 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1381 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1382 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1383 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1384 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1385 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1386 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1387 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1388 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1389 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1390 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1391 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1392 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1393 /* ------------------------------- */
1394 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1395};
1396
1397static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1398 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1399 /* ------------------------------- */
1400 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1401 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1402 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1403 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1404 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1405 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1406 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1407 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1408 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1409 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1410 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1411 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1412 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1413 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1414 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1415 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1416 /* ------------------------------- */
1417 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1418};
1419
1420/* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1421static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1422 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1423 /* ------------------------------- */
1424 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1425 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1426 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1427 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1428 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1429 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1430 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1431 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1432 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1433 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1434 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1435 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1436 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1437 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1438 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1439 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1440 /* ------------------------------- */
1441 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1442};
1443
1444/* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1445static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1446 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1447 /* ------------------------------- */
1448 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1449 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1450 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1451 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1452 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1453 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1454 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1455 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1456 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1457 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1458 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1459 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1460 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1461 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1462 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1463 /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1464 /* ------------------------------- */
1465 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1466};
1467
1468/* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1469static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1470 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1471 /* ------------------------------- */
1472 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1473 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1474 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1475 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1476 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1477 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1478 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1479 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1480 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1481 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1482 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1483 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1484 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1485 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1486 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1487 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1488 /* ------------------------------- */
1489 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1490};
1491
1492/* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1493static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1494 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1495 /* ------------------------------- */
1496 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1497 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1498 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1499 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1500 /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1501 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1502 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1503 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1504 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1505 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1506 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1507 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1508 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1509 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1510 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1511 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1512 /* ------------------------------- */
1513 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1514};
1515
1516/* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1517static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1518 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1519 /* ------------------------------- */
1520 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1521 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1522 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1523 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1524 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1525 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1526 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1527 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1528 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1529 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1530 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1531 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1532 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1533 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1534 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1535 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1536 /* ------------------------------- */
1537 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1538};
1539
1540/* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1541static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1542 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1543 /* ------------------------------- */
1544 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1545 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1546 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1547 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1548 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1549 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1550 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1551 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1552 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1553 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1554 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1555 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1556 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1557 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1558 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1559 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1560 /* ------------------------------- */
1561 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1562};
1563
dc99065b
FB
1564static char obuf[100];
1565static char *obufp;
1566static char scratchbuf[100];
1567static unsigned char *start_codep;
bc51c5c9 1568static unsigned char *insn_codep;
dc99065b
FB
1569static unsigned char *codep;
1570static disassemble_info *the_info;
88103cfe
BS
1571static struct
1572 {
1573 int mod;
1574 int reg;
1575 int rm;
1576 }
1577modrm;
bc51c5c9
FB
1578static unsigned char need_modrm;
1579
1580/* If we are accessing mod/rm/reg without need_modrm set, then the
1581 values are stale. Hitting this abort likely indicates that you
1582 need to update onebyte_has_modrm or twobyte_has_modrm. */
1583#define MODRM_CHECK if (!need_modrm) abort ()
1584
7a786a46
BS
1585static const char * const *names64;
1586static const char * const *names32;
1587static const char * const *names16;
1588static const char * const *names8;
1589static const char * const *names8rex;
1590static const char * const *names_seg;
1591static const char * const *index16;
bc51c5c9 1592
7a786a46 1593static const char * const intel_names64[] = {
bc51c5c9
FB
1594 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1595 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1596};
7a786a46 1597static const char * const intel_names32[] = {
bc51c5c9
FB
1598 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1599 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1600};
7a786a46 1601static const char * const intel_names16[] = {
bc51c5c9
FB
1602 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1603 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1604};
7a786a46 1605static const char * const intel_names8[] = {
bc51c5c9
FB
1606 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1607};
7a786a46 1608static const char * const intel_names8rex[] = {
bc51c5c9
FB
1609 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1610 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1611};
7a786a46 1612static const char * const intel_names_seg[] = {
bc51c5c9
FB
1613 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1614};
7a786a46 1615static const char * const intel_index16[] = {
bc51c5c9
FB
1616 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1617};
dc99065b 1618
7a786a46 1619static const char * const att_names64[] = {
bc51c5c9
FB
1620 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1621 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1622};
7a786a46 1623static const char * const att_names32[] = {
bc51c5c9
FB
1624 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1625 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
dc99065b 1626};
7a786a46 1627static const char * const att_names16[] = {
bc51c5c9
FB
1628 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1629 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
dc99065b 1630};
7a786a46 1631static const char * const att_names8[] = {
bc51c5c9 1632 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
dc99065b 1633};
7a786a46 1634static const char * const att_names8rex[] = {
bc51c5c9
FB
1635 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1636 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
dc99065b 1637};
7a786a46 1638static const char * const att_names_seg[] = {
bc51c5c9
FB
1639 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1640};
7a786a46 1641static const char * const att_index16[] = {
bc51c5c9 1642 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
dc99065b
FB
1643};
1644
bc51c5c9 1645static const struct dis386 grps[][8] = {
88103cfe
BS
1646 /* GRP1a */
1647 {
1648 { "popU", { stackEv } },
1649 { "(bad)", { XX } },
1650 { "(bad)", { XX } },
1651 { "(bad)", { XX } },
1652 { "(bad)", { XX } },
1653 { "(bad)", { XX } },
1654 { "(bad)", { XX } },
1655 { "(bad)", { XX } },
1656 },
dc99065b
FB
1657 /* GRP1b */
1658 {
88103cfe
BS
1659 { "addA", { Eb, Ib } },
1660 { "orA", { Eb, Ib } },
1661 { "adcA", { Eb, Ib } },
1662 { "sbbA", { Eb, Ib } },
1663 { "andA", { Eb, Ib } },
1664 { "subA", { Eb, Ib } },
1665 { "xorA", { Eb, Ib } },
1666 { "cmpA", { Eb, Ib } },
dc99065b
FB
1667 },
1668 /* GRP1S */
1669 {
88103cfe
BS
1670 { "addQ", { Ev, Iv } },
1671 { "orQ", { Ev, Iv } },
1672 { "adcQ", { Ev, Iv } },
1673 { "sbbQ", { Ev, Iv } },
1674 { "andQ", { Ev, Iv } },
1675 { "subQ", { Ev, Iv } },
1676 { "xorQ", { Ev, Iv } },
1677 { "cmpQ", { Ev, Iv } },
dc99065b
FB
1678 },
1679 /* GRP1Ss */
1680 {
88103cfe
BS
1681 { "addQ", { Ev, sIb } },
1682 { "orQ", { Ev, sIb } },
1683 { "adcQ", { Ev, sIb } },
1684 { "sbbQ", { Ev, sIb } },
1685 { "andQ", { Ev, sIb } },
1686 { "subQ", { Ev, sIb } },
1687 { "xorQ", { Ev, sIb } },
1688 { "cmpQ", { Ev, sIb } },
dc99065b
FB
1689 },
1690 /* GRP2b */
1691 {
88103cfe
BS
1692 { "rolA", { Eb, Ib } },
1693 { "rorA", { Eb, Ib } },
1694 { "rclA", { Eb, Ib } },
1695 { "rcrA", { Eb, Ib } },
1696 { "shlA", { Eb, Ib } },
1697 { "shrA", { Eb, Ib } },
1698 { "(bad)", { XX } },
1699 { "sarA", { Eb, Ib } },
dc99065b
FB
1700 },
1701 /* GRP2S */
1702 {
88103cfe
BS
1703 { "rolQ", { Ev, Ib } },
1704 { "rorQ", { Ev, Ib } },
1705 { "rclQ", { Ev, Ib } },
1706 { "rcrQ", { Ev, Ib } },
1707 { "shlQ", { Ev, Ib } },
1708 { "shrQ", { Ev, Ib } },
1709 { "(bad)", { XX } },
1710 { "sarQ", { Ev, Ib } },
dc99065b
FB
1711 },
1712 /* GRP2b_one */
1713 {
88103cfe
BS
1714 { "rolA", { Eb, I1 } },
1715 { "rorA", { Eb, I1 } },
1716 { "rclA", { Eb, I1 } },
1717 { "rcrA", { Eb, I1 } },
1718 { "shlA", { Eb, I1 } },
1719 { "shrA", { Eb, I1 } },
1720 { "(bad)", { XX } },
1721 { "sarA", { Eb, I1 } },
dc99065b
FB
1722 },
1723 /* GRP2S_one */
1724 {
88103cfe
BS
1725 { "rolQ", { Ev, I1 } },
1726 { "rorQ", { Ev, I1 } },
1727 { "rclQ", { Ev, I1 } },
1728 { "rcrQ", { Ev, I1 } },
1729 { "shlQ", { Ev, I1 } },
1730 { "shrQ", { Ev, I1 } },
1731 { "(bad)", { XX } },
1732 { "sarQ", { Ev, I1 } },
dc99065b
FB
1733 },
1734 /* GRP2b_cl */
1735 {
88103cfe
BS
1736 { "rolA", { Eb, CL } },
1737 { "rorA", { Eb, CL } },
1738 { "rclA", { Eb, CL } },
1739 { "rcrA", { Eb, CL } },
1740 { "shlA", { Eb, CL } },
1741 { "shrA", { Eb, CL } },
1742 { "(bad)", { XX } },
1743 { "sarA", { Eb, CL } },
dc99065b
FB
1744 },
1745 /* GRP2S_cl */
1746 {
88103cfe
BS
1747 { "rolQ", { Ev, CL } },
1748 { "rorQ", { Ev, CL } },
1749 { "rclQ", { Ev, CL } },
1750 { "rcrQ", { Ev, CL } },
1751 { "shlQ", { Ev, CL } },
1752 { "shrQ", { Ev, CL } },
1753 { "(bad)", { XX } },
1754 { "sarQ", { Ev, CL } },
dc99065b
FB
1755 },
1756 /* GRP3b */
1757 {
88103cfe
BS
1758 { "testA", { Eb, Ib } },
1759 { "(bad)", { Eb } },
1760 { "notA", { Eb } },
1761 { "negA", { Eb } },
1762 { "mulA", { Eb } }, /* Don't print the implicit %al register, */
1763 { "imulA", { Eb } }, /* to distinguish these opcodes from other */
1764 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */
1765 { "idivA", { Eb } }, /* and idiv for consistency. */
dc99065b
FB
1766 },
1767 /* GRP3S */
1768 {
88103cfe
BS
1769 { "testQ", { Ev, Iv } },
1770 { "(bad)", { XX } },
1771 { "notQ", { Ev } },
1772 { "negQ", { Ev } },
1773 { "mulQ", { Ev } }, /* Don't print the implicit register. */
1774 { "imulQ", { Ev } },
1775 { "divQ", { Ev } },
1776 { "idivQ", { Ev } },
dc99065b
FB
1777 },
1778 /* GRP4 */
1779 {
88103cfe
BS
1780 { "incA", { Eb } },
1781 { "decA", { Eb } },
1782 { "(bad)", { XX } },
1783 { "(bad)", { XX } },
1784 { "(bad)", { XX } },
1785 { "(bad)", { XX } },
1786 { "(bad)", { XX } },
1787 { "(bad)", { XX } },
dc99065b
FB
1788 },
1789 /* GRP5 */
1790 {
88103cfe
BS
1791 { "incQ", { Ev } },
1792 { "decQ", { Ev } },
1793 { "callT", { indirEv } },
1794 { "JcallT", { indirEp } },
1795 { "jmpT", { indirEv } },
1796 { "JjmpT", { indirEp } },
1797 { "pushU", { stackEv } },
1798 { "(bad)", { XX } },
dc99065b
FB
1799 },
1800 /* GRP6 */
1801 {
88103cfe
BS
1802 { "sldtD", { Sv } },
1803 { "strD", { Sv } },
1804 { "lldt", { Ew } },
1805 { "ltr", { Ew } },
1806 { "verr", { Ew } },
1807 { "verw", { Ew } },
1808 { "(bad)", { XX } },
1809 { "(bad)", { XX } },
dc99065b
FB
1810 },
1811 /* GRP7 */
1812 {
88103cfe
BS
1813 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1814 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1815 { "lgdt{Q|Q||}", { M } },
1816 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1817 { "smswD", { Sv } },
1818 { "(bad)", { XX } },
1819 { "lmsw", { Ew } },
1820 { "invlpg", { { INVLPG_Fixup, w_mode } } },
dc99065b
FB
1821 },
1822 /* GRP8 */
1823 {
88103cfe
BS
1824 { "(bad)", { XX } },
1825 { "(bad)", { XX } },
1826 { "(bad)", { XX } },
1827 { "(bad)", { XX } },
1828 { "btQ", { Ev, Ib } },
1829 { "btsQ", { Ev, Ib } },
1830 { "btrQ", { Ev, Ib } },
1831 { "btcQ", { Ev, Ib } },
dc99065b
FB
1832 },
1833 /* GRP9 */
1834 {
88103cfe
BS
1835 { "(bad)", { XX } },
1836 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1837 { "(bad)", { XX } },
1838 { "(bad)", { XX } },
1839 { "(bad)", { XX } },
1840 { "(bad)", { XX } },
1841 { "", { VM } }, /* See OP_VMX. */
1842 { "vmptrst", { Mq } },
1843 },
1844 /* GRP11_C6 */
1845 {
1846 { "movA", { Eb, Ib } },
1847 { "(bad)", { XX } },
1848 { "(bad)", { XX } },
1849 { "(bad)", { XX } },
1850 { "(bad)", { XX } },
1851 { "(bad)", { XX } },
1852 { "(bad)", { XX } },
1853 { "(bad)", { XX } },
1854 },
1855 /* GRP11_C7 */
1856 {
1857 { "movQ", { Ev, Iv } },
1858 { "(bad)", { XX } },
1859 { "(bad)", { XX } },
1860 { "(bad)", { XX } },
1861 { "(bad)", { XX } },
1862 { "(bad)", { XX } },
1863 { "(bad)", { XX } },
1864 { "(bad)", { XX } },
dc99065b
FB
1865 },
1866 /* GRP12 */
1867 {
88103cfe
BS
1868 { "(bad)", { XX } },
1869 { "(bad)", { XX } },
1870 { "psrlw", { MS, Ib } },
1871 { "(bad)", { XX } },
1872 { "psraw", { MS, Ib } },
1873 { "(bad)", { XX } },
1874 { "psllw", { MS, Ib } },
1875 { "(bad)", { XX } },
bc51c5c9
FB
1876 },
1877 /* GRP13 */
1878 {
88103cfe
BS
1879 { "(bad)", { XX } },
1880 { "(bad)", { XX } },
1881 { "psrld", { MS, Ib } },
1882 { "(bad)", { XX } },
1883 { "psrad", { MS, Ib } },
1884 { "(bad)", { XX } },
1885 { "pslld", { MS, Ib } },
1886 { "(bad)", { XX } },
bc51c5c9
FB
1887 },
1888 /* GRP14 */
1889 {
88103cfe
BS
1890 { "(bad)", { XX } },
1891 { "(bad)", { XX } },
1892 { "psrlq", { MS, Ib } },
1893 { "psrldq", { MS, Ib } },
1894 { "(bad)", { XX } },
1895 { "(bad)", { XX } },
1896 { "psllq", { MS, Ib } },
1897 { "pslldq", { MS, Ib } },
1898 },
1899 /* GRP15 */
1900 {
1901 { "fxsave", { Ev } },
1902 { "fxrstor", { Ev } },
1903 { "ldmxcsr", { Ev } },
1904 { "stmxcsr", { Ev } },
1905 { "(bad)", { XX } },
1906 { "lfence", { { OP_0fae, 0 } } },
1907 { "mfence", { { OP_0fae, 0 } } },
1908 { "clflush", { { OP_0fae, 0 } } },
1909 },
1910 /* GRP16 */
1911 {
1912 { "prefetchnta", { Ev } },
1913 { "prefetcht0", { Ev } },
1914 { "prefetcht1", { Ev } },
1915 { "prefetcht2", { Ev } },
1916 { "(bad)", { XX } },
1917 { "(bad)", { XX } },
1918 { "(bad)", { XX } },
1919 { "(bad)", { XX } },
bc51c5c9
FB
1920 },
1921 /* GRPAMD */
1922 {
88103cfe
BS
1923 { "prefetch", { Eb } },
1924 { "prefetchw", { Eb } },
1925 { "(bad)", { XX } },
1926 { "(bad)", { XX } },
1927 { "(bad)", { XX } },
1928 { "(bad)", { XX } },
1929 { "(bad)", { XX } },
1930 { "(bad)", { XX } },
c2c73b42
BS
1931 },
1932 /* GRPPADLCK1 */
1933 {
88103cfe
BS
1934 { "xstore-rng", { { OP_0f07, 0 } } },
1935 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1936 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1937 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1938 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1939 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1940 { "(bad)", { { OP_0f07, 0 } } },
1941 { "(bad)", { { OP_0f07, 0 } } },
c2c73b42
BS
1942 },
1943 /* GRPPADLCK2 */
1944 {
88103cfe
BS
1945 { "montmul", { { OP_0f07, 0 } } },
1946 { "xsha1", { { OP_0f07, 0 } } },
1947 { "xsha256", { { OP_0f07, 0 } } },
1948 { "(bad)", { { OP_0f07, 0 } } },
1949 { "(bad)", { { OP_0f07, 0 } } },
1950 { "(bad)", { { OP_0f07, 0 } } },
1951 { "(bad)", { { OP_0f07, 0 } } },
1952 { "(bad)", { { OP_0f07, 0 } } },
dc99065b
FB
1953 }
1954};
1955
bc51c5c9
FB
1956static const struct dis386 prefix_user_table[][4] = {
1957 /* PREGRP0 */
1958 {
88103cfe
BS
1959 { "addps", { XM, EXx } },
1960 { "addss", { XM, EXd } },
1961 { "addpd", { XM, EXx } },
1962 { "addsd", { XM, EXq } },
bc51c5c9
FB
1963 },
1964 /* PREGRP1 */
1965 {
88103cfe
BS
1966 { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1967 { "", { XM, EXx, OPSIMD } },
1968 { "", { XM, EXx, OPSIMD } },
1969 { "", { XM, EXx, OPSIMD } },
bc51c5c9
FB
1970 },
1971 /* PREGRP2 */
1972 {
88103cfe
BS
1973 { "cvtpi2ps", { XM, EMC } },
1974 { "cvtsi2ssY", { XM, Ev } },
1975 { "cvtpi2pd", { XM, EMC } },
1976 { "cvtsi2sdY", { XM, Ev } },
bc51c5c9
FB
1977 },
1978 /* PREGRP3 */
1979 {
88103cfe
BS
1980 { "cvtps2pi", { MXC, EXx } },
1981 { "cvtss2siY", { Gv, EXx } },
1982 { "cvtpd2pi", { MXC, EXx } },
1983 { "cvtsd2siY", { Gv, EXx } },
bc51c5c9
FB
1984 },
1985 /* PREGRP4 */
1986 {
88103cfe
BS
1987 { "cvttps2pi", { MXC, EXx } },
1988 { "cvttss2siY", { Gv, EXx } },
1989 { "cvttpd2pi", { MXC, EXx } },
1990 { "cvttsd2siY", { Gv, EXx } },
bc51c5c9
FB
1991 },
1992 /* PREGRP5 */
1993 {
88103cfe
BS
1994 { "divps", { XM, EXx } },
1995 { "divss", { XM, EXx } },
1996 { "divpd", { XM, EXx } },
1997 { "divsd", { XM, EXx } },
bc51c5c9
FB
1998 },
1999 /* PREGRP6 */
2000 {
88103cfe
BS
2001 { "maxps", { XM, EXx } },
2002 { "maxss", { XM, EXx } },
2003 { "maxpd", { XM, EXx } },
2004 { "maxsd", { XM, EXx } },
bc51c5c9
FB
2005 },
2006 /* PREGRP7 */
2007 {
88103cfe
BS
2008 { "minps", { XM, EXx } },
2009 { "minss", { XM, EXx } },
2010 { "minpd", { XM, EXx } },
2011 { "minsd", { XM, EXx } },
bc51c5c9
FB
2012 },
2013 /* PREGRP8 */
2014 {
88103cfe
BS
2015 { "movups", { XM, EXx } },
2016 { "movss", { XM, EXx } },
2017 { "movupd", { XM, EXx } },
2018 { "movsd", { XM, EXx } },
bc51c5c9
FB
2019 },
2020 /* PREGRP9 */
2021 {
88103cfe
BS
2022 { "movups", { EXx, XM } },
2023 { "movss", { EXx, XM } },
2024 { "movupd", { EXx, XM } },
2025 { "movsd", { EXx, XM } },
bc51c5c9
FB
2026 },
2027 /* PREGRP10 */
2028 {
88103cfe
BS
2029 { "mulps", { XM, EXx } },
2030 { "mulss", { XM, EXx } },
2031 { "mulpd", { XM, EXx } },
2032 { "mulsd", { XM, EXx } },
bc51c5c9
FB
2033 },
2034 /* PREGRP11 */
2035 {
88103cfe
BS
2036 { "rcpps", { XM, EXx } },
2037 { "rcpss", { XM, EXx } },
2038 { "(bad)", { XM, EXx } },
2039 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2040 },
2041 /* PREGRP12 */
2042 {
88103cfe
BS
2043 { "rsqrtps",{ XM, EXx } },
2044 { "rsqrtss",{ XM, EXx } },
2045 { "(bad)", { XM, EXx } },
2046 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2047 },
2048 /* PREGRP13 */
2049 {
88103cfe
BS
2050 { "sqrtps", { XM, EXx } },
2051 { "sqrtss", { XM, EXx } },
2052 { "sqrtpd", { XM, EXx } },
2053 { "sqrtsd", { XM, EXx } },
bc51c5c9
FB
2054 },
2055 /* PREGRP14 */
2056 {
88103cfe
BS
2057 { "subps", { XM, EXx } },
2058 { "subss", { XM, EXx } },
2059 { "subpd", { XM, EXx } },
2060 { "subsd", { XM, EXx } },
bc51c5c9
FB
2061 },
2062 /* PREGRP15 */
2063 {
88103cfe
BS
2064 { "(bad)", { XM, EXx } },
2065 { "cvtdq2pd", { XM, EXq } },
2066 { "cvttpd2dq", { XM, EXx } },
2067 { "cvtpd2dq", { XM, EXx } },
bc51c5c9
FB
2068 },
2069 /* PREGRP16 */
2070 {
88103cfe
BS
2071 { "cvtdq2ps", { XM, EXx } },
2072 { "cvttps2dq", { XM, EXx } },
2073 { "cvtps2dq", { XM, EXx } },
2074 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2075 },
2076 /* PREGRP17 */
2077 {
88103cfe
BS
2078 { "cvtps2pd", { XM, EXq } },
2079 { "cvtss2sd", { XM, EXx } },
2080 { "cvtpd2ps", { XM, EXx } },
2081 { "cvtsd2ss", { XM, EXx } },
bc51c5c9
FB
2082 },
2083 /* PREGRP18 */
2084 {
88103cfe
BS
2085 { "maskmovq", { MX, MS } },
2086 { "(bad)", { XM, EXx } },
2087 { "maskmovdqu", { XM, XS } },
2088 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2089 },
2090 /* PREGRP19 */
2091 {
88103cfe
BS
2092 { "movq", { MX, EM } },
2093 { "movdqu", { XM, EXx } },
2094 { "movdqa", { XM, EXx } },
2095 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2096 },
2097 /* PREGRP20 */
2098 {
88103cfe
BS
2099 { "movq", { EM, MX } },
2100 { "movdqu", { EXx, XM } },
2101 { "movdqa", { EXx, XM } },
2102 { "(bad)", { EXx, XM } },
bc51c5c9
FB
2103 },
2104 /* PREGRP21 */
2105 {
88103cfe
BS
2106 { "(bad)", { EXx, XM } },
2107 { "movq2dq",{ XM, MS } },
2108 { "movq", { EXx, XM } },
2109 { "movdq2q",{ MX, XS } },
bc51c5c9
FB
2110 },
2111 /* PREGRP22 */
2112 {
88103cfe
BS
2113 { "pshufw", { MX, EM, Ib } },
2114 { "pshufhw",{ XM, EXx, Ib } },
2115 { "pshufd", { XM, EXx, Ib } },
2116 { "pshuflw",{ XM, EXx, Ib } },
bc51c5c9
FB
2117 },
2118 /* PREGRP23 */
2119 {
88103cfe
BS
2120 { "movd", { Edq, MX } },
2121 { "movq", { XM, EXx } },
2122 { "movd", { Edq, XM } },
2123 { "(bad)", { Ed, XM } },
bc51c5c9
FB
2124 },
2125 /* PREGRP24 */
2126 {
88103cfe
BS
2127 { "(bad)", { MX, EXx } },
2128 { "(bad)", { XM, EXx } },
2129 { "punpckhqdq", { XM, EXx } },
2130 { "(bad)", { XM, EXx } },
bc51c5c9
FB
2131 },
2132 /* PREGRP25 */
2133 {
88103cfe
BS
2134 { "movntq", { EM, MX } },
2135 { "(bad)", { EM, XM } },
2136 { "movntdq",{ EM, XM } },
2137 { "(bad)", { EM, XM } },
bc51c5c9
FB
2138 },
2139 /* PREGRP26 */
2140 {
88103cfe
BS
2141 { "(bad)", { MX, EXx } },
2142 { "(bad)", { XM, EXx } },
2143 { "punpcklqdq", { XM, EXx } },
2144 { "(bad)", { XM, EXx } },
bc51c5c9 2145 },
c2c73b42
BS
2146 /* PREGRP27 */
2147 {
88103cfe
BS
2148 { "(bad)", { MX, EXx } },
2149 { "(bad)", { XM, EXx } },
2150 { "addsubpd", { XM, EXx } },
2151 { "addsubps", { XM, EXx } },
c2c73b42
BS
2152 },
2153 /* PREGRP28 */
2154 {
88103cfe
BS
2155 { "(bad)", { MX, EXx } },
2156 { "(bad)", { XM, EXx } },
2157 { "haddpd", { XM, EXx } },
2158 { "haddps", { XM, EXx } },
c2c73b42
BS
2159 },
2160 /* PREGRP29 */
2161 {
88103cfe
BS
2162 { "(bad)", { MX, EXx } },
2163 { "(bad)", { XM, EXx } },
2164 { "hsubpd", { XM, EXx } },
2165 { "hsubps", { XM, EXx } },
c2c73b42
BS
2166 },
2167 /* PREGRP30 */
2168 {
88103cfe
BS
2169 { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
2170 { "movsldup", { XM, EXx } },
2171 { "movlpd", { XM, EXq } },
2172 { "movddup", { XM, EXq } },
c2c73b42
BS
2173 },
2174 /* PREGRP31 */
2175 {
88103cfe
BS
2176 { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } },
2177 { "movshdup", { XM, EXx } },
2178 { "movhpd", { XM, EXq } },
2179 { "(bad)", { XM, EXq } },
c2c73b42
BS
2180 },
2181 /* PREGRP32 */
2182 {
88103cfe
BS
2183 { "(bad)", { XM, EXx } },
2184 { "(bad)", { XM, EXx } },
2185 { "(bad)", { XM, EXx } },
2186 { "lddqu", { XM, M } },
2187 },
2188 /* PREGRP33 */
2189 {
2190 {"movntps", { Ev, XM } },
2191 {"movntss", { Ev, XM } },
2192 {"movntpd", { Ev, XM } },
2193 {"movntsd", { Ev, XM } },
2194 },
2195
2196 /* PREGRP34 */
2197 {
2198 {"vmread", { Em, Gm } },
2199 {"(bad)", { XX } },
2200 {"extrq", { XS, Ib, Ib } },
2201 {"insertq", { XM, XS, Ib, Ib } },
2202 },
2203
2204 /* PREGRP35 */
2205 {
2206 {"vmwrite", { Gm, Em } },
2207 {"(bad)", { XX } },
2208 {"extrq", { XM, XS } },
2209 {"insertq", { XM, XS } },
2210 },
2211
2212 /* PREGRP36 */
2213 {
2214 { "bsrS", { Gv, Ev } },
2215 { "lzcntS", { Gv, Ev } },
2216 { "bsrS", { Gv, Ev } },
2217 { "(bad)", { XX } },
2218 },
2219
2220 /* PREGRP37 */
2221 {
2222 { "(bad)", { XX } },
2223 { "popcntS", { Gv, Ev } },
2224 { "(bad)", { XX } },
2225 { "(bad)", { XX } },
2226 },
2227
2228 /* PREGRP38 */
2229 {
2230 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2231 { "pause", { XX } },
2232 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2233 { "(bad)", { XX } },
2234 },
2235
2236 /* PREGRP39 */
2237 {
2238 { "(bad)", { XX } },
2239 { "(bad)", { XX } },
2240 { "pblendvb", {XM, EXx, XMM0 } },
2241 { "(bad)", { XX } },
2242 },
2243
2244 /* PREGRP40 */
2245 {
2246 { "(bad)", { XX } },
2247 { "(bad)", { XX } },
2248 { "blendvps", {XM, EXx, XMM0 } },
2249 { "(bad)", { XX } },
2250 },
2251
2252 /* PREGRP41 */
2253 {
2254 { "(bad)", { XX } },
2255 { "(bad)", { XX } },
2256 { "blendvpd", { XM, EXx, XMM0 } },
2257 { "(bad)", { XX } },
2258 },
2259
2260 /* PREGRP42 */
2261 {
2262 { "(bad)", { XX } },
2263 { "(bad)", { XX } },
2264 { "ptest", { XM, EXx } },
2265 { "(bad)", { XX } },
2266 },
2267
2268 /* PREGRP43 */
2269 {
2270 { "(bad)", { XX } },
2271 { "(bad)", { XX } },
2272 { "pmovsxbw", { XM, EXx } },
2273 { "(bad)", { XX } },
2274 },
2275
2276 /* PREGRP44 */
2277 {
2278 { "(bad)", { XX } },
2279 { "(bad)", { XX } },
2280 { "pmovsxbd", { XM, EXx } },
2281 { "(bad)", { XX } },
2282 },
2283
2284 /* PREGRP45 */
2285 {
2286 { "(bad)", { XX } },
2287 { "(bad)", { XX } },
2288 { "pmovsxbq", { XM, EXx } },
2289 { "(bad)", { XX } },
2290 },
2291
2292 /* PREGRP46 */
2293 {
2294 { "(bad)", { XX } },
2295 { "(bad)", { XX } },
2296 { "pmovsxwd", { XM, EXx } },
2297 { "(bad)", { XX } },
2298 },
2299
2300 /* PREGRP47 */
2301 {
2302 { "(bad)", { XX } },
2303 { "(bad)", { XX } },
2304 { "pmovsxwq", { XM, EXx } },
2305 { "(bad)", { XX } },
2306 },
2307
2308 /* PREGRP48 */
2309 {
2310 { "(bad)", { XX } },
2311 { "(bad)", { XX } },
2312 { "pmovsxdq", { XM, EXx } },
2313 { "(bad)", { XX } },
2314 },
2315
2316 /* PREGRP49 */
2317 {
2318 { "(bad)", { XX } },
2319 { "(bad)", { XX } },
2320 { "pmuldq", { XM, EXx } },
2321 { "(bad)", { XX } },
2322 },
2323
2324 /* PREGRP50 */
2325 {
2326 { "(bad)", { XX } },
2327 { "(bad)", { XX } },
2328 { "pcmpeqq", { XM, EXx } },
2329 { "(bad)", { XX } },
2330 },
2331
2332 /* PREGRP51 */
2333 {
2334 { "(bad)", { XX } },
2335 { "(bad)", { XX } },
2336 { "movntdqa", { XM, EM } },
2337 { "(bad)", { XX } },
2338 },
2339
2340 /* PREGRP52 */
2341 {
2342 { "(bad)", { XX } },
2343 { "(bad)", { XX } },
2344 { "packusdw", { XM, EXx } },
2345 { "(bad)", { XX } },
2346 },
2347
2348 /* PREGRP53 */
2349 {
2350 { "(bad)", { XX } },
2351 { "(bad)", { XX } },
2352 { "pmovzxbw", { XM, EXx } },
2353 { "(bad)", { XX } },
2354 },
2355
2356 /* PREGRP54 */
2357 {
2358 { "(bad)", { XX } },
2359 { "(bad)", { XX } },
2360 { "pmovzxbd", { XM, EXx } },
2361 { "(bad)", { XX } },
2362 },
2363
2364 /* PREGRP55 */
2365 {
2366 { "(bad)", { XX } },
2367 { "(bad)", { XX } },
2368 { "pmovzxbq", { XM, EXx } },
2369 { "(bad)", { XX } },
2370 },
2371
2372 /* PREGRP56 */
2373 {
2374 { "(bad)", { XX } },
2375 { "(bad)", { XX } },
2376 { "pmovzxwd", { XM, EXx } },
2377 { "(bad)", { XX } },
2378 },
2379
2380 /* PREGRP57 */
2381 {
2382 { "(bad)", { XX } },
2383 { "(bad)", { XX } },
2384 { "pmovzxwq", { XM, EXx } },
2385 { "(bad)", { XX } },
2386 },
2387
2388 /* PREGRP58 */
2389 {
2390 { "(bad)", { XX } },
2391 { "(bad)", { XX } },
2392 { "pmovzxdq", { XM, EXx } },
2393 { "(bad)", { XX } },
2394 },
2395
2396 /* PREGRP59 */
2397 {
2398 { "(bad)", { XX } },
2399 { "(bad)", { XX } },
2400 { "pminsb", { XM, EXx } },
2401 { "(bad)", { XX } },
2402 },
2403
2404 /* PREGRP60 */
2405 {
2406 { "(bad)", { XX } },
2407 { "(bad)", { XX } },
2408 { "pminsd", { XM, EXx } },
2409 { "(bad)", { XX } },
2410 },
2411
2412 /* PREGRP61 */
2413 {
2414 { "(bad)", { XX } },
2415 { "(bad)", { XX } },
2416 { "pminuw", { XM, EXx } },
2417 { "(bad)", { XX } },
2418 },
2419
2420 /* PREGRP62 */
2421 {
2422 { "(bad)", { XX } },
2423 { "(bad)", { XX } },
2424 { "pminud", { XM, EXx } },
2425 { "(bad)", { XX } },
2426 },
2427
2428 /* PREGRP63 */
2429 {
2430 { "(bad)", { XX } },
2431 { "(bad)", { XX } },
2432 { "pmaxsb", { XM, EXx } },
2433 { "(bad)", { XX } },
2434 },
2435
2436 /* PREGRP64 */
2437 {
2438 { "(bad)", { XX } },
2439 { "(bad)", { XX } },
2440 { "pmaxsd", { XM, EXx } },
2441 { "(bad)", { XX } },
2442 },
2443
2444 /* PREGRP65 */
2445 {
2446 { "(bad)", { XX } },
2447 { "(bad)", { XX } },
2448 { "pmaxuw", { XM, EXx } },
2449 { "(bad)", { XX } },
2450 },
2451
2452 /* PREGRP66 */
2453 {
2454 { "(bad)", { XX } },
2455 { "(bad)", { XX } },
2456 { "pmaxud", { XM, EXx } },
2457 { "(bad)", { XX } },
2458 },
2459
2460 /* PREGRP67 */
2461 {
2462 { "(bad)", { XX } },
2463 { "(bad)", { XX } },
2464 { "pmulld", { XM, EXx } },
2465 { "(bad)", { XX } },
2466 },
2467
2468 /* PREGRP68 */
2469 {
2470 { "(bad)", { XX } },
2471 { "(bad)", { XX } },
2472 { "phminposuw", { XM, EXx } },
2473 { "(bad)", { XX } },
2474 },
2475
2476 /* PREGRP69 */
2477 {
2478 { "(bad)", { XX } },
2479 { "(bad)", { XX } },
2480 { "roundps", { XM, EXx, Ib } },
2481 { "(bad)", { XX } },
2482 },
2483
2484 /* PREGRP70 */
2485 {
2486 { "(bad)", { XX } },
2487 { "(bad)", { XX } },
2488 { "roundpd", { XM, EXx, Ib } },
2489 { "(bad)", { XX } },
2490 },
2491
2492 /* PREGRP71 */
2493 {
2494 { "(bad)", { XX } },
2495 { "(bad)", { XX } },
2496 { "roundss", { XM, EXx, Ib } },
2497 { "(bad)", { XX } },
2498 },
2499
2500 /* PREGRP72 */
2501 {
2502 { "(bad)", { XX } },
2503 { "(bad)", { XX } },
2504 { "roundsd", { XM, EXx, Ib } },
2505 { "(bad)", { XX } },
2506 },
2507
2508 /* PREGRP73 */
2509 {
2510 { "(bad)", { XX } },
2511 { "(bad)", { XX } },
2512 { "blendps", { XM, EXx, Ib } },
2513 { "(bad)", { XX } },
2514 },
2515
2516 /* PREGRP74 */
2517 {
2518 { "(bad)", { XX } },
2519 { "(bad)", { XX } },
2520 { "blendpd", { XM, EXx, Ib } },
2521 { "(bad)", { XX } },
2522 },
2523
2524 /* PREGRP75 */
2525 {
2526 { "(bad)", { XX } },
2527 { "(bad)", { XX } },
2528 { "pblendw", { XM, EXx, Ib } },
2529 { "(bad)", { XX } },
2530 },
2531
2532 /* PREGRP76 */
2533 {
2534 { "(bad)", { XX } },
2535 { "(bad)", { XX } },
2536 { "pextrb", { Edqb, XM, Ib } },
2537 { "(bad)", { XX } },
2538 },
2539
2540 /* PREGRP77 */
2541 {
2542 { "(bad)", { XX } },
2543 { "(bad)", { XX } },
2544 { "pextrw", { Edqw, XM, Ib } },
2545 { "(bad)", { XX } },
2546 },
2547
2548 /* PREGRP78 */
2549 {
2550 { "(bad)", { XX } },
2551 { "(bad)", { XX } },
2552 { "pextrK", { Edq, XM, Ib } },
2553 { "(bad)", { XX } },
2554 },
2555
2556 /* PREGRP79 */
2557 {
2558 { "(bad)", { XX } },
2559 { "(bad)", { XX } },
2560 { "extractps", { Edqd, XM, Ib } },
2561 { "(bad)", { XX } },
2562 },
2563
2564 /* PREGRP80 */
2565 {
2566 { "(bad)", { XX } },
2567 { "(bad)", { XX } },
2568 { "pinsrb", { XM, Edqb, Ib } },
2569 { "(bad)", { XX } },
2570 },
2571
2572 /* PREGRP81 */
2573 {
2574 { "(bad)", { XX } },
2575 { "(bad)", { XX } },
2576 { "insertps", { XM, EXx, Ib } },
2577 { "(bad)", { XX } },
2578 },
2579
2580 /* PREGRP82 */
2581 {
2582 { "(bad)", { XX } },
2583 { "(bad)", { XX } },
2584 { "pinsrK", { XM, Edq, Ib } },
2585 { "(bad)", { XX } },
2586 },
2587
2588 /* PREGRP83 */
2589 {
2590 { "(bad)", { XX } },
2591 { "(bad)", { XX } },
2592 { "dpps", { XM, EXx, Ib } },
2593 { "(bad)", { XX } },
2594 },
2595
2596 /* PREGRP84 */
2597 {
2598 { "(bad)", { XX } },
2599 { "(bad)", { XX } },
2600 { "dppd", { XM, EXx, Ib } },
2601 { "(bad)", { XX } },
2602 },
2603
2604 /* PREGRP85 */
2605 {
2606 { "(bad)", { XX } },
2607 { "(bad)", { XX } },
2608 { "mpsadbw", { XM, EXx, Ib } },
2609 { "(bad)", { XX } },
2610 },
2611
2612 /* PREGRP86 */
2613 {
2614 { "(bad)", { XX } },
2615 { "(bad)", { XX } },
2616 { "pcmpgtq", { XM, EXx } },
2617 { "(bad)", { XX } },
2618 },
2619
2620 /* PREGRP87 */
2621 {
2622 { "(bad)", { XX } },
2623 { "(bad)", { XX } },
2624 { "(bad)", { XX } },
2625 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
2626 },
2627
2628 /* PREGRP88 */
2629 {
2630 { "(bad)", { XX } },
2631 { "(bad)", { XX } },
2632 { "(bad)", { XX } },
2633 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
2634 },
2635
2636 /* PREGRP89 */
2637 {
2638 { "(bad)", { XX } },
2639 { "(bad)", { XX } },
2640 { "pcmpestrm", { XM, EXx, Ib } },
2641 { "(bad)", { XX } },
2642 },
2643
2644 /* PREGRP90 */
2645 {
2646 { "(bad)", { XX } },
2647 { "(bad)", { XX } },
2648 { "pcmpestri", { XM, EXx, Ib } },
2649 { "(bad)", { XX } },
2650 },
2651
2652 /* PREGRP91 */
2653 {
2654 { "(bad)", { XX } },
2655 { "(bad)", { XX } },
2656 { "pcmpistrm", { XM, EXx, Ib } },
2657 { "(bad)", { XX } },
2658 },
2659
2660 /* PREGRP92 */
2661 {
2662 { "(bad)", { XX } },
2663 { "(bad)", { XX } },
2664 { "pcmpistri", { XM, EXx, Ib } },
2665 { "(bad)", { XX } },
2666 },
2667
2668 /* PREGRP93 */
2669 {
2670 { "ucomiss",{ XM, EXd } },
2671 { "(bad)", { XX } },
2672 { "ucomisd",{ XM, EXq } },
2673 { "(bad)", { XX } },
2674 },
2675
2676 /* PREGRP94 */
2677 {
2678 { "comiss", { XM, EXd } },
2679 { "(bad)", { XX } },
2680 { "comisd", { XM, EXq } },
2681 { "(bad)", { XX } },
2682 },
2683
2684 /* PREGRP95 */
2685 {
2686 { "punpcklbw",{ MX, EMd } },
2687 { "(bad)", { XX } },
2688 { "punpcklbw",{ MX, EMq } },
2689 { "(bad)", { XX } },
2690 },
2691
2692 /* PREGRP96 */
2693 {
2694 { "punpcklwd",{ MX, EMd } },
2695 { "(bad)", { XX } },
2696 { "punpcklwd",{ MX, EMq } },
2697 { "(bad)", { XX } },
2698 },
2699
2700 /* PREGRP97 */
2701 {
2702 { "punpckldq",{ MX, EMd } },
2703 { "(bad)", { XX } },
2704 { "punpckldq",{ MX, EMq } },
2705 { "(bad)", { XX } },
c2c73b42 2706 },
bc51c5c9 2707};
dc99065b 2708
bc51c5c9
FB
2709static const struct dis386 x86_64_table[][2] = {
2710 {
88103cfe
BS
2711 { "pusha{P|}", { XX } },
2712 { "(bad)", { XX } },
2713 },
2714 {
2715 { "popa{P|}", { XX } },
2716 { "(bad)", { XX } },
2717 },
2718 {
2719 { "bound{S|}", { Gv, Ma } },
2720 { "(bad)", { XX } },
2721 },
2722 {
2723 { "arpl", { Ew, Gw } },
2724 { "movs{||lq|xd}", { Gv, Ed } },
bc51c5c9
FB
2725 },
2726};
2727
88103cfe 2728static const struct dis386 three_byte_table[][256] = {
c2c73b42
BS
2729 /* THREE_BYTE_0 */
2730 {
88103cfe
BS
2731 /* 00 */
2732 { "pshufb", { MX, EM } },
2733 { "phaddw", { MX, EM } },
2734 { "phaddd", { MX, EM } },
2735 { "phaddsw", { MX, EM } },
2736 { "pmaddubsw", { MX, EM } },
2737 { "phsubw", { MX, EM } },
2738 { "phsubd", { MX, EM } },
2739 { "phsubsw", { MX, EM } },
2740 /* 08 */
2741 { "psignb", { MX, EM } },
2742 { "psignw", { MX, EM } },
2743 { "psignd", { MX, EM } },
2744 { "pmulhrsw", { MX, EM } },
2745 { "(bad)", { XX } },
2746 { "(bad)", { XX } },
2747 { "(bad)", { XX } },
2748 { "(bad)", { XX } },
2749 /* 10 */
2750 { PREGRP39 },
2751 { "(bad)", { XX } },
2752 { "(bad)", { XX } },
2753 { "(bad)", { XX } },
2754 { PREGRP40 },
2755 { PREGRP41 },
2756 { "(bad)", { XX } },
2757 { PREGRP42 },
2758 /* 18 */
2759 { "(bad)", { XX } },
2760 { "(bad)", { XX } },
2761 { "(bad)", { XX } },
2762 { "(bad)", { XX } },
2763 { "pabsb", { MX, EM } },
2764 { "pabsw", { MX, EM } },
2765 { "pabsd", { MX, EM } },
2766 { "(bad)", { XX } },
2767 /* 20 */
2768 { PREGRP43 },
2769 { PREGRP44 },
2770 { PREGRP45 },
2771 { PREGRP46 },
2772 { PREGRP47 },
2773 { PREGRP48 },
2774 { "(bad)", { XX } },
2775 { "(bad)", { XX } },
2776 /* 28 */
2777 { PREGRP49 },
2778 { PREGRP50 },
2779 { PREGRP51 },
2780 { PREGRP52 },
2781 { "(bad)", { XX } },
2782 { "(bad)", { XX } },
2783 { "(bad)", { XX } },
2784 { "(bad)", { XX } },
2785 /* 30 */
2786 { PREGRP53 },
2787 { PREGRP54 },
2788 { PREGRP55 },
2789 { PREGRP56 },
2790 { PREGRP57 },
2791 { PREGRP58 },
2792 { "(bad)", { XX } },
2793 { PREGRP86 },
2794 /* 38 */
2795 { PREGRP59 },
2796 { PREGRP60 },
2797 { PREGRP61 },
2798 { PREGRP62 },
2799 { PREGRP63 },
2800 { PREGRP64 },
2801 { PREGRP65 },
2802 { PREGRP66 },
2803 /* 40 */
2804 { PREGRP67 },
2805 { PREGRP68 },
2806 { "(bad)", { XX } },
2807 { "(bad)", { XX } },
2808 { "(bad)", { XX } },
2809 { "(bad)", { XX } },
2810 { "(bad)", { XX } },
2811 { "(bad)", { XX } },
2812 /* 48 */
2813 { "(bad)", { XX } },
2814 { "(bad)", { XX } },
2815 { "(bad)", { XX } },
2816 { "(bad)", { XX } },
2817 { "(bad)", { XX } },
2818 { "(bad)", { XX } },
2819 { "(bad)", { XX } },
2820 { "(bad)", { XX } },
2821 /* 50 */
2822 { "(bad)", { XX } },
2823 { "(bad)", { XX } },
2824 { "(bad)", { XX } },
2825 { "(bad)", { XX } },
2826 { "(bad)", { XX } },
2827 { "(bad)", { XX } },
2828 { "(bad)", { XX } },
2829 { "(bad)", { XX } },
2830 /* 58 */
2831 { "(bad)", { XX } },
2832 { "(bad)", { XX } },
2833 { "(bad)", { XX } },
2834 { "(bad)", { XX } },
2835 { "(bad)", { XX } },
2836 { "(bad)", { XX } },
2837 { "(bad)", { XX } },
2838 { "(bad)", { XX } },
2839 /* 60 */
2840 { "(bad)", { XX } },
2841 { "(bad)", { XX } },
2842 { "(bad)", { XX } },
2843 { "(bad)", { XX } },
2844 { "(bad)", { XX } },
2845 { "(bad)", { XX } },
2846 { "(bad)", { XX } },
2847 { "(bad)", { XX } },
2848 /* 68 */
2849 { "(bad)", { XX } },
2850 { "(bad)", { XX } },
2851 { "(bad)", { XX } },
2852 { "(bad)", { XX } },
2853 { "(bad)", { XX } },
2854 { "(bad)", { XX } },
2855 { "(bad)", { XX } },
2856 { "(bad)", { XX } },
2857 /* 70 */
2858 { "(bad)", { XX } },
2859 { "(bad)", { XX } },
2860 { "(bad)", { XX } },
2861 { "(bad)", { XX } },
2862 { "(bad)", { XX } },
2863 { "(bad)", { XX } },
2864 { "(bad)", { XX } },
2865 { "(bad)", { XX } },
2866 /* 78 */
2867 { "(bad)", { XX } },
2868 { "(bad)", { XX } },
2869 { "(bad)", { XX } },
2870 { "(bad)", { XX } },
2871 { "(bad)", { XX } },
2872 { "(bad)", { XX } },
2873 { "(bad)", { XX } },
2874 { "(bad)", { XX } },
2875 /* 80 */
2876 { "(bad)", { XX } },
2877 { "(bad)", { XX } },
2878 { "(bad)", { XX } },
2879 { "(bad)", { XX } },
2880 { "(bad)", { XX } },
2881 { "(bad)", { XX } },
2882 { "(bad)", { XX } },
2883 { "(bad)", { XX } },
2884 /* 88 */
2885 { "(bad)", { XX } },
2886 { "(bad)", { XX } },
2887 { "(bad)", { XX } },
2888 { "(bad)", { XX } },
2889 { "(bad)", { XX } },
2890 { "(bad)", { XX } },
2891 { "(bad)", { XX } },
2892 { "(bad)", { XX } },
2893 /* 90 */
2894 { "(bad)", { XX } },
2895 { "(bad)", { XX } },
2896 { "(bad)", { XX } },
2897 { "(bad)", { XX } },
2898 { "(bad)", { XX } },
2899 { "(bad)", { XX } },
2900 { "(bad)", { XX } },
2901 { "(bad)", { XX } },
2902 /* 98 */
2903 { "(bad)", { XX } },
2904 { "(bad)", { XX } },
2905 { "(bad)", { XX } },
2906 { "(bad)", { XX } },
2907 { "(bad)", { XX } },
2908 { "(bad)", { XX } },
2909 { "(bad)", { XX } },
2910 { "(bad)", { XX } },
2911 /* a0 */
2912 { "(bad)", { XX } },
2913 { "(bad)", { XX } },
2914 { "(bad)", { XX } },
2915 { "(bad)", { XX } },
2916 { "(bad)", { XX } },
2917 { "(bad)", { XX } },
2918 { "(bad)", { XX } },
2919 { "(bad)", { XX } },
2920 /* a8 */
2921 { "(bad)", { XX } },
2922 { "(bad)", { XX } },
2923 { "(bad)", { XX } },
2924 { "(bad)", { XX } },
2925 { "(bad)", { XX } },
2926 { "(bad)", { XX } },
2927 { "(bad)", { XX } },
2928 { "(bad)", { XX } },
2929 /* b0 */
2930 { "(bad)", { XX } },
2931 { "(bad)", { XX } },
2932 { "(bad)", { XX } },
2933 { "(bad)", { XX } },
2934 { "(bad)", { XX } },
2935 { "(bad)", { XX } },
2936 { "(bad)", { XX } },
2937 { "(bad)", { XX } },
2938 /* b8 */
2939 { "(bad)", { XX } },
2940 { "(bad)", { XX } },
2941 { "(bad)", { XX } },
2942 { "(bad)", { XX } },
2943 { "(bad)", { XX } },
2944 { "(bad)", { XX } },
2945 { "(bad)", { XX } },
2946 { "(bad)", { XX } },
2947 /* c0 */
2948 { "(bad)", { XX } },
2949 { "(bad)", { XX } },
2950 { "(bad)", { XX } },
2951 { "(bad)", { XX } },
2952 { "(bad)", { XX } },
2953 { "(bad)", { XX } },
2954 { "(bad)", { XX } },
2955 { "(bad)", { XX } },
2956 /* c8 */
2957 { "(bad)", { XX } },
2958 { "(bad)", { XX } },
2959 { "(bad)", { XX } },
2960 { "(bad)", { XX } },
2961 { "(bad)", { XX } },
2962 { "(bad)", { XX } },
2963 { "(bad)", { XX } },
2964 { "(bad)", { XX } },
2965 /* d0 */
2966 { "(bad)", { XX } },
2967 { "(bad)", { XX } },
2968 { "(bad)", { XX } },
2969 { "(bad)", { XX } },
2970 { "(bad)", { XX } },
2971 { "(bad)", { XX } },
2972 { "(bad)", { XX } },
2973 { "(bad)", { XX } },
2974 /* d8 */
2975 { "(bad)", { XX } },
2976 { "(bad)", { XX } },
2977 { "(bad)", { XX } },
2978 { "(bad)", { XX } },
2979 { "(bad)", { XX } },
2980 { "(bad)", { XX } },
2981 { "(bad)", { XX } },
2982 { "(bad)", { XX } },
2983 /* e0 */
2984 { "(bad)", { XX } },
2985 { "(bad)", { XX } },
2986 { "(bad)", { XX } },
2987 { "(bad)", { XX } },
2988 { "(bad)", { XX } },
2989 { "(bad)", { XX } },
2990 { "(bad)", { XX } },
2991 { "(bad)", { XX } },
2992 /* e8 */
2993 { "(bad)", { XX } },
2994 { "(bad)", { XX } },
2995 { "(bad)", { XX } },
2996 { "(bad)", { XX } },
2997 { "(bad)", { XX } },
2998 { "(bad)", { XX } },
2999 { "(bad)", { XX } },
3000 { "(bad)", { XX } },
3001 /* f0 */
3002 { PREGRP87 },
3003 { PREGRP88 },
3004 { "(bad)", { XX } },
3005 { "(bad)", { XX } },
3006 { "(bad)", { XX } },
3007 { "(bad)", { XX } },
3008 { "(bad)", { XX } },
3009 { "(bad)", { XX } },
3010 /* f8 */
3011 { "(bad)", { XX } },
3012 { "(bad)", { XX } },
3013 { "(bad)", { XX } },
3014 { "(bad)", { XX } },
3015 { "(bad)", { XX } },
3016 { "(bad)", { XX } },
3017 { "(bad)", { XX } },
3018 { "(bad)", { XX } },
c2c73b42
BS
3019 },
3020 /* THREE_BYTE_1 */
3021 {
88103cfe
BS
3022 /* 00 */
3023 { "(bad)", { XX } },
3024 { "(bad)", { XX } },
3025 { "(bad)", { XX } },
3026 { "(bad)", { XX } },
3027 { "(bad)", { XX } },
3028 { "(bad)", { XX } },
3029 { "(bad)", { XX } },
3030 { "(bad)", { XX } },
3031 /* 08 */
3032 { PREGRP69 },
3033 { PREGRP70 },
3034 { PREGRP71 },
3035 { PREGRP72 },
3036 { PREGRP73 },
3037 { PREGRP74 },
3038 { PREGRP75 },
3039 { "palignr", { MX, EM, Ib } },
3040 /* 10 */
3041 { "(bad)", { XX } },
3042 { "(bad)", { XX } },
3043 { "(bad)", { XX } },
3044 { "(bad)", { XX } },
3045 { PREGRP76 },
3046 { PREGRP77 },
3047 { PREGRP78 },
3048 { PREGRP79 },
3049 /* 18 */
3050 { "(bad)", { XX } },
3051 { "(bad)", { XX } },
3052 { "(bad)", { XX } },
3053 { "(bad)", { XX } },
3054 { "(bad)", { XX } },
3055 { "(bad)", { XX } },
3056 { "(bad)", { XX } },
3057 { "(bad)", { XX } },
3058 /* 20 */
3059 { PREGRP80 },
3060 { PREGRP81 },
3061 { PREGRP82 },
3062 { "(bad)", { XX } },
3063 { "(bad)", { XX } },
3064 { "(bad)", { XX } },
3065 { "(bad)", { XX } },
3066 { "(bad)", { XX } },
3067 /* 28 */
3068 { "(bad)", { XX } },
3069 { "(bad)", { XX } },
3070 { "(bad)", { XX } },
3071 { "(bad)", { XX } },
3072 { "(bad)", { XX } },
3073 { "(bad)", { XX } },
3074 { "(bad)", { XX } },
3075 { "(bad)", { XX } },
3076 /* 30 */
3077 { "(bad)", { XX } },
3078 { "(bad)", { XX } },
3079 { "(bad)", { XX } },
3080 { "(bad)", { XX } },
3081 { "(bad)", { XX } },
3082 { "(bad)", { XX } },
3083 { "(bad)", { XX } },
3084 { "(bad)", { XX } },
3085 /* 38 */
3086 { "(bad)", { XX } },
3087 { "(bad)", { XX } },
3088 { "(bad)", { XX } },
3089 { "(bad)", { XX } },
3090 { "(bad)", { XX } },
3091 { "(bad)", { XX } },
3092 { "(bad)", { XX } },
3093 { "(bad)", { XX } },
3094 /* 40 */
3095 { PREGRP83 },
3096 { PREGRP84 },
3097 { PREGRP85 },
3098 { "(bad)", { XX } },
3099 { "(bad)", { XX } },
3100 { "(bad)", { XX } },
3101 { "(bad)", { XX } },
3102 { "(bad)", { XX } },
3103 /* 48 */
3104 { "(bad)", { XX } },
3105 { "(bad)", { XX } },
3106 { "(bad)", { XX } },
3107 { "(bad)", { XX } },
3108 { "(bad)", { XX } },
3109 { "(bad)", { XX } },
3110 { "(bad)", { XX } },
3111 { "(bad)", { XX } },
3112 /* 50 */
3113 { "(bad)", { XX } },
3114 { "(bad)", { XX } },
3115 { "(bad)", { XX } },
3116 { "(bad)", { XX } },
3117 { "(bad)", { XX } },
3118 { "(bad)", { XX } },
3119 { "(bad)", { XX } },
3120 { "(bad)", { XX } },
3121 /* 58 */
3122 { "(bad)", { XX } },
3123 { "(bad)", { XX } },
3124 { "(bad)", { XX } },
3125 { "(bad)", { XX } },
3126 { "(bad)", { XX } },
3127 { "(bad)", { XX } },
3128 { "(bad)", { XX } },
3129 { "(bad)", { XX } },
3130 /* 60 */
3131 { PREGRP89 },
3132 { PREGRP90 },
3133 { PREGRP91 },
3134 { PREGRP92 },
3135 { "(bad)", { XX } },
3136 { "(bad)", { XX } },
3137 { "(bad)", { XX } },
3138 { "(bad)", { XX } },
3139 /* 68 */
3140 { "(bad)", { XX } },
3141 { "(bad)", { XX } },
3142 { "(bad)", { XX } },
3143 { "(bad)", { XX } },
3144 { "(bad)", { XX } },
3145 { "(bad)", { XX } },
3146 { "(bad)", { XX } },
3147 { "(bad)", { XX } },
3148 /* 70 */
3149 { "(bad)", { XX } },
3150 { "(bad)", { XX } },
3151 { "(bad)", { XX } },
3152 { "(bad)", { XX } },
3153 { "(bad)", { XX } },
3154 { "(bad)", { XX } },
3155 { "(bad)", { XX } },
3156 { "(bad)", { XX } },
3157 /* 78 */
3158 { "(bad)", { XX } },
3159 { "(bad)", { XX } },
3160 { "(bad)", { XX } },
3161 { "(bad)", { XX } },
3162 { "(bad)", { XX } },
3163 { "(bad)", { XX } },
3164 { "(bad)", { XX } },
3165 { "(bad)", { XX } },
3166 /* 80 */
3167 { "(bad)", { XX } },
3168 { "(bad)", { XX } },
3169 { "(bad)", { XX } },
3170 { "(bad)", { XX } },
3171 { "(bad)", { XX } },
3172 { "(bad)", { XX } },
3173 { "(bad)", { XX } },
3174 { "(bad)", { XX } },
3175 /* 88 */
3176 { "(bad)", { XX } },
3177 { "(bad)", { XX } },
3178 { "(bad)", { XX } },
3179 { "(bad)", { XX } },
3180 { "(bad)", { XX } },
3181 { "(bad)", { XX } },
3182 { "(bad)", { XX } },
3183 { "(bad)", { XX } },
3184 /* 90 */
3185 { "(bad)", { XX } },
3186 { "(bad)", { XX } },
3187 { "(bad)", { XX } },
3188 { "(bad)", { XX } },
3189 { "(bad)", { XX } },
3190 { "(bad)", { XX } },
3191 { "(bad)", { XX } },
3192 { "(bad)", { XX } },
3193 /* 98 */
3194 { "(bad)", { XX } },
3195 { "(bad)", { XX } },
3196 { "(bad)", { XX } },
3197 { "(bad)", { XX } },
3198 { "(bad)", { XX } },
3199 { "(bad)", { XX } },
3200 { "(bad)", { XX } },
3201 { "(bad)", { XX } },
3202 /* a0 */
3203 { "(bad)", { XX } },
3204 { "(bad)", { XX } },
3205 { "(bad)", { XX } },
3206 { "(bad)", { XX } },
3207 { "(bad)", { XX } },
3208 { "(bad)", { XX } },
3209 { "(bad)", { XX } },
3210 { "(bad)", { XX } },
3211 /* a8 */
3212 { "(bad)", { XX } },
3213 { "(bad)", { XX } },
3214 { "(bad)", { XX } },
3215 { "(bad)", { XX } },
3216 { "(bad)", { XX } },
3217 { "(bad)", { XX } },
3218 { "(bad)", { XX } },
3219 { "(bad)", { XX } },
3220 /* b0 */
3221 { "(bad)", { XX } },
3222 { "(bad)", { XX } },
3223 { "(bad)", { XX } },
3224 { "(bad)", { XX } },
3225 { "(bad)", { XX } },
3226 { "(bad)", { XX } },
3227 { "(bad)", { XX } },
3228 { "(bad)", { XX } },
3229 /* b8 */
3230 { "(bad)", { XX } },
3231 { "(bad)", { XX } },
3232 { "(bad)", { XX } },
3233 { "(bad)", { XX } },
3234 { "(bad)", { XX } },
3235 { "(bad)", { XX } },
3236 { "(bad)", { XX } },
3237 { "(bad)", { XX } },
3238 /* c0 */
3239 { "(bad)", { XX } },
3240 { "(bad)", { XX } },
3241 { "(bad)", { XX } },
3242 { "(bad)", { XX } },
3243 { "(bad)", { XX } },
3244 { "(bad)", { XX } },
3245 { "(bad)", { XX } },
3246 { "(bad)", { XX } },
3247 /* c8 */
3248 { "(bad)", { XX } },
3249 { "(bad)", { XX } },
3250 { "(bad)", { XX } },
3251 { "(bad)", { XX } },
3252 { "(bad)", { XX } },
3253 { "(bad)", { XX } },
3254 { "(bad)", { XX } },
3255 { "(bad)", { XX } },
3256 /* d0 */
3257 { "(bad)", { XX } },
3258 { "(bad)", { XX } },
3259 { "(bad)", { XX } },
3260 { "(bad)", { XX } },
3261 { "(bad)", { XX } },
3262 { "(bad)", { XX } },
3263 { "(bad)", { XX } },
3264 { "(bad)", { XX } },
3265 /* d8 */
3266 { "(bad)", { XX } },
3267 { "(bad)", { XX } },
3268 { "(bad)", { XX } },
3269 { "(bad)", { XX } },
3270 { "(bad)", { XX } },
3271 { "(bad)", { XX } },
3272 { "(bad)", { XX } },
3273 { "(bad)", { XX } },
3274 /* e0 */
3275 { "(bad)", { XX } },
3276 { "(bad)", { XX } },
3277 { "(bad)", { XX } },
3278 { "(bad)", { XX } },
3279 { "(bad)", { XX } },
3280 { "(bad)", { XX } },
3281 { "(bad)", { XX } },
3282 { "(bad)", { XX } },
3283 /* e8 */
3284 { "(bad)", { XX } },
3285 { "(bad)", { XX } },
3286 { "(bad)", { XX } },
3287 { "(bad)", { XX } },
3288 { "(bad)", { XX } },
3289 { "(bad)", { XX } },
3290 { "(bad)", { XX } },
3291 { "(bad)", { XX } },
3292 /* f0 */
3293 { "(bad)", { XX } },
3294 { "(bad)", { XX } },
3295 { "(bad)", { XX } },
3296 { "(bad)", { XX } },
3297 { "(bad)", { XX } },
3298 { "(bad)", { XX } },
3299 { "(bad)", { XX } },
3300 { "(bad)", { XX } },
3301 /* f8 */
3302 { "(bad)", { XX } },
3303 { "(bad)", { XX } },
3304 { "(bad)", { XX } },
3305 { "(bad)", { XX } },
3306 { "(bad)", { XX } },
3307 { "(bad)", { XX } },
3308 { "(bad)", { XX } },
3309 { "(bad)", { XX } },
3310 }
c2c73b42
BS
3311};
3312
bc51c5c9 3313#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
dc99065b
FB
3314
3315static void
c2c73b42 3316ckprefix (void)
dc99065b 3317{
bc51c5c9
FB
3318 int newrex;
3319 rex = 0;
dc99065b 3320 prefixes = 0;
bc51c5c9
FB
3321 used_prefixes = 0;
3322 rex_used = 0;
dc99065b
FB
3323 while (1)
3324 {
3325 FETCH_DATA (the_info, codep + 1);
bc51c5c9 3326 newrex = 0;
dc99065b
FB
3327 switch (*codep)
3328 {
bc51c5c9
FB
3329 /* REX prefixes family. */
3330 case 0x40:
3331 case 0x41:
3332 case 0x42:
3333 case 0x43:
3334 case 0x44:
3335 case 0x45:
3336 case 0x46:
3337 case 0x47:
3338 case 0x48:
3339 case 0x49:
3340 case 0x4a:
3341 case 0x4b:
3342 case 0x4c:
3343 case 0x4d:
3344 case 0x4e:
3345 case 0x4f:
c2c73b42 3346 if (address_mode == mode_64bit)
bc51c5c9
FB
3347 newrex = *codep;
3348 else
3349 return;
3350 break;
dc99065b
FB
3351 case 0xf3:
3352 prefixes |= PREFIX_REPZ;
3353 break;
3354 case 0xf2:
3355 prefixes |= PREFIX_REPNZ;
3356 break;
3357 case 0xf0:
3358 prefixes |= PREFIX_LOCK;
3359 break;
3360 case 0x2e:
3361 prefixes |= PREFIX_CS;
3362 break;
3363 case 0x36:
3364 prefixes |= PREFIX_SS;
3365 break;
3366 case 0x3e:
3367 prefixes |= PREFIX_DS;
3368 break;
3369 case 0x26:
3370 prefixes |= PREFIX_ES;
3371 break;
3372 case 0x64:
3373 prefixes |= PREFIX_FS;
3374 break;
3375 case 0x65:
3376 prefixes |= PREFIX_GS;
3377 break;
3378 case 0x66:
3379 prefixes |= PREFIX_DATA;
3380 break;
3381 case 0x67:
bc51c5c9 3382 prefixes |= PREFIX_ADDR;
dc99065b 3383 break;
bc51c5c9
FB
3384 case FWAIT_OPCODE:
3385 /* fwait is really an instruction. If there are prefixes
3386 before the fwait, they belong to the fwait, *not* to the
3387 following instruction. */
c2c73b42 3388 if (prefixes || rex)
bc51c5c9
FB
3389 {
3390 prefixes |= PREFIX_FWAIT;
3391 codep++;
3392 return;
3393 }
3394 prefixes = PREFIX_FWAIT;
dc99065b
FB
3395 break;
3396 default:
3397 return;
3398 }
bc51c5c9
FB
3399 /* Rex is ignored when followed by another prefix. */
3400 if (rex)
3401 {
c2c73b42
BS
3402 rex_used = rex;
3403 return;
bc51c5c9
FB
3404 }
3405 rex = newrex;
dc99065b
FB
3406 codep++;
3407 }
3408}
3409
bc51c5c9
FB
3410/* Return the name of the prefix byte PREF, or NULL if PREF is not a
3411 prefix byte. */
3412
3413static const char *
c2c73b42 3414prefix_name (int pref, int sizeflag)
bc51c5c9 3415{
88103cfe
BS
3416 static const char * const rexes [16] =
3417 {
3418 "rex", /* 0x40 */
3419 "rex.B", /* 0x41 */
3420 "rex.X", /* 0x42 */
3421 "rex.XB", /* 0x43 */
3422 "rex.R", /* 0x44 */
3423 "rex.RB", /* 0x45 */
3424 "rex.RX", /* 0x46 */
3425 "rex.RXB", /* 0x47 */
3426 "rex.W", /* 0x48 */
3427 "rex.WB", /* 0x49 */
3428 "rex.WX", /* 0x4a */
3429 "rex.WXB", /* 0x4b */
3430 "rex.WR", /* 0x4c */
3431 "rex.WRB", /* 0x4d */
3432 "rex.WRX", /* 0x4e */
3433 "rex.WRXB", /* 0x4f */
3434 };
3435
bc51c5c9
FB
3436 switch (pref)
3437 {
3438 /* REX prefixes family. */
3439 case 0x40:
bc51c5c9 3440 case 0x41:
bc51c5c9 3441 case 0x42:
bc51c5c9 3442 case 0x43:
bc51c5c9 3443 case 0x44:
bc51c5c9 3444 case 0x45:
bc51c5c9 3445 case 0x46:
bc51c5c9 3446 case 0x47:
bc51c5c9 3447 case 0x48:
bc51c5c9 3448 case 0x49:
bc51c5c9 3449 case 0x4a:
bc51c5c9 3450 case 0x4b:
bc51c5c9 3451 case 0x4c:
bc51c5c9 3452 case 0x4d:
bc51c5c9 3453 case 0x4e:
bc51c5c9 3454 case 0x4f:
88103cfe 3455 return rexes [pref - 0x40];
bc51c5c9
FB
3456 case 0xf3:
3457 return "repz";
3458 case 0xf2:
3459 return "repnz";
3460 case 0xf0:
3461 return "lock";
3462 case 0x2e:
3463 return "cs";
3464 case 0x36:
3465 return "ss";
3466 case 0x3e:
3467 return "ds";
3468 case 0x26:
3469 return "es";
3470 case 0x64:
3471 return "fs";
3472 case 0x65:
3473 return "gs";
3474 case 0x66:
3475 return (sizeflag & DFLAG) ? "data16" : "data32";
3476 case 0x67:
c2c73b42
BS
3477 if (address_mode == mode_64bit)
3478 return (sizeflag & AFLAG) ? "addr32" : "addr64";
bc51c5c9 3479 else
c2c73b42 3480 return (sizeflag & AFLAG) ? "addr16" : "addr32";
bc51c5c9
FB
3481 case FWAIT_OPCODE:
3482 return "fwait";
3483 default:
3484 return NULL;
3485 }
3486}
dc99065b 3487
88103cfe
BS
3488static char op_out[MAX_OPERANDS][100];
3489static int op_ad, op_index[MAX_OPERANDS];
c2c73b42 3490static int two_source_ops;
88103cfe
BS
3491static bfd_vma op_address[MAX_OPERANDS];
3492static bfd_vma op_riprel[MAX_OPERANDS];
bc51c5c9 3493static bfd_vma start_pc;
88103cfe 3494
dc99065b
FB
3495/*
3496 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3497 * (see topic "Redundant prefixes" in the "Differences from 8086"
3498 * section of the "Virtual 8086 Mode" chapter.)
3499 * 'pc' should be the address of this instruction, it will
3500 * be used to print the target address if this is a relative jump or call
3501 * The function returns the length of this instruction in bytes.
3502 */
3503
c2c73b42 3504static char intel_syntax;
bc51c5c9
FB
3505static char open_char;
3506static char close_char;
3507static char separator_char;
3508static char scale_char;
3509
dc99065b 3510int
c2c73b42 3511print_insn_i386 (bfd_vma pc, disassemble_info *info)
bc51c5c9
FB
3512{
3513 intel_syntax = -1;
3514
3515 return print_insn (pc, info);
3516}
3517
3518static int
c2c73b42 3519print_insn (bfd_vma pc, disassemble_info *info)
dc99065b 3520{
bc51c5c9 3521 const struct dis386 *dp;
dc99065b 3522 int i;
88103cfe 3523 char *op_txt[MAX_OPERANDS];
dc99065b 3524 int needcomma;
88103cfe
BS
3525 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3526 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
bc51c5c9
FB
3527 int sizeflag;
3528 const char *p;
dc99065b 3529 struct dis_private priv;
88103cfe 3530 unsigned char op;
dc99065b 3531
c2c73b42
BS
3532 if (info->mach == bfd_mach_x86_64_intel_syntax
3533 || info->mach == bfd_mach_x86_64)
3534 address_mode = mode_64bit;
3535 else
3536 address_mode = mode_32bit;
bc51c5c9 3537
c2c73b42 3538 if (intel_syntax == (char) -1)
bc51c5c9
FB
3539 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
3540 || info->mach == bfd_mach_x86_64_intel_syntax);
3541
3542 if (info->mach == bfd_mach_i386_i386
3543 || info->mach == bfd_mach_x86_64
3544 || info->mach == bfd_mach_i386_i386_intel_syntax
3545 || info->mach == bfd_mach_x86_64_intel_syntax)
3546 priv.orig_sizeflag = AFLAG | DFLAG;
3547 else if (info->mach == bfd_mach_i386_i8086)
3548 priv.orig_sizeflag = 0;
3549 else
3550 abort ();
3551
3552 for (p = info->disassembler_options; p != NULL; )
3553 {
3554 if (strncmp (p, "x86-64", 6) == 0)
3555 {
c2c73b42 3556 address_mode = mode_64bit;
bc51c5c9
FB
3557 priv.orig_sizeflag = AFLAG | DFLAG;
3558 }
3559 else if (strncmp (p, "i386", 4) == 0)
3560 {
c2c73b42 3561 address_mode = mode_32bit;
bc51c5c9
FB
3562 priv.orig_sizeflag = AFLAG | DFLAG;
3563 }
3564 else if (strncmp (p, "i8086", 5) == 0)
3565 {
c2c73b42 3566 address_mode = mode_16bit;
bc51c5c9
FB
3567 priv.orig_sizeflag = 0;
3568 }
3569 else if (strncmp (p, "intel", 5) == 0)
3570 {
3571 intel_syntax = 1;
3572 }
3573 else if (strncmp (p, "att", 3) == 0)
3574 {
3575 intel_syntax = 0;
3576 }
3577 else if (strncmp (p, "addr", 4) == 0)
3578 {
88103cfe
BS
3579 if (address_mode == mode_64bit)
3580 {
3581 if (p[4] == '3' && p[5] == '2')
3582 priv.orig_sizeflag &= ~AFLAG;
3583 else if (p[4] == '6' && p[5] == '4')
3584 priv.orig_sizeflag |= AFLAG;
3585 }
3586 else
3587 {
3588 if (p[4] == '1' && p[5] == '6')
3589 priv.orig_sizeflag &= ~AFLAG;
3590 else if (p[4] == '3' && p[5] == '2')
3591 priv.orig_sizeflag |= AFLAG;
3592 }
bc51c5c9
FB
3593 }
3594 else if (strncmp (p, "data", 4) == 0)
3595 {
3596 if (p[4] == '1' && p[5] == '6')
3597 priv.orig_sizeflag &= ~DFLAG;
3598 else if (p[4] == '3' && p[5] == '2')
3599 priv.orig_sizeflag |= DFLAG;
3600 }
3601 else if (strncmp (p, "suffix", 6) == 0)
3602 priv.orig_sizeflag |= SUFFIX_ALWAYS;
3603
3604 p = strchr (p, ',');
3605 if (p != NULL)
3606 p++;
3607 }
3608
3609 if (intel_syntax)
3610 {
3611 names64 = intel_names64;
3612 names32 = intel_names32;
3613 names16 = intel_names16;
3614 names8 = intel_names8;
3615 names8rex = intel_names8rex;
3616 names_seg = intel_names_seg;
3617 index16 = intel_index16;
3618 open_char = '[';
3619 close_char = ']';
3620 separator_char = '+';
3621 scale_char = '*';
3622 }
3623 else
3624 {
3625 names64 = att_names64;
3626 names32 = att_names32;
3627 names16 = att_names16;
3628 names8 = att_names8;
3629 names8rex = att_names8rex;
3630 names_seg = att_names_seg;
3631 index16 = att_index16;
3632 open_char = '(';
3633 close_char = ')';
3634 separator_char = ',';
3635 scale_char = ',';
3636 }
3637
3638 /* The output looks better if we put 7 bytes on a line, since that
3639 puts most long word instructions on a single line. */
3640 info->bytes_per_line = 7;
dc99065b 3641
c2c73b42 3642 info->private_data = &priv;
dc99065b
FB
3643 priv.max_fetched = priv.the_buffer;
3644 priv.insn_start = pc;
dc99065b
FB
3645
3646 obuf[0] = 0;
88103cfe
BS
3647 for (i = 0; i < MAX_OPERANDS; ++i)
3648 {
3649 op_out[i][0] = 0;
3650 op_index[i] = -1;
3651 }
dc99065b
FB
3652
3653 the_info = info;
3654 start_pc = pc;
bc51c5c9
FB
3655 start_codep = priv.the_buffer;
3656 codep = priv.the_buffer;
3657
3658 if (setjmp (priv.bailout) != 0)
3659 {
3660 const char *name;
3661
3662 /* Getting here means we tried for data but didn't get it. That
3663 means we have an incomplete instruction of some sort. Just
3664 print the first byte as a prefix or a .byte pseudo-op. */
3665 if (codep > priv.the_buffer)
3666 {
3667 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3668 if (name != NULL)
3669 (*info->fprintf_func) (info->stream, "%s", name);
3670 else
3671 {
3672 /* Just print the first byte as a .byte instruction. */
3673 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3674 (unsigned int) priv.the_buffer[0]);
3675 }
3676
3677 return 1;
3678 }
3679
3680 return -1;
3681 }
3682
3683 obufp = obuf;
dc99065b
FB
3684 ckprefix ();
3685
bc51c5c9
FB
3686 insn_codep = codep;
3687 sizeflag = priv.orig_sizeflag;
3688
dc99065b 3689 FETCH_DATA (info, codep + 1);
bc51c5c9
FB
3690 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3691
c2c73b42
BS
3692 if (((prefixes & PREFIX_FWAIT)
3693 && ((*codep < 0xd8) || (*codep > 0xdf)))
3694 || (rex && rex_used))
dc99065b 3695 {
bc51c5c9
FB
3696 const char *name;
3697
c2c73b42
BS
3698 /* fwait not followed by floating point instruction, or rex followed
3699 by other prefixes. Print the first prefix. */
bc51c5c9
FB
3700 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3701 if (name == NULL)
3702 name = INTERNAL_DISASSEMBLER_ERROR;
3703 (*info->fprintf_func) (info->stream, "%s", name);
3704 return 1;
dc99065b 3705 }
bc51c5c9 3706
88103cfe 3707 op = 0;
dc99065b
FB
3708 if (*codep == 0x0f)
3709 {
88103cfe 3710 unsigned char threebyte;
dc99065b 3711 FETCH_DATA (info, codep + 2);
88103cfe
BS
3712 threebyte = *++codep;
3713 dp = &dis386_twobyte[threebyte];
dc99065b 3714 need_modrm = twobyte_has_modrm[*codep];
88103cfe
BS
3715 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3716 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3717 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
c2c73b42 3718 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
88103cfe
BS
3719 codep++;
3720 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3721 {
3722 FETCH_DATA (info, codep + 2);
3723 op = *codep++;
3724 switch (threebyte)
3725 {
3726 case 0x38:
3727 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3728 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3729 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3730 break;
3731 case 0x3a:
3732 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3733 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3734 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3735 break;
3736 default:
3737 break;
3738 }
3739 }
dc99065b
FB
3740 }
3741 else
3742 {
3743 dp = &dis386[*codep];
3744 need_modrm = onebyte_has_modrm[*codep];
88103cfe
BS
3745 uses_DATA_prefix = 0;
3746 uses_REPNZ_prefix = 0;
3747 /* pause is 0xf3 0x90. */
3748 uses_REPZ_prefix = *codep == 0x90;
c2c73b42 3749 uses_LOCK_prefix = 0;
88103cfe 3750 codep++;
dc99065b 3751 }
dc99065b 3752
88103cfe 3753 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
bc51c5c9
FB
3754 {
3755 oappend ("repz ");
3756 used_prefixes |= PREFIX_REPZ;
3757 }
88103cfe 3758 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
bc51c5c9
FB
3759 {
3760 oappend ("repnz ");
3761 used_prefixes |= PREFIX_REPNZ;
3762 }
88103cfe 3763
c2c73b42 3764 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
bc51c5c9
FB
3765 {
3766 oappend ("lock ");
3767 used_prefixes |= PREFIX_LOCK;
3768 }
3769
3770 if (prefixes & PREFIX_ADDR)
3771 {
3772 sizeflag ^= AFLAG;
88103cfe 3773 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
bc51c5c9 3774 {
c2c73b42 3775 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
bc51c5c9
FB
3776 oappend ("addr32 ");
3777 else
3778 oappend ("addr16 ");
3779 used_prefixes |= PREFIX_ADDR;
3780 }
3781 }
3782
88103cfe 3783 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
bc51c5c9
FB
3784 {
3785 sizeflag ^= DFLAG;
88103cfe
BS
3786 if (dp->op[2].bytemode == cond_jump_mode
3787 && dp->op[0].bytemode == v_mode
bc51c5c9
FB
3788 && !intel_syntax)
3789 {
3790 if (sizeflag & DFLAG)
3791 oappend ("data32 ");
3792 else
3793 oappend ("data16 ");
3794 used_prefixes |= PREFIX_DATA;
3795 }
3796 }
3797
88103cfe 3798 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
c2c73b42 3799 {
88103cfe
BS
3800 dp = &three_byte_table[dp->op[1].bytemode][op];
3801 modrm.mod = (*codep >> 6) & 3;
3802 modrm.reg = (*codep >> 3) & 7;
3803 modrm.rm = *codep & 7;
c2c73b42
BS
3804 }
3805 else if (need_modrm)
dc99065b
FB
3806 {
3807 FETCH_DATA (info, codep + 1);
88103cfe
BS
3808 modrm.mod = (*codep >> 6) & 3;
3809 modrm.reg = (*codep >> 3) & 7;
3810 modrm.rm = *codep & 7;
dc99065b
FB
3811 }
3812
88103cfe 3813 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
dc99065b 3814 {
bc51c5c9 3815 dofloat (sizeflag);
dc99065b
FB
3816 }
3817 else
3818 {
bc51c5c9 3819 int index;
dc99065b 3820 if (dp->name == NULL)
bc51c5c9 3821 {
88103cfe 3822 switch (dp->op[0].bytemode)
bc51c5c9
FB
3823 {
3824 case USE_GROUPS:
88103cfe 3825 dp = &grps[dp->op[1].bytemode][modrm.reg];
bc51c5c9
FB
3826 break;
3827
3828 case USE_PREFIX_USER_TABLE:
3829 index = 0;
3830 used_prefixes |= (prefixes & PREFIX_REPZ);
3831 if (prefixes & PREFIX_REPZ)
3832 index = 1;
3833 else
3834 {
88103cfe
BS
3835 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3836 before PREFIX_DATA. */
3837 used_prefixes |= (prefixes & PREFIX_REPNZ);
3838 if (prefixes & PREFIX_REPNZ)
3839 index = 3;
bc51c5c9
FB
3840 else
3841 {
88103cfe
BS
3842 used_prefixes |= (prefixes & PREFIX_DATA);
3843 if (prefixes & PREFIX_DATA)
3844 index = 2;
bc51c5c9
FB
3845 }
3846 }
88103cfe 3847 dp = &prefix_user_table[dp->op[1].bytemode][index];
bc51c5c9
FB
3848 break;
3849
3850 case X86_64_SPECIAL:
c2c73b42 3851 index = address_mode == mode_64bit ? 1 : 0;
88103cfe 3852 dp = &x86_64_table[dp->op[1].bytemode][index];
bc51c5c9
FB
3853 break;
3854
3855 default:
3856 oappend (INTERNAL_DISASSEMBLER_ERROR);
3857 break;
3858 }
3859 }
3860
3861 if (putop (dp->name, sizeflag) == 0)
88103cfe
BS
3862 {
3863 for (i = 0; i < MAX_OPERANDS; ++i)
3864 {
3865 obufp = op_out[i];
3866 op_ad = MAX_OPERANDS - 1 - i;
3867 if (dp->op[i].rtn)
3868 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3869 }
bc51c5c9
FB
3870 }
3871 }
3872
3873 /* See if any prefixes were not used. If so, print the first one
3874 separately. If we don't do this, we'll wind up printing an
3875 instruction stream which does not precisely correspond to the
3876 bytes we are disassembling. */
3877 if ((prefixes & ~used_prefixes) != 0)
3878 {
3879 const char *name;
3880
3881 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3882 if (name == NULL)
3883 name = INTERNAL_DISASSEMBLER_ERROR;
3884 (*info->fprintf_func) (info->stream, "%s", name);
3885 return 1;
3886 }
3887 if (rex & ~rex_used)
3888 {
3889 const char *name;
3890 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3891 if (name == NULL)
3892 name = INTERNAL_DISASSEMBLER_ERROR;
3893 (*info->fprintf_func) (info->stream, "%s ", name);
dc99065b 3894 }
bc51c5c9 3895
dc99065b
FB
3896 obufp = obuf + strlen (obuf);
3897 for (i = strlen (obuf); i < 6; i++)
3898 oappend (" ");
3899 oappend (" ");
3900 (*info->fprintf_func) (info->stream, "%s", obuf);
bc51c5c9
FB
3901
3902 /* The enter and bound instructions are printed with operands in the same
3903 order as the intel book; everything else is printed in reverse order. */
3904 if (intel_syntax || two_source_ops)
dc99065b 3905 {
88103cfe
BS
3906 bfd_vma riprel;
3907
3908 for (i = 0; i < MAX_OPERANDS; ++i)
3909 op_txt[i] = op_out[i];
3910
3911 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3912 {
3913 op_ad = op_index[i];
3914 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3915 op_index[MAX_OPERANDS - 1 - i] = op_ad;
3916 riprel = op_riprel[i];
3917 op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
3918 op_riprel[MAX_OPERANDS - 1 - i] = riprel;
3919 }
dc99065b
FB
3920 }
3921 else
3922 {
88103cfe
BS
3923 for (i = 0; i < MAX_OPERANDS; ++i)
3924 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
dc99065b 3925 }
88103cfe 3926
dc99065b 3927 needcomma = 0;
88103cfe
BS
3928 for (i = 0; i < MAX_OPERANDS; ++i)
3929 if (*op_txt[i])
3930 {
3931 if (needcomma)
3932 (*info->fprintf_func) (info->stream, ",");
3933 if (op_index[i] != -1 && !op_riprel[i])
3934 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3935 else
3936 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3937 needcomma = 1;
3938 }
3939
3940 for (i = 0; i < MAX_OPERANDS; i++)
bc51c5c9
FB
3941 if (op_index[i] != -1 && op_riprel[i])
3942 {
3943 (*info->fprintf_func) (info->stream, " # ");
3944 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3945 + op_address[op_index[i]]), info);
88103cfe 3946 break;
bc51c5c9
FB
3947 }
3948 return codep - priv.the_buffer;
dc99065b
FB
3949}
3950
bc51c5c9 3951static const char *float_mem[] = {
dc99065b 3952 /* d8 */
bc51c5c9
FB
3953 "fadd{s||s|}",
3954 "fmul{s||s|}",
3955 "fcom{s||s|}",
3956 "fcomp{s||s|}",
3957 "fsub{s||s|}",
3958 "fsubr{s||s|}",
3959 "fdiv{s||s|}",
3960 "fdivr{s||s|}",
c2c73b42 3961 /* d9 */
bc51c5c9 3962 "fld{s||s|}",
dc99065b 3963 "(bad)",
bc51c5c9
FB
3964 "fst{s||s|}",
3965 "fstp{s||s|}",
c2c73b42 3966 "fldenvIC",
dc99065b 3967 "fldcw",
c2c73b42 3968 "fNstenvIC",
dc99065b
FB
3969 "fNstcw",
3970 /* da */
bc51c5c9
FB
3971 "fiadd{l||l|}",
3972 "fimul{l||l|}",
3973 "ficom{l||l|}",
3974 "ficomp{l||l|}",
3975 "fisub{l||l|}",
3976 "fisubr{l||l|}",
3977 "fidiv{l||l|}",
3978 "fidivr{l||l|}",
dc99065b 3979 /* db */
bc51c5c9 3980 "fild{l||l|}",
c2c73b42 3981 "fisttp{l||l|}",
bc51c5c9
FB
3982 "fist{l||l|}",
3983 "fistp{l||l|}",
dc99065b 3984 "(bad)",
bc51c5c9 3985 "fld{t||t|}",
dc99065b 3986 "(bad)",
bc51c5c9 3987 "fstp{t||t|}",
dc99065b 3988 /* dc */
bc51c5c9
FB
3989 "fadd{l||l|}",
3990 "fmul{l||l|}",
3991 "fcom{l||l|}",
3992 "fcomp{l||l|}",
3993 "fsub{l||l|}",
3994 "fsubr{l||l|}",
3995 "fdiv{l||l|}",
3996 "fdivr{l||l|}",
dc99065b 3997 /* dd */
bc51c5c9 3998 "fld{l||l|}",
c2c73b42 3999 "fisttp{ll||ll|}",
bc51c5c9
FB
4000 "fst{l||l|}",
4001 "fstp{l||l|}",
c2c73b42 4002 "frstorIC",
dc99065b 4003 "(bad)",
c2c73b42 4004 "fNsaveIC",
dc99065b
FB
4005 "fNstsw",
4006 /* de */
4007 "fiadd",
4008 "fimul",
4009 "ficom",
4010 "ficomp",
4011 "fisub",
4012 "fisubr",
4013 "fidiv",
4014 "fidivr",
4015 /* df */
4016 "fild",
c2c73b42 4017 "fisttp",
dc99065b
FB
4018 "fist",
4019 "fistp",
4020 "fbld",
bc51c5c9 4021 "fild{ll||ll|}",
dc99065b 4022 "fbstp",
c2c73b42
BS
4023 "fistp{ll||ll|}",
4024};
4025
4026static const unsigned char float_mem_mode[] = {
4027 /* d8 */
4028 d_mode,
4029 d_mode,
4030 d_mode,
4031 d_mode,
4032 d_mode,
4033 d_mode,
4034 d_mode,
4035 d_mode,
4036 /* d9 */
4037 d_mode,
4038 0,
4039 d_mode,
4040 d_mode,
4041 0,
4042 w_mode,
4043 0,
4044 w_mode,
4045 /* da */
4046 d_mode,
4047 d_mode,
4048 d_mode,
4049 d_mode,
4050 d_mode,
4051 d_mode,
4052 d_mode,
4053 d_mode,
4054 /* db */
4055 d_mode,
4056 d_mode,
4057 d_mode,
4058 d_mode,
4059 0,
4060 t_mode,
4061 0,
4062 t_mode,
4063 /* dc */
4064 q_mode,
4065 q_mode,
4066 q_mode,
4067 q_mode,
4068 q_mode,
4069 q_mode,
4070 q_mode,
4071 q_mode,
4072 /* dd */
4073 q_mode,
4074 q_mode,
4075 q_mode,
4076 q_mode,
4077 0,
4078 0,
4079 0,
4080 w_mode,
4081 /* de */
4082 w_mode,
4083 w_mode,
4084 w_mode,
4085 w_mode,
4086 w_mode,
4087 w_mode,
4088 w_mode,
4089 w_mode,
4090 /* df */
4091 w_mode,
4092 w_mode,
4093 w_mode,
4094 w_mode,
4095 t_mode,
4096 q_mode,
4097 t_mode,
4098 q_mode
dc99065b
FB
4099};
4100
88103cfe
BS
4101#define ST { OP_ST, 0 }
4102#define STi { OP_STi, 0 }
dc99065b 4103
88103cfe
BS
4104#define FGRPd9_2 NULL, { { NULL, 0 } }
4105#define FGRPd9_4 NULL, { { NULL, 1 } }
4106#define FGRPd9_5 NULL, { { NULL, 2 } }
4107#define FGRPd9_6 NULL, { { NULL, 3 } }
4108#define FGRPd9_7 NULL, { { NULL, 4 } }
4109#define FGRPda_5 NULL, { { NULL, 5 } }
4110#define FGRPdb_4 NULL, { { NULL, 6 } }
4111#define FGRPde_3 NULL, { { NULL, 7 } }
4112#define FGRPdf_4 NULL, { { NULL, 8 } }
bc51c5c9
FB
4113
4114static const struct dis386 float_reg[][8] = {
dc99065b
FB
4115 /* d8 */
4116 {
88103cfe
BS
4117 { "fadd", { ST, STi } },
4118 { "fmul", { ST, STi } },
4119 { "fcom", { STi } },
4120 { "fcomp", { STi } },
4121 { "fsub", { ST, STi } },
4122 { "fsubr", { ST, STi } },
4123 { "fdiv", { ST, STi } },
4124 { "fdivr", { ST, STi } },
dc99065b
FB
4125 },
4126 /* d9 */
4127 {
88103cfe
BS
4128 { "fld", { STi } },
4129 { "fxch", { STi } },
dc99065b 4130 { FGRPd9_2 },
88103cfe 4131 { "(bad)", { XX } },
dc99065b
FB
4132 { FGRPd9_4 },
4133 { FGRPd9_5 },
4134 { FGRPd9_6 },
4135 { FGRPd9_7 },
4136 },
4137 /* da */
4138 {
88103cfe
BS
4139 { "fcmovb", { ST, STi } },
4140 { "fcmove", { ST, STi } },
4141 { "fcmovbe",{ ST, STi } },
4142 { "fcmovu", { ST, STi } },
4143 { "(bad)", { XX } },
dc99065b 4144 { FGRPda_5 },
88103cfe
BS
4145 { "(bad)", { XX } },
4146 { "(bad)", { XX } },
dc99065b
FB
4147 },
4148 /* db */
4149 {
88103cfe
BS
4150 { "fcmovnb",{ ST, STi } },
4151 { "fcmovne",{ ST, STi } },
4152 { "fcmovnbe",{ ST, STi } },
4153 { "fcmovnu",{ ST, STi } },
dc99065b 4154 { FGRPdb_4 },
88103cfe
BS
4155 { "fucomi", { ST, STi } },
4156 { "fcomi", { ST, STi } },
4157 { "(bad)", { XX } },
dc99065b
FB
4158 },
4159 /* dc */
4160 {
88103cfe
BS
4161 { "fadd", { STi, ST } },
4162 { "fmul", { STi, ST } },
4163 { "(bad)", { XX } },
4164 { "(bad)", { XX } },
4165#if SYSV386_COMPAT
4166 { "fsub", { STi, ST } },
4167 { "fsubr", { STi, ST } },
4168 { "fdiv", { STi, ST } },
4169 { "fdivr", { STi, ST } },
bc51c5c9 4170#else
88103cfe
BS
4171 { "fsubr", { STi, ST } },
4172 { "fsub", { STi, ST } },
4173 { "fdivr", { STi, ST } },
4174 { "fdiv", { STi, ST } },
bc51c5c9 4175#endif
dc99065b
FB
4176 },
4177 /* dd */
4178 {
88103cfe
BS
4179 { "ffree", { STi } },
4180 { "(bad)", { XX } },
4181 { "fst", { STi } },
4182 { "fstp", { STi } },
4183 { "fucom", { STi } },
4184 { "fucomp", { STi } },
4185 { "(bad)", { XX } },
4186 { "(bad)", { XX } },
dc99065b
FB
4187 },
4188 /* de */
4189 {
88103cfe
BS
4190 { "faddp", { STi, ST } },
4191 { "fmulp", { STi, ST } },
4192 { "(bad)", { XX } },
dc99065b 4193 { FGRPde_3 },
88103cfe
BS
4194#if SYSV386_COMPAT
4195 { "fsubp", { STi, ST } },
4196 { "fsubrp", { STi, ST } },
4197 { "fdivp", { STi, ST } },
4198 { "fdivrp", { STi, ST } },
bc51c5c9 4199#else
88103cfe
BS
4200 { "fsubrp", { STi, ST } },
4201 { "fsubp", { STi, ST } },
4202 { "fdivrp", { STi, ST } },
4203 { "fdivp", { STi, ST } },
bc51c5c9 4204#endif
dc99065b
FB
4205 },
4206 /* df */
4207 {
88103cfe
BS
4208 { "ffreep", { STi } },
4209 { "(bad)", { XX } },
4210 { "(bad)", { XX } },
4211 { "(bad)", { XX } },
dc99065b 4212 { FGRPdf_4 },
88103cfe
BS
4213 { "fucomip", { ST, STi } },
4214 { "fcomip", { ST, STi } },
4215 { "(bad)", { XX } },
dc99065b
FB
4216 },
4217};
4218
4c7d9dc7 4219static const char *fgrps[][8] = {
dc99065b
FB
4220 /* d9_2 0 */
4221 {
4222 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4223 },
4224
4225 /* d9_4 1 */
4226 {
4227 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4228 },
4229
4230 /* d9_5 2 */
4231 {
4232 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4233 },
4234
4235 /* d9_6 3 */
4236 {
4237 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4238 },
4239
4240 /* d9_7 4 */
4241 {
4242 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4243 },
4244
4245 /* da_5 5 */
4246 {
4247 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4248 },
4249
4250 /* db_4 6 */
4251 {
4252 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4253 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4254 },
4255
4256 /* de_3 7 */
4257 {
4258 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4259 },
4260
4261 /* df_4 8 */
4262 {
4263 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4264 },
4265};
4266
4267static void
c2c73b42 4268dofloat (int sizeflag)
dc99065b 4269{
bc51c5c9 4270 const struct dis386 *dp;
dc99065b 4271 unsigned char floatop;
bc51c5c9 4272
dc99065b 4273 floatop = codep[-1];
bc51c5c9 4274
88103cfe 4275 if (modrm.mod != 3)
dc99065b 4276 {
88103cfe 4277 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
c2c73b42
BS
4278
4279 putop (float_mem[fp_indx], sizeflag);
88103cfe 4280 obufp = op_out[0];
c2c73b42
BS
4281 op_ad = 2;
4282 OP_E (float_mem_mode[fp_indx], sizeflag);
dc99065b
FB
4283 return;
4284 }
bc51c5c9
FB
4285 /* Skip mod/rm byte. */
4286 MODRM_CHECK;
dc99065b 4287 codep++;
bc51c5c9 4288
88103cfe 4289 dp = &float_reg[floatop - 0xd8][modrm.reg];
dc99065b
FB
4290 if (dp->name == NULL)
4291 {
88103cfe 4292 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
bc51c5c9
FB
4293
4294 /* Instruction fnstsw is only one with strange arg. */
4295 if (floatop == 0xdf && codep[-1] == 0xe0)
88103cfe 4296 pstrcpy (op_out[0], sizeof(op_out[0]), names16[0]);
dc99065b
FB
4297 }
4298 else
4299 {
bc51c5c9
FB
4300 putop (dp->name, sizeflag);
4301
88103cfe 4302 obufp = op_out[0];
c2c73b42 4303 op_ad = 2;
88103cfe
BS
4304 if (dp->op[0].rtn)
4305 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
c2c73b42 4306
88103cfe 4307 obufp = op_out[1];
c2c73b42 4308 op_ad = 1;
88103cfe
BS
4309 if (dp->op[1].rtn)
4310 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
dc99065b
FB
4311 }
4312}
4313
bc51c5c9 4314static void
c2c73b42 4315OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 4316{
c2c73b42 4317 oappend ("%st" + intel_syntax);
dc99065b
FB
4318}
4319
bc51c5c9 4320static void
c2c73b42 4321OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 4322{
88103cfe 4323 snprintf (scratchbuf, sizeof(scratchbuf), "%%st(%d)", modrm.rm);
bc51c5c9 4324 oappend (scratchbuf + intel_syntax);
dc99065b
FB
4325}
4326
bc51c5c9
FB
4327/* Capital letters in template are macros. */
4328static int
c2c73b42 4329putop (const char *template, int sizeflag)
dc99065b 4330{
bc51c5c9 4331 const char *p;
c2c73b42 4332 int alt = 0;
bc51c5c9 4333
dc99065b
FB
4334 for (p = template; *p; p++)
4335 {
4336 switch (*p)
4337 {
4338 default:
4339 *obufp++ = *p;
4340 break;
bc51c5c9
FB
4341 case '{':
4342 alt = 0;
4343 if (intel_syntax)
4344 alt += 1;
c2c73b42 4345 if (address_mode == mode_64bit)
bc51c5c9
FB
4346 alt += 2;
4347 while (alt != 0)
4348 {
4349 while (*++p != '|')
4350 {
4351 if (*p == '}')
4352 {
4353 /* Alternative not valid. */
363a37d5 4354 pstrcpy (obuf, sizeof(obuf), "(bad)");
bc51c5c9
FB
4355 obufp = obuf + 5;
4356 return 1;
4357 }
4358 else if (*p == '\0')
4359 abort ();
4360 }
4361 alt--;
4362 }
c2c73b42
BS
4363 /* Fall through. */
4364 case 'I':
4365 alt = 1;
4366 continue;
bc51c5c9
FB
4367 case '|':
4368 while (*++p != '}')
4369 {
4370 if (*p == '\0')
4371 abort ();
4372 }
4373 break;
4374 case '}':
4375 break;
4376 case 'A':
c2c73b42
BS
4377 if (intel_syntax)
4378 break;
88103cfe 4379 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
bc51c5c9
FB
4380 *obufp++ = 'b';
4381 break;
4382 case 'B':
c2c73b42
BS
4383 if (intel_syntax)
4384 break;
bc51c5c9
FB
4385 if (sizeflag & SUFFIX_ALWAYS)
4386 *obufp++ = 'b';
4387 break;
c2c73b42
BS
4388 case 'C':
4389 if (intel_syntax && !alt)
4390 break;
4391 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4392 {
4393 if (sizeflag & DFLAG)
4394 *obufp++ = intel_syntax ? 'd' : 'l';
4395 else
4396 *obufp++ = intel_syntax ? 'w' : 's';
4397 used_prefixes |= (prefixes & PREFIX_DATA);
4398 }
4399 break;
88103cfe
BS
4400 case 'D':
4401 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4402 break;
4403 USED_REX (REX_W);
4404 if (modrm.mod == 3)
4405 {
4406 if (rex & REX_W)
4407 *obufp++ = 'q';
4408 else if (sizeflag & DFLAG)
4409 *obufp++ = intel_syntax ? 'd' : 'l';
4410 else
4411 *obufp++ = 'w';
4412 used_prefixes |= (prefixes & PREFIX_DATA);
4413 }
4414 else
4415 *obufp++ = 'w';
4416 break;
bc51c5c9 4417 case 'E': /* For jcxz/jecxz */
c2c73b42 4418 if (address_mode == mode_64bit)
bc51c5c9
FB
4419 {
4420 if (sizeflag & AFLAG)
4421 *obufp++ = 'r';
4422 else
4423 *obufp++ = 'e';
4424 }
4425 else
4426 if (sizeflag & AFLAG)
4427 *obufp++ = 'e';
4428 used_prefixes |= (prefixes & PREFIX_ADDR);
4429 break;
4430 case 'F':
c2c73b42
BS
4431 if (intel_syntax)
4432 break;
bc51c5c9
FB
4433 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
4434 {
4435 if (sizeflag & AFLAG)
c2c73b42 4436 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
bc51c5c9 4437 else
c2c73b42 4438 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
bc51c5c9
FB
4439 used_prefixes |= (prefixes & PREFIX_ADDR);
4440 }
4441 break;
88103cfe
BS
4442 case 'G':
4443 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4444 break;
4445 if ((rex & REX_W) || (sizeflag & DFLAG))
4446 *obufp++ = 'l';
4447 else
4448 *obufp++ = 'w';
4449 if (!(rex & REX_W))
4450 used_prefixes |= (prefixes & PREFIX_DATA);
4451 break;
bc51c5c9 4452 case 'H':
c2c73b42
BS
4453 if (intel_syntax)
4454 break;
bc51c5c9
FB
4455 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
4456 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
4457 {
4458 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
4459 *obufp++ = ',';
4460 *obufp++ = 'p';
4461 if (prefixes & PREFIX_DS)
4462 *obufp++ = 't';
4463 else
4464 *obufp++ = 'n';
4465 }
4466 break;
c2c73b42
BS
4467 case 'J':
4468 if (intel_syntax)
4469 break;
4470 *obufp++ = 'l';
4471 break;
88103cfe
BS
4472 case 'K':
4473 USED_REX (REX_W);
4474 if (rex & REX_W)
4475 *obufp++ = 'q';
4476 else
4477 *obufp++ = 'd';
4478 break;
c2c73b42
BS
4479 case 'Z':
4480 if (intel_syntax)
4481 break;
4482 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4483 {
4484 *obufp++ = 'q';
4485 break;
4486 }
4487 /* Fall through. */
bc51c5c9 4488 case 'L':
c2c73b42
BS
4489 if (intel_syntax)
4490 break;
bc51c5c9
FB
4491 if (sizeflag & SUFFIX_ALWAYS)
4492 *obufp++ = 'l';
dc99065b
FB
4493 break;
4494 case 'N':
4495 if ((prefixes & PREFIX_FWAIT) == 0)
4496 *obufp++ = 'n';
bc51c5c9
FB
4497 else
4498 used_prefixes |= PREFIX_FWAIT;
4499 break;
4500 case 'O':
88103cfe
BS
4501 USED_REX (REX_W);
4502 if (rex & REX_W)
bc51c5c9 4503 *obufp++ = 'o';
88103cfe
BS
4504 else if (intel_syntax && (sizeflag & DFLAG))
4505 *obufp++ = 'q';
bc51c5c9
FB
4506 else
4507 *obufp++ = 'd';
88103cfe
BS
4508 if (!(rex & REX_W))
4509 used_prefixes |= (prefixes & PREFIX_DATA);
bc51c5c9
FB
4510 break;
4511 case 'T':
c2c73b42
BS
4512 if (intel_syntax)
4513 break;
4514 if (address_mode == mode_64bit && (sizeflag & DFLAG))
bc51c5c9
FB
4515 {
4516 *obufp++ = 'q';
4517 break;
4518 }
4519 /* Fall through. */
4520 case 'P':
c2c73b42
BS
4521 if (intel_syntax)
4522 break;
bc51c5c9 4523 if ((prefixes & PREFIX_DATA)
88103cfe 4524 || (rex & REX_W)
bc51c5c9
FB
4525 || (sizeflag & SUFFIX_ALWAYS))
4526 {
88103cfe
BS
4527 USED_REX (REX_W);
4528 if (rex & REX_W)
bc51c5c9
FB
4529 *obufp++ = 'q';
4530 else
4531 {
4532 if (sizeflag & DFLAG)
4533 *obufp++ = 'l';
4534 else
4535 *obufp++ = 'w';
bc51c5c9 4536 }
c2c73b42 4537 used_prefixes |= (prefixes & PREFIX_DATA);
bc51c5c9
FB
4538 }
4539 break;
4540 case 'U':
c2c73b42
BS
4541 if (intel_syntax)
4542 break;
4543 if (address_mode == mode_64bit && (sizeflag & DFLAG))
bc51c5c9 4544 {
88103cfe 4545 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
c2c73b42 4546 *obufp++ = 'q';
bc51c5c9
FB
4547 break;
4548 }
4549 /* Fall through. */
4550 case 'Q':
c2c73b42
BS
4551 if (intel_syntax && !alt)
4552 break;
88103cfe
BS
4553 USED_REX (REX_W);
4554 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
bc51c5c9 4555 {
88103cfe 4556 if (rex & REX_W)
bc51c5c9
FB
4557 *obufp++ = 'q';
4558 else
4559 {
4560 if (sizeflag & DFLAG)
c2c73b42 4561 *obufp++ = intel_syntax ? 'd' : 'l';
bc51c5c9
FB
4562 else
4563 *obufp++ = 'w';
bc51c5c9 4564 }
c2c73b42 4565 used_prefixes |= (prefixes & PREFIX_DATA);
bc51c5c9
FB
4566 }
4567 break;
4568 case 'R':
88103cfe
BS
4569 USED_REX (REX_W);
4570 if (rex & REX_W)
4571 *obufp++ = 'q';
4572 else if (sizeflag & DFLAG)
bc51c5c9 4573 {
88103cfe 4574 if (intel_syntax)
bc51c5c9 4575 *obufp++ = 'd';
bc51c5c9 4576 else
88103cfe 4577 *obufp++ = 'l';
bc51c5c9
FB
4578 }
4579 else
88103cfe
BS
4580 *obufp++ = 'w';
4581 if (intel_syntax && !p[1]
4582 && ((rex & REX_W) || (sizeflag & DFLAG)))
4583 *obufp++ = 'e';
4584 if (!(rex & REX_W))
bc51c5c9 4585 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b 4586 break;
c2c73b42
BS
4587 case 'V':
4588 if (intel_syntax)
4589 break;
4590 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4591 {
4592 if (sizeflag & SUFFIX_ALWAYS)
4593 *obufp++ = 'q';
4594 break;
4595 }
4596 /* Fall through. */
dc99065b 4597 case 'S':
c2c73b42
BS
4598 if (intel_syntax)
4599 break;
bc51c5c9
FB
4600 if (sizeflag & SUFFIX_ALWAYS)
4601 {
88103cfe 4602 if (rex & REX_W)
bc51c5c9
FB
4603 *obufp++ = 'q';
4604 else
4605 {
4606 if (sizeflag & DFLAG)
4607 *obufp++ = 'l';
4608 else
4609 *obufp++ = 'w';
4610 used_prefixes |= (prefixes & PREFIX_DATA);
4611 }
4612 }
4613 break;
4614 case 'X':
4615 if (prefixes & PREFIX_DATA)
4616 *obufp++ = 'd';
dc99065b 4617 else
bc51c5c9 4618 *obufp++ = 's';
c2c73b42 4619 used_prefixes |= (prefixes & PREFIX_DATA);
bc51c5c9
FB
4620 break;
4621 case 'Y':
c2c73b42
BS
4622 if (intel_syntax)
4623 break;
88103cfe 4624 if (rex & REX_W)
bc51c5c9 4625 {
88103cfe 4626 USED_REX (REX_W);
bc51c5c9
FB
4627 *obufp++ = 'q';
4628 }
dc99065b 4629 break;
bc51c5c9 4630 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
dc99065b
FB
4631 case 'W':
4632 /* operand size flag for cwtl, cbtw */
88103cfe
BS
4633 USED_REX (REX_W);
4634 if (rex & REX_W)
4635 {
4636 if (intel_syntax)
4637 *obufp++ = 'd';
4638 else
4639 *obufp++ = 'l';
4640 }
bc51c5c9 4641 else if (sizeflag & DFLAG)
dc99065b
FB
4642 *obufp++ = 'w';
4643 else
4644 *obufp++ = 'b';
88103cfe 4645 if (!(rex & REX_W))
bc51c5c9 4646 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b
FB
4647 break;
4648 }
c2c73b42 4649 alt = 0;
dc99065b
FB
4650 }
4651 *obufp = 0;
bc51c5c9 4652 return 0;
dc99065b
FB
4653}
4654
4655static void
c2c73b42 4656oappend (const char *s)
dc99065b 4657{
4d5e2b3c 4658 strcpy (obufp, s);
dc99065b 4659 obufp += strlen (s);
dc99065b
FB
4660}
4661
4662static void
c2c73b42 4663append_seg (void)
dc99065b
FB
4664{
4665 if (prefixes & PREFIX_CS)
bc51c5c9
FB
4666 {
4667 used_prefixes |= PREFIX_CS;
4668 oappend ("%cs:" + intel_syntax);
4669 }
dc99065b 4670 if (prefixes & PREFIX_DS)
bc51c5c9
FB
4671 {
4672 used_prefixes |= PREFIX_DS;
4673 oappend ("%ds:" + intel_syntax);
4674 }
dc99065b 4675 if (prefixes & PREFIX_SS)
bc51c5c9
FB
4676 {
4677 used_prefixes |= PREFIX_SS;
4678 oappend ("%ss:" + intel_syntax);
4679 }
dc99065b 4680 if (prefixes & PREFIX_ES)
bc51c5c9
FB
4681 {
4682 used_prefixes |= PREFIX_ES;
4683 oappend ("%es:" + intel_syntax);
4684 }
dc99065b 4685 if (prefixes & PREFIX_FS)
bc51c5c9
FB
4686 {
4687 used_prefixes |= PREFIX_FS;
4688 oappend ("%fs:" + intel_syntax);
4689 }
dc99065b 4690 if (prefixes & PREFIX_GS)
bc51c5c9
FB
4691 {
4692 used_prefixes |= PREFIX_GS;
4693 oappend ("%gs:" + intel_syntax);
4694 }
dc99065b
FB
4695}
4696
bc51c5c9 4697static void
c2c73b42 4698OP_indirE (int bytemode, int sizeflag)
dc99065b 4699{
bc51c5c9
FB
4700 if (!intel_syntax)
4701 oappend ("*");
4702 OP_E (bytemode, sizeflag);
dc99065b
FB
4703}
4704
bc51c5c9 4705static void
363a37d5 4706print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp)
bc51c5c9 4707{
c2c73b42 4708 if (address_mode == mode_64bit)
bc51c5c9
FB
4709 {
4710 if (hex)
4711 {
4712 char tmp[30];
4713 int i;
4714 buf[0] = '0';
4715 buf[1] = 'x';
363a37d5 4716 snprintf_vma (tmp, sizeof(tmp), disp);
bc51c5c9 4717 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
363a37d5 4718 pstrcpy (buf + 2, bufsize - 2, tmp + i);
bc51c5c9
FB
4719 }
4720 else
4721 {
4722 bfd_signed_vma v = disp;
4723 char tmp[30];
4724 int i;
4725 if (v < 0)
4726 {
4727 *(buf++) = '-';
4728 v = -disp;
4729 /* Check for possible overflow on 0x8000000000000000. */
4730 if (v < 0)
4731 {
363a37d5 4732 pstrcpy (buf, bufsize, "9223372036854775808");
bc51c5c9
FB
4733 return;
4734 }
4735 }
4736 if (!v)
4737 {
363a37d5 4738 pstrcpy (buf, bufsize, "0");
bc51c5c9
FB
4739 return;
4740 }
4741
4742 i = 0;
4743 tmp[29] = 0;
4744 while (v)
4745 {
4746 tmp[28 - i] = (v % 10) + '0';
4747 v /= 10;
4748 i++;
4749 }
363a37d5 4750 pstrcpy (buf, bufsize, tmp + 29 - i);
bc51c5c9
FB
4751 }
4752 }
4753 else
4754 {
4755 if (hex)
363a37d5 4756 snprintf (buf, bufsize, "0x%x", (unsigned int) disp);
bc51c5c9 4757 else
363a37d5 4758 snprintf (buf, bufsize, "%d", (int) disp);
bc51c5c9
FB
4759 }
4760}
4761
88103cfe
BS
4762/* Put DISP in BUF as signed hex number. */
4763
4764static void
4765print_displacement (char *buf, bfd_vma disp)
4766{
4767 bfd_signed_vma val = disp;
4768 char tmp[30];
4769 int i, j = 0;
4770
4771 if (val < 0)
4772 {
4773 buf[j++] = '-';
4774 val = -disp;
4775
4776 /* Check for possible overflow. */
4777 if (val < 0)
4778 {
4779 switch (address_mode)
4780 {
4781 case mode_64bit:
4782 strcpy (buf + j, "0x8000000000000000");
4783 break;
4784 case mode_32bit:
4785 strcpy (buf + j, "0x80000000");
4786 break;
4787 case mode_16bit:
4788 strcpy (buf + j, "0x8000");
4789 break;
4790 }
4791 return;
4792 }
4793 }
4794
4795 buf[j++] = '0';
4796 buf[j++] = 'x';
4797
4798 snprintf_vma (tmp, sizeof(tmp), val);
4799 for (i = 0; tmp[i] == '0'; i++)
4800 continue;
4801 if (tmp[i] == '\0')
4802 i--;
4803 strcpy (buf + j, tmp + i);
4804}
4805
bc51c5c9 4806static void
c2c73b42
BS
4807intel_operand_size (int bytemode, int sizeflag)
4808{
4809 switch (bytemode)
4810 {
4811 case b_mode:
88103cfe 4812 case dqb_mode:
c2c73b42
BS
4813 oappend ("BYTE PTR ");
4814 break;
4815 case w_mode:
4816 case dqw_mode:
4817 oappend ("WORD PTR ");
4818 break;
4819 case stack_v_mode:
4820 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4821 {
4822 oappend ("QWORD PTR ");
4823 used_prefixes |= (prefixes & PREFIX_DATA);
4824 break;
4825 }
4826 /* FALLTHRU */
4827 case v_mode:
4828 case dq_mode:
88103cfe
BS
4829 USED_REX (REX_W);
4830 if (rex & REX_W)
c2c73b42
BS
4831 oappend ("QWORD PTR ");
4832 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4833 oappend ("DWORD PTR ");
4834 else
4835 oappend ("WORD PTR ");
4836 used_prefixes |= (prefixes & PREFIX_DATA);
4837 break;
88103cfe
BS
4838 case z_mode:
4839 if ((rex & REX_W) || (sizeflag & DFLAG))
4840 *obufp++ = 'D';
4841 oappend ("WORD PTR ");
4842 if (!(rex & REX_W))
4843 used_prefixes |= (prefixes & PREFIX_DATA);
4844 break;
c2c73b42 4845 case d_mode:
88103cfe 4846 case dqd_mode:
c2c73b42
BS
4847 oappend ("DWORD PTR ");
4848 break;
4849 case q_mode:
4850 oappend ("QWORD PTR ");
4851 break;
4852 case m_mode:
4853 if (address_mode == mode_64bit)
4854 oappend ("QWORD PTR ");
4855 else
4856 oappend ("DWORD PTR ");
4857 break;
4858 case f_mode:
4859 if (sizeflag & DFLAG)
4860 oappend ("FWORD PTR ");
4861 else
4862 oappend ("DWORD PTR ");
4863 used_prefixes |= (prefixes & PREFIX_DATA);
4864 break;
4865 case t_mode:
4866 oappend ("TBYTE PTR ");
4867 break;
4868 case x_mode:
4869 oappend ("XMMWORD PTR ");
4870 break;
88103cfe
BS
4871 case o_mode:
4872 oappend ("OWORD PTR ");
4873 break;
c2c73b42
BS
4874 default:
4875 break;
4876 }
4877}
4878
4879static void
4880OP_E (int bytemode, int sizeflag)
dc99065b 4881{
bc51c5c9
FB
4882 bfd_vma disp;
4883 int add = 0;
4884 int riprel = 0;
88103cfe
BS
4885 USED_REX (REX_B);
4886 if (rex & REX_B)
bc51c5c9 4887 add += 8;
dc99065b 4888
bc51c5c9
FB
4889 /* Skip mod/rm byte. */
4890 MODRM_CHECK;
dc99065b
FB
4891 codep++;
4892
88103cfe 4893 if (modrm.mod == 3)
dc99065b
FB
4894 {
4895 switch (bytemode)
4896 {
4897 case b_mode:
bc51c5c9
FB
4898 USED_REX (0);
4899 if (rex)
88103cfe 4900 oappend (names8rex[modrm.rm + add]);
bc51c5c9 4901 else
88103cfe 4902 oappend (names8[modrm.rm + add]);
dc99065b
FB
4903 break;
4904 case w_mode:
88103cfe 4905 oappend (names16[modrm.rm + add]);
bc51c5c9
FB
4906 break;
4907 case d_mode:
88103cfe 4908 oappend (names32[modrm.rm + add]);
bc51c5c9
FB
4909 break;
4910 case q_mode:
88103cfe 4911 oappend (names64[modrm.rm + add]);
bc51c5c9
FB
4912 break;
4913 case m_mode:
c2c73b42 4914 if (address_mode == mode_64bit)
88103cfe 4915 oappend (names64[modrm.rm + add]);
bc51c5c9 4916 else
88103cfe 4917 oappend (names32[modrm.rm + add]);
dc99065b 4918 break;
c2c73b42
BS
4919 case stack_v_mode:
4920 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4921 {
88103cfe 4922 oappend (names64[modrm.rm + add]);
c2c73b42
BS
4923 used_prefixes |= (prefixes & PREFIX_DATA);
4924 break;
4925 }
4926 bytemode = v_mode;
4927 /* FALLTHRU */
dc99065b 4928 case v_mode:
c2c73b42 4929 case dq_mode:
88103cfe
BS
4930 case dqb_mode:
4931 case dqd_mode:
c2c73b42 4932 case dqw_mode:
88103cfe
BS
4933 USED_REX (REX_W);
4934 if (rex & REX_W)
4935 oappend (names64[modrm.rm + add]);
c2c73b42 4936 else if ((sizeflag & DFLAG) || bytemode != v_mode)
88103cfe 4937 oappend (names32[modrm.rm + add]);
dc99065b 4938 else
88103cfe 4939 oappend (names16[modrm.rm + add]);
bc51c5c9
FB
4940 used_prefixes |= (prefixes & PREFIX_DATA);
4941 break;
4942 case 0:
dc99065b
FB
4943 break;
4944 default:
bc51c5c9 4945 oappend (INTERNAL_DISASSEMBLER_ERROR);
dc99065b
FB
4946 break;
4947 }
bc51c5c9 4948 return;
dc99065b
FB
4949 }
4950
4951 disp = 0;
c2c73b42
BS
4952 if (intel_syntax)
4953 intel_operand_size (bytemode, sizeflag);
bc51c5c9 4954 append_seg ();
dc99065b 4955
88103cfe 4956 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
dc99065b 4957 {
88103cfe
BS
4958 /* 32/64 bit address mode */
4959 int havedisp;
dc99065b
FB
4960 int havesib;
4961 int havebase;
4962 int base;
4963 int index = 0;
4964 int scale = 0;
4965
4966 havesib = 0;
4967 havebase = 1;
88103cfe 4968 base = modrm.rm;
dc99065b
FB
4969
4970 if (base == 4)
4971 {
4972 havesib = 1;
4973 FETCH_DATA (the_info, codep + 1);
dc99065b 4974 index = (*codep >> 3) & 7;
c2c73b42
BS
4975 if (address_mode == mode_64bit || index != 0x4)
4976 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4977 scale = (*codep >> 6) & 3;
dc99065b 4978 base = *codep & 7;
88103cfe
BS
4979 USED_REX (REX_X);
4980 if (rex & REX_X)
bc51c5c9 4981 index += 8;
dc99065b
FB
4982 codep++;
4983 }
c2c73b42 4984 base += add;
dc99065b 4985
88103cfe 4986 switch (modrm.mod)
dc99065b
FB
4987 {
4988 case 0:
bc51c5c9 4989 if ((base & 7) == 5)
dc99065b
FB
4990 {
4991 havebase = 0;
c2c73b42 4992 if (address_mode == mode_64bit && !havesib)
bc51c5c9
FB
4993 riprel = 1;
4994 disp = get32s ();
dc99065b
FB
4995 }
4996 break;
4997 case 1:
4998 FETCH_DATA (the_info, codep + 1);
4999 disp = *codep++;
5000 if ((disp & 0x80) != 0)
5001 disp -= 0x100;
5002 break;
5003 case 2:
bc51c5c9 5004 disp = get32s ();
dc99065b
FB
5005 break;
5006 }
5007
88103cfe
BS
5008 havedisp = havebase || (havesib && (index != 4 || scale != 0));
5009
bc51c5c9 5010 if (!intel_syntax)
88103cfe 5011 if (modrm.mod != 0 || (base & 7) == 5)
c2c73b42 5012 {
88103cfe
BS
5013 if (havedisp || riprel)
5014 print_displacement (scratchbuf, disp);
5015 else
5016 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
c2c73b42 5017 oappend (scratchbuf);
bc51c5c9
FB
5018 if (riprel)
5019 {
5020 set_op (disp, 1);
5021 oappend ("(%rip)");
5022 }
c2c73b42 5023 }
dc99065b 5024
88103cfe 5025 if (havedisp || (intel_syntax && riprel))
dc99065b 5026 {
bc51c5c9
FB
5027 *obufp++ = open_char;
5028 if (intel_syntax && riprel)
88103cfe
BS
5029 {
5030 set_op (disp, 1);
5031 oappend ("rip");
5032 }
c2c73b42 5033 *obufp = '\0';
dc99065b 5034 if (havebase)
c2c73b42 5035 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
bc51c5c9 5036 ? names64[base] : names32[base]);
dc99065b
FB
5037 if (havesib)
5038 {
5039 if (index != 4)
5040 {
c2c73b42
BS
5041 if (!intel_syntax || havebase)
5042 {
5043 *obufp++ = separator_char;
5044 *obufp = '\0';
5045 }
5046 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5047 ? names64[index] : names32[index]);
5048 }
5049 if (scale != 0 || (!intel_syntax && index != 4))
5050 {
5051 *obufp++ = scale_char;
5052 *obufp = '\0';
5053 snprintf (scratchbuf, sizeof(scratchbuf), "%d", 1 << scale);
dc99065b
FB
5054 oappend (scratchbuf);
5055 }
dc99065b 5056 }
88103cfe
BS
5057 if (intel_syntax
5058 && (disp || modrm.mod != 0 || (base & 7) == 5))
c2c73b42 5059 {
88103cfe 5060 if ((bfd_signed_vma) disp >= 0)
c2c73b42
BS
5061 {
5062 *obufp++ = '+';
5063 *obufp = '\0';
5064 }
88103cfe 5065 else if (modrm.mod != 1)
c2c73b42
BS
5066 {
5067 *obufp++ = '-';
5068 *obufp = '\0';
5069 disp = - (bfd_signed_vma) disp;
5070 }
5071
88103cfe 5072 print_displacement (scratchbuf, disp);
c2c73b42
BS
5073 oappend (scratchbuf);
5074 }
bc51c5c9
FB
5075
5076 *obufp++ = close_char;
c2c73b42 5077 *obufp = '\0';
dc99065b 5078 }
bc51c5c9 5079 else if (intel_syntax)
c2c73b42 5080 {
88103cfe 5081 if (modrm.mod != 0 || (base & 7) == 5)
c2c73b42 5082 {
bc51c5c9
FB
5083 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5084 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5085 ;
5086 else
5087 {
5088 oappend (names_seg[ds_reg - es_reg]);
5089 oappend (":");
5090 }
c2c73b42
BS
5091 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5092 oappend (scratchbuf);
5093 }
5094 }
dc99065b
FB
5095 }
5096 else
5097 { /* 16 bit address mode */
88103cfe 5098 switch (modrm.mod)
dc99065b
FB
5099 {
5100 case 0:
88103cfe 5101 if (modrm.rm == 6)
dc99065b
FB
5102 {
5103 disp = get16 ();
5104 if ((disp & 0x8000) != 0)
5105 disp -= 0x10000;
5106 }
5107 break;
5108 case 1:
5109 FETCH_DATA (the_info, codep + 1);
5110 disp = *codep++;
5111 if ((disp & 0x80) != 0)
5112 disp -= 0x100;
5113 break;
5114 case 2:
5115 disp = get16 ();
5116 if ((disp & 0x8000) != 0)
5117 disp -= 0x10000;
5118 break;
5119 }
5120
bc51c5c9 5121 if (!intel_syntax)
88103cfe 5122 if (modrm.mod != 0 || modrm.rm == 6)
c2c73b42 5123 {
88103cfe 5124 print_displacement (scratchbuf, disp);
c2c73b42
BS
5125 oappend (scratchbuf);
5126 }
dc99065b 5127
88103cfe 5128 if (modrm.mod != 0 || modrm.rm != 6)
dc99065b 5129 {
bc51c5c9 5130 *obufp++ = open_char;
c2c73b42 5131 *obufp = '\0';
88103cfe
BS
5132 oappend (index16[modrm.rm]);
5133 if (intel_syntax
5134 && (disp || modrm.mod != 0 || modrm.rm == 6))
c2c73b42 5135 {
88103cfe 5136 if ((bfd_signed_vma) disp >= 0)
c2c73b42
BS
5137 {
5138 *obufp++ = '+';
5139 *obufp = '\0';
5140 }
88103cfe 5141 else if (modrm.mod != 1)
c2c73b42
BS
5142 {
5143 *obufp++ = '-';
5144 *obufp = '\0';
5145 disp = - (bfd_signed_vma) disp;
5146 }
5147
88103cfe 5148 print_displacement (scratchbuf, disp);
c2c73b42
BS
5149 oappend (scratchbuf);
5150 }
5151
5152 *obufp++ = close_char;
5153 *obufp = '\0';
5154 }
5155 else if (intel_syntax)
5156 {
5157 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5158 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5159 ;
5160 else
5161 {
5162 oappend (names_seg[ds_reg - es_reg]);
5163 oappend (":");
5164 }
5165 print_operand_value (scratchbuf, sizeof(scratchbuf), 1,
5166 disp & 0xffff);
5167 oappend (scratchbuf);
dc99065b
FB
5168 }
5169 }
dc99065b
FB
5170}
5171
bc51c5c9 5172static void
c2c73b42 5173OP_G (int bytemode, int sizeflag)
dc99065b 5174{
bc51c5c9 5175 int add = 0;
88103cfe
BS
5176 USED_REX (REX_R);
5177 if (rex & REX_R)
bc51c5c9
FB
5178 add += 8;
5179 switch (bytemode)
dc99065b
FB
5180 {
5181 case b_mode:
bc51c5c9
FB
5182 USED_REX (0);
5183 if (rex)
88103cfe 5184 oappend (names8rex[modrm.reg + add]);
bc51c5c9 5185 else
88103cfe 5186 oappend (names8[modrm.reg + add]);
dc99065b
FB
5187 break;
5188 case w_mode:
88103cfe 5189 oappend (names16[modrm.reg + add]);
dc99065b
FB
5190 break;
5191 case d_mode:
88103cfe 5192 oappend (names32[modrm.reg + add]);
bc51c5c9
FB
5193 break;
5194 case q_mode:
88103cfe 5195 oappend (names64[modrm.reg + add]);
dc99065b
FB
5196 break;
5197 case v_mode:
c2c73b42 5198 case dq_mode:
88103cfe
BS
5199 case dqb_mode:
5200 case dqd_mode:
c2c73b42 5201 case dqw_mode:
88103cfe
BS
5202 USED_REX (REX_W);
5203 if (rex & REX_W)
5204 oappend (names64[modrm.reg + add]);
c2c73b42 5205 else if ((sizeflag & DFLAG) || bytemode != v_mode)
88103cfe 5206 oappend (names32[modrm.reg + add]);
dc99065b 5207 else
88103cfe 5208 oappend (names16[modrm.reg + add]);
bc51c5c9 5209 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b 5210 break;
c2c73b42
BS
5211 case m_mode:
5212 if (address_mode == mode_64bit)
88103cfe 5213 oappend (names64[modrm.reg + add]);
c2c73b42 5214 else
88103cfe 5215 oappend (names32[modrm.reg + add]);
c2c73b42 5216 break;
dc99065b 5217 default:
bc51c5c9 5218 oappend (INTERNAL_DISASSEMBLER_ERROR);
dc99065b
FB
5219 break;
5220 }
dc99065b
FB
5221}
5222
bc51c5c9 5223static bfd_vma
c2c73b42 5224get64 (void)
bc51c5c9
FB
5225{
5226 bfd_vma x;
5227#ifdef BFD64
5228 unsigned int a;
5229 unsigned int b;
5230
5231 FETCH_DATA (the_info, codep + 8);
5232 a = *codep++ & 0xff;
5233 a |= (*codep++ & 0xff) << 8;
5234 a |= (*codep++ & 0xff) << 16;
5235 a |= (*codep++ & 0xff) << 24;
5236 b = *codep++ & 0xff;
5237 b |= (*codep++ & 0xff) << 8;
5238 b |= (*codep++ & 0xff) << 16;
5239 b |= (*codep++ & 0xff) << 24;
5240 x = a + ((bfd_vma) b << 32);
5241#else
5242 abort ();
5243 x = 0;
5244#endif
5245 return x;
5246}
5247
5248static bfd_signed_vma
c2c73b42 5249get32 (void)
dc99065b 5250{
bc51c5c9 5251 bfd_signed_vma x = 0;
dc99065b
FB
5252
5253 FETCH_DATA (the_info, codep + 4);
bc51c5c9
FB
5254 x = *codep++ & (bfd_signed_vma) 0xff;
5255 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5256 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5257 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5258 return x;
5259}
5260
5261static bfd_signed_vma
c2c73b42 5262get32s (void)
bc51c5c9
FB
5263{
5264 bfd_signed_vma x = 0;
5265
5266 FETCH_DATA (the_info, codep + 4);
5267 x = *codep++ & (bfd_signed_vma) 0xff;
5268 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5269 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5270 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5271
5272 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
5273
5274 return x;
dc99065b
FB
5275}
5276
5277static int
c2c73b42 5278get16 (void)
dc99065b
FB
5279{
5280 int x = 0;
5281
5282 FETCH_DATA (the_info, codep + 2);
5283 x = *codep++ & 0xff;
5284 x |= (*codep++ & 0xff) << 8;
bc51c5c9 5285 return x;
dc99065b
FB
5286}
5287
5288static void
c2c73b42 5289set_op (bfd_vma op, int riprel)
dc99065b
FB
5290{
5291 op_index[op_ad] = op_ad;
c2c73b42 5292 if (address_mode == mode_64bit)
bc51c5c9
FB
5293 {
5294 op_address[op_ad] = op;
5295 op_riprel[op_ad] = riprel;
5296 }
5297 else
5298 {
5299 /* Mask to get a 32-bit address. */
5300 op_address[op_ad] = op & 0xffffffff;
5301 op_riprel[op_ad] = riprel & 0xffffffff;
5302 }
dc99065b
FB
5303}
5304
bc51c5c9 5305static void
c2c73b42 5306OP_REG (int code, int sizeflag)
bc51c5c9
FB
5307{
5308 const char *s;
5309 int add = 0;
88103cfe
BS
5310 USED_REX (REX_B);
5311 if (rex & REX_B)
bc51c5c9
FB
5312 add = 8;
5313
5314 switch (code)
5315 {
bc51c5c9
FB
5316 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5317 case sp_reg: case bp_reg: case si_reg: case di_reg:
5318 s = names16[code - ax_reg + add];
5319 break;
5320 case es_reg: case ss_reg: case cs_reg:
5321 case ds_reg: case fs_reg: case gs_reg:
5322 s = names_seg[code - es_reg + add];
5323 break;
5324 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5325 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5326 USED_REX (0);
5327 if (rex)
5328 s = names8rex[code - al_reg + add];
5329 else
5330 s = names8[code - al_reg];
5331 break;
5332 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
5333 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
c2c73b42 5334 if (address_mode == mode_64bit && (sizeflag & DFLAG))
bc51c5c9
FB
5335 {
5336 s = names64[code - rAX_reg + add];
5337 break;
5338 }
5339 code += eAX_reg - rAX_reg;
5340 /* Fall through. */
5341 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5342 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
88103cfe
BS
5343 USED_REX (REX_W);
5344 if (rex & REX_W)
bc51c5c9
FB
5345 s = names64[code - eAX_reg + add];
5346 else if (sizeflag & DFLAG)
5347 s = names32[code - eAX_reg + add];
5348 else
5349 s = names16[code - eAX_reg + add];
5350 used_prefixes |= (prefixes & PREFIX_DATA);
5351 break;
5352 default:
5353 s = INTERNAL_DISASSEMBLER_ERROR;
5354 break;
5355 }
5356 oappend (s);
5357}
5358
5359static void
c2c73b42 5360OP_IMREG (int code, int sizeflag)
dc99065b 5361{
bc51c5c9
FB
5362 const char *s;
5363
5364 switch (code)
dc99065b 5365 {
bc51c5c9
FB
5366 case indir_dx_reg:
5367 if (intel_syntax)
88103cfe 5368 s = "dx";
bc51c5c9 5369 else
c2c73b42 5370 s = "(%dx)";
bc51c5c9
FB
5371 break;
5372 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5373 case sp_reg: case bp_reg: case si_reg: case di_reg:
5374 s = names16[code - ax_reg];
5375 break;
5376 case es_reg: case ss_reg: case cs_reg:
5377 case ds_reg: case fs_reg: case gs_reg:
5378 s = names_seg[code - es_reg];
5379 break;
5380 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5381 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5382 USED_REX (0);
5383 if (rex)
5384 s = names8rex[code - al_reg];
5385 else
5386 s = names8[code - al_reg];
5387 break;
5388 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5389 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
88103cfe
BS
5390 USED_REX (REX_W);
5391 if (rex & REX_W)
bc51c5c9
FB
5392 s = names64[code - eAX_reg];
5393 else if (sizeflag & DFLAG)
dc99065b
FB
5394 s = names32[code - eAX_reg];
5395 else
5396 s = names16[code - eAX_reg];
bc51c5c9 5397 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b 5398 break;
88103cfe
BS
5399 case z_mode_ax_reg:
5400 if ((rex & REX_W) || (sizeflag & DFLAG))
5401 s = *names32;
5402 else
5403 s = *names16;
5404 if (!(rex & REX_W))
5405 used_prefixes |= (prefixes & PREFIX_DATA);
5406 break;
dc99065b 5407 default:
bc51c5c9 5408 s = INTERNAL_DISASSEMBLER_ERROR;
dc99065b
FB
5409 break;
5410 }
5411 oappend (s);
dc99065b
FB
5412}
5413
bc51c5c9 5414static void
c2c73b42 5415OP_I (int bytemode, int sizeflag)
bc51c5c9
FB
5416{
5417 bfd_signed_vma op;
5418 bfd_signed_vma mask = -1;
5419
5420 switch (bytemode)
5421 {
5422 case b_mode:
5423 FETCH_DATA (the_info, codep + 1);
5424 op = *codep++;
5425 mask = 0xff;
5426 break;
5427 case q_mode:
c2c73b42 5428 if (address_mode == mode_64bit)
bc51c5c9
FB
5429 {
5430 op = get32s ();
5431 break;
5432 }
5433 /* Fall through. */
5434 case v_mode:
88103cfe
BS
5435 USED_REX (REX_W);
5436 if (rex & REX_W)
bc51c5c9
FB
5437 op = get32s ();
5438 else if (sizeflag & DFLAG)
5439 {
5440 op = get32 ();
5441 mask = 0xffffffff;
5442 }
5443 else
5444 {
5445 op = get16 ();
5446 mask = 0xfffff;
5447 }
5448 used_prefixes |= (prefixes & PREFIX_DATA);
5449 break;
5450 case w_mode:
5451 mask = 0xfffff;
5452 op = get16 ();
5453 break;
c2c73b42
BS
5454 case const_1_mode:
5455 if (intel_syntax)
5456 oappend ("1");
5457 return;
bc51c5c9
FB
5458 default:
5459 oappend (INTERNAL_DISASSEMBLER_ERROR);
5460 return;
5461 }
5462
5463 op &= mask;
5464 scratchbuf[0] = '$';
363a37d5 5465 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
bc51c5c9
FB
5466 oappend (scratchbuf + intel_syntax);
5467 scratchbuf[0] = '\0';
5468}
5469
5470static void
c2c73b42 5471OP_I64 (int bytemode, int sizeflag)
dc99065b 5472{
bc51c5c9
FB
5473 bfd_signed_vma op;
5474 bfd_signed_vma mask = -1;
5475
c2c73b42 5476 if (address_mode != mode_64bit)
bc51c5c9
FB
5477 {
5478 OP_I (bytemode, sizeflag);
5479 return;
5480 }
5481
5482 switch (bytemode)
dc99065b
FB
5483 {
5484 case b_mode:
5485 FETCH_DATA (the_info, codep + 1);
bc51c5c9
FB
5486 op = *codep++;
5487 mask = 0xff;
dc99065b
FB
5488 break;
5489 case v_mode:
88103cfe
BS
5490 USED_REX (REX_W);
5491 if (rex & REX_W)
bc51c5c9
FB
5492 op = get64 ();
5493 else if (sizeflag & DFLAG)
5494 {
5495 op = get32 ();
5496 mask = 0xffffffff;
5497 }
dc99065b 5498 else
bc51c5c9
FB
5499 {
5500 op = get16 ();
5501 mask = 0xfffff;
5502 }
5503 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b
FB
5504 break;
5505 case w_mode:
bc51c5c9 5506 mask = 0xfffff;
dc99065b
FB
5507 op = get16 ();
5508 break;
5509 default:
bc51c5c9
FB
5510 oappend (INTERNAL_DISASSEMBLER_ERROR);
5511 return;
dc99065b 5512 }
bc51c5c9
FB
5513
5514 op &= mask;
5515 scratchbuf[0] = '$';
363a37d5 5516 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
bc51c5c9
FB
5517 oappend (scratchbuf + intel_syntax);
5518 scratchbuf[0] = '\0';
dc99065b
FB
5519}
5520
bc51c5c9 5521static void
c2c73b42 5522OP_sI (int bytemode, int sizeflag)
dc99065b 5523{
bc51c5c9
FB
5524 bfd_signed_vma op;
5525 bfd_signed_vma mask = -1;
5526
5527 switch (bytemode)
dc99065b
FB
5528 {
5529 case b_mode:
5530 FETCH_DATA (the_info, codep + 1);
5531 op = *codep++;
5532 if ((op & 0x80) != 0)
5533 op -= 0x100;
bc51c5c9 5534 mask = 0xffffffff;
dc99065b
FB
5535 break;
5536 case v_mode:
88103cfe
BS
5537 USED_REX (REX_W);
5538 if (rex & REX_W)
bc51c5c9
FB
5539 op = get32s ();
5540 else if (sizeflag & DFLAG)
5541 {
5542 op = get32s ();
5543 mask = 0xffffffff;
5544 }
dc99065b
FB
5545 else
5546 {
bc51c5c9
FB
5547 mask = 0xffffffff;
5548 op = get16 ();
dc99065b
FB
5549 if ((op & 0x8000) != 0)
5550 op -= 0x10000;
5551 }
bc51c5c9 5552 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b
FB
5553 break;
5554 case w_mode:
5555 op = get16 ();
bc51c5c9 5556 mask = 0xffffffff;
dc99065b
FB
5557 if ((op & 0x8000) != 0)
5558 op -= 0x10000;
5559 break;
5560 default:
bc51c5c9
FB
5561 oappend (INTERNAL_DISASSEMBLER_ERROR);
5562 return;
dc99065b 5563 }
bc51c5c9
FB
5564
5565 scratchbuf[0] = '$';
363a37d5 5566 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
bc51c5c9 5567 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5568}
5569
bc51c5c9 5570static void
c2c73b42 5571OP_J (int bytemode, int sizeflag)
dc99065b 5572{
bc51c5c9
FB
5573 bfd_vma disp;
5574 bfd_vma mask = -1;
88103cfe 5575 bfd_vma segment = 0;
bc51c5c9
FB
5576
5577 switch (bytemode)
dc99065b
FB
5578 {
5579 case b_mode:
5580 FETCH_DATA (the_info, codep + 1);
5581 disp = *codep++;
5582 if ((disp & 0x80) != 0)
5583 disp -= 0x100;
5584 break;
5585 case v_mode:
88103cfe 5586 if ((sizeflag & DFLAG) || (rex & REX_W))
bc51c5c9 5587 disp = get32s ();
dc99065b
FB
5588 else
5589 {
5590 disp = get16 ();
88103cfe
BS
5591 if ((disp & 0x8000) != 0)
5592 disp -= 0x10000;
5593 /* In 16bit mode, address is wrapped around at 64k within
5594 the same segment. Otherwise, a data16 prefix on a jump
5595 instruction means that the pc is masked to 16 bits after
5596 the displacement is added! */
dc99065b 5597 mask = 0xffff;
88103cfe
BS
5598 if ((prefixes & PREFIX_DATA) == 0)
5599 segment = ((start_pc + codep - start_codep)
5600 & ~((bfd_vma) 0xffff));
dc99065b 5601 }
88103cfe 5602 used_prefixes |= (prefixes & PREFIX_DATA);
dc99065b
FB
5603 break;
5604 default:
bc51c5c9
FB
5605 oappend (INTERNAL_DISASSEMBLER_ERROR);
5606 return;
dc99065b 5607 }
88103cfe 5608 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
bc51c5c9 5609 set_op (disp, 0);
363a37d5 5610 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
dc99065b 5611 oappend (scratchbuf);
dc99065b
FB
5612}
5613
bc51c5c9 5614static void
88103cfe 5615OP_SEG (int bytemode, int sizeflag)
dc99065b 5616{
88103cfe
BS
5617 if (bytemode == w_mode)
5618 oappend (names_seg[modrm.reg]);
5619 else
5620 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
dc99065b
FB
5621}
5622
bc51c5c9 5623static void
c2c73b42 5624OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
dc99065b
FB
5625{
5626 int seg, offset;
bc51c5c9
FB
5627
5628 if (sizeflag & DFLAG)
dc99065b 5629 {
bc51c5c9
FB
5630 offset = get32 ();
5631 seg = get16 ();
dc99065b 5632 }
bc51c5c9
FB
5633 else
5634 {
5635 offset = get16 ();
5636 seg = get16 ();
5637 }
5638 used_prefixes |= (prefixes & PREFIX_DATA);
5639 if (intel_syntax)
c2c73b42 5640 snprintf (scratchbuf, sizeof(scratchbuf), "0x%x:0x%x", seg, offset);
bc51c5c9 5641 else
363a37d5 5642 snprintf (scratchbuf, sizeof(scratchbuf), "$0x%x,$0x%x", seg, offset);
bc51c5c9 5643 oappend (scratchbuf);
dc99065b
FB
5644}
5645
bc51c5c9 5646static void
c2c73b42 5647OP_OFF (int bytemode, int sizeflag)
dc99065b 5648{
bc51c5c9 5649 bfd_vma off;
dc99065b 5650
c2c73b42
BS
5651 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5652 intel_operand_size (bytemode, sizeflag);
bc51c5c9 5653 append_seg ();
dc99065b 5654
c2c73b42 5655 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
dc99065b
FB
5656 off = get32 ();
5657 else
5658 off = get16 ();
bc51c5c9
FB
5659
5660 if (intel_syntax)
5661 {
5662 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
c2c73b42 5663 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
bc51c5c9
FB
5664 {
5665 oappend (names_seg[ds_reg - es_reg]);
5666 oappend (":");
5667 }
5668 }
363a37d5 5669 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
dc99065b 5670 oappend (scratchbuf);
dc99065b
FB
5671}
5672
bc51c5c9 5673static void
c2c73b42 5674OP_OFF64 (int bytemode, int sizeflag)
dc99065b 5675{
bc51c5c9
FB
5676 bfd_vma off;
5677
88103cfe
BS
5678 if (address_mode != mode_64bit
5679 || (prefixes & PREFIX_ADDR))
bc51c5c9
FB
5680 {
5681 OP_OFF (bytemode, sizeflag);
5682 return;
5683 }
5684
c2c73b42
BS
5685 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5686 intel_operand_size (bytemode, sizeflag);
bc51c5c9
FB
5687 append_seg ();
5688
5689 off = get64 ();
5690
5691 if (intel_syntax)
5692 {
5693 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
c2c73b42 5694 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
bc51c5c9
FB
5695 {
5696 oappend (names_seg[ds_reg - es_reg]);
5697 oappend (":");
5698 }
5699 }
363a37d5 5700 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
bc51c5c9 5701 oappend (scratchbuf);
dc99065b
FB
5702}
5703
bc51c5c9 5704static void
c2c73b42 5705ptr_reg (int code, int sizeflag)
bc51c5c9
FB
5706{
5707 const char *s;
bc51c5c9 5708
c2c73b42
BS
5709 *obufp++ = open_char;
5710 used_prefixes |= (prefixes & PREFIX_ADDR);
5711 if (address_mode == mode_64bit)
bc51c5c9
FB
5712 {
5713 if (!(sizeflag & AFLAG))
c2c73b42 5714 s = names32[code - eAX_reg];
bc51c5c9 5715 else
c2c73b42 5716 s = names64[code - eAX_reg];
bc51c5c9
FB
5717 }
5718 else if (sizeflag & AFLAG)
5719 s = names32[code - eAX_reg];
5720 else
5721 s = names16[code - eAX_reg];
5722 oappend (s);
c2c73b42
BS
5723 *obufp++ = close_char;
5724 *obufp = 0;
bc51c5c9
FB
5725}
5726
5727static void
c2c73b42 5728OP_ESreg (int code, int sizeflag)
bc51c5c9 5729{
c2c73b42 5730 if (intel_syntax)
88103cfe
BS
5731 {
5732 switch (codep[-1])
5733 {
5734 case 0x6d: /* insw/insl */
5735 intel_operand_size (z_mode, sizeflag);
5736 break;
5737 case 0xa5: /* movsw/movsl/movsq */
5738 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5739 case 0xab: /* stosw/stosl */
5740 case 0xaf: /* scasw/scasl */
5741 intel_operand_size (v_mode, sizeflag);
5742 break;
5743 default:
5744 intel_operand_size (b_mode, sizeflag);
5745 }
5746 }
bc51c5c9
FB
5747 oappend ("%es:" + intel_syntax);
5748 ptr_reg (code, sizeflag);
5749}
5750
5751static void
c2c73b42 5752OP_DSreg (int code, int sizeflag)
dc99065b 5753{
c2c73b42 5754 if (intel_syntax)
88103cfe
BS
5755 {
5756 switch (codep[-1])
5757 {
5758 case 0x6f: /* outsw/outsl */
5759 intel_operand_size (z_mode, sizeflag);
5760 break;
5761 case 0xa5: /* movsw/movsl/movsq */
5762 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5763 case 0xad: /* lodsw/lodsl/lodsq */
5764 intel_operand_size (v_mode, sizeflag);
5765 break;
5766 default:
5767 intel_operand_size (b_mode, sizeflag);
5768 }
5769 }
dc99065b
FB
5770 if ((prefixes
5771 & (PREFIX_CS
5772 | PREFIX_DS
5773 | PREFIX_SS
5774 | PREFIX_ES
5775 | PREFIX_FS
5776 | PREFIX_GS)) == 0)
5777 prefixes |= PREFIX_DS;
bc51c5c9
FB
5778 append_seg ();
5779 ptr_reg (code, sizeflag);
dc99065b
FB
5780}
5781
bc51c5c9 5782static void
c2c73b42 5783OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 5784{
bc51c5c9 5785 int add = 0;
88103cfe 5786 if (rex & REX_R)
c2c73b42 5787 {
88103cfe 5788 USED_REX (REX_R);
c2c73b42
BS
5789 add = 8;
5790 }
5791 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5792 {
5793 used_prefixes |= PREFIX_LOCK;
5794 add = 8;
5795 }
88103cfe 5796 snprintf (scratchbuf, sizeof(scratchbuf), "%%cr%d", modrm.reg + add);
bc51c5c9 5797 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5798}
5799
bc51c5c9 5800static void
c2c73b42 5801OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 5802{
bc51c5c9 5803 int add = 0;
88103cfe
BS
5804 USED_REX (REX_R);
5805 if (rex & REX_R)
bc51c5c9
FB
5806 add = 8;
5807 if (intel_syntax)
88103cfe 5808 snprintf (scratchbuf, sizeof(scratchbuf), "db%d", modrm.reg + add);
bc51c5c9 5809 else
88103cfe 5810 snprintf (scratchbuf, sizeof(scratchbuf), "%%db%d", modrm.reg + add);
dc99065b 5811 oappend (scratchbuf);
dc99065b
FB
5812}
5813
bc51c5c9 5814static void
c2c73b42 5815OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 5816{
88103cfe 5817 snprintf (scratchbuf, sizeof(scratchbuf), "%%tr%d", modrm.reg);
bc51c5c9 5818 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5819}
5820
bc51c5c9 5821static void
88103cfe 5822OP_R (int bytemode, int sizeflag)
dc99065b 5823{
88103cfe 5824 if (modrm.mod == 3)
bc51c5c9
FB
5825 OP_E (bytemode, sizeflag);
5826 else
5827 BadOp ();
dc99065b
FB
5828}
5829
bc51c5c9 5830static void
c2c73b42 5831OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 5832{
bc51c5c9
FB
5833 used_prefixes |= (prefixes & PREFIX_DATA);
5834 if (prefixes & PREFIX_DATA)
c2c73b42
BS
5835 {
5836 int add = 0;
88103cfe
BS
5837 USED_REX (REX_R);
5838 if (rex & REX_R)
c2c73b42 5839 add = 8;
88103cfe 5840 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
c2c73b42 5841 }
bc51c5c9 5842 else
88103cfe 5843 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
bc51c5c9 5844 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5845}
5846
bc51c5c9 5847static void
c2c73b42 5848OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
dc99065b 5849{
bc51c5c9 5850 int add = 0;
88103cfe
BS
5851 USED_REX (REX_R);
5852 if (rex & REX_R)
bc51c5c9 5853 add = 8;
88103cfe 5854 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
bc51c5c9 5855 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5856}
5857
bc51c5c9 5858static void
c2c73b42 5859OP_EM (int bytemode, int sizeflag)
dc99065b 5860{
88103cfe 5861 if (modrm.mod != 3)
bc51c5c9 5862 {
c2c73b42
BS
5863 if (intel_syntax && bytemode == v_mode)
5864 {
5865 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5866 used_prefixes |= (prefixes & PREFIX_DATA);
5867 }
bc51c5c9
FB
5868 OP_E (bytemode, sizeflag);
5869 return;
5870 }
dc99065b 5871
bc51c5c9
FB
5872 /* Skip mod/rm byte. */
5873 MODRM_CHECK;
dc99065b 5874 codep++;
bc51c5c9
FB
5875 used_prefixes |= (prefixes & PREFIX_DATA);
5876 if (prefixes & PREFIX_DATA)
c2c73b42
BS
5877 {
5878 int add = 0;
5879
88103cfe
BS
5880 USED_REX (REX_B);
5881 if (rex & REX_B)
c2c73b42 5882 add = 8;
88103cfe 5883 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
c2c73b42 5884 }
bc51c5c9 5885 else
88103cfe 5886 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
bc51c5c9 5887 oappend (scratchbuf + intel_syntax);
dc99065b
FB
5888}
5889
88103cfe
BS
5890/* cvt* are the only instructions in sse2 which have
5891 both SSE and MMX operands and also have 0x66 prefix
5892 in their opcode. 0x66 was originally used to differentiate
5893 between SSE and MMX instruction(operands). So we have to handle the
5894 cvt* separately using OP_EMC and OP_MXC */
bc51c5c9 5895static void
88103cfe 5896OP_EMC (int bytemode, int sizeflag)
dc99065b 5897{
88103cfe 5898 if (modrm.mod != 3)
bc51c5c9 5899 {
c2c73b42
BS
5900 if (intel_syntax && bytemode == v_mode)
5901 {
88103cfe
BS
5902 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5903 used_prefixes |= (prefixes & PREFIX_DATA);
5904 }
5905 OP_E (bytemode, sizeflag);
5906 return;
5907 }
5908
5909 /* Skip mod/rm byte. */
5910 MODRM_CHECK;
5911 codep++;
5912 used_prefixes |= (prefixes & PREFIX_DATA);
5913 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
5914 oappend (scratchbuf + intel_syntax);
5915}
5916
5917static void
5918OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5919{
5920 used_prefixes |= (prefixes & PREFIX_DATA);
5921 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
5922 oappend (scratchbuf + intel_syntax);
5923}
5924
5925static void
5926OP_EX (int bytemode, int sizeflag)
5927{
5928 int add = 0;
5929 if (modrm.mod != 3)
5930 {
bc51c5c9
FB
5931 OP_E (bytemode, sizeflag);
5932 return;
5933 }
88103cfe
BS
5934 USED_REX (REX_B);
5935 if (rex & REX_B)
bc51c5c9
FB
5936 add = 8;
5937
5938 /* Skip mod/rm byte. */
5939 MODRM_CHECK;
5940 codep++;
88103cfe 5941 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
bc51c5c9
FB
5942 oappend (scratchbuf + intel_syntax);
5943}
5944
5945static void
c2c73b42 5946OP_MS (int bytemode, int sizeflag)
bc51c5c9 5947{
88103cfe 5948 if (modrm.mod == 3)
bc51c5c9
FB
5949 OP_EM (bytemode, sizeflag);
5950 else
5951 BadOp ();
5952}
5953
5954static void
c2c73b42 5955OP_XS (int bytemode, int sizeflag)
bc51c5c9 5956{
88103cfe 5957 if (modrm.mod == 3)
bc51c5c9
FB
5958 OP_EX (bytemode, sizeflag);
5959 else
5960 BadOp ();
5961}
5962
c2c73b42
BS
5963static void
5964OP_M (int bytemode, int sizeflag)
5965{
88103cfe
BS
5966 if (modrm.mod == 3)
5967 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5968 BadOp ();
c2c73b42
BS
5969 else
5970 OP_E (bytemode, sizeflag);
5971}
5972
5973static void
5974OP_0f07 (int bytemode, int sizeflag)
5975{
88103cfe 5976 if (modrm.mod != 3 || modrm.rm != 0)
c2c73b42
BS
5977 BadOp ();
5978 else
5979 OP_E (bytemode, sizeflag);
5980}
5981
5982static void
5983OP_0fae (int bytemode, int sizeflag)
5984{
88103cfe 5985 if (modrm.mod == 3)
c2c73b42 5986 {
88103cfe 5987 if (modrm.reg == 7)
c2c73b42
BS
5988 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5989
88103cfe 5990 if (modrm.reg < 5 || modrm.rm != 0)
c2c73b42
BS
5991 {
5992 BadOp (); /* bad sfence, mfence, or lfence */
5993 return;
5994 }
5995 }
88103cfe 5996 else if (modrm.reg != 7)
c2c73b42
BS
5997 {
5998 BadOp (); /* bad clflush */
5999 return;
6000 }
6001
6002 OP_E (bytemode, sizeflag);
6003}
6004
88103cfe
BS
6005/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6006 32bit mode and "xchg %rax,%rax" in 64bit mode. */
6007
6008static void
6009NOP_Fixup1 (int bytemode, int sizeflag)
6010{
6011 if ((prefixes & PREFIX_DATA) != 0
6012 || (rex != 0
6013 && rex != 0x48
6014 && address_mode == mode_64bit))
6015 OP_REG (bytemode, sizeflag);
6016 else
6017 strcpy (obuf, "nop");
6018}
6019
c2c73b42 6020static void
88103cfe 6021NOP_Fixup2 (int bytemode, int sizeflag)
c2c73b42 6022{
88103cfe
BS
6023 if ((prefixes & PREFIX_DATA) != 0
6024 || (rex != 0
6025 && rex != 0x48
6026 && address_mode == mode_64bit))
6027 OP_IMREG (bytemode, sizeflag);
c2c73b42
BS
6028}
6029
bc51c5c9
FB
6030static const char *Suffix3DNow[] = {
6031/* 00 */ NULL, NULL, NULL, NULL,
6032/* 04 */ NULL, NULL, NULL, NULL,
6033/* 08 */ NULL, NULL, NULL, NULL,
6034/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
6035/* 10 */ NULL, NULL, NULL, NULL,
6036/* 14 */ NULL, NULL, NULL, NULL,
6037/* 18 */ NULL, NULL, NULL, NULL,
6038/* 1C */ "pf2iw", "pf2id", NULL, NULL,
6039/* 20 */ NULL, NULL, NULL, NULL,
6040/* 24 */ NULL, NULL, NULL, NULL,
6041/* 28 */ NULL, NULL, NULL, NULL,
6042/* 2C */ NULL, NULL, NULL, NULL,
6043/* 30 */ NULL, NULL, NULL, NULL,
6044/* 34 */ NULL, NULL, NULL, NULL,
6045/* 38 */ NULL, NULL, NULL, NULL,
6046/* 3C */ NULL, NULL, NULL, NULL,
6047/* 40 */ NULL, NULL, NULL, NULL,
6048/* 44 */ NULL, NULL, NULL, NULL,
6049/* 48 */ NULL, NULL, NULL, NULL,
6050/* 4C */ NULL, NULL, NULL, NULL,
6051/* 50 */ NULL, NULL, NULL, NULL,
6052/* 54 */ NULL, NULL, NULL, NULL,
6053/* 58 */ NULL, NULL, NULL, NULL,
6054/* 5C */ NULL, NULL, NULL, NULL,
6055/* 60 */ NULL, NULL, NULL, NULL,
6056/* 64 */ NULL, NULL, NULL, NULL,
6057/* 68 */ NULL, NULL, NULL, NULL,
6058/* 6C */ NULL, NULL, NULL, NULL,
6059/* 70 */ NULL, NULL, NULL, NULL,
6060/* 74 */ NULL, NULL, NULL, NULL,
6061/* 78 */ NULL, NULL, NULL, NULL,
6062/* 7C */ NULL, NULL, NULL, NULL,
6063/* 80 */ NULL, NULL, NULL, NULL,
6064/* 84 */ NULL, NULL, NULL, NULL,
6065/* 88 */ NULL, NULL, "pfnacc", NULL,
6066/* 8C */ NULL, NULL, "pfpnacc", NULL,
6067/* 90 */ "pfcmpge", NULL, NULL, NULL,
6068/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
6069/* 98 */ NULL, NULL, "pfsub", NULL,
6070/* 9C */ NULL, NULL, "pfadd", NULL,
6071/* A0 */ "pfcmpgt", NULL, NULL, NULL,
6072/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
6073/* A8 */ NULL, NULL, "pfsubr", NULL,
6074/* AC */ NULL, NULL, "pfacc", NULL,
6075/* B0 */ "pfcmpeq", NULL, NULL, NULL,
88103cfe 6076/* B4 */ "pfmul", NULL, "pfrcpit2", "pmulhrw",
bc51c5c9
FB
6077/* B8 */ NULL, NULL, NULL, "pswapd",
6078/* BC */ NULL, NULL, NULL, "pavgusb",
6079/* C0 */ NULL, NULL, NULL, NULL,
6080/* C4 */ NULL, NULL, NULL, NULL,
6081/* C8 */ NULL, NULL, NULL, NULL,
6082/* CC */ NULL, NULL, NULL, NULL,
6083/* D0 */ NULL, NULL, NULL, NULL,
6084/* D4 */ NULL, NULL, NULL, NULL,
6085/* D8 */ NULL, NULL, NULL, NULL,
6086/* DC */ NULL, NULL, NULL, NULL,
6087/* E0 */ NULL, NULL, NULL, NULL,
6088/* E4 */ NULL, NULL, NULL, NULL,
6089/* E8 */ NULL, NULL, NULL, NULL,
6090/* EC */ NULL, NULL, NULL, NULL,
6091/* F0 */ NULL, NULL, NULL, NULL,
6092/* F4 */ NULL, NULL, NULL, NULL,
6093/* F8 */ NULL, NULL, NULL, NULL,
6094/* FC */ NULL, NULL, NULL, NULL,
6095};
6096
6097static void
c2c73b42 6098OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
bc51c5c9
FB
6099{
6100 const char *mnemonic;
6101
6102 FETCH_DATA (the_info, codep + 1);
6103 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6104 place where an 8-bit immediate would normally go. ie. the last
6105 byte of the instruction. */
6106 obufp = obuf + strlen (obuf);
6107 mnemonic = Suffix3DNow[*codep++ & 0xff];
6108 if (mnemonic)
6109 oappend (mnemonic);
6110 else
6111 {
6112 /* Since a variable sized modrm/sib chunk is between the start
6113 of the opcode (0x0f0f) and the opcode suffix, we need to do
6114 all the modrm processing first, and don't know until now that
6115 we have a bad opcode. This necessitates some cleaning up. */
88103cfe
BS
6116 op_out[0][0] = '\0';
6117 op_out[1][0] = '\0';
bc51c5c9
FB
6118 BadOp ();
6119 }
6120}
6121
6122static const char *simd_cmp_op[] = {
6123 "eq",
6124 "lt",
6125 "le",
6126 "unord",
6127 "neq",
6128 "nlt",
6129 "nle",
6130 "ord"
6131};
6132
6133static void
c2c73b42 6134OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
bc51c5c9
FB
6135{
6136 unsigned int cmp_type;
6137
6138 FETCH_DATA (the_info, codep + 1);
6139 obufp = obuf + strlen (obuf);
6140 cmp_type = *codep++ & 0xff;
6141 if (cmp_type < 8)
6142 {
6143 char suffix1 = 'p', suffix2 = 's';
6144 used_prefixes |= (prefixes & PREFIX_REPZ);
6145 if (prefixes & PREFIX_REPZ)
6146 suffix1 = 's';
6147 else
6148 {
6149 used_prefixes |= (prefixes & PREFIX_DATA);
6150 if (prefixes & PREFIX_DATA)
6151 suffix2 = 'd';
6152 else
6153 {
6154 used_prefixes |= (prefixes & PREFIX_REPNZ);
6155 if (prefixes & PREFIX_REPNZ)
6156 suffix1 = 's', suffix2 = 'd';
6157 }
6158 }
363a37d5
BS
6159 snprintf (scratchbuf, sizeof(scratchbuf), "cmp%s%c%c",
6160 simd_cmp_op[cmp_type], suffix1, suffix2);
bc51c5c9
FB
6161 used_prefixes |= (prefixes & PREFIX_REPZ);
6162 oappend (scratchbuf);
6163 }
6164 else
6165 {
6166 /* We have a bad extension byte. Clean up. */
88103cfe
BS
6167 op_out[0][0] = '\0';
6168 op_out[1][0] = '\0';
bc51c5c9
FB
6169 BadOp ();
6170 }
6171}
6172
6173static void
c2c73b42 6174SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
bc51c5c9
FB
6175{
6176 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6177 forms of these instructions. */
88103cfe 6178 if (modrm.mod == 3)
bc51c5c9
FB
6179 {
6180 char *p = obuf + strlen (obuf);
6181 *(p + 1) = '\0';
6182 *p = *(p - 1);
6183 *(p - 1) = *(p - 2);
6184 *(p - 2) = *(p - 3);
6185 *(p - 3) = extrachar;
6186 }
6187}
6188
c2c73b42
BS
6189static void
6190PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6191{
88103cfe 6192 if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
c2c73b42
BS
6193 {
6194 /* Override "sidt". */
6195 size_t olen = strlen (obuf);
6196 char *p = obuf + olen - 4;
6197 const char * const *names = (address_mode == mode_64bit
6198 ? names64 : names32);
6199
6200 /* We might have a suffix when disassembling with -Msuffix. */
6201 if (*p == 'i')
6202 --p;
6203
6204 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6205 if (!intel_syntax
6206 && (prefixes & PREFIX_ADDR)
6207 && olen >= (4 + 7)
6208 && *(p - 1) == ' '
6209 && strncmp (p - 7, "addr", 4) == 0
6210 && (strncmp (p - 3, "16", 2) == 0
6211 || strncmp (p - 3, "32", 2) == 0))
6212 p -= 7;
6213
88103cfe 6214 if (modrm.rm)
c2c73b42
BS
6215 {
6216 /* mwait %eax,%ecx */
6217 strcpy (p, "mwait");
6218 if (!intel_syntax)
88103cfe 6219 strcpy (op_out[0], names[0]);
c2c73b42
BS
6220 }
6221 else
6222 {
6223 /* monitor %eax,%ecx,%edx" */
6224 strcpy (p, "monitor");
6225 if (!intel_syntax)
6226 {
6227 const char * const *op1_names;
6228 if (!(prefixes & PREFIX_ADDR))
6229 op1_names = (address_mode == mode_16bit
6230 ? names16 : names);
6231 else
6232 {
6233 op1_names = (address_mode != mode_32bit
6234 ? names32 : names16);
6235 used_prefixes |= PREFIX_ADDR;
6236 }
88103cfe
BS
6237 strcpy (op_out[0], op1_names[0]);
6238 strcpy (op_out[2], names[2]);
c2c73b42
BS
6239 }
6240 }
6241 if (!intel_syntax)
6242 {
88103cfe 6243 strcpy (op_out[1], names[1]);
c2c73b42
BS
6244 two_source_ops = 1;
6245 }
6246
6247 codep++;
6248 }
6249 else
6250 OP_M (0, sizeflag);
6251}
6252
6253static void
6254SVME_Fixup (int bytemode, int sizeflag)
6255{
6256 const char *alt;
6257 char *p;
6258
6259 switch (*codep)
6260 {
6261 case 0xd8:
6262 alt = "vmrun";
6263 break;
6264 case 0xd9:
6265 alt = "vmmcall";
6266 break;
6267 case 0xda:
6268 alt = "vmload";
6269 break;
6270 case 0xdb:
6271 alt = "vmsave";
6272 break;
6273 case 0xdc:
6274 alt = "stgi";
6275 break;
6276 case 0xdd:
6277 alt = "clgi";
6278 break;
6279 case 0xde:
6280 alt = "skinit";
6281 break;
6282 case 0xdf:
6283 alt = "invlpga";
6284 break;
6285 default:
6286 OP_M (bytemode, sizeflag);
6287 return;
6288 }
6289 /* Override "lidt". */
6290 p = obuf + strlen (obuf) - 4;
6291 /* We might have a suffix. */
6292 if (*p == 'i')
6293 --p;
6294 strcpy (p, alt);
6295 if (!(prefixes & PREFIX_ADDR))
6296 {
6297 ++codep;
6298 return;
6299 }
6300 used_prefixes |= PREFIX_ADDR;
6301 switch (*codep++)
6302 {
6303 case 0xdf:
88103cfe 6304 strcpy (op_out[1], names32[1]);
c2c73b42
BS
6305 two_source_ops = 1;
6306 /* Fall through. */
6307 case 0xd8:
6308 case 0xda:
6309 case 0xdb:
6310 *obufp++ = open_char;
6311 if (address_mode == mode_64bit || (sizeflag & AFLAG))
6312 alt = names32[0];
6313 else
6314 alt = names16[0];
6315 strcpy (obufp, alt);
6316 obufp += strlen (alt);
6317 *obufp++ = close_char;
6318 *obufp = '\0';
6319 break;
6320 }
6321}
6322
6323static void
6324INVLPG_Fixup (int bytemode, int sizeflag)
6325{
6326 const char *alt;
6327
6328 switch (*codep)
6329 {
6330 case 0xf8:
6331 alt = "swapgs";
6332 break;
6333 case 0xf9:
6334 alt = "rdtscp";
6335 break;
6336 default:
6337 OP_M (bytemode, sizeflag);
6338 return;
6339 }
6340 /* Override "invlpg". */
6341 strcpy (obuf + strlen (obuf) - 6, alt);
6342 codep++;
6343}
6344
bc51c5c9
FB
6345static void
6346BadOp (void)
6347{
6348 /* Throw away prefixes and 1st. opcode byte. */
6349 codep = insn_codep + 1;
6350 oappend ("(bad)");
dc99065b 6351}
c2c73b42 6352
c2c73b42
BS
6353static void
6354VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6355{
88103cfe
BS
6356 if (modrm.mod == 3
6357 && modrm.reg == 0
6358 && modrm.rm >=1
6359 && modrm.rm <= 4)
c2c73b42
BS
6360 {
6361 /* Override "sgdt". */
6362 char *p = obuf + strlen (obuf) - 4;
6363
6364 /* We might have a suffix when disassembling with -Msuffix. */
6365 if (*p == 'g')
6366 --p;
6367
88103cfe 6368 switch (modrm.rm)
c2c73b42
BS
6369 {
6370 case 1:
6371 strcpy (p, "vmcall");
6372 break;
6373 case 2:
6374 strcpy (p, "vmlaunch");
6375 break;
6376 case 3:
6377 strcpy (p, "vmresume");
6378 break;
6379 case 4:
6380 strcpy (p, "vmxoff");
6381 break;
6382 }
6383
6384 codep++;
6385 }
6386 else
6387 OP_E (0, sizeflag);
6388}
6389
6390static void
6391OP_VMX (int bytemode, int sizeflag)
6392{
6393 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6394 if (prefixes & PREFIX_DATA)
6395 strcpy (obuf, "vmclear");
6396 else if (prefixes & PREFIX_REPZ)
6397 strcpy (obuf, "vmxon");
6398 else
6399 strcpy (obuf, "vmptrld");
6400 OP_E (bytemode, sizeflag);
6401}
6402
6403static void
6404REP_Fixup (int bytemode, int sizeflag)
6405{
6406 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6407 lods and stos. */
6408 size_t ilen = 0;
6409
6410 if (prefixes & PREFIX_REPZ)
6411 switch (*insn_codep)
6412 {
6413 case 0x6e: /* outsb */
6414 case 0x6f: /* outsw/outsl */
6415 case 0xa4: /* movsb */
6416 case 0xa5: /* movsw/movsl/movsq */
6417 if (!intel_syntax)
6418 ilen = 5;
6419 else
6420 ilen = 4;
6421 break;
6422 case 0xaa: /* stosb */
6423 case 0xab: /* stosw/stosl/stosq */
6424 case 0xac: /* lodsb */
6425 case 0xad: /* lodsw/lodsl/lodsq */
6426 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6427 ilen = 5;
6428 else
6429 ilen = 4;
6430 break;
6431 case 0x6c: /* insb */
6432 case 0x6d: /* insl/insw */
6433 if (!intel_syntax)
6434 ilen = 4;
6435 else
6436 ilen = 3;
6437 break;
6438 default:
6439 abort ();
6440 break;
6441 }
6442
6443 if (ilen != 0)
6444 {
6445 size_t olen;
6446 char *p;
6447
6448 olen = strlen (obuf);
6449 p = obuf + olen - ilen - 1 - 4;
6450 /* Handle "repz [addr16|addr32]". */
6451 if ((prefixes & PREFIX_ADDR))
6452 p -= 1 + 6;
6453
6454 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6455 }
6456
6457 switch (bytemode)
6458 {
6459 case al_reg:
6460 case eAX_reg:
6461 case indir_dx_reg:
6462 OP_IMREG (bytemode, sizeflag);
6463 break;
6464 case eDI_reg:
6465 OP_ESreg (bytemode, sizeflag);
6466 break;
6467 case eSI_reg:
6468 OP_DSreg (bytemode, sizeflag);
6469 break;
6470 default:
6471 abort ();
6472 break;
6473 }
6474}
88103cfe
BS
6475
6476static void
6477CMPXCHG8B_Fixup (int bytemode, int sizeflag)
6478{
6479 USED_REX (REX_W);
6480 if (rex & REX_W)
6481 {
6482 /* Change cmpxchg8b to cmpxchg16b. */
6483 char *p = obuf + strlen (obuf) - 2;
6484 strcpy (p, "16b");
6485 bytemode = o_mode;
6486 }
6487 OP_M (bytemode, sizeflag);
6488}
6489
6490static void
6491XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6492{
6493 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", reg);
6494 oappend (scratchbuf + intel_syntax);
6495}
6496
6497static void
6498CRC32_Fixup (int bytemode, int sizeflag)
6499{
6500 /* Add proper suffix to "crc32". */
6501 char *p = obuf + strlen (obuf);
6502
6503 switch (bytemode)
6504 {
6505 case b_mode:
6506 if (intel_syntax)
6507 break;
6508
6509 *p++ = 'b';
6510 break;
6511 case v_mode:
6512 if (intel_syntax)
6513 break;
6514
6515 USED_REX (REX_W);
6516 if (rex & REX_W)
6517 *p++ = 'q';
6518 else if (sizeflag & DFLAG)
6519 *p++ = 'l';
6520 else
6521 *p++ = 'w';
6522 used_prefixes |= (prefixes & PREFIX_DATA);
6523 break;
6524 default:
6525 oappend (INTERNAL_DISASSEMBLER_ERROR);
6526 break;
6527 }
6528 *p = '\0';
6529
6530 if (modrm.mod == 3)
6531 {
6532 int add;
6533
6534 /* Skip mod/rm byte. */
6535 MODRM_CHECK;
6536 codep++;
6537
6538 USED_REX (REX_B);
6539 add = (rex & REX_B) ? 8 : 0;
6540 if (bytemode == b_mode)
6541 {
6542 USED_REX (0);
6543 if (rex)
6544 oappend (names8rex[modrm.rm + add]);
6545 else
6546 oappend (names8[modrm.rm + add]);
6547 }
6548 else
6549 {
6550 USED_REX (REX_W);
6551 if (rex & REX_W)
6552 oappend (names64[modrm.rm + add]);
6553 else if ((prefixes & PREFIX_DATA))
6554 oappend (names16[modrm.rm + add]);
6555 else
6556 oappend (names32[modrm.rm + add]);
6557 }
6558 }
6559 else
6560 OP_E (bytemode, sizeflag);
6561}