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