Rework patch to check by both armap entry and archive offset. Also,
[binutils.git] / opcodes / i386-dis.c
blob19b13d0dad4f293ad242cc8e06fd91f0ce8f2594
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.
5 This file is part of the GNU opcodes library.
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.
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.
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. */
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). */
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. */
36 #include "sysdep.h"
37 #include "dis-asm.h"
38 #include "opintl.h"
39 #include "opcode/i386.h"
40 #include "libiberty.h"
42 #include <setjmp.h>
44 static int fetch_data (struct disassemble_info *, bfd_byte *);
45 static void ckprefix (void);
46 static const char *prefix_name (int, int);
47 static int print_insn (bfd_vma, disassemble_info *);
48 static void dofloat (int);
49 static void OP_ST (int, int);
50 static void OP_STi (int, int);
51 static int putop (const char *, int);
52 static void oappend (const char *);
53 static void append_seg (void);
54 static void OP_indirE (int, int);
55 static void print_operand_value (char *, int, bfd_vma);
56 static void OP_E_extended (int, int, int);
57 static void print_displacement (char *, bfd_vma);
58 static void OP_E (int, int);
59 static void OP_G (int, int);
60 static bfd_vma get64 (void);
61 static bfd_signed_vma get32 (void);
62 static bfd_signed_vma get32s (void);
63 static int get16 (void);
64 static void set_op (bfd_vma, int);
65 static void OP_Skip_MODRM (int, int);
66 static void OP_REG (int, int);
67 static void OP_IMREG (int, int);
68 static void OP_I (int, int);
69 static void OP_I64 (int, int);
70 static void OP_sI (int, int);
71 static void OP_J (int, int);
72 static void OP_SEG (int, int);
73 static void OP_DIR (int, int);
74 static void OP_OFF (int, int);
75 static void OP_OFF64 (int, int);
76 static void ptr_reg (int, int);
77 static void OP_ESreg (int, int);
78 static void OP_DSreg (int, int);
79 static void OP_C (int, int);
80 static void OP_D (int, int);
81 static void OP_T (int, int);
82 static void OP_R (int, int);
83 static void OP_MMX (int, int);
84 static void OP_XMM (int, int);
85 static void OP_EM (int, int);
86 static void OP_EX (int, int);
87 static void OP_EMC (int,int);
88 static void OP_MXC (int,int);
89 static void OP_MS (int, int);
90 static void OP_XS (int, int);
91 static void OP_M (int, int);
92 static void OP_0f07 (int, int);
93 static void OP_Monitor (int, int);
94 static void OP_Mwait (int, int);
95 static void NOP_Fixup1 (int, int);
96 static void NOP_Fixup2 (int, int);
97 static void OP_3DNowSuffix (int, int);
98 static void OP_SIMD_Suffix (int, int);
99 static void BadOp (void);
100 static void REP_Fixup (int, int);
101 static void CMPXCHG8B_Fixup (int, int);
102 static void XMM_Fixup (int, int);
103 static void CRC32_Fixup (int, int);
104 static void print_drex_arg (unsigned int, int, int);
105 static void OP_DREX4 (int, int);
106 static void OP_DREX3 (int, int);
107 static void OP_DREX_ICMP (int, int);
108 static void OP_DREX_FCMP (int, int);
110 struct 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;
119 enum address_mode
121 mode_16bit,
122 mode_32bit,
123 mode_64bit
126 enum address_mode address_mode;
128 /* Flags for the prefixes for the current instruction. See below. */
129 static int prefixes;
131 /* REX prefix the current instruction. See below. */
132 static int rex;
133 /* Bits of REX we've already used. */
134 static 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) \
141 if (value) \
143 if ((rex & value)) \
144 rex_used |= (value) | REX_OPCODE; \
146 else \
147 rex_used |= REX_OPCODE; \
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 */
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)
164 /* Flags for prefixes which we somehow handled when printing the
165 current instruction. */
166 static int used_prefixes;
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
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)))
189 static int
190 fetch_data (struct disassemble_info *info, bfd_byte *addr)
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);
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)
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);
213 else
214 priv->max_fetched = addr;
215 return 1;
218 #define XX { NULL, 0 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
356 #define cond_jump_flag { NULL, cond_jump_mode }
357 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
359 /* bits in sizeflag */
360 #define SUFFIX_ALWAYS 4
361 #define AFLAG 2
362 #define DFLAG 1
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. */
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 */
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
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
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
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
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
432 #define z_mode_ax_reg 149
433 #define indir_dx_reg 150
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
443 #define FLOAT NULL, { { NULL, FLOATCODE } }
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 } }
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 } }
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 } }
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 } }
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 } }
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 } }
644 typedef void (*op_rtn) (int bytemode, int sizeflag);
646 struct dis386 {
647 const char *name;
648 struct
650 op_rtn rtn;
651 int bytemode;
652 } op[MAX_OPERANDS];
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
687 Many of the above letters print nothing in Intel mode. See "putop"
688 for the details.
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.
696 static 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 },
987 static 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 } },
1278 static 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 */
1301 static 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 */
1324 static char obuf[100];
1325 static char *obufp;
1326 static char scratchbuf[100];
1327 static unsigned char *start_codep;
1328 static unsigned char *insn_codep;
1329 static unsigned char *codep;
1330 static const char *lock_prefix;
1331 static const char *data_prefix;
1332 static const char *addr_prefix;
1333 static const char *repz_prefix;
1334 static const char *repnz_prefix;
1335 static disassemble_info *the_info;
1336 static struct
1338 int mod;
1339 int reg;
1340 int rm;
1342 modrm;
1343 static unsigned char need_modrm;
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 ()
1350 static const char **names64;
1351 static const char **names32;
1352 static const char **names16;
1353 static const char **names8;
1354 static const char **names8rex;
1355 static const char **names_seg;
1356 static const char **index16;
1358 static const char *intel_names64[] = {
1359 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1360 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1362 static const char *intel_names32[] = {
1363 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1364 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1366 static const char *intel_names16[] = {
1367 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1368 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1370 static const char *intel_names8[] = {
1371 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1373 static const char *intel_names8rex[] = {
1374 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1375 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1377 static const char *intel_names_seg[] = {
1378 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1380 static const char *intel_index16[] = {
1381 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1384 static const char *att_names64[] = {
1385 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1386 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1388 static const char *att_names32[] = {
1389 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1390 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1392 static const char *att_names16[] = {
1393 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1394 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1396 static const char *att_names8[] = {
1397 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1399 static const char *att_names8rex[] = {
1400 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1401 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1403 static const char *att_names_seg[] = {
1404 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1406 static const char *att_index16[] = {
1407 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1410 static const struct dis386 grps[][8] = {
1411 /* GRP1a */
1413 { "popU", { stackEv } },
1414 { "(bad)", { XX } },
1415 { "(bad)", { XX } },
1416 { "(bad)", { XX } },
1417 { "(bad)", { XX } },
1418 { "(bad)", { XX } },
1419 { "(bad)", { XX } },
1420 { "(bad)", { XX } },
1422 /* GRP1b */
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 } },
1433 /* GRP1S */
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 } },
1444 /* GRP1Ss */
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 } },
1455 /* GRP2b */
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 } },
1466 /* GRP2S */
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 } },
1477 /* GRP2b_one */
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 } },
1488 /* GRP2S_one */
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 } },
1499 /* GRP2b_cl */
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 } },
1510 /* GRP2S_cl */
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 } },
1521 /* GRP3b */
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. */
1532 /* GRP3S */
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 } },
1543 /* GRP4 */
1545 { "incA", { Eb } },
1546 { "decA", { Eb } },
1547 { "(bad)", { XX } },
1548 { "(bad)", { XX } },
1549 { "(bad)", { XX } },
1550 { "(bad)", { XX } },
1551 { "(bad)", { XX } },
1552 { "(bad)", { XX } },
1554 /* GRP5 */
1556 { "incQ", { Ev } },
1557 { "decQ", { Ev } },
1558 { "callT", { indirEv } },
1559 { "JcallT", { indirEp } },
1560 { "jmpT", { indirEv } },
1561 { "JjmpT", { indirEp } },
1562 { "pushU", { stackEv } },
1563 { "(bad)", { XX } },
1565 /* GRP6 */
1567 { "sldtD", { Sv } },
1568 { "strD", { Sv } },
1569 { "lldt", { Ew } },
1570 { "ltr", { Ew } },
1571 { "verr", { Ew } },
1572 { "verw", { Ew } },
1573 { "(bad)", { XX } },
1574 { "(bad)", { XX } },
1576 /* GRP7 */
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 },
1587 /* GRP8 */
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 } },
1598 /* GRP9 */
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 },
1609 /* GRP11_C6 */
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 } },
1620 /* GRP11_C7 */
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 } },
1631 /* GRP12 */
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 } },
1642 /* GRP13 */
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 } },
1653 /* GRP14 */
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 },
1664 /* GRP15 */
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 },
1675 /* GRP16 */
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 } },
1686 /* GRPAMD */
1688 { "prefetch", { Eb } },
1689 { "prefetchw", { Eb } },
1690 { "(bad)", { XX } },
1691 { "(bad)", { XX } },
1692 { "(bad)", { XX } },
1693 { "(bad)", { XX } },
1694 { "(bad)", { XX } },
1695 { "(bad)", { XX } },
1697 /* GRPPADLCK1 */
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 } } },
1708 /* GRPPADLCK2 */
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 } } },
1721 static const struct dis386 prefix_user_table[][4] = {
1722 /* PREGRP0 */
1724 { "addps", { XM, EXx } },
1725 { "addss", { XM, EXd } },
1726 { "addpd", { XM, EXx } },
1727 { "addsd", { XM, EXq } },
1729 /* PREGRP1 */
1731 { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1732 { "", { XM, EXd, OPSIMD } },
1733 { "", { XM, EXx, OPSIMD } },
1734 { "", { XM, EXq, OPSIMD } },
1736 /* PREGRP2 */
1738 { "cvtpi2ps", { XM, EMCq } },
1739 { "cvtsi2ssY", { XM, Ev } },
1740 { "cvtpi2pd", { XM, EMCq } },
1741 { "cvtsi2sdY", { XM, Ev } },
1743 /* PREGRP3 */
1745 { "cvtps2pi", { MXC, EXq } },
1746 { "cvtss2siY", { Gv, EXd } },
1747 { "cvtpd2pi", { MXC, EXx } },
1748 { "cvtsd2siY", { Gv, EXq } },
1750 /* PREGRP4 */
1752 { "cvttps2pi", { MXC, EXq } },
1753 { "cvttss2siY", { Gv, EXd } },
1754 { "cvttpd2pi", { MXC, EXx } },
1755 { "cvttsd2siY", { Gv, EXq } },
1757 /* PREGRP5 */
1759 { "divps", { XM, EXx } },
1760 { "divss", { XM, EXd } },
1761 { "divpd", { XM, EXx } },
1762 { "divsd", { XM, EXq } },
1764 /* PREGRP6 */
1766 { "maxps", { XM, EXx } },
1767 { "maxss", { XM, EXd } },
1768 { "maxpd", { XM, EXx } },
1769 { "maxsd", { XM, EXq } },
1771 /* PREGRP7 */
1773 { "minps", { XM, EXx } },
1774 { "minss", { XM, EXd } },
1775 { "minpd", { XM, EXx } },
1776 { "minsd", { XM, EXq } },
1778 /* PREGRP8 */
1780 { "movups", { XM, EXx } },
1781 { "movss", { XM, EXd } },
1782 { "movupd", { XM, EXx } },
1783 { "movsd", { XM, EXq } },
1785 /* PREGRP9 */
1787 { "movups", { EXx, XM } },
1788 { "movss", { EXd, XM } },
1789 { "movupd", { EXx, XM } },
1790 { "movsd", { EXq, XM } },
1792 /* PREGRP10 */
1794 { "mulps", { XM, EXx } },
1795 { "mulss", { XM, EXd } },
1796 { "mulpd", { XM, EXx } },
1797 { "mulsd", { XM, EXq } },
1799 /* PREGRP11 */
1801 { "rcpps", { XM, EXx } },
1802 { "rcpss", { XM, EXd } },
1803 { "(bad)", { XM, EXx } },
1804 { "(bad)", { XM, EXx } },
1806 /* PREGRP12 */
1808 { "rsqrtps",{ XM, EXx } },
1809 { "rsqrtss",{ XM, EXd } },
1810 { "(bad)", { XM, EXx } },
1811 { "(bad)", { XM, EXx } },
1813 /* PREGRP13 */
1815 { "sqrtps", { XM, EXx } },
1816 { "sqrtss", { XM, EXd } },
1817 { "sqrtpd", { XM, EXx } },
1818 { "sqrtsd", { XM, EXq } },
1820 /* PREGRP14 */
1822 { "subps", { XM, EXx } },
1823 { "subss", { XM, EXd } },
1824 { "subpd", { XM, EXx } },
1825 { "subsd", { XM, EXq } },
1827 /* PREGRP15 */
1829 { "(bad)", { XM, EXx } },
1830 { "cvtdq2pd", { XM, EXq } },
1831 { "cvttpd2dq", { XM, EXx } },
1832 { "cvtpd2dq", { XM, EXx } },
1834 /* PREGRP16 */
1836 { "cvtdq2ps", { XM, EXx } },
1837 { "cvttps2dq", { XM, EXx } },
1838 { "cvtps2dq", { XM, EXx } },
1839 { "(bad)", { XM, EXx } },
1841 /* PREGRP17 */
1843 { "cvtps2pd", { XM, EXq } },
1844 { "cvtss2sd", { XM, EXd } },
1845 { "cvtpd2ps", { XM, EXx } },
1846 { "cvtsd2ss", { XM, EXq } },
1848 /* PREGRP18 */
1850 { "maskmovq", { MX, MS } },
1851 { "(bad)", { XM, EXx } },
1852 { "maskmovdqu", { XM, XS } },
1853 { "(bad)", { XM, EXx } },
1855 /* PREGRP19 */
1857 { "movq", { MX, EM } },
1858 { "movdqu", { XM, EXx } },
1859 { "movdqa", { XM, EXx } },
1860 { "(bad)", { XM, EXx } },
1862 /* PREGRP20 */
1864 { "movq", { EM, MX } },
1865 { "movdqu", { EXx, XM } },
1866 { "movdqa", { EXx, XM } },
1867 { "(bad)", { EXx, XM } },
1869 /* PREGRP21 */
1871 { "(bad)", { EXx, XM } },
1872 { "movq2dq",{ XM, MS } },
1873 { "movq", { EXq, XM } },
1874 { "movdq2q",{ MX, XS } },
1876 /* PREGRP22 */
1878 { "pshufw", { MX, EM, Ib } },
1879 { "pshufhw",{ XM, EXx, Ib } },
1880 { "pshufd", { XM, EXx, Ib } },
1881 { "pshuflw",{ XM, EXx, Ib } },
1883 /* PREGRP23 */
1885 { "movK", { Edq, MX } },
1886 { "movq", { XM, EXq } },
1887 { "movK", { Edq, XM } },
1888 { "(bad)", { Ed, XM } },
1890 /* PREGRP24 */
1892 { "(bad)", { MX, EXx } },
1893 { "(bad)", { XM, EXx } },
1894 { "punpckhqdq", { XM, EXx } },
1895 { "(bad)", { XM, EXx } },
1897 /* PREGRP25 */
1899 { "movntq", { EM, MX } },
1900 { "(bad)", { EM, XM } },
1901 { "movntdq",{ EM, XM } },
1902 { "(bad)", { EM, XM } },
1904 /* PREGRP26 */
1906 { "(bad)", { MX, EXx } },
1907 { "(bad)", { XM, EXx } },
1908 { "punpcklqdq", { XM, EXx } },
1909 { "(bad)", { XM, EXx } },
1911 /* PREGRP27 */
1913 { "(bad)", { MX, EXx } },
1914 { "(bad)", { XM, EXx } },
1915 { "addsubpd", { XM, EXx } },
1916 { "addsubps", { XM, EXx } },
1918 /* PREGRP28 */
1920 { "(bad)", { MX, EXx } },
1921 { "(bad)", { XM, EXx } },
1922 { "haddpd", { XM, EXx } },
1923 { "haddps", { XM, EXx } },
1925 /* PREGRP29 */
1927 { "(bad)", { MX, EXx } },
1928 { "(bad)", { XM, EXx } },
1929 { "hsubpd", { XM, EXx } },
1930 { "hsubps", { XM, EXx } },
1932 /* PREGRP30 */
1934 { OPC_EXT_36 },
1935 { "movsldup", { XM, EXx } },
1936 { "movlpd", { XM, EXq } },
1937 { "movddup", { XM, EXq } },
1939 /* PREGRP31 */
1941 { OPC_EXT_37 },
1942 { "movshdup", { XM, EXx } },
1943 { "movhpd", { XM, EXq } },
1944 { "(bad)", { XM, EXq } },
1946 /* PREGRP32 */
1948 { "(bad)", { XM, EXx } },
1949 { "(bad)", { XM, EXx } },
1950 { "(bad)", { XM, EXx } },
1951 { OPC_EXT_32 },
1953 /* PREGRP33 */
1955 {"movntps", { Ev, XM } },
1956 {"movntss", { Ed, XM } },
1957 {"movntpd", { Ev, XM } },
1958 {"movntsd", { Eq, XM } },
1961 /* PREGRP34 */
1963 {"vmread", { Em, Gm } },
1964 {"(bad)", { XX } },
1965 {"extrq", { XS, Ib, Ib } },
1966 {"insertq", { XM, XS, Ib, Ib } },
1969 /* PREGRP35 */
1971 {"vmwrite", { Gm, Em } },
1972 {"(bad)", { XX } },
1973 {"extrq", { XM, XS } },
1974 {"insertq", { XM, XS } },
1977 /* PREGRP36 */
1979 { "bsrS", { Gv, Ev } },
1980 { "lzcntS", { Gv, Ev } },
1981 { "bsrS", { Gv, Ev } },
1982 { "(bad)", { XX } },
1985 /* PREGRP37 */
1987 { "(bad)", { XX } },
1988 { "popcntS", { Gv, Ev } },
1989 { "(bad)", { XX } },
1990 { "(bad)", { XX } },
1993 /* PREGRP38 */
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 } },
2001 /* PREGRP39 */
2003 { "(bad)", { XX } },
2004 { "(bad)", { XX } },
2005 { "pblendvb", {XM, EXx, XMM0 } },
2006 { "(bad)", { XX } },
2009 /* PREGRP40 */
2011 { "(bad)", { XX } },
2012 { "(bad)", { XX } },
2013 { "blendvps", {XM, EXx, XMM0 } },
2014 { "(bad)", { XX } },
2017 /* PREGRP41 */
2019 { "(bad)", { XX } },
2020 { "(bad)", { XX } },
2021 { "blendvpd", { XM, EXx, XMM0 } },
2022 { "(bad)", { XX } },
2025 /* PREGRP42 */
2027 { "(bad)", { XX } },
2028 { "(bad)", { XX } },
2029 { "ptest", { XM, EXx } },
2030 { "(bad)", { XX } },
2033 /* PREGRP43 */
2035 { "(bad)", { XX } },
2036 { "(bad)", { XX } },
2037 { "pmovsxbw", { XM, EXq } },
2038 { "(bad)", { XX } },
2041 /* PREGRP44 */
2043 { "(bad)", { XX } },
2044 { "(bad)", { XX } },
2045 { "pmovsxbd", { XM, EXd } },
2046 { "(bad)", { XX } },
2049 /* PREGRP45 */
2051 { "(bad)", { XX } },
2052 { "(bad)", { XX } },
2053 { "pmovsxbq", { XM, EXw } },
2054 { "(bad)", { XX } },
2057 /* PREGRP46 */
2059 { "(bad)", { XX } },
2060 { "(bad)", { XX } },
2061 { "pmovsxwd", { XM, EXq } },
2062 { "(bad)", { XX } },
2065 /* PREGRP47 */
2067 { "(bad)", { XX } },
2068 { "(bad)", { XX } },
2069 { "pmovsxwq", { XM, EXd } },
2070 { "(bad)", { XX } },
2073 /* PREGRP48 */
2075 { "(bad)", { XX } },
2076 { "(bad)", { XX } },
2077 { "pmovsxdq", { XM, EXq } },
2078 { "(bad)", { XX } },
2081 /* PREGRP49 */
2083 { "(bad)", { XX } },
2084 { "(bad)", { XX } },
2085 { "pmuldq", { XM, EXx } },
2086 { "(bad)", { XX } },
2089 /* PREGRP50 */
2091 { "(bad)", { XX } },
2092 { "(bad)", { XX } },
2093 { "pcmpeqq", { XM, EXx } },
2094 { "(bad)", { XX } },
2097 /* PREGRP51 */
2099 { "(bad)", { XX } },
2100 { "(bad)", { XX } },
2101 { "movntdqa", { XM, EM } },
2102 { "(bad)", { XX } },
2105 /* PREGRP52 */
2107 { "(bad)", { XX } },
2108 { "(bad)", { XX } },
2109 { "packusdw", { XM, EXx } },
2110 { "(bad)", { XX } },
2113 /* PREGRP53 */
2115 { "(bad)", { XX } },
2116 { "(bad)", { XX } },
2117 { "pmovzxbw", { XM, EXq } },
2118 { "(bad)", { XX } },
2121 /* PREGRP54 */
2123 { "(bad)", { XX } },
2124 { "(bad)", { XX } },
2125 { "pmovzxbd", { XM, EXd } },
2126 { "(bad)", { XX } },
2129 /* PREGRP55 */
2131 { "(bad)", { XX } },
2132 { "(bad)", { XX } },
2133 { "pmovzxbq", { XM, EXw } },
2134 { "(bad)", { XX } },
2137 /* PREGRP56 */
2139 { "(bad)", { XX } },
2140 { "(bad)", { XX } },
2141 { "pmovzxwd", { XM, EXq } },
2142 { "(bad)", { XX } },
2145 /* PREGRP57 */
2147 { "(bad)", { XX } },
2148 { "(bad)", { XX } },
2149 { "pmovzxwq", { XM, EXd } },
2150 { "(bad)", { XX } },
2153 /* PREGRP58 */
2155 { "(bad)", { XX } },
2156 { "(bad)", { XX } },
2157 { "pmovzxdq", { XM, EXq } },
2158 { "(bad)", { XX } },
2161 /* PREGRP59 */
2163 { "(bad)", { XX } },
2164 { "(bad)", { XX } },
2165 { "pminsb", { XM, EXx } },
2166 { "(bad)", { XX } },
2169 /* PREGRP60 */
2171 { "(bad)", { XX } },
2172 { "(bad)", { XX } },
2173 { "pminsd", { XM, EXx } },
2174 { "(bad)", { XX } },
2177 /* PREGRP61 */
2179 { "(bad)", { XX } },
2180 { "(bad)", { XX } },
2181 { "pminuw", { XM, EXx } },
2182 { "(bad)", { XX } },
2185 /* PREGRP62 */
2187 { "(bad)", { XX } },
2188 { "(bad)", { XX } },
2189 { "pminud", { XM, EXx } },
2190 { "(bad)", { XX } },
2193 /* PREGRP63 */
2195 { "(bad)", { XX } },
2196 { "(bad)", { XX } },
2197 { "pmaxsb", { XM, EXx } },
2198 { "(bad)", { XX } },
2201 /* PREGRP64 */
2203 { "(bad)", { XX } },
2204 { "(bad)", { XX } },
2205 { "pmaxsd", { XM, EXx } },
2206 { "(bad)", { XX } },
2209 /* PREGRP65 */
2211 { "(bad)", { XX } },
2212 { "(bad)", { XX } },
2213 { "pmaxuw", { XM, EXx } },
2214 { "(bad)", { XX } },
2217 /* PREGRP66 */
2219 { "(bad)", { XX } },
2220 { "(bad)", { XX } },
2221 { "pmaxud", { XM, EXx } },
2222 { "(bad)", { XX } },
2225 /* PREGRP67 */
2227 { "(bad)", { XX } },
2228 { "(bad)", { XX } },
2229 { "pmulld", { XM, EXx } },
2230 { "(bad)", { XX } },
2233 /* PREGRP68 */
2235 { "(bad)", { XX } },
2236 { "(bad)", { XX } },
2237 { "phminposuw", { XM, EXx } },
2238 { "(bad)", { XX } },
2241 /* PREGRP69 */
2243 { "(bad)", { XX } },
2244 { "(bad)", { XX } },
2245 { "roundps", { XM, EXx, Ib } },
2246 { "(bad)", { XX } },
2249 /* PREGRP70 */
2251 { "(bad)", { XX } },
2252 { "(bad)", { XX } },
2253 { "roundpd", { XM, EXx, Ib } },
2254 { "(bad)", { XX } },
2257 /* PREGRP71 */
2259 { "(bad)", { XX } },
2260 { "(bad)", { XX } },
2261 { "roundss", { XM, EXd, Ib } },
2262 { "(bad)", { XX } },
2265 /* PREGRP72 */
2267 { "(bad)", { XX } },
2268 { "(bad)", { XX } },
2269 { "roundsd", { XM, EXq, Ib } },
2270 { "(bad)", { XX } },
2273 /* PREGRP73 */
2275 { "(bad)", { XX } },
2276 { "(bad)", { XX } },
2277 { "blendps", { XM, EXx, Ib } },
2278 { "(bad)", { XX } },
2281 /* PREGRP74 */
2283 { "(bad)", { XX } },
2284 { "(bad)", { XX } },
2285 { "blendpd", { XM, EXx, Ib } },
2286 { "(bad)", { XX } },
2289 /* PREGRP75 */
2291 { "(bad)", { XX } },
2292 { "(bad)", { XX } },
2293 { "pblendw", { XM, EXx, Ib } },
2294 { "(bad)", { XX } },
2297 /* PREGRP76 */
2299 { "(bad)", { XX } },
2300 { "(bad)", { XX } },
2301 { "pextrb", { Edqb, XM, Ib } },
2302 { "(bad)", { XX } },
2305 /* PREGRP77 */
2307 { "(bad)", { XX } },
2308 { "(bad)", { XX } },
2309 { "pextrw", { Edqw, XM, Ib } },
2310 { "(bad)", { XX } },
2313 /* PREGRP78 */
2315 { "(bad)", { XX } },
2316 { "(bad)", { XX } },
2317 { "pextrK", { Edq, XM, Ib } },
2318 { "(bad)", { XX } },
2321 /* PREGRP79 */
2323 { "(bad)", { XX } },
2324 { "(bad)", { XX } },
2325 { "extractps", { Edqd, XM, Ib } },
2326 { "(bad)", { XX } },
2329 /* PREGRP80 */
2331 { "(bad)", { XX } },
2332 { "(bad)", { XX } },
2333 { "pinsrb", { XM, Edqb, Ib } },
2334 { "(bad)", { XX } },
2337 /* PREGRP81 */
2339 { "(bad)", { XX } },
2340 { "(bad)", { XX } },
2341 { "insertps", { XM, EXd, Ib } },
2342 { "(bad)", { XX } },
2345 /* PREGRP82 */
2347 { "(bad)", { XX } },
2348 { "(bad)", { XX } },
2349 { "pinsrK", { XM, Edq, Ib } },
2350 { "(bad)", { XX } },
2353 /* PREGRP83 */
2355 { "(bad)", { XX } },
2356 { "(bad)", { XX } },
2357 { "dpps", { XM, EXx, Ib } },
2358 { "(bad)", { XX } },
2361 /* PREGRP84 */
2363 { "(bad)", { XX } },
2364 { "(bad)", { XX } },
2365 { "dppd", { XM, EXx, Ib } },
2366 { "(bad)", { XX } },
2369 /* PREGRP85 */
2371 { "(bad)", { XX } },
2372 { "(bad)", { XX } },
2373 { "mpsadbw", { XM, EXx, Ib } },
2374 { "(bad)", { XX } },
2377 /* PREGRP86 */
2379 { "(bad)", { XX } },
2380 { "(bad)", { XX } },
2381 { "pcmpgtq", { XM, EXx } },
2382 { "(bad)", { XX } },
2385 /* PREGRP87 */
2387 { "(bad)", { XX } },
2388 { "(bad)", { XX } },
2389 { "(bad)", { XX } },
2390 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
2393 /* PREGRP88 */
2395 { "(bad)", { XX } },
2396 { "(bad)", { XX } },
2397 { "(bad)", { XX } },
2398 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
2401 /* PREGRP89 */
2403 { "(bad)", { XX } },
2404 { "(bad)", { XX } },
2405 { "pcmpestrm", { XM, EXx, Ib } },
2406 { "(bad)", { XX } },
2409 /* PREGRP90 */
2411 { "(bad)", { XX } },
2412 { "(bad)", { XX } },
2413 { "pcmpestri", { XM, EXx, Ib } },
2414 { "(bad)", { XX } },
2417 /* PREGRP91 */
2419 { "(bad)", { XX } },
2420 { "(bad)", { XX } },
2421 { "pcmpistrm", { XM, EXx, Ib } },
2422 { "(bad)", { XX } },
2425 /* PREGRP92 */
2427 { "(bad)", { XX } },
2428 { "(bad)", { XX } },
2429 { "pcmpistri", { XM, EXx, Ib } },
2430 { "(bad)", { XX } },
2433 /* PREGRP93 */
2435 { "ucomiss",{ XM, EXd } },
2436 { "(bad)", { XX } },
2437 { "ucomisd",{ XM, EXq } },
2438 { "(bad)", { XX } },
2441 /* PREGRP94 */
2443 { "comiss", { XM, EXd } },
2444 { "(bad)", { XX } },
2445 { "comisd", { XM, EXq } },
2446 { "(bad)", { XX } },
2449 /* PREGRP95 */
2451 { "punpcklbw",{ MX, EMd } },
2452 { "(bad)", { XX } },
2453 { "punpcklbw",{ MX, EMx } },
2454 { "(bad)", { XX } },
2457 /* PREGRP96 */
2459 { "punpcklwd",{ MX, EMd } },
2460 { "(bad)", { XX } },
2461 { "punpcklwd",{ MX, EMx } },
2462 { "(bad)", { XX } },
2465 /* PREGRP97 */
2467 { "punpckldq",{ MX, EMd } },
2468 { "(bad)", { XX } },
2469 { "punpckldq",{ MX, EMx } },
2470 { "(bad)", { XX } },
2473 /* PREGRP98 */
2475 { "vmptrld",{ Mq } },
2476 { "vmxon", { Mq } },
2477 { "vmclear",{ Mq } },
2478 { "(bad)", { XX } },
2481 /* PREGRP99 */
2483 { "(bad)", { XX } },
2484 { "(bad)", { XX } },
2485 { "psrldq", { MS, Ib } },
2486 { "(bad)", { XX } },
2489 /* PREGRP100 */
2491 { "(bad)", { XX } },
2492 { "(bad)", { XX } },
2493 { "pslldq", { MS, Ib } },
2494 { "(bad)", { XX } },
2498 static const struct dis386 x86_64_table[][2] = {
2500 { "pusha{P|}", { XX } },
2501 { "(bad)", { XX } },
2504 { "popa{P|}", { XX } },
2505 { "(bad)", { XX } },
2508 { OPC_EXT_33 },
2509 { "(bad)", { XX } },
2512 { "arpl", { Ew, Gw } },
2513 { "movs{||lq|xd}", { Gv, Ed } },
2517 static const struct dis386 three_byte_table[][256] = {
2518 /* THREE_BYTE_0 */
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 } },
2809 /* THREE_BYTE_1 */
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 } },
3100 /* THREE_BYTE_SSE5_0F24 */
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 } },
3391 /* THREE_BYTE_SSE5_0F25 */
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 } },
3682 /* THREE_BYTE_SSE5_0F7A */
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 } },
3973 /* THREE_BYTE_SSE5_0F7B */
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 } },
4266 static const struct dis386 opc_ext_table[][2] = {
4268 /* OPC_EXT_0 */
4269 { "leaS", { Gv, M } },
4270 { "(bad)", { XX } },
4273 /* OPC_EXT_1 */
4274 { "les{S|}", { Gv, Mp } },
4275 { "(bad)", { XX } },
4278 /* OPC_EXT_2 */
4279 { "ldsS", { Gv, Mp } },
4280 { "(bad)", { XX } },
4283 /* OPC_EXT_3 */
4284 { "lssS", { Gv, Mp } },
4285 { "(bad)", { XX } },
4288 /* OPC_EXT_4 */
4289 { "lfsS", { Gv, Mp } },
4290 { "(bad)", { XX } },
4293 /* OPC_EXT_5 */
4294 { "lgsS", { Gv, Mp } },
4295 { "(bad)", { XX } },
4298 /* OPC_EXT_6 */
4299 { "sgdt{Q|IQ||}", { M } },
4300 { OPC_EXT_RM_0 },
4303 /* OPC_EXT_7 */
4304 { "sidt{Q|IQ||}", { M } },
4305 { OPC_EXT_RM_1 },
4308 /* OPC_EXT_8 */
4309 { "lgdt{Q|Q||}", { M } },
4310 { "(bad)", { XX } },
4313 /* OPC_EXT_9 */
4314 { PREGRP98 },
4315 { "(bad)", { XX } },
4318 /* OPC_EXT_10 */
4319 { "vmptrst", { Mq } },
4320 { "(bad)", { XX } },
4323 /* OPC_EXT_11 */
4324 { "(bad)", { XX } },
4325 { "psrlw", { MS, Ib } },
4328 /* OPC_EXT_12 */
4329 { "(bad)", { XX } },
4330 { "psraw", { MS, Ib } },
4333 /* OPC_EXT_13 */
4334 { "(bad)", { XX } },
4335 { "psllw", { MS, Ib } },
4338 /* OPC_EXT_14 */
4339 { "(bad)", { XX } },
4340 { "psrld", { MS, Ib } },
4343 /* OPC_EXT_15 */
4344 { "(bad)", { XX } },
4345 { "psrad", { MS, Ib } },
4348 /* OPC_EXT_16 */
4349 { "(bad)", { XX } },
4350 { "pslld", { MS, Ib } },
4353 /* OPC_EXT_17 */
4354 { "(bad)", { XX } },
4355 { "psrlq", { MS, Ib } },
4358 /* OPC_EXT_18 */
4359 { "(bad)", { XX } },
4360 { PREGRP99 },
4363 /* OPC_EXT_19 */
4364 { "(bad)", { XX } },
4365 { "psllq", { MS, Ib } },
4368 /* OPC_EXT_20 */
4369 { "(bad)", { XX } },
4370 { PREGRP100 },
4373 /* OPC_EXT_21 */
4374 { "fxsave", { M } },
4375 { "(bad)", { XX } },
4378 /* OPC_EXT_22 */
4379 { "fxrstor", { M } },
4380 { "(bad)", { XX } },
4383 /* OPC_EXT_23 */
4384 { "ldmxcsr", { Md } },
4385 { "(bad)", { XX } },
4388 /* OPC_EXT_24 */
4389 { "stmxcsr", { Md } },
4390 { "(bad)", { XX } },
4393 /* OPC_EXT_25 */
4394 { "(bad)", { XX } },
4395 { OPC_EXT_RM_2 },
4398 /* OPC_EXT_26 */
4399 { "(bad)", { XX } },
4400 { OPC_EXT_RM_3 },
4403 /* OPC_EXT_27 */
4404 { "clflush", { Mb } },
4405 { OPC_EXT_RM_4 },
4408 /* OPC_EXT_28 */
4409 { "prefetchnta", { Mb } },
4410 { "(bad)", { XX } },
4413 /* OPC_EXT_29 */
4414 { "prefetcht0", { Mb } },
4415 { "(bad)", { XX } },
4418 /* OPC_EXT_30 */
4419 { "prefetcht1", { Mb } },
4420 { "(bad)", { XX } },
4423 /* OPC_EXT_31 */
4424 { "prefetcht2", { Mb } },
4425 { "(bad)", { XX } },
4428 /* OPC_EXT_32 */
4429 { "lddqu", { XM, M } },
4430 { "(bad)", { XX } },
4433 /* OPC_EXT_33 */
4434 { "bound{S|}", { Gv, Ma } },
4435 { "(bad)", { XX } },
4438 /* OPC_EXT_34 */
4439 { "movlpX", { EXq, XM } },
4440 { "(bad)", { XX } },
4443 /* OPC_EXT_35 */
4444 { "movhpX", { EXq, XM } },
4445 { "(bad)", { XX } },
4448 /* OPC_EXT_36 */
4449 { "movlpX", { XM, EXq } },
4450 { "movhlpX", { XM, EXq } },
4453 /* OPC_EXT_37 */
4454 { "movhpX", { XM, EXq } },
4455 { "movlhpX", { XM, EXq } },
4458 /* OPC_EXT_38 */
4459 { "invlpg", { Mb } },
4460 { OPC_EXT_RM_5 },
4463 /* OPC_EXT_39 */
4464 { "lidt{Q|Q||}", { M } },
4465 { OPC_EXT_RM_6 },
4468 /* OPC_EXT_40 */
4469 { "(bad)", { XX } },
4470 { "movZ", { Rm, Cm } },
4473 /* OPC_EXT_41 */
4474 { "(bad)", { XX } },
4475 { "movZ", { Rm, Dm } },
4478 /* OPC_EXT_42 */
4479 { "(bad)", { XX } },
4480 { "movZ", { Cm, Rm } },
4483 /* OPC_EXT_43 */
4484 { "(bad)", { XX } },
4485 { "movZ", { Dm, Rm } },
4488 /* OPC_EXT_44 */
4489 { THREE_BYTE_SSE5_0F24 },
4490 { "movL", { Rd, Td } },
4493 /* OPC_EXT_45 */
4494 { "(bad)", { XX } },
4495 { "movL", { Td, Rd } },
4499 static const struct dis386 opc_ext_rm_table[][8] = {
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
4579 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
4581 static void
4582 ckprefix (void)
4584 int newrex;
4585 rex = 0;
4586 prefixes = 0;
4587 used_prefixes = 0;
4588 rex_used = 0;
4589 while (1)
4591 FETCH_DATA (the_info, codep + 1);
4592 newrex = 0;
4593 switch (*codep)
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)
4656 prefixes |= PREFIX_FWAIT;
4657 codep++;
4658 return;
4660 prefixes = PREFIX_FWAIT;
4661 break;
4662 default:
4663 return;
4665 /* Rex is ignored when followed by another prefix. */
4666 if (rex)
4668 rex_used = rex;
4669 return;
4671 rex = newrex;
4672 codep++;
4676 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
4677 prefix byte. */
4679 static const char *
4680 prefix_name (int pref, int sizeflag)
4682 static const char *rexes [16] =
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 */
4702 switch (pref)
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;
4754 static char op_out[MAX_OPERANDS][100];
4755 static int op_ad, op_index[MAX_OPERANDS];
4756 static int two_source_ops;
4757 static bfd_vma op_address[MAX_OPERANDS];
4758 static bfd_vma op_riprel[MAX_OPERANDS];
4759 static bfd_vma start_pc;
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.
4770 static char intel_syntax;
4771 static char open_char;
4772 static char close_char;
4773 static char separator_char;
4774 static char scale_char;
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. */
4780 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
4782 intel_syntax = 0;
4784 return print_insn (pc, info);
4788 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
4790 intel_syntax = 1;
4792 return print_insn (pc, info);
4796 print_insn_i386 (bfd_vma pc, disassemble_info *info)
4798 intel_syntax = -1;
4800 return print_insn (pc, info);
4803 void
4804 print_i386_disassembler_options (FILE *stream)
4806 fprintf (stream, _("\n\
4807 The following i386/x86-64 specific disassembler options are supported for use\n\
4808 with the -M switch (multiple options should be separated by commas):\n"));
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"));
4823 /* Get a pointer to struct dis386 with a valid name. */
4825 static const struct dis386 *
4826 get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
4828 int index;
4830 if (dp->name != NULL)
4831 return dp;
4833 switch (dp->op[0].bytemode)
4835 case USE_GROUPS:
4836 dp = &grps[dp->op[1].bytemode][modrm.reg];
4837 break;
4839 case USE_PREFIX_USER_TABLE:
4840 index = 0;
4841 used_prefixes |= (prefixes & PREFIX_REPZ);
4842 if (prefixes & PREFIX_REPZ)
4844 index = 1;
4845 repz_prefix = NULL;
4847 else
4849 /* We should check PREFIX_REPNZ and PREFIX_REPZ before
4850 PREFIX_DATA. */
4851 used_prefixes |= (prefixes & PREFIX_REPNZ);
4852 if (prefixes & PREFIX_REPNZ)
4854 index = 3;
4855 repnz_prefix = NULL;
4857 else
4859 used_prefixes |= (prefixes & PREFIX_DATA);
4860 if (prefixes & PREFIX_DATA)
4862 index = 2;
4863 data_prefix = NULL;
4867 dp = &prefix_user_table[dp->op[1].bytemode][index];
4868 break;
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;
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;
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;
4889 case USE_OPC_EXT_RM_TABLE:
4890 index = modrm.rm;
4891 dp = &opc_ext_rm_table[dp->op[1].bytemode][index];
4892 break;
4894 default:
4895 oappend (INTERNAL_DISASSEMBLER_ERROR);
4896 return NULL;
4899 if (dp->name != NULL)
4900 return dp;
4901 else
4902 return get_valid_dis386 (dp, info);
4905 static int
4906 print_insn (bfd_vma pc, disassemble_info *info)
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;
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;
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);
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 ();
4939 for (p = info->disassembler_options; p != NULL; )
4941 if (CONST_STRNEQ (p, "x86-64"))
4943 address_mode = mode_64bit;
4944 priv.orig_sizeflag = AFLAG | DFLAG;
4946 else if (CONST_STRNEQ (p, "i386"))
4948 address_mode = mode_32bit;
4949 priv.orig_sizeflag = AFLAG | DFLAG;
4951 else if (CONST_STRNEQ (p, "i8086"))
4953 address_mode = mode_16bit;
4954 priv.orig_sizeflag = 0;
4956 else if (CONST_STRNEQ (p, "intel"))
4958 intel_syntax = 1;
4960 else if (CONST_STRNEQ (p, "att"))
4962 intel_syntax = 0;
4964 else if (CONST_STRNEQ (p, "addr"))
4966 if (address_mode == mode_64bit)
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;
4973 else
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;
4981 else if (CONST_STRNEQ (p, "data"))
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;
4988 else if (CONST_STRNEQ (p, "suffix"))
4989 priv.orig_sizeflag |= SUFFIX_ALWAYS;
4991 p = strchr (p, ',');
4992 if (p != NULL)
4993 p++;
4996 if (intel_syntax)
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 = '*';
5010 else
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 = ',';
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;
5029 info->private_data = &priv;
5030 priv.max_fetched = priv.the_buffer;
5031 priv.insn_start = pc;
5033 obuf[0] = 0;
5034 for (i = 0; i < MAX_OPERANDS; ++i)
5036 op_out[i][0] = 0;
5037 op_index[i] = -1;
5040 the_info = info;
5041 start_pc = pc;
5042 start_codep = priv.the_buffer;
5043 codep = priv.the_buffer;
5045 if (setjmp (priv.bailout) != 0)
5047 const char *name;
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)
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
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]);
5064 return 1;
5067 return -1;
5070 obufp = obuf;
5071 ckprefix ();
5073 insn_codep = codep;
5074 sizeflag = priv.orig_sizeflag;
5076 FETCH_DATA (info, codep + 1);
5077 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
5079 if (((prefixes & PREFIX_FWAIT)
5080 && ((*codep < 0xd8) || (*codep > 0xdf)))
5081 || (rex && rex_used))
5083 const char *name;
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;
5094 op = 0;
5095 if (*codep == 0x0f)
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++;
5104 else
5106 dp = &dis386[*codep];
5107 need_modrm = onebyte_has_modrm[*codep];
5108 codep++;
5111 if ((prefixes & PREFIX_REPZ))
5113 repz_prefix = "repz ";
5114 used_prefixes |= PREFIX_REPZ;
5116 else
5117 repz_prefix = NULL;
5119 if ((prefixes & PREFIX_REPNZ))
5121 repnz_prefix = "repnz ";
5122 used_prefixes |= PREFIX_REPNZ;
5124 else
5125 repnz_prefix = NULL;
5127 if ((prefixes & PREFIX_LOCK))
5129 lock_prefix = "lock ";
5130 used_prefixes |= PREFIX_LOCK;
5132 else
5133 lock_prefix = NULL;
5135 addr_prefix = NULL;
5136 if (prefixes & PREFIX_ADDR)
5138 sizeflag ^= AFLAG;
5139 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
5141 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5142 addr_prefix = "addr32 ";
5143 else
5144 addr_prefix = "addr16 ";
5145 used_prefixes |= PREFIX_ADDR;
5149 data_prefix = NULL;
5150 if ((prefixes & PREFIX_DATA))
5152 sizeflag ^= DFLAG;
5153 if (dp->op[2].bytemode == cond_jump_mode
5154 && dp->op[0].bytemode == v_mode
5155 && !intel_syntax)
5157 if (sizeflag & DFLAG)
5158 data_prefix = "data32 ";
5159 else
5160 data_prefix = "data16 ";
5161 used_prefixes |= PREFIX_DATA;
5165 if (need_modrm)
5167 FETCH_DATA (info, codep + 1);
5168 modrm.mod = (*codep >> 6) & 3;
5169 modrm.reg = (*codep >> 3) & 7;
5170 modrm.rm = *codep & 7;
5173 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
5175 dofloat (sizeflag);
5177 else
5179 dp = get_valid_dis386 (dp, info);
5180 if (dp != NULL && putop (dp->name, sizeflag) == 0)
5182 for (i = 0; i < MAX_OPERANDS; ++i)
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);
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)
5198 const char *name;
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;
5206 if (rex & ~rex_used)
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);
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);
5228 if (prefix_obuf[0] != 0)
5229 (*info->fprintf_func) (info->stream, "%s", prefix_obuf);
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);
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)
5241 bfd_vma riprel;
5243 for (i = 0; i < MAX_OPERANDS; ++i)
5244 op_txt[i] = op_out[i];
5246 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
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;
5256 else
5258 for (i = 0; i < MAX_OPERANDS; ++i)
5259 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
5262 needcomma = 0;
5263 for (i = 0; i < MAX_OPERANDS; ++i)
5264 if (*op_txt[i])
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;
5275 for (i = 0; i < MAX_OPERANDS; i++)
5276 if (op_index[i] != -1 && op_riprel[i])
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;
5283 return codep - priv.the_buffer;
5286 static 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|}",
5361 static 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,
5374 d_mode,
5375 d_mode,
5377 w_mode,
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,
5395 t_mode,
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,
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
5436 #define ST { OP_ST, 0 }
5437 #define STi { OP_STi, 0 }
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 } }
5449 static const struct dis386 float_reg[][8] = {
5450 /* d8 */
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 } },
5461 /* d9 */
5463 { "fld", { STi } },
5464 { "fxch", { STi } },
5465 { FGRPd9_2 },
5466 { "(bad)", { XX } },
5467 { FGRPd9_4 },
5468 { FGRPd9_5 },
5469 { FGRPd9_6 },
5470 { FGRPd9_7 },
5472 /* da */
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 } },
5483 /* db */
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 } },
5494 /* dc */
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
5512 /* dd */
5514 { "ffree", { STi } },
5515 { "(bad)", { XX } },
5516 { "fst", { STi } },
5517 { "fstp", { STi } },
5518 { "fucom", { STi } },
5519 { "fucomp", { STi } },
5520 { "(bad)", { XX } },
5521 { "(bad)", { XX } },
5523 /* de */
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
5541 /* df */
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 } },
5554 static char *fgrps[][8] = {
5555 /* d9_2 0 */
5557 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
5560 /* d9_4 1 */
5562 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
5565 /* d9_5 2 */
5567 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
5570 /* d9_6 3 */
5572 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
5575 /* d9_7 4 */
5577 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
5580 /* da_5 5 */
5582 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
5585 /* db_4 6 */
5587 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
5588 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
5591 /* de_3 7 */
5593 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
5596 /* df_4 8 */
5598 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
5602 static void
5603 OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED,
5604 int sizeflag ATTRIBUTE_UNUSED)
5606 /* Skip mod/rm byte. */
5607 MODRM_CHECK;
5608 codep++;
5611 static void
5612 dofloat (int sizeflag)
5614 const struct dis386 *dp;
5615 unsigned char floatop;
5617 floatop = codep[-1];
5619 if (modrm.mod != 3)
5621 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
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;
5629 /* Skip mod/rm byte. */
5630 MODRM_CHECK;
5631 codep++;
5633 dp = &float_reg[floatop - 0xd8][modrm.reg];
5634 if (dp->name == NULL)
5636 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
5638 /* Instruction fnstsw is only one with strange arg. */
5639 if (floatop == 0xdf && codep[-1] == 0xe0)
5640 strcpy (op_out[0], names16[0]);
5642 else
5644 putop (dp->name, sizeflag);
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);
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);
5658 static void
5659 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5661 oappend ("%st" + intel_syntax);
5664 static void
5665 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5667 sprintf (scratchbuf, "%%st(%d)", modrm.rm);
5668 oappend (scratchbuf + intel_syntax);
5671 /* Capital letters in template are macros. */
5672 static int
5673 putop (const char *template, int sizeflag)
5675 const char *p;
5676 int alt = 0;
5678 for (p = template; *p; p++)
5680 switch (*p)
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)
5693 while (*++p != '|')
5695 if (*p == '}')
5697 /* Alternative not valid. */
5698 strcpy (obuf, "(bad)");
5699 obufp = obuf + 5;
5700 return 1;
5702 else if (*p == '\0')
5703 abort ();
5705 alt--;
5707 /* Fall through. */
5708 case 'I':
5709 alt = 1;
5710 continue;
5711 case '|':
5712 while (*++p != '}')
5714 if (*p == '\0')
5715 abort ();
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))
5737 if (sizeflag & DFLAG)
5738 *obufp++ = intel_syntax ? 'd' : 'l';
5739 else
5740 *obufp++ = intel_syntax ? 'w' : 's';
5741 used_prefixes |= (prefixes & PREFIX_DATA);
5743 break;
5744 case 'D':
5745 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
5746 break;
5747 USED_REX (REX_W);
5748 if (modrm.mod == 3)
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);
5758 else
5759 *obufp++ = 'w';
5760 break;
5761 case 'E': /* For jcxz/jecxz */
5762 if (address_mode == mode_64bit)
5764 if (sizeflag & AFLAG)
5765 *obufp++ = 'r';
5766 else
5767 *obufp++ = 'e';
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))
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);
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)
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';
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))
5828 *obufp++ = 'q';
5829 break;
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))
5860 *obufp++ = 'q';
5861 break;
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))
5871 USED_REX (REX_W);
5872 if (rex & REX_W)
5873 *obufp++ = 'q';
5874 else
5876 if (sizeflag & DFLAG)
5877 *obufp++ = 'l';
5878 else
5879 *obufp++ = 'w';
5881 used_prefixes |= (prefixes & PREFIX_DATA);
5883 break;
5884 case 'U':
5885 if (intel_syntax)
5886 break;
5887 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5889 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
5890 *obufp++ = 'q';
5891 break;
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))
5900 if (rex & REX_W)
5901 *obufp++ = 'q';
5902 else
5904 if (sizeflag & DFLAG)
5905 *obufp++ = intel_syntax ? 'd' : 'l';
5906 else
5907 *obufp++ = 'w';
5909 used_prefixes |= (prefixes & PREFIX_DATA);
5911 break;
5912 case 'R':
5913 USED_REX (REX_W);
5914 if (rex & REX_W)
5915 *obufp++ = 'q';
5916 else if (sizeflag & DFLAG)
5918 if (intel_syntax)
5919 *obufp++ = 'd';
5920 else
5921 *obufp++ = 'l';
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))
5936 if (sizeflag & SUFFIX_ALWAYS)
5937 *obufp++ = 'q';
5938 break;
5940 /* Fall through. */
5941 case 'S':
5942 if (intel_syntax)
5943 break;
5944 if (sizeflag & SUFFIX_ALWAYS)
5946 if (rex & REX_W)
5947 *obufp++ = 'q';
5948 else
5950 if (sizeflag & DFLAG)
5951 *obufp++ = 'l';
5952 else
5953 *obufp++ = 'w';
5954 used_prefixes |= (prefixes & PREFIX_DATA);
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)
5970 USED_REX (REX_W);
5971 *obufp++ = 'q';
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)
5980 if (intel_syntax)
5981 *obufp++ = 'd';
5982 else
5983 *obufp++ = 'l';
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;
5993 alt = 0;
5995 *obufp = 0;
5996 return 0;
5999 static void
6000 oappend (const char *s)
6002 strcpy (obufp, s);
6003 obufp += strlen (s);
6006 static void
6007 append_seg (void)
6009 if (prefixes & PREFIX_CS)
6011 used_prefixes |= PREFIX_CS;
6012 oappend ("%cs:" + intel_syntax);
6014 if (prefixes & PREFIX_DS)
6016 used_prefixes |= PREFIX_DS;
6017 oappend ("%ds:" + intel_syntax);
6019 if (prefixes & PREFIX_SS)
6021 used_prefixes |= PREFIX_SS;
6022 oappend ("%ss:" + intel_syntax);
6024 if (prefixes & PREFIX_ES)
6026 used_prefixes |= PREFIX_ES;
6027 oappend ("%es:" + intel_syntax);
6029 if (prefixes & PREFIX_FS)
6031 used_prefixes |= PREFIX_FS;
6032 oappend ("%fs:" + intel_syntax);
6034 if (prefixes & PREFIX_GS)
6036 used_prefixes |= PREFIX_GS;
6037 oappend ("%gs:" + intel_syntax);
6041 static void
6042 OP_indirE (int bytemode, int sizeflag)
6044 if (!intel_syntax)
6045 oappend ("*");
6046 OP_E (bytemode, sizeflag);
6049 static void
6050 print_operand_value (char *buf, int hex, bfd_vma disp)
6052 if (address_mode == mode_64bit)
6054 if (hex)
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);
6064 else
6066 bfd_signed_vma v = disp;
6067 char tmp[30];
6068 int i;
6069 if (v < 0)
6071 *(buf++) = '-';
6072 v = -disp;
6073 /* Check for possible overflow on 0x8000000000000000. */
6074 if (v < 0)
6076 strcpy (buf, "9223372036854775808");
6077 return;
6080 if (!v)
6082 strcpy (buf, "0");
6083 return;
6086 i = 0;
6087 tmp[29] = 0;
6088 while (v)
6090 tmp[28 - i] = (v % 10) + '0';
6091 v /= 10;
6092 i++;
6094 strcpy (buf, tmp + 29 - i);
6097 else
6099 if (hex)
6100 sprintf (buf, "0x%x", (unsigned int) disp);
6101 else
6102 sprintf (buf, "%d", (int) disp);
6106 /* Put DISP in BUF as signed hex number. */
6108 static void
6109 print_displacement (char *buf, bfd_vma disp)
6111 bfd_signed_vma val = disp;
6112 char tmp[30];
6113 int i, j = 0;
6115 if (val < 0)
6117 buf[j++] = '-';
6118 val = -disp;
6120 /* Check for possible overflow. */
6121 if (val < 0)
6123 switch (address_mode)
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;
6135 return;
6139 buf[j++] = '0';
6140 buf[j++] = 'x';
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);
6150 static void
6151 intel_operand_size (int bytemode, int sizeflag)
6153 switch (bytemode)
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))
6166 oappend ("QWORD PTR ");
6167 used_prefixes |= (prefixes & PREFIX_DATA);
6168 break;
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;
6223 static void
6224 OP_E_extended (int bytemode, int sizeflag, int has_drex)
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;
6233 /* Skip mod/rm byte. */
6234 MODRM_CHECK;
6235 codep++;
6237 if (modrm.mod == 3)
6239 switch (bytemode)
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))
6266 oappend (names64[modrm.rm + add]);
6267 used_prefixes |= (prefixes & PREFIX_DATA);
6268 break;
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;
6292 return;
6295 disp = 0;
6296 if (intel_syntax)
6297 intel_operand_size (bytemode, sizeflag);
6298 append_seg ();
6300 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
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;
6311 havesib = 0;
6312 havebase = 1;
6313 haveindex = 0;
6314 base = modrm.rm;
6316 if (base == 4)
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++;
6331 base += add;
6333 /* If we have a DREX byte, skip it now
6334 (it has already been handled) */
6335 if (has_drex)
6337 FETCH_DATA (the_info, codep + 1);
6338 codep++;
6341 switch (modrm.mod)
6343 case 0:
6344 if ((base & 7) == 5)
6346 havebase = 0;
6347 if (address_mode == mode_64bit && !havesib)
6348 riprel = 1;
6349 disp = get32s ();
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;
6363 havedisp = havebase || (havesib && (haveindex || scale != 0));
6365 if (!intel_syntax)
6366 if (modrm.mod != 0 || (base & 7) == 5)
6368 if (havedisp || riprel)
6369 print_displacement (scratchbuf, disp);
6370 else
6371 print_operand_value (scratchbuf, 1, disp);
6372 oappend (scratchbuf);
6373 if (riprel)
6375 set_op (disp, 1);
6376 oappend ("(%rip)");
6380 if (havedisp || (intel_syntax && riprel))
6382 *obufp++ = open_char;
6383 if (intel_syntax && riprel)
6385 set_op (disp, 1);
6386 oappend ("rip");
6388 *obufp = '\0';
6389 if (havebase)
6390 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
6391 ? names64[base] : names32[base]);
6392 if (havesib)
6394 if (haveindex)
6396 if (!intel_syntax || havebase)
6398 *obufp++ = separator_char;
6399 *obufp = '\0';
6401 oappend (address_mode == mode_64bit
6402 && (sizeflag & AFLAG)
6403 ? names64[index] : names32[index]);
6405 if (scale != 0 || haveindex)
6407 *obufp++ = scale_char;
6408 *obufp = '\0';
6409 sprintf (scratchbuf, "%d", 1 << scale);
6410 oappend (scratchbuf);
6413 if (intel_syntax
6414 && (disp || modrm.mod != 0 || (base & 7) == 5))
6416 if ((bfd_signed_vma) disp >= 0)
6418 *obufp++ = '+';
6419 *obufp = '\0';
6421 else if (modrm.mod != 1)
6423 *obufp++ = '-';
6424 *obufp = '\0';
6425 disp = - (bfd_signed_vma) disp;
6428 print_displacement (scratchbuf, disp);
6429 oappend (scratchbuf);
6432 *obufp++ = close_char;
6433 *obufp = '\0';
6435 else if (intel_syntax)
6437 if (modrm.mod != 0 || (base & 7) == 5)
6439 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
6440 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
6442 else
6444 oappend (names_seg[ds_reg - es_reg]);
6445 oappend (":");
6447 print_operand_value (scratchbuf, 1, disp);
6448 oappend (scratchbuf);
6452 else
6453 { /* 16 bit address mode */
6454 switch (modrm.mod)
6456 case 0:
6457 if (modrm.rm == 6)
6459 disp = get16 ();
6460 if ((disp & 0x8000) != 0)
6461 disp -= 0x10000;
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;
6477 if (!intel_syntax)
6478 if (modrm.mod != 0 || modrm.rm == 6)
6480 print_displacement (scratchbuf, disp);
6481 oappend (scratchbuf);
6484 if (modrm.mod != 0 || modrm.rm != 6)
6486 *obufp++ = open_char;
6487 *obufp = '\0';
6488 oappend (index16[modrm.rm]);
6489 if (intel_syntax
6490 && (disp || modrm.mod != 0 || modrm.rm == 6))
6492 if ((bfd_signed_vma) disp >= 0)
6494 *obufp++ = '+';
6495 *obufp = '\0';
6497 else if (modrm.mod != 1)
6499 *obufp++ = '-';
6500 *obufp = '\0';
6501 disp = - (bfd_signed_vma) disp;
6504 print_displacement (scratchbuf, disp);
6505 oappend (scratchbuf);
6508 *obufp++ = close_char;
6509 *obufp = '\0';
6511 else if (intel_syntax)
6513 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
6514 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
6516 else
6518 oappend (names_seg[ds_reg - es_reg]);
6519 oappend (":");
6521 print_operand_value (scratchbuf, 1, disp & 0xffff);
6522 oappend (scratchbuf);
6527 static void
6528 OP_E (int bytemode, int sizeflag)
6530 OP_E_extended (bytemode, sizeflag, 0);
6534 static void
6535 OP_G (int bytemode, int sizeflag)
6537 int add = 0;
6538 USED_REX (REX_R);
6539 if (rex & REX_R)
6540 add += 8;
6541 switch (bytemode)
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;
6585 static bfd_vma
6586 get64 (void)
6588 bfd_vma x;
6589 #ifdef BFD64
6590 unsigned int a;
6591 unsigned int b;
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;
6610 static bfd_signed_vma
6611 get32 (void)
6613 bfd_signed_vma x = 0;
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;
6623 static bfd_signed_vma
6624 get32s (void)
6626 bfd_signed_vma x = 0;
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;
6634 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
6636 return x;
6639 static int
6640 get16 (void)
6642 int x = 0;
6644 FETCH_DATA (the_info, codep + 2);
6645 x = *codep++ & 0xff;
6646 x |= (*codep++ & 0xff) << 8;
6647 return x;
6650 static void
6651 set_op (bfd_vma op, int riprel)
6653 op_index[op_ad] = op_ad;
6654 if (address_mode == mode_64bit)
6656 op_address[op_ad] = op;
6657 op_riprel[op_ad] = riprel;
6659 else
6661 /* Mask to get a 32-bit address. */
6662 op_address[op_ad] = op & 0xffffffff;
6663 op_riprel[op_ad] = riprel & 0xffffffff;
6667 static void
6668 OP_REG (int code, int sizeflag)
6670 const char *s;
6671 int add = 0;
6672 USED_REX (REX_B);
6673 if (rex & REX_B)
6674 add = 8;
6676 switch (code)
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))
6698 s = names64[code - rAX_reg + add];
6699 break;
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;
6718 oappend (s);
6721 static void
6722 OP_IMREG (int code, int sizeflag)
6724 const char *s;
6726 switch (code)
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;
6773 oappend (s);
6776 static void
6777 OP_I (int bytemode, int sizeflag)
6779 bfd_signed_vma op;
6780 bfd_signed_vma mask = -1;
6782 switch (bytemode)
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)
6792 op = get32s ();
6793 break;
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)
6802 op = get32 ();
6803 mask = 0xffffffff;
6805 else
6807 op = get16 ();
6808 mask = 0xfffff;
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;
6825 op &= mask;
6826 scratchbuf[0] = '$';
6827 print_operand_value (scratchbuf + 1, 1, op);
6828 oappend (scratchbuf + intel_syntax);
6829 scratchbuf[0] = '\0';
6832 static void
6833 OP_I64 (int bytemode, int sizeflag)
6835 bfd_signed_vma op;
6836 bfd_signed_vma mask = -1;
6838 if (address_mode != mode_64bit)
6840 OP_I (bytemode, sizeflag);
6841 return;
6844 switch (bytemode)
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)
6857 op = get32 ();
6858 mask = 0xffffffff;
6860 else
6862 op = get16 ();
6863 mask = 0xfffff;
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;
6876 op &= mask;
6877 scratchbuf[0] = '$';
6878 print_operand_value (scratchbuf + 1, 1, op);
6879 oappend (scratchbuf + intel_syntax);
6880 scratchbuf[0] = '\0';
6883 static void
6884 OP_sI (int bytemode, int sizeflag)
6886 bfd_signed_vma op;
6887 bfd_signed_vma mask = -1;
6889 switch (bytemode)
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)
6904 op = get32s ();
6905 mask = 0xffffffff;
6907 else
6909 mask = 0xffffffff;
6910 op = get16 ();
6911 if ((op & 0x8000) != 0)
6912 op -= 0x10000;
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;
6927 scratchbuf[0] = '$';
6928 print_operand_value (scratchbuf + 1, 1, op);
6929 oappend (scratchbuf + intel_syntax);
6932 static void
6933 OP_J (int bytemode, int sizeflag)
6935 bfd_vma disp;
6936 bfd_vma mask = -1;
6937 bfd_vma segment = 0;
6939 switch (bytemode)
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
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));
6964 used_prefixes |= (prefixes & PREFIX_DATA);
6965 break;
6966 default:
6967 oappend (INTERNAL_DISASSEMBLER_ERROR);
6968 return;
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);
6976 static void
6977 OP_SEG (int bytemode, int sizeflag)
6979 if (bytemode == w_mode)
6980 oappend (names_seg[modrm.reg]);
6981 else
6982 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
6985 static void
6986 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
6988 int seg, offset;
6990 if (sizeflag & DFLAG)
6992 offset = get32 ();
6993 seg = get16 ();
6995 else
6997 offset = get16 ();
6998 seg = get16 ();
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);
7008 static void
7009 OP_OFF (int bytemode, int sizeflag)
7011 bfd_vma off;
7013 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
7014 intel_operand_size (bytemode, sizeflag);
7015 append_seg ();
7017 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
7018 off = get32 ();
7019 else
7020 off = get16 ();
7022 if (intel_syntax)
7024 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
7025 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
7027 oappend (names_seg[ds_reg - es_reg]);
7028 oappend (":");
7031 print_operand_value (scratchbuf, 1, off);
7032 oappend (scratchbuf);
7035 static void
7036 OP_OFF64 (int bytemode, int sizeflag)
7038 bfd_vma off;
7040 if (address_mode != mode_64bit
7041 || (prefixes & PREFIX_ADDR))
7043 OP_OFF (bytemode, sizeflag);
7044 return;
7047 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
7048 intel_operand_size (bytemode, sizeflag);
7049 append_seg ();
7051 off = get64 ();
7053 if (intel_syntax)
7055 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
7056 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
7058 oappend (names_seg[ds_reg - es_reg]);
7059 oappend (":");
7062 print_operand_value (scratchbuf, 1, off);
7063 oappend (scratchbuf);
7066 static void
7067 ptr_reg (int code, int sizeflag)
7069 const char *s;
7071 *obufp++ = open_char;
7072 used_prefixes |= (prefixes & PREFIX_ADDR);
7073 if (address_mode == mode_64bit)
7075 if (!(sizeflag & AFLAG))
7076 s = names32[code - eAX_reg];
7077 else
7078 s = names64[code - eAX_reg];
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;
7089 static void
7090 OP_ESreg (int code, int sizeflag)
7092 if (intel_syntax)
7094 switch (codep[-1])
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);
7109 oappend ("%es:" + intel_syntax);
7110 ptr_reg (code, sizeflag);
7113 static void
7114 OP_DSreg (int code, int sizeflag)
7116 if (intel_syntax)
7118 switch (codep[-1])
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);
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);
7144 static void
7145 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7147 int add = 0;
7148 if (rex & REX_R)
7150 USED_REX (REX_R);
7151 add = 8;
7153 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
7155 lock_prefix = NULL;
7156 used_prefixes |= PREFIX_LOCK;
7157 add = 8;
7159 sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
7160 oappend (scratchbuf + intel_syntax);
7163 static void
7164 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
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);
7177 static void
7178 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7180 sprintf (scratchbuf, "%%tr%d", modrm.reg);
7181 oappend (scratchbuf + intel_syntax);
7184 static void
7185 OP_R (int bytemode, int sizeflag)
7187 if (modrm.mod == 3)
7188 OP_E (bytemode, sizeflag);
7189 else
7190 BadOp ();
7193 static void
7194 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7196 used_prefixes |= (prefixes & PREFIX_DATA);
7197 if (prefixes & PREFIX_DATA)
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);
7205 else
7206 sprintf (scratchbuf, "%%mm%d", modrm.reg);
7207 oappend (scratchbuf + intel_syntax);
7210 static void
7211 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
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);
7221 static void
7222 OP_EM (int bytemode, int sizeflag)
7224 if (modrm.mod != 3)
7226 if (intel_syntax && bytemode == v_mode)
7228 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
7229 used_prefixes |= (prefixes & PREFIX_DATA);
7231 OP_E (bytemode, sizeflag);
7232 return;
7235 /* Skip mod/rm byte. */
7236 MODRM_CHECK;
7237 codep++;
7238 used_prefixes |= (prefixes & PREFIX_DATA);
7239 if (prefixes & PREFIX_DATA)
7241 int add = 0;
7243 USED_REX (REX_B);
7244 if (rex & REX_B)
7245 add = 8;
7246 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
7248 else
7249 sprintf (scratchbuf, "%%mm%d", modrm.rm);
7250 oappend (scratchbuf + intel_syntax);
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 */
7258 static void
7259 OP_EMC (int bytemode, int sizeflag)
7261 if (modrm.mod != 3)
7263 if (intel_syntax && bytemode == v_mode)
7265 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
7266 used_prefixes |= (prefixes & PREFIX_DATA);
7268 OP_E (bytemode, sizeflag);
7269 return;
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);
7280 static void
7281 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7283 used_prefixes |= (prefixes & PREFIX_DATA);
7284 sprintf (scratchbuf, "%%mm%d", modrm.reg);
7285 oappend (scratchbuf + intel_syntax);
7288 static void
7289 OP_EX (int bytemode, int sizeflag)
7291 int add = 0;
7292 if (modrm.mod != 3)
7294 OP_E (bytemode, sizeflag);
7295 return;
7297 USED_REX (REX_B);
7298 if (rex & REX_B)
7299 add = 8;
7301 /* Skip mod/rm byte. */
7302 MODRM_CHECK;
7303 codep++;
7304 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
7305 oappend (scratchbuf + intel_syntax);
7308 static void
7309 OP_MS (int bytemode, int sizeflag)
7311 if (modrm.mod == 3)
7312 OP_EM (bytemode, sizeflag);
7313 else
7314 BadOp ();
7317 static void
7318 OP_XS (int bytemode, int sizeflag)
7320 if (modrm.mod == 3)
7321 OP_EX (bytemode, sizeflag);
7322 else
7323 BadOp ();
7326 static void
7327 OP_M (int bytemode, int sizeflag)
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);
7336 static void
7337 OP_0f07 (int bytemode, int sizeflag)
7339 if (modrm.mod != 3 || modrm.rm != 0)
7340 BadOp ();
7341 else
7342 OP_E (bytemode, sizeflag);
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. */
7348 static void
7349 NOP_Fixup1 (int bytemode, int sizeflag)
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");
7360 static void
7361 NOP_Fixup2 (int bytemode, int sizeflag)
7363 if ((prefixes & PREFIX_DATA) != 0
7364 || (rex != 0
7365 && rex != 0x48
7366 && address_mode == mode_64bit))
7367 OP_IMREG (bytemode, sizeflag);
7370 static 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,
7437 static void
7438 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7440 const char *mnemonic;
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
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 ();
7462 static const char *simd_cmp_op[] = {
7463 "eq",
7464 "lt",
7465 "le",
7466 "unord",
7467 "neq",
7468 "nlt",
7469 "nle",
7470 "ord"
7473 static void
7474 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
7476 unsigned int cmp_type;
7478 FETCH_DATA (the_info, codep + 1);
7479 obufp = obuf + strlen (obuf);
7480 cmp_type = *codep++ & 0xff;
7481 if (cmp_type < 8)
7483 char suffix1 = 'p', suffix2 = 's';
7484 used_prefixes |= (prefixes & PREFIX_REPZ);
7485 if (prefixes & PREFIX_REPZ)
7486 suffix1 = 's';
7487 else
7489 used_prefixes |= (prefixes & PREFIX_DATA);
7490 if (prefixes & PREFIX_DATA)
7491 suffix2 = 'd';
7492 else
7494 used_prefixes |= (prefixes & PREFIX_REPNZ);
7495 if (prefixes & PREFIX_REPNZ)
7496 suffix1 = 's', suffix2 = 'd';
7499 sprintf (scratchbuf, "cmp%s%c%c",
7500 simd_cmp_op[cmp_type], suffix1, suffix2);
7501 used_prefixes |= (prefixes & PREFIX_REPZ);
7502 oappend (scratchbuf);
7504 else
7506 /* We have a bad extension byte. Clean up. */
7507 op_out[0][0] = '\0';
7508 op_out[1][0] = '\0';
7509 BadOp ();
7513 static void
7514 OP_Mwait (int bytemode ATTRIBUTE_UNUSED,
7515 int sizeflag ATTRIBUTE_UNUSED)
7517 /* mwait %eax,%ecx */
7518 if (!intel_syntax)
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;
7526 /* Skip mod/rm byte. */
7527 MODRM_CHECK;
7528 codep++;
7531 static void
7532 OP_Monitor (int bytemode ATTRIBUTE_UNUSED,
7533 int sizeflag ATTRIBUTE_UNUSED)
7535 /* monitor %eax,%ecx,%edx" */
7536 if (!intel_syntax)
7538 const char **op1_names;
7539 const char **names = (address_mode == mode_64bit
7540 ? names64 : names32);
7542 if (!(prefixes & PREFIX_ADDR))
7543 op1_names = (address_mode == mode_16bit
7544 ? names16 : names);
7545 else
7547 /* Remove "addr16/addr32". */
7548 addr_prefix = NULL;
7549 op1_names = (address_mode != mode_32bit
7550 ? names32 : names16);
7551 used_prefixes |= PREFIX_ADDR;
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;
7558 /* Skip mod/rm byte. */
7559 MODRM_CHECK;
7560 codep++;
7563 static void
7564 BadOp (void)
7566 /* Throw away prefixes and 1st. opcode byte. */
7567 codep = insn_codep + 1;
7568 oappend ("(bad)");
7571 static void
7572 REP_Fixup (int bytemode, int sizeflag)
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 ";
7579 switch (bytemode)
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;
7598 static void
7599 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
7601 USED_REX (REX_W);
7602 if (rex & REX_W)
7604 /* Change cmpxchg8b to cmpxchg16b. */
7605 char *p = obuf + strlen (obuf) - 2;
7606 strcpy (p, "16b");
7607 bytemode = o_mode;
7609 OP_M (bytemode, sizeflag);
7612 static void
7613 XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
7615 sprintf (scratchbuf, "%%xmm%d", reg);
7616 oappend (scratchbuf + intel_syntax);
7619 static void
7620 CRC32_Fixup (int bytemode, int sizeflag)
7622 /* Add proper suffix to "crc32". */
7623 char *p = obuf + strlen (obuf);
7625 switch (bytemode)
7627 case b_mode:
7628 if (intel_syntax)
7629 break;
7631 *p++ = 'b';
7632 break;
7633 case v_mode:
7634 if (intel_syntax)
7635 break;
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;
7650 *p = '\0';
7652 if (modrm.mod == 3)
7654 int add;
7656 /* Skip mod/rm byte. */
7657 MODRM_CHECK;
7658 codep++;
7660 USED_REX (REX_B);
7661 add = (rex & REX_B) ? 8 : 0;
7662 if (bytemode == b_mode)
7664 USED_REX (0);
7665 if (rex)
7666 oappend (names8rex[modrm.rm + add]);
7667 else
7668 oappend (names8[modrm.rm + add]);
7670 else
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]);
7681 else
7682 OP_E (bytemode, sizeflag);
7685 /* Print a DREX argument as either a register or memory operation. */
7686 static void
7687 print_drex_arg (unsigned int reg, int bytemode, int sizeflag)
7689 if (reg == DREX_REG_UNKNOWN)
7690 BadOp ();
7692 else if (reg != DREX_REG_MEMORY)
7694 sprintf (scratchbuf, "%%xmm%d", reg);
7695 oappend (scratchbuf + intel_syntax);
7698 else
7699 OP_E_extended (bytemode, sizeflag, 1);
7702 /* SSE5 instructions that have 4 arguments are encoded as:
7703 0f 24 <sub-opcode> <modrm> <optional-sib> <drex> <offset>.
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.
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). */
7717 static void
7718 OP_DREX4 (int flag_bytemode, int sizeflag)
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;
7733 bytemode = flag_bytemode & ~ DREX_MASK;
7735 for (i = 0; i < 4; i++)
7736 regs[i] = DREX_REG_UNKNOWN;
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;
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);
7751 /* Is OC0 legal? If not, hardwire oc0 == 1. */
7752 if (flag_bytemode & DREX_NO_OC0)
7754 oc0 = 1;
7755 if (DREX_OC0 (drex_byte))
7756 BadOp ();
7758 else
7759 oc0 = DREX_OC0 (drex_byte);
7761 if (modrm.mod == 3)
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;
7769 else
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;
7779 /* Based on the OC1/OC0 bits, lay out the arguments in the correct
7780 order. */
7781 switch (oc0 + oc1)
7783 default:
7784 BadOp ();
7785 return;
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;
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;
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;
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;
7816 /* Print out the arguments. */
7817 for (i = 0; i < 4; i++)
7819 int j = (intel_syntax) ? 3 - i : i;
7820 if (i > 0)
7822 *obufp++ = ',';
7823 *obufp = '\0';
7826 print_drex_arg (regs[j], bytemode, sizeflag);
7829 rex = rex_save;
7830 rex_used = rex_used_save;
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>
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. */
7842 static void
7843 OP_DREX3 (int flag_bytemode, int sizeflag)
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;
7857 bytemode = flag_bytemode & ~ DREX_MASK;
7859 for (i = 0; i < 3; i++)
7860 regs[i] = DREX_REG_UNKNOWN;
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;
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);
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 ();
7880 if (modrm.mod == 3)
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;
7888 else
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;
7898 /* Based on the OC1/OC0 bits, lay out the arguments in the correct
7899 order. */
7900 switch (oc0)
7902 default:
7903 BadOp ();
7904 return;
7906 case 0:
7907 regs[0] = modrm_regmem;
7908 regs[1] = modrm_reg;
7909 regs[2] = drex_reg;
7910 break;
7912 case 1:
7913 regs[0] = modrm_reg;
7914 regs[1] = modrm_regmem;
7915 regs[2] = drex_reg;
7916 break;
7919 /* Print out the arguments. */
7920 for (i = 0; i < 3; i++)
7922 int j = (intel_syntax) ? 2 - i : i;
7923 if (i > 0)
7925 *obufp++ = ',';
7926 *obufp = '\0';
7929 print_drex_arg (regs[j], bytemode, sizeflag);
7932 rex = rex_save;
7933 rex_used = rex_used_save;
7936 /* Emit a floating point comparison for comp<xx> instructions. */
7938 static void
7939 OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED,
7940 int sizeflag ATTRIBUTE_UNUSED)
7942 unsigned char byte;
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"
7963 FETCH_DATA (the_info, codep + 1);
7964 byte = *codep & 0xff;
7966 if (byte >= ARRAY_SIZE (cmp_test)
7967 || obuf[0] != 'c'
7968 || obuf[1] != 'o'
7969 || obuf[2] != 'm')
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);
7976 else
7978 sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3);
7979 strcpy (obuf, scratchbuf);
7980 codep++;
7984 /* Emit an integer point comparison for pcom<xx> instructions,
7985 rewriting the instruction to have the test inside of it. */
7987 static void
7988 OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED,
7989 int sizeflag ATTRIBUTE_UNUSED)
7991 unsigned char byte;
7993 static const char *const cmp_test[] = {
7994 "lt",
7995 "le",
7996 "gt",
7997 "ge",
7998 "eq",
7999 "ne",
8000 "false",
8001 "true"
8004 FETCH_DATA (the_info, codep + 1);
8005 byte = *codep & 0xff;
8007 if (byte >= ARRAY_SIZE (cmp_test)
8008 || obuf[0] != 'p'
8009 || obuf[1] != 'c'
8010 || obuf[2] != 'o'
8011 || obuf[3] != 'm')
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);
8018 else
8020 sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4);
8021 strcpy (obuf, scratchbuf);
8022 codep++;