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