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