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