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