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