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