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