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