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