The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cddl/dev/dtrace/x86/dis_tables.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *
    3  * CDDL HEADER START
    4  *
    5  * The contents of this file are subject to the terms of the
    6  * Common Development and Distribution License (the "License").
    7  * You may not use this file except in compliance with the License.
    8  *
    9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   10  * or http://www.opensolaris.org/os/licensing.
   11  * See the License for the specific language governing permissions
   12  * and limitations under the License.
   13  *
   14  * When distributing Covered Code, include this CDDL HEADER in each
   15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   16  * If applicable, add the following below this CDDL HEADER, with the
   17  * fields enclosed by brackets "[]" replaced with your own identifying
   18  * information: Portions Copyright [yyyy] [name of copyright owner]
   19  *
   20  * CDDL HEADER END
   21  */
   22 /*
   23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
   24  * Copyright 2016 Joyent, Inc.
   25  */
   26 
   27 /*
   28  * Copyright (c) 2010, Intel Corporation.
   29  * All rights reserved.
   30  */
   31 
   32 /*      Copyright (c) 1988 AT&T */
   33 /*        All Rights Reserved   */
   34 
   35 /*
   36  * $FreeBSD$
   37  */
   38 
   39 #include        "dis_tables.h"
   40 
   41 /* BEGIN CSTYLED */
   42 
   43 /*
   44  * Disassembly begins in dis_distable, which is equivalent to the One-byte
   45  * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
   46  * decoding loops then traverse out through the other tables as necessary to
   47  * decode a given instruction.
   48  *
   49  * The behavior of this file can be controlled by one of the following flags:
   50  *
   51  *      DIS_TEXT        Include text for disassembly
   52  *      DIS_MEM         Include memory-size calculations
   53  *
   54  * Either or both of these can be defined.
   55  *
   56  * This file is not, and will never be, cstyled.  If anything, the tables should
   57  * be taken out another tab stop or two so nothing overlaps.
   58  */
   59 
   60 /*
   61  * These functions must be provided for the consumer to do disassembly.
   62  */
   63 #ifdef DIS_TEXT
   64 extern char *strncpy(char *, const char *, size_t);
   65 extern size_t strlen(const char *);
   66 extern int strcmp(const char *, const char *);
   67 extern int strncmp(const char *, const char *, size_t);
   68 extern size_t strlcat(char *, const char *, size_t);
   69 #endif
   70 
   71 
   72 #define         TERM    0       /* used to indicate that the 'indirect' */
   73                                 /* field terminates - no pointer.       */
   74 
   75 /* Used to decode instructions. */
   76 typedef struct  instable {
   77         struct instable *it_indirect;   /* for decode op codes */
   78         uchar_t         it_adrmode;
   79 #ifdef DIS_TEXT
   80         char            it_name[NCPS];
   81         uint_t          it_suffix:1;            /* mnem + "w", "l", or "d" */
   82 #endif
   83 #ifdef DIS_MEM
   84         uint_t          it_size:16;
   85 #endif
   86         uint_t          it_invalid64:1;         /* opcode invalid in amd64 */
   87         uint_t          it_always64:1;          /* 64 bit when in 64 bit mode */
   88         uint_t          it_invalid32:1;         /* invalid in IA32 */
   89         uint_t          it_stackop:1;           /* push/pop stack operation */
   90         uint_t          it_vexwoxmm:1;          /* VEX instructions that don't use XMM/YMM */
   91         uint_t          it_avxsuf:1;            /* AVX suffix required */
   92 } instable_t;
   93 
   94 /*
   95  * Instruction formats.
   96  */
   97 enum {
   98         UNKNOWN,
   99         MRw,
  100         IMlw,
  101         IMw,
  102         IR,
  103         OA,
  104         AO,
  105         MS,
  106         SM,
  107         Mv,
  108         Mw,
  109         M,              /* register or memory */
  110         MG9,            /* register or memory in group 9 (prefix optional) */
  111         Mb,             /* register or memory, always byte sized */
  112         MO,             /* memory only (no registers) */
  113         PREF,
  114         SWAPGS_RDTSCP,
  115         MONITOR_MWAIT,
  116         R,
  117         RA,
  118         SEG,
  119         MR,
  120         RM,
  121         RM_66r,         /* RM, but with a required 0x66 prefix */ 
  122         IA,
  123         MA,
  124         SD,
  125         AD,
  126         SA,
  127         D,
  128         INM,
  129         SO,
  130         BD,
  131         I,
  132         P,
  133         V,
  134         DSHIFT,         /* for double shift that has an 8-bit immediate */
  135         U,
  136         OVERRIDE,
  137         NORM,           /* instructions w/o ModR/M byte, no memory access */
  138         IMPLMEM,        /* instructions w/o ModR/M byte, implicit mem access */
  139         O,              /* for call     */
  140         JTAB,           /* jump table   */
  141         IMUL,           /* for 186 iimul instr  */
  142         CBW,            /* so data16 can be evaluated for cbw and variants */
  143         MvI,            /* for 186 logicals */
  144         ENTER,          /* for 186 enter instr  */
  145         RMw,            /* for 286 arpl instr */
  146         Ib,             /* for push immediate byte */
  147         F,              /* for 287 instructions */
  148         FF,             /* for 287 instructions */
  149         FFC,            /* for 287 instructions */
  150         DM,             /* 16-bit data */
  151         AM,             /* 16-bit addr */
  152         LSEG,           /* for 3-bit seg reg encoding */
  153         MIb,            /* for 386 logicals */
  154         SREG,           /* for 386 special registers */
  155         PREFIX,         /* a REP instruction prefix */
  156         LOCK,           /* a LOCK instruction prefix */
  157         INT3,           /* The int 3 instruction, which has a fake operand */
  158         INTx,           /* The normal int instruction, with explicit int num */
  159         DSHIFTcl,       /* for double shift that implicitly uses %cl */
  160         CWD,            /* so data16 can be evaluated for cwd and variants */
  161         RET,            /* single immediate 16-bit operand */
  162         MOVZ,           /* for movs and movz, with different size operands */
  163         CRC32,          /* for crc32, with different size operands */
  164         XADDB,          /* for xaddb */
  165         MOVSXZ,         /* AMD64 mov sign extend 32 to 64 bit instruction */
  166         MOVBE,          /* movbe instruction */
  167 
  168 /*
  169  * MMX/SIMD addressing modes.
  170  */
  171 
  172         MMO,            /* Prefixable MMX/SIMD-Int      mm/mem  -> mm */
  173         MMOIMPL,        /* Prefixable MMX/SIMD-Int      mm      -> mm (mem) */
  174         MMO3P,          /* Prefixable MMX/SIMD-Int      mm      -> r32,imm8 */
  175         MMOM3,          /* Prefixable MMX/SIMD-Int      mm      -> r32  */
  176         MMOS,           /* Prefixable MMX/SIMD-Int      mm      -> mm/mem */
  177         MMOMS,          /* Prefixable MMX/SIMD-Int      mm      -> mem */
  178         MMOPM,          /* MMX/SIMD-Int                 mm/mem  -> mm,imm8 */
  179         MMOPM_66o,      /* MMX/SIMD-Int 0x66 optional   mm/mem  -> mm,imm8 */
  180         MMOPRM,         /* Prefixable MMX/SIMD-Int      r32/mem -> mm,imm8 */
  181         MMOSH,          /* Prefixable MMX               mm,imm8 */
  182         MM,             /* MMX/SIMD-Int                 mm/mem  -> mm   */
  183         MMS,            /* MMX/SIMD-Int                 mm      -> mm/mem */
  184         MMSH,           /* MMX                          mm,imm8 */
  185         XMMO,           /* Prefixable SIMD              xmm/mem -> xmm */
  186         XMMOS,          /* Prefixable SIMD              xmm     -> xmm/mem */
  187         XMMOPM,         /* Prefixable SIMD              xmm/mem w/to xmm,imm8 */
  188         XMMOMX,         /* Prefixable SIMD              mm/mem  -> xmm */
  189         XMMOX3,         /* Prefixable SIMD              xmm     -> r32 */
  190         XMMOXMM,        /* Prefixable SIMD              xmm/mem -> mm   */
  191         XMMOM,          /* Prefixable SIMD              xmm     -> mem */
  192         XMMOMS,         /* Prefixable SIMD              mem     -> xmm */
  193         XMM,            /* SIMD                         xmm/mem -> xmm */
  194         XMM_66r,        /* SIMD 0x66 prefix required    xmm/mem -> xmm */
  195         XMM_66o,        /* SIMD 0x66 prefix optional    xmm/mem -> xmm */
  196         XMMXIMPL,       /* SIMD                         xmm     -> xmm (mem) */
  197         XMM3P,          /* SIMD                         xmm     -> r32,imm8 */
  198         XMM3PM_66r,     /* SIMD 0x66 prefix required    xmm     -> r32/mem,imm8 */
  199         XMMP,           /* SIMD                         xmm/mem w/to xmm,imm8 */
  200         XMMP_66o,       /* SIMD 0x66 prefix optional    xmm/mem w/to xmm,imm8 */
  201         XMMP_66r,       /* SIMD 0x66 prefix required    xmm/mem w/to xmm,imm8 */
  202         XMMPRM,         /* SIMD                         r32/mem -> xmm,imm8 */
  203         XMMPRM_66r,     /* SIMD 0x66 prefix required    r32/mem -> xmm,imm8 */
  204         XMMS,           /* SIMD                         xmm     -> xmm/mem */
  205         XMMM,           /* SIMD                         mem     -> xmm */
  206         XMMM_66r,       /* SIMD 0x66 prefix required    mem     -> xmm */
  207         XMMMS,          /* SIMD                         xmm     -> mem */
  208         XMM3MX,         /* SIMD                         r32/mem -> xmm */
  209         XMM3MXS,        /* SIMD                         xmm     -> r32/mem */
  210         XMMSH,          /* SIMD                         xmm,imm8 */
  211         XMMXM3,         /* SIMD                         xmm/mem -> r32 */
  212         XMMX3,          /* SIMD                         xmm     -> r32 */
  213         XMMXMM,         /* SIMD                         xmm/mem -> mm */
  214         XMMMX,          /* SIMD                         mm      -> xmm */
  215         XMMXM,          /* SIMD                         xmm     -> mm */
  216         XMMX2I,         /* SIMD                         xmm -> xmm, imm, imm */
  217         XMM2I,          /* SIMD                         xmm, imm, imm */
  218         XMMFENCE,       /* SIMD lfence or mfence */
  219         XMMSFNC,        /* SIMD sfence (none or mem) */
  220         XGETBV_XSETBV,
  221         VEX_NONE,       /* VEX  no operand */
  222         VEX_MO,         /* VEX  mod_rm                         -> implicit reg */
  223         VEX_RMrX,       /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
  224         VEX_VRMrX,      /* VEX  mod_rm, VEX.vvvv               -> mod_rm */
  225         VEX_RRX,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
  226         VEX_RMRX,       /* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
  227         VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
  228         VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
  229         VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
  230         VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
  231         VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
  232         VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
  233         VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
  234         VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
  235         VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
  236         VEX_RIM,        /* VEX  mod_reg, imm8                  -> mod_rm */
  237         VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
  238         VEX_RMX,        /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
  239         VEX_SbVM,       /* VEX  SIB, VEX.vvvv                  -> mod_rm */
  240         VMx,            /* vmcall/vmlaunch/vmresume/vmxoff */
  241         VMxo,           /* VMx instruction with optional prefix */
  242         SVM,            /* AMD SVM instructions */
  243         BLS,            /* BLSR, BLSMSK, BLSI */
  244         FMA,            /* FMA instructions, all VEX_RMrX */
  245         ADX             /* ADX instructions, support REX.w, mod_rm->mod_reg */
  246 };
  247 
  248 /*
  249  * VEX prefixes
  250  */
  251 #define VEX_2bytes      0xC5    /* the first byte of two-byte form */
  252 #define VEX_3bytes      0xC4    /* the first byte of three-byte form */
  253 
  254 #define FILL    0x90    /* Fill byte used for alignment (nop)   */
  255 
  256 /*
  257 ** Register numbers for the i386
  258 */
  259 #define EAX_REGNO 0
  260 #define ECX_REGNO 1
  261 #define EDX_REGNO 2
  262 #define EBX_REGNO 3
  263 #define ESP_REGNO 4
  264 #define EBP_REGNO 5
  265 #define ESI_REGNO 6
  266 #define EDI_REGNO 7
  267 
  268 /*
  269  * modes for immediate values
  270  */
  271 #define MODE_NONE       0
  272 #define MODE_IPREL      1       /* signed IP relative value */
  273 #define MODE_SIGNED     2       /* sign extended immediate */
  274 #define MODE_IMPLIED    3       /* constant value implied from opcode */
  275 #define MODE_OFFSET     4       /* offset part of an address */
  276 #define MODE_RIPREL     5       /* like IPREL, but from %rip (amd64) */
  277 
  278 /*
  279  * The letters used in these macros are:
  280  *   IND - indirect to another to another table
  281  *   "T" - means to Terminate indirections (this is the final opcode)
  282  *   "S" - means "operand length suffix required"
  283  *   "Sa" - means AVX2 suffix (d/q) required
  284  *   "NS" - means "no suffix" which is the operand length suffix of the opcode
  285  *   "Z" - means instruction size arg required
  286  *   "u" - means the opcode is invalid in IA32 but valid in amd64
  287  *   "x" - means the opcode is invalid in amd64, but not IA32
  288  *   "y" - means the operand size is always 64 bits in 64 bit mode
  289  *   "p" - means push/pop stack operation
  290  *   "vr" - means VEX instruction that operates on normal registers, not fpu
  291  */
  292 
  293 #if defined(DIS_TEXT) && defined(DIS_MEM)
  294 #define IND(table)              {(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
  295 #define INDx(table)             {(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
  296 #define TNS(name, amode)        {TERM, amode, name, 0, 0, 0, 0, 0, 0}
  297 #define TNSu(name, amode)       {TERM, amode, name, 0, 0, 0, 0, 1, 0}
  298 #define TNSx(name, amode)       {TERM, amode, name, 0, 0, 1, 0, 0, 0}
  299 #define TNSy(name, amode)       {TERM, amode, name, 0, 0, 0, 1, 0, 0}
  300 #define TNSyp(name, amode)      {TERM, amode, name, 0, 0, 0, 1, 0, 1}
  301 #define TNSZ(name, amode, sz)   {TERM, amode, name, 0, sz, 0, 0, 0, 0}
  302 #define TNSZy(name, amode, sz)  {TERM, amode, name, 0, sz, 0, 1, 0, 0}
  303 #define TNSZvr(name, amode, sz) {TERM, amode, name, 0, sz, 0, 0, 0, 0, 1}
  304 #define TS(name, amode)         {TERM, amode, name, 1, 0, 0, 0, 0, 0}
  305 #define TSx(name, amode)        {TERM, amode, name, 1, 0, 1, 0, 0, 0}
  306 #define TSy(name, amode)        {TERM, amode, name, 1, 0, 0, 1, 0, 0}
  307 #define TSp(name, amode)        {TERM, amode, name, 1, 0, 0, 0, 0, 1}
  308 #define TSZ(name, amode, sz)    {TERM, amode, name, 1, sz, 0, 0, 0, 0}
  309 #define TSaZ(name, amode, sz)   {TERM, amode, name, 1, sz, 0, 0, 0, 0, 0, 1}
  310 #define TSZx(name, amode, sz)   {TERM, amode, name, 1, sz, 1, 0, 0, 0}
  311 #define TSZy(name, amode, sz)   {TERM, amode, name, 1, sz, 0, 1, 0, 0}
  312 #define INVALID                 {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
  313 #elif defined(DIS_TEXT)
  314 #define IND(table)              {(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
  315 #define INDx(table)             {(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
  316 #define TNS(name, amode)        {TERM, amode, name, 0, 0, 0, 0, 0}
  317 #define TNSu(name, amode)       {TERM, amode, name, 0, 0, 0, 1, 0}
  318 #define TNSx(name, amode)       {TERM, amode, name, 0, 1, 0, 0, 0}
  319 #define TNSy(name, amode)       {TERM, amode, name, 0, 0, 1, 0, 0}
  320 #define TNSyp(name, amode)      {TERM, amode, name, 0, 0, 1, 0, 1}
  321 #define TNSZ(name, amode, sz)   {TERM, amode, name, 0, 0, 0, 0, 0}
  322 #define TNSZy(name, amode, sz)  {TERM, amode, name, 0, 0, 1, 0, 0}
  323 #define TNSZvr(name, amode, sz) {TERM, amode, name, 0, 0, 0, 0, 0, 1}
  324 #define TS(name, amode)         {TERM, amode, name, 1, 0, 0, 0, 0}
  325 #define TSx(name, amode)        {TERM, amode, name, 1, 1, 0, 0, 0}
  326 #define TSy(name, amode)        {TERM, amode, name, 1, 0, 1, 0, 0}
  327 #define TSp(name, amode)        {TERM, amode, name, 1, 0, 0, 0, 1}
  328 #define TSZ(name, amode, sz)    {TERM, amode, name, 1, 0, 0, 0, 0}
  329 #define TSaZ(name, amode, sz)   {TERM, amode, name, 1, 0, 0, 0, 0, 0, 1}
  330 #define TSZx(name, amode, sz)   {TERM, amode, name, 1, 1, 0, 0, 0}
  331 #define TSZy(name, amode, sz)   {TERM, amode, name, 1, 0, 1, 0, 0}
  332 #define INVALID                 {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
  333 #elif defined(DIS_MEM)
  334 #define IND(table)              {(instable_t *)table, 0, 0, 0, 0, 0, 0}
  335 #define INDx(table)             {(instable_t *)table, 0, 0, 1, 0, 0, 0}
  336 #define TNS(name, amode)        {TERM, amode,  0, 0, 0, 0, 0}
  337 #define TNSu(name, amode)       {TERM, amode,  0, 0, 0, 1, 0}
  338 #define TNSy(name, amode)       {TERM, amode,  0, 0, 1, 0, 0}
  339 #define TNSyp(name, amode)      {TERM, amode,  0, 0, 1, 0, 1}
  340 #define TNSx(name, amode)       {TERM, amode,  0, 1, 0, 0, 0}
  341 #define TNSZ(name, amode, sz)   {TERM, amode, sz, 0, 0, 0, 0}
  342 #define TNSZy(name, amode, sz)  {TERM, amode, sz, 0, 1, 0, 0}
  343 #define TNSZvr(name, amode, sz) {TERM, amode, sz, 0, 0, 0, 0, 1}
  344 #define TS(name, amode)         {TERM, amode,  0, 0, 0, 0, 0}
  345 #define TSx(name, amode)        {TERM, amode,  0, 1, 0, 0, 0}
  346 #define TSy(name, amode)        {TERM, amode,  0, 0, 1, 0, 0}
  347 #define TSp(name, amode)        {TERM, amode,  0, 0, 0, 0, 1}
  348 #define TSZ(name, amode, sz)    {TERM, amode, sz, 0, 0, 0, 0}
  349 #define TSaZ(name, amode, sz)   {TERM, amode, sz, 0, 0, 0, 0, 0, 1}
  350 #define TSZx(name, amode, sz)   {TERM, amode, sz, 1, 0, 0, 0}
  351 #define TSZy(name, amode, sz)   {TERM, amode, sz, 0, 1, 0, 0}
  352 #define INVALID                 {TERM, UNKNOWN, 0, 0, 0, 0, 0}
  353 #else
  354 #define IND(table)              {(instable_t *)table, 0, 0, 0, 0, 0}
  355 #define INDx(table)             {(instable_t *)table, 0, 1, 0, 0, 0}
  356 #define TNS(name, amode)        {TERM, amode,  0, 0, 0, 0}
  357 #define TNSu(name, amode)       {TERM, amode,  0, 0, 1, 0}
  358 #define TNSy(name, amode)       {TERM, amode,  0, 1, 0, 0}
  359 #define TNSyp(name, amode)      {TERM, amode,  0, 1, 0, 1}
  360 #define TNSx(name, amode)       {TERM, amode,  1, 0, 0, 0}
  361 #define TNSZ(name, amode, sz)   {TERM, amode,  0, 0, 0, 0}
  362 #define TNSZy(name, amode, sz)  {TERM, amode,  0, 1, 0, 0}
  363 #define TNSZvr(name, amode, sz) {TERM, amode,  0, 0, 0, 0, 1}
  364 #define TS(name, amode)         {TERM, amode,  0, 0, 0, 0}
  365 #define TSx(name, amode)        {TERM, amode,  1, 0, 0, 0}
  366 #define TSy(name, amode)        {TERM, amode,  0, 1, 0, 0}
  367 #define TSp(name, amode)        {TERM, amode,  0, 0, 0, 1}
  368 #define TSZ(name, amode, sz)    {TERM, amode,  0, 0, 0, 0}
  369 #define TSaZ(name, amode, sz)   {TERM, amode,  0, 0, 0, 0, 0, 1}
  370 #define TSZx(name, amode, sz)   {TERM, amode,  1, 0, 0, 0}
  371 #define TSZy(name, amode, sz)   {TERM, amode,  0, 1, 0, 0}
  372 #define INVALID                 {TERM, UNKNOWN, 0, 0, 0, 0}
  373 #endif
  374 
  375 #ifdef DIS_TEXT
  376 /*
  377  * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
  378  */
  379 const char *const dis_addr16[3][8] = {
  380 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
  381                                                                         "(%bx)",
  382 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
  383                                                                         "(%bx)",
  384 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
  385                                                                         "(%bx)",
  386 };
  387 
  388 
  389 /*
  390  * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
  391  */
  392 const char *const dis_addr32_mode0[16] = {
  393   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
  394   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
  395 };
  396 
  397 const char *const dis_addr32_mode12[16] = {
  398   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
  399   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
  400 };
  401 
  402 /*
  403  * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
  404  */
  405 const char *const dis_addr64_mode0[16] = {
  406  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
  407  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
  408 };
  409 const char *const dis_addr64_mode12[16] = {
  410  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
  411  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
  412 };
  413 
  414 /*
  415  * decode for scale from SIB byte
  416  */
  417 const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
  418 
  419 /*
  420  * decode for scale from VSIB byte, note that we always include the scale factor
  421  * to match gas.
  422  */
  423 const char *const dis_vscale_factor[4] = { ",1)", ",2)", ",4)", ",8)" };
  424 
  425 /*
  426  * register decoding for normal references to registers (ie. not addressing)
  427  */
  428 const char *const dis_REG8[16] = {
  429         "%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
  430         "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
  431 };
  432 
  433 const char *const dis_REG8_REX[16] = {
  434         "%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
  435         "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
  436 };
  437 
  438 const char *const dis_REG16[16] = {
  439         "%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
  440         "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
  441 };
  442 
  443 const char *const dis_REG32[16] = {
  444         "%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
  445         "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
  446 };
  447 
  448 const char *const dis_REG64[16] = {
  449         "%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
  450         "%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
  451 };
  452 
  453 const char *const dis_DEBUGREG[16] = {
  454         "%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
  455         "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
  456 };
  457 
  458 const char *const dis_CONTROLREG[16] = {
  459     "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
  460     "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
  461 };
  462 
  463 const char *const dis_TESTREG[16] = {
  464         "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
  465         "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
  466 };
  467 
  468 const char *const dis_MMREG[16] = {
  469         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
  470         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
  471 };
  472 
  473 const char *const dis_XMMREG[16] = {
  474     "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
  475     "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
  476 };
  477 
  478 const char *const dis_YMMREG[16] = {
  479     "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
  480     "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
  481 };
  482 
  483 const char *const dis_SEGREG[16] = {
  484         "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
  485         "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
  486 };
  487 
  488 /*
  489  * SIMD predicate suffixes
  490  */
  491 const char *const dis_PREDSUFFIX[8] = {
  492         "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
  493 };
  494 
  495 const char *const dis_AVXvgrp7[3][8] = {
  496         /*0     1       2               3               4               5       6               7*/
  497 /*71*/  {"",    "",     "vpsrlw",       "",             "vpsraw",       "",     "vpsllw",       ""},
  498 /*72*/  {"",    "",     "vpsrld",       "",             "vpsrad",       "",     "vpslld",       ""},
  499 /*73*/  {"",    "",     "vpsrlq",       "vpsrldq",      "",             "",     "vpsllq",       "vpslldq"}
  500 };
  501 
  502 #endif  /* DIS_TEXT */
  503 
  504 /*
  505  *      "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
  506  */
  507 const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
  508 
  509 /*
  510  *      "decode table" for pause and clflush instructions
  511  */
  512 const instable_t dis_opPause = TNS("pause", NORM);
  513 
  514 /*
  515  *      Decode table for 0x0F00 opcodes
  516  */
  517 const instable_t dis_op0F00[8] = {
  518 
  519 /*  [0]  */     TNS("sldt",M),          TNS("str",M),           TNSy("lldt",M),         TNSy("ltr",M),
  520 /*  [4]  */     TNSZ("verr",M,2),       TNSZ("verw",M,2),       INVALID,                INVALID,
  521 };
  522 
  523 
  524 /*
  525  *      Decode table for 0x0F01 opcodes
  526  */
  527 const instable_t dis_op0F01[8] = {
  528 
  529 /*  [0]  */     TNSZ("sgdt",VMx,6),     TNSZ("sidt",MONITOR_MWAIT,6),   TNSZ("lgdt",XGETBV_XSETBV,6),   TNSZ("lidt",SVM,6),
  530 /*  [4]  */     TNSZ("smsw",M,2),       INVALID,                TNSZ("lmsw",M,2),       TNS("invlpg",SWAPGS_RDTSCP),
  531 };
  532 
  533 /*
  534  *      Decode table for 0x0F18 opcodes -- SIMD prefetch
  535  */
  536 const instable_t dis_op0F18[8] = {
  537 
  538 /*  [0]  */     TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF),
  539 /*  [4]  */     INVALID,                INVALID,                INVALID,                INVALID,
  540 };
  541 
  542 /*
  543  *      Decode table for 0x0FAE opcodes -- SIMD state save/restore
  544  */
  545 const instable_t dis_op0FAE[8] = {
  546 /*  [0]  */     TNSZ("fxsave",M,512),   TNSZ("fxrstor",M,512),  TNS("ldmxcsr",M),       TNS("stmxcsr",M),
  547 /*  [4]  */     TNSZ("xsave",M,512),    TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC),
  548 };
  549 
  550 /*
  551  *      Decode table for 0x0FBA opcodes
  552  */
  553 
  554 const instable_t dis_op0FBA[8] = {
  555 
  556 /*  [0]  */     INVALID,                INVALID,                INVALID,                INVALID,
  557 /*  [4]  */     TS("bt",MIb),           TS("bts",MIb),          TS("btr",MIb),          TS("btc",MIb),
  558 };
  559 
  560 /*
  561  *      Decode table for 0x0FC7 opcode (group 9)
  562  */
  563 
  564 const instable_t dis_op0FC7[8] = {
  565 
  566 /*  [0]  */     INVALID,                TNS("cmpxchg8b",M),     INVALID,                INVALID,
  567 /*  [4]  */     INVALID,                INVALID,                TNS("vmptrld",MG9),     TNS("vmptrst",MG9),
  568 };
  569 
  570 /*
  571  *      Decode table for 0x0FC7 opcode (group 9) mode 3
  572  */
  573 
  574 const instable_t dis_op0FC7m3[8] = {
  575 
  576 /*  [0]  */     INVALID,                INVALID,        INVALID,                INVALID,
  577 /*  [4]  */     INVALID,                INVALID,        TNS("rdrand",MG9),      TNS("rdseed", MG9),
  578 };
  579 
  580 /*
  581  *      Decode table for 0x0FC7 opcode with 0x66 prefix
  582  */
  583 
  584 const instable_t dis_op660FC7[8] = {
  585 
  586 /*  [0]  */     INVALID,                INVALID,                INVALID,                INVALID,
  587 /*  [4]  */     INVALID,                INVALID,                TNS("vmclear",M),       INVALID,
  588 };
  589 
  590 /*
  591  *      Decode table for 0x0FC7 opcode with 0xF3 prefix
  592  */
  593 
  594 const instable_t dis_opF30FC7[8] = {
  595 
  596 /*  [0]  */     INVALID,                INVALID,                INVALID,                INVALID,
  597 /*  [4]  */     INVALID,                INVALID,                TNS("vmxon",M),         INVALID,
  598 };
  599 
  600 /*
  601  *      Decode table for 0x0FC8 opcode -- 486 bswap instruction
  602  *
  603  *bit pattern: 0000 1111 1100 1reg
  604  */
  605 const instable_t dis_op0FC8[4] = {
  606 /*  [0]  */     TNS("bswap",R),         INVALID,                INVALID,                INVALID,
  607 };
  608 
  609 /*
  610  *      Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
  611  */
  612 const instable_t dis_op0F7123[4][8] = {
  613 {
  614 /*  [70].0 */   INVALID,                INVALID,                INVALID,                INVALID,
  615 /*      .4 */   INVALID,                INVALID,                INVALID,                INVALID,
  616 }, {
  617 /*  [71].0 */   INVALID,                INVALID,                TNS("psrlw",MMOSH),     INVALID,
  618 /*      .4 */   TNS("psraw",MMOSH),     INVALID,                TNS("psllw",MMOSH),     INVALID,
  619 }, {
  620 /*  [72].0 */   INVALID,                INVALID,                TNS("psrld",MMOSH),     INVALID,
  621 /*      .4 */   TNS("psrad",MMOSH),     INVALID,                TNS("pslld",MMOSH),     INVALID,
  622 }, {
  623 /*  [73].0 */   INVALID,                INVALID,                TNS("psrlq",MMOSH),     TNS("INVALID",MMOSH),
  624 /*      .4 */   INVALID,                INVALID,                TNS("psllq",MMOSH),     TNS("INVALID",MMOSH),
  625 } };
  626 
  627 /*
  628  *      Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
  629  */
  630 const instable_t dis_opSIMD7123[32] = {
  631 /* [70].0 */    INVALID,                INVALID,                INVALID,                INVALID,
  632 /*     .4 */    INVALID,                INVALID,                INVALID,                INVALID,
  633 
  634 /* [71].0 */    INVALID,                INVALID,                TNS("psrlw",XMMSH),     INVALID,
  635 /*     .4 */    TNS("psraw",XMMSH),     INVALID,                TNS("psllw",XMMSH),     INVALID,
  636 
  637 /* [72].0 */    INVALID,                INVALID,                TNS("psrld",XMMSH),     INVALID,
  638 /*     .4 */    TNS("psrad",XMMSH),     INVALID,                TNS("pslld",XMMSH),     INVALID,
  639 
  640 /* [73].0 */    INVALID,                INVALID,                TNS("psrlq",XMMSH),     TNS("psrldq",XMMSH),
  641 /*     .4 */    INVALID,                INVALID,                TNS("psllq",XMMSH),     TNS("pslldq",XMMSH),
  642 };
  643 
  644 /*
  645  *      SIMD instructions have been wedged into the existing IA32 instruction
  646  *      set through the use of prefixes.  That is, while 0xf0 0x58 may be
  647  *      addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
  648  *      instruction - addss.  At present, three prefixes have been coopted in
  649  *      this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
  650  *      following tables are used to provide the prefixed instruction names.
  651  *      The arrays are sparse, but they're fast.
  652  */
  653 
  654 /*
  655  *      Decode table for SIMD instructions with the address size (0x66) prefix.
  656  */
  657 const instable_t dis_opSIMDdata16[256] = {
  658 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
  659 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
  660 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
  661 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  662 
  663 /*  [10]  */    TNSZ("movupd",XMM,16),  TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8),  TNSZ("movlpd",XMMMS,8),
  664 /*  [14]  */    TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),  TNSZ("movhpd",XMMMS,8),
  665 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
  666 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  667 
  668 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
  669 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
  670 /*  [28]  */    TNSZ("movapd",XMM,16),  TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
  671 /*  [2C]  */    TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
  672 
  673 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
  674 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
  675 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
  676 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  677 
  678 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
  679 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
  680 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
  681 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  682 
  683 /*  [50]  */    TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16),  INVALID,                INVALID,
  684 /*  [54]  */    TNSZ("andpd",XMM,16),   TNSZ("andnpd",XMM,16),  TNSZ("orpd",XMM,16),    TNSZ("xorpd",XMM,16),
  685 /*  [58]  */    TNSZ("addpd",XMM,16),   TNSZ("mulpd",XMM,16),   TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
  686 /*  [5C]  */    TNSZ("subpd",XMM,16),   TNSZ("minpd",XMM,16),   TNSZ("divpd",XMM,16),   TNSZ("maxpd",XMM,16),
  687 
  688 /*  [60]  */    TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
  689 /*  [64]  */    TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16),
  690 /*  [68]  */    TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
  691 /*  [6C]  */    TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
  692 
  693 /*  [70]  */    TNSZ("pshufd",XMMP,16), INVALID,                INVALID,                INVALID,
  694 /*  [74]  */    TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID,
  695 /*  [78]  */    TNSZ("extrq",XMM2I,16), TNSZ("extrq",XMM,16), INVALID,          INVALID,
  696 /*  [7C]  */    TNSZ("haddpd",XMM,16),  TNSZ("hsubpd",XMM,16),  TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16),
  697 
  698 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
  699 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
  700 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
  701 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  702 
  703 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
  704 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
  705 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
  706 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  707 
  708 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  709 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  710 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  711 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  712 
  713 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  714 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  715 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  716 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  717 
  718 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmppd",XMMP,16),  INVALID,
  719 /*  [C4]  */    TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),    TNSZ("shufpd",XMMP,16), INVALID,
  720 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  721 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  722 
  723 /*  [D0]  */    TNSZ("addsubpd",XMM,16),TNSZ("psrlw",XMM,16),   TNSZ("psrld",XMM,16),   TNSZ("psrlq",XMM,16),
  724 /*  [D4]  */    TNSZ("paddq",XMM,16),   TNSZ("pmullw",XMM,16),  TNSZ("movq",XMMS,8),    TNS("pmovmskb",XMMX3),
  725 /*  [D8]  */    TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16),  TNSZ("pand",XMM,16),
  726 /*  [DC]  */    TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16),  TNSZ("pandn",XMM,16),
  727 
  728 /*  [E0]  */    TNSZ("pavgb",XMM,16),   TNSZ("psraw",XMM,16),   TNSZ("psrad",XMM,16),   TNSZ("pavgw",XMM,16),
  729 /*  [E4]  */    TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16),  TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
  730 /*  [E8]  */    TNSZ("psubsb",XMM,16),  TNSZ("psubsw",XMM,16),  TNSZ("pminsw",XMM,16),  TNSZ("por",XMM,16),
  731 /*  [EC]  */    TNSZ("paddsb",XMM,16),  TNSZ("paddsw",XMM,16),  TNSZ("pmaxsw",XMM,16),  TNSZ("pxor",XMM,16),
  732 
  733 /*  [F0]  */    INVALID,                TNSZ("psllw",XMM,16),   TNSZ("pslld",XMM,16),   TNSZ("psllq",XMM,16),
  734 /*  [F4]  */    TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16),  TNSZ("maskmovdqu", XMMXIMPL,16),
  735 /*  [F8]  */    TNSZ("psubb",XMM,16),   TNSZ("psubw",XMM,16),   TNSZ("psubd",XMM,16),   TNSZ("psubq",XMM,16),
  736 /*  [FC]  */    TNSZ("paddb",XMM,16),   TNSZ("paddw",XMM,16),   TNSZ("paddd",XMM,16),   INVALID,
  737 };
  738 
  739 const instable_t dis_opAVX660F[256] = {
  740 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
  741 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
  742 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
  743 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  744 
  745 /*  [10]  */    TNSZ("vmovupd",VEX_MX,16),      TNSZ("vmovupd",VEX_RX,16),      TNSZ("vmovlpd",VEX_RMrX,8),     TNSZ("vmovlpd",VEX_RM,8),
  746 /*  [14]  */    TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8), TNSZ("vmovhpd",VEX_RM,8),
  747 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
  748 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  749 
  750 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
  751 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
  752 /*  [28]  */    TNSZ("vmovapd",VEX_MX,16),      TNSZ("vmovapd",VEX_RX,16),      INVALID,                TNSZ("vmovntpd",VEX_RM,16),
  753 /*  [2C]  */    INVALID,                INVALID,                TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
  754 
  755 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
  756 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
  757 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
  758 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  759 
  760 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
  761 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
  762 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
  763 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  764 
  765 /*  [50]  */    TNS("vmovmskpd",VEX_MR),        TNSZ("vsqrtpd",VEX_MX,16),      INVALID,                INVALID,
  766 /*  [54]  */    TNSZ("vandpd",VEX_RMrX,16),     TNSZ("vandnpd",VEX_RMrX,16),    TNSZ("vorpd",VEX_RMrX,16),      TNSZ("vxorpd",VEX_RMrX,16),
  767 /*  [58]  */    TNSZ("vaddpd",VEX_RMrX,16),     TNSZ("vmulpd",VEX_RMrX,16),     TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
  768 /*  [5C]  */    TNSZ("vsubpd",VEX_RMrX,16),     TNSZ("vminpd",VEX_RMrX,16),     TNSZ("vdivpd",VEX_RMrX,16),     TNSZ("vmaxpd",VEX_RMrX,16),
  769 
  770 /*  [60]  */    TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
  771 /*  [64]  */    TNSZ("vpcmpgtb",VEX_RMrX,16),   TNSZ("vpcmpgtw",VEX_RMrX,16),   TNSZ("vpcmpgtd",VEX_RMrX,16),   TNSZ("vpackuswb",VEX_RMrX,16),
  772 /*  [68]  */    TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
  773 /*  [6C]  */    TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
  774 
  775 /*  [70]  */    TNSZ("vpshufd",VEX_MXI,16),     TNSZ("vgrp71",VEX_XXI,16),      TNSZ("vgrp72",VEX_XXI,16),              TNSZ("vgrp73",VEX_XXI,16),
  776 /*  [74]  */    TNSZ("vpcmpeqb",VEX_RMrX,16),   TNSZ("vpcmpeqw",VEX_RMrX,16),   TNSZ("vpcmpeqd",VEX_RMrX,16),   INVALID,
  777 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
  778 /*  [7C]  */    TNSZ("vhaddpd",VEX_RMrX,16),    TNSZ("vhsubpd",VEX_RMrX,16),    TNSZ("vmovd",VEX_RR,4), TNSZ("vmovdqa",VEX_RX,16),
  779 
  780 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
  781 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
  782 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
  783 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  784 
  785 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
  786 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
  787 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
  788 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  789 
  790 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  791 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  792 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  793 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  794 
  795 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  796 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  797 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  798 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  799 
  800 /*  [C0]  */    INVALID,                INVALID,                TNSZ("vcmppd",VEX_RMRX,16),     INVALID,
  801 /*  [C4]  */    TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),       TNSZ("vshufpd",VEX_RMRX,16),    INVALID,
  802 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  803 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  804 
  805 /*  [D0]  */    TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),       TNSZ("vpsrld",VEX_RMrX,16),     TNSZ("vpsrlq",VEX_RMrX,16),
  806 /*  [D4]  */    TNSZ("vpaddq",VEX_RMrX,16),     TNSZ("vpmullw",VEX_RMrX,16),    TNSZ("vmovq",VEX_RX,8), TNS("vpmovmskb",VEX_MR),
  807 /*  [D8]  */    TNSZ("vpsubusb",VEX_RMrX,16),   TNSZ("vpsubusw",VEX_RMrX,16),   TNSZ("vpminub",VEX_RMrX,16),    TNSZ("vpand",VEX_RMrX,16),
  808 /*  [DC]  */    TNSZ("vpaddusb",VEX_RMrX,16),   TNSZ("vpaddusw",VEX_RMrX,16),   TNSZ("vpmaxub",VEX_RMrX,16),    TNSZ("vpandn",VEX_RMrX,16),
  809 
  810 /*  [E0]  */    TNSZ("vpavgb",VEX_RMrX,16),     TNSZ("vpsraw",VEX_RMrX,16),     TNSZ("vpsrad",VEX_RMrX,16),     TNSZ("vpavgw",VEX_RMrX,16),
  811 /*  [E4]  */    TNSZ("vpmulhuw",VEX_RMrX,16),   TNSZ("vpmulhw",VEX_RMrX,16),    TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
  812 /*  [E8]  */    TNSZ("vpsubsb",VEX_RMrX,16),    TNSZ("vpsubsw",VEX_RMrX,16),    TNSZ("vpminsw",VEX_RMrX,16),    TNSZ("vpor",VEX_RMrX,16),
  813 /*  [EC]  */    TNSZ("vpaddsb",VEX_RMrX,16),    TNSZ("vpaddsw",VEX_RMrX,16),    TNSZ("vpmaxsw",VEX_RMrX,16),    TNSZ("vpxor",VEX_RMrX,16),
  814 
  815 /*  [F0]  */    INVALID,                TNSZ("vpsllw",VEX_RMrX,16),     TNSZ("vpslld",VEX_RMrX,16),     TNSZ("vpsllq",VEX_RMrX,16),
  816 /*  [F4]  */    TNSZ("vpmuludq",VEX_RMrX,16),   TNSZ("vpmaddwd",VEX_RMrX,16),   TNSZ("vpsadbw",VEX_RMrX,16),    TNS("vmaskmovdqu",VEX_MX),
  817 /*  [F8]  */    TNSZ("vpsubb",VEX_RMrX,16),     TNSZ("vpsubw",VEX_RMrX,16),     TNSZ("vpsubd",VEX_RMrX,16),     TNSZ("vpsubq",VEX_RMrX,16),
  818 /*  [FC]  */    TNSZ("vpaddb",VEX_RMrX,16),     TNSZ("vpaddw",VEX_RMrX,16),     TNSZ("vpaddd",VEX_RMrX,16),     INVALID,
  819 };
  820 
  821 /*
  822  *      Decode table for SIMD instructions with the repnz (0xf2) prefix.
  823  */
  824 const instable_t dis_opSIMDrepnz[256] = {
  825 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
  826 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
  827 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
  828 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  829 
  830 /*  [10]  */    TNSZ("movsd",XMM,8),    TNSZ("movsd",XMMS,8),   TNSZ("movddup",XMM,8),  INVALID,
  831 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
  832 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
  833 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  834 
  835 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
  836 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
  837 /*  [28]  */    INVALID,                INVALID,                TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
  838 /*  [2C]  */    TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,           INVALID,
  839 
  840 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
  841 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
  842 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
  843 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  844 
  845 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
  846 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
  847 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
  848 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  849 
  850 /*  [50]  */    INVALID,                TNSZ("sqrtsd",XMM,8),   INVALID,                INVALID,
  851 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
  852 /*  [58]  */    TNSZ("addsd",XMM,8),    TNSZ("mulsd",XMM,8),    TNSZ("cvtsd2ss",XMM,8), INVALID,
  853 /*  [5C]  */    TNSZ("subsd",XMM,8),    TNSZ("minsd",XMM,8),    TNSZ("divsd",XMM,8),    TNSZ("maxsd",XMM,8),
  854 
  855 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
  856 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
  857 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
  858 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  859 
  860 /*  [70]  */    TNSZ("pshuflw",XMMP,16),INVALID,                INVALID,                INVALID,
  861 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
  862 /*  [78]  */    TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,                INVALID,
  863 /*  [7C]  */    TNSZ("haddps",XMM,16),  TNSZ("hsubps",XMM,16),  INVALID,                INVALID,
  864 
  865 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
  866 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
  867 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
  868 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  869 
  870 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
  871 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
  872 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
  873 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  874 
  875 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  876 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  877 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  878 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  879 
  880 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  881 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  882 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  883 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  884 
  885 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmpsd",XMMP,8),   INVALID,
  886 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  887 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  888 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  889 
  890 /*  [D0]  */    TNSZ("addsubps",XMM,16),INVALID,                INVALID,                INVALID,
  891 /*  [D4]  */    INVALID,                INVALID,                TNS("movdq2q",XMMXM),   INVALID,
  892 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  893 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  894 
  895 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  896 /*  [E4]  */    INVALID,                INVALID,                TNSZ("cvtpd2dq",XMM,16),INVALID,
  897 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  898 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  899 
  900 /*  [F0]  */    TNS("lddqu",XMMM),      INVALID,                INVALID,                INVALID,
  901 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  902 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  903 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  904 };
  905 
  906 const instable_t dis_opAVXF20F[256] = {
  907 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
  908 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
  909 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
  910 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  911 
  912 /*  [10]  */    TNSZ("vmovsd",VEX_RMrX,8),      TNSZ("vmovsd",VEX_RRX,8),       TNSZ("vmovddup",VEX_MX,8),      INVALID,
  913 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
  914 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
  915 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  916 
  917 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
  918 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
  919 /*  [28]  */    INVALID,                INVALID,                TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
  920 /*  [2C]  */    TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,         INVALID,
  921 
  922 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
  923 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
  924 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
  925 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  926 
  927 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
  928 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
  929 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
  930 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  931 
  932 /*  [50]  */    INVALID,                TNSZ("vsqrtsd",VEX_RMrX,8),     INVALID,                INVALID,
  933 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
  934 /*  [58]  */    TNSZ("vaddsd",VEX_RMrX,8),      TNSZ("vmulsd",VEX_RMrX,8),      TNSZ("vcvtsd2ss",VEX_RMrX,8),   INVALID,
  935 /*  [5C]  */    TNSZ("vsubsd",VEX_RMrX,8),      TNSZ("vminsd",VEX_RMrX,8),      TNSZ("vdivsd",VEX_RMrX,8),      TNSZ("vmaxsd",VEX_RMrX,8),
  936 
  937 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
  938 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
  939 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
  940 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  941 
  942 /*  [70]  */    TNSZ("vpshuflw",VEX_MXI,16),INVALID,            INVALID,                INVALID,
  943 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
  944 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
  945 /*  [7C]  */    TNSZ("vhaddps",VEX_RMrX,8),     TNSZ("vhsubps",VEX_RMrX,8),     INVALID,                INVALID,
  946 
  947 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
  948 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
  949 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
  950 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  951 
  952 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
  953 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
  954 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
  955 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  956 
  957 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  958 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  959 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  960 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  961 
  962 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  963 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  964 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  965 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  966 
  967 /*  [C0]  */    INVALID,                INVALID,                TNSZ("vcmpsd",VEX_RMRX,8),      INVALID,
  968 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  969 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  970 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  971 
  972 /*  [D0]  */    TNSZ("vaddsubps",VEX_RMrX,8),   INVALID,                INVALID,                INVALID,
  973 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  974 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  975 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  976 
  977 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
  978 /*  [E4]  */    INVALID,                INVALID,                TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
  979 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  980 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  981 
  982 /*  [F0]  */    TNSZ("vlddqu",VEX_MX,16),       INVALID,                INVALID,                INVALID,
  983 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
  984 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
  985 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
  986 };
  987 
  988 const instable_t dis_opAVXF20F3A[256] = {
  989 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
  990 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
  991 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
  992 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  993 
  994 /*  [10]  */    INVALID,                INVALID,                INVALID,                INVALID,
  995 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
  996 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
  997 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
  998 
  999 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1000 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1001 /*  [28]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1002 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1003 
 1004 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1005 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1006 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1007 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1008 
 1009 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1010 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1011 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1012 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1013 
 1014 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1015 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1016 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1017 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1018 
 1019 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1020 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1021 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1022 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1023 
 1024 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1025 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1026 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1027 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1028 
 1029 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1030 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1031 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1032 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1033 
 1034 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1035 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1036 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1037 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1038 
 1039 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1040 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1041 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1042 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1043 
 1044 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1045 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1046 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1047 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1048 
 1049 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1050 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1051 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1052 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1053 
 1054 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1055 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1056 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1057 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1058 
 1059 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1060 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1061 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1062 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1063 
 1064 /*  [F0]  */    TNSZvr("rorx",VEX_MXI,6),INVALID,               INVALID,                INVALID,
 1065 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1066 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1067 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1068 };
 1069 
 1070 const instable_t dis_opAVXF20F38[256] = {
 1071 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1072 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1073 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1074 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1075 
 1076 /*  [10]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1077 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1078 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1079 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1080 
 1081 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1082 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1083 /*  [28]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1084 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1085 
 1086 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1087 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1088 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1089 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1090 
 1091 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1092 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1093 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1094 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1095 
 1096 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1097 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1098 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1099 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1100 
 1101 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1102 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1103 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1104 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1105 
 1106 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1107 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1108 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1109 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1110 
 1111 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1112 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1113 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1114 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1115 
 1116 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1117 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1118 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1119 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1120 
 1121 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1122 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1123 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1124 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1125 
 1126 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1127 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1128 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1129 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1130 
 1131 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1132 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1133 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1134 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1135 
 1136 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1137 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1138 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1139 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1140 
 1141 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1142 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1143 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1144 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1145 
 1146 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1147 /*  [F4]  */    INVALID,                TNSZvr("pdep",VEX_RMrX,5),TNSZvr("mulx",VEX_RMrX,5),TNSZvr("shrx",VEX_VRMrX,5),
 1148 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1149 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1150 };
 1151 
 1152 const instable_t dis_opAVXF30F38[256] = {
 1153 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1154 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1155 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1156 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1157 
 1158 /*  [10]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1159 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1160 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1161 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1162 
 1163 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1164 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1165 /*  [28]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1166 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1167 
 1168 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1169 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1170 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1171 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1172 
 1173 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1174 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1175 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1176 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1177 
 1178 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1179 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1180 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1181 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1182 
 1183 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1184 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1185 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1186 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1187 
 1188 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1189 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1190 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1191 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1192 
 1193 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1194 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1195 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1196 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1197 
 1198 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1199 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1200 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1201 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1202 
 1203 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1204 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1205 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1206 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1207 
 1208 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1209 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1210 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1211 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1212 
 1213 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1214 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1215 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1216 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1217 
 1218 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1219 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1220 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1221 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1222 
 1223 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1224 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1225 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1226 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1227 
 1228 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1229 /*  [F4]  */    INVALID,                TNSZvr("pext",VEX_RMrX,5),INVALID,              TNSZvr("sarx",VEX_VRMrX,5),
 1230 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1231 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1232 };
 1233 /*
 1234  *      Decode table for SIMD instructions with the repz (0xf3) prefix.
 1235  */
 1236 const instable_t dis_opSIMDrepz[256] = {
 1237 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1238 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1239 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1240 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1241 
 1242 /*  [10]  */    TNSZ("movss",XMM,4),    TNSZ("movss",XMMS,4),   TNSZ("movsldup",XMM,16),INVALID,
 1243 /*  [14]  */    INVALID,                INVALID,                TNSZ("movshdup",XMM,16),INVALID,
 1244 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1245 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1246 
 1247 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1248 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1249 /*  [28]  */    INVALID,                INVALID,                TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
 1250 /*  [2C]  */    TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,           INVALID,
 1251 
 1252 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1253 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1254 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1255 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1256 
 1257 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1258 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1259 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1260 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1261 
 1262 /*  [50]  */    INVALID,                TNSZ("sqrtss",XMM,4),   TNSZ("rsqrtss",XMM,4),  TNSZ("rcpss",XMM,4),
 1263 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1264 /*  [58]  */    TNSZ("addss",XMM,4),    TNSZ("mulss",XMM,4),    TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16),
 1265 /*  [5C]  */    TNSZ("subss",XMM,4),    TNSZ("minss",XMM,4),    TNSZ("divss",XMM,4),    TNSZ("maxss",XMM,4),
 1266 
 1267 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1268 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1269 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1270 /*  [6C]  */    INVALID,                INVALID,                INVALID,                TNSZ("movdqu",XMM,16),
 1271 
 1272 /*  [70]  */    TNSZ("pshufhw",XMMP,16),INVALID,                INVALID,                INVALID,
 1273 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1274 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1275 /*  [7C]  */    INVALID,                INVALID,                TNSZ("movq",XMM,8),     TNSZ("movdqu",XMMS,16),
 1276 
 1277 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1278 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1279 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1280 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1281 
 1282 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1283 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1284 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1285 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1286 
 1287 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1288 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1289 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1290 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1291 
 1292 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1293 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1294 /*  [B8]  */    TS("popcnt",MRw),       INVALID,                INVALID,                INVALID,
 1295 /*  [BC]  */    TNSZ("tzcnt",MRw,5),    TS("lzcnt",MRw),        INVALID,                INVALID,
 1296 
 1297 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmpss",XMMP,4),   INVALID,
 1298 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1299 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1300 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1301 
 1302 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1303 /*  [D4]  */    INVALID,                INVALID,                TNS("movq2dq",XMMMX),   INVALID,
 1304 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1305 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1306 
 1307 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1308 /*  [E4]  */    INVALID,                INVALID,                TNSZ("cvtdq2pd",XMM,8), INVALID,
 1309 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1310 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1311 
 1312 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1313 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1314 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1315 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1316 };
 1317 
 1318 const instable_t dis_opAVXF30F[256] = {
 1319 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1320 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1321 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1322 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1323 
 1324 /*  [10]  */    TNSZ("vmovss",VEX_RMrX,4),      TNSZ("vmovss",VEX_RRX,4),       TNSZ("vmovsldup",VEX_MX,4),     INVALID,
 1325 /*  [14]  */    INVALID,                INVALID,                TNSZ("vmovshdup",VEX_MX,4),     INVALID,
 1326 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1327 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1328 
 1329 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1330 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1331 /*  [28]  */    INVALID,                INVALID,                TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
 1332 /*  [2C]  */    TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,         INVALID,
 1333 
 1334 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1335 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1336 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1337 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1338 
 1339 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1340 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1341 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1342 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1343 
 1344 /*  [50]  */    INVALID,                TNSZ("vsqrtss",VEX_RMrX,4),     TNSZ("vrsqrtss",VEX_RMrX,4),    TNSZ("vrcpss",VEX_RMrX,4),
 1345 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1346 /*  [58]  */    TNSZ("vaddss",VEX_RMrX,4),      TNSZ("vmulss",VEX_RMrX,4),      TNSZ("vcvtss2sd",VEX_RMrX,4),   TNSZ("vcvttps2dq",VEX_MX,16),
 1347 /*  [5C]  */    TNSZ("vsubss",VEX_RMrX,4),      TNSZ("vminss",VEX_RMrX,4),      TNSZ("vdivss",VEX_RMrX,4),      TNSZ("vmaxss",VEX_RMrX,4),
 1348 
 1349 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1350 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1351 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1352 /*  [6C]  */    INVALID,                INVALID,                INVALID,                TNSZ("vmovdqu",VEX_MX,16),
 1353 
 1354 /*  [70]  */    TNSZ("vpshufhw",VEX_MXI,16),INVALID,            INVALID,                INVALID,
 1355 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1356 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1357 /*  [7C]  */    INVALID,                INVALID,                TNSZ("vmovq",VEX_MX,8), TNSZ("vmovdqu",VEX_RX,16),
 1358 
 1359 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1360 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1361 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1362 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1363 
 1364 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1365 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1366 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1367 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1368 
 1369 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1370 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1371 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1372 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1373 
 1374 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1375 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1376 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1377 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1378 
 1379 /*  [C0]  */    INVALID,                INVALID,                TNSZ("vcmpss",VEX_RMRX,4),      INVALID,
 1380 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1381 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1382 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1383 
 1384 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1385 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1386 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1387 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1388 
 1389 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1390 /*  [E4]  */    INVALID,                INVALID,                TNSZ("vcvtdq2pd",VEX_MX,8),     INVALID,
 1391 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1392 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1393 
 1394 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1395 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1396 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1397 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1398 };
 1399 /*
 1400  * The following two tables are used to encode crc32 and movbe
 1401  * since they share the same opcodes.
 1402  */
 1403 const instable_t dis_op0F38F0[2] = {
 1404 /*  [00]  */    TNS("crc32b",CRC32),
 1405                 TS("movbe",MOVBE),
 1406 };
 1407 
 1408 const instable_t dis_op0F38F1[2] = {
 1409 /*  [00]  */    TS("crc32",CRC32),
 1410                 TS("movbe",MOVBE),
 1411 };
 1412 
 1413 /*
 1414  * The following table is used to distinguish between adox and adcx which share
 1415  * the same opcodes.
 1416  */
 1417 const instable_t dis_op0F38F6[2] = {
 1418 /*  [00]  */    TNS("adcx",ADX),
 1419                 TNS("adox",ADX),
 1420 };
 1421 
 1422 const instable_t dis_op0F38[256] = {
 1423 /*  [00]  */    TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
 1424 /*  [04]  */    TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16), TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
 1425 /*  [08]  */    TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
 1426 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1427 
 1428 /*  [10]  */    TNSZ("pblendvb",XMM_66r,16),INVALID,            INVALID,                INVALID,
 1429 /*  [14]  */    TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,        TNSZ("ptest",XMM_66r,16),
 1430 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1431 /*  [1C]  */    TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
 1432 
 1433 /*  [20]  */    TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
 1434 /*  [24]  */    TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,        INVALID,
 1435 /*  [28]  */    TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
 1436 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1437 
 1438 /*  [30]  */    TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
 1439 /*  [34]  */    TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,        TNSZ("pcmpgtq",XMM_66r,16),
 1440 /*  [38]  */    TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
 1441 /*  [3C]  */    TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
 1442 
 1443 /*  [40]  */    TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,        INVALID,
 1444 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1445 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1446 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1447 
 1448 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1449 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1450 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1451 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1452 
 1453 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1454 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1455 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1456 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1457 
 1458 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1459 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1460 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1461 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1462 
 1463 /*  [80]  */    TNSy("invept", RM_66r), TNSy("invvpid", RM_66r),TNSy("invpcid", RM_66r),INVALID,
 1464 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1465 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1466 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1467 
 1468 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1469 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1470 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1471 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1472 
 1473 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1474 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1475 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1476 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1477 
 1478 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1479 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1480 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1481 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1482 
 1483 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1484 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1485 /*  [C8]  */    TNSZ("sha1nexte",XMM,16),TNSZ("sha1msg1",XMM,16),TNSZ("sha1msg2",XMM,16),TNSZ("sha256rnds2",XMM,16),
 1486 /*  [CC]  */    TNSZ("sha256msg1",XMM,16),TNSZ("sha256msg2",XMM,16),INVALID,            INVALID,
 1487 
 1488 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1489 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1490 /*  [D8]  */    INVALID,                INVALID,                INVALID,                TNSZ("aesimc",XMM_66r,16),
 1491 /*  [DC]  */    TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
 1492 
 1493 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1494 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1495 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1496 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1497 /*  [F0]  */    IND(dis_op0F38F0),      IND(dis_op0F38F1),      INVALID,                INVALID,
 1498 /*  [F4]  */    INVALID,                INVALID,                IND(dis_op0F38F6),      INVALID,
 1499 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1500 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1501 };
 1502 
 1503 const instable_t dis_opAVX660F38[256] = {
 1504 /*  [00]  */    TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
 1505 /*  [04]  */    TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),     TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
 1506 /*  [08]  */    TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
 1507 /*  [0C]  */    TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),   TNSZ("vtestpd",VEX_RRI,16),
 1508 
 1509 /*  [10]  */    INVALID,                INVALID,                INVALID,                TNSZ("vcvtph2ps",VEX_MX,16),
 1510 /*  [14]  */    INVALID,                INVALID,                TNSZ("vpermps",VEX_RMrX,16),TNSZ("vptest",VEX_RRI,16),
 1511 /*  [18]  */    TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
 1512 /*  [1C]  */    TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
 1513 
 1514 /*  [20]  */    TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
 1515 /*  [24]  */    TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,        INVALID,
 1516 /*  [28]  */    TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
 1517 /*  [2C]  */    TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
 1518 
 1519 /*  [30]  */    TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
 1520 /*  [34]  */    TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),TNSZ("vpermd",VEX_RMrX,16),TNSZ("vpcmpgtq",VEX_RMrX,16),
 1521 /*  [38]  */    TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
 1522 /*  [3C]  */    TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
 1523 
 1524 /*  [40]  */    TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,      INVALID,
 1525 /*  [44]  */    INVALID,                TSaZ("vpsrlv",VEX_RMrX,16),TNSZ("vpsravd",VEX_RMrX,16),TSaZ("vpsllv",VEX_RMrX,16),
 1526 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1527 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1528 
 1529 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1530 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1531 /*  [58]  */    TNSZ("vpbroadcastd",VEX_MX,16),TNSZ("vpbroadcastq",VEX_MX,16),TNSZ("vbroadcasti128",VEX_MX,16),INVALID,
 1532 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1533 
 1534 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1535 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1536 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1537 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1538 
 1539 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1540 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1541 /*  [78]  */    TNSZ("vpbroadcastb",VEX_MX,16),TNSZ("vpbroadcastw",VEX_MX,16),INVALID,  INVALID,
 1542 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1543 
 1544 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1545 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1546 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1547 /*  [8C]  */    TSaZ("vpmaskmov",VEX_RMrX,16),INVALID,          TSaZ("vpmaskmov",VEX_RRM,16),INVALID,
 1548 
 1549 /*  [90]  */    TNSZ("vpgatherd",VEX_SbVM,16),TNSZ("vpgatherq",VEX_SbVM,16),TNSZ("vgatherdp",VEX_SbVM,16),TNSZ("vgatherqp",VEX_SbVM,16),
 1550 /*  [94]  */    INVALID,                INVALID,                TNSZ("vfmaddsub132p",FMA,16),TNSZ("vfmsubadd132p",FMA,16),
 1551 /*  [98]  */    TNSZ("vfmadd132p",FMA,16),TNSZ("vfmadd132s",FMA,16),TNSZ("vfmsub132p",FMA,16),TNSZ("vfmsub132s",FMA,16),
 1552 /*  [9C]  */    TNSZ("vfnmadd132p",FMA,16),TNSZ("vfnmadd132s",FMA,16),TNSZ("vfnmsub132p",FMA,16),TNSZ("vfnmsub132s",FMA,16),
 1553 
 1554 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1555 /*  [A4]  */    INVALID,                INVALID,                TNSZ("vfmaddsub213p",FMA,16),TNSZ("vfmsubadd213p",FMA,16),
 1556 /*  [A8]  */    TNSZ("vfmadd213p",FMA,16),TNSZ("vfmadd213s",FMA,16),TNSZ("vfmsub213p",FMA,16),TNSZ("vfmsub213s",FMA,16),
 1557 /*  [AC]  */    TNSZ("vfnmadd213p",FMA,16),TNSZ("vfnmadd213s",FMA,16),TNSZ("vfnmsub213p",FMA,16),TNSZ("vfnmsub213s",FMA,16),
 1558 
 1559 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1560 /*  [B4]  */    INVALID,                INVALID,                TNSZ("vfmaddsub231p",FMA,16),TNSZ("vfmsubadd231p",FMA,16),
 1561 /*  [B8]  */    TNSZ("vfmadd231p",FMA,16),TNSZ("vfmadd231s",FMA,16),TNSZ("vfmsub231p",FMA,16),TNSZ("vfmsub231s",FMA,16),
 1562 /*  [BC]  */    TNSZ("vfnmadd231p",FMA,16),TNSZ("vfnmadd231s",FMA,16),TNSZ("vfnmsub231p",FMA,16),TNSZ("vfnmsub231s",FMA,16),
 1563 
 1564 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1565 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1566 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1567 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1568 
 1569 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1570 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1571 /*  [D8]  */    INVALID,                INVALID,                INVALID,                TNSZ("vaesimc",VEX_MX,16),
 1572 /*  [DC]  */    TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
 1573 
 1574 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1575 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1576 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1577 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1578 /*  [F0]  */    IND(dis_op0F38F0),      IND(dis_op0F38F1),      INVALID,                INVALID,
 1579 /*  [F4]  */    INVALID,                INVALID,                INVALID,                TNSZvr("shlx",VEX_VRMrX,5),
 1580 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1581 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1582 };
 1583 
 1584 const instable_t dis_op0F3A[256] = {
 1585 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1586 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1587 /*  [08]  */    TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
 1588 /*  [0C]  */    TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
 1589 
 1590 /*  [10]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1591 /*  [14]  */    TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
 1592 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1593 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1594 
 1595 /*  [20]  */    TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
 1596 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1597 /*  [28]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1598 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1599 
 1600 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1601 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1602 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1603 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1604 
 1605 /*  [40]  */    TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
 1606 /*  [44]  */    TNSZ("pclmulqdq",XMMP_66r,16),INVALID,          INVALID,                INVALID,
 1607 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1608 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1609 
 1610 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1611 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1612 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1613 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1614 
 1615 /*  [60]  */    TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
 1616 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1617 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1618 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1619 
 1620 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1621 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1622 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1623 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1624 
 1625 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1626 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1627 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1628 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1629 
 1630 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1631 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1632 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1633 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1634 
 1635 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1636 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1637 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1638 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1639 
 1640 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1641 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1642 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1643 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1644 
 1645 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1646 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1647 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1648 /*  [CC]  */    TNSZ("sha1rnds4",XMMP,16),INVALID,              INVALID,                INVALID,
 1649 
 1650 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1651 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1652 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1653 /*  [DC]  */    INVALID,                INVALID,                INVALID,                TNSZ("aeskeygenassist",XMMP_66r,16),
 1654 
 1655 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1656 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1657 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1658 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1659 
 1660 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1661 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1662 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1663 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1664 };
 1665 
 1666 const instable_t dis_opAVX660F3A[256] = {
 1667 /*  [00]  */    TNSZ("vpermq",VEX_MXI,16),TNSZ("vpermpd",VEX_MXI,16),TNSZ("vpblendd",VEX_RMRX,16),INVALID,
 1668 /*  [04]  */    TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
 1669 /*  [08]  */    TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
 1670 /*  [0C]  */    TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
 1671 
 1672 /*  [10]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1673 /*  [14]  */    TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
 1674 /*  [18]  */    TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,         INVALID,
 1675 /*  [1C]  */    INVALID,                TNSZ("vcvtps2ph",VEX_RX,16),            INVALID,                INVALID,
 1676 
 1677 /*  [20]  */    TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
 1678 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1679 /*  [28]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1680 /*  [2C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1681 
 1682 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1683 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1684 /*  [38]  */    TNSZ("vinserti128",VEX_RMRX,16),TNSZ("vextracti128",VEX_RIM,16),INVALID,                INVALID,
 1685 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1686 
 1687 /*  [40]  */    TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
 1688 /*  [44]  */    TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,         TNSZ("vperm2i128",VEX_RMRX,16),INVALID,
 1689 /*  [48]  */    INVALID,                INVALID,                TNSZ("vblendvps",VEX_RMRX,8),   TNSZ("vblendvpd",VEX_RMRX,16),
 1690 /*  [4C]  */    TNSZ("vpblendvb",VEX_RMRX,16),INVALID,          INVALID,                INVALID,
 1691 
 1692 /*  [50]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1693 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1694 /*  [58]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1695 /*  [5C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1696 
 1697 /*  [60]  */    TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
 1698 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1699 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1700 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1701 
 1702 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1703 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1704 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1705 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1706 
 1707 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1708 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1709 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1710 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1711 
 1712 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1713 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1714 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1715 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1716 
 1717 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1718 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1719 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1720 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1721 
 1722 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1723 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1724 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1725 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1726 
 1727 /*  [C0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1728 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1729 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1730 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1731 
 1732 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1733 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1734 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1735 /*  [DC]  */    INVALID,                INVALID,                INVALID,                TNSZ("vaeskeygenassist",VEX_MXI,16),
 1736 
 1737 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1738 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1739 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1740 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1741 
 1742 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1743 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1744 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1745 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1746 };
 1747 
 1748 /*
 1749  *      Decode table for 0x0F0D which uses the first byte of the mod_rm to
 1750  *      indicate a sub-code.
 1751  */
 1752 const instable_t dis_op0F0D[8] = {
 1753 /*  [00]  */    INVALID,                TNS("prefetchw",PREF),  TNS("prefetchwt1",PREF),INVALID,
 1754 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1755 };
 1756 
 1757 /*
 1758  *      Decode table for 0x0F opcodes
 1759  */
 1760 
 1761 const instable_t dis_op0F[16][16] = {
 1762 {
 1763 /*  [00]  */    IND(dis_op0F00),        IND(dis_op0F01),        TNS("lar",MR),          TNS("lsl",MR),
 1764 /*  [04]  */    INVALID,                TNS("syscall",NORM),    TNS("clts",NORM),       TNS("sysret",NORM),
 1765 /*  [08]  */    TNS("invd",NORM),       TNS("wbinvd",NORM),     INVALID,                TNS("ud2",NORM),
 1766 /*  [0C]  */    INVALID,                IND(dis_op0F0D),        INVALID,                INVALID,
 1767 }, {
 1768 /*  [10]  */    TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),  TNSZ("movlps",XMMOS,8),
 1769 /*  [14]  */    TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
 1770 /*  [18]  */    IND(dis_op0F18),        INVALID,                INVALID,                INVALID,
 1771 /*  [1C]  */    INVALID,                INVALID,                INVALID,                TS("nop",Mw),
 1772 }, {
 1773 /*  [20]  */    TSy("mov",SREG),        TSy("mov",SREG),        TSy("mov",SREG),        TSy("mov",SREG),
 1774 /*  [24]  */    TSx("mov",SREG),        INVALID,                TSx("mov",SREG),        INVALID,
 1775 /*  [28]  */    TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
 1776 /*  [2C]  */    TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
 1777 }, {
 1778 /*  [30]  */    TNS("wrmsr",NORM),      TNS("rdtsc",NORM),      TNS("rdmsr",NORM),      TNS("rdpmc",NORM),
 1779 /*  [34]  */    TNSx("sysenter",NORM),  TNSx("sysexit",NORM),   INVALID,                INVALID,
 1780 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1781 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1782 }, {
 1783 /*  [40]  */    TS("cmovx.o",MR),       TS("cmovx.no",MR),      TS("cmovx.b",MR),       TS("cmovx.ae",MR),
 1784 /*  [44]  */    TS("cmovx.e",MR),       TS("cmovx.ne",MR),      TS("cmovx.be",MR),      TS("cmovx.a",MR),
 1785 /*  [48]  */    TS("cmovx.s",MR),       TS("cmovx.ns",MR),      TS("cmovx.pe",MR),      TS("cmovx.po",MR),
 1786 /*  [4C]  */    TS("cmovx.l",MR),       TS("cmovx.ge",MR),      TS("cmovx.le",MR),      TS("cmovx.g",MR),
 1787 }, {
 1788 /*  [50]  */    TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
 1789 /*  [54]  */    TNSZ("andps",XMMO,16),  TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16),   TNSZ("xorps",XMMO,16),
 1790 /*  [58]  */    TNSZ("addps",XMMO,16),  TNSZ("mulps",XMMO,16),  TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
 1791 /*  [5C]  */    TNSZ("subps",XMMO,16),  TNSZ("minps",XMMO,16),  TNSZ("divps",XMMO,16),  TNSZ("maxps",XMMO,16),
 1792 }, {
 1793 /*  [60]  */    TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
 1794 /*  [64]  */    TNSZ("pcmpgtb",MMO,8),  TNSZ("pcmpgtw",MMO,8),  TNSZ("pcmpgtd",MMO,8),  TNSZ("packuswb",MMO,8),
 1795 /*  [68]  */    TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
 1796 /*  [6C]  */    TNSZ("INVALID",MMO,0),  TNSZ("INVALID",MMO,0),  TNSZ("movd",MMO,4),     TNSZ("movq",MMO,8),
 1797 }, {
 1798 /*  [70]  */    TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR),       TNS("psrXXX",MR),       TNS("psrXXX",MR),
 1799 /*  [74]  */    TNSZ("pcmpeqb",MMO,8),  TNSZ("pcmpeqw",MMO,8),  TNSZ("pcmpeqd",MMO,8),  TNS("emms",NORM),
 1800 /*  [78]  */    TNSy("vmread",RM),      TNSy("vmwrite",MR),     INVALID,                INVALID,
 1801 /*  [7C]  */    INVALID,                INVALID,                TNSZ("movd",MMOS,4),    TNSZ("movq",MMOS,8),
 1802 }, {
 1803 /*  [80]  */    TNS("jo",D),            TNS("jno",D),           TNS("jb",D),            TNS("jae",D),
 1804 /*  [84]  */    TNS("je",D),            TNS("jne",D),           TNS("jbe",D),           TNS("ja",D),
 1805 /*  [88]  */    TNS("js",D),            TNS("jns",D),           TNS("jp",D),            TNS("jnp",D),
 1806 /*  [8C]  */    TNS("jl",D),            TNS("jge",D),           TNS("jle",D),           TNS("jg",D),
 1807 }, {
 1808 /*  [90]  */    TNS("seto",Mb),         TNS("setno",Mb),        TNS("setb",Mb),         TNS("setae",Mb),
 1809 /*  [94]  */    TNS("sete",Mb),         TNS("setne",Mb),        TNS("setbe",Mb),        TNS("seta",Mb),
 1810 /*  [98]  */    TNS("sets",Mb),         TNS("setns",Mb),        TNS("setp",Mb),         TNS("setnp",Mb),
 1811 /*  [9C]  */    TNS("setl",Mb),         TNS("setge",Mb),        TNS("setle",Mb),        TNS("setg",Mb),
 1812 }, {
 1813 /*  [A0]  */    TSp("push",LSEG),       TSp("pop",LSEG),        TNS("cpuid",NORM),      TS("bt",RMw),
 1814 /*  [A4]  */    TS("shld",DSHIFT),      TS("shld",DSHIFTcl),    INVALID,                INVALID,
 1815 /*  [A8]  */    TSp("push",LSEG),       TSp("pop",LSEG),        TNS("rsm",NORM),        TS("bts",RMw),
 1816 /*  [AC]  */    TS("shrd",DSHIFT),      TS("shrd",DSHIFTcl),    IND(dis_op0FAE),        TS("imul",MRw),
 1817 }, {
 1818 /*  [B0]  */    TNS("cmpxchgb",RMw),    TS("cmpxchg",RMw),      TS("lss",MR),           TS("btr",RMw),
 1819 /*  [B4]  */    TS("lfs",MR),           TS("lgs",MR),           TS("movzb",MOVZ),       TNS("movzwl",MOVZ),
 1820 /*  [B8]  */    TNS("INVALID",MRw),     INVALID,                IND(dis_op0FBA),        TS("btc",RMw),
 1821 /*  [BC]  */    TS("bsf",MRw),          TS("bsr",MRw),          TS("movsb",MOVZ),       TNS("movswl",MOVZ),
 1822 }, {
 1823 /*  [C0]  */    TNS("xaddb",XADDB),     TS("xadd",RMw),         TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
 1824 /*  [C4]  */    TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P),    TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
 1825 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1826 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1827 }, {
 1828 /*  [D0]  */    INVALID,                TNSZ("psrlw",MMO,8),    TNSZ("psrld",MMO,8),    TNSZ("psrlq",MMO,8),
 1829 /*  [D4]  */    TNSZ("paddq",MMO,8),    TNSZ("pmullw",MMO,8),   TNSZ("INVALID",MMO,0),  TNS("pmovmskb",MMOM3),
 1830 /*  [D8]  */    TNSZ("psubusb",MMO,8),  TNSZ("psubusw",MMO,8),  TNSZ("pminub",MMO,8),   TNSZ("pand",MMO,8),
 1831 /*  [DC]  */    TNSZ("paddusb",MMO,8),  TNSZ("paddusw",MMO,8),  TNSZ("pmaxub",MMO,8),   TNSZ("pandn",MMO,8),
 1832 }, {
 1833 /*  [E0]  */    TNSZ("pavgb",MMO,8),    TNSZ("psraw",MMO,8),    TNSZ("psrad",MMO,8),    TNSZ("pavgw",MMO,8),
 1834 /*  [E4]  */    TNSZ("pmulhuw",MMO,8),  TNSZ("pmulhw",MMO,8),   TNS("INVALID",XMMO),    TNSZ("movntq",MMOMS,8),
 1835 /*  [E8]  */    TNSZ("psubsb",MMO,8),   TNSZ("psubsw",MMO,8),   TNSZ("pminsw",MMO,8),   TNSZ("por",MMO,8),
 1836 /*  [EC]  */    TNSZ("paddsb",MMO,8),   TNSZ("paddsw",MMO,8),   TNSZ("pmaxsw",MMO,8),   TNSZ("pxor",MMO,8),
 1837 }, {
 1838 /*  [F0]  */    INVALID,                TNSZ("psllw",MMO,8),    TNSZ("pslld",MMO,8),    TNSZ("psllq",MMO,8),
 1839 /*  [F4]  */    TNSZ("pmuludq",MMO,8),  TNSZ("pmaddwd",MMO,8),  TNSZ("psadbw",MMO,8),   TNSZ("maskmovq",MMOIMPL,8),
 1840 /*  [F8]  */    TNSZ("psubb",MMO,8),    TNSZ("psubw",MMO,8),    TNSZ("psubd",MMO,8),    TNSZ("psubq",MMO,8),
 1841 /*  [FC]  */    TNSZ("paddb",MMO,8),    TNSZ("paddw",MMO,8),    TNSZ("paddd",MMO,8),    INVALID,
 1842 } };
 1843 
 1844 const instable_t dis_opAVX0F[16][16] = {
 1845 {
 1846 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1847 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1848 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1849 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1850 }, {
 1851 /*  [10]  */    TNSZ("vmovups",VEX_MX,16),      TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),   TNSZ("vmovlps",VEX_RM,8),
 1852 /*  [14]  */    TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
 1853 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1854 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1855 }, {
 1856 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1857 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1858 /*  [28]  */    TNSZ("vmovaps",VEX_MX,16),      TNSZ("vmovaps",VEX_RX,16),INVALID,              TNSZ("vmovntps",VEX_RM,16),
 1859 /*  [2C]  */    INVALID,                INVALID,                TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
 1860 }, {
 1861 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1862 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1863 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1864 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1865 }, {
 1866 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1867 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1868 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1869 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1870 }, {
 1871 /*  [50]  */    TNS("vmovmskps",VEX_MR),        TNSZ("vsqrtps",VEX_MX,16),      TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
 1872 /*  [54]  */    TNSZ("vandps",VEX_RMrX,16),     TNSZ("vandnps",VEX_RMrX,16),    TNSZ("vorps",VEX_RMrX,16),      TNSZ("vxorps",VEX_RMrX,16),
 1873 /*  [58]  */    TNSZ("vaddps",VEX_RMrX,16),     TNSZ("vmulps",VEX_RMrX,16),     TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
 1874 /*  [5C]  */    TNSZ("vsubps",VEX_RMrX,16),     TNSZ("vminps",VEX_RMrX,16),     TNSZ("vdivps",VEX_RMrX,16),     TNSZ("vmaxps",VEX_RMrX,16),
 1875 }, {
 1876 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1877 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1878 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1879 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1880 }, {
 1881 /*  [70]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1882 /*  [74]  */    INVALID,                INVALID,                INVALID,                TNS("vzeroupper", VEX_NONE),
 1883 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1884 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1885 }, {
 1886 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1887 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1888 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1889 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1890 }, {
 1891 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1892 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1893 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1894 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1895 }, {
 1896 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1897 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1898 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1899 /*  [AC]  */    INVALID,                INVALID,                TNSZ("vldmxcsr",VEX_MO,2),              INVALID,
 1900 }, {
 1901 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1902 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1903 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1904 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1905 }, {
 1906 /*  [C0]  */    INVALID,                INVALID,                TNSZ("vcmpps",VEX_RMRX,16),INVALID,
 1907 /*  [C4]  */    INVALID,                INVALID,                TNSZ("vshufps",VEX_RMRX,16),INVALID,
 1908 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1909 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1910 }, {
 1911 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1912 /*  [D4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1913 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1914 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1915 }, {
 1916 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1917 /*  [E4]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1918 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1919 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1920 }, {
 1921 /*  [F0]  */    INVALID,                INVALID,                TNSZvr("andn",VEX_RMrX,5),TNSZvr("bls",BLS,5),
 1922 /*  [F4]  */    INVALID,                TNSZvr("bzhi",VEX_VRMrX,5),INVALID,             TNSZvr("bextr",VEX_VRMrX,5),
 1923 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1924 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
 1925 } };
 1926 
 1927 /*
 1928  *      Decode table for 0x80 opcodes
 1929  */
 1930 
 1931 const instable_t dis_op80[8] = {
 1932 
 1933 /*  [0]  */     TNS("addb",IMlw),       TNS("orb",IMw),         TNS("adcb",IMlw),       TNS("sbbb",IMlw),
 1934 /*  [4]  */     TNS("andb",IMw),        TNS("subb",IMlw),       TNS("xorb",IMw),        TNS("cmpb",IMlw),
 1935 };
 1936 
 1937 
 1938 /*
 1939  *      Decode table for 0x81 opcodes.
 1940  */
 1941 
 1942 const instable_t dis_op81[8] = {
 1943 
 1944 /*  [0]  */     TS("add",IMlw),         TS("or",IMw),           TS("adc",IMlw),         TS("sbb",IMlw),
 1945 /*  [4]  */     TS("and",IMw),          TS("sub",IMlw),         TS("xor",IMw),          TS("cmp",IMlw),
 1946 };
 1947 
 1948 
 1949 /*
 1950  *      Decode table for 0x82 opcodes.
 1951  */
 1952 
 1953 const instable_t dis_op82[8] = {
 1954 
 1955 /*  [0]  */     TNSx("addb",IMlw),      TNSx("orb",IMlw),       TNSx("adcb",IMlw),      TNSx("sbbb",IMlw),
 1956 /*  [4]  */     TNSx("andb",IMlw),      TNSx("subb",IMlw),      TNSx("xorb",IMlw),      TNSx("cmpb",IMlw),
 1957 };
 1958 /*
 1959  *      Decode table for 0x83 opcodes.
 1960  */
 1961 
 1962 const instable_t dis_op83[8] = {
 1963 
 1964 /*  [0]  */     TS("add",IMlw),         TS("or",IMlw),          TS("adc",IMlw),         TS("sbb",IMlw),
 1965 /*  [4]  */     TS("and",IMlw),         TS("sub",IMlw),         TS("xor",IMlw),         TS("cmp",IMlw),
 1966 };
 1967 
 1968 /*
 1969  *      Decode table for 0xC0 opcodes.
 1970  */
 1971 
 1972 const instable_t dis_opC0[8] = {
 1973 
 1974 /*  [0]  */     TNS("rolb",MvI),        TNS("rorb",MvI),        TNS("rclb",MvI),        TNS("rcrb",MvI),
 1975 /*  [4]  */     TNS("shlb",MvI),        TNS("shrb",MvI),        INVALID,                TNS("sarb",MvI),
 1976 };
 1977 
 1978 /*
 1979  *      Decode table for 0xD0 opcodes.
 1980  */
 1981 
 1982 const instable_t dis_opD0[8] = {
 1983 
 1984 /*  [0]  */     TNS("rolb",Mv),         TNS("rorb",Mv),         TNS("rclb",Mv),         TNS("rcrb",Mv),
 1985 /*  [4]  */     TNS("shlb",Mv),         TNS("shrb",Mv),         TNS("salb",Mv),         TNS("sarb",Mv),
 1986 };
 1987 
 1988 /*
 1989  *      Decode table for 0xC1 opcodes.
 1990  *      186 instruction set
 1991  */
 1992 
 1993 const instable_t dis_opC1[8] = {
 1994 
 1995 /*  [0]  */     TS("rol",MvI),          TS("ror",MvI),          TS("rcl",MvI),          TS("rcr",MvI),
 1996 /*  [4]  */     TS("shl",MvI),          TS("shr",MvI),          TS("sal",MvI),          TS("sar",MvI),
 1997 };
 1998 
 1999 /*
 2000  *      Decode table for 0xD1 opcodes.
 2001  */
 2002 
 2003 const instable_t dis_opD1[8] = {
 2004 
 2005 /*  [0]  */     TS("rol",Mv),           TS("ror",Mv),           TS("rcl",Mv),           TS("rcr",Mv),
 2006 /*  [4]  */     TS("shl",Mv),           TS("shr",Mv),           TS("sal",Mv),           TS("sar",Mv),
 2007 };
 2008 
 2009 
 2010 /*
 2011  *      Decode table for 0xD2 opcodes.
 2012  */
 2013 
 2014 const instable_t dis_opD2[8] = {
 2015 
 2016 /*  [0]  */     TNS("rolb",Mv),         TNS("rorb",Mv),         TNS("rclb",Mv),         TNS("rcrb",Mv),
 2017 /*  [4]  */     TNS("shlb",Mv),         TNS("shrb",Mv),         TNS("salb",Mv),         TNS("sarb",Mv),
 2018 };
 2019 /*
 2020  *      Decode table for 0xD3 opcodes.
 2021  */
 2022 
 2023 const instable_t dis_opD3[8] = {
 2024 
 2025 /*  [0]  */     TS("rol",Mv),           TS("ror",Mv),           TS("rcl",Mv),           TS("rcr",Mv),
 2026 /*  [4]  */     TS("shl",Mv),           TS("shr",Mv),           TS("salb",Mv),          TS("sar",Mv),
 2027 };
 2028 
 2029 
 2030 /*
 2031  *      Decode table for 0xF6 opcodes.
 2032  */
 2033 
 2034 const instable_t dis_opF6[8] = {
 2035 
 2036 /*  [0]  */     TNS("testb",IMw),       TNS("testb",IMw),       TNS("notb",Mw),         TNS("negb",Mw),
 2037 /*  [4]  */     TNS("mulb",MA),         TNS("imulb",MA),        TNS("divb",MA),         TNS("idivb",MA),
 2038 };
 2039 
 2040 
 2041 /*
 2042  *      Decode table for 0xF7 opcodes.
 2043  */
 2044 
 2045 const instable_t dis_opF7[8] = {
 2046 
 2047 /*  [0]  */     TS("test",IMw),         TS("test",IMw),         TS("not",Mw),           TS("neg",Mw),
 2048 /*  [4]  */     TS("mul",MA),           TS("imul",MA),          TS("div",MA),           TS("idiv",MA),
 2049 };
 2050 
 2051 
 2052 /*
 2053  *      Decode table for 0xFE opcodes.
 2054  */
 2055 
 2056 const instable_t dis_opFE[8] = {
 2057 
 2058 /*  [0]  */     TNS("incb",Mw),         TNS("decb",Mw),         INVALID,                INVALID,
 2059 /*  [4]  */     INVALID,                INVALID,                INVALID,                INVALID,
 2060 };
 2061 /*
 2062  *      Decode table for 0xFF opcodes.
 2063  */
 2064 
 2065 const instable_t dis_opFF[8] = {
 2066 
 2067 /*  [0]  */     TS("inc",Mw),           TS("dec",Mw),           TNSyp("call",INM),      TNS("lcall",INM),
 2068 /*  [4]  */     TNSy("jmp",INM),        TNS("ljmp",INM),        TSp("push",M),          INVALID,
 2069 };
 2070 
 2071 /* for 287 instructions, which are a mess to decode */
 2072 
 2073 const instable_t dis_opFP1n2[8][8] = {
 2074 {
 2075 /* bit pattern: 1101 1xxx MODxx xR/M */
 2076 /*  [0,0] */    TNS("fadds",M),         TNS("fmuls",M),         TNS("fcoms",M),         TNS("fcomps",M),
 2077 /*  [0,4] */    TNS("fsubs",M),         TNS("fsubrs",M),        TNS("fdivs",M),         TNS("fdivrs",M),
 2078 }, {
 2079 /*  [1,0]  */   TNS("flds",M),          INVALID,                TNS("fsts",M),          TNS("fstps",M),
 2080 /*  [1,4]  */   TNSZ("fldenv",M,28),    TNSZ("fldcw",M,2),      TNSZ("fnstenv",M,28),   TNSZ("fnstcw",M,2),
 2081 }, {
 2082 /*  [2,0]  */   TNS("fiaddl",M),        TNS("fimull",M),        TNS("ficoml",M),        TNS("ficompl",M),
 2083 /*  [2,4]  */   TNS("fisubl",M),        TNS("fisubrl",M),       TNS("fidivl",M),        TNS("fidivrl",M),
 2084 }, {
 2085 /*  [3,0]  */   TNS("fildl",M),         TNSZ("tisttpl",M,4),    TNS("fistl",M),         TNS("fistpl",M),
 2086 /*  [3,4]  */   INVALID,                TNSZ("fldt",M,10),      INVALID,                TNSZ("fstpt",M,10),
 2087 }, {
 2088 /*  [4,0]  */   TNSZ("faddl",M,8),      TNSZ("fmull",M,8),      TNSZ("fcoml",M,8),      TNSZ("fcompl",M,8),
 2089 /*  [4,1]  */   TNSZ("fsubl",M,8),      TNSZ("fsubrl",M,8),     TNSZ("fdivl",M,8),      TNSZ("fdivrl",M,8),
 2090 }, {
 2091 /*  [5,0]  */   TNSZ("fldl",M,8),       TNSZ("fisttpll",M,8),   TNSZ("fstl",M,8),       TNSZ("fstpl",M,8),
 2092 /*  [5,4]  */   TNSZ("frstor",M,108),   INVALID,                TNSZ("fnsave",M,108),   TNSZ("fnstsw",M,2),
 2093 }, {
 2094 /*  [6,0]  */   TNSZ("fiadd",M,2),      TNSZ("fimul",M,2),      TNSZ("ficom",M,2),      TNSZ("ficomp",M,2),
 2095 /*  [6,4]  */   TNSZ("fisub",M,2),      TNSZ("fisubr",M,2),     TNSZ("fidiv",M,2),      TNSZ("fidivr",M,2),
 2096 }, {
 2097 /*  [7,0]  */   TNSZ("fild",M,2),       TNSZ("fisttp",M,2),     TNSZ("fist",M,2),       TNSZ("fistp",M,2),
 2098 /*  [7,4]  */   TNSZ("fbld",M,10),      TNSZ("fildll",M,8),     TNSZ("fbstp",M,10),     TNSZ("fistpll",M,8),
 2099 } };
 2100 
 2101 const instable_t dis_opFP3[8][8] = {
 2102 {
 2103 /* bit  pattern:        1101 1xxx 11xx xREG */
 2104 /*  [0,0]  */   TNS("fadd",FF),         TNS("fmul",FF),         TNS("fcom",F),          TNS("fcomp",F),
 2105 /*  [0,4]  */   TNS("fsub",FF),         TNS("fsubr",FF),        TNS("fdiv",FF),         TNS("fdivr",FF),
 2106 }, {
 2107 /*  [1,0]  */   TNS("fld",F),           TNS("fxch",F),          TNS("fnop",NORM),       TNS("fstp",F),
 2108 /*  [1,4]  */   INVALID,                INVALID,                INVALID,                INVALID,
 2109 }, {
 2110 /*  [2,0]  */   INVALID,                INVALID,                INVALID,                INVALID,
 2111 /*  [2,4]  */   INVALID,                TNS("fucompp",NORM),    INVALID,                INVALID,
 2112 }, {
 2113 /*  [3,0]  */   INVALID,                INVALID,                INVALID,                INVALID,
 2114 /*  [3,4]  */   INVALID,                INVALID,                INVALID,                INVALID,
 2115 }, {
 2116 /*  [4,0]  */   TNS("fadd",FF),         TNS("fmul",FF),         TNS("fcom",F),          TNS("fcomp",F),
 2117 /*  [4,4]  */   TNS("fsub",FF),         TNS("fsubr",FF),        TNS("fdiv",FF),         TNS("fdivr",FF),
 2118 }, {
 2119 /*  [5,0]  */   TNS("ffree",F),         TNS("fxch",F),          TNS("fst",F),           TNS("fstp",F),
 2120 /*  [5,4]  */   TNS("fucom",F),         TNS("fucomp",F),        INVALID,                INVALID,
 2121 }, {
 2122 /*  [6,0]  */   TNS("faddp",FF),        TNS("fmulp",FF),        TNS("fcomp",F),         TNS("fcompp",NORM),
 2123 /*  [6,4]  */   TNS("fsubp",FF),        TNS("fsubrp",FF),       TNS("fdivp",FF),        TNS("fdivrp",FF),
 2124 }, {
 2125 /*  [7,0]  */   TNS("ffreep",F),                TNS("fxch",F),          TNS("fstp",F),          TNS("fstp",F),
 2126 /*  [7,4]  */   TNS("fnstsw",M),        TNS("fucomip",FFC),     TNS("fcomip",FFC),      INVALID,
 2127 } };
 2128 
 2129 const instable_t dis_opFP4[4][8] = {
 2130 {
 2131 /* bit pattern: 1101 1001 111x xxxx */
 2132 /*  [0,0]  */   TNS("fchs",NORM),       TNS("fabs",NORM),       INVALID,                INVALID,
 2133 /*  [0,4]  */   TNS("ftst",NORM),       TNS("fxam",NORM),       TNS("ftstp",NORM),      INVALID,
 2134 }, {
 2135 /*  [1,0]  */   TNS("fld1",NORM),       TNS("fldl2t",NORM),     TNS("fldl2e",NORM),     TNS("fldpi",NORM),
 2136 /*  [1,4]  */   TNS("fldlg2",NORM),     TNS("fldln2",NORM),     TNS("fldz",NORM),       INVALID,
 2137 }, {
 2138 /*  [2,0]  */   TNS("f2xm1",NORM),      TNS("fyl2x",NORM),      TNS("fptan",NORM),      TNS("fpatan",NORM),
 2139 /*  [2,4]  */   TNS("fxtract",NORM),    TNS("fprem1",NORM),     TNS("fdecstp",NORM),    TNS("fincstp",NORM),
 2140 }, {
 2141 /*  [3,0]  */   TNS("fprem",NORM),      TNS("fyl2xp1",NORM),    TNS("fsqrt",NORM),      TNS("fsincos",NORM),
 2142 /*  [3,4]  */   TNS("frndint",NORM),    TNS("fscale",NORM),     TNS("fsin",NORM),       TNS("fcos",NORM),
 2143 } };
 2144 
 2145 const instable_t dis_opFP5[8] = {
 2146 /* bit pattern: 1101 1011 111x xxxx */
 2147 /*  [0]  */     TNS("feni",NORM),       TNS("fdisi",NORM),      TNS("fnclex",NORM),     TNS("fninit",NORM),
 2148 /*  [4]  */     TNS("fsetpm",NORM),     TNS("frstpm",NORM),     INVALID,                INVALID,
 2149 };
 2150 
 2151 const instable_t dis_opFP6[8] = {
 2152 /* bit pattern: 1101 1011 11yy yxxx */
 2153 /*  [00]  */    TNS("fcmov.nb",FF),     TNS("fcmov.ne",FF),     TNS("fcmov.nbe",FF),    TNS("fcmov.nu",FF),
 2154 /*  [04]  */    INVALID,                TNS("fucomi",F),        TNS("fcomi",F),         INVALID,
 2155 };
 2156 
 2157 const instable_t dis_opFP7[8] = {
 2158 /* bit pattern: 1101 1010 11yy yxxx */
 2159 /*  [00]  */    TNS("fcmov.b",FF),      TNS("fcmov.e",FF),      TNS("fcmov.be",FF),     TNS("fcmov.u",FF),
 2160 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
 2161 };
 2162 
 2163 /*
 2164  *      Main decode table for the op codes.  The first two nibbles
 2165  *      will be used as an index into the table.  If there is a
 2166  *      a need to further decode an instruction, the array to be
 2167  *      referenced is indicated with the other two entries being
 2168  *      empty.
 2169  */
 2170 
 2171 const instable_t dis_distable[16][16] = {
 2172 {
 2173 /* [0,0] */     TNS("addb",RMw),        TS("add",RMw),          TNS("addb",MRw),        TS("add",MRw),
 2174 /* [0,4] */     TNS("addb",IA),         TS("add",IA),           TSx("push",SEG),        TSx("pop",SEG),
 2175 /* [0,8] */     TNS("orb",RMw),         TS("or",RMw),           TNS("orb",MRw),         TS("or",MRw),
 2176 /* [0,C] */     TNS("orb",IA),          TS("or",IA),            TSx("push",SEG),        IND(dis_op0F),
 2177 }, {
 2178 /* [1,0] */     TNS("adcb",RMw),        TS("adc",RMw),          TNS("adcb",MRw),        TS("adc",MRw),
 2179 /* [1,4] */     TNS("adcb",IA),         TS("adc",IA),           TSx("push",SEG),        TSx("pop",SEG),
 2180 /* [1,8] */     TNS("sbbb",RMw),        TS("sbb",RMw),          TNS("sbbb",MRw),        TS("sbb",MRw),
 2181 /* [1,C] */     TNS("sbbb",IA),         TS("sbb",IA),           TSx("push",SEG),        TSx("pop",SEG),
 2182 }, {
 2183 /* [2,0] */     TNS("andb",RMw),        TS("and",RMw),          TNS("andb",MRw),        TS("and",MRw),
 2184 /* [2,4] */     TNS("andb",IA),         TS("and",IA),           TNSx("%es:",OVERRIDE),  TNSx("daa",NORM),
 2185 /* [2,8] */     TNS("subb",RMw),        TS("sub",RMw),          TNS("subb",MRw),        TS("sub",MRw),
 2186 /* [2,C] */     TNS("subb",IA),         TS("sub",IA),           TNS("%cs:",OVERRIDE),   TNSx("das",NORM),
 2187 }, {
 2188 /* [3,0] */     TNS("xorb",RMw),        TS("xor",RMw),          TNS("xorb",MRw),        TS("xor",MRw),
 2189 /* [3,4] */     TNS("xorb",IA),         TS("xor",IA),           TNSx("%ss:",OVERRIDE),  TNSx("aaa",NORM),
 2190 /* [3,8] */     TNS("cmpb",RMw),        TS("cmp",RMw),          TNS("cmpb",MRw),        TS("cmp",MRw),
 2191 /* [3,C] */     TNS("cmpb",IA),         TS("cmp",IA),           TNSx("%ds:",OVERRIDE),  TNSx("aas",NORM),
 2192 }, {
 2193 /* [4,0] */     TSx("inc",R),           TSx("inc",R),           TSx("inc",R),           TSx("inc",R),
 2194 /* [4,4] */     TSx("inc",R),           TSx("inc",R),           TSx("inc",R),           TSx("inc",R),
 2195 /* [4,8] */     TSx("dec",R),           TSx("dec",R),           TSx("dec",R),           TSx("dec",R),
 2196 /* [4,C] */     TSx("dec",R),           TSx("dec",R),           TSx("dec",R),           TSx("dec",R),
 2197 }, {
 2198 /* [5,0] */     TSp("push",R),          TSp("push",R),          TSp("push",R),          TSp("push",R),
 2199 /* [5,4] */     TSp("push",R),          TSp("push",R),          TSp("push",R),          TSp("push",R),
 2200 /* [5,8] */     TSp("pop",R),           TSp("pop",R),           TSp("pop",R),           TSp("pop",R),
 2201 /* [5,C] */     TSp("pop",R),           TSp("pop",R),           TSp("pop",R),           TSp("pop",R),
 2202 }, {
 2203 /* [6,0] */     TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),      TNS("arpl",RMw),
 2204 /* [6,4] */     TNS("%fs:",OVERRIDE),   TNS("%gs:",OVERRIDE),   TNS("data16",DM),       TNS("addr16",AM),
 2205 /* [6,8] */     TSp("push",I),          TS("imul",IMUL),        TSp("push",Ib), TS("imul",IMUL),
 2206 /* [6,C] */     TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4),   TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
 2207 }, {
 2208 /* [7,0] */     TNSy("jo",BD),          TNSy("jno",BD),         TNSy("jb",BD),          TNSy("jae",BD),
 2209 /* [7,4] */     TNSy("je",BD),          TNSy("jne",BD),         TNSy("jbe",BD),         TNSy("ja",BD),
 2210 /* [7,8] */     TNSy("js",BD),          TNSy("jns",BD),         TNSy("jp",BD),          TNSy("jnp",BD),
 2211 /* [7,C] */     TNSy("jl",BD),          TNSy("jge",BD),         TNSy("jle",BD),         TNSy("jg",BD),
 2212 }, {
 2213 /* [8,0] */     IND(dis_op80),          IND(dis_op81),          INDx(dis_op82),         IND(dis_op83),
 2214 /* [8,4] */     TNS("testb",RMw),       TS("test",RMw),         TNS("xchgb",RMw),       TS("xchg",RMw),
 2215 /* [8,8] */     TNS("movb",RMw),        TS("mov",RMw),          TNS("movb",MRw),        TS("mov",MRw),
 2216 /* [8,C] */     TNS("movw",SM),         TS("lea",MR),           TNS("movw",MS),         TSp("pop",M),
 2217 }, {
 2218 /* [9,0] */     TNS("nop",NORM),        TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),
 2219 /* [9,4] */     TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),
 2220 /* [9,8] */     TNS("cXtX",CBW),        TNS("cXtX",CWD),        TNSx("lcall",SO),       TNS("fwait",NORM),
 2221 /* [9,C] */     TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNS("sahf",NORM),       TNS("lahf",NORM),
 2222 }, {
 2223 /* [A,0] */     TNS("movb",OA),         TS("mov",OA),           TNS("movb",AO),         TS("mov",AO),
 2224 /* [A,4] */     TNSZ("movsb",SD,1),     TS("movs",SD),          TNSZ("cmpsb",SD,1),     TS("cmps",SD),
 2225 /* [A,8] */     TNS("testb",IA),        TS("test",IA),          TNS("stosb",AD),        TS("stos",AD),
 2226 /* [A,C] */     TNS("lodsb",SA),        TS("lods",SA),          TNS("scasb",AD),        TS("scas",AD),
 2227 }, {
 2228 /* [B,0] */     TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),
 2229 /* [B,4] */     TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),
 2230 /* [B,8] */     TS("mov",IR),           TS("mov",IR),           TS("mov",IR),           TS("mov",IR),
 2231 /* [B,C] */     TS("mov",IR),           TS("mov",IR),           TS("mov",IR),           TS("mov",IR),
 2232 }, {
 2233 /* [C,0] */     IND(dis_opC0),          IND(dis_opC1),          TNSyp("ret",RET),       TNSyp("ret",NORM),
 2234 /* [C,4] */     TNSx("les",MR),         TNSx("lds",MR),         TNS("movb",IMw),        TS("mov",IMw),
 2235 /* [C,8] */     TNSyp("enter",ENTER),   TNSyp("leave",NORM),    TNS("lret",RET),        TNS("lret",NORM),
 2236 /* [C,C] */     TNS("int",INT3),        TNS("int",INTx),        TNSx("into",NORM),      TNS("iret",NORM),
 2237 }, {
 2238 /* [D,0] */     IND(dis_opD0),          IND(dis_opD1),          IND(dis_opD2),          IND(dis_opD3),
 2239 /* [D,4] */     TNSx("aam",U),          TNSx("aad",U),          TNSx("falc",NORM),      TNSZ("xlat",IMPLMEM,1),
 2240 
 2241 /* 287 instructions.  Note that although the indirect field             */
 2242 /* indicates opFP1n2 for further decoding, this is not necessarily      */
 2243 /* the case since the opFP arrays are not partitioned according to key1 */
 2244 /* and key2.  opFP1n2 is given only to indicate that we haven't         */
 2245 /* finished decoding the instruction.                                   */
 2246 /* [D,8] */     IND(dis_opFP1n2),       IND(dis_opFP1n2),       IND(dis_opFP1n2),       IND(dis_opFP1n2),
 2247 /* [D,C] */     IND(dis_opFP1n2),       IND(dis_opFP1n2),       IND(dis_opFP1n2),       IND(dis_opFP1n2),
 2248 }, {
 2249 /* [E,0] */     TNSy("loopnz",BD),      TNSy("loopz",BD),       TNSy("loop",BD),        TNSy("jcxz",BD),
 2250 /* [E,4] */     TNS("inb",P),           TS("in",P),             TNS("outb",P),          TS("out",P),
 2251 /* [E,8] */     TNSyp("call",D),        TNSy("jmp",D),          TNSx("ljmp",SO),                TNSy("jmp",BD),
 2252 /* [E,C] */     TNS("inb",V),           TS("in",V),             TNS("outb",V),          TS("out",V),
 2253 }, {
 2254 /* [F,0] */     TNS("lock",LOCK),       TNS("icebp", NORM),     TNS("repnz",PREFIX),    TNS("repz",PREFIX),
 2255 /* [F,4] */     TNS("hlt",NORM),        TNS("cmc",NORM),        IND(dis_opF6),          IND(dis_opF7),
 2256 /* [F,8] */     TNS("clc",NORM),        TNS("stc",NORM),        TNS("cli",NORM),        TNS("sti",NORM),
 2257 /* [F,C] */     TNS("cld",NORM),        TNS("std",NORM),        IND(dis_opFE),          IND(dis_opFF),
 2258 } };
 2259 
 2260 /* END CSTYLED */
 2261 
 2262 /*
 2263  * common functions to decode and disassemble an x86 or amd64 instruction
 2264  */
 2265 
 2266 /*
 2267  * These are the individual fields of a REX prefix. Note that a REX
 2268  * prefix with none of these set is still needed to:
 2269  *      - use the MOVSXD (sign extend 32 to 64 bits) instruction
 2270  *      - access the %sil, %dil, %bpl, %spl registers
 2271  */
 2272 #define REX_W 0x08      /* 64 bit operand size when set */
 2273 #define REX_R 0x04      /* high order bit extension of ModRM reg field */
 2274 #define REX_X 0x02      /* high order bit extension of SIB index field */
 2275 #define REX_B 0x01      /* extends ModRM r_m, SIB base, or opcode reg */
 2276 
 2277 /*
 2278  * These are the individual fields of a VEX prefix.
 2279  */
 2280 #define VEX_R 0x08      /* REX.R in 1's complement form */
 2281 #define VEX_X 0x04      /* REX.X in 1's complement form */
 2282 #define VEX_B 0x02      /* REX.B in 1's complement form */
 2283 /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
 2284 #define VEX_L 0x04
 2285 #define VEX_W 0x08      /* opcode specific, use like REX.W */
 2286 #define VEX_m 0x1F      /* VEX m-mmmm field */
 2287 #define VEX_v 0x78      /* VEX register specifier */
 2288 #define VEX_p 0x03      /* VEX pp field, opcode extension */
 2289 
 2290 /* VEX m-mmmm field, only used by three bytes prefix */
 2291 #define VEX_m_0F 0x01   /* implied 0F leading opcode byte */
 2292 #define VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
 2293 #define VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
 2294 
 2295 /* VEX pp field, providing equivalent functionality of a SIMD prefix */
 2296 #define VEX_p_66 0x01
 2297 #define VEX_p_F3 0x02
 2298 #define VEX_p_F2 0x03
 2299 
 2300 /*
 2301  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
 2302  */
 2303 static int isize[] = {1, 2, 4, 4};
 2304 static int isize64[] = {1, 2, 4, 8};
 2305 
 2306 /*
 2307  * Just a bunch of useful macros.
 2308  */
 2309 #define WBIT(x) (x & 0x1)               /* to get w bit */
 2310 #define REGNO(x) (x & 0x7)              /* to get 3 bit register */
 2311 #define VBIT(x) ((x)>>1 & 0x1)          /* to get 'v' bit */
 2312 #define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
 2313 #define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
 2314 
 2315 #define REG_ONLY 3      /* mode to indicate a register operand (not memory) */
 2316 
 2317 #define BYTE_OPND       0       /* w-bit value indicating byte register */
 2318 #define LONG_OPND       1       /* w-bit value indicating opnd_size register */
 2319 #define MM_OPND         2       /* "value" used to indicate a mmx reg */
 2320 #define XMM_OPND        3       /* "value" used to indicate a xmm reg */
 2321 #define SEG_OPND        4       /* "value" used to indicate a segment reg */
 2322 #define CONTROL_OPND    5       /* "value" used to indicate a control reg */
 2323 #define DEBUG_OPND      6       /* "value" used to indicate a debug reg */
 2324 #define TEST_OPND       7       /* "value" used to indicate a test reg */
 2325 #define WORD_OPND       8       /* w-bit value indicating word size reg */
 2326 #define YMM_OPND        9       /* "value" used to indicate a ymm reg */
 2327 
 2328 /*
 2329  * The AVX2 gather instructions are a bit of a mess. While there's a pattern,
 2330  * there's not really a consistent scheme that we can use to know what the mode
 2331  * is supposed to be for a given type. Various instructions, like VPGATHERDD,
 2332  * always match the value of VEX_L. Other instructions like VPGATHERDQ, have
 2333  * some registers match VEX_L, but the VSIB is always XMM.
 2334  *
 2335  * The simplest way to deal with this is to just define a table based on the
 2336  * instruction opcodes, which are 0x90-0x93, so we subtract 0x90 to index into
 2337  * them.
 2338  *
 2339  * We further have to subdivide this based on the value of VEX_W and the value
 2340  * of VEX_L. The array is constructed to be indexed as:
 2341  *      [opcode - 0x90][VEX_W][VEX_L].
 2342  */
 2343 /* w = 0, 0x90 */
 2344 typedef struct dis_gather_regs {
 2345         uint_t dgr_arg0;        /* src reg */
 2346         uint_t dgr_arg1;        /* vsib reg */
 2347         uint_t dgr_arg2;        /* dst reg */
 2348         char   *dgr_suffix;     /* suffix to append */
 2349 } dis_gather_regs_t;
 2350 
 2351 static dis_gather_regs_t dis_vgather[4][2][2] = {
 2352         {
 2353                 /* op 0x90, W.0 */
 2354                 {
 2355                         { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
 2356                         { YMM_OPND, YMM_OPND, YMM_OPND, "d" }
 2357                 },
 2358                 /* op 0x90, W.1 */
 2359                 {
 2360                         { XMM_OPND, XMM_OPND, XMM_OPND, "q" },
 2361                         { YMM_OPND, XMM_OPND, YMM_OPND, "q" }
 2362                 }
 2363         },
 2364         {
 2365                 /* op 0x91, W.0 */
 2366                 {
 2367                         { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
 2368                         { XMM_OPND, YMM_OPND, XMM_OPND, "d" },
 2369                 },
 2370                 /* op 0x91, W.1 */
 2371                 {
 2372                         { XMM_OPND, XMM_OPND, XMM_OPND, "q" },
 2373                         { YMM_OPND, YMM_OPND, YMM_OPND, "q" },
 2374                 }
 2375         },
 2376         {
 2377                 /* op 0x92, W.0 */
 2378                 {
 2379                         { XMM_OPND, XMM_OPND, XMM_OPND, "s" },
 2380                         { YMM_OPND, YMM_OPND, YMM_OPND, "s" }
 2381                 },
 2382                 /* op 0x92, W.1 */
 2383                 {
 2384                         { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
 2385                         { YMM_OPND, XMM_OPND, YMM_OPND, "d" }
 2386                 }
 2387         },
 2388         {
 2389                 /* op 0x93, W.0 */
 2390                 {
 2391                         { XMM_OPND, XMM_OPND, XMM_OPND, "s" },
 2392                         { XMM_OPND, YMM_OPND, XMM_OPND, "s" }
 2393                 },
 2394                 /* op 0x93, W.1 */
 2395                 {
 2396                         { XMM_OPND, XMM_OPND, XMM_OPND, "d" },
 2397                         { YMM_OPND, YMM_OPND, YMM_OPND, "d" }
 2398                 }
 2399         }
 2400 };
 2401 
 2402 /*
 2403  * Get the next byte and separate the op code into the high and low nibbles.
 2404  */
 2405 static int
 2406 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
 2407 {
 2408         int byte;
 2409 
 2410         /*
 2411          * x86 instructions have a maximum length of 15 bytes.  Bail out if
 2412          * we try to read more.
 2413          */
 2414         if (x->d86_len >= 15)
 2415                 return (x->d86_error = 1);
 2416 
 2417         if (x->d86_error)
 2418                 return (1);
 2419         byte = x->d86_get_byte(x->d86_data);
 2420         if (byte < 0)
 2421                 return (x->d86_error = 1);
 2422         x->d86_bytes[x->d86_len++] = byte;
 2423         *low = byte & 0xf;              /* ----xxxx low 4 bits */
 2424         *high = byte >> 4 & 0xf;        /* xxxx---- bits 7 to 4 */
 2425         return (0);
 2426 }
 2427 
 2428 /*
 2429  * Get and decode an SIB (scaled index base) byte
 2430  */
 2431 static void
 2432 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
 2433 {
 2434         int byte;
 2435 
 2436         if (x->d86_error)
 2437                 return;
 2438 
 2439         byte = x->d86_get_byte(x->d86_data);
 2440         if (byte < 0) {
 2441                 x->d86_error = 1;
 2442                 return;
 2443         }
 2444         x->d86_bytes[x->d86_len++] = byte;
 2445 
 2446         *base = byte & 0x7;
 2447         *index = (byte >> 3) & 0x7;
 2448         *ss = (byte >> 6) & 0x3;
 2449 }
 2450 
 2451 /*
 2452  * Get the byte following the op code and separate it into the
 2453  * mode, register, and r/m fields.
 2454  */
 2455 static void
 2456 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
 2457 {
 2458         if (x->d86_got_modrm == 0) {
 2459                 if (x->d86_rmindex == -1)
 2460                         x->d86_rmindex = x->d86_len;
 2461                 dtrace_get_SIB(x, mode, reg, r_m);
 2462                 x->d86_got_modrm = 1;
 2463         }
 2464 }
 2465 
 2466 /*
 2467  * Adjust register selection based on any REX prefix bits present.
 2468  */
 2469 /*ARGSUSED*/
 2470 static void
 2471 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
 2472 {
 2473         if (reg != NULL && r_m == NULL) {
 2474                 if (rex_prefix & REX_B)
 2475                         *reg += 8;
 2476         } else {
 2477                 if (reg != NULL && (REX_R & rex_prefix) != 0)
 2478                         *reg += 8;
 2479                 if (r_m != NULL && (REX_B & rex_prefix) != 0)
 2480                         *r_m += 8;
 2481         }
 2482 }
 2483 
 2484 /*
 2485  * Adjust register selection based on any VEX prefix bits present.
 2486  * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
 2487  */
 2488 /*ARGSUSED*/
 2489 static void
 2490 dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
 2491 {
 2492         if (reg != NULL && r_m == NULL) {
 2493                 if (!(vex_byte1 & VEX_B))
 2494                         *reg += 8;
 2495         } else {
 2496                 if (reg != NULL && ((VEX_R & vex_byte1) == 0))
 2497                         *reg += 8;
 2498                 if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
 2499                         *r_m += 8;
 2500         }
 2501 }
 2502 
 2503 /*
 2504  * Get an immediate operand of the given size, with sign extension.
 2505  */
 2506 static void
 2507 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
 2508 {
 2509         int i;
 2510         int byte;
 2511         int valsize;
 2512 
 2513         if (x->d86_numopnds < opindex + 1)
 2514                 x->d86_numopnds = opindex + 1;
 2515 
 2516         switch (wbit) {
 2517         case BYTE_OPND:
 2518                 valsize = 1;
 2519                 break;
 2520         case LONG_OPND:
 2521                 if (x->d86_opnd_size == SIZE16)
 2522                         valsize = 2;
 2523                 else if (x->d86_opnd_size == SIZE32)
 2524                         valsize = 4;
 2525                 else
 2526                         valsize = 8;
 2527                 break;
 2528         case MM_OPND:
 2529         case XMM_OPND:
 2530         case YMM_OPND:
 2531         case SEG_OPND:
 2532         case CONTROL_OPND:
 2533         case DEBUG_OPND:
 2534         case TEST_OPND:
 2535                 valsize = size;
 2536                 break;
 2537         case WORD_OPND:
 2538                 valsize = 2;
 2539                 break;
 2540         }
 2541         if (valsize < size)
 2542                 valsize = size;
 2543 
 2544         if (x->d86_error)
 2545                 return;
 2546         x->d86_opnd[opindex].d86_value = 0;
 2547         for (i = 0; i < size; ++i) {
 2548                 byte = x->d86_get_byte(x->d86_data);
 2549                 if (byte < 0) {
 2550                         x->d86_error = 1;
 2551                         return;
 2552                 }
 2553                 x->d86_bytes[x->d86_len++] = byte;
 2554                 x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
 2555         }
 2556         /* Do sign extension */
 2557         if (x->d86_bytes[x->d86_len - 1] & 0x80) {
 2558                 for (; i < sizeof (uint64_t); i++)
 2559                         x->d86_opnd[opindex].d86_value |=
 2560                             (uint64_t)0xff << (i * 8);
 2561         }
 2562 #ifdef DIS_TEXT
 2563         x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
 2564         x->d86_opnd[opindex].d86_value_size = valsize;
 2565         x->d86_imm_bytes += size;
 2566 #endif
 2567 }
 2568 
 2569 /*
 2570  * Get an ip relative operand of the given size, with sign extension.
 2571  */
 2572 static void
 2573 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
 2574 {
 2575         dtrace_imm_opnd(x, wbit, size, opindex);
 2576 #ifdef DIS_TEXT
 2577         x->d86_opnd[opindex].d86_mode = MODE_IPREL;
 2578 #endif
 2579 }
 2580 
 2581 /*
 2582  * Check to see if there is a segment override prefix pending.
 2583  * If so, print it in the current 'operand' location and set
 2584  * the override flag back to false.
 2585  */
 2586 /*ARGSUSED*/
 2587 static void
 2588 dtrace_check_override(dis86_t *x, int opindex)
 2589 {
 2590 #ifdef DIS_TEXT
 2591         if (x->d86_seg_prefix) {
 2592                 (void) strlcat(x->d86_opnd[opindex].d86_prefix,
 2593                     x->d86_seg_prefix, PFIXLEN);
 2594         }
 2595 #endif
 2596         x->d86_seg_prefix = NULL;
 2597 }
 2598 
 2599 
 2600 /*
 2601  * Process a single instruction Register or Memory operand.
 2602  *
 2603  * mode = addressing mode from ModRM byte
 2604  * r_m = r_m (or reg if mode == 3) field from ModRM byte
 2605  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
 2606  * o = index of operand that we are processing (0, 1 or 2)
 2607  *
 2608  * the value of reg or r_m must have already been adjusted for any REX prefix.
 2609  */
 2610 /*ARGSUSED*/
 2611 static void
 2612 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
 2613 {
 2614         int have_SIB = 0;       /* flag presence of scale-index-byte */
 2615         uint_t ss;              /* scale-factor from opcode */
 2616         uint_t index;           /* index register number */
 2617         uint_t base;            /* base register number */
 2618         int dispsize;           /* size of displacement in bytes */
 2619 #ifdef DIS_TEXT
 2620         char *opnd = x->d86_opnd[opindex].d86_opnd;
 2621 #endif
 2622 
 2623         if (x->d86_numopnds < opindex + 1)
 2624                 x->d86_numopnds = opindex + 1;
 2625 
 2626         if (x->d86_error)
 2627                 return;
 2628 
 2629         /*
 2630          * first handle a simple register
 2631          */
 2632         if (mode == REG_ONLY) {
 2633 #ifdef DIS_TEXT
 2634                 switch (wbit) {
 2635                 case MM_OPND:
 2636                         (void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
 2637                         break;
 2638                 case XMM_OPND:
 2639                         (void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
 2640                         break;
 2641                 case YMM_OPND:
 2642                         (void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
 2643                         break;
 2644                 case SEG_OPND:
 2645                         (void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
 2646                         break;
 2647                 case CONTROL_OPND:
 2648                         (void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
 2649                         break;
 2650                 case DEBUG_OPND:
 2651                         (void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
 2652                         break;
 2653                 case TEST_OPND:
 2654                         (void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
 2655                         break;
 2656                 case BYTE_OPND:
 2657                         if (x->d86_rex_prefix == 0)
 2658                                 (void) strlcat(opnd, dis_REG8[r_m], OPLEN);
 2659                         else
 2660                                 (void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
 2661                         break;
 2662                 case WORD_OPND:
 2663                         (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
 2664                         break;
 2665                 case LONG_OPND:
 2666                         if (x->d86_opnd_size == SIZE16)
 2667                                 (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
 2668                         else if (x->d86_opnd_size == SIZE32)
 2669                                 (void) strlcat(opnd, dis_REG32[r_m], OPLEN);
 2670                         else
 2671                                 (void) strlcat(opnd, dis_REG64[r_m], OPLEN);
 2672                         break;
 2673                 }
 2674 #endif /* DIS_TEXT */
 2675                 return;
 2676         }
 2677 
 2678         /*
 2679          * if symbolic representation, skip override prefix, if any
 2680          */
 2681         dtrace_check_override(x, opindex);
 2682 
 2683         /*
 2684          * Handle 16 bit memory references first, since they decode
 2685          * the mode values more simply.
 2686          * mode 1 is r_m + 8 bit displacement
 2687          * mode 2 is r_m + 16 bit displacement
 2688          * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
 2689          */
 2690         if (x->d86_addr_size == SIZE16) {
 2691                 if ((mode == 0 && r_m == 6) || mode == 2)
 2692                         dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
 2693                 else if (mode == 1)
 2694                         dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
 2695 #ifdef DIS_TEXT
 2696                 if (mode == 0 && r_m == 6)
 2697                         x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
 2698                 else if (mode == 0)
 2699                         x->d86_opnd[opindex].d86_mode = MODE_NONE;
 2700                 else
 2701                         x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
 2702                 (void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
 2703 #endif
 2704                 return;
 2705         }
 2706 
 2707         /*
 2708          * 32 and 64 bit addressing modes are more complex since they
 2709          * can involve an SIB (scaled index and base) byte to decode.
 2710          */
 2711         if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
 2712                 have_SIB = 1;
 2713                 dtrace_get_SIB(x, &ss, &index, &base);
 2714                 if (x->d86_error)
 2715                         return;
 2716                 if (base != 5 || mode != 0)
 2717                         if (x->d86_rex_prefix & REX_B)
 2718                                 base += 8;
 2719                 if (x->d86_rex_prefix & REX_X)
 2720                         index += 8;
 2721         } else {
 2722                 base = r_m;
 2723         }
 2724 
 2725         /*
 2726          * Compute the displacement size and get its bytes
 2727          */
 2728         dispsize = 0;
 2729 
 2730         if (mode == 1)
 2731                 dispsize = 1;
 2732         else if (mode == 2)
 2733                 dispsize = 4;
 2734         else if ((r_m & 7) == EBP_REGNO ||
 2735             (have_SIB && (base & 7) == EBP_REGNO))
 2736                 dispsize = 4;
 2737 
 2738         if (dispsize > 0) {
 2739                 dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
 2740                     dispsize, opindex);
 2741                 if (x->d86_error)
 2742                         return;
 2743         }
 2744 
 2745 #ifdef DIS_TEXT
 2746         if (dispsize > 0)
 2747                 x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
 2748 
 2749         if (have_SIB == 0) {
 2750                 if (x->d86_mode == SIZE32) {
 2751                         if (mode == 0)
 2752                                 (void) strlcat(opnd, dis_addr32_mode0[r_m],
 2753                                     OPLEN);
 2754                         else
 2755                                 (void) strlcat(opnd, dis_addr32_mode12[r_m],
 2756                                     OPLEN);
 2757                 } else {
 2758                         if (mode == 0) {
 2759                                 (void) strlcat(opnd, dis_addr64_mode0[r_m],
 2760                                     OPLEN);
 2761                                 if (r_m == 5) {
 2762                                         x->d86_opnd[opindex].d86_mode =
 2763                                             MODE_RIPREL;
 2764                                 }
 2765                         } else {
 2766                                 (void) strlcat(opnd, dis_addr64_mode12[r_m],
 2767                                     OPLEN);
 2768                         }
 2769                 }
 2770         } else {
 2771                 uint_t need_paren = 0;
 2772                 char **regs;
 2773                 char **bregs;
 2774                 const char *const *sf;
 2775                 if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
 2776                         regs = (char **)dis_REG32;
 2777                 else
 2778                         regs = (char **)dis_REG64;
 2779 
 2780                 if (x->d86_vsib != 0) {
 2781                         if (wbit == YMM_OPND) /* NOTE this is not addr_size! */
 2782                                 bregs = (char **)dis_YMMREG;
 2783                         else
 2784                                 bregs = (char **)dis_XMMREG;
 2785                         sf = dis_vscale_factor;
 2786                 } else {
 2787                         bregs = regs;
 2788                         sf = dis_scale_factor;
 2789                 }
 2790 
 2791                 /*
 2792                  * print the base (if any)
 2793                  */
 2794                 if (base == EBP_REGNO && mode == 0) {
 2795                         if (index != ESP_REGNO || x->d86_vsib != 0) {
 2796                                 (void) strlcat(opnd, "(", OPLEN);
 2797                                 need_paren = 1;
 2798                         }
 2799                 } else {
 2800                         (void) strlcat(opnd, "(", OPLEN);
 2801                         (void) strlcat(opnd, regs[base], OPLEN);
 2802                         need_paren = 1;
 2803                 }
 2804 
 2805                 /*
 2806                  * print the index (if any)
 2807                  */
 2808                 if (index != ESP_REGNO || x->d86_vsib) {
 2809                         (void) strlcat(opnd, ",", OPLEN);
 2810                         (void) strlcat(opnd, bregs[index], OPLEN);
 2811                         (void) strlcat(opnd, sf[ss], OPLEN);
 2812                 } else
 2813                         if (need_paren)
 2814                                 (void) strlcat(opnd, ")", OPLEN);
 2815         }
 2816 #endif
 2817 }
 2818 
 2819 /*
 2820  * Operand sequence for standard instruction involving one register
 2821  * and one register/memory operand.
 2822  * wbit indicates a byte(0) or opnd_size(1) operation
 2823  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
 2824  */
 2825 #define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {    \
 2826                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
 2827                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
 2828                 dtrace_get_operand(x, mode, r_m, wbit, vbit);           \
 2829                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);   \
 2830 }
 2831 
 2832 /*
 2833  * Similar to above, but allows for the two operands to be of different
 2834  * classes (ie. wbit).
 2835  *      wbit is for the r_m operand
 2836  *      w2 is for the reg operand
 2837  */
 2838 #define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) {       \
 2839                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
 2840                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
 2841                 dtrace_get_operand(x, mode, r_m, wbit, vbit);           \
 2842                 dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);     \
 2843 }
 2844 
 2845 /*
 2846  * Similar, but for 2 operands plus an immediate.
 2847  * vbit indicates direction
 2848  *      0 for "opcode imm, r, r_m" or
 2849  *      1 for "opcode imm, r_m, r"
 2850  */
 2851 #define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
 2852                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
 2853                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
 2854                 dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);         \
 2855                 dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);       \
 2856                 dtrace_imm_opnd(x, wbit, immsize, 0);                   \
 2857 }
 2858 
 2859 /*
 2860  * Similar, but for 2 operands plus two immediates.
 2861  */
 2862 #define FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
 2863                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
 2864                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
 2865                 dtrace_get_operand(x, mode, r_m, wbit, 2);              \
 2866                 dtrace_get_operand(x, REG_ONLY, reg, w2, 3);            \
 2867                 dtrace_imm_opnd(x, wbit, immsize, 1);                   \
 2868                 dtrace_imm_opnd(x, wbit, immsize, 0);                   \
 2869 }
 2870 
 2871 /*
 2872  * 1 operands plus two immediates.
 2873  */
 2874 #define ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
 2875                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
 2876                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
 2877                 dtrace_get_operand(x, mode, r_m, wbit, 2);              \
 2878                 dtrace_imm_opnd(x, wbit, immsize, 1);                   \
 2879                 dtrace_imm_opnd(x, wbit, immsize, 0);                   \
 2880 }
 2881 
 2882 /*
 2883  * Dissassemble a single x86 or amd64 instruction.
 2884  *
 2885  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
 2886  * for interpreting instructions.
 2887  *
 2888  * returns non-zero for bad opcode
 2889  */
 2890 int
 2891 dtrace_disx86(dis86_t *x, uint_t cpu_mode)
 2892 {
 2893         instable_t *dp;         /* decode table being used */
 2894 #ifdef DIS_TEXT
 2895         uint_t i;
 2896 #endif
 2897 #ifdef DIS_MEM
 2898         uint_t nomem = 0;
 2899 #define NOMEM   (nomem = 1)
 2900 #else
 2901 #define NOMEM   /* nothing */
 2902 #endif
 2903         uint_t opnd_size;       /* SIZE16, SIZE32 or SIZE64 */
 2904         uint_t addr_size;       /* SIZE16, SIZE32 or SIZE64 */
 2905         uint_t wbit;            /* opcode wbit, 0 is 8 bit, !0 for opnd_size */
 2906         uint_t w2;              /* wbit value for second operand */
 2907         uint_t vbit;
 2908         uint_t mode = 0;        /* mode value from ModRM byte */
 2909         uint_t reg;             /* reg value from ModRM byte */
 2910         uint_t r_m;             /* r_m value from ModRM byte */
 2911 
 2912         uint_t opcode1;         /* high nibble of 1st byte */
 2913         uint_t opcode2;         /* low nibble of 1st byte */
 2914         uint_t opcode3;         /* extra opcode bits usually from ModRM byte */
 2915         uint_t opcode4;         /* high nibble of 2nd byte */
 2916         uint_t opcode5;         /* low nibble of 2nd byte */
 2917         uint_t opcode6;         /* high nibble of 3rd byte */
 2918         uint_t opcode7;         /* low nibble of 3rd byte */
 2919         uint_t opcode_bytes = 1;
 2920 
 2921         /*
 2922          * legacy prefixes come in 5 flavors, you should have only one of each
 2923          */
 2924         uint_t  opnd_size_prefix = 0;
 2925         uint_t  addr_size_prefix = 0;
 2926         uint_t  segment_prefix = 0;
 2927         uint_t  lock_prefix = 0;
 2928         uint_t  rep_prefix = 0;
 2929         uint_t  rex_prefix = 0; /* amd64 register extension prefix */
 2930 
 2931         /*
 2932          * Intel VEX instruction encoding prefix and fields
 2933          */
 2934 
 2935         /* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
 2936         uint_t vex_prefix = 0;
 2937 
 2938         /*
 2939          * VEX prefix byte 1, includes vex.r, vex.x and vex.b
 2940          * (for 3 bytes prefix)
 2941          */
 2942         uint_t vex_byte1 = 0;
 2943 
 2944         /*
 2945          * For 32-bit mode, it should prefetch the next byte to
 2946          * distinguish between AVX and les/lds
 2947          */
 2948         uint_t vex_prefetch = 0;
 2949 
 2950         uint_t vex_m = 0;
 2951         uint_t vex_v = 0;
 2952         uint_t vex_p = 0;
 2953         uint_t vex_R = 1;
 2954         uint_t vex_X = 1;
 2955         uint_t vex_B = 1;
 2956         uint_t vex_W = 0;
 2957         uint_t vex_L;
 2958         dis_gather_regs_t *vreg;
 2959 
 2960 #ifdef  DIS_TEXT
 2961         /* Instruction name for BLS* family of instructions */
 2962         char *blsinstr;
 2963 #endif
 2964 
 2965         size_t  off;
 2966 
 2967         instable_t dp_mmx;
 2968 
 2969         x->d86_len = 0;
 2970         x->d86_rmindex = -1;
 2971         x->d86_error = 0;
 2972 #ifdef DIS_TEXT
 2973         x->d86_numopnds = 0;
 2974         x->d86_seg_prefix = NULL;
 2975         x->d86_mnem[0] = 0;
 2976         for (i = 0; i < 4; ++i) {
 2977                 x->d86_opnd[i].d86_opnd[0] = 0;
 2978                 x->d86_opnd[i].d86_prefix[0] = 0;
 2979                 x->d86_opnd[i].d86_value_size = 0;
 2980                 x->d86_opnd[i].d86_value = 0;
 2981                 x->d86_opnd[i].d86_mode = MODE_NONE;
 2982         }
 2983 #endif
 2984         x->d86_rex_prefix = 0;
 2985         x->d86_got_modrm = 0;
 2986         x->d86_memsize = 0;
 2987         x->d86_vsib = 0;
 2988 
 2989         if (cpu_mode == SIZE16) {
 2990                 opnd_size = SIZE16;
 2991                 addr_size = SIZE16;
 2992         } else if (cpu_mode == SIZE32) {
 2993                 opnd_size = SIZE32;
 2994                 addr_size = SIZE32;
 2995         } else {
 2996                 opnd_size = SIZE32;
 2997                 addr_size = SIZE64;
 2998         }
 2999 
 3000         /*
 3001          * Get one opcode byte and check for zero padding that follows
 3002          * jump tables.
 3003          */
 3004         if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
 3005                 goto error;
 3006 
 3007         if (opcode1 == 0 && opcode2 == 0 &&
 3008             x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
 3009 #ifdef DIS_TEXT
 3010                 (void) strncpy(x->d86_mnem, ".byte\t", OPLEN);
 3011 #endif
 3012                 goto done;
 3013         }
 3014 
 3015         /*
 3016          * Gather up legacy x86 prefix bytes.
 3017          */
 3018         for (;;) {
 3019                 uint_t *which_prefix = NULL;
 3020 
 3021                 dp = (instable_t *)&dis_distable[opcode1][opcode2];
 3022 
 3023                 switch (dp->it_adrmode) {
 3024                 case PREFIX:
 3025                         which_prefix = &rep_prefix;
 3026                         break;
 3027                 case LOCK:
 3028                         which_prefix = &lock_prefix;
 3029                         break;
 3030                 case OVERRIDE:
 3031                         which_prefix = &segment_prefix;
 3032 #ifdef DIS_TEXT
 3033                         x->d86_seg_prefix = (char *)dp->it_name;
 3034 #endif
 3035                         if (dp->it_invalid64 && cpu_mode == SIZE64)
 3036                                 goto error;
 3037                         break;
 3038                 case AM:
 3039                         which_prefix = &addr_size_prefix;
 3040                         break;
 3041                 case DM:
 3042                         which_prefix = &opnd_size_prefix;
 3043                         break;
 3044                 }
 3045                 if (which_prefix == NULL)
 3046                         break;
 3047                 *which_prefix = (opcode1 << 4) | opcode2;
 3048                 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
 3049                         goto error;
 3050         }
 3051 
 3052         /*
 3053          * Handle amd64 mode PREFIX values.
 3054          * Some of the segment prefixes are no-ops. (only FS/GS actually work)
 3055          * We might have a REX prefix (opcodes 0x40-0x4f)
 3056          */
 3057         if (cpu_mode == SIZE64) {
 3058                 if (segment_prefix != 0x64 && segment_prefix != 0x65)
 3059                         segment_prefix = 0;
 3060 
 3061                 if (opcode1 == 0x4) {
 3062                         rex_prefix = (opcode1 << 4) | opcode2;
 3063                         if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
 3064                                 goto error;
 3065                         dp = (instable_t *)&dis_distable[opcode1][opcode2];
 3066                 } else if (opcode1 == 0xC &&
 3067                     (opcode2 == 0x4 || opcode2 == 0x5)) {
 3068                         /* AVX instructions */
 3069                         vex_prefix = (opcode1 << 4) | opcode2;
 3070                         x->d86_rex_prefix = 0x40;
 3071                 }
 3072         } else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
 3073                 /* LDS, LES or AVX */
 3074                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3075                 vex_prefetch = 1;
 3076 
 3077                 if (mode == REG_ONLY) {
 3078                         /* AVX */
 3079                         vex_prefix = (opcode1 << 4) | opcode2;
 3080                         x->d86_rex_prefix = 0x40;
 3081                         opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
 3082                         opcode4 = ((reg << 3) | r_m) & 0x0F;
 3083                 }
 3084         }
 3085 
 3086         if (vex_prefix == VEX_2bytes) {
 3087                 if (!vex_prefetch) {
 3088                         if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
 3089                                 goto error;
 3090                 }
 3091                 vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
 3092                 vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
 3093                 vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
 3094                 vex_p = opcode4 & VEX_p;
 3095                 /*
 3096                  * The vex.x and vex.b bits are not defined in two bytes
 3097                  * mode vex prefix, their default values are 1
 3098                  */
 3099                 vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
 3100 
 3101                 if (vex_R == 0)
 3102                         x->d86_rex_prefix |= REX_R;
 3103 
 3104                 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
 3105                         goto error;
 3106 
 3107                 switch (vex_p) {
 3108                         case VEX_p_66:
 3109                                 dp = (instable_t *)
 3110                                     &dis_opAVX660F[(opcode1 << 4) | opcode2];
 3111                                 break;
 3112                         case VEX_p_F3:
 3113                                 dp = (instable_t *)
 3114                                     &dis_opAVXF30F[(opcode1 << 4) | opcode2];
 3115                                 break;
 3116                         case VEX_p_F2:
 3117                                 dp = (instable_t *)
 3118                                     &dis_opAVXF20F [(opcode1 << 4) | opcode2];
 3119                                 break;
 3120                         default:
 3121                                 dp = (instable_t *)
 3122                                     &dis_opAVX0F[opcode1][opcode2];
 3123 
 3124                 }
 3125 
 3126         } else if (vex_prefix == VEX_3bytes) {
 3127                 if (!vex_prefetch) {
 3128                         if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
 3129                                 goto error;
 3130                 }
 3131                 vex_R = (opcode3 & VEX_R) >> 3;
 3132                 vex_X = (opcode3 & VEX_X) >> 2;
 3133                 vex_B = (opcode3 & VEX_B) >> 1;
 3134                 vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
 3135                 vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
 3136 
 3137                 if (vex_R == 0)
 3138                         x->d86_rex_prefix |= REX_R;
 3139                 if (vex_X == 0)
 3140                         x->d86_rex_prefix |= REX_X;
 3141                 if (vex_B == 0)
 3142                         x->d86_rex_prefix |= REX_B;
 3143 
 3144                 if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
 3145                         goto error;
 3146                 vex_W = (opcode5 & VEX_W) >> 3;
 3147                 vex_L = (opcode6 & VEX_L) >> 2;
 3148                 vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
 3149                 vex_p = opcode6 & VEX_p;
 3150 
 3151                 if (vex_W)
 3152                         x->d86_rex_prefix |= REX_W;
 3153 
 3154                 /* Only these three vex_m values valid; others are reserved */
 3155                 if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
 3156                     (vex_m != VEX_m_0F3A))
 3157                         goto error;
 3158 
 3159                 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
 3160                         goto error;
 3161 
 3162                 switch (vex_p) {
 3163                         case VEX_p_66:
 3164                                 if (vex_m == VEX_m_0F) {
 3165                                         dp = (instable_t *)
 3166                                             &dis_opAVX660F
 3167                                             [(opcode1 << 4) | opcode2];
 3168                                 } else if (vex_m == VEX_m_0F38) {
 3169                                         dp = (instable_t *)
 3170                                             &dis_opAVX660F38
 3171                                             [(opcode1 << 4) | opcode2];
 3172                                 } else if (vex_m == VEX_m_0F3A) {
 3173                                         dp = (instable_t *)
 3174                                             &dis_opAVX660F3A
 3175                                             [(opcode1 << 4) | opcode2];
 3176                                 } else {
 3177                                         goto error;
 3178                                 }
 3179                                 break;
 3180                         case VEX_p_F3:
 3181                                 if (vex_m == VEX_m_0F) {
 3182                                         dp = (instable_t *)
 3183                                             &dis_opAVXF30F
 3184                                             [(opcode1 << 4) | opcode2];
 3185                                 } else if (vex_m == VEX_m_0F38) {
 3186                                         dp = (instable_t *)
 3187                                             &dis_opAVXF30F38
 3188                                             [(opcode1 << 4) | opcode2];
 3189                                 } else {
 3190                                         goto error;
 3191                                 }
 3192                                 break;
 3193                         case VEX_p_F2:
 3194                                 if (vex_m == VEX_m_0F) {
 3195                                         dp = (instable_t *)
 3196                                             &dis_opAVXF20F
 3197                                             [(opcode1 << 4) | opcode2];
 3198                                 } else if (vex_m == VEX_m_0F3A) {
 3199                                         dp = (instable_t *)
 3200                                             &dis_opAVXF20F3A
 3201                                             [(opcode1 << 4) | opcode2];
 3202                                 } else if (vex_m == VEX_m_0F38) {
 3203                                         dp = (instable_t *)
 3204                                             &dis_opAVXF20F38
 3205                                             [(opcode1 << 4) | opcode2];
 3206                                 } else {
 3207                                         goto error;
 3208                                 }
 3209                                 break;
 3210                         default:
 3211                                 dp = (instable_t *)
 3212                                     &dis_opAVX0F[opcode1][opcode2];
 3213 
 3214                 }
 3215         }
 3216         if (vex_prefix) {
 3217                 if (dp->it_vexwoxmm) {
 3218                         wbit = LONG_OPND;
 3219                 } else {
 3220                         if (vex_L)
 3221                                 wbit = YMM_OPND;
 3222                         else
 3223                                 wbit = XMM_OPND;
 3224                 }
 3225         }
 3226 
 3227         /*
 3228          * Deal with selection of operand and address size now.
 3229          * Note that the REX.W bit being set causes opnd_size_prefix to be
 3230          * ignored.
 3231          */
 3232         if (cpu_mode == SIZE64) {
 3233                 if ((rex_prefix & REX_W) || vex_W)
 3234                         opnd_size = SIZE64;
 3235                 else if (opnd_size_prefix)
 3236                         opnd_size = SIZE16;
 3237 
 3238                 if (addr_size_prefix)
 3239                         addr_size = SIZE32;
 3240         } else if (cpu_mode == SIZE32) {
 3241                 if (opnd_size_prefix)
 3242                         opnd_size = SIZE16;
 3243                 if (addr_size_prefix)
 3244                         addr_size = SIZE16;
 3245         } else {
 3246                 if (opnd_size_prefix)
 3247                         opnd_size = SIZE32;
 3248                 if (addr_size_prefix)
 3249                         addr_size = SIZE32;
 3250         }
 3251         /*
 3252          * The pause instruction - a repz'd nop.  This doesn't fit
 3253          * with any of the other prefix goop added for SSE, so we'll
 3254          * special-case it here.
 3255          */
 3256         if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
 3257                 rep_prefix = 0;
 3258                 dp = (instable_t *)&dis_opPause;
 3259         }
 3260 
 3261         /*
 3262          * Some 386 instructions have 2 bytes of opcode before the mod_r/m
 3263          * byte so we may need to perform a table indirection.
 3264          */
 3265         if (dp->it_indirect == (instable_t *)dis_op0F) {
 3266                 if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
 3267                         goto error;
 3268                 opcode_bytes = 2;
 3269                 if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
 3270                         uint_t  subcode;
 3271 
 3272                         if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
 3273                                 goto error;
 3274                         opcode_bytes = 3;
 3275                         subcode = ((opcode6 & 0x3) << 1) |
 3276                             ((opcode7 & 0x8) >> 3);
 3277                         dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
 3278                 } else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
 3279                         dp = (instable_t *)&dis_op0FC8[0];
 3280                 } else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
 3281                         opcode_bytes = 3;
 3282                         if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
 3283                                 goto error;
 3284                         if (opnd_size == SIZE16)
 3285                                 opnd_size = SIZE32;
 3286 
 3287                         dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
 3288 #ifdef DIS_TEXT
 3289                         if (strcmp(dp->it_name, "INVALID") == 0)
 3290                                 goto error;
 3291 #endif
 3292                         switch (dp->it_adrmode) {
 3293                                 case XMMP:
 3294                                         break;
 3295                                 case XMMP_66r:
 3296                                 case XMMPRM_66r:
 3297                                 case XMM3PM_66r:
 3298                                         if (opnd_size_prefix == 0) {
 3299                                                 goto error;
 3300                                         }
 3301                                         break;
 3302                                 case XMMP_66o:
 3303                                         if (opnd_size_prefix == 0) {
 3304                                                 /* SSSE3 MMX instructions */
 3305                                                 dp_mmx = *dp;
 3306                                                 dp = &dp_mmx;
 3307                                                 dp->it_adrmode = MMOPM_66o;
 3308 #ifdef  DIS_MEM
 3309                                                 dp->it_size = 8;
 3310 #endif
 3311                                         }
 3312                                         break;
 3313                                 default:
 3314                                         goto error;
 3315                         }
 3316                 } else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
 3317                         opcode_bytes = 3;
 3318                         if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
 3319                                 goto error;
 3320                         dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
 3321 
 3322                         /*
 3323                          * Both crc32 and movbe have the same 3rd opcode
 3324                          * byte of either 0xF0 or 0xF1, so we use another
 3325                          * indirection to distinguish between the two.
 3326                          */
 3327                         if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
 3328                             dp->it_indirect == (instable_t *)dis_op0F38F1) {
 3329 
 3330                                 dp = dp->it_indirect;
 3331                                 if (rep_prefix != 0xF2) {
 3332                                         /* It is movbe */
 3333                                         dp++;
 3334                                 }
 3335                         }
 3336 
 3337                         /*
 3338                          * The adx family of instructions (adcx and adox)
 3339                          * continue the classic Intel tradition of abusing
 3340                          * arbitrary prefixes without actually meaning the
 3341                          * prefix bit. Therefore, if we find either the
 3342                          * opnd_size_prefix or rep_prefix we end up zeroing it
 3343                          * out after making our determination so as to ensure
 3344                          * that we don't get confused and accidentally print
 3345                          * repz prefixes and the like on these instructions.
 3346                          *
 3347                          * In addition, these instructions are actually much
 3348                          * closer to AVX instructions in semantics. Importantly,
 3349                          * they always default to having 32-bit operands.
 3350                          * However, if the CPU is in 64-bit mode, then and only
 3351                          * then, does it use REX.w promotes things to 64-bits
 3352                          * and REX.r allows 64-bit mode to use register r8-r15.
 3353                          */
 3354                         if (dp->it_indirect == (instable_t *)dis_op0F38F6) {
 3355                                 dp = dp->it_indirect;
 3356                                 if (opnd_size_prefix == 0 &&
 3357                                     rep_prefix == 0xf3) {
 3358                                         /* It is adox */
 3359                                         dp++;
 3360                                 } else if (opnd_size_prefix != 0x66 &&
 3361                                     rep_prefix != 0) {
 3362                                         /* It isn't adcx */
 3363                                         goto error;
 3364                                 }
 3365                                 opnd_size_prefix = 0;
 3366                                 rep_prefix = 0;
 3367                                 opnd_size = SIZE32;
 3368                                 if (rex_prefix & REX_W)
 3369                                         opnd_size = SIZE64;
 3370                         }
 3371 
 3372 #ifdef DIS_TEXT
 3373                         if (strcmp(dp->it_name, "INVALID") == 0)
 3374                                 goto error;
 3375 #endif
 3376                         switch (dp->it_adrmode) {
 3377                                 case ADX:
 3378                                 case XMM:
 3379                                         break;
 3380                                 case RM_66r:
 3381                                 case XMM_66r:
 3382                                 case XMMM_66r:
 3383                                         if (opnd_size_prefix == 0) {
 3384                                                 goto error;
 3385                                         }
 3386                                         break;
 3387                                 case XMM_66o:
 3388                                         if (opnd_size_prefix == 0) {
 3389                                                 /* SSSE3 MMX instructions */
 3390                                                 dp_mmx = *dp;
 3391                                                 dp = &dp_mmx;
 3392                                                 dp->it_adrmode = MM;
 3393 #ifdef  DIS_MEM
 3394                                                 dp->it_size = 8;
 3395 #endif
 3396                                         }
 3397                                         break;
 3398                                 case CRC32:
 3399                                         if (rep_prefix != 0xF2) {
 3400                                                 goto error;
 3401                                         }
 3402                                         rep_prefix = 0;
 3403                                         break;
 3404                                 case MOVBE:
 3405                                         if (rep_prefix != 0x0) {
 3406                                                 goto error;
 3407                                         }
 3408                                         break;
 3409                                 default:
 3410                                         goto error;
 3411                         }
 3412                 } else {
 3413                         dp = (instable_t *)&dis_op0F[opcode4][opcode5];
 3414                 }
 3415         }
 3416 
 3417         /*
 3418          * If still not at a TERM decode entry, then a ModRM byte
 3419          * exists and its fields further decode the instruction.
 3420          */
 3421         x->d86_got_modrm = 0;
 3422         if (dp->it_indirect != TERM) {
 3423                 dtrace_get_modrm(x, &mode, &opcode3, &r_m);
 3424                 if (x->d86_error)
 3425                         goto error;
 3426                 reg = opcode3;
 3427 
 3428                 /*
 3429                  * decode 287 instructions (D8-DF) from opcodeN
 3430                  */
 3431                 if (opcode1 == 0xD && opcode2 >= 0x8) {
 3432                         if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
 3433                                 dp = (instable_t *)&dis_opFP5[r_m];
 3434                         else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
 3435                                 dp = (instable_t *)&dis_opFP7[opcode3];
 3436                         else if (opcode2 == 0xB && mode == 0x3)
 3437                                 dp = (instable_t *)&dis_opFP6[opcode3];
 3438                         else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
 3439                                 dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
 3440                         else if (mode == 0x3)
 3441                                 dp = (instable_t *)
 3442                                     &dis_opFP3[opcode2 - 8][opcode3];
 3443                         else
 3444                                 dp = (instable_t *)
 3445                                     &dis_opFP1n2[opcode2 - 8][opcode3];
 3446                 } else {
 3447                         dp = (instable_t *)dp->it_indirect + opcode3;
 3448                 }
 3449         }
 3450 
 3451         /*
 3452          * In amd64 bit mode, ARPL opcode is changed to MOVSXD
 3453          * (sign extend 32bit to 64 bit)
 3454          */
 3455         if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
 3456             opcode1 == 0x6 && opcode2 == 0x3)
 3457                 dp = (instable_t *)&dis_opMOVSLD;
 3458 
 3459         /*
 3460          * at this point we should have a correct (or invalid) opcode
 3461          */
 3462         if (cpu_mode == SIZE64 && dp->it_invalid64 ||
 3463             cpu_mode != SIZE64 && dp->it_invalid32)
 3464                 goto error;
 3465         if (dp->it_indirect != TERM)
 3466                 goto error;
 3467 
 3468         /*
 3469          * Deal with MMX/SSE opcodes which are changed by prefixes. Note, we do
 3470          * need to include UNKNOWN below, as we may have instructions that
 3471          * actually have a prefix, but don't exist in any other form.
 3472          */
 3473         switch (dp->it_adrmode) {
 3474         case UNKNOWN:
 3475         case MMO:
 3476         case MMOIMPL:
 3477         case MMO3P:
 3478         case MMOM3:
 3479         case MMOMS:
 3480         case MMOPM:
 3481         case MMOPRM:
 3482         case MMOS:
 3483         case XMMO:
 3484         case XMMOM:
 3485         case XMMOMS:
 3486         case XMMOPM:
 3487         case XMMOS:
 3488         case XMMOMX:
 3489         case XMMOX3:
 3490         case XMMOXMM:
 3491                 /*
 3492                  * This is horrible.  Some SIMD instructions take the
 3493                  * form 0x0F 0x?? ..., which is easily decoded using the
 3494                  * existing tables.  Other SIMD instructions use various
 3495                  * prefix bytes to overload existing instructions.  For
 3496                  * Example, addps is F0, 58, whereas addss is F3 (repz),
 3497                  * F0, 58.  Presumably someone got a raise for this.
 3498                  *
 3499                  * If we see one of the instructions which can be
 3500                  * modified in this way (if we've got one of the SIMDO*
 3501                  * address modes), we'll check to see if the last prefix
 3502                  * was a repz.  If it was, we strip the prefix from the
 3503                  * mnemonic, and we indirect using the dis_opSIMDrepz
 3504                  * table.
 3505                  */
 3506 
 3507                 /*
 3508                  * Calculate our offset in dis_op0F
 3509                  */
 3510                 if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
 3511                         goto error;
 3512 
 3513                 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
 3514                     sizeof (instable_t);
 3515 
 3516                 /*
 3517                  * Rewrite if this instruction used one of the magic prefixes.
 3518                  */
 3519                 if (rep_prefix) {
 3520                         if (rep_prefix == 0xf2)
 3521                                 dp = (instable_t *)&dis_opSIMDrepnz[off];
 3522                         else
 3523                                 dp = (instable_t *)&dis_opSIMDrepz[off];
 3524                         rep_prefix = 0;
 3525                 } else if (opnd_size_prefix) {
 3526                         dp = (instable_t *)&dis_opSIMDdata16[off];
 3527                         opnd_size_prefix = 0;
 3528                         if (opnd_size == SIZE16)
 3529                                 opnd_size = SIZE32;
 3530                 }
 3531                 break;
 3532 
 3533         case MG9:
 3534                 /*
 3535                  * More horribleness: the group 9 (0xF0 0xC7) instructions are
 3536                  * allowed an optional prefix of 0x66 or 0xF3.  This is similar
 3537                  * to the SIMD business described above, but with a different
 3538                  * addressing mode (and an indirect table), so we deal with it
 3539                  * separately (if similarly).
 3540                  *
 3541                  * Intel further complicated this with the release of Ivy Bridge
 3542                  * where they overloaded these instructions based on the ModR/M
 3543                  * bytes. The VMX instructions have a mode of 0 since they are
 3544                  * memory instructions but rdrand instructions have a mode of
 3545                  * 0b11 (REG_ONLY) because they only operate on registers. While
 3546                  * there are different prefix formats, for now it is sufficient
 3547                  * to use a single different table.
 3548                  */
 3549 
 3550                 /*
 3551                  * Calculate our offset in dis_op0FC7 (the group 9 table)
 3552                  */
 3553                 if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
 3554                         goto error;
 3555 
 3556                 off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
 3557                     sizeof (instable_t);
 3558 
 3559                 /*
 3560                  * If we have a mode of 0b11 then we have to rewrite this.
 3561                  */
 3562                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3563                 if (mode == REG_ONLY) {
 3564                         dp = (instable_t *)&dis_op0FC7m3[off];
 3565                         break;
 3566                 }
 3567 
 3568                 /*
 3569                  * Rewrite if this instruction used one of the magic prefixes.
 3570                  */
 3571                 if (rep_prefix) {
 3572                         if (rep_prefix == 0xf3)
 3573                                 dp = (instable_t *)&dis_opF30FC7[off];
 3574                         else
 3575                                 goto error;
 3576                         rep_prefix = 0;
 3577                 } else if (opnd_size_prefix) {
 3578                         dp = (instable_t *)&dis_op660FC7[off];
 3579                         opnd_size_prefix = 0;
 3580                         if (opnd_size == SIZE16)
 3581                                 opnd_size = SIZE32;
 3582                 }
 3583                 break;
 3584 
 3585 
 3586         case MMOSH:
 3587                 /*
 3588                  * As with the "normal" SIMD instructions, the MMX
 3589                  * shuffle instructions are overloaded.  These
 3590                  * instructions, however, are special in that they use
 3591                  * an extra byte, and thus an extra table.  As of this
 3592                  * writing, they only use the opnd_size prefix.
 3593                  */
 3594 
 3595                 /*
 3596                  * Calculate our offset in dis_op0F7123
 3597                  */
 3598                 if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
 3599                     sizeof (dis_op0F7123))
 3600                         goto error;
 3601 
 3602                 if (opnd_size_prefix) {
 3603                         off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
 3604                             sizeof (instable_t);
 3605                         dp = (instable_t *)&dis_opSIMD7123[off];
 3606                         opnd_size_prefix = 0;
 3607                         if (opnd_size == SIZE16)
 3608                                 opnd_size = SIZE32;
 3609                 }
 3610                 break;
 3611         case MRw:
 3612                 if (rep_prefix) {
 3613                         if (rep_prefix == 0xf3) {
 3614 
 3615                                 /*
 3616                                  * Calculate our offset in dis_op0F
 3617                                  */
 3618                                 if ((uintptr_t)dp - (uintptr_t)dis_op0F
 3619                                     > sizeof (dis_op0F))
 3620                                         goto error;
 3621 
 3622                                 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
 3623                                     sizeof (instable_t);
 3624 
 3625                                 dp = (instable_t *)&dis_opSIMDrepz[off];
 3626                                 rep_prefix = 0;
 3627                         } else {
 3628                                 goto error;
 3629                         }
 3630                 }
 3631                 break;
 3632         }
 3633 
 3634         /*
 3635          * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
 3636          */
 3637         if (cpu_mode == SIZE64)
 3638                 if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
 3639                         opnd_size = SIZE64;
 3640 
 3641 #ifdef DIS_TEXT
 3642         /*
 3643          * At this point most instructions can format the opcode mnemonic
 3644          * including the prefixes.
 3645          */
 3646         if (lock_prefix)
 3647                 (void) strlcat(x->d86_mnem, "lock ", OPLEN);
 3648 
 3649         if (rep_prefix == 0xf2)
 3650                 (void) strlcat(x->d86_mnem, "repnz ", OPLEN);
 3651         else if (rep_prefix == 0xf3)
 3652                 (void) strlcat(x->d86_mnem, "repz ", OPLEN);
 3653 
 3654         if (cpu_mode == SIZE64 && addr_size_prefix)
 3655                 (void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
 3656 
 3657         if (dp->it_adrmode != CBW &&
 3658             dp->it_adrmode != CWD &&
 3659             dp->it_adrmode != XMMSFNC) {
 3660                 if (strcmp(dp->it_name, "INVALID") == 0)
 3661                         goto error;
 3662                 (void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
 3663                 if (dp->it_avxsuf && dp->it_suffix) {
 3664                         (void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",
 3665                             OPLEN);
 3666                 } else if (dp->it_suffix) {
 3667                         char *types[] = {"", "w", "l", "q"};
 3668                         if (opcode_bytes == 2 && opcode4 == 4) {
 3669                                 /* It's a cmovx.yy. Replace the suffix x */
 3670                                 for (i = 5; i < OPLEN; i++) {
 3671                                         if (x->d86_mnem[i] == '.')
 3672                                                 break;
 3673                                 }
 3674                                 x->d86_mnem[i - 1] = *types[opnd_size];
 3675                         } else if ((opnd_size == 2) && (opcode_bytes == 3) &&
 3676                             ((opcode6 == 1 && opcode7 == 6) ||
 3677                             (opcode6 == 2 && opcode7 == 2))) {
 3678                                 /*
 3679                                  * To handle PINSRD and PEXTRD
 3680                                  */
 3681                                 (void) strlcat(x->d86_mnem, "d", OPLEN);
 3682                         } else {
 3683                                 (void) strlcat(x->d86_mnem, types[opnd_size],
 3684                                     OPLEN);
 3685                         }
 3686                 }
 3687         }
 3688 #endif
 3689 
 3690         /*
 3691          * Process operands based on the addressing modes.
 3692          */
 3693         x->d86_mode = cpu_mode;
 3694         /*
 3695          * In vex mode the rex_prefix has no meaning
 3696          */
 3697         if (!vex_prefix)
 3698                 x->d86_rex_prefix = rex_prefix;
 3699         x->d86_opnd_size = opnd_size;
 3700         x->d86_addr_size = addr_size;
 3701         vbit = 0;               /* initialize for mem/reg -> reg */
 3702         switch (dp->it_adrmode) {
 3703                 /*
 3704                  * amd64 instruction to sign extend 32 bit reg/mem operands
 3705                  * into 64 bit register values
 3706                  */
 3707         case MOVSXZ:
 3708 #ifdef DIS_TEXT
 3709                 if (rex_prefix == 0)
 3710                         (void) strncpy(x->d86_mnem, "movzld", OPLEN);
 3711 #endif
 3712                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3713                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 3714                 x->d86_opnd_size = SIZE64;
 3715                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 3716                 x->d86_opnd_size = opnd_size = SIZE32;
 3717                 wbit = LONG_OPND;
 3718                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 3719                 break;
 3720 
 3721                 /*
 3722                  * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
 3723                  * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
 3724                  * wbit lives in 2nd byte, note that operands
 3725                  * are different sized
 3726                  */
 3727         case MOVZ:
 3728                 if (rex_prefix & REX_W) {
 3729                         /* target register size = 64 bit */
 3730                         x->d86_mnem[5] = 'q';
 3731                 }
 3732                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3733                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 3734                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 3735                 x->d86_opnd_size = opnd_size = SIZE16;
 3736                 wbit = WBIT(opcode5);
 3737                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 3738                 break;
 3739         case CRC32:
 3740                 opnd_size = SIZE32;
 3741                 if (rex_prefix & REX_W)
 3742                         opnd_size = SIZE64;
 3743                 x->d86_opnd_size = opnd_size;
 3744 
 3745                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3746                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 3747                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 3748                 wbit = WBIT(opcode7);
 3749                 if (opnd_size_prefix)
 3750                         x->d86_opnd_size = opnd_size = SIZE16;
 3751                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 3752                 break;
 3753         case MOVBE:
 3754                 opnd_size = SIZE32;
 3755                 if (rex_prefix & REX_W)
 3756                         opnd_size = SIZE64;
 3757                 x->d86_opnd_size = opnd_size;
 3758 
 3759                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3760                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 3761                 wbit = WBIT(opcode7);
 3762                 if (opnd_size_prefix)
 3763                         x->d86_opnd_size = opnd_size = SIZE16;
 3764                 if (wbit) {
 3765                         /* reg -> mem */
 3766                         dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
 3767                         dtrace_get_operand(x, mode, r_m, wbit, 1);
 3768                 } else {
 3769                         /* mem -> reg */
 3770                         dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 3771                         dtrace_get_operand(x, mode, r_m, wbit, 0);
 3772                 }
 3773                 break;
 3774 
 3775         /*
 3776          * imul instruction, with either 8-bit or longer immediate
 3777          * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
 3778          */
 3779         case IMUL:
 3780                 wbit = LONG_OPND;
 3781                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
 3782                     OPSIZE(opnd_size, opcode2 == 0x9), 1);
 3783                 break;
 3784 
 3785         /* memory or register operand to register, with 'w' bit */
 3786         case MRw:
 3787         case ADX:
 3788                 wbit = WBIT(opcode2);
 3789                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
 3790                 break;
 3791 
 3792         /* register to memory or register operand, with 'w' bit */
 3793         /* arpl happens to fit here also because it is odd */
 3794         case RMw:
 3795                 if (opcode_bytes == 2)
 3796                         wbit = WBIT(opcode5);
 3797                 else
 3798                         wbit = WBIT(opcode2);
 3799                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
 3800                 break;
 3801 
 3802         /* xaddb instruction */
 3803         case XADDB:
 3804                 wbit = 0;
 3805                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
 3806                 break;
 3807 
 3808         /* MMX register to memory or register operand           */
 3809         case MMS:
 3810         case MMOS:
 3811 #ifdef DIS_TEXT
 3812                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
 3813 #else
 3814                 wbit = LONG_OPND;
 3815 #endif
 3816                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
 3817                 break;
 3818 
 3819         /* MMX register to memory */
 3820         case MMOMS:
 3821                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3822                 if (mode == REG_ONLY)
 3823                         goto error;
 3824                 wbit = MM_OPND;
 3825                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
 3826                 break;
 3827 
 3828         /* Double shift. Has immediate operand specifying the shift. */
 3829         case DSHIFT:
 3830                 wbit = LONG_OPND;
 3831                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3832                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 3833                 dtrace_get_operand(x, mode, r_m, wbit, 2);
 3834                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 3835                 dtrace_imm_opnd(x, wbit, 1, 0);
 3836                 break;
 3837 
 3838         /*
 3839          * Double shift. With no immediate operand, specifies using %cl.
 3840          */
 3841         case DSHIFTcl:
 3842                 wbit = LONG_OPND;
 3843                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
 3844                 break;
 3845 
 3846         /* immediate to memory or register operand */
 3847         case IMlw:
 3848                 wbit = WBIT(opcode2);
 3849                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3850                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 3851                 /*
 3852                  * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
 3853                  */
 3854                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
 3855                 break;
 3856 
 3857         /* immediate to memory or register operand with the     */
 3858         /* 'w' bit present                                      */
 3859         case IMw:
 3860                 wbit = WBIT(opcode2);
 3861                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3862                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3863                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 3864                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
 3865                 break;
 3866 
 3867         /* immediate to register with register in low 3 bits    */
 3868         /* of op code                                           */
 3869         case IR:
 3870                 /* w-bit here (with regs) is bit 3 */
 3871                 wbit = opcode2 >>3 & 0x1;
 3872                 reg = REGNO(opcode2);
 3873                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
 3874                 mode = REG_ONLY;
 3875                 r_m = reg;
 3876                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 3877                 dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
 3878                 break;
 3879 
 3880         /* MMX immediate shift of register */
 3881         case MMSH:
 3882         case MMOSH:
 3883                 wbit = MM_OPND;
 3884                 goto mm_shift;  /* in next case */
 3885 
 3886         /* SIMD immediate shift of register */
 3887         case XMMSH:
 3888                 wbit = XMM_OPND;
 3889 mm_shift:
 3890                 reg = REGNO(opcode7);
 3891                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
 3892                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 3893                 dtrace_imm_opnd(x, wbit, 1, 0);
 3894                 NOMEM;
 3895                 break;
 3896 
 3897         /* accumulator to memory operand */
 3898         case AO:
 3899                 vbit = 1;
 3900                 /*FALLTHROUGH*/
 3901 
 3902         /* memory operand to accumulator */
 3903         case OA:
 3904                 wbit = WBIT(opcode2);
 3905                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
 3906                 dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
 3907 #ifdef DIS_TEXT
 3908                 x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
 3909 #endif
 3910                 break;
 3911 
 3912 
 3913         /* segment register to memory or register operand */
 3914         case SM:
 3915                 vbit = 1;
 3916                 /*FALLTHROUGH*/
 3917 
 3918         /* memory or register operand to segment register */
 3919         case MS:
 3920                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3921                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3922                 dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
 3923                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
 3924                 break;
 3925 
 3926         /*
 3927          * rotate or shift instructions, which may shift by 1 or
 3928          * consult the cl register, depending on the 'v' bit
 3929          */
 3930         case Mv:
 3931                 vbit = VBIT(opcode2);
 3932                 wbit = WBIT(opcode2);
 3933                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3934                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 3935 #ifdef DIS_TEXT
 3936                 if (vbit) {
 3937                         (void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
 3938                 } else {
 3939                         x->d86_opnd[0].d86_mode = MODE_SIGNED;
 3940                         x->d86_opnd[0].d86_value_size = 1;
 3941                         x->d86_opnd[0].d86_value = 1;
 3942                 }
 3943 #endif
 3944                 break;
 3945         /*
 3946          * immediate rotate or shift instructions
 3947          */
 3948         case MvI:
 3949                 wbit = WBIT(opcode2);
 3950 normal_imm_mem:
 3951                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3952                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 3953                 dtrace_imm_opnd(x, wbit, 1, 0);
 3954                 break;
 3955 
 3956         /* bit test instructions */
 3957         case MIb:
 3958                 wbit = LONG_OPND;
 3959                 goto normal_imm_mem;
 3960 
 3961         /* single memory or register operand with 'w' bit present */
 3962         case Mw:
 3963                 wbit = WBIT(opcode2);
 3964 just_mem:
 3965                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 3966                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 3967                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 3968                 break;
 3969 
 3970         case SWAPGS_RDTSCP:
 3971                 if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
 3972 #ifdef DIS_TEXT
 3973                         (void) strncpy(x->d86_mnem, "swapgs", OPLEN);
 3974 #endif
 3975                         NOMEM;
 3976                         break;
 3977                 } else if (mode == 3 && r_m == 1) {
 3978 #ifdef DIS_TEXT
 3979                         (void) strncpy(x->d86_mnem, "rdtscp", OPLEN);
 3980 #endif
 3981                         NOMEM;
 3982                         break;
 3983                 }
 3984 
 3985                 /*FALLTHROUGH*/
 3986 
 3987         /* prefetch instruction - memory operand, but no memory acess */
 3988         case PREF:
 3989                 NOMEM;
 3990                 /*FALLTHROUGH*/
 3991 
 3992         /* single memory or register operand */
 3993         case M:
 3994         case MG9:
 3995                 wbit = LONG_OPND;
 3996                 goto just_mem;
 3997 
 3998         /* single memory or register byte operand */
 3999         case Mb:
 4000                 wbit = BYTE_OPND;
 4001                 goto just_mem;
 4002 
 4003         case VMx:
 4004                 if (mode == 3) {
 4005 #ifdef DIS_TEXT
 4006                         char *vminstr;
 4007 
 4008                         switch (r_m) {
 4009                         case 1:
 4010                                 vminstr = "vmcall";
 4011                                 break;
 4012                         case 2:
 4013                                 vminstr = "vmlaunch";
 4014                                 break;
 4015                         case 3:
 4016                                 vminstr = "vmresume";
 4017                                 break;
 4018                         case 4:
 4019                                 vminstr = "vmxoff";
 4020                                 break;
 4021                         default:
 4022                                 goto error;
 4023                         }
 4024 
 4025                         (void) strncpy(x->d86_mnem, vminstr, OPLEN);
 4026 #else
 4027                         if (r_m < 1 || r_m > 4)
 4028                                 goto error;
 4029 #endif
 4030 
 4031                         NOMEM;
 4032                         break;
 4033                 }
 4034                 /*FALLTHROUGH*/
 4035         case SVM:
 4036                 if (mode == 3) {
 4037 #ifdef DIS_TEXT
 4038                         char *vinstr;
 4039 
 4040                         switch (r_m) {
 4041                         case 0:
 4042                                 vinstr = "vmrun";
 4043                                 break;
 4044                         case 1:
 4045                                 vinstr = "vmmcall";
 4046                                 break;
 4047                         case 2:
 4048                                 vinstr = "vmload";
 4049                                 break;
 4050                         case 3:
 4051                                 vinstr = "vmsave";
 4052                                 break;
 4053                         case 4:
 4054                                 vinstr = "stgi";
 4055                                 break;
 4056                         case 5:
 4057                                 vinstr = "clgi";
 4058                                 break;
 4059                         case 6:
 4060                                 vinstr = "skinit";
 4061                                 break;
 4062                         case 7:
 4063                                 vinstr = "invlpga";
 4064                                 break;
 4065                         }
 4066 
 4067                         (void) strncpy(x->d86_mnem, vinstr, OPLEN);
 4068 #endif
 4069                         NOMEM;
 4070                         break;
 4071                 }
 4072                 /*FALLTHROUGH*/
 4073         case MONITOR_MWAIT:
 4074                 if (mode == 3) {
 4075                         if (r_m == 0) {
 4076 #ifdef DIS_TEXT
 4077                                 (void) strncpy(x->d86_mnem, "monitor", OPLEN);
 4078 #endif
 4079                                 NOMEM;
 4080                                 break;
 4081                         } else if (r_m == 1) {
 4082 #ifdef DIS_TEXT
 4083                                 (void) strncpy(x->d86_mnem, "mwait", OPLEN);
 4084 #endif
 4085                                 NOMEM;
 4086                                 break;
 4087                         } else if (r_m == 2) {
 4088 #ifdef DIS_TEXT
 4089                                 (void) strncpy(x->d86_mnem, "clac", OPLEN);
 4090 #endif
 4091                                 NOMEM;
 4092                                 break;
 4093                         } else if (r_m == 3) {
 4094 #ifdef DIS_TEXT
 4095                                 (void) strncpy(x->d86_mnem, "stac", OPLEN);
 4096 #endif
 4097                                 NOMEM;
 4098                                 break;
 4099                         } else {
 4100                                 goto error;
 4101                         }
 4102                 }
 4103                 /*FALLTHROUGH*/
 4104         case XGETBV_XSETBV:
 4105                 if (mode == 3) {
 4106                         if (r_m == 0) {
 4107 #ifdef DIS_TEXT
 4108                                 (void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
 4109 #endif
 4110                                 NOMEM;
 4111                                 break;
 4112                         } else if (r_m == 1) {
 4113 #ifdef DIS_TEXT
 4114                                 (void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
 4115 #endif
 4116                                 NOMEM;
 4117                                 break;
 4118                         } else {
 4119                                 goto error;
 4120                         }
 4121 
 4122                 }
 4123                 /*FALLTHROUGH*/
 4124         case MO:
 4125                 /* Similar to M, but only memory (no direct registers) */
 4126                 wbit = LONG_OPND;
 4127                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4128                 if (mode == 3)
 4129                         goto error;
 4130                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 4131                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 4132                 break;
 4133 
 4134         /* move special register to register or reverse if vbit */
 4135         case SREG:
 4136                 switch (opcode5) {
 4137 
 4138                 case 2:
 4139                         vbit = 1;
 4140                         /*FALLTHROUGH*/
 4141                 case 0:
 4142                         wbit = CONTROL_OPND;
 4143                         break;
 4144 
 4145                 case 3:
 4146                         vbit = 1;
 4147                         /*FALLTHROUGH*/
 4148                 case 1:
 4149                         wbit = DEBUG_OPND;
 4150                         break;
 4151 
 4152                 case 6:
 4153                         vbit = 1;
 4154                         /*FALLTHROUGH*/
 4155                 case 4:
 4156                         wbit = TEST_OPND;
 4157                         break;
 4158 
 4159                 }
 4160                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4161                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4162                 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
 4163                 dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
 4164                 NOMEM;
 4165                 break;
 4166 
 4167         /*
 4168          * single register operand with register in the low 3
 4169          * bits of op code
 4170          */
 4171         case R:
 4172                 if (opcode_bytes == 2)
 4173                         reg = REGNO(opcode5);
 4174                 else
 4175                         reg = REGNO(opcode2);
 4176                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
 4177                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
 4178                 NOMEM;
 4179                 break;
 4180 
 4181         /*
 4182          * register to accumulator with register in the low 3
 4183          * bits of op code, xchg instructions
 4184          */
 4185         case RA:
 4186                 NOMEM;
 4187                 reg = REGNO(opcode2);
 4188                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
 4189                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
 4190                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
 4191                 break;
 4192 
 4193         /*
 4194          * single segment register operand, with register in
 4195          * bits 3-4 of op code byte
 4196          */
 4197         case SEG:
 4198                 NOMEM;
 4199                 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
 4200                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
 4201                 break;
 4202 
 4203         /*
 4204          * single segment register operand, with register in
 4205          * bits 3-5 of op code
 4206          */
 4207         case LSEG:
 4208                 NOMEM;
 4209                 /* long seg reg from opcode */
 4210                 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
 4211                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
 4212                 break;
 4213 
 4214         /* memory or register operand to register */
 4215         case MR:
 4216                 if (vex_prefetch)
 4217                         x->d86_got_modrm = 1;
 4218                 wbit = LONG_OPND;
 4219                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
 4220                 break;
 4221 
 4222         case RM:
 4223         case RM_66r:
 4224                 wbit = LONG_OPND;
 4225                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
 4226                 break;
 4227 
 4228         /* MMX/SIMD-Int memory or mm reg to mm reg              */
 4229         case MM:
 4230         case MMO:
 4231 #ifdef DIS_TEXT
 4232                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
 4233 #else
 4234                 wbit = LONG_OPND;
 4235 #endif
 4236                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
 4237                 break;
 4238 
 4239         case MMOIMPL:
 4240 #ifdef DIS_TEXT
 4241                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
 4242 #else
 4243                 wbit = LONG_OPND;
 4244 #endif
 4245                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4246                 if (mode != REG_ONLY)
 4247                         goto error;
 4248 
 4249                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4250                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 4251                 dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
 4252                 mode = 0;       /* change for memory access size... */
 4253                 break;
 4254 
 4255         /* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
 4256         case MMO3P:
 4257                 wbit = MM_OPND;
 4258                 goto xmm3p;
 4259         case XMM3P:
 4260                 wbit = XMM_OPND;
 4261 xmm3p:
 4262                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4263                 if (mode != REG_ONLY)
 4264                         goto error;
 4265 
 4266                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
 4267                     1);
 4268                 NOMEM;
 4269                 break;
 4270 
 4271         case XMM3PM_66r:
 4272                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
 4273                     1, 0);
 4274                 break;
 4275 
 4276         /* MMX/SIMD-Int predicated r32/mem to mm reg */
 4277         case MMOPRM:
 4278                 wbit = LONG_OPND;
 4279                 w2 = MM_OPND;
 4280                 goto xmmprm;
 4281         case XMMPRM:
 4282         case XMMPRM_66r:
 4283                 wbit = LONG_OPND;
 4284                 w2 = XMM_OPND;
 4285 xmmprm:
 4286                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
 4287                 break;
 4288 
 4289         /* MMX/SIMD-Int predicated mm/mem to mm reg */
 4290         case MMOPM:
 4291         case MMOPM_66o:
 4292                 wbit = w2 = MM_OPND;
 4293                 goto xmmprm;
 4294 
 4295         /* MMX/SIMD-Int mm reg to r32 */
 4296         case MMOM3:
 4297                 NOMEM;
 4298                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4299                 if (mode != REG_ONLY)
 4300                         goto error;
 4301                 wbit = MM_OPND;
 4302                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
 4303                 break;
 4304 
 4305         /* SIMD memory or xmm reg operand to xmm reg            */
 4306         case XMM:
 4307         case XMM_66o:
 4308         case XMM_66r:
 4309         case XMMO:
 4310         case XMMXIMPL:
 4311                 wbit = XMM_OPND;
 4312                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
 4313 
 4314                 if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
 4315                         goto error;
 4316 
 4317 #ifdef DIS_TEXT
 4318                 /*
 4319                  * movlps and movhlps share opcodes.  They differ in the
 4320                  * addressing modes allowed for their operands.
 4321                  * movhps and movlhps behave similarly.
 4322                  */
 4323                 if (mode == REG_ONLY) {
 4324                         if (strcmp(dp->it_name, "movlps") == 0)
 4325                                 (void) strncpy(x->d86_mnem, "movhlps", OPLEN);
 4326                         else if (strcmp(dp->it_name, "movhps") == 0)
 4327                                 (void) strncpy(x->d86_mnem, "movlhps", OPLEN);
 4328                 }
 4329 #endif
 4330                 if (dp->it_adrmode == XMMXIMPL)
 4331                         mode = 0;       /* change for memory access size... */
 4332                 break;
 4333 
 4334         /* SIMD xmm reg to memory or xmm reg */
 4335         case XMMS:
 4336         case XMMOS:
 4337         case XMMMS:
 4338         case XMMOMS:
 4339                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4340 #ifdef DIS_TEXT
 4341                 if ((strcmp(dp->it_name, "movlps") == 0 ||
 4342                     strcmp(dp->it_name, "movhps") == 0 ||
 4343                     strcmp(dp->it_name, "movntps") == 0) &&
 4344                     mode == REG_ONLY)
 4345                         goto error;
 4346 #endif
 4347                 wbit = XMM_OPND;
 4348                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
 4349                 break;
 4350 
 4351         /* SIMD memory to xmm reg */
 4352         case XMMM:
 4353         case XMMM_66r:
 4354         case XMMOM:
 4355                 wbit = XMM_OPND;
 4356                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4357 #ifdef DIS_TEXT
 4358                 if (mode == REG_ONLY) {
 4359                         if (strcmp(dp->it_name, "movhps") == 0)
 4360                                 (void) strncpy(x->d86_mnem, "movlhps", OPLEN);
 4361                         else
 4362                                 goto error;
 4363                 }
 4364 #endif
 4365                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
 4366                 break;
 4367 
 4368         /* SIMD memory or r32 to xmm reg                        */
 4369         case XMM3MX:
 4370                 wbit = LONG_OPND;
 4371                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
 4372                 break;
 4373 
 4374         case XMM3MXS:
 4375                 wbit = LONG_OPND;
 4376                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
 4377                 break;
 4378 
 4379         /* SIMD memory or mm reg to xmm reg                     */
 4380         case XMMOMX:
 4381         /* SIMD mm to xmm */
 4382         case XMMMX:
 4383                 wbit = MM_OPND;
 4384                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
 4385                 break;
 4386 
 4387         /* SIMD memory or xmm reg to mm reg                     */
 4388         case XMMXMM:
 4389         case XMMOXMM:
 4390         case XMMXM:
 4391                 wbit = XMM_OPND;
 4392                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
 4393                 break;
 4394 
 4395 
 4396         /* SIMD memory or xmm reg to r32                        */
 4397         case XMMXM3:
 4398                 wbit = XMM_OPND;
 4399                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
 4400                 break;
 4401 
 4402         /* SIMD xmm to r32                                      */
 4403         case XMMX3:
 4404         case XMMOX3:
 4405                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4406                 if (mode != REG_ONLY)
 4407                         goto error;
 4408                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4409                 dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
 4410                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
 4411                 NOMEM;
 4412                 break;
 4413 
 4414         /* SIMD predicated memory or xmm reg with/to xmm reg */
 4415         case XMMP:
 4416         case XMMP_66r:
 4417         case XMMP_66o:
 4418         case XMMOPM:
 4419                 wbit = XMM_OPND;
 4420                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
 4421                     1);
 4422 
 4423 #ifdef DIS_TEXT
 4424                 /*
 4425                  * cmpps and cmpss vary their instruction name based
 4426                  * on the value of imm8.  Other XMMP instructions,
 4427                  * such as shufps, require explicit specification of
 4428                  * the predicate.
 4429                  */
 4430                 if (dp->it_name[0] == 'c' &&
 4431                     dp->it_name[1] == 'm' &&
 4432                     dp->it_name[2] == 'p' &&
 4433                     strlen(dp->it_name) == 5) {
 4434                         uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
 4435 
 4436                         if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
 4437                                 goto error;
 4438 
 4439                         (void) strncpy(x->d86_mnem, "cmp", OPLEN);
 4440                         (void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
 4441                             OPLEN);
 4442                         (void) strlcat(x->d86_mnem,
 4443                             dp->it_name + strlen(dp->it_name) - 2,
 4444                             OPLEN);
 4445                         x->d86_opnd[0] = x->d86_opnd[1];
 4446                         x->d86_opnd[1] = x->d86_opnd[2];
 4447                         x->d86_numopnds = 2;
 4448                 }
 4449 #endif
 4450                 break;
 4451 
 4452         case XMMX2I:
 4453                 FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
 4454                     1);
 4455                 NOMEM;
 4456                 break;
 4457 
 4458         case XMM2I:
 4459                 ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
 4460                 NOMEM;
 4461                 break;
 4462 
 4463         /* immediate operand to accumulator */
 4464         case IA:
 4465                 wbit = WBIT(opcode2);
 4466                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
 4467                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
 4468                 NOMEM;
 4469                 break;
 4470 
 4471         /* memory or register operand to accumulator */
 4472         case MA:
 4473                 wbit = WBIT(opcode2);
 4474                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 4475                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 4476                 break;
 4477 
 4478         /* si register to di register used to reference memory          */
 4479         case SD:
 4480 #ifdef DIS_TEXT
 4481                 dtrace_check_override(x, 0);
 4482                 x->d86_numopnds = 2;
 4483                 if (addr_size == SIZE64) {
 4484                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
 4485                             OPLEN);
 4486                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
 4487                             OPLEN);
 4488                 } else if (addr_size == SIZE32) {
 4489                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
 4490                             OPLEN);
 4491                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
 4492                             OPLEN);
 4493                 } else {
 4494                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
 4495                             OPLEN);
 4496                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
 4497                             OPLEN);
 4498                 }
 4499 #endif
 4500                 wbit = LONG_OPND;
 4501                 break;
 4502 
 4503         /* accumulator to di register                           */
 4504         case AD:
 4505                 wbit = WBIT(opcode2);
 4506 #ifdef DIS_TEXT
 4507                 dtrace_check_override(x, 1);
 4508                 x->d86_numopnds = 2;
 4509                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
 4510                 if (addr_size == SIZE64)
 4511                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
 4512                             OPLEN);
 4513                 else if (addr_size == SIZE32)
 4514                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
 4515                             OPLEN);
 4516                 else
 4517                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
 4518                             OPLEN);
 4519 #endif
 4520                 break;
 4521 
 4522         /* si register to accumulator                           */
 4523         case SA:
 4524                 wbit = WBIT(opcode2);
 4525 #ifdef DIS_TEXT
 4526                 dtrace_check_override(x, 0);
 4527                 x->d86_numopnds = 2;
 4528                 if (addr_size == SIZE64)
 4529                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
 4530                             OPLEN);
 4531                 else if (addr_size == SIZE32)
 4532                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
 4533                             OPLEN);
 4534                 else
 4535                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
 4536                             OPLEN);
 4537                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
 4538 #endif
 4539                 break;
 4540 
 4541         /*
 4542          * single operand, a 16/32 bit displacement
 4543          */
 4544         case D:
 4545                 wbit = LONG_OPND;
 4546                 dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
 4547                 NOMEM;
 4548                 break;
 4549 
 4550         /* jmp/call indirect to memory or register operand              */
 4551         case INM:
 4552 #ifdef DIS_TEXT
 4553                 (void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
 4554 #endif
 4555                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 4556                 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
 4557                 wbit = LONG_OPND;
 4558                 break;
 4559 
 4560         /*
 4561          * for long jumps and long calls -- a new code segment
 4562          * register and an offset in IP -- stored in object
 4563          * code in reverse order. Note - not valid in amd64
 4564          */
 4565         case SO:
 4566                 dtrace_check_override(x, 1);
 4567                 wbit = LONG_OPND;
 4568                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
 4569 #ifdef DIS_TEXT
 4570                 x->d86_opnd[1].d86_mode = MODE_SIGNED;
 4571 #endif
 4572                 /* will now get segment operand */
 4573                 dtrace_imm_opnd(x, wbit, 2, 0);
 4574                 break;
 4575 
 4576         /*
 4577          * jmp/call. single operand, 8 bit displacement.
 4578          * added to current EIP in 'compofff'
 4579          */
 4580         case BD:
 4581                 dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
 4582                 NOMEM;
 4583                 break;
 4584 
 4585         /* single 32/16 bit immediate operand                   */
 4586         case I:
 4587                 wbit = LONG_OPND;
 4588                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
 4589                 break;
 4590 
 4591         /* single 8 bit immediate operand                       */
 4592         case Ib:
 4593                 wbit = LONG_OPND;
 4594                 dtrace_imm_opnd(x, wbit, 1, 0);
 4595                 break;
 4596 
 4597         case ENTER:
 4598                 wbit = LONG_OPND;
 4599                 dtrace_imm_opnd(x, wbit, 2, 0);
 4600                 dtrace_imm_opnd(x, wbit, 1, 1);
 4601                 switch (opnd_size) {
 4602                 case SIZE64:
 4603                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
 4604                         break;
 4605                 case SIZE32:
 4606                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
 4607                         break;
 4608                 case SIZE16:
 4609                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
 4610                         break;
 4611                 }
 4612 
 4613                 break;
 4614 
 4615         /* 16-bit immediate operand */
 4616         case RET:
 4617                 wbit = LONG_OPND;
 4618                 dtrace_imm_opnd(x, wbit, 2, 0);
 4619                 break;
 4620 
 4621         /* single 8 bit port operand                            */
 4622         case P:
 4623                 dtrace_check_override(x, 0);
 4624                 dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
 4625                 NOMEM;
 4626                 break;
 4627 
 4628         /* single operand, dx register (variable port instruction) */
 4629         case V:
 4630                 x->d86_numopnds = 1;
 4631                 dtrace_check_override(x, 0);
 4632 #ifdef DIS_TEXT
 4633                 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
 4634 #endif
 4635                 NOMEM;
 4636                 break;
 4637 
 4638         /*
 4639          * The int instruction, which has two forms:
 4640          * int 3 (breakpoint) or
 4641          * int n, where n is indicated in the subsequent
 4642          * byte (format Ib).  The int 3 instruction (opcode 0xCC),
 4643          * where, although the 3 looks  like an operand,
 4644          * it is implied by the opcode. It must be converted
 4645          * to the correct base and output.
 4646          */
 4647         case INT3:
 4648 #ifdef DIS_TEXT
 4649                 x->d86_numopnds = 1;
 4650                 x->d86_opnd[0].d86_mode = MODE_SIGNED;
 4651                 x->d86_opnd[0].d86_value_size = 1;
 4652                 x->d86_opnd[0].d86_value = 3;
 4653 #endif
 4654                 NOMEM;
 4655                 break;
 4656 
 4657         /* single 8 bit immediate operand                       */
 4658         case INTx:
 4659                 dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
 4660                 NOMEM;
 4661                 break;
 4662 
 4663         /* an unused byte must be discarded */
 4664         case U:
 4665                 if (x->d86_get_byte(x->d86_data) < 0)
 4666                         goto error;
 4667                 x->d86_len++;
 4668                 NOMEM;
 4669                 break;
 4670 
 4671         case CBW:
 4672 #ifdef DIS_TEXT
 4673                 if (opnd_size == SIZE16)
 4674                         (void) strlcat(x->d86_mnem, "cbtw", OPLEN);
 4675                 else if (opnd_size == SIZE32)
 4676                         (void) strlcat(x->d86_mnem, "cwtl", OPLEN);
 4677                 else
 4678                         (void) strlcat(x->d86_mnem, "cltq", OPLEN);
 4679 #endif
 4680                 wbit = LONG_OPND;
 4681                 NOMEM;
 4682                 break;
 4683 
 4684         case CWD:
 4685 #ifdef DIS_TEXT
 4686                 if (opnd_size == SIZE16)
 4687                         (void) strlcat(x->d86_mnem, "cwtd", OPLEN);
 4688                 else if (opnd_size == SIZE32)
 4689                         (void) strlcat(x->d86_mnem, "cltd", OPLEN);
 4690                 else
 4691                         (void) strlcat(x->d86_mnem, "cqtd", OPLEN);
 4692 #endif
 4693                 wbit = LONG_OPND;
 4694                 NOMEM;
 4695                 break;
 4696 
 4697         case XMMSFNC:
 4698                 /*
 4699                  * sfence is sfence if mode is REG_ONLY.  If mode isn't
 4700                  * REG_ONLY, mnemonic should be 'clflush'.
 4701                  */
 4702                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4703 
 4704                 /* sfence doesn't take operands */
 4705 #ifdef DIS_TEXT
 4706                 if (mode == REG_ONLY) {
 4707                         (void) strlcat(x->d86_mnem, "sfence", OPLEN);
 4708                 } else {
 4709                         (void) strlcat(x->d86_mnem, "clflush", OPLEN);
 4710                         dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4711                         dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
 4712                         NOMEM;
 4713                 }
 4714 #else
 4715                 if (mode != REG_ONLY) {
 4716                         dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4717                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
 4718                         NOMEM;
 4719                 }
 4720 #endif
 4721                 break;
 4722 
 4723         /*
 4724          * no disassembly, the mnemonic was all there was so go on
 4725          */
 4726         case NORM:
 4727                 if (dp->it_invalid32 && cpu_mode != SIZE64)
 4728                         goto error;
 4729                 NOMEM;
 4730                 /*FALLTHROUGH*/
 4731         case IMPLMEM:
 4732                 break;
 4733 
 4734         case XMMFENCE:
 4735                 /*
 4736                  * XRSTOR and LFENCE share the same opcode but differ in mode
 4737                  */
 4738                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4739 
 4740                 if (mode == REG_ONLY) {
 4741                         /*
 4742                          * Only the following exact byte sequences are allowed:
 4743                          *
 4744                          *      0f ae e8        lfence
 4745                          *      0f ae f0        mfence
 4746                          */
 4747                         if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
 4748                             (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
 4749                                 goto error;
 4750                 } else {
 4751 #ifdef DIS_TEXT
 4752                         (void) strncpy(x->d86_mnem, "xrstor", OPLEN);
 4753 #endif
 4754                         dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 4755                         dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
 4756                 }
 4757                 break;
 4758 
 4759         /* float reg */
 4760         case F:
 4761 #ifdef DIS_TEXT
 4762                 x->d86_numopnds = 1;
 4763                 (void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
 4764                 x->d86_opnd[0].d86_opnd[4] = r_m + '';
 4765 #endif
 4766                 NOMEM;
 4767                 break;
 4768 
 4769         /* float reg to float reg, with ret bit present */
 4770         case FF:
 4771                 vbit = opcode2 >> 2 & 0x1;      /* vbit = 1: st -> st(i) */
 4772                 /*FALLTHROUGH*/
 4773         case FFC:                               /* case for vbit always = 0 */
 4774 #ifdef DIS_TEXT
 4775                 x->d86_numopnds = 2;
 4776                 (void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
 4777                 (void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
 4778                 x->d86_opnd[vbit].d86_opnd[4] = r_m + '';
 4779 #endif
 4780                 NOMEM;
 4781                 break;
 4782 
 4783         /* AVX instructions */
 4784         case VEX_MO:
 4785                 /* op(ModR/M.r/m) */
 4786                 x->d86_numopnds = 1;
 4787                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4788 #ifdef DIS_TEXT
 4789                 if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
 4790                         (void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
 4791 #endif
 4792                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4793                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 4794                 break;
 4795         case VEX_RMrX:
 4796         case FMA:
 4797                 /* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
 4798                 x->d86_numopnds = 3;
 4799                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4800                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4801 
 4802                 /*
 4803                  * In classic Intel fashion, the opcodes for all of the FMA
 4804                  * instructions all have two possible mnemonics which vary by
 4805                  * one letter, which is selected based on the value of the wbit.
 4806                  * When wbit is one, they have the 'd' suffix and when 'wbit' is
 4807                  * 0, they have the 's' suffix. Otherwise, the FMA instructions
 4808                  * are all a standard VEX_RMrX.
 4809                  */
 4810 #ifdef DIS_TEXT
 4811                 if (dp->it_adrmode == FMA) {
 4812                         size_t len = strlen(dp->it_name);
 4813                         (void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
 4814                         if (len + 1 < OPLEN) {
 4815                                 (void) strncpy(x->d86_mnem + len,
 4816                                     vex_W != 0 ? "d" : "s", OPLEN - len);
 4817                         }
 4818                 }
 4819 #endif
 4820 
 4821                 if (mode != REG_ONLY) {
 4822                         if ((dp == &dis_opAVXF20F[0x10]) ||
 4823                             (dp == &dis_opAVXF30F[0x10])) {
 4824                                 /* vmovsd <m64>, <xmm> */
 4825                                 /* or vmovss <m64>, <xmm> */
 4826                                 x->d86_numopnds = 2;
 4827                                 goto L_VEX_MX;
 4828                         }
 4829                 }
 4830 
 4831                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
 4832                 /*
 4833                  * VEX prefix uses the 1's complement form to encode the
 4834                  * XMM/YMM regs
 4835                  */
 4836                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
 4837 
 4838                 if ((dp == &dis_opAVXF20F[0x2A]) ||
 4839                     (dp == &dis_opAVXF30F[0x2A])) {
 4840                         /*
 4841                          * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
 4842                          * <xmm>, <xmm>
 4843                          */
 4844                         wbit = LONG_OPND;
 4845                 }
 4846 #ifdef DIS_TEXT
 4847                 else if ((mode == REG_ONLY) &&
 4848                     (dp == &dis_opAVX0F[0x1][0x6])) {   /* vmovlhps */
 4849                         (void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
 4850                 } else if ((mode == REG_ONLY) &&
 4851                     (dp == &dis_opAVX0F[0x1][0x2])) {   /* vmovhlps */
 4852                         (void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
 4853                 }
 4854 #endif
 4855                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 4856 
 4857                 break;
 4858 
 4859         case VEX_VRMrX:
 4860                 /* ModR/M.reg := op(MODR/M.r/m, VEX.vvvv) */
 4861                 x->d86_numopnds = 3;
 4862                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4863                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4864 
 4865                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
 4866                 /*
 4867                  * VEX prefix uses the 1's complement form to encode the
 4868                  * XMM/YMM regs
 4869                  */
 4870                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 0);
 4871 
 4872                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 4873                 break;
 4874 
 4875         case VEX_SbVM:
 4876                 /* ModR/M.reg := op(MODR/M.r/m, VSIB, VEX.vvvv) */
 4877                 x->d86_numopnds = 3;
 4878                 x->d86_vsib = 1;
 4879 
 4880                 /*
 4881                  * All instructions that use VSIB are currently a mess. See the
 4882                  * comment around the dis_gather_regs_t structure definition.
 4883                  */
 4884 
 4885                 vreg = &dis_vgather[opcode2][vex_W][vex_L];
 4886 
 4887 #ifdef DIS_TEXT
 4888                 (void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
 4889                 (void) strlcat(x->d86_mnem + strlen(dp->it_name),
 4890                     vreg->dgr_suffix, OPLEN - strlen(dp->it_name));
 4891 #endif
 4892 
 4893                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4894                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4895 
 4896                 dtrace_get_operand(x, REG_ONLY, reg, vreg->dgr_arg2, 2);
 4897                 /*
 4898                  * VEX prefix uses the 1's complement form to encode the
 4899                  * XMM/YMM regs
 4900                  */
 4901                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), vreg->dgr_arg0,
 4902                     0);
 4903                 dtrace_get_operand(x, mode, r_m, vreg->dgr_arg1, 1);
 4904                 break;
 4905 
 4906         case VEX_RRX:
 4907                 /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
 4908                 x->d86_numopnds = 3;
 4909 
 4910                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4911                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4912 
 4913                 if (mode != REG_ONLY) {
 4914                         if ((dp == &dis_opAVXF20F[0x11]) ||
 4915                             (dp == &dis_opAVXF30F[0x11])) {
 4916                                 /* vmovsd <xmm>, <m64> */
 4917                                 /* or vmovss <xmm>, <m64> */
 4918                                 x->d86_numopnds = 2;
 4919                                 goto L_VEX_RM;
 4920                         }
 4921                 }
 4922 
 4923                 dtrace_get_operand(x, mode, r_m, wbit, 2);
 4924                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
 4925                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
 4926                 break;
 4927 
 4928         case VEX_RMRX:
 4929                 /* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
 4930                 x->d86_numopnds = 4;
 4931 
 4932                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4933                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4934                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
 4935                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
 4936                 if (dp == &dis_opAVX660F3A[0x18]) {
 4937                         /* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
 4938                         dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
 4939                 } else if ((dp == &dis_opAVX660F3A[0x20]) ||
 4940                     (dp == & dis_opAVX660F[0xC4])) {
 4941                         /* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
 4942                         /* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
 4943                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
 4944                 } else if (dp == &dis_opAVX660F3A[0x22]) {
 4945                         /* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
 4946 #ifdef DIS_TEXT
 4947                         if (vex_W)
 4948                                 x->d86_mnem[6] = 'q';
 4949 #endif
 4950                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
 4951                 } else {
 4952                         dtrace_get_operand(x, mode, r_m, wbit, 1);
 4953                 }
 4954 
 4955                 /* one byte immediate number */
 4956                 dtrace_imm_opnd(x, wbit, 1, 0);
 4957 
 4958                 /* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
 4959                 if ((dp == &dis_opAVX660F3A[0x4A]) ||
 4960                     (dp == &dis_opAVX660F3A[0x4B]) ||
 4961                     (dp == &dis_opAVX660F3A[0x4C])) {
 4962 #ifdef DIS_TEXT
 4963                         int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
 4964 #endif
 4965                         x->d86_opnd[0].d86_mode = MODE_NONE;
 4966 #ifdef DIS_TEXT
 4967                         if (vex_L)
 4968                                 (void) strncpy(x->d86_opnd[0].d86_opnd,
 4969                                     dis_YMMREG[regnum], OPLEN);
 4970                         else
 4971                                 (void) strncpy(x->d86_opnd[0].d86_opnd,
 4972                                     dis_XMMREG[regnum], OPLEN);
 4973 #endif
 4974                 }
 4975                 break;
 4976 
 4977         case VEX_MX:
 4978                 /* ModR/M.reg := op(ModR/M.rm) */
 4979                 x->d86_numopnds = 2;
 4980 
 4981                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 4982                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 4983 L_VEX_MX:
 4984 
 4985                 if ((dp == &dis_opAVXF20F[0xE6]) ||
 4986                     (dp == &dis_opAVX660F[0x5A]) ||
 4987                     (dp == &dis_opAVX660F[0xE6])) {
 4988                         /* vcvtpd2dq <ymm>, <xmm> */
 4989                         /* or vcvtpd2ps <ymm>, <xmm> */
 4990                         /* or vcvttpd2dq <ymm>, <xmm> */
 4991                         dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
 4992                         dtrace_get_operand(x, mode, r_m, wbit, 0);
 4993                 } else if ((dp == &dis_opAVXF30F[0xE6]) ||
 4994                     (dp == &dis_opAVX0F[0x5][0xA]) ||
 4995                     (dp == &dis_opAVX660F38[0x13]) ||
 4996                     (dp == &dis_opAVX660F38[0x18]) ||
 4997                     (dp == &dis_opAVX660F38[0x19]) ||
 4998                     (dp == &dis_opAVX660F38[0x58]) ||
 4999                     (dp == &dis_opAVX660F38[0x78]) ||
 5000                     (dp == &dis_opAVX660F38[0x79]) ||
 5001                     (dp == &dis_opAVX660F38[0x59])) {
 5002                         /* vcvtdq2pd <xmm>, <ymm> */
 5003                         /* or vcvtps2pd <xmm>, <ymm> */
 5004                         /* or vcvtph2ps <xmm>, <ymm> */
 5005                         /* or vbroadcasts* <xmm>, <ymm> */
 5006                         dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5007                         dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
 5008                 } else if (dp == &dis_opAVX660F[0x6E]) {
 5009                         /* vmovd/q <reg/mem 32/64>, <xmm> */
 5010 #ifdef DIS_TEXT
 5011                         if (vex_W)
 5012                                 x->d86_mnem[4] = 'q';
 5013 #endif
 5014                         dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5015                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
 5016                 } else {
 5017                         dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5018                         dtrace_get_operand(x, mode, r_m, wbit, 0);
 5019                 }
 5020 
 5021                 break;
 5022 
 5023         case VEX_MXI:
 5024                 /* ModR/M.reg := op(ModR/M.rm, imm8) */
 5025                 x->d86_numopnds = 3;
 5026 
 5027                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5028                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5029 
 5030                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
 5031                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 5032 
 5033                 /* one byte immediate number */
 5034                 dtrace_imm_opnd(x, wbit, 1, 0);
 5035                 break;
 5036 
 5037         case VEX_XXI:
 5038                 /* VEX.vvvv := op(ModR/M.rm, imm8) */
 5039                 x->d86_numopnds = 3;
 5040 
 5041                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5042 #ifdef DIS_TEXT
 5043                 (void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
 5044                     OPLEN);
 5045 #endif
 5046                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5047 
 5048                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
 5049                 dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
 5050 
 5051                 /* one byte immediate number */
 5052                 dtrace_imm_opnd(x, wbit, 1, 0);
 5053                 break;
 5054 
 5055         case VEX_MR:
 5056                 /* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
 5057                 if (dp == &dis_opAVX660F[0xC5]) {
 5058                         /* vpextrw <imm8>, <xmm>, <reg> */
 5059                         x->d86_numopnds = 2;
 5060                         vbit = 2;
 5061                 } else {
 5062                         x->d86_numopnds = 2;
 5063                         vbit = 1;
 5064                 }
 5065 
 5066                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5067                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5068                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
 5069                 dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
 5070 
 5071                 if (vbit == 2)
 5072                         dtrace_imm_opnd(x, wbit, 1, 0);
 5073 
 5074                 break;
 5075 
 5076         case VEX_RRI:
 5077                 /* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
 5078                 x->d86_numopnds = 2;
 5079 
 5080                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5081                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5082                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5083                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 5084                 break;
 5085 
 5086         case VEX_RX:
 5087                 /* ModR/M.rm := op(ModR/M.reg) */
 5088                 /* vextractf128 || vcvtps2ph */
 5089                 if (dp == &dis_opAVX660F3A[0x19] ||
 5090                     dp == &dis_opAVX660F3A[0x1d]) {
 5091                         x->d86_numopnds = 3;
 5092 
 5093                         dtrace_get_modrm(x, &mode, &reg, &r_m);
 5094                         dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5095 
 5096                         dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
 5097                         dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5098 
 5099                         /* one byte immediate number */
 5100                         dtrace_imm_opnd(x, wbit, 1, 0);
 5101                         break;
 5102                 }
 5103 
 5104                 x->d86_numopnds = 2;
 5105 
 5106                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5107                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5108                 dtrace_get_operand(x, mode, r_m, wbit, 1);
 5109                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
 5110                 break;
 5111 
 5112         case VEX_RR:
 5113                 /* ModR/M.rm := op(ModR/M.reg) */
 5114                 x->d86_numopnds = 2;
 5115 
 5116                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5117                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5118 
 5119                 if (dp == &dis_opAVX660F[0x7E]) {
 5120                         /* vmovd/q <reg/mem 32/64>, <xmm> */
 5121 #ifdef DIS_TEXT
 5122                         if (vex_W)
 5123                                 x->d86_mnem[4] = 'q';
 5124 #endif
 5125                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
 5126                 } else
 5127                         dtrace_get_operand(x, mode, r_m, wbit, 1);
 5128 
 5129                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
 5130                 break;
 5131 
 5132         case VEX_RRi:
 5133                 /* ModR/M.rm := op(ModR/M.reg, imm) */
 5134                 x->d86_numopnds = 3;
 5135 
 5136                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5137                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5138 
 5139 #ifdef DIS_TEXT
 5140                 if (dp == &dis_opAVX660F3A[0x16]) {
 5141                         /* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
 5142                         if (vex_W)
 5143                                 x->d86_mnem[6] = 'q';
 5144                 }
 5145 #endif
 5146                 dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
 5147                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5148 
 5149                 /* one byte immediate number */
 5150                 dtrace_imm_opnd(x, wbit, 1, 0);
 5151                 break;
 5152         case VEX_RIM:
 5153                 /* ModR/M.rm := op(ModR/M.reg, imm) */
 5154                 x->d86_numopnds = 3;
 5155 
 5156                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5157                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5158 
 5159                 dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
 5160                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5161                 /* one byte immediate number */
 5162                 dtrace_imm_opnd(x, wbit, 1, 0);
 5163                 break;
 5164 
 5165         case VEX_RM:
 5166                 /* ModR/M.rm := op(ModR/M.reg) */
 5167                 if (dp == &dis_opAVX660F3A[0x17]) {     /* vextractps */
 5168                         x->d86_numopnds = 3;
 5169 
 5170                         dtrace_get_modrm(x, &mode, &reg, &r_m);
 5171                         dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5172 
 5173                         dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
 5174                         dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
 5175                         /* one byte immediate number */
 5176                         dtrace_imm_opnd(x, wbit, 1, 0);
 5177                         break;
 5178                 }
 5179                 x->d86_numopnds = 2;
 5180 
 5181                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5182                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5183 L_VEX_RM:
 5184                 vbit = 1;
 5185                 dtrace_get_operand(x, mode, r_m, wbit, vbit);
 5186                 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
 5187 
 5188                 break;
 5189 
 5190         case VEX_RRM:
 5191                 /* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
 5192                 x->d86_numopnds = 3;
 5193 
 5194                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5195                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5196                 dtrace_get_operand(x, mode, r_m, wbit, 2);
 5197                 /* VEX use the 1's complement form encode the XMM/YMM regs */
 5198                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
 5199                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
 5200                 break;
 5201 
 5202         case VEX_RMX:
 5203                 /* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
 5204                 x->d86_numopnds = 3;
 5205 
 5206                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5207                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5208                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
 5209                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
 5210                 dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
 5211                 break;
 5212 
 5213         case VEX_NONE:
 5214 #ifdef DIS_TEXT
 5215                 if (vex_L)
 5216                         (void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
 5217 #endif
 5218                 break;
 5219         case BLS: {
 5220 
 5221                 /*
 5222                  * The BLS instructions are VEX instructions that are based on
 5223                  * VEX.0F38.F3; however, they are considered special group 17
 5224                  * and like everything else, they use the bits in 3-5 of the
 5225                  * MOD R/M to determine the sub instruction. Unlike many others
 5226                  * like the VMX instructions, these are valid both for memory
 5227                  * and register forms.
 5228                  */
 5229 
 5230                 dtrace_get_modrm(x, &mode, &reg, &r_m);
 5231                 dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
 5232 
 5233                 switch (reg) {
 5234                 case 1:
 5235 #ifdef  DIS_TEXT
 5236                         blsinstr = "blsr";
 5237 #endif
 5238                         break;
 5239                 case 2:
 5240 #ifdef  DIS_TEXT
 5241                         blsinstr = "blsmsk";
 5242 #endif
 5243                         break;
 5244                 case 3:
 5245 #ifdef  DIS_TEXT
 5246                         blsinstr = "blsi";
 5247 #endif
 5248                         break;
 5249                 default:
 5250                         goto error;
 5251                 }
 5252 
 5253                 x->d86_numopnds = 2;
 5254 #ifdef DIS_TEXT
 5255                 (void) strncpy(x->d86_mnem, blsinstr, OPLEN);
 5256 #endif
 5257                 dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
 5258                 dtrace_get_operand(x, mode, r_m, wbit, 0);
 5259                 break;
 5260         }
 5261         /* an invalid op code */
 5262         case AM:
 5263         case DM:
 5264         case OVERRIDE:
 5265         case PREFIX:
 5266         case UNKNOWN:
 5267                 NOMEM;
 5268         default:
 5269                 goto error;
 5270         } /* end switch */
 5271         if (x->d86_error)
 5272                 goto error;
 5273 
 5274 done:
 5275 #ifdef DIS_MEM
 5276         /*
 5277          * compute the size of any memory accessed by the instruction
 5278          */
 5279         if (x->d86_memsize != 0) {
 5280                 return (0);
 5281         } else if (dp->it_stackop) {
 5282                 switch (opnd_size) {
 5283                 case SIZE16:
 5284                         x->d86_memsize = 2;
 5285                         break;
 5286                 case SIZE32:
 5287                         x->d86_memsize = 4;
 5288                         break;
 5289                 case SIZE64:
 5290                         x->d86_memsize = 8;
 5291                         break;
 5292                 }
 5293         } else if (nomem || mode == REG_ONLY) {
 5294                 x->d86_memsize = 0;
 5295 
 5296         } else if (dp->it_size != 0) {
 5297                 /*
 5298                  * In 64 bit mode descriptor table entries
 5299                  * go up to 10 bytes and popf/pushf are always 8 bytes
 5300                  */
 5301                 if (x->d86_mode == SIZE64 && dp->it_size == 6)
 5302                         x->d86_memsize = 10;
 5303                 else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
 5304                     (opcode2 == 0xc || opcode2 == 0xd))
 5305                         x->d86_memsize = 8;
 5306                 else
 5307                         x->d86_memsize = dp->it_size;
 5308 
 5309         } else if (wbit == 0) {
 5310                 x->d86_memsize = 1;
 5311 
 5312         } else if (wbit == LONG_OPND) {
 5313                 if (opnd_size == SIZE64)
 5314                         x->d86_memsize = 8;
 5315                 else if (opnd_size == SIZE32)
 5316                         x->d86_memsize = 4;
 5317                 else
 5318                         x->d86_memsize = 2;
 5319 
 5320         } else if (wbit == SEG_OPND) {
 5321                 x->d86_memsize = 4;
 5322 
 5323         } else {
 5324                 x->d86_memsize = 8;
 5325         }
 5326 #endif
 5327         return (0);
 5328 
 5329 error:
 5330 #ifdef DIS_TEXT
 5331         (void) strlcat(x->d86_mnem, "undef", OPLEN);
 5332 #endif
 5333         return (1);
 5334 }
 5335 
 5336 #ifdef DIS_TEXT
 5337 
 5338 /*
 5339  * Some instructions should have immediate operands printed
 5340  * as unsigned integers. We compare against this table.
 5341  */
 5342 static char *unsigned_ops[] = {
 5343         "or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
 5344         "rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
 5345         0
 5346 };
 5347 
 5348 
 5349 static int
 5350 isunsigned_op(char *opcode)
 5351 {
 5352         char *where;
 5353         int i;
 5354         int is_unsigned = 0;
 5355 
 5356         /*
 5357          * Work back to start of last mnemonic, since we may have
 5358          * prefixes on some opcodes.
 5359          */
 5360         where = opcode + strlen(opcode) - 1;
 5361         while (where > opcode && *where != ' ')
 5362                 --where;
 5363         if (*where == ' ')
 5364                 ++where;
 5365 
 5366         for (i = 0; unsigned_ops[i]; ++i) {
 5367                 if (strncmp(where, unsigned_ops[i],
 5368                     strlen(unsigned_ops[i])))
 5369                         continue;
 5370                 is_unsigned = 1;
 5371                 break;
 5372         }
 5373         return (is_unsigned);
 5374 }
 5375 
 5376 /*
 5377  * Print a numeric immediate into end of buf, maximum length buflen.
 5378  * The immediate may be an address or a displacement.  Mask is set
 5379  * for address size.  If the immediate is a "small negative", or
 5380  * if it's a negative displacement of any magnitude, print as -<absval>.
 5381  * Respect the "octal" flag.  "Small negative" is defined as "in the
 5382  * interval [NEG_LIMIT, 0)".
 5383  *
 5384  * Also, "isunsigned_op()" instructions never print negatives.
 5385  *
 5386  * Return whether we decided to print a negative value or not.
 5387  */
 5388 
 5389 #define NEG_LIMIT       -255
 5390 enum {IMM, DISP};
 5391 enum {POS, TRY_NEG};
 5392 
 5393 static int
 5394 print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
 5395     size_t buflen, int disp, int try_neg)
 5396 {
 5397         int curlen;
 5398         int64_t sv = (int64_t)usv;
 5399         int octal = dis->d86_flags & DIS_F_OCTAL;
 5400 
 5401         curlen = strlen(buf);
 5402 
 5403         if (try_neg == TRY_NEG && sv < 0 &&
 5404             (disp || sv >= NEG_LIMIT) &&
 5405             !isunsigned_op(dis->d86_mnem)) {
 5406                 dis->d86_sprintf_func(buf + curlen, buflen - curlen,
 5407                     octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
 5408                 return (1);
 5409         } else {
 5410                 if (disp == DISP)
 5411                         dis->d86_sprintf_func(buf + curlen, buflen - curlen,
 5412                             octal ? "+0%llo" : "+0x%llx", usv & mask);
 5413                 else
 5414                         dis->d86_sprintf_func(buf + curlen, buflen - curlen,
 5415                             octal ? "0%llo" : "0x%llx", usv & mask);
 5416                 return (0);
 5417 
 5418         }
 5419 }
 5420 
 5421 
 5422 static int
 5423 log2(int size)
 5424 {
 5425         switch (size) {
 5426         case 1: return (0);
 5427         case 2: return (1);
 5428         case 4: return (2);
 5429         case 8: return (3);
 5430         }
 5431         return (0);
 5432 }
 5433 
 5434 /* ARGSUSED */
 5435 void
 5436 dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
 5437     size_t buflen)
 5438 {
 5439         uint64_t reltgt = 0;
 5440         uint64_t tgt = 0;
 5441         int curlen;
 5442         int (*lookup)(void *, uint64_t, char *, size_t);
 5443         int i;
 5444         int64_t sv;
 5445         uint64_t usv, mask, save_mask, save_usv;
 5446         static uint64_t masks[] =
 5447             {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
 5448         save_usv = 0;
 5449 
 5450         dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
 5451 
 5452         /*
 5453          * For PC-relative jumps, the pc is really the next pc after executing
 5454          * this instruction, so increment it appropriately.
 5455          */
 5456         pc += dis->d86_len;
 5457 
 5458         for (i = 0; i < dis->d86_numopnds; i++) {
 5459                 d86opnd_t *op = &dis->d86_opnd[i];
 5460 
 5461                 if (i != 0)
 5462                         (void) strlcat(buf, ",", buflen);
 5463 
 5464                 (void) strlcat(buf, op->d86_prefix, buflen);
 5465 
 5466                 /*
 5467                  * sv is for the signed, possibly-truncated immediate or
 5468                  * displacement; usv retains the original size and
 5469                  * unsignedness for symbol lookup.
 5470                  */
 5471 
 5472                 sv = usv = op->d86_value;
 5473 
 5474                 /*
 5475                  * About masks: for immediates that represent
 5476                  * addresses, the appropriate display size is
 5477                  * the effective address size of the instruction.
 5478                  * This includes MODE_OFFSET, MODE_IPREL, and
 5479                  * MODE_RIPREL.  Immediates that are simply
 5480                  * immediate values should display in the operand's
 5481                  * size, however, since they don't represent addresses.
 5482                  */
 5483 
 5484                 /* d86_addr_size is SIZEnn, which is log2(real size) */
 5485                 mask = masks[dis->d86_addr_size];
 5486 
 5487                 /* d86_value_size and d86_imm_bytes are in bytes */
 5488                 if (op->d86_mode == MODE_SIGNED ||
 5489                     op->d86_mode == MODE_IMPLIED)
 5490                         mask = masks[log2(op->d86_value_size)];
 5491 
 5492                 switch (op->d86_mode) {
 5493 
 5494                 case MODE_NONE:
 5495 
 5496                         (void) strlcat(buf, op->d86_opnd, buflen);
 5497                         break;
 5498 
 5499                 case MODE_SIGNED:
 5500                 case MODE_IMPLIED:
 5501                 case MODE_OFFSET:
 5502 
 5503                         tgt = usv;
 5504 
 5505                         if (dis->d86_seg_prefix)
 5506                                 (void) strlcat(buf, dis->d86_seg_prefix,
 5507                                     buflen);
 5508 
 5509                         if (op->d86_mode == MODE_SIGNED ||
 5510                             op->d86_mode == MODE_IMPLIED) {
 5511                                 (void) strlcat(buf, "$", buflen);
 5512                         }
 5513 
 5514                         if (print_imm(dis, usv, mask, buf, buflen,
 5515                             IMM, TRY_NEG) &&
 5516                             (op->d86_mode == MODE_SIGNED ||
 5517                             op->d86_mode == MODE_IMPLIED)) {
 5518 
 5519                                 /*
 5520                                  * We printed a negative value for an
 5521                                  * immediate that wasn't a
 5522                                  * displacement.  Note that fact so we can
 5523                                  * print the positive value as an
 5524                                  * annotation.
 5525                                  */
 5526 
 5527                                 save_usv = usv;
 5528                                 save_mask = mask;
 5529                         }
 5530                         (void) strlcat(buf, op->d86_opnd, buflen);
 5531 
 5532                         break;
 5533 
 5534                 case MODE_IPREL:
 5535                 case MODE_RIPREL:
 5536 
 5537                         reltgt = pc + sv;
 5538 
 5539                         switch (mode) {
 5540                         case SIZE16:
 5541                                 reltgt = (uint16_t)reltgt;
 5542                                 break;
 5543                         case SIZE32:
 5544                                 reltgt = (uint32_t)reltgt;
 5545                                 break;
 5546                         }
 5547 
 5548                         (void) print_imm(dis, usv, mask, buf, buflen,
 5549                             DISP, TRY_NEG);
 5550 
 5551                         if (op->d86_mode == MODE_RIPREL)
 5552                                 (void) strlcat(buf, "(%rip)", buflen);
 5553                         break;
 5554                 }
 5555         }
 5556 
 5557         /*
 5558          * The symbol lookups may result in false positives,
 5559          * particularly on object files, where small numbers may match
 5560          * the 0-relative non-relocated addresses of symbols.
 5561          */
 5562 
 5563         lookup = dis->d86_sym_lookup;
 5564         if (tgt != 0) {
 5565                 if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
 5566                     lookup(dis->d86_data, tgt, NULL, 0) == 0) {
 5567                         (void) strlcat(buf, "\t<", buflen);
 5568                         curlen = strlen(buf);
 5569                         lookup(dis->d86_data, tgt, buf + curlen,
 5570                             buflen - curlen);
 5571                         (void) strlcat(buf, ">", buflen);
 5572                 }
 5573 
 5574                 /*
 5575                  * If we printed a negative immediate above, print the
 5576                  * positive in case our heuristic was unhelpful
 5577                  */
 5578                 if (save_usv) {
 5579                         (void) strlcat(buf, "\t<", buflen);
 5580                         (void) print_imm(dis, save_usv, save_mask, buf, buflen,
 5581                             IMM, POS);
 5582                         (void) strlcat(buf, ">", buflen);
 5583                 }
 5584         }
 5585 
 5586         if (reltgt != 0) {
 5587                 /* Print symbol or effective address for reltgt */
 5588 
 5589                 (void) strlcat(buf, "\t<", buflen);
 5590                 curlen = strlen(buf);
 5591                 lookup(dis->d86_data, reltgt, buf + curlen,
 5592                     buflen - curlen);
 5593                 (void) strlcat(buf, ">", buflen);
 5594         }
 5595 }
 5596 
 5597 #endif /* DIS_TEXT */

Cache object: eac9a44f02b95b617672c274011fa8c4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.