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