config.status: Pass extra parameters
[qemu/kevin.git] / disas / i386.c
blob894b0a1e0f133af6e805e18d2ffd201fcd285ea3
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 "qemu/cutils.h"
38 /* include/opcode/i386.h r1.78 */
40 /* opcode/i386.h -- Intel 80386 opcode macros
41 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
42 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
43 Free Software Foundation, Inc.
45 This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
47 This program is free software; you can redistribute it and/or modify
48 it under the terms of the GNU General Public License as published by
49 the Free Software Foundation; either version 2 of the License, or
50 (at your option) any later version.
52 This program is distributed in the hope that it will be useful,
53 but WITHOUT ANY WARRANTY; without even the implied warranty of
54 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 GNU General Public License for more details.
57 You should have received a copy of the GNU General Public License
58 along with this program; if not, see <http://www.gnu.org/licenses/>. */
60 /* The SystemV/386 SVR3.2 assembler, and probably all AT&T derived
61 ix86 Unix assemblers, generate floating point instructions with
62 reversed source and destination registers in certain cases.
63 Unfortunately, gcc and possibly many other programs use this
64 reversed syntax, so we're stuck with it.
66 eg. `fsub %st(3),%st' results in st = st - st(3) as expected, but
67 `fsub %st,%st(3)' results in st(3) = st - st(3), rather than
68 the expected st(3) = st(3) - st
70 This happens with all the non-commutative arithmetic floating point
71 operations with two register operands, where the source register is
72 %st, and destination register is %st(i).
74 The affected opcode map is dceX, dcfX, deeX, defX. */
76 #ifndef SYSV386_COMPAT
77 /* Set non-zero for broken, compatible instructions. Set to zero for
78 non-broken opcodes at your peril. gcc generates SystemV/386
79 compatible instructions. */
80 #define SYSV386_COMPAT 1
81 #endif
82 #ifndef OLDGCC_COMPAT
83 /* Set non-zero to cater for old (<= 2.8.1) versions of gcc that could
84 generate nonsense fsubp, fsubrp, fdivp and fdivrp with operands
85 reversed. */
86 #define OLDGCC_COMPAT SYSV386_COMPAT
87 #endif
89 #define MOV_AX_DISP32 0xa0
90 #define POP_SEG_SHORT 0x07
91 #define JUMP_PC_RELATIVE 0xeb
92 #define INT_OPCODE 0xcd
93 #define INT3_OPCODE 0xcc
94 /* The opcode for the fwait instruction, which disassembler treats as a
95 prefix when it can. */
96 #define FWAIT_OPCODE 0x9b
97 #define ADDR_PREFIX_OPCODE 0x67
98 #define DATA_PREFIX_OPCODE 0x66
99 #define LOCK_PREFIX_OPCODE 0xf0
100 #define CS_PREFIX_OPCODE 0x2e
101 #define DS_PREFIX_OPCODE 0x3e
102 #define ES_PREFIX_OPCODE 0x26
103 #define FS_PREFIX_OPCODE 0x64
104 #define GS_PREFIX_OPCODE 0x65
105 #define SS_PREFIX_OPCODE 0x36
106 #define REPNE_PREFIX_OPCODE 0xf2
107 #define REPE_PREFIX_OPCODE 0xf3
109 #define TWO_BYTE_OPCODE_ESCAPE 0x0f
110 #define NOP_OPCODE (char) 0x90
112 /* register numbers */
113 #define EBP_REG_NUM 5
114 #define ESP_REG_NUM 4
116 /* modrm_byte.regmem for twobyte escape */
117 #define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
118 /* index_base_byte.index for no index register addressing */
119 #define NO_INDEX_REGISTER ESP_REG_NUM
120 /* index_base_byte.base for no base register addressing */
121 #define NO_BASE_REGISTER EBP_REG_NUM
122 #define NO_BASE_REGISTER_16 6
124 /* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */
125 #define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */
126 #define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
128 /* x86-64 extension prefix. */
129 #define REX_OPCODE 0x40
131 /* Indicates 64 bit operand size. */
132 #define REX_W 8
133 /* High extension to reg field of modrm byte. */
134 #define REX_R 4
135 /* High extension to SIB index field. */
136 #define REX_X 2
137 /* High extension to base field of modrm or SIB, or reg field of opcode. */
138 #define REX_B 1
140 /* max operands per insn */
141 #define MAX_OPERANDS 4
143 /* max immediates per insn (lcall, ljmp, insertq, extrq) */
144 #define MAX_IMMEDIATE_OPERANDS 2
146 /* max memory refs per insn (string ops) */
147 #define MAX_MEMORY_OPERANDS 2
149 /* max size of insn mnemonics. */
150 #define MAX_MNEM_SIZE 16
152 /* max size of register name in insn mnemonics. */
153 #define MAX_REG_NAME_SIZE 8
155 /* opcodes/i386-dis.c r1.126 */
156 #include "qemu-common.h"
158 #include <setjmp.h>
160 static int fetch_data2(struct disassemble_info *, bfd_byte *);
161 static int fetch_data(struct disassemble_info *, bfd_byte *);
162 static void ckprefix (void);
163 static const char *prefix_name (int, int);
164 static int print_insn (bfd_vma, disassemble_info *);
165 static void dofloat (int);
166 static void OP_ST (int, int);
167 static void OP_STi (int, int);
168 static int putop (const char *, int);
169 static void oappend (const char *);
170 static void append_seg (void);
171 static void OP_indirE (int, int);
172 static void print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp);
173 static void print_displacement (char *, bfd_vma);
174 static void OP_E (int, int);
175 static void OP_G (int, int);
176 static void OP_vvvv (int, int);
177 static bfd_vma get64 (void);
178 static bfd_signed_vma get32 (void);
179 static bfd_signed_vma get32s (void);
180 static int get16 (void);
181 static void set_op (bfd_vma, int);
182 static void OP_REG (int, int);
183 static void OP_IMREG (int, int);
184 static void OP_I (int, int);
185 static void OP_I64 (int, int);
186 static void OP_sI (int, int);
187 static void OP_J (int, int);
188 static void OP_SEG (int, int);
189 static void OP_DIR (int, int);
190 static void OP_OFF (int, int);
191 static void OP_OFF64 (int, int);
192 static void ptr_reg (int, int);
193 static void OP_ESreg (int, int);
194 static void OP_DSreg (int, int);
195 static void OP_C (int, int);
196 static void OP_D (int, int);
197 static void OP_T (int, int);
198 static void OP_R (int, int);
199 static void OP_MMX (int, int);
200 static void OP_XMM (int, int);
201 static void OP_EM (int, int);
202 static void OP_EX (int, int);
203 static void OP_EMC (int,int);
204 static void OP_MXC (int,int);
205 static void OP_MS (int, int);
206 static void OP_XS (int, int);
207 static void OP_M (int, int);
208 static void OP_VMX (int, int);
209 static void OP_0fae (int, int);
210 static void OP_0f07 (int, int);
211 static void NOP_Fixup1 (int, int);
212 static void NOP_Fixup2 (int, int);
213 static void OP_3DNowSuffix (int, int);
214 static void OP_SIMD_Suffix (int, int);
215 static void SIMD_Fixup (int, int);
216 static void PNI_Fixup (int, int);
217 static void SVME_Fixup (int, int);
218 static void INVLPG_Fixup (int, int);
219 static void BadOp (void);
220 static void VMX_Fixup (int, int);
221 static void REP_Fixup (int, int);
222 static void CMPXCHG8B_Fixup (int, int);
223 static void XMM_Fixup (int, int);
224 static void CRC32_Fixup (int, int);
226 struct dis_private {
227 /* Points to first byte not fetched. */
228 bfd_byte *max_fetched;
229 bfd_byte the_buffer[MAX_MNEM_SIZE];
230 bfd_vma insn_start;
231 int orig_sizeflag;
232 sigjmp_buf bailout;
235 enum address_mode
237 mode_16bit,
238 mode_32bit,
239 mode_64bit
242 static enum address_mode address_mode;
244 /* Flags for the prefixes for the current instruction. See below. */
245 static int prefixes;
247 /* REX prefix the current instruction. See below. */
248 static int rex;
249 /* Bits of REX we've already used. */
250 static int rex_used;
251 /* Mark parts used in the REX prefix. When we are testing for
252 empty prefix (for 8bit register REX extension), just mask it
253 out. Otherwise test for REX bit is excuse for existence of REX
254 only in case value is nonzero. */
255 #define USED_REX(value) \
257 if (value) \
259 if ((rex & value)) \
260 rex_used |= (value) | REX_OPCODE; \
262 else \
263 rex_used |= REX_OPCODE; \
266 /* Flags for prefixes which we somehow handled when printing the
267 current instruction. */
268 static int used_prefixes;
270 /* The VEX.vvvv register, unencoded. */
271 static int vex_reg;
273 /* Flags stored in PREFIXES. */
274 #define PREFIX_REPZ 1
275 #define PREFIX_REPNZ 2
276 #define PREFIX_LOCK 4
277 #define PREFIX_CS 8
278 #define PREFIX_SS 0x10
279 #define PREFIX_DS 0x20
280 #define PREFIX_ES 0x40
281 #define PREFIX_FS 0x80
282 #define PREFIX_GS 0x100
283 #define PREFIX_DATA 0x200
284 #define PREFIX_ADDR 0x400
285 #define PREFIX_FWAIT 0x800
287 #define PREFIX_VEX_0F 0x1000
288 #define PREFIX_VEX_0F38 0x2000
289 #define PREFIX_VEX_0F3A 0x4000
291 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
292 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
293 on error. */
294 static int
295 fetch_data2(struct disassemble_info *info, bfd_byte *addr)
297 int status;
298 struct dis_private *priv = (struct dis_private *) info->private_data;
299 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
301 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
302 status = (*info->read_memory_func) (start,
303 priv->max_fetched,
304 addr - priv->max_fetched,
305 info);
306 else
307 status = -1;
308 if (status != 0)
310 /* If we did manage to read at least one byte, then
311 print_insn_i386 will do something sensible. Otherwise, print
312 an error. We do that here because this is where we know
313 STATUS. */
314 if (priv->max_fetched == priv->the_buffer)
315 (*info->memory_error_func) (status, start, info);
316 siglongjmp(priv->bailout, 1);
318 else
319 priv->max_fetched = addr;
320 return 1;
323 static int
324 fetch_data(struct disassemble_info *info, bfd_byte *addr)
326 if (addr <= ((struct dis_private *) (info->private_data))->max_fetched) {
327 return 1;
328 } else {
329 return fetch_data2(info, addr);
334 #define XX { NULL, 0 }
336 #define Bv { OP_vvvv, v_mode }
337 #define Eb { OP_E, b_mode }
338 #define Ev { OP_E, v_mode }
339 #define Ed { OP_E, d_mode }
340 #define Edq { OP_E, dq_mode }
341 #define Edqw { OP_E, dqw_mode }
342 #define Edqb { OP_E, dqb_mode }
343 #define Edqd { OP_E, dqd_mode }
344 #define indirEv { OP_indirE, stack_v_mode }
345 #define indirEp { OP_indirE, f_mode }
346 #define stackEv { OP_E, stack_v_mode }
347 #define Em { OP_E, m_mode }
348 #define Ew { OP_E, w_mode }
349 #define M { OP_M, 0 } /* lea, lgdt, etc. */
350 #define Ma { OP_M, v_mode }
351 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
352 #define Mq { OP_M, q_mode }
353 #define Gb { OP_G, b_mode }
354 #define Gv { OP_G, v_mode }
355 #define Gd { OP_G, d_mode }
356 #define Gdq { OP_G, dq_mode }
357 #define Gm { OP_G, m_mode }
358 #define Gw { OP_G, w_mode }
359 #define Rd { OP_R, d_mode }
360 #define Rm { OP_R, m_mode }
361 #define Ib { OP_I, b_mode }
362 #define sIb { OP_sI, b_mode } /* sign extended byte */
363 #define Iv { OP_I, v_mode }
364 #define Iq { OP_I, q_mode }
365 #define Iv64 { OP_I64, v_mode }
366 #define Iw { OP_I, w_mode }
367 #define I1 { OP_I, const_1_mode }
368 #define Jb { OP_J, b_mode }
369 #define Jv { OP_J, v_mode }
370 #define Cm { OP_C, m_mode }
371 #define Dm { OP_D, m_mode }
372 #define Td { OP_T, d_mode }
374 #define RMeAX { OP_REG, eAX_reg }
375 #define RMeBX { OP_REG, eBX_reg }
376 #define RMeCX { OP_REG, eCX_reg }
377 #define RMeDX { OP_REG, eDX_reg }
378 #define RMeSP { OP_REG, eSP_reg }
379 #define RMeBP { OP_REG, eBP_reg }
380 #define RMeSI { OP_REG, eSI_reg }
381 #define RMeDI { OP_REG, eDI_reg }
382 #define RMrAX { OP_REG, rAX_reg }
383 #define RMrBX { OP_REG, rBX_reg }
384 #define RMrCX { OP_REG, rCX_reg }
385 #define RMrDX { OP_REG, rDX_reg }
386 #define RMrSP { OP_REG, rSP_reg }
387 #define RMrBP { OP_REG, rBP_reg }
388 #define RMrSI { OP_REG, rSI_reg }
389 #define RMrDI { OP_REG, rDI_reg }
390 #define RMAL { OP_REG, al_reg }
391 #define RMAL { OP_REG, al_reg }
392 #define RMCL { OP_REG, cl_reg }
393 #define RMDL { OP_REG, dl_reg }
394 #define RMBL { OP_REG, bl_reg }
395 #define RMAH { OP_REG, ah_reg }
396 #define RMCH { OP_REG, ch_reg }
397 #define RMDH { OP_REG, dh_reg }
398 #define RMBH { OP_REG, bh_reg }
399 #define RMAX { OP_REG, ax_reg }
400 #define RMDX { OP_REG, dx_reg }
402 #define eAX { OP_IMREG, eAX_reg }
403 #define eBX { OP_IMREG, eBX_reg }
404 #define eCX { OP_IMREG, eCX_reg }
405 #define eDX { OP_IMREG, eDX_reg }
406 #define eSP { OP_IMREG, eSP_reg }
407 #define eBP { OP_IMREG, eBP_reg }
408 #define eSI { OP_IMREG, eSI_reg }
409 #define eDI { OP_IMREG, eDI_reg }
410 #define AL { OP_IMREG, al_reg }
411 #define CL { OP_IMREG, cl_reg }
412 #define DL { OP_IMREG, dl_reg }
413 #define BL { OP_IMREG, bl_reg }
414 #define AH { OP_IMREG, ah_reg }
415 #define CH { OP_IMREG, ch_reg }
416 #define DH { OP_IMREG, dh_reg }
417 #define BH { OP_IMREG, bh_reg }
418 #define AX { OP_IMREG, ax_reg }
419 #define DX { OP_IMREG, dx_reg }
420 #define zAX { OP_IMREG, z_mode_ax_reg }
421 #define indirDX { OP_IMREG, indir_dx_reg }
423 #define Sw { OP_SEG, w_mode }
424 #define Sv { OP_SEG, v_mode }
425 #define Ap { OP_DIR, 0 }
426 #define Ob { OP_OFF64, b_mode }
427 #define Ov { OP_OFF64, v_mode }
428 #define Xb { OP_DSreg, eSI_reg }
429 #define Xv { OP_DSreg, eSI_reg }
430 #define Xz { OP_DSreg, eSI_reg }
431 #define Yb { OP_ESreg, eDI_reg }
432 #define Yv { OP_ESreg, eDI_reg }
433 #define DSBX { OP_DSreg, eBX_reg }
435 #define es { OP_REG, es_reg }
436 #define ss { OP_REG, ss_reg }
437 #define cs { OP_REG, cs_reg }
438 #define ds { OP_REG, ds_reg }
439 #define fs { OP_REG, fs_reg }
440 #define gs { OP_REG, gs_reg }
442 #define MX { OP_MMX, 0 }
443 #define XM { OP_XMM, 0 }
444 #define EM { OP_EM, v_mode }
445 #define EMd { OP_EM, d_mode }
446 #define EMq { OP_EM, q_mode }
447 #define EXd { OP_EX, d_mode }
448 #define EXq { OP_EX, q_mode }
449 #define EXx { OP_EX, x_mode }
450 #define MS { OP_MS, v_mode }
451 #define XS { OP_XS, v_mode }
452 #define EMC { OP_EMC, v_mode }
453 #define MXC { OP_MXC, 0 }
454 #define VM { OP_VMX, q_mode }
455 #define OPSUF { OP_3DNowSuffix, 0 }
456 #define OPSIMD { OP_SIMD_Suffix, 0 }
457 #define XMM0 { XMM_Fixup, 0 }
459 /* Used handle "rep" prefix for string instructions. */
460 #define Xbr { REP_Fixup, eSI_reg }
461 #define Xvr { REP_Fixup, eSI_reg }
462 #define Ybr { REP_Fixup, eDI_reg }
463 #define Yvr { REP_Fixup, eDI_reg }
464 #define Yzr { REP_Fixup, eDI_reg }
465 #define indirDXr { REP_Fixup, indir_dx_reg }
466 #define ALr { REP_Fixup, al_reg }
467 #define eAXr { REP_Fixup, eAX_reg }
469 #define cond_jump_flag { NULL, cond_jump_mode }
470 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
472 /* bits in sizeflag */
473 #define SUFFIX_ALWAYS 4
474 #define AFLAG 2
475 #define DFLAG 1
477 #define b_mode 1 /* byte operand */
478 #define v_mode 2 /* operand size depends on prefixes */
479 #define w_mode 3 /* word operand */
480 #define d_mode 4 /* double word operand */
481 #define q_mode 5 /* quad word operand */
482 #define t_mode 6 /* ten-byte operand */
483 #define x_mode 7 /* 16-byte XMM operand */
484 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
485 #define cond_jump_mode 9
486 #define loop_jcxz_mode 10
487 #define dq_mode 11 /* operand size depends on REX prefixes. */
488 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
489 #define f_mode 13 /* 4- or 6-byte pointer operand */
490 #define const_1_mode 14
491 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
492 #define z_mode 16 /* non-quad operand size depends on prefixes */
493 #define o_mode 17 /* 16-byte operand */
494 #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */
495 #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */
497 #define es_reg 100
498 #define cs_reg 101
499 #define ss_reg 102
500 #define ds_reg 103
501 #define fs_reg 104
502 #define gs_reg 105
504 #define eAX_reg 108
505 #define eCX_reg 109
506 #define eDX_reg 110
507 #define eBX_reg 111
508 #define eSP_reg 112
509 #define eBP_reg 113
510 #define eSI_reg 114
511 #define eDI_reg 115
513 #define al_reg 116
514 #define cl_reg 117
515 #define dl_reg 118
516 #define bl_reg 119
517 #define ah_reg 120
518 #define ch_reg 121
519 #define dh_reg 122
520 #define bh_reg 123
522 #define ax_reg 124
523 #define cx_reg 125
524 #define dx_reg 126
525 #define bx_reg 127
526 #define sp_reg 128
527 #define bp_reg 129
528 #define si_reg 130
529 #define di_reg 131
531 #define rAX_reg 132
532 #define rCX_reg 133
533 #define rDX_reg 134
534 #define rBX_reg 135
535 #define rSP_reg 136
536 #define rBP_reg 137
537 #define rSI_reg 138
538 #define rDI_reg 139
540 #define z_mode_ax_reg 149
541 #define indir_dx_reg 150
543 #define FLOATCODE 1
544 #define USE_GROUPS 2
545 #define USE_PREFIX_USER_TABLE 3
546 #define X86_64_SPECIAL 4
547 #define IS_3BYTE_OPCODE 5
549 #define FLOAT NULL, { { NULL, FLOATCODE } }
551 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
552 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
553 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
554 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
555 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
556 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
557 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
558 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
559 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
560 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
561 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
562 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
563 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
564 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
565 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
566 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
567 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
568 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
569 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
570 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
571 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
572 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
573 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
574 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
575 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
576 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
577 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
578 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
580 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
581 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
582 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
583 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
584 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
585 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
586 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
587 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
588 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
589 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
590 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
591 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
592 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
593 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
594 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
595 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
596 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
597 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
598 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
599 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
600 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
601 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
602 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
603 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
604 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
605 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
606 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
607 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
608 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
609 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
610 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
611 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
612 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
613 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
614 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
615 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
616 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
617 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
618 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
619 #define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
620 #define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
621 #define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
622 #define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
623 #define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
624 #define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
625 #define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
626 #define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
627 #define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
628 #define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
629 #define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
630 #define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
631 #define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
632 #define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
633 #define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
634 #define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
635 #define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
636 #define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
637 #define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
638 #define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
639 #define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
640 #define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
641 #define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
642 #define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
643 #define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
644 #define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
645 #define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
646 #define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
647 #define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
648 #define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
649 #define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
650 #define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
651 #define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
652 #define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
653 #define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
654 #define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
655 #define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
656 #define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
657 #define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
658 #define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
659 #define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
660 #define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
661 #define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
662 #define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
663 #define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
664 #define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
665 #define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
666 #define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
667 #define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
668 #define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
669 #define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
670 #define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
671 #define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
672 #define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
673 #define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
674 #define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
675 #define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
676 #define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
677 #define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
678 #define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
679 #define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
680 #define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
681 #define PREGRP101 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 101 } }
682 #define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
683 #define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
684 #define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
685 #define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
686 #define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
688 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
689 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
690 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
691 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
693 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
694 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
696 typedef void (*op_rtn) (int bytemode, int sizeflag);
698 struct dis386 {
699 const char *name;
700 struct
702 op_rtn rtn;
703 int bytemode;
704 } op[MAX_OPERANDS];
707 /* Upper case letters in the instruction names here are macros.
708 'A' => print 'b' if no register operands or suffix_always is true
709 'B' => print 'b' if suffix_always is true
710 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
711 . size prefix
712 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
713 . suffix_always is true
714 'E' => print 'e' if 32-bit form of jcxz
715 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
716 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
717 'H' => print ",pt" or ",pn" branch hint
718 'I' => honor following macro letter even in Intel mode (implemented only
719 . for some of the macro letters)
720 'J' => print 'l'
721 'K' => print 'd' or 'q' if rex prefix is present.
722 'L' => print 'l' if suffix_always is true
723 'N' => print 'n' if instruction has no wait "prefix"
724 'O' => print 'd' or 'o' (or 'q' in Intel mode)
725 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
726 . or suffix_always is true. print 'q' if rex prefix is present.
727 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
728 . is true
729 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
730 'S' => print 'w', 'l' or 'q' if suffix_always is true
731 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
732 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
733 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
734 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
735 'X' => print 's', 'd' depending on data16 prefix (for XMM)
736 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
737 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
739 Many of the above letters print nothing in Intel mode. See "putop"
740 for the details.
742 Braces '{' and '}', and vertical bars '|', indicate alternative
743 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
744 modes. In cases where there are only two alternatives, the X86_64
745 instruction is reserved, and "(bad)" is printed.
748 static const struct dis386 dis386[] = {
749 /* 00 */
750 { "addB", { Eb, Gb } },
751 { "addS", { Ev, Gv } },
752 { "addB", { Gb, Eb } },
753 { "addS", { Gv, Ev } },
754 { "addB", { AL, Ib } },
755 { "addS", { eAX, Iv } },
756 { "push{T|}", { es } },
757 { "pop{T|}", { es } },
758 /* 08 */
759 { "orB", { Eb, Gb } },
760 { "orS", { Ev, Gv } },
761 { "orB", { Gb, Eb } },
762 { "orS", { Gv, Ev } },
763 { "orB", { AL, Ib } },
764 { "orS", { eAX, Iv } },
765 { "push{T|}", { cs } },
766 { "(bad)", { XX } }, /* 0x0f extended opcode escape */
767 /* 10 */
768 { "adcB", { Eb, Gb } },
769 { "adcS", { Ev, Gv } },
770 { "adcB", { Gb, Eb } },
771 { "adcS", { Gv, Ev } },
772 { "adcB", { AL, Ib } },
773 { "adcS", { eAX, Iv } },
774 { "push{T|}", { ss } },
775 { "pop{T|}", { ss } },
776 /* 18 */
777 { "sbbB", { Eb, Gb } },
778 { "sbbS", { Ev, Gv } },
779 { "sbbB", { Gb, Eb } },
780 { "sbbS", { Gv, Ev } },
781 { "sbbB", { AL, Ib } },
782 { "sbbS", { eAX, Iv } },
783 { "push{T|}", { ds } },
784 { "pop{T|}", { ds } },
785 /* 20 */
786 { "andB", { Eb, Gb } },
787 { "andS", { Ev, Gv } },
788 { "andB", { Gb, Eb } },
789 { "andS", { Gv, Ev } },
790 { "andB", { AL, Ib } },
791 { "andS", { eAX, Iv } },
792 { "(bad)", { XX } }, /* SEG ES prefix */
793 { "daa{|}", { XX } },
794 /* 28 */
795 { "subB", { Eb, Gb } },
796 { "subS", { Ev, Gv } },
797 { "subB", { Gb, Eb } },
798 { "subS", { Gv, Ev } },
799 { "subB", { AL, Ib } },
800 { "subS", { eAX, Iv } },
801 { "(bad)", { XX } }, /* SEG CS prefix */
802 { "das{|}", { XX } },
803 /* 30 */
804 { "xorB", { Eb, Gb } },
805 { "xorS", { Ev, Gv } },
806 { "xorB", { Gb, Eb } },
807 { "xorS", { Gv, Ev } },
808 { "xorB", { AL, Ib } },
809 { "xorS", { eAX, Iv } },
810 { "(bad)", { XX } }, /* SEG SS prefix */
811 { "aaa{|}", { XX } },
812 /* 38 */
813 { "cmpB", { Eb, Gb } },
814 { "cmpS", { Ev, Gv } },
815 { "cmpB", { Gb, Eb } },
816 { "cmpS", { Gv, Ev } },
817 { "cmpB", { AL, Ib } },
818 { "cmpS", { eAX, Iv } },
819 { "(bad)", { XX } }, /* SEG DS prefix */
820 { "aas{|}", { XX } },
821 /* 40 */
822 { "inc{S|}", { RMeAX } },
823 { "inc{S|}", { RMeCX } },
824 { "inc{S|}", { RMeDX } },
825 { "inc{S|}", { RMeBX } },
826 { "inc{S|}", { RMeSP } },
827 { "inc{S|}", { RMeBP } },
828 { "inc{S|}", { RMeSI } },
829 { "inc{S|}", { RMeDI } },
830 /* 48 */
831 { "dec{S|}", { RMeAX } },
832 { "dec{S|}", { RMeCX } },
833 { "dec{S|}", { RMeDX } },
834 { "dec{S|}", { RMeBX } },
835 { "dec{S|}", { RMeSP } },
836 { "dec{S|}", { RMeBP } },
837 { "dec{S|}", { RMeSI } },
838 { "dec{S|}", { RMeDI } },
839 /* 50 */
840 { "pushV", { RMrAX } },
841 { "pushV", { RMrCX } },
842 { "pushV", { RMrDX } },
843 { "pushV", { RMrBX } },
844 { "pushV", { RMrSP } },
845 { "pushV", { RMrBP } },
846 { "pushV", { RMrSI } },
847 { "pushV", { RMrDI } },
848 /* 58 */
849 { "popV", { RMrAX } },
850 { "popV", { RMrCX } },
851 { "popV", { RMrDX } },
852 { "popV", { RMrBX } },
853 { "popV", { RMrSP } },
854 { "popV", { RMrBP } },
855 { "popV", { RMrSI } },
856 { "popV", { RMrDI } },
857 /* 60 */
858 { X86_64_0 },
859 { X86_64_1 },
860 { X86_64_2 },
861 { X86_64_3 },
862 { "(bad)", { XX } }, /* seg fs */
863 { "(bad)", { XX } }, /* seg gs */
864 { "(bad)", { XX } }, /* op size prefix */
865 { "(bad)", { XX } }, /* adr size prefix */
866 /* 68 */
867 { "pushT", { Iq } },
868 { "imulS", { Gv, Ev, Iv } },
869 { "pushT", { sIb } },
870 { "imulS", { Gv, Ev, sIb } },
871 { "ins{b||b|}", { Ybr, indirDX } },
872 { "ins{R||G|}", { Yzr, indirDX } },
873 { "outs{b||b|}", { indirDXr, Xb } },
874 { "outs{R||G|}", { indirDXr, Xz } },
875 /* 70 */
876 { "joH", { Jb, XX, cond_jump_flag } },
877 { "jnoH", { Jb, XX, cond_jump_flag } },
878 { "jbH", { Jb, XX, cond_jump_flag } },
879 { "jaeH", { Jb, XX, cond_jump_flag } },
880 { "jeH", { Jb, XX, cond_jump_flag } },
881 { "jneH", { Jb, XX, cond_jump_flag } },
882 { "jbeH", { Jb, XX, cond_jump_flag } },
883 { "jaH", { Jb, XX, cond_jump_flag } },
884 /* 78 */
885 { "jsH", { Jb, XX, cond_jump_flag } },
886 { "jnsH", { Jb, XX, cond_jump_flag } },
887 { "jpH", { Jb, XX, cond_jump_flag } },
888 { "jnpH", { Jb, XX, cond_jump_flag } },
889 { "jlH", { Jb, XX, cond_jump_flag } },
890 { "jgeH", { Jb, XX, cond_jump_flag } },
891 { "jleH", { Jb, XX, cond_jump_flag } },
892 { "jgH", { Jb, XX, cond_jump_flag } },
893 /* 80 */
894 { GRP1b },
895 { GRP1S },
896 { "(bad)", { XX } },
897 { GRP1Ss },
898 { "testB", { Eb, Gb } },
899 { "testS", { Ev, Gv } },
900 { "xchgB", { Eb, Gb } },
901 { "xchgS", { Ev, Gv } },
902 /* 88 */
903 { "movB", { Eb, Gb } },
904 { "movS", { Ev, Gv } },
905 { "movB", { Gb, Eb } },
906 { "movS", { Gv, Ev } },
907 { "movD", { Sv, Sw } },
908 { "leaS", { Gv, M } },
909 { "movD", { Sw, Sv } },
910 { GRP1a },
911 /* 90 */
912 { PREGRP38 },
913 { "xchgS", { RMeCX, eAX } },
914 { "xchgS", { RMeDX, eAX } },
915 { "xchgS", { RMeBX, eAX } },
916 { "xchgS", { RMeSP, eAX } },
917 { "xchgS", { RMeBP, eAX } },
918 { "xchgS", { RMeSI, eAX } },
919 { "xchgS", { RMeDI, eAX } },
920 /* 98 */
921 { "cW{t||t|}R", { XX } },
922 { "cR{t||t|}O", { XX } },
923 { "Jcall{T|}", { Ap } },
924 { "(bad)", { XX } }, /* fwait */
925 { "pushfT", { XX } },
926 { "popfT", { XX } },
927 { "sahf{|}", { XX } },
928 { "lahf{|}", { XX } },
929 /* a0 */
930 { "movB", { AL, Ob } },
931 { "movS", { eAX, Ov } },
932 { "movB", { Ob, AL } },
933 { "movS", { Ov, eAX } },
934 { "movs{b||b|}", { Ybr, Xb } },
935 { "movs{R||R|}", { Yvr, Xv } },
936 { "cmps{b||b|}", { Xb, Yb } },
937 { "cmps{R||R|}", { Xv, Yv } },
938 /* a8 */
939 { "testB", { AL, Ib } },
940 { "testS", { eAX, Iv } },
941 { "stosB", { Ybr, AL } },
942 { "stosS", { Yvr, eAX } },
943 { "lodsB", { ALr, Xb } },
944 { "lodsS", { eAXr, Xv } },
945 { "scasB", { AL, Yb } },
946 { "scasS", { eAX, Yv } },
947 /* b0 */
948 { "movB", { RMAL, Ib } },
949 { "movB", { RMCL, Ib } },
950 { "movB", { RMDL, Ib } },
951 { "movB", { RMBL, Ib } },
952 { "movB", { RMAH, Ib } },
953 { "movB", { RMCH, Ib } },
954 { "movB", { RMDH, Ib } },
955 { "movB", { RMBH, Ib } },
956 /* b8 */
957 { "movS", { RMeAX, Iv64 } },
958 { "movS", { RMeCX, Iv64 } },
959 { "movS", { RMeDX, Iv64 } },
960 { "movS", { RMeBX, Iv64 } },
961 { "movS", { RMeSP, Iv64 } },
962 { "movS", { RMeBP, Iv64 } },
963 { "movS", { RMeSI, Iv64 } },
964 { "movS", { RMeDI, Iv64 } },
965 /* c0 */
966 { GRP2b },
967 { GRP2S },
968 { "retT", { Iw } },
969 { "retT", { XX } },
970 { "les{S|}", { Gv, Mp } },
971 { "ldsS", { Gv, Mp } },
972 { GRP11_C6 },
973 { GRP11_C7 },
974 /* c8 */
975 { "enterT", { Iw, Ib } },
976 { "leaveT", { XX } },
977 { "lretP", { Iw } },
978 { "lretP", { XX } },
979 { "int3", { XX } },
980 { "int", { Ib } },
981 { "into{|}", { XX } },
982 { "iretP", { XX } },
983 /* d0 */
984 { GRP2b_one },
985 { GRP2S_one },
986 { GRP2b_cl },
987 { GRP2S_cl },
988 { "aam{|}", { sIb } },
989 { "aad{|}", { sIb } },
990 { "(bad)", { XX } },
991 { "xlat", { DSBX } },
992 /* d8 */
993 { FLOAT },
994 { FLOAT },
995 { FLOAT },
996 { FLOAT },
997 { FLOAT },
998 { FLOAT },
999 { FLOAT },
1000 { FLOAT },
1001 /* e0 */
1002 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
1003 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
1004 { "loopFH", { Jb, XX, loop_jcxz_flag } },
1005 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
1006 { "inB", { AL, Ib } },
1007 { "inG", { zAX, Ib } },
1008 { "outB", { Ib, AL } },
1009 { "outG", { Ib, zAX } },
1010 /* e8 */
1011 { "callT", { Jv } },
1012 { "jmpT", { Jv } },
1013 { "Jjmp{T|}", { Ap } },
1014 { "jmp", { Jb } },
1015 { "inB", { AL, indirDX } },
1016 { "inG", { zAX, indirDX } },
1017 { "outB", { indirDX, AL } },
1018 { "outG", { indirDX, zAX } },
1019 /* f0 */
1020 { "(bad)", { XX } }, /* lock prefix */
1021 { "icebp", { XX } },
1022 { "(bad)", { XX } }, /* repne */
1023 { "(bad)", { XX } }, /* repz */
1024 { "hlt", { XX } },
1025 { "cmc", { XX } },
1026 { GRP3b },
1027 { GRP3S },
1028 /* f8 */
1029 { "clc", { XX } },
1030 { "stc", { XX } },
1031 { "cli", { XX } },
1032 { "sti", { XX } },
1033 { "cld", { XX } },
1034 { "std", { XX } },
1035 { GRP4 },
1036 { GRP5 },
1039 static const struct dis386 dis386_twobyte[] = {
1040 /* 00 */
1041 { GRP6 },
1042 { GRP7 },
1043 { "larS", { Gv, Ew } },
1044 { "lslS", { Gv, Ew } },
1045 { "(bad)", { XX } },
1046 { "syscall", { XX } },
1047 { "clts", { XX } },
1048 { "sysretP", { XX } },
1049 /* 08 */
1050 { "invd", { XX } },
1051 { "wbinvd", { XX } },
1052 { "(bad)", { XX } },
1053 { "ud2a", { XX } },
1054 { "(bad)", { XX } },
1055 { GRPAMD },
1056 { "femms", { XX } },
1057 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
1058 /* 10 */
1059 { PREGRP8 },
1060 { PREGRP9 },
1061 { PREGRP30 },
1062 { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } },
1063 { "unpcklpX", { XM, EXq } },
1064 { "unpckhpX", { XM, EXq } },
1065 { PREGRP31 },
1066 { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } },
1067 /* 18 */
1068 { GRP16 },
1069 { "(bad)", { XX } },
1070 { "(bad)", { XX } },
1071 { "(bad)", { XX } },
1072 { "(bad)", { XX } },
1073 { "(bad)", { XX } },
1074 { "(bad)", { XX } },
1075 { "nopQ", { Ev } },
1076 /* 20 */
1077 { "movZ", { Rm, Cm } },
1078 { "movZ", { Rm, Dm } },
1079 { "movZ", { Cm, Rm } },
1080 { "movZ", { Dm, Rm } },
1081 { "movL", { Rd, Td } },
1082 { "(bad)", { XX } },
1083 { "movL", { Td, Rd } },
1084 { "(bad)", { XX } },
1085 /* 28 */
1086 { "movapX", { XM, EXx } },
1087 { "movapX", { EXx, XM } },
1088 { PREGRP2 },
1089 { PREGRP33 },
1090 { PREGRP4 },
1091 { PREGRP3 },
1092 { PREGRP93 },
1093 { PREGRP94 },
1094 /* 30 */
1095 { "wrmsr", { XX } },
1096 { "rdtsc", { XX } },
1097 { "rdmsr", { XX } },
1098 { "rdpmc", { XX } },
1099 { "sysenter", { XX } },
1100 { "sysexit", { XX } },
1101 { "(bad)", { XX } },
1102 { "(bad)", { XX } },
1103 /* 38 */
1104 { THREE_BYTE_0 },
1105 { "(bad)", { XX } },
1106 { THREE_BYTE_1 },
1107 { "(bad)", { XX } },
1108 { "(bad)", { XX } },
1109 { "(bad)", { XX } },
1110 { "(bad)", { XX } },
1111 { "(bad)", { XX } },
1112 /* 40 */
1113 { "cmovo", { Gv, Ev } },
1114 { "cmovno", { Gv, Ev } },
1115 { "cmovb", { Gv, Ev } },
1116 { "cmovae", { Gv, Ev } },
1117 { "cmove", { Gv, Ev } },
1118 { "cmovne", { Gv, Ev } },
1119 { "cmovbe", { Gv, Ev } },
1120 { "cmova", { Gv, Ev } },
1121 /* 48 */
1122 { "cmovs", { Gv, Ev } },
1123 { "cmovns", { Gv, Ev } },
1124 { "cmovp", { Gv, Ev } },
1125 { "cmovnp", { Gv, Ev } },
1126 { "cmovl", { Gv, Ev } },
1127 { "cmovge", { Gv, Ev } },
1128 { "cmovle", { Gv, Ev } },
1129 { "cmovg", { Gv, Ev } },
1130 /* 50 */
1131 { "movmskpX", { Gdq, XS } },
1132 { PREGRP13 },
1133 { PREGRP12 },
1134 { PREGRP11 },
1135 { "andpX", { XM, EXx } },
1136 { "andnpX", { XM, EXx } },
1137 { "orpX", { XM, EXx } },
1138 { "xorpX", { XM, EXx } },
1139 /* 58 */
1140 { PREGRP0 },
1141 { PREGRP10 },
1142 { PREGRP17 },
1143 { PREGRP16 },
1144 { PREGRP14 },
1145 { PREGRP7 },
1146 { PREGRP5 },
1147 { PREGRP6 },
1148 /* 60 */
1149 { PREGRP95 },
1150 { PREGRP96 },
1151 { PREGRP97 },
1152 { "packsswb", { MX, EM } },
1153 { "pcmpgtb", { MX, EM } },
1154 { "pcmpgtw", { MX, EM } },
1155 { "pcmpgtd", { MX, EM } },
1156 { "packuswb", { MX, EM } },
1157 /* 68 */
1158 { "punpckhbw", { MX, EM } },
1159 { "punpckhwd", { MX, EM } },
1160 { "punpckhdq", { MX, EM } },
1161 { "packssdw", { MX, EM } },
1162 { PREGRP26 },
1163 { PREGRP24 },
1164 { "movd", { MX, Edq } },
1165 { PREGRP19 },
1166 /* 70 */
1167 { PREGRP22 },
1168 { GRP12 },
1169 { GRP13 },
1170 { GRP14 },
1171 { "pcmpeqb", { MX, EM } },
1172 { "pcmpeqw", { MX, EM } },
1173 { "pcmpeqd", { MX, EM } },
1174 { "emms", { XX } },
1175 /* 78 */
1176 { PREGRP34 },
1177 { PREGRP35 },
1178 { "(bad)", { XX } },
1179 { "(bad)", { XX } },
1180 { PREGRP28 },
1181 { PREGRP29 },
1182 { PREGRP23 },
1183 { PREGRP20 },
1184 /* 80 */
1185 { "joH", { Jv, XX, cond_jump_flag } },
1186 { "jnoH", { Jv, XX, cond_jump_flag } },
1187 { "jbH", { Jv, XX, cond_jump_flag } },
1188 { "jaeH", { Jv, XX, cond_jump_flag } },
1189 { "jeH", { Jv, XX, cond_jump_flag } },
1190 { "jneH", { Jv, XX, cond_jump_flag } },
1191 { "jbeH", { Jv, XX, cond_jump_flag } },
1192 { "jaH", { Jv, XX, cond_jump_flag } },
1193 /* 88 */
1194 { "jsH", { Jv, XX, cond_jump_flag } },
1195 { "jnsH", { Jv, XX, cond_jump_flag } },
1196 { "jpH", { Jv, XX, cond_jump_flag } },
1197 { "jnpH", { Jv, XX, cond_jump_flag } },
1198 { "jlH", { Jv, XX, cond_jump_flag } },
1199 { "jgeH", { Jv, XX, cond_jump_flag } },
1200 { "jleH", { Jv, XX, cond_jump_flag } },
1201 { "jgH", { Jv, XX, cond_jump_flag } },
1202 /* 90 */
1203 { "seto", { Eb } },
1204 { "setno", { Eb } },
1205 { "setb", { Eb } },
1206 { "setae", { Eb } },
1207 { "sete", { Eb } },
1208 { "setne", { Eb } },
1209 { "setbe", { Eb } },
1210 { "seta", { Eb } },
1211 /* 98 */
1212 { "sets", { Eb } },
1213 { "setns", { Eb } },
1214 { "setp", { Eb } },
1215 { "setnp", { Eb } },
1216 { "setl", { Eb } },
1217 { "setge", { Eb } },
1218 { "setle", { Eb } },
1219 { "setg", { Eb } },
1220 /* a0 */
1221 { "pushT", { fs } },
1222 { "popT", { fs } },
1223 { "cpuid", { XX } },
1224 { "btS", { Ev, Gv } },
1225 { "shldS", { Ev, Gv, Ib } },
1226 { "shldS", { Ev, Gv, CL } },
1227 { GRPPADLCK2 },
1228 { GRPPADLCK1 },
1229 /* a8 */
1230 { "pushT", { gs } },
1231 { "popT", { gs } },
1232 { "rsm", { XX } },
1233 { "btsS", { Ev, Gv } },
1234 { "shrdS", { Ev, Gv, Ib } },
1235 { "shrdS", { Ev, Gv, CL } },
1236 { GRP15 },
1237 { "imulS", { Gv, Ev } },
1238 /* b0 */
1239 { "cmpxchgB", { Eb, Gb } },
1240 { "cmpxchgS", { Ev, Gv } },
1241 { "lssS", { Gv, Mp } },
1242 { "btrS", { Ev, Gv } },
1243 { "lfsS", { Gv, Mp } },
1244 { "lgsS", { Gv, Mp } },
1245 { "movz{bR|x|bR|x}", { Gv, Eb } },
1246 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
1247 /* b8 */
1248 { PREGRP37 },
1249 { "ud2b", { XX } },
1250 { GRP8 },
1251 { "btcS", { Ev, Gv } },
1252 { "bsfS", { Gv, Ev } },
1253 { PREGRP36 },
1254 { "movs{bR|x|bR|x}", { Gv, Eb } },
1255 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
1256 /* c0 */
1257 { "xaddB", { Eb, Gb } },
1258 { "xaddS", { Ev, Gv } },
1259 { PREGRP1 },
1260 { "movntiS", { Ev, Gv } },
1261 { "pinsrw", { MX, Edqw, Ib } },
1262 { "pextrw", { Gdq, MS, Ib } },
1263 { "shufpX", { XM, EXx, Ib } },
1264 { GRP9 },
1265 /* c8 */
1266 { "bswap", { RMeAX } },
1267 { "bswap", { RMeCX } },
1268 { "bswap", { RMeDX } },
1269 { "bswap", { RMeBX } },
1270 { "bswap", { RMeSP } },
1271 { "bswap", { RMeBP } },
1272 { "bswap", { RMeSI } },
1273 { "bswap", { RMeDI } },
1274 /* d0 */
1275 { PREGRP27 },
1276 { "psrlw", { MX, EM } },
1277 { "psrld", { MX, EM } },
1278 { "psrlq", { MX, EM } },
1279 { "paddq", { MX, EM } },
1280 { "pmullw", { MX, EM } },
1281 { PREGRP21 },
1282 { "pmovmskb", { Gdq, MS } },
1283 /* d8 */
1284 { "psubusb", { MX, EM } },
1285 { "psubusw", { MX, EM } },
1286 { "pminub", { MX, EM } },
1287 { "pand", { MX, EM } },
1288 { "paddusb", { MX, EM } },
1289 { "paddusw", { MX, EM } },
1290 { "pmaxub", { MX, EM } },
1291 { "pandn", { MX, EM } },
1292 /* e0 */
1293 { "pavgb", { MX, EM } },
1294 { "psraw", { MX, EM } },
1295 { "psrad", { MX, EM } },
1296 { "pavgw", { MX, EM } },
1297 { "pmulhuw", { MX, EM } },
1298 { "pmulhw", { MX, EM } },
1299 { PREGRP15 },
1300 { PREGRP25 },
1301 /* e8 */
1302 { "psubsb", { MX, EM } },
1303 { "psubsw", { MX, EM } },
1304 { "pminsw", { MX, EM } },
1305 { "por", { MX, EM } },
1306 { "paddsb", { MX, EM } },
1307 { "paddsw", { MX, EM } },
1308 { "pmaxsw", { MX, EM } },
1309 { "pxor", { MX, EM } },
1310 /* f0 */
1311 { PREGRP32 },
1312 { "psllw", { MX, EM } },
1313 { "pslld", { MX, EM } },
1314 { "psllq", { MX, EM } },
1315 { "pmuludq", { MX, EM } },
1316 { "pmaddwd", { MX, EM } },
1317 { "psadbw", { MX, EM } },
1318 { PREGRP18 },
1319 /* f8 */
1320 { "psubb", { MX, EM } },
1321 { "psubw", { MX, EM } },
1322 { "psubd", { MX, EM } },
1323 { "psubq", { MX, EM } },
1324 { "paddb", { MX, EM } },
1325 { "paddw", { MX, EM } },
1326 { "paddd", { MX, EM } },
1327 { "(bad)", { XX } },
1330 static const unsigned char onebyte_has_modrm[256] = {
1331 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1332 /* ------------------------------- */
1333 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1334 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1335 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1336 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1337 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1338 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1339 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1340 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1341 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1342 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1343 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1344 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1345 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1346 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1347 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1348 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1349 /* ------------------------------- */
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1353 static const unsigned char twobyte_has_modrm[256] = {
1354 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1355 /* ------------------------------- */
1356 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1357 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1358 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1359 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1360 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1361 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1362 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1363 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1364 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1365 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1366 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1367 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1368 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1369 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1370 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1371 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1372 /* ------------------------------- */
1373 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1376 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1377 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1378 /* ------------------------------- */
1379 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1380 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1381 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1382 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1383 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1384 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1385 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1386 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1387 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1388 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1389 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1390 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1391 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1392 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1393 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1394 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1395 /* ------------------------------- */
1396 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1399 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1400 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1401 /* ------------------------------- */
1402 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1403 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1404 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1405 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1406 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1407 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1408 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1409 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1410 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1411 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1412 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1413 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1414 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1415 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1416 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1417 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1418 /* ------------------------------- */
1419 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1422 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1423 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1424 /* ------------------------------- */
1425 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1426 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1427 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1428 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1429 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1430 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1431 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1432 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1433 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1434 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1435 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1436 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1437 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1438 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1439 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1440 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1441 /* ------------------------------- */
1442 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1445 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1446 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1447 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1448 /* ------------------------------- */
1449 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1450 /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
1451 /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
1452 /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
1453 /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1454 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1455 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1456 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1457 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1458 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1459 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1460 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1461 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1462 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
1463 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1464 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1465 /* ------------------------------- */
1466 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1469 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1470 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1471 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1472 /* ------------------------------- */
1473 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1474 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1475 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1476 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1477 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1478 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1479 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1480 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1481 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1482 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1483 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1484 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1485 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1486 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1487 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1488 /* f0 */ 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1489 /* ------------------------------- */
1490 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1493 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1494 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1495 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1496 /* ------------------------------- */
1497 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1498 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1499 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1500 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1501 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1502 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1503 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1504 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1505 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1506 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1507 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1508 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1509 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1510 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1511 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1512 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
1513 /* ------------------------------- */
1514 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1517 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1518 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1519 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1520 /* ------------------------------- */
1521 /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
1522 /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
1523 /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1524 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1525 /* 40 */ 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1526 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1527 /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1528 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1529 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1530 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1531 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1532 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1533 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1534 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* df */
1535 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1536 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1537 /* ------------------------------- */
1538 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1541 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1542 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1543 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1544 /* ------------------------------- */
1545 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1546 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1547 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1548 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1549 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1550 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1551 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1552 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1553 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1554 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1555 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1556 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1557 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1558 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1559 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1560 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1561 /* ------------------------------- */
1562 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1565 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1566 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1567 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1568 /* ------------------------------- */
1569 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1570 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1571 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1572 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1573 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1574 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1575 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1576 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1577 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1578 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1579 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1580 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1581 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1582 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1583 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1584 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1585 /* ------------------------------- */
1586 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1589 static char obuf[100];
1590 static char *obufp;
1591 static char scratchbuf[100];
1592 static unsigned char *start_codep;
1593 static unsigned char *insn_codep;
1594 static unsigned char *codep;
1595 static disassemble_info *the_info;
1596 static struct
1598 int mod;
1599 int reg;
1600 int rm;
1602 modrm;
1603 static unsigned char need_modrm;
1605 /* If we are accessing mod/rm/reg without need_modrm set, then the
1606 values are stale. Hitting this abort likely indicates that you
1607 need to update onebyte_has_modrm or twobyte_has_modrm. */
1608 #define MODRM_CHECK if (!need_modrm) abort ()
1610 static const char * const *names64;
1611 static const char * const *names32;
1612 static const char * const *names16;
1613 static const char * const *names8;
1614 static const char * const *names8rex;
1615 static const char * const *names_seg;
1616 static const char * const *index16;
1618 static const char * const intel_names64[] = {
1619 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1620 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1622 static const char * const intel_names32[] = {
1623 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1624 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1626 static const char * const intel_names16[] = {
1627 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1628 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1630 static const char * const intel_names8[] = {
1631 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1633 static const char * const intel_names8rex[] = {
1634 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1635 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1637 static const char * const intel_names_seg[] = {
1638 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1640 static const char * const intel_index16[] = {
1641 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1644 static const char * const att_names64[] = {
1645 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1646 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1648 static const char * const att_names32[] = {
1649 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1650 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1652 static const char * const att_names16[] = {
1653 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1654 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1656 static const char * const att_names8[] = {
1657 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1659 static const char * const att_names8rex[] = {
1660 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1661 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1663 static const char * const att_names_seg[] = {
1664 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1666 static const char * const att_index16[] = {
1667 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1670 static const struct dis386 grps[][8] = {
1671 /* GRP1a */
1673 { "popU", { stackEv } },
1674 { "(bad)", { XX } },
1675 { "(bad)", { XX } },
1676 { "(bad)", { XX } },
1677 { "(bad)", { XX } },
1678 { "(bad)", { XX } },
1679 { "(bad)", { XX } },
1680 { "(bad)", { XX } },
1682 /* GRP1b */
1684 { "addA", { Eb, Ib } },
1685 { "orA", { Eb, Ib } },
1686 { "adcA", { Eb, Ib } },
1687 { "sbbA", { Eb, Ib } },
1688 { "andA", { Eb, Ib } },
1689 { "subA", { Eb, Ib } },
1690 { "xorA", { Eb, Ib } },
1691 { "cmpA", { Eb, Ib } },
1693 /* GRP1S */
1695 { "addQ", { Ev, Iv } },
1696 { "orQ", { Ev, Iv } },
1697 { "adcQ", { Ev, Iv } },
1698 { "sbbQ", { Ev, Iv } },
1699 { "andQ", { Ev, Iv } },
1700 { "subQ", { Ev, Iv } },
1701 { "xorQ", { Ev, Iv } },
1702 { "cmpQ", { Ev, Iv } },
1704 /* GRP1Ss */
1706 { "addQ", { Ev, sIb } },
1707 { "orQ", { Ev, sIb } },
1708 { "adcQ", { Ev, sIb } },
1709 { "sbbQ", { Ev, sIb } },
1710 { "andQ", { Ev, sIb } },
1711 { "subQ", { Ev, sIb } },
1712 { "xorQ", { Ev, sIb } },
1713 { "cmpQ", { Ev, sIb } },
1715 /* GRP2b */
1717 { "rolA", { Eb, Ib } },
1718 { "rorA", { Eb, Ib } },
1719 { "rclA", { Eb, Ib } },
1720 { "rcrA", { Eb, Ib } },
1721 { "shlA", { Eb, Ib } },
1722 { "shrA", { Eb, Ib } },
1723 { "(bad)", { XX } },
1724 { "sarA", { Eb, Ib } },
1726 /* GRP2S */
1728 { "rolQ", { Ev, Ib } },
1729 { "rorQ", { Ev, Ib } },
1730 { "rclQ", { Ev, Ib } },
1731 { "rcrQ", { Ev, Ib } },
1732 { "shlQ", { Ev, Ib } },
1733 { "shrQ", { Ev, Ib } },
1734 { "(bad)", { XX } },
1735 { "sarQ", { Ev, Ib } },
1737 /* GRP2b_one */
1739 { "rolA", { Eb, I1 } },
1740 { "rorA", { Eb, I1 } },
1741 { "rclA", { Eb, I1 } },
1742 { "rcrA", { Eb, I1 } },
1743 { "shlA", { Eb, I1 } },
1744 { "shrA", { Eb, I1 } },
1745 { "(bad)", { XX } },
1746 { "sarA", { Eb, I1 } },
1748 /* GRP2S_one */
1750 { "rolQ", { Ev, I1 } },
1751 { "rorQ", { Ev, I1 } },
1752 { "rclQ", { Ev, I1 } },
1753 { "rcrQ", { Ev, I1 } },
1754 { "shlQ", { Ev, I1 } },
1755 { "shrQ", { Ev, I1 } },
1756 { "(bad)", { XX } },
1757 { "sarQ", { Ev, I1 } },
1759 /* GRP2b_cl */
1761 { "rolA", { Eb, CL } },
1762 { "rorA", { Eb, CL } },
1763 { "rclA", { Eb, CL } },
1764 { "rcrA", { Eb, CL } },
1765 { "shlA", { Eb, CL } },
1766 { "shrA", { Eb, CL } },
1767 { "(bad)", { XX } },
1768 { "sarA", { Eb, CL } },
1770 /* GRP2S_cl */
1772 { "rolQ", { Ev, CL } },
1773 { "rorQ", { Ev, CL } },
1774 { "rclQ", { Ev, CL } },
1775 { "rcrQ", { Ev, CL } },
1776 { "shlQ", { Ev, CL } },
1777 { "shrQ", { Ev, CL } },
1778 { "(bad)", { XX } },
1779 { "sarQ", { Ev, CL } },
1781 /* GRP3b */
1783 { "testA", { Eb, Ib } },
1784 { "(bad)", { Eb } },
1785 { "notA", { Eb } },
1786 { "negA", { Eb } },
1787 { "mulA", { Eb } }, /* Don't print the implicit %al register, */
1788 { "imulA", { Eb } }, /* to distinguish these opcodes from other */
1789 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */
1790 { "idivA", { Eb } }, /* and idiv for consistency. */
1792 /* GRP3S */
1794 { "testQ", { Ev, Iv } },
1795 { "(bad)", { XX } },
1796 { "notQ", { Ev } },
1797 { "negQ", { Ev } },
1798 { "mulQ", { Ev } }, /* Don't print the implicit register. */
1799 { "imulQ", { Ev } },
1800 { "divQ", { Ev } },
1801 { "idivQ", { Ev } },
1803 /* GRP4 */
1805 { "incA", { Eb } },
1806 { "decA", { Eb } },
1807 { "(bad)", { XX } },
1808 { "(bad)", { XX } },
1809 { "(bad)", { XX } },
1810 { "(bad)", { XX } },
1811 { "(bad)", { XX } },
1812 { "(bad)", { XX } },
1814 /* GRP5 */
1816 { "incQ", { Ev } },
1817 { "decQ", { Ev } },
1818 { "callT", { indirEv } },
1819 { "JcallT", { indirEp } },
1820 { "jmpT", { indirEv } },
1821 { "JjmpT", { indirEp } },
1822 { "pushU", { stackEv } },
1823 { "(bad)", { XX } },
1825 /* GRP6 */
1827 { "sldtD", { Sv } },
1828 { "strD", { Sv } },
1829 { "lldt", { Ew } },
1830 { "ltr", { Ew } },
1831 { "verr", { Ew } },
1832 { "verw", { Ew } },
1833 { "(bad)", { XX } },
1834 { "(bad)", { XX } },
1836 /* GRP7 */
1838 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1839 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1840 { "lgdt{Q|Q||}", { M } },
1841 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1842 { "smswD", { Sv } },
1843 { "(bad)", { XX } },
1844 { "lmsw", { Ew } },
1845 { "invlpg", { { INVLPG_Fixup, w_mode } } },
1847 /* GRP8 */
1849 { "(bad)", { XX } },
1850 { "(bad)", { XX } },
1851 { "(bad)", { XX } },
1852 { "(bad)", { XX } },
1853 { "btQ", { Ev, Ib } },
1854 { "btsQ", { Ev, Ib } },
1855 { "btrQ", { Ev, Ib } },
1856 { "btcQ", { Ev, Ib } },
1858 /* GRP9 */
1860 { "(bad)", { XX } },
1861 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1862 { "(bad)", { XX } },
1863 { "(bad)", { XX } },
1864 { "(bad)", { XX } },
1865 { "(bad)", { XX } },
1866 { "", { VM } }, /* See OP_VMX. */
1867 { "vmptrst", { Mq } },
1869 /* GRP11_C6 */
1871 { "movA", { Eb, Ib } },
1872 { "(bad)", { XX } },
1873 { "(bad)", { XX } },
1874 { "(bad)", { XX } },
1875 { "(bad)", { XX } },
1876 { "(bad)", { XX } },
1877 { "(bad)", { XX } },
1878 { "(bad)", { XX } },
1880 /* GRP11_C7 */
1882 { "movQ", { Ev, Iv } },
1883 { "(bad)", { XX } },
1884 { "(bad)", { XX } },
1885 { "(bad)", { XX } },
1886 { "(bad)", { XX } },
1887 { "(bad)", { XX } },
1888 { "(bad)", { XX } },
1889 { "(bad)", { XX } },
1891 /* GRP12 */
1893 { "(bad)", { XX } },
1894 { "(bad)", { XX } },
1895 { "psrlw", { MS, Ib } },
1896 { "(bad)", { XX } },
1897 { "psraw", { MS, Ib } },
1898 { "(bad)", { XX } },
1899 { "psllw", { MS, Ib } },
1900 { "(bad)", { XX } },
1902 /* GRP13 */
1904 { "(bad)", { XX } },
1905 { "(bad)", { XX } },
1906 { "psrld", { MS, Ib } },
1907 { "(bad)", { XX } },
1908 { "psrad", { MS, Ib } },
1909 { "(bad)", { XX } },
1910 { "pslld", { MS, Ib } },
1911 { "(bad)", { XX } },
1913 /* GRP14 */
1915 { "(bad)", { XX } },
1916 { "(bad)", { XX } },
1917 { "psrlq", { MS, Ib } },
1918 { "psrldq", { MS, Ib } },
1919 { "(bad)", { XX } },
1920 { "(bad)", { XX } },
1921 { "psllq", { MS, Ib } },
1922 { "pslldq", { MS, Ib } },
1924 /* GRP15 */
1926 { "fxsave", { Ev } },
1927 { "fxrstor", { Ev } },
1928 { "ldmxcsr", { Ev } },
1929 { "stmxcsr", { Ev } },
1930 { "(bad)", { XX } },
1931 { "lfence", { { OP_0fae, 0 } } },
1932 { "mfence", { { OP_0fae, 0 } } },
1933 { "clflush", { { OP_0fae, 0 } } },
1935 /* GRP16 */
1937 { "prefetchnta", { Ev } },
1938 { "prefetcht0", { Ev } },
1939 { "prefetcht1", { Ev } },
1940 { "prefetcht2", { Ev } },
1941 { "(bad)", { XX } },
1942 { "(bad)", { XX } },
1943 { "(bad)", { XX } },
1944 { "(bad)", { XX } },
1946 /* GRPAMD */
1948 { "prefetch", { Eb } },
1949 { "prefetchw", { Eb } },
1950 { "(bad)", { XX } },
1951 { "(bad)", { XX } },
1952 { "(bad)", { XX } },
1953 { "(bad)", { XX } },
1954 { "(bad)", { XX } },
1955 { "(bad)", { XX } },
1957 /* GRPPADLCK1 */
1959 { "xstore-rng", { { OP_0f07, 0 } } },
1960 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1961 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1962 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1963 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1964 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1965 { "(bad)", { { OP_0f07, 0 } } },
1966 { "(bad)", { { OP_0f07, 0 } } },
1968 /* GRPPADLCK2 */
1970 { "montmul", { { OP_0f07, 0 } } },
1971 { "xsha1", { { OP_0f07, 0 } } },
1972 { "xsha256", { { OP_0f07, 0 } } },
1973 { "(bad)", { { OP_0f07, 0 } } },
1974 { "(bad)", { { OP_0f07, 0 } } },
1975 { "(bad)", { { OP_0f07, 0 } } },
1976 { "(bad)", { { OP_0f07, 0 } } },
1977 { "(bad)", { { OP_0f07, 0 } } },
1981 static const struct dis386 prefix_user_table[][4] = {
1982 /* PREGRP0 */
1984 { "addps", { XM, EXx } },
1985 { "addss", { XM, EXd } },
1986 { "addpd", { XM, EXx } },
1987 { "addsd", { XM, EXq } },
1989 /* PREGRP1 */
1991 { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1992 { "", { XM, EXx, OPSIMD } },
1993 { "", { XM, EXx, OPSIMD } },
1994 { "", { XM, EXx, OPSIMD } },
1996 /* PREGRP2 */
1998 { "cvtpi2ps", { XM, EMC } },
1999 { "cvtsi2ssY", { XM, Ev } },
2000 { "cvtpi2pd", { XM, EMC } },
2001 { "cvtsi2sdY", { XM, Ev } },
2003 /* PREGRP3 */
2005 { "cvtps2pi", { MXC, EXx } },
2006 { "cvtss2siY", { Gv, EXx } },
2007 { "cvtpd2pi", { MXC, EXx } },
2008 { "cvtsd2siY", { Gv, EXx } },
2010 /* PREGRP4 */
2012 { "cvttps2pi", { MXC, EXx } },
2013 { "cvttss2siY", { Gv, EXx } },
2014 { "cvttpd2pi", { MXC, EXx } },
2015 { "cvttsd2siY", { Gv, EXx } },
2017 /* PREGRP5 */
2019 { "divps", { XM, EXx } },
2020 { "divss", { XM, EXx } },
2021 { "divpd", { XM, EXx } },
2022 { "divsd", { XM, EXx } },
2024 /* PREGRP6 */
2026 { "maxps", { XM, EXx } },
2027 { "maxss", { XM, EXx } },
2028 { "maxpd", { XM, EXx } },
2029 { "maxsd", { XM, EXx } },
2031 /* PREGRP7 */
2033 { "minps", { XM, EXx } },
2034 { "minss", { XM, EXx } },
2035 { "minpd", { XM, EXx } },
2036 { "minsd", { XM, EXx } },
2038 /* PREGRP8 */
2040 { "movups", { XM, EXx } },
2041 { "movss", { XM, EXx } },
2042 { "movupd", { XM, EXx } },
2043 { "movsd", { XM, EXx } },
2045 /* PREGRP9 */
2047 { "movups", { EXx, XM } },
2048 { "movss", { EXx, XM } },
2049 { "movupd", { EXx, XM } },
2050 { "movsd", { EXx, XM } },
2052 /* PREGRP10 */
2054 { "mulps", { XM, EXx } },
2055 { "mulss", { XM, EXx } },
2056 { "mulpd", { XM, EXx } },
2057 { "mulsd", { XM, EXx } },
2059 /* PREGRP11 */
2061 { "rcpps", { XM, EXx } },
2062 { "rcpss", { XM, EXx } },
2063 { "(bad)", { XM, EXx } },
2064 { "(bad)", { XM, EXx } },
2066 /* PREGRP12 */
2068 { "rsqrtps",{ XM, EXx } },
2069 { "rsqrtss",{ XM, EXx } },
2070 { "(bad)", { XM, EXx } },
2071 { "(bad)", { XM, EXx } },
2073 /* PREGRP13 */
2075 { "sqrtps", { XM, EXx } },
2076 { "sqrtss", { XM, EXx } },
2077 { "sqrtpd", { XM, EXx } },
2078 { "sqrtsd", { XM, EXx } },
2080 /* PREGRP14 */
2082 { "subps", { XM, EXx } },
2083 { "subss", { XM, EXx } },
2084 { "subpd", { XM, EXx } },
2085 { "subsd", { XM, EXx } },
2087 /* PREGRP15 */
2089 { "(bad)", { XM, EXx } },
2090 { "cvtdq2pd", { XM, EXq } },
2091 { "cvttpd2dq", { XM, EXx } },
2092 { "cvtpd2dq", { XM, EXx } },
2094 /* PREGRP16 */
2096 { "cvtdq2ps", { XM, EXx } },
2097 { "cvttps2dq", { XM, EXx } },
2098 { "cvtps2dq", { XM, EXx } },
2099 { "(bad)", { XM, EXx } },
2101 /* PREGRP17 */
2103 { "cvtps2pd", { XM, EXq } },
2104 { "cvtss2sd", { XM, EXx } },
2105 { "cvtpd2ps", { XM, EXx } },
2106 { "cvtsd2ss", { XM, EXx } },
2108 /* PREGRP18 */
2110 { "maskmovq", { MX, MS } },
2111 { "(bad)", { XM, EXx } },
2112 { "maskmovdqu", { XM, XS } },
2113 { "(bad)", { XM, EXx } },
2115 /* PREGRP19 */
2117 { "movq", { MX, EM } },
2118 { "movdqu", { XM, EXx } },
2119 { "movdqa", { XM, EXx } },
2120 { "(bad)", { XM, EXx } },
2122 /* PREGRP20 */
2124 { "movq", { EM, MX } },
2125 { "movdqu", { EXx, XM } },
2126 { "movdqa", { EXx, XM } },
2127 { "(bad)", { EXx, XM } },
2129 /* PREGRP21 */
2131 { "(bad)", { EXx, XM } },
2132 { "movq2dq",{ XM, MS } },
2133 { "movq", { EXx, XM } },
2134 { "movdq2q",{ MX, XS } },
2136 /* PREGRP22 */
2138 { "pshufw", { MX, EM, Ib } },
2139 { "pshufhw",{ XM, EXx, Ib } },
2140 { "pshufd", { XM, EXx, Ib } },
2141 { "pshuflw",{ XM, EXx, Ib } },
2143 /* PREGRP23 */
2145 { "movd", { Edq, MX } },
2146 { "movq", { XM, EXx } },
2147 { "movd", { Edq, XM } },
2148 { "(bad)", { Ed, XM } },
2150 /* PREGRP24 */
2152 { "(bad)", { MX, EXx } },
2153 { "(bad)", { XM, EXx } },
2154 { "punpckhqdq", { XM, EXx } },
2155 { "(bad)", { XM, EXx } },
2157 /* PREGRP25 */
2159 { "movntq", { EM, MX } },
2160 { "(bad)", { EM, XM } },
2161 { "movntdq",{ EM, XM } },
2162 { "(bad)", { EM, XM } },
2164 /* PREGRP26 */
2166 { "(bad)", { MX, EXx } },
2167 { "(bad)", { XM, EXx } },
2168 { "punpcklqdq", { XM, EXx } },
2169 { "(bad)", { XM, EXx } },
2171 /* PREGRP27 */
2173 { "(bad)", { MX, EXx } },
2174 { "(bad)", { XM, EXx } },
2175 { "addsubpd", { XM, EXx } },
2176 { "addsubps", { XM, EXx } },
2178 /* PREGRP28 */
2180 { "(bad)", { MX, EXx } },
2181 { "(bad)", { XM, EXx } },
2182 { "haddpd", { XM, EXx } },
2183 { "haddps", { XM, EXx } },
2185 /* PREGRP29 */
2187 { "(bad)", { MX, EXx } },
2188 { "(bad)", { XM, EXx } },
2189 { "hsubpd", { XM, EXx } },
2190 { "hsubps", { XM, EXx } },
2192 /* PREGRP30 */
2194 { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
2195 { "movsldup", { XM, EXx } },
2196 { "movlpd", { XM, EXq } },
2197 { "movddup", { XM, EXq } },
2199 /* PREGRP31 */
2201 { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } },
2202 { "movshdup", { XM, EXx } },
2203 { "movhpd", { XM, EXq } },
2204 { "(bad)", { XM, EXq } },
2206 /* PREGRP32 */
2208 { "(bad)", { XM, EXx } },
2209 { "(bad)", { XM, EXx } },
2210 { "(bad)", { XM, EXx } },
2211 { "lddqu", { XM, M } },
2213 /* PREGRP33 */
2215 {"movntps", { Ev, XM } },
2216 {"movntss", { Ev, XM } },
2217 {"movntpd", { Ev, XM } },
2218 {"movntsd", { Ev, XM } },
2221 /* PREGRP34 */
2223 {"vmread", { Em, Gm } },
2224 {"(bad)", { XX } },
2225 {"extrq", { XS, Ib, Ib } },
2226 {"insertq", { XM, XS, Ib, Ib } },
2229 /* PREGRP35 */
2231 {"vmwrite", { Gm, Em } },
2232 {"(bad)", { XX } },
2233 {"extrq", { XM, XS } },
2234 {"insertq", { XM, XS } },
2237 /* PREGRP36 */
2239 { "bsrS", { Gv, Ev } },
2240 { "lzcntS", { Gv, Ev } },
2241 { "bsrS", { Gv, Ev } },
2242 { "(bad)", { XX } },
2245 /* PREGRP37 */
2247 { "(bad)", { XX } },
2248 { "popcntS", { Gv, Ev } },
2249 { "(bad)", { XX } },
2250 { "(bad)", { XX } },
2253 /* PREGRP38 */
2255 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2256 { "pause", { XX } },
2257 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2258 { "(bad)", { XX } },
2261 /* PREGRP39 */
2263 { "(bad)", { XX } },
2264 { "(bad)", { XX } },
2265 { "pblendvb", {XM, EXx, XMM0 } },
2266 { "(bad)", { XX } },
2269 /* PREGRP40 */
2271 { "(bad)", { XX } },
2272 { "(bad)", { XX } },
2273 { "blendvps", {XM, EXx, XMM0 } },
2274 { "(bad)", { XX } },
2277 /* PREGRP41 */
2279 { "(bad)", { XX } },
2280 { "(bad)", { XX } },
2281 { "blendvpd", { XM, EXx, XMM0 } },
2282 { "(bad)", { XX } },
2285 /* PREGRP42 */
2287 { "(bad)", { XX } },
2288 { "(bad)", { XX } },
2289 { "ptest", { XM, EXx } },
2290 { "(bad)", { XX } },
2293 /* PREGRP43 */
2295 { "(bad)", { XX } },
2296 { "(bad)", { XX } },
2297 { "pmovsxbw", { XM, EXx } },
2298 { "(bad)", { XX } },
2301 /* PREGRP44 */
2303 { "(bad)", { XX } },
2304 { "(bad)", { XX } },
2305 { "pmovsxbd", { XM, EXx } },
2306 { "(bad)", { XX } },
2309 /* PREGRP45 */
2311 { "(bad)", { XX } },
2312 { "(bad)", { XX } },
2313 { "pmovsxbq", { XM, EXx } },
2314 { "(bad)", { XX } },
2317 /* PREGRP46 */
2319 { "(bad)", { XX } },
2320 { "(bad)", { XX } },
2321 { "pmovsxwd", { XM, EXx } },
2322 { "(bad)", { XX } },
2325 /* PREGRP47 */
2327 { "(bad)", { XX } },
2328 { "(bad)", { XX } },
2329 { "pmovsxwq", { XM, EXx } },
2330 { "(bad)", { XX } },
2333 /* PREGRP48 */
2335 { "(bad)", { XX } },
2336 { "(bad)", { XX } },
2337 { "pmovsxdq", { XM, EXx } },
2338 { "(bad)", { XX } },
2341 /* PREGRP49 */
2343 { "(bad)", { XX } },
2344 { "(bad)", { XX } },
2345 { "pmuldq", { XM, EXx } },
2346 { "(bad)", { XX } },
2349 /* PREGRP50 */
2351 { "(bad)", { XX } },
2352 { "(bad)", { XX } },
2353 { "pcmpeqq", { XM, EXx } },
2354 { "(bad)", { XX } },
2357 /* PREGRP51 */
2359 { "(bad)", { XX } },
2360 { "(bad)", { XX } },
2361 { "movntdqa", { XM, EM } },
2362 { "(bad)", { XX } },
2365 /* PREGRP52 */
2367 { "(bad)", { XX } },
2368 { "(bad)", { XX } },
2369 { "packusdw", { XM, EXx } },
2370 { "(bad)", { XX } },
2373 /* PREGRP53 */
2375 { "(bad)", { XX } },
2376 { "(bad)", { XX } },
2377 { "pmovzxbw", { XM, EXx } },
2378 { "(bad)", { XX } },
2381 /* PREGRP54 */
2383 { "(bad)", { XX } },
2384 { "(bad)", { XX } },
2385 { "pmovzxbd", { XM, EXx } },
2386 { "(bad)", { XX } },
2389 /* PREGRP55 */
2391 { "(bad)", { XX } },
2392 { "(bad)", { XX } },
2393 { "pmovzxbq", { XM, EXx } },
2394 { "(bad)", { XX } },
2397 /* PREGRP56 */
2399 { "(bad)", { XX } },
2400 { "(bad)", { XX } },
2401 { "pmovzxwd", { XM, EXx } },
2402 { "(bad)", { XX } },
2405 /* PREGRP57 */
2407 { "(bad)", { XX } },
2408 { "(bad)", { XX } },
2409 { "pmovzxwq", { XM, EXx } },
2410 { "(bad)", { XX } },
2413 /* PREGRP58 */
2415 { "(bad)", { XX } },
2416 { "(bad)", { XX } },
2417 { "pmovzxdq", { XM, EXx } },
2418 { "(bad)", { XX } },
2421 /* PREGRP59 */
2423 { "(bad)", { XX } },
2424 { "(bad)", { XX } },
2425 { "pminsb", { XM, EXx } },
2426 { "(bad)", { XX } },
2429 /* PREGRP60 */
2431 { "(bad)", { XX } },
2432 { "(bad)", { XX } },
2433 { "pminsd", { XM, EXx } },
2434 { "(bad)", { XX } },
2437 /* PREGRP61 */
2439 { "(bad)", { XX } },
2440 { "(bad)", { XX } },
2441 { "pminuw", { XM, EXx } },
2442 { "(bad)", { XX } },
2445 /* PREGRP62 */
2447 { "(bad)", { XX } },
2448 { "(bad)", { XX } },
2449 { "pminud", { XM, EXx } },
2450 { "(bad)", { XX } },
2453 /* PREGRP63 */
2455 { "(bad)", { XX } },
2456 { "(bad)", { XX } },
2457 { "pmaxsb", { XM, EXx } },
2458 { "(bad)", { XX } },
2461 /* PREGRP64 */
2463 { "(bad)", { XX } },
2464 { "(bad)", { XX } },
2465 { "pmaxsd", { XM, EXx } },
2466 { "(bad)", { XX } },
2469 /* PREGRP65 */
2471 { "(bad)", { XX } },
2472 { "(bad)", { XX } },
2473 { "pmaxuw", { XM, EXx } },
2474 { "(bad)", { XX } },
2477 /* PREGRP66 */
2479 { "(bad)", { XX } },
2480 { "(bad)", { XX } },
2481 { "pmaxud", { XM, EXx } },
2482 { "(bad)", { XX } },
2485 /* PREGRP67 */
2487 { "(bad)", { XX } },
2488 { "(bad)", { XX } },
2489 { "pmulld", { XM, EXx } },
2490 { "(bad)", { XX } },
2493 /* PREGRP68 */
2495 { "(bad)", { XX } },
2496 { "(bad)", { XX } },
2497 { "phminposuw", { XM, EXx } },
2498 { "(bad)", { XX } },
2501 /* PREGRP69 */
2503 { "(bad)", { XX } },
2504 { "(bad)", { XX } },
2505 { "roundps", { XM, EXx, Ib } },
2506 { "(bad)", { XX } },
2509 /* PREGRP70 */
2511 { "(bad)", { XX } },
2512 { "(bad)", { XX } },
2513 { "roundpd", { XM, EXx, Ib } },
2514 { "(bad)", { XX } },
2517 /* PREGRP71 */
2519 { "(bad)", { XX } },
2520 { "(bad)", { XX } },
2521 { "roundss", { XM, EXx, Ib } },
2522 { "(bad)", { XX } },
2525 /* PREGRP72 */
2527 { "(bad)", { XX } },
2528 { "(bad)", { XX } },
2529 { "roundsd", { XM, EXx, Ib } },
2530 { "(bad)", { XX } },
2533 /* PREGRP73 */
2535 { "(bad)", { XX } },
2536 { "(bad)", { XX } },
2537 { "blendps", { XM, EXx, Ib } },
2538 { "(bad)", { XX } },
2541 /* PREGRP74 */
2543 { "(bad)", { XX } },
2544 { "(bad)", { XX } },
2545 { "blendpd", { XM, EXx, Ib } },
2546 { "(bad)", { XX } },
2549 /* PREGRP75 */
2551 { "(bad)", { XX } },
2552 { "(bad)", { XX } },
2553 { "pblendw", { XM, EXx, Ib } },
2554 { "(bad)", { XX } },
2557 /* PREGRP76 */
2559 { "(bad)", { XX } },
2560 { "(bad)", { XX } },
2561 { "pextrb", { Edqb, XM, Ib } },
2562 { "(bad)", { XX } },
2565 /* PREGRP77 */
2567 { "(bad)", { XX } },
2568 { "(bad)", { XX } },
2569 { "pextrw", { Edqw, XM, Ib } },
2570 { "(bad)", { XX } },
2573 /* PREGRP78 */
2575 { "(bad)", { XX } },
2576 { "(bad)", { XX } },
2577 { "pextrK", { Edq, XM, Ib } },
2578 { "(bad)", { XX } },
2581 /* PREGRP79 */
2583 { "(bad)", { XX } },
2584 { "(bad)", { XX } },
2585 { "extractps", { Edqd, XM, Ib } },
2586 { "(bad)", { XX } },
2589 /* PREGRP80 */
2591 { "(bad)", { XX } },
2592 { "(bad)", { XX } },
2593 { "pinsrb", { XM, Edqb, Ib } },
2594 { "(bad)", { XX } },
2597 /* PREGRP81 */
2599 { "(bad)", { XX } },
2600 { "(bad)", { XX } },
2601 { "insertps", { XM, EXx, Ib } },
2602 { "(bad)", { XX } },
2605 /* PREGRP82 */
2607 { "(bad)", { XX } },
2608 { "(bad)", { XX } },
2609 { "pinsrK", { XM, Edq, Ib } },
2610 { "(bad)", { XX } },
2613 /* PREGRP83 */
2615 { "(bad)", { XX } },
2616 { "(bad)", { XX } },
2617 { "dpps", { XM, EXx, Ib } },
2618 { "(bad)", { XX } },
2621 /* PREGRP84 */
2623 { "(bad)", { XX } },
2624 { "(bad)", { XX } },
2625 { "dppd", { XM, EXx, Ib } },
2626 { "(bad)", { XX } },
2629 /* PREGRP85 */
2631 { "(bad)", { XX } },
2632 { "(bad)", { XX } },
2633 { "mpsadbw", { XM, EXx, Ib } },
2634 { "(bad)", { XX } },
2637 /* PREGRP86 */
2639 { "(bad)", { XX } },
2640 { "(bad)", { XX } },
2641 { "pcmpgtq", { XM, EXx } },
2642 { "(bad)", { XX } },
2645 /* PREGRP87 */
2647 { "movbe", { Gv, Ev } },
2648 { "(bad)", { XX } },
2649 { "movbe", { Gv, Ev } },
2650 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
2653 /* PREGRP88 */
2655 { "movbe", { Ev, Gv } },
2656 { "(bad)", { XX } },
2657 { "movbe", { Ev, Gv } },
2658 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
2661 /* PREGRP89 */
2663 { "(bad)", { XX } },
2664 { "(bad)", { XX } },
2665 { "pcmpestrm", { XM, EXx, Ib } },
2666 { "(bad)", { XX } },
2669 /* PREGRP90 */
2671 { "(bad)", { XX } },
2672 { "(bad)", { XX } },
2673 { "pcmpestri", { XM, EXx, Ib } },
2674 { "(bad)", { XX } },
2677 /* PREGRP91 */
2679 { "(bad)", { XX } },
2680 { "(bad)", { XX } },
2681 { "pcmpistrm", { XM, EXx, Ib } },
2682 { "(bad)", { XX } },
2685 /* PREGRP92 */
2687 { "(bad)", { XX } },
2688 { "(bad)", { XX } },
2689 { "pcmpistri", { XM, EXx, Ib } },
2690 { "(bad)", { XX } },
2693 /* PREGRP93 */
2695 { "ucomiss",{ XM, EXd } },
2696 { "(bad)", { XX } },
2697 { "ucomisd",{ XM, EXq } },
2698 { "(bad)", { XX } },
2701 /* PREGRP94 */
2703 { "comiss", { XM, EXd } },
2704 { "(bad)", { XX } },
2705 { "comisd", { XM, EXq } },
2706 { "(bad)", { XX } },
2709 /* PREGRP95 */
2711 { "punpcklbw",{ MX, EMd } },
2712 { "(bad)", { XX } },
2713 { "punpcklbw",{ MX, EMq } },
2714 { "(bad)", { XX } },
2717 /* PREGRP96 */
2719 { "punpcklwd",{ MX, EMd } },
2720 { "(bad)", { XX } },
2721 { "punpcklwd",{ MX, EMq } },
2722 { "(bad)", { XX } },
2725 /* PREGRP97 */
2727 { "punpckldq",{ MX, EMd } },
2728 { "(bad)", { XX } },
2729 { "punpckldq",{ MX, EMq } },
2730 { "(bad)", { XX } },
2733 /* PREGRP98 */
2735 { "(bad)", { XX } },
2736 { "(bad)", { XX } },
2737 { "pclmulqdq", { XM, EXx, Ib } },
2738 { "(bad)", { XX } },
2741 /* PREGRP99 */
2743 { "(bad)", { XX } },
2744 { "(bad)", { XX } },
2745 { "aesimc", { XM, EXx } },
2746 { "(bad)", { XX } },
2749 /* PREGRP100 */
2751 { "(bad)", { XX } },
2752 { "(bad)", { XX } },
2753 { "aesenc", { XM, EXx } },
2754 { "(bad)", { XX } },
2757 /* PREGRP101 */
2759 { "(bad)", { XX } },
2760 { "(bad)", { XX } },
2761 { "aesenclast", { XM, EXx } },
2762 { "(bad)", { XX } },
2765 /* PREGRP102 */
2767 { "(bad)", { XX } },
2768 { "(bad)", { XX } },
2769 { "aesdec", { XM, EXx } },
2770 { "(bad)", { XX } },
2773 /* PREGRP103 */
2775 { "(bad)", { XX } },
2776 { "(bad)", { XX } },
2777 { "aesdeclast", { XM, EXx } },
2778 { "(bad)", { XX } },
2781 /* PREGRP104 */
2783 { "(bad)", { XX } },
2784 { "(bad)", { XX } },
2785 { "aeskeygenassist", { XM, EXx, Ib } },
2786 { "(bad)", { XX } },
2789 /* PREGRP105 */
2791 { "andnS", { Gv, Bv, Ev } },
2792 { "(bad)", { XX } },
2793 { "(bad)", { XX } },
2794 { "(bad)", { XX } },
2797 /* PREGRP106 */
2799 { "bextrS", { Gv, Ev, Bv } },
2800 { "sarxS", { Gv, Ev, Bv } },
2801 { "shlxS", { Gv, Ev, Bv } },
2802 { "shrxS", { Gv, Ev, Bv } },
2807 static const struct dis386 x86_64_table[][2] = {
2809 { "pusha{P|}", { XX } },
2810 { "(bad)", { XX } },
2813 { "popa{P|}", { XX } },
2814 { "(bad)", { XX } },
2817 { "bound{S|}", { Gv, Ma } },
2818 { "(bad)", { XX } },
2821 { "arpl", { Ew, Gw } },
2822 { "movs{||lq|xd}", { Gv, Ed } },
2826 static const struct dis386 three_byte_table[][256] = {
2827 /* THREE_BYTE_0 */
2829 /* 00 */
2830 { "pshufb", { MX, EM } },
2831 { "phaddw", { MX, EM } },
2832 { "phaddd", { MX, EM } },
2833 { "phaddsw", { MX, EM } },
2834 { "pmaddubsw", { MX, EM } },
2835 { "phsubw", { MX, EM } },
2836 { "phsubd", { MX, EM } },
2837 { "phsubsw", { MX, EM } },
2838 /* 08 */
2839 { "psignb", { MX, EM } },
2840 { "psignw", { MX, EM } },
2841 { "psignd", { MX, EM } },
2842 { "pmulhrsw", { MX, EM } },
2843 { "(bad)", { XX } },
2844 { "(bad)", { XX } },
2845 { "(bad)", { XX } },
2846 { "(bad)", { XX } },
2847 /* 10 */
2848 { PREGRP39 },
2849 { "(bad)", { XX } },
2850 { "(bad)", { XX } },
2851 { "(bad)", { XX } },
2852 { PREGRP40 },
2853 { PREGRP41 },
2854 { "(bad)", { XX } },
2855 { PREGRP42 },
2856 /* 18 */
2857 { "(bad)", { XX } },
2858 { "(bad)", { XX } },
2859 { "(bad)", { XX } },
2860 { "(bad)", { XX } },
2861 { "pabsb", { MX, EM } },
2862 { "pabsw", { MX, EM } },
2863 { "pabsd", { MX, EM } },
2864 { "(bad)", { XX } },
2865 /* 20 */
2866 { PREGRP43 },
2867 { PREGRP44 },
2868 { PREGRP45 },
2869 { PREGRP46 },
2870 { PREGRP47 },
2871 { PREGRP48 },
2872 { "(bad)", { XX } },
2873 { "(bad)", { XX } },
2874 /* 28 */
2875 { PREGRP49 },
2876 { PREGRP50 },
2877 { PREGRP51 },
2878 { PREGRP52 },
2879 { "(bad)", { XX } },
2880 { "(bad)", { XX } },
2881 { "(bad)", { XX } },
2882 { "(bad)", { XX } },
2883 /* 30 */
2884 { PREGRP53 },
2885 { PREGRP54 },
2886 { PREGRP55 },
2887 { PREGRP56 },
2888 { PREGRP57 },
2889 { PREGRP58 },
2890 { "(bad)", { XX } },
2891 { PREGRP86 },
2892 /* 38 */
2893 { PREGRP59 },
2894 { PREGRP60 },
2895 { PREGRP61 },
2896 { PREGRP62 },
2897 { PREGRP63 },
2898 { PREGRP64 },
2899 { PREGRP65 },
2900 { PREGRP66 },
2901 /* 40 */
2902 { PREGRP67 },
2903 { PREGRP68 },
2904 { "(bad)", { XX } },
2905 { "(bad)", { XX } },
2906 { "(bad)", { XX } },
2907 { "(bad)", { XX } },
2908 { "(bad)", { XX } },
2909 { "(bad)", { XX } },
2910 /* 48 */
2911 { "(bad)", { XX } },
2912 { "(bad)", { XX } },
2913 { "(bad)", { XX } },
2914 { "(bad)", { XX } },
2915 { "(bad)", { XX } },
2916 { "(bad)", { XX } },
2917 { "(bad)", { XX } },
2918 { "(bad)", { XX } },
2919 /* 50 */
2920 { "(bad)", { XX } },
2921 { "(bad)", { XX } },
2922 { "(bad)", { XX } },
2923 { "(bad)", { XX } },
2924 { "(bad)", { XX } },
2925 { "(bad)", { XX } },
2926 { "(bad)", { XX } },
2927 { "(bad)", { XX } },
2928 /* 58 */
2929 { "(bad)", { XX } },
2930 { "(bad)", { XX } },
2931 { "(bad)", { XX } },
2932 { "(bad)", { XX } },
2933 { "(bad)", { XX } },
2934 { "(bad)", { XX } },
2935 { "(bad)", { XX } },
2936 { "(bad)", { XX } },
2937 /* 60 */
2938 { "(bad)", { XX } },
2939 { "(bad)", { XX } },
2940 { "(bad)", { XX } },
2941 { "(bad)", { XX } },
2942 { "(bad)", { XX } },
2943 { "(bad)", { XX } },
2944 { "(bad)", { XX } },
2945 { "(bad)", { XX } },
2946 /* 68 */
2947 { "(bad)", { XX } },
2948 { "(bad)", { XX } },
2949 { "(bad)", { XX } },
2950 { "(bad)", { XX } },
2951 { "(bad)", { XX } },
2952 { "(bad)", { XX } },
2953 { "(bad)", { XX } },
2954 { "(bad)", { XX } },
2955 /* 70 */
2956 { "(bad)", { XX } },
2957 { "(bad)", { XX } },
2958 { "(bad)", { XX } },
2959 { "(bad)", { XX } },
2960 { "(bad)", { XX } },
2961 { "(bad)", { XX } },
2962 { "(bad)", { XX } },
2963 { "(bad)", { XX } },
2964 /* 78 */
2965 { "(bad)", { XX } },
2966 { "(bad)", { XX } },
2967 { "(bad)", { XX } },
2968 { "(bad)", { XX } },
2969 { "(bad)", { XX } },
2970 { "(bad)", { XX } },
2971 { "(bad)", { XX } },
2972 { "(bad)", { XX } },
2973 /* 80 */
2974 { "(bad)", { XX } },
2975 { "(bad)", { XX } },
2976 { "(bad)", { XX } },
2977 { "(bad)", { XX } },
2978 { "(bad)", { XX } },
2979 { "(bad)", { XX } },
2980 { "(bad)", { XX } },
2981 { "(bad)", { XX } },
2982 /* 88 */
2983 { "(bad)", { XX } },
2984 { "(bad)", { XX } },
2985 { "(bad)", { XX } },
2986 { "(bad)", { XX } },
2987 { "(bad)", { XX } },
2988 { "(bad)", { XX } },
2989 { "(bad)", { XX } },
2990 { "(bad)", { XX } },
2991 /* 90 */
2992 { "(bad)", { XX } },
2993 { "(bad)", { XX } },
2994 { "(bad)", { XX } },
2995 { "(bad)", { XX } },
2996 { "(bad)", { XX } },
2997 { "(bad)", { XX } },
2998 { "(bad)", { XX } },
2999 { "(bad)", { XX } },
3000 /* 98 */
3001 { "(bad)", { XX } },
3002 { "(bad)", { XX } },
3003 { "(bad)", { XX } },
3004 { "(bad)", { XX } },
3005 { "(bad)", { XX } },
3006 { "(bad)", { XX } },
3007 { "(bad)", { XX } },
3008 { "(bad)", { XX } },
3009 /* a0 */
3010 { "(bad)", { XX } },
3011 { "(bad)", { XX } },
3012 { "(bad)", { XX } },
3013 { "(bad)", { XX } },
3014 { "(bad)", { XX } },
3015 { "(bad)", { XX } },
3016 { "(bad)", { XX } },
3017 { "(bad)", { XX } },
3018 /* a8 */
3019 { "(bad)", { XX } },
3020 { "(bad)", { XX } },
3021 { "(bad)", { XX } },
3022 { "(bad)", { XX } },
3023 { "(bad)", { XX } },
3024 { "(bad)", { XX } },
3025 { "(bad)", { XX } },
3026 { "(bad)", { XX } },
3027 /* b0 */
3028 { "(bad)", { XX } },
3029 { "(bad)", { XX } },
3030 { "(bad)", { XX } },
3031 { "(bad)", { XX } },
3032 { "(bad)", { XX } },
3033 { "(bad)", { XX } },
3034 { "(bad)", { XX } },
3035 { "(bad)", { XX } },
3036 /* b8 */
3037 { "(bad)", { XX } },
3038 { "(bad)", { XX } },
3039 { "(bad)", { XX } },
3040 { "(bad)", { XX } },
3041 { "(bad)", { XX } },
3042 { "(bad)", { XX } },
3043 { "(bad)", { XX } },
3044 { "(bad)", { XX } },
3045 /* c0 */
3046 { "(bad)", { XX } },
3047 { "(bad)", { XX } },
3048 { "(bad)", { XX } },
3049 { "(bad)", { XX } },
3050 { "(bad)", { XX } },
3051 { "(bad)", { XX } },
3052 { "(bad)", { XX } },
3053 { "(bad)", { XX } },
3054 /* c8 */
3055 { "(bad)", { XX } },
3056 { "(bad)", { XX } },
3057 { "(bad)", { XX } },
3058 { "(bad)", { XX } },
3059 { "(bad)", { XX } },
3060 { "(bad)", { XX } },
3061 { "(bad)", { XX } },
3062 { "(bad)", { XX } },
3063 /* d0 */
3064 { "(bad)", { XX } },
3065 { "(bad)", { XX } },
3066 { "(bad)", { XX } },
3067 { "(bad)", { XX } },
3068 { "(bad)", { XX } },
3069 { "(bad)", { XX } },
3070 { "(bad)", { XX } },
3071 { "(bad)", { XX } },
3072 /* d8 */
3073 { "(bad)", { XX } },
3074 { "(bad)", { XX } },
3075 { "(bad)", { XX } },
3076 { PREGRP99 },
3077 { PREGRP100 },
3078 { PREGRP101 },
3079 { PREGRP102 },
3080 { PREGRP103 },
3081 /* e0 */
3082 { "(bad)", { XX } },
3083 { "(bad)", { XX } },
3084 { "(bad)", { XX } },
3085 { "(bad)", { XX } },
3086 { "(bad)", { XX } },
3087 { "(bad)", { XX } },
3088 { "(bad)", { XX } },
3089 { "(bad)", { XX } },
3090 /* e8 */
3091 { "(bad)", { XX } },
3092 { "(bad)", { XX } },
3093 { "(bad)", { XX } },
3094 { "(bad)", { XX } },
3095 { "(bad)", { XX } },
3096 { "(bad)", { XX } },
3097 { "(bad)", { XX } },
3098 { "(bad)", { XX } },
3099 /* f0 */
3100 { PREGRP87 },
3101 { PREGRP88 },
3102 { PREGRP105 },
3103 { "(bad)", { XX } },
3104 { "(bad)", { XX } },
3105 { "(bad)", { XX } },
3106 { "(bad)", { XX } },
3107 { PREGRP106 },
3108 /* f8 */
3109 { "(bad)", { XX } },
3110 { "(bad)", { XX } },
3111 { "(bad)", { XX } },
3112 { "(bad)", { XX } },
3113 { "(bad)", { XX } },
3114 { "(bad)", { XX } },
3115 { "(bad)", { XX } },
3116 { "(bad)", { XX } },
3118 /* THREE_BYTE_1 */
3120 /* 00 */
3121 { "(bad)", { XX } },
3122 { "(bad)", { XX } },
3123 { "(bad)", { XX } },
3124 { "(bad)", { XX } },
3125 { "(bad)", { XX } },
3126 { "(bad)", { XX } },
3127 { "(bad)", { XX } },
3128 { "(bad)", { XX } },
3129 /* 08 */
3130 { PREGRP69 },
3131 { PREGRP70 },
3132 { PREGRP71 },
3133 { PREGRP72 },
3134 { PREGRP73 },
3135 { PREGRP74 },
3136 { PREGRP75 },
3137 { "palignr", { MX, EM, Ib } },
3138 /* 10 */
3139 { "(bad)", { XX } },
3140 { "(bad)", { XX } },
3141 { "(bad)", { XX } },
3142 { "(bad)", { XX } },
3143 { PREGRP76 },
3144 { PREGRP77 },
3145 { PREGRP78 },
3146 { PREGRP79 },
3147 /* 18 */
3148 { "(bad)", { XX } },
3149 { "(bad)", { XX } },
3150 { "(bad)", { XX } },
3151 { "(bad)", { XX } },
3152 { "(bad)", { XX } },
3153 { "(bad)", { XX } },
3154 { "(bad)", { XX } },
3155 { "(bad)", { XX } },
3156 /* 20 */
3157 { PREGRP80 },
3158 { PREGRP81 },
3159 { PREGRP82 },
3160 { "(bad)", { XX } },
3161 { "(bad)", { XX } },
3162 { "(bad)", { XX } },
3163 { "(bad)", { XX } },
3164 { "(bad)", { XX } },
3165 /* 28 */
3166 { "(bad)", { XX } },
3167 { "(bad)", { XX } },
3168 { "(bad)", { XX } },
3169 { "(bad)", { XX } },
3170 { "(bad)", { XX } },
3171 { "(bad)", { XX } },
3172 { "(bad)", { XX } },
3173 { "(bad)", { XX } },
3174 /* 30 */
3175 { "(bad)", { XX } },
3176 { "(bad)", { XX } },
3177 { "(bad)", { XX } },
3178 { "(bad)", { XX } },
3179 { "(bad)", { XX } },
3180 { "(bad)", { XX } },
3181 { "(bad)", { XX } },
3182 { "(bad)", { XX } },
3183 /* 38 */
3184 { "(bad)", { XX } },
3185 { "(bad)", { XX } },
3186 { "(bad)", { XX } },
3187 { "(bad)", { XX } },
3188 { "(bad)", { XX } },
3189 { "(bad)", { XX } },
3190 { "(bad)", { XX } },
3191 { "(bad)", { XX } },
3192 /* 40 */
3193 { PREGRP83 },
3194 { PREGRP84 },
3195 { PREGRP85 },
3196 { "(bad)", { XX } },
3197 { PREGRP98 },
3198 { "(bad)", { XX } },
3199 { "(bad)", { XX } },
3200 { "(bad)", { XX } },
3201 /* 48 */
3202 { "(bad)", { XX } },
3203 { "(bad)", { XX } },
3204 { "(bad)", { XX } },
3205 { "(bad)", { XX } },
3206 { "(bad)", { XX } },
3207 { "(bad)", { XX } },
3208 { "(bad)", { XX } },
3209 { "(bad)", { XX } },
3210 /* 50 */
3211 { "(bad)", { XX } },
3212 { "(bad)", { XX } },
3213 { "(bad)", { XX } },
3214 { "(bad)", { XX } },
3215 { "(bad)", { XX } },
3216 { "(bad)", { XX } },
3217 { "(bad)", { XX } },
3218 { "(bad)", { XX } },
3219 /* 58 */
3220 { "(bad)", { XX } },
3221 { "(bad)", { XX } },
3222 { "(bad)", { XX } },
3223 { "(bad)", { XX } },
3224 { "(bad)", { XX } },
3225 { "(bad)", { XX } },
3226 { "(bad)", { XX } },
3227 { "(bad)", { XX } },
3228 /* 60 */
3229 { PREGRP89 },
3230 { PREGRP90 },
3231 { PREGRP91 },
3232 { PREGRP92 },
3233 { "(bad)", { XX } },
3234 { "(bad)", { XX } },
3235 { "(bad)", { XX } },
3236 { "(bad)", { XX } },
3237 /* 68 */
3238 { "(bad)", { XX } },
3239 { "(bad)", { XX } },
3240 { "(bad)", { XX } },
3241 { "(bad)", { XX } },
3242 { "(bad)", { XX } },
3243 { "(bad)", { XX } },
3244 { "(bad)", { XX } },
3245 { "(bad)", { XX } },
3246 /* 70 */
3247 { "(bad)", { XX } },
3248 { "(bad)", { XX } },
3249 { "(bad)", { XX } },
3250 { "(bad)", { XX } },
3251 { "(bad)", { XX } },
3252 { "(bad)", { XX } },
3253 { "(bad)", { XX } },
3254 { "(bad)", { XX } },
3255 /* 78 */
3256 { "(bad)", { XX } },
3257 { "(bad)", { XX } },
3258 { "(bad)", { XX } },
3259 { "(bad)", { XX } },
3260 { "(bad)", { XX } },
3261 { "(bad)", { XX } },
3262 { "(bad)", { XX } },
3263 { "(bad)", { XX } },
3264 /* 80 */
3265 { "(bad)", { XX } },
3266 { "(bad)", { XX } },
3267 { "(bad)", { XX } },
3268 { "(bad)", { XX } },
3269 { "(bad)", { XX } },
3270 { "(bad)", { XX } },
3271 { "(bad)", { XX } },
3272 { "(bad)", { XX } },
3273 /* 88 */
3274 { "(bad)", { XX } },
3275 { "(bad)", { XX } },
3276 { "(bad)", { XX } },
3277 { "(bad)", { XX } },
3278 { "(bad)", { XX } },
3279 { "(bad)", { XX } },
3280 { "(bad)", { XX } },
3281 { "(bad)", { XX } },
3282 /* 90 */
3283 { "(bad)", { XX } },
3284 { "(bad)", { XX } },
3285 { "(bad)", { XX } },
3286 { "(bad)", { XX } },
3287 { "(bad)", { XX } },
3288 { "(bad)", { XX } },
3289 { "(bad)", { XX } },
3290 { "(bad)", { XX } },
3291 /* 98 */
3292 { "(bad)", { XX } },
3293 { "(bad)", { XX } },
3294 { "(bad)", { XX } },
3295 { "(bad)", { XX } },
3296 { "(bad)", { XX } },
3297 { "(bad)", { XX } },
3298 { "(bad)", { XX } },
3299 { "(bad)", { XX } },
3300 /* a0 */
3301 { "(bad)", { XX } },
3302 { "(bad)", { XX } },
3303 { "(bad)", { XX } },
3304 { "(bad)", { XX } },
3305 { "(bad)", { XX } },
3306 { "(bad)", { XX } },
3307 { "(bad)", { XX } },
3308 { "(bad)", { XX } },
3309 /* a8 */
3310 { "(bad)", { XX } },
3311 { "(bad)", { XX } },
3312 { "(bad)", { XX } },
3313 { "(bad)", { XX } },
3314 { "(bad)", { XX } },
3315 { "(bad)", { XX } },
3316 { "(bad)", { XX } },
3317 { "(bad)", { XX } },
3318 /* b0 */
3319 { "(bad)", { XX } },
3320 { "(bad)", { XX } },
3321 { "(bad)", { XX } },
3322 { "(bad)", { XX } },
3323 { "(bad)", { XX } },
3324 { "(bad)", { XX } },
3325 { "(bad)", { XX } },
3326 { "(bad)", { XX } },
3327 /* b8 */
3328 { "(bad)", { XX } },
3329 { "(bad)", { XX } },
3330 { "(bad)", { XX } },
3331 { "(bad)", { XX } },
3332 { "(bad)", { XX } },
3333 { "(bad)", { XX } },
3334 { "(bad)", { XX } },
3335 { "(bad)", { XX } },
3336 /* c0 */
3337 { "(bad)", { XX } },
3338 { "(bad)", { XX } },
3339 { "(bad)", { XX } },
3340 { "(bad)", { XX } },
3341 { "(bad)", { XX } },
3342 { "(bad)", { XX } },
3343 { "(bad)", { XX } },
3344 { "(bad)", { XX } },
3345 /* c8 */
3346 { "(bad)", { XX } },
3347 { "(bad)", { XX } },
3348 { "(bad)", { XX } },
3349 { "(bad)", { XX } },
3350 { "(bad)", { XX } },
3351 { "(bad)", { XX } },
3352 { "(bad)", { XX } },
3353 { "(bad)", { XX } },
3354 /* d0 */
3355 { "(bad)", { XX } },
3356 { "(bad)", { XX } },
3357 { "(bad)", { XX } },
3358 { "(bad)", { XX } },
3359 { "(bad)", { XX } },
3360 { "(bad)", { XX } },
3361 { "(bad)", { XX } },
3362 { "(bad)", { XX } },
3363 /* d8 */
3364 { "(bad)", { XX } },
3365 { "(bad)", { XX } },
3366 { "(bad)", { XX } },
3367 { "(bad)", { XX } },
3368 { "(bad)", { XX } },
3369 { "(bad)", { XX } },
3370 { "(bad)", { XX } },
3371 { PREGRP104 },
3372 /* e0 */
3373 { "(bad)", { XX } },
3374 { "(bad)", { XX } },
3375 { "(bad)", { XX } },
3376 { "(bad)", { XX } },
3377 { "(bad)", { XX } },
3378 { "(bad)", { XX } },
3379 { "(bad)", { XX } },
3380 { "(bad)", { XX } },
3381 /* e8 */
3382 { "(bad)", { XX } },
3383 { "(bad)", { XX } },
3384 { "(bad)", { XX } },
3385 { "(bad)", { XX } },
3386 { "(bad)", { XX } },
3387 { "(bad)", { XX } },
3388 { "(bad)", { XX } },
3389 { "(bad)", { XX } },
3390 /* f0 */
3391 { "(bad)", { XX } },
3392 { "(bad)", { XX } },
3393 { "(bad)", { XX } },
3394 { "(bad)", { XX } },
3395 { "(bad)", { XX } },
3396 { "(bad)", { XX } },
3397 { "(bad)", { XX } },
3398 { "(bad)", { XX } },
3399 /* f8 */
3400 { "(bad)", { XX } },
3401 { "(bad)", { XX } },
3402 { "(bad)", { XX } },
3403 { "(bad)", { XX } },
3404 { "(bad)", { XX } },
3405 { "(bad)", { XX } },
3406 { "(bad)", { XX } },
3407 { "(bad)", { XX } },
3411 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
3413 static void
3414 ckprefix (void)
3416 int newrex;
3417 rex = 0;
3418 prefixes = 0;
3419 used_prefixes = 0;
3420 rex_used = 0;
3421 while (1)
3423 fetch_data(the_info, codep + 1);
3424 newrex = 0;
3425 switch (*codep)
3427 /* REX prefixes family. */
3428 case 0x40:
3429 case 0x41:
3430 case 0x42:
3431 case 0x43:
3432 case 0x44:
3433 case 0x45:
3434 case 0x46:
3435 case 0x47:
3436 case 0x48:
3437 case 0x49:
3438 case 0x4a:
3439 case 0x4b:
3440 case 0x4c:
3441 case 0x4d:
3442 case 0x4e:
3443 case 0x4f:
3444 if (address_mode == mode_64bit)
3445 newrex = *codep;
3446 else
3447 return;
3448 break;
3449 case 0xf3:
3450 prefixes |= PREFIX_REPZ;
3451 break;
3452 case 0xf2:
3453 prefixes |= PREFIX_REPNZ;
3454 break;
3455 case 0xf0:
3456 prefixes |= PREFIX_LOCK;
3457 break;
3458 case 0x2e:
3459 prefixes |= PREFIX_CS;
3460 break;
3461 case 0x36:
3462 prefixes |= PREFIX_SS;
3463 break;
3464 case 0x3e:
3465 prefixes |= PREFIX_DS;
3466 break;
3467 case 0x26:
3468 prefixes |= PREFIX_ES;
3469 break;
3470 case 0x64:
3471 prefixes |= PREFIX_FS;
3472 break;
3473 case 0x65:
3474 prefixes |= PREFIX_GS;
3475 break;
3476 case 0x66:
3477 prefixes |= PREFIX_DATA;
3478 break;
3479 case 0x67:
3480 prefixes |= PREFIX_ADDR;
3481 break;
3482 case FWAIT_OPCODE:
3483 /* fwait is really an instruction. If there are prefixes
3484 before the fwait, they belong to the fwait, *not* to the
3485 following instruction. */
3486 if (prefixes || rex)
3488 prefixes |= PREFIX_FWAIT;
3489 codep++;
3490 return;
3492 prefixes = PREFIX_FWAIT;
3493 break;
3494 default:
3495 return;
3497 /* Rex is ignored when followed by another prefix. */
3498 if (rex)
3500 rex_used = rex;
3501 return;
3503 rex = newrex;
3504 codep++;
3508 static void
3509 ckvexprefix (void)
3511 int op, vex2, vex3, newrex = 0, newpfx = prefixes;
3513 if (address_mode == mode_16bit) {
3514 return;
3517 fetch_data(the_info, codep + 1);
3518 op = *codep;
3520 if (op != 0xc4 && op != 0xc5) {
3521 return;
3524 fetch_data(the_info, codep + 2);
3525 vex2 = codep[1];
3527 if (address_mode == mode_32bit && (vex2 & 0xc0) != 0xc0) {
3528 return;
3531 if (op == 0xc4) {
3532 /* Three byte VEX prefix. */
3533 fetch_data(the_info, codep + 3);
3534 vex3 = codep[2];
3536 newrex |= (vex2 & 0x80 ? 0 : REX_R);
3537 newrex |= (vex2 & 0x40 ? 0 : REX_X);
3538 newrex |= (vex2 & 0x20 ? 0 : REX_B);
3539 newrex |= (vex3 & 0x80 ? REX_W : 0);
3540 switch (vex2 & 0x1f) { /* VEX.m-mmmm */
3541 case 1:
3542 newpfx |= PREFIX_VEX_0F;
3543 break;
3544 case 2:
3545 newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F38;
3546 break;
3547 case 3:
3548 newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F3A;
3549 break;
3551 vex2 = vex3;
3552 codep += 3;
3553 } else {
3554 /* Two byte VEX prefix. */
3555 newrex |= (vex2 & 0x80 ? 0 : REX_R);
3556 codep += 2;
3559 vex_reg = (~vex2 >> 3) & 15; /* VEX.vvvv */
3560 switch (vex2 & 3) { /* VEX.pp */
3561 case 1:
3562 newpfx |= PREFIX_DATA; /* 0x66 */
3563 break;
3564 case 2:
3565 newpfx |= PREFIX_REPZ; /* 0xf3 */
3566 break;
3567 case 3:
3568 newpfx |= PREFIX_REPNZ; /* 0xf2 */
3569 break;
3572 rex = newrex;
3573 prefixes = newpfx;
3576 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
3577 prefix byte. */
3579 static const char *
3580 prefix_name (int pref, int sizeflag)
3582 static const char * const rexes [16] =
3584 "rex", /* 0x40 */
3585 "rex.B", /* 0x41 */
3586 "rex.X", /* 0x42 */
3587 "rex.XB", /* 0x43 */
3588 "rex.R", /* 0x44 */
3589 "rex.RB", /* 0x45 */
3590 "rex.RX", /* 0x46 */
3591 "rex.RXB", /* 0x47 */
3592 "rex.W", /* 0x48 */
3593 "rex.WB", /* 0x49 */
3594 "rex.WX", /* 0x4a */
3595 "rex.WXB", /* 0x4b */
3596 "rex.WR", /* 0x4c */
3597 "rex.WRB", /* 0x4d */
3598 "rex.WRX", /* 0x4e */
3599 "rex.WRXB", /* 0x4f */
3602 switch (pref)
3604 /* REX prefixes family. */
3605 case 0x40:
3606 case 0x41:
3607 case 0x42:
3608 case 0x43:
3609 case 0x44:
3610 case 0x45:
3611 case 0x46:
3612 case 0x47:
3613 case 0x48:
3614 case 0x49:
3615 case 0x4a:
3616 case 0x4b:
3617 case 0x4c:
3618 case 0x4d:
3619 case 0x4e:
3620 case 0x4f:
3621 return rexes [pref - 0x40];
3622 case 0xf3:
3623 return "repz";
3624 case 0xf2:
3625 return "repnz";
3626 case 0xf0:
3627 return "lock";
3628 case 0x2e:
3629 return "cs";
3630 case 0x36:
3631 return "ss";
3632 case 0x3e:
3633 return "ds";
3634 case 0x26:
3635 return "es";
3636 case 0x64:
3637 return "fs";
3638 case 0x65:
3639 return "gs";
3640 case 0x66:
3641 return (sizeflag & DFLAG) ? "data16" : "data32";
3642 case 0x67:
3643 if (address_mode == mode_64bit)
3644 return (sizeflag & AFLAG) ? "addr32" : "addr64";
3645 else
3646 return (sizeflag & AFLAG) ? "addr16" : "addr32";
3647 case FWAIT_OPCODE:
3648 return "fwait";
3649 default:
3650 return NULL;
3654 static char op_out[MAX_OPERANDS][100];
3655 static int op_ad, op_index[MAX_OPERANDS];
3656 static int two_source_ops;
3657 static bfd_vma op_address[MAX_OPERANDS];
3658 static bfd_vma op_riprel[MAX_OPERANDS];
3659 static bfd_vma start_pc;
3662 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
3663 * (see topic "Redundant prefixes" in the "Differences from 8086"
3664 * section of the "Virtual 8086 Mode" chapter.)
3665 * 'pc' should be the address of this instruction, it will
3666 * be used to print the target address if this is a relative jump or call
3667 * The function returns the length of this instruction in bytes.
3670 static char intel_syntax;
3671 static char open_char;
3672 static char close_char;
3673 static char separator_char;
3674 static char scale_char;
3677 print_insn_i386 (bfd_vma pc, disassemble_info *info)
3679 intel_syntax = -1;
3681 return print_insn (pc, info);
3684 static int
3685 print_insn (bfd_vma pc, disassemble_info *info)
3687 const struct dis386 *dp;
3688 int i;
3689 char *op_txt[MAX_OPERANDS];
3690 int needcomma;
3691 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3692 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
3693 int sizeflag;
3694 const char *p;
3695 struct dis_private priv;
3696 unsigned char op;
3697 unsigned char threebyte;
3699 if (info->mach == bfd_mach_x86_64_intel_syntax
3700 || info->mach == bfd_mach_x86_64)
3701 address_mode = mode_64bit;
3702 else
3703 address_mode = mode_32bit;
3705 if (intel_syntax == (char) -1)
3706 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
3707 || info->mach == bfd_mach_x86_64_intel_syntax);
3709 if (info->mach == bfd_mach_i386_i386
3710 || info->mach == bfd_mach_x86_64
3711 || info->mach == bfd_mach_i386_i386_intel_syntax
3712 || info->mach == bfd_mach_x86_64_intel_syntax)
3713 priv.orig_sizeflag = AFLAG | DFLAG;
3714 else if (info->mach == bfd_mach_i386_i8086)
3715 priv.orig_sizeflag = 0;
3716 else
3717 abort ();
3719 for (p = info->disassembler_options; p != NULL; )
3721 if (strncmp (p, "x86-64", 6) == 0)
3723 address_mode = mode_64bit;
3724 priv.orig_sizeflag = AFLAG | DFLAG;
3726 else if (strncmp (p, "i386", 4) == 0)
3728 address_mode = mode_32bit;
3729 priv.orig_sizeflag = AFLAG | DFLAG;
3731 else if (strncmp (p, "i8086", 5) == 0)
3733 address_mode = mode_16bit;
3734 priv.orig_sizeflag = 0;
3736 else if (strncmp (p, "intel", 5) == 0)
3738 intel_syntax = 1;
3740 else if (strncmp (p, "att", 3) == 0)
3742 intel_syntax = 0;
3744 else if (strncmp (p, "addr", 4) == 0)
3746 if (address_mode == mode_64bit)
3748 if (p[4] == '3' && p[5] == '2')
3749 priv.orig_sizeflag &= ~AFLAG;
3750 else if (p[4] == '6' && p[5] == '4')
3751 priv.orig_sizeflag |= AFLAG;
3753 else
3755 if (p[4] == '1' && p[5] == '6')
3756 priv.orig_sizeflag &= ~AFLAG;
3757 else if (p[4] == '3' && p[5] == '2')
3758 priv.orig_sizeflag |= AFLAG;
3761 else if (strncmp (p, "data", 4) == 0)
3763 if (p[4] == '1' && p[5] == '6')
3764 priv.orig_sizeflag &= ~DFLAG;
3765 else if (p[4] == '3' && p[5] == '2')
3766 priv.orig_sizeflag |= DFLAG;
3768 else if (strncmp (p, "suffix", 6) == 0)
3769 priv.orig_sizeflag |= SUFFIX_ALWAYS;
3771 p = strchr (p, ',');
3772 if (p != NULL)
3773 p++;
3776 if (intel_syntax)
3778 names64 = intel_names64;
3779 names32 = intel_names32;
3780 names16 = intel_names16;
3781 names8 = intel_names8;
3782 names8rex = intel_names8rex;
3783 names_seg = intel_names_seg;
3784 index16 = intel_index16;
3785 open_char = '[';
3786 close_char = ']';
3787 separator_char = '+';
3788 scale_char = '*';
3790 else
3792 names64 = att_names64;
3793 names32 = att_names32;
3794 names16 = att_names16;
3795 names8 = att_names8;
3796 names8rex = att_names8rex;
3797 names_seg = att_names_seg;
3798 index16 = att_index16;
3799 open_char = '(';
3800 close_char = ')';
3801 separator_char = ',';
3802 scale_char = ',';
3805 /* The output looks better if we put 7 bytes on a line, since that
3806 puts most long word instructions on a single line. */
3807 info->bytes_per_line = 7;
3809 info->private_data = &priv;
3810 priv.max_fetched = priv.the_buffer;
3811 priv.insn_start = pc;
3813 obuf[0] = 0;
3814 for (i = 0; i < MAX_OPERANDS; ++i)
3816 op_out[i][0] = 0;
3817 op_index[i] = -1;
3820 the_info = info;
3821 start_pc = pc;
3822 start_codep = priv.the_buffer;
3823 codep = priv.the_buffer;
3825 if (sigsetjmp(priv.bailout, 0) != 0)
3827 const char *name;
3829 /* Getting here means we tried for data but didn't get it. That
3830 means we have an incomplete instruction of some sort. Just
3831 print the first byte as a prefix or a .byte pseudo-op. */
3832 if (codep > priv.the_buffer)
3834 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3835 if (name != NULL)
3836 (*info->fprintf_func) (info->stream, "%s", name);
3837 else
3839 /* Just print the first byte as a .byte instruction. */
3840 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3841 (unsigned int) priv.the_buffer[0]);
3844 return 1;
3847 return -1;
3850 obufp = obuf;
3851 ckprefix ();
3852 ckvexprefix ();
3854 insn_codep = codep;
3855 sizeflag = priv.orig_sizeflag;
3857 fetch_data(info, codep + 1);
3858 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3860 if (((prefixes & PREFIX_FWAIT)
3861 && ((*codep < 0xd8) || (*codep > 0xdf)))
3862 || (rex && rex_used))
3864 const char *name;
3866 /* fwait not followed by floating point instruction, or rex followed
3867 by other prefixes. Print the first prefix. */
3868 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3869 if (name == NULL)
3870 name = INTERNAL_DISASSEMBLER_ERROR;
3871 (*info->fprintf_func) (info->stream, "%s", name);
3872 return 1;
3875 op = 0;
3876 if (prefixes & PREFIX_VEX_0F)
3878 used_prefixes |= PREFIX_VEX_0F | PREFIX_VEX_0F38 | PREFIX_VEX_0F3A;
3879 if (prefixes & PREFIX_VEX_0F38)
3880 threebyte = 0x38;
3881 else if (prefixes & PREFIX_VEX_0F3A)
3882 threebyte = 0x3a;
3883 else
3884 threebyte = *codep++;
3885 goto vex_opcode;
3887 if (*codep == 0x0f)
3889 fetch_data(info, codep + 2);
3890 threebyte = codep[1];
3891 codep += 2;
3892 vex_opcode:
3893 dp = &dis386_twobyte[threebyte];
3894 need_modrm = twobyte_has_modrm[threebyte];
3895 uses_DATA_prefix = twobyte_uses_DATA_prefix[threebyte];
3896 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[threebyte];
3897 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[threebyte];
3898 uses_LOCK_prefix = (threebyte & ~0x02) == 0x20;
3899 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3901 fetch_data(info, codep + 2);
3902 op = *codep++;
3903 switch (threebyte)
3905 case 0x38:
3906 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3907 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3908 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3909 break;
3910 case 0x3a:
3911 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3912 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3913 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3914 break;
3915 default:
3916 break;
3920 else
3922 dp = &dis386[*codep];
3923 need_modrm = onebyte_has_modrm[*codep];
3924 uses_DATA_prefix = 0;
3925 uses_REPNZ_prefix = 0;
3926 /* pause is 0xf3 0x90. */
3927 uses_REPZ_prefix = *codep == 0x90;
3928 uses_LOCK_prefix = 0;
3929 codep++;
3932 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3934 oappend ("repz ");
3935 used_prefixes |= PREFIX_REPZ;
3937 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3939 oappend ("repnz ");
3940 used_prefixes |= PREFIX_REPNZ;
3943 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3945 oappend ("lock ");
3946 used_prefixes |= PREFIX_LOCK;
3949 if (prefixes & PREFIX_ADDR)
3951 sizeflag ^= AFLAG;
3952 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
3954 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3955 oappend ("addr32 ");
3956 else
3957 oappend ("addr16 ");
3958 used_prefixes |= PREFIX_ADDR;
3962 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3964 sizeflag ^= DFLAG;
3965 if (dp->op[2].bytemode == cond_jump_mode
3966 && dp->op[0].bytemode == v_mode
3967 && !intel_syntax)
3969 if (sizeflag & DFLAG)
3970 oappend ("data32 ");
3971 else
3972 oappend ("data16 ");
3973 used_prefixes |= PREFIX_DATA;
3977 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3979 dp = &three_byte_table[dp->op[1].bytemode][op];
3980 modrm.mod = (*codep >> 6) & 3;
3981 modrm.reg = (*codep >> 3) & 7;
3982 modrm.rm = *codep & 7;
3984 else if (need_modrm)
3986 fetch_data(info, codep + 1);
3987 modrm.mod = (*codep >> 6) & 3;
3988 modrm.reg = (*codep >> 3) & 7;
3989 modrm.rm = *codep & 7;
3992 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
3994 dofloat (sizeflag);
3996 else
3998 int index;
3999 if (dp->name == NULL)
4001 switch (dp->op[0].bytemode)
4003 case USE_GROUPS:
4004 dp = &grps[dp->op[1].bytemode][modrm.reg];
4005 break;
4007 case USE_PREFIX_USER_TABLE:
4008 index = 0;
4009 used_prefixes |= (prefixes & PREFIX_REPZ);
4010 if (prefixes & PREFIX_REPZ)
4011 index = 1;
4012 else
4014 /* We should check PREFIX_REPNZ and PREFIX_REPZ
4015 before PREFIX_DATA. */
4016 used_prefixes |= (prefixes & PREFIX_REPNZ);
4017 if (prefixes & PREFIX_REPNZ)
4018 index = 3;
4019 else
4021 used_prefixes |= (prefixes & PREFIX_DATA);
4022 if (prefixes & PREFIX_DATA)
4023 index = 2;
4026 dp = &prefix_user_table[dp->op[1].bytemode][index];
4027 break;
4029 case X86_64_SPECIAL:
4030 index = address_mode == mode_64bit ? 1 : 0;
4031 dp = &x86_64_table[dp->op[1].bytemode][index];
4032 break;
4034 default:
4035 oappend (INTERNAL_DISASSEMBLER_ERROR);
4036 break;
4040 if (putop (dp->name, sizeflag) == 0)
4042 for (i = 0; i < MAX_OPERANDS; ++i)
4044 obufp = op_out[i];
4045 op_ad = MAX_OPERANDS - 1 - i;
4046 if (dp->op[i].rtn)
4047 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
4052 /* See if any prefixes were not used. If so, print the first one
4053 separately. If we don't do this, we'll wind up printing an
4054 instruction stream which does not precisely correspond to the
4055 bytes we are disassembling. */
4056 if ((prefixes & ~used_prefixes) != 0)
4058 const char *name;
4060 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
4061 if (name == NULL)
4062 name = INTERNAL_DISASSEMBLER_ERROR;
4063 (*info->fprintf_func) (info->stream, "%s", name);
4064 return 1;
4066 if (rex & ~rex_used)
4068 const char *name;
4069 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
4070 if (name == NULL)
4071 name = INTERNAL_DISASSEMBLER_ERROR;
4072 (*info->fprintf_func) (info->stream, "%s ", name);
4075 obufp = obuf + strlen (obuf);
4076 for (i = strlen (obuf); i < 6; i++)
4077 oappend (" ");
4078 oappend (" ");
4079 (*info->fprintf_func) (info->stream, "%s", obuf);
4081 /* The enter and bound instructions are printed with operands in the same
4082 order as the intel book; everything else is printed in reverse order. */
4083 if (intel_syntax || two_source_ops)
4085 bfd_vma riprel;
4087 for (i = 0; i < MAX_OPERANDS; ++i)
4088 op_txt[i] = op_out[i];
4090 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
4092 op_ad = op_index[i];
4093 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
4094 op_index[MAX_OPERANDS - 1 - i] = op_ad;
4095 riprel = op_riprel[i];
4096 op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
4097 op_riprel[MAX_OPERANDS - 1 - i] = riprel;
4100 else
4102 for (i = 0; i < MAX_OPERANDS; ++i)
4103 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
4106 needcomma = 0;
4107 for (i = 0; i < MAX_OPERANDS; ++i)
4108 if (*op_txt[i])
4110 if (needcomma)
4111 (*info->fprintf_func) (info->stream, ",");
4112 if (op_index[i] != -1 && !op_riprel[i])
4113 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
4114 else
4115 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
4116 needcomma = 1;
4119 for (i = 0; i < MAX_OPERANDS; i++)
4120 if (op_index[i] != -1 && op_riprel[i])
4122 (*info->fprintf_func) (info->stream, " # ");
4123 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
4124 + op_address[op_index[i]]), info);
4125 break;
4127 return codep - priv.the_buffer;
4130 static const char *float_mem[] = {
4131 /* d8 */
4132 "fadd{s||s|}",
4133 "fmul{s||s|}",
4134 "fcom{s||s|}",
4135 "fcomp{s||s|}",
4136 "fsub{s||s|}",
4137 "fsubr{s||s|}",
4138 "fdiv{s||s|}",
4139 "fdivr{s||s|}",
4140 /* d9 */
4141 "fld{s||s|}",
4142 "(bad)",
4143 "fst{s||s|}",
4144 "fstp{s||s|}",
4145 "fldenvIC",
4146 "fldcw",
4147 "fNstenvIC",
4148 "fNstcw",
4149 /* da */
4150 "fiadd{l||l|}",
4151 "fimul{l||l|}",
4152 "ficom{l||l|}",
4153 "ficomp{l||l|}",
4154 "fisub{l||l|}",
4155 "fisubr{l||l|}",
4156 "fidiv{l||l|}",
4157 "fidivr{l||l|}",
4158 /* db */
4159 "fild{l||l|}",
4160 "fisttp{l||l|}",
4161 "fist{l||l|}",
4162 "fistp{l||l|}",
4163 "(bad)",
4164 "fld{t||t|}",
4165 "(bad)",
4166 "fstp{t||t|}",
4167 /* dc */
4168 "fadd{l||l|}",
4169 "fmul{l||l|}",
4170 "fcom{l||l|}",
4171 "fcomp{l||l|}",
4172 "fsub{l||l|}",
4173 "fsubr{l||l|}",
4174 "fdiv{l||l|}",
4175 "fdivr{l||l|}",
4176 /* dd */
4177 "fld{l||l|}",
4178 "fisttp{ll||ll|}",
4179 "fst{l||l|}",
4180 "fstp{l||l|}",
4181 "frstorIC",
4182 "(bad)",
4183 "fNsaveIC",
4184 "fNstsw",
4185 /* de */
4186 "fiadd",
4187 "fimul",
4188 "ficom",
4189 "ficomp",
4190 "fisub",
4191 "fisubr",
4192 "fidiv",
4193 "fidivr",
4194 /* df */
4195 "fild",
4196 "fisttp",
4197 "fist",
4198 "fistp",
4199 "fbld",
4200 "fild{ll||ll|}",
4201 "fbstp",
4202 "fistp{ll||ll|}",
4205 static const unsigned char float_mem_mode[] = {
4206 /* d8 */
4207 d_mode,
4208 d_mode,
4209 d_mode,
4210 d_mode,
4211 d_mode,
4212 d_mode,
4213 d_mode,
4214 d_mode,
4215 /* d9 */
4216 d_mode,
4218 d_mode,
4219 d_mode,
4221 w_mode,
4223 w_mode,
4224 /* da */
4225 d_mode,
4226 d_mode,
4227 d_mode,
4228 d_mode,
4229 d_mode,
4230 d_mode,
4231 d_mode,
4232 d_mode,
4233 /* db */
4234 d_mode,
4235 d_mode,
4236 d_mode,
4237 d_mode,
4239 t_mode,
4241 t_mode,
4242 /* dc */
4243 q_mode,
4244 q_mode,
4245 q_mode,
4246 q_mode,
4247 q_mode,
4248 q_mode,
4249 q_mode,
4250 q_mode,
4251 /* dd */
4252 q_mode,
4253 q_mode,
4254 q_mode,
4255 q_mode,
4259 w_mode,
4260 /* de */
4261 w_mode,
4262 w_mode,
4263 w_mode,
4264 w_mode,
4265 w_mode,
4266 w_mode,
4267 w_mode,
4268 w_mode,
4269 /* df */
4270 w_mode,
4271 w_mode,
4272 w_mode,
4273 w_mode,
4274 t_mode,
4275 q_mode,
4276 t_mode,
4277 q_mode
4280 #define ST { OP_ST, 0 }
4281 #define STi { OP_STi, 0 }
4283 #define FGRPd9_2 NULL, { { NULL, 0 } }
4284 #define FGRPd9_4 NULL, { { NULL, 1 } }
4285 #define FGRPd9_5 NULL, { { NULL, 2 } }
4286 #define FGRPd9_6 NULL, { { NULL, 3 } }
4287 #define FGRPd9_7 NULL, { { NULL, 4 } }
4288 #define FGRPda_5 NULL, { { NULL, 5 } }
4289 #define FGRPdb_4 NULL, { { NULL, 6 } }
4290 #define FGRPde_3 NULL, { { NULL, 7 } }
4291 #define FGRPdf_4 NULL, { { NULL, 8 } }
4293 static const struct dis386 float_reg[][8] = {
4294 /* d8 */
4296 { "fadd", { ST, STi } },
4297 { "fmul", { ST, STi } },
4298 { "fcom", { STi } },
4299 { "fcomp", { STi } },
4300 { "fsub", { ST, STi } },
4301 { "fsubr", { ST, STi } },
4302 { "fdiv", { ST, STi } },
4303 { "fdivr", { ST, STi } },
4305 /* d9 */
4307 { "fld", { STi } },
4308 { "fxch", { STi } },
4309 { FGRPd9_2 },
4310 { "(bad)", { XX } },
4311 { FGRPd9_4 },
4312 { FGRPd9_5 },
4313 { FGRPd9_6 },
4314 { FGRPd9_7 },
4316 /* da */
4318 { "fcmovb", { ST, STi } },
4319 { "fcmove", { ST, STi } },
4320 { "fcmovbe",{ ST, STi } },
4321 { "fcmovu", { ST, STi } },
4322 { "(bad)", { XX } },
4323 { FGRPda_5 },
4324 { "(bad)", { XX } },
4325 { "(bad)", { XX } },
4327 /* db */
4329 { "fcmovnb",{ ST, STi } },
4330 { "fcmovne",{ ST, STi } },
4331 { "fcmovnbe",{ ST, STi } },
4332 { "fcmovnu",{ ST, STi } },
4333 { FGRPdb_4 },
4334 { "fucomi", { ST, STi } },
4335 { "fcomi", { ST, STi } },
4336 { "(bad)", { XX } },
4338 /* dc */
4340 { "fadd", { STi, ST } },
4341 { "fmul", { STi, ST } },
4342 { "(bad)", { XX } },
4343 { "(bad)", { XX } },
4344 #if SYSV386_COMPAT
4345 { "fsub", { STi, ST } },
4346 { "fsubr", { STi, ST } },
4347 { "fdiv", { STi, ST } },
4348 { "fdivr", { STi, ST } },
4349 #else
4350 { "fsubr", { STi, ST } },
4351 { "fsub", { STi, ST } },
4352 { "fdivr", { STi, ST } },
4353 { "fdiv", { STi, ST } },
4354 #endif
4356 /* dd */
4358 { "ffree", { STi } },
4359 { "(bad)", { XX } },
4360 { "fst", { STi } },
4361 { "fstp", { STi } },
4362 { "fucom", { STi } },
4363 { "fucomp", { STi } },
4364 { "(bad)", { XX } },
4365 { "(bad)", { XX } },
4367 /* de */
4369 { "faddp", { STi, ST } },
4370 { "fmulp", { STi, ST } },
4371 { "(bad)", { XX } },
4372 { FGRPde_3 },
4373 #if SYSV386_COMPAT
4374 { "fsubp", { STi, ST } },
4375 { "fsubrp", { STi, ST } },
4376 { "fdivp", { STi, ST } },
4377 { "fdivrp", { STi, ST } },
4378 #else
4379 { "fsubrp", { STi, ST } },
4380 { "fsubp", { STi, ST } },
4381 { "fdivrp", { STi, ST } },
4382 { "fdivp", { STi, ST } },
4383 #endif
4385 /* df */
4387 { "ffreep", { STi } },
4388 { "(bad)", { XX } },
4389 { "(bad)", { XX } },
4390 { "(bad)", { XX } },
4391 { FGRPdf_4 },
4392 { "fucomip", { ST, STi } },
4393 { "fcomip", { ST, STi } },
4394 { "(bad)", { XX } },
4398 static const char *fgrps[][8] = {
4399 /* d9_2 0 */
4401 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4404 /* d9_4 1 */
4406 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4409 /* d9_5 2 */
4411 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4414 /* d9_6 3 */
4416 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4419 /* d9_7 4 */
4421 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4424 /* da_5 5 */
4426 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4429 /* db_4 6 */
4431 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4432 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4435 /* de_3 7 */
4437 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4440 /* df_4 8 */
4442 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4446 static void
4447 dofloat (int sizeflag)
4449 const struct dis386 *dp;
4450 unsigned char floatop;
4452 floatop = codep[-1];
4454 if (modrm.mod != 3)
4456 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
4458 putop (float_mem[fp_indx], sizeflag);
4459 obufp = op_out[0];
4460 op_ad = 2;
4461 OP_E (float_mem_mode[fp_indx], sizeflag);
4462 return;
4464 /* Skip mod/rm byte. */
4465 MODRM_CHECK;
4466 codep++;
4468 dp = &float_reg[floatop - 0xd8][modrm.reg];
4469 if (dp->name == NULL)
4471 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
4473 /* Instruction fnstsw is only one with strange arg. */
4474 if (floatop == 0xdf && codep[-1] == 0xe0)
4475 pstrcpy (op_out[0], sizeof(op_out[0]), names16[0]);
4477 else
4479 putop (dp->name, sizeflag);
4481 obufp = op_out[0];
4482 op_ad = 2;
4483 if (dp->op[0].rtn)
4484 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
4486 obufp = op_out[1];
4487 op_ad = 1;
4488 if (dp->op[1].rtn)
4489 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
4493 static void
4494 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4496 oappend ("%st" + intel_syntax);
4499 static void
4500 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4502 snprintf (scratchbuf, sizeof(scratchbuf), "%%st(%d)", modrm.rm);
4503 oappend (scratchbuf + intel_syntax);
4506 /* Capital letters in template are macros. */
4507 static int
4508 putop (const char *template, int sizeflag)
4510 const char *p;
4511 int alt = 0;
4513 for (p = template; *p; p++)
4515 switch (*p)
4517 default:
4518 *obufp++ = *p;
4519 break;
4520 case '{':
4521 alt = 0;
4522 if (intel_syntax)
4523 alt += 1;
4524 if (address_mode == mode_64bit)
4525 alt += 2;
4526 while (alt != 0)
4528 while (*++p != '|')
4530 if (*p == '}')
4532 /* Alternative not valid. */
4533 pstrcpy (obuf, sizeof(obuf), "(bad)");
4534 obufp = obuf + 5;
4535 return 1;
4537 else if (*p == '\0')
4538 abort ();
4540 alt--;
4542 /* Fall through. */
4543 case 'I':
4544 alt = 1;
4545 continue;
4546 case '|':
4547 while (*++p != '}')
4549 if (*p == '\0')
4550 abort ();
4552 break;
4553 case '}':
4554 break;
4555 case 'A':
4556 if (intel_syntax)
4557 break;
4558 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4559 *obufp++ = 'b';
4560 break;
4561 case 'B':
4562 if (intel_syntax)
4563 break;
4564 if (sizeflag & SUFFIX_ALWAYS)
4565 *obufp++ = 'b';
4566 break;
4567 case 'C':
4568 if (intel_syntax && !alt)
4569 break;
4570 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4572 if (sizeflag & DFLAG)
4573 *obufp++ = intel_syntax ? 'd' : 'l';
4574 else
4575 *obufp++ = intel_syntax ? 'w' : 's';
4576 used_prefixes |= (prefixes & PREFIX_DATA);
4578 break;
4579 case 'D':
4580 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4581 break;
4582 USED_REX (REX_W);
4583 if (modrm.mod == 3)
4585 if (rex & REX_W)
4586 *obufp++ = 'q';
4587 else if (sizeflag & DFLAG)
4588 *obufp++ = intel_syntax ? 'd' : 'l';
4589 else
4590 *obufp++ = 'w';
4591 used_prefixes |= (prefixes & PREFIX_DATA);
4593 else
4594 *obufp++ = 'w';
4595 break;
4596 case 'E': /* For jcxz/jecxz */
4597 if (address_mode == mode_64bit)
4599 if (sizeflag & AFLAG)
4600 *obufp++ = 'r';
4601 else
4602 *obufp++ = 'e';
4604 else
4605 if (sizeflag & AFLAG)
4606 *obufp++ = 'e';
4607 used_prefixes |= (prefixes & PREFIX_ADDR);
4608 break;
4609 case 'F':
4610 if (intel_syntax)
4611 break;
4612 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
4614 if (sizeflag & AFLAG)
4615 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
4616 else
4617 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
4618 used_prefixes |= (prefixes & PREFIX_ADDR);
4620 break;
4621 case 'G':
4622 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4623 break;
4624 if ((rex & REX_W) || (sizeflag & DFLAG))
4625 *obufp++ = 'l';
4626 else
4627 *obufp++ = 'w';
4628 if (!(rex & REX_W))
4629 used_prefixes |= (prefixes & PREFIX_DATA);
4630 break;
4631 case 'H':
4632 if (intel_syntax)
4633 break;
4634 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
4635 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
4637 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
4638 *obufp++ = ',';
4639 *obufp++ = 'p';
4640 if (prefixes & PREFIX_DS)
4641 *obufp++ = 't';
4642 else
4643 *obufp++ = 'n';
4645 break;
4646 case 'J':
4647 if (intel_syntax)
4648 break;
4649 *obufp++ = 'l';
4650 break;
4651 case 'K':
4652 USED_REX (REX_W);
4653 if (rex & REX_W)
4654 *obufp++ = 'q';
4655 else
4656 *obufp++ = 'd';
4657 break;
4658 case 'Z':
4659 if (intel_syntax)
4660 break;
4661 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4663 *obufp++ = 'q';
4664 break;
4666 /* Fall through. */
4667 case 'L':
4668 if (intel_syntax)
4669 break;
4670 if (sizeflag & SUFFIX_ALWAYS)
4671 *obufp++ = 'l';
4672 break;
4673 case 'N':
4674 if ((prefixes & PREFIX_FWAIT) == 0)
4675 *obufp++ = 'n';
4676 else
4677 used_prefixes |= PREFIX_FWAIT;
4678 break;
4679 case 'O':
4680 USED_REX (REX_W);
4681 if (rex & REX_W)
4682 *obufp++ = 'o';
4683 else if (intel_syntax && (sizeflag & DFLAG))
4684 *obufp++ = 'q';
4685 else
4686 *obufp++ = 'd';
4687 if (!(rex & REX_W))
4688 used_prefixes |= (prefixes & PREFIX_DATA);
4689 break;
4690 case 'T':
4691 if (intel_syntax)
4692 break;
4693 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4695 *obufp++ = 'q';
4696 break;
4698 /* Fall through. */
4699 case 'P':
4700 if (intel_syntax)
4701 break;
4702 if ((prefixes & PREFIX_DATA)
4703 || (rex & REX_W)
4704 || (sizeflag & SUFFIX_ALWAYS))
4706 USED_REX (REX_W);
4707 if (rex & REX_W)
4708 *obufp++ = 'q';
4709 else
4711 if (sizeflag & DFLAG)
4712 *obufp++ = 'l';
4713 else
4714 *obufp++ = 'w';
4716 used_prefixes |= (prefixes & PREFIX_DATA);
4718 break;
4719 case 'U':
4720 if (intel_syntax)
4721 break;
4722 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4724 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4725 *obufp++ = 'q';
4726 break;
4728 /* Fall through. */
4729 case 'Q':
4730 if (intel_syntax && !alt)
4731 break;
4732 USED_REX (REX_W);
4733 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4735 if (rex & REX_W)
4736 *obufp++ = 'q';
4737 else
4739 if (sizeflag & DFLAG)
4740 *obufp++ = intel_syntax ? 'd' : 'l';
4741 else
4742 *obufp++ = 'w';
4744 used_prefixes |= (prefixes & PREFIX_DATA);
4746 break;
4747 case 'R':
4748 USED_REX (REX_W);
4749 if (rex & REX_W)
4750 *obufp++ = 'q';
4751 else if (sizeflag & DFLAG)
4753 if (intel_syntax)
4754 *obufp++ = 'd';
4755 else
4756 *obufp++ = 'l';
4758 else
4759 *obufp++ = 'w';
4760 if (intel_syntax && !p[1]
4761 && ((rex & REX_W) || (sizeflag & DFLAG)))
4762 *obufp++ = 'e';
4763 if (!(rex & REX_W))
4764 used_prefixes |= (prefixes & PREFIX_DATA);
4765 break;
4766 case 'V':
4767 if (intel_syntax)
4768 break;
4769 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4771 if (sizeflag & SUFFIX_ALWAYS)
4772 *obufp++ = 'q';
4773 break;
4775 /* Fall through. */
4776 case 'S':
4777 if (intel_syntax)
4778 break;
4779 if (sizeflag & SUFFIX_ALWAYS)
4781 if (rex & REX_W)
4782 *obufp++ = 'q';
4783 else
4785 if (sizeflag & DFLAG)
4786 *obufp++ = 'l';
4787 else
4788 *obufp++ = 'w';
4789 used_prefixes |= (prefixes & PREFIX_DATA);
4792 break;
4793 case 'X':
4794 if (prefixes & PREFIX_DATA)
4795 *obufp++ = 'd';
4796 else
4797 *obufp++ = 's';
4798 used_prefixes |= (prefixes & PREFIX_DATA);
4799 break;
4800 case 'Y':
4801 if (intel_syntax)
4802 break;
4803 if (rex & REX_W)
4805 USED_REX (REX_W);
4806 *obufp++ = 'q';
4808 break;
4809 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
4810 case 'W':
4811 /* operand size flag for cwtl, cbtw */
4812 USED_REX (REX_W);
4813 if (rex & REX_W)
4815 if (intel_syntax)
4816 *obufp++ = 'd';
4817 else
4818 *obufp++ = 'l';
4820 else if (sizeflag & DFLAG)
4821 *obufp++ = 'w';
4822 else
4823 *obufp++ = 'b';
4824 if (!(rex & REX_W))
4825 used_prefixes |= (prefixes & PREFIX_DATA);
4826 break;
4828 alt = 0;
4830 *obufp = 0;
4831 return 0;
4834 static void
4835 oappend (const char *s)
4837 strcpy (obufp, s);
4838 obufp += strlen (s);
4841 static void
4842 append_seg (void)
4844 if (prefixes & PREFIX_CS)
4846 used_prefixes |= PREFIX_CS;
4847 oappend ("%cs:" + intel_syntax);
4849 if (prefixes & PREFIX_DS)
4851 used_prefixes |= PREFIX_DS;
4852 oappend ("%ds:" + intel_syntax);
4854 if (prefixes & PREFIX_SS)
4856 used_prefixes |= PREFIX_SS;
4857 oappend ("%ss:" + intel_syntax);
4859 if (prefixes & PREFIX_ES)
4861 used_prefixes |= PREFIX_ES;
4862 oappend ("%es:" + intel_syntax);
4864 if (prefixes & PREFIX_FS)
4866 used_prefixes |= PREFIX_FS;
4867 oappend ("%fs:" + intel_syntax);
4869 if (prefixes & PREFIX_GS)
4871 used_prefixes |= PREFIX_GS;
4872 oappend ("%gs:" + intel_syntax);
4876 static void
4877 OP_indirE (int bytemode, int sizeflag)
4879 if (!intel_syntax)
4880 oappend ("*");
4881 OP_E (bytemode, sizeflag);
4884 static void
4885 print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp)
4887 if (address_mode == mode_64bit)
4889 if (hex)
4891 char tmp[30];
4892 int i;
4893 buf[0] = '0';
4894 buf[1] = 'x';
4895 snprintf_vma (tmp, sizeof(tmp), disp);
4896 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++) {
4898 pstrcpy (buf + 2, bufsize - 2, tmp + i);
4900 else
4902 bfd_signed_vma v = disp;
4903 char tmp[30];
4904 int i;
4905 if (v < 0)
4907 *(buf++) = '-';
4908 v = -disp;
4909 /* Check for possible overflow on 0x8000000000000000. */
4910 if (v < 0)
4912 pstrcpy (buf, bufsize, "9223372036854775808");
4913 return;
4916 if (!v)
4918 pstrcpy (buf, bufsize, "0");
4919 return;
4922 i = 0;
4923 tmp[29] = 0;
4924 while (v)
4926 tmp[28 - i] = (v % 10) + '0';
4927 v /= 10;
4928 i++;
4930 pstrcpy (buf, bufsize, tmp + 29 - i);
4933 else
4935 if (hex)
4936 snprintf (buf, bufsize, "0x%x", (unsigned int) disp);
4937 else
4938 snprintf (buf, bufsize, "%d", (int) disp);
4942 /* Put DISP in BUF as signed hex number. */
4944 static void
4945 print_displacement (char *buf, bfd_vma disp)
4947 bfd_signed_vma val = disp;
4948 char tmp[30];
4949 int i, j = 0;
4951 if (val < 0)
4953 buf[j++] = '-';
4954 val = -disp;
4956 /* Check for possible overflow. */
4957 if (val < 0)
4959 switch (address_mode)
4961 case mode_64bit:
4962 strcpy (buf + j, "0x8000000000000000");
4963 break;
4964 case mode_32bit:
4965 strcpy (buf + j, "0x80000000");
4966 break;
4967 case mode_16bit:
4968 strcpy (buf + j, "0x8000");
4969 break;
4971 return;
4975 buf[j++] = '0';
4976 buf[j++] = 'x';
4978 snprintf_vma (tmp, sizeof(tmp), val);
4979 for (i = 0; tmp[i] == '0'; i++)
4980 continue;
4981 if (tmp[i] == '\0')
4982 i--;
4983 strcpy (buf + j, tmp + i);
4986 static void
4987 intel_operand_size (int bytemode, int sizeflag)
4989 switch (bytemode)
4991 case b_mode:
4992 case dqb_mode:
4993 oappend ("BYTE PTR ");
4994 break;
4995 case w_mode:
4996 case dqw_mode:
4997 oappend ("WORD PTR ");
4998 break;
4999 case stack_v_mode:
5000 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5002 oappend ("QWORD PTR ");
5003 used_prefixes |= (prefixes & PREFIX_DATA);
5004 break;
5006 /* FALLTHRU */
5007 case v_mode:
5008 case dq_mode:
5009 USED_REX (REX_W);
5010 if (rex & REX_W)
5011 oappend ("QWORD PTR ");
5012 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
5013 oappend ("DWORD PTR ");
5014 else
5015 oappend ("WORD PTR ");
5016 used_prefixes |= (prefixes & PREFIX_DATA);
5017 break;
5018 case z_mode:
5019 if ((rex & REX_W) || (sizeflag & DFLAG))
5020 *obufp++ = 'D';
5021 oappend ("WORD PTR ");
5022 if (!(rex & REX_W))
5023 used_prefixes |= (prefixes & PREFIX_DATA);
5024 break;
5025 case d_mode:
5026 case dqd_mode:
5027 oappend ("DWORD PTR ");
5028 break;
5029 case q_mode:
5030 oappend ("QWORD PTR ");
5031 break;
5032 case m_mode:
5033 if (address_mode == mode_64bit)
5034 oappend ("QWORD PTR ");
5035 else
5036 oappend ("DWORD PTR ");
5037 break;
5038 case f_mode:
5039 if (sizeflag & DFLAG)
5040 oappend ("FWORD PTR ");
5041 else
5042 oappend ("DWORD PTR ");
5043 used_prefixes |= (prefixes & PREFIX_DATA);
5044 break;
5045 case t_mode:
5046 oappend ("TBYTE PTR ");
5047 break;
5048 case x_mode:
5049 oappend ("XMMWORD PTR ");
5050 break;
5051 case o_mode:
5052 oappend ("OWORD PTR ");
5053 break;
5054 default:
5055 break;
5059 static void
5060 OP_E (int bytemode, int sizeflag)
5062 bfd_vma disp;
5063 int add = 0;
5064 int riprel = 0;
5065 USED_REX (REX_B);
5066 if (rex & REX_B)
5067 add += 8;
5069 /* Skip mod/rm byte. */
5070 MODRM_CHECK;
5071 codep++;
5073 if (modrm.mod == 3)
5075 switch (bytemode)
5077 case b_mode:
5078 USED_REX (0);
5079 if (rex)
5080 oappend (names8rex[modrm.rm + add]);
5081 else
5082 oappend (names8[modrm.rm + add]);
5083 break;
5084 case w_mode:
5085 oappend (names16[modrm.rm + add]);
5086 break;
5087 case d_mode:
5088 oappend (names32[modrm.rm + add]);
5089 break;
5090 case q_mode:
5091 oappend (names64[modrm.rm + add]);
5092 break;
5093 case m_mode:
5094 if (address_mode == mode_64bit)
5095 oappend (names64[modrm.rm + add]);
5096 else
5097 oappend (names32[modrm.rm + add]);
5098 break;
5099 case stack_v_mode:
5100 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5102 oappend (names64[modrm.rm + add]);
5103 used_prefixes |= (prefixes & PREFIX_DATA);
5104 break;
5106 bytemode = v_mode;
5107 /* FALLTHRU */
5108 case v_mode:
5109 case dq_mode:
5110 case dqb_mode:
5111 case dqd_mode:
5112 case dqw_mode:
5113 USED_REX (REX_W);
5114 if (rex & REX_W)
5115 oappend (names64[modrm.rm + add]);
5116 else if ((sizeflag & DFLAG) || bytemode != v_mode)
5117 oappend (names32[modrm.rm + add]);
5118 else
5119 oappend (names16[modrm.rm + add]);
5120 used_prefixes |= (prefixes & PREFIX_DATA);
5121 break;
5122 case 0:
5123 break;
5124 default:
5125 oappend (INTERNAL_DISASSEMBLER_ERROR);
5126 break;
5128 return;
5131 disp = 0;
5132 if (intel_syntax)
5133 intel_operand_size (bytemode, sizeflag);
5134 append_seg ();
5136 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5138 /* 32/64 bit address mode */
5139 int havedisp;
5140 int havesib;
5141 int havebase;
5142 int base;
5143 int index = 0;
5144 int scale = 0;
5146 havesib = 0;
5147 havebase = 1;
5148 base = modrm.rm;
5150 if (base == 4)
5152 havesib = 1;
5153 fetch_data(the_info, codep + 1);
5154 index = (*codep >> 3) & 7;
5155 if (address_mode == mode_64bit || index != 0x4)
5156 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
5157 scale = (*codep >> 6) & 3;
5158 base = *codep & 7;
5159 USED_REX (REX_X);
5160 if (rex & REX_X)
5161 index += 8;
5162 codep++;
5164 base += add;
5166 switch (modrm.mod)
5168 case 0:
5169 if ((base & 7) == 5)
5171 havebase = 0;
5172 if (address_mode == mode_64bit && !havesib)
5173 riprel = 1;
5174 disp = get32s ();
5176 break;
5177 case 1:
5178 fetch_data (the_info, codep + 1);
5179 disp = *codep++;
5180 if ((disp & 0x80) != 0)
5181 disp -= 0x100;
5182 break;
5183 case 2:
5184 disp = get32s ();
5185 break;
5188 havedisp = havebase || (havesib && (index != 4 || scale != 0));
5190 if (!intel_syntax)
5191 if (modrm.mod != 0 || (base & 7) == 5)
5193 if (havedisp || riprel)
5194 print_displacement (scratchbuf, disp);
5195 else
5196 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5197 oappend (scratchbuf);
5198 if (riprel)
5200 set_op (disp, 1);
5201 oappend ("(%rip)");
5205 if (havedisp || (intel_syntax && riprel))
5207 *obufp++ = open_char;
5208 if (intel_syntax && riprel)
5210 set_op (disp, 1);
5211 oappend ("rip");
5213 *obufp = '\0';
5214 if (havebase)
5215 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5216 ? names64[base] : names32[base]);
5217 if (havesib)
5219 if (index != 4)
5221 if (!intel_syntax || havebase)
5223 *obufp++ = separator_char;
5224 *obufp = '\0';
5226 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5227 ? names64[index] : names32[index]);
5229 if (scale != 0 || (!intel_syntax && index != 4))
5231 *obufp++ = scale_char;
5232 *obufp = '\0';
5233 snprintf (scratchbuf, sizeof(scratchbuf), "%d", 1 << scale);
5234 oappend (scratchbuf);
5237 if (intel_syntax
5238 && (disp || modrm.mod != 0 || (base & 7) == 5))
5240 if ((bfd_signed_vma) disp >= 0)
5242 *obufp++ = '+';
5243 *obufp = '\0';
5245 else if (modrm.mod != 1)
5247 *obufp++ = '-';
5248 *obufp = '\0';
5249 disp = - (bfd_signed_vma) disp;
5252 print_displacement (scratchbuf, disp);
5253 oappend (scratchbuf);
5256 *obufp++ = close_char;
5257 *obufp = '\0';
5259 else if (intel_syntax)
5261 if (modrm.mod != 0 || (base & 7) == 5)
5263 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5264 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5266 else
5268 oappend (names_seg[ds_reg - es_reg]);
5269 oappend (":");
5271 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5272 oappend (scratchbuf);
5276 else
5277 { /* 16 bit address mode */
5278 switch (modrm.mod)
5280 case 0:
5281 if (modrm.rm == 6)
5283 disp = get16 ();
5284 if ((disp & 0x8000) != 0)
5285 disp -= 0x10000;
5287 break;
5288 case 1:
5289 fetch_data(the_info, codep + 1);
5290 disp = *codep++;
5291 if ((disp & 0x80) != 0)
5292 disp -= 0x100;
5293 break;
5294 case 2:
5295 disp = get16 ();
5296 if ((disp & 0x8000) != 0)
5297 disp -= 0x10000;
5298 break;
5301 if (!intel_syntax)
5302 if (modrm.mod != 0 || modrm.rm == 6)
5304 print_displacement (scratchbuf, disp);
5305 oappend (scratchbuf);
5308 if (modrm.mod != 0 || modrm.rm != 6)
5310 *obufp++ = open_char;
5311 *obufp = '\0';
5312 oappend (index16[modrm.rm]);
5313 if (intel_syntax
5314 && (disp || modrm.mod != 0 || modrm.rm == 6))
5316 if ((bfd_signed_vma) disp >= 0)
5318 *obufp++ = '+';
5319 *obufp = '\0';
5321 else if (modrm.mod != 1)
5323 *obufp++ = '-';
5324 *obufp = '\0';
5325 disp = - (bfd_signed_vma) disp;
5328 print_displacement (scratchbuf, disp);
5329 oappend (scratchbuf);
5332 *obufp++ = close_char;
5333 *obufp = '\0';
5335 else if (intel_syntax)
5337 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5338 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5340 else
5342 oappend (names_seg[ds_reg - es_reg]);
5343 oappend (":");
5345 print_operand_value (scratchbuf, sizeof(scratchbuf), 1,
5346 disp & 0xffff);
5347 oappend (scratchbuf);
5352 static void
5353 OP_G (int bytemode, int sizeflag)
5355 int add = 0;
5356 USED_REX (REX_R);
5357 if (rex & REX_R)
5358 add += 8;
5359 switch (bytemode)
5361 case b_mode:
5362 USED_REX (0);
5363 if (rex)
5364 oappend (names8rex[modrm.reg + add]);
5365 else
5366 oappend (names8[modrm.reg + add]);
5367 break;
5368 case w_mode:
5369 oappend (names16[modrm.reg + add]);
5370 break;
5371 case d_mode:
5372 oappend (names32[modrm.reg + add]);
5373 break;
5374 case q_mode:
5375 oappend (names64[modrm.reg + add]);
5376 break;
5377 case v_mode:
5378 case dq_mode:
5379 case dqb_mode:
5380 case dqd_mode:
5381 case dqw_mode:
5382 USED_REX (REX_W);
5383 if (rex & REX_W)
5384 oappend (names64[modrm.reg + add]);
5385 else if ((sizeflag & DFLAG) || bytemode != v_mode)
5386 oappend (names32[modrm.reg + add]);
5387 else
5388 oappend (names16[modrm.reg + add]);
5389 used_prefixes |= (prefixes & PREFIX_DATA);
5390 break;
5391 case m_mode:
5392 if (address_mode == mode_64bit)
5393 oappend (names64[modrm.reg + add]);
5394 else
5395 oappend (names32[modrm.reg + add]);
5396 break;
5397 default:
5398 oappend (INTERNAL_DISASSEMBLER_ERROR);
5399 break;
5403 static void
5404 OP_vvvv (int bytemode, int sizeflags)
5406 USED_REX (REX_W);
5407 if (rex & REX_W) {
5408 oappend(names64[vex_reg]);
5409 } else {
5410 oappend(names32[vex_reg]);
5414 static bfd_vma
5415 get64 (void)
5417 bfd_vma x;
5418 #ifdef BFD64
5419 unsigned int a;
5420 unsigned int b;
5422 fetch_data(the_info, codep + 8);
5423 a = *codep++ & 0xff;
5424 a |= (*codep++ & 0xff) << 8;
5425 a |= (*codep++ & 0xff) << 16;
5426 a |= (*codep++ & 0xff) << 24;
5427 b = *codep++ & 0xff;
5428 b |= (*codep++ & 0xff) << 8;
5429 b |= (*codep++ & 0xff) << 16;
5430 b |= (*codep++ & 0xff) << 24;
5431 x = a + ((bfd_vma) b << 32);
5432 #else
5433 abort ();
5434 x = 0;
5435 #endif
5436 return x;
5439 static bfd_signed_vma
5440 get32 (void)
5442 bfd_signed_vma x = 0;
5444 fetch_data(the_info, codep + 4);
5445 x = *codep++ & (bfd_signed_vma) 0xff;
5446 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5447 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5448 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5449 return x;
5452 static bfd_signed_vma
5453 get32s (void)
5455 bfd_signed_vma x = 0;
5457 fetch_data(the_info, codep + 4);
5458 x = *codep++ & (bfd_signed_vma) 0xff;
5459 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5460 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5461 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5463 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
5465 return x;
5468 static int
5469 get16 (void)
5471 int x = 0;
5473 fetch_data(the_info, codep + 2);
5474 x = *codep++ & 0xff;
5475 x |= (*codep++ & 0xff) << 8;
5476 return x;
5479 static void
5480 set_op (bfd_vma op, int riprel)
5482 op_index[op_ad] = op_ad;
5483 if (address_mode == mode_64bit)
5485 op_address[op_ad] = op;
5486 op_riprel[op_ad] = riprel;
5488 else
5490 /* Mask to get a 32-bit address. */
5491 op_address[op_ad] = op & 0xffffffff;
5492 op_riprel[op_ad] = riprel & 0xffffffff;
5496 static void
5497 OP_REG (int code, int sizeflag)
5499 const char *s;
5500 int add = 0;
5501 USED_REX (REX_B);
5502 if (rex & REX_B)
5503 add = 8;
5505 switch (code)
5507 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5508 case sp_reg: case bp_reg: case si_reg: case di_reg:
5509 s = names16[code - ax_reg + add];
5510 break;
5511 case es_reg: case ss_reg: case cs_reg:
5512 case ds_reg: case fs_reg: case gs_reg:
5513 s = names_seg[code - es_reg + add];
5514 break;
5515 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5516 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5517 USED_REX (0);
5518 if (rex)
5519 s = names8rex[code - al_reg + add];
5520 else
5521 s = names8[code - al_reg];
5522 break;
5523 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
5524 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
5525 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5527 s = names64[code - rAX_reg + add];
5528 break;
5530 code += eAX_reg - rAX_reg;
5531 /* Fall through. */
5532 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5533 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5534 USED_REX (REX_W);
5535 if (rex & REX_W)
5536 s = names64[code - eAX_reg + add];
5537 else if (sizeflag & DFLAG)
5538 s = names32[code - eAX_reg + add];
5539 else
5540 s = names16[code - eAX_reg + add];
5541 used_prefixes |= (prefixes & PREFIX_DATA);
5542 break;
5543 default:
5544 s = INTERNAL_DISASSEMBLER_ERROR;
5545 break;
5547 oappend (s);
5550 static void
5551 OP_IMREG (int code, int sizeflag)
5553 const char *s;
5555 switch (code)
5557 case indir_dx_reg:
5558 if (intel_syntax)
5559 s = "dx";
5560 else
5561 s = "(%dx)";
5562 break;
5563 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5564 case sp_reg: case bp_reg: case si_reg: case di_reg:
5565 s = names16[code - ax_reg];
5566 break;
5567 case es_reg: case ss_reg: case cs_reg:
5568 case ds_reg: case fs_reg: case gs_reg:
5569 s = names_seg[code - es_reg];
5570 break;
5571 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5572 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5573 USED_REX (0);
5574 if (rex)
5575 s = names8rex[code - al_reg];
5576 else
5577 s = names8[code - al_reg];
5578 break;
5579 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5580 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5581 USED_REX (REX_W);
5582 if (rex & REX_W)
5583 s = names64[code - eAX_reg];
5584 else if (sizeflag & DFLAG)
5585 s = names32[code - eAX_reg];
5586 else
5587 s = names16[code - eAX_reg];
5588 used_prefixes |= (prefixes & PREFIX_DATA);
5589 break;
5590 case z_mode_ax_reg:
5591 if ((rex & REX_W) || (sizeflag & DFLAG))
5592 s = *names32;
5593 else
5594 s = *names16;
5595 if (!(rex & REX_W))
5596 used_prefixes |= (prefixes & PREFIX_DATA);
5597 break;
5598 default:
5599 s = INTERNAL_DISASSEMBLER_ERROR;
5600 break;
5602 oappend (s);
5605 static void
5606 OP_I (int bytemode, int sizeflag)
5608 bfd_signed_vma op;
5609 bfd_signed_vma mask = -1;
5611 switch (bytemode)
5613 case b_mode:
5614 fetch_data(the_info, codep + 1);
5615 op = *codep++;
5616 mask = 0xff;
5617 break;
5618 case q_mode:
5619 if (address_mode == mode_64bit)
5621 op = get32s ();
5622 break;
5624 /* Fall through. */
5625 case v_mode:
5626 USED_REX (REX_W);
5627 if (rex & REX_W)
5628 op = get32s ();
5629 else if (sizeflag & DFLAG)
5631 op = get32 ();
5632 mask = 0xffffffff;
5634 else
5636 op = get16 ();
5637 mask = 0xfffff;
5639 used_prefixes |= (prefixes & PREFIX_DATA);
5640 break;
5641 case w_mode:
5642 mask = 0xfffff;
5643 op = get16 ();
5644 break;
5645 case const_1_mode:
5646 if (intel_syntax)
5647 oappend ("1");
5648 return;
5649 default:
5650 oappend (INTERNAL_DISASSEMBLER_ERROR);
5651 return;
5654 op &= mask;
5655 scratchbuf[0] = '$';
5656 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5657 oappend (scratchbuf + intel_syntax);
5658 scratchbuf[0] = '\0';
5661 static void
5662 OP_I64 (int bytemode, int sizeflag)
5664 bfd_signed_vma op;
5665 bfd_signed_vma mask = -1;
5667 if (address_mode != mode_64bit)
5669 OP_I (bytemode, sizeflag);
5670 return;
5673 switch (bytemode)
5675 case b_mode:
5676 fetch_data(the_info, codep + 1);
5677 op = *codep++;
5678 mask = 0xff;
5679 break;
5680 case v_mode:
5681 USED_REX (REX_W);
5682 if (rex & REX_W)
5683 op = get64 ();
5684 else if (sizeflag & DFLAG)
5686 op = get32 ();
5687 mask = 0xffffffff;
5689 else
5691 op = get16 ();
5692 mask = 0xfffff;
5694 used_prefixes |= (prefixes & PREFIX_DATA);
5695 break;
5696 case w_mode:
5697 mask = 0xfffff;
5698 op = get16 ();
5699 break;
5700 default:
5701 oappend (INTERNAL_DISASSEMBLER_ERROR);
5702 return;
5705 op &= mask;
5706 scratchbuf[0] = '$';
5707 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5708 oappend (scratchbuf + intel_syntax);
5709 scratchbuf[0] = '\0';
5712 static void
5713 OP_sI (int bytemode, int sizeflag)
5715 bfd_signed_vma op;
5717 switch (bytemode)
5719 case b_mode:
5720 fetch_data(the_info, codep + 1);
5721 op = *codep++;
5722 if ((op & 0x80) != 0)
5723 op -= 0x100;
5724 break;
5725 case v_mode:
5726 USED_REX (REX_W);
5727 if (rex & REX_W)
5728 op = get32s ();
5729 else if (sizeflag & DFLAG)
5731 op = get32s ();
5733 else
5735 op = get16 ();
5736 if ((op & 0x8000) != 0)
5737 op -= 0x10000;
5739 used_prefixes |= (prefixes & PREFIX_DATA);
5740 break;
5741 case w_mode:
5742 op = get16 ();
5743 if ((op & 0x8000) != 0)
5744 op -= 0x10000;
5745 break;
5746 default:
5747 oappend (INTERNAL_DISASSEMBLER_ERROR);
5748 return;
5751 scratchbuf[0] = '$';
5752 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5753 oappend (scratchbuf + intel_syntax);
5756 static void
5757 OP_J (int bytemode, int sizeflag)
5759 bfd_vma disp;
5760 bfd_vma mask = -1;
5761 bfd_vma segment = 0;
5763 switch (bytemode)
5765 case b_mode:
5766 fetch_data(the_info, codep + 1);
5767 disp = *codep++;
5768 if ((disp & 0x80) != 0)
5769 disp -= 0x100;
5770 break;
5771 case v_mode:
5772 if ((sizeflag & DFLAG) || (rex & REX_W))
5773 disp = get32s ();
5774 else
5776 disp = get16 ();
5777 if ((disp & 0x8000) != 0)
5778 disp -= 0x10000;
5779 /* In 16bit mode, address is wrapped around at 64k within
5780 the same segment. Otherwise, a data16 prefix on a jump
5781 instruction means that the pc is masked to 16 bits after
5782 the displacement is added! */
5783 mask = 0xffff;
5784 if ((prefixes & PREFIX_DATA) == 0)
5785 segment = ((start_pc + codep - start_codep)
5786 & ~((bfd_vma) 0xffff));
5788 used_prefixes |= (prefixes & PREFIX_DATA);
5789 break;
5790 default:
5791 oappend (INTERNAL_DISASSEMBLER_ERROR);
5792 return;
5794 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
5795 set_op (disp, 0);
5796 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5797 oappend (scratchbuf);
5800 static void
5801 OP_SEG (int bytemode, int sizeflag)
5803 if (bytemode == w_mode)
5804 oappend (names_seg[modrm.reg]);
5805 else
5806 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
5809 static void
5810 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
5812 int seg, offset;
5814 if (sizeflag & DFLAG)
5816 offset = get32 ();
5817 seg = get16 ();
5819 else
5821 offset = get16 ();
5822 seg = get16 ();
5824 used_prefixes |= (prefixes & PREFIX_DATA);
5825 if (intel_syntax)
5826 snprintf (scratchbuf, sizeof(scratchbuf), "0x%x:0x%x", seg, offset);
5827 else
5828 snprintf (scratchbuf, sizeof(scratchbuf), "$0x%x,$0x%x", seg, offset);
5829 oappend (scratchbuf);
5832 static void
5833 OP_OFF (int bytemode, int sizeflag)
5835 bfd_vma off;
5837 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5838 intel_operand_size (bytemode, sizeflag);
5839 append_seg ();
5841 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5842 off = get32 ();
5843 else
5844 off = get16 ();
5846 if (intel_syntax)
5848 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5849 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5851 oappend (names_seg[ds_reg - es_reg]);
5852 oappend (":");
5855 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
5856 oappend (scratchbuf);
5859 static void
5860 OP_OFF64 (int bytemode, int sizeflag)
5862 bfd_vma off;
5864 if (address_mode != mode_64bit
5865 || (prefixes & PREFIX_ADDR))
5867 OP_OFF (bytemode, sizeflag);
5868 return;
5871 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5872 intel_operand_size (bytemode, sizeflag);
5873 append_seg ();
5875 off = get64 ();
5877 if (intel_syntax)
5879 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5880 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5882 oappend (names_seg[ds_reg - es_reg]);
5883 oappend (":");
5886 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
5887 oappend (scratchbuf);
5890 static void
5891 ptr_reg (int code, int sizeflag)
5893 const char *s;
5895 *obufp++ = open_char;
5896 used_prefixes |= (prefixes & PREFIX_ADDR);
5897 if (address_mode == mode_64bit)
5899 if (!(sizeflag & AFLAG))
5900 s = names32[code - eAX_reg];
5901 else
5902 s = names64[code - eAX_reg];
5904 else if (sizeflag & AFLAG)
5905 s = names32[code - eAX_reg];
5906 else
5907 s = names16[code - eAX_reg];
5908 oappend (s);
5909 *obufp++ = close_char;
5910 *obufp = 0;
5913 static void
5914 OP_ESreg (int code, int sizeflag)
5916 if (intel_syntax)
5918 switch (codep[-1])
5920 case 0x6d: /* insw/insl */
5921 intel_operand_size (z_mode, sizeflag);
5922 break;
5923 case 0xa5: /* movsw/movsl/movsq */
5924 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5925 case 0xab: /* stosw/stosl */
5926 case 0xaf: /* scasw/scasl */
5927 intel_operand_size (v_mode, sizeflag);
5928 break;
5929 default:
5930 intel_operand_size (b_mode, sizeflag);
5933 oappend ("%es:" + intel_syntax);
5934 ptr_reg (code, sizeflag);
5937 static void
5938 OP_DSreg (int code, int sizeflag)
5940 if (intel_syntax)
5942 switch (codep[-1])
5944 case 0x6f: /* outsw/outsl */
5945 intel_operand_size (z_mode, sizeflag);
5946 break;
5947 case 0xa5: /* movsw/movsl/movsq */
5948 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5949 case 0xad: /* lodsw/lodsl/lodsq */
5950 intel_operand_size (v_mode, sizeflag);
5951 break;
5952 default:
5953 intel_operand_size (b_mode, sizeflag);
5956 if ((prefixes
5957 & (PREFIX_CS
5958 | PREFIX_DS
5959 | PREFIX_SS
5960 | PREFIX_ES
5961 | PREFIX_FS
5962 | PREFIX_GS)) == 0)
5963 prefixes |= PREFIX_DS;
5964 append_seg ();
5965 ptr_reg (code, sizeflag);
5968 static void
5969 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5971 int add = 0;
5972 if (rex & REX_R)
5974 USED_REX (REX_R);
5975 add = 8;
5977 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5979 used_prefixes |= PREFIX_LOCK;
5980 add = 8;
5982 snprintf (scratchbuf, sizeof(scratchbuf), "%%cr%d", modrm.reg + add);
5983 oappend (scratchbuf + intel_syntax);
5986 static void
5987 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5989 int add = 0;
5990 USED_REX (REX_R);
5991 if (rex & REX_R)
5992 add = 8;
5993 if (intel_syntax)
5994 snprintf (scratchbuf, sizeof(scratchbuf), "db%d", modrm.reg + add);
5995 else
5996 snprintf (scratchbuf, sizeof(scratchbuf), "%%db%d", modrm.reg + add);
5997 oappend (scratchbuf);
6000 static void
6001 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6003 snprintf (scratchbuf, sizeof(scratchbuf), "%%tr%d", modrm.reg);
6004 oappend (scratchbuf + intel_syntax);
6007 static void
6008 OP_R (int bytemode, int sizeflag)
6010 if (modrm.mod == 3)
6011 OP_E (bytemode, sizeflag);
6012 else
6013 BadOp ();
6016 static void
6017 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6019 used_prefixes |= (prefixes & PREFIX_DATA);
6020 if (prefixes & PREFIX_DATA)
6022 int add = 0;
6023 USED_REX (REX_R);
6024 if (rex & REX_R)
6025 add = 8;
6026 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
6028 else
6029 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
6030 oappend (scratchbuf + intel_syntax);
6033 static void
6034 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6036 int add = 0;
6037 USED_REX (REX_R);
6038 if (rex & REX_R)
6039 add = 8;
6040 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
6041 oappend (scratchbuf + intel_syntax);
6044 static void
6045 OP_EM (int bytemode, int sizeflag)
6047 if (modrm.mod != 3)
6049 if (intel_syntax && bytemode == v_mode)
6051 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
6052 used_prefixes |= (prefixes & PREFIX_DATA);
6054 OP_E (bytemode, sizeflag);
6055 return;
6058 /* Skip mod/rm byte. */
6059 MODRM_CHECK;
6060 codep++;
6061 used_prefixes |= (prefixes & PREFIX_DATA);
6062 if (prefixes & PREFIX_DATA)
6064 int add = 0;
6066 USED_REX (REX_B);
6067 if (rex & REX_B)
6068 add = 8;
6069 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
6071 else
6072 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
6073 oappend (scratchbuf + intel_syntax);
6076 /* cvt* are the only instructions in sse2 which have
6077 both SSE and MMX operands and also have 0x66 prefix
6078 in their opcode. 0x66 was originally used to differentiate
6079 between SSE and MMX instruction(operands). So we have to handle the
6080 cvt* separately using OP_EMC and OP_MXC */
6081 static void
6082 OP_EMC (int bytemode, int sizeflag)
6084 if (modrm.mod != 3)
6086 if (intel_syntax && bytemode == v_mode)
6088 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
6089 used_prefixes |= (prefixes & PREFIX_DATA);
6091 OP_E (bytemode, sizeflag);
6092 return;
6095 /* Skip mod/rm byte. */
6096 MODRM_CHECK;
6097 codep++;
6098 used_prefixes |= (prefixes & PREFIX_DATA);
6099 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
6100 oappend (scratchbuf + intel_syntax);
6103 static void
6104 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6106 used_prefixes |= (prefixes & PREFIX_DATA);
6107 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
6108 oappend (scratchbuf + intel_syntax);
6111 static void
6112 OP_EX (int bytemode, int sizeflag)
6114 int add = 0;
6115 if (modrm.mod != 3)
6117 OP_E (bytemode, sizeflag);
6118 return;
6120 USED_REX (REX_B);
6121 if (rex & REX_B)
6122 add = 8;
6124 /* Skip mod/rm byte. */
6125 MODRM_CHECK;
6126 codep++;
6127 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
6128 oappend (scratchbuf + intel_syntax);
6131 static void
6132 OP_MS (int bytemode, int sizeflag)
6134 if (modrm.mod == 3)
6135 OP_EM (bytemode, sizeflag);
6136 else
6137 BadOp ();
6140 static void
6141 OP_XS (int bytemode, int sizeflag)
6143 if (modrm.mod == 3)
6144 OP_EX (bytemode, sizeflag);
6145 else
6146 BadOp ();
6149 static void
6150 OP_M (int bytemode, int sizeflag)
6152 if (modrm.mod == 3)
6153 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
6154 BadOp ();
6155 else
6156 OP_E (bytemode, sizeflag);
6159 static void
6160 OP_0f07 (int bytemode, int sizeflag)
6162 if (modrm.mod != 3 || modrm.rm != 0)
6163 BadOp ();
6164 else
6165 OP_E (bytemode, sizeflag);
6168 static void
6169 OP_0fae (int bytemode, int sizeflag)
6171 if (modrm.mod == 3)
6173 if (modrm.reg == 7)
6174 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
6176 if (modrm.reg < 5 || modrm.rm != 0)
6178 BadOp (); /* bad sfence, mfence, or lfence */
6179 return;
6182 else if (modrm.reg != 7)
6184 BadOp (); /* bad clflush */
6185 return;
6188 OP_E (bytemode, sizeflag);
6191 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
6192 32bit mode and "xchg %rax,%rax" in 64bit mode. */
6194 static void
6195 NOP_Fixup1 (int bytemode, int sizeflag)
6197 if ((prefixes & PREFIX_DATA) != 0
6198 || (rex != 0
6199 && rex != 0x48
6200 && address_mode == mode_64bit))
6201 OP_REG (bytemode, sizeflag);
6202 else
6203 strcpy (obuf, "nop");
6206 static void
6207 NOP_Fixup2 (int bytemode, int sizeflag)
6209 if ((prefixes & PREFIX_DATA) != 0
6210 || (rex != 0
6211 && rex != 0x48
6212 && address_mode == mode_64bit))
6213 OP_IMREG (bytemode, sizeflag);
6216 static const char *Suffix3DNow[] = {
6217 /* 00 */ NULL, NULL, NULL, NULL,
6218 /* 04 */ NULL, NULL, NULL, NULL,
6219 /* 08 */ NULL, NULL, NULL, NULL,
6220 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
6221 /* 10 */ NULL, NULL, NULL, NULL,
6222 /* 14 */ NULL, NULL, NULL, NULL,
6223 /* 18 */ NULL, NULL, NULL, NULL,
6224 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
6225 /* 20 */ NULL, NULL, NULL, NULL,
6226 /* 24 */ NULL, NULL, NULL, NULL,
6227 /* 28 */ NULL, NULL, NULL, NULL,
6228 /* 2C */ NULL, NULL, NULL, NULL,
6229 /* 30 */ NULL, NULL, NULL, NULL,
6230 /* 34 */ NULL, NULL, NULL, NULL,
6231 /* 38 */ NULL, NULL, NULL, NULL,
6232 /* 3C */ NULL, NULL, NULL, NULL,
6233 /* 40 */ NULL, NULL, NULL, NULL,
6234 /* 44 */ NULL, NULL, NULL, NULL,
6235 /* 48 */ NULL, NULL, NULL, NULL,
6236 /* 4C */ NULL, NULL, NULL, NULL,
6237 /* 50 */ NULL, NULL, NULL, NULL,
6238 /* 54 */ NULL, NULL, NULL, NULL,
6239 /* 58 */ NULL, NULL, NULL, NULL,
6240 /* 5C */ NULL, NULL, NULL, NULL,
6241 /* 60 */ NULL, NULL, NULL, NULL,
6242 /* 64 */ NULL, NULL, NULL, NULL,
6243 /* 68 */ NULL, NULL, NULL, NULL,
6244 /* 6C */ NULL, NULL, NULL, NULL,
6245 /* 70 */ NULL, NULL, NULL, NULL,
6246 /* 74 */ NULL, NULL, NULL, NULL,
6247 /* 78 */ NULL, NULL, NULL, NULL,
6248 /* 7C */ NULL, NULL, NULL, NULL,
6249 /* 80 */ NULL, NULL, NULL, NULL,
6250 /* 84 */ NULL, NULL, NULL, NULL,
6251 /* 88 */ NULL, NULL, "pfnacc", NULL,
6252 /* 8C */ NULL, NULL, "pfpnacc", NULL,
6253 /* 90 */ "pfcmpge", NULL, NULL, NULL,
6254 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
6255 /* 98 */ NULL, NULL, "pfsub", NULL,
6256 /* 9C */ NULL, NULL, "pfadd", NULL,
6257 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
6258 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
6259 /* A8 */ NULL, NULL, "pfsubr", NULL,
6260 /* AC */ NULL, NULL, "pfacc", NULL,
6261 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
6262 /* B4 */ "pfmul", NULL, "pfrcpit2", "pmulhrw",
6263 /* B8 */ NULL, NULL, NULL, "pswapd",
6264 /* BC */ NULL, NULL, NULL, "pavgusb",
6265 /* C0 */ NULL, NULL, NULL, NULL,
6266 /* C4 */ NULL, NULL, NULL, NULL,
6267 /* C8 */ NULL, NULL, NULL, NULL,
6268 /* CC */ NULL, NULL, NULL, NULL,
6269 /* D0 */ NULL, NULL, NULL, NULL,
6270 /* D4 */ NULL, NULL, NULL, NULL,
6271 /* D8 */ NULL, NULL, NULL, NULL,
6272 /* DC */ NULL, NULL, NULL, NULL,
6273 /* E0 */ NULL, NULL, NULL, NULL,
6274 /* E4 */ NULL, NULL, NULL, NULL,
6275 /* E8 */ NULL, NULL, NULL, NULL,
6276 /* EC */ NULL, NULL, NULL, NULL,
6277 /* F0 */ NULL, NULL, NULL, NULL,
6278 /* F4 */ NULL, NULL, NULL, NULL,
6279 /* F8 */ NULL, NULL, NULL, NULL,
6280 /* FC */ NULL, NULL, NULL, NULL,
6283 static void
6284 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6286 const char *mnemonic;
6288 fetch_data(the_info, codep + 1);
6289 /* AMD 3DNow! instructions are specified by an opcode suffix in the
6290 place where an 8-bit immediate would normally go. ie. the last
6291 byte of the instruction. */
6292 obufp = obuf + strlen (obuf);
6293 mnemonic = Suffix3DNow[*codep++ & 0xff];
6294 if (mnemonic)
6295 oappend (mnemonic);
6296 else
6298 /* Since a variable sized modrm/sib chunk is between the start
6299 of the opcode (0x0f0f) and the opcode suffix, we need to do
6300 all the modrm processing first, and don't know until now that
6301 we have a bad opcode. This necessitates some cleaning up. */
6302 op_out[0][0] = '\0';
6303 op_out[1][0] = '\0';
6304 BadOp ();
6308 static const char *simd_cmp_op[] = {
6309 "eq",
6310 "lt",
6311 "le",
6312 "unord",
6313 "neq",
6314 "nlt",
6315 "nle",
6316 "ord"
6319 static void
6320 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6322 unsigned int cmp_type;
6324 fetch_data(the_info, codep + 1);
6325 obufp = obuf + strlen (obuf);
6326 cmp_type = *codep++ & 0xff;
6327 if (cmp_type < 8)
6329 char suffix1 = 'p', suffix2 = 's';
6330 used_prefixes |= (prefixes & PREFIX_REPZ);
6331 if (prefixes & PREFIX_REPZ)
6332 suffix1 = 's';
6333 else
6335 used_prefixes |= (prefixes & PREFIX_DATA);
6336 if (prefixes & PREFIX_DATA)
6337 suffix2 = 'd';
6338 else
6340 used_prefixes |= (prefixes & PREFIX_REPNZ);
6341 if (prefixes & PREFIX_REPNZ)
6342 suffix1 = 's', suffix2 = 'd';
6345 snprintf (scratchbuf, sizeof(scratchbuf), "cmp%s%c%c",
6346 simd_cmp_op[cmp_type], suffix1, suffix2);
6347 used_prefixes |= (prefixes & PREFIX_REPZ);
6348 oappend (scratchbuf);
6350 else
6352 /* We have a bad extension byte. Clean up. */
6353 op_out[0][0] = '\0';
6354 op_out[1][0] = '\0';
6355 BadOp ();
6359 static void
6360 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
6362 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
6363 forms of these instructions. */
6364 if (modrm.mod == 3)
6366 char *p = obuf + strlen (obuf);
6367 *(p + 1) = '\0';
6368 *p = *(p - 1);
6369 *(p - 1) = *(p - 2);
6370 *(p - 2) = *(p - 3);
6371 *(p - 3) = extrachar;
6375 static void
6376 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6378 if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
6380 /* Override "sidt". */
6381 size_t olen = strlen (obuf);
6382 char *p = obuf + olen - 4;
6383 const char * const *names = (address_mode == mode_64bit
6384 ? names64 : names32);
6386 /* We might have a suffix when disassembling with -Msuffix. */
6387 if (*p == 'i')
6388 --p;
6390 /* Remove "addr16/addr32" if we aren't in Intel mode. */
6391 if (!intel_syntax
6392 && (prefixes & PREFIX_ADDR)
6393 && olen >= (4 + 7)
6394 && *(p - 1) == ' '
6395 && strncmp (p - 7, "addr", 4) == 0
6396 && (strncmp (p - 3, "16", 2) == 0
6397 || strncmp (p - 3, "32", 2) == 0))
6398 p -= 7;
6400 if (modrm.rm)
6402 /* mwait %eax,%ecx */
6403 strcpy (p, "mwait");
6404 if (!intel_syntax)
6405 strcpy (op_out[0], names[0]);
6407 else
6409 /* monitor %eax,%ecx,%edx" */
6410 strcpy (p, "monitor");
6411 if (!intel_syntax)
6413 const char * const *op1_names;
6414 if (!(prefixes & PREFIX_ADDR))
6415 op1_names = (address_mode == mode_16bit
6416 ? names16 : names);
6417 else
6419 op1_names = (address_mode != mode_32bit
6420 ? names32 : names16);
6421 used_prefixes |= PREFIX_ADDR;
6423 strcpy (op_out[0], op1_names[0]);
6424 strcpy (op_out[2], names[2]);
6427 if (!intel_syntax)
6429 strcpy (op_out[1], names[1]);
6430 two_source_ops = 1;
6433 codep++;
6435 else
6436 OP_M (0, sizeflag);
6439 static void
6440 SVME_Fixup (int bytemode, int sizeflag)
6442 const char *alt;
6443 char *p;
6445 switch (*codep)
6447 case 0xd8:
6448 alt = "vmrun";
6449 break;
6450 case 0xd9:
6451 alt = "vmmcall";
6452 break;
6453 case 0xda:
6454 alt = "vmload";
6455 break;
6456 case 0xdb:
6457 alt = "vmsave";
6458 break;
6459 case 0xdc:
6460 alt = "stgi";
6461 break;
6462 case 0xdd:
6463 alt = "clgi";
6464 break;
6465 case 0xde:
6466 alt = "skinit";
6467 break;
6468 case 0xdf:
6469 alt = "invlpga";
6470 break;
6471 default:
6472 OP_M (bytemode, sizeflag);
6473 return;
6475 /* Override "lidt". */
6476 p = obuf + strlen (obuf) - 4;
6477 /* We might have a suffix. */
6478 if (*p == 'i')
6479 --p;
6480 strcpy (p, alt);
6481 if (!(prefixes & PREFIX_ADDR))
6483 ++codep;
6484 return;
6486 used_prefixes |= PREFIX_ADDR;
6487 switch (*codep++)
6489 case 0xdf:
6490 strcpy (op_out[1], names32[1]);
6491 two_source_ops = 1;
6492 /* Fall through. */
6493 case 0xd8:
6494 case 0xda:
6495 case 0xdb:
6496 *obufp++ = open_char;
6497 if (address_mode == mode_64bit || (sizeflag & AFLAG))
6498 alt = names32[0];
6499 else
6500 alt = names16[0];
6501 strcpy (obufp, alt);
6502 obufp += strlen (alt);
6503 *obufp++ = close_char;
6504 *obufp = '\0';
6505 break;
6509 static void
6510 INVLPG_Fixup (int bytemode, int sizeflag)
6512 const char *alt;
6514 switch (*codep)
6516 case 0xf8:
6517 alt = "swapgs";
6518 break;
6519 case 0xf9:
6520 alt = "rdtscp";
6521 break;
6522 default:
6523 OP_M (bytemode, sizeflag);
6524 return;
6526 /* Override "invlpg". */
6527 strcpy (obuf + strlen (obuf) - 6, alt);
6528 codep++;
6531 static void
6532 BadOp (void)
6534 /* Throw away prefixes and 1st. opcode byte. */
6535 codep = insn_codep + 1;
6536 oappend ("(bad)");
6539 static void
6540 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6542 if (modrm.mod == 3
6543 && modrm.reg == 0
6544 && modrm.rm >=1
6545 && modrm.rm <= 4)
6547 /* Override "sgdt". */
6548 char *p = obuf + strlen (obuf) - 4;
6550 /* We might have a suffix when disassembling with -Msuffix. */
6551 if (*p == 'g')
6552 --p;
6554 switch (modrm.rm)
6556 case 1:
6557 strcpy (p, "vmcall");
6558 break;
6559 case 2:
6560 strcpy (p, "vmlaunch");
6561 break;
6562 case 3:
6563 strcpy (p, "vmresume");
6564 break;
6565 case 4:
6566 strcpy (p, "vmxoff");
6567 break;
6570 codep++;
6572 else
6573 OP_E (0, sizeflag);
6576 static void
6577 OP_VMX (int bytemode, int sizeflag)
6579 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6580 if (prefixes & PREFIX_DATA)
6581 strcpy (obuf, "vmclear");
6582 else if (prefixes & PREFIX_REPZ)
6583 strcpy (obuf, "vmxon");
6584 else
6585 strcpy (obuf, "vmptrld");
6586 OP_E (bytemode, sizeflag);
6589 static void
6590 REP_Fixup (int bytemode, int sizeflag)
6592 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
6593 lods and stos. */
6594 size_t ilen = 0;
6596 if (prefixes & PREFIX_REPZ)
6597 switch (*insn_codep)
6599 case 0x6e: /* outsb */
6600 case 0x6f: /* outsw/outsl */
6601 case 0xa4: /* movsb */
6602 case 0xa5: /* movsw/movsl/movsq */
6603 if (!intel_syntax)
6604 ilen = 5;
6605 else
6606 ilen = 4;
6607 break;
6608 case 0xaa: /* stosb */
6609 case 0xab: /* stosw/stosl/stosq */
6610 case 0xac: /* lodsb */
6611 case 0xad: /* lodsw/lodsl/lodsq */
6612 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6613 ilen = 5;
6614 else
6615 ilen = 4;
6616 break;
6617 case 0x6c: /* insb */
6618 case 0x6d: /* insl/insw */
6619 if (!intel_syntax)
6620 ilen = 4;
6621 else
6622 ilen = 3;
6623 break;
6624 default:
6625 abort ();
6626 break;
6629 if (ilen != 0)
6631 size_t olen;
6632 char *p;
6634 olen = strlen (obuf);
6635 p = obuf + olen - ilen - 1 - 4;
6636 /* Handle "repz [addr16|addr32]". */
6637 if ((prefixes & PREFIX_ADDR))
6638 p -= 1 + 6;
6640 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6643 switch (bytemode)
6645 case al_reg:
6646 case eAX_reg:
6647 case indir_dx_reg:
6648 OP_IMREG (bytemode, sizeflag);
6649 break;
6650 case eDI_reg:
6651 OP_ESreg (bytemode, sizeflag);
6652 break;
6653 case eSI_reg:
6654 OP_DSreg (bytemode, sizeflag);
6655 break;
6656 default:
6657 abort ();
6658 break;
6662 static void
6663 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
6665 USED_REX (REX_W);
6666 if (rex & REX_W)
6668 /* Change cmpxchg8b to cmpxchg16b. */
6669 char *p = obuf + strlen (obuf) - 2;
6670 strcpy (p, "16b");
6671 bytemode = o_mode;
6673 OP_M (bytemode, sizeflag);
6676 static void
6677 XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6679 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", reg);
6680 oappend (scratchbuf + intel_syntax);
6683 static void
6684 CRC32_Fixup (int bytemode, int sizeflag)
6686 /* Add proper suffix to "crc32". */
6687 char *p = obuf + strlen (obuf);
6689 switch (bytemode)
6691 case b_mode:
6692 if (intel_syntax)
6693 break;
6695 *p++ = 'b';
6696 break;
6697 case v_mode:
6698 if (intel_syntax)
6699 break;
6701 USED_REX (REX_W);
6702 if (rex & REX_W)
6703 *p++ = 'q';
6704 else if (sizeflag & DFLAG)
6705 *p++ = 'l';
6706 else
6707 *p++ = 'w';
6708 used_prefixes |= (prefixes & PREFIX_DATA);
6709 break;
6710 default:
6711 oappend (INTERNAL_DISASSEMBLER_ERROR);
6712 break;
6714 *p = '\0';
6716 if (modrm.mod == 3)
6718 int add;
6720 /* Skip mod/rm byte. */
6721 MODRM_CHECK;
6722 codep++;
6724 USED_REX (REX_B);
6725 add = (rex & REX_B) ? 8 : 0;
6726 if (bytemode == b_mode)
6728 USED_REX (0);
6729 if (rex)
6730 oappend (names8rex[modrm.rm + add]);
6731 else
6732 oappend (names8[modrm.rm + add]);
6734 else
6736 USED_REX (REX_W);
6737 if (rex & REX_W)
6738 oappend (names64[modrm.rm + add]);
6739 else if ((prefixes & PREFIX_DATA))
6740 oappend (names16[modrm.rm + add]);
6741 else
6742 oappend (names32[modrm.rm + add]);
6745 else
6746 OP_E (bytemode, sizeflag);