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