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