1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988-2023 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 modified by John Hassey (hassey@dg-rtp.dg.com)
25 x86-64 support added by Jan Hubicka (jh@suse.cz)
26 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
28 /* The main tables describing the instructions is essentially a copy
29 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 Programmers Manual. Usually, there is a capital letter, followed
31 by a small letter. The capital letter tell the addressing mode,
32 and the small letter tells about the operand size. Refer to
33 the Intel manual for details. */
36 #include "disassemble.h"
38 #include "opcode/i386.h"
39 #include "libiberty.h"
40 #include "safe-ctype.h"
42 typedef struct instr_info instr_info
;
44 static bool dofloat (instr_info
*, int);
45 static int putop (instr_info
*, const char *, int);
46 static void oappend_with_style (instr_info
*, const char *,
47 enum disassembler_style
);
49 static bool OP_E (instr_info
*, int, int);
50 static bool OP_E_memory (instr_info
*, int, int);
51 static bool OP_indirE (instr_info
*, int, int);
52 static bool OP_G (instr_info
*, int, int);
53 static bool OP_ST (instr_info
*, int, int);
54 static bool OP_STi (instr_info
*, int, int);
55 static bool OP_Skip_MODRM (instr_info
*, int, int);
56 static bool OP_REG (instr_info
*, int, int);
57 static bool OP_IMREG (instr_info
*, int, int);
58 static bool OP_I (instr_info
*, int, int);
59 static bool OP_I64 (instr_info
*, int, int);
60 static bool OP_sI (instr_info
*, int, int);
61 static bool OP_J (instr_info
*, int, int);
62 static bool OP_SEG (instr_info
*, int, int);
63 static bool OP_DIR (instr_info
*, int, int);
64 static bool OP_OFF (instr_info
*, int, int);
65 static bool OP_OFF64 (instr_info
*, int, int);
66 static bool OP_ESreg (instr_info
*, int, int);
67 static bool OP_DSreg (instr_info
*, int, int);
68 static bool OP_C (instr_info
*, int, int);
69 static bool OP_D (instr_info
*, int, int);
70 static bool OP_T (instr_info
*, int, int);
71 static bool OP_MMX (instr_info
*, int, int);
72 static bool OP_XMM (instr_info
*, int, int);
73 static bool OP_EM (instr_info
*, int, int);
74 static bool OP_EX (instr_info
*, int, int);
75 static bool OP_EMC (instr_info
*, int,int);
76 static bool OP_MXC (instr_info
*, int,int);
77 static bool OP_R (instr_info
*, int, int);
78 static bool OP_M (instr_info
*, int, int);
79 static bool OP_VEX (instr_info
*, int, int);
80 static bool OP_VexR (instr_info
*, int, int);
81 static bool OP_VexW (instr_info
*, int, int);
82 static bool OP_Rounding (instr_info
*, int, int);
83 static bool OP_REG_VexI4 (instr_info
*, int, int);
84 static bool OP_VexI4 (instr_info
*, int, int);
85 static bool OP_0f07 (instr_info
*, int, int);
86 static bool OP_Monitor (instr_info
*, int, int);
87 static bool OP_Mwait (instr_info
*, int, int);
89 static bool PCLMUL_Fixup (instr_info
*, int, int);
90 static bool VPCMP_Fixup (instr_info
*, int, int);
91 static bool VPCOM_Fixup (instr_info
*, int, int);
92 static bool NOP_Fixup (instr_info
*, int, int);
93 static bool OP_3DNowSuffix (instr_info
*, int, int);
94 static bool CMP_Fixup (instr_info
*, int, int);
95 static bool REP_Fixup (instr_info
*, int, int);
96 static bool SEP_Fixup (instr_info
*, int, int);
97 static bool BND_Fixup (instr_info
*, int, int);
98 static bool NOTRACK_Fixup (instr_info
*, int, int);
99 static bool HLE_Fixup1 (instr_info
*, int, int);
100 static bool HLE_Fixup2 (instr_info
*, int, int);
101 static bool HLE_Fixup3 (instr_info
*, int, int);
102 static bool CMPXCHG8B_Fixup (instr_info
*, int, int);
103 static bool XMM_Fixup (instr_info
*, int, int);
104 static bool FXSAVE_Fixup (instr_info
*, int, int);
105 static bool MOVSXD_Fixup (instr_info
*, int, int);
106 static bool DistinctDest_Fixup (instr_info
*, int, int);
107 static bool PREFETCHI_Fixup (instr_info
*, int, int);
109 static void ATTRIBUTE_PRINTF_3
i386_dis_printf (const disassemble_info
*,
110 enum disassembler_style
,
113 /* This character is used to encode style information within the output
114 buffers. See oappend_insert_style for more details. */
115 #define STYLE_MARKER_CHAR '\002'
117 /* The maximum operand buffer size. */
118 #define MAX_OPERAND_BUFFER_SIZE 128
127 static const char *prefix_name (enum address_mode
, uint8_t, int);
137 enum address_mode address_mode
;
139 /* Flags for the prefixes for the current instruction. See below. */
142 /* REX prefix the current instruction. See below. */
144 /* Bits of REX we've already used. */
148 unsigned char need_vex
;
151 /* Flags for ins->prefixes which we somehow handled when printing the
152 current instruction. */
155 /* Flags for EVEX bits which we somehow handled when printing the
156 current instruction. */
159 char obuf
[MAX_OPERAND_BUFFER_SIZE
];
162 const uint8_t *start_codep
;
164 const uint8_t *end_codep
;
165 unsigned char nr_prefixes
;
166 signed char last_lock_prefix
;
167 signed char last_repz_prefix
;
168 signed char last_repnz_prefix
;
169 signed char last_data_prefix
;
170 signed char last_addr_prefix
;
171 signed char last_rex_prefix
;
172 signed char last_seg_prefix
;
173 signed char fwait_prefix
;
174 /* The active segment register prefix. */
175 unsigned char active_seg_prefix
;
177 #define MAX_CODE_LENGTH 15
178 /* We can up to 14 ins->prefixes since the maximum instruction length is
180 uint8_t all_prefixes
[MAX_CODE_LENGTH
- 1];
181 disassemble_info
*info
;
201 int register_specifier
;
204 int mask_register_specifier
;
216 /* Remember if the current op is a jump instruction. */
221 /* Record whether EVEX masking is used incorrectly. */
222 bool illegal_masking
;
225 signed char op_index
[MAX_OPERANDS
];
226 bool op_riprel
[MAX_OPERANDS
];
227 char *op_out
[MAX_OPERANDS
];
228 bfd_vma op_address
[MAX_OPERANDS
];
231 /* On the 386's of 1988, the maximum length of an instruction is 15 bytes.
232 * (see topic "Redundant ins->prefixes" in the "Differences from 8086"
233 * section of the "Virtual 8086 Mode" chapter.)
234 * 'pc' should be the address of this instruction, it will
235 * be used to print the target address if this is a relative jump or call
236 * The function returns the length of this instruction in bytes.
245 enum x86_64_isa isa64
;
252 /* Indexes first byte not fetched. */
253 unsigned int fetched
;
254 uint8_t the_buffer
[2 * MAX_CODE_LENGTH
- 1];
257 /* Mark parts used in the REX prefix. When we are testing for
258 empty prefix (for 8bit register REX extension), just mask it
259 out. Otherwise test for REX bit is excuse for existence of REX
260 only in case value is nonzero. */
261 #define USED_REX(value) \
265 if ((ins->rex & value)) \
266 ins->rex_used |= (value) | REX_OPCODE; \
269 ins->rex_used |= REX_OPCODE; \
273 #define EVEX_b_used 1
274 #define EVEX_len_used 2
276 /* Flags stored in PREFIXES. */
277 #define PREFIX_REPZ 1
278 #define PREFIX_REPNZ 2
281 #define PREFIX_DS 0x10
282 #define PREFIX_ES 0x20
283 #define PREFIX_FS 0x40
284 #define PREFIX_GS 0x80
285 #define PREFIX_LOCK 0x100
286 #define PREFIX_DATA 0x200
287 #define PREFIX_ADDR 0x400
288 #define PREFIX_FWAIT 0x800
290 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
291 to ADDR (exclusive) are valid. Returns true for success, false
294 fetch_code (struct disassemble_info
*info
, const uint8_t *until
)
297 struct dis_private
*priv
= info
->private_data
;
298 bfd_vma start
= priv
->insn_start
+ priv
->fetched
;
299 uint8_t *fetch_end
= priv
->the_buffer
+ priv
->fetched
;
300 ptrdiff_t needed
= until
- fetch_end
;
305 if (priv
->fetched
+ (size_t) needed
<= ARRAY_SIZE (priv
->the_buffer
))
306 status
= (*info
->read_memory_func
) (start
, fetch_end
, needed
, info
);
309 /* If we did manage to read at least one byte, then
310 print_insn_i386 will do something sensible. Otherwise, print
311 an error. We do that here because this is where we know
314 (*info
->memory_error_func
) (status
, start
, info
);
318 priv
->fetched
+= needed
;
323 fetch_modrm (instr_info
*ins
)
325 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
328 ins
->modrm
.mod
= (*ins
->codep
>> 6) & 3;
329 ins
->modrm
.reg
= (*ins
->codep
>> 3) & 7;
330 ins
->modrm
.rm
= *ins
->codep
& 7;
336 fetch_error (const instr_info
*ins
)
338 /* Getting here means we tried for data but didn't get it. That
339 means we have an incomplete instruction of some sort. Just
340 print the first byte as a prefix or a .byte pseudo-op. */
341 const struct dis_private
*priv
= ins
->info
->private_data
;
342 const char *name
= NULL
;
344 if (ins
->codep
<= priv
->the_buffer
)
347 if (ins
->prefixes
|| ins
->fwait_prefix
>= 0 || (ins
->rex
& REX_OPCODE
))
348 name
= prefix_name (ins
->address_mode
, priv
->the_buffer
[0],
349 priv
->orig_sizeflag
);
351 i386_dis_printf (ins
->info
, dis_style_mnemonic
, "%s", name
);
354 /* Just print the first byte as a .byte instruction. */
355 i386_dis_printf (ins
->info
, dis_style_assembler_directive
, ".byte ");
356 i386_dis_printf (ins
->info
, dis_style_immediate
, "%#x",
357 (unsigned int) priv
->the_buffer
[0]);
363 /* Possible values for prefix requirement. */
364 #define PREFIX_IGNORED_SHIFT 16
365 #define PREFIX_IGNORED_REPZ (PREFIX_REPZ << PREFIX_IGNORED_SHIFT)
366 #define PREFIX_IGNORED_REPNZ (PREFIX_REPNZ << PREFIX_IGNORED_SHIFT)
367 #define PREFIX_IGNORED_DATA (PREFIX_DATA << PREFIX_IGNORED_SHIFT)
368 #define PREFIX_IGNORED_ADDR (PREFIX_ADDR << PREFIX_IGNORED_SHIFT)
369 #define PREFIX_IGNORED_LOCK (PREFIX_LOCK << PREFIX_IGNORED_SHIFT)
371 /* Opcode prefixes. */
372 #define PREFIX_OPCODE (PREFIX_REPZ \
376 /* Prefixes ignored. */
377 #define PREFIX_IGNORED (PREFIX_IGNORED_REPZ \
378 | PREFIX_IGNORED_REPNZ \
379 | PREFIX_IGNORED_DATA)
381 #define XX { NULL, 0 }
382 #define Bad_Opcode NULL, { { NULL, 0 } }, 0
384 #define Eb { OP_E, b_mode }
385 #define Ebnd { OP_E, bnd_mode }
386 #define EbS { OP_E, b_swap_mode }
387 #define EbndS { OP_E, bnd_swap_mode }
388 #define Ev { OP_E, v_mode }
389 #define Eva { OP_E, va_mode }
390 #define Ev_bnd { OP_E, v_bnd_mode }
391 #define EvS { OP_E, v_swap_mode }
392 #define Ed { OP_E, d_mode }
393 #define Edq { OP_E, dq_mode }
394 #define Edb { OP_E, db_mode }
395 #define Edw { OP_E, dw_mode }
396 #define Eq { OP_E, q_mode }
397 #define indirEv { OP_indirE, indir_v_mode }
398 #define indirEp { OP_indirE, f_mode }
399 #define stackEv { OP_E, stack_v_mode }
400 #define Em { OP_E, m_mode }
401 #define Ew { OP_E, w_mode }
402 #define M { OP_M, 0 } /* lea, lgdt, etc. */
403 #define Ma { OP_M, a_mode }
404 #define Mb { OP_M, b_mode }
405 #define Md { OP_M, d_mode }
406 #define Mdq { OP_M, dq_mode }
407 #define Mo { OP_M, o_mode }
408 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
409 #define Mq { OP_M, q_mode }
410 #define Mv { OP_M, v_mode }
411 #define Mv_bnd { OP_M, v_bndmk_mode }
412 #define Mw { OP_M, w_mode }
413 #define Mx { OP_M, x_mode }
414 #define Mxmm { OP_M, xmm_mode }
415 #define Mymm { OP_M, ymm_mode }
416 #define Gb { OP_G, b_mode }
417 #define Gbnd { OP_G, bnd_mode }
418 #define Gv { OP_G, v_mode }
419 #define Gd { OP_G, d_mode }
420 #define Gdq { OP_G, dq_mode }
421 #define Gm { OP_G, m_mode }
422 #define Gva { OP_G, va_mode }
423 #define Gw { OP_G, w_mode }
424 #define Ib { OP_I, b_mode }
425 #define sIb { OP_sI, b_mode } /* sign extened byte */
426 #define sIbT { OP_sI, b_T_mode } /* sign extened byte like 'T' */
427 #define Iv { OP_I, v_mode }
428 #define sIv { OP_sI, v_mode }
429 #define Iv64 { OP_I64, v_mode }
430 #define Id { OP_I, d_mode }
431 #define Iw { OP_I, w_mode }
432 #define I1 { OP_I, const_1_mode }
433 #define Jb { OP_J, b_mode }
434 #define Jv { OP_J, v_mode }
435 #define Jdqw { OP_J, dqw_mode }
436 #define Cm { OP_C, m_mode }
437 #define Dm { OP_D, m_mode }
438 #define Td { OP_T, d_mode }
439 #define Skip_MODRM { OP_Skip_MODRM, 0 }
441 #define RMeAX { OP_REG, eAX_reg }
442 #define RMeBX { OP_REG, eBX_reg }
443 #define RMeCX { OP_REG, eCX_reg }
444 #define RMeDX { OP_REG, eDX_reg }
445 #define RMeSP { OP_REG, eSP_reg }
446 #define RMeBP { OP_REG, eBP_reg }
447 #define RMeSI { OP_REG, eSI_reg }
448 #define RMeDI { OP_REG, eDI_reg }
449 #define RMrAX { OP_REG, rAX_reg }
450 #define RMrBX { OP_REG, rBX_reg }
451 #define RMrCX { OP_REG, rCX_reg }
452 #define RMrDX { OP_REG, rDX_reg }
453 #define RMrSP { OP_REG, rSP_reg }
454 #define RMrBP { OP_REG, rBP_reg }
455 #define RMrSI { OP_REG, rSI_reg }
456 #define RMrDI { OP_REG, rDI_reg }
457 #define RMAL { OP_REG, al_reg }
458 #define RMCL { OP_REG, cl_reg }
459 #define RMDL { OP_REG, dl_reg }
460 #define RMBL { OP_REG, bl_reg }
461 #define RMAH { OP_REG, ah_reg }
462 #define RMCH { OP_REG, ch_reg }
463 #define RMDH { OP_REG, dh_reg }
464 #define RMBH { OP_REG, bh_reg }
465 #define RMAX { OP_REG, ax_reg }
466 #define RMDX { OP_REG, dx_reg }
468 #define eAX { OP_IMREG, eAX_reg }
469 #define AL { OP_IMREG, al_reg }
470 #define CL { OP_IMREG, cl_reg }
471 #define zAX { OP_IMREG, z_mode_ax_reg }
472 #define indirDX { OP_IMREG, indir_dx_reg }
474 #define Sw { OP_SEG, w_mode }
475 #define Sv { OP_SEG, v_mode }
476 #define Ap { OP_DIR, 0 }
477 #define Ob { OP_OFF64, b_mode }
478 #define Ov { OP_OFF64, v_mode }
479 #define Xb { OP_DSreg, eSI_reg }
480 #define Xv { OP_DSreg, eSI_reg }
481 #define Xz { OP_DSreg, eSI_reg }
482 #define Yb { OP_ESreg, eDI_reg }
483 #define Yv { OP_ESreg, eDI_reg }
484 #define DSBX { OP_DSreg, eBX_reg }
486 #define es { OP_REG, es_reg }
487 #define ss { OP_REG, ss_reg }
488 #define cs { OP_REG, cs_reg }
489 #define ds { OP_REG, ds_reg }
490 #define fs { OP_REG, fs_reg }
491 #define gs { OP_REG, gs_reg }
493 #define MX { OP_MMX, 0 }
494 #define XM { OP_XMM, 0 }
495 #define XMScalar { OP_XMM, scalar_mode }
496 #define XMGatherD { OP_XMM, vex_vsib_d_w_dq_mode }
497 #define XMGatherQ { OP_XMM, vex_vsib_q_w_dq_mode }
498 #define XMM { OP_XMM, xmm_mode }
499 #define TMM { OP_XMM, tmm_mode }
500 #define XMxmmq { OP_XMM, xmmq_mode }
501 #define EM { OP_EM, v_mode }
502 #define EMS { OP_EM, v_swap_mode }
503 #define EMd { OP_EM, d_mode }
504 #define EMx { OP_EM, x_mode }
505 #define EXbwUnit { OP_EX, bw_unit_mode }
506 #define EXb { OP_EX, b_mode }
507 #define EXw { OP_EX, w_mode }
508 #define EXd { OP_EX, d_mode }
509 #define EXdS { OP_EX, d_swap_mode }
510 #define EXwS { OP_EX, w_swap_mode }
511 #define EXq { OP_EX, q_mode }
512 #define EXqS { OP_EX, q_swap_mode }
513 #define EXdq { OP_EX, dq_mode }
514 #define EXx { OP_EX, x_mode }
515 #define EXxh { OP_EX, xh_mode }
516 #define EXxS { OP_EX, x_swap_mode }
517 #define EXxmm { OP_EX, xmm_mode }
518 #define EXymm { OP_EX, ymm_mode }
519 #define EXxmmq { OP_EX, xmmq_mode }
520 #define EXxmmqh { OP_EX, evex_half_bcst_xmmqh_mode }
521 #define EXEvexHalfBcstXmmq { OP_EX, evex_half_bcst_xmmq_mode }
522 #define EXxmmdw { OP_EX, xmmdw_mode }
523 #define EXxmmqd { OP_EX, xmmqd_mode }
524 #define EXxmmqdh { OP_EX, evex_half_bcst_xmmqdh_mode }
525 #define EXymmq { OP_EX, ymmq_mode }
526 #define EXEvexXGscat { OP_EX, evex_x_gscat_mode }
527 #define EXEvexXNoBcst { OP_EX, evex_x_nobcst_mode }
528 #define Rd { OP_R, d_mode }
529 #define Rdq { OP_R, dq_mode }
530 #define Nq { OP_R, q_mode }
531 #define Ux { OP_R, x_mode }
532 #define Uxmm { OP_R, xmm_mode }
533 #define Rxmmq { OP_R, xmmq_mode }
534 #define Rymm { OP_R, ymm_mode }
535 #define Rtmm { OP_R, tmm_mode }
536 #define EMCq { OP_EMC, q_mode }
537 #define MXC { OP_MXC, 0 }
538 #define OPSUF { OP_3DNowSuffix, 0 }
539 #define SEP { SEP_Fixup, 0 }
540 #define CMP { CMP_Fixup, 0 }
541 #define XMM0 { XMM_Fixup, 0 }
542 #define FXSAVE { FXSAVE_Fixup, 0 }
544 #define Vex { OP_VEX, x_mode }
545 #define VexW { OP_VexW, x_mode }
546 #define VexScalar { OP_VEX, scalar_mode }
547 #define VexScalarR { OP_VexR, scalar_mode }
548 #define VexGatherD { OP_VEX, vex_vsib_d_w_dq_mode }
549 #define VexGatherQ { OP_VEX, vex_vsib_q_w_dq_mode }
550 #define VexGdq { OP_VEX, dq_mode }
551 #define VexTmm { OP_VEX, tmm_mode }
552 #define XMVexI4 { OP_REG_VexI4, x_mode }
553 #define XMVexScalarI4 { OP_REG_VexI4, scalar_mode }
554 #define VexI4 { OP_VexI4, 0 }
555 #define PCLMUL { PCLMUL_Fixup, 0 }
556 #define VPCMP { VPCMP_Fixup, 0 }
557 #define VPCOM { VPCOM_Fixup, 0 }
559 #define EXxEVexR { OP_Rounding, evex_rounding_mode }
560 #define EXxEVexR64 { OP_Rounding, evex_rounding_64_mode }
561 #define EXxEVexS { OP_Rounding, evex_sae_mode }
563 #define MaskG { OP_G, mask_mode }
564 #define MaskE { OP_E, mask_mode }
565 #define MaskR { OP_R, mask_mode }
566 #define MaskBDE { OP_E, mask_bd_mode }
567 #define MaskVex { OP_VEX, mask_mode }
569 #define MVexVSIBDWpX { OP_M, vex_vsib_d_w_dq_mode }
570 #define MVexVSIBQWpX { OP_M, vex_vsib_q_w_dq_mode }
572 #define MVexSIBMEM { OP_M, vex_sibmem_mode }
574 /* Used handle "rep" prefix for string instructions. */
575 #define Xbr { REP_Fixup, eSI_reg }
576 #define Xvr { REP_Fixup, eSI_reg }
577 #define Ybr { REP_Fixup, eDI_reg }
578 #define Yvr { REP_Fixup, eDI_reg }
579 #define Yzr { REP_Fixup, eDI_reg }
580 #define indirDXr { REP_Fixup, indir_dx_reg }
581 #define ALr { REP_Fixup, al_reg }
582 #define eAXr { REP_Fixup, eAX_reg }
584 /* Used handle HLE prefix for lockable instructions. */
585 #define Ebh1 { HLE_Fixup1, b_mode }
586 #define Evh1 { HLE_Fixup1, v_mode }
587 #define Ebh2 { HLE_Fixup2, b_mode }
588 #define Evh2 { HLE_Fixup2, v_mode }
589 #define Ebh3 { HLE_Fixup3, b_mode }
590 #define Evh3 { HLE_Fixup3, v_mode }
592 #define BND { BND_Fixup, 0 }
593 #define NOTRACK { NOTRACK_Fixup, 0 }
595 #define cond_jump_flag { NULL, cond_jump_mode }
596 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
598 /* bits in sizeflag */
599 #define SUFFIX_ALWAYS 4
607 /* byte operand with operand swapped */
609 /* byte operand, sign extend like 'T' suffix */
611 /* operand size depends on prefixes */
613 /* operand size depends on prefixes with operand swapped */
615 /* operand size depends on address prefix */
619 /* double word operand */
621 /* word operand with operand swapped */
623 /* double word operand with operand swapped */
625 /* quad word operand */
627 /* quad word operand with operand swapped */
629 /* ten-byte operand */
631 /* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
632 broadcast enabled. */
634 /* Similar to x_mode, but with different EVEX mem shifts. */
636 /* Similar to x_mode, but with yet different EVEX mem shifts. */
638 /* Similar to x_mode, but with disabled broadcast. */
640 /* Similar to x_mode, but with operands swapped and disabled broadcast
643 /* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
644 broadcast of 16bit enabled. */
646 /* 16-byte XMM operand */
648 /* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
649 memory operand (depending on vector length). Broadcast isn't
652 /* Same as xmmq_mode, but broadcast is allowed. */
653 evex_half_bcst_xmmq_mode
,
654 /* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
655 memory operand (depending on vector length). 16bit broadcast. */
656 evex_half_bcst_xmmqh_mode
,
657 /* 16-byte XMM, word, double word or quad word operand. */
659 /* 16-byte XMM, double word, quad word operand or xmm word operand. */
661 /* 16-byte XMM, double word, quad word operand or xmm word operand.
663 evex_half_bcst_xmmqdh_mode
,
664 /* 32-byte YMM operand */
666 /* quad word, ymmword or zmmword memory operand. */
670 /* d_mode in 32bit, q_mode in 64bit mode. */
672 /* pair of v_mode operands */
678 /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */
680 /* operand size depends on REX.W / VEX.W. */
682 /* Displacements like v_mode without considering Intel64 ISA. */
686 /* bounds operand with operand swapped */
688 /* 4- or 6-byte pointer operand */
691 /* v_mode for indirect branch opcodes. */
693 /* v_mode for stack-related opcodes. */
695 /* non-quad operand size depends on prefixes */
697 /* 16-byte operand */
699 /* registers like d_mode, memory like b_mode. */
701 /* registers like d_mode, memory like w_mode. */
704 /* Operand size depends on the VEX.W bit, with VSIB dword indices. */
705 vex_vsib_d_w_dq_mode
,
706 /* Operand size depends on the VEX.W bit, with VSIB qword indices. */
707 vex_vsib_q_w_dq_mode
,
708 /* mandatory non-vector SIB. */
711 /* scalar, ignore vector length. */
714 /* Static rounding. */
716 /* Static rounding, 64-bit mode only. */
717 evex_rounding_64_mode
,
718 /* Supress all exceptions. */
721 /* Mask register operand. */
723 /* Mask register operand. */
791 #define FLOAT NULL, { { NULL, FLOATCODE } }, 0
793 #define DIS386(T, I) NULL, { { NULL, (T)}, { NULL, (I) } }, 0
794 #define REG_TABLE(I) DIS386 (USE_REG_TABLE, (I))
795 #define MOD_TABLE(I) DIS386 (USE_MOD_TABLE, (I))
796 #define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I))
797 #define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I))
798 #define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I))
799 #define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I))
800 #define XOP_8F_TABLE() DIS386 (USE_XOP_8F_TABLE, 0)
801 #define VEX_C4_TABLE() DIS386 (USE_VEX_C4_TABLE, 0)
802 #define VEX_C5_TABLE() DIS386 (USE_VEX_C5_TABLE, 0)
803 #define VEX_LEN_TABLE(I) DIS386 (USE_VEX_LEN_TABLE, (I))
804 #define VEX_W_TABLE(I) DIS386 (USE_VEX_W_TABLE, (I))
805 #define EVEX_TABLE() DIS386 (USE_EVEX_TABLE, 0)
806 #define EVEX_LEN_TABLE(I) DIS386 (USE_EVEX_LEN_TABLE, (I))
846 REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0
,
897 MOD_VEX_0F3849_X86_64_L_0_W_0
,
910 RM_0F1E_P_1_MOD_3_REG_7
,
911 RM_0FAE_REG_6_MOD_3_P_0
,
915 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
,
916 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
,
922 PREFIX_0F00_REG_6_X86_64
,
923 PREFIX_0F01_REG_0_MOD_3_RM_6
,
924 PREFIX_0F01_REG_0_MOD_3_RM_7
,
925 PREFIX_0F01_REG_1_RM_2
,
926 PREFIX_0F01_REG_1_RM_4
,
927 PREFIX_0F01_REG_1_RM_5
,
928 PREFIX_0F01_REG_1_RM_6
,
929 PREFIX_0F01_REG_1_RM_7
,
930 PREFIX_0F01_REG_3_RM_1
,
931 PREFIX_0F01_REG_5_MOD_0
,
932 PREFIX_0F01_REG_5_MOD_3_RM_0
,
933 PREFIX_0F01_REG_5_MOD_3_RM_1
,
934 PREFIX_0F01_REG_5_MOD_3_RM_2
,
935 PREFIX_0F01_REG_5_MOD_3_RM_4
,
936 PREFIX_0F01_REG_5_MOD_3_RM_5
,
937 PREFIX_0F01_REG_5_MOD_3_RM_6
,
938 PREFIX_0F01_REG_5_MOD_3_RM_7
,
939 PREFIX_0F01_REG_7_MOD_3_RM_2
,
940 PREFIX_0F01_REG_7_MOD_3_RM_5
,
941 PREFIX_0F01_REG_7_MOD_3_RM_6
,
942 PREFIX_0F01_REG_7_MOD_3_RM_7
,
948 PREFIX_0F18_REG_6_MOD_0_X86_64
,
949 PREFIX_0F18_REG_7_MOD_0_X86_64
,
982 PREFIX_0FAE_REG_0_MOD_3
,
983 PREFIX_0FAE_REG_1_MOD_3
,
984 PREFIX_0FAE_REG_2_MOD_3
,
985 PREFIX_0FAE_REG_3_MOD_3
,
986 PREFIX_0FAE_REG_4_MOD_0
,
987 PREFIX_0FAE_REG_4_MOD_3
,
988 PREFIX_0FAE_REG_5_MOD_3
,
989 PREFIX_0FAE_REG_6_MOD_0
,
990 PREFIX_0FAE_REG_6_MOD_3
,
991 PREFIX_0FAE_REG_7_MOD_0
,
996 PREFIX_0FC7_REG_6_MOD_0
,
997 PREFIX_0FC7_REG_6_MOD_3
,
998 PREFIX_0FC7_REG_7_MOD_3
,
1023 PREFIX_VEX_0F41_L_1_W_0
,
1024 PREFIX_VEX_0F41_L_1_W_1
,
1025 PREFIX_VEX_0F42_L_1_W_0
,
1026 PREFIX_VEX_0F42_L_1_W_1
,
1027 PREFIX_VEX_0F44_L_0_W_0
,
1028 PREFIX_VEX_0F44_L_0_W_1
,
1029 PREFIX_VEX_0F45_L_1_W_0
,
1030 PREFIX_VEX_0F45_L_1_W_1
,
1031 PREFIX_VEX_0F46_L_1_W_0
,
1032 PREFIX_VEX_0F46_L_1_W_1
,
1033 PREFIX_VEX_0F47_L_1_W_0
,
1034 PREFIX_VEX_0F47_L_1_W_1
,
1035 PREFIX_VEX_0F4A_L_1_W_0
,
1036 PREFIX_VEX_0F4A_L_1_W_1
,
1037 PREFIX_VEX_0F4B_L_1_W_0
,
1038 PREFIX_VEX_0F4B_L_1_W_1
,
1043 PREFIX_VEX_0F90_L_0_W_0
,
1044 PREFIX_VEX_0F90_L_0_W_1
,
1045 PREFIX_VEX_0F91_L_0_W_0
,
1046 PREFIX_VEX_0F91_L_0_W_1
,
1047 PREFIX_VEX_0F92_L_0_W_0
,
1048 PREFIX_VEX_0F92_L_0_W_1
,
1049 PREFIX_VEX_0F93_L_0_W_0
,
1050 PREFIX_VEX_0F93_L_0_W_1
,
1051 PREFIX_VEX_0F98_L_0_W_0
,
1052 PREFIX_VEX_0F98_L_0_W_1
,
1053 PREFIX_VEX_0F99_L_0_W_0
,
1054 PREFIX_VEX_0F99_L_0_W_1
,
1055 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
,
1056 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
,
1057 PREFIX_VEX_0F384B_X86_64_L_0_W_0
,
1058 PREFIX_VEX_0F3850_W_0
,
1059 PREFIX_VEX_0F3851_W_0
,
1060 PREFIX_VEX_0F385C_X86_64_L_0_W_0
,
1061 PREFIX_VEX_0F385E_X86_64_L_0_W_0
,
1062 PREFIX_VEX_0F386C_X86_64_L_0_W_0
,
1064 PREFIX_VEX_0F38B0_W_0
,
1065 PREFIX_VEX_0F38B1_W_0
,
1066 PREFIX_VEX_0F38D2_W_0
,
1067 PREFIX_VEX_0F38D3_W_0
,
1071 PREFIX_VEX_0F38DA_W_0
,
1072 PREFIX_VEX_0F38F5_L_0
,
1073 PREFIX_VEX_0F38F6_L_0
,
1074 PREFIX_VEX_0F38F7_L_0
,
1075 PREFIX_VEX_0F3AF0_L_0
,
1133 PREFIX_EVEX_MAP5_10
,
1134 PREFIX_EVEX_MAP5_11
,
1135 PREFIX_EVEX_MAP5_1D
,
1136 PREFIX_EVEX_MAP5_2A
,
1137 PREFIX_EVEX_MAP5_2C
,
1138 PREFIX_EVEX_MAP5_2D
,
1139 PREFIX_EVEX_MAP5_2E
,
1140 PREFIX_EVEX_MAP5_2F
,
1141 PREFIX_EVEX_MAP5_51
,
1142 PREFIX_EVEX_MAP5_58
,
1143 PREFIX_EVEX_MAP5_59
,
1144 PREFIX_EVEX_MAP5_5A
,
1145 PREFIX_EVEX_MAP5_5B
,
1146 PREFIX_EVEX_MAP5_5C
,
1147 PREFIX_EVEX_MAP5_5D
,
1148 PREFIX_EVEX_MAP5_5E
,
1149 PREFIX_EVEX_MAP5_5F
,
1150 PREFIX_EVEX_MAP5_78
,
1151 PREFIX_EVEX_MAP5_79
,
1152 PREFIX_EVEX_MAP5_7A
,
1153 PREFIX_EVEX_MAP5_7B
,
1154 PREFIX_EVEX_MAP5_7C
,
1155 PREFIX_EVEX_MAP5_7D
,
1157 PREFIX_EVEX_MAP6_13
,
1158 PREFIX_EVEX_MAP6_56
,
1159 PREFIX_EVEX_MAP6_57
,
1160 PREFIX_EVEX_MAP6_D6
,
1161 PREFIX_EVEX_MAP6_D7
,
1197 X86_64_0F01_REG_0_MOD_3_RM_6_P_1
,
1198 X86_64_0F01_REG_0_MOD_3_RM_6_P_3
,
1199 X86_64_0F01_REG_0_MOD_3_RM_7_P_0
,
1201 X86_64_0F01_REG_1_RM_2_PREFIX_1
,
1202 X86_64_0F01_REG_1_RM_2_PREFIX_3
,
1203 X86_64_0F01_REG_1_RM_5_PREFIX_2
,
1204 X86_64_0F01_REG_1_RM_6_PREFIX_2
,
1205 X86_64_0F01_REG_1_RM_7_PREFIX_2
,
1208 X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
,
1209 X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
,
1210 X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
,
1211 X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
,
1212 X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
,
1213 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
,
1214 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
,
1215 X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
,
1216 X86_64_0F18_REG_6_MOD_0
,
1217 X86_64_0F18_REG_7_MOD_0
,
1220 X86_64_0FC7_REG_6_MOD_3_PREFIX_1
,
1247 THREE_BYTE_0F38
= 0,
1276 VEX_LEN_0F12_P_0
= 0,
1309 VEX_LEN_0F3849_X86_64
,
1310 VEX_LEN_0F384B_X86_64
,
1312 VEX_LEN_0F385C_X86_64
,
1313 VEX_LEN_0F385E_X86_64
,
1314 VEX_LEN_0F386C_X86_64
,
1315 VEX_LEN_0F38CB_P_3_W_0
,
1316 VEX_LEN_0F38CC_P_3_W_0
,
1317 VEX_LEN_0F38CD_P_3_W_0
,
1318 VEX_LEN_0F38DA_W_0_P_0
,
1319 VEX_LEN_0F38DA_W_0_P_2
,
1381 VEX_LEN_XOP_09_82_W_0
,
1382 VEX_LEN_XOP_09_83_W_0
,
1415 EVEX_LEN_0F3816
= 0,
1469 VEX_W_0F3849_X86_64_L_0
,
1470 VEX_W_0F384B_X86_64_L_0
,
1478 VEX_W_0F385C_X86_64_L_0
,
1479 VEX_W_0F385E_X86_64_L_0
,
1480 VEX_W_0F386C_X86_64_L_0
,
1514 VEX_W_XOP_08_85_L_0
,
1515 VEX_W_XOP_08_86_L_0
,
1516 VEX_W_XOP_08_87_L_0
,
1517 VEX_W_XOP_08_8E_L_0
,
1518 VEX_W_XOP_08_8F_L_0
,
1519 VEX_W_XOP_08_95_L_0
,
1520 VEX_W_XOP_08_96_L_0
,
1521 VEX_W_XOP_08_97_L_0
,
1522 VEX_W_XOP_08_9E_L_0
,
1523 VEX_W_XOP_08_9F_L_0
,
1524 VEX_W_XOP_08_A6_L_0
,
1525 VEX_W_XOP_08_B6_L_0
,
1526 VEX_W_XOP_08_C0_L_0
,
1527 VEX_W_XOP_08_C1_L_0
,
1528 VEX_W_XOP_08_C2_L_0
,
1529 VEX_W_XOP_08_C3_L_0
,
1530 VEX_W_XOP_08_CC_L_0
,
1531 VEX_W_XOP_08_CD_L_0
,
1532 VEX_W_XOP_08_CE_L_0
,
1533 VEX_W_XOP_08_CF_L_0
,
1534 VEX_W_XOP_08_EC_L_0
,
1535 VEX_W_XOP_08_ED_L_0
,
1536 VEX_W_XOP_08_EE_L_0
,
1537 VEX_W_XOP_08_EF_L_0
,
1543 VEX_W_XOP_09_C1_L_0
,
1544 VEX_W_XOP_09_C2_L_0
,
1545 VEX_W_XOP_09_C3_L_0
,
1546 VEX_W_XOP_09_C6_L_0
,
1547 VEX_W_XOP_09_C7_L_0
,
1548 VEX_W_XOP_09_CB_L_0
,
1549 VEX_W_XOP_09_D1_L_0
,
1550 VEX_W_XOP_09_D2_L_0
,
1551 VEX_W_XOP_09_D3_L_0
,
1552 VEX_W_XOP_09_D6_L_0
,
1553 VEX_W_XOP_09_D7_L_0
,
1554 VEX_W_XOP_09_DB_L_0
,
1555 VEX_W_XOP_09_E1_L_0
,
1556 VEX_W_XOP_09_E2_L_0
,
1557 VEX_W_XOP_09_E3_L_0
,
1663 typedef bool (*op_rtn
) (instr_info
*ins
, int bytemode
, int sizeflag
);
1672 unsigned int prefix_requirement
;
1675 /* Upper case letters in the instruction names here are macros.
1676 'A' => print 'b' if no register operands or suffix_always is true
1677 'B' => print 'b' if suffix_always is true
1678 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
1680 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
1681 suffix_always is true
1682 'E' => print 'e' if 32-bit form of jcxz
1683 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
1684 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
1685 'H' => print ",pt" or ",pn" branch hint
1688 'K' => print 'd' or 'q' if rex prefix is present.
1690 'M' => print 'r' if intel_mnemonic is false.
1691 'N' => print 'n' if instruction has no wait "prefix"
1692 'O' => print 'd' or 'o' (or 'q' in Intel mode)
1693 'P' => behave as 'T' except with register operand outside of suffix_always
1695 'Q' => print 'w', 'l' or 'q' for memory operand or suffix_always
1697 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
1698 'S' => print 'w', 'l' or 'q' if suffix_always is true
1699 'T' => print 'w', 'l'/'d', or 'q' if instruction has an operand size
1700 prefix or if suffix_always is true.
1702 'V' => print 'v' for VEX/EVEX and nothing for legacy encodings.
1703 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
1704 'X' => print 's', 'd' depending on data16 prefix (for XMM)
1705 'Y' => no output, mark EVEX.aaa != 0 as bad.
1706 'Z' => print 'q' in 64bit mode and 'l' otherwise, if suffix_always is true.
1707 '!' => change condition from true to false or from false to true.
1708 '%' => add 1 upper case letter to the macro.
1709 '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
1710 prefix or suffix_always is true (lcall/ljmp).
1711 '@' => in 64bit mode for Intel64 ISA or if instruction
1712 has no operand sizing prefix, print 'q' if suffix_always is true or
1713 nothing otherwise; behave as 'P' in all other cases
1715 2 upper case letter macros:
1716 "XY" => print 'x' or 'y' if suffix_always is true or no register
1717 operands and no broadcast.
1718 "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
1719 register operands and no broadcast.
1720 "XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
1721 "XD" => print 'd' if !EVEX or EVEX.W=1, EVEX.W=0 is not a valid encoding
1722 "XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
1723 "XS" => print 's' if !EVEX or EVEX.W=0, EVEX.W=1 is not a valid encoding
1724 "XV" => print "{vex} " pseudo prefix
1725 "XE" => print "{evex} " pseudo prefix if no EVEX-specific functionality is
1726 is used by an EVEX-encoded (AVX512VL) instruction.
1727 "YK" keep unused, to avoid ambiguity with the combined use of Y and K.
1728 "YX" keep unused, to avoid ambiguity with the combined use of Y and X.
1729 "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
1730 being false, or no operand at all in 64bit mode, or if suffix_always
1732 "LB" => print "abs" in 64bit mode and behave as 'B' otherwise
1733 "LS" => print "abs" in 64bit mode and behave as 'S' otherwise
1734 "LV" => print "abs" for 64bit operand and behave as 'S' otherwise
1735 "DQ" => print 'd' or 'q' depending on the VEX.W bit
1736 "BW" => print 'b' or 'w' depending on the VEX.W bit
1737 "LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has
1738 an operand size prefix, or suffix_always is true. print
1739 'q' if rex prefix is present.
1741 Many of the above letters print nothing in Intel mode. See "putop"
1744 Braces '{' and '}', and vertical bars '|', indicate alternative
1745 mnemonic strings for AT&T and Intel. */
1747 static const struct dis386 dis386
[] = {
1749 { "addB", { Ebh1
, Gb
}, 0 },
1750 { "addS", { Evh1
, Gv
}, 0 },
1751 { "addB", { Gb
, EbS
}, 0 },
1752 { "addS", { Gv
, EvS
}, 0 },
1753 { "addB", { AL
, Ib
}, 0 },
1754 { "addS", { eAX
, Iv
}, 0 },
1755 { X86_64_TABLE (X86_64_06
) },
1756 { X86_64_TABLE (X86_64_07
) },
1758 { "orB", { Ebh1
, Gb
}, 0 },
1759 { "orS", { Evh1
, Gv
}, 0 },
1760 { "orB", { Gb
, EbS
}, 0 },
1761 { "orS", { Gv
, EvS
}, 0 },
1762 { "orB", { AL
, Ib
}, 0 },
1763 { "orS", { eAX
, Iv
}, 0 },
1764 { X86_64_TABLE (X86_64_0E
) },
1765 { Bad_Opcode
}, /* 0x0f extended opcode escape */
1767 { "adcB", { Ebh1
, Gb
}, 0 },
1768 { "adcS", { Evh1
, Gv
}, 0 },
1769 { "adcB", { Gb
, EbS
}, 0 },
1770 { "adcS", { Gv
, EvS
}, 0 },
1771 { "adcB", { AL
, Ib
}, 0 },
1772 { "adcS", { eAX
, Iv
}, 0 },
1773 { X86_64_TABLE (X86_64_16
) },
1774 { X86_64_TABLE (X86_64_17
) },
1776 { "sbbB", { Ebh1
, Gb
}, 0 },
1777 { "sbbS", { Evh1
, Gv
}, 0 },
1778 { "sbbB", { Gb
, EbS
}, 0 },
1779 { "sbbS", { Gv
, EvS
}, 0 },
1780 { "sbbB", { AL
, Ib
}, 0 },
1781 { "sbbS", { eAX
, Iv
}, 0 },
1782 { X86_64_TABLE (X86_64_1E
) },
1783 { X86_64_TABLE (X86_64_1F
) },
1785 { "andB", { Ebh1
, Gb
}, 0 },
1786 { "andS", { Evh1
, Gv
}, 0 },
1787 { "andB", { Gb
, EbS
}, 0 },
1788 { "andS", { Gv
, EvS
}, 0 },
1789 { "andB", { AL
, Ib
}, 0 },
1790 { "andS", { eAX
, Iv
}, 0 },
1791 { Bad_Opcode
}, /* SEG ES prefix */
1792 { X86_64_TABLE (X86_64_27
) },
1794 { "subB", { Ebh1
, Gb
}, 0 },
1795 { "subS", { Evh1
, Gv
}, 0 },
1796 { "subB", { Gb
, EbS
}, 0 },
1797 { "subS", { Gv
, EvS
}, 0 },
1798 { "subB", { AL
, Ib
}, 0 },
1799 { "subS", { eAX
, Iv
}, 0 },
1800 { Bad_Opcode
}, /* SEG CS prefix */
1801 { X86_64_TABLE (X86_64_2F
) },
1803 { "xorB", { Ebh1
, Gb
}, 0 },
1804 { "xorS", { Evh1
, Gv
}, 0 },
1805 { "xorB", { Gb
, EbS
}, 0 },
1806 { "xorS", { Gv
, EvS
}, 0 },
1807 { "xorB", { AL
, Ib
}, 0 },
1808 { "xorS", { eAX
, Iv
}, 0 },
1809 { Bad_Opcode
}, /* SEG SS prefix */
1810 { X86_64_TABLE (X86_64_37
) },
1812 { "cmpB", { Eb
, Gb
}, 0 },
1813 { "cmpS", { Ev
, Gv
}, 0 },
1814 { "cmpB", { Gb
, EbS
}, 0 },
1815 { "cmpS", { Gv
, EvS
}, 0 },
1816 { "cmpB", { AL
, Ib
}, 0 },
1817 { "cmpS", { eAX
, Iv
}, 0 },
1818 { Bad_Opcode
}, /* SEG DS prefix */
1819 { X86_64_TABLE (X86_64_3F
) },
1821 { "inc{S|}", { RMeAX
}, 0 },
1822 { "inc{S|}", { RMeCX
}, 0 },
1823 { "inc{S|}", { RMeDX
}, 0 },
1824 { "inc{S|}", { RMeBX
}, 0 },
1825 { "inc{S|}", { RMeSP
}, 0 },
1826 { "inc{S|}", { RMeBP
}, 0 },
1827 { "inc{S|}", { RMeSI
}, 0 },
1828 { "inc{S|}", { RMeDI
}, 0 },
1830 { "dec{S|}", { RMeAX
}, 0 },
1831 { "dec{S|}", { RMeCX
}, 0 },
1832 { "dec{S|}", { RMeDX
}, 0 },
1833 { "dec{S|}", { RMeBX
}, 0 },
1834 { "dec{S|}", { RMeSP
}, 0 },
1835 { "dec{S|}", { RMeBP
}, 0 },
1836 { "dec{S|}", { RMeSI
}, 0 },
1837 { "dec{S|}", { RMeDI
}, 0 },
1839 { "push{!P|}", { RMrAX
}, 0 },
1840 { "push{!P|}", { RMrCX
}, 0 },
1841 { "push{!P|}", { RMrDX
}, 0 },
1842 { "push{!P|}", { RMrBX
}, 0 },
1843 { "push{!P|}", { RMrSP
}, 0 },
1844 { "push{!P|}", { RMrBP
}, 0 },
1845 { "push{!P|}", { RMrSI
}, 0 },
1846 { "push{!P|}", { RMrDI
}, 0 },
1848 { "pop{!P|}", { RMrAX
}, 0 },
1849 { "pop{!P|}", { RMrCX
}, 0 },
1850 { "pop{!P|}", { RMrDX
}, 0 },
1851 { "pop{!P|}", { RMrBX
}, 0 },
1852 { "pop{!P|}", { RMrSP
}, 0 },
1853 { "pop{!P|}", { RMrBP
}, 0 },
1854 { "pop{!P|}", { RMrSI
}, 0 },
1855 { "pop{!P|}", { RMrDI
}, 0 },
1857 { X86_64_TABLE (X86_64_60
) },
1858 { X86_64_TABLE (X86_64_61
) },
1859 { X86_64_TABLE (X86_64_62
) },
1860 { X86_64_TABLE (X86_64_63
) },
1861 { Bad_Opcode
}, /* seg fs */
1862 { Bad_Opcode
}, /* seg gs */
1863 { Bad_Opcode
}, /* op size prefix */
1864 { Bad_Opcode
}, /* adr size prefix */
1866 { "pushP", { sIv
}, 0 },
1867 { "imulS", { Gv
, Ev
, Iv
}, 0 },
1868 { "pushP", { sIbT
}, 0 },
1869 { "imulS", { Gv
, Ev
, sIb
}, 0 },
1870 { "ins{b|}", { Ybr
, indirDX
}, 0 },
1871 { X86_64_TABLE (X86_64_6D
) },
1872 { "outs{b|}", { indirDXr
, Xb
}, 0 },
1873 { X86_64_TABLE (X86_64_6F
) },
1875 { "joH", { Jb
, BND
, cond_jump_flag
}, 0 },
1876 { "jnoH", { Jb
, BND
, cond_jump_flag
}, 0 },
1877 { "jbH", { Jb
, BND
, cond_jump_flag
}, 0 },
1878 { "jaeH", { Jb
, BND
, cond_jump_flag
}, 0 },
1879 { "jeH", { Jb
, BND
, cond_jump_flag
}, 0 },
1880 { "jneH", { Jb
, BND
, cond_jump_flag
}, 0 },
1881 { "jbeH", { Jb
, BND
, cond_jump_flag
}, 0 },
1882 { "jaH", { Jb
, BND
, cond_jump_flag
}, 0 },
1884 { "jsH", { Jb
, BND
, cond_jump_flag
}, 0 },
1885 { "jnsH", { Jb
, BND
, cond_jump_flag
}, 0 },
1886 { "jpH", { Jb
, BND
, cond_jump_flag
}, 0 },
1887 { "jnpH", { Jb
, BND
, cond_jump_flag
}, 0 },
1888 { "jlH", { Jb
, BND
, cond_jump_flag
}, 0 },
1889 { "jgeH", { Jb
, BND
, cond_jump_flag
}, 0 },
1890 { "jleH", { Jb
, BND
, cond_jump_flag
}, 0 },
1891 { "jgH", { Jb
, BND
, cond_jump_flag
}, 0 },
1893 { REG_TABLE (REG_80
) },
1894 { REG_TABLE (REG_81
) },
1895 { X86_64_TABLE (X86_64_82
) },
1896 { REG_TABLE (REG_83
) },
1897 { "testB", { Eb
, Gb
}, 0 },
1898 { "testS", { Ev
, Gv
}, 0 },
1899 { "xchgB", { Ebh2
, Gb
}, 0 },
1900 { "xchgS", { Evh2
, Gv
}, 0 },
1902 { "movB", { Ebh3
, Gb
}, 0 },
1903 { "movS", { Evh3
, Gv
}, 0 },
1904 { "movB", { Gb
, EbS
}, 0 },
1905 { "movS", { Gv
, EvS
}, 0 },
1906 { "movD", { Sv
, Sw
}, 0 },
1907 { "leaS", { Gv
, M
}, 0 },
1908 { "movD", { Sw
, Sv
}, 0 },
1909 { REG_TABLE (REG_8F
) },
1911 { PREFIX_TABLE (PREFIX_90
) },
1912 { "xchgS", { RMeCX
, eAX
}, 0 },
1913 { "xchgS", { RMeDX
, eAX
}, 0 },
1914 { "xchgS", { RMeBX
, eAX
}, 0 },
1915 { "xchgS", { RMeSP
, eAX
}, 0 },
1916 { "xchgS", { RMeBP
, eAX
}, 0 },
1917 { "xchgS", { RMeSI
, eAX
}, 0 },
1918 { "xchgS", { RMeDI
, eAX
}, 0 },
1920 { "cW{t|}R", { XX
}, 0 },
1921 { "cR{t|}O", { XX
}, 0 },
1922 { X86_64_TABLE (X86_64_9A
) },
1923 { Bad_Opcode
}, /* fwait */
1924 { "pushfP", { XX
}, 0 },
1925 { "popfP", { XX
}, 0 },
1926 { "sahf", { XX
}, 0 },
1927 { "lahf", { XX
}, 0 },
1929 { "mov%LB", { AL
, Ob
}, 0 },
1930 { "mov%LS", { eAX
, Ov
}, 0 },
1931 { "mov%LB", { Ob
, AL
}, 0 },
1932 { "mov%LS", { Ov
, eAX
}, 0 },
1933 { "movs{b|}", { Ybr
, Xb
}, 0 },
1934 { "movs{R|}", { Yvr
, Xv
}, 0 },
1935 { "cmps{b|}", { Xb
, Yb
}, 0 },
1936 { "cmps{R|}", { Xv
, Yv
}, 0 },
1938 { "testB", { AL
, Ib
}, 0 },
1939 { "testS", { eAX
, Iv
}, 0 },
1940 { "stosB", { Ybr
, AL
}, 0 },
1941 { "stosS", { Yvr
, eAX
}, 0 },
1942 { "lodsB", { ALr
, Xb
}, 0 },
1943 { "lodsS", { eAXr
, Xv
}, 0 },
1944 { "scasB", { AL
, Yb
}, 0 },
1945 { "scasS", { eAX
, Yv
}, 0 },
1947 { "movB", { RMAL
, Ib
}, 0 },
1948 { "movB", { RMCL
, Ib
}, 0 },
1949 { "movB", { RMDL
, Ib
}, 0 },
1950 { "movB", { RMBL
, Ib
}, 0 },
1951 { "movB", { RMAH
, Ib
}, 0 },
1952 { "movB", { RMCH
, Ib
}, 0 },
1953 { "movB", { RMDH
, Ib
}, 0 },
1954 { "movB", { RMBH
, Ib
}, 0 },
1956 { "mov%LV", { RMeAX
, Iv64
}, 0 },
1957 { "mov%LV", { RMeCX
, Iv64
}, 0 },
1958 { "mov%LV", { RMeDX
, Iv64
}, 0 },
1959 { "mov%LV", { RMeBX
, Iv64
}, 0 },
1960 { "mov%LV", { RMeSP
, Iv64
}, 0 },
1961 { "mov%LV", { RMeBP
, Iv64
}, 0 },
1962 { "mov%LV", { RMeSI
, Iv64
}, 0 },
1963 { "mov%LV", { RMeDI
, Iv64
}, 0 },
1965 { REG_TABLE (REG_C0
) },
1966 { REG_TABLE (REG_C1
) },
1967 { X86_64_TABLE (X86_64_C2
) },
1968 { X86_64_TABLE (X86_64_C3
) },
1969 { X86_64_TABLE (X86_64_C4
) },
1970 { X86_64_TABLE (X86_64_C5
) },
1971 { REG_TABLE (REG_C6
) },
1972 { REG_TABLE (REG_C7
) },
1974 { "enterP", { Iw
, Ib
}, 0 },
1975 { "leaveP", { XX
}, 0 },
1976 { "{l|}ret{|f}%LP", { Iw
}, 0 },
1977 { "{l|}ret{|f}%LP", { XX
}, 0 },
1978 { "int3", { XX
}, 0 },
1979 { "int", { Ib
}, 0 },
1980 { X86_64_TABLE (X86_64_CE
) },
1981 { "iret%LP", { XX
}, 0 },
1983 { REG_TABLE (REG_D0
) },
1984 { REG_TABLE (REG_D1
) },
1985 { REG_TABLE (REG_D2
) },
1986 { REG_TABLE (REG_D3
) },
1987 { X86_64_TABLE (X86_64_D4
) },
1988 { X86_64_TABLE (X86_64_D5
) },
1990 { "xlat", { DSBX
}, 0 },
2001 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
}, 0 },
2002 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
}, 0 },
2003 { "loopFH", { Jb
, XX
, loop_jcxz_flag
}, 0 },
2004 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
}, 0 },
2005 { "inB", { AL
, Ib
}, 0 },
2006 { "inG", { zAX
, Ib
}, 0 },
2007 { "outB", { Ib
, AL
}, 0 },
2008 { "outG", { Ib
, zAX
}, 0 },
2010 { X86_64_TABLE (X86_64_E8
) },
2011 { X86_64_TABLE (X86_64_E9
) },
2012 { X86_64_TABLE (X86_64_EA
) },
2013 { "jmp", { Jb
, BND
}, 0 },
2014 { "inB", { AL
, indirDX
}, 0 },
2015 { "inG", { zAX
, indirDX
}, 0 },
2016 { "outB", { indirDX
, AL
}, 0 },
2017 { "outG", { indirDX
, zAX
}, 0 },
2019 { Bad_Opcode
}, /* lock prefix */
2020 { "int1", { XX
}, 0 },
2021 { Bad_Opcode
}, /* repne */
2022 { Bad_Opcode
}, /* repz */
2023 { "hlt", { XX
}, 0 },
2024 { "cmc", { XX
}, 0 },
2025 { REG_TABLE (REG_F6
) },
2026 { REG_TABLE (REG_F7
) },
2028 { "clc", { XX
}, 0 },
2029 { "stc", { XX
}, 0 },
2030 { "cli", { XX
}, 0 },
2031 { "sti", { XX
}, 0 },
2032 { "cld", { XX
}, 0 },
2033 { "std", { XX
}, 0 },
2034 { REG_TABLE (REG_FE
) },
2035 { REG_TABLE (REG_FF
) },
2038 static const struct dis386 dis386_twobyte
[] = {
2040 { REG_TABLE (REG_0F00
) },
2041 { REG_TABLE (REG_0F01
) },
2042 { "larS", { Gv
, Sv
}, 0 },
2043 { "lslS", { Gv
, Sv
}, 0 },
2045 { "syscall", { XX
}, 0 },
2046 { "clts", { XX
}, 0 },
2047 { "sysret%LQ", { XX
}, 0 },
2049 { "invd", { XX
}, 0 },
2050 { PREFIX_TABLE (PREFIX_0F09
) },
2052 { "ud2", { XX
}, 0 },
2054 { REG_TABLE (REG_0F0D
) },
2055 { "femms", { XX
}, 0 },
2056 { "", { MX
, EM
, OPSUF
}, 0 }, /* See OP_3DNowSuffix. */
2058 { PREFIX_TABLE (PREFIX_0F10
) },
2059 { PREFIX_TABLE (PREFIX_0F11
) },
2060 { PREFIX_TABLE (PREFIX_0F12
) },
2061 { "movlpX", { Mq
, XM
}, PREFIX_OPCODE
},
2062 { "unpcklpX", { XM
, EXx
}, PREFIX_OPCODE
},
2063 { "unpckhpX", { XM
, EXx
}, PREFIX_OPCODE
},
2064 { PREFIX_TABLE (PREFIX_0F16
) },
2065 { "movhpX", { Mq
, XM
}, PREFIX_OPCODE
},
2067 { REG_TABLE (REG_0F18
) },
2068 { "nopQ", { Ev
}, 0 },
2069 { PREFIX_TABLE (PREFIX_0F1A
) },
2070 { PREFIX_TABLE (PREFIX_0F1B
) },
2071 { PREFIX_TABLE (PREFIX_0F1C
) },
2072 { "nopQ", { Ev
}, 0 },
2073 { PREFIX_TABLE (PREFIX_0F1E
) },
2074 { "nopQ", { Ev
}, 0 },
2076 { "movZ", { Em
, Cm
}, 0 },
2077 { "movZ", { Em
, Dm
}, 0 },
2078 { "movZ", { Cm
, Em
}, 0 },
2079 { "movZ", { Dm
, Em
}, 0 },
2080 { X86_64_TABLE (X86_64_0F24
) },
2082 { X86_64_TABLE (X86_64_0F26
) },
2085 { "movapX", { XM
, EXx
}, PREFIX_OPCODE
},
2086 { "movapX", { EXxS
, XM
}, PREFIX_OPCODE
},
2087 { PREFIX_TABLE (PREFIX_0F2A
) },
2088 { PREFIX_TABLE (PREFIX_0F2B
) },
2089 { PREFIX_TABLE (PREFIX_0F2C
) },
2090 { PREFIX_TABLE (PREFIX_0F2D
) },
2091 { PREFIX_TABLE (PREFIX_0F2E
) },
2092 { PREFIX_TABLE (PREFIX_0F2F
) },
2094 { "wrmsr", { XX
}, 0 },
2095 { "rdtsc", { XX
}, 0 },
2096 { "rdmsr", { XX
}, 0 },
2097 { "rdpmc", { XX
}, 0 },
2098 { "sysenter", { SEP
}, 0 },
2099 { "sysexit%LQ", { SEP
}, 0 },
2101 { "getsec", { XX
}, 0 },
2103 { THREE_BYTE_TABLE (THREE_BYTE_0F38
) },
2105 { THREE_BYTE_TABLE (THREE_BYTE_0F3A
) },
2112 { "cmovoS", { Gv
, Ev
}, 0 },
2113 { "cmovnoS", { Gv
, Ev
}, 0 },
2114 { "cmovbS", { Gv
, Ev
}, 0 },
2115 { "cmovaeS", { Gv
, Ev
}, 0 },
2116 { "cmoveS", { Gv
, Ev
}, 0 },
2117 { "cmovneS", { Gv
, Ev
}, 0 },
2118 { "cmovbeS", { Gv
, Ev
}, 0 },
2119 { "cmovaS", { Gv
, Ev
}, 0 },
2121 { "cmovsS", { Gv
, Ev
}, 0 },
2122 { "cmovnsS", { Gv
, Ev
}, 0 },
2123 { "cmovpS", { Gv
, Ev
}, 0 },
2124 { "cmovnpS", { Gv
, Ev
}, 0 },
2125 { "cmovlS", { Gv
, Ev
}, 0 },
2126 { "cmovgeS", { Gv
, Ev
}, 0 },
2127 { "cmovleS", { Gv
, Ev
}, 0 },
2128 { "cmovgS", { Gv
, Ev
}, 0 },
2130 { "movmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
2131 { PREFIX_TABLE (PREFIX_0F51
) },
2132 { PREFIX_TABLE (PREFIX_0F52
) },
2133 { PREFIX_TABLE (PREFIX_0F53
) },
2134 { "andpX", { XM
, EXx
}, PREFIX_OPCODE
},
2135 { "andnpX", { XM
, EXx
}, PREFIX_OPCODE
},
2136 { "orpX", { XM
, EXx
}, PREFIX_OPCODE
},
2137 { "xorpX", { XM
, EXx
}, PREFIX_OPCODE
},
2139 { PREFIX_TABLE (PREFIX_0F58
) },
2140 { PREFIX_TABLE (PREFIX_0F59
) },
2141 { PREFIX_TABLE (PREFIX_0F5A
) },
2142 { PREFIX_TABLE (PREFIX_0F5B
) },
2143 { PREFIX_TABLE (PREFIX_0F5C
) },
2144 { PREFIX_TABLE (PREFIX_0F5D
) },
2145 { PREFIX_TABLE (PREFIX_0F5E
) },
2146 { PREFIX_TABLE (PREFIX_0F5F
) },
2148 { PREFIX_TABLE (PREFIX_0F60
) },
2149 { PREFIX_TABLE (PREFIX_0F61
) },
2150 { PREFIX_TABLE (PREFIX_0F62
) },
2151 { "packsswb", { MX
, EM
}, PREFIX_OPCODE
},
2152 { "pcmpgtb", { MX
, EM
}, PREFIX_OPCODE
},
2153 { "pcmpgtw", { MX
, EM
}, PREFIX_OPCODE
},
2154 { "pcmpgtd", { MX
, EM
}, PREFIX_OPCODE
},
2155 { "packuswb", { MX
, EM
}, PREFIX_OPCODE
},
2157 { "punpckhbw", { MX
, EM
}, PREFIX_OPCODE
},
2158 { "punpckhwd", { MX
, EM
}, PREFIX_OPCODE
},
2159 { "punpckhdq", { MX
, EM
}, PREFIX_OPCODE
},
2160 { "packssdw", { MX
, EM
}, PREFIX_OPCODE
},
2161 { "punpcklqdq", { XM
, EXx
}, PREFIX_DATA
},
2162 { "punpckhqdq", { XM
, EXx
}, PREFIX_DATA
},
2163 { "movK", { MX
, Edq
}, PREFIX_OPCODE
},
2164 { PREFIX_TABLE (PREFIX_0F6F
) },
2166 { PREFIX_TABLE (PREFIX_0F70
) },
2167 { REG_TABLE (REG_0F71
) },
2168 { REG_TABLE (REG_0F72
) },
2169 { REG_TABLE (REG_0F73
) },
2170 { "pcmpeqb", { MX
, EM
}, PREFIX_OPCODE
},
2171 { "pcmpeqw", { MX
, EM
}, PREFIX_OPCODE
},
2172 { "pcmpeqd", { MX
, EM
}, PREFIX_OPCODE
},
2173 { "emms", { XX
}, PREFIX_OPCODE
},
2175 { PREFIX_TABLE (PREFIX_0F78
) },
2176 { PREFIX_TABLE (PREFIX_0F79
) },
2179 { PREFIX_TABLE (PREFIX_0F7C
) },
2180 { PREFIX_TABLE (PREFIX_0F7D
) },
2181 { PREFIX_TABLE (PREFIX_0F7E
) },
2182 { PREFIX_TABLE (PREFIX_0F7F
) },
2184 { "joH", { Jv
, BND
, cond_jump_flag
}, 0 },
2185 { "jnoH", { Jv
, BND
, cond_jump_flag
}, 0 },
2186 { "jbH", { Jv
, BND
, cond_jump_flag
}, 0 },
2187 { "jaeH", { Jv
, BND
, cond_jump_flag
}, 0 },
2188 { "jeH", { Jv
, BND
, cond_jump_flag
}, 0 },
2189 { "jneH", { Jv
, BND
, cond_jump_flag
}, 0 },
2190 { "jbeH", { Jv
, BND
, cond_jump_flag
}, 0 },
2191 { "jaH", { Jv
, BND
, cond_jump_flag
}, 0 },
2193 { "jsH", { Jv
, BND
, cond_jump_flag
}, 0 },
2194 { "jnsH", { Jv
, BND
, cond_jump_flag
}, 0 },
2195 { "jpH", { Jv
, BND
, cond_jump_flag
}, 0 },
2196 { "jnpH", { Jv
, BND
, cond_jump_flag
}, 0 },
2197 { "jlH", { Jv
, BND
, cond_jump_flag
}, 0 },
2198 { "jgeH", { Jv
, BND
, cond_jump_flag
}, 0 },
2199 { "jleH", { Jv
, BND
, cond_jump_flag
}, 0 },
2200 { "jgH", { Jv
, BND
, cond_jump_flag
}, 0 },
2202 { "seto", { Eb
}, 0 },
2203 { "setno", { Eb
}, 0 },
2204 { "setb", { Eb
}, 0 },
2205 { "setae", { Eb
}, 0 },
2206 { "sete", { Eb
}, 0 },
2207 { "setne", { Eb
}, 0 },
2208 { "setbe", { Eb
}, 0 },
2209 { "seta", { Eb
}, 0 },
2211 { "sets", { Eb
}, 0 },
2212 { "setns", { Eb
}, 0 },
2213 { "setp", { Eb
}, 0 },
2214 { "setnp", { Eb
}, 0 },
2215 { "setl", { Eb
}, 0 },
2216 { "setge", { Eb
}, 0 },
2217 { "setle", { Eb
}, 0 },
2218 { "setg", { Eb
}, 0 },
2220 { "pushP", { fs
}, 0 },
2221 { "popP", { fs
}, 0 },
2222 { "cpuid", { XX
}, 0 },
2223 { "btS", { Ev
, Gv
}, 0 },
2224 { "shldS", { Ev
, Gv
, Ib
}, 0 },
2225 { "shldS", { Ev
, Gv
, CL
}, 0 },
2226 { REG_TABLE (REG_0FA6
) },
2227 { REG_TABLE (REG_0FA7
) },
2229 { "pushP", { gs
}, 0 },
2230 { "popP", { gs
}, 0 },
2231 { "rsm", { XX
}, 0 },
2232 { "btsS", { Evh1
, Gv
}, 0 },
2233 { "shrdS", { Ev
, Gv
, Ib
}, 0 },
2234 { "shrdS", { Ev
, Gv
, CL
}, 0 },
2235 { REG_TABLE (REG_0FAE
) },
2236 { "imulS", { Gv
, Ev
}, 0 },
2238 { "cmpxchgB", { Ebh1
, Gb
}, 0 },
2239 { "cmpxchgS", { Evh1
, Gv
}, 0 },
2240 { "lssS", { Gv
, Mp
}, 0 },
2241 { "btrS", { Evh1
, Gv
}, 0 },
2242 { "lfsS", { Gv
, Mp
}, 0 },
2243 { "lgsS", { Gv
, Mp
}, 0 },
2244 { "movz{bR|x}", { Gv
, Eb
}, 0 },
2245 { "movz{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movzww ! */
2247 { PREFIX_TABLE (PREFIX_0FB8
) },
2248 { "ud1S", { Gv
, Ev
}, 0 },
2249 { REG_TABLE (REG_0FBA
) },
2250 { "btcS", { Evh1
, Gv
}, 0 },
2251 { PREFIX_TABLE (PREFIX_0FBC
) },
2252 { PREFIX_TABLE (PREFIX_0FBD
) },
2253 { "movs{bR|x}", { Gv
, Eb
}, 0 },
2254 { "movs{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movsww ! */
2256 { "xaddB", { Ebh1
, Gb
}, 0 },
2257 { "xaddS", { Evh1
, Gv
}, 0 },
2258 { PREFIX_TABLE (PREFIX_0FC2
) },
2259 { "movntiS", { Mdq
, Gdq
}, PREFIX_OPCODE
},
2260 { "pinsrw", { MX
, Edw
, Ib
}, PREFIX_OPCODE
},
2261 { "pextrw", { Gd
, Nq
, Ib
}, PREFIX_OPCODE
},
2262 { "shufpX", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
2263 { REG_TABLE (REG_0FC7
) },
2265 { "bswap", { RMeAX
}, 0 },
2266 { "bswap", { RMeCX
}, 0 },
2267 { "bswap", { RMeDX
}, 0 },
2268 { "bswap", { RMeBX
}, 0 },
2269 { "bswap", { RMeSP
}, 0 },
2270 { "bswap", { RMeBP
}, 0 },
2271 { "bswap", { RMeSI
}, 0 },
2272 { "bswap", { RMeDI
}, 0 },
2274 { PREFIX_TABLE (PREFIX_0FD0
) },
2275 { "psrlw", { MX
, EM
}, PREFIX_OPCODE
},
2276 { "psrld", { MX
, EM
}, PREFIX_OPCODE
},
2277 { "psrlq", { MX
, EM
}, PREFIX_OPCODE
},
2278 { "paddq", { MX
, EM
}, PREFIX_OPCODE
},
2279 { "pmullw", { MX
, EM
}, PREFIX_OPCODE
},
2280 { PREFIX_TABLE (PREFIX_0FD6
) },
2281 { "pmovmskb", { Gdq
, Nq
}, PREFIX_OPCODE
},
2283 { "psubusb", { MX
, EM
}, PREFIX_OPCODE
},
2284 { "psubusw", { MX
, EM
}, PREFIX_OPCODE
},
2285 { "pminub", { MX
, EM
}, PREFIX_OPCODE
},
2286 { "pand", { MX
, EM
}, PREFIX_OPCODE
},
2287 { "paddusb", { MX
, EM
}, PREFIX_OPCODE
},
2288 { "paddusw", { MX
, EM
}, PREFIX_OPCODE
},
2289 { "pmaxub", { MX
, EM
}, PREFIX_OPCODE
},
2290 { "pandn", { MX
, EM
}, PREFIX_OPCODE
},
2292 { "pavgb", { MX
, EM
}, PREFIX_OPCODE
},
2293 { "psraw", { MX
, EM
}, PREFIX_OPCODE
},
2294 { "psrad", { MX
, EM
}, PREFIX_OPCODE
},
2295 { "pavgw", { MX
, EM
}, PREFIX_OPCODE
},
2296 { "pmulhuw", { MX
, EM
}, PREFIX_OPCODE
},
2297 { "pmulhw", { MX
, EM
}, PREFIX_OPCODE
},
2298 { PREFIX_TABLE (PREFIX_0FE6
) },
2299 { PREFIX_TABLE (PREFIX_0FE7
) },
2301 { "psubsb", { MX
, EM
}, PREFIX_OPCODE
},
2302 { "psubsw", { MX
, EM
}, PREFIX_OPCODE
},
2303 { "pminsw", { MX
, EM
}, PREFIX_OPCODE
},
2304 { "por", { MX
, EM
}, PREFIX_OPCODE
},
2305 { "paddsb", { MX
, EM
}, PREFIX_OPCODE
},
2306 { "paddsw", { MX
, EM
}, PREFIX_OPCODE
},
2307 { "pmaxsw", { MX
, EM
}, PREFIX_OPCODE
},
2308 { "pxor", { MX
, EM
}, PREFIX_OPCODE
},
2310 { PREFIX_TABLE (PREFIX_0FF0
) },
2311 { "psllw", { MX
, EM
}, PREFIX_OPCODE
},
2312 { "pslld", { MX
, EM
}, PREFIX_OPCODE
},
2313 { "psllq", { MX
, EM
}, PREFIX_OPCODE
},
2314 { "pmuludq", { MX
, EM
}, PREFIX_OPCODE
},
2315 { "pmaddwd", { MX
, EM
}, PREFIX_OPCODE
},
2316 { "psadbw", { MX
, EM
}, PREFIX_OPCODE
},
2317 { PREFIX_TABLE (PREFIX_0FF7
) },
2319 { "psubb", { MX
, EM
}, PREFIX_OPCODE
},
2320 { "psubw", { MX
, EM
}, PREFIX_OPCODE
},
2321 { "psubd", { MX
, EM
}, PREFIX_OPCODE
},
2322 { "psubq", { MX
, EM
}, PREFIX_OPCODE
},
2323 { "paddb", { MX
, EM
}, PREFIX_OPCODE
},
2324 { "paddw", { MX
, EM
}, PREFIX_OPCODE
},
2325 { "paddd", { MX
, EM
}, PREFIX_OPCODE
},
2326 { "ud0S", { Gv
, Ev
}, 0 },
2329 static const bool onebyte_has_modrm
[256] = {
2330 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2331 /* ------------------------------- */
2332 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
2333 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
2334 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
2335 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
2336 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
2337 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
2338 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
2339 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
2340 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
2341 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
2342 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
2343 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
2344 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
2345 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
2346 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
2347 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
2348 /* ------------------------------- */
2349 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2352 static const bool twobyte_has_modrm
[256] = {
2353 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2354 /* ------------------------------- */
2355 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
2356 /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
2357 /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
2358 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
2359 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
2360 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
2361 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
2362 /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
2363 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2364 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
2365 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
2366 /* b0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bf */
2367 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
2368 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
2369 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
2370 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /* ff */
2371 /* ------------------------------- */
2372 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2382 /* If we are accessing mod/rm/reg without need_modrm set, then the
2383 values are stale. Hitting this abort likely indicates that you
2384 need to update onebyte_has_modrm or twobyte_has_modrm. */
2385 #define MODRM_CHECK if (!ins->need_modrm) abort ()
2387 static const char intel_index16
[][6] = {
2388 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
2391 static const char att_names64
[][8] = {
2392 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
2393 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
2395 static const char att_names32
[][8] = {
2396 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
2397 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
2399 static const char att_names16
[][8] = {
2400 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
2401 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
2403 static const char att_names8
[][8] = {
2404 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
2406 static const char att_names8rex
[][8] = {
2407 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
2408 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
2410 static const char att_names_seg
[][4] = {
2411 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
2413 static const char att_index64
[] = "%riz";
2414 static const char att_index32
[] = "%eiz";
2415 static const char att_index16
[][8] = {
2416 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
2419 static const char att_names_mm
[][8] = {
2420 "%mm0", "%mm1", "%mm2", "%mm3",
2421 "%mm4", "%mm5", "%mm6", "%mm7"
2424 static const char att_names_bnd
[][8] = {
2425 "%bnd0", "%bnd1", "%bnd2", "%bnd3"
2428 static const char att_names_xmm
[][8] = {
2429 "%xmm0", "%xmm1", "%xmm2", "%xmm3",
2430 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
2431 "%xmm8", "%xmm9", "%xmm10", "%xmm11",
2432 "%xmm12", "%xmm13", "%xmm14", "%xmm15",
2433 "%xmm16", "%xmm17", "%xmm18", "%xmm19",
2434 "%xmm20", "%xmm21", "%xmm22", "%xmm23",
2435 "%xmm24", "%xmm25", "%xmm26", "%xmm27",
2436 "%xmm28", "%xmm29", "%xmm30", "%xmm31"
2439 static const char att_names_ymm
[][8] = {
2440 "%ymm0", "%ymm1", "%ymm2", "%ymm3",
2441 "%ymm4", "%ymm5", "%ymm6", "%ymm7",
2442 "%ymm8", "%ymm9", "%ymm10", "%ymm11",
2443 "%ymm12", "%ymm13", "%ymm14", "%ymm15",
2444 "%ymm16", "%ymm17", "%ymm18", "%ymm19",
2445 "%ymm20", "%ymm21", "%ymm22", "%ymm23",
2446 "%ymm24", "%ymm25", "%ymm26", "%ymm27",
2447 "%ymm28", "%ymm29", "%ymm30", "%ymm31"
2450 static const char att_names_zmm
[][8] = {
2451 "%zmm0", "%zmm1", "%zmm2", "%zmm3",
2452 "%zmm4", "%zmm5", "%zmm6", "%zmm7",
2453 "%zmm8", "%zmm9", "%zmm10", "%zmm11",
2454 "%zmm12", "%zmm13", "%zmm14", "%zmm15",
2455 "%zmm16", "%zmm17", "%zmm18", "%zmm19",
2456 "%zmm20", "%zmm21", "%zmm22", "%zmm23",
2457 "%zmm24", "%zmm25", "%zmm26", "%zmm27",
2458 "%zmm28", "%zmm29", "%zmm30", "%zmm31"
2461 static const char att_names_tmm
[][8] = {
2462 "%tmm0", "%tmm1", "%tmm2", "%tmm3",
2463 "%tmm4", "%tmm5", "%tmm6", "%tmm7"
2466 static const char att_names_mask
[][8] = {
2467 "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
2470 static const char *const names_rounding
[] =
2478 static const struct dis386 reg_table
[][8] = {
2481 { "addA", { Ebh1
, Ib
}, 0 },
2482 { "orA", { Ebh1
, Ib
}, 0 },
2483 { "adcA", { Ebh1
, Ib
}, 0 },
2484 { "sbbA", { Ebh1
, Ib
}, 0 },
2485 { "andA", { Ebh1
, Ib
}, 0 },
2486 { "subA", { Ebh1
, Ib
}, 0 },
2487 { "xorA", { Ebh1
, Ib
}, 0 },
2488 { "cmpA", { Eb
, Ib
}, 0 },
2492 { "addQ", { Evh1
, Iv
}, 0 },
2493 { "orQ", { Evh1
, Iv
}, 0 },
2494 { "adcQ", { Evh1
, Iv
}, 0 },
2495 { "sbbQ", { Evh1
, Iv
}, 0 },
2496 { "andQ", { Evh1
, Iv
}, 0 },
2497 { "subQ", { Evh1
, Iv
}, 0 },
2498 { "xorQ", { Evh1
, Iv
}, 0 },
2499 { "cmpQ", { Ev
, Iv
}, 0 },
2503 { "addQ", { Evh1
, sIb
}, 0 },
2504 { "orQ", { Evh1
, sIb
}, 0 },
2505 { "adcQ", { Evh1
, sIb
}, 0 },
2506 { "sbbQ", { Evh1
, sIb
}, 0 },
2507 { "andQ", { Evh1
, sIb
}, 0 },
2508 { "subQ", { Evh1
, sIb
}, 0 },
2509 { "xorQ", { Evh1
, sIb
}, 0 },
2510 { "cmpQ", { Ev
, sIb
}, 0 },
2514 { "pop{P|}", { stackEv
}, 0 },
2515 { XOP_8F_TABLE () },
2519 { XOP_8F_TABLE () },
2523 { "rolA", { Eb
, Ib
}, 0 },
2524 { "rorA", { Eb
, Ib
}, 0 },
2525 { "rclA", { Eb
, Ib
}, 0 },
2526 { "rcrA", { Eb
, Ib
}, 0 },
2527 { "shlA", { Eb
, Ib
}, 0 },
2528 { "shrA", { Eb
, Ib
}, 0 },
2529 { "shlA", { Eb
, Ib
}, 0 },
2530 { "sarA", { Eb
, Ib
}, 0 },
2534 { "rolQ", { Ev
, Ib
}, 0 },
2535 { "rorQ", { Ev
, Ib
}, 0 },
2536 { "rclQ", { Ev
, Ib
}, 0 },
2537 { "rcrQ", { Ev
, Ib
}, 0 },
2538 { "shlQ", { Ev
, Ib
}, 0 },
2539 { "shrQ", { Ev
, Ib
}, 0 },
2540 { "shlQ", { Ev
, Ib
}, 0 },
2541 { "sarQ", { Ev
, Ib
}, 0 },
2545 { "movA", { Ebh3
, Ib
}, 0 },
2552 { RM_TABLE (RM_C6_REG_7
) },
2556 { "movQ", { Evh3
, Iv
}, 0 },
2563 { RM_TABLE (RM_C7_REG_7
) },
2567 { "rolA", { Eb
, I1
}, 0 },
2568 { "rorA", { Eb
, I1
}, 0 },
2569 { "rclA", { Eb
, I1
}, 0 },
2570 { "rcrA", { Eb
, I1
}, 0 },
2571 { "shlA", { Eb
, I1
}, 0 },
2572 { "shrA", { Eb
, I1
}, 0 },
2573 { "shlA", { Eb
, I1
}, 0 },
2574 { "sarA", { Eb
, I1
}, 0 },
2578 { "rolQ", { Ev
, I1
}, 0 },
2579 { "rorQ", { Ev
, I1
}, 0 },
2580 { "rclQ", { Ev
, I1
}, 0 },
2581 { "rcrQ", { Ev
, I1
}, 0 },
2582 { "shlQ", { Ev
, I1
}, 0 },
2583 { "shrQ", { Ev
, I1
}, 0 },
2584 { "shlQ", { Ev
, I1
}, 0 },
2585 { "sarQ", { Ev
, I1
}, 0 },
2589 { "rolA", { Eb
, CL
}, 0 },
2590 { "rorA", { Eb
, CL
}, 0 },
2591 { "rclA", { Eb
, CL
}, 0 },
2592 { "rcrA", { Eb
, CL
}, 0 },
2593 { "shlA", { Eb
, CL
}, 0 },
2594 { "shrA", { Eb
, CL
}, 0 },
2595 { "shlA", { Eb
, CL
}, 0 },
2596 { "sarA", { Eb
, CL
}, 0 },
2600 { "rolQ", { Ev
, CL
}, 0 },
2601 { "rorQ", { Ev
, CL
}, 0 },
2602 { "rclQ", { Ev
, CL
}, 0 },
2603 { "rcrQ", { Ev
, CL
}, 0 },
2604 { "shlQ", { Ev
, CL
}, 0 },
2605 { "shrQ", { Ev
, CL
}, 0 },
2606 { "shlQ", { Ev
, CL
}, 0 },
2607 { "sarQ", { Ev
, CL
}, 0 },
2611 { "testA", { Eb
, Ib
}, 0 },
2612 { "testA", { Eb
, Ib
}, 0 },
2613 { "notA", { Ebh1
}, 0 },
2614 { "negA", { Ebh1
}, 0 },
2615 { "mulA", { Eb
}, 0 }, /* Don't print the implicit %al register, */
2616 { "imulA", { Eb
}, 0 }, /* to distinguish these opcodes from other */
2617 { "divA", { Eb
}, 0 }, /* mul/imul opcodes. Do the same for div */
2618 { "idivA", { Eb
}, 0 }, /* and idiv for consistency. */
2622 { "testQ", { Ev
, Iv
}, 0 },
2623 { "testQ", { Ev
, Iv
}, 0 },
2624 { "notQ", { Evh1
}, 0 },
2625 { "negQ", { Evh1
}, 0 },
2626 { "mulQ", { Ev
}, 0 }, /* Don't print the implicit register. */
2627 { "imulQ", { Ev
}, 0 },
2628 { "divQ", { Ev
}, 0 },
2629 { "idivQ", { Ev
}, 0 },
2633 { "incA", { Ebh1
}, 0 },
2634 { "decA", { Ebh1
}, 0 },
2638 { "incQ", { Evh1
}, 0 },
2639 { "decQ", { Evh1
}, 0 },
2640 { "call{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2641 { "{l|}call^", { indirEp
}, 0 },
2642 { "jmp{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2643 { "{l|}jmp^", { indirEp
}, 0 },
2644 { "push{P|}", { stackEv
}, 0 },
2649 { "sldtD", { Sv
}, 0 },
2650 { "strD", { Sv
}, 0 },
2651 { "lldtD", { Sv
}, 0 },
2652 { "ltrD", { Sv
}, 0 },
2653 { "verrD", { Sv
}, 0 },
2654 { "verwD", { Sv
}, 0 },
2655 { X86_64_TABLE (X86_64_0F00_REG_6
) },
2660 { MOD_TABLE (MOD_0F01_REG_0
) },
2661 { MOD_TABLE (MOD_0F01_REG_1
) },
2662 { MOD_TABLE (MOD_0F01_REG_2
) },
2663 { MOD_TABLE (MOD_0F01_REG_3
) },
2664 { "smswD", { Sv
}, 0 },
2665 { MOD_TABLE (MOD_0F01_REG_5
) },
2666 { "lmsw", { Ew
}, 0 },
2667 { MOD_TABLE (MOD_0F01_REG_7
) },
2671 { "prefetch", { Mb
}, 0 },
2672 { "prefetchw", { Mb
}, 0 },
2673 { "prefetchwt1", { Mb
}, 0 },
2674 { "prefetch", { Mb
}, 0 },
2675 { "prefetch", { Mb
}, 0 },
2676 { "prefetch", { Mb
}, 0 },
2677 { "prefetch", { Mb
}, 0 },
2678 { "prefetch", { Mb
}, 0 },
2682 { MOD_TABLE (MOD_0F18_REG_0
) },
2683 { MOD_TABLE (MOD_0F18_REG_1
) },
2684 { MOD_TABLE (MOD_0F18_REG_2
) },
2685 { MOD_TABLE (MOD_0F18_REG_3
) },
2686 { "nopQ", { Ev
}, 0 },
2687 { "nopQ", { Ev
}, 0 },
2688 { MOD_TABLE (MOD_0F18_REG_6
) },
2689 { MOD_TABLE (MOD_0F18_REG_7
) },
2691 /* REG_0F1C_P_0_MOD_0 */
2693 { "cldemote", { Mb
}, 0 },
2694 { "nopQ", { Ev
}, 0 },
2695 { "nopQ", { Ev
}, 0 },
2696 { "nopQ", { Ev
}, 0 },
2697 { "nopQ", { Ev
}, 0 },
2698 { "nopQ", { Ev
}, 0 },
2699 { "nopQ", { Ev
}, 0 },
2700 { "nopQ", { Ev
}, 0 },
2702 /* REG_0F1E_P_1_MOD_3 */
2704 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2705 { "rdsspK", { Edq
}, 0 },
2706 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2707 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2708 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2709 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2710 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2711 { RM_TABLE (RM_0F1E_P_1_MOD_3_REG_7
) },
2713 /* REG_0F38D8_PREFIX_1 */
2715 { "aesencwide128kl", { M
}, 0 },
2716 { "aesdecwide128kl", { M
}, 0 },
2717 { "aesencwide256kl", { M
}, 0 },
2718 { "aesdecwide256kl", { M
}, 0 },
2720 /* REG_0F3A0F_P_1 */
2722 { RM_TABLE (RM_0F3A0F_P_1_R_0
) },
2728 { "psrlw", { Nq
, Ib
}, PREFIX_OPCODE
},
2730 { "psraw", { Nq
, Ib
}, PREFIX_OPCODE
},
2732 { "psllw", { Nq
, Ib
}, PREFIX_OPCODE
},
2738 { "psrld", { Nq
, Ib
}, PREFIX_OPCODE
},
2740 { "psrad", { Nq
, Ib
}, PREFIX_OPCODE
},
2742 { "pslld", { Nq
, Ib
}, PREFIX_OPCODE
},
2748 { "psrlq", { Nq
, Ib
}, PREFIX_OPCODE
},
2749 { "psrldq", { Ux
, Ib
}, PREFIX_DATA
},
2752 { "psllq", { Nq
, Ib
}, PREFIX_OPCODE
},
2753 { "pslldq", { Ux
, Ib
}, PREFIX_DATA
},
2757 { "montmul", { { OP_0f07
, 0 } }, 0 },
2758 { "xsha1", { { OP_0f07
, 0 } }, 0 },
2759 { "xsha256", { { OP_0f07
, 0 } }, 0 },
2763 { "xstore-rng", { { OP_0f07
, 0 } }, 0 },
2764 { "xcrypt-ecb", { { OP_0f07
, 0 } }, 0 },
2765 { "xcrypt-cbc", { { OP_0f07
, 0 } }, 0 },
2766 { "xcrypt-ctr", { { OP_0f07
, 0 } }, 0 },
2767 { "xcrypt-cfb", { { OP_0f07
, 0 } }, 0 },
2768 { "xcrypt-ofb", { { OP_0f07
, 0 } }, 0 },
2772 { MOD_TABLE (MOD_0FAE_REG_0
) },
2773 { MOD_TABLE (MOD_0FAE_REG_1
) },
2774 { MOD_TABLE (MOD_0FAE_REG_2
) },
2775 { MOD_TABLE (MOD_0FAE_REG_3
) },
2776 { MOD_TABLE (MOD_0FAE_REG_4
) },
2777 { MOD_TABLE (MOD_0FAE_REG_5
) },
2778 { MOD_TABLE (MOD_0FAE_REG_6
) },
2779 { MOD_TABLE (MOD_0FAE_REG_7
) },
2787 { "btQ", { Ev
, Ib
}, 0 },
2788 { "btsQ", { Evh1
, Ib
}, 0 },
2789 { "btrQ", { Evh1
, Ib
}, 0 },
2790 { "btcQ", { Evh1
, Ib
}, 0 },
2795 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} }, 0 },
2797 { "xrstors", { FXSAVE
}, 0 },
2798 { "xsavec", { FXSAVE
}, 0 },
2799 { "xsaves", { FXSAVE
}, 0 },
2800 { MOD_TABLE (MOD_0FC7_REG_6
) },
2801 { MOD_TABLE (MOD_0FC7_REG_7
) },
2807 { "vpsrlw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2809 { "vpsraw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2811 { "vpsllw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2817 { "vpsrld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2819 { "vpsrad", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2821 { "vpslld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2827 { "vpsrlq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2828 { "vpsrldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2831 { "vpsllq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2832 { "vpslldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2838 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_2
) },
2839 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_3
) },
2841 /* REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0 */
2843 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
) },
2845 /* REG_VEX_0F38F3_L_0 */
2848 { "blsrS", { VexGdq
, Edq
}, PREFIX_OPCODE
},
2849 { "blsmskS", { VexGdq
, Edq
}, PREFIX_OPCODE
},
2850 { "blsiS", { VexGdq
, Edq
}, PREFIX_OPCODE
},
2852 /* REG_XOP_09_01_L_0 */
2855 { "blcfill", { VexGdq
, Edq
}, 0 },
2856 { "blsfill", { VexGdq
, Edq
}, 0 },
2857 { "blcs", { VexGdq
, Edq
}, 0 },
2858 { "tzmsk", { VexGdq
, Edq
}, 0 },
2859 { "blcic", { VexGdq
, Edq
}, 0 },
2860 { "blsic", { VexGdq
, Edq
}, 0 },
2861 { "t1mskc", { VexGdq
, Edq
}, 0 },
2863 /* REG_XOP_09_02_L_0 */
2866 { "blcmsk", { VexGdq
, Edq
}, 0 },
2871 { "blci", { VexGdq
, Edq
}, 0 },
2873 /* REG_XOP_09_12_L_0 */
2875 { "llwpcb", { Rdq
}, 0 },
2876 { "slwpcb", { Rdq
}, 0 },
2878 /* REG_XOP_0A_12_L_0 */
2880 { "lwpins", { VexGdq
, Ed
, Id
}, 0 },
2881 { "lwpval", { VexGdq
, Ed
, Id
}, 0 },
2884 #include "i386-dis-evex-reg.h"
2887 static const struct dis386 prefix_table
[][4] = {
2890 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
2891 { "pause", { XX
}, 0 },
2892 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
2893 { NULL
, { { NULL
, 0 } }, PREFIX_IGNORED
}
2896 /* PREFIX_0F00_REG_6_X86_64 */
2901 { "lkgsD", { Sv
}, 0 },
2904 /* PREFIX_0F01_REG_0_MOD_3_RM_6 */
2906 { "wrmsrns", { Skip_MODRM
}, 0 },
2907 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_1
) },
2909 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_3
) },
2912 /* PREFIX_0F01_REG_0_MOD_3_RM_7 */
2914 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_7_P_0
) },
2917 /* PREFIX_0F01_REG_1_RM_2 */
2919 { "clac", { Skip_MODRM
}, 0 },
2920 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_1
) },
2922 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_3
)},
2925 /* PREFIX_0F01_REG_1_RM_4 */
2929 { "tdcall", { Skip_MODRM
}, 0 },
2933 /* PREFIX_0F01_REG_1_RM_5 */
2937 { X86_64_TABLE (X86_64_0F01_REG_1_RM_5_PREFIX_2
) },
2941 /* PREFIX_0F01_REG_1_RM_6 */
2945 { X86_64_TABLE (X86_64_0F01_REG_1_RM_6_PREFIX_2
) },
2949 /* PREFIX_0F01_REG_1_RM_7 */
2951 { "encls", { Skip_MODRM
}, 0 },
2953 { X86_64_TABLE (X86_64_0F01_REG_1_RM_7_PREFIX_2
) },
2957 /* PREFIX_0F01_REG_3_RM_1 */
2959 { "vmmcall", { Skip_MODRM
}, 0 },
2960 { "vmgexit", { Skip_MODRM
}, 0 },
2962 { "vmgexit", { Skip_MODRM
}, 0 },
2965 /* PREFIX_0F01_REG_5_MOD_0 */
2968 { "rstorssp", { Mq
}, PREFIX_OPCODE
},
2971 /* PREFIX_0F01_REG_5_MOD_3_RM_0 */
2973 { "serialize", { Skip_MODRM
}, PREFIX_OPCODE
},
2974 { "setssbsy", { Skip_MODRM
}, PREFIX_OPCODE
},
2976 { "xsusldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
2979 /* PREFIX_0F01_REG_5_MOD_3_RM_1 */
2984 { "xresldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
2987 /* PREFIX_0F01_REG_5_MOD_3_RM_2 */
2990 { "saveprevssp", { Skip_MODRM
}, PREFIX_OPCODE
},
2993 /* PREFIX_0F01_REG_5_MOD_3_RM_4 */
2996 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
) },
2999 /* PREFIX_0F01_REG_5_MOD_3_RM_5 */
3002 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
) },
3005 /* PREFIX_0F01_REG_5_MOD_3_RM_6 */
3007 { "rdpkru", { Skip_MODRM
}, 0 },
3008 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
) },
3011 /* PREFIX_0F01_REG_5_MOD_3_RM_7 */
3013 { "wrpkru", { Skip_MODRM
}, 0 },
3014 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
) },
3017 /* PREFIX_0F01_REG_7_MOD_3_RM_2 */
3019 { "monitorx", { { OP_Monitor
, 0 } }, 0 },
3020 { "mcommit", { Skip_MODRM
}, 0 },
3023 /* PREFIX_0F01_REG_7_MOD_3_RM_5 */
3025 { "rdpru", { Skip_MODRM
}, 0 },
3026 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
) },
3029 /* PREFIX_0F01_REG_7_MOD_3_RM_6 */
3031 { "invlpgb", { Skip_MODRM
}, 0 },
3032 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
) },
3034 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
) },
3037 /* PREFIX_0F01_REG_7_MOD_3_RM_7 */
3039 { "tlbsync", { Skip_MODRM
}, 0 },
3040 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
) },
3042 { "pvalidate", { Skip_MODRM
}, 0 },
3047 { "wbinvd", { XX
}, 0 },
3048 { "wbnoinvd", { XX
}, 0 },
3053 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3054 { "%XEVmovs%XS", { XMScalar
, VexScalarR
, EXd
}, 0 },
3055 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3056 { "%XEVmovs%XD", { XMScalar
, VexScalarR
, EXq
}, 0 },
3061 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3062 { "%XEVmovs%XS", { EXdS
, VexScalarR
, XMScalar
}, 0 },
3063 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3064 { "%XEVmovs%XD", { EXqS
, VexScalarR
, XMScalar
}, 0 },
3069 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
3070 { "movsldup", { XM
, EXx
}, 0 },
3071 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
3072 { "movddup", { XM
, EXq
}, 0 },
3077 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
3078 { "movshdup", { XM
, EXx
}, 0 },
3079 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
3082 /* PREFIX_0F18_REG_6_MOD_0_X86_64 */
3084 { "prefetchit1", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3085 { "nopQ", { Ev
}, 0 },
3086 { "nopQ", { Ev
}, 0 },
3087 { "nopQ", { Ev
}, 0 },
3090 /* PREFIX_0F18_REG_7_MOD_0_X86_64 */
3092 { "prefetchit0", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3093 { "nopQ", { Ev
}, 0 },
3094 { "nopQ", { Ev
}, 0 },
3095 { "nopQ", { Ev
}, 0 },
3100 { MOD_TABLE (MOD_0F1A_PREFIX_0
) },
3101 { "bndcl", { Gbnd
, Ev_bnd
}, 0 },
3102 { "bndmov", { Gbnd
, Ebnd
}, 0 },
3103 { "bndcu", { Gbnd
, Ev_bnd
}, 0 },
3108 { MOD_TABLE (MOD_0F1B_PREFIX_0
) },
3109 { MOD_TABLE (MOD_0F1B_PREFIX_1
) },
3110 { "bndmov", { EbndS
, Gbnd
}, 0 },
3111 { "bndcn", { Gbnd
, Ev_bnd
}, 0 },
3116 { MOD_TABLE (MOD_0F1C_PREFIX_0
) },
3117 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3118 { "nopQ", { Ev
}, 0 },
3119 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3124 { "nopQ", { Ev
}, 0 },
3125 { MOD_TABLE (MOD_0F1E_PREFIX_1
) },
3126 { "nopQ", { Ev
}, 0 },
3127 { NULL
, { XX
}, PREFIX_IGNORED
},
3132 { "cvtpi2ps", { XM
, EMCq
}, PREFIX_OPCODE
},
3133 { "cvtsi2ss{%LQ|}", { XM
, Edq
}, PREFIX_OPCODE
},
3134 { "cvtpi2pd", { XM
, EMCq
}, PREFIX_OPCODE
},
3135 { "cvtsi2sd{%LQ|}", { XM
, Edq
}, 0 },
3140 { "movntps", { Mx
, XM
}, 0 },
3141 { "movntss", { Md
, XM
}, 0 },
3142 { "movntpd", { Mx
, XM
}, 0 },
3143 { "movntsd", { Mq
, XM
}, 0 },
3148 { "cvttps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3149 { "cvttss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3150 { "cvttpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3151 { "cvttsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3156 { "cvtps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3157 { "cvtss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3158 { "cvtpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3159 { "cvtsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3164 { "%XEVucomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3166 { "%XEVucomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3171 { "%XEVcomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3173 { "%XEVcomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3178 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3179 { "%XEVsqrts%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3180 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3181 { "%XEVsqrts%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3186 { "Vrsqrtps", { XM
, EXx
}, 0 },
3187 { "Vrsqrtss", { XMScalar
, VexScalar
, EXd
}, 0 },
3192 { "Vrcpps", { XM
, EXx
}, 0 },
3193 { "Vrcpss", { XMScalar
, VexScalar
, EXd
}, 0 },
3198 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3199 { "%XEVadds%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3200 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3201 { "%XEVadds%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3206 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3207 { "%XEVmuls%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3208 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3209 { "%XEVmuls%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3214 { "%XEVcvtp%XS2pd", { XM
, EXEvexHalfBcstXmmq
, EXxEVexS
}, 0 },
3215 { "%XEVcvts%XS2sd", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3216 { "%XEVcvtp%XD2ps%XY", { XMxmmq
, EXx
, EXxEVexR
}, 0 },
3217 { "%XEVcvts%XD2ss", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3222 { "Vcvtdq2ps", { XM
, EXx
}, 0 },
3223 { "Vcvttps2dq", { XM
, EXx
}, 0 },
3224 { "Vcvtps2dq", { XM
, EXx
}, 0 },
3229 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3230 { "%XEVsubs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3231 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3232 { "%XEVsubs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3237 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3238 { "%XEVmins%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3239 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3240 { "%XEVmins%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3245 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3246 { "%XEVdivs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3247 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3248 { "%XEVdivs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3253 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3254 { "%XEVmaxs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3255 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3256 { "%XEVmaxs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3261 { "punpcklbw",{ MX
, EMd
}, PREFIX_OPCODE
},
3263 { "punpcklbw",{ MX
, EMx
}, PREFIX_OPCODE
},
3268 { "punpcklwd",{ MX
, EMd
}, PREFIX_OPCODE
},
3270 { "punpcklwd",{ MX
, EMx
}, PREFIX_OPCODE
},
3275 { "punpckldq",{ MX
, EMd
}, PREFIX_OPCODE
},
3277 { "punpckldq",{ MX
, EMx
}, PREFIX_OPCODE
},
3282 { "movq", { MX
, EM
}, PREFIX_OPCODE
},
3283 { "movdqu", { XM
, EXx
}, PREFIX_OPCODE
},
3284 { "movdqa", { XM
, EXx
}, PREFIX_OPCODE
},
3289 { "pshufw", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
3290 { "pshufhw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3291 { "pshufd", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3292 { "pshuflw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3297 {"vmread", { Em
, Gm
}, 0 },
3299 {"extrq", { Uxmm
, Ib
, Ib
}, 0 },
3300 {"insertq", { XM
, Uxmm
, Ib
, Ib
}, 0 },
3305 {"vmwrite", { Gm
, Em
}, 0 },
3307 {"extrq", { XM
, Uxmm
}, 0 },
3308 {"insertq", { XM
, Uxmm
}, 0 },
3315 { "Vhaddpd", { XM
, Vex
, EXx
}, 0 },
3316 { "Vhaddps", { XM
, Vex
, EXx
}, 0 },
3323 { "Vhsubpd", { XM
, Vex
, EXx
}, 0 },
3324 { "Vhsubps", { XM
, Vex
, EXx
}, 0 },
3329 { "movK", { Edq
, MX
}, PREFIX_OPCODE
},
3330 { "movq", { XM
, EXq
}, PREFIX_OPCODE
},
3331 { "movK", { Edq
, XM
}, PREFIX_OPCODE
},
3336 { "movq", { EMS
, MX
}, PREFIX_OPCODE
},
3337 { "movdqu", { EXxS
, XM
}, PREFIX_OPCODE
},
3338 { "movdqa", { EXxS
, XM
}, PREFIX_OPCODE
},
3341 /* PREFIX_0FAE_REG_0_MOD_3 */
3344 { "rdfsbase", { Ev
}, 0 },
3347 /* PREFIX_0FAE_REG_1_MOD_3 */
3350 { "rdgsbase", { Ev
}, 0 },
3353 /* PREFIX_0FAE_REG_2_MOD_3 */
3356 { "wrfsbase", { Ev
}, 0 },
3359 /* PREFIX_0FAE_REG_3_MOD_3 */
3362 { "wrgsbase", { Ev
}, 0 },
3365 /* PREFIX_0FAE_REG_4_MOD_0 */
3367 { "xsave", { FXSAVE
}, 0 },
3368 { "ptwrite{%LQ|}", { Edq
}, 0 },
3371 /* PREFIX_0FAE_REG_4_MOD_3 */
3374 { "ptwrite{%LQ|}", { Edq
}, 0 },
3377 /* PREFIX_0FAE_REG_5_MOD_3 */
3379 { "lfence", { Skip_MODRM
}, 0 },
3380 { "incsspK", { Edq
}, PREFIX_OPCODE
},
3383 /* PREFIX_0FAE_REG_6_MOD_0 */
3385 { "xsaveopt", { FXSAVE
}, PREFIX_OPCODE
},
3386 { "clrssbsy", { Mq
}, PREFIX_OPCODE
},
3387 { "clwb", { Mb
}, PREFIX_OPCODE
},
3390 /* PREFIX_0FAE_REG_6_MOD_3 */
3392 { RM_TABLE (RM_0FAE_REG_6_MOD_3_P_0
) },
3393 { "umonitor", { Eva
}, PREFIX_OPCODE
},
3394 { "tpause", { Edq
}, PREFIX_OPCODE
},
3395 { "umwait", { Edq
}, PREFIX_OPCODE
},
3398 /* PREFIX_0FAE_REG_7_MOD_0 */
3400 { "clflush", { Mb
}, 0 },
3402 { "clflushopt", { Mb
}, 0 },
3408 { "popcntS", { Gv
, Ev
}, 0 },
3413 { "bsfS", { Gv
, Ev
}, 0 },
3414 { "tzcntS", { Gv
, Ev
}, 0 },
3415 { "bsfS", { Gv
, Ev
}, 0 },
3420 { "bsrS", { Gv
, Ev
}, 0 },
3421 { "lzcntS", { Gv
, Ev
}, 0 },
3422 { "bsrS", { Gv
, Ev
}, 0 },
3427 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3428 { "Vcmpss", { XMScalar
, VexScalar
, EXd
, CMP
}, 0 },
3429 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3430 { "Vcmpsd", { XMScalar
, VexScalar
, EXq
, CMP
}, 0 },
3433 /* PREFIX_0FC7_REG_6_MOD_0 */
3435 { "vmptrld",{ Mq
}, 0 },
3436 { "vmxon", { Mq
}, 0 },
3437 { "vmclear",{ Mq
}, 0 },
3440 /* PREFIX_0FC7_REG_6_MOD_3 */
3442 { "rdrand", { Ev
}, 0 },
3443 { X86_64_TABLE (X86_64_0FC7_REG_6_MOD_3_PREFIX_1
) },
3444 { "rdrand", { Ev
}, 0 }
3447 /* PREFIX_0FC7_REG_7_MOD_3 */
3449 { "rdseed", { Ev
}, 0 },
3450 { "rdpid", { Em
}, 0 },
3451 { "rdseed", { Ev
}, 0 },
3458 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3459 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3465 { "movq2dq",{ XM
, Nq
}, 0 },
3466 { "movq", { EXqS
, XM
}, 0 },
3467 { "movdq2q",{ MX
, Ux
}, 0 },
3473 { "Vcvtdq2pd", { XM
, EXxmmq
}, 0 },
3474 { "Vcvttpd2dq%XY", { XMM
, EXx
}, 0 },
3475 { "Vcvtpd2dq%XY", { XMM
, EXx
}, 0 },
3480 { "movntq", { Mq
, MX
}, 0 },
3482 { "movntdq", { Mx
, XM
}, 0 },
3490 { "Vlddqu", { XM
, M
}, 0 },
3495 { "maskmovq", { MX
, Nq
}, PREFIX_OPCODE
},
3497 { "maskmovdqu", { XM
, Ux
}, PREFIX_OPCODE
},
3503 { REG_TABLE (REG_0F38D8_PREFIX_1
) },
3509 { MOD_TABLE (MOD_0F38DC_PREFIX_1
) },
3510 { "aesenc", { XM
, EXx
}, 0 },
3516 { "aesdec128kl", { XM
, M
}, 0 },
3517 { "aesenclast", { XM
, EXx
}, 0 },
3523 { "aesenc256kl", { XM
, M
}, 0 },
3524 { "aesdec", { XM
, EXx
}, 0 },
3530 { "aesdec256kl", { XM
, M
}, 0 },
3531 { "aesdeclast", { XM
, EXx
}, 0 },
3536 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3538 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3539 { "crc32A", { Gdq
, Eb
}, PREFIX_OPCODE
},
3544 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3546 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3547 { "crc32Q", { Gdq
, Ev
}, PREFIX_OPCODE
},
3552 { "wrssK", { M
, Gdq
}, 0 },
3553 { "adoxS", { Gdq
, Edq
}, 0 },
3554 { "adcxS", { Gdq
, Edq
}, 0 },
3561 { "enqcmds", { Gva
, M
}, 0 },
3562 { "movdir64b", { Gva
, M
}, 0 },
3563 { "enqcmd", { Gva
, M
}, 0 },
3568 { "encodekey128", { Gd
, Rd
}, 0 },
3574 { "encodekey256", { Gd
, Rd
}, 0 },
3579 { "aadd", { Mdq
, Gdq
}, 0 },
3580 { "axor", { Mdq
, Gdq
}, 0 },
3581 { "aand", { Mdq
, Gdq
}, 0 },
3582 { "aor", { Mdq
, Gdq
}, 0 },
3588 { REG_TABLE (REG_0F3A0F_P_1
) },
3591 /* PREFIX_VEX_0F12 */
3593 { VEX_LEN_TABLE (VEX_LEN_0F12_P_0
) },
3594 { "%XEvmov%XSldup", { XM
, EXEvexXNoBcst
}, 0 },
3595 { VEX_LEN_TABLE (VEX_LEN_0F12_P_2
) },
3596 { "%XEvmov%XDdup", { XM
, EXymmq
}, 0 },
3599 /* PREFIX_VEX_0F16 */
3601 { VEX_LEN_TABLE (VEX_LEN_0F16_P_0
) },
3602 { "%XEvmov%XShdup", { XM
, EXEvexXNoBcst
}, 0 },
3603 { VEX_LEN_TABLE (VEX_LEN_0F16_P_2
) },
3606 /* PREFIX_VEX_0F2A */
3609 { "%XEvcvtsi2ssY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR
, Edq
}, 0 },
3611 { "%XEvcvtsi2sdY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR64
, Edq
}, 0 },
3614 /* PREFIX_VEX_0F2C */
3617 { "%XEvcvttss2si", { Gdq
, EXd
, EXxEVexS
}, 0 },
3619 { "%XEvcvttsd2si", { Gdq
, EXq
, EXxEVexS
}, 0 },
3622 /* PREFIX_VEX_0F2D */
3625 { "%XEvcvtss2si", { Gdq
, EXd
, EXxEVexR
}, 0 },
3627 { "%XEvcvtsd2si", { Gdq
, EXq
, EXxEVexR
}, 0 },
3630 /* PREFIX_VEX_0F41_L_1_W_0 */
3632 { "kandw", { MaskG
, MaskVex
, MaskR
}, 0 },
3634 { "kandb", { MaskG
, MaskVex
, MaskR
}, 0 },
3637 /* PREFIX_VEX_0F41_L_1_W_1 */
3639 { "kandq", { MaskG
, MaskVex
, MaskR
}, 0 },
3641 { "kandd", { MaskG
, MaskVex
, MaskR
}, 0 },
3644 /* PREFIX_VEX_0F42_L_1_W_0 */
3646 { "kandnw", { MaskG
, MaskVex
, MaskR
}, 0 },
3648 { "kandnb", { MaskG
, MaskVex
, MaskR
}, 0 },
3651 /* PREFIX_VEX_0F42_L_1_W_1 */
3653 { "kandnq", { MaskG
, MaskVex
, MaskR
}, 0 },
3655 { "kandnd", { MaskG
, MaskVex
, MaskR
}, 0 },
3658 /* PREFIX_VEX_0F44_L_0_W_0 */
3660 { "knotw", { MaskG
, MaskR
}, 0 },
3662 { "knotb", { MaskG
, MaskR
}, 0 },
3665 /* PREFIX_VEX_0F44_L_0_W_1 */
3667 { "knotq", { MaskG
, MaskR
}, 0 },
3669 { "knotd", { MaskG
, MaskR
}, 0 },
3672 /* PREFIX_VEX_0F45_L_1_W_0 */
3674 { "korw", { MaskG
, MaskVex
, MaskR
}, 0 },
3676 { "korb", { MaskG
, MaskVex
, MaskR
}, 0 },
3679 /* PREFIX_VEX_0F45_L_1_W_1 */
3681 { "korq", { MaskG
, MaskVex
, MaskR
}, 0 },
3683 { "kord", { MaskG
, MaskVex
, MaskR
}, 0 },
3686 /* PREFIX_VEX_0F46_L_1_W_0 */
3688 { "kxnorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3690 { "kxnorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3693 /* PREFIX_VEX_0F46_L_1_W_1 */
3695 { "kxnorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3697 { "kxnord", { MaskG
, MaskVex
, MaskR
}, 0 },
3700 /* PREFIX_VEX_0F47_L_1_W_0 */
3702 { "kxorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3704 { "kxorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3707 /* PREFIX_VEX_0F47_L_1_W_1 */
3709 { "kxorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3711 { "kxord", { MaskG
, MaskVex
, MaskR
}, 0 },
3714 /* PREFIX_VEX_0F4A_L_1_W_0 */
3716 { "kaddw", { MaskG
, MaskVex
, MaskR
}, 0 },
3718 { "kaddb", { MaskG
, MaskVex
, MaskR
}, 0 },
3721 /* PREFIX_VEX_0F4A_L_1_W_1 */
3723 { "kaddq", { MaskG
, MaskVex
, MaskR
}, 0 },
3725 { "kaddd", { MaskG
, MaskVex
, MaskR
}, 0 },
3728 /* PREFIX_VEX_0F4B_L_1_W_0 */
3730 { "kunpckwd", { MaskG
, MaskVex
, MaskR
}, 0 },
3732 { "kunpckbw", { MaskG
, MaskVex
, MaskR
}, 0 },
3735 /* PREFIX_VEX_0F4B_L_1_W_1 */
3737 { "kunpckdq", { MaskG
, MaskVex
, MaskR
}, 0 },
3740 /* PREFIX_VEX_0F6F */
3743 { "vmovdqu", { XM
, EXx
}, 0 },
3744 { "vmovdqa", { XM
, EXx
}, 0 },
3747 /* PREFIX_VEX_0F70 */
3750 { "vpshufhw", { XM
, EXx
, Ib
}, 0 },
3751 { "vpshufd", { XM
, EXx
, Ib
}, 0 },
3752 { "vpshuflw", { XM
, EXx
, Ib
}, 0 },
3755 /* PREFIX_VEX_0F7E */
3758 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_1
) },
3759 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_2
) },
3762 /* PREFIX_VEX_0F7F */
3765 { "vmovdqu", { EXxS
, XM
}, 0 },
3766 { "vmovdqa", { EXxS
, XM
}, 0 },
3769 /* PREFIX_VEX_0F90_L_0_W_0 */
3771 { "kmovw", { MaskG
, MaskE
}, 0 },
3773 { "kmovb", { MaskG
, MaskBDE
}, 0 },
3776 /* PREFIX_VEX_0F90_L_0_W_1 */
3778 { "kmovq", { MaskG
, MaskE
}, 0 },
3780 { "kmovd", { MaskG
, MaskBDE
}, 0 },
3783 /* PREFIX_VEX_0F91_L_0_W_0 */
3785 { "kmovw", { Mw
, MaskG
}, 0 },
3787 { "kmovb", { Mb
, MaskG
}, 0 },
3790 /* PREFIX_VEX_0F91_L_0_W_1 */
3792 { "kmovq", { Mq
, MaskG
}, 0 },
3794 { "kmovd", { Md
, MaskG
}, 0 },
3797 /* PREFIX_VEX_0F92_L_0_W_0 */
3799 { "kmovw", { MaskG
, Rdq
}, 0 },
3801 { "kmovb", { MaskG
, Rdq
}, 0 },
3802 { "kmovd", { MaskG
, Rdq
}, 0 },
3805 /* PREFIX_VEX_0F92_L_0_W_1 */
3810 { "kmovK", { MaskG
, Rdq
}, 0 },
3813 /* PREFIX_VEX_0F93_L_0_W_0 */
3815 { "kmovw", { Gdq
, MaskR
}, 0 },
3817 { "kmovb", { Gdq
, MaskR
}, 0 },
3818 { "kmovd", { Gdq
, MaskR
}, 0 },
3821 /* PREFIX_VEX_0F93_L_0_W_1 */
3826 { "kmovK", { Gdq
, MaskR
}, 0 },
3829 /* PREFIX_VEX_0F98_L_0_W_0 */
3831 { "kortestw", { MaskG
, MaskR
}, 0 },
3833 { "kortestb", { MaskG
, MaskR
}, 0 },
3836 /* PREFIX_VEX_0F98_L_0_W_1 */
3838 { "kortestq", { MaskG
, MaskR
}, 0 },
3840 { "kortestd", { MaskG
, MaskR
}, 0 },
3843 /* PREFIX_VEX_0F99_L_0_W_0 */
3845 { "ktestw", { MaskG
, MaskR
}, 0 },
3847 { "ktestb", { MaskG
, MaskR
}, 0 },
3850 /* PREFIX_VEX_0F99_L_0_W_1 */
3852 { "ktestq", { MaskG
, MaskR
}, 0 },
3854 { "ktestd", { MaskG
, MaskR
}, 0 },
3857 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0 */
3859 { "ldtilecfg", { M
}, 0 },
3861 { "sttilecfg", { M
}, 0 },
3864 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1 */
3866 { REG_TABLE (REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0
) },
3869 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
) },
3872 /* PREFIX_VEX_0F384B_X86_64_L_0_W_0 */
3875 { "tilestored", { MVexSIBMEM
, TMM
}, 0 },
3876 { "tileloaddt1", { TMM
, MVexSIBMEM
}, 0 },
3877 { "tileloadd", { TMM
, MVexSIBMEM
}, 0 },
3880 /* PREFIX_VEX_0F3850_W_0 */
3882 { "vpdpbuud", { XM
, Vex
, EXx
}, 0 },
3883 { "vpdpbsud", { XM
, Vex
, EXx
}, 0 },
3884 { "%XVvpdpbusd", { XM
, Vex
, EXx
}, 0 },
3885 { "vpdpbssd", { XM
, Vex
, EXx
}, 0 },
3888 /* PREFIX_VEX_0F3851_W_0 */
3890 { "vpdpbuuds", { XM
, Vex
, EXx
}, 0 },
3891 { "vpdpbsuds", { XM
, Vex
, EXx
}, 0 },
3892 { "%XVvpdpbusds", { XM
, Vex
, EXx
}, 0 },
3893 { "vpdpbssds", { XM
, Vex
, EXx
}, 0 },
3895 /* PREFIX_VEX_0F385C_X86_64_L_0_W_0 */
3898 { "tdpbf16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
3900 { "tdpfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
3903 /* PREFIX_VEX_0F385E_X86_64_L_0_W_0 */
3905 { "tdpbuud", {TMM
, Rtmm
, VexTmm
}, 0 },
3906 { "tdpbsud", {TMM
, Rtmm
, VexTmm
}, 0 },
3907 { "tdpbusd", {TMM
, Rtmm
, VexTmm
}, 0 },
3908 { "tdpbssd", {TMM
, Rtmm
, VexTmm
}, 0 },
3911 /* PREFIX_VEX_0F386C_X86_64_L_0_W_0 */
3913 { "tcmmrlfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
3915 { "tcmmimfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
3918 /* PREFIX_VEX_0F3872 */
3921 { VEX_W_TABLE (VEX_W_0F3872_P_1
) },
3924 /* PREFIX_VEX_0F38B0_W_0 */
3926 { "vcvtneoph2ps", { XM
, Mx
}, 0 },
3927 { "vcvtneebf162ps", { XM
, Mx
}, 0 },
3928 { "vcvtneeph2ps", { XM
, Mx
}, 0 },
3929 { "vcvtneobf162ps", { XM
, Mx
}, 0 },
3932 /* PREFIX_VEX_0F38B1_W_0 */
3935 { "vbcstnebf162ps", { XM
, Mw
}, 0 },
3936 { "vbcstnesh2ps", { XM
, Mw
}, 0 },
3939 /* PREFIX_VEX_0F38D2_W_0 */
3941 { "vpdpwuud", { XM
, Vex
, EXx
}, 0 },
3942 { "vpdpwsud", { XM
, Vex
, EXx
}, 0 },
3943 { "vpdpwusd", { XM
, Vex
, EXx
}, 0 },
3946 /* PREFIX_VEX_0F38D3_W_0 */
3948 { "vpdpwuuds", { XM
, Vex
, EXx
}, 0 },
3949 { "vpdpwsuds", { XM
, Vex
, EXx
}, 0 },
3950 { "vpdpwusds", { XM
, Vex
, EXx
}, 0 },
3953 /* PREFIX_VEX_0F38CB */
3958 { VEX_W_TABLE (VEX_W_0F38CB_P_3
) },
3961 /* PREFIX_VEX_0F38CC */
3966 { VEX_W_TABLE (VEX_W_0F38CC_P_3
) },
3969 /* PREFIX_VEX_0F38CD */
3974 { VEX_W_TABLE (VEX_W_0F38CD_P_3
) },
3977 /* PREFIX_VEX_0F38DA_W_0 */
3979 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_0
) },
3980 { "vsm4key4", { XM
, Vex
, EXx
}, 0 },
3981 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_2
) },
3982 { "vsm4rnds4", { XM
, Vex
, EXx
}, 0 },
3985 /* PREFIX_VEX_0F38F5_L_0 */
3987 { "bzhiS", { Gdq
, Edq
, VexGdq
}, 0 },
3988 { "pextS", { Gdq
, VexGdq
, Edq
}, 0 },
3990 { "pdepS", { Gdq
, VexGdq
, Edq
}, 0 },
3993 /* PREFIX_VEX_0F38F6_L_0 */
3998 { "mulxS", { Gdq
, VexGdq
, Edq
}, 0 },
4001 /* PREFIX_VEX_0F38F7_L_0 */
4003 { "bextrS", { Gdq
, Edq
, VexGdq
}, 0 },
4004 { "sarxS", { Gdq
, Edq
, VexGdq
}, 0 },
4005 { "shlxS", { Gdq
, Edq
, VexGdq
}, 0 },
4006 { "shrxS", { Gdq
, Edq
, VexGdq
}, 0 },
4009 /* PREFIX_VEX_0F3AF0_L_0 */
4014 { "rorxS", { Gdq
, Edq
, Ib
}, 0 },
4017 #include "i386-dis-evex-prefix.h"
4020 static const struct dis386 x86_64_table
[][2] = {
4023 { "pushP", { es
}, 0 },
4028 { "popP", { es
}, 0 },
4033 { "pushP", { cs
}, 0 },
4038 { "pushP", { ss
}, 0 },
4043 { "popP", { ss
}, 0 },
4048 { "pushP", { ds
}, 0 },
4053 { "popP", { ds
}, 0 },
4058 { "daa", { XX
}, 0 },
4063 { "das", { XX
}, 0 },
4068 { "aaa", { XX
}, 0 },
4073 { "aas", { XX
}, 0 },
4078 { "pushaP", { XX
}, 0 },
4083 { "popaP", { XX
}, 0 },
4088 { MOD_TABLE (MOD_62_32BIT
) },
4094 { "arplS", { Sv
, Gv
}, 0 },
4095 { "movs", { Gv
, { MOVSXD_Fixup
, movsxd_mode
} }, 0 },
4100 { "ins{R|}", { Yzr
, indirDX
}, 0 },
4101 { "ins{G|}", { Yzr
, indirDX
}, 0 },
4106 { "outs{R|}", { indirDXr
, Xz
}, 0 },
4107 { "outs{G|}", { indirDXr
, Xz
}, 0 },
4112 /* Opcode 0x82 is an alias of opcode 0x80 in 32-bit mode. */
4113 { REG_TABLE (REG_80
) },
4118 { "{l|}call{P|}", { Ap
}, 0 },
4123 { "retP", { Iw
, BND
}, 0 },
4124 { "ret@", { Iw
, BND
}, 0 },
4129 { "retP", { BND
}, 0 },
4130 { "ret@", { BND
}, 0 },
4135 { MOD_TABLE (MOD_C4_32BIT
) },
4136 { VEX_C4_TABLE () },
4141 { MOD_TABLE (MOD_C5_32BIT
) },
4142 { VEX_C5_TABLE () },
4147 { "into", { XX
}, 0 },
4152 { "aam", { Ib
}, 0 },
4157 { "aad", { Ib
}, 0 },
4162 { "callP", { Jv
, BND
}, 0 },
4163 { "call@", { Jv
, BND
}, 0 }
4168 { "jmpP", { Jv
, BND
}, 0 },
4169 { "jmp@", { Jv
, BND
}, 0 }
4174 { "{l|}jmp{P|}", { Ap
}, 0 },
4177 /* X86_64_0F00_REG_6 */
4180 { PREFIX_TABLE (PREFIX_0F00_REG_6_X86_64
) },
4183 /* X86_64_0F01_REG_0 */
4185 { "sgdt{Q|Q}", { M
}, 0 },
4186 { "sgdt", { M
}, 0 },
4189 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_1 */
4192 { "wrmsrlist", { Skip_MODRM
}, 0 },
4195 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_3 */
4198 { "rdmsrlist", { Skip_MODRM
}, 0 },
4201 /* X86_64_0F01_REG_0_MOD_3_RM_7_P_0 */
4204 { "pbndkb", { Skip_MODRM
}, 0 },
4207 /* X86_64_0F01_REG_1 */
4209 { "sidt{Q|Q}", { M
}, 0 },
4210 { "sidt", { M
}, 0 },
4213 /* X86_64_0F01_REG_1_RM_2_PREFIX_1 */
4216 { "eretu", { Skip_MODRM
}, 0 },
4219 /* X86_64_0F01_REG_1_RM_2_PREFIX_3 */
4222 { "erets", { Skip_MODRM
}, 0 },
4225 /* X86_64_0F01_REG_1_RM_5_PREFIX_2 */
4228 { "seamret", { Skip_MODRM
}, 0 },
4231 /* X86_64_0F01_REG_1_RM_6_PREFIX_2 */
4234 { "seamops", { Skip_MODRM
}, 0 },
4237 /* X86_64_0F01_REG_1_RM_7_PREFIX_2 */
4240 { "seamcall", { Skip_MODRM
}, 0 },
4243 /* X86_64_0F01_REG_2 */
4245 { "lgdt{Q|Q}", { M
}, 0 },
4246 { "lgdt", { M
}, 0 },
4249 /* X86_64_0F01_REG_3 */
4251 { "lidt{Q|Q}", { M
}, 0 },
4252 { "lidt", { M
}, 0 },
4255 /* X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1 */
4258 { "uiret", { Skip_MODRM
}, 0 },
4261 /* X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1 */
4264 { "testui", { Skip_MODRM
}, 0 },
4267 /* X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1 */
4270 { "clui", { Skip_MODRM
}, 0 },
4273 /* X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1 */
4276 { "stui", { Skip_MODRM
}, 0 },
4279 /* X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1 */
4282 { "rmpquery", { Skip_MODRM
}, 0 },
4285 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1 */
4288 { "rmpadjust", { Skip_MODRM
}, 0 },
4291 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */
4294 { "rmpupdate", { Skip_MODRM
}, 0 },
4297 /* X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1 */
4300 { "psmash", { Skip_MODRM
}, 0 },
4303 /* X86_64_0F18_REG_6_MOD_0 */
4305 { "nopQ", { Ev
}, 0 },
4306 { PREFIX_TABLE (PREFIX_0F18_REG_6_MOD_0_X86_64
) },
4309 /* X86_64_0F18_REG_7_MOD_0 */
4311 { "nopQ", { Ev
}, 0 },
4312 { PREFIX_TABLE (PREFIX_0F18_REG_7_MOD_0_X86_64
) },
4317 { "movZ", { Em
, Td
}, 0 },
4322 { "movZ", { Td
, Em
}, 0 },
4325 /* X86_64_0FC7_REG_6_MOD_3_PREFIX_1 */
4328 { "senduipi", { Eq
}, 0 },
4331 /* X86_64_VEX_0F3849 */
4334 { VEX_LEN_TABLE (VEX_LEN_0F3849_X86_64
) },
4337 /* X86_64_VEX_0F384B */
4340 { VEX_LEN_TABLE (VEX_LEN_0F384B_X86_64
) },
4343 /* X86_64_VEX_0F385C */
4346 { VEX_LEN_TABLE (VEX_LEN_0F385C_X86_64
) },
4349 /* X86_64_VEX_0F385E */
4352 { VEX_LEN_TABLE (VEX_LEN_0F385E_X86_64
) },
4355 /* X86_64_VEX_0F386C */
4358 { VEX_LEN_TABLE (VEX_LEN_0F386C_X86_64
) },
4361 /* X86_64_VEX_0F38E0 */
4364 { "cmpoxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4367 /* X86_64_VEX_0F38E1 */
4370 { "cmpnoxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4373 /* X86_64_VEX_0F38E2 */
4376 { "cmpbxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4379 /* X86_64_VEX_0F38E3 */
4382 { "cmpnbxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4385 /* X86_64_VEX_0F38E4 */
4388 { "cmpzxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4391 /* X86_64_VEX_0F38E5 */
4394 { "cmpnzxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4397 /* X86_64_VEX_0F38E6 */
4400 { "cmpbexadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4403 /* X86_64_VEX_0F38E7 */
4406 { "cmpnbexadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4409 /* X86_64_VEX_0F38E8 */
4412 { "cmpsxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4415 /* X86_64_VEX_0F38E9 */
4418 { "cmpnsxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4421 /* X86_64_VEX_0F38EA */
4424 { "cmppxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4427 /* X86_64_VEX_0F38EB */
4430 { "cmpnpxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4433 /* X86_64_VEX_0F38EC */
4436 { "cmplxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4439 /* X86_64_VEX_0F38ED */
4442 { "cmpnlxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4445 /* X86_64_VEX_0F38EE */
4448 { "cmplexadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4451 /* X86_64_VEX_0F38EF */
4454 { "cmpnlexadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4458 static const struct dis386 three_byte_table
[][256] = {
4460 /* THREE_BYTE_0F38 */
4463 { "pshufb", { MX
, EM
}, PREFIX_OPCODE
},
4464 { "phaddw", { MX
, EM
}, PREFIX_OPCODE
},
4465 { "phaddd", { MX
, EM
}, PREFIX_OPCODE
},
4466 { "phaddsw", { MX
, EM
}, PREFIX_OPCODE
},
4467 { "pmaddubsw", { MX
, EM
}, PREFIX_OPCODE
},
4468 { "phsubw", { MX
, EM
}, PREFIX_OPCODE
},
4469 { "phsubd", { MX
, EM
}, PREFIX_OPCODE
},
4470 { "phsubsw", { MX
, EM
}, PREFIX_OPCODE
},
4472 { "psignb", { MX
, EM
}, PREFIX_OPCODE
},
4473 { "psignw", { MX
, EM
}, PREFIX_OPCODE
},
4474 { "psignd", { MX
, EM
}, PREFIX_OPCODE
},
4475 { "pmulhrsw", { MX
, EM
}, PREFIX_OPCODE
},
4481 { "pblendvb", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4485 { "blendvps", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4486 { "blendvpd", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4488 { "ptest", { XM
, EXx
}, PREFIX_DATA
},
4494 { "pabsb", { MX
, EM
}, PREFIX_OPCODE
},
4495 { "pabsw", { MX
, EM
}, PREFIX_OPCODE
},
4496 { "pabsd", { MX
, EM
}, PREFIX_OPCODE
},
4499 { "pmovsxbw", { XM
, EXq
}, PREFIX_DATA
},
4500 { "pmovsxbd", { XM
, EXd
}, PREFIX_DATA
},
4501 { "pmovsxbq", { XM
, EXw
}, PREFIX_DATA
},
4502 { "pmovsxwd", { XM
, EXq
}, PREFIX_DATA
},
4503 { "pmovsxwq", { XM
, EXd
}, PREFIX_DATA
},
4504 { "pmovsxdq", { XM
, EXq
}, PREFIX_DATA
},
4508 { "pmuldq", { XM
, EXx
}, PREFIX_DATA
},
4509 { "pcmpeqq", { XM
, EXx
}, PREFIX_DATA
},
4510 { "movntdqa", { XM
, Mx
}, PREFIX_DATA
},
4511 { "packusdw", { XM
, EXx
}, PREFIX_DATA
},
4517 { "pmovzxbw", { XM
, EXq
}, PREFIX_DATA
},
4518 { "pmovzxbd", { XM
, EXd
}, PREFIX_DATA
},
4519 { "pmovzxbq", { XM
, EXw
}, PREFIX_DATA
},
4520 { "pmovzxwd", { XM
, EXq
}, PREFIX_DATA
},
4521 { "pmovzxwq", { XM
, EXd
}, PREFIX_DATA
},
4522 { "pmovzxdq", { XM
, EXq
}, PREFIX_DATA
},
4524 { "pcmpgtq", { XM
, EXx
}, PREFIX_DATA
},
4526 { "pminsb", { XM
, EXx
}, PREFIX_DATA
},
4527 { "pminsd", { XM
, EXx
}, PREFIX_DATA
},
4528 { "pminuw", { XM
, EXx
}, PREFIX_DATA
},
4529 { "pminud", { XM
, EXx
}, PREFIX_DATA
},
4530 { "pmaxsb", { XM
, EXx
}, PREFIX_DATA
},
4531 { "pmaxsd", { XM
, EXx
}, PREFIX_DATA
},
4532 { "pmaxuw", { XM
, EXx
}, PREFIX_DATA
},
4533 { "pmaxud", { XM
, EXx
}, PREFIX_DATA
},
4535 { "pmulld", { XM
, EXx
}, PREFIX_DATA
},
4536 { "phminposuw", { XM
, EXx
}, PREFIX_DATA
},
4607 { "invept", { Gm
, Mo
}, PREFIX_DATA
},
4608 { "invvpid", { Gm
, Mo
}, PREFIX_DATA
},
4609 { "invpcid", { Gm
, M
}, PREFIX_DATA
},
4688 { "sha1nexte", { XM
, EXxmm
}, PREFIX_OPCODE
},
4689 { "sha1msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
4690 { "sha1msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
4691 { "sha256rnds2", { XM
, EXxmm
, XMM0
}, PREFIX_OPCODE
},
4692 { "sha256msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
4693 { "sha256msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
4695 { "gf2p8mulb", { XM
, EXxmm
}, PREFIX_DATA
},
4706 { PREFIX_TABLE (PREFIX_0F38D8
) },
4709 { "aesimc", { XM
, EXx
}, PREFIX_DATA
},
4710 { PREFIX_TABLE (PREFIX_0F38DC
) },
4711 { PREFIX_TABLE (PREFIX_0F38DD
) },
4712 { PREFIX_TABLE (PREFIX_0F38DE
) },
4713 { PREFIX_TABLE (PREFIX_0F38DF
) },
4733 { PREFIX_TABLE (PREFIX_0F38F0
) },
4734 { PREFIX_TABLE (PREFIX_0F38F1
) },
4738 { "wrussK", { M
, Gdq
}, PREFIX_DATA
},
4739 { PREFIX_TABLE (PREFIX_0F38F6
) },
4742 { PREFIX_TABLE (PREFIX_0F38F8
) },
4743 { "movdiri", { Mdq
, Gdq
}, PREFIX_OPCODE
},
4744 { PREFIX_TABLE (PREFIX_0F38FA
) },
4745 { PREFIX_TABLE (PREFIX_0F38FB
) },
4746 { PREFIX_TABLE (PREFIX_0F38FC
) },
4751 /* THREE_BYTE_0F3A */
4763 { "roundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4764 { "roundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4765 { "roundss", { XM
, EXd
, Ib
}, PREFIX_DATA
},
4766 { "roundsd", { XM
, EXq
, Ib
}, PREFIX_DATA
},
4767 { "blendps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4768 { "blendpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4769 { "pblendw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4770 { "palignr", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
4776 { "pextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
4777 { "pextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
4778 { "pextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
4779 { "extractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
4790 { "pinsrb", { XM
, Edb
, Ib
}, PREFIX_DATA
},
4791 { "insertps", { XM
, EXd
, Ib
}, PREFIX_DATA
},
4792 { "pinsrK", { XM
, Edq
, Ib
}, PREFIX_DATA
},
4826 { "dpps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4827 { "dppd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4828 { "mpsadbw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4830 { "pclmulqdq", { XM
, EXx
, PCLMUL
}, PREFIX_DATA
},
4862 { "pcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4863 { "pcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4864 { "pcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4865 { "pcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4983 { "sha1rnds4", { XM
, EXxmm
, Ib
}, PREFIX_OPCODE
},
4985 { "gf2p8affineqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
4986 { "gf2p8affineinvqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
5004 { "aeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5024 { PREFIX_TABLE (PREFIX_0F3A0F
) },
5044 static const struct dis386 xop_table
[][256] = {
5197 { VEX_LEN_TABLE (VEX_LEN_XOP_08_85
) },
5198 { VEX_LEN_TABLE (VEX_LEN_XOP_08_86
) },
5199 { VEX_LEN_TABLE (VEX_LEN_XOP_08_87
) },
5207 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8E
) },
5208 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8F
) },
5215 { VEX_LEN_TABLE (VEX_LEN_XOP_08_95
) },
5216 { VEX_LEN_TABLE (VEX_LEN_XOP_08_96
) },
5217 { VEX_LEN_TABLE (VEX_LEN_XOP_08_97
) },
5225 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9E
) },
5226 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9F
) },
5230 { "vpcmov", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
5231 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A3
) },
5234 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A6
) },
5252 { VEX_LEN_TABLE (VEX_LEN_XOP_08_B6
) },
5264 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C0
) },
5265 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C1
) },
5266 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C2
) },
5267 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C3
) },
5277 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CC
) },
5278 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CD
) },
5279 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CE
) },
5280 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CF
) },
5313 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EC
) },
5314 { VEX_LEN_TABLE (VEX_LEN_XOP_08_ED
) },
5315 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EE
) },
5316 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EF
) },
5340 { VEX_LEN_TABLE (VEX_LEN_XOP_09_01
) },
5341 { VEX_LEN_TABLE (VEX_LEN_XOP_09_02
) },
5359 { VEX_LEN_TABLE (VEX_LEN_XOP_09_12
) },
5483 { VEX_W_TABLE (VEX_W_XOP_09_80
) },
5484 { VEX_W_TABLE (VEX_W_XOP_09_81
) },
5485 { VEX_W_TABLE (VEX_W_XOP_09_82
) },
5486 { VEX_W_TABLE (VEX_W_XOP_09_83
) },
5501 { VEX_LEN_TABLE (VEX_LEN_XOP_09_90
) },
5502 { VEX_LEN_TABLE (VEX_LEN_XOP_09_91
) },
5503 { VEX_LEN_TABLE (VEX_LEN_XOP_09_92
) },
5504 { VEX_LEN_TABLE (VEX_LEN_XOP_09_93
) },
5505 { VEX_LEN_TABLE (VEX_LEN_XOP_09_94
) },
5506 { VEX_LEN_TABLE (VEX_LEN_XOP_09_95
) },
5507 { VEX_LEN_TABLE (VEX_LEN_XOP_09_96
) },
5508 { VEX_LEN_TABLE (VEX_LEN_XOP_09_97
) },
5510 { VEX_LEN_TABLE (VEX_LEN_XOP_09_98
) },
5511 { VEX_LEN_TABLE (VEX_LEN_XOP_09_99
) },
5512 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9A
) },
5513 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9B
) },
5556 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C1
) },
5557 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C2
) },
5558 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C3
) },
5561 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C6
) },
5562 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C7
) },
5567 { VEX_LEN_TABLE (VEX_LEN_XOP_09_CB
) },
5574 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D1
) },
5575 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D2
) },
5576 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D3
) },
5579 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D6
) },
5580 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D7
) },
5585 { VEX_LEN_TABLE (VEX_LEN_XOP_09_DB
) },
5592 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E1
) },
5593 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E2
) },
5594 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E3
) },
5648 { "bextrS", { Gdq
, Edq
, Id
}, 0 },
5650 { VEX_LEN_TABLE (VEX_LEN_XOP_0A_12
) },
5920 static const struct dis386 vex_table
[][256] = {
5942 { PREFIX_TABLE (PREFIX_0F10
) },
5943 { PREFIX_TABLE (PREFIX_0F11
) },
5944 { PREFIX_TABLE (PREFIX_VEX_0F12
) },
5945 { VEX_LEN_TABLE (VEX_LEN_0F13
) },
5946 { "vunpcklpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
5947 { "vunpckhpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
5948 { PREFIX_TABLE (PREFIX_VEX_0F16
) },
5949 { VEX_LEN_TABLE (VEX_LEN_0F17
) },
5969 { "vmovapX", { XM
, EXx
}, PREFIX_OPCODE
},
5970 { "vmovapX", { EXxS
, XM
}, PREFIX_OPCODE
},
5971 { PREFIX_TABLE (PREFIX_VEX_0F2A
) },
5972 { "vmovntpX", { Mx
, XM
}, PREFIX_OPCODE
},
5973 { PREFIX_TABLE (PREFIX_VEX_0F2C
) },
5974 { PREFIX_TABLE (PREFIX_VEX_0F2D
) },
5975 { PREFIX_TABLE (PREFIX_0F2E
) },
5976 { PREFIX_TABLE (PREFIX_0F2F
) },
5997 { VEX_LEN_TABLE (VEX_LEN_0F41
) },
5998 { VEX_LEN_TABLE (VEX_LEN_0F42
) },
6000 { VEX_LEN_TABLE (VEX_LEN_0F44
) },
6001 { VEX_LEN_TABLE (VEX_LEN_0F45
) },
6002 { VEX_LEN_TABLE (VEX_LEN_0F46
) },
6003 { VEX_LEN_TABLE (VEX_LEN_0F47
) },
6007 { VEX_LEN_TABLE (VEX_LEN_0F4A
) },
6008 { VEX_LEN_TABLE (VEX_LEN_0F4B
) },
6014 { "vmovmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
6015 { PREFIX_TABLE (PREFIX_0F51
) },
6016 { PREFIX_TABLE (PREFIX_0F52
) },
6017 { PREFIX_TABLE (PREFIX_0F53
) },
6018 { "vandpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6019 { "vandnpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6020 { "vorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6021 { "vxorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6023 { PREFIX_TABLE (PREFIX_0F58
) },
6024 { PREFIX_TABLE (PREFIX_0F59
) },
6025 { PREFIX_TABLE (PREFIX_0F5A
) },
6026 { PREFIX_TABLE (PREFIX_0F5B
) },
6027 { PREFIX_TABLE (PREFIX_0F5C
) },
6028 { PREFIX_TABLE (PREFIX_0F5D
) },
6029 { PREFIX_TABLE (PREFIX_0F5E
) },
6030 { PREFIX_TABLE (PREFIX_0F5F
) },
6032 { "vpunpcklbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6033 { "vpunpcklwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6034 { "vpunpckldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6035 { "vpacksswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6036 { "vpcmpgtb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6037 { "vpcmpgtw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6038 { "vpcmpgtd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6039 { "vpackuswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6041 { "vpunpckhbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6042 { "vpunpckhwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6043 { "vpunpckhdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6044 { "vpackssdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6045 { "vpunpcklqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6046 { "vpunpckhqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6047 { VEX_LEN_TABLE (VEX_LEN_0F6E
) },
6048 { PREFIX_TABLE (PREFIX_VEX_0F6F
) },
6050 { PREFIX_TABLE (PREFIX_VEX_0F70
) },
6051 { REG_TABLE (REG_VEX_0F71
) },
6052 { REG_TABLE (REG_VEX_0F72
) },
6053 { REG_TABLE (REG_VEX_0F73
) },
6054 { "vpcmpeqb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6055 { "vpcmpeqw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6056 { "vpcmpeqd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6057 { VEX_LEN_TABLE (VEX_LEN_0F77
) },
6063 { PREFIX_TABLE (PREFIX_0F7C
) },
6064 { PREFIX_TABLE (PREFIX_0F7D
) },
6065 { PREFIX_TABLE (PREFIX_VEX_0F7E
) },
6066 { PREFIX_TABLE (PREFIX_VEX_0F7F
) },
6086 { VEX_LEN_TABLE (VEX_LEN_0F90
) },
6087 { VEX_LEN_TABLE (VEX_LEN_0F91
) },
6088 { VEX_LEN_TABLE (VEX_LEN_0F92
) },
6089 { VEX_LEN_TABLE (VEX_LEN_0F93
) },
6095 { VEX_LEN_TABLE (VEX_LEN_0F98
) },
6096 { VEX_LEN_TABLE (VEX_LEN_0F99
) },
6119 { REG_TABLE (REG_VEX_0FAE
) },
6142 { PREFIX_TABLE (PREFIX_0FC2
) },
6144 { VEX_LEN_TABLE (VEX_LEN_0FC4
) },
6145 { "vpextrw", { Gd
, Uxmm
, Ib
}, PREFIX_DATA
},
6146 { "vshufpX", { XM
, Vex
, EXx
, Ib
}, PREFIX_OPCODE
},
6158 { PREFIX_TABLE (PREFIX_0FD0
) },
6159 { "vpsrlw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6160 { "vpsrld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6161 { "vpsrlq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6162 { "vpaddq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6163 { "vpmullw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6164 { VEX_LEN_TABLE (VEX_LEN_0FD6
) },
6165 { "vpmovmskb", { Gdq
, Ux
}, PREFIX_DATA
},
6167 { "vpsubusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6168 { "vpsubusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6169 { "vpminub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6170 { "vpand", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6171 { "vpaddusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6172 { "vpaddusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6173 { "vpmaxub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6174 { "vpandn", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6176 { "vpavgb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6177 { "vpsraw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6178 { "vpsrad", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6179 { "vpavgw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6180 { "vpmulhuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6181 { "vpmulhw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6182 { PREFIX_TABLE (PREFIX_0FE6
) },
6183 { "vmovntdq", { Mx
, XM
}, PREFIX_DATA
},
6185 { "vpsubsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6186 { "vpsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6187 { "vpminsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6188 { "vpor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6189 { "vpaddsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6190 { "vpaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6191 { "vpmaxsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6192 { "vpxor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6194 { PREFIX_TABLE (PREFIX_0FF0
) },
6195 { "vpsllw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6196 { "vpslld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6197 { "vpsllq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6198 { "vpmuludq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6199 { "vpmaddwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6200 { "vpsadbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6201 { "vmaskmovdqu", { XM
, Uxmm
}, PREFIX_DATA
},
6203 { "vpsubb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6204 { "vpsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6205 { "vpsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6206 { "vpsubq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6207 { "vpaddb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6208 { "vpaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6209 { "vpaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6215 { "vpshufb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6216 { "vphaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6217 { "vphaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6218 { "vphaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6219 { "vpmaddubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6220 { "vphsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6221 { "vphsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6222 { "vphsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6224 { "vpsignb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6225 { "vpsignw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6226 { "vpsignd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6227 { "vpmulhrsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6228 { VEX_W_TABLE (VEX_W_0F380C
) },
6229 { VEX_W_TABLE (VEX_W_0F380D
) },
6230 { VEX_W_TABLE (VEX_W_0F380E
) },
6231 { VEX_W_TABLE (VEX_W_0F380F
) },
6236 { VEX_W_TABLE (VEX_W_0F3813
) },
6239 { VEX_LEN_TABLE (VEX_LEN_0F3816
) },
6240 { "vptest", { XM
, EXx
}, PREFIX_DATA
},
6242 { VEX_W_TABLE (VEX_W_0F3818
) },
6243 { VEX_LEN_TABLE (VEX_LEN_0F3819
) },
6244 { VEX_LEN_TABLE (VEX_LEN_0F381A
) },
6246 { "vpabsb", { XM
, EXx
}, PREFIX_DATA
},
6247 { "vpabsw", { XM
, EXx
}, PREFIX_DATA
},
6248 { "vpabsd", { XM
, EXx
}, PREFIX_DATA
},
6251 { "vpmovsxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6252 { "vpmovsxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6253 { "vpmovsxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6254 { "vpmovsxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6255 { "vpmovsxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6256 { "vpmovsxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6260 { "vpmuldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6261 { "vpcmpeqq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6262 { "vmovntdqa", { XM
, Mx
}, PREFIX_DATA
},
6263 { "vpackusdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6264 { VEX_W_TABLE (VEX_W_0F382C
) },
6265 { VEX_W_TABLE (VEX_W_0F382D
) },
6266 { VEX_W_TABLE (VEX_W_0F382E
) },
6267 { VEX_W_TABLE (VEX_W_0F382F
) },
6269 { "vpmovzxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6270 { "vpmovzxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6271 { "vpmovzxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6272 { "vpmovzxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6273 { "vpmovzxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6274 { "vpmovzxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6275 { VEX_LEN_TABLE (VEX_LEN_0F3836
) },
6276 { "vpcmpgtq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6278 { "vpminsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6279 { "vpminsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6280 { "vpminuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6281 { "vpminud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6282 { "vpmaxsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6283 { "vpmaxsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6284 { "vpmaxuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6285 { "vpmaxud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6287 { "vpmulld", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6288 { VEX_LEN_TABLE (VEX_LEN_0F3841
) },
6292 { "vpsrlv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6293 { VEX_W_TABLE (VEX_W_0F3846
) },
6294 { "vpsllv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6297 { X86_64_TABLE (X86_64_VEX_0F3849
) },
6299 { X86_64_TABLE (X86_64_VEX_0F384B
) },
6305 { VEX_W_TABLE (VEX_W_0F3850
) },
6306 { VEX_W_TABLE (VEX_W_0F3851
) },
6307 { VEX_W_TABLE (VEX_W_0F3852
) },
6308 { VEX_W_TABLE (VEX_W_0F3853
) },
6314 { VEX_W_TABLE (VEX_W_0F3858
) },
6315 { VEX_W_TABLE (VEX_W_0F3859
) },
6316 { VEX_LEN_TABLE (VEX_LEN_0F385A
) },
6318 { X86_64_TABLE (X86_64_VEX_0F385C
) },
6320 { X86_64_TABLE (X86_64_VEX_0F385E
) },
6336 { X86_64_TABLE (X86_64_VEX_0F386C
) },
6343 { PREFIX_TABLE (PREFIX_VEX_0F3872
) },
6350 { VEX_W_TABLE (VEX_W_0F3878
) },
6351 { VEX_W_TABLE (VEX_W_0F3879
) },
6372 { "vpmaskmov%DQ", { XM
, Vex
, Mx
}, PREFIX_DATA
},
6374 { "vpmaskmov%DQ", { Mx
, Vex
, XM
}, PREFIX_DATA
},
6377 { "vpgatherd%DQ", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6378 { "vpgatherq%DQ", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6379 { "vgatherdp%XW", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6380 { "vgatherqp%XW", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6383 { "vfmaddsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6384 { "vfmsubadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6386 { "vfmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6387 { "vfmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6388 { "vfmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6389 { "vfmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6390 { "vfnmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6391 { "vfnmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6392 { "vfnmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6393 { "vfnmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6401 { "vfmaddsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6402 { "vfmsubadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6404 { "vfmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6405 { "vfmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6406 { "vfmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6407 { "vfmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6408 { "vfnmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6409 { "vfnmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6410 { "vfnmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6411 { "vfnmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6413 { VEX_W_TABLE (VEX_W_0F38B0
) },
6414 { VEX_W_TABLE (VEX_W_0F38B1
) },
6417 { VEX_W_TABLE (VEX_W_0F38B4
) },
6418 { VEX_W_TABLE (VEX_W_0F38B5
) },
6419 { "vfmaddsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6420 { "vfmsubadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6422 { "vfmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6423 { "vfmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6424 { "vfmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6425 { "vfmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6426 { "vfnmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6427 { "vfnmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6428 { "vfnmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6429 { "vfnmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6443 { PREFIX_TABLE (PREFIX_VEX_0F38CB
) },
6444 { PREFIX_TABLE (PREFIX_VEX_0F38CC
) },
6445 { PREFIX_TABLE (PREFIX_VEX_0F38CD
) },
6447 { VEX_W_TABLE (VEX_W_0F38CF
) },
6451 { VEX_W_TABLE (VEX_W_0F38D2
) },
6452 { VEX_W_TABLE (VEX_W_0F38D3
) },
6460 { VEX_W_TABLE (VEX_W_0F38DA
) },
6461 { VEX_LEN_TABLE (VEX_LEN_0F38DB
) },
6462 { "vaesenc", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6463 { "vaesenclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6464 { "vaesdec", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6465 { "vaesdeclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6467 { X86_64_TABLE (X86_64_VEX_0F38E0
) },
6468 { X86_64_TABLE (X86_64_VEX_0F38E1
) },
6469 { X86_64_TABLE (X86_64_VEX_0F38E2
) },
6470 { X86_64_TABLE (X86_64_VEX_0F38E3
) },
6471 { X86_64_TABLE (X86_64_VEX_0F38E4
) },
6472 { X86_64_TABLE (X86_64_VEX_0F38E5
) },
6473 { X86_64_TABLE (X86_64_VEX_0F38E6
) },
6474 { X86_64_TABLE (X86_64_VEX_0F38E7
) },
6476 { X86_64_TABLE (X86_64_VEX_0F38E8
) },
6477 { X86_64_TABLE (X86_64_VEX_0F38E9
) },
6478 { X86_64_TABLE (X86_64_VEX_0F38EA
) },
6479 { X86_64_TABLE (X86_64_VEX_0F38EB
) },
6480 { X86_64_TABLE (X86_64_VEX_0F38EC
) },
6481 { X86_64_TABLE (X86_64_VEX_0F38ED
) },
6482 { X86_64_TABLE (X86_64_VEX_0F38EE
) },
6483 { X86_64_TABLE (X86_64_VEX_0F38EF
) },
6487 { VEX_LEN_TABLE (VEX_LEN_0F38F2
) },
6488 { VEX_LEN_TABLE (VEX_LEN_0F38F3
) },
6490 { VEX_LEN_TABLE (VEX_LEN_0F38F5
) },
6491 { VEX_LEN_TABLE (VEX_LEN_0F38F6
) },
6492 { VEX_LEN_TABLE (VEX_LEN_0F38F7
) },
6506 { VEX_LEN_TABLE (VEX_LEN_0F3A00
) },
6507 { VEX_LEN_TABLE (VEX_LEN_0F3A01
) },
6508 { VEX_W_TABLE (VEX_W_0F3A02
) },
6510 { VEX_W_TABLE (VEX_W_0F3A04
) },
6511 { VEX_W_TABLE (VEX_W_0F3A05
) },
6512 { VEX_LEN_TABLE (VEX_LEN_0F3A06
) },
6515 { "vroundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6516 { "vroundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6517 { "vroundss", { XMScalar
, VexScalar
, EXd
, Ib
}, PREFIX_DATA
},
6518 { "vroundsd", { XMScalar
, VexScalar
, EXq
, Ib
}, PREFIX_DATA
},
6519 { "vblendps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6520 { "vblendpd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6521 { "vpblendw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6522 { "vpalignr", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6528 { VEX_LEN_TABLE (VEX_LEN_0F3A14
) },
6529 { VEX_LEN_TABLE (VEX_LEN_0F3A15
) },
6530 { VEX_LEN_TABLE (VEX_LEN_0F3A16
) },
6531 { VEX_LEN_TABLE (VEX_LEN_0F3A17
) },
6533 { VEX_LEN_TABLE (VEX_LEN_0F3A18
) },
6534 { VEX_LEN_TABLE (VEX_LEN_0F3A19
) },
6538 { VEX_W_TABLE (VEX_W_0F3A1D
) },
6542 { VEX_LEN_TABLE (VEX_LEN_0F3A20
) },
6543 { VEX_LEN_TABLE (VEX_LEN_0F3A21
) },
6544 { VEX_LEN_TABLE (VEX_LEN_0F3A22
) },
6560 { VEX_LEN_TABLE (VEX_LEN_0F3A30
) },
6561 { VEX_LEN_TABLE (VEX_LEN_0F3A31
) },
6562 { VEX_LEN_TABLE (VEX_LEN_0F3A32
) },
6563 { VEX_LEN_TABLE (VEX_LEN_0F3A33
) },
6569 { VEX_LEN_TABLE (VEX_LEN_0F3A38
) },
6570 { VEX_LEN_TABLE (VEX_LEN_0F3A39
) },
6578 { "vdpps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6579 { VEX_LEN_TABLE (VEX_LEN_0F3A41
) },
6580 { "vmpsadbw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6582 { "vpclmulqdq", { XM
, Vex
, EXx
, PCLMUL
}, PREFIX_DATA
},
6584 { VEX_LEN_TABLE (VEX_LEN_0F3A46
) },
6587 { "vpermil2ps", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6588 { "vpermil2pd", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6589 { VEX_W_TABLE (VEX_W_0F3A4A
) },
6590 { VEX_W_TABLE (VEX_W_0F3A4B
) },
6591 { VEX_W_TABLE (VEX_W_0F3A4C
) },
6609 { "vfmaddsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6610 { "vfmaddsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6611 { "vfmsubaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6612 { "vfmsubaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6614 { VEX_LEN_TABLE (VEX_LEN_0F3A60
) },
6615 { VEX_LEN_TABLE (VEX_LEN_0F3A61
) },
6616 { VEX_LEN_TABLE (VEX_LEN_0F3A62
) },
6617 { VEX_LEN_TABLE (VEX_LEN_0F3A63
) },
6623 { "vfmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6624 { "vfmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6625 { "vfmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6626 { "vfmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6627 { "vfmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6628 { "vfmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6629 { "vfmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6630 { "vfmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6641 { "vfnmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6642 { "vfnmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6643 { "vfnmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6644 { "vfnmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6645 { "vfnmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6646 { "vfnmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6647 { "vfnmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6648 { "vfnmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6737 { VEX_W_TABLE (VEX_W_0F3ACE
) },
6738 { VEX_W_TABLE (VEX_W_0F3ACF
) },
6755 { VEX_W_TABLE (VEX_W_0F3ADE
) },
6756 { VEX_LEN_TABLE (VEX_LEN_0F3ADF
) },
6776 { VEX_LEN_TABLE (VEX_LEN_0F3AF0
) },
6796 #include "i386-dis-evex.h"
6798 static const struct dis386 vex_len_table
[][2] = {
6799 /* VEX_LEN_0F12_P_0 */
6801 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
6804 /* VEX_LEN_0F12_P_2 */
6806 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
6811 { "%XEVmovlpYX", { Mq
, XM
}, PREFIX_OPCODE
},
6814 /* VEX_LEN_0F16_P_0 */
6816 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
6819 /* VEX_LEN_0F16_P_2 */
6821 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
6826 { "%XEVmovhpYX", { Mq
, XM
}, PREFIX_OPCODE
},
6832 { VEX_W_TABLE (VEX_W_0F41_L_1
) },
6838 { VEX_W_TABLE (VEX_W_0F42_L_1
) },
6843 { VEX_W_TABLE (VEX_W_0F44_L_0
) },
6849 { VEX_W_TABLE (VEX_W_0F45_L_1
) },
6855 { VEX_W_TABLE (VEX_W_0F46_L_1
) },
6861 { VEX_W_TABLE (VEX_W_0F47_L_1
) },
6867 { VEX_W_TABLE (VEX_W_0F4A_L_1
) },
6873 { VEX_W_TABLE (VEX_W_0F4B_L_1
) },
6878 { "%XEvmovYK", { XMScalar
, Edq
}, PREFIX_DATA
},
6883 { "vzeroupper", { XX
}, 0 },
6884 { "vzeroall", { XX
}, 0 },
6887 /* VEX_LEN_0F7E_P_1 */
6889 { "%XEvmovqY", { XMScalar
, EXq
}, 0 },
6892 /* VEX_LEN_0F7E_P_2 */
6894 { "%XEvmovK", { Edq
, XMScalar
}, 0 },
6899 { VEX_W_TABLE (VEX_W_0F90_L_0
) },
6904 { VEX_W_TABLE (VEX_W_0F91_L_0
) },
6909 { VEX_W_TABLE (VEX_W_0F92_L_0
) },
6914 { VEX_W_TABLE (VEX_W_0F93_L_0
) },
6919 { VEX_W_TABLE (VEX_W_0F98_L_0
) },
6924 { VEX_W_TABLE (VEX_W_0F99_L_0
) },
6927 /* VEX_LEN_0FAE_R_2 */
6929 { "vldmxcsr", { Md
}, 0 },
6932 /* VEX_LEN_0FAE_R_3 */
6934 { "vstmxcsr", { Md
}, 0 },
6939 { "%XEvpinsrwY", { XM
, Vex
, Edw
, Ib
}, PREFIX_DATA
},
6944 { "%XEvmovqY", { EXqS
, XMScalar
}, PREFIX_DATA
},
6947 /* VEX_LEN_0F3816 */
6950 { VEX_W_TABLE (VEX_W_0F3816_L_1
) },
6953 /* VEX_LEN_0F3819 */
6956 { VEX_W_TABLE (VEX_W_0F3819_L_1
) },
6959 /* VEX_LEN_0F381A */
6962 { VEX_W_TABLE (VEX_W_0F381A_L_1
) },
6965 /* VEX_LEN_0F3836 */
6968 { VEX_W_TABLE (VEX_W_0F3836
) },
6971 /* VEX_LEN_0F3841 */
6973 { "vphminposuw", { XM
, EXx
}, PREFIX_DATA
},
6976 /* VEX_LEN_0F3849_X86_64 */
6978 { VEX_W_TABLE (VEX_W_0F3849_X86_64_L_0
) },
6981 /* VEX_LEN_0F384B_X86_64 */
6983 { VEX_W_TABLE (VEX_W_0F384B_X86_64_L_0
) },
6986 /* VEX_LEN_0F385A */
6989 { VEX_W_TABLE (VEX_W_0F385A_L_0
) },
6992 /* VEX_LEN_0F385C_X86_64 */
6994 { VEX_W_TABLE (VEX_W_0F385C_X86_64_L_0
) },
6997 /* VEX_LEN_0F385E_X86_64 */
6999 { VEX_W_TABLE (VEX_W_0F385E_X86_64_L_0
) },
7002 /* VEX_LEN_0F386C_X86_64 */
7004 { VEX_W_TABLE (VEX_W_0F386C_X86_64_L_0
) },
7007 /* VEX_LEN_0F38CB_P_3_W_0 */
7010 { "vsha512rnds2", { XM
, Vex
, Rxmmq
}, 0 },
7013 /* VEX_LEN_0F38CC_P_3_W_0 */
7016 { "vsha512msg1", { XM
, Rxmmq
}, 0 },
7019 /* VEX_LEN_0F38CD_P_3_W_0 */
7022 { "vsha512msg2", { XM
, Rymm
}, 0 },
7025 /* VEX_LEN_0F38DA_W_0_P_0 */
7027 { "vsm3msg1", { XM
, Vex
, EXxmm
}, 0 },
7030 /* VEX_LEN_0F38DA_W_0_P_2 */
7032 { "vsm3msg2", { XM
, Vex
, EXxmm
}, 0 },
7035 /* VEX_LEN_0F38DB */
7037 { "vaesimc", { XM
, EXx
}, PREFIX_DATA
},
7040 /* VEX_LEN_0F38F2 */
7042 { "andnS", { Gdq
, VexGdq
, Edq
}, PREFIX_OPCODE
},
7045 /* VEX_LEN_0F38F3 */
7047 { REG_TABLE(REG_VEX_0F38F3_L_0
) },
7050 /* VEX_LEN_0F38F5 */
7052 { PREFIX_TABLE(PREFIX_VEX_0F38F5_L_0
) },
7055 /* VEX_LEN_0F38F6 */
7057 { PREFIX_TABLE(PREFIX_VEX_0F38F6_L_0
) },
7060 /* VEX_LEN_0F38F7 */
7062 { PREFIX_TABLE(PREFIX_VEX_0F38F7_L_0
) },
7065 /* VEX_LEN_0F3A00 */
7068 { VEX_W_TABLE (VEX_W_0F3A00_L_1
) },
7071 /* VEX_LEN_0F3A01 */
7074 { VEX_W_TABLE (VEX_W_0F3A01_L_1
) },
7077 /* VEX_LEN_0F3A06 */
7080 { VEX_W_TABLE (VEX_W_0F3A06_L_1
) },
7083 /* VEX_LEN_0F3A14 */
7085 { "%XEvpextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
7088 /* VEX_LEN_0F3A15 */
7090 { "%XEvpextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
7093 /* VEX_LEN_0F3A16 */
7095 { "%XEvpextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
7098 /* VEX_LEN_0F3A17 */
7100 { "%XEvextractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
7103 /* VEX_LEN_0F3A18 */
7106 { VEX_W_TABLE (VEX_W_0F3A18_L_1
) },
7109 /* VEX_LEN_0F3A19 */
7112 { VEX_W_TABLE (VEX_W_0F3A19_L_1
) },
7115 /* VEX_LEN_0F3A20 */
7117 { "%XEvpinsrbY", { XM
, Vex
, Edb
, Ib
}, PREFIX_DATA
},
7120 /* VEX_LEN_0F3A21 */
7122 { "%XEvinsertpsY", { XM
, Vex
, EXd
, Ib
}, PREFIX_DATA
},
7125 /* VEX_LEN_0F3A22 */
7127 { "%XEvpinsrYK", { XM
, Vex
, Edq
, Ib
}, PREFIX_DATA
},
7130 /* VEX_LEN_0F3A30 */
7132 { "kshiftr%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7135 /* VEX_LEN_0F3A31 */
7137 { "kshiftr%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7140 /* VEX_LEN_0F3A32 */
7142 { "kshiftl%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7145 /* VEX_LEN_0F3A33 */
7147 { "kshiftl%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7150 /* VEX_LEN_0F3A38 */
7153 { VEX_W_TABLE (VEX_W_0F3A38_L_1
) },
7156 /* VEX_LEN_0F3A39 */
7159 { VEX_W_TABLE (VEX_W_0F3A39_L_1
) },
7162 /* VEX_LEN_0F3A41 */
7164 { "vdppd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7167 /* VEX_LEN_0F3A46 */
7170 { VEX_W_TABLE (VEX_W_0F3A46_L_1
) },
7173 /* VEX_LEN_0F3A60 */
7175 { "vpcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7178 /* VEX_LEN_0F3A61 */
7180 { "vpcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7183 /* VEX_LEN_0F3A62 */
7185 { "vpcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7188 /* VEX_LEN_0F3A63 */
7190 { "vpcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7193 /* VEX_LEN_0F3ADE_W_0 */
7195 { "vsm3rnds2", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7198 /* VEX_LEN_0F3ADF */
7200 { "vaeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7203 /* VEX_LEN_0F3AF0 */
7205 { PREFIX_TABLE (PREFIX_VEX_0F3AF0_L_0
) },
7208 /* VEX_LEN_XOP_08_85 */
7210 { VEX_W_TABLE (VEX_W_XOP_08_85_L_0
) },
7213 /* VEX_LEN_XOP_08_86 */
7215 { VEX_W_TABLE (VEX_W_XOP_08_86_L_0
) },
7218 /* VEX_LEN_XOP_08_87 */
7220 { VEX_W_TABLE (VEX_W_XOP_08_87_L_0
) },
7223 /* VEX_LEN_XOP_08_8E */
7225 { VEX_W_TABLE (VEX_W_XOP_08_8E_L_0
) },
7228 /* VEX_LEN_XOP_08_8F */
7230 { VEX_W_TABLE (VEX_W_XOP_08_8F_L_0
) },
7233 /* VEX_LEN_XOP_08_95 */
7235 { VEX_W_TABLE (VEX_W_XOP_08_95_L_0
) },
7238 /* VEX_LEN_XOP_08_96 */
7240 { VEX_W_TABLE (VEX_W_XOP_08_96_L_0
) },
7243 /* VEX_LEN_XOP_08_97 */
7245 { VEX_W_TABLE (VEX_W_XOP_08_97_L_0
) },
7248 /* VEX_LEN_XOP_08_9E */
7250 { VEX_W_TABLE (VEX_W_XOP_08_9E_L_0
) },
7253 /* VEX_LEN_XOP_08_9F */
7255 { VEX_W_TABLE (VEX_W_XOP_08_9F_L_0
) },
7258 /* VEX_LEN_XOP_08_A3 */
7260 { "vpperm", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7263 /* VEX_LEN_XOP_08_A6 */
7265 { VEX_W_TABLE (VEX_W_XOP_08_A6_L_0
) },
7268 /* VEX_LEN_XOP_08_B6 */
7270 { VEX_W_TABLE (VEX_W_XOP_08_B6_L_0
) },
7273 /* VEX_LEN_XOP_08_C0 */
7275 { VEX_W_TABLE (VEX_W_XOP_08_C0_L_0
) },
7278 /* VEX_LEN_XOP_08_C1 */
7280 { VEX_W_TABLE (VEX_W_XOP_08_C1_L_0
) },
7283 /* VEX_LEN_XOP_08_C2 */
7285 { VEX_W_TABLE (VEX_W_XOP_08_C2_L_0
) },
7288 /* VEX_LEN_XOP_08_C3 */
7290 { VEX_W_TABLE (VEX_W_XOP_08_C3_L_0
) },
7293 /* VEX_LEN_XOP_08_CC */
7295 { VEX_W_TABLE (VEX_W_XOP_08_CC_L_0
) },
7298 /* VEX_LEN_XOP_08_CD */
7300 { VEX_W_TABLE (VEX_W_XOP_08_CD_L_0
) },
7303 /* VEX_LEN_XOP_08_CE */
7305 { VEX_W_TABLE (VEX_W_XOP_08_CE_L_0
) },
7308 /* VEX_LEN_XOP_08_CF */
7310 { VEX_W_TABLE (VEX_W_XOP_08_CF_L_0
) },
7313 /* VEX_LEN_XOP_08_EC */
7315 { VEX_W_TABLE (VEX_W_XOP_08_EC_L_0
) },
7318 /* VEX_LEN_XOP_08_ED */
7320 { VEX_W_TABLE (VEX_W_XOP_08_ED_L_0
) },
7323 /* VEX_LEN_XOP_08_EE */
7325 { VEX_W_TABLE (VEX_W_XOP_08_EE_L_0
) },
7328 /* VEX_LEN_XOP_08_EF */
7330 { VEX_W_TABLE (VEX_W_XOP_08_EF_L_0
) },
7333 /* VEX_LEN_XOP_09_01 */
7335 { REG_TABLE (REG_XOP_09_01_L_0
) },
7338 /* VEX_LEN_XOP_09_02 */
7340 { REG_TABLE (REG_XOP_09_02_L_0
) },
7343 /* VEX_LEN_XOP_09_12 */
7345 { REG_TABLE (REG_XOP_09_12_L_0
) },
7348 /* VEX_LEN_XOP_09_82_W_0 */
7350 { "vfrczss", { XM
, EXd
}, 0 },
7353 /* VEX_LEN_XOP_09_83_W_0 */
7355 { "vfrczsd", { XM
, EXq
}, 0 },
7358 /* VEX_LEN_XOP_09_90 */
7360 { "vprotb", { XM
, EXx
, VexW
}, 0 },
7363 /* VEX_LEN_XOP_09_91 */
7365 { "vprotw", { XM
, EXx
, VexW
}, 0 },
7368 /* VEX_LEN_XOP_09_92 */
7370 { "vprotd", { XM
, EXx
, VexW
}, 0 },
7373 /* VEX_LEN_XOP_09_93 */
7375 { "vprotq", { XM
, EXx
, VexW
}, 0 },
7378 /* VEX_LEN_XOP_09_94 */
7380 { "vpshlb", { XM
, EXx
, VexW
}, 0 },
7383 /* VEX_LEN_XOP_09_95 */
7385 { "vpshlw", { XM
, EXx
, VexW
}, 0 },
7388 /* VEX_LEN_XOP_09_96 */
7390 { "vpshld", { XM
, EXx
, VexW
}, 0 },
7393 /* VEX_LEN_XOP_09_97 */
7395 { "vpshlq", { XM
, EXx
, VexW
}, 0 },
7398 /* VEX_LEN_XOP_09_98 */
7400 { "vpshab", { XM
, EXx
, VexW
}, 0 },
7403 /* VEX_LEN_XOP_09_99 */
7405 { "vpshaw", { XM
, EXx
, VexW
}, 0 },
7408 /* VEX_LEN_XOP_09_9A */
7410 { "vpshad", { XM
, EXx
, VexW
}, 0 },
7413 /* VEX_LEN_XOP_09_9B */
7415 { "vpshaq", { XM
, EXx
, VexW
}, 0 },
7418 /* VEX_LEN_XOP_09_C1 */
7420 { VEX_W_TABLE (VEX_W_XOP_09_C1_L_0
) },
7423 /* VEX_LEN_XOP_09_C2 */
7425 { VEX_W_TABLE (VEX_W_XOP_09_C2_L_0
) },
7428 /* VEX_LEN_XOP_09_C3 */
7430 { VEX_W_TABLE (VEX_W_XOP_09_C3_L_0
) },
7433 /* VEX_LEN_XOP_09_C6 */
7435 { VEX_W_TABLE (VEX_W_XOP_09_C6_L_0
) },
7438 /* VEX_LEN_XOP_09_C7 */
7440 { VEX_W_TABLE (VEX_W_XOP_09_C7_L_0
) },
7443 /* VEX_LEN_XOP_09_CB */
7445 { VEX_W_TABLE (VEX_W_XOP_09_CB_L_0
) },
7448 /* VEX_LEN_XOP_09_D1 */
7450 { VEX_W_TABLE (VEX_W_XOP_09_D1_L_0
) },
7453 /* VEX_LEN_XOP_09_D2 */
7455 { VEX_W_TABLE (VEX_W_XOP_09_D2_L_0
) },
7458 /* VEX_LEN_XOP_09_D3 */
7460 { VEX_W_TABLE (VEX_W_XOP_09_D3_L_0
) },
7463 /* VEX_LEN_XOP_09_D6 */
7465 { VEX_W_TABLE (VEX_W_XOP_09_D6_L_0
) },
7468 /* VEX_LEN_XOP_09_D7 */
7470 { VEX_W_TABLE (VEX_W_XOP_09_D7_L_0
) },
7473 /* VEX_LEN_XOP_09_DB */
7475 { VEX_W_TABLE (VEX_W_XOP_09_DB_L_0
) },
7478 /* VEX_LEN_XOP_09_E1 */
7480 { VEX_W_TABLE (VEX_W_XOP_09_E1_L_0
) },
7483 /* VEX_LEN_XOP_09_E2 */
7485 { VEX_W_TABLE (VEX_W_XOP_09_E2_L_0
) },
7488 /* VEX_LEN_XOP_09_E3 */
7490 { VEX_W_TABLE (VEX_W_XOP_09_E3_L_0
) },
7493 /* VEX_LEN_XOP_0A_12 */
7495 { REG_TABLE (REG_XOP_0A_12_L_0
) },
7499 #include "i386-dis-evex-len.h"
7501 static const struct dis386 vex_w_table
[][2] = {
7503 /* VEX_W_0F41_L_1_M_1 */
7504 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_0
) },
7505 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_1
) },
7508 /* VEX_W_0F42_L_1_M_1 */
7509 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_0
) },
7510 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_1
) },
7513 /* VEX_W_0F44_L_0_M_1 */
7514 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_0
) },
7515 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_1
) },
7518 /* VEX_W_0F45_L_1_M_1 */
7519 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_0
) },
7520 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_1
) },
7523 /* VEX_W_0F46_L_1_M_1 */
7524 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_0
) },
7525 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_1
) },
7528 /* VEX_W_0F47_L_1_M_1 */
7529 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_0
) },
7530 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_1
) },
7533 /* VEX_W_0F4A_L_1_M_1 */
7534 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_0
) },
7535 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_1
) },
7538 /* VEX_W_0F4B_L_1_M_1 */
7539 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_0
) },
7540 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_1
) },
7543 /* VEX_W_0F90_L_0 */
7544 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_0
) },
7545 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_1
) },
7548 /* VEX_W_0F91_L_0_M_0 */
7549 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_0
) },
7550 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_1
) },
7553 /* VEX_W_0F92_L_0_M_1 */
7554 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_0
) },
7555 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_1
) },
7558 /* VEX_W_0F93_L_0_M_1 */
7559 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_0
) },
7560 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_1
) },
7563 /* VEX_W_0F98_L_0_M_1 */
7564 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_0
) },
7565 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_1
) },
7568 /* VEX_W_0F99_L_0_M_1 */
7569 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_0
) },
7570 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_1
) },
7574 { "%XEvpermilps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7578 { "vpermilpd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7582 { "vtestps", { XM
, EXx
}, PREFIX_DATA
},
7586 { "vtestpd", { XM
, EXx
}, PREFIX_DATA
},
7590 { "vcvtph2ps", { XM
, EXxmmq
}, PREFIX_DATA
},
7593 /* VEX_W_0F3816_L_1 */
7594 { "vpermps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7598 { "%XEvbroadcastss", { XM
, EXd
}, PREFIX_DATA
},
7601 /* VEX_W_0F3819_L_1 */
7602 { "vbroadcastsd", { XM
, EXq
}, PREFIX_DATA
},
7605 /* VEX_W_0F381A_L_1 */
7606 { "vbroadcastf128", { XM
, Mxmm
}, PREFIX_DATA
},
7610 { "vmaskmovps", { XM
, Vex
, Mx
}, PREFIX_DATA
},
7614 { "vmaskmovpd", { XM
, Vex
, Mx
}, PREFIX_DATA
},
7618 { "vmaskmovps", { Mx
, Vex
, XM
}, PREFIX_DATA
},
7622 { "vmaskmovpd", { Mx
, Vex
, XM
}, PREFIX_DATA
},
7626 { "vpermd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7630 { "vpsravd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7633 /* VEX_W_0F3849_X86_64_L_0 */
7634 { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_0
) },
7637 /* VEX_W_0F384B_X86_64_L_0 */
7638 { PREFIX_TABLE (PREFIX_VEX_0F384B_X86_64_L_0_W_0
) },
7642 { PREFIX_TABLE (PREFIX_VEX_0F3850_W_0
) },
7646 { PREFIX_TABLE (PREFIX_VEX_0F3851_W_0
) },
7650 { "%XVvpdpwssd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7654 { "%XVvpdpwssds", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7658 { "%XEvpbroadcastd", { XM
, EXd
}, PREFIX_DATA
},
7662 { "vpbroadcastq", { XM
, EXq
}, PREFIX_DATA
},
7665 /* VEX_W_0F385A_L_0 */
7666 { "vbroadcasti128", { XM
, Mxmm
}, PREFIX_DATA
},
7669 /* VEX_W_0F385C_X86_64_L_0 */
7670 { PREFIX_TABLE (PREFIX_VEX_0F385C_X86_64_L_0_W_0
) },
7673 /* VEX_W_0F385E_X86_64_L_0 */
7674 { PREFIX_TABLE (PREFIX_VEX_0F385E_X86_64_L_0_W_0
) },
7677 /* VEX_W_0F386C_X86_64_L_0 */
7678 { PREFIX_TABLE (PREFIX_VEX_0F386C_X86_64_L_0_W_0
) },
7681 /* VEX_W_0F3872_P_1 */
7682 { "%XVvcvtneps2bf16%XY", { XMM
, EXx
}, 0 },
7686 { "%XEvpbroadcastb", { XM
, EXb
}, PREFIX_DATA
},
7690 { "%XEvpbroadcastw", { XM
, EXw
}, PREFIX_DATA
},
7694 { PREFIX_TABLE (PREFIX_VEX_0F38B0_W_0
) },
7698 { PREFIX_TABLE (PREFIX_VEX_0F38B1_W_0
) },
7703 { "%XVvpmadd52luq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7708 { "%XVvpmadd52huq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7711 /* VEX_W_0F38CB_P_3 */
7712 { VEX_LEN_TABLE (VEX_LEN_0F38CB_P_3_W_0
) },
7715 /* VEX_W_0F38CC_P_3 */
7716 { VEX_LEN_TABLE (VEX_LEN_0F38CC_P_3_W_0
) },
7719 /* VEX_W_0F38CD_P_3 */
7720 { VEX_LEN_TABLE (VEX_LEN_0F38CD_P_3_W_0
) },
7724 { "%XEvgf2p8mulb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7728 { PREFIX_TABLE (PREFIX_VEX_0F38D2_W_0
) },
7732 { PREFIX_TABLE (PREFIX_VEX_0F38D3_W_0
) },
7736 { PREFIX_TABLE (PREFIX_VEX_0F38DA_W_0
) },
7739 /* VEX_W_0F3A00_L_1 */
7741 { "%XEvpermq", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7744 /* VEX_W_0F3A01_L_1 */
7746 { "%XEvpermpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7750 { "vpblendd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7754 { "%XEvpermilps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7758 { "vpermilpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7761 /* VEX_W_0F3A06_L_1 */
7762 { "vperm2f128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7765 /* VEX_W_0F3A18_L_1 */
7766 { "vinsertf128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7769 /* VEX_W_0F3A19_L_1 */
7770 { "vextractf128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
7774 { "%XEvcvtps2ph", { EXxmmq
, XM
, EXxEVexS
, Ib
}, PREFIX_DATA
},
7777 /* VEX_W_0F3A38_L_1 */
7778 { "vinserti128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7781 /* VEX_W_0F3A39_L_1 */
7782 { "vextracti128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
7785 /* VEX_W_0F3A46_L_1 */
7786 { "vperm2i128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7790 { "vblendvps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7794 { "vblendvpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7798 { "vpblendvb", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7803 { "%XEvgf2p8affineqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7808 { "%XEvgf2p8affineinvqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7812 { VEX_LEN_TABLE (VEX_LEN_0F3ADE_W_0
) },
7814 /* VEX_W_XOP_08_85_L_0 */
7816 { "vpmacssww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7818 /* VEX_W_XOP_08_86_L_0 */
7820 { "vpmacsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7822 /* VEX_W_XOP_08_87_L_0 */
7824 { "vpmacssdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7826 /* VEX_W_XOP_08_8E_L_0 */
7828 { "vpmacssdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7830 /* VEX_W_XOP_08_8F_L_0 */
7832 { "vpmacssdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7834 /* VEX_W_XOP_08_95_L_0 */
7836 { "vpmacsww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7838 /* VEX_W_XOP_08_96_L_0 */
7840 { "vpmacswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7842 /* VEX_W_XOP_08_97_L_0 */
7844 { "vpmacsdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7846 /* VEX_W_XOP_08_9E_L_0 */
7848 { "vpmacsdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7850 /* VEX_W_XOP_08_9F_L_0 */
7852 { "vpmacsdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7854 /* VEX_W_XOP_08_A6_L_0 */
7856 { "vpmadcsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7858 /* VEX_W_XOP_08_B6_L_0 */
7860 { "vpmadcswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7862 /* VEX_W_XOP_08_C0_L_0 */
7864 { "vprotb", { XM
, EXx
, Ib
}, 0 },
7866 /* VEX_W_XOP_08_C1_L_0 */
7868 { "vprotw", { XM
, EXx
, Ib
}, 0 },
7870 /* VEX_W_XOP_08_C2_L_0 */
7872 { "vprotd", { XM
, EXx
, Ib
}, 0 },
7874 /* VEX_W_XOP_08_C3_L_0 */
7876 { "vprotq", { XM
, EXx
, Ib
}, 0 },
7878 /* VEX_W_XOP_08_CC_L_0 */
7880 { "vpcomb", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7882 /* VEX_W_XOP_08_CD_L_0 */
7884 { "vpcomw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7886 /* VEX_W_XOP_08_CE_L_0 */
7888 { "vpcomd", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7890 /* VEX_W_XOP_08_CF_L_0 */
7892 { "vpcomq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7894 /* VEX_W_XOP_08_EC_L_0 */
7896 { "vpcomub", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7898 /* VEX_W_XOP_08_ED_L_0 */
7900 { "vpcomuw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7902 /* VEX_W_XOP_08_EE_L_0 */
7904 { "vpcomud", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7906 /* VEX_W_XOP_08_EF_L_0 */
7908 { "vpcomuq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
7910 /* VEX_W_XOP_09_80 */
7912 { "vfrczps", { XM
, EXx
}, 0 },
7914 /* VEX_W_XOP_09_81 */
7916 { "vfrczpd", { XM
, EXx
}, 0 },
7918 /* VEX_W_XOP_09_82 */
7920 { VEX_LEN_TABLE (VEX_LEN_XOP_09_82_W_0
) },
7922 /* VEX_W_XOP_09_83 */
7924 { VEX_LEN_TABLE (VEX_LEN_XOP_09_83_W_0
) },
7926 /* VEX_W_XOP_09_C1_L_0 */
7928 { "vphaddbw", { XM
, EXxmm
}, 0 },
7930 /* VEX_W_XOP_09_C2_L_0 */
7932 { "vphaddbd", { XM
, EXxmm
}, 0 },
7934 /* VEX_W_XOP_09_C3_L_0 */
7936 { "vphaddbq", { XM
, EXxmm
}, 0 },
7938 /* VEX_W_XOP_09_C6_L_0 */
7940 { "vphaddwd", { XM
, EXxmm
}, 0 },
7942 /* VEX_W_XOP_09_C7_L_0 */
7944 { "vphaddwq", { XM
, EXxmm
}, 0 },
7946 /* VEX_W_XOP_09_CB_L_0 */
7948 { "vphadddq", { XM
, EXxmm
}, 0 },
7950 /* VEX_W_XOP_09_D1_L_0 */
7952 { "vphaddubw", { XM
, EXxmm
}, 0 },
7954 /* VEX_W_XOP_09_D2_L_0 */
7956 { "vphaddubd", { XM
, EXxmm
}, 0 },
7958 /* VEX_W_XOP_09_D3_L_0 */
7960 { "vphaddubq", { XM
, EXxmm
}, 0 },
7962 /* VEX_W_XOP_09_D6_L_0 */
7964 { "vphadduwd", { XM
, EXxmm
}, 0 },
7966 /* VEX_W_XOP_09_D7_L_0 */
7968 { "vphadduwq", { XM
, EXxmm
}, 0 },
7970 /* VEX_W_XOP_09_DB_L_0 */
7972 { "vphaddudq", { XM
, EXxmm
}, 0 },
7974 /* VEX_W_XOP_09_E1_L_0 */
7976 { "vphsubbw", { XM
, EXxmm
}, 0 },
7978 /* VEX_W_XOP_09_E2_L_0 */
7980 { "vphsubwd", { XM
, EXxmm
}, 0 },
7982 /* VEX_W_XOP_09_E3_L_0 */
7984 { "vphsubdq", { XM
, EXxmm
}, 0 },
7987 #include "i386-dis-evex-w.h"
7990 static const struct dis386 mod_table
[][2] = {
7993 { "bound{S|}", { Gv
, Ma
}, 0 },
7998 { "lesS", { Gv
, Mp
}, 0 },
7999 { VEX_C4_TABLE () },
8003 { "ldsS", { Gv
, Mp
}, 0 },
8004 { VEX_C5_TABLE () },
8007 /* MOD_0F01_REG_0 */
8008 { X86_64_TABLE (X86_64_0F01_REG_0
) },
8009 { RM_TABLE (RM_0F01_REG_0
) },
8012 /* MOD_0F01_REG_1 */
8013 { X86_64_TABLE (X86_64_0F01_REG_1
) },
8014 { RM_TABLE (RM_0F01_REG_1
) },
8017 /* MOD_0F01_REG_2 */
8018 { X86_64_TABLE (X86_64_0F01_REG_2
) },
8019 { RM_TABLE (RM_0F01_REG_2
) },
8022 /* MOD_0F01_REG_3 */
8023 { X86_64_TABLE (X86_64_0F01_REG_3
) },
8024 { RM_TABLE (RM_0F01_REG_3
) },
8027 /* MOD_0F01_REG_5 */
8028 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_0
) },
8029 { RM_TABLE (RM_0F01_REG_5_MOD_3
) },
8032 /* MOD_0F01_REG_7 */
8033 { "invlpg", { Mb
}, 0 },
8034 { RM_TABLE (RM_0F01_REG_7_MOD_3
) },
8037 /* MOD_0F12_PREFIX_0 */
8038 { "%XEVmovlpYX", { XM
, Vex
, EXq
}, 0 },
8039 { "%XEVmovhlpY%XS", { XM
, Vex
, EXq
}, 0 },
8042 /* MOD_0F16_PREFIX_0 */
8043 { "%XEVmovhpYX", { XM
, Vex
, EXq
}, 0 },
8044 { "%XEVmovlhpY%XS", { XM
, Vex
, EXq
}, 0 },
8047 /* MOD_0F18_REG_0 */
8048 { "prefetchnta", { Mb
}, 0 },
8049 { "nopQ", { Ev
}, 0 },
8052 /* MOD_0F18_REG_1 */
8053 { "prefetcht0", { Mb
}, 0 },
8054 { "nopQ", { Ev
}, 0 },
8057 /* MOD_0F18_REG_2 */
8058 { "prefetcht1", { Mb
}, 0 },
8059 { "nopQ", { Ev
}, 0 },
8062 /* MOD_0F18_REG_3 */
8063 { "prefetcht2", { Mb
}, 0 },
8064 { "nopQ", { Ev
}, 0 },
8067 /* MOD_0F18_REG_6 */
8068 { X86_64_TABLE (X86_64_0F18_REG_6_MOD_0
) },
8069 { "nopQ", { Ev
}, 0 },
8072 /* MOD_0F18_REG_7 */
8073 { X86_64_TABLE (X86_64_0F18_REG_7_MOD_0
) },
8074 { "nopQ", { Ev
}, 0 },
8077 /* MOD_0F1A_PREFIX_0 */
8078 { "bndldx", { Gbnd
, Mv_bnd
}, 0 },
8079 { "nopQ", { Ev
}, 0 },
8082 /* MOD_0F1B_PREFIX_0 */
8083 { "bndstx", { Mv_bnd
, Gbnd
}, 0 },
8084 { "nopQ", { Ev
}, 0 },
8087 /* MOD_0F1B_PREFIX_1 */
8088 { "bndmk", { Gbnd
, Mv_bnd
}, 0 },
8089 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8092 /* MOD_0F1C_PREFIX_0 */
8093 { REG_TABLE (REG_0F1C_P_0_MOD_0
) },
8094 { "nopQ", { Ev
}, 0 },
8097 /* MOD_0F1E_PREFIX_1 */
8098 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8099 { REG_TABLE (REG_0F1E_P_1_MOD_3
) },
8102 /* MOD_0FAE_REG_0 */
8103 { "fxsave", { FXSAVE
}, 0 },
8104 { PREFIX_TABLE (PREFIX_0FAE_REG_0_MOD_3
) },
8107 /* MOD_0FAE_REG_1 */
8108 { "fxrstor", { FXSAVE
}, 0 },
8109 { PREFIX_TABLE (PREFIX_0FAE_REG_1_MOD_3
) },
8112 /* MOD_0FAE_REG_2 */
8113 { "ldmxcsr", { Md
}, 0 },
8114 { PREFIX_TABLE (PREFIX_0FAE_REG_2_MOD_3
) },
8117 /* MOD_0FAE_REG_3 */
8118 { "stmxcsr", { Md
}, 0 },
8119 { PREFIX_TABLE (PREFIX_0FAE_REG_3_MOD_3
) },
8122 /* MOD_0FAE_REG_4 */
8123 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_0
) },
8124 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_3
) },
8127 /* MOD_0FAE_REG_5 */
8128 { "xrstor", { FXSAVE
}, PREFIX_OPCODE
},
8129 { PREFIX_TABLE (PREFIX_0FAE_REG_5_MOD_3
) },
8132 /* MOD_0FAE_REG_6 */
8133 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_0
) },
8134 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_3
) },
8137 /* MOD_0FAE_REG_7 */
8138 { PREFIX_TABLE (PREFIX_0FAE_REG_7_MOD_0
) },
8139 { RM_TABLE (RM_0FAE_REG_7_MOD_3
) },
8142 /* MOD_0FC7_REG_6 */
8143 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_0
) },
8144 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_3
) }
8147 /* MOD_0FC7_REG_7 */
8148 { "vmptrst", { Mq
}, 0 },
8149 { PREFIX_TABLE (PREFIX_0FC7_REG_7_MOD_3
) }
8152 /* MOD_0F38DC_PREFIX_1 */
8153 { "aesenc128kl", { XM
, M
}, 0 },
8154 { "loadiwkey", { XM
, EXx
}, 0 },
8157 /* MOD_VEX_0F3849_X86_64_L_0_W_0 */
8158 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
) },
8159 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
) },
8162 #include "i386-dis-evex-mod.h"
8165 static const struct dis386 rm_table
[][8] = {
8168 { "xabort", { Skip_MODRM
, Ib
}, 0 },
8172 { "xbeginT", { Skip_MODRM
, Jdqw
}, 0 },
8176 { "enclv", { Skip_MODRM
}, 0 },
8177 { "vmcall", { Skip_MODRM
}, 0 },
8178 { "vmlaunch", { Skip_MODRM
}, 0 },
8179 { "vmresume", { Skip_MODRM
}, 0 },
8180 { "vmxoff", { Skip_MODRM
}, 0 },
8181 { "pconfig", { Skip_MODRM
}, 0 },
8182 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_6
) },
8183 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_7
) },
8187 { "monitor", { { OP_Monitor
, 0 } }, 0 },
8188 { "mwait", { { OP_Mwait
, 0 } }, 0 },
8189 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_2
) },
8190 { "stac", { Skip_MODRM
}, 0 },
8191 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_4
) },
8192 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_5
) },
8193 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_6
) },
8194 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_7
) },
8198 { "xgetbv", { Skip_MODRM
}, 0 },
8199 { "xsetbv", { Skip_MODRM
}, 0 },
8202 { "vmfunc", { Skip_MODRM
}, 0 },
8203 { "xend", { Skip_MODRM
}, 0 },
8204 { "xtest", { Skip_MODRM
}, 0 },
8205 { "enclu", { Skip_MODRM
}, 0 },
8209 { "vmrun", { Skip_MODRM
}, 0 },
8210 { PREFIX_TABLE (PREFIX_0F01_REG_3_RM_1
) },
8211 { "vmload", { Skip_MODRM
}, 0 },
8212 { "vmsave", { Skip_MODRM
}, 0 },
8213 { "stgi", { Skip_MODRM
}, 0 },
8214 { "clgi", { Skip_MODRM
}, 0 },
8215 { "skinit", { Skip_MODRM
}, 0 },
8216 { "invlpga", { Skip_MODRM
}, 0 },
8219 /* RM_0F01_REG_5_MOD_3 */
8220 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_0
) },
8221 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_1
) },
8222 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_2
) },
8224 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_4
) },
8225 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_5
) },
8226 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_6
) },
8227 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_7
) },
8230 /* RM_0F01_REG_7_MOD_3 */
8231 { "swapgs", { Skip_MODRM
}, 0 },
8232 { "rdtscp", { Skip_MODRM
}, 0 },
8233 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_2
) },
8234 { "mwaitx", { { OP_Mwait
, eBX_reg
} }, PREFIX_OPCODE
},
8235 { "clzero", { Skip_MODRM
}, 0 },
8236 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_5
) },
8237 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_6
) },
8238 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_7
) },
8241 /* RM_0F1E_P_1_MOD_3_REG_7 */
8242 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8243 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8244 { "endbr64", { Skip_MODRM
}, 0 },
8245 { "endbr32", { Skip_MODRM
}, 0 },
8246 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8247 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8248 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8249 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8252 /* RM_0FAE_REG_6_MOD_3 */
8253 { "mfence", { Skip_MODRM
}, 0 },
8256 /* RM_0FAE_REG_7_MOD_3 */
8257 { "sfence", { Skip_MODRM
}, 0 },
8260 /* RM_0F3A0F_P_1_R_0 */
8261 { "hreset", { Skip_MODRM
, Ib
}, 0 },
8264 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0 */
8265 { "tilerelease", { Skip_MODRM
}, 0 },
8268 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3 */
8269 { "tilezero", { TMM
, Skip_MODRM
}, 0 },
8273 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
8275 /* The values used here must be non-zero, fit in 'unsigned char', and not be
8276 in conflict with actual prefix opcodes. */
8277 #define REP_PREFIX 0x01
8278 #define XACQUIRE_PREFIX 0x02
8279 #define XRELEASE_PREFIX 0x03
8280 #define BND_PREFIX 0x04
8281 #define NOTRACK_PREFIX 0x05
8288 ckprefix (instr_info
*ins
)
8295 /* The maximum instruction length is 15bytes. */
8296 while (length
< MAX_CODE_LENGTH
- 1)
8298 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
8299 return ckp_fetch_error
;
8301 switch (*ins
->codep
)
8303 /* REX prefixes family. */
8320 if (ins
->address_mode
== mode_64bit
)
8321 newrex
= *ins
->codep
;
8324 ins
->last_rex_prefix
= i
;
8327 ins
->prefixes
|= PREFIX_REPZ
;
8328 ins
->last_repz_prefix
= i
;
8331 ins
->prefixes
|= PREFIX_REPNZ
;
8332 ins
->last_repnz_prefix
= i
;
8335 ins
->prefixes
|= PREFIX_LOCK
;
8336 ins
->last_lock_prefix
= i
;
8339 ins
->prefixes
|= PREFIX_CS
;
8340 ins
->last_seg_prefix
= i
;
8341 if (ins
->address_mode
!= mode_64bit
)
8342 ins
->active_seg_prefix
= PREFIX_CS
;
8345 ins
->prefixes
|= PREFIX_SS
;
8346 ins
->last_seg_prefix
= i
;
8347 if (ins
->address_mode
!= mode_64bit
)
8348 ins
->active_seg_prefix
= PREFIX_SS
;
8351 ins
->prefixes
|= PREFIX_DS
;
8352 ins
->last_seg_prefix
= i
;
8353 if (ins
->address_mode
!= mode_64bit
)
8354 ins
->active_seg_prefix
= PREFIX_DS
;
8357 ins
->prefixes
|= PREFIX_ES
;
8358 ins
->last_seg_prefix
= i
;
8359 if (ins
->address_mode
!= mode_64bit
)
8360 ins
->active_seg_prefix
= PREFIX_ES
;
8363 ins
->prefixes
|= PREFIX_FS
;
8364 ins
->last_seg_prefix
= i
;
8365 ins
->active_seg_prefix
= PREFIX_FS
;
8368 ins
->prefixes
|= PREFIX_GS
;
8369 ins
->last_seg_prefix
= i
;
8370 ins
->active_seg_prefix
= PREFIX_GS
;
8373 ins
->prefixes
|= PREFIX_DATA
;
8374 ins
->last_data_prefix
= i
;
8377 ins
->prefixes
|= PREFIX_ADDR
;
8378 ins
->last_addr_prefix
= i
;
8381 /* fwait is really an instruction. If there are prefixes
8382 before the fwait, they belong to the fwait, *not* to the
8383 following instruction. */
8384 ins
->fwait_prefix
= i
;
8385 if (ins
->prefixes
|| ins
->rex
)
8387 ins
->prefixes
|= PREFIX_FWAIT
;
8389 /* This ensures that the previous REX prefixes are noticed
8390 as unused prefixes, as in the return case below. */
8391 return ins
->rex
? ckp_bogus
: ckp_okay
;
8393 ins
->prefixes
= PREFIX_FWAIT
;
8398 /* Rex is ignored when followed by another prefix. */
8401 if (*ins
->codep
!= FWAIT_OPCODE
)
8402 ins
->all_prefixes
[i
++] = *ins
->codep
;
8410 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
8414 prefix_name (enum address_mode mode
, uint8_t pref
, int sizeflag
)
8416 static const char *rexes
[16] =
8421 "rex.XB", /* 0x43 */
8423 "rex.RB", /* 0x45 */
8424 "rex.RX", /* 0x46 */
8425 "rex.RXB", /* 0x47 */
8427 "rex.WB", /* 0x49 */
8428 "rex.WX", /* 0x4a */
8429 "rex.WXB", /* 0x4b */
8430 "rex.WR", /* 0x4c */
8431 "rex.WRB", /* 0x4d */
8432 "rex.WRX", /* 0x4e */
8433 "rex.WRXB", /* 0x4f */
8438 /* REX prefixes family. */
8455 return rexes
[pref
- 0x40];
8475 return (sizeflag
& DFLAG
) ? "data16" : "data32";
8477 if (mode
== mode_64bit
)
8478 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
8480 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
8485 case XACQUIRE_PREFIX
:
8487 case XRELEASE_PREFIX
:
8491 case NOTRACK_PREFIX
:
8499 print_i386_disassembler_options (FILE *stream
)
8501 fprintf (stream
, _("\n\
8502 The following i386/x86-64 specific disassembler options are supported for use\n\
8503 with the -M switch (multiple options should be separated by commas):\n"));
8505 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
8506 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
8507 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
8508 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
8509 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
8510 fprintf (stream
, _(" att-mnemonic\n"
8511 " Display instruction in AT&T mnemonic\n"));
8512 fprintf (stream
, _(" intel-mnemonic\n"
8513 " Display instruction in Intel mnemonic\n"));
8514 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
8515 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
8516 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
8517 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
8518 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
8519 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
8520 fprintf (stream
, _(" amd64 Display instruction in AMD64 ISA\n"));
8521 fprintf (stream
, _(" intel64 Display instruction in Intel64 ISA\n"));
8525 static const struct dis386 bad_opcode
= { "(bad)", { XX
}, 0 };
8527 /* Fetch error indicator. */
8528 static const struct dis386 err_opcode
= { NULL
, { XX
}, 0 };
8530 /* Get a pointer to struct dis386 with a valid name. */
8532 static const struct dis386
*
8533 get_valid_dis386 (const struct dis386
*dp
, instr_info
*ins
)
8535 int vindex
, vex_table_index
;
8537 if (dp
->name
!= NULL
)
8540 switch (dp
->op
[0].bytemode
)
8543 dp
= ®_table
[dp
->op
[1].bytemode
][ins
->modrm
.reg
];
8547 vindex
= ins
->modrm
.mod
== 0x3 ? 1 : 0;
8548 dp
= &mod_table
[dp
->op
[1].bytemode
][vindex
];
8552 dp
= &rm_table
[dp
->op
[1].bytemode
][ins
->modrm
.rm
];
8555 case USE_PREFIX_TABLE
:
8558 /* The prefix in VEX is implicit. */
8559 switch (ins
->vex
.prefix
)
8564 case REPE_PREFIX_OPCODE
:
8567 case DATA_PREFIX_OPCODE
:
8570 case REPNE_PREFIX_OPCODE
:
8580 int last_prefix
= -1;
8583 /* We check PREFIX_REPNZ and PREFIX_REPZ before PREFIX_DATA.
8584 When there are multiple PREFIX_REPNZ and PREFIX_REPZ, the
8586 if ((ins
->prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
8588 if (ins
->last_repz_prefix
> ins
->last_repnz_prefix
)
8591 prefix
= PREFIX_REPZ
;
8592 last_prefix
= ins
->last_repz_prefix
;
8597 prefix
= PREFIX_REPNZ
;
8598 last_prefix
= ins
->last_repnz_prefix
;
8601 /* Check if prefix should be ignored. */
8602 if ((((prefix_table
[dp
->op
[1].bytemode
][vindex
].prefix_requirement
8603 & PREFIX_IGNORED
) >> PREFIX_IGNORED_SHIFT
)
8605 && !prefix_table
[dp
->op
[1].bytemode
][vindex
].name
)
8609 if (vindex
== 0 && (ins
->prefixes
& PREFIX_DATA
) != 0)
8612 prefix
= PREFIX_DATA
;
8613 last_prefix
= ins
->last_data_prefix
;
8618 ins
->used_prefixes
|= prefix
;
8619 ins
->all_prefixes
[last_prefix
] = 0;
8622 dp
= &prefix_table
[dp
->op
[1].bytemode
][vindex
];
8625 case USE_X86_64_TABLE
:
8626 vindex
= ins
->address_mode
== mode_64bit
? 1 : 0;
8627 dp
= &x86_64_table
[dp
->op
[1].bytemode
][vindex
];
8630 case USE_3BYTE_TABLE
:
8631 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
8633 vindex
= *ins
->codep
++;
8634 dp
= &three_byte_table
[dp
->op
[1].bytemode
][vindex
];
8635 ins
->end_codep
= ins
->codep
;
8636 if (!fetch_modrm (ins
))
8640 case USE_VEX_LEN_TABLE
:
8644 switch (ins
->vex
.length
)
8650 /* This allows re-using in particular table entries where only
8651 128-bit operand size (VEX.L=0 / EVEX.L'L=0) are valid. */
8664 dp
= &vex_len_table
[dp
->op
[1].bytemode
][vindex
];
8667 case USE_EVEX_LEN_TABLE
:
8671 switch (ins
->vex
.length
)
8687 dp
= &evex_len_table
[dp
->op
[1].bytemode
][vindex
];
8690 case USE_XOP_8F_TABLE
:
8691 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
8693 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
8695 /* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm". */
8696 switch ((*ins
->codep
& 0x1f))
8702 vex_table_index
= XOP_08
;
8705 vex_table_index
= XOP_09
;
8708 vex_table_index
= XOP_0A
;
8712 ins
->vex
.w
= *ins
->codep
& 0x80;
8713 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
8716 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8717 if (ins
->address_mode
!= mode_64bit
)
8719 /* In 16/32-bit mode REX_B is silently ignored. */
8723 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
8724 switch ((*ins
->codep
& 0x3))
8729 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8732 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8735 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8740 vindex
= *ins
->codep
++;
8741 dp
= &xop_table
[vex_table_index
][vindex
];
8743 ins
->end_codep
= ins
->codep
;
8744 if (!fetch_modrm (ins
))
8747 /* No XOP encoding so far allows for a non-zero embedded prefix. Avoid
8748 having to decode the bits for every otherwise valid encoding. */
8749 if (ins
->vex
.prefix
)
8753 case USE_VEX_C4_TABLE
:
8755 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
8757 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
8758 switch ((*ins
->codep
& 0x1f))
8764 vex_table_index
= VEX_0F
;
8767 vex_table_index
= VEX_0F38
;
8770 vex_table_index
= VEX_0F3A
;
8774 ins
->vex
.w
= *ins
->codep
& 0x80;
8775 if (ins
->address_mode
== mode_64bit
)
8782 /* For the 3-byte VEX prefix in 32-bit mode, the REX_B bit
8783 is ignored, other REX bits are 0 and the highest bit in
8784 VEX.vvvv is also ignored (but we mustn't clear it here). */
8787 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8788 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
8789 switch ((*ins
->codep
& 0x3))
8794 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8797 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8800 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8805 vindex
= *ins
->codep
++;
8806 dp
= &vex_table
[vex_table_index
][vindex
];
8807 ins
->end_codep
= ins
->codep
;
8808 /* There is no MODRM byte for VEX0F 77. */
8809 if ((vex_table_index
!= VEX_0F
|| vindex
!= 0x77)
8810 && !fetch_modrm (ins
))
8814 case USE_VEX_C5_TABLE
:
8816 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
8818 ins
->rex
= (*ins
->codep
& 0x80) ? 0 : REX_R
;
8820 /* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
8822 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8823 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
8824 switch ((*ins
->codep
& 0x3))
8829 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8832 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8835 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8840 vindex
= *ins
->codep
++;
8841 dp
= &vex_table
[VEX_0F
][vindex
];
8842 ins
->end_codep
= ins
->codep
;
8843 /* There is no MODRM byte for VEX 77. */
8844 if (vindex
!= 0x77 && !fetch_modrm (ins
))
8848 case USE_VEX_W_TABLE
:
8852 dp
= &vex_w_table
[dp
->op
[1].bytemode
][ins
->vex
.w
];
8855 case USE_EVEX_TABLE
:
8856 ins
->two_source_ops
= false;
8858 ins
->vex
.evex
= true;
8859 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
8861 /* The first byte after 0x62. */
8862 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
8863 ins
->vex
.r
= *ins
->codep
& 0x10;
8864 switch ((*ins
->codep
& 0xf))
8869 vex_table_index
= EVEX_0F
;
8872 vex_table_index
= EVEX_0F38
;
8875 vex_table_index
= EVEX_0F3A
;
8878 vex_table_index
= EVEX_MAP5
;
8881 vex_table_index
= EVEX_MAP6
;
8885 /* The second byte after 0x62. */
8887 ins
->vex
.w
= *ins
->codep
& 0x80;
8888 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
8891 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8894 if (!(*ins
->codep
& 0x4))
8897 switch ((*ins
->codep
& 0x3))
8902 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8905 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8908 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8912 /* The third byte after 0x62. */
8915 /* Remember the static rounding bits. */
8916 ins
->vex
.ll
= (*ins
->codep
>> 5) & 3;
8917 ins
->vex
.b
= *ins
->codep
& 0x10;
8919 ins
->vex
.v
= *ins
->codep
& 0x8;
8920 ins
->vex
.mask_register_specifier
= *ins
->codep
& 0x7;
8921 ins
->vex
.zeroing
= *ins
->codep
& 0x80;
8923 if (ins
->address_mode
!= mode_64bit
)
8925 /* In 16/32-bit mode silently ignore following bits. */
8932 vindex
= *ins
->codep
++;
8933 dp
= &evex_table
[vex_table_index
][vindex
];
8934 ins
->end_codep
= ins
->codep
;
8935 if (!fetch_modrm (ins
))
8938 /* Set vector length. */
8939 if (ins
->modrm
.mod
== 3 && ins
->vex
.b
)
8940 ins
->vex
.length
= 512;
8943 switch (ins
->vex
.ll
)
8946 ins
->vex
.length
= 128;
8949 ins
->vex
.length
= 256;
8952 ins
->vex
.length
= 512;
8968 if (dp
->name
!= NULL
)
8971 return get_valid_dis386 (dp
, ins
);
8975 get_sib (instr_info
*ins
, int sizeflag
)
8977 /* If modrm.mod == 3, operand must be register. */
8979 && ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
8980 && ins
->modrm
.mod
!= 3
8981 && ins
->modrm
.rm
== 4)
8983 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
8985 ins
->sib
.index
= (ins
->codep
[1] >> 3) & 7;
8986 ins
->sib
.scale
= (ins
->codep
[1] >> 6) & 3;
8987 ins
->sib
.base
= ins
->codep
[1] & 7;
8988 ins
->has_sib
= true;
8991 ins
->has_sib
= false;
8996 /* Like oappend_with_style (below) but always with text style. */
8999 oappend (instr_info
*ins
, const char *s
)
9001 oappend_with_style (ins
, s
, dis_style_text
);
9004 /* Like oappend (above), but S is a string starting with '%'. In
9005 Intel syntax, the '%' is elided. */
9008 oappend_register (instr_info
*ins
, const char *s
)
9010 oappend_with_style (ins
, s
+ ins
->intel_syntax
, dis_style_register
);
9013 /* Wrap around a call to INS->info->fprintf_styled_func, printing FMT.
9014 STYLE is the default style to use in the fprintf_styled_func calls,
9015 however, FMT might include embedded style markers (see oappend_style),
9016 these embedded markers are not printed, but instead change the style
9017 used in the next fprintf_styled_func call. */
9019 static void ATTRIBUTE_PRINTF_3
9020 i386_dis_printf (const disassemble_info
*info
, enum disassembler_style style
,
9021 const char *fmt
, ...)
9024 enum disassembler_style curr_style
= style
;
9025 const char *start
, *curr
;
9026 char staging_area
[40];
9029 /* In particular print_insn()'s processing of op_txt[] can hand rather long
9030 strings here. Bypass vsnprintf() in such cases to avoid capacity issues
9031 with the staging area. */
9032 if (strcmp (fmt
, "%s"))
9034 int res
= vsnprintf (staging_area
, sizeof (staging_area
), fmt
, ap
);
9041 if ((size_t) res
>= sizeof (staging_area
))
9044 start
= curr
= staging_area
;
9048 start
= curr
= va_arg (ap
, const char *);
9055 || (*curr
== STYLE_MARKER_CHAR
9056 && ISXDIGIT (*(curr
+ 1))
9057 && *(curr
+ 2) == STYLE_MARKER_CHAR
))
9059 /* Output content between our START position and CURR. */
9060 int len
= curr
- start
;
9061 int n
= (*info
->fprintf_styled_func
) (info
->stream
, curr_style
,
9062 "%.*s", len
, start
);
9069 /* Skip over the initial STYLE_MARKER_CHAR. */
9072 /* Update the CURR_STYLE. As there are less than 16 styles, it
9073 is possible, that if the input is corrupted in some way, that
9074 we might set CURR_STYLE to an invalid value. Don't worry
9075 though, we check for this situation. */
9076 if (*curr
>= '0' && *curr
<= '9')
9077 curr_style
= (enum disassembler_style
) (*curr
- '0');
9078 else if (*curr
>= 'a' && *curr
<= 'f')
9079 curr_style
= (enum disassembler_style
) (*curr
- 'a' + 10);
9081 curr_style
= dis_style_text
;
9083 /* Check for an invalid style having been selected. This should
9084 never happen, but it doesn't hurt to be a little paranoid. */
9085 if (curr_style
> dis_style_comment_start
)
9086 curr_style
= dis_style_text
;
9088 /* Skip the hex character, and the closing STYLE_MARKER_CHAR. */
9091 /* Reset the START to after the style marker. */
9101 print_insn (bfd_vma pc
, disassemble_info
*info
, int intel_syntax
)
9103 const struct dis386
*dp
;
9106 char *op_txt
[MAX_OPERANDS
];
9108 bool intel_swap_2_3
;
9109 int sizeflag
, orig_sizeflag
;
9111 struct dis_private priv
;
9116 .intel_syntax
= intel_syntax
>= 0
9118 : (info
->mach
& bfd_mach_i386_intel_syntax
) != 0,
9119 .intel_mnemonic
= !SYSV386_COMPAT
,
9120 .op_index
[0 ... MAX_OPERANDS
- 1] = -1,
9122 .start_codep
= priv
.the_buffer
,
9123 .codep
= priv
.the_buffer
,
9125 .last_lock_prefix
= -1,
9126 .last_repz_prefix
= -1,
9127 .last_repnz_prefix
= -1,
9128 .last_data_prefix
= -1,
9129 .last_addr_prefix
= -1,
9130 .last_rex_prefix
= -1,
9131 .last_seg_prefix
= -1,
9134 char op_out
[MAX_OPERANDS
][MAX_OPERAND_BUFFER_SIZE
];
9136 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
9137 if ((info
->mach
& bfd_mach_i386_i386
) != 0)
9138 ins
.address_mode
= mode_32bit
;
9139 else if (info
->mach
== bfd_mach_i386_i8086
)
9141 ins
.address_mode
= mode_16bit
;
9142 priv
.orig_sizeflag
= 0;
9145 ins
.address_mode
= mode_64bit
;
9147 for (p
= info
->disassembler_options
; p
!= NULL
;)
9149 if (startswith (p
, "amd64"))
9151 else if (startswith (p
, "intel64"))
9152 ins
.isa64
= intel64
;
9153 else if (startswith (p
, "x86-64"))
9155 ins
.address_mode
= mode_64bit
;
9156 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9158 else if (startswith (p
, "i386"))
9160 ins
.address_mode
= mode_32bit
;
9161 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9163 else if (startswith (p
, "i8086"))
9165 ins
.address_mode
= mode_16bit
;
9166 priv
.orig_sizeflag
&= ~(AFLAG
| DFLAG
);
9168 else if (startswith (p
, "intel"))
9170 ins
.intel_syntax
= 1;
9171 if (startswith (p
+ 5, "-mnemonic"))
9172 ins
.intel_mnemonic
= true;
9174 else if (startswith (p
, "att"))
9176 ins
.intel_syntax
= 0;
9177 if (startswith (p
+ 3, "-mnemonic"))
9178 ins
.intel_mnemonic
= false;
9180 else if (startswith (p
, "addr"))
9182 if (ins
.address_mode
== mode_64bit
)
9184 if (p
[4] == '3' && p
[5] == '2')
9185 priv
.orig_sizeflag
&= ~AFLAG
;
9186 else if (p
[4] == '6' && p
[5] == '4')
9187 priv
.orig_sizeflag
|= AFLAG
;
9191 if (p
[4] == '1' && p
[5] == '6')
9192 priv
.orig_sizeflag
&= ~AFLAG
;
9193 else if (p
[4] == '3' && p
[5] == '2')
9194 priv
.orig_sizeflag
|= AFLAG
;
9197 else if (startswith (p
, "data"))
9199 if (p
[4] == '1' && p
[5] == '6')
9200 priv
.orig_sizeflag
&= ~DFLAG
;
9201 else if (p
[4] == '3' && p
[5] == '2')
9202 priv
.orig_sizeflag
|= DFLAG
;
9204 else if (startswith (p
, "suffix"))
9205 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
9207 p
= strchr (p
, ',');
9212 if (ins
.address_mode
== mode_64bit
&& sizeof (bfd_vma
) < 8)
9214 i386_dis_printf (info
, dis_style_text
, _("64-bit address is disabled"));
9218 if (ins
.intel_syntax
)
9220 ins
.open_char
= '[';
9221 ins
.close_char
= ']';
9222 ins
.separator_char
= '+';
9223 ins
.scale_char
= '*';
9227 ins
.open_char
= '(';
9228 ins
.close_char
= ')';
9229 ins
.separator_char
= ',';
9230 ins
.scale_char
= ',';
9233 /* The output looks better if we put 7 bytes on a line, since that
9234 puts most long word instructions on a single line. */
9235 info
->bytes_per_line
= 7;
9237 info
->private_data
= &priv
;
9239 priv
.insn_start
= pc
;
9241 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9244 ins
.op_out
[i
] = op_out
[i
];
9247 sizeflag
= priv
.orig_sizeflag
;
9249 switch (ckprefix (&ins
))
9255 /* Too many prefixes or unused REX prefixes. */
9257 i
< (int) ARRAY_SIZE (ins
.all_prefixes
) && ins
.all_prefixes
[i
];
9259 i386_dis_printf (info
, dis_style_mnemonic
, "%s%s",
9260 (i
== 0 ? "" : " "),
9261 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9266 case ckp_fetch_error
:
9267 goto fetch_error_out
;
9270 ins
.nr_prefixes
= ins
.codep
- ins
.start_codep
;
9272 if (!fetch_code (info
, ins
.codep
+ 1))
9275 ret
= fetch_error (&ins
);
9279 ins
.two_source_ops
= (*ins
.codep
== 0x62 || *ins
.codep
== 0xc8);
9281 if ((ins
.prefixes
& PREFIX_FWAIT
)
9282 && (*ins
.codep
< 0xd8 || *ins
.codep
> 0xdf))
9284 /* Handle ins.prefixes before fwait. */
9285 for (i
= 0; i
< ins
.fwait_prefix
&& ins
.all_prefixes
[i
];
9287 i386_dis_printf (info
, dis_style_mnemonic
, "%s ",
9288 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9290 i386_dis_printf (info
, dis_style_mnemonic
, "fwait");
9295 if (*ins
.codep
== 0x0f)
9297 unsigned char threebyte
;
9300 if (!fetch_code (info
, ins
.codep
+ 1))
9301 goto fetch_error_out
;
9302 threebyte
= *ins
.codep
;
9303 dp
= &dis386_twobyte
[threebyte
];
9304 ins
.need_modrm
= twobyte_has_modrm
[threebyte
];
9309 dp
= &dis386
[*ins
.codep
];
9310 ins
.need_modrm
= onebyte_has_modrm
[*ins
.codep
];
9314 /* Save sizeflag for printing the extra ins.prefixes later before updating
9315 it for mnemonic and operand processing. The prefix names depend
9316 only on the address mode. */
9317 orig_sizeflag
= sizeflag
;
9318 if (ins
.prefixes
& PREFIX_ADDR
)
9320 if ((ins
.prefixes
& PREFIX_DATA
))
9323 ins
.end_codep
= ins
.codep
;
9324 if (ins
.need_modrm
&& !fetch_modrm (&ins
))
9325 goto fetch_error_out
;
9327 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
9329 if (!get_sib (&ins
, sizeflag
)
9330 || !dofloat (&ins
, sizeflag
))
9331 goto fetch_error_out
;
9335 dp
= get_valid_dis386 (dp
, &ins
);
9336 if (dp
== &err_opcode
)
9337 goto fetch_error_out
;
9338 if (dp
!= NULL
&& putop (&ins
, dp
->name
, sizeflag
) == 0)
9340 if (!get_sib (&ins
, sizeflag
))
9341 goto fetch_error_out
;
9342 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9344 ins
.obufp
= ins
.op_out
[i
];
9345 ins
.op_ad
= MAX_OPERANDS
- 1 - i
;
9347 && !dp
->op
[i
].rtn (&ins
, dp
->op
[i
].bytemode
, sizeflag
))
9348 goto fetch_error_out
;
9349 /* For EVEX instruction after the last operand masking
9350 should be printed. */
9351 if (i
== 0 && ins
.vex
.evex
)
9353 /* Don't print {%k0}. */
9354 if (ins
.vex
.mask_register_specifier
)
9356 const char *reg_name
9357 = att_names_mask
[ins
.vex
.mask_register_specifier
];
9359 oappend (&ins
, "{");
9360 oappend_register (&ins
, reg_name
);
9361 oappend (&ins
, "}");
9363 if (ins
.vex
.zeroing
)
9364 oappend (&ins
, "{z}");
9366 else if (ins
.vex
.zeroing
)
9368 oappend (&ins
, "{bad}");
9372 /* Instructions with a mask register destination allow for
9373 zeroing-masking only (if any masking at all), which is
9374 _not_ expressed by EVEX.z. */
9375 if (ins
.vex
.zeroing
&& dp
->op
[0].bytemode
== mask_mode
)
9376 ins
.illegal_masking
= true;
9378 /* S/G insns require a mask and don't allow
9380 if ((dp
->op
[0].bytemode
== vex_vsib_d_w_dq_mode
9381 || dp
->op
[0].bytemode
== vex_vsib_q_w_dq_mode
)
9382 && (ins
.vex
.mask_register_specifier
== 0
9383 || ins
.vex
.zeroing
))
9384 ins
.illegal_masking
= true;
9386 if (ins
.illegal_masking
)
9387 oappend (&ins
, "/(bad)");
9391 /* Check whether rounding control was enabled for an insn not
9393 if (ins
.modrm
.mod
== 3 && ins
.vex
.b
9394 && !(ins
.evex_used
& EVEX_b_used
))
9396 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9398 ins
.obufp
= ins
.op_out
[i
];
9401 oappend (&ins
, names_rounding
[ins
.vex
.ll
]);
9402 oappend (&ins
, "bad}");
9409 /* Clear instruction information. */
9410 info
->insn_info_valid
= 0;
9411 info
->branch_delay_insns
= 0;
9412 info
->data_size
= 0;
9413 info
->insn_type
= dis_noninsn
;
9417 /* Reset jump operation indicator. */
9418 ins
.op_is_jump
= false;
9420 int jump_detection
= 0;
9422 /* Extract flags. */
9423 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9425 if ((dp
->op
[i
].rtn
== OP_J
)
9426 || (dp
->op
[i
].rtn
== OP_indirE
))
9427 jump_detection
|= 1;
9428 else if ((dp
->op
[i
].rtn
== BND_Fixup
)
9429 || (!dp
->op
[i
].rtn
&& !dp
->op
[i
].bytemode
))
9430 jump_detection
|= 2;
9431 else if ((dp
->op
[i
].bytemode
== cond_jump_mode
)
9432 || (dp
->op
[i
].bytemode
== loop_jcxz_mode
))
9433 jump_detection
|= 4;
9436 /* Determine if this is a jump or branch. */
9437 if ((jump_detection
& 0x3) == 0x3)
9439 ins
.op_is_jump
= true;
9440 if (jump_detection
& 0x4)
9441 info
->insn_type
= dis_condbranch
;
9443 info
->insn_type
= (dp
->name
&& !strncmp (dp
->name
, "call", 4))
9444 ? dis_jsr
: dis_branch
;
9448 /* If VEX.vvvv and EVEX.vvvv are unused, they must be all 1s, which
9449 are all 0s in inverted form. */
9450 if (ins
.need_vex
&& ins
.vex
.register_specifier
!= 0)
9452 i386_dis_printf (info
, dis_style_text
, "(bad)");
9453 ret
= ins
.end_codep
- priv
.the_buffer
;
9457 switch (dp
->prefix_requirement
)
9460 /* If only the data prefix is marked as mandatory, its absence renders
9461 the encoding invalid. Most other PREFIX_OPCODE rules still apply. */
9462 if (ins
.need_vex
? !ins
.vex
.prefix
: !(ins
.prefixes
& PREFIX_DATA
))
9464 i386_dis_printf (info
, dis_style_text
, "(bad)");
9465 ret
= ins
.end_codep
- priv
.the_buffer
;
9468 ins
.used_prefixes
|= PREFIX_DATA
;
9471 /* If the mandatory PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is
9472 unused, opcode is invalid. Since the PREFIX_DATA prefix may be
9473 used by putop and MMX/SSE operand and may be overridden by the
9474 PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
9477 ? ins
.vex
.prefix
== REPE_PREFIX_OPCODE
9478 || ins
.vex
.prefix
== REPNE_PREFIX_OPCODE
9480 & (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
9481 && (ins
.used_prefixes
9482 & (PREFIX_REPZ
| PREFIX_REPNZ
)) == 0)
9484 ? ins
.vex
.prefix
== DATA_PREFIX_OPCODE
9486 & (PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
))
9488 && (ins
.used_prefixes
& PREFIX_DATA
) == 0))
9489 || (ins
.vex
.evex
&& dp
->prefix_requirement
!= PREFIX_DATA
9490 && !ins
.vex
.w
!= !(ins
.used_prefixes
& PREFIX_DATA
)))
9492 i386_dis_printf (info
, dis_style_text
, "(bad)");
9493 ret
= ins
.end_codep
- priv
.the_buffer
;
9498 case PREFIX_IGNORED
:
9499 /* Zap data size and rep prefixes from used_prefixes and reinstate their
9500 origins in all_prefixes. */
9501 ins
.used_prefixes
&= ~PREFIX_OPCODE
;
9502 if (ins
.last_data_prefix
>= 0)
9503 ins
.all_prefixes
[ins
.last_data_prefix
] = 0x66;
9504 if (ins
.last_repz_prefix
>= 0)
9505 ins
.all_prefixes
[ins
.last_repz_prefix
] = 0xf3;
9506 if (ins
.last_repnz_prefix
>= 0)
9507 ins
.all_prefixes
[ins
.last_repnz_prefix
] = 0xf2;
9511 /* Check if the REX prefix is used. */
9512 if ((ins
.rex
^ ins
.rex_used
) == 0
9513 && !ins
.need_vex
&& ins
.last_rex_prefix
>= 0)
9514 ins
.all_prefixes
[ins
.last_rex_prefix
] = 0;
9516 /* Check if the SEG prefix is used. */
9517 if ((ins
.prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
| PREFIX_ES
9518 | PREFIX_FS
| PREFIX_GS
)) != 0
9519 && (ins
.used_prefixes
& ins
.active_seg_prefix
) != 0)
9520 ins
.all_prefixes
[ins
.last_seg_prefix
] = 0;
9522 /* Check if the ADDR prefix is used. */
9523 if ((ins
.prefixes
& PREFIX_ADDR
) != 0
9524 && (ins
.used_prefixes
& PREFIX_ADDR
) != 0)
9525 ins
.all_prefixes
[ins
.last_addr_prefix
] = 0;
9527 /* Check if the DATA prefix is used. */
9528 if ((ins
.prefixes
& PREFIX_DATA
) != 0
9529 && (ins
.used_prefixes
& PREFIX_DATA
) != 0
9531 ins
.all_prefixes
[ins
.last_data_prefix
] = 0;
9533 /* Print the extra ins.prefixes. */
9535 for (i
= 0; i
< (int) ARRAY_SIZE (ins
.all_prefixes
); i
++)
9536 if (ins
.all_prefixes
[i
])
9538 const char *name
= prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9543 prefix_length
+= strlen (name
) + 1;
9544 i386_dis_printf (info
, dis_style_mnemonic
, "%s ", name
);
9547 /* Check maximum code length. */
9548 if ((ins
.codep
- ins
.start_codep
) > MAX_CODE_LENGTH
)
9550 i386_dis_printf (info
, dis_style_text
, "(bad)");
9551 ret
= MAX_CODE_LENGTH
;
9555 /* Calculate the number of operands this instruction has. */
9557 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9558 if (*ins
.op_out
[i
] != '\0')
9561 /* Calculate the number of spaces to print after the mnemonic. */
9562 ins
.obufp
= ins
.mnemonicendp
;
9565 i
= strlen (ins
.obuf
) + prefix_length
;
9574 /* Print the instruction mnemonic along with any trailing whitespace. */
9575 i386_dis_printf (info
, dis_style_mnemonic
, "%s%*s", ins
.obuf
, i
, "");
9577 /* The enter and bound instructions are printed with operands in the same
9578 order as the intel book; everything else is printed in reverse order. */
9579 intel_swap_2_3
= false;
9580 if (ins
.intel_syntax
|| ins
.two_source_ops
)
9582 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9583 op_txt
[i
] = ins
.op_out
[i
];
9585 if (ins
.intel_syntax
&& dp
&& dp
->op
[2].rtn
== OP_Rounding
9586 && dp
->op
[3].rtn
== OP_E
&& dp
->op
[4].rtn
== NULL
)
9588 op_txt
[2] = ins
.op_out
[3];
9589 op_txt
[3] = ins
.op_out
[2];
9590 intel_swap_2_3
= true;
9593 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
9597 ins
.op_ad
= ins
.op_index
[i
];
9598 ins
.op_index
[i
] = ins
.op_index
[MAX_OPERANDS
- 1 - i
];
9599 ins
.op_index
[MAX_OPERANDS
- 1 - i
] = ins
.op_ad
;
9600 riprel
= ins
.op_riprel
[i
];
9601 ins
.op_riprel
[i
] = ins
.op_riprel
[MAX_OPERANDS
- 1 - i
];
9602 ins
.op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
9607 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9608 op_txt
[MAX_OPERANDS
- 1 - i
] = ins
.op_out
[i
];
9612 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9615 /* In Intel syntax embedded rounding / SAE are not separate operands.
9616 Instead they're attached to the prior register operand. Simply
9617 suppress emission of the comma to achieve that effect. */
9618 switch (i
& -(ins
.intel_syntax
&& dp
))
9621 if (dp
->op
[2].rtn
== OP_Rounding
&& !intel_swap_2_3
)
9625 if (dp
->op
[3].rtn
== OP_Rounding
|| intel_swap_2_3
)
9630 i386_dis_printf (info
, dis_style_text
, ",");
9631 if (ins
.op_index
[i
] != -1 && !ins
.op_riprel
[i
])
9633 bfd_vma target
= (bfd_vma
) ins
.op_address
[ins
.op_index
[i
]];
9637 info
->insn_info_valid
= 1;
9638 info
->branch_delay_insns
= 0;
9639 info
->data_size
= 0;
9640 info
->target
= target
;
9643 (*info
->print_address_func
) (target
, info
);
9646 i386_dis_printf (info
, dis_style_text
, "%s", op_txt
[i
]);
9650 for (i
= 0; i
< MAX_OPERANDS
; i
++)
9651 if (ins
.op_index
[i
] != -1 && ins
.op_riprel
[i
])
9653 i386_dis_printf (info
, dis_style_comment_start
, " # ");
9654 (*info
->print_address_func
)
9655 ((bfd_vma
)(ins
.start_pc
+ (ins
.codep
- ins
.start_codep
)
9656 + ins
.op_address
[ins
.op_index
[i
]]),
9660 ret
= ins
.codep
- priv
.the_buffer
;
9662 info
->private_data
= NULL
;
9666 /* Here for backwards compatibility. When gdb stops using
9667 print_insn_i386_att and print_insn_i386_intel these functions can
9668 disappear, and print_insn_i386 be merged into print_insn. */
9670 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
9672 return print_insn (pc
, info
, 0);
9676 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
9678 return print_insn (pc
, info
, 1);
9682 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
9684 return print_insn (pc
, info
, -1);
9687 static const char *float_mem
[] = {
9762 static const unsigned char float_mem_mode
[] = {
9837 #define ST { OP_ST, 0 }
9838 #define STi { OP_STi, 0 }
9840 #define FGRPd9_2 NULL, { { NULL, 1 } }, 0
9841 #define FGRPd9_4 NULL, { { NULL, 2 } }, 0
9842 #define FGRPd9_5 NULL, { { NULL, 3 } }, 0
9843 #define FGRPd9_6 NULL, { { NULL, 4 } }, 0
9844 #define FGRPd9_7 NULL, { { NULL, 5 } }, 0
9845 #define FGRPda_5 NULL, { { NULL, 6 } }, 0
9846 #define FGRPdb_4 NULL, { { NULL, 7 } }, 0
9847 #define FGRPde_3 NULL, { { NULL, 8 } }, 0
9848 #define FGRPdf_4 NULL, { { NULL, 9 } }, 0
9850 static const struct dis386 float_reg
[][8] = {
9853 { "fadd", { ST
, STi
}, 0 },
9854 { "fmul", { ST
, STi
}, 0 },
9855 { "fcom", { STi
}, 0 },
9856 { "fcomp", { STi
}, 0 },
9857 { "fsub", { ST
, STi
}, 0 },
9858 { "fsubr", { ST
, STi
}, 0 },
9859 { "fdiv", { ST
, STi
}, 0 },
9860 { "fdivr", { ST
, STi
}, 0 },
9864 { "fld", { STi
}, 0 },
9865 { "fxch", { STi
}, 0 },
9875 { "fcmovb", { ST
, STi
}, 0 },
9876 { "fcmove", { ST
, STi
}, 0 },
9877 { "fcmovbe",{ ST
, STi
}, 0 },
9878 { "fcmovu", { ST
, STi
}, 0 },
9886 { "fcmovnb",{ ST
, STi
}, 0 },
9887 { "fcmovne",{ ST
, STi
}, 0 },
9888 { "fcmovnbe",{ ST
, STi
}, 0 },
9889 { "fcmovnu",{ ST
, STi
}, 0 },
9891 { "fucomi", { ST
, STi
}, 0 },
9892 { "fcomi", { ST
, STi
}, 0 },
9897 { "fadd", { STi
, ST
}, 0 },
9898 { "fmul", { STi
, ST
}, 0 },
9901 { "fsub{!M|r}", { STi
, ST
}, 0 },
9902 { "fsub{M|}", { STi
, ST
}, 0 },
9903 { "fdiv{!M|r}", { STi
, ST
}, 0 },
9904 { "fdiv{M|}", { STi
, ST
}, 0 },
9908 { "ffree", { STi
}, 0 },
9910 { "fst", { STi
}, 0 },
9911 { "fstp", { STi
}, 0 },
9912 { "fucom", { STi
}, 0 },
9913 { "fucomp", { STi
}, 0 },
9919 { "faddp", { STi
, ST
}, 0 },
9920 { "fmulp", { STi
, ST
}, 0 },
9923 { "fsub{!M|r}p", { STi
, ST
}, 0 },
9924 { "fsub{M|}p", { STi
, ST
}, 0 },
9925 { "fdiv{!M|r}p", { STi
, ST
}, 0 },
9926 { "fdiv{M|}p", { STi
, ST
}, 0 },
9930 { "ffreep", { STi
}, 0 },
9935 { "fucomip", { ST
, STi
}, 0 },
9936 { "fcomip", { ST
, STi
}, 0 },
9941 static const char *const fgrps
[][8] = {
9944 "(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
9949 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
9954 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
9959 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
9964 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
9969 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
9974 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
9979 "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
9980 "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
9985 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
9990 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
9995 swap_operand (instr_info
*ins
)
9997 ins
->mnemonicendp
[0] = '.';
9998 ins
->mnemonicendp
[1] = 's';
9999 ins
->mnemonicendp
[2] = '\0';
10000 ins
->mnemonicendp
+= 2;
10004 dofloat (instr_info
*ins
, int sizeflag
)
10006 const struct dis386
*dp
;
10007 unsigned char floatop
= ins
->codep
[-1];
10009 if (ins
->modrm
.mod
!= 3)
10011 int fp_indx
= (floatop
- 0xd8) * 8 + ins
->modrm
.reg
;
10013 putop (ins
, float_mem
[fp_indx
], sizeflag
);
10014 ins
->obufp
= ins
->op_out
[0];
10016 return OP_E (ins
, float_mem_mode
[fp_indx
], sizeflag
);
10018 /* Skip mod/rm byte. */
10022 dp
= &float_reg
[floatop
- 0xd8][ins
->modrm
.reg
];
10023 if (dp
->name
== NULL
)
10025 putop (ins
, fgrps
[dp
->op
[0].bytemode
][ins
->modrm
.rm
], sizeflag
);
10027 /* Instruction fnstsw is only one with strange arg. */
10028 if (floatop
== 0xdf && ins
->codep
[-1] == 0xe0)
10029 strcpy (ins
->op_out
[0], att_names16
[0] + ins
->intel_syntax
);
10033 putop (ins
, dp
->name
, sizeflag
);
10035 ins
->obufp
= ins
->op_out
[0];
10038 && !dp
->op
[0].rtn (ins
, dp
->op
[0].bytemode
, sizeflag
))
10041 ins
->obufp
= ins
->op_out
[1];
10044 && !dp
->op
[1].rtn (ins
, dp
->op
[1].bytemode
, sizeflag
))
10051 OP_ST (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10052 int sizeflag ATTRIBUTE_UNUSED
)
10054 oappend_register (ins
, "%st");
10059 OP_STi (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10060 int sizeflag ATTRIBUTE_UNUSED
)
10063 int res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%st(%d)", ins
->modrm
.rm
);
10065 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
10067 oappend_register (ins
, scratch
);
10071 /* Capital letters in template are macros. */
10073 putop (instr_info
*ins
, const char *in_template
, int sizeflag
)
10078 unsigned int l
= 0, len
= 0;
10081 for (p
= in_template
; *p
; p
++)
10085 if (l
>= sizeof (last
) || !ISUPPER (*p
))
10093 *ins
->obufp
++ = *p
;
10102 if (ins
->intel_syntax
)
10104 while (*++p
!= '|')
10105 if (*p
== '}' || *p
== '\0')
10111 while (*++p
!= '}')
10121 if (ins
->intel_syntax
)
10123 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3)
10124 || (sizeflag
& SUFFIX_ALWAYS
))
10125 *ins
->obufp
++ = 'b';
10131 if (ins
->intel_syntax
)
10133 if (sizeflag
& SUFFIX_ALWAYS
)
10134 *ins
->obufp
++ = 'b';
10136 else if (l
== 1 && last
[0] == 'L')
10138 if (ins
->address_mode
== mode_64bit
10139 && !(ins
->prefixes
& PREFIX_ADDR
))
10141 *ins
->obufp
++ = 'a';
10142 *ins
->obufp
++ = 'b';
10143 *ins
->obufp
++ = 's';
10152 if (ins
->intel_syntax
&& !alt
)
10154 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
10156 if (sizeflag
& DFLAG
)
10157 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10159 *ins
->obufp
++ = ins
->intel_syntax
? 'w' : 's';
10160 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10169 if (!ins
->vex
.evex
|| ins
->vex
.w
)
10170 *ins
->obufp
++ = 'd';
10172 oappend (ins
, "{bad}");
10181 if (ins
->intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
10184 if (ins
->modrm
.mod
== 3)
10186 if (ins
->rex
& REX_W
)
10187 *ins
->obufp
++ = 'q';
10190 if (sizeflag
& DFLAG
)
10191 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10193 *ins
->obufp
++ = 'w';
10194 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10198 *ins
->obufp
++ = 'w';
10206 if (!ins
->vex
.evex
|| ins
->vex
.b
|| ins
->vex
.ll
>= 2
10208 || (ins
->modrm
.mod
== 3 && (ins
->rex
& REX_X
))
10209 || !ins
->vex
.v
|| ins
->vex
.mask_register_specifier
)
10211 /* AVX512 extends a number of V*D insns to also have V*Q variants,
10212 merely distinguished by EVEX.W. Look for a use of the
10213 respective macro. */
10216 const char *pct
= strchr (p
+ 1, '%');
10218 if (pct
!= NULL
&& pct
[1] == 'D' && pct
[2] == 'Q')
10221 *ins
->obufp
++ = '{';
10222 *ins
->obufp
++ = 'e';
10223 *ins
->obufp
++ = 'v';
10224 *ins
->obufp
++ = 'e';
10225 *ins
->obufp
++ = 'x';
10226 *ins
->obufp
++ = '}';
10227 *ins
->obufp
++ = ' ';
10234 /* For jcxz/jecxz */
10235 if (ins
->address_mode
== mode_64bit
)
10237 if (sizeflag
& AFLAG
)
10238 *ins
->obufp
++ = 'r';
10240 *ins
->obufp
++ = 'e';
10243 if (sizeflag
& AFLAG
)
10244 *ins
->obufp
++ = 'e';
10245 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
10248 if (ins
->intel_syntax
)
10250 if ((ins
->prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
10252 if (sizeflag
& AFLAG
)
10253 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
10255 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'l' : 'w';
10256 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
10260 if (ins
->intel_syntax
|| (ins
->obufp
[-1] != 's'
10261 && !(sizeflag
& SUFFIX_ALWAYS
)))
10263 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
10264 *ins
->obufp
++ = 'l';
10266 *ins
->obufp
++ = 'w';
10267 if (!(ins
->rex
& REX_W
))
10268 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10273 if (ins
->intel_syntax
)
10275 if ((ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
10276 || (ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
10278 ins
->used_prefixes
|= ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
);
10279 *ins
->obufp
++ = ',';
10280 *ins
->obufp
++ = 'p';
10282 /* Set active_seg_prefix even if not set in 64-bit mode
10283 because here it is a valid branch hint. */
10284 if (ins
->prefixes
& PREFIX_DS
)
10286 ins
->active_seg_prefix
= PREFIX_DS
;
10287 *ins
->obufp
++ = 't';
10291 ins
->active_seg_prefix
= PREFIX_CS
;
10292 *ins
->obufp
++ = 'n';
10296 else if (l
== 1 && last
[0] == 'X')
10299 *ins
->obufp
++ = 'h';
10301 oappend (ins
, "{bad}");
10308 if (ins
->rex
& REX_W
)
10309 *ins
->obufp
++ = 'q';
10311 *ins
->obufp
++ = 'd';
10316 if (ins
->intel_mnemonic
!= cond
)
10317 *ins
->obufp
++ = 'r';
10320 if ((ins
->prefixes
& PREFIX_FWAIT
) == 0)
10321 *ins
->obufp
++ = 'n';
10323 ins
->used_prefixes
|= PREFIX_FWAIT
;
10327 if (ins
->rex
& REX_W
)
10328 *ins
->obufp
++ = 'o';
10329 else if (ins
->intel_syntax
&& (sizeflag
& DFLAG
))
10330 *ins
->obufp
++ = 'q';
10332 *ins
->obufp
++ = 'd';
10333 if (!(ins
->rex
& REX_W
))
10334 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10337 if (ins
->address_mode
== mode_64bit
10338 && (ins
->isa64
== intel64
|| (ins
->rex
& REX_W
)
10339 || !(ins
->prefixes
& PREFIX_DATA
)))
10341 if (sizeflag
& SUFFIX_ALWAYS
)
10342 *ins
->obufp
++ = 'q';
10345 /* Fall through. */
10349 if ((ins
->modrm
.mod
== 3 || !cond
)
10350 && !(sizeflag
& SUFFIX_ALWAYS
))
10352 /* Fall through. */
10354 if ((!(ins
->rex
& REX_W
) && (ins
->prefixes
& PREFIX_DATA
))
10355 || ((sizeflag
& SUFFIX_ALWAYS
)
10356 && ins
->address_mode
!= mode_64bit
))
10358 *ins
->obufp
++ = (sizeflag
& DFLAG
)
10359 ? ins
->intel_syntax
? 'd' : 'l' : 'w';
10360 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10362 else if (sizeflag
& SUFFIX_ALWAYS
)
10363 *ins
->obufp
++ = 'q';
10365 else if (l
== 1 && last
[0] == 'L')
10367 if ((ins
->prefixes
& PREFIX_DATA
)
10368 || (ins
->rex
& REX_W
)
10369 || (sizeflag
& SUFFIX_ALWAYS
))
10372 if (ins
->rex
& REX_W
)
10373 *ins
->obufp
++ = 'q';
10376 if (sizeflag
& DFLAG
)
10377 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10379 *ins
->obufp
++ = 'w';
10380 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10390 if (ins
->intel_syntax
&& !alt
)
10393 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3)
10394 || (sizeflag
& SUFFIX_ALWAYS
))
10396 if (ins
->rex
& REX_W
)
10397 *ins
->obufp
++ = 'q';
10400 if (sizeflag
& DFLAG
)
10401 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10403 *ins
->obufp
++ = 'w';
10404 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10408 else if (l
== 1 && last
[0] == 'D')
10409 *ins
->obufp
++ = ins
->vex
.w
? 'q' : 'd';
10410 else if (l
== 1 && last
[0] == 'L')
10412 if (cond
? ins
->modrm
.mod
== 3 && !(sizeflag
& SUFFIX_ALWAYS
)
10413 : ins
->address_mode
!= mode_64bit
)
10415 if ((ins
->rex
& REX_W
))
10418 *ins
->obufp
++ = 'q';
10420 else if ((ins
->address_mode
== mode_64bit
&& cond
)
10421 || (sizeflag
& SUFFIX_ALWAYS
))
10422 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10429 if (ins
->rex
& REX_W
)
10430 *ins
->obufp
++ = 'q';
10431 else if (sizeflag
& DFLAG
)
10433 if (ins
->intel_syntax
)
10434 *ins
->obufp
++ = 'd';
10436 *ins
->obufp
++ = 'l';
10439 *ins
->obufp
++ = 'w';
10440 if (ins
->intel_syntax
&& !p
[1]
10441 && ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
)))
10442 *ins
->obufp
++ = 'e';
10443 if (!(ins
->rex
& REX_W
))
10444 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10450 if (ins
->intel_syntax
)
10452 if (sizeflag
& SUFFIX_ALWAYS
)
10454 if (ins
->rex
& REX_W
)
10455 *ins
->obufp
++ = 'q';
10458 if (sizeflag
& DFLAG
)
10459 *ins
->obufp
++ = 'l';
10461 *ins
->obufp
++ = 'w';
10462 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10472 if (ins
->address_mode
== mode_64bit
10473 && !(ins
->prefixes
& PREFIX_ADDR
))
10475 *ins
->obufp
++ = 'a';
10476 *ins
->obufp
++ = 'b';
10477 *ins
->obufp
++ = 's';
10482 if (!ins
->vex
.evex
|| !ins
->vex
.w
)
10483 *ins
->obufp
++ = 's';
10485 oappend (ins
, "{bad}");
10495 *ins
->obufp
++ = 'v';
10504 *ins
->obufp
++ = '{';
10505 *ins
->obufp
++ = 'v';
10506 *ins
->obufp
++ = 'e';
10507 *ins
->obufp
++ = 'x';
10508 *ins
->obufp
++ = '}';
10509 *ins
->obufp
++ = ' ';
10512 if (ins
->rex
& REX_W
)
10514 *ins
->obufp
++ = 'a';
10515 *ins
->obufp
++ = 'b';
10516 *ins
->obufp
++ = 's';
10529 /* operand size flag for cwtl, cbtw */
10531 if (ins
->rex
& REX_W
)
10533 if (ins
->intel_syntax
)
10534 *ins
->obufp
++ = 'd';
10536 *ins
->obufp
++ = 'l';
10538 else if (sizeflag
& DFLAG
)
10539 *ins
->obufp
++ = 'w';
10541 *ins
->obufp
++ = 'b';
10542 if (!(ins
->rex
& REX_W
))
10543 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10547 if (!ins
->need_vex
)
10549 if (last
[0] == 'X')
10550 *ins
->obufp
++ = ins
->vex
.w
? 'd': 's';
10551 else if (last
[0] == 'B')
10552 *ins
->obufp
++ = ins
->vex
.w
? 'w': 'b';
10563 ? ins
->vex
.prefix
== DATA_PREFIX_OPCODE
10564 : ins
->prefixes
& PREFIX_DATA
)
10566 *ins
->obufp
++ = 'd';
10567 ins
->used_prefixes
|= PREFIX_DATA
;
10570 *ins
->obufp
++ = 's';
10575 if (ins
->vex
.mask_register_specifier
)
10576 ins
->illegal_masking
= true;
10578 else if (l
== 1 && last
[0] == 'X')
10580 if (!ins
->need_vex
)
10582 if (ins
->intel_syntax
10583 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
10584 && !(sizeflag
& SUFFIX_ALWAYS
)))
10586 switch (ins
->vex
.length
)
10589 *ins
->obufp
++ = 'x';
10592 *ins
->obufp
++ = 'y';
10595 if (!ins
->vex
.evex
)
10606 /* These insns ignore ModR/M.mod: Force it to 3 for OP_E(). */
10607 ins
->modrm
.mod
= 3;
10608 if (!ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
10609 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
10611 else if (l
== 1 && last
[0] == 'X')
10613 if (!ins
->vex
.evex
)
10615 if (ins
->intel_syntax
10616 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
10617 && !(sizeflag
& SUFFIX_ALWAYS
)))
10619 switch (ins
->vex
.length
)
10622 *ins
->obufp
++ = 'x';
10625 *ins
->obufp
++ = 'y';
10628 *ins
->obufp
++ = 'z';
10638 if (ins
->intel_syntax
)
10640 if (ins
->isa64
== intel64
&& (ins
->rex
& REX_W
))
10643 *ins
->obufp
++ = 'q';
10646 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
10648 if (sizeflag
& DFLAG
)
10649 *ins
->obufp
++ = 'l';
10651 *ins
->obufp
++ = 'w';
10652 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10661 ins
->mnemonicendp
= ins
->obufp
;
10665 /* Add a style marker to *INS->obufp that encodes STYLE. This assumes that
10666 the buffer pointed to by INS->obufp has space. A style marker is made
10667 from the STYLE_MARKER_CHAR followed by STYLE converted to a single hex
10668 digit, followed by another STYLE_MARKER_CHAR. This function assumes
10669 that the number of styles is not greater than 16. */
10672 oappend_insert_style (instr_info
*ins
, enum disassembler_style style
)
10674 unsigned num
= (unsigned) style
;
10676 /* We currently assume that STYLE can be encoded as a single hex
10677 character. If more styles are added then this might start to fail,
10678 and we'll need to expand this code. */
10682 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
10683 *ins
->obufp
++ = (num
< 10 ? ('0' + num
)
10684 : ((num
< 16) ? ('a' + (num
- 10)) : '0'));
10685 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
10687 /* This final null character is not strictly necessary, after inserting a
10688 style marker we should always be inserting some additional content.
10689 However, having the buffer null terminated doesn't cost much, and make
10690 it easier to debug what's going on. Also, if we do ever forget to add
10691 any additional content after this style marker, then the buffer will
10692 still be well formed. */
10693 *ins
->obufp
= '\0';
10697 oappend_with_style (instr_info
*ins
, const char *s
,
10698 enum disassembler_style style
)
10700 oappend_insert_style (ins
, style
);
10701 ins
->obufp
= stpcpy (ins
->obufp
, s
);
10704 /* Add a single character C to the buffer pointer to by INS->obufp, marking
10705 the style for the character as STYLE. */
10708 oappend_char_with_style (instr_info
*ins
, const char c
,
10709 enum disassembler_style style
)
10711 oappend_insert_style (ins
, style
);
10713 *ins
->obufp
= '\0';
10716 /* Like oappend_char_with_style, but always uses dis_style_text. */
10719 oappend_char (instr_info
*ins
, const char c
)
10721 oappend_char_with_style (ins
, c
, dis_style_text
);
10725 append_seg (instr_info
*ins
)
10727 /* Only print the active segment register. */
10728 if (!ins
->active_seg_prefix
)
10731 ins
->used_prefixes
|= ins
->active_seg_prefix
;
10732 switch (ins
->active_seg_prefix
)
10735 oappend_register (ins
, att_names_seg
[1]);
10738 oappend_register (ins
, att_names_seg
[3]);
10741 oappend_register (ins
, att_names_seg
[2]);
10744 oappend_register (ins
, att_names_seg
[0]);
10747 oappend_register (ins
, att_names_seg
[4]);
10750 oappend_register (ins
, att_names_seg
[5]);
10755 oappend_char (ins
, ':');
10759 print_operand_value (instr_info
*ins
, bfd_vma disp
,
10760 enum disassembler_style style
)
10764 if (ins
->address_mode
!= mode_64bit
)
10765 disp
&= 0xffffffff;
10766 sprintf (tmp
, "0x%" PRIx64
, (uint64_t) disp
);
10767 oappend_with_style (ins
, tmp
, style
);
10770 /* Like oappend, but called for immediate operands. */
10773 oappend_immediate (instr_info
*ins
, bfd_vma imm
)
10775 if (!ins
->intel_syntax
)
10776 oappend_char_with_style (ins
, '$', dis_style_immediate
);
10777 print_operand_value (ins
, imm
, dis_style_immediate
);
10780 /* Put DISP in BUF as signed hex number. */
10783 print_displacement (instr_info
*ins
, bfd_signed_vma val
)
10789 oappend_char_with_style (ins
, '-', dis_style_address_offset
);
10790 val
= (bfd_vma
) 0 - val
;
10792 /* Check for possible overflow. */
10795 switch (ins
->address_mode
)
10798 oappend_with_style (ins
, "0x8000000000000000",
10799 dis_style_address_offset
);
10802 oappend_with_style (ins
, "0x80000000",
10803 dis_style_address_offset
);
10806 oappend_with_style (ins
, "0x8000",
10807 dis_style_address_offset
);
10814 sprintf (tmp
, "0x%" PRIx64
, (int64_t) val
);
10815 oappend_with_style (ins
, tmp
, dis_style_address_offset
);
10819 intel_operand_size (instr_info
*ins
, int bytemode
, int sizeflag
)
10823 if (!ins
->vex
.no_broadcast
)
10827 case evex_half_bcst_xmmq_mode
:
10829 oappend (ins
, "QWORD BCST ");
10831 oappend (ins
, "DWORD BCST ");
10834 case evex_half_bcst_xmmqh_mode
:
10835 case evex_half_bcst_xmmqdh_mode
:
10836 oappend (ins
, "WORD BCST ");
10839 ins
->vex
.no_broadcast
= true;
10849 oappend (ins
, "BYTE PTR ");
10854 oappend (ins
, "WORD PTR ");
10857 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
10859 oappend (ins
, "QWORD PTR ");
10862 /* Fall through. */
10864 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
10865 || (ins
->rex
& REX_W
)))
10867 oappend (ins
, "QWORD PTR ");
10870 /* Fall through. */
10875 if (ins
->rex
& REX_W
)
10876 oappend (ins
, "QWORD PTR ");
10877 else if (bytemode
== dq_mode
)
10878 oappend (ins
, "DWORD PTR ");
10881 if (sizeflag
& DFLAG
)
10882 oappend (ins
, "DWORD PTR ");
10884 oappend (ins
, "WORD PTR ");
10885 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10889 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
10890 *ins
->obufp
++ = 'D';
10891 oappend (ins
, "WORD PTR ");
10892 if (!(ins
->rex
& REX_W
))
10893 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10896 if (sizeflag
& DFLAG
)
10897 oappend (ins
, "QWORD PTR ");
10899 oappend (ins
, "DWORD PTR ");
10900 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10903 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
10904 oappend (ins
, "WORD PTR ");
10906 oappend (ins
, "DWORD PTR ");
10907 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10911 oappend (ins
, "DWORD PTR ");
10915 oappend (ins
, "QWORD PTR ");
10918 if (ins
->address_mode
== mode_64bit
)
10919 oappend (ins
, "QWORD PTR ");
10921 oappend (ins
, "DWORD PTR ");
10924 if (sizeflag
& DFLAG
)
10925 oappend (ins
, "FWORD PTR ");
10927 oappend (ins
, "DWORD PTR ");
10928 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10931 oappend (ins
, "TBYTE PTR ");
10936 case evex_x_gscat_mode
:
10937 case evex_x_nobcst_mode
:
10941 switch (ins
->vex
.length
)
10944 oappend (ins
, "XMMWORD PTR ");
10947 oappend (ins
, "YMMWORD PTR ");
10950 oappend (ins
, "ZMMWORD PTR ");
10957 oappend (ins
, "XMMWORD PTR ");
10960 oappend (ins
, "XMMWORD PTR ");
10963 oappend (ins
, "YMMWORD PTR ");
10966 case evex_half_bcst_xmmqh_mode
:
10967 case evex_half_bcst_xmmq_mode
:
10968 switch (ins
->vex
.length
)
10972 oappend (ins
, "QWORD PTR ");
10975 oappend (ins
, "XMMWORD PTR ");
10978 oappend (ins
, "YMMWORD PTR ");
10985 if (!ins
->need_vex
)
10988 switch (ins
->vex
.length
)
10991 oappend (ins
, "WORD PTR ");
10994 oappend (ins
, "DWORD PTR ");
10997 oappend (ins
, "QWORD PTR ");
11004 case evex_half_bcst_xmmqdh_mode
:
11005 if (!ins
->need_vex
)
11008 switch (ins
->vex
.length
)
11011 oappend (ins
, "DWORD PTR ");
11014 oappend (ins
, "QWORD PTR ");
11017 oappend (ins
, "XMMWORD PTR ");
11024 if (!ins
->need_vex
)
11027 switch (ins
->vex
.length
)
11030 oappend (ins
, "QWORD PTR ");
11033 oappend (ins
, "YMMWORD PTR ");
11036 oappend (ins
, "ZMMWORD PTR ");
11043 oappend (ins
, "OWORD PTR ");
11045 case vex_vsib_d_w_dq_mode
:
11046 case vex_vsib_q_w_dq_mode
:
11047 if (!ins
->need_vex
)
11050 oappend (ins
, "QWORD PTR ");
11052 oappend (ins
, "DWORD PTR ");
11055 if (!ins
->need_vex
|| ins
->vex
.length
!= 128)
11058 oappend (ins
, "DWORD PTR ");
11060 oappend (ins
, "BYTE PTR ");
11063 if (!ins
->need_vex
)
11066 oappend (ins
, "QWORD PTR ");
11068 oappend (ins
, "WORD PTR ");
11078 print_register (instr_info
*ins
, unsigned int reg
, unsigned int rexmask
,
11079 int bytemode
, int sizeflag
)
11081 const char (*names
)[8];
11083 /* Masking is invalid for insns with GPR destination. Set the flag uniformly,
11084 as the consumer will inspect it only for the destination operand. */
11085 if (bytemode
!= mask_mode
&& ins
->vex
.mask_register_specifier
)
11086 ins
->illegal_masking
= true;
11088 USED_REX (rexmask
);
11089 if (ins
->rex
& rexmask
)
11099 names
= att_names8rex
;
11101 names
= att_names8
;
11104 names
= att_names16
;
11109 names
= att_names32
;
11112 names
= att_names64
;
11116 names
= ins
->address_mode
== mode_64bit
? att_names64
: att_names32
;
11119 case bnd_swap_mode
:
11122 oappend (ins
, "(bad)");
11125 names
= att_names_bnd
;
11128 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
11130 names
= att_names64
;
11133 /* Fall through. */
11135 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
11136 || (ins
->rex
& REX_W
)))
11138 names
= att_names64
;
11142 /* Fall through. */
11147 if (ins
->rex
& REX_W
)
11148 names
= att_names64
;
11149 else if (bytemode
!= v_mode
&& bytemode
!= v_swap_mode
)
11150 names
= att_names32
;
11153 if (sizeflag
& DFLAG
)
11154 names
= att_names32
;
11156 names
= att_names16
;
11157 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11161 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
11162 names
= att_names16
;
11164 names
= att_names32
;
11165 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11168 names
= (ins
->address_mode
== mode_64bit
11169 ? att_names64
: att_names32
);
11170 if (!(ins
->prefixes
& PREFIX_ADDR
))
11171 names
= (ins
->address_mode
== mode_16bit
11172 ? att_names16
: names
);
11175 /* Remove "addr16/addr32". */
11176 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
11177 names
= (ins
->address_mode
!= mode_32bit
11178 ? att_names32
: att_names16
);
11179 ins
->used_prefixes
|= PREFIX_ADDR
;
11186 oappend (ins
, "(bad)");
11189 names
= att_names_mask
;
11194 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
11197 oappend_register (ins
, names
[reg
]);
11201 get8s (instr_info
*ins
, bfd_vma
*res
)
11203 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
11205 *res
= ((bfd_vma
) *ins
->codep
++ ^ 0x80) - 0x80;
11210 get16 (instr_info
*ins
, bfd_vma
*res
)
11212 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
11214 *res
= *ins
->codep
++;
11215 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
11220 get16s (instr_info
*ins
, bfd_vma
*res
)
11222 if (!get16 (ins
, res
))
11224 *res
= (*res
^ 0x8000) - 0x8000;
11229 get32 (instr_info
*ins
, bfd_vma
*res
)
11231 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
11233 *res
= *ins
->codep
++;
11234 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
11235 *res
|= (bfd_vma
) *ins
->codep
++ << 16;
11236 *res
|= (bfd_vma
) *ins
->codep
++ << 24;
11241 get32s (instr_info
*ins
, bfd_vma
*res
)
11243 if (!get32 (ins
, res
))
11246 *res
= (*res
^ ((bfd_vma
) 1 << 31)) - ((bfd_vma
) 1 << 31);
11252 get64 (instr_info
*ins
, uint64_t *res
)
11257 if (!fetch_code (ins
->info
, ins
->codep
+ 8))
11260 a
|= (unsigned int) *ins
->codep
++ << 8;
11261 a
|= (unsigned int) *ins
->codep
++ << 16;
11262 a
|= (unsigned int) *ins
->codep
++ << 24;
11264 b
|= (unsigned int) *ins
->codep
++ << 8;
11265 b
|= (unsigned int) *ins
->codep
++ << 16;
11266 b
|= (unsigned int) *ins
->codep
++ << 24;
11267 *res
= a
+ ((uint64_t) b
<< 32);
11272 set_op (instr_info
*ins
, bfd_vma op
, bool riprel
)
11274 ins
->op_index
[ins
->op_ad
] = ins
->op_ad
;
11275 if (ins
->address_mode
== mode_64bit
)
11276 ins
->op_address
[ins
->op_ad
] = op
;
11277 else /* Mask to get a 32-bit address. */
11278 ins
->op_address
[ins
->op_ad
] = op
& 0xffffffff;
11279 ins
->op_riprel
[ins
->op_ad
] = riprel
;
11283 BadOp (instr_info
*ins
)
11285 /* Throw away prefixes and 1st. opcode byte. */
11286 struct dis_private
*priv
= ins
->info
->private_data
;
11288 ins
->codep
= priv
->the_buffer
+ ins
->nr_prefixes
+ ins
->need_vex
+ 1;
11289 ins
->obufp
= stpcpy (ins
->obufp
, "(bad)");
11294 OP_Skip_MODRM (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
11295 int sizeflag ATTRIBUTE_UNUSED
)
11297 if (ins
->modrm
.mod
!= 3)
11298 return BadOp (ins
);
11300 /* Skip mod/rm byte. */
11307 OP_E_memory (instr_info
*ins
, int bytemode
, int sizeflag
)
11309 int add
= (ins
->rex
& REX_B
) ? 8 : 0;
11316 /* Zeroing-masking is invalid for memory destinations. Set the flag
11317 uniformly, as the consumer will inspect it only for the destination
11319 if (ins
->vex
.zeroing
)
11320 ins
->illegal_masking
= true;
11334 if (ins
->address_mode
!= mode_64bit
)
11342 case vex_vsib_d_w_dq_mode
:
11343 case vex_vsib_q_w_dq_mode
:
11344 case evex_x_gscat_mode
:
11345 shift
= ins
->vex
.w
? 3 : 2;
11348 case evex_half_bcst_xmmqh_mode
:
11349 case evex_half_bcst_xmmqdh_mode
:
11352 shift
= ins
->vex
.w
? 2 : 1;
11355 /* Fall through. */
11357 case evex_half_bcst_xmmq_mode
:
11360 shift
= ins
->vex
.w
? 3 : 2;
11363 /* Fall through. */
11368 case evex_x_nobcst_mode
:
11370 switch (ins
->vex
.length
)
11384 /* Make necessary corrections to shift for modes that need it. */
11385 if (bytemode
== xmmq_mode
11386 || bytemode
== evex_half_bcst_xmmqh_mode
11387 || bytemode
== evex_half_bcst_xmmq_mode
11388 || (bytemode
== ymmq_mode
&& ins
->vex
.length
== 128))
11390 else if (bytemode
== xmmqd_mode
11391 || bytemode
== evex_half_bcst_xmmqdh_mode
)
11393 else if (bytemode
== xmmdw_mode
)
11407 shift
= ins
->vex
.w
? 1 : 0;
11417 if (ins
->intel_syntax
)
11418 intel_operand_size (ins
, bytemode
, sizeflag
);
11421 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
11423 /* 32/64 bit address mode */
11432 int addr32flag
= !((sizeflag
& AFLAG
)
11433 || bytemode
== v_bnd_mode
11434 || bytemode
== v_bndmk_mode
11435 || bytemode
== bnd_mode
11436 || bytemode
== bnd_swap_mode
);
11437 bool check_gather
= false;
11438 const char (*indexes
)[8] = NULL
;
11441 base
= ins
->modrm
.rm
;
11445 vindex
= ins
->sib
.index
;
11447 if (ins
->rex
& REX_X
)
11451 case vex_vsib_d_w_dq_mode
:
11452 case vex_vsib_q_w_dq_mode
:
11453 if (!ins
->need_vex
)
11459 check_gather
= ins
->obufp
== ins
->op_out
[1];
11462 switch (ins
->vex
.length
)
11465 indexes
= att_names_xmm
;
11469 || bytemode
== vex_vsib_q_w_dq_mode
)
11470 indexes
= att_names_ymm
;
11472 indexes
= att_names_xmm
;
11476 || bytemode
== vex_vsib_q_w_dq_mode
)
11477 indexes
= att_names_zmm
;
11479 indexes
= att_names_ymm
;
11487 indexes
= ins
->address_mode
== mode_64bit
&& !addr32flag
11488 ? att_names64
: att_names32
;
11491 scale
= ins
->sib
.scale
;
11492 base
= ins
->sib
.base
;
11497 /* Check for mandatory SIB. */
11498 if (bytemode
== vex_vsib_d_w_dq_mode
11499 || bytemode
== vex_vsib_q_w_dq_mode
11500 || bytemode
== vex_sibmem_mode
)
11502 oappend (ins
, "(bad)");
11506 rbase
= base
+ add
;
11508 switch (ins
->modrm
.mod
)
11514 if (ins
->address_mode
== mode_64bit
&& !ins
->has_sib
)
11516 if (!get32s (ins
, &disp
))
11518 if (riprel
&& bytemode
== v_bndmk_mode
)
11520 oappend (ins
, "(bad)");
11526 if (!get8s (ins
, &disp
))
11528 if (ins
->vex
.evex
&& shift
> 0)
11532 if (!get32s (ins
, &disp
))
11542 && ins
->address_mode
!= mode_16bit
)
11544 if (ins
->address_mode
== mode_64bit
)
11548 /* Without base nor index registers, zero-extend the
11549 lower 32-bit displacement to 64 bits. */
11550 disp
&= 0xffffffff;
11557 /* In 32-bit mode, we need index register to tell [offset]
11558 from [eiz*1 + offset]. */
11563 havedisp
= (havebase
11565 || (ins
->has_sib
&& (indexes
|| scale
!= 0)));
11567 if (!ins
->intel_syntax
)
11568 if (ins
->modrm
.mod
!= 0 || base
== 5)
11570 if (havedisp
|| riprel
)
11571 print_displacement (ins
, disp
);
11573 print_operand_value (ins
, disp
, dis_style_address_offset
);
11576 set_op (ins
, disp
, true);
11577 oappend_char (ins
, '(');
11578 oappend_with_style (ins
, !addr32flag
? "%rip" : "%eip",
11579 dis_style_register
);
11580 oappend_char (ins
, ')');
11584 if ((havebase
|| indexes
|| needindex
|| needaddr32
|| riprel
)
11585 && (ins
->address_mode
!= mode_64bit
11586 || ((bytemode
!= v_bnd_mode
)
11587 && (bytemode
!= v_bndmk_mode
)
11588 && (bytemode
!= bnd_mode
)
11589 && (bytemode
!= bnd_swap_mode
))))
11590 ins
->used_prefixes
|= PREFIX_ADDR
;
11592 if (havedisp
|| (ins
->intel_syntax
&& riprel
))
11594 oappend_char (ins
, ins
->open_char
);
11595 if (ins
->intel_syntax
&& riprel
)
11597 set_op (ins
, disp
, true);
11598 oappend_with_style (ins
, !addr32flag
? "rip" : "eip",
11599 dis_style_register
);
11604 (ins
->address_mode
== mode_64bit
&& !addr32flag
11605 ? att_names64
: att_names32
)[rbase
]);
11608 /* ESP/RSP won't allow index. If base isn't ESP/RSP,
11609 print index to tell base + index from base. */
11613 || (havebase
&& base
!= ESP_REG_NUM
))
11615 if (!ins
->intel_syntax
|| havebase
)
11616 oappend_char (ins
, ins
->separator_char
);
11619 if (ins
->address_mode
== mode_64bit
|| vindex
< 16)
11620 oappend_register (ins
, indexes
[vindex
]);
11622 oappend (ins
, "(bad)");
11625 oappend_register (ins
,
11626 ins
->address_mode
== mode_64bit
11631 oappend_char (ins
, ins
->scale_char
);
11632 oappend_char_with_style (ins
, '0' + (1 << scale
),
11633 dis_style_immediate
);
11636 if (ins
->intel_syntax
11637 && (disp
|| ins
->modrm
.mod
!= 0 || base
== 5))
11639 if (!havedisp
|| (bfd_signed_vma
) disp
>= 0)
11640 oappend_char (ins
, '+');
11642 print_displacement (ins
, disp
);
11644 print_operand_value (ins
, disp
, dis_style_address_offset
);
11647 oappend_char (ins
, ins
->close_char
);
11651 /* Both XMM/YMM/ZMM registers must be distinct. */
11652 int modrm_reg
= ins
->modrm
.reg
;
11654 if (ins
->rex
& REX_R
)
11658 if (vindex
== modrm_reg
)
11659 oappend (ins
, "/(bad)");
11662 else if (ins
->intel_syntax
)
11664 if (ins
->modrm
.mod
!= 0 || base
== 5)
11666 if (!ins
->active_seg_prefix
)
11668 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
11669 oappend (ins
, ":");
11671 print_operand_value (ins
, disp
, dis_style_text
);
11675 else if (bytemode
== v_bnd_mode
11676 || bytemode
== v_bndmk_mode
11677 || bytemode
== bnd_mode
11678 || bytemode
== bnd_swap_mode
11679 || bytemode
== vex_vsib_d_w_dq_mode
11680 || bytemode
== vex_vsib_q_w_dq_mode
)
11682 oappend (ins
, "(bad)");
11687 /* 16 bit address mode */
11690 ins
->used_prefixes
|= ins
->prefixes
& PREFIX_ADDR
;
11691 switch (ins
->modrm
.mod
)
11694 if (ins
->modrm
.rm
== 6)
11697 if (!get16s (ins
, &disp
))
11702 if (!get8s (ins
, &disp
))
11704 if (ins
->vex
.evex
&& shift
> 0)
11709 if (!ins
->intel_syntax
)
11710 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6)
11711 print_displacement (ins
, disp
);
11713 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 6)
11715 oappend_char (ins
, ins
->open_char
);
11716 oappend (ins
, ins
->intel_syntax
? intel_index16
[ins
->modrm
.rm
]
11717 : att_index16
[ins
->modrm
.rm
]);
11718 if (ins
->intel_syntax
11719 && (disp
|| ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6))
11721 if ((bfd_signed_vma
) disp
>= 0)
11722 oappend_char (ins
, '+');
11723 print_displacement (ins
, disp
);
11726 oappend_char (ins
, ins
->close_char
);
11728 else if (ins
->intel_syntax
)
11730 if (!ins
->active_seg_prefix
)
11732 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
11733 oappend (ins
, ":");
11735 print_operand_value (ins
, disp
& 0xffff, dis_style_text
);
11740 ins
->evex_used
|= EVEX_b_used
;
11742 /* Broadcast can only ever be valid for memory sources. */
11743 if (ins
->obufp
== ins
->op_out
[0])
11744 ins
->vex
.no_broadcast
= true;
11746 if (!ins
->vex
.no_broadcast
11747 && (!ins
->intel_syntax
|| !(ins
->evex_used
& EVEX_len_used
)))
11749 if (bytemode
== xh_mode
)
11751 switch (ins
->vex
.length
)
11754 oappend (ins
, "{1to8}");
11757 oappend (ins
, "{1to16}");
11760 oappend (ins
, "{1to32}");
11766 else if (bytemode
== q_mode
11767 || bytemode
== ymmq_mode
)
11768 ins
->vex
.no_broadcast
= true;
11769 else if (ins
->vex
.w
11770 || bytemode
== evex_half_bcst_xmmqdh_mode
11771 || bytemode
== evex_half_bcst_xmmq_mode
)
11773 switch (ins
->vex
.length
)
11776 oappend (ins
, "{1to2}");
11779 oappend (ins
, "{1to4}");
11782 oappend (ins
, "{1to8}");
11788 else if (bytemode
== x_mode
11789 || bytemode
== evex_half_bcst_xmmqh_mode
)
11791 switch (ins
->vex
.length
)
11794 oappend (ins
, "{1to4}");
11797 oappend (ins
, "{1to8}");
11800 oappend (ins
, "{1to16}");
11807 ins
->vex
.no_broadcast
= true;
11809 if (ins
->vex
.no_broadcast
)
11810 oappend (ins
, "{bad}");
11817 OP_E (instr_info
*ins
, int bytemode
, int sizeflag
)
11819 /* Skip mod/rm byte. */
11823 if (ins
->modrm
.mod
== 3)
11825 if ((sizeflag
& SUFFIX_ALWAYS
)
11826 && (bytemode
== b_swap_mode
11827 || bytemode
== bnd_swap_mode
11828 || bytemode
== v_swap_mode
))
11829 swap_operand (ins
);
11831 print_register (ins
, ins
->modrm
.rm
, REX_B
, bytemode
, sizeflag
);
11835 /* Masking is invalid for insns with GPR-like memory destination. Set the
11836 flag uniformly, as the consumer will inspect it only for the destination
11838 if (ins
->vex
.mask_register_specifier
)
11839 ins
->illegal_masking
= true;
11841 return OP_E_memory (ins
, bytemode
, sizeflag
);
11845 OP_indirE (instr_info
*ins
, int bytemode
, int sizeflag
)
11847 if (ins
->modrm
.mod
== 3 && bytemode
== f_mode
)
11848 /* bad lcall/ljmp */
11849 return BadOp (ins
);
11850 if (!ins
->intel_syntax
)
11851 oappend (ins
, "*");
11852 return OP_E (ins
, bytemode
, sizeflag
);
11856 OP_G (instr_info
*ins
, int bytemode
, int sizeflag
)
11858 if (ins
->vex
.evex
&& !ins
->vex
.r
&& ins
->address_mode
== mode_64bit
)
11859 oappend (ins
, "(bad)");
11861 print_register (ins
, ins
->modrm
.reg
, REX_R
, bytemode
, sizeflag
);
11866 OP_REG (instr_info
*ins
, int code
, int sizeflag
)
11873 case es_reg
: case ss_reg
: case cs_reg
:
11874 case ds_reg
: case fs_reg
: case gs_reg
:
11875 oappend_register (ins
, att_names_seg
[code
- es_reg
]);
11880 if (ins
->rex
& REX_B
)
11887 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
11888 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
11889 s
= att_names16
[code
- ax_reg
+ add
];
11891 case ah_reg
: case ch_reg
: case dh_reg
: case bh_reg
:
11893 /* Fall through. */
11894 case al_reg
: case cl_reg
: case dl_reg
: case bl_reg
:
11896 s
= att_names8rex
[code
- al_reg
+ add
];
11898 s
= att_names8
[code
- al_reg
];
11900 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
11901 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
11902 if (ins
->address_mode
== mode_64bit
11903 && ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
11905 s
= att_names64
[code
- rAX_reg
+ add
];
11908 code
+= eAX_reg
- rAX_reg
;
11909 /* Fall through. */
11910 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
11911 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
11913 if (ins
->rex
& REX_W
)
11914 s
= att_names64
[code
- eAX_reg
+ add
];
11917 if (sizeflag
& DFLAG
)
11918 s
= att_names32
[code
- eAX_reg
+ add
];
11920 s
= att_names16
[code
- eAX_reg
+ add
];
11921 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11925 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
11928 oappend_register (ins
, s
);
11933 OP_IMREG (instr_info
*ins
, int code
, int sizeflag
)
11940 if (!ins
->intel_syntax
)
11942 oappend (ins
, "(%dx)");
11945 s
= att_names16
[dx_reg
- ax_reg
];
11947 case al_reg
: case cl_reg
:
11948 s
= att_names8
[code
- al_reg
];
11952 if (ins
->rex
& REX_W
)
11957 /* Fall through. */
11958 case z_mode_ax_reg
:
11959 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
11963 if (!(ins
->rex
& REX_W
))
11964 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11967 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
11970 oappend_register (ins
, s
);
11975 OP_I (instr_info
*ins
, int bytemode
, int sizeflag
)
11982 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
11984 op
= *ins
->codep
++;
11988 if (ins
->rex
& REX_W
)
11990 if (!get32s (ins
, &op
))
11995 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11996 if (sizeflag
& DFLAG
)
11999 if (!get32 (ins
, &op
))
12004 /* Fall through. */
12006 if (!get16 (ins
, &op
))
12012 if (ins
->intel_syntax
)
12013 oappend (ins
, "1");
12016 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12020 oappend_immediate (ins
, op
);
12025 OP_I64 (instr_info
*ins
, int bytemode
, int sizeflag
)
12029 if (bytemode
!= v_mode
|| ins
->address_mode
!= mode_64bit
12030 || !(ins
->rex
& REX_W
))
12031 return OP_I (ins
, bytemode
, sizeflag
);
12035 if (!get64 (ins
, &op
))
12038 oappend_immediate (ins
, op
);
12043 OP_sI (instr_info
*ins
, int bytemode
, int sizeflag
)
12051 if (!get8s (ins
, &op
))
12053 if (bytemode
== b_T_mode
)
12055 if (ins
->address_mode
!= mode_64bit
12056 || !((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
12058 /* The operand-size prefix is overridden by a REX prefix. */
12059 if ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
))
12067 if (!(ins
->rex
& REX_W
))
12069 if (sizeflag
& DFLAG
)
12077 /* The operand-size prefix is overridden by a REX prefix. */
12078 if (!(sizeflag
& DFLAG
) && !(ins
->rex
& REX_W
))
12080 if (!get16 (ins
, &op
))
12083 else if (!get32s (ins
, &op
))
12087 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12091 oappend_immediate (ins
, op
);
12096 OP_J (instr_info
*ins
, int bytemode
, int sizeflag
)
12100 bfd_vma segment
= 0;
12105 if (!get8s (ins
, &disp
))
12110 if ((sizeflag
& DFLAG
)
12111 || (ins
->address_mode
== mode_64bit
12112 && ((ins
->isa64
== intel64
&& bytemode
!= dqw_mode
)
12113 || (ins
->rex
& REX_W
))))
12115 if (!get32s (ins
, &disp
))
12120 if (!get16s (ins
, &disp
))
12122 /* In 16bit mode, address is wrapped around at 64k within
12123 the same segment. Otherwise, a data16 prefix on a jump
12124 instruction means that the pc is masked to 16 bits after
12125 the displacement is added! */
12127 if ((ins
->prefixes
& PREFIX_DATA
) == 0)
12128 segment
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
))
12129 & ~((bfd_vma
) 0xffff));
12131 if (ins
->address_mode
!= mode_64bit
12132 || (ins
->isa64
!= intel64
&& !(ins
->rex
& REX_W
)))
12133 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12136 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12139 disp
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
) + disp
) & mask
)
12141 set_op (ins
, disp
, false);
12142 print_operand_value (ins
, disp
, dis_style_text
);
12147 OP_SEG (instr_info
*ins
, int bytemode
, int sizeflag
)
12149 if (bytemode
== w_mode
)
12151 oappend_register (ins
, att_names_seg
[ins
->modrm
.reg
]);
12154 return OP_E (ins
, ins
->modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
12158 OP_DIR (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
12160 bfd_vma seg
, offset
;
12164 if (sizeflag
& DFLAG
)
12166 if (!get32 (ins
, &offset
))
12169 else if (!get16 (ins
, &offset
))
12171 if (!get16 (ins
, &seg
))
12173 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12175 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
12176 ins
->intel_syntax
? "0x%x:0x%x" : "$0x%x,$0x%x",
12177 (unsigned) seg
, (unsigned) offset
);
12178 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12180 oappend (ins
, scratch
);
12185 OP_OFF (instr_info
*ins
, int bytemode
, int sizeflag
)
12189 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
12190 intel_operand_size (ins
, bytemode
, sizeflag
);
12193 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
12195 if (!get32 (ins
, &off
))
12200 if (!get16 (ins
, &off
))
12204 if (ins
->intel_syntax
)
12206 if (!ins
->active_seg_prefix
)
12208 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12209 oappend (ins
, ":");
12212 print_operand_value (ins
, off
, dis_style_address_offset
);
12217 OP_OFF64 (instr_info
*ins
, int bytemode
, int sizeflag
)
12221 if (ins
->address_mode
!= mode_64bit
12222 || (ins
->prefixes
& PREFIX_ADDR
))
12223 return OP_OFF (ins
, bytemode
, sizeflag
);
12225 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
12226 intel_operand_size (ins
, bytemode
, sizeflag
);
12229 if (!get64 (ins
, &off
))
12232 if (ins
->intel_syntax
)
12234 if (!ins
->active_seg_prefix
)
12236 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12237 oappend (ins
, ":");
12240 print_operand_value (ins
, off
, dis_style_address_offset
);
12245 ptr_reg (instr_info
*ins
, int code
, int sizeflag
)
12249 *ins
->obufp
++ = ins
->open_char
;
12250 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
12251 if (ins
->address_mode
== mode_64bit
)
12253 if (!(sizeflag
& AFLAG
))
12254 s
= att_names32
[code
- eAX_reg
];
12256 s
= att_names64
[code
- eAX_reg
];
12258 else if (sizeflag
& AFLAG
)
12259 s
= att_names32
[code
- eAX_reg
];
12261 s
= att_names16
[code
- eAX_reg
];
12262 oappend_register (ins
, s
);
12263 oappend_char (ins
, ins
->close_char
);
12267 OP_ESreg (instr_info
*ins
, int code
, int sizeflag
)
12269 if (ins
->intel_syntax
)
12271 switch (ins
->codep
[-1])
12273 case 0x6d: /* insw/insl */
12274 intel_operand_size (ins
, z_mode
, sizeflag
);
12276 case 0xa5: /* movsw/movsl/movsq */
12277 case 0xa7: /* cmpsw/cmpsl/cmpsq */
12278 case 0xab: /* stosw/stosl */
12279 case 0xaf: /* scasw/scasl */
12280 intel_operand_size (ins
, v_mode
, sizeflag
);
12283 intel_operand_size (ins
, b_mode
, sizeflag
);
12286 oappend_register (ins
, att_names_seg
[0]);
12287 oappend_char (ins
, ':');
12288 ptr_reg (ins
, code
, sizeflag
);
12293 OP_DSreg (instr_info
*ins
, int code
, int sizeflag
)
12295 if (ins
->intel_syntax
)
12297 switch (ins
->codep
[-1])
12299 case 0x6f: /* outsw/outsl */
12300 intel_operand_size (ins
, z_mode
, sizeflag
);
12302 case 0xa5: /* movsw/movsl/movsq */
12303 case 0xa7: /* cmpsw/cmpsl/cmpsq */
12304 case 0xad: /* lodsw/lodsl/lodsq */
12305 intel_operand_size (ins
, v_mode
, sizeflag
);
12308 intel_operand_size (ins
, b_mode
, sizeflag
);
12311 /* Set ins->active_seg_prefix to PREFIX_DS if it is unset so that the
12312 default segment register DS is printed. */
12313 if (!ins
->active_seg_prefix
)
12314 ins
->active_seg_prefix
= PREFIX_DS
;
12316 ptr_reg (ins
, code
, sizeflag
);
12321 OP_C (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12322 int sizeflag ATTRIBUTE_UNUSED
)
12327 if (ins
->rex
& REX_R
)
12332 else if (ins
->address_mode
!= mode_64bit
&& (ins
->prefixes
& PREFIX_LOCK
))
12334 ins
->all_prefixes
[ins
->last_lock_prefix
] = 0;
12335 ins
->used_prefixes
|= PREFIX_LOCK
;
12340 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%cr%d",
12341 ins
->modrm
.reg
+ add
);
12342 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12344 oappend_register (ins
, scratch
);
12349 OP_D (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12350 int sizeflag ATTRIBUTE_UNUSED
)
12356 if (ins
->rex
& REX_R
)
12360 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
12361 ins
->intel_syntax
? "dr%d" : "%%db%d",
12362 ins
->modrm
.reg
+ add
);
12363 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12365 oappend (ins
, scratch
);
12370 OP_T (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12371 int sizeflag ATTRIBUTE_UNUSED
)
12376 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%tr%d", ins
->modrm
.reg
);
12377 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12379 oappend_register (ins
, scratch
);
12384 OP_MMX (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12385 int sizeflag ATTRIBUTE_UNUSED
)
12387 int reg
= ins
->modrm
.reg
;
12388 const char (*names
)[8];
12390 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12391 if (ins
->prefixes
& PREFIX_DATA
)
12393 names
= att_names_xmm
;
12395 if (ins
->rex
& REX_R
)
12399 names
= att_names_mm
;
12400 oappend_register (ins
, names
[reg
]);
12405 print_vector_reg (instr_info
*ins
, unsigned int reg
, int bytemode
)
12407 const char (*names
)[8];
12409 if (bytemode
== xmmq_mode
12410 || bytemode
== evex_half_bcst_xmmqh_mode
12411 || bytemode
== evex_half_bcst_xmmq_mode
)
12413 switch (ins
->vex
.length
)
12418 names
= att_names_xmm
;
12421 names
= att_names_ymm
;
12422 ins
->evex_used
|= EVEX_len_used
;
12428 else if (bytemode
== ymm_mode
)
12429 names
= att_names_ymm
;
12430 else if (bytemode
== tmm_mode
)
12434 oappend (ins
, "(bad)");
12437 names
= att_names_tmm
;
12439 else if (ins
->need_vex
12440 && bytemode
!= xmm_mode
12441 && bytemode
!= scalar_mode
12442 && bytemode
!= xmmdw_mode
12443 && bytemode
!= xmmqd_mode
12444 && bytemode
!= evex_half_bcst_xmmqdh_mode
12445 && bytemode
!= w_swap_mode
12446 && bytemode
!= b_mode
12447 && bytemode
!= w_mode
12448 && bytemode
!= d_mode
12449 && bytemode
!= q_mode
)
12451 ins
->evex_used
|= EVEX_len_used
;
12452 switch (ins
->vex
.length
)
12455 names
= att_names_xmm
;
12459 || bytemode
!= vex_vsib_q_w_dq_mode
)
12460 names
= att_names_ymm
;
12462 names
= att_names_xmm
;
12466 || bytemode
!= vex_vsib_q_w_dq_mode
)
12467 names
= att_names_zmm
;
12469 names
= att_names_ymm
;
12476 names
= att_names_xmm
;
12477 oappend_register (ins
, names
[reg
]);
12481 OP_XMM (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
12483 unsigned int reg
= ins
->modrm
.reg
;
12486 if (ins
->rex
& REX_R
)
12494 if (bytemode
== tmm_mode
)
12495 ins
->modrm
.reg
= reg
;
12496 else if (bytemode
== scalar_mode
)
12497 ins
->vex
.no_broadcast
= true;
12499 print_vector_reg (ins
, reg
, bytemode
);
12504 OP_EM (instr_info
*ins
, int bytemode
, int sizeflag
)
12507 const char (*names
)[8];
12509 if (ins
->modrm
.mod
!= 3)
12511 if (ins
->intel_syntax
12512 && (bytemode
== v_mode
|| bytemode
== v_swap_mode
))
12514 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
12515 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12517 return OP_E (ins
, bytemode
, sizeflag
);
12520 if ((sizeflag
& SUFFIX_ALWAYS
) && bytemode
== v_swap_mode
)
12521 swap_operand (ins
);
12523 /* Skip mod/rm byte. */
12526 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12527 reg
= ins
->modrm
.rm
;
12528 if (ins
->prefixes
& PREFIX_DATA
)
12530 names
= att_names_xmm
;
12532 if (ins
->rex
& REX_B
)
12536 names
= att_names_mm
;
12537 oappend_register (ins
, names
[reg
]);
12541 /* cvt* are the only instructions in sse2 which have
12542 both SSE and MMX operands and also have 0x66 prefix
12543 in their opcode. 0x66 was originally used to differentiate
12544 between SSE and MMX instruction(operands). So we have to handle the
12545 cvt* separately using OP_EMC and OP_MXC */
12547 OP_EMC (instr_info
*ins
, int bytemode
, int sizeflag
)
12549 if (ins
->modrm
.mod
!= 3)
12551 if (ins
->intel_syntax
&& bytemode
== v_mode
)
12553 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
12554 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12556 return OP_E (ins
, bytemode
, sizeflag
);
12559 /* Skip mod/rm byte. */
12562 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12563 oappend_register (ins
, att_names_mm
[ins
->modrm
.rm
]);
12568 OP_MXC (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12569 int sizeflag ATTRIBUTE_UNUSED
)
12571 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12572 oappend_register (ins
, att_names_mm
[ins
->modrm
.reg
]);
12577 OP_EX (instr_info
*ins
, int bytemode
, int sizeflag
)
12581 /* Skip mod/rm byte. */
12585 if (bytemode
== dq_mode
)
12586 bytemode
= ins
->vex
.w
? q_mode
: d_mode
;
12588 if (ins
->modrm
.mod
!= 3)
12589 return OP_E_memory (ins
, bytemode
, sizeflag
);
12591 reg
= ins
->modrm
.rm
;
12593 if (ins
->rex
& REX_B
)
12598 if ((ins
->rex
& REX_X
))
12602 if ((sizeflag
& SUFFIX_ALWAYS
)
12603 && (bytemode
== x_swap_mode
12604 || bytemode
== w_swap_mode
12605 || bytemode
== d_swap_mode
12606 || bytemode
== q_swap_mode
))
12607 swap_operand (ins
);
12609 if (bytemode
== tmm_mode
)
12610 ins
->modrm
.rm
= reg
;
12612 print_vector_reg (ins
, reg
, bytemode
);
12617 OP_R (instr_info
*ins
, int bytemode
, int sizeflag
)
12619 if (ins
->modrm
.mod
!= 3)
12620 return BadOp (ins
);
12627 return OP_E (ins
, bytemode
, sizeflag
);
12629 return OP_EM (ins
, x_mode
, sizeflag
);
12631 if (ins
->vex
.length
<= 128)
12633 return BadOp (ins
);
12636 return OP_EX (ins
, bytemode
, sizeflag
);
12640 OP_M (instr_info
*ins
, int bytemode
, int sizeflag
)
12642 /* Skip mod/rm byte. */
12646 if (ins
->modrm
.mod
== 3)
12647 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
12648 return BadOp (ins
);
12650 if (bytemode
== x_mode
)
12651 ins
->vex
.no_broadcast
= true;
12653 return OP_E_memory (ins
, bytemode
, sizeflag
);
12657 OP_0f07 (instr_info
*ins
, int bytemode
, int sizeflag
)
12659 if (ins
->modrm
.mod
!= 3 || ins
->modrm
.rm
!= 0)
12660 return BadOp (ins
);
12661 return OP_E (ins
, bytemode
, sizeflag
);
12664 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
12665 32bit mode and "xchg %rax,%rax" in 64bit mode. */
12668 NOP_Fixup (instr_info
*ins
, int opnd
, int sizeflag
)
12670 if ((ins
->prefixes
& PREFIX_DATA
) == 0 && (ins
->rex
& REX_B
) == 0)
12672 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop");
12676 return OP_REG (ins
, eAX_reg
, sizeflag
);
12677 return OP_IMREG (ins
, eAX_reg
, sizeflag
);
12680 static const char *const Suffix3DNow
[] = {
12681 /* 00 */ NULL
, NULL
, NULL
, NULL
,
12682 /* 04 */ NULL
, NULL
, NULL
, NULL
,
12683 /* 08 */ NULL
, NULL
, NULL
, NULL
,
12684 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
12685 /* 10 */ NULL
, NULL
, NULL
, NULL
,
12686 /* 14 */ NULL
, NULL
, NULL
, NULL
,
12687 /* 18 */ NULL
, NULL
, NULL
, NULL
,
12688 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
12689 /* 20 */ NULL
, NULL
, NULL
, NULL
,
12690 /* 24 */ NULL
, NULL
, NULL
, NULL
,
12691 /* 28 */ NULL
, NULL
, NULL
, NULL
,
12692 /* 2C */ NULL
, NULL
, NULL
, NULL
,
12693 /* 30 */ NULL
, NULL
, NULL
, NULL
,
12694 /* 34 */ NULL
, NULL
, NULL
, NULL
,
12695 /* 38 */ NULL
, NULL
, NULL
, NULL
,
12696 /* 3C */ NULL
, NULL
, NULL
, NULL
,
12697 /* 40 */ NULL
, NULL
, NULL
, NULL
,
12698 /* 44 */ NULL
, NULL
, NULL
, NULL
,
12699 /* 48 */ NULL
, NULL
, NULL
, NULL
,
12700 /* 4C */ NULL
, NULL
, NULL
, NULL
,
12701 /* 50 */ NULL
, NULL
, NULL
, NULL
,
12702 /* 54 */ NULL
, NULL
, NULL
, NULL
,
12703 /* 58 */ NULL
, NULL
, NULL
, NULL
,
12704 /* 5C */ NULL
, NULL
, NULL
, NULL
,
12705 /* 60 */ NULL
, NULL
, NULL
, NULL
,
12706 /* 64 */ NULL
, NULL
, NULL
, NULL
,
12707 /* 68 */ NULL
, NULL
, NULL
, NULL
,
12708 /* 6C */ NULL
, NULL
, NULL
, NULL
,
12709 /* 70 */ NULL
, NULL
, NULL
, NULL
,
12710 /* 74 */ NULL
, NULL
, NULL
, NULL
,
12711 /* 78 */ NULL
, NULL
, NULL
, NULL
,
12712 /* 7C */ NULL
, NULL
, NULL
, NULL
,
12713 /* 80 */ NULL
, NULL
, NULL
, NULL
,
12714 /* 84 */ NULL
, NULL
, NULL
, NULL
,
12715 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
12716 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
12717 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
12718 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
12719 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
12720 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
12721 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
12722 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
12723 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
12724 /* AC */ NULL
, NULL
, "pfacc", NULL
,
12725 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
12726 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
12727 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
12728 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
12729 /* C0 */ NULL
, NULL
, NULL
, NULL
,
12730 /* C4 */ NULL
, NULL
, NULL
, NULL
,
12731 /* C8 */ NULL
, NULL
, NULL
, NULL
,
12732 /* CC */ NULL
, NULL
, NULL
, NULL
,
12733 /* D0 */ NULL
, NULL
, NULL
, NULL
,
12734 /* D4 */ NULL
, NULL
, NULL
, NULL
,
12735 /* D8 */ NULL
, NULL
, NULL
, NULL
,
12736 /* DC */ NULL
, NULL
, NULL
, NULL
,
12737 /* E0 */ NULL
, NULL
, NULL
, NULL
,
12738 /* E4 */ NULL
, NULL
, NULL
, NULL
,
12739 /* E8 */ NULL
, NULL
, NULL
, NULL
,
12740 /* EC */ NULL
, NULL
, NULL
, NULL
,
12741 /* F0 */ NULL
, NULL
, NULL
, NULL
,
12742 /* F4 */ NULL
, NULL
, NULL
, NULL
,
12743 /* F8 */ NULL
, NULL
, NULL
, NULL
,
12744 /* FC */ NULL
, NULL
, NULL
, NULL
,
12748 OP_3DNowSuffix (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12749 int sizeflag ATTRIBUTE_UNUSED
)
12751 const char *mnemonic
;
12753 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
12755 /* AMD 3DNow! instructions are specified by an opcode suffix in the
12756 place where an 8-bit immediate would normally go. ie. the last
12757 byte of the instruction. */
12758 ins
->obufp
= ins
->mnemonicendp
;
12759 mnemonic
= Suffix3DNow
[*ins
->codep
++];
12761 ins
->obufp
= stpcpy (ins
->obufp
, mnemonic
);
12764 /* Since a variable sized ins->modrm/ins->sib chunk is between the start
12765 of the opcode (0x0f0f) and the opcode suffix, we need to do
12766 all the ins->modrm processing first, and don't know until now that
12767 we have a bad opcode. This necessitates some cleaning up. */
12768 ins
->op_out
[0][0] = '\0';
12769 ins
->op_out
[1][0] = '\0';
12772 ins
->mnemonicendp
= ins
->obufp
;
12776 static const struct op simd_cmp_op
[] =
12778 { STRING_COMMA_LEN ("eq") },
12779 { STRING_COMMA_LEN ("lt") },
12780 { STRING_COMMA_LEN ("le") },
12781 { STRING_COMMA_LEN ("unord") },
12782 { STRING_COMMA_LEN ("neq") },
12783 { STRING_COMMA_LEN ("nlt") },
12784 { STRING_COMMA_LEN ("nle") },
12785 { STRING_COMMA_LEN ("ord") }
12788 static const struct op vex_cmp_op
[] =
12790 { STRING_COMMA_LEN ("eq_uq") },
12791 { STRING_COMMA_LEN ("nge") },
12792 { STRING_COMMA_LEN ("ngt") },
12793 { STRING_COMMA_LEN ("false") },
12794 { STRING_COMMA_LEN ("neq_oq") },
12795 { STRING_COMMA_LEN ("ge") },
12796 { STRING_COMMA_LEN ("gt") },
12797 { STRING_COMMA_LEN ("true") },
12798 { STRING_COMMA_LEN ("eq_os") },
12799 { STRING_COMMA_LEN ("lt_oq") },
12800 { STRING_COMMA_LEN ("le_oq") },
12801 { STRING_COMMA_LEN ("unord_s") },
12802 { STRING_COMMA_LEN ("neq_us") },
12803 { STRING_COMMA_LEN ("nlt_uq") },
12804 { STRING_COMMA_LEN ("nle_uq") },
12805 { STRING_COMMA_LEN ("ord_s") },
12806 { STRING_COMMA_LEN ("eq_us") },
12807 { STRING_COMMA_LEN ("nge_uq") },
12808 { STRING_COMMA_LEN ("ngt_uq") },
12809 { STRING_COMMA_LEN ("false_os") },
12810 { STRING_COMMA_LEN ("neq_os") },
12811 { STRING_COMMA_LEN ("ge_oq") },
12812 { STRING_COMMA_LEN ("gt_oq") },
12813 { STRING_COMMA_LEN ("true_us") },
12817 CMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12818 int sizeflag ATTRIBUTE_UNUSED
)
12820 unsigned int cmp_type
;
12822 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
12824 cmp_type
= *ins
->codep
++;
12825 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
))
12828 char *p
= ins
->mnemonicendp
- 2;
12832 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
12833 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
12835 else if (ins
->need_vex
12836 && cmp_type
< ARRAY_SIZE (simd_cmp_op
) + ARRAY_SIZE (vex_cmp_op
))
12839 char *p
= ins
->mnemonicendp
- 2;
12843 cmp_type
-= ARRAY_SIZE (simd_cmp_op
);
12844 sprintf (p
, "%s%s", vex_cmp_op
[cmp_type
].name
, suffix
);
12845 ins
->mnemonicendp
+= vex_cmp_op
[cmp_type
].len
;
12849 /* We have a reserved extension byte. Output it directly. */
12850 oappend_immediate (ins
, cmp_type
);
12856 OP_Mwait (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
12858 /* mwait %eax,%ecx / mwaitx %eax,%ecx,%ebx */
12859 if (!ins
->intel_syntax
)
12861 strcpy (ins
->op_out
[0], att_names32
[0] + ins
->intel_syntax
);
12862 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
12863 if (bytemode
== eBX_reg
)
12864 strcpy (ins
->op_out
[2], att_names32
[3] + ins
->intel_syntax
);
12865 ins
->two_source_ops
= true;
12867 /* Skip mod/rm byte. */
12874 OP_Monitor (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12875 int sizeflag ATTRIBUTE_UNUSED
)
12877 /* monitor %{e,r,}ax,%ecx,%edx" */
12878 if (!ins
->intel_syntax
)
12880 const char (*names
)[8] = (ins
->address_mode
== mode_64bit
12881 ? att_names64
: att_names32
);
12883 if (ins
->prefixes
& PREFIX_ADDR
)
12885 /* Remove "addr16/addr32". */
12886 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
12887 names
= (ins
->address_mode
!= mode_32bit
12888 ? att_names32
: att_names16
);
12889 ins
->used_prefixes
|= PREFIX_ADDR
;
12891 else if (ins
->address_mode
== mode_16bit
)
12892 names
= att_names16
;
12893 strcpy (ins
->op_out
[0], names
[0] + ins
->intel_syntax
);
12894 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
12895 strcpy (ins
->op_out
[2], att_names32
[2] + ins
->intel_syntax
);
12896 ins
->two_source_ops
= true;
12898 /* Skip mod/rm byte. */
12905 REP_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
12907 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
12909 if (ins
->prefixes
& PREFIX_REPZ
)
12910 ins
->all_prefixes
[ins
->last_repz_prefix
] = REP_PREFIX
;
12917 return OP_IMREG (ins
, bytemode
, sizeflag
);
12919 return OP_ESreg (ins
, bytemode
, sizeflag
);
12921 return OP_DSreg (ins
, bytemode
, sizeflag
);
12930 SEP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12931 int sizeflag ATTRIBUTE_UNUSED
)
12933 if (ins
->isa64
!= amd64
)
12936 ins
->obufp
= ins
->obuf
;
12938 ins
->mnemonicendp
= ins
->obufp
;
12943 /* For BND-prefixed instructions 0xF2 prefix should be displayed as
12947 BND_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12948 int sizeflag ATTRIBUTE_UNUSED
)
12950 if (ins
->prefixes
& PREFIX_REPNZ
)
12951 ins
->all_prefixes
[ins
->last_repnz_prefix
] = BND_PREFIX
;
12955 /* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
12959 NOTRACK_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12960 int sizeflag ATTRIBUTE_UNUSED
)
12962 /* Since active_seg_prefix is not set in 64-bit mode, check whether
12963 we've seen a PREFIX_DS. */
12964 if ((ins
->prefixes
& PREFIX_DS
) != 0
12965 && (ins
->address_mode
!= mode_64bit
|| ins
->last_data_prefix
< 0))
12967 /* NOTRACK prefix is only valid on indirect branch instructions.
12968 NB: DATA prefix is unsupported for Intel64. */
12969 ins
->active_seg_prefix
= 0;
12970 ins
->all_prefixes
[ins
->last_seg_prefix
] = NOTRACK_PREFIX
;
12975 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
12976 "xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
12980 HLE_Fixup1 (instr_info
*ins
, int bytemode
, int sizeflag
)
12982 if (ins
->modrm
.mod
!= 3
12983 && (ins
->prefixes
& PREFIX_LOCK
) != 0)
12985 if (ins
->prefixes
& PREFIX_REPZ
)
12986 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
12987 if (ins
->prefixes
& PREFIX_REPNZ
)
12988 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
12991 return OP_E (ins
, bytemode
, sizeflag
);
12994 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
12995 "xacquire"/"xrelease" for memory operand. No check for LOCK prefix.
12999 HLE_Fixup2 (instr_info
*ins
, int bytemode
, int sizeflag
)
13001 if (ins
->modrm
.mod
!= 3)
13003 if (ins
->prefixes
& PREFIX_REPZ
)
13004 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13005 if (ins
->prefixes
& PREFIX_REPNZ
)
13006 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13009 return OP_E (ins
, bytemode
, sizeflag
);
13012 /* Similar to OP_E. But the 0xf3 prefixes should be displayed as
13013 "xrelease" for memory operand. No check for LOCK prefix. */
13016 HLE_Fixup3 (instr_info
*ins
, int bytemode
, int sizeflag
)
13018 if (ins
->modrm
.mod
!= 3
13019 && ins
->last_repz_prefix
> ins
->last_repnz_prefix
13020 && (ins
->prefixes
& PREFIX_REPZ
) != 0)
13021 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13023 return OP_E (ins
, bytemode
, sizeflag
);
13027 CMPXCHG8B_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13030 if (ins
->rex
& REX_W
)
13032 /* Change cmpxchg8b to cmpxchg16b. */
13033 char *p
= ins
->mnemonicendp
- 2;
13034 ins
->mnemonicendp
= stpcpy (p
, "16b");
13037 else if ((ins
->prefixes
& PREFIX_LOCK
) != 0)
13039 if (ins
->prefixes
& PREFIX_REPZ
)
13040 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13041 if (ins
->prefixes
& PREFIX_REPNZ
)
13042 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13045 return OP_M (ins
, bytemode
, sizeflag
);
13049 XMM_Fixup (instr_info
*ins
, int reg
, int sizeflag ATTRIBUTE_UNUSED
)
13051 const char (*names
)[8] = att_names_xmm
;
13055 switch (ins
->vex
.length
)
13060 names
= att_names_ymm
;
13066 oappend_register (ins
, names
[reg
]);
13071 FXSAVE_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13073 /* Add proper suffix to "fxsave" and "fxrstor". */
13075 if (ins
->rex
& REX_W
)
13077 char *p
= ins
->mnemonicendp
;
13081 ins
->mnemonicendp
= p
;
13083 return OP_M (ins
, bytemode
, sizeflag
);
13086 /* Display the destination register operand for instructions with
13090 OP_VEX (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13092 int reg
, modrm_reg
, sib_index
= -1;
13093 const char (*names
)[8];
13095 if (!ins
->need_vex
)
13098 reg
= ins
->vex
.register_specifier
;
13099 ins
->vex
.register_specifier
= 0;
13100 if (ins
->address_mode
!= mode_64bit
)
13102 if (ins
->vex
.evex
&& !ins
->vex
.v
)
13104 oappend (ins
, "(bad)");
13110 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
13116 oappend_register (ins
, att_names_xmm
[reg
]);
13119 case vex_vsib_d_w_dq_mode
:
13120 case vex_vsib_q_w_dq_mode
:
13121 /* This must be the 3rd operand. */
13122 if (ins
->obufp
!= ins
->op_out
[2])
13124 if (ins
->vex
.length
== 128
13125 || (bytemode
!= vex_vsib_d_w_dq_mode
13127 oappend_register (ins
, att_names_xmm
[reg
]);
13129 oappend_register (ins
, att_names_ymm
[reg
]);
13131 /* All 3 XMM/YMM registers must be distinct. */
13132 modrm_reg
= ins
->modrm
.reg
;
13133 if (ins
->rex
& REX_R
)
13136 if (ins
->has_sib
&& ins
->modrm
.rm
== 4)
13138 sib_index
= ins
->sib
.index
;
13139 if (ins
->rex
& REX_X
)
13143 if (reg
== modrm_reg
|| reg
== sib_index
)
13144 strcpy (ins
->obufp
, "/(bad)");
13145 if (modrm_reg
== sib_index
|| modrm_reg
== reg
)
13146 strcat (ins
->op_out
[0], "/(bad)");
13147 if (sib_index
== modrm_reg
|| sib_index
== reg
)
13148 strcat (ins
->op_out
[1], "/(bad)");
13153 /* All 3 TMM registers must be distinct. */
13155 oappend (ins
, "(bad)");
13158 /* This must be the 3rd operand. */
13159 if (ins
->obufp
!= ins
->op_out
[2])
13161 oappend_register (ins
, att_names_tmm
[reg
]);
13162 if (reg
== ins
->modrm
.reg
|| reg
== ins
->modrm
.rm
)
13163 strcpy (ins
->obufp
, "/(bad)");
13166 if (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
13167 || ins
->modrm
.rm
== reg
)
13169 if (ins
->modrm
.reg
<= 8
13170 && (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
))
13171 strcat (ins
->op_out
[0], "/(bad)");
13172 if (ins
->modrm
.rm
<= 8
13173 && (ins
->modrm
.rm
== ins
->modrm
.reg
|| ins
->modrm
.rm
== reg
))
13174 strcat (ins
->op_out
[1], "/(bad)");
13180 switch (ins
->vex
.length
)
13186 names
= att_names_xmm
;
13187 ins
->evex_used
|= EVEX_len_used
;
13190 if (ins
->rex
& REX_W
)
13191 names
= att_names64
;
13193 names
= att_names32
;
13199 oappend (ins
, "(bad)");
13202 names
= att_names_mask
;
13213 names
= att_names_ymm
;
13214 ins
->evex_used
|= EVEX_len_used
;
13220 names
= att_names_mask
;
13223 /* Fall through. */
13225 /* See PR binutils/20893 for a reproducer. */
13226 oappend (ins
, "(bad)");
13231 names
= att_names_zmm
;
13232 ins
->evex_used
|= EVEX_len_used
;
13238 oappend_register (ins
, names
[reg
]);
13243 OP_VexR (instr_info
*ins
, int bytemode
, int sizeflag
)
13245 if (ins
->modrm
.mod
== 3)
13246 return OP_VEX (ins
, bytemode
, sizeflag
);
13251 OP_VexW (instr_info
*ins
, int bytemode
, int sizeflag
)
13253 OP_VEX (ins
, bytemode
, sizeflag
);
13257 /* Swap 2nd and 3rd operands. */
13258 char *tmp
= ins
->op_out
[2];
13260 ins
->op_out
[2] = ins
->op_out
[1];
13261 ins
->op_out
[1] = tmp
;
13267 OP_REG_VexI4 (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13270 const char (*names
)[8] = att_names_xmm
;
13272 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13274 reg
= *ins
->codep
++;
13276 if (bytemode
!= x_mode
&& bytemode
!= scalar_mode
)
13280 if (ins
->address_mode
!= mode_64bit
)
13283 if (bytemode
== x_mode
&& ins
->vex
.length
== 256)
13284 names
= att_names_ymm
;
13286 oappend_register (ins
, names
[reg
]);
13290 /* Swap 3rd and 4th operands. */
13291 char *tmp
= ins
->op_out
[3];
13293 ins
->op_out
[3] = ins
->op_out
[2];
13294 ins
->op_out
[2] = tmp
;
13300 OP_VexI4 (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13301 int sizeflag ATTRIBUTE_UNUSED
)
13303 oappend_immediate (ins
, ins
->codep
[-1] & 0xf);
13308 VPCMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13309 int sizeflag ATTRIBUTE_UNUSED
)
13311 unsigned int cmp_type
;
13313 if (!ins
->vex
.evex
)
13316 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13318 cmp_type
= *ins
->codep
++;
13319 /* There are aliases for immediates 0, 1, 2, 4, 5, 6.
13320 If it's the case, print suffix, otherwise - print the immediate. */
13321 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
)
13326 char *p
= ins
->mnemonicendp
- 2;
13328 /* vpcmp* can have both one- and two-lettered suffix. */
13342 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
13343 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
13347 /* We have a reserved extension byte. Output it directly. */
13348 oappend_immediate (ins
, cmp_type
);
13353 static const struct op xop_cmp_op
[] =
13355 { STRING_COMMA_LEN ("lt") },
13356 { STRING_COMMA_LEN ("le") },
13357 { STRING_COMMA_LEN ("gt") },
13358 { STRING_COMMA_LEN ("ge") },
13359 { STRING_COMMA_LEN ("eq") },
13360 { STRING_COMMA_LEN ("neq") },
13361 { STRING_COMMA_LEN ("false") },
13362 { STRING_COMMA_LEN ("true") }
13366 VPCOM_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13367 int sizeflag ATTRIBUTE_UNUSED
)
13369 unsigned int cmp_type
;
13371 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13373 cmp_type
= *ins
->codep
++;
13374 if (cmp_type
< ARRAY_SIZE (xop_cmp_op
))
13377 char *p
= ins
->mnemonicendp
- 2;
13379 /* vpcom* can have both one- and two-lettered suffix. */
13393 sprintf (p
, "%s%s", xop_cmp_op
[cmp_type
].name
, suffix
);
13394 ins
->mnemonicendp
+= xop_cmp_op
[cmp_type
].len
;
13398 /* We have a reserved extension byte. Output it directly. */
13399 oappend_immediate (ins
, cmp_type
);
13404 static const struct op pclmul_op
[] =
13406 { STRING_COMMA_LEN ("lql") },
13407 { STRING_COMMA_LEN ("hql") },
13408 { STRING_COMMA_LEN ("lqh") },
13409 { STRING_COMMA_LEN ("hqh") }
13413 PCLMUL_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13414 int sizeflag ATTRIBUTE_UNUSED
)
13416 unsigned int pclmul_type
;
13418 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13420 pclmul_type
= *ins
->codep
++;
13421 switch (pclmul_type
)
13432 if (pclmul_type
< ARRAY_SIZE (pclmul_op
))
13435 char *p
= ins
->mnemonicendp
- 3;
13440 sprintf (p
, "%s%s", pclmul_op
[pclmul_type
].name
, suffix
);
13441 ins
->mnemonicendp
+= pclmul_op
[pclmul_type
].len
;
13445 /* We have a reserved extension byte. Output it directly. */
13446 oappend_immediate (ins
, pclmul_type
);
13452 MOVSXD_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13454 /* Add proper suffix to "movsxd". */
13455 char *p
= ins
->mnemonicendp
;
13460 if (!ins
->intel_syntax
)
13463 if (ins
->rex
& REX_W
)
13475 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
13479 ins
->mnemonicendp
= p
;
13481 return OP_E (ins
, bytemode
, sizeflag
);
13485 DistinctDest_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13487 unsigned int reg
= ins
->vex
.register_specifier
;
13488 unsigned int modrm_reg
= ins
->modrm
.reg
;
13489 unsigned int modrm_rm
= ins
->modrm
.rm
;
13491 /* Calc destination register number. */
13492 if (ins
->rex
& REX_R
)
13497 /* Calc src1 register number. */
13498 if (ins
->address_mode
!= mode_64bit
)
13500 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
13503 /* Calc src2 register number. */
13504 if (ins
->modrm
.mod
== 3)
13506 if (ins
->rex
& REX_B
)
13508 if (ins
->rex
& REX_X
)
13512 /* Destination and source registers must be distinct, output bad if
13513 dest == src1 or dest == src2. */
13514 if (modrm_reg
== reg
13515 || (ins
->modrm
.mod
== 3
13516 && modrm_reg
== modrm_rm
))
13518 oappend (ins
, "(bad)");
13521 return OP_XMM (ins
, bytemode
, sizeflag
);
13525 OP_Rounding (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13527 if (ins
->modrm
.mod
!= 3 || !ins
->vex
.b
)
13532 case evex_rounding_64_mode
:
13533 if (ins
->address_mode
!= mode_64bit
|| !ins
->vex
.w
)
13535 /* Fall through. */
13536 case evex_rounding_mode
:
13537 ins
->evex_used
|= EVEX_b_used
;
13538 oappend (ins
, names_rounding
[ins
->vex
.ll
]);
13540 case evex_sae_mode
:
13541 ins
->evex_used
|= EVEX_b_used
;
13542 oappend (ins
, "{");
13547 oappend (ins
, "sae}");
13552 PREFETCHI_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13554 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 5)
13556 if (ins
->intel_syntax
)
13558 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop ");
13563 if (ins
->rex
& REX_W
)
13564 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopq ");
13567 if (sizeflag
& DFLAG
)
13568 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopl ");
13570 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopw ");
13571 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13577 return OP_M (ins
, bytemode
, sizeflag
);