initial commit
[freebsd-arm:freebsd-arm.git] / cddl / dev / dtrace / i386 / dis_tables.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * $FreeBSD$
22  */
23 /*
24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27
28 /*      Copyright (c) 1988 AT&T */
29 /*        All Rights Reserved   */
30
31
32 #if defined(sun)
33 #pragma ident   "@(#)dis_tables.c       1.11    06/03/02 SMI"
34 #endif
35
36 #include        "dis_tables.h"
37
38 /* BEGIN CSTYLED */
39
40 /*
41  * Disassembly begins in dis_distable, which is equivalent to the One-byte
42  * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
43  * decoding loops then traverse out through the other tables as necessary to
44  * decode a given instruction.
45  *
46  * The behavior of this file can be controlled by one of the following flags:
47  *
48  *      DIS_TEXT        Include text for disassembly
49  *      DIS_MEM         Include memory-size calculations
50  *
51  * Either or both of these can be defined.
52  *
53  * This file is not, and will never be, cstyled.  If anything, the tables should
54  * be taken out another tab stop or two so nothing overlaps.
55  */
56
57 /*
58  * These functions must be provided for the consumer to do disassembly.
59  */
60 #ifdef DIS_TEXT
61 extern char *strncpy(char *, const char *, size_t);
62 extern size_t strlen(const char *);
63 extern int strcmp(const char *, const char *);
64 extern int strncmp(const char *, const char *, size_t);
65 extern size_t strlcat(char *, const char *, size_t);
66 #endif
67
68
69 #define         TERM    NULL    /* used to indicate that the 'indirect' */
70                                 /* field terminates - no pointer.       */
71
72 /* Used to decode instructions. */
73 typedef struct  instable {
74         const struct instable   *it_indirect;   /* for decode op codes */
75         uchar_t         it_adrmode;
76 #ifdef DIS_TEXT
77         char            it_name[NCPS];
78         uint_t          it_suffix:1;            /* mneu + "w", "l", or "d" */
79 #endif
80 #ifdef DIS_MEM
81         uint_t          it_size:16;
82 #endif
83         uint_t          it_invalid64:1;         /* opcode invalid in amd64 */
84         uint_t          it_always64:1;          /* 64 bit when in 64 bit mode */
85         uint_t          it_invalid32:1;         /* invalid in IA32 */
86         uint_t          it_stackop:1;           /* push/pop stack operation */
87 } instable_t;
88
89 /*
90  * Instruction formats.
91  */
92 enum {
93         UNKNOWN,
94         MRw,
95         IMlw,
96         IMw,
97         IR,
98         OA,
99         AO,
100         MS,
101         SM,
102         Mv,
103         Mw,
104         M,              /* register or memory */
105         Mb,             /* register or memory, always byte sized */
106         MO,             /* memory only (no registers) */
107         PREF,
108         SWAPGS,
109         R,
110         RA,
111         SEG,
112         MR,
113         RM,
114         IA,
115         MA,
116         SD,
117         AD,
118         SA,
119         D,
120         INM,
121         SO,
122         BD,
123         I,
124         P,
125         V,
126         DSHIFT,         /* for double shift that has an 8-bit immediate */
127         U,
128         OVERRIDE,
129         NORM,           /* instructions w/o ModR/M byte, no memory access */
130         IMPLMEM,        /* instructions w/o ModR/M byte, implicit mem access */
131         O,              /* for call     */
132         JTAB,           /* jump table   */
133         IMUL,           /* for 186 iimul instr  */
134         CBW,            /* so data16 can be evaluated for cbw and variants */
135         MvI,            /* for 186 logicals */
136         ENTER,          /* for 186 enter instr  */
137         RMw,            /* for 286 arpl instr */
138         Ib,             /* for push immediate byte */
139         F,              /* for 287 instructions */
140         FF,             /* for 287 instructions */
141         FFC,            /* for 287 instructions */
142         DM,             /* 16-bit data */
143         AM,             /* 16-bit addr */
144         LSEG,           /* for 3-bit seg reg encoding */
145         MIb,            /* for 386 logicals */
146         SREG,           /* for 386 special registers */
147         PREFIX,         /* a REP instruction prefix */
148         LOCK,           /* a LOCK instruction prefix */
149         INT3,           /* The int 3 instruction, which has a fake operand */
150         INTx,           /* The normal int instruction, with explicit int num */
151         DSHIFTcl,       /* for double shift that implicitly uses %cl */
152         CWD,            /* so data16 can be evaluated for cwd and variants */
153         RET,            /* single immediate 16-bit operand */
154         MOVZ,           /* for movs and movz, with different size operands */
155         XADDB,          /* for xaddb */
156         MOVSXZ,         /* AMD64 mov sign extend 32 to 64 bit instruction */
157
158 /*
159  * MMX/SIMD addressing modes.
160  */
161
162         MMO,            /* Prefixable MMX/SIMD-Int      mm/mem  -> mm */
163         MMOIMPL,        /* Prefixable MMX/SIMD-Int      mm      -> mm (mem) */
164         MMO3P,          /* Prefixable MMX/SIMD-Int      mm      -> r32,imm8 */
165         MMOM3,          /* Prefixable MMX/SIMD-Int      mm      -> r32  */
166         MMOS,           /* Prefixable MMX/SIMD-Int      mm      -> mm/mem */
167         MMOMS,          /* Prefixable MMX/SIMD-Int      mm      -> mem */
168         MMOPM,          /* MMX/SIMD-Int                 mm/mem  -> mm,imm8 */
169         MMOPRM,         /* Prefixable MMX/SIMD-Int      r32/mem -> mm,imm8 */
170         MMOSH,          /* Prefixable MMX               mm,imm8 */
171         MM,             /* MMX/SIMD-Int                 mm/mem  -> mm   */
172         MMS,            /* MMX/SIMD-Int                 mm      -> mm/mem */
173         MMSH,           /* MMX                          mm,imm8 */
174         XMMO,           /* Prefixable SIMD              xmm/mem -> xmm */
175         XMMOS,          /* Prefixable SIMD              xmm     -> xmm/mem */
176         XMMOPM,         /* Prefixable SIMD              xmm/mem w/to xmm,imm8 */
177         XMMOMX,         /* Prefixable SIMD              mm/mem  -> xmm */
178         XMMOX3,         /* Prefixable SIMD              xmm     -> r32 */
179         XMMOXMM,        /* Prefixable SIMD              xmm/mem -> mm   */
180         XMMOM,          /* Prefixable SIMD              xmm     -> mem */
181         XMMOMS,         /* Prefixable SIMD              mem     -> xmm */
182         XMM,            /* SIMD                         xmm/mem -> xmm */
183         XMMXIMPL,       /* SIMD                         xmm     -> xmm (mem) */
184         XMM3P,          /* SIMD                         xmm     -> r32,imm8 */
185         XMMP,           /* SIMD                         xmm/mem w/to xmm,imm8 */
186         XMMPRM,         /* SIMD                         r32/mem -> xmm,imm8 */
187         XMMS,           /* SIMD                         xmm     -> xmm/mem */
188         XMMM,           /* SIMD                         mem     -> xmm */
189         XMMMS,          /* SIMD                         xmm     -> mem */
190         XMM3MX,         /* SIMD                         r32/mem -> xmm */
191         XMM3MXS,        /* SIMD                         xmm     -> r32/mem */
192         XMMSH,          /* SIMD                         xmm,imm8 */
193         XMMXM3,         /* SIMD                         xmm/mem -> r32 */
194         XMMX3,          /* SIMD                         xmm     -> r32 */
195         XMMXMM,         /* SIMD                         xmm/mem -> mm */
196         XMMMX,          /* SIMD                         mm      -> xmm */
197         XMMXM,          /* SIMD                         xmm     -> mm */
198         XMMFENCE,       /* SIMD lfence or mfence */
199         XMMSFNC         /* SIMD sfence (none or mem) */
200 };
201
202 #define FILL    0x90    /* Fill byte used for alignment (nop)   */
203
204 /*
205 ** Register numbers for the i386
206 */
207 #define EAX_REGNO 0
208 #define ECX_REGNO 1
209 #define EDX_REGNO 2
210 #define EBX_REGNO 3
211 #define ESP_REGNO 4
212 #define EBP_REGNO 5
213 #define ESI_REGNO 6
214 #define EDI_REGNO 7
215
216 /*
217  * modes for immediate values
218  */
219 #define MODE_NONE       0
220 #define MODE_IPREL      1       /* signed IP relative value */
221 #define MODE_SIGNED     2       /* sign extended immediate */
222 #define MODE_IMPLIED    3       /* constant value implied from opcode */
223 #define MODE_OFFSET     4       /* offset part of an address */
224
225 /*
226  * The letters used in these macros are:
227  *   IND - indirect to another to another table
228  *   "T" - means to Terminate indirections (this is the final opcode)
229  *   "S" - means "operand length suffix required"
230  *   "NS" - means "no suffix" which is the operand length suffix of the opcode
231  *   "Z" - means instruction size arg required
232  *   "u" - means the opcode is invalid in IA32 but valid in amd64
233  *   "x" - means the opcode is invalid in amd64, but not IA32
234  *   "y" - means the operand size is always 64 bits in 64 bit mode
235  *   "p" - means push/pop stack operation
236  */
237
238 #if defined(DIS_TEXT) && defined(DIS_MEM)
239 #define IND(table)              {table, 0, "", 0, 0, 0, 0, 0, 0}
240 #define INDx(table)             {table, 0, "", 0, 0, 1, 0, 0, 0}
241 #define TNS(name, amode)        {TERM, amode, name, 0, 0, 0, 0, 0, 0}
242 #define TNSu(name, amode)       {TERM, amode, name, 0, 0, 0, 0, 1, 0}
243 #define TNSx(name, amode)       {TERM, amode, name, 0, 0, 1, 0, 0, 0}
244 #define TNSy(name, amode)       {TERM, amode, name, 0, 0, 0, 1, 0, 0}
245 #define TNSyp(name, amode)      {TERM, amode, name, 0, 0, 0, 1, 0, 1}
246 #define TNSZ(name, amode, sz)   {TERM, amode, name, 0, sz, 0, 0, 0, 0}
247 #define TNSZy(name, amode, sz)  {TERM, amode, name, 0, sz, 0, 1, 0, 0}
248 #define TS(name, amode)         {TERM, amode, name, 1, 0, 0, 0, 0, 0}
249 #define TSx(name, amode)        {TERM, amode, name, 1, 0, 1, 0, 0, 0}
250 #define TSy(name, amode)        {TERM, amode, name, 1, 0, 0, 1, 0, 0}
251 #define TSp(name, amode)        {TERM, amode, name, 1, 0, 0, 0, 0, 1}
252 #define TSZ(name, amode, sz)    {TERM, amode, name, 1, sz, 0, 0, 0, 0}
253 #define TSZx(name, amode, sz)   {TERM, amode, name, 1, sz, 1, 0, 0, 0}
254 #define TSZy(name, amode, sz)   {TERM, amode, name, 1, sz, 0, 1, 0, 0}
255 #define INVALID                 {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
256 #elif defined(DIS_TEXT)
257 #define IND(table)              {table, 0, "", 0, 0, 0, 0, 0}
258 #define INDx(table)             {table, 0, "", 0, 1, 0, 0, 0}
259 #define TNS(name, amode)        {TERM, amode, name, 0, 0, 0, 0, 0}
260 #define TNSu(name, amode)       {TERM, amode, name, 0, 0, 0, 1, 0}
261 #define TNSx(name, amode)       {TERM, amode, name, 0, 1, 0, 0, 0}
262 #define TNSy(name, amode)       {TERM, amode, name, 0, 0, 1, 0, 0}
263 #define TNSyp(name, amode)      {TERM, amode, name, 0, 0, 1, 0, 1}
264 #define TNSZ(name, amode, sz)   {TERM, amode, name, 0, 0, 0, 0, 0}
265 #define TNSZy(name, amode, sz)  {TERM, amode, name, 0, 0, 1, 0, 0}
266 #define TS(name, amode)         {TERM, amode, name, 1, 0, 0, 0, 0}
267 #define TSx(name, amode)        {TERM, amode, name, 1, 1, 0, 0, 0}
268 #define TSy(name, amode)        {TERM, amode, name, 1, 0, 1, 0, 0}
269 #define TSp(name, amode)        {TERM, amode, name, 1, 0, 0, 0, 1}
270 #define TSZ(name, amode, sz)    {TERM, amode, name, 1, 0, 0, 0, 0}
271 #define TSZx(name, amode, sz)   {TERM, amode, name, 1, 1, 0, 0, 0}
272 #define TSZy(name, amode, sz)   {TERM, amode, name, 1, 0, 1, 0, 0}
273 #define INVALID                 {TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
274 #elif defined(DIS_MEM)
275 #define IND(table)              {table, 0, 0, 0, 0, 0, 0}
276 #define INDx(table)             {table, 0, 0, 1, 0, 0, 0}
277 #define TNS(name, amode)        {TERM, amode,  0, 0, 0, 0, 0}
278 #define TNSu(name, amode)       {TERM, amode,  0, 0, 0, 1, 0}
279 #define TNSy(name, amode)       {TERM, amode,  0, 0, 1, 0, 0}
280 #define TNSyp(name, amode)      {TERM, amode,  0, 0, 1, 0, 1}
281 #define TNSx(name, amode)       {TERM, amode,  0, 1, 0, 0, 0}
282 #define TNSZ(name, amode, sz)   {TERM, amode, sz, 0, 0, 0, 0}
283 #define TNSZy(name, amode, sz)  {TERM, amode, sz, 0, 1, 0, 0}
284 #define TS(name, amode)         {TERM, amode,  0, 0, 0, 0, 0}
285 #define TSx(name, amode)        {TERM, amode,  0, 1, 0, 0, 0}
286 #define TSy(name, amode)        {TERM, amode,  0, 0, 1, 0, 0}
287 #define TSp(name, amode)        {TERM, amode,  0, 0, 0, 0, 1}
288 #define TSZ(name, amode, sz)    {TERM, amode, sz, 0, 0, 0, 0}
289 #define TSZx(name, amode, sz)   {TERM, amode, sz, 1, 0, 0, 0}
290 #define TSZy(name, amode, sz)   {TERM, amode, sz, 0, 1, 0, 0}
291 #define INVALID                 {TERM, UNKNOWN, 0, 0, 0, 0, 0}
292 #else
293 #define IND(table)              {table[0], 0, 0, 0, 0, 0}
294 #define INDx(table)             {table[0], 0, 1, 0, 0, 0}
295 #define TNS(name, amode)        {TERM, amode,  0, 0, 0, 0}
296 #define TNSu(name, amode)       {TERM, amode,  0, 0, 1, 0}
297 #define TNSy(name, amode)       {TERM, amode,  0, 1, 0, 0}
298 #define TNSyp(name, amode)      {TERM, amode,  0, 1, 0, 1}
299 #define TNSx(name, amode)       {TERM, amode,  1, 0, 0, 0}
300 #define TNSZ(name, amode, sz)   {TERM, amode,  0, 0, 0, 0}
301 #define TNSZy(name, amode, sz)  {TERM, amode,  0, 1, 0, 0}
302 #define TS(name, amode)         {TERM, amode,  0, 0, 0, 0}
303 #define TSx(name, amode)        {TERM, amode,  1, 0, 0, 0}
304 #define TSy(name, amode)        {TERM, amode,  0, 1, 0, 0}
305 #define TSp(name, amode)        {TERM, amode,  0, 0, 0, 1}
306 #define TSZ(name, amode, sz)    {TERM, amode,  0, 0, 0, 0}
307 #define TSZx(name, amode, sz)   {TERM, amode,  1, 0, 0, 0}
308 #define TSZy(name, amode, sz)   {TERM, amode,  0, 1, 0, 0}
309 #define INVALID                 {TERM, UNKNOWN, 0, 0, 0, 0}
310 #endif
311
312 #ifdef DIS_TEXT
313 /*
314  * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
315  */
316 const char *const dis_addr16[3][8] = {
317 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
318                                                                         "(%bx)",
319 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
320                                                                         "(%bx)",
321 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
322                                                                         "(%bx)",
323 };
324
325
326 /*
327  * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
328  */
329 const char *const dis_addr32_mode0[16] = {
330   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
331   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
332 };
333
334 const char *const dis_addr32_mode12[16] = {
335   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
336   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
337 };
338
339 /*
340  * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
341  */
342 const char *const dis_addr64_mode0[16] = {
343  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
344  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
345 };
346 const char *const dis_addr64_mode12[16] = {
347  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
348  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
349 };
350
351 /*
352  * decode for scale from SIB byte
353  */
354 const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
355
356 /*
357  * register decoding for normal references to registers (ie. not addressing)
358  */
359 const char *const dis_REG8[16] = {
360         "%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
361         "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
362 };
363
364 const char *const dis_REG8_REX[16] = {
365         "%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
366         "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
367 };
368
369 const char *const dis_REG16[16] = {
370         "%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
371         "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
372 };
373
374 const char *const dis_REG32[16] = {
375         "%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
376         "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
377 };
378
379 const char *const dis_REG64[16] = {
380         "%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
381         "%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
382 };
383
384 const char *const dis_DEBUGREG[16] = {
385         "%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
386         "%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
387 };
388
389 const char *const dis_CONTROLREG[16] = {
390     "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
391     "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
392 };
393
394 const char *const dis_TESTREG[16] = {
395         "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
396         "%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
397 };
398
399 const char *const dis_MMREG[16] = {
400         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
401         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
402 };
403
404 const char *const dis_XMMREG[16] = {
405     "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
406     "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
407 };
408
409 const char *const dis_SEGREG[16] = {
410         "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
411         "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
412 };
413
414 /*
415  * SIMD predicate suffixes
416  */
417 const char *const dis_PREDSUFFIX[8] = {
418         "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
419 };
420
421
422
423 #endif  /* DIS_TEXT */
424
425
426
427
428 /*
429  *      "decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
430  */
431 const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
432
433 /*
434  *      "decode table" for pause and clflush instructions
435  */
436 const instable_t dis_opPause = TNS("pause", NORM);
437
438 /*
439  *      Decode table for 0x0F00 opcodes
440  */
441 const instable_t dis_op0F00[8] = {
442
443 /*  [0]  */     TNS("sldt",M),          TNS("str",M),           TNSy("lldt",M),         TNSy("ltr",M),
444 /*  [4]  */     TNSZ("verr",M,2),       TNSZ("verw",M,2),       INVALID,                INVALID,
445 };
446
447
448 /*
449  *      Decode table for 0x0F01 opcodes
450  */
451 const instable_t dis_op0F01[8] = {
452
453 /*  [0]  */     TNSZ("sgdt",MO,6),      TNSZ("sidt",MO,6),      TNSZ("lgdt",MO,6),      TNSZ("lidt",MO,6),
454 /*  [4]  */     TNSZ("smsw",M,2),       INVALID,                TNSZ("lmsw",M,2),       TNS("invlpg",SWAPGS),
455 };
456
457 /*
458  *      Decode table for 0x0F18 opcodes -- SIMD prefetch
459  */
460 const instable_t dis_op0F18[8] = {
461
462 /*  [0]  */     TNS("prefetchnta",PREF),TNS("prefetcht0",PREF), TNS("prefetcht1",PREF), TNS("prefetcht2",PREF),
463 /*  [4]  */     INVALID,                INVALID,                INVALID,                INVALID,
464 };
465
466 /*
467  *      Decode table for 0x0FAE opcodes -- SIMD state save/restore
468  */
469 const instable_t dis_op0FAE[8] = {
470 /*  [0]  */     TNSZ("fxsave",M,512),   TNSZ("fxrstor",M,512),  TNS("ldmxcsr",M),       TNS("stmxcsr",M),
471 /*  [4]  */     INVALID,                TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE), TNS("sfence",XMMSFNC),
472 };
473
474 /*
475  *      Decode table for 0x0FBA opcodes
476  */
477
478 const instable_t dis_op0FBA[8] = {
479
480 /*  [0]  */     INVALID,                INVALID,                INVALID,                INVALID,
481 /*  [4]  */     TS("bt",MIb),           TS("bts",MIb),          TS("btr",MIb),          TS("btc",MIb),
482 };
483
484 /*
485  *      Decode table for 0x0FC7 opcode
486  */
487
488 const instable_t dis_op0FC7[8] = {
489
490 /*  [0]  */     INVALID,                TNS("cmpxchg8b",M),     INVALID,                INVALID,
491 /*  [4]  */     INVALID,                INVALID,        INVALID,                 INVALID,
492 };
493
494
495 /*
496  *      Decode table for 0x0FC8 opcode -- 486 bswap instruction
497  *
498  *bit pattern: 0000 1111 1100 1reg
499  */
500 const instable_t dis_op0FC8[4] = {
501 /*  [0]  */     TNS("bswap",R),         INVALID,                INVALID,                INVALID,
502 };
503
504 /*
505  *      Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
506  */
507 const instable_t dis_op0F7123[4][8] = {
508 {
509 /*  [70].0 */   INVALID,                INVALID,                INVALID,                INVALID,
510 /*      .4 */   INVALID,                INVALID,                INVALID,                INVALID,
511 }, {
512 /*  [71].0 */   INVALID,                INVALID,                TNS("psrlw",MMOSH),     INVALID,
513 /*      .4 */   TNS("psraw",MMOSH),     INVALID,                TNS("psllw",MMOSH),     INVALID,
514 }, {
515 /*  [72].0 */   INVALID,                INVALID,                TNS("psrld",MMOSH),     INVALID,
516 /*      .4 */   TNS("psrad",MMOSH),     INVALID,                TNS("pslld",MMOSH),     INVALID,
517 }, {
518 /*  [73].0 */   INVALID,                INVALID,                TNS("psrlq",MMOSH),     TNS("INVALID",MMOSH),
519 /*      .4 */   INVALID,                INVALID,                TNS("psllq",MMOSH),     TNS("INVALID",MMOSH),
520 } };
521
522 /*
523  *      Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
524  */
525 const instable_t dis_opSIMD7123[32] = {
526 /* [70].0 */    INVALID,                INVALID,                INVALID,                INVALID,
527 /*     .4 */    INVALID,                INVALID,                INVALID,                INVALID,
528
529 /* [71].0 */    INVALID,                INVALID,                TNS("psrlw",XMMSH),     INVALID,
530 /*     .4 */    TNS("psraw",XMMSH),     INVALID,                TNS("psllw",XMMSH),     INVALID,
531
532 /* [72].0 */    INVALID,                INVALID,                TNS("psrld",XMMSH),     INVALID,
533 /*     .4 */    TNS("psrad",XMMSH),     INVALID,                TNS("pslld",XMMSH),     INVALID,
534
535 /* [73].0 */    INVALID,                INVALID,                TNS("psrlq",XMMSH),     TNS("psrldq",XMMSH),
536 /*     .4 */    INVALID,                INVALID,                TNS("psllq",XMMSH),     TNS("pslldq",XMMSH),
537 };
538
539 /*
540  *      SIMD instructions have been wedged into the existing IA32 instruction
541  *      set through the use of prefixes.  That is, while 0xf0 0x58 may be
542  *      addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
543  *      instruction - addss.  At present, three prefixes have been coopted in
544  *      this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
545  *      following tables are used to provide the prefixed instruction names.
546  *      The arrays are sparse, but they're fast.
547  */
548
549 /*
550  *      Decode table for SIMD instructions with the address size (0x66) prefix.
551  */
552 const instable_t dis_opSIMDdata16[256] = {
553 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
554 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
555 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
556 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
557
558 /*  [10]  */    TNSZ("movupd",XMM,16),  TNSZ("movupd",XMMS,16), TNSZ("movlpd",XMMM,8),  TNSZ("movlpd",XMMMS,8),
559 /*  [14]  */    TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),  TNSZ("movhpd",XMMMS,8),
560 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
561 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
562
563 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
564 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
565 /*  [28]  */    TNSZ("movapd",XMM,16),  TNSZ("movapd",XMMS,16), TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
566 /*  [2C]  */    TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
567
568 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
569 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
570 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
571 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
572
573 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
574 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
575 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
576 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
577
578 /*  [50]  */    TNS("movmskpd",XMMOX3), TNSZ("sqrtpd",XMM,16),  INVALID,                INVALID,
579 /*  [54]  */    TNSZ("andpd",XMM,16),   TNSZ("andnpd",XMM,16),  TNSZ("orpd",XMM,16),    TNSZ("xorpd",XMM,16),
580 /*  [58]  */    TNSZ("addpd",XMM,16),   TNSZ("mulpd",XMM,16),   TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
581 /*  [5C]  */    TNSZ("subpd",XMM,16),   TNSZ("minpd",XMM,16),   TNSZ("divpd",XMM,16),   TNSZ("maxpd",XMM,16),
582
583 /*  [60]  */    TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
584 /*  [64]  */    TNSZ("pcmpgtb",XMM,16), TNSZ("pcmpgtw",XMM,16), TNSZ("pcmpgtd",XMM,16), TNSZ("packuswb",XMM,16),
585 /*  [68]  */    TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
586 /*  [6C]  */    TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
587
588 /*  [70]  */    TNSZ("pshufd",XMMP,16), INVALID,                INVALID,                INVALID,
589 /*  [74]  */    TNSZ("pcmpeqb",XMM,16), TNSZ("pcmpeqw",XMM,16), TNSZ("pcmpeqd",XMM,16), INVALID,
590 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
591 /*  [7C]  */    INVALID,                INVALID,                TNSZ("movd",XMM3MXS,4), TNSZ("movdqa",XMMS,16),
592
593 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
594 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
595 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
596 /*  [8C]  */    INVALID,                INVALID,                INVALID,                INVALID,
597
598 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
599 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
600 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
601 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
602
603 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
604 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
605 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
606 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
607
608 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
609 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
610 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
611 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
612
613 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmppd",XMMP,16),  INVALID,
614 /*  [C4]  */    TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),    TNSZ("shufpd",XMMP,16), INVALID,
615 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
616 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
617
618 /*  [D0]  */    INVALID,                TNSZ("psrlw",XMM,16),   TNSZ("psrld",XMM,16),   TNSZ("psrlq",XMM,16),
619 /*  [D4]  */    TNSZ("paddq",XMM,16),   TNSZ("pmullw",XMM,16),  TNSZ("movq",XMMS,8),    TNS("pmovmskb",XMMX3),
620 /*  [D8]  */    TNSZ("psubusb",XMM,16), TNSZ("psubusw",XMM,16), TNSZ("pminub",XMM,16),  TNSZ("pand",XMM,16),
621 /*  [DC]  */    TNSZ("paddusb",XMM,16), TNSZ("paddusw",XMM,16), TNSZ("pmaxub",XMM,16),  TNSZ("pandn",XMM,16),
622
623 /*  [E0]  */    TNSZ("pavgb",XMM,16),   TNSZ("psraw",XMM,16),   TNSZ("psrad",XMM,16),   TNSZ("pavgw",XMM,16),
624 /*  [E4]  */    TNSZ("pmulhuw",XMM,16), TNSZ("pmulhw",XMM,16),  TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
625 /*  [E8]  */    TNSZ("psubsb",XMM,16),  TNSZ("psubsw",XMM,16),  TNSZ("pminsw",XMM,16),  TNSZ("por",XMM,16),
626 /*  [EC]  */    TNSZ("paddsb",XMM,16),  TNSZ("paddsw",XMM,16),  TNSZ("pmaxsw",XMM,16),  TNSZ("pxor",XMM,16),
627
628 /*  [F0]  */    INVALID,                TNSZ("psllw",XMM,16),   TNSZ("pslld",XMM,16),   TNSZ("psllq",XMM,16),
629 /*  [F4]  */    TNSZ("pmuludq",XMM,16), TNSZ("pmaddwd",XMM,16), TNSZ("psadbw",XMM,16),  TNSZ("maskmovdqu", XMMXIMPL,16),
630 /*  [F8]  */    TNSZ("psubb",XMM,16),   TNSZ("psubw",XMM,16),   TNSZ("psubd",XMM,16),   TNSZ("psubq",XMM,16),
631 /*  [FC]  */    TNSZ("paddb",XMM,16),   TNSZ("paddw",XMM,16),   TNSZ("paddd",XMM,16),   INVALID,
632 };
633
634 /*
635  *      Decode table for SIMD instructions with the repnz (0xf2) prefix.
636  */
637 const instable_t dis_opSIMDrepnz[256] = {
638 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
639 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
640 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
641 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
642
643 /*  [10]  */    TNSZ("movsd",XMM,8),    TNSZ("movsd",XMMS,8),   INVALID,                INVALID,
644 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
645 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
646 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
647
648 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
649 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
650 /*  [28]  */    INVALID,                INVALID,                TNSZ("cvtsi2sd",XMM3MX,4),INVALID,
651 /*  [2C]  */    TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,           INVALID,
652
653 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
654 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
655 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
656 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
657
658 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
659 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
660 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
661 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
662
663 /*  [50]  */    INVALID,                TNSZ("sqrtsd",XMM,8),   INVALID,                INVALID,
664 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
665 /*  [58]  */    TNSZ("addsd",XMM,8),    TNSZ("mulsd",XMM,8),    TNSZ("cvtsd2ss",XMM,8), INVALID,
666 /*  [5C]  */    TNSZ("subsd",XMM,8),    TNSZ("minsd",XMM,8),    TNSZ("divsd",XMM,8),    TNSZ("maxsd",XMM,8),
667
668 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
669 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
670 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
671 /*  [6C]  */    INVALID,                INVALID,                INVALID,                INVALID,
672
673 /*  [70]  */    TNSZ("pshuflw",XMMP,16),INVALID,                INVALID,                INVALID,
674 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
675 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
676 /*  [7C]  */    INVALID,                INVALID,                INVALID,                INVALID,
677
678 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
679 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
680 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
681 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
682
683 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
684 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
685 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
686 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
687
688 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
689 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
690 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
691 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
692
693 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
694 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
695 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
696 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
697
698 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmpsd",XMMP,8),   INVALID,
699 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
700 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
701 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
702
703 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
704 /*  [D4]  */    INVALID,                INVALID,                TNS("movdq2q",XMMXM),   INVALID,
705 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
706 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
707
708 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
709 /*  [E4]  */    INVALID,                INVALID,                TNSZ("cvtpd2dq",XMM,16),INVALID,
710 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
711 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
712
713 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
714 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
715 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
716 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
717 };
718
719 /*
720  *      Decode table for SIMD instructions with the repz (0xf3) prefix.
721  */
722 const instable_t dis_opSIMDrepz[256] = {
723 /*  [00]  */    INVALID,                INVALID,                INVALID,                INVALID,
724 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
725 /*  [08]  */    INVALID,                INVALID,                INVALID,                INVALID,
726 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
727
728 /*  [10]  */    TNSZ("movss",XMM,4),    TNSZ("movss",XMMS,4),   INVALID,                INVALID,
729 /*  [14]  */    INVALID,                INVALID,                INVALID,                INVALID,
730 /*  [18]  */    INVALID,                INVALID,                INVALID,                INVALID,
731 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
732
733 /*  [20]  */    INVALID,                INVALID,                INVALID,                INVALID,
734 /*  [24]  */    INVALID,                INVALID,                INVALID,                INVALID,
735 /*  [28]  */    INVALID,                INVALID,                TNSZ("cvtsi2ss",XMM3MX,4),INVALID,
736 /*  [2C]  */    TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,           INVALID,
737
738 /*  [30]  */    INVALID,                INVALID,                INVALID,                INVALID,
739 /*  [34]  */    INVALID,                INVALID,                INVALID,                INVALID,
740 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
741 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
742
743 /*  [40]  */    INVALID,                INVALID,                INVALID,                INVALID,
744 /*  [44]  */    INVALID,                INVALID,                INVALID,                INVALID,
745 /*  [48]  */    INVALID,                INVALID,                INVALID,                INVALID,
746 /*  [4C]  */    INVALID,                INVALID,                INVALID,                INVALID,
747
748 /*  [50]  */    INVALID,                TNSZ("sqrtss",XMM,4),   TNSZ("rsqrtss",XMM,4),  TNSZ("rcpss",XMM,4),
749 /*  [54]  */    INVALID,                INVALID,                INVALID,                INVALID,
750 /*  [58]  */    TNSZ("addss",XMM,4),    TNSZ("mulss",XMM,4),    TNSZ("cvtss2sd",XMM,4), TNSZ("cvttps2dq",XMM,16),
751 /*  [5C]  */    TNSZ("subss",XMM,4),    TNSZ("minss",XMM,4),    TNSZ("divss",XMM,4),    TNSZ("maxss",XMM,4),
752
753 /*  [60]  */    INVALID,                INVALID,                INVALID,                INVALID,
754 /*  [64]  */    INVALID,                INVALID,                INVALID,                INVALID,
755 /*  [68]  */    INVALID,                INVALID,                INVALID,                INVALID,
756 /*  [6C]  */    INVALID,                INVALID,                INVALID,                TNSZ("movdqu",XMM,16),
757
758 /*  [70]  */    TNSZ("pshufhw",XMMP,16),INVALID,                INVALID,                INVALID,
759 /*  [74]  */    INVALID,                INVALID,                INVALID,                INVALID,
760 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
761 /*  [7C]  */    INVALID,                INVALID,                TNSZ("movq",XMM,8),     TNSZ("movdqu",XMMS,16),
762
763 /*  [80]  */    INVALID,                INVALID,                INVALID,                INVALID,
764 /*  [84]  */    INVALID,                INVALID,                INVALID,                INVALID,
765 /*  [88]  */    INVALID,                INVALID,                INVALID,                INVALID,
766 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
767
768 /*  [90]  */    INVALID,                INVALID,                INVALID,                INVALID,
769 /*  [94]  */    INVALID,                INVALID,                INVALID,                INVALID,
770 /*  [98]  */    INVALID,                INVALID,                INVALID,                INVALID,
771 /*  [9C]  */    INVALID,                INVALID,                INVALID,                INVALID,
772
773 /*  [A0]  */    INVALID,                INVALID,                INVALID,                INVALID,
774 /*  [A4]  */    INVALID,                INVALID,                INVALID,                INVALID,
775 /*  [A8]  */    INVALID,                INVALID,                INVALID,                INVALID,
776 /*  [AC]  */    INVALID,                INVALID,                INVALID,                INVALID,
777
778 /*  [B0]  */    INVALID,                INVALID,                INVALID,                INVALID,
779 /*  [B4]  */    INVALID,                INVALID,                INVALID,                INVALID,
780 /*  [B8]  */    INVALID,                INVALID,                INVALID,                INVALID,
781 /*  [BC]  */    INVALID,                INVALID,                INVALID,                INVALID,
782
783 /*  [C0]  */    INVALID,                INVALID,                TNSZ("cmpss",XMMP,4),   INVALID,
784 /*  [C4]  */    INVALID,                INVALID,                INVALID,                INVALID,
785 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
786 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
787
788 /*  [D0]  */    INVALID,                INVALID,                INVALID,                INVALID,
789 /*  [D4]  */    INVALID,                INVALID,                TNS("movq2dq",XMMMX),   INVALID,
790 /*  [D8]  */    INVALID,                INVALID,                INVALID,                INVALID,
791 /*  [DC]  */    INVALID,                INVALID,                INVALID,                INVALID,
792
793 /*  [E0]  */    INVALID,                INVALID,                INVALID,                INVALID,
794 /*  [E4]  */    INVALID,                INVALID,                TNSZ("cvtdq2pd",XMM,8), INVALID,
795 /*  [E8]  */    INVALID,                INVALID,                INVALID,                INVALID,
796 /*  [EC]  */    INVALID,                INVALID,                INVALID,                INVALID,
797
798 /*  [F0]  */    INVALID,                INVALID,                INVALID,                INVALID,
799 /*  [F4]  */    INVALID,                INVALID,                INVALID,                INVALID,
800 /*  [F8]  */    INVALID,                INVALID,                INVALID,                INVALID,
801 /*  [FC]  */    INVALID,                INVALID,                INVALID,                INVALID,
802 };
803
804 /*
805  *      Decode table for 0x0F opcodes
806  */
807
808 const instable_t dis_op0F[16][16] = {
809 {
810 /*  [00]  */    IND(dis_op0F00),        IND(dis_op0F01),        TNS("lar",MR),          TNS("lsl",MR),
811 /*  [04]  */    INVALID,                TNS("syscall",NORM),    TNS("clts",NORM),       TNS("sysret",NORM),
812 /*  [08]  */    TNS("invd",NORM),       TNS("wbinvd",NORM),     INVALID,                TNS("ud2",NORM),
813 /*  [0C]  */    INVALID,                INVALID,                INVALID,                INVALID,
814 }, {
815 /*  [10]  */    TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),  TNSZ("movlps",XMMOS,8),
816 /*  [14]  */    TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
817 /*  [18]  */    IND(dis_op0F18),        INVALID,                INVALID,                INVALID,
818 /*  [1C]  */    INVALID,                INVALID,                INVALID,                INVALID,
819 }, {
820 /*  [20]  */    TSy("mov",SREG),        TSy("mov",SREG),        TSy("mov",SREG),        TSy("mov",SREG),
821 /*  [24]  */    TSx("mov",SREG),        INVALID,                TSx("mov",SREG),        INVALID,
822 /*  [28]  */    TNSZ("movaps",XMMO,16), TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
823 /*  [2C]  */    TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
824 }, {
825 /*  [30]  */    TNS("wrmsr",NORM),      TNS("rdtsc",NORM),      TNS("rdmsr",NORM),      TNS("rdpmc",NORM),
826 /*  [34]  */    TNSx("sysenter",NORM),  TNSx("sysexit",NORM),   INVALID,                INVALID,
827 /*  [38]  */    INVALID,                INVALID,                INVALID,                INVALID,
828 /*  [3C]  */    INVALID,                INVALID,                INVALID,                INVALID,
829 }, {
830 /*  [40]  */    TS("cmovx.o",MR),       TS("cmovx.no",MR),      TS("cmovx.b",MR),       TS("cmovx.ae",MR),
831 /*  [44]  */    TS("cmovx.e",MR),       TS("cmovx.ne",MR),      TS("cmovx.be",MR),      TS("cmovx.a",MR),
832 /*  [48]  */    TS("cmovx.s",MR),       TS("cmovx.ns",MR),      TS("cmovx.pe",MR),      TS("cmovx.po",MR),
833 /*  [4C]  */    TS("cmovx.l",MR),       TS("cmovx.ge",MR),      TS("cmovx.le",MR),      TS("cmovx.g",MR),
834 }, {
835 /*  [50]  */    TNS("movmskps",XMMOX3), TNSZ("sqrtps",XMMO,16), TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
836 /*  [54]  */    TNSZ("andps",XMMO,16),  TNSZ("andnps",XMMO,16), TNSZ("orps",XMMO,16),   TNSZ("xorps",XMMO,16),
837 /*  [58]  */    TNSZ("addps",XMMO,16),  TNSZ("mulps",XMMO,16),  TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
838 /*  [5C]  */    TNSZ("subps",XMMO,16),  TNSZ("minps",XMMO,16),  TNSZ("divps",XMMO,16),  TNSZ("maxps",XMMO,16),
839 }, {
840 /*  [60]  */    TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
841 /*  [64]  */    TNSZ("pcmpgtb",MMO,8),  TNSZ("pcmpgtw",MMO,8),  TNSZ("pcmpgtd",MMO,8),  TNSZ("packuswb",MMO,8),
842 /*  [68]  */    TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
843 /*  [6C]  */    TNSZ("INVALID",MMO,0),  TNSZ("INVALID",MMO,0),  TNSZ("movd",MMO,4),     TNSZ("movq",MMO,8),
844 }, {
845 /*  [70]  */    TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR),       TNS("psrXXX",MR),       TNS("psrXXX",MR),
846 /*  [74]  */    TNSZ("pcmpeqb",MMO,8),  TNSZ("pcmpeqw",MMO,8),  TNSZ("pcmpeqd",MMO,8),  TNS("emms",NORM),
847 /*  [78]  */    INVALID,                INVALID,                INVALID,                INVALID,
848 /*  [7C]  */    INVALID,                INVALID,                TNSZ("movd",MMOS,4),    TNSZ("movq",MMOS,8),
849 }, {
850 /*  [80]  */    TNS("jo",D),            TNS("jno",D),           TNS("jb",D),            TNS("jae",D),
851 /*  [84]  */    TNS("je",D),            TNS("jne",D),           TNS("jbe",D),           TNS("ja",D),
852 /*  [88]  */    TNS("js",D),            TNS("jns",D),           TNS("jp",D),            TNS("jnp",D),
853 /*  [8C]  */    TNS("jl",D),            TNS("jge",D),           TNS("jle",D),           TNS("jg",D),
854 }, {
855 /*  [90]  */    TNS("seto",Mb),         TNS("setno",Mb),        TNS("setb",Mb),         TNS("setae",Mb),
856 /*  [94]  */    TNS("sete",Mb),         TNS("setne",Mb),        TNS("setbe",Mb),        TNS("seta",Mb),
857 /*  [98]  */    TNS("sets",Mb),         TNS("setns",Mb),        TNS("setp",Mb),         TNS("setnp",Mb),
858 /*  [9C]  */    TNS("setl",Mb),         TNS("setge",Mb),        TNS("setle",Mb),        TNS("setg",Mb),
859 }, {
860 /*  [A0]  */    TSp("push",LSEG),       TSp("pop",LSEG),        TNS("cpuid",NORM),      TS("bt",RMw),
861 /*  [A4]  */    TS("shld",DSHIFT),      TS("shld",DSHIFTcl),    INVALID,                INVALID,
862 /*  [A8]  */    TSp("push",LSEG),       TSp("pop",LSEG),        TNS("rsm",NORM),        TS("bts",RMw),
863 /*  [AC]  */    TS("shrd",DSHIFT),      TS("shrd",DSHIFTcl),    IND(dis_op0FAE),        TS("imul",MRw),
864 }, {
865 /*  [B0]  */    TNS("cmpxchgb",RMw),    TS("cmpxchg",RMw),      TS("lss",MR),           TS("btr",RMw),
866 /*  [B4]  */    TS("lfs",MR),           TS("lgs",MR),           TS("movzb",MOVZ),       TNS("movzwl",MOVZ),
867 /*  [B8]  */    INVALID,                INVALID,                IND(dis_op0FBA),        TS("btc",RMw),
868 /*  [BC]  */    TS("bsf",MRw),          TS("bsr",MRw),          TS("movsb",MOVZ),       TNS("movswl",MOVZ),
869 }, {
870 /*  [C0]  */    TNS("xaddb",XADDB),     TS("xadd",RMw),         TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
871 /*  [C4]  */    TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P),    TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
872 /*  [C8]  */    INVALID,                INVALID,                INVALID,                INVALID,
873 /*  [CC]  */    INVALID,                INVALID,                INVALID,                INVALID,
874 }, {
875 /*  [D0]  */    INVALID,                TNSZ("psrlw",MMO,8),    TNSZ("psrld",MMO,8),    TNSZ("psrlq",MMO,8),
876 /*  [D4]  */    TNSZ("paddq",MMO,8),    TNSZ("pmullw",MMO,8),   TNSZ("INVALID",MMO,0),  TNS("pmovmskb",MMOM3),
877 /*  [D8]  */    TNSZ("psubusb",MMO,8),  TNSZ("psubusw",MMO,8),  TNSZ("pminub",MMO,8),   TNSZ("pand",MMO,8),
878 /*  [DC]  */    TNSZ("paddusb",MMO,8),  TNSZ("paddusw",MMO,8),  TNSZ("pmaxub",MMO,8),   TNSZ("pandn",MMO,8),
879 }, {
880 /*  [E0]  */    TNSZ("pavgb",MMO,8),    TNSZ("psraw",MMO,8),    TNSZ("psrad",MMO,8),    TNSZ("pavgw",MMO,8),
881 /*  [E4]  */    TNSZ("pmulhuw",MMO,8),  TNSZ("pmulhw",MMO,8),   TNS("INVALID",XMMO),    TNSZ("movntq",MMOMS,8),
882 /*  [E8]  */    TNSZ("psubsb",MMO,8),   TNSZ("psubsw",MMO,8),   TNSZ("pminsw",MMO,8),   TNSZ("por",MMO,8),
883 /*  [EC]  */    TNSZ("paddsb",MMO,8),   TNSZ("paddsw",MMO,8),   TNSZ("pmaxsw",MMO,8),   TNSZ("pxor",MMO,8),
884 }, {
885 /*  [F0]  */    INVALID,                TNSZ("psllw",MMO,8),    TNSZ("pslld",MMO,8),    TNSZ("psllq",MMO,8),
886 /*  [F4]  */    TNSZ("pmuludq",MMO,8),  TNSZ("pmaddwd",MMO,8),  TNSZ("psadbw",MMO,8),   TNSZ("maskmovq",MMOIMPL,8),
887 /*  [F8]  */    TNSZ("psubb",MMO,8),    TNSZ("psubw",MMO,8),    TNSZ("psubd",MMO,8),    TNSZ("psubq",MMO,8),
888 /*  [FC]  */    TNSZ("paddb",MMO,8),    TNSZ("paddw",MMO,8),    TNSZ("paddd",MMO,8),    INVALID,
889 } };
890
891
892 /*
893  *      Decode table for 0x80 opcodes
894  */
895
896 const instable_t dis_op80[8] = {
897
898 /*  [0]  */     TNS("addb",IMlw),       TNS("orb",IMw),         TNS("adcb",IMlw),       TNS("sbbb",IMlw),
899 /*  [4]  */     TNS("andb",IMw),        TNS("subb",IMlw),       TNS("xorb",IMw),        TNS("cmpb",IMlw),
900 };
901
902
903 /*
904  *      Decode table for 0x81 opcodes.
905  */
906
907 const instable_t dis_op81[8] = {
908
909 /*  [0]  */     TS("add",IMlw),         TS("or",IMw),           TS("adc",IMlw),         TS("sbb",IMlw),
910 /*  [4]  */     TS("and",IMw),          TS("sub",IMlw),         TS("xor",IMw),          TS("cmp",IMlw),
911 };
912
913
914 /*
915  *      Decode table for 0x82 opcodes.
916  */
917
918 const instable_t dis_op82[8] = {
919
920 /*  [0]  */     TNSx("addb",IMlw),      TNSx("orb",IMlw),       TNSx("adcb",IMlw),      TNSx("sbbb",IMlw),
921 /*  [4]  */     TNSx("andb",IMlw),      TNSx("subb",IMlw),      TNSx("xorb",IMlw),      TNSx("cmpb",IMlw),
922 };
923 /*
924  *      Decode table for 0x83 opcodes.
925  */
926
927 const instable_t dis_op83[8] = {
928
929 /*  [0]  */     TS("add",IMlw),         TS("or",IMlw),          TS("adc",IMlw),         TS("sbb",IMlw),
930 /*  [4]  */     TS("and",IMlw),         TS("sub",IMlw),         TS("xor",IMlw),         TS("cmp",IMlw),
931 };
932
933 /*
934  *      Decode table for 0xC0 opcodes.
935  */
936
937 const instable_t dis_opC0[8] = {
938
939 /*  [0]  */     TNS("rolb",MvI),        TNS("rorb",MvI),        TNS("rclb",MvI),        TNS("rcrb",MvI),
940 /*  [4]  */     TNS("shlb",MvI),        TNS("shrb",MvI),        INVALID,                TNS("sarb",MvI),
941 };
942
943 /*
944  *      Decode table for 0xD0 opcodes.
945  */
946
947 const instable_t dis_opD0[8] = {
948
949 /*  [0]  */     TNS("rolb",Mv),         TNS("rorb",Mv),         TNS("rclb",Mv),         TNS("rcrb",Mv),
950 /*  [4]  */     TNS("shlb",Mv),         TNS("shrb",Mv),         TNS("salb",Mv),         TNS("sarb",Mv),
951 };
952
953 /*
954  *      Decode table for 0xC1 opcodes.
955  *      186 instruction set
956  */
957
958 const instable_t dis_opC1[8] = {
959
960 /*  [0]  */     TS("rol",MvI),          TS("ror",MvI),          TS("rcl",MvI),          TS("rcr",MvI),
961 /*  [4]  */     TS("shl",MvI),          TS("shr",MvI),          TS("sal",MvI),          TS("sar",MvI),
962 };
963
964 /*
965  *      Decode table for 0xD1 opcodes.
966  */
967
968 const instable_t dis_opD1[8] = {
969
970 /*  [0]  */     TS("rol",Mv),           TS("ror",Mv),           TS("rcl",Mv),           TS("rcr",Mv),
971 /*  [4]  */     TS("shl",Mv),           TS("shr",Mv),           TS("sal",Mv),           TS("sar",Mv),
972 };
973
974
975 /*
976  *      Decode table for 0xD2 opcodes.
977  */
978
979 const instable_t dis_opD2[8] = {
980
981 /*  [0]  */     TNS("rolb",Mv),         TNS("rorb",Mv),         TNS("rclb",Mv),         TNS("rcrb",Mv),
982 /*  [4]  */     TNS("shlb",Mv),         TNS("shrb",Mv),         TNS("salb",Mv),         TNS("sarb",Mv),
983 };
984 /*
985  *      Decode table for 0xD3 opcodes.
986  */
987
988 const instable_t dis_opD3[8] = {
989
990 /*  [0]  */     TS("rol",Mv),           TS("ror",Mv),           TS("rcl",Mv),           TS("rcr",Mv),
991 /*  [4]  */     TS("shl",Mv),           TS("shr",Mv),           TS("salb",Mv),          TS("sar",Mv),
992 };
993
994
995 /*
996  *      Decode table for 0xF6 opcodes.
997  */
998
999 const instable_t dis_opF6[8] = {
1000
1001 /*  [0]  */     TNS("testb",IMw),       TNS("testb",IMw),       TNS("notb",Mw),         TNS("negb",Mw),
1002 /*  [4]  */     TNS("mulb",MA),         TNS("imulb",MA),        TNS("divb",MA),         TNS("idivb",MA),
1003 };
1004
1005
1006 /*
1007  *      Decode table for 0xF7 opcodes.
1008  */
1009
1010 const instable_t dis_opF7[8] = {
1011
1012 /*  [0]  */     TS("test",IMw),         TS("test",IMw),         TS("not",Mw),           TS("neg",Mw),
1013 /*  [4]  */     TS("mul",MA),           TS("imul",MA),          TS("div",MA),           TS("idiv",MA),
1014 };
1015
1016
1017 /*
1018  *      Decode table for 0xFE opcodes.
1019  */
1020
1021 const instable_t dis_opFE[8] = {
1022
1023 /*  [0]  */     TNS("incb",Mw),         TNS("decb",Mw),         INVALID,                INVALID,
1024 /*  [4]  */     INVALID,                INVALID,                INVALID,                INVALID,
1025 };
1026 /*
1027  *      Decode table for 0xFF opcodes.
1028  */
1029
1030 const instable_t dis_opFF[8] = {
1031
1032 /*  [0]  */     TS("inc",Mw),           TS("dec",Mw),           TNSyp("call",INM),      TNS("lcall",INM),
1033 /*  [4]  */     TNSy("jmp",INM),        TNS("ljmp",INM),        TSp("push",M),          INVALID,
1034 };
1035
1036 /* for 287 instructions, which are a mess to decode */
1037
1038 const instable_t dis_opFP1n2[8][8] = {
1039 {
1040 /* bit pattern: 1101 1xxx MODxx xR/M */
1041 /*  [0,0] */    TNS("fadds",M),         TNS("fmuls",M),         TNS("fcoms",M),         TNS("fcomps",M),
1042 /*  [0,4] */    TNS("fsubs",M),         TNS("fsubrs",M),        TNS("fdivs",M),         TNS("fdivrs",M),
1043 }, {
1044 /*  [1,0]  */   TNS("flds",M),          INVALID,                TNS("fsts",M),          TNS("fstps",M),
1045 /*  [1,4]  */   TNSZ("fldenv",M,28),    TNSZ("fldcw",M,2),      TNSZ("fnstenv",M,28),   TNSZ("fnstcw",M,2),
1046 }, {
1047 /*  [2,0]  */   TNS("fiaddl",M),        TNS("fimull",M),        TNS("ficoml",M),        TNS("ficompl",M),
1048 /*  [2,4]  */   TNS("fisubl",M),        TNS("fisubrl",M),       TNS("fidivl",M),        TNS("fidivrl",M),
1049 }, {
1050 /*  [3,0]  */   TNS("fildl",M),         INVALID,                TNS("fistl",M),         TNS("fistpl",M),
1051 /*  [3,4]  */   INVALID,                TNSZ("fldt",M,10),      INVALID,                TNSZ("fstpt",M,10),
1052 }, {
1053 /*  [4,0]  */   TNSZ("faddl",M,8),      TNSZ("fmull",M,8),      TNSZ("fcoml",M,8),      TNSZ("fcompl",M,8),
1054 /*  [4,1]  */   TNSZ("fsubl",M,8),      TNSZ("fsubrl",M,8),     TNSZ("fdivl",M,8),      TNSZ("fdivrl",M,8),
1055 }, {
1056 /*  [5,0]  */   TNSZ("fldl",M,8),       INVALID,                TNSZ("fstl",M,8),       TNSZ("fstpl",M,8),
1057 /*  [5,4]  */   TNSZ("frstor",M,108),   INVALID,                TNSZ("fnsave",M,108),   TNSZ("fnstsw",M,2),
1058 }, {
1059 /*  [6,0]  */   TNSZ("fiadd",M,2),      TNSZ("fimul",M,2),      TNSZ("ficom",M,2),      TNSZ("ficomp",M,2),
1060 /*  [6,4]  */   TNSZ("fisub",M,2),      TNSZ("fisubr",M,2),     TNSZ("fidiv",M,2),      TNSZ("fidivr",M,2),
1061 }, {
1062 /*  [7,0]  */   TNSZ("fild",M,2),       INVALID,                TNSZ("fist",M,2),       TNSZ("fistp",M,2),
1063 /*  [7,4]  */   TNSZ("fbld",M,10),      TNSZ("fildll",M,8),     TNSZ("fbstp",M,10),     TNSZ("fistpll",M,8),
1064 } };
1065
1066 const instable_t dis_opFP3[8][8] = {
1067 {
1068 /* bit  pattern:        1101 1xxx 11xx xREG */
1069 /*  [0,0]  */   TNS("fadd",FF),         TNS("fmul",FF),         TNS("fcom",F),          TNS("fcomp",F),
1070 /*  [0,4]  */   TNS("fsub",FF),         TNS("fsubr",FF),        TNS("fdiv",FF),         TNS("fdivr",FF),
1071 }, {
1072 /*  [1,0]  */   TNS("fld",F),           TNS("fxch",F),          TNS("fnop",NORM),       TNS("fstp",F),
1073 /*  [1,4]  */   INVALID,                INVALID,                INVALID,                INVALID,
1074 }, {
1075 /*  [2,0]  */   INVALID,                INVALID,                INVALID,                INVALID,
1076 /*  [2,4]  */   INVALID,                TNS("fucompp",NORM),    INVALID,                INVALID,
1077 }, {
1078 /*  [3,0]  */   INVALID,                INVALID,                INVALID,                INVALID,
1079 /*  [3,4]  */   INVALID,                INVALID,                INVALID,                INVALID,
1080 }, {
1081 /*  [4,0]  */   TNS("fadd",FF),         TNS("fmul",FF),         TNS("fcom",F),          TNS("fcomp",F),
1082 /*  [4,4]  */   TNS("fsub",FF),         TNS("fsubr",FF),        TNS("fdiv",FF),         TNS("fdivr",FF),
1083 }, {
1084 /*  [5,0]  */   TNS("ffree",F),         TNS("fxch",F),          TNS("fst",F),           TNS("fstp",F),
1085 /*  [5,4]  */   TNS("fucom",F),         TNS("fucomp",F),        INVALID,                INVALID,
1086 }, {
1087 /*  [6,0]  */   TNS("faddp",FF),        TNS("fmulp",FF),        TNS("fcomp",F),         TNS("fcompp",NORM),
1088 /*  [6,4]  */   TNS("fsubp",FF),        TNS("fsubrp",FF),       TNS("fdivp",FF),        TNS("fdivrp",FF),
1089 }, {
1090 /*  [7,0]  */   TNS("ffree",F),         TNS("fxch",F),          TNS("fstp",F),          TNS("fstp",F),
1091 /*  [7,4]  */   TNS("fnstsw",M),        TNS("fucomip",FFC),     TNS("fcomip",FFC),      INVALID,
1092 } };
1093
1094 const instable_t dis_opFP4[4][8] = {
1095 {
1096 /* bit pattern: 1101 1001 111x xxxx */
1097 /*  [0,0]  */   TNS("fchs",NORM),       TNS("fabs",NORM),       INVALID,                INVALID,
1098 /*  [0,4]  */   TNS("ftst",NORM),       TNS("fxam",NORM),       TNS("ftstp",NORM),      INVALID,
1099 }, {
1100 /*  [1,0]  */   TNS("fld1",NORM),       TNS("fldl2t",NORM),     TNS("fldl2e",NORM),     TNS("fldpi",NORM),
1101 /*  [1,4]  */   TNS("fldlg2",NORM),     TNS("fldln2",NORM),     TNS("fldz",NORM),       INVALID,
1102 }, {
1103 /*  [2,0]  */   TNS("f2xm1",NORM),      TNS("fyl2x",NORM),      TNS("fptan",NORM),      TNS("fpatan",NORM),
1104 /*  [2,4]  */   TNS("fxtract",NORM),    TNS("fprem1",NORM),     TNS("fdecstp",NORM),    TNS("fincstp",NORM),
1105 }, {
1106 /*  [3,0]  */   TNS("fprem",NORM),      TNS("fyl2xp1",NORM),    TNS("fsqrt",NORM),      TNS("fsincos",NORM),
1107 /*  [3,4]  */   TNS("frndint",NORM),    TNS("fscale",NORM),     TNS("fsin",NORM),       TNS("fcos",NORM),
1108 } };
1109
1110 const instable_t dis_opFP5[8] = {
1111 /* bit pattern: 1101 1011 111x xxxx */
1112 /*  [0]  */     TNS("feni",NORM),       TNS("fdisi",NORM),      TNS("fnclex",NORM),     TNS("fninit",NORM),
1113 /*  [4]  */     TNS("fsetpm",NORM),     TNS("frstpm",NORM),     INVALID,                INVALID,
1114 };
1115
1116 const instable_t dis_opFP6[8] = {
1117 /* bit pattern: 1101 1011 11yy yxxx */
1118 /*  [00]  */    TNS("fcmov.nb",FF),     TNS("fcmov.ne",FF),     TNS("fcmov.nbe",FF),    TNS("fcmov.nu",FF),
1119 /*  [04]  */    INVALID,                TNS("fucomi",F),        TNS("fcomi",F),         INVALID,
1120 };
1121
1122 const instable_t dis_opFP7[8] = {
1123 /* bit pattern: 1101 1010 11yy yxxx */
1124 /*  [00]  */    TNS("fcmov.b",FF),      TNS("fcmov.e",FF),      TNS("fcmov.be",FF),     TNS("fcmov.u",FF),
1125 /*  [04]  */    INVALID,                INVALID,                INVALID,                INVALID,
1126 };
1127
1128 /*
1129  *      Main decode table for the op codes.  The first two nibbles
1130  *      will be used as an index into the table.  If there is a
1131  *      a need to further decode an instruction, the array to be
1132  *      referenced is indicated with the other two entries being
1133  *      empty.
1134  */
1135
1136 const instable_t dis_distable[16][16] = {
1137 {
1138 /* [0,0] */     TNS("addb",RMw),        TS("add",RMw),          TNS("addb",MRw),        TS("add",MRw),
1139 /* [0,4] */     TNS("addb",IA),         TS("add",IA),           TSx("push",SEG),        TSx("pop",SEG),
1140 /* [0,8] */     TNS("orb",RMw),         TS("or",RMw),           TNS("orb",MRw),         TS("or",MRw),
1141 /* [0,C] */     TNS("orb",IA),          TS("or",IA),            TSx("push",SEG),        IND(&dis_op0F[0][0]),
1142 }, {
1143 /* [1,0] */     TNS("adcb",RMw),        TS("adc",RMw),          TNS("adcb",MRw),        TS("adc",MRw),
1144 /* [1,4] */     TNS("adcb",IA),         TS("adc",IA),           TSx("push",SEG),        TSx("pop",SEG),
1145 /* [1,8] */     TNS("sbbb",RMw),        TS("sbb",RMw),          TNS("sbbb",MRw),        TS("sbb",MRw),
1146 /* [1,C] */     TNS("sbbb",IA),         TS("sbb",IA),           TSx("push",SEG),        TSx("pop",SEG),
1147 }, {
1148 /* [2,0] */     TNS("andb",RMw),        TS("and",RMw),          TNS("andb",MRw),        TS("and",MRw),
1149 /* [2,4] */     TNS("andb",IA),         TS("and",IA),           TNSx("%es:",OVERRIDE),  TNSx("daa",NORM),
1150 /* [2,8] */     TNS("subb",RMw),        TS("sub",RMw),          TNS("subb",MRw),        TS("sub",MRw),
1151 /* [2,C] */     TNS("subb",IA),         TS("sub",IA),           TNSx("%cs:",OVERRIDE),  TNSx("das",NORM),
1152 }, {
1153 /* [3,0] */     TNS("xorb",RMw),        TS("xor",RMw),          TNS("xorb",MRw),        TS("xor",MRw),
1154 /* [3,4] */     TNS("xorb",IA),         TS("xor",IA),           TNSx("%ss:",OVERRIDE),  TNSx("aaa",NORM),
1155 /* [3,8] */     TNS("cmpb",RMw),        TS("cmp",RMw),          TNS("cmpb",MRw),        TS("cmp",MRw),
1156 /* [3,C] */     TNS("cmpb",IA),         TS("cmp",IA),           TNSx("%ds:",OVERRIDE),  TNSx("aas",NORM),
1157 }, {
1158 /* [4,0] */     TSx("inc",R),           TSx("inc",R),           TSx("inc",R),           TSx("inc",R),
1159 /* [4,4] */     TSx("inc",R),           TSx("inc",R),           TSx("inc",R),           TSx("inc",R),
1160 /* [4,8] */     TSx("dec",R),           TSx("dec",R),           TSx("dec",R),           TSx("dec",R),
1161 /* [4,C] */     TSx("dec",R),           TSx("dec",R),           TSx("dec",R),           TSx("dec",R),
1162 }, {
1163 /* [5,0] */     TSp("push",R),          TSp("push",R),          TSp("push",R),          TSp("push",R),
1164 /* [5,4] */     TSp("push",R),          TSp("push",R),          TSp("push",R),          TSp("push",R),
1165 /* [5,8] */     TSp("pop",R),           TSp("pop",R),           TSp("pop",R),           TSp("pop",R),
1166 /* [5,C] */     TSp("pop",R),           TSp("pop",R),           TSp("pop",R),           TSp("pop",R),
1167 }, {
1168 /* [6,0] */     TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),      TNS("arpl",RMw),
1169 /* [6,4] */     TNS("%fs:",OVERRIDE),   TNS("%gs:",OVERRIDE),   TNS("data16",DM),       TNS("addr16",AM),
1170 /* [6,8] */     TSp("push",I),          TS("imul",IMUL),        TSp("push",Ib), TS("imul",IMUL),
1171 /* [6,C] */     TNSZ("insb",IMPLMEM,1), TSZ("ins",IMPLMEM,4),   TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
1172 }, {
1173 /* [7,0] */     TNSy("jo",BD),          TNSy("jno",BD),         TNSy("jb",BD),          TNSy("jae",BD),
1174 /* [7,4] */     TNSy("je",BD),          TNSy("jne",BD),         TNSy("jbe",BD),         TNSy("ja",BD),
1175 /* [7,8] */     TNSy("js",BD),          TNSy("jns",BD),         TNSy("jp",BD),          TNSy("jnp",BD),
1176 /* [7,C] */     TNSy("jl",BD),          TNSy("jge",BD),         TNSy("jle",BD),         TNSy("jg",BD),
1177 }, {
1178 /* [8,0] */     IND(dis_op80),          IND(dis_op81),          INDx(dis_op82),         IND(dis_op83),
1179 /* [8,4] */     TNS("testb",RMw),       TS("test",RMw),         TNS("xchgb",RMw),       TS("xchg",RMw),
1180 /* [8,8] */     TNS("movb",RMw),        TS("mov",RMw),          TNS("movb",MRw),        TS("mov",MRw),
1181 /* [8,C] */     TNS("movw",SM),         TS("lea",MR),           TNS("movw",MS),         TSp("pop",M),
1182 }, {
1183 /* [9,0] */     TNS("nop",NORM),        TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),
1184 /* [9,4] */     TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),          TS("xchg",RA),
1185 /* [9,8] */     TNS("cXtX",CBW),        TNS("cXtX",CWD),        TNSx("lcall",SO),       TNS("fwait",NORM),
1186 /* [9,C] */     TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4), TNSx("sahf",NORM),      TNSx("lahf",NORM),
1187 }, {
1188 /* [A,0] */     TNS("movb",OA),         TS("mov",OA),           TNS("movb",AO),         TS("mov",AO),
1189 /* [A,4] */     TNSZ("movsb",SD,1),     TS("movs",SD),          TNSZ("cmpsb",SD,1),     TS("cmps",SD),
1190 /* [A,8] */     TNS("testb",IA),        TS("test",IA),          TNS("stosb",AD),        TS("stos",AD),
1191 /* [A,C] */     TNS("lodsb",SA),        TS("lods",SA),          TNS("scasb",AD),        TS("scas",AD),
1192 }, {
1193 /* [B,0] */     TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),
1194 /* [B,4] */     TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),         TNS("movb",IR),
1195 /* [B,8] */     TS("mov",IR),           TS("mov",IR),           TS("mov",IR),           TS("mov",IR),
1196 /* [B,C] */     TS("mov",IR),           TS("mov",IR),           TS("mov",IR),           TS("mov",IR),
1197 }, {
1198 /* [C,0] */     IND(dis_opC0),          IND(dis_opC1),          TNSyp("ret",RET),       TNSyp("ret",NORM),
1199 /* [C,4] */     TNSx("les",MR),         TNSx("lds",MR),         TNS("movb",IMw),        TS("mov",IMw),
1200 /* [C,8] */     TNSyp("enter",ENTER),   TNSyp("leave",NORM),    TNS("lret",RET),        TNS("lret",NORM),
1201 /* [C,C] */     TNS("int",INT3),        TNS("int",INTx),        TNSx("into",NORM),      TNS("iret",NORM),
1202 }, {
1203 /* [D,0] */     IND(dis_opD0),          IND(dis_opD1),          IND(dis_opD2),          IND(dis_opD3),
1204 /* [D,4] */     TNSx("aam",U),          TNSx("aad",U),          TNSx("falc",NORM),      TNSZ("xlat",IMPLMEM,1),
1205
1206 /* 287 instructions.  Note that although the indirect field             */
1207 /* indicates opFP1n2 for further decoding, this is not necessarily      */
1208 /* the case since the opFP arrays are not partitioned according to key1 */
1209 /* and key2.  opFP1n2 is given only to indicate that we haven't         */
1210 /* finished decoding the instruction.                                   */
1211 /* [D,8] */     IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),
1212 /* [D,C] */     IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),        IND(&dis_opFP1n2[0][0]),
1213 }, {
1214 /* [E,0] */     TNSy("loopnz",BD),      TNSy("loopz",BD),       TNSy("loop",BD),        TNSy("jcxz",BD),
1215 /* [E,4] */     TNS("inb",P),           TS("in",P),             TNS("outb",P),          TS("out",P),
1216 /* [E,8] */     TNSyp("call",D),        TNSy("jmp",D),          TNSx("ljmp",SO),                TNSy("jmp",BD),
1217 /* [E,C] */     TNS("inb",V),           TS("in",V),             TNS("outb",V),          TS("out",V),
1218 }, {
1219 /* [F,0] */     TNS("lock",LOCK),       TNS("icebp", NORM),     TNS("repnz",PREFIX),    TNS("repz",PREFIX),
1220 /* [F,4] */     TNS("hlt",NORM),        TNS("cmc",NORM),        IND(dis_opF6),          IND(dis_opF7),
1221 /* [F,8] */     TNS("clc",NORM),        TNS("stc",NORM),        TNS("cli",NORM),        TNS("sti",NORM),
1222 /* [F,C] */     TNS("cld",NORM),        TNS("std",NORM),        IND(dis_opFE),          IND(dis_opFF),
1223 } };
1224
1225 /* END CSTYLED */
1226
1227 /*
1228  * common functions to decode and disassemble an x86 or amd64 instruction
1229  */
1230
1231 /*
1232  * These are the individual fields of a REX prefix. Note that a REX
1233  * prefix with none of these set is still needed to:
1234  *      - use the MOVSXD (sign extend 32 to 64 bits) instruction
1235  *      - access the %sil, %dil, %bpl, %spl registers
1236  */
1237 #define REX_W 0x08      /* 64 bit operand size when set */
1238 #define REX_R 0x04      /* high order bit extension of ModRM reg field */
1239 #define REX_X 0x02      /* high order bit extension of SIB index field */
1240 #define REX_B 0x01      /* extends ModRM r_m, SIB base, or opcode reg */
1241
1242 static uint_t opnd_size;        /* SIZE16, SIZE32 or SIZE64 */
1243 static uint_t addr_size;        /* SIZE16, SIZE32 or SIZE64 */
1244
1245 /*
1246  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
1247  */
1248 static int isize[] = {1, 2, 4, 4};
1249 static int isize64[] = {1, 2, 4, 8};
1250
1251 /*
1252  * Just a bunch of useful macros.
1253  */
1254 #define WBIT(x) (x & 0x1)               /* to get w bit */
1255 #define REGNO(x) (x & 0x7)              /* to get 3 bit register */
1256 #define VBIT(x) ((x)>>1 & 0x1)          /* to get 'v' bit */
1257 #define OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
1258 #define OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
1259
1260 #define REG_ONLY 3      /* mode to indicate a register operand (not memory) */
1261
1262 #define BYTE_OPND       0       /* w-bit value indicating byte register */
1263 #define LONG_OPND       1       /* w-bit value indicating opnd_size register */
1264 #define MM_OPND         2       /* "value" used to indicate a mmx reg */
1265 #define XMM_OPND        3       /* "value" used to indicate a xmm reg */
1266 #define SEG_OPND        4       /* "value" used to indicate a segment reg */
1267 #define CONTROL_OPND    5       /* "value" used to indicate a control reg */
1268 #define DEBUG_OPND      6       /* "value" used to indicate a debug reg */
1269 #define TEST_OPND       7       /* "value" used to indicate a test reg */
1270 #define WORD_OPND       8       /* w-bit value indicating word size reg */
1271
1272 /*
1273  * Get the next byte and separate the op code into the high and low nibbles.
1274  */
1275 static int
1276 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
1277 {
1278         int byte;
1279
1280         /*
1281          * x86 instructions have a maximum length of 15 bytes.  Bail out if
1282          * we try to read more.
1283          */
1284         if (x->d86_len >= 15)
1285                 return (x->d86_error = 1);
1286
1287         if (x->d86_error)
1288                 return (1);
1289         byte = x->d86_get_byte(x->d86_data);
1290         if (byte < 0)
1291                 return (x->d86_error = 1);
1292         x->d86_bytes[x->d86_len++] = byte;
1293         *low = byte & 0xf;              /* ----xxxx low 4 bits */
1294         *high = byte >> 4 & 0xf;        /* xxxx---- bits 7 to 4 */
1295         return (0);
1296 }
1297
1298 /*
1299  * Get and decode an SIB (scaled index base) byte
1300  */
1301 static void
1302 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
1303 {
1304         int byte;
1305
1306         if (x->d86_error)
1307                 return;
1308
1309         byte = x->d86_get_byte(x->d86_data);
1310         if (byte < 0) {
1311                 x->d86_error = 1;
1312                 return;
1313         }
1314         x->d86_bytes[x->d86_len++] = byte;
1315
1316         *base = byte & 0x7;
1317         *index = (byte >> 3) & 0x7;
1318         *ss = (byte >> 6) & 0x3;
1319 }
1320
1321 /*
1322  * Get the byte following the op code and separate it into the
1323  * mode, register, and r/m fields.
1324  */
1325 static void
1326 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
1327 {
1328         if (x->d86_got_modrm == 0) {
1329                 if (x->d86_rmindex == -1)
1330                         x->d86_rmindex = x->d86_len;
1331                 dtrace_get_SIB(x, mode, reg, r_m);
1332                 x->d86_got_modrm = 1;
1333         }
1334 }
1335
1336 /*
1337  * Adjust register selection based on any REX prefix bits present.
1338  */
1339 /*ARGSUSED*/
1340 static void
1341 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
1342 {
1343         if (reg != NULL && r_m == NULL) {
1344                 if (rex_prefix & REX_B)
1345                         *reg += 8;
1346         } else {
1347                 if (reg != NULL && (REX_R & rex_prefix) != 0)
1348                         *reg += 8;
1349                 if (r_m != NULL && (REX_B & rex_prefix) != 0)
1350                         *r_m += 8;
1351         }
1352 }
1353
1354 /*
1355  * Get an immediate operand of the given size, with sign extension.
1356  */
1357 static void
1358 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
1359 {
1360         int i;
1361         int byte;
1362         int valsize = 0;
1363
1364         if (x->d86_numopnds < opindex + 1)
1365                 x->d86_numopnds = opindex + 1;
1366
1367         switch (wbit) {
1368         case BYTE_OPND:
1369                 valsize = 1;
1370                 break;
1371         case LONG_OPND:
1372                 if (x->d86_opnd_size == SIZE16)
1373                         valsize = 2;
1374                 else if (x->d86_opnd_size == SIZE32)
1375                         valsize = 4;
1376                 else
1377                         valsize = 8;
1378                 break;
1379         case MM_OPND:
1380         case XMM_OPND:
1381         case SEG_OPND:
1382         case CONTROL_OPND:
1383         case DEBUG_OPND:
1384         case TEST_OPND:
1385                 valsize = size;
1386                 break;
1387         case WORD_OPND:
1388                 valsize = 2;
1389                 break;
1390         }
1391         if (valsize < size)
1392                 valsize = size;
1393
1394         if (x->d86_error)
1395                 return;
1396         x->d86_opnd[opindex].d86_value = 0;
1397         for (i = 0; i < size; ++i) {
1398                 byte = x->d86_get_byte(x->d86_data);
1399                 if (byte < 0) {
1400                         x->d86_error = 1;
1401                         return;
1402                 }
1403                 x->d86_bytes[x->d86_len++] = byte;
1404                 x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
1405         }
1406         /* Do sign extension */
1407         if (x->d86_bytes[x->d86_len - 1] & 0x80) {
1408                 for (; i < valsize; i++)
1409                         x->d86_opnd[opindex].d86_value |=
1410                             (uint64_t)0xff << (i* 8);
1411         }
1412 #ifdef DIS_TEXT
1413         x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
1414         x->d86_opnd[opindex].d86_value_size = valsize;
1415         x->d86_imm_bytes += size;
1416 #endif
1417 }
1418
1419 /*
1420  * Get an ip relative operand of the given size, with sign extension.
1421  */
1422 static void
1423 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
1424 {
1425         dtrace_imm_opnd(x, wbit, size, opindex);
1426 #ifdef DIS_TEXT
1427         x->d86_opnd[opindex].d86_mode = MODE_IPREL;
1428 #endif
1429 }
1430
1431 /*
1432  * Check to see if there is a segment override prefix pending.
1433  * If so, print it in the current 'operand' location and set
1434  * the override flag back to false.
1435  */
1436 /*ARGSUSED*/
1437 static void
1438 dtrace_check_override(dis86_t *x, int opindex)
1439 {
1440 #ifdef DIS_TEXT
1441         if (x->d86_seg_prefix) {
1442                 (void) strlcat(x->d86_opnd[opindex].d86_prefix,
1443                     x->d86_seg_prefix, PFIXLEN);
1444         }
1445 #endif
1446         x->d86_seg_prefix = NULL;
1447 }
1448
1449
1450 /*
1451  * Process a single instruction Register or Memory operand.
1452  *
1453  * mode = addressing mode from ModRM byte
1454  * r_m = r_m (or reg if mode == 3) field from ModRM byte
1455  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
1456  * o = index of operand that we are processing (0, 1 or 2)
1457  *
1458  * the value of reg or r_m must have already been adjusted for any REX prefix.
1459  */
1460 /*ARGSUSED*/
1461 static void
1462 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
1463 {
1464         int have_SIB = 0;       /* flag presence of scale-index-byte */
1465         uint_t ss;              /* scale-factor from opcode */
1466         uint_t index;           /* index register number */
1467         uint_t base;            /* base register number */
1468         int dispsize;           /* size of displacement in bytes */
1469 #ifdef DIS_TEXT
1470         char *opnd = x->d86_opnd[opindex].d86_opnd;
1471 #endif
1472
1473         if (x->d86_numopnds < opindex + 1)
1474                 x->d86_numopnds = opindex + 1;
1475
1476         if (x->d86_error)
1477                 return;
1478
1479         /*
1480          * first handle a simple register
1481          */
1482         if (mode == REG_ONLY) {
1483 #ifdef DIS_TEXT
1484                 switch (wbit) {
1485                 case MM_OPND:
1486                         (void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
1487                         break;
1488                 case XMM_OPND:
1489                         (void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
1490                         break;
1491                 case SEG_OPND:
1492                         (void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
1493                         break;
1494                 case CONTROL_OPND:
1495                         (void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
1496                         break;
1497                 case DEBUG_OPND:
1498                         (void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
1499                         break;
1500                 case TEST_OPND:
1501                         (void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
1502                         break;
1503                 case BYTE_OPND:
1504                         if (x->d86_rex_prefix == 0)
1505                                 (void) strlcat(opnd, dis_REG8[r_m], OPLEN);
1506                         else
1507                                 (void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
1508                         break;
1509                 case WORD_OPND:
1510                         (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
1511                         break;
1512                 case LONG_OPND:
1513                         if (x->d86_opnd_size == SIZE16)
1514                                 (void) strlcat(opnd, dis_REG16[r_m], OPLEN);
1515                         else if (x->d86_opnd_size == SIZE32)
1516                                 (void) strlcat(opnd, dis_REG32[r_m], OPLEN);
1517                         else
1518                                 (void) strlcat(opnd, dis_REG64[r_m], OPLEN);
1519                         break;
1520                 }
1521 #endif /* DIS_TEXT */
1522                 return;
1523         }
1524
1525         /*
1526          * if symbolic representation, skip override prefix, if any
1527          */
1528         dtrace_check_override(x, opindex);
1529
1530         /*
1531          * Handle 16 bit memory references first, since they decode
1532          * the mode values more simply.
1533          * mode 1 is r_m + 8 bit displacement
1534          * mode 2 is r_m + 16 bit displacement
1535          * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
1536          */
1537         if (x->d86_addr_size == SIZE16) {
1538                 if ((mode == 0 && r_m == 6) || mode == 2)
1539                         dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
1540                 else if (mode == 1)
1541                         dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
1542 #ifdef DIS_TEXT
1543                 if (mode == 0 && r_m == 6)
1544                         x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
1545                 else if (mode == 0)
1546                         x->d86_opnd[opindex].d86_mode = MODE_NONE;
1547                 else
1548                         x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
1549                 (void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
1550 #endif
1551                 return;
1552         }
1553
1554         /*
1555          * 32 and 64 bit addressing modes are more complex since they
1556          * can involve an SIB (scaled index and base) byte to decode.
1557          */
1558         if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
1559                 have_SIB = 1;
1560                 dtrace_get_SIB(x, &ss, &index, &base);
1561                 if (x->d86_error)
1562                         return;
1563                 if (base != 5 || mode != 0)
1564                         if (x->d86_rex_prefix & REX_B)
1565                                 base += 8;
1566                 if (x->d86_rex_prefix & REX_X)
1567                         index += 8;
1568         } else {
1569                 base = r_m;
1570         }
1571
1572         /*
1573          * Compute the displacement size and get its bytes
1574          */
1575         dispsize = 0;
1576
1577         if (mode == 1)
1578                 dispsize = 1;
1579         else if (mode == 2)
1580                 dispsize = 4;
1581         else if ((r_m & 7) == EBP_REGNO ||
1582             (have_SIB && (base & 7) == EBP_REGNO))
1583                 dispsize = 4;
1584
1585         if (dispsize > 0) {
1586                 dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
1587                     dispsize, opindex);
1588                 if (x->d86_error)
1589                         return;
1590         }
1591
1592 #ifdef DIS_TEXT
1593         if (dispsize > 0)
1594                 x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
1595
1596         if (have_SIB == 0) {
1597                 if (x->d86_mode == SIZE32) {
1598                         if (mode == 0)
1599                                 (void) strlcat(opnd, dis_addr32_mode0[r_m],
1600                                     OPLEN);
1601                         else
1602                                 (void) strlcat(opnd, dis_addr32_mode12[r_m],
1603                                     OPLEN);
1604                 } else {
1605                         if (mode == 0)
1606                                 (void) strlcat(opnd, dis_addr64_mode0[r_m],
1607                                     OPLEN);
1608                         else
1609                                 (void) strlcat(opnd, dis_addr64_mode12[r_m],
1610                                     OPLEN);
1611                 }
1612         } else {
1613                 uint_t need_paren = 0;
1614                 char **regs;
1615                 if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
1616                         regs = (char **)dis_REG32;
1617                 else
1618                         regs = (char **)dis_REG64;
1619
1620                 /*
1621                  * print the base (if any)
1622                  */
1623                 if (base == EBP_REGNO && mode == 0) {
1624                         if (index != ESP_REGNO) {
1625                                 (void) strlcat(opnd, "(", OPLEN);
1626                                 need_paren = 1;
1627                         }
1628                 } else {
1629                         (void) strlcat(opnd, "(", OPLEN);
1630                         (void) strlcat(opnd, regs[base], OPLEN);
1631                         need_paren = 1;
1632                 }
1633
1634                 /*
1635                  * print the index (if any)
1636                  */
1637                 if (index != ESP_REGNO) {
1638                         (void) strlcat(opnd, ",", OPLEN);
1639                         (void) strlcat(opnd, regs[index], OPLEN);
1640                         (void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
1641                 } else
1642                         if (need_paren)
1643                                 (void) strlcat(opnd, ")", OPLEN);
1644         }
1645 #endif
1646 }
1647
1648 /*
1649  * Operand sequence for standard instruction involving one register
1650  * and one register/memory operand.
1651  * wbit indicates a byte(0) or opnd_size(1) operation
1652  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
1653  */
1654 #define STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {    \
1655                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
1656                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
1657                 dtrace_get_operand(x, mode, r_m, wbit, vbit);           \
1658                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);   \
1659 }
1660
1661 /*
1662  * Similar to above, but allows for the two operands to be of different
1663  * classes (ie. wbit).
1664  *      wbit is for the r_m operand
1665  *      w2 is for the reg operand
1666  */
1667 #define MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit) {       \
1668                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
1669                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
1670                 dtrace_get_operand(x, mode, r_m, wbit, vbit);           \
1671                 dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);     \
1672 }
1673
1674 /*
1675  * Similar, but for 2 operands plus an immediate.
1676  */
1677 #define THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
1678                 dtrace_get_modrm(x, &mode, &reg, &r_m);                 \
1679                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);        \
1680                 dtrace_get_operand(x, mode, r_m, wbit, 1);              \
1681                 dtrace_get_operand(x, REG_ONLY, reg, w2, 2);            \
1682                 dtrace_imm_opnd(x, wbit, immsize, 0);                   \
1683 }
1684
1685 /*
1686  * Dissassemble a single x86 or amd64 instruction.
1687  *
1688  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
1689  * for interpreting instructions.
1690  *
1691  * returns non-zero for bad opcode
1692  */
1693 int
1694 dtrace_disx86(dis86_t *x, uint_t cpu_mode)
1695 {
1696         const instable_t *dp = NULL;    /* decode table being used */
1697 #ifdef DIS_TEXT
1698         uint_t i;
1699 #endif
1700 #ifdef DIS_MEM
1701         uint_t nomem = 0;
1702 #define NOMEM   (nomem = 1)
1703 #else
1704 #define NOMEM   /* nothing */
1705 #endif
1706         uint_t wbit = 0;        /* opcode wbit, 0 is 8 bit, !0 for opnd_size */
1707         uint_t w2;              /* wbit value for second operand */
1708         uint_t vbit;
1709         uint_t mode = 0;        /* mode value from ModRM byte */
1710         uint_t reg;             /* reg value from ModRM byte */
1711         uint_t r_m;             /* r_m value from ModRM byte */
1712
1713         uint_t opcode1;         /* high nibble of 1st byte */
1714         uint_t opcode2;         /* low nibble of 1st byte */
1715         uint_t opcode3;         /* extra opcode bits usually from ModRM byte */
1716         uint_t opcode4;         /* high nibble of 2nd byte */
1717         uint_t opcode5;         /* low nibble of 2ne byte */
1718         uint_t opcode6;         /* high nibble of 3rd byte */
1719         uint_t opcode7;         /* low nibble of 3rd byte */
1720         uint_t opcode_bytes = 1;
1721
1722         /*
1723          * legacy prefixes come in 5 flavors, you should have only one of each
1724          */
1725         uint_t  opnd_size_prefix = 0;
1726         uint_t  addr_size_prefix = 0;
1727         uint_t  segment_prefix = 0;
1728         uint_t  lock_prefix = 0;
1729         uint_t  rep_prefix = 0;
1730         uint_t  rex_prefix = 0; /* amd64 register extension prefix */
1731         size_t  off;
1732
1733         x->d86_len = 0;
1734         x->d86_rmindex = -1;
1735         x->d86_error = 0;
1736 #ifdef DIS_TEXT
1737         x->d86_numopnds = 0;
1738         x->d86_seg_prefix = NULL;
1739         x->d86_mneu[0] = 0;
1740         for (i = 0; i < 3; ++i) {
1741                 x->d86_opnd[i].d86_opnd[0] = 0;
1742                 x->d86_opnd[i].d86_prefix[0] = 0;
1743                 x->d86_opnd[i].d86_value_size = 0;
1744                 x->d86_opnd[i].d86_value = 0;
1745                 x->d86_opnd[i].d86_mode = MODE_NONE;
1746         }
1747 #endif
1748         x->d86_error = 0;
1749         x->d86_memsize = 0;
1750
1751         if (cpu_mode == SIZE16) {
1752                 opnd_size = SIZE16;
1753                 addr_size = SIZE16;
1754         } else if (cpu_mode == SIZE32) {
1755                 opnd_size = SIZE32;
1756                 addr_size = SIZE32;
1757         } else {
1758                 opnd_size = SIZE32;
1759                 addr_size = SIZE64;
1760         }
1761
1762         /*
1763          * Get one opcode byte and check for zero padding that follows
1764          * jump tables.
1765          */
1766         if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
1767                 goto error;
1768
1769         if (opcode1 == 0 && opcode2 == 0 &&
1770             x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
1771 #ifdef DIS_TEXT
1772                 (void) strncpy(x->d86_mneu, ".byte\t0", OPLEN);
1773 #endif
1774                 goto done;
1775         }
1776
1777         /*
1778          * Gather up legacy x86 prefix bytes.
1779          */
1780         for (;;) {
1781                 uint_t *which_prefix = NULL;
1782
1783                 dp = &dis_distable[opcode1][opcode2];
1784
1785                 switch (dp->it_adrmode) {
1786                 case PREFIX:
1787                         which_prefix = &rep_prefix;
1788                         break;
1789                 case LOCK:
1790                         which_prefix = &lock_prefix;
1791                         break;
1792                 case OVERRIDE:
1793                         which_prefix = &segment_prefix;
1794 #ifdef DIS_TEXT
1795                         x->d86_seg_prefix = (char *)dp->it_name;
1796 #endif
1797                         if (dp->it_invalid64 && cpu_mode == SIZE64)
1798                                 goto error;
1799                         break;
1800                 case AM:
1801                         which_prefix = &addr_size_prefix;
1802                         break;
1803                 case DM:
1804                         which_prefix = &opnd_size_prefix;
1805                         break;
1806                 }
1807                 if (which_prefix == NULL)
1808                         break;
1809                 *which_prefix = (opcode1 << 4) | opcode2;
1810                 if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
1811                         goto error;
1812         }
1813
1814         /*
1815          * Handle amd64 mode PREFIX values.
1816          * Some of the segment prefixes are no-ops. (only FS/GS actually work)
1817          * We might have a REX prefix (opcodes 0x40-0x4f)
1818          */
1819         if (cpu_mode == SIZE64) {
1820                 if (segment_prefix != 0x64 && segment_prefix != 0x65)
1821                         segment_prefix = 0;
1822
1823                 if (opcode1 == 0x4) {
1824                         rex_prefix = (opcode1 << 4) | opcode2;
1825                         if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
1826                                 goto error;
1827                         dp = &dis_distable[opcode1][opcode2];
1828                 }
1829         }
1830
1831         /*
1832          * Deal with selection of operand and address size now.
1833          * Note that the REX.W bit being set causes opnd_size_prefix to be
1834          * ignored.
1835          */
1836         if (cpu_mode == SIZE64) {
1837                 if (rex_prefix & 0x08)
1838                         opnd_size = SIZE64;
1839                 else if (opnd_size_prefix)
1840                         opnd_size = SIZE16;
1841
1842                 if (addr_size_prefix)
1843                         addr_size = SIZE32;
1844         } else if (cpu_mode == SIZE32) {
1845                 if (opnd_size_prefix)
1846                         opnd_size = SIZE16;
1847                 if (addr_size_prefix)
1848                         addr_size = SIZE16;
1849         } else {
1850                 if (opnd_size_prefix)
1851                         opnd_size = SIZE32;
1852                 if (addr_size_prefix)
1853                         addr_size = SIZE32;
1854         }
1855
1856         /*
1857          * The pause instruction - a repz'd nop.  This doesn't fit
1858          * with any of the other prefix goop added for SSE, so we'll
1859          * special-case it here.
1860          */
1861         if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
1862                 rep_prefix = 0;
1863                 dp = &dis_opPause;
1864         }
1865
1866         /*
1867          * Some 386 instructions have 2 bytes of opcode before the mod_r/m
1868          * byte so we may need to perform a table indirection.
1869          */
1870         if (dp->it_indirect == dis_op0F[0]) {
1871                 if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
1872                         goto error;
1873                 opcode_bytes = 2;
1874                 if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
1875                         uint_t  subcode;
1876
1877                         if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
1878                                 goto error;
1879                         opcode_bytes = 3;
1880                         subcode = ((opcode6 & 0x3) << 1) |
1881                             ((opcode7 & 0x8) >> 3);
1882                         dp = &dis_op0F7123[opcode5][subcode];
1883                 } else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
1884                         dp = &dis_op0FC8[0];
1885                 } else {
1886                         dp = &dis_op0F[opcode4][opcode5];
1887                 }
1888         }
1889
1890         /*
1891          * If still not at a TERM decode entry, then a ModRM byte
1892          * exists and its fields further decode the instruction.
1893          */
1894         x->d86_got_modrm = 0;
1895         if (dp->it_indirect != TERM) {
1896                 dtrace_get_modrm(x, &mode, &opcode3, &r_m);
1897                 if (x->d86_error)
1898                         goto error;
1899                 reg = opcode3;
1900
1901                 /*
1902                  * decode 287 instructions (D8-DF) from opcodeN
1903                  */
1904                 if (opcode1 == 0xD && opcode2 >= 0x8) {
1905                         if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
1906                                 dp = &dis_opFP5[r_m];
1907                         else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
1908                                 dp = &dis_opFP7[opcode3];
1909                         else if (opcode2 == 0xB && mode == 0x3)
1910                                 dp = &dis_opFP6[opcode3];
1911                         else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
1912                                 dp = &dis_opFP4[opcode3 - 4][r_m];
1913                         else if (mode == 0x3)
1914                                 dp = &dis_opFP3[opcode2 - 8][opcode3];
1915                         else
1916                                 dp = &dis_opFP1n2[opcode2 - 8][opcode3];
1917                 } else {
1918                         dp = dp->it_indirect + opcode3;
1919                 }
1920         }
1921
1922         /*
1923          * In amd64 bit mode, ARPL opcode is changed to MOVSXD
1924          * (sign extend 32bit to 64 bit)
1925          */
1926         if (cpu_mode == SIZE64 && opcode1 == 0x6 && opcode2 == 0x3)
1927                 dp = &dis_opMOVSLD;
1928
1929         /*
1930          * at this point we should have a correct (or invalid) opcode
1931          */
1932         if ((cpu_mode == SIZE64 && dp->it_invalid64) ||
1933             (cpu_mode != SIZE64 && dp->it_invalid32))
1934                 goto error;
1935         if (dp->it_indirect != TERM)
1936                 goto error;
1937
1938         /*
1939          * deal with MMX/SSE opcodes which are changed by prefixes
1940          */
1941         switch (dp->it_adrmode) {
1942         case MMO:
1943         case MMOIMPL:
1944         case MMO3P:
1945         case MMOM3:
1946         case MMOMS:
1947         case MMOPM:
1948         case MMOPRM:
1949         case MMOS:
1950         case XMMO:
1951         case XMMOM:
1952         case XMMOMS:
1953         case XMMOPM:
1954         case XMMOS:
1955         case XMMOMX:
1956         case XMMOX3:
1957         case XMMOXMM:
1958                 /*
1959                  * This is horrible.  Some SIMD instructions take the
1960                  * form 0x0F 0x?? ..., which is easily decoded using the
1961                  * existing tables.  Other SIMD instructions use various
1962                  * prefix bytes to overload existing instructions.  For
1963                  * Example, addps is F0, 58, whereas addss is F3 (repz),
1964                  * F0, 58.  Presumably someone got a raise for this.
1965                  *
1966                  * If we see one of the instructions which can be
1967                  * modified in this way (if we've got one of the SIMDO*
1968                  * address modes), we'll check to see if the last prefix
1969                  * was a repz.  If it was, we strip the prefix from the
1970                  * mnemonic, and we indirect using the dis_opSIMDrepz
1971                  * table.
1972                  */
1973
1974                 /*
1975                  * Calculate our offset in dis_op0F
1976                  */
1977                 if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
1978                         goto error;
1979
1980                 off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
1981                     sizeof (instable_t);
1982
1983                 /*
1984                  * Rewrite if this instruction used one of the magic prefixes.
1985                  */
1986                 if (rep_prefix) {
1987                         if (rep_prefix == 0xf2)
1988                                 dp = &dis_opSIMDrepnz[off];
1989                         else
1990                                 dp = &dis_opSIMDrepz[off];
1991                         rep_prefix = 0;
1992                 } else if (opnd_size_prefix) {
1993                         dp = &dis_opSIMDdata16[off];
1994                         opnd_size_prefix = 0;
1995                         if (opnd_size == SIZE16)
1996                                 opnd_size = SIZE32;
1997                 }
1998                 break;
1999
2000         case MMOSH:
2001                 /*
2002                  * As with the "normal" SIMD instructions, the MMX
2003                  * shuffle instructions are overloaded.  These
2004                  * instructions, however, are special in that they use
2005                  * an extra byte, and thus an extra table.  As of this
2006                  * writing, they only use the opnd_size prefix.
2007                  */
2008
2009                 /*
2010                  * Calculate our offset in dis_op0F7123
2011                  */
2012                 if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
2013                     sizeof (dis_op0F7123))
2014                         goto error;
2015
2016                 if (opnd_size_prefix) {
2017                         off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
2018                             sizeof (instable_t);
2019                         dp = &dis_opSIMD7123[off];
2020                         opnd_size_prefix = 0;
2021                         if (opnd_size == SIZE16)
2022                                 opnd_size = SIZE32;
2023                 }
2024                 break;
2025         }
2026
2027         /*
2028          * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
2029          */
2030         if (cpu_mode == SIZE64)
2031                 if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
2032                         opnd_size = SIZE64;
2033
2034 #ifdef DIS_TEXT
2035         /*
2036          * At this point most instructions can format the opcode mnemonic
2037          * including the prefixes.
2038          */
2039         if (lock_prefix)
2040                 (void) strlcat(x->d86_mneu, "lock ", OPLEN);
2041
2042         if (rep_prefix == 0xf2)
2043                 (void) strlcat(x->d86_mneu, "repnz ", OPLEN);
2044         else if (rep_prefix == 0xf3)
2045                 (void) strlcat(x->d86_mneu, "repz ", OPLEN);
2046
2047         if (cpu_mode == SIZE64 && addr_size_prefix)
2048                 (void) strlcat(x->d86_mneu, "addr32 ", OPLEN);
2049
2050         if (dp->it_adrmode != CBW &&
2051             dp->it_adrmode != CWD &&
2052             dp->it_adrmode != XMMSFNC) {
2053                 if (strcmp(dp->it_name, "INVALID") == 0)
2054                         goto error;
2055                 (void) strlcat(x->d86_mneu, dp->it_name, OPLEN);
2056                 if (dp->it_suffix) {
2057                         char *types[] = {"", "w", "l", "q"};
2058                         if (opcode_bytes == 2 && opcode4 == 4) {
2059                                 /* It's a cmovx.yy. Replace the suffix x */
2060                                 for (i = 5; i < OPLEN; i++) {
2061                                         if (x->d86_mneu[i] == '.')
2062                                                 break;
2063                                 }
2064                                 x->d86_mneu[i - 1] = *types[opnd_size];
2065                         } else {
2066                                 (void) strlcat(x->d86_mneu, types[opnd_size],
2067                                     OPLEN);
2068                         }
2069                 }
2070         }
2071 #endif
2072
2073         /*
2074          * Process operands based on the addressing modes.
2075          */
2076         x->d86_mode = cpu_mode;
2077         x->d86_rex_prefix = rex_prefix;
2078         x->d86_opnd_size = opnd_size;
2079         x->d86_addr_size = addr_size;
2080         vbit = 0;               /* initialize for mem/reg -> reg */
2081         switch (dp->it_adrmode) {
2082                 /*
2083                  * amd64 instruction to sign extend 32 bit reg/mem operands
2084                  * into 64 bit register values
2085                  */
2086         case MOVSXZ:
2087 #ifdef DIS_TEXT
2088                 if (rex_prefix == 0)
2089                         (void) strncpy(x->d86_mneu, "movzld", OPLEN);
2090 #endif
2091                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2092                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2093                 x->d86_opnd_size = SIZE64;
2094                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2095                 x->d86_opnd_size = opnd_size = SIZE32;
2096                 wbit = LONG_OPND;
2097                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2098                 break;
2099
2100                 /*
2101                  * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
2102                  * movzbl movzbw movzbq (0x0FB6) or mobzwl movzwq (0x0FB7)
2103                  * wbit lives in 2nd byte, note that operands
2104                  * are different sized
2105                  */
2106         case MOVZ:
2107                 if (rex_prefix & REX_W) {
2108                         /* target register size = 64 bit */
2109                         x->d86_mneu[5] = 'q';
2110                 }
2111                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2112                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2113                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2114                 x->d86_opnd_size = opnd_size = SIZE16;
2115                 wbit = WBIT(opcode5);
2116                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2117                 break;
2118
2119         /*
2120          * imul instruction, with either 8-bit or longer immediate
2121          * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
2122          */
2123         case IMUL:
2124                 wbit = LONG_OPND;
2125                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
2126                     OPSIZE(opnd_size, opcode2 == 0x9));
2127                 break;
2128
2129         /* memory or register operand to register, with 'w' bit */
2130         case MRw:
2131                 wbit = WBIT(opcode2);
2132                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2133                 break;
2134
2135         /* register to memory or register operand, with 'w' bit */
2136         /* arpl happens to fit here also because it is odd */
2137         case RMw:
2138                 if (opcode_bytes == 2)
2139                         wbit = WBIT(opcode5);
2140                 else
2141                         wbit = WBIT(opcode2);
2142                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2143                 break;
2144
2145         /* xaddb instruction */
2146         case XADDB:
2147                 wbit = 0;
2148                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2149                 break;
2150
2151         /* MMX register to memory or register operand           */
2152         case MMS:
2153         case MMOS:
2154 #ifdef DIS_TEXT
2155                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2156 #else
2157                 wbit = LONG_OPND;
2158 #endif
2159                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
2160                 break;
2161
2162         /* MMX register to memory */
2163         case MMOMS:
2164                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2165                 if (mode == REG_ONLY)
2166                         goto error;
2167                 wbit = MM_OPND;
2168                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
2169                 break;
2170
2171         /* Double shift. Has immediate operand specifying the shift. */
2172         case DSHIFT:
2173                 wbit = LONG_OPND;
2174                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2175                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2176                 dtrace_get_operand(x, mode, r_m, wbit, 2);
2177                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2178                 dtrace_imm_opnd(x, wbit, 1, 0);
2179                 break;
2180
2181         /*
2182          * Double shift. With no immediate operand, specifies using %cl.
2183          */
2184         case DSHIFTcl:
2185                 wbit = LONG_OPND;
2186                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2187                 break;
2188
2189         /* immediate to memory or register operand */
2190         case IMlw:
2191                 wbit = WBIT(opcode2);
2192                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2193                 dtrace_get_operand(x, mode, r_m, wbit, 1);
2194                 /*
2195                  * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
2196                  */
2197                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
2198                 break;
2199
2200         /* immediate to memory or register operand with the     */
2201         /* 'w' bit present                                      */
2202         case IMw:
2203                 wbit = WBIT(opcode2);
2204                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2205                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2206                 dtrace_get_operand(x, mode, r_m, wbit, 1);
2207                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
2208                 break;
2209
2210         /* immediate to register with register in low 3 bits    */
2211         /* of op code                                           */
2212         case IR:
2213                 /* w-bit here (with regs) is bit 3 */
2214                 wbit = opcode2 >>3 & 0x1;
2215                 reg = REGNO(opcode2);
2216                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2217                 mode = REG_ONLY;
2218                 r_m = reg;
2219                 dtrace_get_operand(x, mode, r_m, wbit, 1);
2220                 dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
2221                 break;
2222
2223         /* MMX immediate shift of register */
2224         case MMSH:
2225         case MMOSH:
2226                 wbit = MM_OPND;
2227                 goto mm_shift;  /* in next case */
2228
2229         /* SIMD immediate shift of register */
2230         case XMMSH:
2231                 wbit = XMM_OPND;
2232 mm_shift:
2233                 reg = REGNO(opcode7);
2234                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2235                 dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
2236                 dtrace_imm_opnd(x, wbit, 1, 0);
2237                 NOMEM;
2238                 break;
2239
2240         /* accumulator to memory operand */
2241         case AO:
2242                 vbit = 1;
2243                 /*FALLTHROUGH*/
2244
2245         /* memory operand to accumulator */
2246         case OA:
2247                 wbit = WBIT(opcode2);
2248                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
2249                 dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
2250 #ifdef DIS_TEXT
2251                 x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
2252 #endif
2253                 break;
2254
2255
2256         /* segment register to memory or register operand */
2257         case SM:
2258                 vbit = 1;
2259                 /*FALLTHROUGH*/
2260
2261         /* memory or register operand to segment register */
2262         case MS:
2263                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2264                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2265                 dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
2266                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
2267                 break;
2268
2269         /*
2270          * rotate or shift instructions, which may shift by 1 or
2271          * consult the cl register, depending on the 'v' bit
2272          */
2273         case Mv:
2274                 vbit = VBIT(opcode2);
2275                 wbit = WBIT(opcode2);
2276                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2277                 dtrace_get_operand(x, mode, r_m, wbit, 1);
2278 #ifdef DIS_TEXT
2279                 if (vbit) {
2280                         (void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
2281                 } else {
2282                         x->d86_opnd[0].d86_mode = MODE_SIGNED;
2283                         x->d86_opnd[0].d86_value_size = 1;
2284                         x->d86_opnd[0].d86_value = 1;
2285                 }
2286 #endif
2287                 break;
2288         /*
2289          * immediate rotate or shift instructions
2290          */
2291         case MvI:
2292                 wbit = WBIT(opcode2);
2293 normal_imm_mem:
2294                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2295                 dtrace_get_operand(x, mode, r_m, wbit, 1);
2296                 dtrace_imm_opnd(x, wbit, 1, 0);
2297                 break;
2298
2299         /* bit test instructions */
2300         case MIb:
2301                 wbit = LONG_OPND;
2302                 goto normal_imm_mem;
2303
2304         /* single memory or register operand with 'w' bit present */
2305         case Mw:
2306                 wbit = WBIT(opcode2);
2307 just_mem:
2308                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2309                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2310                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2311                 break;
2312
2313         case SWAPGS:
2314                 if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
2315 #ifdef DIS_TEXT
2316                         (void) strncpy(x->d86_mneu, "swapgs", OPLEN);
2317 #endif
2318                         NOMEM;
2319                         break;
2320                 }
2321                 /*FALLTHROUGH*/
2322
2323         /* prefetch instruction - memory operand, but no memory acess */
2324         case PREF:
2325                 NOMEM;
2326                 /*FALLTHROUGH*/
2327
2328         /* single memory or register operand */
2329         case M:
2330                 wbit = LONG_OPND;
2331                 goto just_mem;
2332
2333         /* single memory or register byte operand */
2334         case Mb:
2335                 wbit = BYTE_OPND;
2336                 goto just_mem;
2337
2338         case MO:
2339                 /* Similar to M, but only memory (no direct registers) */
2340                 wbit = LONG_OPND;
2341                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2342                 if (mode == 3)