ld/testsuite/
[binutils.git] / opcodes / i386-dis.c
blobaa206176d68c88cee6c92e4304303f3d3f61e2f1
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 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program 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 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public 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, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 July 1988
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
34 #include "dis-asm.h"
35 #include "sysdep.h"
36 #include "opintl.h"
38 #define MAXLEN 15
40 #include <setjmp.h>
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
46 #endif
48 static int fetch_data (struct disassemble_info *, bfd_byte *);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma, disassemble_info *);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *, int, bfd_vma);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma get64 (void);
63 static bfd_signed_vma get32 (void);
64 static bfd_signed_vma get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_EMC (int,int);
89 static void OP_MXC (int,int);
90 static void OP_MS (int, int);
91 static void OP_XS (int, int);
92 static void OP_M (int, int);
93 static void OP_VMX (int, int);
94 static void OP_0fae (int, int);
95 static void OP_0f07 (int, int);
96 static void NOP_Fixup1 (int, int);
97 static void NOP_Fixup2 (int, int);
98 static void OP_3DNowSuffix (int, int);
99 static void OP_SIMD_Suffix (int, int);
100 static void SIMD_Fixup (int, int);
101 static void PNI_Fixup (int, int);
102 static void SVME_Fixup (int, int);
103 static void INVLPG_Fixup (int, int);
104 static void BadOp (void);
105 static void VMX_Fixup (int, int);
106 static void REP_Fixup (int, int);
107 static void CMPXCHG8B_Fixup (int, int);
109 struct dis_private {
110 /* Points to first byte not fetched. */
111 bfd_byte *max_fetched;
112 bfd_byte the_buffer[MAXLEN];
113 bfd_vma insn_start;
114 int orig_sizeflag;
115 jmp_buf bailout;
118 /* The opcode for the fwait instruction, which we treat as a prefix
119 when we can. */
120 #define FWAIT_OPCODE (0x9b)
122 enum address_mode
124 mode_16bit,
125 mode_32bit,
126 mode_64bit
129 enum address_mode address_mode;
131 /* Flags for the prefixes for the current instruction. See below. */
132 static int prefixes;
134 /* REX prefix the current instruction. See below. */
135 static int rex;
136 /* Bits of REX we've already used. */
137 static int rex_used;
138 #define REX_MODE64 8
139 #define REX_EXTX 4
140 #define REX_EXTY 2
141 #define REX_EXTZ 1
142 /* Mark parts used in the REX prefix. When we are testing for
143 empty prefix (for 8bit register REX extension), just mask it
144 out. Otherwise test for REX bit is excuse for existence of REX
145 only in case value is nonzero. */
146 #define USED_REX(value) \
148 if (value) \
149 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
150 else \
151 rex_used |= 0x40; \
154 /* Flags for prefixes which we somehow handled when printing the
155 current instruction. */
156 static int used_prefixes;
158 /* Flags stored in PREFIXES. */
159 #define PREFIX_REPZ 1
160 #define PREFIX_REPNZ 2
161 #define PREFIX_LOCK 4
162 #define PREFIX_CS 8
163 #define PREFIX_SS 0x10
164 #define PREFIX_DS 0x20
165 #define PREFIX_ES 0x40
166 #define PREFIX_FS 0x80
167 #define PREFIX_GS 0x100
168 #define PREFIX_DATA 0x200
169 #define PREFIX_ADDR 0x400
170 #define PREFIX_FWAIT 0x800
172 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
173 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
174 on error. */
175 #define FETCH_DATA(info, addr) \
176 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
177 ? 1 : fetch_data ((info), (addr)))
179 static int
180 fetch_data (struct disassemble_info *info, bfd_byte *addr)
182 int status;
183 struct dis_private *priv = (struct dis_private *) info->private_data;
184 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
186 if (addr <= priv->the_buffer + MAXLEN)
187 status = (*info->read_memory_func) (start,
188 priv->max_fetched,
189 addr - priv->max_fetched,
190 info);
191 else
192 status = -1;
193 if (status != 0)
195 /* If we did manage to read at least one byte, then
196 print_insn_i386 will do something sensible. Otherwise, print
197 an error. We do that here because this is where we know
198 STATUS. */
199 if (priv->max_fetched == priv->the_buffer)
200 (*info->memory_error_func) (status, start, info);
201 longjmp (priv->bailout, 1);
203 else
204 priv->max_fetched = addr;
205 return 1;
208 #define XX NULL, 0
210 #define Eb OP_E, b_mode
211 #define Ev OP_E, v_mode
212 #define Ed OP_E, d_mode
213 #define Edq OP_E, dq_mode
214 #define Edqw OP_E, dqw_mode
215 #define indirEv OP_indirE, stack_v_mode
216 #define indirEp OP_indirE, f_mode
217 #define stackEv OP_E, stack_v_mode
218 #define Em OP_E, m_mode
219 #define Ew OP_E, w_mode
220 #define M OP_M, 0 /* lea, lgdt, etc. */
221 #define Ma OP_M, v_mode
222 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
223 #define Mq OP_M, q_mode
224 #define Gb OP_G, b_mode
225 #define Gv OP_G, v_mode
226 #define Gd OP_G, d_mode
227 #define Gdq OP_G, dq_mode
228 #define Gm OP_G, m_mode
229 #define Gw OP_G, w_mode
230 #define Rd OP_Rd, d_mode
231 #define Rm OP_Rd, m_mode
232 #define Ib OP_I, b_mode
233 #define sIb OP_sI, b_mode /* sign extened byte */
234 #define Iv OP_I, v_mode
235 #define Iq OP_I, q_mode
236 #define Iv64 OP_I64, v_mode
237 #define Iw OP_I, w_mode
238 #define I1 OP_I, const_1_mode
239 #define Jb OP_J, b_mode
240 #define Jv OP_J, v_mode
241 #define Cm OP_C, m_mode
242 #define Dm OP_D, m_mode
243 #define Td OP_T, d_mode
245 #define RMeAX OP_REG, eAX_reg
246 #define RMeBX OP_REG, eBX_reg
247 #define RMeCX OP_REG, eCX_reg
248 #define RMeDX OP_REG, eDX_reg
249 #define RMeSP OP_REG, eSP_reg
250 #define RMeBP OP_REG, eBP_reg
251 #define RMeSI OP_REG, eSI_reg
252 #define RMeDI OP_REG, eDI_reg
253 #define RMrAX OP_REG, rAX_reg
254 #define RMrBX OP_REG, rBX_reg
255 #define RMrCX OP_REG, rCX_reg
256 #define RMrDX OP_REG, rDX_reg
257 #define RMrSP OP_REG, rSP_reg
258 #define RMrBP OP_REG, rBP_reg
259 #define RMrSI OP_REG, rSI_reg
260 #define RMrDI OP_REG, rDI_reg
261 #define RMAL OP_REG, al_reg
262 #define RMAL OP_REG, al_reg
263 #define RMCL OP_REG, cl_reg
264 #define RMDL OP_REG, dl_reg
265 #define RMBL OP_REG, bl_reg
266 #define RMAH OP_REG, ah_reg
267 #define RMCH OP_REG, ch_reg
268 #define RMDH OP_REG, dh_reg
269 #define RMBH OP_REG, bh_reg
270 #define RMAX OP_REG, ax_reg
271 #define RMDX OP_REG, dx_reg
273 #define eAX OP_IMREG, eAX_reg
274 #define eBX OP_IMREG, eBX_reg
275 #define eCX OP_IMREG, eCX_reg
276 #define eDX OP_IMREG, eDX_reg
277 #define eSP OP_IMREG, eSP_reg
278 #define eBP OP_IMREG, eBP_reg
279 #define eSI OP_IMREG, eSI_reg
280 #define eDI OP_IMREG, eDI_reg
281 #define AL OP_IMREG, al_reg
282 #define CL OP_IMREG, cl_reg
283 #define DL OP_IMREG, dl_reg
284 #define BL OP_IMREG, bl_reg
285 #define AH OP_IMREG, ah_reg
286 #define CH OP_IMREG, ch_reg
287 #define DH OP_IMREG, dh_reg
288 #define BH OP_IMREG, bh_reg
289 #define AX OP_IMREG, ax_reg
290 #define DX OP_IMREG, dx_reg
291 #define zAX OP_IMREG, z_mode_ax_reg
292 #define indirDX OP_IMREG, indir_dx_reg
294 #define Sw OP_SEG, w_mode
295 #define Sv OP_SEG, v_mode
296 #define Ap OP_DIR, 0
297 #define Ob OP_OFF64, b_mode
298 #define Ov OP_OFF64, v_mode
299 #define Xb OP_DSreg, eSI_reg
300 #define Xv OP_DSreg, eSI_reg
301 #define Xz OP_DSreg, eSI_reg
302 #define Yb OP_ESreg, eDI_reg
303 #define Yv OP_ESreg, eDI_reg
304 #define DSBX OP_DSreg, eBX_reg
306 #define es OP_REG, es_reg
307 #define ss OP_REG, ss_reg
308 #define cs OP_REG, cs_reg
309 #define ds OP_REG, ds_reg
310 #define fs OP_REG, fs_reg
311 #define gs OP_REG, gs_reg
313 #define MX OP_MMX, 0
314 #define XM OP_XMM, 0
315 #define EM OP_EM, v_mode
316 #define EX OP_EX, v_mode
317 #define MS OP_MS, v_mode
318 #define XS OP_XS, v_mode
319 #define EMC OP_EMC, v_mode
320 #define MXC OP_MXC, 0
321 #define VM OP_VMX, q_mode
322 #define OPSUF OP_3DNowSuffix, 0
323 #define OPSIMD OP_SIMD_Suffix, 0
325 /* Used handle "rep" prefix for string instructions. */
326 #define Xbr REP_Fixup, eSI_reg
327 #define Xvr REP_Fixup, eSI_reg
328 #define Ybr REP_Fixup, eDI_reg
329 #define Yvr REP_Fixup, eDI_reg
330 #define Yzr REP_Fixup, eDI_reg
331 #define indirDXr REP_Fixup, indir_dx_reg
332 #define ALr REP_Fixup, al_reg
333 #define eAXr REP_Fixup, eAX_reg
335 #define cond_jump_flag NULL, cond_jump_mode
336 #define loop_jcxz_flag NULL, loop_jcxz_mode
338 /* bits in sizeflag */
339 #define SUFFIX_ALWAYS 4
340 #define AFLAG 2
341 #define DFLAG 1
343 #define b_mode 1 /* byte operand */
344 #define v_mode 2 /* operand size depends on prefixes */
345 #define w_mode 3 /* word operand */
346 #define d_mode 4 /* double word operand */
347 #define q_mode 5 /* quad word operand */
348 #define t_mode 6 /* ten-byte operand */
349 #define x_mode 7 /* 16-byte XMM operand */
350 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
351 #define cond_jump_mode 9
352 #define loop_jcxz_mode 10
353 #define dq_mode 11 /* operand size depends on REX prefixes. */
354 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
355 #define f_mode 13 /* 4- or 6-byte pointer operand */
356 #define const_1_mode 14
357 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
358 #define z_mode 16 /* non-quad operand size depends on prefixes */
359 #define o_mode 17 /* 16-byte operand */
361 #define es_reg 100
362 #define cs_reg 101
363 #define ss_reg 102
364 #define ds_reg 103
365 #define fs_reg 104
366 #define gs_reg 105
368 #define eAX_reg 108
369 #define eCX_reg 109
370 #define eDX_reg 110
371 #define eBX_reg 111
372 #define eSP_reg 112
373 #define eBP_reg 113
374 #define eSI_reg 114
375 #define eDI_reg 115
377 #define al_reg 116
378 #define cl_reg 117
379 #define dl_reg 118
380 #define bl_reg 119
381 #define ah_reg 120
382 #define ch_reg 121
383 #define dh_reg 122
384 #define bh_reg 123
386 #define ax_reg 124
387 #define cx_reg 125
388 #define dx_reg 126
389 #define bx_reg 127
390 #define sp_reg 128
391 #define bp_reg 129
392 #define si_reg 130
393 #define di_reg 131
395 #define rAX_reg 132
396 #define rCX_reg 133
397 #define rDX_reg 134
398 #define rBX_reg 135
399 #define rSP_reg 136
400 #define rBP_reg 137
401 #define rSI_reg 138
402 #define rDI_reg 139
404 #define z_mode_ax_reg 149
405 #define indir_dx_reg 150
407 #define FLOATCODE 1
408 #define USE_GROUPS 2
409 #define USE_PREFIX_USER_TABLE 3
410 #define X86_64_SPECIAL 4
411 #define IS_3BYTE_OPCODE 5
413 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
415 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
416 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
417 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
418 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
419 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
420 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
421 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
422 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
423 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
424 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
425 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
426 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
427 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
428 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
429 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
430 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
431 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
432 #define GRP11_C6 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
433 #define GRP11_C7 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
434 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
435 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
436 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
437 #define GRP15 NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
438 #define GRP16 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
439 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
440 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
441 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
443 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
444 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
445 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
446 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
447 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
448 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
449 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
450 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
451 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
452 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
453 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
454 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
455 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
456 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
457 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
458 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
459 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
460 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
461 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
462 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
463 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
464 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
465 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
466 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
467 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
468 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
469 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
470 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
471 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
472 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
473 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
474 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
475 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
476 #define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
477 #define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
478 #define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
479 #define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
480 #define PREGRP37 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 37, NULL, 0, NULL, 0
483 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
484 #define X86_64_1 NULL, NULL, X86_64_SPECIAL, NULL, 1, NULL, 0, NULL, 0
485 #define X86_64_2 NULL, NULL, X86_64_SPECIAL, NULL, 2, NULL, 0, NULL, 0
486 #define X86_64_3 NULL, NULL, X86_64_SPECIAL, NULL, 3, NULL, 0, NULL, 0
488 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
489 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
491 typedef void (*op_rtn) (int bytemode, int sizeflag);
493 struct dis386 {
494 const char *name;
495 op_rtn op1;
496 int bytemode1;
497 op_rtn op2;
498 int bytemode2;
499 op_rtn op3;
500 int bytemode3;
501 op_rtn op4;
502 int bytemode4;
505 /* Upper case letters in the instruction names here are macros.
506 'A' => print 'b' if no register operands or suffix_always is true
507 'B' => print 'b' if suffix_always is true
508 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
509 . size prefix
510 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
511 . suffix_always is true
512 'E' => print 'e' if 32-bit form of jcxz
513 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
514 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
515 'H' => print ",pt" or ",pn" branch hint
516 'I' => honor following macro letter even in Intel mode (implemented only
517 . for some of the macro letters)
518 'J' => print 'l'
519 'L' => print 'l' if suffix_always is true
520 'N' => print 'n' if instruction has no wait "prefix"
521 'O' => print 'd' or 'o' (or 'q' in Intel mode)
522 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
523 . or suffix_always is true. print 'q' if rex prefix is present.
524 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
525 . is true
526 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
527 'S' => print 'w', 'l' or 'q' if suffix_always is true
528 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
529 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
530 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
531 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
532 'X' => print 's', 'd' depending on data16 prefix (for XMM)
533 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
534 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
536 Many of the above letters print nothing in Intel mode. See "putop"
537 for the details.
539 Braces '{' and '}', and vertical bars '|', indicate alternative
540 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
541 modes. In cases where there are only two alternatives, the X86_64
542 instruction is reserved, and "(bad)" is printed.
545 static const struct dis386 dis386[] = {
546 /* 00 */
547 { "addB", Eb, Gb, XX, XX },
548 { "addS", Ev, Gv, XX, XX },
549 { "addB", Gb, Eb, XX, XX },
550 { "addS", Gv, Ev, XX, XX },
551 { "addB", AL, Ib, XX, XX },
552 { "addS", eAX, Iv, XX, XX },
553 { "push{T|}", es, XX, XX, XX },
554 { "pop{T|}", es, XX, XX, XX },
555 /* 08 */
556 { "orB", Eb, Gb, XX, XX },
557 { "orS", Ev, Gv, XX, XX },
558 { "orB", Gb, Eb, XX, XX },
559 { "orS", Gv, Ev, XX, XX },
560 { "orB", AL, Ib, XX, XX },
561 { "orS", eAX, Iv, XX, XX },
562 { "push{T|}", cs, XX, XX, XX },
563 { "(bad)", XX, XX, XX, XX }, /* 0x0f extended opcode escape */
564 /* 10 */
565 { "adcB", Eb, Gb, XX, XX },
566 { "adcS", Ev, Gv, XX, XX },
567 { "adcB", Gb, Eb, XX, XX },
568 { "adcS", Gv, Ev, XX, XX },
569 { "adcB", AL, Ib, XX, XX },
570 { "adcS", eAX, Iv, XX, XX },
571 { "push{T|}", ss, XX, XX, XX },
572 { "pop{T|}", ss, XX, XX, XX },
573 /* 18 */
574 { "sbbB", Eb, Gb, XX, XX },
575 { "sbbS", Ev, Gv, XX, XX },
576 { "sbbB", Gb, Eb, XX, XX },
577 { "sbbS", Gv, Ev, XX, XX },
578 { "sbbB", AL, Ib, XX, XX },
579 { "sbbS", eAX, Iv, XX, XX },
580 { "push{T|}", ds, XX, XX, XX },
581 { "pop{T|}", ds, XX, XX, XX },
582 /* 20 */
583 { "andB", Eb, Gb, XX, XX },
584 { "andS", Ev, Gv, XX, XX },
585 { "andB", Gb, Eb, XX, XX },
586 { "andS", Gv, Ev, XX, XX },
587 { "andB", AL, Ib, XX, XX },
588 { "andS", eAX, Iv, XX, XX },
589 { "(bad)", XX, XX, XX, XX }, /* SEG ES prefix */
590 { "daa{|}", XX, XX, XX, XX },
591 /* 28 */
592 { "subB", Eb, Gb, XX, XX },
593 { "subS", Ev, Gv, XX, XX },
594 { "subB", Gb, Eb, XX, XX },
595 { "subS", Gv, Ev, XX, XX },
596 { "subB", AL, Ib, XX, XX },
597 { "subS", eAX, Iv, XX, XX },
598 { "(bad)", XX, XX, XX, XX }, /* SEG CS prefix */
599 { "das{|}", XX, XX, XX, XX },
600 /* 30 */
601 { "xorB", Eb, Gb, XX, XX },
602 { "xorS", Ev, Gv, XX, XX },
603 { "xorB", Gb, Eb, XX, XX },
604 { "xorS", Gv, Ev, XX, XX },
605 { "xorB", AL, Ib, XX, XX },
606 { "xorS", eAX, Iv, XX, XX },
607 { "(bad)", XX, XX, XX, XX }, /* SEG SS prefix */
608 { "aaa{|}", XX, XX, XX, XX },
609 /* 38 */
610 { "cmpB", Eb, Gb, XX, XX },
611 { "cmpS", Ev, Gv, XX, XX },
612 { "cmpB", Gb, Eb, XX, XX },
613 { "cmpS", Gv, Ev, XX, XX },
614 { "cmpB", AL, Ib, XX, XX },
615 { "cmpS", eAX, Iv, XX, XX },
616 { "(bad)", XX, XX, XX, XX }, /* SEG DS prefix */
617 { "aas{|}", XX, XX, XX, XX },
618 /* 40 */
619 { "inc{S|}", RMeAX, XX, XX, XX },
620 { "inc{S|}", RMeCX, XX, XX, XX },
621 { "inc{S|}", RMeDX, XX, XX, XX },
622 { "inc{S|}", RMeBX, XX, XX, XX },
623 { "inc{S|}", RMeSP, XX, XX, XX },
624 { "inc{S|}", RMeBP, XX, XX, XX },
625 { "inc{S|}", RMeSI, XX, XX, XX },
626 { "inc{S|}", RMeDI, XX, XX, XX },
627 /* 48 */
628 { "dec{S|}", RMeAX, XX, XX, XX },
629 { "dec{S|}", RMeCX, XX, XX, XX },
630 { "dec{S|}", RMeDX, XX, XX, XX },
631 { "dec{S|}", RMeBX, XX, XX, XX },
632 { "dec{S|}", RMeSP, XX, XX, XX },
633 { "dec{S|}", RMeBP, XX, XX, XX },
634 { "dec{S|}", RMeSI, XX, XX, XX },
635 { "dec{S|}", RMeDI, XX, XX, XX },
636 /* 50 */
637 { "pushV", RMrAX, XX, XX, XX },
638 { "pushV", RMrCX, XX, XX, XX },
639 { "pushV", RMrDX, XX, XX, XX },
640 { "pushV", RMrBX, XX, XX, XX },
641 { "pushV", RMrSP, XX, XX, XX },
642 { "pushV", RMrBP, XX, XX, XX },
643 { "pushV", RMrSI, XX, XX, XX },
644 { "pushV", RMrDI, XX, XX, XX },
645 /* 58 */
646 { "popV", RMrAX, XX, XX, XX },
647 { "popV", RMrCX, XX, XX, XX },
648 { "popV", RMrDX, XX, XX, XX },
649 { "popV", RMrBX, XX, XX, XX },
650 { "popV", RMrSP, XX, XX, XX },
651 { "popV", RMrBP, XX, XX, XX },
652 { "popV", RMrSI, XX, XX, XX },
653 { "popV", RMrDI, XX, XX, XX },
654 /* 60 */
655 { X86_64_0 },
656 { X86_64_1 },
657 { X86_64_2 },
658 { X86_64_3 },
659 { "(bad)", XX, XX, XX, XX }, /* seg fs */
660 { "(bad)", XX, XX, XX, XX }, /* seg gs */
661 { "(bad)", XX, XX, XX, XX }, /* op size prefix */
662 { "(bad)", XX, XX, XX, XX }, /* adr size prefix */
663 /* 68 */
664 { "pushT", Iq, XX, XX, XX },
665 { "imulS", Gv, Ev, Iv, XX },
666 { "pushT", sIb, XX, XX, XX },
667 { "imulS", Gv, Ev, sIb, XX },
668 { "ins{b||b|}", Ybr, indirDX, XX, XX },
669 { "ins{R||G|}", Yzr, indirDX, XX, XX },
670 { "outs{b||b|}", indirDXr, Xb, XX, XX },
671 { "outs{R||G|}", indirDXr, Xz, XX, XX },
672 /* 70 */
673 { "joH", Jb, XX, cond_jump_flag, XX },
674 { "jnoH", Jb, XX, cond_jump_flag, XX },
675 { "jbH", Jb, XX, cond_jump_flag, XX },
676 { "jaeH", Jb, XX, cond_jump_flag, XX },
677 { "jeH", Jb, XX, cond_jump_flag, XX },
678 { "jneH", Jb, XX, cond_jump_flag, XX },
679 { "jbeH", Jb, XX, cond_jump_flag, XX },
680 { "jaH", Jb, XX, cond_jump_flag, XX },
681 /* 78 */
682 { "jsH", Jb, XX, cond_jump_flag, XX },
683 { "jnsH", Jb, XX, cond_jump_flag, XX },
684 { "jpH", Jb, XX, cond_jump_flag, XX },
685 { "jnpH", Jb, XX, cond_jump_flag, XX },
686 { "jlH", Jb, XX, cond_jump_flag, XX },
687 { "jgeH", Jb, XX, cond_jump_flag, XX },
688 { "jleH", Jb, XX, cond_jump_flag, XX },
689 { "jgH", Jb, XX, cond_jump_flag, XX },
690 /* 80 */
691 { GRP1b },
692 { GRP1S },
693 { "(bad)", XX, XX, XX, XX },
694 { GRP1Ss },
695 { "testB", Eb, Gb, XX, XX },
696 { "testS", Ev, Gv, XX, XX },
697 { "xchgB", Eb, Gb, XX, XX },
698 { "xchgS", Ev, Gv, XX, XX },
699 /* 88 */
700 { "movB", Eb, Gb, XX, XX },
701 { "movS", Ev, Gv, XX, XX },
702 { "movB", Gb, Eb, XX, XX },
703 { "movS", Gv, Ev, XX, XX },
704 { "movD", Sv, Sw, XX, XX },
705 { "leaS", Gv, M, XX, XX },
706 { "movD", Sw, Sv, XX, XX },
707 { "popU", stackEv, XX, XX, XX },
708 /* 90 */
709 { "xchgS", NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
710 { "xchgS", RMeCX, eAX, XX, XX },
711 { "xchgS", RMeDX, eAX, XX, XX },
712 { "xchgS", RMeBX, eAX, XX, XX },
713 { "xchgS", RMeSP, eAX, XX, XX },
714 { "xchgS", RMeBP, eAX, XX, XX },
715 { "xchgS", RMeSI, eAX, XX, XX },
716 { "xchgS", RMeDI, eAX, XX, XX },
717 /* 98 */
718 { "cW{t||t|}R", XX, XX, XX, XX },
719 { "cR{t||t|}O", XX, XX, XX, XX },
720 { "Jcall{T|}", Ap, XX, XX, XX },
721 { "(bad)", XX, XX, XX, XX }, /* fwait */
722 { "pushfT", XX, XX, XX, XX },
723 { "popfT", XX, XX, XX, XX },
724 { "sahf{|}", XX, XX, XX, XX },
725 { "lahf{|}", XX, XX, XX, XX },
726 /* a0 */
727 { "movB", AL, Ob, XX, XX },
728 { "movS", eAX, Ov, XX, XX },
729 { "movB", Ob, AL, XX, XX },
730 { "movS", Ov, eAX, XX, XX },
731 { "movs{b||b|}", Ybr, Xb, XX, XX },
732 { "movs{R||R|}", Yvr, Xv, XX, XX },
733 { "cmps{b||b|}", Xb, Yb, XX, XX },
734 { "cmps{R||R|}", Xv, Yv, XX, XX },
735 /* a8 */
736 { "testB", AL, Ib, XX, XX },
737 { "testS", eAX, Iv, XX, XX },
738 { "stosB", Ybr, AL, XX, XX },
739 { "stosS", Yvr, eAX, XX, XX },
740 { "lodsB", ALr, Xb, XX, XX },
741 { "lodsS", eAXr, Xv, XX, XX },
742 { "scasB", AL, Yb, XX, XX },
743 { "scasS", eAX, Yv, XX, XX },
744 /* b0 */
745 { "movB", RMAL, Ib, XX, XX },
746 { "movB", RMCL, Ib, XX, XX },
747 { "movB", RMDL, Ib, XX, XX },
748 { "movB", RMBL, Ib, XX, XX },
749 { "movB", RMAH, Ib, XX, XX },
750 { "movB", RMCH, Ib, XX, XX },
751 { "movB", RMDH, Ib, XX, XX },
752 { "movB", RMBH, Ib, XX, XX },
753 /* b8 */
754 { "movS", RMeAX, Iv64, XX, XX },
755 { "movS", RMeCX, Iv64, XX, XX },
756 { "movS", RMeDX, Iv64, XX, XX },
757 { "movS", RMeBX, Iv64, XX, XX },
758 { "movS", RMeSP, Iv64, XX, XX },
759 { "movS", RMeBP, Iv64, XX, XX },
760 { "movS", RMeSI, Iv64, XX, XX },
761 { "movS", RMeDI, Iv64, XX, XX },
762 /* c0 */
763 { GRP2b },
764 { GRP2S },
765 { "retT", Iw, XX, XX, XX },
766 { "retT", XX, XX, XX, XX },
767 { "les{S|}", Gv, Mp, XX, XX },
768 { "ldsS", Gv, Mp, XX, XX },
769 { GRP11_C6 },
770 { GRP11_C7 },
771 /* c8 */
772 { "enterT", Iw, Ib, XX, XX },
773 { "leaveT", XX, XX, XX, XX },
774 { "lretP", Iw, XX, XX, XX },
775 { "lretP", XX, XX, XX, XX },
776 { "int3", XX, XX, XX, XX },
777 { "int", Ib, XX, XX, XX },
778 { "into{|}", XX, XX, XX, XX },
779 { "iretP", XX, XX, XX, XX },
780 /* d0 */
781 { GRP2b_one },
782 { GRP2S_one },
783 { GRP2b_cl },
784 { GRP2S_cl },
785 { "aam{|}", sIb, XX, XX, XX },
786 { "aad{|}", sIb, XX, XX, XX },
787 { "(bad)", XX, XX, XX, XX },
788 { "xlat", DSBX, XX, XX, XX },
789 /* d8 */
790 { FLOAT },
791 { FLOAT },
792 { FLOAT },
793 { FLOAT },
794 { FLOAT },
795 { FLOAT },
796 { FLOAT },
797 { FLOAT },
798 /* e0 */
799 { "loopneFH", Jb, XX, loop_jcxz_flag, XX },
800 { "loopeFH", Jb, XX, loop_jcxz_flag, XX },
801 { "loopFH", Jb, XX, loop_jcxz_flag, XX },
802 { "jEcxzH", Jb, XX, loop_jcxz_flag, XX },
803 { "inB", AL, Ib, XX, XX },
804 { "inG", zAX, Ib, XX, XX },
805 { "outB", Ib, AL, XX, XX },
806 { "outG", Ib, zAX, XX, XX },
807 /* e8 */
808 { "callT", Jv, XX, XX, XX },
809 { "jmpT", Jv, XX, XX, XX },
810 { "Jjmp{T|}", Ap, XX, XX, XX },
811 { "jmp", Jb, XX, XX, XX },
812 { "inB", AL, indirDX, XX, XX },
813 { "inG", zAX, indirDX, XX, XX },
814 { "outB", indirDX, AL, XX, XX },
815 { "outG", indirDX, zAX, XX, XX },
816 /* f0 */
817 { "(bad)", XX, XX, XX, XX }, /* lock prefix */
818 { "icebp", XX, XX, XX, XX },
819 { "(bad)", XX, XX, XX, XX }, /* repne */
820 { "(bad)", XX, XX, XX, XX }, /* repz */
821 { "hlt", XX, XX, XX, XX },
822 { "cmc", XX, XX, XX, XX },
823 { GRP3b },
824 { GRP3S },
825 /* f8 */
826 { "clc", XX, XX, XX, XX },
827 { "stc", XX, XX, XX, XX },
828 { "cli", XX, XX, XX, XX },
829 { "sti", XX, XX, XX, XX },
830 { "cld", XX, XX, XX, XX },
831 { "std", XX, XX, XX, XX },
832 { GRP4 },
833 { GRP5 },
836 static const struct dis386 dis386_twobyte[] = {
837 /* 00 */
838 { GRP6 },
839 { GRP7 },
840 { "larS", Gv, Ew, XX, XX },
841 { "lslS", Gv, Ew, XX, XX },
842 { "(bad)", XX, XX, XX, XX },
843 { "syscall", XX, XX, XX, XX },
844 { "clts", XX, XX, XX, XX },
845 { "sysretP", XX, XX, XX, XX },
846 /* 08 */
847 { "invd", XX, XX, XX, XX },
848 { "wbinvd", XX, XX, XX, XX },
849 { "(bad)", XX, XX, XX, XX },
850 { "ud2a", XX, XX, XX, XX },
851 { "(bad)", XX, XX, XX, XX },
852 { GRPAMD },
853 { "femms", XX, XX, XX, XX },
854 { "", MX, EM, OPSUF, XX }, /* See OP_3DNowSuffix. */
855 /* 10 */
856 { PREGRP8 },
857 { PREGRP9 },
858 { PREGRP30 },
859 { "movlpX", EX, XM, SIMD_Fixup, 'h', XX },
860 { "unpcklpX", XM, EX, XX, XX },
861 { "unpckhpX", XM, EX, XX, XX },
862 { PREGRP31 },
863 { "movhpX", EX, XM, SIMD_Fixup, 'l', XX },
864 /* 18 */
865 { GRP16 },
866 { "(bad)", XX, XX, XX, XX },
867 { "(bad)", XX, XX, XX, XX },
868 { "(bad)", XX, XX, XX, XX },
869 { "(bad)", XX, XX, XX, XX },
870 { "(bad)", XX, XX, XX, XX },
871 { "(bad)", XX, XX, XX, XX },
872 { "nopQ", Ev, XX, XX, XX },
873 /* 20 */
874 { "movZ", Rm, Cm, XX, XX },
875 { "movZ", Rm, Dm, XX, XX },
876 { "movZ", Cm, Rm, XX, XX },
877 { "movZ", Dm, Rm, XX, XX },
878 { "movL", Rd, Td, XX, XX },
879 { "(bad)", XX, XX, XX, XX },
880 { "movL", Td, Rd, XX, XX },
881 { "(bad)", XX, XX, XX, XX },
882 /* 28 */
883 { "movapX", XM, EX, XX, XX },
884 { "movapX", EX, XM, XX, XX },
885 { PREGRP2 },
886 { PREGRP33 },
887 { PREGRP4 },
888 { PREGRP3 },
889 { "ucomisX", XM,EX, XX, XX },
890 { "comisX", XM,EX, XX, XX },
891 /* 30 */
892 { "wrmsr", XX, XX, XX, XX },
893 { "rdtsc", XX, XX, XX, XX },
894 { "rdmsr", XX, XX, XX, XX },
895 { "rdpmc", XX, XX, XX, XX },
896 { "sysenter", XX, XX, XX, XX },
897 { "sysexit", XX, XX, XX, XX },
898 { "(bad)", XX, XX, XX, XX },
899 { "(bad)", XX, XX, XX, XX },
900 /* 38 */
901 { THREE_BYTE_0 },
902 { "(bad)", XX, XX, XX, XX },
903 { THREE_BYTE_1 },
904 { "(bad)", XX, XX, XX, XX },
905 { "(bad)", XX, XX, XX, XX },
906 { "(bad)", XX, XX, XX, XX },
907 { "(bad)", XX, XX, XX, XX },
908 { "(bad)", XX, XX, XX, XX },
909 /* 40 */
910 { "cmovo", Gv, Ev, XX, XX },
911 { "cmovno", Gv, Ev, XX, XX },
912 { "cmovb", Gv, Ev, XX, XX },
913 { "cmovae", Gv, Ev, XX, XX },
914 { "cmove", Gv, Ev, XX, XX },
915 { "cmovne", Gv, Ev, XX, XX },
916 { "cmovbe", Gv, Ev, XX, XX },
917 { "cmova", Gv, Ev, XX, XX },
918 /* 48 */
919 { "cmovs", Gv, Ev, XX, XX },
920 { "cmovns", Gv, Ev, XX, XX },
921 { "cmovp", Gv, Ev, XX, XX },
922 { "cmovnp", Gv, Ev, XX, XX },
923 { "cmovl", Gv, Ev, XX, XX },
924 { "cmovge", Gv, Ev, XX, XX },
925 { "cmovle", Gv, Ev, XX, XX },
926 { "cmovg", Gv, Ev, XX, XX },
927 /* 50 */
928 { "movmskpX", Gdq, XS, XX, XX },
929 { PREGRP13 },
930 { PREGRP12 },
931 { PREGRP11 },
932 { "andpX", XM, EX, XX, XX },
933 { "andnpX", XM, EX, XX, XX },
934 { "orpX", XM, EX, XX, XX },
935 { "xorpX", XM, EX, XX, XX },
936 /* 58 */
937 { PREGRP0 },
938 { PREGRP10 },
939 { PREGRP17 },
940 { PREGRP16 },
941 { PREGRP14 },
942 { PREGRP7 },
943 { PREGRP5 },
944 { PREGRP6 },
945 /* 60 */
946 { "punpcklbw", MX, EM, XX, XX },
947 { "punpcklwd", MX, EM, XX, XX },
948 { "punpckldq", MX, EM, XX, XX },
949 { "packsswb", MX, EM, XX, XX },
950 { "pcmpgtb", MX, EM, XX, XX },
951 { "pcmpgtw", MX, EM, XX, XX },
952 { "pcmpgtd", MX, EM, XX, XX },
953 { "packuswb", MX, EM, XX, XX },
954 /* 68 */
955 { "punpckhbw", MX, EM, XX, XX },
956 { "punpckhwd", MX, EM, XX, XX },
957 { "punpckhdq", MX, EM, XX, XX },
958 { "packssdw", MX, EM, XX, XX },
959 { PREGRP26 },
960 { PREGRP24 },
961 { "movd", MX, Edq, XX, XX },
962 { PREGRP19 },
963 /* 70 */
964 { PREGRP22 },
965 { GRP12 },
966 { GRP13 },
967 { GRP14 },
968 { "pcmpeqb", MX, EM, XX, XX },
969 { "pcmpeqw", MX, EM, XX, XX },
970 { "pcmpeqd", MX, EM, XX, XX },
971 { "emms", XX, XX, XX, XX },
972 /* 78 */
973 { PREGRP34 },
974 { PREGRP35 },
975 { "(bad)", XX, XX, XX, XX },
976 { "(bad)", XX, XX, XX, XX },
977 { PREGRP28 },
978 { PREGRP29 },
979 { PREGRP23 },
980 { PREGRP20 },
981 /* 80 */
982 { "joH", Jv, XX, cond_jump_flag, XX },
983 { "jnoH", Jv, XX, cond_jump_flag, XX },
984 { "jbH", Jv, XX, cond_jump_flag, XX },
985 { "jaeH", Jv, XX, cond_jump_flag, XX },
986 { "jeH", Jv, XX, cond_jump_flag, XX },
987 { "jneH", Jv, XX, cond_jump_flag, XX },
988 { "jbeH", Jv, XX, cond_jump_flag, XX },
989 { "jaH", Jv, XX, cond_jump_flag, XX },
990 /* 88 */
991 { "jsH", Jv, XX, cond_jump_flag, XX },
992 { "jnsH", Jv, XX, cond_jump_flag, XX },
993 { "jpH", Jv, XX, cond_jump_flag, XX },
994 { "jnpH", Jv, XX, cond_jump_flag, XX },
995 { "jlH", Jv, XX, cond_jump_flag, XX },
996 { "jgeH", Jv, XX, cond_jump_flag, XX },
997 { "jleH", Jv, XX, cond_jump_flag, XX },
998 { "jgH", Jv, XX, cond_jump_flag, XX },
999 /* 90 */
1000 { "seto", Eb, XX, XX, XX },
1001 { "setno", Eb, XX, XX, XX },
1002 { "setb", Eb, XX, XX, XX },
1003 { "setae", Eb, XX, XX, XX },
1004 { "sete", Eb, XX, XX, XX },
1005 { "setne", Eb, XX, XX, XX },
1006 { "setbe", Eb, XX, XX, XX },
1007 { "seta", Eb, XX, XX, XX },
1008 /* 98 */
1009 { "sets", Eb, XX, XX, XX },
1010 { "setns", Eb, XX, XX, XX },
1011 { "setp", Eb, XX, XX, XX },
1012 { "setnp", Eb, XX, XX, XX },
1013 { "setl", Eb, XX, XX, XX },
1014 { "setge", Eb, XX, XX, XX },
1015 { "setle", Eb, XX, XX, XX },
1016 { "setg", Eb, XX, XX, XX },
1017 /* a0 */
1018 { "pushT", fs, XX, XX, XX },
1019 { "popT", fs, XX, XX, XX },
1020 { "cpuid", XX, XX, XX, XX },
1021 { "btS", Ev, Gv, XX, XX },
1022 { "shldS", Ev, Gv, Ib, XX },
1023 { "shldS", Ev, Gv, CL, XX },
1024 { GRPPADLCK2 },
1025 { GRPPADLCK1 },
1026 /* a8 */
1027 { "pushT", gs, XX, XX, XX },
1028 { "popT", gs, XX, XX, XX },
1029 { "rsm", XX, XX, XX, XX },
1030 { "btsS", Ev, Gv, XX, XX },
1031 { "shrdS", Ev, Gv, Ib, XX },
1032 { "shrdS", Ev, Gv, CL, XX },
1033 { GRP15 },
1034 { "imulS", Gv, Ev, XX, XX },
1035 /* b0 */
1036 { "cmpxchgB", Eb, Gb, XX, XX },
1037 { "cmpxchgS", Ev, Gv, XX, XX },
1038 { "lssS", Gv, Mp, XX, XX },
1039 { "btrS", Ev, Gv, XX, XX },
1040 { "lfsS", Gv, Mp, XX, XX },
1041 { "lgsS", Gv, Mp, XX, XX },
1042 { "movz{bR|x|bR|x}", Gv, Eb, XX, XX },
1043 { "movz{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movzww ! */
1044 /* b8 */
1045 { PREGRP37 },
1046 { "ud2b", XX, XX, XX, XX },
1047 { GRP8 },
1048 { "btcS", Ev, Gv, XX, XX },
1049 { "bsfS", Gv, Ev, XX, XX },
1050 { PREGRP36 },
1051 { "movs{bR|x|bR|x}", Gv, Eb, XX, XX },
1052 { "movs{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movsww ! */
1053 /* c0 */
1054 { "xaddB", Eb, Gb, XX, XX },
1055 { "xaddS", Ev, Gv, XX, XX },
1056 { PREGRP1 },
1057 { "movntiS", Ev, Gv, XX, XX },
1058 { "pinsrw", MX, Edqw, Ib, XX },
1059 { "pextrw", Gdq, MS, Ib, XX },
1060 { "shufpX", XM, EX, Ib, XX },
1061 { GRP9 },
1062 /* c8 */
1063 { "bswap", RMeAX, XX, XX, XX },
1064 { "bswap", RMeCX, XX, XX, XX },
1065 { "bswap", RMeDX, XX, XX, XX },
1066 { "bswap", RMeBX, XX, XX, XX },
1067 { "bswap", RMeSP, XX, XX, XX },
1068 { "bswap", RMeBP, XX, XX, XX },
1069 { "bswap", RMeSI, XX, XX, XX },
1070 { "bswap", RMeDI, XX, XX, XX },
1071 /* d0 */
1072 { PREGRP27 },
1073 { "psrlw", MX, EM, XX, XX },
1074 { "psrld", MX, EM, XX, XX },
1075 { "psrlq", MX, EM, XX, XX },
1076 { "paddq", MX, EM, XX, XX },
1077 { "pmullw", MX, EM, XX, XX },
1078 { PREGRP21 },
1079 { "pmovmskb", Gdq, MS, XX, XX },
1080 /* d8 */
1081 { "psubusb", MX, EM, XX, XX },
1082 { "psubusw", MX, EM, XX, XX },
1083 { "pminub", MX, EM, XX, XX },
1084 { "pand", MX, EM, XX, XX },
1085 { "paddusb", MX, EM, XX, XX },
1086 { "paddusw", MX, EM, XX, XX },
1087 { "pmaxub", MX, EM, XX, XX },
1088 { "pandn", MX, EM, XX, XX },
1089 /* e0 */
1090 { "pavgb", MX, EM, XX, XX },
1091 { "psraw", MX, EM, XX, XX },
1092 { "psrad", MX, EM, XX, XX },
1093 { "pavgw", MX, EM, XX, XX },
1094 { "pmulhuw", MX, EM, XX, XX },
1095 { "pmulhw", MX, EM, XX, XX },
1096 { PREGRP15 },
1097 { PREGRP25 },
1098 /* e8 */
1099 { "psubsb", MX, EM, XX, XX },
1100 { "psubsw", MX, EM, XX, XX },
1101 { "pminsw", MX, EM, XX, XX },
1102 { "por", MX, EM, XX, XX },
1103 { "paddsb", MX, EM, XX, XX },
1104 { "paddsw", MX, EM, XX, XX },
1105 { "pmaxsw", MX, EM, XX, XX },
1106 { "pxor", MX, EM, XX, XX },
1107 /* f0 */
1108 { PREGRP32 },
1109 { "psllw", MX, EM, XX, XX },
1110 { "pslld", MX, EM, XX, XX },
1111 { "psllq", MX, EM, XX, XX },
1112 { "pmuludq", MX, EM, XX, XX },
1113 { "pmaddwd", MX, EM, XX, XX },
1114 { "psadbw", MX, EM, XX, XX },
1115 { PREGRP18 },
1116 /* f8 */
1117 { "psubb", MX, EM, XX, XX },
1118 { "psubw", MX, EM, XX, XX },
1119 { "psubd", MX, EM, XX, XX },
1120 { "psubq", MX, EM, XX, XX },
1121 { "paddb", MX, EM, XX, XX },
1122 { "paddw", MX, EM, XX, XX },
1123 { "paddd", MX, EM, XX, XX },
1124 { "(bad)", XX, XX, XX, XX }
1127 static const unsigned char onebyte_has_modrm[256] = {
1128 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1129 /* ------------------------------- */
1130 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1131 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1132 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1133 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1134 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1135 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1136 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1137 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1138 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1139 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1140 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1141 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1142 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1143 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1144 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1145 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1146 /* ------------------------------- */
1147 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1150 static const unsigned char twobyte_has_modrm[256] = {
1151 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1152 /* ------------------------------- */
1153 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1154 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1155 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1156 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1157 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1158 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1159 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1160 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1161 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1162 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1163 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1164 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1165 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1166 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1167 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1168 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1169 /* ------------------------------- */
1170 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1173 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1174 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1175 /* ------------------------------- */
1176 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1177 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1178 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1179 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1180 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1181 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1182 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1183 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1184 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1185 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1186 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1187 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1188 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1189 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1190 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1191 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1192 /* ------------------------------- */
1193 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1196 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1197 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1198 /* ------------------------------- */
1199 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1200 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1201 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1202 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1203 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1204 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1205 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1206 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1207 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1208 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1209 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1210 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1211 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1212 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1213 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1214 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1215 /* ------------------------------- */
1216 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1219 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1220 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1221 /* ------------------------------- */
1222 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1223 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1224 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1225 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1226 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1227 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1228 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1229 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1230 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1231 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1232 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1233 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1234 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1235 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1236 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1237 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1238 /* ------------------------------- */
1239 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1242 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1243 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1244 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1245 /* ------------------------------- */
1246 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1247 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1248 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1249 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1250 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1251 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1252 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1253 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1254 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1255 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1256 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1257 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1258 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1259 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1260 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1261 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1262 /* ------------------------------- */
1263 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1266 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1267 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1268 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1269 /* ------------------------------- */
1270 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1271 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1272 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1273 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1274 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1275 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1276 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1277 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1278 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1279 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1280 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1281 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1282 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1283 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1284 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1285 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1286 /* ------------------------------- */
1287 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1290 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1291 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1292 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1293 /* ------------------------------- */
1294 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1295 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1296 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1297 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1298 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1299 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1300 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1301 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1302 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1303 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1304 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1305 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1306 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1307 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1308 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1309 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1310 /* ------------------------------- */
1311 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1314 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1315 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1316 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1317 /* ------------------------------- */
1318 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1319 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1320 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1321 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1322 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1323 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1324 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1325 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1326 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1327 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1328 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1329 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1330 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1331 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1332 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1333 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1334 /* ------------------------------- */
1335 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1338 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1339 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1340 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1341 /* ------------------------------- */
1342 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1343 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1344 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1345 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1346 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1347 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1348 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1349 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1350 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1351 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1352 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1353 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1354 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1355 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1356 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1357 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1358 /* ------------------------------- */
1359 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1362 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1363 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1364 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1365 /* ------------------------------- */
1366 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1367 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1368 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1369 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1370 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1371 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1372 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1373 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1374 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1375 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1376 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1377 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1378 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1379 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1380 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1381 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1382 /* ------------------------------- */
1383 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1386 static char obuf[100];
1387 static char *obufp;
1388 static char scratchbuf[100];
1389 static unsigned char *start_codep;
1390 static unsigned char *insn_codep;
1391 static unsigned char *codep;
1392 static disassemble_info *the_info;
1393 static int mod;
1394 static int rm;
1395 static int reg;
1396 static unsigned char need_modrm;
1398 /* If we are accessing mod/rm/reg without need_modrm set, then the
1399 values are stale. Hitting this abort likely indicates that you
1400 need to update onebyte_has_modrm or twobyte_has_modrm. */
1401 #define MODRM_CHECK if (!need_modrm) abort ()
1403 static const char **names64;
1404 static const char **names32;
1405 static const char **names16;
1406 static const char **names8;
1407 static const char **names8rex;
1408 static const char **names_seg;
1409 static const char **index16;
1411 static const char *intel_names64[] = {
1412 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1413 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1415 static const char *intel_names32[] = {
1416 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1417 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1419 static const char *intel_names16[] = {
1420 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1421 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1423 static const char *intel_names8[] = {
1424 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1426 static const char *intel_names8rex[] = {
1427 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1428 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1430 static const char *intel_names_seg[] = {
1431 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1433 static const char *intel_index16[] = {
1434 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1437 static const char *att_names64[] = {
1438 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1439 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1441 static const char *att_names32[] = {
1442 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1443 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1445 static const char *att_names16[] = {
1446 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1447 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1449 static const char *att_names8[] = {
1450 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1452 static const char *att_names8rex[] = {
1453 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1454 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1456 static const char *att_names_seg[] = {
1457 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1459 static const char *att_index16[] = {
1460 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1463 static const struct dis386 grps[][8] = {
1464 /* GRP1b */
1466 { "addA", Eb, Ib, XX, XX },
1467 { "orA", Eb, Ib, XX, XX },
1468 { "adcA", Eb, Ib, XX, XX },
1469 { "sbbA", Eb, Ib, XX, XX },
1470 { "andA", Eb, Ib, XX, XX },
1471 { "subA", Eb, Ib, XX, XX },
1472 { "xorA", Eb, Ib, XX, XX },
1473 { "cmpA", Eb, Ib, XX, XX }
1475 /* GRP1S */
1477 { "addQ", Ev, Iv, XX, XX },
1478 { "orQ", Ev, Iv, XX, XX },
1479 { "adcQ", Ev, Iv, XX, XX },
1480 { "sbbQ", Ev, Iv, XX, XX },
1481 { "andQ", Ev, Iv, XX, XX },
1482 { "subQ", Ev, Iv, XX, XX },
1483 { "xorQ", Ev, Iv, XX, XX },
1484 { "cmpQ", Ev, Iv, XX, XX }
1486 /* GRP1Ss */
1488 { "addQ", Ev, sIb, XX, XX },
1489 { "orQ", Ev, sIb, XX, XX },
1490 { "adcQ", Ev, sIb, XX, XX },
1491 { "sbbQ", Ev, sIb, XX, XX },
1492 { "andQ", Ev, sIb, XX, XX },
1493 { "subQ", Ev, sIb, XX, XX },
1494 { "xorQ", Ev, sIb, XX, XX },
1495 { "cmpQ", Ev, sIb, XX, XX }
1497 /* GRP2b */
1499 { "rolA", Eb, Ib, XX, XX },
1500 { "rorA", Eb, Ib, XX, XX },
1501 { "rclA", Eb, Ib, XX, XX },
1502 { "rcrA", Eb, Ib, XX, XX },
1503 { "shlA", Eb, Ib, XX, XX },
1504 { "shrA", Eb, Ib, XX, XX },
1505 { "(bad)", XX, XX, XX, XX },
1506 { "sarA", Eb, Ib, XX, XX },
1508 /* GRP2S */
1510 { "rolQ", Ev, Ib, XX, XX },
1511 { "rorQ", Ev, Ib, XX, XX },
1512 { "rclQ", Ev, Ib, XX, XX },
1513 { "rcrQ", Ev, Ib, XX, XX },
1514 { "shlQ", Ev, Ib, XX, XX },
1515 { "shrQ", Ev, Ib, XX, XX },
1516 { "(bad)", XX, XX, XX, XX },
1517 { "sarQ", Ev, Ib, XX, XX },
1519 /* GRP2b_one */
1521 { "rolA", Eb, I1, XX, XX },
1522 { "rorA", Eb, I1, XX, XX },
1523 { "rclA", Eb, I1, XX, XX },
1524 { "rcrA", Eb, I1, XX, XX },
1525 { "shlA", Eb, I1, XX, XX },
1526 { "shrA", Eb, I1, XX, XX },
1527 { "(bad)", XX, XX, XX, XX },
1528 { "sarA", Eb, I1, XX, XX },
1530 /* GRP2S_one */
1532 { "rolQ", Ev, I1, XX, XX },
1533 { "rorQ", Ev, I1, XX, XX },
1534 { "rclQ", Ev, I1, XX, XX },
1535 { "rcrQ", Ev, I1, XX, XX },
1536 { "shlQ", Ev, I1, XX, XX },
1537 { "shrQ", Ev, I1, XX, XX },
1538 { "(bad)", XX, XX, XX, XX },
1539 { "sarQ", Ev, I1, XX, XX },
1541 /* GRP2b_cl */
1543 { "rolA", Eb, CL, XX, XX },
1544 { "rorA", Eb, CL, XX, XX },
1545 { "rclA", Eb, CL, XX, XX },
1546 { "rcrA", Eb, CL, XX, XX },
1547 { "shlA", Eb, CL, XX, XX },
1548 { "shrA", Eb, CL, XX, XX },
1549 { "(bad)", XX, XX, XX, XX },
1550 { "sarA", Eb, CL, XX, XX },
1552 /* GRP2S_cl */
1554 { "rolQ", Ev, CL, XX, XX },
1555 { "rorQ", Ev, CL, XX, XX },
1556 { "rclQ", Ev, CL, XX, XX },
1557 { "rcrQ", Ev, CL, XX, XX },
1558 { "shlQ", Ev, CL, XX, XX },
1559 { "shrQ", Ev, CL, XX, XX },
1560 { "(bad)", XX, XX, XX, XX },
1561 { "sarQ", Ev, CL, XX, XX }
1563 /* GRP3b */
1565 { "testA", Eb, Ib, XX, XX },
1566 { "(bad)", Eb, XX, XX, XX },
1567 { "notA", Eb, XX, XX, XX },
1568 { "negA", Eb, XX, XX, XX },
1569 { "mulA", Eb, XX, XX, XX }, /* Don't print the implicit %al register, */
1570 { "imulA", Eb, XX, XX, XX }, /* to distinguish these opcodes from other */
1571 { "divA", Eb, XX, XX, XX }, /* mul/imul opcodes. Do the same for div */
1572 { "idivA", Eb, XX, XX, XX } /* and idiv for consistency. */
1574 /* GRP3S */
1576 { "testQ", Ev, Iv, XX, XX },
1577 { "(bad)", XX, XX, XX, XX },
1578 { "notQ", Ev, XX, XX, XX },
1579 { "negQ", Ev, XX, XX, XX },
1580 { "mulQ", Ev, XX, XX, XX }, /* Don't print the implicit register. */
1581 { "imulQ", Ev, XX, XX, XX },
1582 { "divQ", Ev, XX, XX, XX },
1583 { "idivQ", Ev, XX, XX, XX },
1585 /* GRP4 */
1587 { "incA", Eb, XX, XX, XX },
1588 { "decA", Eb, XX, XX, XX },
1589 { "(bad)", XX, XX, XX, XX },
1590 { "(bad)", XX, XX, XX, XX },
1591 { "(bad)", XX, XX, XX, XX },
1592 { "(bad)", XX, XX, XX, XX },
1593 { "(bad)", XX, XX, XX, XX },
1594 { "(bad)", XX, XX, XX, XX },
1596 /* GRP5 */
1598 { "incQ", Ev, XX, XX, XX },
1599 { "decQ", Ev, XX, XX, XX },
1600 { "callT", indirEv, XX, XX, XX },
1601 { "JcallT", indirEp, XX, XX, XX },
1602 { "jmpT", indirEv, XX, XX, XX },
1603 { "JjmpT", indirEp, XX, XX, XX },
1604 { "pushU", stackEv, XX, XX, XX },
1605 { "(bad)", XX, XX, XX, XX },
1607 /* GRP6 */
1609 { "sldtD", Sv, XX, XX, XX },
1610 { "strD", Sv, XX, XX, XX },
1611 { "lldt", Ew, XX, XX, XX },
1612 { "ltr", Ew, XX, XX, XX },
1613 { "verr", Ew, XX, XX, XX },
1614 { "verw", Ew, XX, XX, XX },
1615 { "(bad)", XX, XX, XX, XX },
1616 { "(bad)", XX, XX, XX, XX }
1618 /* GRP7 */
1620 { "sgdt{Q|IQ||}", VMX_Fixup, 0, XX, XX, XX },
1621 { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
1622 { "lgdt{Q|Q||}", M, XX, XX, XX },
1623 { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX, XX },
1624 { "smswD", Sv, XX, XX, XX },
1625 { "(bad)", XX, XX, XX, XX },
1626 { "lmsw", Ew, XX, XX, XX },
1627 { "invlpg", INVLPG_Fixup, w_mode, XX, XX, XX },
1629 /* GRP8 */
1631 { "(bad)", XX, XX, XX, XX },
1632 { "(bad)", XX, XX, XX, XX },
1633 { "(bad)", XX, XX, XX, XX },
1634 { "(bad)", XX, XX, XX, XX },
1635 { "btQ", Ev, Ib, XX, XX },
1636 { "btsQ", Ev, Ib, XX, XX },
1637 { "btrQ", Ev, Ib, XX, XX },
1638 { "btcQ", Ev, Ib, XX, XX },
1640 /* GRP9 */
1642 { "(bad)", XX, XX, XX, XX },
1643 { "cmpxchg8b", CMPXCHG8B_Fixup, q_mode, XX, XX, XX },
1644 { "(bad)", XX, XX, XX, XX },
1645 { "(bad)", XX, XX, XX, XX },
1646 { "(bad)", XX, XX, XX, XX },
1647 { "(bad)", XX, XX, XX, XX },
1648 { "", VM, XX, XX, XX }, /* See OP_VMX. */
1649 { "vmptrst", Mq, XX, XX, XX },
1651 /* GRP11_C6 */
1653 { "movA", Eb, Ib, XX, XX },
1654 { "(bad)", XX, XX, XX, XX },
1655 { "(bad)", XX, XX, XX, XX },
1656 { "(bad)", XX, XX, XX, XX },
1657 { "(bad)", XX, XX, XX, XX },
1658 { "(bad)", XX, XX, XX, XX },
1659 { "(bad)", XX, XX, XX, XX },
1660 { "(bad)", XX, XX, XX, XX },
1662 /* GRP11_C7 */
1664 { "movQ", Ev, Iv, XX, XX },
1665 { "(bad)", XX, XX, XX, XX },
1666 { "(bad)", XX, XX, XX, XX },
1667 { "(bad)", XX, XX, XX, XX },
1668 { "(bad)", XX, XX, XX, XX },
1669 { "(bad)", XX, XX, XX, XX },
1670 { "(bad)", XX, XX, XX, XX },
1671 { "(bad)", XX, XX, XX, XX },
1673 /* GRP12 */
1675 { "(bad)", XX, XX, XX, XX },
1676 { "(bad)", XX, XX, XX, XX },
1677 { "psrlw", MS, Ib, XX, XX },
1678 { "(bad)", XX, XX, XX, XX },
1679 { "psraw", MS, Ib, XX, XX },
1680 { "(bad)", XX, XX, XX, XX },
1681 { "psllw", MS, Ib, XX, XX },
1682 { "(bad)", XX, XX, XX, XX },
1684 /* GRP13 */
1686 { "(bad)", XX, XX, XX, XX },
1687 { "(bad)", XX, XX, XX, XX },
1688 { "psrld", MS, Ib, XX, XX },
1689 { "(bad)", XX, XX, XX, XX },
1690 { "psrad", MS, Ib, XX, XX },
1691 { "(bad)", XX, XX, XX, XX },
1692 { "pslld", MS, Ib, XX, XX },
1693 { "(bad)", XX, XX, XX, XX },
1695 /* GRP14 */
1697 { "(bad)", XX, XX, XX, XX },
1698 { "(bad)", XX, XX, XX, XX },
1699 { "psrlq", MS, Ib, XX, XX },
1700 { "psrldq", MS, Ib, XX, XX },
1701 { "(bad)", XX, XX, XX, XX },
1702 { "(bad)", XX, XX, XX, XX },
1703 { "psllq", MS, Ib, XX, XX },
1704 { "pslldq", MS, Ib, XX, XX },
1706 /* GRP15 */
1708 { "fxsave", Ev, XX, XX, XX },
1709 { "fxrstor", Ev, XX, XX, XX },
1710 { "ldmxcsr", Ev, XX, XX, XX },
1711 { "stmxcsr", Ev, XX, XX, XX },
1712 { "(bad)", XX, XX, XX, XX },
1713 { "lfence", OP_0fae, 0, XX, XX, XX },
1714 { "mfence", OP_0fae, 0, XX, XX, XX },
1715 { "clflush", OP_0fae, 0, XX, XX, XX },
1717 /* GRP16 */
1719 { "prefetchnta", Ev, XX, XX, XX },
1720 { "prefetcht0", Ev, XX, XX, XX },
1721 { "prefetcht1", Ev, XX, XX, XX },
1722 { "prefetcht2", Ev, XX, XX, XX },
1723 { "(bad)", XX, XX, XX, XX },
1724 { "(bad)", XX, XX, XX, XX },
1725 { "(bad)", XX, XX, XX, XX },
1726 { "(bad)", XX, XX, XX, XX },
1728 /* GRPAMD */
1730 { "prefetch", Eb, XX, XX, XX },
1731 { "prefetchw", Eb, XX, XX, XX },
1732 { "(bad)", XX, XX, XX, XX },
1733 { "(bad)", XX, XX, XX, XX },
1734 { "(bad)", XX, XX, XX, XX },
1735 { "(bad)", XX, XX, XX, XX },
1736 { "(bad)", XX, XX, XX, XX },
1737 { "(bad)", XX, XX, XX, XX },
1739 /* GRPPADLCK1 */
1741 { "xstore-rng", OP_0f07, 0, XX, XX, XX },
1742 { "xcrypt-ecb", OP_0f07, 0, XX, XX, XX },
1743 { "xcrypt-cbc", OP_0f07, 0, XX, XX, XX },
1744 { "xcrypt-ctr", OP_0f07, 0, XX, XX, XX },
1745 { "xcrypt-cfb", OP_0f07, 0, XX, XX, XX },
1746 { "xcrypt-ofb", OP_0f07, 0, XX, XX, XX },
1747 { "(bad)", OP_0f07, 0, XX, XX, XX },
1748 { "(bad)", OP_0f07, 0, XX, XX, XX },
1750 /* GRPPADLCK2 */
1752 { "montmul", OP_0f07, 0, XX, XX, XX },
1753 { "xsha1", OP_0f07, 0, XX, XX, XX },
1754 { "xsha256", OP_0f07, 0, XX, XX, XX },
1755 { "(bad)", OP_0f07, 0, XX, XX, XX },
1756 { "(bad)", OP_0f07, 0, XX, XX, XX },
1757 { "(bad)", OP_0f07, 0, XX, XX, XX },
1758 { "(bad)", OP_0f07, 0, XX, XX, XX },
1759 { "(bad)", OP_0f07, 0, XX, XX, XX },
1763 static const struct dis386 prefix_user_table[][4] = {
1764 /* PREGRP0 */
1766 { "addps", XM, EX, XX, XX },
1767 { "addss", XM, EX, XX, XX },
1768 { "addpd", XM, EX, XX, XX },
1769 { "addsd", XM, EX, XX, XX },
1771 /* PREGRP1 */
1773 { "", XM, EX, OPSIMD, XX }, /* See OP_SIMD_SUFFIX. */
1774 { "", XM, EX, OPSIMD, XX },
1775 { "", XM, EX, OPSIMD, XX },
1776 { "", XM, EX, OPSIMD, XX },
1778 /* PREGRP2 */
1780 { "cvtpi2ps", XM, EMC, XX, XX },
1781 { "cvtsi2ssY", XM, Ev, XX, XX },
1782 { "cvtpi2pd", XM, EMC, XX, XX },
1783 { "cvtsi2sdY", XM, Ev, XX, XX },
1785 /* PREGRP3 */
1787 { "cvtps2pi", MXC, EX, XX, XX },
1788 { "cvtss2siY", Gv, EX, XX, XX },
1789 { "cvtpd2pi", MXC, EX, XX, XX },
1790 { "cvtsd2siY", Gv, EX, XX, XX },
1792 /* PREGRP4 */
1794 { "cvttps2pi", MXC, EX, XX, XX },
1795 { "cvttss2siY", Gv, EX, XX, XX },
1796 { "cvttpd2pi", MXC, EX, XX, XX },
1797 { "cvttsd2siY", Gv, EX, XX, XX },
1799 /* PREGRP5 */
1801 { "divps", XM, EX, XX, XX },
1802 { "divss", XM, EX, XX, XX },
1803 { "divpd", XM, EX, XX, XX },
1804 { "divsd", XM, EX, XX, XX },
1806 /* PREGRP6 */
1808 { "maxps", XM, EX, XX, XX },
1809 { "maxss", XM, EX, XX, XX },
1810 { "maxpd", XM, EX, XX, XX },
1811 { "maxsd", XM, EX, XX, XX },
1813 /* PREGRP7 */
1815 { "minps", XM, EX, XX, XX },
1816 { "minss", XM, EX, XX, XX },
1817 { "minpd", XM, EX, XX, XX },
1818 { "minsd", XM, EX, XX, XX },
1820 /* PREGRP8 */
1822 { "movups", XM, EX, XX, XX },
1823 { "movss", XM, EX, XX, XX },
1824 { "movupd", XM, EX, XX, XX },
1825 { "movsd", XM, EX, XX, XX },
1827 /* PREGRP9 */
1829 { "movups", EX, XM, XX, XX },
1830 { "movss", EX, XM, XX, XX },
1831 { "movupd", EX, XM, XX, XX },
1832 { "movsd", EX, XM, XX, XX },
1834 /* PREGRP10 */
1836 { "mulps", XM, EX, XX, XX },
1837 { "mulss", XM, EX, XX, XX },
1838 { "mulpd", XM, EX, XX, XX },
1839 { "mulsd", XM, EX, XX, XX },
1841 /* PREGRP11 */
1843 { "rcpps", XM, EX, XX, XX },
1844 { "rcpss", XM, EX, XX, XX },
1845 { "(bad)", XM, EX, XX, XX },
1846 { "(bad)", XM, EX, XX, XX },
1848 /* PREGRP12 */
1850 { "rsqrtps", XM, EX, XX, XX },
1851 { "rsqrtss", XM, EX, XX, XX },
1852 { "(bad)", XM, EX, XX, XX },
1853 { "(bad)", XM, EX, XX, XX },
1855 /* PREGRP13 */
1857 { "sqrtps", XM, EX, XX, XX },
1858 { "sqrtss", XM, EX, XX, XX },
1859 { "sqrtpd", XM, EX, XX, XX },
1860 { "sqrtsd", XM, EX, XX, XX },
1862 /* PREGRP14 */
1864 { "subps", XM, EX, XX, XX },
1865 { "subss", XM, EX, XX, XX },
1866 { "subpd", XM, EX, XX, XX },
1867 { "subsd", XM, EX, XX, XX },
1869 /* PREGRP15 */
1871 { "(bad)", XM, EX, XX, XX },
1872 { "cvtdq2pd", XM, EX, XX, XX },
1873 { "cvttpd2dq", XM, EX, XX, XX },
1874 { "cvtpd2dq", XM, EX, XX, XX },
1876 /* PREGRP16 */
1878 { "cvtdq2ps", XM, EX, XX, XX },
1879 { "cvttps2dq",XM, EX, XX, XX },
1880 { "cvtps2dq",XM, EX, XX, XX },
1881 { "(bad)", XM, EX, XX, XX },
1883 /* PREGRP17 */
1885 { "cvtps2pd", XM, EX, XX, XX },
1886 { "cvtss2sd", XM, EX, XX, XX },
1887 { "cvtpd2ps", XM, EX, XX, XX },
1888 { "cvtsd2ss", XM, EX, XX, XX },
1890 /* PREGRP18 */
1892 { "maskmovq", MX, MS, XX, XX },
1893 { "(bad)", XM, EX, XX, XX },
1894 { "maskmovdqu", XM, XS, XX, XX },
1895 { "(bad)", XM, EX, XX, XX },
1897 /* PREGRP19 */
1899 { "movq", MX, EM, XX, XX },
1900 { "movdqu", XM, EX, XX, XX },
1901 { "movdqa", XM, EX, XX, XX },
1902 { "(bad)", XM, EX, XX, XX },
1904 /* PREGRP20 */
1906 { "movq", EM, MX, XX, XX },
1907 { "movdqu", EX, XM, XX, XX },
1908 { "movdqa", EX, XM, XX, XX },
1909 { "(bad)", EX, XM, XX, XX },
1911 /* PREGRP21 */
1913 { "(bad)", EX, XM, XX, XX },
1914 { "movq2dq", XM, MS, XX, XX },
1915 { "movq", EX, XM, XX, XX },
1916 { "movdq2q", MX, XS, XX, XX },
1918 /* PREGRP22 */
1920 { "pshufw", MX, EM, Ib, XX },
1921 { "pshufhw", XM, EX, Ib, XX },
1922 { "pshufd", XM, EX, Ib, XX },
1923 { "pshuflw", XM, EX, Ib, XX },
1925 /* PREGRP23 */
1927 { "movd", Edq, MX, XX, XX },
1928 { "movq", XM, EX, XX, XX },
1929 { "movd", Edq, XM, XX, XX },
1930 { "(bad)", Ed, XM, XX, XX },
1932 /* PREGRP24 */
1934 { "(bad)", MX, EX, XX, XX },
1935 { "(bad)", XM, EX, XX, XX },
1936 { "punpckhqdq", XM, EX, XX, XX },
1937 { "(bad)", XM, EX, XX, XX },
1939 /* PREGRP25 */
1941 { "movntq", EM, MX, XX, XX },
1942 { "(bad)", EM, XM, XX, XX },
1943 { "movntdq", EM, XM, XX, XX },
1944 { "(bad)", EM, XM, XX, XX },
1946 /* PREGRP26 */
1948 { "(bad)", MX, EX, XX, XX },
1949 { "(bad)", XM, EX, XX, XX },
1950 { "punpcklqdq", XM, EX, XX, XX },
1951 { "(bad)", XM, EX, XX, XX },
1953 /* PREGRP27 */
1955 { "(bad)", MX, EX, XX, XX },
1956 { "(bad)", XM, EX, XX, XX },
1957 { "addsubpd", XM, EX, XX, XX },
1958 { "addsubps", XM, EX, XX, XX },
1960 /* PREGRP28 */
1962 { "(bad)", MX, EX, XX, XX },
1963 { "(bad)", XM, EX, XX, XX },
1964 { "haddpd", XM, EX, XX, XX },
1965 { "haddps", XM, EX, XX, XX },
1967 /* PREGRP29 */
1969 { "(bad)", MX, EX, XX, XX },
1970 { "(bad)", XM, EX, XX, XX },
1971 { "hsubpd", XM, EX, XX, XX },
1972 { "hsubps", XM, EX, XX, XX },
1974 /* PREGRP30 */
1976 { "movlpX", XM, EX, SIMD_Fixup, 'h', XX }, /* really only 2 operands */
1977 { "movsldup", XM, EX, XX, XX },
1978 { "movlpd", XM, EX, XX, XX },
1979 { "movddup", XM, EX, XX, XX },
1981 /* PREGRP31 */
1983 { "movhpX", XM, EX, SIMD_Fixup, 'l', XX },
1984 { "movshdup", XM, EX, XX, XX },
1985 { "movhpd", XM, EX, XX, XX },
1986 { "(bad)", XM, EX, XX, XX },
1988 /* PREGRP32 */
1990 { "(bad)", XM, EX, XX, XX },
1991 { "(bad)", XM, EX, XX, XX },
1992 { "(bad)", XM, EX, XX, XX },
1993 { "lddqu", XM, M, XX, XX },
1995 /* PREGRP33 */
1997 {"movntps",Ev, XM, XX, XX },
1998 {"movntss",Ev, XM, XX, XX },
1999 {"movntpd",Ev, XM, XX, XX },
2000 {"movntsd",Ev, XM, XX, XX },
2003 /* PREGRP34 */
2005 {"vmread", Em, Gm, XX, XX },
2006 {"(bad)", XX, XX, XX, XX },
2007 {"extrq", XS, Ib, Ib, XX },
2008 {"insertq",XM, XS, Ib, Ib },
2011 /* PREGRP35 */
2013 {"vmwrite", Gm, Em, XX, XX },
2014 {"(bad)", XX, XX, XX, XX },
2015 {"extrq", XM, XS, XX, XX },
2016 {"insertq", XM, XS, XX, XX },
2019 /* PREGRP36 */
2021 { "bsrS", Gv, Ev, XX, XX },
2022 { "lzcntS", Gv, Ev, XX, XX },
2023 { "bsrS", Gv, Ev, XX, XX },
2024 { "(bad)", XX, XX, XX, XX },
2027 /* PREGRP37 */
2029 { "(bad)", XX, XX, XX, XX },
2030 { "popcntS",Gv, Ev, XX, XX },
2031 { "(bad)", XX, XX, XX, XX },
2032 { "(bad)", XX, XX, XX, XX },
2036 static const struct dis386 x86_64_table[][2] = {
2038 { "pusha{P|}", XX, XX, XX, XX },
2039 { "(bad)", XX, XX, XX, XX },
2042 { "popa{P|}", XX, XX, XX, XX },
2043 { "(bad)", XX, XX, XX, XX },
2046 { "bound{S|}", Gv, Ma, XX, XX },
2047 { "(bad)", XX, XX, XX, XX },
2050 { "arpl", Ew, Gw, XX, XX },
2051 { "movs{||lq|xd}", Gv, Ed, XX, XX },
2055 static const struct dis386 three_byte_table[][256] = {
2056 /* THREE_BYTE_0 */
2058 /* 00 */
2059 { "pshufb", MX, EM, XX, XX },
2060 { "phaddw", MX, EM, XX, XX },
2061 { "phaddd", MX, EM, XX, XX },
2062 { "phaddsw", MX, EM, XX, XX },
2063 { "pmaddubsw", MX, EM, XX, XX },
2064 { "phsubw", MX, EM, XX, XX },
2065 { "phsubd", MX, EM, XX, XX },
2066 { "phsubsw", MX, EM, XX, XX },
2067 /* 08 */
2068 { "psignb", MX, EM, XX, XX },
2069 { "psignw", MX, EM, XX, XX },
2070 { "psignd", MX, EM, XX, XX },
2071 { "pmulhrsw", MX, EM, XX, XX },
2072 { "(bad)", XX, XX, XX, XX },
2073 { "(bad)", XX, XX, XX, XX },
2074 { "(bad)", XX, XX, XX, XX },
2075 { "(bad)", XX, XX, XX, XX },
2076 /* 10 */
2077 { "(bad)", XX, XX, XX, XX },
2078 { "(bad)", XX, XX, XX, XX },
2079 { "(bad)", XX, XX, XX, XX },
2080 { "(bad)", XX, XX, XX, XX },
2081 { "(bad)", XX, XX, XX, XX },
2082 { "(bad)", XX, XX, XX, XX },
2083 { "(bad)", XX, XX, XX, XX },
2084 { "(bad)", XX, XX, XX, XX },
2085 /* 18 */
2086 { "(bad)", XX, XX, XX, XX },
2087 { "(bad)", XX, XX, XX, XX },
2088 { "(bad)", XX, XX, XX, XX },
2089 { "(bad)", XX, XX, XX, XX },
2090 { "pabsb", MX, EM, XX, XX },
2091 { "pabsw", MX, EM, XX, XX },
2092 { "pabsd", MX, EM, XX, XX },
2093 { "(bad)", XX, XX, XX, XX },
2094 /* 20 */
2095 { "(bad)", XX, XX, XX, XX },
2096 { "(bad)", XX, XX, XX, XX },
2097 { "(bad)", XX, XX, XX, XX },
2098 { "(bad)", XX, XX, XX, XX },
2099 { "(bad)", XX, XX, XX, XX },
2100 { "(bad)", XX, XX, XX, XX },
2101 { "(bad)", XX, XX, XX, XX },
2102 { "(bad)", XX, XX, XX, XX },
2103 /* 28 */
2104 { "(bad)", XX, XX, XX, XX },
2105 { "(bad)", XX, XX, XX, XX },
2106 { "(bad)", XX, XX, XX, XX },
2107 { "(bad)", XX, XX, XX, XX },
2108 { "(bad)", XX, XX, XX, XX },
2109 { "(bad)", XX, XX, XX, XX },
2110 { "(bad)", XX, XX, XX, XX },
2111 { "(bad)", XX, XX, XX, XX },
2112 /* 30 */
2113 { "(bad)", XX, XX, XX, XX },
2114 { "(bad)", XX, XX, XX, XX },
2115 { "(bad)", XX, XX, XX, XX },
2116 { "(bad)", XX, XX, XX, XX },
2117 { "(bad)", XX, XX, XX, XX },
2118 { "(bad)", XX, XX, XX, XX },
2119 { "(bad)", XX, XX, XX, XX },
2120 { "(bad)", XX, XX, XX, XX },
2121 /* 38 */
2122 { "(bad)", XX, XX, XX, XX },
2123 { "(bad)", XX, XX, XX, XX },
2124 { "(bad)", XX, XX, XX, XX },
2125 { "(bad)", XX, XX, XX, XX },
2126 { "(bad)", XX, XX, XX, XX },
2127 { "(bad)", XX, XX, XX, XX },
2128 { "(bad)", XX, XX, XX, XX },
2129 { "(bad)", XX, XX, XX, XX },
2130 /* 40 */
2131 { "(bad)", XX, XX, XX, XX },
2132 { "(bad)", XX, XX, XX, XX },
2133 { "(bad)", XX, XX, XX, XX },
2134 { "(bad)", XX, XX, XX, XX },
2135 { "(bad)", XX, XX, XX, XX },
2136 { "(bad)", XX, XX, XX, XX },
2137 { "(bad)", XX, XX, XX, XX },
2138 { "(bad)", XX, XX, XX, XX },
2139 /* 48 */
2140 { "(bad)", XX, XX, XX, XX },
2141 { "(bad)", XX, XX, XX, XX },
2142 { "(bad)", XX, XX, XX, XX },
2143 { "(bad)", XX, XX, XX, XX },
2144 { "(bad)", XX, XX, XX, XX },
2145 { "(bad)", XX, XX, XX, XX },
2146 { "(bad)", XX, XX, XX, XX },
2147 { "(bad)", XX, XX, XX, XX },
2148 /* 50 */
2149 { "(bad)", XX, XX, XX, XX },
2150 { "(bad)", XX, XX, XX, XX },
2151 { "(bad)", XX, XX, XX, XX },
2152 { "(bad)", XX, XX, XX, XX },
2153 { "(bad)", XX, XX, XX, XX },
2154 { "(bad)", XX, XX, XX, XX },
2155 { "(bad)", XX, XX, XX, XX },
2156 { "(bad)", XX, XX, XX, XX },
2157 /* 58 */
2158 { "(bad)", XX, XX, XX, XX },
2159 { "(bad)", XX, XX, XX, XX },
2160 { "(bad)", XX, XX, XX, XX },
2161 { "(bad)", XX, XX, XX, XX },
2162 { "(bad)", XX, XX, XX, XX },
2163 { "(bad)", XX, XX, XX, XX },
2164 { "(bad)", XX, XX, XX, XX },
2165 { "(bad)", XX, XX, XX, XX },
2166 /* 60 */
2167 { "(bad)", XX, XX, XX, XX },
2168 { "(bad)", XX, XX, XX, XX },
2169 { "(bad)", XX, XX, XX, XX },
2170 { "(bad)", XX, XX, XX, XX },
2171 { "(bad)", XX, XX, XX, XX },
2172 { "(bad)", XX, XX, XX, XX },
2173 { "(bad)", XX, XX, XX, XX },
2174 { "(bad)", XX, XX, XX, XX },
2175 /* 68 */
2176 { "(bad)", XX, XX, XX, XX },
2177 { "(bad)", XX, XX, XX, XX },
2178 { "(bad)", XX, XX, XX, XX },
2179 { "(bad)", XX, XX, XX, XX },
2180 { "(bad)", XX, XX, XX, XX },
2181 { "(bad)", XX, XX, XX, XX },
2182 { "(bad)", XX, XX, XX, XX },
2183 { "(bad)", XX, XX, XX, XX },
2184 /* 70 */
2185 { "(bad)", XX, XX, XX, XX },
2186 { "(bad)", XX, XX, XX, XX },
2187 { "(bad)", XX, XX, XX, XX },
2188 { "(bad)", XX, XX, XX, XX },
2189 { "(bad)", XX, XX, XX, XX },
2190 { "(bad)", XX, XX, XX, XX },
2191 { "(bad)", XX, XX, XX, XX },
2192 { "(bad)", XX, XX, XX, XX },
2193 /* 78 */
2194 { "(bad)", XX, XX, XX, XX },
2195 { "(bad)", XX, XX, XX, XX },
2196 { "(bad)", XX, XX, XX, XX },
2197 { "(bad)", XX, XX, XX, XX },
2198 { "(bad)", XX, XX, XX, XX },
2199 { "(bad)", XX, XX, XX, XX },
2200 { "(bad)", XX, XX, XX, XX },
2201 { "(bad)", XX, XX, XX, XX },
2202 /* 80 */
2203 { "(bad)", XX, XX, XX, XX },
2204 { "(bad)", XX, XX, XX, XX },
2205 { "(bad)", XX, XX, XX, XX },
2206 { "(bad)", XX, XX, XX, XX },
2207 { "(bad)", XX, XX, XX, XX },
2208 { "(bad)", XX, XX, XX, XX },
2209 { "(bad)", XX, XX, XX, XX },
2210 { "(bad)", XX, XX, XX, XX },
2211 /* 88 */
2212 { "(bad)", XX, XX, XX, XX },
2213 { "(bad)", XX, XX, XX, XX },
2214 { "(bad)", XX, XX, XX, XX },
2215 { "(bad)", XX, XX, XX, XX },
2216 { "(bad)", XX, XX, XX, XX },
2217 { "(bad)", XX, XX, XX, XX },
2218 { "(bad)", XX, XX, XX, XX },
2219 { "(bad)", XX, XX, XX, XX },
2220 /* 90 */
2221 { "(bad)", XX, XX, XX, XX },
2222 { "(bad)", XX, XX, XX, XX },
2223 { "(bad)", XX, XX, XX, XX },
2224 { "(bad)", XX, XX, XX, XX },
2225 { "(bad)", XX, XX, XX, XX },
2226 { "(bad)", XX, XX, XX, XX },
2227 { "(bad)", XX, XX, XX, XX },
2228 { "(bad)", XX, XX, XX, XX },
2229 /* 98 */
2230 { "(bad)", XX, XX, XX, XX },
2231 { "(bad)", XX, XX, XX, XX },
2232 { "(bad)", XX, XX, XX, XX },
2233 { "(bad)", XX, XX, XX, XX },
2234 { "(bad)", XX, XX, XX, XX },
2235 { "(bad)", XX, XX, XX, XX },
2236 { "(bad)", XX, XX, XX, XX },
2237 { "(bad)", XX, XX, XX, XX },
2238 /* a0 */
2239 { "(bad)", XX, XX, XX, XX },
2240 { "(bad)", XX, XX, XX, XX },
2241 { "(bad)", XX, XX, XX, XX },
2242 { "(bad)", XX, XX, XX, XX },
2243 { "(bad)", XX, XX, XX, XX },
2244 { "(bad)", XX, XX, XX, XX },
2245 { "(bad)", XX, XX, XX, XX },
2246 { "(bad)", XX, XX, XX, XX },
2247 /* a8 */
2248 { "(bad)", XX, XX, XX, XX },
2249 { "(bad)", XX, XX, XX, XX },
2250 { "(bad)", XX, XX, XX, XX },
2251 { "(bad)", XX, XX, XX, XX },
2252 { "(bad)", XX, XX, XX, XX },
2253 { "(bad)", XX, XX, XX, XX },
2254 { "(bad)", XX, XX, XX, XX },
2255 { "(bad)", XX, XX, XX, XX },
2256 /* b0 */
2257 { "(bad)", XX, XX, XX, XX },
2258 { "(bad)", XX, XX, XX, XX },
2259 { "(bad)", XX, XX, XX, XX },
2260 { "(bad)", XX, XX, XX, XX },
2261 { "(bad)", XX, XX, XX, XX },
2262 { "(bad)", XX, XX, XX, XX },
2263 { "(bad)", XX, XX, XX, XX },
2264 { "(bad)", XX, XX, XX, XX },
2265 /* b8 */
2266 { "(bad)", XX, XX, XX, XX },
2267 { "(bad)", XX, XX, XX, XX },
2268 { "(bad)", XX, XX, XX, XX },
2269 { "(bad)", XX, XX, XX, XX },
2270 { "(bad)", XX, XX, XX, XX },
2271 { "(bad)", XX, XX, XX, XX },
2272 { "(bad)", XX, XX, XX, XX },
2273 { "(bad)", XX, XX, XX, XX },
2274 /* c0 */
2275 { "(bad)", XX, XX, XX, XX },
2276 { "(bad)", XX, XX, XX, XX },
2277 { "(bad)", XX, XX, XX, XX },
2278 { "(bad)", XX, XX, XX, XX },
2279 { "(bad)", XX, XX, XX, XX },
2280 { "(bad)", XX, XX, XX, XX },
2281 { "(bad)", XX, XX, XX, XX },
2282 { "(bad)", XX, XX, XX, XX },
2283 /* c8 */
2284 { "(bad)", XX, XX, XX, XX },
2285 { "(bad)", XX, XX, XX, XX },
2286 { "(bad)", XX, XX, XX, XX },
2287 { "(bad)", XX, XX, XX, XX },
2288 { "(bad)", XX, XX, XX, XX },
2289 { "(bad)", XX, XX, XX, XX },
2290 { "(bad)", XX, XX, XX, XX },
2291 { "(bad)", XX, XX, XX, XX },
2292 /* d0 */
2293 { "(bad)", XX, XX, XX, XX },
2294 { "(bad)", XX, XX, XX, XX },
2295 { "(bad)", XX, XX, XX, XX },
2296 { "(bad)", XX, XX, XX, XX },
2297 { "(bad)", XX, XX, XX, XX },
2298 { "(bad)", XX, XX, XX, XX },
2299 { "(bad)", XX, XX, XX, XX },
2300 { "(bad)", XX, XX, XX, XX },
2301 /* d8 */
2302 { "(bad)", XX, XX, XX, XX },
2303 { "(bad)", XX, XX, XX, XX },
2304 { "(bad)", XX, XX, XX, XX },
2305 { "(bad)", XX, XX, XX, XX },
2306 { "(bad)", XX, XX, XX, XX },
2307 { "(bad)", XX, XX, XX, XX },
2308 { "(bad)", XX, XX, XX, XX },
2309 { "(bad)", XX, XX, XX, XX },
2310 /* e0 */
2311 { "(bad)", XX, XX, XX, XX },
2312 { "(bad)", XX, XX, XX, XX },
2313 { "(bad)", XX, XX, XX, XX },
2314 { "(bad)", XX, XX, XX, XX },
2315 { "(bad)", XX, XX, XX, XX },
2316 { "(bad)", XX, XX, XX, XX },
2317 { "(bad)", XX, XX, XX, XX },
2318 { "(bad)", XX, XX, XX, XX },
2319 /* e8 */
2320 { "(bad)", XX, XX, XX, XX },
2321 { "(bad)", XX, XX, XX, XX },
2322 { "(bad)", XX, XX, XX, XX },
2323 { "(bad)", XX, XX, XX, XX },
2324 { "(bad)", XX, XX, XX, XX },
2325 { "(bad)", XX, XX, XX, XX },
2326 { "(bad)", XX, XX, XX, XX },
2327 { "(bad)", XX, XX, XX, XX },
2328 /* f0 */
2329 { "(bad)", XX, XX, XX, XX },
2330 { "(bad)", XX, XX, XX, XX },
2331 { "(bad)", XX, XX, XX, XX },
2332 { "(bad)", XX, XX, XX, XX },
2333 { "(bad)", XX, XX, XX, XX },
2334 { "(bad)", XX, XX, XX, XX },
2335 { "(bad)", XX, XX, XX, XX },
2336 { "(bad)", XX, XX, XX, XX },
2337 /* f8 */
2338 { "(bad)", XX, XX, XX, XX },
2339 { "(bad)", XX, XX, XX, XX },
2340 { "(bad)", XX, XX, XX, XX },
2341 { "(bad)", XX, XX, XX, XX },
2342 { "(bad)", XX, XX, XX, XX },
2343 { "(bad)", XX, XX, XX, XX },
2344 { "(bad)", XX, XX, XX, XX },
2345 { "(bad)", XX, XX, XX, XX }
2347 /* THREE_BYTE_1 */
2349 /* 00 */
2350 { "(bad)", XX, XX, XX, XX },
2351 { "(bad)", XX, XX, XX, XX },
2352 { "(bad)", XX, XX, XX, XX },
2353 { "(bad)", XX, XX, XX, XX },
2354 { "(bad)", XX, XX, XX, XX },
2355 { "(bad)", XX, XX, XX, XX },
2356 { "(bad)", XX, XX, XX, XX },
2357 { "(bad)", XX, XX, XX, XX },
2358 /* 08 */
2359 { "(bad)", XX, XX, XX, XX },
2360 { "(bad)", XX, XX, XX, XX },
2361 { "(bad)", XX, XX, XX, XX },
2362 { "(bad)", XX, XX, XX, XX },
2363 { "(bad)", XX, XX, XX, XX },
2364 { "(bad)", XX, XX, XX, XX },
2365 { "(bad)", XX, XX, XX, XX },
2366 { "palignr", MX, EM, Ib, XX },
2367 /* 10 */
2368 { "(bad)", XX, XX, XX, XX },
2369 { "(bad)", XX, XX, XX, XX },
2370 { "(bad)", XX, XX, XX, XX },
2371 { "(bad)", XX, XX, XX, XX },
2372 { "(bad)", XX, XX, XX, XX },
2373 { "(bad)", XX, XX, XX, XX },
2374 { "(bad)", XX, XX, XX, XX },
2375 { "(bad)", XX, XX, XX, XX },
2376 /* 18 */
2377 { "(bad)", XX, XX, XX, XX },
2378 { "(bad)", XX, XX, XX, XX },
2379 { "(bad)", XX, XX, XX, XX },
2380 { "(bad)", XX, XX, XX, XX },
2381 { "(bad)", XX, XX, XX, XX },
2382 { "(bad)", XX, XX, XX, XX },
2383 { "(bad)", XX, XX, XX, XX },
2384 { "(bad)", XX, XX, XX, XX },
2385 /* 20 */
2386 { "(bad)", XX, XX, XX, XX },
2387 { "(bad)", XX, XX, XX, XX },
2388 { "(bad)", XX, XX, XX, XX },
2389 { "(bad)", XX, XX, XX, XX },
2390 { "(bad)", XX, XX, XX, XX },
2391 { "(bad)", XX, XX, XX, XX },
2392 { "(bad)", XX, XX, XX, XX },
2393 { "(bad)", XX, XX, XX, XX },
2394 /* 28 */
2395 { "(bad)", XX, XX, XX, XX },
2396 { "(bad)", XX, XX, XX, XX },
2397 { "(bad)", XX, XX, XX, XX },
2398 { "(bad)", XX, XX, XX, XX },
2399 { "(bad)", XX, XX, XX, XX },
2400 { "(bad)", XX, XX, XX, XX },
2401 { "(bad)", XX, XX, XX, XX },
2402 { "(bad)", XX, XX, XX, XX },
2403 /* 30 */
2404 { "(bad)", XX, XX, XX, XX },
2405 { "(bad)", XX, XX, XX, XX },
2406 { "(bad)", XX, XX, XX, XX },
2407 { "(bad)", XX, XX, XX, XX },
2408 { "(bad)", XX, XX, XX, XX },
2409 { "(bad)", XX, XX, XX, XX },
2410 { "(bad)", XX, XX, XX, XX },
2411 { "(bad)", XX, XX, XX, XX },
2412 /* 38 */
2413 { "(bad)", XX, XX, XX, XX },
2414 { "(bad)", XX, XX, XX, XX },
2415 { "(bad)", XX, XX, XX, XX },
2416 { "(bad)", XX, XX, XX, XX },
2417 { "(bad)", XX, XX, XX, XX },
2418 { "(bad)", XX, XX, XX, XX },
2419 { "(bad)", XX, XX, XX, XX },
2420 { "(bad)", XX, XX, XX, XX },
2421 /* 40 */
2422 { "(bad)", XX, XX, XX, XX },
2423 { "(bad)", XX, XX, XX, XX },
2424 { "(bad)", XX, XX, XX, XX },
2425 { "(bad)", XX, XX, XX, XX },
2426 { "(bad)", XX, XX, XX, XX },
2427 { "(bad)", XX, XX, XX, XX },
2428 { "(bad)", XX, XX, XX, XX },
2429 { "(bad)", XX, XX, XX, XX },
2430 /* 48 */
2431 { "(bad)", XX, XX, XX, XX },
2432 { "(bad)", XX, XX, XX, XX },
2433 { "(bad)", XX, XX, XX, XX },
2434 { "(bad)", XX, XX, XX, XX },
2435 { "(bad)", XX, XX, XX, XX },
2436 { "(bad)", XX, XX, XX, XX },
2437 { "(bad)", XX, XX, XX, XX },
2438 { "(bad)", XX, XX, XX, XX },
2439 /* 50 */
2440 { "(bad)", XX, XX, XX, XX },
2441 { "(bad)", XX, XX, XX, XX },
2442 { "(bad)", XX, XX, XX, XX },
2443 { "(bad)", XX, XX, XX, XX },
2444 { "(bad)", XX, XX, XX, XX },
2445 { "(bad)", XX, XX, XX, XX },
2446 { "(bad)", XX, XX, XX, XX },
2447 { "(bad)", XX, XX, XX, XX },
2448 /* 58 */
2449 { "(bad)", XX, XX, XX, XX },
2450 { "(bad)", XX, XX, XX, XX },
2451 { "(bad)", XX, XX, XX, XX },
2452 { "(bad)", XX, XX, XX, XX },
2453 { "(bad)", XX, XX, XX, XX },
2454 { "(bad)", XX, XX, XX, XX },
2455 { "(bad)", XX, XX, XX, XX },
2456 { "(bad)", XX, XX, XX, XX },
2457 /* 60 */
2458 { "(bad)", XX, XX, XX, XX },
2459 { "(bad)", XX, XX, XX, XX },
2460 { "(bad)", XX, XX, XX, XX },
2461 { "(bad)", XX, XX, XX, XX },
2462 { "(bad)", XX, XX, XX, XX },
2463 { "(bad)", XX, XX, XX, XX },
2464 { "(bad)", XX, XX, XX, XX },
2465 { "(bad)", XX, XX, XX, XX },
2466 /* 68 */
2467 { "(bad)", XX, XX, XX, XX },
2468 { "(bad)", XX, XX, XX, XX },
2469 { "(bad)", XX, XX, XX, XX },
2470 { "(bad)", XX, XX, XX, XX },
2471 { "(bad)", XX, XX, XX, XX },
2472 { "(bad)", XX, XX, XX, XX },
2473 { "(bad)", XX, XX, XX, XX },
2474 { "(bad)", XX, XX, XX, XX },
2475 /* 70 */
2476 { "(bad)", XX, XX, XX, XX },
2477 { "(bad)", XX, XX, XX, XX },
2478 { "(bad)", XX, XX, XX, XX },
2479 { "(bad)", XX, XX, XX, XX },
2480 { "(bad)", XX, XX, XX, XX },
2481 { "(bad)", XX, XX, XX, XX },
2482 { "(bad)", XX, XX, XX, XX },
2483 { "(bad)", XX, XX, XX, XX },
2484 /* 78 */
2485 { "(bad)", XX, XX, XX, XX },
2486 { "(bad)", XX, XX, XX, XX },
2487 { "(bad)", XX, XX, XX, XX },
2488 { "(bad)", XX, XX, XX, XX },
2489 { "(bad)", XX, XX, XX, XX },
2490 { "(bad)", XX, XX, XX, XX },
2491 { "(bad)", XX, XX, XX, XX },
2492 { "(bad)", XX, XX, XX, XX },
2493 /* 80 */
2494 { "(bad)", XX, XX, XX, XX },
2495 { "(bad)", XX, XX, XX, XX },
2496 { "(bad)", XX, XX, XX, XX },
2497 { "(bad)", XX, XX, XX, XX },
2498 { "(bad)", XX, XX, XX, XX },
2499 { "(bad)", XX, XX, XX, XX },
2500 { "(bad)", XX, XX, XX, XX },
2501 { "(bad)", XX, XX, XX, XX },
2502 /* 88 */
2503 { "(bad)", XX, XX, XX, XX },
2504 { "(bad)", XX, XX, XX, XX },
2505 { "(bad)", XX, XX, XX, XX },
2506 { "(bad)", XX, XX, XX, XX },
2507 { "(bad)", XX, XX, XX, XX },
2508 { "(bad)", XX, XX, XX, XX },
2509 { "(bad)", XX, XX, XX, XX },
2510 { "(bad)", XX, XX, XX, XX },
2511 /* 90 */
2512 { "(bad)", XX, XX, XX, XX },
2513 { "(bad)", XX, XX, XX, XX },
2514 { "(bad)", XX, XX, XX, XX },
2515 { "(bad)", XX, XX, XX, XX },
2516 { "(bad)", XX, XX, XX, XX },
2517 { "(bad)", XX, XX, XX, XX },
2518 { "(bad)", XX, XX, XX, XX },
2519 { "(bad)", XX, XX, XX, XX },
2520 /* 98 */
2521 { "(bad)", XX, XX, XX, XX },
2522 { "(bad)", XX, XX, XX, XX },
2523 { "(bad)", XX, XX, XX, XX },
2524 { "(bad)", XX, XX, XX, XX },
2525 { "(bad)", XX, XX, XX, XX },
2526 { "(bad)", XX, XX, XX, XX },
2527 { "(bad)", XX, XX, XX, XX },
2528 { "(bad)", XX, XX, XX, XX },
2529 /* a0 */
2530 { "(bad)", XX, XX, XX, XX },
2531 { "(bad)", XX, XX, XX, XX },
2532 { "(bad)", XX, XX, XX, XX },
2533 { "(bad)", XX, XX, XX, XX },
2534 { "(bad)", XX, XX, XX, XX },
2535 { "(bad)", XX, XX, XX, XX },
2536 { "(bad)", XX, XX, XX, XX },
2537 { "(bad)", XX, XX, XX, XX },
2538 /* a8 */
2539 { "(bad)", XX, XX, XX, XX },
2540 { "(bad)", XX, XX, XX, XX },
2541 { "(bad)", XX, XX, XX, XX },
2542 { "(bad)", XX, XX, XX, XX },
2543 { "(bad)", XX, XX, XX, XX },
2544 { "(bad)", XX, XX, XX, XX },
2545 { "(bad)", XX, XX, XX, XX },
2546 { "(bad)", XX, XX, XX, XX },
2547 /* b0 */
2548 { "(bad)", XX, XX, XX, XX },
2549 { "(bad)", XX, XX, XX, XX },
2550 { "(bad)", XX, XX, XX, XX },
2551 { "(bad)", XX, XX, XX, XX },
2552 { "(bad)", XX, XX, XX, XX },
2553 { "(bad)", XX, XX, XX, XX },
2554 { "(bad)", XX, XX, XX, XX },
2555 { "(bad)", XX, XX, XX, XX },
2556 /* b8 */
2557 { "(bad)", XX, XX, XX, XX },
2558 { "(bad)", XX, XX, XX, XX },
2559 { "(bad)", XX, XX, XX, XX },
2560 { "(bad)", XX, XX, XX, XX },
2561 { "(bad)", XX, XX, XX, XX },
2562 { "(bad)", XX, XX, XX, XX },
2563 { "(bad)", XX, XX, XX, XX },
2564 { "(bad)", XX, XX, XX, XX },
2565 /* c0 */
2566 { "(bad)", XX, XX, XX, XX },
2567 { "(bad)", XX, XX, XX, XX },
2568 { "(bad)", XX, XX, XX, XX },
2569 { "(bad)", XX, XX, XX, XX },
2570 { "(bad)", XX, XX, XX, XX },
2571 { "(bad)", XX, XX, XX, XX },
2572 { "(bad)", XX, XX, XX, XX },
2573 { "(bad)", XX, XX, XX, XX },
2574 /* c8 */
2575 { "(bad)", XX, XX, XX, XX },
2576 { "(bad)", XX, XX, XX, XX },
2577 { "(bad)", XX, XX, XX, XX },
2578 { "(bad)", XX, XX, XX, XX },
2579 { "(bad)", XX, XX, XX, XX },
2580 { "(bad)", XX, XX, XX, XX },
2581 { "(bad)", XX, XX, XX, XX },
2582 { "(bad)", XX, XX, XX, XX },
2583 /* d0 */
2584 { "(bad)", XX, XX, XX, XX },
2585 { "(bad)", XX, XX, XX, XX },
2586 { "(bad)", XX, XX, XX, XX },
2587 { "(bad)", XX, XX, XX, XX },
2588 { "(bad)", XX, XX, XX, XX },
2589 { "(bad)", XX, XX, XX, XX },
2590 { "(bad)", XX, XX, XX, XX },
2591 { "(bad)", XX, XX, XX, XX },
2592 /* d8 */
2593 { "(bad)", XX, XX, XX, XX },
2594 { "(bad)", XX, XX, XX, XX },
2595 { "(bad)", XX, XX, XX, XX },
2596 { "(bad)", XX, XX, XX, XX },
2597 { "(bad)", XX, XX, XX, XX },
2598 { "(bad)", XX, XX, XX, XX },
2599 { "(bad)", XX, XX, XX, XX },
2600 { "(bad)", XX, XX, XX, XX },
2601 /* e0 */
2602 { "(bad)", XX, XX, XX, XX },
2603 { "(bad)", XX, XX, XX, XX },
2604 { "(bad)", XX, XX, XX, XX },
2605 { "(bad)", XX, XX, XX, XX },
2606 { "(bad)", XX, XX, XX, XX },
2607 { "(bad)", XX, XX, XX, XX },
2608 { "(bad)", XX, XX, XX, XX },
2609 { "(bad)", XX, XX, XX, XX },
2610 /* e8 */
2611 { "(bad)", XX, XX, XX, XX },
2612 { "(bad)", XX, XX, XX, XX },
2613 { "(bad)", XX, XX, XX, XX },
2614 { "(bad)", XX, XX, XX, XX },
2615 { "(bad)", XX, XX, XX, XX },
2616 { "(bad)", XX, XX, XX, XX },
2617 { "(bad)", XX, XX, XX, XX },
2618 { "(bad)", XX, XX, XX, XX },
2619 /* f0 */
2620 { "(bad)", XX, XX, XX, XX },
2621 { "(bad)", XX, XX, XX, XX },
2622 { "(bad)", XX, XX, XX, XX },
2623 { "(bad)", XX, XX, XX, XX },
2624 { "(bad)", XX, XX, XX, XX },
2625 { "(bad)", XX, XX, XX, XX },
2626 { "(bad)", XX, XX, XX, XX },
2627 { "(bad)", XX, XX, XX, XX },
2628 /* f8 */
2629 { "(bad)", XX, XX, XX, XX },
2630 { "(bad)", XX, XX, XX, XX },
2631 { "(bad)", XX, XX, XX, XX },
2632 { "(bad)", XX, XX, XX, XX },
2633 { "(bad)", XX, XX, XX, XX },
2634 { "(bad)", XX, XX, XX, XX },
2635 { "(bad)", XX, XX, XX, XX },
2636 { "(bad)", XX, XX, XX, XX }
2640 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2642 static void
2643 ckprefix (void)
2645 int newrex;
2646 rex = 0;
2647 prefixes = 0;
2648 used_prefixes = 0;
2649 rex_used = 0;
2650 while (1)
2652 FETCH_DATA (the_info, codep + 1);
2653 newrex = 0;
2654 switch (*codep)
2656 /* REX prefixes family. */
2657 case 0x40:
2658 case 0x41:
2659 case 0x42:
2660 case 0x43:
2661 case 0x44:
2662 case 0x45:
2663 case 0x46:
2664 case 0x47:
2665 case 0x48:
2666 case 0x49:
2667 case 0x4a:
2668 case 0x4b:
2669 case 0x4c:
2670 case 0x4d:
2671 case 0x4e:
2672 case 0x4f:
2673 if (address_mode == mode_64bit)
2674 newrex = *codep;
2675 else
2676 return;
2677 break;
2678 case 0xf3:
2679 prefixes |= PREFIX_REPZ;
2680 break;
2681 case 0xf2:
2682 prefixes |= PREFIX_REPNZ;
2683 break;
2684 case 0xf0:
2685 prefixes |= PREFIX_LOCK;
2686 break;
2687 case 0x2e:
2688 prefixes |= PREFIX_CS;
2689 break;
2690 case 0x36:
2691 prefixes |= PREFIX_SS;
2692 break;
2693 case 0x3e:
2694 prefixes |= PREFIX_DS;
2695 break;
2696 case 0x26:
2697 prefixes |= PREFIX_ES;
2698 break;
2699 case 0x64:
2700 prefixes |= PREFIX_FS;
2701 break;
2702 case 0x65:
2703 prefixes |= PREFIX_GS;
2704 break;
2705 case 0x66:
2706 prefixes |= PREFIX_DATA;
2707 break;
2708 case 0x67:
2709 prefixes |= PREFIX_ADDR;
2710 break;
2711 case FWAIT_OPCODE:
2712 /* fwait is really an instruction. If there are prefixes
2713 before the fwait, they belong to the fwait, *not* to the
2714 following instruction. */
2715 if (prefixes || rex)
2717 prefixes |= PREFIX_FWAIT;
2718 codep++;
2719 return;
2721 prefixes = PREFIX_FWAIT;
2722 break;
2723 default:
2724 return;
2726 /* Rex is ignored when followed by another prefix. */
2727 if (rex)
2729 rex_used = rex;
2730 return;
2732 rex = newrex;
2733 codep++;
2737 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2738 prefix byte. */
2740 static const char *
2741 prefix_name (int pref, int sizeflag)
2743 switch (pref)
2745 /* REX prefixes family. */
2746 case 0x40:
2747 return "rex";
2748 case 0x41:
2749 return "rexZ";
2750 case 0x42:
2751 return "rexY";
2752 case 0x43:
2753 return "rexYZ";
2754 case 0x44:
2755 return "rexX";
2756 case 0x45:
2757 return "rexXZ";
2758 case 0x46:
2759 return "rexXY";
2760 case 0x47:
2761 return "rexXYZ";
2762 case 0x48:
2763 return "rex64";
2764 case 0x49:
2765 return "rex64Z";
2766 case 0x4a:
2767 return "rex64Y";
2768 case 0x4b:
2769 return "rex64YZ";
2770 case 0x4c:
2771 return "rex64X";
2772 case 0x4d:
2773 return "rex64XZ";
2774 case 0x4e:
2775 return "rex64XY";
2776 case 0x4f:
2777 return "rex64XYZ";
2778 case 0xf3:
2779 return "repz";
2780 case 0xf2:
2781 return "repnz";
2782 case 0xf0:
2783 return "lock";
2784 case 0x2e:
2785 return "cs";
2786 case 0x36:
2787 return "ss";
2788 case 0x3e:
2789 return "ds";
2790 case 0x26:
2791 return "es";
2792 case 0x64:
2793 return "fs";
2794 case 0x65:
2795 return "gs";
2796 case 0x66:
2797 return (sizeflag & DFLAG) ? "data16" : "data32";
2798 case 0x67:
2799 if (address_mode == mode_64bit)
2800 return (sizeflag & AFLAG) ? "addr32" : "addr64";
2801 else
2802 return (sizeflag & AFLAG) ? "addr16" : "addr32";
2803 case FWAIT_OPCODE:
2804 return "fwait";
2805 default:
2806 return NULL;
2810 static char op1out[100], op2out[100], op3out[100], op4out[100];
2811 static int op_ad, op_index[4];
2812 static int two_source_ops;
2813 static bfd_vma op_address[4];
2814 static bfd_vma op_riprel[4];
2815 static bfd_vma start_pc;
2818 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2819 * (see topic "Redundant prefixes" in the "Differences from 8086"
2820 * section of the "Virtual 8086 Mode" chapter.)
2821 * 'pc' should be the address of this instruction, it will
2822 * be used to print the target address if this is a relative jump or call
2823 * The function returns the length of this instruction in bytes.
2826 static char intel_syntax;
2827 static char open_char;
2828 static char close_char;
2829 static char separator_char;
2830 static char scale_char;
2832 /* Here for backwards compatibility. When gdb stops using
2833 print_insn_i386_att and print_insn_i386_intel these functions can
2834 disappear, and print_insn_i386 be merged into print_insn. */
2836 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
2838 intel_syntax = 0;
2840 return print_insn (pc, info);
2844 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
2846 intel_syntax = 1;
2848 return print_insn (pc, info);
2852 print_insn_i386 (bfd_vma pc, disassemble_info *info)
2854 intel_syntax = -1;
2856 return print_insn (pc, info);
2859 void
2860 print_i386_disassembler_options (FILE *stream)
2862 fprintf (stream, _("\n\
2863 The following i386/x86-64 specific disassembler options are supported for use\n\
2864 with the -M switch (multiple options should be separated by commas):\n"));
2866 fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n"));
2867 fprintf (stream, _(" i386 Disassemble in 32bit mode\n"));
2868 fprintf (stream, _(" i8086 Disassemble in 16bit mode\n"));
2869 fprintf (stream, _(" att Display instruction in AT&T syntax\n"));
2870 fprintf (stream, _(" intel Display instruction in Intel syntax\n"));
2871 fprintf (stream, _(" addr64 Assume 64bit address size\n"));
2872 fprintf (stream, _(" addr32 Assume 32bit address size\n"));
2873 fprintf (stream, _(" addr16 Assume 16bit address size\n"));
2874 fprintf (stream, _(" data32 Assume 32bit data size\n"));
2875 fprintf (stream, _(" data16 Assume 16bit data size\n"));
2876 fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n"));
2879 static int
2880 print_insn (bfd_vma pc, disassemble_info *info)
2882 const struct dis386 *dp;
2883 int i;
2884 char *first, *second, *third, *fourth;
2885 int needcomma;
2886 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
2887 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
2888 int sizeflag;
2889 const char *p;
2890 struct dis_private priv;
2891 unsigned char op;
2893 if (info->mach == bfd_mach_x86_64_intel_syntax
2894 || info->mach == bfd_mach_x86_64)
2895 address_mode = mode_64bit;
2896 else
2897 address_mode = mode_32bit;
2899 if (intel_syntax == (char) -1)
2900 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2901 || info->mach == bfd_mach_x86_64_intel_syntax);
2903 if (info->mach == bfd_mach_i386_i386
2904 || info->mach == bfd_mach_x86_64
2905 || info->mach == bfd_mach_i386_i386_intel_syntax
2906 || info->mach == bfd_mach_x86_64_intel_syntax)
2907 priv.orig_sizeflag = AFLAG | DFLAG;
2908 else if (info->mach == bfd_mach_i386_i8086)
2909 priv.orig_sizeflag = 0;
2910 else
2911 abort ();
2913 for (p = info->disassembler_options; p != NULL; )
2915 if (CONST_STRNEQ (p, "x86-64"))
2917 address_mode = mode_64bit;
2918 priv.orig_sizeflag = AFLAG | DFLAG;
2920 else if (CONST_STRNEQ (p, "i386"))
2922 address_mode = mode_32bit;
2923 priv.orig_sizeflag = AFLAG | DFLAG;
2925 else if (CONST_STRNEQ (p, "i8086"))
2927 address_mode = mode_16bit;
2928 priv.orig_sizeflag = 0;
2930 else if (CONST_STRNEQ (p, "intel"))
2932 intel_syntax = 1;
2934 else if (CONST_STRNEQ (p, "att"))
2936 intel_syntax = 0;
2938 else if (CONST_STRNEQ (p, "addr"))
2940 if (address_mode == mode_64bit)
2942 if (p[4] == '3' && p[5] == '2')
2943 priv.orig_sizeflag &= ~AFLAG;
2944 else if (p[4] == '6' && p[5] == '4')
2945 priv.orig_sizeflag |= AFLAG;
2947 else
2949 if (p[4] == '1' && p[5] == '6')
2950 priv.orig_sizeflag &= ~AFLAG;
2951 else if (p[4] == '3' && p[5] == '2')
2952 priv.orig_sizeflag |= AFLAG;
2955 else if (CONST_STRNEQ (p, "data"))
2957 if (p[4] == '1' && p[5] == '6')
2958 priv.orig_sizeflag &= ~DFLAG;
2959 else if (p[4] == '3' && p[5] == '2')
2960 priv.orig_sizeflag |= DFLAG;
2962 else if (CONST_STRNEQ (p, "suffix"))
2963 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2965 p = strchr (p, ',');
2966 if (p != NULL)
2967 p++;
2970 if (intel_syntax)
2972 names64 = intel_names64;
2973 names32 = intel_names32;
2974 names16 = intel_names16;
2975 names8 = intel_names8;
2976 names8rex = intel_names8rex;
2977 names_seg = intel_names_seg;
2978 index16 = intel_index16;
2979 open_char = '[';
2980 close_char = ']';
2981 separator_char = '+';
2982 scale_char = '*';
2984 else
2986 names64 = att_names64;
2987 names32 = att_names32;
2988 names16 = att_names16;
2989 names8 = att_names8;
2990 names8rex = att_names8rex;
2991 names_seg = att_names_seg;
2992 index16 = att_index16;
2993 open_char = '(';
2994 close_char = ')';
2995 separator_char = ',';
2996 scale_char = ',';
2999 /* The output looks better if we put 7 bytes on a line, since that
3000 puts most long word instructions on a single line. */
3001 info->bytes_per_line = 7;
3003 info->private_data = &priv;
3004 priv.max_fetched = priv.the_buffer;
3005 priv.insn_start = pc;
3007 obuf[0] = 0;
3008 op1out[0] = 0;
3009 op2out[0] = 0;
3010 op3out[0] = 0;
3011 op4out[0] = 0;
3013 op_index[0] = op_index[1] = op_index[2] = op_index[3] = -1;
3015 the_info = info;
3016 start_pc = pc;
3017 start_codep = priv.the_buffer;
3018 codep = priv.the_buffer;
3020 if (setjmp (priv.bailout) != 0)
3022 const char *name;
3024 /* Getting here means we tried for data but didn't get it. That
3025 means we have an incomplete instruction of some sort. Just
3026 print the first byte as a prefix or a .byte pseudo-op. */
3027 if (codep > priv.the_buffer)
3029 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3030 if (name != NULL)
3031 (*info->fprintf_func) (info->stream, "%s", name);
3032 else
3034 /* Just print the first byte as a .byte instruction. */
3035 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3036 (unsigned int) priv.the_buffer[0]);
3039 return 1;
3042 return -1;
3045 obufp = obuf;
3046 ckprefix ();
3048 insn_codep = codep;
3049 sizeflag = priv.orig_sizeflag;
3051 FETCH_DATA (info, codep + 1);
3052 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3054 if (((prefixes & PREFIX_FWAIT)
3055 && ((*codep < 0xd8) || (*codep > 0xdf)))
3056 || (rex && rex_used))
3058 const char *name;
3060 /* fwait not followed by floating point instruction, or rex followed
3061 by other prefixes. Print the first prefix. */
3062 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3063 if (name == NULL)
3064 name = INTERNAL_DISASSEMBLER_ERROR;
3065 (*info->fprintf_func) (info->stream, "%s", name);
3066 return 1;
3069 op = 0;
3070 if (*codep == 0x0f)
3072 unsigned char threebyte;
3073 FETCH_DATA (info, codep + 2);
3074 threebyte = *++codep;
3075 dp = &dis386_twobyte[threebyte];
3076 need_modrm = twobyte_has_modrm[*codep];
3077 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3078 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3079 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3080 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3081 codep++;
3082 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
3084 FETCH_DATA (info, codep + 2);
3085 op = *codep++;
3086 switch (threebyte)
3088 case 0x38:
3089 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3090 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3091 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3092 break;
3093 case 0x3a:
3094 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3095 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3096 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3097 break;
3098 default:
3099 break;
3103 else
3105 dp = &dis386[*codep];
3106 need_modrm = onebyte_has_modrm[*codep];
3107 uses_DATA_prefix = 0;
3108 uses_REPNZ_prefix = 0;
3109 uses_REPZ_prefix = 0;
3110 uses_LOCK_prefix = 0;
3111 codep++;
3114 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3116 oappend ("repz ");
3117 used_prefixes |= PREFIX_REPZ;
3119 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3121 oappend ("repnz ");
3122 used_prefixes |= PREFIX_REPNZ;
3125 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3127 oappend ("lock ");
3128 used_prefixes |= PREFIX_LOCK;
3131 if (prefixes & PREFIX_ADDR)
3133 sizeflag ^= AFLAG;
3134 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
3136 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3137 oappend ("addr32 ");
3138 else
3139 oappend ("addr16 ");
3140 used_prefixes |= PREFIX_ADDR;
3144 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3146 sizeflag ^= DFLAG;
3147 if (dp->bytemode3 == cond_jump_mode
3148 && dp->bytemode1 == v_mode
3149 && !intel_syntax)
3151 if (sizeflag & DFLAG)
3152 oappend ("data32 ");
3153 else
3154 oappend ("data16 ");
3155 used_prefixes |= PREFIX_DATA;
3159 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
3161 dp = &three_byte_table[dp->bytemode2][op];
3162 mod = (*codep >> 6) & 3;
3163 reg = (*codep >> 3) & 7;
3164 rm = *codep & 7;
3166 else if (need_modrm)
3168 FETCH_DATA (info, codep + 1);
3169 mod = (*codep >> 6) & 3;
3170 reg = (*codep >> 3) & 7;
3171 rm = *codep & 7;
3174 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
3176 dofloat (sizeflag);
3178 else
3180 int index;
3181 if (dp->name == NULL)
3183 switch (dp->bytemode1)
3185 case USE_GROUPS:
3186 dp = &grps[dp->bytemode2][reg];
3187 break;
3189 case USE_PREFIX_USER_TABLE:
3190 index = 0;
3191 used_prefixes |= (prefixes & PREFIX_REPZ);
3192 if (prefixes & PREFIX_REPZ)
3193 index = 1;
3194 else
3196 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3197 before PREFIX_DATA. */
3198 used_prefixes |= (prefixes & PREFIX_REPNZ);
3199 if (prefixes & PREFIX_REPNZ)
3200 index = 3;
3201 else
3203 used_prefixes |= (prefixes & PREFIX_DATA);
3204 if (prefixes & PREFIX_DATA)
3205 index = 2;
3208 dp = &prefix_user_table[dp->bytemode2][index];
3209 break;
3211 case X86_64_SPECIAL:
3212 index = address_mode == mode_64bit ? 1 : 0;
3213 dp = &x86_64_table[dp->bytemode2][index];
3214 break;
3216 default:
3217 oappend (INTERNAL_DISASSEMBLER_ERROR);
3218 break;
3222 if (putop (dp->name, sizeflag) == 0)
3224 obufp = op1out;
3225 op_ad = 3;
3226 if (dp->op1)
3227 (*dp->op1) (dp->bytemode1, sizeflag);
3229 obufp = op2out;
3230 op_ad = 2;
3231 if (dp->op2)
3232 (*dp->op2) (dp->bytemode2, sizeflag);
3234 obufp = op3out;
3235 op_ad = 1;
3236 if (dp->op3)
3237 (*dp->op3) (dp->bytemode3, sizeflag);
3239 obufp = op4out;
3240 op_ad = 0;
3241 if (dp->op4)
3242 (*dp->op4) (dp->bytemode4, sizeflag);
3246 /* See if any prefixes were not used. If so, print the first one
3247 separately. If we don't do this, we'll wind up printing an
3248 instruction stream which does not precisely correspond to the
3249 bytes we are disassembling. */
3250 if ((prefixes & ~used_prefixes) != 0)
3252 const char *name;
3254 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3255 if (name == NULL)
3256 name = INTERNAL_DISASSEMBLER_ERROR;
3257 (*info->fprintf_func) (info->stream, "%s", name);
3258 return 1;
3260 if (rex & ~rex_used)
3262 const char *name;
3263 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3264 if (name == NULL)
3265 name = INTERNAL_DISASSEMBLER_ERROR;
3266 (*info->fprintf_func) (info->stream, "%s ", name);
3269 obufp = obuf + strlen (obuf);
3270 for (i = strlen (obuf); i < 6; i++)
3271 oappend (" ");
3272 oappend (" ");
3273 (*info->fprintf_func) (info->stream, "%s", obuf);
3275 /* The enter and bound instructions are printed with operands in the same
3276 order as the intel book; everything else is printed in reverse order. */
3277 if (intel_syntax || two_source_ops)
3279 first = op1out;
3280 second = op2out;
3281 third = op3out;
3282 fourth = op4out;
3283 op_ad = op_index[0];
3284 op_index[0] = op_index[3];
3285 op_index[3] = op_ad;
3286 op_ad = op_index[1];
3287 op_index[1] = op_index[2];
3288 op_index[2] = op_ad;
3291 else
3293 first = op4out;
3294 second = op3out;
3295 third = op2out;
3296 fourth = op1out;
3298 needcomma = 0;
3299 if (*first)
3301 if (op_index[0] != -1 && !op_riprel[0])
3302 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
3303 else
3304 (*info->fprintf_func) (info->stream, "%s", first);
3305 needcomma = 1;
3308 if (*second)
3310 if (needcomma)
3311 (*info->fprintf_func) (info->stream, ",");
3312 if (op_index[1] != -1 && !op_riprel[1])
3313 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
3314 else
3315 (*info->fprintf_func) (info->stream, "%s", second);
3316 needcomma = 1;
3319 if (*third)
3321 if (needcomma)
3322 (*info->fprintf_func) (info->stream, ",");
3323 if (op_index[2] != -1 && !op_riprel[2])
3324 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
3325 else
3326 (*info->fprintf_func) (info->stream, "%s", third);
3327 needcomma = 1;
3330 if (*fourth)
3332 if (needcomma)
3333 (*info->fprintf_func) (info->stream, ",");
3334 if (op_index[3] != -1 && !op_riprel[3])
3335 (*info->print_address_func) ((bfd_vma) op_address[op_index[3]], info);
3336 else
3337 (*info->fprintf_func) (info->stream, "%s", fourth);
3340 for (i = 0; i < 4; i++)
3341 if (op_index[i] != -1 && op_riprel[i])
3343 (*info->fprintf_func) (info->stream, " # ");
3344 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3345 + op_address[op_index[i]]), info);
3347 return codep - priv.the_buffer;
3350 static const char *float_mem[] = {
3351 /* d8 */
3352 "fadd{s||s|}",
3353 "fmul{s||s|}",
3354 "fcom{s||s|}",
3355 "fcomp{s||s|}",
3356 "fsub{s||s|}",
3357 "fsubr{s||s|}",
3358 "fdiv{s||s|}",
3359 "fdivr{s||s|}",
3360 /* d9 */
3361 "fld{s||s|}",
3362 "(bad)",
3363 "fst{s||s|}",
3364 "fstp{s||s|}",
3365 "fldenvIC",
3366 "fldcw",
3367 "fNstenvIC",
3368 "fNstcw",
3369 /* da */
3370 "fiadd{l||l|}",
3371 "fimul{l||l|}",
3372 "ficom{l||l|}",
3373 "ficomp{l||l|}",
3374 "fisub{l||l|}",
3375 "fisubr{l||l|}",
3376 "fidiv{l||l|}",
3377 "fidivr{l||l|}",
3378 /* db */
3379 "fild{l||l|}",
3380 "fisttp{l||l|}",
3381 "fist{l||l|}",
3382 "fistp{l||l|}",
3383 "(bad)",
3384 "fld{t||t|}",
3385 "(bad)",
3386 "fstp{t||t|}",
3387 /* dc */
3388 "fadd{l||l|}",
3389 "fmul{l||l|}",
3390 "fcom{l||l|}",
3391 "fcomp{l||l|}",
3392 "fsub{l||l|}",
3393 "fsubr{l||l|}",
3394 "fdiv{l||l|}",
3395 "fdivr{l||l|}",
3396 /* dd */
3397 "fld{l||l|}",
3398 "fisttp{ll||ll|}",
3399 "fst{l||l|}",
3400 "fstp{l||l|}",
3401 "frstorIC",
3402 "(bad)",
3403 "fNsaveIC",
3404 "fNstsw",
3405 /* de */
3406 "fiadd",
3407 "fimul",
3408 "ficom",
3409 "ficomp",
3410 "fisub",
3411 "fisubr",
3412 "fidiv",
3413 "fidivr",
3414 /* df */
3415 "fild",
3416 "fisttp",
3417 "fist",
3418 "fistp",
3419 "fbld",
3420 "fild{ll||ll|}",
3421 "fbstp",
3422 "fistp{ll||ll|}",
3425 static const unsigned char float_mem_mode[] = {
3426 /* d8 */
3427 d_mode,
3428 d_mode,
3429 d_mode,
3430 d_mode,
3431 d_mode,
3432 d_mode,
3433 d_mode,
3434 d_mode,
3435 /* d9 */
3436 d_mode,
3438 d_mode,
3439 d_mode,
3441 w_mode,
3443 w_mode,
3444 /* da */
3445 d_mode,
3446 d_mode,
3447 d_mode,
3448 d_mode,
3449 d_mode,
3450 d_mode,
3451 d_mode,
3452 d_mode,
3453 /* db */
3454 d_mode,
3455 d_mode,
3456 d_mode,
3457 d_mode,
3459 t_mode,
3461 t_mode,
3462 /* dc */
3463 q_mode,
3464 q_mode,
3465 q_mode,
3466 q_mode,
3467 q_mode,
3468 q_mode,
3469 q_mode,
3470 q_mode,
3471 /* dd */
3472 q_mode,
3473 q_mode,
3474 q_mode,
3475 q_mode,
3479 w_mode,
3480 /* de */
3481 w_mode,
3482 w_mode,
3483 w_mode,
3484 w_mode,
3485 w_mode,
3486 w_mode,
3487 w_mode,
3488 w_mode,
3489 /* df */
3490 w_mode,
3491 w_mode,
3492 w_mode,
3493 w_mode,
3494 t_mode,
3495 q_mode,
3496 t_mode,
3497 q_mode
3500 #define ST OP_ST, 0
3501 #define STi OP_STi, 0
3503 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
3504 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
3505 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
3506 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
3507 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
3508 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
3509 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
3510 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
3511 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
3513 static const struct dis386 float_reg[][8] = {
3514 /* d8 */
3516 { "fadd", ST, STi, XX, XX },
3517 { "fmul", ST, STi, XX, XX },
3518 { "fcom", STi, XX, XX, XX },
3519 { "fcomp", STi, XX, XX, XX },
3520 { "fsub", ST, STi, XX, XX },
3521 { "fsubr", ST, STi, XX, XX },
3522 { "fdiv", ST, STi, XX, XX },
3523 { "fdivr", ST, STi, XX, XX },
3525 /* d9 */
3527 { "fld", STi, XX, XX, XX },
3528 { "fxch", STi, XX, XX, XX },
3529 { FGRPd9_2 },
3530 { "(bad)", XX, XX, XX, XX },
3531 { FGRPd9_4 },
3532 { FGRPd9_5 },
3533 { FGRPd9_6 },
3534 { FGRPd9_7 },
3536 /* da */
3538 { "fcmovb", ST, STi, XX, XX },
3539 { "fcmove", ST, STi, XX, XX },
3540 { "fcmovbe",ST, STi, XX, XX },
3541 { "fcmovu", ST, STi, XX, XX },
3542 { "(bad)", XX, XX, XX, XX },
3543 { FGRPda_5 },
3544 { "(bad)", XX, XX, XX, XX },
3545 { "(bad)", XX, XX, XX, XX },
3547 /* db */
3549 { "fcmovnb",ST, STi, XX, XX },
3550 { "fcmovne",ST, STi, XX, XX },
3551 { "fcmovnbe",ST, STi, XX, XX },
3552 { "fcmovnu",ST, STi, XX, XX },
3553 { FGRPdb_4 },
3554 { "fucomi", ST, STi, XX, XX },
3555 { "fcomi", ST, STi, XX, XX },
3556 { "(bad)", XX, XX, XX, XX },
3558 /* dc */
3560 { "fadd", STi, ST, XX, XX },
3561 { "fmul", STi, ST, XX, XX },
3562 { "(bad)", XX, XX, XX, XX },
3563 { "(bad)", XX, XX, XX, XX },
3564 #if UNIXWARE_COMPAT
3565 { "fsub", STi, ST, XX, XX },
3566 { "fsubr", STi, ST, XX, XX },
3567 { "fdiv", STi, ST, XX, XX },
3568 { "fdivr", STi, ST, XX, XX },
3569 #else
3570 { "fsubr", STi, ST, XX, XX },
3571 { "fsub", STi, ST, XX, XX },
3572 { "fdivr", STi, ST, XX, XX },
3573 { "fdiv", STi, ST, XX, XX },
3574 #endif
3576 /* dd */
3578 { "ffree", STi, XX, XX, XX },
3579 { "(bad)", XX, XX, XX, XX },
3580 { "fst", STi, XX, XX, XX },
3581 { "fstp", STi, XX, XX, XX },
3582 { "fucom", STi, XX, XX, XX },
3583 { "fucomp", STi, XX, XX, XX },
3584 { "(bad)", XX, XX, XX, XX },
3585 { "(bad)", XX, XX, XX, XX },
3587 /* de */
3589 { "faddp", STi, ST, XX, XX },
3590 { "fmulp", STi, ST, XX, XX },
3591 { "(bad)", XX, XX, XX, XX },
3592 { FGRPde_3 },
3593 #if UNIXWARE_COMPAT
3594 { "fsubp", STi, ST, XX, XX },
3595 { "fsubrp", STi, ST, XX, XX },
3596 { "fdivp", STi, ST, XX, XX },
3597 { "fdivrp", STi, ST, XX, XX },
3598 #else
3599 { "fsubrp", STi, ST, XX, XX },
3600 { "fsubp", STi, ST, XX, XX },
3601 { "fdivrp", STi, ST, XX, XX },
3602 { "fdivp", STi, ST, XX, XX },
3603 #endif
3605 /* df */
3607 { "ffreep", STi, XX, XX, XX },
3608 { "(bad)", XX, XX, XX, XX },
3609 { "(bad)", XX, XX, XX, XX },
3610 { "(bad)", XX, XX, XX, XX },
3611 { FGRPdf_4 },
3612 { "fucomip",ST, STi, XX, XX },
3613 { "fcomip", ST, STi, XX, XX },
3614 { "(bad)", XX, XX, XX, XX },
3618 static char *fgrps[][8] = {
3619 /* d9_2 0 */
3621 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3624 /* d9_4 1 */
3626 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3629 /* d9_5 2 */
3631 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3634 /* d9_6 3 */
3636 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3639 /* d9_7 4 */
3641 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3644 /* da_5 5 */
3646 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3649 /* db_4 6 */
3651 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3652 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3655 /* de_3 7 */
3657 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3660 /* df_4 8 */
3662 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3666 static void
3667 dofloat (int sizeflag)
3669 const struct dis386 *dp;
3670 unsigned char floatop;
3672 floatop = codep[-1];
3674 if (mod != 3)
3676 int fp_indx = (floatop - 0xd8) * 8 + reg;
3678 putop (float_mem[fp_indx], sizeflag);
3679 obufp = op1out;
3680 op_ad = 2;
3681 OP_E (float_mem_mode[fp_indx], sizeflag);
3682 return;
3684 /* Skip mod/rm byte. */
3685 MODRM_CHECK;
3686 codep++;
3688 dp = &float_reg[floatop - 0xd8][reg];
3689 if (dp->name == NULL)
3691 putop (fgrps[dp->bytemode1][rm], sizeflag);
3693 /* Instruction fnstsw is only one with strange arg. */
3694 if (floatop == 0xdf && codep[-1] == 0xe0)
3695 strcpy (op1out, names16[0]);
3697 else
3699 putop (dp->name, sizeflag);
3701 obufp = op1out;
3702 op_ad = 2;
3703 if (dp->op1)
3704 (*dp->op1) (dp->bytemode1, sizeflag);
3706 obufp = op2out;
3707 op_ad = 1;
3708 if (dp->op2)
3709 (*dp->op2) (dp->bytemode2, sizeflag);
3713 static void
3714 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3716 oappend ("%st" + intel_syntax);
3719 static void
3720 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3722 sprintf (scratchbuf, "%%st(%d)", rm);
3723 oappend (scratchbuf + intel_syntax);
3726 /* Capital letters in template are macros. */
3727 static int
3728 putop (const char *template, int sizeflag)
3730 const char *p;
3731 int alt = 0;
3733 for (p = template; *p; p++)
3735 switch (*p)
3737 default:
3738 *obufp++ = *p;
3739 break;
3740 case '{':
3741 alt = 0;
3742 if (intel_syntax)
3743 alt += 1;
3744 if (address_mode == mode_64bit)
3745 alt += 2;
3746 while (alt != 0)
3748 while (*++p != '|')
3750 if (*p == '}')
3752 /* Alternative not valid. */
3753 strcpy (obuf, "(bad)");
3754 obufp = obuf + 5;
3755 return 1;
3757 else if (*p == '\0')
3758 abort ();
3760 alt--;
3762 /* Fall through. */
3763 case 'I':
3764 alt = 1;
3765 continue;
3766 case '|':
3767 while (*++p != '}')
3769 if (*p == '\0')
3770 abort ();
3772 break;
3773 case '}':
3774 break;
3775 case 'A':
3776 if (intel_syntax)
3777 break;
3778 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3779 *obufp++ = 'b';
3780 break;
3781 case 'B':
3782 if (intel_syntax)
3783 break;
3784 if (sizeflag & SUFFIX_ALWAYS)
3785 *obufp++ = 'b';
3786 break;
3787 case 'C':
3788 if (intel_syntax && !alt)
3789 break;
3790 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
3792 if (sizeflag & DFLAG)
3793 *obufp++ = intel_syntax ? 'd' : 'l';
3794 else
3795 *obufp++ = intel_syntax ? 'w' : 's';
3796 used_prefixes |= (prefixes & PREFIX_DATA);
3798 break;
3799 case 'D':
3800 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
3801 break;
3802 USED_REX (REX_MODE64);
3803 if (mod == 3)
3805 if (rex & REX_MODE64)
3806 *obufp++ = 'q';
3807 else if (sizeflag & DFLAG)
3808 *obufp++ = intel_syntax ? 'd' : 'l';
3809 else
3810 *obufp++ = 'w';
3811 used_prefixes |= (prefixes & PREFIX_DATA);
3813 else
3814 *obufp++ = 'w';
3815 break;
3816 case 'E': /* For jcxz/jecxz */
3817 if (address_mode == mode_64bit)
3819 if (sizeflag & AFLAG)
3820 *obufp++ = 'r';
3821 else
3822 *obufp++ = 'e';
3824 else
3825 if (sizeflag & AFLAG)
3826 *obufp++ = 'e';
3827 used_prefixes |= (prefixes & PREFIX_ADDR);
3828 break;
3829 case 'F':
3830 if (intel_syntax)
3831 break;
3832 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3834 if (sizeflag & AFLAG)
3835 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
3836 else
3837 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
3838 used_prefixes |= (prefixes & PREFIX_ADDR);
3840 break;
3841 case 'G':
3842 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
3843 break;
3844 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
3845 *obufp++ = 'l';
3846 else
3847 *obufp++ = 'w';
3848 if (!(rex & REX_MODE64))
3849 used_prefixes |= (prefixes & PREFIX_DATA);
3850 break;
3851 case 'H':
3852 if (intel_syntax)
3853 break;
3854 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3855 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3857 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3858 *obufp++ = ',';
3859 *obufp++ = 'p';
3860 if (prefixes & PREFIX_DS)
3861 *obufp++ = 't';
3862 else
3863 *obufp++ = 'n';
3865 break;
3866 case 'J':
3867 if (intel_syntax)
3868 break;
3869 *obufp++ = 'l';
3870 break;
3871 case 'Z':
3872 if (intel_syntax)
3873 break;
3874 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3876 *obufp++ = 'q';
3877 break;
3879 /* Fall through. */
3880 case 'L':
3881 if (intel_syntax)
3882 break;
3883 if (sizeflag & SUFFIX_ALWAYS)
3884 *obufp++ = 'l';
3885 break;
3886 case 'N':
3887 if ((prefixes & PREFIX_FWAIT) == 0)
3888 *obufp++ = 'n';
3889 else
3890 used_prefixes |= PREFIX_FWAIT;
3891 break;
3892 case 'O':
3893 USED_REX (REX_MODE64);
3894 if (rex & REX_MODE64)
3895 *obufp++ = 'o';
3896 else if (intel_syntax && (sizeflag & DFLAG))
3897 *obufp++ = 'q';
3898 else
3899 *obufp++ = 'd';
3900 if (!(rex & REX_MODE64))
3901 used_prefixes |= (prefixes & PREFIX_DATA);
3902 break;
3903 case 'T':
3904 if (intel_syntax)
3905 break;
3906 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3908 *obufp++ = 'q';
3909 break;
3911 /* Fall through. */
3912 case 'P':
3913 if (intel_syntax)
3914 break;
3915 if ((prefixes & PREFIX_DATA)
3916 || (rex & REX_MODE64)
3917 || (sizeflag & SUFFIX_ALWAYS))
3919 USED_REX (REX_MODE64);
3920 if (rex & REX_MODE64)
3921 *obufp++ = 'q';
3922 else
3924 if (sizeflag & DFLAG)
3925 *obufp++ = 'l';
3926 else
3927 *obufp++ = 'w';
3929 used_prefixes |= (prefixes & PREFIX_DATA);
3931 break;
3932 case 'U':
3933 if (intel_syntax)
3934 break;
3935 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3937 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3938 *obufp++ = 'q';
3939 break;
3941 /* Fall through. */
3942 case 'Q':
3943 if (intel_syntax && !alt)
3944 break;
3945 USED_REX (REX_MODE64);
3946 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3948 if (rex & REX_MODE64)
3949 *obufp++ = 'q';
3950 else
3952 if (sizeflag & DFLAG)
3953 *obufp++ = intel_syntax ? 'd' : 'l';
3954 else
3955 *obufp++ = 'w';
3957 used_prefixes |= (prefixes & PREFIX_DATA);
3959 break;
3960 case 'R':
3961 USED_REX (REX_MODE64);
3962 if (rex & REX_MODE64)
3963 *obufp++ = 'q';
3964 else if (sizeflag & DFLAG)
3966 if (intel_syntax)
3967 *obufp++ = 'd';
3968 else
3969 *obufp++ = 'l';
3971 else
3972 *obufp++ = 'w';
3973 if (intel_syntax && !p[1]
3974 && ((rex & REX_MODE64) || (sizeflag & DFLAG)))
3975 *obufp++ = 'e';
3976 if (!(rex & REX_MODE64))
3977 used_prefixes |= (prefixes & PREFIX_DATA);
3978 break;
3979 case 'V':
3980 if (intel_syntax)
3981 break;
3982 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3984 if (sizeflag & SUFFIX_ALWAYS)
3985 *obufp++ = 'q';
3986 break;
3988 /* Fall through. */
3989 case 'S':
3990 if (intel_syntax)
3991 break;
3992 if (sizeflag & SUFFIX_ALWAYS)
3994 if (rex & REX_MODE64)
3995 *obufp++ = 'q';
3996 else
3998 if (sizeflag & DFLAG)
3999 *obufp++ = 'l';
4000 else
4001 *obufp++ = 'w';
4002 used_prefixes |= (prefixes & PREFIX_DATA);
4005 break;
4006 case 'X':
4007 if (prefixes & PREFIX_DATA)
4008 *obufp++ = 'd';
4009 else
4010 *obufp++ = 's';
4011 used_prefixes |= (prefixes & PREFIX_DATA);
4012 break;
4013 case 'Y':
4014 if (intel_syntax)
4015 break;
4016 if (rex & REX_MODE64)
4018 USED_REX (REX_MODE64);
4019 *obufp++ = 'q';
4021 break;
4022 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4023 case 'W':
4024 /* operand size flag for cwtl, cbtw */
4025 USED_REX (REX_MODE64);
4026 if (rex & REX_MODE64)
4028 if (intel_syntax)
4029 *obufp++ = 'd';
4030 else
4031 *obufp++ = 'l';
4033 else if (sizeflag & DFLAG)
4034 *obufp++ = 'w';
4035 else
4036 *obufp++ = 'b';
4037 if (!(rex & REX_MODE64))
4038 used_prefixes |= (prefixes & PREFIX_DATA);
4039 break;
4041 alt = 0;
4043 *obufp = 0;
4044 return 0;
4047 static void
4048 oappend (const char *s)
4050 strcpy (obufp, s);
4051 obufp += strlen (s);
4054 static void
4055 append_seg (void)
4057 if (prefixes & PREFIX_CS)
4059 used_prefixes |= PREFIX_CS;
4060 oappend ("%cs:" + intel_syntax);
4062 if (prefixes & PREFIX_DS)
4064 used_prefixes |= PREFIX_DS;
4065 oappend ("%ds:" + intel_syntax);
4067 if (prefixes & PREFIX_SS)
4069 used_prefixes |= PREFIX_SS;
4070 oappend ("%ss:" + intel_syntax);
4072 if (prefixes & PREFIX_ES)
4074 used_prefixes |= PREFIX_ES;
4075 oappend ("%es:" + intel_syntax);
4077 if (prefixes & PREFIX_FS)
4079 used_prefixes |= PREFIX_FS;
4080 oappend ("%fs:" + intel_syntax);
4082 if (prefixes & PREFIX_GS)
4084 used_prefixes |= PREFIX_GS;
4085 oappend ("%gs:" + intel_syntax);
4089 static void
4090 OP_indirE (int bytemode, int sizeflag)
4092 if (!intel_syntax)
4093 oappend ("*");
4094 OP_E (bytemode, sizeflag);
4097 static void
4098 print_operand_value (char *buf, int hex, bfd_vma disp)
4100 if (address_mode == mode_64bit)
4102 if (hex)
4104 char tmp[30];
4105 int i;
4106 buf[0] = '0';
4107 buf[1] = 'x';
4108 sprintf_vma (tmp, disp);
4109 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
4110 strcpy (buf + 2, tmp + i);
4112 else
4114 bfd_signed_vma v = disp;
4115 char tmp[30];
4116 int i;
4117 if (v < 0)
4119 *(buf++) = '-';
4120 v = -disp;
4121 /* Check for possible overflow on 0x8000000000000000. */
4122 if (v < 0)
4124 strcpy (buf, "9223372036854775808");
4125 return;
4128 if (!v)
4130 strcpy (buf, "0");
4131 return;
4134 i = 0;
4135 tmp[29] = 0;
4136 while (v)
4138 tmp[28 - i] = (v % 10) + '0';
4139 v /= 10;
4140 i++;
4142 strcpy (buf, tmp + 29 - i);
4145 else
4147 if (hex)
4148 sprintf (buf, "0x%x", (unsigned int) disp);
4149 else
4150 sprintf (buf, "%d", (int) disp);
4154 static void
4155 intel_operand_size (int bytemode, int sizeflag)
4157 switch (bytemode)
4159 case b_mode:
4160 oappend ("BYTE PTR ");
4161 break;
4162 case w_mode:
4163 case dqw_mode:
4164 oappend ("WORD PTR ");
4165 break;
4166 case stack_v_mode:
4167 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4169 oappend ("QWORD PTR ");
4170 used_prefixes |= (prefixes & PREFIX_DATA);
4171 break;
4173 /* FALLTHRU */
4174 case v_mode:
4175 case dq_mode:
4176 USED_REX (REX_MODE64);
4177 if (rex & REX_MODE64)
4178 oappend ("QWORD PTR ");
4179 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4180 oappend ("DWORD PTR ");
4181 else
4182 oappend ("WORD PTR ");
4183 used_prefixes |= (prefixes & PREFIX_DATA);
4184 break;
4185 case z_mode:
4186 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4187 *obufp++ = 'D';
4188 oappend ("WORD PTR ");
4189 if (!(rex & REX_MODE64))
4190 used_prefixes |= (prefixes & PREFIX_DATA);
4191 break;
4192 case d_mode:
4193 oappend ("DWORD PTR ");
4194 break;
4195 case q_mode:
4196 oappend ("QWORD PTR ");
4197 break;
4198 case m_mode:
4199 if (address_mode == mode_64bit)
4200 oappend ("QWORD PTR ");
4201 else
4202 oappend ("DWORD PTR ");
4203 break;
4204 case f_mode:
4205 if (sizeflag & DFLAG)
4206 oappend ("FWORD PTR ");
4207 else
4208 oappend ("DWORD PTR ");
4209 used_prefixes |= (prefixes & PREFIX_DATA);
4210 break;
4211 case t_mode:
4212 oappend ("TBYTE PTR ");
4213 break;
4214 case x_mode:
4215 oappend ("XMMWORD PTR ");
4216 break;
4217 case o_mode:
4218 oappend ("OWORD PTR ");
4219 break;
4220 default:
4221 break;
4225 static void
4226 OP_E (int bytemode, int sizeflag)
4228 bfd_vma disp;
4229 int add = 0;
4230 int riprel = 0;
4231 USED_REX (REX_EXTZ);
4232 if (rex & REX_EXTZ)
4233 add += 8;
4235 /* Skip mod/rm byte. */
4236 MODRM_CHECK;
4237 codep++;
4239 if (mod == 3)
4241 switch (bytemode)
4243 case b_mode:
4244 USED_REX (0);
4245 if (rex)
4246 oappend (names8rex[rm + add]);
4247 else
4248 oappend (names8[rm + add]);
4249 break;
4250 case w_mode:
4251 oappend (names16[rm + add]);
4252 break;
4253 case d_mode:
4254 oappend (names32[rm + add]);
4255 break;
4256 case q_mode:
4257 oappend (names64[rm + add]);
4258 break;
4259 case m_mode:
4260 if (address_mode == mode_64bit)
4261 oappend (names64[rm + add]);
4262 else
4263 oappend (names32[rm + add]);
4264 break;
4265 case stack_v_mode:
4266 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4268 oappend (names64[rm + add]);
4269 used_prefixes |= (prefixes & PREFIX_DATA);
4270 break;
4272 bytemode = v_mode;
4273 /* FALLTHRU */
4274 case v_mode:
4275 case dq_mode:
4276 case dqw_mode:
4277 USED_REX (REX_MODE64);
4278 if (rex & REX_MODE64)
4279 oappend (names64[rm + add]);
4280 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4281 oappend (names32[rm + add]);
4282 else
4283 oappend (names16[rm + add]);
4284 used_prefixes |= (prefixes & PREFIX_DATA);
4285 break;
4286 case 0:
4287 break;
4288 default:
4289 oappend (INTERNAL_DISASSEMBLER_ERROR);
4290 break;
4292 return;
4295 disp = 0;
4296 if (intel_syntax)
4297 intel_operand_size (bytemode, sizeflag);
4298 append_seg ();
4300 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
4302 int havesib;
4303 int havebase;
4304 int base;
4305 int index = 0;
4306 int scale = 0;
4308 havesib = 0;
4309 havebase = 1;
4310 base = rm;
4312 if (base == 4)
4314 havesib = 1;
4315 FETCH_DATA (the_info, codep + 1);
4316 index = (*codep >> 3) & 7;
4317 if (address_mode == mode_64bit || index != 0x4)
4318 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4319 scale = (*codep >> 6) & 3;
4320 base = *codep & 7;
4321 USED_REX (REX_EXTY);
4322 if (rex & REX_EXTY)
4323 index += 8;
4324 codep++;
4326 base += add;
4328 switch (mod)
4330 case 0:
4331 if ((base & 7) == 5)
4333 havebase = 0;
4334 if (address_mode == mode_64bit && !havesib)
4335 riprel = 1;
4336 disp = get32s ();
4338 break;
4339 case 1:
4340 FETCH_DATA (the_info, codep + 1);
4341 disp = *codep++;
4342 if ((disp & 0x80) != 0)
4343 disp -= 0x100;
4344 break;
4345 case 2:
4346 disp = get32s ();
4347 break;
4350 if (!intel_syntax)
4351 if (mod != 0 || (base & 7) == 5)
4353 print_operand_value (scratchbuf, !riprel, disp);
4354 oappend (scratchbuf);
4355 if (riprel)
4357 set_op (disp, 1);
4358 oappend ("(%rip)");
4362 if (havebase || (havesib && (index != 4 || scale != 0)))
4364 *obufp++ = open_char;
4365 if (intel_syntax && riprel)
4366 oappend ("rip + ");
4367 *obufp = '\0';
4368 if (havebase)
4369 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4370 ? names64[base] : names32[base]);
4371 if (havesib)
4373 if (index != 4)
4375 if (!intel_syntax || havebase)
4377 *obufp++ = separator_char;
4378 *obufp = '\0';
4380 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4381 ? names64[index] : names32[index]);
4383 if (scale != 0 || (!intel_syntax && index != 4))
4385 *obufp++ = scale_char;
4386 *obufp = '\0';
4387 sprintf (scratchbuf, "%d", 1 << scale);
4388 oappend (scratchbuf);
4391 if (intel_syntax && disp)
4393 if ((bfd_signed_vma) disp > 0)
4395 *obufp++ = '+';
4396 *obufp = '\0';
4398 else if (mod != 1)
4400 *obufp++ = '-';
4401 *obufp = '\0';
4402 disp = - (bfd_signed_vma) disp;
4405 print_operand_value (scratchbuf, mod != 1, disp);
4406 oappend (scratchbuf);
4409 *obufp++ = close_char;
4410 *obufp = '\0';
4412 else if (intel_syntax)
4414 if (mod != 0 || (base & 7) == 5)
4416 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4417 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4419 else
4421 oappend (names_seg[ds_reg - es_reg]);
4422 oappend (":");
4424 print_operand_value (scratchbuf, 1, disp);
4425 oappend (scratchbuf);
4429 else
4430 { /* 16 bit address mode */
4431 switch (mod)
4433 case 0:
4434 if (rm == 6)
4436 disp = get16 ();
4437 if ((disp & 0x8000) != 0)
4438 disp -= 0x10000;
4440 break;
4441 case 1:
4442 FETCH_DATA (the_info, codep + 1);
4443 disp = *codep++;
4444 if ((disp & 0x80) != 0)
4445 disp -= 0x100;
4446 break;
4447 case 2:
4448 disp = get16 ();
4449 if ((disp & 0x8000) != 0)
4450 disp -= 0x10000;
4451 break;
4454 if (!intel_syntax)
4455 if (mod != 0 || rm == 6)
4457 print_operand_value (scratchbuf, 0, disp);
4458 oappend (scratchbuf);
4461 if (mod != 0 || rm != 6)
4463 *obufp++ = open_char;
4464 *obufp = '\0';
4465 oappend (index16[rm]);
4466 if (intel_syntax && disp)
4468 if ((bfd_signed_vma) disp > 0)
4470 *obufp++ = '+';
4471 *obufp = '\0';
4473 else if (mod != 1)
4475 *obufp++ = '-';
4476 *obufp = '\0';
4477 disp = - (bfd_signed_vma) disp;
4480 print_operand_value (scratchbuf, mod != 1, disp);
4481 oappend (scratchbuf);
4484 *obufp++ = close_char;
4485 *obufp = '\0';
4487 else if (intel_syntax)
4489 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4490 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4492 else
4494 oappend (names_seg[ds_reg - es_reg]);
4495 oappend (":");
4497 print_operand_value (scratchbuf, 1, disp & 0xffff);
4498 oappend (scratchbuf);
4503 static void
4504 OP_G (int bytemode, int sizeflag)
4506 int add = 0;
4507 USED_REX (REX_EXTX);
4508 if (rex & REX_EXTX)
4509 add += 8;
4510 switch (bytemode)
4512 case b_mode:
4513 USED_REX (0);
4514 if (rex)
4515 oappend (names8rex[reg + add]);
4516 else
4517 oappend (names8[reg + add]);
4518 break;
4519 case w_mode:
4520 oappend (names16[reg + add]);
4521 break;
4522 case d_mode:
4523 oappend (names32[reg + add]);
4524 break;
4525 case q_mode:
4526 oappend (names64[reg + add]);
4527 break;
4528 case v_mode:
4529 case dq_mode:
4530 case dqw_mode:
4531 USED_REX (REX_MODE64);
4532 if (rex & REX_MODE64)
4533 oappend (names64[reg + add]);
4534 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4535 oappend (names32[reg + add]);
4536 else
4537 oappend (names16[reg + add]);
4538 used_prefixes |= (prefixes & PREFIX_DATA);
4539 break;
4540 case m_mode:
4541 if (address_mode == mode_64bit)
4542 oappend (names64[reg + add]);
4543 else
4544 oappend (names32[reg + add]);
4545 break;
4546 default:
4547 oappend (INTERNAL_DISASSEMBLER_ERROR);
4548 break;
4552 static bfd_vma
4553 get64 (void)
4555 bfd_vma x;
4556 #ifdef BFD64
4557 unsigned int a;
4558 unsigned int b;
4560 FETCH_DATA (the_info, codep + 8);
4561 a = *codep++ & 0xff;
4562 a |= (*codep++ & 0xff) << 8;
4563 a |= (*codep++ & 0xff) << 16;
4564 a |= (*codep++ & 0xff) << 24;
4565 b = *codep++ & 0xff;
4566 b |= (*codep++ & 0xff) << 8;
4567 b |= (*codep++ & 0xff) << 16;
4568 b |= (*codep++ & 0xff) << 24;
4569 x = a + ((bfd_vma) b << 32);
4570 #else
4571 abort ();
4572 x = 0;
4573 #endif
4574 return x;
4577 static bfd_signed_vma
4578 get32 (void)
4580 bfd_signed_vma x = 0;
4582 FETCH_DATA (the_info, codep + 4);
4583 x = *codep++ & (bfd_signed_vma) 0xff;
4584 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4585 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4586 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4587 return x;
4590 static bfd_signed_vma
4591 get32s (void)
4593 bfd_signed_vma x = 0;
4595 FETCH_DATA (the_info, codep + 4);
4596 x = *codep++ & (bfd_signed_vma) 0xff;
4597 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4598 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4599 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4601 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
4603 return x;
4606 static int
4607 get16 (void)
4609 int x = 0;
4611 FETCH_DATA (the_info, codep + 2);
4612 x = *codep++ & 0xff;
4613 x |= (*codep++ & 0xff) << 8;
4614 return x;
4617 static void
4618 set_op (bfd_vma op, int riprel)
4620 op_index[op_ad] = op_ad;
4621 if (address_mode == mode_64bit)
4623 op_address[op_ad] = op;
4624 op_riprel[op_ad] = riprel;
4626 else
4628 /* Mask to get a 32-bit address. */
4629 op_address[op_ad] = op & 0xffffffff;
4630 op_riprel[op_ad] = riprel & 0xffffffff;
4634 static void
4635 OP_REG (int code, int sizeflag)
4637 const char *s;
4638 int add = 0;
4639 USED_REX (REX_EXTZ);
4640 if (rex & REX_EXTZ)
4641 add = 8;
4643 switch (code)
4645 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4646 case sp_reg: case bp_reg: case si_reg: case di_reg:
4647 s = names16[code - ax_reg + add];
4648 break;
4649 case es_reg: case ss_reg: case cs_reg:
4650 case ds_reg: case fs_reg: case gs_reg:
4651 s = names_seg[code - es_reg + add];
4652 break;
4653 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4654 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4655 USED_REX (0);
4656 if (rex)
4657 s = names8rex[code - al_reg + add];
4658 else
4659 s = names8[code - al_reg];
4660 break;
4661 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
4662 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
4663 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4665 s = names64[code - rAX_reg + add];
4666 break;
4668 code += eAX_reg - rAX_reg;
4669 /* Fall through. */
4670 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4671 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4672 USED_REX (REX_MODE64);
4673 if (rex & REX_MODE64)
4674 s = names64[code - eAX_reg + add];
4675 else if (sizeflag & DFLAG)
4676 s = names32[code - eAX_reg + add];
4677 else
4678 s = names16[code - eAX_reg + add];
4679 used_prefixes |= (prefixes & PREFIX_DATA);
4680 break;
4681 default:
4682 s = INTERNAL_DISASSEMBLER_ERROR;
4683 break;
4685 oappend (s);
4688 static void
4689 OP_IMREG (int code, int sizeflag)
4691 const char *s;
4693 switch (code)
4695 case indir_dx_reg:
4696 if (intel_syntax)
4697 s = "dx";
4698 else
4699 s = "(%dx)";
4700 break;
4701 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4702 case sp_reg: case bp_reg: case si_reg: case di_reg:
4703 s = names16[code - ax_reg];
4704 break;
4705 case es_reg: case ss_reg: case cs_reg:
4706 case ds_reg: case fs_reg: case gs_reg:
4707 s = names_seg[code - es_reg];
4708 break;
4709 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4710 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4711 USED_REX (0);
4712 if (rex)
4713 s = names8rex[code - al_reg];
4714 else
4715 s = names8[code - al_reg];
4716 break;
4717 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4718 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4719 USED_REX (REX_MODE64);
4720 if (rex & REX_MODE64)
4721 s = names64[code - eAX_reg];
4722 else if (sizeflag & DFLAG)
4723 s = names32[code - eAX_reg];
4724 else
4725 s = names16[code - eAX_reg];
4726 used_prefixes |= (prefixes & PREFIX_DATA);
4727 break;
4728 case z_mode_ax_reg:
4729 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4730 s = *names32;
4731 else
4732 s = *names16;
4733 if (!(rex & REX_MODE64))
4734 used_prefixes |= (prefixes & PREFIX_DATA);
4735 break;
4736 default:
4737 s = INTERNAL_DISASSEMBLER_ERROR;
4738 break;
4740 oappend (s);
4743 static void
4744 OP_I (int bytemode, int sizeflag)
4746 bfd_signed_vma op;
4747 bfd_signed_vma mask = -1;
4749 switch (bytemode)
4751 case b_mode:
4752 FETCH_DATA (the_info, codep + 1);
4753 op = *codep++;
4754 mask = 0xff;
4755 break;
4756 case q_mode:
4757 if (address_mode == mode_64bit)
4759 op = get32s ();
4760 break;
4762 /* Fall through. */
4763 case v_mode:
4764 USED_REX (REX_MODE64);
4765 if (rex & REX_MODE64)
4766 op = get32s ();
4767 else if (sizeflag & DFLAG)
4769 op = get32 ();
4770 mask = 0xffffffff;
4772 else
4774 op = get16 ();
4775 mask = 0xfffff;
4777 used_prefixes |= (prefixes & PREFIX_DATA);
4778 break;
4779 case w_mode:
4780 mask = 0xfffff;
4781 op = get16 ();
4782 break;
4783 case const_1_mode:
4784 if (intel_syntax)
4785 oappend ("1");
4786 return;
4787 default:
4788 oappend (INTERNAL_DISASSEMBLER_ERROR);
4789 return;
4792 op &= mask;
4793 scratchbuf[0] = '$';
4794 print_operand_value (scratchbuf + 1, 1, op);
4795 oappend (scratchbuf + intel_syntax);
4796 scratchbuf[0] = '\0';
4799 static void
4800 OP_I64 (int bytemode, int sizeflag)
4802 bfd_signed_vma op;
4803 bfd_signed_vma mask = -1;
4805 if (address_mode != mode_64bit)
4807 OP_I (bytemode, sizeflag);
4808 return;
4811 switch (bytemode)
4813 case b_mode:
4814 FETCH_DATA (the_info, codep + 1);
4815 op = *codep++;
4816 mask = 0xff;
4817 break;
4818 case v_mode:
4819 USED_REX (REX_MODE64);
4820 if (rex & REX_MODE64)
4821 op = get64 ();
4822 else if (sizeflag & DFLAG)
4824 op = get32 ();
4825 mask = 0xffffffff;
4827 else
4829 op = get16 ();
4830 mask = 0xfffff;
4832 used_prefixes |= (prefixes & PREFIX_DATA);
4833 break;
4834 case w_mode:
4835 mask = 0xfffff;
4836 op = get16 ();
4837 break;
4838 default:
4839 oappend (INTERNAL_DISASSEMBLER_ERROR);
4840 return;
4843 op &= mask;
4844 scratchbuf[0] = '$';
4845 print_operand_value (scratchbuf + 1, 1, op);
4846 oappend (scratchbuf + intel_syntax);
4847 scratchbuf[0] = '\0';
4850 static void
4851 OP_sI (int bytemode, int sizeflag)
4853 bfd_signed_vma op;
4854 bfd_signed_vma mask = -1;
4856 switch (bytemode)
4858 case b_mode:
4859 FETCH_DATA (the_info, codep + 1);
4860 op = *codep++;
4861 if ((op & 0x80) != 0)
4862 op -= 0x100;
4863 mask = 0xffffffff;
4864 break;
4865 case v_mode:
4866 USED_REX (REX_MODE64);
4867 if (rex & REX_MODE64)
4868 op = get32s ();
4869 else if (sizeflag & DFLAG)
4871 op = get32s ();
4872 mask = 0xffffffff;
4874 else
4876 mask = 0xffffffff;
4877 op = get16 ();
4878 if ((op & 0x8000) != 0)
4879 op -= 0x10000;
4881 used_prefixes |= (prefixes & PREFIX_DATA);
4882 break;
4883 case w_mode:
4884 op = get16 ();
4885 mask = 0xffffffff;
4886 if ((op & 0x8000) != 0)
4887 op -= 0x10000;
4888 break;
4889 default:
4890 oappend (INTERNAL_DISASSEMBLER_ERROR);
4891 return;
4894 scratchbuf[0] = '$';
4895 print_operand_value (scratchbuf + 1, 1, op);
4896 oappend (scratchbuf + intel_syntax);
4899 static void
4900 OP_J (int bytemode, int sizeflag)
4902 bfd_vma disp;
4903 bfd_vma mask = -1;
4905 switch (bytemode)
4907 case b_mode:
4908 FETCH_DATA (the_info, codep + 1);
4909 disp = *codep++;
4910 if ((disp & 0x80) != 0)
4911 disp -= 0x100;
4912 break;
4913 case v_mode:
4914 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
4915 disp = get32s ();
4916 else
4918 disp = get16 ();
4919 if ((disp & 0x8000) != 0)
4920 disp -= 0x10000;
4921 /* For some reason, a data16 prefix on a jump instruction
4922 means that the pc is masked to 16 bits after the
4923 displacement is added! */
4924 if ((prefixes & PREFIX_DATA))
4925 mask = 0xffff;
4927 used_prefixes |= (prefixes & PREFIX_DATA);
4928 break;
4929 default:
4930 oappend (INTERNAL_DISASSEMBLER_ERROR);
4931 return;
4933 disp = (start_pc + codep - start_codep + disp) & mask;
4934 set_op (disp, 0);
4935 print_operand_value (scratchbuf, 1, disp);
4936 oappend (scratchbuf);
4939 static void
4940 OP_SEG (int bytemode, int sizeflag)
4942 if (bytemode == w_mode)
4943 oappend (names_seg[reg]);
4944 else
4945 OP_E (mod == 3 ? bytemode : w_mode, sizeflag);
4948 static void
4949 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
4951 int seg, offset;
4953 if (sizeflag & DFLAG)
4955 offset = get32 ();
4956 seg = get16 ();
4958 else
4960 offset = get16 ();
4961 seg = get16 ();
4963 used_prefixes |= (prefixes & PREFIX_DATA);
4964 if (intel_syntax)
4965 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
4966 else
4967 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
4968 oappend (scratchbuf);
4971 static void
4972 OP_OFF (int bytemode, int sizeflag)
4974 bfd_vma off;
4976 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4977 intel_operand_size (bytemode, sizeflag);
4978 append_seg ();
4980 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4981 off = get32 ();
4982 else
4983 off = get16 ();
4985 if (intel_syntax)
4987 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4988 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4990 oappend (names_seg[ds_reg - es_reg]);
4991 oappend (":");
4994 print_operand_value (scratchbuf, 1, off);
4995 oappend (scratchbuf);
4998 static void
4999 OP_OFF64 (int bytemode, int sizeflag)
5001 bfd_vma off;
5003 if (address_mode != mode_64bit
5004 || (prefixes & PREFIX_ADDR))
5006 OP_OFF (bytemode, sizeflag);
5007 return;
5010 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5011 intel_operand_size (bytemode, sizeflag);
5012 append_seg ();
5014 off = get64 ();
5016 if (intel_syntax)
5018 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5019 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5021 oappend (names_seg[ds_reg - es_reg]);
5022 oappend (":");
5025 print_operand_value (scratchbuf, 1, off);
5026 oappend (scratchbuf);
5029 static void
5030 ptr_reg (int code, int sizeflag)
5032 const char *s;
5034 *obufp++ = open_char;
5035 used_prefixes |= (prefixes & PREFIX_ADDR);
5036 if (address_mode == mode_64bit)
5038 if (!(sizeflag & AFLAG))
5039 s = names32[code - eAX_reg];
5040 else
5041 s = names64[code - eAX_reg];
5043 else if (sizeflag & AFLAG)
5044 s = names32[code - eAX_reg];
5045 else
5046 s = names16[code - eAX_reg];
5047 oappend (s);
5048 *obufp++ = close_char;
5049 *obufp = 0;
5052 static void
5053 OP_ESreg (int code, int sizeflag)
5055 if (intel_syntax)
5057 switch (codep[-1])
5059 case 0x6d: /* insw/insl */
5060 intel_operand_size (z_mode, sizeflag);
5061 break;
5062 case 0xa5: /* movsw/movsl/movsq */
5063 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5064 case 0xab: /* stosw/stosl */
5065 case 0xaf: /* scasw/scasl */
5066 intel_operand_size (v_mode, sizeflag);
5067 break;
5068 default:
5069 intel_operand_size (b_mode, sizeflag);
5072 oappend ("%es:" + intel_syntax);
5073 ptr_reg (code, sizeflag);
5076 static void
5077 OP_DSreg (int code, int sizeflag)
5079 if (intel_syntax)
5081 switch (codep[-1])
5083 case 0x6f: /* outsw/outsl */
5084 intel_operand_size (z_mode, sizeflag);
5085 break;
5086 case 0xa5: /* movsw/movsl/movsq */
5087 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5088 case 0xad: /* lodsw/lodsl/lodsq */
5089 intel_operand_size (v_mode, sizeflag);
5090 break;
5091 default:
5092 intel_operand_size (b_mode, sizeflag);
5095 if ((prefixes
5096 & (PREFIX_CS
5097 | PREFIX_DS
5098 | PREFIX_SS
5099 | PREFIX_ES
5100 | PREFIX_FS
5101 | PREFIX_GS)) == 0)
5102 prefixes |= PREFIX_DS;
5103 append_seg ();
5104 ptr_reg (code, sizeflag);
5107 static void
5108 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5110 int add = 0;
5111 if (rex & REX_EXTX)
5113 USED_REX (REX_EXTX);
5114 add = 8;
5116 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5118 used_prefixes |= PREFIX_LOCK;
5119 add = 8;
5121 sprintf (scratchbuf, "%%cr%d", reg + add);
5122 oappend (scratchbuf + intel_syntax);
5125 static void
5126 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5128 int add = 0;
5129 USED_REX (REX_EXTX);
5130 if (rex & REX_EXTX)
5131 add = 8;
5132 if (intel_syntax)
5133 sprintf (scratchbuf, "db%d", reg + add);
5134 else
5135 sprintf (scratchbuf, "%%db%d", reg + add);
5136 oappend (scratchbuf);
5139 static void
5140 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5142 sprintf (scratchbuf, "%%tr%d", reg);
5143 oappend (scratchbuf + intel_syntax);
5146 static void
5147 OP_Rd (int bytemode, int sizeflag)
5149 if (mod == 3)
5150 OP_E (bytemode, sizeflag);
5151 else
5152 BadOp ();
5155 static void
5156 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5158 used_prefixes |= (prefixes & PREFIX_DATA);
5159 if (prefixes & PREFIX_DATA)
5161 int add = 0;
5162 USED_REX (REX_EXTX);
5163 if (rex & REX_EXTX)
5164 add = 8;
5165 sprintf (scratchbuf, "%%xmm%d", reg + add);
5167 else
5168 sprintf (scratchbuf, "%%mm%d", reg);
5169 oappend (scratchbuf + intel_syntax);
5172 static void
5173 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5175 int add = 0;
5176 USED_REX (REX_EXTX);
5177 if (rex & REX_EXTX)
5178 add = 8;
5179 sprintf (scratchbuf, "%%xmm%d", reg + add);
5180 oappend (scratchbuf + intel_syntax);
5183 static void
5184 OP_EM (int bytemode, int sizeflag)
5186 if (mod != 3)
5188 if (intel_syntax && bytemode == v_mode)
5190 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5191 used_prefixes |= (prefixes & PREFIX_DATA);
5193 OP_E (bytemode, sizeflag);
5194 return;
5197 /* Skip mod/rm byte. */
5198 MODRM_CHECK;
5199 codep++;
5200 used_prefixes |= (prefixes & PREFIX_DATA);
5201 if (prefixes & PREFIX_DATA)
5203 int add = 0;
5205 USED_REX (REX_EXTZ);
5206 if (rex & REX_EXTZ)
5207 add = 8;
5208 sprintf (scratchbuf, "%%xmm%d", rm + add);
5210 else
5211 sprintf (scratchbuf, "%%mm%d", rm);
5212 oappend (scratchbuf + intel_syntax);
5215 /* cvt* are the only instructions in sse2 which have
5216 both SSE and MMX operands and also have 0x66 prefix
5217 in their opcode. 0x66 was originally used to differentiate
5218 between SSE and MMX instruction(operands). So we have to handle the
5219 cvt* separately using OP_EMC and OP_MXC */
5220 static void
5221 OP_EMC (int bytemode, int sizeflag)
5223 if (mod != 3)
5225 if (intel_syntax && bytemode == v_mode)
5227 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5228 used_prefixes |= (prefixes & PREFIX_DATA);
5230 OP_E (bytemode, sizeflag);
5231 return;
5234 /* Skip mod/rm byte. */
5235 MODRM_CHECK;
5236 codep++;
5237 used_prefixes |= (prefixes & PREFIX_DATA);
5238 sprintf (scratchbuf, "%%mm%d", rm);
5239 oappend (scratchbuf + intel_syntax);
5242 static void
5243 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5245 used_prefixes |= (prefixes & PREFIX_DATA);
5246 sprintf (scratchbuf, "%%mm%d", reg);
5247 oappend (scratchbuf + intel_syntax);
5250 static void
5251 OP_EX (int bytemode, int sizeflag)
5253 int add = 0;
5254 if (mod != 3)
5256 if (intel_syntax && bytemode == v_mode)
5258 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
5260 case 0: bytemode = x_mode; break;
5261 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
5262 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
5263 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
5264 default: bytemode = 0; break;
5267 OP_E (bytemode, sizeflag);
5268 return;
5270 USED_REX (REX_EXTZ);
5271 if (rex & REX_EXTZ)
5272 add = 8;
5274 /* Skip mod/rm byte. */
5275 MODRM_CHECK;
5276 codep++;
5277 sprintf (scratchbuf, "%%xmm%d", rm + add);
5278 oappend (scratchbuf + intel_syntax);
5281 static void
5282 OP_MS (int bytemode, int sizeflag)
5284 if (mod == 3)
5285 OP_EM (bytemode, sizeflag);
5286 else
5287 BadOp ();
5290 static void
5291 OP_XS (int bytemode, int sizeflag)
5293 if (mod == 3)
5294 OP_EX (bytemode, sizeflag);
5295 else
5296 BadOp ();
5299 static void
5300 OP_M (int bytemode, int sizeflag)
5302 if (mod == 3)
5303 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5304 BadOp ();
5305 else
5306 OP_E (bytemode, sizeflag);
5309 static void
5310 OP_0f07 (int bytemode, int sizeflag)
5312 if (mod != 3 || rm != 0)
5313 BadOp ();
5314 else
5315 OP_E (bytemode, sizeflag);
5318 static void
5319 OP_0fae (int bytemode, int sizeflag)
5321 if (mod == 3)
5323 if (reg == 7)
5324 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5326 if (reg < 5 || rm != 0)
5328 BadOp (); /* bad sfence, mfence, or lfence */
5329 return;
5332 else if (reg != 7)
5334 BadOp (); /* bad clflush */
5335 return;
5338 OP_E (bytemode, sizeflag);
5341 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5342 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5343 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5346 static void
5347 NOP_Fixup1 (int bytemode, int sizeflag)
5349 if (prefixes == PREFIX_REPZ)
5350 strcpy (obuf, "pause");
5351 else if (prefixes == PREFIX_DATA
5352 || ((rex & REX_MODE64) && rex != 0x48))
5353 OP_REG (bytemode, sizeflag);
5354 else
5355 strcpy (obuf, "nop");
5358 static void
5359 NOP_Fixup2 (int bytemode, int sizeflag)
5361 if (prefixes == PREFIX_DATA
5362 || ((rex & REX_MODE64) && rex != 0x48))
5363 OP_IMREG (bytemode, sizeflag);
5366 static const char *const Suffix3DNow[] = {
5367 /* 00 */ NULL, NULL, NULL, NULL,
5368 /* 04 */ NULL, NULL, NULL, NULL,
5369 /* 08 */ NULL, NULL, NULL, NULL,
5370 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
5371 /* 10 */ NULL, NULL, NULL, NULL,
5372 /* 14 */ NULL, NULL, NULL, NULL,
5373 /* 18 */ NULL, NULL, NULL, NULL,
5374 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
5375 /* 20 */ NULL, NULL, NULL, NULL,
5376 /* 24 */ NULL, NULL, NULL, NULL,
5377 /* 28 */ NULL, NULL, NULL, NULL,
5378 /* 2C */ NULL, NULL, NULL, NULL,
5379 /* 30 */ NULL, NULL, NULL, NULL,
5380 /* 34 */ NULL, NULL, NULL, NULL,
5381 /* 38 */ NULL, NULL, NULL, NULL,
5382 /* 3C */ NULL, NULL, NULL, NULL,
5383 /* 40 */ NULL, NULL, NULL, NULL,
5384 /* 44 */ NULL, NULL, NULL, NULL,
5385 /* 48 */ NULL, NULL, NULL, NULL,
5386 /* 4C */ NULL, NULL, NULL, NULL,
5387 /* 50 */ NULL, NULL, NULL, NULL,
5388 /* 54 */ NULL, NULL, NULL, NULL,
5389 /* 58 */ NULL, NULL, NULL, NULL,
5390 /* 5C */ NULL, NULL, NULL, NULL,
5391 /* 60 */ NULL, NULL, NULL, NULL,
5392 /* 64 */ NULL, NULL, NULL, NULL,
5393 /* 68 */ NULL, NULL, NULL, NULL,
5394 /* 6C */ NULL, NULL, NULL, NULL,
5395 /* 70 */ NULL, NULL, NULL, NULL,
5396 /* 74 */ NULL, NULL, NULL, NULL,
5397 /* 78 */ NULL, NULL, NULL, NULL,
5398 /* 7C */ NULL, NULL, NULL, NULL,
5399 /* 80 */ NULL, NULL, NULL, NULL,
5400 /* 84 */ NULL, NULL, NULL, NULL,
5401 /* 88 */ NULL, NULL, "pfnacc", NULL,
5402 /* 8C */ NULL, NULL, "pfpnacc", NULL,
5403 /* 90 */ "pfcmpge", NULL, NULL, NULL,
5404 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
5405 /* 98 */ NULL, NULL, "pfsub", NULL,
5406 /* 9C */ NULL, NULL, "pfadd", NULL,
5407 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
5408 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
5409 /* A8 */ NULL, NULL, "pfsubr", NULL,
5410 /* AC */ NULL, NULL, "pfacc", NULL,
5411 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
5412 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
5413 /* B8 */ NULL, NULL, NULL, "pswapd",
5414 /* BC */ NULL, NULL, NULL, "pavgusb",
5415 /* C0 */ NULL, NULL, NULL, NULL,
5416 /* C4 */ NULL, NULL, NULL, NULL,
5417 /* C8 */ NULL, NULL, NULL, NULL,
5418 /* CC */ NULL, NULL, NULL, NULL,
5419 /* D0 */ NULL, NULL, NULL, NULL,
5420 /* D4 */ NULL, NULL, NULL, NULL,
5421 /* D8 */ NULL, NULL, NULL, NULL,
5422 /* DC */ NULL, NULL, NULL, NULL,
5423 /* E0 */ NULL, NULL, NULL, NULL,
5424 /* E4 */ NULL, NULL, NULL, NULL,
5425 /* E8 */ NULL, NULL, NULL, NULL,
5426 /* EC */ NULL, NULL, NULL, NULL,
5427 /* F0 */ NULL, NULL, NULL, NULL,
5428 /* F4 */ NULL, NULL, NULL, NULL,
5429 /* F8 */ NULL, NULL, NULL, NULL,
5430 /* FC */ NULL, NULL, NULL, NULL,
5433 static void
5434 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5436 const char *mnemonic;
5438 FETCH_DATA (the_info, codep + 1);
5439 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5440 place where an 8-bit immediate would normally go. ie. the last
5441 byte of the instruction. */
5442 obufp = obuf + strlen (obuf);
5443 mnemonic = Suffix3DNow[*codep++ & 0xff];
5444 if (mnemonic)
5445 oappend (mnemonic);
5446 else
5448 /* Since a variable sized modrm/sib chunk is between the start
5449 of the opcode (0x0f0f) and the opcode suffix, we need to do
5450 all the modrm processing first, and don't know until now that
5451 we have a bad opcode. This necessitates some cleaning up. */
5452 op1out[0] = '\0';
5453 op2out[0] = '\0';
5454 BadOp ();
5458 static const char *simd_cmp_op[] = {
5459 "eq",
5460 "lt",
5461 "le",
5462 "unord",
5463 "neq",
5464 "nlt",
5465 "nle",
5466 "ord"
5469 static void
5470 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5472 unsigned int cmp_type;
5474 FETCH_DATA (the_info, codep + 1);
5475 obufp = obuf + strlen (obuf);
5476 cmp_type = *codep++ & 0xff;
5477 if (cmp_type < 8)
5479 char suffix1 = 'p', suffix2 = 's';
5480 used_prefixes |= (prefixes & PREFIX_REPZ);
5481 if (prefixes & PREFIX_REPZ)
5482 suffix1 = 's';
5483 else
5485 used_prefixes |= (prefixes & PREFIX_DATA);
5486 if (prefixes & PREFIX_DATA)
5487 suffix2 = 'd';
5488 else
5490 used_prefixes |= (prefixes & PREFIX_REPNZ);
5491 if (prefixes & PREFIX_REPNZ)
5492 suffix1 = 's', suffix2 = 'd';
5495 sprintf (scratchbuf, "cmp%s%c%c",
5496 simd_cmp_op[cmp_type], suffix1, suffix2);
5497 used_prefixes |= (prefixes & PREFIX_REPZ);
5498 oappend (scratchbuf);
5500 else
5502 /* We have a bad extension byte. Clean up. */
5503 op1out[0] = '\0';
5504 op2out[0] = '\0';
5505 BadOp ();
5509 static void
5510 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
5512 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5513 forms of these instructions. */
5514 if (mod == 3)
5516 char *p = obuf + strlen (obuf);
5517 *(p + 1) = '\0';
5518 *p = *(p - 1);
5519 *(p - 1) = *(p - 2);
5520 *(p - 2) = *(p - 3);
5521 *(p - 3) = extrachar;
5525 static void
5526 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5528 if (mod == 3 && reg == 1 && rm <= 1)
5530 /* Override "sidt". */
5531 size_t olen = strlen (obuf);
5532 char *p = obuf + olen - 4;
5533 const char **names = (address_mode == mode_64bit
5534 ? names64 : names32);
5536 /* We might have a suffix when disassembling with -Msuffix. */
5537 if (*p == 'i')
5538 --p;
5540 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5541 if (!intel_syntax
5542 && (prefixes & PREFIX_ADDR)
5543 && olen >= (4 + 7)
5544 && *(p - 1) == ' '
5545 && CONST_STRNEQ (p - 7, "addr")
5546 && (CONST_STRNEQ (p - 3, "16")
5547 || CONST_STRNEQ (p - 3, "32")))
5548 p -= 7;
5550 if (rm)
5552 /* mwait %eax,%ecx */
5553 strcpy (p, "mwait");
5554 if (!intel_syntax)
5555 strcpy (op1out, names[0]);
5557 else
5559 /* monitor %eax,%ecx,%edx" */
5560 strcpy (p, "monitor");
5561 if (!intel_syntax)
5563 const char **op1_names;
5564 if (!(prefixes & PREFIX_ADDR))
5565 op1_names = (address_mode == mode_16bit
5566 ? names16 : names);
5567 else
5569 op1_names = (address_mode != mode_32bit
5570 ? names32 : names16);
5571 used_prefixes |= PREFIX_ADDR;
5573 strcpy (op1out, op1_names[0]);
5574 strcpy (op3out, names[2]);
5577 if (!intel_syntax)
5579 strcpy (op2out, names[1]);
5580 two_source_ops = 1;
5583 codep++;
5585 else
5586 OP_M (0, sizeflag);
5589 static void
5590 SVME_Fixup (int bytemode, int sizeflag)
5592 const char *alt;
5593 char *p;
5595 switch (*codep)
5597 case 0xd8:
5598 alt = "vmrun";
5599 break;
5600 case 0xd9:
5601 alt = "vmmcall";
5602 break;
5603 case 0xda:
5604 alt = "vmload";
5605 break;
5606 case 0xdb:
5607 alt = "vmsave";
5608 break;
5609 case 0xdc:
5610 alt = "stgi";
5611 break;
5612 case 0xdd:
5613 alt = "clgi";
5614 break;
5615 case 0xde:
5616 alt = "skinit";
5617 break;
5618 case 0xdf:
5619 alt = "invlpga";
5620 break;
5621 default:
5622 OP_M (bytemode, sizeflag);
5623 return;
5625 /* Override "lidt". */
5626 p = obuf + strlen (obuf) - 4;
5627 /* We might have a suffix. */
5628 if (*p == 'i')
5629 --p;
5630 strcpy (p, alt);
5631 if (!(prefixes & PREFIX_ADDR))
5633 ++codep;
5634 return;
5636 used_prefixes |= PREFIX_ADDR;
5637 switch (*codep++)
5639 case 0xdf:
5640 strcpy (op2out, names32[1]);
5641 two_source_ops = 1;
5642 /* Fall through. */
5643 case 0xd8:
5644 case 0xda:
5645 case 0xdb:
5646 *obufp++ = open_char;
5647 if (address_mode == mode_64bit || (sizeflag & AFLAG))
5648 alt = names32[0];
5649 else
5650 alt = names16[0];
5651 strcpy (obufp, alt);
5652 obufp += strlen (alt);
5653 *obufp++ = close_char;
5654 *obufp = '\0';
5655 break;
5659 static void
5660 INVLPG_Fixup (int bytemode, int sizeflag)
5662 const char *alt;
5664 switch (*codep)
5666 case 0xf8:
5667 alt = "swapgs";
5668 break;
5669 case 0xf9:
5670 alt = "rdtscp";
5671 break;
5672 default:
5673 OP_M (bytemode, sizeflag);
5674 return;
5676 /* Override "invlpg". */
5677 strcpy (obuf + strlen (obuf) - 6, alt);
5678 codep++;
5681 static void
5682 BadOp (void)
5684 /* Throw away prefixes and 1st. opcode byte. */
5685 codep = insn_codep + 1;
5686 oappend ("(bad)");
5689 static void
5690 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5692 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
5694 /* Override "sgdt". */
5695 char *p = obuf + strlen (obuf) - 4;
5697 /* We might have a suffix when disassembling with -Msuffix. */
5698 if (*p == 'g')
5699 --p;
5701 switch (rm)
5703 case 1:
5704 strcpy (p, "vmcall");
5705 break;
5706 case 2:
5707 strcpy (p, "vmlaunch");
5708 break;
5709 case 3:
5710 strcpy (p, "vmresume");
5711 break;
5712 case 4:
5713 strcpy (p, "vmxoff");
5714 break;
5717 codep++;
5719 else
5720 OP_E (0, sizeflag);
5723 static void
5724 OP_VMX (int bytemode, int sizeflag)
5726 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
5727 if (prefixes & PREFIX_DATA)
5728 strcpy (obuf, "vmclear");
5729 else if (prefixes & PREFIX_REPZ)
5730 strcpy (obuf, "vmxon");
5731 else
5732 strcpy (obuf, "vmptrld");
5733 OP_E (bytemode, sizeflag);
5736 static void
5737 REP_Fixup (int bytemode, int sizeflag)
5739 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5740 lods and stos. */
5741 size_t ilen = 0;
5743 if (prefixes & PREFIX_REPZ)
5744 switch (*insn_codep)
5746 case 0x6e: /* outsb */
5747 case 0x6f: /* outsw/outsl */
5748 case 0xa4: /* movsb */
5749 case 0xa5: /* movsw/movsl/movsq */
5750 if (!intel_syntax)
5751 ilen = 5;
5752 else
5753 ilen = 4;
5754 break;
5755 case 0xaa: /* stosb */
5756 case 0xab: /* stosw/stosl/stosq */
5757 case 0xac: /* lodsb */
5758 case 0xad: /* lodsw/lodsl/lodsq */
5759 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5760 ilen = 5;
5761 else
5762 ilen = 4;
5763 break;
5764 case 0x6c: /* insb */
5765 case 0x6d: /* insl/insw */
5766 if (!intel_syntax)
5767 ilen = 4;
5768 else
5769 ilen = 3;
5770 break;
5771 default:
5772 abort ();
5773 break;
5776 if (ilen != 0)
5778 size_t olen;
5779 char *p;
5781 olen = strlen (obuf);
5782 p = obuf + olen - ilen - 1 - 4;
5783 /* Handle "repz [addr16|addr32]". */
5784 if ((prefixes & PREFIX_ADDR))
5785 p -= 1 + 6;
5787 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
5790 switch (bytemode)
5792 case al_reg:
5793 case eAX_reg:
5794 case indir_dx_reg:
5795 OP_IMREG (bytemode, sizeflag);
5796 break;
5797 case eDI_reg:
5798 OP_ESreg (bytemode, sizeflag);
5799 break;
5800 case eSI_reg:
5801 OP_DSreg (bytemode, sizeflag);
5802 break;
5803 default:
5804 abort ();
5805 break;
5809 static void
5810 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
5812 USED_REX (REX_MODE64);
5813 if (rex & REX_MODE64)
5815 /* Change cmpxchg8b to cmpxchg16b. */
5816 char *p = obuf + strlen (obuf) - 2;
5817 strcpy (p, "16b");
5818 bytemode = o_mode;
5820 OP_M (bytemode, sizeflag);