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