10339a1c2SMark Johnston /*
20339a1c2SMark Johnston *
30339a1c2SMark Johnston * CDDL HEADER START
40339a1c2SMark Johnston *
50339a1c2SMark Johnston * The contents of this file are subject to the terms of the
60339a1c2SMark Johnston * Common Development and Distribution License (the "License").
70339a1c2SMark Johnston * You may not use this file except in compliance with the License.
80339a1c2SMark Johnston *
90339a1c2SMark Johnston * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100339a1c2SMark Johnston * or http://www.opensolaris.org/os/licensing.
110339a1c2SMark Johnston * See the License for the specific language governing permissions
120339a1c2SMark Johnston * and limitations under the License.
130339a1c2SMark Johnston *
140339a1c2SMark Johnston * When distributing Covered Code, include this CDDL HEADER in each
150339a1c2SMark Johnston * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160339a1c2SMark Johnston * If applicable, add the following below this CDDL HEADER, with the
170339a1c2SMark Johnston * fields enclosed by brackets "[]" replaced with your own identifying
180339a1c2SMark Johnston * information: Portions Copyright [yyyy] [name of copyright owner]
190339a1c2SMark Johnston *
200339a1c2SMark Johnston * CDDL HEADER END
210339a1c2SMark Johnston */
220339a1c2SMark Johnston /*
230339a1c2SMark Johnston * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24722b2e2fSMark Johnston * Copyright 2019 Joyent, Inc.
25722b2e2fSMark Johnston * Copyright 2020 Robert Mustacchi
260339a1c2SMark Johnston */
270339a1c2SMark Johnston
280339a1c2SMark Johnston /*
290339a1c2SMark Johnston * Copyright (c) 2010, Intel Corporation.
300339a1c2SMark Johnston * All rights reserved.
310339a1c2SMark Johnston */
320339a1c2SMark Johnston
330339a1c2SMark Johnston /* Copyright (c) 1988 AT&T */
340339a1c2SMark Johnston /* All Rights Reserved */
350339a1c2SMark Johnston
360339a1c2SMark Johnston /*
370339a1c2SMark Johnston */
380339a1c2SMark Johnston
390339a1c2SMark Johnston #include "dis_tables.h"
400339a1c2SMark Johnston
410339a1c2SMark Johnston /* BEGIN CSTYLED */
420339a1c2SMark Johnston
430339a1c2SMark Johnston /*
440339a1c2SMark Johnston * Disassembly begins in dis_distable, which is equivalent to the One-byte
450339a1c2SMark Johnston * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy). The
460339a1c2SMark Johnston * decoding loops then traverse out through the other tables as necessary to
470339a1c2SMark Johnston * decode a given instruction.
480339a1c2SMark Johnston *
490339a1c2SMark Johnston * The behavior of this file can be controlled by one of the following flags:
500339a1c2SMark Johnston *
510339a1c2SMark Johnston * DIS_TEXT Include text for disassembly
520339a1c2SMark Johnston * DIS_MEM Include memory-size calculations
530339a1c2SMark Johnston *
540339a1c2SMark Johnston * Either or both of these can be defined.
550339a1c2SMark Johnston *
560339a1c2SMark Johnston * This file is not, and will never be, cstyled. If anything, the tables should
570339a1c2SMark Johnston * be taken out another tab stop or two so nothing overlaps.
580339a1c2SMark Johnston */
590339a1c2SMark Johnston
600339a1c2SMark Johnston /*
610339a1c2SMark Johnston * These functions must be provided for the consumer to do disassembly.
620339a1c2SMark Johnston */
630339a1c2SMark Johnston #ifdef DIS_TEXT
640339a1c2SMark Johnston extern char *strncpy(char *, const char *, size_t);
650339a1c2SMark Johnston extern size_t strlen(const char *);
660339a1c2SMark Johnston extern int strcmp(const char *, const char *);
670339a1c2SMark Johnston extern int strncmp(const char *, const char *, size_t);
680339a1c2SMark Johnston extern size_t strlcat(char *, const char *, size_t);
690339a1c2SMark Johnston #endif
700339a1c2SMark Johnston
710339a1c2SMark Johnston
720339a1c2SMark Johnston #define TERM 0 /* used to indicate that the 'indirect' */
730339a1c2SMark Johnston /* field terminates - no pointer. */
740339a1c2SMark Johnston
750339a1c2SMark Johnston /* Used to decode instructions. */
760339a1c2SMark Johnston typedef struct instable {
770339a1c2SMark Johnston struct instable *it_indirect; /* for decode op codes */
780339a1c2SMark Johnston uchar_t it_adrmode;
790339a1c2SMark Johnston #ifdef DIS_TEXT
800339a1c2SMark Johnston char it_name[NCPS];
810339a1c2SMark Johnston uint_t it_suffix:1; /* mnem + "w", "l", or "d" */
820339a1c2SMark Johnston #endif
830339a1c2SMark Johnston #ifdef DIS_MEM
840339a1c2SMark Johnston uint_t it_size:16;
850339a1c2SMark Johnston #endif
860339a1c2SMark Johnston uint_t it_invalid64:1; /* opcode invalid in amd64 */
870339a1c2SMark Johnston uint_t it_always64:1; /* 64 bit when in 64 bit mode */
880339a1c2SMark Johnston uint_t it_invalid32:1; /* invalid in IA32 */
890339a1c2SMark Johnston uint_t it_stackop:1; /* push/pop stack operation */
90b3b5bfebSMark Johnston uint_t it_vexwoxmm:1; /* VEX instructions that don't use XMM/YMM */
91722b2e2fSMark Johnston uint_t it_avxsuf:2; /* AVX2/AVX512 suffix rqd. */
92722b2e2fSMark Johnston uint_t it_vexopmask:1; /* VEX inst. that use opmask */
930339a1c2SMark Johnston } instable_t;
940339a1c2SMark Johnston
950339a1c2SMark Johnston /*
960339a1c2SMark Johnston * Instruction formats.
970339a1c2SMark Johnston */
980339a1c2SMark Johnston enum {
990339a1c2SMark Johnston UNKNOWN,
1000339a1c2SMark Johnston MRw,
1010339a1c2SMark Johnston IMlw,
1020339a1c2SMark Johnston IMw,
1030339a1c2SMark Johnston IR,
1040339a1c2SMark Johnston OA,
1050339a1c2SMark Johnston AO,
1060339a1c2SMark Johnston MS,
1070339a1c2SMark Johnston SM,
1080339a1c2SMark Johnston Mv,
1090339a1c2SMark Johnston Mw,
1100339a1c2SMark Johnston M, /* register or memory */
111c3ddb60eSPeter Grehan MG9, /* register or memory in group 9 (prefix optional) */
1120339a1c2SMark Johnston Mb, /* register or memory, always byte sized */
1130339a1c2SMark Johnston MO, /* memory only (no registers) */
1140339a1c2SMark Johnston PREF,
115c3ddb60eSPeter Grehan SWAPGS_RDTSCP,
1160339a1c2SMark Johnston MONITOR_MWAIT,
1170339a1c2SMark Johnston R,
1180339a1c2SMark Johnston RA,
1190339a1c2SMark Johnston SEG,
1200339a1c2SMark Johnston MR,
1210339a1c2SMark Johnston RM,
122c3ddb60eSPeter Grehan RM_66r, /* RM, but with a required 0x66 prefix */
1230339a1c2SMark Johnston IA,
1240339a1c2SMark Johnston MA,
1250339a1c2SMark Johnston SD,
1260339a1c2SMark Johnston AD,
1270339a1c2SMark Johnston SA,
1280339a1c2SMark Johnston D,
1290339a1c2SMark Johnston INM,
1300339a1c2SMark Johnston SO,
1310339a1c2SMark Johnston BD,
1320339a1c2SMark Johnston I,
1330339a1c2SMark Johnston P,
1340339a1c2SMark Johnston V,
1350339a1c2SMark Johnston DSHIFT, /* for double shift that has an 8-bit immediate */
1360339a1c2SMark Johnston U,
1370339a1c2SMark Johnston OVERRIDE,
1380339a1c2SMark Johnston NORM, /* instructions w/o ModR/M byte, no memory access */
1390339a1c2SMark Johnston IMPLMEM, /* instructions w/o ModR/M byte, implicit mem access */
1400339a1c2SMark Johnston O, /* for call */
1410339a1c2SMark Johnston JTAB, /* jump table */
1420339a1c2SMark Johnston IMUL, /* for 186 iimul instr */
1430339a1c2SMark Johnston CBW, /* so data16 can be evaluated for cbw and variants */
1440339a1c2SMark Johnston MvI, /* for 186 logicals */
1450339a1c2SMark Johnston ENTER, /* for 186 enter instr */
1460339a1c2SMark Johnston RMw, /* for 286 arpl instr */
1470339a1c2SMark Johnston Ib, /* for push immediate byte */
1480339a1c2SMark Johnston F, /* for 287 instructions */
1490339a1c2SMark Johnston FF, /* for 287 instructions */
1500339a1c2SMark Johnston FFC, /* for 287 instructions */
1510339a1c2SMark Johnston DM, /* 16-bit data */
1520339a1c2SMark Johnston AM, /* 16-bit addr */
1530339a1c2SMark Johnston LSEG, /* for 3-bit seg reg encoding */
1540339a1c2SMark Johnston MIb, /* for 386 logicals */
1550339a1c2SMark Johnston SREG, /* for 386 special registers */
1560339a1c2SMark Johnston PREFIX, /* a REP instruction prefix */
1570339a1c2SMark Johnston LOCK, /* a LOCK instruction prefix */
1580339a1c2SMark Johnston INT3, /* The int 3 instruction, which has a fake operand */
1590339a1c2SMark Johnston INTx, /* The normal int instruction, with explicit int num */
1600339a1c2SMark Johnston DSHIFTcl, /* for double shift that implicitly uses %cl */
1610339a1c2SMark Johnston CWD, /* so data16 can be evaluated for cwd and variants */
1620339a1c2SMark Johnston RET, /* single immediate 16-bit operand */
1630339a1c2SMark Johnston MOVZ, /* for movs and movz, with different size operands */
1640339a1c2SMark Johnston CRC32, /* for crc32, with different size operands */
1650339a1c2SMark Johnston XADDB, /* for xaddb */
1660339a1c2SMark Johnston MOVSXZ, /* AMD64 mov sign extend 32 to 64 bit instruction */
1670339a1c2SMark Johnston MOVBE, /* movbe instruction */
1680339a1c2SMark Johnston
1690339a1c2SMark Johnston /*
1700339a1c2SMark Johnston * MMX/SIMD addressing modes.
1710339a1c2SMark Johnston */
1720339a1c2SMark Johnston
1730339a1c2SMark Johnston MMO, /* Prefixable MMX/SIMD-Int mm/mem -> mm */
1740339a1c2SMark Johnston MMOIMPL, /* Prefixable MMX/SIMD-Int mm -> mm (mem) */
1750339a1c2SMark Johnston MMO3P, /* Prefixable MMX/SIMD-Int mm -> r32,imm8 */
1760339a1c2SMark Johnston MMOM3, /* Prefixable MMX/SIMD-Int mm -> r32 */
1770339a1c2SMark Johnston MMOS, /* Prefixable MMX/SIMD-Int mm -> mm/mem */
1780339a1c2SMark Johnston MMOMS, /* Prefixable MMX/SIMD-Int mm -> mem */
1790339a1c2SMark Johnston MMOPM, /* MMX/SIMD-Int mm/mem -> mm,imm8 */
1800339a1c2SMark Johnston MMOPM_66o, /* MMX/SIMD-Int 0x66 optional mm/mem -> mm,imm8 */
1810339a1c2SMark Johnston MMOPRM, /* Prefixable MMX/SIMD-Int r32/mem -> mm,imm8 */
1820339a1c2SMark Johnston MMOSH, /* Prefixable MMX mm,imm8 */
1830339a1c2SMark Johnston MM, /* MMX/SIMD-Int mm/mem -> mm */
1840339a1c2SMark Johnston MMS, /* MMX/SIMD-Int mm -> mm/mem */
1850339a1c2SMark Johnston MMSH, /* MMX mm,imm8 */
1860339a1c2SMark Johnston XMMO, /* Prefixable SIMD xmm/mem -> xmm */
1870339a1c2SMark Johnston XMMOS, /* Prefixable SIMD xmm -> xmm/mem */
1880339a1c2SMark Johnston XMMOPM, /* Prefixable SIMD xmm/mem w/to xmm,imm8 */
1890339a1c2SMark Johnston XMMOMX, /* Prefixable SIMD mm/mem -> xmm */
1900339a1c2SMark Johnston XMMOX3, /* Prefixable SIMD xmm -> r32 */
1910339a1c2SMark Johnston XMMOXMM, /* Prefixable SIMD xmm/mem -> mm */
1920339a1c2SMark Johnston XMMOM, /* Prefixable SIMD xmm -> mem */
1930339a1c2SMark Johnston XMMOMS, /* Prefixable SIMD mem -> xmm */
1940339a1c2SMark Johnston XMM, /* SIMD xmm/mem -> xmm */
1950339a1c2SMark Johnston XMM_66r, /* SIMD 0x66 prefix required xmm/mem -> xmm */
1960339a1c2SMark Johnston XMM_66o, /* SIMD 0x66 prefix optional xmm/mem -> xmm */
1970339a1c2SMark Johnston XMMXIMPL, /* SIMD xmm -> xmm (mem) */
1980339a1c2SMark Johnston XMM3P, /* SIMD xmm -> r32,imm8 */
1990339a1c2SMark Johnston XMM3PM_66r, /* SIMD 0x66 prefix required xmm -> r32/mem,imm8 */
2000339a1c2SMark Johnston XMMP, /* SIMD xmm/mem w/to xmm,imm8 */
2010339a1c2SMark Johnston XMMP_66o, /* SIMD 0x66 prefix optional xmm/mem w/to xmm,imm8 */
2020339a1c2SMark Johnston XMMP_66r, /* SIMD 0x66 prefix required xmm/mem w/to xmm,imm8 */
2030339a1c2SMark Johnston XMMPRM, /* SIMD r32/mem -> xmm,imm8 */
2040339a1c2SMark Johnston XMMPRM_66r, /* SIMD 0x66 prefix required r32/mem -> xmm,imm8 */
2050339a1c2SMark Johnston XMMS, /* SIMD xmm -> xmm/mem */
2060339a1c2SMark Johnston XMMM, /* SIMD mem -> xmm */
2070339a1c2SMark Johnston XMMM_66r, /* SIMD 0x66 prefix required mem -> xmm */
2080339a1c2SMark Johnston XMMMS, /* SIMD xmm -> mem */
2090339a1c2SMark Johnston XMM3MX, /* SIMD r32/mem -> xmm */
2100339a1c2SMark Johnston XMM3MXS, /* SIMD xmm -> r32/mem */
2110339a1c2SMark Johnston XMMSH, /* SIMD xmm,imm8 */
2120339a1c2SMark Johnston XMMXM3, /* SIMD xmm/mem -> r32 */
2130339a1c2SMark Johnston XMMX3, /* SIMD xmm -> r32 */
2140339a1c2SMark Johnston XMMXMM, /* SIMD xmm/mem -> mm */
2150339a1c2SMark Johnston XMMMX, /* SIMD mm -> xmm */
2160339a1c2SMark Johnston XMMXM, /* SIMD xmm -> mm */
2170339a1c2SMark Johnston XMMX2I, /* SIMD xmm -> xmm, imm, imm */
2180339a1c2SMark Johnston XMM2I, /* SIMD xmm, imm, imm */
2190339a1c2SMark Johnston XMMFENCE, /* SIMD lfence or mfence */
2200339a1c2SMark Johnston XMMSFNC, /* SIMD sfence (none or mem) */
221722b2e2fSMark Johnston FSGS, /* FSGSBASE if reg */
2220339a1c2SMark Johnston XGETBV_XSETBV,
2230339a1c2SMark Johnston VEX_NONE, /* VEX no operand */
2240339a1c2SMark Johnston VEX_MO, /* VEX mod_rm -> implicit reg */
2250339a1c2SMark Johnston VEX_RMrX, /* VEX VEX.vvvv, mod_rm -> mod_reg */
226b3b5bfebSMark Johnston VEX_VRMrX, /* VEX mod_rm, VEX.vvvv -> mod_rm */
2270339a1c2SMark Johnston VEX_RRX, /* VEX VEX.vvvv, mod_reg -> mod_rm */
2280339a1c2SMark Johnston VEX_RMRX, /* VEX VEX.vvvv, mod_rm, imm8[7:4] -> mod_reg */
2290339a1c2SMark Johnston VEX_MX, /* VEX mod_rm -> mod_reg */
2300339a1c2SMark Johnston VEX_MXI, /* VEX mod_rm, imm8 -> mod_reg */
2310339a1c2SMark Johnston VEX_XXI, /* VEX mod_rm, imm8 -> VEX.vvvv */
2320339a1c2SMark Johnston VEX_MR, /* VEX mod_rm -> mod_reg */
2330339a1c2SMark Johnston VEX_RRI, /* VEX mod_reg, mod_rm -> implicit(eflags/r32) */
2340339a1c2SMark Johnston VEX_RX, /* VEX mod_reg -> mod_rm */
235722b2e2fSMark Johnston VEX_KRR, /* VEX mod_rm -> mod_reg */
236722b2e2fSMark Johnston VEX_KMR, /* VEX mod_reg -> mod_rm */
237722b2e2fSMark Johnston VEX_KRM, /* VEX mod_rm -> mod_reg */
2380339a1c2SMark Johnston VEX_RR, /* VEX mod_rm -> mod_reg */
2390339a1c2SMark Johnston VEX_RRi, /* VEX mod_rm, imm8 -> mod_reg */
2400339a1c2SMark Johnston VEX_RM, /* VEX mod_reg -> mod_rm */
241b3b5bfebSMark Johnston VEX_RIM, /* VEX mod_reg, imm8 -> mod_rm */
2420339a1c2SMark Johnston VEX_RRM, /* VEX VEX.vvvv, mod_reg -> mod_rm */
243c3ddb60eSPeter Grehan VEX_RMX, /* VEX VEX.vvvv, mod_rm -> mod_reg */
244b3b5bfebSMark Johnston VEX_SbVM, /* VEX SIB, VEX.vvvv -> mod_rm */
245c3ddb60eSPeter Grehan VMx, /* vmcall/vmlaunch/vmresume/vmxoff */
246c3ddb60eSPeter Grehan VMxo, /* VMx instruction with optional prefix */
247b3b5bfebSMark Johnston SVM, /* AMD SVM instructions */
248b3b5bfebSMark Johnston BLS, /* BLSR, BLSMSK, BLSI */
249b3b5bfebSMark Johnston FMA, /* FMA instructions, all VEX_RMrX */
250722b2e2fSMark Johnston ADX, /* ADX instructions, support REX.w, mod_rm->mod_reg */
251722b2e2fSMark Johnston EVEX_RX, /* EVEX mod_reg -> mod_rm */
252722b2e2fSMark Johnston EVEX_MX, /* EVEX mod_rm -> mod_reg */
253722b2e2fSMark Johnston EVEX_RMrX, /* EVEX EVEX.vvvv, mod_rm -> mod_reg */
254722b2e2fSMark Johnston EVEX_RMRX /* EVEX EVEX.vvvv, mod_rm, imm8 -> mod_reg */
2550339a1c2SMark Johnston };
2560339a1c2SMark Johnston
2570339a1c2SMark Johnston /*
2580339a1c2SMark Johnston * VEX prefixes
2590339a1c2SMark Johnston */
2600339a1c2SMark Johnston #define VEX_2bytes 0xC5 /* the first byte of two-byte form */
2610339a1c2SMark Johnston #define VEX_3bytes 0xC4 /* the first byte of three-byte form */
2620339a1c2SMark Johnston
2630339a1c2SMark Johnston #define FILL 0x90 /* Fill byte used for alignment (nop) */
2640339a1c2SMark Johnston
2650339a1c2SMark Johnston /*
2660339a1c2SMark Johnston ** Register numbers for the i386
2670339a1c2SMark Johnston */
2680339a1c2SMark Johnston #define EAX_REGNO 0
2690339a1c2SMark Johnston #define ECX_REGNO 1
2700339a1c2SMark Johnston #define EDX_REGNO 2
2710339a1c2SMark Johnston #define EBX_REGNO 3
2720339a1c2SMark Johnston #define ESP_REGNO 4
2730339a1c2SMark Johnston #define EBP_REGNO 5
2740339a1c2SMark Johnston #define ESI_REGNO 6
2750339a1c2SMark Johnston #define EDI_REGNO 7
2760339a1c2SMark Johnston
2770339a1c2SMark Johnston /*
2780339a1c2SMark Johnston * modes for immediate values
2790339a1c2SMark Johnston */
2800339a1c2SMark Johnston #define MODE_NONE 0
2810339a1c2SMark Johnston #define MODE_IPREL 1 /* signed IP relative value */
2820339a1c2SMark Johnston #define MODE_SIGNED 2 /* sign extended immediate */
2830339a1c2SMark Johnston #define MODE_IMPLIED 3 /* constant value implied from opcode */
2840339a1c2SMark Johnston #define MODE_OFFSET 4 /* offset part of an address */
2850339a1c2SMark Johnston #define MODE_RIPREL 5 /* like IPREL, but from %rip (amd64) */
2860339a1c2SMark Johnston
2870339a1c2SMark Johnston /*
2880339a1c2SMark Johnston * The letters used in these macros are:
2890339a1c2SMark Johnston * IND - indirect to another to another table
2900339a1c2SMark Johnston * "T" - means to Terminate indirections (this is the final opcode)
2910339a1c2SMark Johnston * "S" - means "operand length suffix required"
292722b2e2fSMark Johnston * "Sa" - means AVX2 suffix (q/d) required
293722b2e2fSMark Johnston * "Sq" - means AVX512 suffix (q/d) required
294722b2e2fSMark Johnston * "Sd" - means AVX512 suffix (d/s) required
2950339a1c2SMark Johnston * "NS" - means "no suffix" which is the operand length suffix of the opcode
2960339a1c2SMark Johnston * "Z" - means instruction size arg required
2970339a1c2SMark Johnston * "u" - means the opcode is invalid in IA32 but valid in amd64
2980339a1c2SMark Johnston * "x" - means the opcode is invalid in amd64, but not IA32
2990339a1c2SMark Johnston * "y" - means the operand size is always 64 bits in 64 bit mode
3000339a1c2SMark Johnston * "p" - means push/pop stack operation
301b3b5bfebSMark Johnston * "vr" - means VEX instruction that operates on normal registers, not fpu
302722b2e2fSMark Johnston * "vo" - means VEX instruction that operates on opmask registers, not fpu
3030339a1c2SMark Johnston */
3040339a1c2SMark Johnston
305722b2e2fSMark Johnston #define AVS2 (uint_t)1 /* it_avxsuf: AVX2 q/d suffix handling */
306722b2e2fSMark Johnston #define AVS5Q (uint_t)2 /* it_avxsuf: AVX512 q/d suffix handling */
307722b2e2fSMark Johnston #define AVS5D (uint_t)3 /* it_avxsuf: AVX512 d/s suffix handling */
308722b2e2fSMark Johnston
3090339a1c2SMark Johnston #if defined(DIS_TEXT) && defined(DIS_MEM)
3100339a1c2SMark Johnston #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
3110339a1c2SMark Johnston #define INDx(table) {(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
3120339a1c2SMark Johnston #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0}
3130339a1c2SMark Johnston #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 0, 1, 0}
3140339a1c2SMark Johnston #define TNSx(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0, 0}
3150339a1c2SMark Johnston #define TNSy(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 0}
3160339a1c2SMark Johnston #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 1}
3170339a1c2SMark Johnston #define TNSZ(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0}
3180339a1c2SMark Johnston #define TNSZy(name, amode, sz) {TERM, amode, name, 0, sz, 0, 1, 0, 0}
319b3b5bfebSMark Johnston #define TNSZvr(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0, 1}
320722b2e2fSMark Johnston #define TSvo(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0, 0, 0, 1}
3210339a1c2SMark Johnston #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0}
3220339a1c2SMark Johnston #define TSx(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0, 0}
3230339a1c2SMark Johnston #define TSy(name, amode) {TERM, amode, name, 1, 0, 0, 1, 0, 0}
3240339a1c2SMark Johnston #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 1}
3250339a1c2SMark Johnston #define TSZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0}
326722b2e2fSMark Johnston #define TSaZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0, 0, AVS2}
327722b2e2fSMark Johnston #define TSq(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, 0, AVS5Q}
328722b2e2fSMark Johnston #define TSd(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, 0, AVS5D}
3290339a1c2SMark Johnston #define TSZx(name, amode, sz) {TERM, amode, name, 1, sz, 1, 0, 0, 0}
3300339a1c2SMark Johnston #define TSZy(name, amode, sz) {TERM, amode, name, 1, sz, 0, 1, 0, 0}
3310339a1c2SMark Johnston #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3320339a1c2SMark Johnston #elif defined(DIS_TEXT)
3330339a1c2SMark Johnston #define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
3340339a1c2SMark Johnston #define INDx(table) {(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
3350339a1c2SMark Johnston #define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0}
3360339a1c2SMark Johnston #define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0}
3370339a1c2SMark Johnston #define TNSx(name, amode) {TERM, amode, name, 0, 1, 0, 0, 0}
3380339a1c2SMark Johnston #define TNSy(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0}
3390339a1c2SMark Johnston #define TNSyp(name, amode) {TERM, amode, name, 0, 0, 1, 0, 1}
3400339a1c2SMark Johnston #define TNSZ(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0}
3410339a1c2SMark Johnston #define TNSZy(name, amode, sz) {TERM, amode, name, 0, 0, 1, 0, 0}
342b3b5bfebSMark Johnston #define TNSZvr(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0, 1}
343722b2e2fSMark Johnston #define TSvo(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0, 0, 1}
3440339a1c2SMark Johnston #define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0}
3450339a1c2SMark Johnston #define TSx(name, amode) {TERM, amode, name, 1, 1, 0, 0, 0}
3460339a1c2SMark Johnston #define TSy(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0}
3470339a1c2SMark Johnston #define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 1}
3480339a1c2SMark Johnston #define TSZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0}
349722b2e2fSMark Johnston #define TSaZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0, 0, AVS2}
350722b2e2fSMark Johnston #define TSq(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, AVS5Q}
3510339a1c2SMark Johnston #define TSZx(name, amode, sz) {TERM, amode, name, 1, 1, 0, 0, 0}
3520339a1c2SMark Johnston #define TSZy(name, amode, sz) {TERM, amode, name, 1, 0, 1, 0, 0}
3530339a1c2SMark Johnston #define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3540339a1c2SMark Johnston #elif defined(DIS_MEM)
3550339a1c2SMark Johnston #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0, 0}
3560339a1c2SMark Johnston #define INDx(table) {(instable_t *)table, 0, 0, 1, 0, 0, 0}
3570339a1c2SMark Johnston #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0, 0}
3580339a1c2SMark Johnston #define TNSu(name, amode) {TERM, amode, 0, 0, 0, 1, 0}
3590339a1c2SMark Johnston #define TNSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0}
3600339a1c2SMark Johnston #define TNSyp(name, amode) {TERM, amode, 0, 0, 1, 0, 1}
3610339a1c2SMark Johnston #define TNSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0}
3620339a1c2SMark Johnston #define TNSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0}
3630339a1c2SMark Johnston #define TNSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0}
364b3b5bfebSMark Johnston #define TNSZvr(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0, 1}
365722b2e2fSMark Johnston #define TSvo(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, 0, 1}
3660339a1c2SMark Johnston #define TS(name, amode) {TERM, amode, 0, 0, 0, 0, 0}
3670339a1c2SMark Johnston #define TSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0}
3680339a1c2SMark Johnston #define TSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0}
3690339a1c2SMark Johnston #define TSp(name, amode) {TERM, amode, 0, 0, 0, 0, 1}
3700339a1c2SMark Johnston #define TSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0}
371722b2e2fSMark Johnston #define TSaZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0, 0, AVS2}
372722b2e2fSMark Johnston #define TSq(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, AVS5Q}
3730339a1c2SMark Johnston #define TSZx(name, amode, sz) {TERM, amode, sz, 1, 0, 0, 0}
3740339a1c2SMark Johnston #define TSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0}
3750339a1c2SMark Johnston #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0, 0}
3760339a1c2SMark Johnston #else
3770339a1c2SMark Johnston #define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0}
3780339a1c2SMark Johnston #define INDx(table) {(instable_t *)table, 0, 1, 0, 0, 0}
3790339a1c2SMark Johnston #define TNS(name, amode) {TERM, amode, 0, 0, 0, 0}
3800339a1c2SMark Johnston #define TNSu(name, amode) {TERM, amode, 0, 0, 1, 0}
3810339a1c2SMark Johnston #define TNSy(name, amode) {TERM, amode, 0, 1, 0, 0}
3820339a1c2SMark Johnston #define TNSyp(name, amode) {TERM, amode, 0, 1, 0, 1}
3830339a1c2SMark Johnston #define TNSx(name, amode) {TERM, amode, 1, 0, 0, 0}
3840339a1c2SMark Johnston #define TNSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0}
3850339a1c2SMark Johnston #define TNSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0}
386b3b5bfebSMark Johnston #define TNSZvr(name, amode, sz) {TERM, amode, 0, 0, 0, 0, 1}
387722b2e2fSMark Johnston #define TSvo(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, 1}
3880339a1c2SMark Johnston #define TS(name, amode) {TERM, amode, 0, 0, 0, 0}
3890339a1c2SMark Johnston #define TSx(name, amode) {TERM, amode, 1, 0, 0, 0}
3900339a1c2SMark Johnston #define TSy(name, amode) {TERM, amode, 0, 1, 0, 0}
3910339a1c2SMark Johnston #define TSp(name, amode) {TERM, amode, 0, 0, 0, 1}
3920339a1c2SMark Johnston #define TSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0}
393722b2e2fSMark Johnston #define TSaZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0, 0, AVS2}
394722b2e2fSMark Johnston #define TSq(name, amode) {TERM, amode, 0, 0, 0, 0, 0, AVS5Q}
395722b2e2fSMark Johnston #define TSd(name, amode) {TERM, amode, 0, 0, 0, 0, 0, AVS5D}
3960339a1c2SMark Johnston #define TSZx(name, amode, sz) {TERM, amode, 1, 0, 0, 0}
3970339a1c2SMark Johnston #define TSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0}
3980339a1c2SMark Johnston #define INVALID {TERM, UNKNOWN, 0, 0, 0, 0}
3990339a1c2SMark Johnston #endif
4000339a1c2SMark Johnston
4010339a1c2SMark Johnston #ifdef DIS_TEXT
4020339a1c2SMark Johnston /*
4030339a1c2SMark Johnston * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
4040339a1c2SMark Johnston */
4050339a1c2SMark Johnston const char *const dis_addr16[3][8] = {
4060339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
4070339a1c2SMark Johnston "(%bx)",
4080339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
4090339a1c2SMark Johnston "(%bx)",
4100339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
4110339a1c2SMark Johnston "(%bx)",
4120339a1c2SMark Johnston };
4130339a1c2SMark Johnston
4140339a1c2SMark Johnston
4150339a1c2SMark Johnston /*
4160339a1c2SMark Johnston * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
4170339a1c2SMark Johnston */
4180339a1c2SMark Johnston const char *const dis_addr32_mode0[16] = {
4190339a1c2SMark Johnston "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "", "(%esi)", "(%edi)",
4200339a1c2SMark Johnston "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "", "(%r14d)", "(%r15d)"
4210339a1c2SMark Johnston };
4220339a1c2SMark Johnston
4230339a1c2SMark Johnston const char *const dis_addr32_mode12[16] = {
4240339a1c2SMark Johnston "(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "(%ebp)", "(%esi)", "(%edi)",
4250339a1c2SMark Johnston "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
4260339a1c2SMark Johnston };
4270339a1c2SMark Johnston
4280339a1c2SMark Johnston /*
4290339a1c2SMark Johnston * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
4300339a1c2SMark Johnston */
4310339a1c2SMark Johnston const char *const dis_addr64_mode0[16] = {
4320339a1c2SMark Johnston "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rip)", "(%rsi)", "(%rdi)",
4330339a1c2SMark Johnston "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
4340339a1c2SMark Johnston };
4350339a1c2SMark Johnston const char *const dis_addr64_mode12[16] = {
4360339a1c2SMark Johnston "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rbp)", "(%rsi)", "(%rdi)",
4370339a1c2SMark Johnston "(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
4380339a1c2SMark Johnston };
4390339a1c2SMark Johnston
4400339a1c2SMark Johnston /*
4410339a1c2SMark Johnston * decode for scale from SIB byte
4420339a1c2SMark Johnston */
4430339a1c2SMark Johnston const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
4440339a1c2SMark Johnston
4450339a1c2SMark Johnston /*
446b3b5bfebSMark Johnston * decode for scale from VSIB byte, note that we always include the scale factor
447b3b5bfebSMark Johnston * to match gas.
448b3b5bfebSMark Johnston */
449b3b5bfebSMark Johnston const char *const dis_vscale_factor[4] = { ",1)", ",2)", ",4)", ",8)" };
450b3b5bfebSMark Johnston
451b3b5bfebSMark Johnston /*
4520339a1c2SMark Johnston * register decoding for normal references to registers (ie. not addressing)
4530339a1c2SMark Johnston */
4540339a1c2SMark Johnston const char *const dis_REG8[16] = {
4550339a1c2SMark Johnston "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
4560339a1c2SMark Johnston "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4570339a1c2SMark Johnston };
4580339a1c2SMark Johnston
4590339a1c2SMark Johnston const char *const dis_REG8_REX[16] = {
4600339a1c2SMark Johnston "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
4610339a1c2SMark Johnston "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4620339a1c2SMark Johnston };
4630339a1c2SMark Johnston
4640339a1c2SMark Johnston const char *const dis_REG16[16] = {
4650339a1c2SMark Johnston "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
4660339a1c2SMark Johnston "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
4670339a1c2SMark Johnston };
4680339a1c2SMark Johnston
4690339a1c2SMark Johnston const char *const dis_REG32[16] = {
4700339a1c2SMark Johnston "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
4710339a1c2SMark Johnston "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
4720339a1c2SMark Johnston };
4730339a1c2SMark Johnston
4740339a1c2SMark Johnston const char *const dis_REG64[16] = {
4750339a1c2SMark Johnston "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
4760339a1c2SMark Johnston "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
4770339a1c2SMark Johnston };
4780339a1c2SMark Johnston
4790339a1c2SMark Johnston const char *const dis_DEBUGREG[16] = {
4800339a1c2SMark Johnston "%db0", "%db1", "%db2", "%db3", "%db4", "%db5", "%db6", "%db7",
4810339a1c2SMark Johnston "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
4820339a1c2SMark Johnston };
4830339a1c2SMark Johnston
4840339a1c2SMark Johnston const char *const dis_CONTROLREG[16] = {
4850339a1c2SMark Johnston "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
4860339a1c2SMark Johnston "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
4870339a1c2SMark Johnston };
4880339a1c2SMark Johnston
4890339a1c2SMark Johnston const char *const dis_TESTREG[16] = {
4900339a1c2SMark Johnston "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
4910339a1c2SMark Johnston "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
4920339a1c2SMark Johnston };
4930339a1c2SMark Johnston
4940339a1c2SMark Johnston const char *const dis_MMREG[16] = {
4950339a1c2SMark Johnston "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
4960339a1c2SMark Johnston "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
4970339a1c2SMark Johnston };
4980339a1c2SMark Johnston
499722b2e2fSMark Johnston const char *const dis_XMMREG[32] = {
500722b2e2fSMark Johnston "%xmm0", "%xmm1", "%xmm2", "%xmm3",
501722b2e2fSMark Johnston "%xmm4", "%xmm5", "%xmm6", "%xmm7",
502722b2e2fSMark Johnston "%xmm8", "%xmm9", "%xmm10", "%xmm11",
503722b2e2fSMark Johnston "%xmm12", "%xmm13", "%xmm14", "%xmm15",
504722b2e2fSMark Johnston "%xmm16", "%xmm17", "%xmm18", "%xmm19",
505722b2e2fSMark Johnston "%xmm20", "%xmm21", "%xmm22", "%xmm23",
506722b2e2fSMark Johnston "%xmm24", "%xmm25", "%xmm26", "%xmm27",
507722b2e2fSMark Johnston "%xmm28", "%xmm29", "%xmm30", "%xmm31",
5080339a1c2SMark Johnston };
5090339a1c2SMark Johnston
510722b2e2fSMark Johnston const char *const dis_YMMREG[32] = {
511722b2e2fSMark Johnston "%ymm0", "%ymm1", "%ymm2", "%ymm3",
512722b2e2fSMark Johnston "%ymm4", "%ymm5", "%ymm6", "%ymm7",
513722b2e2fSMark Johnston "%ymm8", "%ymm9", "%ymm10", "%ymm11",
514722b2e2fSMark Johnston "%ymm12", "%ymm13", "%ymm14", "%ymm15",
515722b2e2fSMark Johnston "%ymm16", "%ymm17", "%ymm18", "%ymm19",
516722b2e2fSMark Johnston "%ymm20", "%ymm21", "%ymm22", "%ymm23",
517722b2e2fSMark Johnston "%ymm24", "%ymm25", "%ymm26", "%ymm27",
518722b2e2fSMark Johnston "%ymm28", "%ymm29", "%ymm30", "%ymm31",
519722b2e2fSMark Johnston };
520722b2e2fSMark Johnston
521722b2e2fSMark Johnston const char *const dis_ZMMREG[32] = {
522722b2e2fSMark Johnston "%zmm0", "%zmm1", "%zmm2", "%zmm3",
523722b2e2fSMark Johnston "%zmm4", "%zmm5", "%zmm6", "%zmm7",
524722b2e2fSMark Johnston "%zmm8", "%zmm9", "%zmm10", "%zmm11",
525722b2e2fSMark Johnston "%zmm12", "%zmm13", "%zmm14", "%zmm15",
526722b2e2fSMark Johnston "%zmm16", "%zmm17", "%zmm18", "%zmm19",
527722b2e2fSMark Johnston "%zmm20", "%zmm21", "%zmm22", "%zmm23",
528722b2e2fSMark Johnston "%zmm24", "%zmm25", "%zmm26", "%zmm27",
529722b2e2fSMark Johnston "%zmm28", "%zmm29", "%zmm30", "%zmm31",
530722b2e2fSMark Johnston };
531722b2e2fSMark Johnston
532722b2e2fSMark Johnston const char *const dis_KOPMASKREG[8] = {
533722b2e2fSMark Johnston "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
5340339a1c2SMark Johnston };
5350339a1c2SMark Johnston
5360339a1c2SMark Johnston const char *const dis_SEGREG[16] = {
5370339a1c2SMark Johnston "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
5380339a1c2SMark Johnston "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
5390339a1c2SMark Johnston };
5400339a1c2SMark Johnston
5410339a1c2SMark Johnston /*
5420339a1c2SMark Johnston * SIMD predicate suffixes
5430339a1c2SMark Johnston */
5440339a1c2SMark Johnston const char *const dis_PREDSUFFIX[8] = {
5450339a1c2SMark Johnston "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
5460339a1c2SMark Johnston };
5470339a1c2SMark Johnston
5480339a1c2SMark Johnston const char *const dis_AVXvgrp7[3][8] = {
5490339a1c2SMark Johnston /*0 1 2 3 4 5 6 7*/
5500339a1c2SMark Johnston /*71*/ {"", "", "vpsrlw", "", "vpsraw", "", "vpsllw", ""},
5510339a1c2SMark Johnston /*72*/ {"", "", "vpsrld", "", "vpsrad", "", "vpslld", ""},
5520339a1c2SMark Johnston /*73*/ {"", "", "vpsrlq", "vpsrldq", "", "", "vpsllq", "vpslldq"}
5530339a1c2SMark Johnston };
5540339a1c2SMark Johnston
5550339a1c2SMark Johnston #endif /* DIS_TEXT */
5560339a1c2SMark Johnston
5570339a1c2SMark Johnston /*
5580339a1c2SMark Johnston * "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
5590339a1c2SMark Johnston */
5600339a1c2SMark Johnston const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
5610339a1c2SMark Johnston
5620339a1c2SMark Johnston /*
5630339a1c2SMark Johnston * "decode table" for pause and clflush instructions
5640339a1c2SMark Johnston */
5650339a1c2SMark Johnston const instable_t dis_opPause = TNS("pause", NORM);
5660339a1c2SMark Johnston
5670339a1c2SMark Johnston /*
568722b2e2fSMark Johnston * "decode table" for wbnoinvd instruction
569722b2e2fSMark Johnston */
570722b2e2fSMark Johnston const instable_t dis_opWbnoinvd = TNS("wbnoinvd", NORM);
571722b2e2fSMark Johnston
572722b2e2fSMark Johnston /*
5730339a1c2SMark Johnston * Decode table for 0x0F00 opcodes
5740339a1c2SMark Johnston */
5750339a1c2SMark Johnston const instable_t dis_op0F00[8] = {
5760339a1c2SMark Johnston
5770339a1c2SMark Johnston /* [0] */ TNS("sldt",M), TNS("str",M), TNSy("lldt",M), TNSy("ltr",M),
5780339a1c2SMark Johnston /* [4] */ TNSZ("verr",M,2), TNSZ("verw",M,2), INVALID, INVALID,
5790339a1c2SMark Johnston };
5800339a1c2SMark Johnston
5810339a1c2SMark Johnston
5820339a1c2SMark Johnston /*
5830339a1c2SMark Johnston * Decode table for 0x0F01 opcodes
5840339a1c2SMark Johnston */
5850339a1c2SMark Johnston const instable_t dis_op0F01[8] = {
5860339a1c2SMark Johnston
587c3ddb60eSPeter Grehan /* [0] */ TNSZ("sgdt",VMx,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6), TNSZ("lidt",SVM,6),
588c3ddb60eSPeter Grehan /* [4] */ TNSZ("smsw",M,2), INVALID, TNSZ("lmsw",M,2), TNS("invlpg",SWAPGS_RDTSCP),
5890339a1c2SMark Johnston };
5900339a1c2SMark Johnston
5910339a1c2SMark Johnston /*
5920339a1c2SMark Johnston * Decode table for 0x0F18 opcodes -- SIMD prefetch
5930339a1c2SMark Johnston */
5940339a1c2SMark Johnston const instable_t dis_op0F18[8] = {
5950339a1c2SMark Johnston
5960339a1c2SMark Johnston /* [0] */ TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF),
5970339a1c2SMark Johnston /* [4] */ INVALID, INVALID, INVALID, INVALID,
5980339a1c2SMark Johnston };
5990339a1c2SMark Johnston
6000339a1c2SMark Johnston /*
6010339a1c2SMark Johnston * Decode table for 0x0FAE opcodes -- SIMD state save/restore
6020339a1c2SMark Johnston */
6030339a1c2SMark Johnston const instable_t dis_op0FAE[8] = {
604722b2e2fSMark Johnston /* [0] */ TNSZ("fxsave",FSGS,512),TNSZ("fxrstor",FSGS,512),TNS("ldmxcsr",FSGS), TNS("stmxcsr",FSGS),
6050339a1c2SMark Johnston /* [4] */ TNSZ("xsave",M,512), TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC),
6060339a1c2SMark Johnston };
6070339a1c2SMark Johnston
6080339a1c2SMark Johnston /*
609722b2e2fSMark Johnston * Decode table for 0xF30FAE opcodes -- FSGSBASE
610722b2e2fSMark Johnston */
611722b2e2fSMark Johnston const instable_t dis_opF30FAE[8] = {
612722b2e2fSMark Johnston /* [0] */ TNSx("rdfsbase",FSGS), TNSx("rdgsbase",FSGS), TNSx("wrfsbase",FSGS), TNSx("wrgsbase",FSGS),
613722b2e2fSMark Johnston /* [4] */ INVALID, INVALID, INVALID, INVALID,
614722b2e2fSMark Johnston };
615722b2e2fSMark Johnston
616722b2e2fSMark Johnston /*
6170339a1c2SMark Johnston * Decode table for 0x0FBA opcodes
6180339a1c2SMark Johnston */
6190339a1c2SMark Johnston
6200339a1c2SMark Johnston const instable_t dis_op0FBA[8] = {
6210339a1c2SMark Johnston
6220339a1c2SMark Johnston /* [0] */ INVALID, INVALID, INVALID, INVALID,
6230339a1c2SMark Johnston /* [4] */ TS("bt",MIb), TS("bts",MIb), TS("btr",MIb), TS("btc",MIb),
6240339a1c2SMark Johnston };
6250339a1c2SMark Johnston
6260339a1c2SMark Johnston /*
627c3ddb60eSPeter Grehan * Decode table for 0x0FC7 opcode (group 9)
6280339a1c2SMark Johnston */
6290339a1c2SMark Johnston
6300339a1c2SMark Johnston const instable_t dis_op0FC7[8] = {
6310339a1c2SMark Johnston
632722b2e2fSMark Johnston /* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, TNS("xrstors",MG9),
633722b2e2fSMark Johnston /* [4] */ TNS("xsavec",MG9), TNS("xsaves",MG9), TNS("vmptrld",MG9), TNS("vmptrst",MG9),
6340339a1c2SMark Johnston };
6350339a1c2SMark Johnston
636c3ddb60eSPeter Grehan /*
637c3ddb60eSPeter Grehan * Decode table for 0x0FC7 opcode (group 9) mode 3
638c3ddb60eSPeter Grehan */
639c3ddb60eSPeter Grehan
640c3ddb60eSPeter Grehan const instable_t dis_op0FC7m3[8] = {
641c3ddb60eSPeter Grehan
642c3ddb60eSPeter Grehan /* [0] */ INVALID, INVALID, INVALID, INVALID,
643b3b5bfebSMark Johnston /* [4] */ INVALID, INVALID, TNS("rdrand",MG9), TNS("rdseed", MG9),
644c3ddb60eSPeter Grehan };
645c3ddb60eSPeter Grehan
646c3ddb60eSPeter Grehan /*
647c3ddb60eSPeter Grehan * Decode table for 0x0FC7 opcode with 0x66 prefix
648c3ddb60eSPeter Grehan */
649c3ddb60eSPeter Grehan
650c3ddb60eSPeter Grehan const instable_t dis_op660FC7[8] = {
651c3ddb60eSPeter Grehan
652c3ddb60eSPeter Grehan /* [0] */ INVALID, INVALID, INVALID, INVALID,
653c3ddb60eSPeter Grehan /* [4] */ INVALID, INVALID, TNS("vmclear",M), INVALID,
654c3ddb60eSPeter Grehan };
655c3ddb60eSPeter Grehan
656c3ddb60eSPeter Grehan /*
657c3ddb60eSPeter Grehan * Decode table for 0x0FC7 opcode with 0xF3 prefix
658c3ddb60eSPeter Grehan */
659c3ddb60eSPeter Grehan
660c3ddb60eSPeter Grehan const instable_t dis_opF30FC7[8] = {
661c3ddb60eSPeter Grehan
662c3ddb60eSPeter Grehan /* [0] */ INVALID, INVALID, INVALID, INVALID,
663c3ddb60eSPeter Grehan /* [4] */ INVALID, INVALID, TNS("vmxon",M), INVALID,
664c3ddb60eSPeter Grehan };
6650339a1c2SMark Johnston
6660339a1c2SMark Johnston /*
6670339a1c2SMark Johnston * Decode table for 0x0FC8 opcode -- 486 bswap instruction
6680339a1c2SMark Johnston *
6690339a1c2SMark Johnston *bit pattern: 0000 1111 1100 1reg
6700339a1c2SMark Johnston */
6710339a1c2SMark Johnston const instable_t dis_op0FC8[4] = {
6720339a1c2SMark Johnston /* [0] */ TNS("bswap",R), INVALID, INVALID, INVALID,
6730339a1c2SMark Johnston };
6740339a1c2SMark Johnston
6750339a1c2SMark Johnston /*
6760339a1c2SMark Johnston * Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
6770339a1c2SMark Johnston */
6780339a1c2SMark Johnston const instable_t dis_op0F7123[4][8] = {
6790339a1c2SMark Johnston {
6800339a1c2SMark Johnston /* [70].0 */ INVALID, INVALID, INVALID, INVALID,
6810339a1c2SMark Johnston /* .4 */ INVALID, INVALID, INVALID, INVALID,
6820339a1c2SMark Johnston }, {
6830339a1c2SMark Johnston /* [71].0 */ INVALID, INVALID, TNS("psrlw",MMOSH), INVALID,
6840339a1c2SMark Johnston /* .4 */ TNS("psraw",MMOSH), INVALID, TNS("psllw",MMOSH), INVALID,
6850339a1c2SMark Johnston }, {
6860339a1c2SMark Johnston /* [72].0 */ INVALID, INVALID, TNS("psrld",MMOSH), INVALID,
6870339a1c2SMark Johnston /* .4 */ TNS("psrad",MMOSH), INVALID, TNS("pslld",MMOSH), INVALID,
6880339a1c2SMark Johnston }, {
6890339a1c2SMark Johnston /* [73].0 */ INVALID, INVALID, TNS("psrlq",MMOSH), TNS("INVALID",MMOSH),
6900339a1c2SMark Johnston /* .4 */ INVALID, INVALID, TNS("psllq",MMOSH), TNS("INVALID",MMOSH),
6910339a1c2SMark Johnston } };
6920339a1c2SMark Johnston
6930339a1c2SMark Johnston /*
6940339a1c2SMark Johnston * Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
6950339a1c2SMark Johnston */
6960339a1c2SMark Johnston const instable_t dis_opSIMD7123[32] = {
6970339a1c2SMark Johnston /* [70].0 */ INVALID, INVALID, INVALID, INVALID,
6980339a1c2SMark Johnston /* .4 */ INVALID, INVALID, INVALID, INVALID,
6990339a1c2SMark Johnston
7000339a1c2SMark Johnston /* [71].0 */ INVALID, INVALID, TNS("psrlw",XMMSH), INVALID,
7010339a1c2SMark Johnston /* .4 */ TNS("psraw",XMMSH), INVALID, TNS("psllw",XMMSH), INVALID,
7020339a1c2SMark Johnston
7030339a1c2SMark Johnston /* [72].0 */ INVALID, INVALID, TNS("psrld",XMMSH), INVALID,
7040339a1c2SMark Johnston /* .4 */ TNS("psrad",XMMSH), INVALID, TNS("pslld",XMMSH), INVALID,
7050339a1c2SMark Johnston
7060339a1c2SMark Johnston /* [73].0 */ INVALID, INVALID, TNS("psrlq",XMMSH), TNS("psrldq",XMMSH),
7070339a1c2SMark Johnston /* .4 */ INVALID, INVALID, TNS("psllq",XMMSH), TNS("pslldq",XMMSH),
7080339a1c2SMark Johnston };
7090339a1c2SMark Johnston
7100339a1c2SMark Johnston /*
7110339a1c2SMark Johnston * SIMD instructions have been wedged into the existing IA32 instruction
7120339a1c2SMark Johnston * set through the use of prefixes. That is, while 0xf0 0x58 may be
7130339a1c2SMark Johnston * addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
7140339a1c2SMark Johnston * instruction - addss. At present, three prefixes have been coopted in
7150339a1c2SMark Johnston * this manner - address size (0x66), repnz (0xf2) and repz (0xf3). The
7160339a1c2SMark Johnston * following tables are used to provide the prefixed instruction names.
7170339a1c2SMark Johnston * The arrays are sparse, but they're fast.
7180339a1c2SMark Johnston */
7190339a1c2SMark Johnston
7200339a1c2SMark Johnston /*
7210339a1c2SMark Johnston * Decode table for SIMD instructions with the address size (0x66) prefix.
7220339a1c2SMark Johnston */
7230339a1c2SMark Johnston const instable_t dis_opSIMDdata16[256] = {
7240339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
7250339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
7260339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
7270339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
7280339a1c2SMark Johnston
7290339a1c2SMark Johnston /* [10] */ TNSZ("movupd",XMM,16), TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8), TNSZ("movlpd",XMMMS,8),
7300339a1c2SMark Johnston /* [14] */ TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8), TNSZ("movhpd",XMMMS,8),
7310339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
7320339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
7330339a1c2SMark Johnston
7340339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
7350339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
7360339a1c2SMark Johnston /* [28] */ TNSZ("movapd",XMM,16), TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
7370339a1c2SMark Johnston /* [2C] */ TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
7380339a1c2SMark Johnston
7390339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
7400339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
7410339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
7420339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
7430339a1c2SMark Johnston
7440339a1c2SMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
7450339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
7460339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
7470339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
7480339a1c2SMark Johnston
7490339a1c2SMark Johnston /* [50] */ TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16), INVALID, INVALID,
7500339a1c2SMark Johnston /* [54] */ TNSZ("andpd",XMM,16), TNSZ("andnpd",XMM,16), TNSZ("orpd",XMM,16), TNSZ("xorpd",XMM,16),
7510339a1c2SMark Johnston /* [58] */ TNSZ("addpd",XMM,16), TNSZ("mulpd",XMM,16), TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
7520339a1c2SMark Johnston /* [5C] */ TNSZ("subpd",XMM,16), TNSZ("minpd",XMM,16), TNSZ("divpd",XMM,16), TNSZ("maxpd",XMM,16),
7530339a1c2SMark Johnston
7540339a1c2SMark Johnston /* [60] */ TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
7550339a1c2SMark Johnston /* [64] */ TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16),
7560339a1c2SMark Johnston /* [68] */ TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
7570339a1c2SMark Johnston /* [6C] */ TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
7580339a1c2SMark Johnston
7590339a1c2SMark Johnston /* [70] */ TNSZ("pshufd",XMMP,16), INVALID, INVALID, INVALID,
7600339a1c2SMark Johnston /* [74] */ TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID,
7610339a1c2SMark Johnston /* [78] */ TNSZ("extrq",XMM2I,16), TNSZ("extrq",XMM,16), INVALID, INVALID,
762b3b5bfebSMark Johnston /* [7C] */ TNSZ("haddpd",XMM,16), TNSZ("hsubpd",XMM,16), TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16),
7630339a1c2SMark Johnston
7640339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
7650339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
7660339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
7670339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
7680339a1c2SMark Johnston
7690339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
7700339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
7710339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
7720339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
7730339a1c2SMark Johnston
7740339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
7750339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
7760339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
7770339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
7780339a1c2SMark Johnston
7790339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
7800339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
7810339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
7820339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
7830339a1c2SMark Johnston
7840339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("cmppd",XMMP,16), INVALID,
7850339a1c2SMark Johnston /* [C4] */ TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P), TNSZ("shufpd",XMMP,16), INVALID,
7860339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
7870339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
7880339a1c2SMark Johnston
789b3b5bfebSMark Johnston /* [D0] */ TNSZ("addsubpd",XMM,16),TNSZ("psrlw",XMM,16), TNSZ("psrld",XMM,16), TNSZ("psrlq",XMM,16),
7900339a1c2SMark Johnston /* [D4] */ TNSZ("paddq",XMM,16), TNSZ("pmullw",XMM,16), TNSZ("movq",XMMS,8), TNS("pmovmskb",XMMX3),
7910339a1c2SMark Johnston /* [D8] */ TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16), TNSZ("pand",XMM,16),
7920339a1c2SMark Johnston /* [DC] */ TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16), TNSZ("pandn",XMM,16),
7930339a1c2SMark Johnston
7940339a1c2SMark Johnston /* [E0] */ TNSZ("pavgb",XMM,16), TNSZ("psraw",XMM,16), TNSZ("psrad",XMM,16), TNSZ("pavgw",XMM,16),
7950339a1c2SMark Johnston /* [E4] */ TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16), TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
7960339a1c2SMark Johnston /* [E8] */ TNSZ("psubsb",XMM,16), TNSZ("psubsw",XMM,16), TNSZ("pminsw",XMM,16), TNSZ("por",XMM,16),
7970339a1c2SMark Johnston /* [EC] */ TNSZ("paddsb",XMM,16), TNSZ("paddsw",XMM,16), TNSZ("pmaxsw",XMM,16), TNSZ("pxor",XMM,16),
7980339a1c2SMark Johnston
7990339a1c2SMark Johnston /* [F0] */ INVALID, TNSZ("psllw",XMM,16), TNSZ("pslld",XMM,16), TNSZ("psllq",XMM,16),
8000339a1c2SMark Johnston /* [F4] */ TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16), TNSZ("maskmovdqu", XMMXIMPL,16),
8010339a1c2SMark Johnston /* [F8] */ TNSZ("psubb",XMM,16), TNSZ("psubw",XMM,16), TNSZ("psubd",XMM,16), TNSZ("psubq",XMM,16),
8020339a1c2SMark Johnston /* [FC] */ TNSZ("paddb",XMM,16), TNSZ("paddw",XMM,16), TNSZ("paddd",XMM,16), INVALID,
8030339a1c2SMark Johnston };
8040339a1c2SMark Johnston
8050339a1c2SMark Johnston const instable_t dis_opAVX660F[256] = {
8060339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
8070339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
8080339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
8090339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
8100339a1c2SMark Johnston
8110339a1c2SMark Johnston /* [10] */ TNSZ("vmovupd",VEX_MX,16), TNSZ("vmovupd",VEX_RX,16), TNSZ("vmovlpd",VEX_RMrX,8), TNSZ("vmovlpd",VEX_RM,8),
8120339a1c2SMark Johnston /* [14] */ TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8), TNSZ("vmovhpd",VEX_RM,8),
8130339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
8140339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
8150339a1c2SMark Johnston
8160339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
8170339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
8180339a1c2SMark Johnston /* [28] */ TNSZ("vmovapd",VEX_MX,16), TNSZ("vmovapd",VEX_RX,16), INVALID, TNSZ("vmovntpd",VEX_RM,16),
8190339a1c2SMark Johnston /* [2C] */ INVALID, INVALID, TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
8200339a1c2SMark Johnston
8210339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
8220339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
8230339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
8240339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
8250339a1c2SMark Johnston
826722b2e2fSMark Johnston /* [40] */ INVALID, TSvo("kand",VEX_RMX), TSvo("kandn",VEX_RMX), INVALID,
827722b2e2fSMark Johnston /* [44] */ TSvo("knot",VEX_MX), TSvo("kor",VEX_RMX), TSvo("kxnor",VEX_RMX), TSvo("kxor",VEX_RMX),
828722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, TSvo("kadd",VEX_RMX), TSvo("kunpck",VEX_RMX),
8290339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
8300339a1c2SMark Johnston
8310339a1c2SMark Johnston /* [50] */ TNS("vmovmskpd",VEX_MR), TNSZ("vsqrtpd",VEX_MX,16), INVALID, INVALID,
8320339a1c2SMark Johnston /* [54] */ TNSZ("vandpd",VEX_RMrX,16), TNSZ("vandnpd",VEX_RMrX,16), TNSZ("vorpd",VEX_RMrX,16), TNSZ("vxorpd",VEX_RMrX,16),
8330339a1c2SMark Johnston /* [58] */ TNSZ("vaddpd",VEX_RMrX,16), TNSZ("vmulpd",VEX_RMrX,16), TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
8340339a1c2SMark Johnston /* [5C] */ TNSZ("vsubpd",VEX_RMrX,16), TNSZ("vminpd",VEX_RMrX,16), TNSZ("vdivpd",VEX_RMrX,16), TNSZ("vmaxpd",VEX_RMrX,16),
8350339a1c2SMark Johnston
8360339a1c2SMark Johnston /* [60] */ TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
8370339a1c2SMark Johnston /* [64] */ TNSZ("vpcmpgtb",VEX_RMrX,16), TNSZ("vpcmpgtw",VEX_RMrX,16), TNSZ("vpcmpgtd",VEX_RMrX,16), TNSZ("vpackuswb",VEX_RMrX,16),
8380339a1c2SMark Johnston /* [68] */ TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
8390339a1c2SMark Johnston /* [6C] */ TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
8400339a1c2SMark Johnston
8410339a1c2SMark Johnston /* [70] */ TNSZ("vpshufd",VEX_MXI,16), TNSZ("vgrp71",VEX_XXI,16), TNSZ("vgrp72",VEX_XXI,16), TNSZ("vgrp73",VEX_XXI,16),
8420339a1c2SMark Johnston /* [74] */ TNSZ("vpcmpeqb",VEX_RMrX,16), TNSZ("vpcmpeqw",VEX_RMrX,16), TNSZ("vpcmpeqd",VEX_RMrX,16), INVALID,
8430339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
8440339a1c2SMark Johnston /* [7C] */ TNSZ("vhaddpd",VEX_RMrX,16), TNSZ("vhsubpd",VEX_RMrX,16), TNSZ("vmovd",VEX_RR,4), TNSZ("vmovdqa",VEX_RX,16),
8450339a1c2SMark Johnston
8460339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
8470339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
8480339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
8490339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
8500339a1c2SMark Johnston
851722b2e2fSMark Johnston /* [90] */ TSvo("kmov",VEX_KRM), TSvo("kmov",VEX_KMR), TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),
8520339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
853722b2e2fSMark Johnston /* [98] */ TSvo("kortest",VEX_MX), TSvo("ktest",VEX_MX), INVALID, INVALID,
8540339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
8550339a1c2SMark Johnston
8560339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
8570339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
8580339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
8590339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
8600339a1c2SMark Johnston
8610339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
8620339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
8630339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
8640339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
8650339a1c2SMark Johnston
8660339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("vcmppd",VEX_RMRX,16), INVALID,
8670339a1c2SMark Johnston /* [C4] */ TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR), TNSZ("vshufpd",VEX_RMRX,16), INVALID,
8680339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
8690339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
8700339a1c2SMark Johnston
8710339a1c2SMark Johnston /* [D0] */ TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16), TNSZ("vpsrld",VEX_RMrX,16), TNSZ("vpsrlq",VEX_RMrX,16),
8720339a1c2SMark Johnston /* [D4] */ TNSZ("vpaddq",VEX_RMrX,16), TNSZ("vpmullw",VEX_RMrX,16), TNSZ("vmovq",VEX_RX,8), TNS("vpmovmskb",VEX_MR),
8730339a1c2SMark Johnston /* [D8] */ TNSZ("vpsubusb",VEX_RMrX,16), TNSZ("vpsubusw",VEX_RMrX,16), TNSZ("vpminub",VEX_RMrX,16), TNSZ("vpand",VEX_RMrX,16),
8740339a1c2SMark Johnston /* [DC] */ TNSZ("vpaddusb",VEX_RMrX,16), TNSZ("vpaddusw",VEX_RMrX,16), TNSZ("vpmaxub",VEX_RMrX,16), TNSZ("vpandn",VEX_RMrX,16),
8750339a1c2SMark Johnston
8760339a1c2SMark Johnston /* [E0] */ TNSZ("vpavgb",VEX_RMrX,16), TNSZ("vpsraw",VEX_RMrX,16), TNSZ("vpsrad",VEX_RMrX,16), TNSZ("vpavgw",VEX_RMrX,16),
8770339a1c2SMark Johnston /* [E4] */ TNSZ("vpmulhuw",VEX_RMrX,16), TNSZ("vpmulhw",VEX_RMrX,16), TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
8780339a1c2SMark Johnston /* [E8] */ TNSZ("vpsubsb",VEX_RMrX,16), TNSZ("vpsubsw",VEX_RMrX,16), TNSZ("vpminsw",VEX_RMrX,16), TNSZ("vpor",VEX_RMrX,16),
8790339a1c2SMark Johnston /* [EC] */ TNSZ("vpaddsb",VEX_RMrX,16), TNSZ("vpaddsw",VEX_RMrX,16), TNSZ("vpmaxsw",VEX_RMrX,16), TNSZ("vpxor",VEX_RMrX,16),
8800339a1c2SMark Johnston
8810339a1c2SMark Johnston /* [F0] */ INVALID, TNSZ("vpsllw",VEX_RMrX,16), TNSZ("vpslld",VEX_RMrX,16), TNSZ("vpsllq",VEX_RMrX,16),
8820339a1c2SMark Johnston /* [F4] */ TNSZ("vpmuludq",VEX_RMrX,16), TNSZ("vpmaddwd",VEX_RMrX,16), TNSZ("vpsadbw",VEX_RMrX,16), TNS("vmaskmovdqu",VEX_MX),
8830339a1c2SMark Johnston /* [F8] */ TNSZ("vpsubb",VEX_RMrX,16), TNSZ("vpsubw",VEX_RMrX,16), TNSZ("vpsubd",VEX_RMrX,16), TNSZ("vpsubq",VEX_RMrX,16),
8840339a1c2SMark Johnston /* [FC] */ TNSZ("vpaddb",VEX_RMrX,16), TNSZ("vpaddw",VEX_RMrX,16), TNSZ("vpaddd",VEX_RMrX,16), INVALID,
8850339a1c2SMark Johnston };
8860339a1c2SMark Johnston
8870339a1c2SMark Johnston /*
8880339a1c2SMark Johnston * Decode table for SIMD instructions with the repnz (0xf2) prefix.
8890339a1c2SMark Johnston */
8900339a1c2SMark Johnston const instable_t dis_opSIMDrepnz[256] = {
8910339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
8920339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
8930339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
8940339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
8950339a1c2SMark Johnston
896b3b5bfebSMark Johnston /* [10] */ TNSZ("movsd",XMM,8), TNSZ("movsd",XMMS,8), TNSZ("movddup",XMM,8), INVALID,
8970339a1c2SMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
8980339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
8990339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
9000339a1c2SMark Johnston
9010339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
9020339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
9030339a1c2SMark Johnston /* [28] */ INVALID, INVALID, TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
9040339a1c2SMark Johnston /* [2C] */ TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID, INVALID,
9050339a1c2SMark Johnston
9060339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
9070339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
9080339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
9090339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
9100339a1c2SMark Johnston
9110339a1c2SMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
9120339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
9130339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
9140339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
9150339a1c2SMark Johnston
9160339a1c2SMark Johnston /* [50] */ INVALID, TNSZ("sqrtsd",XMM,8), INVALID, INVALID,
9170339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
9180339a1c2SMark Johnston /* [58] */ TNSZ("addsd",XMM,8), TNSZ("mulsd",XMM,8), TNSZ("cvtsd2ss",XMM,8), INVALID,
9190339a1c2SMark Johnston /* [5C] */ TNSZ("subsd",XMM,8), TNSZ("minsd",XMM,8), TNSZ("divsd",XMM,8), TNSZ("maxsd",XMM,8),
9200339a1c2SMark Johnston
9210339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
9220339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
9230339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
9240339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
9250339a1c2SMark Johnston
9260339a1c2SMark Johnston /* [70] */ TNSZ("pshuflw",XMMP,16),INVALID, INVALID, INVALID,
9270339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
9280339a1c2SMark Johnston /* [78] */ TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID, INVALID,
929b3b5bfebSMark Johnston /* [7C] */ TNSZ("haddps",XMM,16), TNSZ("hsubps",XMM,16), INVALID, INVALID,
9300339a1c2SMark Johnston
9310339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
9320339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
9330339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
9340339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
9350339a1c2SMark Johnston
9360339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
9370339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
9380339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
9390339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
9400339a1c2SMark Johnston
9410339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
9420339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
9430339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
9440339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
9450339a1c2SMark Johnston
9460339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
9470339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
9480339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
9490339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
9500339a1c2SMark Johnston
9510339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("cmpsd",XMMP,8), INVALID,
9520339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
9530339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
9540339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
9550339a1c2SMark Johnston
956b3b5bfebSMark Johnston /* [D0] */ TNSZ("addsubps",XMM,16),INVALID, INVALID, INVALID,
9570339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, TNS("movdq2q",XMMXM), INVALID,
9580339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
9590339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
9600339a1c2SMark Johnston
9610339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
9620339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, TNSZ("cvtpd2dq",XMM,16),INVALID,
9630339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
9640339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
9650339a1c2SMark Johnston
966b3b5bfebSMark Johnston /* [F0] */ TNS("lddqu",XMMM), INVALID, INVALID, INVALID,
9670339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
9680339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
9690339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
9700339a1c2SMark Johnston };
9710339a1c2SMark Johnston
9720339a1c2SMark Johnston const instable_t dis_opAVXF20F[256] = {
9730339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
9740339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
9750339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
9760339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
9770339a1c2SMark Johnston
9780339a1c2SMark Johnston /* [10] */ TNSZ("vmovsd",VEX_RMrX,8), TNSZ("vmovsd",VEX_RRX,8), TNSZ("vmovddup",VEX_MX,8), INVALID,
9790339a1c2SMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
9800339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
9810339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
9820339a1c2SMark Johnston
9830339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
9840339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
9850339a1c2SMark Johnston /* [28] */ INVALID, INVALID, TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
9860339a1c2SMark Johnston /* [2C] */ TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID, INVALID,
9870339a1c2SMark Johnston
9880339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
9890339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
9900339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
9910339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
9920339a1c2SMark Johnston
9930339a1c2SMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
9940339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
9950339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
9960339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
9970339a1c2SMark Johnston
9980339a1c2SMark Johnston /* [50] */ INVALID, TNSZ("vsqrtsd",VEX_RMrX,8), INVALID, INVALID,
9990339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
10000339a1c2SMark Johnston /* [58] */ TNSZ("vaddsd",VEX_RMrX,8), TNSZ("vmulsd",VEX_RMrX,8), TNSZ("vcvtsd2ss",VEX_RMrX,8), INVALID,
10010339a1c2SMark Johnston /* [5C] */ TNSZ("vsubsd",VEX_RMrX,8), TNSZ("vminsd",VEX_RMrX,8), TNSZ("vdivsd",VEX_RMrX,8), TNSZ("vmaxsd",VEX_RMrX,8),
10020339a1c2SMark Johnston
10030339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
10040339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
10050339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
10060339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
10070339a1c2SMark Johnston
10080339a1c2SMark Johnston /* [70] */ TNSZ("vpshuflw",VEX_MXI,16),INVALID, INVALID, INVALID,
10090339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
10100339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
10110339a1c2SMark Johnston /* [7C] */ TNSZ("vhaddps",VEX_RMrX,8), TNSZ("vhsubps",VEX_RMrX,8), INVALID, INVALID,
10120339a1c2SMark Johnston
10130339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
10140339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
10150339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
10160339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
10170339a1c2SMark Johnston
1018722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),
10190339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
10200339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
10210339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
10220339a1c2SMark Johnston
10230339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
10240339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
10250339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
10260339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
10270339a1c2SMark Johnston
10280339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
10290339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
10300339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
10310339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
10320339a1c2SMark Johnston
10330339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("vcmpsd",VEX_RMRX,8), INVALID,
10340339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
10350339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
10360339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
10370339a1c2SMark Johnston
10380339a1c2SMark Johnston /* [D0] */ TNSZ("vaddsubps",VEX_RMrX,8), INVALID, INVALID, INVALID,
10390339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
10400339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
10410339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
10420339a1c2SMark Johnston
10430339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
10440339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
10450339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
10460339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
10470339a1c2SMark Johnston
10480339a1c2SMark Johnston /* [F0] */ TNSZ("vlddqu",VEX_MX,16), INVALID, INVALID, INVALID,
10490339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
10500339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
10510339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
10520339a1c2SMark Johnston };
10530339a1c2SMark Johnston
1054b3b5bfebSMark Johnston const instable_t dis_opAVXF20F3A[256] = {
1055b3b5bfebSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1056b3b5bfebSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1057b3b5bfebSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1058b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1059b3b5bfebSMark Johnston
1060b3b5bfebSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1061b3b5bfebSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1062b3b5bfebSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1063b3b5bfebSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1064b3b5bfebSMark Johnston
1065b3b5bfebSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1066b3b5bfebSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1067b3b5bfebSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1068b3b5bfebSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1069b3b5bfebSMark Johnston
1070b3b5bfebSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1071b3b5bfebSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1072b3b5bfebSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1073b3b5bfebSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1074b3b5bfebSMark Johnston
1075b3b5bfebSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1076b3b5bfebSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1077b3b5bfebSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1078b3b5bfebSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1079b3b5bfebSMark Johnston
1080b3b5bfebSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1081b3b5bfebSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1082b3b5bfebSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1083b3b5bfebSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1084b3b5bfebSMark Johnston
1085b3b5bfebSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1086b3b5bfebSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1087b3b5bfebSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1088b3b5bfebSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1089b3b5bfebSMark Johnston
1090b3b5bfebSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1091b3b5bfebSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1092b3b5bfebSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1093b3b5bfebSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1094b3b5bfebSMark Johnston
1095b3b5bfebSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1096b3b5bfebSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1097b3b5bfebSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1098b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1099b3b5bfebSMark Johnston
1100b3b5bfebSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1101b3b5bfebSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1102b3b5bfebSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1103b3b5bfebSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1104b3b5bfebSMark Johnston
1105b3b5bfebSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1106b3b5bfebSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1107b3b5bfebSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1108b3b5bfebSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1109b3b5bfebSMark Johnston
1110b3b5bfebSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1111b3b5bfebSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1112b3b5bfebSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1113b3b5bfebSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1114b3b5bfebSMark Johnston
1115b3b5bfebSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1116b3b5bfebSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1117b3b5bfebSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1118b3b5bfebSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1119b3b5bfebSMark Johnston
1120b3b5bfebSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1121b3b5bfebSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1122b3b5bfebSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1123b3b5bfebSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1124b3b5bfebSMark Johnston
1125b3b5bfebSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1126b3b5bfebSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1127b3b5bfebSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1128b3b5bfebSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1129b3b5bfebSMark Johnston
1130b3b5bfebSMark Johnston /* [F0] */ TNSZvr("rorx",VEX_MXI,6),INVALID, INVALID, INVALID,
1131b3b5bfebSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1132b3b5bfebSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1133b3b5bfebSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1134b3b5bfebSMark Johnston };
1135b3b5bfebSMark Johnston
1136b3b5bfebSMark Johnston const instable_t dis_opAVXF20F38[256] = {
1137b3b5bfebSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1138b3b5bfebSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1139b3b5bfebSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1140b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1141b3b5bfebSMark Johnston
1142b3b5bfebSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1143b3b5bfebSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1144b3b5bfebSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1145b3b5bfebSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1146b3b5bfebSMark Johnston
1147b3b5bfebSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1148b3b5bfebSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1149b3b5bfebSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1150b3b5bfebSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1151b3b5bfebSMark Johnston
1152b3b5bfebSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1153b3b5bfebSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1154b3b5bfebSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1155b3b5bfebSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1156b3b5bfebSMark Johnston
1157b3b5bfebSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1158b3b5bfebSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1159b3b5bfebSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1160b3b5bfebSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1161b3b5bfebSMark Johnston
1162b3b5bfebSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1163b3b5bfebSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1164b3b5bfebSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1165b3b5bfebSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1166b3b5bfebSMark Johnston
1167b3b5bfebSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1168b3b5bfebSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1169b3b5bfebSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1170b3b5bfebSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1171b3b5bfebSMark Johnston
1172b3b5bfebSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1173b3b5bfebSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1174b3b5bfebSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1175b3b5bfebSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1176b3b5bfebSMark Johnston
1177b3b5bfebSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1178b3b5bfebSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1179b3b5bfebSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1180b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1181b3b5bfebSMark Johnston
1182b3b5bfebSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1183b3b5bfebSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1184b3b5bfebSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1185b3b5bfebSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1186b3b5bfebSMark Johnston
1187b3b5bfebSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1188b3b5bfebSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1189b3b5bfebSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1190b3b5bfebSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1191b3b5bfebSMark Johnston
1192b3b5bfebSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1193b3b5bfebSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1194b3b5bfebSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1195b3b5bfebSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1196b3b5bfebSMark Johnston
1197b3b5bfebSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1198b3b5bfebSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1199b3b5bfebSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1200b3b5bfebSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1201b3b5bfebSMark Johnston
1202b3b5bfebSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1203b3b5bfebSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1204b3b5bfebSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1205b3b5bfebSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1206b3b5bfebSMark Johnston
1207b3b5bfebSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1208b3b5bfebSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1209b3b5bfebSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1210b3b5bfebSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1211b3b5bfebSMark Johnston
1212b3b5bfebSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1213b3b5bfebSMark Johnston /* [F4] */ INVALID, TNSZvr("pdep",VEX_RMrX,5),TNSZvr("mulx",VEX_RMrX,5),TNSZvr("shrx",VEX_VRMrX,5),
1214b3b5bfebSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1215b3b5bfebSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1216b3b5bfebSMark Johnston };
1217b3b5bfebSMark Johnston
1218b3b5bfebSMark Johnston const instable_t dis_opAVXF30F38[256] = {
1219b3b5bfebSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1220b3b5bfebSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1221b3b5bfebSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1222b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1223b3b5bfebSMark Johnston
1224b3b5bfebSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1225b3b5bfebSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1226b3b5bfebSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1227b3b5bfebSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1228b3b5bfebSMark Johnston
1229b3b5bfebSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1230b3b5bfebSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1231b3b5bfebSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1232b3b5bfebSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1233b3b5bfebSMark Johnston
1234b3b5bfebSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1235b3b5bfebSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1236b3b5bfebSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1237b3b5bfebSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1238b3b5bfebSMark Johnston
1239b3b5bfebSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1240b3b5bfebSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1241b3b5bfebSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1242b3b5bfebSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1243b3b5bfebSMark Johnston
1244b3b5bfebSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1245b3b5bfebSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1246b3b5bfebSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1247b3b5bfebSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1248b3b5bfebSMark Johnston
1249b3b5bfebSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1250b3b5bfebSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1251b3b5bfebSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1252b3b5bfebSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1253b3b5bfebSMark Johnston
1254b3b5bfebSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1255b3b5bfebSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1256b3b5bfebSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1257b3b5bfebSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1258b3b5bfebSMark Johnston
1259b3b5bfebSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1260b3b5bfebSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1261b3b5bfebSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1262b3b5bfebSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1263b3b5bfebSMark Johnston
1264b3b5bfebSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1265b3b5bfebSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1266b3b5bfebSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1267b3b5bfebSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1268b3b5bfebSMark Johnston
1269b3b5bfebSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1270b3b5bfebSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1271b3b5bfebSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1272b3b5bfebSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1273b3b5bfebSMark Johnston
1274b3b5bfebSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1275b3b5bfebSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1276b3b5bfebSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1277b3b5bfebSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1278b3b5bfebSMark Johnston
1279b3b5bfebSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1280b3b5bfebSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1281b3b5bfebSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1282b3b5bfebSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1283b3b5bfebSMark Johnston
1284b3b5bfebSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1285b3b5bfebSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1286b3b5bfebSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1287b3b5bfebSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1288b3b5bfebSMark Johnston
1289b3b5bfebSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1290b3b5bfebSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1291b3b5bfebSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1292b3b5bfebSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1293b3b5bfebSMark Johnston
1294b3b5bfebSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1295b3b5bfebSMark Johnston /* [F4] */ INVALID, TNSZvr("pext",VEX_RMrX,5),INVALID, TNSZvr("sarx",VEX_VRMrX,5),
1296b3b5bfebSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1297b3b5bfebSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1298b3b5bfebSMark Johnston };
12990339a1c2SMark Johnston /*
13000339a1c2SMark Johnston * Decode table for SIMD instructions with the repz (0xf3) prefix.
13010339a1c2SMark Johnston */
13020339a1c2SMark Johnston const instable_t dis_opSIMDrepz[256] = {
13030339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
13040339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
13050339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
13060339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
13070339a1c2SMark Johnston
1308b3b5bfebSMark Johnston /* [10] */ TNSZ("movss",XMM,4), TNSZ("movss",XMMS,4), TNSZ("movsldup",XMM,16),INVALID,
1309b3b5bfebSMark Johnston /* [14] */ INVALID, INVALID, TNSZ("movshdup",XMM,16),INVALID,
13100339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
13110339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
13120339a1c2SMark Johnston
13130339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
13140339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
13150339a1c2SMark Johnston /* [28] */ INVALID, INVALID, TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
13160339a1c2SMark Johnston /* [2C] */ TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID, INVALID,
13170339a1c2SMark Johnston
13180339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
13190339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
13200339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
13210339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
13220339a1c2SMark Johnston
13230339a1c2SMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
13240339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
13250339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
13260339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
13270339a1c2SMark Johnston
13280339a1c2SMark Johnston /* [50] */ INVALID, TNSZ("sqrtss",XMM,4), TNSZ("rsqrtss",XMM,4), TNSZ("rcpss",XMM,4),
13290339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
13300339a1c2SMark Johnston /* [58] */ TNSZ("addss",XMM,4), TNSZ("mulss",XMM,4), TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16),
13310339a1c2SMark Johnston /* [5C] */ TNSZ("subss",XMM,4), TNSZ("minss",XMM,4), TNSZ("divss",XMM,4), TNSZ("maxss",XMM,4),
13320339a1c2SMark Johnston
13330339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
13340339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
13350339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
13360339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, TNSZ("movdqu",XMM,16),
13370339a1c2SMark Johnston
13380339a1c2SMark Johnston /* [70] */ TNSZ("pshufhw",XMMP,16),INVALID, INVALID, INVALID,
13390339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
13400339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
13410339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, TNSZ("movq",XMM,8), TNSZ("movdqu",XMMS,16),
13420339a1c2SMark Johnston
13430339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
13440339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
13450339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
13460339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
13470339a1c2SMark Johnston
13480339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
13490339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
13500339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
13510339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
13520339a1c2SMark Johnston
13530339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
13540339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
13550339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
13560339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
13570339a1c2SMark Johnston
13580339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
13590339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
13600339a1c2SMark Johnston /* [B8] */ TS("popcnt",MRw), INVALID, INVALID, INVALID,
1361b3b5bfebSMark Johnston /* [BC] */ TNSZ("tzcnt",MRw,5), TS("lzcnt",MRw), INVALID, INVALID,
13620339a1c2SMark Johnston
13630339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("cmpss",XMMP,4), INVALID,
13640339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
13650339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
13660339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
13670339a1c2SMark Johnston
13680339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
13690339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, TNS("movq2dq",XMMMX), INVALID,
13700339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
13710339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
13720339a1c2SMark Johnston
13730339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
13740339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, TNSZ("cvtdq2pd",XMM,8), INVALID,
13750339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
13760339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
13770339a1c2SMark Johnston
13780339a1c2SMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
13790339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
13800339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
13810339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
13820339a1c2SMark Johnston };
13830339a1c2SMark Johnston
13840339a1c2SMark Johnston const instable_t dis_opAVXF30F[256] = {
13850339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
13860339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
13870339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
13880339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
13890339a1c2SMark Johnston
13900339a1c2SMark Johnston /* [10] */ TNSZ("vmovss",VEX_RMrX,4), TNSZ("vmovss",VEX_RRX,4), TNSZ("vmovsldup",VEX_MX,4), INVALID,
13910339a1c2SMark Johnston /* [14] */ INVALID, INVALID, TNSZ("vmovshdup",VEX_MX,4), INVALID,
13920339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
13930339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
13940339a1c2SMark Johnston
13950339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
13960339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
13970339a1c2SMark Johnston /* [28] */ INVALID, INVALID, TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
13980339a1c2SMark Johnston /* [2C] */ TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID, INVALID,
13990339a1c2SMark Johnston
14000339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
14010339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
14020339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
14030339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
14040339a1c2SMark Johnston
14050339a1c2SMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
14060339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
14070339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
14080339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
14090339a1c2SMark Johnston
14100339a1c2SMark Johnston /* [50] */ INVALID, TNSZ("vsqrtss",VEX_RMrX,4), TNSZ("vrsqrtss",VEX_RMrX,4), TNSZ("vrcpss",VEX_RMrX,4),
14110339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
14120339a1c2SMark Johnston /* [58] */ TNSZ("vaddss",VEX_RMrX,4), TNSZ("vmulss",VEX_RMrX,4), TNSZ("vcvtss2sd",VEX_RMrX,4), TNSZ("vcvttps2dq",VEX_MX,16),
14130339a1c2SMark Johnston /* [5C] */ TNSZ("vsubss",VEX_RMrX,4), TNSZ("vminss",VEX_RMrX,4), TNSZ("vdivss",VEX_RMrX,4), TNSZ("vmaxss",VEX_RMrX,4),
14140339a1c2SMark Johnston
14150339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
14160339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
14170339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
14180339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, TNSZ("vmovdqu",VEX_MX,16),
14190339a1c2SMark Johnston
14200339a1c2SMark Johnston /* [70] */ TNSZ("vpshufhw",VEX_MXI,16),INVALID, INVALID, INVALID,
14210339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
14220339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
14230339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, TNSZ("vmovq",VEX_MX,8), TNSZ("vmovdqu",VEX_RX,16),
14240339a1c2SMark Johnston
14250339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
14260339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
14270339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
14280339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
14290339a1c2SMark Johnston
14300339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
14310339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
14320339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
14330339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
14340339a1c2SMark Johnston
14350339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
14360339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
14370339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
14380339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
14390339a1c2SMark Johnston
14400339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
14410339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
14420339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
14430339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
14440339a1c2SMark Johnston
14450339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("vcmpss",VEX_RMRX,4), INVALID,
14460339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
14470339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
14480339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
14490339a1c2SMark Johnston
14500339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
14510339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
14520339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
14530339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
14540339a1c2SMark Johnston
14550339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
14560339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, TNSZ("vcvtdq2pd",VEX_MX,8), INVALID,
14570339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
14580339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
14590339a1c2SMark Johnston
14600339a1c2SMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
14610339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
14620339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
14630339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
14640339a1c2SMark Johnston };
1465722b2e2fSMark Johnston
1466722b2e2fSMark Johnston /*
1467722b2e2fSMark Johnston * Table for instructions with an EVEX prefix followed by 0F.
1468722b2e2fSMark Johnston */
1469722b2e2fSMark Johnston const instable_t dis_opEVEX0F[256] = {
1470722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1471722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1472722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1473722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1474722b2e2fSMark Johnston
1475722b2e2fSMark Johnston /* [10] */ TNS("vmovups",EVEX_MX), TNS("vmovups",EVEX_RX), INVALID, INVALID,
1476722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1477722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1478722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1479722b2e2fSMark Johnston
1480722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1481722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1482722b2e2fSMark Johnston /* [28] */ TNS("vmovaps",EVEX_MX), TNS("vmovaps",EVEX_RX), INVALID, INVALID,
1483722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1484722b2e2fSMark Johnston
1485722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1486722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1487722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1488722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1489722b2e2fSMark Johnston
1490722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1491722b2e2fSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1492722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1493722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1494722b2e2fSMark Johnston
1495722b2e2fSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1496722b2e2fSMark Johnston /* [54] */ TNS("vandps",EVEX_RMrX),TNS("vandnps",EVEX_RMrX),TNS("vorps",EVEX_RMrX),TNS("vxorps",EVEX_RMrX),
1497722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1498722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1499722b2e2fSMark Johnston
1500722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1501722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1502722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1503722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1504722b2e2fSMark Johnston
1505722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1506722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1507722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1508722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1509722b2e2fSMark Johnston
1510722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1511722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1512722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1513722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1514722b2e2fSMark Johnston
1515722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1516722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1517722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1518722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1519722b2e2fSMark Johnston
1520722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1521722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1522722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1523722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1524722b2e2fSMark Johnston
1525722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1526722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1527722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1528722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1529722b2e2fSMark Johnston
1530722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1531722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1532722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1533722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1534722b2e2fSMark Johnston
1535722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1536722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1537722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1538722b2e2fSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1539722b2e2fSMark Johnston
1540722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1541722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1542722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1543722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1544722b2e2fSMark Johnston
1545722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1546722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1547722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1548722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1549722b2e2fSMark Johnston };
1550722b2e2fSMark Johnston
1551722b2e2fSMark Johnston /*
1552722b2e2fSMark Johnston * Decode tables for EVEX 66 0F
1553722b2e2fSMark Johnston */
1554722b2e2fSMark Johnston const instable_t dis_opEVEX660F[256] = {
1555722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1556722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1557722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1558722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1559722b2e2fSMark Johnston
1560722b2e2fSMark Johnston /* [10] */ TNS("vmovupd",EVEX_MX), TNS("vmovupd",EVEX_RX), INVALID, INVALID,
1561722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1562722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1563722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1564722b2e2fSMark Johnston
1565722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1566722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1567722b2e2fSMark Johnston /* [28] */ TNS("vmovapd",EVEX_MX), TNS("vmovapd",EVEX_RX), INVALID, INVALID,
1568722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1569722b2e2fSMark Johnston
1570722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1571722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1572722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1573722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1574722b2e2fSMark Johnston
1575722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1576722b2e2fSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1577722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1578722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1579722b2e2fSMark Johnston
1580722b2e2fSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1581722b2e2fSMark Johnston /* [54] */ TNS("vandpd",EVEX_RMrX),TNS("vandnpd",EVEX_RMrX),TNS("vorpd",EVEX_RMrX),TNS("vxorpd",EVEX_RMrX),
1582722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1583722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1584722b2e2fSMark Johnston
1585722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1586722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1587722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1588722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqa",EVEX_MX),
1589722b2e2fSMark Johnston
1590722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1591722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1592722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1593722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqa",EVEX_RX),
1594722b2e2fSMark Johnston
1595722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1596722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1597722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1598722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1599722b2e2fSMark Johnston
1600722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1601722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1602722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1603722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1604722b2e2fSMark Johnston
1605722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1606722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1607722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1608722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1609722b2e2fSMark Johnston
1610722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1611722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1612722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1613722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1614722b2e2fSMark Johnston
1615722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1616722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1617722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1618722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1619722b2e2fSMark Johnston
1620722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1621722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1622722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, TSq("vpand",EVEX_RMrX),
1623722b2e2fSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, TSq("vpandn",EVEX_RMrX),
1624722b2e2fSMark Johnston
1625722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1626722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1627722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, TSq("vpor",EVEX_RMrX),
1628722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, TSq("vpxor",EVEX_RMrX),
1629722b2e2fSMark Johnston
1630722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1631722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1632722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1633722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1634722b2e2fSMark Johnston };
1635722b2e2fSMark Johnston
1636722b2e2fSMark Johnston const instable_t dis_opEVEX660F38[256] = {
1637722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1638722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1639722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1640722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1641722b2e2fSMark Johnston
1642722b2e2fSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1643722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1644722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1645722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1646722b2e2fSMark Johnston
1647722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1648722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1649722b2e2fSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1650722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1651722b2e2fSMark Johnston
1652722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1653722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1654722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1655722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1656722b2e2fSMark Johnston
1657722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1658722b2e2fSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1659722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1660722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1661722b2e2fSMark Johnston
1662722b2e2fSMark Johnston /* [50] */ TNSZ("vpdpbusd",EVEX_RMrX,16),TNSZ("vpdpbusds",EVEX_RMrX,16),TNSZ("vpdpwssd",EVEX_RMrX,16),TNSZ("vpdpwssds",EVEX_RMrX,16),
1663722b2e2fSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1664722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1665722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1666722b2e2fSMark Johnston
1667722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1668722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1669722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1670722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1671722b2e2fSMark Johnston
1672722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1673722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1674722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1675722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1676722b2e2fSMark Johnston
1677722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1678722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1679722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1680722b2e2fSMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
1681722b2e2fSMark Johnston
1682722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1683722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1684722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1685722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1686722b2e2fSMark Johnston
1687722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1688722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1689722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1690722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1691722b2e2fSMark Johnston
1692722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1693722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1694722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1695722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1696722b2e2fSMark Johnston
1697722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1698722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1699722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1700722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, TNS("vgf2p8mulb",EVEX_RMrX),
1701722b2e2fSMark Johnston
1702722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1703722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1704722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1705722b2e2fSMark Johnston /* [DC] */ TNSZ("vaesenc",EVEX_RMrX,16),TNSZ("vaesenclast",EVEX_RMrX,16),TNSZ("vaesdec",EVEX_RMrX,16),TNSZ("vaesdeclast",EVEX_RMrX,16),
1706722b2e2fSMark Johnston
1707722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1708722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1709722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1710722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1711722b2e2fSMark Johnston
1712722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1713722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1714722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1715722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1716722b2e2fSMark Johnston };
1717722b2e2fSMark Johnston
1718722b2e2fSMark Johnston const instable_t dis_opEVEX660F3A[256] = {
1719722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1720722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1721722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1722722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1723722b2e2fSMark Johnston
1724722b2e2fSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1725722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1726722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1727722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1728722b2e2fSMark Johnston
1729722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1730722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1731722b2e2fSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1732722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1733722b2e2fSMark Johnston
1734722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1735722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1736722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1737722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1738722b2e2fSMark Johnston
1739722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1740722b2e2fSMark Johnston /* [44] */ TNSZ("vpclmulqdq",EVEX_RMRX,16),INVALID, INVALID, INVALID,
1741722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1742722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1743722b2e2fSMark Johnston
1744722b2e2fSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1745722b2e2fSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1746722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1747722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1748722b2e2fSMark Johnston
1749722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1750722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1751722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1752722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
1753722b2e2fSMark Johnston
1754722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1755722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1756722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1757722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
1758722b2e2fSMark Johnston
1759722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1760722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1761722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1762722b2e2fSMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
1763722b2e2fSMark Johnston
1764722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1765722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1766722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1767722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1768722b2e2fSMark Johnston
1769722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1770722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1771722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1772722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1773722b2e2fSMark Johnston
1774722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1775722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1776722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1777722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1778722b2e2fSMark Johnston
1779722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1780722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1781722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1782722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, TNS("vgf2p8affineqb",EVEX_RMRX),TNS("vgf2p8affineinvqb",EVEX_RMRX),
1783722b2e2fSMark Johnston
1784722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1785722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1786722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1787722b2e2fSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1788722b2e2fSMark Johnston
1789722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1790722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1791722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1792722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1793722b2e2fSMark Johnston
1794722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1795722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1796722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1797722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1798722b2e2fSMark Johnston };
1799722b2e2fSMark Johnston
1800722b2e2fSMark Johnston
1801722b2e2fSMark Johnston const instable_t dis_opEVEXF20F[256] = {
1802722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1803722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1804722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1805722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1806722b2e2fSMark Johnston
1807722b2e2fSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1808722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1809722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1810722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1811722b2e2fSMark Johnston
1812722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1813722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1814722b2e2fSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1815722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1816722b2e2fSMark Johnston
1817722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1818722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1819722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1820722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1821722b2e2fSMark Johnston
1822722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1823722b2e2fSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1824722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1825722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1826722b2e2fSMark Johnston
1827722b2e2fSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1828722b2e2fSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1829722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1830722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1831722b2e2fSMark Johnston
1832722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1833722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1834722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1835722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_MX),
1836722b2e2fSMark Johnston
1837722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1838722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1839722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1840722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_RX),
1841722b2e2fSMark Johnston
1842722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1843722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1844722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1845722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1846722b2e2fSMark Johnston
1847722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1848722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1849722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1850722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1851722b2e2fSMark Johnston
1852722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1853722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1854722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1855722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1856722b2e2fSMark Johnston
1857722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1858722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1859722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1860722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1861722b2e2fSMark Johnston
1862722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1863722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1864722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1865722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1866722b2e2fSMark Johnston
1867722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1868722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1869722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1870722b2e2fSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1871722b2e2fSMark Johnston
1872722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1873722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1874722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1875722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1876722b2e2fSMark Johnston
1877722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1878722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1879722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1880722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1881722b2e2fSMark Johnston };
1882722b2e2fSMark Johnston
1883722b2e2fSMark Johnston const instable_t dis_opEVEXF30F[256] = {
1884722b2e2fSMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
1885722b2e2fSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
1886722b2e2fSMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
1887722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1888722b2e2fSMark Johnston
1889722b2e2fSMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
1890722b2e2fSMark Johnston /* [14] */ INVALID, INVALID, INVALID, INVALID,
1891722b2e2fSMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
1892722b2e2fSMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
1893722b2e2fSMark Johnston
1894722b2e2fSMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
1895722b2e2fSMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
1896722b2e2fSMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
1897722b2e2fSMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
1898722b2e2fSMark Johnston
1899722b2e2fSMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
1900722b2e2fSMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
1901722b2e2fSMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
1902722b2e2fSMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
1903722b2e2fSMark Johnston
1904722b2e2fSMark Johnston /* [40] */ INVALID, INVALID, INVALID, INVALID,
1905722b2e2fSMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
1906722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
1907722b2e2fSMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
1908722b2e2fSMark Johnston
1909722b2e2fSMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
1910722b2e2fSMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
1911722b2e2fSMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
1912722b2e2fSMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
1913722b2e2fSMark Johnston
1914722b2e2fSMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
1915722b2e2fSMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
1916722b2e2fSMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
1917722b2e2fSMark Johnston /* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_MX),
1918722b2e2fSMark Johnston
1919722b2e2fSMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
1920722b2e2fSMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
1921722b2e2fSMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
1922722b2e2fSMark Johnston /* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_RX),
1923722b2e2fSMark Johnston
1924722b2e2fSMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
1925722b2e2fSMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
1926722b2e2fSMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
1927722b2e2fSMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
1928722b2e2fSMark Johnston
1929722b2e2fSMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
1930722b2e2fSMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
1931722b2e2fSMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
1932722b2e2fSMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
1933722b2e2fSMark Johnston
1934722b2e2fSMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
1935722b2e2fSMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
1936722b2e2fSMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
1937722b2e2fSMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
1938722b2e2fSMark Johnston
1939722b2e2fSMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
1940722b2e2fSMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
1941722b2e2fSMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
1942722b2e2fSMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
1943722b2e2fSMark Johnston
1944722b2e2fSMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
1945722b2e2fSMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
1946722b2e2fSMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
1947722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
1948722b2e2fSMark Johnston
1949722b2e2fSMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
1950722b2e2fSMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
1951722b2e2fSMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
1952722b2e2fSMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
1953722b2e2fSMark Johnston
1954722b2e2fSMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
1955722b2e2fSMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
1956722b2e2fSMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
1957722b2e2fSMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
1958722b2e2fSMark Johnston
1959722b2e2fSMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
1960722b2e2fSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
1961722b2e2fSMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
1962722b2e2fSMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
1963722b2e2fSMark Johnston };
19640339a1c2SMark Johnston /*
19650339a1c2SMark Johnston * The following two tables are used to encode crc32 and movbe
19660339a1c2SMark Johnston * since they share the same opcodes.
19670339a1c2SMark Johnston */
19680339a1c2SMark Johnston const instable_t dis_op0F38F0[2] = {
19690339a1c2SMark Johnston /* [00] */ TNS("crc32b",CRC32),
19700339a1c2SMark Johnston TS("movbe",MOVBE),
19710339a1c2SMark Johnston };
19720339a1c2SMark Johnston
19730339a1c2SMark Johnston const instable_t dis_op0F38F1[2] = {
19740339a1c2SMark Johnston /* [00] */ TS("crc32",CRC32),
19750339a1c2SMark Johnston TS("movbe",MOVBE),
19760339a1c2SMark Johnston };
19770339a1c2SMark Johnston
1978b3b5bfebSMark Johnston /*
1979b3b5bfebSMark Johnston * The following table is used to distinguish between adox and adcx which share
1980b3b5bfebSMark Johnston * the same opcodes.
1981b3b5bfebSMark Johnston */
1982b3b5bfebSMark Johnston const instable_t dis_op0F38F6[2] = {
1983b3b5bfebSMark Johnston /* [00] */ TNS("adcx",ADX),
1984b3b5bfebSMark Johnston TNS("adox",ADX),
1985b3b5bfebSMark Johnston };
1986b3b5bfebSMark Johnston
19870339a1c2SMark Johnston const instable_t dis_op0F38[256] = {
19880339a1c2SMark Johnston /* [00] */ TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
19890339a1c2SMark Johnston /* [04] */ TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
19900339a1c2SMark Johnston /* [08] */ TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
19910339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
19920339a1c2SMark Johnston
19930339a1c2SMark Johnston /* [10] */ TNSZ("pblendvb",XMM_66r,16),INVALID, INVALID, INVALID,
19940339a1c2SMark Johnston /* [14] */ TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID, TNSZ("ptest",XMM_66r,16),
19950339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
19960339a1c2SMark Johnston /* [1C] */ TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
19970339a1c2SMark Johnston
19980339a1c2SMark Johnston /* [20] */ TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
19990339a1c2SMark Johnston /* [24] */ TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID, INVALID,
20000339a1c2SMark Johnston /* [28] */ TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
20010339a1c2SMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
20020339a1c2SMark Johnston
20030339a1c2SMark Johnston /* [30] */ TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
20040339a1c2SMark Johnston /* [34] */ TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID, TNSZ("pcmpgtq",XMM_66r,16),
20050339a1c2SMark Johnston /* [38] */ TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
20060339a1c2SMark Johnston /* [3C] */ TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
20070339a1c2SMark Johnston
20080339a1c2SMark Johnston /* [40] */ TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID, INVALID,
20090339a1c2SMark Johnston /* [44] */ INVALID, INVALID, INVALID, INVALID,
20100339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
20110339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
20120339a1c2SMark Johnston
20130339a1c2SMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
20140339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
20150339a1c2SMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
20160339a1c2SMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
20170339a1c2SMark Johnston
20180339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
20190339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
20200339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
20210339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
20220339a1c2SMark Johnston
20230339a1c2SMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
20240339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
20250339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
20260339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
20270339a1c2SMark Johnston
202827b6c497SAndriy Gapon /* [80] */ TNSy("invept", RM_66r), TNSy("invvpid", RM_66r),TNSy("invpcid", RM_66r),INVALID,
20290339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
20300339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
20310339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
20320339a1c2SMark Johnston
20330339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
20340339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
20350339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
20360339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
20370339a1c2SMark Johnston
20380339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
20390339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
20400339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
20410339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
20420339a1c2SMark Johnston
20430339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
20440339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
20450339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
20460339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
20470339a1c2SMark Johnston
20480339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
20490339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
2050b3b5bfebSMark Johnston /* [C8] */ TNSZ("sha1nexte",XMM,16),TNSZ("sha1msg1",XMM,16),TNSZ("sha1msg2",XMM,16),TNSZ("sha256rnds2",XMM,16),
2051722b2e2fSMark Johnston /* [CC] */ TNSZ("sha256msg1",XMM,16),TNSZ("sha256msg2",XMM,16),INVALID, TNS("gf2p8mulb",XMM_66r),
20520339a1c2SMark Johnston
20530339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
20540339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
20550339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, TNSZ("aesimc",XMM_66r,16),
20560339a1c2SMark Johnston /* [DC] */ TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
20570339a1c2SMark Johnston
20580339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
20590339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
20600339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
20610339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
20620339a1c2SMark Johnston /* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID,
2063b3b5bfebSMark Johnston /* [F4] */ INVALID, INVALID, IND(dis_op0F38F6), INVALID,
20640339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
20650339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
20660339a1c2SMark Johnston };
20670339a1c2SMark Johnston
20680339a1c2SMark Johnston const instable_t dis_opAVX660F38[256] = {
20690339a1c2SMark Johnston /* [00] */ TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
20700339a1c2SMark Johnston /* [04] */ TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16), TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
20710339a1c2SMark Johnston /* [08] */ TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
20720339a1c2SMark Johnston /* [0C] */ TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8), TNSZ("vtestpd",VEX_RRI,16),
20730339a1c2SMark Johnston
2074c3ddb60eSPeter Grehan /* [10] */ INVALID, INVALID, INVALID, TNSZ("vcvtph2ps",VEX_MX,16),
2075b3b5bfebSMark Johnston /* [14] */ INVALID, INVALID, TNSZ("vpermps",VEX_RMrX,16),TNSZ("vptest",VEX_RRI,16),
20760339a1c2SMark Johnston /* [18] */ TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
20770339a1c2SMark Johnston /* [1C] */ TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
20780339a1c2SMark Johnston
20790339a1c2SMark Johnston /* [20] */ TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
20800339a1c2SMark Johnston /* [24] */ TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID, INVALID,
20810339a1c2SMark Johnston /* [28] */ TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
20820339a1c2SMark Johnston /* [2C] */ TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
20830339a1c2SMark Johnston
20840339a1c2SMark Johnston /* [30] */ TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
2085b3b5bfebSMark Johnston /* [34] */ TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),TNSZ("vpermd",VEX_RMrX,16),TNSZ("vpcmpgtq",VEX_RMrX,16),
20860339a1c2SMark Johnston /* [38] */ TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
20870339a1c2SMark Johnston /* [3C] */ TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
20880339a1c2SMark Johnston
20890339a1c2SMark Johnston /* [40] */ TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID, INVALID,
2090b3b5bfebSMark Johnston /* [44] */ INVALID, TSaZ("vpsrlv",VEX_RMrX,16),TNSZ("vpsravd",VEX_RMrX,16),TSaZ("vpsllv",VEX_RMrX,16),
20910339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
20920339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
20930339a1c2SMark Johnston
20940339a1c2SMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
20950339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
2096b3b5bfebSMark Johnston /* [58] */ TNSZ("vpbroadcastd",VEX_MX,16),TNSZ("vpbroadcastq",VEX_MX,16),TNSZ("vbroadcasti128",VEX_MX,16),INVALID,
20970339a1c2SMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
20980339a1c2SMark Johnston
20990339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
21000339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
21010339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
21020339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
21030339a1c2SMark Johnston
21040339a1c2SMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
21050339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
2106b3b5bfebSMark Johnston /* [78] */ TNSZ("vpbroadcastb",VEX_MX,16),TNSZ("vpbroadcastw",VEX_MX,16),INVALID, INVALID,
21070339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
21080339a1c2SMark Johnston
21090339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
21100339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
21110339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
2112b3b5bfebSMark Johnston /* [8C] */ TSaZ("vpmaskmov",VEX_RMrX,16),INVALID, TSaZ("vpmaskmov",VEX_RRM,16),INVALID,
21130339a1c2SMark Johnston
2114b3b5bfebSMark Johnston /* [90] */ TNSZ("vpgatherd",VEX_SbVM,16),TNSZ("vpgatherq",VEX_SbVM,16),TNSZ("vgatherdp",VEX_SbVM,16),TNSZ("vgatherqp",VEX_SbVM,16),
2115b3b5bfebSMark Johnston /* [94] */ INVALID, INVALID, TNSZ("vfmaddsub132p",FMA,16),TNSZ("vfmsubadd132p",FMA,16),
2116b3b5bfebSMark Johnston /* [98] */ TNSZ("vfmadd132p",FMA,16),TNSZ("vfmadd132s",FMA,16),TNSZ("vfmsub132p",FMA,16),TNSZ("vfmsub132s",FMA,16),
2117b3b5bfebSMark Johnston /* [9C] */ TNSZ("vfnmadd132p",FMA,16),TNSZ("vfnmadd132s",FMA,16),TNSZ("vfnmsub132p",FMA,16),TNSZ("vfnmsub132s",FMA,16),
21180339a1c2SMark Johnston
21190339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
2120b3b5bfebSMark Johnston /* [A4] */ INVALID, INVALID, TNSZ("vfmaddsub213p",FMA,16),TNSZ("vfmsubadd213p",FMA,16),
2121b3b5bfebSMark Johnston /* [A8] */ TNSZ("vfmadd213p",FMA,16),TNSZ("vfmadd213s",FMA,16),TNSZ("vfmsub213p",FMA,16),TNSZ("vfmsub213s",FMA,16),
2122b3b5bfebSMark Johnston /* [AC] */ TNSZ("vfnmadd213p",FMA,16),TNSZ("vfnmadd213s",FMA,16),TNSZ("vfnmsub213p",FMA,16),TNSZ("vfnmsub213s",FMA,16),
21230339a1c2SMark Johnston
21240339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
2125b3b5bfebSMark Johnston /* [B4] */ INVALID, INVALID, TNSZ("vfmaddsub231p",FMA,16),TNSZ("vfmsubadd231p",FMA,16),
2126b3b5bfebSMark Johnston /* [B8] */ TNSZ("vfmadd231p",FMA,16),TNSZ("vfmadd231s",FMA,16),TNSZ("vfmsub231p",FMA,16),TNSZ("vfmsub231s",FMA,16),
2127b3b5bfebSMark Johnston /* [BC] */ TNSZ("vfnmadd231p",FMA,16),TNSZ("vfnmadd231s",FMA,16),TNSZ("vfnmsub231p",FMA,16),TNSZ("vfnmsub231s",FMA,16),
21280339a1c2SMark Johnston
21290339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
21300339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
21310339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
2132722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, INVALID, TNS("vgf2p8mulb",VEX_RMrX),
21330339a1c2SMark Johnston
21340339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
21350339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
21360339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, TNSZ("vaesimc",VEX_MX,16),
21370339a1c2SMark Johnston /* [DC] */ TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
21380339a1c2SMark Johnston
21390339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
21400339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
21410339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
21420339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
21430339a1c2SMark Johnston /* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID,
2144b3b5bfebSMark Johnston /* [F4] */ INVALID, INVALID, INVALID, TNSZvr("shlx",VEX_VRMrX,5),
21450339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
21460339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
21470339a1c2SMark Johnston };
21480339a1c2SMark Johnston
21490339a1c2SMark Johnston const instable_t dis_op0F3A[256] = {
21500339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
21510339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
21520339a1c2SMark Johnston /* [08] */ TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
21530339a1c2SMark Johnston /* [0C] */ TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
21540339a1c2SMark Johnston
21550339a1c2SMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
21560339a1c2SMark Johnston /* [14] */ TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
21570339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
21580339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
21590339a1c2SMark Johnston
21600339a1c2SMark Johnston /* [20] */ TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
21610339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
21620339a1c2SMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
21630339a1c2SMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
21640339a1c2SMark Johnston
21650339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
21660339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
21670339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
21680339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
21690339a1c2SMark Johnston
21700339a1c2SMark Johnston /* [40] */ TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
21710339a1c2SMark Johnston /* [44] */ TNSZ("pclmulqdq",XMMP_66r,16),INVALID, INVALID, INVALID,
21720339a1c2SMark Johnston /* [48] */ INVALID, INVALID, INVALID, INVALID,
21730339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
21740339a1c2SMark Johnston
21750339a1c2SMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
21760339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
21770339a1c2SMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
21780339a1c2SMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
21790339a1c2SMark Johnston
21800339a1c2SMark Johnston /* [60] */ TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
21810339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
21820339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
21830339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
21840339a1c2SMark Johnston
21850339a1c2SMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
21860339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
21870339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
21880339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
21890339a1c2SMark Johnston
21900339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
21910339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
21920339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
21930339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
21940339a1c2SMark Johnston
21950339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
21960339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
21970339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
21980339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
21990339a1c2SMark Johnston
22000339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
22010339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
22020339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
22030339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
22040339a1c2SMark Johnston
22050339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
22060339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
22070339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
22080339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
22090339a1c2SMark Johnston
22100339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
22110339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
22120339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
2213722b2e2fSMark Johnston /* [CC] */ TNSZ("sha1rnds4",XMMP,16),INVALID, TNS("gf2p8affineqb",XMMP_66r),TNS("gf2p8affineinvqb",XMMP_66r),
22140339a1c2SMark Johnston
22150339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
22160339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
22170339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
22180339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, TNSZ("aeskeygenassist",XMMP_66r,16),
22190339a1c2SMark Johnston
22200339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
22210339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
22220339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
22230339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
22240339a1c2SMark Johnston
22250339a1c2SMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
22260339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
22270339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
22280339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
22290339a1c2SMark Johnston };
22300339a1c2SMark Johnston
22310339a1c2SMark Johnston const instable_t dis_opAVX660F3A[256] = {
2232b3b5bfebSMark Johnston /* [00] */ TNSZ("vpermq",VEX_MXI,16),TNSZ("vpermpd",VEX_MXI,16),TNSZ("vpblendd",VEX_RMRX,16),INVALID,
22330339a1c2SMark Johnston /* [04] */ TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
22340339a1c2SMark Johnston /* [08] */ TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
22350339a1c2SMark Johnston /* [0C] */ TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
22360339a1c2SMark Johnston
22370339a1c2SMark Johnston /* [10] */ INVALID, INVALID, INVALID, INVALID,
22380339a1c2SMark Johnston /* [14] */ TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
22390339a1c2SMark Johnston /* [18] */ TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID, INVALID,
2240c3ddb60eSPeter Grehan /* [1C] */ INVALID, TNSZ("vcvtps2ph",VEX_RX,16), INVALID, INVALID,
22410339a1c2SMark Johnston
22420339a1c2SMark Johnston /* [20] */ TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
22430339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
22440339a1c2SMark Johnston /* [28] */ INVALID, INVALID, INVALID, INVALID,
22450339a1c2SMark Johnston /* [2C] */ INVALID, INVALID, INVALID, INVALID,
22460339a1c2SMark Johnston
2247722b2e2fSMark Johnston /* [30] */ TSvo("kshiftr",VEX_MXI), TSvo("kshiftr",VEX_MXI), TSvo("kshiftl",VEX_MXI), TSvo("kshiftl",VEX_MXI),
22480339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
2249b3b5bfebSMark Johnston /* [38] */ TNSZ("vinserti128",VEX_RMRX,16),TNSZ("vextracti128",VEX_RIM,16),INVALID, INVALID,
22500339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
22510339a1c2SMark Johnston
22520339a1c2SMark Johnston /* [40] */ TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
2253b3b5bfebSMark Johnston /* [44] */ TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID, TNSZ("vperm2i128",VEX_RMRX,16),INVALID,
22540339a1c2SMark Johnston /* [48] */ INVALID, INVALID, TNSZ("vblendvps",VEX_RMRX,8), TNSZ("vblendvpd",VEX_RMRX,16),
22550339a1c2SMark Johnston /* [4C] */ TNSZ("vpblendvb",VEX_RMRX,16),INVALID, INVALID, INVALID,
22560339a1c2SMark Johnston
22570339a1c2SMark Johnston /* [50] */ INVALID, INVALID, INVALID, INVALID,
22580339a1c2SMark Johnston /* [54] */ INVALID, INVALID, INVALID, INVALID,
22590339a1c2SMark Johnston /* [58] */ INVALID, INVALID, INVALID, INVALID,
22600339a1c2SMark Johnston /* [5C] */ INVALID, INVALID, INVALID, INVALID,
22610339a1c2SMark Johnston
22620339a1c2SMark Johnston /* [60] */ TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
22630339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
22640339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
22650339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
22660339a1c2SMark Johnston
22670339a1c2SMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
22680339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, INVALID,
22690339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
22700339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
22710339a1c2SMark Johnston
22720339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
22730339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
22740339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
22750339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
22760339a1c2SMark Johnston
22770339a1c2SMark Johnston /* [90] */ INVALID, INVALID, INVALID, INVALID,
22780339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
22790339a1c2SMark Johnston /* [98] */ INVALID, INVALID, INVALID, INVALID,
22800339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
22810339a1c2SMark Johnston
22820339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
22830339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
22840339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
22850339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, INVALID, INVALID,
22860339a1c2SMark Johnston
22870339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
22880339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
22890339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
22900339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
22910339a1c2SMark Johnston
22920339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, INVALID, INVALID,
22930339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, INVALID, INVALID,
22940339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
2295722b2e2fSMark Johnston /* [CC] */ INVALID, INVALID, TNS("vgf2p8affineqb",VEX_RMRX),TNS("vgf2p8affineinvqb",VEX_RMRX),
22960339a1c2SMark Johnston
22970339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
22980339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
22990339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
23000339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, TNSZ("vaeskeygenassist",VEX_MXI,16),
23010339a1c2SMark Johnston
23020339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
23030339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
23040339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
23050339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
23060339a1c2SMark Johnston
23070339a1c2SMark Johnston /* [F0] */ INVALID, INVALID, INVALID, INVALID,
23080339a1c2SMark Johnston /* [F4] */ INVALID, INVALID, INVALID, INVALID,
23090339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
23100339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
23110339a1c2SMark Johnston };
23120339a1c2SMark Johnston
23130339a1c2SMark Johnston /*
2314b3b5bfebSMark Johnston * Decode table for 0x0F0D which uses the first byte of the mod_rm to
2315b3b5bfebSMark Johnston * indicate a sub-code.
2316b3b5bfebSMark Johnston */
2317b3b5bfebSMark Johnston const instable_t dis_op0F0D[8] = {
2318b3b5bfebSMark Johnston /* [00] */ INVALID, TNS("prefetchw",PREF), TNS("prefetchwt1",PREF),INVALID,
2319b3b5bfebSMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
2320b3b5bfebSMark Johnston };
2321b3b5bfebSMark Johnston
2322b3b5bfebSMark Johnston /*
23230339a1c2SMark Johnston * Decode table for 0x0F opcodes
23240339a1c2SMark Johnston */
23250339a1c2SMark Johnston
23260339a1c2SMark Johnston const instable_t dis_op0F[16][16] = {
23270339a1c2SMark Johnston {
23280339a1c2SMark Johnston /* [00] */ IND(dis_op0F00), IND(dis_op0F01), TNS("lar",MR), TNS("lsl",MR),
23290339a1c2SMark Johnston /* [04] */ INVALID, TNS("syscall",NORM), TNS("clts",NORM), TNS("sysret",NORM),
23300339a1c2SMark Johnston /* [08] */ TNS("invd",NORM), TNS("wbinvd",NORM), INVALID, TNS("ud2",NORM),
2331b3b5bfebSMark Johnston /* [0C] */ INVALID, IND(dis_op0F0D), INVALID, INVALID,
23320339a1c2SMark Johnston }, {
23330339a1c2SMark Johnston /* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8),
23340339a1c2SMark Johnston /* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
23350339a1c2SMark Johnston /* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID,
2336c3ddb60eSPeter Grehan /* [1C] */ INVALID, INVALID, INVALID, TS("nop",Mw),
23370339a1c2SMark Johnston }, {
23380339a1c2SMark Johnston /* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG),
23390339a1c2SMark Johnston /* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID,
23400339a1c2SMark Johnston /* [28] */ TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
23410339a1c2SMark Johnston /* [2C] */ TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
23420339a1c2SMark Johnston }, {
23430339a1c2SMark Johnston /* [30] */ TNS("wrmsr",NORM), TNS("rdtsc",NORM), TNS("rdmsr",NORM), TNS("rdpmc",NORM),
2344722b2e2fSMark Johnston /* [34] */ TNS("sysenter",NORM), TNS("sysexit",NORM), INVALID, INVALID,
23450339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
23460339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
23470339a1c2SMark Johnston }, {
23480339a1c2SMark Johnston /* [40] */ TS("cmovx.o",MR), TS("cmovx.no",MR), TS("cmovx.b",MR), TS("cmovx.ae",MR),
23490339a1c2SMark Johnston /* [44] */ TS("cmovx.e",MR), TS("cmovx.ne",MR), TS("cmovx.be",MR), TS("cmovx.a",MR),
23500339a1c2SMark Johnston /* [48] */ TS("cmovx.s",MR), TS("cmovx.ns",MR), TS("cmovx.pe",MR), TS("cmovx.po",MR),
23510339a1c2SMark Johnston /* [4C] */ TS("cmovx.l",MR), TS("cmovx.ge",MR), TS("cmovx.le",MR), TS("cmovx.g",MR),
23520339a1c2SMark Johnston }, {
23530339a1c2SMark Johnston /* [50] */ TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
23540339a1c2SMark Johnston /* [54] */ TNSZ("andps",XMMO,16), TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16), TNSZ("xorps",XMMO,16),
23550339a1c2SMark Johnston /* [58] */ TNSZ("addps",XMMO,16), TNSZ("mulps",XMMO,16), TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
23560339a1c2SMark Johnston /* [5C] */ TNSZ("subps",XMMO,16), TNSZ("minps",XMMO,16), TNSZ("divps",XMMO,16), TNSZ("maxps",XMMO,16),
23570339a1c2SMark Johnston }, {
23580339a1c2SMark Johnston /* [60] */ TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
23590339a1c2SMark Johnston /* [64] */ TNSZ("pcmpgtb",MMO,8), TNSZ("pcmpgtw",MMO,8), TNSZ("pcmpgtd",MMO,8), TNSZ("packuswb",MMO,8),
23600339a1c2SMark Johnston /* [68] */ TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
23610339a1c2SMark Johnston /* [6C] */ TNSZ("INVALID",MMO,0), TNSZ("INVALID",MMO,0), TNSZ("movd",MMO,4), TNSZ("movq",MMO,8),
23620339a1c2SMark Johnston }, {
23630339a1c2SMark Johnston /* [70] */ TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR), TNS("psrXXX",MR), TNS("psrXXX",MR),
23640339a1c2SMark Johnston /* [74] */ TNSZ("pcmpeqb",MMO,8), TNSZ("pcmpeqw",MMO,8), TNSZ("pcmpeqd",MMO,8), TNS("emms",NORM),
2365c3ddb60eSPeter Grehan /* [78] */ TNSy("vmread",RM), TNSy("vmwrite",MR), INVALID, INVALID,
23660339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, TNSZ("movd",MMOS,4), TNSZ("movq",MMOS,8),
23670339a1c2SMark Johnston }, {
23680339a1c2SMark Johnston /* [80] */ TNS("jo",D), TNS("jno",D), TNS("jb",D), TNS("jae",D),
23690339a1c2SMark Johnston /* [84] */ TNS("je",D), TNS("jne",D), TNS("jbe",D), TNS("ja",D),
23700339a1c2SMark Johnston /* [88] */ TNS("js",D), TNS("jns",D), TNS("jp",D), TNS("jnp",D),
23710339a1c2SMark Johnston /* [8C] */ TNS("jl",D), TNS("jge",D), TNS("jle",D), TNS("jg",D),
23720339a1c2SMark Johnston }, {
23730339a1c2SMark Johnston /* [90] */ TNS("seto",Mb), TNS("setno",Mb), TNS("setb",Mb), TNS("setae",Mb),
23740339a1c2SMark Johnston /* [94] */ TNS("sete",Mb), TNS("setne",Mb), TNS("setbe",Mb), TNS("seta",Mb),
23750339a1c2SMark Johnston /* [98] */ TNS("sets",Mb), TNS("setns",Mb), TNS("setp",Mb), TNS("setnp",Mb),
23760339a1c2SMark Johnston /* [9C] */ TNS("setl",Mb), TNS("setge",Mb), TNS("setle",Mb), TNS("setg",Mb),
23770339a1c2SMark Johnston }, {
23780339a1c2SMark Johnston /* [A0] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("cpuid",NORM), TS("bt",RMw),
23790339a1c2SMark Johnston /* [A4] */ TS("shld",DSHIFT), TS("shld",DSHIFTcl), INVALID, INVALID,
23800339a1c2SMark Johnston /* [A8] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("rsm",NORM), TS("bts",RMw),
23810339a1c2SMark Johnston /* [AC] */ TS("shrd",DSHIFT), TS("shrd",DSHIFTcl), IND(dis_op0FAE), TS("imul",MRw),
23820339a1c2SMark Johnston }, {
23830339a1c2SMark Johnston /* [B0] */ TNS("cmpxchgb",RMw), TS("cmpxchg",RMw), TS("lss",MR), TS("btr",RMw),
23840339a1c2SMark Johnston /* [B4] */ TS("lfs",MR), TS("lgs",MR), TS("movzb",MOVZ), TNS("movzwl",MOVZ),
23850339a1c2SMark Johnston /* [B8] */ TNS("INVALID",MRw), INVALID, IND(dis_op0FBA), TS("btc",RMw),
23860339a1c2SMark Johnston /* [BC] */ TS("bsf",MRw), TS("bsr",MRw), TS("movsb",MOVZ), TNS("movswl",MOVZ),
23870339a1c2SMark Johnston }, {
23880339a1c2SMark Johnston /* [C0] */ TNS("xaddb",XADDB), TS("xadd",RMw), TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
23890339a1c2SMark Johnston /* [C4] */ TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
23900339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
23910339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
23920339a1c2SMark Johnston }, {
23930339a1c2SMark Johnston /* [D0] */ INVALID, TNSZ("psrlw",MMO,8), TNSZ("psrld",MMO,8), TNSZ("psrlq",MMO,8),
23940339a1c2SMark Johnston /* [D4] */ TNSZ("paddq",MMO,8), TNSZ("pmullw",MMO,8), TNSZ("INVALID",MMO,0), TNS("pmovmskb",MMOM3),
23950339a1c2SMark Johnston /* [D8] */ TNSZ("psubusb",MMO,8), TNSZ("psubusw",MMO,8), TNSZ("pminub",MMO,8), TNSZ("pand",MMO,8),
23960339a1c2SMark Johnston /* [DC] */ TNSZ("paddusb",MMO,8), TNSZ("paddusw",MMO,8), TNSZ("pmaxub",MMO,8), TNSZ("pandn",MMO,8),
23970339a1c2SMark Johnston }, {
23980339a1c2SMark Johnston /* [E0] */ TNSZ("pavgb",MMO,8), TNSZ("psraw",MMO,8), TNSZ("psrad",MMO,8), TNSZ("pavgw",MMO,8),
23990339a1c2SMark Johnston /* [E4] */ TNSZ("pmulhuw",MMO,8), TNSZ("pmulhw",MMO,8), TNS("INVALID",XMMO), TNSZ("movntq",MMOMS,8),
24000339a1c2SMark Johnston /* [E8] */ TNSZ("psubsb",MMO,8), TNSZ("psubsw",MMO,8), TNSZ("pminsw",MMO,8), TNSZ("por",MMO,8),
24010339a1c2SMark Johnston /* [EC] */ TNSZ("paddsb",MMO,8), TNSZ("paddsw",MMO,8), TNSZ("pmaxsw",MMO,8), TNSZ("pxor",MMO,8),
24020339a1c2SMark Johnston }, {
24030339a1c2SMark Johnston /* [F0] */ INVALID, TNSZ("psllw",MMO,8), TNSZ("pslld",MMO,8), TNSZ("psllq",MMO,8),
24040339a1c2SMark Johnston /* [F4] */ TNSZ("pmuludq",MMO,8), TNSZ("pmaddwd",MMO,8), TNSZ("psadbw",MMO,8), TNSZ("maskmovq",MMOIMPL,8),
24050339a1c2SMark Johnston /* [F8] */ TNSZ("psubb",MMO,8), TNSZ("psubw",MMO,8), TNSZ("psubd",MMO,8), TNSZ("psubq",MMO,8),
24060339a1c2SMark Johnston /* [FC] */ TNSZ("paddb",MMO,8), TNSZ("paddw",MMO,8), TNSZ("paddd",MMO,8), INVALID,
24070339a1c2SMark Johnston } };
24080339a1c2SMark Johnston
24090339a1c2SMark Johnston const instable_t dis_opAVX0F[16][16] = {
24100339a1c2SMark Johnston {
24110339a1c2SMark Johnston /* [00] */ INVALID, INVALID, INVALID, INVALID,
24120339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
24130339a1c2SMark Johnston /* [08] */ INVALID, INVALID, INVALID, INVALID,
24140339a1c2SMark Johnston /* [0C] */ INVALID, INVALID, INVALID, INVALID,
24150339a1c2SMark Johnston }, {
24160339a1c2SMark Johnston /* [10] */ TNSZ("vmovups",VEX_MX,16), TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8), TNSZ("vmovlps",VEX_RM,8),
24170339a1c2SMark Johnston /* [14] */ TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
24180339a1c2SMark Johnston /* [18] */ INVALID, INVALID, INVALID, INVALID,
24190339a1c2SMark Johnston /* [1C] */ INVALID, INVALID, INVALID, INVALID,
24200339a1c2SMark Johnston }, {
24210339a1c2SMark Johnston /* [20] */ INVALID, INVALID, INVALID, INVALID,
24220339a1c2SMark Johnston /* [24] */ INVALID, INVALID, INVALID, INVALID,
24230339a1c2SMark Johnston /* [28] */ TNSZ("vmovaps",VEX_MX,16), TNSZ("vmovaps",VEX_RX,16),INVALID, TNSZ("vmovntps",VEX_RM,16),
24240339a1c2SMark Johnston /* [2C] */ INVALID, INVALID, TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
24250339a1c2SMark Johnston }, {
24260339a1c2SMark Johnston /* [30] */ INVALID, INVALID, INVALID, INVALID,
24270339a1c2SMark Johnston /* [34] */ INVALID, INVALID, INVALID, INVALID,
24280339a1c2SMark Johnston /* [38] */ INVALID, INVALID, INVALID, INVALID,
24290339a1c2SMark Johnston /* [3C] */ INVALID, INVALID, INVALID, INVALID,
24300339a1c2SMark Johnston }, {
2431722b2e2fSMark Johnston /* [40] */ INVALID, TSvo("kand",VEX_RMX), TSvo("kandn",VEX_RMX), INVALID,
2432722b2e2fSMark Johnston /* [44] */ TSvo("knot",VEX_MX), TSvo("kor",VEX_RMX), TSvo("kxnor",VEX_RMX), TSvo("kxor",VEX_RMX),
2433722b2e2fSMark Johnston /* [48] */ INVALID, INVALID, TSvo("kadd",VEX_RMX), TSvo("kunpck",VEX_RMX),
24340339a1c2SMark Johnston /* [4C] */ INVALID, INVALID, INVALID, INVALID,
24350339a1c2SMark Johnston }, {
24360339a1c2SMark Johnston /* [50] */ TNS("vmovmskps",VEX_MR), TNSZ("vsqrtps",VEX_MX,16), TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
24370339a1c2SMark Johnston /* [54] */ TNSZ("vandps",VEX_RMrX,16), TNSZ("vandnps",VEX_RMrX,16), TNSZ("vorps",VEX_RMrX,16), TNSZ("vxorps",VEX_RMrX,16),
24380339a1c2SMark Johnston /* [58] */ TNSZ("vaddps",VEX_RMrX,16), TNSZ("vmulps",VEX_RMrX,16), TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
24390339a1c2SMark Johnston /* [5C] */ TNSZ("vsubps",VEX_RMrX,16), TNSZ("vminps",VEX_RMrX,16), TNSZ("vdivps",VEX_RMrX,16), TNSZ("vmaxps",VEX_RMrX,16),
24400339a1c2SMark Johnston }, {
24410339a1c2SMark Johnston /* [60] */ INVALID, INVALID, INVALID, INVALID,
24420339a1c2SMark Johnston /* [64] */ INVALID, INVALID, INVALID, INVALID,
24430339a1c2SMark Johnston /* [68] */ INVALID, INVALID, INVALID, INVALID,
24440339a1c2SMark Johnston /* [6C] */ INVALID, INVALID, INVALID, INVALID,
24450339a1c2SMark Johnston }, {
24460339a1c2SMark Johnston /* [70] */ INVALID, INVALID, INVALID, INVALID,
24470339a1c2SMark Johnston /* [74] */ INVALID, INVALID, INVALID, TNS("vzeroupper", VEX_NONE),
24480339a1c2SMark Johnston /* [78] */ INVALID, INVALID, INVALID, INVALID,
24490339a1c2SMark Johnston /* [7C] */ INVALID, INVALID, INVALID, INVALID,
24500339a1c2SMark Johnston }, {
24510339a1c2SMark Johnston /* [80] */ INVALID, INVALID, INVALID, INVALID,
24520339a1c2SMark Johnston /* [84] */ INVALID, INVALID, INVALID, INVALID,
24530339a1c2SMark Johnston /* [88] */ INVALID, INVALID, INVALID, INVALID,
24540339a1c2SMark Johnston /* [8C] */ INVALID, INVALID, INVALID, INVALID,
24550339a1c2SMark Johnston }, {
2456722b2e2fSMark Johnston /* [90] */ TSvo("kmov",VEX_KRM), TSvo("kmov",VEX_KMR), TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),
24570339a1c2SMark Johnston /* [94] */ INVALID, INVALID, INVALID, INVALID,
2458722b2e2fSMark Johnston /* [98] */ TSvo("kortest",VEX_MX), TSvo("ktest",VEX_MX), INVALID, INVALID,
24590339a1c2SMark Johnston /* [9C] */ INVALID, INVALID, INVALID, INVALID,
24600339a1c2SMark Johnston }, {
24610339a1c2SMark Johnston /* [A0] */ INVALID, INVALID, INVALID, INVALID,
24620339a1c2SMark Johnston /* [A4] */ INVALID, INVALID, INVALID, INVALID,
24630339a1c2SMark Johnston /* [A8] */ INVALID, INVALID, INVALID, INVALID,
24640339a1c2SMark Johnston /* [AC] */ INVALID, INVALID, TNSZ("vldmxcsr",VEX_MO,2), INVALID,
24650339a1c2SMark Johnston }, {
24660339a1c2SMark Johnston /* [B0] */ INVALID, INVALID, INVALID, INVALID,
24670339a1c2SMark Johnston /* [B4] */ INVALID, INVALID, INVALID, INVALID,
24680339a1c2SMark Johnston /* [B8] */ INVALID, INVALID, INVALID, INVALID,
24690339a1c2SMark Johnston /* [BC] */ INVALID, INVALID, INVALID, INVALID,
24700339a1c2SMark Johnston }, {
24710339a1c2SMark Johnston /* [C0] */ INVALID, INVALID, TNSZ("vcmpps",VEX_RMRX,16),INVALID,
24720339a1c2SMark Johnston /* [C4] */ INVALID, INVALID, TNSZ("vshufps",VEX_RMRX,16),INVALID,
24730339a1c2SMark Johnston /* [C8] */ INVALID, INVALID, INVALID, INVALID,
24740339a1c2SMark Johnston /* [CC] */ INVALID, INVALID, INVALID, INVALID,
24750339a1c2SMark Johnston }, {
24760339a1c2SMark Johnston /* [D0] */ INVALID, INVALID, INVALID, INVALID,
24770339a1c2SMark Johnston /* [D4] */ INVALID, INVALID, INVALID, INVALID,
24780339a1c2SMark Johnston /* [D8] */ INVALID, INVALID, INVALID, INVALID,
24790339a1c2SMark Johnston /* [DC] */ INVALID, INVALID, INVALID, INVALID,
24800339a1c2SMark Johnston }, {
24810339a1c2SMark Johnston /* [E0] */ INVALID, INVALID, INVALID, INVALID,
24820339a1c2SMark Johnston /* [E4] */ INVALID, INVALID, INVALID, INVALID,
24830339a1c2SMark Johnston /* [E8] */ INVALID, INVALID, INVALID, INVALID,
24840339a1c2SMark Johnston /* [EC] */ INVALID, INVALID, INVALID, INVALID,
24850339a1c2SMark Johnston }, {
2486b3b5bfebSMark Johnston /* [F0] */ INVALID, INVALID, TNSZvr("andn",VEX_RMrX,5),TNSZvr("bls",BLS,5),
2487b3b5bfebSMark Johnston /* [F4] */ INVALID, TNSZvr("bzhi",VEX_VRMrX,5),INVALID, TNSZvr("bextr",VEX_VRMrX,5),
24880339a1c2SMark Johnston /* [F8] */ INVALID, INVALID, INVALID, INVALID,
24890339a1c2SMark Johnston /* [FC] */ INVALID, INVALID, INVALID, INVALID,
24900339a1c2SMark Johnston } };
24910339a1c2SMark Johnston
24920339a1c2SMark Johnston /*
24930339a1c2SMark Johnston * Decode table for 0x80 opcodes
24940339a1c2SMark Johnston */
24950339a1c2SMark Johnston
24960339a1c2SMark Johnston const instable_t dis_op80[8] = {
24970339a1c2SMark Johnston
24980339a1c2SMark Johnston /* [0] */ TNS("addb",IMlw), TNS("orb",IMw), TNS("adcb",IMlw), TNS("sbbb",IMlw),
24990339a1c2SMark Johnston /* [4] */ TNS("andb",IMw), TNS("subb",IMlw), TNS("xorb",IMw), TNS("cmpb",IMlw),
25000339a1c2SMark Johnston };
25010339a1c2SMark Johnston
25020339a1c2SMark Johnston
25030339a1c2SMark Johnston /*
25040339a1c2SMark Johnston * Decode table for 0x81 opcodes.
25050339a1c2SMark Johnston */
25060339a1c2SMark Johnston
25070339a1c2SMark Johnston const instable_t dis_op81[8] = {
25080339a1c2SMark Johnston
25090339a1c2SMark Johnston /* [0] */ TS("add",IMlw), TS("or",IMw), TS("adc",IMlw), TS("sbb",IMlw),
25100339a1c2SMark Johnston /* [4] */ TS("and",IMw), TS("sub",IMlw), TS("xor",IMw), TS("cmp",IMlw),
25110339a1c2SMark Johnston };
25120339a1c2SMark Johnston
25130339a1c2SMark Johnston
25140339a1c2SMark Johnston /*
25150339a1c2SMark Johnston * Decode table for 0x82 opcodes.
25160339a1c2SMark Johnston */
25170339a1c2SMark Johnston
25180339a1c2SMark Johnston const instable_t dis_op82[8] = {
25190339a1c2SMark Johnston
25200339a1c2SMark Johnston /* [0] */ TNSx("addb",IMlw), TNSx("orb",IMlw), TNSx("adcb",IMlw), TNSx("sbbb",IMlw),
25210339a1c2SMark Johnston /* [4] */ TNSx("andb",IMlw), TNSx("subb",IMlw), TNSx("xorb",IMlw), TNSx("cmpb",IMlw),
25220339a1c2SMark Johnston };
25230339a1c2SMark Johnston /*
25240339a1c2SMark Johnston * Decode table for 0x83 opcodes.
25250339a1c2SMark Johnston */
25260339a1c2SMark Johnston
25270339a1c2SMark Johnston const instable_t dis_op83[8] = {
25280339a1c2SMark Johnston
25290339a1c2SMark Johnston /* [0] */ TS("add",IMlw), TS("or",IMlw), TS("adc",IMlw), TS("sbb",IMlw),
25300339a1c2SMark Johnston /* [4] */ TS("and",IMlw), TS("sub",IMlw), TS("xor",IMlw), TS("cmp",IMlw),
25310339a1c2SMark Johnston };
25320339a1c2SMark Johnston
25330339a1c2SMark Johnston /*
25340339a1c2SMark Johnston * Decode table for 0xC0 opcodes.
25350339a1c2SMark Johnston */
25360339a1c2SMark Johnston
25370339a1c2SMark Johnston const instable_t dis_opC0[8] = {
25380339a1c2SMark Johnston
25390339a1c2SMark Johnston /* [0] */ TNS("rolb",MvI), TNS("rorb",MvI), TNS("rclb",MvI), TNS("rcrb",MvI),
25400339a1c2SMark Johnston /* [4] */ TNS("shlb",MvI), TNS("shrb",MvI), INVALID, TNS("sarb",MvI),
25410339a1c2SMark Johnston };
25420339a1c2SMark Johnston
25430339a1c2SMark Johnston /*
25440339a1c2SMark Johnston * Decode table for 0xD0 opcodes.
25450339a1c2SMark Johnston */
25460339a1c2SMark Johnston
25470339a1c2SMark Johnston const instable_t dis_opD0[8] = {
25480339a1c2SMark Johnston
25490339a1c2SMark Johnston /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv),
25500339a1c2SMark Johnston /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv),
25510339a1c2SMark Johnston };
25520339a1c2SMark Johnston
25530339a1c2SMark Johnston /*
25540339a1c2SMark Johnston * Decode table for 0xC1 opcodes.
25550339a1c2SMark Johnston * 186 instruction set
25560339a1c2SMark Johnston */
25570339a1c2SMark Johnston
25580339a1c2SMark Johnston const instable_t dis_opC1[8] = {
25590339a1c2SMark Johnston
25600339a1c2SMark Johnston /* [0] */ TS("rol",MvI), TS("ror",MvI), TS("rcl",MvI), TS("rcr",MvI),
25610339a1c2SMark Johnston /* [4] */ TS("shl",MvI), TS("shr",MvI), TS("sal",MvI), TS("sar",MvI),
25620339a1c2SMark Johnston };
25630339a1c2SMark Johnston
25640339a1c2SMark Johnston /*
25650339a1c2SMark Johnston * Decode table for 0xD1 opcodes.
25660339a1c2SMark Johnston */
25670339a1c2SMark Johnston
25680339a1c2SMark Johnston const instable_t dis_opD1[8] = {
25690339a1c2SMark Johnston
25700339a1c2SMark Johnston /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv),
25710339a1c2SMark Johnston /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("sal",Mv), TS("sar",Mv),
25720339a1c2SMark Johnston };
25730339a1c2SMark Johnston
25740339a1c2SMark Johnston
25750339a1c2SMark Johnston /*
25760339a1c2SMark Johnston * Decode table for 0xD2 opcodes.
25770339a1c2SMark Johnston */
25780339a1c2SMark Johnston
25790339a1c2SMark Johnston const instable_t dis_opD2[8] = {
25800339a1c2SMark Johnston
25810339a1c2SMark Johnston /* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv),
25820339a1c2SMark Johnston /* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv),
25830339a1c2SMark Johnston };
25840339a1c2SMark Johnston /*
25850339a1c2SMark Johnston * Decode table for 0xD3 opcodes.
25860339a1c2SMark Johnston */
25870339a1c2SMark Johnston
25880339a1c2SMark Johnston const instable_t dis_opD3[8] = {
25890339a1c2SMark Johnston
25900339a1c2SMark Johnston /* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv),
25910339a1c2SMark Johnston /* [4] */ TS("shl",Mv), TS("shr",Mv), TS("salb",Mv), TS("sar",Mv),
25920339a1c2SMark Johnston };
25930339a1c2SMark Johnston
25940339a1c2SMark Johnston
25950339a1c2SMark Johnston /*
25960339a1c2SMark Johnston * Decode table for 0xF6 opcodes.
25970339a1c2SMark Johnston */
25980339a1c2SMark Johnston
25990339a1c2SMark Johnston const instable_t dis_opF6[8] = {
26000339a1c2SMark Johnston
26010339a1c2SMark Johnston /* [0] */ TNS("testb",IMw), TNS("testb",IMw), TNS("notb",Mw), TNS("negb",Mw),
26020339a1c2SMark Johnston /* [4] */ TNS("mulb",MA), TNS("imulb",MA), TNS("divb",MA), TNS("idivb",MA),
26030339a1c2SMark Johnston };
26040339a1c2SMark Johnston
26050339a1c2SMark Johnston
26060339a1c2SMark Johnston /*
26070339a1c2SMark Johnston * Decode table for 0xF7 opcodes.
26080339a1c2SMark Johnston */
26090339a1c2SMark Johnston
26100339a1c2SMark Johnston const instable_t dis_opF7[8] = {
26110339a1c2SMark Johnston
26120339a1c2SMark Johnston /* [0] */ TS("test",IMw), TS("test",IMw), TS("not",Mw), TS("neg",Mw),
26130339a1c2SMark Johnston /* [4] */ TS("mul",MA), TS("imul",MA), TS("div",MA), TS("idiv",MA),
26140339a1c2SMark Johnston };
26150339a1c2SMark Johnston
26160339a1c2SMark Johnston
26170339a1c2SMark Johnston /*
26180339a1c2SMark Johnston * Decode table for 0xFE opcodes.
26190339a1c2SMark Johnston */
26200339a1c2SMark Johnston
26210339a1c2SMark Johnston const instable_t dis_opFE[8] = {
26220339a1c2SMark Johnston
26230339a1c2SMark Johnston /* [0] */ TNS("incb",Mw), TNS("decb",Mw), INVALID, INVALID,
26240339a1c2SMark Johnston /* [4] */ INVALID, INVALID, INVALID, INVALID,
26250339a1c2SMark Johnston };
26260339a1c2SMark Johnston /*
26270339a1c2SMark Johnston * Decode table for 0xFF opcodes.
26280339a1c2SMark Johnston */
26290339a1c2SMark Johnston
26300339a1c2SMark Johnston const instable_t dis_opFF[8] = {
26310339a1c2SMark Johnston
26320339a1c2SMark Johnston /* [0] */ TS("inc",Mw), TS("dec",Mw), TNSyp("call",INM), TNS("lcall",INM),
26330339a1c2SMark Johnston /* [4] */ TNSy("jmp",INM), TNS("ljmp",INM), TSp("push",M), INVALID,
26340339a1c2SMark Johnston };
26350339a1c2SMark Johnston
26360339a1c2SMark Johnston /* for 287 instructions, which are a mess to decode */
26370339a1c2SMark Johnston
26380339a1c2SMark Johnston const instable_t dis_opFP1n2[8][8] = {
26390339a1c2SMark Johnston {
26400339a1c2SMark Johnston /* bit pattern: 1101 1xxx MODxx xR/M */
26410339a1c2SMark Johnston /* [0,0] */ TNS("fadds",M), TNS("fmuls",M), TNS("fcoms",M), TNS("fcomps",M),
26420339a1c2SMark Johnston /* [0,4] */ TNS("fsubs",M), TNS("fsubrs",M), TNS("fdivs",M), TNS("fdivrs",M),
26430339a1c2SMark Johnston }, {
26440339a1c2SMark Johnston /* [1,0] */ TNS("flds",M), INVALID, TNS("fsts",M), TNS("fstps",M),
26450339a1c2SMark Johnston /* [1,4] */ TNSZ("fldenv",M,28), TNSZ("fldcw",M,2), TNSZ("fnstenv",M,28), TNSZ("fnstcw",M,2),
26460339a1c2SMark Johnston }, {
26470339a1c2SMark Johnston /* [2,0] */ TNS("fiaddl",M), TNS("fimull",M), TNS("ficoml",M), TNS("ficompl",M),
26480339a1c2SMark Johnston /* [2,4] */ TNS("fisubl",M), TNS("fisubrl",M), TNS("fidivl",M), TNS("fidivrl",M),
26490339a1c2SMark Johnston }, {
2650b3b5bfebSMark Johnston /* [3,0] */ TNS("fildl",M), TNSZ("tisttpl",M,4), TNS("fistl",M), TNS("fistpl",M),
26510339a1c2SMark Johnston /* [3,4] */ INVALID, TNSZ("fldt",M,10), INVALID, TNSZ("fstpt",M,10),
26520339a1c2SMark Johnston }, {
26530339a1c2SMark Johnston /* [4,0] */ TNSZ("faddl",M,8), TNSZ("fmull",M,8), TNSZ("fcoml",M,8), TNSZ("fcompl",M,8),
26540339a1c2SMark Johnston /* [4,1] */ TNSZ("fsubl",M,8), TNSZ("fsubrl",M,8), TNSZ("fdivl",M,8), TNSZ("fdivrl",M,8),
26550339a1c2SMark Johnston }, {
2656b3b5bfebSMark Johnston /* [5,0] */ TNSZ("fldl",M,8), TNSZ("fisttpll",M,8), TNSZ("fstl",M,8), TNSZ("fstpl",M,8),
26570339a1c2SMark Johnston /* [5,4] */ TNSZ("frstor",M,108), INVALID, TNSZ("fnsave",M,108), TNSZ("fnstsw",M,2),
26580339a1c2SMark Johnston }, {
26590339a1c2SMark Johnston /* [6,0] */ TNSZ("fiadd",M,2), TNSZ("fimul",M,2), TNSZ("ficom",M,2), TNSZ("ficomp",M,2),
26600339a1c2SMark Johnston /* [6,4] */ TNSZ("fisub",M,2), TNSZ("fisubr",M,2), TNSZ("fidiv",M,2), TNSZ("fidivr",M,2),
26610339a1c2SMark Johnston }, {
2662b3b5bfebSMark Johnston /* [7,0] */ TNSZ("fild",M,2), TNSZ("fisttp",M,2), TNSZ("fist",M,2), TNSZ("fistp",M,2),
26630339a1c2SMark Johnston /* [7,4] */ TNSZ("fbld",M,10), TNSZ("fildll",M,8), TNSZ("fbstp",M,10), TNSZ("fistpll",M,8),
26640339a1c2SMark Johnston } };
26650339a1c2SMark Johnston
26660339a1c2SMark Johnston const instable_t dis_opFP3[8][8] = {
26670339a1c2SMark Johnston {
26680339a1c2SMark Johnston /* bit pattern: 1101 1xxx 11xx xREG */
26690339a1c2SMark Johnston /* [0,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F),
26700339a1c2SMark Johnston /* [0,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF),
26710339a1c2SMark Johnston }, {
26720339a1c2SMark Johnston /* [1,0] */ TNS("fld",F), TNS("fxch",F), TNS("fnop",NORM), TNS("fstp",F),
26730339a1c2SMark Johnston /* [1,4] */ INVALID, INVALID, INVALID, INVALID,
26740339a1c2SMark Johnston }, {
26750339a1c2SMark Johnston /* [2,0] */ INVALID, INVALID, INVALID, INVALID,
26760339a1c2SMark Johnston /* [2,4] */ INVALID, TNS("fucompp",NORM), INVALID, INVALID,
26770339a1c2SMark Johnston }, {
26780339a1c2SMark Johnston /* [3,0] */ INVALID, INVALID, INVALID, INVALID,
26790339a1c2SMark Johnston /* [3,4] */ INVALID, INVALID, INVALID, INVALID,
26800339a1c2SMark Johnston }, {
26810339a1c2SMark Johnston /* [4,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F),
26820339a1c2SMark Johnston /* [4,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF),
26830339a1c2SMark Johnston }, {
26840339a1c2SMark Johnston /* [5,0] */ TNS("ffree",F), TNS("fxch",F), TNS("fst",F), TNS("fstp",F),
26850339a1c2SMark Johnston /* [5,4] */ TNS("fucom",F), TNS("fucomp",F), INVALID, INVALID,
26860339a1c2SMark Johnston }, {
26870339a1c2SMark Johnston /* [6,0] */ TNS("faddp",FF), TNS("fmulp",FF), TNS("fcomp",F), TNS("fcompp",NORM),
26880339a1c2SMark Johnston /* [6,4] */ TNS("fsubp",FF), TNS("fsubrp",FF), TNS("fdivp",FF), TNS("fdivrp",FF),
26890339a1c2SMark Johnston }, {
26900339a1c2SMark Johnston /* [7,0] */ TNS("ffreep",F), TNS("fxch",F), TNS("fstp",F), TNS("fstp",F),
26910339a1c2SMark Johnston /* [7,4] */ TNS("fnstsw",M), TNS("fucomip",FFC), TNS("fcomip",FFC), INVALID,
26920339a1c2SMark Johnston } };
26930339a1c2SMark Johnston
26940339a1c2SMark Johnston const instable_t dis_opFP4[4][8] = {
26950339a1c2SMark Johnston {
26960339a1c2SMark Johnston /* bit pattern: 1101 1001 111x xxxx */
26970339a1c2SMark Johnston /* [0,0] */ TNS("fchs",NORM), TNS("fabs",NORM), INVALID, INVALID,
26980339a1c2SMark Johnston /* [0,4] */ TNS("ftst",NORM), TNS("fxam",NORM), TNS("ftstp",NORM), INVALID,
26990339a1c2SMark Johnston }, {
27000339a1c2SMark Johnston /* [1,0] */ TNS("fld1",NORM), TNS("fldl2t",NORM), TNS("fldl2e",NORM), TNS("fldpi",NORM),
27010339a1c2SMark Johnston /* [1,4] */ TNS("fldlg2",NORM), TNS("fldln2",NORM), TNS("fldz",NORM), INVALID,
27020339a1c2SMark Johnston }, {
27030339a1c2SMark Johnston /* [2,0] */ TNS("f2xm1",NORM), TNS("fyl2x",NORM), TNS("fptan",NORM), TNS("fpatan",NORM),
27040339a1c2SMark Johnston /* [2,4] */ TNS("fxtract",NORM), TNS("fprem1",NORM), TNS("fdecstp",NORM), TNS("fincstp",NORM),
27050339a1c2SMark Johnston }, {
27060339a1c2SMark Johnston /* [3,0] */ TNS("fprem",NORM), TNS("fyl2xp1",NORM), TNS("fsqrt",NORM), TNS("fsincos",NORM),
27070339a1c2SMark Johnston /* [3,4] */ TNS("frndint",NORM), TNS("fscale",NORM), TNS("fsin",NORM), TNS("fcos",NORM),
27080339a1c2SMark Johnston } };
27090339a1c2SMark Johnston
27100339a1c2SMark Johnston const instable_t dis_opFP5[8] = {
27110339a1c2SMark Johnston /* bit pattern: 1101 1011 111x xxxx */
27120339a1c2SMark Johnston /* [0] */ TNS("feni",NORM), TNS("fdisi",NORM), TNS("fnclex",NORM), TNS("fninit",NORM),
27130339a1c2SMark Johnston /* [4] */ TNS("fsetpm",NORM), TNS("frstpm",NORM), INVALID, INVALID,
27140339a1c2SMark Johnston };
27150339a1c2SMark Johnston
27160339a1c2SMark Johnston const instable_t dis_opFP6[8] = {
27170339a1c2SMark Johnston /* bit pattern: 1101 1011 11yy yxxx */
27180339a1c2SMark Johnston /* [00] */ TNS("fcmov.nb",FF), TNS("fcmov.ne",FF), TNS("fcmov.nbe",FF), TNS("fcmov.nu",FF),
27190339a1c2SMark Johnston /* [04] */ INVALID, TNS("fucomi",F), TNS("fcomi",F), INVALID,
27200339a1c2SMark Johnston };
27210339a1c2SMark Johnston
27220339a1c2SMark Johnston const instable_t dis_opFP7[8] = {
27230339a1c2SMark Johnston /* bit pattern: 1101 1010 11yy yxxx */
27240339a1c2SMark Johnston /* [00] */ TNS("fcmov.b",FF), TNS("fcmov.e",FF), TNS("fcmov.be",FF), TNS("fcmov.u",FF),
27250339a1c2SMark Johnston /* [04] */ INVALID, INVALID, INVALID, INVALID,
27260339a1c2SMark Johnston };
27270339a1c2SMark Johnston
27280339a1c2SMark Johnston /*
27290339a1c2SMark Johnston * Main decode table for the op codes. The first two nibbles
27300339a1c2SMark Johnston * will be used as an index into the table. If there is a
27310339a1c2SMark Johnston * a need to further decode an instruction, the array to be
27320339a1c2SMark Johnston * referenced is indicated with the other two entries being
27330339a1c2SMark Johnston * empty.
27340339a1c2SMark Johnston */
27350339a1c2SMark Johnston
27360339a1c2SMark Johnston const instable_t dis_distable[16][16] = {
27370339a1c2SMark Johnston {
27380339a1c2SMark Johnston /* [0,0] */ TNS("addb",RMw), TS("add",RMw), TNS("addb",MRw), TS("add",MRw),
27390339a1c2SMark Johnston /* [0,4] */ TNS("addb",IA), TS("add",IA), TSx("push",SEG), TSx("pop",SEG),
27400339a1c2SMark Johnston /* [0,8] */ TNS("orb",RMw), TS("or",RMw), TNS("orb",MRw), TS("or",MRw),
27410339a1c2SMark Johnston /* [0,C] */ TNS("orb",IA), TS("or",IA), TSx("push",SEG), IND(dis_op0F),
27420339a1c2SMark Johnston }, {
27430339a1c2SMark Johnston /* [1,0] */ TNS("adcb",RMw), TS("adc",RMw), TNS("adcb",MRw), TS("adc",MRw),
27440339a1c2SMark Johnston /* [1,4] */ TNS("adcb",IA), TS("adc",IA), TSx("push",SEG), TSx("pop",SEG),
27450339a1c2SMark Johnston /* [1,8] */ TNS("sbbb",RMw), TS("sbb",RMw), TNS("sbbb",MRw), TS("sbb",MRw),
27460339a1c2SMark Johnston /* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG),
27470339a1c2SMark Johnston }, {
27480339a1c2SMark Johnston /* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw),
2749c3ddb60eSPeter Grehan /* [2,4] */ TNS("andb",IA), TS("and",IA), TNSx("%es:",OVERRIDE), TNSx("daa",NORM),
27500339a1c2SMark Johnston /* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw),
27510339a1c2SMark Johnston /* [2,C] */ TNS("subb",IA), TS("sub",IA), TNS("%cs:",OVERRIDE), TNSx("das",NORM),
27520339a1c2SMark Johnston }, {
27530339a1c2SMark Johnston /* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw),
2754c3ddb60eSPeter Grehan /* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNSx("%ss:",OVERRIDE), TNSx("aaa",NORM),
27550339a1c2SMark Johnston /* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw),
2756c3ddb60eSPeter Grehan /* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNSx("%ds:",OVERRIDE), TNSx("aas",NORM),
27570339a1c2SMark Johnston }, {
27580339a1c2SMark Johnston /* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
27590339a1c2SMark Johnston /* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),
27600339a1c2SMark Johnston /* [4,8] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R),
27610339a1c2SMark Johnston /* [4,C] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R),
27620339a1c2SMark Johnston }, {
27630339a1c2SMark Johnston /* [5,0] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R),
27640339a1c2SMark Johnston /* [5,4] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R),
27650339a1c2SMark Johnston /* [5,8] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R),
27660339a1c2SMark Johnston /* [5,C] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R),
27670339a1c2SMark Johnston }, {
2768722b2e2fSMark Johnston /* [6,0] */ TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",RM), TNS("arpl",RMw),
27690339a1c2SMark Johnston /* [6,4] */ TNS("%fs:",OVERRIDE), TNS("%gs:",OVERRIDE), TNS("data16",DM), TNS("addr16",AM),
27700339a1c2SMark Johnston /* [6,8] */ TSp("push",I), TS("imul",IMUL), TSp("push",Ib), TS("imul",IMUL),
27710339a1c2SMark Johnston /* [6,C] */ TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4), TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
27720339a1c2SMark Johnston }, {
27730339a1c2SMark Johnston /* [7,0] */ TNSy("jo",BD), TNSy("jno",BD), TNSy("jb",BD), TNSy("jae",BD),
27740339a1c2SMark Johnston /* [7,4] */ TNSy("je",BD), TNSy("jne",BD), TNSy("jbe",BD), TNSy("ja",BD),
27750339a1c2SMark Johnston /* [7,8] */ TNSy("js",BD), TNSy("jns",BD), TNSy("jp",BD), TNSy("jnp",BD),
27760339a1c2SMark Johnston /* [7,C] */ TNSy("jl",BD), TNSy("jge",BD), TNSy("jle",BD), TNSy("jg",BD),
27770339a1c2SMark Johnston }, {
27780339a1c2SMark Johnston /* [8,0] */ IND(dis_op80), IND(dis_op81), INDx(dis_op82), IND(dis_op83),
27790339a1c2SMark Johnston /* [8,4] */ TNS("testb",RMw), TS("test",RMw), TNS("xchgb",RMw), TS("xchg",RMw),
27800339a1c2SMark Johnston /* [8,8] */ TNS("movb",RMw), TS("mov",RMw), TNS("movb",MRw), TS("mov",MRw),
27810339a1c2SMark Johnston /* [8,C] */ TNS("movw",SM), TS("lea",MR), TNS("movw",MS), TSp("pop",M),
27820339a1c2SMark Johnston }, {
27830339a1c2SMark Johnston /* [9,0] */ TNS("nop",NORM), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA),
27840339a1c2SMark Johnston /* [9,4] */ TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA),
27850339a1c2SMark Johnston /* [9,8] */ TNS("cXtX",CBW), TNS("cXtX",CWD), TNSx("lcall",SO), TNS("fwait",NORM),
27862d69831bSAndriy Gapon /* [9,C] */ TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNS("sahf",NORM), TNS("lahf",NORM),
27870339a1c2SMark Johnston }, {
27880339a1c2SMark Johnston /* [A,0] */ TNS("movb",OA), TS("mov",OA), TNS("movb",AO), TS("mov",AO),
27890339a1c2SMark Johnston /* [A,4] */ TNSZ("movsb",SD,1), TS("movs",SD), TNSZ("cmpsb",SD,1), TS("cmps",SD),
27900339a1c2SMark Johnston /* [A,8] */ TNS("testb",IA), TS("test",IA), TNS("stosb",AD), TS("stos",AD),
27910339a1c2SMark Johnston /* [A,C] */ TNS("lodsb",SA), TS("lods",SA), TNS("scasb",AD), TS("scas",AD),
27920339a1c2SMark Johnston }, {
27930339a1c2SMark Johnston /* [B,0] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR),
27940339a1c2SMark Johnston /* [B,4] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR),
27950339a1c2SMark Johnston /* [B,8] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR),
27960339a1c2SMark Johnston /* [B,C] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR),
27970339a1c2SMark Johnston }, {
27980339a1c2SMark Johnston /* [C,0] */ IND(dis_opC0), IND(dis_opC1), TNSyp("ret",RET), TNSyp("ret",NORM),
27990339a1c2SMark Johnston /* [C,4] */ TNSx("les",MR), TNSx("lds",MR), TNS("movb",IMw), TS("mov",IMw),
28000339a1c2SMark Johnston /* [C,8] */ TNSyp("enter",ENTER), TNSyp("leave",NORM), TNS("lret",RET), TNS("lret",NORM),
28010339a1c2SMark Johnston /* [C,C] */ TNS("int",INT3), TNS("int",INTx), TNSx("into",NORM), TNS("iret",NORM),
28020339a1c2SMark Johnston }, {
28030339a1c2SMark Johnston /* [D,0] */ IND(dis_opD0), IND(dis_opD1), IND(dis_opD2), IND(dis_opD3),
28040339a1c2SMark Johnston /* [D,4] */ TNSx("aam",U), TNSx("aad",U), TNSx("falc",NORM), TNSZ("xlat",IMPLMEM,1),
28050339a1c2SMark Johnston
28060339a1c2SMark Johnston /* 287 instructions. Note that although the indirect field */
28070339a1c2SMark Johnston /* indicates opFP1n2 for further decoding, this is not necessarily */
28080339a1c2SMark Johnston /* the case since the opFP arrays are not partitioned according to key1 */
28090339a1c2SMark Johnston /* and key2. opFP1n2 is given only to indicate that we haven't */
28100339a1c2SMark Johnston /* finished decoding the instruction. */
28110339a1c2SMark Johnston /* [D,8] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2),
28120339a1c2SMark Johnston /* [D,C] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2),
28130339a1c2SMark Johnston }, {
28140339a1c2SMark Johnston /* [E,0] */ TNSy("loopnz",BD), TNSy("loopz",BD), TNSy("loop",BD), TNSy("jcxz",BD),
28150339a1c2SMark Johnston /* [E,4] */ TNS("inb",P), TS("in",P), TNS("outb",P), TS("out",P),
28160339a1c2SMark Johnston /* [E,8] */ TNSyp("call",D), TNSy("jmp",D), TNSx("ljmp",SO), TNSy("jmp",BD),
28170339a1c2SMark Johnston /* [E,C] */ TNS("inb",V), TS("in",V), TNS("outb",V), TS("out",V),
28180339a1c2SMark Johnston }, {
28190339a1c2SMark Johnston /* [F,0] */ TNS("lock",LOCK), TNS("icebp", NORM), TNS("repnz",PREFIX), TNS("repz",PREFIX),
28200339a1c2SMark Johnston /* [F,4] */ TNS("hlt",NORM), TNS("cmc",NORM), IND(dis_opF6), IND(dis_opF7),
28210339a1c2SMark Johnston /* [F,8] */ TNS("clc",NORM), TNS("stc",NORM), TNS("cli",NORM), TNS("sti",NORM),
28220339a1c2SMark Johnston /* [F,C] */ TNS("cld",NORM), TNS("std",NORM), IND(dis_opFE), IND(dis_opFF),
28230339a1c2SMark Johnston } };
28240339a1c2SMark Johnston
28250339a1c2SMark Johnston /* END CSTYLED */
28260339a1c2SMark Johnston
28270339a1c2SMark Johnston /*
28280339a1c2SMark Johnston * common functions to decode and disassemble an x86 or amd64 instruction
28290339a1c2SMark Johnston */
28300339a1c2SMark Johnston
28310339a1c2SMark Johnston /*
28320339a1c2SMark Johnston * These are the individual fields of a REX prefix. Note that a REX
28330339a1c2SMark Johnston * prefix with none of these set is still needed to:
28340339a1c2SMark Johnston * - use the MOVSXD (sign extend 32 to 64 bits) instruction
28350339a1c2SMark Johnston * - access the %sil, %dil, %bpl, %spl registers
28360339a1c2SMark Johnston */
28370339a1c2SMark Johnston #define REX_W 0x08 /* 64 bit operand size when set */
28380339a1c2SMark Johnston #define REX_R 0x04 /* high order bit extension of ModRM reg field */
28390339a1c2SMark Johnston #define REX_X 0x02 /* high order bit extension of SIB index field */
28400339a1c2SMark Johnston #define REX_B 0x01 /* extends ModRM r_m, SIB base, or opcode reg */
28410339a1c2SMark Johnston
28420339a1c2SMark Johnston /*
2843722b2e2fSMark Johnston * These are the individual fields of a VEX/EVEX prefix.
28440339a1c2SMark Johnston */
28450339a1c2SMark Johnston #define VEX_R 0x08 /* REX.R in 1's complement form */
28460339a1c2SMark Johnston #define VEX_X 0x04 /* REX.X in 1's complement form */
28470339a1c2SMark Johnston #define VEX_B 0x02 /* REX.B in 1's complement form */
2848722b2e2fSMark Johnston
2849722b2e2fSMark Johnston /* Additional EVEX prefix definitions */
2850722b2e2fSMark Johnston #define EVEX_R 0x01 /* REX.R' in 1's complement form */
2851722b2e2fSMark Johnston #define EVEX_OPREG_MASK 0x7 /* bit mask for selecting opmask register number */
2852722b2e2fSMark Johnston #define EVEX_ZERO_MASK 0x80 /* bit mask for selecting zeroing */
2853722b2e2fSMark Johnston
28540339a1c2SMark Johnston /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
28550339a1c2SMark Johnston #define VEX_L 0x04
2856722b2e2fSMark Johnston /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector, 2: 512-bit */
2857722b2e2fSMark Johnston #define EVEX_L 0x06 /* bit mask for EVEX.L'L vector length/RC */
28580339a1c2SMark Johnston #define VEX_W 0x08 /* opcode specific, use like REX.W */
28590339a1c2SMark Johnston #define VEX_m 0x1F /* VEX m-mmmm field */
2860722b2e2fSMark Johnston #define EVEX_m 0x3 /* EVEX mm field */
2861722b2e2fSMark Johnston #define VEX_v 0x78 /* VEX/EVEX register specifier */
28620339a1c2SMark Johnston #define VEX_p 0x03 /* VEX pp field, opcode extension */
28630339a1c2SMark Johnston
28640339a1c2SMark Johnston /* VEX m-mmmm field, only used by three bytes prefix */
28650339a1c2SMark Johnston #define VEX_m_0F 0x01 /* implied 0F leading opcode byte */
28660339a1c2SMark Johnston #define VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
28670339a1c2SMark Johnston #define VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
28680339a1c2SMark Johnston
28690339a1c2SMark Johnston /* VEX pp field, providing equivalent functionality of a SIMD prefix */
28700339a1c2SMark Johnston #define VEX_p_66 0x01
28710339a1c2SMark Johnston #define VEX_p_F3 0x02
28720339a1c2SMark Johnston #define VEX_p_F2 0x03
28730339a1c2SMark Johnston
28740339a1c2SMark Johnston /*
28750339a1c2SMark Johnston * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
28760339a1c2SMark Johnston */
28770339a1c2SMark Johnston static int isize[] = {1, 2, 4, 4};
28780339a1c2SMark Johnston static int isize64[] = {1, 2, 4, 8};
28790339a1c2SMark Johnston
28800339a1c2SMark Johnston /*
28810339a1c2SMark Johnston * Just a bunch of useful macros.
28820339a1c2SMark Johnston */
28830339a1c2SMark Johnston #define WBIT(x) (x & 0x1) /* to get w bit */
28840339a1c2SMark Johnston #define REGNO(x) (x & 0x7) /* to get 3 bit register */
28850339a1c2SMark Johnston #define VBIT(x) ((x)>>1 & 0x1) /* to get 'v' bit */
28860339a1c2SMark Johnston #define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
28870339a1c2SMark Johnston #define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
28880339a1c2SMark Johnston
28890339a1c2SMark Johnston #define REG_ONLY 3 /* mode to indicate a register operand (not memory) */
28900339a1c2SMark Johnston
28910339a1c2SMark Johnston #define BYTE_OPND 0 /* w-bit value indicating byte register */
28920339a1c2SMark Johnston #define LONG_OPND 1 /* w-bit value indicating opnd_size register */
28930339a1c2SMark Johnston #define MM_OPND 2 /* "value" used to indicate a mmx reg */
28940339a1c2SMark Johnston #define XMM_OPND 3 /* "value" used to indicate a xmm reg */
28950339a1c2SMark Johnston #define SEG_OPND 4 /* "value" used to indicate a segment reg */
28960339a1c2SMark Johnston #define CONTROL_OPND 5 /* "value" used to indicate a control reg */
28970339a1c2SMark Johnston #define DEBUG_OPND 6 /* "value" used to indicate a debug reg */
28980339a1c2SMark Johnston #define TEST_OPND 7 /* "value" used to indicate a test reg */
28990339a1c2SMark Johnston #define WORD_OPND 8 /* w-bit value indicating word size reg */
29000339a1c2SMark Johnston #define YMM_OPND 9 /* "value" used to indicate a ymm reg */
2901722b2e2fSMark Johnston #define KOPMASK_OPND 10 /* "value" used to indicate an opmask reg */
2902722b2e2fSMark Johnston #define ZMM_OPND 11 /* "value" used to indicate a zmm reg */
29030339a1c2SMark Johnston
29040339a1c2SMark Johnston /*
2905b3b5bfebSMark Johnston * The AVX2 gather instructions are a bit of a mess. While there's a pattern,
2906b3b5bfebSMark Johnston * there's not really a consistent scheme that we can use to know what the mode
2907b3b5bfebSMark Johnston * is supposed to be for a given type. Various instructions, like VPGATHERDD,
2908b3b5bfebSMark Johnston * always match the value of VEX_L. Other instructions like VPGATHERDQ, have
2909b3b5bfebSMark Johnston * some registers match VEX_L, but the VSIB is always XMM.
2910b3b5bfebSMark Johnston *
2911b3b5bfebSMark Johnston * The simplest way to deal with this is to just define a table based on the
2912b3b5bfebSMark Johnston * instruction opcodes, which are 0x90-0x93, so we subtract 0x90 to index into
2913b3b5bfebSMark Johnston * them.
2914b3b5bfebSMark Johnston *
2915b3b5bfebSMark Johnston * We further have to subdivide this based on the value of VEX_W and the value
2916b3b5bfebSMark Johnston * of VEX_L. The array is constructed to be indexed as:
2917b3b5bfebSMark Johnston * [opcode - 0x90][VEX_W][VEX_L].
2918b3b5bfebSMark Johnston */
2919b3b5bfebSMark Johnston /* w = 0, 0x90 */
2920b3b5bfebSMark Johnston typedef struct dis_gather_regs {
2921b3b5bfebSMark Johnston uint_t dgr_arg0; /* src reg */
2922b3b5bfebSMark Johnston uint_t dgr_arg1; /* vsib reg */
2923b3b5bfebSMark Johnston uint_t dgr_arg2; /* dst reg */
2924b3b5bfebSMark Johnston char *dgr_suffix; /* suffix to append */
2925b3b5bfebSMark Johnston } dis_gather_regs_t;
2926b3b5bfebSMark Johnston
2927b3b5bfebSMark Johnston static dis_gather_regs_t dis_vgather[4][2][2] = {
2928b3b5bfebSMark Johnston {
2929b3b5bfebSMark Johnston /* op 0x90, W.0 */
2930b3b5bfebSMark Johnston {
2931b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2932b3b5bfebSMark Johnston { YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2933b3b5bfebSMark Johnston },
2934b3b5bfebSMark Johnston /* op 0x90, W.1 */
2935b3b5bfebSMark Johnston {
2936b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2937b3b5bfebSMark Johnston { YMM_OPND, XMM_OPND, YMM_OPND, "q" }
2938b3b5bfebSMark Johnston }
2939b3b5bfebSMark Johnston },
2940b3b5bfebSMark Johnston {
2941b3b5bfebSMark Johnston /* op 0x91, W.0 */
2942b3b5bfebSMark Johnston {
2943b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2944b3b5bfebSMark Johnston { XMM_OPND, YMM_OPND, XMM_OPND, "d" },
2945b3b5bfebSMark Johnston },
2946b3b5bfebSMark Johnston /* op 0x91, W.1 */
2947b3b5bfebSMark Johnston {
2948b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2949b3b5bfebSMark Johnston { YMM_OPND, YMM_OPND, YMM_OPND, "q" },
2950b3b5bfebSMark Johnston }
2951b3b5bfebSMark Johnston },
2952b3b5bfebSMark Johnston {
2953b3b5bfebSMark Johnston /* op 0x92, W.0 */
2954b3b5bfebSMark Johnston {
2955b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2956b3b5bfebSMark Johnston { YMM_OPND, YMM_OPND, YMM_OPND, "s" }
2957b3b5bfebSMark Johnston },
2958b3b5bfebSMark Johnston /* op 0x92, W.1 */
2959b3b5bfebSMark Johnston {
2960b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2961b3b5bfebSMark Johnston { YMM_OPND, XMM_OPND, YMM_OPND, "d" }
2962b3b5bfebSMark Johnston }
2963b3b5bfebSMark Johnston },
2964b3b5bfebSMark Johnston {
2965b3b5bfebSMark Johnston /* op 0x93, W.0 */
2966b3b5bfebSMark Johnston {
2967b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2968b3b5bfebSMark Johnston { XMM_OPND, YMM_OPND, XMM_OPND, "s" }
2969b3b5bfebSMark Johnston },
2970b3b5bfebSMark Johnston /* op 0x93, W.1 */
2971b3b5bfebSMark Johnston {
2972b3b5bfebSMark Johnston { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2973b3b5bfebSMark Johnston { YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2974b3b5bfebSMark Johnston }
2975b3b5bfebSMark Johnston }
2976b3b5bfebSMark Johnston };
2977b3b5bfebSMark Johnston
2978b3b5bfebSMark Johnston /*
29790339a1c2SMark Johnston * Get the next byte and separate the op code into the high and low nibbles.
29800339a1c2SMark Johnston */
29810339a1c2SMark Johnston static int
dtrace_get_opcode(dis86_t * x,uint_t * high,uint_t * low)29820339a1c2SMark Johnston dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
29830339a1c2SMark Johnston {
29840339a1c2SMark Johnston int byte;
29850339a1c2SMark Johnston
29860339a1c2SMark Johnston /*
29870339a1c2SMark Johnston * x86 instructions have a maximum length of 15 bytes. Bail out if
29880339a1c2SMark Johnston * we try to read more.
29890339a1c2SMark Johnston */
29900339a1c2SMark Johnston if (x->d86_len >= 15)
29910339a1c2SMark Johnston return (x->d86_error = 1);
29920339a1c2SMark Johnston
29930339a1c2SMark Johnston if (x->d86_error)
29940339a1c2SMark Johnston return (1);
29950339a1c2SMark Johnston byte = x->d86_get_byte(x->d86_data);
29960339a1c2SMark Johnston if (byte < 0)
29970339a1c2SMark Johnston return (x->d86_error = 1);
29980339a1c2SMark Johnston x->d86_bytes[x->d86_len++] = byte;
29990339a1c2SMark Johnston *low = byte & 0xf; /* ----xxxx low 4 bits */
30000339a1c2SMark Johnston *high = byte >> 4 & 0xf; /* xxxx---- bits 7 to 4 */
30010339a1c2SMark Johnston return (0);
30020339a1c2SMark Johnston }
30030339a1c2SMark Johnston
30040339a1c2SMark Johnston /*
30050339a1c2SMark Johnston * Get and decode an SIB (scaled index base) byte
30060339a1c2SMark Johnston */
30070339a1c2SMark Johnston static void
dtrace_get_SIB(dis86_t * x,uint_t * ss,uint_t * index,uint_t * base)30080339a1c2SMark Johnston dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
30090339a1c2SMark Johnston {
30100339a1c2SMark Johnston int byte;
30110339a1c2SMark Johnston
30120339a1c2SMark Johnston if (x->d86_error)
30130339a1c2SMark Johnston return;
30140339a1c2SMark Johnston
30150339a1c2SMark Johnston byte = x->d86_get_byte(x->d86_data);
30160339a1c2SMark Johnston if (byte < 0) {
30170339a1c2SMark Johnston x->d86_error = 1;
30180339a1c2SMark Johnston return;
30190339a1c2SMark Johnston }
30200339a1c2SMark Johnston x->d86_bytes[x->d86_len++] = byte;
30210339a1c2SMark Johnston
30220339a1c2SMark Johnston *base = byte & 0x7;
30230339a1c2SMark Johnston *index = (byte >> 3) & 0x7;
30240339a1c2SMark Johnston *ss = (byte >> 6) & 0x3;
30250339a1c2SMark Johnston }
30260339a1c2SMark Johnston
30270339a1c2SMark Johnston /*
30280339a1c2SMark Johnston * Get the byte following the op code and separate it into the
30290339a1c2SMark Johnston * mode, register, and r/m fields.
30300339a1c2SMark Johnston */
30310339a1c2SMark Johnston static void
dtrace_get_modrm(dis86_t * x,uint_t * mode,uint_t * reg,uint_t * r_m)30320339a1c2SMark Johnston dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
30330339a1c2SMark Johnston {
30340339a1c2SMark Johnston if (x->d86_got_modrm == 0) {
30350339a1c2SMark Johnston if (x->d86_rmindex == -1)
30360339a1c2SMark Johnston x->d86_rmindex = x->d86_len;
30370339a1c2SMark Johnston dtrace_get_SIB(x, mode, reg, r_m);
30380339a1c2SMark Johnston x->d86_got_modrm = 1;
30390339a1c2SMark Johnston }
30400339a1c2SMark Johnston }
30410339a1c2SMark Johnston
30420339a1c2SMark Johnston /*
30430339a1c2SMark Johnston * Adjust register selection based on any REX prefix bits present.
30440339a1c2SMark Johnston */
30450339a1c2SMark Johnston /*ARGSUSED*/
30460339a1c2SMark Johnston static void
dtrace_rex_adjust(uint_t rex_prefix,uint_t mode,uint_t * reg,uint_t * r_m)30470339a1c2SMark Johnston dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
30480339a1c2SMark Johnston {
30490339a1c2SMark Johnston if (reg != NULL && r_m == NULL) {
30500339a1c2SMark Johnston if (rex_prefix & REX_B)
30510339a1c2SMark Johnston *reg += 8;
30520339a1c2SMark Johnston } else {
30530339a1c2SMark Johnston if (reg != NULL && (REX_R & rex_prefix) != 0)
30540339a1c2SMark Johnston *reg += 8;
30550339a1c2SMark Johnston if (r_m != NULL && (REX_B & rex_prefix) != 0)
30560339a1c2SMark Johnston *r_m += 8;
30570339a1c2SMark Johnston }
30580339a1c2SMark Johnston }
30590339a1c2SMark Johnston
30600339a1c2SMark Johnston /*
30610339a1c2SMark Johnston * Adjust register selection based on any VEX prefix bits present.
30620339a1c2SMark Johnston * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
30630339a1c2SMark Johnston */
30640339a1c2SMark Johnston /*ARGSUSED*/
30650339a1c2SMark Johnston static void
dtrace_vex_adjust(uint_t vex_byte1,uint_t mode,uint_t * reg,uint_t * r_m)30660339a1c2SMark Johnston dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
30670339a1c2SMark Johnston {
30680339a1c2SMark Johnston if (reg != NULL && r_m == NULL) {
30690339a1c2SMark Johnston if (!(vex_byte1 & VEX_B))
30700339a1c2SMark Johnston *reg += 8;
30710339a1c2SMark Johnston } else {
30720339a1c2SMark Johnston if (reg != NULL && ((VEX_R & vex_byte1) == 0))
30730339a1c2SMark Johnston *reg += 8;
30740339a1c2SMark Johnston if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
30750339a1c2SMark Johnston *r_m += 8;
30760339a1c2SMark Johnston }
30770339a1c2SMark Johnston }
30780339a1c2SMark Johnston
30790339a1c2SMark Johnston /*
3080722b2e2fSMark Johnston * Adjust the instruction mnemonic with the appropriate suffix.
3081722b2e2fSMark Johnston */
3082722b2e2fSMark Johnston /* ARGSUSED */
3083722b2e2fSMark Johnston static void
dtrace_evex_mnem_adjust(dis86_t * x,const instable_t * dp,uint_t vex_W,uint_t evex_byte2)3084722b2e2fSMark Johnston dtrace_evex_mnem_adjust(dis86_t *x, const instable_t *dp, uint_t vex_W,
3085722b2e2fSMark Johnston uint_t evex_byte2)
3086722b2e2fSMark Johnston {
3087722b2e2fSMark Johnston #ifdef DIS_TEXT
3088722b2e2fSMark Johnston if (dp == &dis_opEVEX660F[0x7f] || /* vmovdqa */
3089722b2e2fSMark Johnston dp == &dis_opEVEX660F[0x6f]) {
3090722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, vex_W != 0 ? "64" : "32",
3091722b2e2fSMark Johnston OPLEN);
3092722b2e2fSMark Johnston }
3093722b2e2fSMark Johnston
3094722b2e2fSMark Johnston if (dp == &dis_opEVEXF20F[0x7f] || /* vmovdqu */
3095722b2e2fSMark Johnston dp == &dis_opEVEXF20F[0x6f] ||
3096722b2e2fSMark Johnston dp == &dis_opEVEXF30F[0x7f] ||
3097722b2e2fSMark Johnston dp == &dis_opEVEXF30F[0x6f]) {
3098722b2e2fSMark Johnston switch (evex_byte2 & 0x81) {
3099722b2e2fSMark Johnston case 0x0:
3100722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "32", OPLEN);
3101722b2e2fSMark Johnston break;
3102722b2e2fSMark Johnston case 0x1:
3103722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "8", OPLEN);
3104722b2e2fSMark Johnston break;
3105722b2e2fSMark Johnston case 0x80:
3106722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "64", OPLEN);
3107722b2e2fSMark Johnston break;
3108722b2e2fSMark Johnston case 0x81:
3109722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "16", OPLEN);
3110722b2e2fSMark Johnston break;
3111722b2e2fSMark Johnston }
3112722b2e2fSMark Johnston }
3113722b2e2fSMark Johnston
3114722b2e2fSMark Johnston if (dp->it_avxsuf == AVS5Q) {
3115722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",
3116722b2e2fSMark Johnston OPLEN);
3117722b2e2fSMark Johnston }
3118722b2e2fSMark Johnston #endif
3119722b2e2fSMark Johnston }
3120722b2e2fSMark Johnston
3121722b2e2fSMark Johnston /*
3122722b2e2fSMark Johnston * The following three functions adjust the register selection based on any
3123722b2e2fSMark Johnston * EVEX prefix bits present. See Intel 64 and IA-32 Architectures Software
3124722b2e2fSMark Johnston * Developer’s Manual Volume 2 (IASDv2), section 2.6.1 Table 2-30 and
3125722b2e2fSMark Johnston * section 2.6.2 Table 2-31.
3126722b2e2fSMark Johnston */
3127722b2e2fSMark Johnston static void
dtrace_evex_adjust_reg(uint_t evex_byte1,uint_t * reg)3128722b2e2fSMark Johnston dtrace_evex_adjust_reg(uint_t evex_byte1, uint_t *reg)
3129722b2e2fSMark Johnston {
3130722b2e2fSMark Johnston if (reg != NULL) {
3131722b2e2fSMark Johnston if ((VEX_R & evex_byte1) == 0) {
3132722b2e2fSMark Johnston *reg += 8;
3133722b2e2fSMark Johnston }
3134722b2e2fSMark Johnston if ((EVEX_R & evex_byte1) == 0) {
3135722b2e2fSMark Johnston *reg += 16;
3136722b2e2fSMark Johnston }
3137722b2e2fSMark Johnston }
3138722b2e2fSMark Johnston }
3139722b2e2fSMark Johnston
3140722b2e2fSMark Johnston static void
dtrace_evex_adjust_rm(uint_t evex_byte1,uint_t * r_m)3141722b2e2fSMark Johnston dtrace_evex_adjust_rm(uint_t evex_byte1, uint_t *r_m)
3142722b2e2fSMark Johnston {
3143722b2e2fSMark Johnston if (r_m != NULL) {
3144722b2e2fSMark Johnston if ((VEX_B & evex_byte1) == 0) {
3145722b2e2fSMark Johnston *r_m += 8;
3146722b2e2fSMark Johnston }
3147722b2e2fSMark Johnston if ((VEX_X & evex_byte1) == 0) {
3148722b2e2fSMark Johnston *r_m += 16;
3149722b2e2fSMark Johnston }
3150722b2e2fSMark Johnston }
3151722b2e2fSMark Johnston }
3152722b2e2fSMark Johnston
3153722b2e2fSMark Johnston /*
3154722b2e2fSMark Johnston * Use evex_L to set wbit. See IASDv2 Section 2.6.10 and Table 2-36.
3155722b2e2fSMark Johnston */
3156722b2e2fSMark Johnston static void
dtrace_evex_adjust_reg_name(uint_t evex_L,uint_t * wbitp)3157722b2e2fSMark Johnston dtrace_evex_adjust_reg_name(uint_t evex_L, uint_t *wbitp)
3158722b2e2fSMark Johnston {
3159722b2e2fSMark Johnston switch (evex_L) {
3160722b2e2fSMark Johnston case 0x0:
3161722b2e2fSMark Johnston *wbitp = XMM_OPND;
3162722b2e2fSMark Johnston break;
3163722b2e2fSMark Johnston case 0x1:
3164722b2e2fSMark Johnston *wbitp = YMM_OPND;
3165722b2e2fSMark Johnston break;
3166722b2e2fSMark Johnston case 0x2:
3167722b2e2fSMark Johnston *wbitp = ZMM_OPND;
3168722b2e2fSMark Johnston break;
3169722b2e2fSMark Johnston }
3170722b2e2fSMark Johnston }
3171722b2e2fSMark Johnston
3172722b2e2fSMark Johnston /*
3173722b2e2fSMark Johnston * Adjust operand value for disp8*N immediate. See IASDv2 Section 2.6.5.
3174722b2e2fSMark Johnston * This currently only handles a subset of the possibilities.
3175722b2e2fSMark Johnston */
3176722b2e2fSMark Johnston static void
dtrace_evex_adjust_disp8_n(dis86_t * x,int opindex,uint_t L,uint_t modrm)3177722b2e2fSMark Johnston dtrace_evex_adjust_disp8_n(dis86_t *x, int opindex, uint_t L, uint_t modrm)
3178722b2e2fSMark Johnston {
3179722b2e2fSMark Johnston d86opnd_t *opnd = &x->d86_opnd[opindex];
3180722b2e2fSMark Johnston
3181722b2e2fSMark Johnston if (x->d86_error)
3182722b2e2fSMark Johnston return;
3183722b2e2fSMark Johnston
3184722b2e2fSMark Johnston /* Check disp8 bit in the ModR/M byte */
3185722b2e2fSMark Johnston if ((modrm & 0x80) == 0x80)
3186722b2e2fSMark Johnston return;
3187722b2e2fSMark Johnston
3188722b2e2fSMark Johnston /* use evex_L to adjust the value */
3189722b2e2fSMark Johnston switch (L) {
3190722b2e2fSMark Johnston case 0x0:
3191722b2e2fSMark Johnston opnd->d86_value *= 16;
3192722b2e2fSMark Johnston break;
3193722b2e2fSMark Johnston case 0x1:
3194722b2e2fSMark Johnston opnd->d86_value *= 32;
3195722b2e2fSMark Johnston break;
3196722b2e2fSMark Johnston case 0x2:
3197722b2e2fSMark Johnston opnd->d86_value *= 64;
3198722b2e2fSMark Johnston break;
3199722b2e2fSMark Johnston }
3200722b2e2fSMark Johnston }
3201722b2e2fSMark Johnston
3202722b2e2fSMark Johnston /*
3203722b2e2fSMark Johnston * Adjust target for opmask and zeroing. See IASDv2 Section 2.6.1 Table 2-30.
3204722b2e2fSMark Johnston */
3205722b2e2fSMark Johnston /* ARGSUSED */
3206722b2e2fSMark Johnston static void
dtrace_evex_adjust_z_opmask(dis86_t * x,uint_t tgtop,uint_t evex_byte3)3207722b2e2fSMark Johnston dtrace_evex_adjust_z_opmask(dis86_t *x, uint_t tgtop, uint_t evex_byte3)
3208722b2e2fSMark Johnston {
3209722b2e2fSMark Johnston #ifdef DIS_TEXT
3210722b2e2fSMark Johnston char *opnd = x->d86_opnd[tgtop].d86_opnd;
3211722b2e2fSMark Johnston int opmask_reg = evex_byte3 & EVEX_OPREG_MASK;
3212722b2e2fSMark Johnston #endif
3213722b2e2fSMark Johnston if (x->d86_error)
3214722b2e2fSMark Johnston return;
3215722b2e2fSMark Johnston
3216722b2e2fSMark Johnston #ifdef DIS_TEXT
3217722b2e2fSMark Johnston if (opmask_reg != 0) {
3218722b2e2fSMark Johnston /* Append the opmask register to operand 1 */
3219722b2e2fSMark Johnston (void) strlcat(opnd, "{", OPLEN);
3220722b2e2fSMark Johnston (void) strlcat(opnd, dis_KOPMASKREG[opmask_reg], OPLEN);
3221722b2e2fSMark Johnston (void) strlcat(opnd, "}", OPLEN);
3222722b2e2fSMark Johnston }
3223722b2e2fSMark Johnston if ((evex_byte3 & EVEX_ZERO_MASK) != 0) {
3224722b2e2fSMark Johnston /* Append the 'zeroing' modifier to operand 1 */
3225722b2e2fSMark Johnston (void) strlcat(opnd, "{z}", OPLEN);
3226722b2e2fSMark Johnston }
3227722b2e2fSMark Johnston #endif /* DIS_TEXT */
3228722b2e2fSMark Johnston }
3229722b2e2fSMark Johnston
3230722b2e2fSMark Johnston /*
32310339a1c2SMark Johnston * Get an immediate operand of the given size, with sign extension.
32320339a1c2SMark Johnston */
32330339a1c2SMark Johnston static void
dtrace_imm_opnd(dis86_t * x,int wbit,int size,int opindex)32340339a1c2SMark Johnston dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
32350339a1c2SMark Johnston {
32360339a1c2SMark Johnston int i;
32370339a1c2SMark Johnston int byte;
32380339a1c2SMark Johnston int valsize;
32390339a1c2SMark Johnston
32400339a1c2SMark Johnston if (x->d86_numopnds < opindex + 1)
32410339a1c2SMark Johnston x->d86_numopnds = opindex + 1;
32420339a1c2SMark Johnston
32430339a1c2SMark Johnston switch (wbit) {
32440339a1c2SMark Johnston case BYTE_OPND:
32450339a1c2SMark Johnston valsize = 1;
32460339a1c2SMark Johnston break;
32470339a1c2SMark Johnston case LONG_OPND:
32480339a1c2SMark Johnston if (x->d86_opnd_size == SIZE16)
32490339a1c2SMark Johnston valsize = 2;
32500339a1c2SMark Johnston else if (x->d86_opnd_size == SIZE32)
32510339a1c2SMark Johnston valsize = 4;
32520339a1c2SMark Johnston else
32530339a1c2SMark Johnston valsize = 8;
32540339a1c2SMark Johnston break;
32550339a1c2SMark Johnston case MM_OPND:
32560339a1c2SMark Johnston case XMM_OPND:
32570339a1c2SMark Johnston case YMM_OPND:
3258722b2e2fSMark Johnston case ZMM_OPND:
32590339a1c2SMark Johnston case SEG_OPND:
32600339a1c2SMark Johnston case CONTROL_OPND:
32610339a1c2SMark Johnston case DEBUG_OPND:
32620339a1c2SMark Johnston case TEST_OPND:
32630339a1c2SMark Johnston valsize = size;
32640339a1c2SMark Johnston break;
32650339a1c2SMark Johnston case WORD_OPND:
32660339a1c2SMark Johnston valsize = 2;
32670339a1c2SMark Johnston break;
32680339a1c2SMark Johnston }
32690339a1c2SMark Johnston if (valsize < size)
32700339a1c2SMark Johnston valsize = size;
32710339a1c2SMark Johnston
32720339a1c2SMark Johnston if (x->d86_error)
32730339a1c2SMark Johnston return;
32740339a1c2SMark Johnston x->d86_opnd[opindex].d86_value = 0;
32750339a1c2SMark Johnston for (i = 0; i < size; ++i) {
32760339a1c2SMark Johnston byte = x->d86_get_byte(x->d86_data);
32770339a1c2SMark Johnston if (byte < 0) {
32780339a1c2SMark Johnston x->d86_error = 1;
32790339a1c2SMark Johnston return;
32800339a1c2SMark Johnston }
32810339a1c2SMark Johnston x->d86_bytes[x->d86_len++] = byte;
32820339a1c2SMark Johnston x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
32830339a1c2SMark Johnston }
32840339a1c2SMark Johnston /* Do sign extension */
32850339a1c2SMark Johnston if (x->d86_bytes[x->d86_len - 1] & 0x80) {
32860339a1c2SMark Johnston for (; i < sizeof (uint64_t); i++)
32870339a1c2SMark Johnston x->d86_opnd[opindex].d86_value |=
32880339a1c2SMark Johnston (uint64_t)0xff << (i * 8);
32890339a1c2SMark Johnston }
32900339a1c2SMark Johnston #ifdef DIS_TEXT
32910339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
32920339a1c2SMark Johnston x->d86_opnd[opindex].d86_value_size = valsize;
32930339a1c2SMark Johnston x->d86_imm_bytes += size;
32940339a1c2SMark Johnston #endif
32950339a1c2SMark Johnston }
32960339a1c2SMark Johnston
32970339a1c2SMark Johnston /*
32980339a1c2SMark Johnston * Get an ip relative operand of the given size, with sign extension.
32990339a1c2SMark Johnston */
33000339a1c2SMark Johnston static void
dtrace_disp_opnd(dis86_t * x,int wbit,int size,int opindex)33010339a1c2SMark Johnston dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
33020339a1c2SMark Johnston {
33030339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, size, opindex);
33040339a1c2SMark Johnston #ifdef DIS_TEXT
33050339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_IPREL;
33060339a1c2SMark Johnston #endif
33070339a1c2SMark Johnston }
33080339a1c2SMark Johnston
33090339a1c2SMark Johnston /*
33100339a1c2SMark Johnston * Check to see if there is a segment override prefix pending.
33110339a1c2SMark Johnston * If so, print it in the current 'operand' location and set
33120339a1c2SMark Johnston * the override flag back to false.
33130339a1c2SMark Johnston */
33140339a1c2SMark Johnston /*ARGSUSED*/
33150339a1c2SMark Johnston static void
dtrace_check_override(dis86_t * x,int opindex)33160339a1c2SMark Johnston dtrace_check_override(dis86_t *x, int opindex)
33170339a1c2SMark Johnston {
33180339a1c2SMark Johnston #ifdef DIS_TEXT
33190339a1c2SMark Johnston if (x->d86_seg_prefix) {
33200339a1c2SMark Johnston (void) strlcat(x->d86_opnd[opindex].d86_prefix,
33210339a1c2SMark Johnston x->d86_seg_prefix, PFIXLEN);
33220339a1c2SMark Johnston }
33230339a1c2SMark Johnston #endif
33240339a1c2SMark Johnston x->d86_seg_prefix = NULL;
33250339a1c2SMark Johnston }
33260339a1c2SMark Johnston
33270339a1c2SMark Johnston
33280339a1c2SMark Johnston /*
33290339a1c2SMark Johnston * Process a single instruction Register or Memory operand.
33300339a1c2SMark Johnston *
33310339a1c2SMark Johnston * mode = addressing mode from ModRM byte
33320339a1c2SMark Johnston * r_m = r_m (or reg if mode == 3) field from ModRM byte
33330339a1c2SMark Johnston * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
33340339a1c2SMark Johnston * o = index of operand that we are processing (0, 1 or 2)
33350339a1c2SMark Johnston *
33360339a1c2SMark Johnston * the value of reg or r_m must have already been adjusted for any REX prefix.
33370339a1c2SMark Johnston */
33380339a1c2SMark Johnston /*ARGSUSED*/
33390339a1c2SMark Johnston static void
dtrace_get_operand(dis86_t * x,uint_t mode,uint_t r_m,int wbit,int opindex)33400339a1c2SMark Johnston dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
33410339a1c2SMark Johnston {
33420339a1c2SMark Johnston int have_SIB = 0; /* flag presence of scale-index-byte */
33430339a1c2SMark Johnston uint_t ss; /* scale-factor from opcode */
33440339a1c2SMark Johnston uint_t index; /* index register number */
33450339a1c2SMark Johnston uint_t base; /* base register number */
33460339a1c2SMark Johnston int dispsize; /* size of displacement in bytes */
33470339a1c2SMark Johnston #ifdef DIS_TEXT
33480339a1c2SMark Johnston char *opnd = x->d86_opnd[opindex].d86_opnd;
33490339a1c2SMark Johnston #endif
33500339a1c2SMark Johnston
33510339a1c2SMark Johnston if (x->d86_numopnds < opindex + 1)
33520339a1c2SMark Johnston x->d86_numopnds = opindex + 1;
33530339a1c2SMark Johnston
33540339a1c2SMark Johnston if (x->d86_error)
33550339a1c2SMark Johnston return;
33560339a1c2SMark Johnston
33570339a1c2SMark Johnston /*
33580339a1c2SMark Johnston * first handle a simple register
33590339a1c2SMark Johnston */
33600339a1c2SMark Johnston if (mode == REG_ONLY) {
33610339a1c2SMark Johnston #ifdef DIS_TEXT
33620339a1c2SMark Johnston switch (wbit) {
33630339a1c2SMark Johnston case MM_OPND:
33640339a1c2SMark Johnston (void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
33650339a1c2SMark Johnston break;
33660339a1c2SMark Johnston case XMM_OPND:
33670339a1c2SMark Johnston (void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
33680339a1c2SMark Johnston break;
33690339a1c2SMark Johnston case YMM_OPND:
33700339a1c2SMark Johnston (void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
33710339a1c2SMark Johnston break;
3372722b2e2fSMark Johnston case ZMM_OPND:
3373722b2e2fSMark Johnston (void) strlcat(opnd, dis_ZMMREG[r_m], OPLEN);
3374722b2e2fSMark Johnston break;
3375722b2e2fSMark Johnston case KOPMASK_OPND:
3376722b2e2fSMark Johnston (void) strlcat(opnd, dis_KOPMASKREG[r_m], OPLEN);
3377722b2e2fSMark Johnston break;
33780339a1c2SMark Johnston case SEG_OPND:
33790339a1c2SMark Johnston (void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
33800339a1c2SMark Johnston break;
33810339a1c2SMark Johnston case CONTROL_OPND:
33820339a1c2SMark Johnston (void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
33830339a1c2SMark Johnston break;
33840339a1c2SMark Johnston case DEBUG_OPND:
33850339a1c2SMark Johnston (void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
33860339a1c2SMark Johnston break;
33870339a1c2SMark Johnston case TEST_OPND:
33880339a1c2SMark Johnston (void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
33890339a1c2SMark Johnston break;
33900339a1c2SMark Johnston case BYTE_OPND:
33910339a1c2SMark Johnston if (x->d86_rex_prefix == 0)
33920339a1c2SMark Johnston (void) strlcat(opnd, dis_REG8[r_m], OPLEN);
33930339a1c2SMark Johnston else
33940339a1c2SMark Johnston (void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
33950339a1c2SMark Johnston break;
33960339a1c2SMark Johnston case WORD_OPND:
33970339a1c2SMark Johnston (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
33980339a1c2SMark Johnston break;
33990339a1c2SMark Johnston case LONG_OPND:
34000339a1c2SMark Johnston if (x->d86_opnd_size == SIZE16)
34010339a1c2SMark Johnston (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
34020339a1c2SMark Johnston else if (x->d86_opnd_size == SIZE32)
34030339a1c2SMark Johnston (void) strlcat(opnd, dis_REG32[r_m], OPLEN);
34040339a1c2SMark Johnston else
34050339a1c2SMark Johnston (void) strlcat(opnd, dis_REG64[r_m], OPLEN);
34060339a1c2SMark Johnston break;
34070339a1c2SMark Johnston }
34080339a1c2SMark Johnston #endif /* DIS_TEXT */
34090339a1c2SMark Johnston return;
34100339a1c2SMark Johnston }
34110339a1c2SMark Johnston
34120339a1c2SMark Johnston /*
34130339a1c2SMark Johnston * if symbolic representation, skip override prefix, if any
34140339a1c2SMark Johnston */
34150339a1c2SMark Johnston dtrace_check_override(x, opindex);
34160339a1c2SMark Johnston
34170339a1c2SMark Johnston /*
34180339a1c2SMark Johnston * Handle 16 bit memory references first, since they decode
34190339a1c2SMark Johnston * the mode values more simply.
34200339a1c2SMark Johnston * mode 1 is r_m + 8 bit displacement
34210339a1c2SMark Johnston * mode 2 is r_m + 16 bit displacement
34220339a1c2SMark Johnston * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
34230339a1c2SMark Johnston */
34240339a1c2SMark Johnston if (x->d86_addr_size == SIZE16) {
34250339a1c2SMark Johnston if ((mode == 0 && r_m == 6) || mode == 2)
34260339a1c2SMark Johnston dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
34270339a1c2SMark Johnston else if (mode == 1)
34280339a1c2SMark Johnston dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
34290339a1c2SMark Johnston #ifdef DIS_TEXT
34300339a1c2SMark Johnston if (mode == 0 && r_m == 6)
34310339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
34320339a1c2SMark Johnston else if (mode == 0)
34330339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_NONE;
34340339a1c2SMark Johnston else
34350339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
34360339a1c2SMark Johnston (void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
34370339a1c2SMark Johnston #endif
34380339a1c2SMark Johnston return;
34390339a1c2SMark Johnston }
34400339a1c2SMark Johnston
34410339a1c2SMark Johnston /*
3442722b2e2fSMark Johnston * 32 and 64 bit addressing modes are more complex since they can
3443722b2e2fSMark Johnston * involve an SIB (scaled index and base) byte to decode. When using VEX
3444722b2e2fSMark Johnston * and EVEX encodings, the r_m indicator for a SIB may be offset by 8
3445722b2e2fSMark Johnston * and 24 (8 + 16) respectively.
34460339a1c2SMark Johnston */
3447722b2e2fSMark Johnston if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8 || r_m == ESP_REGNO + 24) {
34480339a1c2SMark Johnston have_SIB = 1;
34490339a1c2SMark Johnston dtrace_get_SIB(x, &ss, &index, &base);
34500339a1c2SMark Johnston if (x->d86_error)
34510339a1c2SMark Johnston return;
34520339a1c2SMark Johnston if (base != 5 || mode != 0)
34530339a1c2SMark Johnston if (x->d86_rex_prefix & REX_B)
34540339a1c2SMark Johnston base += 8;
34550339a1c2SMark Johnston if (x->d86_rex_prefix & REX_X)
34560339a1c2SMark Johnston index += 8;
34570339a1c2SMark Johnston } else {
34580339a1c2SMark Johnston base = r_m;
34590339a1c2SMark Johnston }
34600339a1c2SMark Johnston
34610339a1c2SMark Johnston /*
34620339a1c2SMark Johnston * Compute the displacement size and get its bytes
34630339a1c2SMark Johnston */
34640339a1c2SMark Johnston dispsize = 0;
34650339a1c2SMark Johnston
34660339a1c2SMark Johnston if (mode == 1)
34670339a1c2SMark Johnston dispsize = 1;
34680339a1c2SMark Johnston else if (mode == 2)
34690339a1c2SMark Johnston dispsize = 4;
34700339a1c2SMark Johnston else if ((r_m & 7) == EBP_REGNO ||
34710339a1c2SMark Johnston (have_SIB && (base & 7) == EBP_REGNO))
34720339a1c2SMark Johnston dispsize = 4;
34730339a1c2SMark Johnston
34740339a1c2SMark Johnston if (dispsize > 0) {
34750339a1c2SMark Johnston dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
34760339a1c2SMark Johnston dispsize, opindex);
34770339a1c2SMark Johnston if (x->d86_error)
34780339a1c2SMark Johnston return;
34790339a1c2SMark Johnston }
34800339a1c2SMark Johnston
34810339a1c2SMark Johnston #ifdef DIS_TEXT
34820339a1c2SMark Johnston if (dispsize > 0)
34830339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
34840339a1c2SMark Johnston
34850339a1c2SMark Johnston if (have_SIB == 0) {
34860339a1c2SMark Johnston if (x->d86_mode == SIZE32) {
34870339a1c2SMark Johnston if (mode == 0)
34880339a1c2SMark Johnston (void) strlcat(opnd, dis_addr32_mode0[r_m],
34890339a1c2SMark Johnston OPLEN);
34900339a1c2SMark Johnston else
34910339a1c2SMark Johnston (void) strlcat(opnd, dis_addr32_mode12[r_m],
34920339a1c2SMark Johnston OPLEN);
34930339a1c2SMark Johnston } else {
34940339a1c2SMark Johnston if (mode == 0) {
34950339a1c2SMark Johnston (void) strlcat(opnd, dis_addr64_mode0[r_m],
34960339a1c2SMark Johnston OPLEN);
34970339a1c2SMark Johnston if (r_m == 5) {
34980339a1c2SMark Johnston x->d86_opnd[opindex].d86_mode =
34990339a1c2SMark Johnston MODE_RIPREL;
35000339a1c2SMark Johnston }
35010339a1c2SMark Johnston } else {
35020339a1c2SMark Johnston (void) strlcat(opnd, dis_addr64_mode12[r_m],
35030339a1c2SMark Johnston OPLEN);
35040339a1c2SMark Johnston }
35050339a1c2SMark Johnston }
35060339a1c2SMark Johnston } else {
35070339a1c2SMark Johnston uint_t need_paren = 0;
35080339a1c2SMark Johnston char **regs;
3509b3b5bfebSMark Johnston char **bregs;
3510b3b5bfebSMark Johnston const char *const *sf;
35110339a1c2SMark Johnston if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
35120339a1c2SMark Johnston regs = (char **)dis_REG32;
35130339a1c2SMark Johnston else
35140339a1c2SMark Johnston regs = (char **)dis_REG64;
35150339a1c2SMark Johnston
3516b3b5bfebSMark Johnston if (x->d86_vsib != 0) {
3517722b2e2fSMark Johnston if (wbit == YMM_OPND) { /* NOTE this is not addr_size */
3518b3b5bfebSMark Johnston bregs = (char **)dis_YMMREG;
3519722b2e2fSMark Johnston } else if (wbit == XMM_OPND) {
3520b3b5bfebSMark Johnston bregs = (char **)dis_XMMREG;
3521722b2e2fSMark Johnston } else {
3522722b2e2fSMark Johnston bregs = (char **)dis_ZMMREG;
3523722b2e2fSMark Johnston }
3524b3b5bfebSMark Johnston sf = dis_vscale_factor;
3525b3b5bfebSMark Johnston } else {
3526b3b5bfebSMark Johnston bregs = regs;
3527b3b5bfebSMark Johnston sf = dis_scale_factor;
3528b3b5bfebSMark Johnston }
3529b3b5bfebSMark Johnston
35300339a1c2SMark Johnston /*
35310339a1c2SMark Johnston * print the base (if any)
35320339a1c2SMark Johnston */
35330339a1c2SMark Johnston if (base == EBP_REGNO && mode == 0) {
3534b3b5bfebSMark Johnston if (index != ESP_REGNO || x->d86_vsib != 0) {
35350339a1c2SMark Johnston (void) strlcat(opnd, "(", OPLEN);
35360339a1c2SMark Johnston need_paren = 1;
35370339a1c2SMark Johnston }
35380339a1c2SMark Johnston } else {
35390339a1c2SMark Johnston (void) strlcat(opnd, "(", OPLEN);
35400339a1c2SMark Johnston (void) strlcat(opnd, regs[base], OPLEN);
35410339a1c2SMark Johnston need_paren = 1;
35420339a1c2SMark Johnston }
35430339a1c2SMark Johnston
35440339a1c2SMark Johnston /*
35450339a1c2SMark Johnston * print the index (if any)
35460339a1c2SMark Johnston */
3547b3b5bfebSMark Johnston if (index != ESP_REGNO || x->d86_vsib) {
35480339a1c2SMark Johnston (void) strlcat(opnd, ",", OPLEN);
3549b3b5bfebSMark Johnston (void) strlcat(opnd, bregs[index], OPLEN);
3550b3b5bfebSMark Johnston (void) strlcat(opnd, sf[ss], OPLEN);
35510339a1c2SMark Johnston } else
35520339a1c2SMark Johnston if (need_paren)
35530339a1c2SMark Johnston (void) strlcat(opnd, ")", OPLEN);
35540339a1c2SMark Johnston }
35550339a1c2SMark Johnston #endif
35560339a1c2SMark Johnston }
35570339a1c2SMark Johnston
35580339a1c2SMark Johnston /*
35590339a1c2SMark Johnston * Operand sequence for standard instruction involving one register
35600339a1c2SMark Johnston * and one register/memory operand.
35610339a1c2SMark Johnston * wbit indicates a byte(0) or opnd_size(1) operation
35620339a1c2SMark Johnston * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
35630339a1c2SMark Johnston */
35640339a1c2SMark Johnston #define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit) { \
35650339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m); \
35660339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \
35670339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, vbit); \
35680339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit); \
35690339a1c2SMark Johnston }
35700339a1c2SMark Johnston
35710339a1c2SMark Johnston /*
35720339a1c2SMark Johnston * Similar to above, but allows for the two operands to be of different
35730339a1c2SMark Johnston * classes (ie. wbit).
35740339a1c2SMark Johnston * wbit is for the r_m operand
35750339a1c2SMark Johnston * w2 is for the reg operand
35760339a1c2SMark Johnston */
35770339a1c2SMark Johnston #define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) { \
35780339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m); \
35790339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \
35800339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, vbit); \
35810339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit); \
35820339a1c2SMark Johnston }
35830339a1c2SMark Johnston
35840339a1c2SMark Johnston /*
35850339a1c2SMark Johnston * Similar, but for 2 operands plus an immediate.
35860339a1c2SMark Johnston * vbit indicates direction
35870339a1c2SMark Johnston * 0 for "opcode imm, r, r_m" or
35880339a1c2SMark Johnston * 1 for "opcode imm, r_m, r"
35890339a1c2SMark Johnston */
35900339a1c2SMark Johnston #define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
35910339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m); \
35920339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \
35930339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2-vbit); \
35940339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit); \
35950339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, immsize, 0); \
35960339a1c2SMark Johnston }
35970339a1c2SMark Johnston
35980339a1c2SMark Johnston /*
35990339a1c2SMark Johnston * Similar, but for 2 operands plus two immediates.
36000339a1c2SMark Johnston */
36010339a1c2SMark Johnston #define FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
36020339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m); \
36030339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \
36040339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2); \
36050339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, w2, 3); \
36060339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, immsize, 1); \
36070339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, immsize, 0); \
36080339a1c2SMark Johnston }
36090339a1c2SMark Johnston
36100339a1c2SMark Johnston /*
36110339a1c2SMark Johnston * 1 operands plus two immediates.
36120339a1c2SMark Johnston */
36130339a1c2SMark Johnston #define ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
36140339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m); \
36150339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \
36160339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2); \
36170339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, immsize, 1); \
36180339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, immsize, 0); \
36190339a1c2SMark Johnston }
36200339a1c2SMark Johnston
36210339a1c2SMark Johnston /*
36220339a1c2SMark Johnston * Dissassemble a single x86 or amd64 instruction.
36230339a1c2SMark Johnston *
36240339a1c2SMark Johnston * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
36250339a1c2SMark Johnston * for interpreting instructions.
36260339a1c2SMark Johnston *
36270339a1c2SMark Johnston * returns non-zero for bad opcode
36280339a1c2SMark Johnston */
36290339a1c2SMark Johnston int
dtrace_disx86(dis86_t * x,uint_t cpu_mode)36300339a1c2SMark Johnston dtrace_disx86(dis86_t *x, uint_t cpu_mode)
36310339a1c2SMark Johnston {
3632722b2e2fSMark Johnston const instable_t *dp; /* decode table being used */
36330339a1c2SMark Johnston #ifdef DIS_TEXT
36340339a1c2SMark Johnston uint_t i;
36350339a1c2SMark Johnston #endif
36360339a1c2SMark Johnston #ifdef DIS_MEM
36370339a1c2SMark Johnston uint_t nomem = 0;
36380339a1c2SMark Johnston #define NOMEM (nomem = 1)
36390339a1c2SMark Johnston #else
36400339a1c2SMark Johnston #define NOMEM /* nothing */
36410339a1c2SMark Johnston #endif
36420339a1c2SMark Johnston uint_t opnd_size; /* SIZE16, SIZE32 or SIZE64 */
36430339a1c2SMark Johnston uint_t addr_size; /* SIZE16, SIZE32 or SIZE64 */
36440339a1c2SMark Johnston uint_t wbit; /* opcode wbit, 0 is 8 bit, !0 for opnd_size */
36450339a1c2SMark Johnston uint_t w2; /* wbit value for second operand */
36460339a1c2SMark Johnston uint_t vbit;
36470339a1c2SMark Johnston uint_t mode = 0; /* mode value from ModRM byte */
36480339a1c2SMark Johnston uint_t reg; /* reg value from ModRM byte */
36490339a1c2SMark Johnston uint_t r_m; /* r_m value from ModRM byte */
36500339a1c2SMark Johnston
36510339a1c2SMark Johnston uint_t opcode1; /* high nibble of 1st byte */
36520339a1c2SMark Johnston uint_t opcode2; /* low nibble of 1st byte */
36530339a1c2SMark Johnston uint_t opcode3; /* extra opcode bits usually from ModRM byte */
36540339a1c2SMark Johnston uint_t opcode4; /* high nibble of 2nd byte */
36550339a1c2SMark Johnston uint_t opcode5; /* low nibble of 2nd byte */
36560339a1c2SMark Johnston uint_t opcode6; /* high nibble of 3rd byte */
36570339a1c2SMark Johnston uint_t opcode7; /* low nibble of 3rd byte */
3658722b2e2fSMark Johnston uint_t opcode8; /* high nibble of 4th byte */
3659722b2e2fSMark Johnston uint_t opcode9; /* low nibble of 4th byte */
36600339a1c2SMark Johnston uint_t opcode_bytes = 1;
36610339a1c2SMark Johnston
36620339a1c2SMark Johnston /*
36630339a1c2SMark Johnston * legacy prefixes come in 5 flavors, you should have only one of each
36640339a1c2SMark Johnston */
36650339a1c2SMark Johnston uint_t opnd_size_prefix = 0;
36660339a1c2SMark Johnston uint_t addr_size_prefix = 0;
36670339a1c2SMark Johnston uint_t segment_prefix = 0;
36680339a1c2SMark Johnston uint_t lock_prefix = 0;
36690339a1c2SMark Johnston uint_t rep_prefix = 0;
36700339a1c2SMark Johnston uint_t rex_prefix = 0; /* amd64 register extension prefix */
36710339a1c2SMark Johnston
36720339a1c2SMark Johnston /*
36730339a1c2SMark Johnston * Intel VEX instruction encoding prefix and fields
36740339a1c2SMark Johnston */
36750339a1c2SMark Johnston
36760339a1c2SMark Johnston /* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
36770339a1c2SMark Johnston uint_t vex_prefix = 0;
36780339a1c2SMark Johnston
36790339a1c2SMark Johnston /*
36800339a1c2SMark Johnston * VEX prefix byte 1, includes vex.r, vex.x and vex.b
36810339a1c2SMark Johnston * (for 3 bytes prefix)
36820339a1c2SMark Johnston */
36830339a1c2SMark Johnston uint_t vex_byte1 = 0;
36840339a1c2SMark Johnston
36850339a1c2SMark Johnston /*
3686722b2e2fSMark Johnston * EVEX prefix byte 1 includes vex.r, vex.x, vex.b and evex.r.
3687722b2e2fSMark Johnston */
3688722b2e2fSMark Johnston uint_t evex_byte1 = 0;
3689722b2e2fSMark Johnston uint_t evex_byte2 = 0;
3690722b2e2fSMark Johnston uint_t evex_byte3 = 0;
3691722b2e2fSMark Johnston
3692722b2e2fSMark Johnston /*
36930339a1c2SMark Johnston * For 32-bit mode, it should prefetch the next byte to
36940339a1c2SMark Johnston * distinguish between AVX and les/lds
36950339a1c2SMark Johnston */
36960339a1c2SMark Johnston uint_t vex_prefetch = 0;
36970339a1c2SMark Johnston
36980339a1c2SMark Johnston uint_t vex_m = 0;
36990339a1c2SMark Johnston uint_t vex_v = 0;
37000339a1c2SMark Johnston uint_t vex_p = 0;
37010339a1c2SMark Johnston uint_t vex_R = 1;
37020339a1c2SMark Johnston uint_t vex_X = 1;
37030339a1c2SMark Johnston uint_t vex_B = 1;
37040339a1c2SMark Johnston uint_t vex_W = 0;
3705722b2e2fSMark Johnston uint_t vex_L = 0;
3706722b2e2fSMark Johnston uint_t evex_L = 0;
3707722b2e2fSMark Johnston uint_t evex_modrm = 0;
3708722b2e2fSMark Johnston uint_t evex_prefix = 0;
3709b3b5bfebSMark Johnston dis_gather_regs_t *vreg;
37100339a1c2SMark Johnston
3711b3b5bfebSMark Johnston #ifdef DIS_TEXT
3712b3b5bfebSMark Johnston /* Instruction name for BLS* family of instructions */
3713b3b5bfebSMark Johnston char *blsinstr;
3714b3b5bfebSMark Johnston #endif
37150339a1c2SMark Johnston
37160339a1c2SMark Johnston size_t off;
37170339a1c2SMark Johnston
37180339a1c2SMark Johnston instable_t dp_mmx;
37190339a1c2SMark Johnston
37200339a1c2SMark Johnston x->d86_len = 0;
37210339a1c2SMark Johnston x->d86_rmindex = -1;
37220339a1c2SMark Johnston x->d86_error = 0;
37230339a1c2SMark Johnston x->d86_numopnds = 0;
3724*418d8f0dSMark Johnston #ifdef DIS_TEXT
37250339a1c2SMark Johnston x->d86_seg_prefix = NULL;
37260339a1c2SMark Johnston x->d86_mnem[0] = 0;
37270339a1c2SMark Johnston for (i = 0; i < 4; ++i) {
37280339a1c2SMark Johnston x->d86_opnd[i].d86_opnd[0] = 0;
37290339a1c2SMark Johnston x->d86_opnd[i].d86_prefix[0] = 0;
37300339a1c2SMark Johnston x->d86_opnd[i].d86_value_size = 0;
37310339a1c2SMark Johnston x->d86_opnd[i].d86_value = 0;
37320339a1c2SMark Johnston x->d86_opnd[i].d86_mode = MODE_NONE;
37330339a1c2SMark Johnston }
37340339a1c2SMark Johnston #endif
37350339a1c2SMark Johnston x->d86_rex_prefix = 0;
37360339a1c2SMark Johnston x->d86_got_modrm = 0;
37370339a1c2SMark Johnston x->d86_memsize = 0;
3738b3b5bfebSMark Johnston x->d86_vsib = 0;
37390339a1c2SMark Johnston
37400339a1c2SMark Johnston if (cpu_mode == SIZE16) {
37410339a1c2SMark Johnston opnd_size = SIZE16;
37420339a1c2SMark Johnston addr_size = SIZE16;
37430339a1c2SMark Johnston } else if (cpu_mode == SIZE32) {
37440339a1c2SMark Johnston opnd_size = SIZE32;
37450339a1c2SMark Johnston addr_size = SIZE32;
37460339a1c2SMark Johnston } else {
37470339a1c2SMark Johnston opnd_size = SIZE32;
37480339a1c2SMark Johnston addr_size = SIZE64;
37490339a1c2SMark Johnston }
37500339a1c2SMark Johnston
37510339a1c2SMark Johnston /*
37520339a1c2SMark Johnston * Get one opcode byte and check for zero padding that follows
37530339a1c2SMark Johnston * jump tables.
37540339a1c2SMark Johnston */
37550339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
37560339a1c2SMark Johnston goto error;
37570339a1c2SMark Johnston
37580339a1c2SMark Johnston if (opcode1 == 0 && opcode2 == 0 &&
37590339a1c2SMark Johnston x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
37600339a1c2SMark Johnston #ifdef DIS_TEXT
37610339a1c2SMark Johnston (void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
37620339a1c2SMark Johnston #endif
37630339a1c2SMark Johnston goto done;
37640339a1c2SMark Johnston }
37650339a1c2SMark Johnston
37660339a1c2SMark Johnston /*
37670339a1c2SMark Johnston * Gather up legacy x86 prefix bytes.
37680339a1c2SMark Johnston */
37690339a1c2SMark Johnston for (;;) {
37700339a1c2SMark Johnston uint_t *which_prefix = NULL;
37710339a1c2SMark Johnston
37720339a1c2SMark Johnston dp = (instable_t *)&dis_distable[opcode1][opcode2];
37730339a1c2SMark Johnston
37740339a1c2SMark Johnston switch (dp->it_adrmode) {
37750339a1c2SMark Johnston case PREFIX:
37760339a1c2SMark Johnston which_prefix = &rep_prefix;
37770339a1c2SMark Johnston break;
37780339a1c2SMark Johnston case LOCK:
37790339a1c2SMark Johnston which_prefix = &lock_prefix;
37800339a1c2SMark Johnston break;
37810339a1c2SMark Johnston case OVERRIDE:
37820339a1c2SMark Johnston which_prefix = &segment_prefix;
37830339a1c2SMark Johnston #ifdef DIS_TEXT
37840339a1c2SMark Johnston x->d86_seg_prefix = (char *)dp->it_name;
37850339a1c2SMark Johnston #endif
37860339a1c2SMark Johnston if (dp->it_invalid64 && cpu_mode == SIZE64)
37870339a1c2SMark Johnston goto error;
37880339a1c2SMark Johnston break;
37890339a1c2SMark Johnston case AM:
37900339a1c2SMark Johnston which_prefix = &addr_size_prefix;
37910339a1c2SMark Johnston break;
37920339a1c2SMark Johnston case DM:
37930339a1c2SMark Johnston which_prefix = &opnd_size_prefix;
37940339a1c2SMark Johnston break;
37950339a1c2SMark Johnston }
37960339a1c2SMark Johnston if (which_prefix == NULL)
37970339a1c2SMark Johnston break;
37980339a1c2SMark Johnston *which_prefix = (opcode1 << 4) | opcode2;
37990339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
38000339a1c2SMark Johnston goto error;
38010339a1c2SMark Johnston }
38020339a1c2SMark Johnston
38030339a1c2SMark Johnston /*
38040339a1c2SMark Johnston * Handle amd64 mode PREFIX values.
38050339a1c2SMark Johnston * Some of the segment prefixes are no-ops. (only FS/GS actually work)
38060339a1c2SMark Johnston * We might have a REX prefix (opcodes 0x40-0x4f)
38070339a1c2SMark Johnston */
38080339a1c2SMark Johnston if (cpu_mode == SIZE64) {
38090339a1c2SMark Johnston if (segment_prefix != 0x64 && segment_prefix != 0x65)
38100339a1c2SMark Johnston segment_prefix = 0;
38110339a1c2SMark Johnston
38120339a1c2SMark Johnston if (opcode1 == 0x4) {
38130339a1c2SMark Johnston rex_prefix = (opcode1 << 4) | opcode2;
38140339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
38150339a1c2SMark Johnston goto error;
38160339a1c2SMark Johnston dp = (instable_t *)&dis_distable[opcode1][opcode2];
38170339a1c2SMark Johnston } else if (opcode1 == 0xC &&
38180339a1c2SMark Johnston (opcode2 == 0x4 || opcode2 == 0x5)) {
38190339a1c2SMark Johnston /* AVX instructions */
38200339a1c2SMark Johnston vex_prefix = (opcode1 << 4) | opcode2;
38210339a1c2SMark Johnston x->d86_rex_prefix = 0x40;
38220339a1c2SMark Johnston }
38230339a1c2SMark Johnston } else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
38240339a1c2SMark Johnston /* LDS, LES or AVX */
38250339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
38260339a1c2SMark Johnston vex_prefetch = 1;
38270339a1c2SMark Johnston
38280339a1c2SMark Johnston if (mode == REG_ONLY) {
38290339a1c2SMark Johnston /* AVX */
38300339a1c2SMark Johnston vex_prefix = (opcode1 << 4) | opcode2;
38310339a1c2SMark Johnston x->d86_rex_prefix = 0x40;
38320339a1c2SMark Johnston opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
38330339a1c2SMark Johnston opcode4 = ((reg << 3) | r_m) & 0x0F;
38340339a1c2SMark Johnston }
38350339a1c2SMark Johnston }
38360339a1c2SMark Johnston
3837722b2e2fSMark Johnston /*
3838722b2e2fSMark Johnston * The EVEX prefix and "bound" instruction share the same first byte.
3839722b2e2fSMark Johnston * "bound" is only valid for 32-bit. For 64-bit this byte begins the
3840722b2e2fSMark Johnston * EVEX prefix and the 2nd byte must have bits 2 & 3 set to 0.
3841722b2e2fSMark Johnston */
3842722b2e2fSMark Johnston if (opcode1 == 0x6 && opcode2 == 0x2) {
3843722b2e2fSMark Johnston evex_prefix = 0x62;
3844722b2e2fSMark Johnston
3845722b2e2fSMark Johnston /*
3846722b2e2fSMark Johnston * An EVEX prefix is 4 bytes long, get the next 3 bytes.
3847722b2e2fSMark Johnston */
3848722b2e2fSMark Johnston if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
3849722b2e2fSMark Johnston goto error;
3850722b2e2fSMark Johnston
3851722b2e2fSMark Johnston if (addr_size == SIZE32 && (opcode4 & 0xf) == 0) {
3852722b2e2fSMark Johnston /*
3853722b2e2fSMark Johnston * Upper bits in 2nd byte == 0 is 'bound' instn.
3854722b2e2fSMark Johnston *
3855722b2e2fSMark Johnston * We've already read the byte so perform the
3856722b2e2fSMark Johnston * equivalent of dtrace_get_modrm on the byte and set
3857722b2e2fSMark Johnston * the flag to indicate we've already read it.
3858722b2e2fSMark Johnston */
3859722b2e2fSMark Johnston char b = (opcode4 << 4) | opcode5;
3860722b2e2fSMark Johnston
3861722b2e2fSMark Johnston r_m = b & 0x7;
3862722b2e2fSMark Johnston reg = (b >> 3) & 0x7;
3863722b2e2fSMark Johnston mode = (b >> 6) & 0x3;
3864722b2e2fSMark Johnston vex_prefetch = 1;
3865722b2e2fSMark Johnston goto not_avx512;
3866722b2e2fSMark Johnston }
3867722b2e2fSMark Johnston
3868722b2e2fSMark Johnston /* check for correct bits being 0 in 2nd byte */
3869722b2e2fSMark Johnston if ((opcode5 & 0xc) != 0)
3870722b2e2fSMark Johnston goto error;
3871722b2e2fSMark Johnston
3872722b2e2fSMark Johnston if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
3873722b2e2fSMark Johnston goto error;
3874722b2e2fSMark Johnston /* check for correct bit being 1 in 3rd byte */
3875722b2e2fSMark Johnston if ((opcode7 & 0x4) == 0)
3876722b2e2fSMark Johnston goto error;
3877722b2e2fSMark Johnston
3878722b2e2fSMark Johnston if (dtrace_get_opcode(x, &opcode8, &opcode9) != 0)
3879722b2e2fSMark Johnston goto error;
3880722b2e2fSMark Johnston
3881722b2e2fSMark Johnston /* Reuse opcode1 & opcode2 to get the real opcode now */
3882722b2e2fSMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3883722b2e2fSMark Johnston goto error;
3884722b2e2fSMark Johnston
3885722b2e2fSMark Johnston /*
3886722b2e2fSMark Johnston * We only use the high nibble from the 2nd byte of the prefix
3887722b2e2fSMark Johnston * and save it in the low bits of evex_byte1. This is because
3888722b2e2fSMark Johnston * two of the bits in opcode5 are constant 0 (checked above),
3889722b2e2fSMark Johnston * and the other two bits are captured in vex_m. Also, the VEX
3890722b2e2fSMark Johnston * constants we check in evex_byte1 are against the low bits.
3891722b2e2fSMark Johnston */
3892722b2e2fSMark Johnston evex_byte1 = opcode4;
3893722b2e2fSMark Johnston evex_byte2 = (opcode6 << 4) | opcode7;
3894722b2e2fSMark Johnston evex_byte3 = (opcode8 << 4) | opcode9;
3895722b2e2fSMark Johnston
3896722b2e2fSMark Johnston vex_m = opcode5 & EVEX_m;
3897722b2e2fSMark Johnston vex_v = (((opcode6 << 4) | opcode7) & VEX_v) >> 3;
3898722b2e2fSMark Johnston vex_W = (opcode6 & VEX_W) >> 3;
3899722b2e2fSMark Johnston vex_p = opcode7 & VEX_p;
3900722b2e2fSMark Johnston
3901722b2e2fSMark Johnston /*
3902722b2e2fSMark Johnston * Store the corresponding prefix information for later use when
3903722b2e2fSMark Johnston * calculating the SIB.
3904722b2e2fSMark Johnston */
3905722b2e2fSMark Johnston if ((evex_byte1 & VEX_R) == 0)
3906722b2e2fSMark Johnston x->d86_rex_prefix |= REX_R;
3907722b2e2fSMark Johnston if ((evex_byte1 & VEX_X) == 0)
3908722b2e2fSMark Johnston x->d86_rex_prefix |= REX_X;
3909722b2e2fSMark Johnston if ((evex_byte1 & VEX_B) == 0)
3910722b2e2fSMark Johnston x->d86_rex_prefix |= REX_B;
3911722b2e2fSMark Johnston
3912722b2e2fSMark Johnston /* Currently only 3 valid values for evex L'L: 00, 01, 10 */
3913722b2e2fSMark Johnston evex_L = (opcode8 & EVEX_L) >> 1;
3914722b2e2fSMark Johnston
3915722b2e2fSMark Johnston switch (vex_p) {
3916722b2e2fSMark Johnston case VEX_p_66:
3917722b2e2fSMark Johnston switch (vex_m) {
3918722b2e2fSMark Johnston case VEX_m_0F:
3919722b2e2fSMark Johnston dp = &dis_opEVEX660F[(opcode1 << 4) | opcode2];
3920722b2e2fSMark Johnston break;
3921722b2e2fSMark Johnston case VEX_m_0F38:
3922722b2e2fSMark Johnston dp = &dis_opEVEX660F38[(opcode1 << 4) |
3923722b2e2fSMark Johnston opcode2];
3924722b2e2fSMark Johnston break;
3925722b2e2fSMark Johnston case VEX_m_0F3A:
3926722b2e2fSMark Johnston dp = &dis_opEVEX660F3A[(opcode1 << 4) |
3927722b2e2fSMark Johnston opcode2];
3928722b2e2fSMark Johnston break;
3929722b2e2fSMark Johnston default:
3930722b2e2fSMark Johnston goto error;
3931722b2e2fSMark Johnston }
3932722b2e2fSMark Johnston break;
3933722b2e2fSMark Johnston case VEX_p_F3:
3934722b2e2fSMark Johnston switch (vex_m) {
3935722b2e2fSMark Johnston case VEX_m_0F:
3936722b2e2fSMark Johnston dp = &dis_opEVEXF30F[(opcode1 << 4) | opcode2];
3937722b2e2fSMark Johnston break;
3938722b2e2fSMark Johnston default:
3939722b2e2fSMark Johnston goto error;
3940722b2e2fSMark Johnston }
3941722b2e2fSMark Johnston break;
3942722b2e2fSMark Johnston case VEX_p_F2:
3943722b2e2fSMark Johnston switch (vex_m) {
3944722b2e2fSMark Johnston case VEX_m_0F:
3945722b2e2fSMark Johnston dp = &dis_opEVEXF20F[(opcode1 << 4) | opcode2];
3946722b2e2fSMark Johnston break;
3947722b2e2fSMark Johnston default:
3948722b2e2fSMark Johnston goto error;
3949722b2e2fSMark Johnston }
3950722b2e2fSMark Johnston break;
3951722b2e2fSMark Johnston default:
3952722b2e2fSMark Johnston dp = &dis_opEVEX0F[(opcode1 << 4) | opcode2];
3953722b2e2fSMark Johnston break;
3954722b2e2fSMark Johnston }
3955722b2e2fSMark Johnston }
3956722b2e2fSMark Johnston not_avx512:
3957722b2e2fSMark Johnston
39580339a1c2SMark Johnston if (vex_prefix == VEX_2bytes) {
39590339a1c2SMark Johnston if (!vex_prefetch) {
39600339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
39610339a1c2SMark Johnston goto error;
39620339a1c2SMark Johnston }
39630339a1c2SMark Johnston vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
39640339a1c2SMark Johnston vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
39650339a1c2SMark Johnston vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
39660339a1c2SMark Johnston vex_p = opcode4 & VEX_p;
39670339a1c2SMark Johnston /*
39680339a1c2SMark Johnston * The vex.x and vex.b bits are not defined in two bytes
39690339a1c2SMark Johnston * mode vex prefix, their default values are 1
39700339a1c2SMark Johnston */
39710339a1c2SMark Johnston vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
39720339a1c2SMark Johnston
39730339a1c2SMark Johnston if (vex_R == 0)
39740339a1c2SMark Johnston x->d86_rex_prefix |= REX_R;
39750339a1c2SMark Johnston
39760339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
39770339a1c2SMark Johnston goto error;
39780339a1c2SMark Johnston
39790339a1c2SMark Johnston switch (vex_p) {
39800339a1c2SMark Johnston case VEX_p_66:
39810339a1c2SMark Johnston dp = (instable_t *)
39820339a1c2SMark Johnston &dis_opAVX660F[(opcode1 << 4) | opcode2];
39830339a1c2SMark Johnston break;
39840339a1c2SMark Johnston case VEX_p_F3:
39850339a1c2SMark Johnston dp = (instable_t *)
39860339a1c2SMark Johnston &dis_opAVXF30F[(opcode1 << 4) | opcode2];
39870339a1c2SMark Johnston break;
39880339a1c2SMark Johnston case VEX_p_F2:
39890339a1c2SMark Johnston dp = (instable_t *)
39900339a1c2SMark Johnston &dis_opAVXF20F [(opcode1 << 4) | opcode2];
39910339a1c2SMark Johnston break;
39920339a1c2SMark Johnston default:
39930339a1c2SMark Johnston dp = (instable_t *)
39940339a1c2SMark Johnston &dis_opAVX0F[opcode1][opcode2];
39950339a1c2SMark Johnston
39960339a1c2SMark Johnston }
39970339a1c2SMark Johnston
39980339a1c2SMark Johnston } else if (vex_prefix == VEX_3bytes) {
39990339a1c2SMark Johnston if (!vex_prefetch) {
40000339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
40010339a1c2SMark Johnston goto error;
40020339a1c2SMark Johnston }
40030339a1c2SMark Johnston vex_R = (opcode3 & VEX_R) >> 3;
40040339a1c2SMark Johnston vex_X = (opcode3 & VEX_X) >> 2;
40050339a1c2SMark Johnston vex_B = (opcode3 & VEX_B) >> 1;
40060339a1c2SMark Johnston vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
40070339a1c2SMark Johnston vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
40080339a1c2SMark Johnston
40090339a1c2SMark Johnston if (vex_R == 0)
40100339a1c2SMark Johnston x->d86_rex_prefix |= REX_R;
40110339a1c2SMark Johnston if (vex_X == 0)
40120339a1c2SMark Johnston x->d86_rex_prefix |= REX_X;
40130339a1c2SMark Johnston if (vex_B == 0)
40140339a1c2SMark Johnston x->d86_rex_prefix |= REX_B;
40150339a1c2SMark Johnston
40160339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
40170339a1c2SMark Johnston goto error;
40180339a1c2SMark Johnston vex_W = (opcode5 & VEX_W) >> 3;
40190339a1c2SMark Johnston vex_L = (opcode6 & VEX_L) >> 2;
40200339a1c2SMark Johnston vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
40210339a1c2SMark Johnston vex_p = opcode6 & VEX_p;
40220339a1c2SMark Johnston
40230339a1c2SMark Johnston if (vex_W)
40240339a1c2SMark Johnston x->d86_rex_prefix |= REX_W;
40250339a1c2SMark Johnston
40260339a1c2SMark Johnston /* Only these three vex_m values valid; others are reserved */
40270339a1c2SMark Johnston if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
40280339a1c2SMark Johnston (vex_m != VEX_m_0F3A))
40290339a1c2SMark Johnston goto error;
40300339a1c2SMark Johnston
40310339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
40320339a1c2SMark Johnston goto error;
40330339a1c2SMark Johnston
40340339a1c2SMark Johnston switch (vex_p) {
40350339a1c2SMark Johnston case VEX_p_66:
40360339a1c2SMark Johnston if (vex_m == VEX_m_0F) {
40370339a1c2SMark Johnston dp = (instable_t *)
40380339a1c2SMark Johnston &dis_opAVX660F
40390339a1c2SMark Johnston [(opcode1 << 4) | opcode2];
40400339a1c2SMark Johnston } else if (vex_m == VEX_m_0F38) {
40410339a1c2SMark Johnston dp = (instable_t *)
40420339a1c2SMark Johnston &dis_opAVX660F38
40430339a1c2SMark Johnston [(opcode1 << 4) | opcode2];
40440339a1c2SMark Johnston } else if (vex_m == VEX_m_0F3A) {
40450339a1c2SMark Johnston dp = (instable_t *)
40460339a1c2SMark Johnston &dis_opAVX660F3A
40470339a1c2SMark Johnston [(opcode1 << 4) | opcode2];
40480339a1c2SMark Johnston } else {
40490339a1c2SMark Johnston goto error;
40500339a1c2SMark Johnston }
40510339a1c2SMark Johnston break;
40520339a1c2SMark Johnston case VEX_p_F3:
40530339a1c2SMark Johnston if (vex_m == VEX_m_0F) {
40540339a1c2SMark Johnston dp = (instable_t *)
40550339a1c2SMark Johnston &dis_opAVXF30F
40560339a1c2SMark Johnston [(opcode1 << 4) | opcode2];
4057b3b5bfebSMark Johnston } else if (vex_m == VEX_m_0F38) {
4058b3b5bfebSMark Johnston dp = (instable_t *)
4059b3b5bfebSMark Johnston &dis_opAVXF30F38
4060b3b5bfebSMark Johnston [(opcode1 << 4) | opcode2];
40610339a1c2SMark Johnston } else {
40620339a1c2SMark Johnston goto error;
40630339a1c2SMark Johnston }
40640339a1c2SMark Johnston break;
40650339a1c2SMark Johnston case VEX_p_F2:
40660339a1c2SMark Johnston if (vex_m == VEX_m_0F) {
40670339a1c2SMark Johnston dp = (instable_t *)
40680339a1c2SMark Johnston &dis_opAVXF20F
40690339a1c2SMark Johnston [(opcode1 << 4) | opcode2];
4070b3b5bfebSMark Johnston } else if (vex_m == VEX_m_0F3A) {
4071b3b5bfebSMark Johnston dp = (instable_t *)
4072b3b5bfebSMark Johnston &dis_opAVXF20F3A
4073b3b5bfebSMark Johnston [(opcode1 << 4) | opcode2];
4074b3b5bfebSMark Johnston } else if (vex_m == VEX_m_0F38) {
4075b3b5bfebSMark Johnston dp = (instable_t *)
4076b3b5bfebSMark Johnston &dis_opAVXF20F38
4077b3b5bfebSMark Johnston [(opcode1 << 4) | opcode2];
40780339a1c2SMark Johnston } else {
40790339a1c2SMark Johnston goto error;
40800339a1c2SMark Johnston }
40810339a1c2SMark Johnston break;
40820339a1c2SMark Johnston default:
40830339a1c2SMark Johnston dp = (instable_t *)
40840339a1c2SMark Johnston &dis_opAVX0F[opcode1][opcode2];
40850339a1c2SMark Johnston
40860339a1c2SMark Johnston }
40870339a1c2SMark Johnston }
40880339a1c2SMark Johnston if (vex_prefix) {
4089b3b5bfebSMark Johnston if (dp->it_vexwoxmm) {
4090b3b5bfebSMark Johnston wbit = LONG_OPND;
4091722b2e2fSMark Johnston } else if (dp->it_vexopmask) {
4092722b2e2fSMark Johnston wbit = KOPMASK_OPND;
4093b3b5bfebSMark Johnston } else {
4094722b2e2fSMark Johnston if (vex_L) {
40950339a1c2SMark Johnston wbit = YMM_OPND;
4096722b2e2fSMark Johnston } else {
40970339a1c2SMark Johnston wbit = XMM_OPND;
40980339a1c2SMark Johnston }
4099b3b5bfebSMark Johnston }
4100722b2e2fSMark Johnston }
41010339a1c2SMark Johnston
41020339a1c2SMark Johnston /*
41030339a1c2SMark Johnston * Deal with selection of operand and address size now.
41040339a1c2SMark Johnston * Note that the REX.W bit being set causes opnd_size_prefix to be
41050339a1c2SMark Johnston * ignored.
41060339a1c2SMark Johnston */
41070339a1c2SMark Johnston if (cpu_mode == SIZE64) {
41080339a1c2SMark Johnston if ((rex_prefix & REX_W) || vex_W)
41090339a1c2SMark Johnston opnd_size = SIZE64;
41100339a1c2SMark Johnston else if (opnd_size_prefix)
41110339a1c2SMark Johnston opnd_size = SIZE16;
41120339a1c2SMark Johnston
41130339a1c2SMark Johnston if (addr_size_prefix)
41140339a1c2SMark Johnston addr_size = SIZE32;
41150339a1c2SMark Johnston } else if (cpu_mode == SIZE32) {
41160339a1c2SMark Johnston if (opnd_size_prefix)
41170339a1c2SMark Johnston opnd_size = SIZE16;
41180339a1c2SMark Johnston if (addr_size_prefix)
41190339a1c2SMark Johnston addr_size = SIZE16;
41200339a1c2SMark Johnston } else {
41210339a1c2SMark Johnston if (opnd_size_prefix)
41220339a1c2SMark Johnston opnd_size = SIZE32;
41230339a1c2SMark Johnston if (addr_size_prefix)
41240339a1c2SMark Johnston addr_size = SIZE32;
41250339a1c2SMark Johnston }
41260339a1c2SMark Johnston /*
41270339a1c2SMark Johnston * The pause instruction - a repz'd nop. This doesn't fit
41280339a1c2SMark Johnston * with any of the other prefix goop added for SSE, so we'll
41290339a1c2SMark Johnston * special-case it here.
41300339a1c2SMark Johnston */
41310339a1c2SMark Johnston if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
41320339a1c2SMark Johnston rep_prefix = 0;
41330339a1c2SMark Johnston dp = (instable_t *)&dis_opPause;
41340339a1c2SMark Johnston }
41350339a1c2SMark Johnston
41360339a1c2SMark Johnston /*
41370339a1c2SMark Johnston * Some 386 instructions have 2 bytes of opcode before the mod_r/m
41380339a1c2SMark Johnston * byte so we may need to perform a table indirection.
41390339a1c2SMark Johnston */
41400339a1c2SMark Johnston if (dp->it_indirect == (instable_t *)dis_op0F) {
41410339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
41420339a1c2SMark Johnston goto error;
41430339a1c2SMark Johnston opcode_bytes = 2;
41440339a1c2SMark Johnston if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
41450339a1c2SMark Johnston uint_t subcode;
41460339a1c2SMark Johnston
41470339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
41480339a1c2SMark Johnston goto error;
41490339a1c2SMark Johnston opcode_bytes = 3;
41500339a1c2SMark Johnston subcode = ((opcode6 & 0x3) << 1) |
41510339a1c2SMark Johnston ((opcode7 & 0x8) >> 3);
41520339a1c2SMark Johnston dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
41530339a1c2SMark Johnston } else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
41540339a1c2SMark Johnston dp = (instable_t *)&dis_op0FC8[0];
41550339a1c2SMark Johnston } else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
41560339a1c2SMark Johnston opcode_bytes = 3;
41570339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
41580339a1c2SMark Johnston goto error;
41590339a1c2SMark Johnston if (opnd_size == SIZE16)
41600339a1c2SMark Johnston opnd_size = SIZE32;
41610339a1c2SMark Johnston
41620339a1c2SMark Johnston dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
41630339a1c2SMark Johnston #ifdef DIS_TEXT
41640339a1c2SMark Johnston if (strcmp(dp->it_name, "INVALID") == 0)
41650339a1c2SMark Johnston goto error;
41660339a1c2SMark Johnston #endif
41670339a1c2SMark Johnston switch (dp->it_adrmode) {
4168b3b5bfebSMark Johnston case XMMP:
4169b3b5bfebSMark Johnston break;
41700339a1c2SMark Johnston case XMMP_66r:
41710339a1c2SMark Johnston case XMMPRM_66r:
41720339a1c2SMark Johnston case XMM3PM_66r:
41730339a1c2SMark Johnston if (opnd_size_prefix == 0) {
41740339a1c2SMark Johnston goto error;
41750339a1c2SMark Johnston }
4176722b2e2fSMark Johnston
41770339a1c2SMark Johnston break;
41780339a1c2SMark Johnston case XMMP_66o:
41790339a1c2SMark Johnston if (opnd_size_prefix == 0) {
41800339a1c2SMark Johnston /* SSSE3 MMX instructions */
41810339a1c2SMark Johnston dp_mmx = *dp;
4182722b2e2fSMark Johnston dp_mmx.it_adrmode = MMOPM_66o;
41830339a1c2SMark Johnston #ifdef DIS_MEM
4184722b2e2fSMark Johnston dp_mmx.it_size = 8;
41850339a1c2SMark Johnston #endif
4186722b2e2fSMark Johnston dp = &dp_mmx;
41870339a1c2SMark Johnston }
41880339a1c2SMark Johnston break;
41890339a1c2SMark Johnston default:
41900339a1c2SMark Johnston goto error;
41910339a1c2SMark Johnston }
41920339a1c2SMark Johnston } else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
41930339a1c2SMark Johnston opcode_bytes = 3;
41940339a1c2SMark Johnston if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
41950339a1c2SMark Johnston goto error;
41960339a1c2SMark Johnston dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
41970339a1c2SMark Johnston
41980339a1c2SMark Johnston /*
41990339a1c2SMark Johnston * Both crc32 and movbe have the same 3rd opcode
42000339a1c2SMark Johnston * byte of either 0xF0 or 0xF1, so we use another
42010339a1c2SMark Johnston * indirection to distinguish between the two.
42020339a1c2SMark Johnston */
42030339a1c2SMark Johnston if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
42040339a1c2SMark Johnston dp->it_indirect == (instable_t *)dis_op0F38F1) {
42050339a1c2SMark Johnston
42060339a1c2SMark Johnston dp = dp->it_indirect;
42070339a1c2SMark Johnston if (rep_prefix != 0xF2) {
42080339a1c2SMark Johnston /* It is movbe */
42090339a1c2SMark Johnston dp++;
42100339a1c2SMark Johnston }
42110339a1c2SMark Johnston }
4212b3b5bfebSMark Johnston
4213b3b5bfebSMark Johnston /*
4214b3b5bfebSMark Johnston * The adx family of instructions (adcx and adox)
4215b3b5bfebSMark Johnston * continue the classic Intel tradition of abusing
4216b3b5bfebSMark Johnston * arbitrary prefixes without actually meaning the
4217b3b5bfebSMark Johnston * prefix bit. Therefore, if we find either the
4218b3b5bfebSMark Johnston * opnd_size_prefix or rep_prefix we end up zeroing it
4219b3b5bfebSMark Johnston * out after making our determination so as to ensure
4220b3b5bfebSMark Johnston * that we don't get confused and accidentally print
4221b3b5bfebSMark Johnston * repz prefixes and the like on these instructions.
4222b3b5bfebSMark Johnston *
4223b3b5bfebSMark Johnston * In addition, these instructions are actually much
4224b3b5bfebSMark Johnston * closer to AVX instructions in semantics. Importantly,
4225b3b5bfebSMark Johnston * they always default to having 32-bit operands.
4226b3b5bfebSMark Johnston * However, if the CPU is in 64-bit mode, then and only
4227b3b5bfebSMark Johnston * then, does it use REX.w promotes things to 64-bits
4228b3b5bfebSMark Johnston * and REX.r allows 64-bit mode to use register r8-r15.
4229b3b5bfebSMark Johnston */
4230b3b5bfebSMark Johnston if (dp->it_indirect == (instable_t *)dis_op0F38F6) {
4231b3b5bfebSMark Johnston dp = dp->it_indirect;
4232b3b5bfebSMark Johnston if (opnd_size_prefix == 0 &&
4233b3b5bfebSMark Johnston rep_prefix == 0xf3) {
4234b3b5bfebSMark Johnston /* It is adox */
4235b3b5bfebSMark Johnston dp++;
4236b3b5bfebSMark Johnston } else if (opnd_size_prefix != 0x66 &&
4237b3b5bfebSMark Johnston rep_prefix != 0) {
4238b3b5bfebSMark Johnston /* It isn't adcx */
4239b3b5bfebSMark Johnston goto error;
4240b3b5bfebSMark Johnston }
4241b3b5bfebSMark Johnston opnd_size_prefix = 0;
4242b3b5bfebSMark Johnston rep_prefix = 0;
4243b3b5bfebSMark Johnston opnd_size = SIZE32;
4244b3b5bfebSMark Johnston if (rex_prefix & REX_W)
4245b3b5bfebSMark Johnston opnd_size = SIZE64;
4246b3b5bfebSMark Johnston }
4247b3b5bfebSMark Johnston
42480339a1c2SMark Johnston #ifdef DIS_TEXT
42490339a1c2SMark Johnston if (strcmp(dp->it_name, "INVALID") == 0)
42500339a1c2SMark Johnston goto error;
42510339a1c2SMark Johnston #endif
42520339a1c2SMark Johnston switch (dp->it_adrmode) {
4253b3b5bfebSMark Johnston case ADX:
4254b3b5bfebSMark Johnston case XMM:
4255b3b5bfebSMark Johnston break;
4256c3ddb60eSPeter Grehan case RM_66r:
42570339a1c2SMark Johnston case XMM_66r:
42580339a1c2SMark Johnston case XMMM_66r:
42590339a1c2SMark Johnston if (opnd_size_prefix == 0) {
42600339a1c2SMark Johnston goto error;
42610339a1c2SMark Johnston }
42620339a1c2SMark Johnston break;
42630339a1c2SMark Johnston case XMM_66o:
42640339a1c2SMark Johnston if (opnd_size_prefix == 0) {
42650339a1c2SMark Johnston /* SSSE3 MMX instructions */
42660339a1c2SMark Johnston dp_mmx = *dp;
4267722b2e2fSMark Johnston dp_mmx.it_adrmode = MM;
42680339a1c2SMark Johnston #ifdef DIS_MEM
4269722b2e2fSMark Johnston dp_mmx.it_size = 8;
42700339a1c2SMark Johnston #endif
4271722b2e2fSMark Johnston dp = &dp_mmx;
42720339a1c2SMark Johnston }
42730339a1c2SMark Johnston break;
42740339a1c2SMark Johnston case CRC32:
42750339a1c2SMark Johnston if (rep_prefix != 0xF2) {
42760339a1c2SMark Johnston goto error;
42770339a1c2SMark Johnston }
42780339a1c2SMark Johnston rep_prefix = 0;
42790339a1c2SMark Johnston break;
42800339a1c2SMark Johnston case MOVBE:
42810339a1c2SMark Johnston if (rep_prefix != 0x0) {
42820339a1c2SMark Johnston goto error;
42830339a1c2SMark Johnston }
42840339a1c2SMark Johnston break;
42850339a1c2SMark Johnston default:
42860339a1c2SMark Johnston goto error;
42870339a1c2SMark Johnston }
4288722b2e2fSMark Johnston } else if (rep_prefix == 0xf3 && opcode4 == 0 && opcode5 == 9) {
4289722b2e2fSMark Johnston rep_prefix = 0;
4290722b2e2fSMark Johnston dp = (instable_t *)&dis_opWbnoinvd;
42910339a1c2SMark Johnston } else {
42920339a1c2SMark Johnston dp = (instable_t *)&dis_op0F[opcode4][opcode5];
42930339a1c2SMark Johnston }
42940339a1c2SMark Johnston }
42950339a1c2SMark Johnston
42960339a1c2SMark Johnston /*
42970339a1c2SMark Johnston * If still not at a TERM decode entry, then a ModRM byte
42980339a1c2SMark Johnston * exists and its fields further decode the instruction.
42990339a1c2SMark Johnston */
43000339a1c2SMark Johnston x->d86_got_modrm = 0;
43010339a1c2SMark Johnston if (dp->it_indirect != TERM) {
43020339a1c2SMark Johnston dtrace_get_modrm(x, &mode, &opcode3, &r_m);
43030339a1c2SMark Johnston if (x->d86_error)
43040339a1c2SMark Johnston goto error;
43050339a1c2SMark Johnston reg = opcode3;
43060339a1c2SMark Johnston
43070339a1c2SMark Johnston /*
43080339a1c2SMark Johnston * decode 287 instructions (D8-DF) from opcodeN
43090339a1c2SMark Johnston */
43100339a1c2SMark Johnston if (opcode1 == 0xD && opcode2 >= 0x8) {
43110339a1c2SMark Johnston if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
43120339a1c2SMark Johnston dp = (instable_t *)&dis_opFP5[r_m];
43130339a1c2SMark Johnston else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
43140339a1c2SMark Johnston dp = (instable_t *)&dis_opFP7[opcode3];
43150339a1c2SMark Johnston else if (opcode2 == 0xB && mode == 0x3)
43160339a1c2SMark Johnston dp = (instable_t *)&dis_opFP6[opcode3];
43170339a1c2SMark Johnston else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
43180339a1c2SMark Johnston dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
43190339a1c2SMark Johnston else if (mode == 0x3)
43200339a1c2SMark Johnston dp = (instable_t *)
43210339a1c2SMark Johnston &dis_opFP3[opcode2 - 8][opcode3];
43220339a1c2SMark Johnston else
43230339a1c2SMark Johnston dp = (instable_t *)
43240339a1c2SMark Johnston &dis_opFP1n2[opcode2 - 8][opcode3];
43250339a1c2SMark Johnston } else {
43260339a1c2SMark Johnston dp = (instable_t *)dp->it_indirect + opcode3;
43270339a1c2SMark Johnston }
43280339a1c2SMark Johnston }
43290339a1c2SMark Johnston
43300339a1c2SMark Johnston /*
43310339a1c2SMark Johnston * In amd64 bit mode, ARPL opcode is changed to MOVSXD
43320339a1c2SMark Johnston * (sign extend 32bit to 64 bit)
43330339a1c2SMark Johnston */
43340339a1c2SMark Johnston if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
43350339a1c2SMark Johnston opcode1 == 0x6 && opcode2 == 0x3)
43360339a1c2SMark Johnston dp = (instable_t *)&dis_opMOVSLD;
43370339a1c2SMark Johnston
43380339a1c2SMark Johnston /*
43390339a1c2SMark Johnston * at this point we should have a correct (or invalid) opcode
43400339a1c2SMark Johnston */
43410339a1c2SMark Johnston if (cpu_mode == SIZE64 && dp->it_invalid64 ||
43420339a1c2SMark Johnston cpu_mode != SIZE64 && dp->it_invalid32)
43430339a1c2SMark Johnston goto error;
43440339a1c2SMark Johnston if (dp->it_indirect != TERM)
43450339a1c2SMark Johnston goto error;
43460339a1c2SMark Johnston
43470339a1c2SMark Johnston /*
4348b3b5bfebSMark Johnston * Deal with MMX/SSE opcodes which are changed by prefixes. Note, we do
4349b3b5bfebSMark Johnston * need to include UNKNOWN below, as we may have instructions that
4350b3b5bfebSMark Johnston * actually have a prefix, but don't exist in any other form.
43510339a1c2SMark Johnston */
43520339a1c2SMark Johnston switch (dp->it_adrmode) {
4353b3b5bfebSMark Johnston case UNKNOWN:
43540339a1c2SMark Johnston case MMO:
43550339a1c2SMark Johnston case MMOIMPL:
43560339a1c2SMark Johnston case MMO3P:
43570339a1c2SMark Johnston case MMOM3:
43580339a1c2SMark Johnston case MMOMS:
43590339a1c2SMark Johnston case MMOPM:
43600339a1c2SMark Johnston case MMOPRM:
43610339a1c2SMark Johnston case MMOS:
43620339a1c2SMark Johnston case XMMO:
43630339a1c2SMark Johnston case XMMOM:
43640339a1c2SMark Johnston case XMMOMS:
43650339a1c2SMark Johnston case XMMOPM:
43660339a1c2SMark Johnston case XMMOS:
43670339a1c2SMark Johnston case XMMOMX:
43680339a1c2SMark Johnston case XMMOX3:
43690339a1c2SMark Johnston case XMMOXMM:
43700339a1c2SMark Johnston /*
43710339a1c2SMark Johnston * This is horrible. Some SIMD instructions take the
43720339a1c2SMark Johnston * form 0x0F 0x?? ..., which is easily decoded using the
43730339a1c2SMark Johnston * existing tables. Other SIMD instructions use various
43740339a1c2SMark Johnston * prefix bytes to overload existing instructions. For
43750339a1c2SMark Johnston * Example, addps is F0, 58, whereas addss is F3 (repz),
43760339a1c2SMark Johnston * F0, 58. Presumably someone got a raise for this.
43770339a1c2SMark Johnston *
43780339a1c2SMark Johnston * If we see one of the instructions which can be
43790339a1c2SMark Johnston * modified in this way (if we've got one of the SIMDO*
43800339a1c2SMark Johnston * address modes), we'll check to see if the last prefix
43810339a1c2SMark Johnston * was a repz. If it was, we strip the prefix from the
43820339a1c2SMark Johnston * mnemonic, and we indirect using the dis_opSIMDrepz
43830339a1c2SMark Johnston * table.
43840339a1c2SMark Johnston */
43850339a1c2SMark Johnston
43860339a1c2SMark Johnston /*
43870339a1c2SMark Johnston * Calculate our offset in dis_op0F
43880339a1c2SMark Johnston */
43890339a1c2SMark Johnston if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
43900339a1c2SMark Johnston goto error;
43910339a1c2SMark Johnston
43920339a1c2SMark Johnston off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
43930339a1c2SMark Johnston sizeof (instable_t);
43940339a1c2SMark Johnston
43950339a1c2SMark Johnston /*
43960339a1c2SMark Johnston * Rewrite if this instruction used one of the magic prefixes.
43970339a1c2SMark Johnston */
43980339a1c2SMark Johnston if (rep_prefix) {
43990339a1c2SMark Johnston if (rep_prefix == 0xf2)
44000339a1c2SMark Johnston dp = (instable_t *)&dis_opSIMDrepnz[off];
44010339a1c2SMark Johnston else
44020339a1c2SMark Johnston dp = (instable_t *)&dis_opSIMDrepz[off];
44030339a1c2SMark Johnston rep_prefix = 0;
44040339a1c2SMark Johnston } else if (opnd_size_prefix) {
44050339a1c2SMark Johnston dp = (instable_t *)&dis_opSIMDdata16[off];
44060339a1c2SMark Johnston opnd_size_prefix = 0;
44070339a1c2SMark Johnston if (opnd_size == SIZE16)
44080339a1c2SMark Johnston opnd_size = SIZE32;
44090339a1c2SMark Johnston }
44100339a1c2SMark Johnston break;
44110339a1c2SMark Johnston
4412c3ddb60eSPeter Grehan case MG9:
4413c3ddb60eSPeter Grehan /*
4414c3ddb60eSPeter Grehan * More horribleness: the group 9 (0xF0 0xC7) instructions are
4415c3ddb60eSPeter Grehan * allowed an optional prefix of 0x66 or 0xF3. This is similar
4416c3ddb60eSPeter Grehan * to the SIMD business described above, but with a different
4417c3ddb60eSPeter Grehan * addressing mode (and an indirect table), so we deal with it
4418c3ddb60eSPeter Grehan * separately (if similarly).
4419c3ddb60eSPeter Grehan *
4420c3ddb60eSPeter Grehan * Intel further complicated this with the release of Ivy Bridge
4421c3ddb60eSPeter Grehan * where they overloaded these instructions based on the ModR/M
4422c3ddb60eSPeter Grehan * bytes. The VMX instructions have a mode of 0 since they are
4423c3ddb60eSPeter Grehan * memory instructions but rdrand instructions have a mode of
4424c3ddb60eSPeter Grehan * 0b11 (REG_ONLY) because they only operate on registers. While
4425c3ddb60eSPeter Grehan * there are different prefix formats, for now it is sufficient
4426c3ddb60eSPeter Grehan * to use a single different table.
4427c3ddb60eSPeter Grehan */
4428c3ddb60eSPeter Grehan
4429c3ddb60eSPeter Grehan /*
4430c3ddb60eSPeter Grehan * Calculate our offset in dis_op0FC7 (the group 9 table)
4431c3ddb60eSPeter Grehan */
4432c3ddb60eSPeter Grehan if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
4433c3ddb60eSPeter Grehan goto error;
4434c3ddb60eSPeter Grehan
4435c3ddb60eSPeter Grehan off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
4436c3ddb60eSPeter Grehan sizeof (instable_t);
4437c3ddb60eSPeter Grehan
4438c3ddb60eSPeter Grehan /*
4439c3ddb60eSPeter Grehan * If we have a mode of 0b11 then we have to rewrite this.
4440c3ddb60eSPeter Grehan */
4441c3ddb60eSPeter Grehan dtrace_get_modrm(x, &mode, ®, &r_m);
4442c3ddb60eSPeter Grehan if (mode == REG_ONLY) {
4443c3ddb60eSPeter Grehan dp = (instable_t *)&dis_op0FC7m3[off];
4444c3ddb60eSPeter Grehan break;
4445c3ddb60eSPeter Grehan }
4446c3ddb60eSPeter Grehan
4447c3ddb60eSPeter Grehan /*
4448c3ddb60eSPeter Grehan * Rewrite if this instruction used one of the magic prefixes.
4449c3ddb60eSPeter Grehan */
4450c3ddb60eSPeter Grehan if (rep_prefix) {
4451c3ddb60eSPeter Grehan if (rep_prefix == 0xf3)
4452c3ddb60eSPeter Grehan dp = (instable_t *)&dis_opF30FC7[off];
4453c3ddb60eSPeter Grehan else
4454c3ddb60eSPeter Grehan goto error;
4455c3ddb60eSPeter Grehan rep_prefix = 0;
4456c3ddb60eSPeter Grehan } else if (opnd_size_prefix) {
4457c3ddb60eSPeter Grehan dp = (instable_t *)&dis_op660FC7[off];
4458c3ddb60eSPeter Grehan opnd_size_prefix = 0;
4459c3ddb60eSPeter Grehan if (opnd_size == SIZE16)
4460c3ddb60eSPeter Grehan opnd_size = SIZE32;
4461722b2e2fSMark Johnston } else if (reg == 4 || reg == 5) {
4462722b2e2fSMark Johnston /*
4463722b2e2fSMark Johnston * We have xsavec (4) or xsaves (5), so rewrite.
4464722b2e2fSMark Johnston */
4465722b2e2fSMark Johnston dp = (instable_t *)&dis_op0FC7[reg];
4466722b2e2fSMark Johnston break;
4467c3ddb60eSPeter Grehan }
4468c3ddb60eSPeter Grehan break;
4469c3ddb60eSPeter Grehan
4470c3ddb60eSPeter Grehan
44710339a1c2SMark Johnston case MMOSH:
44720339a1c2SMark Johnston /*
44730339a1c2SMark Johnston * As with the "normal" SIMD instructions, the MMX
44740339a1c2SMark Johnston * shuffle instructions are overloaded. These
44750339a1c2SMark Johnston * instructions, however, are special in that they use
44760339a1c2SMark Johnston * an extra byte, and thus an extra table. As of this
44770339a1c2SMark Johnston * writing, they only use the opnd_size prefix.
44780339a1c2SMark Johnston */
44790339a1c2SMark Johnston
44800339a1c2SMark Johnston /*
44810339a1c2SMark Johnston * Calculate our offset in dis_op0F7123
44820339a1c2SMark Johnston */
44830339a1c2SMark Johnston if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
44840339a1c2SMark Johnston sizeof (dis_op0F7123))
44850339a1c2SMark Johnston goto error;
44860339a1c2SMark Johnston
44870339a1c2SMark Johnston if (opnd_size_prefix) {
44880339a1c2SMark Johnston off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
44890339a1c2SMark Johnston sizeof (instable_t);
44900339a1c2SMark Johnston dp = (instable_t *)&dis_opSIMD7123[off];
44910339a1c2SMark Johnston opnd_size_prefix = 0;
44920339a1c2SMark Johnston if (opnd_size == SIZE16)
44930339a1c2SMark Johnston opnd_size = SIZE32;
44940339a1c2SMark Johnston }
44950339a1c2SMark Johnston break;
44960339a1c2SMark Johnston case MRw:
44970339a1c2SMark Johnston if (rep_prefix) {
44980339a1c2SMark Johnston if (rep_prefix == 0xf3) {
44990339a1c2SMark Johnston
45000339a1c2SMark Johnston /*
45010339a1c2SMark Johnston * Calculate our offset in dis_op0F
45020339a1c2SMark Johnston */
4503722b2e2fSMark Johnston if ((uintptr_t)dp - (uintptr_t)dis_op0F >
4504722b2e2fSMark Johnston sizeof (dis_op0F))
45050339a1c2SMark Johnston goto error;
45060339a1c2SMark Johnston
45070339a1c2SMark Johnston off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
45080339a1c2SMark Johnston sizeof (instable_t);
45090339a1c2SMark Johnston
45100339a1c2SMark Johnston dp = (instable_t *)&dis_opSIMDrepz[off];
45110339a1c2SMark Johnston rep_prefix = 0;
45120339a1c2SMark Johnston } else {
45130339a1c2SMark Johnston goto error;
45140339a1c2SMark Johnston }
45150339a1c2SMark Johnston }
45160339a1c2SMark Johnston break;
4517722b2e2fSMark Johnston case FSGS:
4518722b2e2fSMark Johnston if (rep_prefix == 0xf3) {
4519722b2e2fSMark Johnston if ((uintptr_t)dp - (uintptr_t)dis_op0FAE >
4520722b2e2fSMark Johnston sizeof (dis_op0FAE))
4521722b2e2fSMark Johnston goto error;
4522722b2e2fSMark Johnston
4523722b2e2fSMark Johnston off = ((uintptr_t)dp - (uintptr_t)dis_op0FAE) /
4524722b2e2fSMark Johnston sizeof (instable_t);
4525722b2e2fSMark Johnston dp = (instable_t *)&dis_opF30FAE[off];
4526722b2e2fSMark Johnston rep_prefix = 0;
4527722b2e2fSMark Johnston } else if (rep_prefix != 0x00) {
4528722b2e2fSMark Johnston goto error;
4529722b2e2fSMark Johnston }
45300339a1c2SMark Johnston }
45310339a1c2SMark Johnston
45320339a1c2SMark Johnston /*
45330339a1c2SMark Johnston * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
45340339a1c2SMark Johnston */
45350339a1c2SMark Johnston if (cpu_mode == SIZE64)
45360339a1c2SMark Johnston if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
45370339a1c2SMark Johnston opnd_size = SIZE64;
45380339a1c2SMark Johnston
45390339a1c2SMark Johnston #ifdef DIS_TEXT
45400339a1c2SMark Johnston /*
45410339a1c2SMark Johnston * At this point most instructions can format the opcode mnemonic
45420339a1c2SMark Johnston * including the prefixes.
45430339a1c2SMark Johnston */
45440339a1c2SMark Johnston if (lock_prefix)
45450339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "lock ", OPLEN);
45460339a1c2SMark Johnston
45470339a1c2SMark Johnston if (rep_prefix == 0xf2)
45480339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "repnz ", OPLEN);
45490339a1c2SMark Johnston else if (rep_prefix == 0xf3)
45500339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "repz ", OPLEN);
45510339a1c2SMark Johnston
45520339a1c2SMark Johnston if (cpu_mode == SIZE64 && addr_size_prefix)
45530339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
45540339a1c2SMark Johnston
45550339a1c2SMark Johnston if (dp->it_adrmode != CBW &&
45560339a1c2SMark Johnston dp->it_adrmode != CWD &&
45570339a1c2SMark Johnston dp->it_adrmode != XMMSFNC) {
45580339a1c2SMark Johnston if (strcmp(dp->it_name, "INVALID") == 0)
45590339a1c2SMark Johnston goto error;
45600339a1c2SMark Johnston (void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
4561722b2e2fSMark Johnston if (dp->it_avxsuf == AVS2 && dp->it_suffix) {
4562b3b5bfebSMark Johnston (void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",
4563b3b5bfebSMark Johnston OPLEN);
4564722b2e2fSMark Johnston } else if (dp->it_vexopmask && dp->it_suffix) {
4565722b2e2fSMark Johnston /* opmask instructions */
4566722b2e2fSMark Johnston
4567722b2e2fSMark Johnston if (opcode1 == 4 && opcode2 == 0xb) {
4568722b2e2fSMark Johnston /* It's a kunpck. */
4569722b2e2fSMark Johnston if (vex_prefix == VEX_2bytes) {
4570722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4571722b2e2fSMark Johnston vex_p == 0 ? "wd" : "bw", OPLEN);
4572722b2e2fSMark Johnston } else {
4573722b2e2fSMark Johnston /* vex_prefix == VEX_3bytes */
4574722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4575722b2e2fSMark Johnston "dq", OPLEN);
4576722b2e2fSMark Johnston }
4577722b2e2fSMark Johnston } else if (opcode1 == 3) {
4578722b2e2fSMark Johnston /* It's a kshift[l|r]. */
4579722b2e2fSMark Johnston if (vex_W == 0) {
4580722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4581722b2e2fSMark Johnston opcode2 == 2 ||
4582722b2e2fSMark Johnston opcode2 == 0 ?
4583722b2e2fSMark Johnston "b" : "d", OPLEN);
4584722b2e2fSMark Johnston } else {
4585722b2e2fSMark Johnston /* W == 1 */
4586722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4587722b2e2fSMark Johnston opcode2 == 3 || opcode2 == 1 ?
4588722b2e2fSMark Johnston "q" : "w", OPLEN);
4589722b2e2fSMark Johnston }
4590722b2e2fSMark Johnston } else {
4591722b2e2fSMark Johnston /* if (vex_prefix == VEX_2bytes) { */
4592722b2e2fSMark Johnston if ((cpu_mode == SIZE64 && opnd_size == 2) ||
4593722b2e2fSMark Johnston vex_prefix == VEX_2bytes) {
4594722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4595722b2e2fSMark Johnston vex_p == 0 ? "w" :
4596722b2e2fSMark Johnston vex_p == 1 ? "b" : "d",
4597722b2e2fSMark Johnston OPLEN);
4598722b2e2fSMark Johnston } else {
4599722b2e2fSMark Johnston /* vex_prefix == VEX_3bytes */
4600722b2e2fSMark Johnston (void) strlcat(x->d86_mnem,
4601722b2e2fSMark Johnston vex_p == 1 ? "d" : "q", OPLEN);
4602722b2e2fSMark Johnston }
4603722b2e2fSMark Johnston }
4604b3b5bfebSMark Johnston } else if (dp->it_suffix) {
46050339a1c2SMark Johnston char *types[] = {"", "w", "l", "q"};
46060339a1c2SMark Johnston if (opcode_bytes == 2 && opcode4 == 4) {
46070339a1c2SMark Johnston /* It's a cmovx.yy. Replace the suffix x */
46080339a1c2SMark Johnston for (i = 5; i < OPLEN; i++) {
46090339a1c2SMark Johnston if (x->d86_mnem[i] == '.')
46100339a1c2SMark Johnston break;
46110339a1c2SMark Johnston }
46120339a1c2SMark Johnston x->d86_mnem[i - 1] = *types[opnd_size];
46130339a1c2SMark Johnston } else if ((opnd_size == 2) && (opcode_bytes == 3) &&
46140339a1c2SMark Johnston ((opcode6 == 1 && opcode7 == 6) ||
46150339a1c2SMark Johnston (opcode6 == 2 && opcode7 == 2))) {
46160339a1c2SMark Johnston /*
46170339a1c2SMark Johnston * To handle PINSRD and PEXTRD
46180339a1c2SMark Johnston */
46190339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "d", OPLEN);
4620722b2e2fSMark Johnston } else if (dp != &dis_distable[0x6][0x2]) {
4621722b2e2fSMark Johnston /* bound instructions (0x62) have no suffix */
46220339a1c2SMark Johnston (void) strlcat(x->d86_mnem, types[opnd_size],
46230339a1c2SMark Johnston OPLEN);
46240339a1c2SMark Johnston }
46250339a1c2SMark Johnston }
46260339a1c2SMark Johnston }
46270339a1c2SMark Johnston #endif
46280339a1c2SMark Johnston
46290339a1c2SMark Johnston /*
46300339a1c2SMark Johnston * Process operands based on the addressing modes.
46310339a1c2SMark Johnston */
46320339a1c2SMark Johnston x->d86_mode = cpu_mode;
46330339a1c2SMark Johnston /*
46340339a1c2SMark Johnston * In vex mode the rex_prefix has no meaning
46350339a1c2SMark Johnston */
4636722b2e2fSMark Johnston if (!vex_prefix && evex_prefix == 0)
46370339a1c2SMark Johnston x->d86_rex_prefix = rex_prefix;
46380339a1c2SMark Johnston x->d86_opnd_size = opnd_size;
46390339a1c2SMark Johnston x->d86_addr_size = addr_size;
46400339a1c2SMark Johnston vbit = 0; /* initialize for mem/reg -> reg */
46410339a1c2SMark Johnston switch (dp->it_adrmode) {
46420339a1c2SMark Johnston /*
46430339a1c2SMark Johnston * amd64 instruction to sign extend 32 bit reg/mem operands
46440339a1c2SMark Johnston * into 64 bit register values
46450339a1c2SMark Johnston */
46460339a1c2SMark Johnston case MOVSXZ:
46470339a1c2SMark Johnston #ifdef DIS_TEXT
46480339a1c2SMark Johnston if (rex_prefix == 0)
46490339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "movzld", OPLEN);
46500339a1c2SMark Johnston #endif
46510339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
46520339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
46530339a1c2SMark Johnston x->d86_opnd_size = SIZE64;
46540339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
46550339a1c2SMark Johnston x->d86_opnd_size = opnd_size = SIZE32;
46560339a1c2SMark Johnston wbit = LONG_OPND;
46570339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
46580339a1c2SMark Johnston break;
46590339a1c2SMark Johnston
46600339a1c2SMark Johnston /*
46610339a1c2SMark Johnston * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
46620339a1c2SMark Johnston * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
46630339a1c2SMark Johnston * wbit lives in 2nd byte, note that operands
46640339a1c2SMark Johnston * are different sized
46650339a1c2SMark Johnston */
46660339a1c2SMark Johnston case MOVZ:
46670339a1c2SMark Johnston if (rex_prefix & REX_W) {
46680339a1c2SMark Johnston /* target register size = 64 bit */
46690339a1c2SMark Johnston x->d86_mnem[5] = 'q';
46700339a1c2SMark Johnston }
46710339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
46720339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
46730339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
46740339a1c2SMark Johnston x->d86_opnd_size = opnd_size = SIZE16;
46750339a1c2SMark Johnston wbit = WBIT(opcode5);
46760339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
46770339a1c2SMark Johnston break;
46780339a1c2SMark Johnston case CRC32:
46790339a1c2SMark Johnston opnd_size = SIZE32;
46800339a1c2SMark Johnston if (rex_prefix & REX_W)
46810339a1c2SMark Johnston opnd_size = SIZE64;
46820339a1c2SMark Johnston x->d86_opnd_size = opnd_size;
46830339a1c2SMark Johnston
46840339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
46850339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
46860339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
46870339a1c2SMark Johnston wbit = WBIT(opcode7);
46880339a1c2SMark Johnston if (opnd_size_prefix)
46890339a1c2SMark Johnston x->d86_opnd_size = opnd_size = SIZE16;
46900339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
46910339a1c2SMark Johnston break;
46920339a1c2SMark Johnston case MOVBE:
46930339a1c2SMark Johnston opnd_size = SIZE32;
46940339a1c2SMark Johnston if (rex_prefix & REX_W)
46950339a1c2SMark Johnston opnd_size = SIZE64;
46960339a1c2SMark Johnston x->d86_opnd_size = opnd_size;
46970339a1c2SMark Johnston
46980339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
46990339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
47000339a1c2SMark Johnston wbit = WBIT(opcode7);
47010339a1c2SMark Johnston if (opnd_size_prefix)
47020339a1c2SMark Johnston x->d86_opnd_size = opnd_size = SIZE16;
47030339a1c2SMark Johnston if (wbit) {
47040339a1c2SMark Johnston /* reg -> mem */
47050339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
47060339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
47070339a1c2SMark Johnston } else {
47080339a1c2SMark Johnston /* mem -> reg */
47090339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
47100339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
47110339a1c2SMark Johnston }
47120339a1c2SMark Johnston break;
47130339a1c2SMark Johnston
47140339a1c2SMark Johnston /*
47150339a1c2SMark Johnston * imul instruction, with either 8-bit or longer immediate
47160339a1c2SMark Johnston * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
47170339a1c2SMark Johnston */
47180339a1c2SMark Johnston case IMUL:
47190339a1c2SMark Johnston wbit = LONG_OPND;
47200339a1c2SMark Johnston THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
47210339a1c2SMark Johnston OPSIZE(opnd_size, opcode2 == 0x9), 1);
47220339a1c2SMark Johnston break;
47230339a1c2SMark Johnston
47240339a1c2SMark Johnston /* memory or register operand to register, with 'w' bit */
47250339a1c2SMark Johnston case MRw:
4726b3b5bfebSMark Johnston case ADX:
47270339a1c2SMark Johnston wbit = WBIT(opcode2);
47280339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
47290339a1c2SMark Johnston break;
47300339a1c2SMark Johnston
47310339a1c2SMark Johnston /* register to memory or register operand, with 'w' bit */
47320339a1c2SMark Johnston /* arpl happens to fit here also because it is odd */
47330339a1c2SMark Johnston case RMw:
47340339a1c2SMark Johnston if (opcode_bytes == 2)
47350339a1c2SMark Johnston wbit = WBIT(opcode5);
47360339a1c2SMark Johnston else
47370339a1c2SMark Johnston wbit = WBIT(opcode2);
47380339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
47390339a1c2SMark Johnston break;
47400339a1c2SMark Johnston
47410339a1c2SMark Johnston /* xaddb instruction */
47420339a1c2SMark Johnston case XADDB:
47430339a1c2SMark Johnston wbit = 0;
47440339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
47450339a1c2SMark Johnston break;
47460339a1c2SMark Johnston
47470339a1c2SMark Johnston /* MMX register to memory or register operand */
47480339a1c2SMark Johnston case MMS:
47490339a1c2SMark Johnston case MMOS:
47500339a1c2SMark Johnston #ifdef DIS_TEXT
47510339a1c2SMark Johnston wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
47520339a1c2SMark Johnston #else
47530339a1c2SMark Johnston wbit = LONG_OPND;
47540339a1c2SMark Johnston #endif
47550339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
47560339a1c2SMark Johnston break;
47570339a1c2SMark Johnston
47580339a1c2SMark Johnston /* MMX register to memory */
47590339a1c2SMark Johnston case MMOMS:
47600339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
47610339a1c2SMark Johnston if (mode == REG_ONLY)
47620339a1c2SMark Johnston goto error;
47630339a1c2SMark Johnston wbit = MM_OPND;
47640339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
47650339a1c2SMark Johnston break;
47660339a1c2SMark Johnston
47670339a1c2SMark Johnston /* Double shift. Has immediate operand specifying the shift. */
47680339a1c2SMark Johnston case DSHIFT:
47690339a1c2SMark Johnston wbit = LONG_OPND;
47700339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
47710339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
47720339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2);
47730339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
47740339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
47750339a1c2SMark Johnston break;
47760339a1c2SMark Johnston
47770339a1c2SMark Johnston /*
47780339a1c2SMark Johnston * Double shift. With no immediate operand, specifies using %cl.
47790339a1c2SMark Johnston */
47800339a1c2SMark Johnston case DSHIFTcl:
47810339a1c2SMark Johnston wbit = LONG_OPND;
47820339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
47830339a1c2SMark Johnston break;
47840339a1c2SMark Johnston
47850339a1c2SMark Johnston /* immediate to memory or register operand */
47860339a1c2SMark Johnston case IMlw:
47870339a1c2SMark Johnston wbit = WBIT(opcode2);
47880339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
47890339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
47900339a1c2SMark Johnston /*
47910339a1c2SMark Johnston * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
47920339a1c2SMark Johnston */
47930339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
47940339a1c2SMark Johnston break;
47950339a1c2SMark Johnston
47960339a1c2SMark Johnston /* immediate to memory or register operand with the */
47970339a1c2SMark Johnston /* 'w' bit present */
47980339a1c2SMark Johnston case IMw:
47990339a1c2SMark Johnston wbit = WBIT(opcode2);
48000339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
48010339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
48020339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
48030339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
48040339a1c2SMark Johnston break;
48050339a1c2SMark Johnston
48060339a1c2SMark Johnston /* immediate to register with register in low 3 bits */
48070339a1c2SMark Johnston /* of op code */
48080339a1c2SMark Johnston case IR:
48090339a1c2SMark Johnston /* w-bit here (with regs) is bit 3 */
48100339a1c2SMark Johnston wbit = opcode2 >>3 & 0x1;
48110339a1c2SMark Johnston reg = REGNO(opcode2);
48120339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, NULL);
48130339a1c2SMark Johnston mode = REG_ONLY;
48140339a1c2SMark Johnston r_m = reg;
48150339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
48160339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
48170339a1c2SMark Johnston break;
48180339a1c2SMark Johnston
48190339a1c2SMark Johnston /* MMX immediate shift of register */
48200339a1c2SMark Johnston case MMSH:
48210339a1c2SMark Johnston case MMOSH:
48220339a1c2SMark Johnston wbit = MM_OPND;
48230339a1c2SMark Johnston goto mm_shift; /* in next case */
48240339a1c2SMark Johnston
48250339a1c2SMark Johnston /* SIMD immediate shift of register */
48260339a1c2SMark Johnston case XMMSH:
48270339a1c2SMark Johnston wbit = XMM_OPND;
48280339a1c2SMark Johnston mm_shift:
48290339a1c2SMark Johnston reg = REGNO(opcode7);
48300339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, NULL);
48310339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
48320339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
48330339a1c2SMark Johnston NOMEM;
48340339a1c2SMark Johnston break;
48350339a1c2SMark Johnston
48360339a1c2SMark Johnston /* accumulator to memory operand */
48370339a1c2SMark Johnston case AO:
48380339a1c2SMark Johnston vbit = 1;
48390339a1c2SMark Johnston /*FALLTHROUGH*/
48400339a1c2SMark Johnston
48410339a1c2SMark Johnston /* memory operand to accumulator */
48420339a1c2SMark Johnston case OA:
48430339a1c2SMark Johnston wbit = WBIT(opcode2);
48440339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
48450339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
48460339a1c2SMark Johnston #ifdef DIS_TEXT
48470339a1c2SMark Johnston x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
48480339a1c2SMark Johnston #endif
48490339a1c2SMark Johnston break;
48500339a1c2SMark Johnston
48510339a1c2SMark Johnston
48520339a1c2SMark Johnston /* segment register to memory or register operand */
48530339a1c2SMark Johnston case SM:
48540339a1c2SMark Johnston vbit = 1;
48550339a1c2SMark Johnston /*FALLTHROUGH*/
48560339a1c2SMark Johnston
48570339a1c2SMark Johnston /* memory or register operand to segment register */
48580339a1c2SMark Johnston case MS:
48590339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
48600339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
48610339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
48620339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
4863*418d8f0dSMark Johnston wbit = SEG_OPND;
48640339a1c2SMark Johnston break;
48650339a1c2SMark Johnston
48660339a1c2SMark Johnston /*
48670339a1c2SMark Johnston * rotate or shift instructions, which may shift by 1 or
48680339a1c2SMark Johnston * consult the cl register, depending on the 'v' bit
48690339a1c2SMark Johnston */
48700339a1c2SMark Johnston case Mv:
48710339a1c2SMark Johnston vbit = VBIT(opcode2);
48720339a1c2SMark Johnston wbit = WBIT(opcode2);
48730339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
48740339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
48750339a1c2SMark Johnston #ifdef DIS_TEXT
48760339a1c2SMark Johnston if (vbit) {
48770339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
48780339a1c2SMark Johnston } else {
48790339a1c2SMark Johnston x->d86_opnd[0].d86_mode = MODE_SIGNED;
48800339a1c2SMark Johnston x->d86_opnd[0].d86_value_size = 1;
48810339a1c2SMark Johnston x->d86_opnd[0].d86_value = 1;
48820339a1c2SMark Johnston }
48830339a1c2SMark Johnston #endif
48840339a1c2SMark Johnston break;
48850339a1c2SMark Johnston /*
48860339a1c2SMark Johnston * immediate rotate or shift instructions
48870339a1c2SMark Johnston */
48880339a1c2SMark Johnston case MvI:
48890339a1c2SMark Johnston wbit = WBIT(opcode2);
48900339a1c2SMark Johnston normal_imm_mem:
48910339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
48920339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
48930339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
48940339a1c2SMark Johnston break;
48950339a1c2SMark Johnston
48960339a1c2SMark Johnston /* bit test instructions */
48970339a1c2SMark Johnston case MIb:
48980339a1c2SMark Johnston wbit = LONG_OPND;
48990339a1c2SMark Johnston goto normal_imm_mem;
49000339a1c2SMark Johnston
49010339a1c2SMark Johnston /* single memory or register operand with 'w' bit present */
49020339a1c2SMark Johnston case Mw:
49030339a1c2SMark Johnston wbit = WBIT(opcode2);
49040339a1c2SMark Johnston just_mem:
49050339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
49060339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
49070339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
49080339a1c2SMark Johnston break;
49090339a1c2SMark Johnston
4910c3ddb60eSPeter Grehan case SWAPGS_RDTSCP:
49110339a1c2SMark Johnston if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
49120339a1c2SMark Johnston #ifdef DIS_TEXT
49130339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "swapgs", OPLEN);
49140339a1c2SMark Johnston #endif
49150339a1c2SMark Johnston NOMEM;
49160339a1c2SMark Johnston break;
4917c3ddb60eSPeter Grehan } else if (mode == 3 && r_m == 1) {
4918c3ddb60eSPeter Grehan #ifdef DIS_TEXT
4919c3ddb60eSPeter Grehan (void) strncpy(x->d86_mnem, "rdtscp", OPLEN);
4920c3ddb60eSPeter Grehan #endif
4921c3ddb60eSPeter Grehan NOMEM;
4922c3ddb60eSPeter Grehan break;
4923722b2e2fSMark Johnston } else if (mode == 3 && r_m == 2) {
4924722b2e2fSMark Johnston #ifdef DIS_TEXT
4925722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "monitorx", OPLEN);
4926722b2e2fSMark Johnston #endif
4927722b2e2fSMark Johnston NOMEM;
4928722b2e2fSMark Johnston break;
4929722b2e2fSMark Johnston } else if (mode == 3 && r_m == 3) {
4930722b2e2fSMark Johnston #ifdef DIS_TEXT
4931722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "mwaitx", OPLEN);
4932722b2e2fSMark Johnston #endif
4933722b2e2fSMark Johnston NOMEM;
4934722b2e2fSMark Johnston break;
4935722b2e2fSMark Johnston } else if (mode == 3 && r_m == 4) {
4936722b2e2fSMark Johnston #ifdef DIS_TEXT
4937722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "clzero", OPLEN);
4938722b2e2fSMark Johnston #endif
4939722b2e2fSMark Johnston NOMEM;
4940722b2e2fSMark Johnston break;
49410339a1c2SMark Johnston }
4942c3ddb60eSPeter Grehan
49430339a1c2SMark Johnston /*FALLTHROUGH*/
49440339a1c2SMark Johnston
49450339a1c2SMark Johnston /* prefetch instruction - memory operand, but no memory acess */
49460339a1c2SMark Johnston case PREF:
49470339a1c2SMark Johnston NOMEM;
49480339a1c2SMark Johnston /*FALLTHROUGH*/
49490339a1c2SMark Johnston
49500339a1c2SMark Johnston /* single memory or register operand */
49510339a1c2SMark Johnston case M:
4952c3ddb60eSPeter Grehan case MG9:
49530339a1c2SMark Johnston wbit = LONG_OPND;
49540339a1c2SMark Johnston goto just_mem;
49550339a1c2SMark Johnston
49560339a1c2SMark Johnston /* single memory or register byte operand */
49570339a1c2SMark Johnston case Mb:
49580339a1c2SMark Johnston wbit = BYTE_OPND;
49590339a1c2SMark Johnston goto just_mem;
49600339a1c2SMark Johnston
4961c3ddb60eSPeter Grehan case VMx:
4962c3ddb60eSPeter Grehan if (mode == 3) {
4963c3ddb60eSPeter Grehan #ifdef DIS_TEXT
4964c3ddb60eSPeter Grehan char *vminstr;
4965c3ddb60eSPeter Grehan
4966c3ddb60eSPeter Grehan switch (r_m) {
4967c3ddb60eSPeter Grehan case 1:
4968c3ddb60eSPeter Grehan vminstr = "vmcall";
4969c3ddb60eSPeter Grehan break;
4970c3ddb60eSPeter Grehan case 2:
4971c3ddb60eSPeter Grehan vminstr = "vmlaunch";
4972c3ddb60eSPeter Grehan break;
4973c3ddb60eSPeter Grehan case 3:
4974c3ddb60eSPeter Grehan vminstr = "vmresume";
4975c3ddb60eSPeter Grehan break;
4976c3ddb60eSPeter Grehan case 4:
4977c3ddb60eSPeter Grehan vminstr = "vmxoff";
4978c3ddb60eSPeter Grehan break;
4979c3ddb60eSPeter Grehan default:
4980c3ddb60eSPeter Grehan goto error;
4981c3ddb60eSPeter Grehan }
4982c3ddb60eSPeter Grehan
4983c3ddb60eSPeter Grehan (void) strncpy(x->d86_mnem, vminstr, OPLEN);
4984c3ddb60eSPeter Grehan #else
4985c3ddb60eSPeter Grehan if (r_m < 1 || r_m > 4)
4986c3ddb60eSPeter Grehan goto error;
4987c3ddb60eSPeter Grehan #endif
4988c3ddb60eSPeter Grehan
4989c3ddb60eSPeter Grehan NOMEM;
4990c3ddb60eSPeter Grehan break;
4991c3ddb60eSPeter Grehan }
4992c3ddb60eSPeter Grehan /*FALLTHROUGH*/
4993c3ddb60eSPeter Grehan case SVM:
4994c3ddb60eSPeter Grehan if (mode == 3) {
4995c3ddb60eSPeter Grehan #ifdef DIS_TEXT
4996c3ddb60eSPeter Grehan char *vinstr;
4997c3ddb60eSPeter Grehan
4998c3ddb60eSPeter Grehan switch (r_m) {
4999c3ddb60eSPeter Grehan case 0:
5000c3ddb60eSPeter Grehan vinstr = "vmrun";
5001c3ddb60eSPeter Grehan break;
5002c3ddb60eSPeter Grehan case 1:
5003c3ddb60eSPeter Grehan vinstr = "vmmcall";
5004c3ddb60eSPeter Grehan break;
5005c3ddb60eSPeter Grehan case 2:
5006c3ddb60eSPeter Grehan vinstr = "vmload";
5007c3ddb60eSPeter Grehan break;
5008c3ddb60eSPeter Grehan case 3:
5009c3ddb60eSPeter Grehan vinstr = "vmsave";
5010c3ddb60eSPeter Grehan break;
5011c3ddb60eSPeter Grehan case 4:
5012c3ddb60eSPeter Grehan vinstr = "stgi";
5013c3ddb60eSPeter Grehan break;
5014c3ddb60eSPeter Grehan case 5:
5015c3ddb60eSPeter Grehan vinstr = "clgi";
5016c3ddb60eSPeter Grehan break;
5017c3ddb60eSPeter Grehan case 6:
5018c3ddb60eSPeter Grehan vinstr = "skinit";
5019c3ddb60eSPeter Grehan break;
5020c3ddb60eSPeter Grehan case 7:
5021c3ddb60eSPeter Grehan vinstr = "invlpga";
5022c3ddb60eSPeter Grehan break;
5023c3ddb60eSPeter Grehan }
5024c3ddb60eSPeter Grehan
5025c3ddb60eSPeter Grehan (void) strncpy(x->d86_mnem, vinstr, OPLEN);
5026c3ddb60eSPeter Grehan #endif
5027c3ddb60eSPeter Grehan NOMEM;
5028c3ddb60eSPeter Grehan break;
5029c3ddb60eSPeter Grehan }
5030c3ddb60eSPeter Grehan /*FALLTHROUGH*/
50310339a1c2SMark Johnston case MONITOR_MWAIT:
50320339a1c2SMark Johnston if (mode == 3) {
50330339a1c2SMark Johnston if (r_m == 0) {
50340339a1c2SMark Johnston #ifdef DIS_TEXT
50350339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "monitor", OPLEN);
50360339a1c2SMark Johnston #endif
50370339a1c2SMark Johnston NOMEM;
50380339a1c2SMark Johnston break;
50390339a1c2SMark Johnston } else if (r_m == 1) {
50400339a1c2SMark Johnston #ifdef DIS_TEXT
50410339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "mwait", OPLEN);
50420339a1c2SMark Johnston #endif
50430339a1c2SMark Johnston NOMEM;
50440339a1c2SMark Johnston break;
5045b3b5bfebSMark Johnston } else if (r_m == 2) {
5046b3b5bfebSMark Johnston #ifdef DIS_TEXT
5047b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem, "clac", OPLEN);
5048b3b5bfebSMark Johnston #endif
5049b3b5bfebSMark Johnston NOMEM;
5050b3b5bfebSMark Johnston break;
5051b3b5bfebSMark Johnston } else if (r_m == 3) {
5052b3b5bfebSMark Johnston #ifdef DIS_TEXT
5053b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem, "stac", OPLEN);
5054b3b5bfebSMark Johnston #endif
5055b3b5bfebSMark Johnston NOMEM;
5056b3b5bfebSMark Johnston break;
50570339a1c2SMark Johnston } else {
50580339a1c2SMark Johnston goto error;
50590339a1c2SMark Johnston }
50600339a1c2SMark Johnston }
50610339a1c2SMark Johnston /*FALLTHROUGH*/
50620339a1c2SMark Johnston case XGETBV_XSETBV:
50630339a1c2SMark Johnston if (mode == 3) {
50640339a1c2SMark Johnston if (r_m == 0) {
50650339a1c2SMark Johnston #ifdef DIS_TEXT
50660339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
50670339a1c2SMark Johnston #endif
50680339a1c2SMark Johnston NOMEM;
50690339a1c2SMark Johnston break;
50700339a1c2SMark Johnston } else if (r_m == 1) {
50710339a1c2SMark Johnston #ifdef DIS_TEXT
50720339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
50730339a1c2SMark Johnston #endif
50740339a1c2SMark Johnston NOMEM;
50750339a1c2SMark Johnston break;
50760339a1c2SMark Johnston } else {
50770339a1c2SMark Johnston goto error;
50780339a1c2SMark Johnston }
50790339a1c2SMark Johnston
50800339a1c2SMark Johnston }
50810339a1c2SMark Johnston /*FALLTHROUGH*/
50820339a1c2SMark Johnston case MO:
50830339a1c2SMark Johnston /* Similar to M, but only memory (no direct registers) */
50840339a1c2SMark Johnston wbit = LONG_OPND;
50850339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
50860339a1c2SMark Johnston if (mode == 3)
50870339a1c2SMark Johnston goto error;
50880339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
50890339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
50900339a1c2SMark Johnston break;
50910339a1c2SMark Johnston
50920339a1c2SMark Johnston /* move special register to register or reverse if vbit */
50930339a1c2SMark Johnston case SREG:
50940339a1c2SMark Johnston switch (opcode5) {
50950339a1c2SMark Johnston
50960339a1c2SMark Johnston case 2:
50970339a1c2SMark Johnston vbit = 1;
50980339a1c2SMark Johnston /*FALLTHROUGH*/
50990339a1c2SMark Johnston case 0:
51000339a1c2SMark Johnston wbit = CONTROL_OPND;
51010339a1c2SMark Johnston break;
51020339a1c2SMark Johnston
51030339a1c2SMark Johnston case 3:
51040339a1c2SMark Johnston vbit = 1;
51050339a1c2SMark Johnston /*FALLTHROUGH*/
51060339a1c2SMark Johnston case 1:
51070339a1c2SMark Johnston wbit = DEBUG_OPND;
51080339a1c2SMark Johnston break;
51090339a1c2SMark Johnston
51100339a1c2SMark Johnston case 6:
51110339a1c2SMark Johnston vbit = 1;
51120339a1c2SMark Johnston /*FALLTHROUGH*/
51130339a1c2SMark Johnston case 4:
51140339a1c2SMark Johnston wbit = TEST_OPND;
51150339a1c2SMark Johnston break;
51160339a1c2SMark Johnston
51170339a1c2SMark Johnston }
51180339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
51190339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
51200339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
51210339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
51220339a1c2SMark Johnston NOMEM;
51230339a1c2SMark Johnston break;
51240339a1c2SMark Johnston
51250339a1c2SMark Johnston /*
51260339a1c2SMark Johnston * single register operand with register in the low 3
51270339a1c2SMark Johnston * bits of op code
51280339a1c2SMark Johnston */
51290339a1c2SMark Johnston case R:
51300339a1c2SMark Johnston if (opcode_bytes == 2)
51310339a1c2SMark Johnston reg = REGNO(opcode5);
51320339a1c2SMark Johnston else
51330339a1c2SMark Johnston reg = REGNO(opcode2);
51340339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, NULL);
51350339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
51360339a1c2SMark Johnston NOMEM;
51370339a1c2SMark Johnston break;
51380339a1c2SMark Johnston
51390339a1c2SMark Johnston /*
51400339a1c2SMark Johnston * register to accumulator with register in the low 3
51410339a1c2SMark Johnston * bits of op code, xchg instructions
51420339a1c2SMark Johnston */
51430339a1c2SMark Johnston case RA:
51440339a1c2SMark Johnston NOMEM;
51450339a1c2SMark Johnston reg = REGNO(opcode2);
51460339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, NULL);
51470339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
51480339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
51490339a1c2SMark Johnston break;
51500339a1c2SMark Johnston
51510339a1c2SMark Johnston /*
51520339a1c2SMark Johnston * single segment register operand, with register in
51530339a1c2SMark Johnston * bits 3-4 of op code byte
51540339a1c2SMark Johnston */
51550339a1c2SMark Johnston case SEG:
51560339a1c2SMark Johnston NOMEM;
51570339a1c2SMark Johnston reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
51580339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
51590339a1c2SMark Johnston break;
51600339a1c2SMark Johnston
51610339a1c2SMark Johnston /*
51620339a1c2SMark Johnston * single segment register operand, with register in
51630339a1c2SMark Johnston * bits 3-5 of op code
51640339a1c2SMark Johnston */
51650339a1c2SMark Johnston case LSEG:
51660339a1c2SMark Johnston NOMEM;
51670339a1c2SMark Johnston /* long seg reg from opcode */
51680339a1c2SMark Johnston reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
51690339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
51700339a1c2SMark Johnston break;
51710339a1c2SMark Johnston
51720339a1c2SMark Johnston /* memory or register operand to register */
51730339a1c2SMark Johnston case MR:
51740339a1c2SMark Johnston if (vex_prefetch)
51750339a1c2SMark Johnston x->d86_got_modrm = 1;
51760339a1c2SMark Johnston wbit = LONG_OPND;
51770339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
51780339a1c2SMark Johnston break;
51790339a1c2SMark Johnston
51800339a1c2SMark Johnston case RM:
5181c3ddb60eSPeter Grehan case RM_66r:
5182722b2e2fSMark Johnston if (vex_prefetch)
5183722b2e2fSMark Johnston x->d86_got_modrm = 1;
51840339a1c2SMark Johnston wbit = LONG_OPND;
51850339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
51860339a1c2SMark Johnston break;
51870339a1c2SMark Johnston
51880339a1c2SMark Johnston /* MMX/SIMD-Int memory or mm reg to mm reg */
51890339a1c2SMark Johnston case MM:
51900339a1c2SMark Johnston case MMO:
51910339a1c2SMark Johnston #ifdef DIS_TEXT
51920339a1c2SMark Johnston wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
51930339a1c2SMark Johnston #else
51940339a1c2SMark Johnston wbit = LONG_OPND;
51950339a1c2SMark Johnston #endif
51960339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
51970339a1c2SMark Johnston break;
51980339a1c2SMark Johnston
51990339a1c2SMark Johnston case MMOIMPL:
52000339a1c2SMark Johnston #ifdef DIS_TEXT
52010339a1c2SMark Johnston wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
52020339a1c2SMark Johnston #else
52030339a1c2SMark Johnston wbit = LONG_OPND;
52040339a1c2SMark Johnston #endif
52050339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
52060339a1c2SMark Johnston if (mode != REG_ONLY)
52070339a1c2SMark Johnston goto error;
52080339a1c2SMark Johnston
52090339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
52100339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
52110339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
52120339a1c2SMark Johnston mode = 0; /* change for memory access size... */
52130339a1c2SMark Johnston break;
52140339a1c2SMark Johnston
52150339a1c2SMark Johnston /* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
52160339a1c2SMark Johnston case MMO3P:
52170339a1c2SMark Johnston wbit = MM_OPND;
52180339a1c2SMark Johnston goto xmm3p;
52190339a1c2SMark Johnston case XMM3P:
52200339a1c2SMark Johnston wbit = XMM_OPND;
52210339a1c2SMark Johnston xmm3p:
52220339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
52230339a1c2SMark Johnston if (mode != REG_ONLY)
52240339a1c2SMark Johnston goto error;
52250339a1c2SMark Johnston
52260339a1c2SMark Johnston THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
52270339a1c2SMark Johnston 1);
52280339a1c2SMark Johnston NOMEM;
52290339a1c2SMark Johnston break;
52300339a1c2SMark Johnston
52310339a1c2SMark Johnston case XMM3PM_66r:
52320339a1c2SMark Johnston THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
52330339a1c2SMark Johnston 1, 0);
52340339a1c2SMark Johnston break;
52350339a1c2SMark Johnston
52360339a1c2SMark Johnston /* MMX/SIMD-Int predicated r32/mem to mm reg */
52370339a1c2SMark Johnston case MMOPRM:
52380339a1c2SMark Johnston wbit = LONG_OPND;
52390339a1c2SMark Johnston w2 = MM_OPND;
52400339a1c2SMark Johnston goto xmmprm;
52410339a1c2SMark Johnston case XMMPRM:
52420339a1c2SMark Johnston case XMMPRM_66r:
52430339a1c2SMark Johnston wbit = LONG_OPND;
52440339a1c2SMark Johnston w2 = XMM_OPND;
52450339a1c2SMark Johnston xmmprm:
52460339a1c2SMark Johnston THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
52470339a1c2SMark Johnston break;
52480339a1c2SMark Johnston
52490339a1c2SMark Johnston /* MMX/SIMD-Int predicated mm/mem to mm reg */
52500339a1c2SMark Johnston case MMOPM:
52510339a1c2SMark Johnston case MMOPM_66o:
52520339a1c2SMark Johnston wbit = w2 = MM_OPND;
52530339a1c2SMark Johnston goto xmmprm;
52540339a1c2SMark Johnston
52550339a1c2SMark Johnston /* MMX/SIMD-Int mm reg to r32 */
52560339a1c2SMark Johnston case MMOM3:
52570339a1c2SMark Johnston NOMEM;
52580339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
52590339a1c2SMark Johnston if (mode != REG_ONLY)
52600339a1c2SMark Johnston goto error;
52610339a1c2SMark Johnston wbit = MM_OPND;
52620339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
52630339a1c2SMark Johnston break;
52640339a1c2SMark Johnston
52650339a1c2SMark Johnston /* SIMD memory or xmm reg operand to xmm reg */
52660339a1c2SMark Johnston case XMM:
52670339a1c2SMark Johnston case XMM_66o:
52680339a1c2SMark Johnston case XMM_66r:
52690339a1c2SMark Johnston case XMMO:
52700339a1c2SMark Johnston case XMMXIMPL:
52710339a1c2SMark Johnston wbit = XMM_OPND;
52720339a1c2SMark Johnston STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
52730339a1c2SMark Johnston
52740339a1c2SMark Johnston if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
52750339a1c2SMark Johnston goto error;
52760339a1c2SMark Johnston
52770339a1c2SMark Johnston #ifdef DIS_TEXT
52780339a1c2SMark Johnston /*
52790339a1c2SMark Johnston * movlps and movhlps share opcodes. They differ in the
52800339a1c2SMark Johnston * addressing modes allowed for their operands.
52810339a1c2SMark Johnston * movhps and movlhps behave similarly.
52820339a1c2SMark Johnston */
52830339a1c2SMark Johnston if (mode == REG_ONLY) {
52840339a1c2SMark Johnston if (strcmp(dp->it_name, "movlps") == 0)
52850339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "movhlps", OPLEN);
52860339a1c2SMark Johnston else if (strcmp(dp->it_name, "movhps") == 0)
52870339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "movlhps", OPLEN);
52880339a1c2SMark Johnston }
52890339a1c2SMark Johnston #endif
52900339a1c2SMark Johnston if (dp->it_adrmode == XMMXIMPL)
52910339a1c2SMark Johnston mode = 0; /* change for memory access size... */
52920339a1c2SMark Johnston break;
52930339a1c2SMark Johnston
52940339a1c2SMark Johnston /* SIMD xmm reg to memory or xmm reg */
52950339a1c2SMark Johnston case XMMS:
52960339a1c2SMark Johnston case XMMOS:
52970339a1c2SMark Johnston case XMMMS:
52980339a1c2SMark Johnston case XMMOMS:
52990339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
53000339a1c2SMark Johnston #ifdef DIS_TEXT
53010339a1c2SMark Johnston if ((strcmp(dp->it_name, "movlps") == 0 ||
53020339a1c2SMark Johnston strcmp(dp->it_name, "movhps") == 0 ||
53030339a1c2SMark Johnston strcmp(dp->it_name, "movntps") == 0) &&
53040339a1c2SMark Johnston mode == REG_ONLY)
53050339a1c2SMark Johnston goto error;
53060339a1c2SMark Johnston #endif
53070339a1c2SMark Johnston wbit = XMM_OPND;
53080339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
53090339a1c2SMark Johnston break;
53100339a1c2SMark Johnston
53110339a1c2SMark Johnston /* SIMD memory to xmm reg */
53120339a1c2SMark Johnston case XMMM:
53130339a1c2SMark Johnston case XMMM_66r:
53140339a1c2SMark Johnston case XMMOM:
53150339a1c2SMark Johnston wbit = XMM_OPND;
53160339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
53170339a1c2SMark Johnston #ifdef DIS_TEXT
53180339a1c2SMark Johnston if (mode == REG_ONLY) {
53190339a1c2SMark Johnston if (strcmp(dp->it_name, "movhps") == 0)
53200339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "movlhps", OPLEN);
53210339a1c2SMark Johnston else
53220339a1c2SMark Johnston goto error;
53230339a1c2SMark Johnston }
53240339a1c2SMark Johnston #endif
53250339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
53260339a1c2SMark Johnston break;
53270339a1c2SMark Johnston
53280339a1c2SMark Johnston /* SIMD memory or r32 to xmm reg */
53290339a1c2SMark Johnston case XMM3MX:
53300339a1c2SMark Johnston wbit = LONG_OPND;
53310339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
53320339a1c2SMark Johnston break;
53330339a1c2SMark Johnston
53340339a1c2SMark Johnston case XMM3MXS:
53350339a1c2SMark Johnston wbit = LONG_OPND;
53360339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
53370339a1c2SMark Johnston break;
53380339a1c2SMark Johnston
53390339a1c2SMark Johnston /* SIMD memory or mm reg to xmm reg */
53400339a1c2SMark Johnston case XMMOMX:
53410339a1c2SMark Johnston /* SIMD mm to xmm */
53420339a1c2SMark Johnston case XMMMX:
53430339a1c2SMark Johnston wbit = MM_OPND;
53440339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
53450339a1c2SMark Johnston break;
53460339a1c2SMark Johnston
53470339a1c2SMark Johnston /* SIMD memory or xmm reg to mm reg */
53480339a1c2SMark Johnston case XMMXMM:
53490339a1c2SMark Johnston case XMMOXMM:
53500339a1c2SMark Johnston case XMMXM:
53510339a1c2SMark Johnston wbit = XMM_OPND;
53520339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
53530339a1c2SMark Johnston break;
53540339a1c2SMark Johnston
53550339a1c2SMark Johnston
53560339a1c2SMark Johnston /* SIMD memory or xmm reg to r32 */
53570339a1c2SMark Johnston case XMMXM3:
53580339a1c2SMark Johnston wbit = XMM_OPND;
53590339a1c2SMark Johnston MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
53600339a1c2SMark Johnston break;
53610339a1c2SMark Johnston
53620339a1c2SMark Johnston /* SIMD xmm to r32 */
53630339a1c2SMark Johnston case XMMX3:
53640339a1c2SMark Johnston case XMMOX3:
53650339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
53660339a1c2SMark Johnston if (mode != REG_ONLY)
53670339a1c2SMark Johnston goto error;
53680339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
53690339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
53700339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
53710339a1c2SMark Johnston NOMEM;
53720339a1c2SMark Johnston break;
53730339a1c2SMark Johnston
53740339a1c2SMark Johnston /* SIMD predicated memory or xmm reg with/to xmm reg */
53750339a1c2SMark Johnston case XMMP:
53760339a1c2SMark Johnston case XMMP_66r:
53770339a1c2SMark Johnston case XMMP_66o:
53780339a1c2SMark Johnston case XMMOPM:
53790339a1c2SMark Johnston wbit = XMM_OPND;
53800339a1c2SMark Johnston THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
53810339a1c2SMark Johnston 1);
53820339a1c2SMark Johnston
53830339a1c2SMark Johnston #ifdef DIS_TEXT
53840339a1c2SMark Johnston /*
53850339a1c2SMark Johnston * cmpps and cmpss vary their instruction name based
53860339a1c2SMark Johnston * on the value of imm8. Other XMMP instructions,
53870339a1c2SMark Johnston * such as shufps, require explicit specification of
53880339a1c2SMark Johnston * the predicate.
53890339a1c2SMark Johnston */
53900339a1c2SMark Johnston if (dp->it_name[0] == 'c' &&
53910339a1c2SMark Johnston dp->it_name[1] == 'm' &&
53920339a1c2SMark Johnston dp->it_name[2] == 'p' &&
53930339a1c2SMark Johnston strlen(dp->it_name) == 5) {
53940339a1c2SMark Johnston uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
53950339a1c2SMark Johnston
53960339a1c2SMark Johnston if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
53970339a1c2SMark Johnston goto error;
53980339a1c2SMark Johnston
53990339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "cmp", OPLEN);
54000339a1c2SMark Johnston (void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
54010339a1c2SMark Johnston OPLEN);
54020339a1c2SMark Johnston (void) strlcat(x->d86_mnem,
54030339a1c2SMark Johnston dp->it_name + strlen(dp->it_name) - 2,
54040339a1c2SMark Johnston OPLEN);
54050339a1c2SMark Johnston x->d86_opnd[0] = x->d86_opnd[1];
54060339a1c2SMark Johnston x->d86_opnd[1] = x->d86_opnd[2];
54070339a1c2SMark Johnston x->d86_numopnds = 2;
54080339a1c2SMark Johnston }
5409722b2e2fSMark Johnston
5410722b2e2fSMark Johnston /*
5411722b2e2fSMark Johnston * The pclmulqdq instruction has a series of alternate names for
5412722b2e2fSMark Johnston * various encodings of the immediate byte. As such, if we
5413722b2e2fSMark Johnston * happen to find it and the immediate value matches, we'll
5414722b2e2fSMark Johnston * rewrite the mnemonic.
5415722b2e2fSMark Johnston */
5416722b2e2fSMark Johnston if (strcmp(dp->it_name, "pclmulqdq") == 0) {
5417722b2e2fSMark Johnston boolean_t changed = B_TRUE;
5418722b2e2fSMark Johnston switch (x->d86_opnd[0].d86_value) {
5419722b2e2fSMark Johnston case 0x00:
5420722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "pclmullqlqdq",
5421722b2e2fSMark Johnston OPLEN);
5422722b2e2fSMark Johnston break;
5423722b2e2fSMark Johnston case 0x01:
5424722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "pclmulhqlqdq",
5425722b2e2fSMark Johnston OPLEN);
5426722b2e2fSMark Johnston break;
5427722b2e2fSMark Johnston case 0x10:
5428722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "pclmullqhqdq",
5429722b2e2fSMark Johnston OPLEN);
5430722b2e2fSMark Johnston break;
5431722b2e2fSMark Johnston case 0x11:
5432722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "pclmulhqhqdq",
5433722b2e2fSMark Johnston OPLEN);
5434722b2e2fSMark Johnston break;
5435722b2e2fSMark Johnston default:
5436722b2e2fSMark Johnston changed = B_FALSE;
5437722b2e2fSMark Johnston break;
5438722b2e2fSMark Johnston }
5439722b2e2fSMark Johnston
5440722b2e2fSMark Johnston if (changed == B_TRUE) {
5441722b2e2fSMark Johnston x->d86_opnd[0].d86_value_size = 0;
5442722b2e2fSMark Johnston x->d86_opnd[0] = x->d86_opnd[1];
5443722b2e2fSMark Johnston x->d86_opnd[1] = x->d86_opnd[2];
5444722b2e2fSMark Johnston x->d86_numopnds = 2;
5445722b2e2fSMark Johnston }
5446722b2e2fSMark Johnston }
54470339a1c2SMark Johnston #endif
54480339a1c2SMark Johnston break;
54490339a1c2SMark Johnston
54500339a1c2SMark Johnston case XMMX2I:
54510339a1c2SMark Johnston FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
54520339a1c2SMark Johnston 1);
54530339a1c2SMark Johnston NOMEM;
54540339a1c2SMark Johnston break;
54550339a1c2SMark Johnston
54560339a1c2SMark Johnston case XMM2I:
54570339a1c2SMark Johnston ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
54580339a1c2SMark Johnston NOMEM;
54590339a1c2SMark Johnston break;
54600339a1c2SMark Johnston
54610339a1c2SMark Johnston /* immediate operand to accumulator */
54620339a1c2SMark Johnston case IA:
54630339a1c2SMark Johnston wbit = WBIT(opcode2);
54640339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
54650339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
54660339a1c2SMark Johnston NOMEM;
54670339a1c2SMark Johnston break;
54680339a1c2SMark Johnston
54690339a1c2SMark Johnston /* memory or register operand to accumulator */
54700339a1c2SMark Johnston case MA:
54710339a1c2SMark Johnston wbit = WBIT(opcode2);
54720339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
54730339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
54740339a1c2SMark Johnston break;
54750339a1c2SMark Johnston
54760339a1c2SMark Johnston /* si register to di register used to reference memory */
54770339a1c2SMark Johnston case SD:
54780339a1c2SMark Johnston #ifdef DIS_TEXT
54790339a1c2SMark Johnston dtrace_check_override(x, 0);
54800339a1c2SMark Johnston x->d86_numopnds = 2;
54810339a1c2SMark Johnston if (addr_size == SIZE64) {
54820339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
54830339a1c2SMark Johnston OPLEN);
54840339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
54850339a1c2SMark Johnston OPLEN);
54860339a1c2SMark Johnston } else if (addr_size == SIZE32) {
54870339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
54880339a1c2SMark Johnston OPLEN);
54890339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
54900339a1c2SMark Johnston OPLEN);
54910339a1c2SMark Johnston } else {
54920339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
54930339a1c2SMark Johnston OPLEN);
54940339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
54950339a1c2SMark Johnston OPLEN);
54960339a1c2SMark Johnston }
54970339a1c2SMark Johnston #endif
54980339a1c2SMark Johnston wbit = LONG_OPND;
54990339a1c2SMark Johnston break;
55000339a1c2SMark Johnston
55010339a1c2SMark Johnston /* accumulator to di register */
55020339a1c2SMark Johnston case AD:
55030339a1c2SMark Johnston wbit = WBIT(opcode2);
55040339a1c2SMark Johnston #ifdef DIS_TEXT
55050339a1c2SMark Johnston dtrace_check_override(x, 1);
55060339a1c2SMark Johnston x->d86_numopnds = 2;
55070339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
55080339a1c2SMark Johnston if (addr_size == SIZE64)
55090339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
55100339a1c2SMark Johnston OPLEN);
55110339a1c2SMark Johnston else if (addr_size == SIZE32)
55120339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
55130339a1c2SMark Johnston OPLEN);
55140339a1c2SMark Johnston else
55150339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
55160339a1c2SMark Johnston OPLEN);
55170339a1c2SMark Johnston #endif
55180339a1c2SMark Johnston break;
55190339a1c2SMark Johnston
55200339a1c2SMark Johnston /* si register to accumulator */
55210339a1c2SMark Johnston case SA:
55220339a1c2SMark Johnston wbit = WBIT(opcode2);
55230339a1c2SMark Johnston #ifdef DIS_TEXT
55240339a1c2SMark Johnston dtrace_check_override(x, 0);
55250339a1c2SMark Johnston x->d86_numopnds = 2;
55260339a1c2SMark Johnston if (addr_size == SIZE64)
55270339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
55280339a1c2SMark Johnston OPLEN);
55290339a1c2SMark Johnston else if (addr_size == SIZE32)
55300339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
55310339a1c2SMark Johnston OPLEN);
55320339a1c2SMark Johnston else
55330339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
55340339a1c2SMark Johnston OPLEN);
55350339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
55360339a1c2SMark Johnston #endif
55370339a1c2SMark Johnston break;
55380339a1c2SMark Johnston
55390339a1c2SMark Johnston /*
55400339a1c2SMark Johnston * single operand, a 16/32 bit displacement
55410339a1c2SMark Johnston */
55420339a1c2SMark Johnston case D:
55430339a1c2SMark Johnston wbit = LONG_OPND;
55440339a1c2SMark Johnston dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
55450339a1c2SMark Johnston NOMEM;
55460339a1c2SMark Johnston break;
55470339a1c2SMark Johnston
55480339a1c2SMark Johnston /* jmp/call indirect to memory or register operand */
55490339a1c2SMark Johnston case INM:
55500339a1c2SMark Johnston #ifdef DIS_TEXT
55510339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
55520339a1c2SMark Johnston #endif
55530339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
55540339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
55550339a1c2SMark Johnston wbit = LONG_OPND;
55560339a1c2SMark Johnston break;
55570339a1c2SMark Johnston
55580339a1c2SMark Johnston /*
55590339a1c2SMark Johnston * for long jumps and long calls -- a new code segment
55600339a1c2SMark Johnston * register and an offset in IP -- stored in object
55610339a1c2SMark Johnston * code in reverse order. Note - not valid in amd64
55620339a1c2SMark Johnston */
55630339a1c2SMark Johnston case SO:
55640339a1c2SMark Johnston dtrace_check_override(x, 1);
55650339a1c2SMark Johnston wbit = LONG_OPND;
55660339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
55670339a1c2SMark Johnston #ifdef DIS_TEXT
55680339a1c2SMark Johnston x->d86_opnd[1].d86_mode = MODE_SIGNED;
55690339a1c2SMark Johnston #endif
55700339a1c2SMark Johnston /* will now get segment operand */
55710339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 2, 0);
55720339a1c2SMark Johnston break;
55730339a1c2SMark Johnston
55740339a1c2SMark Johnston /*
55750339a1c2SMark Johnston * jmp/call. single operand, 8 bit displacement.
55760339a1c2SMark Johnston * added to current EIP in 'compofff'
55770339a1c2SMark Johnston */
55780339a1c2SMark Johnston case BD:
55790339a1c2SMark Johnston dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
55800339a1c2SMark Johnston NOMEM;
55810339a1c2SMark Johnston break;
55820339a1c2SMark Johnston
55830339a1c2SMark Johnston /* single 32/16 bit immediate operand */
55840339a1c2SMark Johnston case I:
55850339a1c2SMark Johnston wbit = LONG_OPND;
55860339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
55870339a1c2SMark Johnston break;
55880339a1c2SMark Johnston
55890339a1c2SMark Johnston /* single 8 bit immediate operand */
55900339a1c2SMark Johnston case Ib:
55910339a1c2SMark Johnston wbit = LONG_OPND;
55920339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
55930339a1c2SMark Johnston break;
55940339a1c2SMark Johnston
55950339a1c2SMark Johnston case ENTER:
55960339a1c2SMark Johnston wbit = LONG_OPND;
55970339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 2, 0);
55980339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 1);
55990339a1c2SMark Johnston switch (opnd_size) {
56000339a1c2SMark Johnston case SIZE64:
56010339a1c2SMark Johnston x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
56020339a1c2SMark Johnston break;
56030339a1c2SMark Johnston case SIZE32:
56040339a1c2SMark Johnston x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
56050339a1c2SMark Johnston break;
56060339a1c2SMark Johnston case SIZE16:
56070339a1c2SMark Johnston x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
56080339a1c2SMark Johnston break;
56090339a1c2SMark Johnston }
56100339a1c2SMark Johnston
56110339a1c2SMark Johnston break;
56120339a1c2SMark Johnston
56130339a1c2SMark Johnston /* 16-bit immediate operand */
56140339a1c2SMark Johnston case RET:
56150339a1c2SMark Johnston wbit = LONG_OPND;
56160339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 2, 0);
56170339a1c2SMark Johnston break;
56180339a1c2SMark Johnston
56190339a1c2SMark Johnston /* single 8 bit port operand */
56200339a1c2SMark Johnston case P:
56210339a1c2SMark Johnston dtrace_check_override(x, 0);
56220339a1c2SMark Johnston dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
56230339a1c2SMark Johnston NOMEM;
56240339a1c2SMark Johnston break;
56250339a1c2SMark Johnston
56260339a1c2SMark Johnston /* single operand, dx register (variable port instruction) */
56270339a1c2SMark Johnston case V:
56280339a1c2SMark Johnston x->d86_numopnds = 1;
56290339a1c2SMark Johnston dtrace_check_override(x, 0);
56300339a1c2SMark Johnston #ifdef DIS_TEXT
56310339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
56320339a1c2SMark Johnston #endif
56330339a1c2SMark Johnston NOMEM;
56340339a1c2SMark Johnston break;
56350339a1c2SMark Johnston
56360339a1c2SMark Johnston /*
56370339a1c2SMark Johnston * The int instruction, which has two forms:
56380339a1c2SMark Johnston * int 3 (breakpoint) or
56390339a1c2SMark Johnston * int n, where n is indicated in the subsequent
56400339a1c2SMark Johnston * byte (format Ib). The int 3 instruction (opcode 0xCC),
56410339a1c2SMark Johnston * where, although the 3 looks like an operand,
56420339a1c2SMark Johnston * it is implied by the opcode. It must be converted
56430339a1c2SMark Johnston * to the correct base and output.
56440339a1c2SMark Johnston */
56450339a1c2SMark Johnston case INT3:
56460339a1c2SMark Johnston #ifdef DIS_TEXT
56470339a1c2SMark Johnston x->d86_numopnds = 1;
56480339a1c2SMark Johnston x->d86_opnd[0].d86_mode = MODE_SIGNED;
56490339a1c2SMark Johnston x->d86_opnd[0].d86_value_size = 1;
56500339a1c2SMark Johnston x->d86_opnd[0].d86_value = 3;
56510339a1c2SMark Johnston #endif
56520339a1c2SMark Johnston NOMEM;
56530339a1c2SMark Johnston break;
56540339a1c2SMark Johnston
56550339a1c2SMark Johnston /* single 8 bit immediate operand */
56560339a1c2SMark Johnston case INTx:
56570339a1c2SMark Johnston dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
56580339a1c2SMark Johnston NOMEM;
56590339a1c2SMark Johnston break;
56600339a1c2SMark Johnston
56610339a1c2SMark Johnston /* an unused byte must be discarded */
56620339a1c2SMark Johnston case U:
56630339a1c2SMark Johnston if (x->d86_get_byte(x->d86_data) < 0)
56640339a1c2SMark Johnston goto error;
56650339a1c2SMark Johnston x->d86_len++;
56660339a1c2SMark Johnston NOMEM;
56670339a1c2SMark Johnston break;
56680339a1c2SMark Johnston
56690339a1c2SMark Johnston case CBW:
56700339a1c2SMark Johnston #ifdef DIS_TEXT
56710339a1c2SMark Johnston if (opnd_size == SIZE16)
56720339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cbtw", OPLEN);
56730339a1c2SMark Johnston else if (opnd_size == SIZE32)
56740339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cwtl", OPLEN);
56750339a1c2SMark Johnston else
56760339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cltq", OPLEN);
56770339a1c2SMark Johnston #endif
56780339a1c2SMark Johnston wbit = LONG_OPND;
56790339a1c2SMark Johnston NOMEM;
56800339a1c2SMark Johnston break;
56810339a1c2SMark Johnston
56820339a1c2SMark Johnston case CWD:
56830339a1c2SMark Johnston #ifdef DIS_TEXT
56840339a1c2SMark Johnston if (opnd_size == SIZE16)
56850339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cwtd", OPLEN);
56860339a1c2SMark Johnston else if (opnd_size == SIZE32)
56870339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cltd", OPLEN);
56880339a1c2SMark Johnston else
56890339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "cqtd", OPLEN);
56900339a1c2SMark Johnston #endif
56910339a1c2SMark Johnston wbit = LONG_OPND;
56920339a1c2SMark Johnston NOMEM;
56930339a1c2SMark Johnston break;
56940339a1c2SMark Johnston
56950339a1c2SMark Johnston case XMMSFNC:
56960339a1c2SMark Johnston /*
56970339a1c2SMark Johnston * sfence is sfence if mode is REG_ONLY. If mode isn't
56980339a1c2SMark Johnston * REG_ONLY, mnemonic should be 'clflush'.
56990339a1c2SMark Johnston */
57000339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
57010339a1c2SMark Johnston
57020339a1c2SMark Johnston /* sfence doesn't take operands */
5703722b2e2fSMark Johnston if (mode != REG_ONLY) {
5704722b2e2fSMark Johnston if (opnd_size_prefix == 0x66) {
57050339a1c2SMark Johnston #ifdef DIS_TEXT
5706722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "clflushopt",
5707722b2e2fSMark Johnston OPLEN);
5708722b2e2fSMark Johnston #endif
5709722b2e2fSMark Johnston } else if (opnd_size_prefix == 0) {
5710722b2e2fSMark Johnston #ifdef DIS_TEXT
57110339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "clflush", OPLEN);
5712722b2e2fSMark Johnston #endif
5713722b2e2fSMark Johnston } else {
5714722b2e2fSMark Johnston /* Unknown instruction */
5715722b2e2fSMark Johnston goto error;
5716722b2e2fSMark Johnston }
5717722b2e2fSMark Johnston
57180339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
57190339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
57200339a1c2SMark Johnston NOMEM;
5721722b2e2fSMark Johnston #ifdef DIS_TEXT
5722722b2e2fSMark Johnston } else {
5723722b2e2fSMark Johnston (void) strlcat(x->d86_mnem, "sfence", OPLEN);
5724722b2e2fSMark Johnston #endif
57250339a1c2SMark Johnston }
5726722b2e2fSMark Johnston break;
5727722b2e2fSMark Johnston
5728722b2e2fSMark Johnston case FSGS:
5729722b2e2fSMark Johnston /*
5730722b2e2fSMark Johnston * The FSGSBASE instructions are taken only when the mode is set
5731722b2e2fSMark Johnston * to registers. They share opcodes with instructions like
5732722b2e2fSMark Johnston * fxrstor, stmxcsr, etc. We handle the repz prefix earlier.
5733722b2e2fSMark Johnston */
5734722b2e2fSMark Johnston wbit = WBIT(opcode2);
5735722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
5736722b2e2fSMark Johnston dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
5737722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
5738722b2e2fSMark Johnston if (mode == REG_ONLY) {
57390339a1c2SMark Johnston NOMEM;
57400339a1c2SMark Johnston }
57410339a1c2SMark Johnston break;
57420339a1c2SMark Johnston
57430339a1c2SMark Johnston /*
57440339a1c2SMark Johnston * no disassembly, the mnemonic was all there was so go on
57450339a1c2SMark Johnston */
57460339a1c2SMark Johnston case NORM:
57470339a1c2SMark Johnston if (dp->it_invalid32 && cpu_mode != SIZE64)
57480339a1c2SMark Johnston goto error;
57490339a1c2SMark Johnston NOMEM;
57500339a1c2SMark Johnston /*FALLTHROUGH*/
57510339a1c2SMark Johnston case IMPLMEM:
57520339a1c2SMark Johnston break;
57530339a1c2SMark Johnston
57540339a1c2SMark Johnston case XMMFENCE:
57550339a1c2SMark Johnston /*
5756722b2e2fSMark Johnston * XRSTOR, XSAVEOPT and LFENCE share the same opcode but
5757722b2e2fSMark Johnston * differ in mode and reg.
57580339a1c2SMark Johnston */
57590339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
57600339a1c2SMark Johnston
57610339a1c2SMark Johnston if (mode == REG_ONLY) {
57620339a1c2SMark Johnston /*
57630339a1c2SMark Johnston * Only the following exact byte sequences are allowed:
57640339a1c2SMark Johnston *
57650339a1c2SMark Johnston * 0f ae e8 lfence
57660339a1c2SMark Johnston * 0f ae f0 mfence
57670339a1c2SMark Johnston */
57680339a1c2SMark Johnston if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
57690339a1c2SMark Johnston (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
57700339a1c2SMark Johnston goto error;
57710339a1c2SMark Johnston } else {
57720339a1c2SMark Johnston #ifdef DIS_TEXT
5773722b2e2fSMark Johnston if (reg == 5) {
57740339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "xrstor", OPLEN);
5775722b2e2fSMark Johnston } else if (reg == 6) {
5776722b2e2fSMark Johnston if (opnd_size_prefix == 0x66) {
5777722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "clwb",
5778722b2e2fSMark Johnston OPLEN);
5779722b2e2fSMark Johnston } else if (opnd_size_prefix == 0x00) {
5780722b2e2fSMark Johnston (void) strncpy(x->d86_mnem, "xsaveopt",
5781722b2e2fSMark Johnston OPLEN);
5782722b2e2fSMark Johnston } else {
5783722b2e2fSMark Johnston goto error;
5784722b2e2fSMark Johnston }
5785722b2e2fSMark Johnston } else {
5786722b2e2fSMark Johnston goto error;
5787722b2e2fSMark Johnston }
57880339a1c2SMark Johnston #endif
57890339a1c2SMark Johnston dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);
57900339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
5791*418d8f0dSMark Johnston wbit = LONG_OPND;
57920339a1c2SMark Johnston }
57930339a1c2SMark Johnston break;
57940339a1c2SMark Johnston
57950339a1c2SMark Johnston /* float reg */
57960339a1c2SMark Johnston case F:
57970339a1c2SMark Johnston #ifdef DIS_TEXT
57980339a1c2SMark Johnston x->d86_numopnds = 1;
57990339a1c2SMark Johnston (void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
58000339a1c2SMark Johnston x->d86_opnd[0].d86_opnd[4] = r_m + '0';
58010339a1c2SMark Johnston #endif
58020339a1c2SMark Johnston NOMEM;
58030339a1c2SMark Johnston break;
58040339a1c2SMark Johnston
58050339a1c2SMark Johnston /* float reg to float reg, with ret bit present */
58060339a1c2SMark Johnston case FF:
58070339a1c2SMark Johnston vbit = opcode2 >> 2 & 0x1; /* vbit = 1: st -> st(i) */
58080339a1c2SMark Johnston /*FALLTHROUGH*/
58090339a1c2SMark Johnston case FFC: /* case for vbit always = 0 */
58100339a1c2SMark Johnston #ifdef DIS_TEXT
58110339a1c2SMark Johnston x->d86_numopnds = 2;
58120339a1c2SMark Johnston (void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
58130339a1c2SMark Johnston (void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
58140339a1c2SMark Johnston x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
58150339a1c2SMark Johnston #endif
58160339a1c2SMark Johnston NOMEM;
58170339a1c2SMark Johnston break;
58180339a1c2SMark Johnston
58190339a1c2SMark Johnston /* AVX instructions */
58200339a1c2SMark Johnston case VEX_MO:
58210339a1c2SMark Johnston /* op(ModR/M.r/m) */
58220339a1c2SMark Johnston x->d86_numopnds = 1;
58230339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
58240339a1c2SMark Johnston #ifdef DIS_TEXT
58250339a1c2SMark Johnston if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
58260339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
58270339a1c2SMark Johnston #endif
58280339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
58290339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
58300339a1c2SMark Johnston break;
58310339a1c2SMark Johnston case VEX_RMrX:
5832b3b5bfebSMark Johnston case FMA:
58330339a1c2SMark Johnston /* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
58340339a1c2SMark Johnston x->d86_numopnds = 3;
58350339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
58360339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
58370339a1c2SMark Johnston
5838b3b5bfebSMark Johnston /*
5839b3b5bfebSMark Johnston * In classic Intel fashion, the opcodes for all of the FMA
5840b3b5bfebSMark Johnston * instructions all have two possible mnemonics which vary by
5841b3b5bfebSMark Johnston * one letter, which is selected based on the value of the wbit.
5842b3b5bfebSMark Johnston * When wbit is one, they have the 'd' suffix and when 'wbit' is
5843b3b5bfebSMark Johnston * 0, they have the 's' suffix. Otherwise, the FMA instructions
5844b3b5bfebSMark Johnston * are all a standard VEX_RMrX.
5845b3b5bfebSMark Johnston */
5846b3b5bfebSMark Johnston #ifdef DIS_TEXT
5847b3b5bfebSMark Johnston if (dp->it_adrmode == FMA) {
5848b3b5bfebSMark Johnston size_t len = strlen(dp->it_name);
5849b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
5850b3b5bfebSMark Johnston if (len + 1 < OPLEN) {
5851b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem + len,
5852b3b5bfebSMark Johnston vex_W != 0 ? "d" : "s", OPLEN - len);
5853b3b5bfebSMark Johnston }
5854b3b5bfebSMark Johnston }
5855b3b5bfebSMark Johnston #endif
5856b3b5bfebSMark Johnston
58570339a1c2SMark Johnston if (mode != REG_ONLY) {
58580339a1c2SMark Johnston if ((dp == &dis_opAVXF20F[0x10]) ||
58590339a1c2SMark Johnston (dp == &dis_opAVXF30F[0x10])) {
58600339a1c2SMark Johnston /* vmovsd <m64>, <xmm> */
58610339a1c2SMark Johnston /* or vmovss <m64>, <xmm> */
58620339a1c2SMark Johnston x->d86_numopnds = 2;
58630339a1c2SMark Johnston goto L_VEX_MX;
58640339a1c2SMark Johnston }
58650339a1c2SMark Johnston }
58660339a1c2SMark Johnston
58670339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
58680339a1c2SMark Johnston /*
58690339a1c2SMark Johnston * VEX prefix uses the 1's complement form to encode the
58700339a1c2SMark Johnston * XMM/YMM regs
58710339a1c2SMark Johnston */
58720339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
58730339a1c2SMark Johnston
58740339a1c2SMark Johnston if ((dp == &dis_opAVXF20F[0x2A]) ||
58750339a1c2SMark Johnston (dp == &dis_opAVXF30F[0x2A])) {
58760339a1c2SMark Johnston /*
58770339a1c2SMark Johnston * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
58780339a1c2SMark Johnston * <xmm>, <xmm>
58790339a1c2SMark Johnston */
58800339a1c2SMark Johnston wbit = LONG_OPND;
58810339a1c2SMark Johnston }
58820339a1c2SMark Johnston #ifdef DIS_TEXT
58830339a1c2SMark Johnston else if ((mode == REG_ONLY) &&
58840339a1c2SMark Johnston (dp == &dis_opAVX0F[0x1][0x6])) { /* vmovlhps */
58850339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
58860339a1c2SMark Johnston } else if ((mode == REG_ONLY) &&
58870339a1c2SMark Johnston (dp == &dis_opAVX0F[0x1][0x2])) { /* vmovhlps */
58880339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
58890339a1c2SMark Johnston }
58900339a1c2SMark Johnston #endif
58910339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
58920339a1c2SMark Johnston
58930339a1c2SMark Johnston break;
58940339a1c2SMark Johnston
5895b3b5bfebSMark Johnston case VEX_VRMrX:
5896b3b5bfebSMark Johnston /* ModR/M.reg := op(MODR/M.r/m, VEX.vvvv) */
5897b3b5bfebSMark Johnston x->d86_numopnds = 3;
5898b3b5bfebSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
5899b3b5bfebSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
5900b3b5bfebSMark Johnston
5901b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
5902b3b5bfebSMark Johnston /*
5903b3b5bfebSMark Johnston * VEX prefix uses the 1's complement form to encode the
5904b3b5bfebSMark Johnston * XMM/YMM regs
5905b3b5bfebSMark Johnston */
5906b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 0);
5907b3b5bfebSMark Johnston
5908b3b5bfebSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
5909b3b5bfebSMark Johnston break;
5910b3b5bfebSMark Johnston
5911b3b5bfebSMark Johnston case VEX_SbVM:
5912b3b5bfebSMark Johnston /* ModR/M.reg := op(MODR/M.r/m, VSIB, VEX.vvvv) */
5913b3b5bfebSMark Johnston x->d86_numopnds = 3;
5914b3b5bfebSMark Johnston x->d86_vsib = 1;
5915b3b5bfebSMark Johnston
5916b3b5bfebSMark Johnston /*
5917b3b5bfebSMark Johnston * All instructions that use VSIB are currently a mess. See the
5918b3b5bfebSMark Johnston * comment around the dis_gather_regs_t structure definition.
5919b3b5bfebSMark Johnston */
5920b3b5bfebSMark Johnston
5921b3b5bfebSMark Johnston vreg = &dis_vgather[opcode2][vex_W][vex_L];
5922b3b5bfebSMark Johnston
5923b3b5bfebSMark Johnston #ifdef DIS_TEXT
5924b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
5925b3b5bfebSMark Johnston (void) strlcat(x->d86_mnem + strlen(dp->it_name),
5926b3b5bfebSMark Johnston vreg->dgr_suffix, OPLEN - strlen(dp->it_name));
5927b3b5bfebSMark Johnston #endif
5928b3b5bfebSMark Johnston
5929b3b5bfebSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
5930b3b5bfebSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
5931b3b5bfebSMark Johnston
5932b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, vreg->dgr_arg2, 2);
5933b3b5bfebSMark Johnston /*
5934b3b5bfebSMark Johnston * VEX prefix uses the 1's complement form to encode the
5935b3b5bfebSMark Johnston * XMM/YMM regs
5936b3b5bfebSMark Johnston */
5937b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), vreg->dgr_arg0,
5938b3b5bfebSMark Johnston 0);
5939b3b5bfebSMark Johnston dtrace_get_operand(x, mode, r_m, vreg->dgr_arg1, 1);
5940b3b5bfebSMark Johnston break;
5941b3b5bfebSMark Johnston
59420339a1c2SMark Johnston case VEX_RRX:
59430339a1c2SMark Johnston /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
59440339a1c2SMark Johnston x->d86_numopnds = 3;
59450339a1c2SMark Johnston
59460339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
59470339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
59480339a1c2SMark Johnston
59490339a1c2SMark Johnston if (mode != REG_ONLY) {
59500339a1c2SMark Johnston if ((dp == &dis_opAVXF20F[0x11]) ||
59510339a1c2SMark Johnston (dp == &dis_opAVXF30F[0x11])) {
59520339a1c2SMark Johnston /* vmovsd <xmm>, <m64> */
59530339a1c2SMark Johnston /* or vmovss <xmm>, <m64> */
59540339a1c2SMark Johnston x->d86_numopnds = 2;
59550339a1c2SMark Johnston goto L_VEX_RM;
59560339a1c2SMark Johnston }
59570339a1c2SMark Johnston }
59580339a1c2SMark Johnston
59590339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2);
59600339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
59610339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
59620339a1c2SMark Johnston break;
59630339a1c2SMark Johnston
59640339a1c2SMark Johnston case VEX_RMRX:
59650339a1c2SMark Johnston /* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
59660339a1c2SMark Johnston x->d86_numopnds = 4;
59670339a1c2SMark Johnston
59680339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
59690339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
59700339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
59710339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
59720339a1c2SMark Johnston if (dp == &dis_opAVX660F3A[0x18]) {
59730339a1c2SMark Johnston /* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
59740339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
59750339a1c2SMark Johnston } else if ((dp == &dis_opAVX660F3A[0x20]) ||
59760339a1c2SMark Johnston (dp == & dis_opAVX660F[0xC4])) {
59770339a1c2SMark Johnston /* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
59780339a1c2SMark Johnston /* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
59790339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
59800339a1c2SMark Johnston } else if (dp == &dis_opAVX660F3A[0x22]) {
59810339a1c2SMark Johnston /* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
59820339a1c2SMark Johnston #ifdef DIS_TEXT
59830339a1c2SMark Johnston if (vex_W)
59840339a1c2SMark Johnston x->d86_mnem[6] = 'q';
59850339a1c2SMark Johnston #endif
59860339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
59870339a1c2SMark Johnston } else {
59880339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
59890339a1c2SMark Johnston }
59900339a1c2SMark Johnston
59910339a1c2SMark Johnston /* one byte immediate number */
59920339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
59930339a1c2SMark Johnston
59940339a1c2SMark Johnston /* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
59950339a1c2SMark Johnston if ((dp == &dis_opAVX660F3A[0x4A]) ||
59960339a1c2SMark Johnston (dp == &dis_opAVX660F3A[0x4B]) ||
59970339a1c2SMark Johnston (dp == &dis_opAVX660F3A[0x4C])) {
59980339a1c2SMark Johnston #ifdef DIS_TEXT
59990339a1c2SMark Johnston int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
60000339a1c2SMark Johnston #endif
60010339a1c2SMark Johnston x->d86_opnd[0].d86_mode = MODE_NONE;
60020339a1c2SMark Johnston #ifdef DIS_TEXT
60030339a1c2SMark Johnston if (vex_L)
60040339a1c2SMark Johnston (void) strncpy(x->d86_opnd[0].d86_opnd,
60050339a1c2SMark Johnston dis_YMMREG[regnum], OPLEN);
60060339a1c2SMark Johnston else
60070339a1c2SMark Johnston (void) strncpy(x->d86_opnd[0].d86_opnd,
60080339a1c2SMark Johnston dis_XMMREG[regnum], OPLEN);
60090339a1c2SMark Johnston #endif
60100339a1c2SMark Johnston }
60110339a1c2SMark Johnston break;
60120339a1c2SMark Johnston
60130339a1c2SMark Johnston case VEX_MX:
60140339a1c2SMark Johnston /* ModR/M.reg := op(ModR/M.rm) */
60150339a1c2SMark Johnston x->d86_numopnds = 2;
60160339a1c2SMark Johnston
60170339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
60180339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
60190339a1c2SMark Johnston L_VEX_MX:
60200339a1c2SMark Johnston
60210339a1c2SMark Johnston if ((dp == &dis_opAVXF20F[0xE6]) ||
60220339a1c2SMark Johnston (dp == &dis_opAVX660F[0x5A]) ||
60230339a1c2SMark Johnston (dp == &dis_opAVX660F[0xE6])) {
60240339a1c2SMark Johnston /* vcvtpd2dq <ymm>, <xmm> */
60250339a1c2SMark Johnston /* or vcvtpd2ps <ymm>, <xmm> */
60260339a1c2SMark Johnston /* or vcvttpd2dq <ymm>, <xmm> */
60270339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
60280339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
60290339a1c2SMark Johnston } else if ((dp == &dis_opAVXF30F[0xE6]) ||
6030c3ddb60eSPeter Grehan (dp == &dis_opAVX0F[0x5][0xA]) ||
6031b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x13]) ||
6032b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x18]) ||
6033b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x19]) ||
6034b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x58]) ||
6035b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x78]) ||
6036b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x79]) ||
6037b3b5bfebSMark Johnston (dp == &dis_opAVX660F38[0x59])) {
60380339a1c2SMark Johnston /* vcvtdq2pd <xmm>, <ymm> */
60390339a1c2SMark Johnston /* or vcvtps2pd <xmm>, <ymm> */
6040b3b5bfebSMark Johnston /* or vcvtph2ps <xmm>, <ymm> */
6041b3b5bfebSMark Johnston /* or vbroadcasts* <xmm>, <ymm> */
60420339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
60430339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
60440339a1c2SMark Johnston } else if (dp == &dis_opAVX660F[0x6E]) {
60450339a1c2SMark Johnston /* vmovd/q <reg/mem 32/64>, <xmm> */
60460339a1c2SMark Johnston #ifdef DIS_TEXT
60470339a1c2SMark Johnston if (vex_W)
60480339a1c2SMark Johnston x->d86_mnem[4] = 'q';
60490339a1c2SMark Johnston #endif
60500339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
60510339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
60520339a1c2SMark Johnston } else {
60530339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
60540339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
60550339a1c2SMark Johnston }
60560339a1c2SMark Johnston
60570339a1c2SMark Johnston break;
60580339a1c2SMark Johnston
60590339a1c2SMark Johnston case VEX_MXI:
60600339a1c2SMark Johnston /* ModR/M.reg := op(ModR/M.rm, imm8) */
60610339a1c2SMark Johnston x->d86_numopnds = 3;
60620339a1c2SMark Johnston
60630339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
60640339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
60650339a1c2SMark Johnston
60660339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
60670339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
60680339a1c2SMark Johnston
60690339a1c2SMark Johnston /* one byte immediate number */
60700339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
60710339a1c2SMark Johnston break;
60720339a1c2SMark Johnston
60730339a1c2SMark Johnston case VEX_XXI:
60740339a1c2SMark Johnston /* VEX.vvvv := op(ModR/M.rm, imm8) */
60750339a1c2SMark Johnston x->d86_numopnds = 3;
60760339a1c2SMark Johnston
60770339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
60780339a1c2SMark Johnston #ifdef DIS_TEXT
60790339a1c2SMark Johnston (void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
60800339a1c2SMark Johnston OPLEN);
60810339a1c2SMark Johnston #endif
60820339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
60830339a1c2SMark Johnston
60840339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
60850339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
60860339a1c2SMark Johnston
60870339a1c2SMark Johnston /* one byte immediate number */
60880339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
60890339a1c2SMark Johnston break;
60900339a1c2SMark Johnston
60910339a1c2SMark Johnston case VEX_MR:
60920339a1c2SMark Johnston /* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
60930339a1c2SMark Johnston if (dp == &dis_opAVX660F[0xC5]) {
60940339a1c2SMark Johnston /* vpextrw <imm8>, <xmm>, <reg> */
60950339a1c2SMark Johnston x->d86_numopnds = 2;
60960339a1c2SMark Johnston vbit = 2;
60970339a1c2SMark Johnston } else {
60980339a1c2SMark Johnston x->d86_numopnds = 2;
60990339a1c2SMark Johnston vbit = 1;
61000339a1c2SMark Johnston }
61010339a1c2SMark Johnston
61020339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
61030339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
61040339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
61050339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
61060339a1c2SMark Johnston
61070339a1c2SMark Johnston if (vbit == 2)
61080339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
61090339a1c2SMark Johnston
61100339a1c2SMark Johnston break;
61110339a1c2SMark Johnston
6112722b2e2fSMark Johnston case VEX_KMR:
6113722b2e2fSMark Johnston /* opmask: mod_rm := %k */
6114722b2e2fSMark Johnston x->d86_numopnds = 2;
6115722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6116722b2e2fSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
6117722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
6118722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
6119722b2e2fSMark Johnston break;
6120722b2e2fSMark Johnston
6121722b2e2fSMark Johnston case VEX_KRM:
6122722b2e2fSMark Johnston /* opmask: mod_reg := mod_rm */
6123722b2e2fSMark Johnston x->d86_numopnds = 2;
6124722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6125722b2e2fSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
6126722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
6127722b2e2fSMark Johnston if (mode == REG_ONLY) {
6128722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, KOPMASK_OPND, 0);
6129722b2e2fSMark Johnston } else {
6130722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
6131722b2e2fSMark Johnston }
6132722b2e2fSMark Johnston break;
6133722b2e2fSMark Johnston
6134722b2e2fSMark Johnston case VEX_KRR:
6135722b2e2fSMark Johnston /* opmask: mod_reg := mod_rm */
6136722b2e2fSMark Johnston x->d86_numopnds = 2;
6137722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6138722b2e2fSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
6139722b2e2fSMark Johnston dtrace_get_operand(x, mode, reg, wbit, 1);
6140722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 0);
6141722b2e2fSMark Johnston break;
6142722b2e2fSMark Johnston
61430339a1c2SMark Johnston case VEX_RRI:
61440339a1c2SMark Johnston /* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
61450339a1c2SMark Johnston x->d86_numopnds = 2;
61460339a1c2SMark Johnston
61470339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
61480339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
61490339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
61500339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
61510339a1c2SMark Johnston break;
61520339a1c2SMark Johnston
61530339a1c2SMark Johnston case VEX_RX:
61540339a1c2SMark Johnston /* ModR/M.rm := op(ModR/M.reg) */
6155c3ddb60eSPeter Grehan /* vextractf128 || vcvtps2ph */
6156c3ddb60eSPeter Grehan if (dp == &dis_opAVX660F3A[0x19] ||
6157c3ddb60eSPeter Grehan dp == &dis_opAVX660F3A[0x1d]) {
61580339a1c2SMark Johnston x->d86_numopnds = 3;
61590339a1c2SMark Johnston
61600339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
61610339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
61620339a1c2SMark Johnston
61630339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
61640339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
61650339a1c2SMark Johnston
61660339a1c2SMark Johnston /* one byte immediate number */
61670339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
61680339a1c2SMark Johnston break;
61690339a1c2SMark Johnston }
61700339a1c2SMark Johnston
61710339a1c2SMark Johnston x->d86_numopnds = 2;
61720339a1c2SMark Johnston
61730339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
61740339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
61750339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
61760339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
61770339a1c2SMark Johnston break;
61780339a1c2SMark Johnston
61790339a1c2SMark Johnston case VEX_RR:
61800339a1c2SMark Johnston /* ModR/M.rm := op(ModR/M.reg) */
61810339a1c2SMark Johnston x->d86_numopnds = 2;
61820339a1c2SMark Johnston
61830339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
61840339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
61850339a1c2SMark Johnston
61860339a1c2SMark Johnston if (dp == &dis_opAVX660F[0x7E]) {
61870339a1c2SMark Johnston /* vmovd/q <reg/mem 32/64>, <xmm> */
61880339a1c2SMark Johnston #ifdef DIS_TEXT
61890339a1c2SMark Johnston if (vex_W)
61900339a1c2SMark Johnston x->d86_mnem[4] = 'q';
61910339a1c2SMark Johnston #endif
61920339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
61930339a1c2SMark Johnston } else
61940339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
61950339a1c2SMark Johnston
61960339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
61970339a1c2SMark Johnston break;
61980339a1c2SMark Johnston
61990339a1c2SMark Johnston case VEX_RRi:
62000339a1c2SMark Johnston /* ModR/M.rm := op(ModR/M.reg, imm) */
62010339a1c2SMark Johnston x->d86_numopnds = 3;
62020339a1c2SMark Johnston
62030339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
62040339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
62050339a1c2SMark Johnston
62060339a1c2SMark Johnston #ifdef DIS_TEXT
62070339a1c2SMark Johnston if (dp == &dis_opAVX660F3A[0x16]) {
62080339a1c2SMark Johnston /* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
62090339a1c2SMark Johnston if (vex_W)
62100339a1c2SMark Johnston x->d86_mnem[6] = 'q';
62110339a1c2SMark Johnston }
62120339a1c2SMark Johnston #endif
62130339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
62140339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
62150339a1c2SMark Johnston
62160339a1c2SMark Johnston /* one byte immediate number */
62170339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
62180339a1c2SMark Johnston break;
6219b3b5bfebSMark Johnston case VEX_RIM:
6220b3b5bfebSMark Johnston /* ModR/M.rm := op(ModR/M.reg, imm) */
6221b3b5bfebSMark Johnston x->d86_numopnds = 3;
6222b3b5bfebSMark Johnston
6223b3b5bfebSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6224b3b5bfebSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
6225b3b5bfebSMark Johnston
6226b3b5bfebSMark Johnston dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
6227b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
6228b3b5bfebSMark Johnston /* one byte immediate number */
6229b3b5bfebSMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
6230b3b5bfebSMark Johnston break;
62310339a1c2SMark Johnston
62320339a1c2SMark Johnston case VEX_RM:
62330339a1c2SMark Johnston /* ModR/M.rm := op(ModR/M.reg) */
62340339a1c2SMark Johnston if (dp == &dis_opAVX660F3A[0x17]) { /* vextractps */
62350339a1c2SMark Johnston x->d86_numopnds = 3;
62360339a1c2SMark Johnston
62370339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
62380339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
62390339a1c2SMark Johnston
62400339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
62410339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
62420339a1c2SMark Johnston /* one byte immediate number */
62430339a1c2SMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
62440339a1c2SMark Johnston break;
62450339a1c2SMark Johnston }
62460339a1c2SMark Johnston x->d86_numopnds = 2;
62470339a1c2SMark Johnston
62480339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
62490339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
62500339a1c2SMark Johnston L_VEX_RM:
62510339a1c2SMark Johnston vbit = 1;
62520339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, vbit);
62530339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
62540339a1c2SMark Johnston
62550339a1c2SMark Johnston break;
62560339a1c2SMark Johnston
62570339a1c2SMark Johnston case VEX_RRM:
62580339a1c2SMark Johnston /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
62590339a1c2SMark Johnston x->d86_numopnds = 3;
62600339a1c2SMark Johnston
62610339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
62620339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
62630339a1c2SMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 2);
62640339a1c2SMark Johnston /* VEX use the 1's complement form encode the XMM/YMM regs */
62650339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
62660339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
62670339a1c2SMark Johnston break;
62680339a1c2SMark Johnston
62690339a1c2SMark Johnston case VEX_RMX:
62700339a1c2SMark Johnston /* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
62710339a1c2SMark Johnston x->d86_numopnds = 3;
62720339a1c2SMark Johnston
62730339a1c2SMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
62740339a1c2SMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
62750339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
62760339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
62770339a1c2SMark Johnston dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
62780339a1c2SMark Johnston break;
62790339a1c2SMark Johnston
62800339a1c2SMark Johnston case VEX_NONE:
62810339a1c2SMark Johnston #ifdef DIS_TEXT
62820339a1c2SMark Johnston if (vex_L)
62830339a1c2SMark Johnston (void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
62840339a1c2SMark Johnston #endif
62850339a1c2SMark Johnston break;
6286b3b5bfebSMark Johnston case BLS: {
6287b3b5bfebSMark Johnston
6288b3b5bfebSMark Johnston /*
6289b3b5bfebSMark Johnston * The BLS instructions are VEX instructions that are based on
6290b3b5bfebSMark Johnston * VEX.0F38.F3; however, they are considered special group 17
6291b3b5bfebSMark Johnston * and like everything else, they use the bits in 3-5 of the
6292b3b5bfebSMark Johnston * MOD R/M to determine the sub instruction. Unlike many others
6293b3b5bfebSMark Johnston * like the VMX instructions, these are valid both for memory
6294b3b5bfebSMark Johnston * and register forms.
6295b3b5bfebSMark Johnston */
6296b3b5bfebSMark Johnston
6297b3b5bfebSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6298b3b5bfebSMark Johnston dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);
6299b3b5bfebSMark Johnston
6300b3b5bfebSMark Johnston switch (reg) {
6301b3b5bfebSMark Johnston case 1:
6302b3b5bfebSMark Johnston #ifdef DIS_TEXT
6303b3b5bfebSMark Johnston blsinstr = "blsr";
6304b3b5bfebSMark Johnston #endif
6305b3b5bfebSMark Johnston break;
6306b3b5bfebSMark Johnston case 2:
6307b3b5bfebSMark Johnston #ifdef DIS_TEXT
6308b3b5bfebSMark Johnston blsinstr = "blsmsk";
6309b3b5bfebSMark Johnston #endif
6310b3b5bfebSMark Johnston break;
6311b3b5bfebSMark Johnston case 3:
6312b3b5bfebSMark Johnston #ifdef DIS_TEXT
6313b3b5bfebSMark Johnston blsinstr = "blsi";
6314b3b5bfebSMark Johnston #endif
6315b3b5bfebSMark Johnston break;
6316b3b5bfebSMark Johnston default:
6317b3b5bfebSMark Johnston goto error;
6318b3b5bfebSMark Johnston }
6319b3b5bfebSMark Johnston
6320b3b5bfebSMark Johnston x->d86_numopnds = 2;
6321b3b5bfebSMark Johnston #ifdef DIS_TEXT
6322b3b5bfebSMark Johnston (void) strncpy(x->d86_mnem, blsinstr, OPLEN);
6323b3b5bfebSMark Johnston #endif
6324b3b5bfebSMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
6325b3b5bfebSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
6326b3b5bfebSMark Johnston break;
6327b3b5bfebSMark Johnston }
6328722b2e2fSMark Johnston case EVEX_MX:
6329722b2e2fSMark Johnston /* ModR/M.reg := op(ModR/M.rm) */
6330722b2e2fSMark Johnston x->d86_numopnds = 2;
6331722b2e2fSMark Johnston dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);
6332722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6333722b2e2fSMark Johnston evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;
6334722b2e2fSMark Johnston dtrace_evex_adjust_reg(evex_byte1, ®);
6335722b2e2fSMark Johnston dtrace_evex_adjust_rm(evex_byte1, &r_m);
6336722b2e2fSMark Johnston dtrace_evex_adjust_reg_name(evex_L, &wbit);
6337722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
6338722b2e2fSMark Johnston dtrace_evex_adjust_z_opmask(x, 1, evex_byte3);
6339722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
6340722b2e2fSMark Johnston dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);
6341722b2e2fSMark Johnston break;
6342722b2e2fSMark Johnston case EVEX_RX:
6343722b2e2fSMark Johnston /* ModR/M.rm := op(ModR/M.reg) */
6344722b2e2fSMark Johnston x->d86_numopnds = 2;
6345722b2e2fSMark Johnston dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);
6346722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6347722b2e2fSMark Johnston evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;
6348722b2e2fSMark Johnston dtrace_evex_adjust_reg(evex_byte1, ®);
6349722b2e2fSMark Johnston dtrace_evex_adjust_rm(evex_byte1, &r_m);
6350722b2e2fSMark Johnston dtrace_evex_adjust_reg_name(evex_L, &wbit);
6351722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
6352722b2e2fSMark Johnston dtrace_evex_adjust_disp8_n(x, 1, evex_L, evex_modrm);
6353722b2e2fSMark Johnston dtrace_evex_adjust_z_opmask(x, 1, evex_byte3);
6354722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
6355722b2e2fSMark Johnston break;
6356722b2e2fSMark Johnston case EVEX_RMrX:
6357722b2e2fSMark Johnston /* ModR/M.reg := op(EVEX.vvvv, ModR/M.r/m) */
6358722b2e2fSMark Johnston x->d86_numopnds = 3;
6359722b2e2fSMark Johnston dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);
6360722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6361722b2e2fSMark Johnston evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;
6362722b2e2fSMark Johnston dtrace_evex_adjust_reg(evex_byte1, ®);
6363722b2e2fSMark Johnston dtrace_evex_adjust_rm(evex_byte1, &r_m);
6364722b2e2fSMark Johnston dtrace_evex_adjust_reg_name(evex_L, &wbit);
6365722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
6366722b2e2fSMark Johnston /*
6367722b2e2fSMark Johnston * EVEX.vvvv is the same as VEX.vvvv (ones complement of the
6368722b2e2fSMark Johnston * register specifier). The EVEX prefix handling uses the vex_v
6369722b2e2fSMark Johnston * variable for these bits.
6370722b2e2fSMark Johnston */
6371722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
6372722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 0);
6373722b2e2fSMark Johnston dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);
6374722b2e2fSMark Johnston dtrace_evex_adjust_z_opmask(x, 2, evex_byte3);
6375722b2e2fSMark Johnston break;
6376722b2e2fSMark Johnston case EVEX_RMRX:
6377722b2e2fSMark Johnston /* ModR/M.reg := op(EVEX.vvvv, ModR/M.r_m, imm8) */
6378722b2e2fSMark Johnston x->d86_numopnds = 4;
6379722b2e2fSMark Johnston
6380722b2e2fSMark Johnston dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);
6381722b2e2fSMark Johnston dtrace_get_modrm(x, &mode, ®, &r_m);
6382722b2e2fSMark Johnston evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;
6383722b2e2fSMark Johnston dtrace_evex_adjust_reg(evex_byte1, ®);
6384722b2e2fSMark Johnston dtrace_evex_adjust_rm(evex_byte1, &r_m);
6385722b2e2fSMark Johnston dtrace_evex_adjust_reg_name(evex_L, &wbit);
6386722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
6387722b2e2fSMark Johnston /*
6388722b2e2fSMark Johnston * EVEX.vvvv is the same as VEX.vvvv (ones complement of the
6389722b2e2fSMark Johnston * register specifier). The EVEX prefix handling uses the vex_v
6390722b2e2fSMark Johnston * variable for these bits.
6391722b2e2fSMark Johnston */
6392722b2e2fSMark Johnston dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
6393722b2e2fSMark Johnston dtrace_get_operand(x, mode, r_m, wbit, 1);
6394722b2e2fSMark Johnston dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);
6395722b2e2fSMark Johnston dtrace_evex_adjust_z_opmask(x, 3, evex_byte3);
6396722b2e2fSMark Johnston
6397722b2e2fSMark Johnston dtrace_imm_opnd(x, wbit, 1, 0);
6398722b2e2fSMark Johnston break;
63990339a1c2SMark Johnston /* an invalid op code */
64000339a1c2SMark Johnston case AM:
64010339a1c2SMark Johnston case DM:
64020339a1c2SMark Johnston case OVERRIDE:
64030339a1c2SMark Johnston case PREFIX:
64040339a1c2SMark Johnston case UNKNOWN:
64050339a1c2SMark Johnston NOMEM;
64060339a1c2SMark Johnston default:
64070339a1c2SMark Johnston goto error;
64080339a1c2SMark Johnston } /* end switch */
64090339a1c2SMark Johnston if (x->d86_error)
64100339a1c2SMark Johnston goto error;
64110339a1c2SMark Johnston
64120339a1c2SMark Johnston done:
64130339a1c2SMark Johnston #ifdef DIS_MEM
64140339a1c2SMark Johnston /*
64150339a1c2SMark Johnston * compute the size of any memory accessed by the instruction
64160339a1c2SMark Johnston */
64170339a1c2SMark Johnston if (x->d86_memsize != 0) {
64180339a1c2SMark Johnston return (0);
64190339a1c2SMark Johnston } else if (dp->it_stackop) {
64200339a1c2SMark Johnston switch (opnd_size) {
64210339a1c2SMark Johnston case SIZE16:
64220339a1c2SMark Johnston x->d86_memsize = 2;
64230339a1c2SMark Johnston break;
64240339a1c2SMark Johnston case SIZE32:
64250339a1c2SMark Johnston x->d86_memsize = 4;
64260339a1c2SMark Johnston break;
64270339a1c2SMark Johnston case SIZE64:
64280339a1c2SMark Johnston x->d86_memsize = 8;
64290339a1c2SMark Johnston break;
64300339a1c2SMark Johnston }
64310339a1c2SMark Johnston } else if (nomem || mode == REG_ONLY) {
64320339a1c2SMark Johnston x->d86_memsize = 0;
64330339a1c2SMark Johnston
64340339a1c2SMark Johnston } else if (dp->it_size != 0) {
64350339a1c2SMark Johnston /*
64360339a1c2SMark Johnston * In 64 bit mode descriptor table entries
64370339a1c2SMark Johnston * go up to 10 bytes and popf/pushf are always 8 bytes
64380339a1c2SMark Johnston */
64390339a1c2SMark Johnston if (x->d86_mode == SIZE64 && dp->it_size == 6)
64400339a1c2SMark Johnston x->d86_memsize = 10;
64410339a1c2SMark Johnston else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
64420339a1c2SMark Johnston (opcode2 == 0xc || opcode2 == 0xd))
64430339a1c2SMark Johnston x->d86_memsize = 8;
64440339a1c2SMark Johnston else
64450339a1c2SMark Johnston x->d86_memsize = dp->it_size;
64460339a1c2SMark Johnston
6447*418d8f0dSMark Johnston } else if (wbit == BYTE_OPND) {
64480339a1c2SMark Johnston x->d86_memsize = 1;
64490339a1c2SMark Johnston
64500339a1c2SMark Johnston } else if (wbit == LONG_OPND) {
64510339a1c2SMark Johnston if (opnd_size == SIZE64)
64520339a1c2SMark Johnston x->d86_memsize = 8;
64530339a1c2SMark Johnston else if (opnd_size == SIZE32)
64540339a1c2SMark Johnston x->d86_memsize = 4;
64550339a1c2SMark Johnston else
64560339a1c2SMark Johnston x->d86_memsize = 2;
64570339a1c2SMark Johnston
64580339a1c2SMark Johnston } else if (wbit == SEG_OPND) {
64590339a1c2SMark Johnston x->d86_memsize = 4;
64600339a1c2SMark Johnston
64610339a1c2SMark Johnston } else {
64620339a1c2SMark Johnston x->d86_memsize = 8;
64630339a1c2SMark Johnston }
64640339a1c2SMark Johnston #endif
64650339a1c2SMark Johnston return (0);
64660339a1c2SMark Johnston
64670339a1c2SMark Johnston error:
64680339a1c2SMark Johnston #ifdef DIS_TEXT
64690339a1c2SMark Johnston (void) strlcat(x->d86_mnem, "undef", OPLEN);
64700339a1c2SMark Johnston #endif
64710339a1c2SMark Johnston return (1);
64720339a1c2SMark Johnston }
64730339a1c2SMark Johnston
64740339a1c2SMark Johnston #ifdef DIS_TEXT
64750339a1c2SMark Johnston
64760339a1c2SMark Johnston /*
64770339a1c2SMark Johnston * Some instructions should have immediate operands printed
64780339a1c2SMark Johnston * as unsigned integers. We compare against this table.
64790339a1c2SMark Johnston */
64800339a1c2SMark Johnston static char *unsigned_ops[] = {
64810339a1c2SMark Johnston "or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
64820339a1c2SMark Johnston "rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
64830339a1c2SMark Johnston 0
64840339a1c2SMark Johnston };
64850339a1c2SMark Johnston
64860339a1c2SMark Johnston
64870339a1c2SMark Johnston static int
isunsigned_op(char * opcode)64880339a1c2SMark Johnston isunsigned_op(char *opcode)
64890339a1c2SMark Johnston {
64900339a1c2SMark Johnston char *where;
64910339a1c2SMark Johnston int i;
64920339a1c2SMark Johnston int is_unsigned = 0;
64930339a1c2SMark Johnston
64940339a1c2SMark Johnston /*
64950339a1c2SMark Johnston * Work back to start of last mnemonic, since we may have
64960339a1c2SMark Johnston * prefixes on some opcodes.
64970339a1c2SMark Johnston */
64980339a1c2SMark Johnston where = opcode + strlen(opcode) - 1;
64990339a1c2SMark Johnston while (where > opcode && *where != ' ')
65000339a1c2SMark Johnston --where;
65010339a1c2SMark Johnston if (*where == ' ')
65020339a1c2SMark Johnston ++where;
65030339a1c2SMark Johnston
65040339a1c2SMark Johnston for (i = 0; unsigned_ops[i]; ++i) {
65050339a1c2SMark Johnston if (strncmp(where, unsigned_ops[i],
65060339a1c2SMark Johnston strlen(unsigned_ops[i])))
65070339a1c2SMark Johnston continue;
65080339a1c2SMark Johnston is_unsigned = 1;
65090339a1c2SMark Johnston break;
65100339a1c2SMark Johnston }
65110339a1c2SMark Johnston return (is_unsigned);
65120339a1c2SMark Johnston }
65130339a1c2SMark Johnston
65140339a1c2SMark Johnston /*
65150339a1c2SMark Johnston * Print a numeric immediate into end of buf, maximum length buflen.
65160339a1c2SMark Johnston * The immediate may be an address or a displacement. Mask is set
65170339a1c2SMark Johnston * for address size. If the immediate is a "small negative", or
65180339a1c2SMark Johnston * if it's a negative displacement of any magnitude, print as -<absval>.
65190339a1c2SMark Johnston * Respect the "octal" flag. "Small negative" is defined as "in the
65200339a1c2SMark Johnston * interval [NEG_LIMIT, 0)".
65210339a1c2SMark Johnston *
65220339a1c2SMark Johnston * Also, "isunsigned_op()" instructions never print negatives.
65230339a1c2SMark Johnston *
65240339a1c2SMark Johnston * Return whether we decided to print a negative value or not.
65250339a1c2SMark Johnston */
65260339a1c2SMark Johnston
65270339a1c2SMark Johnston #define NEG_LIMIT -255
65280339a1c2SMark Johnston enum {IMM, DISP};
65290339a1c2SMark Johnston enum {POS, TRY_NEG};
65300339a1c2SMark Johnston
65310339a1c2SMark Johnston static int
print_imm(dis86_t * dis,uint64_t usv,uint64_t mask,char * buf,size_t buflen,int disp,int try_neg)65320339a1c2SMark Johnston print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
65330339a1c2SMark Johnston size_t buflen, int disp, int try_neg)
65340339a1c2SMark Johnston {
65350339a1c2SMark Johnston int curlen;
65360339a1c2SMark Johnston int64_t sv = (int64_t)usv;
65370339a1c2SMark Johnston int octal = dis->d86_flags & DIS_F_OCTAL;
65380339a1c2SMark Johnston
65390339a1c2SMark Johnston curlen = strlen(buf);
65400339a1c2SMark Johnston
65410339a1c2SMark Johnston if (try_neg == TRY_NEG && sv < 0 &&
65420339a1c2SMark Johnston (disp || sv >= NEG_LIMIT) &&
65430339a1c2SMark Johnston !isunsigned_op(dis->d86_mnem)) {
65440339a1c2SMark Johnston dis->d86_sprintf_func(buf + curlen, buflen - curlen,
65450339a1c2SMark Johnston octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
65460339a1c2SMark Johnston return (1);
65470339a1c2SMark Johnston } else {
65480339a1c2SMark Johnston if (disp == DISP)
65490339a1c2SMark Johnston dis->d86_sprintf_func(buf + curlen, buflen - curlen,
65500339a1c2SMark Johnston octal ? "+0%llo" : "+0x%llx", usv & mask);
65510339a1c2SMark Johnston else
65520339a1c2SMark Johnston dis->d86_sprintf_func(buf + curlen, buflen - curlen,
65530339a1c2SMark Johnston octal ? "0%llo" : "0x%llx", usv & mask);
65540339a1c2SMark Johnston return (0);
65550339a1c2SMark Johnston
65560339a1c2SMark Johnston }
65570339a1c2SMark Johnston }
65580339a1c2SMark Johnston
65590339a1c2SMark Johnston
65600339a1c2SMark Johnston static int
log2(int size)65610339a1c2SMark Johnston log2(int size)
65620339a1c2SMark Johnston {
65630339a1c2SMark Johnston switch (size) {
65640339a1c2SMark Johnston case 1: return (0);
65650339a1c2SMark Johnston case 2: return (1);
65660339a1c2SMark Johnston case 4: return (2);
65670339a1c2SMark Johnston case 8: return (3);
65680339a1c2SMark Johnston }
65690339a1c2SMark Johnston return (0);
65700339a1c2SMark Johnston }
65710339a1c2SMark Johnston
65720339a1c2SMark Johnston /* ARGSUSED */
65730339a1c2SMark Johnston void
dtrace_disx86_str(dis86_t * dis,uint_t mode,uint64_t pc,char * buf,size_t buflen)65740339a1c2SMark Johnston dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
65750339a1c2SMark Johnston size_t buflen)
65760339a1c2SMark Johnston {
65770339a1c2SMark Johnston uint64_t reltgt = 0;
65780339a1c2SMark Johnston uint64_t tgt = 0;
65790339a1c2SMark Johnston int curlen;
65800339a1c2SMark Johnston int (*lookup)(void *, uint64_t, char *, size_t);
65810339a1c2SMark Johnston int i;
65820339a1c2SMark Johnston int64_t sv;
65830339a1c2SMark Johnston uint64_t usv, mask, save_mask, save_usv;
65840339a1c2SMark Johnston static uint64_t masks[] =
65850339a1c2SMark Johnston {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
65860339a1c2SMark Johnston save_usv = 0;
65870339a1c2SMark Johnston
65880339a1c2SMark Johnston dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
65890339a1c2SMark Johnston
65900339a1c2SMark Johnston /*
65910339a1c2SMark Johnston * For PC-relative jumps, the pc is really the next pc after executing
65920339a1c2SMark Johnston * this instruction, so increment it appropriately.
65930339a1c2SMark Johnston */
65940339a1c2SMark Johnston pc += dis->d86_len;
65950339a1c2SMark Johnston
65960339a1c2SMark Johnston for (i = 0; i < dis->d86_numopnds; i++) {
65970339a1c2SMark Johnston d86opnd_t *op = &dis->d86_opnd[i];
65980339a1c2SMark Johnston
65990339a1c2SMark Johnston if (i != 0)
66000339a1c2SMark Johnston (void) strlcat(buf, ",", buflen);
66010339a1c2SMark Johnston
66020339a1c2SMark Johnston (void) strlcat(buf, op->d86_prefix, buflen);
66030339a1c2SMark Johnston
66040339a1c2SMark Johnston /*
66050339a1c2SMark Johnston * sv is for the signed, possibly-truncated immediate or
66060339a1c2SMark Johnston * displacement; usv retains the original size and
66070339a1c2SMark Johnston * unsignedness for symbol lookup.
66080339a1c2SMark Johnston */
66090339a1c2SMark Johnston
66100339a1c2SMark Johnston sv = usv = op->d86_value;
66110339a1c2SMark Johnston
66120339a1c2SMark Johnston /*
66130339a1c2SMark Johnston * About masks: for immediates that represent
66140339a1c2SMark Johnston * addresses, the appropriate display size is
66150339a1c2SMark Johnston * the effective address size of the instruction.
66160339a1c2SMark Johnston * This includes MODE_OFFSET, MODE_IPREL, and
66170339a1c2SMark Johnston * MODE_RIPREL. Immediates that are simply
66180339a1c2SMark Johnston * immediate values should display in the operand's
66190339a1c2SMark Johnston * size, however, since they don't represent addresses.
66200339a1c2SMark Johnston */
66210339a1c2SMark Johnston
66220339a1c2SMark Johnston /* d86_addr_size is SIZEnn, which is log2(real size) */
66230339a1c2SMark Johnston mask = masks[dis->d86_addr_size];
66240339a1c2SMark Johnston
66250339a1c2SMark Johnston /* d86_value_size and d86_imm_bytes are in bytes */
66260339a1c2SMark Johnston if (op->d86_mode == MODE_SIGNED ||
66270339a1c2SMark Johnston op->d86_mode == MODE_IMPLIED)
66280339a1c2SMark Johnston mask = masks[log2(op->d86_value_size)];
66290339a1c2SMark Johnston
66300339a1c2SMark Johnston switch (op->d86_mode) {
66310339a1c2SMark Johnston
66320339a1c2SMark Johnston case MODE_NONE:
66330339a1c2SMark Johnston
66340339a1c2SMark Johnston (void) strlcat(buf, op->d86_opnd, buflen);
66350339a1c2SMark Johnston break;
66360339a1c2SMark Johnston
66370339a1c2SMark Johnston case MODE_SIGNED:
66380339a1c2SMark Johnston case MODE_IMPLIED:
66390339a1c2SMark Johnston case MODE_OFFSET:
66400339a1c2SMark Johnston
66410339a1c2SMark Johnston tgt = usv;
66420339a1c2SMark Johnston
66430339a1c2SMark Johnston if (dis->d86_seg_prefix)
66440339a1c2SMark Johnston (void) strlcat(buf, dis->d86_seg_prefix,
66450339a1c2SMark Johnston buflen);
66460339a1c2SMark Johnston
66470339a1c2SMark Johnston if (op->d86_mode == MODE_SIGNED ||
66480339a1c2SMark Johnston op->d86_mode == MODE_IMPLIED) {
66490339a1c2SMark Johnston (void) strlcat(buf, "$", buflen);
66500339a1c2SMark Johnston }
66510339a1c2SMark Johnston
66520339a1c2SMark Johnston if (print_imm(dis, usv, mask, buf, buflen,
66530339a1c2SMark Johnston IMM, TRY_NEG) &&
66540339a1c2SMark Johnston (op->d86_mode == MODE_SIGNED ||
66550339a1c2SMark Johnston op->d86_mode == MODE_IMPLIED)) {
66560339a1c2SMark Johnston
66570339a1c2SMark Johnston /*
66580339a1c2SMark Johnston * We printed a negative value for an
66590339a1c2SMark Johnston * immediate that wasn't a
66600339a1c2SMark Johnston * displacement. Note that fact so we can
66610339a1c2SMark Johnston * print the positive value as an
66620339a1c2SMark Johnston * annotation.
66630339a1c2SMark Johnston */
66640339a1c2SMark Johnston
66650339a1c2SMark Johnston save_usv = usv;
66660339a1c2SMark Johnston save_mask = mask;
66670339a1c2SMark Johnston }
66680339a1c2SMark Johnston (void) strlcat(buf, op->d86_opnd, buflen);
66690339a1c2SMark Johnston break;
66700339a1c2SMark Johnston
66710339a1c2SMark Johnston case MODE_IPREL:
66720339a1c2SMark Johnston case MODE_RIPREL:
66730339a1c2SMark Johnston
66740339a1c2SMark Johnston reltgt = pc + sv;
66750339a1c2SMark Johnston
66760339a1c2SMark Johnston switch (mode) {
66770339a1c2SMark Johnston case SIZE16:
66780339a1c2SMark Johnston reltgt = (uint16_t)reltgt;
66790339a1c2SMark Johnston break;
66800339a1c2SMark Johnston case SIZE32:
66810339a1c2SMark Johnston reltgt = (uint32_t)reltgt;
66820339a1c2SMark Johnston break;
66830339a1c2SMark Johnston }
66840339a1c2SMark Johnston
66850339a1c2SMark Johnston (void) print_imm(dis, usv, mask, buf, buflen,
66860339a1c2SMark Johnston DISP, TRY_NEG);
66870339a1c2SMark Johnston
66880339a1c2SMark Johnston if (op->d86_mode == MODE_RIPREL)
66890339a1c2SMark Johnston (void) strlcat(buf, "(%rip)", buflen);
66900339a1c2SMark Johnston break;
66910339a1c2SMark Johnston }
66920339a1c2SMark Johnston }
66930339a1c2SMark Johnston
66940339a1c2SMark Johnston /*
66950339a1c2SMark Johnston * The symbol lookups may result in false positives,
66960339a1c2SMark Johnston * particularly on object files, where small numbers may match
66970339a1c2SMark Johnston * the 0-relative non-relocated addresses of symbols.
66980339a1c2SMark Johnston */
66990339a1c2SMark Johnston
67000339a1c2SMark Johnston lookup = dis->d86_sym_lookup;
67010339a1c2SMark Johnston if (tgt != 0) {
67020339a1c2SMark Johnston if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
67030339a1c2SMark Johnston lookup(dis->d86_data, tgt, NULL, 0) == 0) {
67040339a1c2SMark Johnston (void) strlcat(buf, "\t<", buflen);
67050339a1c2SMark Johnston curlen = strlen(buf);
67060339a1c2SMark Johnston lookup(dis->d86_data, tgt, buf + curlen,
67070339a1c2SMark Johnston buflen - curlen);
67080339a1c2SMark Johnston (void) strlcat(buf, ">", buflen);
67090339a1c2SMark Johnston }
67100339a1c2SMark Johnston
67110339a1c2SMark Johnston /*
67120339a1c2SMark Johnston * If we printed a negative immediate above, print the
67130339a1c2SMark Johnston * positive in case our heuristic was unhelpful
67140339a1c2SMark Johnston */
67150339a1c2SMark Johnston if (save_usv) {
67160339a1c2SMark Johnston (void) strlcat(buf, "\t<", buflen);
67170339a1c2SMark Johnston (void) print_imm(dis, save_usv, save_mask, buf, buflen,
67180339a1c2SMark Johnston IMM, POS);
67190339a1c2SMark Johnston (void) strlcat(buf, ">", buflen);
67200339a1c2SMark Johnston }
67210339a1c2SMark Johnston }
67220339a1c2SMark Johnston
67230339a1c2SMark Johnston if (reltgt != 0) {
67240339a1c2SMark Johnston /* Print symbol or effective address for reltgt */
67250339a1c2SMark Johnston
67260339a1c2SMark Johnston (void) strlcat(buf, "\t<", buflen);
67270339a1c2SMark Johnston curlen = strlen(buf);
67280339a1c2SMark Johnston lookup(dis->d86_data, reltgt, buf + curlen,
67290339a1c2SMark Johnston buflen - curlen);
67300339a1c2SMark Johnston (void) strlcat(buf, ">", buflen);
67310339a1c2SMark Johnston }
67320339a1c2SMark Johnston }
67330339a1c2SMark Johnston
67340339a1c2SMark Johnston #endif /* DIS_TEXT */
6735