1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988-2025 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
,
966 MOD_VEX_0F3849_X86_64_L_0_W_0
,
970 MOD_EVEX_MAP4_F8_P_1
,
971 MOD_EVEX_MAP4_F8_P_3
,
984 RM_0F1E_P_1_MOD_3_REG_7
,
985 RM_0FAE_REG_6_MOD_3_P_0
,
989 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
,
990 RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
,
996 PREFIX_0F00_REG_6_X86_64
,
997 PREFIX_0F01_REG_0_MOD_3_RM_6
,
998 PREFIX_0F01_REG_0_MOD_3_RM_7
,
999 PREFIX_0F01_REG_1_RM_2
,
1000 PREFIX_0F01_REG_1_RM_4
,
1001 PREFIX_0F01_REG_1_RM_5
,
1002 PREFIX_0F01_REG_1_RM_6
,
1003 PREFIX_0F01_REG_1_RM_7
,
1004 PREFIX_0F01_REG_3_RM_1
,
1005 PREFIX_0F01_REG_5_MOD_0
,
1006 PREFIX_0F01_REG_5_MOD_3_RM_0
,
1007 PREFIX_0F01_REG_5_MOD_3_RM_1
,
1008 PREFIX_0F01_REG_5_MOD_3_RM_2
,
1009 PREFIX_0F01_REG_5_MOD_3_RM_4
,
1010 PREFIX_0F01_REG_5_MOD_3_RM_5
,
1011 PREFIX_0F01_REG_5_MOD_3_RM_6
,
1012 PREFIX_0F01_REG_5_MOD_3_RM_7
,
1013 PREFIX_0F01_REG_7_MOD_3_RM_2
,
1014 PREFIX_0F01_REG_7_MOD_3_RM_5
,
1015 PREFIX_0F01_REG_7_MOD_3_RM_6
,
1016 PREFIX_0F01_REG_7_MOD_3_RM_7
,
1022 PREFIX_0F18_REG_6_MOD_0_X86_64
,
1023 PREFIX_0F18_REG_7_MOD_0_X86_64
,
1059 PREFIX_0FAE_REG_0_MOD_3
,
1060 PREFIX_0FAE_REG_1_MOD_3
,
1061 PREFIX_0FAE_REG_2_MOD_3
,
1062 PREFIX_0FAE_REG_3_MOD_3
,
1063 PREFIX_0FAE_REG_4_MOD_0
,
1064 PREFIX_0FAE_REG_4_MOD_3
,
1065 PREFIX_0FAE_REG_5_MOD_3
,
1066 PREFIX_0FAE_REG_6_MOD_0
,
1067 PREFIX_0FAE_REG_6_MOD_3
,
1068 PREFIX_0FAE_REG_7_MOD_0
,
1073 PREFIX_0FC7_REG_6_MOD_0
,
1074 PREFIX_0FC7_REG_6_MOD_3
,
1075 PREFIX_0FC7_REG_7_MOD_3
,
1091 PREFIX_0F38F8_M_1_X86_64
,
1101 PREFIX_VEX_0F41_L_1_W_0
,
1102 PREFIX_VEX_0F41_L_1_W_1
,
1103 PREFIX_VEX_0F42_L_1_W_0
,
1104 PREFIX_VEX_0F42_L_1_W_1
,
1105 PREFIX_VEX_0F44_L_0_W_0
,
1106 PREFIX_VEX_0F44_L_0_W_1
,
1107 PREFIX_VEX_0F45_L_1_W_0
,
1108 PREFIX_VEX_0F45_L_1_W_1
,
1109 PREFIX_VEX_0F46_L_1_W_0
,
1110 PREFIX_VEX_0F46_L_1_W_1
,
1111 PREFIX_VEX_0F47_L_1_W_0
,
1112 PREFIX_VEX_0F47_L_1_W_1
,
1113 PREFIX_VEX_0F4A_L_1_W_0
,
1114 PREFIX_VEX_0F4A_L_1_W_1
,
1115 PREFIX_VEX_0F4B_L_1_W_0
,
1116 PREFIX_VEX_0F4B_L_1_W_1
,
1121 PREFIX_VEX_0F90_L_0_W_0
,
1122 PREFIX_VEX_0F90_L_0_W_1
,
1123 PREFIX_VEX_0F91_L_0_W_0
,
1124 PREFIX_VEX_0F91_L_0_W_1
,
1125 PREFIX_VEX_0F92_L_0_W_0
,
1126 PREFIX_VEX_0F92_L_0_W_1
,
1127 PREFIX_VEX_0F93_L_0_W_0
,
1128 PREFIX_VEX_0F93_L_0_W_1
,
1129 PREFIX_VEX_0F98_L_0_W_0
,
1130 PREFIX_VEX_0F98_L_0_W_1
,
1131 PREFIX_VEX_0F99_L_0_W_0
,
1132 PREFIX_VEX_0F99_L_0_W_1
,
1133 PREFIX_VEX_0F3848_X86_64_L_0_W_0
,
1134 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
,
1135 PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
,
1136 PREFIX_VEX_0F384A_X86_64_W_0_L_0
,
1137 PREFIX_VEX_0F384B_X86_64_L_0_W_0
,
1138 PREFIX_VEX_0F3850_W_0
,
1139 PREFIX_VEX_0F3851_W_0
,
1140 PREFIX_VEX_0F385C_X86_64_L_0_W_0
,
1141 PREFIX_VEX_0F385E_X86_64_L_0_W_0
,
1142 PREFIX_VEX_0F385F_X86_64_L_0_W_0
,
1143 PREFIX_VEX_0F386B_X86_64_L_0_W_0
,
1144 PREFIX_VEX_0F386C_X86_64_L_0_W_0
,
1145 PREFIX_VEX_0F386E_X86_64_L_0_W_0
,
1146 PREFIX_VEX_0F386F_X86_64_L_0_W_0
,
1148 PREFIX_VEX_0F38B0_W_0
,
1149 PREFIX_VEX_0F38B1_W_0
,
1150 PREFIX_VEX_0F38D2_W_0
,
1151 PREFIX_VEX_0F38D3_W_0
,
1155 PREFIX_VEX_0F38DA_W_0
,
1156 PREFIX_VEX_0F38F2_L_0
,
1157 PREFIX_VEX_0F38F3_L_0
,
1158 PREFIX_VEX_0F38F5_L_0
,
1159 PREFIX_VEX_0F38F6_L_0
,
1160 PREFIX_VEX_0F38F7_L_0
,
1161 PREFIX_VEX_0F3AF0_L_0
,
1162 PREFIX_VEX_MAP5_F8_X86_64_L_0_W_0
,
1163 PREFIX_VEX_MAP5_F9_X86_64_L_0_W_0
,
1164 PREFIX_VEX_MAP5_FD_X86_64_L_0_W_0
,
1165 PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64
,
1166 PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64
,
1207 PREFIX_EVEX_0F384A_X86_64_W_0_L_2
,
1211 PREFIX_EVEX_0F386D_X86_64_W_0_L_2
,
1219 PREFIX_EVEX_0F3A07_X86_64_W_0_L_2
,
1224 PREFIX_EVEX_0F3A42_W_0
,
1231 PREFIX_EVEX_0F3A77_X86_64_W_0_L_2
,
1234 PREFIX_EVEX_MAP4_4x
,
1235 PREFIX_EVEX_MAP4_F0
,
1236 PREFIX_EVEX_MAP4_F1
,
1237 PREFIX_EVEX_MAP4_F2
,
1238 PREFIX_EVEX_MAP4_F8
,
1240 PREFIX_EVEX_MAP5_10
,
1241 PREFIX_EVEX_MAP5_11
,
1242 PREFIX_EVEX_MAP5_18
,
1243 PREFIX_EVEX_MAP5_1B
,
1244 PREFIX_EVEX_MAP5_1D
,
1245 PREFIX_EVEX_MAP5_1E
,
1246 PREFIX_EVEX_MAP5_2A
,
1247 PREFIX_EVEX_MAP5_2C
,
1248 PREFIX_EVEX_MAP5_2D
,
1249 PREFIX_EVEX_MAP5_2E
,
1250 PREFIX_EVEX_MAP5_2F
,
1251 PREFIX_EVEX_MAP5_51
,
1252 PREFIX_EVEX_MAP5_58
,
1253 PREFIX_EVEX_MAP5_59
,
1254 PREFIX_EVEX_MAP5_5A
,
1255 PREFIX_EVEX_MAP5_5B
,
1256 PREFIX_EVEX_MAP5_5C
,
1257 PREFIX_EVEX_MAP5_5D
,
1258 PREFIX_EVEX_MAP5_5E
,
1259 PREFIX_EVEX_MAP5_5F
,
1260 PREFIX_EVEX_MAP5_68
,
1261 PREFIX_EVEX_MAP5_69
,
1262 PREFIX_EVEX_MAP5_6A
,
1263 PREFIX_EVEX_MAP5_6B
,
1264 PREFIX_EVEX_MAP5_6C
,
1265 PREFIX_EVEX_MAP5_6D
,
1266 PREFIX_EVEX_MAP5_6E_L_0
,
1267 PREFIX_EVEX_MAP5_6F_X86_64
,
1268 PREFIX_EVEX_MAP5_74
,
1269 PREFIX_EVEX_MAP5_78
,
1270 PREFIX_EVEX_MAP5_79
,
1271 PREFIX_EVEX_MAP5_7A
,
1272 PREFIX_EVEX_MAP5_7B
,
1273 PREFIX_EVEX_MAP5_7C
,
1274 PREFIX_EVEX_MAP5_7D
,
1275 PREFIX_EVEX_MAP5_7E_L_0
,
1277 PREFIX_EVEX_MAP6_13
,
1278 PREFIX_EVEX_MAP6_2C
,
1279 PREFIX_EVEX_MAP6_42
,
1280 PREFIX_EVEX_MAP6_4C
,
1281 PREFIX_EVEX_MAP6_4E
,
1282 PREFIX_EVEX_MAP6_56
,
1283 PREFIX_EVEX_MAP6_57
,
1284 PREFIX_EVEX_MAP6_98
,
1285 PREFIX_EVEX_MAP6_9A
,
1286 PREFIX_EVEX_MAP6_9C
,
1287 PREFIX_EVEX_MAP6_9E
,
1288 PREFIX_EVEX_MAP6_A8
,
1289 PREFIX_EVEX_MAP6_AA
,
1290 PREFIX_EVEX_MAP6_AC
,
1291 PREFIX_EVEX_MAP6_AE
,
1292 PREFIX_EVEX_MAP6_B8
,
1293 PREFIX_EVEX_MAP6_BA
,
1294 PREFIX_EVEX_MAP6_BC
,
1295 PREFIX_EVEX_MAP6_BE
,
1296 PREFIX_EVEX_MAP6_D6
,
1297 PREFIX_EVEX_MAP6_D7
,
1333 X86_64_0F01_REG_0_MOD_3_RM_6_P_1
,
1334 X86_64_0F01_REG_0_MOD_3_RM_6_P_3
,
1335 X86_64_0F01_REG_0_MOD_3_RM_7_P_0
,
1337 X86_64_0F01_REG_1_RM_2_PREFIX_1
,
1338 X86_64_0F01_REG_1_RM_2_PREFIX_3
,
1339 X86_64_0F01_REG_1_RM_5_PREFIX_2
,
1340 X86_64_0F01_REG_1_RM_6_PREFIX_2
,
1341 X86_64_0F01_REG_1_RM_7_PREFIX_2
,
1344 X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
,
1345 X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
,
1346 X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
,
1347 X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
,
1348 X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
,
1349 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
,
1350 X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
,
1351 X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
,
1352 X86_64_0F18_REG_6_MOD_0
,
1353 X86_64_0F18_REG_7_MOD_0
,
1359 X86_64_0FC7_REG_6_MOD_3_PREFIX_1
,
1377 X86_64_VEX_MAP7_F6_L_0_W_0_R_0
,
1378 X86_64_VEX_MAP7_F8_L_0_W_0_R_0
,
1385 X86_64_EVEX_MAP5_6F
,
1390 THREE_BYTE_0F38
= 0,
1423 VEX_LEN_0F12_P_0
= 0,
1456 VEX_LEN_0F3848_X86_64
,
1457 VEX_LEN_0F3849_X86_64
,
1458 VEX_LEN_0F384A_X86_64_W_0
,
1459 VEX_LEN_0F384B_X86_64
,
1461 VEX_LEN_0F385C_X86_64
,
1462 VEX_LEN_0F385E_X86_64
,
1463 VEX_LEN_0F385F_X86_64
,
1464 VEX_LEN_0F386B_X86_64
,
1465 VEX_LEN_0F386C_X86_64
,
1466 VEX_LEN_0F386E_X86_64
,
1467 VEX_LEN_0F386F_X86_64
,
1468 VEX_LEN_0F38CB_P_3_W_0
,
1469 VEX_LEN_0F38CC_P_3_W_0
,
1470 VEX_LEN_0F38CD_P_3_W_0
,
1471 VEX_LEN_0F38DA_W_0_P_0
,
1472 VEX_LEN_0F38DA_W_0_P_2
,
1506 VEX_LEN_MAP5_F8_X86_64
,
1507 VEX_LEN_MAP5_F9_X86_64
,
1508 VEX_LEN_MAP5_FD_X86_64
,
1539 VEX_LEN_XOP_09_82_W_0
,
1540 VEX_LEN_XOP_09_83_W_0
,
1573 EVEX_LEN_0F7E_P_1_W_0
= 0,
1574 EVEX_LEN_0FD6_P_2_W_0
,
1580 EVEX_LEN_0F384A_X86_64_W_0
,
1583 EVEX_LEN_0F386D_X86_64_W_0
,
1588 EVEX_LEN_0F3A07_X86_64_W_0
,
1599 EVEX_LEN_0F3A77_X86_64_W_0
,
1636 VEX_W_0F3848_X86_64_L_0
,
1637 VEX_W_0F3849_X86_64_L_0
,
1638 VEX_W_0F384A_X86_64
,
1639 VEX_W_0F384B_X86_64_L_0
,
1647 VEX_W_0F385C_X86_64_L_0
,
1648 VEX_W_0F385E_X86_64_L_0
,
1649 VEX_W_0F385F_X86_64_L_0
,
1650 VEX_W_0F386B_X86_64_L_0
,
1651 VEX_W_0F386C_X86_64_L_0
,
1652 VEX_W_0F386E_X86_64_L_0
,
1653 VEX_W_0F386F_X86_64_L_0
,
1686 VEX_W_MAP5_F8_X86_64_L_0
,
1687 VEX_W_MAP5_F9_X86_64_L_0
,
1688 VEX_W_MAP5_FD_X86_64_L_0
,
1692 VEX_W_XOP_08_85_L_0
,
1693 VEX_W_XOP_08_86_L_0
,
1694 VEX_W_XOP_08_87_L_0
,
1695 VEX_W_XOP_08_8E_L_0
,
1696 VEX_W_XOP_08_8F_L_0
,
1697 VEX_W_XOP_08_95_L_0
,
1698 VEX_W_XOP_08_96_L_0
,
1699 VEX_W_XOP_08_97_L_0
,
1700 VEX_W_XOP_08_9E_L_0
,
1701 VEX_W_XOP_08_9F_L_0
,
1702 VEX_W_XOP_08_A6_L_0
,
1703 VEX_W_XOP_08_B6_L_0
,
1704 VEX_W_XOP_08_C0_L_0
,
1705 VEX_W_XOP_08_C1_L_0
,
1706 VEX_W_XOP_08_C2_L_0
,
1707 VEX_W_XOP_08_C3_L_0
,
1708 VEX_W_XOP_08_CC_L_0
,
1709 VEX_W_XOP_08_CD_L_0
,
1710 VEX_W_XOP_08_CE_L_0
,
1711 VEX_W_XOP_08_CF_L_0
,
1712 VEX_W_XOP_08_EC_L_0
,
1713 VEX_W_XOP_08_ED_L_0
,
1714 VEX_W_XOP_08_EE_L_0
,
1715 VEX_W_XOP_08_EF_L_0
,
1721 VEX_W_XOP_09_C1_L_0
,
1722 VEX_W_XOP_09_C2_L_0
,
1723 VEX_W_XOP_09_C3_L_0
,
1724 VEX_W_XOP_09_C6_L_0
,
1725 VEX_W_XOP_09_C7_L_0
,
1726 VEX_W_XOP_09_CB_L_0
,
1727 VEX_W_XOP_09_D1_L_0
,
1728 VEX_W_XOP_09_D2_L_0
,
1729 VEX_W_XOP_09_D3_L_0
,
1730 VEX_W_XOP_09_D6_L_0
,
1731 VEX_W_XOP_09_D7_L_0
,
1732 VEX_W_XOP_09_DB_L_0
,
1733 VEX_W_XOP_09_E1_L_0
,
1734 VEX_W_XOP_09_E2_L_0
,
1735 VEX_W_XOP_09_E3_L_0
,
1815 EVEX_W_0F384A_X86_64
,
1819 EVEX_W_0F386D_X86_64
,
1826 EVEX_W_0F3A07_X86_64
,
1841 EVEX_W_0F3A77_X86_64
,
1844 EVEX_W_MAP4_F8_P1_M_1
,
1845 EVEX_W_MAP4_F8_P3_M_1
,
1858 typedef bool (*op_rtn
) (instr_info
*ins
, int bytemode
, int sizeflag
);
1867 unsigned int prefix_requirement
;
1870 /* Upper case letters in the instruction names here are macros.
1871 'A' => print 'b' if no (suitable) register operand or suffix_always is true
1872 'B' => print 'b' if suffix_always is true
1873 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
1875 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
1876 suffix_always is true
1877 'E' => print 'e' if 32-bit form of jcxz
1878 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
1879 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
1880 'H' => print ",pt" or ",pn" branch hint
1883 'K' => print 'd' or 'q' if rex prefix is present.
1884 'L' => print 'l' or 'q' if suffix_always is true
1885 'M' => print 'r' if intel_mnemonic is false.
1886 'N' => print 'n' if instruction has no wait "prefix"
1887 'O' => print 'd' or 'o' (or 'q' in Intel mode)
1888 'P' => behave as 'T' except with register operand outside of suffix_always
1890 'Q' => print 'w', 'l' or 'q' if no (suitable) register operand or
1891 suffix_always is true
1892 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
1893 'S' => print 'w', 'l' or 'q' if suffix_always is true
1894 'T' => print 'w', 'l'/'d', or 'q' if instruction has an operand size
1895 prefix or if suffix_always is true.
1897 'V' => print 'v' for VEX/EVEX and nothing for legacy encodings.
1898 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
1899 'X' => print 's', 'd' depending on data16 prefix (for XMM)
1900 'Y' => no output, mark EVEX.aaa != 0 as bad.
1901 'Z' => print 'q' in 64bit mode and 'l' otherwise, if suffix_always is true.
1902 '!' => change condition from true to false or from false to true.
1903 '%' => add 1 upper case letter to the macro.
1904 '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
1905 prefix or suffix_always is true (lcall/ljmp).
1906 '@' => in 64bit mode for Intel64 ISA or if instruction
1907 has no operand sizing prefix, print 'q' if suffix_always is true or
1908 nothing otherwise; behave as 'P' in all other cases
1910 2 upper case letter macros:
1911 "CC" => print condition code
1912 "XY" => print 'x' or 'y' if suffix_always is true or no register
1913 operands and no broadcast.
1914 "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
1915 register operands and no broadcast.
1916 "XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
1917 "XD" => print 'd' if !EVEX or EVEX.W=1, EVEX.W=0 is not a valid encoding
1918 "XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
1919 "XB" => print 'bf16' if EVEX.W=0, EVEX.W=1 is not a valid encoding
1921 "XS" => print 's' if !EVEX or EVEX.W=0, EVEX.W=1 is not a valid encoding
1922 "XV" => print "{vex} " pseudo prefix
1923 "XE" => print "{evex} " pseudo prefix if no EVEX-specific functionality is
1924 is used by an EVEX-encoded (AVX512VL) instruction.
1925 "ME" => Similar to "XE", but only print "{evex} " when there is no
1927 "NF" => print "{nf} " pseudo prefix when EVEX.NF = 1 and print "{evex} "
1928 pseudo prefix when instructions without NF, EGPR and VVVV,
1929 "NE" => don't print "{evex} " pseudo prefix for some special instructions
1931 "ZU" => print 'zu' if EVEX.ZU=1.
1932 "SC" => print suffix SCC for SCC insns
1933 "YK" keep unused, to avoid ambiguity with the combined use of Y and K.
1934 "YX" keep unused, to avoid ambiguity with the combined use of Y and X.
1935 "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
1936 being false, or no operand at all in 64bit mode, or if suffix_always
1938 "LB" => print "abs" in 64bit mode and behave as 'B' otherwise
1939 "LS" => print "abs" in 64bit mode and behave as 'S' otherwise
1940 "LV" => print "abs" for 64bit operand and behave as 'S' otherwise
1941 "DQ" => print 'd' or 'q' depending on the VEX.W bit
1942 "DF" => print default flag value for SCC insns
1943 "BW" => print 'b' or 'w' depending on the VEX.W bit
1944 "LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has
1945 an operand size prefix, or suffix_always is true. print
1946 'q' if rex prefix is present.
1948 Many of the above letters print nothing in Intel mode. See "putop"
1951 Braces '{' and '}', and vertical bars '|', indicate alternative
1952 mnemonic strings for AT&T and Intel. */
1954 static const struct dis386 dis386
[] = {
1956 { "addB", { Ebh1
, Gb
}, 0 },
1957 { "addS", { Evh1
, Gv
}, 0 },
1958 { "addB", { Gb
, EbS
}, 0 },
1959 { "addS", { Gv
, EvS
}, 0 },
1960 { "addB", { AL
, Ib
}, 0 },
1961 { "addS", { eAX
, Iv
}, 0 },
1962 { X86_64_TABLE (X86_64_06
) },
1963 { X86_64_TABLE (X86_64_07
) },
1965 { "orB", { Ebh1
, Gb
}, 0 },
1966 { "orS", { Evh1
, Gv
}, 0 },
1967 { "orB", { Gb
, EbS
}, 0 },
1968 { "orS", { Gv
, EvS
}, 0 },
1969 { "orB", { AL
, Ib
}, 0 },
1970 { "orS", { eAX
, Iv
}, 0 },
1971 { X86_64_TABLE (X86_64_0E
) },
1972 { Bad_Opcode
}, /* 0x0f extended opcode escape */
1974 { "adcB", { Ebh1
, Gb
}, 0 },
1975 { "adcS", { Evh1
, Gv
}, 0 },
1976 { "adcB", { Gb
, EbS
}, 0 },
1977 { "adcS", { Gv
, EvS
}, 0 },
1978 { "adcB", { AL
, Ib
}, 0 },
1979 { "adcS", { eAX
, Iv
}, 0 },
1980 { X86_64_TABLE (X86_64_16
) },
1981 { X86_64_TABLE (X86_64_17
) },
1983 { "sbbB", { Ebh1
, Gb
}, 0 },
1984 { "sbbS", { Evh1
, Gv
}, 0 },
1985 { "sbbB", { Gb
, EbS
}, 0 },
1986 { "sbbS", { Gv
, EvS
}, 0 },
1987 { "sbbB", { AL
, Ib
}, 0 },
1988 { "sbbS", { eAX
, Iv
}, 0 },
1989 { X86_64_TABLE (X86_64_1E
) },
1990 { X86_64_TABLE (X86_64_1F
) },
1992 { "andB", { Ebh1
, Gb
}, 0 },
1993 { "andS", { Evh1
, Gv
}, 0 },
1994 { "andB", { Gb
, EbS
}, 0 },
1995 { "andS", { Gv
, EvS
}, 0 },
1996 { "andB", { AL
, Ib
}, 0 },
1997 { "andS", { eAX
, Iv
}, 0 },
1998 { Bad_Opcode
}, /* SEG ES prefix */
1999 { X86_64_TABLE (X86_64_27
) },
2001 { "subB", { Ebh1
, Gb
}, 0 },
2002 { "subS", { Evh1
, Gv
}, 0 },
2003 { "subB", { Gb
, EbS
}, 0 },
2004 { "subS", { Gv
, EvS
}, 0 },
2005 { "subB", { AL
, Ib
}, 0 },
2006 { "subS", { eAX
, Iv
}, 0 },
2007 { Bad_Opcode
}, /* SEG CS prefix */
2008 { X86_64_TABLE (X86_64_2F
) },
2010 { "xorB", { Ebh1
, Gb
}, 0 },
2011 { "xorS", { Evh1
, Gv
}, 0 },
2012 { "xorB", { Gb
, EbS
}, 0 },
2013 { "xorS", { Gv
, EvS
}, 0 },
2014 { "xorB", { AL
, Ib
}, 0 },
2015 { "xorS", { eAX
, Iv
}, 0 },
2016 { Bad_Opcode
}, /* SEG SS prefix */
2017 { X86_64_TABLE (X86_64_37
) },
2019 { "cmpB", { Eb
, Gb
}, 0 },
2020 { "cmpS", { Ev
, Gv
}, 0 },
2021 { "cmpB", { Gb
, EbS
}, 0 },
2022 { "cmpS", { Gv
, EvS
}, 0 },
2023 { "cmpB", { AL
, Ib
}, 0 },
2024 { "cmpS", { eAX
, Iv
}, 0 },
2025 { Bad_Opcode
}, /* SEG DS prefix */
2026 { X86_64_TABLE (X86_64_3F
) },
2028 { "inc{S|}", { RMeAX
}, 0 },
2029 { "inc{S|}", { RMeCX
}, 0 },
2030 { "inc{S|}", { RMeDX
}, 0 },
2031 { "inc{S|}", { RMeBX
}, 0 },
2032 { "inc{S|}", { RMeSP
}, 0 },
2033 { "inc{S|}", { RMeBP
}, 0 },
2034 { "inc{S|}", { RMeSI
}, 0 },
2035 { "inc{S|}", { RMeDI
}, 0 },
2037 { "dec{S|}", { RMeAX
}, 0 },
2038 { "dec{S|}", { RMeCX
}, 0 },
2039 { "dec{S|}", { RMeDX
}, 0 },
2040 { "dec{S|}", { RMeBX
}, 0 },
2041 { "dec{S|}", { RMeSP
}, 0 },
2042 { "dec{S|}", { RMeBP
}, 0 },
2043 { "dec{S|}", { RMeSI
}, 0 },
2044 { "dec{S|}", { RMeDI
}, 0 },
2046 { "push!P", { RMrAX
}, 0 },
2047 { "push!P", { RMrCX
}, 0 },
2048 { "push!P", { RMrDX
}, 0 },
2049 { "push!P", { RMrBX
}, 0 },
2050 { "push!P", { RMrSP
}, 0 },
2051 { "push!P", { RMrBP
}, 0 },
2052 { "push!P", { RMrSI
}, 0 },
2053 { "push!P", { RMrDI
}, 0 },
2055 { "pop!P", { RMrAX
}, 0 },
2056 { "pop!P", { RMrCX
}, 0 },
2057 { "pop!P", { RMrDX
}, 0 },
2058 { "pop!P", { RMrBX
}, 0 },
2059 { "pop!P", { RMrSP
}, 0 },
2060 { "pop!P", { RMrBP
}, 0 },
2061 { "pop!P", { RMrSI
}, 0 },
2062 { "pop!P", { RMrDI
}, 0 },
2064 { X86_64_TABLE (X86_64_60
) },
2065 { X86_64_TABLE (X86_64_61
) },
2066 { X86_64_TABLE (X86_64_62
) },
2067 { X86_64_TABLE (X86_64_63
) },
2068 { Bad_Opcode
}, /* seg fs */
2069 { Bad_Opcode
}, /* seg gs */
2070 { Bad_Opcode
}, /* op size prefix */
2071 { Bad_Opcode
}, /* adr size prefix */
2073 { "pushP", { sIv
}, 0 },
2074 { "imulS", { Gv
, Ev
, Iv
}, 0 },
2075 { "pushP", { sIbT
}, 0 },
2076 { "imulS", { Gv
, Ev
, sIb
}, 0 },
2077 { "ins{b|}", { Ybr
, indirDX
}, 0 },
2078 { X86_64_TABLE (X86_64_6D
) },
2079 { "outs{b|}", { indirDXr
, Xb
}, 0 },
2080 { X86_64_TABLE (X86_64_6F
) },
2082 { "joH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2083 { "jnoH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2084 { "jbH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2085 { "jaeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2086 { "jeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2087 { "jneH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2088 { "jbeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2089 { "jaH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2091 { "jsH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2092 { "jnsH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2093 { "jpH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2094 { "jnpH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2095 { "jlH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2096 { "jgeH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2097 { "jleH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2098 { "jgH", { Jb
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2100 { REG_TABLE (REG_80
) },
2101 { REG_TABLE (REG_81
) },
2102 { X86_64_TABLE (X86_64_82
) },
2103 { REG_TABLE (REG_83
) },
2104 { "testB", { Eb
, Gb
}, 0 },
2105 { "testS", { Ev
, Gv
}, 0 },
2106 { "xchgB", { Ebh2
, Gb
}, 0 },
2107 { "xchgS", { Evh2
, Gv
}, 0 },
2109 { "movB", { Ebh3
, Gb
}, 0 },
2110 { "movS", { Evh3
, Gv
}, 0 },
2111 { "movB", { Gb
, EbS
}, 0 },
2112 { "movS", { Gv
, EvS
}, 0 },
2113 { "movD", { Sv
, Sw
}, 0 },
2114 { "leaS", { Gv
, M
}, 0 },
2115 { "movD", { Sw
, Sv
}, 0 },
2116 { REG_TABLE (REG_8F
) },
2118 { PREFIX_TABLE (PREFIX_90
) },
2119 { "xchgS", { RMeCX
, eAX
}, 0 },
2120 { "xchgS", { RMeDX
, eAX
}, 0 },
2121 { "xchgS", { RMeBX
, eAX
}, 0 },
2122 { "xchgS", { RMeSP
, eAX
}, 0 },
2123 { "xchgS", { RMeBP
, eAX
}, 0 },
2124 { "xchgS", { RMeSI
, eAX
}, 0 },
2125 { "xchgS", { RMeDI
, eAX
}, 0 },
2127 { "cW{t|}R", { XX
}, 0 },
2128 { "cR{t|}O", { XX
}, 0 },
2129 { X86_64_TABLE (X86_64_9A
) },
2130 { Bad_Opcode
}, /* fwait */
2131 { "pushfP", { XX
}, 0 },
2132 { "popfP", { XX
}, 0 },
2133 { "sahf", { XX
}, 0 },
2134 { "lahf", { XX
}, 0 },
2136 { "mov%LB", { AL
, Ob
}, PREFIX_REX2_ILLEGAL
},
2137 { "mov%LS", { { JMPABS_Fixup
, eAX_reg
}, { JMPABS_Fixup
, v_mode
} }, PREFIX_REX2_ILLEGAL
},
2138 { "mov%LB", { Ob
, AL
}, PREFIX_REX2_ILLEGAL
},
2139 { "mov%LS", { Ov
, eAX
}, PREFIX_REX2_ILLEGAL
},
2140 { "movs{b|}", { Ybr
, Xb
}, PREFIX_REX2_ILLEGAL
},
2141 { "movs{R|}", { Yvr
, Xv
}, PREFIX_REX2_ILLEGAL
},
2142 { "cmps{b|}", { Xb
, Yb
}, PREFIX_REX2_ILLEGAL
},
2143 { "cmps{R|}", { Xv
, Yv
}, PREFIX_REX2_ILLEGAL
},
2145 { "testB", { AL
, Ib
}, PREFIX_REX2_ILLEGAL
},
2146 { "testS", { eAX
, Iv
}, PREFIX_REX2_ILLEGAL
},
2147 { "stosB", { Ybr
, AL
}, PREFIX_REX2_ILLEGAL
},
2148 { "stosS", { Yvr
, eAX
}, PREFIX_REX2_ILLEGAL
},
2149 { "lodsB", { ALr
, Xb
}, PREFIX_REX2_ILLEGAL
},
2150 { "lodsS", { eAXr
, Xv
}, PREFIX_REX2_ILLEGAL
},
2151 { "scasB", { AL
, Yb
}, PREFIX_REX2_ILLEGAL
},
2152 { "scasS", { eAX
, Yv
}, PREFIX_REX2_ILLEGAL
},
2154 { "movB", { RMAL
, Ib
}, 0 },
2155 { "movB", { RMCL
, Ib
}, 0 },
2156 { "movB", { RMDL
, Ib
}, 0 },
2157 { "movB", { RMBL
, Ib
}, 0 },
2158 { "movB", { RMAH
, Ib
}, 0 },
2159 { "movB", { RMCH
, Ib
}, 0 },
2160 { "movB", { RMDH
, Ib
}, 0 },
2161 { "movB", { RMBH
, Ib
}, 0 },
2163 { "mov%LV", { RMeAX
, Iv64
}, 0 },
2164 { "mov%LV", { RMeCX
, Iv64
}, 0 },
2165 { "mov%LV", { RMeDX
, Iv64
}, 0 },
2166 { "mov%LV", { RMeBX
, Iv64
}, 0 },
2167 { "mov%LV", { RMeSP
, Iv64
}, 0 },
2168 { "mov%LV", { RMeBP
, Iv64
}, 0 },
2169 { "mov%LV", { RMeSI
, Iv64
}, 0 },
2170 { "mov%LV", { RMeDI
, Iv64
}, 0 },
2172 { REG_TABLE (REG_C0
) },
2173 { REG_TABLE (REG_C1
) },
2174 { X86_64_TABLE (X86_64_C2
) },
2175 { X86_64_TABLE (X86_64_C3
) },
2176 { X86_64_TABLE (X86_64_C4
) },
2177 { X86_64_TABLE (X86_64_C5
) },
2178 { REG_TABLE (REG_C6
) },
2179 { REG_TABLE (REG_C7
) },
2181 { "enterP", { Iw
, Ib
}, 0 },
2182 { "leaveP", { XX
}, 0 },
2183 { "{l|}ret{|f}%LP", { Iw
}, 0 },
2184 { "{l|}ret{|f}%LP", { XX
}, 0 },
2185 { "int3", { XX
}, 0 },
2186 { "int", { Ib
}, 0 },
2187 { X86_64_TABLE (X86_64_CE
) },
2188 { "iret%LP", { XX
}, 0 },
2190 { REG_TABLE (REG_D0
) },
2191 { REG_TABLE (REG_D1
) },
2192 { REG_TABLE (REG_D2
) },
2193 { REG_TABLE (REG_D3
) },
2194 { X86_64_TABLE (X86_64_D4
) },
2195 { X86_64_TABLE (X86_64_D5
) },
2197 { "xlat", { DSBX
}, 0 },
2208 { "loopneFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2209 { "loopeFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2210 { "loopFH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2211 { "jEcxzH", { Jb
, XX
, loop_jcxz_flag
}, PREFIX_REX2_ILLEGAL
},
2212 { "inB", { AL
, Ib
}, PREFIX_REX2_ILLEGAL
},
2213 { "inG", { zAX
, Ib
}, PREFIX_REX2_ILLEGAL
},
2214 { "outB", { Ib
, AL
}, PREFIX_REX2_ILLEGAL
},
2215 { "outG", { Ib
, zAX
}, PREFIX_REX2_ILLEGAL
},
2217 { X86_64_TABLE (X86_64_E8
) },
2218 { X86_64_TABLE (X86_64_E9
) },
2219 { X86_64_TABLE (X86_64_EA
) },
2220 { "jmp", { Jb
, BND
}, PREFIX_REX2_ILLEGAL
},
2221 { "inB", { AL
, indirDX
}, PREFIX_REX2_ILLEGAL
},
2222 { "inG", { zAX
, indirDX
}, PREFIX_REX2_ILLEGAL
},
2223 { "outB", { indirDX
, AL
}, PREFIX_REX2_ILLEGAL
},
2224 { "outG", { indirDX
, zAX
}, PREFIX_REX2_ILLEGAL
},
2226 { Bad_Opcode
}, /* lock prefix */
2227 { "int1", { XX
}, 0 },
2228 { Bad_Opcode
}, /* repne */
2229 { Bad_Opcode
}, /* repz */
2230 { "hlt", { XX
}, 0 },
2231 { "cmc", { XX
}, 0 },
2232 { REG_TABLE (REG_F6
) },
2233 { REG_TABLE (REG_F7
) },
2235 { "clc", { XX
}, 0 },
2236 { "stc", { XX
}, 0 },
2237 { "cli", { XX
}, 0 },
2238 { "sti", { XX
}, 0 },
2239 { "cld", { XX
}, 0 },
2240 { "std", { XX
}, 0 },
2241 { REG_TABLE (REG_FE
) },
2242 { REG_TABLE (REG_FF
) },
2245 static const struct dis386 dis386_twobyte
[] = {
2247 { REG_TABLE (REG_0F00
) },
2248 { REG_TABLE (REG_0F01
) },
2249 { "larS", { Gv
, Sv
}, 0 },
2250 { "lslS", { Gv
, Sv
}, 0 },
2252 { "syscall", { XX
}, 0 },
2253 { "clts", { XX
}, 0 },
2254 { "sysret%LQ", { XX
}, 0 },
2256 { "invd", { XX
}, 0 },
2257 { PREFIX_TABLE (PREFIX_0F09
) },
2259 { "ud2", { XX
}, 0 },
2261 { REG_TABLE (REG_0F0D
) },
2262 { "femms", { XX
}, 0 },
2263 { "", { MX
, EM
, OPSUF
}, 0 }, /* See OP_3DNowSuffix. */
2265 { PREFIX_TABLE (PREFIX_0F10
) },
2266 { PREFIX_TABLE (PREFIX_0F11
) },
2267 { PREFIX_TABLE (PREFIX_0F12
) },
2268 { "movlpX", { Mq
, XM
}, PREFIX_OPCODE
},
2269 { "unpcklpX", { XM
, EXx
}, PREFIX_OPCODE
},
2270 { "unpckhpX", { XM
, EXx
}, PREFIX_OPCODE
},
2271 { PREFIX_TABLE (PREFIX_0F16
) },
2272 { "movhpX", { Mq
, XM
}, PREFIX_OPCODE
},
2274 { REG_TABLE (REG_0F18
) },
2275 { "nopQ", { Ev
}, 0 },
2276 { PREFIX_TABLE (PREFIX_0F1A
) },
2277 { PREFIX_TABLE (PREFIX_0F1B
) },
2278 { PREFIX_TABLE (PREFIX_0F1C
) },
2279 { "nopQ", { Ev
}, 0 },
2280 { PREFIX_TABLE (PREFIX_0F1E
) },
2281 { "nopQ", { Ev
}, 0 },
2283 { "movZ", { Em
, Cm
}, 0 },
2284 { "movZ", { Em
, Dm
}, 0 },
2285 { "movZ", { Cm
, Em
}, 0 },
2286 { "movZ", { Dm
, Em
}, 0 },
2287 { X86_64_TABLE (X86_64_0F24
) },
2289 { X86_64_TABLE (X86_64_0F26
) },
2292 { "movapX", { XM
, EXx
}, PREFIX_OPCODE
},
2293 { "movapX", { EXxS
, XM
}, PREFIX_OPCODE
},
2294 { PREFIX_TABLE (PREFIX_0F2A
) },
2295 { PREFIX_TABLE (PREFIX_0F2B
) },
2296 { PREFIX_TABLE (PREFIX_0F2C
) },
2297 { PREFIX_TABLE (PREFIX_0F2D
) },
2298 { PREFIX_TABLE (PREFIX_0F2E
) },
2299 { PREFIX_TABLE (PREFIX_0F2F
) },
2301 { "wrmsr", { XX
}, PREFIX_REX2_ILLEGAL
},
2302 { "rdtsc", { XX
}, PREFIX_REX2_ILLEGAL
},
2303 { "rdmsr", { XX
}, PREFIX_REX2_ILLEGAL
},
2304 { "rdpmc", { XX
}, PREFIX_REX2_ILLEGAL
},
2305 { "sysenter", { SEP
}, PREFIX_REX2_ILLEGAL
},
2306 { "sysexit%LQ", { SEP
}, PREFIX_REX2_ILLEGAL
},
2308 { "getsec", { XX
}, 0 },
2310 { THREE_BYTE_TABLE (THREE_BYTE_0F38
) },
2312 { THREE_BYTE_TABLE (THREE_BYTE_0F3A
) },
2319 { "cmovoS", { Gv
, Ev
}, 0 },
2320 { "cmovnoS", { Gv
, Ev
}, 0 },
2321 { "cmovbS", { Gv
, Ev
}, 0 },
2322 { "cmovaeS", { Gv
, Ev
}, 0 },
2323 { "cmoveS", { Gv
, Ev
}, 0 },
2324 { "cmovneS", { Gv
, Ev
}, 0 },
2325 { "cmovbeS", { Gv
, Ev
}, 0 },
2326 { "cmovaS", { Gv
, Ev
}, 0 },
2328 { "cmovsS", { Gv
, Ev
}, 0 },
2329 { "cmovnsS", { Gv
, Ev
}, 0 },
2330 { "cmovpS", { Gv
, Ev
}, 0 },
2331 { "cmovnpS", { Gv
, Ev
}, 0 },
2332 { "cmovlS", { Gv
, Ev
}, 0 },
2333 { "cmovgeS", { Gv
, Ev
}, 0 },
2334 { "cmovleS", { Gv
, Ev
}, 0 },
2335 { "cmovgS", { Gv
, Ev
}, 0 },
2337 { "movmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
2338 { PREFIX_TABLE (PREFIX_0F51
) },
2339 { PREFIX_TABLE (PREFIX_0F52
) },
2340 { PREFIX_TABLE (PREFIX_0F53
) },
2341 { "andpX", { XM
, EXx
}, PREFIX_OPCODE
},
2342 { "andnpX", { XM
, EXx
}, PREFIX_OPCODE
},
2343 { "orpX", { XM
, EXx
}, PREFIX_OPCODE
},
2344 { "xorpX", { XM
, EXx
}, PREFIX_OPCODE
},
2346 { PREFIX_TABLE (PREFIX_0F58
) },
2347 { PREFIX_TABLE (PREFIX_0F59
) },
2348 { PREFIX_TABLE (PREFIX_0F5A
) },
2349 { PREFIX_TABLE (PREFIX_0F5B
) },
2350 { PREFIX_TABLE (PREFIX_0F5C
) },
2351 { PREFIX_TABLE (PREFIX_0F5D
) },
2352 { PREFIX_TABLE (PREFIX_0F5E
) },
2353 { PREFIX_TABLE (PREFIX_0F5F
) },
2355 { PREFIX_TABLE (PREFIX_0F60
) },
2356 { PREFIX_TABLE (PREFIX_0F61
) },
2357 { PREFIX_TABLE (PREFIX_0F62
) },
2358 { "packsswb", { MX
, EM
}, PREFIX_OPCODE
},
2359 { "pcmpgtb", { MX
, EM
}, PREFIX_OPCODE
},
2360 { "pcmpgtw", { MX
, EM
}, PREFIX_OPCODE
},
2361 { "pcmpgtd", { MX
, EM
}, PREFIX_OPCODE
},
2362 { "packuswb", { MX
, EM
}, PREFIX_OPCODE
},
2364 { "punpckhbw", { MX
, EM
}, PREFIX_OPCODE
},
2365 { "punpckhwd", { MX
, EM
}, PREFIX_OPCODE
},
2366 { "punpckhdq", { MX
, EM
}, PREFIX_OPCODE
},
2367 { "packssdw", { MX
, EM
}, PREFIX_OPCODE
},
2368 { "punpcklqdq", { XM
, EXx
}, PREFIX_DATA
},
2369 { "punpckhqdq", { XM
, EXx
}, PREFIX_DATA
},
2370 { "movK", { MX
, Edq
}, PREFIX_OPCODE
},
2371 { PREFIX_TABLE (PREFIX_0F6F
) },
2373 { PREFIX_TABLE (PREFIX_0F70
) },
2374 { REG_TABLE (REG_0F71
) },
2375 { REG_TABLE (REG_0F72
) },
2376 { REG_TABLE (REG_0F73
) },
2377 { "pcmpeqb", { MX
, EM
}, PREFIX_OPCODE
},
2378 { "pcmpeqw", { MX
, EM
}, PREFIX_OPCODE
},
2379 { "pcmpeqd", { MX
, EM
}, PREFIX_OPCODE
},
2380 { "emms", { XX
}, PREFIX_OPCODE
},
2382 { PREFIX_TABLE (PREFIX_0F78
) },
2383 { PREFIX_TABLE (PREFIX_0F79
) },
2386 { PREFIX_TABLE (PREFIX_0F7C
) },
2387 { PREFIX_TABLE (PREFIX_0F7D
) },
2388 { PREFIX_TABLE (PREFIX_0F7E
) },
2389 { PREFIX_TABLE (PREFIX_0F7F
) },
2391 { "joH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2392 { "jnoH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2393 { "jbH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2394 { "jaeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2395 { "jeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2396 { "jneH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2397 { "jbeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2398 { "jaH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2400 { "jsH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2401 { "jnsH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2402 { "jpH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2403 { "jnpH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2404 { "jlH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2405 { "jgeH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2406 { "jleH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2407 { "jgH", { Jv
, BND
, cond_jump_flag
}, PREFIX_REX2_ILLEGAL
},
2409 { "seto", { Eb
}, 0 },
2410 { "setno", { Eb
}, 0 },
2411 { "setb", { Eb
}, 0 },
2412 { "setae", { Eb
}, 0 },
2413 { "sete", { Eb
}, 0 },
2414 { "setne", { Eb
}, 0 },
2415 { "setbe", { Eb
}, 0 },
2416 { "seta", { Eb
}, 0 },
2418 { "sets", { Eb
}, 0 },
2419 { "setns", { Eb
}, 0 },
2420 { "setp", { Eb
}, 0 },
2421 { "setnp", { Eb
}, 0 },
2422 { "setl", { Eb
}, 0 },
2423 { "setge", { Eb
}, 0 },
2424 { "setle", { Eb
}, 0 },
2425 { "setg", { Eb
}, 0 },
2427 { "pushP", { fs
}, 0 },
2428 { "popP", { fs
}, 0 },
2429 { "cpuid", { XX
}, 0 },
2430 { "btS", { Ev
, Gv
}, 0 },
2431 { "shldS", { Ev
, Gv
, Ib
}, 0 },
2432 { "shldS", { Ev
, Gv
, CL
}, 0 },
2433 { REG_TABLE (REG_0FA6
) },
2434 { REG_TABLE (REG_0FA7
) },
2436 { "pushP", { gs
}, 0 },
2437 { "popP", { gs
}, 0 },
2438 { "rsm", { XX
}, 0 },
2439 { "btsS", { Evh1
, Gv
}, 0 },
2440 { "shrdS", { Ev
, Gv
, Ib
}, 0 },
2441 { "shrdS", { Ev
, Gv
, CL
}, 0 },
2442 { REG_TABLE (REG_0FAE
) },
2443 { "imulS", { Gv
, Ev
}, 0 },
2445 { "cmpxchgB", { Ebh1
, Gb
}, 0 },
2446 { "cmpxchgS", { Evh1
, Gv
}, 0 },
2447 { "lssS", { Gv
, Mp
}, 0 },
2448 { "btrS", { Evh1
, Gv
}, 0 },
2449 { "lfsS", { Gv
, Mp
}, 0 },
2450 { "lgsS", { Gv
, Mp
}, 0 },
2451 { "movz{bR|x}", { Gv
, Eb
}, 0 },
2452 { "movz{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movzww ! */
2454 { PREFIX_TABLE (PREFIX_0FB8
) },
2455 { "ud1S", { Gv
, Ev
}, 0 },
2456 { REG_TABLE (REG_0FBA
) },
2457 { "btcS", { Evh1
, Gv
}, 0 },
2458 { PREFIX_TABLE (PREFIX_0FBC
) },
2459 { PREFIX_TABLE (PREFIX_0FBD
) },
2460 { "movs{bR|x}", { Gv
, Eb
}, 0 },
2461 { "movs{wR|x}", { Gv
, Ew
}, 0 }, /* yes, there really is movsww ! */
2463 { "xaddB", { Ebh1
, Gb
}, 0 },
2464 { "xaddS", { Evh1
, Gv
}, 0 },
2465 { PREFIX_TABLE (PREFIX_0FC2
) },
2466 { "movntiS", { Mdq
, Gdq
}, PREFIX_OPCODE
},
2467 { "pinsrw", { MX
, Edw
, Ib
}, PREFIX_OPCODE
},
2468 { "pextrw", { Gd
, Nq
, Ib
}, PREFIX_OPCODE
},
2469 { "shufpX", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
2470 { REG_TABLE (REG_0FC7
) },
2472 { "bswap", { RMeAX
}, 0 },
2473 { "bswap", { RMeCX
}, 0 },
2474 { "bswap", { RMeDX
}, 0 },
2475 { "bswap", { RMeBX
}, 0 },
2476 { "bswap", { RMeSP
}, 0 },
2477 { "bswap", { RMeBP
}, 0 },
2478 { "bswap", { RMeSI
}, 0 },
2479 { "bswap", { RMeDI
}, 0 },
2481 { PREFIX_TABLE (PREFIX_0FD0
) },
2482 { "psrlw", { MX
, EM
}, PREFIX_OPCODE
},
2483 { "psrld", { MX
, EM
}, PREFIX_OPCODE
},
2484 { "psrlq", { MX
, EM
}, PREFIX_OPCODE
},
2485 { "paddq", { MX
, EM
}, PREFIX_OPCODE
},
2486 { "pmullw", { MX
, EM
}, PREFIX_OPCODE
},
2487 { PREFIX_TABLE (PREFIX_0FD6
) },
2488 { "pmovmskb", { Gdq
, Nq
}, PREFIX_OPCODE
},
2490 { "psubusb", { MX
, EM
}, PREFIX_OPCODE
},
2491 { "psubusw", { MX
, EM
}, PREFIX_OPCODE
},
2492 { "pminub", { MX
, EM
}, PREFIX_OPCODE
},
2493 { "pand", { MX
, EM
}, PREFIX_OPCODE
},
2494 { "paddusb", { MX
, EM
}, PREFIX_OPCODE
},
2495 { "paddusw", { MX
, EM
}, PREFIX_OPCODE
},
2496 { "pmaxub", { MX
, EM
}, PREFIX_OPCODE
},
2497 { "pandn", { MX
, EM
}, PREFIX_OPCODE
},
2499 { "pavgb", { MX
, EM
}, PREFIX_OPCODE
},
2500 { "psraw", { MX
, EM
}, PREFIX_OPCODE
},
2501 { "psrad", { MX
, EM
}, PREFIX_OPCODE
},
2502 { "pavgw", { MX
, EM
}, PREFIX_OPCODE
},
2503 { "pmulhuw", { MX
, EM
}, PREFIX_OPCODE
},
2504 { "pmulhw", { MX
, EM
}, PREFIX_OPCODE
},
2505 { PREFIX_TABLE (PREFIX_0FE6
) },
2506 { PREFIX_TABLE (PREFIX_0FE7
) },
2508 { "psubsb", { MX
, EM
}, PREFIX_OPCODE
},
2509 { "psubsw", { MX
, EM
}, PREFIX_OPCODE
},
2510 { "pminsw", { MX
, EM
}, PREFIX_OPCODE
},
2511 { "por", { MX
, EM
}, PREFIX_OPCODE
},
2512 { "paddsb", { MX
, EM
}, PREFIX_OPCODE
},
2513 { "paddsw", { MX
, EM
}, PREFIX_OPCODE
},
2514 { "pmaxsw", { MX
, EM
}, PREFIX_OPCODE
},
2515 { "pxor", { MX
, EM
}, PREFIX_OPCODE
},
2517 { PREFIX_TABLE (PREFIX_0FF0
) },
2518 { "psllw", { MX
, EM
}, PREFIX_OPCODE
},
2519 { "pslld", { MX
, EM
}, PREFIX_OPCODE
},
2520 { "psllq", { MX
, EM
}, PREFIX_OPCODE
},
2521 { "pmuludq", { MX
, EM
}, PREFIX_OPCODE
},
2522 { "pmaddwd", { MX
, EM
}, PREFIX_OPCODE
},
2523 { "psadbw", { MX
, EM
}, PREFIX_OPCODE
},
2524 { PREFIX_TABLE (PREFIX_0FF7
) },
2526 { "psubb", { MX
, EM
}, PREFIX_OPCODE
},
2527 { "psubw", { MX
, EM
}, PREFIX_OPCODE
},
2528 { "psubd", { MX
, EM
}, PREFIX_OPCODE
},
2529 { "psubq", { MX
, EM
}, PREFIX_OPCODE
},
2530 { "paddb", { MX
, EM
}, PREFIX_OPCODE
},
2531 { "paddw", { MX
, EM
}, PREFIX_OPCODE
},
2532 { "paddd", { MX
, EM
}, PREFIX_OPCODE
},
2533 { "ud0S", { Gv
, Ev
}, 0 },
2536 static const bool onebyte_has_modrm
[256] = {
2537 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2538 /* ------------------------------- */
2539 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
2540 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
2541 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
2542 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
2543 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
2544 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
2545 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
2546 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
2547 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
2548 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
2549 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
2550 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
2551 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
2552 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
2553 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
2554 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
2555 /* ------------------------------- */
2556 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2559 static const bool twobyte_has_modrm
[256] = {
2560 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2561 /* ------------------------------- */
2562 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
2563 /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
2564 /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
2565 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
2566 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
2567 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
2568 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
2569 /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
2570 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2571 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
2572 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
2573 /* b0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bf */
2574 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
2575 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
2576 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
2577 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /* ff */
2578 /* ------------------------------- */
2579 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2589 /* If we are accessing mod/rm/reg without need_modrm set, then the
2590 values are stale. Hitting this abort likely indicates that you
2591 need to update onebyte_has_modrm or twobyte_has_modrm. */
2592 #define MODRM_CHECK if (!ins->need_modrm) abort ()
2594 static const char intel_index16
[][6] = {
2595 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
2598 static const char att_names64
[][8] = {
2599 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
2600 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
2601 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
2602 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
2604 static const char att_names32
[][8] = {
2605 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
2606 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d",
2607 "%r16d", "%r17d", "%r18d", "%r19d", "%r20d", "%r21d", "%r22d", "%r23d",
2608 "%r24d", "%r25d", "%r26d", "%r27d", "%r28d", "%r29d", "%r30d", "%r31d",
2610 static const char att_names16
[][8] = {
2611 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
2612 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w",
2613 "%r16w", "%r17w", "%r18w", "%r19w", "%r20w", "%r21w", "%r22w", "%r23w",
2614 "%r24w", "%r25w", "%r26w", "%r27w", "%r28w", "%r29w", "%r30w", "%r31w",
2616 static const char att_names8
[][8] = {
2617 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
2619 static const char att_names8rex
[][8] = {
2620 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
2621 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b",
2622 "%r16b", "%r17b", "%r18b", "%r19b", "%r20b", "%r21b", "%r22b", "%r23b",
2623 "%r24b", "%r25b", "%r26b", "%r27b", "%r28b", "%r29b", "%r30b", "%r31b",
2625 static const char att_names_seg
[][4] = {
2626 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
2628 static const char att_index64
[] = "%riz";
2629 static const char att_index32
[] = "%eiz";
2630 static const char att_index16
[][8] = {
2631 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
2634 static const char att_names_mm
[][8] = {
2635 "%mm0", "%mm1", "%mm2", "%mm3",
2636 "%mm4", "%mm5", "%mm6", "%mm7"
2639 static const char att_names_bnd
[][8] = {
2640 "%bnd0", "%bnd1", "%bnd2", "%bnd3"
2643 static const char att_names_xmm
[][8] = {
2644 "%xmm0", "%xmm1", "%xmm2", "%xmm3",
2645 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
2646 "%xmm8", "%xmm9", "%xmm10", "%xmm11",
2647 "%xmm12", "%xmm13", "%xmm14", "%xmm15",
2648 "%xmm16", "%xmm17", "%xmm18", "%xmm19",
2649 "%xmm20", "%xmm21", "%xmm22", "%xmm23",
2650 "%xmm24", "%xmm25", "%xmm26", "%xmm27",
2651 "%xmm28", "%xmm29", "%xmm30", "%xmm31"
2654 static const char att_names_ymm
[][8] = {
2655 "%ymm0", "%ymm1", "%ymm2", "%ymm3",
2656 "%ymm4", "%ymm5", "%ymm6", "%ymm7",
2657 "%ymm8", "%ymm9", "%ymm10", "%ymm11",
2658 "%ymm12", "%ymm13", "%ymm14", "%ymm15",
2659 "%ymm16", "%ymm17", "%ymm18", "%ymm19",
2660 "%ymm20", "%ymm21", "%ymm22", "%ymm23",
2661 "%ymm24", "%ymm25", "%ymm26", "%ymm27",
2662 "%ymm28", "%ymm29", "%ymm30", "%ymm31"
2665 static const char att_names_zmm
[][8] = {
2666 "%zmm0", "%zmm1", "%zmm2", "%zmm3",
2667 "%zmm4", "%zmm5", "%zmm6", "%zmm7",
2668 "%zmm8", "%zmm9", "%zmm10", "%zmm11",
2669 "%zmm12", "%zmm13", "%zmm14", "%zmm15",
2670 "%zmm16", "%zmm17", "%zmm18", "%zmm19",
2671 "%zmm20", "%zmm21", "%zmm22", "%zmm23",
2672 "%zmm24", "%zmm25", "%zmm26", "%zmm27",
2673 "%zmm28", "%zmm29", "%zmm30", "%zmm31"
2676 static const char att_names_tmm
[][8] = {
2677 "%tmm0", "%tmm1", "%tmm2", "%tmm3",
2678 "%tmm4", "%tmm5", "%tmm6", "%tmm7"
2681 static const char att_names_mask
[][8] = {
2682 "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
2685 static const char *const names_rounding
[] =
2693 static const struct dis386 reg_table
[][8] = {
2696 { "addA", { Ebh1
, Ib
}, 0 },
2697 { "orA", { Ebh1
, Ib
}, 0 },
2698 { "adcA", { Ebh1
, Ib
}, 0 },
2699 { "sbbA", { Ebh1
, Ib
}, 0 },
2700 { "andA", { Ebh1
, Ib
}, 0 },
2701 { "subA", { Ebh1
, Ib
}, 0 },
2702 { "xorA", { Ebh1
, Ib
}, 0 },
2703 { "cmpA", { Eb
, Ib
}, 0 },
2707 { "addQ", { Evh1
, Iv
}, 0 },
2708 { "orQ", { Evh1
, Iv
}, 0 },
2709 { "adcQ", { Evh1
, Iv
}, 0 },
2710 { "sbbQ", { Evh1
, Iv
}, 0 },
2711 { "andQ", { Evh1
, Iv
}, 0 },
2712 { "subQ", { Evh1
, Iv
}, 0 },
2713 { "xorQ", { Evh1
, Iv
}, 0 },
2714 { "cmpQ", { Ev
, Iv
}, 0 },
2718 { "addQ", { Evh1
, sIb
}, 0 },
2719 { "orQ", { Evh1
, sIb
}, 0 },
2720 { "adcQ", { Evh1
, sIb
}, 0 },
2721 { "sbbQ", { Evh1
, sIb
}, 0 },
2722 { "andQ", { Evh1
, sIb
}, 0 },
2723 { "subQ", { Evh1
, sIb
}, 0 },
2724 { "xorQ", { Evh1
, sIb
}, 0 },
2725 { "cmpQ", { Ev
, sIb
}, 0 },
2729 { "pop{P|}", { stackEv
}, 0 },
2730 { XOP_8F_TABLE () },
2734 { XOP_8F_TABLE () },
2738 { "%NFrolA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2739 { "%NFrorA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2740 { "rclA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2741 { "rcrA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2742 { "%NFshlA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2743 { "%NFshrA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2744 { "%NFshlA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2745 { "%NFsarA", { VexGb
, Eb
, Ib
}, NO_PREFIX
},
2749 { "%NFrolQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2750 { "%NFrorQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2751 { "rclQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2752 { "rcrQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2753 { "%NFshlQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2754 { "%NFshrQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2755 { "%NFshlQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2756 { "%NFsarQ", { VexGv
, Ev
, Ib
}, PREFIX_NP_OR_DATA
},
2760 { "movA", { Ebh3
, Ib
}, 0 },
2767 { RM_TABLE (RM_C6_REG_7
) },
2771 { "movQ", { Evh3
, Iv
}, 0 },
2778 { RM_TABLE (RM_C7_REG_7
) },
2782 { "%NFrolA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2783 { "%NFrorA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2784 { "rclA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2785 { "rcrA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2786 { "%NFshlA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2787 { "%NFshrA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2788 { "%NFshlA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2789 { "%NFsarA", { VexGb
, Eb
, I1
}, NO_PREFIX
},
2793 { "%NFrolQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2794 { "%NFrorQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2795 { "rclQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2796 { "rcrQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2797 { "%NFshlQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2798 { "%NFshrQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2799 { "%NFshlQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2800 { "%NFsarQ", { VexGv
, Ev
, I1
}, PREFIX_NP_OR_DATA
},
2804 { "%NFrolA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2805 { "%NFrorA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2806 { "rclA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2807 { "rcrA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2808 { "%NFshlA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2809 { "%NFshrA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2810 { "%NFshlA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2811 { "%NFsarA", { VexGb
, Eb
, CL
}, NO_PREFIX
},
2815 { "%NFrolQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2816 { "%NFrorQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2817 { "rclQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2818 { "rcrQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2819 { "%NFshlQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2820 { "%NFshrQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2821 { "%NFshlQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2822 { "%NFsarQ", { VexGv
, Ev
, CL
}, PREFIX_NP_OR_DATA
},
2826 { "testA", { Eb
, Ib
}, 0 },
2827 { "testA", { Eb
, Ib
}, 0 },
2828 { "notA", { Ebh1
}, 0 },
2829 { "negA", { Ebh1
}, 0 },
2830 { "mulA", { Eb
}, 0 }, /* Don't print the implicit %al register, */
2831 { "imulA", { Eb
}, 0 }, /* to distinguish these opcodes from other */
2832 { "divA", { Eb
}, 0 }, /* mul/imul opcodes. Do the same for div */
2833 { "idivA", { Eb
}, 0 }, /* and idiv for consistency. */
2837 { "testQ", { Ev
, Iv
}, 0 },
2838 { "testQ", { Ev
, Iv
}, 0 },
2839 { "notQ", { Evh1
}, 0 },
2840 { "negQ", { Evh1
}, 0 },
2841 { "mulQ", { Ev
}, 0 }, /* Don't print the implicit register. */
2842 { "imulQ", { Ev
}, 0 },
2843 { "divQ", { Ev
}, 0 },
2844 { "idivQ", { Ev
}, 0 },
2848 { "incA", { Ebh1
}, 0 },
2849 { "decA", { Ebh1
}, 0 },
2853 { "incQ", { Evh1
}, 0 },
2854 { "decQ", { Evh1
}, 0 },
2855 { "call{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2856 { "{l|}call^", { indirEp
}, 0 },
2857 { "jmp{@|}", { NOTRACK
, indirEv
, BND
}, 0 },
2858 { "{l|}jmp^", { indirEp
}, 0 },
2859 { "push{P|}", { stackEv
}, 0 },
2864 { "sldtD", { Sv
}, 0 },
2865 { "strD", { Sv
}, 0 },
2866 { "lldtD", { Sv
}, 0 },
2867 { "ltrD", { Sv
}, 0 },
2868 { "verrD", { Sv
}, 0 },
2869 { "verwD", { Sv
}, 0 },
2870 { X86_64_TABLE (X86_64_0F00_REG_6
) },
2875 { MOD_TABLE (MOD_0F01_REG_0
) },
2876 { MOD_TABLE (MOD_0F01_REG_1
) },
2877 { MOD_TABLE (MOD_0F01_REG_2
) },
2878 { MOD_TABLE (MOD_0F01_REG_3
) },
2879 { "smswD", { Sv
}, 0 },
2880 { MOD_TABLE (MOD_0F01_REG_5
) },
2881 { "lmsw", { Ew
}, 0 },
2882 { MOD_TABLE (MOD_0F01_REG_7
) },
2886 { "prefetch", { Mb
}, 0 },
2887 { "prefetchw", { Mb
}, 0 },
2888 { "prefetchwt1", { Mb
}, 0 },
2889 { "prefetch", { Mb
}, 0 },
2890 { "prefetch", { Mb
}, 0 },
2891 { "prefetch", { Mb
}, 0 },
2892 { "prefetch", { Mb
}, 0 },
2893 { "prefetch", { Mb
}, 0 },
2897 { MOD_TABLE (MOD_0F18_REG_0
) },
2898 { MOD_TABLE (MOD_0F18_REG_1
) },
2899 { MOD_TABLE (MOD_0F18_REG_2
) },
2900 { MOD_TABLE (MOD_0F18_REG_3
) },
2901 { MOD_TABLE (MOD_0F18_REG_4
) },
2902 { "nopQ", { Ev
}, 0 },
2903 { MOD_TABLE (MOD_0F18_REG_6
) },
2904 { MOD_TABLE (MOD_0F18_REG_7
) },
2906 /* REG_0F1C_P_0_MOD_0 */
2908 { "cldemote", { Mb
}, 0 },
2909 { "nopQ", { Ev
}, 0 },
2910 { "nopQ", { Ev
}, 0 },
2911 { "nopQ", { Ev
}, 0 },
2912 { "nopQ", { Ev
}, 0 },
2913 { "nopQ", { Ev
}, 0 },
2914 { "nopQ", { Ev
}, 0 },
2915 { "nopQ", { Ev
}, 0 },
2917 /* REG_0F1E_P_1_MOD_3 */
2919 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2920 { "rdsspK", { Edq
}, 0 },
2921 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2922 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2923 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2924 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2925 { "nopQ", { Ev
}, PREFIX_IGNORED
},
2926 { RM_TABLE (RM_0F1E_P_1_MOD_3_REG_7
) },
2928 /* REG_0F38D8_PREFIX_1 */
2930 { "aesencwide128kl", { M
}, 0 },
2931 { "aesdecwide128kl", { M
}, 0 },
2932 { "aesencwide256kl", { M
}, 0 },
2933 { "aesdecwide256kl", { M
}, 0 },
2935 /* REG_0F3A0F_P_1 */
2937 { RM_TABLE (RM_0F3A0F_P_1_R_0
) },
2943 { "psrlw", { Nq
, Ib
}, PREFIX_OPCODE
},
2945 { "psraw", { Nq
, Ib
}, PREFIX_OPCODE
},
2947 { "psllw", { Nq
, Ib
}, PREFIX_OPCODE
},
2953 { "psrld", { Nq
, Ib
}, PREFIX_OPCODE
},
2955 { "psrad", { Nq
, Ib
}, PREFIX_OPCODE
},
2957 { "pslld", { Nq
, Ib
}, PREFIX_OPCODE
},
2963 { "psrlq", { Nq
, Ib
}, PREFIX_OPCODE
},
2964 { "psrldq", { Ux
, Ib
}, PREFIX_DATA
},
2967 { "psllq", { Nq
, Ib
}, PREFIX_OPCODE
},
2968 { "pslldq", { Ux
, Ib
}, PREFIX_DATA
},
2972 { PREFIX_TABLE (PREFIX_0FA6_REG_0
) },
2973 { "xsha1", { { OP_0f07
, 0 } }, 0 },
2974 { "xsha256", { { OP_0f07
, 0 } }, 0 },
2975 { "xsha384", { { OP_0f07
, 0 } }, 0 },
2976 { "xsha512", { { OP_0f07
, 0 } }, 0 },
2977 { PREFIX_TABLE (PREFIX_0FA6_REG_5
) },
2981 { "xstore-rng", { { OP_0f07
, 0 } }, 0 },
2982 { "xcrypt-ecb", { { OP_0f07
, 0 } }, 0 },
2983 { "xcrypt-cbc", { { OP_0f07
, 0 } }, 0 },
2984 { "xcrypt-ctr", { { OP_0f07
, 0 } }, 0 },
2985 { "xcrypt-cfb", { { OP_0f07
, 0 } }, 0 },
2986 { "xcrypt-ofb", { { OP_0f07
, 0 } }, 0 },
2987 { PREFIX_TABLE (PREFIX_0FA7_REG_6
) },
2988 { "xrng2", { { OP_0f07
, 0 } }, 0 },
2992 { MOD_TABLE (MOD_0FAE_REG_0
) },
2993 { MOD_TABLE (MOD_0FAE_REG_1
) },
2994 { MOD_TABLE (MOD_0FAE_REG_2
) },
2995 { MOD_TABLE (MOD_0FAE_REG_3
) },
2996 { MOD_TABLE (MOD_0FAE_REG_4
) },
2997 { MOD_TABLE (MOD_0FAE_REG_5
) },
2998 { MOD_TABLE (MOD_0FAE_REG_6
) },
2999 { MOD_TABLE (MOD_0FAE_REG_7
) },
3007 { "btQ", { Ev
, Ib
}, 0 },
3008 { "btsQ", { Evh1
, Ib
}, 0 },
3009 { "btrQ", { Evh1
, Ib
}, 0 },
3010 { "btcQ", { Evh1
, Ib
}, 0 },
3015 { "cmpxchg8b", { { CMPXCHG8B_Fixup
, q_mode
} }, 0 },
3017 { "xrstors", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
3018 { "xsavec", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
3019 { "xsaves", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
3020 { MOD_TABLE (MOD_0FC7_REG_6
) },
3021 { MOD_TABLE (MOD_0FC7_REG_7
) },
3027 { "vpsrlw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3029 { "vpsraw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3031 { "vpsllw", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3037 { "vpsrld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3039 { "vpsrad", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3041 { "vpslld", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3047 { "vpsrlq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3048 { "vpsrldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3051 { "vpsllq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3052 { "vpslldq", { Vex
, Ux
, Ib
}, PREFIX_DATA
},
3058 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_2
) },
3059 { VEX_LEN_TABLE (VEX_LEN_0FAE_R_3
) },
3061 /* REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0 */
3063 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0
) },
3065 /* REG_VEX_0F38F3_L_0_P_0 */
3068 { "%NFblsrS", { VexGdq
, Edq
}, 0 },
3069 { "%NFblsmskS", { VexGdq
, Edq
}, 0 },
3070 { "%NFblsiS", { VexGdq
, Edq
}, 0 },
3072 /* REG_VEX_MAP7_F6_L_0_W_0 */
3074 { X86_64_TABLE (X86_64_VEX_MAP7_F6_L_0_W_0_R_0
) },
3076 /* REG_VEX_MAP7_F8_L_0_W_0 */
3078 { X86_64_TABLE (X86_64_VEX_MAP7_F8_L_0_W_0_R_0
) },
3080 /* REG_XOP_09_01_L_0 */
3083 { "blcfill", { VexGdq
, Edq
}, 0 },
3084 { "blsfill", { VexGdq
, Edq
}, 0 },
3085 { "blcs", { VexGdq
, Edq
}, 0 },
3086 { "tzmsk", { VexGdq
, Edq
}, 0 },
3087 { "blcic", { VexGdq
, Edq
}, 0 },
3088 { "blsic", { VexGdq
, Edq
}, 0 },
3089 { "t1mskc", { VexGdq
, Edq
}, 0 },
3091 /* REG_XOP_09_02_L_0 */
3094 { "blcmsk", { VexGdq
, Edq
}, 0 },
3099 { "blci", { VexGdq
, Edq
}, 0 },
3101 /* REG_XOP_09_12_L_0 */
3103 { "llwpcb", { Rdq
}, 0 },
3104 { "slwpcb", { Rdq
}, 0 },
3106 /* REG_XOP_0A_12_L_0 */
3108 { "lwpins", { VexGdq
, Ed
, Id
}, 0 },
3109 { "lwpval", { VexGdq
, Ed
, Id
}, 0 },
3112 #include "i386-dis-evex-reg.h"
3115 static const struct dis386 prefix_table
[][4] = {
3118 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
3119 { "pause", { XX
}, 0 },
3120 { "xchgS", { { NOP_Fixup
, 0 }, { NOP_Fixup
, 1 } }, 0 },
3121 { NULL
, { { NULL
, 0 } }, PREFIX_IGNORED
}
3124 /* PREFIX_0F00_REG_6_X86_64 */
3129 { "lkgsD", { Sv
}, 0 },
3132 /* PREFIX_0F01_REG_0_MOD_3_RM_6 */
3134 { "wrmsrns", { Skip_MODRM
}, 0 },
3135 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_1
) },
3137 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_6_P_3
) },
3140 /* PREFIX_0F01_REG_0_MOD_3_RM_7 */
3142 { X86_64_TABLE (X86_64_0F01_REG_0_MOD_3_RM_7_P_0
) },
3145 /* PREFIX_0F01_REG_1_RM_2 */
3147 { "clac", { Skip_MODRM
}, 0 },
3148 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_1
) },
3150 { X86_64_TABLE (X86_64_0F01_REG_1_RM_2_PREFIX_3
)},
3153 /* PREFIX_0F01_REG_1_RM_4 */
3157 { "tdcall", { Skip_MODRM
}, 0 },
3161 /* PREFIX_0F01_REG_1_RM_5 */
3165 { X86_64_TABLE (X86_64_0F01_REG_1_RM_5_PREFIX_2
) },
3169 /* PREFIX_0F01_REG_1_RM_6 */
3173 { X86_64_TABLE (X86_64_0F01_REG_1_RM_6_PREFIX_2
) },
3177 /* PREFIX_0F01_REG_1_RM_7 */
3179 { "encls", { Skip_MODRM
}, 0 },
3181 { X86_64_TABLE (X86_64_0F01_REG_1_RM_7_PREFIX_2
) },
3185 /* PREFIX_0F01_REG_3_RM_1 */
3187 { "vmmcall", { Skip_MODRM
}, 0 },
3188 { "vmgexit", { Skip_MODRM
}, 0 },
3190 { "vmgexit", { Skip_MODRM
}, 0 },
3193 /* PREFIX_0F01_REG_5_MOD_0 */
3196 { "rstorssp", { Mq
}, PREFIX_OPCODE
},
3199 /* PREFIX_0F01_REG_5_MOD_3_RM_0 */
3201 { "serialize", { Skip_MODRM
}, PREFIX_OPCODE
},
3202 { "setssbsy", { Skip_MODRM
}, PREFIX_OPCODE
},
3204 { "xsusldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
3207 /* PREFIX_0F01_REG_5_MOD_3_RM_1 */
3212 { "xresldtrk", { Skip_MODRM
}, PREFIX_OPCODE
},
3215 /* PREFIX_0F01_REG_5_MOD_3_RM_2 */
3218 { "saveprevssp", { Skip_MODRM
}, PREFIX_OPCODE
},
3221 /* PREFIX_0F01_REG_5_MOD_3_RM_4 */
3224 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1
) },
3227 /* PREFIX_0F01_REG_5_MOD_3_RM_5 */
3230 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1
) },
3233 /* PREFIX_0F01_REG_5_MOD_3_RM_6 */
3235 { "rdpkru", { Skip_MODRM
}, 0 },
3236 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1
) },
3239 /* PREFIX_0F01_REG_5_MOD_3_RM_7 */
3241 { "wrpkru", { Skip_MODRM
}, 0 },
3242 { X86_64_TABLE (X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1
) },
3245 /* PREFIX_0F01_REG_7_MOD_3_RM_2 */
3247 { "monitorx", { { OP_Monitor
, 0 } }, 0 },
3248 { "mcommit", { Skip_MODRM
}, 0 },
3251 /* PREFIX_0F01_REG_7_MOD_3_RM_5 */
3253 { "rdpru", { Skip_MODRM
}, 0 },
3254 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1
) },
3257 /* PREFIX_0F01_REG_7_MOD_3_RM_6 */
3259 { "invlpgb", { Skip_MODRM
}, 0 },
3260 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1
) },
3262 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3
) },
3265 /* PREFIX_0F01_REG_7_MOD_3_RM_7 */
3267 { "tlbsync", { Skip_MODRM
}, 0 },
3268 { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1
) },
3270 { "pvalidate", { Skip_MODRM
}, 0 },
3275 { "wbinvd", { XX
}, 0 },
3276 { "wbnoinvd", { XX
}, 0 },
3281 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3282 { "%XEVmovs%XS", { XMScalar
, VexScalarR
, EXd
}, 0 },
3283 { "%XEVmovupX", { XM
, EXEvexXNoBcst
}, 0 },
3284 { "%XEVmovs%XD", { XMScalar
, VexScalarR
, EXq
}, 0 },
3289 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3290 { "%XEVmovs%XS", { EXdS
, VexScalarR
, XMScalar
}, 0 },
3291 { "%XEVmovupX", { EXxS
, XM
}, 0 },
3292 { "%XEVmovs%XD", { EXqS
, VexScalarR
, XMScalar
}, 0 },
3297 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
3298 { "movsldup", { XM
, EXx
}, 0 },
3299 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
3300 { "movddup", { XM
, EXq
}, 0 },
3305 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
3306 { "movshdup", { XM
, EXx
}, 0 },
3307 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
3310 /* PREFIX_0F18_REG_6_MOD_0_X86_64 */
3312 { "prefetchit1", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3313 { "nopQ", { Ev
}, 0 },
3314 { "nopQ", { Ev
}, 0 },
3315 { "nopQ", { Ev
}, 0 },
3318 /* PREFIX_0F18_REG_7_MOD_0_X86_64 */
3320 { "prefetchit0", { { PREFETCHI_Fixup
, b_mode
} }, 0 },
3321 { "nopQ", { Ev
}, 0 },
3322 { "nopQ", { Ev
}, 0 },
3323 { "nopQ", { Ev
}, 0 },
3328 { MOD_TABLE (MOD_0F1A_PREFIX_0
) },
3329 { "bndcl", { Gbnd
, Ev_bnd
}, 0 },
3330 { "bndmov", { Gbnd
, Ebnd
}, 0 },
3331 { "bndcu", { Gbnd
, Ev_bnd
}, 0 },
3336 { MOD_TABLE (MOD_0F1B_PREFIX_0
) },
3337 { MOD_TABLE (MOD_0F1B_PREFIX_1
) },
3338 { "bndmov", { EbndS
, Gbnd
}, 0 },
3339 { "bndcn", { Gbnd
, Ev_bnd
}, 0 },
3344 { MOD_TABLE (MOD_0F1C_PREFIX_0
) },
3345 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3346 { "nopQ", { Ev
}, 0 },
3347 { "nopQ", { Ev
}, PREFIX_IGNORED
},
3352 { "nopQ", { Ev
}, 0 },
3353 { MOD_TABLE (MOD_0F1E_PREFIX_1
) },
3354 { "nopQ", { Ev
}, 0 },
3355 { NULL
, { XX
}, PREFIX_IGNORED
},
3360 { "cvtpi2ps", { XM
, EMCq
}, PREFIX_OPCODE
},
3361 { "cvtsi2ss{%LQ|}", { XM
, Edq
}, PREFIX_OPCODE
},
3362 { "cvtpi2pd", { XM
, EMCq
}, PREFIX_OPCODE
},
3363 { "cvtsi2sd{%LQ|}", { XM
, Edq
}, 0 },
3368 { "movntps", { Mx
, XM
}, 0 },
3369 { "movntss", { Md
, XM
}, 0 },
3370 { "movntpd", { Mx
, XM
}, 0 },
3371 { "movntsd", { Mq
, XM
}, 0 },
3376 { "cvttps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3377 { "cvttss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3378 { "cvttpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3379 { "cvttsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3384 { "cvtps2pi", { MXC
, EXq
}, PREFIX_OPCODE
},
3385 { "cvtss2si", { Gdq
, EXd
}, PREFIX_OPCODE
},
3386 { "cvtpd2pi", { MXC
, EXx
}, PREFIX_OPCODE
},
3387 { "cvtsd2si", { Gdq
, EXq
}, PREFIX_OPCODE
},
3392 { "VucomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3394 { "VucomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3399 { "VcomisYX", { XMScalar
, EXd
, EXxEVexS
}, 0 },
3401 { "VcomisYX", { XMScalar
, EXq
, EXxEVexS
}, 0 },
3406 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3407 { "%XEVsqrts%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3408 { "%XEVsqrtpX", { XM
, EXx
, EXxEVexR
}, 0 },
3409 { "%XEVsqrts%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3414 { "Vrsqrtps", { XM
, EXx
}, 0 },
3415 { "Vrsqrtss", { XMScalar
, VexScalar
, EXd
}, 0 },
3420 { "Vrcpps", { XM
, EXx
}, 0 },
3421 { "Vrcpss", { XMScalar
, VexScalar
, EXd
}, 0 },
3426 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3427 { "%XEVadds%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3428 { "%XEVaddpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3429 { "%XEVadds%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3434 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3435 { "%XEVmuls%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3436 { "%XEVmulpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3437 { "%XEVmuls%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3442 { "%XEVcvtp%XS2pd", { XM
, EXEvexHalfBcstXmmq
, EXxEVexS
}, 0 },
3443 { "%XEVcvts%XS2sd", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3444 { "%XEVcvtp%XD2ps%XY", { XMxmmq
, EXx
, EXxEVexR
}, 0 },
3445 { "%XEVcvts%XD2ss", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3450 { "Vcvtdq2ps", { XM
, EXx
}, 0 },
3451 { "Vcvttps2dq", { XM
, EXx
}, 0 },
3452 { "Vcvtps2dq", { XM
, EXx
}, 0 },
3457 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3458 { "%XEVsubs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3459 { "%XEVsubpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3460 { "%XEVsubs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3465 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3466 { "%XEVmins%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3467 { "%XEVminpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3468 { "%XEVmins%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3473 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3474 { "%XEVdivs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexR
}, 0 },
3475 { "%XEVdivpX", { XM
, Vex
, EXx
, EXxEVexR
}, 0 },
3476 { "%XEVdivs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexR
}, 0 },
3481 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3482 { "%XEVmaxs%XS", { XMScalar
, VexScalar
, EXd
, EXxEVexS
}, 0 },
3483 { "%XEVmaxpX", { XM
, Vex
, EXx
, EXxEVexS
}, 0 },
3484 { "%XEVmaxs%XD", { XMScalar
, VexScalar
, EXq
, EXxEVexS
}, 0 },
3489 { "punpcklbw",{ MX
, EMd
}, PREFIX_OPCODE
},
3491 { "punpcklbw",{ MX
, EMx
}, PREFIX_OPCODE
},
3496 { "punpcklwd",{ MX
, EMd
}, PREFIX_OPCODE
},
3498 { "punpcklwd",{ MX
, EMx
}, PREFIX_OPCODE
},
3503 { "punpckldq",{ MX
, EMd
}, PREFIX_OPCODE
},
3505 { "punpckldq",{ MX
, EMx
}, PREFIX_OPCODE
},
3510 { "movq", { MX
, EM
}, PREFIX_OPCODE
},
3511 { "movdqu", { XM
, EXx
}, PREFIX_OPCODE
},
3512 { "movdqa", { XM
, EXx
}, PREFIX_OPCODE
},
3517 { "pshufw", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
3518 { "pshufhw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3519 { "pshufd", { XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3520 { "pshuflw",{ XM
, EXx
, Ib
}, PREFIX_OPCODE
},
3525 {"vmread", { Em
, Gm
}, 0 },
3527 {"extrq", { Uxmm
, Ib
, Ib
}, 0 },
3528 {"insertq", { XM
, Uxmm
, Ib
, Ib
}, 0 },
3533 {"vmwrite", { Gm
, Em
}, 0 },
3535 {"extrq", { XM
, Uxmm
}, 0 },
3536 {"insertq", { XM
, Uxmm
}, 0 },
3543 { "Vhaddpd", { XM
, Vex
, EXx
}, 0 },
3544 { "Vhaddps", { XM
, Vex
, EXx
}, 0 },
3551 { "Vhsubpd", { XM
, Vex
, EXx
}, 0 },
3552 { "Vhsubps", { XM
, Vex
, EXx
}, 0 },
3557 { "movK", { Edq
, MX
}, PREFIX_OPCODE
},
3558 { "movq", { XM
, EXq
}, PREFIX_OPCODE
},
3559 { "movK", { Edq
, XM
}, PREFIX_OPCODE
},
3564 { "movq", { EMS
, MX
}, PREFIX_OPCODE
},
3565 { "movdqu", { EXxS
, XM
}, PREFIX_OPCODE
},
3566 { "movdqa", { EXxS
, XM
}, PREFIX_OPCODE
},
3569 /* PREFIX_0FA6_REG_0 */
3572 { "montmul", { { MONTMUL_Fixup
, 0 } }, 0},
3574 { "sm2", { Skip_MODRM
}, 0 },
3577 /* PREFIX_0FA6_REG_5 */
3580 { "sm3", { Skip_MODRM
}, 0 },
3583 /* PREFIX_0FA7_REG_6 */
3586 { "sm4", { Skip_MODRM
}, 0 },
3589 /* PREFIX_0FAE_REG_0_MOD_3 */
3592 { "rdfsbase", { Ev
}, 0 },
3595 /* PREFIX_0FAE_REG_1_MOD_3 */
3598 { "rdgsbase", { Ev
}, 0 },
3601 /* PREFIX_0FAE_REG_2_MOD_3 */
3604 { "wrfsbase", { Ev
}, 0 },
3607 /* PREFIX_0FAE_REG_3_MOD_3 */
3610 { "wrgsbase", { Ev
}, 0 },
3613 /* PREFIX_0FAE_REG_4_MOD_0 */
3615 { "xsave", { FXSAVE
}, PREFIX_REX2_ILLEGAL
},
3616 { "ptwrite{%LQ|}", { Edq
}, 0 },
3619 /* PREFIX_0FAE_REG_4_MOD_3 */
3622 { "ptwrite{%LQ|}", { Edq
}, 0 },
3625 /* PREFIX_0FAE_REG_5_MOD_3 */
3627 { "lfence", { Skip_MODRM
}, 0 },
3628 { "incsspK", { Edq
}, PREFIX_OPCODE
},
3631 /* PREFIX_0FAE_REG_6_MOD_0 */
3633 { "xsaveopt", { FXSAVE
}, PREFIX_OPCODE
| PREFIX_REX2_ILLEGAL
},
3634 { "clrssbsy", { Mq
}, PREFIX_OPCODE
},
3635 { "clwb", { Mb
}, PREFIX_OPCODE
},
3638 /* PREFIX_0FAE_REG_6_MOD_3 */
3640 { RM_TABLE (RM_0FAE_REG_6_MOD_3_P_0
) },
3641 { "umonitor", { Eva
}, PREFIX_OPCODE
},
3642 { "tpause", { Edq
}, PREFIX_OPCODE
},
3643 { "umwait", { Edq
}, PREFIX_OPCODE
},
3646 /* PREFIX_0FAE_REG_7_MOD_0 */
3648 { "clflush", { Mb
}, 0 },
3650 { "clflushopt", { Mb
}, 0 },
3656 { "popcntS", { Gv
, Ev
}, 0 },
3661 { "bsfS", { Gv
, Ev
}, 0 },
3662 { "tzcntS", { Gv
, Ev
}, 0 },
3663 { "bsfS", { Gv
, Ev
}, 0 },
3668 { "bsrS", { Gv
, Ev
}, 0 },
3669 { "lzcntS", { Gv
, Ev
}, 0 },
3670 { "bsrS", { Gv
, Ev
}, 0 },
3675 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3676 { "Vcmpss", { XMScalar
, VexScalar
, EXd
, CMP
}, 0 },
3677 { "VcmppX", { XM
, Vex
, EXx
, CMP
}, 0 },
3678 { "Vcmpsd", { XMScalar
, VexScalar
, EXq
, CMP
}, 0 },
3681 /* PREFIX_0FC7_REG_6_MOD_0 */
3683 { "vmptrld",{ Mq
}, 0 },
3684 { "vmxon", { Mq
}, 0 },
3685 { "vmclear",{ Mq
}, 0 },
3688 /* PREFIX_0FC7_REG_6_MOD_3 */
3690 { "rdrand", { Ev
}, 0 },
3691 { X86_64_TABLE (X86_64_0FC7_REG_6_MOD_3_PREFIX_1
) },
3692 { "rdrand", { Ev
}, 0 }
3695 /* PREFIX_0FC7_REG_7_MOD_3 */
3697 { "rdseed", { Ev
}, 0 },
3698 { "rdpid", { Em
}, 0 },
3699 { "rdseed", { Ev
}, 0 },
3706 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3707 { "VaddsubpX", { XM
, Vex
, EXx
}, 0 },
3713 { "movq2dq",{ XM
, Nq
}, 0 },
3714 { "movq", { EXqS
, XM
}, 0 },
3715 { "movdq2q",{ MX
, Ux
}, 0 },
3721 { "Vcvtdq2pd", { XM
, EXxmmq
}, 0 },
3722 { "Vcvttpd2dq%XY", { XMM
, EXx
}, 0 },
3723 { "Vcvtpd2dq%XY", { XMM
, EXx
}, 0 },
3728 { "movntq", { Mq
, MX
}, 0 },
3730 { "movntdq", { Mx
, XM
}, 0 },
3738 { "Vlddqu", { XM
, M
}, 0 },
3743 { "maskmovq", { MX
, Nq
}, PREFIX_OPCODE
},
3745 { "maskmovdqu", { XM
, Ux
}, PREFIX_OPCODE
},
3751 { REG_TABLE (REG_0F38D8_PREFIX_1
) },
3757 { MOD_TABLE (MOD_0F38DC_PREFIX_1
) },
3758 { "aesenc", { XM
, EXx
}, 0 },
3764 { "aesdec128kl", { XM
, M
}, 0 },
3765 { "aesenclast", { XM
, EXx
}, 0 },
3771 { "aesenc256kl", { XM
, M
}, 0 },
3772 { "aesdec", { XM
, EXx
}, 0 },
3778 { "aesdec256kl", { XM
, M
}, 0 },
3779 { "aesdeclast", { XM
, EXx
}, 0 },
3784 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3786 { "movbeS", { Gv
, Mv
}, PREFIX_OPCODE
},
3787 { "crc32A", { Gdq
, Eb
}, PREFIX_OPCODE
},
3792 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3794 { "movbeS", { Mv
, Gv
}, PREFIX_OPCODE
},
3795 { "crc32Q", { Gdq
, Ev
}, PREFIX_OPCODE
},
3800 { "wrssK", { M
, Gdq
}, 0 },
3801 { "adoxL", { VexGdq
, Gdq
, Edq
}, 0 },
3802 { "adcxL", { VexGdq
, Gdq
, Edq
}, 0 },
3806 /* PREFIX_0F38F8_M_0 */
3809 { "enqcmds", { Gva
, M
}, 0 },
3810 { "movdir64b", { Gva
, M
}, 0 },
3811 { "enqcmd", { Gva
, M
}, 0 },
3814 /* PREFIX_0F38F8_M_1_X86_64 */
3817 { "uwrmsr", { Gq
, Rq
}, 0 },
3819 { "urdmsr", { Rq
, Gq
}, 0 },
3825 { "encodekey128", { Gd
, Rd
}, 0 },
3831 { "encodekey256", { Gd
, Rd
}, 0 },
3836 { "aadd", { Mdq
, Gdq
}, 0 },
3837 { "axor", { Mdq
, Gdq
}, 0 },
3838 { "aand", { Mdq
, Gdq
}, 0 },
3839 { "aor", { Mdq
, Gdq
}, 0 },
3845 { REG_TABLE (REG_0F3A0F_P_1
) },
3848 /* PREFIX_VEX_0F12 */
3850 { VEX_LEN_TABLE (VEX_LEN_0F12_P_0
) },
3851 { "%XEvmov%XSldup", { XM
, EXEvexXNoBcst
}, 0 },
3852 { VEX_LEN_TABLE (VEX_LEN_0F12_P_2
) },
3853 { "%XEvmov%XDdup", { XM
, EXymmq
}, 0 },
3856 /* PREFIX_VEX_0F16 */
3858 { VEX_LEN_TABLE (VEX_LEN_0F16_P_0
) },
3859 { "%XEvmov%XShdup", { XM
, EXEvexXNoBcst
}, 0 },
3860 { VEX_LEN_TABLE (VEX_LEN_0F16_P_2
) },
3863 /* PREFIX_VEX_0F2A */
3866 { "%XEvcvtsi2ssY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR
, Edq
}, 0 },
3868 { "%XEvcvtsi2sdY{%LQ|}", { XMScalar
, VexScalar
, EXxEVexR64
, Edq
}, 0 },
3871 /* PREFIX_VEX_0F2C */
3874 { "%XEvcvttss2si", { Gdq
, EXd
, EXxEVexS
}, 0 },
3876 { "%XEvcvttsd2si", { Gdq
, EXq
, EXxEVexS
}, 0 },
3879 /* PREFIX_VEX_0F2D */
3882 { "%XEvcvtss2si", { Gdq
, EXd
, EXxEVexR
}, 0 },
3884 { "%XEvcvtsd2si", { Gdq
, EXq
, EXxEVexR
}, 0 },
3887 /* PREFIX_VEX_0F41_L_1_W_0 */
3889 { "kandw", { MaskG
, MaskVex
, MaskR
}, 0 },
3891 { "kandb", { MaskG
, MaskVex
, MaskR
}, 0 },
3894 /* PREFIX_VEX_0F41_L_1_W_1 */
3896 { "kandq", { MaskG
, MaskVex
, MaskR
}, 0 },
3898 { "kandd", { MaskG
, MaskVex
, MaskR
}, 0 },
3901 /* PREFIX_VEX_0F42_L_1_W_0 */
3903 { "kandnw", { MaskG
, MaskVex
, MaskR
}, 0 },
3905 { "kandnb", { MaskG
, MaskVex
, MaskR
}, 0 },
3908 /* PREFIX_VEX_0F42_L_1_W_1 */
3910 { "kandnq", { MaskG
, MaskVex
, MaskR
}, 0 },
3912 { "kandnd", { MaskG
, MaskVex
, MaskR
}, 0 },
3915 /* PREFIX_VEX_0F44_L_0_W_0 */
3917 { "knotw", { MaskG
, MaskR
}, 0 },
3919 { "knotb", { MaskG
, MaskR
}, 0 },
3922 /* PREFIX_VEX_0F44_L_0_W_1 */
3924 { "knotq", { MaskG
, MaskR
}, 0 },
3926 { "knotd", { MaskG
, MaskR
}, 0 },
3929 /* PREFIX_VEX_0F45_L_1_W_0 */
3931 { "korw", { MaskG
, MaskVex
, MaskR
}, 0 },
3933 { "korb", { MaskG
, MaskVex
, MaskR
}, 0 },
3936 /* PREFIX_VEX_0F45_L_1_W_1 */
3938 { "korq", { MaskG
, MaskVex
, MaskR
}, 0 },
3940 { "kord", { MaskG
, MaskVex
, MaskR
}, 0 },
3943 /* PREFIX_VEX_0F46_L_1_W_0 */
3945 { "kxnorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3947 { "kxnorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3950 /* PREFIX_VEX_0F46_L_1_W_1 */
3952 { "kxnorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3954 { "kxnord", { MaskG
, MaskVex
, MaskR
}, 0 },
3957 /* PREFIX_VEX_0F47_L_1_W_0 */
3959 { "kxorw", { MaskG
, MaskVex
, MaskR
}, 0 },
3961 { "kxorb", { MaskG
, MaskVex
, MaskR
}, 0 },
3964 /* PREFIX_VEX_0F47_L_1_W_1 */
3966 { "kxorq", { MaskG
, MaskVex
, MaskR
}, 0 },
3968 { "kxord", { MaskG
, MaskVex
, MaskR
}, 0 },
3971 /* PREFIX_VEX_0F4A_L_1_W_0 */
3973 { "kaddw", { MaskG
, MaskVex
, MaskR
}, 0 },
3975 { "kaddb", { MaskG
, MaskVex
, MaskR
}, 0 },
3978 /* PREFIX_VEX_0F4A_L_1_W_1 */
3980 { "kaddq", { MaskG
, MaskVex
, MaskR
}, 0 },
3982 { "kaddd", { MaskG
, MaskVex
, MaskR
}, 0 },
3985 /* PREFIX_VEX_0F4B_L_1_W_0 */
3987 { "kunpckwd", { MaskG
, MaskVex
, MaskR
}, 0 },
3989 { "kunpckbw", { MaskG
, MaskVex
, MaskR
}, 0 },
3992 /* PREFIX_VEX_0F4B_L_1_W_1 */
3994 { "kunpckdq", { MaskG
, MaskVex
, MaskR
}, 0 },
3997 /* PREFIX_VEX_0F6F */
4000 { "vmovdqu", { XM
, EXx
}, 0 },
4001 { "vmovdqa", { XM
, EXx
}, 0 },
4004 /* PREFIX_VEX_0F70 */
4007 { "vpshufhw", { XM
, EXx
, Ib
}, 0 },
4008 { "vpshufd", { XM
, EXx
, Ib
}, 0 },
4009 { "vpshuflw", { XM
, EXx
, Ib
}, 0 },
4012 /* PREFIX_VEX_0F7E */
4015 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_1
) },
4016 { VEX_LEN_TABLE (VEX_LEN_0F7E_P_2
) },
4019 /* PREFIX_VEX_0F7F */
4022 { "vmovdqu", { EXxS
, XM
}, 0 },
4023 { "vmovdqa", { EXxS
, XM
}, 0 },
4026 /* PREFIX_VEX_0F90_L_0_W_0 */
4028 { "%XEkmovw", { MaskG
, MaskE
}, 0 },
4030 { "%XEkmovb", { MaskG
, MaskBDE
}, 0 },
4033 /* PREFIX_VEX_0F90_L_0_W_1 */
4035 { "%XEkmovq", { MaskG
, MaskE
}, 0 },
4037 { "%XEkmovd", { MaskG
, MaskBDE
}, 0 },
4040 /* PREFIX_VEX_0F91_L_0_W_0 */
4042 { "%XEkmovw", { Mw
, MaskG
}, 0 },
4044 { "%XEkmovb", { Mb
, MaskG
}, 0 },
4047 /* PREFIX_VEX_0F91_L_0_W_1 */
4049 { "%XEkmovq", { Mq
, MaskG
}, 0 },
4051 { "%XEkmovd", { Md
, MaskG
}, 0 },
4054 /* PREFIX_VEX_0F92_L_0_W_0 */
4056 { "%XEkmovw", { MaskG
, Rdq
}, 0 },
4058 { "%XEkmovb", { MaskG
, Rdq
}, 0 },
4059 { "%XEkmovd", { MaskG
, Rdq
}, 0 },
4062 /* PREFIX_VEX_0F92_L_0_W_1 */
4067 { "%XEkmovK", { MaskG
, Rdq
}, 0 },
4070 /* PREFIX_VEX_0F93_L_0_W_0 */
4072 { "%XEkmovw", { Gdq
, MaskR
}, 0 },
4074 { "%XEkmovb", { Gdq
, MaskR
}, 0 },
4075 { "%XEkmovd", { Gdq
, MaskR
}, 0 },
4078 /* PREFIX_VEX_0F93_L_0_W_1 */
4083 { "%XEkmovK", { Gdq
, MaskR
}, 0 },
4086 /* PREFIX_VEX_0F98_L_0_W_0 */
4088 { "kortestw", { MaskG
, MaskR
}, 0 },
4090 { "kortestb", { MaskG
, MaskR
}, 0 },
4093 /* PREFIX_VEX_0F98_L_0_W_1 */
4095 { "kortestq", { MaskG
, MaskR
}, 0 },
4097 { "kortestd", { MaskG
, MaskR
}, 0 },
4100 /* PREFIX_VEX_0F99_L_0_W_0 */
4102 { "ktestw", { MaskG
, MaskR
}, 0 },
4104 { "ktestb", { MaskG
, MaskR
}, 0 },
4107 /* PREFIX_VEX_0F99_L_0_W_1 */
4109 { "ktestq", { MaskG
, MaskR
}, 0 },
4111 { "ktestd", { MaskG
, MaskR
}, 0 },
4114 /* PREFIX_VEX_0F3848_X86_64_L_0_W_0 */
4116 { "ttmmultf32ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4118 { "tmmultf32ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4121 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0 */
4123 { "ldtilecfg", { M
}, 0 },
4125 { "sttilecfg", { M
}, 0 },
4128 /* PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1 */
4130 { REG_TABLE (REG_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0
) },
4133 { RM_TABLE (RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3
) },
4136 /* PREFIX_VEX_0F384A_X86_64_W_0_L_0 */
4140 { "tileloaddrst1", { TMM
, MVexSIBMEM
}, 0 },
4141 { "tileloaddrs", { TMM
, MVexSIBMEM
}, 0 },
4144 /* PREFIX_VEX_0F384B_X86_64_L_0_W_0 */
4147 { "tilestored", { MVexSIBMEM
, TMM
}, 0 },
4148 { "tileloaddt1", { TMM
, MVexSIBMEM
}, 0 },
4149 { "tileloadd", { TMM
, MVexSIBMEM
}, 0 },
4152 /* PREFIX_VEX_0F3850_W_0 */
4154 { "%XEvpdpbuud", { XM
, Vex
, EXx
}, 0 },
4155 { "%XEvpdpbsud", { XM
, Vex
, EXx
}, 0 },
4156 { "%XVvpdpbusd", { XM
, Vex
, EXx
}, 0 },
4157 { "%XEvpdpbssd", { XM
, Vex
, EXx
}, 0 },
4160 /* PREFIX_VEX_0F3851_W_0 */
4162 { "%XEvpdpbuuds", { XM
, Vex
, EXx
}, 0 },
4163 { "%XEvpdpbsuds", { XM
, Vex
, EXx
}, 0 },
4164 { "%XVvpdpbusds", { XM
, Vex
, EXx
}, 0 },
4165 { "%XEvpdpbssds", { XM
, Vex
, EXx
}, 0 },
4167 /* PREFIX_VEX_0F385C_X86_64_L_0_W_0 */
4170 { "tdpbf16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4172 { "tdpfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4175 /* PREFIX_VEX_0F385E_X86_64_L_0_W_0 */
4177 { "tdpbuud", {TMM
, Rtmm
, VexTmm
}, 0 },
4178 { "tdpbsud", {TMM
, Rtmm
, VexTmm
}, 0 },
4179 { "tdpbusd", {TMM
, Rtmm
, VexTmm
}, 0 },
4180 { "tdpbssd", {TMM
, Rtmm
, VexTmm
}, 0 },
4183 /* PREFIX_VEX_0F385F_X86_64_L_0_W_0 */
4186 { "ttransposed", { TMM
, Rtmm
}, 0 },
4189 /* PREFIX_VEX_0F386B_X86_64_L_0_W_0 */
4191 { "tconjtcmmimfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4192 { "ttcmmrlfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4193 { "tconjtfp16", { TMM
, Rtmm
}, 0 },
4194 { "ttcmmimfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4197 /* PREFIX_VEX_0F386C_X86_64_L_0_W_0 */
4199 { "tcmmrlfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4200 { "ttdpbf16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4201 { "tcmmimfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4202 { "ttdpfp16ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4205 /* PREFIX_VEX_0F386E_X86_64_L_0_W_0 */
4207 { "t2rpntlvwz0", { TMM
, MVexSIBMEM
}, 0 },
4209 { "t2rpntlvwz1", { TMM
, MVexSIBMEM
}, 0 },
4212 /* PREFIX_VEX_0F386F_X86_64_L_0_W_0 */
4214 { "t2rpntlvwz0t1", { TMM
, MVexSIBMEM
}, 0 },
4216 { "t2rpntlvwz1t1", { TMM
, MVexSIBMEM
}, 0 },
4219 /* PREFIX_VEX_0F3872 */
4222 { VEX_W_TABLE (VEX_W_0F3872_P_1
) },
4225 /* PREFIX_VEX_0F38B0_W_0 */
4227 { "vcvtneoph2ps", { XM
, Mx
}, 0 },
4228 { "vcvtneebf162ps", { XM
, Mx
}, 0 },
4229 { "vcvtneeph2ps", { XM
, Mx
}, 0 },
4230 { "vcvtneobf162ps", { XM
, Mx
}, 0 },
4233 /* PREFIX_VEX_0F38B1_W_0 */
4236 { "vbcstnebf162ps", { XM
, Mw
}, 0 },
4237 { "vbcstnesh2ps", { XM
, Mw
}, 0 },
4240 /* PREFIX_VEX_0F38D2_W_0 */
4242 { "%XEvpdpwuud", { XM
, Vex
, EXx
}, 0 },
4243 { "%XEvpdpwsud", { XM
, Vex
, EXx
}, 0 },
4244 { "%XEvpdpwusd", { XM
, Vex
, EXx
}, 0 },
4247 /* PREFIX_VEX_0F38D3_W_0 */
4249 { "%XEvpdpwuuds", { XM
, Vex
, EXx
}, 0 },
4250 { "%XEvpdpwsuds", { XM
, Vex
, EXx
}, 0 },
4251 { "%XEvpdpwusds", { XM
, Vex
, EXx
}, 0 },
4254 /* PREFIX_VEX_0F38CB */
4259 { VEX_W_TABLE (VEX_W_0F38CB_P_3
) },
4262 /* PREFIX_VEX_0F38CC */
4267 { VEX_W_TABLE (VEX_W_0F38CC_P_3
) },
4270 /* PREFIX_VEX_0F38CD */
4275 { VEX_W_TABLE (VEX_W_0F38CD_P_3
) },
4278 /* PREFIX_VEX_0F38DA_W_0 */
4280 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_0
) },
4281 { "%XEvsm4key4", { XM
, Vex
, EXx
}, 0 },
4282 { VEX_LEN_TABLE (VEX_LEN_0F38DA_W_0_P_2
) },
4283 { "%XEvsm4rnds4", { XM
, Vex
, EXx
}, 0 },
4286 /* PREFIX_VEX_0F38F2_L_0 */
4288 { "%NFandnS", { Gdq
, VexGdq
, Edq
}, 0 },
4291 /* PREFIX_VEX_0F38F3_L_0 */
4293 { REG_TABLE (REG_VEX_0F38F3_L_0_P_0
) },
4296 /* PREFIX_VEX_0F38F5_L_0 */
4298 { "%NFbzhiS", { Gdq
, Edq
, VexGdq
}, 0 },
4299 { "%XEpextS", { Gdq
, VexGdq
, Edq
}, 0 },
4301 { "%XEpdepS", { Gdq
, VexGdq
, Edq
}, 0 },
4304 /* PREFIX_VEX_0F38F6_L_0 */
4309 { "%XEmulxS", { Gdq
, VexGdq
, Edq
}, 0 },
4312 /* PREFIX_VEX_0F38F7_L_0 */
4314 { "%NFbextrS", { Gdq
, Edq
, VexGdq
}, 0 },
4315 { "%XEsarxS", { Gdq
, Edq
, VexGdq
}, 0 },
4316 { "%XEshlxS", { Gdq
, Edq
, VexGdq
}, 0 },
4317 { "%XEshrxS", { Gdq
, Edq
, VexGdq
}, 0 },
4320 /* PREFIX_VEX_0F3AF0_L_0 */
4325 { "%XErorxS", { Gdq
, Edq
, Ib
}, 0 },
4328 /* PREFIX_VEX_MAP5_F8_X86_64_L_0_W_0 */
4330 { "t2rpntlvwz0rs", { TMM
, MVexSIBMEM
}, 0 },
4332 { "t2rpntlvwz1rs", { TMM
, MVexSIBMEM
}, 0 },
4335 /* PREFIX_VEX_MAP5_F9_X86_64_L_0_W_0 */
4337 { "t2rpntlvwz0rst1", { TMM
, MVexSIBMEM
}, 0 },
4339 { "t2rpntlvwz1rst1", { TMM
, MVexSIBMEM
}, 0 },
4342 /* PREFIX_VEX_MAP5_FD_X86_64_L_0_W_0 */
4344 { "tdpbf8ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4345 { "tdphbf8ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4346 { "tdphf8ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4347 { "tdpbhf8ps", { TMM
, Rtmm
, VexTmm
}, 0 },
4350 /* PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64 */
4353 { "wrmsrns", { Skip_MODRM
, Id
, Rq
}, 0 },
4355 { "rdmsr", { Rq
, Id
}, 0 },
4358 /* PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64 */
4361 { "uwrmsr", { Skip_MODRM
, Id
, Rq
}, 0 },
4363 { "urdmsr", { Rq
, Id
}, 0 },
4366 #include "i386-dis-evex-prefix.h"
4369 static const struct dis386 x86_64_table
[][2] = {
4372 { "pushP", { es
}, 0 },
4377 { "popP", { es
}, 0 },
4382 { "pushP", { cs
}, 0 },
4387 { "pushP", { ss
}, 0 },
4392 { "popP", { ss
}, 0 },
4397 { "pushP", { ds
}, 0 },
4402 { "popP", { ds
}, 0 },
4407 { "daa", { XX
}, 0 },
4412 { "das", { XX
}, 0 },
4417 { "aaa", { XX
}, 0 },
4422 { "aas", { XX
}, 0 },
4427 { "pushaP", { XX
}, 0 },
4432 { "popaP", { XX
}, 0 },
4437 { MOD_TABLE (MOD_62_32BIT
) },
4443 { "arplS", { Sv
, Gv
}, 0 },
4444 { "movs", { Gv
, { MOVSXD_Fixup
, movsxd_mode
} }, 0 },
4449 { "ins{R|}", { Yzr
, indirDX
}, 0 },
4450 { "ins{G|}", { Yzr
, indirDX
}, 0 },
4455 { "outs{R|}", { indirDXr
, Xz
}, 0 },
4456 { "outs{G|}", { indirDXr
, Xz
}, 0 },
4461 /* Opcode 0x82 is an alias of opcode 0x80 in 32-bit mode. */
4462 { REG_TABLE (REG_80
) },
4467 { "{l|}call{P|}", { Ap
}, 0 },
4472 { "retP", { Iw
, BND
}, 0 },
4473 { "ret@", { Iw
, BND
}, 0 },
4478 { "retP", { BND
}, 0 },
4479 { "ret@", { BND
}, 0 },
4484 { MOD_TABLE (MOD_C4_32BIT
) },
4485 { VEX_C4_TABLE () },
4490 { MOD_TABLE (MOD_C5_32BIT
) },
4491 { VEX_C5_TABLE () },
4496 { "into", { XX
}, 0 },
4501 { "aam", { Ib
}, 0 },
4506 { "aad", { Ib
}, 0 },
4511 { "callP", { Jv
, BND
}, 0 },
4512 { "call@", { Jv
, BND
}, PREFIX_REX2_ILLEGAL
}
4517 { "jmpP", { Jv
, BND
}, 0 },
4518 { "jmp@", { Jv
, BND
}, PREFIX_REX2_ILLEGAL
}
4523 { "{l|}jmp{P|}", { Ap
}, 0 },
4526 /* X86_64_0F00_REG_6 */
4529 { PREFIX_TABLE (PREFIX_0F00_REG_6_X86_64
) },
4532 /* X86_64_0F01_REG_0 */
4534 { "sgdt{Q|Q}", { M
}, 0 },
4535 { "sgdt", { M
}, 0 },
4538 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_1 */
4541 { "wrmsrlist", { Skip_MODRM
}, 0 },
4544 /* X86_64_0F01_REG_0_MOD_3_RM_6_P_3 */
4547 { "rdmsrlist", { Skip_MODRM
}, 0 },
4550 /* X86_64_0F01_REG_0_MOD_3_RM_7_P_0 */
4553 { "pbndkb", { Skip_MODRM
}, 0 },
4556 /* X86_64_0F01_REG_1 */
4558 { "sidt{Q|Q}", { M
}, 0 },
4559 { "sidt", { M
}, 0 },
4562 /* X86_64_0F01_REG_1_RM_2_PREFIX_1 */
4565 { "eretu", { Skip_MODRM
}, 0 },
4568 /* X86_64_0F01_REG_1_RM_2_PREFIX_3 */
4571 { "erets", { Skip_MODRM
}, 0 },
4574 /* X86_64_0F01_REG_1_RM_5_PREFIX_2 */
4577 { "seamret", { Skip_MODRM
}, 0 },
4580 /* X86_64_0F01_REG_1_RM_6_PREFIX_2 */
4583 { "seamops", { Skip_MODRM
}, 0 },
4586 /* X86_64_0F01_REG_1_RM_7_PREFIX_2 */
4589 { "seamcall", { Skip_MODRM
}, 0 },
4592 /* X86_64_0F01_REG_2 */
4594 { "lgdt{Q|Q}", { M
}, 0 },
4595 { "lgdt", { M
}, 0 },
4598 /* X86_64_0F01_REG_3 */
4600 { "lidt{Q|Q}", { M
}, 0 },
4601 { "lidt", { M
}, 0 },
4604 /* X86_64_0F01_REG_5_MOD_3_RM_4_PREFIX_1 */
4607 { "uiret", { Skip_MODRM
}, 0 },
4610 /* X86_64_0F01_REG_5_MOD_3_RM_5_PREFIX_1 */
4613 { "testui", { Skip_MODRM
}, 0 },
4616 /* X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1 */
4619 { "clui", { Skip_MODRM
}, 0 },
4622 /* X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1 */
4625 { "stui", { Skip_MODRM
}, 0 },
4628 /* X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1 */
4631 { "rmpquery", { Skip_MODRM
}, 0 },
4634 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1 */
4637 { "rmpadjust", { Skip_MODRM
}, 0 },
4640 /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */
4643 { "rmpupdate", { Skip_MODRM
}, 0 },
4646 /* X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1 */
4649 { "psmash", { Skip_MODRM
}, 0 },
4652 /* X86_64_0F18_REG_6_MOD_0 */
4654 { "nopQ", { Ev
}, 0 },
4655 { PREFIX_TABLE (PREFIX_0F18_REG_6_MOD_0_X86_64
) },
4658 /* X86_64_0F18_REG_7_MOD_0 */
4660 { "nopQ", { Ev
}, 0 },
4661 { PREFIX_TABLE (PREFIX_0F18_REG_7_MOD_0_X86_64
) },
4666 { "movZ", { Em
, Td
}, 0 },
4671 { "movZ", { Td
, Em
}, 0 },
4677 { "movrsB", { Gb
, Mb
}, PREFIX_OPCODE
},
4683 { "movrsS", { Gv
, Mv
}, PREFIX_OPCODE
},
4687 /* X86_64_0F38F8_M_1 */
4689 { PREFIX_TABLE (PREFIX_0F38F8_M_1_X86_64
) },
4692 /* X86_64_0FC7_REG_6_MOD_3_PREFIX_1 */
4695 { "senduipi", { Eq
}, 0 },
4698 /* X86_64_VEX_0F3848 */
4701 { VEX_LEN_TABLE (VEX_LEN_0F3848_X86_64
) },
4704 /* X86_64_VEX_0F3849 */
4707 { VEX_LEN_TABLE (VEX_LEN_0F3849_X86_64
) },
4710 /* X86_64_VEX_0F384A */
4713 { VEX_W_TABLE (VEX_W_0F384A_X86_64
) },
4716 /* X86_64_VEX_0F384B */
4719 { VEX_LEN_TABLE (VEX_LEN_0F384B_X86_64
) },
4722 /* X86_64_VEX_0F385C */
4725 { VEX_LEN_TABLE (VEX_LEN_0F385C_X86_64
) },
4728 /* X86_64_VEX_0F385E */
4731 { VEX_LEN_TABLE (VEX_LEN_0F385E_X86_64
) },
4734 /* X86_64_VEX_0F385F */
4737 { VEX_LEN_TABLE (VEX_LEN_0F385F_X86_64
) },
4740 /* X86_64_VEX_0F386B */
4743 { VEX_LEN_TABLE (VEX_LEN_0F386B_X86_64
) },
4746 /* X86_64_VEX_0F386C */
4749 { VEX_LEN_TABLE (VEX_LEN_0F386C_X86_64
) },
4752 /* X86_64_VEX_0F386E */
4755 { VEX_LEN_TABLE (VEX_LEN_0F386E_X86_64
) },
4758 /* X86_64_VEX_0F386F */
4761 { VEX_LEN_TABLE (VEX_LEN_0F386F_X86_64
) },
4764 /* X86_64_VEX_0F38Ex */
4767 { "%XEcmp%CCxadd", { Mdq
, Gdq
, VexGdq
}, PREFIX_DATA
},
4770 /* X86_64_VEX_MAP5_F8 */
4773 { VEX_LEN_TABLE (VEX_LEN_MAP5_F8_X86_64
) },
4776 /* X86_64_VEX_MAP5_F9 */
4779 { VEX_LEN_TABLE (VEX_LEN_MAP5_F9_X86_64
) },
4782 /* X86_64_VEX_MAP5_FD */
4785 { VEX_LEN_TABLE (VEX_LEN_MAP5_FD_X86_64
) },
4788 /* X86_64_VEX_MAP7_F6_L_0_W_0_R_0 */
4791 { PREFIX_TABLE (PREFIX_VEX_MAP7_F6_L_0_W_0_R_0_X86_64
) },
4794 /* X86_64_VEX_MAP7_F8_L_0_W_0_R_0 */
4797 { PREFIX_TABLE (PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64
) },
4800 #include "i386-dis-evex-x86-64.h"
4803 static const struct dis386 three_byte_table
[][256] = {
4805 /* THREE_BYTE_0F38 */
4808 { "pshufb", { MX
, EM
}, PREFIX_OPCODE
},
4809 { "phaddw", { MX
, EM
}, PREFIX_OPCODE
},
4810 { "phaddd", { MX
, EM
}, PREFIX_OPCODE
},
4811 { "phaddsw", { MX
, EM
}, PREFIX_OPCODE
},
4812 { "pmaddubsw", { MX
, EM
}, PREFIX_OPCODE
},
4813 { "phsubw", { MX
, EM
}, PREFIX_OPCODE
},
4814 { "phsubd", { MX
, EM
}, PREFIX_OPCODE
},
4815 { "phsubsw", { MX
, EM
}, PREFIX_OPCODE
},
4817 { "psignb", { MX
, EM
}, PREFIX_OPCODE
},
4818 { "psignw", { MX
, EM
}, PREFIX_OPCODE
},
4819 { "psignd", { MX
, EM
}, PREFIX_OPCODE
},
4820 { "pmulhrsw", { MX
, EM
}, PREFIX_OPCODE
},
4826 { "pblendvb", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4830 { "blendvps", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4831 { "blendvpd", { XM
, EXx
, XMM0
}, PREFIX_DATA
},
4833 { "ptest", { XM
, EXx
}, PREFIX_DATA
},
4839 { "pabsb", { MX
, EM
}, PREFIX_OPCODE
},
4840 { "pabsw", { MX
, EM
}, PREFIX_OPCODE
},
4841 { "pabsd", { MX
, EM
}, PREFIX_OPCODE
},
4844 { "pmovsxbw", { XM
, EXq
}, PREFIX_DATA
},
4845 { "pmovsxbd", { XM
, EXd
}, PREFIX_DATA
},
4846 { "pmovsxbq", { XM
, EXw
}, PREFIX_DATA
},
4847 { "pmovsxwd", { XM
, EXq
}, PREFIX_DATA
},
4848 { "pmovsxwq", { XM
, EXd
}, PREFIX_DATA
},
4849 { "pmovsxdq", { XM
, EXq
}, PREFIX_DATA
},
4853 { "pmuldq", { XM
, EXx
}, PREFIX_DATA
},
4854 { "pcmpeqq", { XM
, EXx
}, PREFIX_DATA
},
4855 { "movntdqa", { XM
, Mx
}, PREFIX_DATA
},
4856 { "packusdw", { XM
, EXx
}, PREFIX_DATA
},
4862 { "pmovzxbw", { XM
, EXq
}, PREFIX_DATA
},
4863 { "pmovzxbd", { XM
, EXd
}, PREFIX_DATA
},
4864 { "pmovzxbq", { XM
, EXw
}, PREFIX_DATA
},
4865 { "pmovzxwd", { XM
, EXq
}, PREFIX_DATA
},
4866 { "pmovzxwq", { XM
, EXd
}, PREFIX_DATA
},
4867 { "pmovzxdq", { XM
, EXq
}, PREFIX_DATA
},
4869 { "pcmpgtq", { XM
, EXx
}, PREFIX_DATA
},
4871 { "pminsb", { XM
, EXx
}, PREFIX_DATA
},
4872 { "pminsd", { XM
, EXx
}, PREFIX_DATA
},
4873 { "pminuw", { XM
, EXx
}, PREFIX_DATA
},
4874 { "pminud", { XM
, EXx
}, PREFIX_DATA
},
4875 { "pmaxsb", { XM
, EXx
}, PREFIX_DATA
},
4876 { "pmaxsd", { XM
, EXx
}, PREFIX_DATA
},
4877 { "pmaxuw", { XM
, EXx
}, PREFIX_DATA
},
4878 { "pmaxud", { XM
, EXx
}, PREFIX_DATA
},
4880 { "pmulld", { XM
, EXx
}, PREFIX_DATA
},
4881 { "phminposuw", { XM
, EXx
}, PREFIX_DATA
},
4952 { "invept", { Gm
, Mo
}, PREFIX_DATA
},
4953 { "invvpid", { Gm
, Mo
}, PREFIX_DATA
},
4954 { "invpcid", { Gm
, M
}, PREFIX_DATA
},
4963 { X86_64_TABLE (X86_64_0F388A
) },
4964 { X86_64_TABLE (X86_64_0F388B
) },
5033 { "sha1nexte", { XM
, EXxmm
}, PREFIX_OPCODE
},
5034 { "sha1msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
5035 { "sha1msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
5036 { "sha256rnds2", { XM
, EXxmm
, XMM0
}, PREFIX_OPCODE
},
5037 { "sha256msg1", { XM
, EXxmm
}, PREFIX_OPCODE
},
5038 { "sha256msg2", { XM
, EXxmm
}, PREFIX_OPCODE
},
5040 { "gf2p8mulb", { XM
, EXxmm
}, PREFIX_DATA
},
5051 { PREFIX_TABLE (PREFIX_0F38D8
) },
5054 { "aesimc", { XM
, EXx
}, PREFIX_DATA
},
5055 { PREFIX_TABLE (PREFIX_0F38DC
) },
5056 { PREFIX_TABLE (PREFIX_0F38DD
) },
5057 { PREFIX_TABLE (PREFIX_0F38DE
) },
5058 { PREFIX_TABLE (PREFIX_0F38DF
) },
5078 { PREFIX_TABLE (PREFIX_0F38F0
) },
5079 { PREFIX_TABLE (PREFIX_0F38F1
) },
5083 { "wrussK", { M
, Gdq
}, PREFIX_DATA
},
5084 { PREFIX_TABLE (PREFIX_0F38F6
) },
5087 { MOD_TABLE (MOD_0F38F8
) },
5088 { "movdiri", { Mdq
, Gdq
}, PREFIX_OPCODE
},
5089 { PREFIX_TABLE (PREFIX_0F38FA
) },
5090 { PREFIX_TABLE (PREFIX_0F38FB
) },
5091 { PREFIX_TABLE (PREFIX_0F38FC
) },
5096 /* THREE_BYTE_0F3A */
5108 { "roundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5109 { "roundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5110 { "roundss", { XM
, EXd
, Ib
}, PREFIX_DATA
},
5111 { "roundsd", { XM
, EXq
, Ib
}, PREFIX_DATA
},
5112 { "blendps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5113 { "blendpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5114 { "pblendw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5115 { "palignr", { MX
, EM
, Ib
}, PREFIX_OPCODE
},
5121 { "pextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
5122 { "pextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
5123 { "pextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
5124 { "extractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
5135 { "pinsrb", { XM
, Edb
, Ib
}, PREFIX_DATA
},
5136 { "insertps", { XM
, EXd
, Ib
}, PREFIX_DATA
},
5137 { "pinsrK", { XM
, Edq
, Ib
}, PREFIX_DATA
},
5171 { "dpps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5172 { "dppd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5173 { "mpsadbw", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5175 { "pclmulqdq", { XM
, EXx
, PCLMUL
}, PREFIX_DATA
},
5207 { "pcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5208 { "pcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5209 { "pcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5210 { "pcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5328 { "sha1rnds4", { XM
, EXxmm
, Ib
}, PREFIX_OPCODE
},
5330 { "gf2p8affineqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
5331 { "gf2p8affineinvqb", { XM
, EXxmm
, Ib
}, PREFIX_DATA
},
5349 { "aeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
5369 { PREFIX_TABLE (PREFIX_0F3A0F
) },
5389 static const struct dis386 xop_table
[][256] = {
5542 { VEX_LEN_TABLE (VEX_LEN_XOP_08_85
) },
5543 { VEX_LEN_TABLE (VEX_LEN_XOP_08_86
) },
5544 { VEX_LEN_TABLE (VEX_LEN_XOP_08_87
) },
5552 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8E
) },
5553 { VEX_LEN_TABLE (VEX_LEN_XOP_08_8F
) },
5560 { VEX_LEN_TABLE (VEX_LEN_XOP_08_95
) },
5561 { VEX_LEN_TABLE (VEX_LEN_XOP_08_96
) },
5562 { VEX_LEN_TABLE (VEX_LEN_XOP_08_97
) },
5570 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9E
) },
5571 { VEX_LEN_TABLE (VEX_LEN_XOP_08_9F
) },
5575 { "vpcmov", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
5576 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A3
) },
5579 { VEX_LEN_TABLE (VEX_LEN_XOP_08_A6
) },
5597 { VEX_LEN_TABLE (VEX_LEN_XOP_08_B6
) },
5609 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C0
) },
5610 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C1
) },
5611 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C2
) },
5612 { VEX_LEN_TABLE (VEX_LEN_XOP_08_C3
) },
5622 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CC
) },
5623 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CD
) },
5624 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CE
) },
5625 { VEX_LEN_TABLE (VEX_LEN_XOP_08_CF
) },
5658 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EC
) },
5659 { VEX_LEN_TABLE (VEX_LEN_XOP_08_ED
) },
5660 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EE
) },
5661 { VEX_LEN_TABLE (VEX_LEN_XOP_08_EF
) },
5685 { VEX_LEN_TABLE (VEX_LEN_XOP_09_01
) },
5686 { VEX_LEN_TABLE (VEX_LEN_XOP_09_02
) },
5704 { VEX_LEN_TABLE (VEX_LEN_XOP_09_12
) },
5828 { VEX_W_TABLE (VEX_W_XOP_09_80
) },
5829 { VEX_W_TABLE (VEX_W_XOP_09_81
) },
5830 { VEX_W_TABLE (VEX_W_XOP_09_82
) },
5831 { VEX_W_TABLE (VEX_W_XOP_09_83
) },
5846 { VEX_LEN_TABLE (VEX_LEN_XOP_09_90
) },
5847 { VEX_LEN_TABLE (VEX_LEN_XOP_09_91
) },
5848 { VEX_LEN_TABLE (VEX_LEN_XOP_09_92
) },
5849 { VEX_LEN_TABLE (VEX_LEN_XOP_09_93
) },
5850 { VEX_LEN_TABLE (VEX_LEN_XOP_09_94
) },
5851 { VEX_LEN_TABLE (VEX_LEN_XOP_09_95
) },
5852 { VEX_LEN_TABLE (VEX_LEN_XOP_09_96
) },
5853 { VEX_LEN_TABLE (VEX_LEN_XOP_09_97
) },
5855 { VEX_LEN_TABLE (VEX_LEN_XOP_09_98
) },
5856 { VEX_LEN_TABLE (VEX_LEN_XOP_09_99
) },
5857 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9A
) },
5858 { VEX_LEN_TABLE (VEX_LEN_XOP_09_9B
) },
5901 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C1
) },
5902 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C2
) },
5903 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C3
) },
5906 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C6
) },
5907 { VEX_LEN_TABLE (VEX_LEN_XOP_09_C7
) },
5912 { VEX_LEN_TABLE (VEX_LEN_XOP_09_CB
) },
5919 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D1
) },
5920 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D2
) },
5921 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D3
) },
5924 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D6
) },
5925 { VEX_LEN_TABLE (VEX_LEN_XOP_09_D7
) },
5930 { VEX_LEN_TABLE (VEX_LEN_XOP_09_DB
) },
5937 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E1
) },
5938 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E2
) },
5939 { VEX_LEN_TABLE (VEX_LEN_XOP_09_E3
) },
5993 { "bextrS", { Gdq
, Edq
, Id
}, 0 },
5995 { VEX_LEN_TABLE (VEX_LEN_XOP_0A_12
) },
6265 static const struct dis386 vex_table
[][256] = {
6287 { PREFIX_TABLE (PREFIX_0F10
) },
6288 { PREFIX_TABLE (PREFIX_0F11
) },
6289 { PREFIX_TABLE (PREFIX_VEX_0F12
) },
6290 { VEX_LEN_TABLE (VEX_LEN_0F13
) },
6291 { "vunpcklpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6292 { "vunpckhpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6293 { PREFIX_TABLE (PREFIX_VEX_0F16
) },
6294 { VEX_LEN_TABLE (VEX_LEN_0F17
) },
6314 { "vmovapX", { XM
, EXx
}, PREFIX_OPCODE
},
6315 { "vmovapX", { EXxS
, XM
}, PREFIX_OPCODE
},
6316 { PREFIX_TABLE (PREFIX_VEX_0F2A
) },
6317 { "vmovntpX", { Mx
, XM
}, PREFIX_OPCODE
},
6318 { PREFIX_TABLE (PREFIX_VEX_0F2C
) },
6319 { PREFIX_TABLE (PREFIX_VEX_0F2D
) },
6320 { PREFIX_TABLE (PREFIX_0F2E
) },
6321 { PREFIX_TABLE (PREFIX_0F2F
) },
6342 { VEX_LEN_TABLE (VEX_LEN_0F41
) },
6343 { VEX_LEN_TABLE (VEX_LEN_0F42
) },
6345 { VEX_LEN_TABLE (VEX_LEN_0F44
) },
6346 { VEX_LEN_TABLE (VEX_LEN_0F45
) },
6347 { VEX_LEN_TABLE (VEX_LEN_0F46
) },
6348 { VEX_LEN_TABLE (VEX_LEN_0F47
) },
6352 { VEX_LEN_TABLE (VEX_LEN_0F4A
) },
6353 { VEX_LEN_TABLE (VEX_LEN_0F4B
) },
6359 { "vmovmskpX", { Gdq
, Ux
}, PREFIX_OPCODE
},
6360 { PREFIX_TABLE (PREFIX_0F51
) },
6361 { PREFIX_TABLE (PREFIX_0F52
) },
6362 { PREFIX_TABLE (PREFIX_0F53
) },
6363 { "vandpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6364 { "vandnpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6365 { "vorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6366 { "vxorpX", { XM
, Vex
, EXx
}, PREFIX_OPCODE
},
6368 { PREFIX_TABLE (PREFIX_0F58
) },
6369 { PREFIX_TABLE (PREFIX_0F59
) },
6370 { PREFIX_TABLE (PREFIX_0F5A
) },
6371 { PREFIX_TABLE (PREFIX_0F5B
) },
6372 { PREFIX_TABLE (PREFIX_0F5C
) },
6373 { PREFIX_TABLE (PREFIX_0F5D
) },
6374 { PREFIX_TABLE (PREFIX_0F5E
) },
6375 { PREFIX_TABLE (PREFIX_0F5F
) },
6377 { "vpunpcklbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6378 { "vpunpcklwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6379 { "vpunpckldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6380 { "vpacksswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6381 { "vpcmpgtb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6382 { "vpcmpgtw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6383 { "vpcmpgtd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6384 { "vpackuswb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6386 { "vpunpckhbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6387 { "vpunpckhwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6388 { "vpunpckhdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6389 { "vpackssdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6390 { "vpunpcklqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6391 { "vpunpckhqdq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6392 { VEX_LEN_TABLE (VEX_LEN_0F6E
) },
6393 { PREFIX_TABLE (PREFIX_VEX_0F6F
) },
6395 { PREFIX_TABLE (PREFIX_VEX_0F70
) },
6396 { REG_TABLE (REG_VEX_0F71
) },
6397 { REG_TABLE (REG_VEX_0F72
) },
6398 { REG_TABLE (REG_VEX_0F73
) },
6399 { "vpcmpeqb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6400 { "vpcmpeqw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6401 { "vpcmpeqd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6402 { VEX_LEN_TABLE (VEX_LEN_0F77
) },
6408 { PREFIX_TABLE (PREFIX_0F7C
) },
6409 { PREFIX_TABLE (PREFIX_0F7D
) },
6410 { PREFIX_TABLE (PREFIX_VEX_0F7E
) },
6411 { PREFIX_TABLE (PREFIX_VEX_0F7F
) },
6431 { VEX_LEN_TABLE (VEX_LEN_0F90
) },
6432 { VEX_LEN_TABLE (VEX_LEN_0F91
) },
6433 { VEX_LEN_TABLE (VEX_LEN_0F92
) },
6434 { VEX_LEN_TABLE (VEX_LEN_0F93
) },
6440 { VEX_LEN_TABLE (VEX_LEN_0F98
) },
6441 { VEX_LEN_TABLE (VEX_LEN_0F99
) },
6464 { REG_TABLE (REG_VEX_0FAE
) },
6487 { PREFIX_TABLE (PREFIX_0FC2
) },
6489 { VEX_LEN_TABLE (VEX_LEN_0FC4
) },
6490 { "vpextrw", { Gd
, Uxmm
, Ib
}, PREFIX_DATA
},
6491 { "vshufpX", { XM
, Vex
, EXx
, Ib
}, PREFIX_OPCODE
},
6503 { PREFIX_TABLE (PREFIX_0FD0
) },
6504 { "vpsrlw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6505 { "vpsrld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6506 { "vpsrlq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6507 { "vpaddq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6508 { "vpmullw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6509 { VEX_LEN_TABLE (VEX_LEN_0FD6
) },
6510 { "vpmovmskb", { Gdq
, Ux
}, PREFIX_DATA
},
6512 { "vpsubusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6513 { "vpsubusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6514 { "vpminub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6515 { "vpand", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6516 { "vpaddusb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6517 { "vpaddusw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6518 { "vpmaxub", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6519 { "vpandn", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6521 { "vpavgb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6522 { "vpsraw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6523 { "vpsrad", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6524 { "vpavgw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6525 { "vpmulhuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6526 { "vpmulhw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6527 { PREFIX_TABLE (PREFIX_0FE6
) },
6528 { "vmovntdq", { Mx
, XM
}, PREFIX_DATA
},
6530 { "vpsubsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6531 { "vpsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6532 { "vpminsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6533 { "vpor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6534 { "vpaddsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6535 { "vpaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6536 { "vpmaxsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6537 { "vpxor", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6539 { PREFIX_TABLE (PREFIX_0FF0
) },
6540 { "vpsllw", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6541 { "vpslld", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6542 { "vpsllq", { XM
, Vex
, EXxmm
}, PREFIX_DATA
},
6543 { "vpmuludq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6544 { "vpmaddwd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6545 { "vpsadbw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6546 { "vmaskmovdqu", { XM
, Uxmm
}, PREFIX_DATA
},
6548 { "vpsubb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6549 { "vpsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6550 { "vpsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6551 { "vpsubq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6552 { "vpaddb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6553 { "vpaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6554 { "vpaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6560 { "vpshufb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6561 { "vphaddw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6562 { "vphaddd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6563 { "vphaddsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6564 { "vpmaddubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6565 { "vphsubw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6566 { "vphsubd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6567 { "vphsubsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6569 { "vpsignb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6570 { "vpsignw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6571 { "vpsignd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6572 { "vpmulhrsw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6573 { VEX_W_TABLE (VEX_W_0F380C
) },
6574 { VEX_W_TABLE (VEX_W_0F380D
) },
6575 { VEX_W_TABLE (VEX_W_0F380E
) },
6576 { VEX_W_TABLE (VEX_W_0F380F
) },
6581 { VEX_W_TABLE (VEX_W_0F3813
) },
6584 { VEX_LEN_TABLE (VEX_LEN_0F3816
) },
6585 { "vptest", { XM
, EXx
}, PREFIX_DATA
},
6587 { VEX_W_TABLE (VEX_W_0F3818
) },
6588 { VEX_LEN_TABLE (VEX_LEN_0F3819
) },
6589 { VEX_LEN_TABLE (VEX_LEN_0F381A
) },
6591 { "vpabsb", { XM
, EXx
}, PREFIX_DATA
},
6592 { "vpabsw", { XM
, EXx
}, PREFIX_DATA
},
6593 { "vpabsd", { XM
, EXx
}, PREFIX_DATA
},
6596 { "vpmovsxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6597 { "vpmovsxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6598 { "vpmovsxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6599 { "vpmovsxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6600 { "vpmovsxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6601 { "vpmovsxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6605 { "vpmuldq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6606 { "vpcmpeqq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6607 { "vmovntdqa", { XM
, Mx
}, PREFIX_DATA
},
6608 { "vpackusdw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6609 { VEX_W_TABLE (VEX_W_0F382C
) },
6610 { VEX_W_TABLE (VEX_W_0F382D
) },
6611 { VEX_W_TABLE (VEX_W_0F382E
) },
6612 { VEX_W_TABLE (VEX_W_0F382F
) },
6614 { "vpmovzxbw", { XM
, EXxmmq
}, PREFIX_DATA
},
6615 { "vpmovzxbd", { XM
, EXxmmqd
}, PREFIX_DATA
},
6616 { "vpmovzxbq", { XM
, EXxmmdw
}, PREFIX_DATA
},
6617 { "vpmovzxwd", { XM
, EXxmmq
}, PREFIX_DATA
},
6618 { "vpmovzxwq", { XM
, EXxmmqd
}, PREFIX_DATA
},
6619 { "vpmovzxdq", { XM
, EXxmmq
}, PREFIX_DATA
},
6620 { VEX_LEN_TABLE (VEX_LEN_0F3836
) },
6621 { "vpcmpgtq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6623 { "vpminsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6624 { "vpminsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6625 { "vpminuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6626 { "vpminud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6627 { "vpmaxsb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6628 { "vpmaxsd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6629 { "vpmaxuw", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6630 { "vpmaxud", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6632 { "vpmulld", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6633 { VEX_LEN_TABLE (VEX_LEN_0F3841
) },
6637 { "vpsrlv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6638 { VEX_W_TABLE (VEX_W_0F3846
) },
6639 { "vpsllv%DQ", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6641 { X86_64_TABLE (X86_64_VEX_0F3848
) },
6642 { X86_64_TABLE (X86_64_VEX_0F3849
) },
6643 { X86_64_TABLE (X86_64_VEX_0F384A
) },
6644 { X86_64_TABLE (X86_64_VEX_0F384B
) },
6650 { VEX_W_TABLE (VEX_W_0F3850
) },
6651 { VEX_W_TABLE (VEX_W_0F3851
) },
6652 { VEX_W_TABLE (VEX_W_0F3852
) },
6653 { VEX_W_TABLE (VEX_W_0F3853
) },
6659 { VEX_W_TABLE (VEX_W_0F3858
) },
6660 { VEX_W_TABLE (VEX_W_0F3859
) },
6661 { VEX_LEN_TABLE (VEX_LEN_0F385A
) },
6663 { X86_64_TABLE (X86_64_VEX_0F385C
) },
6665 { X86_64_TABLE (X86_64_VEX_0F385E
) },
6666 { X86_64_TABLE (X86_64_VEX_0F385F
) },
6680 { X86_64_TABLE (X86_64_VEX_0F386B
) },
6681 { X86_64_TABLE (X86_64_VEX_0F386C
) },
6683 { X86_64_TABLE (X86_64_VEX_0F386E
) },
6684 { X86_64_TABLE (X86_64_VEX_0F386F
) },
6688 { PREFIX_TABLE (PREFIX_VEX_0F3872
) },
6695 { VEX_W_TABLE (VEX_W_0F3878
) },
6696 { VEX_W_TABLE (VEX_W_0F3879
) },
6717 { "vpmaskmov%DQ", { XM
, Vex
, Mx
}, PREFIX_DATA
},
6719 { "vpmaskmov%DQ", { Mx
, Vex
, XM
}, PREFIX_DATA
},
6722 { "vpgatherd%DQ", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6723 { "vpgatherq%DQ", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6724 { "vgatherdp%XW", { XM
, MVexVSIBDWpX
, VexGatherD
}, PREFIX_DATA
},
6725 { "vgatherqp%XW", { XMGatherQ
, MVexVSIBQWpX
, VexGatherQ
}, PREFIX_DATA
},
6728 { "vfmaddsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6729 { "vfmsubadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6731 { "vfmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6732 { "vfmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6733 { "vfmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6734 { "vfmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6735 { "vfnmadd132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6736 { "vfnmadd132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6737 { "vfnmsub132p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6738 { "vfnmsub132s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6746 { "vfmaddsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6747 { "vfmsubadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6749 { "vfmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6750 { "vfmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6751 { "vfmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6752 { "vfmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6753 { "vfnmadd213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6754 { "vfnmadd213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6755 { "vfnmsub213p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6756 { "vfnmsub213s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6758 { VEX_W_TABLE (VEX_W_0F38B0
) },
6759 { VEX_W_TABLE (VEX_W_0F38B1
) },
6762 { VEX_W_TABLE (VEX_W_0F38B4
) },
6763 { VEX_W_TABLE (VEX_W_0F38B5
) },
6764 { "vfmaddsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6765 { "vfmsubadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6767 { "vfmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6768 { "vfmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6769 { "vfmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6770 { "vfmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6771 { "vfnmadd231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6772 { "vfnmadd231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6773 { "vfnmsub231p%XW", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6774 { "vfnmsub231s%XW", { XMScalar
, VexScalar
, EXdq
}, PREFIX_DATA
},
6788 { PREFIX_TABLE (PREFIX_VEX_0F38CB
) },
6789 { PREFIX_TABLE (PREFIX_VEX_0F38CC
) },
6790 { PREFIX_TABLE (PREFIX_VEX_0F38CD
) },
6792 { VEX_W_TABLE (VEX_W_0F38CF
) },
6796 { VEX_W_TABLE (VEX_W_0F38D2
) },
6797 { VEX_W_TABLE (VEX_W_0F38D3
) },
6805 { VEX_W_TABLE (VEX_W_0F38DA
) },
6806 { VEX_LEN_TABLE (VEX_LEN_0F38DB
) },
6807 { "vaesenc", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6808 { "vaesenclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6809 { "vaesdec", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6810 { "vaesdeclast", { XM
, Vex
, EXx
}, PREFIX_DATA
},
6812 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6813 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6814 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6815 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6816 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6817 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6818 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6819 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6821 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6822 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6823 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6824 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6825 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6826 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6827 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6828 { X86_64_TABLE (X86_64_VEX_0F38Ex
) },
6832 { VEX_LEN_TABLE (VEX_LEN_0F38F2
) },
6833 { VEX_LEN_TABLE (VEX_LEN_0F38F3
) },
6835 { VEX_LEN_TABLE (VEX_LEN_0F38F5
) },
6836 { VEX_LEN_TABLE (VEX_LEN_0F38F6
) },
6837 { VEX_LEN_TABLE (VEX_LEN_0F38F7
) },
6851 { VEX_LEN_TABLE (VEX_LEN_0F3A00
) },
6852 { VEX_LEN_TABLE (VEX_LEN_0F3A01
) },
6853 { VEX_W_TABLE (VEX_W_0F3A02
) },
6855 { VEX_W_TABLE (VEX_W_0F3A04
) },
6856 { VEX_W_TABLE (VEX_W_0F3A05
) },
6857 { VEX_LEN_TABLE (VEX_LEN_0F3A06
) },
6860 { "vroundps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6861 { "vroundpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
6862 { "vroundss", { XMScalar
, VexScalar
, EXd
, Ib
}, PREFIX_DATA
},
6863 { "vroundsd", { XMScalar
, VexScalar
, EXq
, Ib
}, PREFIX_DATA
},
6864 { "vblendps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6865 { "vblendpd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6866 { "vpblendw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6867 { "vpalignr", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6873 { VEX_LEN_TABLE (VEX_LEN_0F3A14
) },
6874 { VEX_LEN_TABLE (VEX_LEN_0F3A15
) },
6875 { VEX_LEN_TABLE (VEX_LEN_0F3A16
) },
6876 { VEX_LEN_TABLE (VEX_LEN_0F3A17
) },
6878 { VEX_LEN_TABLE (VEX_LEN_0F3A18
) },
6879 { VEX_LEN_TABLE (VEX_LEN_0F3A19
) },
6883 { VEX_W_TABLE (VEX_W_0F3A1D
) },
6887 { VEX_LEN_TABLE (VEX_LEN_0F3A20
) },
6888 { VEX_LEN_TABLE (VEX_LEN_0F3A21
) },
6889 { VEX_LEN_TABLE (VEX_LEN_0F3A22
) },
6905 { VEX_LEN_TABLE (VEX_LEN_0F3A30
) },
6906 { VEX_LEN_TABLE (VEX_LEN_0F3A31
) },
6907 { VEX_LEN_TABLE (VEX_LEN_0F3A32
) },
6908 { VEX_LEN_TABLE (VEX_LEN_0F3A33
) },
6914 { VEX_LEN_TABLE (VEX_LEN_0F3A38
) },
6915 { VEX_LEN_TABLE (VEX_LEN_0F3A39
) },
6923 { "vdpps", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6924 { VEX_LEN_TABLE (VEX_LEN_0F3A41
) },
6925 { "vmpsadbw", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
6927 { "vpclmulqdq", { XM
, Vex
, EXx
, PCLMUL
}, PREFIX_DATA
},
6929 { VEX_LEN_TABLE (VEX_LEN_0F3A46
) },
6932 { "vpermil2ps", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6933 { "vpermil2pd", { XM
, Vex
, EXx
, XMVexI4
, VexI4
}, PREFIX_DATA
},
6934 { VEX_W_TABLE (VEX_W_0F3A4A
) },
6935 { VEX_W_TABLE (VEX_W_0F3A4B
) },
6936 { VEX_W_TABLE (VEX_W_0F3A4C
) },
6954 { "vfmaddsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6955 { "vfmaddsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6956 { "vfmsubaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6957 { "vfmsubaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6959 { VEX_LEN_TABLE (VEX_LEN_0F3A60
) },
6960 { VEX_LEN_TABLE (VEX_LEN_0F3A61
) },
6961 { VEX_LEN_TABLE (VEX_LEN_0F3A62
) },
6962 { VEX_LEN_TABLE (VEX_LEN_0F3A63
) },
6968 { "vfmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6969 { "vfmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6970 { "vfmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6971 { "vfmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6972 { "vfmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6973 { "vfmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6974 { "vfmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6975 { "vfmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6986 { "vfnmaddps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6987 { "vfnmaddpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6988 { "vfnmaddss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6989 { "vfnmaddsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
6990 { "vfnmsubps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6991 { "vfnmsubpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
6992 { "vfnmsubss", { XMScalar
, VexScalar
, EXd
, XMVexScalarI4
}, PREFIX_DATA
},
6993 { "vfnmsubsd", { XMScalar
, VexScalar
, EXq
, XMVexScalarI4
}, PREFIX_DATA
},
7082 { VEX_W_TABLE (VEX_W_0F3ACE
) },
7083 { VEX_W_TABLE (VEX_W_0F3ACF
) },
7100 { VEX_W_TABLE (VEX_W_0F3ADE
) },
7101 { VEX_LEN_TABLE (VEX_LEN_0F3ADF
) },
7121 { VEX_LEN_TABLE (VEX_LEN_0F3AF0
) },
7141 #include "i386-dis-evex.h"
7143 static const struct dis386 vex_len_table
[][2] = {
7144 /* VEX_LEN_0F12_P_0 */
7146 { MOD_TABLE (MOD_0F12_PREFIX_0
) },
7149 /* VEX_LEN_0F12_P_2 */
7151 { "%XEVmovlpYX", { XM
, Vex
, Mq
}, 0 },
7156 { "%XEVmovlpYX", { Mq
, XM
}, PREFIX_OPCODE
},
7159 /* VEX_LEN_0F16_P_0 */
7161 { MOD_TABLE (MOD_0F16_PREFIX_0
) },
7164 /* VEX_LEN_0F16_P_2 */
7166 { "%XEVmovhpYX", { XM
, Vex
, Mq
}, 0 },
7171 { "%XEVmovhpYX", { Mq
, XM
}, PREFIX_OPCODE
},
7177 { VEX_W_TABLE (VEX_W_0F41_L_1
) },
7183 { VEX_W_TABLE (VEX_W_0F42_L_1
) },
7188 { VEX_W_TABLE (VEX_W_0F44_L_0
) },
7194 { VEX_W_TABLE (VEX_W_0F45_L_1
) },
7200 { VEX_W_TABLE (VEX_W_0F46_L_1
) },
7206 { VEX_W_TABLE (VEX_W_0F47_L_1
) },
7212 { VEX_W_TABLE (VEX_W_0F4A_L_1
) },
7218 { VEX_W_TABLE (VEX_W_0F4B_L_1
) },
7223 { "%XEvmovYK", { XMScalar
, Edq
}, PREFIX_DATA
},
7228 { "vzeroupper", { XX
}, 0 },
7229 { "vzeroall", { XX
}, 0 },
7232 /* VEX_LEN_0F7E_P_1 */
7234 { "%XEvmovqY", { XMScalar
, EXq
}, 0 },
7237 /* VEX_LEN_0F7E_P_2 */
7239 { "%XEvmovK", { Edq
, XMScalar
}, 0 },
7244 { VEX_W_TABLE (VEX_W_0F90_L_0
) },
7249 { VEX_W_TABLE (VEX_W_0F91_L_0
) },
7254 { VEX_W_TABLE (VEX_W_0F92_L_0
) },
7259 { VEX_W_TABLE (VEX_W_0F93_L_0
) },
7264 { VEX_W_TABLE (VEX_W_0F98_L_0
) },
7269 { VEX_W_TABLE (VEX_W_0F99_L_0
) },
7272 /* VEX_LEN_0FAE_R_2 */
7274 { "vldmxcsr", { Md
}, 0 },
7277 /* VEX_LEN_0FAE_R_3 */
7279 { "vstmxcsr", { Md
}, 0 },
7284 { "%XEvpinsrwY", { XM
, Vex
, Edw
, Ib
}, PREFIX_DATA
},
7289 { "%XEvmovqY", { EXqS
, XMScalar
}, PREFIX_DATA
},
7292 /* VEX_LEN_0F3816 */
7295 { VEX_W_TABLE (VEX_W_0F3816_L_1
) },
7298 /* VEX_LEN_0F3819 */
7301 { VEX_W_TABLE (VEX_W_0F3819_L_1
) },
7304 /* VEX_LEN_0F381A */
7307 { VEX_W_TABLE (VEX_W_0F381A_L_1
) },
7310 /* VEX_LEN_0F3836 */
7313 { VEX_W_TABLE (VEX_W_0F3836
) },
7316 /* VEX_LEN_0F3841 */
7318 { "vphminposuw", { XM
, EXx
}, PREFIX_DATA
},
7321 /* VEX_LEN_0F3848_X86_64 */
7323 { VEX_W_TABLE (VEX_W_0F3848_X86_64_L_0
) },
7326 /* VEX_LEN_0F3849_X86_64 */
7328 { VEX_W_TABLE (VEX_W_0F3849_X86_64_L_0
) },
7331 /* VEX_LEN_0F384A_X86_64_W_0 */
7333 { PREFIX_TABLE (PREFIX_VEX_0F384A_X86_64_W_0_L_0
) },
7336 /* VEX_LEN_0F384B_X86_64 */
7338 { VEX_W_TABLE (VEX_W_0F384B_X86_64_L_0
) },
7341 /* VEX_LEN_0F385A */
7344 { VEX_W_TABLE (VEX_W_0F385A_L_0
) },
7347 /* VEX_LEN_0F385C_X86_64 */
7349 { VEX_W_TABLE (VEX_W_0F385C_X86_64_L_0
) },
7352 /* VEX_LEN_0F385E_X86_64 */
7354 { VEX_W_TABLE (VEX_W_0F385E_X86_64_L_0
) },
7357 /* VEX_LEN_0F385F_X86_64 */
7359 { VEX_W_TABLE (VEX_W_0F385F_X86_64_L_0
) },
7362 /* VEX_LEN_0F386B_X86_64 */
7364 { VEX_W_TABLE (VEX_W_0F386B_X86_64_L_0
) },
7367 /* VEX_LEN_0F386C_X86_64 */
7369 { VEX_W_TABLE (VEX_W_0F386C_X86_64_L_0
) },
7372 /* VEX_LEN_0F386E_X86_64 */
7374 { VEX_W_TABLE (VEX_W_0F386E_X86_64_L_0
) },
7377 /* VEX_LEN_0F386F_X86_64 */
7379 { VEX_W_TABLE (VEX_W_0F386F_X86_64_L_0
) },
7382 /* VEX_LEN_0F38CB_P_3_W_0 */
7385 { "vsha512rnds2", { XM
, Vex
, Rxmmq
}, 0 },
7388 /* VEX_LEN_0F38CC_P_3_W_0 */
7391 { "vsha512msg1", { XM
, Rxmmq
}, 0 },
7394 /* VEX_LEN_0F38CD_P_3_W_0 */
7397 { "vsha512msg2", { XM
, Rymm
}, 0 },
7400 /* VEX_LEN_0F38DA_W_0_P_0 */
7402 { "vsm3msg1", { XM
, Vex
, EXxmm
}, 0 },
7405 /* VEX_LEN_0F38DA_W_0_P_2 */
7407 { "vsm3msg2", { XM
, Vex
, EXxmm
}, 0 },
7410 /* VEX_LEN_0F38DB */
7412 { "vaesimc", { XM
, EXx
}, PREFIX_DATA
},
7415 /* VEX_LEN_0F38F2 */
7417 { PREFIX_TABLE (PREFIX_VEX_0F38F2_L_0
) },
7420 /* VEX_LEN_0F38F3 */
7422 { PREFIX_TABLE (PREFIX_VEX_0F38F3_L_0
) },
7425 /* VEX_LEN_0F38F5 */
7427 { PREFIX_TABLE(PREFIX_VEX_0F38F5_L_0
) },
7430 /* VEX_LEN_0F38F6 */
7432 { PREFIX_TABLE(PREFIX_VEX_0F38F6_L_0
) },
7435 /* VEX_LEN_0F38F7 */
7437 { PREFIX_TABLE(PREFIX_VEX_0F38F7_L_0
) },
7440 /* VEX_LEN_0F3A00 */
7443 { VEX_W_TABLE (VEX_W_0F3A00_L_1
) },
7446 /* VEX_LEN_0F3A01 */
7449 { VEX_W_TABLE (VEX_W_0F3A01_L_1
) },
7452 /* VEX_LEN_0F3A06 */
7455 { VEX_W_TABLE (VEX_W_0F3A06_L_1
) },
7458 /* VEX_LEN_0F3A14 */
7460 { "%XEvpextrb", { Edb
, XM
, Ib
}, PREFIX_DATA
},
7463 /* VEX_LEN_0F3A15 */
7465 { "%XEvpextrw", { Edw
, XM
, Ib
}, PREFIX_DATA
},
7468 /* VEX_LEN_0F3A16 */
7470 { "%XEvpextrK", { Edq
, XM
, Ib
}, PREFIX_DATA
},
7473 /* VEX_LEN_0F3A17 */
7475 { "%XEvextractps", { Ed
, XM
, Ib
}, PREFIX_DATA
},
7478 /* VEX_LEN_0F3A18 */
7481 { VEX_W_TABLE (VEX_W_0F3A18_L_1
) },
7484 /* VEX_LEN_0F3A19 */
7487 { VEX_W_TABLE (VEX_W_0F3A19_L_1
) },
7490 /* VEX_LEN_0F3A20 */
7492 { "%XEvpinsrbY", { XM
, Vex
, Edb
, Ib
}, PREFIX_DATA
},
7495 /* VEX_LEN_0F3A21 */
7497 { "%XEvinsertpsY", { XM
, Vex
, EXd
, Ib
}, PREFIX_DATA
},
7500 /* VEX_LEN_0F3A22 */
7502 { "%XEvpinsrYK", { XM
, Vex
, Edq
, Ib
}, PREFIX_DATA
},
7505 /* VEX_LEN_0F3A30 */
7507 { "kshiftr%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7510 /* VEX_LEN_0F3A31 */
7512 { "kshiftr%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7515 /* VEX_LEN_0F3A32 */
7517 { "kshiftl%BW", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7520 /* VEX_LEN_0F3A33 */
7522 { "kshiftl%DQ", { MaskG
, MaskR
, Ib
}, PREFIX_DATA
},
7525 /* VEX_LEN_0F3A38 */
7528 { VEX_W_TABLE (VEX_W_0F3A38_L_1
) },
7531 /* VEX_LEN_0F3A39 */
7534 { VEX_W_TABLE (VEX_W_0F3A39_L_1
) },
7537 /* VEX_LEN_0F3A41 */
7539 { "vdppd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
7542 /* VEX_LEN_0F3A46 */
7545 { VEX_W_TABLE (VEX_W_0F3A46_L_1
) },
7548 /* VEX_LEN_0F3A60 */
7550 { "vpcmpestrm!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7553 /* VEX_LEN_0F3A61 */
7555 { "vpcmpestri!%LQ", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7558 /* VEX_LEN_0F3A62 */
7560 { "vpcmpistrm", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7563 /* VEX_LEN_0F3A63 */
7565 { "vpcmpistri", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7568 /* VEX_LEN_0F3ADE_W_0 */
7570 { "vsm3rnds2", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
7573 /* VEX_LEN_0F3ADF */
7575 { "vaeskeygenassist", { XM
, EXx
, Ib
}, PREFIX_DATA
},
7578 /* VEX_LEN_0F3AF0 */
7580 { PREFIX_TABLE (PREFIX_VEX_0F3AF0_L_0
) },
7583 /* VEX_LEN_MAP5_F8_X86_64 */
7585 { VEX_W_TABLE (VEX_W_MAP5_F8_X86_64_L_0
) },
7588 /* VEX_LEN_MAP5_F9_X86_64 */
7590 { VEX_W_TABLE (VEX_W_MAP5_F9_X86_64_L_0
) },
7593 /* VEX_LEN_MAP5_FD_X86_64 */
7595 { VEX_W_TABLE (VEX_W_MAP5_FD_X86_64_L_0
) },
7598 /* VEX_LEN_MAP7_F6 */
7600 { VEX_W_TABLE (VEX_W_MAP7_F6_L_0
) },
7603 /* VEX_LEN_MAP7_F8 */
7605 { VEX_W_TABLE (VEX_W_MAP7_F8_L_0
) },
7608 /* VEX_LEN_XOP_08_85 */
7610 { VEX_W_TABLE (VEX_W_XOP_08_85_L_0
) },
7613 /* VEX_LEN_XOP_08_86 */
7615 { VEX_W_TABLE (VEX_W_XOP_08_86_L_0
) },
7618 /* VEX_LEN_XOP_08_87 */
7620 { VEX_W_TABLE (VEX_W_XOP_08_87_L_0
) },
7623 /* VEX_LEN_XOP_08_8E */
7625 { VEX_W_TABLE (VEX_W_XOP_08_8E_L_0
) },
7628 /* VEX_LEN_XOP_08_8F */
7630 { VEX_W_TABLE (VEX_W_XOP_08_8F_L_0
) },
7633 /* VEX_LEN_XOP_08_95 */
7635 { VEX_W_TABLE (VEX_W_XOP_08_95_L_0
) },
7638 /* VEX_LEN_XOP_08_96 */
7640 { VEX_W_TABLE (VEX_W_XOP_08_96_L_0
) },
7643 /* VEX_LEN_XOP_08_97 */
7645 { VEX_W_TABLE (VEX_W_XOP_08_97_L_0
) },
7648 /* VEX_LEN_XOP_08_9E */
7650 { VEX_W_TABLE (VEX_W_XOP_08_9E_L_0
) },
7653 /* VEX_LEN_XOP_08_9F */
7655 { VEX_W_TABLE (VEX_W_XOP_08_9F_L_0
) },
7658 /* VEX_LEN_XOP_08_A3 */
7660 { "vpperm", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
7663 /* VEX_LEN_XOP_08_A6 */
7665 { VEX_W_TABLE (VEX_W_XOP_08_A6_L_0
) },
7668 /* VEX_LEN_XOP_08_B6 */
7670 { VEX_W_TABLE (VEX_W_XOP_08_B6_L_0
) },
7673 /* VEX_LEN_XOP_08_C0 */
7675 { VEX_W_TABLE (VEX_W_XOP_08_C0_L_0
) },
7678 /* VEX_LEN_XOP_08_C1 */
7680 { VEX_W_TABLE (VEX_W_XOP_08_C1_L_0
) },
7683 /* VEX_LEN_XOP_08_C2 */
7685 { VEX_W_TABLE (VEX_W_XOP_08_C2_L_0
) },
7688 /* VEX_LEN_XOP_08_C3 */
7690 { VEX_W_TABLE (VEX_W_XOP_08_C3_L_0
) },
7693 /* VEX_LEN_XOP_08_CC */
7695 { VEX_W_TABLE (VEX_W_XOP_08_CC_L_0
) },
7698 /* VEX_LEN_XOP_08_CD */
7700 { VEX_W_TABLE (VEX_W_XOP_08_CD_L_0
) },
7703 /* VEX_LEN_XOP_08_CE */
7705 { VEX_W_TABLE (VEX_W_XOP_08_CE_L_0
) },
7708 /* VEX_LEN_XOP_08_CF */
7710 { VEX_W_TABLE (VEX_W_XOP_08_CF_L_0
) },
7713 /* VEX_LEN_XOP_08_EC */
7715 { VEX_W_TABLE (VEX_W_XOP_08_EC_L_0
) },
7718 /* VEX_LEN_XOP_08_ED */
7720 { VEX_W_TABLE (VEX_W_XOP_08_ED_L_0
) },
7723 /* VEX_LEN_XOP_08_EE */
7725 { VEX_W_TABLE (VEX_W_XOP_08_EE_L_0
) },
7728 /* VEX_LEN_XOP_08_EF */
7730 { VEX_W_TABLE (VEX_W_XOP_08_EF_L_0
) },
7733 /* VEX_LEN_XOP_09_01 */
7735 { REG_TABLE (REG_XOP_09_01_L_0
) },
7738 /* VEX_LEN_XOP_09_02 */
7740 { REG_TABLE (REG_XOP_09_02_L_0
) },
7743 /* VEX_LEN_XOP_09_12 */
7745 { REG_TABLE (REG_XOP_09_12_L_0
) },
7748 /* VEX_LEN_XOP_09_82_W_0 */
7750 { "vfrczss", { XM
, EXd
}, 0 },
7753 /* VEX_LEN_XOP_09_83_W_0 */
7755 { "vfrczsd", { XM
, EXq
}, 0 },
7758 /* VEX_LEN_XOP_09_90 */
7760 { "vprotb", { XM
, EXx
, VexW
}, 0 },
7763 /* VEX_LEN_XOP_09_91 */
7765 { "vprotw", { XM
, EXx
, VexW
}, 0 },
7768 /* VEX_LEN_XOP_09_92 */
7770 { "vprotd", { XM
, EXx
, VexW
}, 0 },
7773 /* VEX_LEN_XOP_09_93 */
7775 { "vprotq", { XM
, EXx
, VexW
}, 0 },
7778 /* VEX_LEN_XOP_09_94 */
7780 { "vpshlb", { XM
, EXx
, VexW
}, 0 },
7783 /* VEX_LEN_XOP_09_95 */
7785 { "vpshlw", { XM
, EXx
, VexW
}, 0 },
7788 /* VEX_LEN_XOP_09_96 */
7790 { "vpshld", { XM
, EXx
, VexW
}, 0 },
7793 /* VEX_LEN_XOP_09_97 */
7795 { "vpshlq", { XM
, EXx
, VexW
}, 0 },
7798 /* VEX_LEN_XOP_09_98 */
7800 { "vpshab", { XM
, EXx
, VexW
}, 0 },
7803 /* VEX_LEN_XOP_09_99 */
7805 { "vpshaw", { XM
, EXx
, VexW
}, 0 },
7808 /* VEX_LEN_XOP_09_9A */
7810 { "vpshad", { XM
, EXx
, VexW
}, 0 },
7813 /* VEX_LEN_XOP_09_9B */
7815 { "vpshaq", { XM
, EXx
, VexW
}, 0 },
7818 /* VEX_LEN_XOP_09_C1 */
7820 { VEX_W_TABLE (VEX_W_XOP_09_C1_L_0
) },
7823 /* VEX_LEN_XOP_09_C2 */
7825 { VEX_W_TABLE (VEX_W_XOP_09_C2_L_0
) },
7828 /* VEX_LEN_XOP_09_C3 */
7830 { VEX_W_TABLE (VEX_W_XOP_09_C3_L_0
) },
7833 /* VEX_LEN_XOP_09_C6 */
7835 { VEX_W_TABLE (VEX_W_XOP_09_C6_L_0
) },
7838 /* VEX_LEN_XOP_09_C7 */
7840 { VEX_W_TABLE (VEX_W_XOP_09_C7_L_0
) },
7843 /* VEX_LEN_XOP_09_CB */
7845 { VEX_W_TABLE (VEX_W_XOP_09_CB_L_0
) },
7848 /* VEX_LEN_XOP_09_D1 */
7850 { VEX_W_TABLE (VEX_W_XOP_09_D1_L_0
) },
7853 /* VEX_LEN_XOP_09_D2 */
7855 { VEX_W_TABLE (VEX_W_XOP_09_D2_L_0
) },
7858 /* VEX_LEN_XOP_09_D3 */
7860 { VEX_W_TABLE (VEX_W_XOP_09_D3_L_0
) },
7863 /* VEX_LEN_XOP_09_D6 */
7865 { VEX_W_TABLE (VEX_W_XOP_09_D6_L_0
) },
7868 /* VEX_LEN_XOP_09_D7 */
7870 { VEX_W_TABLE (VEX_W_XOP_09_D7_L_0
) },
7873 /* VEX_LEN_XOP_09_DB */
7875 { VEX_W_TABLE (VEX_W_XOP_09_DB_L_0
) },
7878 /* VEX_LEN_XOP_09_E1 */
7880 { VEX_W_TABLE (VEX_W_XOP_09_E1_L_0
) },
7883 /* VEX_LEN_XOP_09_E2 */
7885 { VEX_W_TABLE (VEX_W_XOP_09_E2_L_0
) },
7888 /* VEX_LEN_XOP_09_E3 */
7890 { VEX_W_TABLE (VEX_W_XOP_09_E3_L_0
) },
7893 /* VEX_LEN_XOP_0A_12 */
7895 { REG_TABLE (REG_XOP_0A_12_L_0
) },
7899 #include "i386-dis-evex-len.h"
7901 static const struct dis386 vex_w_table
[][2] = {
7903 /* VEX_W_0F41_L_1_M_1 */
7904 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_0
) },
7905 { PREFIX_TABLE (PREFIX_VEX_0F41_L_1_W_1
) },
7908 /* VEX_W_0F42_L_1_M_1 */
7909 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_0
) },
7910 { PREFIX_TABLE (PREFIX_VEX_0F42_L_1_W_1
) },
7913 /* VEX_W_0F44_L_0_M_1 */
7914 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_0
) },
7915 { PREFIX_TABLE (PREFIX_VEX_0F44_L_0_W_1
) },
7918 /* VEX_W_0F45_L_1_M_1 */
7919 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_0
) },
7920 { PREFIX_TABLE (PREFIX_VEX_0F45_L_1_W_1
) },
7923 /* VEX_W_0F46_L_1_M_1 */
7924 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_0
) },
7925 { PREFIX_TABLE (PREFIX_VEX_0F46_L_1_W_1
) },
7928 /* VEX_W_0F47_L_1_M_1 */
7929 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_0
) },
7930 { PREFIX_TABLE (PREFIX_VEX_0F47_L_1_W_1
) },
7933 /* VEX_W_0F4A_L_1_M_1 */
7934 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_0
) },
7935 { PREFIX_TABLE (PREFIX_VEX_0F4A_L_1_W_1
) },
7938 /* VEX_W_0F4B_L_1_M_1 */
7939 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_0
) },
7940 { PREFIX_TABLE (PREFIX_VEX_0F4B_L_1_W_1
) },
7943 /* VEX_W_0F90_L_0 */
7944 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_0
) },
7945 { PREFIX_TABLE (PREFIX_VEX_0F90_L_0_W_1
) },
7948 /* VEX_W_0F91_L_0_M_0 */
7949 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_0
) },
7950 { PREFIX_TABLE (PREFIX_VEX_0F91_L_0_W_1
) },
7953 /* VEX_W_0F92_L_0_M_1 */
7954 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_0
) },
7955 { PREFIX_TABLE (PREFIX_VEX_0F92_L_0_W_1
) },
7958 /* VEX_W_0F93_L_0_M_1 */
7959 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_0
) },
7960 { PREFIX_TABLE (PREFIX_VEX_0F93_L_0_W_1
) },
7963 /* VEX_W_0F98_L_0_M_1 */
7964 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_0
) },
7965 { PREFIX_TABLE (PREFIX_VEX_0F98_L_0_W_1
) },
7968 /* VEX_W_0F99_L_0_M_1 */
7969 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_0
) },
7970 { PREFIX_TABLE (PREFIX_VEX_0F99_L_0_W_1
) },
7974 { "%XEvpermilps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7978 { "vpermilpd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7982 { "vtestps", { XM
, EXx
}, PREFIX_DATA
},
7986 { "vtestpd", { XM
, EXx
}, PREFIX_DATA
},
7990 { "vcvtph2ps", { XM
, EXxmmq
}, PREFIX_DATA
},
7993 /* VEX_W_0F3816_L_1 */
7994 { "vpermps", { XM
, Vex
, EXx
}, PREFIX_DATA
},
7998 { "%XEvbroadcastss", { XM
, EXd
}, PREFIX_DATA
},
8001 /* VEX_W_0F3819_L_1 */
8002 { "vbroadcastsd", { XM
, EXq
}, PREFIX_DATA
},
8005 /* VEX_W_0F381A_L_1 */
8006 { "vbroadcastf128", { XM
, Mxmm
}, PREFIX_DATA
},
8010 { "vmaskmovps", { XM
, Vex
, Mx
}, PREFIX_DATA
},
8014 { "vmaskmovpd", { XM
, Vex
, Mx
}, PREFIX_DATA
},
8018 { "vmaskmovps", { Mx
, Vex
, XM
}, PREFIX_DATA
},
8022 { "vmaskmovpd", { Mx
, Vex
, XM
}, PREFIX_DATA
},
8026 { "vpermd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8030 { "vpsravd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8033 /* VEX_W_0F3848_X86_64_L_0 */
8034 { PREFIX_TABLE (PREFIX_VEX_0F3848_X86_64_L_0_W_0
) },
8037 /* VEX_W_0F3849_X86_64_L_0 */
8038 { MOD_TABLE (MOD_VEX_0F3849_X86_64_L_0_W_0
) },
8041 /* VEX_W_0F384A_X86_64 */
8042 { VEX_LEN_TABLE (VEX_LEN_0F384A_X86_64_W_0
) },
8045 /* VEX_W_0F384B_X86_64_L_0 */
8046 { PREFIX_TABLE (PREFIX_VEX_0F384B_X86_64_L_0_W_0
) },
8050 { PREFIX_TABLE (PREFIX_VEX_0F3850_W_0
) },
8054 { PREFIX_TABLE (PREFIX_VEX_0F3851_W_0
) },
8058 { "%XVvpdpwssd", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8062 { "%XVvpdpwssds", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8066 { "%XEvpbroadcastd", { XM
, EXd
}, PREFIX_DATA
},
8070 { "vpbroadcastq", { XM
, EXq
}, PREFIX_DATA
},
8073 /* VEX_W_0F385A_L_0 */
8074 { "vbroadcasti128", { XM
, Mxmm
}, PREFIX_DATA
},
8077 /* VEX_W_0F385C_X86_64_L_0 */
8078 { PREFIX_TABLE (PREFIX_VEX_0F385C_X86_64_L_0_W_0
) },
8081 /* VEX_W_0F385E_X86_64_L_0 */
8082 { PREFIX_TABLE (PREFIX_VEX_0F385E_X86_64_L_0_W_0
) },
8085 /* VEX_W_0F385F_X86_64_L_0 */
8086 { PREFIX_TABLE (PREFIX_VEX_0F385F_X86_64_L_0_W_0
) },
8089 /* VEX_W_0F386B_X86_64_L_0 */
8090 { PREFIX_TABLE (PREFIX_VEX_0F386B_X86_64_L_0_W_0
) },
8093 /* VEX_W_0F386C_X86_64_L_0 */
8094 { PREFIX_TABLE (PREFIX_VEX_0F386C_X86_64_L_0_W_0
) },
8097 /* VEX_W_0F386E_X86_64_L_0 */
8098 { PREFIX_TABLE (PREFIX_VEX_0F386E_X86_64_L_0_W_0
) },
8101 /* VEX_W_0F386F_X86_64_L_0 */
8102 { PREFIX_TABLE (PREFIX_VEX_0F386F_X86_64_L_0_W_0
) },
8105 /* VEX_W_0F3872_P_1 */
8106 { "%XVvcvtneps2bf16%XY", { XMM
, EXx
}, 0 },
8110 { "%XEvpbroadcastb", { XM
, EXb
}, PREFIX_DATA
},
8114 { "%XEvpbroadcastw", { XM
, EXw
}, PREFIX_DATA
},
8118 { PREFIX_TABLE (PREFIX_VEX_0F38B0_W_0
) },
8122 { PREFIX_TABLE (PREFIX_VEX_0F38B1_W_0
) },
8127 { "%XVvpmadd52luq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8132 { "%XVvpmadd52huq", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8135 /* VEX_W_0F38CB_P_3 */
8136 { VEX_LEN_TABLE (VEX_LEN_0F38CB_P_3_W_0
) },
8139 /* VEX_W_0F38CC_P_3 */
8140 { VEX_LEN_TABLE (VEX_LEN_0F38CC_P_3_W_0
) },
8143 /* VEX_W_0F38CD_P_3 */
8144 { VEX_LEN_TABLE (VEX_LEN_0F38CD_P_3_W_0
) },
8148 { "%XEvgf2p8mulb", { XM
, Vex
, EXx
}, PREFIX_DATA
},
8152 { PREFIX_TABLE (PREFIX_VEX_0F38D2_W_0
) },
8156 { PREFIX_TABLE (PREFIX_VEX_0F38D3_W_0
) },
8160 { PREFIX_TABLE (PREFIX_VEX_0F38DA_W_0
) },
8163 /* VEX_W_0F3A00_L_1 */
8165 { "%XEvpermq", { XM
, EXx
, Ib
}, PREFIX_DATA
},
8168 /* VEX_W_0F3A01_L_1 */
8170 { "%XEvpermpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
8174 { "vpblendd", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
8178 { "%XEvpermilps", { XM
, EXx
, Ib
}, PREFIX_DATA
},
8182 { "vpermilpd", { XM
, EXx
, Ib
}, PREFIX_DATA
},
8185 /* VEX_W_0F3A06_L_1 */
8186 { "vperm2f128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
8189 /* VEX_W_0F3A18_L_1 */
8190 { "vinsertf128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
8193 /* VEX_W_0F3A19_L_1 */
8194 { "vextractf128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
8198 { "%XEvcvtps2ph", { EXxmmq
, XM
, EXxEVexS
, Ib
}, PREFIX_DATA
},
8201 /* VEX_W_0F3A38_L_1 */
8202 { "vinserti128", { XM
, Vex
, EXxmm
, Ib
}, PREFIX_DATA
},
8205 /* VEX_W_0F3A39_L_1 */
8206 { "vextracti128", { EXxmm
, XM
, Ib
}, PREFIX_DATA
},
8209 /* VEX_W_0F3A46_L_1 */
8210 { "vperm2i128", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
8214 { "vblendvps", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
8218 { "vblendvpd", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
8222 { "vpblendvb", { XM
, Vex
, EXx
, XMVexI4
}, PREFIX_DATA
},
8227 { "%XEvgf2p8affineqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
8232 { "%XEvgf2p8affineinvqb", { XM
, Vex
, EXx
, Ib
}, PREFIX_DATA
},
8236 { VEX_LEN_TABLE (VEX_LEN_0F3ADE_W_0
) },
8239 /* VEX_W_MAP5_F8_X86_64 */
8240 { PREFIX_TABLE (PREFIX_VEX_MAP5_F8_X86_64_L_0_W_0
) },
8243 /* VEX_W_MAP5_F9_X86_64 */
8244 { PREFIX_TABLE (PREFIX_VEX_MAP5_F9_X86_64_L_0_W_0
) },
8247 /* VEX_W_MAP5_FD_X86_64 */
8248 { PREFIX_TABLE (PREFIX_VEX_MAP5_FD_X86_64_L_0_W_0
) },
8251 /* VEX_W_MAP7_F6_L_0 */
8252 { REG_TABLE (REG_VEX_MAP7_F6_L_0_W_0
) },
8255 /* VEX_W_MAP7_F8_L_0 */
8256 { REG_TABLE (REG_VEX_MAP7_F8_L_0_W_0
) },
8258 /* VEX_W_XOP_08_85_L_0 */
8260 { "vpmacssww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8262 /* VEX_W_XOP_08_86_L_0 */
8264 { "vpmacsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8266 /* VEX_W_XOP_08_87_L_0 */
8268 { "vpmacssdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8270 /* VEX_W_XOP_08_8E_L_0 */
8272 { "vpmacssdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8274 /* VEX_W_XOP_08_8F_L_0 */
8276 { "vpmacssdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8278 /* VEX_W_XOP_08_95_L_0 */
8280 { "vpmacsww", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8282 /* VEX_W_XOP_08_96_L_0 */
8284 { "vpmacswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8286 /* VEX_W_XOP_08_97_L_0 */
8288 { "vpmacsdql", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8290 /* VEX_W_XOP_08_9E_L_0 */
8292 { "vpmacsdd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8294 /* VEX_W_XOP_08_9F_L_0 */
8296 { "vpmacsdqh", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8298 /* VEX_W_XOP_08_A6_L_0 */
8300 { "vpmadcsswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8302 /* VEX_W_XOP_08_B6_L_0 */
8304 { "vpmadcswd", { XM
, Vex
, EXx
, XMVexI4
}, 0 },
8306 /* VEX_W_XOP_08_C0_L_0 */
8308 { "vprotb", { XM
, EXx
, Ib
}, 0 },
8310 /* VEX_W_XOP_08_C1_L_0 */
8312 { "vprotw", { XM
, EXx
, Ib
}, 0 },
8314 /* VEX_W_XOP_08_C2_L_0 */
8316 { "vprotd", { XM
, EXx
, Ib
}, 0 },
8318 /* VEX_W_XOP_08_C3_L_0 */
8320 { "vprotq", { XM
, EXx
, Ib
}, 0 },
8322 /* VEX_W_XOP_08_CC_L_0 */
8324 { "vpcomb", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8326 /* VEX_W_XOP_08_CD_L_0 */
8328 { "vpcomw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8330 /* VEX_W_XOP_08_CE_L_0 */
8332 { "vpcomd", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8334 /* VEX_W_XOP_08_CF_L_0 */
8336 { "vpcomq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8338 /* VEX_W_XOP_08_EC_L_0 */
8340 { "vpcomub", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8342 /* VEX_W_XOP_08_ED_L_0 */
8344 { "vpcomuw", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8346 /* VEX_W_XOP_08_EE_L_0 */
8348 { "vpcomud", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8350 /* VEX_W_XOP_08_EF_L_0 */
8352 { "vpcomuq", { XM
, Vex
, EXx
, VPCOM
}, 0 },
8354 /* VEX_W_XOP_09_80 */
8356 { "vfrczps", { XM
, EXx
}, 0 },
8358 /* VEX_W_XOP_09_81 */
8360 { "vfrczpd", { XM
, EXx
}, 0 },
8362 /* VEX_W_XOP_09_82 */
8364 { VEX_LEN_TABLE (VEX_LEN_XOP_09_82_W_0
) },
8366 /* VEX_W_XOP_09_83 */
8368 { VEX_LEN_TABLE (VEX_LEN_XOP_09_83_W_0
) },
8370 /* VEX_W_XOP_09_C1_L_0 */
8372 { "vphaddbw", { XM
, EXxmm
}, 0 },
8374 /* VEX_W_XOP_09_C2_L_0 */
8376 { "vphaddbd", { XM
, EXxmm
}, 0 },
8378 /* VEX_W_XOP_09_C3_L_0 */
8380 { "vphaddbq", { XM
, EXxmm
}, 0 },
8382 /* VEX_W_XOP_09_C6_L_0 */
8384 { "vphaddwd", { XM
, EXxmm
}, 0 },
8386 /* VEX_W_XOP_09_C7_L_0 */
8388 { "vphaddwq", { XM
, EXxmm
}, 0 },
8390 /* VEX_W_XOP_09_CB_L_0 */
8392 { "vphadddq", { XM
, EXxmm
}, 0 },
8394 /* VEX_W_XOP_09_D1_L_0 */
8396 { "vphaddubw", { XM
, EXxmm
}, 0 },
8398 /* VEX_W_XOP_09_D2_L_0 */
8400 { "vphaddubd", { XM
, EXxmm
}, 0 },
8402 /* VEX_W_XOP_09_D3_L_0 */
8404 { "vphaddubq", { XM
, EXxmm
}, 0 },
8406 /* VEX_W_XOP_09_D6_L_0 */
8408 { "vphadduwd", { XM
, EXxmm
}, 0 },
8410 /* VEX_W_XOP_09_D7_L_0 */
8412 { "vphadduwq", { XM
, EXxmm
}, 0 },
8414 /* VEX_W_XOP_09_DB_L_0 */
8416 { "vphaddudq", { XM
, EXxmm
}, 0 },
8418 /* VEX_W_XOP_09_E1_L_0 */
8420 { "vphsubbw", { XM
, EXxmm
}, 0 },
8422 /* VEX_W_XOP_09_E2_L_0 */
8424 { "vphsubwd", { XM
, EXxmm
}, 0 },
8426 /* VEX_W_XOP_09_E3_L_0 */
8428 { "vphsubdq", { XM
, EXxmm
}, 0 },
8431 #include "i386-dis-evex-w.h"
8434 static const struct dis386 mod_table
[][2] = {
8437 { "bound{S|}", { Gv
, Ma
}, 0 },
8442 { "lesS", { Gv
, Mp
}, 0 },
8443 { VEX_C4_TABLE () },
8447 { "ldsS", { Gv
, Mp
}, 0 },
8448 { VEX_C5_TABLE () },
8451 /* MOD_0F01_REG_0 */
8452 { X86_64_TABLE (X86_64_0F01_REG_0
) },
8453 { RM_TABLE (RM_0F01_REG_0
) },
8456 /* MOD_0F01_REG_1 */
8457 { X86_64_TABLE (X86_64_0F01_REG_1
) },
8458 { RM_TABLE (RM_0F01_REG_1
) },
8461 /* MOD_0F01_REG_2 */
8462 { X86_64_TABLE (X86_64_0F01_REG_2
) },
8463 { RM_TABLE (RM_0F01_REG_2
) },
8466 /* MOD_0F01_REG_3 */
8467 { X86_64_TABLE (X86_64_0F01_REG_3
) },
8468 { RM_TABLE (RM_0F01_REG_3
) },
8471 /* MOD_0F01_REG_5 */
8472 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_0
) },
8473 { RM_TABLE (RM_0F01_REG_5_MOD_3
) },
8476 /* MOD_0F01_REG_7 */
8477 { "invlpg", { Mb
}, 0 },
8478 { RM_TABLE (RM_0F01_REG_7_MOD_3
) },
8481 /* MOD_0F12_PREFIX_0 */
8482 { "%XEVmovlpYX", { XM
, Vex
, EXq
}, 0 },
8483 { "%XEVmovhlpY%XS", { XM
, Vex
, EXq
}, 0 },
8486 /* MOD_0F16_PREFIX_0 */
8487 { "%XEVmovhpYX", { XM
, Vex
, EXq
}, 0 },
8488 { "%XEVmovlhpY%XS", { XM
, Vex
, EXq
}, 0 },
8491 /* MOD_0F18_REG_0 */
8492 { "prefetchnta", { Mb
}, 0 },
8493 { "nopQ", { Ev
}, 0 },
8496 /* MOD_0F18_REG_1 */
8497 { "prefetcht0", { Mb
}, 0 },
8498 { "nopQ", { Ev
}, 0 },
8501 /* MOD_0F18_REG_2 */
8502 { "prefetcht1", { Mb
}, 0 },
8503 { "nopQ", { Ev
}, 0 },
8506 /* MOD_0F18_REG_3 */
8507 { "prefetcht2", { Mb
}, 0 },
8508 { "nopQ", { Ev
}, 0 },
8511 /* MOD_0F18_REG_4 */
8512 { "prefetchrst2", { Mb
}, 0 },
8513 { "nopQ", { Ev
}, 0 },
8516 /* MOD_0F18_REG_6 */
8517 { X86_64_TABLE (X86_64_0F18_REG_6_MOD_0
) },
8518 { "nopQ", { Ev
}, 0 },
8521 /* MOD_0F18_REG_7 */
8522 { X86_64_TABLE (X86_64_0F18_REG_7_MOD_0
) },
8523 { "nopQ", { Ev
}, 0 },
8526 /* MOD_0F1A_PREFIX_0 */
8527 { "bndldx", { Gbnd
, Mv_bnd
}, 0 },
8528 { "nopQ", { Ev
}, 0 },
8531 /* MOD_0F1B_PREFIX_0 */
8532 { "bndstx", { Mv_bnd
, Gbnd
}, 0 },
8533 { "nopQ", { Ev
}, 0 },
8536 /* MOD_0F1B_PREFIX_1 */
8537 { "bndmk", { Gbnd
, Mv_bnd
}, 0 },
8538 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8541 /* MOD_0F1C_PREFIX_0 */
8542 { REG_TABLE (REG_0F1C_P_0_MOD_0
) },
8543 { "nopQ", { Ev
}, 0 },
8546 /* MOD_0F1E_PREFIX_1 */
8547 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8548 { REG_TABLE (REG_0F1E_P_1_MOD_3
) },
8551 /* MOD_0FAE_REG_0 */
8552 { "fxsave", { FXSAVE
}, 0 },
8553 { PREFIX_TABLE (PREFIX_0FAE_REG_0_MOD_3
) },
8556 /* MOD_0FAE_REG_1 */
8557 { "fxrstor", { FXSAVE
}, 0 },
8558 { PREFIX_TABLE (PREFIX_0FAE_REG_1_MOD_3
) },
8561 /* MOD_0FAE_REG_2 */
8562 { "ldmxcsr", { Md
}, 0 },
8563 { PREFIX_TABLE (PREFIX_0FAE_REG_2_MOD_3
) },
8566 /* MOD_0FAE_REG_3 */
8567 { "stmxcsr", { Md
}, 0 },
8568 { PREFIX_TABLE (PREFIX_0FAE_REG_3_MOD_3
) },
8571 /* MOD_0FAE_REG_4 */
8572 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_0
) },
8573 { PREFIX_TABLE (PREFIX_0FAE_REG_4_MOD_3
) },
8576 /* MOD_0FAE_REG_5 */
8577 { "xrstor", { FXSAVE
}, PREFIX_OPCODE
| PREFIX_REX2_ILLEGAL
},
8578 { PREFIX_TABLE (PREFIX_0FAE_REG_5_MOD_3
) },
8581 /* MOD_0FAE_REG_6 */
8582 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_0
) },
8583 { PREFIX_TABLE (PREFIX_0FAE_REG_6_MOD_3
) },
8586 /* MOD_0FAE_REG_7 */
8587 { PREFIX_TABLE (PREFIX_0FAE_REG_7_MOD_0
) },
8588 { RM_TABLE (RM_0FAE_REG_7_MOD_3
) },
8591 /* MOD_0FC7_REG_6 */
8592 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_0
) },
8593 { PREFIX_TABLE (PREFIX_0FC7_REG_6_MOD_3
) }
8596 /* MOD_0FC7_REG_7 */
8597 { "vmptrst", { Mq
}, 0 },
8598 { PREFIX_TABLE (PREFIX_0FC7_REG_7_MOD_3
) }
8601 /* MOD_0F38DC_PREFIX_1 */
8602 { "aesenc128kl", { XM
, M
}, 0 },
8603 { "loadiwkey", { XM
, EXx
}, 0 },
8607 { PREFIX_TABLE (PREFIX_0F38F8_M_0
) },
8608 { X86_64_TABLE (X86_64_0F38F8_M_1
) },
8611 /* MOD_VEX_0F3849_X86_64_L_0_W_0 */
8612 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_0
) },
8613 { PREFIX_TABLE (PREFIX_VEX_0F3849_X86_64_L_0_W_0_M_1
) },
8616 #include "i386-dis-evex-mod.h"
8619 static const struct dis386 rm_table
[][8] = {
8622 { "xabort", { Skip_MODRM
, Ib
}, 0 },
8626 { "xbeginT", { Skip_MODRM
, Jdqw
}, 0 },
8630 { "enclv", { Skip_MODRM
}, 0 },
8631 { "vmcall", { Skip_MODRM
}, 0 },
8632 { "vmlaunch", { Skip_MODRM
}, 0 },
8633 { "vmresume", { Skip_MODRM
}, 0 },
8634 { "vmxoff", { Skip_MODRM
}, 0 },
8635 { "pconfig", { Skip_MODRM
}, 0 },
8636 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_6
) },
8637 { PREFIX_TABLE (PREFIX_0F01_REG_0_MOD_3_RM_7
) },
8641 { "monitor", { { OP_Monitor
, 0 } }, 0 },
8642 { "mwait", { { OP_Mwait
, 0 } }, 0 },
8643 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_2
) },
8644 { "stac", { Skip_MODRM
}, 0 },
8645 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_4
) },
8646 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_5
) },
8647 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_6
) },
8648 { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_7
) },
8652 { "xgetbv", { Skip_MODRM
}, 0 },
8653 { "xsetbv", { Skip_MODRM
}, 0 },
8656 { "vmfunc", { Skip_MODRM
}, 0 },
8657 { "xend", { Skip_MODRM
}, 0 },
8658 { "xtest", { Skip_MODRM
}, 0 },
8659 { "enclu", { Skip_MODRM
}, 0 },
8663 { "vmrun", { Skip_MODRM
}, 0 },
8664 { PREFIX_TABLE (PREFIX_0F01_REG_3_RM_1
) },
8665 { "vmload", { Skip_MODRM
}, 0 },
8666 { "vmsave", { Skip_MODRM
}, 0 },
8667 { "stgi", { Skip_MODRM
}, 0 },
8668 { "clgi", { Skip_MODRM
}, 0 },
8669 { "skinit", { Skip_MODRM
}, 0 },
8670 { "invlpga", { Skip_MODRM
}, 0 },
8673 /* RM_0F01_REG_5_MOD_3 */
8674 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_0
) },
8675 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_1
) },
8676 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_2
) },
8678 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_4
) },
8679 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_5
) },
8680 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_6
) },
8681 { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_7
) },
8684 /* RM_0F01_REG_7_MOD_3 */
8685 { "swapgs", { Skip_MODRM
}, 0 },
8686 { "rdtscp", { Skip_MODRM
}, 0 },
8687 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_2
) },
8688 { "mwaitx", { { OP_Mwait
, eBX_reg
} }, PREFIX_OPCODE
},
8689 { "clzero", { Skip_MODRM
}, 0 },
8690 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_5
) },
8691 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_6
) },
8692 { PREFIX_TABLE (PREFIX_0F01_REG_7_MOD_3_RM_7
) },
8695 /* RM_0F1E_P_1_MOD_3_REG_7 */
8696 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8697 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8698 { "endbr64", { Skip_MODRM
}, 0 },
8699 { "endbr32", { Skip_MODRM
}, 0 },
8700 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8701 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8702 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8703 { "nopQ", { Ev
}, PREFIX_IGNORED
},
8706 /* RM_0FAE_REG_6_MOD_3 */
8707 { "mfence", { Skip_MODRM
}, 0 },
8710 /* RM_0FAE_REG_7_MOD_3 */
8711 { "sfence", { Skip_MODRM
}, 0 },
8714 /* RM_0F3A0F_P_1_R_0 */
8715 { "hreset", { Skip_MODRM
, Ib
}, 0 },
8718 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_0_R_0 */
8719 { "tilerelease", { Skip_MODRM
}, 0 },
8722 /* RM_VEX_0F3849_X86_64_L_0_W_0_M_1_P_3 */
8723 { "tilezero", { TMM
, Skip_MODRM
}, 0 },
8727 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
8729 /* The values used here must be non-zero, fit in 'unsigned char', and not be
8730 in conflict with actual prefix opcodes. */
8731 #define REP_PREFIX 0x01
8732 #define XACQUIRE_PREFIX 0x02
8733 #define XRELEASE_PREFIX 0x03
8734 #define BND_PREFIX 0x04
8735 #define NOTRACK_PREFIX 0x05
8742 ckprefix (instr_info
*ins
)
8749 /* The maximum instruction length is 15bytes. */
8750 while (length
< MAX_CODE_LENGTH
- 1)
8752 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
8753 return ckp_fetch_error
;
8755 switch (*ins
->codep
)
8757 /* REX prefixes family. */
8774 if (ins
->address_mode
== mode_64bit
)
8775 newrex
= *ins
->codep
;
8778 ins
->last_rex_prefix
= i
;
8780 /* REX2 must be the last prefix. */
8782 if (ins
->address_mode
== mode_64bit
)
8784 if (ins
->last_rex_prefix
>= 0)
8788 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
8789 return ckp_fetch_error
;
8790 ins
->rex2_payload
= *ins
->codep
;
8791 ins
->rex2
= ins
->rex2_payload
>> 4;
8792 ins
->rex
= (ins
->rex2_payload
& 0xf) | REX_OPCODE
;
8794 ins
->last_rex2_prefix
= i
;
8795 ins
->all_prefixes
[i
] = REX2_OPCODE
;
8799 ins
->prefixes
|= PREFIX_REPZ
;
8800 ins
->last_repz_prefix
= i
;
8803 ins
->prefixes
|= PREFIX_REPNZ
;
8804 ins
->last_repnz_prefix
= i
;
8807 ins
->prefixes
|= PREFIX_LOCK
;
8808 ins
->last_lock_prefix
= i
;
8811 ins
->prefixes
|= PREFIX_CS
;
8812 ins
->last_seg_prefix
= i
;
8813 if (ins
->address_mode
!= mode_64bit
)
8814 ins
->active_seg_prefix
= PREFIX_CS
;
8817 ins
->prefixes
|= PREFIX_SS
;
8818 ins
->last_seg_prefix
= i
;
8819 if (ins
->address_mode
!= mode_64bit
)
8820 ins
->active_seg_prefix
= PREFIX_SS
;
8823 ins
->prefixes
|= PREFIX_DS
;
8824 ins
->last_seg_prefix
= i
;
8825 if (ins
->address_mode
!= mode_64bit
)
8826 ins
->active_seg_prefix
= PREFIX_DS
;
8829 ins
->prefixes
|= PREFIX_ES
;
8830 ins
->last_seg_prefix
= i
;
8831 if (ins
->address_mode
!= mode_64bit
)
8832 ins
->active_seg_prefix
= PREFIX_ES
;
8835 ins
->prefixes
|= PREFIX_FS
;
8836 ins
->last_seg_prefix
= i
;
8837 ins
->active_seg_prefix
= PREFIX_FS
;
8840 ins
->prefixes
|= PREFIX_GS
;
8841 ins
->last_seg_prefix
= i
;
8842 ins
->active_seg_prefix
= PREFIX_GS
;
8845 ins
->prefixes
|= PREFIX_DATA
;
8846 ins
->last_data_prefix
= i
;
8849 ins
->prefixes
|= PREFIX_ADDR
;
8850 ins
->last_addr_prefix
= i
;
8853 /* fwait is really an instruction. If there are prefixes
8854 before the fwait, they belong to the fwait, *not* to the
8855 following instruction. */
8856 ins
->fwait_prefix
= i
;
8857 if (ins
->prefixes
|| ins
->rex
)
8859 ins
->prefixes
|= PREFIX_FWAIT
;
8861 /* This ensures that the previous REX prefixes are noticed
8862 as unused prefixes, as in the return case below. */
8863 return ins
->rex
? ckp_bogus
: ckp_okay
;
8865 ins
->prefixes
= PREFIX_FWAIT
;
8870 /* Rex is ignored when followed by another prefix. */
8873 if (*ins
->codep
!= FWAIT_OPCODE
)
8874 ins
->all_prefixes
[i
++] = *ins
->codep
;
8882 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
8886 prefix_name (enum address_mode mode
, uint8_t pref
, int sizeflag
)
8888 static const char *rexes
[16] =
8893 "rex.XB", /* 0x43 */
8895 "rex.RB", /* 0x45 */
8896 "rex.RX", /* 0x46 */
8897 "rex.RXB", /* 0x47 */
8899 "rex.WB", /* 0x49 */
8900 "rex.WX", /* 0x4a */
8901 "rex.WXB", /* 0x4b */
8902 "rex.WR", /* 0x4c */
8903 "rex.WRB", /* 0x4d */
8904 "rex.WRX", /* 0x4e */
8905 "rex.WRXB", /* 0x4f */
8910 /* REX prefixes family. */
8927 return rexes
[pref
- 0x40];
8947 return (sizeflag
& DFLAG
) ? "data16" : "data32";
8949 if (mode
== mode_64bit
)
8950 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
8952 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
8957 case XACQUIRE_PREFIX
:
8959 case XRELEASE_PREFIX
:
8963 case NOTRACK_PREFIX
:
8973 print_i386_disassembler_options (FILE *stream
)
8975 fprintf (stream
, _("\n\
8976 The following i386/x86-64 specific disassembler options are supported for use\n\
8977 with the -M switch (multiple options should be separated by commas):\n"));
8979 fprintf (stream
, _(" x86-64 Disassemble in 64bit mode\n"));
8980 fprintf (stream
, _(" i386 Disassemble in 32bit mode\n"));
8981 fprintf (stream
, _(" i8086 Disassemble in 16bit mode\n"));
8982 fprintf (stream
, _(" att Display instruction in AT&T syntax\n"));
8983 fprintf (stream
, _(" intel Display instruction in Intel syntax\n"));
8984 fprintf (stream
, _(" att-mnemonic (AT&T syntax only)\n"
8985 " Display instruction with AT&T mnemonic\n"));
8986 fprintf (stream
, _(" intel-mnemonic (AT&T syntax only)\n"
8987 " Display instruction with Intel mnemonic\n"));
8988 fprintf (stream
, _(" addr64 Assume 64bit address size\n"));
8989 fprintf (stream
, _(" addr32 Assume 32bit address size\n"));
8990 fprintf (stream
, _(" addr16 Assume 16bit address size\n"));
8991 fprintf (stream
, _(" data32 Assume 32bit data size\n"));
8992 fprintf (stream
, _(" data16 Assume 16bit data size\n"));
8993 fprintf (stream
, _(" suffix Always display instruction suffix in AT&T syntax\n"));
8994 fprintf (stream
, _(" amd64 Display instruction in AMD64 ISA\n"));
8995 fprintf (stream
, _(" intel64 Display instruction in Intel64 ISA\n"));
8999 static const struct dis386 bad_opcode
= { "(bad)", { XX
}, 0 };
9001 /* Fetch error indicator. */
9002 static const struct dis386 err_opcode
= { NULL
, { XX
}, 0 };
9004 static const struct dis386 map5_f8_opcode
= { X86_64_TABLE (X86_64_VEX_MAP5_F8
) };
9005 static const struct dis386 map5_f9_opcode
= { X86_64_TABLE (X86_64_VEX_MAP5_F9
) };
9006 static const struct dis386 map5_fd_opcode
= { X86_64_TABLE (X86_64_VEX_MAP5_FD
) };
9007 static const struct dis386 map7_f6_opcode
= { VEX_LEN_TABLE (VEX_LEN_MAP7_F6
) };
9008 static const struct dis386 map7_f8_opcode
= { VEX_LEN_TABLE (VEX_LEN_MAP7_F8
) };
9010 /* Get a pointer to struct dis386 with a valid name. */
9012 static const struct dis386
*
9013 get_valid_dis386 (const struct dis386
*dp
, instr_info
*ins
)
9015 int vindex
, vex_table_index
;
9017 if (dp
->name
!= NULL
)
9020 switch (dp
->op
[0].bytemode
)
9023 dp
= ®_table
[dp
->op
[1].bytemode
][ins
->modrm
.reg
];
9027 vindex
= ins
->modrm
.mod
== 0x3 ? 1 : 0;
9028 dp
= &mod_table
[dp
->op
[1].bytemode
][vindex
];
9032 dp
= &rm_table
[dp
->op
[1].bytemode
][ins
->modrm
.rm
];
9035 case USE_PREFIX_TABLE
:
9039 /* The prefix in VEX is implicit. */
9040 switch (ins
->vex
.prefix
)
9045 case REPE_PREFIX_OPCODE
:
9048 case DATA_PREFIX_OPCODE
:
9051 case REPNE_PREFIX_OPCODE
:
9061 int last_prefix
= -1;
9064 /* We check PREFIX_REPNZ and PREFIX_REPZ before PREFIX_DATA.
9065 When there are multiple PREFIX_REPNZ and PREFIX_REPZ, the
9067 if ((ins
->prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
9069 if (ins
->last_repz_prefix
> ins
->last_repnz_prefix
)
9072 prefix
= PREFIX_REPZ
;
9073 last_prefix
= ins
->last_repz_prefix
;
9078 prefix
= PREFIX_REPNZ
;
9079 last_prefix
= ins
->last_repnz_prefix
;
9082 /* Check if prefix should be ignored. */
9083 if ((((prefix_table
[dp
->op
[1].bytemode
][vindex
].prefix_requirement
9084 & PREFIX_IGNORED
) >> PREFIX_IGNORED_SHIFT
)
9086 && !prefix_table
[dp
->op
[1].bytemode
][vindex
].name
)
9090 if (vindex
== 0 && (ins
->prefixes
& PREFIX_DATA
) != 0)
9093 prefix
= PREFIX_DATA
;
9094 last_prefix
= ins
->last_data_prefix
;
9099 ins
->used_prefixes
|= prefix
;
9100 ins
->all_prefixes
[last_prefix
] = 0;
9103 dp
= &prefix_table
[dp
->op
[1].bytemode
][vindex
];
9106 case USE_X86_64_EVEX_FROM_VEX_TABLE
:
9107 case USE_X86_64_EVEX_PFX_TABLE
:
9108 case USE_X86_64_EVEX_W_TABLE
:
9109 case USE_X86_64_EVEX_MEM_W_TABLE
:
9110 ins
->evex_type
= evex_from_vex
;
9111 /* EVEX from VEX instructions are 64-bit only and require that EVEX.z,
9112 EVEX.L'L, EVEX.b, and the lower 2 bits of EVEX.aaa must be 0. */
9113 if (ins
->address_mode
!= mode_64bit
9114 || (ins
->vex
.mask_register_specifier
& 0x3) != 0
9116 || ins
->vex
.zeroing
!= 0
9120 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_PFX_TABLE
)
9121 goto use_prefix_table
;
9122 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_W_TABLE
)
9123 goto use_vex_w_table
;
9124 if (dp
->op
[0].bytemode
== USE_X86_64_EVEX_MEM_W_TABLE
)
9126 if (ins
->modrm
.mod
== 3)
9128 goto use_vex_w_table
;
9132 case USE_X86_64_TABLE
:
9133 vindex
= ins
->address_mode
== mode_64bit
? 1 : 0;
9134 dp
= &x86_64_table
[dp
->op
[1].bytemode
][vindex
];
9137 case USE_3BYTE_TABLE
:
9138 if (ins
->last_rex2_prefix
>= 0)
9140 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
9142 vindex
= *ins
->codep
++;
9143 dp
= &three_byte_table
[dp
->op
[1].bytemode
][vindex
];
9144 ins
->end_codep
= ins
->codep
;
9145 if (!fetch_modrm (ins
))
9149 case USE_VEX_LEN_TABLE
:
9153 switch (ins
->vex
.length
)
9159 /* This allows re-using in particular table entries where only
9160 128-bit operand size (VEX.L=0 / EVEX.L'L=0) are valid. */
9173 dp
= &vex_len_table
[dp
->op
[1].bytemode
][vindex
];
9176 case USE_EVEX_LEN_TABLE
:
9180 switch (ins
->vex
.length
)
9196 dp
= &evex_len_table
[dp
->op
[1].bytemode
][vindex
];
9199 case USE_XOP_8F_TABLE
:
9200 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
9202 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
9204 /* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm". */
9205 switch ((*ins
->codep
& 0x1f))
9211 vex_table_index
= XOP_08
;
9214 vex_table_index
= XOP_09
;
9217 vex_table_index
= XOP_0A
;
9221 ins
->vex
.w
= *ins
->codep
& 0x80;
9222 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
9225 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9226 if (ins
->address_mode
!= mode_64bit
)
9228 /* In 16/32-bit mode REX_B is silently ignored. */
9232 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
9233 switch ((*ins
->codep
& 0x3))
9238 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9241 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9244 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9249 vindex
= *ins
->codep
++;
9250 dp
= &xop_table
[vex_table_index
][vindex
];
9252 ins
->end_codep
= ins
->codep
;
9253 if (!fetch_modrm (ins
))
9256 /* No XOP encoding so far allows for a non-zero embedded prefix. Avoid
9257 having to decode the bits for every otherwise valid encoding. */
9258 if (ins
->vex
.prefix
)
9262 case USE_VEX_C4_TABLE
:
9264 if (!fetch_code (ins
->info
, ins
->codep
+ 3))
9266 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
9267 switch ((*ins
->codep
& 0x1f))
9273 vex_table_index
= VEX_0F
;
9276 vex_table_index
= VEX_0F38
;
9279 vex_table_index
= VEX_0F3A
;
9282 vex_table_index
= VEX_MAP5
;
9285 vex_table_index
= VEX_MAP7
;
9289 ins
->vex
.w
= *ins
->codep
& 0x80;
9290 if (ins
->address_mode
== mode_64bit
)
9297 /* For the 3-byte VEX prefix in 32-bit mode, the REX_B bit
9298 is ignored, other REX bits are 0 and the highest bit in
9299 VEX.vvvv is also ignored (but we mustn't clear it here). */
9302 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9303 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
9304 switch ((*ins
->codep
& 0x3))
9309 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9312 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9315 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9320 vindex
= *ins
->codep
++;
9321 ins
->condition_code
= vindex
& 0xf;
9322 if (vex_table_index
!= VEX_MAP7
&& vex_table_index
!= VEX_MAP5
)
9323 dp
= &vex_table
[vex_table_index
][vindex
];
9324 else if (vindex
== 0xf6)
9325 dp
= &map7_f6_opcode
;
9326 else if (vindex
== 0xf8)
9328 if (vex_table_index
== VEX_MAP5
)
9329 dp
= &map5_f8_opcode
;
9331 dp
= &map7_f8_opcode
;
9333 else if (vindex
== 0xf9)
9334 dp
= &map5_f9_opcode
;
9335 else if (vindex
== 0xfd)
9336 dp
= &map5_fd_opcode
;
9339 ins
->end_codep
= ins
->codep
;
9340 /* There is no MODRM byte for VEX0F 77. */
9341 if ((vex_table_index
!= VEX_0F
|| vindex
!= 0x77)
9342 && !fetch_modrm (ins
))
9346 case USE_VEX_C5_TABLE
:
9348 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
9350 ins
->rex
= (*ins
->codep
& 0x80) ? 0 : REX_R
;
9352 /* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
9354 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9355 ins
->vex
.length
= (*ins
->codep
& 0x4) ? 256 : 128;
9356 switch ((*ins
->codep
& 0x3))
9361 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9364 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9367 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9372 vindex
= *ins
->codep
++;
9373 dp
= &vex_table
[VEX_0F
][vindex
];
9374 ins
->end_codep
= ins
->codep
;
9375 /* There is no MODRM byte for VEX 77. */
9376 if (vindex
!= 0x77 && !fetch_modrm (ins
))
9380 case USE_VEX_W_TABLE
:
9385 dp
= &vex_w_table
[dp
->op
[1].bytemode
][ins
->vex
.w
];
9388 case USE_EVEX_TABLE
:
9389 ins
->two_source_ops
= false;
9391 ins
->vex
.evex
= true;
9392 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
9394 /* The first byte after 0x62. */
9395 if (*ins
->codep
& 0x8)
9397 if (!(*ins
->codep
& 0x10))
9400 ins
->rex
= ~(*ins
->codep
>> 5) & 0x7;
9401 switch (*ins
->codep
& 0x7)
9406 vex_table_index
= EVEX_0F
;
9409 vex_table_index
= EVEX_0F38
;
9412 vex_table_index
= EVEX_0F3A
;
9415 vex_table_index
= EVEX_MAP4
;
9416 ins
->evex_type
= evex_from_legacy
;
9417 if (ins
->address_mode
!= mode_64bit
)
9419 ins
->rex
|= REX_OPCODE
;
9422 vex_table_index
= EVEX_MAP5
;
9425 vex_table_index
= EVEX_MAP6
;
9428 vex_table_index
= EVEX_MAP7
;
9432 /* The second byte after 0x62. */
9434 ins
->vex
.w
= *ins
->codep
& 0x80;
9435 if (ins
->vex
.w
&& ins
->address_mode
== mode_64bit
)
9438 ins
->vex
.register_specifier
= (~(*ins
->codep
>> 3)) & 0xf;
9440 if (!(*ins
->codep
& 0x4))
9443 ins
->vex
.u
= *ins
->codep
& 0x4;
9445 switch ((*ins
->codep
& 0x3))
9450 ins
->vex
.prefix
= DATA_PREFIX_OPCODE
;
9453 ins
->vex
.prefix
= REPE_PREFIX_OPCODE
;
9456 ins
->vex
.prefix
= REPNE_PREFIX_OPCODE
;
9460 /* The third byte after 0x62. */
9463 /* Remember the static rounding bits. */
9464 ins
->vex
.ll
= (*ins
->codep
>> 5) & 3;
9465 ins
->vex
.b
= *ins
->codep
& 0x10;
9467 ins
->vex
.v
= *ins
->codep
& 0x8;
9468 ins
->vex
.mask_register_specifier
= *ins
->codep
& 0x7;
9469 ins
->vex
.scc
= *ins
->codep
& 0xf;
9470 ins
->vex
.zeroing
= *ins
->codep
& 0x80;
9471 /* Set the NF bit for EVEX-Promoted instructions, this bit will be cleared
9472 when it's an evex_default one. */
9473 ins
->vex
.nf
= *ins
->codep
& 0x4;
9475 if (ins
->address_mode
!= mode_64bit
)
9477 /* Report bad for !evex_default and when two fixed values of evex
9479 if (ins
->evex_type
!= evex_default
|| (ins
->rex2
& REX_B
)
9480 || ((ins
->rex2
& REX_X
) && (ins
->modrm
.mod
!= 3)))
9482 /* In 16/32-bit mode silently ignore following bits. */
9484 ins
->rex2
&= ~REX_R
;
9490 vindex
= *ins
->codep
++;
9491 ins
->condition_code
= vindex
& 0xf;
9492 if (vex_table_index
!= EVEX_MAP7
)
9493 dp
= &evex_table
[vex_table_index
][vindex
];
9494 else if (vindex
== 0xf8)
9495 dp
= &map7_f8_opcode
;
9496 else if (vindex
== 0xf6)
9497 dp
= &map7_f6_opcode
;
9500 ins
->end_codep
= ins
->codep
;
9501 if (!fetch_modrm (ins
))
9504 /* When modrm.mod != 3, the U bit is used by APX for bit X4.
9505 When modrm.mod == 3, the U bit is used by AVX10. The U bit and
9506 the b bit should not be zero at the same time. */
9507 if (ins
->modrm
.mod
== 3 && !ins
->vex
.u
&& !ins
->vex
.b
)
9510 /* Set vector length. For EVEX-promoted instructions, evex.ll == 0b00,
9511 which has the same encoding as vex.length == 128 and they can share
9512 the same processing with vex.length in OP_VEX. */
9513 if (ins
->modrm
.mod
== 3 && ins
->vex
.b
&& ins
->evex_type
!= evex_from_legacy
)
9516 ins
->vex
.length
= 512;
9518 ins
->vex
.length
= 256;
9522 switch (ins
->vex
.ll
)
9525 ins
->vex
.length
= 128;
9528 ins
->vex
.length
= 256;
9531 ins
->vex
.length
= 512;
9547 if (dp
->name
!= NULL
)
9550 return get_valid_dis386 (dp
, ins
);
9554 get_sib (instr_info
*ins
, int sizeflag
)
9556 /* If modrm.mod == 3, operand must be register. */
9558 && ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
9559 && ins
->modrm
.mod
!= 3
9560 && ins
->modrm
.rm
== 4)
9562 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
9564 ins
->sib
.index
= (ins
->codep
[1] >> 3) & 7;
9565 ins
->sib
.scale
= (ins
->codep
[1] >> 6) & 3;
9566 ins
->sib
.base
= ins
->codep
[1] & 7;
9567 ins
->has_sib
= true;
9570 ins
->has_sib
= false;
9575 /* Like oappend_with_style (below) but always with text style. */
9578 oappend (instr_info
*ins
, const char *s
)
9580 oappend_with_style (ins
, s
, dis_style_text
);
9583 /* Like oappend (above), but S is a string starting with '%'. In
9584 Intel syntax, the '%' is elided. */
9587 oappend_register (instr_info
*ins
, const char *s
)
9589 oappend_with_style (ins
, s
+ ins
->intel_syntax
, dis_style_register
);
9592 /* Wrap around a call to INS->info->fprintf_styled_func, printing FMT.
9593 STYLE is the default style to use in the fprintf_styled_func calls,
9594 however, FMT might include embedded style markers (see oappend_style),
9595 these embedded markers are not printed, but instead change the style
9596 used in the next fprintf_styled_func call. */
9598 static void ATTRIBUTE_PRINTF_3
9599 i386_dis_printf (const disassemble_info
*info
, enum disassembler_style style
,
9600 const char *fmt
, ...)
9603 enum disassembler_style curr_style
= style
;
9604 const char *start
, *curr
;
9605 char staging_area
[50];
9608 /* In particular print_insn()'s processing of op_txt[] can hand rather long
9609 strings here. Bypass vsnprintf() in such cases to avoid capacity issues
9610 with the staging area. */
9611 if (strcmp (fmt
, "%s"))
9613 int res
= vsnprintf (staging_area
, sizeof (staging_area
), fmt
, ap
);
9620 if ((size_t) res
>= sizeof (staging_area
))
9623 start
= curr
= staging_area
;
9627 start
= curr
= va_arg (ap
, const char *);
9634 || (*curr
== STYLE_MARKER_CHAR
9635 && ISXDIGIT (*(curr
+ 1))
9636 && *(curr
+ 2) == STYLE_MARKER_CHAR
))
9638 /* Output content between our START position and CURR. */
9639 int len
= curr
- start
;
9640 int n
= (*info
->fprintf_styled_func
) (info
->stream
, curr_style
,
9641 "%.*s", len
, start
);
9648 /* Skip over the initial STYLE_MARKER_CHAR. */
9651 /* Update the CURR_STYLE. As there are less than 16 styles, it
9652 is possible, that if the input is corrupted in some way, that
9653 we might set CURR_STYLE to an invalid value. Don't worry
9654 though, we check for this situation. */
9655 if (*curr
>= '0' && *curr
<= '9')
9656 curr_style
= (enum disassembler_style
) (*curr
- '0');
9657 else if (*curr
>= 'a' && *curr
<= 'f')
9658 curr_style
= (enum disassembler_style
) (*curr
- 'a' + 10);
9660 curr_style
= dis_style_text
;
9662 /* Check for an invalid style having been selected. This should
9663 never happen, but it doesn't hurt to be a little paranoid. */
9664 if (curr_style
> dis_style_comment_start
)
9665 curr_style
= dis_style_text
;
9667 /* Skip the hex character, and the closing STYLE_MARKER_CHAR. */
9670 /* Reset the START to after the style marker. */
9680 print_insn (bfd_vma pc
, disassemble_info
*info
, int intel_syntax
)
9682 const struct dis386
*dp
;
9685 char *op_txt
[MAX_OPERANDS
];
9687 bool intel_swap_2_3
;
9688 int sizeflag
, orig_sizeflag
;
9690 struct dis_private priv
;
9695 .intel_syntax
= intel_syntax
>= 0
9697 : (info
->mach
& bfd_mach_i386_intel_syntax
) != 0,
9698 .intel_mnemonic
= !SYSV386_COMPAT
,
9699 .op_index
[0 ... MAX_OPERANDS
- 1] = -1,
9701 .start_codep
= priv
.the_buffer
,
9702 .codep
= priv
.the_buffer
,
9704 .last_lock_prefix
= -1,
9705 .last_repz_prefix
= -1,
9706 .last_repnz_prefix
= -1,
9707 .last_data_prefix
= -1,
9708 .last_addr_prefix
= -1,
9709 .last_rex_prefix
= -1,
9710 .last_rex2_prefix
= -1,
9711 .last_seg_prefix
= -1,
9714 char op_out
[MAX_OPERANDS
][MAX_OPERAND_BUFFER_SIZE
];
9716 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
9717 if ((info
->mach
& bfd_mach_i386_i386
) != 0)
9718 ins
.address_mode
= mode_32bit
;
9719 else if (info
->mach
== bfd_mach_i386_i8086
)
9721 ins
.address_mode
= mode_16bit
;
9722 priv
.orig_sizeflag
= 0;
9725 ins
.address_mode
= mode_64bit
;
9727 for (p
= info
->disassembler_options
; p
!= NULL
;)
9729 if (startswith (p
, "amd64"))
9731 else if (startswith (p
, "intel64"))
9732 ins
.isa64
= intel64
;
9733 else if (startswith (p
, "x86-64"))
9735 ins
.address_mode
= mode_64bit
;
9736 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9738 else if (startswith (p
, "i386"))
9740 ins
.address_mode
= mode_32bit
;
9741 priv
.orig_sizeflag
|= AFLAG
| DFLAG
;
9743 else if (startswith (p
, "i8086"))
9745 ins
.address_mode
= mode_16bit
;
9746 priv
.orig_sizeflag
&= ~(AFLAG
| DFLAG
);
9748 else if (startswith (p
, "intel"))
9750 if (startswith (p
+ 5, "-mnemonic"))
9751 ins
.intel_mnemonic
= true;
9753 ins
.intel_syntax
= 1;
9755 else if (startswith (p
, "att"))
9757 ins
.intel_syntax
= 0;
9758 if (startswith (p
+ 3, "-mnemonic"))
9759 ins
.intel_mnemonic
= false;
9761 else if (startswith (p
, "addr"))
9763 if (ins
.address_mode
== mode_64bit
)
9765 if (p
[4] == '3' && p
[5] == '2')
9766 priv
.orig_sizeflag
&= ~AFLAG
;
9767 else if (p
[4] == '6' && p
[5] == '4')
9768 priv
.orig_sizeflag
|= AFLAG
;
9772 if (p
[4] == '1' && p
[5] == '6')
9773 priv
.orig_sizeflag
&= ~AFLAG
;
9774 else if (p
[4] == '3' && p
[5] == '2')
9775 priv
.orig_sizeflag
|= AFLAG
;
9778 else if (startswith (p
, "data"))
9780 if (p
[4] == '1' && p
[5] == '6')
9781 priv
.orig_sizeflag
&= ~DFLAG
;
9782 else if (p
[4] == '3' && p
[5] == '2')
9783 priv
.orig_sizeflag
|= DFLAG
;
9785 else if (startswith (p
, "suffix"))
9786 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
9788 p
= strchr (p
, ',');
9793 if (ins
.address_mode
== mode_64bit
&& sizeof (bfd_vma
) < 8)
9795 i386_dis_printf (info
, dis_style_text
, _("64-bit address is disabled"));
9799 if (ins
.intel_syntax
)
9801 ins
.open_char
= '[';
9802 ins
.close_char
= ']';
9803 ins
.separator_char
= '+';
9804 ins
.scale_char
= '*';
9808 ins
.open_char
= '(';
9809 ins
.close_char
= ')';
9810 ins
.separator_char
= ',';
9811 ins
.scale_char
= ',';
9814 /* The output looks better if we put 7 bytes on a line, since that
9815 puts most long word instructions on a single line. */
9816 info
->bytes_per_line
= 7;
9818 info
->private_data
= &priv
;
9820 priv
.insn_start
= pc
;
9822 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9825 ins
.op_out
[i
] = op_out
[i
];
9828 sizeflag
= priv
.orig_sizeflag
;
9830 switch (ckprefix (&ins
))
9836 /* Too many prefixes or unused REX prefixes. */
9838 i
< (int) ARRAY_SIZE (ins
.all_prefixes
) && ins
.all_prefixes
[i
];
9840 i386_dis_printf (info
, dis_style_mnemonic
, "%s%s",
9841 (i
== 0 ? "" : " "),
9842 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9847 case ckp_fetch_error
:
9848 goto fetch_error_out
;
9851 ins
.nr_prefixes
= ins
.codep
- ins
.start_codep
;
9853 if (!fetch_code (info
, ins
.codep
+ 1))
9856 ret
= fetch_error (&ins
);
9860 ins
.two_source_ops
= (*ins
.codep
== 0x62 || *ins
.codep
== 0xc8);
9862 if ((ins
.prefixes
& PREFIX_FWAIT
)
9863 && (*ins
.codep
< 0xd8 || *ins
.codep
> 0xdf))
9865 /* Handle ins.prefixes before fwait. */
9866 for (i
= 0; i
< ins
.fwait_prefix
&& ins
.all_prefixes
[i
];
9868 i386_dis_printf (info
, dis_style_mnemonic
, "%s ",
9869 prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
9871 i386_dis_printf (info
, dis_style_mnemonic
, "fwait");
9876 /* REX2.M in rex2 prefix represents map0 or map1. */
9877 if (ins
.last_rex2_prefix
< 0 ? *ins
.codep
== 0x0f : (ins
.rex2
& REX2_M
))
9882 if (!fetch_code (info
, ins
.codep
+ 1))
9883 goto fetch_error_out
;
9886 dp
= &dis386_twobyte
[*ins
.codep
];
9887 ins
.need_modrm
= twobyte_has_modrm
[*ins
.codep
];
9891 dp
= &dis386
[*ins
.codep
];
9892 ins
.need_modrm
= onebyte_has_modrm
[*ins
.codep
];
9894 ins
.condition_code
= *ins
.codep
& 0xf;
9897 /* Save sizeflag for printing the extra ins.prefixes later before updating
9898 it for mnemonic and operand processing. The prefix names depend
9899 only on the address mode. */
9900 orig_sizeflag
= sizeflag
;
9901 if (ins
.prefixes
& PREFIX_ADDR
)
9903 if ((ins
.prefixes
& PREFIX_DATA
))
9906 ins
.end_codep
= ins
.codep
;
9907 if (ins
.need_modrm
&& !fetch_modrm (&ins
))
9908 goto fetch_error_out
;
9910 if (dp
->name
== NULL
&& dp
->op
[0].bytemode
== FLOATCODE
)
9912 if (!get_sib (&ins
, sizeflag
)
9913 || !dofloat (&ins
, sizeflag
))
9914 goto fetch_error_out
;
9918 dp
= get_valid_dis386 (dp
, &ins
);
9919 if (dp
== &err_opcode
)
9920 goto fetch_error_out
;
9922 /* For APX instructions promoted from legacy maps 0/1, embedded prefix
9923 is interpreted as the operand size override. */
9924 if (ins
.evex_type
== evex_from_legacy
9925 && ins
.vex
.prefix
== DATA_PREFIX_OPCODE
)
9928 if(ins
.evex_type
== evex_default
)
9931 /* For EVEX-promoted formats, we need to clear EVEX.NF (ccmp and ctest
9932 are cleared separately.) in mask_register_specifier and keep the low
9933 2 bits of mask_register_specifier to report errors for invalid cases
9935 ins
.vex
.mask_register_specifier
&= 0x3;
9937 if (dp
!= NULL
&& putop (&ins
, dp
->name
, sizeflag
) == 0)
9939 if (!get_sib (&ins
, sizeflag
))
9940 goto fetch_error_out
;
9941 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
9943 ins
.obufp
= ins
.op_out
[i
];
9944 ins
.op_ad
= MAX_OPERANDS
- 1 - i
;
9946 && !dp
->op
[i
].rtn (&ins
, dp
->op
[i
].bytemode
, sizeflag
))
9947 goto fetch_error_out
;
9948 /* For EVEX instruction after the last operand masking
9949 should be printed. */
9950 if (i
== 0 && ins
.vex
.evex
)
9952 /* Don't print {%k0}. */
9953 if (ins
.vex
.mask_register_specifier
)
9955 const char *reg_name
9956 = att_names_mask
[ins
.vex
.mask_register_specifier
];
9958 oappend (&ins
, "{");
9959 oappend_register (&ins
, reg_name
);
9960 oappend (&ins
, "}");
9962 if (ins
.vex
.zeroing
)
9963 oappend (&ins
, "{z}");
9965 else if (ins
.vex
.zeroing
)
9967 oappend (&ins
, "{bad}");
9971 /* Instructions with a mask register destination allow for
9972 zeroing-masking only (if any masking at all), which is
9973 _not_ expressed by EVEX.z. */
9974 if (ins
.vex
.zeroing
&& dp
->op
[0].bytemode
== mask_mode
)
9975 ins
.illegal_masking
= true;
9977 /* S/G insns require a mask and don't allow
9979 if ((dp
->op
[0].bytemode
== vex_vsib_d_w_dq_mode
9980 || dp
->op
[0].bytemode
== vex_vsib_q_w_dq_mode
)
9981 && (ins
.vex
.mask_register_specifier
== 0
9982 || ins
.vex
.zeroing
))
9983 ins
.illegal_masking
= true;
9985 if (ins
.illegal_masking
)
9986 oappend (&ins
, "/(bad)");
9989 /* vex.nf is cleared after being consumed. */
9991 oappend (&ins
, "{bad-nf}");
9993 /* Check whether rounding control was enabled for an insn not
9994 supporting it, when evex.b is not treated as evex.nd. */
9995 if (ins
.modrm
.mod
== 3 && ins
.vex
.b
&& ins
.evex_type
== evex_default
9996 && !(ins
.evex_used
& EVEX_b_used
))
9998 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10000 ins
.obufp
= ins
.op_out
[i
];
10003 oappend (&ins
, names_rounding
[ins
.vex
.ll
]);
10004 oappend (&ins
, "bad}");
10011 /* Clear instruction information. */
10012 info
->insn_info_valid
= 0;
10013 info
->branch_delay_insns
= 0;
10014 info
->data_size
= 0;
10015 info
->insn_type
= dis_noninsn
;
10019 /* Reset jump operation indicator. */
10020 ins
.op_is_jump
= false;
10022 int jump_detection
= 0;
10024 /* Extract flags. */
10025 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10027 if ((dp
->op
[i
].rtn
== OP_J
)
10028 || (dp
->op
[i
].rtn
== OP_indirE
))
10029 jump_detection
|= 1;
10030 else if ((dp
->op
[i
].rtn
== BND_Fixup
)
10031 || (!dp
->op
[i
].rtn
&& !dp
->op
[i
].bytemode
))
10032 jump_detection
|= 2;
10033 else if ((dp
->op
[i
].bytemode
== cond_jump_mode
)
10034 || (dp
->op
[i
].bytemode
== loop_jcxz_mode
))
10035 jump_detection
|= 4;
10038 /* Determine if this is a jump or branch. */
10039 if ((jump_detection
& 0x3) == 0x3)
10041 ins
.op_is_jump
= true;
10042 if (jump_detection
& 0x4)
10043 info
->insn_type
= dis_condbranch
;
10045 info
->insn_type
= (dp
->name
&& !strncmp (dp
->name
, "call", 4))
10046 ? dis_jsr
: dis_branch
;
10049 /* The purpose of placing the check here is to wait for the EVEX prefix for
10050 conditional CMP and TEST to be consumed and cleared, and then make a
10051 unified judgment. Because they are both in map4, we can not distinguish
10052 EVEX prefix for conditional CMP and TEST from others during the
10053 EVEX prefix stage of parsing. */
10054 if (ins
.evex_type
== evex_from_legacy
)
10056 /* EVEX from legacy instructions, when the EVEX.ND bit is 0,
10057 all bits of EVEX.vvvv and EVEX.V' must be 1. */
10058 if (!ins
.vex
.nd
&& (ins
.vex
.register_specifier
|| !ins
.vex
.v
))
10060 i386_dis_printf (info
, dis_style_text
, "(bad)");
10061 ret
= ins
.end_codep
- priv
.the_buffer
;
10065 /* EVEX from legacy instructions require that EVEX.z, EVEX.L’L and the
10066 lower 2 bits of EVEX.aaa must be 0. */
10067 if ((ins
.vex
.mask_register_specifier
& 0x3) != 0
10068 || ins
.vex
.ll
!= 0 || ins
.vex
.zeroing
!= 0)
10070 i386_dis_printf (info
, dis_style_text
, "(bad)");
10071 ret
= ins
.end_codep
- priv
.the_buffer
;
10075 /* If VEX.vvvv and EVEX.vvvv are unused, they must be all 1s, which
10076 are all 0s in inverted form. */
10077 if (ins
.need_vex
&& ins
.vex
.register_specifier
!= 0)
10079 i386_dis_printf (info
, dis_style_text
, "(bad)");
10080 ret
= ins
.end_codep
- priv
.the_buffer
;
10084 if ((dp
->prefix_requirement
& PREFIX_REX2_ILLEGAL
)
10085 && ins
.last_rex2_prefix
>= 0 && (ins
.rex2
& REX2_SPECIAL
) == 0)
10087 i386_dis_printf (info
, dis_style_text
, "(bad)");
10088 ret
= ins
.end_codep
- priv
.the_buffer
;
10092 switch (dp
->prefix_requirement
& ~PREFIX_REX2_ILLEGAL
)
10095 /* If only the data prefix is marked as mandatory, its absence renders
10096 the encoding invalid. Most other PREFIX_OPCODE rules still apply. */
10097 if (ins
.need_vex
? !ins
.vex
.prefix
: !(ins
.prefixes
& PREFIX_DATA
))
10099 i386_dis_printf (info
, dis_style_text
, "(bad)");
10100 ret
= ins
.end_codep
- priv
.the_buffer
;
10103 ins
.used_prefixes
|= PREFIX_DATA
;
10104 /* Fall through. */
10105 case PREFIX_OPCODE
:
10106 /* If the mandatory PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is
10107 unused, opcode is invalid. Since the PREFIX_DATA prefix may be
10108 used by putop and MMX/SSE operand and may be overridden by the
10109 PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
10112 ? ins
.vex
.prefix
== REPE_PREFIX_OPCODE
10113 || ins
.vex
.prefix
== REPNE_PREFIX_OPCODE
10115 & (PREFIX_REPZ
| PREFIX_REPNZ
)) != 0)
10116 && (ins
.used_prefixes
10117 & (PREFIX_REPZ
| PREFIX_REPNZ
)) == 0)
10119 ? ins
.vex
.prefix
== DATA_PREFIX_OPCODE
10121 & (PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
))
10123 && (ins
.used_prefixes
& PREFIX_DATA
) == 0))
10124 || (ins
.vex
.evex
&& dp
->prefix_requirement
!= PREFIX_DATA
10125 && !ins
.vex
.w
!= !(ins
.used_prefixes
& PREFIX_DATA
)))
10127 i386_dis_printf (info
, dis_style_text
, "(bad)");
10128 ret
= ins
.end_codep
- priv
.the_buffer
;
10133 case PREFIX_IGNORED
:
10134 /* Zap data size and rep prefixes from used_prefixes and reinstate their
10135 origins in all_prefixes. */
10136 ins
.used_prefixes
&= ~PREFIX_OPCODE
;
10137 if (ins
.last_data_prefix
>= 0)
10138 ins
.all_prefixes
[ins
.last_data_prefix
] = 0x66;
10139 if (ins
.last_repz_prefix
>= 0)
10140 ins
.all_prefixes
[ins
.last_repz_prefix
] = 0xf3;
10141 if (ins
.last_repnz_prefix
>= 0)
10142 ins
.all_prefixes
[ins
.last_repnz_prefix
] = 0xf2;
10145 case PREFIX_NP_OR_DATA
:
10146 if (ins
.vex
.prefix
== REPE_PREFIX_OPCODE
10147 || ins
.vex
.prefix
== REPNE_PREFIX_OPCODE
)
10149 i386_dis_printf (info
, dis_style_text
, "(bad)");
10150 ret
= ins
.end_codep
- priv
.the_buffer
;
10156 if (ins
.vex
.prefix
)
10158 i386_dis_printf (info
, dis_style_text
, "(bad)");
10159 ret
= ins
.end_codep
- priv
.the_buffer
;
10165 /* Check if the REX prefix is used. */
10166 if ((ins
.rex
^ ins
.rex_used
) == 0
10167 && !ins
.need_vex
&& ins
.last_rex_prefix
>= 0)
10168 ins
.all_prefixes
[ins
.last_rex_prefix
] = 0;
10170 /* Check if the REX2 prefix is used. */
10171 if (ins
.last_rex2_prefix
>= 0
10172 && ((ins
.rex2
& REX2_SPECIAL
)
10173 || (((ins
.rex2
& 7) ^ (ins
.rex2_used
& 7)) == 0
10174 && (ins
.rex
^ ins
.rex_used
) == 0
10175 && (ins
.rex2
& 7))))
10176 ins
.all_prefixes
[ins
.last_rex2_prefix
] = 0;
10178 /* Check if the SEG prefix is used. */
10179 if ((ins
.prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
| PREFIX_ES
10180 | PREFIX_FS
| PREFIX_GS
)) != 0
10181 && (ins
.used_prefixes
& ins
.active_seg_prefix
) != 0)
10182 ins
.all_prefixes
[ins
.last_seg_prefix
] = 0;
10184 /* Check if the ADDR prefix is used. */
10185 if ((ins
.prefixes
& PREFIX_ADDR
) != 0
10186 && (ins
.used_prefixes
& PREFIX_ADDR
) != 0)
10187 ins
.all_prefixes
[ins
.last_addr_prefix
] = 0;
10189 /* Check if the DATA prefix is used. */
10190 if ((ins
.prefixes
& PREFIX_DATA
) != 0
10191 && (ins
.used_prefixes
& PREFIX_DATA
) != 0
10193 ins
.all_prefixes
[ins
.last_data_prefix
] = 0;
10195 /* Print the extra ins.prefixes. */
10197 for (i
= 0; i
< (int) ARRAY_SIZE (ins
.all_prefixes
); i
++)
10198 if (ins
.all_prefixes
[i
])
10200 const char *name
= prefix_name (ins
.address_mode
, ins
.all_prefixes
[i
],
10205 prefix_length
+= strlen (name
) + 1;
10206 if (ins
.all_prefixes
[i
] == REX2_OPCODE
)
10207 i386_dis_printf (info
, dis_style_mnemonic
, "{%s 0x%x} ", name
,
10208 (unsigned int) ins
.rex2_payload
);
10210 i386_dis_printf (info
, dis_style_mnemonic
, "%s ", name
);
10213 /* Check maximum code length. */
10214 if ((ins
.codep
- ins
.start_codep
) > MAX_CODE_LENGTH
)
10216 i386_dis_printf (info
, dis_style_text
, "(bad)");
10217 ret
= MAX_CODE_LENGTH
;
10221 /* Calculate the number of operands this instruction has. */
10223 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10224 if (*ins
.op_out
[i
] != '\0')
10227 /* Calculate the number of spaces to print after the mnemonic. */
10228 ins
.obufp
= ins
.mnemonicendp
;
10231 i
= strlen (ins
.obuf
) + prefix_length
;
10240 /* Print the instruction mnemonic along with any trailing whitespace. */
10241 i386_dis_printf (info
, dis_style_mnemonic
, "%s%*s", ins
.obuf
, i
, "");
10243 /* The enter and bound instructions are printed with operands in the same
10244 order as the intel book; everything else is printed in reverse order. */
10245 intel_swap_2_3
= false;
10246 if (ins
.intel_syntax
|| ins
.two_source_ops
)
10248 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10249 op_txt
[i
] = ins
.op_out
[i
];
10251 if (ins
.intel_syntax
&& dp
&& dp
->op
[2].rtn
== OP_Rounding
10252 && dp
->op
[3].rtn
== OP_E
&& dp
->op
[4].rtn
== NULL
)
10254 op_txt
[2] = ins
.op_out
[3];
10255 op_txt
[3] = ins
.op_out
[2];
10256 intel_swap_2_3
= true;
10259 for (i
= 0; i
< (MAX_OPERANDS
>> 1); ++i
)
10263 ins
.op_ad
= ins
.op_index
[i
];
10264 ins
.op_index
[i
] = ins
.op_index
[MAX_OPERANDS
- 1 - i
];
10265 ins
.op_index
[MAX_OPERANDS
- 1 - i
] = ins
.op_ad
;
10266 riprel
= ins
.op_riprel
[i
];
10267 ins
.op_riprel
[i
] = ins
.op_riprel
[MAX_OPERANDS
- 1 - i
];
10268 ins
.op_riprel
[MAX_OPERANDS
- 1 - i
] = riprel
;
10273 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10274 op_txt
[MAX_OPERANDS
- 1 - i
] = ins
.op_out
[i
];
10278 for (i
= 0; i
< MAX_OPERANDS
; ++i
)
10281 /* In Intel syntax embedded rounding / SAE are not separate operands.
10282 Instead they're attached to the prior register operand. Simply
10283 suppress emission of the comma to achieve that effect. */
10284 switch (i
& -(ins
.intel_syntax
&& dp
))
10287 if (dp
->op
[2].rtn
== OP_Rounding
&& !intel_swap_2_3
)
10291 if (dp
->op
[3].rtn
== OP_Rounding
|| intel_swap_2_3
)
10296 i386_dis_printf (info
, dis_style_text
, ",");
10297 if (ins
.op_index
[i
] != -1 && !ins
.op_riprel
[i
])
10299 bfd_vma target
= (bfd_vma
) ins
.op_address
[ins
.op_index
[i
]];
10301 if (ins
.op_is_jump
)
10303 info
->insn_info_valid
= 1;
10304 info
->branch_delay_insns
= 0;
10305 info
->data_size
= 0;
10306 info
->target
= target
;
10309 (*info
->print_address_func
) (target
, info
);
10312 i386_dis_printf (info
, dis_style_text
, "%s", op_txt
[i
]);
10316 for (i
= 0; i
< MAX_OPERANDS
; i
++)
10317 if (ins
.op_index
[i
] != -1 && ins
.op_riprel
[i
])
10319 i386_dis_printf (info
, dis_style_comment_start
, " # ");
10320 (*info
->print_address_func
)
10321 ((bfd_vma
)(ins
.start_pc
+ (ins
.codep
- ins
.start_codep
)
10322 + ins
.op_address
[ins
.op_index
[i
]]),
10326 ret
= ins
.codep
- priv
.the_buffer
;
10328 info
->private_data
= NULL
;
10332 /* Here for backwards compatibility. When gdb stops using
10333 print_insn_i386_att and print_insn_i386_intel these functions can
10334 disappear, and print_insn_i386 be merged into print_insn. */
10336 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
10338 return print_insn (pc
, info
, 0);
10342 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
10344 return print_insn (pc
, info
, 1);
10348 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
10350 return print_insn (pc
, info
, -1);
10353 static const char *float_mem
[] = {
10428 static const unsigned char float_mem_mode
[] = {
10503 #define ST { OP_ST, 0 }
10504 #define STi { OP_STi, 0 }
10506 #define FGRPd9_2 NULL, { { NULL, 1 } }, 0
10507 #define FGRPd9_4 NULL, { { NULL, 2 } }, 0
10508 #define FGRPd9_5 NULL, { { NULL, 3 } }, 0
10509 #define FGRPd9_6 NULL, { { NULL, 4 } }, 0
10510 #define FGRPd9_7 NULL, { { NULL, 5 } }, 0
10511 #define FGRPda_5 NULL, { { NULL, 6 } }, 0
10512 #define FGRPdb_4 NULL, { { NULL, 7 } }, 0
10513 #define FGRPde_3 NULL, { { NULL, 8 } }, 0
10514 #define FGRPdf_4 NULL, { { NULL, 9 } }, 0
10516 static const struct dis386 float_reg
[][8] = {
10519 { "fadd", { ST
, STi
}, 0 },
10520 { "fmul", { ST
, STi
}, 0 },
10521 { "fcom", { STi
}, 0 },
10522 { "fcomp", { STi
}, 0 },
10523 { "fsub", { ST
, STi
}, 0 },
10524 { "fsubr", { ST
, STi
}, 0 },
10525 { "fdiv", { ST
, STi
}, 0 },
10526 { "fdivr", { ST
, STi
}, 0 },
10530 { "fld", { STi
}, 0 },
10531 { "fxch", { STi
}, 0 },
10541 { "fcmovb", { ST
, STi
}, 0 },
10542 { "fcmove", { ST
, STi
}, 0 },
10543 { "fcmovbe",{ ST
, STi
}, 0 },
10544 { "fcmovu", { ST
, STi
}, 0 },
10552 { "fcmovnb",{ ST
, STi
}, 0 },
10553 { "fcmovne",{ ST
, STi
}, 0 },
10554 { "fcmovnbe",{ ST
, STi
}, 0 },
10555 { "fcmovnu",{ ST
, STi
}, 0 },
10557 { "fucomi", { ST
, STi
}, 0 },
10558 { "fcomi", { ST
, STi
}, 0 },
10563 { "fadd", { STi
, ST
}, 0 },
10564 { "fmul", { STi
, ST
}, 0 },
10567 { "fsub{!M|r}", { STi
, ST
}, 0 },
10568 { "fsub{M|}", { STi
, ST
}, 0 },
10569 { "fdiv{!M|r}", { STi
, ST
}, 0 },
10570 { "fdiv{M|}", { STi
, ST
}, 0 },
10574 { "ffree", { STi
}, 0 },
10576 { "fst", { STi
}, 0 },
10577 { "fstp", { STi
}, 0 },
10578 { "fucom", { STi
}, 0 },
10579 { "fucomp", { STi
}, 0 },
10585 { "faddp", { STi
, ST
}, 0 },
10586 { "fmulp", { STi
, ST
}, 0 },
10589 { "fsub{!M|r}p", { STi
, ST
}, 0 },
10590 { "fsub{M|}p", { STi
, ST
}, 0 },
10591 { "fdiv{!M|r}p", { STi
, ST
}, 0 },
10592 { "fdiv{M|}p", { STi
, ST
}, 0 },
10596 { "ffreep", { STi
}, 0 },
10601 { "fucomip", { ST
, STi
}, 0 },
10602 { "fcomip", { ST
, STi
}, 0 },
10607 static const char *const fgrps
[][8] = {
10610 "(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10615 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10620 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
10625 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
10630 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
10635 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
10640 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10645 "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
10646 "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
10651 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10656 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
10660 static const char *const oszc_flags
[16] = {
10661 " {dfv=}", " {dfv=cf}", " {dfv=zf}", " {dfv=zf, cf}", " {dfv=sf}",
10662 " {dfv=sf, cf}", " {dfv=sf, zf}", " {dfv=sf, zf, cf}", " {dfv=of}",
10663 " {dfv=of, cf}", " {dfv=of, zf}", " {dfv=of, zf, cf}", " {dfv=of, sf}",
10664 " {dfv=of, sf, cf}", " {dfv=of, sf, zf}", " {dfv=of, sf, zf, cf}"
10667 static const char *const scc_suffix
[16] = {
10668 "o", "no", "b", "ae", "e", "ne", "be", "a", "s", "ns", "t", "f",
10669 "l", "ge", "le", "g"
10673 swap_operand (instr_info
*ins
)
10675 char *p
= ins
->mnemonicendp
;
10679 while (*--p
!= '{')
10681 if (p
<= ins
->obuf
+ 2)
10687 memmove (p
+ 2, p
, ins
->mnemonicendp
- p
+ 1);
10690 ins
->mnemonicendp
+= 2;
10694 dofloat (instr_info
*ins
, int sizeflag
)
10696 const struct dis386
*dp
;
10697 unsigned char floatop
= ins
->codep
[-1];
10699 if (ins
->modrm
.mod
!= 3)
10701 int fp_indx
= (floatop
- 0xd8) * 8 + ins
->modrm
.reg
;
10703 putop (ins
, float_mem
[fp_indx
], sizeflag
);
10704 ins
->obufp
= ins
->op_out
[0];
10706 return OP_E (ins
, float_mem_mode
[fp_indx
], sizeflag
);
10708 /* Skip mod/rm byte. */
10712 dp
= &float_reg
[floatop
- 0xd8][ins
->modrm
.reg
];
10713 if (dp
->name
== NULL
)
10715 putop (ins
, fgrps
[dp
->op
[0].bytemode
][ins
->modrm
.rm
], sizeflag
);
10717 /* Instruction fnstsw is only one with strange arg. */
10718 if (floatop
== 0xdf && ins
->codep
[-1] == 0xe0)
10719 strcpy (ins
->op_out
[0], att_names16
[0] + ins
->intel_syntax
);
10723 putop (ins
, dp
->name
, sizeflag
);
10725 ins
->obufp
= ins
->op_out
[0];
10728 && !dp
->op
[0].rtn (ins
, dp
->op
[0].bytemode
, sizeflag
))
10731 ins
->obufp
= ins
->op_out
[1];
10734 && !dp
->op
[1].rtn (ins
, dp
->op
[1].bytemode
, sizeflag
))
10741 OP_ST (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10742 int sizeflag ATTRIBUTE_UNUSED
)
10744 oappend_register (ins
, "%st");
10749 OP_STi (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
10750 int sizeflag ATTRIBUTE_UNUSED
)
10753 int res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%st(%d)", ins
->modrm
.rm
);
10755 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
10757 oappend_register (ins
, scratch
);
10761 /* Capital letters in template are macros. */
10763 putop (instr_info
*ins
, const char *in_template
, int sizeflag
)
10768 unsigned int l
= 0, len
= 0;
10770 bool evex_printed
= false;
10772 /* We don't want to add any prefix or suffix to (bad), so return early. */
10773 if (!strncmp (in_template
, "(bad)", 5))
10775 oappend (ins
, "(bad)");
10777 ins
->mnemonicendp
= ins
->obufp
;
10781 for (p
= in_template
; *p
; p
++)
10785 if (l
>= sizeof (last
) || !ISUPPER (*p
))
10793 if (ins
->evex_type
== evex_from_legacy
&& !ins
->vex
.nd
10794 && !(ins
->rex2
& 7) && !evex_printed
)
10796 oappend (ins
, "{evex} ");
10797 evex_printed
= true;
10799 *ins
->obufp
++ = *p
;
10808 if (ins
->intel_syntax
)
10810 while (*++p
!= '|')
10811 if (*p
== '}' || *p
== '\0')
10817 while (*++p
!= '}')
10827 if (ins
->intel_syntax
)
10829 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3 && !ins
->vex
.nd
)
10830 || (sizeflag
& SUFFIX_ALWAYS
))
10831 *ins
->obufp
++ = 'b';
10837 if (ins
->intel_syntax
)
10839 if (sizeflag
& SUFFIX_ALWAYS
)
10840 *ins
->obufp
++ = 'b';
10842 else if (l
== 1 && last
[0] == 'L')
10844 if (ins
->address_mode
== mode_64bit
10845 && !(ins
->prefixes
& PREFIX_ADDR
))
10847 *ins
->obufp
++ = 'a';
10848 *ins
->obufp
++ = 'b';
10849 *ins
->obufp
++ = 's';
10854 else if (l
&& last
[0] == 'X')
10857 oappend (ins
, "bf16");
10859 oappend (ins
, "{bad}");
10865 if (l
== 1 && last
[0] == 'C')
10867 /* Condition code (taken from the map-0 Jcc entries). */
10868 for (const char *q
= dis386
[0x70 | ins
->condition_code
].name
+ 1;
10870 *ins
->obufp
++ = *q
;
10873 else if (l
== 1 && last
[0] == 'S')
10875 /* Add scc suffix. */
10876 oappend (ins
, scc_suffix
[ins
->vex
.scc
]);
10878 /* For SCC insns, the ND bit is required to be set to 0. */
10880 oappend (ins
, "(bad)");
10882 /* These bits have been consumed and should be cleared or restored
10883 to default values. */
10885 ins
->vex
.nf
= false;
10886 ins
->vex
.mask_register_specifier
= 0;
10892 if (ins
->intel_syntax
&& !alt
)
10894 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
10896 if (sizeflag
& DFLAG
)
10897 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10899 *ins
->obufp
++ = ins
->intel_syntax
? 'w' : 's';
10900 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10909 if (!ins
->vex
.evex
|| ins
->vex
.w
)
10910 *ins
->obufp
++ = 'd';
10912 oappend (ins
, "{bad}");
10921 if (ins
->intel_syntax
|| !(sizeflag
& SUFFIX_ALWAYS
))
10924 if (ins
->modrm
.mod
== 3)
10926 if (ins
->rex
& REX_W
)
10927 *ins
->obufp
++ = 'q';
10930 if (sizeflag
& DFLAG
)
10931 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
10933 *ins
->obufp
++ = 'w';
10934 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
10938 *ins
->obufp
++ = 'w';
10946 if (ins
->modrm
.mod
!= 3)
10948 /* Fall through. */
10950 if (!ins
->vex
.evex
|| ins
->vex
.b
|| ins
->vex
.ll
>= 2
10952 || (ins
->modrm
.mod
== 3 && (ins
->rex
& REX_X
))
10953 || !ins
->vex
.v
|| ins
->vex
.mask_register_specifier
)
10955 /* AVX512 extends a number of V*D insns to also have V*Q variants,
10956 merely distinguished by EVEX.W. Look for a use of the
10957 respective macro. */
10960 const char *pct
= strchr (p
+ 1, '%');
10962 if (pct
!= NULL
&& pct
[1] == 'D' && pct
[2] == 'Q')
10965 *ins
->obufp
++ = '{';
10966 *ins
->obufp
++ = 'e';
10967 *ins
->obufp
++ = 'v';
10968 *ins
->obufp
++ = 'e';
10969 *ins
->obufp
++ = 'x';
10970 *ins
->obufp
++ = '}';
10971 *ins
->obufp
++ = ' ';
10974 /* Skip printing {evex} for some special instructions in MAP4. */
10975 evex_printed
= true;
10982 /* For jcxz/jecxz */
10983 if (ins
->address_mode
== mode_64bit
)
10985 if (sizeflag
& AFLAG
)
10986 *ins
->obufp
++ = 'r';
10988 *ins
->obufp
++ = 'e';
10991 if (sizeflag
& AFLAG
)
10992 *ins
->obufp
++ = 'e';
10993 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
10998 if (ins
->intel_syntax
)
11000 if ((ins
->prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
11002 if (sizeflag
& AFLAG
)
11003 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
11005 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'l' : 'w';
11006 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
11009 else if (l
== 1 && last
[0] == 'C')
11011 if (ins
->vex
.nd
&& !ins
->vex
.nf
)
11013 *ins
->obufp
++ = 'c';
11014 *ins
->obufp
++ = 'f';
11015 /* Skip printing {evex} */
11016 evex_printed
= true;
11018 else if (l
== 1 && last
[0] == 'N')
11022 oappend (ins
, "{nf} ");
11023 /* This bit needs to be cleared after it is consumed. */
11024 ins
->vex
.nf
= false;
11025 evex_printed
= true;
11027 else if (ins
->evex_type
== evex_from_vex
&& !(ins
->rex2
& 7)
11030 oappend (ins
, "{evex} ");
11031 evex_printed
= true;
11034 else if (l
== 1 && last
[0] == 'D')
11036 /* Get oszc flags value from register_specifier. */
11037 int oszc_value
= ~ins
->vex
.register_specifier
& 0xf;
11039 /* Add {dfv=of, sf, zf, cf} flags. */
11040 oappend (ins
, oszc_flags
[oszc_value
]);
11042 /* These bits have been consumed and should be cleared. */
11043 ins
->vex
.register_specifier
= 0;
11049 if (ins
->intel_syntax
|| (ins
->obufp
[-1] != 's'
11050 && !(sizeflag
& SUFFIX_ALWAYS
)))
11052 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
11053 *ins
->obufp
++ = 'l';
11055 *ins
->obufp
++ = 'w';
11056 if (!(ins
->rex
& REX_W
))
11057 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11062 if (ins
->intel_syntax
)
11064 if ((ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
11065 || (ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
11067 ins
->used_prefixes
|= ins
->prefixes
& (PREFIX_CS
| PREFIX_DS
);
11068 *ins
->obufp
++ = ',';
11069 *ins
->obufp
++ = 'p';
11071 /* Set active_seg_prefix even if not set in 64-bit mode
11072 because here it is a valid branch hint. */
11073 if (ins
->prefixes
& PREFIX_DS
)
11075 ins
->active_seg_prefix
= PREFIX_DS
;
11076 *ins
->obufp
++ = 't';
11080 ins
->active_seg_prefix
= PREFIX_CS
;
11081 *ins
->obufp
++ = 'n';
11085 else if (l
== 1 && last
[0] == 'X')
11088 *ins
->obufp
++ = 'h';
11090 oappend (ins
, "{bad}");
11097 if (ins
->rex
& REX_W
)
11098 *ins
->obufp
++ = 'q';
11100 *ins
->obufp
++ = 'd';
11103 if (ins
->intel_syntax
)
11105 if (sizeflag
& SUFFIX_ALWAYS
)
11107 if (ins
->rex
& REX_W
)
11108 *ins
->obufp
++ = 'q';
11110 *ins
->obufp
++ = 'l';
11114 if (ins
->intel_mnemonic
!= cond
)
11115 *ins
->obufp
++ = 'r';
11118 if ((ins
->prefixes
& PREFIX_FWAIT
) == 0)
11119 *ins
->obufp
++ = 'n';
11121 ins
->used_prefixes
|= PREFIX_FWAIT
;
11125 if (ins
->rex
& REX_W
)
11126 *ins
->obufp
++ = 'o';
11127 else if (ins
->intel_syntax
&& (sizeflag
& DFLAG
))
11128 *ins
->obufp
++ = 'q';
11130 *ins
->obufp
++ = 'd';
11131 if (!(ins
->rex
& REX_W
))
11132 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11135 if (ins
->address_mode
== mode_64bit
11136 && (ins
->isa64
== intel64
|| (ins
->rex
& REX_W
)
11137 || !(ins
->prefixes
& PREFIX_DATA
)))
11139 if (sizeflag
& SUFFIX_ALWAYS
)
11140 *ins
->obufp
++ = 'q';
11143 /* Fall through. */
11147 if (!cond
&& ins
->last_rex2_prefix
>= 0 && (ins
->rex
& REX_W
))
11149 /* For pushp and popp, p is printed and do not print {rex2}
11151 *ins
->obufp
++ = 'p';
11152 ins
->rex2
|= REX2_SPECIAL
;
11156 /* For "!P" print nothing else in Intel syntax. */
11157 if (!cond
&& ins
->intel_syntax
)
11160 if ((ins
->modrm
.mod
== 3 || !cond
)
11161 && !(sizeflag
& SUFFIX_ALWAYS
))
11163 /* Fall through. */
11165 if ((!(ins
->rex
& REX_W
) && (ins
->prefixes
& PREFIX_DATA
))
11166 || ((sizeflag
& SUFFIX_ALWAYS
)
11167 && ins
->address_mode
!= mode_64bit
))
11169 *ins
->obufp
++ = (sizeflag
& DFLAG
)
11170 ? ins
->intel_syntax
? 'd' : 'l' : 'w';
11171 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11173 else if (sizeflag
& SUFFIX_ALWAYS
)
11174 *ins
->obufp
++ = 'q';
11176 else if (l
== 1 && last
[0] == 'L')
11178 if ((ins
->prefixes
& PREFIX_DATA
)
11179 || (ins
->rex
& REX_W
)
11180 || (sizeflag
& SUFFIX_ALWAYS
))
11183 if (ins
->rex
& REX_W
)
11184 *ins
->obufp
++ = 'q';
11187 if (sizeflag
& DFLAG
)
11188 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
11190 *ins
->obufp
++ = 'w';
11191 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11201 if (ins
->intel_syntax
&& !alt
)
11204 if ((ins
->need_modrm
&& ins
->modrm
.mod
!= 3 && !ins
->vex
.nd
)
11205 || (sizeflag
& SUFFIX_ALWAYS
))
11207 if (ins
->rex
& REX_W
)
11208 *ins
->obufp
++ = 'q';
11211 if (sizeflag
& DFLAG
)
11212 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
11214 *ins
->obufp
++ = 'w';
11215 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11219 else if (l
== 1 && last
[0] == 'D')
11220 *ins
->obufp
++ = ins
->vex
.w
? 'q' : 'd';
11221 else if (l
== 1 && last
[0] == 'L')
11223 if (cond
? ins
->modrm
.mod
== 3 && !(sizeflag
& SUFFIX_ALWAYS
)
11224 : ins
->address_mode
!= mode_64bit
)
11226 if ((ins
->rex
& REX_W
))
11229 *ins
->obufp
++ = 'q';
11231 else if ((ins
->address_mode
== mode_64bit
&& cond
)
11232 || (sizeflag
& SUFFIX_ALWAYS
))
11233 *ins
->obufp
++ = ins
->intel_syntax
? 'd' : 'l';
11240 if (ins
->rex
& REX_W
)
11241 *ins
->obufp
++ = 'q';
11242 else if (sizeflag
& DFLAG
)
11244 if (ins
->intel_syntax
)
11245 *ins
->obufp
++ = 'd';
11247 *ins
->obufp
++ = 'l';
11250 *ins
->obufp
++ = 'w';
11251 if (ins
->intel_syntax
&& !p
[1]
11252 && ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
)))
11253 *ins
->obufp
++ = 'e';
11254 if (!(ins
->rex
& REX_W
))
11255 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11261 if (ins
->intel_syntax
)
11263 if (sizeflag
& SUFFIX_ALWAYS
)
11265 if (ins
->rex
& REX_W
)
11266 *ins
->obufp
++ = 'q';
11269 if (sizeflag
& DFLAG
)
11270 *ins
->obufp
++ = 'l';
11272 *ins
->obufp
++ = 'w';
11273 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11283 if (ins
->address_mode
== mode_64bit
11284 && !(ins
->prefixes
& PREFIX_ADDR
))
11286 *ins
->obufp
++ = 'a';
11287 *ins
->obufp
++ = 'b';
11288 *ins
->obufp
++ = 's';
11293 if (!ins
->vex
.evex
|| !ins
->vex
.w
)
11294 *ins
->obufp
++ = 's';
11296 oappend (ins
, "{bad}");
11303 if (l
== 1 && (last
[0] == 'Z'))
11305 /* Although IMUL/SETcc does not support NDD, the EVEX.ND bit is
11306 used to control whether its destination register has its upper
11309 oappend (ins
, "zu");
11318 *ins
->obufp
++ = 'v';
11327 *ins
->obufp
++ = '{';
11328 *ins
->obufp
++ = 'v';
11329 *ins
->obufp
++ = 'e';
11330 *ins
->obufp
++ = 'x';
11331 *ins
->obufp
++ = '}';
11332 *ins
->obufp
++ = ' ';
11335 if (ins
->rex
& REX_W
)
11337 *ins
->obufp
++ = 'a';
11338 *ins
->obufp
++ = 'b';
11339 *ins
->obufp
++ = 's';
11352 /* operand size flag for cwtl, cbtw */
11354 if (ins
->rex
& REX_W
)
11356 if (ins
->intel_syntax
)
11357 *ins
->obufp
++ = 'd';
11359 *ins
->obufp
++ = 'l';
11361 else if (sizeflag
& DFLAG
)
11362 *ins
->obufp
++ = 'w';
11364 *ins
->obufp
++ = 'b';
11365 if (!(ins
->rex
& REX_W
))
11366 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11370 if (!ins
->need_vex
)
11372 if (last
[0] == 'X')
11373 *ins
->obufp
++ = ins
->vex
.w
? 'd': 's';
11374 else if (last
[0] == 'B')
11375 *ins
->obufp
++ = ins
->vex
.w
? 'w': 'b';
11386 ? ins
->vex
.prefix
== DATA_PREFIX_OPCODE
11387 : ins
->prefixes
& PREFIX_DATA
)
11389 *ins
->obufp
++ = 'd';
11390 ins
->used_prefixes
|= PREFIX_DATA
;
11393 *ins
->obufp
++ = 's';
11398 if (ins
->vex
.mask_register_specifier
)
11399 ins
->illegal_masking
= true;
11401 else if (l
== 1 && last
[0] == 'X')
11403 if (!ins
->need_vex
)
11405 if (ins
->intel_syntax
11406 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
11407 && !(sizeflag
& SUFFIX_ALWAYS
)))
11409 switch (ins
->vex
.length
)
11412 *ins
->obufp
++ = 'x';
11415 *ins
->obufp
++ = 'y';
11418 if (!ins
->vex
.evex
)
11429 /* These insns ignore ModR/M.mod: Force it to 3 for OP_E(). */
11430 ins
->modrm
.mod
= 3;
11431 if (!ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
11432 *ins
->obufp
++ = ins
->address_mode
== mode_64bit
? 'q' : 'l';
11434 else if (l
== 1 && last
[0] == 'X')
11436 if (!ins
->vex
.evex
)
11438 if (ins
->intel_syntax
11439 || ((ins
->modrm
.mod
== 3 || ins
->vex
.b
)
11440 && !(sizeflag
& SUFFIX_ALWAYS
)))
11442 switch (ins
->vex
.length
)
11445 *ins
->obufp
++ = 'x';
11448 *ins
->obufp
++ = 'y';
11451 *ins
->obufp
++ = 'z';
11461 if (ins
->intel_syntax
)
11463 if (ins
->isa64
== intel64
&& (ins
->rex
& REX_W
))
11466 *ins
->obufp
++ = 'q';
11469 if ((ins
->prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
11471 if (sizeflag
& DFLAG
)
11472 *ins
->obufp
++ = 'l';
11474 *ins
->obufp
++ = 'w';
11475 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11484 ins
->mnemonicendp
= ins
->obufp
;
11488 /* Add a style marker to *INS->obufp that encodes STYLE. This assumes that
11489 the buffer pointed to by INS->obufp has space. A style marker is made
11490 from the STYLE_MARKER_CHAR followed by STYLE converted to a single hex
11491 digit, followed by another STYLE_MARKER_CHAR. This function assumes
11492 that the number of styles is not greater than 16. */
11495 oappend_insert_style (instr_info
*ins
, enum disassembler_style style
)
11497 unsigned num
= (unsigned) style
;
11499 /* We currently assume that STYLE can be encoded as a single hex
11500 character. If more styles are added then this might start to fail,
11501 and we'll need to expand this code. */
11505 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
11506 *ins
->obufp
++ = (num
< 10 ? ('0' + num
)
11507 : ((num
< 16) ? ('a' + (num
- 10)) : '0'));
11508 *ins
->obufp
++ = STYLE_MARKER_CHAR
;
11510 /* This final null character is not strictly necessary, after inserting a
11511 style marker we should always be inserting some additional content.
11512 However, having the buffer null terminated doesn't cost much, and make
11513 it easier to debug what's going on. Also, if we do ever forget to add
11514 any additional content after this style marker, then the buffer will
11515 still be well formed. */
11516 *ins
->obufp
= '\0';
11520 oappend_with_style (instr_info
*ins
, const char *s
,
11521 enum disassembler_style style
)
11523 oappend_insert_style (ins
, style
);
11524 ins
->obufp
= stpcpy (ins
->obufp
, s
);
11527 /* Add a single character C to the buffer pointer to by INS->obufp, marking
11528 the style for the character as STYLE. */
11531 oappend_char_with_style (instr_info
*ins
, const char c
,
11532 enum disassembler_style style
)
11534 oappend_insert_style (ins
, style
);
11536 *ins
->obufp
= '\0';
11539 /* Like oappend_char_with_style, but always uses dis_style_text. */
11542 oappend_char (instr_info
*ins
, const char c
)
11544 oappend_char_with_style (ins
, c
, dis_style_text
);
11548 append_seg (instr_info
*ins
)
11550 /* Only print the active segment register. */
11551 if (!ins
->active_seg_prefix
)
11554 ins
->used_prefixes
|= ins
->active_seg_prefix
;
11555 switch (ins
->active_seg_prefix
)
11558 oappend_register (ins
, att_names_seg
[1]);
11561 oappend_register (ins
, att_names_seg
[3]);
11564 oappend_register (ins
, att_names_seg
[2]);
11567 oappend_register (ins
, att_names_seg
[0]);
11570 oappend_register (ins
, att_names_seg
[4]);
11573 oappend_register (ins
, att_names_seg
[5]);
11578 oappend_char (ins
, ':');
11582 print_operand_value (instr_info
*ins
, bfd_vma disp
,
11583 enum disassembler_style style
)
11587 if (ins
->address_mode
!= mode_64bit
)
11588 disp
&= 0xffffffff;
11589 sprintf (tmp
, "0x%" PRIx64
, (uint64_t) disp
);
11590 oappend_with_style (ins
, tmp
, style
);
11593 /* Like oappend, but called for immediate operands. */
11596 oappend_immediate (instr_info
*ins
, bfd_vma imm
)
11598 if (!ins
->intel_syntax
)
11599 oappend_char_with_style (ins
, '$', dis_style_immediate
);
11600 print_operand_value (ins
, imm
, dis_style_immediate
);
11603 /* Put DISP in BUF as signed hex number. */
11606 print_displacement (instr_info
*ins
, bfd_signed_vma val
)
11612 oappend_char_with_style (ins
, '-', dis_style_address_offset
);
11613 val
= (bfd_vma
) 0 - val
;
11615 /* Check for possible overflow. */
11618 switch (ins
->address_mode
)
11621 oappend_with_style (ins
, "0x8000000000000000",
11622 dis_style_address_offset
);
11625 oappend_with_style (ins
, "0x80000000",
11626 dis_style_address_offset
);
11629 oappend_with_style (ins
, "0x8000",
11630 dis_style_address_offset
);
11637 sprintf (tmp
, "0x%" PRIx64
, (int64_t) val
);
11638 oappend_with_style (ins
, tmp
, dis_style_address_offset
);
11642 intel_operand_size (instr_info
*ins
, int bytemode
, int sizeflag
)
11644 /* Check if there is a broadcast, when evex.b is not treated as evex.nd. */
11645 if (ins
->vex
.b
&& ins
->evex_type
== evex_default
)
11647 if (!ins
->vex
.no_broadcast
)
11651 case evex_half_bcst_xmmq_mode
:
11653 oappend (ins
, "QWORD BCST ");
11655 oappend (ins
, "DWORD BCST ");
11658 case evex_half_bcst_xmmqh_mode
:
11659 case evex_half_bcst_xmmqdh_mode
:
11660 oappend (ins
, "WORD BCST ");
11663 ins
->vex
.no_broadcast
= true;
11673 oappend (ins
, "BYTE PTR ");
11678 oappend (ins
, "WORD PTR ");
11681 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
11683 oappend (ins
, "QWORD PTR ");
11686 /* Fall through. */
11688 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
11689 || (ins
->rex
& REX_W
)))
11691 oappend (ins
, "QWORD PTR ");
11694 /* Fall through. */
11699 if (ins
->rex
& REX_W
)
11700 oappend (ins
, "QWORD PTR ");
11701 else if (bytemode
== dq_mode
)
11702 oappend (ins
, "DWORD PTR ");
11705 if (sizeflag
& DFLAG
)
11706 oappend (ins
, "DWORD PTR ");
11708 oappend (ins
, "WORD PTR ");
11709 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11713 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
11714 *ins
->obufp
++ = 'D';
11715 oappend (ins
, "WORD PTR ");
11716 if (!(ins
->rex
& REX_W
))
11717 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11720 if (sizeflag
& DFLAG
)
11721 oappend (ins
, "QWORD PTR ");
11723 oappend (ins
, "DWORD PTR ");
11724 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11727 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
11728 oappend (ins
, "WORD PTR ");
11730 oappend (ins
, "DWORD PTR ");
11731 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11735 oappend (ins
, "DWORD PTR ");
11739 oappend (ins
, "QWORD PTR ");
11742 if (ins
->address_mode
== mode_64bit
)
11743 oappend (ins
, "QWORD PTR ");
11745 oappend (ins
, "DWORD PTR ");
11748 if (sizeflag
& DFLAG
)
11749 oappend (ins
, "FWORD PTR ");
11751 oappend (ins
, "DWORD PTR ");
11752 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11755 oappend (ins
, "TBYTE PTR ");
11760 case evex_x_gscat_mode
:
11761 case evex_x_nobcst_mode
:
11765 switch (ins
->vex
.length
)
11768 oappend (ins
, "XMMWORD PTR ");
11771 oappend (ins
, "YMMWORD PTR ");
11774 oappend (ins
, "ZMMWORD PTR ");
11781 oappend (ins
, "XMMWORD PTR ");
11784 oappend (ins
, "XMMWORD PTR ");
11787 oappend (ins
, "YMMWORD PTR ");
11790 case evex_half_bcst_xmmqh_mode
:
11791 case evex_half_bcst_xmmq_mode
:
11792 switch (ins
->vex
.length
)
11796 oappend (ins
, "QWORD PTR ");
11799 oappend (ins
, "XMMWORD PTR ");
11802 oappend (ins
, "YMMWORD PTR ");
11809 if (!ins
->need_vex
)
11812 switch (ins
->vex
.length
)
11815 oappend (ins
, "WORD PTR ");
11818 oappend (ins
, "DWORD PTR ");
11821 oappend (ins
, "QWORD PTR ");
11828 case evex_half_bcst_xmmqdh_mode
:
11829 if (!ins
->need_vex
)
11832 switch (ins
->vex
.length
)
11835 oappend (ins
, "DWORD PTR ");
11838 oappend (ins
, "QWORD PTR ");
11841 oappend (ins
, "XMMWORD PTR ");
11848 if (!ins
->need_vex
)
11851 switch (ins
->vex
.length
)
11854 oappend (ins
, "QWORD PTR ");
11857 oappend (ins
, "YMMWORD PTR ");
11860 oappend (ins
, "ZMMWORD PTR ");
11867 oappend (ins
, "OWORD PTR ");
11869 case vex_vsib_d_w_dq_mode
:
11870 case vex_vsib_q_w_dq_mode
:
11871 if (!ins
->need_vex
)
11874 oappend (ins
, "QWORD PTR ");
11876 oappend (ins
, "DWORD PTR ");
11879 if (!ins
->need_vex
|| ins
->vex
.length
!= 128)
11882 oappend (ins
, "DWORD PTR ");
11884 oappend (ins
, "BYTE PTR ");
11887 if (!ins
->need_vex
)
11890 oappend (ins
, "QWORD PTR ");
11892 oappend (ins
, "WORD PTR ");
11902 print_register (instr_info
*ins
, unsigned int reg
, unsigned int rexmask
,
11903 int bytemode
, int sizeflag
)
11905 const char (*names
)[8];
11907 /* Masking is invalid for insns with GPR destination. Set the flag uniformly,
11908 as the consumer will inspect it only for the destination operand. */
11909 if (bytemode
!= mask_mode
&& ins
->vex
.mask_register_specifier
)
11910 ins
->illegal_masking
= true;
11912 USED_REX (rexmask
);
11913 if (ins
->rex
& rexmask
)
11915 if (ins
->rex2
& rexmask
)
11924 if (ins
->rex
|| ins
->rex2
)
11925 names
= att_names8rex
;
11927 names
= att_names8
;
11930 names
= att_names16
;
11935 names
= att_names32
;
11938 names
= att_names64
;
11942 names
= ins
->address_mode
== mode_64bit
? att_names64
: att_names32
;
11945 case bnd_swap_mode
:
11948 oappend (ins
, "(bad)");
11951 names
= att_names_bnd
;
11954 if (ins
->address_mode
== mode_64bit
&& ins
->isa64
== intel64
)
11956 names
= att_names64
;
11959 /* Fall through. */
11961 if (ins
->address_mode
== mode_64bit
&& ((sizeflag
& DFLAG
)
11962 || (ins
->rex
& REX_W
)))
11964 names
= att_names64
;
11968 /* Fall through. */
11973 if (ins
->rex
& REX_W
)
11974 names
= att_names64
;
11975 else if (bytemode
!= v_mode
&& bytemode
!= v_swap_mode
)
11976 names
= att_names32
;
11979 if (sizeflag
& DFLAG
)
11980 names
= att_names32
;
11982 names
= att_names16
;
11983 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11987 if (!(sizeflag
& DFLAG
) && ins
->isa64
== intel64
)
11988 names
= att_names16
;
11990 names
= att_names32
;
11991 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
11994 names
= (ins
->address_mode
== mode_64bit
11995 ? att_names64
: att_names32
);
11996 if (!(ins
->prefixes
& PREFIX_ADDR
))
11997 names
= (ins
->address_mode
== mode_16bit
11998 ? att_names16
: names
);
12001 /* Remove "addr16/addr32". */
12002 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
12003 names
= (ins
->address_mode
!= mode_32bit
12004 ? att_names32
: att_names16
);
12005 ins
->used_prefixes
|= PREFIX_ADDR
;
12012 oappend (ins
, "(bad)");
12015 names
= att_names_mask
;
12020 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12023 oappend_register (ins
, names
[reg
]);
12027 get8s (instr_info
*ins
, bfd_vma
*res
)
12029 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
12031 *res
= ((bfd_vma
) *ins
->codep
++ ^ 0x80) - 0x80;
12036 get16 (instr_info
*ins
, bfd_vma
*res
)
12038 if (!fetch_code (ins
->info
, ins
->codep
+ 2))
12040 *res
= *ins
->codep
++;
12041 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
12046 get16s (instr_info
*ins
, bfd_vma
*res
)
12048 if (!get16 (ins
, res
))
12050 *res
= (*res
^ 0x8000) - 0x8000;
12055 get32 (instr_info
*ins
, bfd_vma
*res
)
12057 if (!fetch_code (ins
->info
, ins
->codep
+ 4))
12059 *res
= *ins
->codep
++;
12060 *res
|= (bfd_vma
) *ins
->codep
++ << 8;
12061 *res
|= (bfd_vma
) *ins
->codep
++ << 16;
12062 *res
|= (bfd_vma
) *ins
->codep
++ << 24;
12067 get32s (instr_info
*ins
, bfd_vma
*res
)
12069 if (!get32 (ins
, res
))
12072 *res
= (*res
^ ((bfd_vma
) 1 << 31)) - ((bfd_vma
) 1 << 31);
12078 get64 (instr_info
*ins
, uint64_t *res
)
12083 if (!fetch_code (ins
->info
, ins
->codep
+ 8))
12086 a
|= (unsigned int) *ins
->codep
++ << 8;
12087 a
|= (unsigned int) *ins
->codep
++ << 16;
12088 a
|= (unsigned int) *ins
->codep
++ << 24;
12090 b
|= (unsigned int) *ins
->codep
++ << 8;
12091 b
|= (unsigned int) *ins
->codep
++ << 16;
12092 b
|= (unsigned int) *ins
->codep
++ << 24;
12093 *res
= a
+ ((uint64_t) b
<< 32);
12098 set_op (instr_info
*ins
, bfd_vma op
, bool riprel
)
12100 ins
->op_index
[ins
->op_ad
] = ins
->op_ad
;
12101 if (ins
->address_mode
== mode_64bit
)
12102 ins
->op_address
[ins
->op_ad
] = op
;
12103 else /* Mask to get a 32-bit address. */
12104 ins
->op_address
[ins
->op_ad
] = op
& 0xffffffff;
12105 ins
->op_riprel
[ins
->op_ad
] = riprel
;
12109 BadOp (instr_info
*ins
)
12111 /* Throw away prefixes and 1st. opcode byte. */
12112 struct dis_private
*priv
= ins
->info
->private_data
;
12114 ins
->codep
= priv
->the_buffer
+ ins
->nr_prefixes
+ ins
->need_vex
+ 1;
12115 ins
->obufp
= stpcpy (ins
->obufp
, "(bad)");
12120 OP_Skip_MODRM (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
12121 int sizeflag ATTRIBUTE_UNUSED
)
12123 if (ins
->modrm
.mod
!= 3)
12124 return BadOp (ins
);
12126 /* Skip mod/rm byte. */
12129 ins
->has_skipped_modrm
= true;
12134 OP_E_memory (instr_info
*ins
, int bytemode
, int sizeflag
)
12136 int add
= (ins
->rex
& REX_B
) ? 8 : 0;
12140 add
+= (ins
->rex2
& REX_B
) ? 16 : 0;
12142 /* Handles EVEX other than APX EVEX-promoted instructions. */
12143 if (ins
->vex
.evex
&& ins
->evex_type
== evex_default
)
12146 /* Zeroing-masking is invalid for memory destinations. Set the flag
12147 uniformly, as the consumer will inspect it only for the destination
12149 if (ins
->vex
.zeroing
)
12150 ins
->illegal_masking
= true;
12164 if (ins
->address_mode
!= mode_64bit
)
12172 case vex_vsib_d_w_dq_mode
:
12173 case vex_vsib_q_w_dq_mode
:
12174 case evex_x_gscat_mode
:
12175 shift
= ins
->vex
.w
? 3 : 2;
12178 case evex_half_bcst_xmmqh_mode
:
12179 case evex_half_bcst_xmmqdh_mode
:
12182 shift
= ins
->vex
.w
? 2 : 1;
12185 /* Fall through. */
12187 case evex_half_bcst_xmmq_mode
:
12190 shift
= ins
->vex
.w
? 3 : 2;
12193 /* Fall through. */
12198 case evex_x_nobcst_mode
:
12200 switch (ins
->vex
.length
)
12214 /* Make necessary corrections to shift for modes that need it. */
12215 if (bytemode
== xmmq_mode
12216 || bytemode
== evex_half_bcst_xmmqh_mode
12217 || bytemode
== evex_half_bcst_xmmq_mode
12218 || (bytemode
== ymmq_mode
&& ins
->vex
.length
== 128))
12220 else if (bytemode
== xmmqd_mode
12221 || bytemode
== evex_half_bcst_xmmqdh_mode
)
12223 else if (bytemode
== xmmdw_mode
)
12237 shift
= ins
->vex
.w
? 1 : 0;
12247 if (ins
->intel_syntax
)
12248 intel_operand_size (ins
, bytemode
, sizeflag
);
12251 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
12253 /* 32/64 bit address mode */
12262 int addr32flag
= !((sizeflag
& AFLAG
)
12263 || bytemode
== v_bnd_mode
12264 || bytemode
== v_bndmk_mode
12265 || bytemode
== bnd_mode
12266 || bytemode
== bnd_swap_mode
);
12267 bool check_gather
= false;
12268 const char (*indexes
)[8] = NULL
;
12271 base
= ins
->modrm
.rm
;
12275 vindex
= ins
->sib
.index
;
12277 if (ins
->rex
& REX_X
)
12281 case vex_vsib_d_w_dq_mode
:
12282 case vex_vsib_q_w_dq_mode
:
12283 if (!ins
->need_vex
)
12287 /* S/G EVEX insns require EVEX.X4 not to be set. */
12288 if (ins
->rex2
& REX_X
)
12290 oappend (ins
, "(bad)");
12296 check_gather
= ins
->obufp
== ins
->op_out
[1];
12299 switch (ins
->vex
.length
)
12302 indexes
= att_names_xmm
;
12306 || bytemode
== vex_vsib_q_w_dq_mode
)
12307 indexes
= att_names_ymm
;
12309 indexes
= att_names_xmm
;
12313 || bytemode
== vex_vsib_q_w_dq_mode
)
12314 indexes
= att_names_zmm
;
12316 indexes
= att_names_ymm
;
12323 if (ins
->rex2
& REX_X
)
12327 indexes
= ins
->address_mode
== mode_64bit
&& !addr32flag
12328 ? att_names64
: att_names32
;
12331 scale
= ins
->sib
.scale
;
12332 base
= ins
->sib
.base
;
12337 /* Check for mandatory SIB. */
12338 if (bytemode
== vex_vsib_d_w_dq_mode
12339 || bytemode
== vex_vsib_q_w_dq_mode
12340 || bytemode
== vex_sibmem_mode
)
12342 oappend (ins
, "(bad)");
12346 rbase
= base
+ add
;
12348 switch (ins
->modrm
.mod
)
12354 if (ins
->address_mode
== mode_64bit
&& !ins
->has_sib
)
12356 if (!get32s (ins
, &disp
))
12358 if (riprel
&& bytemode
== v_bndmk_mode
)
12360 oappend (ins
, "(bad)");
12366 if (!get8s (ins
, &disp
))
12368 if (ins
->vex
.evex
&& shift
> 0)
12372 if (!get32s (ins
, &disp
))
12382 && ins
->address_mode
!= mode_16bit
)
12384 if (ins
->address_mode
== mode_64bit
)
12388 /* Without base nor index registers, zero-extend the
12389 lower 32-bit displacement to 64 bits. */
12390 disp
&= 0xffffffff;
12397 /* In 32-bit mode, we need index register to tell [offset]
12398 from [eiz*1 + offset]. */
12403 havedisp
= (havebase
12405 || (ins
->has_sib
&& (indexes
|| scale
!= 0)));
12407 if (!ins
->intel_syntax
)
12408 if (ins
->modrm
.mod
!= 0 || base
== 5)
12410 if (havedisp
|| riprel
)
12411 print_displacement (ins
, disp
);
12413 print_operand_value (ins
, disp
, dis_style_address_offset
);
12416 set_op (ins
, disp
, true);
12417 oappend_char (ins
, '(');
12418 oappend_with_style (ins
, !addr32flag
? "%rip" : "%eip",
12419 dis_style_register
);
12420 oappend_char (ins
, ')');
12424 if ((havebase
|| indexes
|| needindex
|| needaddr32
|| riprel
)
12425 && (ins
->address_mode
!= mode_64bit
12426 || ((bytemode
!= v_bnd_mode
)
12427 && (bytemode
!= v_bndmk_mode
)
12428 && (bytemode
!= bnd_mode
)
12429 && (bytemode
!= bnd_swap_mode
))))
12430 ins
->used_prefixes
|= PREFIX_ADDR
;
12432 if (havedisp
|| (ins
->intel_syntax
&& riprel
))
12434 oappend_char (ins
, ins
->open_char
);
12435 if (ins
->intel_syntax
&& riprel
)
12437 set_op (ins
, disp
, true);
12438 oappend_with_style (ins
, !addr32flag
? "rip" : "eip",
12439 dis_style_register
);
12444 (ins
->address_mode
== mode_64bit
&& !addr32flag
12445 ? att_names64
: att_names32
)[rbase
]);
12448 /* ESP/RSP won't allow index. If base isn't ESP/RSP,
12449 print index to tell base + index from base. */
12453 || (havebase
&& base
!= ESP_REG_NUM
))
12455 if (!ins
->intel_syntax
|| havebase
)
12456 oappend_char (ins
, ins
->separator_char
);
12459 if (ins
->address_mode
== mode_64bit
|| vindex
< 16)
12460 oappend_register (ins
, indexes
[vindex
]);
12462 oappend (ins
, "(bad)");
12465 oappend_register (ins
,
12466 ins
->address_mode
== mode_64bit
12471 oappend_char (ins
, ins
->scale_char
);
12472 oappend_char_with_style (ins
, '0' + (1 << scale
),
12473 dis_style_immediate
);
12476 if (ins
->intel_syntax
12477 && (disp
|| ins
->modrm
.mod
!= 0 || base
== 5))
12479 if (!havedisp
|| (bfd_signed_vma
) disp
>= 0)
12480 oappend_char (ins
, '+');
12482 print_displacement (ins
, disp
);
12484 print_operand_value (ins
, disp
, dis_style_address_offset
);
12487 oappend_char (ins
, ins
->close_char
);
12491 /* Both XMM/YMM/ZMM registers must be distinct. */
12492 int modrm_reg
= ins
->modrm
.reg
;
12494 if (ins
->rex
& REX_R
)
12496 if (ins
->rex2
& REX_R
)
12498 if (vindex
== modrm_reg
)
12499 oappend (ins
, "/(bad)");
12502 else if (ins
->intel_syntax
)
12504 if (ins
->modrm
.mod
!= 0 || base
== 5)
12506 if (!ins
->active_seg_prefix
)
12508 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12509 oappend (ins
, ":");
12511 print_operand_value (ins
, disp
, dis_style_text
);
12515 else if (bytemode
== v_bnd_mode
12516 || bytemode
== v_bndmk_mode
12517 || bytemode
== bnd_mode
12518 || bytemode
== bnd_swap_mode
12519 || bytemode
== vex_vsib_d_w_dq_mode
12520 || bytemode
== vex_vsib_q_w_dq_mode
)
12522 oappend (ins
, "(bad)");
12527 /* 16 bit address mode */
12530 ins
->used_prefixes
|= ins
->prefixes
& PREFIX_ADDR
;
12531 switch (ins
->modrm
.mod
)
12534 if (ins
->modrm
.rm
== 6)
12537 if (!get16s (ins
, &disp
))
12542 if (!get8s (ins
, &disp
))
12544 if (ins
->vex
.evex
&& shift
> 0)
12549 if (!ins
->intel_syntax
)
12550 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6)
12551 print_displacement (ins
, disp
);
12553 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 6)
12555 oappend_char (ins
, ins
->open_char
);
12556 oappend (ins
, ins
->intel_syntax
? intel_index16
[ins
->modrm
.rm
]
12557 : att_index16
[ins
->modrm
.rm
]);
12558 if (ins
->intel_syntax
12559 && (disp
|| ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
== 6))
12561 if ((bfd_signed_vma
) disp
>= 0)
12562 oappend_char (ins
, '+');
12563 print_displacement (ins
, disp
);
12566 oappend_char (ins
, ins
->close_char
);
12568 else if (ins
->intel_syntax
)
12570 if (!ins
->active_seg_prefix
)
12572 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
12573 oappend (ins
, ":");
12575 print_operand_value (ins
, disp
& 0xffff, dis_style_text
);
12578 if (ins
->vex
.b
&& ins
->evex_type
== evex_default
)
12580 ins
->evex_used
|= EVEX_b_used
;
12582 /* Broadcast can only ever be valid for memory sources. */
12583 if (ins
->obufp
== ins
->op_out
[0])
12584 ins
->vex
.no_broadcast
= true;
12586 if (!ins
->vex
.no_broadcast
12587 && (!ins
->intel_syntax
|| !(ins
->evex_used
& EVEX_len_used
)))
12589 if (bytemode
== xh_mode
)
12591 switch (ins
->vex
.length
)
12594 oappend (ins
, "{1to8}");
12597 oappend (ins
, "{1to16}");
12600 oappend (ins
, "{1to32}");
12606 else if (bytemode
== q_mode
12607 || bytemode
== ymmq_mode
)
12608 ins
->vex
.no_broadcast
= true;
12609 else if (ins
->vex
.w
12610 || bytemode
== evex_half_bcst_xmmqdh_mode
12611 || bytemode
== evex_half_bcst_xmmq_mode
)
12613 switch (ins
->vex
.length
)
12616 oappend (ins
, "{1to2}");
12619 oappend (ins
, "{1to4}");
12622 oappend (ins
, "{1to8}");
12628 else if (bytemode
== x_mode
12629 || bytemode
== evex_half_bcst_xmmqh_mode
)
12631 switch (ins
->vex
.length
)
12634 oappend (ins
, "{1to4}");
12637 oappend (ins
, "{1to8}");
12640 oappend (ins
, "{1to16}");
12647 ins
->vex
.no_broadcast
= true;
12649 if (ins
->vex
.no_broadcast
)
12650 oappend (ins
, "{bad}");
12657 OP_E (instr_info
*ins
, int bytemode
, int sizeflag
)
12659 /* Skip mod/rm byte. */
12661 if (!ins
->has_skipped_modrm
)
12664 ins
->has_skipped_modrm
= true;
12667 if (ins
->modrm
.mod
== 3)
12669 if ((sizeflag
& SUFFIX_ALWAYS
)
12670 && (bytemode
== b_swap_mode
12671 || bytemode
== bnd_swap_mode
12672 || bytemode
== v_swap_mode
))
12673 swap_operand (ins
);
12675 print_register (ins
, ins
->modrm
.rm
, REX_B
, bytemode
, sizeflag
);
12679 /* Masking is invalid for insns with GPR-like memory destination. Set the
12680 flag uniformly, as the consumer will inspect it only for the destination
12682 if (ins
->vex
.mask_register_specifier
)
12683 ins
->illegal_masking
= true;
12685 return OP_E_memory (ins
, bytemode
, sizeflag
);
12689 OP_indirE (instr_info
*ins
, int bytemode
, int sizeflag
)
12691 if (ins
->modrm
.mod
== 3 && bytemode
== f_mode
)
12692 /* bad lcall/ljmp */
12693 return BadOp (ins
);
12694 if (!ins
->intel_syntax
)
12695 oappend (ins
, "*");
12696 return OP_E (ins
, bytemode
, sizeflag
);
12700 OP_G (instr_info
*ins
, int bytemode
, int sizeflag
)
12702 print_register (ins
, ins
->modrm
.reg
, REX_R
, bytemode
, sizeflag
);
12707 OP_REG (instr_info
*ins
, int code
, int sizeflag
)
12714 case es_reg
: case ss_reg
: case cs_reg
:
12715 case ds_reg
: case fs_reg
: case gs_reg
:
12716 oappend_register (ins
, att_names_seg
[code
- es_reg
]);
12721 if (ins
->rex
& REX_B
)
12723 if (ins
->rex2
& REX_B
)
12728 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
12729 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
12730 s
= att_names16
[code
- ax_reg
+ add
];
12732 case ah_reg
: case ch_reg
: case dh_reg
: case bh_reg
:
12734 /* Fall through. */
12735 case al_reg
: case cl_reg
: case dl_reg
: case bl_reg
:
12737 s
= att_names8rex
[code
- al_reg
+ add
];
12739 s
= att_names8
[code
- al_reg
];
12741 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
12742 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
12743 if (ins
->address_mode
== mode_64bit
12744 && ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
12746 s
= att_names64
[code
- rAX_reg
+ add
];
12749 code
+= eAX_reg
- rAX_reg
;
12750 /* Fall through. */
12751 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
12752 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
12754 if (ins
->rex
& REX_W
)
12755 s
= att_names64
[code
- eAX_reg
+ add
];
12758 if (sizeflag
& DFLAG
)
12759 s
= att_names32
[code
- eAX_reg
+ add
];
12761 s
= att_names16
[code
- eAX_reg
+ add
];
12762 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12766 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12769 oappend_register (ins
, s
);
12774 OP_IMREG (instr_info
*ins
, int code
, int sizeflag
)
12781 if (!ins
->intel_syntax
)
12783 oappend (ins
, "(%dx)");
12786 s
= att_names16
[dx_reg
- ax_reg
];
12788 case al_reg
: case cl_reg
:
12789 s
= att_names8
[code
- al_reg
];
12793 if (ins
->rex
& REX_W
)
12798 /* Fall through. */
12799 case z_mode_ax_reg
:
12800 if ((ins
->rex
& REX_W
) || (sizeflag
& DFLAG
))
12804 if (!(ins
->rex
& REX_W
))
12805 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12808 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12811 oappend_register (ins
, s
);
12816 OP_I (instr_info
*ins
, int bytemode
, int sizeflag
)
12823 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
12825 op
= *ins
->codep
++;
12829 if (ins
->rex
& REX_W
)
12831 if (!get32s (ins
, &op
))
12836 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12837 if (sizeflag
& DFLAG
)
12840 if (!get32 (ins
, &op
))
12845 /* Fall through. */
12847 if (!get16 (ins
, &op
))
12853 if (ins
->intel_syntax
)
12854 oappend_with_style (ins
, "1", dis_style_immediate
);
12856 oappend_with_style (ins
, "$1", dis_style_immediate
);
12859 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12863 oappend_immediate (ins
, op
);
12868 OP_I64 (instr_info
*ins
, int bytemode
, int sizeflag
)
12872 if (bytemode
!= v_mode
|| ins
->address_mode
!= mode_64bit
12873 || !(ins
->rex
& REX_W
))
12874 return OP_I (ins
, bytemode
, sizeflag
);
12878 if (!get64 (ins
, &op
))
12881 oappend_immediate (ins
, op
);
12886 OP_sI (instr_info
*ins
, int bytemode
, int sizeflag
)
12894 if (!get8s (ins
, &op
))
12896 if (bytemode
== b_T_mode
)
12898 if (ins
->address_mode
!= mode_64bit
12899 || !((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
)))
12901 /* The operand-size prefix is overridden by a REX prefix. */
12902 if ((sizeflag
& DFLAG
) || (ins
->rex
& REX_W
))
12910 if (!(ins
->rex
& REX_W
))
12912 if (sizeflag
& DFLAG
)
12920 /* The operand-size prefix is overridden by a REX prefix. */
12921 if (!(sizeflag
& DFLAG
) && !(ins
->rex
& REX_W
))
12923 if (!get16 (ins
, &op
))
12926 else if (!get32s (ins
, &op
))
12930 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12934 oappend_immediate (ins
, op
);
12939 OP_J (instr_info
*ins
, int bytemode
, int sizeflag
)
12943 bfd_vma segment
= 0;
12948 if (!get8s (ins
, &disp
))
12953 if ((sizeflag
& DFLAG
)
12954 || (ins
->address_mode
== mode_64bit
12955 && ((ins
->isa64
== intel64
&& bytemode
!= dqw_mode
)
12956 || (ins
->rex
& REX_W
))))
12958 if (!get32s (ins
, &disp
))
12963 if (!get16s (ins
, &disp
))
12965 /* In 16bit mode, address is wrapped around at 64k within
12966 the same segment. Otherwise, a data16 prefix on a jump
12967 instruction means that the pc is masked to 16 bits after
12968 the displacement is added! */
12970 if ((ins
->prefixes
& PREFIX_DATA
) == 0)
12971 segment
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
))
12972 & ~((bfd_vma
) 0xffff));
12974 if (ins
->address_mode
!= mode_64bit
12975 || (ins
->isa64
!= intel64
&& !(ins
->rex
& REX_W
)))
12976 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
12979 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
12982 disp
= ((ins
->start_pc
+ (ins
->codep
- ins
->start_codep
) + disp
) & mask
)
12984 set_op (ins
, disp
, false);
12985 print_operand_value (ins
, disp
, dis_style_text
);
12990 OP_SEG (instr_info
*ins
, int bytemode
, int sizeflag
)
12992 if (bytemode
== w_mode
)
12994 oappend_register (ins
, att_names_seg
[ins
->modrm
.reg
]);
12997 return OP_E (ins
, ins
->modrm
.mod
== 3 ? bytemode
: w_mode
, sizeflag
);
13001 OP_DIR (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
13003 bfd_vma seg
, offset
;
13007 if (sizeflag
& DFLAG
)
13009 if (!get32 (ins
, &offset
))
13012 else if (!get16 (ins
, &offset
))
13014 if (!get16 (ins
, &seg
))
13016 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13018 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
13019 ins
->intel_syntax
? "0x%x:0x%x" : "$0x%x,$0x%x",
13020 (unsigned) seg
, (unsigned) offset
);
13021 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
13023 oappend (ins
, scratch
);
13028 OP_OFF (instr_info
*ins
, int bytemode
, int sizeflag
)
13032 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
13033 intel_operand_size (ins
, bytemode
, sizeflag
);
13036 if ((sizeflag
& AFLAG
) || ins
->address_mode
== mode_64bit
)
13038 if (!get32 (ins
, &off
))
13043 if (!get16 (ins
, &off
))
13047 if (ins
->intel_syntax
)
13049 if (!ins
->active_seg_prefix
)
13051 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
13052 oappend (ins
, ":");
13055 print_operand_value (ins
, off
, dis_style_address_offset
);
13060 OP_OFF64 (instr_info
*ins
, int bytemode
, int sizeflag
)
13064 if (ins
->address_mode
!= mode_64bit
13065 || (ins
->prefixes
& PREFIX_ADDR
))
13066 return OP_OFF (ins
, bytemode
, sizeflag
);
13068 if (ins
->intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
13069 intel_operand_size (ins
, bytemode
, sizeflag
);
13072 if (!get64 (ins
, &off
))
13075 if (ins
->intel_syntax
)
13077 if (!ins
->active_seg_prefix
)
13079 oappend_register (ins
, att_names_seg
[ds_reg
- es_reg
]);
13080 oappend (ins
, ":");
13083 print_operand_value (ins
, off
, dis_style_address_offset
);
13088 ptr_reg (instr_info
*ins
, int code
, int sizeflag
)
13092 *ins
->obufp
++ = ins
->open_char
;
13093 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_ADDR
);
13094 if (ins
->address_mode
== mode_64bit
)
13096 if (!(sizeflag
& AFLAG
))
13097 s
= att_names32
[code
- eAX_reg
];
13099 s
= att_names64
[code
- eAX_reg
];
13101 else if (sizeflag
& AFLAG
)
13102 s
= att_names32
[code
- eAX_reg
];
13104 s
= att_names16
[code
- eAX_reg
];
13105 oappend_register (ins
, s
);
13106 oappend_char (ins
, ins
->close_char
);
13110 OP_ESreg (instr_info
*ins
, int code
, int sizeflag
)
13112 if (ins
->intel_syntax
)
13114 switch (ins
->codep
[-1])
13116 case 0x6d: /* insw/insl */
13117 intel_operand_size (ins
, z_mode
, sizeflag
);
13119 case 0xa5: /* movsw/movsl/movsq */
13120 case 0xa7: /* cmpsw/cmpsl/cmpsq */
13121 case 0xab: /* stosw/stosl */
13122 case 0xaf: /* scasw/scasl */
13123 intel_operand_size (ins
, v_mode
, sizeflag
);
13126 intel_operand_size (ins
, b_mode
, sizeflag
);
13129 oappend_register (ins
, att_names_seg
[0]);
13130 oappend_char (ins
, ':');
13131 ptr_reg (ins
, code
, sizeflag
);
13136 OP_DSreg (instr_info
*ins
, int code
, int sizeflag
)
13138 if (ins
->intel_syntax
)
13140 switch (ins
->codep
[-1])
13142 case 0x6f: /* outsw/outsl */
13143 intel_operand_size (ins
, z_mode
, sizeflag
);
13145 case 0xa5: /* movsw/movsl/movsq */
13146 case 0xa7: /* cmpsw/cmpsl/cmpsq */
13147 case 0xad: /* lodsw/lodsl/lodsq */
13148 intel_operand_size (ins
, v_mode
, sizeflag
);
13151 intel_operand_size (ins
, b_mode
, sizeflag
);
13154 /* Set ins->active_seg_prefix to PREFIX_DS if it is unset so that the
13155 default segment register DS is printed. */
13156 if (!ins
->active_seg_prefix
)
13157 ins
->active_seg_prefix
= PREFIX_DS
;
13159 ptr_reg (ins
, code
, sizeflag
);
13164 OP_C (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
13165 int sizeflag ATTRIBUTE_UNUSED
)
13170 if (ins
->rex
& REX_R
)
13175 else if (ins
->address_mode
!= mode_64bit
&& (ins
->prefixes
& PREFIX_LOCK
))
13177 ins
->all_prefixes
[ins
->last_lock_prefix
] = 0;
13178 ins
->used_prefixes
|= PREFIX_LOCK
;
13183 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%cr%d",
13184 ins
->modrm
.reg
+ add
);
13185 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
13187 oappend_register (ins
, scratch
);
13192 OP_D (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
13193 int sizeflag ATTRIBUTE_UNUSED
)
13199 if (ins
->rex
& REX_R
)
13203 res
= snprintf (scratch
, ARRAY_SIZE (scratch
),
13204 ins
->intel_syntax
? "dr%d" : "%%db%d",
13205 ins
->modrm
.reg
+ add
);
13206 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
13208 oappend (ins
, scratch
);
13213 OP_T (instr_info
*ins
, int dummy ATTRIBUTE_UNUSED
,
13214 int sizeflag ATTRIBUTE_UNUSED
)
13219 res
= snprintf (scratch
, ARRAY_SIZE (scratch
), "%%tr%d", ins
->modrm
.reg
);
13220 if (res
< 0 || (size_t) res
>= ARRAY_SIZE (scratch
))
13222 oappend_register (ins
, scratch
);
13227 OP_MMX (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13228 int sizeflag ATTRIBUTE_UNUSED
)
13230 int reg
= ins
->modrm
.reg
;
13231 const char (*names
)[8];
13233 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13234 if (ins
->prefixes
& PREFIX_DATA
)
13236 names
= att_names_xmm
;
13238 if (ins
->rex
& REX_R
)
13242 names
= att_names_mm
;
13243 oappend_register (ins
, names
[reg
]);
13248 print_vector_reg (instr_info
*ins
, unsigned int reg
, int bytemode
)
13250 const char (*names
)[8];
13252 if (bytemode
== xmmq_mode
13253 || bytemode
== evex_half_bcst_xmmqh_mode
13254 || bytemode
== evex_half_bcst_xmmq_mode
)
13256 switch (ins
->vex
.length
)
13261 names
= att_names_xmm
;
13264 names
= att_names_ymm
;
13265 ins
->evex_used
|= EVEX_len_used
;
13271 else if (bytemode
== ymm_mode
)
13272 names
= att_names_ymm
;
13273 else if (bytemode
== tmm_mode
)
13277 oappend (ins
, "(bad)");
13280 names
= att_names_tmm
;
13282 else if (ins
->need_vex
13283 && bytemode
!= xmm_mode
13284 && bytemode
!= scalar_mode
13285 && bytemode
!= xmmdw_mode
13286 && bytemode
!= xmmqd_mode
13287 && bytemode
!= evex_half_bcst_xmmqdh_mode
13288 && bytemode
!= w_swap_mode
13289 && bytemode
!= b_mode
13290 && bytemode
!= w_mode
13291 && bytemode
!= d_mode
13292 && bytemode
!= q_mode
)
13294 ins
->evex_used
|= EVEX_len_used
;
13295 switch (ins
->vex
.length
)
13298 names
= att_names_xmm
;
13302 || bytemode
!= vex_vsib_q_w_dq_mode
)
13303 names
= att_names_ymm
;
13305 names
= att_names_xmm
;
13309 || bytemode
!= vex_vsib_q_w_dq_mode
)
13310 names
= att_names_zmm
;
13312 names
= att_names_ymm
;
13319 names
= att_names_xmm
;
13320 oappend_register (ins
, names
[reg
]);
13324 OP_XMM (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13326 unsigned int reg
= ins
->modrm
.reg
;
13329 if (ins
->rex
& REX_R
)
13333 if (ins
->rex2
& REX_R
)
13337 if (bytemode
== tmm_mode
)
13338 ins
->modrm
.reg
= reg
;
13339 else if (bytemode
== scalar_mode
)
13340 ins
->vex
.no_broadcast
= true;
13342 print_vector_reg (ins
, reg
, bytemode
);
13347 OP_EM (instr_info
*ins
, int bytemode
, int sizeflag
)
13350 const char (*names
)[8];
13352 if (ins
->modrm
.mod
!= 3)
13354 if (ins
->intel_syntax
13355 && (bytemode
== v_mode
|| bytemode
== v_swap_mode
))
13357 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
13358 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13360 return OP_E (ins
, bytemode
, sizeflag
);
13363 if ((sizeflag
& SUFFIX_ALWAYS
) && bytemode
== v_swap_mode
)
13364 swap_operand (ins
);
13366 /* Skip mod/rm byte. */
13369 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13370 reg
= ins
->modrm
.rm
;
13371 if (ins
->prefixes
& PREFIX_DATA
)
13373 names
= att_names_xmm
;
13375 if (ins
->rex
& REX_B
)
13379 names
= att_names_mm
;
13380 oappend_register (ins
, names
[reg
]);
13384 /* cvt* are the only instructions in sse2 which have
13385 both SSE and MMX operands and also have 0x66 prefix
13386 in their opcode. 0x66 was originally used to differentiate
13387 between SSE and MMX instruction(operands). So we have to handle the
13388 cvt* separately using OP_EMC and OP_MXC */
13390 OP_EMC (instr_info
*ins
, int bytemode
, int sizeflag
)
13392 if (ins
->modrm
.mod
!= 3)
13394 if (ins
->intel_syntax
&& bytemode
== v_mode
)
13396 bytemode
= (ins
->prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
13397 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13399 return OP_E (ins
, bytemode
, sizeflag
);
13402 /* Skip mod/rm byte. */
13405 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13406 oappend_register (ins
, att_names_mm
[ins
->modrm
.rm
]);
13411 OP_MXC (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13412 int sizeflag ATTRIBUTE_UNUSED
)
13414 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
13415 oappend_register (ins
, att_names_mm
[ins
->modrm
.reg
]);
13420 OP_EX (instr_info
*ins
, int bytemode
, int sizeflag
)
13424 /* Skip mod/rm byte. */
13428 if (bytemode
== dq_mode
)
13429 bytemode
= ins
->vex
.w
? q_mode
: d_mode
;
13431 if (ins
->modrm
.mod
!= 3)
13432 return OP_E_memory (ins
, bytemode
, sizeflag
);
13434 reg
= ins
->modrm
.rm
;
13436 if (ins
->rex
& REX_B
)
13441 if ((ins
->rex
& REX_X
))
13443 ins
->rex2_used
&= ~REX_B
;
13445 else if (ins
->rex2
& REX_B
)
13448 if ((sizeflag
& SUFFIX_ALWAYS
)
13449 && (bytemode
== x_swap_mode
13450 || bytemode
== w_swap_mode
13451 || bytemode
== d_swap_mode
13452 || bytemode
== q_swap_mode
))
13453 swap_operand (ins
);
13455 if (bytemode
== tmm_mode
)
13456 ins
->modrm
.rm
= reg
;
13458 print_vector_reg (ins
, reg
, bytemode
);
13463 OP_R (instr_info
*ins
, int bytemode
, int sizeflag
)
13465 if (ins
->modrm
.mod
!= 3)
13466 return BadOp (ins
);
13474 return OP_E (ins
, bytemode
, sizeflag
);
13476 return OP_EM (ins
, x_mode
, sizeflag
);
13478 if (ins
->vex
.length
<= 128)
13480 return BadOp (ins
);
13483 return OP_EX (ins
, bytemode
, sizeflag
);
13487 OP_M (instr_info
*ins
, int bytemode
, int sizeflag
)
13489 /* Skip mod/rm byte. */
13493 if (ins
->modrm
.mod
== 3)
13494 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
13495 return BadOp (ins
);
13497 if (bytemode
== x_mode
)
13498 ins
->vex
.no_broadcast
= true;
13500 return OP_E_memory (ins
, bytemode
, sizeflag
);
13504 OP_0f07 (instr_info
*ins
, int bytemode
, int sizeflag
)
13506 if (ins
->modrm
.mod
!= 3 || ins
->modrm
.rm
!= 0)
13507 return BadOp (ins
);
13508 return OP_E (ins
, bytemode
, sizeflag
);
13511 /* montmul instruction need display repz and skip modrm */
13514 MONTMUL_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
13516 if (ins
->modrm
.mod
!= 3 || ins
->modrm
.rm
!= 0)
13517 return BadOp (ins
);
13519 /* The 0xf3 prefix should be displayed as "repz" for montmul. */
13520 if (ins
->prefixes
& PREFIX_REPZ
)
13521 ins
->all_prefixes
[ins
->last_repz_prefix
] = 0xf3;
13523 /* Skip mod/rm byte. */
13529 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
13530 32bit mode and "xchg %rax,%rax" in 64bit mode. */
13533 NOP_Fixup (instr_info
*ins
, int opnd
, int sizeflag
)
13535 if ((ins
->prefixes
& PREFIX_DATA
) == 0 && (ins
->rex
& REX_B
) == 0)
13537 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop");
13541 return OP_REG (ins
, eAX_reg
, sizeflag
);
13542 return OP_IMREG (ins
, eAX_reg
, sizeflag
);
13545 static const char *const Suffix3DNow
[] = {
13546 /* 00 */ NULL
, NULL
, NULL
, NULL
,
13547 /* 04 */ NULL
, NULL
, NULL
, NULL
,
13548 /* 08 */ NULL
, NULL
, NULL
, NULL
,
13549 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
13550 /* 10 */ NULL
, NULL
, NULL
, NULL
,
13551 /* 14 */ NULL
, NULL
, NULL
, NULL
,
13552 /* 18 */ NULL
, NULL
, NULL
, NULL
,
13553 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
13554 /* 20 */ NULL
, NULL
, NULL
, NULL
,
13555 /* 24 */ NULL
, NULL
, NULL
, NULL
,
13556 /* 28 */ NULL
, NULL
, NULL
, NULL
,
13557 /* 2C */ NULL
, NULL
, NULL
, NULL
,
13558 /* 30 */ NULL
, NULL
, NULL
, NULL
,
13559 /* 34 */ NULL
, NULL
, NULL
, NULL
,
13560 /* 38 */ NULL
, NULL
, NULL
, NULL
,
13561 /* 3C */ NULL
, NULL
, NULL
, NULL
,
13562 /* 40 */ NULL
, NULL
, NULL
, NULL
,
13563 /* 44 */ NULL
, NULL
, NULL
, NULL
,
13564 /* 48 */ NULL
, NULL
, NULL
, NULL
,
13565 /* 4C */ NULL
, NULL
, NULL
, NULL
,
13566 /* 50 */ NULL
, NULL
, NULL
, NULL
,
13567 /* 54 */ NULL
, NULL
, NULL
, NULL
,
13568 /* 58 */ NULL
, NULL
, NULL
, NULL
,
13569 /* 5C */ NULL
, NULL
, NULL
, NULL
,
13570 /* 60 */ NULL
, NULL
, NULL
, NULL
,
13571 /* 64 */ NULL
, NULL
, NULL
, NULL
,
13572 /* 68 */ NULL
, NULL
, NULL
, NULL
,
13573 /* 6C */ NULL
, NULL
, NULL
, NULL
,
13574 /* 70 */ NULL
, NULL
, NULL
, NULL
,
13575 /* 74 */ NULL
, NULL
, NULL
, NULL
,
13576 /* 78 */ NULL
, NULL
, NULL
, NULL
,
13577 /* 7C */ NULL
, NULL
, NULL
, NULL
,
13578 /* 80 */ NULL
, NULL
, NULL
, NULL
,
13579 /* 84 */ NULL
, NULL
, NULL
, NULL
,
13580 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
13581 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
13582 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
13583 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
13584 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
13585 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
13586 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
13587 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
13588 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
13589 /* AC */ NULL
, NULL
, "pfacc", NULL
,
13590 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
13591 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pmulhrw",
13592 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
13593 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
13594 /* C0 */ NULL
, NULL
, NULL
, NULL
,
13595 /* C4 */ NULL
, NULL
, NULL
, NULL
,
13596 /* C8 */ NULL
, NULL
, NULL
, NULL
,
13597 /* CC */ NULL
, NULL
, NULL
, NULL
,
13598 /* D0 */ NULL
, NULL
, NULL
, NULL
,
13599 /* D4 */ NULL
, NULL
, NULL
, NULL
,
13600 /* D8 */ NULL
, NULL
, NULL
, NULL
,
13601 /* DC */ NULL
, NULL
, NULL
, NULL
,
13602 /* E0 */ NULL
, NULL
, NULL
, NULL
,
13603 /* E4 */ NULL
, NULL
, NULL
, NULL
,
13604 /* E8 */ NULL
, NULL
, NULL
, NULL
,
13605 /* EC */ NULL
, NULL
, NULL
, NULL
,
13606 /* F0 */ NULL
, NULL
, NULL
, NULL
,
13607 /* F4 */ NULL
, NULL
, NULL
, NULL
,
13608 /* F8 */ NULL
, NULL
, NULL
, NULL
,
13609 /* FC */ NULL
, NULL
, NULL
, NULL
,
13613 OP_3DNowSuffix (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13614 int sizeflag ATTRIBUTE_UNUSED
)
13616 const char *mnemonic
;
13618 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13620 /* AMD 3DNow! instructions are specified by an opcode suffix in the
13621 place where an 8-bit immediate would normally go. ie. the last
13622 byte of the instruction. */
13623 ins
->obufp
= ins
->mnemonicendp
;
13624 mnemonic
= Suffix3DNow
[*ins
->codep
++];
13626 ins
->obufp
= stpcpy (ins
->obufp
, mnemonic
);
13629 /* Since a variable sized ins->modrm/ins->sib chunk is between the start
13630 of the opcode (0x0f0f) and the opcode suffix, we need to do
13631 all the ins->modrm processing first, and don't know until now that
13632 we have a bad opcode. This necessitates some cleaning up. */
13633 ins
->op_out
[0][0] = '\0';
13634 ins
->op_out
[1][0] = '\0';
13637 ins
->mnemonicendp
= ins
->obufp
;
13641 static const struct op simd_cmp_op
[] =
13643 { STRING_COMMA_LEN ("eq") },
13644 { STRING_COMMA_LEN ("lt") },
13645 { STRING_COMMA_LEN ("le") },
13646 { STRING_COMMA_LEN ("unord") },
13647 { STRING_COMMA_LEN ("neq") },
13648 { STRING_COMMA_LEN ("nlt") },
13649 { STRING_COMMA_LEN ("nle") },
13650 { STRING_COMMA_LEN ("ord") }
13653 static const struct op vex_cmp_op
[] =
13655 { STRING_COMMA_LEN ("eq_uq") },
13656 { STRING_COMMA_LEN ("nge") },
13657 { STRING_COMMA_LEN ("ngt") },
13658 { STRING_COMMA_LEN ("false") },
13659 { STRING_COMMA_LEN ("neq_oq") },
13660 { STRING_COMMA_LEN ("ge") },
13661 { STRING_COMMA_LEN ("gt") },
13662 { STRING_COMMA_LEN ("true") },
13663 { STRING_COMMA_LEN ("eq_os") },
13664 { STRING_COMMA_LEN ("lt_oq") },
13665 { STRING_COMMA_LEN ("le_oq") },
13666 { STRING_COMMA_LEN ("unord_s") },
13667 { STRING_COMMA_LEN ("neq_us") },
13668 { STRING_COMMA_LEN ("nlt_uq") },
13669 { STRING_COMMA_LEN ("nle_uq") },
13670 { STRING_COMMA_LEN ("ord_s") },
13671 { STRING_COMMA_LEN ("eq_us") },
13672 { STRING_COMMA_LEN ("nge_uq") },
13673 { STRING_COMMA_LEN ("ngt_uq") },
13674 { STRING_COMMA_LEN ("false_os") },
13675 { STRING_COMMA_LEN ("neq_os") },
13676 { STRING_COMMA_LEN ("ge_oq") },
13677 { STRING_COMMA_LEN ("gt_oq") },
13678 { STRING_COMMA_LEN ("true_us") },
13682 CMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13683 int sizeflag ATTRIBUTE_UNUSED
)
13685 unsigned int cmp_type
;
13687 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
13689 cmp_type
= *ins
->codep
++;
13690 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
))
13693 char *p
= ins
->mnemonicendp
- 2;
13697 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
13698 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
13700 else if (ins
->need_vex
13701 && cmp_type
< ARRAY_SIZE (simd_cmp_op
) + ARRAY_SIZE (vex_cmp_op
))
13704 char *p
= ins
->mnemonicendp
- 2;
13708 cmp_type
-= ARRAY_SIZE (simd_cmp_op
);
13709 sprintf (p
, "%s%s", vex_cmp_op
[cmp_type
].name
, suffix
);
13710 ins
->mnemonicendp
+= vex_cmp_op
[cmp_type
].len
;
13714 /* We have a reserved extension byte. Output it directly. */
13715 oappend_immediate (ins
, cmp_type
);
13721 OP_Mwait (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13723 /* mwait %eax,%ecx / mwaitx %eax,%ecx,%ebx */
13724 if (!ins
->intel_syntax
)
13726 strcpy (ins
->op_out
[0], att_names32
[0] + ins
->intel_syntax
);
13727 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
13728 if (bytemode
== eBX_reg
)
13729 strcpy (ins
->op_out
[2], att_names32
[3] + ins
->intel_syntax
);
13730 ins
->two_source_ops
= true;
13732 /* Skip mod/rm byte. */
13739 OP_Monitor (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13740 int sizeflag ATTRIBUTE_UNUSED
)
13742 /* monitor %{e,r,}ax,%ecx,%edx" */
13743 if (!ins
->intel_syntax
)
13745 const char (*names
)[8] = (ins
->address_mode
== mode_64bit
13746 ? att_names64
: att_names32
);
13748 if (ins
->prefixes
& PREFIX_ADDR
)
13750 /* Remove "addr16/addr32". */
13751 ins
->all_prefixes
[ins
->last_addr_prefix
] = 0;
13752 names
= (ins
->address_mode
!= mode_32bit
13753 ? att_names32
: att_names16
);
13754 ins
->used_prefixes
|= PREFIX_ADDR
;
13756 else if (ins
->address_mode
== mode_16bit
)
13757 names
= att_names16
;
13758 strcpy (ins
->op_out
[0], names
[0] + ins
->intel_syntax
);
13759 strcpy (ins
->op_out
[1], att_names32
[1] + ins
->intel_syntax
);
13760 strcpy (ins
->op_out
[2], att_names32
[2] + ins
->intel_syntax
);
13761 ins
->two_source_ops
= true;
13763 /* Skip mod/rm byte. */
13770 REP_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13772 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
13774 if (ins
->prefixes
& PREFIX_REPZ
)
13775 ins
->all_prefixes
[ins
->last_repz_prefix
] = REP_PREFIX
;
13782 return OP_IMREG (ins
, bytemode
, sizeflag
);
13784 return OP_ESreg (ins
, bytemode
, sizeflag
);
13786 return OP_DSreg (ins
, bytemode
, sizeflag
);
13795 SEP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13796 int sizeflag ATTRIBUTE_UNUSED
)
13798 if (ins
->isa64
!= amd64
)
13801 ins
->obufp
= ins
->obuf
;
13803 ins
->mnemonicendp
= ins
->obufp
;
13808 /* For BND-prefixed instructions 0xF2 prefix should be displayed as
13812 BND_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13813 int sizeflag ATTRIBUTE_UNUSED
)
13815 if (ins
->prefixes
& PREFIX_REPNZ
)
13816 ins
->all_prefixes
[ins
->last_repnz_prefix
] = BND_PREFIX
;
13820 /* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
13824 NOTRACK_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
13825 int sizeflag ATTRIBUTE_UNUSED
)
13827 /* Since active_seg_prefix is not set in 64-bit mode, check whether
13828 we've seen a PREFIX_DS. */
13829 if ((ins
->prefixes
& PREFIX_DS
) != 0
13830 && (ins
->address_mode
!= mode_64bit
|| ins
->last_data_prefix
< 0))
13832 /* NOTRACK prefix is only valid on indirect branch instructions.
13833 NB: DATA prefix is unsupported for Intel64. */
13834 ins
->active_seg_prefix
= 0;
13835 ins
->all_prefixes
[ins
->last_seg_prefix
] = NOTRACK_PREFIX
;
13840 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
13841 "xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
13845 HLE_Fixup1 (instr_info
*ins
, int bytemode
, int sizeflag
)
13847 if (ins
->modrm
.mod
!= 3
13848 && (ins
->prefixes
& PREFIX_LOCK
) != 0)
13850 if (ins
->prefixes
& PREFIX_REPZ
)
13851 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13852 if (ins
->prefixes
& PREFIX_REPNZ
)
13853 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13856 return OP_E (ins
, bytemode
, sizeflag
);
13859 /* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
13860 "xacquire"/"xrelease" for memory operand. No check for LOCK prefix.
13864 HLE_Fixup2 (instr_info
*ins
, int bytemode
, int sizeflag
)
13866 if (ins
->modrm
.mod
!= 3)
13868 if (ins
->prefixes
& PREFIX_REPZ
)
13869 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13870 if (ins
->prefixes
& PREFIX_REPNZ
)
13871 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13874 return OP_E (ins
, bytemode
, sizeflag
);
13877 /* Similar to OP_E. But the 0xf3 prefixes should be displayed as
13878 "xrelease" for memory operand. No check for LOCK prefix. */
13881 HLE_Fixup3 (instr_info
*ins
, int bytemode
, int sizeflag
)
13883 if (ins
->modrm
.mod
!= 3
13884 && ins
->last_repz_prefix
> ins
->last_repnz_prefix
13885 && (ins
->prefixes
& PREFIX_REPZ
) != 0)
13886 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13888 return OP_E (ins
, bytemode
, sizeflag
);
13892 CMPXCHG8B_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13895 if (ins
->rex
& REX_W
)
13897 /* Change cmpxchg8b to cmpxchg16b. */
13898 char *p
= ins
->mnemonicendp
- 2;
13899 ins
->mnemonicendp
= stpcpy (p
, "16b");
13902 else if ((ins
->prefixes
& PREFIX_LOCK
) != 0)
13904 if (ins
->prefixes
& PREFIX_REPZ
)
13905 ins
->all_prefixes
[ins
->last_repz_prefix
] = XRELEASE_PREFIX
;
13906 if (ins
->prefixes
& PREFIX_REPNZ
)
13907 ins
->all_prefixes
[ins
->last_repnz_prefix
] = XACQUIRE_PREFIX
;
13910 return OP_M (ins
, bytemode
, sizeflag
);
13914 XMM_Fixup (instr_info
*ins
, int reg
, int sizeflag ATTRIBUTE_UNUSED
)
13916 const char (*names
)[8] = att_names_xmm
;
13920 switch (ins
->vex
.length
)
13925 names
= att_names_ymm
;
13931 oappend_register (ins
, names
[reg
]);
13936 FXSAVE_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
13938 /* Add proper suffix to "fxsave" and "fxrstor". */
13940 if (ins
->rex
& REX_W
)
13942 char *p
= ins
->mnemonicendp
;
13946 ins
->mnemonicendp
= p
;
13948 return OP_M (ins
, bytemode
, sizeflag
);
13951 /* Display the destination register operand for instructions with
13955 OP_VEX (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
13957 int reg
, modrm_reg
, sib_index
= -1;
13958 const char (*names
)[8];
13960 if (!ins
->need_vex
)
13963 if (ins
->evex_type
== evex_from_legacy
)
13965 ins
->evex_used
|= EVEX_b_used
;
13970 reg
= ins
->vex
.register_specifier
;
13971 ins
->vex
.register_specifier
= 0;
13972 if (ins
->address_mode
!= mode_64bit
)
13974 if (ins
->vex
.evex
&& !ins
->vex
.v
)
13976 oappend (ins
, "(bad)");
13982 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
13988 oappend_register (ins
, att_names_xmm
[reg
]);
13991 case vex_vsib_d_w_dq_mode
:
13992 case vex_vsib_q_w_dq_mode
:
13993 /* This must be the 3rd operand. */
13994 if (ins
->obufp
!= ins
->op_out
[2])
13996 if (ins
->vex
.length
== 128
13997 || (bytemode
!= vex_vsib_d_w_dq_mode
13999 oappend_register (ins
, att_names_xmm
[reg
]);
14001 oappend_register (ins
, att_names_ymm
[reg
]);
14003 /* All 3 XMM/YMM registers must be distinct. */
14004 modrm_reg
= ins
->modrm
.reg
;
14005 if (ins
->rex
& REX_R
)
14008 if (ins
->has_sib
&& ins
->modrm
.rm
== 4)
14010 sib_index
= ins
->sib
.index
;
14011 if (ins
->rex
& REX_X
)
14015 if (reg
== modrm_reg
|| reg
== sib_index
)
14016 strcpy (ins
->obufp
, "/(bad)");
14017 if (modrm_reg
== sib_index
|| modrm_reg
== reg
)
14018 strcat (ins
->op_out
[0], "/(bad)");
14019 if (sib_index
== modrm_reg
|| sib_index
== reg
)
14020 strcat (ins
->op_out
[1], "/(bad)");
14025 /* All 3 TMM registers must be distinct. */
14027 oappend (ins
, "(bad)");
14030 /* This must be the 3rd operand. */
14031 if (ins
->obufp
!= ins
->op_out
[2])
14033 oappend_register (ins
, att_names_tmm
[reg
]);
14034 if (reg
== ins
->modrm
.reg
|| reg
== ins
->modrm
.rm
)
14035 strcpy (ins
->obufp
, "/(bad)");
14038 if (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
14039 || ins
->modrm
.rm
== reg
)
14041 if (ins
->modrm
.reg
<= 8
14042 && (ins
->modrm
.reg
== ins
->modrm
.rm
|| ins
->modrm
.reg
== reg
))
14043 strcat (ins
->op_out
[0], "/(bad)");
14044 if (ins
->modrm
.rm
<= 8
14045 && (ins
->modrm
.rm
== ins
->modrm
.reg
|| ins
->modrm
.rm
== reg
))
14046 strcat (ins
->op_out
[1], "/(bad)");
14053 if (ins
->rex
& REX_W
)
14054 oappend_register (ins
, att_names64
[reg
]);
14055 else if (bytemode
== v_mode
14056 && !(sizeflag
& DFLAG
))
14057 oappend_register (ins
, att_names16
[reg
]);
14059 oappend_register (ins
, att_names32
[reg
]);
14063 oappend_register (ins
, att_names8rex
[reg
]);
14067 oappend_register (ins
, att_names64
[reg
]);
14071 switch (ins
->vex
.length
)
14077 names
= att_names_xmm
;
14078 ins
->evex_used
|= EVEX_len_used
;
14084 oappend (ins
, "(bad)");
14087 names
= att_names_mask
;
14098 names
= att_names_ymm
;
14099 ins
->evex_used
|= EVEX_len_used
;
14105 names
= att_names_mask
;
14108 /* Fall through. */
14110 /* See PR binutils/20893 for a reproducer. */
14111 oappend (ins
, "(bad)");
14116 names
= att_names_zmm
;
14117 ins
->evex_used
|= EVEX_len_used
;
14123 oappend_register (ins
, names
[reg
]);
14128 OP_VexR (instr_info
*ins
, int bytemode
, int sizeflag
)
14130 if (ins
->modrm
.mod
== 3)
14131 return OP_VEX (ins
, bytemode
, sizeflag
);
14136 OP_VexW (instr_info
*ins
, int bytemode
, int sizeflag
)
14138 OP_VEX (ins
, bytemode
, sizeflag
);
14142 /* Swap 2nd and 3rd operands. */
14143 char *tmp
= ins
->op_out
[2];
14145 ins
->op_out
[2] = ins
->op_out
[1];
14146 ins
->op_out
[1] = tmp
;
14152 OP_REG_VexI4 (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
14155 const char (*names
)[8] = att_names_xmm
;
14157 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
14159 reg
= *ins
->codep
++;
14161 if (bytemode
!= x_mode
&& bytemode
!= scalar_mode
)
14165 if (ins
->address_mode
!= mode_64bit
)
14168 if (bytemode
== x_mode
&& ins
->vex
.length
== 256)
14169 names
= att_names_ymm
;
14171 oappend_register (ins
, names
[reg
]);
14175 /* Swap 3rd and 4th operands. */
14176 char *tmp
= ins
->op_out
[3];
14178 ins
->op_out
[3] = ins
->op_out
[2];
14179 ins
->op_out
[2] = tmp
;
14185 OP_VexI4 (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
14186 int sizeflag ATTRIBUTE_UNUSED
)
14188 oappend_immediate (ins
, ins
->codep
[-1] & 0xf);
14193 VPCMP_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
14194 int sizeflag ATTRIBUTE_UNUSED
)
14196 unsigned int cmp_type
;
14198 if (!ins
->vex
.evex
)
14201 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
14203 cmp_type
= *ins
->codep
++;
14204 /* There are aliases for immediates 0, 1, 2, 4, 5, 6.
14205 If it's the case, print suffix, otherwise - print the immediate. */
14206 if (cmp_type
< ARRAY_SIZE (simd_cmp_op
)
14211 char *p
= ins
->mnemonicendp
- 2;
14213 /* vpcmp* can have both one- and two-lettered suffix. */
14227 sprintf (p
, "%s%s", simd_cmp_op
[cmp_type
].name
, suffix
);
14228 ins
->mnemonicendp
+= simd_cmp_op
[cmp_type
].len
;
14232 /* We have a reserved extension byte. Output it directly. */
14233 oappend_immediate (ins
, cmp_type
);
14238 static const struct op xop_cmp_op
[] =
14240 { STRING_COMMA_LEN ("lt") },
14241 { STRING_COMMA_LEN ("le") },
14242 { STRING_COMMA_LEN ("gt") },
14243 { STRING_COMMA_LEN ("ge") },
14244 { STRING_COMMA_LEN ("eq") },
14245 { STRING_COMMA_LEN ("neq") },
14246 { STRING_COMMA_LEN ("false") },
14247 { STRING_COMMA_LEN ("true") }
14251 VPCOM_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
14252 int sizeflag ATTRIBUTE_UNUSED
)
14254 unsigned int cmp_type
;
14256 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
14258 cmp_type
= *ins
->codep
++;
14259 if (cmp_type
< ARRAY_SIZE (xop_cmp_op
))
14262 char *p
= ins
->mnemonicendp
- 2;
14264 /* vpcom* can have both one- and two-lettered suffix. */
14278 sprintf (p
, "%s%s", xop_cmp_op
[cmp_type
].name
, suffix
);
14279 ins
->mnemonicendp
+= xop_cmp_op
[cmp_type
].len
;
14283 /* We have a reserved extension byte. Output it directly. */
14284 oappend_immediate (ins
, cmp_type
);
14289 static const struct op pclmul_op
[] =
14291 { STRING_COMMA_LEN ("lql") },
14292 { STRING_COMMA_LEN ("hql") },
14293 { STRING_COMMA_LEN ("lqh") },
14294 { STRING_COMMA_LEN ("hqh") }
14298 PCLMUL_Fixup (instr_info
*ins
, int bytemode ATTRIBUTE_UNUSED
,
14299 int sizeflag ATTRIBUTE_UNUSED
)
14301 unsigned int pclmul_type
;
14303 if (!fetch_code (ins
->info
, ins
->codep
+ 1))
14305 pclmul_type
= *ins
->codep
++;
14306 switch (pclmul_type
)
14317 if (pclmul_type
< ARRAY_SIZE (pclmul_op
))
14320 char *p
= ins
->mnemonicendp
- 3;
14325 sprintf (p
, "%s%s", pclmul_op
[pclmul_type
].name
, suffix
);
14326 ins
->mnemonicendp
+= pclmul_op
[pclmul_type
].len
;
14330 /* We have a reserved extension byte. Output it directly. */
14331 oappend_immediate (ins
, pclmul_type
);
14337 MOVSXD_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14339 /* Add proper suffix to "movsxd". */
14340 char *p
= ins
->mnemonicendp
;
14345 if (!ins
->intel_syntax
)
14348 if (ins
->rex
& REX_W
)
14360 oappend (ins
, INTERNAL_DISASSEMBLER_ERROR
);
14364 ins
->mnemonicendp
= p
;
14366 return OP_E (ins
, bytemode
, sizeflag
);
14370 DistinctDest_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14372 unsigned int reg
= ins
->vex
.register_specifier
;
14373 unsigned int modrm_reg
= ins
->modrm
.reg
;
14374 unsigned int modrm_rm
= ins
->modrm
.rm
;
14376 /* Calc destination register number. */
14377 if (ins
->rex
& REX_R
)
14379 if (ins
->rex2
& REX_R
)
14382 /* Calc src1 register number. */
14383 if (ins
->address_mode
!= mode_64bit
)
14385 else if (ins
->vex
.evex
&& !ins
->vex
.v
)
14388 /* Calc src2 register number. */
14389 if (ins
->modrm
.mod
== 3)
14391 if (ins
->rex
& REX_B
)
14393 if (ins
->rex
& REX_X
)
14397 /* Destination and source registers must be distinct, output bad if
14398 dest == src1 or dest == src2. */
14399 if (modrm_reg
== reg
14400 || (ins
->modrm
.mod
== 3
14401 && modrm_reg
== modrm_rm
))
14403 oappend (ins
, "(bad)");
14406 return OP_XMM (ins
, bytemode
, sizeflag
);
14410 OP_Rounding (instr_info
*ins
, int bytemode
, int sizeflag ATTRIBUTE_UNUSED
)
14412 if (ins
->modrm
.mod
!= 3 || !ins
->vex
.b
)
14415 ins
->evex_used
|= EVEX_b_used
;
14418 case evex_rounding_64_mode
:
14419 if (ins
->address_mode
!= mode_64bit
|| !ins
->vex
.w
)
14421 /* Fall through. */
14422 case evex_rounding_mode
:
14423 oappend (ins
, names_rounding
[ins
->vex
.ll
]);
14425 case evex_sae_mode
:
14426 oappend (ins
, "{");
14431 oappend (ins
, "sae}");
14436 PREFETCHI_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14438 if (ins
->modrm
.mod
!= 0 || ins
->modrm
.rm
!= 5)
14440 if (ins
->intel_syntax
)
14442 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nop ");
14447 if (ins
->rex
& REX_W
)
14448 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopq ");
14451 if (sizeflag
& DFLAG
)
14452 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopl ");
14454 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "nopw ");
14455 ins
->used_prefixes
|= (ins
->prefixes
& PREFIX_DATA
);
14461 return OP_M (ins
, bytemode
, sizeflag
);
14465 PUSH2_POP2_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14467 if (ins
->modrm
.mod
!= 3)
14470 unsigned int vvvv_reg
= ins
->vex
.register_specifier
14471 | (!ins
->vex
.v
<< 4);
14472 unsigned int rm_reg
= ins
->modrm
.rm
+ (ins
->rex
& REX_B
? 8 : 0)
14473 + (ins
->rex2
& REX_B
? 16 : 0);
14475 /* Push2/Pop2 cannot use RSP and Pop2 cannot pop two same registers. */
14476 if (!ins
->vex
.nd
|| vvvv_reg
== 0x4 || rm_reg
== 0x4
14477 || (!ins
->modrm
.reg
14478 && vvvv_reg
== rm_reg
))
14480 oappend (ins
, "(bad)");
14484 return OP_VEX (ins
, bytemode
, sizeflag
);
14488 JMPABS_Fixup (instr_info
*ins
, int bytemode
, int sizeflag
)
14490 if (ins
->last_rex2_prefix
>= 0)
14494 if ((ins
->prefixes
& (PREFIX_OPCODE
| PREFIX_ADDR
| PREFIX_LOCK
)) != 0x0
14495 || (ins
->rex
& REX_W
) != 0x0)
14497 oappend (ins
, "(bad)");
14501 if (bytemode
== eAX_reg
)
14504 if (!get64 (ins
, &op
))
14507 ins
->mnemonicendp
= stpcpy (ins
->obuf
, "jmpabs");
14508 ins
->rex2
|= REX2_SPECIAL
;
14509 oappend_immediate (ins
, op
);
14514 if (bytemode
== eAX_reg
)
14515 return OP_IMREG (ins
, bytemode
, sizeflag
);
14516 return OP_OFF64 (ins
, bytemode
, sizeflag
);
14520 CFCMOV_Fixup (instr_info
*ins
, int opnd
, int sizeflag
)
14522 /* EVEX.NF is used as a direction bit in the 2-operand case to reverse the
14523 source and destination operands. */
14524 bool dstmem
= !ins
->vex
.nd
&& ins
->vex
.nf
;
14529 return OP_E (ins
, v_swap_mode
, sizeflag
);
14530 return OP_G (ins
, v_mode
, sizeflag
);
14533 /* These bits have been consumed and should be cleared. */
14534 ins
->vex
.nf
= false;
14535 ins
->vex
.mask_register_specifier
= 0;
14538 return OP_G (ins
, v_mode
, sizeflag
);
14539 return OP_E (ins
, v_mode
, sizeflag
);