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