]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/cddl/dev/dtrace/i386/dis_tables.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / 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,                TS("nopw", Mw),
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),           TNS("%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),           TNS("%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),           TNS("%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),           TNS("%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)
2343                         goto error;
2344                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2345                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2346                 break;
2347
2348         /* move special register to register or reverse if vbit */
2349         case SREG:
2350                 switch (opcode5) {
2351
2352                 case 2:
2353                         vbit = 1;
2354                         /*FALLTHROUGH*/
2355                 case 0:
2356                         wbit = CONTROL_OPND;
2357                         break;
2358
2359                 case 3:
2360                         vbit = 1;
2361                         /*FALLTHROUGH*/
2362                 case 1:
2363                         wbit = DEBUG_OPND;
2364                         break;
2365
2366                 case 6:
2367                         vbit = 1;
2368                         /*FALLTHROUGH*/
2369                 case 4:
2370                         wbit = TEST_OPND;
2371                         break;
2372
2373                 }
2374                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2375                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2376                 dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
2377                 dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
2378                 NOMEM;
2379                 break;
2380
2381         /*
2382          * single register operand with register in the low 3
2383          * bits of op code
2384          */
2385         case R:
2386                 if (opcode_bytes == 2)
2387                         reg = REGNO(opcode5);
2388                 else
2389                         reg = REGNO(opcode2);
2390                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2391                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
2392                 NOMEM;
2393                 break;
2394
2395         /*
2396          * register to accumulator with register in the low 3
2397          * bits of op code, xchg instructions
2398          */
2399         case RA:
2400                 NOMEM;
2401                 reg = REGNO(opcode2);
2402                 dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2403                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
2404                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
2405                 break;
2406
2407         /*
2408          * single segment register operand, with register in
2409          * bits 3-4 of op code byte
2410          */
2411         case SEG:
2412                 NOMEM;
2413                 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
2414                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
2415                 break;
2416
2417         /*
2418          * single segment register operand, with register in
2419          * bits 3-5 of op code
2420          */
2421         case LSEG:
2422                 NOMEM;
2423                 /* long seg reg from opcode */
2424                 reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
2425                 dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
2426                 break;
2427
2428         /* memory or register operand to register */
2429         case MR:
2430                 wbit = LONG_OPND;
2431                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2432                 break;
2433
2434         case RM:
2435                 wbit = LONG_OPND;
2436                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2437                 break;
2438
2439         /* MMX/SIMD-Int memory or mm reg to mm reg              */
2440         case MM:
2441         case MMO:
2442 #ifdef DIS_TEXT
2443                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2444 #else
2445                 wbit = LONG_OPND;
2446 #endif
2447                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
2448                 break;
2449
2450         case MMOIMPL:
2451 #ifdef DIS_TEXT
2452                 wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2453 #else
2454                 wbit = LONG_OPND;
2455 #endif
2456                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2457                 if (mode != REG_ONLY)
2458                         goto error;
2459
2460                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2461                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2462                 dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
2463                 mode = 0;       /* change for memory access size... */
2464                 break;
2465
2466         /* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
2467         case MMO3P:
2468                 wbit = MM_OPND;
2469                 goto xmm3p;
2470         case XMM3P:
2471                 wbit = XMM_OPND;
2472 xmm3p:
2473                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2474                 if (mode != REG_ONLY)
2475                         goto error;
2476
2477                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1);
2478                 NOMEM;
2479                 break;
2480
2481         /* MMX/SIMD-Int predicated r32/mem to mm reg */
2482         case MMOPRM:
2483                 wbit = LONG_OPND;
2484                 w2 = MM_OPND;
2485                 goto xmmprm;
2486         case XMMPRM:
2487                 wbit = LONG_OPND;
2488                 w2 = XMM_OPND;
2489 xmmprm:
2490                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1);
2491                 break;
2492
2493         /* MMX/SIMD-Int predicated mm/mem to mm reg */
2494         case MMOPM:
2495                 wbit = w2 = MM_OPND;
2496                 goto xmmprm;
2497
2498         /* MMX/SIMD-Int mm reg to r32 */
2499         case MMOM3:
2500                 NOMEM;
2501                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2502                 if (mode != REG_ONLY)
2503                         goto error;
2504                 wbit = MM_OPND;
2505                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
2506                 break;
2507
2508         /* SIMD memory or xmm reg operand to xmm reg            */
2509         case XMM:
2510         case XMMO:
2511         case XMMXIMPL:
2512                 wbit = XMM_OPND;
2513                 STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2514
2515                 if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
2516                         goto error;
2517
2518 #ifdef DIS_TEXT
2519                 /*
2520                  * movlps and movhlps share opcodes.  They differ in the
2521                  * addressing modes allowed for their operands.
2522                  * movhps and movlhps behave similarly.
2523                  */
2524                 if (mode == REG_ONLY) {
2525                         if (strcmp(dp->it_name, "movlps") == 0)
2526                                 (void) strncpy(x->d86_mneu, "movhlps", OPLEN);
2527                         else if (strcmp(dp->it_name, "movhps") == 0)
2528                                 (void) strncpy(x->d86_mneu, "movlhps", OPLEN);
2529                 }
2530 #endif
2531                 if (dp->it_adrmode == XMMXIMPL)
2532                         mode = 0;       /* change for memory access size... */
2533                 break;
2534
2535         /* SIMD xmm reg to memory or xmm reg */
2536         case XMMS:
2537         case XMMOS:
2538         case XMMMS:
2539         case XMMOMS:
2540                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2541 #ifdef DIS_TEXT
2542                 if ((strcmp(dp->it_name, "movlps") == 0 ||
2543                     strcmp(dp->it_name, "movhps") == 0 ||
2544                     strcmp(dp->it_name, "movntps") == 0) &&
2545                     mode == REG_ONLY)
2546                         goto error;
2547 #endif
2548                 wbit = XMM_OPND;
2549                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
2550                 break;
2551
2552         /* SIMD memory to xmm reg */
2553         case XMMM:
2554         case XMMOM:
2555                 wbit = XMM_OPND;
2556                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2557 #ifdef DIS_TEXT
2558                 if (mode == REG_ONLY) {
2559                         if (strcmp(dp->it_name, "movhps") == 0)
2560                                 (void) strncpy(x->d86_mneu, "movlhps", OPLEN);
2561                         else
2562                                 goto error;
2563                 }
2564 #endif
2565                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2566                 break;
2567
2568         /* SIMD memory or r32 to xmm reg                        */
2569         case XMM3MX:
2570                 wbit = LONG_OPND;
2571                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2572                 break;
2573
2574         case XMM3MXS:
2575                 wbit = LONG_OPND;
2576                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
2577                 break;
2578
2579         /* SIMD memory or mm reg to xmm reg                     */
2580         case XMMOMX:
2581         /* SIMD mm to xmm */
2582         case XMMMX:
2583                 wbit = MM_OPND;
2584                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2585                 break;
2586
2587         /* SIMD memory or xmm reg to mm reg                     */
2588         case XMMXMM:
2589         case XMMOXMM:
2590         case XMMXM:
2591                 wbit = XMM_OPND;
2592                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
2593                 break;
2594
2595
2596         /* SIMD memory or xmm reg to r32                        */
2597         case XMMXM3:
2598                 wbit = XMM_OPND;
2599                 MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
2600                 break;
2601
2602         /* SIMD xmm to r32                                      */
2603         case XMMX3:
2604         case XMMOX3:
2605                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2606                 if (mode != REG_ONLY)
2607                         goto error;
2608                 dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2609                 dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
2610                 dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2611                 NOMEM;
2612                 break;
2613
2614         /* SIMD predicated memory or xmm reg with/to xmm reg */
2615         case XMMP:
2616         case XMMOPM:
2617                 wbit = XMM_OPND;
2618                 THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
2619
2620 #ifdef DIS_TEXT
2621                 /*
2622                  * cmpps and cmpss vary their instruction name based
2623                  * on the value of imm8.  Other XMMP instructions,
2624                  * such as shufps, require explicit specification of
2625                  * the predicate.
2626                  */
2627                 if (dp->it_name[0] == 'c' &&
2628                     dp->it_name[1] == 'm' &&
2629                     dp->it_name[2] == 'p' &&
2630                     strlen(dp->it_name) == 5) {
2631                         uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
2632
2633                         if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
2634                                 goto error;
2635
2636                         (void) strncpy(x->d86_mneu, "cmp", OPLEN);
2637                         (void) strlcat(x->d86_mneu, dis_PREDSUFFIX[pred],
2638                             OPLEN);
2639                         (void) strlcat(x->d86_mneu,
2640                             dp->it_name + strlen(dp->it_name) - 2,
2641                             OPLEN);
2642                         x->d86_opnd[0] = x->d86_opnd[1];
2643                         x->d86_opnd[1] = x->d86_opnd[2];
2644                         x->d86_numopnds = 2;
2645                 }
2646 #endif
2647                 break;
2648
2649         /* immediate operand to accumulator */
2650         case IA:
2651                 wbit = WBIT(opcode2);
2652                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
2653                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
2654                 NOMEM;
2655                 break;
2656
2657         /* memory or register operand to accumulator */
2658         case MA:
2659                 wbit = WBIT(opcode2);
2660                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2661                 dtrace_get_operand(x, mode, r_m, wbit, 0);
2662                 break;
2663
2664         /* si register to di register used to reference memory          */
2665         case SD:
2666 #ifdef DIS_TEXT
2667                 dtrace_check_override(x, 0);
2668                 x->d86_numopnds = 2;
2669                 if (addr_size == SIZE64) {
2670                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
2671                             OPLEN);
2672                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
2673                             OPLEN);
2674                 } else if (addr_size == SIZE32) {
2675                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
2676                             OPLEN);
2677                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
2678                             OPLEN);
2679                 } else {
2680                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
2681                             OPLEN);
2682                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
2683                             OPLEN);
2684                 }
2685 #endif
2686                 wbit = LONG_OPND;
2687                 break;
2688
2689         /* accumulator to di register                           */
2690         case AD:
2691                 wbit = WBIT(opcode2);
2692 #ifdef DIS_TEXT
2693                 dtrace_check_override(x, 1);
2694                 x->d86_numopnds = 2;
2695                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
2696                 if (addr_size == SIZE64)
2697                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
2698                             OPLEN);
2699                 else if (addr_size == SIZE32)
2700                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
2701                             OPLEN);
2702                 else
2703                         (void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
2704                             OPLEN);
2705 #endif
2706                 break;
2707
2708         /* si register to accumulator                           */
2709         case SA:
2710                 wbit = WBIT(opcode2);
2711 #ifdef DIS_TEXT
2712                 dtrace_check_override(x, 0);
2713                 x->d86_numopnds = 2;
2714                 if (addr_size == SIZE64)
2715                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
2716                             OPLEN);
2717                 else if (addr_size == SIZE32)
2718                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
2719                             OPLEN);
2720                 else
2721                         (void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
2722                             OPLEN);
2723                 dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
2724 #endif
2725                 break;
2726
2727         /*
2728          * single operand, a 16/32 bit displacement
2729          */
2730         case D:
2731                 wbit = LONG_OPND;
2732                 dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
2733                 NOMEM;
2734                 break;
2735
2736         /* jmp/call indirect to memory or register operand              */
2737         case INM:
2738 #ifdef DIS_TEXT
2739                 (void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
2740 #endif
2741                 dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2742                 dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
2743                 wbit = LONG_OPND;
2744                 break;
2745
2746         /*
2747          * for long jumps and long calls -- a new code segment
2748          * register and an offset in IP -- stored in object
2749          * code in reverse order. Note - not valid in amd64
2750          */
2751         case SO:
2752                 dtrace_check_override(x, 1);
2753                 wbit = LONG_OPND;
2754                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
2755 #ifdef DIS_TEXT
2756                 x->d86_opnd[1].d86_mode = MODE_SIGNED;
2757 #endif
2758                 /* will now get segment operand */
2759                 dtrace_imm_opnd(x, wbit, 2, 0);
2760                 break;
2761
2762         /*
2763          * jmp/call. single operand, 8 bit displacement.
2764          * added to current EIP in 'compofff'
2765          */
2766         case BD:
2767                 dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
2768                 NOMEM;
2769                 break;
2770
2771         /* single 32/16 bit immediate operand                   */
2772         case I:
2773                 wbit = LONG_OPND;
2774                 dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
2775                 break;
2776
2777         /* single 8 bit immediate operand                       */
2778         case Ib:
2779                 wbit = LONG_OPND;
2780                 dtrace_imm_opnd(x, wbit, 1, 0);
2781                 break;
2782
2783         case ENTER:
2784                 wbit = LONG_OPND;
2785                 dtrace_imm_opnd(x, wbit, 2, 0);
2786                 dtrace_imm_opnd(x, wbit, 1, 1);
2787                 switch (opnd_size) {
2788                 case SIZE64:
2789                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
2790                         break;
2791                 case SIZE32:
2792                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
2793                         break;
2794                 case SIZE16:
2795                         x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
2796                         break;
2797                 }
2798
2799                 break;
2800
2801         /* 16-bit immediate operand */
2802         case RET:
2803                 wbit = LONG_OPND;
2804                 dtrace_imm_opnd(x, wbit, 2, 0);
2805                 break;
2806
2807         /* single 8 bit port operand                            */
2808         case P:
2809                 dtrace_check_override(x, 0);
2810                 dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
2811                 NOMEM;
2812                 break;
2813
2814         /* single operand, dx register (variable port instruction) */
2815         case V:
2816                 x->d86_numopnds = 1;
2817                 dtrace_check_override(x, 0);
2818 #ifdef DIS_TEXT
2819                 (void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
2820 #endif
2821                 NOMEM;
2822                 break;
2823
2824         /*
2825          * The int instruction, which has two forms:
2826          * int 3 (breakpoint) or
2827          * int n, where n is indicated in the subsequent
2828          * byte (format Ib).  The int 3 instruction (opcode 0xCC),
2829          * where, although the 3 looks  like an operand,
2830          * it is implied by the opcode. It must be converted
2831          * to the correct base and output.
2832          */
2833         case INT3:
2834 #ifdef DIS_TEXT
2835                 x->d86_numopnds = 1;
2836                 x->d86_opnd[0].d86_mode = MODE_SIGNED;
2837                 x->d86_opnd[0].d86_value_size = 1;
2838                 x->d86_opnd[0].d86_value = 3;
2839 #endif
2840                 NOMEM;
2841                 break;
2842
2843         /* single 8 bit immediate operand                       */
2844         case INTx:
2845                 dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
2846                 NOMEM;
2847                 break;
2848
2849         /* an unused byte must be discarded */
2850         case U:
2851                 if (x->d86_get_byte(x->d86_data) < 0)
2852                         goto error;
2853                 x->d86_len++;
2854                 NOMEM;
2855                 break;
2856
2857         case CBW:
2858 #ifdef DIS_TEXT
2859                 if (opnd_size == SIZE16)
2860                         (void) strlcat(x->d86_mneu, "cbtw", OPLEN);
2861                 else if (opnd_size == SIZE32)
2862                         (void) strlcat(x->d86_mneu, "cwtl", OPLEN);
2863                 else
2864                         (void) strlcat(x->d86_mneu, "cltq", OPLEN);
2865 #endif
2866                 wbit = LONG_OPND;
2867                 NOMEM;
2868                 break;
2869
2870         case CWD:
2871 #ifdef DIS_TEXT
2872                 if (opnd_size == SIZE16)
2873                         (void) strlcat(x->d86_mneu, "cwtd", OPLEN);
2874                 else if (opnd_size == SIZE32)
2875                         (void) strlcat(x->d86_mneu, "cltd", OPLEN);
2876                 else
2877                         (void) strlcat(x->d86_mneu, "cqtd", OPLEN);
2878 #endif
2879                 wbit = LONG_OPND;
2880                 NOMEM;
2881                 break;
2882
2883         case XMMSFNC:
2884                 /*
2885                  * sfence is sfence if mode is REG_ONLY.  If mode isn't
2886                  * REG_ONLY, mnemonic should be 'clflush'.
2887                  */
2888                 dtrace_get_modrm(x, &mode, &reg, &r_m);
2889
2890                 /* sfence doesn't take operands */
2891 #ifdef DIS_TEXT
2892                 if (mode == REG_ONLY) {
2893                         (void) strlcat(x->d86_mneu, "sfence", OPLEN);
2894                 } else {
2895                         (void) strlcat(x->d86_mneu, "clflush", OPLEN);
2896                         dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2897                         dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
2898                         NOMEM;
2899                 }
2900 #else
2901                 if (mode != REG_ONLY) {
2902                         dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2903                         dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
2904                         NOMEM;
2905                 }
2906 #endif
2907                 break;
2908
2909         /*
2910          * no disassembly, the mnemonic was all there was so go on
2911          */
2912         case NORM:
2913                 if (dp->it_invalid32 && cpu_mode != SIZE64)
2914                         goto error;
2915                 NOMEM;
2916                 /*FALLTHROUGH*/
2917         case IMPLMEM:
2918                 break;
2919
2920         case XMMFENCE:
2921                 /*
2922                  * Only the following exact byte sequences are allowed:
2923                  *
2924                  *      0f ae e8        lfence
2925                  *      0f ae f0        mfence
2926                  */
2927                 if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
2928                     (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
2929                         goto error;
2930
2931                 break;
2932
2933
2934         /* float reg */
2935         case F:
2936 #ifdef DIS_TEXT
2937                 x->d86_numopnds = 1;
2938                 (void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
2939                 x->d86_opnd[0].d86_opnd[4] = r_m + '0';
2940 #endif
2941                 NOMEM;
2942                 break;
2943
2944         /* float reg to float reg, with ret bit present */
2945         case FF:
2946                 vbit = opcode2 >> 2 & 0x1;      /* vbit = 1: st -> st(i) */
2947                 /*FALLTHROUGH*/
2948         case FFC:                               /* case for vbit always = 0 */
2949 #ifdef DIS_TEXT
2950                 x->d86_numopnds = 2;
2951                 (void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
2952                 (void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
2953                 x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
2954 #endif
2955                 NOMEM;
2956                 break;
2957
2958         /* an invalid op code */
2959         case AM:
2960         case DM:
2961         case OVERRIDE:
2962         case PREFIX:
2963         case UNKNOWN:
2964                 NOMEM;
2965         default:
2966                 goto error;
2967         } /* end switch */
2968         if (x->d86_error)
2969                 goto error;
2970
2971 done:
2972 #ifdef DIS_MEM
2973         /*
2974          * compute the size of any memory accessed by the instruction
2975          */
2976         if (x->d86_memsize != 0) {
2977                 return (0);
2978         } else if (dp->it_stackop) {
2979                 switch (opnd_size) {
2980                 case SIZE16:
2981                         x->d86_memsize = 2;
2982                         break;
2983                 case SIZE32:
2984                         x->d86_memsize = 4;
2985                         break;
2986                 case SIZE64:
2987                         x->d86_memsize = 8;
2988                         break;
2989                 }
2990         } else if (nomem || mode == REG_ONLY) {
2991                 x->d86_memsize = 0;
2992
2993         } else if (dp->it_size != 0) {
2994                 /*
2995                  * In 64 bit mode descriptor table entries
2996                  * go up to 10 bytes and popf/pushf are always 8 bytes
2997                  */
2998                 if (x->d86_mode == SIZE64 && dp->it_size == 6)
2999                         x->d86_memsize = 10;
3000                 else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
3001                     (opcode2 == 0xc || opcode2 == 0xd))
3002                         x->d86_memsize = 8;
3003                 else
3004                         x->d86_memsize = dp->it_size;
3005
3006         } else if (wbit == 0) {
3007                 x->d86_memsize = 1;
3008
3009         } else if (wbit == LONG_OPND) {
3010                 if (opnd_size == SIZE64)
3011                         x->d86_memsize = 8;
3012                 else if (opnd_size == SIZE32)
3013                         x->d86_memsize = 4;
3014                 else
3015                         x->d86_memsize = 2;
3016
3017         } else if (wbit == SEG_OPND) {
3018                 x->d86_memsize = 4;
3019
3020         } else {
3021                 x->d86_memsize = 8;
3022         }
3023 #endif
3024         return (0);
3025
3026 error:
3027 #ifdef DIS_TEXT
3028         (void) strlcat(x->d86_mneu, "undef", OPLEN);
3029 #endif
3030         return (1);
3031 }
3032
3033 #ifdef DIS_TEXT
3034
3035 /*
3036  * Some instructions should have immediate operands printed
3037  * as unsigned integers. We compare against this table.
3038  */
3039 static char *unsigned_ops[] = {
3040         "or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
3041         "rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
3042         0
3043 };
3044
3045 static int
3046 isunsigned_op(char *opcode)
3047 {
3048         char *where;
3049         int i;
3050         int is_unsigned = 0;
3051
3052         /*
3053          * Work back to start of last mnemonic, since we may have
3054          * prefixes on some opcodes.
3055          */
3056         where = opcode + strlen(opcode) - 1;
3057         while (where > opcode && *where != ' ')
3058                 --where;
3059         if (*where == ' ')
3060                 ++where;
3061
3062         for (i = 0; unsigned_ops[i]; ++i) {
3063                 if (strncmp(where, unsigned_ops[i],
3064                     strlen(unsigned_ops[i])))
3065                         continue;
3066                 is_unsigned = 1;
3067                 break;
3068         }
3069         return (is_unsigned);
3070 }
3071
3072 /* ARGSUSED */
3073 void
3074 dtrace_disx86_str(dis86_t *dis, uint_t mode, uintptr_t pc, char *buf,
3075     size_t buflen)
3076 {
3077         int i;
3078
3079         dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mneu);
3080
3081         /*
3082          * For PC-relative jumps, the pc is really the next pc after executing
3083          * this instruction, so increment it appropriately.
3084          */
3085         pc += dis->d86_len;
3086
3087         for (i = 0; i < dis->d86_numopnds; i++) {
3088                 d86opnd_t *op = &dis->d86_opnd[i];
3089                 int64_t sv;
3090                 uint64_t mask;
3091
3092                 if (i != 0)
3093                         (void) strlcat(buf, ",", buflen);
3094
3095                 (void) strlcat(buf, op->d86_prefix, buflen);
3096
3097                 sv = op->d86_value;
3098
3099                 switch (op->d86_mode) {
3100
3101                 case MODE_NONE:
3102
3103                         (void) strlcat(buf, op->d86_opnd, buflen);
3104                         break;
3105
3106                 case MODE_SIGNED:
3107                 case MODE_IMPLIED:
3108                 case MODE_OFFSET:
3109
3110                         if (dis->d86_seg_prefix)
3111                                 (void) strlcat(buf, dis->d86_seg_prefix,
3112                                     buflen);
3113
3114                         switch (op->d86_value_size) {
3115                         case 1:
3116                                 sv = (int8_t)sv;
3117                                 mask = 0xff;
3118                                 break;
3119                         case 2:
3120                                 sv = (int16_t)sv;
3121                                 mask = 0xffff;
3122                                 break;
3123                         case 4:
3124                                 sv = (int32_t)sv;
3125                                 mask = 0xffffffff;
3126                                 break;
3127                         case 8:
3128                                 mask = 0xffffffffffffffffULL;
3129                                 break;
3130                         }
3131
3132                         if (op->d86_mode == MODE_SIGNED ||
3133                             op->d86_mode == MODE_IMPLIED)
3134                                 (void) strlcat(buf, "$", buflen);
3135
3136                         if (sv < 0 && sv > -0xffff &&
3137                             !isunsigned_op(dis->d86_mneu)) {
3138                                 dis->d86_sprintf_func(buf + strlen(buf),
3139                                     buflen - strlen(buf),
3140                                     (dis->d86_flags & DIS_OP_OCTAL) ?
3141                                     "-0%llo" : "-0x%llx", -sv & mask);
3142                         } else {
3143                                 dis->d86_sprintf_func(buf + strlen(buf),
3144                                     buflen - strlen(buf),
3145                                     (dis->d86_flags & DIS_OP_OCTAL) ?
3146                                     "0%llo" : "0x%llx", sv & mask);
3147                         }
3148                         (void) strlcat(buf, op->d86_opnd, buflen);
3149                         break;
3150
3151                 case MODE_IPREL:
3152
3153                         switch (op->d86_value_size) {
3154                         case 1:
3155                                 sv = (int8_t)sv;
3156                                 break;
3157                         case 2:
3158                                 sv = (int16_t)sv;
3159                                 break;
3160                         case 4:
3161                                 sv = (int32_t)sv;
3162                                 break;
3163                         }
3164
3165                         if (sv < 0)
3166                                 dis->d86_sprintf_func(buf + strlen(buf),
3167                                     buflen - strlen(buf),
3168                                     (dis->d86_flags & DIS_OP_OCTAL) ?
3169                                     "-0%llo" : "-0x%llx", -sv - dis->d86_len);
3170                         else
3171                                 dis->d86_sprintf_func(buf + strlen(buf),
3172                                     buflen - strlen(buf),
3173                                     (dis->d86_flags & DIS_OP_OCTAL) ?
3174                                     "+0%llo" : "+0x%llx", sv + dis->d86_len);
3175
3176                         (void) strlcat(buf, "\t<", buflen);
3177
3178                         if (dis->d86_sym_lookup == NULL ||
3179                             dis->d86_sym_lookup(dis->d86_data, pc + sv,
3180                             buf + strlen(buf), buflen - strlen(buf)) != 0)
3181                                 dis->d86_sprintf_func(buf + strlen(buf),
3182                                     buflen - strlen(buf),
3183                                     (dis->d86_flags & DIS_OP_OCTAL) ?
3184                                     "0%llo" : "0x%llx", pc + sv);
3185
3186                         (void) strlcat(buf, ">", buflen);
3187
3188                         break;
3189                 }
3190         }
3191 }
3192
3193 #endif /* DIS_TEXT */