Path: blob/main/sys/cddl/dev/dtrace/x86/dis_tables.c
48375 views
/*1*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.23* Copyright 2019 Joyent, Inc.24* Copyright 2020 Robert Mustacchi25*/2627/*28* Copyright (c) 2010, Intel Corporation.29* All rights reserved.30*/3132/* Copyright (c) 1988 AT&T */33/* All Rights Reserved */3435/*36*/3738#include "dis_tables.h"3940/* BEGIN CSTYLED */4142/*43* Disassembly begins in dis_distable, which is equivalent to the One-byte44* Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy). The45* decoding loops then traverse out through the other tables as necessary to46* decode a given instruction.47*48* The behavior of this file can be controlled by one of the following flags:49*50* DIS_TEXT Include text for disassembly51* DIS_MEM Include memory-size calculations52*53* Either or both of these can be defined.54*55* This file is not, and will never be, cstyled. If anything, the tables should56* be taken out another tab stop or two so nothing overlaps.57*/5859/*60* These functions must be provided for the consumer to do disassembly.61*/62#ifdef DIS_TEXT63extern char *strncpy(char *, const char *, size_t);64extern size_t strlen(const char *);65extern int strcmp(const char *, const char *);66extern int strncmp(const char *, const char *, size_t);67extern size_t strlcat(char *, const char *, size_t);68#endif697071#define TERM 0 /* used to indicate that the 'indirect' */72/* field terminates - no pointer. */7374/* Used to decode instructions. */75typedef struct instable {76struct instable *it_indirect; /* for decode op codes */77uchar_t it_adrmode;78#ifdef DIS_TEXT79char it_name[NCPS];80uint_t it_suffix:1; /* mnem + "w", "l", or "d" */81#endif82#ifdef DIS_MEM83uint_t it_size:16;84#endif85uint_t it_invalid64:1; /* opcode invalid in amd64 */86uint_t it_always64:1; /* 64 bit when in 64 bit mode */87uint_t it_invalid32:1; /* invalid in IA32 */88uint_t it_stackop:1; /* push/pop stack operation */89uint_t it_vexwoxmm:1; /* VEX instructions that don't use XMM/YMM */90uint_t it_avxsuf:2; /* AVX2/AVX512 suffix rqd. */91uint_t it_vexopmask:1; /* VEX inst. that use opmask */92} instable_t;9394/*95* Instruction formats.96*/97enum {98UNKNOWN,99MRw,100IMlw,101IMw,102IR,103OA,104AO,105MS,106SM,107Mv,108Mw,109M, /* register or memory */110MG9, /* register or memory in group 9 (prefix optional) */111Mb, /* register or memory, always byte sized */112MO, /* memory only (no registers) */113PREF,114SWAPGS_RDTSCP,115MONITOR_MWAIT,116R,117RA,118SEG,119MR,120RM,121RM_66r, /* RM, but with a required 0x66 prefix */122IA,123MA,124SD,125AD,126SA,127D,128INM,129SO,130BD,131I,132P,133V,134DSHIFT, /* for double shift that has an 8-bit immediate */135U,136OVERRIDE,137NORM, /* instructions w/o ModR/M byte, no memory access */138IMPLMEM, /* instructions w/o ModR/M byte, implicit mem access */139O, /* for call */140JTAB, /* jump table */141IMUL, /* for 186 iimul instr */142CBW, /* so data16 can be evaluated for cbw and variants */143MvI, /* for 186 logicals */144ENTER, /* for 186 enter instr */145RMw, /* for 286 arpl instr */146Ib, /* for push immediate byte */147F, /* for 287 instructions */148FF, /* for 287 instructions */149FFC, /* for 287 instructions */150DM, /* 16-bit data */151AM, /* 16-bit addr */152LSEG, /* for 3-bit seg reg encoding */153MIb, /* for 386 logicals */154SREG, /* for 386 special registers */155PREFIX, /* a REP instruction prefix */156LOCK, /* a LOCK instruction prefix */157INT3, /* The int 3 instruction, which has a fake operand */158INTx, /* The normal int instruction, with explicit int num */159DSHIFTcl, /* for double shift that implicitly uses %cl */160CWD, /* so data16 can be evaluated for cwd and variants */161RET, /* single immediate 16-bit operand */162MOVZ, /* for movs and movz, with different size operands */163CRC32, /* for crc32, with different size operands */164XADDB, /* for xaddb */165MOVSXZ, /* AMD64 mov sign extend 32 to 64 bit instruction */166MOVBE, /* movbe instruction */167168/*169* MMX/SIMD addressing modes.170*/171172MMO, /* Prefixable MMX/SIMD-Int mm/mem -> mm */173MMOIMPL, /* Prefixable MMX/SIMD-Int mm -> mm (mem) */174MMO3P, /* Prefixable MMX/SIMD-Int mm -> r32,imm8 */175MMOM3, /* Prefixable MMX/SIMD-Int mm -> r32 */176MMOS, /* Prefixable MMX/SIMD-Int mm -> mm/mem */177MMOMS, /* Prefixable MMX/SIMD-Int mm -> mem */178MMOPM, /* MMX/SIMD-Int mm/mem -> mm,imm8 */179MMOPM_66o, /* MMX/SIMD-Int 0x66 optional mm/mem -> mm,imm8 */180MMOPRM, /* Prefixable MMX/SIMD-Int r32/mem -> mm,imm8 */181MMOSH, /* Prefixable MMX mm,imm8 */182MM, /* MMX/SIMD-Int mm/mem -> mm */183MMS, /* MMX/SIMD-Int mm -> mm/mem */184MMSH, /* MMX mm,imm8 */185XMMO, /* Prefixable SIMD xmm/mem -> xmm */186XMMOS, /* Prefixable SIMD xmm -> xmm/mem */187XMMOPM, /* Prefixable SIMD xmm/mem w/to xmm,imm8 */188XMMOMX, /* Prefixable SIMD mm/mem -> xmm */189XMMOX3, /* Prefixable SIMD xmm -> r32 */190XMMOXMM, /* Prefixable SIMD xmm/mem -> mm */191XMMOM, /* Prefixable SIMD xmm -> mem */192XMMOMS, /* Prefixable SIMD mem -> xmm */193XMM, /* SIMD xmm/mem -> xmm */194XMM_66r, /* SIMD 0x66 prefix required xmm/mem -> xmm */195XMM_66o, /* SIMD 0x66 prefix optional xmm/mem -> xmm */196XMMXIMPL, /* SIMD xmm -> xmm (mem) */197XMM3P, /* SIMD xmm -> r32,imm8 */198XMM3PM_66r, /* SIMD 0x66 prefix required xmm -> r32/mem,imm8 */199XMMP, /* SIMD xmm/mem w/to xmm,imm8 */200XMMP_66o, /* SIMD 0x66 prefix optional xmm/mem w/to xmm,imm8 */201XMMP_66r, /* SIMD 0x66 prefix required xmm/mem w/to xmm,imm8 */202XMMPRM, /* SIMD r32/mem -> xmm,imm8 */203XMMPRM_66r, /* SIMD 0x66 prefix required r32/mem -> xmm,imm8 */204XMMS, /* SIMD xmm -> xmm/mem */205XMMM, /* SIMD mem -> xmm */206XMMM_66r, /* SIMD 0x66 prefix required mem -> xmm */207XMMMS, /* SIMD xmm -> mem */208XMM3MX, /* SIMD r32/mem -> xmm */209XMM3MXS, /* SIMD xmm -> r32/mem */210XMMSH, /* SIMD xmm,imm8 */211XMMXM3, /* SIMD xmm/mem -> r32 */212XMMX3, /* SIMD xmm -> r32 */213XMMXMM, /* SIMD xmm/mem -> mm */214XMMMX, /* SIMD mm -> xmm */215XMMXM, /* SIMD xmm -> mm */216XMMX2I, /* SIMD xmm -> xmm, imm, imm */217XMM2I, /* SIMD xmm, imm, imm */218XMMFENCE, /* SIMD lfence or mfence */219XMMSFNC, /* SIMD sfence (none or mem) */220FSGS, /* FSGSBASE if reg */221XGETBV_XSETBV,222VEX_NONE, /* VEX no operand */223VEX_MO, /* VEX mod_rm -> implicit reg */224VEX_RMrX, /* VEX VEX.vvvv, mod_rm -> mod_reg */225VEX_VRMrX, /* VEX mod_rm, VEX.vvvv -> mod_rm */226VEX_RRX, /* VEX VEX.vvvv, mod_reg -> mod_rm */227VEX_RMRX, /* VEX VEX.vvvv, mod_rm, imm8[7:4] -> mod_reg */228VEX_MX, /* VEX mod_rm -> mod_reg */229VEX_MXI, /* VEX mod_rm, imm8 -> mod_reg */230VEX_XXI, /* VEX mod_rm, imm8 -> VEX.vvvv */231VEX_MR, /* VEX mod_rm -> mod_reg */232VEX_RRI, /* VEX mod_reg, mod_rm -> implicit(eflags/r32) */233VEX_RX, /* VEX mod_reg -> mod_rm */234VEX_KRR, /* VEX mod_rm -> mod_reg */235VEX_KMR, /* VEX mod_reg -> mod_rm */236VEX_KRM, /* VEX mod_rm -> mod_reg */237VEX_RR, /* VEX mod_rm -> mod_reg */238VEX_RRi, /* VEX mod_rm, imm8 -> mod_reg */239VEX_RM, /* VEX mod_reg -> mod_rm */240VEX_RIM, /* VEX mod_reg, imm8 -> mod_rm */241VEX_RRM, /* VEX VEX.vvvv, mod_reg -> mod_rm */242VEX_RMX, /* VEX VEX.vvvv, mod_rm -> mod_reg */243VEX_SbVM, /* VEX SIB, VEX.vvvv -> mod_rm */244VMx, /* vmcall/vmlaunch/vmresume/vmxoff */245VMxo, /* VMx instruction with optional prefix */246SVM, /* AMD SVM instructions */247BLS, /* BLSR, BLSMSK, BLSI */248FMA, /* FMA instructions, all VEX_RMrX */249ADX, /* ADX instructions, support REX.w, mod_rm->mod_reg */250EVEX_RX, /* EVEX mod_reg -> mod_rm */251EVEX_MX, /* EVEX mod_rm -> mod_reg */252EVEX_RMrX, /* EVEX EVEX.vvvv, mod_rm -> mod_reg */253EVEX_RMRX /* EVEX EVEX.vvvv, mod_rm, imm8 -> mod_reg */254};255256/*257* VEX prefixes258*/259#define VEX_2bytes 0xC5 /* the first byte of two-byte form */260#define VEX_3bytes 0xC4 /* the first byte of three-byte form */261262#define FILL 0x90 /* Fill byte used for alignment (nop) */263264/*265** Register numbers for the i386266*/267#define EAX_REGNO 0268#define ECX_REGNO 1269#define EDX_REGNO 2270#define EBX_REGNO 3271#define ESP_REGNO 4272#define EBP_REGNO 5273#define ESI_REGNO 6274#define EDI_REGNO 7275276/*277* modes for immediate values278*/279#define MODE_NONE 0280#define MODE_IPREL 1 /* signed IP relative value */281#define MODE_SIGNED 2 /* sign extended immediate */282#define MODE_IMPLIED 3 /* constant value implied from opcode */283#define MODE_OFFSET 4 /* offset part of an address */284#define MODE_RIPREL 5 /* like IPREL, but from %rip (amd64) */285286/*287* The letters used in these macros are:288* IND - indirect to another to another table289* "T" - means to Terminate indirections (this is the final opcode)290* "S" - means "operand length suffix required"291* "Sa" - means AVX2 suffix (q/d) required292* "Sq" - means AVX512 suffix (q/d) required293* "Sd" - means AVX512 suffix (d/s) required294* "NS" - means "no suffix" which is the operand length suffix of the opcode295* "Z" - means instruction size arg required296* "u" - means the opcode is invalid in IA32 but valid in amd64297* "x" - means the opcode is invalid in amd64, but not IA32298* "y" - means the operand size is always 64 bits in 64 bit mode299* "p" - means push/pop stack operation300* "vr" - means VEX instruction that operates on normal registers, not fpu301* "vo" - means VEX instruction that operates on opmask registers, not fpu302*/303304#define AVS2 (uint_t)1 /* it_avxsuf: AVX2 q/d suffix handling */305#define AVS5Q (uint_t)2 /* it_avxsuf: AVX512 q/d suffix handling */306#define AVS5D (uint_t)3 /* it_avxsuf: AVX512 d/s suffix handling */307308#if defined(DIS_TEXT) && defined(DIS_MEM)309#define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}310#define INDx(table) {(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}311#define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0}312#define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 0, 1, 0}313#define TNSx(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0, 0}314#define TNSy(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 0}315#define TNSyp(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0, 1}316#define TNSZ(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0}317#define TNSZy(name, amode, sz) {TERM, amode, name, 0, sz, 0, 1, 0, 0}318#define TNSZvr(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0, 1}319#define TSvo(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0, 0, 0, 1}320#define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0}321#define TSx(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0, 0}322#define TSy(name, amode) {TERM, amode, name, 1, 0, 0, 1, 0, 0}323#define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 1}324#define TSZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0}325#define TSaZ(name, amode, sz) {TERM, amode, name, 1, sz, 0, 0, 0, 0, 0, AVS2}326#define TSq(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, 0, AVS5Q}327#define TSd(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, 0, AVS5D}328#define TSZx(name, amode, sz) {TERM, amode, name, 1, sz, 1, 0, 0, 0}329#define TSZy(name, amode, sz) {TERM, amode, name, 1, sz, 0, 1, 0, 0}330#define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}331#elif defined(DIS_TEXT)332#define IND(table) {(instable_t *)table, 0, "", 0, 0, 0, 0, 0}333#define INDx(table) {(instable_t *)table, 0, "", 0, 1, 0, 0, 0}334#define TNS(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0}335#define TNSu(name, amode) {TERM, amode, name, 0, 0, 0, 1, 0}336#define TNSx(name, amode) {TERM, amode, name, 0, 1, 0, 0, 0}337#define TNSy(name, amode) {TERM, amode, name, 0, 0, 1, 0, 0}338#define TNSyp(name, amode) {TERM, amode, name, 0, 0, 1, 0, 1}339#define TNSZ(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0}340#define TNSZy(name, amode, sz) {TERM, amode, name, 0, 0, 1, 0, 0}341#define TNSZvr(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0, 1}342#define TSvo(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0, 0, 0, 1}343#define TS(name, amode) {TERM, amode, name, 1, 0, 0, 0, 0}344#define TSx(name, amode) {TERM, amode, name, 1, 1, 0, 0, 0}345#define TSy(name, amode) {TERM, amode, name, 1, 0, 1, 0, 0}346#define TSp(name, amode) {TERM, amode, name, 1, 0, 0, 0, 1}347#define TSZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0}348#define TSaZ(name, amode, sz) {TERM, amode, name, 1, 0, 0, 0, 0, 0, AVS2}349#define TSq(name, amode) {TERM, amode, name, 0, 0, 0, 0, 0, 0, AVS5Q}350#define TSZx(name, amode, sz) {TERM, amode, name, 1, 1, 0, 0, 0}351#define TSZy(name, amode, sz) {TERM, amode, name, 1, 0, 1, 0, 0}352#define INVALID {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}353#elif defined(DIS_MEM)354#define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0, 0}355#define INDx(table) {(instable_t *)table, 0, 0, 1, 0, 0, 0}356#define TNS(name, amode) {TERM, amode, 0, 0, 0, 0, 0}357#define TNSu(name, amode) {TERM, amode, 0, 0, 0, 1, 0}358#define TNSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0}359#define TNSyp(name, amode) {TERM, amode, 0, 0, 1, 0, 1}360#define TNSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0}361#define TNSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0}362#define TNSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0}363#define TNSZvr(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0, 1}364#define TSvo(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, 0, 1}365#define TS(name, amode) {TERM, amode, 0, 0, 0, 0, 0}366#define TSx(name, amode) {TERM, amode, 0, 1, 0, 0, 0}367#define TSy(name, amode) {TERM, amode, 0, 0, 1, 0, 0}368#define TSp(name, amode) {TERM, amode, 0, 0, 0, 0, 1}369#define TSZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0}370#define TSaZ(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0, 0, AVS2}371#define TSq(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, AVS5Q}372#define TSZx(name, amode, sz) {TERM, amode, sz, 1, 0, 0, 0}373#define TSZy(name, amode, sz) {TERM, amode, sz, 0, 1, 0, 0}374#define INVALID {TERM, UNKNOWN, 0, 0, 0, 0, 0}375#else376#define IND(table) {(instable_t *)table, 0, 0, 0, 0, 0}377#define INDx(table) {(instable_t *)table, 0, 1, 0, 0, 0}378#define TNS(name, amode) {TERM, amode, 0, 0, 0, 0}379#define TNSu(name, amode) {TERM, amode, 0, 0, 1, 0}380#define TNSy(name, amode) {TERM, amode, 0, 1, 0, 0}381#define TNSyp(name, amode) {TERM, amode, 0, 1, 0, 1}382#define TNSx(name, amode) {TERM, amode, 1, 0, 0, 0}383#define TNSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0}384#define TNSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0}385#define TNSZvr(name, amode, sz) {TERM, amode, 0, 0, 0, 0, 1}386#define TSvo(name, amode) {TERM, amode, 0, 0, 0, 0, 0, 0, 1}387#define TS(name, amode) {TERM, amode, 0, 0, 0, 0}388#define TSx(name, amode) {TERM, amode, 1, 0, 0, 0}389#define TSy(name, amode) {TERM, amode, 0, 1, 0, 0}390#define TSp(name, amode) {TERM, amode, 0, 0, 0, 1}391#define TSZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0}392#define TSaZ(name, amode, sz) {TERM, amode, 0, 0, 0, 0, 0, AVS2}393#define TSq(name, amode) {TERM, amode, 0, 0, 0, 0, 0, AVS5Q}394#define TSd(name, amode) {TERM, amode, 0, 0, 0, 0, 0, AVS5D}395#define TSZx(name, amode, sz) {TERM, amode, 1, 0, 0, 0}396#define TSZy(name, amode, sz) {TERM, amode, 0, 1, 0, 0}397#define INVALID {TERM, UNKNOWN, 0, 0, 0, 0}398#endif399400#ifdef DIS_TEXT401/*402* this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode403*/404const char *const dis_addr16[3][8] = {405"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",406"(%bx)",407"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",408"(%bx)",409"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",410"(%bx)",411};412413414/*415* This decodes 32 bit addressing mode r_m field for modes 0, 1, 2416*/417const char *const dis_addr32_mode0[16] = {418"(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "", "(%esi)", "(%edi)",419"(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "", "(%r14d)", "(%r15d)"420};421422const char *const dis_addr32_mode12[16] = {423"(%eax)", "(%ecx)", "(%edx)", "(%ebx)", "", "(%ebp)", "(%esi)", "(%edi)",424"(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"425};426427/*428* This decodes 64 bit addressing mode r_m field for modes 0, 1, 2429*/430const char *const dis_addr64_mode0[16] = {431"(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rip)", "(%rsi)", "(%rdi)",432"(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"433};434const char *const dis_addr64_mode12[16] = {435"(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "", "(%rbp)", "(%rsi)", "(%rdi)",436"(%r8)", "(%r9)", "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"437};438439/*440* decode for scale from SIB byte441*/442const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };443444/*445* decode for scale from VSIB byte, note that we always include the scale factor446* to match gas.447*/448const char *const dis_vscale_factor[4] = { ",1)", ",2)", ",4)", ",8)" };449450/*451* register decoding for normal references to registers (ie. not addressing)452*/453const char *const dis_REG8[16] = {454"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",455"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"456};457458const char *const dis_REG8_REX[16] = {459"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",460"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"461};462463const char *const dis_REG16[16] = {464"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",465"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"466};467468const char *const dis_REG32[16] = {469"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",470"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"471};472473const char *const dis_REG64[16] = {474"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",475"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"476};477478const char *const dis_DEBUGREG[16] = {479"%db0", "%db1", "%db2", "%db3", "%db4", "%db5", "%db6", "%db7",480"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"481};482483const char *const dis_CONTROLREG[16] = {484"%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",485"%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"486};487488const char *const dis_TESTREG[16] = {489"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",490"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"491};492493const char *const dis_MMREG[16] = {494"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",495"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"496};497498const char *const dis_XMMREG[32] = {499"%xmm0", "%xmm1", "%xmm2", "%xmm3",500"%xmm4", "%xmm5", "%xmm6", "%xmm7",501"%xmm8", "%xmm9", "%xmm10", "%xmm11",502"%xmm12", "%xmm13", "%xmm14", "%xmm15",503"%xmm16", "%xmm17", "%xmm18", "%xmm19",504"%xmm20", "%xmm21", "%xmm22", "%xmm23",505"%xmm24", "%xmm25", "%xmm26", "%xmm27",506"%xmm28", "%xmm29", "%xmm30", "%xmm31",507};508509const char *const dis_YMMREG[32] = {510"%ymm0", "%ymm1", "%ymm2", "%ymm3",511"%ymm4", "%ymm5", "%ymm6", "%ymm7",512"%ymm8", "%ymm9", "%ymm10", "%ymm11",513"%ymm12", "%ymm13", "%ymm14", "%ymm15",514"%ymm16", "%ymm17", "%ymm18", "%ymm19",515"%ymm20", "%ymm21", "%ymm22", "%ymm23",516"%ymm24", "%ymm25", "%ymm26", "%ymm27",517"%ymm28", "%ymm29", "%ymm30", "%ymm31",518};519520const char *const dis_ZMMREG[32] = {521"%zmm0", "%zmm1", "%zmm2", "%zmm3",522"%zmm4", "%zmm5", "%zmm6", "%zmm7",523"%zmm8", "%zmm9", "%zmm10", "%zmm11",524"%zmm12", "%zmm13", "%zmm14", "%zmm15",525"%zmm16", "%zmm17", "%zmm18", "%zmm19",526"%zmm20", "%zmm21", "%zmm22", "%zmm23",527"%zmm24", "%zmm25", "%zmm26", "%zmm27",528"%zmm28", "%zmm29", "%zmm30", "%zmm31",529};530531const char *const dis_KOPMASKREG[8] = {532"%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"533};534535const char *const dis_SEGREG[16] = {536"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",537"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"538};539540/*541* SIMD predicate suffixes542*/543const char *const dis_PREDSUFFIX[8] = {544"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"545};546547const char *const dis_AVXvgrp7[3][8] = {548/*0 1 2 3 4 5 6 7*/549/*71*/ {"", "", "vpsrlw", "", "vpsraw", "", "vpsllw", ""},550/*72*/ {"", "", "vpsrld", "", "vpsrad", "", "vpslld", ""},551/*73*/ {"", "", "vpsrlq", "vpsrldq", "", "", "vpsllq", "vpslldq"}552};553554#endif /* DIS_TEXT */555556/*557* "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)558*/559const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);560561/*562* "decode table" for pause and clflush instructions563*/564const instable_t dis_opPause = TNS("pause", NORM);565566/*567* "decode table" for wbnoinvd instruction568*/569const instable_t dis_opWbnoinvd = TNS("wbnoinvd", NORM);570571/*572* Decode table for 0x0F00 opcodes573*/574const instable_t dis_op0F00[8] = {575576/* [0] */ TNS("sldt",M), TNS("str",M), TNSy("lldt",M), TNSy("ltr",M),577/* [4] */ TNSZ("verr",M,2), TNSZ("verw",M,2), INVALID, INVALID,578};579580581/*582* Decode table for 0x0F01 opcodes583*/584const instable_t dis_op0F01[8] = {585586/* [0] */ TNSZ("sgdt",VMx,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6), TNSZ("lidt",SVM,6),587/* [4] */ TNSZ("smsw",M,2), INVALID, TNSZ("lmsw",M,2), TNS("invlpg",SWAPGS_RDTSCP),588};589590/*591* Decode table for 0x0F18 opcodes -- SIMD prefetch592*/593const instable_t dis_op0F18[8] = {594595/* [0] */ TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF),596/* [4] */ INVALID, INVALID, INVALID, INVALID,597};598599/*600* Decode table for 0x0FAE opcodes -- SIMD state save/restore601*/602const instable_t dis_op0FAE[8] = {603/* [0] */ TNSZ("fxsave",FSGS,512),TNSZ("fxrstor",FSGS,512),TNS("ldmxcsr",FSGS), TNS("stmxcsr",FSGS),604/* [4] */ TNSZ("xsave",M,512), TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC),605};606607/*608* Decode table for 0xF30FAE opcodes -- FSGSBASE609*/610const instable_t dis_opF30FAE[8] = {611/* [0] */ TNSx("rdfsbase",FSGS), TNSx("rdgsbase",FSGS), TNSx("wrfsbase",FSGS), TNSx("wrgsbase",FSGS),612/* [4] */ INVALID, INVALID, INVALID, INVALID,613};614615/*616* Decode table for 0x0FBA opcodes617*/618619const instable_t dis_op0FBA[8] = {620621/* [0] */ INVALID, INVALID, INVALID, INVALID,622/* [4] */ TS("bt",MIb), TS("bts",MIb), TS("btr",MIb), TS("btc",MIb),623};624625/*626* Decode table for 0x0FC7 opcode (group 9)627*/628629const instable_t dis_op0FC7[8] = {630631/* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, TNS("xrstors",MG9),632/* [4] */ TNS("xsavec",MG9), TNS("xsaves",MG9), TNS("vmptrld",MG9), TNS("vmptrst",MG9),633};634635/*636* Decode table for 0x0FC7 opcode (group 9) mode 3637*/638639const instable_t dis_op0FC7m3[8] = {640641/* [0] */ INVALID, INVALID, INVALID, INVALID,642/* [4] */ INVALID, INVALID, TNS("rdrand",MG9), TNS("rdseed", MG9),643};644645/*646* Decode table for 0x0FC7 opcode with 0x66 prefix647*/648649const instable_t dis_op660FC7[8] = {650651/* [0] */ INVALID, INVALID, INVALID, INVALID,652/* [4] */ INVALID, INVALID, TNS("vmclear",M), INVALID,653};654655/*656* Decode table for 0x0FC7 opcode with 0xF3 prefix657*/658659const instable_t dis_opF30FC7[8] = {660661/* [0] */ INVALID, INVALID, INVALID, INVALID,662/* [4] */ INVALID, INVALID, TNS("vmxon",M), INVALID,663};664665/*666* Decode table for 0x0FC8 opcode -- 486 bswap instruction667*668*bit pattern: 0000 1111 1100 1reg669*/670const instable_t dis_op0FC8[4] = {671/* [0] */ TNS("bswap",R), INVALID, INVALID, INVALID,672};673674/*675* Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions676*/677const instable_t dis_op0F7123[4][8] = {678{679/* [70].0 */ INVALID, INVALID, INVALID, INVALID,680/* .4 */ INVALID, INVALID, INVALID, INVALID,681}, {682/* [71].0 */ INVALID, INVALID, TNS("psrlw",MMOSH), INVALID,683/* .4 */ TNS("psraw",MMOSH), INVALID, TNS("psllw",MMOSH), INVALID,684}, {685/* [72].0 */ INVALID, INVALID, TNS("psrld",MMOSH), INVALID,686/* .4 */ TNS("psrad",MMOSH), INVALID, TNS("pslld",MMOSH), INVALID,687}, {688/* [73].0 */ INVALID, INVALID, TNS("psrlq",MMOSH), TNS("INVALID",MMOSH),689/* .4 */ INVALID, INVALID, TNS("psllq",MMOSH), TNS("INVALID",MMOSH),690} };691692/*693* Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.694*/695const instable_t dis_opSIMD7123[32] = {696/* [70].0 */ INVALID, INVALID, INVALID, INVALID,697/* .4 */ INVALID, INVALID, INVALID, INVALID,698699/* [71].0 */ INVALID, INVALID, TNS("psrlw",XMMSH), INVALID,700/* .4 */ TNS("psraw",XMMSH), INVALID, TNS("psllw",XMMSH), INVALID,701702/* [72].0 */ INVALID, INVALID, TNS("psrld",XMMSH), INVALID,703/* .4 */ TNS("psrad",XMMSH), INVALID, TNS("pslld",XMMSH), INVALID,704705/* [73].0 */ INVALID, INVALID, TNS("psrlq",XMMSH), TNS("psrldq",XMMSH),706/* .4 */ INVALID, INVALID, TNS("psllq",XMMSH), TNS("pslldq",XMMSH),707};708709/*710* SIMD instructions have been wedged into the existing IA32 instruction711* set through the use of prefixes. That is, while 0xf0 0x58 may be712* addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different713* instruction - addss. At present, three prefixes have been coopted in714* this manner - address size (0x66), repnz (0xf2) and repz (0xf3). The715* following tables are used to provide the prefixed instruction names.716* The arrays are sparse, but they're fast.717*/718719/*720* Decode table for SIMD instructions with the address size (0x66) prefix.721*/722const instable_t dis_opSIMDdata16[256] = {723/* [00] */ INVALID, INVALID, INVALID, INVALID,724/* [04] */ INVALID, INVALID, INVALID, INVALID,725/* [08] */ INVALID, INVALID, INVALID, INVALID,726/* [0C] */ INVALID, INVALID, INVALID, INVALID,727728/* [10] */ TNSZ("movupd",XMM,16), TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8), TNSZ("movlpd",XMMMS,8),729/* [14] */ TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8), TNSZ("movhpd",XMMMS,8),730/* [18] */ INVALID, INVALID, INVALID, INVALID,731/* [1C] */ INVALID, INVALID, INVALID, INVALID,732733/* [20] */ INVALID, INVALID, INVALID, INVALID,734/* [24] */ INVALID, INVALID, INVALID, INVALID,735/* [28] */ TNSZ("movapd",XMM,16), TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),736/* [2C] */ TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),737738/* [30] */ INVALID, INVALID, INVALID, INVALID,739/* [34] */ INVALID, INVALID, INVALID, INVALID,740/* [38] */ INVALID, INVALID, INVALID, INVALID,741/* [3C] */ INVALID, INVALID, INVALID, INVALID,742743/* [40] */ INVALID, INVALID, INVALID, INVALID,744/* [44] */ INVALID, INVALID, INVALID, INVALID,745/* [48] */ INVALID, INVALID, INVALID, INVALID,746/* [4C] */ INVALID, INVALID, INVALID, INVALID,747748/* [50] */ TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16), INVALID, INVALID,749/* [54] */ TNSZ("andpd",XMM,16), TNSZ("andnpd",XMM,16), TNSZ("orpd",XMM,16), TNSZ("xorpd",XMM,16),750/* [58] */ TNSZ("addpd",XMM,16), TNSZ("mulpd",XMM,16), TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),751/* [5C] */ TNSZ("subpd",XMM,16), TNSZ("minpd",XMM,16), TNSZ("divpd",XMM,16), TNSZ("maxpd",XMM,16),752753/* [60] */ TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),754/* [64] */ TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16),755/* [68] */ TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),756/* [6C] */ TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),757758/* [70] */ TNSZ("pshufd",XMMP,16), INVALID, INVALID, INVALID,759/* [74] */ TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID,760/* [78] */ TNSZ("extrq",XMM2I,16), TNSZ("extrq",XMM,16), INVALID, INVALID,761/* [7C] */ TNSZ("haddpd",XMM,16), TNSZ("hsubpd",XMM,16), TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16),762763/* [80] */ INVALID, INVALID, INVALID, INVALID,764/* [84] */ INVALID, INVALID, INVALID, INVALID,765/* [88] */ INVALID, INVALID, INVALID, INVALID,766/* [8C] */ INVALID, INVALID, INVALID, INVALID,767768/* [90] */ INVALID, INVALID, INVALID, INVALID,769/* [94] */ INVALID, INVALID, INVALID, INVALID,770/* [98] */ INVALID, INVALID, INVALID, INVALID,771/* [9C] */ INVALID, INVALID, INVALID, INVALID,772773/* [A0] */ INVALID, INVALID, INVALID, INVALID,774/* [A4] */ INVALID, INVALID, INVALID, INVALID,775/* [A8] */ INVALID, INVALID, INVALID, INVALID,776/* [AC] */ INVALID, INVALID, INVALID, INVALID,777778/* [B0] */ INVALID, INVALID, INVALID, INVALID,779/* [B4] */ INVALID, INVALID, INVALID, INVALID,780/* [B8] */ INVALID, INVALID, INVALID, INVALID,781/* [BC] */ INVALID, INVALID, INVALID, INVALID,782783/* [C0] */ INVALID, INVALID, TNSZ("cmppd",XMMP,16), INVALID,784/* [C4] */ TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P), TNSZ("shufpd",XMMP,16), INVALID,785/* [C8] */ INVALID, INVALID, INVALID, INVALID,786/* [CC] */ INVALID, INVALID, INVALID, INVALID,787788/* [D0] */ TNSZ("addsubpd",XMM,16),TNSZ("psrlw",XMM,16), TNSZ("psrld",XMM,16), TNSZ("psrlq",XMM,16),789/* [D4] */ TNSZ("paddq",XMM,16), TNSZ("pmullw",XMM,16), TNSZ("movq",XMMS,8), TNS("pmovmskb",XMMX3),790/* [D8] */ TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16), TNSZ("pand",XMM,16),791/* [DC] */ TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16), TNSZ("pandn",XMM,16),792793/* [E0] */ TNSZ("pavgb",XMM,16), TNSZ("psraw",XMM,16), TNSZ("psrad",XMM,16), TNSZ("pavgw",XMM,16),794/* [E4] */ TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16), TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),795/* [E8] */ TNSZ("psubsb",XMM,16), TNSZ("psubsw",XMM,16), TNSZ("pminsw",XMM,16), TNSZ("por",XMM,16),796/* [EC] */ TNSZ("paddsb",XMM,16), TNSZ("paddsw",XMM,16), TNSZ("pmaxsw",XMM,16), TNSZ("pxor",XMM,16),797798/* [F0] */ INVALID, TNSZ("psllw",XMM,16), TNSZ("pslld",XMM,16), TNSZ("psllq",XMM,16),799/* [F4] */ TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16), TNSZ("maskmovdqu", XMMXIMPL,16),800/* [F8] */ TNSZ("psubb",XMM,16), TNSZ("psubw",XMM,16), TNSZ("psubd",XMM,16), TNSZ("psubq",XMM,16),801/* [FC] */ TNSZ("paddb",XMM,16), TNSZ("paddw",XMM,16), TNSZ("paddd",XMM,16), INVALID,802};803804const instable_t dis_opAVX660F[256] = {805/* [00] */ INVALID, INVALID, INVALID, INVALID,806/* [04] */ INVALID, INVALID, INVALID, INVALID,807/* [08] */ INVALID, INVALID, INVALID, INVALID,808/* [0C] */ INVALID, INVALID, INVALID, INVALID,809810/* [10] */ TNSZ("vmovupd",VEX_MX,16), TNSZ("vmovupd",VEX_RX,16), TNSZ("vmovlpd",VEX_RMrX,8), TNSZ("vmovlpd",VEX_RM,8),811/* [14] */ TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8), TNSZ("vmovhpd",VEX_RM,8),812/* [18] */ INVALID, INVALID, INVALID, INVALID,813/* [1C] */ INVALID, INVALID, INVALID, INVALID,814815/* [20] */ INVALID, INVALID, INVALID, INVALID,816/* [24] */ INVALID, INVALID, INVALID, INVALID,817/* [28] */ TNSZ("vmovapd",VEX_MX,16), TNSZ("vmovapd",VEX_RX,16), INVALID, TNSZ("vmovntpd",VEX_RM,16),818/* [2C] */ INVALID, INVALID, TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),819820/* [30] */ INVALID, INVALID, INVALID, INVALID,821/* [34] */ INVALID, INVALID, INVALID, INVALID,822/* [38] */ INVALID, INVALID, INVALID, INVALID,823/* [3C] */ INVALID, INVALID, INVALID, INVALID,824825/* [40] */ INVALID, TSvo("kand",VEX_RMX), TSvo("kandn",VEX_RMX), INVALID,826/* [44] */ TSvo("knot",VEX_MX), TSvo("kor",VEX_RMX), TSvo("kxnor",VEX_RMX), TSvo("kxor",VEX_RMX),827/* [48] */ INVALID, INVALID, TSvo("kadd",VEX_RMX), TSvo("kunpck",VEX_RMX),828/* [4C] */ INVALID, INVALID, INVALID, INVALID,829830/* [50] */ TNS("vmovmskpd",VEX_MR), TNSZ("vsqrtpd",VEX_MX,16), INVALID, INVALID,831/* [54] */ TNSZ("vandpd",VEX_RMrX,16), TNSZ("vandnpd",VEX_RMrX,16), TNSZ("vorpd",VEX_RMrX,16), TNSZ("vxorpd",VEX_RMrX,16),832/* [58] */ TNSZ("vaddpd",VEX_RMrX,16), TNSZ("vmulpd",VEX_RMrX,16), TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),833/* [5C] */ TNSZ("vsubpd",VEX_RMrX,16), TNSZ("vminpd",VEX_RMrX,16), TNSZ("vdivpd",VEX_RMrX,16), TNSZ("vmaxpd",VEX_RMrX,16),834835/* [60] */ TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),836/* [64] */ TNSZ("vpcmpgtb",VEX_RMrX,16), TNSZ("vpcmpgtw",VEX_RMrX,16), TNSZ("vpcmpgtd",VEX_RMrX,16), TNSZ("vpackuswb",VEX_RMrX,16),837/* [68] */ TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),838/* [6C] */ TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),839840/* [70] */ TNSZ("vpshufd",VEX_MXI,16), TNSZ("vgrp71",VEX_XXI,16), TNSZ("vgrp72",VEX_XXI,16), TNSZ("vgrp73",VEX_XXI,16),841/* [74] */ TNSZ("vpcmpeqb",VEX_RMrX,16), TNSZ("vpcmpeqw",VEX_RMrX,16), TNSZ("vpcmpeqd",VEX_RMrX,16), INVALID,842/* [78] */ INVALID, INVALID, INVALID, INVALID,843/* [7C] */ TNSZ("vhaddpd",VEX_RMrX,16), TNSZ("vhsubpd",VEX_RMrX,16), TNSZ("vmovd",VEX_RR,4), TNSZ("vmovdqa",VEX_RX,16),844845/* [80] */ INVALID, INVALID, INVALID, INVALID,846/* [84] */ INVALID, INVALID, INVALID, INVALID,847/* [88] */ INVALID, INVALID, INVALID, INVALID,848/* [8C] */ INVALID, INVALID, INVALID, INVALID,849850/* [90] */ TSvo("kmov",VEX_KRM), TSvo("kmov",VEX_KMR), TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),851/* [94] */ INVALID, INVALID, INVALID, INVALID,852/* [98] */ TSvo("kortest",VEX_MX), TSvo("ktest",VEX_MX), INVALID, INVALID,853/* [9C] */ INVALID, INVALID, INVALID, INVALID,854855/* [A0] */ INVALID, INVALID, INVALID, INVALID,856/* [A4] */ INVALID, INVALID, INVALID, INVALID,857/* [A8] */ INVALID, INVALID, INVALID, INVALID,858/* [AC] */ INVALID, INVALID, INVALID, INVALID,859860/* [B0] */ INVALID, INVALID, INVALID, INVALID,861/* [B4] */ INVALID, INVALID, INVALID, INVALID,862/* [B8] */ INVALID, INVALID, INVALID, INVALID,863/* [BC] */ INVALID, INVALID, INVALID, INVALID,864865/* [C0] */ INVALID, INVALID, TNSZ("vcmppd",VEX_RMRX,16), INVALID,866/* [C4] */ TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR), TNSZ("vshufpd",VEX_RMRX,16), INVALID,867/* [C8] */ INVALID, INVALID, INVALID, INVALID,868/* [CC] */ INVALID, INVALID, INVALID, INVALID,869870/* [D0] */ TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16), TNSZ("vpsrld",VEX_RMrX,16), TNSZ("vpsrlq",VEX_RMrX,16),871/* [D4] */ TNSZ("vpaddq",VEX_RMrX,16), TNSZ("vpmullw",VEX_RMrX,16), TNSZ("vmovq",VEX_RX,8), TNS("vpmovmskb",VEX_MR),872/* [D8] */ TNSZ("vpsubusb",VEX_RMrX,16), TNSZ("vpsubusw",VEX_RMrX,16), TNSZ("vpminub",VEX_RMrX,16), TNSZ("vpand",VEX_RMrX,16),873/* [DC] */ TNSZ("vpaddusb",VEX_RMrX,16), TNSZ("vpaddusw",VEX_RMrX,16), TNSZ("vpmaxub",VEX_RMrX,16), TNSZ("vpandn",VEX_RMrX,16),874875/* [E0] */ TNSZ("vpavgb",VEX_RMrX,16), TNSZ("vpsraw",VEX_RMrX,16), TNSZ("vpsrad",VEX_RMrX,16), TNSZ("vpavgw",VEX_RMrX,16),876/* [E4] */ TNSZ("vpmulhuw",VEX_RMrX,16), TNSZ("vpmulhw",VEX_RMrX,16), TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),877/* [E8] */ TNSZ("vpsubsb",VEX_RMrX,16), TNSZ("vpsubsw",VEX_RMrX,16), TNSZ("vpminsw",VEX_RMrX,16), TNSZ("vpor",VEX_RMrX,16),878/* [EC] */ TNSZ("vpaddsb",VEX_RMrX,16), TNSZ("vpaddsw",VEX_RMrX,16), TNSZ("vpmaxsw",VEX_RMrX,16), TNSZ("vpxor",VEX_RMrX,16),879880/* [F0] */ INVALID, TNSZ("vpsllw",VEX_RMrX,16), TNSZ("vpslld",VEX_RMrX,16), TNSZ("vpsllq",VEX_RMrX,16),881/* [F4] */ TNSZ("vpmuludq",VEX_RMrX,16), TNSZ("vpmaddwd",VEX_RMrX,16), TNSZ("vpsadbw",VEX_RMrX,16), TNS("vmaskmovdqu",VEX_MX),882/* [F8] */ TNSZ("vpsubb",VEX_RMrX,16), TNSZ("vpsubw",VEX_RMrX,16), TNSZ("vpsubd",VEX_RMrX,16), TNSZ("vpsubq",VEX_RMrX,16),883/* [FC] */ TNSZ("vpaddb",VEX_RMrX,16), TNSZ("vpaddw",VEX_RMrX,16), TNSZ("vpaddd",VEX_RMrX,16), INVALID,884};885886/*887* Decode table for SIMD instructions with the repnz (0xf2) prefix.888*/889const instable_t dis_opSIMDrepnz[256] = {890/* [00] */ INVALID, INVALID, INVALID, INVALID,891/* [04] */ INVALID, INVALID, INVALID, INVALID,892/* [08] */ INVALID, INVALID, INVALID, INVALID,893/* [0C] */ INVALID, INVALID, INVALID, INVALID,894895/* [10] */ TNSZ("movsd",XMM,8), TNSZ("movsd",XMMS,8), TNSZ("movddup",XMM,8), INVALID,896/* [14] */ INVALID, INVALID, INVALID, INVALID,897/* [18] */ INVALID, INVALID, INVALID, INVALID,898/* [1C] */ INVALID, INVALID, INVALID, INVALID,899900/* [20] */ INVALID, INVALID, INVALID, INVALID,901/* [24] */ INVALID, INVALID, INVALID, INVALID,902/* [28] */ INVALID, INVALID, TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),903/* [2C] */ TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID, INVALID,904905/* [30] */ INVALID, INVALID, INVALID, INVALID,906/* [34] */ INVALID, INVALID, INVALID, INVALID,907/* [38] */ INVALID, INVALID, INVALID, INVALID,908/* [3C] */ INVALID, INVALID, INVALID, INVALID,909910/* [40] */ INVALID, INVALID, INVALID, INVALID,911/* [44] */ INVALID, INVALID, INVALID, INVALID,912/* [48] */ INVALID, INVALID, INVALID, INVALID,913/* [4C] */ INVALID, INVALID, INVALID, INVALID,914915/* [50] */ INVALID, TNSZ("sqrtsd",XMM,8), INVALID, INVALID,916/* [54] */ INVALID, INVALID, INVALID, INVALID,917/* [58] */ TNSZ("addsd",XMM,8), TNSZ("mulsd",XMM,8), TNSZ("cvtsd2ss",XMM,8), INVALID,918/* [5C] */ TNSZ("subsd",XMM,8), TNSZ("minsd",XMM,8), TNSZ("divsd",XMM,8), TNSZ("maxsd",XMM,8),919920/* [60] */ INVALID, INVALID, INVALID, INVALID,921/* [64] */ INVALID, INVALID, INVALID, INVALID,922/* [68] */ INVALID, INVALID, INVALID, INVALID,923/* [6C] */ INVALID, INVALID, INVALID, INVALID,924925/* [70] */ TNSZ("pshuflw",XMMP,16),INVALID, INVALID, INVALID,926/* [74] */ INVALID, INVALID, INVALID, INVALID,927/* [78] */ TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID, INVALID,928/* [7C] */ TNSZ("haddps",XMM,16), TNSZ("hsubps",XMM,16), INVALID, INVALID,929930/* [80] */ INVALID, INVALID, INVALID, INVALID,931/* [84] */ INVALID, INVALID, INVALID, INVALID,932/* [88] */ INVALID, INVALID, INVALID, INVALID,933/* [0C] */ INVALID, INVALID, INVALID, INVALID,934935/* [90] */ INVALID, INVALID, INVALID, INVALID,936/* [94] */ INVALID, INVALID, INVALID, INVALID,937/* [98] */ INVALID, INVALID, INVALID, INVALID,938/* [9C] */ INVALID, INVALID, INVALID, INVALID,939940/* [A0] */ INVALID, INVALID, INVALID, INVALID,941/* [A4] */ INVALID, INVALID, INVALID, INVALID,942/* [A8] */ INVALID, INVALID, INVALID, INVALID,943/* [AC] */ INVALID, INVALID, INVALID, INVALID,944945/* [B0] */ INVALID, INVALID, INVALID, INVALID,946/* [B4] */ INVALID, INVALID, INVALID, INVALID,947/* [B8] */ INVALID, INVALID, INVALID, INVALID,948/* [BC] */ INVALID, INVALID, INVALID, INVALID,949950/* [C0] */ INVALID, INVALID, TNSZ("cmpsd",XMMP,8), INVALID,951/* [C4] */ INVALID, INVALID, INVALID, INVALID,952/* [C8] */ INVALID, INVALID, INVALID, INVALID,953/* [CC] */ INVALID, INVALID, INVALID, INVALID,954955/* [D0] */ TNSZ("addsubps",XMM,16),INVALID, INVALID, INVALID,956/* [D4] */ INVALID, INVALID, TNS("movdq2q",XMMXM), INVALID,957/* [D8] */ INVALID, INVALID, INVALID, INVALID,958/* [DC] */ INVALID, INVALID, INVALID, INVALID,959960/* [E0] */ INVALID, INVALID, INVALID, INVALID,961/* [E4] */ INVALID, INVALID, TNSZ("cvtpd2dq",XMM,16),INVALID,962/* [E8] */ INVALID, INVALID, INVALID, INVALID,963/* [EC] */ INVALID, INVALID, INVALID, INVALID,964965/* [F0] */ TNS("lddqu",XMMM), INVALID, INVALID, INVALID,966/* [F4] */ INVALID, INVALID, INVALID, INVALID,967/* [F8] */ INVALID, INVALID, INVALID, INVALID,968/* [FC] */ INVALID, INVALID, INVALID, INVALID,969};970971const instable_t dis_opAVXF20F[256] = {972/* [00] */ INVALID, INVALID, INVALID, INVALID,973/* [04] */ INVALID, INVALID, INVALID, INVALID,974/* [08] */ INVALID, INVALID, INVALID, INVALID,975/* [0C] */ INVALID, INVALID, INVALID, INVALID,976977/* [10] */ TNSZ("vmovsd",VEX_RMrX,8), TNSZ("vmovsd",VEX_RRX,8), TNSZ("vmovddup",VEX_MX,8), INVALID,978/* [14] */ INVALID, INVALID, INVALID, INVALID,979/* [18] */ INVALID, INVALID, INVALID, INVALID,980/* [1C] */ INVALID, INVALID, INVALID, INVALID,981982/* [20] */ INVALID, INVALID, INVALID, INVALID,983/* [24] */ INVALID, INVALID, INVALID, INVALID,984/* [28] */ INVALID, INVALID, TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,985/* [2C] */ TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID, INVALID,986987/* [30] */ INVALID, INVALID, INVALID, INVALID,988/* [34] */ INVALID, INVALID, INVALID, INVALID,989/* [38] */ INVALID, INVALID, INVALID, INVALID,990/* [3C] */ INVALID, INVALID, INVALID, INVALID,991992/* [40] */ INVALID, INVALID, INVALID, INVALID,993/* [44] */ INVALID, INVALID, INVALID, INVALID,994/* [48] */ INVALID, INVALID, INVALID, INVALID,995/* [4C] */ INVALID, INVALID, INVALID, INVALID,996997/* [50] */ INVALID, TNSZ("vsqrtsd",VEX_RMrX,8), INVALID, INVALID,998/* [54] */ INVALID, INVALID, INVALID, INVALID,999/* [58] */ TNSZ("vaddsd",VEX_RMrX,8), TNSZ("vmulsd",VEX_RMrX,8), TNSZ("vcvtsd2ss",VEX_RMrX,8), INVALID,1000/* [5C] */ TNSZ("vsubsd",VEX_RMrX,8), TNSZ("vminsd",VEX_RMrX,8), TNSZ("vdivsd",VEX_RMrX,8), TNSZ("vmaxsd",VEX_RMrX,8),10011002/* [60] */ INVALID, INVALID, INVALID, INVALID,1003/* [64] */ INVALID, INVALID, INVALID, INVALID,1004/* [68] */ INVALID, INVALID, INVALID, INVALID,1005/* [6C] */ INVALID, INVALID, INVALID, INVALID,10061007/* [70] */ TNSZ("vpshuflw",VEX_MXI,16),INVALID, INVALID, INVALID,1008/* [74] */ INVALID, INVALID, INVALID, INVALID,1009/* [78] */ INVALID, INVALID, INVALID, INVALID,1010/* [7C] */ TNSZ("vhaddps",VEX_RMrX,8), TNSZ("vhsubps",VEX_RMrX,8), INVALID, INVALID,10111012/* [80] */ INVALID, INVALID, INVALID, INVALID,1013/* [84] */ INVALID, INVALID, INVALID, INVALID,1014/* [88] */ INVALID, INVALID, INVALID, INVALID,1015/* [0C] */ INVALID, INVALID, INVALID, INVALID,10161017/* [90] */ INVALID, INVALID, TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),1018/* [94] */ INVALID, INVALID, INVALID, INVALID,1019/* [98] */ INVALID, INVALID, INVALID, INVALID,1020/* [9C] */ INVALID, INVALID, INVALID, INVALID,10211022/* [A0] */ INVALID, INVALID, INVALID, INVALID,1023/* [A4] */ INVALID, INVALID, INVALID, INVALID,1024/* [A8] */ INVALID, INVALID, INVALID, INVALID,1025/* [AC] */ INVALID, INVALID, INVALID, INVALID,10261027/* [B0] */ INVALID, INVALID, INVALID, INVALID,1028/* [B4] */ INVALID, INVALID, INVALID, INVALID,1029/* [B8] */ INVALID, INVALID, INVALID, INVALID,1030/* [BC] */ INVALID, INVALID, INVALID, INVALID,10311032/* [C0] */ INVALID, INVALID, TNSZ("vcmpsd",VEX_RMRX,8), INVALID,1033/* [C4] */ INVALID, INVALID, INVALID, INVALID,1034/* [C8] */ INVALID, INVALID, INVALID, INVALID,1035/* [CC] */ INVALID, INVALID, INVALID, INVALID,10361037/* [D0] */ TNSZ("vaddsubps",VEX_RMrX,8), INVALID, INVALID, INVALID,1038/* [D4] */ INVALID, INVALID, INVALID, INVALID,1039/* [D8] */ INVALID, INVALID, INVALID, INVALID,1040/* [DC] */ INVALID, INVALID, INVALID, INVALID,10411042/* [E0] */ INVALID, INVALID, INVALID, INVALID,1043/* [E4] */ INVALID, INVALID, TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,1044/* [E8] */ INVALID, INVALID, INVALID, INVALID,1045/* [EC] */ INVALID, INVALID, INVALID, INVALID,10461047/* [F0] */ TNSZ("vlddqu",VEX_MX,16), INVALID, INVALID, INVALID,1048/* [F4] */ INVALID, INVALID, INVALID, INVALID,1049/* [F8] */ INVALID, INVALID, INVALID, INVALID,1050/* [FC] */ INVALID, INVALID, INVALID, INVALID,1051};10521053const instable_t dis_opAVXF20F3A[256] = {1054/* [00] */ INVALID, INVALID, INVALID, INVALID,1055/* [04] */ INVALID, INVALID, INVALID, INVALID,1056/* [08] */ INVALID, INVALID, INVALID, INVALID,1057/* [0C] */ INVALID, INVALID, INVALID, INVALID,10581059/* [10] */ INVALID, INVALID, INVALID, INVALID,1060/* [14] */ INVALID, INVALID, INVALID, INVALID,1061/* [18] */ INVALID, INVALID, INVALID, INVALID,1062/* [1C] */ INVALID, INVALID, INVALID, INVALID,10631064/* [20] */ INVALID, INVALID, INVALID, INVALID,1065/* [24] */ INVALID, INVALID, INVALID, INVALID,1066/* [28] */ INVALID, INVALID, INVALID, INVALID,1067/* [2C] */ INVALID, INVALID, INVALID, INVALID,10681069/* [30] */ INVALID, INVALID, INVALID, INVALID,1070/* [34] */ INVALID, INVALID, INVALID, INVALID,1071/* [38] */ INVALID, INVALID, INVALID, INVALID,1072/* [3C] */ INVALID, INVALID, INVALID, INVALID,10731074/* [40] */ INVALID, INVALID, INVALID, INVALID,1075/* [44] */ INVALID, INVALID, INVALID, INVALID,1076/* [48] */ INVALID, INVALID, INVALID, INVALID,1077/* [4C] */ INVALID, INVALID, INVALID, INVALID,10781079/* [50] */ INVALID, INVALID, INVALID, INVALID,1080/* [54] */ INVALID, INVALID, INVALID, INVALID,1081/* [58] */ INVALID, INVALID, INVALID, INVALID,1082/* [5C] */ INVALID, INVALID, INVALID, INVALID,10831084/* [60] */ INVALID, INVALID, INVALID, INVALID,1085/* [64] */ INVALID, INVALID, INVALID, INVALID,1086/* [68] */ INVALID, INVALID, INVALID, INVALID,1087/* [6C] */ INVALID, INVALID, INVALID, INVALID,10881089/* [70] */ INVALID, INVALID, INVALID, INVALID,1090/* [74] */ INVALID, INVALID, INVALID, INVALID,1091/* [78] */ INVALID, INVALID, INVALID, INVALID,1092/* [7C] */ INVALID, INVALID, INVALID, INVALID,10931094/* [80] */ INVALID, INVALID, INVALID, INVALID,1095/* [84] */ INVALID, INVALID, INVALID, INVALID,1096/* [88] */ INVALID, INVALID, INVALID, INVALID,1097/* [0C] */ INVALID, INVALID, INVALID, INVALID,10981099/* [90] */ INVALID, INVALID, INVALID, INVALID,1100/* [94] */ INVALID, INVALID, INVALID, INVALID,1101/* [98] */ INVALID, INVALID, INVALID, INVALID,1102/* [9C] */ INVALID, INVALID, INVALID, INVALID,11031104/* [A0] */ INVALID, INVALID, INVALID, INVALID,1105/* [A4] */ INVALID, INVALID, INVALID, INVALID,1106/* [A8] */ INVALID, INVALID, INVALID, INVALID,1107/* [AC] */ INVALID, INVALID, INVALID, INVALID,11081109/* [B0] */ INVALID, INVALID, INVALID, INVALID,1110/* [B4] */ INVALID, INVALID, INVALID, INVALID,1111/* [B8] */ INVALID, INVALID, INVALID, INVALID,1112/* [BC] */ INVALID, INVALID, INVALID, INVALID,11131114/* [C0] */ INVALID, INVALID, INVALID, INVALID,1115/* [C4] */ INVALID, INVALID, INVALID, INVALID,1116/* [C8] */ INVALID, INVALID, INVALID, INVALID,1117/* [CC] */ INVALID, INVALID, INVALID, INVALID,11181119/* [D0] */ INVALID, INVALID, INVALID, INVALID,1120/* [D4] */ INVALID, INVALID, INVALID, INVALID,1121/* [D8] */ INVALID, INVALID, INVALID, INVALID,1122/* [DC] */ INVALID, INVALID, INVALID, INVALID,11231124/* [E0] */ INVALID, INVALID, INVALID, INVALID,1125/* [E4] */ INVALID, INVALID, INVALID, INVALID,1126/* [E8] */ INVALID, INVALID, INVALID, INVALID,1127/* [EC] */ INVALID, INVALID, INVALID, INVALID,11281129/* [F0] */ TNSZvr("rorx",VEX_MXI,6),INVALID, INVALID, INVALID,1130/* [F4] */ INVALID, INVALID, INVALID, INVALID,1131/* [F8] */ INVALID, INVALID, INVALID, INVALID,1132/* [FC] */ INVALID, INVALID, INVALID, INVALID,1133};11341135const instable_t dis_opAVXF20F38[256] = {1136/* [00] */ INVALID, INVALID, INVALID, INVALID,1137/* [04] */ INVALID, INVALID, INVALID, INVALID,1138/* [08] */ INVALID, INVALID, INVALID, INVALID,1139/* [0C] */ INVALID, INVALID, INVALID, INVALID,11401141/* [10] */ INVALID, INVALID, INVALID, INVALID,1142/* [14] */ INVALID, INVALID, INVALID, INVALID,1143/* [18] */ INVALID, INVALID, INVALID, INVALID,1144/* [1C] */ INVALID, INVALID, INVALID, INVALID,11451146/* [20] */ INVALID, INVALID, INVALID, INVALID,1147/* [24] */ INVALID, INVALID, INVALID, INVALID,1148/* [28] */ INVALID, INVALID, INVALID, INVALID,1149/* [2C] */ INVALID, INVALID, INVALID, INVALID,11501151/* [30] */ INVALID, INVALID, INVALID, INVALID,1152/* [34] */ INVALID, INVALID, INVALID, INVALID,1153/* [38] */ INVALID, INVALID, INVALID, INVALID,1154/* [3C] */ INVALID, INVALID, INVALID, INVALID,11551156/* [40] */ INVALID, INVALID, INVALID, INVALID,1157/* [44] */ INVALID, INVALID, INVALID, INVALID,1158/* [48] */ INVALID, INVALID, INVALID, INVALID,1159/* [4C] */ INVALID, INVALID, INVALID, INVALID,11601161/* [50] */ INVALID, INVALID, INVALID, INVALID,1162/* [54] */ INVALID, INVALID, INVALID, INVALID,1163/* [58] */ INVALID, INVALID, INVALID, INVALID,1164/* [5C] */ INVALID, INVALID, INVALID, INVALID,11651166/* [60] */ INVALID, INVALID, INVALID, INVALID,1167/* [64] */ INVALID, INVALID, INVALID, INVALID,1168/* [68] */ INVALID, INVALID, INVALID, INVALID,1169/* [6C] */ INVALID, INVALID, INVALID, INVALID,11701171/* [70] */ INVALID, INVALID, INVALID, INVALID,1172/* [74] */ INVALID, INVALID, INVALID, INVALID,1173/* [78] */ INVALID, INVALID, INVALID, INVALID,1174/* [7C] */ INVALID, INVALID, INVALID, INVALID,11751176/* [80] */ INVALID, INVALID, INVALID, INVALID,1177/* [84] */ INVALID, INVALID, INVALID, INVALID,1178/* [88] */ INVALID, INVALID, INVALID, INVALID,1179/* [0C] */ INVALID, INVALID, INVALID, INVALID,11801181/* [90] */ INVALID, INVALID, INVALID, INVALID,1182/* [94] */ INVALID, INVALID, INVALID, INVALID,1183/* [98] */ INVALID, INVALID, INVALID, INVALID,1184/* [9C] */ INVALID, INVALID, INVALID, INVALID,11851186/* [A0] */ INVALID, INVALID, INVALID, INVALID,1187/* [A4] */ INVALID, INVALID, INVALID, INVALID,1188/* [A8] */ INVALID, INVALID, INVALID, INVALID,1189/* [AC] */ INVALID, INVALID, INVALID, INVALID,11901191/* [B0] */ INVALID, INVALID, INVALID, INVALID,1192/* [B4] */ INVALID, INVALID, INVALID, INVALID,1193/* [B8] */ INVALID, INVALID, INVALID, INVALID,1194/* [BC] */ INVALID, INVALID, INVALID, INVALID,11951196/* [C0] */ INVALID, INVALID, INVALID, INVALID,1197/* [C4] */ INVALID, INVALID, INVALID, INVALID,1198/* [C8] */ INVALID, INVALID, INVALID, INVALID,1199/* [CC] */ INVALID, INVALID, INVALID, INVALID,12001201/* [D0] */ INVALID, INVALID, INVALID, INVALID,1202/* [D4] */ INVALID, INVALID, INVALID, INVALID,1203/* [D8] */ INVALID, INVALID, INVALID, INVALID,1204/* [DC] */ INVALID, INVALID, INVALID, INVALID,12051206/* [E0] */ INVALID, INVALID, INVALID, INVALID,1207/* [E4] */ INVALID, INVALID, INVALID, INVALID,1208/* [E8] */ INVALID, INVALID, INVALID, INVALID,1209/* [EC] */ INVALID, INVALID, INVALID, INVALID,12101211/* [F0] */ INVALID, INVALID, INVALID, INVALID,1212/* [F4] */ INVALID, TNSZvr("pdep",VEX_RMrX,5),TNSZvr("mulx",VEX_RMrX,5),TNSZvr("shrx",VEX_VRMrX,5),1213/* [F8] */ INVALID, INVALID, INVALID, INVALID,1214/* [FC] */ INVALID, INVALID, INVALID, INVALID,1215};12161217const instable_t dis_opAVXF30F38[256] = {1218/* [00] */ INVALID, INVALID, INVALID, INVALID,1219/* [04] */ INVALID, INVALID, INVALID, INVALID,1220/* [08] */ INVALID, INVALID, INVALID, INVALID,1221/* [0C] */ INVALID, INVALID, INVALID, INVALID,12221223/* [10] */ INVALID, INVALID, INVALID, INVALID,1224/* [14] */ INVALID, INVALID, INVALID, INVALID,1225/* [18] */ INVALID, INVALID, INVALID, INVALID,1226/* [1C] */ INVALID, INVALID, INVALID, INVALID,12271228/* [20] */ INVALID, INVALID, INVALID, INVALID,1229/* [24] */ INVALID, INVALID, INVALID, INVALID,1230/* [28] */ INVALID, INVALID, INVALID, INVALID,1231/* [2C] */ INVALID, INVALID, INVALID, INVALID,12321233/* [30] */ INVALID, INVALID, INVALID, INVALID,1234/* [34] */ INVALID, INVALID, INVALID, INVALID,1235/* [38] */ INVALID, INVALID, INVALID, INVALID,1236/* [3C] */ INVALID, INVALID, INVALID, INVALID,12371238/* [40] */ INVALID, INVALID, INVALID, INVALID,1239/* [44] */ INVALID, INVALID, INVALID, INVALID,1240/* [48] */ INVALID, INVALID, INVALID, INVALID,1241/* [4C] */ INVALID, INVALID, INVALID, INVALID,12421243/* [50] */ INVALID, INVALID, INVALID, INVALID,1244/* [54] */ INVALID, INVALID, INVALID, INVALID,1245/* [58] */ INVALID, INVALID, INVALID, INVALID,1246/* [5C] */ INVALID, INVALID, INVALID, INVALID,12471248/* [60] */ INVALID, INVALID, INVALID, INVALID,1249/* [64] */ INVALID, INVALID, INVALID, INVALID,1250/* [68] */ INVALID, INVALID, INVALID, INVALID,1251/* [6C] */ INVALID, INVALID, INVALID, INVALID,12521253/* [70] */ INVALID, INVALID, INVALID, INVALID,1254/* [74] */ INVALID, INVALID, INVALID, INVALID,1255/* [78] */ INVALID, INVALID, INVALID, INVALID,1256/* [7C] */ INVALID, INVALID, INVALID, INVALID,12571258/* [80] */ INVALID, INVALID, INVALID, INVALID,1259/* [84] */ INVALID, INVALID, INVALID, INVALID,1260/* [88] */ INVALID, INVALID, INVALID, INVALID,1261/* [0C] */ INVALID, INVALID, INVALID, INVALID,12621263/* [90] */ INVALID, INVALID, INVALID, INVALID,1264/* [94] */ INVALID, INVALID, INVALID, INVALID,1265/* [98] */ INVALID, INVALID, INVALID, INVALID,1266/* [9C] */ INVALID, INVALID, INVALID, INVALID,12671268/* [A0] */ INVALID, INVALID, INVALID, INVALID,1269/* [A4] */ INVALID, INVALID, INVALID, INVALID,1270/* [A8] */ INVALID, INVALID, INVALID, INVALID,1271/* [AC] */ INVALID, INVALID, INVALID, INVALID,12721273/* [B0] */ INVALID, INVALID, INVALID, INVALID,1274/* [B4] */ INVALID, INVALID, INVALID, INVALID,1275/* [B8] */ INVALID, INVALID, INVALID, INVALID,1276/* [BC] */ INVALID, INVALID, INVALID, INVALID,12771278/* [C0] */ INVALID, INVALID, INVALID, INVALID,1279/* [C4] */ INVALID, INVALID, INVALID, INVALID,1280/* [C8] */ INVALID, INVALID, INVALID, INVALID,1281/* [CC] */ INVALID, INVALID, INVALID, INVALID,12821283/* [D0] */ INVALID, INVALID, INVALID, INVALID,1284/* [D4] */ INVALID, INVALID, INVALID, INVALID,1285/* [D8] */ INVALID, INVALID, INVALID, INVALID,1286/* [DC] */ INVALID, INVALID, INVALID, INVALID,12871288/* [E0] */ INVALID, INVALID, INVALID, INVALID,1289/* [E4] */ INVALID, INVALID, INVALID, INVALID,1290/* [E8] */ INVALID, INVALID, INVALID, INVALID,1291/* [EC] */ INVALID, INVALID, INVALID, INVALID,12921293/* [F0] */ INVALID, INVALID, INVALID, INVALID,1294/* [F4] */ INVALID, TNSZvr("pext",VEX_RMrX,5),INVALID, TNSZvr("sarx",VEX_VRMrX,5),1295/* [F8] */ INVALID, INVALID, INVALID, INVALID,1296/* [FC] */ INVALID, INVALID, INVALID, INVALID,1297};1298/*1299* Decode table for SIMD instructions with the repz (0xf3) prefix.1300*/1301const instable_t dis_opSIMDrepz[256] = {1302/* [00] */ INVALID, INVALID, INVALID, INVALID,1303/* [04] */ INVALID, INVALID, INVALID, INVALID,1304/* [08] */ INVALID, INVALID, INVALID, INVALID,1305/* [0C] */ INVALID, INVALID, INVALID, INVALID,13061307/* [10] */ TNSZ("movss",XMM,4), TNSZ("movss",XMMS,4), TNSZ("movsldup",XMM,16),INVALID,1308/* [14] */ INVALID, INVALID, TNSZ("movshdup",XMM,16),INVALID,1309/* [18] */ INVALID, INVALID, INVALID, INVALID,1310/* [1C] */ INVALID, INVALID, INVALID, INVALID,13111312/* [20] */ INVALID, INVALID, INVALID, INVALID,1313/* [24] */ INVALID, INVALID, INVALID, INVALID,1314/* [28] */ INVALID, INVALID, TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),1315/* [2C] */ TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID, INVALID,13161317/* [30] */ INVALID, INVALID, INVALID, INVALID,1318/* [34] */ INVALID, INVALID, INVALID, INVALID,1319/* [38] */ INVALID, INVALID, INVALID, INVALID,1320/* [3C] */ INVALID, INVALID, INVALID, INVALID,13211322/* [40] */ INVALID, INVALID, INVALID, INVALID,1323/* [44] */ INVALID, INVALID, INVALID, INVALID,1324/* [48] */ INVALID, INVALID, INVALID, INVALID,1325/* [4C] */ INVALID, INVALID, INVALID, INVALID,13261327/* [50] */ INVALID, TNSZ("sqrtss",XMM,4), TNSZ("rsqrtss",XMM,4), TNSZ("rcpss",XMM,4),1328/* [54] */ INVALID, INVALID, INVALID, INVALID,1329/* [58] */ TNSZ("addss",XMM,4), TNSZ("mulss",XMM,4), TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16),1330/* [5C] */ TNSZ("subss",XMM,4), TNSZ("minss",XMM,4), TNSZ("divss",XMM,4), TNSZ("maxss",XMM,4),13311332/* [60] */ INVALID, INVALID, INVALID, INVALID,1333/* [64] */ INVALID, INVALID, INVALID, INVALID,1334/* [68] */ INVALID, INVALID, INVALID, INVALID,1335/* [6C] */ INVALID, INVALID, INVALID, TNSZ("movdqu",XMM,16),13361337/* [70] */ TNSZ("pshufhw",XMMP,16),INVALID, INVALID, INVALID,1338/* [74] */ INVALID, INVALID, INVALID, INVALID,1339/* [78] */ INVALID, INVALID, INVALID, INVALID,1340/* [7C] */ INVALID, INVALID, TNSZ("movq",XMM,8), TNSZ("movdqu",XMMS,16),13411342/* [80] */ INVALID, INVALID, INVALID, INVALID,1343/* [84] */ INVALID, INVALID, INVALID, INVALID,1344/* [88] */ INVALID, INVALID, INVALID, INVALID,1345/* [0C] */ INVALID, INVALID, INVALID, INVALID,13461347/* [90] */ INVALID, INVALID, INVALID, INVALID,1348/* [94] */ INVALID, INVALID, INVALID, INVALID,1349/* [98] */ INVALID, INVALID, INVALID, INVALID,1350/* [9C] */ INVALID, INVALID, INVALID, INVALID,13511352/* [A0] */ INVALID, INVALID, INVALID, INVALID,1353/* [A4] */ INVALID, INVALID, INVALID, INVALID,1354/* [A8] */ INVALID, INVALID, INVALID, INVALID,1355/* [AC] */ INVALID, INVALID, INVALID, INVALID,13561357/* [B0] */ INVALID, INVALID, INVALID, INVALID,1358/* [B4] */ INVALID, INVALID, INVALID, INVALID,1359/* [B8] */ TS("popcnt",MRw), INVALID, INVALID, INVALID,1360/* [BC] */ TNSZ("tzcnt",MRw,5), TS("lzcnt",MRw), INVALID, INVALID,13611362/* [C0] */ INVALID, INVALID, TNSZ("cmpss",XMMP,4), INVALID,1363/* [C4] */ INVALID, INVALID, INVALID, INVALID,1364/* [C8] */ INVALID, INVALID, INVALID, INVALID,1365/* [CC] */ INVALID, INVALID, INVALID, INVALID,13661367/* [D0] */ INVALID, INVALID, INVALID, INVALID,1368/* [D4] */ INVALID, INVALID, TNS("movq2dq",XMMMX), INVALID,1369/* [D8] */ INVALID, INVALID, INVALID, INVALID,1370/* [DC] */ INVALID, INVALID, INVALID, INVALID,13711372/* [E0] */ INVALID, INVALID, INVALID, INVALID,1373/* [E4] */ INVALID, INVALID, TNSZ("cvtdq2pd",XMM,8), INVALID,1374/* [E8] */ INVALID, INVALID, INVALID, INVALID,1375/* [EC] */ INVALID, INVALID, INVALID, INVALID,13761377/* [F0] */ INVALID, INVALID, INVALID, INVALID,1378/* [F4] */ INVALID, INVALID, INVALID, INVALID,1379/* [F8] */ INVALID, INVALID, INVALID, INVALID,1380/* [FC] */ INVALID, INVALID, INVALID, INVALID,1381};13821383const instable_t dis_opAVXF30F[256] = {1384/* [00] */ INVALID, INVALID, INVALID, INVALID,1385/* [04] */ INVALID, INVALID, INVALID, INVALID,1386/* [08] */ INVALID, INVALID, INVALID, INVALID,1387/* [0C] */ INVALID, INVALID, INVALID, INVALID,13881389/* [10] */ TNSZ("vmovss",VEX_RMrX,4), TNSZ("vmovss",VEX_RRX,4), TNSZ("vmovsldup",VEX_MX,4), INVALID,1390/* [14] */ INVALID, INVALID, TNSZ("vmovshdup",VEX_MX,4), INVALID,1391/* [18] */ INVALID, INVALID, INVALID, INVALID,1392/* [1C] */ INVALID, INVALID, INVALID, INVALID,13931394/* [20] */ INVALID, INVALID, INVALID, INVALID,1395/* [24] */ INVALID, INVALID, INVALID, INVALID,1396/* [28] */ INVALID, INVALID, TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,1397/* [2C] */ TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID, INVALID,13981399/* [30] */ INVALID, INVALID, INVALID, INVALID,1400/* [34] */ INVALID, INVALID, INVALID, INVALID,1401/* [38] */ INVALID, INVALID, INVALID, INVALID,1402/* [3C] */ INVALID, INVALID, INVALID, INVALID,14031404/* [40] */ INVALID, INVALID, INVALID, INVALID,1405/* [44] */ INVALID, INVALID, INVALID, INVALID,1406/* [48] */ INVALID, INVALID, INVALID, INVALID,1407/* [4C] */ INVALID, INVALID, INVALID, INVALID,14081409/* [50] */ INVALID, TNSZ("vsqrtss",VEX_RMrX,4), TNSZ("vrsqrtss",VEX_RMrX,4), TNSZ("vrcpss",VEX_RMrX,4),1410/* [54] */ INVALID, INVALID, INVALID, INVALID,1411/* [58] */ TNSZ("vaddss",VEX_RMrX,4), TNSZ("vmulss",VEX_RMrX,4), TNSZ("vcvtss2sd",VEX_RMrX,4), TNSZ("vcvttps2dq",VEX_MX,16),1412/* [5C] */ TNSZ("vsubss",VEX_RMrX,4), TNSZ("vminss",VEX_RMrX,4), TNSZ("vdivss",VEX_RMrX,4), TNSZ("vmaxss",VEX_RMrX,4),14131414/* [60] */ INVALID, INVALID, INVALID, INVALID,1415/* [64] */ INVALID, INVALID, INVALID, INVALID,1416/* [68] */ INVALID, INVALID, INVALID, INVALID,1417/* [6C] */ INVALID, INVALID, INVALID, TNSZ("vmovdqu",VEX_MX,16),14181419/* [70] */ TNSZ("vpshufhw",VEX_MXI,16),INVALID, INVALID, INVALID,1420/* [74] */ INVALID, INVALID, INVALID, INVALID,1421/* [78] */ INVALID, INVALID, INVALID, INVALID,1422/* [7C] */ INVALID, INVALID, TNSZ("vmovq",VEX_MX,8), TNSZ("vmovdqu",VEX_RX,16),14231424/* [80] */ INVALID, INVALID, INVALID, INVALID,1425/* [84] */ INVALID, INVALID, INVALID, INVALID,1426/* [88] */ INVALID, INVALID, INVALID, INVALID,1427/* [0C] */ INVALID, INVALID, INVALID, INVALID,14281429/* [90] */ INVALID, INVALID, INVALID, INVALID,1430/* [94] */ INVALID, INVALID, INVALID, INVALID,1431/* [98] */ INVALID, INVALID, INVALID, INVALID,1432/* [9C] */ INVALID, INVALID, INVALID, INVALID,14331434/* [A0] */ INVALID, INVALID, INVALID, INVALID,1435/* [A4] */ INVALID, INVALID, INVALID, INVALID,1436/* [A8] */ INVALID, INVALID, INVALID, INVALID,1437/* [AC] */ INVALID, INVALID, INVALID, INVALID,14381439/* [B0] */ INVALID, INVALID, INVALID, INVALID,1440/* [B4] */ INVALID, INVALID, INVALID, INVALID,1441/* [B8] */ INVALID, INVALID, INVALID, INVALID,1442/* [BC] */ INVALID, INVALID, INVALID, INVALID,14431444/* [C0] */ INVALID, INVALID, TNSZ("vcmpss",VEX_RMRX,4), INVALID,1445/* [C4] */ INVALID, INVALID, INVALID, INVALID,1446/* [C8] */ INVALID, INVALID, INVALID, INVALID,1447/* [CC] */ INVALID, INVALID, INVALID, INVALID,14481449/* [D0] */ INVALID, INVALID, INVALID, INVALID,1450/* [D4] */ INVALID, INVALID, INVALID, INVALID,1451/* [D8] */ INVALID, INVALID, INVALID, INVALID,1452/* [DC] */ INVALID, INVALID, INVALID, INVALID,14531454/* [E0] */ INVALID, INVALID, INVALID, INVALID,1455/* [E4] */ INVALID, INVALID, TNSZ("vcvtdq2pd",VEX_MX,8), INVALID,1456/* [E8] */ INVALID, INVALID, INVALID, INVALID,1457/* [EC] */ INVALID, INVALID, INVALID, INVALID,14581459/* [F0] */ INVALID, INVALID, INVALID, INVALID,1460/* [F4] */ INVALID, INVALID, INVALID, INVALID,1461/* [F8] */ INVALID, INVALID, INVALID, INVALID,1462/* [FC] */ INVALID, INVALID, INVALID, INVALID,1463};14641465/*1466* Table for instructions with an EVEX prefix followed by 0F.1467*/1468const instable_t dis_opEVEX0F[256] = {1469/* [00] */ INVALID, INVALID, INVALID, INVALID,1470/* [04] */ INVALID, INVALID, INVALID, INVALID,1471/* [08] */ INVALID, INVALID, INVALID, INVALID,1472/* [0C] */ INVALID, INVALID, INVALID, INVALID,14731474/* [10] */ TNS("vmovups",EVEX_MX), TNS("vmovups",EVEX_RX), INVALID, INVALID,1475/* [14] */ INVALID, INVALID, INVALID, INVALID,1476/* [18] */ INVALID, INVALID, INVALID, INVALID,1477/* [1C] */ INVALID, INVALID, INVALID, INVALID,14781479/* [20] */ INVALID, INVALID, INVALID, INVALID,1480/* [24] */ INVALID, INVALID, INVALID, INVALID,1481/* [28] */ TNS("vmovaps",EVEX_MX), TNS("vmovaps",EVEX_RX), INVALID, INVALID,1482/* [2C] */ INVALID, INVALID, INVALID, INVALID,14831484/* [30] */ INVALID, INVALID, INVALID, INVALID,1485/* [34] */ INVALID, INVALID, INVALID, INVALID,1486/* [38] */ INVALID, INVALID, INVALID, INVALID,1487/* [3C] */ INVALID, INVALID, INVALID, INVALID,14881489/* [40] */ INVALID, INVALID, INVALID, INVALID,1490/* [44] */ INVALID, INVALID, INVALID, INVALID,1491/* [48] */ INVALID, INVALID, INVALID, INVALID,1492/* [4C] */ INVALID, INVALID, INVALID, INVALID,14931494/* [50] */ INVALID, INVALID, INVALID, INVALID,1495/* [54] */ TNS("vandps",EVEX_RMrX),TNS("vandnps",EVEX_RMrX),TNS("vorps",EVEX_RMrX),TNS("vxorps",EVEX_RMrX),1496/* [58] */ INVALID, INVALID, INVALID, INVALID,1497/* [5C] */ INVALID, INVALID, INVALID, INVALID,14981499/* [60] */ INVALID, INVALID, INVALID, INVALID,1500/* [64] */ INVALID, INVALID, INVALID, INVALID,1501/* [68] */ INVALID, INVALID, INVALID, INVALID,1502/* [6C] */ INVALID, INVALID, INVALID, INVALID,15031504/* [70] */ INVALID, INVALID, INVALID, INVALID,1505/* [74] */ INVALID, INVALID, INVALID, INVALID,1506/* [78] */ INVALID, INVALID, INVALID, INVALID,1507/* [7C] */ INVALID, INVALID, INVALID, INVALID,15081509/* [80] */ INVALID, INVALID, INVALID, INVALID,1510/* [84] */ INVALID, INVALID, INVALID, INVALID,1511/* [88] */ INVALID, INVALID, INVALID, INVALID,1512/* [0C] */ INVALID, INVALID, INVALID, INVALID,15131514/* [90] */ INVALID, INVALID, INVALID, INVALID,1515/* [94] */ INVALID, INVALID, INVALID, INVALID,1516/* [98] */ INVALID, INVALID, INVALID, INVALID,1517/* [9C] */ INVALID, INVALID, INVALID, INVALID,15181519/* [A0] */ INVALID, INVALID, INVALID, INVALID,1520/* [A4] */ INVALID, INVALID, INVALID, INVALID,1521/* [A8] */ INVALID, INVALID, INVALID, INVALID,1522/* [AC] */ INVALID, INVALID, INVALID, INVALID,15231524/* [B0] */ INVALID, INVALID, INVALID, INVALID,1525/* [B4] */ INVALID, INVALID, INVALID, INVALID,1526/* [B8] */ INVALID, INVALID, INVALID, INVALID,1527/* [BC] */ INVALID, INVALID, INVALID, INVALID,15281529/* [C0] */ INVALID, INVALID, INVALID, INVALID,1530/* [C4] */ INVALID, INVALID, INVALID, INVALID,1531/* [C8] */ INVALID, INVALID, INVALID, INVALID,1532/* [CC] */ INVALID, INVALID, INVALID, INVALID,15331534/* [D0] */ INVALID, INVALID, INVALID, INVALID,1535/* [D4] */ INVALID, INVALID, INVALID, INVALID,1536/* [D8] */ INVALID, INVALID, INVALID, INVALID,1537/* [DC] */ INVALID, INVALID, INVALID, INVALID,15381539/* [E0] */ INVALID, INVALID, INVALID, INVALID,1540/* [E4] */ INVALID, INVALID, INVALID, INVALID,1541/* [E8] */ INVALID, INVALID, INVALID, INVALID,1542/* [EC] */ INVALID, INVALID, INVALID, INVALID,15431544/* [F0] */ INVALID, INVALID, INVALID, INVALID,1545/* [F4] */ INVALID, INVALID, INVALID, INVALID,1546/* [F8] */ INVALID, INVALID, INVALID, INVALID,1547/* [FC] */ INVALID, INVALID, INVALID, INVALID,1548};15491550/*1551* Decode tables for EVEX 66 0F1552*/1553const instable_t dis_opEVEX660F[256] = {1554/* [00] */ INVALID, INVALID, INVALID, INVALID,1555/* [04] */ INVALID, INVALID, INVALID, INVALID,1556/* [08] */ INVALID, INVALID, INVALID, INVALID,1557/* [0C] */ INVALID, INVALID, INVALID, INVALID,15581559/* [10] */ TNS("vmovupd",EVEX_MX), TNS("vmovupd",EVEX_RX), INVALID, INVALID,1560/* [14] */ INVALID, INVALID, INVALID, INVALID,1561/* [18] */ INVALID, INVALID, INVALID, INVALID,1562/* [1C] */ INVALID, INVALID, INVALID, INVALID,15631564/* [20] */ INVALID, INVALID, INVALID, INVALID,1565/* [24] */ INVALID, INVALID, INVALID, INVALID,1566/* [28] */ TNS("vmovapd",EVEX_MX), TNS("vmovapd",EVEX_RX), INVALID, INVALID,1567/* [2C] */ INVALID, INVALID, INVALID, INVALID,15681569/* [30] */ INVALID, INVALID, INVALID, INVALID,1570/* [34] */ INVALID, INVALID, INVALID, INVALID,1571/* [38] */ INVALID, INVALID, INVALID, INVALID,1572/* [3C] */ INVALID, INVALID, INVALID, INVALID,15731574/* [40] */ INVALID, INVALID, INVALID, INVALID,1575/* [44] */ INVALID, INVALID, INVALID, INVALID,1576/* [48] */ INVALID, INVALID, INVALID, INVALID,1577/* [4C] */ INVALID, INVALID, INVALID, INVALID,15781579/* [50] */ INVALID, INVALID, INVALID, INVALID,1580/* [54] */ TNS("vandpd",EVEX_RMrX),TNS("vandnpd",EVEX_RMrX),TNS("vorpd",EVEX_RMrX),TNS("vxorpd",EVEX_RMrX),1581/* [58] */ INVALID, INVALID, INVALID, INVALID,1582/* [5C] */ INVALID, INVALID, INVALID, INVALID,15831584/* [60] */ INVALID, INVALID, INVALID, INVALID,1585/* [64] */ INVALID, INVALID, INVALID, INVALID,1586/* [68] */ INVALID, INVALID, INVALID, INVALID,1587/* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqa",EVEX_MX),15881589/* [70] */ INVALID, INVALID, INVALID, INVALID,1590/* [74] */ INVALID, INVALID, INVALID, INVALID,1591/* [78] */ INVALID, INVALID, INVALID, INVALID,1592/* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqa",EVEX_RX),15931594/* [80] */ INVALID, INVALID, INVALID, INVALID,1595/* [84] */ INVALID, INVALID, INVALID, INVALID,1596/* [88] */ INVALID, INVALID, INVALID, INVALID,1597/* [0C] */ INVALID, INVALID, INVALID, INVALID,15981599/* [90] */ INVALID, INVALID, INVALID, INVALID,1600/* [94] */ INVALID, INVALID, INVALID, INVALID,1601/* [98] */ INVALID, INVALID, INVALID, INVALID,1602/* [9C] */ INVALID, INVALID, INVALID, INVALID,16031604/* [A0] */ INVALID, INVALID, INVALID, INVALID,1605/* [A4] */ INVALID, INVALID, INVALID, INVALID,1606/* [A8] */ INVALID, INVALID, INVALID, INVALID,1607/* [AC] */ INVALID, INVALID, INVALID, INVALID,16081609/* [B0] */ INVALID, INVALID, INVALID, INVALID,1610/* [B4] */ INVALID, INVALID, INVALID, INVALID,1611/* [B8] */ INVALID, INVALID, INVALID, INVALID,1612/* [BC] */ INVALID, INVALID, INVALID, INVALID,16131614/* [C0] */ INVALID, INVALID, INVALID, INVALID,1615/* [C4] */ INVALID, INVALID, INVALID, INVALID,1616/* [C8] */ INVALID, INVALID, INVALID, INVALID,1617/* [CC] */ INVALID, INVALID, INVALID, INVALID,16181619/* [D0] */ INVALID, INVALID, INVALID, INVALID,1620/* [D4] */ INVALID, INVALID, INVALID, INVALID,1621/* [D8] */ INVALID, INVALID, INVALID, TSq("vpand",EVEX_RMrX),1622/* [DC] */ INVALID, INVALID, INVALID, TSq("vpandn",EVEX_RMrX),16231624/* [E0] */ INVALID, INVALID, INVALID, INVALID,1625/* [E4] */ INVALID, INVALID, INVALID, INVALID,1626/* [E8] */ INVALID, INVALID, INVALID, TSq("vpor",EVEX_RMrX),1627/* [EC] */ INVALID, INVALID, INVALID, TSq("vpxor",EVEX_RMrX),16281629/* [F0] */ INVALID, INVALID, INVALID, INVALID,1630/* [F4] */ INVALID, INVALID, INVALID, INVALID,1631/* [F8] */ INVALID, INVALID, INVALID, INVALID,1632/* [FC] */ INVALID, INVALID, INVALID, INVALID,1633};16341635const instable_t dis_opEVEX660F38[256] = {1636/* [00] */ INVALID, INVALID, INVALID, INVALID,1637/* [04] */ INVALID, INVALID, INVALID, INVALID,1638/* [08] */ INVALID, INVALID, INVALID, INVALID,1639/* [0C] */ INVALID, INVALID, INVALID, INVALID,16401641/* [10] */ INVALID, INVALID, INVALID, INVALID,1642/* [14] */ INVALID, INVALID, INVALID, INVALID,1643/* [18] */ INVALID, INVALID, INVALID, INVALID,1644/* [1C] */ INVALID, INVALID, INVALID, INVALID,16451646/* [20] */ INVALID, INVALID, INVALID, INVALID,1647/* [24] */ INVALID, INVALID, INVALID, INVALID,1648/* [28] */ INVALID, INVALID, INVALID, INVALID,1649/* [2C] */ INVALID, INVALID, INVALID, INVALID,16501651/* [30] */ INVALID, INVALID, INVALID, INVALID,1652/* [34] */ INVALID, INVALID, INVALID, INVALID,1653/* [38] */ INVALID, INVALID, INVALID, INVALID,1654/* [3C] */ INVALID, INVALID, INVALID, INVALID,16551656/* [40] */ INVALID, INVALID, INVALID, INVALID,1657/* [44] */ INVALID, INVALID, INVALID, INVALID,1658/* [48] */ INVALID, INVALID, INVALID, INVALID,1659/* [4C] */ INVALID, INVALID, INVALID, INVALID,16601661/* [50] */ TNSZ("vpdpbusd",EVEX_RMrX,16),TNSZ("vpdpbusds",EVEX_RMrX,16),TNSZ("vpdpwssd",EVEX_RMrX,16),TNSZ("vpdpwssds",EVEX_RMrX,16),1662/* [54] */ INVALID, INVALID, INVALID, INVALID,1663/* [58] */ INVALID, INVALID, INVALID, INVALID,1664/* [5C] */ INVALID, INVALID, INVALID, INVALID,16651666/* [60] */ INVALID, INVALID, INVALID, INVALID,1667/* [64] */ INVALID, INVALID, INVALID, INVALID,1668/* [68] */ INVALID, INVALID, INVALID, INVALID,1669/* [6C] */ INVALID, INVALID, INVALID, INVALID,16701671/* [70] */ INVALID, INVALID, INVALID, INVALID,1672/* [74] */ INVALID, INVALID, INVALID, INVALID,1673/* [78] */ INVALID, INVALID, INVALID, INVALID,1674/* [7C] */ INVALID, INVALID, INVALID, INVALID,16751676/* [80] */ INVALID, INVALID, INVALID, INVALID,1677/* [84] */ INVALID, INVALID, INVALID, INVALID,1678/* [88] */ INVALID, INVALID, INVALID, INVALID,1679/* [8C] */ INVALID, INVALID, INVALID, INVALID,16801681/* [90] */ INVALID, INVALID, INVALID, INVALID,1682/* [94] */ INVALID, INVALID, INVALID, INVALID,1683/* [98] */ INVALID, INVALID, INVALID, INVALID,1684/* [9C] */ INVALID, INVALID, INVALID, INVALID,16851686/* [A0] */ INVALID, INVALID, INVALID, INVALID,1687/* [A4] */ INVALID, INVALID, INVALID, INVALID,1688/* [A8] */ INVALID, INVALID, INVALID, INVALID,1689/* [AC] */ INVALID, INVALID, INVALID, INVALID,16901691/* [B0] */ INVALID, INVALID, INVALID, INVALID,1692/* [B4] */ INVALID, INVALID, INVALID, INVALID,1693/* [B8] */ INVALID, INVALID, INVALID, INVALID,1694/* [BC] */ INVALID, INVALID, INVALID, INVALID,16951696/* [C0] */ INVALID, INVALID, INVALID, INVALID,1697/* [C4] */ INVALID, INVALID, INVALID, INVALID,1698/* [C8] */ INVALID, INVALID, INVALID, INVALID,1699/* [CC] */ INVALID, INVALID, INVALID, TNS("vgf2p8mulb",EVEX_RMrX),17001701/* [D0] */ INVALID, INVALID, INVALID, INVALID,1702/* [D4] */ INVALID, INVALID, INVALID, INVALID,1703/* [D8] */ INVALID, INVALID, INVALID, INVALID,1704/* [DC] */ TNSZ("vaesenc",EVEX_RMrX,16),TNSZ("vaesenclast",EVEX_RMrX,16),TNSZ("vaesdec",EVEX_RMrX,16),TNSZ("vaesdeclast",EVEX_RMrX,16),17051706/* [E0] */ INVALID, INVALID, INVALID, INVALID,1707/* [E4] */ INVALID, INVALID, INVALID, INVALID,1708/* [E8] */ INVALID, INVALID, INVALID, INVALID,1709/* [EC] */ INVALID, INVALID, INVALID, INVALID,17101711/* [F0] */ INVALID, INVALID, INVALID, INVALID,1712/* [F4] */ INVALID, INVALID, INVALID, INVALID,1713/* [F8] */ INVALID, INVALID, INVALID, INVALID,1714/* [FC] */ INVALID, INVALID, INVALID, INVALID,1715};17161717const instable_t dis_opEVEX660F3A[256] = {1718/* [00] */ INVALID, INVALID, INVALID, INVALID,1719/* [04] */ INVALID, INVALID, INVALID, INVALID,1720/* [08] */ INVALID, INVALID, INVALID, INVALID,1721/* [0C] */ INVALID, INVALID, INVALID, INVALID,17221723/* [10] */ INVALID, INVALID, INVALID, INVALID,1724/* [14] */ INVALID, INVALID, INVALID, INVALID,1725/* [18] */ INVALID, INVALID, INVALID, INVALID,1726/* [1C] */ INVALID, INVALID, INVALID, INVALID,17271728/* [20] */ INVALID, INVALID, INVALID, INVALID,1729/* [24] */ INVALID, INVALID, INVALID, INVALID,1730/* [28] */ INVALID, INVALID, INVALID, INVALID,1731/* [2C] */ INVALID, INVALID, INVALID, INVALID,17321733/* [30] */ INVALID, INVALID, INVALID, INVALID,1734/* [34] */ INVALID, INVALID, INVALID, INVALID,1735/* [38] */ INVALID, INVALID, INVALID, INVALID,1736/* [3C] */ INVALID, INVALID, INVALID, INVALID,17371738/* [40] */ INVALID, INVALID, INVALID, INVALID,1739/* [44] */ TNSZ("vpclmulqdq",EVEX_RMRX,16),INVALID, INVALID, INVALID,1740/* [48] */ INVALID, INVALID, INVALID, INVALID,1741/* [4C] */ INVALID, INVALID, INVALID, INVALID,17421743/* [50] */ INVALID, INVALID, INVALID, INVALID,1744/* [54] */ INVALID, INVALID, INVALID, INVALID,1745/* [58] */ INVALID, INVALID, INVALID, INVALID,1746/* [5C] */ INVALID, INVALID, INVALID, INVALID,17471748/* [60] */ INVALID, INVALID, INVALID, INVALID,1749/* [64] */ INVALID, INVALID, INVALID, INVALID,1750/* [68] */ INVALID, INVALID, INVALID, INVALID,1751/* [6C] */ INVALID, INVALID, INVALID, INVALID,17521753/* [70] */ INVALID, INVALID, INVALID, INVALID,1754/* [74] */ INVALID, INVALID, INVALID, INVALID,1755/* [78] */ INVALID, INVALID, INVALID, INVALID,1756/* [7C] */ INVALID, INVALID, INVALID, INVALID,17571758/* [80] */ INVALID, INVALID, INVALID, INVALID,1759/* [84] */ INVALID, INVALID, INVALID, INVALID,1760/* [88] */ INVALID, INVALID, INVALID, INVALID,1761/* [8C] */ INVALID, INVALID, INVALID, INVALID,17621763/* [90] */ INVALID, INVALID, INVALID, INVALID,1764/* [94] */ INVALID, INVALID, INVALID, INVALID,1765/* [98] */ INVALID, INVALID, INVALID, INVALID,1766/* [9C] */ INVALID, INVALID, INVALID, INVALID,17671768/* [A0] */ INVALID, INVALID, INVALID, INVALID,1769/* [A4] */ INVALID, INVALID, INVALID, INVALID,1770/* [A8] */ INVALID, INVALID, INVALID, INVALID,1771/* [AC] */ INVALID, INVALID, INVALID, INVALID,17721773/* [B0] */ INVALID, INVALID, INVALID, INVALID,1774/* [B4] */ INVALID, INVALID, INVALID, INVALID,1775/* [B8] */ INVALID, INVALID, INVALID, INVALID,1776/* [BC] */ INVALID, INVALID, INVALID, INVALID,17771778/* [C0] */ INVALID, INVALID, INVALID, INVALID,1779/* [C4] */ INVALID, INVALID, INVALID, INVALID,1780/* [C8] */ INVALID, INVALID, INVALID, INVALID,1781/* [CC] */ INVALID, INVALID, TNS("vgf2p8affineqb",EVEX_RMRX),TNS("vgf2p8affineinvqb",EVEX_RMRX),17821783/* [D0] */ INVALID, INVALID, INVALID, INVALID,1784/* [D4] */ INVALID, INVALID, INVALID, INVALID,1785/* [D8] */ INVALID, INVALID, INVALID, INVALID,1786/* [DC] */ INVALID, INVALID, INVALID, INVALID,17871788/* [E0] */ INVALID, INVALID, INVALID, INVALID,1789/* [E4] */ INVALID, INVALID, INVALID, INVALID,1790/* [E8] */ INVALID, INVALID, INVALID, INVALID,1791/* [EC] */ INVALID, INVALID, INVALID, INVALID,17921793/* [F0] */ INVALID, INVALID, INVALID, INVALID,1794/* [F4] */ INVALID, INVALID, INVALID, INVALID,1795/* [F8] */ INVALID, INVALID, INVALID, INVALID,1796/* [FC] */ INVALID, INVALID, INVALID, INVALID,1797};179817991800const instable_t dis_opEVEXF20F[256] = {1801/* [00] */ INVALID, INVALID, INVALID, INVALID,1802/* [04] */ INVALID, INVALID, INVALID, INVALID,1803/* [08] */ INVALID, INVALID, INVALID, INVALID,1804/* [0C] */ INVALID, INVALID, INVALID, INVALID,18051806/* [10] */ INVALID, INVALID, INVALID, INVALID,1807/* [14] */ INVALID, INVALID, INVALID, INVALID,1808/* [18] */ INVALID, INVALID, INVALID, INVALID,1809/* [1C] */ INVALID, INVALID, INVALID, INVALID,18101811/* [20] */ INVALID, INVALID, INVALID, INVALID,1812/* [24] */ INVALID, INVALID, INVALID, INVALID,1813/* [28] */ INVALID, INVALID, INVALID, INVALID,1814/* [2C] */ INVALID, INVALID, INVALID, INVALID,18151816/* [30] */ INVALID, INVALID, INVALID, INVALID,1817/* [34] */ INVALID, INVALID, INVALID, INVALID,1818/* [38] */ INVALID, INVALID, INVALID, INVALID,1819/* [3C] */ INVALID, INVALID, INVALID, INVALID,18201821/* [40] */ INVALID, INVALID, INVALID, INVALID,1822/* [44] */ INVALID, INVALID, INVALID, INVALID,1823/* [48] */ INVALID, INVALID, INVALID, INVALID,1824/* [4C] */ INVALID, INVALID, INVALID, INVALID,18251826/* [50] */ INVALID, INVALID, INVALID, INVALID,1827/* [54] */ INVALID, INVALID, INVALID, INVALID,1828/* [58] */ INVALID, INVALID, INVALID, INVALID,1829/* [5C] */ INVALID, INVALID, INVALID, INVALID,18301831/* [60] */ INVALID, INVALID, INVALID, INVALID,1832/* [64] */ INVALID, INVALID, INVALID, INVALID,1833/* [68] */ INVALID, INVALID, INVALID, INVALID,1834/* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_MX),18351836/* [70] */ INVALID, INVALID, INVALID, INVALID,1837/* [74] */ INVALID, INVALID, INVALID, INVALID,1838/* [78] */ INVALID, INVALID, INVALID, INVALID,1839/* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_RX),18401841/* [80] */ INVALID, INVALID, INVALID, INVALID,1842/* [84] */ INVALID, INVALID, INVALID, INVALID,1843/* [88] */ INVALID, INVALID, INVALID, INVALID,1844/* [0C] */ INVALID, INVALID, INVALID, INVALID,18451846/* [90] */ INVALID, INVALID, INVALID, INVALID,1847/* [94] */ INVALID, INVALID, INVALID, INVALID,1848/* [98] */ INVALID, INVALID, INVALID, INVALID,1849/* [9C] */ INVALID, INVALID, INVALID, INVALID,18501851/* [A0] */ INVALID, INVALID, INVALID, INVALID,1852/* [A4] */ INVALID, INVALID, INVALID, INVALID,1853/* [A8] */ INVALID, INVALID, INVALID, INVALID,1854/* [AC] */ INVALID, INVALID, INVALID, INVALID,18551856/* [B0] */ INVALID, INVALID, INVALID, INVALID,1857/* [B4] */ INVALID, INVALID, INVALID, INVALID,1858/* [B8] */ INVALID, INVALID, INVALID, INVALID,1859/* [BC] */ INVALID, INVALID, INVALID, INVALID,18601861/* [C0] */ INVALID, INVALID, INVALID, INVALID,1862/* [C4] */ INVALID, INVALID, INVALID, INVALID,1863/* [C8] */ INVALID, INVALID, INVALID, INVALID,1864/* [CC] */ INVALID, INVALID, INVALID, INVALID,18651866/* [D0] */ INVALID, INVALID, INVALID, INVALID,1867/* [D4] */ INVALID, INVALID, INVALID, INVALID,1868/* [D8] */ INVALID, INVALID, INVALID, INVALID,1869/* [DC] */ INVALID, INVALID, INVALID, INVALID,18701871/* [E0] */ INVALID, INVALID, INVALID, INVALID,1872/* [E4] */ INVALID, INVALID, INVALID, INVALID,1873/* [E8] */ INVALID, INVALID, INVALID, INVALID,1874/* [EC] */ INVALID, INVALID, INVALID, INVALID,18751876/* [F0] */ INVALID, INVALID, INVALID, INVALID,1877/* [F4] */ INVALID, INVALID, INVALID, INVALID,1878/* [F8] */ INVALID, INVALID, INVALID, INVALID,1879/* [FC] */ INVALID, INVALID, INVALID, INVALID,1880};18811882const instable_t dis_opEVEXF30F[256] = {1883/* [00] */ INVALID, INVALID, INVALID, INVALID,1884/* [04] */ INVALID, INVALID, INVALID, INVALID,1885/* [08] */ INVALID, INVALID, INVALID, INVALID,1886/* [0C] */ INVALID, INVALID, INVALID, INVALID,18871888/* [10] */ INVALID, INVALID, INVALID, INVALID,1889/* [14] */ INVALID, INVALID, INVALID, INVALID,1890/* [18] */ INVALID, INVALID, INVALID, INVALID,1891/* [1C] */ INVALID, INVALID, INVALID, INVALID,18921893/* [20] */ INVALID, INVALID, INVALID, INVALID,1894/* [24] */ INVALID, INVALID, INVALID, INVALID,1895/* [28] */ INVALID, INVALID, INVALID, INVALID,1896/* [2C] */ INVALID, INVALID, INVALID, INVALID,18971898/* [30] */ INVALID, INVALID, INVALID, INVALID,1899/* [34] */ INVALID, INVALID, INVALID, INVALID,1900/* [38] */ INVALID, INVALID, INVALID, INVALID,1901/* [3C] */ INVALID, INVALID, INVALID, INVALID,19021903/* [40] */ INVALID, INVALID, INVALID, INVALID,1904/* [44] */ INVALID, INVALID, INVALID, INVALID,1905/* [48] */ INVALID, INVALID, INVALID, INVALID,1906/* [4C] */ INVALID, INVALID, INVALID, INVALID,19071908/* [50] */ INVALID, INVALID, INVALID, INVALID,1909/* [54] */ INVALID, INVALID, INVALID, INVALID,1910/* [58] */ INVALID, INVALID, INVALID, INVALID,1911/* [5C] */ INVALID, INVALID, INVALID, INVALID,19121913/* [60] */ INVALID, INVALID, INVALID, INVALID,1914/* [64] */ INVALID, INVALID, INVALID, INVALID,1915/* [68] */ INVALID, INVALID, INVALID, INVALID,1916/* [6C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_MX),19171918/* [70] */ INVALID, INVALID, INVALID, INVALID,1919/* [74] */ INVALID, INVALID, INVALID, INVALID,1920/* [78] */ INVALID, INVALID, INVALID, INVALID,1921/* [7C] */ INVALID, INVALID, INVALID, TNS("vmovdqu",EVEX_RX),19221923/* [80] */ INVALID, INVALID, INVALID, INVALID,1924/* [84] */ INVALID, INVALID, INVALID, INVALID,1925/* [88] */ INVALID, INVALID, INVALID, INVALID,1926/* [0C] */ INVALID, INVALID, INVALID, INVALID,19271928/* [90] */ INVALID, INVALID, INVALID, INVALID,1929/* [94] */ INVALID, INVALID, INVALID, INVALID,1930/* [98] */ INVALID, INVALID, INVALID, INVALID,1931/* [9C] */ INVALID, INVALID, INVALID, INVALID,19321933/* [A0] */ INVALID, INVALID, INVALID, INVALID,1934/* [A4] */ INVALID, INVALID, INVALID, INVALID,1935/* [A8] */ INVALID, INVALID, INVALID, INVALID,1936/* [AC] */ INVALID, INVALID, INVALID, INVALID,19371938/* [B0] */ INVALID, INVALID, INVALID, INVALID,1939/* [B4] */ INVALID, INVALID, INVALID, INVALID,1940/* [B8] */ INVALID, INVALID, INVALID, INVALID,1941/* [BC] */ INVALID, INVALID, INVALID, INVALID,19421943/* [C0] */ INVALID, INVALID, INVALID, INVALID,1944/* [C4] */ INVALID, INVALID, INVALID, INVALID,1945/* [C8] */ INVALID, INVALID, INVALID, INVALID,1946/* [CC] */ INVALID, INVALID, INVALID, INVALID,19471948/* [D0] */ INVALID, INVALID, INVALID, INVALID,1949/* [D4] */ INVALID, INVALID, INVALID, INVALID,1950/* [D8] */ INVALID, INVALID, INVALID, INVALID,1951/* [DC] */ INVALID, INVALID, INVALID, INVALID,19521953/* [E0] */ INVALID, INVALID, INVALID, INVALID,1954/* [E4] */ INVALID, INVALID, INVALID, INVALID,1955/* [E8] */ INVALID, INVALID, INVALID, INVALID,1956/* [EC] */ INVALID, INVALID, INVALID, INVALID,19571958/* [F0] */ INVALID, INVALID, INVALID, INVALID,1959/* [F4] */ INVALID, INVALID, INVALID, INVALID,1960/* [F8] */ INVALID, INVALID, INVALID, INVALID,1961/* [FC] */ INVALID, INVALID, INVALID, INVALID,1962};1963/*1964* The following two tables are used to encode crc32 and movbe1965* since they share the same opcodes.1966*/1967const instable_t dis_op0F38F0[2] = {1968/* [00] */ TNS("crc32b",CRC32),1969TS("movbe",MOVBE),1970};19711972const instable_t dis_op0F38F1[2] = {1973/* [00] */ TS("crc32",CRC32),1974TS("movbe",MOVBE),1975};19761977/*1978* The following table is used to distinguish between adox and adcx which share1979* the same opcodes.1980*/1981const instable_t dis_op0F38F6[2] = {1982/* [00] */ TNS("adcx",ADX),1983TNS("adox",ADX),1984};19851986const instable_t dis_op0F38[256] = {1987/* [00] */ TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),1988/* [04] */ TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),1989/* [08] */ TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),1990/* [0C] */ INVALID, INVALID, INVALID, INVALID,19911992/* [10] */ TNSZ("pblendvb",XMM_66r,16),INVALID, INVALID, INVALID,1993/* [14] */ TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID, TNSZ("ptest",XMM_66r,16),1994/* [18] */ INVALID, INVALID, INVALID, INVALID,1995/* [1C] */ TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,19961997/* [20] */ TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),1998/* [24] */ TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID, INVALID,1999/* [28] */ TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),2000/* [2C] */ INVALID, INVALID, INVALID, INVALID,20012002/* [30] */ TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),2003/* [34] */ TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID, TNSZ("pcmpgtq",XMM_66r,16),2004/* [38] */ TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),2005/* [3C] */ TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),20062007/* [40] */ TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID, INVALID,2008/* [44] */ INVALID, INVALID, INVALID, INVALID,2009/* [48] */ INVALID, INVALID, INVALID, INVALID,2010/* [4C] */ INVALID, INVALID, INVALID, INVALID,20112012/* [50] */ INVALID, INVALID, INVALID, INVALID,2013/* [54] */ INVALID, INVALID, INVALID, INVALID,2014/* [58] */ INVALID, INVALID, INVALID, INVALID,2015/* [5C] */ INVALID, INVALID, INVALID, INVALID,20162017/* [60] */ INVALID, INVALID, INVALID, INVALID,2018/* [64] */ INVALID, INVALID, INVALID, INVALID,2019/* [68] */ INVALID, INVALID, INVALID, INVALID,2020/* [6C] */ INVALID, INVALID, INVALID, INVALID,20212022/* [70] */ INVALID, INVALID, INVALID, INVALID,2023/* [74] */ INVALID, INVALID, INVALID, INVALID,2024/* [78] */ INVALID, INVALID, INVALID, INVALID,2025/* [7C] */ INVALID, INVALID, INVALID, INVALID,20262027/* [80] */ TNSy("invept", RM_66r), TNSy("invvpid", RM_66r),TNSy("invpcid", RM_66r),INVALID,2028/* [84] */ INVALID, INVALID, INVALID, INVALID,2029/* [88] */ INVALID, INVALID, INVALID, INVALID,2030/* [8C] */ INVALID, INVALID, INVALID, INVALID,20312032/* [90] */ INVALID, INVALID, INVALID, INVALID,2033/* [94] */ INVALID, INVALID, INVALID, INVALID,2034/* [98] */ INVALID, INVALID, INVALID, INVALID,2035/* [9C] */ INVALID, INVALID, INVALID, INVALID,20362037/* [A0] */ INVALID, INVALID, INVALID, INVALID,2038/* [A4] */ INVALID, INVALID, INVALID, INVALID,2039/* [A8] */ INVALID, INVALID, INVALID, INVALID,2040/* [AC] */ INVALID, INVALID, INVALID, INVALID,20412042/* [B0] */ INVALID, INVALID, INVALID, INVALID,2043/* [B4] */ INVALID, INVALID, INVALID, INVALID,2044/* [B8] */ INVALID, INVALID, INVALID, INVALID,2045/* [BC] */ INVALID, INVALID, INVALID, INVALID,20462047/* [C0] */ INVALID, INVALID, INVALID, INVALID,2048/* [C4] */ INVALID, INVALID, INVALID, INVALID,2049/* [C8] */ TNSZ("sha1nexte",XMM,16),TNSZ("sha1msg1",XMM,16),TNSZ("sha1msg2",XMM,16),TNSZ("sha256rnds2",XMM,16),2050/* [CC] */ TNSZ("sha256msg1",XMM,16),TNSZ("sha256msg2",XMM,16),INVALID, TNS("gf2p8mulb",XMM_66r),20512052/* [D0] */ INVALID, INVALID, INVALID, INVALID,2053/* [D4] */ INVALID, INVALID, INVALID, INVALID,2054/* [D8] */ INVALID, INVALID, INVALID, TNSZ("aesimc",XMM_66r,16),2055/* [DC] */ TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),20562057/* [E0] */ INVALID, INVALID, INVALID, INVALID,2058/* [E4] */ INVALID, INVALID, INVALID, INVALID,2059/* [E8] */ INVALID, INVALID, INVALID, INVALID,2060/* [EC] */ INVALID, INVALID, INVALID, INVALID,2061/* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID,2062/* [F4] */ INVALID, INVALID, IND(dis_op0F38F6), INVALID,2063/* [F8] */ INVALID, INVALID, INVALID, INVALID,2064/* [FC] */ INVALID, INVALID, INVALID, INVALID,2065};20662067const instable_t dis_opAVX660F38[256] = {2068/* [00] */ TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),2069/* [04] */ TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16), TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),2070/* [08] */ TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),2071/* [0C] */ TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8), TNSZ("vtestpd",VEX_RRI,16),20722073/* [10] */ INVALID, INVALID, INVALID, TNSZ("vcvtph2ps",VEX_MX,16),2074/* [14] */ INVALID, INVALID, TNSZ("vpermps",VEX_RMrX,16),TNSZ("vptest",VEX_RRI,16),2075/* [18] */ TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,2076/* [1C] */ TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,20772078/* [20] */ TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),2079/* [24] */ TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID, INVALID,2080/* [28] */ TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),2081/* [2C] */ TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),20822083/* [30] */ TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),2084/* [34] */ TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),TNSZ("vpermd",VEX_RMrX,16),TNSZ("vpcmpgtq",VEX_RMrX,16),2085/* [38] */ TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),2086/* [3C] */ TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),20872088/* [40] */ TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID, INVALID,2089/* [44] */ INVALID, TSaZ("vpsrlv",VEX_RMrX,16),TNSZ("vpsravd",VEX_RMrX,16),TSaZ("vpsllv",VEX_RMrX,16),2090/* [48] */ INVALID, INVALID, INVALID, INVALID,2091/* [4C] */ INVALID, INVALID, INVALID, INVALID,20922093/* [50] */ INVALID, INVALID, INVALID, INVALID,2094/* [54] */ INVALID, INVALID, INVALID, INVALID,2095/* [58] */ TNSZ("vpbroadcastd",VEX_MX,16),TNSZ("vpbroadcastq",VEX_MX,16),TNSZ("vbroadcasti128",VEX_MX,16),INVALID,2096/* [5C] */ INVALID, INVALID, INVALID, INVALID,20972098/* [60] */ INVALID, INVALID, INVALID, INVALID,2099/* [64] */ INVALID, INVALID, INVALID, INVALID,2100/* [68] */ INVALID, INVALID, INVALID, INVALID,2101/* [6C] */ INVALID, INVALID, INVALID, INVALID,21022103/* [70] */ INVALID, INVALID, INVALID, INVALID,2104/* [74] */ INVALID, INVALID, INVALID, INVALID,2105/* [78] */ TNSZ("vpbroadcastb",VEX_MX,16),TNSZ("vpbroadcastw",VEX_MX,16),INVALID, INVALID,2106/* [7C] */ INVALID, INVALID, INVALID, INVALID,21072108/* [80] */ INVALID, INVALID, INVALID, INVALID,2109/* [84] */ INVALID, INVALID, INVALID, INVALID,2110/* [88] */ INVALID, INVALID, INVALID, INVALID,2111/* [8C] */ TSaZ("vpmaskmov",VEX_RMrX,16),INVALID, TSaZ("vpmaskmov",VEX_RRM,16),INVALID,21122113/* [90] */ TNSZ("vpgatherd",VEX_SbVM,16),TNSZ("vpgatherq",VEX_SbVM,16),TNSZ("vgatherdp",VEX_SbVM,16),TNSZ("vgatherqp",VEX_SbVM,16),2114/* [94] */ INVALID, INVALID, TNSZ("vfmaddsub132p",FMA,16),TNSZ("vfmsubadd132p",FMA,16),2115/* [98] */ TNSZ("vfmadd132p",FMA,16),TNSZ("vfmadd132s",FMA,16),TNSZ("vfmsub132p",FMA,16),TNSZ("vfmsub132s",FMA,16),2116/* [9C] */ TNSZ("vfnmadd132p",FMA,16),TNSZ("vfnmadd132s",FMA,16),TNSZ("vfnmsub132p",FMA,16),TNSZ("vfnmsub132s",FMA,16),21172118/* [A0] */ INVALID, INVALID, INVALID, INVALID,2119/* [A4] */ INVALID, INVALID, TNSZ("vfmaddsub213p",FMA,16),TNSZ("vfmsubadd213p",FMA,16),2120/* [A8] */ TNSZ("vfmadd213p",FMA,16),TNSZ("vfmadd213s",FMA,16),TNSZ("vfmsub213p",FMA,16),TNSZ("vfmsub213s",FMA,16),2121/* [AC] */ TNSZ("vfnmadd213p",FMA,16),TNSZ("vfnmadd213s",FMA,16),TNSZ("vfnmsub213p",FMA,16),TNSZ("vfnmsub213s",FMA,16),21222123/* [B0] */ INVALID, INVALID, INVALID, INVALID,2124/* [B4] */ INVALID, INVALID, TNSZ("vfmaddsub231p",FMA,16),TNSZ("vfmsubadd231p",FMA,16),2125/* [B8] */ TNSZ("vfmadd231p",FMA,16),TNSZ("vfmadd231s",FMA,16),TNSZ("vfmsub231p",FMA,16),TNSZ("vfmsub231s",FMA,16),2126/* [BC] */ TNSZ("vfnmadd231p",FMA,16),TNSZ("vfnmadd231s",FMA,16),TNSZ("vfnmsub231p",FMA,16),TNSZ("vfnmsub231s",FMA,16),21272128/* [C0] */ INVALID, INVALID, INVALID, INVALID,2129/* [C4] */ INVALID, INVALID, INVALID, INVALID,2130/* [C8] */ INVALID, INVALID, INVALID, INVALID,2131/* [CC] */ INVALID, INVALID, INVALID, TNS("vgf2p8mulb",VEX_RMrX),21322133/* [D0] */ INVALID, INVALID, INVALID, INVALID,2134/* [D4] */ INVALID, INVALID, INVALID, INVALID,2135/* [D8] */ INVALID, INVALID, INVALID, TNSZ("vaesimc",VEX_MX,16),2136/* [DC] */ TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),21372138/* [E0] */ INVALID, INVALID, INVALID, INVALID,2139/* [E4] */ INVALID, INVALID, INVALID, INVALID,2140/* [E8] */ INVALID, INVALID, INVALID, INVALID,2141/* [EC] */ INVALID, INVALID, INVALID, INVALID,2142/* [F0] */ IND(dis_op0F38F0), IND(dis_op0F38F1), INVALID, INVALID,2143/* [F4] */ INVALID, INVALID, INVALID, TNSZvr("shlx",VEX_VRMrX,5),2144/* [F8] */ INVALID, INVALID, INVALID, INVALID,2145/* [FC] */ INVALID, INVALID, INVALID, INVALID,2146};21472148const instable_t dis_op0F3A[256] = {2149/* [00] */ INVALID, INVALID, INVALID, INVALID,2150/* [04] */ INVALID, INVALID, INVALID, INVALID,2151/* [08] */ TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),2152/* [0C] */ TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),21532154/* [10] */ INVALID, INVALID, INVALID, INVALID,2155/* [14] */ TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),2156/* [18] */ INVALID, INVALID, INVALID, INVALID,2157/* [1C] */ INVALID, INVALID, INVALID, INVALID,21582159/* [20] */ TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,2160/* [24] */ INVALID, INVALID, INVALID, INVALID,2161/* [28] */ INVALID, INVALID, INVALID, INVALID,2162/* [2C] */ INVALID, INVALID, INVALID, INVALID,21632164/* [30] */ INVALID, INVALID, INVALID, INVALID,2165/* [34] */ INVALID, INVALID, INVALID, INVALID,2166/* [38] */ INVALID, INVALID, INVALID, INVALID,2167/* [3C] */ INVALID, INVALID, INVALID, INVALID,21682169/* [40] */ TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,2170/* [44] */ TNSZ("pclmulqdq",XMMP_66r,16),INVALID, INVALID, INVALID,2171/* [48] */ INVALID, INVALID, INVALID, INVALID,2172/* [4C] */ INVALID, INVALID, INVALID, INVALID,21732174/* [50] */ INVALID, INVALID, INVALID, INVALID,2175/* [54] */ INVALID, INVALID, INVALID, INVALID,2176/* [58] */ INVALID, INVALID, INVALID, INVALID,2177/* [5C] */ INVALID, INVALID, INVALID, INVALID,21782179/* [60] */ TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),2180/* [64] */ INVALID, INVALID, INVALID, INVALID,2181/* [68] */ INVALID, INVALID, INVALID, INVALID,2182/* [6C] */ INVALID, INVALID, INVALID, INVALID,21832184/* [70] */ INVALID, INVALID, INVALID, INVALID,2185/* [74] */ INVALID, INVALID, INVALID, INVALID,2186/* [78] */ INVALID, INVALID, INVALID, INVALID,2187/* [7C] */ INVALID, INVALID, INVALID, INVALID,21882189/* [80] */ INVALID, INVALID, INVALID, INVALID,2190/* [84] */ INVALID, INVALID, INVALID, INVALID,2191/* [88] */ INVALID, INVALID, INVALID, INVALID,2192/* [8C] */ INVALID, INVALID, INVALID, INVALID,21932194/* [90] */ INVALID, INVALID, INVALID, INVALID,2195/* [94] */ INVALID, INVALID, INVALID, INVALID,2196/* [98] */ INVALID, INVALID, INVALID, INVALID,2197/* [9C] */ INVALID, INVALID, INVALID, INVALID,21982199/* [A0] */ INVALID, INVALID, INVALID, INVALID,2200/* [A4] */ INVALID, INVALID, INVALID, INVALID,2201/* [A8] */ INVALID, INVALID, INVALID, INVALID,2202/* [AC] */ INVALID, INVALID, INVALID, INVALID,22032204/* [B0] */ INVALID, INVALID, INVALID, INVALID,2205/* [B4] */ INVALID, INVALID, INVALID, INVALID,2206/* [B8] */ INVALID, INVALID, INVALID, INVALID,2207/* [BC] */ INVALID, INVALID, INVALID, INVALID,22082209/* [C0] */ INVALID, INVALID, INVALID, INVALID,2210/* [C4] */ INVALID, INVALID, INVALID, INVALID,2211/* [C8] */ INVALID, INVALID, INVALID, INVALID,2212/* [CC] */ TNSZ("sha1rnds4",XMMP,16),INVALID, TNS("gf2p8affineqb",XMMP_66r),TNS("gf2p8affineinvqb",XMMP_66r),22132214/* [D0] */ INVALID, INVALID, INVALID, INVALID,2215/* [D4] */ INVALID, INVALID, INVALID, INVALID,2216/* [D8] */ INVALID, INVALID, INVALID, INVALID,2217/* [DC] */ INVALID, INVALID, INVALID, TNSZ("aeskeygenassist",XMMP_66r,16),22182219/* [E0] */ INVALID, INVALID, INVALID, INVALID,2220/* [E4] */ INVALID, INVALID, INVALID, INVALID,2221/* [E8] */ INVALID, INVALID, INVALID, INVALID,2222/* [EC] */ INVALID, INVALID, INVALID, INVALID,22232224/* [F0] */ INVALID, INVALID, INVALID, INVALID,2225/* [F4] */ INVALID, INVALID, INVALID, INVALID,2226/* [F8] */ INVALID, INVALID, INVALID, INVALID,2227/* [FC] */ INVALID, INVALID, INVALID, INVALID,2228};22292230const instable_t dis_opAVX660F3A[256] = {2231/* [00] */ TNSZ("vpermq",VEX_MXI,16),TNSZ("vpermpd",VEX_MXI,16),TNSZ("vpblendd",VEX_RMRX,16),INVALID,2232/* [04] */ TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,2233/* [08] */ TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),2234/* [0C] */ TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),22352236/* [10] */ INVALID, INVALID, INVALID, INVALID,2237/* [14] */ TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),2238/* [18] */ TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID, INVALID,2239/* [1C] */ INVALID, TNSZ("vcvtps2ph",VEX_RX,16), INVALID, INVALID,22402241/* [20] */ TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,2242/* [24] */ INVALID, INVALID, INVALID, INVALID,2243/* [28] */ INVALID, INVALID, INVALID, INVALID,2244/* [2C] */ INVALID, INVALID, INVALID, INVALID,22452246/* [30] */ TSvo("kshiftr",VEX_MXI), TSvo("kshiftr",VEX_MXI), TSvo("kshiftl",VEX_MXI), TSvo("kshiftl",VEX_MXI),2247/* [34] */ INVALID, INVALID, INVALID, INVALID,2248/* [38] */ TNSZ("vinserti128",VEX_RMRX,16),TNSZ("vextracti128",VEX_RIM,16),INVALID, INVALID,2249/* [3C] */ INVALID, INVALID, INVALID, INVALID,22502251/* [40] */ TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,2252/* [44] */ TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID, TNSZ("vperm2i128",VEX_RMRX,16),INVALID,2253/* [48] */ INVALID, INVALID, TNSZ("vblendvps",VEX_RMRX,8), TNSZ("vblendvpd",VEX_RMRX,16),2254/* [4C] */ TNSZ("vpblendvb",VEX_RMRX,16),INVALID, INVALID, INVALID,22552256/* [50] */ INVALID, INVALID, INVALID, INVALID,2257/* [54] */ INVALID, INVALID, INVALID, INVALID,2258/* [58] */ INVALID, INVALID, INVALID, INVALID,2259/* [5C] */ INVALID, INVALID, INVALID, INVALID,22602261/* [60] */ TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),2262/* [64] */ INVALID, INVALID, INVALID, INVALID,2263/* [68] */ INVALID, INVALID, INVALID, INVALID,2264/* [6C] */ INVALID, INVALID, INVALID, INVALID,22652266/* [70] */ INVALID, INVALID, INVALID, INVALID,2267/* [74] */ INVALID, INVALID, INVALID, INVALID,2268/* [78] */ INVALID, INVALID, INVALID, INVALID,2269/* [7C] */ INVALID, INVALID, INVALID, INVALID,22702271/* [80] */ INVALID, INVALID, INVALID, INVALID,2272/* [84] */ INVALID, INVALID, INVALID, INVALID,2273/* [88] */ INVALID, INVALID, INVALID, INVALID,2274/* [8C] */ INVALID, INVALID, INVALID, INVALID,22752276/* [90] */ INVALID, INVALID, INVALID, INVALID,2277/* [94] */ INVALID, INVALID, INVALID, INVALID,2278/* [98] */ INVALID, INVALID, INVALID, INVALID,2279/* [9C] */ INVALID, INVALID, INVALID, INVALID,22802281/* [A0] */ INVALID, INVALID, INVALID, INVALID,2282/* [A4] */ INVALID, INVALID, INVALID, INVALID,2283/* [A8] */ INVALID, INVALID, INVALID, INVALID,2284/* [AC] */ INVALID, INVALID, INVALID, INVALID,22852286/* [B0] */ INVALID, INVALID, INVALID, INVALID,2287/* [B4] */ INVALID, INVALID, INVALID, INVALID,2288/* [B8] */ INVALID, INVALID, INVALID, INVALID,2289/* [BC] */ INVALID, INVALID, INVALID, INVALID,22902291/* [C0] */ INVALID, INVALID, INVALID, INVALID,2292/* [C4] */ INVALID, INVALID, INVALID, INVALID,2293/* [C8] */ INVALID, INVALID, INVALID, INVALID,2294/* [CC] */ INVALID, INVALID, TNS("vgf2p8affineqb",VEX_RMRX),TNS("vgf2p8affineinvqb",VEX_RMRX),22952296/* [D0] */ INVALID, INVALID, INVALID, INVALID,2297/* [D4] */ INVALID, INVALID, INVALID, INVALID,2298/* [D8] */ INVALID, INVALID, INVALID, INVALID,2299/* [DC] */ INVALID, INVALID, INVALID, TNSZ("vaeskeygenassist",VEX_MXI,16),23002301/* [E0] */ INVALID, INVALID, INVALID, INVALID,2302/* [E4] */ INVALID, INVALID, INVALID, INVALID,2303/* [E8] */ INVALID, INVALID, INVALID, INVALID,2304/* [EC] */ INVALID, INVALID, INVALID, INVALID,23052306/* [F0] */ INVALID, INVALID, INVALID, INVALID,2307/* [F4] */ INVALID, INVALID, INVALID, INVALID,2308/* [F8] */ INVALID, INVALID, INVALID, INVALID,2309/* [FC] */ INVALID, INVALID, INVALID, INVALID,2310};23112312/*2313* Decode table for 0x0F0D which uses the first byte of the mod_rm to2314* indicate a sub-code.2315*/2316const instable_t dis_op0F0D[8] = {2317/* [00] */ INVALID, TNS("prefetchw",PREF), TNS("prefetchwt1",PREF),INVALID,2318/* [04] */ INVALID, INVALID, INVALID, INVALID,2319};23202321/*2322* Decode table for 0x0F opcodes2323*/23242325const instable_t dis_op0F[16][16] = {2326{2327/* [00] */ IND(dis_op0F00), IND(dis_op0F01), TNS("lar",MR), TNS("lsl",MR),2328/* [04] */ INVALID, TNS("syscall",NORM), TNS("clts",NORM), TNS("sysret",NORM),2329/* [08] */ TNS("invd",NORM), TNS("wbinvd",NORM), INVALID, TNS("ud2",NORM),2330/* [0C] */ INVALID, IND(dis_op0F0D), INVALID, INVALID,2331}, {2332/* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8),2333/* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),2334/* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID,2335/* [1C] */ INVALID, INVALID, INVALID, TS("nop",Mw),2336}, {2337/* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG),2338/* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID,2339/* [28] */ TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),2340/* [2C] */ TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),2341}, {2342/* [30] */ TNS("wrmsr",NORM), TNS("rdtsc",NORM), TNS("rdmsr",NORM), TNS("rdpmc",NORM),2343/* [34] */ TNS("sysenter",NORM), TNS("sysexit",NORM), INVALID, INVALID,2344/* [38] */ INVALID, INVALID, INVALID, INVALID,2345/* [3C] */ INVALID, INVALID, INVALID, INVALID,2346}, {2347/* [40] */ TS("cmovx.o",MR), TS("cmovx.no",MR), TS("cmovx.b",MR), TS("cmovx.ae",MR),2348/* [44] */ TS("cmovx.e",MR), TS("cmovx.ne",MR), TS("cmovx.be",MR), TS("cmovx.a",MR),2349/* [48] */ TS("cmovx.s",MR), TS("cmovx.ns",MR), TS("cmovx.pe",MR), TS("cmovx.po",MR),2350/* [4C] */ TS("cmovx.l",MR), TS("cmovx.ge",MR), TS("cmovx.le",MR), TS("cmovx.g",MR),2351}, {2352/* [50] */ TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),2353/* [54] */ TNSZ("andps",XMMO,16), TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16), TNSZ("xorps",XMMO,16),2354/* [58] */ TNSZ("addps",XMMO,16), TNSZ("mulps",XMMO,16), TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),2355/* [5C] */ TNSZ("subps",XMMO,16), TNSZ("minps",XMMO,16), TNSZ("divps",XMMO,16), TNSZ("maxps",XMMO,16),2356}, {2357/* [60] */ TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),2358/* [64] */ TNSZ("pcmpgtb",MMO,8), TNSZ("pcmpgtw",MMO,8), TNSZ("pcmpgtd",MMO,8), TNSZ("packuswb",MMO,8),2359/* [68] */ TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),2360/* [6C] */ TNSZ("INVALID",MMO,0), TNSZ("INVALID",MMO,0), TNSZ("movd",MMO,4), TNSZ("movq",MMO,8),2361}, {2362/* [70] */ TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR), TNS("psrXXX",MR), TNS("psrXXX",MR),2363/* [74] */ TNSZ("pcmpeqb",MMO,8), TNSZ("pcmpeqw",MMO,8), TNSZ("pcmpeqd",MMO,8), TNS("emms",NORM),2364/* [78] */ TNSy("vmread",RM), TNSy("vmwrite",MR), INVALID, INVALID,2365/* [7C] */ INVALID, INVALID, TNSZ("movd",MMOS,4), TNSZ("movq",MMOS,8),2366}, {2367/* [80] */ TNS("jo",D), TNS("jno",D), TNS("jb",D), TNS("jae",D),2368/* [84] */ TNS("je",D), TNS("jne",D), TNS("jbe",D), TNS("ja",D),2369/* [88] */ TNS("js",D), TNS("jns",D), TNS("jp",D), TNS("jnp",D),2370/* [8C] */ TNS("jl",D), TNS("jge",D), TNS("jle",D), TNS("jg",D),2371}, {2372/* [90] */ TNS("seto",Mb), TNS("setno",Mb), TNS("setb",Mb), TNS("setae",Mb),2373/* [94] */ TNS("sete",Mb), TNS("setne",Mb), TNS("setbe",Mb), TNS("seta",Mb),2374/* [98] */ TNS("sets",Mb), TNS("setns",Mb), TNS("setp",Mb), TNS("setnp",Mb),2375/* [9C] */ TNS("setl",Mb), TNS("setge",Mb), TNS("setle",Mb), TNS("setg",Mb),2376}, {2377/* [A0] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("cpuid",NORM), TS("bt",RMw),2378/* [A4] */ TS("shld",DSHIFT), TS("shld",DSHIFTcl), INVALID, INVALID,2379/* [A8] */ TSp("push",LSEG), TSp("pop",LSEG), TNS("rsm",NORM), TS("bts",RMw),2380/* [AC] */ TS("shrd",DSHIFT), TS("shrd",DSHIFTcl), IND(dis_op0FAE), TS("imul",MRw),2381}, {2382/* [B0] */ TNS("cmpxchgb",RMw), TS("cmpxchg",RMw), TS("lss",MR), TS("btr",RMw),2383/* [B4] */ TS("lfs",MR), TS("lgs",MR), TS("movzb",MOVZ), TNS("movzwl",MOVZ),2384/* [B8] */ TNS("INVALID",MRw), INVALID, IND(dis_op0FBA), TS("btc",RMw),2385/* [BC] */ TS("bsf",MRw), TS("bsr",MRw), TS("movsb",MOVZ), TNS("movswl",MOVZ),2386}, {2387/* [C0] */ TNS("xaddb",XADDB), TS("xadd",RMw), TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),2388/* [C4] */ TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),2389/* [C8] */ INVALID, INVALID, INVALID, INVALID,2390/* [CC] */ INVALID, INVALID, INVALID, INVALID,2391}, {2392/* [D0] */ INVALID, TNSZ("psrlw",MMO,8), TNSZ("psrld",MMO,8), TNSZ("psrlq",MMO,8),2393/* [D4] */ TNSZ("paddq",MMO,8), TNSZ("pmullw",MMO,8), TNSZ("INVALID",MMO,0), TNS("pmovmskb",MMOM3),2394/* [D8] */ TNSZ("psubusb",MMO,8), TNSZ("psubusw",MMO,8), TNSZ("pminub",MMO,8), TNSZ("pand",MMO,8),2395/* [DC] */ TNSZ("paddusb",MMO,8), TNSZ("paddusw",MMO,8), TNSZ("pmaxub",MMO,8), TNSZ("pandn",MMO,8),2396}, {2397/* [E0] */ TNSZ("pavgb",MMO,8), TNSZ("psraw",MMO,8), TNSZ("psrad",MMO,8), TNSZ("pavgw",MMO,8),2398/* [E4] */ TNSZ("pmulhuw",MMO,8), TNSZ("pmulhw",MMO,8), TNS("INVALID",XMMO), TNSZ("movntq",MMOMS,8),2399/* [E8] */ TNSZ("psubsb",MMO,8), TNSZ("psubsw",MMO,8), TNSZ("pminsw",MMO,8), TNSZ("por",MMO,8),2400/* [EC] */ TNSZ("paddsb",MMO,8), TNSZ("paddsw",MMO,8), TNSZ("pmaxsw",MMO,8), TNSZ("pxor",MMO,8),2401}, {2402/* [F0] */ INVALID, TNSZ("psllw",MMO,8), TNSZ("pslld",MMO,8), TNSZ("psllq",MMO,8),2403/* [F4] */ TNSZ("pmuludq",MMO,8), TNSZ("pmaddwd",MMO,8), TNSZ("psadbw",MMO,8), TNSZ("maskmovq",MMOIMPL,8),2404/* [F8] */ TNSZ("psubb",MMO,8), TNSZ("psubw",MMO,8), TNSZ("psubd",MMO,8), TNSZ("psubq",MMO,8),2405/* [FC] */ TNSZ("paddb",MMO,8), TNSZ("paddw",MMO,8), TNSZ("paddd",MMO,8), INVALID,2406} };24072408const instable_t dis_opAVX0F[16][16] = {2409{2410/* [00] */ INVALID, INVALID, INVALID, INVALID,2411/* [04] */ INVALID, INVALID, INVALID, INVALID,2412/* [08] */ INVALID, INVALID, INVALID, INVALID,2413/* [0C] */ INVALID, INVALID, INVALID, INVALID,2414}, {2415/* [10] */ TNSZ("vmovups",VEX_MX,16), TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8), TNSZ("vmovlps",VEX_RM,8),2416/* [14] */ TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),2417/* [18] */ INVALID, INVALID, INVALID, INVALID,2418/* [1C] */ INVALID, INVALID, INVALID, INVALID,2419}, {2420/* [20] */ INVALID, INVALID, INVALID, INVALID,2421/* [24] */ INVALID, INVALID, INVALID, INVALID,2422/* [28] */ TNSZ("vmovaps",VEX_MX,16), TNSZ("vmovaps",VEX_RX,16),INVALID, TNSZ("vmovntps",VEX_RM,16),2423/* [2C] */ INVALID, INVALID, TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),2424}, {2425/* [30] */ INVALID, INVALID, INVALID, INVALID,2426/* [34] */ INVALID, INVALID, INVALID, INVALID,2427/* [38] */ INVALID, INVALID, INVALID, INVALID,2428/* [3C] */ INVALID, INVALID, INVALID, INVALID,2429}, {2430/* [40] */ INVALID, TSvo("kand",VEX_RMX), TSvo("kandn",VEX_RMX), INVALID,2431/* [44] */ TSvo("knot",VEX_MX), TSvo("kor",VEX_RMX), TSvo("kxnor",VEX_RMX), TSvo("kxor",VEX_RMX),2432/* [48] */ INVALID, INVALID, TSvo("kadd",VEX_RMX), TSvo("kunpck",VEX_RMX),2433/* [4C] */ INVALID, INVALID, INVALID, INVALID,2434}, {2435/* [50] */ TNS("vmovmskps",VEX_MR), TNSZ("vsqrtps",VEX_MX,16), TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),2436/* [54] */ TNSZ("vandps",VEX_RMrX,16), TNSZ("vandnps",VEX_RMrX,16), TNSZ("vorps",VEX_RMrX,16), TNSZ("vxorps",VEX_RMrX,16),2437/* [58] */ TNSZ("vaddps",VEX_RMrX,16), TNSZ("vmulps",VEX_RMrX,16), TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),2438/* [5C] */ TNSZ("vsubps",VEX_RMrX,16), TNSZ("vminps",VEX_RMrX,16), TNSZ("vdivps",VEX_RMrX,16), TNSZ("vmaxps",VEX_RMrX,16),2439}, {2440/* [60] */ INVALID, INVALID, INVALID, INVALID,2441/* [64] */ INVALID, INVALID, INVALID, INVALID,2442/* [68] */ INVALID, INVALID, INVALID, INVALID,2443/* [6C] */ INVALID, INVALID, INVALID, INVALID,2444}, {2445/* [70] */ INVALID, INVALID, INVALID, INVALID,2446/* [74] */ INVALID, INVALID, INVALID, TNS("vzeroupper", VEX_NONE),2447/* [78] */ INVALID, INVALID, INVALID, INVALID,2448/* [7C] */ INVALID, INVALID, INVALID, INVALID,2449}, {2450/* [80] */ INVALID, INVALID, INVALID, INVALID,2451/* [84] */ INVALID, INVALID, INVALID, INVALID,2452/* [88] */ INVALID, INVALID, INVALID, INVALID,2453/* [8C] */ INVALID, INVALID, INVALID, INVALID,2454}, {2455/* [90] */ TSvo("kmov",VEX_KRM), TSvo("kmov",VEX_KMR), TSvo("kmov",VEX_KRR), TSvo("kmov",VEX_MR),2456/* [94] */ INVALID, INVALID, INVALID, INVALID,2457/* [98] */ TSvo("kortest",VEX_MX), TSvo("ktest",VEX_MX), INVALID, INVALID,2458/* [9C] */ INVALID, INVALID, INVALID, INVALID,2459}, {2460/* [A0] */ INVALID, INVALID, INVALID, INVALID,2461/* [A4] */ INVALID, INVALID, INVALID, INVALID,2462/* [A8] */ INVALID, INVALID, INVALID, INVALID,2463/* [AC] */ INVALID, INVALID, TNSZ("vldmxcsr",VEX_MO,2), INVALID,2464}, {2465/* [B0] */ INVALID, INVALID, INVALID, INVALID,2466/* [B4] */ INVALID, INVALID, INVALID, INVALID,2467/* [B8] */ INVALID, INVALID, INVALID, INVALID,2468/* [BC] */ INVALID, INVALID, INVALID, INVALID,2469}, {2470/* [C0] */ INVALID, INVALID, TNSZ("vcmpps",VEX_RMRX,16),INVALID,2471/* [C4] */ INVALID, INVALID, TNSZ("vshufps",VEX_RMRX,16),INVALID,2472/* [C8] */ INVALID, INVALID, INVALID, INVALID,2473/* [CC] */ INVALID, INVALID, INVALID, INVALID,2474}, {2475/* [D0] */ INVALID, INVALID, INVALID, INVALID,2476/* [D4] */ INVALID, INVALID, INVALID, INVALID,2477/* [D8] */ INVALID, INVALID, INVALID, INVALID,2478/* [DC] */ INVALID, INVALID, INVALID, INVALID,2479}, {2480/* [E0] */ INVALID, INVALID, INVALID, INVALID,2481/* [E4] */ INVALID, INVALID, INVALID, INVALID,2482/* [E8] */ INVALID, INVALID, INVALID, INVALID,2483/* [EC] */ INVALID, INVALID, INVALID, INVALID,2484}, {2485/* [F0] */ INVALID, INVALID, TNSZvr("andn",VEX_RMrX,5),TNSZvr("bls",BLS,5),2486/* [F4] */ INVALID, TNSZvr("bzhi",VEX_VRMrX,5),INVALID, TNSZvr("bextr",VEX_VRMrX,5),2487/* [F8] */ INVALID, INVALID, INVALID, INVALID,2488/* [FC] */ INVALID, INVALID, INVALID, INVALID,2489} };24902491/*2492* Decode table for 0x80 opcodes2493*/24942495const instable_t dis_op80[8] = {24962497/* [0] */ TNS("addb",IMlw), TNS("orb",IMw), TNS("adcb",IMlw), TNS("sbbb",IMlw),2498/* [4] */ TNS("andb",IMw), TNS("subb",IMlw), TNS("xorb",IMw), TNS("cmpb",IMlw),2499};250025012502/*2503* Decode table for 0x81 opcodes.2504*/25052506const instable_t dis_op81[8] = {25072508/* [0] */ TS("add",IMlw), TS("or",IMw), TS("adc",IMlw), TS("sbb",IMlw),2509/* [4] */ TS("and",IMw), TS("sub",IMlw), TS("xor",IMw), TS("cmp",IMlw),2510};251125122513/*2514* Decode table for 0x82 opcodes.2515*/25162517const instable_t dis_op82[8] = {25182519/* [0] */ TNSx("addb",IMlw), TNSx("orb",IMlw), TNSx("adcb",IMlw), TNSx("sbbb",IMlw),2520/* [4] */ TNSx("andb",IMlw), TNSx("subb",IMlw), TNSx("xorb",IMlw), TNSx("cmpb",IMlw),2521};2522/*2523* Decode table for 0x83 opcodes.2524*/25252526const instable_t dis_op83[8] = {25272528/* [0] */ TS("add",IMlw), TS("or",IMlw), TS("adc",IMlw), TS("sbb",IMlw),2529/* [4] */ TS("and",IMlw), TS("sub",IMlw), TS("xor",IMlw), TS("cmp",IMlw),2530};25312532/*2533* Decode table for 0xC0 opcodes.2534*/25352536const instable_t dis_opC0[8] = {25372538/* [0] */ TNS("rolb",MvI), TNS("rorb",MvI), TNS("rclb",MvI), TNS("rcrb",MvI),2539/* [4] */ TNS("shlb",MvI), TNS("shrb",MvI), INVALID, TNS("sarb",MvI),2540};25412542/*2543* Decode table for 0xD0 opcodes.2544*/25452546const instable_t dis_opD0[8] = {25472548/* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv),2549/* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv),2550};25512552/*2553* Decode table for 0xC1 opcodes.2554* 186 instruction set2555*/25562557const instable_t dis_opC1[8] = {25582559/* [0] */ TS("rol",MvI), TS("ror",MvI), TS("rcl",MvI), TS("rcr",MvI),2560/* [4] */ TS("shl",MvI), TS("shr",MvI), TS("sal",MvI), TS("sar",MvI),2561};25622563/*2564* Decode table for 0xD1 opcodes.2565*/25662567const instable_t dis_opD1[8] = {25682569/* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv),2570/* [4] */ TS("shl",Mv), TS("shr",Mv), TS("sal",Mv), TS("sar",Mv),2571};257225732574/*2575* Decode table for 0xD2 opcodes.2576*/25772578const instable_t dis_opD2[8] = {25792580/* [0] */ TNS("rolb",Mv), TNS("rorb",Mv), TNS("rclb",Mv), TNS("rcrb",Mv),2581/* [4] */ TNS("shlb",Mv), TNS("shrb",Mv), TNS("salb",Mv), TNS("sarb",Mv),2582};2583/*2584* Decode table for 0xD3 opcodes.2585*/25862587const instable_t dis_opD3[8] = {25882589/* [0] */ TS("rol",Mv), TS("ror",Mv), TS("rcl",Mv), TS("rcr",Mv),2590/* [4] */ TS("shl",Mv), TS("shr",Mv), TS("salb",Mv), TS("sar",Mv),2591};259225932594/*2595* Decode table for 0xF6 opcodes.2596*/25972598const instable_t dis_opF6[8] = {25992600/* [0] */ TNS("testb",IMw), TNS("testb",IMw), TNS("notb",Mw), TNS("negb",Mw),2601/* [4] */ TNS("mulb",MA), TNS("imulb",MA), TNS("divb",MA), TNS("idivb",MA),2602};260326042605/*2606* Decode table for 0xF7 opcodes.2607*/26082609const instable_t dis_opF7[8] = {26102611/* [0] */ TS("test",IMw), TS("test",IMw), TS("not",Mw), TS("neg",Mw),2612/* [4] */ TS("mul",MA), TS("imul",MA), TS("div",MA), TS("idiv",MA),2613};261426152616/*2617* Decode table for 0xFE opcodes.2618*/26192620const instable_t dis_opFE[8] = {26212622/* [0] */ TNS("incb",Mw), TNS("decb",Mw), INVALID, INVALID,2623/* [4] */ INVALID, INVALID, INVALID, INVALID,2624};2625/*2626* Decode table for 0xFF opcodes.2627*/26282629const instable_t dis_opFF[8] = {26302631/* [0] */ TS("inc",Mw), TS("dec",Mw), TNSyp("call",INM), TNS("lcall",INM),2632/* [4] */ TNSy("jmp",INM), TNS("ljmp",INM), TSp("push",M), INVALID,2633};26342635/* for 287 instructions, which are a mess to decode */26362637const instable_t dis_opFP1n2[8][8] = {2638{2639/* bit pattern: 1101 1xxx MODxx xR/M */2640/* [0,0] */ TNS("fadds",M), TNS("fmuls",M), TNS("fcoms",M), TNS("fcomps",M),2641/* [0,4] */ TNS("fsubs",M), TNS("fsubrs",M), TNS("fdivs",M), TNS("fdivrs",M),2642}, {2643/* [1,0] */ TNS("flds",M), INVALID, TNS("fsts",M), TNS("fstps",M),2644/* [1,4] */ TNSZ("fldenv",M,28), TNSZ("fldcw",M,2), TNSZ("fnstenv",M,28), TNSZ("fnstcw",M,2),2645}, {2646/* [2,0] */ TNS("fiaddl",M), TNS("fimull",M), TNS("ficoml",M), TNS("ficompl",M),2647/* [2,4] */ TNS("fisubl",M), TNS("fisubrl",M), TNS("fidivl",M), TNS("fidivrl",M),2648}, {2649/* [3,0] */ TNS("fildl",M), TNSZ("tisttpl",M,4), TNS("fistl",M), TNS("fistpl",M),2650/* [3,4] */ INVALID, TNSZ("fldt",M,10), INVALID, TNSZ("fstpt",M,10),2651}, {2652/* [4,0] */ TNSZ("faddl",M,8), TNSZ("fmull",M,8), TNSZ("fcoml",M,8), TNSZ("fcompl",M,8),2653/* [4,1] */ TNSZ("fsubl",M,8), TNSZ("fsubrl",M,8), TNSZ("fdivl",M,8), TNSZ("fdivrl",M,8),2654}, {2655/* [5,0] */ TNSZ("fldl",M,8), TNSZ("fisttpll",M,8), TNSZ("fstl",M,8), TNSZ("fstpl",M,8),2656/* [5,4] */ TNSZ("frstor",M,108), INVALID, TNSZ("fnsave",M,108), TNSZ("fnstsw",M,2),2657}, {2658/* [6,0] */ TNSZ("fiadd",M,2), TNSZ("fimul",M,2), TNSZ("ficom",M,2), TNSZ("ficomp",M,2),2659/* [6,4] */ TNSZ("fisub",M,2), TNSZ("fisubr",M,2), TNSZ("fidiv",M,2), TNSZ("fidivr",M,2),2660}, {2661/* [7,0] */ TNSZ("fild",M,2), TNSZ("fisttp",M,2), TNSZ("fist",M,2), TNSZ("fistp",M,2),2662/* [7,4] */ TNSZ("fbld",M,10), TNSZ("fildll",M,8), TNSZ("fbstp",M,10), TNSZ("fistpll",M,8),2663} };26642665const instable_t dis_opFP3[8][8] = {2666{2667/* bit pattern: 1101 1xxx 11xx xREG */2668/* [0,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F),2669/* [0,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF),2670}, {2671/* [1,0] */ TNS("fld",F), TNS("fxch",F), TNS("fnop",NORM), TNS("fstp",F),2672/* [1,4] */ INVALID, INVALID, INVALID, INVALID,2673}, {2674/* [2,0] */ INVALID, INVALID, INVALID, INVALID,2675/* [2,4] */ INVALID, TNS("fucompp",NORM), INVALID, INVALID,2676}, {2677/* [3,0] */ INVALID, INVALID, INVALID, INVALID,2678/* [3,4] */ INVALID, INVALID, INVALID, INVALID,2679}, {2680/* [4,0] */ TNS("fadd",FF), TNS("fmul",FF), TNS("fcom",F), TNS("fcomp",F),2681/* [4,4] */ TNS("fsub",FF), TNS("fsubr",FF), TNS("fdiv",FF), TNS("fdivr",FF),2682}, {2683/* [5,0] */ TNS("ffree",F), TNS("fxch",F), TNS("fst",F), TNS("fstp",F),2684/* [5,4] */ TNS("fucom",F), TNS("fucomp",F), INVALID, INVALID,2685}, {2686/* [6,0] */ TNS("faddp",FF), TNS("fmulp",FF), TNS("fcomp",F), TNS("fcompp",NORM),2687/* [6,4] */ TNS("fsubp",FF), TNS("fsubrp",FF), TNS("fdivp",FF), TNS("fdivrp",FF),2688}, {2689/* [7,0] */ TNS("ffreep",F), TNS("fxch",F), TNS("fstp",F), TNS("fstp",F),2690/* [7,4] */ TNS("fnstsw",M), TNS("fucomip",FFC), TNS("fcomip",FFC), INVALID,2691} };26922693const instable_t dis_opFP4[4][8] = {2694{2695/* bit pattern: 1101 1001 111x xxxx */2696/* [0,0] */ TNS("fchs",NORM), TNS("fabs",NORM), INVALID, INVALID,2697/* [0,4] */ TNS("ftst",NORM), TNS("fxam",NORM), TNS("ftstp",NORM), INVALID,2698}, {2699/* [1,0] */ TNS("fld1",NORM), TNS("fldl2t",NORM), TNS("fldl2e",NORM), TNS("fldpi",NORM),2700/* [1,4] */ TNS("fldlg2",NORM), TNS("fldln2",NORM), TNS("fldz",NORM), INVALID,2701}, {2702/* [2,0] */ TNS("f2xm1",NORM), TNS("fyl2x",NORM), TNS("fptan",NORM), TNS("fpatan",NORM),2703/* [2,4] */ TNS("fxtract",NORM), TNS("fprem1",NORM), TNS("fdecstp",NORM), TNS("fincstp",NORM),2704}, {2705/* [3,0] */ TNS("fprem",NORM), TNS("fyl2xp1",NORM), TNS("fsqrt",NORM), TNS("fsincos",NORM),2706/* [3,4] */ TNS("frndint",NORM), TNS("fscale",NORM), TNS("fsin",NORM), TNS("fcos",NORM),2707} };27082709const instable_t dis_opFP5[8] = {2710/* bit pattern: 1101 1011 111x xxxx */2711/* [0] */ TNS("feni",NORM), TNS("fdisi",NORM), TNS("fnclex",NORM), TNS("fninit",NORM),2712/* [4] */ TNS("fsetpm",NORM), TNS("frstpm",NORM), INVALID, INVALID,2713};27142715const instable_t dis_opFP6[8] = {2716/* bit pattern: 1101 1011 11yy yxxx */2717/* [00] */ TNS("fcmov.nb",FF), TNS("fcmov.ne",FF), TNS("fcmov.nbe",FF), TNS("fcmov.nu",FF),2718/* [04] */ INVALID, TNS("fucomi",F), TNS("fcomi",F), INVALID,2719};27202721const instable_t dis_opFP7[8] = {2722/* bit pattern: 1101 1010 11yy yxxx */2723/* [00] */ TNS("fcmov.b",FF), TNS("fcmov.e",FF), TNS("fcmov.be",FF), TNS("fcmov.u",FF),2724/* [04] */ INVALID, INVALID, INVALID, INVALID,2725};27262727/*2728* Main decode table for the op codes. The first two nibbles2729* will be used as an index into the table. If there is a2730* a need to further decode an instruction, the array to be2731* referenced is indicated with the other two entries being2732* empty.2733*/27342735const instable_t dis_distable[16][16] = {2736{2737/* [0,0] */ TNS("addb",RMw), TS("add",RMw), TNS("addb",MRw), TS("add",MRw),2738/* [0,4] */ TNS("addb",IA), TS("add",IA), TSx("push",SEG), TSx("pop",SEG),2739/* [0,8] */ TNS("orb",RMw), TS("or",RMw), TNS("orb",MRw), TS("or",MRw),2740/* [0,C] */ TNS("orb",IA), TS("or",IA), TSx("push",SEG), IND(dis_op0F),2741}, {2742/* [1,0] */ TNS("adcb",RMw), TS("adc",RMw), TNS("adcb",MRw), TS("adc",MRw),2743/* [1,4] */ TNS("adcb",IA), TS("adc",IA), TSx("push",SEG), TSx("pop",SEG),2744/* [1,8] */ TNS("sbbb",RMw), TS("sbb",RMw), TNS("sbbb",MRw), TS("sbb",MRw),2745/* [1,C] */ TNS("sbbb",IA), TS("sbb",IA), TSx("push",SEG), TSx("pop",SEG),2746}, {2747/* [2,0] */ TNS("andb",RMw), TS("and",RMw), TNS("andb",MRw), TS("and",MRw),2748/* [2,4] */ TNS("andb",IA), TS("and",IA), TNSx("%es:",OVERRIDE), TNSx("daa",NORM),2749/* [2,8] */ TNS("subb",RMw), TS("sub",RMw), TNS("subb",MRw), TS("sub",MRw),2750/* [2,C] */ TNS("subb",IA), TS("sub",IA), TNS("%cs:",OVERRIDE), TNSx("das",NORM),2751}, {2752/* [3,0] */ TNS("xorb",RMw), TS("xor",RMw), TNS("xorb",MRw), TS("xor",MRw),2753/* [3,4] */ TNS("xorb",IA), TS("xor",IA), TNSx("%ss:",OVERRIDE), TNSx("aaa",NORM),2754/* [3,8] */ TNS("cmpb",RMw), TS("cmp",RMw), TNS("cmpb",MRw), TS("cmp",MRw),2755/* [3,C] */ TNS("cmpb",IA), TS("cmp",IA), TNSx("%ds:",OVERRIDE), TNSx("aas",NORM),2756}, {2757/* [4,0] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),2758/* [4,4] */ TSx("inc",R), TSx("inc",R), TSx("inc",R), TSx("inc",R),2759/* [4,8] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R),2760/* [4,C] */ TSx("dec",R), TSx("dec",R), TSx("dec",R), TSx("dec",R),2761}, {2762/* [5,0] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R),2763/* [5,4] */ TSp("push",R), TSp("push",R), TSp("push",R), TSp("push",R),2764/* [5,8] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R),2765/* [5,C] */ TSp("pop",R), TSp("pop",R), TSp("pop",R), TSp("pop",R),2766}, {2767/* [6,0] */ TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",RM), TNS("arpl",RMw),2768/* [6,4] */ TNS("%fs:",OVERRIDE), TNS("%gs:",OVERRIDE), TNS("data16",DM), TNS("addr16",AM),2769/* [6,8] */ TSp("push",I), TS("imul",IMUL), TSp("push",Ib), TS("imul",IMUL),2770/* [6,C] */ TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4), TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),2771}, {2772/* [7,0] */ TNSy("jo",BD), TNSy("jno",BD), TNSy("jb",BD), TNSy("jae",BD),2773/* [7,4] */ TNSy("je",BD), TNSy("jne",BD), TNSy("jbe",BD), TNSy("ja",BD),2774/* [7,8] */ TNSy("js",BD), TNSy("jns",BD), TNSy("jp",BD), TNSy("jnp",BD),2775/* [7,C] */ TNSy("jl",BD), TNSy("jge",BD), TNSy("jle",BD), TNSy("jg",BD),2776}, {2777/* [8,0] */ IND(dis_op80), IND(dis_op81), INDx(dis_op82), IND(dis_op83),2778/* [8,4] */ TNS("testb",RMw), TS("test",RMw), TNS("xchgb",RMw), TS("xchg",RMw),2779/* [8,8] */ TNS("movb",RMw), TS("mov",RMw), TNS("movb",MRw), TS("mov",MRw),2780/* [8,C] */ TNS("movw",SM), TS("lea",MR), TNS("movw",MS), TSp("pop",M),2781}, {2782/* [9,0] */ TNS("nop",NORM), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA),2783/* [9,4] */ TS("xchg",RA), TS("xchg",RA), TS("xchg",RA), TS("xchg",RA),2784/* [9,8] */ TNS("cXtX",CBW), TNS("cXtX",CWD), TNSx("lcall",SO), TNS("fwait",NORM),2785/* [9,C] */ TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNS("sahf",NORM), TNS("lahf",NORM),2786}, {2787/* [A,0] */ TNS("movb",OA), TS("mov",OA), TNS("movb",AO), TS("mov",AO),2788/* [A,4] */ TNSZ("movsb",SD,1), TS("movs",SD), TNSZ("cmpsb",SD,1), TS("cmps",SD),2789/* [A,8] */ TNS("testb",IA), TS("test",IA), TNS("stosb",AD), TS("stos",AD),2790/* [A,C] */ TNS("lodsb",SA), TS("lods",SA), TNS("scasb",AD), TS("scas",AD),2791}, {2792/* [B,0] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR),2793/* [B,4] */ TNS("movb",IR), TNS("movb",IR), TNS("movb",IR), TNS("movb",IR),2794/* [B,8] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR),2795/* [B,C] */ TS("mov",IR), TS("mov",IR), TS("mov",IR), TS("mov",IR),2796}, {2797/* [C,0] */ IND(dis_opC0), IND(dis_opC1), TNSyp("ret",RET), TNSyp("ret",NORM),2798/* [C,4] */ TNSx("les",MR), TNSx("lds",MR), TNS("movb",IMw), TS("mov",IMw),2799/* [C,8] */ TNSyp("enter",ENTER), TNSyp("leave",NORM), TNS("lret",RET), TNS("lret",NORM),2800/* [C,C] */ TNS("int",INT3), TNS("int",INTx), TNSx("into",NORM), TNS("iret",NORM),2801}, {2802/* [D,0] */ IND(dis_opD0), IND(dis_opD1), IND(dis_opD2), IND(dis_opD3),2803/* [D,4] */ TNSx("aam",U), TNSx("aad",U), TNSx("falc",NORM), TNSZ("xlat",IMPLMEM,1),28042805/* 287 instructions. Note that although the indirect field */2806/* indicates opFP1n2 for further decoding, this is not necessarily */2807/* the case since the opFP arrays are not partitioned according to key1 */2808/* and key2. opFP1n2 is given only to indicate that we haven't */2809/* finished decoding the instruction. */2810/* [D,8] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2),2811/* [D,C] */ IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2), IND(dis_opFP1n2),2812}, {2813/* [E,0] */ TNSy("loopnz",BD), TNSy("loopz",BD), TNSy("loop",BD), TNSy("jcxz",BD),2814/* [E,4] */ TNS("inb",P), TS("in",P), TNS("outb",P), TS("out",P),2815/* [E,8] */ TNSyp("call",D), TNSy("jmp",D), TNSx("ljmp",SO), TNSy("jmp",BD),2816/* [E,C] */ TNS("inb",V), TS("in",V), TNS("outb",V), TS("out",V),2817}, {2818/* [F,0] */ TNS("lock",LOCK), TNS("icebp", NORM), TNS("repnz",PREFIX), TNS("repz",PREFIX),2819/* [F,4] */ TNS("hlt",NORM), TNS("cmc",NORM), IND(dis_opF6), IND(dis_opF7),2820/* [F,8] */ TNS("clc",NORM), TNS("stc",NORM), TNS("cli",NORM), TNS("sti",NORM),2821/* [F,C] */ TNS("cld",NORM), TNS("std",NORM), IND(dis_opFE), IND(dis_opFF),2822} };28232824/* END CSTYLED */28252826/*2827* common functions to decode and disassemble an x86 or amd64 instruction2828*/28292830/*2831* These are the individual fields of a REX prefix. Note that a REX2832* prefix with none of these set is still needed to:2833* - use the MOVSXD (sign extend 32 to 64 bits) instruction2834* - access the %sil, %dil, %bpl, %spl registers2835*/2836#define REX_W 0x08 /* 64 bit operand size when set */2837#define REX_R 0x04 /* high order bit extension of ModRM reg field */2838#define REX_X 0x02 /* high order bit extension of SIB index field */2839#define REX_B 0x01 /* extends ModRM r_m, SIB base, or opcode reg */28402841/*2842* These are the individual fields of a VEX/EVEX prefix.2843*/2844#define VEX_R 0x08 /* REX.R in 1's complement form */2845#define VEX_X 0x04 /* REX.X in 1's complement form */2846#define VEX_B 0x02 /* REX.B in 1's complement form */28472848/* Additional EVEX prefix definitions */2849#define EVEX_R 0x01 /* REX.R' in 1's complement form */2850#define EVEX_OPREG_MASK 0x7 /* bit mask for selecting opmask register number */2851#define EVEX_ZERO_MASK 0x80 /* bit mask for selecting zeroing */28522853/* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */2854#define VEX_L 0x042855/* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector, 2: 512-bit */2856#define EVEX_L 0x06 /* bit mask for EVEX.L'L vector length/RC */2857#define VEX_W 0x08 /* opcode specific, use like REX.W */2858#define VEX_m 0x1F /* VEX m-mmmm field */2859#define EVEX_m 0x3 /* EVEX mm field */2860#define VEX_v 0x78 /* VEX/EVEX register specifier */2861#define VEX_p 0x03 /* VEX pp field, opcode extension */28622863/* VEX m-mmmm field, only used by three bytes prefix */2864#define VEX_m_0F 0x01 /* implied 0F leading opcode byte */2865#define VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */2866#define VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */28672868/* VEX pp field, providing equivalent functionality of a SIMD prefix */2869#define VEX_p_66 0x012870#define VEX_p_F3 0x022871#define VEX_p_F2 0x0328722873/*2874* Even in 64 bit mode, usually only 4 byte immediate operands are supported.2875*/2876static int isize[] = {1, 2, 4, 4};2877static int isize64[] = {1, 2, 4, 8};28782879/*2880* Just a bunch of useful macros.2881*/2882#define WBIT(x) (x & 0x1) /* to get w bit */2883#define REGNO(x) (x & 0x7) /* to get 3 bit register */2884#define VBIT(x) ((x)>>1 & 0x1) /* to get 'v' bit */2885#define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)2886#define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)28872888#define REG_ONLY 3 /* mode to indicate a register operand (not memory) */28892890#define BYTE_OPND 0 /* w-bit value indicating byte register */2891#define LONG_OPND 1 /* w-bit value indicating opnd_size register */2892#define MM_OPND 2 /* "value" used to indicate a mmx reg */2893#define XMM_OPND 3 /* "value" used to indicate a xmm reg */2894#define SEG_OPND 4 /* "value" used to indicate a segment reg */2895#define CONTROL_OPND 5 /* "value" used to indicate a control reg */2896#define DEBUG_OPND 6 /* "value" used to indicate a debug reg */2897#define TEST_OPND 7 /* "value" used to indicate a test reg */2898#define WORD_OPND 8 /* w-bit value indicating word size reg */2899#define YMM_OPND 9 /* "value" used to indicate a ymm reg */2900#define KOPMASK_OPND 10 /* "value" used to indicate an opmask reg */2901#define ZMM_OPND 11 /* "value" used to indicate a zmm reg */29022903/*2904* The AVX2 gather instructions are a bit of a mess. While there's a pattern,2905* there's not really a consistent scheme that we can use to know what the mode2906* is supposed to be for a given type. Various instructions, like VPGATHERDD,2907* always match the value of VEX_L. Other instructions like VPGATHERDQ, have2908* some registers match VEX_L, but the VSIB is always XMM.2909*2910* The simplest way to deal with this is to just define a table based on the2911* instruction opcodes, which are 0x90-0x93, so we subtract 0x90 to index into2912* them.2913*2914* We further have to subdivide this based on the value of VEX_W and the value2915* of VEX_L. The array is constructed to be indexed as:2916* [opcode - 0x90][VEX_W][VEX_L].2917*/2918/* w = 0, 0x90 */2919typedef struct dis_gather_regs {2920uint_t dgr_arg0; /* src reg */2921uint_t dgr_arg1; /* vsib reg */2922uint_t dgr_arg2; /* dst reg */2923char *dgr_suffix; /* suffix to append */2924} dis_gather_regs_t;29252926static dis_gather_regs_t dis_vgather[4][2][2] = {2927{2928/* op 0x90, W.0 */2929{2930{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },2931{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }2932},2933/* op 0x90, W.1 */2934{2935{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },2936{ YMM_OPND, XMM_OPND, YMM_OPND, "q" }2937}2938},2939{2940/* op 0x91, W.0 */2941{2942{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },2943{ XMM_OPND, YMM_OPND, XMM_OPND, "d" },2944},2945/* op 0x91, W.1 */2946{2947{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },2948{ YMM_OPND, YMM_OPND, YMM_OPND, "q" },2949}2950},2951{2952/* op 0x92, W.0 */2953{2954{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },2955{ YMM_OPND, YMM_OPND, YMM_OPND, "s" }2956},2957/* op 0x92, W.1 */2958{2959{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },2960{ YMM_OPND, XMM_OPND, YMM_OPND, "d" }2961}2962},2963{2964/* op 0x93, W.0 */2965{2966{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },2967{ XMM_OPND, YMM_OPND, XMM_OPND, "s" }2968},2969/* op 0x93, W.1 */2970{2971{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },2972{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }2973}2974}2975};29762977/*2978* Get the next byte and separate the op code into the high and low nibbles.2979*/2980static int2981dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)2982{2983int byte;29842985/*2986* x86 instructions have a maximum length of 15 bytes. Bail out if2987* we try to read more.2988*/2989if (x->d86_len >= 15)2990return (x->d86_error = 1);29912992if (x->d86_error)2993return (1);2994byte = x->d86_get_byte(x->d86_data);2995if (byte < 0)2996return (x->d86_error = 1);2997x->d86_bytes[x->d86_len++] = byte;2998*low = byte & 0xf; /* ----xxxx low 4 bits */2999*high = byte >> 4 & 0xf; /* xxxx---- bits 7 to 4 */3000return (0);3001}30023003/*3004* Get and decode an SIB (scaled index base) byte3005*/3006static void3007dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)3008{3009int byte;30103011if (x->d86_error)3012return;30133014byte = x->d86_get_byte(x->d86_data);3015if (byte < 0) {3016x->d86_error = 1;3017return;3018}3019x->d86_bytes[x->d86_len++] = byte;30203021*base = byte & 0x7;3022*index = (byte >> 3) & 0x7;3023*ss = (byte >> 6) & 0x3;3024}30253026/*3027* Get the byte following the op code and separate it into the3028* mode, register, and r/m fields.3029*/3030static void3031dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)3032{3033if (x->d86_got_modrm == 0) {3034if (x->d86_rmindex == -1)3035x->d86_rmindex = x->d86_len;3036dtrace_get_SIB(x, mode, reg, r_m);3037x->d86_got_modrm = 1;3038}3039}30403041/*3042* Adjust register selection based on any REX prefix bits present.3043*/3044/*ARGSUSED*/3045static void3046dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)3047{3048if (reg != NULL && r_m == NULL) {3049if (rex_prefix & REX_B)3050*reg += 8;3051} else {3052if (reg != NULL && (REX_R & rex_prefix) != 0)3053*reg += 8;3054if (r_m != NULL && (REX_B & rex_prefix) != 0)3055*r_m += 8;3056}3057}30583059/*3060* Adjust register selection based on any VEX prefix bits present.3061* Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix3062*/3063/*ARGSUSED*/3064static void3065dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)3066{3067if (reg != NULL && r_m == NULL) {3068if (!(vex_byte1 & VEX_B))3069*reg += 8;3070} else {3071if (reg != NULL && ((VEX_R & vex_byte1) == 0))3072*reg += 8;3073if (r_m != NULL && ((VEX_B & vex_byte1) == 0))3074*r_m += 8;3075}3076}30773078/*3079* Adjust the instruction mnemonic with the appropriate suffix.3080*/3081/* ARGSUSED */3082static void3083dtrace_evex_mnem_adjust(dis86_t *x, const instable_t *dp, uint_t vex_W,3084uint_t evex_byte2)3085{3086#ifdef DIS_TEXT3087if (dp == &dis_opEVEX660F[0x7f] || /* vmovdqa */3088dp == &dis_opEVEX660F[0x6f]) {3089(void) strlcat(x->d86_mnem, vex_W != 0 ? "64" : "32",3090OPLEN);3091}30923093if (dp == &dis_opEVEXF20F[0x7f] || /* vmovdqu */3094dp == &dis_opEVEXF20F[0x6f] ||3095dp == &dis_opEVEXF30F[0x7f] ||3096dp == &dis_opEVEXF30F[0x6f]) {3097switch (evex_byte2 & 0x81) {3098case 0x0:3099(void) strlcat(x->d86_mnem, "32", OPLEN);3100break;3101case 0x1:3102(void) strlcat(x->d86_mnem, "8", OPLEN);3103break;3104case 0x80:3105(void) strlcat(x->d86_mnem, "64", OPLEN);3106break;3107case 0x81:3108(void) strlcat(x->d86_mnem, "16", OPLEN);3109break;3110}3111}31123113if (dp->it_avxsuf == AVS5Q) {3114(void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",3115OPLEN);3116}3117#endif3118}31193120/*3121* The following three functions adjust the register selection based on any3122* EVEX prefix bits present. See Intel 64 and IA-32 Architectures Software3123* Developer’s Manual Volume 2 (IASDv2), section 2.6.1 Table 2-30 and3124* section 2.6.2 Table 2-31.3125*/3126static void3127dtrace_evex_adjust_reg(uint_t evex_byte1, uint_t *reg)3128{3129if (reg != NULL) {3130if ((VEX_R & evex_byte1) == 0) {3131*reg += 8;3132}3133if ((EVEX_R & evex_byte1) == 0) {3134*reg += 16;3135}3136}3137}31383139static void3140dtrace_evex_adjust_rm(uint_t evex_byte1, uint_t *r_m)3141{3142if (r_m != NULL) {3143if ((VEX_B & evex_byte1) == 0) {3144*r_m += 8;3145}3146if ((VEX_X & evex_byte1) == 0) {3147*r_m += 16;3148}3149}3150}31513152/*3153* Use evex_L to set wbit. See IASDv2 Section 2.6.10 and Table 2-36.3154*/3155static void3156dtrace_evex_adjust_reg_name(uint_t evex_L, uint_t *wbitp)3157{3158switch (evex_L) {3159case 0x0:3160*wbitp = XMM_OPND;3161break;3162case 0x1:3163*wbitp = YMM_OPND;3164break;3165case 0x2:3166*wbitp = ZMM_OPND;3167break;3168}3169}31703171/*3172* Adjust operand value for disp8*N immediate. See IASDv2 Section 2.6.5.3173* This currently only handles a subset of the possibilities.3174*/3175static void3176dtrace_evex_adjust_disp8_n(dis86_t *x, int opindex, uint_t L, uint_t modrm)3177{3178d86opnd_t *opnd = &x->d86_opnd[opindex];31793180if (x->d86_error)3181return;31823183/* Check disp8 bit in the ModR/M byte */3184if ((modrm & 0x80) == 0x80)3185return;31863187/* use evex_L to adjust the value */3188switch (L) {3189case 0x0:3190opnd->d86_value *= 16;3191break;3192case 0x1:3193opnd->d86_value *= 32;3194break;3195case 0x2:3196opnd->d86_value *= 64;3197break;3198}3199}32003201/*3202* Adjust target for opmask and zeroing. See IASDv2 Section 2.6.1 Table 2-30.3203*/3204/* ARGSUSED */3205static void3206dtrace_evex_adjust_z_opmask(dis86_t *x, uint_t tgtop, uint_t evex_byte3)3207{3208#ifdef DIS_TEXT3209char *opnd = x->d86_opnd[tgtop].d86_opnd;3210int opmask_reg = evex_byte3 & EVEX_OPREG_MASK;3211#endif3212if (x->d86_error)3213return;32143215#ifdef DIS_TEXT3216if (opmask_reg != 0) {3217/* Append the opmask register to operand 1 */3218(void) strlcat(opnd, "{", OPLEN);3219(void) strlcat(opnd, dis_KOPMASKREG[opmask_reg], OPLEN);3220(void) strlcat(opnd, "}", OPLEN);3221}3222if ((evex_byte3 & EVEX_ZERO_MASK) != 0) {3223/* Append the 'zeroing' modifier to operand 1 */3224(void) strlcat(opnd, "{z}", OPLEN);3225}3226#endif /* DIS_TEXT */3227}32283229/*3230* Get an immediate operand of the given size, with sign extension.3231*/3232static void3233dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)3234{3235int i;3236int byte;3237int valsize;32383239if (x->d86_numopnds < opindex + 1)3240x->d86_numopnds = opindex + 1;32413242switch (wbit) {3243case BYTE_OPND:3244valsize = 1;3245break;3246case LONG_OPND:3247if (x->d86_opnd_size == SIZE16)3248valsize = 2;3249else if (x->d86_opnd_size == SIZE32)3250valsize = 4;3251else3252valsize = 8;3253break;3254case MM_OPND:3255case XMM_OPND:3256case YMM_OPND:3257case ZMM_OPND:3258case SEG_OPND:3259case CONTROL_OPND:3260case DEBUG_OPND:3261case TEST_OPND:3262valsize = size;3263break;3264case WORD_OPND:3265valsize = 2;3266break;3267}3268if (valsize < size)3269valsize = size;32703271if (x->d86_error)3272return;3273x->d86_opnd[opindex].d86_value = 0;3274for (i = 0; i < size; ++i) {3275byte = x->d86_get_byte(x->d86_data);3276if (byte < 0) {3277x->d86_error = 1;3278return;3279}3280x->d86_bytes[x->d86_len++] = byte;3281x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);3282}3283/* Do sign extension */3284if (x->d86_bytes[x->d86_len - 1] & 0x80) {3285for (; i < sizeof (uint64_t); i++)3286x->d86_opnd[opindex].d86_value |=3287(uint64_t)0xff << (i * 8);3288}3289#ifdef DIS_TEXT3290x->d86_opnd[opindex].d86_mode = MODE_SIGNED;3291x->d86_opnd[opindex].d86_value_size = valsize;3292x->d86_imm_bytes += size;3293#endif3294}32953296/*3297* Get an ip relative operand of the given size, with sign extension.3298*/3299static void3300dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)3301{3302dtrace_imm_opnd(x, wbit, size, opindex);3303#ifdef DIS_TEXT3304x->d86_opnd[opindex].d86_mode = MODE_IPREL;3305#endif3306}33073308/*3309* Check to see if there is a segment override prefix pending.3310* If so, print it in the current 'operand' location and set3311* the override flag back to false.3312*/3313/*ARGSUSED*/3314static void3315dtrace_check_override(dis86_t *x, int opindex)3316{3317#ifdef DIS_TEXT3318if (x->d86_seg_prefix) {3319(void) strlcat(x->d86_opnd[opindex].d86_prefix,3320x->d86_seg_prefix, PFIXLEN);3321}3322#endif3323x->d86_seg_prefix = NULL;3324}332533263327/*3328* Process a single instruction Register or Memory operand.3329*3330* mode = addressing mode from ModRM byte3331* r_m = r_m (or reg if mode == 3) field from ModRM byte3332* wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.3333* o = index of operand that we are processing (0, 1 or 2)3334*3335* the value of reg or r_m must have already been adjusted for any REX prefix.3336*/3337/*ARGSUSED*/3338static void3339dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)3340{3341int have_SIB = 0; /* flag presence of scale-index-byte */3342uint_t ss; /* scale-factor from opcode */3343uint_t index; /* index register number */3344uint_t base; /* base register number */3345int dispsize; /* size of displacement in bytes */3346#ifdef DIS_TEXT3347char *opnd = x->d86_opnd[opindex].d86_opnd;3348#endif33493350if (x->d86_numopnds < opindex + 1)3351x->d86_numopnds = opindex + 1;33523353if (x->d86_error)3354return;33553356/*3357* first handle a simple register3358*/3359if (mode == REG_ONLY) {3360#ifdef DIS_TEXT3361switch (wbit) {3362case MM_OPND:3363(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);3364break;3365case XMM_OPND:3366(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);3367break;3368case YMM_OPND:3369(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);3370break;3371case ZMM_OPND:3372(void) strlcat(opnd, dis_ZMMREG[r_m], OPLEN);3373break;3374case KOPMASK_OPND:3375(void) strlcat(opnd, dis_KOPMASKREG[r_m], OPLEN);3376break;3377case SEG_OPND:3378(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);3379break;3380case CONTROL_OPND:3381(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);3382break;3383case DEBUG_OPND:3384(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);3385break;3386case TEST_OPND:3387(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);3388break;3389case BYTE_OPND:3390if (x->d86_rex_prefix == 0)3391(void) strlcat(opnd, dis_REG8[r_m], OPLEN);3392else3393(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);3394break;3395case WORD_OPND:3396(void) strlcat(opnd, dis_REG16[r_m], OPLEN);3397break;3398case LONG_OPND:3399if (x->d86_opnd_size == SIZE16)3400(void) strlcat(opnd, dis_REG16[r_m], OPLEN);3401else if (x->d86_opnd_size == SIZE32)3402(void) strlcat(opnd, dis_REG32[r_m], OPLEN);3403else3404(void) strlcat(opnd, dis_REG64[r_m], OPLEN);3405break;3406}3407#endif /* DIS_TEXT */3408return;3409}34103411/*3412* if symbolic representation, skip override prefix, if any3413*/3414dtrace_check_override(x, opindex);34153416/*3417* Handle 16 bit memory references first, since they decode3418* the mode values more simply.3419* mode 1 is r_m + 8 bit displacement3420* mode 2 is r_m + 16 bit displacement3421* mode 0 is just r_m, unless r_m is 6 which is 16 bit disp3422*/3423if (x->d86_addr_size == SIZE16) {3424if ((mode == 0 && r_m == 6) || mode == 2)3425dtrace_imm_opnd(x, WORD_OPND, 2, opindex);3426else if (mode == 1)3427dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);3428#ifdef DIS_TEXT3429if (mode == 0 && r_m == 6)3430x->d86_opnd[opindex].d86_mode = MODE_SIGNED;3431else if (mode == 0)3432x->d86_opnd[opindex].d86_mode = MODE_NONE;3433else3434x->d86_opnd[opindex].d86_mode = MODE_OFFSET;3435(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);3436#endif3437return;3438}34393440/*3441* 32 and 64 bit addressing modes are more complex since they can3442* involve an SIB (scaled index and base) byte to decode. When using VEX3443* and EVEX encodings, the r_m indicator for a SIB may be offset by 83444* and 24 (8 + 16) respectively.3445*/3446if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8 || r_m == ESP_REGNO + 24) {3447have_SIB = 1;3448dtrace_get_SIB(x, &ss, &index, &base);3449if (x->d86_error)3450return;3451if (base != 5 || mode != 0)3452if (x->d86_rex_prefix & REX_B)3453base += 8;3454if (x->d86_rex_prefix & REX_X)3455index += 8;3456} else {3457base = r_m;3458}34593460/*3461* Compute the displacement size and get its bytes3462*/3463dispsize = 0;34643465if (mode == 1)3466dispsize = 1;3467else if (mode == 2)3468dispsize = 4;3469else if ((r_m & 7) == EBP_REGNO ||3470(have_SIB && (base & 7) == EBP_REGNO))3471dispsize = 4;34723473if (dispsize > 0) {3474dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,3475dispsize, opindex);3476if (x->d86_error)3477return;3478}34793480#ifdef DIS_TEXT3481if (dispsize > 0)3482x->d86_opnd[opindex].d86_mode = MODE_OFFSET;34833484if (have_SIB == 0) {3485if (x->d86_mode == SIZE32) {3486if (mode == 0)3487(void) strlcat(opnd, dis_addr32_mode0[r_m],3488OPLEN);3489else3490(void) strlcat(opnd, dis_addr32_mode12[r_m],3491OPLEN);3492} else {3493if (mode == 0) {3494(void) strlcat(opnd, dis_addr64_mode0[r_m],3495OPLEN);3496if (r_m == 5) {3497x->d86_opnd[opindex].d86_mode =3498MODE_RIPREL;3499}3500} else {3501(void) strlcat(opnd, dis_addr64_mode12[r_m],3502OPLEN);3503}3504}3505} else {3506uint_t need_paren = 0;3507char **regs;3508char **bregs;3509const char *const *sf;3510if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */3511regs = (char **)dis_REG32;3512else3513regs = (char **)dis_REG64;35143515if (x->d86_vsib != 0) {3516if (wbit == YMM_OPND) { /* NOTE this is not addr_size */3517bregs = (char **)dis_YMMREG;3518} else if (wbit == XMM_OPND) {3519bregs = (char **)dis_XMMREG;3520} else {3521bregs = (char **)dis_ZMMREG;3522}3523sf = dis_vscale_factor;3524} else {3525bregs = regs;3526sf = dis_scale_factor;3527}35283529/*3530* print the base (if any)3531*/3532if (base == EBP_REGNO && mode == 0) {3533if (index != ESP_REGNO || x->d86_vsib != 0) {3534(void) strlcat(opnd, "(", OPLEN);3535need_paren = 1;3536}3537} else {3538(void) strlcat(opnd, "(", OPLEN);3539(void) strlcat(opnd, regs[base], OPLEN);3540need_paren = 1;3541}35423543/*3544* print the index (if any)3545*/3546if (index != ESP_REGNO || x->d86_vsib) {3547(void) strlcat(opnd, ",", OPLEN);3548(void) strlcat(opnd, bregs[index], OPLEN);3549(void) strlcat(opnd, sf[ss], OPLEN);3550} else3551if (need_paren)3552(void) strlcat(opnd, ")", OPLEN);3553}3554#endif3555}35563557/*3558* Operand sequence for standard instruction involving one register3559* and one register/memory operand.3560* wbit indicates a byte(0) or opnd_size(1) operation3561* vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")3562*/3563#define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit) { \3564dtrace_get_modrm(x, &mode, ®, &r_m); \3565dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \3566dtrace_get_operand(x, mode, r_m, wbit, vbit); \3567dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit); \3568}35693570/*3571* Similar to above, but allows for the two operands to be of different3572* classes (ie. wbit).3573* wbit is for the r_m operand3574* w2 is for the reg operand3575*/3576#define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) { \3577dtrace_get_modrm(x, &mode, ®, &r_m); \3578dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \3579dtrace_get_operand(x, mode, r_m, wbit, vbit); \3580dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit); \3581}35823583/*3584* Similar, but for 2 operands plus an immediate.3585* vbit indicates direction3586* 0 for "opcode imm, r, r_m" or3587* 1 for "opcode imm, r_m, r"3588*/3589#define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \3590dtrace_get_modrm(x, &mode, ®, &r_m); \3591dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \3592dtrace_get_operand(x, mode, r_m, wbit, 2-vbit); \3593dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit); \3594dtrace_imm_opnd(x, wbit, immsize, 0); \3595}35963597/*3598* Similar, but for 2 operands plus two immediates.3599*/3600#define FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \3601dtrace_get_modrm(x, &mode, ®, &r_m); \3602dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \3603dtrace_get_operand(x, mode, r_m, wbit, 2); \3604dtrace_get_operand(x, REG_ONLY, reg, w2, 3); \3605dtrace_imm_opnd(x, wbit, immsize, 1); \3606dtrace_imm_opnd(x, wbit, immsize, 0); \3607}36083609/*3610* 1 operands plus two immediates.3611*/3612#define ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \3613dtrace_get_modrm(x, &mode, ®, &r_m); \3614dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); \3615dtrace_get_operand(x, mode, r_m, wbit, 2); \3616dtrace_imm_opnd(x, wbit, immsize, 1); \3617dtrace_imm_opnd(x, wbit, immsize, 0); \3618}36193620/*3621* Dissassemble a single x86 or amd64 instruction.3622*3623* Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)3624* for interpreting instructions.3625*3626* returns non-zero for bad opcode3627*/3628int3629dtrace_disx86(dis86_t *x, uint_t cpu_mode)3630{3631const instable_t *dp; /* decode table being used */3632#ifdef DIS_TEXT3633uint_t i;3634#endif3635#ifdef DIS_MEM3636uint_t nomem = 0;3637#define NOMEM (nomem = 1)3638#else3639#define NOMEM /* nothing */3640#endif3641uint_t opnd_size; /* SIZE16, SIZE32 or SIZE64 */3642uint_t addr_size; /* SIZE16, SIZE32 or SIZE64 */3643uint_t wbit; /* opcode wbit, 0 is 8 bit, !0 for opnd_size */3644uint_t w2; /* wbit value for second operand */3645uint_t vbit;3646uint_t mode = 0; /* mode value from ModRM byte */3647uint_t reg; /* reg value from ModRM byte */3648uint_t r_m; /* r_m value from ModRM byte */36493650uint_t opcode1; /* high nibble of 1st byte */3651uint_t opcode2; /* low nibble of 1st byte */3652uint_t opcode3; /* extra opcode bits usually from ModRM byte */3653uint_t opcode4; /* high nibble of 2nd byte */3654uint_t opcode5; /* low nibble of 2nd byte */3655uint_t opcode6; /* high nibble of 3rd byte */3656uint_t opcode7; /* low nibble of 3rd byte */3657uint_t opcode8; /* high nibble of 4th byte */3658uint_t opcode9; /* low nibble of 4th byte */3659uint_t opcode_bytes = 1;36603661/*3662* legacy prefixes come in 5 flavors, you should have only one of each3663*/3664uint_t opnd_size_prefix = 0;3665uint_t addr_size_prefix = 0;3666uint_t segment_prefix = 0;3667uint_t lock_prefix = 0;3668uint_t rep_prefix = 0;3669uint_t rex_prefix = 0; /* amd64 register extension prefix */36703671/*3672* Intel VEX instruction encoding prefix and fields3673*/36743675/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */3676uint_t vex_prefix = 0;36773678/*3679* VEX prefix byte 1, includes vex.r, vex.x and vex.b3680* (for 3 bytes prefix)3681*/3682uint_t vex_byte1 = 0;36833684/*3685* EVEX prefix byte 1 includes vex.r, vex.x, vex.b and evex.r.3686*/3687uint_t evex_byte1 = 0;3688uint_t evex_byte2 = 0;3689uint_t evex_byte3 = 0;36903691/*3692* For 32-bit mode, it should prefetch the next byte to3693* distinguish between AVX and les/lds3694*/3695uint_t vex_prefetch = 0;36963697uint_t vex_m = 0;3698uint_t vex_v = 0;3699uint_t vex_p = 0;3700uint_t vex_R = 1;3701uint_t vex_X = 1;3702uint_t vex_B = 1;3703uint_t vex_W = 0;3704uint_t vex_L = 0;3705uint_t evex_L = 0;3706uint_t evex_modrm = 0;3707uint_t evex_prefix = 0;3708dis_gather_regs_t *vreg;37093710#ifdef DIS_TEXT3711/* Instruction name for BLS* family of instructions */3712char *blsinstr;3713#endif37143715size_t off;37163717instable_t dp_mmx;37183719x->d86_len = 0;3720x->d86_rmindex = -1;3721x->d86_error = 0;3722x->d86_numopnds = 0;3723#ifdef DIS_TEXT3724x->d86_seg_prefix = NULL;3725x->d86_mnem[0] = 0;3726for (i = 0; i < 4; ++i) {3727x->d86_opnd[i].d86_opnd[0] = 0;3728x->d86_opnd[i].d86_prefix[0] = 0;3729x->d86_opnd[i].d86_value_size = 0;3730x->d86_opnd[i].d86_value = 0;3731x->d86_opnd[i].d86_mode = MODE_NONE;3732}3733#endif3734x->d86_rex_prefix = 0;3735x->d86_got_modrm = 0;3736x->d86_memsize = 0;3737x->d86_vsib = 0;37383739if (cpu_mode == SIZE16) {3740opnd_size = SIZE16;3741addr_size = SIZE16;3742} else if (cpu_mode == SIZE32) {3743opnd_size = SIZE32;3744addr_size = SIZE32;3745} else {3746opnd_size = SIZE32;3747addr_size = SIZE64;3748}37493750/*3751* Get one opcode byte and check for zero padding that follows3752* jump tables.3753*/3754if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)3755goto error;37563757if (opcode1 == 0 && opcode2 == 0 &&3758x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {3759#ifdef DIS_TEXT3760(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);3761#endif3762goto done;3763}37643765/*3766* Gather up legacy x86 prefix bytes.3767*/3768for (;;) {3769uint_t *which_prefix = NULL;37703771dp = (instable_t *)&dis_distable[opcode1][opcode2];37723773switch (dp->it_adrmode) {3774case PREFIX:3775which_prefix = &rep_prefix;3776break;3777case LOCK:3778which_prefix = &lock_prefix;3779break;3780case OVERRIDE:3781which_prefix = &segment_prefix;3782#ifdef DIS_TEXT3783x->d86_seg_prefix = (char *)dp->it_name;3784#endif3785if (dp->it_invalid64 && cpu_mode == SIZE64)3786goto error;3787break;3788case AM:3789which_prefix = &addr_size_prefix;3790break;3791case DM:3792which_prefix = &opnd_size_prefix;3793break;3794}3795if (which_prefix == NULL)3796break;3797*which_prefix = (opcode1 << 4) | opcode2;3798if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)3799goto error;3800}38013802/*3803* Handle amd64 mode PREFIX values.3804* Some of the segment prefixes are no-ops. (only FS/GS actually work)3805* We might have a REX prefix (opcodes 0x40-0x4f)3806*/3807if (cpu_mode == SIZE64) {3808if (segment_prefix != 0x64 && segment_prefix != 0x65)3809segment_prefix = 0;38103811if (opcode1 == 0x4) {3812rex_prefix = (opcode1 << 4) | opcode2;3813if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)3814goto error;3815dp = (instable_t *)&dis_distable[opcode1][opcode2];3816} else if (opcode1 == 0xC &&3817(opcode2 == 0x4 || opcode2 == 0x5)) {3818/* AVX instructions */3819vex_prefix = (opcode1 << 4) | opcode2;3820x->d86_rex_prefix = 0x40;3821}3822} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {3823/* LDS, LES or AVX */3824dtrace_get_modrm(x, &mode, ®, &r_m);3825vex_prefetch = 1;38263827if (mode == REG_ONLY) {3828/* AVX */3829vex_prefix = (opcode1 << 4) | opcode2;3830x->d86_rex_prefix = 0x40;3831opcode3 = (((mode << 3) | reg)>>1) & 0x0F;3832opcode4 = ((reg << 3) | r_m) & 0x0F;3833}3834}38353836/*3837* The EVEX prefix and "bound" instruction share the same first byte.3838* "bound" is only valid for 32-bit. For 64-bit this byte begins the3839* EVEX prefix and the 2nd byte must have bits 2 & 3 set to 0.3840*/3841if (opcode1 == 0x6 && opcode2 == 0x2) {3842evex_prefix = 0x62;38433844/*3845* An EVEX prefix is 4 bytes long, get the next 3 bytes.3846*/3847if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)3848goto error;38493850if (addr_size == SIZE32 && (opcode4 & 0xf) == 0) {3851/*3852* Upper bits in 2nd byte == 0 is 'bound' instn.3853*3854* We've already read the byte so perform the3855* equivalent of dtrace_get_modrm on the byte and set3856* the flag to indicate we've already read it.3857*/3858char b = (opcode4 << 4) | opcode5;38593860r_m = b & 0x7;3861reg = (b >> 3) & 0x7;3862mode = (b >> 6) & 0x3;3863vex_prefetch = 1;3864goto not_avx512;3865}38663867/* check for correct bits being 0 in 2nd byte */3868if ((opcode5 & 0xc) != 0)3869goto error;38703871if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)3872goto error;3873/* check for correct bit being 1 in 3rd byte */3874if ((opcode7 & 0x4) == 0)3875goto error;38763877if (dtrace_get_opcode(x, &opcode8, &opcode9) != 0)3878goto error;38793880/* Reuse opcode1 & opcode2 to get the real opcode now */3881if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)3882goto error;38833884/*3885* We only use the high nibble from the 2nd byte of the prefix3886* and save it in the low bits of evex_byte1. This is because3887* two of the bits in opcode5 are constant 0 (checked above),3888* and the other two bits are captured in vex_m. Also, the VEX3889* constants we check in evex_byte1 are against the low bits.3890*/3891evex_byte1 = opcode4;3892evex_byte2 = (opcode6 << 4) | opcode7;3893evex_byte3 = (opcode8 << 4) | opcode9;38943895vex_m = opcode5 & EVEX_m;3896vex_v = (((opcode6 << 4) | opcode7) & VEX_v) >> 3;3897vex_W = (opcode6 & VEX_W) >> 3;3898vex_p = opcode7 & VEX_p;38993900/*3901* Store the corresponding prefix information for later use when3902* calculating the SIB.3903*/3904if ((evex_byte1 & VEX_R) == 0)3905x->d86_rex_prefix |= REX_R;3906if ((evex_byte1 & VEX_X) == 0)3907x->d86_rex_prefix |= REX_X;3908if ((evex_byte1 & VEX_B) == 0)3909x->d86_rex_prefix |= REX_B;39103911/* Currently only 3 valid values for evex L'L: 00, 01, 10 */3912evex_L = (opcode8 & EVEX_L) >> 1;39133914switch (vex_p) {3915case VEX_p_66:3916switch (vex_m) {3917case VEX_m_0F:3918dp = &dis_opEVEX660F[(opcode1 << 4) | opcode2];3919break;3920case VEX_m_0F38:3921dp = &dis_opEVEX660F38[(opcode1 << 4) |3922opcode2];3923break;3924case VEX_m_0F3A:3925dp = &dis_opEVEX660F3A[(opcode1 << 4) |3926opcode2];3927break;3928default:3929goto error;3930}3931break;3932case VEX_p_F3:3933switch (vex_m) {3934case VEX_m_0F:3935dp = &dis_opEVEXF30F[(opcode1 << 4) | opcode2];3936break;3937default:3938goto error;3939}3940break;3941case VEX_p_F2:3942switch (vex_m) {3943case VEX_m_0F:3944dp = &dis_opEVEXF20F[(opcode1 << 4) | opcode2];3945break;3946default:3947goto error;3948}3949break;3950default:3951dp = &dis_opEVEX0F[(opcode1 << 4) | opcode2];3952break;3953}3954}3955not_avx512:39563957if (vex_prefix == VEX_2bytes) {3958if (!vex_prefetch) {3959if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)3960goto error;3961}3962vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;3963vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;3964vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;3965vex_p = opcode4 & VEX_p;3966/*3967* The vex.x and vex.b bits are not defined in two bytes3968* mode vex prefix, their default values are 13969*/3970vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;39713972if (vex_R == 0)3973x->d86_rex_prefix |= REX_R;39743975if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)3976goto error;39773978switch (vex_p) {3979case VEX_p_66:3980dp = (instable_t *)3981&dis_opAVX660F[(opcode1 << 4) | opcode2];3982break;3983case VEX_p_F3:3984dp = (instable_t *)3985&dis_opAVXF30F[(opcode1 << 4) | opcode2];3986break;3987case VEX_p_F2:3988dp = (instable_t *)3989&dis_opAVXF20F [(opcode1 << 4) | opcode2];3990break;3991default:3992dp = (instable_t *)3993&dis_opAVX0F[opcode1][opcode2];39943995}39963997} else if (vex_prefix == VEX_3bytes) {3998if (!vex_prefetch) {3999if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)4000goto error;4001}4002vex_R = (opcode3 & VEX_R) >> 3;4003vex_X = (opcode3 & VEX_X) >> 2;4004vex_B = (opcode3 & VEX_B) >> 1;4005vex_m = (((opcode3 << 4) | opcode4) & VEX_m);4006vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);40074008if (vex_R == 0)4009x->d86_rex_prefix |= REX_R;4010if (vex_X == 0)4011x->d86_rex_prefix |= REX_X;4012if (vex_B == 0)4013x->d86_rex_prefix |= REX_B;40144015if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)4016goto error;4017vex_W = (opcode5 & VEX_W) >> 3;4018vex_L = (opcode6 & VEX_L) >> 2;4019vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;4020vex_p = opcode6 & VEX_p;40214022if (vex_W)4023x->d86_rex_prefix |= REX_W;40244025/* Only these three vex_m values valid; others are reserved */4026if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&4027(vex_m != VEX_m_0F3A))4028goto error;40294030if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)4031goto error;40324033switch (vex_p) {4034case VEX_p_66:4035if (vex_m == VEX_m_0F) {4036dp = (instable_t *)4037&dis_opAVX660F4038[(opcode1 << 4) | opcode2];4039} else if (vex_m == VEX_m_0F38) {4040dp = (instable_t *)4041&dis_opAVX660F384042[(opcode1 << 4) | opcode2];4043} else if (vex_m == VEX_m_0F3A) {4044dp = (instable_t *)4045&dis_opAVX660F3A4046[(opcode1 << 4) | opcode2];4047} else {4048goto error;4049}4050break;4051case VEX_p_F3:4052if (vex_m == VEX_m_0F) {4053dp = (instable_t *)4054&dis_opAVXF30F4055[(opcode1 << 4) | opcode2];4056} else if (vex_m == VEX_m_0F38) {4057dp = (instable_t *)4058&dis_opAVXF30F384059[(opcode1 << 4) | opcode2];4060} else {4061goto error;4062}4063break;4064case VEX_p_F2:4065if (vex_m == VEX_m_0F) {4066dp = (instable_t *)4067&dis_opAVXF20F4068[(opcode1 << 4) | opcode2];4069} else if (vex_m == VEX_m_0F3A) {4070dp = (instable_t *)4071&dis_opAVXF20F3A4072[(opcode1 << 4) | opcode2];4073} else if (vex_m == VEX_m_0F38) {4074dp = (instable_t *)4075&dis_opAVXF20F384076[(opcode1 << 4) | opcode2];4077} else {4078goto error;4079}4080break;4081default:4082dp = (instable_t *)4083&dis_opAVX0F[opcode1][opcode2];40844085}4086}4087if (vex_prefix) {4088if (dp->it_vexwoxmm) {4089wbit = LONG_OPND;4090} else if (dp->it_vexopmask) {4091wbit = KOPMASK_OPND;4092} else {4093if (vex_L) {4094wbit = YMM_OPND;4095} else {4096wbit = XMM_OPND;4097}4098}4099}41004101/*4102* Deal with selection of operand and address size now.4103* Note that the REX.W bit being set causes opnd_size_prefix to be4104* ignored.4105*/4106if (cpu_mode == SIZE64) {4107if ((rex_prefix & REX_W) || vex_W)4108opnd_size = SIZE64;4109else if (opnd_size_prefix)4110opnd_size = SIZE16;41114112if (addr_size_prefix)4113addr_size = SIZE32;4114} else if (cpu_mode == SIZE32) {4115if (opnd_size_prefix)4116opnd_size = SIZE16;4117if (addr_size_prefix)4118addr_size = SIZE16;4119} else {4120if (opnd_size_prefix)4121opnd_size = SIZE32;4122if (addr_size_prefix)4123addr_size = SIZE32;4124}4125/*4126* The pause instruction - a repz'd nop. This doesn't fit4127* with any of the other prefix goop added for SSE, so we'll4128* special-case it here.4129*/4130if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {4131rep_prefix = 0;4132dp = (instable_t *)&dis_opPause;4133}41344135/*4136* Some 386 instructions have 2 bytes of opcode before the mod_r/m4137* byte so we may need to perform a table indirection.4138*/4139if (dp->it_indirect == (instable_t *)dis_op0F) {4140if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)4141goto error;4142opcode_bytes = 2;4143if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {4144uint_t subcode;41454146if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)4147goto error;4148opcode_bytes = 3;4149subcode = ((opcode6 & 0x3) << 1) |4150((opcode7 & 0x8) >> 3);4151dp = (instable_t *)&dis_op0F7123[opcode5][subcode];4152} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {4153dp = (instable_t *)&dis_op0FC8[0];4154} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {4155opcode_bytes = 3;4156if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)4157goto error;4158if (opnd_size == SIZE16)4159opnd_size = SIZE32;41604161dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];4162#ifdef DIS_TEXT4163if (strcmp(dp->it_name, "INVALID") == 0)4164goto error;4165#endif4166switch (dp->it_adrmode) {4167case XMMP:4168break;4169case XMMP_66r:4170case XMMPRM_66r:4171case XMM3PM_66r:4172if (opnd_size_prefix == 0) {4173goto error;4174}41754176break;4177case XMMP_66o:4178if (opnd_size_prefix == 0) {4179/* SSSE3 MMX instructions */4180dp_mmx = *dp;4181dp_mmx.it_adrmode = MMOPM_66o;4182#ifdef DIS_MEM4183dp_mmx.it_size = 8;4184#endif4185dp = &dp_mmx;4186}4187break;4188default:4189goto error;4190}4191} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {4192opcode_bytes = 3;4193if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)4194goto error;4195dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];41964197/*4198* Both crc32 and movbe have the same 3rd opcode4199* byte of either 0xF0 or 0xF1, so we use another4200* indirection to distinguish between the two.4201*/4202if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||4203dp->it_indirect == (instable_t *)dis_op0F38F1) {42044205dp = dp->it_indirect;4206if (rep_prefix != 0xF2) {4207/* It is movbe */4208dp++;4209}4210}42114212/*4213* The adx family of instructions (adcx and adox)4214* continue the classic Intel tradition of abusing4215* arbitrary prefixes without actually meaning the4216* prefix bit. Therefore, if we find either the4217* opnd_size_prefix or rep_prefix we end up zeroing it4218* out after making our determination so as to ensure4219* that we don't get confused and accidentally print4220* repz prefixes and the like on these instructions.4221*4222* In addition, these instructions are actually much4223* closer to AVX instructions in semantics. Importantly,4224* they always default to having 32-bit operands.4225* However, if the CPU is in 64-bit mode, then and only4226* then, does it use REX.w promotes things to 64-bits4227* and REX.r allows 64-bit mode to use register r8-r15.4228*/4229if (dp->it_indirect == (instable_t *)dis_op0F38F6) {4230dp = dp->it_indirect;4231if (opnd_size_prefix == 0 &&4232rep_prefix == 0xf3) {4233/* It is adox */4234dp++;4235} else if (opnd_size_prefix != 0x66 &&4236rep_prefix != 0) {4237/* It isn't adcx */4238goto error;4239}4240opnd_size_prefix = 0;4241rep_prefix = 0;4242opnd_size = SIZE32;4243if (rex_prefix & REX_W)4244opnd_size = SIZE64;4245}42464247#ifdef DIS_TEXT4248if (strcmp(dp->it_name, "INVALID") == 0)4249goto error;4250#endif4251switch (dp->it_adrmode) {4252case ADX:4253case XMM:4254break;4255case RM_66r:4256case XMM_66r:4257case XMMM_66r:4258if (opnd_size_prefix == 0) {4259goto error;4260}4261break;4262case XMM_66o:4263if (opnd_size_prefix == 0) {4264/* SSSE3 MMX instructions */4265dp_mmx = *dp;4266dp_mmx.it_adrmode = MM;4267#ifdef DIS_MEM4268dp_mmx.it_size = 8;4269#endif4270dp = &dp_mmx;4271}4272break;4273case CRC32:4274if (rep_prefix != 0xF2) {4275goto error;4276}4277rep_prefix = 0;4278break;4279case MOVBE:4280if (rep_prefix != 0x0) {4281goto error;4282}4283break;4284default:4285goto error;4286}4287} else if (rep_prefix == 0xf3 && opcode4 == 0 && opcode5 == 9) {4288rep_prefix = 0;4289dp = (instable_t *)&dis_opWbnoinvd;4290} else {4291dp = (instable_t *)&dis_op0F[opcode4][opcode5];4292}4293}42944295/*4296* If still not at a TERM decode entry, then a ModRM byte4297* exists and its fields further decode the instruction.4298*/4299x->d86_got_modrm = 0;4300if (dp->it_indirect != TERM) {4301dtrace_get_modrm(x, &mode, &opcode3, &r_m);4302if (x->d86_error)4303goto error;4304reg = opcode3;43054306/*4307* decode 287 instructions (D8-DF) from opcodeN4308*/4309if (opcode1 == 0xD && opcode2 >= 0x8) {4310if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)4311dp = (instable_t *)&dis_opFP5[r_m];4312else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)4313dp = (instable_t *)&dis_opFP7[opcode3];4314else if (opcode2 == 0xB && mode == 0x3)4315dp = (instable_t *)&dis_opFP6[opcode3];4316else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)4317dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];4318else if (mode == 0x3)4319dp = (instable_t *)4320&dis_opFP3[opcode2 - 8][opcode3];4321else4322dp = (instable_t *)4323&dis_opFP1n2[opcode2 - 8][opcode3];4324} else {4325dp = (instable_t *)dp->it_indirect + opcode3;4326}4327}43284329/*4330* In amd64 bit mode, ARPL opcode is changed to MOVSXD4331* (sign extend 32bit to 64 bit)4332*/4333if ((vex_prefix == 0) && cpu_mode == SIZE64 &&4334opcode1 == 0x6 && opcode2 == 0x3)4335dp = (instable_t *)&dis_opMOVSLD;43364337/*4338* at this point we should have a correct (or invalid) opcode4339*/4340if (cpu_mode == SIZE64 && dp->it_invalid64 ||4341cpu_mode != SIZE64 && dp->it_invalid32)4342goto error;4343if (dp->it_indirect != TERM)4344goto error;43454346/*4347* Deal with MMX/SSE opcodes which are changed by prefixes. Note, we do4348* need to include UNKNOWN below, as we may have instructions that4349* actually have a prefix, but don't exist in any other form.4350*/4351switch (dp->it_adrmode) {4352case UNKNOWN:4353case MMO:4354case MMOIMPL:4355case MMO3P:4356case MMOM3:4357case MMOMS:4358case MMOPM:4359case MMOPRM:4360case MMOS:4361case XMMO:4362case XMMOM:4363case XMMOMS:4364case XMMOPM:4365case XMMOS:4366case XMMOMX:4367case XMMOX3:4368case XMMOXMM:4369/*4370* This is horrible. Some SIMD instructions take the4371* form 0x0F 0x?? ..., which is easily decoded using the4372* existing tables. Other SIMD instructions use various4373* prefix bytes to overload existing instructions. For4374* Example, addps is F0, 58, whereas addss is F3 (repz),4375* F0, 58. Presumably someone got a raise for this.4376*4377* If we see one of the instructions which can be4378* modified in this way (if we've got one of the SIMDO*4379* address modes), we'll check to see if the last prefix4380* was a repz. If it was, we strip the prefix from the4381* mnemonic, and we indirect using the dis_opSIMDrepz4382* table.4383*/43844385/*4386* Calculate our offset in dis_op0F4387*/4388if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))4389goto error;43904391off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /4392sizeof (instable_t);43934394/*4395* Rewrite if this instruction used one of the magic prefixes.4396*/4397if (rep_prefix) {4398if (rep_prefix == 0xf2)4399dp = (instable_t *)&dis_opSIMDrepnz[off];4400else4401dp = (instable_t *)&dis_opSIMDrepz[off];4402rep_prefix = 0;4403} else if (opnd_size_prefix) {4404dp = (instable_t *)&dis_opSIMDdata16[off];4405opnd_size_prefix = 0;4406if (opnd_size == SIZE16)4407opnd_size = SIZE32;4408}4409break;44104411case MG9:4412/*4413* More horribleness: the group 9 (0xF0 0xC7) instructions are4414* allowed an optional prefix of 0x66 or 0xF3. This is similar4415* to the SIMD business described above, but with a different4416* addressing mode (and an indirect table), so we deal with it4417* separately (if similarly).4418*4419* Intel further complicated this with the release of Ivy Bridge4420* where they overloaded these instructions based on the ModR/M4421* bytes. The VMX instructions have a mode of 0 since they are4422* memory instructions but rdrand instructions have a mode of4423* 0b11 (REG_ONLY) because they only operate on registers. While4424* there are different prefix formats, for now it is sufficient4425* to use a single different table.4426*/44274428/*4429* Calculate our offset in dis_op0FC7 (the group 9 table)4430*/4431if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))4432goto error;44334434off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /4435sizeof (instable_t);44364437/*4438* If we have a mode of 0b11 then we have to rewrite this.4439*/4440dtrace_get_modrm(x, &mode, ®, &r_m);4441if (mode == REG_ONLY) {4442dp = (instable_t *)&dis_op0FC7m3[off];4443break;4444}44454446/*4447* Rewrite if this instruction used one of the magic prefixes.4448*/4449if (rep_prefix) {4450if (rep_prefix == 0xf3)4451dp = (instable_t *)&dis_opF30FC7[off];4452else4453goto error;4454rep_prefix = 0;4455} else if (opnd_size_prefix) {4456dp = (instable_t *)&dis_op660FC7[off];4457opnd_size_prefix = 0;4458if (opnd_size == SIZE16)4459opnd_size = SIZE32;4460} else if (reg == 4 || reg == 5) {4461/*4462* We have xsavec (4) or xsaves (5), so rewrite.4463*/4464dp = (instable_t *)&dis_op0FC7[reg];4465break;4466}4467break;446844694470case MMOSH:4471/*4472* As with the "normal" SIMD instructions, the MMX4473* shuffle instructions are overloaded. These4474* instructions, however, are special in that they use4475* an extra byte, and thus an extra table. As of this4476* writing, they only use the opnd_size prefix.4477*/44784479/*4480* Calculate our offset in dis_op0F71234481*/4482if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >4483sizeof (dis_op0F7123))4484goto error;44854486if (opnd_size_prefix) {4487off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /4488sizeof (instable_t);4489dp = (instable_t *)&dis_opSIMD7123[off];4490opnd_size_prefix = 0;4491if (opnd_size == SIZE16)4492opnd_size = SIZE32;4493}4494break;4495case MRw:4496if (rep_prefix) {4497if (rep_prefix == 0xf3) {44984499/*4500* Calculate our offset in dis_op0F4501*/4502if ((uintptr_t)dp - (uintptr_t)dis_op0F >4503sizeof (dis_op0F))4504goto error;45054506off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /4507sizeof (instable_t);45084509dp = (instable_t *)&dis_opSIMDrepz[off];4510rep_prefix = 0;4511} else {4512goto error;4513}4514}4515break;4516case FSGS:4517if (rep_prefix == 0xf3) {4518if ((uintptr_t)dp - (uintptr_t)dis_op0FAE >4519sizeof (dis_op0FAE))4520goto error;45214522off = ((uintptr_t)dp - (uintptr_t)dis_op0FAE) /4523sizeof (instable_t);4524dp = (instable_t *)&dis_opF30FAE[off];4525rep_prefix = 0;4526} else if (rep_prefix != 0x00) {4527goto error;4528}4529}45304531/*4532* In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.4533*/4534if (cpu_mode == SIZE64)4535if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))4536opnd_size = SIZE64;45374538#ifdef DIS_TEXT4539/*4540* At this point most instructions can format the opcode mnemonic4541* including the prefixes.4542*/4543if (lock_prefix)4544(void) strlcat(x->d86_mnem, "lock ", OPLEN);45454546if (rep_prefix == 0xf2)4547(void) strlcat(x->d86_mnem, "repnz ", OPLEN);4548else if (rep_prefix == 0xf3)4549(void) strlcat(x->d86_mnem, "repz ", OPLEN);45504551if (cpu_mode == SIZE64 && addr_size_prefix)4552(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);45534554if (dp->it_adrmode != CBW &&4555dp->it_adrmode != CWD &&4556dp->it_adrmode != XMMSFNC) {4557if (strcmp(dp->it_name, "INVALID") == 0)4558goto error;4559(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);4560if (dp->it_avxsuf == AVS2 && dp->it_suffix) {4561(void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",4562OPLEN);4563} else if (dp->it_vexopmask && dp->it_suffix) {4564/* opmask instructions */45654566if (opcode1 == 4 && opcode2 == 0xb) {4567/* It's a kunpck. */4568if (vex_prefix == VEX_2bytes) {4569(void) strlcat(x->d86_mnem,4570vex_p == 0 ? "wd" : "bw", OPLEN);4571} else {4572/* vex_prefix == VEX_3bytes */4573(void) strlcat(x->d86_mnem,4574"dq", OPLEN);4575}4576} else if (opcode1 == 3) {4577/* It's a kshift[l|r]. */4578if (vex_W == 0) {4579(void) strlcat(x->d86_mnem,4580opcode2 == 2 ||4581opcode2 == 0 ?4582"b" : "d", OPLEN);4583} else {4584/* W == 1 */4585(void) strlcat(x->d86_mnem,4586opcode2 == 3 || opcode2 == 1 ?4587"q" : "w", OPLEN);4588}4589} else {4590/* if (vex_prefix == VEX_2bytes) { */4591if ((cpu_mode == SIZE64 && opnd_size == 2) ||4592vex_prefix == VEX_2bytes) {4593(void) strlcat(x->d86_mnem,4594vex_p == 0 ? "w" :4595vex_p == 1 ? "b" : "d",4596OPLEN);4597} else {4598/* vex_prefix == VEX_3bytes */4599(void) strlcat(x->d86_mnem,4600vex_p == 1 ? "d" : "q", OPLEN);4601}4602}4603} else if (dp->it_suffix) {4604char *types[] = {"", "w", "l", "q"};4605if (opcode_bytes == 2 && opcode4 == 4) {4606/* It's a cmovx.yy. Replace the suffix x */4607for (i = 5; i < OPLEN; i++) {4608if (x->d86_mnem[i] == '.')4609break;4610}4611x->d86_mnem[i - 1] = *types[opnd_size];4612} else if ((opnd_size == 2) && (opcode_bytes == 3) &&4613((opcode6 == 1 && opcode7 == 6) ||4614(opcode6 == 2 && opcode7 == 2))) {4615/*4616* To handle PINSRD and PEXTRD4617*/4618(void) strlcat(x->d86_mnem, "d", OPLEN);4619} else if (dp != &dis_distable[0x6][0x2]) {4620/* bound instructions (0x62) have no suffix */4621(void) strlcat(x->d86_mnem, types[opnd_size],4622OPLEN);4623}4624}4625}4626#endif46274628/*4629* Process operands based on the addressing modes.4630*/4631x->d86_mode = cpu_mode;4632/*4633* In vex mode the rex_prefix has no meaning4634*/4635if (!vex_prefix && evex_prefix == 0)4636x->d86_rex_prefix = rex_prefix;4637x->d86_opnd_size = opnd_size;4638x->d86_addr_size = addr_size;4639vbit = 0; /* initialize for mem/reg -> reg */4640switch (dp->it_adrmode) {4641/*4642* amd64 instruction to sign extend 32 bit reg/mem operands4643* into 64 bit register values4644*/4645case MOVSXZ:4646#ifdef DIS_TEXT4647if (rex_prefix == 0)4648(void) strncpy(x->d86_mnem, "movzld", OPLEN);4649#endif4650dtrace_get_modrm(x, &mode, ®, &r_m);4651dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);4652x->d86_opnd_size = SIZE64;4653dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);4654x->d86_opnd_size = opnd_size = SIZE32;4655wbit = LONG_OPND;4656dtrace_get_operand(x, mode, r_m, wbit, 0);4657break;46584659/*4660* movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)4661* movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)4662* wbit lives in 2nd byte, note that operands4663* are different sized4664*/4665case MOVZ:4666if (rex_prefix & REX_W) {4667/* target register size = 64 bit */4668x->d86_mnem[5] = 'q';4669}4670dtrace_get_modrm(x, &mode, ®, &r_m);4671dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);4672dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);4673x->d86_opnd_size = opnd_size = SIZE16;4674wbit = WBIT(opcode5);4675dtrace_get_operand(x, mode, r_m, wbit, 0);4676break;4677case CRC32:4678opnd_size = SIZE32;4679if (rex_prefix & REX_W)4680opnd_size = SIZE64;4681x->d86_opnd_size = opnd_size;46824683dtrace_get_modrm(x, &mode, ®, &r_m);4684dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);4685dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);4686wbit = WBIT(opcode7);4687if (opnd_size_prefix)4688x->d86_opnd_size = opnd_size = SIZE16;4689dtrace_get_operand(x, mode, r_m, wbit, 0);4690break;4691case MOVBE:4692opnd_size = SIZE32;4693if (rex_prefix & REX_W)4694opnd_size = SIZE64;4695x->d86_opnd_size = opnd_size;46964697dtrace_get_modrm(x, &mode, ®, &r_m);4698dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);4699wbit = WBIT(opcode7);4700if (opnd_size_prefix)4701x->d86_opnd_size = opnd_size = SIZE16;4702if (wbit) {4703/* reg -> mem */4704dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);4705dtrace_get_operand(x, mode, r_m, wbit, 1);4706} else {4707/* mem -> reg */4708dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);4709dtrace_get_operand(x, mode, r_m, wbit, 0);4710}4711break;47124713/*4714* imul instruction, with either 8-bit or longer immediate4715* opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)4716*/4717case IMUL:4718wbit = LONG_OPND;4719THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,4720OPSIZE(opnd_size, opcode2 == 0x9), 1);4721break;47224723/* memory or register operand to register, with 'w' bit */4724case MRw:4725case ADX:4726wbit = WBIT(opcode2);4727STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);4728break;47294730/* register to memory or register operand, with 'w' bit */4731/* arpl happens to fit here also because it is odd */4732case RMw:4733if (opcode_bytes == 2)4734wbit = WBIT(opcode5);4735else4736wbit = WBIT(opcode2);4737STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);4738break;47394740/* xaddb instruction */4741case XADDB:4742wbit = 0;4743STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);4744break;47454746/* MMX register to memory or register operand */4747case MMS:4748case MMOS:4749#ifdef DIS_TEXT4750wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;4751#else4752wbit = LONG_OPND;4753#endif4754MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);4755break;47564757/* MMX register to memory */4758case MMOMS:4759dtrace_get_modrm(x, &mode, ®, &r_m);4760if (mode == REG_ONLY)4761goto error;4762wbit = MM_OPND;4763MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);4764break;47654766/* Double shift. Has immediate operand specifying the shift. */4767case DSHIFT:4768wbit = LONG_OPND;4769dtrace_get_modrm(x, &mode, ®, &r_m);4770dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);4771dtrace_get_operand(x, mode, r_m, wbit, 2);4772dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);4773dtrace_imm_opnd(x, wbit, 1, 0);4774break;47754776/*4777* Double shift. With no immediate operand, specifies using %cl.4778*/4779case DSHIFTcl:4780wbit = LONG_OPND;4781STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);4782break;47834784/* immediate to memory or register operand */4785case IMlw:4786wbit = WBIT(opcode2);4787dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4788dtrace_get_operand(x, mode, r_m, wbit, 1);4789/*4790* Have long immediate for opcode 0x81, but not 0x80 nor 0x834791*/4792dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);4793break;47944795/* immediate to memory or register operand with the */4796/* 'w' bit present */4797case IMw:4798wbit = WBIT(opcode2);4799dtrace_get_modrm(x, &mode, ®, &r_m);4800dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4801dtrace_get_operand(x, mode, r_m, wbit, 1);4802dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);4803break;48044805/* immediate to register with register in low 3 bits */4806/* of op code */4807case IR:4808/* w-bit here (with regs) is bit 3 */4809wbit = opcode2 >>3 & 0x1;4810reg = REGNO(opcode2);4811dtrace_rex_adjust(rex_prefix, mode, ®, NULL);4812mode = REG_ONLY;4813r_m = reg;4814dtrace_get_operand(x, mode, r_m, wbit, 1);4815dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);4816break;48174818/* MMX immediate shift of register */4819case MMSH:4820case MMOSH:4821wbit = MM_OPND;4822goto mm_shift; /* in next case */48234824/* SIMD immediate shift of register */4825case XMMSH:4826wbit = XMM_OPND;4827mm_shift:4828reg = REGNO(opcode7);4829dtrace_rex_adjust(rex_prefix, mode, ®, NULL);4830dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);4831dtrace_imm_opnd(x, wbit, 1, 0);4832NOMEM;4833break;48344835/* accumulator to memory operand */4836case AO:4837vbit = 1;4838/*FALLTHROUGH*/48394840/* memory operand to accumulator */4841case OA:4842wbit = WBIT(opcode2);4843dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);4844dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);4845#ifdef DIS_TEXT4846x->d86_opnd[vbit].d86_mode = MODE_OFFSET;4847#endif4848break;484948504851/* segment register to memory or register operand */4852case SM:4853vbit = 1;4854/*FALLTHROUGH*/48554856/* memory or register operand to segment register */4857case MS:4858dtrace_get_modrm(x, &mode, ®, &r_m);4859dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4860dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);4861dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);4862wbit = SEG_OPND;4863break;48644865/*4866* rotate or shift instructions, which may shift by 1 or4867* consult the cl register, depending on the 'v' bit4868*/4869case Mv:4870vbit = VBIT(opcode2);4871wbit = WBIT(opcode2);4872dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4873dtrace_get_operand(x, mode, r_m, wbit, 1);4874#ifdef DIS_TEXT4875if (vbit) {4876(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);4877} else {4878x->d86_opnd[0].d86_mode = MODE_SIGNED;4879x->d86_opnd[0].d86_value_size = 1;4880x->d86_opnd[0].d86_value = 1;4881}4882#endif4883break;4884/*4885* immediate rotate or shift instructions4886*/4887case MvI:4888wbit = WBIT(opcode2);4889normal_imm_mem:4890dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4891dtrace_get_operand(x, mode, r_m, wbit, 1);4892dtrace_imm_opnd(x, wbit, 1, 0);4893break;48944895/* bit test instructions */4896case MIb:4897wbit = LONG_OPND;4898goto normal_imm_mem;48994900/* single memory or register operand with 'w' bit present */4901case Mw:4902wbit = WBIT(opcode2);4903just_mem:4904dtrace_get_modrm(x, &mode, ®, &r_m);4905dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);4906dtrace_get_operand(x, mode, r_m, wbit, 0);4907break;49084909case SWAPGS_RDTSCP:4910if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {4911#ifdef DIS_TEXT4912(void) strncpy(x->d86_mnem, "swapgs", OPLEN);4913#endif4914NOMEM;4915break;4916} else if (mode == 3 && r_m == 1) {4917#ifdef DIS_TEXT4918(void) strncpy(x->d86_mnem, "rdtscp", OPLEN);4919#endif4920NOMEM;4921break;4922} else if (mode == 3 && r_m == 2) {4923#ifdef DIS_TEXT4924(void) strncpy(x->d86_mnem, "monitorx", OPLEN);4925#endif4926NOMEM;4927break;4928} else if (mode == 3 && r_m == 3) {4929#ifdef DIS_TEXT4930(void) strncpy(x->d86_mnem, "mwaitx", OPLEN);4931#endif4932NOMEM;4933break;4934} else if (mode == 3 && r_m == 4) {4935#ifdef DIS_TEXT4936(void) strncpy(x->d86_mnem, "clzero", OPLEN);4937#endif4938NOMEM;4939break;4940}49414942/*FALLTHROUGH*/49434944/* prefetch instruction - memory operand, but no memory acess */4945case PREF:4946NOMEM;4947/*FALLTHROUGH*/49484949/* single memory or register operand */4950case M:4951case MG9:4952wbit = LONG_OPND;4953goto just_mem;49544955/* single memory or register byte operand */4956case Mb:4957wbit = BYTE_OPND;4958goto just_mem;49594960case VMx:4961if (mode == 3) {4962#ifdef DIS_TEXT4963char *vminstr;49644965switch (r_m) {4966case 1:4967vminstr = "vmcall";4968break;4969case 2:4970vminstr = "vmlaunch";4971break;4972case 3:4973vminstr = "vmresume";4974break;4975case 4:4976vminstr = "vmxoff";4977break;4978default:4979goto error;4980}49814982(void) strncpy(x->d86_mnem, vminstr, OPLEN);4983#else4984if (r_m < 1 || r_m > 4)4985goto error;4986#endif49874988NOMEM;4989break;4990}4991/*FALLTHROUGH*/4992case SVM:4993if (mode == 3) {4994#ifdef DIS_TEXT4995char *vinstr;49964997switch (r_m) {4998case 0:4999vinstr = "vmrun";5000break;5001case 1:5002vinstr = "vmmcall";5003break;5004case 2:5005vinstr = "vmload";5006break;5007case 3:5008vinstr = "vmsave";5009break;5010case 4:5011vinstr = "stgi";5012break;5013case 5:5014vinstr = "clgi";5015break;5016case 6:5017vinstr = "skinit";5018break;5019case 7:5020vinstr = "invlpga";5021break;5022}50235024(void) strncpy(x->d86_mnem, vinstr, OPLEN);5025#endif5026NOMEM;5027break;5028}5029/*FALLTHROUGH*/5030case MONITOR_MWAIT:5031if (mode == 3) {5032if (r_m == 0) {5033#ifdef DIS_TEXT5034(void) strncpy(x->d86_mnem, "monitor", OPLEN);5035#endif5036NOMEM;5037break;5038} else if (r_m == 1) {5039#ifdef DIS_TEXT5040(void) strncpy(x->d86_mnem, "mwait", OPLEN);5041#endif5042NOMEM;5043break;5044} else if (r_m == 2) {5045#ifdef DIS_TEXT5046(void) strncpy(x->d86_mnem, "clac", OPLEN);5047#endif5048NOMEM;5049break;5050} else if (r_m == 3) {5051#ifdef DIS_TEXT5052(void) strncpy(x->d86_mnem, "stac", OPLEN);5053#endif5054NOMEM;5055break;5056} else {5057goto error;5058}5059}5060/*FALLTHROUGH*/5061case XGETBV_XSETBV:5062if (mode == 3) {5063if (r_m == 0) {5064#ifdef DIS_TEXT5065(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);5066#endif5067NOMEM;5068break;5069} else if (r_m == 1) {5070#ifdef DIS_TEXT5071(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);5072#endif5073NOMEM;5074break;5075} else {5076goto error;5077}50785079}5080/*FALLTHROUGH*/5081case MO:5082/* Similar to M, but only memory (no direct registers) */5083wbit = LONG_OPND;5084dtrace_get_modrm(x, &mode, ®, &r_m);5085if (mode == 3)5086goto error;5087dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);5088dtrace_get_operand(x, mode, r_m, wbit, 0);5089break;50905091/* move special register to register or reverse if vbit */5092case SREG:5093switch (opcode5) {50945095case 2:5096vbit = 1;5097/*FALLTHROUGH*/5098case 0:5099wbit = CONTROL_OPND;5100break;51015102case 3:5103vbit = 1;5104/*FALLTHROUGH*/5105case 1:5106wbit = DEBUG_OPND;5107break;51085109case 6:5110vbit = 1;5111/*FALLTHROUGH*/5112case 4:5113wbit = TEST_OPND;5114break;51155116}5117dtrace_get_modrm(x, &mode, ®, &r_m);5118dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);5119dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);5120dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);5121NOMEM;5122break;51235124/*5125* single register operand with register in the low 35126* bits of op code5127*/5128case R:5129if (opcode_bytes == 2)5130reg = REGNO(opcode5);5131else5132reg = REGNO(opcode2);5133dtrace_rex_adjust(rex_prefix, mode, ®, NULL);5134dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);5135NOMEM;5136break;51375138/*5139* register to accumulator with register in the low 35140* bits of op code, xchg instructions5141*/5142case RA:5143NOMEM;5144reg = REGNO(opcode2);5145dtrace_rex_adjust(rex_prefix, mode, ®, NULL);5146dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);5147dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);5148break;51495150/*5151* single segment register operand, with register in5152* bits 3-4 of op code byte5153*/5154case SEG:5155NOMEM;5156reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;5157dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);5158break;51595160/*5161* single segment register operand, with register in5162* bits 3-5 of op code5163*/5164case LSEG:5165NOMEM;5166/* long seg reg from opcode */5167reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;5168dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);5169break;51705171/* memory or register operand to register */5172case MR:5173if (vex_prefetch)5174x->d86_got_modrm = 1;5175wbit = LONG_OPND;5176STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);5177break;51785179case RM:5180case RM_66r:5181if (vex_prefetch)5182x->d86_got_modrm = 1;5183wbit = LONG_OPND;5184STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);5185break;51865187/* MMX/SIMD-Int memory or mm reg to mm reg */5188case MM:5189case MMO:5190#ifdef DIS_TEXT5191wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;5192#else5193wbit = LONG_OPND;5194#endif5195MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);5196break;51975198case MMOIMPL:5199#ifdef DIS_TEXT5200wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;5201#else5202wbit = LONG_OPND;5203#endif5204dtrace_get_modrm(x, &mode, ®, &r_m);5205if (mode != REG_ONLY)5206goto error;52075208dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);5209dtrace_get_operand(x, mode, r_m, wbit, 0);5210dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);5211mode = 0; /* change for memory access size... */5212break;52135214/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */5215case MMO3P:5216wbit = MM_OPND;5217goto xmm3p;5218case XMM3P:5219wbit = XMM_OPND;5220xmm3p:5221dtrace_get_modrm(x, &mode, ®, &r_m);5222if (mode != REG_ONLY)5223goto error;52245225THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,52261);5227NOMEM;5228break;52295230case XMM3PM_66r:5231THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,52321, 0);5233break;52345235/* MMX/SIMD-Int predicated r32/mem to mm reg */5236case MMOPRM:5237wbit = LONG_OPND;5238w2 = MM_OPND;5239goto xmmprm;5240case XMMPRM:5241case XMMPRM_66r:5242wbit = LONG_OPND;5243w2 = XMM_OPND;5244xmmprm:5245THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);5246break;52475248/* MMX/SIMD-Int predicated mm/mem to mm reg */5249case MMOPM:5250case MMOPM_66o:5251wbit = w2 = MM_OPND;5252goto xmmprm;52535254/* MMX/SIMD-Int mm reg to r32 */5255case MMOM3:5256NOMEM;5257dtrace_get_modrm(x, &mode, ®, &r_m);5258if (mode != REG_ONLY)5259goto error;5260wbit = MM_OPND;5261MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);5262break;52635264/* SIMD memory or xmm reg operand to xmm reg */5265case XMM:5266case XMM_66o:5267case XMM_66r:5268case XMMO:5269case XMMXIMPL:5270wbit = XMM_OPND;5271STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);52725273if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)5274goto error;52755276#ifdef DIS_TEXT5277/*5278* movlps and movhlps share opcodes. They differ in the5279* addressing modes allowed for their operands.5280* movhps and movlhps behave similarly.5281*/5282if (mode == REG_ONLY) {5283if (strcmp(dp->it_name, "movlps") == 0)5284(void) strncpy(x->d86_mnem, "movhlps", OPLEN);5285else if (strcmp(dp->it_name, "movhps") == 0)5286(void) strncpy(x->d86_mnem, "movlhps", OPLEN);5287}5288#endif5289if (dp->it_adrmode == XMMXIMPL)5290mode = 0; /* change for memory access size... */5291break;52925293/* SIMD xmm reg to memory or xmm reg */5294case XMMS:5295case XMMOS:5296case XMMMS:5297case XMMOMS:5298dtrace_get_modrm(x, &mode, ®, &r_m);5299#ifdef DIS_TEXT5300if ((strcmp(dp->it_name, "movlps") == 0 ||5301strcmp(dp->it_name, "movhps") == 0 ||5302strcmp(dp->it_name, "movntps") == 0) &&5303mode == REG_ONLY)5304goto error;5305#endif5306wbit = XMM_OPND;5307MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);5308break;53095310/* SIMD memory to xmm reg */5311case XMMM:5312case XMMM_66r:5313case XMMOM:5314wbit = XMM_OPND;5315dtrace_get_modrm(x, &mode, ®, &r_m);5316#ifdef DIS_TEXT5317if (mode == REG_ONLY) {5318if (strcmp(dp->it_name, "movhps") == 0)5319(void) strncpy(x->d86_mnem, "movlhps", OPLEN);5320else5321goto error;5322}5323#endif5324MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);5325break;53265327/* SIMD memory or r32 to xmm reg */5328case XMM3MX:5329wbit = LONG_OPND;5330MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);5331break;53325333case XMM3MXS:5334wbit = LONG_OPND;5335MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);5336break;53375338/* SIMD memory or mm reg to xmm reg */5339case XMMOMX:5340/* SIMD mm to xmm */5341case XMMMX:5342wbit = MM_OPND;5343MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);5344break;53455346/* SIMD memory or xmm reg to mm reg */5347case XMMXMM:5348case XMMOXMM:5349case XMMXM:5350wbit = XMM_OPND;5351MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);5352break;535353545355/* SIMD memory or xmm reg to r32 */5356case XMMXM3:5357wbit = XMM_OPND;5358MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);5359break;53605361/* SIMD xmm to r32 */5362case XMMX3:5363case XMMOX3:5364dtrace_get_modrm(x, &mode, ®, &r_m);5365if (mode != REG_ONLY)5366goto error;5367dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);5368dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);5369dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);5370NOMEM;5371break;53725373/* SIMD predicated memory or xmm reg with/to xmm reg */5374case XMMP:5375case XMMP_66r:5376case XMMP_66o:5377case XMMOPM:5378wbit = XMM_OPND;5379THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,53801);53815382#ifdef DIS_TEXT5383/*5384* cmpps and cmpss vary their instruction name based5385* on the value of imm8. Other XMMP instructions,5386* such as shufps, require explicit specification of5387* the predicate.5388*/5389if (dp->it_name[0] == 'c' &&5390dp->it_name[1] == 'm' &&5391dp->it_name[2] == 'p' &&5392strlen(dp->it_name) == 5) {5393uchar_t pred = x->d86_opnd[0].d86_value & 0xff;53945395if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))5396goto error;53975398(void) strncpy(x->d86_mnem, "cmp", OPLEN);5399(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],5400OPLEN);5401(void) strlcat(x->d86_mnem,5402dp->it_name + strlen(dp->it_name) - 2,5403OPLEN);5404x->d86_opnd[0] = x->d86_opnd[1];5405x->d86_opnd[1] = x->d86_opnd[2];5406x->d86_numopnds = 2;5407}54085409/*5410* The pclmulqdq instruction has a series of alternate names for5411* various encodings of the immediate byte. As such, if we5412* happen to find it and the immediate value matches, we'll5413* rewrite the mnemonic.5414*/5415if (strcmp(dp->it_name, "pclmulqdq") == 0) {5416boolean_t changed = B_TRUE;5417switch (x->d86_opnd[0].d86_value) {5418case 0x00:5419(void) strncpy(x->d86_mnem, "pclmullqlqdq",5420OPLEN);5421break;5422case 0x01:5423(void) strncpy(x->d86_mnem, "pclmulhqlqdq",5424OPLEN);5425break;5426case 0x10:5427(void) strncpy(x->d86_mnem, "pclmullqhqdq",5428OPLEN);5429break;5430case 0x11:5431(void) strncpy(x->d86_mnem, "pclmulhqhqdq",5432OPLEN);5433break;5434default:5435changed = B_FALSE;5436break;5437}54385439if (changed == B_TRUE) {5440x->d86_opnd[0].d86_value_size = 0;5441x->d86_opnd[0] = x->d86_opnd[1];5442x->d86_opnd[1] = x->d86_opnd[2];5443x->d86_numopnds = 2;5444}5445}5446#endif5447break;54485449case XMMX2I:5450FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,54511);5452NOMEM;5453break;54545455case XMM2I:5456ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);5457NOMEM;5458break;54595460/* immediate operand to accumulator */5461case IA:5462wbit = WBIT(opcode2);5463dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);5464dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);5465NOMEM;5466break;54675468/* memory or register operand to accumulator */5469case MA:5470wbit = WBIT(opcode2);5471dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);5472dtrace_get_operand(x, mode, r_m, wbit, 0);5473break;54745475/* si register to di register used to reference memory */5476case SD:5477#ifdef DIS_TEXT5478dtrace_check_override(x, 0);5479x->d86_numopnds = 2;5480if (addr_size == SIZE64) {5481(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",5482OPLEN);5483(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",5484OPLEN);5485} else if (addr_size == SIZE32) {5486(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",5487OPLEN);5488(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",5489OPLEN);5490} else {5491(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",5492OPLEN);5493(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",5494OPLEN);5495}5496#endif5497wbit = LONG_OPND;5498break;54995500/* accumulator to di register */5501case AD:5502wbit = WBIT(opcode2);5503#ifdef DIS_TEXT5504dtrace_check_override(x, 1);5505x->d86_numopnds = 2;5506dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);5507if (addr_size == SIZE64)5508(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",5509OPLEN);5510else if (addr_size == SIZE32)5511(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",5512OPLEN);5513else5514(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",5515OPLEN);5516#endif5517break;55185519/* si register to accumulator */5520case SA:5521wbit = WBIT(opcode2);5522#ifdef DIS_TEXT5523dtrace_check_override(x, 0);5524x->d86_numopnds = 2;5525if (addr_size == SIZE64)5526(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",5527OPLEN);5528else if (addr_size == SIZE32)5529(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",5530OPLEN);5531else5532(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",5533OPLEN);5534dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);5535#endif5536break;55375538/*5539* single operand, a 16/32 bit displacement5540*/5541case D:5542wbit = LONG_OPND;5543dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);5544NOMEM;5545break;55465547/* jmp/call indirect to memory or register operand */5548case INM:5549#ifdef DIS_TEXT5550(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);5551#endif5552dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);5553dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);5554wbit = LONG_OPND;5555break;55565557/*5558* for long jumps and long calls -- a new code segment5559* register and an offset in IP -- stored in object5560* code in reverse order. Note - not valid in amd645561*/5562case SO:5563dtrace_check_override(x, 1);5564wbit = LONG_OPND;5565dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);5566#ifdef DIS_TEXT5567x->d86_opnd[1].d86_mode = MODE_SIGNED;5568#endif5569/* will now get segment operand */5570dtrace_imm_opnd(x, wbit, 2, 0);5571break;55725573/*5574* jmp/call. single operand, 8 bit displacement.5575* added to current EIP in 'compofff'5576*/5577case BD:5578dtrace_disp_opnd(x, BYTE_OPND, 1, 0);5579NOMEM;5580break;55815582/* single 32/16 bit immediate operand */5583case I:5584wbit = LONG_OPND;5585dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);5586break;55875588/* single 8 bit immediate operand */5589case Ib:5590wbit = LONG_OPND;5591dtrace_imm_opnd(x, wbit, 1, 0);5592break;55935594case ENTER:5595wbit = LONG_OPND;5596dtrace_imm_opnd(x, wbit, 2, 0);5597dtrace_imm_opnd(x, wbit, 1, 1);5598switch (opnd_size) {5599case SIZE64:5600x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;5601break;5602case SIZE32:5603x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;5604break;5605case SIZE16:5606x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;5607break;5608}56095610break;56115612/* 16-bit immediate operand */5613case RET:5614wbit = LONG_OPND;5615dtrace_imm_opnd(x, wbit, 2, 0);5616break;56175618/* single 8 bit port operand */5619case P:5620dtrace_check_override(x, 0);5621dtrace_imm_opnd(x, BYTE_OPND, 1, 0);5622NOMEM;5623break;56245625/* single operand, dx register (variable port instruction) */5626case V:5627x->d86_numopnds = 1;5628dtrace_check_override(x, 0);5629#ifdef DIS_TEXT5630(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);5631#endif5632NOMEM;5633break;56345635/*5636* The int instruction, which has two forms:5637* int 3 (breakpoint) or5638* int n, where n is indicated in the subsequent5639* byte (format Ib). The int 3 instruction (opcode 0xCC),5640* where, although the 3 looks like an operand,5641* it is implied by the opcode. It must be converted5642* to the correct base and output.5643*/5644case INT3:5645#ifdef DIS_TEXT5646x->d86_numopnds = 1;5647x->d86_opnd[0].d86_mode = MODE_SIGNED;5648x->d86_opnd[0].d86_value_size = 1;5649x->d86_opnd[0].d86_value = 3;5650#endif5651NOMEM;5652break;56535654/* single 8 bit immediate operand */5655case INTx:5656dtrace_imm_opnd(x, BYTE_OPND, 1, 0);5657NOMEM;5658break;56595660/* an unused byte must be discarded */5661case U:5662if (x->d86_get_byte(x->d86_data) < 0)5663goto error;5664x->d86_len++;5665NOMEM;5666break;56675668case CBW:5669#ifdef DIS_TEXT5670if (opnd_size == SIZE16)5671(void) strlcat(x->d86_mnem, "cbtw", OPLEN);5672else if (opnd_size == SIZE32)5673(void) strlcat(x->d86_mnem, "cwtl", OPLEN);5674else5675(void) strlcat(x->d86_mnem, "cltq", OPLEN);5676#endif5677wbit = LONG_OPND;5678NOMEM;5679break;56805681case CWD:5682#ifdef DIS_TEXT5683if (opnd_size == SIZE16)5684(void) strlcat(x->d86_mnem, "cwtd", OPLEN);5685else if (opnd_size == SIZE32)5686(void) strlcat(x->d86_mnem, "cltd", OPLEN);5687else5688(void) strlcat(x->d86_mnem, "cqtd", OPLEN);5689#endif5690wbit = LONG_OPND;5691NOMEM;5692break;56935694case XMMSFNC:5695/*5696* sfence is sfence if mode is REG_ONLY. If mode isn't5697* REG_ONLY, mnemonic should be 'clflush'.5698*/5699dtrace_get_modrm(x, &mode, ®, &r_m);57005701/* sfence doesn't take operands */5702if (mode != REG_ONLY) {5703if (opnd_size_prefix == 0x66) {5704#ifdef DIS_TEXT5705(void) strlcat(x->d86_mnem, "clflushopt",5706OPLEN);5707#endif5708} else if (opnd_size_prefix == 0) {5709#ifdef DIS_TEXT5710(void) strlcat(x->d86_mnem, "clflush", OPLEN);5711#endif5712} else {5713/* Unknown instruction */5714goto error;5715}57165717dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);5718dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);5719NOMEM;5720#ifdef DIS_TEXT5721} else {5722(void) strlcat(x->d86_mnem, "sfence", OPLEN);5723#endif5724}5725break;57265727case FSGS:5728/*5729* The FSGSBASE instructions are taken only when the mode is set5730* to registers. They share opcodes with instructions like5731* fxrstor, stmxcsr, etc. We handle the repz prefix earlier.5732*/5733wbit = WBIT(opcode2);5734dtrace_get_modrm(x, &mode, ®, &r_m);5735dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);5736dtrace_get_operand(x, mode, r_m, wbit, 0);5737if (mode == REG_ONLY) {5738NOMEM;5739}5740break;57415742/*5743* no disassembly, the mnemonic was all there was so go on5744*/5745case NORM:5746if (dp->it_invalid32 && cpu_mode != SIZE64)5747goto error;5748NOMEM;5749/*FALLTHROUGH*/5750case IMPLMEM:5751break;57525753case XMMFENCE:5754/*5755* XRSTOR, XSAVEOPT and LFENCE share the same opcode but5756* differ in mode and reg.5757*/5758dtrace_get_modrm(x, &mode, ®, &r_m);57595760if (mode == REG_ONLY) {5761/*5762* Only the following exact byte sequences are allowed:5763*5764* 0f ae e8 lfence5765* 0f ae f0 mfence5766*/5767if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&5768(uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)5769goto error;5770} else {5771#ifdef DIS_TEXT5772if (reg == 5) {5773(void) strncpy(x->d86_mnem, "xrstor", OPLEN);5774} else if (reg == 6) {5775if (opnd_size_prefix == 0x66) {5776(void) strncpy(x->d86_mnem, "clwb",5777OPLEN);5778} else if (opnd_size_prefix == 0x00) {5779(void) strncpy(x->d86_mnem, "xsaveopt",5780OPLEN);5781} else {5782goto error;5783}5784} else {5785goto error;5786}5787#endif5788dtrace_rex_adjust(rex_prefix, mode, ®, &r_m);5789dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);5790wbit = LONG_OPND;5791}5792break;57935794/* float reg */5795case F:5796#ifdef DIS_TEXT5797x->d86_numopnds = 1;5798(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);5799x->d86_opnd[0].d86_opnd[4] = r_m + '0';5800#endif5801NOMEM;5802break;58035804/* float reg to float reg, with ret bit present */5805case FF:5806vbit = opcode2 >> 2 & 0x1; /* vbit = 1: st -> st(i) */5807/*FALLTHROUGH*/5808case FFC: /* case for vbit always = 0 */5809#ifdef DIS_TEXT5810x->d86_numopnds = 2;5811(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);5812(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);5813x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';5814#endif5815NOMEM;5816break;58175818/* AVX instructions */5819case VEX_MO:5820/* op(ModR/M.r/m) */5821x->d86_numopnds = 1;5822dtrace_get_modrm(x, &mode, ®, &r_m);5823#ifdef DIS_TEXT5824if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))5825(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);5826#endif5827dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);5828dtrace_get_operand(x, mode, r_m, wbit, 0);5829break;5830case VEX_RMrX:5831case FMA:5832/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */5833x->d86_numopnds = 3;5834dtrace_get_modrm(x, &mode, ®, &r_m);5835dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);58365837/*5838* In classic Intel fashion, the opcodes for all of the FMA5839* instructions all have two possible mnemonics which vary by5840* one letter, which is selected based on the value of the wbit.5841* When wbit is one, they have the 'd' suffix and when 'wbit' is5842* 0, they have the 's' suffix. Otherwise, the FMA instructions5843* are all a standard VEX_RMrX.5844*/5845#ifdef DIS_TEXT5846if (dp->it_adrmode == FMA) {5847size_t len = strlen(dp->it_name);5848(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);5849if (len + 1 < OPLEN) {5850(void) strncpy(x->d86_mnem + len,5851vex_W != 0 ? "d" : "s", OPLEN - len);5852}5853}5854#endif58555856if (mode != REG_ONLY) {5857if ((dp == &dis_opAVXF20F[0x10]) ||5858(dp == &dis_opAVXF30F[0x10])) {5859/* vmovsd <m64>, <xmm> */5860/* or vmovss <m64>, <xmm> */5861x->d86_numopnds = 2;5862goto L_VEX_MX;5863}5864}58655866dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);5867/*5868* VEX prefix uses the 1's complement form to encode the5869* XMM/YMM regs5870*/5871dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);58725873if ((dp == &dis_opAVXF20F[0x2A]) ||5874(dp == &dis_opAVXF30F[0x2A])) {5875/*5876* vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,5877* <xmm>, <xmm>5878*/5879wbit = LONG_OPND;5880}5881#ifdef DIS_TEXT5882else if ((mode == REG_ONLY) &&5883(dp == &dis_opAVX0F[0x1][0x6])) { /* vmovlhps */5884(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);5885} else if ((mode == REG_ONLY) &&5886(dp == &dis_opAVX0F[0x1][0x2])) { /* vmovhlps */5887(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);5888}5889#endif5890dtrace_get_operand(x, mode, r_m, wbit, 0);58915892break;58935894case VEX_VRMrX:5895/* ModR/M.reg := op(MODR/M.r/m, VEX.vvvv) */5896x->d86_numopnds = 3;5897dtrace_get_modrm(x, &mode, ®, &r_m);5898dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);58995900dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);5901/*5902* VEX prefix uses the 1's complement form to encode the5903* XMM/YMM regs5904*/5905dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 0);59065907dtrace_get_operand(x, mode, r_m, wbit, 1);5908break;59095910case VEX_SbVM:5911/* ModR/M.reg := op(MODR/M.r/m, VSIB, VEX.vvvv) */5912x->d86_numopnds = 3;5913x->d86_vsib = 1;59145915/*5916* All instructions that use VSIB are currently a mess. See the5917* comment around the dis_gather_regs_t structure definition.5918*/59195920vreg = &dis_vgather[opcode2][vex_W][vex_L];59215922#ifdef DIS_TEXT5923(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);5924(void) strlcat(x->d86_mnem + strlen(dp->it_name),5925vreg->dgr_suffix, OPLEN - strlen(dp->it_name));5926#endif59275928dtrace_get_modrm(x, &mode, ®, &r_m);5929dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);59305931dtrace_get_operand(x, REG_ONLY, reg, vreg->dgr_arg2, 2);5932/*5933* VEX prefix uses the 1's complement form to encode the5934* XMM/YMM regs5935*/5936dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), vreg->dgr_arg0,59370);5938dtrace_get_operand(x, mode, r_m, vreg->dgr_arg1, 1);5939break;59405941case VEX_RRX:5942/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */5943x->d86_numopnds = 3;59445945dtrace_get_modrm(x, &mode, ®, &r_m);5946dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);59475948if (mode != REG_ONLY) {5949if ((dp == &dis_opAVXF20F[0x11]) ||5950(dp == &dis_opAVXF30F[0x11])) {5951/* vmovsd <xmm>, <m64> */5952/* or vmovss <xmm>, <m64> */5953x->d86_numopnds = 2;5954goto L_VEX_RM;5955}5956}59575958dtrace_get_operand(x, mode, r_m, wbit, 2);5959dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);5960dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);5961break;59625963case VEX_RMRX:5964/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */5965x->d86_numopnds = 4;59665967dtrace_get_modrm(x, &mode, ®, &r_m);5968dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);5969dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);5970dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);5971if (dp == &dis_opAVX660F3A[0x18]) {5972/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */5973dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);5974} else if ((dp == &dis_opAVX660F3A[0x20]) ||5975(dp == & dis_opAVX660F[0xC4])) {5976/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */5977/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */5978dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);5979} else if (dp == &dis_opAVX660F3A[0x22]) {5980/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */5981#ifdef DIS_TEXT5982if (vex_W)5983x->d86_mnem[6] = 'q';5984#endif5985dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);5986} else {5987dtrace_get_operand(x, mode, r_m, wbit, 1);5988}59895990/* one byte immediate number */5991dtrace_imm_opnd(x, wbit, 1, 0);59925993/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */5994if ((dp == &dis_opAVX660F3A[0x4A]) ||5995(dp == &dis_opAVX660F3A[0x4B]) ||5996(dp == &dis_opAVX660F3A[0x4C])) {5997#ifdef DIS_TEXT5998int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;5999#endif6000x->d86_opnd[0].d86_mode = MODE_NONE;6001#ifdef DIS_TEXT6002if (vex_L)6003(void) strncpy(x->d86_opnd[0].d86_opnd,6004dis_YMMREG[regnum], OPLEN);6005else6006(void) strncpy(x->d86_opnd[0].d86_opnd,6007dis_XMMREG[regnum], OPLEN);6008#endif6009}6010break;60116012case VEX_MX:6013/* ModR/M.reg := op(ModR/M.rm) */6014x->d86_numopnds = 2;60156016dtrace_get_modrm(x, &mode, ®, &r_m);6017dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6018L_VEX_MX:60196020if ((dp == &dis_opAVXF20F[0xE6]) ||6021(dp == &dis_opAVX660F[0x5A]) ||6022(dp == &dis_opAVX660F[0xE6])) {6023/* vcvtpd2dq <ymm>, <xmm> */6024/* or vcvtpd2ps <ymm>, <xmm> */6025/* or vcvttpd2dq <ymm>, <xmm> */6026dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);6027dtrace_get_operand(x, mode, r_m, wbit, 0);6028} else if ((dp == &dis_opAVXF30F[0xE6]) ||6029(dp == &dis_opAVX0F[0x5][0xA]) ||6030(dp == &dis_opAVX660F38[0x13]) ||6031(dp == &dis_opAVX660F38[0x18]) ||6032(dp == &dis_opAVX660F38[0x19]) ||6033(dp == &dis_opAVX660F38[0x58]) ||6034(dp == &dis_opAVX660F38[0x78]) ||6035(dp == &dis_opAVX660F38[0x79]) ||6036(dp == &dis_opAVX660F38[0x59])) {6037/* vcvtdq2pd <xmm>, <ymm> */6038/* or vcvtps2pd <xmm>, <ymm> */6039/* or vcvtph2ps <xmm>, <ymm> */6040/* or vbroadcasts* <xmm>, <ymm> */6041dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6042dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);6043} else if (dp == &dis_opAVX660F[0x6E]) {6044/* vmovd/q <reg/mem 32/64>, <xmm> */6045#ifdef DIS_TEXT6046if (vex_W)6047x->d86_mnem[4] = 'q';6048#endif6049dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6050dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);6051} else {6052dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6053dtrace_get_operand(x, mode, r_m, wbit, 0);6054}60556056break;60576058case VEX_MXI:6059/* ModR/M.reg := op(ModR/M.rm, imm8) */6060x->d86_numopnds = 3;60616062dtrace_get_modrm(x, &mode, ®, &r_m);6063dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);60646065dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);6066dtrace_get_operand(x, mode, r_m, wbit, 1);60676068/* one byte immediate number */6069dtrace_imm_opnd(x, wbit, 1, 0);6070break;60716072case VEX_XXI:6073/* VEX.vvvv := op(ModR/M.rm, imm8) */6074x->d86_numopnds = 3;60756076dtrace_get_modrm(x, &mode, ®, &r_m);6077#ifdef DIS_TEXT6078(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],6079OPLEN);6080#endif6081dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);60826083dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);6084dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);60856086/* one byte immediate number */6087dtrace_imm_opnd(x, wbit, 1, 0);6088break;60896090case VEX_MR:6091/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */6092if (dp == &dis_opAVX660F[0xC5]) {6093/* vpextrw <imm8>, <xmm>, <reg> */6094x->d86_numopnds = 2;6095vbit = 2;6096} else {6097x->d86_numopnds = 2;6098vbit = 1;6099}61006101dtrace_get_modrm(x, &mode, ®, &r_m);6102dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6103dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);6104dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);61056106if (vbit == 2)6107dtrace_imm_opnd(x, wbit, 1, 0);61086109break;61106111case VEX_KMR:6112/* opmask: mod_rm := %k */6113x->d86_numopnds = 2;6114dtrace_get_modrm(x, &mode, ®, &r_m);6115dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6116dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);6117dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);6118break;61196120case VEX_KRM:6121/* opmask: mod_reg := mod_rm */6122x->d86_numopnds = 2;6123dtrace_get_modrm(x, &mode, ®, &r_m);6124dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6125dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6126if (mode == REG_ONLY) {6127dtrace_get_operand(x, mode, r_m, KOPMASK_OPND, 0);6128} else {6129dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);6130}6131break;61326133case VEX_KRR:6134/* opmask: mod_reg := mod_rm */6135x->d86_numopnds = 2;6136dtrace_get_modrm(x, &mode, ®, &r_m);6137dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6138dtrace_get_operand(x, mode, reg, wbit, 1);6139dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 0);6140break;61416142case VEX_RRI:6143/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */6144x->d86_numopnds = 2;61456146dtrace_get_modrm(x, &mode, ®, &r_m);6147dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6148dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6149dtrace_get_operand(x, mode, r_m, wbit, 0);6150break;61516152case VEX_RX:6153/* ModR/M.rm := op(ModR/M.reg) */6154/* vextractf128 || vcvtps2ph */6155if (dp == &dis_opAVX660F3A[0x19] ||6156dp == &dis_opAVX660F3A[0x1d]) {6157x->d86_numopnds = 3;61586159dtrace_get_modrm(x, &mode, ®, &r_m);6160dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);61616162dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);6163dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);61646165/* one byte immediate number */6166dtrace_imm_opnd(x, wbit, 1, 0);6167break;6168}61696170x->d86_numopnds = 2;61716172dtrace_get_modrm(x, &mode, ®, &r_m);6173dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6174dtrace_get_operand(x, mode, r_m, wbit, 1);6175dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);6176break;61776178case VEX_RR:6179/* ModR/M.rm := op(ModR/M.reg) */6180x->d86_numopnds = 2;61816182dtrace_get_modrm(x, &mode, ®, &r_m);6183dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);61846185if (dp == &dis_opAVX660F[0x7E]) {6186/* vmovd/q <reg/mem 32/64>, <xmm> */6187#ifdef DIS_TEXT6188if (vex_W)6189x->d86_mnem[4] = 'q';6190#endif6191dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);6192} else6193dtrace_get_operand(x, mode, r_m, wbit, 1);61946195dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);6196break;61976198case VEX_RRi:6199/* ModR/M.rm := op(ModR/M.reg, imm) */6200x->d86_numopnds = 3;62016202dtrace_get_modrm(x, &mode, ®, &r_m);6203dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);62046205#ifdef DIS_TEXT6206if (dp == &dis_opAVX660F3A[0x16]) {6207/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */6208if (vex_W)6209x->d86_mnem[6] = 'q';6210}6211#endif6212dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);6213dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);62146215/* one byte immediate number */6216dtrace_imm_opnd(x, wbit, 1, 0);6217break;6218case VEX_RIM:6219/* ModR/M.rm := op(ModR/M.reg, imm) */6220x->d86_numopnds = 3;62216222dtrace_get_modrm(x, &mode, ®, &r_m);6223dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);62246225dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);6226dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6227/* one byte immediate number */6228dtrace_imm_opnd(x, wbit, 1, 0);6229break;62306231case VEX_RM:6232/* ModR/M.rm := op(ModR/M.reg) */6233if (dp == &dis_opAVX660F3A[0x17]) { /* vextractps */6234x->d86_numopnds = 3;62356236dtrace_get_modrm(x, &mode, ®, &r_m);6237dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);62386239dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);6240dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6241/* one byte immediate number */6242dtrace_imm_opnd(x, wbit, 1, 0);6243break;6244}6245x->d86_numopnds = 2;62466247dtrace_get_modrm(x, &mode, ®, &r_m);6248dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6249L_VEX_RM:6250vbit = 1;6251dtrace_get_operand(x, mode, r_m, wbit, vbit);6252dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);62536254break;62556256case VEX_RRM:6257/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */6258x->d86_numopnds = 3;62596260dtrace_get_modrm(x, &mode, ®, &r_m);6261dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6262dtrace_get_operand(x, mode, r_m, wbit, 2);6263/* VEX use the 1's complement form encode the XMM/YMM regs */6264dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);6265dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);6266break;62676268case VEX_RMX:6269/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */6270x->d86_numopnds = 3;62716272dtrace_get_modrm(x, &mode, ®, &r_m);6273dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);6274dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);6275dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);6276dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);6277break;62786279case VEX_NONE:6280#ifdef DIS_TEXT6281if (vex_L)6282(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);6283#endif6284break;6285case BLS: {62866287/*6288* The BLS instructions are VEX instructions that are based on6289* VEX.0F38.F3; however, they are considered special group 176290* and like everything else, they use the bits in 3-5 of the6291* MOD R/M to determine the sub instruction. Unlike many others6292* like the VMX instructions, these are valid both for memory6293* and register forms.6294*/62956296dtrace_get_modrm(x, &mode, ®, &r_m);6297dtrace_vex_adjust(vex_byte1, mode, ®, &r_m);62986299switch (reg) {6300case 1:6301#ifdef DIS_TEXT6302blsinstr = "blsr";6303#endif6304break;6305case 2:6306#ifdef DIS_TEXT6307blsinstr = "blsmsk";6308#endif6309break;6310case 3:6311#ifdef DIS_TEXT6312blsinstr = "blsi";6313#endif6314break;6315default:6316goto error;6317}63186319x->d86_numopnds = 2;6320#ifdef DIS_TEXT6321(void) strncpy(x->d86_mnem, blsinstr, OPLEN);6322#endif6323dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);6324dtrace_get_operand(x, mode, r_m, wbit, 0);6325break;6326}6327case EVEX_MX:6328/* ModR/M.reg := op(ModR/M.rm) */6329x->d86_numopnds = 2;6330dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);6331dtrace_get_modrm(x, &mode, ®, &r_m);6332evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;6333dtrace_evex_adjust_reg(evex_byte1, ®);6334dtrace_evex_adjust_rm(evex_byte1, &r_m);6335dtrace_evex_adjust_reg_name(evex_L, &wbit);6336dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);6337dtrace_evex_adjust_z_opmask(x, 1, evex_byte3);6338dtrace_get_operand(x, mode, r_m, wbit, 0);6339dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);6340break;6341case EVEX_RX:6342/* ModR/M.rm := op(ModR/M.reg) */6343x->d86_numopnds = 2;6344dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);6345dtrace_get_modrm(x, &mode, ®, &r_m);6346evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;6347dtrace_evex_adjust_reg(evex_byte1, ®);6348dtrace_evex_adjust_rm(evex_byte1, &r_m);6349dtrace_evex_adjust_reg_name(evex_L, &wbit);6350dtrace_get_operand(x, mode, r_m, wbit, 1);6351dtrace_evex_adjust_disp8_n(x, 1, evex_L, evex_modrm);6352dtrace_evex_adjust_z_opmask(x, 1, evex_byte3);6353dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);6354break;6355case EVEX_RMrX:6356/* ModR/M.reg := op(EVEX.vvvv, ModR/M.r/m) */6357x->d86_numopnds = 3;6358dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);6359dtrace_get_modrm(x, &mode, ®, &r_m);6360evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;6361dtrace_evex_adjust_reg(evex_byte1, ®);6362dtrace_evex_adjust_rm(evex_byte1, &r_m);6363dtrace_evex_adjust_reg_name(evex_L, &wbit);6364dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);6365/*6366* EVEX.vvvv is the same as VEX.vvvv (ones complement of the6367* register specifier). The EVEX prefix handling uses the vex_v6368* variable for these bits.6369*/6370dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);6371dtrace_get_operand(x, mode, r_m, wbit, 0);6372dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);6373dtrace_evex_adjust_z_opmask(x, 2, evex_byte3);6374break;6375case EVEX_RMRX:6376/* ModR/M.reg := op(EVEX.vvvv, ModR/M.r_m, imm8) */6377x->d86_numopnds = 4;63786379dtrace_evex_mnem_adjust(x, dp, vex_W, evex_byte2);6380dtrace_get_modrm(x, &mode, ®, &r_m);6381evex_modrm = x->d86_bytes[x->d86_len - 1] & 0xff;6382dtrace_evex_adjust_reg(evex_byte1, ®);6383dtrace_evex_adjust_rm(evex_byte1, &r_m);6384dtrace_evex_adjust_reg_name(evex_L, &wbit);6385dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);6386/*6387* EVEX.vvvv is the same as VEX.vvvv (ones complement of the6388* register specifier). The EVEX prefix handling uses the vex_v6389* variable for these bits.6390*/6391dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);6392dtrace_get_operand(x, mode, r_m, wbit, 1);6393dtrace_evex_adjust_disp8_n(x, 0, evex_L, evex_modrm);6394dtrace_evex_adjust_z_opmask(x, 3, evex_byte3);63956396dtrace_imm_opnd(x, wbit, 1, 0);6397break;6398/* an invalid op code */6399case AM:6400case DM:6401case OVERRIDE:6402case PREFIX:6403case UNKNOWN:6404NOMEM;6405default:6406goto error;6407} /* end switch */6408if (x->d86_error)6409goto error;64106411done:6412#ifdef DIS_MEM6413/*6414* compute the size of any memory accessed by the instruction6415*/6416if (x->d86_memsize != 0) {6417return (0);6418} else if (dp->it_stackop) {6419switch (opnd_size) {6420case SIZE16:6421x->d86_memsize = 2;6422break;6423case SIZE32:6424x->d86_memsize = 4;6425break;6426case SIZE64:6427x->d86_memsize = 8;6428break;6429}6430} else if (nomem || mode == REG_ONLY) {6431x->d86_memsize = 0;64326433} else if (dp->it_size != 0) {6434/*6435* In 64 bit mode descriptor table entries6436* go up to 10 bytes and popf/pushf are always 8 bytes6437*/6438if (x->d86_mode == SIZE64 && dp->it_size == 6)6439x->d86_memsize = 10;6440else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&6441(opcode2 == 0xc || opcode2 == 0xd))6442x->d86_memsize = 8;6443else6444x->d86_memsize = dp->it_size;64456446} else if (wbit == BYTE_OPND) {6447x->d86_memsize = 1;64486449} else if (wbit == LONG_OPND) {6450if (opnd_size == SIZE64)6451x->d86_memsize = 8;6452else if (opnd_size == SIZE32)6453x->d86_memsize = 4;6454else6455x->d86_memsize = 2;64566457} else if (wbit == SEG_OPND) {6458x->d86_memsize = 4;64596460} else {6461x->d86_memsize = 8;6462}6463#endif6464return (0);64656466error:6467#ifdef DIS_TEXT6468(void) strlcat(x->d86_mnem, "undef", OPLEN);6469#endif6470return (1);6471}64726473#ifdef DIS_TEXT64746475/*6476* Some instructions should have immediate operands printed6477* as unsigned integers. We compare against this table.6478*/6479static char *unsigned_ops[] = {6480"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",6481"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",648206483};648464856486static int6487isunsigned_op(char *opcode)6488{6489char *where;6490int i;6491int is_unsigned = 0;64926493/*6494* Work back to start of last mnemonic, since we may have6495* prefixes on some opcodes.6496*/6497where = opcode + strlen(opcode) - 1;6498while (where > opcode && *where != ' ')6499--where;6500if (*where == ' ')6501++where;65026503for (i = 0; unsigned_ops[i]; ++i) {6504if (strncmp(where, unsigned_ops[i],6505strlen(unsigned_ops[i])))6506continue;6507is_unsigned = 1;6508break;6509}6510return (is_unsigned);6511}65126513/*6514* Print a numeric immediate into end of buf, maximum length buflen.6515* The immediate may be an address or a displacement. Mask is set6516* for address size. If the immediate is a "small negative", or6517* if it's a negative displacement of any magnitude, print as -<absval>.6518* Respect the "octal" flag. "Small negative" is defined as "in the6519* interval [NEG_LIMIT, 0)".6520*6521* Also, "isunsigned_op()" instructions never print negatives.6522*6523* Return whether we decided to print a negative value or not.6524*/65256526#define NEG_LIMIT -2556527enum {IMM, DISP};6528enum {POS, TRY_NEG};65296530static int6531print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,6532size_t buflen, int disp, int try_neg)6533{6534int curlen;6535int64_t sv = (int64_t)usv;6536int octal = dis->d86_flags & DIS_F_OCTAL;65376538curlen = strlen(buf);65396540if (try_neg == TRY_NEG && sv < 0 &&6541(disp || sv >= NEG_LIMIT) &&6542!isunsigned_op(dis->d86_mnem)) {6543dis->d86_sprintf_func(buf + curlen, buflen - curlen,6544octal ? "-0%llo" : "-0x%llx", (-sv) & mask);6545return (1);6546} else {6547if (disp == DISP)6548dis->d86_sprintf_func(buf + curlen, buflen - curlen,6549octal ? "+0%llo" : "+0x%llx", usv & mask);6550else6551dis->d86_sprintf_func(buf + curlen, buflen - curlen,6552octal ? "0%llo" : "0x%llx", usv & mask);6553return (0);65546555}6556}655765586559static int6560log2(int size)6561{6562switch (size) {6563case 1: return (0);6564case 2: return (1);6565case 4: return (2);6566case 8: return (3);6567}6568return (0);6569}65706571/* ARGSUSED */6572void6573dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,6574size_t buflen)6575{6576uint64_t reltgt = 0;6577uint64_t tgt = 0;6578int curlen;6579int (*lookup)(void *, uint64_t, char *, size_t);6580int i;6581int64_t sv;6582uint64_t usv, mask, save_mask, save_usv;6583static uint64_t masks[] =6584{0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};6585save_usv = 0;65866587dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);65886589/*6590* For PC-relative jumps, the pc is really the next pc after executing6591* this instruction, so increment it appropriately.6592*/6593pc += dis->d86_len;65946595for (i = 0; i < dis->d86_numopnds; i++) {6596d86opnd_t *op = &dis->d86_opnd[i];65976598if (i != 0)6599(void) strlcat(buf, ",", buflen);66006601(void) strlcat(buf, op->d86_prefix, buflen);66026603/*6604* sv is for the signed, possibly-truncated immediate or6605* displacement; usv retains the original size and6606* unsignedness for symbol lookup.6607*/66086609sv = usv = op->d86_value;66106611/*6612* About masks: for immediates that represent6613* addresses, the appropriate display size is6614* the effective address size of the instruction.6615* This includes MODE_OFFSET, MODE_IPREL, and6616* MODE_RIPREL. Immediates that are simply6617* immediate values should display in the operand's6618* size, however, since they don't represent addresses.6619*/66206621/* d86_addr_size is SIZEnn, which is log2(real size) */6622mask = masks[dis->d86_addr_size];66236624/* d86_value_size and d86_imm_bytes are in bytes */6625if (op->d86_mode == MODE_SIGNED ||6626op->d86_mode == MODE_IMPLIED)6627mask = masks[log2(op->d86_value_size)];66286629switch (op->d86_mode) {66306631case MODE_NONE:66326633(void) strlcat(buf, op->d86_opnd, buflen);6634break;66356636case MODE_SIGNED:6637case MODE_IMPLIED:6638case MODE_OFFSET:66396640tgt = usv;66416642if (dis->d86_seg_prefix)6643(void) strlcat(buf, dis->d86_seg_prefix,6644buflen);66456646if (op->d86_mode == MODE_SIGNED ||6647op->d86_mode == MODE_IMPLIED) {6648(void) strlcat(buf, "$", buflen);6649}66506651if (print_imm(dis, usv, mask, buf, buflen,6652IMM, TRY_NEG) &&6653(op->d86_mode == MODE_SIGNED ||6654op->d86_mode == MODE_IMPLIED)) {66556656/*6657* We printed a negative value for an6658* immediate that wasn't a6659* displacement. Note that fact so we can6660* print the positive value as an6661* annotation.6662*/66636664save_usv = usv;6665save_mask = mask;6666}6667(void) strlcat(buf, op->d86_opnd, buflen);6668break;66696670case MODE_IPREL:6671case MODE_RIPREL:66726673reltgt = pc + sv;66746675switch (mode) {6676case SIZE16:6677reltgt = (uint16_t)reltgt;6678break;6679case SIZE32:6680reltgt = (uint32_t)reltgt;6681break;6682}66836684(void) print_imm(dis, usv, mask, buf, buflen,6685DISP, TRY_NEG);66866687if (op->d86_mode == MODE_RIPREL)6688(void) strlcat(buf, "(%rip)", buflen);6689break;6690}6691}66926693/*6694* The symbol lookups may result in false positives,6695* particularly on object files, where small numbers may match6696* the 0-relative non-relocated addresses of symbols.6697*/66986699lookup = dis->d86_sym_lookup;6700if (tgt != 0) {6701if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&6702lookup(dis->d86_data, tgt, NULL, 0) == 0) {6703(void) strlcat(buf, "\t<", buflen);6704curlen = strlen(buf);6705lookup(dis->d86_data, tgt, buf + curlen,6706buflen - curlen);6707(void) strlcat(buf, ">", buflen);6708}67096710/*6711* If we printed a negative immediate above, print the6712* positive in case our heuristic was unhelpful6713*/6714if (save_usv) {6715(void) strlcat(buf, "\t<", buflen);6716(void) print_imm(dis, save_usv, save_mask, buf, buflen,6717IMM, POS);6718(void) strlcat(buf, ">", buflen);6719}6720}67216722if (reltgt != 0) {6723/* Print symbol or effective address for reltgt */67246725(void) strlcat(buf, "\t<", buflen);6726curlen = strlen(buf);6727lookup(dis->d86_data, reltgt, buf + curlen,6728buflen - curlen);6729(void) strlcat(buf, ">", buflen);6730}6731}67326733#endif /* DIS_TEXT */673467356736