xref: /titanic_52/usr/src/common/dis/i386/dis_tables.c (revision b9bd317cda1afb3a01f4812de73e8cec888cbbd7)
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 /*
1417  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
1418  */
1419 static int isize[] = {1, 2, 4, 4};
1420 static int isize64[] = {1, 2, 4, 8};
1421 
1422 /*
1423  * Just a bunch of useful macros.
1424  */
1425 #define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
1426 #define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
1427 #define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
1428 #define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
1429 #define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
1430 
1431 #define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
1432 
1433 #define	BYTE_OPND	0	/* w-bit value indicating byte register */
1434 #define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
1435 #define	MM_OPND		2	/* "value" used to indicate a mmx reg */
1436 #define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
1437 #define	SEG_OPND	4	/* "value" used to indicate a segment reg */
1438 #define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
1439 #define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
1440 #define	TEST_OPND	7	/* "value" used to indicate a test reg */
1441 #define	WORD_OPND	8	/* w-bit value indicating word size reg */
1442 
1443 /*
1444  * Get the next byte and separate the op code into the high and low nibbles.
1445  */
1446 static int
1447 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
1448 {
1449 	int byte;
1450 
1451 	/*
1452 	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
1453 	 * we try to read more.
1454 	 */
1455 	if (x->d86_len >= 15)
1456 		return (x->d86_error = 1);
1457 
1458 	if (x->d86_error)
1459 		return (1);
1460 	byte = x->d86_get_byte(x->d86_data);
1461 	if (byte < 0)
1462 		return (x->d86_error = 1);
1463 	x->d86_bytes[x->d86_len++] = byte;
1464 	*low = byte & 0xf;		/* ----xxxx low 4 bits */
1465 	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
1466 	return (0);
1467 }
1468 
1469 /*
1470  * Get and decode an SIB (scaled index base) byte
1471  */
1472 static void
1473 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
1474 {
1475 	int byte;
1476 
1477 	if (x->d86_error)
1478 		return;
1479 
1480 	byte = x->d86_get_byte(x->d86_data);
1481 	if (byte < 0) {
1482 		x->d86_error = 1;
1483 		return;
1484 	}
1485 	x->d86_bytes[x->d86_len++] = byte;
1486 
1487 	*base = byte & 0x7;
1488 	*index = (byte >> 3) & 0x7;
1489 	*ss = (byte >> 6) & 0x3;
1490 }
1491 
1492 /*
1493  * Get the byte following the op code and separate it into the
1494  * mode, register, and r/m fields.
1495  */
1496 static void
1497 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
1498 {
1499 	if (x->d86_got_modrm == 0) {
1500 		if (x->d86_rmindex == -1)
1501 			x->d86_rmindex = x->d86_len;
1502 		dtrace_get_SIB(x, mode, reg, r_m);
1503 		x->d86_got_modrm = 1;
1504 	}
1505 }
1506 
1507 /*
1508  * Adjust register selection based on any REX prefix bits present.
1509  */
1510 /*ARGSUSED*/
1511 static void
1512 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
1513 {
1514 	if (reg != NULL && r_m == NULL) {
1515 		if (rex_prefix & REX_B)
1516 			*reg += 8;
1517 	} else {
1518 		if (reg != NULL && (REX_R & rex_prefix) != 0)
1519 			*reg += 8;
1520 		if (r_m != NULL && (REX_B & rex_prefix) != 0)
1521 			*r_m += 8;
1522 	}
1523 }
1524 
1525 /*
1526  * Get an immediate operand of the given size, with sign extension.
1527  */
1528 static void
1529 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
1530 {
1531 	int i;
1532 	int byte;
1533 	int valsize;
1534 
1535 	if (x->d86_numopnds < opindex + 1)
1536 		x->d86_numopnds = opindex + 1;
1537 
1538 	switch (wbit) {
1539 	case BYTE_OPND:
1540 		valsize = 1;
1541 		break;
1542 	case LONG_OPND:
1543 		if (x->d86_opnd_size == SIZE16)
1544 			valsize = 2;
1545 		else if (x->d86_opnd_size == SIZE32)
1546 			valsize = 4;
1547 		else
1548 			valsize = 8;
1549 		break;
1550 	case MM_OPND:
1551 	case XMM_OPND:
1552 	case SEG_OPND:
1553 	case CONTROL_OPND:
1554 	case DEBUG_OPND:
1555 	case TEST_OPND:
1556 		valsize = size;
1557 		break;
1558 	case WORD_OPND:
1559 		valsize = 2;
1560 		break;
1561 	}
1562 	if (valsize < size)
1563 		valsize = size;
1564 
1565 	if (x->d86_error)
1566 		return;
1567 	x->d86_opnd[opindex].d86_value = 0;
1568 	for (i = 0; i < size; ++i) {
1569 		byte = x->d86_get_byte(x->d86_data);
1570 		if (byte < 0) {
1571 			x->d86_error = 1;
1572 			return;
1573 		}
1574 		x->d86_bytes[x->d86_len++] = byte;
1575 		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
1576 	}
1577 	/* Do sign extension */
1578 	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
1579 		for (; i < sizeof (uint64_t); i++)
1580 			x->d86_opnd[opindex].d86_value |=
1581 			    (uint64_t)0xff << (i * 8);
1582 	}
1583 #ifdef DIS_TEXT
1584 	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
1585 	x->d86_opnd[opindex].d86_value_size = valsize;
1586 	x->d86_imm_bytes += size;
1587 #endif
1588 }
1589 
1590 /*
1591  * Get an ip relative operand of the given size, with sign extension.
1592  */
1593 static void
1594 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
1595 {
1596 	dtrace_imm_opnd(x, wbit, size, opindex);
1597 #ifdef DIS_TEXT
1598 	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
1599 #endif
1600 }
1601 
1602 /*
1603  * Check to see if there is a segment override prefix pending.
1604  * If so, print it in the current 'operand' location and set
1605  * the override flag back to false.
1606  */
1607 /*ARGSUSED*/
1608 static void
1609 dtrace_check_override(dis86_t *x, int opindex)
1610 {
1611 #ifdef DIS_TEXT
1612 	if (x->d86_seg_prefix) {
1613 		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
1614 		    x->d86_seg_prefix, PFIXLEN);
1615 	}
1616 #endif
1617 	x->d86_seg_prefix = NULL;
1618 }
1619 
1620 
1621 /*
1622  * Process a single instruction Register or Memory operand.
1623  *
1624  * mode = addressing mode from ModRM byte
1625  * r_m = r_m (or reg if mode == 3) field from ModRM byte
1626  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
1627  * o = index of operand that we are processing (0, 1 or 2)
1628  *
1629  * the value of reg or r_m must have already been adjusted for any REX prefix.
1630  */
1631 /*ARGSUSED*/
1632 static void
1633 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
1634 {
1635 	int have_SIB = 0;	/* flag presence of scale-index-byte */
1636 	uint_t ss;		/* scale-factor from opcode */
1637 	uint_t index;		/* index register number */
1638 	uint_t base;		/* base register number */
1639 	int dispsize;   	/* size of displacement in bytes */
1640 #ifdef DIS_TEXT
1641 	char *opnd = x->d86_opnd[opindex].d86_opnd;
1642 #endif
1643 
1644 	if (x->d86_numopnds < opindex + 1)
1645 		x->d86_numopnds = opindex + 1;
1646 
1647 	if (x->d86_error)
1648 		return;
1649 
1650 	/*
1651 	 * first handle a simple register
1652 	 */
1653 	if (mode == REG_ONLY) {
1654 #ifdef DIS_TEXT
1655 		switch (wbit) {
1656 		case MM_OPND:
1657 			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
1658 			break;
1659 		case XMM_OPND:
1660 			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
1661 			break;
1662 		case SEG_OPND:
1663 			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
1664 			break;
1665 		case CONTROL_OPND:
1666 			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
1667 			break;
1668 		case DEBUG_OPND:
1669 			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
1670 			break;
1671 		case TEST_OPND:
1672 			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
1673 			break;
1674 		case BYTE_OPND:
1675 			if (x->d86_rex_prefix == 0)
1676 				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
1677 			else
1678 				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
1679 			break;
1680 		case WORD_OPND:
1681 			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
1682 			break;
1683 		case LONG_OPND:
1684 			if (x->d86_opnd_size == SIZE16)
1685 				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
1686 			else if (x->d86_opnd_size == SIZE32)
1687 				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
1688 			else
1689 				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
1690 			break;
1691 		}
1692 #endif /* DIS_TEXT */
1693 		return;
1694 	}
1695 
1696 	/*
1697 	 * if symbolic representation, skip override prefix, if any
1698 	 */
1699 	dtrace_check_override(x, opindex);
1700 
1701 	/*
1702 	 * Handle 16 bit memory references first, since they decode
1703 	 * the mode values more simply.
1704 	 * mode 1 is r_m + 8 bit displacement
1705 	 * mode 2 is r_m + 16 bit displacement
1706 	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
1707 	 */
1708 	if (x->d86_addr_size == SIZE16) {
1709 		if ((mode == 0 && r_m == 6) || mode == 2)
1710 			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
1711 		else if (mode == 1)
1712 			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
1713 #ifdef DIS_TEXT
1714 		if (mode == 0 && r_m == 6)
1715 			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
1716 		else if (mode == 0)
1717 			x->d86_opnd[opindex].d86_mode = MODE_NONE;
1718 		else
1719 			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
1720 		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
1721 #endif
1722 		return;
1723 	}
1724 
1725 	/*
1726 	 * 32 and 64 bit addressing modes are more complex since they
1727 	 * can involve an SIB (scaled index and base) byte to decode.
1728 	 */
1729 	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
1730 		have_SIB = 1;
1731 		dtrace_get_SIB(x, &ss, &index, &base);
1732 		if (x->d86_error)
1733 			return;
1734 		if (base != 5 || mode != 0)
1735 			if (x->d86_rex_prefix & REX_B)
1736 				base += 8;
1737 		if (x->d86_rex_prefix & REX_X)
1738 			index += 8;
1739 	} else {
1740 		base = r_m;
1741 	}
1742 
1743 	/*
1744 	 * Compute the displacement size and get its bytes
1745 	 */
1746 	dispsize = 0;
1747 
1748 	if (mode == 1)
1749 		dispsize = 1;
1750 	else if (mode == 2)
1751 		dispsize = 4;
1752 	else if ((r_m & 7) == EBP_REGNO ||
1753 	    (have_SIB && (base & 7) == EBP_REGNO))
1754 		dispsize = 4;
1755 
1756 	if (dispsize > 0) {
1757 		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
1758 		    dispsize, opindex);
1759 		if (x->d86_error)
1760 			return;
1761 	}
1762 
1763 #ifdef DIS_TEXT
1764 	if (dispsize > 0)
1765 		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
1766 
1767 	if (have_SIB == 0) {
1768 		if (x->d86_mode == SIZE32) {
1769 			if (mode == 0)
1770 				(void) strlcat(opnd, dis_addr32_mode0[r_m],
1771 				    OPLEN);
1772 			else
1773 				(void) strlcat(opnd, dis_addr32_mode12[r_m],
1774 				    OPLEN);
1775 		} else {
1776 			if (mode == 0) {
1777 				(void) strlcat(opnd, dis_addr64_mode0[r_m],
1778 				    OPLEN);
1779 				if (r_m == 5) {
1780 					x->d86_opnd[opindex].d86_mode =
1781 					    MODE_RIPREL;
1782 				}
1783 			} else {
1784 				(void) strlcat(opnd, dis_addr64_mode12[r_m],
1785 				    OPLEN);
1786 			}
1787 		}
1788 	} else {
1789 		uint_t need_paren = 0;
1790 		char **regs;
1791 		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
1792 			regs = (char **)dis_REG32;
1793 		else
1794 			regs = (char **)dis_REG64;
1795 
1796 		/*
1797 		 * print the base (if any)
1798 		 */
1799 		if (base == EBP_REGNO && mode == 0) {
1800 			if (index != ESP_REGNO) {
1801 				(void) strlcat(opnd, "(", OPLEN);
1802 				need_paren = 1;
1803 			}
1804 		} else {
1805 			(void) strlcat(opnd, "(", OPLEN);
1806 			(void) strlcat(opnd, regs[base], OPLEN);
1807 			need_paren = 1;
1808 		}
1809 
1810 		/*
1811 		 * print the index (if any)
1812 		 */
1813 		if (index != ESP_REGNO) {
1814 			(void) strlcat(opnd, ",", OPLEN);
1815 			(void) strlcat(opnd, regs[index], OPLEN);
1816 			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
1817 		} else
1818 			if (need_paren)
1819 				(void) strlcat(opnd, ")", OPLEN);
1820 	}
1821 #endif
1822 }
1823 
1824 /*
1825  * Operand sequence for standard instruction involving one register
1826  * and one register/memory operand.
1827  * wbit indicates a byte(0) or opnd_size(1) operation
1828  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
1829  */
1830 #define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
1831 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
1832 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
1833 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
1834 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
1835 }
1836 
1837 /*
1838  * Similar to above, but allows for the two operands to be of different
1839  * classes (ie. wbit).
1840  *	wbit is for the r_m operand
1841  *	w2 is for the reg operand
1842  */
1843 #define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
1844 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
1845 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
1846 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
1847 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
1848 }
1849 
1850 /*
1851  * Similar, but for 2 operands plus an immediate.
1852  * vbit indicates direction
1853  * 	0 for "opcode imm, r, r_m" or
1854  *	1 for "opcode imm, r_m, r"
1855  */
1856 #define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
1857 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
1858 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
1859 		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
1860 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
1861 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
1862 }
1863 
1864 /*
1865  * Similar, but for 2 operands plus two immediates.
1866  */
1867 #define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
1868 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
1869 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
1870 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
1871 		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
1872 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
1873 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
1874 }
1875 
1876 /*
1877  * 1 operands plus two immediates.
1878  */
1879 #define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
1880 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
1881 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
1882 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
1883 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
1884 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
1885 }
1886 
1887 /*
1888  * Dissassemble a single x86 or amd64 instruction.
1889  *
1890  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
1891  * for interpreting instructions.
1892  *
1893  * returns non-zero for bad opcode
1894  */
1895 int
1896 dtrace_disx86(dis86_t *x, uint_t cpu_mode)
1897 {
1898 	instable_t *dp;		/* decode table being used */
1899 #ifdef DIS_TEXT
1900 	uint_t i;
1901 #endif
1902 #ifdef DIS_MEM
1903 	uint_t nomem = 0;
1904 #define	NOMEM	(nomem = 1)
1905 #else
1906 #define	NOMEM	/* nothing */
1907 #endif
1908 	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
1909 	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
1910 	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
1911 	uint_t w2;		/* wbit value for second operand */
1912 	uint_t vbit;
1913 	uint_t mode = 0;	/* mode value from ModRM byte */
1914 	uint_t reg;		/* reg value from ModRM byte */
1915 	uint_t r_m;		/* r_m value from ModRM byte */
1916 
1917 	uint_t opcode1;		/* high nibble of 1st byte */
1918 	uint_t opcode2;		/* low nibble of 1st byte */
1919 	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
1920 	uint_t opcode4;		/* high nibble of 2nd byte */
1921 	uint_t opcode5;		/* low nibble of 2nd byte */
1922 	uint_t opcode6;		/* high nibble of 3rd byte */
1923 	uint_t opcode7;		/* low nibble of 3rd byte */
1924 	uint_t opcode_bytes = 1;
1925 
1926 	/*
1927 	 * legacy prefixes come in 5 flavors, you should have only one of each
1928 	 */
1929 	uint_t	opnd_size_prefix = 0;
1930 	uint_t	addr_size_prefix = 0;
1931 	uint_t	segment_prefix = 0;
1932 	uint_t	lock_prefix = 0;
1933 	uint_t	rep_prefix = 0;
1934 	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
1935 	size_t	off;
1936 
1937 	instable_t dp_mmx;
1938 
1939 	x->d86_len = 0;
1940 	x->d86_rmindex = -1;
1941 	x->d86_error = 0;
1942 #ifdef DIS_TEXT
1943 	x->d86_numopnds = 0;
1944 	x->d86_seg_prefix = NULL;
1945 	x->d86_mnem[0] = 0;
1946 	for (i = 0; i < 4; ++i) {
1947 		x->d86_opnd[i].d86_opnd[0] = 0;
1948 		x->d86_opnd[i].d86_prefix[0] = 0;
1949 		x->d86_opnd[i].d86_value_size = 0;
1950 		x->d86_opnd[i].d86_value = 0;
1951 		x->d86_opnd[i].d86_mode = MODE_NONE;
1952 	}
1953 #endif
1954 	x->d86_error = 0;
1955 	x->d86_memsize = 0;
1956 
1957 	if (cpu_mode == SIZE16) {
1958 		opnd_size = SIZE16;
1959 		addr_size = SIZE16;
1960 	} else if (cpu_mode == SIZE32) {
1961 		opnd_size = SIZE32;
1962 		addr_size = SIZE32;
1963 	} else {
1964 		opnd_size = SIZE32;
1965 		addr_size = SIZE64;
1966 	}
1967 
1968 	/*
1969 	 * Get one opcode byte and check for zero padding that follows
1970 	 * jump tables.
1971 	 */
1972 	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
1973 		goto error;
1974 
1975 	if (opcode1 == 0 && opcode2 == 0 &&
1976 	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
1977 #ifdef DIS_TEXT
1978 		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
1979 #endif
1980 		goto done;
1981 	}
1982 
1983 	/*
1984 	 * Gather up legacy x86 prefix bytes.
1985 	 */
1986 	for (;;) {
1987 		uint_t *which_prefix = NULL;
1988 
1989 		dp = (instable_t *)&dis_distable[opcode1][opcode2];
1990 
1991 		switch (dp->it_adrmode) {
1992 		case PREFIX:
1993 			which_prefix = &rep_prefix;
1994 			break;
1995 		case LOCK:
1996 			which_prefix = &lock_prefix;
1997 			break;
1998 		case OVERRIDE:
1999 			which_prefix = &segment_prefix;
2000 #ifdef DIS_TEXT
2001 			x->d86_seg_prefix = (char *)dp->it_name;
2002 #endif
2003 			if (dp->it_invalid64 && cpu_mode == SIZE64)
2004 				goto error;
2005 			break;
2006 		case AM:
2007 			which_prefix = &addr_size_prefix;
2008 			break;
2009 		case DM:
2010 			which_prefix = &opnd_size_prefix;
2011 			break;
2012 		}
2013 		if (which_prefix == NULL)
2014 			break;
2015 		*which_prefix = (opcode1 << 4) | opcode2;
2016 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2017 			goto error;
2018 	}
2019 
2020 	/*
2021 	 * Handle amd64 mode PREFIX values.
2022 	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
2023 	 * We might have a REX prefix (opcodes 0x40-0x4f)
2024 	 */
2025 	if (cpu_mode == SIZE64) {
2026 		if (segment_prefix != 0x64 && segment_prefix != 0x65)
2027 			segment_prefix = 0;
2028 
2029 		if (opcode1 == 0x4) {
2030 			rex_prefix = (opcode1 << 4) | opcode2;
2031 			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2032 				goto error;
2033 			dp = (instable_t *)&dis_distable[opcode1][opcode2];
2034 		}
2035 	}
2036 
2037 	/*
2038 	 * Deal with selection of operand and address size now.
2039 	 * Note that the REX.W bit being set causes opnd_size_prefix to be
2040 	 * ignored.
2041 	 */
2042 	if (cpu_mode == SIZE64) {
2043 		if (rex_prefix & REX_W)
2044 			opnd_size = SIZE64;
2045 		else if (opnd_size_prefix)
2046 			opnd_size = SIZE16;
2047 
2048 		if (addr_size_prefix)
2049 			addr_size = SIZE32;
2050 	} else if (cpu_mode == SIZE32) {
2051 		if (opnd_size_prefix)
2052 			opnd_size = SIZE16;
2053 		if (addr_size_prefix)
2054 			addr_size = SIZE16;
2055 	} else {
2056 		if (opnd_size_prefix)
2057 			opnd_size = SIZE32;
2058 		if (addr_size_prefix)
2059 			addr_size = SIZE32;
2060 	}
2061 
2062 	/*
2063 	 * The pause instruction - a repz'd nop.  This doesn't fit
2064 	 * with any of the other prefix goop added for SSE, so we'll
2065 	 * special-case it here.
2066 	 */
2067 	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
2068 		rep_prefix = 0;
2069 		dp = (instable_t *)&dis_opPause;
2070 	}
2071 
2072 	/*
2073 	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
2074 	 * byte so we may need to perform a table indirection.
2075 	 */
2076 	if (dp->it_indirect == (instable_t *)dis_op0F) {
2077 		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
2078 			goto error;
2079 		opcode_bytes = 2;
2080 		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
2081 			uint_t	subcode;
2082 
2083 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2084 				goto error;
2085 			opcode_bytes = 3;
2086 			subcode = ((opcode6 & 0x3) << 1) |
2087 			    ((opcode7 & 0x8) >> 3);
2088 			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
2089 		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
2090 			dp = (instable_t *)&dis_op0FC8[0];
2091 		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
2092 			opcode_bytes = 3;
2093 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2094 				goto error;
2095 			if (opnd_size == SIZE16)
2096 				opnd_size = SIZE32;
2097 
2098 			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
2099 #ifdef DIS_TEXT
2100 			if (strcmp(dp->it_name, "INVALID") == 0)
2101 				goto error;
2102 #endif
2103 			switch (dp->it_adrmode) {
2104 				case XMMP_66r:
2105 				case XMMPRM_66r:
2106 				case XMM3PM_66r:
2107 					if (opnd_size_prefix == 0) {
2108 						goto error;
2109 					}
2110 					break;
2111 				case XMMP_66o:
2112 					if (opnd_size_prefix == 0) {
2113 						/* SSSE3 MMX instructions */
2114 						dp_mmx = *dp;
2115 						dp = &dp_mmx;
2116 						dp->it_adrmode = MMOPM_66o;
2117 #ifdef	DIS_MEM
2118 						dp->it_size = 8;
2119 #endif
2120 					}
2121 					break;
2122 				default:
2123 					goto error;
2124 			}
2125 		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
2126 			opcode_bytes = 3;
2127 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2128 				goto error;
2129 			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
2130 #ifdef DIS_TEXT
2131 			if (strcmp(dp->it_name, "INVALID") == 0)
2132 				goto error;
2133 #endif
2134 			switch (dp->it_adrmode) {
2135 				case XMM_66r:
2136 				case XMMM_66r:
2137 					if (opnd_size_prefix == 0) {
2138 						goto error;
2139 					}
2140 					break;
2141 				case XMM_66o:
2142 					if (opnd_size_prefix == 0) {
2143 						/* SSSE3 MMX instructions */
2144 						dp_mmx = *dp;
2145 						dp = &dp_mmx;
2146 						dp->it_adrmode = MM;
2147 #ifdef	DIS_MEM
2148 						dp->it_size = 8;
2149 #endif
2150 					}
2151 					break;
2152 				case CRC32:
2153 					if (rep_prefix != 0xF2) {
2154 						goto error;
2155 					}
2156 					rep_prefix = 0;
2157 					break;
2158 				default:
2159 					goto error;
2160 			}
2161 		} else {
2162 			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
2163 		}
2164 	}
2165 
2166 	/*
2167 	 * If still not at a TERM decode entry, then a ModRM byte
2168 	 * exists and its fields further decode the instruction.
2169 	 */
2170 	x->d86_got_modrm = 0;
2171 	if (dp->it_indirect != TERM) {
2172 		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
2173 		if (x->d86_error)
2174 			goto error;
2175 		reg = opcode3;
2176 
2177 		/*
2178 		 * decode 287 instructions (D8-DF) from opcodeN
2179 		 */
2180 		if (opcode1 == 0xD && opcode2 >= 0x8) {
2181 			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
2182 				dp = (instable_t *)&dis_opFP5[r_m];
2183 			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
2184 				dp = (instable_t *)&dis_opFP7[opcode3];
2185 			else if (opcode2 == 0xB && mode == 0x3)
2186 				dp = (instable_t *)&dis_opFP6[opcode3];
2187 			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
2188 				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
2189 			else if (mode == 0x3)
2190 				dp = (instable_t *)
2191 				    &dis_opFP3[opcode2 - 8][opcode3];
2192 			else
2193 				dp = (instable_t *)
2194 				    &dis_opFP1n2[opcode2 - 8][opcode3];
2195 		} else {
2196 			dp = (instable_t *)dp->it_indirect + opcode3;
2197 		}
2198 	}
2199 
2200 	/*
2201 	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
2202 	 * (sign extend 32bit to 64 bit)
2203 	 */
2204 	if (cpu_mode == SIZE64 && opcode1 == 0x6 && opcode2 == 0x3)
2205 		dp = (instable_t *)&dis_opMOVSLD;
2206 
2207 	/*
2208 	 * at this point we should have a correct (or invalid) opcode
2209 	 */
2210 	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
2211 	    cpu_mode != SIZE64 && dp->it_invalid32)
2212 		goto error;
2213 	if (dp->it_indirect != TERM)
2214 		goto error;
2215 
2216 	/*
2217 	 * deal with MMX/SSE opcodes which are changed by prefixes
2218 	 */
2219 	switch (dp->it_adrmode) {
2220 	case MMO:
2221 	case MMOIMPL:
2222 	case MMO3P:
2223 	case MMOM3:
2224 	case MMOMS:
2225 	case MMOPM:
2226 	case MMOPRM:
2227 	case MMOS:
2228 	case XMMO:
2229 	case XMMOM:
2230 	case XMMOMS:
2231 	case XMMOPM:
2232 	case XMMOS:
2233 	case XMMOMX:
2234 	case XMMOX3:
2235 	case XMMOXMM:
2236 		/*
2237 		 * This is horrible.  Some SIMD instructions take the
2238 		 * form 0x0F 0x?? ..., which is easily decoded using the
2239 		 * existing tables.  Other SIMD instructions use various
2240 		 * prefix bytes to overload existing instructions.  For
2241 		 * Example, addps is F0, 58, whereas addss is F3 (repz),
2242 		 * F0, 58.  Presumably someone got a raise for this.
2243 		 *
2244 		 * If we see one of the instructions which can be
2245 		 * modified in this way (if we've got one of the SIMDO*
2246 		 * address modes), we'll check to see if the last prefix
2247 		 * was a repz.  If it was, we strip the prefix from the
2248 		 * mnemonic, and we indirect using the dis_opSIMDrepz
2249 		 * table.
2250 		 */
2251 
2252 		/*
2253 		 * Calculate our offset in dis_op0F
2254 		 */
2255 		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
2256 			goto error;
2257 
2258 		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
2259 		    sizeof (instable_t);
2260 
2261 		/*
2262 		 * Rewrite if this instruction used one of the magic prefixes.
2263 		 */
2264 		if (rep_prefix) {
2265 			if (rep_prefix == 0xf2)
2266 				dp = (instable_t *)&dis_opSIMDrepnz[off];
2267 			else
2268 				dp = (instable_t *)&dis_opSIMDrepz[off];
2269 			rep_prefix = 0;
2270 		} else if (opnd_size_prefix) {
2271 			dp = (instable_t *)&dis_opSIMDdata16[off];
2272 			opnd_size_prefix = 0;
2273 			if (opnd_size == SIZE16)
2274 				opnd_size = SIZE32;
2275 		}
2276 		break;
2277 
2278 	case MMOSH:
2279 		/*
2280 		 * As with the "normal" SIMD instructions, the MMX
2281 		 * shuffle instructions are overloaded.  These
2282 		 * instructions, however, are special in that they use
2283 		 * an extra byte, and thus an extra table.  As of this
2284 		 * writing, they only use the opnd_size prefix.
2285 		 */
2286 
2287 		/*
2288 		 * Calculate our offset in dis_op0F7123
2289 		 */
2290 		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
2291 		    sizeof (dis_op0F7123))
2292 			goto error;
2293 
2294 		if (opnd_size_prefix) {
2295 			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
2296 			    sizeof (instable_t);
2297 			dp = (instable_t *)&dis_opSIMD7123[off];
2298 			opnd_size_prefix = 0;
2299 			if (opnd_size == SIZE16)
2300 				opnd_size = SIZE32;
2301 		}
2302 		break;
2303 	case MRw:
2304 		if (rep_prefix) {
2305 			if (rep_prefix == 0xf3) {
2306 
2307 				/*
2308 				 * Calculate our offset in dis_op0F
2309 				 */
2310 				if ((uintptr_t)dp - (uintptr_t)dis_op0F
2311 				    > sizeof (dis_op0F))
2312 					goto error;
2313 
2314 				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
2315 				    sizeof (instable_t);
2316 
2317 				dp = (instable_t *)&dis_opSIMDrepz[off];
2318 				rep_prefix = 0;
2319 			} else {
2320 				goto error;
2321 			}
2322 		}
2323 		break;
2324 	}
2325 
2326 	/*
2327 	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
2328 	 */
2329 	if (cpu_mode == SIZE64)
2330 		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
2331 			opnd_size = SIZE64;
2332 
2333 #ifdef DIS_TEXT
2334 	/*
2335 	 * At this point most instructions can format the opcode mnemonic
2336 	 * including the prefixes.
2337 	 */
2338 	if (lock_prefix)
2339 		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
2340 
2341 	if (rep_prefix == 0xf2)
2342 		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
2343 	else if (rep_prefix == 0xf3)
2344 		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
2345 
2346 	if (cpu_mode == SIZE64 && addr_size_prefix)
2347 		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
2348 
2349 	if (dp->it_adrmode != CBW &&
2350 	    dp->it_adrmode != CWD &&
2351 	    dp->it_adrmode != XMMSFNC) {
2352 		if (strcmp(dp->it_name, "INVALID") == 0)
2353 			goto error;
2354 		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
2355 		if (dp->it_suffix) {
2356 			char *types[] = {"", "w", "l", "q"};
2357 			if (opcode_bytes == 2 && opcode4 == 4) {
2358 				/* It's a cmovx.yy. Replace the suffix x */
2359 				for (i = 5; i < OPLEN; i++) {
2360 					if (x->d86_mnem[i] == '.')
2361 						break;
2362 				}
2363 				x->d86_mnem[i - 1] = *types[opnd_size];
2364 			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
2365 			    ((opcode6 == 1 && opcode7 == 6) ||
2366 			    (opcode6 == 2 && opcode7 == 2))) {
2367 				/*
2368 				 * To handle PINSRD and PEXTRD
2369 				 */
2370 				(void) strlcat(x->d86_mnem, "d", OPLEN);
2371 			} else {
2372 				(void) strlcat(x->d86_mnem, types[opnd_size],
2373 				    OPLEN);
2374 			}
2375 		}
2376 	}
2377 #endif
2378 
2379 	/*
2380 	 * Process operands based on the addressing modes.
2381 	 */
2382 	x->d86_mode = cpu_mode;
2383 	x->d86_rex_prefix = rex_prefix;
2384 	x->d86_opnd_size = opnd_size;
2385 	x->d86_addr_size = addr_size;
2386 	vbit = 0;		/* initialize for mem/reg -> reg */
2387 	switch (dp->it_adrmode) {
2388 		/*
2389 		 * amd64 instruction to sign extend 32 bit reg/mem operands
2390 		 * into 64 bit register values
2391 		 */
2392 	case MOVSXZ:
2393 #ifdef DIS_TEXT
2394 		if (rex_prefix == 0)
2395 			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
2396 #endif
2397 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2398 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2399 		x->d86_opnd_size = SIZE64;
2400 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2401 		x->d86_opnd_size = opnd_size = SIZE32;
2402 		wbit = LONG_OPND;
2403 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2404 		break;
2405 
2406 		/*
2407 		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
2408 		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
2409 		 * wbit lives in 2nd byte, note that operands
2410 		 * are different sized
2411 		 */
2412 	case MOVZ:
2413 		if (rex_prefix & REX_W) {
2414 			/* target register size = 64 bit */
2415 			x->d86_mnem[5] = 'q';
2416 		}
2417 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2418 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2419 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2420 		x->d86_opnd_size = opnd_size = SIZE16;
2421 		wbit = WBIT(opcode5);
2422 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2423 		break;
2424 	case CRC32:
2425 		opnd_size = SIZE32;
2426 		if (rex_prefix & REX_W)
2427 			opnd_size = SIZE64;
2428 		x->d86_opnd_size = opnd_size;
2429 
2430 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2431 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2432 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2433 		wbit = WBIT(opcode7);
2434 		if (opnd_size_prefix)
2435 			x->d86_opnd_size = opnd_size = SIZE16;
2436 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2437 		break;
2438 
2439 	/*
2440 	 * imul instruction, with either 8-bit or longer immediate
2441 	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
2442 	 */
2443 	case IMUL:
2444 		wbit = LONG_OPND;
2445 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
2446 		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
2447 		break;
2448 
2449 	/* memory or register operand to register, with 'w' bit	*/
2450 	case MRw:
2451 		wbit = WBIT(opcode2);
2452 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2453 		break;
2454 
2455 	/* register to memory or register operand, with 'w' bit	*/
2456 	/* arpl happens to fit here also because it is odd */
2457 	case RMw:
2458 		if (opcode_bytes == 2)
2459 			wbit = WBIT(opcode5);
2460 		else
2461 			wbit = WBIT(opcode2);
2462 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2463 		break;
2464 
2465 	/* xaddb instruction */
2466 	case XADDB:
2467 		wbit = 0;
2468 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2469 		break;
2470 
2471 	/* MMX register to memory or register operand		*/
2472 	case MMS:
2473 	case MMOS:
2474 #ifdef DIS_TEXT
2475 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2476 #else
2477 		wbit = LONG_OPND;
2478 #endif
2479 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
2480 		break;
2481 
2482 	/* MMX register to memory */
2483 	case MMOMS:
2484 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2485 		if (mode == REG_ONLY)
2486 			goto error;
2487 		wbit = MM_OPND;
2488 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
2489 		break;
2490 
2491 	/* Double shift. Has immediate operand specifying the shift. */
2492 	case DSHIFT:
2493 		wbit = LONG_OPND;
2494 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2495 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2496 		dtrace_get_operand(x, mode, r_m, wbit, 2);
2497 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2498 		dtrace_imm_opnd(x, wbit, 1, 0);
2499 		break;
2500 
2501 	/*
2502 	 * Double shift. With no immediate operand, specifies using %cl.
2503 	 */
2504 	case DSHIFTcl:
2505 		wbit = LONG_OPND;
2506 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2507 		break;
2508 
2509 	/* immediate to memory or register operand */
2510 	case IMlw:
2511 		wbit = WBIT(opcode2);
2512 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2513 		dtrace_get_operand(x, mode, r_m, wbit, 1);
2514 		/*
2515 		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
2516 		 */
2517 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
2518 		break;
2519 
2520 	/* immediate to memory or register operand with the	*/
2521 	/* 'w' bit present					*/
2522 	case IMw:
2523 		wbit = WBIT(opcode2);
2524 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2525 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2526 		dtrace_get_operand(x, mode, r_m, wbit, 1);
2527 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
2528 		break;
2529 
2530 	/* immediate to register with register in low 3 bits	*/
2531 	/* of op code						*/
2532 	case IR:
2533 		/* w-bit here (with regs) is bit 3 */
2534 		wbit = opcode2 >>3 & 0x1;
2535 		reg = REGNO(opcode2);
2536 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2537 		mode = REG_ONLY;
2538 		r_m = reg;
2539 		dtrace_get_operand(x, mode, r_m, wbit, 1);
2540 		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
2541 		break;
2542 
2543 	/* MMX immediate shift of register */
2544 	case MMSH:
2545 	case MMOSH:
2546 		wbit = MM_OPND;
2547 		goto mm_shift;	/* in next case */
2548 
2549 	/* SIMD immediate shift of register */
2550 	case XMMSH:
2551 		wbit = XMM_OPND;
2552 mm_shift:
2553 		reg = REGNO(opcode7);
2554 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2555 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
2556 		dtrace_imm_opnd(x, wbit, 1, 0);
2557 		NOMEM;
2558 		break;
2559 
2560 	/* accumulator to memory operand */
2561 	case AO:
2562 		vbit = 1;
2563 		/*FALLTHROUGH*/
2564 
2565 	/* memory operand to accumulator */
2566 	case OA:
2567 		wbit = WBIT(opcode2);
2568 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
2569 		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
2570 #ifdef DIS_TEXT
2571 		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
2572 #endif
2573 		break;
2574 
2575 
2576 	/* segment register to memory or register operand */
2577 	case SM:
2578 		vbit = 1;
2579 		/*FALLTHROUGH*/
2580 
2581 	/* memory or register operand to segment register */
2582 	case MS:
2583 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2584 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2585 		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
2586 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
2587 		break;
2588 
2589 	/*
2590 	 * rotate or shift instructions, which may shift by 1 or
2591 	 * consult the cl register, depending on the 'v' bit
2592 	 */
2593 	case Mv:
2594 		vbit = VBIT(opcode2);
2595 		wbit = WBIT(opcode2);
2596 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2597 		dtrace_get_operand(x, mode, r_m, wbit, 1);
2598 #ifdef DIS_TEXT
2599 		if (vbit) {
2600 			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
2601 		} else {
2602 			x->d86_opnd[0].d86_mode = MODE_SIGNED;
2603 			x->d86_opnd[0].d86_value_size = 1;
2604 			x->d86_opnd[0].d86_value = 1;
2605 		}
2606 #endif
2607 		break;
2608 	/*
2609 	 * immediate rotate or shift instructions
2610 	 */
2611 	case MvI:
2612 		wbit = WBIT(opcode2);
2613 normal_imm_mem:
2614 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2615 		dtrace_get_operand(x, mode, r_m, wbit, 1);
2616 		dtrace_imm_opnd(x, wbit, 1, 0);
2617 		break;
2618 
2619 	/* bit test instructions */
2620 	case MIb:
2621 		wbit = LONG_OPND;
2622 		goto normal_imm_mem;
2623 
2624 	/* single memory or register operand with 'w' bit present */
2625 	case Mw:
2626 		wbit = WBIT(opcode2);
2627 just_mem:
2628 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2629 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2630 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2631 		break;
2632 
2633 	case SWAPGS:
2634 		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
2635 #ifdef DIS_TEXT
2636 			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
2637 #endif
2638 			NOMEM;
2639 			break;
2640 		}
2641 		/*FALLTHROUGH*/
2642 
2643 	/* prefetch instruction - memory operand, but no memory acess */
2644 	case PREF:
2645 		NOMEM;
2646 		/*FALLTHROUGH*/
2647 
2648 	/* single memory or register operand */
2649 	case M:
2650 		wbit = LONG_OPND;
2651 		goto just_mem;
2652 
2653 	/* single memory or register byte operand */
2654 	case Mb:
2655 		wbit = BYTE_OPND;
2656 		goto just_mem;
2657 
2658 	case MONITOR_MWAIT:
2659 		if (mode == 3) {
2660 			if (r_m == 0) {
2661 #ifdef DIS_TEXT
2662 				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
2663 #endif
2664 				NOMEM;
2665 				break;
2666 			} else if (r_m == 1) {
2667 #ifdef DIS_TEXT
2668 				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
2669 #endif
2670 				NOMEM;
2671 				break;
2672 			} else {
2673 				goto error;
2674 			}
2675 		}
2676 		/*FALLTHROUGH*/
2677 
2678 	case MO:
2679 		/* Similar to M, but only memory (no direct registers) */
2680 		wbit = LONG_OPND;
2681 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2682 		if (mode == 3)
2683 			goto error;
2684 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
2685 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2686 		break;
2687 
2688 	/* move special register to register or reverse if vbit */
2689 	case SREG:
2690 		switch (opcode5) {
2691 
2692 		case 2:
2693 			vbit = 1;
2694 			/*FALLTHROUGH*/
2695 		case 0:
2696 			wbit = CONTROL_OPND;
2697 			break;
2698 
2699 		case 3:
2700 			vbit = 1;
2701 			/*FALLTHROUGH*/
2702 		case 1:
2703 			wbit = DEBUG_OPND;
2704 			break;
2705 
2706 		case 6:
2707 			vbit = 1;
2708 			/*FALLTHROUGH*/
2709 		case 4:
2710 			wbit = TEST_OPND;
2711 			break;
2712 
2713 		}
2714 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2715 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2716 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
2717 		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
2718 		NOMEM;
2719 		break;
2720 
2721 	/*
2722 	 * single register operand with register in the low 3
2723 	 * bits of op code
2724 	 */
2725 	case R:
2726 		if (opcode_bytes == 2)
2727 			reg = REGNO(opcode5);
2728 		else
2729 			reg = REGNO(opcode2);
2730 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2731 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
2732 		NOMEM;
2733 		break;
2734 
2735 	/*
2736 	 * register to accumulator with register in the low 3
2737 	 * bits of op code, xchg instructions
2738 	 */
2739 	case RA:
2740 		NOMEM;
2741 		reg = REGNO(opcode2);
2742 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
2743 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
2744 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
2745 		break;
2746 
2747 	/*
2748 	 * single segment register operand, with register in
2749 	 * bits 3-4 of op code byte
2750 	 */
2751 	case SEG:
2752 		NOMEM;
2753 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
2754 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
2755 		break;
2756 
2757 	/*
2758 	 * single segment register operand, with register in
2759 	 * bits 3-5 of op code
2760 	 */
2761 	case LSEG:
2762 		NOMEM;
2763 		/* long seg reg from opcode */
2764 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
2765 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
2766 		break;
2767 
2768 	/* memory or register operand to register */
2769 	case MR:
2770 		wbit = LONG_OPND;
2771 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2772 		break;
2773 
2774 	case RM:
2775 		wbit = LONG_OPND;
2776 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
2777 		break;
2778 
2779 	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
2780 	case MM:
2781 	case MMO:
2782 #ifdef DIS_TEXT
2783 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2784 #else
2785 		wbit = LONG_OPND;
2786 #endif
2787 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
2788 		break;
2789 
2790 	case MMOIMPL:
2791 #ifdef DIS_TEXT
2792 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
2793 #else
2794 		wbit = LONG_OPND;
2795 #endif
2796 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2797 		if (mode != REG_ONLY)
2798 			goto error;
2799 
2800 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2801 		dtrace_get_operand(x, mode, r_m, wbit, 0);
2802 		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
2803 		mode = 0;	/* change for memory access size... */
2804 		break;
2805 
2806 	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
2807 	case MMO3P:
2808 		wbit = MM_OPND;
2809 		goto xmm3p;
2810 	case XMM3P:
2811 		wbit = XMM_OPND;
2812 xmm3p:
2813 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2814 		if (mode != REG_ONLY)
2815 			goto error;
2816 
2817 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
2818 		    1);
2819 		NOMEM;
2820 		break;
2821 
2822 	case XMM3PM_66r:
2823 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
2824 		    1, 0);
2825 		break;
2826 
2827 	/* MMX/SIMD-Int predicated r32/mem to mm reg */
2828 	case MMOPRM:
2829 		wbit = LONG_OPND;
2830 		w2 = MM_OPND;
2831 		goto xmmprm;
2832 	case XMMPRM:
2833 	case XMMPRM_66r:
2834 		wbit = LONG_OPND;
2835 		w2 = XMM_OPND;
2836 xmmprm:
2837 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
2838 		break;
2839 
2840 	/* MMX/SIMD-Int predicated mm/mem to mm reg */
2841 	case MMOPM:
2842 	case MMOPM_66o:
2843 		wbit = w2 = MM_OPND;
2844 		goto xmmprm;
2845 
2846 	/* MMX/SIMD-Int mm reg to r32 */
2847 	case MMOM3:
2848 		NOMEM;
2849 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2850 		if (mode != REG_ONLY)
2851 			goto error;
2852 		wbit = MM_OPND;
2853 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
2854 		break;
2855 
2856 	/* SIMD memory or xmm reg operand to xmm reg		*/
2857 	case XMM:
2858 	case XMM_66o:
2859 	case XMM_66r:
2860 	case XMMO:
2861 	case XMMXIMPL:
2862 		wbit = XMM_OPND;
2863 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
2864 
2865 		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
2866 			goto error;
2867 
2868 #ifdef DIS_TEXT
2869 		/*
2870 		 * movlps and movhlps share opcodes.  They differ in the
2871 		 * addressing modes allowed for their operands.
2872 		 * movhps and movlhps behave similarly.
2873 		 */
2874 		if (mode == REG_ONLY) {
2875 			if (strcmp(dp->it_name, "movlps") == 0)
2876 				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
2877 			else if (strcmp(dp->it_name, "movhps") == 0)
2878 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
2879 		}
2880 #endif
2881 		if (dp->it_adrmode == XMMXIMPL)
2882 			mode = 0;	/* change for memory access size... */
2883 		break;
2884 
2885 	/* SIMD xmm reg to memory or xmm reg */
2886 	case XMMS:
2887 	case XMMOS:
2888 	case XMMMS:
2889 	case XMMOMS:
2890 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2891 #ifdef DIS_TEXT
2892 		if ((strcmp(dp->it_name, "movlps") == 0 ||
2893 		    strcmp(dp->it_name, "movhps") == 0 ||
2894 		    strcmp(dp->it_name, "movntps") == 0) &&
2895 		    mode == REG_ONLY)
2896 			goto error;
2897 #endif
2898 		wbit = XMM_OPND;
2899 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
2900 		break;
2901 
2902 	/* SIMD memory to xmm reg */
2903 	case XMMM:
2904 	case XMMM_66r:
2905 	case XMMOM:
2906 		wbit = XMM_OPND;
2907 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2908 #ifdef DIS_TEXT
2909 		if (mode == REG_ONLY) {
2910 			if (strcmp(dp->it_name, "movhps") == 0)
2911 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
2912 			else
2913 				goto error;
2914 		}
2915 #endif
2916 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2917 		break;
2918 
2919 	/* SIMD memory or r32 to xmm reg			*/
2920 	case XMM3MX:
2921 		wbit = LONG_OPND;
2922 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2923 		break;
2924 
2925 	case XMM3MXS:
2926 		wbit = LONG_OPND;
2927 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
2928 		break;
2929 
2930 	/* SIMD memory or mm reg to xmm reg			*/
2931 	case XMMOMX:
2932 	/* SIMD mm to xmm */
2933 	case XMMMX:
2934 		wbit = MM_OPND;
2935 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
2936 		break;
2937 
2938 	/* SIMD memory or xmm reg to mm reg			*/
2939 	case XMMXMM:
2940 	case XMMOXMM:
2941 	case XMMXM:
2942 		wbit = XMM_OPND;
2943 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
2944 		break;
2945 
2946 
2947 	/* SIMD memory or xmm reg to r32			*/
2948 	case XMMXM3:
2949 		wbit = XMM_OPND;
2950 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
2951 		break;
2952 
2953 	/* SIMD xmm to r32					*/
2954 	case XMMX3:
2955 	case XMMOX3:
2956 		dtrace_get_modrm(x, &mode, &reg, &r_m);
2957 		if (mode != REG_ONLY)
2958 			goto error;
2959 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
2960 		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
2961 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
2962 		NOMEM;
2963 		break;
2964 
2965 	/* SIMD predicated memory or xmm reg with/to xmm reg */
2966 	case XMMP:
2967 	case XMMP_66r:
2968 	case XMMP_66o:
2969 	case XMMOPM:
2970 		wbit = XMM_OPND;
2971 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
2972 		    1);
2973 
2974 #ifdef DIS_TEXT
2975 		/*
2976 		 * cmpps and cmpss vary their instruction name based
2977 		 * on the value of imm8.  Other XMMP instructions,
2978 		 * such as shufps, require explicit specification of
2979 		 * the predicate.
2980 		 */
2981 		if (dp->it_name[0] == 'c' &&
2982 		    dp->it_name[1] == 'm' &&
2983 		    dp->it_name[2] == 'p' &&
2984 		    strlen(dp->it_name) == 5) {
2985 			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
2986 
2987 			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
2988 				goto error;
2989 
2990 			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
2991 			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
2992 			    OPLEN);
2993 			(void) strlcat(x->d86_mnem,
2994 			    dp->it_name + strlen(dp->it_name) - 2,
2995 			    OPLEN);
2996 			x->d86_opnd[0] = x->d86_opnd[1];
2997 			x->d86_opnd[1] = x->d86_opnd[2];
2998 			x->d86_numopnds = 2;
2999 		}
3000 #endif
3001 		break;
3002 
3003 	case XMMX2I:
3004 		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
3005 		    1);
3006 		NOMEM;
3007 		break;
3008 
3009 	case XMM2I:
3010 		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
3011 		NOMEM;
3012 		break;
3013 
3014 	/* immediate operand to accumulator */
3015 	case IA:
3016 		wbit = WBIT(opcode2);
3017 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3018 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3019 		NOMEM;
3020 		break;
3021 
3022 	/* memory or register operand to accumulator */
3023 	case MA:
3024 		wbit = WBIT(opcode2);
3025 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3026 		dtrace_get_operand(x, mode, r_m, wbit, 0);
3027 		break;
3028 
3029 	/* si register to di register used to reference memory		*/
3030 	case SD:
3031 #ifdef DIS_TEXT
3032 		dtrace_check_override(x, 0);
3033 		x->d86_numopnds = 2;
3034 		if (addr_size == SIZE64) {
3035 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3036 			    OPLEN);
3037 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3038 			    OPLEN);
3039 		} else if (addr_size == SIZE32) {
3040 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3041 			    OPLEN);
3042 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3043 			    OPLEN);
3044 		} else {
3045 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3046 			    OPLEN);
3047 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3048 			    OPLEN);
3049 		}
3050 #endif
3051 		wbit = LONG_OPND;
3052 		break;
3053 
3054 	/* accumulator to di register				*/
3055 	case AD:
3056 		wbit = WBIT(opcode2);
3057 #ifdef DIS_TEXT
3058 		dtrace_check_override(x, 1);
3059 		x->d86_numopnds = 2;
3060 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
3061 		if (addr_size == SIZE64)
3062 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3063 			    OPLEN);
3064 		else if (addr_size == SIZE32)
3065 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3066 			    OPLEN);
3067 		else
3068 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3069 			    OPLEN);
3070 #endif
3071 		break;
3072 
3073 	/* si register to accumulator				*/
3074 	case SA:
3075 		wbit = WBIT(opcode2);
3076 #ifdef DIS_TEXT
3077 		dtrace_check_override(x, 0);
3078 		x->d86_numopnds = 2;
3079 		if (addr_size == SIZE64)
3080 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3081 			    OPLEN);
3082 		else if (addr_size == SIZE32)
3083 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3084 			    OPLEN);
3085 		else
3086 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3087 			    OPLEN);
3088 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3089 #endif
3090 		break;
3091 
3092 	/*
3093 	 * single operand, a 16/32 bit displacement
3094 	 */
3095 	case D:
3096 		wbit = LONG_OPND;
3097 		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3098 		NOMEM;
3099 		break;
3100 
3101 	/* jmp/call indirect to memory or register operand		*/
3102 	case INM:
3103 #ifdef DIS_TEXT
3104 		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
3105 #endif
3106 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3107 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
3108 		wbit = LONG_OPND;
3109 		break;
3110 
3111 	/*
3112 	 * for long jumps and long calls -- a new code segment
3113 	 * register and an offset in IP -- stored in object
3114 	 * code in reverse order. Note - not valid in amd64
3115 	 */
3116 	case SO:
3117 		dtrace_check_override(x, 1);
3118 		wbit = LONG_OPND;
3119 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
3120 #ifdef DIS_TEXT
3121 		x->d86_opnd[1].d86_mode = MODE_SIGNED;
3122 #endif
3123 		/* will now get segment operand */
3124 		dtrace_imm_opnd(x, wbit, 2, 0);
3125 		break;
3126 
3127 	/*
3128 	 * jmp/call. single operand, 8 bit displacement.
3129 	 * added to current EIP in 'compofff'
3130 	 */
3131 	case BD:
3132 		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
3133 		NOMEM;
3134 		break;
3135 
3136 	/* single 32/16 bit immediate operand			*/
3137 	case I:
3138 		wbit = LONG_OPND;
3139 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3140 		break;
3141 
3142 	/* single 8 bit immediate operand			*/
3143 	case Ib:
3144 		wbit = LONG_OPND;
3145 		dtrace_imm_opnd(x, wbit, 1, 0);
3146 		break;
3147 
3148 	case ENTER:
3149 		wbit = LONG_OPND;
3150 		dtrace_imm_opnd(x, wbit, 2, 0);
3151 		dtrace_imm_opnd(x, wbit, 1, 1);
3152 		switch (opnd_size) {
3153 		case SIZE64:
3154 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
3155 			break;
3156 		case SIZE32:
3157 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
3158 			break;
3159 		case SIZE16:
3160 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
3161 			break;
3162 		}
3163 
3164 		break;
3165 
3166 	/* 16-bit immediate operand */
3167 	case RET:
3168 		wbit = LONG_OPND;
3169 		dtrace_imm_opnd(x, wbit, 2, 0);
3170 		break;
3171 
3172 	/* single 8 bit port operand				*/
3173 	case P:
3174 		dtrace_check_override(x, 0);
3175 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
3176 		NOMEM;
3177 		break;
3178 
3179 	/* single operand, dx register (variable port instruction) */
3180 	case V:
3181 		x->d86_numopnds = 1;
3182 		dtrace_check_override(x, 0);
3183 #ifdef DIS_TEXT
3184 		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
3185 #endif
3186 		NOMEM;
3187 		break;
3188 
3189 	/*
3190 	 * The int instruction, which has two forms:
3191 	 * int 3 (breakpoint) or
3192 	 * int n, where n is indicated in the subsequent
3193 	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
3194 	 * where, although the 3 looks  like an operand,
3195 	 * it is implied by the opcode. It must be converted
3196 	 * to the correct base and output.
3197 	 */
3198 	case INT3:
3199 #ifdef DIS_TEXT
3200 		x->d86_numopnds = 1;
3201 		x->d86_opnd[0].d86_mode = MODE_SIGNED;
3202 		x->d86_opnd[0].d86_value_size = 1;
3203 		x->d86_opnd[0].d86_value = 3;
3204 #endif
3205 		NOMEM;
3206 		break;
3207 
3208 	/* single 8 bit immediate operand			*/
3209 	case INTx:
3210 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
3211 		NOMEM;
3212 		break;
3213 
3214 	/* an unused byte must be discarded */
3215 	case U:
3216 		if (x->d86_get_byte(x->d86_data) < 0)
3217 			goto error;
3218 		x->d86_len++;
3219 		NOMEM;
3220 		break;
3221 
3222 	case CBW:
3223 #ifdef DIS_TEXT
3224 		if (opnd_size == SIZE16)
3225 			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
3226 		else if (opnd_size == SIZE32)
3227 			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
3228 		else
3229 			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
3230 #endif
3231 		wbit = LONG_OPND;
3232 		NOMEM;
3233 		break;
3234 
3235 	case CWD:
3236 #ifdef DIS_TEXT
3237 		if (opnd_size == SIZE16)
3238 			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
3239 		else if (opnd_size == SIZE32)
3240 			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
3241 		else
3242 			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
3243 #endif
3244 		wbit = LONG_OPND;
3245 		NOMEM;
3246 		break;
3247 
3248 	case XMMSFNC:
3249 		/*
3250 		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
3251 		 * REG_ONLY, mnemonic should be 'clflush'.
3252 		 */
3253 		dtrace_get_modrm(x, &mode, &reg, &r_m);
3254 
3255 		/* sfence doesn't take operands */
3256 #ifdef DIS_TEXT
3257 		if (mode == REG_ONLY) {
3258 			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
3259 		} else {
3260 			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
3261 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3262 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
3263 			NOMEM;
3264 		}
3265 #else
3266 		if (mode != REG_ONLY) {
3267 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3268 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
3269 			NOMEM;
3270 		}
3271 #endif
3272 		break;
3273 
3274 	/*
3275 	 * no disassembly, the mnemonic was all there was so go on
3276 	 */
3277 	case NORM:
3278 		if (dp->it_invalid32 && cpu_mode != SIZE64)
3279 			goto error;
3280 		NOMEM;
3281 		/*FALLTHROUGH*/
3282 	case IMPLMEM:
3283 		break;
3284 
3285 	case XMMFENCE:
3286 		/*
3287 		 * Only the following exact byte sequences are allowed:
3288 		 *
3289 		 * 	0f ae e8	lfence
3290 		 * 	0f ae f0	mfence
3291 		 */
3292 		if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
3293 		    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
3294 			goto error;
3295 
3296 		break;
3297 
3298 
3299 	/* float reg */
3300 	case F:
3301 #ifdef DIS_TEXT
3302 		x->d86_numopnds = 1;
3303 		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
3304 		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
3305 #endif
3306 		NOMEM;
3307 		break;
3308 
3309 	/* float reg to float reg, with ret bit present */
3310 	case FF:
3311 		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
3312 		/*FALLTHROUGH*/
3313 	case FFC:				/* case for vbit always = 0 */
3314 #ifdef DIS_TEXT
3315 		x->d86_numopnds = 2;
3316 		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
3317 		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
3318 		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
3319 #endif
3320 		NOMEM;
3321 		break;
3322 
3323 	/* an invalid op code */
3324 	case AM:
3325 	case DM:
3326 	case OVERRIDE:
3327 	case PREFIX:
3328 	case UNKNOWN:
3329 		NOMEM;
3330 	default:
3331 		goto error;
3332 	} /* end switch */
3333 	if (x->d86_error)
3334 		goto error;
3335 
3336 done:
3337 #ifdef DIS_MEM
3338 	/*
3339 	 * compute the size of any memory accessed by the instruction
3340 	 */
3341 	if (x->d86_memsize != 0) {
3342 		return (0);
3343 	} else if (dp->it_stackop) {
3344 		switch (opnd_size) {
3345 		case SIZE16:
3346 			x->d86_memsize = 2;
3347 			break;
3348 		case SIZE32:
3349 			x->d86_memsize = 4;
3350 			break;
3351 		case SIZE64:
3352 			x->d86_memsize = 8;
3353 			break;
3354 		}
3355 	} else if (nomem || mode == REG_ONLY) {
3356 		x->d86_memsize = 0;
3357 
3358 	} else if (dp->it_size != 0) {
3359 		/*
3360 		 * In 64 bit mode descriptor table entries
3361 		 * go up to 10 bytes and popf/pushf are always 8 bytes
3362 		 */
3363 		if (x->d86_mode == SIZE64 && dp->it_size == 6)
3364 			x->d86_memsize = 10;
3365 		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
3366 		    (opcode2 == 0xc || opcode2 == 0xd))
3367 			x->d86_memsize = 8;
3368 		else
3369 			x->d86_memsize = dp->it_size;
3370 
3371 	} else if (wbit == 0) {
3372 		x->d86_memsize = 1;
3373 
3374 	} else if (wbit == LONG_OPND) {
3375 		if (opnd_size == SIZE64)
3376 			x->d86_memsize = 8;
3377 		else if (opnd_size == SIZE32)
3378 			x->d86_memsize = 4;
3379 		else
3380 			x->d86_memsize = 2;
3381 
3382 	} else if (wbit == SEG_OPND) {
3383 		x->d86_memsize = 4;
3384 
3385 	} else {
3386 		x->d86_memsize = 8;
3387 	}
3388 #endif
3389 	return (0);
3390 
3391 error:
3392 #ifdef DIS_TEXT
3393 	(void) strlcat(x->d86_mnem, "undef", OPLEN);
3394 #endif
3395 	return (1);
3396 }
3397 
3398 #ifdef DIS_TEXT
3399 
3400 /*
3401  * Some instructions should have immediate operands printed
3402  * as unsigned integers. We compare against this table.
3403  */
3404 static char *unsigned_ops[] = {
3405 	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
3406 	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
3407 	0
3408 };
3409 
3410 
3411 static int
3412 isunsigned_op(char *opcode)
3413 {
3414 	char *where;
3415 	int i;
3416 	int is_unsigned = 0;
3417 
3418 	/*
3419 	 * Work back to start of last mnemonic, since we may have
3420 	 * prefixes on some opcodes.
3421 	 */
3422 	where = opcode + strlen(opcode) - 1;
3423 	while (where > opcode && *where != ' ')
3424 		--where;
3425 	if (*where == ' ')
3426 		++where;
3427 
3428 	for (i = 0; unsigned_ops[i]; ++i) {
3429 		if (strncmp(where, unsigned_ops[i],
3430 		    strlen(unsigned_ops[i])))
3431 			continue;
3432 		is_unsigned = 1;
3433 		break;
3434 	}
3435 	return (is_unsigned);
3436 }
3437 
3438 /*
3439  * Print a numeric immediate into end of buf, maximum length buflen.
3440  * The immediate may be an address or a displacement.  Mask is set
3441  * for address size.  If the immediate is a "small negative", or
3442  * if it's a negative displacement of any magnitude, print as -<absval>.
3443  * Respect the "octal" flag.  "Small negative" is defined as "in the
3444  * interval [NEG_LIMIT, 0)".
3445  *
3446  * Also, "isunsigned_op()" instructions never print negatives.
3447  *
3448  * Return whether we decided to print a negative value or not.
3449  */
3450 
3451 #define	NEG_LIMIT	-255
3452 enum {IMM, DISP};
3453 enum {POS, TRY_NEG};
3454 
3455 static int
3456 print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
3457     size_t buflen, int disp, int try_neg)
3458 {
3459 	int curlen;
3460 	int64_t sv = (int64_t)usv;
3461 	int octal = dis->d86_flags & DIS_F_OCTAL;
3462 
3463 	curlen = strlen(buf);
3464 
3465 	if (try_neg == TRY_NEG && sv < 0 &&
3466 	    (disp || sv >= NEG_LIMIT) &&
3467 	    !isunsigned_op(dis->d86_mnem)) {
3468 		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
3469 		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
3470 		return (1);
3471 	} else {
3472 		if (disp == DISP)
3473 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
3474 			    octal ? "+0%llo" : "+0x%llx", usv & mask);
3475 		else
3476 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
3477 			    octal ? "0%llo" : "0x%llx", usv & mask);
3478 		return (0);
3479 
3480 	}
3481 }
3482 
3483 
3484 static int
3485 log2(int size)
3486 {
3487 	switch (size) {
3488 	case 1: return (0);
3489 	case 2: return (1);
3490 	case 4: return (2);
3491 	case 8: return (3);
3492 	}
3493 	return (0);
3494 }
3495 
3496 /* ARGSUSED */
3497 void
3498 dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
3499     size_t buflen)
3500 {
3501 	uint64_t reltgt = 0;
3502 	uint64_t tgt = 0;
3503 	int curlen;
3504 	int (*lookup)(void *, uint64_t, char *, size_t);
3505 	int i;
3506 	int64_t sv;
3507 	uint64_t usv, mask, save_mask, save_usv;
3508 	static uint64_t masks[] =
3509 	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
3510 	save_usv = 0;
3511 
3512 	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
3513 
3514 	/*
3515 	 * For PC-relative jumps, the pc is really the next pc after executing
3516 	 * this instruction, so increment it appropriately.
3517 	 */
3518 	pc += dis->d86_len;
3519 
3520 	for (i = 0; i < dis->d86_numopnds; i++) {
3521 		d86opnd_t *op = &dis->d86_opnd[i];
3522 
3523 		if (i != 0)
3524 			(void) strlcat(buf, ",", buflen);
3525 
3526 		(void) strlcat(buf, op->d86_prefix, buflen);
3527 
3528 		/*
3529 		 * sv is for the signed, possibly-truncated immediate or
3530 		 * displacement; usv retains the original size and
3531 		 * unsignedness for symbol lookup.
3532 		 */
3533 
3534 		sv = usv = op->d86_value;
3535 
3536 		/*
3537 		 * About masks: for immediates that represent
3538 		 * addresses, the appropriate display size is
3539 		 * the effective address size of the instruction.
3540 		 * This includes MODE_OFFSET, MODE_IPREL, and
3541 		 * MODE_RIPREL.  Immediates that are simply
3542 		 * immediate values should display in the operand's
3543 		 * size, however, since they don't represent addresses.
3544 		 */
3545 
3546 		/* d86_addr_size is SIZEnn, which is log2(real size) */
3547 		mask = masks[dis->d86_addr_size];
3548 
3549 		/* d86_value_size and d86_imm_bytes are in bytes */
3550 		if (op->d86_mode == MODE_SIGNED ||
3551 		    op->d86_mode == MODE_IMPLIED)
3552 			mask = masks[log2(op->d86_value_size)];
3553 
3554 		switch (op->d86_mode) {
3555 
3556 		case MODE_NONE:
3557 
3558 			(void) strlcat(buf, op->d86_opnd, buflen);
3559 			break;
3560 
3561 		case MODE_SIGNED:
3562 		case MODE_IMPLIED:
3563 		case MODE_OFFSET:
3564 
3565 			tgt = usv;
3566 
3567 			if (dis->d86_seg_prefix)
3568 				(void) strlcat(buf, dis->d86_seg_prefix,
3569 				    buflen);
3570 
3571 			if (op->d86_mode == MODE_SIGNED ||
3572 			    op->d86_mode == MODE_IMPLIED) {
3573 				(void) strlcat(buf, "$", buflen);
3574 			}
3575 
3576 			if (print_imm(dis, usv, mask, buf, buflen,
3577 			    IMM, TRY_NEG) &&
3578 			    (op->d86_mode == MODE_SIGNED ||
3579 			    op->d86_mode == MODE_IMPLIED)) {
3580 
3581 				/*
3582 				 * We printed a negative value for an
3583 				 * immediate that wasn't a
3584 				 * displacement.  Note that fact so we can
3585 				 * print the positive value as an
3586 				 * annotation.
3587 				 */
3588 
3589 				save_usv = usv;
3590 				save_mask = mask;
3591 			}
3592 			(void) strlcat(buf, op->d86_opnd, buflen);
3593 
3594 			break;
3595 
3596 		case MODE_IPREL:
3597 		case MODE_RIPREL:
3598 
3599 			reltgt = pc + sv;
3600 
3601 			switch (mode) {
3602 			case SIZE16:
3603 				reltgt = (uint16_t)reltgt;
3604 				break;
3605 			case SIZE32:
3606 				reltgt = (uint32_t)reltgt;
3607 				break;
3608 			}
3609 
3610 			(void) print_imm(dis, usv, mask, buf, buflen,
3611 			    DISP, TRY_NEG);
3612 
3613 			if (op->d86_mode == MODE_RIPREL)
3614 				(void) strlcat(buf, "(%rip)", buflen);
3615 			break;
3616 		}
3617 	}
3618 
3619 	/*
3620 	 * The symbol lookups may result in false positives,
3621 	 * particularly on object files, where small numbers may match
3622 	 * the 0-relative non-relocated addresses of symbols.
3623 	 */
3624 
3625 	lookup = dis->d86_sym_lookup;
3626 	if (tgt != 0) {
3627 		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
3628 		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
3629 			(void) strlcat(buf, "\t<", buflen);
3630 			curlen = strlen(buf);
3631 			lookup(dis->d86_data, tgt, buf + curlen,
3632 			    buflen - curlen);
3633 			(void) strlcat(buf, ">", buflen);
3634 		}
3635 
3636 		/*
3637 		 * If we printed a negative immediate above, print the
3638 		 * positive in case our heuristic was unhelpful
3639 		 */
3640 		if (save_usv) {
3641 			(void) strlcat(buf, "\t<", buflen);
3642 			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
3643 			    IMM, POS);
3644 			(void) strlcat(buf, ">", buflen);
3645 		}
3646 	}
3647 
3648 	if (reltgt != 0) {
3649 		/* Print symbol or effective address for reltgt */
3650 
3651 		(void) strlcat(buf, "\t<", buflen);
3652 		curlen = strlen(buf);
3653 		lookup(dis->d86_data, reltgt, buf + curlen,
3654 		    buflen - curlen);
3655 		(void) strlcat(buf, ">", buflen);
3656 	}
3657 }
3658 
3659 #endif /* DIS_TEXT */
3660