1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988-2024 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 MONTMUL_Fixup (instr_info
*, int, int);
94 static bool OP_3DNowSuffix (instr_info
*, int, int);
95 static bool CMP_Fixup (instr_info
*, int, int);
96 static bool REP_Fixup (instr_info
*, int, int);
97 static bool SEP_Fixup (instr_info
*, int, int);
98 static bool BND_Fixup (instr_info
*, int, int);
99 static bool NOTRACK_Fixup (instr_info
*, int, int);
100 static bool HLE_Fixup1 (instr_info
*, int, int);
101 static bool HLE_Fixup2 (instr_info
*, int, int);
102 static bool HLE_Fixup3 (instr_info
*, int, int);
103 static bool CMPXCHG8B_Fixup (instr_info
*, int, int);
104 static bool XMM_Fixup (instr_info
*, int, int);
105 static bool FXSAVE_Fixup (instr_info
*, int, int);
106 static bool MOVSXD_Fixup (instr_info
*, int, int);
107 static bool DistinctDest_Fixup (instr_info
*, int, int);
108 static bool PREFETCHI_Fixup (instr_info
*, int, int);
109 static bool PUSH2_POP2_Fixup (instr_info
*, int, int);
110 static bool JMPABS_Fixup (instr_info
*, int, int);
111 static bool CFCMOV_Fixup (instr_info
*, int, int);
113 static void ATTRIBUTE_PRINTF_3
i386_dis_printf (const disassemble_info
*,
114 enum disassembler_style
,
117 /* This character is used to encode style information within the output
118 buffers. See oappend_insert_style for more details. */
119 #define STYLE_MARKER_CHAR '\002'
121 /* The maximum operand buffer size. */
122 #define MAX_OPERAND_BUFFER_SIZE 128
131 static const char *prefix_name (enum address_mode
, uint8_t, int);
148 enum address_mode address_mode
;
150 /* Flags for the prefixes for the current instruction. See below. */
153 /* REX prefix the current instruction. See below. */
155 /* Bits of REX we've already used. */
158 /* Record W R4 X4 B4 bits for rex2. */
160 /* Bits of rex2 we've already used. */
161 unsigned char rex2_used
;
162 unsigned char rex2_payload
;
165 unsigned char condition_code
;
166 unsigned char need_vex
;
169 /* Flags for ins->prefixes which we somehow handled when printing the
170 current instruction. */
173 /* Flags for EVEX bits which we somehow handled when printing the
174 current instruction. */
177 char obuf
[MAX_OPERAND_BUFFER_SIZE
];
180 const uint8_t *start_codep
;
182 const uint8_t *end_codep
;
183 unsigned char nr_prefixes
;
184 signed char last_lock_prefix
;
185 signed char last_repz_prefix
;
186 signed char last_repnz_prefix
;
187 signed char last_data_prefix
;
188 signed char last_addr_prefix
;
189 signed char last_rex_prefix
;
190 signed char last_rex2_prefix
;
191 signed char last_seg_prefix
;
192 signed char fwait_prefix
;
193 /* The active segment register prefix. */
194 unsigned char active_seg_prefix
;
196 #define MAX_CODE_LENGTH 15
197 /* We can up to 14 ins->prefixes since the maximum instruction length is
199 uint8_t all_prefixes
[MAX_CODE_LENGTH
- 1];
200 disassemble_info
*info
;
220 int register_specifier
;
223 int mask_register_specifier
;
237 /* For APX EVEX-promoted prefix, EVEX.ND shares the same bit as vex.b. */
240 enum evex_type evex_type
;
242 /* Remember if the current op is a jump instruction. */
247 /* Record whether EVEX masking is used incorrectly. */
248 bool illegal_masking
;
250 /* Record whether the modrm byte has been skipped. */
251 bool has_skipped_modrm
;
254 signed char op_index
[MAX_OPERANDS
];
255 bool op_riprel
[MAX_OPERANDS
];
256 char *op_out
[MAX_OPERANDS
];
257 bfd_vma op_address
[MAX_OPERANDS
];
260 /* On the 386's of 1988, the maximum length of an instruction is 15 bytes.
261 * (see topic "Redundant ins->prefixes" in the "Differences from 8086"
262 * section of the "Virtual 8086 Mode" chapter.)
263 * 'pc' should be the address of this instruction, it will
264 * be used to print the target address if this is a relative jump or call
265 * The function returns the length of this instruction in bytes.
274 enum x86_64_isa isa64
;
281 /* Indexes first byte not fetched. */
282 unsigned int fetched
;
283 uint8_t the_buffer
[2 * MAX_CODE_LENGTH
- 1];
286 /* Mark parts used in the REX prefix. When we are testing for
287 empty prefix (for 8bit register REX extension), just mask it
288 out. Otherwise test for REX bit is excuse for existence of REX
289 only in case value is nonzero. */
290 #define USED_REX(value) \
294 if (ins->rex & value) \
295 ins->rex_used |= (value) | REX_OPCODE; \
296 if (ins->rex2 & value) \
298 ins->rex2_used |= (value); \
299 ins->rex_used |= REX_OPCODE; \
303 ins->rex_used |= REX_OPCODE; \
307 #define EVEX_b_used 1
308 #define EVEX_len_used 2
311 /* {rex2} is not printed when the REX2_SPECIAL is set. */
312 #define REX2_SPECIAL 16
314 /* Flags stored in PREFIXES. */
315 #define PREFIX_REPZ 1
316 #define PREFIX_REPNZ 2
319 #define PREFIX_DS 0x10
320 #define PREFIX_ES 0x20
321 #define PREFIX_FS 0x40
322 #define PREFIX_GS 0x80
323 #define PREFIX_LOCK 0x100
324 #define PREFIX_DATA 0x200
325 #define PREFIX_ADDR 0x400
326 #define PREFIX_FWAIT 0x800
327 #define PREFIX_REX2 0x1000
328 #define PREFIX_NP_OR_DATA 0x2000
329 #define NO_PREFIX 0x4000
331 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
332 to ADDR (exclusive) are valid. Returns true for success, false
335 fetch_code (struct disassemble_info
*info
, const uint8_t *until
)
338 struct dis_private
*priv
= info
->private_data
;
339 bfd_vma start
= priv
->insn_start
+ priv
->fetched
;
340 uint8_t *fetch_end
= priv
->the_buffer
+ priv
->fetched
;
341 ptrdiff_t needed
= until
- fetch_end
;
346 if (priv
->fetched
+ (size_t) needed
<= ARRAY_SIZE (priv
->the_buffer
))
347 status
= (*info
->read_memory_func
) (start
, fetch_end
, needed
, info
);
350 /* If we did manage to read at least one byte, then
351 print_insn_i386 will do something sensible. Otherwise, print
352 an error. We do that here because this is where we know
355 (*info
->memory_error_func
) (status
, start
, info
);
359 priv
->fetched
+= needed
;
364 fetch_modrm (instr_info
*ins
)
366 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
369 ins
->modrm
.mod
= (*ins
->codep
>> 6) & 3;
370 ins
->modrm
.reg
= (*ins
->codep
>> 3) & 7;
371 ins
->modrm
.rm
= *ins
->codep
& 7;
377 fetch_error (const instr_info
*ins
)
379 /* Getting here means we tried for data but didn't get it. That
380 means we have an incomplete instruction of some sort. Just
381 print the first byte as a prefix or a .byte pseudo-op. */
382 const struct dis_private
*priv
= ins
->info
->private_data
;
383 const char *name
= NULL
;
385 if (ins
->codep
<= priv
->the_buffer
)
388 if (ins
->prefixes
|| ins
->fwait_prefix
>= 0 || (ins
->rex
& REX_OPCODE
))
389 name
= prefix_name (ins
->address_mode
, priv
->the_buffer
[0],
390 priv
->orig_sizeflag
);
392 i386_dis_printf (ins
->info
, dis_style_mnemonic
, "%s", name
);
395 /* Just print the first byte as a .byte instruction. */
396 i386_dis_printf (ins
->info
, dis_style_assembler_directive
, ".byte ");
397 i386_dis_printf (ins
->info
, dis_style_immediate
, "%#x",
398 (unsigned int) priv
->the_buffer
[0]);
404 /* Possible values for prefix requirement. */
405 #define PREFIX_IGNORED_SHIFT 16
406 #define PREFIX_IGNORED_REPZ (PREFIX_REPZ << PREFIX_IGNORED_SHIFT)
407 #define PREFIX_IGNORED_REPNZ (PREFIX_REPNZ << PREFIX_IGNORED_SHIFT)
408 #define PREFIX_IGNORED_DATA (PREFIX_DATA << PREFIX_IGNORED_SHIFT)
409 #define PREFIX_IGNORED_ADDR (PREFIX_ADDR << PREFIX_IGNORED_SHIFT)
410 #define PREFIX_IGNORED_LOCK (PREFIX_LOCK << PREFIX_IGNORED_SHIFT)
411 #define PREFIX_REX2_ILLEGAL (PREFIX_REX2 << PREFIX_IGNORED_SHIFT)
413 /* Opcode prefixes. */
414 #define PREFIX_OPCODE (PREFIX_REPZ \
418 /* Prefixes ignored. */
419 #define PREFIX_IGNORED (PREFIX_IGNORED_REPZ \
420 | PREFIX_IGNORED_REPNZ \
421 | PREFIX_IGNORED_DATA)
423 #define XX { NULL, 0 }
424 #define Bad_Opcode NULL, { { NULL, 0 } }, 0
426 #define Eb { OP_E, b_mode }
427 #define Ebnd { OP_E, bnd_mode }
428 #define EbS { OP_E, b_swap_mode }
429 #define EbndS { OP_E, bnd_swap_mode }
430 #define Ev { OP_E, v_mode }
431 #define Eva { OP_E, va_mode }
432 #define Ev_bnd { OP_E, v_bnd_mode }
433 #define EvS { OP_E, v_swap_mode }
434 #define Ed { OP_E, d_mode }
435 #define Edq { OP_E, dq_mode }
436 #define Edb { OP_E, db_mode }
437 #define Edw { OP_E, dw_mode }
438 #define Eq { OP_E, q_mode }
439 #define indirEv { OP_indirE, indir_v_mode }
440 #define indirEp { OP_indirE, f_mode }
441 #define stackEv { OP_E, stack_v_mode }
442 #define Em { OP_E, m_mode }
443 #define Ew { OP_E, w_mode }
444 #define M { OP_M, 0 } /* lea, lgdt, etc. */
445 #define Ma { OP_M, a_mode }
446 #define Mb { OP_M, b_mode }
447 #define Md { OP_M, d_mode }
448 #define Mdq { OP_M, dq_mode }
449 #define Mo { OP_M, o_mode }
450 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
451 #define Mq { OP_M, q_mode }
452 #define Mv { OP_M, v_mode }
453 #define Mv_bnd { OP_M, v_bndmk_mode }
454 #define Mw { OP_M, w_mode }
455 #define Mx { OP_M, x_mode }
456 #define Mxmm { OP_M, xmm_mode }
457 #define Mymm { OP_M, ymm_mode }
458 #define Gb { OP_G, b_mode }
459 #define Gbnd { OP_G, bnd_mode }
460 #define Gv { OP_G, v_mode }
461 #define Gd { OP_G, d_mode }
462 #define Gdq { OP_G, dq_mode }
463 #define Gq { OP_G, q_mode }
464 #define Gm { OP_G, m_mode }
465 #define Gva { OP_G, va_mode }
466 #define Gw { OP_G, w_mode }
467 #define Ib { OP_I, b_mode }
468 #define sIb { OP_sI, b_mode } /* sign extened byte */
469 #define sIbT { OP_sI, b_T_mode } /* sign extened byte like 'T' */
470 #define Iv { OP_I, v_mode }
471 #define sIv { OP_sI, v_mode }
472 #define Iv64 { OP_I64, v_mode }
473 #define Id { OP_I, d_mode }
474 #define Iw { OP_I, w_mode }
475 #define I1 { OP_I, const_1_mode }
476 #define Jb { OP_J, b_mode }
477 #define Jv { OP_J, v_mode }
478 #define Jdqw { OP_J, dqw_mode }
479 #define Cm { OP_C, m_mode }
480 #define Dm { OP_D, m_mode }
481 #define Td { OP_T, d_mode }
482 #define Skip_MODRM { OP_Skip_MODRM, 0 }
484 #define RMeAX { OP_REG, eAX_reg }
485 #define RMeBX { OP_REG, eBX_reg }
486 #define RMeCX { OP_REG, eCX_reg }
487 #define RMeDX { OP_REG, eDX_reg }
488 #define RMeSP { OP_REG, eSP_reg }
489 #define RMeBP { OP_REG, eBP_reg }
490 #define RMeSI { OP_REG, eSI_reg }
491 #define RMeDI { OP_REG, eDI_reg }
492 #define RMrAX { OP_REG, rAX_reg }
493 #define RMrBX { OP_REG, rBX_reg }
494 #define RMrCX { OP_REG, rCX_reg }
495 #define RMrDX { OP_REG, rDX_reg }
496 #define RMrSP { OP_REG, rSP_reg }
497 #define RMrBP { OP_REG, rBP_reg }
498 #define RMrSI { OP_REG, rSI_reg }
499 #define RMrDI { OP_REG, rDI_reg }
500 #define RMAL { OP_REG, al_reg }
501 #define RMCL { OP_REG, cl_reg }
502 #define RMDL { OP_REG, dl_reg }
503 #define RMBL { OP_REG, bl_reg }
504 #define RMAH { OP_REG, ah_reg }
505 #define RMCH { OP_REG, ch_reg }
506 #define RMDH { OP_REG, dh_reg }
507 #define RMBH { OP_REG, bh_reg }
508 #define RMAX { OP_REG, ax_reg }
509 #define RMDX { OP_REG, dx_reg }
511 #define eAX { OP_IMREG, eAX_reg }
512 #define AL { OP_IMREG, al_reg }
513 #define CL { OP_IMREG, cl_reg }
514 #define zAX { OP_IMREG, z_mode_ax_reg }
515 #define indirDX { OP_IMREG, indir_dx_reg }
517 #define Sw { OP_SEG, w_mode }
518 #define Sv { OP_SEG, v_mode }
519 #define Ap { OP_DIR, 0 }
520 #define Ob { OP_OFF64, b_mode }
521 #define Ov { OP_OFF64, v_mode }
522 #define Xb { OP_DSreg, eSI_reg }
523 #define Xv { OP_DSreg, eSI_reg }
524 #define Xz { OP_DSreg, eSI_reg }
525 #define Yb { OP_ESreg, eDI_reg }
526 #define Yv { OP_ESreg, eDI_reg }
527 #define DSBX { OP_DSreg, eBX_reg }
529 #define es { OP_REG, es_reg }
530 #define ss { OP_REG, ss_reg }
531 #define cs { OP_REG, cs_reg }
532 #define ds { OP_REG, ds_reg }
533 #define fs { OP_REG, fs_reg }
534 #define gs { OP_REG, gs_reg }
536 #define MX { OP_MMX, 0 }
537 #define XM { OP_XMM, 0 }
538 #define XMScalar { OP_XMM, scalar_mode }
539 #define XMGatherD { OP_XMM, vex_vsib_d_w_dq_mode }
540 #define XMGatherQ { OP_XMM, vex_vsib_q_w_dq_mode }
541 #define XMM { OP_XMM, xmm_mode }
542 #define TMM { OP_XMM, tmm_mode }
543 #define XMxmmq { OP_XMM, xmmq_mode }
544 #define EM { OP_EM, v_mode }
545 #define EMS { OP_EM, v_swap_mode }
546 #define EMd { OP_EM, d_mode }
547 #define EMx { OP_EM, x_mode }
548 #define EXbwUnit { OP_EX, bw_unit_mode }
549 #define EXb { OP_EX, b_mode }
550 #define EXw { OP_EX, w_mode }
551 #define EXd { OP_EX, d_mode }
552 #define EXdS { OP_EX, d_swap_mode }
553 #define EXwS { OP_EX, w_swap_mode }
554 #define EXq { OP_EX, q_mode }
555 #define EXqS { OP_EX, q_swap_mode }
556 #define EXdq { OP_EX, dq_mode }
557 #define EXx { OP_EX, x_mode }
558 #define EXxh { OP_EX, xh_mode }
559 #define EXxS { OP_EX, x_swap_mode }
560 #define EXxmm { OP_EX, xmm_mode }
561 #define EXymm { OP_EX, ymm_mode }
562 #define EXxmmq { OP_EX, xmmq_mode }
563 #define EXxmmqh { OP_EX, evex_half_bcst_xmmqh_mode }
564 #define EXEvexHalfBcstXmmq { OP_EX, evex_half_bcst_xmmq_mode }
565 #define EXxmmdw { OP_EX, xmmdw_mode }
566 #define EXxmmqd { OP_EX, xmmqd_mode }
567 #define EXxmmqdh { OP_EX, evex_half_bcst_xmmqdh_mode }
568 #define EXymmq { OP_EX, ymmq_mode }
569 #define EXEvexXGscat { OP_EX, evex_x_gscat_mode }
570 #define EXEvexXNoBcst { OP_EX, evex_x_nobcst_mode }
571 #define Rd { OP_R, d_mode }
572 #define Rdq { OP_R, dq_mode }
573 #define Rq { OP_R, q_mode }
574 #define Nq { OP_R, q_mm_mode }
575 #define Ux { OP_R, x_mode }
576 #define Uxmm { OP_R, xmm_mode }
577 #define Rxmmq { OP_R, xmmq_mode }
578 #define Rymm { OP_R, ymm_mode }
579 #define Rtmm { OP_R, tmm_mode }
580 #define EMCq { OP_EMC, q_mode }
581 #define MXC { OP_MXC, 0 }
582 #define OPSUF { OP_3DNowSuffix, 0 }
583 #define SEP { SEP_Fixup, 0 }
584 #define CMP { CMP_Fixup, 0 }
585 #define XMM0 { XMM_Fixup, 0 }
586 #define FXSAVE { FXSAVE_Fixup, 0 }
588 #define Vex { OP_VEX, x_mode }
589 #define VexW { OP_VexW, x_mode }
590 #define VexScalar { OP_VEX, scalar_mode }
591 #define VexScalarR { OP_VexR, scalar_mode }
592 #define VexGatherD { OP_VEX, vex_vsib_d_w_dq_mode }
593 #define VexGatherQ { OP_VEX, vex_vsib_q_w_dq_mode }
594 #define VexGdq { OP_VEX, dq_mode }
595 #define VexGb { OP_VEX, b_mode }
596 #define VexGv { OP_VEX, v_mode }
597 #define VexTmm { OP_VEX, tmm_mode }
598 #define XMVexI4 { OP_REG_VexI4, x_mode }
599 #define XMVexScalarI4 { OP_REG_VexI4, scalar_mode }
600 #define VexI4 { OP_VexI4, 0 }
601 #define PCLMUL { PCLMUL_Fixup, 0 }
602 #define VPCMP { VPCMP_Fixup, 0 }
603 #define VPCOM { VPCOM_Fixup, 0 }
605 #define EXxEVexR { OP_Rounding, evex_rounding_mode }
606 #define EXxEVexR64 { OP_Rounding, evex_rounding_64_mode }
607 #define EXxEVexS { OP_Rounding, evex_sae_mode }
609 #define MaskG { OP_G, mask_mode }
610 #define MaskE { OP_E, mask_mode }
611 #define MaskR { OP_R, mask_mode }
612 #define MaskBDE { OP_E, mask_bd_mode }
613 #define MaskVex { OP_VEX, mask_mode }
615 #define MVexVSIBDWpX { OP_M, vex_vsib_d_w_dq_mode }
616 #define MVexVSIBQWpX { OP_M, vex_vsib_q_w_dq_mode }
618 #define MVexSIBMEM { OP_M, vex_sibmem_mode }
620 /* Used handle "rep" prefix for string instructions. */
621 #define Xbr { REP_Fixup, eSI_reg }
622 #define Xvr { REP_Fixup, eSI_reg }
623 #define Ybr { REP_Fixup, eDI_reg }
624 #define Yvr { REP_Fixup, eDI_reg }
625 #define Yzr { REP_Fixup, eDI_reg }
626 #define indirDXr { REP_Fixup, indir_dx_reg }
627 #define ALr { REP_Fixup, al_reg }
628 #define eAXr { REP_Fixup, eAX_reg }
630 /* Used handle HLE prefix for lockable instructions. */
631 #define Ebh1 { HLE_Fixup1, b_mode }
632 #define Evh1 { HLE_Fixup1, v_mode }
633 #define Ebh2 { HLE_Fixup2, b_mode }
634 #define Evh2 { HLE_Fixup2, v_mode }
635 #define Ebh3 { HLE_Fixup3, b_mode }
636 #define Evh3 { HLE_Fixup3, v_mode }
638 #define BND { BND_Fixup, 0 }
639 #define NOTRACK { NOTRACK_Fixup, 0 }
641 #define cond_jump_flag { NULL, cond_jump_mode }
642 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
644 /* bits in sizeflag */
645 #define SUFFIX_ALWAYS 4
653 /* byte operand with operand swapped */
655 /* byte operand, sign extend like 'T' suffix */
657 /* operand size depends on prefixes */
659 /* operand size depends on prefixes with operand swapped */
661 /* operand size depends on address prefix */
665 /* double word operand */
667 /* word operand with operand swapped */
669 /* double word operand with operand swapped */
671 /* quad word operand */
673 /* 8-byte MM operand */
675 /* quad word operand with operand swapped */
677 /* ten-byte operand */
679 /* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
680 broadcast enabled. */
682 /* Similar to x_mode, but with different EVEX mem shifts. */
684 /* Similar to x_mode, but with yet different EVEX mem shifts. */
686 /* Similar to x_mode, but with disabled broadcast. */
688 /* Similar to x_mode, but with operands swapped and disabled broadcast
691 /* 16-byte XMM, 32-byte YMM or 64-byte ZMM operand. In EVEX with
692 broadcast of 16bit enabled. */
694 /* 16-byte XMM operand */
696 /* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
697 memory operand (depending on vector length). Broadcast isn't
700 /* Same as xmmq_mode, but broadcast is allowed. */
701 evex_half_bcst_xmmq_mode
,
702 /* XMM, XMM or YMM register operand, or quad word, xmmword or ymmword
703 memory operand (depending on vector length). 16bit broadcast. */
704 evex_half_bcst_xmmqh_mode
,
705 /* 16-byte XMM, word, double word or quad word operand. */
707 /* 16-byte XMM, double word, quad word operand or xmm word operand. */
709 /* 16-byte XMM, double word, quad word operand or xmm word operand.
711 evex_half_bcst_xmmqdh_mode
,
712 /* 32-byte YMM operand */
714 /* quad word, ymmword or zmmword memory operand. */
718 /* d_mode in 32bit, q_mode in 64bit mode. */
720 /* pair of v_mode operands */
726 /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */
728 /* operand size depends on REX.W / VEX.W. */
730 /* Displacements like v_mode without considering Intel64 ISA. */
734 /* bounds operand with operand swapped */
736 /* 4- or 6-byte pointer operand */
739 /* v_mode for indirect branch opcodes. */
741 /* v_mode for stack-related opcodes. */
743 /* non-quad operand size depends on prefixes */
745 /* 16-byte operand */
747 /* registers like d_mode, memory like b_mode. */
749 /* registers like d_mode, memory like w_mode. */
752 /* Operand size depends on the VEX.W bit, with VSIB dword indices. */
753 vex_vsib_d_w_dq_mode
,
754 /* Operand size depends on the VEX.W bit, with VSIB qword indices. */
755 vex_vsib_q_w_dq_mode
,
756 /* mandatory non-vector SIB. */
759 /* scalar, ignore vector length. */
762 /* Static rounding. */
764 /* Static rounding, 64-bit mode only. */
765 evex_rounding_64_mode
,
766 /* Supress all exceptions. */
769 /* Mask register operand. */
771 /* Mask register operand. */
829 USE_X86_64_EVEX_FROM_VEX_TABLE
,
830 USE_X86_64_EVEX_PFX_TABLE
,
831 USE_X86_64_EVEX_W_TABLE
,
832 USE_X86_64_EVEX_MEM_W_TABLE
,
843 #define FLOAT NULL, { { NULL, FLOATCODE } }, 0
845 #define DIS386(T, I) NULL, { { NULL, (T)}, { NULL, (I) } }, 0
846 #define REG_TABLE(I) DIS386 (USE_REG_TABLE, (I))
847 #define MOD_TABLE(I) DIS386 (USE_MOD_TABLE, (I))
848 #define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I))
849 #define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I))
850 #define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I))
851 #define X86_64_EVEX_FROM_VEX_TABLE(I) \
852 DIS386 (USE_X86_64_EVEX_FROM_VEX_TABLE, (I))
853 #define X86_64_EVEX_PFX_TABLE(I) DIS386 (USE_X86_64_EVEX_PFX_TABLE, (I))
854 #define X86_64_EVEX_W_TABLE(I) DIS386 (USE_X86_64_EVEX_W_TABLE, (I))
855 #define X86_64_EVEX_MEM_W_TABLE(I) DIS386 (USE_X86_64_EVEX_MEM_W_TABLE, (I))
856 #define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I))
857 #define XOP_8F_TABLE() DIS386 (USE_XOP_8F_TABLE, 0)
858 #define VEX_C4_TABLE() DIS386 (USE_VEX_C4_TABLE, 0)
859 #define VEX_C5_TABLE() DIS386 (USE_VEX_C5_TABLE, 0)
860 #define VEX_LEN_TABLE(I) DIS386 (USE_VEX_LEN_TABLE, (I))
861 #define VEX_W_TABLE(I) DIS386 (USE_VEX_W_TABLE, (I))
862 #define EVEX_TABLE() DIS386 (USE_EVEX_TABLE, 0)
863 #define EVEX_LEN_TABLE(I) DIS386 (USE_EVEX_LEN_TABLE, (I))
903 REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0
,
904 REG_VEX_0F38F3_L_0_P_0
,
905 REG_VEX_MAP7_F6_L_0_W_0
,
906 REG_VEX_MAP7_F8_L_0_W_0
,
965 MOD_VEX_0F3849_X86_64_L_0_W_0
,
969 MOD_EVEX_MAP4_F8_P_1
,
970 MOD_EVEX_MAP4_F8_P_3
,
983 RM_0F1E_P_1_MOD_3_REG_7
,
984 RM_0FAE_REG_6_MOD_3_P_0
,
988 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
,
989 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
,
995 PREFIX_0F00_REG_6_X86_64
,
996 PREFIX_0F01_REG_0_MOD_3_RM_6
,
997 PREFIX_0F01_REG_0_MOD_3_RM_7
,
998 PREFIX_0F01_REG_1_RM_2
,
999 PREFIX_0F01_REG_1_RM_4
,
1000 PREFIX_0F01_REG_1_RM_5
,
1001 PREFIX_0F01_REG_1_RM_6
,
1002 PREFIX_0F01_REG_1_RM_7
,
1003 PREFIX_0F01_REG_3_RM_1
,
1004 PREFIX_0F01_REG_5_MOD_0
,
1005 PREFIX_0F01_REG_5_MOD_3_RM_0
,
1006 PREFIX_0F01_REG_5_MOD_3_RM_1
,
1007 PREFIX_0F01_REG_5_MOD_3_RM_2
,
1008 PREFIX_0F01_REG_5_MOD_3_RM_4
,
1009 PREFIX_0F01_REG_5_MOD_3_RM_5
,
1010 PREFIX_0F01_REG_5_MOD_3_RM_6
,
1011 PREFIX_0F01_REG_5_MOD_3_RM_7
,
1012 PREFIX_0F01_REG_7_MOD_3_RM_2
,
1013 PREFIX_0F01_REG_7_MOD_3_RM_5
,
1014 PREFIX_0F01_REG_7_MOD_3_RM_6
,
1015 PREFIX_0F01_REG_7_MOD_3_RM_7
,
1021 PREFIX_0F18_REG_6_MOD_0_X86_64
,
1022 PREFIX_0F18_REG_7_MOD_0_X86_64
,
1058 PREFIX_0FAE_REG_0_MOD_3
,
1059 PREFIX_0FAE_REG_1_MOD_3
,
1060 PREFIX_0FAE_REG_2_MOD_3
,
1061 PREFIX_0FAE_REG_3_MOD_3
,
1062 PREFIX_0FAE_REG_4_MOD_0
,
1063 PREFIX_0FAE_REG_4_MOD_3
,
1064 PREFIX_0FAE_REG_5_MOD_3
,
1065 PREFIX_0FAE_REG_6_MOD_0
,
1066 PREFIX_0FAE_REG_6_MOD_3
,
1067 PREFIX_0FAE_REG_7_MOD_0
,
1072 PREFIX_0FC7_REG_6_MOD_0
,
1073 PREFIX_0FC7_REG_6_MOD_3
,
1074 PREFIX_0FC7_REG_7_MOD_3
,
1090 PREFIX_0F38F8_M_1_X86_64
,
1100 PREFIX_VEX_0F41_L_1_W_0
,
1101 PREFIX_VEX_0F41_L_1_W_1
,
1102 PREFIX_VEX_0F42_L_1_W_0
,
1103 PREFIX_VEX_0F42_L_1_W_1
,
1104 PREFIX_VEX_0F44_L_0_W_0
,
1105 PREFIX_VEX_0F44_L_0_W_1
,
1106 PREFIX_VEX_0F45_L_1_W_0
,
1107 PREFIX_VEX_0F45_L_1_W_1
,
1108 PREFIX_VEX_0F46_L_1_W_0
,
1109 PREFIX_VEX_0F46_L_1_W_1
,
1110 PREFIX_VEX_0F47_L_1_W_0
,
1111 PREFIX_VEX_0F47_L_1_W_1
,
1112 PREFIX_VEX_0F4A_L_1_W_0
,
1113 PREFIX_VEX_0F4A_L_1_W_1
,
1114 PREFIX_VEX_0F4B_L_1_W_0
,
1115 PREFIX_VEX_0F4B_L_1_W_1
,
1120 PREFIX_VEX_0F90_L_0_W_0
,
1121 PREFIX_VEX_0F90_L_0_W_1
,
1122 PREFIX_VEX_0F91_L_0_W_0
,
1123 PREFIX_VEX_0F91_L_0_W_1
,
1124 PREFIX_VEX_0F92_L_0_W_0
,
1125 PREFIX_VEX_0F92_L_0_W_1
,
1126 PREFIX_VEX_0F93_L_0_W_0
,
1127 PREFIX_VEX_0F93_L_0_W_1
,
1128 PREFIX_VEX_0F98_L_0_W_0
,
1129 PREFIX_VEX_0F98_L_0_W_1
,
1130 PREFIX_VEX_0F99_L_0_W_0
,
1131 PREFIX_VEX_0F99_L_0_W_1
,
1132 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
,
1133 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
,
1134 PREFIX_VEX_0F384B_X86_64_L_0_W_0
,
1135 PREFIX_VEX_0F3850_W_0
,
1136 PREFIX_VEX_0F3851_W_0
,
1137 PREFIX_VEX_0F385C_X86_64_L_0_W_0
,
1138 PREFIX_VEX_0F385E_X86_64_L_0_W_0
,
1139 PREFIX_VEX_0F386C_X86_64_L_0_W_0
,
1141 PREFIX_VEX_0F38B0_W_0
,
1142 PREFIX_VEX_0F38B1_W_0
,
1143 PREFIX_VEX_0F38D2_W_0
,
1144 PREFIX_VEX_0F38D3_W_0
,
1148 PREFIX_VEX_0F38DA_W_0
,
1149 PREFIX_VEX_0F38F2_L_0
,
1150 PREFIX_VEX_0F38F3_L_0
,
1151 PREFIX_VEX_0F38F5_L_0
,
1152 PREFIX_VEX_0F38F6_L_0
,
1153 PREFIX_VEX_0F38F7_L_0
,
1154 PREFIX_VEX_0F3AF0_L_0
,
1155 PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64
,
1156 PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64
,
1209 PREFIX_EVEX_0F3A42_W_0
,
1216 PREFIX_EVEX_MAP4_4x
,
1217 PREFIX_EVEX_MAP4_F0
,
1218 PREFIX_EVEX_MAP4_F1
,
1219 PREFIX_EVEX_MAP4_F2
,
1220 PREFIX_EVEX_MAP4_F8
,
1222 PREFIX_EVEX_MAP5_10
,
1223 PREFIX_EVEX_MAP5_11
,
1224 PREFIX_EVEX_MAP5_18
,
1225 PREFIX_EVEX_MAP5_1B
,
1226 PREFIX_EVEX_MAP5_1D
,
1227 PREFIX_EVEX_MAP5_1E
,
1228 PREFIX_EVEX_MAP5_2A
,
1229 PREFIX_EVEX_MAP5_2C
,
1230 PREFIX_EVEX_MAP5_2D
,
1231 PREFIX_EVEX_MAP5_2E
,
1232 PREFIX_EVEX_MAP5_2F
,
1233 PREFIX_EVEX_MAP5_51
,
1234 PREFIX_EVEX_MAP5_58
,
1235 PREFIX_EVEX_MAP5_59
,
1236 PREFIX_EVEX_MAP5_5A
,
1237 PREFIX_EVEX_MAP5_5B
,
1238 PREFIX_EVEX_MAP5_5C
,
1239 PREFIX_EVEX_MAP5_5D
,
1240 PREFIX_EVEX_MAP5_5E
,
1241 PREFIX_EVEX_MAP5_5F
,
1242 PREFIX_EVEX_MAP5_74
,
1243 PREFIX_EVEX_MAP5_78
,
1244 PREFIX_EVEX_MAP5_79
,
1245 PREFIX_EVEX_MAP5_7A
,
1246 PREFIX_EVEX_MAP5_7B
,
1247 PREFIX_EVEX_MAP5_7C
,
1248 PREFIX_EVEX_MAP5_7D
,
1250 PREFIX_EVEX_MAP6_13
,
1251 PREFIX_EVEX_MAP6_56
,
1252 PREFIX_EVEX_MAP6_57
,
1253 PREFIX_EVEX_MAP6_D6
,
1254 PREFIX_EVEX_MAP6_D7
,
1290 X86_64_0F01_REG_0_MOD_3_RM_6_P_1
,
1291 X86_64_0F01_REG_0_MOD_3_RM_6_P_3
,
1292 X86_64_0F01_REG_0_MOD_3_RM_7_P_0
,
1294 X86_64_0F01_REG_1_RM_2_PREFIX_1
,
1295 X86_64_0F01_REG_1_RM_2_PREFIX_3
,
1296 X86_64_0F01_REG_1_RM_5_PREFIX_2
,
1297 X86_64_0F01_REG_1_RM_6_PREFIX_2
,
1298 X86_64_0F01_REG_1_RM_7_PREFIX_2
,
1301 X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
,
1302 X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
,
1303 X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
,
1304 X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
,
1305 X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
,
1306 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
,
1307 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
,
1308 X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
,
1309 X86_64_0F18_REG_6_MOD_0
,
1310 X86_64_0F18_REG_7_MOD_0
,
1314 X86_64_0FC7_REG_6_MOD_3_PREFIX_1
,
1323 X86_64_VEX_MAP7_F6_L_0_W_0_R_0
,
1324 X86_64_VEX_MAP7_F8_L_0_W_0_R_0
,
1329 THREE_BYTE_0F38
= 0,
1361 VEX_LEN_0F12_P_0
= 0,
1394 VEX_LEN_0F3849_X86_64
,
1395 VEX_LEN_0F384B_X86_64
,
1397 VEX_LEN_0F385C_X86_64
,
1398 VEX_LEN_0F385E_X86_64
,
1399 VEX_LEN_0F386C_X86_64
,
1400 VEX_LEN_0F38CB_P_3_W_0
,
1401 VEX_LEN_0F38CC_P_3_W_0
,
1402 VEX_LEN_0F38CD_P_3_W_0
,
1403 VEX_LEN_0F38DA_W_0_P_0
,
1404 VEX_LEN_0F38DA_W_0_P_2
,
1468 VEX_LEN_XOP_09_82_W_0
,
1469 VEX_LEN_XOP_09_83_W_0
,
1502 EVEX_LEN_0F3816
= 0,
1556 VEX_W_0F3849_X86_64_L_0
,
1557 VEX_W_0F384B_X86_64_L_0
,
1565 VEX_W_0F385C_X86_64_L_0
,
1566 VEX_W_0F385E_X86_64_L_0
,
1567 VEX_W_0F386C_X86_64_L_0
,
1603 VEX_W_XOP_08_85_L_0
,
1604 VEX_W_XOP_08_86_L_0
,
1605 VEX_W_XOP_08_87_L_0
,
1606 VEX_W_XOP_08_8E_L_0
,
1607 VEX_W_XOP_08_8F_L_0
,
1608 VEX_W_XOP_08_95_L_0
,
1609 VEX_W_XOP_08_96_L_0
,
1610 VEX_W_XOP_08_97_L_0
,
1611 VEX_W_XOP_08_9E_L_0
,
1612 VEX_W_XOP_08_9F_L_0
,
1613 VEX_W_XOP_08_A6_L_0
,
1614 VEX_W_XOP_08_B6_L_0
,
1615 VEX_W_XOP_08_C0_L_0
,
1616 VEX_W_XOP_08_C1_L_0
,
1617 VEX_W_XOP_08_C2_L_0
,
1618 VEX_W_XOP_08_C3_L_0
,
1619 VEX_W_XOP_08_CC_L_0
,
1620 VEX_W_XOP_08_CD_L_0
,
1621 VEX_W_XOP_08_CE_L_0
,
1622 VEX_W_XOP_08_CF_L_0
,
1623 VEX_W_XOP_08_EC_L_0
,
1624 VEX_W_XOP_08_ED_L_0
,
1625 VEX_W_XOP_08_EE_L_0
,
1626 VEX_W_XOP_08_EF_L_0
,
1632 VEX_W_XOP_09_C1_L_0
,
1633 VEX_W_XOP_09_C2_L_0
,
1634 VEX_W_XOP_09_C3_L_0
,
1635 VEX_W_XOP_09_C6_L_0
,
1636 VEX_W_XOP_09_C7_L_0
,
1637 VEX_W_XOP_09_CB_L_0
,
1638 VEX_W_XOP_09_D1_L_0
,
1639 VEX_W_XOP_09_D2_L_0
,
1640 VEX_W_XOP_09_D3_L_0
,
1641 VEX_W_XOP_09_D6_L_0
,
1642 VEX_W_XOP_09_D7_L_0
,
1643 VEX_W_XOP_09_DB_L_0
,
1644 VEX_W_XOP_09_E1_L_0
,
1645 VEX_W_XOP_09_E2_L_0
,
1646 VEX_W_XOP_09_E3_L_0
,
1749 EVEX_W_MAP4_F8_P1_M_1
,
1750 EVEX_W_MAP4_F8_P3_M_1
,
1757 typedef bool (*op_rtn
) (instr_info
*ins
, int bytemode
, int sizeflag
);
1766 unsigned int prefix_requirement
;
1769 /* Upper case letters in the instruction names here are macros.
1770 'A' => print 'b' if no (suitable) register operand or suffix_always is true
1771 'B' => print 'b' if suffix_always is true
1772 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
1774 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
1775 suffix_always is true
1776 'E' => print 'e' if 32-bit form of jcxz
1777 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
1778 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
1779 'H' => print ",pt" or ",pn" branch hint
1782 'K' => print 'd' or 'q' if rex prefix is present.
1783 'L' => print 'l' or 'q' if suffix_always is true
1784 'M' => print 'r' if intel_mnemonic is false.
1785 'N' => print 'n' if instruction has no wait "prefix"
1786 'O' => print 'd' or 'o' (or 'q' in Intel mode)
1787 'P' => behave as 'T' except with register operand outside of suffix_always
1789 'Q' => print 'w', 'l' or 'q' if no (suitable) register operand or
1790 suffix_always is true
1791 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
1792 'S' => print 'w', 'l' or 'q' if suffix_always is true
1793 'T' => print 'w', 'l'/'d', or 'q' if instruction has an operand size
1794 prefix or if suffix_always is true.
1796 'V' => print 'v' for VEX/EVEX and nothing for legacy encodings.
1797 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
1798 'X' => print 's', 'd' depending on data16 prefix (for XMM)
1799 'Y' => no output, mark EVEX.aaa != 0 as bad.
1800 'Z' => print 'q' in 64bit mode and 'l' otherwise, if suffix_always is true.
1801 '!' => change condition from true to false or from false to true.
1802 '%' => add 1 upper case letter to the macro.
1803 '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
1804 prefix or suffix_always is true (lcall/ljmp).
1805 '@' => in 64bit mode for Intel64 ISA or if instruction
1806 has no operand sizing prefix, print 'q' if suffix_always is true or
1807 nothing otherwise; behave as 'P' in all other cases
1809 2 upper case letter macros:
1810 "CC" => print condition code
1811 "XY" => print 'x' or 'y' if suffix_always is true or no register
1812 operands and no broadcast.
1813 "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
1814 register operands and no broadcast.
1815 "XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
1816 "XD" => print 'd' if !EVEX or EVEX.W=1, EVEX.W=0 is not a valid encoding
1817 "XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
1818 "XS" => print 's' if !EVEX or EVEX.W=0, EVEX.W=1 is not a valid encoding
1819 "XV" => print "{vex} " pseudo prefix
1820 "XE" => print "{evex} " pseudo prefix if no EVEX-specific functionality is
1821 is used by an EVEX-encoded (AVX512VL) instruction.
1822 "NF" => print "{nf} " pseudo prefix when EVEX.NF = 1 and print "{evex} "
1823 pseudo prefix when instructions without NF, EGPR and VVVV,
1824 "NE" => don't print "{evex} " pseudo prefix for some special instructions
1826 "ZU" => print 'zu' if EVEX.ZU=1.
1827 "SC" => print suffix SCC for SCC insns
1828 "YK" keep unused, to avoid ambiguity with the combined use of Y and K.
1829 "YX" keep unused, to avoid ambiguity with the combined use of Y and X.
1830 "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
1831 being false, or no operand at all in 64bit mode, or if suffix_always
1833 "LB" => print "abs" in 64bit mode and behave as 'B' otherwise
1834 "LS" => print "abs" in 64bit mode and behave as 'S' otherwise
1835 "LV" => print "abs" for 64bit operand and behave as 'S' otherwise
1836 "DQ" => print 'd' or 'q' depending on the VEX.W bit
1837 "DF" => print default flag value for SCC insns
1838 "BW" => print 'b' or 'w' depending on the VEX.W bit
1839 "LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has
1840 an operand size prefix, or suffix_always is true. print
1841 'q' if rex prefix is present.
1843 Many of the above letters print nothing in Intel mode. See "putop"
1846 Braces '{' and '}', and vertical bars '|', indicate alternative
1847 mnemonic strings for AT&T and Intel. */
1849 static const struct dis386 dis386
[] = {
1851 { "addB", { Ebh1
, Gb
}, 0 },
1852 { "addS", { Evh1
, Gv
}, 0 },
1853 { "addB", { Gb
, EbS
}, 0 },
1854 { "addS", { Gv
, EvS
}, 0 },
1855 { "addB", { AL
, Ib
}, 0 },
1856 { "addS", { eAX
, Iv
}, 0 },
1857 { X86_64_TABLE (X86_64_06
) },
1858 { X86_64_TABLE (X86_64_07
) },
1860 { "orB", { Ebh1
, Gb
}, 0 },
1861 { "orS", { Evh1
, Gv
}, 0 },
1862 { "orB", { Gb
, EbS
}, 0 },
1863 { "orS", { Gv
, EvS
}, 0 },
1864 { "orB", { AL
, Ib
}, 0 },
1865 { "orS", { eAX
, Iv
}, 0 },
1866 { X86_64_TABLE (X86_64_0E
) },
1867 { Bad_Opcode
}, /* 0x0f extended opcode escape */
1869 { "adcB", { Ebh1
, Gb
}, 0 },
1870 { "adcS", { Evh1
, Gv
}, 0 },
1871 { "adcB", { Gb
, EbS
}, 0 },
1872 { "adcS", { Gv
, EvS
}, 0 },
1873 { "adcB", { AL
, Ib
}, 0 },
1874 { "adcS", { eAX
, Iv
}, 0 },
1875 { X86_64_TABLE (X86_64_16
) },
1876 { X86_64_TABLE (X86_64_17
) },
1878 { "sbbB", { Ebh1
, Gb
}, 0 },
1879 { "sbbS", { Evh1
, Gv
}, 0 },
1880 { "sbbB", { Gb
, EbS
}, 0 },
1881 { "sbbS", { Gv
, EvS
}, 0 },
1882 { "sbbB", { AL
, Ib
}, 0 },
1883 { "sbbS", { eAX
, Iv
}, 0 },
1884 { X86_64_TABLE (X86_64_1E
) },
1885 { X86_64_TABLE (X86_64_1F
) },
1887 { "andB", { Ebh1
, Gb
}, 0 },
1888 { "andS", { Evh1
, Gv
}, 0 },
1889 { "andB", { Gb
, EbS
}, 0 },
1890 { "andS", { Gv
, EvS
}, 0 },
1891 { "andB", { AL
, Ib
}, 0 },
1892 { "andS", { eAX
, Iv
}, 0 },
1893 { Bad_Opcode
}, /* SEG ES prefix */
1894 { X86_64_TABLE (X86_64_27
) },
1896 { "subB", { Ebh1
, Gb
}, 0 },
1897 { "subS", { Evh1
, Gv
}, 0 },
1898 { "subB", { Gb
, EbS
}, 0 },
1899 { "subS", { Gv
, EvS
}, 0 },
1900 { "subB", { AL
, Ib
}, 0 },
1901 { "subS", { eAX
, Iv
}, 0 },
1902 { Bad_Opcode
}, /* SEG CS prefix */
1903 { X86_64_TABLE (X86_64_2F
) },
1905 { "xorB", { Ebh1
, Gb
}, 0 },
1906 { "xorS", { Evh1
, Gv
}, 0 },
1907 { "xorB", { Gb
, EbS
}, 0 },
1908 { "xorS", { Gv
, EvS
}, 0 },
1909 { "xorB", { AL
, Ib
}, 0 },
1910 { "xorS", { eAX
, Iv
}, 0 },
1911 { Bad_Opcode
}, /* SEG SS prefix */
1912 { X86_64_TABLE (X86_64_37
) },
1914 { "cmpB", { Eb
, Gb
}, 0 },
1915 { "cmpS", { Ev
, Gv
}, 0 },
1916 { "cmpB", { Gb
, EbS
}, 0 },
1917 { "cmpS", { Gv
, EvS
}, 0 },
1918 { "cmpB", { AL
, Ib
}, 0 },
1919 { "cmpS", { eAX
, Iv
}, 0 },
1920 { Bad_Opcode
}, /* SEG DS prefix */
1921 { X86_64_TABLE (X86_64_3F
) },
1923 { "inc{S|}", { RMeAX
}, 0 },
1924 { "inc{S|}", { RMeCX
}, 0 },
1925 { "inc{S|}", { RMeDX
}, 0 },
1926 { "inc{S|}", { RMeBX
}, 0 },
1927 { "inc{S|}", { RMeSP
}, 0 },
1928 { "inc{S|}", { RMeBP
}, 0 },
1929 { "inc{S|}", { RMeSI
}, 0 },
1930 { "inc{S|}", { RMeDI
}, 0 },
1932 { "dec{S|}", { RMeAX
}, 0 },
1933 { "dec{S|}", { RMeCX
}, 0 },
1934 { "dec{S|}", { RMeDX
}, 0 },
1935 { "dec{S|}", { RMeBX
}, 0 },
1936 { "dec{S|}", { RMeSP
}, 0 },
1937 { "dec{S|}", { RMeBP
}, 0 },
1938 { "dec{S|}", { RMeSI
}, 0 },
1939 { "dec{S|}", { RMeDI
}, 0 },
1941 { "push!P", { RMrAX
}, 0 },
1942 { "push!P", { RMrCX
}, 0 },
1943 { "push!P", { RMrDX
}, 0 },
1944 { "push!P", { RMrBX
}, 0 },
1945 { "push!P", { RMrSP
}, 0 },
1946 { "push!P", { RMrBP
}, 0 },
1947 { "push!P", { RMrSI
}, 0 },
1948 { "push!P", { RMrDI
}, 0 },
1950 { "pop!P", { RMrAX
}, 0 },
1951 { "pop!P", { RMrCX
}, 0 },
1952 { "pop!P", { RMrDX
}, 0 },
1953 { "pop!P", { RMrBX
}, 0 },
1954 { "pop!P", { RMrSP
}, 0 },
1955 { "pop!P", { RMrBP
}, 0 },
1956 { "pop!P", { RMrSI
}, 0 },
1957 { "pop!P", { RMrDI
}, 0 },
1959 { X86_64_TABLE (X86_64_60
) },
1960 { X86_64_TABLE (X86_64_61
) },
1961 { X86_64_TABLE (X86_64_62
) },
1962 { X86_64_TABLE (X86_64_63
) },
1963 { Bad_Opcode
}, /* seg fs */
1964 { Bad_Opcode
}, /* seg gs */
1965 { Bad_Opcode
}, /* op size prefix */
1966 { Bad_Opcode
}, /* adr size prefix */
1968 { "pushP", { sIv
}, 0 },
1969 { "imulS", { Gv
, Ev
, Iv
}, 0 },
1970 { "pushP", { sIbT
}, 0 },
1971 { "imulS", { Gv
, Ev
, sIb
}, 0 },
1972 { "ins{b|}", { Ybr
, indirDX
}, 0 },
1973 { X86_64_TABLE (X86_64_6D
) },
1974 { "outs{b|}", { indirDXr
, Xb
}, 0 },
1975 { X86_64_TABLE (X86_64_6F
) },
1977 { "joH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1978 { "jnoH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1979 { "jbH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1980 { "jaeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1981 { "jeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1982 { "jneH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1983 { "jbeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1984 { "jaH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1986 { "jsH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1987 { "jnsH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1988 { "jpH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1989 { "jnpH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1990 { "jlH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1991 { "jgeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1992 { "jleH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1993 { "jgH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
1995 { REG_TABLE (REG_80
) },
1996 { REG_TABLE (REG_81
) },
1997 { X86_64_TABLE (X86_64_82
) },
1998 { REG_TABLE (REG_83
) },
1999 { "testB", { Eb
, Gb
}, 0 },
2000 { "testS", { Ev
, Gv
}, 0 },
2001 { "xchgB", { Ebh2
, Gb
}, 0 },
2002 { "xchgS", { Evh2
, Gv
}, 0 },
2004 { "movB", { Ebh3
, Gb
}, 0 },
2005 { "movS", { Evh3
, Gv
}, 0 },
2006 { "movB", { Gb
, EbS
}, 0 },
2007 { "movS", { Gv
, EvS
}, 0 },
2008 { "movD", { Sv
, Sw
}, 0 },
2009 { "leaS", { Gv
, M
}, 0 },
2010 { "movD", { Sw
, Sv
}, 0 },
2011 { REG_TABLE (REG_8F
) },
2013 { PREFIX_TABLE (PREFIX_90
) },
2014 { "xchgS", { RMeCX
, eAX
}, 0 },
2015 { "xchgS", { RMeDX
, eAX
}, 0 },
2016 { "xchgS", { RMeBX
, eAX
}, 0 },
2017 { "xchgS", { RMeSP
, eAX
}, 0 },
2018 { "xchgS", { RMeBP
, eAX
}, 0 },
2019 { "xchgS", { RMeSI
, eAX
}, 0 },
2020 { "xchgS", { RMeDI
, eAX
}, 0 },
2022 { "cW{t|}R", { XX
}, 0 },
2023 { "cR{t|}O", { XX
}, 0 },
2024 { X86_64_TABLE (X86_64_9A
) },
2025 { Bad_Opcode
}, /* fwait */
2026 { "pushfP", { XX
}, 0 },
2027 { "popfP", { XX
}, 0 },
2028 { "sahf", { XX
}, 0 },
2029 { "lahf", { XX
}, 0 },
2031 { "mov%LB", { AL
, Ob
}, PREFIX_REX2_ILLEGAL
},
2032 { "mov%LS", { { JMPABS_Fixup
, eAX_reg
}, { JMPABS_Fixup
, v_mode
} }, PREFIX_REX2_ILLEGAL
},
2033 { "mov%LB", { Ob
, AL
}, PREFIX_REX2_ILLEGAL
},
2034 { "mov%LS", { Ov
, eAX
}, PREFIX_REX2_ILLEGAL
},
2035 { "movs{b|}", { Ybr
, Xb
}, PREFIX_REX2_ILLEGAL
},
2036 { "movs{R|}", { Yvr
, Xv
}, PREFIX_REX2_ILLEGAL
},
2037 { "cmps{b|}", { Xb
, Yb
}, PREFIX_REX2_ILLEGAL
},
2038 { "cmps{R|}", { Xv
, Yv
}, PREFIX_REX2_ILLEGAL
},
2040 { "testB", { AL
, Ib
}, PREFIX_REX2_ILLEGAL
},
2041 { "testS", { eAX
, Iv
}, PREFIX_REX2_ILLEGAL
},
2042 { "stosB", { Ybr
, AL
}, PREFIX_REX2_ILLEGAL
},
2043 { "stosS", { Yvr
, eAX
}, PREFIX_REX2_ILLEGAL
},
2044 { "lodsB", { ALr
, Xb
}, PREFIX_REX2_ILLEGAL
},
2045 { "lodsS", { eAXr
, Xv
}, PREFIX_REX2_ILLEGAL
},
2046 { "scasB", { AL
, Yb
}, PREFIX_REX2_ILLEGAL
},
2047 { "scasS", { eAX
, Yv
}, PREFIX_REX2_ILLEGAL
},
2049 { "movB", { RMAL
, Ib
}, 0 },
2050 { "movB", { RMCL
, Ib
}, 0 },
2051 { "movB", { RMDL
, Ib
}, 0 },
2052 { "movB", { RMBL
, Ib
}, 0 },
2053 { "movB", { RMAH
, Ib
}, 0 },
2054 { "movB", { RMCH
, Ib
}, 0 },
2055 { "movB", { RMDH
, Ib
}, 0 },
2056 { "movB", { RMBH
, Ib
}, 0 },
2058 { "mov%LV", { RMeAX
, Iv64
}, 0 },
2059 { "mov%LV", { RMeCX
, Iv64
}, 0 },
2060 { "mov%LV", { RMeDX
, Iv64
}, 0 },
2061 { "mov%LV", { RMeBX
, Iv64
}, 0 },
2062 { "mov%LV", { RMeSP
, Iv64
}, 0 },
2063 { "mov%LV", { RMeBP
, Iv64
}, 0 },
2064 { "mov%LV", { RMeSI
, Iv64
}, 0 },
2065 { "mov%LV", { RMeDI
, Iv64
}, 0 },
2067 { REG_TABLE (REG_C0
) },
2068 { REG_TABLE (REG_C1
) },
2069 { X86_64_TABLE (X86_64_C2
) },
2070 { X86_64_TABLE (X86_64_C3
) },
2071 { X86_64_TABLE (X86_64_C4
) },
2072 { X86_64_TABLE (X86_64_C5
) },
2073 { REG_TABLE (REG_C6
) },
2074 { REG_TABLE (REG_C7
) },
2076 { "enterP", { Iw
, Ib
}, 0 },
2077 { "leaveP", { XX
}, 0 },
2078 { "{l|}ret{|f}%LP", { Iw
}, 0 },
2079 { "{l|}ret{|f}%LP", { XX
}, 0 },
2080 { "int3", { XX
}, 0 },
2081 { "int", { Ib
}, 0 },
2082 { X86_64_TABLE (X86_64_CE
) },
2083 { "iret%LP", { XX
}, 0 },
2085 { REG_TABLE (REG_D0
) },
2086 { REG_TABLE (REG_D1
) },
2087 { REG_TABLE (REG_D2
) },
2088 { REG_TABLE (REG_D3
) },
2089 { X86_64_TABLE (X86_64_D4
) },
2090 { X86_64_TABLE (X86_64_D5
) },
2092 { "xlat", { DSBX
}, 0 },
2103 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2104 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2105 { "loopFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2106 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2107 { "inB", { AL
, Ib
}, PREFIX_REX2_ILLEGAL
},
2108 { "inG", { zAX
, Ib
}, PREFIX_REX2_ILLEGAL
},
2109 { "outB", { Ib
, AL
}, PREFIX_REX2_ILLEGAL
},
2110 { "outG", { Ib
, zAX
}, PREFIX_REX2_ILLEGAL
},
2112 { X86_64_TABLE (X86_64_E8
) },
2113 { X86_64_TABLE (X86_64_E9
) },
2114 { X86_64_TABLE (X86_64_EA
) },
2115 { "jmp", { Jb
, BND
}, PREFIX_REX2_ILLEGAL
},
2116 { "inB", { AL
, indirDX
}, PREFIX_REX2_ILLEGAL
},
2117 { "inG", { zAX
, indirDX
}, PREFIX_REX2_ILLEGAL
},
2118 { "outB", { indirDX
, AL
}, PREFIX_REX2_ILLEGAL
},
2119 { "outG", { indirDX
, zAX
}, PREFIX_REX2_ILLEGAL
},
2121 { Bad_Opcode
}, /* lock prefix */
2122 { "int1", { XX
}, 0 },
2123 { Bad_Opcode
}, /* repne */
2124 { Bad_Opcode
}, /* repz */
2125 { "hlt", { XX
}, 0 },
2126 { "cmc", { XX
}, 0 },
2127 { REG_TABLE (REG_F6
) },
2128 { REG_TABLE (REG_F7
) },
2130 { "clc", { XX
}, 0 },
2131 { "stc", { XX
}, 0 },
2132 { "cli", { XX
}, 0 },
2133 { "sti", { XX
}, 0 },
2134 { "cld", { XX
}, 0 },
2135 { "std", { XX
}, 0 },
2136 { REG_TABLE (REG_FE
) },
2137 { REG_TABLE (REG_FF
) },
2140 static const struct dis386 dis386_twobyte
[] = {
2142 { REG_TABLE (REG_0F00
) },
2143 { REG_TABLE (REG_0F01
) },
2144 { "larS", { Gv
, Sv
}, 0 },
2145 { "lslS", { Gv
, Sv
}, 0 },
2147 { "syscall", { XX
}, 0 },
2148 { "clts", { XX
}, 0 },
2149 { "sysret%LQ", { XX
}, 0 },
2151 { "invd", { XX
}, 0 },
2152 { PREFIX_TABLE (PREFIX_0F09
) },
2154 { "ud2", { XX
}, 0 },
2156 { REG_TABLE (REG_0F0D
) },
2157 { "femms", { XX
}, 0 },
2158 { "", { MX
, EM
, OPSUF
}, 0 }, /* See OP_3DNowSuffix. */
2160 { PREFIX_TABLE (PREFIX_0F10
) },
2161 { PREFIX_TABLE (PREFIX_0F11
) },
2162 { PREFIX_TABLE (PREFIX_0F12
) },
2163 { "movlpX", { Mq
, XM
}, PREFIX_OPCODE
},
2164 { "unpcklpX", { XM
, EXx
}, PREFIX_OPCODE
},
2165 { "unpckhpX", { XM
, EXx
}, PREFIX_OPCODE
},
2166 { PREFIX_TABLE (PREFIX_0F16
) },
2167 { "movhpX", { Mq
, XM
}, PREFIX_OPCODE
},
2169 { REG_TABLE (REG_0F18
) },
2170 { "nopQ", { Ev
}, 0 },
2171 { PREFIX_TABLE (PREFIX_0F1A
) },
2172 { PREFIX_TABLE (PREFIX_0F1B
) },
2173 { PREFIX_TABLE (PREFIX_0F1C
) },
2174 { "nopQ", { Ev
}, 0 },
2175 { PREFIX_TABLE (PREFIX_0F1E
) },
2176 { "nopQ", { Ev
}, 0 },
2178 { "movZ", { Em
, Cm
}, 0 },
2179 { "movZ", { Em
, Dm
}, 0 },
2180 { "movZ", { Cm
, Em
}, 0 },
2181 { "movZ", { Dm
, Em
}, 0 },
2182 { X86_64_TABLE (X86_64_0F24
) },
2184 { X86_64_TABLE (X86_64_0F26
) },
2187 { "movapX", { XM
, EXx
}, PREFIX_OPCODE
},
2188 { "movapX", { EXxS
, XM
}, PREFIX_OPCODE
},
2189 { PREFIX_TABLE (PREFIX_0F2A
) },
2190 { PREFIX_TABLE (PREFIX_0F2B
) },
2191 { PREFIX_TABLE (PREFIX_0F2C
) },
2192 { PREFIX_TABLE (PREFIX_0F2D
) },
2193 { PREFIX_TABLE (PREFIX_0F2E
) },
2194 { PREFIX_TABLE (PREFIX_0F2F
) },
2196 { "wrmsr", { XX
}, PREFIX_REX2_ILLEGAL
},
2197 { "rdtsc", { XX
}, PREFIX_REX2_ILLEGAL
},
2198 { "rdmsr", { XX
}, PREFIX_REX2_ILLEGAL
},
2199 { "rdpmc", { XX
}, PREFIX_REX2_ILLEGAL
},
2200 { "sysenter", { SEP
}, PREFIX_REX2_ILLEGAL
},
2201 { "sysexit%LQ", { SEP
}, PREFIX_REX2_ILLEGAL
},
2203 { "getsec", { XX
}, 0 },
2205 { THREE_BYTE_TABLE (THREE_BYTE_0F38
) },
2207 { THREE_BYTE_TABLE (THREE_BYTE_0F3A
) },
2214 { "cmovoS", { Gv
, Ev
}, 0 },
2215 { "cmovnoS", { Gv
, Ev
}, 0 },
2216 { "cmovbS", { Gv
, Ev
}, 0 },
2217 { "cmovaeS", { Gv
, Ev
}, 0 },
2218 { "cmoveS", { Gv
, Ev
}, 0 },
2219 { "cmovneS", { Gv
, Ev
}, 0 },
2220 { "cmovbeS", { Gv
, Ev
}, 0 },
2221 { "cmovaS", { Gv
, Ev
}, 0 },
2223 { "cmovsS", { Gv
, Ev
}, 0 },
2224 { "cmovnsS", { Gv
, Ev
}, 0 },
2225 { "cmovpS", { Gv
, Ev
}, 0 },
2226 { "cmovnpS", { Gv
, Ev
}, 0 },
2227 { "cmovlS", { Gv
, Ev
}, 0 },
2228 { "cmovgeS", { Gv
, Ev
}, 0 },
2229 { "cmovleS", { Gv
, Ev
}, 0 },
2230 { "cmovgS", { Gv
, Ev
}, 0 },
2232 { "movmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
2233 { PREFIX_TABLE (PREFIX_0F51
) },
2234 { PREFIX_TABLE (PREFIX_0F52
) },
2235 { PREFIX_TABLE (PREFIX_0F53
) },
2236 { "andpX", { XM
, EXx
}, PREFIX_OPCODE
},
2237 { "andnpX", { XM
, EXx
}, PREFIX_OPCODE
},
2238 { "orpX", { XM
, EXx
}, PREFIX_OPCODE
},
2239 { "xorpX", { XM
, EXx
}, PREFIX_OPCODE
},
2241 { PREFIX_TABLE (PREFIX_0F58
) },
2242 { PREFIX_TABLE (PREFIX_0F59
) },
2243 { PREFIX_TABLE (PREFIX_0F5A
) },
2244 { PREFIX_TABLE (PREFIX_0F5B
) },
2245 { PREFIX_TABLE (PREFIX_0F5C
) },
2246 { PREFIX_TABLE (PREFIX_0F5D
) },
2247 { PREFIX_TABLE (PREFIX_0F5E
) },
2248 { PREFIX_TABLE (PREFIX_0F5F
) },
2250 { PREFIX_TABLE (PREFIX_0F60
) },
2251 { PREFIX_TABLE (PREFIX_0F61
) },
2252 { PREFIX_TABLE (PREFIX_0F62
) },
2253 { "packsswb", { MX
, EM
}, PREFIX_OPCODE
},
2254 { "pcmpgtb", { MX
, EM
}, PREFIX_OPCODE
},
2255 { "pcmpgtw", { MX
, EM
}, PREFIX_OPCODE
},
2256 { "pcmpgtd", { MX
, EM
}, PREFIX_OPCODE
},
2257 { "packuswb", { MX
, EM
}, PREFIX_OPCODE
},
2259 { "punpckhbw", { MX
, EM
}, PREFIX_OPCODE
},
2260 { "punpckhwd", { MX
, EM
}, PREFIX_OPCODE
},
2261 { "punpckhdq", { MX
, EM
}, PREFIX_OPCODE
},
2262 { "packssdw", { MX
, EM
}, PREFIX_OPCODE
},
2263 { "punpcklqdq", { XM
, EXx
}, PREFIX_DATA
},
2264 { "punpckhqdq", { XM
, EXx
}, PREFIX_DATA
},
2265 { "movK", { MX
, Edq
}, PREFIX_OPCODE
},
2266 { PREFIX_TABLE (PREFIX_0F6F
) },
2268 { PREFIX_TABLE (PREFIX_0F70
) },
2269 { REG_TABLE (REG_0F71
) },
2270 { REG_TABLE (REG_0F72
) },
2271 { REG_TABLE (REG_0F73
) },
2272 { "pcmpeqb", { MX
, EM
}, PREFIX_OPCODE
},
2273 { "pcmpeqw", { MX
, EM
}, PREFIX_OPCODE
},
2274 { "pcmpeqd", { MX
, EM
}, PREFIX_OPCODE
},
2275 { "emms", { XX
}, PREFIX_OPCODE
},
2277 { PREFIX_TABLE (PREFIX_0F78
) },
2278 { PREFIX_TABLE (PREFIX_0F79
) },
2281 { PREFIX_TABLE (PREFIX_0F7C
) },
2282 { PREFIX_TABLE (PREFIX_0F7D
) },
2283 { PREFIX_TABLE (PREFIX_0F7E
) },
2284 { PREFIX_TABLE (PREFIX_0F7F
) },
2286 { "joH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2287 { "jnoH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2288 { "jbH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2289 { "jaeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2290 { "jeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2291 { "jneH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2292 { "jbeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2293 { "jaH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2295 { "jsH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2296 { "jnsH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2297 { "jpH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2298 { "jnpH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2299 { "jlH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2300 { "jgeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2301 { "jleH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2302 { "jgH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2304 { "seto", { Eb
}, 0 },
2305 { "setno", { Eb
}, 0 },
2306 { "setb", { Eb
}, 0 },
2307 { "setae", { Eb
}, 0 },
2308 { "sete", { Eb
}, 0 },
2309 { "setne", { Eb
}, 0 },
2310 { "setbe", { Eb
}, 0 },
2311 { "seta", { Eb
}, 0 },
2313 { "sets", { Eb
}, 0 },
2314 { "setns", { Eb
}, 0 },
2315 { "setp", { Eb
}, 0 },
2316 { "setnp", { Eb
}, 0 },
2317 { "setl", { Eb
}, 0 },
2318 { "setge", { Eb
}, 0 },
2319 { "setle", { Eb
}, 0 },
2320 { "setg", { Eb
}, 0 },
2322 { "pushP", { fs
}, 0 },
2323 { "popP", { fs
}, 0 },
2324 { "cpuid", { XX
}, 0 },
2325 { "btS", { Ev
, Gv
}, 0 },
2326 { "shldS", { Ev
, Gv
, Ib
}, 0 },
2327 { "shldS", { Ev
, Gv
, CL
}, 0 },
2328 { REG_TABLE (REG_0FA6
) },
2329 { REG_TABLE (REG_0FA7
) },
2331 { "pushP", { gs
}, 0 },
2332 { "popP", { gs
}, 0 },
2333 { "rsm", { XX
}, 0 },
2334 { "btsS", { Evh1
, Gv
}, 0 },
2335 { "shrdS", { Ev
, Gv
, Ib
}, 0 },
2336 { "shrdS", { Ev
, Gv
, CL
}, 0 },
2337 { REG_TABLE (REG_0FAE
) },
2338 { "imulS", { Gv
, Ev
}, 0 },
2340 { "cmpxchgB", { Ebh1
, Gb
}, 0 },
2341 { "cmpxchgS", { Evh1
, Gv
}, 0 },
2342 { "lssS", { Gv
, Mp
}, 0 },
2343 { "btrS", { Evh1
, Gv
}, 0 },
2344 { "lfsS", { Gv
, Mp
}, 0 },
2345 { "lgsS", { Gv
, Mp
}, 0 },
2346 { "movz{bR|x}", { Gv
, Eb
}, 0 },
2347 { "movz{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movzww ! */
2349 { PREFIX_TABLE (PREFIX_0FB8
) },
2350 { "ud1S", { Gv
, Ev
}, 0 },
2351 { REG_TABLE (REG_0FBA
) },
2352 { "btcS", { Evh1
, Gv
}, 0 },
2353 { PREFIX_TABLE (PREFIX_0FBC
) },
2354 { PREFIX_TABLE (PREFIX_0FBD
) },
2355 { "movs{bR|x}", { Gv
, Eb
}, 0 },
2356 { "movs{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movsww ! */
2358 { "xaddB", { Ebh1
, Gb
}, 0 },
2359 { "xaddS", { Evh1
, Gv
}, 0 },
2360 { PREFIX_TABLE (PREFIX_0FC2
) },
2361 { "movntiS", { Mdq
, Gdq
}, PREFIX_OPCODE
},
2362 { "pinsrw", { MX
, Edw
, Ib
}, PREFIX_OPCODE
},
2363 { "pextrw", { Gd
, Nq
, Ib
}, PREFIX_OPCODE
},
2364 { "shufpX", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
2365 { REG_TABLE (REG_0FC7
) },
2367 { "bswap", { RMeAX
}, 0 },
2368 { "bswap", { RMeCX
}, 0 },
2369 { "bswap", { RMeDX
}, 0 },
2370 { "bswap", { RMeBX
}, 0 },
2371 { "bswap", { RMeSP
}, 0 },
2372 { "bswap", { RMeBP
}, 0 },
2373 { "bswap", { RMeSI
}, 0 },
2374 { "bswap", { RMeDI
}, 0 },
2376 { PREFIX_TABLE (PREFIX_0FD0
) },
2377 { "psrlw", { MX
, EM
}, PREFIX_OPCODE
},
2378 { "psrld", { MX
, EM
}, PREFIX_OPCODE
},
2379 { "psrlq", { MX
, EM
}, PREFIX_OPCODE
},
2380 { "paddq", { MX
, EM
}, PREFIX_OPCODE
},
2381 { "pmullw", { MX
, EM
}, PREFIX_OPCODE
},
2382 { PREFIX_TABLE (PREFIX_0FD6
) },
2383 { "pmovmskb", { Gdq
, Nq
}, PREFIX_OPCODE
},
2385 { "psubusb", { MX
, EM
}, PREFIX_OPCODE
},
2386 { "psubusw", { MX
, EM
}, PREFIX_OPCODE
},
2387 { "pminub", { MX
, EM
}, PREFIX_OPCODE
},
2388 { "pand", { MX
, EM
}, PREFIX_OPCODE
},
2389 { "paddusb", { MX
, EM
}, PREFIX_OPCODE
},
2390 { "paddusw", { MX
, EM
}, PREFIX_OPCODE
},
2391 { "pmaxub", { MX
, EM
}, PREFIX_OPCODE
},
2392 { "pandn", { MX
, EM
}, PREFIX_OPCODE
},
2394 { "pavgb", { MX
, EM
}, PREFIX_OPCODE
},
2395 { "psraw", { MX
, EM
}, PREFIX_OPCODE
},
2396 { "psrad", { MX
, EM
}, PREFIX_OPCODE
},
2397 { "pavgw", { MX
, EM
}, PREFIX_OPCODE
},
2398 { "pmulhuw", { MX
, EM
}, PREFIX_OPCODE
},
2399 { "pmulhw", { MX
, EM
}, PREFIX_OPCODE
},
2400 { PREFIX_TABLE (PREFIX_0FE6
) },
2401 { PREFIX_TABLE (PREFIX_0FE7
) },
2403 { "psubsb", { MX
, EM
}, PREFIX_OPCODE
},
2404 { "psubsw", { MX
, EM
}, PREFIX_OPCODE
},
2405 { "pminsw", { MX
, EM
}, PREFIX_OPCODE
},
2406 { "por", { MX
, EM
}, PREFIX_OPCODE
},
2407 { "paddsb", { MX
, EM
}, PREFIX_OPCODE
},
2408 { "paddsw", { MX
, EM
}, PREFIX_OPCODE
},
2409 { "pmaxsw", { MX
, EM
}, PREFIX_OPCODE
},
2410 { "pxor", { MX
, EM
}, PREFIX_OPCODE
},
2412 { PREFIX_TABLE (PREFIX_0FF0
) },
2413 { "psllw", { MX
, EM
}, PREFIX_OPCODE
},
2414 { "pslld", { MX
, EM
}, PREFIX_OPCODE
},
2415 { "psllq", { MX
, EM
}, PREFIX_OPCODE
},
2416 { "pmuludq", { MX
, EM
}, PREFIX_OPCODE
},
2417 { "pmaddwd", { MX
, EM
}, PREFIX_OPCODE
},
2418 { "psadbw", { MX
, EM
}, PREFIX_OPCODE
},
2419 { PREFIX_TABLE (PREFIX_0FF7
) },
2421 { "psubb", { MX
, EM
}, PREFIX_OPCODE
},
2422 { "psubw", { MX
, EM
}, PREFIX_OPCODE
},
2423 { "psubd", { MX
, EM
}, PREFIX_OPCODE
},
2424 { "psubq", { MX
, EM
}, PREFIX_OPCODE
},
2425 { "paddb", { MX
, EM
}, PREFIX_OPCODE
},
2426 { "paddw", { MX
, EM
}, PREFIX_OPCODE
},
2427 { "paddd", { MX
, EM
}, PREFIX_OPCODE
},
2428 { "ud0S", { Gv
, Ev
}, 0 },
2431 static const bool onebyte_has_modrm
[256] = {
2432 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2433 /* ------------------------------- */
2434 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
2435 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
2436 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
2437 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
2438 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
2439 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
2440 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
2441 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
2442 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
2443 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
2444 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
2445 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
2446 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
2447 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
2448 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
2449 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
2450 /* ------------------------------- */
2451 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2454 static const bool twobyte_has_modrm
[256] = {
2455 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2456 /* ------------------------------- */
2457 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
2458 /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
2459 /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
2460 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
2461 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
2462 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
2463 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
2464 /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
2465 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2466 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
2467 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
2468 /* b0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bf */
2469 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
2470 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
2471 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
2472 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /* ff */
2473 /* ------------------------------- */
2474 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2484 /* If we are accessing mod/rm/reg without need_modrm set, then the
2485 values are stale. Hitting this abort likely indicates that you
2486 need to update onebyte_has_modrm or twobyte_has_modrm. */
2487 #define MODRM_CHECK if (!ins->need_modrm) abort ()
2489 static const char intel_index16
[][6] = {
2490 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
2493 static const char att_names64
[][8] = {
2494 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
2495 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
2496 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
2497 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
2499 static const char att_names32
[][8] = {
2500 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
2501 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d",
2502 "%r16d", "%r17d", "%r18d", "%r19d", "%r20d", "%r21d", "%r22d", "%r23d",
2503 "%r24d", "%r25d", "%r26d", "%r27d", "%r28d", "%r29d", "%r30d", "%r31d",
2505 static const char att_names16
[][8] = {
2506 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
2507 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w",
2508 "%r16w", "%r17w", "%r18w", "%r19w", "%r20w", "%r21w", "%r22w", "%r23w",
2509 "%r24w", "%r25w", "%r26w", "%r27w", "%r28w", "%r29w", "%r30w", "%r31w",
2511 static const char att_names8
[][8] = {
2512 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
2514 static const char att_names8rex
[][8] = {
2515 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
2516 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b",
2517 "%r16b", "%r17b", "%r18b", "%r19b", "%r20b", "%r21b", "%r22b", "%r23b",
2518 "%r24b", "%r25b", "%r26b", "%r27b", "%r28b", "%r29b", "%r30b", "%r31b",
2520 static const char att_names_seg
[][4] = {
2521 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
2523 static const char att_index64
[] = "%riz";
2524 static const char att_index32
[] = "%eiz";
2525 static const char att_index16
[][8] = {
2526 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
2529 static const char att_names_mm
[][8] = {
2530 "%mm0", "%mm1", "%mm2", "%mm3",
2531 "%mm4", "%mm5", "%mm6", "%mm7"
2534 static const char att_names_bnd
[][8] = {
2535 "%bnd0", "%bnd1", "%bnd2", "%bnd3"
2538 static const char att_names_xmm
[][8] = {
2539 "%xmm0", "%xmm1", "%xmm2", "%xmm3",
2540 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
2541 "%xmm8", "%xmm9", "%xmm10", "%xmm11",
2542 "%xmm12", "%xmm13", "%xmm14", "%xmm15",
2543 "%xmm16", "%xmm17", "%xmm18", "%xmm19",
2544 "%xmm20", "%xmm21", "%xmm22", "%xmm23",
2545 "%xmm24", "%xmm25", "%xmm26", "%xmm27",
2546 "%xmm28", "%xmm29", "%xmm30", "%xmm31"
2549 static const char att_names_ymm
[][8] = {
2550 "%ymm0", "%ymm1", "%ymm2", "%ymm3",
2551 "%ymm4", "%ymm5", "%ymm6", "%ymm7",
2552 "%ymm8", "%ymm9", "%ymm10", "%ymm11",
2553 "%ymm12", "%ymm13", "%ymm14", "%ymm15",
2554 "%ymm16", "%ymm17", "%ymm18", "%ymm19",
2555 "%ymm20", "%ymm21", "%ymm22", "%ymm23",
2556 "%ymm24", "%ymm25", "%ymm26", "%ymm27",
2557 "%ymm28", "%ymm29", "%ymm30", "%ymm31"
2560 static const char att_names_zmm
[][8] = {
2561 "%zmm0", "%zmm1", "%zmm2", "%zmm3",
2562 "%zmm4", "%zmm5", "%zmm6", "%zmm7",
2563 "%zmm8", "%zmm9", "%zmm10", "%zmm11",
2564 "%zmm12", "%zmm13", "%zmm14", "%zmm15",
2565 "%zmm16", "%zmm17", "%zmm18", "%zmm19",
2566 "%zmm20", "%zmm21", "%zmm22", "%zmm23",
2567 "%zmm24", "%zmm25", "%zmm26", "%zmm27",
2568 "%zmm28", "%zmm29", "%zmm30", "%zmm31"
2571 static const char att_names_tmm
[][8] = {
2572 "%tmm0", "%tmm1", "%tmm2", "%tmm3",
2573 "%tmm4", "%tmm5", "%tmm6", "%tmm7"
2576 static const char att_names_mask
[][8] = {
2577 "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
2580 static const char *const names_rounding
[] =
2588 static const struct dis386 reg_table
[][8] = {
2591 { "addA", { Ebh1
, Ib
}, 0 },
2592 { "orA", { Ebh1
, Ib
}, 0 },
2593 { "adcA", { Ebh1
, Ib
}, 0 },
2594 { "sbbA", { Ebh1
, Ib
}, 0 },
2595 { "andA", { Ebh1
, Ib
}, 0 },
2596 { "subA", { Ebh1
, Ib
}, 0 },
2597 { "xorA", { Ebh1
, Ib
}, 0 },
2598 { "cmpA", { Eb
, Ib
}, 0 },
2602 { "addQ", { Evh1
, Iv
}, 0 },
2603 { "orQ", { Evh1
, Iv
}, 0 },
2604 { "adcQ", { Evh1
, Iv
}, 0 },
2605 { "sbbQ", { Evh1
, Iv
}, 0 },
2606 { "andQ", { Evh1
, Iv
}, 0 },
2607 { "subQ", { Evh1
, Iv
}, 0 },
2608 { "xorQ", { Evh1
, Iv
}, 0 },
2609 { "cmpQ", { Ev
, Iv
}, 0 },
2613 { "addQ", { Evh1
, sIb
}, 0 },
2614 { "orQ", { Evh1
, sIb
}, 0 },
2615 { "adcQ", { Evh1
, sIb
}, 0 },
2616 { "sbbQ", { Evh1
, sIb
}, 0 },
2617 { "andQ", { Evh1
, sIb
}, 0 },
2618 { "subQ", { Evh1
, sIb
}, 0 },
2619 { "xorQ", { Evh1
, sIb
}, 0 },
2620 { "cmpQ", { Ev
, sIb
}, 0 },
2624 { "pop{P|}", { stackEv
}, 0 },
2625 { XOP_8F_TABLE () },
2629 { XOP_8F_TABLE () },
2633 { "%NFrolA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2634 { "%NFrorA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2635 { "rclA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2636 { "rcrA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2637 { "%NFshlA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2638 { "%NFshrA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2639 { "%NFshlA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2640 { "%NFsarA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2644 { "%NFrolQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2645 { "%NFrorQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2646 { "rclQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2647 { "rcrQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2648 { "%NFshlQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2649 { "%NFshrQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2650 { "%NFshlQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2651 { "%NFsarQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2655 { "movA", { Ebh3
, Ib
}, 0 },
2662 { RM_TABLE (RM_C6_REG_7
) },
2666 { "movQ", { Evh3
, Iv
}, 0 },
2673 { RM_TABLE (RM_C7_REG_7
) },
2677 { "%NFrolA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2678 { "%NFrorA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2679 { "rclA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2680 { "rcrA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2681 { "%NFshlA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2682 { "%NFshrA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2683 { "%NFshlA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2684 { "%NFsarA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2688 { "%NFrolQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2689 { "%NFrorQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2690 { "rclQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2691 { "rcrQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2692 { "%NFshlQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2693 { "%NFshrQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2694 { "%NFshlQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2695 { "%NFsarQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2699 { "%NFrolA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2700 { "%NFrorA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2701 { "rclA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2702 { "rcrA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2703 { "%NFshlA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2704 { "%NFshrA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2705 { "%NFshlA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2706 { "%NFsarA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2710 { "%NFrolQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2711 { "%NFrorQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2712 { "rclQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2713 { "rcrQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2714 { "%NFshlQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2715 { "%NFshrQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2716 { "%NFshlQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2717 { "%NFsarQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2721 { "testA", { Eb
, Ib
}, 0 },
2722 { "testA", { Eb
, Ib
}, 0 },
2723 { "notA", { Ebh1
}, 0 },
2724 { "negA", { Ebh1
}, 0 },
2725 { "mulA", { Eb
}, 0 }, /* Don't print the implicit %al register, */
2726 { "imulA", { Eb
}, 0 }, /* to distinguish these opcodes from other */
2727 { "divA", { Eb
}, 0 }, /* mul/imul opcodes. Do the same for div */
2728 { "idivA", { Eb
}, 0 }, /* and idiv for consistency. */
2732 { "testQ", { Ev
, Iv
}, 0 },
2733 { "testQ", { Ev
, Iv
}, 0 },
2734 { "notQ", { Evh1
}, 0 },
2735 { "negQ", { Evh1
}, 0 },
2736 { "mulQ", { Ev
}, 0 }, /* Don't print the implicit register. */
2737 { "imulQ", { Ev
}, 0 },
2738 { "divQ", { Ev
}, 0 },
2739 { "idivQ", { Ev
}, 0 },
2743 { "incA", { Ebh1
}, 0 },
2744 { "decA", { Ebh1
}, 0 },
2748 { "incQ", { Evh1
}, 0 },
2749 { "decQ", { Evh1
}, 0 },
2750 { "call{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2751 { "{l|}call^", { indirEp
}, 0 },
2752 { "jmp{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2753 { "{l|}jmp^", { indirEp
}, 0 },
2754 { "push{P|}", { stackEv
}, 0 },
2759 { "sldtD", { Sv
}, 0 },
2760 { "strD", { Sv
}, 0 },
2761 { "lldtD", { Sv
}, 0 },
2762 { "ltrD", { Sv
}, 0 },
2763 { "verrD", { Sv
}, 0 },
2764 { "verwD", { Sv
}, 0 },
2765 { X86_64_TABLE (X86_64_0F00_REG_6
) },
2770 { MOD_TABLE (MOD_0F01_REG_0
) },
2771 { MOD_TABLE (MOD_0F01_REG_1
) },
2772 { MOD_TABLE (MOD_0F01_REG_2
) },
2773 { MOD_TABLE (MOD_0F01_REG_3
) },
2774 { "smswD", { Sv
}, 0 },
2775 { MOD_TABLE (MOD_0F01_REG_5
) },
2776 { "lmsw", { Ew
}, 0 },
2777 { MOD_TABLE (MOD_0F01_REG_7
) },
2781 { "prefetch", { Mb
}, 0 },
2782 { "prefetchw", { Mb
}, 0 },
2783 { "prefetchwt1", { Mb
}, 0 },
2784 { "prefetch", { Mb
}, 0 },
2785 { "prefetch", { Mb
}, 0 },
2786 { "prefetch", { Mb
}, 0 },
2787 { "prefetch", { Mb
}, 0 },
2788 { "prefetch", { Mb
}, 0 },
2792 { MOD_TABLE (MOD_0F18_REG_0
) },
2793 { MOD_TABLE (MOD_0F18_REG_1
) },
2794 { MOD_TABLE (MOD_0F18_REG_2
) },
2795 { MOD_TABLE (MOD_0F18_REG_3
) },
2796 { "nopQ", { Ev
}, 0 },
2797 { "nopQ", { Ev
}, 0 },
2798 { MOD_TABLE (MOD_0F18_REG_6
) },
2799 { MOD_TABLE (MOD_0F18_REG_7
) },
2801 /* REG_0F1C_P_0_MOD_0 */
2803 { "cldemote", { Mb
}, 0 },
2804 { "nopQ", { Ev
}, 0 },
2805 { "nopQ", { Ev
}, 0 },
2806 { "nopQ", { Ev
}, 0 },
2807 { "nopQ", { Ev
}, 0 },
2808 { "nopQ", { Ev
}, 0 },
2809 { "nopQ", { Ev
}, 0 },
2810 { "nopQ", { Ev
}, 0 },
2812 /* REG_0F1E_P_1_MOD_3 */
2814 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2815 { "rdsspK", { Edq
}, 0 },
2816 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2817 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2818 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2819 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2820 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2821 { RM_TABLE (RM_0F1E_P_1_MOD_3_REG_7
) },
2823 /* REG_0F38D8_PREFIX_1 */
2825 { "aesencwide128kl", { M
}, 0 },
2826 { "aesdecwide128kl", { M
}, 0 },
2827 { "aesencwide256kl", { M
}, 0 },
2828 { "aesdecwide256kl", { M
}, 0 },
2830 /* REG_0F3A0F_P_1 */
2832 { RM_TABLE (RM_0F3A0F_P_1_R_0
) },
2838 { "psrlw", { Nq
, Ib
}, PREFIX_OPCODE
},
2840 { "psraw", { Nq
, Ib
}, PREFIX_OPCODE
},
2842 { "psllw", { Nq
, Ib
}, PREFIX_OPCODE
},
2848 { "psrld", { Nq
, Ib
}, PREFIX_OPCODE
},
2850 { "psrad", { Nq
, Ib
}, PREFIX_OPCODE
},
2852 { "pslld", { Nq
, Ib
}, PREFIX_OPCODE
},
2858 { "psrlq", { Nq
, Ib
}, PREFIX_OPCODE
},
2859 { "psrldq", { Ux
, Ib
}, PREFIX_DATA
},
2862 { "psllq", { Nq
, Ib
}, PREFIX_OPCODE
},
2863 { "pslldq", { Ux
, Ib
}, PREFIX_DATA
},
2867 { PREFIX_TABLE (PREFIX_0FA6_REG_0
) },
2868 { "xsha1", { { OP_0f07
, 0 } }, 0 },
2869 { "xsha256", { { OP_0f07
, 0 } }, 0 },
2872 { PREFIX_TABLE (PREFIX_0FA6_REG_5
) },
2876 { "xstore-rng", { { OP_0f07
, 0 } }, 0 },
2877 { "xcrypt-ecb", { { OP_0f07
, 0 } }, 0 },
2878 { "xcrypt-cbc", { { OP_0f07
, 0 } }, 0 },
2879 { "xcrypt-ctr", { { OP_0f07
, 0 } }, 0 },
2880 { "xcrypt-cfb", { { OP_0f07
, 0 } }, 0 },
2881 { "xcrypt-ofb", { { OP_0f07
, 0 } }, 0 },
2882 { PREFIX_TABLE (PREFIX_0FA7_REG_6
) },
2886 { MOD_TABLE (MOD_0FAE_REG_0
) },
2887 { MOD_TABLE (MOD_0FAE_REG_1
) },
2888 { MOD_TABLE (MOD_0FAE_REG_2
) },
2889 { MOD_TABLE (MOD_0FAE_REG_3
) },
2890 { MOD_TABLE (MOD_0FAE_REG_4
) },
2891 { MOD_TABLE (MOD_0FAE_REG_5
) },
2892 { MOD_TABLE (MOD_0FAE_REG_6
) },
2893 { MOD_TABLE (MOD_0FAE_REG_7
) },
2901 { "btQ", { Ev
, Ib
}, 0 },
2902 { "btsQ", { Evh1
, Ib
}, 0 },
2903 { "btrQ", { Evh1
, Ib
}, 0 },
2904 { "btcQ", { Evh1
, Ib
}, 0 },
2909 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} }, 0 },
2911 { "xrstors", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
2912 { "xsavec", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
2913 { "xsaves", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
2914 { MOD_TABLE (MOD_0FC7_REG_6
) },
2915 { MOD_TABLE (MOD_0FC7_REG_7
) },
2921 { "vpsrlw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2923 { "vpsraw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2925 { "vpsllw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2931 { "vpsrld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2933 { "vpsrad", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2935 { "vpslld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2941 { "vpsrlq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2942 { "vpsrldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2945 { "vpsllq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2946 { "vpslldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
2952 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_2
) },
2953 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_3
) },
2955 /* REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0 */
2957 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
) },
2959 /* REG_VEX_0F38F3_L_0_P_0 */
2962 { "%NFblsrS", { VexGdq
, Edq
}, 0 },
2963 { "%NFblsmskS", { VexGdq
, Edq
}, 0 },
2964 { "%NFblsiS", { VexGdq
, Edq
}, 0 },
2966 /* REG_VEX_MAP7_F6_L_0_W_0 */
2968 { X86_64_TABLE (X86_64_VEX_MAP7_F6_L_0_W_0_R_0
) },
2970 /* REG_VEX_MAP7_F8_L_0_W_0 */
2972 { X86_64_TABLE (X86_64_VEX_MAP7_F8_L_0_W_0_R_0
) },
2974 /* REG_XOP_09_01_L_0 */
2977 { "blcfill", { VexGdq
, Edq
}, 0 },
2978 { "blsfill", { VexGdq
, Edq
}, 0 },
2979 { "blcs", { VexGdq
, Edq
}, 0 },
2980 { "tzmsk", { VexGdq
, Edq
}, 0 },
2981 { "blcic", { VexGdq
, Edq
}, 0 },
2982 { "blsic", { VexGdq
, Edq
}, 0 },
2983 { "t1mskc", { VexGdq
, Edq
}, 0 },
2985 /* REG_XOP_09_02_L_0 */
2988 { "blcmsk", { VexGdq
, Edq
}, 0 },
2993 { "blci", { VexGdq
, Edq
}, 0 },
2995 /* REG_XOP_09_12_L_0 */
2997 { "llwpcb", { Rdq
}, 0 },
2998 { "slwpcb", { Rdq
}, 0 },
3000 /* REG_XOP_0A_12_L_0 */
3002 { "lwpins", { VexGdq
, Ed
, Id
}, 0 },
3003 { "lwpval", { VexGdq
, Ed
, Id
}, 0 },
3006 #include "i386-dis-evex-reg.h"
3009 static const struct dis386 prefix_table
[][4] = {
3012 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
3013 { "pause", { XX
}, 0 },
3014 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
3015 { NULL
, { { NULL
, 0 } }, PREFIX_IGNORED
}
3018 /* PREFIX_0F00_REG_6_X86_64 */
3023 { "lkgsD", { Sv
}, 0 },
3026 /* PREFIX_0F01_REG_0_MOD_3_RM_6 */
3028 { "wrmsrns", { Skip_MODRM
}, 0 },
3029 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_1
) },
3031 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_3
) },
3034 /* PREFIX_0F01_REG_0_MOD_3_RM_7 */
3036 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_7_P_0
) },
3039 /* PREFIX_0F01_REG_1_RM_2 */
3041 { "clac", { Skip_MODRM
}, 0 },
3042 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_1
) },
3044 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_3
)},
3047 /* PREFIX_0F01_REG_1_RM_4 */
3051 { "tdcall", { Skip_MODRM
}, 0 },
3055 /* PREFIX_0F01_REG_1_RM_5 */
3059 { X86_64_TABLE (X86_64_0F01_REG_1_RM_5_PREFIX_2
) },
3063 /* PREFIX_0F01_REG_1_RM_6 */
3067 { X86_64_TABLE (X86_64_0F01_REG_1_RM_6_PREFIX_2
) },
3071 /* PREFIX_0F01_REG_1_RM_7 */
3073 { "encls", { Skip_MODRM
}, 0 },
3075 { X86_64_TABLE (X86_64_0F01_REG_1_RM_7_PREFIX_2
) },
3079 /* PREFIX_0F01_REG_3_RM_1 */
3081 { "vmmcall", { Skip_MODRM
}, 0 },
3082 { "vmgexit", { Skip_MODRM
}, 0 },
3084 { "vmgexit", { Skip_MODRM
}, 0 },
3087 /* PREFIX_0F01_REG_5_MOD_0 */
3090 { "rstorssp", { Mq
}, PREFIX_OPCODE
},
3093 /* PREFIX_0F01_REG_5_MOD_3_RM_0 */
3095 { "serialize", { Skip_MODRM
}, PREFIX_OPCODE
},
3096 { "setssbsy", { Skip_MODRM
}, PREFIX_OPCODE
},
3098 { "xsusldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
3101 /* PREFIX_0F01_REG_5_MOD_3_RM_1 */
3106 { "xresldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
3109 /* PREFIX_0F01_REG_5_MOD_3_RM_2 */
3112 { "saveprevssp", { Skip_MODRM
}, PREFIX_OPCODE
},
3115 /* PREFIX_0F01_REG_5_MOD_3_RM_4 */
3118 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
) },
3121 /* PREFIX_0F01_REG_5_MOD_3_RM_5 */
3124 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
) },
3127 /* PREFIX_0F01_REG_5_MOD_3_RM_6 */
3129 { "rdpkru", { Skip_MODRM
}, 0 },
3130 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
) },
3133 /* PREFIX_0F01_REG_5_MOD_3_RM_7 */
3135 { "wrpkru", { Skip_MODRM
}, 0 },
3136 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
) },
3139 /* PREFIX_0F01_REG_7_MOD_3_RM_2 */
3141 { "monitorx", { { OP_Monitor
, 0 } }, 0 },
3142 { "mcommit", { Skip_MODRM
}, 0 },
3145 /* PREFIX_0F01_REG_7_MOD_3_RM_5 */
3147 { "rdpru", { Skip_MODRM
}, 0 },
3148 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
) },
3151 /* PREFIX_0F01_REG_7_MOD_3_RM_6 */
3153 { "invlpgb", { Skip_MODRM
}, 0 },
3154 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
) },
3156 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
) },
3159 /* PREFIX_0F01_REG_7_MOD_3_RM_7 */
3161 { "tlbsync", { Skip_MODRM
}, 0 },
3162 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
) },
3164 { "pvalidate", { Skip_MODRM
}, 0 },
3169 { "wbinvd", { XX
}, 0 },
3170 { "wbnoinvd", { XX
}, 0 },
3175 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3176 { "%XEVmovs%XS", { XMScalar
, VexScalarR
, EXd
}, 0 },
3177 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3178 { "%XEVmovs%XD", { XMScalar
, VexScalarR
, EXq
}, 0 },
3183 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3184 { "%XEVmovs%XS", { EXdS
, VexScalarR
, XMScalar
}, 0 },
3185 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3186 { "%XEVmovs%XD", { EXqS
, VexScalarR
, XMScalar
}, 0 },
3191 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
3192 { "movsldup", { XM
, EXx
}, 0 },
3193 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
3194 { "movddup", { XM
, EXq
}, 0 },
3199 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
3200 { "movshdup", { XM
, EXx
}, 0 },
3201 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
3204 /* PREFIX_0F18_REG_6_MOD_0_X86_64 */
3206 { "prefetchit1", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3207 { "nopQ", { Ev
}, 0 },
3208 { "nopQ", { Ev
}, 0 },
3209 { "nopQ", { Ev
}, 0 },
3212 /* PREFIX_0F18_REG_7_MOD_0_X86_64 */
3214 { "prefetchit0", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3215 { "nopQ", { Ev
}, 0 },
3216 { "nopQ", { Ev
}, 0 },
3217 { "nopQ", { Ev
}, 0 },
3222 { MOD_TABLE (MOD_0F1A_PREFIX_0
) },
3223 { "bndcl", { Gbnd
, Ev_bnd
}, 0 },
3224 { "bndmov", { Gbnd
, Ebnd
}, 0 },
3225 { "bndcu", { Gbnd
, Ev_bnd
}, 0 },
3230 { MOD_TABLE (MOD_0F1B_PREFIX_0
) },
3231 { MOD_TABLE (MOD_0F1B_PREFIX_1
) },
3232 { "bndmov", { EbndS
, Gbnd
}, 0 },
3233 { "bndcn", { Gbnd
, Ev_bnd
}, 0 },
3238 { MOD_TABLE (MOD_0F1C_PREFIX_0
) },
3239 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3240 { "nopQ", { Ev
}, 0 },
3241 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3246 { "nopQ", { Ev
}, 0 },
3247 { MOD_TABLE (MOD_0F1E_PREFIX_1
) },
3248 { "nopQ", { Ev
}, 0 },
3249 { NULL
, { XX
}, PREFIX_IGNORED
},
3254 { "cvtpi2ps", { XM
, EMCq
}, PREFIX_OPCODE
},
3255 { "cvtsi2ss{%LQ|}", { XM
, Edq
}, PREFIX_OPCODE
},
3256 { "cvtpi2pd", { XM
, EMCq
}, PREFIX_OPCODE
},
3257 { "cvtsi2sd{%LQ|}", { XM
, Edq
}, 0 },
3262 { "movntps", { Mx
, XM
}, 0 },
3263 { "movntss", { Md
, XM
}, 0 },
3264 { "movntpd", { Mx
, XM
}, 0 },
3265 { "movntsd", { Mq
, XM
}, 0 },
3270 { "cvttps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3271 { "cvttss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3272 { "cvttpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3273 { "cvttsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3278 { "cvtps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3279 { "cvtss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3280 { "cvtpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3281 { "cvtsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3286 { "%XEVucomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3288 { "%XEVucomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3293 { "%XEVcomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3295 { "%XEVcomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3300 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3301 { "%XEVsqrts%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3302 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3303 { "%XEVsqrts%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3308 { "Vrsqrtps", { XM
, EXx
}, 0 },
3309 { "Vrsqrtss", { XMScalar
, VexScalar
, EXd
}, 0 },
3314 { "Vrcpps", { XM
, EXx
}, 0 },
3315 { "Vrcpss", { XMScalar
, VexScalar
, EXd
}, 0 },
3320 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3321 { "%XEVadds%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3322 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3323 { "%XEVadds%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3328 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3329 { "%XEVmuls%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3330 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3331 { "%XEVmuls%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3336 { "%XEVcvtp%XS2pd", { XM
, EXEvexHalfBcstXmmq
, EXxEVexS
}, 0 },
3337 { "%XEVcvts%XS2sd", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3338 { "%XEVcvtp%XD2ps%XY", { XMxmmq
, EXx
, EXxEVexR
}, 0 },
3339 { "%XEVcvts%XD2ss", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3344 { "Vcvtdq2ps", { XM
, EXx
}, 0 },
3345 { "Vcvttps2dq", { XM
, EXx
}, 0 },
3346 { "Vcvtps2dq", { XM
, EXx
}, 0 },
3351 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3352 { "%XEVsubs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3353 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3354 { "%XEVsubs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3359 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3360 { "%XEVmins%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3361 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3362 { "%XEVmins%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3367 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3368 { "%XEVdivs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3369 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3370 { "%XEVdivs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3375 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3376 { "%XEVmaxs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3377 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3378 { "%XEVmaxs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3383 { "punpcklbw",{ MX
, EMd
}, PREFIX_OPCODE
},
3385 { "punpcklbw",{ MX
, EMx
}, PREFIX_OPCODE
},
3390 { "punpcklwd",{ MX
, EMd
}, PREFIX_OPCODE
},
3392 { "punpcklwd",{ MX
, EMx
}, PREFIX_OPCODE
},
3397 { "punpckldq",{ MX
, EMd
}, PREFIX_OPCODE
},
3399 { "punpckldq",{ MX
, EMx
}, PREFIX_OPCODE
},
3404 { "movq", { MX
, EM
}, PREFIX_OPCODE
},
3405 { "movdqu", { XM
, EXx
}, PREFIX_OPCODE
},
3406 { "movdqa", { XM
, EXx
}, PREFIX_OPCODE
},
3411 { "pshufw", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
3412 { "pshufhw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3413 { "pshufd", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3414 { "pshuflw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3419 {"vmread", { Em
, Gm
}, 0 },
3421 {"extrq", { Uxmm
, Ib
, Ib
}, 0 },
3422 {"insertq", { XM
, Uxmm
, Ib
, Ib
}, 0 },
3427 {"vmwrite", { Gm
, Em
}, 0 },
3429 {"extrq", { XM
, Uxmm
}, 0 },
3430 {"insertq", { XM
, Uxmm
}, 0 },
3437 { "Vhaddpd", { XM
, Vex
, EXx
}, 0 },
3438 { "Vhaddps", { XM
, Vex
, EXx
}, 0 },
3445 { "Vhsubpd", { XM
, Vex
, EXx
}, 0 },
3446 { "Vhsubps", { XM
, Vex
, EXx
}, 0 },
3451 { "movK", { Edq
, MX
}, PREFIX_OPCODE
},
3452 { "movq", { XM
, EXq
}, PREFIX_OPCODE
},
3453 { "movK", { Edq
, XM
}, PREFIX_OPCODE
},
3458 { "movq", { EMS
, MX
}, PREFIX_OPCODE
},
3459 { "movdqu", { EXxS
, XM
}, PREFIX_OPCODE
},
3460 { "movdqa", { EXxS
, XM
}, PREFIX_OPCODE
},
3463 /* PREFIX_0FA6_REG_0 */
3466 { "montmul", { { MONTMUL_Fixup
, 0 } }, 0},
3468 { "sm2", { Skip_MODRM
}, 0 },
3471 /* PREFIX_0FA6_REG_5 */
3474 { "sm3", { Skip_MODRM
}, 0 },
3477 /* PREFIX_0FA7_REG_6 */
3480 { "sm4", { Skip_MODRM
}, 0 },
3483 /* PREFIX_0FAE_REG_0_MOD_3 */
3486 { "rdfsbase", { Ev
}, 0 },
3489 /* PREFIX_0FAE_REG_1_MOD_3 */
3492 { "rdgsbase", { Ev
}, 0 },
3495 /* PREFIX_0FAE_REG_2_MOD_3 */
3498 { "wrfsbase", { Ev
}, 0 },
3501 /* PREFIX_0FAE_REG_3_MOD_3 */
3504 { "wrgsbase", { Ev
}, 0 },
3507 /* PREFIX_0FAE_REG_4_MOD_0 */
3509 { "xsave", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
3510 { "ptwrite{%LQ|}", { Edq
}, 0 },
3513 /* PREFIX_0FAE_REG_4_MOD_3 */
3516 { "ptwrite{%LQ|}", { Edq
}, 0 },
3519 /* PREFIX_0FAE_REG_5_MOD_3 */
3521 { "lfence", { Skip_MODRM
}, 0 },
3522 { "incsspK", { Edq
}, PREFIX_OPCODE
},
3525 /* PREFIX_0FAE_REG_6_MOD_0 */
3527 { "xsaveopt", { FXSAVE
}, PREFIX_OPCODE
| PREFIX_REX2_ILLEGAL
},
3528 { "clrssbsy", { Mq
}, PREFIX_OPCODE
},
3529 { "clwb", { Mb
}, PREFIX_OPCODE
},
3532 /* PREFIX_0FAE_REG_6_MOD_3 */
3534 { RM_TABLE (RM_0FAE_REG_6_MOD_3_P_0
) },
3535 { "umonitor", { Eva
}, PREFIX_OPCODE
},
3536 { "tpause", { Edq
}, PREFIX_OPCODE
},
3537 { "umwait", { Edq
}, PREFIX_OPCODE
},
3540 /* PREFIX_0FAE_REG_7_MOD_0 */
3542 { "clflush", { Mb
}, 0 },
3544 { "clflushopt", { Mb
}, 0 },
3550 { "popcntS", { Gv
, Ev
}, 0 },
3555 { "bsfS", { Gv
, Ev
}, 0 },
3556 { "tzcntS", { Gv
, Ev
}, 0 },
3557 { "bsfS", { Gv
, Ev
}, 0 },
3562 { "bsrS", { Gv
, Ev
}, 0 },
3563 { "lzcntS", { Gv
, Ev
}, 0 },
3564 { "bsrS", { Gv
, Ev
}, 0 },
3569 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3570 { "Vcmpss", { XMScalar
, VexScalar
, EXd
, CMP
}, 0 },
3571 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3572 { "Vcmpsd", { XMScalar
, VexScalar
, EXq
, CMP
}, 0 },
3575 /* PREFIX_0FC7_REG_6_MOD_0 */
3577 { "vmptrld",{ Mq
}, 0 },
3578 { "vmxon", { Mq
}, 0 },
3579 { "vmclear",{ Mq
}, 0 },
3582 /* PREFIX_0FC7_REG_6_MOD_3 */
3584 { "rdrand", { Ev
}, 0 },
3585 { X86_64_TABLE (X86_64_0FC7_REG_6_MOD_3_PREFIX_1
) },
3586 { "rdrand", { Ev
}, 0 }
3589 /* PREFIX_0FC7_REG_7_MOD_3 */
3591 { "rdseed", { Ev
}, 0 },
3592 { "rdpid", { Em
}, 0 },
3593 { "rdseed", { Ev
}, 0 },
3600 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3601 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3607 { "movq2dq",{ XM
, Nq
}, 0 },
3608 { "movq", { EXqS
, XM
}, 0 },
3609 { "movdq2q",{ MX
, Ux
}, 0 },
3615 { "Vcvtdq2pd", { XM
, EXxmmq
}, 0 },
3616 { "Vcvttpd2dq%XY", { XMM
, EXx
}, 0 },
3617 { "Vcvtpd2dq%XY", { XMM
, EXx
}, 0 },
3622 { "movntq", { Mq
, MX
}, 0 },
3624 { "movntdq", { Mx
, XM
}, 0 },
3632 { "Vlddqu", { XM
, M
}, 0 },
3637 { "maskmovq", { MX
, Nq
}, PREFIX_OPCODE
},
3639 { "maskmovdqu", { XM
, Ux
}, PREFIX_OPCODE
},
3645 { REG_TABLE (REG_0F38D8_PREFIX_1
) },
3651 { MOD_TABLE (MOD_0F38DC_PREFIX_1
) },
3652 { "aesenc", { XM
, EXx
}, 0 },
3658 { "aesdec128kl", { XM
, M
}, 0 },
3659 { "aesenclast", { XM
, EXx
}, 0 },
3665 { "aesenc256kl", { XM
, M
}, 0 },
3666 { "aesdec", { XM
, EXx
}, 0 },
3672 { "aesdec256kl", { XM
, M
}, 0 },
3673 { "aesdeclast", { XM
, EXx
}, 0 },
3678 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3680 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3681 { "crc32A", { Gdq
, Eb
}, PREFIX_OPCODE
},
3686 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3688 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3689 { "crc32Q", { Gdq
, Ev
}, PREFIX_OPCODE
},
3694 { "wrssK", { M
, Gdq
}, 0 },
3695 { "adoxL", { VexGdq
, Gdq
, Edq
}, 0 },
3696 { "adcxL", { VexGdq
, Gdq
, Edq
}, 0 },
3700 /* PREFIX_0F38F8_M_0 */
3703 { "enqcmds", { Gva
, M
}, 0 },
3704 { "movdir64b", { Gva
, M
}, 0 },
3705 { "enqcmd", { Gva
, M
}, 0 },
3708 /* PREFIX_0F38F8_M_1_X86_64 */
3711 { "uwrmsr", { Gq
, Rq
}, 0 },
3713 { "urdmsr", { Rq
, Gq
}, 0 },
3719 { "encodekey128", { Gd
, Rd
}, 0 },
3725 { "encodekey256", { Gd
, Rd
}, 0 },
3730 { "aadd", { Mdq
, Gdq
}, 0 },
3731 { "axor", { Mdq
, Gdq
}, 0 },
3732 { "aand", { Mdq
, Gdq
}, 0 },
3733 { "aor", { Mdq
, Gdq
}, 0 },
3739 { REG_TABLE (REG_0F3A0F_P_1
) },
3742 /* PREFIX_VEX_0F12 */
3744 { VEX_LEN_TABLE (VEX_LEN_0F12_P_0
) },
3745 { "%XEvmov%XSldup", { XM
, EXEvexXNoBcst
}, 0 },
3746 { VEX_LEN_TABLE (VEX_LEN_0F12_P_2
) },
3747 { "%XEvmov%XDdup", { XM
, EXymmq
}, 0 },
3750 /* PREFIX_VEX_0F16 */
3752 { VEX_LEN_TABLE (VEX_LEN_0F16_P_0
) },
3753 { "%XEvmov%XShdup", { XM
, EXEvexXNoBcst
}, 0 },
3754 { VEX_LEN_TABLE (VEX_LEN_0F16_P_2
) },
3757 /* PREFIX_VEX_0F2A */
3760 { "%XEvcvtsi2ssY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR
, Edq
}, 0 },
3762 { "%XEvcvtsi2sdY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR64
, Edq
}, 0 },
3765 /* PREFIX_VEX_0F2C */
3768 { "%XEvcvttss2si", { Gdq
, EXd
, EXxEVexS
}, 0 },
3770 { "%XEvcvttsd2si", { Gdq
, EXq
, EXxEVexS
}, 0 },
3773 /* PREFIX_VEX_0F2D */
3776 { "%XEvcvtss2si", { Gdq
, EXd
, EXxEVexR
}, 0 },
3778 { "%XEvcvtsd2si", { Gdq
, EXq
, EXxEVexR
}, 0 },
3781 /* PREFIX_VEX_0F41_L_1_W_0 */
3783 { "kandw", { MaskG
, MaskVex
, MaskR
}, 0 },
3785 { "kandb", { MaskG
, MaskVex
, MaskR
}, 0 },
3788 /* PREFIX_VEX_0F41_L_1_W_1 */
3790 { "kandq", { MaskG
, MaskVex
, MaskR
}, 0 },
3792 { "kandd", { MaskG
, MaskVex
, MaskR
}, 0 },
3795 /* PREFIX_VEX_0F42_L_1_W_0 */
3797 { "kandnw", { MaskG
, MaskVex
, MaskR
}, 0 },
3799 { "kandnb", { MaskG
, MaskVex
, MaskR
}, 0 },
3802 /* PREFIX_VEX_0F42_L_1_W_1 */
3804 { "kandnq", { MaskG
, MaskVex
, MaskR
}, 0 },
3806 { "kandnd", { MaskG
, MaskVex
, MaskR
}, 0 },
3809 /* PREFIX_VEX_0F44_L_0_W_0 */
3811 { "knotw", { MaskG
, MaskR
}, 0 },
3813 { "knotb", { MaskG
, MaskR
}, 0 },
3816 /* PREFIX_VEX_0F44_L_0_W_1 */
3818 { "knotq", { MaskG
, MaskR
}, 0 },
3820 { "knotd", { MaskG
, MaskR
}, 0 },
3823 /* PREFIX_VEX_0F45_L_1_W_0 */
3825 { "korw", { MaskG
, MaskVex
, MaskR
}, 0 },
3827 { "korb", { MaskG
, MaskVex
, MaskR
}, 0 },
3830 /* PREFIX_VEX_0F45_L_1_W_1 */
3832 { "korq", { MaskG
, MaskVex
, MaskR
}, 0 },
3834 { "kord", { MaskG
, MaskVex
, MaskR
}, 0 },
3837 /* PREFIX_VEX_0F46_L_1_W_0 */
3839 { "kxnorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3841 { "kxnorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3844 /* PREFIX_VEX_0F46_L_1_W_1 */
3846 { "kxnorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3848 { "kxnord", { MaskG
, MaskVex
, MaskR
}, 0 },
3851 /* PREFIX_VEX_0F47_L_1_W_0 */
3853 { "kxorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3855 { "kxorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3858 /* PREFIX_VEX_0F47_L_1_W_1 */
3860 { "kxorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3862 { "kxord", { MaskG
, MaskVex
, MaskR
}, 0 },
3865 /* PREFIX_VEX_0F4A_L_1_W_0 */
3867 { "kaddw", { MaskG
, MaskVex
, MaskR
}, 0 },
3869 { "kaddb", { MaskG
, MaskVex
, MaskR
}, 0 },
3872 /* PREFIX_VEX_0F4A_L_1_W_1 */
3874 { "kaddq", { MaskG
, MaskVex
, MaskR
}, 0 },
3876 { "kaddd", { MaskG
, MaskVex
, MaskR
}, 0 },
3879 /* PREFIX_VEX_0F4B_L_1_W_0 */
3881 { "kunpckwd", { MaskG
, MaskVex
, MaskR
}, 0 },
3883 { "kunpckbw", { MaskG
, MaskVex
, MaskR
}, 0 },
3886 /* PREFIX_VEX_0F4B_L_1_W_1 */
3888 { "kunpckdq", { MaskG
, MaskVex
, MaskR
}, 0 },
3891 /* PREFIX_VEX_0F6F */
3894 { "vmovdqu", { XM
, EXx
}, 0 },
3895 { "vmovdqa", { XM
, EXx
}, 0 },
3898 /* PREFIX_VEX_0F70 */
3901 { "vpshufhw", { XM
, EXx
, Ib
}, 0 },
3902 { "vpshufd", { XM
, EXx
, Ib
}, 0 },
3903 { "vpshuflw", { XM
, EXx
, Ib
}, 0 },
3906 /* PREFIX_VEX_0F7E */
3909 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_1
) },
3910 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_2
) },
3913 /* PREFIX_VEX_0F7F */
3916 { "vmovdqu", { EXxS
, XM
}, 0 },
3917 { "vmovdqa", { EXxS
, XM
}, 0 },
3920 /* PREFIX_VEX_0F90_L_0_W_0 */
3922 { "%XEkmovw", { MaskG
, MaskE
}, 0 },
3924 { "%XEkmovb", { MaskG
, MaskBDE
}, 0 },
3927 /* PREFIX_VEX_0F90_L_0_W_1 */
3929 { "%XEkmovq", { MaskG
, MaskE
}, 0 },
3931 { "%XEkmovd", { MaskG
, MaskBDE
}, 0 },
3934 /* PREFIX_VEX_0F91_L_0_W_0 */
3936 { "%XEkmovw", { Mw
, MaskG
}, 0 },
3938 { "%XEkmovb", { Mb
, MaskG
}, 0 },
3941 /* PREFIX_VEX_0F91_L_0_W_1 */
3943 { "%XEkmovq", { Mq
, MaskG
}, 0 },
3945 { "%XEkmovd", { Md
, MaskG
}, 0 },
3948 /* PREFIX_VEX_0F92_L_0_W_0 */
3950 { "%XEkmovw", { MaskG
, Rdq
}, 0 },
3952 { "%XEkmovb", { MaskG
, Rdq
}, 0 },
3953 { "%XEkmovd", { MaskG
, Rdq
}, 0 },
3956 /* PREFIX_VEX_0F92_L_0_W_1 */
3961 { "%XEkmovK", { MaskG
, Rdq
}, 0 },
3964 /* PREFIX_VEX_0F93_L_0_W_0 */
3966 { "%XEkmovw", { Gdq
, MaskR
}, 0 },
3968 { "%XEkmovb", { Gdq
, MaskR
}, 0 },
3969 { "%XEkmovd", { Gdq
, MaskR
}, 0 },
3972 /* PREFIX_VEX_0F93_L_0_W_1 */
3977 { "%XEkmovK", { Gdq
, MaskR
}, 0 },
3980 /* PREFIX_VEX_0F98_L_0_W_0 */
3982 { "kortestw", { MaskG
, MaskR
}, 0 },
3984 { "kortestb", { MaskG
, MaskR
}, 0 },
3987 /* PREFIX_VEX_0F98_L_0_W_1 */
3989 { "kortestq", { MaskG
, MaskR
}, 0 },
3991 { "kortestd", { MaskG
, MaskR
}, 0 },
3994 /* PREFIX_VEX_0F99_L_0_W_0 */
3996 { "ktestw", { MaskG
, MaskR
}, 0 },
3998 { "ktestb", { MaskG
, MaskR
}, 0 },
4001 /* PREFIX_VEX_0F99_L_0_W_1 */
4003 { "ktestq", { MaskG
, MaskR
}, 0 },
4005 { "ktestd", { MaskG
, MaskR
}, 0 },
4008 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0 */
4010 { "ldtilecfg", { M
}, 0 },
4012 { "sttilecfg", { M
}, 0 },
4015 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1 */
4017 { REG_TABLE (REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0
) },
4020 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
) },
4023 /* PREFIX_VEX_0F384B_X86_64_L_0_W_0 */
4026 { "tilestored", { MVexSIBMEM
, TMM
}, 0 },
4027 { "tileloaddt1", { TMM
, MVexSIBMEM
}, 0 },
4028 { "tileloadd", { TMM
, MVexSIBMEM
}, 0 },
4031 /* PREFIX_VEX_0F3850_W_0 */
4033 { "%XEvpdpbuud", { XM
, Vex
, EXx
}, 0 },
4034 { "%XEvpdpbsud", { XM
, Vex
, EXx
}, 0 },
4035 { "%XVvpdpbusd", { XM
, Vex
, EXx
}, 0 },
4036 { "%XEvpdpbssd", { XM
, Vex
, EXx
}, 0 },
4039 /* PREFIX_VEX_0F3851_W_0 */
4041 { "%XEvpdpbuuds", { XM
, Vex
, EXx
}, 0 },
4042 { "%XEvpdpbsuds", { XM
, Vex
, EXx
}, 0 },
4043 { "%XVvpdpbusds", { XM
, Vex
, EXx
}, 0 },
4044 { "%XEvpdpbssds", { XM
, Vex
, EXx
}, 0 },
4046 /* PREFIX_VEX_0F385C_X86_64_L_0_W_0 */
4049 { "tdpbf16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4051 { "tdpfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4054 /* PREFIX_VEX_0F385E_X86_64_L_0_W_0 */
4056 { "tdpbuud", {TMM
, Rtmm
, VexTmm
}, 0 },
4057 { "tdpbsud", {TMM
, Rtmm
, VexTmm
}, 0 },
4058 { "tdpbusd", {TMM
, Rtmm
, VexTmm
}, 0 },
4059 { "tdpbssd", {TMM
, Rtmm
, VexTmm
}, 0 },
4062 /* PREFIX_VEX_0F386C_X86_64_L_0_W_0 */
4064 { "tcmmrlfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4066 { "tcmmimfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4069 /* PREFIX_VEX_0F3872 */
4072 { VEX_W_TABLE (VEX_W_0F3872_P_1
) },
4075 /* PREFIX_VEX_0F38B0_W_0 */
4077 { "vcvtneoph2ps", { XM
, Mx
}, 0 },
4078 { "vcvtneebf162ps", { XM
, Mx
}, 0 },
4079 { "vcvtneeph2ps", { XM
, Mx
}, 0 },
4080 { "vcvtneobf162ps", { XM
, Mx
}, 0 },
4083 /* PREFIX_VEX_0F38B1_W_0 */
4086 { "vbcstnebf162ps", { XM
, Mw
}, 0 },
4087 { "vbcstnesh2ps", { XM
, Mw
}, 0 },
4090 /* PREFIX_VEX_0F38D2_W_0 */
4092 { "%XEvpdpwuud", { XM
, Vex
, EXx
}, 0 },
4093 { "%XEvpdpwsud", { XM
, Vex
, EXx
}, 0 },
4094 { "%XEvpdpwusd", { XM
, Vex
, EXx
}, 0 },
4097 /* PREFIX_VEX_0F38D3_W_0 */
4099 { "%XEvpdpwuuds", { XM
, Vex
, EXx
}, 0 },
4100 { "%XEvpdpwsuds", { XM
, Vex
, EXx
}, 0 },
4101 { "%XEvpdpwusds", { XM
, Vex
, EXx
}, 0 },
4104 /* PREFIX_VEX_0F38CB */
4109 { VEX_W_TABLE (VEX_W_0F38CB_P_3
) },
4112 /* PREFIX_VEX_0F38CC */
4117 { VEX_W_TABLE (VEX_W_0F38CC_P_3
) },
4120 /* PREFIX_VEX_0F38CD */
4125 { VEX_W_TABLE (VEX_W_0F38CD_P_3
) },
4128 /* PREFIX_VEX_0F38DA_W_0 */
4130 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_0
) },
4131 { "vsm4key4", { XM
, Vex
, EXx
}, 0 },
4132 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_2
) },
4133 { "vsm4rnds4", { XM
, Vex
, EXx
}, 0 },
4136 /* PREFIX_VEX_0F38F2_L_0 */
4138 { "%NFandnS", { Gdq
, VexGdq
, Edq
}, 0 },
4141 /* PREFIX_VEX_0F38F3_L_0 */
4143 { REG_TABLE (REG_VEX_0F38F3_L_0_P_0
) },
4146 /* PREFIX_VEX_0F38F5_L_0 */
4148 { "%NFbzhiS", { Gdq
, Edq
, VexGdq
}, 0 },
4149 { "%XEpextS", { Gdq
, VexGdq
, Edq
}, 0 },
4151 { "%XEpdepS", { Gdq
, VexGdq
, Edq
}, 0 },
4154 /* PREFIX_VEX_0F38F6_L_0 */
4159 { "%XEmulxS", { Gdq
, VexGdq
, Edq
}, 0 },
4162 /* PREFIX_VEX_0F38F7_L_0 */
4164 { "%NFbextrS", { Gdq
, Edq
, VexGdq
}, 0 },
4165 { "%XEsarxS", { Gdq
, Edq
, VexGdq
}, 0 },
4166 { "%XEshlxS", { Gdq
, Edq
, VexGdq
}, 0 },
4167 { "%XEshrxS", { Gdq
, Edq
, VexGdq
}, 0 },
4170 /* PREFIX_VEX_0F3AF0_L_0 */
4175 { "%XErorxS", { Gdq
, Edq
, Ib
}, 0 },
4178 /* PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64 */
4181 { "wrmsrns", { Skip_MODRM
, Id
, Rq
}, 0 },
4183 { "rdmsr", { Rq
, Id
}, 0 },
4186 /* PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64 */
4189 { "uwrmsr", { Skip_MODRM
, Id
, Rq
}, 0 },
4191 { "urdmsr", { Rq
, Id
}, 0 },
4194 #include "i386-dis-evex-prefix.h"
4197 static const struct dis386 x86_64_table
[][2] = {
4200 { "pushP", { es
}, 0 },
4205 { "popP", { es
}, 0 },
4210 { "pushP", { cs
}, 0 },
4215 { "pushP", { ss
}, 0 },
4220 { "popP", { ss
}, 0 },
4225 { "pushP", { ds
}, 0 },
4230 { "popP", { ds
}, 0 },
4235 { "daa", { XX
}, 0 },
4240 { "das", { XX
}, 0 },
4245 { "aaa", { XX
}, 0 },
4250 { "aas", { XX
}, 0 },
4255 { "pushaP", { XX
}, 0 },
4260 { "popaP", { XX
}, 0 },
4265 { MOD_TABLE (MOD_62_32BIT
) },
4271 { "arplS", { Sv
, Gv
}, 0 },
4272 { "movs", { Gv
, { MOVSXD_Fixup
, movsxd_mode
} }, 0 },
4277 { "ins{R|}", { Yzr
, indirDX
}, 0 },
4278 { "ins{G|}", { Yzr
, indirDX
}, 0 },
4283 { "outs{R|}", { indirDXr
, Xz
}, 0 },
4284 { "outs{G|}", { indirDXr
, Xz
}, 0 },
4289 /* Opcode 0x82 is an alias of opcode 0x80 in 32-bit mode. */
4290 { REG_TABLE (REG_80
) },
4295 { "{l|}call{P|}", { Ap
}, 0 },
4300 { "retP", { Iw
, BND
}, 0 },
4301 { "ret@", { Iw
, BND
}, 0 },
4306 { "retP", { BND
}, 0 },
4307 { "ret@", { BND
}, 0 },
4312 { MOD_TABLE (MOD_C4_32BIT
) },
4313 { VEX_C4_TABLE () },
4318 { MOD_TABLE (MOD_C5_32BIT
) },
4319 { VEX_C5_TABLE () },
4324 { "into", { XX
}, 0 },
4329 { "aam", { Ib
}, 0 },
4334 { "aad", { Ib
}, 0 },
4339 { "callP", { Jv
, BND
}, 0 },
4340 { "call@", { Jv
, BND
}, PREFIX_REX2_ILLEGAL
}
4345 { "jmpP", { Jv
, BND
}, 0 },
4346 { "jmp@", { Jv
, BND
}, PREFIX_REX2_ILLEGAL
}
4351 { "{l|}jmp{P|}", { Ap
}, 0 },
4354 /* X86_64_0F00_REG_6 */
4357 { PREFIX_TABLE (PREFIX_0F00_REG_6_X86_64
) },
4360 /* X86_64_0F01_REG_0 */
4362 { "sgdt{Q|Q}", { M
}, 0 },
4363 { "sgdt", { M
}, 0 },
4366 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_1 */
4369 { "wrmsrlist", { Skip_MODRM
}, 0 },
4372 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_3 */
4375 { "rdmsrlist", { Skip_MODRM
}, 0 },
4378 /* X86_64_0F01_REG_0_MOD_3_RM_7_P_0 */
4381 { "pbndkb", { Skip_MODRM
}, 0 },
4384 /* X86_64_0F01_REG_1 */
4386 { "sidt{Q|Q}", { M
}, 0 },
4387 { "sidt", { M
}, 0 },
4390 /* X86_64_0F01_REG_1_RM_2_PREFIX_1 */
4393 { "eretu", { Skip_MODRM
}, 0 },
4396 /* X86_64_0F01_REG_1_RM_2_PREFIX_3 */
4399 { "erets", { Skip_MODRM
}, 0 },
4402 /* X86_64_0F01_REG_1_RM_5_PREFIX_2 */
4405 { "seamret", { Skip_MODRM
}, 0 },
4408 /* X86_64_0F01_REG_1_RM_6_PREFIX_2 */
4411 { "seamops", { Skip_MODRM
}, 0 },
4414 /* X86_64_0F01_REG_1_RM_7_PREFIX_2 */
4417 { "seamcall", { Skip_MODRM
}, 0 },
4420 /* X86_64_0F01_REG_2 */
4422 { "lgdt{Q|Q}", { M
}, 0 },
4423 { "lgdt", { M
}, 0 },
4426 /* X86_64_0F01_REG_3 */
4428 { "lidt{Q|Q}", { M
}, 0 },
4429 { "lidt", { M
}, 0 },
4432 /* X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1 */
4435 { "uiret", { Skip_MODRM
}, 0 },
4438 /* X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1 */
4441 { "testui", { Skip_MODRM
}, 0 },
4444 /* X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1 */
4447 { "clui", { Skip_MODRM
}, 0 },
4450 /* X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1 */
4453 { "stui", { Skip_MODRM
}, 0 },
4456 /* X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1 */
4459 { "rmpquery", { Skip_MODRM
}, 0 },
4462 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1 */
4465 { "rmpadjust", { Skip_MODRM
}, 0 },
4468 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */
4471 { "rmpupdate", { Skip_MODRM
}, 0 },
4474 /* X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1 */
4477 { "psmash", { Skip_MODRM
}, 0 },
4480 /* X86_64_0F18_REG_6_MOD_0 */
4482 { "nopQ", { Ev
}, 0 },
4483 { PREFIX_TABLE (PREFIX_0F18_REG_6_MOD_0_X86_64
) },
4486 /* X86_64_0F18_REG_7_MOD_0 */
4488 { "nopQ", { Ev
}, 0 },
4489 { PREFIX_TABLE (PREFIX_0F18_REG_7_MOD_0_X86_64
) },
4494 { "movZ", { Em
, Td
}, 0 },
4499 { "movZ", { Td
, Em
}, 0 },
4503 /* X86_64_0F38F8_M_1 */
4505 { PREFIX_TABLE (PREFIX_0F38F8_M_1_X86_64
) },
4508 /* X86_64_0FC7_REG_6_MOD_3_PREFIX_1 */
4511 { "senduipi", { Eq
}, 0 },
4514 /* X86_64_VEX_0F3849 */
4517 { VEX_LEN_TABLE (VEX_LEN_0F3849_X86_64
) },
4520 /* X86_64_VEX_0F384B */
4523 { VEX_LEN_TABLE (VEX_LEN_0F384B_X86_64
) },
4526 /* X86_64_VEX_0F385C */
4529 { VEX_LEN_TABLE (VEX_LEN_0F385C_X86_64
) },
4532 /* X86_64_VEX_0F385E */
4535 { VEX_LEN_TABLE (VEX_LEN_0F385E_X86_64
) },
4538 /* X86_64_VEX_0F386C */
4541 { VEX_LEN_TABLE (VEX_LEN_0F386C_X86_64
) },
4544 /* X86_64_VEX_0F38Ex */
4547 { "%XEcmp%CCxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4550 /* X86_64_VEX_MAP7_F6_L_0_W_0_R_0 */
4553 { PREFIX_TABLE (PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64
) },
4556 /* X86_64_VEX_MAP7_F8_L_0_W_0_R_0 */
4559 { PREFIX_TABLE (PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64
) },
4563 static const struct dis386 three_byte_table
[][256] = {
4565 /* THREE_BYTE_0F38 */
4568 { "pshufb", { MX
, EM
}, PREFIX_OPCODE
},
4569 { "phaddw", { MX
, EM
}, PREFIX_OPCODE
},
4570 { "phaddd", { MX
, EM
}, PREFIX_OPCODE
},
4571 { "phaddsw", { MX
, EM
}, PREFIX_OPCODE
},
4572 { "pmaddubsw", { MX
, EM
}, PREFIX_OPCODE
},
4573 { "phsubw", { MX
, EM
}, PREFIX_OPCODE
},
4574 { "phsubd", { MX
, EM
}, PREFIX_OPCODE
},
4575 { "phsubsw", { MX
, EM
}, PREFIX_OPCODE
},
4577 { "psignb", { MX
, EM
}, PREFIX_OPCODE
},
4578 { "psignw", { MX
, EM
}, PREFIX_OPCODE
},
4579 { "psignd", { MX
, EM
}, PREFIX_OPCODE
},
4580 { "pmulhrsw", { MX
, EM
}, PREFIX_OPCODE
},
4586 { "pblendvb", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4590 { "blendvps", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4591 { "blendvpd", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4593 { "ptest", { XM
, EXx
}, PREFIX_DATA
},
4599 { "pabsb", { MX
, EM
}, PREFIX_OPCODE
},
4600 { "pabsw", { MX
, EM
}, PREFIX_OPCODE
},
4601 { "pabsd", { MX
, EM
}, PREFIX_OPCODE
},
4604 { "pmovsxbw", { XM
, EXq
}, PREFIX_DATA
},
4605 { "pmovsxbd", { XM
, EXd
}, PREFIX_DATA
},
4606 { "pmovsxbq", { XM
, EXw
}, PREFIX_DATA
},
4607 { "pmovsxwd", { XM
, EXq
}, PREFIX_DATA
},
4608 { "pmovsxwq", { XM
, EXd
}, PREFIX_DATA
},
4609 { "pmovsxdq", { XM
, EXq
}, PREFIX_DATA
},
4613 { "pmuldq", { XM
, EXx
}, PREFIX_DATA
},
4614 { "pcmpeqq", { XM
, EXx
}, PREFIX_DATA
},
4615 { "movntdqa", { XM
, Mx
}, PREFIX_DATA
},
4616 { "packusdw", { XM
, EXx
}, PREFIX_DATA
},
4622 { "pmovzxbw", { XM
, EXq
}, PREFIX_DATA
},
4623 { "pmovzxbd", { XM
, EXd
}, PREFIX_DATA
},
4624 { "pmovzxbq", { XM
, EXw
}, PREFIX_DATA
},
4625 { "pmovzxwd", { XM
, EXq
}, PREFIX_DATA
},
4626 { "pmovzxwq", { XM
, EXd
}, PREFIX_DATA
},
4627 { "pmovzxdq", { XM
, EXq
}, PREFIX_DATA
},
4629 { "pcmpgtq", { XM
, EXx
}, PREFIX_DATA
},
4631 { "pminsb", { XM
, EXx
}, PREFIX_DATA
},
4632 { "pminsd", { XM
, EXx
}, PREFIX_DATA
},
4633 { "pminuw", { XM
, EXx
}, PREFIX_DATA
},
4634 { "pminud", { XM
, EXx
}, PREFIX_DATA
},
4635 { "pmaxsb", { XM
, EXx
}, PREFIX_DATA
},
4636 { "pmaxsd", { XM
, EXx
}, PREFIX_DATA
},
4637 { "pmaxuw", { XM
, EXx
}, PREFIX_DATA
},
4638 { "pmaxud", { XM
, EXx
}, PREFIX_DATA
},
4640 { "pmulld", { XM
, EXx
}, PREFIX_DATA
},
4641 { "phminposuw", { XM
, EXx
}, PREFIX_DATA
},
4712 { "invept", { Gm
, Mo
}, PREFIX_DATA
},
4713 { "invvpid", { Gm
, Mo
}, PREFIX_DATA
},
4714 { "invpcid", { Gm
, M
}, PREFIX_DATA
},
4793 { "sha1nexte", { XM
, EXxmm
}, PREFIX_OPCODE
},
4794 { "sha1msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
4795 { "sha1msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
4796 { "sha256rnds2", { XM
, EXxmm
, XMM0
}, PREFIX_OPCODE
},
4797 { "sha256msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
4798 { "sha256msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
4800 { "gf2p8mulb", { XM
, EXxmm
}, PREFIX_DATA
},
4811 { PREFIX_TABLE (PREFIX_0F38D8
) },
4814 { "aesimc", { XM
, EXx
}, PREFIX_DATA
},
4815 { PREFIX_TABLE (PREFIX_0F38DC
) },
4816 { PREFIX_TABLE (PREFIX_0F38DD
) },
4817 { PREFIX_TABLE (PREFIX_0F38DE
) },
4818 { PREFIX_TABLE (PREFIX_0F38DF
) },
4838 { PREFIX_TABLE (PREFIX_0F38F0
) },
4839 { PREFIX_TABLE (PREFIX_0F38F1
) },
4843 { "wrussK", { M
, Gdq
}, PREFIX_DATA
},
4844 { PREFIX_TABLE (PREFIX_0F38F6
) },
4847 { MOD_TABLE (MOD_0F38F8
) },
4848 { "movdiri", { Mdq
, Gdq
}, PREFIX_OPCODE
},
4849 { PREFIX_TABLE (PREFIX_0F38FA
) },
4850 { PREFIX_TABLE (PREFIX_0F38FB
) },
4851 { PREFIX_TABLE (PREFIX_0F38FC
) },
4856 /* THREE_BYTE_0F3A */
4868 { "roundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4869 { "roundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4870 { "roundss", { XM
, EXd
, Ib
}, PREFIX_DATA
},
4871 { "roundsd", { XM
, EXq
, Ib
}, PREFIX_DATA
},
4872 { "blendps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4873 { "blendpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4874 { "pblendw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4875 { "palignr", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
4881 { "pextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
4882 { "pextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
4883 { "pextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
4884 { "extractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
4895 { "pinsrb", { XM
, Edb
, Ib
}, PREFIX_DATA
},
4896 { "insertps", { XM
, EXd
, Ib
}, PREFIX_DATA
},
4897 { "pinsrK", { XM
, Edq
, Ib
}, PREFIX_DATA
},
4931 { "dpps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4932 { "dppd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4933 { "mpsadbw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4935 { "pclmulqdq", { XM
, EXx
, PCLMUL
}, PREFIX_DATA
},
4967 { "pcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4968 { "pcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4969 { "pcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
4970 { "pcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5088 { "sha1rnds4", { XM
, EXxmm
, Ib
}, PREFIX_OPCODE
},
5090 { "gf2p8affineqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
5091 { "gf2p8affineinvqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
5109 { "aeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5129 { PREFIX_TABLE (PREFIX_0F3A0F
) },
5149 static const struct dis386 xop_table
[][256] = {
5302 { VEX_LEN_TABLE (VEX_LEN_XOP_08_85
) },
5303 { VEX_LEN_TABLE (VEX_LEN_XOP_08_86
) },
5304 { VEX_LEN_TABLE (VEX_LEN_XOP_08_87
) },
5312 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8E
) },
5313 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8F
) },
5320 { VEX_LEN_TABLE (VEX_LEN_XOP_08_95
) },
5321 { VEX_LEN_TABLE (VEX_LEN_XOP_08_96
) },
5322 { VEX_LEN_TABLE (VEX_LEN_XOP_08_97
) },
5330 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9E
) },
5331 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9F
) },
5335 { "vpcmov", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
5336 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A3
) },
5339 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A6
) },
5357 { VEX_LEN_TABLE (VEX_LEN_XOP_08_B6
) },
5369 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C0
) },
5370 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C1
) },
5371 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C2
) },
5372 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C3
) },
5382 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CC
) },
5383 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CD
) },
5384 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CE
) },
5385 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CF
) },
5418 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EC
) },
5419 { VEX_LEN_TABLE (VEX_LEN_XOP_08_ED
) },
5420 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EE
) },
5421 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EF
) },
5445 { VEX_LEN_TABLE (VEX_LEN_XOP_09_01
) },
5446 { VEX_LEN_TABLE (VEX_LEN_XOP_09_02
) },
5464 { VEX_LEN_TABLE (VEX_LEN_XOP_09_12
) },
5588 { VEX_W_TABLE (VEX_W_XOP_09_80
) },
5589 { VEX_W_TABLE (VEX_W_XOP_09_81
) },
5590 { VEX_W_TABLE (VEX_W_XOP_09_82
) },
5591 { VEX_W_TABLE (VEX_W_XOP_09_83
) },
5606 { VEX_LEN_TABLE (VEX_LEN_XOP_09_90
) },
5607 { VEX_LEN_TABLE (VEX_LEN_XOP_09_91
) },
5608 { VEX_LEN_TABLE (VEX_LEN_XOP_09_92
) },
5609 { VEX_LEN_TABLE (VEX_LEN_XOP_09_93
) },
5610 { VEX_LEN_TABLE (VEX_LEN_XOP_09_94
) },
5611 { VEX_LEN_TABLE (VEX_LEN_XOP_09_95
) },
5612 { VEX_LEN_TABLE (VEX_LEN_XOP_09_96
) },
5613 { VEX_LEN_TABLE (VEX_LEN_XOP_09_97
) },
5615 { VEX_LEN_TABLE (VEX_LEN_XOP_09_98
) },
5616 { VEX_LEN_TABLE (VEX_LEN_XOP_09_99
) },
5617 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9A
) },
5618 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9B
) },
5661 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C1
) },
5662 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C2
) },
5663 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C3
) },
5666 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C6
) },
5667 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C7
) },
5672 { VEX_LEN_TABLE (VEX_LEN_XOP_09_CB
) },
5679 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D1
) },
5680 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D2
) },
5681 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D3
) },
5684 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D6
) },
5685 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D7
) },
5690 { VEX_LEN_TABLE (VEX_LEN_XOP_09_DB
) },
5697 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E1
) },
5698 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E2
) },
5699 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E3
) },
5753 { "bextrS", { Gdq
, Edq
, Id
}, 0 },
5755 { VEX_LEN_TABLE (VEX_LEN_XOP_0A_12
) },
6025 static const struct dis386 vex_table
[][256] = {
6047 { PREFIX_TABLE (PREFIX_0F10
) },
6048 { PREFIX_TABLE (PREFIX_0F11
) },
6049 { PREFIX_TABLE (PREFIX_VEX_0F12
) },
6050 { VEX_LEN_TABLE (VEX_LEN_0F13
) },
6051 { "vunpcklpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6052 { "vunpckhpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6053 { PREFIX_TABLE (PREFIX_VEX_0F16
) },
6054 { VEX_LEN_TABLE (VEX_LEN_0F17
) },
6074 { "vmovapX", { XM
, EXx
}, PREFIX_OPCODE
},
6075 { "vmovapX", { EXxS
, XM
}, PREFIX_OPCODE
},
6076 { PREFIX_TABLE (PREFIX_VEX_0F2A
) },
6077 { "vmovntpX", { Mx
, XM
}, PREFIX_OPCODE
},
6078 { PREFIX_TABLE (PREFIX_VEX_0F2C
) },
6079 { PREFIX_TABLE (PREFIX_VEX_0F2D
) },
6080 { PREFIX_TABLE (PREFIX_0F2E
) },
6081 { PREFIX_TABLE (PREFIX_0F2F
) },
6102 { VEX_LEN_TABLE (VEX_LEN_0F41
) },
6103 { VEX_LEN_TABLE (VEX_LEN_0F42
) },
6105 { VEX_LEN_TABLE (VEX_LEN_0F44
) },
6106 { VEX_LEN_TABLE (VEX_LEN_0F45
) },
6107 { VEX_LEN_TABLE (VEX_LEN_0F46
) },
6108 { VEX_LEN_TABLE (VEX_LEN_0F47
) },
6112 { VEX_LEN_TABLE (VEX_LEN_0F4A
) },
6113 { VEX_LEN_TABLE (VEX_LEN_0F4B
) },
6119 { "vmovmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
6120 { PREFIX_TABLE (PREFIX_0F51
) },
6121 { PREFIX_TABLE (PREFIX_0F52
) },
6122 { PREFIX_TABLE (PREFIX_0F53
) },
6123 { "vandpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6124 { "vandnpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6125 { "vorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6126 { "vxorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6128 { PREFIX_TABLE (PREFIX_0F58
) },
6129 { PREFIX_TABLE (PREFIX_0F59
) },
6130 { PREFIX_TABLE (PREFIX_0F5A
) },
6131 { PREFIX_TABLE (PREFIX_0F5B
) },
6132 { PREFIX_TABLE (PREFIX_0F5C
) },
6133 { PREFIX_TABLE (PREFIX_0F5D
) },
6134 { PREFIX_TABLE (PREFIX_0F5E
) },
6135 { PREFIX_TABLE (PREFIX_0F5F
) },
6137 { "vpunpcklbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6138 { "vpunpcklwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6139 { "vpunpckldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6140 { "vpacksswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6141 { "vpcmpgtb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6142 { "vpcmpgtw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6143 { "vpcmpgtd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6144 { "vpackuswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6146 { "vpunpckhbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6147 { "vpunpckhwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6148 { "vpunpckhdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6149 { "vpackssdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6150 { "vpunpcklqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6151 { "vpunpckhqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6152 { VEX_LEN_TABLE (VEX_LEN_0F6E
) },
6153 { PREFIX_TABLE (PREFIX_VEX_0F6F
) },
6155 { PREFIX_TABLE (PREFIX_VEX_0F70
) },
6156 { REG_TABLE (REG_VEX_0F71
) },
6157 { REG_TABLE (REG_VEX_0F72
) },
6158 { REG_TABLE (REG_VEX_0F73
) },
6159 { "vpcmpeqb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6160 { "vpcmpeqw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6161 { "vpcmpeqd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6162 { VEX_LEN_TABLE (VEX_LEN_0F77
) },
6168 { PREFIX_TABLE (PREFIX_0F7C
) },
6169 { PREFIX_TABLE (PREFIX_0F7D
) },
6170 { PREFIX_TABLE (PREFIX_VEX_0F7E
) },
6171 { PREFIX_TABLE (PREFIX_VEX_0F7F
) },
6191 { VEX_LEN_TABLE (VEX_LEN_0F90
) },
6192 { VEX_LEN_TABLE (VEX_LEN_0F91
) },
6193 { VEX_LEN_TABLE (VEX_LEN_0F92
) },
6194 { VEX_LEN_TABLE (VEX_LEN_0F93
) },
6200 { VEX_LEN_TABLE (VEX_LEN_0F98
) },
6201 { VEX_LEN_TABLE (VEX_LEN_0F99
) },
6224 { REG_TABLE (REG_VEX_0FAE
) },
6247 { PREFIX_TABLE (PREFIX_0FC2
) },
6249 { VEX_LEN_TABLE (VEX_LEN_0FC4
) },
6250 { "vpextrw", { Gd
, Uxmm
, Ib
}, PREFIX_DATA
},
6251 { "vshufpX", { XM
, Vex
, EXx
, Ib
}, PREFIX_OPCODE
},
6263 { PREFIX_TABLE (PREFIX_0FD0
) },
6264 { "vpsrlw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6265 { "vpsrld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6266 { "vpsrlq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6267 { "vpaddq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6268 { "vpmullw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6269 { VEX_LEN_TABLE (VEX_LEN_0FD6
) },
6270 { "vpmovmskb", { Gdq
, Ux
}, PREFIX_DATA
},
6272 { "vpsubusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6273 { "vpsubusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6274 { "vpminub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6275 { "vpand", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6276 { "vpaddusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6277 { "vpaddusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6278 { "vpmaxub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6279 { "vpandn", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6281 { "vpavgb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6282 { "vpsraw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6283 { "vpsrad", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6284 { "vpavgw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6285 { "vpmulhuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6286 { "vpmulhw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6287 { PREFIX_TABLE (PREFIX_0FE6
) },
6288 { "vmovntdq", { Mx
, XM
}, PREFIX_DATA
},
6290 { "vpsubsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6291 { "vpsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6292 { "vpminsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6293 { "vpor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6294 { "vpaddsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6295 { "vpaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6296 { "vpmaxsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6297 { "vpxor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6299 { PREFIX_TABLE (PREFIX_0FF0
) },
6300 { "vpsllw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6301 { "vpslld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6302 { "vpsllq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6303 { "vpmuludq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6304 { "vpmaddwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6305 { "vpsadbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6306 { "vmaskmovdqu", { XM
, Uxmm
}, PREFIX_DATA
},
6308 { "vpsubb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6309 { "vpsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6310 { "vpsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6311 { "vpsubq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6312 { "vpaddb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6313 { "vpaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6314 { "vpaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6320 { "vpshufb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6321 { "vphaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6322 { "vphaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6323 { "vphaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6324 { "vpmaddubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6325 { "vphsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6326 { "vphsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6327 { "vphsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6329 { "vpsignb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6330 { "vpsignw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6331 { "vpsignd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6332 { "vpmulhrsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6333 { VEX_W_TABLE (VEX_W_0F380C
) },
6334 { VEX_W_TABLE (VEX_W_0F380D
) },
6335 { VEX_W_TABLE (VEX_W_0F380E
) },
6336 { VEX_W_TABLE (VEX_W_0F380F
) },
6341 { VEX_W_TABLE (VEX_W_0F3813
) },
6344 { VEX_LEN_TABLE (VEX_LEN_0F3816
) },
6345 { "vptest", { XM
, EXx
}, PREFIX_DATA
},
6347 { VEX_W_TABLE (VEX_W_0F3818
) },
6348 { VEX_LEN_TABLE (VEX_LEN_0F3819
) },
6349 { VEX_LEN_TABLE (VEX_LEN_0F381A
) },
6351 { "vpabsb", { XM
, EXx
}, PREFIX_DATA
},
6352 { "vpabsw", { XM
, EXx
}, PREFIX_DATA
},
6353 { "vpabsd", { XM
, EXx
}, PREFIX_DATA
},
6356 { "vpmovsxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6357 { "vpmovsxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6358 { "vpmovsxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6359 { "vpmovsxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6360 { "vpmovsxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6361 { "vpmovsxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6365 { "vpmuldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6366 { "vpcmpeqq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6367 { "vmovntdqa", { XM
, Mx
}, PREFIX_DATA
},
6368 { "vpackusdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6369 { VEX_W_TABLE (VEX_W_0F382C
) },
6370 { VEX_W_TABLE (VEX_W_0F382D
) },
6371 { VEX_W_TABLE (VEX_W_0F382E
) },
6372 { VEX_W_TABLE (VEX_W_0F382F
) },
6374 { "vpmovzxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6375 { "vpmovzxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6376 { "vpmovzxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6377 { "vpmovzxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6378 { "vpmovzxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6379 { "vpmovzxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6380 { VEX_LEN_TABLE (VEX_LEN_0F3836
) },
6381 { "vpcmpgtq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6383 { "vpminsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6384 { "vpminsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6385 { "vpminuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6386 { "vpminud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6387 { "vpmaxsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6388 { "vpmaxsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6389 { "vpmaxuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6390 { "vpmaxud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6392 { "vpmulld", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6393 { VEX_LEN_TABLE (VEX_LEN_0F3841
) },
6397 { "vpsrlv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6398 { VEX_W_TABLE (VEX_W_0F3846
) },
6399 { "vpsllv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6402 { X86_64_TABLE (X86_64_VEX_0F3849
) },
6404 { X86_64_TABLE (X86_64_VEX_0F384B
) },
6410 { VEX_W_TABLE (VEX_W_0F3850
) },
6411 { VEX_W_TABLE (VEX_W_0F3851
) },
6412 { VEX_W_TABLE (VEX_W_0F3852
) },
6413 { VEX_W_TABLE (VEX_W_0F3853
) },
6419 { VEX_W_TABLE (VEX_W_0F3858
) },
6420 { VEX_W_TABLE (VEX_W_0F3859
) },
6421 { VEX_LEN_TABLE (VEX_LEN_0F385A
) },
6423 { X86_64_TABLE (X86_64_VEX_0F385C
) },
6425 { X86_64_TABLE (X86_64_VEX_0F385E
) },
6441 { X86_64_TABLE (X86_64_VEX_0F386C
) },
6448 { PREFIX_TABLE (PREFIX_VEX_0F3872
) },
6455 { VEX_W_TABLE (VEX_W_0F3878
) },
6456 { VEX_W_TABLE (VEX_W_0F3879
) },
6477 { "vpmaskmov%DQ", { XM
, Vex
, Mx
}, PREFIX_DATA
},
6479 { "vpmaskmov%DQ", { Mx
, Vex
, XM
}, PREFIX_DATA
},
6482 { "vpgatherd%DQ", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6483 { "vpgatherq%DQ", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6484 { "vgatherdp%XW", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6485 { "vgatherqp%XW", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6488 { "vfmaddsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6489 { "vfmsubadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6491 { "vfmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6492 { "vfmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6493 { "vfmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6494 { "vfmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6495 { "vfnmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6496 { "vfnmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6497 { "vfnmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6498 { "vfnmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6506 { "vfmaddsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6507 { "vfmsubadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6509 { "vfmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6510 { "vfmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6511 { "vfmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6512 { "vfmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6513 { "vfnmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6514 { "vfnmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6515 { "vfnmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6516 { "vfnmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6518 { VEX_W_TABLE (VEX_W_0F38B0
) },
6519 { VEX_W_TABLE (VEX_W_0F38B1
) },
6522 { VEX_W_TABLE (VEX_W_0F38B4
) },
6523 { VEX_W_TABLE (VEX_W_0F38B5
) },
6524 { "vfmaddsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6525 { "vfmsubadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6527 { "vfmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6528 { "vfmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6529 { "vfmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6530 { "vfmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6531 { "vfnmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6532 { "vfnmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6533 { "vfnmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6534 { "vfnmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6548 { PREFIX_TABLE (PREFIX_VEX_0F38CB
) },
6549 { PREFIX_TABLE (PREFIX_VEX_0F38CC
) },
6550 { PREFIX_TABLE (PREFIX_VEX_0F38CD
) },
6552 { VEX_W_TABLE (VEX_W_0F38CF
) },
6556 { VEX_W_TABLE (VEX_W_0F38D2
) },
6557 { VEX_W_TABLE (VEX_W_0F38D3
) },
6565 { VEX_W_TABLE (VEX_W_0F38DA
) },
6566 { VEX_LEN_TABLE (VEX_LEN_0F38DB
) },
6567 { "vaesenc", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6568 { "vaesenclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6569 { "vaesdec", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6570 { "vaesdeclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6572 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6573 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6574 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6575 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6576 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6577 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6578 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6579 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6581 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6582 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6583 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6584 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6585 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6586 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6587 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6588 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6592 { VEX_LEN_TABLE (VEX_LEN_0F38F2
) },
6593 { VEX_LEN_TABLE (VEX_LEN_0F38F3
) },
6595 { VEX_LEN_TABLE (VEX_LEN_0F38F5
) },
6596 { VEX_LEN_TABLE (VEX_LEN_0F38F6
) },
6597 { VEX_LEN_TABLE (VEX_LEN_0F38F7
) },
6611 { VEX_LEN_TABLE (VEX_LEN_0F3A00
) },
6612 { VEX_LEN_TABLE (VEX_LEN_0F3A01
) },
6613 { VEX_W_TABLE (VEX_W_0F3A02
) },
6615 { VEX_W_TABLE (VEX_W_0F3A04
) },
6616 { VEX_W_TABLE (VEX_W_0F3A05
) },
6617 { VEX_LEN_TABLE (VEX_LEN_0F3A06
) },
6620 { "vroundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6621 { "vroundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6622 { "vroundss", { XMScalar
, VexScalar
, EXd
, Ib
}, PREFIX_DATA
},
6623 { "vroundsd", { XMScalar
, VexScalar
, EXq
, Ib
}, PREFIX_DATA
},
6624 { "vblendps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6625 { "vblendpd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6626 { "vpblendw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6627 { "vpalignr", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6633 { VEX_LEN_TABLE (VEX_LEN_0F3A14
) },
6634 { VEX_LEN_TABLE (VEX_LEN_0F3A15
) },
6635 { VEX_LEN_TABLE (VEX_LEN_0F3A16
) },
6636 { VEX_LEN_TABLE (VEX_LEN_0F3A17
) },
6638 { VEX_LEN_TABLE (VEX_LEN_0F3A18
) },
6639 { VEX_LEN_TABLE (VEX_LEN_0F3A19
) },
6643 { VEX_W_TABLE (VEX_W_0F3A1D
) },
6647 { VEX_LEN_TABLE (VEX_LEN_0F3A20
) },
6648 { VEX_LEN_TABLE (VEX_LEN_0F3A21
) },
6649 { VEX_LEN_TABLE (VEX_LEN_0F3A22
) },
6665 { VEX_LEN_TABLE (VEX_LEN_0F3A30
) },
6666 { VEX_LEN_TABLE (VEX_LEN_0F3A31
) },
6667 { VEX_LEN_TABLE (VEX_LEN_0F3A32
) },
6668 { VEX_LEN_TABLE (VEX_LEN_0F3A33
) },
6674 { VEX_LEN_TABLE (VEX_LEN_0F3A38
) },
6675 { VEX_LEN_TABLE (VEX_LEN_0F3A39
) },
6683 { "vdpps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6684 { VEX_LEN_TABLE (VEX_LEN_0F3A41
) },
6685 { "vmpsadbw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6687 { "vpclmulqdq", { XM
, Vex
, EXx
, PCLMUL
}, PREFIX_DATA
},
6689 { VEX_LEN_TABLE (VEX_LEN_0F3A46
) },
6692 { "vpermil2ps", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6693 { "vpermil2pd", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6694 { VEX_W_TABLE (VEX_W_0F3A4A
) },
6695 { VEX_W_TABLE (VEX_W_0F3A4B
) },
6696 { VEX_W_TABLE (VEX_W_0F3A4C
) },
6714 { "vfmaddsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6715 { "vfmaddsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6716 { "vfmsubaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6717 { "vfmsubaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6719 { VEX_LEN_TABLE (VEX_LEN_0F3A60
) },
6720 { VEX_LEN_TABLE (VEX_LEN_0F3A61
) },
6721 { VEX_LEN_TABLE (VEX_LEN_0F3A62
) },
6722 { VEX_LEN_TABLE (VEX_LEN_0F3A63
) },
6728 { "vfmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6729 { "vfmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6730 { "vfmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6731 { "vfmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6732 { "vfmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6733 { "vfmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6734 { "vfmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6735 { "vfmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6746 { "vfnmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6747 { "vfnmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6748 { "vfnmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6749 { "vfnmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6750 { "vfnmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6751 { "vfnmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6752 { "vfnmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6753 { "vfnmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6842 { VEX_W_TABLE (VEX_W_0F3ACE
) },
6843 { VEX_W_TABLE (VEX_W_0F3ACF
) },
6860 { VEX_W_TABLE (VEX_W_0F3ADE
) },
6861 { VEX_LEN_TABLE (VEX_LEN_0F3ADF
) },
6881 { VEX_LEN_TABLE (VEX_LEN_0F3AF0
) },
6901 #include "i386-dis-evex.h"
6903 static const struct dis386 vex_len_table
[][2] = {
6904 /* VEX_LEN_0F12_P_0 */
6906 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
6909 /* VEX_LEN_0F12_P_2 */
6911 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
6916 { "%XEVmovlpYX", { Mq
, XM
}, PREFIX_OPCODE
},
6919 /* VEX_LEN_0F16_P_0 */
6921 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
6924 /* VEX_LEN_0F16_P_2 */
6926 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
6931 { "%XEVmovhpYX", { Mq
, XM
}, PREFIX_OPCODE
},
6937 { VEX_W_TABLE (VEX_W_0F41_L_1
) },
6943 { VEX_W_TABLE (VEX_W_0F42_L_1
) },
6948 { VEX_W_TABLE (VEX_W_0F44_L_0
) },
6954 { VEX_W_TABLE (VEX_W_0F45_L_1
) },
6960 { VEX_W_TABLE (VEX_W_0F46_L_1
) },
6966 { VEX_W_TABLE (VEX_W_0F47_L_1
) },
6972 { VEX_W_TABLE (VEX_W_0F4A_L_1
) },
6978 { VEX_W_TABLE (VEX_W_0F4B_L_1
) },
6983 { "%XEvmovYK", { XMScalar
, Edq
}, PREFIX_DATA
},
6988 { "vzeroupper", { XX
}, 0 },
6989 { "vzeroall", { XX
}, 0 },
6992 /* VEX_LEN_0F7E_P_1 */
6994 { "%XEvmovqY", { XMScalar
, EXq
}, 0 },
6997 /* VEX_LEN_0F7E_P_2 */
6999 { "%XEvmovK", { Edq
, XMScalar
}, 0 },
7004 { VEX_W_TABLE (VEX_W_0F90_L_0
) },
7009 { VEX_W_TABLE (VEX_W_0F91_L_0
) },
7014 { VEX_W_TABLE (VEX_W_0F92_L_0
) },
7019 { VEX_W_TABLE (VEX_W_0F93_L_0
) },
7024 { VEX_W_TABLE (VEX_W_0F98_L_0
) },
7029 { VEX_W_TABLE (VEX_W_0F99_L_0
) },
7032 /* VEX_LEN_0FAE_R_2 */
7034 { "vldmxcsr", { Md
}, 0 },
7037 /* VEX_LEN_0FAE_R_3 */
7039 { "vstmxcsr", { Md
}, 0 },
7044 { "%XEvpinsrwY", { XM
, Vex
, Edw
, Ib
}, PREFIX_DATA
},
7049 { "%XEvmovqY", { EXqS
, XMScalar
}, PREFIX_DATA
},
7052 /* VEX_LEN_0F3816 */
7055 { VEX_W_TABLE (VEX_W_0F3816_L_1
) },
7058 /* VEX_LEN_0F3819 */
7061 { VEX_W_TABLE (VEX_W_0F3819_L_1
) },
7064 /* VEX_LEN_0F381A */
7067 { VEX_W_TABLE (VEX_W_0F381A_L_1
) },
7070 /* VEX_LEN_0F3836 */
7073 { VEX_W_TABLE (VEX_W_0F3836
) },
7076 /* VEX_LEN_0F3841 */
7078 { "vphminposuw", { XM
, EXx
}, PREFIX_DATA
},
7081 /* VEX_LEN_0F3849_X86_64 */
7083 { VEX_W_TABLE (VEX_W_0F3849_X86_64_L_0
) },
7086 /* VEX_LEN_0F384B_X86_64 */
7088 { VEX_W_TABLE (VEX_W_0F384B_X86_64_L_0
) },
7091 /* VEX_LEN_0F385A */
7094 { VEX_W_TABLE (VEX_W_0F385A_L_0
) },
7097 /* VEX_LEN_0F385C_X86_64 */
7099 { VEX_W_TABLE (VEX_W_0F385C_X86_64_L_0
) },
7102 /* VEX_LEN_0F385E_X86_64 */
7104 { VEX_W_TABLE (VEX_W_0F385E_X86_64_L_0
) },
7107 /* VEX_LEN_0F386C_X86_64 */
7109 { VEX_W_TABLE (VEX_W_0F386C_X86_64_L_0
) },
7112 /* VEX_LEN_0F38CB_P_3_W_0 */
7115 { "vsha512rnds2", { XM
, Vex
, Rxmmq
}, 0 },
7118 /* VEX_LEN_0F38CC_P_3_W_0 */
7121 { "vsha512msg1", { XM
, Rxmmq
}, 0 },
7124 /* VEX_LEN_0F38CD_P_3_W_0 */
7127 { "vsha512msg2", { XM
, Rymm
}, 0 },
7130 /* VEX_LEN_0F38DA_W_0_P_0 */
7132 { "vsm3msg1", { XM
, Vex
, EXxmm
}, 0 },
7135 /* VEX_LEN_0F38DA_W_0_P_2 */
7137 { "vsm3msg2", { XM
, Vex
, EXxmm
}, 0 },
7140 /* VEX_LEN_0F38DB */
7142 { "vaesimc", { XM
, EXx
}, PREFIX_DATA
},
7145 /* VEX_LEN_0F38F2 */
7147 { PREFIX_TABLE (PREFIX_VEX_0F38F2_L_0
) },
7150 /* VEX_LEN_0F38F3 */
7152 { PREFIX_TABLE (PREFIX_VEX_0F38F3_L_0
) },
7155 /* VEX_LEN_0F38F5 */
7157 { PREFIX_TABLE(PREFIX_VEX_0F38F5_L_0
) },
7160 /* VEX_LEN_0F38F6 */
7162 { PREFIX_TABLE(PREFIX_VEX_0F38F6_L_0
) },
7165 /* VEX_LEN_0F38F7 */
7167 { PREFIX_TABLE(PREFIX_VEX_0F38F7_L_0
) },
7170 /* VEX_LEN_0F3A00 */
7173 { VEX_W_TABLE (VEX_W_0F3A00_L_1
) },
7176 /* VEX_LEN_0F3A01 */
7179 { VEX_W_TABLE (VEX_W_0F3A01_L_1
) },
7182 /* VEX_LEN_0F3A06 */
7185 { VEX_W_TABLE (VEX_W_0F3A06_L_1
) },
7188 /* VEX_LEN_0F3A14 */
7190 { "%XEvpextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
7193 /* VEX_LEN_0F3A15 */
7195 { "%XEvpextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
7198 /* VEX_LEN_0F3A16 */
7200 { "%XEvpextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
7203 /* VEX_LEN_0F3A17 */
7205 { "%XEvextractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
7208 /* VEX_LEN_0F3A18 */
7211 { VEX_W_TABLE (VEX_W_0F3A18_L_1
) },
7214 /* VEX_LEN_0F3A19 */
7217 { VEX_W_TABLE (VEX_W_0F3A19_L_1
) },
7220 /* VEX_LEN_0F3A20 */
7222 { "%XEvpinsrbY", { XM
, Vex
, Edb
, Ib
}, PREFIX_DATA
},
7225 /* VEX_LEN_0F3A21 */
7227 { "%XEvinsertpsY", { XM
, Vex
, EXd
, Ib
}, PREFIX_DATA
},
7230 /* VEX_LEN_0F3A22 */
7232 { "%XEvpinsrYK", { XM
, Vex
, Edq
, Ib
}, PREFIX_DATA
},
7235 /* VEX_LEN_0F3A30 */
7237 { "kshiftr%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7240 /* VEX_LEN_0F3A31 */
7242 { "kshiftr%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7245 /* VEX_LEN_0F3A32 */
7247 { "kshiftl%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7250 /* VEX_LEN_0F3A33 */
7252 { "kshiftl%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7255 /* VEX_LEN_0F3A38 */
7258 { VEX_W_TABLE (VEX_W_0F3A38_L_1
) },
7261 /* VEX_LEN_0F3A39 */
7264 { VEX_W_TABLE (VEX_W_0F3A39_L_1
) },
7267 /* VEX_LEN_0F3A41 */
7269 { "vdppd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7272 /* VEX_LEN_0F3A46 */
7275 { VEX_W_TABLE (VEX_W_0F3A46_L_1
) },
7278 /* VEX_LEN_0F3A60 */
7280 { "vpcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7283 /* VEX_LEN_0F3A61 */
7285 { "vpcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7288 /* VEX_LEN_0F3A62 */
7290 { "vpcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7293 /* VEX_LEN_0F3A63 */
7295 { "vpcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7298 /* VEX_LEN_0F3ADE_W_0 */
7300 { "vsm3rnds2", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7303 /* VEX_LEN_0F3ADF */
7305 { "vaeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7308 /* VEX_LEN_0F3AF0 */
7310 { PREFIX_TABLE (PREFIX_VEX_0F3AF0_L_0
) },
7313 /* VEX_LEN_MAP7_F6 */
7315 { VEX_W_TABLE (VEX_W_MAP7_F6_L_0
) },
7318 /* VEX_LEN_MAP7_F8 */
7320 { VEX_W_TABLE (VEX_W_MAP7_F8_L_0
) },
7323 /* VEX_LEN_XOP_08_85 */
7325 { VEX_W_TABLE (VEX_W_XOP_08_85_L_0
) },
7328 /* VEX_LEN_XOP_08_86 */
7330 { VEX_W_TABLE (VEX_W_XOP_08_86_L_0
) },
7333 /* VEX_LEN_XOP_08_87 */
7335 { VEX_W_TABLE (VEX_W_XOP_08_87_L_0
) },
7338 /* VEX_LEN_XOP_08_8E */
7340 { VEX_W_TABLE (VEX_W_XOP_08_8E_L_0
) },
7343 /* VEX_LEN_XOP_08_8F */
7345 { VEX_W_TABLE (VEX_W_XOP_08_8F_L_0
) },
7348 /* VEX_LEN_XOP_08_95 */
7350 { VEX_W_TABLE (VEX_W_XOP_08_95_L_0
) },
7353 /* VEX_LEN_XOP_08_96 */
7355 { VEX_W_TABLE (VEX_W_XOP_08_96_L_0
) },
7358 /* VEX_LEN_XOP_08_97 */
7360 { VEX_W_TABLE (VEX_W_XOP_08_97_L_0
) },
7363 /* VEX_LEN_XOP_08_9E */
7365 { VEX_W_TABLE (VEX_W_XOP_08_9E_L_0
) },
7368 /* VEX_LEN_XOP_08_9F */
7370 { VEX_W_TABLE (VEX_W_XOP_08_9F_L_0
) },
7373 /* VEX_LEN_XOP_08_A3 */
7375 { "vpperm", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7378 /* VEX_LEN_XOP_08_A6 */
7380 { VEX_W_TABLE (VEX_W_XOP_08_A6_L_0
) },
7383 /* VEX_LEN_XOP_08_B6 */
7385 { VEX_W_TABLE (VEX_W_XOP_08_B6_L_0
) },
7388 /* VEX_LEN_XOP_08_C0 */
7390 { VEX_W_TABLE (VEX_W_XOP_08_C0_L_0
) },
7393 /* VEX_LEN_XOP_08_C1 */
7395 { VEX_W_TABLE (VEX_W_XOP_08_C1_L_0
) },
7398 /* VEX_LEN_XOP_08_C2 */
7400 { VEX_W_TABLE (VEX_W_XOP_08_C2_L_0
) },
7403 /* VEX_LEN_XOP_08_C3 */
7405 { VEX_W_TABLE (VEX_W_XOP_08_C3_L_0
) },
7408 /* VEX_LEN_XOP_08_CC */
7410 { VEX_W_TABLE (VEX_W_XOP_08_CC_L_0
) },
7413 /* VEX_LEN_XOP_08_CD */
7415 { VEX_W_TABLE (VEX_W_XOP_08_CD_L_0
) },
7418 /* VEX_LEN_XOP_08_CE */
7420 { VEX_W_TABLE (VEX_W_XOP_08_CE_L_0
) },
7423 /* VEX_LEN_XOP_08_CF */
7425 { VEX_W_TABLE (VEX_W_XOP_08_CF_L_0
) },
7428 /* VEX_LEN_XOP_08_EC */
7430 { VEX_W_TABLE (VEX_W_XOP_08_EC_L_0
) },
7433 /* VEX_LEN_XOP_08_ED */
7435 { VEX_W_TABLE (VEX_W_XOP_08_ED_L_0
) },
7438 /* VEX_LEN_XOP_08_EE */
7440 { VEX_W_TABLE (VEX_W_XOP_08_EE_L_0
) },
7443 /* VEX_LEN_XOP_08_EF */
7445 { VEX_W_TABLE (VEX_W_XOP_08_EF_L_0
) },
7448 /* VEX_LEN_XOP_09_01 */
7450 { REG_TABLE (REG_XOP_09_01_L_0
) },
7453 /* VEX_LEN_XOP_09_02 */
7455 { REG_TABLE (REG_XOP_09_02_L_0
) },
7458 /* VEX_LEN_XOP_09_12 */
7460 { REG_TABLE (REG_XOP_09_12_L_0
) },
7463 /* VEX_LEN_XOP_09_82_W_0 */
7465 { "vfrczss", { XM
, EXd
}, 0 },
7468 /* VEX_LEN_XOP_09_83_W_0 */
7470 { "vfrczsd", { XM
, EXq
}, 0 },
7473 /* VEX_LEN_XOP_09_90 */
7475 { "vprotb", { XM
, EXx
, VexW
}, 0 },
7478 /* VEX_LEN_XOP_09_91 */
7480 { "vprotw", { XM
, EXx
, VexW
}, 0 },
7483 /* VEX_LEN_XOP_09_92 */
7485 { "vprotd", { XM
, EXx
, VexW
}, 0 },
7488 /* VEX_LEN_XOP_09_93 */
7490 { "vprotq", { XM
, EXx
, VexW
}, 0 },
7493 /* VEX_LEN_XOP_09_94 */
7495 { "vpshlb", { XM
, EXx
, VexW
}, 0 },
7498 /* VEX_LEN_XOP_09_95 */
7500 { "vpshlw", { XM
, EXx
, VexW
}, 0 },
7503 /* VEX_LEN_XOP_09_96 */
7505 { "vpshld", { XM
, EXx
, VexW
}, 0 },
7508 /* VEX_LEN_XOP_09_97 */
7510 { "vpshlq", { XM
, EXx
, VexW
}, 0 },
7513 /* VEX_LEN_XOP_09_98 */
7515 { "vpshab", { XM
, EXx
, VexW
}, 0 },
7518 /* VEX_LEN_XOP_09_99 */
7520 { "vpshaw", { XM
, EXx
, VexW
}, 0 },
7523 /* VEX_LEN_XOP_09_9A */
7525 { "vpshad", { XM
, EXx
, VexW
}, 0 },
7528 /* VEX_LEN_XOP_09_9B */
7530 { "vpshaq", { XM
, EXx
, VexW
}, 0 },
7533 /* VEX_LEN_XOP_09_C1 */
7535 { VEX_W_TABLE (VEX_W_XOP_09_C1_L_0
) },
7538 /* VEX_LEN_XOP_09_C2 */
7540 { VEX_W_TABLE (VEX_W_XOP_09_C2_L_0
) },
7543 /* VEX_LEN_XOP_09_C3 */
7545 { VEX_W_TABLE (VEX_W_XOP_09_C3_L_0
) },
7548 /* VEX_LEN_XOP_09_C6 */
7550 { VEX_W_TABLE (VEX_W_XOP_09_C6_L_0
) },
7553 /* VEX_LEN_XOP_09_C7 */
7555 { VEX_W_TABLE (VEX_W_XOP_09_C7_L_0
) },
7558 /* VEX_LEN_XOP_09_CB */
7560 { VEX_W_TABLE (VEX_W_XOP_09_CB_L_0
) },
7563 /* VEX_LEN_XOP_09_D1 */
7565 { VEX_W_TABLE (VEX_W_XOP_09_D1_L_0
) },
7568 /* VEX_LEN_XOP_09_D2 */
7570 { VEX_W_TABLE (VEX_W_XOP_09_D2_L_0
) },
7573 /* VEX_LEN_XOP_09_D3 */
7575 { VEX_W_TABLE (VEX_W_XOP_09_D3_L_0
) },
7578 /* VEX_LEN_XOP_09_D6 */
7580 { VEX_W_TABLE (VEX_W_XOP_09_D6_L_0
) },
7583 /* VEX_LEN_XOP_09_D7 */
7585 { VEX_W_TABLE (VEX_W_XOP_09_D7_L_0
) },
7588 /* VEX_LEN_XOP_09_DB */
7590 { VEX_W_TABLE (VEX_W_XOP_09_DB_L_0
) },
7593 /* VEX_LEN_XOP_09_E1 */
7595 { VEX_W_TABLE (VEX_W_XOP_09_E1_L_0
) },
7598 /* VEX_LEN_XOP_09_E2 */
7600 { VEX_W_TABLE (VEX_W_XOP_09_E2_L_0
) },
7603 /* VEX_LEN_XOP_09_E3 */
7605 { VEX_W_TABLE (VEX_W_XOP_09_E3_L_0
) },
7608 /* VEX_LEN_XOP_0A_12 */
7610 { REG_TABLE (REG_XOP_0A_12_L_0
) },
7614 #include "i386-dis-evex-len.h"
7616 static const struct dis386 vex_w_table
[][2] = {
7618 /* VEX_W_0F41_L_1_M_1 */
7619 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_0
) },
7620 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_1
) },
7623 /* VEX_W_0F42_L_1_M_1 */
7624 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_0
) },
7625 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_1
) },
7628 /* VEX_W_0F44_L_0_M_1 */
7629 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_0
) },
7630 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_1
) },
7633 /* VEX_W_0F45_L_1_M_1 */
7634 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_0
) },
7635 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_1
) },
7638 /* VEX_W_0F46_L_1_M_1 */
7639 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_0
) },
7640 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_1
) },
7643 /* VEX_W_0F47_L_1_M_1 */
7644 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_0
) },
7645 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_1
) },
7648 /* VEX_W_0F4A_L_1_M_1 */
7649 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_0
) },
7650 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_1
) },
7653 /* VEX_W_0F4B_L_1_M_1 */
7654 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_0
) },
7655 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_1
) },
7658 /* VEX_W_0F90_L_0 */
7659 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_0
) },
7660 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_1
) },
7663 /* VEX_W_0F91_L_0_M_0 */
7664 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_0
) },
7665 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_1
) },
7668 /* VEX_W_0F92_L_0_M_1 */
7669 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_0
) },
7670 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_1
) },
7673 /* VEX_W_0F93_L_0_M_1 */
7674 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_0
) },
7675 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_1
) },
7678 /* VEX_W_0F98_L_0_M_1 */
7679 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_0
) },
7680 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_1
) },
7683 /* VEX_W_0F99_L_0_M_1 */
7684 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_0
) },
7685 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_1
) },
7689 { "%XEvpermilps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7693 { "vpermilpd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7697 { "vtestps", { XM
, EXx
}, PREFIX_DATA
},
7701 { "vtestpd", { XM
, EXx
}, PREFIX_DATA
},
7705 { "vcvtph2ps", { XM
, EXxmmq
}, PREFIX_DATA
},
7708 /* VEX_W_0F3816_L_1 */
7709 { "vpermps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7713 { "%XEvbroadcastss", { XM
, EXd
}, PREFIX_DATA
},
7716 /* VEX_W_0F3819_L_1 */
7717 { "vbroadcastsd", { XM
, EXq
}, PREFIX_DATA
},
7720 /* VEX_W_0F381A_L_1 */
7721 { "vbroadcastf128", { XM
, Mxmm
}, PREFIX_DATA
},
7725 { "vmaskmovps", { XM
, Vex
, Mx
}, PREFIX_DATA
},
7729 { "vmaskmovpd", { XM
, Vex
, Mx
}, PREFIX_DATA
},
7733 { "vmaskmovps", { Mx
, Vex
, XM
}, PREFIX_DATA
},
7737 { "vmaskmovpd", { Mx
, Vex
, XM
}, PREFIX_DATA
},
7741 { "vpermd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7745 { "vpsravd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7748 /* VEX_W_0F3849_X86_64_L_0 */
7749 { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_0
) },
7752 /* VEX_W_0F384B_X86_64_L_0 */
7753 { PREFIX_TABLE (PREFIX_VEX_0F384B_X86_64_L_0_W_0
) },
7757 { PREFIX_TABLE (PREFIX_VEX_0F3850_W_0
) },
7761 { PREFIX_TABLE (PREFIX_VEX_0F3851_W_0
) },
7765 { "%XVvpdpwssd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7769 { "%XVvpdpwssds", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7773 { "%XEvpbroadcastd", { XM
, EXd
}, PREFIX_DATA
},
7777 { "vpbroadcastq", { XM
, EXq
}, PREFIX_DATA
},
7780 /* VEX_W_0F385A_L_0 */
7781 { "vbroadcasti128", { XM
, Mxmm
}, PREFIX_DATA
},
7784 /* VEX_W_0F385C_X86_64_L_0 */
7785 { PREFIX_TABLE (PREFIX_VEX_0F385C_X86_64_L_0_W_0
) },
7788 /* VEX_W_0F385E_X86_64_L_0 */
7789 { PREFIX_TABLE (PREFIX_VEX_0F385E_X86_64_L_0_W_0
) },
7792 /* VEX_W_0F386C_X86_64_L_0 */
7793 { PREFIX_TABLE (PREFIX_VEX_0F386C_X86_64_L_0_W_0
) },
7796 /* VEX_W_0F3872_P_1 */
7797 { "%XVvcvtneps2bf16%XY", { XMM
, EXx
}, 0 },
7801 { "%XEvpbroadcastb", { XM
, EXb
}, PREFIX_DATA
},
7805 { "%XEvpbroadcastw", { XM
, EXw
}, PREFIX_DATA
},
7809 { PREFIX_TABLE (PREFIX_VEX_0F38B0_W_0
) },
7813 { PREFIX_TABLE (PREFIX_VEX_0F38B1_W_0
) },
7818 { "%XVvpmadd52luq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7823 { "%XVvpmadd52huq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7826 /* VEX_W_0F38CB_P_3 */
7827 { VEX_LEN_TABLE (VEX_LEN_0F38CB_P_3_W_0
) },
7830 /* VEX_W_0F38CC_P_3 */
7831 { VEX_LEN_TABLE (VEX_LEN_0F38CC_P_3_W_0
) },
7834 /* VEX_W_0F38CD_P_3 */
7835 { VEX_LEN_TABLE (VEX_LEN_0F38CD_P_3_W_0
) },
7839 { "%XEvgf2p8mulb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7843 { PREFIX_TABLE (PREFIX_VEX_0F38D2_W_0
) },
7847 { PREFIX_TABLE (PREFIX_VEX_0F38D3_W_0
) },
7851 { PREFIX_TABLE (PREFIX_VEX_0F38DA_W_0
) },
7854 /* VEX_W_0F3A00_L_1 */
7856 { "%XEvpermq", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7859 /* VEX_W_0F3A01_L_1 */
7861 { "%XEvpermpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7865 { "vpblendd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7869 { "%XEvpermilps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7873 { "vpermilpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7876 /* VEX_W_0F3A06_L_1 */
7877 { "vperm2f128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7880 /* VEX_W_0F3A18_L_1 */
7881 { "vinsertf128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7884 /* VEX_W_0F3A19_L_1 */
7885 { "vextractf128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
7889 { "%XEvcvtps2ph", { EXxmmq
, XM
, EXxEVexS
, Ib
}, PREFIX_DATA
},
7892 /* VEX_W_0F3A38_L_1 */
7893 { "vinserti128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7896 /* VEX_W_0F3A39_L_1 */
7897 { "vextracti128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
7900 /* VEX_W_0F3A46_L_1 */
7901 { "vperm2i128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7905 { "vblendvps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7909 { "vblendvpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7913 { "vpblendvb", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
7918 { "%XEvgf2p8affineqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7923 { "%XEvgf2p8affineinvqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7927 { VEX_LEN_TABLE (VEX_LEN_0F3ADE_W_0
) },
7930 /* VEX_W_MAP7_F6_L_0 */
7931 { REG_TABLE (REG_VEX_MAP7_F6_L_0_W_0
) },
7934 /* VEX_W_MAP7_F8_L_0 */
7935 { REG_TABLE (REG_VEX_MAP7_F8_L_0_W_0
) },
7937 /* VEX_W_XOP_08_85_L_0 */
7939 { "vpmacssww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7941 /* VEX_W_XOP_08_86_L_0 */
7943 { "vpmacsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7945 /* VEX_W_XOP_08_87_L_0 */
7947 { "vpmacssdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7949 /* VEX_W_XOP_08_8E_L_0 */
7951 { "vpmacssdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7953 /* VEX_W_XOP_08_8F_L_0 */
7955 { "vpmacssdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7957 /* VEX_W_XOP_08_95_L_0 */
7959 { "vpmacsww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7961 /* VEX_W_XOP_08_96_L_0 */
7963 { "vpmacswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7965 /* VEX_W_XOP_08_97_L_0 */
7967 { "vpmacsdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7969 /* VEX_W_XOP_08_9E_L_0 */
7971 { "vpmacsdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7973 /* VEX_W_XOP_08_9F_L_0 */
7975 { "vpmacsdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7977 /* VEX_W_XOP_08_A6_L_0 */
7979 { "vpmadcsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7981 /* VEX_W_XOP_08_B6_L_0 */
7983 { "vpmadcswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7985 /* VEX_W_XOP_08_C0_L_0 */
7987 { "vprotb", { XM
, EXx
, Ib
}, 0 },
7989 /* VEX_W_XOP_08_C1_L_0 */
7991 { "vprotw", { XM
, EXx
, Ib
}, 0 },
7993 /* VEX_W_XOP_08_C2_L_0 */
7995 { "vprotd", { XM
, EXx
, Ib
}, 0 },
7997 /* VEX_W_XOP_08_C3_L_0 */
7999 { "vprotq", { XM
, EXx
, Ib
}, 0 },
8001 /* VEX_W_XOP_08_CC_L_0 */
8003 { "vpcomb", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8005 /* VEX_W_XOP_08_CD_L_0 */
8007 { "vpcomw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8009 /* VEX_W_XOP_08_CE_L_0 */
8011 { "vpcomd", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8013 /* VEX_W_XOP_08_CF_L_0 */
8015 { "vpcomq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8017 /* VEX_W_XOP_08_EC_L_0 */
8019 { "vpcomub", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8021 /* VEX_W_XOP_08_ED_L_0 */
8023 { "vpcomuw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8025 /* VEX_W_XOP_08_EE_L_0 */
8027 { "vpcomud", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8029 /* VEX_W_XOP_08_EF_L_0 */
8031 { "vpcomuq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8033 /* VEX_W_XOP_09_80 */
8035 { "vfrczps", { XM
, EXx
}, 0 },
8037 /* VEX_W_XOP_09_81 */
8039 { "vfrczpd", { XM
, EXx
}, 0 },
8041 /* VEX_W_XOP_09_82 */
8043 { VEX_LEN_TABLE (VEX_LEN_XOP_09_82_W_0
) },
8045 /* VEX_W_XOP_09_83 */
8047 { VEX_LEN_TABLE (VEX_LEN_XOP_09_83_W_0
) },
8049 /* VEX_W_XOP_09_C1_L_0 */
8051 { "vphaddbw", { XM
, EXxmm
}, 0 },
8053 /* VEX_W_XOP_09_C2_L_0 */
8055 { "vphaddbd", { XM
, EXxmm
}, 0 },
8057 /* VEX_W_XOP_09_C3_L_0 */
8059 { "vphaddbq", { XM
, EXxmm
}, 0 },
8061 /* VEX_W_XOP_09_C6_L_0 */
8063 { "vphaddwd", { XM
, EXxmm
}, 0 },
8065 /* VEX_W_XOP_09_C7_L_0 */
8067 { "vphaddwq", { XM
, EXxmm
}, 0 },
8069 /* VEX_W_XOP_09_CB_L_0 */
8071 { "vphadddq", { XM
, EXxmm
}, 0 },
8073 /* VEX_W_XOP_09_D1_L_0 */
8075 { "vphaddubw", { XM
, EXxmm
}, 0 },
8077 /* VEX_W_XOP_09_D2_L_0 */
8079 { "vphaddubd", { XM
, EXxmm
}, 0 },
8081 /* VEX_W_XOP_09_D3_L_0 */
8083 { "vphaddubq", { XM
, EXxmm
}, 0 },
8085 /* VEX_W_XOP_09_D6_L_0 */
8087 { "vphadduwd", { XM
, EXxmm
}, 0 },
8089 /* VEX_W_XOP_09_D7_L_0 */
8091 { "vphadduwq", { XM
, EXxmm
}, 0 },
8093 /* VEX_W_XOP_09_DB_L_0 */
8095 { "vphaddudq", { XM
, EXxmm
}, 0 },
8097 /* VEX_W_XOP_09_E1_L_0 */
8099 { "vphsubbw", { XM
, EXxmm
}, 0 },
8101 /* VEX_W_XOP_09_E2_L_0 */
8103 { "vphsubwd", { XM
, EXxmm
}, 0 },
8105 /* VEX_W_XOP_09_E3_L_0 */
8107 { "vphsubdq", { XM
, EXxmm
}, 0 },
8110 #include "i386-dis-evex-w.h"
8113 static const struct dis386 mod_table
[][2] = {
8116 { "bound{S|}", { Gv
, Ma
}, 0 },
8121 { "lesS", { Gv
, Mp
}, 0 },
8122 { VEX_C4_TABLE () },
8126 { "ldsS", { Gv
, Mp
}, 0 },
8127 { VEX_C5_TABLE () },
8130 /* MOD_0F01_REG_0 */
8131 { X86_64_TABLE (X86_64_0F01_REG_0
) },
8132 { RM_TABLE (RM_0F01_REG_0
) },
8135 /* MOD_0F01_REG_1 */
8136 { X86_64_TABLE (X86_64_0F01_REG_1
) },
8137 { RM_TABLE (RM_0F01_REG_1
) },
8140 /* MOD_0F01_REG_2 */
8141 { X86_64_TABLE (X86_64_0F01_REG_2
) },
8142 { RM_TABLE (RM_0F01_REG_2
) },
8145 /* MOD_0F01_REG_3 */
8146 { X86_64_TABLE (X86_64_0F01_REG_3
) },
8147 { RM_TABLE (RM_0F01_REG_3
) },
8150 /* MOD_0F01_REG_5 */
8151 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_0
) },
8152 { RM_TABLE (RM_0F01_REG_5_MOD_3
) },
8155 /* MOD_0F01_REG_7 */
8156 { "invlpg", { Mb
}, 0 },
8157 { RM_TABLE (RM_0F01_REG_7_MOD_3
) },
8160 /* MOD_0F12_PREFIX_0 */
8161 { "%XEVmovlpYX", { XM
, Vex
, EXq
}, 0 },
8162 { "%XEVmovhlpY%XS", { XM
, Vex
, EXq
}, 0 },
8165 /* MOD_0F16_PREFIX_0 */
8166 { "%XEVmovhpYX", { XM
, Vex
, EXq
}, 0 },
8167 { "%XEVmovlhpY%XS", { XM
, Vex
, EXq
}, 0 },
8170 /* MOD_0F18_REG_0 */
8171 { "prefetchnta", { Mb
}, 0 },
8172 { "nopQ", { Ev
}, 0 },
8175 /* MOD_0F18_REG_1 */
8176 { "prefetcht0", { Mb
}, 0 },
8177 { "nopQ", { Ev
}, 0 },
8180 /* MOD_0F18_REG_2 */
8181 { "prefetcht1", { Mb
}, 0 },
8182 { "nopQ", { Ev
}, 0 },
8185 /* MOD_0F18_REG_3 */
8186 { "prefetcht2", { Mb
}, 0 },
8187 { "nopQ", { Ev
}, 0 },
8190 /* MOD_0F18_REG_6 */
8191 { X86_64_TABLE (X86_64_0F18_REG_6_MOD_0
) },
8192 { "nopQ", { Ev
}, 0 },
8195 /* MOD_0F18_REG_7 */
8196 { X86_64_TABLE (X86_64_0F18_REG_7_MOD_0
) },
8197 { "nopQ", { Ev
}, 0 },
8200 /* MOD_0F1A_PREFIX_0 */
8201 { "bndldx", { Gbnd
, Mv_bnd
}, 0 },
8202 { "nopQ", { Ev
}, 0 },
8205 /* MOD_0F1B_PREFIX_0 */
8206 { "bndstx", { Mv_bnd
, Gbnd
}, 0 },
8207 { "nopQ", { Ev
}, 0 },
8210 /* MOD_0F1B_PREFIX_1 */
8211 { "bndmk", { Gbnd
, Mv_bnd
}, 0 },
8212 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8215 /* MOD_0F1C_PREFIX_0 */
8216 { REG_TABLE (REG_0F1C_P_0_MOD_0
) },
8217 { "nopQ", { Ev
}, 0 },
8220 /* MOD_0F1E_PREFIX_1 */
8221 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8222 { REG_TABLE (REG_0F1E_P_1_MOD_3
) },
8225 /* MOD_0FAE_REG_0 */
8226 { "fxsave", { FXSAVE
}, 0 },
8227 { PREFIX_TABLE (PREFIX_0FAE_REG_0_MOD_3
) },
8230 /* MOD_0FAE_REG_1 */
8231 { "fxrstor", { FXSAVE
}, 0 },
8232 { PREFIX_TABLE (PREFIX_0FAE_REG_1_MOD_3
) },
8235 /* MOD_0FAE_REG_2 */
8236 { "ldmxcsr", { Md
}, 0 },
8237 { PREFIX_TABLE (PREFIX_0FAE_REG_2_MOD_3
) },
8240 /* MOD_0FAE_REG_3 */
8241 { "stmxcsr", { Md
}, 0 },
8242 { PREFIX_TABLE (PREFIX_0FAE_REG_3_MOD_3
) },
8245 /* MOD_0FAE_REG_4 */
8246 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_0
) },
8247 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_3
) },
8250 /* MOD_0FAE_REG_5 */
8251 { "xrstor", { FXSAVE
}, PREFIX_OPCODE
| PREFIX_REX2_ILLEGAL
},
8252 { PREFIX_TABLE (PREFIX_0FAE_REG_5_MOD_3
) },
8255 /* MOD_0FAE_REG_6 */
8256 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_0
) },
8257 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_3
) },
8260 /* MOD_0FAE_REG_7 */
8261 { PREFIX_TABLE (PREFIX_0FAE_REG_7_MOD_0
) },
8262 { RM_TABLE (RM_0FAE_REG_7_MOD_3
) },
8265 /* MOD_0FC7_REG_6 */
8266 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_0
) },
8267 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_3
) }
8270 /* MOD_0FC7_REG_7 */
8271 { "vmptrst", { Mq
}, 0 },
8272 { PREFIX_TABLE (PREFIX_0FC7_REG_7_MOD_3
) }
8275 /* MOD_0F38DC_PREFIX_1 */
8276 { "aesenc128kl", { XM
, M
}, 0 },
8277 { "loadiwkey", { XM
, EXx
}, 0 },
8281 { PREFIX_TABLE (PREFIX_0F38F8_M_0
) },
8282 { X86_64_TABLE (X86_64_0F38F8_M_1
) },
8285 /* MOD_VEX_0F3849_X86_64_L_0_W_0 */
8286 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
) },
8287 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
) },
8290 #include "i386-dis-evex-mod.h"
8293 static const struct dis386 rm_table
[][8] = {
8296 { "xabort", { Skip_MODRM
, Ib
}, 0 },
8300 { "xbeginT", { Skip_MODRM
, Jdqw
}, 0 },
8304 { "enclv", { Skip_MODRM
}, 0 },
8305 { "vmcall", { Skip_MODRM
}, 0 },
8306 { "vmlaunch", { Skip_MODRM
}, 0 },
8307 { "vmresume", { Skip_MODRM
}, 0 },
8308 { "vmxoff", { Skip_MODRM
}, 0 },
8309 { "pconfig", { Skip_MODRM
}, 0 },
8310 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_6
) },
8311 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_7
) },
8315 { "monitor", { { OP_Monitor
, 0 } }, 0 },
8316 { "mwait", { { OP_Mwait
, 0 } }, 0 },
8317 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_2
) },
8318 { "stac", { Skip_MODRM
}, 0 },
8319 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_4
) },
8320 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_5
) },
8321 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_6
) },
8322 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_7
) },
8326 { "xgetbv", { Skip_MODRM
}, 0 },
8327 { "xsetbv", { Skip_MODRM
}, 0 },
8330 { "vmfunc", { Skip_MODRM
}, 0 },
8331 { "xend", { Skip_MODRM
}, 0 },
8332 { "xtest", { Skip_MODRM
}, 0 },
8333 { "enclu", { Skip_MODRM
}, 0 },
8337 { "vmrun", { Skip_MODRM
}, 0 },
8338 { PREFIX_TABLE (PREFIX_0F01_REG_3_RM_1
) },
8339 { "vmload", { Skip_MODRM
}, 0 },
8340 { "vmsave", { Skip_MODRM
}, 0 },
8341 { "stgi", { Skip_MODRM
}, 0 },
8342 { "clgi", { Skip_MODRM
}, 0 },
8343 { "skinit", { Skip_MODRM
}, 0 },
8344 { "invlpga", { Skip_MODRM
}, 0 },
8347 /* RM_0F01_REG_5_MOD_3 */
8348 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_0
) },
8349 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_1
) },
8350 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_2
) },
8352 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_4
) },
8353 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_5
) },
8354 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_6
) },
8355 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_7
) },
8358 /* RM_0F01_REG_7_MOD_3 */
8359 { "swapgs", { Skip_MODRM
}, 0 },
8360 { "rdtscp", { Skip_MODRM
}, 0 },
8361 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_2
) },
8362 { "mwaitx", { { OP_Mwait
, eBX_reg
} }, PREFIX_OPCODE
},
8363 { "clzero", { Skip_MODRM
}, 0 },
8364 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_5
) },
8365 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_6
) },
8366 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_7
) },
8369 /* RM_0F1E_P_1_MOD_3_REG_7 */
8370 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8371 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8372 { "endbr64", { Skip_MODRM
}, 0 },
8373 { "endbr32", { Skip_MODRM
}, 0 },
8374 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8375 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8376 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8377 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8380 /* RM_0FAE_REG_6_MOD_3 */
8381 { "mfence", { Skip_MODRM
}, 0 },
8384 /* RM_0FAE_REG_7_MOD_3 */
8385 { "sfence", { Skip_MODRM
}, 0 },
8388 /* RM_0F3A0F_P_1_R_0 */
8389 { "hreset", { Skip_MODRM
, Ib
}, 0 },
8392 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0 */
8393 { "tilerelease", { Skip_MODRM
}, 0 },
8396 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3 */
8397 { "tilezero", { TMM
, Skip_MODRM
}, 0 },
8401 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
8403 /* The values used here must be non-zero, fit in 'unsigned char', and not be
8404 in conflict with actual prefix opcodes. */
8405 #define REP_PREFIX 0x01
8406 #define XACQUIRE_PREFIX 0x02
8407 #define XRELEASE_PREFIX 0x03
8408 #define BND_PREFIX 0x04
8409 #define NOTRACK_PREFIX 0x05
8416 ckprefix (instr_info
*ins
)
8423 /* The maximum instruction length is 15bytes. */
8424 while (length
< MAX_CODE_LENGTH
- 1)
8426 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
8427 return ckp_fetch_error
;
8429 switch (*ins
->codep
)
8431 /* REX prefixes family. */
8448 if (ins
->address_mode
== mode_64bit
)
8449 newrex
= *ins
->codep
;
8452 ins
->last_rex_prefix
= i
;
8454 /* REX2 must be the last prefix. */
8456 if (ins
->address_mode
== mode_64bit
)
8458 if (ins
->last_rex_prefix
>= 0)
8462 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
8463 return ckp_fetch_error
;
8464 ins
->rex2_payload
= *ins
->codep
;
8465 ins
->rex2
= ins
->rex2_payload
>> 4;
8466 ins
->rex
= (ins
->rex2_payload
& 0xf) | REX_OPCODE
;
8468 ins
->last_rex2_prefix
= i
;
8469 ins
->all_prefixes
[i
] = REX2_OPCODE
;
8473 ins
->prefixes
|= PREFIX_REPZ
;
8474 ins
->last_repz_prefix
= i
;
8477 ins
->prefixes
|= PREFIX_REPNZ
;
8478 ins
->last_repnz_prefix
= i
;
8481 ins
->prefixes
|= PREFIX_LOCK
;
8482 ins
->last_lock_prefix
= i
;
8485 ins
->prefixes
|= PREFIX_CS
;
8486 ins
->last_seg_prefix
= i
;
8487 if (ins
->address_mode
!= mode_64bit
)
8488 ins
->active_seg_prefix
= PREFIX_CS
;
8491 ins
->prefixes
|= PREFIX_SS
;
8492 ins
->last_seg_prefix
= i
;
8493 if (ins
->address_mode
!= mode_64bit
)
8494 ins
->active_seg_prefix
= PREFIX_SS
;
8497 ins
->prefixes
|= PREFIX_DS
;
8498 ins
->last_seg_prefix
= i
;
8499 if (ins
->address_mode
!= mode_64bit
)
8500 ins
->active_seg_prefix
= PREFIX_DS
;
8503 ins
->prefixes
|= PREFIX_ES
;
8504 ins
->last_seg_prefix
= i
;
8505 if (ins
->address_mode
!= mode_64bit
)
8506 ins
->active_seg_prefix
= PREFIX_ES
;
8509 ins
->prefixes
|= PREFIX_FS
;
8510 ins
->last_seg_prefix
= i
;
8511 ins
->active_seg_prefix
= PREFIX_FS
;
8514 ins
->prefixes
|= PREFIX_GS
;
8515 ins
->last_seg_prefix
= i
;
8516 ins
->active_seg_prefix
= PREFIX_GS
;
8519 ins
->prefixes
|= PREFIX_DATA
;
8520 ins
->last_data_prefix
= i
;
8523 ins
->prefixes
|= PREFIX_ADDR
;
8524 ins
->last_addr_prefix
= i
;
8527 /* fwait is really an instruction. If there are prefixes
8528 before the fwait, they belong to the fwait, *not* to the
8529 following instruction. */
8530 ins
->fwait_prefix
= i
;
8531 if (ins
->prefixes
|| ins
->rex
)
8533 ins
->prefixes
|= PREFIX_FWAIT
;
8535 /* This ensures that the previous REX prefixes are noticed
8536 as unused prefixes, as in the return case below. */
8537 return ins
->rex
? ckp_bogus
: ckp_okay
;
8539 ins
->prefixes
= PREFIX_FWAIT
;
8544 /* Rex is ignored when followed by another prefix. */
8547 if (*ins
->codep
!= FWAIT_OPCODE
)
8548 ins
->all_prefixes
[i
++] = *ins
->codep
;
8556 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
8560 prefix_name (enum address_mode mode
, uint8_t pref
, int sizeflag
)
8562 static const char *rexes
[16] =
8567 "rex.XB", /* 0x43 */
8569 "rex.RB", /* 0x45 */
8570 "rex.RX", /* 0x46 */
8571 "rex.RXB", /* 0x47 */
8573 "rex.WB", /* 0x49 */
8574 "rex.WX", /* 0x4a */
8575 "rex.WXB", /* 0x4b */
8576 "rex.WR", /* 0x4c */
8577 "rex.WRB", /* 0x4d */
8578 "rex.WRX", /* 0x4e */
8579 "rex.WRXB", /* 0x4f */
8584 /* REX prefixes family. */
8601 return rexes
[pref
- 0x40];
8621 return (sizeflag
& DFLAG
) ? "data16" : "data32";
8623 if (mode
== mode_64bit
)
8624 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
8626 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
8631 case XACQUIRE_PREFIX
:
8633 case XRELEASE_PREFIX
:
8637 case NOTRACK_PREFIX
:
8647 print_i386_disassembler_options (FILE *stream
)
8649 fprintf (stream
, _("\n\
8650 The following i386/x86-64 specific disassembler options are supported for use\n\
8651 with the -M switch (multiple options should be separated by commas):\n"));
8653 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
8654 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
8655 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
8656 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
8657 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
8658 fprintf (stream
, _(" att-mnemonic (AT&T syntax only)\n"
8659 " Display instruction with AT&T mnemonic\n"));
8660 fprintf (stream
, _(" intel-mnemonic (AT&T syntax only)\n"
8661 " Display instruction with Intel mnemonic\n"));
8662 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
8663 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
8664 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
8665 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
8666 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
8667 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
8668 fprintf (stream
, _(" amd64 Display instruction in AMD64 ISA\n"));
8669 fprintf (stream
, _(" intel64 Display instruction in Intel64 ISA\n"));
8673 static const struct dis386 bad_opcode
= { "(bad)", { XX
}, 0 };
8675 /* Fetch error indicator. */
8676 static const struct dis386 err_opcode
= { NULL
, { XX
}, 0 };
8678 static const struct dis386 map7_f6_opcode
= { VEX_LEN_TABLE (VEX_LEN_MAP7_F6
) };
8679 static const struct dis386 map7_f8_opcode
= { VEX_LEN_TABLE (VEX_LEN_MAP7_F8
) };
8681 /* Get a pointer to struct dis386 with a valid name. */
8683 static const struct dis386
*
8684 get_valid_dis386 (const struct dis386
*dp
, instr_info
*ins
)
8686 int vindex
, vex_table_index
;
8688 if (dp
->name
!= NULL
)
8691 switch (dp
->op
[0].bytemode
)
8694 dp
= ®_table
[dp
->op
[1].bytemode
][ins
->modrm
.reg
];
8698 vindex
= ins
->modrm
.mod
== 0x3 ? 1 : 0;
8699 dp
= &mod_table
[dp
->op
[1].bytemode
][vindex
];
8703 dp
= &rm_table
[dp
->op
[1].bytemode
][ins
->modrm
.rm
];
8706 case USE_PREFIX_TABLE
:
8710 /* The prefix in VEX is implicit. */
8711 switch (ins
->vex
.prefix
)
8716 case REPE_PREFIX_OPCODE
:
8719 case DATA_PREFIX_OPCODE
:
8722 case REPNE_PREFIX_OPCODE
:
8732 int last_prefix
= -1;
8735 /* We check PREFIX_REPNZ and PREFIX_REPZ before PREFIX_DATA.
8736 When there are multiple PREFIX_REPNZ and PREFIX_REPZ, the
8738 if ((ins
->prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
8740 if (ins
->last_repz_prefix
> ins
->last_repnz_prefix
)
8743 prefix
= PREFIX_REPZ
;
8744 last_prefix
= ins
->last_repz_prefix
;
8749 prefix
= PREFIX_REPNZ
;
8750 last_prefix
= ins
->last_repnz_prefix
;
8753 /* Check if prefix should be ignored. */
8754 if ((((prefix_table
[dp
->op
[1].bytemode
][vindex
].prefix_requirement
8755 & PREFIX_IGNORED
) >> PREFIX_IGNORED_SHIFT
)
8757 && !prefix_table
[dp
->op
[1].bytemode
][vindex
].name
)
8761 if (vindex
== 0 && (ins
->prefixes
& PREFIX_DATA
) != 0)
8764 prefix
= PREFIX_DATA
;
8765 last_prefix
= ins
->last_data_prefix
;
8770 ins
->used_prefixes
|= prefix
;
8771 ins
->all_prefixes
[last_prefix
] = 0;
8774 dp
= &prefix_table
[dp
->op
[1].bytemode
][vindex
];
8777 case USE_X86_64_EVEX_FROM_VEX_TABLE
:
8778 case USE_X86_64_EVEX_PFX_TABLE
:
8779 case USE_X86_64_EVEX_W_TABLE
:
8780 case USE_X86_64_EVEX_MEM_W_TABLE
:
8781 ins
->evex_type
= evex_from_vex
;
8782 /* EVEX from VEX instructions are 64-bit only and require that EVEX.z,
8783 EVEX.L'L, EVEX.b, and the lower 2 bits of EVEX.aaa must be 0. */
8784 if (ins
->address_mode
!= mode_64bit
8785 || (ins
->vex
.mask_register_specifier
& 0x3) != 0
8787 || ins
->vex
.zeroing
!= 0
8791 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_PFX_TABLE
)
8792 goto use_prefix_table
;
8793 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_W_TABLE
)
8794 goto use_vex_w_table
;
8795 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_MEM_W_TABLE
)
8797 if (ins
->modrm
.mod
== 3)
8799 goto use_vex_w_table
;
8803 case USE_X86_64_TABLE
:
8804 vindex
= ins
->address_mode
== mode_64bit
? 1 : 0;
8805 dp
= &x86_64_table
[dp
->op
[1].bytemode
][vindex
];
8808 case USE_3BYTE_TABLE
:
8809 if (ins
->last_rex2_prefix
>= 0)
8811 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
8813 vindex
= *ins
->codep
++;
8814 dp
= &three_byte_table
[dp
->op
[1].bytemode
][vindex
];
8815 ins
->end_codep
= ins
->codep
;
8816 if (!fetch_modrm (ins
))
8820 case USE_VEX_LEN_TABLE
:
8824 switch (ins
->vex
.length
)
8830 /* This allows re-using in particular table entries where only
8831 128-bit operand size (VEX.L=0 / EVEX.L'L=0) are valid. */
8844 dp
= &vex_len_table
[dp
->op
[1].bytemode
][vindex
];
8847 case USE_EVEX_LEN_TABLE
:
8851 switch (ins
->vex
.length
)
8867 dp
= &evex_len_table
[dp
->op
[1].bytemode
][vindex
];
8870 case USE_XOP_8F_TABLE
:
8871 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
8873 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
8875 /* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm". */
8876 switch ((*ins
->codep
& 0x1f))
8882 vex_table_index
= XOP_08
;
8885 vex_table_index
= XOP_09
;
8888 vex_table_index
= XOP_0A
;
8892 ins
->vex
.w
= *ins
->codep
& 0x80;
8893 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
8896 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8897 if (ins
->address_mode
!= mode_64bit
)
8899 /* In 16/32-bit mode REX_B is silently ignored. */
8903 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
8904 switch ((*ins
->codep
& 0x3))
8909 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8912 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8915 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8920 vindex
= *ins
->codep
++;
8921 dp
= &xop_table
[vex_table_index
][vindex
];
8923 ins
->end_codep
= ins
->codep
;
8924 if (!fetch_modrm (ins
))
8927 /* No XOP encoding so far allows for a non-zero embedded prefix. Avoid
8928 having to decode the bits for every otherwise valid encoding. */
8929 if (ins
->vex
.prefix
)
8933 case USE_VEX_C4_TABLE
:
8935 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
8937 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
8938 switch ((*ins
->codep
& 0x1f))
8944 vex_table_index
= VEX_0F
;
8947 vex_table_index
= VEX_0F38
;
8950 vex_table_index
= VEX_0F3A
;
8953 vex_table_index
= VEX_MAP7
;
8957 ins
->vex
.w
= *ins
->codep
& 0x80;
8958 if (ins
->address_mode
== mode_64bit
)
8965 /* For the 3-byte VEX prefix in 32-bit mode, the REX_B bit
8966 is ignored, other REX bits are 0 and the highest bit in
8967 VEX.vvvv is also ignored (but we mustn't clear it here). */
8970 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
8971 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
8972 switch ((*ins
->codep
& 0x3))
8977 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
8980 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
8983 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
8988 vindex
= *ins
->codep
++;
8989 ins
->condition_code
= vindex
& 0xf;
8990 if (vex_table_index
!= VEX_MAP7
)
8991 dp
= &vex_table
[vex_table_index
][vindex
];
8992 else if (vindex
== 0xf6)
8993 dp
= &map7_f6_opcode
;
8994 else if (vindex
== 0xf8)
8995 dp
= &map7_f8_opcode
;
8998 ins
->end_codep
= ins
->codep
;
8999 /* There is no MODRM byte for VEX0F 77. */
9000 if ((vex_table_index
!= VEX_0F
|| vindex
!= 0x77)
9001 && !fetch_modrm (ins
))
9005 case USE_VEX_C5_TABLE
:
9007 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
9009 ins
->rex
= (*ins
->codep
& 0x80) ? 0 : REX_R
;
9011 /* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
9013 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9014 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
9015 switch ((*ins
->codep
& 0x3))
9020 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9023 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9026 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9031 vindex
= *ins
->codep
++;
9032 dp
= &vex_table
[VEX_0F
][vindex
];
9033 ins
->end_codep
= ins
->codep
;
9034 /* There is no MODRM byte for VEX 77. */
9035 if (vindex
!= 0x77 && !fetch_modrm (ins
))
9039 case USE_VEX_W_TABLE
:
9044 dp
= &vex_w_table
[dp
->op
[1].bytemode
][ins
->vex
.w
];
9047 case USE_EVEX_TABLE
:
9048 ins
->two_source_ops
= false;
9050 ins
->vex
.evex
= true;
9051 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
9053 /* The first byte after 0x62. */
9054 if (*ins
->codep
& 0x8)
9056 if (!(*ins
->codep
& 0x10))
9059 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
9060 switch (*ins
->codep
& 0x7)
9065 vex_table_index
= EVEX_0F
;
9068 vex_table_index
= EVEX_0F38
;
9071 vex_table_index
= EVEX_0F3A
;
9074 vex_table_index
= EVEX_MAP4
;
9075 ins
->evex_type
= evex_from_legacy
;
9076 if (ins
->address_mode
!= mode_64bit
)
9078 ins
->rex
|= REX_OPCODE
;
9081 vex_table_index
= EVEX_MAP5
;
9084 vex_table_index
= EVEX_MAP6
;
9087 vex_table_index
= EVEX_MAP7
;
9091 /* The second byte after 0x62. */
9093 ins
->vex
.w
= *ins
->codep
& 0x80;
9094 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
9097 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9099 if (!(*ins
->codep
& 0x4))
9102 ins
->vex
.u
= *ins
->codep
& 0x4;
9104 switch ((*ins
->codep
& 0x3))
9109 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9112 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9115 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9119 /* The third byte after 0x62. */
9122 /* Remember the static rounding bits. */
9123 ins
->vex
.ll
= (*ins
->codep
>> 5) & 3;
9124 ins
->vex
.b
= *ins
->codep
& 0x10;
9126 ins
->vex
.v
= *ins
->codep
& 0x8;
9127 ins
->vex
.mask_register_specifier
= *ins
->codep
& 0x7;
9128 ins
->vex
.scc
= *ins
->codep
& 0xf;
9129 ins
->vex
.zeroing
= *ins
->codep
& 0x80;
9130 /* Set the NF bit for EVEX-Promoted instructions, this bit will be cleared
9131 when it's an evex_default one. */
9132 ins
->vex
.nf
= *ins
->codep
& 0x4;
9134 if (ins
->address_mode
!= mode_64bit
)
9136 /* Report bad for !evex_default and when two fixed values of evex
9138 if (ins
->evex_type
!= evex_default
|| (ins
->rex2
& REX_B
)
9139 || ((ins
->rex2
& REX_X
) && (ins
->modrm
.mod
!= 3)))
9141 /* In 16/32-bit mode silently ignore following bits. */
9143 ins
->rex2
&= ~REX_R
;
9149 vindex
= *ins
->codep
++;
9150 ins
->condition_code
= vindex
& 0xf;
9151 if (vex_table_index
!= EVEX_MAP7
)
9152 dp
= &evex_table
[vex_table_index
][vindex
];
9153 else if (vindex
== 0xf8)
9154 dp
= &map7_f8_opcode
;
9155 else if (vindex
== 0xf6)
9156 dp
= &map7_f6_opcode
;
9159 ins
->end_codep
= ins
->codep
;
9160 if (!fetch_modrm (ins
))
9163 /* When modrm.mod != 3, the U bit is used by APX for bit X4.
9164 When modrm.mod == 3, the U bit is used by AVX10. The U bit and
9165 the b bit should not be zero at the same time. */
9166 if (ins
->modrm
.mod
== 3 && !ins
->vex
.u
&& !ins
->vex
.b
)
9169 /* Set vector length. For EVEX-promoted instructions, evex.ll == 0b00,
9170 which has the same encoding as vex.length == 128 and they can share
9171 the same processing with vex.length in OP_VEX. */
9172 if (ins
->modrm
.mod
== 3 && ins
->vex
.b
&& ins
->evex_type
!= evex_from_legacy
)
9175 ins
->vex
.length
= 512;
9177 ins
->vex
.length
= 256;
9181 switch (ins
->vex
.ll
)
9184 ins
->vex
.length
= 128;
9187 ins
->vex
.length
= 256;
9190 ins
->vex
.length
= 512;
9206 if (dp
->name
!= NULL
)
9209 return get_valid_dis386 (dp
, ins
);
9213 get_sib (instr_info
*ins
, int sizeflag
)
9215 /* If modrm.mod == 3, operand must be register. */
9217 && ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
9218 && ins
->modrm
.mod
!= 3
9219 && ins
->modrm
.rm
== 4)
9221 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
9223 ins
->sib
.index
= (ins
->codep
[1] >> 3) & 7;
9224 ins
->sib
.scale
= (ins
->codep
[1] >> 6) & 3;
9225 ins
->sib
.base
= ins
->codep
[1] & 7;
9226 ins
->has_sib
= true;
9229 ins
->has_sib
= false;
9234 /* Like oappend_with_style (below) but always with text style. */
9237 oappend (instr_info
*ins
, const char *s
)
9239 oappend_with_style (ins
, s
, dis_style_text
);
9242 /* Like oappend (above), but S is a string starting with '%'. In
9243 Intel syntax, the '%' is elided. */
9246 oappend_register (instr_info
*ins
, const char *s
)
9248 oappend_with_style (ins
, s
+ ins
->intel_syntax
, dis_style_register
);
9251 /* Wrap around a call to INS->info->fprintf_styled_func, printing FMT.
9252 STYLE is the default style to use in the fprintf_styled_func calls,
9253 however, FMT might include embedded style markers (see oappend_style),
9254 these embedded markers are not printed, but instead change the style
9255 used in the next fprintf_styled_func call. */
9257 static void ATTRIBUTE_PRINTF_3
9258 i386_dis_printf (const disassemble_info
*info
, enum disassembler_style style
,
9259 const char *fmt
, ...)
9262 enum disassembler_style curr_style
= style
;
9263 const char *start
, *curr
;
9264 char staging_area
[50];
9267 /* In particular print_insn()'s processing of op_txt[] can hand rather long
9268 strings here. Bypass vsnprintf() in such cases to avoid capacity issues
9269 with the staging area. */
9270 if (strcmp (fmt
, "%s"))
9272 int res
= vsnprintf (staging_area
, sizeof (staging_area
), fmt
, ap
);
9279 if ((size_t) res
>= sizeof (staging_area
))
9282 start
= curr
= staging_area
;
9286 start
= curr
= va_arg (ap
, const char *);
9293 || (*curr
== STYLE_MARKER_CHAR
9294 && ISXDIGIT (*(curr
+ 1))
9295 && *(curr
+ 2) == STYLE_MARKER_CHAR
))
9297 /* Output content between our START position and CURR. */
9298 int len
= curr
- start
;
9299 int n
= (*info
->fprintf_styled_func
) (info
->stream
, curr_style
,
9300 "%.*s", len
, start
);
9307 /* Skip over the initial STYLE_MARKER_CHAR. */
9310 /* Update the CURR_STYLE. As there are less than 16 styles, it
9311 is possible, that if the input is corrupted in some way, that
9312 we might set CURR_STYLE to an invalid value. Don't worry
9313 though, we check for this situation. */
9314 if (*curr
>= '0' && *curr
<= '9')
9315 curr_style
= (enum disassembler_style
) (*curr
- '0');
9316 else if (*curr
>= 'a' && *curr
<= 'f')
9317 curr_style
= (enum disassembler_style
) (*curr
- 'a' + 10);
9319 curr_style
= dis_style_text
;
9321 /* Check for an invalid style having been selected. This should
9322 never happen, but it doesn't hurt to be a little paranoid. */
9323 if (curr_style
> dis_style_comment_start
)
9324 curr_style
= dis_style_text
;
9326 /* Skip the hex character, and the closing STYLE_MARKER_CHAR. */
9329 /* Reset the START to after the style marker. */
9339 print_insn (bfd_vma pc
, disassemble_info
*info
, int intel_syntax
)
9341 const struct dis386
*dp
;
9344 char *op_txt
[MAX_OPERANDS
];
9346 bool intel_swap_2_3
;
9347 int sizeflag
, orig_sizeflag
;
9349 struct dis_private priv
;
9354 .intel_syntax
= intel_syntax
>= 0
9356 : (info
->mach
& bfd_mach_i386_intel_syntax
) != 0,
9357 .intel_mnemonic
= !SYSV386_COMPAT
,
9358 .op_index
[0 ... MAX_OPERANDS
- 1] = -1,
9360 .start_codep
= priv
.the_buffer
,
9361 .codep
= priv
.the_buffer
,
9363 .last_lock_prefix
= -1,
9364 .last_repz_prefix
= -1,
9365 .last_repnz_prefix
= -1,
9366 .last_data_prefix
= -1,
9367 .last_addr_prefix
= -1,
9368 .last_rex_prefix
= -1,
9369 .last_rex2_prefix
= -1,
9370 .last_seg_prefix
= -1,
9373 char op_out
[MAX_OPERANDS
][MAX_OPERAND_BUFFER_SIZE
];
9375 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
9376 if ((info
->mach
& bfd_mach_i386_i386
) != 0)
9377 ins
.address_mode
= mode_32bit
;
9378 else if (info
->mach
== bfd_mach_i386_i8086
)
9380 ins
.address_mode
= mode_16bit
;
9381 priv
.orig_sizeflag
= 0;
9384 ins
.address_mode
= mode_64bit
;
9386 for (p
= info
->disassembler_options
; p
!= NULL
;)
9388 if (startswith (p
, "amd64"))
9390 else if (startswith (p
, "intel64"))
9391 ins
.isa64
= intel64
;
9392 else if (startswith (p
, "x86-64"))
9394 ins
.address_mode
= mode_64bit
;
9395 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9397 else if (startswith (p
, "i386"))
9399 ins
.address_mode
= mode_32bit
;
9400 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9402 else if (startswith (p
, "i8086"))
9404 ins
.address_mode
= mode_16bit
;
9405 priv
.orig_sizeflag
&= ~(AFLAG
| DFLAG
);
9407 else if (startswith (p
, "intel"))
9409 if (startswith (p
+ 5, "-mnemonic"))
9410 ins
.intel_mnemonic
= true;
9412 ins
.intel_syntax
= 1;
9414 else if (startswith (p
, "att"))
9416 ins
.intel_syntax
= 0;
9417 if (startswith (p
+ 3, "-mnemonic"))
9418 ins
.intel_mnemonic
= false;
9420 else if (startswith (p
, "addr"))
9422 if (ins
.address_mode
== mode_64bit
)
9424 if (p
[4] == '3' && p
[5] == '2')
9425 priv
.orig_sizeflag
&= ~AFLAG
;
9426 else if (p
[4] == '6' && p
[5] == '4')
9427 priv
.orig_sizeflag
|= AFLAG
;
9431 if (p
[4] == '1' && p
[5] == '6')
9432 priv
.orig_sizeflag
&= ~AFLAG
;
9433 else if (p
[4] == '3' && p
[5] == '2')
9434 priv
.orig_sizeflag
|= AFLAG
;
9437 else if (startswith (p
, "data"))
9439 if (p
[4] == '1' && p
[5] == '6')
9440 priv
.orig_sizeflag
&= ~DFLAG
;
9441 else if (p
[4] == '3' && p
[5] == '2')
9442 priv
.orig_sizeflag
|= DFLAG
;
9444 else if (startswith (p
, "suffix"))
9445 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
9447 p
= strchr (p
, ',');
9452 if (ins
.address_mode
== mode_64bit
&& sizeof (bfd_vma
) < 8)
9454 i386_dis_printf (info
, dis_style_text
, _("64-bit address is disabled"));
9458 if (ins
.intel_syntax
)
9460 ins
.open_char
= '[';
9461 ins
.close_char
= ']';
9462 ins
.separator_char
= '+';
9463 ins
.scale_char
= '*';
9467 ins
.open_char
= '(';
9468 ins
.close_char
= ')';
9469 ins
.separator_char
= ',';
9470 ins
.scale_char
= ',';
9473 /* The output looks better if we put 7 bytes on a line, since that
9474 puts most long word instructions on a single line. */
9475 info
->bytes_per_line
= 7;
9477 info
->private_data
= &priv
;
9479 priv
.insn_start
= pc
;
9481 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9484 ins
.op_out
[i
] = op_out
[i
];
9487 sizeflag
= priv
.orig_sizeflag
;
9489 switch (ckprefix (&ins
))
9495 /* Too many prefixes or unused REX prefixes. */
9497 i
< (int) ARRAY_SIZE (ins
.all_prefixes
) && ins
.all_prefixes
[i
];
9499 i386_dis_printf (info
, dis_style_mnemonic
, "%s%s",
9500 (i
== 0 ? "" : " "),
9501 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9506 case ckp_fetch_error
:
9507 goto fetch_error_out
;
9510 ins
.nr_prefixes
= ins
.codep
- ins
.start_codep
;
9512 if (!fetch_code (info
, ins
.codep
+ 1))
9515 ret
= fetch_error (&ins
);
9519 ins
.two_source_ops
= (*ins
.codep
== 0x62 || *ins
.codep
== 0xc8);
9521 if ((ins
.prefixes
& PREFIX_FWAIT
)
9522 && (*ins
.codep
< 0xd8 || *ins
.codep
> 0xdf))
9524 /* Handle ins.prefixes before fwait. */
9525 for (i
= 0; i
< ins
.fwait_prefix
&& ins
.all_prefixes
[i
];
9527 i386_dis_printf (info
, dis_style_mnemonic
, "%s ",
9528 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9530 i386_dis_printf (info
, dis_style_mnemonic
, "fwait");
9535 /* REX2.M in rex2 prefix represents map0 or map1. */
9536 if (ins
.last_rex2_prefix
< 0 ? *ins
.codep
== 0x0f : (ins
.rex2
& REX2_M
))
9541 if (!fetch_code (info
, ins
.codep
+ 1))
9542 goto fetch_error_out
;
9545 dp
= &dis386_twobyte
[*ins
.codep
];
9546 ins
.need_modrm
= twobyte_has_modrm
[*ins
.codep
];
9550 dp
= &dis386
[*ins
.codep
];
9551 ins
.need_modrm
= onebyte_has_modrm
[*ins
.codep
];
9553 ins
.condition_code
= *ins
.codep
& 0xf;
9556 /* Save sizeflag for printing the extra ins.prefixes later before updating
9557 it for mnemonic and operand processing. The prefix names depend
9558 only on the address mode. */
9559 orig_sizeflag
= sizeflag
;
9560 if (ins
.prefixes
& PREFIX_ADDR
)
9562 if ((ins
.prefixes
& PREFIX_DATA
))
9565 ins
.end_codep
= ins
.codep
;
9566 if (ins
.need_modrm
&& !fetch_modrm (&ins
))
9567 goto fetch_error_out
;
9569 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
9571 if (!get_sib (&ins
, sizeflag
)
9572 || !dofloat (&ins
, sizeflag
))
9573 goto fetch_error_out
;
9577 dp
= get_valid_dis386 (dp
, &ins
);
9578 if (dp
== &err_opcode
)
9579 goto fetch_error_out
;
9581 /* For APX instructions promoted from legacy maps 0/1, embedded prefix
9582 is interpreted as the operand size override. */
9583 if (ins
.evex_type
== evex_from_legacy
9584 && ins
.vex
.prefix
== DATA_PREFIX_OPCODE
)
9587 if(ins
.evex_type
== evex_default
)
9590 /* For EVEX-promoted formats, we need to clear EVEX.NF (ccmp and ctest
9591 are cleared separately.) in mask_register_specifier and keep the low
9592 2 bits of mask_register_specifier to report errors for invalid cases
9594 ins
.vex
.mask_register_specifier
&= 0x3;
9596 if (dp
!= NULL
&& putop (&ins
, dp
->name
, sizeflag
) == 0)
9598 if (!get_sib (&ins
, sizeflag
))
9599 goto fetch_error_out
;
9600 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9602 ins
.obufp
= ins
.op_out
[i
];
9603 ins
.op_ad
= MAX_OPERANDS
- 1 - i
;
9605 && !dp
->op
[i
].rtn (&ins
, dp
->op
[i
].bytemode
, sizeflag
))
9606 goto fetch_error_out
;
9607 /* For EVEX instruction after the last operand masking
9608 should be printed. */
9609 if (i
== 0 && ins
.vex
.evex
)
9611 /* Don't print {%k0}. */
9612 if (ins
.vex
.mask_register_specifier
)
9614 const char *reg_name
9615 = att_names_mask
[ins
.vex
.mask_register_specifier
];
9617 oappend (&ins
, "{");
9618 oappend_register (&ins
, reg_name
);
9619 oappend (&ins
, "}");
9621 if (ins
.vex
.zeroing
)
9622 oappend (&ins
, "{z}");
9624 else if (ins
.vex
.zeroing
)
9626 oappend (&ins
, "{bad}");
9630 /* Instructions with a mask register destination allow for
9631 zeroing-masking only (if any masking at all), which is
9632 _not_ expressed by EVEX.z. */
9633 if (ins
.vex
.zeroing
&& dp
->op
[0].bytemode
== mask_mode
)
9634 ins
.illegal_masking
= true;
9636 /* S/G insns require a mask and don't allow
9638 if ((dp
->op
[0].bytemode
== vex_vsib_d_w_dq_mode
9639 || dp
->op
[0].bytemode
== vex_vsib_q_w_dq_mode
)
9640 && (ins
.vex
.mask_register_specifier
== 0
9641 || ins
.vex
.zeroing
))
9642 ins
.illegal_masking
= true;
9644 if (ins
.illegal_masking
)
9645 oappend (&ins
, "/(bad)");
9648 /* vex.nf is cleared after being consumed. */
9650 oappend (&ins
, "{bad-nf}");
9652 /* Check whether rounding control was enabled for an insn not
9653 supporting it, when evex.b is not treated as evex.nd. */
9654 if (ins
.modrm
.mod
== 3 && ins
.vex
.b
&& ins
.evex_type
== evex_default
9655 && !(ins
.evex_used
& EVEX_b_used
))
9657 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9659 ins
.obufp
= ins
.op_out
[i
];
9662 oappend (&ins
, names_rounding
[ins
.vex
.ll
]);
9663 oappend (&ins
, "bad}");
9670 /* Clear instruction information. */
9671 info
->insn_info_valid
= 0;
9672 info
->branch_delay_insns
= 0;
9673 info
->data_size
= 0;
9674 info
->insn_type
= dis_noninsn
;
9678 /* Reset jump operation indicator. */
9679 ins
.op_is_jump
= false;
9681 int jump_detection
= 0;
9683 /* Extract flags. */
9684 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9686 if ((dp
->op
[i
].rtn
== OP_J
)
9687 || (dp
->op
[i
].rtn
== OP_indirE
))
9688 jump_detection
|= 1;
9689 else if ((dp
->op
[i
].rtn
== BND_Fixup
)
9690 || (!dp
->op
[i
].rtn
&& !dp
->op
[i
].bytemode
))
9691 jump_detection
|= 2;
9692 else if ((dp
->op
[i
].bytemode
== cond_jump_mode
)
9693 || (dp
->op
[i
].bytemode
== loop_jcxz_mode
))
9694 jump_detection
|= 4;
9697 /* Determine if this is a jump or branch. */
9698 if ((jump_detection
& 0x3) == 0x3)
9700 ins
.op_is_jump
= true;
9701 if (jump_detection
& 0x4)
9702 info
->insn_type
= dis_condbranch
;
9704 info
->insn_type
= (dp
->name
&& !strncmp (dp
->name
, "call", 4))
9705 ? dis_jsr
: dis_branch
;
9708 /* The purpose of placing the check here is to wait for the EVEX prefix for
9709 conditional CMP and TEST to be consumed and cleared, and then make a
9710 unified judgment. Because they are both in map4, we can not distinguish
9711 EVEX prefix for conditional CMP and TEST from others during the
9712 EVEX prefix stage of parsing. */
9713 if (ins
.evex_type
== evex_from_legacy
)
9715 /* EVEX from legacy instructions, when the EVEX.ND bit is 0,
9716 all bits of EVEX.vvvv and EVEX.V' must be 1. */
9717 if (!ins
.vex
.nd
&& (ins
.vex
.register_specifier
|| !ins
.vex
.v
))
9719 i386_dis_printf (info
, dis_style_text
, "(bad)");
9720 ret
= ins
.end_codep
- priv
.the_buffer
;
9724 /* EVEX from legacy instructions require that EVEX.z, EVEX.L’L and the
9725 lower 2 bits of EVEX.aaa must be 0. */
9726 if ((ins
.vex
.mask_register_specifier
& 0x3) != 0
9727 || ins
.vex
.ll
!= 0 || ins
.vex
.zeroing
!= 0)
9729 i386_dis_printf (info
, dis_style_text
, "(bad)");
9730 ret
= ins
.end_codep
- priv
.the_buffer
;
9734 /* If VEX.vvvv and EVEX.vvvv are unused, they must be all 1s, which
9735 are all 0s in inverted form. */
9736 if (ins
.need_vex
&& ins
.vex
.register_specifier
!= 0)
9738 i386_dis_printf (info
, dis_style_text
, "(bad)");
9739 ret
= ins
.end_codep
- priv
.the_buffer
;
9743 if ((dp
->prefix_requirement
& PREFIX_REX2_ILLEGAL
)
9744 && ins
.last_rex2_prefix
>= 0 && (ins
.rex2
& REX2_SPECIAL
) == 0)
9746 i386_dis_printf (info
, dis_style_text
, "(bad)");
9747 ret
= ins
.end_codep
- priv
.the_buffer
;
9751 switch (dp
->prefix_requirement
& ~PREFIX_REX2_ILLEGAL
)
9754 /* If only the data prefix is marked as mandatory, its absence renders
9755 the encoding invalid. Most other PREFIX_OPCODE rules still apply. */
9756 if (ins
.need_vex
? !ins
.vex
.prefix
: !(ins
.prefixes
& PREFIX_DATA
))
9758 i386_dis_printf (info
, dis_style_text
, "(bad)");
9759 ret
= ins
.end_codep
- priv
.the_buffer
;
9762 ins
.used_prefixes
|= PREFIX_DATA
;
9765 /* If the mandatory PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is
9766 unused, opcode is invalid. Since the PREFIX_DATA prefix may be
9767 used by putop and MMX/SSE operand and may be overridden by the
9768 PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
9771 ? ins
.vex
.prefix
== REPE_PREFIX_OPCODE
9772 || ins
.vex
.prefix
== REPNE_PREFIX_OPCODE
9774 & (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
9775 && (ins
.used_prefixes
9776 & (PREFIX_REPZ
| PREFIX_REPNZ
)) == 0)
9778 ? ins
.vex
.prefix
== DATA_PREFIX_OPCODE
9780 & (PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
))
9782 && (ins
.used_prefixes
& PREFIX_DATA
) == 0))
9783 || (ins
.vex
.evex
&& dp
->prefix_requirement
!= PREFIX_DATA
9784 && !ins
.vex
.w
!= !(ins
.used_prefixes
& PREFIX_DATA
)))
9786 i386_dis_printf (info
, dis_style_text
, "(bad)");
9787 ret
= ins
.end_codep
- priv
.the_buffer
;
9792 case PREFIX_IGNORED
:
9793 /* Zap data size and rep prefixes from used_prefixes and reinstate their
9794 origins in all_prefixes. */
9795 ins
.used_prefixes
&= ~PREFIX_OPCODE
;
9796 if (ins
.last_data_prefix
>= 0)
9797 ins
.all_prefixes
[ins
.last_data_prefix
] = 0x66;
9798 if (ins
.last_repz_prefix
>= 0)
9799 ins
.all_prefixes
[ins
.last_repz_prefix
] = 0xf3;
9800 if (ins
.last_repnz_prefix
>= 0)
9801 ins
.all_prefixes
[ins
.last_repnz_prefix
] = 0xf2;
9804 case PREFIX_NP_OR_DATA
:
9805 if (ins
.vex
.prefix
== REPE_PREFIX_OPCODE
9806 || ins
.vex
.prefix
== REPNE_PREFIX_OPCODE
)
9808 i386_dis_printf (info
, dis_style_text
, "(bad)");
9809 ret
= ins
.end_codep
- priv
.the_buffer
;
9817 i386_dis_printf (info
, dis_style_text
, "(bad)");
9818 ret
= ins
.end_codep
- priv
.the_buffer
;
9824 /* Check if the REX prefix is used. */
9825 if ((ins
.rex
^ ins
.rex_used
) == 0
9826 && !ins
.need_vex
&& ins
.last_rex_prefix
>= 0)
9827 ins
.all_prefixes
[ins
.last_rex_prefix
] = 0;
9829 /* Check if the REX2 prefix is used. */
9830 if (ins
.last_rex2_prefix
>= 0
9831 && ((ins
.rex2
& REX2_SPECIAL
)
9832 || (((ins
.rex2
& 7) ^ (ins
.rex2_used
& 7)) == 0
9833 && (ins
.rex
^ ins
.rex_used
) == 0
9834 && (ins
.rex2
& 7))))
9835 ins
.all_prefixes
[ins
.last_rex2_prefix
] = 0;
9837 /* Check if the SEG prefix is used. */
9838 if ((ins
.prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
| PREFIX_ES
9839 | PREFIX_FS
| PREFIX_GS
)) != 0
9840 && (ins
.used_prefixes
& ins
.active_seg_prefix
) != 0)
9841 ins
.all_prefixes
[ins
.last_seg_prefix
] = 0;
9843 /* Check if the ADDR prefix is used. */
9844 if ((ins
.prefixes
& PREFIX_ADDR
) != 0
9845 && (ins
.used_prefixes
& PREFIX_ADDR
) != 0)
9846 ins
.all_prefixes
[ins
.last_addr_prefix
] = 0;
9848 /* Check if the DATA prefix is used. */
9849 if ((ins
.prefixes
& PREFIX_DATA
) != 0
9850 && (ins
.used_prefixes
& PREFIX_DATA
) != 0
9852 ins
.all_prefixes
[ins
.last_data_prefix
] = 0;
9854 /* Print the extra ins.prefixes. */
9856 for (i
= 0; i
< (int) ARRAY_SIZE (ins
.all_prefixes
); i
++)
9857 if (ins
.all_prefixes
[i
])
9859 const char *name
= prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9864 prefix_length
+= strlen (name
) + 1;
9865 if (ins
.all_prefixes
[i
] == REX2_OPCODE
)
9866 i386_dis_printf (info
, dis_style_mnemonic
, "{%s 0x%x} ", name
,
9867 (unsigned int) ins
.rex2_payload
);
9869 i386_dis_printf (info
, dis_style_mnemonic
, "%s ", name
);
9872 /* Check maximum code length. */
9873 if ((ins
.codep
- ins
.start_codep
) > MAX_CODE_LENGTH
)
9875 i386_dis_printf (info
, dis_style_text
, "(bad)");
9876 ret
= MAX_CODE_LENGTH
;
9880 /* Calculate the number of operands this instruction has. */
9882 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9883 if (*ins
.op_out
[i
] != '\0')
9886 /* Calculate the number of spaces to print after the mnemonic. */
9887 ins
.obufp
= ins
.mnemonicendp
;
9890 i
= strlen (ins
.obuf
) + prefix_length
;
9899 /* Print the instruction mnemonic along with any trailing whitespace. */
9900 i386_dis_printf (info
, dis_style_mnemonic
, "%s%*s", ins
.obuf
, i
, "");
9902 /* The enter and bound instructions are printed with operands in the same
9903 order as the intel book; everything else is printed in reverse order. */
9904 intel_swap_2_3
= false;
9905 if (ins
.intel_syntax
|| ins
.two_source_ops
)
9907 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9908 op_txt
[i
] = ins
.op_out
[i
];
9910 if (ins
.intel_syntax
&& dp
&& dp
->op
[2].rtn
== OP_Rounding
9911 && dp
->op
[3].rtn
== OP_E
&& dp
->op
[4].rtn
== NULL
)
9913 op_txt
[2] = ins
.op_out
[3];
9914 op_txt
[3] = ins
.op_out
[2];
9915 intel_swap_2_3
= true;
9918 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
9922 ins
.op_ad
= ins
.op_index
[i
];
9923 ins
.op_index
[i
] = ins
.op_index
[MAX_OPERANDS
- 1 - i
];
9924 ins
.op_index
[MAX_OPERANDS
- 1 - i
] = ins
.op_ad
;
9925 riprel
= ins
.op_riprel
[i
];
9926 ins
.op_riprel
[i
] = ins
.op_riprel
[MAX_OPERANDS
- 1 - i
];
9927 ins
.op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
9932 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9933 op_txt
[MAX_OPERANDS
- 1 - i
] = ins
.op_out
[i
];
9937 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9940 /* In Intel syntax embedded rounding / SAE are not separate operands.
9941 Instead they're attached to the prior register operand. Simply
9942 suppress emission of the comma to achieve that effect. */
9943 switch (i
& -(ins
.intel_syntax
&& dp
))
9946 if (dp
->op
[2].rtn
== OP_Rounding
&& !intel_swap_2_3
)
9950 if (dp
->op
[3].rtn
== OP_Rounding
|| intel_swap_2_3
)
9955 i386_dis_printf (info
, dis_style_text
, ",");
9956 if (ins
.op_index
[i
] != -1 && !ins
.op_riprel
[i
])
9958 bfd_vma target
= (bfd_vma
) ins
.op_address
[ins
.op_index
[i
]];
9962 info
->insn_info_valid
= 1;
9963 info
->branch_delay_insns
= 0;
9964 info
->data_size
= 0;
9965 info
->target
= target
;
9968 (*info
->print_address_func
) (target
, info
);
9971 i386_dis_printf (info
, dis_style_text
, "%s", op_txt
[i
]);
9975 for (i
= 0; i
< MAX_OPERANDS
; i
++)
9976 if (ins
.op_index
[i
] != -1 && ins
.op_riprel
[i
])
9978 i386_dis_printf (info
, dis_style_comment_start
, " # ");
9979 (*info
->print_address_func
)
9980 ((bfd_vma
)(ins
.start_pc
+ (ins
.codep
- ins
.start_codep
)
9981 + ins
.op_address
[ins
.op_index
[i
]]),
9985 ret
= ins
.codep
- priv
.the_buffer
;
9987 info
->private_data
= NULL
;
9991 /* Here for backwards compatibility. When gdb stops using
9992 print_insn_i386_att and print_insn_i386_intel these functions can
9993 disappear, and print_insn_i386 be merged into print_insn. */
9995 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
9997 return print_insn (pc
, info
, 0);
10001 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
10003 return print_insn (pc
, info
, 1);
10007 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
10009 return print_insn (pc
, info
, -1);
10012 static const char *float_mem
[] = {
10087 static const unsigned char float_mem_mode
[] = {
10162 #define ST { OP_ST, 0 }
10163 #define STi { OP_STi, 0 }
10165 #define FGRPd9_2 NULL, { { NULL, 1 } }, 0
10166 #define FGRPd9_4 NULL, { { NULL, 2 } }, 0
10167 #define FGRPd9_5 NULL, { { NULL, 3 } }, 0
10168 #define FGRPd9_6 NULL, { { NULL, 4 } }, 0
10169 #define FGRPd9_7 NULL, { { NULL, 5 } }, 0
10170 #define FGRPda_5 NULL, { { NULL, 6 } }, 0
10171 #define FGRPdb_4 NULL, { { NULL, 7 } }, 0
10172 #define FGRPde_3 NULL, { { NULL, 8 } }, 0
10173 #define FGRPdf_4 NULL, { { NULL, 9 } }, 0
10175 static const struct dis386 float_reg
[][8] = {
10178 { "fadd", { ST
, STi
}, 0 },
10179 { "fmul", { ST
, STi
}, 0 },
10180 { "fcom", { STi
}, 0 },
10181 { "fcomp", { STi
}, 0 },
10182 { "fsub", { ST
, STi
}, 0 },
10183 { "fsubr", { ST
, STi
}, 0 },
10184 { "fdiv", { ST
, STi
}, 0 },
10185 { "fdivr", { ST
, STi
}, 0 },
10189 { "fld", { STi
}, 0 },
10190 { "fxch", { STi
}, 0 },
10200 { "fcmovb", { ST
, STi
}, 0 },
10201 { "fcmove", { ST
, STi
}, 0 },
10202 { "fcmovbe",{ ST
, STi
}, 0 },
10203 { "fcmovu", { ST
, STi
}, 0 },
10211 { "fcmovnb",{ ST
, STi
}, 0 },
10212 { "fcmovne",{ ST
, STi
}, 0 },
10213 { "fcmovnbe",{ ST
, STi
}, 0 },
10214 { "fcmovnu",{ ST
, STi
}, 0 },
10216 { "fucomi", { ST
, STi
}, 0 },
10217 { "fcomi", { ST
, STi
}, 0 },
10222 { "fadd", { STi
, ST
}, 0 },
10223 { "fmul", { STi
, ST
}, 0 },
10226 { "fsub{!M|r}", { STi
, ST
}, 0 },
10227 { "fsub{M|}", { STi
, ST
}, 0 },
10228 { "fdiv{!M|r}", { STi
, ST
}, 0 },
10229 { "fdiv{M|}", { STi
, ST
}, 0 },
10233 { "ffree", { STi
}, 0 },
10235 { "fst", { STi
}, 0 },
10236 { "fstp", { STi
}, 0 },
10237 { "fucom", { STi
}, 0 },
10238 { "fucomp", { STi
}, 0 },
10244 { "faddp", { STi
, ST
}, 0 },
10245 { "fmulp", { STi
, ST
}, 0 },
10248 { "fsub{!M|r}p", { STi
, ST
}, 0 },
10249 { "fsub{M|}p", { STi
, ST
}, 0 },
10250 { "fdiv{!M|r}p", { STi
, ST
}, 0 },
10251 { "fdiv{M|}p", { STi
, ST
}, 0 },
10255 { "ffreep", { STi
}, 0 },
10260 { "fucomip", { ST
, STi
}, 0 },
10261 { "fcomip", { ST
, STi
}, 0 },
10266 static const char *const fgrps
[][8] = {
10269 "(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10274 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10279 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
10284 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
10289 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
10294 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
10299 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10304 "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
10305 "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
10310 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10315 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10319 static const char *const oszc_flags
[16] = {
10320 " {dfv=}", " {dfv=cf}", " {dfv=zf}", " {dfv=zf, cf}", " {dfv=sf}",
10321 " {dfv=sf, cf}", " {dfv=sf, zf}", " {dfv=sf, zf, cf}", " {dfv=of}",
10322 " {dfv=of, cf}", " {dfv=of, zf}", " {dfv=of, zf, cf}", " {dfv=of, sf}",
10323 " {dfv=of, sf, cf}", " {dfv=of, sf, zf}", " {dfv=of, sf, zf, cf}"
10326 static const char *const scc_suffix
[16] = {
10327 "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "t", "f",
10328 "l", "ge", "le", "g"
10332 swap_operand (instr_info
*ins
)
10334 char *p
= ins
->mnemonicendp
;
10338 while (*--p
!= '{')
10340 if (p
<= ins
->obuf
+ 2)
10346 memmove (p
+ 2, p
, ins
->mnemonicendp
- p
+ 1);
10349 ins
->mnemonicendp
+= 2;
10353 dofloat (instr_info
*ins
, int sizeflag
)
10355 const struct dis386
*dp
;
10356 unsigned char floatop
= ins
->codep
[-1];
10358 if (ins
->modrm
.mod
!= 3)
10360 int fp_indx
= (floatop
- 0xd8) * 8 + ins
->modrm
.reg
;
10362 putop (ins
, float_mem
[fp_indx
], sizeflag
);
10363 ins
->obufp
= ins
->op_out
[0];
10365 return OP_E (ins
, float_mem_mode
[fp_indx
], sizeflag
);
10367 /* Skip mod/rm byte. */
10371 dp
= &float_reg
[floatop
- 0xd8][ins
->modrm
.reg
];
10372 if (dp
->name
== NULL
)
10374 putop (ins
, fgrps
[dp
->op
[0].bytemode
][ins
->modrm
.rm
], sizeflag
);
10376 /* Instruction fnstsw is only one with strange arg. */
10377 if (floatop
== 0xdf && ins
->codep
[-1] == 0xe0)
10378 strcpy (ins
->op_out
[0], att_names16
[0] + ins
->intel_syntax
);
10382 putop (ins
, dp
->name
, sizeflag
);
10384 ins
->obufp
= ins
->op_out
[0];
10387 && !dp
->op
[0].rtn (ins
, dp
->op
[0].bytemode
, sizeflag
))
10390 ins
->obufp
= ins
->op_out
[1];
10393 && !dp
->op
[1].rtn (ins
, dp
->op
[1].bytemode
, sizeflag
))
10400 OP_ST (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10401 int sizeflag ATTRIBUTE_UNUSED
)
10403 oappend_register (ins
, "%st");
10408 OP_STi (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10409 int sizeflag ATTRIBUTE_UNUSED
)
10412 int res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%st(%d)", ins
->modrm
.rm
);
10414 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
10416 oappend_register (ins
, scratch
);
10420 /* Capital letters in template are macros. */
10422 putop (instr_info
*ins
, const char *in_template
, int sizeflag
)
10427 unsigned int l
= 0, len
= 0;
10429 bool evex_printed
= false;
10431 /* We don't want to add any prefix or suffix to (bad), so return early. */
10432 if (!strncmp (in_template
, "(bad)", 5))
10434 oappend (ins
, "(bad)");
10436 ins
->mnemonicendp
= ins
->obufp
;
10440 for (p
= in_template
; *p
; p
++)
10444 if (l
>= sizeof (last
) || !ISUPPER (*p
))
10452 if (ins
->evex_type
== evex_from_legacy
&& !ins
->vex
.nd
10453 && !(ins
->rex2
& 7) && !evex_printed
)
10455 oappend (ins
, "{evex} ");
10456 evex_printed
= true;
10458 *ins
->obufp
++ = *p
;
10467 if (ins
->intel_syntax
)
10469 while (*++p
!= '|')
10470 if (*p
== '}' || *p
== '\0')
10476 while (*++p
!= '}')
10486 if (ins
->intel_syntax
)
10488 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3 && !ins
->vex
.nd
)
10489 || (sizeflag
& SUFFIX_ALWAYS
))
10490 *ins
->obufp
++ = 'b';
10496 if (ins
->intel_syntax
)
10498 if (sizeflag
& SUFFIX_ALWAYS
)
10499 *ins
->obufp
++ = 'b';
10501 else if (l
== 1 && last
[0] == 'L')
10503 if (ins
->address_mode
== mode_64bit
10504 && !(ins
->prefixes
& PREFIX_ADDR
))
10506 *ins
->obufp
++ = 'a';
10507 *ins
->obufp
++ = 'b';
10508 *ins
->obufp
++ = 's';
10517 if (l
== 1 && last
[0] == 'C')
10519 /* Condition code (taken from the map-0 Jcc entries). */
10520 for (const char *q
= dis386
[0x70 | ins
->condition_code
].name
+ 1;
10522 *ins
->obufp
++ = *q
;
10525 else if (l
== 1 && last
[0] == 'S')
10527 /* Add scc suffix. */
10528 oappend (ins
, scc_suffix
[ins
->vex
.scc
]);
10530 /* For SCC insns, the ND bit is required to be set to 0. */
10532 oappend (ins
, "(bad)");
10534 /* These bits have been consumed and should be cleared or restored
10535 to default values. */
10537 ins
->vex
.nf
= false;
10538 ins
->vex
.mask_register_specifier
= 0;
10544 if (ins
->intel_syntax
&& !alt
)
10546 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
10548 if (sizeflag
& DFLAG
)
10549 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10551 *ins
->obufp
++ = ins
->intel_syntax
? 'w' : 's';
10552 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10561 if (!ins
->vex
.evex
|| ins
->vex
.w
)
10562 *ins
->obufp
++ = 'd';
10564 oappend (ins
, "{bad}");
10573 if (ins
->intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
10576 if (ins
->modrm
.mod
== 3)
10578 if (ins
->rex
& REX_W
)
10579 *ins
->obufp
++ = 'q';
10582 if (sizeflag
& DFLAG
)
10583 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10585 *ins
->obufp
++ = 'w';
10586 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10590 *ins
->obufp
++ = 'w';
10598 if (!ins
->vex
.evex
|| ins
->vex
.b
|| ins
->vex
.ll
>= 2
10600 || (ins
->modrm
.mod
== 3 && (ins
->rex
& REX_X
))
10601 || !ins
->vex
.v
|| ins
->vex
.mask_register_specifier
)
10603 /* AVX512 extends a number of V*D insns to also have V*Q variants,
10604 merely distinguished by EVEX.W. Look for a use of the
10605 respective macro. */
10608 const char *pct
= strchr (p
+ 1, '%');
10610 if (pct
!= NULL
&& pct
[1] == 'D' && pct
[2] == 'Q')
10613 *ins
->obufp
++ = '{';
10614 *ins
->obufp
++ = 'e';
10615 *ins
->obufp
++ = 'v';
10616 *ins
->obufp
++ = 'e';
10617 *ins
->obufp
++ = 'x';
10618 *ins
->obufp
++ = '}';
10619 *ins
->obufp
++ = ' ';
10622 /* Skip printing {evex} for some special instructions in MAP4. */
10623 evex_printed
= true;
10630 /* For jcxz/jecxz */
10631 if (ins
->address_mode
== mode_64bit
)
10633 if (sizeflag
& AFLAG
)
10634 *ins
->obufp
++ = 'r';
10636 *ins
->obufp
++ = 'e';
10639 if (sizeflag
& AFLAG
)
10640 *ins
->obufp
++ = 'e';
10641 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
10646 if (ins
->intel_syntax
)
10648 if ((ins
->prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
10650 if (sizeflag
& AFLAG
)
10651 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
10653 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'l' : 'w';
10654 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
10657 else if (l
== 1 && last
[0] == 'C')
10659 if (ins
->vex
.nd
&& !ins
->vex
.nf
)
10661 *ins
->obufp
++ = 'c';
10662 *ins
->obufp
++ = 'f';
10663 /* Skip printing {evex} */
10664 evex_printed
= true;
10666 else if (l
== 1 && last
[0] == 'N')
10670 oappend (ins
, "{nf} ");
10671 /* This bit needs to be cleared after it is consumed. */
10672 ins
->vex
.nf
= false;
10673 evex_printed
= true;
10675 else if (ins
->evex_type
== evex_from_vex
&& !(ins
->rex2
& 7)
10678 oappend (ins
, "{evex} ");
10679 evex_printed
= true;
10682 else if (l
== 1 && last
[0] == 'D')
10684 /* Get oszc flags value from register_specifier. */
10685 int oszc_value
= ~ins
->vex
.register_specifier
& 0xf;
10687 /* Add {dfv=of, sf, zf, cf} flags. */
10688 oappend (ins
, oszc_flags
[oszc_value
]);
10690 /* These bits have been consumed and should be cleared. */
10691 ins
->vex
.register_specifier
= 0;
10697 if (ins
->intel_syntax
|| (ins
->obufp
[-1] != 's'
10698 && !(sizeflag
& SUFFIX_ALWAYS
)))
10700 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
10701 *ins
->obufp
++ = 'l';
10703 *ins
->obufp
++ = 'w';
10704 if (!(ins
->rex
& REX_W
))
10705 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10710 if (ins
->intel_syntax
)
10712 if ((ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
10713 || (ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
10715 ins
->used_prefixes
|= ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
);
10716 *ins
->obufp
++ = ',';
10717 *ins
->obufp
++ = 'p';
10719 /* Set active_seg_prefix even if not set in 64-bit mode
10720 because here it is a valid branch hint. */
10721 if (ins
->prefixes
& PREFIX_DS
)
10723 ins
->active_seg_prefix
= PREFIX_DS
;
10724 *ins
->obufp
++ = 't';
10728 ins
->active_seg_prefix
= PREFIX_CS
;
10729 *ins
->obufp
++ = 'n';
10733 else if (l
== 1 && last
[0] == 'X')
10736 *ins
->obufp
++ = 'h';
10738 oappend (ins
, "{bad}");
10745 if (ins
->rex
& REX_W
)
10746 *ins
->obufp
++ = 'q';
10748 *ins
->obufp
++ = 'd';
10751 if (ins
->intel_syntax
)
10753 if (sizeflag
& SUFFIX_ALWAYS
)
10755 if (ins
->rex
& REX_W
)
10756 *ins
->obufp
++ = 'q';
10758 *ins
->obufp
++ = 'l';
10762 if (ins
->intel_mnemonic
!= cond
)
10763 *ins
->obufp
++ = 'r';
10766 if ((ins
->prefixes
& PREFIX_FWAIT
) == 0)
10767 *ins
->obufp
++ = 'n';
10769 ins
->used_prefixes
|= PREFIX_FWAIT
;
10773 if (ins
->rex
& REX_W
)
10774 *ins
->obufp
++ = 'o';
10775 else if (ins
->intel_syntax
&& (sizeflag
& DFLAG
))
10776 *ins
->obufp
++ = 'q';
10778 *ins
->obufp
++ = 'd';
10779 if (!(ins
->rex
& REX_W
))
10780 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10783 if (ins
->address_mode
== mode_64bit
10784 && (ins
->isa64
== intel64
|| (ins
->rex
& REX_W
)
10785 || !(ins
->prefixes
& PREFIX_DATA
)))
10787 if (sizeflag
& SUFFIX_ALWAYS
)
10788 *ins
->obufp
++ = 'q';
10791 /* Fall through. */
10795 if (!cond
&& ins
->last_rex2_prefix
>= 0 && (ins
->rex
& REX_W
))
10797 /* For pushp and popp, p is printed and do not print {rex2}
10799 *ins
->obufp
++ = 'p';
10800 ins
->rex2
|= REX2_SPECIAL
;
10804 /* For "!P" print nothing else in Intel syntax. */
10805 if (!cond
&& ins
->intel_syntax
)
10808 if ((ins
->modrm
.mod
== 3 || !cond
)
10809 && !(sizeflag
& SUFFIX_ALWAYS
))
10811 /* Fall through. */
10813 if ((!(ins
->rex
& REX_W
) && (ins
->prefixes
& PREFIX_DATA
))
10814 || ((sizeflag
& SUFFIX_ALWAYS
)
10815 && ins
->address_mode
!= mode_64bit
))
10817 *ins
->obufp
++ = (sizeflag
& DFLAG
)
10818 ? ins
->intel_syntax
? 'd' : 'l' : 'w';
10819 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10821 else if (sizeflag
& SUFFIX_ALWAYS
)
10822 *ins
->obufp
++ = 'q';
10824 else if (l
== 1 && last
[0] == 'L')
10826 if ((ins
->prefixes
& PREFIX_DATA
)
10827 || (ins
->rex
& REX_W
)
10828 || (sizeflag
& SUFFIX_ALWAYS
))
10831 if (ins
->rex
& REX_W
)
10832 *ins
->obufp
++ = 'q';
10835 if (sizeflag
& DFLAG
)
10836 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10838 *ins
->obufp
++ = 'w';
10839 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10849 if (ins
->intel_syntax
&& !alt
)
10852 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3 && !ins
->vex
.nd
)
10853 || (sizeflag
& SUFFIX_ALWAYS
))
10855 if (ins
->rex
& REX_W
)
10856 *ins
->obufp
++ = 'q';
10859 if (sizeflag
& DFLAG
)
10860 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10862 *ins
->obufp
++ = 'w';
10863 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10867 else if (l
== 1 && last
[0] == 'D')
10868 *ins
->obufp
++ = ins
->vex
.w
? 'q' : 'd';
10869 else if (l
== 1 && last
[0] == 'L')
10871 if (cond
? ins
->modrm
.mod
== 3 && !(sizeflag
& SUFFIX_ALWAYS
)
10872 : ins
->address_mode
!= mode_64bit
)
10874 if ((ins
->rex
& REX_W
))
10877 *ins
->obufp
++ = 'q';
10879 else if ((ins
->address_mode
== mode_64bit
&& cond
)
10880 || (sizeflag
& SUFFIX_ALWAYS
))
10881 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10888 if (ins
->rex
& REX_W
)
10889 *ins
->obufp
++ = 'q';
10890 else if (sizeflag
& DFLAG
)
10892 if (ins
->intel_syntax
)
10893 *ins
->obufp
++ = 'd';
10895 *ins
->obufp
++ = 'l';
10898 *ins
->obufp
++ = 'w';
10899 if (ins
->intel_syntax
&& !p
[1]
10900 && ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
)))
10901 *ins
->obufp
++ = 'e';
10902 if (!(ins
->rex
& REX_W
))
10903 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10909 if (ins
->intel_syntax
)
10911 if (sizeflag
& SUFFIX_ALWAYS
)
10913 if (ins
->rex
& REX_W
)
10914 *ins
->obufp
++ = 'q';
10917 if (sizeflag
& DFLAG
)
10918 *ins
->obufp
++ = 'l';
10920 *ins
->obufp
++ = 'w';
10921 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10931 if (ins
->address_mode
== mode_64bit
10932 && !(ins
->prefixes
& PREFIX_ADDR
))
10934 *ins
->obufp
++ = 'a';
10935 *ins
->obufp
++ = 'b';
10936 *ins
->obufp
++ = 's';
10941 if (!ins
->vex
.evex
|| !ins
->vex
.w
)
10942 *ins
->obufp
++ = 's';
10944 oappend (ins
, "{bad}");
10951 if (l
== 1 && (last
[0] == 'Z'))
10953 /* Although IMUL/SETcc does not support NDD, the EVEX.ND bit is
10954 used to control whether its destination register has its upper
10957 oappend (ins
, "zu");
10966 *ins
->obufp
++ = 'v';
10975 *ins
->obufp
++ = '{';
10976 *ins
->obufp
++ = 'v';
10977 *ins
->obufp
++ = 'e';
10978 *ins
->obufp
++ = 'x';
10979 *ins
->obufp
++ = '}';
10980 *ins
->obufp
++ = ' ';
10983 if (ins
->rex
& REX_W
)
10985 *ins
->obufp
++ = 'a';
10986 *ins
->obufp
++ = 'b';
10987 *ins
->obufp
++ = 's';
11000 /* operand size flag for cwtl, cbtw */
11002 if (ins
->rex
& REX_W
)
11004 if (ins
->intel_syntax
)
11005 *ins
->obufp
++ = 'd';
11007 *ins
->obufp
++ = 'l';
11009 else if (sizeflag
& DFLAG
)
11010 *ins
->obufp
++ = 'w';
11012 *ins
->obufp
++ = 'b';
11013 if (!(ins
->rex
& REX_W
))
11014 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11018 if (!ins
->need_vex
)
11020 if (last
[0] == 'X')
11021 *ins
->obufp
++ = ins
->vex
.w
? 'd': 's';
11022 else if (last
[0] == 'B')
11023 *ins
->obufp
++ = ins
->vex
.w
? 'w': 'b';
11034 ? ins
->vex
.prefix
== DATA_PREFIX_OPCODE
11035 : ins
->prefixes
& PREFIX_DATA
)
11037 *ins
->obufp
++ = 'd';
11038 ins
->used_prefixes
|= PREFIX_DATA
;
11041 *ins
->obufp
++ = 's';
11046 if (ins
->vex
.mask_register_specifier
)
11047 ins
->illegal_masking
= true;
11049 else if (l
== 1 && last
[0] == 'X')
11051 if (!ins
->need_vex
)
11053 if (ins
->intel_syntax
11054 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
11055 && !(sizeflag
& SUFFIX_ALWAYS
)))
11057 switch (ins
->vex
.length
)
11060 *ins
->obufp
++ = 'x';
11063 *ins
->obufp
++ = 'y';
11066 if (!ins
->vex
.evex
)
11077 /* These insns ignore ModR/M.mod: Force it to 3 for OP_E(). */
11078 ins
->modrm
.mod
= 3;
11079 if (!ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
11080 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
11082 else if (l
== 1 && last
[0] == 'X')
11084 if (!ins
->vex
.evex
)
11086 if (ins
->intel_syntax
11087 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
11088 && !(sizeflag
& SUFFIX_ALWAYS
)))
11090 switch (ins
->vex
.length
)
11093 *ins
->obufp
++ = 'x';
11096 *ins
->obufp
++ = 'y';
11099 *ins
->obufp
++ = 'z';
11109 if (ins
->intel_syntax
)
11111 if (ins
->isa64
== intel64
&& (ins
->rex
& REX_W
))
11114 *ins
->obufp
++ = 'q';
11117 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
11119 if (sizeflag
& DFLAG
)
11120 *ins
->obufp
++ = 'l';
11122 *ins
->obufp
++ = 'w';
11123 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11132 ins
->mnemonicendp
= ins
->obufp
;
11136 /* Add a style marker to *INS->obufp that encodes STYLE. This assumes that
11137 the buffer pointed to by INS->obufp has space. A style marker is made
11138 from the STYLE_MARKER_CHAR followed by STYLE converted to a single hex
11139 digit, followed by another STYLE_MARKER_CHAR. This function assumes
11140 that the number of styles is not greater than 16. */
11143 oappend_insert_style (instr_info
*ins
, enum disassembler_style style
)
11145 unsigned num
= (unsigned) style
;
11147 /* We currently assume that STYLE can be encoded as a single hex
11148 character. If more styles are added then this might start to fail,
11149 and we'll need to expand this code. */
11153 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
11154 *ins
->obufp
++ = (num
< 10 ? ('0' + num
)
11155 : ((num
< 16) ? ('a' + (num
- 10)) : '0'));
11156 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
11158 /* This final null character is not strictly necessary, after inserting a
11159 style marker we should always be inserting some additional content.
11160 However, having the buffer null terminated doesn't cost much, and make
11161 it easier to debug what's going on. Also, if we do ever forget to add
11162 any additional content after this style marker, then the buffer will
11163 still be well formed. */
11164 *ins
->obufp
= '\0';
11168 oappend_with_style (instr_info
*ins
, const char *s
,
11169 enum disassembler_style style
)
11171 oappend_insert_style (ins
, style
);
11172 ins
->obufp
= stpcpy (ins
->obufp
, s
);
11175 /* Add a single character C to the buffer pointer to by INS->obufp, marking
11176 the style for the character as STYLE. */
11179 oappend_char_with_style (instr_info
*ins
, const char c
,
11180 enum disassembler_style style
)
11182 oappend_insert_style (ins
, style
);
11184 *ins
->obufp
= '\0';
11187 /* Like oappend_char_with_style, but always uses dis_style_text. */
11190 oappend_char (instr_info
*ins
, const char c
)
11192 oappend_char_with_style (ins
, c
, dis_style_text
);
11196 append_seg (instr_info
*ins
)
11198 /* Only print the active segment register. */
11199 if (!ins
->active_seg_prefix
)
11202 ins
->used_prefixes
|= ins
->active_seg_prefix
;
11203 switch (ins
->active_seg_prefix
)
11206 oappend_register (ins
, att_names_seg
[1]);
11209 oappend_register (ins
, att_names_seg
[3]);
11212 oappend_register (ins
, att_names_seg
[2]);
11215 oappend_register (ins
, att_names_seg
[0]);
11218 oappend_register (ins
, att_names_seg
[4]);
11221 oappend_register (ins
, att_names_seg
[5]);
11226 oappend_char (ins
, ':');
11230 print_operand_value (instr_info
*ins
, bfd_vma disp
,
11231 enum disassembler_style style
)
11235 if (ins
->address_mode
!= mode_64bit
)
11236 disp
&= 0xffffffff;
11237 sprintf (tmp
, "0x%" PRIx64
, (uint64_t) disp
);
11238 oappend_with_style (ins
, tmp
, style
);
11241 /* Like oappend, but called for immediate operands. */
11244 oappend_immediate (instr_info
*ins
, bfd_vma imm
)
11246 if (!ins
->intel_syntax
)
11247 oappend_char_with_style (ins
, '$', dis_style_immediate
);
11248 print_operand_value (ins
, imm
, dis_style_immediate
);
11251 /* Put DISP in BUF as signed hex number. */
11254 print_displacement (instr_info
*ins
, bfd_signed_vma val
)
11260 oappend_char_with_style (ins
, '-', dis_style_address_offset
);
11261 val
= (bfd_vma
) 0 - val
;
11263 /* Check for possible overflow. */
11266 switch (ins
->address_mode
)
11269 oappend_with_style (ins
, "0x8000000000000000",
11270 dis_style_address_offset
);
11273 oappend_with_style (ins
, "0x80000000",
11274 dis_style_address_offset
);
11277 oappend_with_style (ins
, "0x8000",
11278 dis_style_address_offset
);
11285 sprintf (tmp
, "0x%" PRIx64
, (int64_t) val
);
11286 oappend_with_style (ins
, tmp
, dis_style_address_offset
);
11290 intel_operand_size (instr_info
*ins
, int bytemode
, int sizeflag
)
11292 /* Check if there is a broadcast, when evex.b is not treated as evex.nd. */
11293 if (ins
->vex
.b
&& ins
->evex_type
== evex_default
)
11295 if (!ins
->vex
.no_broadcast
)
11299 case evex_half_bcst_xmmq_mode
:
11301 oappend (ins
, "QWORD BCST ");
11303 oappend (ins
, "DWORD BCST ");
11306 case evex_half_bcst_xmmqh_mode
:
11307 case evex_half_bcst_xmmqdh_mode
:
11308 oappend (ins
, "WORD BCST ");
11311 ins
->vex
.no_broadcast
= true;
11321 oappend (ins
, "BYTE PTR ");
11326 oappend (ins
, "WORD PTR ");
11329 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
11331 oappend (ins
, "QWORD PTR ");
11334 /* Fall through. */
11336 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
11337 || (ins
->rex
& REX_W
)))
11339 oappend (ins
, "QWORD PTR ");
11342 /* Fall through. */
11347 if (ins
->rex
& REX_W
)
11348 oappend (ins
, "QWORD PTR ");
11349 else if (bytemode
== dq_mode
)
11350 oappend (ins
, "DWORD PTR ");
11353 if (sizeflag
& DFLAG
)
11354 oappend (ins
, "DWORD PTR ");
11356 oappend (ins
, "WORD PTR ");
11357 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11361 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
11362 *ins
->obufp
++ = 'D';
11363 oappend (ins
, "WORD PTR ");
11364 if (!(ins
->rex
& REX_W
))
11365 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11368 if (sizeflag
& DFLAG
)
11369 oappend (ins
, "QWORD PTR ");
11371 oappend (ins
, "DWORD PTR ");
11372 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11375 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
11376 oappend (ins
, "WORD PTR ");
11378 oappend (ins
, "DWORD PTR ");
11379 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11383 oappend (ins
, "DWORD PTR ");
11387 oappend (ins
, "QWORD PTR ");
11390 if (ins
->address_mode
== mode_64bit
)
11391 oappend (ins
, "QWORD PTR ");
11393 oappend (ins
, "DWORD PTR ");
11396 if (sizeflag
& DFLAG
)
11397 oappend (ins
, "FWORD PTR ");
11399 oappend (ins
, "DWORD PTR ");
11400 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11403 oappend (ins
, "TBYTE PTR ");
11408 case evex_x_gscat_mode
:
11409 case evex_x_nobcst_mode
:
11413 switch (ins
->vex
.length
)
11416 oappend (ins
, "XMMWORD PTR ");
11419 oappend (ins
, "YMMWORD PTR ");
11422 oappend (ins
, "ZMMWORD PTR ");
11429 oappend (ins
, "XMMWORD PTR ");
11432 oappend (ins
, "XMMWORD PTR ");
11435 oappend (ins
, "YMMWORD PTR ");
11438 case evex_half_bcst_xmmqh_mode
:
11439 case evex_half_bcst_xmmq_mode
:
11440 switch (ins
->vex
.length
)
11444 oappend (ins
, "QWORD PTR ");
11447 oappend (ins
, "XMMWORD PTR ");
11450 oappend (ins
, "YMMWORD PTR ");
11457 if (!ins
->need_vex
)
11460 switch (ins
->vex
.length
)
11463 oappend (ins
, "WORD PTR ");
11466 oappend (ins
, "DWORD PTR ");
11469 oappend (ins
, "QWORD PTR ");
11476 case evex_half_bcst_xmmqdh_mode
:
11477 if (!ins
->need_vex
)
11480 switch (ins
->vex
.length
)
11483 oappend (ins
, "DWORD PTR ");
11486 oappend (ins
, "QWORD PTR ");
11489 oappend (ins
, "XMMWORD PTR ");
11496 if (!ins
->need_vex
)
11499 switch (ins
->vex
.length
)
11502 oappend (ins
, "QWORD PTR ");
11505 oappend (ins
, "YMMWORD PTR ");
11508 oappend (ins
, "ZMMWORD PTR ");
11515 oappend (ins
, "OWORD PTR ");
11517 case vex_vsib_d_w_dq_mode
:
11518 case vex_vsib_q_w_dq_mode
:
11519 if (!ins
->need_vex
)
11522 oappend (ins
, "QWORD PTR ");
11524 oappend (ins
, "DWORD PTR ");
11527 if (!ins
->need_vex
|| ins
->vex
.length
!= 128)
11530 oappend (ins
, "DWORD PTR ");
11532 oappend (ins
, "BYTE PTR ");
11535 if (!ins
->need_vex
)
11538 oappend (ins
, "QWORD PTR ");
11540 oappend (ins
, "WORD PTR ");
11550 print_register (instr_info
*ins
, unsigned int reg
, unsigned int rexmask
,
11551 int bytemode
, int sizeflag
)
11553 const char (*names
)[8];
11555 /* Masking is invalid for insns with GPR destination. Set the flag uniformly,
11556 as the consumer will inspect it only for the destination operand. */
11557 if (bytemode
!= mask_mode
&& ins
->vex
.mask_register_specifier
)
11558 ins
->illegal_masking
= true;
11560 USED_REX (rexmask
);
11561 if (ins
->rex
& rexmask
)
11563 if (ins
->rex2
& rexmask
)
11572 if (ins
->rex
|| ins
->rex2
)
11573 names
= att_names8rex
;
11575 names
= att_names8
;
11578 names
= att_names16
;
11583 names
= att_names32
;
11586 names
= att_names64
;
11590 names
= ins
->address_mode
== mode_64bit
? att_names64
: att_names32
;
11593 case bnd_swap_mode
:
11596 oappend (ins
, "(bad)");
11599 names
= att_names_bnd
;
11602 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
11604 names
= att_names64
;
11607 /* Fall through. */
11609 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
11610 || (ins
->rex
& REX_W
)))
11612 names
= att_names64
;
11616 /* Fall through. */
11621 if (ins
->rex
& REX_W
)
11622 names
= att_names64
;
11623 else if (bytemode
!= v_mode
&& bytemode
!= v_swap_mode
)
11624 names
= att_names32
;
11627 if (sizeflag
& DFLAG
)
11628 names
= att_names32
;
11630 names
= att_names16
;
11631 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11635 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
11636 names
= att_names16
;
11638 names
= att_names32
;
11639 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11642 names
= (ins
->address_mode
== mode_64bit
11643 ? att_names64
: att_names32
);
11644 if (!(ins
->prefixes
& PREFIX_ADDR
))
11645 names
= (ins
->address_mode
== mode_16bit
11646 ? att_names16
: names
);
11649 /* Remove "addr16/addr32". */
11650 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
11651 names
= (ins
->address_mode
!= mode_32bit
11652 ? att_names32
: att_names16
);
11653 ins
->used_prefixes
|= PREFIX_ADDR
;
11660 oappend (ins
, "(bad)");
11663 names
= att_names_mask
;
11668 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
11671 oappend_register (ins
, names
[reg
]);
11675 get8s (instr_info
*ins
, bfd_vma
*res
)
11677 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
11679 *res
= ((bfd_vma
) *ins
->codep
++ ^ 0x80) - 0x80;
11684 get16 (instr_info
*ins
, bfd_vma
*res
)
11686 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
11688 *res
= *ins
->codep
++;
11689 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
11694 get16s (instr_info
*ins
, bfd_vma
*res
)
11696 if (!get16 (ins
, res
))
11698 *res
= (*res
^ 0x8000) - 0x8000;
11703 get32 (instr_info
*ins
, bfd_vma
*res
)
11705 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
11707 *res
= *ins
->codep
++;
11708 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
11709 *res
|= (bfd_vma
) *ins
->codep
++ << 16;
11710 *res
|= (bfd_vma
) *ins
->codep
++ << 24;
11715 get32s (instr_info
*ins
, bfd_vma
*res
)
11717 if (!get32 (ins
, res
))
11720 *res
= (*res
^ ((bfd_vma
) 1 << 31)) - ((bfd_vma
) 1 << 31);
11726 get64 (instr_info
*ins
, uint64_t *res
)
11731 if (!fetch_code (ins
->info
, ins
->codep
+ 8))
11734 a
|= (unsigned int) *ins
->codep
++ << 8;
11735 a
|= (unsigned int) *ins
->codep
++ << 16;
11736 a
|= (unsigned int) *ins
->codep
++ << 24;
11738 b
|= (unsigned int) *ins
->codep
++ << 8;
11739 b
|= (unsigned int) *ins
->codep
++ << 16;
11740 b
|= (unsigned int) *ins
->codep
++ << 24;
11741 *res
= a
+ ((uint64_t) b
<< 32);
11746 set_op (instr_info
*ins
, bfd_vma op
, bool riprel
)
11748 ins
->op_index
[ins
->op_ad
] = ins
->op_ad
;
11749 if (ins
->address_mode
== mode_64bit
)
11750 ins
->op_address
[ins
->op_ad
] = op
;
11751 else /* Mask to get a 32-bit address. */
11752 ins
->op_address
[ins
->op_ad
] = op
& 0xffffffff;
11753 ins
->op_riprel
[ins
->op_ad
] = riprel
;
11757 BadOp (instr_info
*ins
)
11759 /* Throw away prefixes and 1st. opcode byte. */
11760 struct dis_private
*priv
= ins
->info
->private_data
;
11762 ins
->codep
= priv
->the_buffer
+ ins
->nr_prefixes
+ ins
->need_vex
+ 1;
11763 ins
->obufp
= stpcpy (ins
->obufp
, "(bad)");
11768 OP_Skip_MODRM (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
11769 int sizeflag ATTRIBUTE_UNUSED
)
11771 if (ins
->modrm
.mod
!= 3)
11772 return BadOp (ins
);
11774 /* Skip mod/rm byte. */
11777 ins
->has_skipped_modrm
= true;
11782 OP_E_memory (instr_info
*ins
, int bytemode
, int sizeflag
)
11784 int add
= (ins
->rex
& REX_B
) ? 8 : 0;
11788 add
+= (ins
->rex2
& REX_B
) ? 16 : 0;
11790 /* Handles EVEX other than APX EVEX-promoted instructions. */
11791 if (ins
->vex
.evex
&& ins
->evex_type
== evex_default
)
11794 /* Zeroing-masking is invalid for memory destinations. Set the flag
11795 uniformly, as the consumer will inspect it only for the destination
11797 if (ins
->vex
.zeroing
)
11798 ins
->illegal_masking
= true;
11812 if (ins
->address_mode
!= mode_64bit
)
11820 case vex_vsib_d_w_dq_mode
:
11821 case vex_vsib_q_w_dq_mode
:
11822 case evex_x_gscat_mode
:
11823 shift
= ins
->vex
.w
? 3 : 2;
11826 case evex_half_bcst_xmmqh_mode
:
11827 case evex_half_bcst_xmmqdh_mode
:
11830 shift
= ins
->vex
.w
? 2 : 1;
11833 /* Fall through. */
11835 case evex_half_bcst_xmmq_mode
:
11838 shift
= ins
->vex
.w
? 3 : 2;
11841 /* Fall through. */
11846 case evex_x_nobcst_mode
:
11848 switch (ins
->vex
.length
)
11862 /* Make necessary corrections to shift for modes that need it. */
11863 if (bytemode
== xmmq_mode
11864 || bytemode
== evex_half_bcst_xmmqh_mode
11865 || bytemode
== evex_half_bcst_xmmq_mode
11866 || (bytemode
== ymmq_mode
&& ins
->vex
.length
== 128))
11868 else if (bytemode
== xmmqd_mode
11869 || bytemode
== evex_half_bcst_xmmqdh_mode
)
11871 else if (bytemode
== xmmdw_mode
)
11885 shift
= ins
->vex
.w
? 1 : 0;
11895 if (ins
->intel_syntax
)
11896 intel_operand_size (ins
, bytemode
, sizeflag
);
11899 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
11901 /* 32/64 bit address mode */
11910 int addr32flag
= !((sizeflag
& AFLAG
)
11911 || bytemode
== v_bnd_mode
11912 || bytemode
== v_bndmk_mode
11913 || bytemode
== bnd_mode
11914 || bytemode
== bnd_swap_mode
);
11915 bool check_gather
= false;
11916 const char (*indexes
)[8] = NULL
;
11919 base
= ins
->modrm
.rm
;
11923 vindex
= ins
->sib
.index
;
11925 if (ins
->rex
& REX_X
)
11929 case vex_vsib_d_w_dq_mode
:
11930 case vex_vsib_q_w_dq_mode
:
11931 if (!ins
->need_vex
)
11935 /* S/G EVEX insns require EVEX.X4 not to be set. */
11936 if (ins
->rex2
& REX_X
)
11938 oappend (ins
, "(bad)");
11944 check_gather
= ins
->obufp
== ins
->op_out
[1];
11947 switch (ins
->vex
.length
)
11950 indexes
= att_names_xmm
;
11954 || bytemode
== vex_vsib_q_w_dq_mode
)
11955 indexes
= att_names_ymm
;
11957 indexes
= att_names_xmm
;
11961 || bytemode
== vex_vsib_q_w_dq_mode
)
11962 indexes
= att_names_zmm
;
11964 indexes
= att_names_ymm
;
11971 if (ins
->rex2
& REX_X
)
11975 indexes
= ins
->address_mode
== mode_64bit
&& !addr32flag
11976 ? att_names64
: att_names32
;
11979 scale
= ins
->sib
.scale
;
11980 base
= ins
->sib
.base
;
11985 /* Check for mandatory SIB. */
11986 if (bytemode
== vex_vsib_d_w_dq_mode
11987 || bytemode
== vex_vsib_q_w_dq_mode
11988 || bytemode
== vex_sibmem_mode
)
11990 oappend (ins
, "(bad)");
11994 rbase
= base
+ add
;
11996 switch (ins
->modrm
.mod
)
12002 if (ins
->address_mode
== mode_64bit
&& !ins
->has_sib
)
12004 if (!get32s (ins
, &disp
))
12006 if (riprel
&& bytemode
== v_bndmk_mode
)
12008 oappend (ins
, "(bad)");
12014 if (!get8s (ins
, &disp
))
12016 if (ins
->vex
.evex
&& shift
> 0)
12020 if (!get32s (ins
, &disp
))
12030 && ins
->address_mode
!= mode_16bit
)
12032 if (ins
->address_mode
== mode_64bit
)
12036 /* Without base nor index registers, zero-extend the
12037 lower 32-bit displacement to 64 bits. */
12038 disp
&= 0xffffffff;
12045 /* In 32-bit mode, we need index register to tell [offset]
12046 from [eiz*1 + offset]. */
12051 havedisp
= (havebase
12053 || (ins
->has_sib
&& (indexes
|| scale
!= 0)));
12055 if (!ins
->intel_syntax
)
12056 if (ins
->modrm
.mod
!= 0 || base
== 5)
12058 if (havedisp
|| riprel
)
12059 print_displacement (ins
, disp
);
12061 print_operand_value (ins
, disp
, dis_style_address_offset
);
12064 set_op (ins
, disp
, true);
12065 oappend_char (ins
, '(');
12066 oappend_with_style (ins
, !addr32flag
? "%rip" : "%eip",
12067 dis_style_register
);
12068 oappend_char (ins
, ')');
12072 if ((havebase
|| indexes
|| needindex
|| needaddr32
|| riprel
)
12073 && (ins
->address_mode
!= mode_64bit
12074 || ((bytemode
!= v_bnd_mode
)
12075 && (bytemode
!= v_bndmk_mode
)
12076 && (bytemode
!= bnd_mode
)
12077 && (bytemode
!= bnd_swap_mode
))))
12078 ins
->used_prefixes
|= PREFIX_ADDR
;
12080 if (havedisp
|| (ins
->intel_syntax
&& riprel
))
12082 oappend_char (ins
, ins
->open_char
);
12083 if (ins
->intel_syntax
&& riprel
)
12085 set_op (ins
, disp
, true);
12086 oappend_with_style (ins
, !addr32flag
? "rip" : "eip",
12087 dis_style_register
);
12092 (ins
->address_mode
== mode_64bit
&& !addr32flag
12093 ? att_names64
: att_names32
)[rbase
]);
12096 /* ESP/RSP won't allow index. If base isn't ESP/RSP,
12097 print index to tell base + index from base. */
12101 || (havebase
&& base
!= ESP_REG_NUM
))
12103 if (!ins
->intel_syntax
|| havebase
)
12104 oappend_char (ins
, ins
->separator_char
);
12107 if (ins
->address_mode
== mode_64bit
|| vindex
< 16)
12108 oappend_register (ins
, indexes
[vindex
]);
12110 oappend (ins
, "(bad)");
12113 oappend_register (ins
,
12114 ins
->address_mode
== mode_64bit
12119 oappend_char (ins
, ins
->scale_char
);
12120 oappend_char_with_style (ins
, '0' + (1 << scale
),
12121 dis_style_immediate
);
12124 if (ins
->intel_syntax
12125 && (disp
|| ins
->modrm
.mod
!= 0 || base
== 5))
12127 if (!havedisp
|| (bfd_signed_vma
) disp
>= 0)
12128 oappend_char (ins
, '+');
12130 print_displacement (ins
, disp
);
12132 print_operand_value (ins
, disp
, dis_style_address_offset
);
12135 oappend_char (ins
, ins
->close_char
);
12139 /* Both XMM/YMM/ZMM registers must be distinct. */
12140 int modrm_reg
= ins
->modrm
.reg
;
12142 if (ins
->rex
& REX_R
)
12144 if (ins
->rex2
& REX_R
)
12146 if (vindex
== modrm_reg
)
12147 oappend (ins
, "/(bad)");
12150 else if (ins
->intel_syntax
)
12152 if (ins
->modrm
.mod
!= 0 || base
== 5)
12154 if (!ins
->active_seg_prefix
)
12156 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12157 oappend (ins
, ":");
12159 print_operand_value (ins
, disp
, dis_style_text
);
12163 else if (bytemode
== v_bnd_mode
12164 || bytemode
== v_bndmk_mode
12165 || bytemode
== bnd_mode
12166 || bytemode
== bnd_swap_mode
12167 || bytemode
== vex_vsib_d_w_dq_mode
12168 || bytemode
== vex_vsib_q_w_dq_mode
)
12170 oappend (ins
, "(bad)");
12175 /* 16 bit address mode */
12178 ins
->used_prefixes
|= ins
->prefixes
& PREFIX_ADDR
;
12179 switch (ins
->modrm
.mod
)
12182 if (ins
->modrm
.rm
== 6)
12185 if (!get16s (ins
, &disp
))
12190 if (!get8s (ins
, &disp
))
12192 if (ins
->vex
.evex
&& shift
> 0)
12197 if (!ins
->intel_syntax
)
12198 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6)
12199 print_displacement (ins
, disp
);
12201 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 6)
12203 oappend_char (ins
, ins
->open_char
);
12204 oappend (ins
, ins
->intel_syntax
? intel_index16
[ins
->modrm
.rm
]
12205 : att_index16
[ins
->modrm
.rm
]);
12206 if (ins
->intel_syntax
12207 && (disp
|| ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6))
12209 if ((bfd_signed_vma
) disp
>= 0)
12210 oappend_char (ins
, '+');
12211 print_displacement (ins
, disp
);
12214 oappend_char (ins
, ins
->close_char
);
12216 else if (ins
->intel_syntax
)
12218 if (!ins
->active_seg_prefix
)
12220 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12221 oappend (ins
, ":");
12223 print_operand_value (ins
, disp
& 0xffff, dis_style_text
);
12226 if (ins
->vex
.b
&& ins
->evex_type
== evex_default
)
12228 ins
->evex_used
|= EVEX_b_used
;
12230 /* Broadcast can only ever be valid for memory sources. */
12231 if (ins
->obufp
== ins
->op_out
[0])
12232 ins
->vex
.no_broadcast
= true;
12234 if (!ins
->vex
.no_broadcast
12235 && (!ins
->intel_syntax
|| !(ins
->evex_used
& EVEX_len_used
)))
12237 if (bytemode
== xh_mode
)
12239 switch (ins
->vex
.length
)
12242 oappend (ins
, "{1to8}");
12245 oappend (ins
, "{1to16}");
12248 oappend (ins
, "{1to32}");
12254 else if (bytemode
== q_mode
12255 || bytemode
== ymmq_mode
)
12256 ins
->vex
.no_broadcast
= true;
12257 else if (ins
->vex
.w
12258 || bytemode
== evex_half_bcst_xmmqdh_mode
12259 || bytemode
== evex_half_bcst_xmmq_mode
)
12261 switch (ins
->vex
.length
)
12264 oappend (ins
, "{1to2}");
12267 oappend (ins
, "{1to4}");
12270 oappend (ins
, "{1to8}");
12276 else if (bytemode
== x_mode
12277 || bytemode
== evex_half_bcst_xmmqh_mode
)
12279 switch (ins
->vex
.length
)
12282 oappend (ins
, "{1to4}");
12285 oappend (ins
, "{1to8}");
12288 oappend (ins
, "{1to16}");
12295 ins
->vex
.no_broadcast
= true;
12297 if (ins
->vex
.no_broadcast
)
12298 oappend (ins
, "{bad}");
12305 OP_E (instr_info
*ins
, int bytemode
, int sizeflag
)
12307 /* Skip mod/rm byte. */
12309 if (!ins
->has_skipped_modrm
)
12312 ins
->has_skipped_modrm
= true;
12315 if (ins
->modrm
.mod
== 3)
12317 if ((sizeflag
& SUFFIX_ALWAYS
)
12318 && (bytemode
== b_swap_mode
12319 || bytemode
== bnd_swap_mode
12320 || bytemode
== v_swap_mode
))
12321 swap_operand (ins
);
12323 print_register (ins
, ins
->modrm
.rm
, REX_B
, bytemode
, sizeflag
);
12327 /* Masking is invalid for insns with GPR-like memory destination. Set the
12328 flag uniformly, as the consumer will inspect it only for the destination
12330 if (ins
->vex
.mask_register_specifier
)
12331 ins
->illegal_masking
= true;
12333 return OP_E_memory (ins
, bytemode
, sizeflag
);
12337 OP_indirE (instr_info
*ins
, int bytemode
, int sizeflag
)
12339 if (ins
->modrm
.mod
== 3 && bytemode
== f_mode
)
12340 /* bad lcall/ljmp */
12341 return BadOp (ins
);
12342 if (!ins
->intel_syntax
)
12343 oappend (ins
, "*");
12344 return OP_E (ins
, bytemode
, sizeflag
);
12348 OP_G (instr_info
*ins
, int bytemode
, int sizeflag
)
12350 print_register (ins
, ins
->modrm
.reg
, REX_R
, bytemode
, sizeflag
);
12355 OP_REG (instr_info
*ins
, int code
, int sizeflag
)
12362 case es_reg
: case ss_reg
: case cs_reg
:
12363 case ds_reg
: case fs_reg
: case gs_reg
:
12364 oappend_register (ins
, att_names_seg
[code
- es_reg
]);
12369 if (ins
->rex
& REX_B
)
12371 if (ins
->rex2
& REX_B
)
12376 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
12377 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
12378 s
= att_names16
[code
- ax_reg
+ add
];
12380 case ah_reg
: case ch_reg
: case dh_reg
: case bh_reg
:
12382 /* Fall through. */
12383 case al_reg
: case cl_reg
: case dl_reg
: case bl_reg
:
12385 s
= att_names8rex
[code
- al_reg
+ add
];
12387 s
= att_names8
[code
- al_reg
];
12389 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
12390 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
12391 if (ins
->address_mode
== mode_64bit
12392 && ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
12394 s
= att_names64
[code
- rAX_reg
+ add
];
12397 code
+= eAX_reg
- rAX_reg
;
12398 /* Fall through. */
12399 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
12400 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
12402 if (ins
->rex
& REX_W
)
12403 s
= att_names64
[code
- eAX_reg
+ add
];
12406 if (sizeflag
& DFLAG
)
12407 s
= att_names32
[code
- eAX_reg
+ add
];
12409 s
= att_names16
[code
- eAX_reg
+ add
];
12410 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12414 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12417 oappend_register (ins
, s
);
12422 OP_IMREG (instr_info
*ins
, int code
, int sizeflag
)
12429 if (!ins
->intel_syntax
)
12431 oappend (ins
, "(%dx)");
12434 s
= att_names16
[dx_reg
- ax_reg
];
12436 case al_reg
: case cl_reg
:
12437 s
= att_names8
[code
- al_reg
];
12441 if (ins
->rex
& REX_W
)
12446 /* Fall through. */
12447 case z_mode_ax_reg
:
12448 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
12452 if (!(ins
->rex
& REX_W
))
12453 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12456 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12459 oappend_register (ins
, s
);
12464 OP_I (instr_info
*ins
, int bytemode
, int sizeflag
)
12471 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
12473 op
= *ins
->codep
++;
12477 if (ins
->rex
& REX_W
)
12479 if (!get32s (ins
, &op
))
12484 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12485 if (sizeflag
& DFLAG
)
12488 if (!get32 (ins
, &op
))
12493 /* Fall through. */
12495 if (!get16 (ins
, &op
))
12501 if (ins
->intel_syntax
)
12502 oappend_with_style (ins
, "1", dis_style_immediate
);
12504 oappend_with_style (ins
, "$1", dis_style_immediate
);
12507 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12511 oappend_immediate (ins
, op
);
12516 OP_I64 (instr_info
*ins
, int bytemode
, int sizeflag
)
12520 if (bytemode
!= v_mode
|| ins
->address_mode
!= mode_64bit
12521 || !(ins
->rex
& REX_W
))
12522 return OP_I (ins
, bytemode
, sizeflag
);
12526 if (!get64 (ins
, &op
))
12529 oappend_immediate (ins
, op
);
12534 OP_sI (instr_info
*ins
, int bytemode
, int sizeflag
)
12542 if (!get8s (ins
, &op
))
12544 if (bytemode
== b_T_mode
)
12546 if (ins
->address_mode
!= mode_64bit
12547 || !((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
12549 /* The operand-size prefix is overridden by a REX prefix. */
12550 if ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
))
12558 if (!(ins
->rex
& REX_W
))
12560 if (sizeflag
& DFLAG
)
12568 /* The operand-size prefix is overridden by a REX prefix. */
12569 if (!(sizeflag
& DFLAG
) && !(ins
->rex
& REX_W
))
12571 if (!get16 (ins
, &op
))
12574 else if (!get32s (ins
, &op
))
12578 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12582 oappend_immediate (ins
, op
);
12587 OP_J (instr_info
*ins
, int bytemode
, int sizeflag
)
12591 bfd_vma segment
= 0;
12596 if (!get8s (ins
, &disp
))
12601 if ((sizeflag
& DFLAG
)
12602 || (ins
->address_mode
== mode_64bit
12603 && ((ins
->isa64
== intel64
&& bytemode
!= dqw_mode
)
12604 || (ins
->rex
& REX_W
))))
12606 if (!get32s (ins
, &disp
))
12611 if (!get16s (ins
, &disp
))
12613 /* In 16bit mode, address is wrapped around at 64k within
12614 the same segment. Otherwise, a data16 prefix on a jump
12615 instruction means that the pc is masked to 16 bits after
12616 the displacement is added! */
12618 if ((ins
->prefixes
& PREFIX_DATA
) == 0)
12619 segment
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
))
12620 & ~((bfd_vma
) 0xffff));
12622 if (ins
->address_mode
!= mode_64bit
12623 || (ins
->isa64
!= intel64
&& !(ins
->rex
& REX_W
)))
12624 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12627 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12630 disp
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
) + disp
) & mask
)
12632 set_op (ins
, disp
, false);
12633 print_operand_value (ins
, disp
, dis_style_text
);
12638 OP_SEG (instr_info
*ins
, int bytemode
, int sizeflag
)
12640 if (bytemode
== w_mode
)
12642 oappend_register (ins
, att_names_seg
[ins
->modrm
.reg
]);
12645 return OP_E (ins
, ins
->modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
12649 OP_DIR (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
12651 bfd_vma seg
, offset
;
12655 if (sizeflag
& DFLAG
)
12657 if (!get32 (ins
, &offset
))
12660 else if (!get16 (ins
, &offset
))
12662 if (!get16 (ins
, &seg
))
12664 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12666 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
12667 ins
->intel_syntax
? "0x%x:0x%x" : "$0x%x,$0x%x",
12668 (unsigned) seg
, (unsigned) offset
);
12669 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12671 oappend (ins
, scratch
);
12676 OP_OFF (instr_info
*ins
, int bytemode
, int sizeflag
)
12680 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
12681 intel_operand_size (ins
, bytemode
, sizeflag
);
12684 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
12686 if (!get32 (ins
, &off
))
12691 if (!get16 (ins
, &off
))
12695 if (ins
->intel_syntax
)
12697 if (!ins
->active_seg_prefix
)
12699 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12700 oappend (ins
, ":");
12703 print_operand_value (ins
, off
, dis_style_address_offset
);
12708 OP_OFF64 (instr_info
*ins
, int bytemode
, int sizeflag
)
12712 if (ins
->address_mode
!= mode_64bit
12713 || (ins
->prefixes
& PREFIX_ADDR
))
12714 return OP_OFF (ins
, bytemode
, sizeflag
);
12716 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
12717 intel_operand_size (ins
, bytemode
, sizeflag
);
12720 if (!get64 (ins
, &off
))
12723 if (ins
->intel_syntax
)
12725 if (!ins
->active_seg_prefix
)
12727 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12728 oappend (ins
, ":");
12731 print_operand_value (ins
, off
, dis_style_address_offset
);
12736 ptr_reg (instr_info
*ins
, int code
, int sizeflag
)
12740 *ins
->obufp
++ = ins
->open_char
;
12741 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
12742 if (ins
->address_mode
== mode_64bit
)
12744 if (!(sizeflag
& AFLAG
))
12745 s
= att_names32
[code
- eAX_reg
];
12747 s
= att_names64
[code
- eAX_reg
];
12749 else if (sizeflag
& AFLAG
)
12750 s
= att_names32
[code
- eAX_reg
];
12752 s
= att_names16
[code
- eAX_reg
];
12753 oappend_register (ins
, s
);
12754 oappend_char (ins
, ins
->close_char
);
12758 OP_ESreg (instr_info
*ins
, int code
, int sizeflag
)
12760 if (ins
->intel_syntax
)
12762 switch (ins
->codep
[-1])
12764 case 0x6d: /* insw/insl */
12765 intel_operand_size (ins
, z_mode
, sizeflag
);
12767 case 0xa5: /* movsw/movsl/movsq */
12768 case 0xa7: /* cmpsw/cmpsl/cmpsq */
12769 case 0xab: /* stosw/stosl */
12770 case 0xaf: /* scasw/scasl */
12771 intel_operand_size (ins
, v_mode
, sizeflag
);
12774 intel_operand_size (ins
, b_mode
, sizeflag
);
12777 oappend_register (ins
, att_names_seg
[0]);
12778 oappend_char (ins
, ':');
12779 ptr_reg (ins
, code
, sizeflag
);
12784 OP_DSreg (instr_info
*ins
, int code
, int sizeflag
)
12786 if (ins
->intel_syntax
)
12788 switch (ins
->codep
[-1])
12790 case 0x6f: /* outsw/outsl */
12791 intel_operand_size (ins
, z_mode
, sizeflag
);
12793 case 0xa5: /* movsw/movsl/movsq */
12794 case 0xa7: /* cmpsw/cmpsl/cmpsq */
12795 case 0xad: /* lodsw/lodsl/lodsq */
12796 intel_operand_size (ins
, v_mode
, sizeflag
);
12799 intel_operand_size (ins
, b_mode
, sizeflag
);
12802 /* Set ins->active_seg_prefix to PREFIX_DS if it is unset so that the
12803 default segment register DS is printed. */
12804 if (!ins
->active_seg_prefix
)
12805 ins
->active_seg_prefix
= PREFIX_DS
;
12807 ptr_reg (ins
, code
, sizeflag
);
12812 OP_C (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12813 int sizeflag ATTRIBUTE_UNUSED
)
12818 if (ins
->rex
& REX_R
)
12823 else if (ins
->address_mode
!= mode_64bit
&& (ins
->prefixes
& PREFIX_LOCK
))
12825 ins
->all_prefixes
[ins
->last_lock_prefix
] = 0;
12826 ins
->used_prefixes
|= PREFIX_LOCK
;
12831 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%cr%d",
12832 ins
->modrm
.reg
+ add
);
12833 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12835 oappend_register (ins
, scratch
);
12840 OP_D (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12841 int sizeflag ATTRIBUTE_UNUSED
)
12847 if (ins
->rex
& REX_R
)
12851 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
12852 ins
->intel_syntax
? "dr%d" : "%%db%d",
12853 ins
->modrm
.reg
+ add
);
12854 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12856 oappend (ins
, scratch
);
12861 OP_T (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
12862 int sizeflag ATTRIBUTE_UNUSED
)
12867 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%tr%d", ins
->modrm
.reg
);
12868 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
12870 oappend_register (ins
, scratch
);
12875 OP_MMX (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12876 int sizeflag ATTRIBUTE_UNUSED
)
12878 int reg
= ins
->modrm
.reg
;
12879 const char (*names
)[8];
12881 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12882 if (ins
->prefixes
& PREFIX_DATA
)
12884 names
= att_names_xmm
;
12886 if (ins
->rex
& REX_R
)
12890 names
= att_names_mm
;
12891 oappend_register (ins
, names
[reg
]);
12896 print_vector_reg (instr_info
*ins
, unsigned int reg
, int bytemode
)
12898 const char (*names
)[8];
12900 if (bytemode
== xmmq_mode
12901 || bytemode
== evex_half_bcst_xmmqh_mode
12902 || bytemode
== evex_half_bcst_xmmq_mode
)
12904 switch (ins
->vex
.length
)
12909 names
= att_names_xmm
;
12912 names
= att_names_ymm
;
12913 ins
->evex_used
|= EVEX_len_used
;
12919 else if (bytemode
== ymm_mode
)
12920 names
= att_names_ymm
;
12921 else if (bytemode
== tmm_mode
)
12925 oappend (ins
, "(bad)");
12928 names
= att_names_tmm
;
12930 else if (ins
->need_vex
12931 && bytemode
!= xmm_mode
12932 && bytemode
!= scalar_mode
12933 && bytemode
!= xmmdw_mode
12934 && bytemode
!= xmmqd_mode
12935 && bytemode
!= evex_half_bcst_xmmqdh_mode
12936 && bytemode
!= w_swap_mode
12937 && bytemode
!= b_mode
12938 && bytemode
!= w_mode
12939 && bytemode
!= d_mode
12940 && bytemode
!= q_mode
)
12942 ins
->evex_used
|= EVEX_len_used
;
12943 switch (ins
->vex
.length
)
12946 names
= att_names_xmm
;
12950 || bytemode
!= vex_vsib_q_w_dq_mode
)
12951 names
= att_names_ymm
;
12953 names
= att_names_xmm
;
12957 || bytemode
!= vex_vsib_q_w_dq_mode
)
12958 names
= att_names_zmm
;
12960 names
= att_names_ymm
;
12967 names
= att_names_xmm
;
12968 oappend_register (ins
, names
[reg
]);
12972 OP_XMM (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
12974 unsigned int reg
= ins
->modrm
.reg
;
12977 if (ins
->rex
& REX_R
)
12981 if (ins
->rex2
& REX_R
)
12985 if (bytemode
== tmm_mode
)
12986 ins
->modrm
.reg
= reg
;
12987 else if (bytemode
== scalar_mode
)
12988 ins
->vex
.no_broadcast
= true;
12990 print_vector_reg (ins
, reg
, bytemode
);
12995 OP_EM (instr_info
*ins
, int bytemode
, int sizeflag
)
12998 const char (*names
)[8];
13000 if (ins
->modrm
.mod
!= 3)
13002 if (ins
->intel_syntax
13003 && (bytemode
== v_mode
|| bytemode
== v_swap_mode
))
13005 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
13006 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13008 return OP_E (ins
, bytemode
, sizeflag
);
13011 if ((sizeflag
& SUFFIX_ALWAYS
) && bytemode
== v_swap_mode
)
13012 swap_operand (ins
);
13014 /* Skip mod/rm byte. */
13017 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13018 reg
= ins
->modrm
.rm
;
13019 if (ins
->prefixes
& PREFIX_DATA
)
13021 names
= att_names_xmm
;
13023 if (ins
->rex
& REX_B
)
13027 names
= att_names_mm
;
13028 oappend_register (ins
, names
[reg
]);
13032 /* cvt* are the only instructions in sse2 which have
13033 both SSE and MMX operands and also have 0x66 prefix
13034 in their opcode. 0x66 was originally used to differentiate
13035 between SSE and MMX instruction(operands). So we have to handle the
13036 cvt* separately using OP_EMC and OP_MXC */
13038 OP_EMC (instr_info
*ins
, int bytemode
, int sizeflag
)
13040 if (ins
->modrm
.mod
!= 3)
13042 if (ins
->intel_syntax
&& bytemode
== v_mode
)
13044 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
13045 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13047 return OP_E (ins
, bytemode
, sizeflag
);
13050 /* Skip mod/rm byte. */
13053 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13054 oappend_register (ins
, att_names_mm
[ins
->modrm
.rm
]);
13059 OP_MXC (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13060 int sizeflag ATTRIBUTE_UNUSED
)
13062 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13063 oappend_register (ins
, att_names_mm
[ins
->modrm
.reg
]);
13068 OP_EX (instr_info
*ins
, int bytemode
, int sizeflag
)
13072 /* Skip mod/rm byte. */
13076 if (bytemode
== dq_mode
)
13077 bytemode
= ins
->vex
.w
? q_mode
: d_mode
;
13079 if (ins
->modrm
.mod
!= 3)
13080 return OP_E_memory (ins
, bytemode
, sizeflag
);
13082 reg
= ins
->modrm
.rm
;
13084 if (ins
->rex
& REX_B
)
13089 if ((ins
->rex
& REX_X
))
13091 ins
->rex2_used
&= ~REX_B
;
13093 else if (ins
->rex2
& REX_B
)
13096 if ((sizeflag
& SUFFIX_ALWAYS
)
13097 && (bytemode
== x_swap_mode
13098 || bytemode
== w_swap_mode
13099 || bytemode
== d_swap_mode
13100 || bytemode
== q_swap_mode
))
13101 swap_operand (ins
);
13103 if (bytemode
== tmm_mode
)
13104 ins
->modrm
.rm
= reg
;
13106 print_vector_reg (ins
, reg
, bytemode
);
13111 OP_R (instr_info
*ins
, int bytemode
, int sizeflag
)
13113 if (ins
->modrm
.mod
!= 3)
13114 return BadOp (ins
);
13122 return OP_E (ins
, bytemode
, sizeflag
);
13124 return OP_EM (ins
, x_mode
, sizeflag
);
13126 if (ins
->vex
.length
<= 128)
13128 return BadOp (ins
);
13131 return OP_EX (ins
, bytemode
, sizeflag
);
13135 OP_M (instr_info
*ins
, int bytemode
, int sizeflag
)
13137 /* Skip mod/rm byte. */
13141 if (ins
->modrm
.mod
== 3)
13142 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
13143 return BadOp (ins
);
13145 if (bytemode
== x_mode
)
13146 ins
->vex
.no_broadcast
= true;
13148 return OP_E_memory (ins
, bytemode
, sizeflag
);
13152 OP_0f07 (instr_info
*ins
, int bytemode
, int sizeflag
)
13154 if (ins
->modrm
.mod
!= 3 || ins
->modrm
.rm
!= 0)
13155 return BadOp (ins
);
13156 return OP_E (ins
, bytemode
, sizeflag
);
13159 /* montmul instruction need display repz and skip modrm */
13162 MONTMUL_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
13164 if (ins
->modrm
.mod
!= 3 || ins
->modrm
.rm
!= 0)
13165 return BadOp (ins
);
13167 /* The 0xf3 prefix should be displayed as "repz" for montmul. */
13168 if (ins
->prefixes
& PREFIX_REPZ
)
13169 ins
->all_prefixes
[ins
->last_repz_prefix
] = 0xf3;
13171 /* Skip mod/rm byte. */
13177 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
13178 32bit mode and "xchg %rax,%rax" in 64bit mode. */
13181 NOP_Fixup (instr_info
*ins
, int opnd
, int sizeflag
)
13183 if ((ins
->prefixes
& PREFIX_DATA
) == 0 && (ins
->rex
& REX_B
) == 0)
13185 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop");
13189 return OP_REG (ins
, eAX_reg
, sizeflag
);
13190 return OP_IMREG (ins
, eAX_reg
, sizeflag
);
13193 static const char *const Suffix3DNow
[] = {
13194 /* 00 */ NULL
, NULL
, NULL
, NULL
,
13195 /* 04 */ NULL
, NULL
, NULL
, NULL
,
13196 /* 08 */ NULL
, NULL
, NULL
, NULL
,
13197 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
13198 /* 10 */ NULL
, NULL
, NULL
, NULL
,
13199 /* 14 */ NULL
, NULL
, NULL
, NULL
,
13200 /* 18 */ NULL
, NULL
, NULL
, NULL
,
13201 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
13202 /* 20 */ NULL
, NULL
, NULL
, NULL
,
13203 /* 24 */ NULL
, NULL
, NULL
, NULL
,
13204 /* 28 */ NULL
, NULL
, NULL
, NULL
,
13205 /* 2C */ NULL
, NULL
, NULL
, NULL
,
13206 /* 30 */ NULL
, NULL
, NULL
, NULL
,
13207 /* 34 */ NULL
, NULL
, NULL
, NULL
,
13208 /* 38 */ NULL
, NULL
, NULL
, NULL
,
13209 /* 3C */ NULL
, NULL
, NULL
, NULL
,
13210 /* 40 */ NULL
, NULL
, NULL
, NULL
,
13211 /* 44 */ NULL
, NULL
, NULL
, NULL
,
13212 /* 48 */ NULL
, NULL
, NULL
, NULL
,
13213 /* 4C */ NULL
, NULL
, NULL
, NULL
,
13214 /* 50 */ NULL
, NULL
, NULL
, NULL
,
13215 /* 54 */ NULL
, NULL
, NULL
, NULL
,
13216 /* 58 */ NULL
, NULL
, NULL
, NULL
,
13217 /* 5C */ NULL
, NULL
, NULL
, NULL
,
13218 /* 60 */ NULL
, NULL
, NULL
, NULL
,
13219 /* 64 */ NULL
, NULL
, NULL
, NULL
,
13220 /* 68 */ NULL
, NULL
, NULL
, NULL
,
13221 /* 6C */ NULL
, NULL
, NULL
, NULL
,
13222 /* 70 */ NULL
, NULL
, NULL
, NULL
,
13223 /* 74 */ NULL
, NULL
, NULL
, NULL
,
13224 /* 78 */ NULL
, NULL
, NULL
, NULL
,
13225 /* 7C */ NULL
, NULL
, NULL
, NULL
,
13226 /* 80 */ NULL
, NULL
, NULL
, NULL
,
13227 /* 84 */ NULL
, NULL
, NULL
, NULL
,
13228 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
13229 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
13230 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
13231 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
13232 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
13233 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
13234 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
13235 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
13236 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
13237 /* AC */ NULL
, NULL
, "pfacc", NULL
,
13238 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
13239 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
13240 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
13241 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
13242 /* C0 */ NULL
, NULL
, NULL
, NULL
,
13243 /* C4 */ NULL
, NULL
, NULL
, NULL
,
13244 /* C8 */ NULL
, NULL
, NULL
, NULL
,
13245 /* CC */ NULL
, NULL
, NULL
, NULL
,
13246 /* D0 */ NULL
, NULL
, NULL
, NULL
,
13247 /* D4 */ NULL
, NULL
, NULL
, NULL
,
13248 /* D8 */ NULL
, NULL
, NULL
, NULL
,
13249 /* DC */ NULL
, NULL
, NULL
, NULL
,
13250 /* E0 */ NULL
, NULL
, NULL
, NULL
,
13251 /* E4 */ NULL
, NULL
, NULL
, NULL
,
13252 /* E8 */ NULL
, NULL
, NULL
, NULL
,
13253 /* EC */ NULL
, NULL
, NULL
, NULL
,
13254 /* F0 */ NULL
, NULL
, NULL
, NULL
,
13255 /* F4 */ NULL
, NULL
, NULL
, NULL
,
13256 /* F8 */ NULL
, NULL
, NULL
, NULL
,
13257 /* FC */ NULL
, NULL
, NULL
, NULL
,
13261 OP_3DNowSuffix (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13262 int sizeflag ATTRIBUTE_UNUSED
)
13264 const char *mnemonic
;
13266 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13268 /* AMD 3DNow! instructions are specified by an opcode suffix in the
13269 place where an 8-bit immediate would normally go. ie. the last
13270 byte of the instruction. */
13271 ins
->obufp
= ins
->mnemonicendp
;
13272 mnemonic
= Suffix3DNow
[*ins
->codep
++];
13274 ins
->obufp
= stpcpy (ins
->obufp
, mnemonic
);
13277 /* Since a variable sized ins->modrm/ins->sib chunk is between the start
13278 of the opcode (0x0f0f) and the opcode suffix, we need to do
13279 all the ins->modrm processing first, and don't know until now that
13280 we have a bad opcode. This necessitates some cleaning up. */
13281 ins
->op_out
[0][0] = '\0';
13282 ins
->op_out
[1][0] = '\0';
13285 ins
->mnemonicendp
= ins
->obufp
;
13289 static const struct op simd_cmp_op
[] =
13291 { STRING_COMMA_LEN ("eq") },
13292 { STRING_COMMA_LEN ("lt") },
13293 { STRING_COMMA_LEN ("le") },
13294 { STRING_COMMA_LEN ("unord") },
13295 { STRING_COMMA_LEN ("neq") },
13296 { STRING_COMMA_LEN ("nlt") },
13297 { STRING_COMMA_LEN ("nle") },
13298 { STRING_COMMA_LEN ("ord") }
13301 static const struct op vex_cmp_op
[] =
13303 { STRING_COMMA_LEN ("eq_uq") },
13304 { STRING_COMMA_LEN ("nge") },
13305 { STRING_COMMA_LEN ("ngt") },
13306 { STRING_COMMA_LEN ("false") },
13307 { STRING_COMMA_LEN ("neq_oq") },
13308 { STRING_COMMA_LEN ("ge") },
13309 { STRING_COMMA_LEN ("gt") },
13310 { STRING_COMMA_LEN ("true") },
13311 { STRING_COMMA_LEN ("eq_os") },
13312 { STRING_COMMA_LEN ("lt_oq") },
13313 { STRING_COMMA_LEN ("le_oq") },
13314 { STRING_COMMA_LEN ("unord_s") },
13315 { STRING_COMMA_LEN ("neq_us") },
13316 { STRING_COMMA_LEN ("nlt_uq") },
13317 { STRING_COMMA_LEN ("nle_uq") },
13318 { STRING_COMMA_LEN ("ord_s") },
13319 { STRING_COMMA_LEN ("eq_us") },
13320 { STRING_COMMA_LEN ("nge_uq") },
13321 { STRING_COMMA_LEN ("ngt_uq") },
13322 { STRING_COMMA_LEN ("false_os") },
13323 { STRING_COMMA_LEN ("neq_os") },
13324 { STRING_COMMA_LEN ("ge_oq") },
13325 { STRING_COMMA_LEN ("gt_oq") },
13326 { STRING_COMMA_LEN ("true_us") },
13330 CMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13331 int sizeflag ATTRIBUTE_UNUSED
)
13333 unsigned int cmp_type
;
13335 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13337 cmp_type
= *ins
->codep
++;
13338 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
))
13341 char *p
= ins
->mnemonicendp
- 2;
13345 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
13346 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
13348 else if (ins
->need_vex
13349 && cmp_type
< ARRAY_SIZE (simd_cmp_op
) + ARRAY_SIZE (vex_cmp_op
))
13352 char *p
= ins
->mnemonicendp
- 2;
13356 cmp_type
-= ARRAY_SIZE (simd_cmp_op
);
13357 sprintf (p
, "%s%s", vex_cmp_op
[cmp_type
].name
, suffix
);
13358 ins
->mnemonicendp
+= vex_cmp_op
[cmp_type
].len
;
13362 /* We have a reserved extension byte. Output it directly. */
13363 oappend_immediate (ins
, cmp_type
);
13369 OP_Mwait (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13371 /* mwait %eax,%ecx / mwaitx %eax,%ecx,%ebx */
13372 if (!ins
->intel_syntax
)
13374 strcpy (ins
->op_out
[0], att_names32
[0] + ins
->intel_syntax
);
13375 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
13376 if (bytemode
== eBX_reg
)
13377 strcpy (ins
->op_out
[2], att_names32
[3] + ins
->intel_syntax
);
13378 ins
->two_source_ops
= true;
13380 /* Skip mod/rm byte. */
13387 OP_Monitor (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13388 int sizeflag ATTRIBUTE_UNUSED
)
13390 /* monitor %{e,r,}ax,%ecx,%edx" */
13391 if (!ins
->intel_syntax
)
13393 const char (*names
)[8] = (ins
->address_mode
== mode_64bit
13394 ? att_names64
: att_names32
);
13396 if (ins
->prefixes
& PREFIX_ADDR
)
13398 /* Remove "addr16/addr32". */
13399 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
13400 names
= (ins
->address_mode
!= mode_32bit
13401 ? att_names32
: att_names16
);
13402 ins
->used_prefixes
|= PREFIX_ADDR
;
13404 else if (ins
->address_mode
== mode_16bit
)
13405 names
= att_names16
;
13406 strcpy (ins
->op_out
[0], names
[0] + ins
->intel_syntax
);
13407 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
13408 strcpy (ins
->op_out
[2], att_names32
[2] + ins
->intel_syntax
);
13409 ins
->two_source_ops
= true;
13411 /* Skip mod/rm byte. */
13418 REP_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13420 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
13422 if (ins
->prefixes
& PREFIX_REPZ
)
13423 ins
->all_prefixes
[ins
->last_repz_prefix
] = REP_PREFIX
;
13430 return OP_IMREG (ins
, bytemode
, sizeflag
);
13432 return OP_ESreg (ins
, bytemode
, sizeflag
);
13434 return OP_DSreg (ins
, bytemode
, sizeflag
);
13443 SEP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13444 int sizeflag ATTRIBUTE_UNUSED
)
13446 if (ins
->isa64
!= amd64
)
13449 ins
->obufp
= ins
->obuf
;
13451 ins
->mnemonicendp
= ins
->obufp
;
13456 /* For BND-prefixed instructions 0xF2 prefix should be displayed as
13460 BND_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13461 int sizeflag ATTRIBUTE_UNUSED
)
13463 if (ins
->prefixes
& PREFIX_REPNZ
)
13464 ins
->all_prefixes
[ins
->last_repnz_prefix
] = BND_PREFIX
;
13468 /* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
13472 NOTRACK_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13473 int sizeflag ATTRIBUTE_UNUSED
)
13475 /* Since active_seg_prefix is not set in 64-bit mode, check whether
13476 we've seen a PREFIX_DS. */
13477 if ((ins
->prefixes
& PREFIX_DS
) != 0
13478 && (ins
->address_mode
!= mode_64bit
|| ins
->last_data_prefix
< 0))
13480 /* NOTRACK prefix is only valid on indirect branch instructions.
13481 NB: DATA prefix is unsupported for Intel64. */
13482 ins
->active_seg_prefix
= 0;
13483 ins
->all_prefixes
[ins
->last_seg_prefix
] = NOTRACK_PREFIX
;
13488 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
13489 "xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
13493 HLE_Fixup1 (instr_info
*ins
, int bytemode
, int sizeflag
)
13495 if (ins
->modrm
.mod
!= 3
13496 && (ins
->prefixes
& PREFIX_LOCK
) != 0)
13498 if (ins
->prefixes
& PREFIX_REPZ
)
13499 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13500 if (ins
->prefixes
& PREFIX_REPNZ
)
13501 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13504 return OP_E (ins
, bytemode
, sizeflag
);
13507 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
13508 "xacquire"/"xrelease" for memory operand. No check for LOCK prefix.
13512 HLE_Fixup2 (instr_info
*ins
, int bytemode
, int sizeflag
)
13514 if (ins
->modrm
.mod
!= 3)
13516 if (ins
->prefixes
& PREFIX_REPZ
)
13517 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13518 if (ins
->prefixes
& PREFIX_REPNZ
)
13519 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13522 return OP_E (ins
, bytemode
, sizeflag
);
13525 /* Similar to OP_E. But the 0xf3 prefixes should be displayed as
13526 "xrelease" for memory operand. No check for LOCK prefix. */
13529 HLE_Fixup3 (instr_info
*ins
, int bytemode
, int sizeflag
)
13531 if (ins
->modrm
.mod
!= 3
13532 && ins
->last_repz_prefix
> ins
->last_repnz_prefix
13533 && (ins
->prefixes
& PREFIX_REPZ
) != 0)
13534 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13536 return OP_E (ins
, bytemode
, sizeflag
);
13540 CMPXCHG8B_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13543 if (ins
->rex
& REX_W
)
13545 /* Change cmpxchg8b to cmpxchg16b. */
13546 char *p
= ins
->mnemonicendp
- 2;
13547 ins
->mnemonicendp
= stpcpy (p
, "16b");
13550 else if ((ins
->prefixes
& PREFIX_LOCK
) != 0)
13552 if (ins
->prefixes
& PREFIX_REPZ
)
13553 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13554 if (ins
->prefixes
& PREFIX_REPNZ
)
13555 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13558 return OP_M (ins
, bytemode
, sizeflag
);
13562 XMM_Fixup (instr_info
*ins
, int reg
, int sizeflag ATTRIBUTE_UNUSED
)
13564 const char (*names
)[8] = att_names_xmm
;
13568 switch (ins
->vex
.length
)
13573 names
= att_names_ymm
;
13579 oappend_register (ins
, names
[reg
]);
13584 FXSAVE_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13586 /* Add proper suffix to "fxsave" and "fxrstor". */
13588 if (ins
->rex
& REX_W
)
13590 char *p
= ins
->mnemonicendp
;
13594 ins
->mnemonicendp
= p
;
13596 return OP_M (ins
, bytemode
, sizeflag
);
13599 /* Display the destination register operand for instructions with
13603 OP_VEX (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13605 int reg
, modrm_reg
, sib_index
= -1;
13606 const char (*names
)[8];
13608 if (!ins
->need_vex
)
13611 if (ins
->evex_type
== evex_from_legacy
)
13613 ins
->evex_used
|= EVEX_b_used
;
13618 reg
= ins
->vex
.register_specifier
;
13619 ins
->vex
.register_specifier
= 0;
13620 if (ins
->address_mode
!= mode_64bit
)
13622 if (ins
->vex
.evex
&& !ins
->vex
.v
)
13624 oappend (ins
, "(bad)");
13630 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
13636 oappend_register (ins
, att_names_xmm
[reg
]);
13639 case vex_vsib_d_w_dq_mode
:
13640 case vex_vsib_q_w_dq_mode
:
13641 /* This must be the 3rd operand. */
13642 if (ins
->obufp
!= ins
->op_out
[2])
13644 if (ins
->vex
.length
== 128
13645 || (bytemode
!= vex_vsib_d_w_dq_mode
13647 oappend_register (ins
, att_names_xmm
[reg
]);
13649 oappend_register (ins
, att_names_ymm
[reg
]);
13651 /* All 3 XMM/YMM registers must be distinct. */
13652 modrm_reg
= ins
->modrm
.reg
;
13653 if (ins
->rex
& REX_R
)
13656 if (ins
->has_sib
&& ins
->modrm
.rm
== 4)
13658 sib_index
= ins
->sib
.index
;
13659 if (ins
->rex
& REX_X
)
13663 if (reg
== modrm_reg
|| reg
== sib_index
)
13664 strcpy (ins
->obufp
, "/(bad)");
13665 if (modrm_reg
== sib_index
|| modrm_reg
== reg
)
13666 strcat (ins
->op_out
[0], "/(bad)");
13667 if (sib_index
== modrm_reg
|| sib_index
== reg
)
13668 strcat (ins
->op_out
[1], "/(bad)");
13673 /* All 3 TMM registers must be distinct. */
13675 oappend (ins
, "(bad)");
13678 /* This must be the 3rd operand. */
13679 if (ins
->obufp
!= ins
->op_out
[2])
13681 oappend_register (ins
, att_names_tmm
[reg
]);
13682 if (reg
== ins
->modrm
.reg
|| reg
== ins
->modrm
.rm
)
13683 strcpy (ins
->obufp
, "/(bad)");
13686 if (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
13687 || ins
->modrm
.rm
== reg
)
13689 if (ins
->modrm
.reg
<= 8
13690 && (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
))
13691 strcat (ins
->op_out
[0], "/(bad)");
13692 if (ins
->modrm
.rm
<= 8
13693 && (ins
->modrm
.rm
== ins
->modrm
.reg
|| ins
->modrm
.rm
== reg
))
13694 strcat (ins
->op_out
[1], "/(bad)");
13700 switch (ins
->vex
.length
)
13706 names
= att_names_xmm
;
13707 ins
->evex_used
|= EVEX_len_used
;
13711 if (ins
->rex
& REX_W
)
13712 names
= att_names64
;
13713 else if (bytemode
== v_mode
13714 && !(sizeflag
& DFLAG
))
13715 names
= att_names16
;
13717 names
= att_names32
;
13720 names
= att_names8rex
;
13723 names
= att_names64
;
13729 oappend (ins
, "(bad)");
13732 names
= att_names_mask
;
13743 names
= att_names_ymm
;
13744 ins
->evex_used
|= EVEX_len_used
;
13750 names
= att_names_mask
;
13753 /* Fall through. */
13755 /* See PR binutils/20893 for a reproducer. */
13756 oappend (ins
, "(bad)");
13761 names
= att_names_zmm
;
13762 ins
->evex_used
|= EVEX_len_used
;
13768 oappend_register (ins
, names
[reg
]);
13773 OP_VexR (instr_info
*ins
, int bytemode
, int sizeflag
)
13775 if (ins
->modrm
.mod
== 3)
13776 return OP_VEX (ins
, bytemode
, sizeflag
);
13781 OP_VexW (instr_info
*ins
, int bytemode
, int sizeflag
)
13783 OP_VEX (ins
, bytemode
, sizeflag
);
13787 /* Swap 2nd and 3rd operands. */
13788 char *tmp
= ins
->op_out
[2];
13790 ins
->op_out
[2] = ins
->op_out
[1];
13791 ins
->op_out
[1] = tmp
;
13797 OP_REG_VexI4 (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13800 const char (*names
)[8] = att_names_xmm
;
13802 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13804 reg
= *ins
->codep
++;
13806 if (bytemode
!= x_mode
&& bytemode
!= scalar_mode
)
13810 if (ins
->address_mode
!= mode_64bit
)
13813 if (bytemode
== x_mode
&& ins
->vex
.length
== 256)
13814 names
= att_names_ymm
;
13816 oappend_register (ins
, names
[reg
]);
13820 /* Swap 3rd and 4th operands. */
13821 char *tmp
= ins
->op_out
[3];
13823 ins
->op_out
[3] = ins
->op_out
[2];
13824 ins
->op_out
[2] = tmp
;
13830 OP_VexI4 (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13831 int sizeflag ATTRIBUTE_UNUSED
)
13833 oappend_immediate (ins
, ins
->codep
[-1] & 0xf);
13838 VPCMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13839 int sizeflag ATTRIBUTE_UNUSED
)
13841 unsigned int cmp_type
;
13843 if (!ins
->vex
.evex
)
13846 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13848 cmp_type
= *ins
->codep
++;
13849 /* There are aliases for immediates 0, 1, 2, 4, 5, 6.
13850 If it's the case, print suffix, otherwise - print the immediate. */
13851 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
)
13856 char *p
= ins
->mnemonicendp
- 2;
13858 /* vpcmp* can have both one- and two-lettered suffix. */
13872 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
13873 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
13877 /* We have a reserved extension byte. Output it directly. */
13878 oappend_immediate (ins
, cmp_type
);
13883 static const struct op xop_cmp_op
[] =
13885 { STRING_COMMA_LEN ("lt") },
13886 { STRING_COMMA_LEN ("le") },
13887 { STRING_COMMA_LEN ("gt") },
13888 { STRING_COMMA_LEN ("ge") },
13889 { STRING_COMMA_LEN ("eq") },
13890 { STRING_COMMA_LEN ("neq") },
13891 { STRING_COMMA_LEN ("false") },
13892 { STRING_COMMA_LEN ("true") }
13896 VPCOM_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13897 int sizeflag ATTRIBUTE_UNUSED
)
13899 unsigned int cmp_type
;
13901 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13903 cmp_type
= *ins
->codep
++;
13904 if (cmp_type
< ARRAY_SIZE (xop_cmp_op
))
13907 char *p
= ins
->mnemonicendp
- 2;
13909 /* vpcom* can have both one- and two-lettered suffix. */
13923 sprintf (p
, "%s%s", xop_cmp_op
[cmp_type
].name
, suffix
);
13924 ins
->mnemonicendp
+= xop_cmp_op
[cmp_type
].len
;
13928 /* We have a reserved extension byte. Output it directly. */
13929 oappend_immediate (ins
, cmp_type
);
13934 static const struct op pclmul_op
[] =
13936 { STRING_COMMA_LEN ("lql") },
13937 { STRING_COMMA_LEN ("hql") },
13938 { STRING_COMMA_LEN ("lqh") },
13939 { STRING_COMMA_LEN ("hqh") }
13943 PCLMUL_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13944 int sizeflag ATTRIBUTE_UNUSED
)
13946 unsigned int pclmul_type
;
13948 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13950 pclmul_type
= *ins
->codep
++;
13951 switch (pclmul_type
)
13962 if (pclmul_type
< ARRAY_SIZE (pclmul_op
))
13965 char *p
= ins
->mnemonicendp
- 3;
13970 sprintf (p
, "%s%s", pclmul_op
[pclmul_type
].name
, suffix
);
13971 ins
->mnemonicendp
+= pclmul_op
[pclmul_type
].len
;
13975 /* We have a reserved extension byte. Output it directly. */
13976 oappend_immediate (ins
, pclmul_type
);
13982 MOVSXD_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13984 /* Add proper suffix to "movsxd". */
13985 char *p
= ins
->mnemonicendp
;
13990 if (!ins
->intel_syntax
)
13993 if (ins
->rex
& REX_W
)
14005 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
14009 ins
->mnemonicendp
= p
;
14011 return OP_E (ins
, bytemode
, sizeflag
);
14015 DistinctDest_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14017 unsigned int reg
= ins
->vex
.register_specifier
;
14018 unsigned int modrm_reg
= ins
->modrm
.reg
;
14019 unsigned int modrm_rm
= ins
->modrm
.rm
;
14021 /* Calc destination register number. */
14022 if (ins
->rex
& REX_R
)
14024 if (ins
->rex2
& REX_R
)
14027 /* Calc src1 register number. */
14028 if (ins
->address_mode
!= mode_64bit
)
14030 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
14033 /* Calc src2 register number. */
14034 if (ins
->modrm
.mod
== 3)
14036 if (ins
->rex
& REX_B
)
14038 if (ins
->rex
& REX_X
)
14042 /* Destination and source registers must be distinct, output bad if
14043 dest == src1 or dest == src2. */
14044 if (modrm_reg
== reg
14045 || (ins
->modrm
.mod
== 3
14046 && modrm_reg
== modrm_rm
))
14048 oappend (ins
, "(bad)");
14051 return OP_XMM (ins
, bytemode
, sizeflag
);
14055 OP_Rounding (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
14057 if (ins
->modrm
.mod
!= 3 || !ins
->vex
.b
)
14062 case evex_rounding_64_mode
:
14063 if (ins
->address_mode
!= mode_64bit
|| !ins
->vex
.w
)
14065 /* Fall through. */
14066 case evex_rounding_mode
:
14067 ins
->evex_used
|= EVEX_b_used
;
14068 oappend (ins
, names_rounding
[ins
->vex
.ll
]);
14070 case evex_sae_mode
:
14071 ins
->evex_used
|= EVEX_b_used
;
14072 oappend (ins
, "{");
14077 oappend (ins
, "sae}");
14082 PREFETCHI_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14084 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 5)
14086 if (ins
->intel_syntax
)
14088 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop ");
14093 if (ins
->rex
& REX_W
)
14094 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopq ");
14097 if (sizeflag
& DFLAG
)
14098 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopl ");
14100 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopw ");
14101 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
14107 return OP_M (ins
, bytemode
, sizeflag
);
14111 PUSH2_POP2_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14113 if (ins
->modrm
.mod
!= 3)
14116 unsigned int vvvv_reg
= ins
->vex
.register_specifier
14117 | (!ins
->vex
.v
<< 4);
14118 unsigned int rm_reg
= ins
->modrm
.rm
+ (ins
->rex
& REX_B
? 8 : 0)
14119 + (ins
->rex2
& REX_B
? 16 : 0);
14121 /* Push2/Pop2 cannot use RSP and Pop2 cannot pop two same registers. */
14122 if (!ins
->vex
.nd
|| vvvv_reg
== 0x4 || rm_reg
== 0x4
14123 || (!ins
->modrm
.reg
14124 && vvvv_reg
== rm_reg
))
14126 oappend (ins
, "(bad)");
14130 return OP_VEX (ins
, bytemode
, sizeflag
);
14134 JMPABS_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14136 if (ins
->last_rex2_prefix
>= 0)
14140 if ((ins
->prefixes
& (PREFIX_OPCODE
| PREFIX_ADDR
| PREFIX_LOCK
)) != 0x0
14141 || (ins
->rex
& REX_W
) != 0x0)
14143 oappend (ins
, "(bad)");
14147 if (bytemode
== eAX_reg
)
14150 if (!get64 (ins
, &op
))
14153 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "jmpabs");
14154 ins
->rex2
|= REX2_SPECIAL
;
14155 oappend_immediate (ins
, op
);
14160 if (bytemode
== eAX_reg
)
14161 return OP_IMREG (ins
, bytemode
, sizeflag
);
14162 return OP_OFF64 (ins
, bytemode
, sizeflag
);
14166 CFCMOV_Fixup (instr_info
*ins
, int opnd
, int sizeflag
)
14168 /* EVEX.NF is used as a direction bit in the 2-operand case to reverse the
14169 source and destination operands. */
14170 bool dstmem
= !ins
->vex
.nd
&& ins
->vex
.nf
;
14175 return OP_E (ins
, v_swap_mode
, sizeflag
);
14176 return OP_G (ins
, v_mode
, sizeflag
);
14179 /* These bits have been consumed and should be cleared. */
14180 ins
->vex
.nf
= false;
14181 ins
->vex
.mask_register_specifier
= 0;
14184 return OP_G (ins
, v_mode
, sizeflag
);
14185 return OP_E (ins
, v_mode
, sizeflag
);