1179237Sjb/*
2253772Savg *
3179237Sjb * CDDL HEADER START
4179237Sjb *
5179237Sjb * The contents of this file are subject to the terms of the
6179237Sjb * Common Development and Distribution License (the "License").
7179237Sjb * You may not use this file except in compliance with the License.
8179237Sjb *
9179237Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10179237Sjb * or http://www.opensolaris.org/os/licensing.
11179237Sjb * See the License for the specific language governing permissions
12179237Sjb * and limitations under the License.
13179237Sjb *
14179237Sjb * When distributing Covered Code, include this CDDL HEADER in each
15179237Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16179237Sjb * If applicable, add the following below this CDDL HEADER, with the
17179237Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18179237Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19179237Sjb *
20179237Sjb * CDDL HEADER END
21179237Sjb */
22179237Sjb/*
23253772Savg * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24179237Sjb */
25179237Sjb
26253772Savg/*
27253772Savg * Copyright (c) 2010, Intel Corporation.
28253772Savg * All rights reserved.
29253772Savg */
30253772Savg
31179237Sjb/*	Copyright (c) 1988 AT&T	*/
32179237Sjb/*	  All Rights Reserved  	*/
33179237Sjb
34253772Savg/*
35253772Savg * $FreeBSD$
36253772Savg */
37179237Sjb
38179237Sjb#include	"dis_tables.h"
39179237Sjb
40179237Sjb/* BEGIN CSTYLED */
41179237Sjb
42179237Sjb/*
43179237Sjb * Disassembly begins in dis_distable, which is equivalent to the One-byte
44179237Sjb * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
45179237Sjb * decoding loops then traverse out through the other tables as necessary to
46179237Sjb * decode a given instruction.
47179237Sjb *
48179237Sjb * The behavior of this file can be controlled by one of the following flags:
49179237Sjb *
50179237Sjb * 	DIS_TEXT	Include text for disassembly
51179237Sjb * 	DIS_MEM		Include memory-size calculations
52179237Sjb *
53179237Sjb * Either or both of these can be defined.
54179237Sjb *
55179237Sjb * This file is not, and will never be, cstyled.  If anything, the tables should
56179237Sjb * be taken out another tab stop or two so nothing overlaps.
57179237Sjb */
58179237Sjb
59179237Sjb/*
60179237Sjb * These functions must be provided for the consumer to do disassembly.
61179237Sjb */
62179237Sjb#ifdef DIS_TEXT
63179237Sjbextern char *strncpy(char *, const char *, size_t);
64179237Sjbextern size_t strlen(const char *);
65179237Sjbextern int strcmp(const char *, const char *);
66179237Sjbextern int strncmp(const char *, const char *, size_t);
67179237Sjbextern size_t strlcat(char *, const char *, size_t);
68179237Sjb#endif
69179237Sjb
70179237Sjb
71253772Savg#define		TERM 	0	/* used to indicate that the 'indirect' */
72179237Sjb				/* field terminates - no pointer.	*/
73179237Sjb
74179237Sjb/* Used to decode instructions. */
75179237Sjbtypedef struct	instable {
76253772Savg	struct instable	*it_indirect;	/* for decode op codes */
77179237Sjb	uchar_t		it_adrmode;
78179237Sjb#ifdef DIS_TEXT
79179237Sjb	char		it_name[NCPS];
80253772Savg	uint_t		it_suffix:1;		/* mnem + "w", "l", or "d" */
81179237Sjb#endif
82179237Sjb#ifdef DIS_MEM
83179237Sjb	uint_t		it_size:16;
84179237Sjb#endif
85179237Sjb	uint_t		it_invalid64:1;		/* opcode invalid in amd64 */
86179237Sjb	uint_t		it_always64:1;		/* 64 bit when in 64 bit mode */
87179237Sjb	uint_t		it_invalid32:1;		/* invalid in IA32 */
88179237Sjb	uint_t		it_stackop:1;		/* push/pop stack operation */
89179237Sjb} instable_t;
90179237Sjb
91179237Sjb/*
92179237Sjb * Instruction formats.
93179237Sjb */
94179237Sjbenum {
95179237Sjb	UNKNOWN,
96179237Sjb	MRw,
97179237Sjb	IMlw,
98179237Sjb	IMw,
99179237Sjb	IR,
100179237Sjb	OA,
101179237Sjb	AO,
102179237Sjb	MS,
103179237Sjb	SM,
104179237Sjb	Mv,
105179237Sjb	Mw,
106179237Sjb	M,		/* register or memory */
107179237Sjb	Mb,		/* register or memory, always byte sized */
108179237Sjb	MO,		/* memory only (no registers) */
109179237Sjb	PREF,
110179237Sjb	SWAPGS,
111253772Savg	MONITOR_MWAIT,
112179237Sjb	R,
113179237Sjb	RA,
114179237Sjb	SEG,
115179237Sjb	MR,
116179237Sjb	RM,
117179237Sjb	IA,
118179237Sjb	MA,
119179237Sjb	SD,
120179237Sjb	AD,
121179237Sjb	SA,
122179237Sjb	D,
123179237Sjb	INM,
124179237Sjb	SO,
125179237Sjb	BD,
126179237Sjb	I,
127179237Sjb	P,
128179237Sjb	V,
129179237Sjb	DSHIFT,		/* for double shift that has an 8-bit immediate */
130179237Sjb	U,
131179237Sjb	OVERRIDE,
132179237Sjb	NORM,		/* instructions w/o ModR/M byte, no memory access */
133179237Sjb	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
134179237Sjb	O,		/* for call	*/
135179237Sjb	JTAB,		/* jump table 	*/
136179237Sjb	IMUL,		/* for 186 iimul instr  */
137179237Sjb	CBW,		/* so data16 can be evaluated for cbw and variants */
138179237Sjb	MvI,		/* for 186 logicals */
139179237Sjb	ENTER,		/* for 186 enter instr  */
140179237Sjb	RMw,		/* for 286 arpl instr */
141179237Sjb	Ib,		/* for push immediate byte */
142179237Sjb	F,		/* for 287 instructions */
143179237Sjb	FF,		/* for 287 instructions */
144179237Sjb	FFC,		/* for 287 instructions */
145179237Sjb	DM,		/* 16-bit data */
146179237Sjb	AM,		/* 16-bit addr */
147179237Sjb	LSEG,		/* for 3-bit seg reg encoding */
148179237Sjb	MIb,		/* for 386 logicals */
149179237Sjb	SREG,		/* for 386 special registers */
150179237Sjb	PREFIX,		/* a REP instruction prefix */
151179237Sjb	LOCK,		/* a LOCK instruction prefix */
152179237Sjb	INT3,		/* The int 3 instruction, which has a fake operand */
153179237Sjb	INTx,		/* The normal int instruction, with explicit int num */
154179237Sjb	DSHIFTcl,	/* for double shift that implicitly uses %cl */
155179237Sjb	CWD,		/* so data16 can be evaluated for cwd and variants */
156179237Sjb	RET,		/* single immediate 16-bit operand */
157179237Sjb	MOVZ,		/* for movs and movz, with different size operands */
158253772Savg	CRC32,		/* for crc32, with different size operands */
159179237Sjb	XADDB,		/* for xaddb */
160179237Sjb	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
161253772Savg	MOVBE,		/* movbe instruction */
162179237Sjb
163179237Sjb/*
164179237Sjb * MMX/SIMD addressing modes.
165179237Sjb */
166179237Sjb
167179237Sjb	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
168179237Sjb	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
169179237Sjb	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
170179237Sjb	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
171179237Sjb	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
172179237Sjb	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
173179237Sjb	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
174253772Savg	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
175179237Sjb	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
176179237Sjb	MMOSH,		/* Prefixable MMX		mm,imm8	*/
177179237Sjb	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
178179237Sjb	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
179179237Sjb	MMSH,		/* MMX				mm,imm8 */
180179237Sjb	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
181179237Sjb	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
182179237Sjb	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
183179237Sjb	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
184179237Sjb	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
185179237Sjb	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
186179237Sjb	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
187179237Sjb	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
188179237Sjb	XMM,		/* SIMD 			xmm/mem	-> xmm */
189253772Savg	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
190253772Savg	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
191179237Sjb	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
192179237Sjb	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
193253772Savg	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
194179237Sjb	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
195253772Savg	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
196253772Savg	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
197179237Sjb	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
198253772Savg	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
199179237Sjb	XMMS,		/* SIMD				xmm	-> xmm/mem */
200179237Sjb	XMMM,		/* SIMD 			mem	-> xmm */
201253772Savg	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
202179237Sjb	XMMMS,		/* SIMD				xmm	-> mem */
203179237Sjb	XMM3MX,		/* SIMD 			r32/mem -> xmm */
204179237Sjb	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
205179237Sjb	XMMSH,		/* SIMD 			xmm,imm8 */
206179237Sjb	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
207179237Sjb	XMMX3,		/* SIMD 			xmm	-> r32 */
208179237Sjb	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
209179237Sjb	XMMMX,		/* SIMD 			mm	-> xmm */
210179237Sjb	XMMXM,		/* SIMD 			xmm	-> mm */
211253772Savg        XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
212253772Savg        XMM2I,		/* SIMD				xmm, imm, imm */
213179237Sjb	XMMFENCE,	/* SIMD lfence or mfence */
214253772Savg	XMMSFNC,	/* SIMD sfence (none or mem) */
215253772Savg	XGETBV_XSETBV,
216253772Savg	VEX_NONE,	/* VEX  no operand */
217253772Savg	VEX_MO,		/* VEX	mod_rm		               -> implicit reg */
218253772Savg	VEX_RMrX,	/* VEX  VEX.vvvv, mod_rm               -> mod_reg */
219253772Savg	VEX_RRX,	/* VEX  VEX.vvvv, mod_reg              -> mod_rm */
220253772Savg	VEX_RMRX,	/* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
221253772Savg	VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
222253772Savg	VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
223253772Savg	VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
224253772Savg	VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
225253772Savg	VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
226253772Savg	VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
227253772Savg	VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
228253772Savg	VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
229253772Savg	VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
230253772Savg	VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
231253772Savg	VEX_RMX         /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
232179237Sjb};
233179237Sjb
234253772Savg/*
235253772Savg * VEX prefixes
236253772Savg */
237253772Savg#define VEX_2bytes	0xC5	/* the first byte of two-byte form */
238253772Savg#define VEX_3bytes	0xC4	/* the first byte of three-byte form */
239253772Savg
240179237Sjb#define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
241179237Sjb
242179237Sjb/*
243179237Sjb** Register numbers for the i386
244179237Sjb*/
245179237Sjb#define	EAX_REGNO 0
246179237Sjb#define	ECX_REGNO 1
247179237Sjb#define	EDX_REGNO 2
248179237Sjb#define	EBX_REGNO 3
249179237Sjb#define	ESP_REGNO 4
250179237Sjb#define	EBP_REGNO 5
251179237Sjb#define	ESI_REGNO 6
252179237Sjb#define	EDI_REGNO 7
253179237Sjb
254179237Sjb/*
255179237Sjb * modes for immediate values
256179237Sjb */
257179237Sjb#define	MODE_NONE	0
258179237Sjb#define	MODE_IPREL	1	/* signed IP relative value */
259179237Sjb#define	MODE_SIGNED	2	/* sign extended immediate */
260179237Sjb#define	MODE_IMPLIED	3	/* constant value implied from opcode */
261179237Sjb#define	MODE_OFFSET	4	/* offset part of an address */
262253772Savg#define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
263179237Sjb
264179237Sjb/*
265179237Sjb * The letters used in these macros are:
266179237Sjb *   IND - indirect to another to another table
267179237Sjb *   "T" - means to Terminate indirections (this is the final opcode)
268179237Sjb *   "S" - means "operand length suffix required"
269179237Sjb *   "NS" - means "no suffix" which is the operand length suffix of the opcode
270179237Sjb *   "Z" - means instruction size arg required
271179237Sjb *   "u" - means the opcode is invalid in IA32 but valid in amd64
272179237Sjb *   "x" - means the opcode is invalid in amd64, but not IA32
273179237Sjb *   "y" - means the operand size is always 64 bits in 64 bit mode
274179237Sjb *   "p" - means push/pop stack operation
275179237Sjb */
276179237Sjb
277179237Sjb#if defined(DIS_TEXT) && defined(DIS_MEM)
278253772Savg#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
279253772Savg#define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
280179237Sjb#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
281179237Sjb#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
282179237Sjb#define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
283179237Sjb#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
284179237Sjb#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
285179237Sjb#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
286179237Sjb#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
287179237Sjb#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
288179237Sjb#define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
289179237Sjb#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
290179237Sjb#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
291179237Sjb#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
292179237Sjb#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
293179237Sjb#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
294179237Sjb#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
295179237Sjb#elif defined(DIS_TEXT)
296253772Savg#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
297253772Savg#define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
298179237Sjb#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
299179237Sjb#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
300179237Sjb#define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
301179237Sjb#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
302179237Sjb#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
303179237Sjb#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
304179237Sjb#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
305179237Sjb#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
306179237Sjb#define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
307179237Sjb#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
308179237Sjb#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
309179237Sjb#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
310179237Sjb#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
311179237Sjb#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
312179237Sjb#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
313179237Sjb#elif defined(DIS_MEM)
314253772Savg#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
315253772Savg#define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
316179237Sjb#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
317179237Sjb#define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
318179237Sjb#define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
319179237Sjb#define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
320179237Sjb#define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
321179237Sjb#define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
322179237Sjb#define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
323179237Sjb#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
324179237Sjb#define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
325179237Sjb#define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
326179237Sjb#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
327179237Sjb#define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
328179237Sjb#define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
329179237Sjb#define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
330179237Sjb#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
331179237Sjb#else
332253772Savg#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
333253772Savg#define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
334179237Sjb#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
335179237Sjb#define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
336179237Sjb#define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
337179237Sjb#define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
338179237Sjb#define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
339179237Sjb#define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
340179237Sjb#define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
341179237Sjb#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
342179237Sjb#define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
343179237Sjb#define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
344179237Sjb#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
345179237Sjb#define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
346179237Sjb#define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
347179237Sjb#define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
348179237Sjb#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
349179237Sjb#endif
350179237Sjb
351179237Sjb#ifdef DIS_TEXT
352179237Sjb/*
353179237Sjb * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
354179237Sjb */
355179237Sjbconst char *const dis_addr16[3][8] = {
356179237Sjb"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
357179237Sjb									"(%bx)",
358179237Sjb"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
359179237Sjb									"(%bx)",
360179237Sjb"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
361179237Sjb									"(%bx)",
362179237Sjb};
363179237Sjb
364179237Sjb
365179237Sjb/*
366179237Sjb * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
367179237Sjb */
368179237Sjbconst char *const dis_addr32_mode0[16] = {
369179237Sjb  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
370179237Sjb  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
371179237Sjb};
372179237Sjb
373179237Sjbconst char *const dis_addr32_mode12[16] = {
374179237Sjb  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
375179237Sjb  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
376179237Sjb};
377179237Sjb
378179237Sjb/*
379179237Sjb * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
380179237Sjb */
381179237Sjbconst char *const dis_addr64_mode0[16] = {
382179237Sjb "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
383179237Sjb "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
384179237Sjb};
385179237Sjbconst char *const dis_addr64_mode12[16] = {
386179237Sjb "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
387179237Sjb "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
388179237Sjb};
389179237Sjb
390179237Sjb/*
391179237Sjb * decode for scale from SIB byte
392179237Sjb */
393179237Sjbconst char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
394179237Sjb
395179237Sjb/*
396179237Sjb * register decoding for normal references to registers (ie. not addressing)
397179237Sjb */
398179237Sjbconst char *const dis_REG8[16] = {
399179237Sjb	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
400179237Sjb	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
401179237Sjb};
402179237Sjb
403179237Sjbconst char *const dis_REG8_REX[16] = {
404179237Sjb	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
405179237Sjb	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
406179237Sjb};
407179237Sjb
408179237Sjbconst char *const dis_REG16[16] = {
409179237Sjb	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
410179237Sjb	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
411179237Sjb};
412179237Sjb
413179237Sjbconst char *const dis_REG32[16] = {
414179237Sjb	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
415179237Sjb	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
416179237Sjb};
417179237Sjb
418179237Sjbconst char *const dis_REG64[16] = {
419179237Sjb	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
420179237Sjb	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
421179237Sjb};
422179237Sjb
423179237Sjbconst char *const dis_DEBUGREG[16] = {
424179237Sjb	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
425179237Sjb	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
426179237Sjb};
427179237Sjb
428179237Sjbconst char *const dis_CONTROLREG[16] = {
429179237Sjb    "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
430179237Sjb    "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
431179237Sjb};
432179237Sjb
433179237Sjbconst char *const dis_TESTREG[16] = {
434179237Sjb	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
435179237Sjb	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
436179237Sjb};
437179237Sjb
438179237Sjbconst char *const dis_MMREG[16] = {
439179237Sjb	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
440179237Sjb	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
441179237Sjb};
442179237Sjb
443179237Sjbconst char *const dis_XMMREG[16] = {
444179237Sjb    "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
445179237Sjb    "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
446179237Sjb};
447179237Sjb
448253772Savgconst char *const dis_YMMREG[16] = {
449253772Savg    "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
450253772Savg    "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
451253772Savg};
452253772Savg
453179237Sjbconst char *const dis_SEGREG[16] = {
454179237Sjb	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
455179237Sjb	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
456179237Sjb};
457179237Sjb
458179237Sjb/*
459179237Sjb * SIMD predicate suffixes
460179237Sjb */
461179237Sjbconst char *const dis_PREDSUFFIX[8] = {
462179237Sjb	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
463179237Sjb};
464179237Sjb
465253772Savgconst char *const dis_AVXvgrp7[3][8] = {
466253772Savg	/*0	1	2		3		4		5	6		7*/
467253772Savg/*71*/	{"",	"",	"vpsrlw",	"",		"vpsraw",	"",	"vpsllw",	""},
468253772Savg/*72*/	{"",	"",	"vpsrld",	"",		"vpsrad",	"",	"vpslld",	""},
469253772Savg/*73*/	{"",	"",	"vpsrlq",	"vpsrldq",	"",		"",	"vpsllq",	"vpslldq"}
470253772Savg};
471179237Sjb
472179237Sjb#endif	/* DIS_TEXT */
473179237Sjb
474179237Sjb/*
475179237Sjb *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
476179237Sjb */
477179237Sjbconst instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
478179237Sjb
479179237Sjb/*
480179237Sjb *	"decode table" for pause and clflush instructions
481179237Sjb */
482179237Sjbconst instable_t dis_opPause = TNS("pause", NORM);
483179237Sjb
484179237Sjb/*
485179237Sjb *	Decode table for 0x0F00 opcodes
486179237Sjb */
487179237Sjbconst instable_t dis_op0F00[8] = {
488179237Sjb
489179237Sjb/*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
490179237Sjb/*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
491179237Sjb};
492179237Sjb
493179237Sjb
494179237Sjb/*
495179237Sjb *	Decode table for 0x0F01 opcodes
496179237Sjb */
497179237Sjbconst instable_t dis_op0F01[8] = {
498179237Sjb
499253772Savg/*  [0]  */	TNSZ("sgdt",MO,6),	TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6),	TNSZ("lidt",MO,6),
500179237Sjb/*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS),
501179237Sjb};
502179237Sjb
503179237Sjb/*
504179237Sjb *	Decode table for 0x0F18 opcodes -- SIMD prefetch
505179237Sjb */
506179237Sjbconst instable_t dis_op0F18[8] = {
507179237Sjb
508179237Sjb/*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
509179237Sjb/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
510179237Sjb};
511179237Sjb
512179237Sjb/*
513179237Sjb * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
514179237Sjb */
515179237Sjbconst instable_t dis_op0FAE[8] = {
516179237Sjb/*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
517253772Savg/*  [4]  */	TNSZ("xsave",M,512),	TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
518179237Sjb};
519179237Sjb
520179237Sjb/*
521179237Sjb *	Decode table for 0x0FBA opcodes
522179237Sjb */
523179237Sjb
524179237Sjbconst instable_t dis_op0FBA[8] = {
525179237Sjb
526179237Sjb/*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
527179237Sjb/*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
528179237Sjb};
529179237Sjb
530179237Sjb/*
531179237Sjb * 	Decode table for 0x0FC7 opcode
532179237Sjb */
533179237Sjb
534179237Sjbconst instable_t dis_op0FC7[8] = {
535179237Sjb
536179237Sjb/*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
537179237Sjb/*  [4]  */	INVALID,		INVALID,	INVALID,		 INVALID,
538179237Sjb};
539179237Sjb
540179237Sjb
541179237Sjb/*
542179237Sjb *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
543179237Sjb *
544179237Sjb *bit pattern: 0000 1111 1100 1reg
545179237Sjb */
546179237Sjbconst instable_t dis_op0FC8[4] = {
547179237Sjb/*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
548179237Sjb};
549179237Sjb
550179237Sjb/*
551179237Sjb *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
552179237Sjb */
553179237Sjbconst instable_t dis_op0F7123[4][8] = {
554179237Sjb{
555179237Sjb/*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
556179237Sjb/*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
557179237Sjb}, {
558179237Sjb/*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
559179237Sjb/*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
560179237Sjb}, {
561179237Sjb/*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
562179237Sjb/*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
563179237Sjb}, {
564179237Sjb/*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
565179237Sjb/*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
566179237Sjb} };
567179237Sjb
568179237Sjb/*
569179237Sjb *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
570179237Sjb */
571179237Sjbconst instable_t dis_opSIMD7123[32] = {
572179237Sjb/* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
573179237Sjb/*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
574179237Sjb
575179237Sjb/* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
576179237Sjb/*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
577179237Sjb
578179237Sjb/* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
579179237Sjb/*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
580179237Sjb
581179237Sjb/* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
582179237Sjb/*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
583179237Sjb};
584179237Sjb
585179237Sjb/*
586179237Sjb *	SIMD instructions have been wedged into the existing IA32 instruction
587179237Sjb *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
588179237Sjb *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
589179237Sjb *	instruction - addss.  At present, three prefixes have been coopted in
590179237Sjb *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
591179237Sjb *	following tables are used to provide the prefixed instruction names.
592179237Sjb *	The arrays are sparse, but they're fast.
593179237Sjb */
594179237Sjb
595179237Sjb/*
596179237Sjb *	Decode table for SIMD instructions with the address size (0x66) prefix.
597179237Sjb */
598179237Sjbconst instable_t dis_opSIMDdata16[256] = {
599179237Sjb/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
600179237Sjb/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
601179237Sjb/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
602179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
603179237Sjb
604179237Sjb/*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
605179237Sjb/*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
606179237Sjb/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
607179237Sjb/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
608179237Sjb
609179237Sjb/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
610179237Sjb/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
611179237Sjb/*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
612179237Sjb/*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
613179237Sjb
614179237Sjb/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
615179237Sjb/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
616179237Sjb/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
617179237Sjb/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
618179237Sjb
619179237Sjb/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
620179237Sjb/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
621179237Sjb/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
622179237Sjb/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
623179237Sjb
624179237Sjb/*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
625179237Sjb/*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
626179237Sjb/*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
627179237Sjb/*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
628179237Sjb
629179237Sjb/*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
630179237Sjb/*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
631179237Sjb/*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
632179237Sjb/*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
633179237Sjb
634179237Sjb/*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
635179237Sjb/*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
636253772Savg/*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
637179237Sjb/*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
638179237Sjb
639179237Sjb/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
640179237Sjb/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
641179237Sjb/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
642179237Sjb/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
643179237Sjb
644179237Sjb/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
645179237Sjb/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
646179237Sjb/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
647179237Sjb/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
648179237Sjb
649179237Sjb/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
650179237Sjb/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
651179237Sjb/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
652179237Sjb/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
653179237Sjb
654179237Sjb/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
655179237Sjb/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
656179237Sjb/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
657179237Sjb/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
658179237Sjb
659179237Sjb/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
660179237Sjb/*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
661179237Sjb/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
662179237Sjb/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
663179237Sjb
664179237Sjb/*  [D0]  */	INVALID,		TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
665179237Sjb/*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
666179237Sjb/*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
667179237Sjb/*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
668179237Sjb
669179237Sjb/*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
670179237Sjb/*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
671179237Sjb/*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
672179237Sjb/*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
673179237Sjb
674179237Sjb/*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
675179237Sjb/*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
676179237Sjb/*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
677179237Sjb/*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
678179237Sjb};
679179237Sjb
680253772Savgconst instable_t dis_opAVX660F[256] = {
681253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
682253772Savg/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
683253772Savg/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
684253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
685253772Savg
686253772Savg/*  [10]  */	TNSZ("vmovupd",VEX_MX,16),	TNSZ("vmovupd",VEX_RX,16),	TNSZ("vmovlpd",VEX_RMrX,8),	TNSZ("vmovlpd",VEX_RM,8),
687253772Savg/*  [14]  */	TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8),	TNSZ("vmovhpd",VEX_RM,8),
688253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
689253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
690253772Savg
691253772Savg/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
692253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
693253772Savg/*  [28]  */	TNSZ("vmovapd",VEX_MX,16),	TNSZ("vmovapd",VEX_RX,16),	INVALID,		TNSZ("vmovntpd",VEX_RM,16),
694253772Savg/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
695253772Savg
696253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
697253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
698253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
699253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
700253772Savg
701253772Savg/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
702253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
703253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
704253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
705253772Savg
706253772Savg/*  [50]  */	TNS("vmovmskpd",VEX_MR),	TNSZ("vsqrtpd",VEX_MX,16),	INVALID,		INVALID,
707253772Savg/*  [54]  */	TNSZ("vandpd",VEX_RMrX,16),	TNSZ("vandnpd",VEX_RMrX,16),	TNSZ("vorpd",VEX_RMrX,16),	TNSZ("vxorpd",VEX_RMrX,16),
708253772Savg/*  [58]  */	TNSZ("vaddpd",VEX_RMrX,16),	TNSZ("vmulpd",VEX_RMrX,16),	TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
709253772Savg/*  [5C]  */	TNSZ("vsubpd",VEX_RMrX,16),	TNSZ("vminpd",VEX_RMrX,16),	TNSZ("vdivpd",VEX_RMrX,16),	TNSZ("vmaxpd",VEX_RMrX,16),
710253772Savg
711253772Savg/*  [60]  */	TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
712253772Savg/*  [64]  */	TNSZ("vpcmpgtb",VEX_RMrX,16),	TNSZ("vpcmpgtw",VEX_RMrX,16),	TNSZ("vpcmpgtd",VEX_RMrX,16),	TNSZ("vpackuswb",VEX_RMrX,16),
713253772Savg/*  [68]  */	TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
714253772Savg/*  [6C]  */	TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
715253772Savg
716253772Savg/*  [70]  */	TNSZ("vpshufd",VEX_MXI,16),	TNSZ("vgrp71",VEX_XXI,16),	TNSZ("vgrp72",VEX_XXI,16),		TNSZ("vgrp73",VEX_XXI,16),
717253772Savg/*  [74]  */	TNSZ("vpcmpeqb",VEX_RMrX,16),	TNSZ("vpcmpeqw",VEX_RMrX,16),	TNSZ("vpcmpeqd",VEX_RMrX,16),	INVALID,
718253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
719253772Savg/*  [7C]  */	TNSZ("vhaddpd",VEX_RMrX,16),	TNSZ("vhsubpd",VEX_RMrX,16),	TNSZ("vmovd",VEX_RR,4),	TNSZ("vmovdqa",VEX_RX,16),
720253772Savg
721253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
722253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
723253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
724253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
725253772Savg
726253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
727253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
728253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
729253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
730253772Savg
731253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
732253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
733253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
734253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
735253772Savg
736253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
737253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
738253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
739253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
740253772Savg
741253772Savg/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmppd",VEX_RMRX,16),	INVALID,
742253772Savg/*  [C4]  */	TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),	TNSZ("vshufpd",VEX_RMRX,16),	INVALID,
743253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
744253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
745253772Savg
746253772Savg/*  [D0]  */	TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),	TNSZ("vpsrld",VEX_RMrX,16),	TNSZ("vpsrlq",VEX_RMrX,16),
747253772Savg/*  [D4]  */	TNSZ("vpaddq",VEX_RMrX,16),	TNSZ("vpmullw",VEX_RMrX,16),	TNSZ("vmovq",VEX_RX,8),	TNS("vpmovmskb",VEX_MR),
748253772Savg/*  [D8]  */	TNSZ("vpsubusb",VEX_RMrX,16),	TNSZ("vpsubusw",VEX_RMrX,16),	TNSZ("vpminub",VEX_RMrX,16),	TNSZ("vpand",VEX_RMrX,16),
749253772Savg/*  [DC]  */	TNSZ("vpaddusb",VEX_RMrX,16),	TNSZ("vpaddusw",VEX_RMrX,16),	TNSZ("vpmaxub",VEX_RMrX,16),	TNSZ("vpandn",VEX_RMrX,16),
750253772Savg
751253772Savg/*  [E0]  */	TNSZ("vpavgb",VEX_RMrX,16),	TNSZ("vpsraw",VEX_RMrX,16),	TNSZ("vpsrad",VEX_RMrX,16),	TNSZ("vpavgw",VEX_RMrX,16),
752253772Savg/*  [E4]  */	TNSZ("vpmulhuw",VEX_RMrX,16),	TNSZ("vpmulhw",VEX_RMrX,16),	TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
753253772Savg/*  [E8]  */	TNSZ("vpsubsb",VEX_RMrX,16),	TNSZ("vpsubsw",VEX_RMrX,16),	TNSZ("vpminsw",VEX_RMrX,16),	TNSZ("vpor",VEX_RMrX,16),
754253772Savg/*  [EC]  */	TNSZ("vpaddsb",VEX_RMrX,16),	TNSZ("vpaddsw",VEX_RMrX,16),	TNSZ("vpmaxsw",VEX_RMrX,16),	TNSZ("vpxor",VEX_RMrX,16),
755253772Savg
756253772Savg/*  [F0]  */	INVALID,		TNSZ("vpsllw",VEX_RMrX,16),	TNSZ("vpslld",VEX_RMrX,16),	TNSZ("vpsllq",VEX_RMrX,16),
757253772Savg/*  [F4]  */	TNSZ("vpmuludq",VEX_RMrX,16),	TNSZ("vpmaddwd",VEX_RMrX,16),	TNSZ("vpsadbw",VEX_RMrX,16),	TNS("vmaskmovdqu",VEX_MX),
758253772Savg/*  [F8]  */	TNSZ("vpsubb",VEX_RMrX,16),	TNSZ("vpsubw",VEX_RMrX,16),	TNSZ("vpsubd",VEX_RMrX,16),	TNSZ("vpsubq",VEX_RMrX,16),
759253772Savg/*  [FC]  */	TNSZ("vpaddb",VEX_RMrX,16),	TNSZ("vpaddw",VEX_RMrX,16),	TNSZ("vpaddd",VEX_RMrX,16),	INVALID,
760253772Savg};
761253772Savg
762179237Sjb/*
763179237Sjb *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
764179237Sjb */
765179237Sjbconst instable_t dis_opSIMDrepnz[256] = {
766179237Sjb/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
767179237Sjb/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
768179237Sjb/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
769179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
770179237Sjb
771179237Sjb/*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	INVALID,		INVALID,
772179237Sjb/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
773179237Sjb/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
774179237Sjb/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
775179237Sjb
776179237Sjb/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
777179237Sjb/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
778253772Savg/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
779179237Sjb/*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
780179237Sjb
781179237Sjb/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
782179237Sjb/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
783179237Sjb/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
784179237Sjb/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
785179237Sjb
786179237Sjb/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
787179237Sjb/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
788179237Sjb/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
789179237Sjb/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
790179237Sjb
791179237Sjb/*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
792179237Sjb/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
793179237Sjb/*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
794179237Sjb/*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
795179237Sjb
796179237Sjb/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
797179237Sjb/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
798179237Sjb/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
799179237Sjb/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
800179237Sjb
801179237Sjb/*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
802179237Sjb/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
803253772Savg/*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
804179237Sjb/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
805179237Sjb
806179237Sjb/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
807179237Sjb/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
808179237Sjb/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
809179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
810179237Sjb
811179237Sjb/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
812179237Sjb/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
813179237Sjb/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
814179237Sjb/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
815179237Sjb
816179237Sjb/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
817179237Sjb/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
818179237Sjb/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
819179237Sjb/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
820179237Sjb
821179237Sjb/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
822179237Sjb/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
823179237Sjb/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
824179237Sjb/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
825179237Sjb
826179237Sjb/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
827179237Sjb/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
828179237Sjb/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
829179237Sjb/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
830179237Sjb
831179237Sjb/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
832179237Sjb/*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
833179237Sjb/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
834179237Sjb/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
835179237Sjb
836179237Sjb/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
837179237Sjb/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
838179237Sjb/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
839179237Sjb/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
840179237Sjb
841179237Sjb/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
842179237Sjb/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
843179237Sjb/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
844179237Sjb/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
845179237Sjb};
846179237Sjb
847253772Savgconst instable_t dis_opAVXF20F[256] = {
848253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
849253772Savg/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
850253772Savg/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
851253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
852253772Savg
853253772Savg/*  [10]  */	TNSZ("vmovsd",VEX_RMrX,8),	TNSZ("vmovsd",VEX_RRX,8),	TNSZ("vmovddup",VEX_MX,8),	INVALID,
854253772Savg/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
855253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
856253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
857253772Savg
858253772Savg/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
859253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
860253772Savg/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
861253772Savg/*  [2C]  */	TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,		INVALID,
862253772Savg
863253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
864253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
865253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
866253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
867253772Savg
868253772Savg/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
869253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
870253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
871253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
872253772Savg
873253772Savg/*  [50]  */	INVALID,		TNSZ("vsqrtsd",VEX_RMrX,8),	INVALID,		INVALID,
874253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
875253772Savg/*  [58]  */	TNSZ("vaddsd",VEX_RMrX,8),	TNSZ("vmulsd",VEX_RMrX,8),	TNSZ("vcvtsd2ss",VEX_RMrX,8),	INVALID,
876253772Savg/*  [5C]  */	TNSZ("vsubsd",VEX_RMrX,8),	TNSZ("vminsd",VEX_RMrX,8),	TNSZ("vdivsd",VEX_RMrX,8),	TNSZ("vmaxsd",VEX_RMrX,8),
877253772Savg
878253772Savg/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
879253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
880253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
881253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
882253772Savg
883253772Savg/*  [70]  */	TNSZ("vpshuflw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
884253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
885253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
886253772Savg/*  [7C]  */	TNSZ("vhaddps",VEX_RMrX,8),	TNSZ("vhsubps",VEX_RMrX,8),	INVALID,		INVALID,
887253772Savg
888253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
889253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
890253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
891253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
892253772Savg
893253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
894253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
895253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
896253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
897253772Savg
898253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
899253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
900253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
901253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
902253772Savg
903253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
904253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
905253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
906253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
907253772Savg
908253772Savg/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpsd",VEX_RMRX,8),	INVALID,
909253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
910253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
911253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
912253772Savg
913253772Savg/*  [D0]  */	TNSZ("vaddsubps",VEX_RMrX,8),	INVALID,		INVALID,		INVALID,
914253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
915253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
916253772Savg/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
917253772Savg
918253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
919253772Savg/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
920253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
921253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
922253772Savg
923253772Savg/*  [F0]  */	TNSZ("vlddqu",VEX_MX,16),	INVALID,		INVALID,		INVALID,
924253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
925253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
926253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
927253772Savg};
928253772Savg
929179237Sjb/*
930179237Sjb *	Decode table for SIMD instructions with the repz (0xf3) prefix.
931179237Sjb */
932179237Sjbconst instable_t dis_opSIMDrepz[256] = {
933179237Sjb/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
934179237Sjb/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
935179237Sjb/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
936179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
937179237Sjb
938179237Sjb/*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	INVALID,		INVALID,
939179237Sjb/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
940179237Sjb/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
941179237Sjb/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
942179237Sjb
943179237Sjb/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
944179237Sjb/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
945253772Savg/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
946179237Sjb/*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
947179237Sjb
948179237Sjb/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
949179237Sjb/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
950179237Sjb/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
951179237Sjb/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
952179237Sjb
953179237Sjb/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
954179237Sjb/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
955179237Sjb/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
956179237Sjb/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
957179237Sjb
958179237Sjb/*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
959179237Sjb/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
960179237Sjb/*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
961179237Sjb/*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
962179237Sjb
963179237Sjb/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
964179237Sjb/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
965179237Sjb/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
966179237Sjb/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
967179237Sjb
968179237Sjb/*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
969179237Sjb/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
970179237Sjb/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
971179237Sjb/*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
972179237Sjb
973179237Sjb/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
974179237Sjb/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
975179237Sjb/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
976179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
977179237Sjb
978179237Sjb/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
979179237Sjb/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
980179237Sjb/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
981179237Sjb/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
982179237Sjb
983179237Sjb/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
984179237Sjb/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
985179237Sjb/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
986179237Sjb/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
987179237Sjb
988179237Sjb/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
989179237Sjb/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
990253772Savg/*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
991253772Savg/*  [BC]  */	INVALID,		TS("lzcnt",MRw),	INVALID,		INVALID,
992179237Sjb
993179237Sjb/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
994179237Sjb/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
995179237Sjb/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
996179237Sjb/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
997179237Sjb
998179237Sjb/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
999179237Sjb/*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
1000179237Sjb/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1001179237Sjb/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1002179237Sjb
1003179237Sjb/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1004179237Sjb/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
1005179237Sjb/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1006179237Sjb/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1007179237Sjb
1008179237Sjb/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1009179237Sjb/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1010179237Sjb/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1011179237Sjb/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1012179237Sjb};
1013179237Sjb
1014253772Savgconst instable_t dis_opAVXF30F[256] = {
1015253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1016253772Savg/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1017253772Savg/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1018253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1019253772Savg
1020253772Savg/*  [10]  */	TNSZ("vmovss",VEX_RMrX,4),	TNSZ("vmovss",VEX_RRX,4),	TNSZ("vmovsldup",VEX_MX,4),	INVALID,
1021253772Savg/*  [14]  */	INVALID,		INVALID,		TNSZ("vmovshdup",VEX_MX,4),	INVALID,
1022253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1023253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1024253772Savg
1025253772Savg/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1026253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1027253772Savg/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
1028253772Savg/*  [2C]  */	TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,		INVALID,
1029253772Savg
1030253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1031253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1032253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1033253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1034253772Savg
1035253772Savg/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1036253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1037253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1038253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1039253772Savg
1040253772Savg/*  [50]  */	INVALID,		TNSZ("vsqrtss",VEX_RMrX,4),	TNSZ("vrsqrtss",VEX_RMrX,4),	TNSZ("vrcpss",VEX_RMrX,4),
1041253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1042253772Savg/*  [58]  */	TNSZ("vaddss",VEX_RMrX,4),	TNSZ("vmulss",VEX_RMrX,4),	TNSZ("vcvtss2sd",VEX_RMrX,4),	TNSZ("vcvttps2dq",VEX_MX,16),
1043253772Savg/*  [5C]  */	TNSZ("vsubss",VEX_RMrX,4),	TNSZ("vminss",VEX_RMrX,4),	TNSZ("vdivss",VEX_RMrX,4),	TNSZ("vmaxss",VEX_RMrX,4),
1044253772Savg
1045253772Savg/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1046253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1047253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1048253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("vmovdqu",VEX_MX,16),
1049253772Savg
1050253772Savg/*  [70]  */	TNSZ("vpshufhw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
1051253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1052253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1053253772Savg/*  [7C]  */	INVALID,		INVALID,		TNSZ("vmovq",VEX_MX,8),	TNSZ("vmovdqu",VEX_RX,16),
1054253772Savg
1055253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1056253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1057253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1058253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1059253772Savg
1060253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1061253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1062253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1063253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1064253772Savg
1065253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1066253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1067253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1068253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1069253772Savg
1070253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1071253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1072253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1073253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1074253772Savg
1075253772Savg/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpss",VEX_RMRX,4),	INVALID,
1076253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1077253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1078253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1079253772Savg
1080253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1081253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1082253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1083253772Savg/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1084253772Savg
1085253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1086253772Savg/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtdq2pd",VEX_MX,8),	INVALID,
1087253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1088253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1089253772Savg
1090253772Savg/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1091253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1092253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1093253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1094253772Savg};
1095179237Sjb/*
1096253772Savg * The following two tables are used to encode crc32 and movbe
1097253772Savg * since they share the same opcodes.
1098253772Savg */
1099253772Savgconst instable_t dis_op0F38F0[2] = {
1100253772Savg/*  [00]  */	TNS("crc32b",CRC32),
1101253772Savg		TS("movbe",MOVBE),
1102253772Savg};
1103253772Savg
1104253772Savgconst instable_t dis_op0F38F1[2] = {
1105253772Savg/*  [00]  */	TS("crc32",CRC32),
1106253772Savg		TS("movbe",MOVBE),
1107253772Savg};
1108253772Savg
1109253772Savgconst instable_t dis_op0F38[256] = {
1110253772Savg/*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
1111253772Savg/*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
1112253772Savg/*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
1113253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1114253772Savg
1115253772Savg/*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
1116253772Savg/*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
1117253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1118253772Savg/*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
1119253772Savg
1120253772Savg/*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
1121253772Savg/*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
1122253772Savg/*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
1123253772Savg/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1124253772Savg
1125253772Savg/*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
1126253772Savg/*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
1127253772Savg/*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
1128253772Savg/*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
1129253772Savg
1130253772Savg/*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
1131253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1132253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1133253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1134253772Savg
1135253772Savg/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1136253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1137253772Savg/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1138253772Savg/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1139253772Savg
1140253772Savg/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1141253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1142253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1143253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1144253772Savg
1145253772Savg/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1146253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1147253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1148253772Savg/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1149253772Savg
1150253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1151253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1152253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1153253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1154253772Savg
1155253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1156253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1157253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1158253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1159253772Savg
1160253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1161253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1162253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1163253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1164253772Savg
1165253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1166253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1167253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1168253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1169253772Savg
1170253772Savg/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1171253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1172253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1173253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1174253772Savg
1175253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1176253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1177253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
1178253772Savg/*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
1179253772Savg
1180253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1181253772Savg/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1182253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1183253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1184253772Savg/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1185253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1186253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1187253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1188253772Savg};
1189253772Savg
1190253772Savgconst instable_t dis_opAVX660F38[256] = {
1191253772Savg/*  [00]  */	TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
1192253772Savg/*  [04]  */	TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),	TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
1193253772Savg/*  [08]  */	TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
1194253772Savg/*  [0C]  */	TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),	TNSZ("vtestpd",VEX_RRI,16),
1195253772Savg
1196253772Savg/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1197253772Savg/*  [14]  */	INVALID,		INVALID,		INVALID,		TNSZ("vptest",VEX_RRI,16),
1198253772Savg/*  [18]  */	TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
1199253772Savg/*  [1C]  */	TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
1200253772Savg
1201253772Savg/*  [20]  */	TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
1202253772Savg/*  [24]  */	TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,	INVALID,
1203253772Savg/*  [28]  */	TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
1204253772Savg/*  [2C]  */	TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
1205253772Savg
1206253772Savg/*  [30]  */	TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
1207253772Savg/*  [34]  */	TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),INVALID,	TNSZ("vpcmpgtq",VEX_RMrX,16),
1208253772Savg/*  [38]  */	TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
1209253772Savg/*  [3C]  */	TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
1210253772Savg
1211253772Savg/*  [40]  */	TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,	INVALID,
1212253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1213253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1214253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1215253772Savg
1216253772Savg/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1217253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1218253772Savg/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1219253772Savg/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1220253772Savg
1221253772Savg/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1222253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1223253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1224253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1225253772Savg
1226253772Savg/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1227253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1228253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1229253772Savg/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1230253772Savg
1231253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1232253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1233253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1234253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1235253772Savg
1236253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1237253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1238253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1239253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1240253772Savg
1241253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1242253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1243253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1244253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1245253772Savg
1246253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1247253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1248253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1249253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1250253772Savg
1251253772Savg/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1252253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1253253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1254253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1255253772Savg
1256253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1257253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1258253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaesimc",VEX_MX,16),
1259253772Savg/*  [DC]  */	TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
1260253772Savg
1261253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1262253772Savg/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1263253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1264253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1265253772Savg/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1266253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1267253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1268253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1269253772Savg};
1270253772Savg
1271253772Savgconst instable_t dis_op0F3A[256] = {
1272253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1273253772Savg/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1274253772Savg/*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
1275253772Savg/*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
1276253772Savg
1277253772Savg/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1278253772Savg/*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
1279253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1280253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1281253772Savg
1282253772Savg/*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
1283253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1284253772Savg/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1285253772Savg/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1286253772Savg
1287253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1288253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1289253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1290253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1291253772Savg
1292253772Savg/*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
1293253772Savg/*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
1294253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1295253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1296253772Savg
1297253772Savg/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1298253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1299253772Savg/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1300253772Savg/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1301253772Savg
1302253772Savg/*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
1303253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1304253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1305253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1306253772Savg
1307253772Savg/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1308253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1309253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1310253772Savg/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1311253772Savg
1312253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1313253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1314253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1315253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1316253772Savg
1317253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1318253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1319253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1320253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1321253772Savg
1322253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1323253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1324253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1325253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1326253772Savg
1327253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1328253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1329253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1330253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1331253772Savg
1332253772Savg/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1333253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1334253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1335253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1336253772Savg
1337253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1338253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1339253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1340253772Savg/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
1341253772Savg
1342253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1343253772Savg/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1344253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1345253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1346253772Savg
1347253772Savg/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1348253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1349253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1350253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1351253772Savg};
1352253772Savg
1353253772Savgconst instable_t dis_opAVX660F3A[256] = {
1354253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1355253772Savg/*  [04]  */	TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
1356253772Savg/*  [08]  */	TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
1357253772Savg/*  [0C]  */	TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
1358253772Savg
1359253772Savg/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1360253772Savg/*  [14]  */	TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
1361253772Savg/*  [18]  */	TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,		INVALID,
1362253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1363253772Savg
1364253772Savg/*  [20]  */	TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
1365253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1366253772Savg/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1367253772Savg/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1368253772Savg
1369253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1370253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1371253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1372253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1373253772Savg
1374253772Savg/*  [40]  */	TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
1375253772Savg/*  [44]  */	TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
1376253772Savg/*  [48]  */	INVALID,		INVALID,		TNSZ("vblendvps",VEX_RMRX,8),	TNSZ("vblendvpd",VEX_RMRX,16),
1377253772Savg/*  [4C]  */	TNSZ("vpblendvb",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
1378253772Savg
1379253772Savg/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1380253772Savg/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1381253772Savg/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1382253772Savg/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1383253772Savg
1384253772Savg/*  [60]  */	TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
1385253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1386253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1387253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1388253772Savg
1389253772Savg/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1390253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1391253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1392253772Savg/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1393253772Savg
1394253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1395253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1396253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1397253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1398253772Savg
1399253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1400253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1401253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1402253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1403253772Savg
1404253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1405253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1406253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1407253772Savg/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1408253772Savg
1409253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1410253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1411253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1412253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1413253772Savg
1414253772Savg/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1415253772Savg/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1416253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1417253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1418253772Savg
1419253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1420253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1421253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1422253772Savg/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaeskeygenassist",VEX_MXI,16),
1423253772Savg
1424253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1425253772Savg/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1426253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1427253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1428253772Savg
1429253772Savg/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1430253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1431253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1432253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1433253772Savg};
1434253772Savg
1435253772Savg/*
1436179237Sjb *	Decode table for 0x0F opcodes
1437179237Sjb */
1438179237Sjb
1439179237Sjbconst instable_t dis_op0F[16][16] = {
1440179237Sjb{
1441179237Sjb/*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
1442179237Sjb/*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
1443179237Sjb/*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
1444179237Sjb/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1445179237Sjb}, {
1446179237Sjb/*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
1447179237Sjb/*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
1448179237Sjb/*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
1449238169Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		TS("nopw", Mw),
1450179237Sjb}, {
1451179237Sjb/*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
1452179237Sjb/*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
1453179237Sjb/*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
1454179237Sjb/*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
1455179237Sjb}, {
1456179237Sjb/*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
1457179237Sjb/*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
1458179237Sjb/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1459179237Sjb/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1460179237Sjb}, {
1461179237Sjb/*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
1462179237Sjb/*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
1463179237Sjb/*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
1464179237Sjb/*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
1465179237Sjb}, {
1466179237Sjb/*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
1467179237Sjb/*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
1468179237Sjb/*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
1469179237Sjb/*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
1470179237Sjb}, {
1471179237Sjb/*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
1472179237Sjb/*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
1473179237Sjb/*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
1474179237Sjb/*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
1475179237Sjb}, {
1476179237Sjb/*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
1477179237Sjb/*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
1478253772Savg/*  [78]  */	TNS("INVALID",XMMO),	TNS("INVALID",XMMO),	INVALID,		INVALID,
1479179237Sjb/*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
1480179237Sjb}, {
1481179237Sjb/*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
1482179237Sjb/*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
1483179237Sjb/*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
1484179237Sjb/*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
1485179237Sjb}, {
1486179237Sjb/*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
1487179237Sjb/*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
1488179237Sjb/*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
1489179237Sjb/*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
1490179237Sjb}, {
1491179237Sjb/*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
1492179237Sjb/*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
1493179237Sjb/*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
1494179237Sjb/*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
1495179237Sjb}, {
1496179237Sjb/*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
1497179237Sjb/*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
1498253772Savg/*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
1499179237Sjb/*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
1500179237Sjb}, {
1501179237Sjb/*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
1502179237Sjb/*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
1503179237Sjb/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1504179237Sjb/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1505179237Sjb}, {
1506179237Sjb/*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
1507179237Sjb/*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
1508179237Sjb/*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
1509179237Sjb/*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
1510179237Sjb}, {
1511179237Sjb/*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
1512179237Sjb/*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
1513179237Sjb/*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
1514179237Sjb/*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
1515179237Sjb}, {
1516179237Sjb/*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
1517179237Sjb/*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
1518179237Sjb/*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
1519179237Sjb/*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
1520179237Sjb} };
1521179237Sjb
1522253772Savgconst instable_t dis_opAVX0F[16][16] = {
1523253772Savg{
1524253772Savg/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1525253772Savg/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1526253772Savg/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1527253772Savg/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1528253772Savg}, {
1529253772Savg/*  [10]  */	TNSZ("vmovups",VEX_MX,16),	TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),	TNSZ("vmovlps",VEX_RM,8),
1530253772Savg/*  [14]  */	TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
1531253772Savg/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1532253772Savg/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1533253772Savg}, {
1534253772Savg/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1535253772Savg/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1536253772Savg/*  [28]  */	TNSZ("vmovaps",VEX_MX,16),	TNSZ("vmovaps",VEX_RX,16),INVALID,		TNSZ("vmovntps",VEX_RM,16),
1537253772Savg/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
1538253772Savg}, {
1539253772Savg/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1540253772Savg/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1541253772Savg/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1542253772Savg/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1543253772Savg}, {
1544253772Savg/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1545253772Savg/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1546253772Savg/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1547253772Savg/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1548253772Savg}, {
1549253772Savg/*  [50]  */	TNS("vmovmskps",VEX_MR),	TNSZ("vsqrtps",VEX_MX,16),	TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
1550253772Savg/*  [54]  */	TNSZ("vandps",VEX_RMrX,16),	TNSZ("vandnps",VEX_RMrX,16),	TNSZ("vorps",VEX_RMrX,16),	TNSZ("vxorps",VEX_RMrX,16),
1551253772Savg/*  [58]  */	TNSZ("vaddps",VEX_RMrX,16),	TNSZ("vmulps",VEX_RMrX,16),	TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
1552253772Savg/*  [5C]  */	TNSZ("vsubps",VEX_RMrX,16),	TNSZ("vminps",VEX_RMrX,16),	TNSZ("vdivps",VEX_RMrX,16),	TNSZ("vmaxps",VEX_RMrX,16),
1553253772Savg}, {
1554253772Savg/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1555253772Savg/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1556253772Savg/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1557253772Savg/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1558253772Savg}, {
1559253772Savg/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1560253772Savg/*  [74]  */	INVALID,		INVALID,		INVALID,		TNS("vzeroupper", VEX_NONE),
1561253772Savg/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1562253772Savg/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1563253772Savg}, {
1564253772Savg/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1565253772Savg/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1566253772Savg/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1567253772Savg/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1568253772Savg}, {
1569253772Savg/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1570253772Savg/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1571253772Savg/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1572253772Savg/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1573253772Savg}, {
1574253772Savg/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1575253772Savg/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1576253772Savg/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1577253772Savg/*  [AC]  */	INVALID,		INVALID,		TNSZ("vldmxcsr",VEX_MO,2),		INVALID,
1578253772Savg}, {
1579253772Savg/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1580253772Savg/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1581253772Savg/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1582253772Savg/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1583253772Savg}, {
1584253772Savg/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpps",VEX_RMRX,16),INVALID,
1585253772Savg/*  [C4]  */	INVALID,		INVALID,	 	TNSZ("vshufps",VEX_RMRX,16),INVALID,
1586253772Savg/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1587253772Savg/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1588253772Savg}, {
1589253772Savg/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1590253772Savg/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1591253772Savg/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1592253772Savg/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1593253772Savg}, {
1594253772Savg/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1595253772Savg/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1596253772Savg/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1597253772Savg/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1598253772Savg}, {
1599253772Savg/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1600253772Savg/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1601253772Savg/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1602253772Savg/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1603253772Savg} };
1604179237Sjb
1605179237Sjb/*
1606179237Sjb *	Decode table for 0x80 opcodes
1607179237Sjb */
1608179237Sjb
1609179237Sjbconst instable_t dis_op80[8] = {
1610179237Sjb
1611179237Sjb/*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
1612179237Sjb/*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
1613179237Sjb};
1614179237Sjb
1615179237Sjb
1616179237Sjb/*
1617179237Sjb *	Decode table for 0x81 opcodes.
1618179237Sjb */
1619179237Sjb
1620179237Sjbconst instable_t dis_op81[8] = {
1621179237Sjb
1622179237Sjb/*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
1623179237Sjb/*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
1624179237Sjb};
1625179237Sjb
1626179237Sjb
1627179237Sjb/*
1628179237Sjb *	Decode table for 0x82 opcodes.
1629179237Sjb */
1630179237Sjb
1631179237Sjbconst instable_t dis_op82[8] = {
1632179237Sjb
1633179237Sjb/*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
1634179237Sjb/*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
1635179237Sjb};
1636179237Sjb/*
1637179237Sjb *	Decode table for 0x83 opcodes.
1638179237Sjb */
1639179237Sjb
1640179237Sjbconst instable_t dis_op83[8] = {
1641179237Sjb
1642179237Sjb/*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
1643179237Sjb/*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
1644179237Sjb};
1645179237Sjb
1646179237Sjb/*
1647179237Sjb *	Decode table for 0xC0 opcodes.
1648179237Sjb */
1649179237Sjb
1650179237Sjbconst instable_t dis_opC0[8] = {
1651179237Sjb
1652179237Sjb/*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
1653179237Sjb/*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
1654179237Sjb};
1655179237Sjb
1656179237Sjb/*
1657179237Sjb *	Decode table for 0xD0 opcodes.
1658179237Sjb */
1659179237Sjb
1660179237Sjbconst instable_t dis_opD0[8] = {
1661179237Sjb
1662179237Sjb/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
1663179237Sjb/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
1664179237Sjb};
1665179237Sjb
1666179237Sjb/*
1667179237Sjb *	Decode table for 0xC1 opcodes.
1668179237Sjb *	186 instruction set
1669179237Sjb */
1670179237Sjb
1671179237Sjbconst instable_t dis_opC1[8] = {
1672179237Sjb
1673179237Sjb/*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
1674179237Sjb/*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
1675179237Sjb};
1676179237Sjb
1677179237Sjb/*
1678179237Sjb *	Decode table for 0xD1 opcodes.
1679179237Sjb */
1680179237Sjb
1681179237Sjbconst instable_t dis_opD1[8] = {
1682179237Sjb
1683179237Sjb/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
1684179237Sjb/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
1685179237Sjb};
1686179237Sjb
1687179237Sjb
1688179237Sjb/*
1689179237Sjb *	Decode table for 0xD2 opcodes.
1690179237Sjb */
1691179237Sjb
1692179237Sjbconst instable_t dis_opD2[8] = {
1693179237Sjb
1694179237Sjb/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
1695179237Sjb/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
1696179237Sjb};
1697179237Sjb/*
1698179237Sjb *	Decode table for 0xD3 opcodes.
1699179237Sjb */
1700179237Sjb
1701179237Sjbconst instable_t dis_opD3[8] = {
1702179237Sjb
1703179237Sjb/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
1704179237Sjb/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
1705179237Sjb};
1706179237Sjb
1707179237Sjb
1708179237Sjb/*
1709179237Sjb *	Decode table for 0xF6 opcodes.
1710179237Sjb */
1711179237Sjb
1712179237Sjbconst instable_t dis_opF6[8] = {
1713179237Sjb
1714179237Sjb/*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
1715179237Sjb/*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
1716179237Sjb};
1717179237Sjb
1718179237Sjb
1719179237Sjb/*
1720179237Sjb *	Decode table for 0xF7 opcodes.
1721179237Sjb */
1722179237Sjb
1723179237Sjbconst instable_t dis_opF7[8] = {
1724179237Sjb
1725179237Sjb/*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
1726179237Sjb/*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
1727179237Sjb};
1728179237Sjb
1729179237Sjb
1730179237Sjb/*
1731179237Sjb *	Decode table for 0xFE opcodes.
1732179237Sjb */
1733179237Sjb
1734179237Sjbconst instable_t dis_opFE[8] = {
1735179237Sjb
1736179237Sjb/*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
1737179237Sjb/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1738179237Sjb};
1739179237Sjb/*
1740179237Sjb *	Decode table for 0xFF opcodes.
1741179237Sjb */
1742179237Sjb
1743179237Sjbconst instable_t dis_opFF[8] = {
1744179237Sjb
1745179237Sjb/*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
1746179237Sjb/*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
1747179237Sjb};
1748179237Sjb
1749179237Sjb/* for 287 instructions, which are a mess to decode */
1750179237Sjb
1751179237Sjbconst instable_t dis_opFP1n2[8][8] = {
1752179237Sjb{
1753179237Sjb/* bit pattern:	1101 1xxx MODxx xR/M */
1754179237Sjb/*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
1755179237Sjb/*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
1756179237Sjb}, {
1757179237Sjb/*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
1758179237Sjb/*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
1759179237Sjb}, {
1760179237Sjb/*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
1761179237Sjb/*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
1762179237Sjb}, {
1763179237Sjb/*  [3,0]  */	TNS("fildl",M),		INVALID,		TNS("fistl",M),		TNS("fistpl",M),
1764179237Sjb/*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
1765179237Sjb}, {
1766179237Sjb/*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
1767179237Sjb/*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
1768179237Sjb}, {
1769179237Sjb/*  [5,0]  */	TNSZ("fldl",M,8),	INVALID,		TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
1770179237Sjb/*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
1771179237Sjb}, {
1772179237Sjb/*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
1773179237Sjb/*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
1774179237Sjb}, {
1775179237Sjb/*  [7,0]  */	TNSZ("fild",M,2),	INVALID,		TNSZ("fist",M,2),	TNSZ("fistp",M,2),
1776179237Sjb/*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
1777179237Sjb} };
1778179237Sjb
1779179237Sjbconst instable_t dis_opFP3[8][8] = {
1780179237Sjb{
1781179237Sjb/* bit  pattern:	1101 1xxx 11xx xREG */
1782179237Sjb/*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
1783179237Sjb/*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
1784179237Sjb}, {
1785179237Sjb/*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
1786179237Sjb/*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1787179237Sjb}, {
1788179237Sjb/*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1789179237Sjb/*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
1790179237Sjb}, {
1791179237Sjb/*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1792179237Sjb/*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1793179237Sjb}, {
1794179237Sjb/*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
1795179237Sjb/*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
1796179237Sjb}, {
1797179237Sjb/*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
1798179237Sjb/*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
1799179237Sjb}, {
1800179237Sjb/*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
1801179237Sjb/*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
1802179237Sjb}, {
1803253772Savg/*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
1804179237Sjb/*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
1805179237Sjb} };
1806179237Sjb
1807179237Sjbconst instable_t dis_opFP4[4][8] = {
1808179237Sjb{
1809179237Sjb/* bit pattern:	1101 1001 111x xxxx */
1810179237Sjb/*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
1811179237Sjb/*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
1812179237Sjb}, {
1813179237Sjb/*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
1814179237Sjb/*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
1815179237Sjb}, {
1816179237Sjb/*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
1817179237Sjb/*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
1818179237Sjb}, {
1819179237Sjb/*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
1820179237Sjb/*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
1821179237Sjb} };
1822179237Sjb
1823179237Sjbconst instable_t dis_opFP5[8] = {
1824179237Sjb/* bit pattern:	1101 1011 111x xxxx */
1825179237Sjb/*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
1826179237Sjb/*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
1827179237Sjb};
1828179237Sjb
1829179237Sjbconst instable_t dis_opFP6[8] = {
1830179237Sjb/* bit pattern:	1101 1011 11yy yxxx */
1831179237Sjb/*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
1832179237Sjb/*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
1833179237Sjb};
1834179237Sjb
1835179237Sjbconst instable_t dis_opFP7[8] = {
1836179237Sjb/* bit pattern:	1101 1010 11yy yxxx */
1837179237Sjb/*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
1838179237Sjb/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1839179237Sjb};
1840179237Sjb
1841179237Sjb/*
1842179237Sjb *	Main decode table for the op codes.  The first two nibbles
1843179237Sjb *	will be used as an index into the table.  If there is a
1844179237Sjb *	a need to further decode an instruction, the array to be
1845179237Sjb *	referenced is indicated with the other two entries being
1846179237Sjb *	empty.
1847179237Sjb */
1848179237Sjb
1849179237Sjbconst instable_t dis_distable[16][16] = {
1850179237Sjb{
1851179237Sjb/* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
1852179237Sjb/* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
1853179237Sjb/* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
1854253772Savg/* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
1855179237Sjb}, {
1856179237Sjb/* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
1857179237Sjb/* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
1858179237Sjb/* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
1859179237Sjb/* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
1860179237Sjb}, {
1861179237Sjb/* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
1862238168Savg/* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNS("%es:",OVERRIDE),	TNSx("daa",NORM),
1863179237Sjb/* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
1864238168Savg/* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNS("%cs:",OVERRIDE),	TNSx("das",NORM),
1865179237Sjb}, {
1866179237Sjb/* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
1867238168Savg/* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNS("%ss:",OVERRIDE),	TNSx("aaa",NORM),
1868179237Sjb/* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
1869238168Savg/* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNS("%ds:",OVERRIDE),	TNSx("aas",NORM),
1870179237Sjb}, {
1871179237Sjb/* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
1872179237Sjb/* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
1873179237Sjb/* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
1874179237Sjb/* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
1875179237Sjb}, {
1876179237Sjb/* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
1877179237Sjb/* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
1878179237Sjb/* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
1879179237Sjb/* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
1880179237Sjb}, {
1881179237Sjb/* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
1882179237Sjb/* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
1883179237Sjb/* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
1884179237Sjb/* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
1885179237Sjb}, {
1886179237Sjb/* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
1887179237Sjb/* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
1888179237Sjb/* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
1889179237Sjb/* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
1890179237Sjb}, {
1891179237Sjb/* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
1892179237Sjb/* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
1893179237Sjb/* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
1894179237Sjb/* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
1895179237Sjb}, {
1896179237Sjb/* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
1897179237Sjb/* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
1898179237Sjb/* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
1899179237Sjb/* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNSx("sahf",NORM),	TNSx("lahf",NORM),
1900179237Sjb}, {
1901179237Sjb/* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
1902179237Sjb/* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
1903179237Sjb/* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
1904179237Sjb/* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
1905179237Sjb}, {
1906179237Sjb/* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
1907179237Sjb/* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
1908179237Sjb/* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
1909179237Sjb/* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
1910179237Sjb}, {
1911179237Sjb/* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
1912179237Sjb/* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
1913179237Sjb/* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
1914179237Sjb/* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
1915179237Sjb}, {
1916179237Sjb/* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
1917179237Sjb/* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
1918179237Sjb
1919179237Sjb/* 287 instructions.  Note that although the indirect field		*/
1920179237Sjb/* indicates opFP1n2 for further decoding, this is not necessarily	*/
1921179237Sjb/* the case since the opFP arrays are not partitioned according to key1	*/
1922179237Sjb/* and key2.  opFP1n2 is given only to indicate that we haven't		*/
1923179237Sjb/* finished decoding the instruction.					*/
1924253772Savg/* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
1925253772Savg/* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
1926179237Sjb}, {
1927179237Sjb/* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
1928179237Sjb/* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
1929179237Sjb/* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
1930179237Sjb/* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
1931179237Sjb}, {
1932179237Sjb/* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
1933179237Sjb/* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
1934179237Sjb/* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
1935179237Sjb/* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
1936179237Sjb} };
1937179237Sjb
1938179237Sjb/* END CSTYLED */
1939179237Sjb
1940179237Sjb/*
1941179237Sjb * common functions to decode and disassemble an x86 or amd64 instruction
1942179237Sjb */
1943179237Sjb
1944179237Sjb/*
1945179237Sjb * These are the individual fields of a REX prefix. Note that a REX
1946179237Sjb * prefix with none of these set is still needed to:
1947179237Sjb *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
1948179237Sjb *	- access the %sil, %dil, %bpl, %spl registers
1949179237Sjb */
1950179237Sjb#define	REX_W 0x08	/* 64 bit operand size when set */
1951179237Sjb#define	REX_R 0x04	/* high order bit extension of ModRM reg field */
1952179237Sjb#define	REX_X 0x02	/* high order bit extension of SIB index field */
1953179237Sjb#define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
1954179237Sjb
1955253772Savg/*
1956253772Savg * These are the individual fields of a VEX prefix.
1957253772Savg */
1958253772Savg#define	VEX_R 0x08	/* REX.R in 1's complement form */
1959253772Savg#define	VEX_X 0x04	/* REX.X in 1's complement form */
1960253772Savg#define	VEX_B 0x02	/* REX.B in 1's complement form */
1961253772Savg/* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
1962253772Savg#define	VEX_L 0x04
1963253772Savg#define	VEX_W 0x08	/* opcode specific, use like REX.W */
1964253772Savg#define	VEX_m 0x1F	/* VEX m-mmmm field */
1965253772Savg#define	VEX_v 0x78	/* VEX register specifier */
1966253772Savg#define	VEX_p 0x03	/* VEX pp field, opcode extension */
1967179237Sjb
1968253772Savg/* VEX m-mmmm field, only used by three bytes prefix */
1969253772Savg#define	VEX_m_0F 0x01   /* implied 0F leading opcode byte */
1970253772Savg#define	VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
1971253772Savg#define	VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
1972253772Savg
1973253772Savg/* VEX pp field, providing equivalent functionality of a SIMD prefix */
1974253772Savg#define	VEX_p_66 0x01
1975253772Savg#define	VEX_p_F3 0x02
1976253772Savg#define	VEX_p_F2 0x03
1977253772Savg
1978179237Sjb/*
1979179237Sjb * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
1980179237Sjb */
1981179237Sjbstatic int isize[] = {1, 2, 4, 4};
1982179237Sjbstatic int isize64[] = {1, 2, 4, 8};
1983179237Sjb
1984179237Sjb/*
1985179237Sjb * Just a bunch of useful macros.
1986179237Sjb */
1987179237Sjb#define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
1988179237Sjb#define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
1989179237Sjb#define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
1990179237Sjb#define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
1991179237Sjb#define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
1992179237Sjb
1993179237Sjb#define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
1994179237Sjb
1995179237Sjb#define	BYTE_OPND	0	/* w-bit value indicating byte register */
1996179237Sjb#define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
1997179237Sjb#define	MM_OPND		2	/* "value" used to indicate a mmx reg */
1998179237Sjb#define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
1999179237Sjb#define	SEG_OPND	4	/* "value" used to indicate a segment reg */
2000179237Sjb#define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
2001179237Sjb#define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
2002179237Sjb#define	TEST_OPND	7	/* "value" used to indicate a test reg */
2003179237Sjb#define	WORD_OPND	8	/* w-bit value indicating word size reg */
2004253772Savg#define	YMM_OPND	9	/* "value" used to indicate a ymm reg */
2005179237Sjb
2006179237Sjb/*
2007179237Sjb * Get the next byte and separate the op code into the high and low nibbles.
2008179237Sjb */
2009179237Sjbstatic int
2010179237Sjbdtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
2011179237Sjb{
2012179237Sjb	int byte;
2013179237Sjb
2014179237Sjb	/*
2015179237Sjb	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
2016179237Sjb	 * we try to read more.
2017179237Sjb	 */
2018179237Sjb	if (x->d86_len >= 15)
2019179237Sjb		return (x->d86_error = 1);
2020179237Sjb
2021179237Sjb	if (x->d86_error)
2022179237Sjb		return (1);
2023179237Sjb	byte = x->d86_get_byte(x->d86_data);
2024179237Sjb	if (byte < 0)
2025179237Sjb		return (x->d86_error = 1);
2026179237Sjb	x->d86_bytes[x->d86_len++] = byte;
2027179237Sjb	*low = byte & 0xf;		/* ----xxxx low 4 bits */
2028179237Sjb	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
2029179237Sjb	return (0);
2030179237Sjb}
2031179237Sjb
2032179237Sjb/*
2033179237Sjb * Get and decode an SIB (scaled index base) byte
2034179237Sjb */
2035179237Sjbstatic void
2036179237Sjbdtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
2037179237Sjb{
2038179237Sjb	int byte;
2039179237Sjb
2040179237Sjb	if (x->d86_error)
2041179237Sjb		return;
2042179237Sjb
2043179237Sjb	byte = x->d86_get_byte(x->d86_data);
2044179237Sjb	if (byte < 0) {
2045179237Sjb		x->d86_error = 1;
2046179237Sjb		return;
2047179237Sjb	}
2048179237Sjb	x->d86_bytes[x->d86_len++] = byte;
2049179237Sjb
2050179237Sjb	*base = byte & 0x7;
2051179237Sjb	*index = (byte >> 3) & 0x7;
2052179237Sjb	*ss = (byte >> 6) & 0x3;
2053179237Sjb}
2054179237Sjb
2055179237Sjb/*
2056179237Sjb * Get the byte following the op code and separate it into the
2057179237Sjb * mode, register, and r/m fields.
2058179237Sjb */
2059179237Sjbstatic void
2060179237Sjbdtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
2061179237Sjb{
2062179237Sjb	if (x->d86_got_modrm == 0) {
2063179237Sjb		if (x->d86_rmindex == -1)
2064179237Sjb			x->d86_rmindex = x->d86_len;
2065179237Sjb		dtrace_get_SIB(x, mode, reg, r_m);
2066179237Sjb		x->d86_got_modrm = 1;
2067179237Sjb	}
2068179237Sjb}
2069179237Sjb
2070179237Sjb/*
2071179237Sjb * Adjust register selection based on any REX prefix bits present.
2072179237Sjb */
2073179237Sjb/*ARGSUSED*/
2074179237Sjbstatic void
2075179237Sjbdtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
2076179237Sjb{
2077179237Sjb	if (reg != NULL && r_m == NULL) {
2078179237Sjb		if (rex_prefix & REX_B)
2079179237Sjb			*reg += 8;
2080179237Sjb	} else {
2081179237Sjb		if (reg != NULL && (REX_R & rex_prefix) != 0)
2082179237Sjb			*reg += 8;
2083179237Sjb		if (r_m != NULL && (REX_B & rex_prefix) != 0)
2084179237Sjb			*r_m += 8;
2085179237Sjb	}
2086179237Sjb}
2087179237Sjb
2088179237Sjb/*
2089253772Savg * Adjust register selection based on any VEX prefix bits present.
2090253772Savg * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
2091253772Savg */
2092253772Savg/*ARGSUSED*/
2093253772Savgstatic void
2094253772Savgdtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
2095253772Savg{
2096253772Savg	if (reg != NULL && r_m == NULL) {
2097253772Savg		if (!(vex_byte1 & VEX_B))
2098253772Savg			*reg += 8;
2099253772Savg	} else {
2100253772Savg		if (reg != NULL && ((VEX_R & vex_byte1) == 0))
2101253772Savg			*reg += 8;
2102253772Savg		if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
2103253772Savg			*r_m += 8;
2104253772Savg	}
2105253772Savg}
2106253772Savg
2107253772Savg/*
2108179237Sjb * Get an immediate operand of the given size, with sign extension.
2109179237Sjb */
2110179237Sjbstatic void
2111179237Sjbdtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
2112179237Sjb{
2113179237Sjb	int i;
2114179237Sjb	int byte;
2115253772Savg	int valsize;
2116179237Sjb
2117179237Sjb	if (x->d86_numopnds < opindex + 1)
2118179237Sjb		x->d86_numopnds = opindex + 1;
2119179237Sjb
2120179237Sjb	switch (wbit) {
2121179237Sjb	case BYTE_OPND:
2122179237Sjb		valsize = 1;
2123179237Sjb		break;
2124179237Sjb	case LONG_OPND:
2125179237Sjb		if (x->d86_opnd_size == SIZE16)
2126179237Sjb			valsize = 2;
2127179237Sjb		else if (x->d86_opnd_size == SIZE32)
2128179237Sjb			valsize = 4;
2129179237Sjb		else
2130179237Sjb			valsize = 8;
2131179237Sjb		break;
2132179237Sjb	case MM_OPND:
2133179237Sjb	case XMM_OPND:
2134253772Savg	case YMM_OPND:
2135179237Sjb	case SEG_OPND:
2136179237Sjb	case CONTROL_OPND:
2137179237Sjb	case DEBUG_OPND:
2138179237Sjb	case TEST_OPND:
2139179237Sjb		valsize = size;
2140179237Sjb		break;
2141179237Sjb	case WORD_OPND:
2142179237Sjb		valsize = 2;
2143179237Sjb		break;
2144179237Sjb	}
2145179237Sjb	if (valsize < size)
2146179237Sjb		valsize = size;
2147179237Sjb
2148179237Sjb	if (x->d86_error)
2149179237Sjb		return;
2150179237Sjb	x->d86_opnd[opindex].d86_value = 0;
2151179237Sjb	for (i = 0; i < size; ++i) {
2152179237Sjb		byte = x->d86_get_byte(x->d86_data);
2153179237Sjb		if (byte < 0) {
2154179237Sjb			x->d86_error = 1;
2155179237Sjb			return;
2156179237Sjb		}
2157179237Sjb		x->d86_bytes[x->d86_len++] = byte;
2158179237Sjb		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
2159179237Sjb	}
2160179237Sjb	/* Do sign extension */
2161179237Sjb	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
2162253772Savg		for (; i < sizeof (uint64_t); i++)
2163179237Sjb			x->d86_opnd[opindex].d86_value |=
2164253772Savg			    (uint64_t)0xff << (i * 8);
2165179237Sjb	}
2166179237Sjb#ifdef DIS_TEXT
2167179237Sjb	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2168179237Sjb	x->d86_opnd[opindex].d86_value_size = valsize;
2169179237Sjb	x->d86_imm_bytes += size;
2170179237Sjb#endif
2171179237Sjb}
2172179237Sjb
2173179237Sjb/*
2174179237Sjb * Get an ip relative operand of the given size, with sign extension.
2175179237Sjb */
2176179237Sjbstatic void
2177179237Sjbdtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
2178179237Sjb{
2179179237Sjb	dtrace_imm_opnd(x, wbit, size, opindex);
2180179237Sjb#ifdef DIS_TEXT
2181179237Sjb	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
2182179237Sjb#endif
2183179237Sjb}
2184179237Sjb
2185179237Sjb/*
2186179237Sjb * Check to see if there is a segment override prefix pending.
2187179237Sjb * If so, print it in the current 'operand' location and set
2188179237Sjb * the override flag back to false.
2189179237Sjb */
2190179237Sjb/*ARGSUSED*/
2191179237Sjbstatic void
2192179237Sjbdtrace_check_override(dis86_t *x, int opindex)
2193179237Sjb{
2194179237Sjb#ifdef DIS_TEXT
2195179237Sjb	if (x->d86_seg_prefix) {
2196179237Sjb		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
2197179237Sjb		    x->d86_seg_prefix, PFIXLEN);
2198179237Sjb	}
2199179237Sjb#endif
2200179237Sjb	x->d86_seg_prefix = NULL;
2201179237Sjb}
2202179237Sjb
2203179237Sjb
2204179237Sjb/*
2205179237Sjb * Process a single instruction Register or Memory operand.
2206179237Sjb *
2207179237Sjb * mode = addressing mode from ModRM byte
2208179237Sjb * r_m = r_m (or reg if mode == 3) field from ModRM byte
2209179237Sjb * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
2210179237Sjb * o = index of operand that we are processing (0, 1 or 2)
2211179237Sjb *
2212179237Sjb * the value of reg or r_m must have already been adjusted for any REX prefix.
2213179237Sjb */
2214179237Sjb/*ARGSUSED*/
2215179237Sjbstatic void
2216179237Sjbdtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
2217179237Sjb{
2218179237Sjb	int have_SIB = 0;	/* flag presence of scale-index-byte */
2219179237Sjb	uint_t ss;		/* scale-factor from opcode */
2220179237Sjb	uint_t index;		/* index register number */
2221179237Sjb	uint_t base;		/* base register number */
2222179237Sjb	int dispsize;   	/* size of displacement in bytes */
2223179237Sjb#ifdef DIS_TEXT
2224179237Sjb	char *opnd = x->d86_opnd[opindex].d86_opnd;
2225179237Sjb#endif
2226179237Sjb
2227179237Sjb	if (x->d86_numopnds < opindex + 1)
2228179237Sjb		x->d86_numopnds = opindex + 1;
2229179237Sjb
2230179237Sjb	if (x->d86_error)
2231179237Sjb		return;
2232179237Sjb
2233179237Sjb	/*
2234179237Sjb	 * first handle a simple register
2235179237Sjb	 */
2236179237Sjb	if (mode == REG_ONLY) {
2237179237Sjb#ifdef DIS_TEXT
2238179237Sjb		switch (wbit) {
2239179237Sjb		case MM_OPND:
2240179237Sjb			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
2241179237Sjb			break;
2242179237Sjb		case XMM_OPND:
2243179237Sjb			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
2244179237Sjb			break;
2245253772Savg		case YMM_OPND:
2246253772Savg			(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
2247253772Savg			break;
2248179237Sjb		case SEG_OPND:
2249179237Sjb			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
2250179237Sjb			break;
2251179237Sjb		case CONTROL_OPND:
2252179237Sjb			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
2253179237Sjb			break;
2254179237Sjb		case DEBUG_OPND:
2255179237Sjb			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
2256179237Sjb			break;
2257179237Sjb		case TEST_OPND:
2258179237Sjb			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
2259179237Sjb			break;
2260179237Sjb		case BYTE_OPND:
2261179237Sjb			if (x->d86_rex_prefix == 0)
2262179237Sjb				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
2263179237Sjb			else
2264179237Sjb				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
2265179237Sjb			break;
2266179237Sjb		case WORD_OPND:
2267179237Sjb			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2268179237Sjb			break;
2269179237Sjb		case LONG_OPND:
2270179237Sjb			if (x->d86_opnd_size == SIZE16)
2271179237Sjb				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2272179237Sjb			else if (x->d86_opnd_size == SIZE32)
2273179237Sjb				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
2274179237Sjb			else
2275179237Sjb				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
2276179237Sjb			break;
2277179237Sjb		}
2278179237Sjb#endif /* DIS_TEXT */
2279179237Sjb		return;
2280179237Sjb	}
2281179237Sjb
2282179237Sjb	/*
2283179237Sjb	 * if symbolic representation, skip override prefix, if any
2284179237Sjb	 */
2285179237Sjb	dtrace_check_override(x, opindex);
2286179237Sjb
2287179237Sjb	/*
2288179237Sjb	 * Handle 16 bit memory references first, since they decode
2289179237Sjb	 * the mode values more simply.
2290179237Sjb	 * mode 1 is r_m + 8 bit displacement
2291179237Sjb	 * mode 2 is r_m + 16 bit displacement
2292179237Sjb	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
2293179237Sjb	 */
2294179237Sjb	if (x->d86_addr_size == SIZE16) {
2295179237Sjb		if ((mode == 0 && r_m == 6) || mode == 2)
2296179237Sjb			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
2297179237Sjb		else if (mode == 1)
2298179237Sjb			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
2299179237Sjb#ifdef DIS_TEXT
2300179237Sjb		if (mode == 0 && r_m == 6)
2301179237Sjb			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2302179237Sjb		else if (mode == 0)
2303179237Sjb			x->d86_opnd[opindex].d86_mode = MODE_NONE;
2304179237Sjb		else
2305179237Sjb			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2306179237Sjb		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
2307179237Sjb#endif
2308179237Sjb		return;
2309179237Sjb	}
2310179237Sjb
2311179237Sjb	/*
2312179237Sjb	 * 32 and 64 bit addressing modes are more complex since they
2313179237Sjb	 * can involve an SIB (scaled index and base) byte to decode.
2314179237Sjb	 */
2315179237Sjb	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
2316179237Sjb		have_SIB = 1;
2317179237Sjb		dtrace_get_SIB(x, &ss, &index, &base);
2318179237Sjb		if (x->d86_error)
2319179237Sjb			return;
2320179237Sjb		if (base != 5 || mode != 0)
2321179237Sjb			if (x->d86_rex_prefix & REX_B)
2322179237Sjb				base += 8;
2323179237Sjb		if (x->d86_rex_prefix & REX_X)
2324179237Sjb			index += 8;
2325179237Sjb	} else {
2326179237Sjb		base = r_m;
2327179237Sjb	}
2328179237Sjb
2329179237Sjb	/*
2330179237Sjb	 * Compute the displacement size and get its bytes
2331179237Sjb	 */
2332179237Sjb	dispsize = 0;
2333179237Sjb
2334179237Sjb	if (mode == 1)
2335179237Sjb		dispsize = 1;
2336179237Sjb	else if (mode == 2)
2337179237Sjb		dispsize = 4;
2338179237Sjb	else if ((r_m & 7) == EBP_REGNO ||
2339179237Sjb	    (have_SIB && (base & 7) == EBP_REGNO))
2340179237Sjb		dispsize = 4;
2341179237Sjb
2342179237Sjb	if (dispsize > 0) {
2343179237Sjb		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
2344179237Sjb		    dispsize, opindex);
2345179237Sjb		if (x->d86_error)
2346179237Sjb			return;
2347179237Sjb	}
2348179237Sjb
2349179237Sjb#ifdef DIS_TEXT
2350179237Sjb	if (dispsize > 0)
2351179237Sjb		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2352179237Sjb
2353179237Sjb	if (have_SIB == 0) {
2354179237Sjb		if (x->d86_mode == SIZE32) {
2355179237Sjb			if (mode == 0)
2356179237Sjb				(void) strlcat(opnd, dis_addr32_mode0[r_m],
2357179237Sjb				    OPLEN);
2358179237Sjb			else
2359179237Sjb				(void) strlcat(opnd, dis_addr32_mode12[r_m],
2360179237Sjb				    OPLEN);
2361179237Sjb		} else {
2362253772Savg			if (mode == 0) {
2363179237Sjb				(void) strlcat(opnd, dis_addr64_mode0[r_m],
2364179237Sjb				    OPLEN);
2365253772Savg				if (r_m == 5) {
2366253772Savg					x->d86_opnd[opindex].d86_mode =
2367253772Savg					    MODE_RIPREL;
2368253772Savg				}
2369253772Savg			} else {
2370179237Sjb				(void) strlcat(opnd, dis_addr64_mode12[r_m],
2371179237Sjb				    OPLEN);
2372253772Savg			}
2373179237Sjb		}
2374179237Sjb	} else {
2375179237Sjb		uint_t need_paren = 0;
2376179237Sjb		char **regs;
2377179237Sjb		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
2378179237Sjb			regs = (char **)dis_REG32;
2379179237Sjb		else
2380179237Sjb			regs = (char **)dis_REG64;
2381179237Sjb
2382179237Sjb		/*
2383179237Sjb		 * print the base (if any)
2384179237Sjb		 */
2385179237Sjb		if (base == EBP_REGNO && mode == 0) {
2386179237Sjb			if (index != ESP_REGNO) {
2387179237Sjb				(void) strlcat(opnd, "(", OPLEN);
2388179237Sjb				need_paren = 1;
2389179237Sjb			}
2390179237Sjb		} else {
2391179237Sjb			(void) strlcat(opnd, "(", OPLEN);
2392179237Sjb			(void) strlcat(opnd, regs[base], OPLEN);
2393179237Sjb			need_paren = 1;
2394179237Sjb		}
2395179237Sjb
2396179237Sjb		/*
2397179237Sjb		 * print the index (if any)
2398179237Sjb		 */
2399179237Sjb		if (index != ESP_REGNO) {
2400179237Sjb			(void) strlcat(opnd, ",", OPLEN);
2401179237Sjb			(void) strlcat(opnd, regs[index], OPLEN);
2402179237Sjb			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
2403179237Sjb		} else
2404179237Sjb			if (need_paren)
2405179237Sjb				(void) strlcat(opnd, ")", OPLEN);
2406179237Sjb	}
2407179237Sjb#endif
2408179237Sjb}
2409179237Sjb
2410179237Sjb/*
2411179237Sjb * Operand sequence for standard instruction involving one register
2412179237Sjb * and one register/memory operand.
2413179237Sjb * wbit indicates a byte(0) or opnd_size(1) operation
2414179237Sjb * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
2415179237Sjb */
2416179237Sjb#define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
2417179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2418179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2419179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2420179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
2421179237Sjb}
2422179237Sjb
2423179237Sjb/*
2424179237Sjb * Similar to above, but allows for the two operands to be of different
2425179237Sjb * classes (ie. wbit).
2426179237Sjb *	wbit is for the r_m operand
2427179237Sjb *	w2 is for the reg operand
2428179237Sjb */
2429179237Sjb#define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
2430179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2431179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2432179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2433179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
2434179237Sjb}
2435179237Sjb
2436179237Sjb/*
2437179237Sjb * Similar, but for 2 operands plus an immediate.
2438253772Savg * vbit indicates direction
2439253772Savg * 	0 for "opcode imm, r, r_m" or
2440253772Savg *	1 for "opcode imm, r_m, r"
2441179237Sjb */
2442253772Savg#define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
2443179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2444179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2445253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
2446253772Savg		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
2447179237Sjb		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2448179237Sjb}
2449179237Sjb
2450179237Sjb/*
2451253772Savg * Similar, but for 2 operands plus two immediates.
2452253772Savg */
2453253772Savg#define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
2454253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2455253772Savg		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2456253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2457253772Savg		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
2458253772Savg		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2459253772Savg		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2460253772Savg}
2461253772Savg
2462253772Savg/*
2463253772Savg * 1 operands plus two immediates.
2464253772Savg */
2465253772Savg#define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
2466253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2467253772Savg		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2468253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2469253772Savg		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2470253772Savg		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2471253772Savg}
2472253772Savg
2473253772Savg/*
2474179237Sjb * Dissassemble a single x86 or amd64 instruction.
2475179237Sjb *
2476179237Sjb * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
2477179237Sjb * for interpreting instructions.
2478179237Sjb *
2479179237Sjb * returns non-zero for bad opcode
2480179237Sjb */
2481179237Sjbint
2482179237Sjbdtrace_disx86(dis86_t *x, uint_t cpu_mode)
2483179237Sjb{
2484253772Savg	instable_t *dp;		/* decode table being used */
2485179237Sjb#ifdef DIS_TEXT
2486179237Sjb	uint_t i;
2487179237Sjb#endif
2488179237Sjb#ifdef DIS_MEM
2489179237Sjb	uint_t nomem = 0;
2490179237Sjb#define	NOMEM	(nomem = 1)
2491179237Sjb#else
2492179237Sjb#define	NOMEM	/* nothing */
2493179237Sjb#endif
2494253772Savg	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
2495253772Savg	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
2496253772Savg	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
2497179237Sjb	uint_t w2;		/* wbit value for second operand */
2498179237Sjb	uint_t vbit;
2499179237Sjb	uint_t mode = 0;	/* mode value from ModRM byte */
2500179237Sjb	uint_t reg;		/* reg value from ModRM byte */
2501179237Sjb	uint_t r_m;		/* r_m value from ModRM byte */
2502179237Sjb
2503179237Sjb	uint_t opcode1;		/* high nibble of 1st byte */
2504179237Sjb	uint_t opcode2;		/* low nibble of 1st byte */
2505179237Sjb	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
2506179237Sjb	uint_t opcode4;		/* high nibble of 2nd byte */
2507253772Savg	uint_t opcode5;		/* low nibble of 2nd byte */
2508179237Sjb	uint_t opcode6;		/* high nibble of 3rd byte */
2509179237Sjb	uint_t opcode7;		/* low nibble of 3rd byte */
2510179237Sjb	uint_t opcode_bytes = 1;
2511179237Sjb
2512179237Sjb	/*
2513179237Sjb	 * legacy prefixes come in 5 flavors, you should have only one of each
2514179237Sjb	 */
2515179237Sjb	uint_t	opnd_size_prefix = 0;
2516179237Sjb	uint_t	addr_size_prefix = 0;
2517179237Sjb	uint_t	segment_prefix = 0;
2518179237Sjb	uint_t	lock_prefix = 0;
2519179237Sjb	uint_t	rep_prefix = 0;
2520179237Sjb	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
2521253772Savg
2522253772Savg	/*
2523253772Savg	 * Intel VEX instruction encoding prefix and fields
2524253772Savg	 */
2525253772Savg
2526253772Savg	/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
2527253772Savg	uint_t vex_prefix = 0;
2528253772Savg
2529253772Savg	/*
2530253772Savg	 * VEX prefix byte 1, includes vex.r, vex.x and vex.b
2531253772Savg	 * (for 3 bytes prefix)
2532253772Savg	 */
2533253772Savg	uint_t vex_byte1 = 0;
2534253772Savg
2535253772Savg	/*
2536253772Savg	 * For 32-bit mode, it should prefetch the next byte to
2537253772Savg	 * distinguish between AVX and les/lds
2538253772Savg	 */
2539253772Savg	uint_t vex_prefetch = 0;
2540253772Savg
2541253772Savg	uint_t vex_m = 0;
2542253772Savg	uint_t vex_v = 0;
2543253772Savg	uint_t vex_p = 0;
2544253772Savg	uint_t vex_R = 1;
2545253772Savg	uint_t vex_X = 1;
2546253772Savg	uint_t vex_B = 1;
2547253772Savg	uint_t vex_W = 0;
2548253772Savg	uint_t vex_L;
2549253772Savg
2550253772Savg
2551179237Sjb	size_t	off;
2552179237Sjb
2553253772Savg	instable_t dp_mmx;
2554253772Savg
2555179237Sjb	x->d86_len = 0;
2556179237Sjb	x->d86_rmindex = -1;
2557179237Sjb	x->d86_error = 0;
2558179237Sjb#ifdef DIS_TEXT
2559179237Sjb	x->d86_numopnds = 0;
2560179237Sjb	x->d86_seg_prefix = NULL;
2561253772Savg	x->d86_mnem[0] = 0;
2562253772Savg	for (i = 0; i < 4; ++i) {
2563179237Sjb		x->d86_opnd[i].d86_opnd[0] = 0;
2564179237Sjb		x->d86_opnd[i].d86_prefix[0] = 0;
2565179237Sjb		x->d86_opnd[i].d86_value_size = 0;
2566179237Sjb		x->d86_opnd[i].d86_value = 0;
2567179237Sjb		x->d86_opnd[i].d86_mode = MODE_NONE;
2568179237Sjb	}
2569179237Sjb#endif
2570253772Savg	x->d86_rex_prefix = 0;
2571253772Savg	x->d86_got_modrm = 0;
2572179237Sjb	x->d86_memsize = 0;
2573179237Sjb
2574179237Sjb	if (cpu_mode == SIZE16) {
2575179237Sjb		opnd_size = SIZE16;
2576179237Sjb		addr_size = SIZE16;
2577179237Sjb	} else if (cpu_mode == SIZE32) {
2578179237Sjb		opnd_size = SIZE32;
2579179237Sjb		addr_size = SIZE32;
2580179237Sjb	} else {
2581179237Sjb		opnd_size = SIZE32;
2582179237Sjb		addr_size = SIZE64;
2583179237Sjb	}
2584179237Sjb
2585179237Sjb	/*
2586179237Sjb	 * Get one opcode byte and check for zero padding that follows
2587179237Sjb	 * jump tables.
2588179237Sjb	 */
2589179237Sjb	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2590179237Sjb		goto error;
2591179237Sjb
2592179237Sjb	if (opcode1 == 0 && opcode2 == 0 &&
2593179237Sjb	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
2594179237Sjb#ifdef DIS_TEXT
2595253772Savg		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
2596179237Sjb#endif
2597179237Sjb		goto done;
2598179237Sjb	}
2599179237Sjb
2600179237Sjb	/*
2601179237Sjb	 * Gather up legacy x86 prefix bytes.
2602179237Sjb	 */
2603179237Sjb	for (;;) {
2604179237Sjb		uint_t *which_prefix = NULL;
2605179237Sjb
2606253772Savg		dp = (instable_t *)&dis_distable[opcode1][opcode2];
2607179237Sjb
2608179237Sjb		switch (dp->it_adrmode) {
2609179237Sjb		case PREFIX:
2610179237Sjb			which_prefix = &rep_prefix;
2611179237Sjb			break;
2612179237Sjb		case LOCK:
2613179237Sjb			which_prefix = &lock_prefix;
2614179237Sjb			break;
2615179237Sjb		case OVERRIDE:
2616179237Sjb			which_prefix = &segment_prefix;
2617179237Sjb#ifdef DIS_TEXT
2618179237Sjb			x->d86_seg_prefix = (char *)dp->it_name;
2619179237Sjb#endif
2620179237Sjb			if (dp->it_invalid64 && cpu_mode == SIZE64)
2621179237Sjb				goto error;
2622179237Sjb			break;
2623179237Sjb		case AM:
2624179237Sjb			which_prefix = &addr_size_prefix;
2625179237Sjb			break;
2626179237Sjb		case DM:
2627179237Sjb			which_prefix = &opnd_size_prefix;
2628179237Sjb			break;
2629179237Sjb		}
2630179237Sjb		if (which_prefix == NULL)
2631179237Sjb			break;
2632179237Sjb		*which_prefix = (opcode1 << 4) | opcode2;
2633179237Sjb		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2634179237Sjb			goto error;
2635179237Sjb	}
2636179237Sjb
2637179237Sjb	/*
2638179237Sjb	 * Handle amd64 mode PREFIX values.
2639179237Sjb	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
2640179237Sjb	 * We might have a REX prefix (opcodes 0x40-0x4f)
2641179237Sjb	 */
2642179237Sjb	if (cpu_mode == SIZE64) {
2643179237Sjb		if (segment_prefix != 0x64 && segment_prefix != 0x65)
2644179237Sjb			segment_prefix = 0;
2645179237Sjb
2646179237Sjb		if (opcode1 == 0x4) {
2647179237Sjb			rex_prefix = (opcode1 << 4) | opcode2;
2648179237Sjb			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2649179237Sjb				goto error;
2650253772Savg			dp = (instable_t *)&dis_distable[opcode1][opcode2];
2651253772Savg		} else if (opcode1 == 0xC &&
2652253772Savg		    (opcode2 == 0x4 || opcode2 == 0x5)) {
2653253772Savg			/* AVX instructions */
2654253772Savg			vex_prefix = (opcode1 << 4) | opcode2;
2655253772Savg			x->d86_rex_prefix = 0x40;
2656179237Sjb		}
2657253772Savg	} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
2658253772Savg		/* LDS, LES or AVX */
2659253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
2660253772Savg		vex_prefetch = 1;
2661253772Savg
2662253772Savg		if (mode == REG_ONLY) {
2663253772Savg			/* AVX */
2664253772Savg			vex_prefix = (opcode1 << 4) | opcode2;
2665253772Savg			x->d86_rex_prefix = 0x40;
2666253772Savg			opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
2667253772Savg			opcode4 = ((reg << 3) | r_m) & 0x0F;
2668253772Savg		}
2669179237Sjb	}
2670179237Sjb
2671253772Savg	if (vex_prefix == VEX_2bytes) {
2672253772Savg		if (!vex_prefetch) {
2673253772Savg			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
2674253772Savg				goto error;
2675253772Savg		}
2676253772Savg		vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
2677253772Savg		vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
2678253772Savg		vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
2679253772Savg		vex_p = opcode4 & VEX_p;
2680253772Savg		/*
2681253772Savg		 * The vex.x and vex.b bits are not defined in two bytes
2682253772Savg		 * mode vex prefix, their default values are 1
2683253772Savg		 */
2684253772Savg		vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
2685253772Savg
2686253772Savg		if (vex_R == 0)
2687253772Savg			x->d86_rex_prefix |= REX_R;
2688253772Savg
2689253772Savg		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2690253772Savg			goto error;
2691253772Savg
2692253772Savg		switch (vex_p) {
2693253772Savg			case VEX_p_66:
2694253772Savg				dp = (instable_t *)
2695253772Savg				    &dis_opAVX660F[(opcode1 << 4) | opcode2];
2696253772Savg				break;
2697253772Savg			case VEX_p_F3:
2698253772Savg				dp = (instable_t *)
2699253772Savg				    &dis_opAVXF30F[(opcode1 << 4) | opcode2];
2700253772Savg				break;
2701253772Savg			case VEX_p_F2:
2702253772Savg				dp = (instable_t *)
2703253772Savg				    &dis_opAVXF20F [(opcode1 << 4) | opcode2];
2704253772Savg				break;
2705253772Savg			default:
2706253772Savg				dp = (instable_t *)
2707253772Savg				    &dis_opAVX0F[opcode1][opcode2];
2708253772Savg
2709253772Savg		}
2710253772Savg
2711253772Savg	} else if (vex_prefix == VEX_3bytes) {
2712253772Savg		if (!vex_prefetch) {
2713253772Savg			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
2714253772Savg				goto error;
2715253772Savg		}
2716253772Savg		vex_R = (opcode3 & VEX_R) >> 3;
2717253772Savg		vex_X = (opcode3 & VEX_X) >> 2;
2718253772Savg		vex_B = (opcode3 & VEX_B) >> 1;
2719253772Savg		vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
2720253772Savg		vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
2721253772Savg
2722253772Savg		if (vex_R == 0)
2723253772Savg			x->d86_rex_prefix |= REX_R;
2724253772Savg		if (vex_X == 0)
2725253772Savg			x->d86_rex_prefix |= REX_X;
2726253772Savg		if (vex_B == 0)
2727253772Savg			x->d86_rex_prefix |= REX_B;
2728253772Savg
2729253772Savg		if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
2730253772Savg			goto error;
2731253772Savg		vex_W = (opcode5 & VEX_W) >> 3;
2732253772Savg		vex_L = (opcode6 & VEX_L) >> 2;
2733253772Savg		vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
2734253772Savg		vex_p = opcode6 & VEX_p;
2735253772Savg
2736253772Savg		if (vex_W)
2737253772Savg			x->d86_rex_prefix |= REX_W;
2738253772Savg
2739253772Savg		/* Only these three vex_m values valid; others are reserved */
2740253772Savg		if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
2741253772Savg		    (vex_m != VEX_m_0F3A))
2742253772Savg			goto error;
2743253772Savg
2744253772Savg		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2745253772Savg			goto error;
2746253772Savg
2747253772Savg		switch (vex_p) {
2748253772Savg			case VEX_p_66:
2749253772Savg				if (vex_m == VEX_m_0F) {
2750253772Savg					dp = (instable_t *)
2751253772Savg					    &dis_opAVX660F
2752253772Savg					    [(opcode1 << 4) | opcode2];
2753253772Savg				} else if (vex_m == VEX_m_0F38) {
2754253772Savg					dp = (instable_t *)
2755253772Savg					    &dis_opAVX660F38
2756253772Savg					    [(opcode1 << 4) | opcode2];
2757253772Savg				} else if (vex_m == VEX_m_0F3A) {
2758253772Savg					dp = (instable_t *)
2759253772Savg					    &dis_opAVX660F3A
2760253772Savg					    [(opcode1 << 4) | opcode2];
2761253772Savg				} else {
2762253772Savg					goto error;
2763253772Savg				}
2764253772Savg				break;
2765253772Savg			case VEX_p_F3:
2766253772Savg				if (vex_m == VEX_m_0F) {
2767253772Savg					dp = (instable_t *)
2768253772Savg					    &dis_opAVXF30F
2769253772Savg					    [(opcode1 << 4) | opcode2];
2770253772Savg				} else {
2771253772Savg					goto error;
2772253772Savg				}
2773253772Savg				break;
2774253772Savg			case VEX_p_F2:
2775253772Savg				if (vex_m == VEX_m_0F) {
2776253772Savg					dp = (instable_t *)
2777253772Savg					    &dis_opAVXF20F
2778253772Savg					    [(opcode1 << 4) | opcode2];
2779253772Savg				} else {
2780253772Savg					goto error;
2781253772Savg				}
2782253772Savg				break;
2783253772Savg			default:
2784253772Savg				dp = (instable_t *)
2785253772Savg				    &dis_opAVX0F[opcode1][opcode2];
2786253772Savg
2787253772Savg		}
2788253772Savg	}
2789253772Savg	if (vex_prefix) {
2790253772Savg		if (vex_L)
2791253772Savg			wbit = YMM_OPND;
2792253772Savg		else
2793253772Savg			wbit = XMM_OPND;
2794253772Savg	}
2795253772Savg
2796179237Sjb	/*
2797179237Sjb	 * Deal with selection of operand and address size now.
2798179237Sjb	 * Note that the REX.W bit being set causes opnd_size_prefix to be
2799179237Sjb	 * ignored.
2800179237Sjb	 */
2801179237Sjb	if (cpu_mode == SIZE64) {
2802253772Savg		if ((rex_prefix & REX_W) || vex_W)
2803179237Sjb			opnd_size = SIZE64;
2804179237Sjb		else if (opnd_size_prefix)
2805179237Sjb			opnd_size = SIZE16;
2806179237Sjb
2807179237Sjb		if (addr_size_prefix)
2808179237Sjb			addr_size = SIZE32;
2809179237Sjb	} else if (cpu_mode == SIZE32) {
2810179237Sjb		if (opnd_size_prefix)
2811179237Sjb			opnd_size = SIZE16;
2812179237Sjb		if (addr_size_prefix)
2813179237Sjb			addr_size = SIZE16;
2814179237Sjb	} else {
2815179237Sjb		if (opnd_size_prefix)
2816179237Sjb			opnd_size = SIZE32;
2817179237Sjb		if (addr_size_prefix)
2818179237Sjb			addr_size = SIZE32;
2819179237Sjb	}
2820179237Sjb	/*
2821179237Sjb	 * The pause instruction - a repz'd nop.  This doesn't fit
2822179237Sjb	 * with any of the other prefix goop added for SSE, so we'll
2823179237Sjb	 * special-case it here.
2824179237Sjb	 */
2825179237Sjb	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
2826179237Sjb		rep_prefix = 0;
2827253772Savg		dp = (instable_t *)&dis_opPause;
2828179237Sjb	}
2829179237Sjb
2830179237Sjb	/*
2831179237Sjb	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
2832179237Sjb	 * byte so we may need to perform a table indirection.
2833179237Sjb	 */
2834253772Savg	if (dp->it_indirect == (instable_t *)dis_op0F) {
2835179237Sjb		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
2836179237Sjb			goto error;
2837179237Sjb		opcode_bytes = 2;
2838179237Sjb		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
2839179237Sjb			uint_t	subcode;
2840179237Sjb
2841179237Sjb			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2842179237Sjb				goto error;
2843179237Sjb			opcode_bytes = 3;
2844179237Sjb			subcode = ((opcode6 & 0x3) << 1) |
2845179237Sjb			    ((opcode7 & 0x8) >> 3);
2846253772Savg			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
2847179237Sjb		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
2848253772Savg			dp = (instable_t *)&dis_op0FC8[0];
2849253772Savg		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
2850253772Savg			opcode_bytes = 3;
2851253772Savg			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2852253772Savg				goto error;
2853253772Savg			if (opnd_size == SIZE16)
2854253772Savg				opnd_size = SIZE32;
2855253772Savg
2856253772Savg			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
2857253772Savg#ifdef DIS_TEXT
2858253772Savg			if (strcmp(dp->it_name, "INVALID") == 0)
2859253772Savg				goto error;
2860253772Savg#endif
2861253772Savg			switch (dp->it_adrmode) {
2862253772Savg				case XMMP_66r:
2863253772Savg				case XMMPRM_66r:
2864253772Savg				case XMM3PM_66r:
2865253772Savg					if (opnd_size_prefix == 0) {
2866253772Savg						goto error;
2867253772Savg					}
2868253772Savg					break;
2869253772Savg				case XMMP_66o:
2870253772Savg					if (opnd_size_prefix == 0) {
2871253772Savg						/* SSSE3 MMX instructions */
2872253772Savg						dp_mmx = *dp;
2873253772Savg						dp = &dp_mmx;
2874253772Savg						dp->it_adrmode = MMOPM_66o;
2875253772Savg#ifdef	DIS_MEM
2876253772Savg						dp->it_size = 8;
2877253772Savg#endif
2878253772Savg					}
2879253772Savg					break;
2880253772Savg				default:
2881253772Savg					goto error;
2882253772Savg			}
2883253772Savg		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
2884253772Savg			opcode_bytes = 3;
2885253772Savg			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2886253772Savg				goto error;
2887253772Savg			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
2888253772Savg
2889253772Savg			/*
2890253772Savg			 * Both crc32 and movbe have the same 3rd opcode
2891253772Savg			 * byte of either 0xF0 or 0xF1, so we use another
2892253772Savg			 * indirection to distinguish between the two.
2893253772Savg			 */
2894253772Savg			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
2895253772Savg			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
2896253772Savg
2897253772Savg				dp = dp->it_indirect;
2898253772Savg				if (rep_prefix != 0xF2) {
2899253772Savg					/* It is movbe */
2900253772Savg					dp++;
2901253772Savg				}
2902253772Savg			}
2903253772Savg#ifdef DIS_TEXT
2904253772Savg			if (strcmp(dp->it_name, "INVALID") == 0)
2905253772Savg				goto error;
2906253772Savg#endif
2907253772Savg			switch (dp->it_adrmode) {
2908253772Savg				case XMM_66r:
2909253772Savg				case XMMM_66r:
2910253772Savg					if (opnd_size_prefix == 0) {
2911253772Savg						goto error;
2912253772Savg					}
2913253772Savg					break;
2914253772Savg				case XMM_66o:
2915253772Savg					if (opnd_size_prefix == 0) {
2916253772Savg						/* SSSE3 MMX instructions */
2917253772Savg						dp_mmx = *dp;
2918253772Savg						dp = &dp_mmx;
2919253772Savg						dp->it_adrmode = MM;
2920253772Savg#ifdef	DIS_MEM
2921253772Savg						dp->it_size = 8;
2922253772Savg#endif
2923253772Savg					}
2924253772Savg					break;
2925253772Savg				case CRC32:
2926253772Savg					if (rep_prefix != 0xF2) {
2927253772Savg						goto error;
2928253772Savg					}
2929253772Savg					rep_prefix = 0;
2930253772Savg					break;
2931253772Savg				case MOVBE:
2932253772Savg					if (rep_prefix != 0x0) {
2933253772Savg						goto error;
2934253772Savg					}
2935253772Savg					break;
2936253772Savg				default:
2937253772Savg					goto error;
2938253772Savg			}
2939179237Sjb		} else {
2940253772Savg			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
2941179237Sjb		}
2942179237Sjb	}
2943179237Sjb
2944179237Sjb	/*
2945179237Sjb	 * If still not at a TERM decode entry, then a ModRM byte
2946179237Sjb	 * exists and its fields further decode the instruction.
2947179237Sjb	 */
2948179237Sjb	x->d86_got_modrm = 0;
2949179237Sjb	if (dp->it_indirect != TERM) {
2950179237Sjb		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
2951179237Sjb		if (x->d86_error)
2952179237Sjb			goto error;
2953179237Sjb		reg = opcode3;
2954179237Sjb
2955179237Sjb		/*
2956179237Sjb		 * decode 287 instructions (D8-DF) from opcodeN
2957179237Sjb		 */
2958179237Sjb		if (opcode1 == 0xD && opcode2 >= 0x8) {
2959179237Sjb			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
2960253772Savg				dp = (instable_t *)&dis_opFP5[r_m];
2961179237Sjb			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
2962253772Savg				dp = (instable_t *)&dis_opFP7[opcode3];
2963179237Sjb			else if (opcode2 == 0xB && mode == 0x3)
2964253772Savg				dp = (instable_t *)&dis_opFP6[opcode3];
2965179237Sjb			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
2966253772Savg				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
2967179237Sjb			else if (mode == 0x3)
2968253772Savg				dp = (instable_t *)
2969253772Savg				    &dis_opFP3[opcode2 - 8][opcode3];
2970179237Sjb			else
2971253772Savg				dp = (instable_t *)
2972253772Savg				    &dis_opFP1n2[opcode2 - 8][opcode3];
2973179237Sjb		} else {
2974253772Savg			dp = (instable_t *)dp->it_indirect + opcode3;
2975179237Sjb		}
2976179237Sjb	}
2977179237Sjb
2978179237Sjb	/*
2979179237Sjb	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
2980179237Sjb	 * (sign extend 32bit to 64 bit)
2981179237Sjb	 */
2982253772Savg	if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
2983253772Savg	    opcode1 == 0x6 && opcode2 == 0x3)
2984253772Savg		dp = (instable_t *)&dis_opMOVSLD;
2985179237Sjb
2986179237Sjb	/*
2987179237Sjb	 * at this point we should have a correct (or invalid) opcode
2988179237Sjb	 */
2989253772Savg	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
2990253772Savg	    cpu_mode != SIZE64 && dp->it_invalid32)
2991179237Sjb		goto error;
2992179237Sjb	if (dp->it_indirect != TERM)
2993179237Sjb		goto error;
2994179237Sjb
2995179237Sjb	/*
2996179237Sjb	 * deal with MMX/SSE opcodes which are changed by prefixes
2997179237Sjb	 */
2998179237Sjb	switch (dp->it_adrmode) {
2999179237Sjb	case MMO:
3000179237Sjb	case MMOIMPL:
3001179237Sjb	case MMO3P:
3002179237Sjb	case MMOM3:
3003179237Sjb	case MMOMS:
3004179237Sjb	case MMOPM:
3005179237Sjb	case MMOPRM:
3006179237Sjb	case MMOS:
3007179237Sjb	case XMMO:
3008179237Sjb	case XMMOM:
3009179237Sjb	case XMMOMS:
3010179237Sjb	case XMMOPM:
3011179237Sjb	case XMMOS:
3012179237Sjb	case XMMOMX:
3013179237Sjb	case XMMOX3:
3014179237Sjb	case XMMOXMM:
3015179237Sjb		/*
3016179237Sjb		 * This is horrible.  Some SIMD instructions take the
3017179237Sjb		 * form 0x0F 0x?? ..., which is easily decoded using the
3018179237Sjb		 * existing tables.  Other SIMD instructions use various
3019179237Sjb		 * prefix bytes to overload existing instructions.  For
3020179237Sjb		 * Example, addps is F0, 58, whereas addss is F3 (repz),
3021179237Sjb		 * F0, 58.  Presumably someone got a raise for this.
3022179237Sjb		 *
3023179237Sjb		 * If we see one of the instructions which can be
3024179237Sjb		 * modified in this way (if we've got one of the SIMDO*
3025179237Sjb		 * address modes), we'll check to see if the last prefix
3026179237Sjb		 * was a repz.  If it was, we strip the prefix from the
3027179237Sjb		 * mnemonic, and we indirect using the dis_opSIMDrepz
3028179237Sjb		 * table.
3029179237Sjb		 */
3030179237Sjb
3031179237Sjb		/*
3032179237Sjb		 * Calculate our offset in dis_op0F
3033179237Sjb		 */
3034179237Sjb		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
3035179237Sjb			goto error;
3036179237Sjb
3037179237Sjb		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3038179237Sjb		    sizeof (instable_t);
3039179237Sjb
3040179237Sjb		/*
3041179237Sjb		 * Rewrite if this instruction used one of the magic prefixes.
3042179237Sjb		 */
3043179237Sjb		if (rep_prefix) {
3044179237Sjb			if (rep_prefix == 0xf2)
3045253772Savg				dp = (instable_t *)&dis_opSIMDrepnz[off];
3046179237Sjb			else
3047253772Savg				dp = (instable_t *)&dis_opSIMDrepz[off];
3048179237Sjb			rep_prefix = 0;
3049179237Sjb		} else if (opnd_size_prefix) {
3050253772Savg			dp = (instable_t *)&dis_opSIMDdata16[off];
3051179237Sjb			opnd_size_prefix = 0;
3052179237Sjb			if (opnd_size == SIZE16)
3053179237Sjb				opnd_size = SIZE32;
3054179237Sjb		}
3055179237Sjb		break;
3056179237Sjb
3057179237Sjb	case MMOSH:
3058179237Sjb		/*
3059179237Sjb		 * As with the "normal" SIMD instructions, the MMX
3060179237Sjb		 * shuffle instructions are overloaded.  These
3061179237Sjb		 * instructions, however, are special in that they use
3062179237Sjb		 * an extra byte, and thus an extra table.  As of this
3063179237Sjb		 * writing, they only use the opnd_size prefix.
3064179237Sjb		 */
3065179237Sjb
3066179237Sjb		/*
3067179237Sjb		 * Calculate our offset in dis_op0F7123
3068179237Sjb		 */
3069179237Sjb		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
3070179237Sjb		    sizeof (dis_op0F7123))
3071179237Sjb			goto error;
3072179237Sjb
3073179237Sjb		if (opnd_size_prefix) {
3074179237Sjb			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
3075179237Sjb			    sizeof (instable_t);
3076253772Savg			dp = (instable_t *)&dis_opSIMD7123[off];
3077179237Sjb			opnd_size_prefix = 0;
3078179237Sjb			if (opnd_size == SIZE16)
3079179237Sjb				opnd_size = SIZE32;
3080179237Sjb		}
3081179237Sjb		break;
3082253772Savg	case MRw:
3083253772Savg		if (rep_prefix) {
3084253772Savg			if (rep_prefix == 0xf3) {
3085253772Savg
3086253772Savg				/*
3087253772Savg				 * Calculate our offset in dis_op0F
3088253772Savg				 */
3089253772Savg				if ((uintptr_t)dp - (uintptr_t)dis_op0F
3090253772Savg				    > sizeof (dis_op0F))
3091253772Savg					goto error;
3092253772Savg
3093253772Savg				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3094253772Savg				    sizeof (instable_t);
3095253772Savg
3096253772Savg				dp = (instable_t *)&dis_opSIMDrepz[off];
3097253772Savg				rep_prefix = 0;
3098253772Savg			} else {
3099253772Savg				goto error;
3100253772Savg			}
3101253772Savg		}
3102253772Savg		break;
3103179237Sjb	}
3104179237Sjb
3105179237Sjb	/*
3106179237Sjb	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
3107179237Sjb	 */
3108179237Sjb	if (cpu_mode == SIZE64)
3109179237Sjb		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
3110179237Sjb			opnd_size = SIZE64;
3111179237Sjb
3112179237Sjb#ifdef DIS_TEXT
3113179237Sjb	/*
3114179237Sjb	 * At this point most instructions can format the opcode mnemonic
3115179237Sjb	 * including the prefixes.
3116179237Sjb	 */
3117179237Sjb	if (lock_prefix)
3118253772Savg		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
3119179237Sjb
3120179237Sjb	if (rep_prefix == 0xf2)
3121253772Savg		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
3122179237Sjb	else if (rep_prefix == 0xf3)
3123253772Savg		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
3124179237Sjb
3125179237Sjb	if (cpu_mode == SIZE64 && addr_size_prefix)
3126253772Savg		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
3127179237Sjb
3128179237Sjb	if (dp->it_adrmode != CBW &&
3129179237Sjb	    dp->it_adrmode != CWD &&
3130179237Sjb	    dp->it_adrmode != XMMSFNC) {
3131179237Sjb		if (strcmp(dp->it_name, "INVALID") == 0)
3132179237Sjb			goto error;
3133253772Savg		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
3134179237Sjb		if (dp->it_suffix) {
3135179237Sjb			char *types[] = {"", "w", "l", "q"};
3136179237Sjb			if (opcode_bytes == 2 && opcode4 == 4) {
3137179237Sjb				/* It's a cmovx.yy. Replace the suffix x */
3138179237Sjb				for (i = 5; i < OPLEN; i++) {
3139253772Savg					if (x->d86_mnem[i] == '.')
3140179237Sjb						break;
3141179237Sjb				}
3142253772Savg				x->d86_mnem[i - 1] = *types[opnd_size];
3143253772Savg			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
3144253772Savg			    ((opcode6 == 1 && opcode7 == 6) ||
3145253772Savg			    (opcode6 == 2 && opcode7 == 2))) {
3146253772Savg				/*
3147253772Savg				 * To handle PINSRD and PEXTRD
3148253772Savg				 */
3149253772Savg				(void) strlcat(x->d86_mnem, "d", OPLEN);
3150179237Sjb			} else {
3151253772Savg				(void) strlcat(x->d86_mnem, types[opnd_size],
3152179237Sjb				    OPLEN);
3153179237Sjb			}
3154179237Sjb		}
3155179237Sjb	}
3156179237Sjb#endif
3157179237Sjb
3158179237Sjb	/*
3159179237Sjb	 * Process operands based on the addressing modes.
3160179237Sjb	 */
3161179237Sjb	x->d86_mode = cpu_mode;
3162253772Savg	/*
3163253772Savg	 * In vex mode the rex_prefix has no meaning
3164253772Savg	 */
3165253772Savg	if (!vex_prefix)
3166253772Savg		x->d86_rex_prefix = rex_prefix;
3167179237Sjb	x->d86_opnd_size = opnd_size;
3168179237Sjb	x->d86_addr_size = addr_size;
3169179237Sjb	vbit = 0;		/* initialize for mem/reg -> reg */
3170179237Sjb	switch (dp->it_adrmode) {
3171179237Sjb		/*
3172179237Sjb		 * amd64 instruction to sign extend 32 bit reg/mem operands
3173179237Sjb		 * into 64 bit register values
3174179237Sjb		 */
3175179237Sjb	case MOVSXZ:
3176179237Sjb#ifdef DIS_TEXT
3177179237Sjb		if (rex_prefix == 0)
3178253772Savg			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
3179179237Sjb#endif
3180179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3181179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3182179237Sjb		x->d86_opnd_size = SIZE64;
3183179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3184179237Sjb		x->d86_opnd_size = opnd_size = SIZE32;
3185179237Sjb		wbit = LONG_OPND;
3186179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3187179237Sjb		break;
3188179237Sjb
3189179237Sjb		/*
3190179237Sjb		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
3191253772Savg		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
3192179237Sjb		 * wbit lives in 2nd byte, note that operands
3193179237Sjb		 * are different sized
3194179237Sjb		 */
3195179237Sjb	case MOVZ:
3196179237Sjb		if (rex_prefix & REX_W) {
3197179237Sjb			/* target register size = 64 bit */
3198253772Savg			x->d86_mnem[5] = 'q';
3199179237Sjb		}
3200179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3201179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3202179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3203179237Sjb		x->d86_opnd_size = opnd_size = SIZE16;
3204179237Sjb		wbit = WBIT(opcode5);
3205179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3206179237Sjb		break;
3207253772Savg	case CRC32:
3208253772Savg		opnd_size = SIZE32;
3209253772Savg		if (rex_prefix & REX_W)
3210253772Savg			opnd_size = SIZE64;
3211253772Savg		x->d86_opnd_size = opnd_size;
3212179237Sjb
3213253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
3214253772Savg		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3215253772Savg		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3216253772Savg		wbit = WBIT(opcode7);
3217253772Savg		if (opnd_size_prefix)
3218253772Savg			x->d86_opnd_size = opnd_size = SIZE16;
3219253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 0);
3220253772Savg		break;
3221253772Savg	case MOVBE:
3222253772Savg		opnd_size = SIZE32;
3223253772Savg		if (rex_prefix & REX_W)
3224253772Savg			opnd_size = SIZE64;
3225253772Savg		x->d86_opnd_size = opnd_size;
3226253772Savg
3227253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
3228253772Savg		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3229253772Savg		wbit = WBIT(opcode7);
3230253772Savg		if (opnd_size_prefix)
3231253772Savg			x->d86_opnd_size = opnd_size = SIZE16;
3232253772Savg		if (wbit) {
3233253772Savg			/* reg -> mem */
3234253772Savg			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3235253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 1);
3236253772Savg		} else {
3237253772Savg			/* mem -> reg */
3238253772Savg			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3239253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 0);
3240253772Savg		}
3241253772Savg		break;
3242253772Savg
3243179237Sjb	/*
3244179237Sjb	 * imul instruction, with either 8-bit or longer immediate
3245179237Sjb	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
3246179237Sjb	 */
3247179237Sjb	case IMUL:
3248179237Sjb		wbit = LONG_OPND;
3249179237Sjb		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
3250253772Savg		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
3251179237Sjb		break;
3252179237Sjb
3253179237Sjb	/* memory or register operand to register, with 'w' bit	*/
3254179237Sjb	case MRw:
3255179237Sjb		wbit = WBIT(opcode2);
3256179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3257179237Sjb		break;
3258179237Sjb
3259179237Sjb	/* register to memory or register operand, with 'w' bit	*/
3260179237Sjb	/* arpl happens to fit here also because it is odd */
3261179237Sjb	case RMw:
3262179237Sjb		if (opcode_bytes == 2)
3263179237Sjb			wbit = WBIT(opcode5);
3264179237Sjb		else
3265179237Sjb			wbit = WBIT(opcode2);
3266179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3267179237Sjb		break;
3268179237Sjb
3269179237Sjb	/* xaddb instruction */
3270179237Sjb	case XADDB:
3271179237Sjb		wbit = 0;
3272179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3273179237Sjb		break;
3274179237Sjb
3275179237Sjb	/* MMX register to memory or register operand		*/
3276179237Sjb	case MMS:
3277179237Sjb	case MMOS:
3278179237Sjb#ifdef DIS_TEXT
3279179237Sjb		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3280179237Sjb#else
3281179237Sjb		wbit = LONG_OPND;
3282179237Sjb#endif
3283179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3284179237Sjb		break;
3285179237Sjb
3286179237Sjb	/* MMX register to memory */
3287179237Sjb	case MMOMS:
3288179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3289179237Sjb		if (mode == REG_ONLY)
3290179237Sjb			goto error;
3291179237Sjb		wbit = MM_OPND;
3292179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3293179237Sjb		break;
3294179237Sjb
3295179237Sjb	/* Double shift. Has immediate operand specifying the shift. */
3296179237Sjb	case DSHIFT:
3297179237Sjb		wbit = LONG_OPND;
3298179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3299179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3300179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 2);
3301179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3302179237Sjb		dtrace_imm_opnd(x, wbit, 1, 0);
3303179237Sjb		break;
3304179237Sjb
3305179237Sjb	/*
3306179237Sjb	 * Double shift. With no immediate operand, specifies using %cl.
3307179237Sjb	 */
3308179237Sjb	case DSHIFTcl:
3309179237Sjb		wbit = LONG_OPND;
3310179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3311179237Sjb		break;
3312179237Sjb
3313179237Sjb	/* immediate to memory or register operand */
3314179237Sjb	case IMlw:
3315179237Sjb		wbit = WBIT(opcode2);
3316179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3317179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 1);
3318179237Sjb		/*
3319179237Sjb		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
3320179237Sjb		 */
3321179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
3322179237Sjb		break;
3323179237Sjb
3324179237Sjb	/* immediate to memory or register operand with the	*/
3325179237Sjb	/* 'w' bit present					*/
3326179237Sjb	case IMw:
3327179237Sjb		wbit = WBIT(opcode2);
3328179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3329179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3330179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 1);
3331179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3332179237Sjb		break;
3333179237Sjb
3334179237Sjb	/* immediate to register with register in low 3 bits	*/
3335179237Sjb	/* of op code						*/
3336179237Sjb	case IR:
3337179237Sjb		/* w-bit here (with regs) is bit 3 */
3338179237Sjb		wbit = opcode2 >>3 & 0x1;
3339179237Sjb		reg = REGNO(opcode2);
3340179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3341179237Sjb		mode = REG_ONLY;
3342179237Sjb		r_m = reg;
3343179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 1);
3344179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
3345179237Sjb		break;
3346179237Sjb
3347179237Sjb	/* MMX immediate shift of register */
3348179237Sjb	case MMSH:
3349179237Sjb	case MMOSH:
3350179237Sjb		wbit = MM_OPND;
3351179237Sjb		goto mm_shift;	/* in next case */
3352179237Sjb
3353179237Sjb	/* SIMD immediate shift of register */
3354179237Sjb	case XMMSH:
3355179237Sjb		wbit = XMM_OPND;
3356179237Sjbmm_shift:
3357179237Sjb		reg = REGNO(opcode7);
3358179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3359179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
3360179237Sjb		dtrace_imm_opnd(x, wbit, 1, 0);
3361179237Sjb		NOMEM;
3362179237Sjb		break;
3363179237Sjb
3364179237Sjb	/* accumulator to memory operand */
3365179237Sjb	case AO:
3366179237Sjb		vbit = 1;
3367179237Sjb		/*FALLTHROUGH*/
3368179237Sjb
3369179237Sjb	/* memory operand to accumulator */
3370179237Sjb	case OA:
3371179237Sjb		wbit = WBIT(opcode2);
3372179237Sjb		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
3373179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
3374179237Sjb#ifdef DIS_TEXT
3375179237Sjb		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
3376179237Sjb#endif
3377179237Sjb		break;
3378179237Sjb
3379179237Sjb
3380179237Sjb	/* segment register to memory or register operand */
3381179237Sjb	case SM:
3382179237Sjb		vbit = 1;
3383179237Sjb		/*FALLTHROUGH*/
3384179237Sjb
3385179237Sjb	/* memory or register operand to segment register */
3386179237Sjb	case MS:
3387179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3388179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3389179237Sjb		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
3390179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
3391179237Sjb		break;
3392179237Sjb
3393179237Sjb	/*
3394179237Sjb	 * rotate or shift instructions, which may shift by 1 or
3395179237Sjb	 * consult the cl register, depending on the 'v' bit
3396179237Sjb	 */
3397179237Sjb	case Mv:
3398179237Sjb		vbit = VBIT(opcode2);
3399179237Sjb		wbit = WBIT(opcode2);
3400179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3401179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 1);
3402179237Sjb#ifdef DIS_TEXT
3403179237Sjb		if (vbit) {
3404179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
3405179237Sjb		} else {
3406179237Sjb			x->d86_opnd[0].d86_mode = MODE_SIGNED;
3407179237Sjb			x->d86_opnd[0].d86_value_size = 1;
3408179237Sjb			x->d86_opnd[0].d86_value = 1;
3409179237Sjb		}
3410179237Sjb#endif
3411179237Sjb		break;
3412179237Sjb	/*
3413179237Sjb	 * immediate rotate or shift instructions
3414179237Sjb	 */
3415179237Sjb	case MvI:
3416179237Sjb		wbit = WBIT(opcode2);
3417179237Sjbnormal_imm_mem:
3418179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3419179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 1);
3420179237Sjb		dtrace_imm_opnd(x, wbit, 1, 0);
3421179237Sjb		break;
3422179237Sjb
3423179237Sjb	/* bit test instructions */
3424179237Sjb	case MIb:
3425179237Sjb		wbit = LONG_OPND;
3426179237Sjb		goto normal_imm_mem;
3427179237Sjb
3428179237Sjb	/* single memory or register operand with 'w' bit present */
3429179237Sjb	case Mw:
3430179237Sjb		wbit = WBIT(opcode2);
3431179237Sjbjust_mem:
3432179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3433179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3434179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3435179237Sjb		break;
3436179237Sjb
3437179237Sjb	case SWAPGS:
3438179237Sjb		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
3439179237Sjb#ifdef DIS_TEXT
3440253772Savg			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
3441179237Sjb#endif
3442179237Sjb			NOMEM;
3443179237Sjb			break;
3444179237Sjb		}
3445179237Sjb		/*FALLTHROUGH*/
3446179237Sjb
3447179237Sjb	/* prefetch instruction - memory operand, but no memory acess */
3448179237Sjb	case PREF:
3449179237Sjb		NOMEM;
3450179237Sjb		/*FALLTHROUGH*/
3451179237Sjb
3452179237Sjb	/* single memory or register operand */
3453179237Sjb	case M:
3454179237Sjb		wbit = LONG_OPND;
3455179237Sjb		goto just_mem;
3456179237Sjb
3457179237Sjb	/* single memory or register byte operand */
3458179237Sjb	case Mb:
3459179237Sjb		wbit = BYTE_OPND;
3460179237Sjb		goto just_mem;
3461179237Sjb
3462253772Savg	case MONITOR_MWAIT:
3463253772Savg		if (mode == 3) {
3464253772Savg			if (r_m == 0) {
3465253772Savg#ifdef DIS_TEXT
3466253772Savg				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
3467253772Savg#endif
3468253772Savg				NOMEM;
3469253772Savg				break;
3470253772Savg			} else if (r_m == 1) {
3471253772Savg#ifdef DIS_TEXT
3472253772Savg				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
3473253772Savg#endif
3474253772Savg				NOMEM;
3475253772Savg				break;
3476253772Savg			} else {
3477253772Savg				goto error;
3478253772Savg			}
3479253772Savg		}
3480253772Savg		/*FALLTHROUGH*/
3481253772Savg	case XGETBV_XSETBV:
3482253772Savg		if (mode == 3) {
3483253772Savg			if (r_m == 0) {
3484253772Savg#ifdef DIS_TEXT
3485253772Savg				(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
3486253772Savg#endif
3487253772Savg				NOMEM;
3488253772Savg				break;
3489253772Savg			} else if (r_m == 1) {
3490253772Savg#ifdef DIS_TEXT
3491253772Savg				(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
3492253772Savg#endif
3493253772Savg				NOMEM;
3494253772Savg				break;
3495253772Savg			} else {
3496253772Savg				goto error;
3497253772Savg			}
3498253772Savg
3499253772Savg		}
3500253772Savg		/*FALLTHROUGH*/
3501179237Sjb	case MO:
3502179237Sjb		/* Similar to M, but only memory (no direct registers) */
3503179237Sjb		wbit = LONG_OPND;
3504179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3505179237Sjb		if (mode == 3)
3506179237Sjb			goto error;
3507179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3508179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3509179237Sjb		break;
3510179237Sjb
3511179237Sjb	/* move special register to register or reverse if vbit */
3512179237Sjb	case SREG:
3513179237Sjb		switch (opcode5) {
3514179237Sjb
3515179237Sjb		case 2:
3516179237Sjb			vbit = 1;
3517179237Sjb			/*FALLTHROUGH*/
3518179237Sjb		case 0:
3519179237Sjb			wbit = CONTROL_OPND;
3520179237Sjb			break;
3521179237Sjb
3522179237Sjb		case 3:
3523179237Sjb			vbit = 1;
3524179237Sjb			/*FALLTHROUGH*/
3525179237Sjb		case 1:
3526179237Sjb			wbit = DEBUG_OPND;
3527179237Sjb			break;
3528179237Sjb
3529179237Sjb		case 6:
3530179237Sjb			vbit = 1;
3531179237Sjb			/*FALLTHROUGH*/
3532179237Sjb		case 4:
3533179237Sjb			wbit = TEST_OPND;
3534179237Sjb			break;
3535179237Sjb
3536179237Sjb		}
3537179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3538179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3539179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
3540179237Sjb		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
3541179237Sjb		NOMEM;
3542179237Sjb		break;
3543179237Sjb
3544179237Sjb	/*
3545179237Sjb	 * single register operand with register in the low 3
3546179237Sjb	 * bits of op code
3547179237Sjb	 */
3548179237Sjb	case R:
3549179237Sjb		if (opcode_bytes == 2)
3550179237Sjb			reg = REGNO(opcode5);
3551179237Sjb		else
3552179237Sjb			reg = REGNO(opcode2);
3553179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3554179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3555179237Sjb		NOMEM;
3556179237Sjb		break;
3557179237Sjb
3558179237Sjb	/*
3559179237Sjb	 * register to accumulator with register in the low 3
3560179237Sjb	 * bits of op code, xchg instructions
3561179237Sjb	 */
3562179237Sjb	case RA:
3563179237Sjb		NOMEM;
3564179237Sjb		reg = REGNO(opcode2);
3565179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3566179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3567179237Sjb		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
3568179237Sjb		break;
3569179237Sjb
3570179237Sjb	/*
3571179237Sjb	 * single segment register operand, with register in
3572179237Sjb	 * bits 3-4 of op code byte
3573179237Sjb	 */
3574179237Sjb	case SEG:
3575179237Sjb		NOMEM;
3576179237Sjb		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
3577179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
3578179237Sjb		break;
3579179237Sjb
3580179237Sjb	/*
3581179237Sjb	 * single segment register operand, with register in
3582179237Sjb	 * bits 3-5 of op code
3583179237Sjb	 */
3584179237Sjb	case LSEG:
3585179237Sjb		NOMEM;
3586179237Sjb		/* long seg reg from opcode */
3587179237Sjb		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
3588179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
3589179237Sjb		break;
3590179237Sjb
3591179237Sjb	/* memory or register operand to register */
3592179237Sjb	case MR:
3593253772Savg		if (vex_prefetch)
3594253772Savg			x->d86_got_modrm = 1;
3595179237Sjb		wbit = LONG_OPND;
3596179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3597179237Sjb		break;
3598179237Sjb
3599179237Sjb	case RM:
3600179237Sjb		wbit = LONG_OPND;
3601179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3602179237Sjb		break;
3603179237Sjb
3604179237Sjb	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
3605179237Sjb	case MM:
3606179237Sjb	case MMO:
3607179237Sjb#ifdef DIS_TEXT
3608179237Sjb		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3609179237Sjb#else
3610179237Sjb		wbit = LONG_OPND;
3611179237Sjb#endif
3612179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
3613179237Sjb		break;
3614179237Sjb
3615179237Sjb	case MMOIMPL:
3616179237Sjb#ifdef DIS_TEXT
3617179237Sjb		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3618179237Sjb#else
3619179237Sjb		wbit = LONG_OPND;
3620179237Sjb#endif
3621179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3622179237Sjb		if (mode != REG_ONLY)
3623179237Sjb			goto error;
3624179237Sjb
3625179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3626179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3627179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
3628179237Sjb		mode = 0;	/* change for memory access size... */
3629179237Sjb		break;
3630179237Sjb
3631179237Sjb	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
3632179237Sjb	case MMO3P:
3633179237Sjb		wbit = MM_OPND;
3634179237Sjb		goto xmm3p;
3635179237Sjb	case XMM3P:
3636179237Sjb		wbit = XMM_OPND;
3637179237Sjbxmm3p:
3638179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3639179237Sjb		if (mode != REG_ONLY)
3640179237Sjb			goto error;
3641179237Sjb
3642253772Savg		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
3643253772Savg		    1);
3644179237Sjb		NOMEM;
3645179237Sjb		break;
3646179237Sjb
3647253772Savg	case XMM3PM_66r:
3648253772Savg		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
3649253772Savg		    1, 0);
3650253772Savg		break;
3651253772Savg
3652179237Sjb	/* MMX/SIMD-Int predicated r32/mem to mm reg */
3653179237Sjb	case MMOPRM:
3654179237Sjb		wbit = LONG_OPND;
3655179237Sjb		w2 = MM_OPND;
3656179237Sjb		goto xmmprm;
3657179237Sjb	case XMMPRM:
3658253772Savg	case XMMPRM_66r:
3659179237Sjb		wbit = LONG_OPND;
3660179237Sjb		w2 = XMM_OPND;
3661179237Sjbxmmprm:
3662253772Savg		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
3663179237Sjb		break;
3664179237Sjb
3665179237Sjb	/* MMX/SIMD-Int predicated mm/mem to mm reg */
3666179237Sjb	case MMOPM:
3667253772Savg	case MMOPM_66o:
3668179237Sjb		wbit = w2 = MM_OPND;
3669179237Sjb		goto xmmprm;
3670179237Sjb
3671179237Sjb	/* MMX/SIMD-Int mm reg to r32 */
3672179237Sjb	case MMOM3:
3673179237Sjb		NOMEM;
3674179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3675179237Sjb		if (mode != REG_ONLY)
3676179237Sjb			goto error;
3677179237Sjb		wbit = MM_OPND;
3678179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
3679179237Sjb		break;
3680179237Sjb
3681179237Sjb	/* SIMD memory or xmm reg operand to xmm reg		*/
3682179237Sjb	case XMM:
3683253772Savg	case XMM_66o:
3684253772Savg	case XMM_66r:
3685179237Sjb	case XMMO:
3686179237Sjb	case XMMXIMPL:
3687179237Sjb		wbit = XMM_OPND;
3688179237Sjb		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3689179237Sjb
3690179237Sjb		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
3691179237Sjb			goto error;
3692179237Sjb
3693179237Sjb#ifdef DIS_TEXT
3694179237Sjb		/*
3695179237Sjb		 * movlps and movhlps share opcodes.  They differ in the
3696179237Sjb		 * addressing modes allowed for their operands.
3697179237Sjb		 * movhps and movlhps behave similarly.
3698179237Sjb		 */
3699179237Sjb		if (mode == REG_ONLY) {
3700179237Sjb			if (strcmp(dp->it_name, "movlps") == 0)
3701253772Savg				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
3702179237Sjb			else if (strcmp(dp->it_name, "movhps") == 0)
3703253772Savg				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
3704179237Sjb		}
3705179237Sjb#endif
3706179237Sjb		if (dp->it_adrmode == XMMXIMPL)
3707179237Sjb			mode = 0;	/* change for memory access size... */
3708179237Sjb		break;
3709179237Sjb
3710179237Sjb	/* SIMD xmm reg to memory or xmm reg */
3711179237Sjb	case XMMS:
3712179237Sjb	case XMMOS:
3713179237Sjb	case XMMMS:
3714179237Sjb	case XMMOMS:
3715179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3716179237Sjb#ifdef DIS_TEXT
3717179237Sjb		if ((strcmp(dp->it_name, "movlps") == 0 ||
3718179237Sjb		    strcmp(dp->it_name, "movhps") == 0 ||
3719179237Sjb		    strcmp(dp->it_name, "movntps") == 0) &&
3720179237Sjb		    mode == REG_ONLY)
3721179237Sjb			goto error;
3722179237Sjb#endif
3723179237Sjb		wbit = XMM_OPND;
3724179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
3725179237Sjb		break;
3726179237Sjb
3727179237Sjb	/* SIMD memory to xmm reg */
3728179237Sjb	case XMMM:
3729253772Savg	case XMMM_66r:
3730179237Sjb	case XMMOM:
3731179237Sjb		wbit = XMM_OPND;
3732179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3733179237Sjb#ifdef DIS_TEXT
3734179237Sjb		if (mode == REG_ONLY) {
3735179237Sjb			if (strcmp(dp->it_name, "movhps") == 0)
3736253772Savg				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
3737179237Sjb			else
3738179237Sjb				goto error;
3739179237Sjb		}
3740179237Sjb#endif
3741179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3742179237Sjb		break;
3743179237Sjb
3744179237Sjb	/* SIMD memory or r32 to xmm reg			*/
3745179237Sjb	case XMM3MX:
3746179237Sjb		wbit = LONG_OPND;
3747179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3748179237Sjb		break;
3749179237Sjb
3750179237Sjb	case XMM3MXS:
3751179237Sjb		wbit = LONG_OPND;
3752179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
3753179237Sjb		break;
3754179237Sjb
3755179237Sjb	/* SIMD memory or mm reg to xmm reg			*/
3756179237Sjb	case XMMOMX:
3757179237Sjb	/* SIMD mm to xmm */
3758179237Sjb	case XMMMX:
3759179237Sjb		wbit = MM_OPND;
3760179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3761179237Sjb		break;
3762179237Sjb
3763179237Sjb	/* SIMD memory or xmm reg to mm reg			*/
3764179237Sjb	case XMMXMM:
3765179237Sjb	case XMMOXMM:
3766179237Sjb	case XMMXM:
3767179237Sjb		wbit = XMM_OPND;
3768179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
3769179237Sjb		break;
3770179237Sjb
3771179237Sjb
3772179237Sjb	/* SIMD memory or xmm reg to r32			*/
3773179237Sjb	case XMMXM3:
3774179237Sjb		wbit = XMM_OPND;
3775179237Sjb		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
3776179237Sjb		break;
3777179237Sjb
3778179237Sjb	/* SIMD xmm to r32					*/
3779179237Sjb	case XMMX3:
3780179237Sjb	case XMMOX3:
3781179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
3782179237Sjb		if (mode != REG_ONLY)
3783179237Sjb			goto error;
3784179237Sjb		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3785179237Sjb		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
3786179237Sjb		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3787179237Sjb		NOMEM;
3788179237Sjb		break;
3789179237Sjb
3790179237Sjb	/* SIMD predicated memory or xmm reg with/to xmm reg */
3791179237Sjb	case XMMP:
3792253772Savg	case XMMP_66r:
3793253772Savg	case XMMP_66o:
3794179237Sjb	case XMMOPM:
3795179237Sjb		wbit = XMM_OPND;
3796253772Savg		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
3797253772Savg		    1);
3798179237Sjb
3799179237Sjb#ifdef DIS_TEXT
3800179237Sjb		/*
3801179237Sjb		 * cmpps and cmpss vary their instruction name based
3802179237Sjb		 * on the value of imm8.  Other XMMP instructions,
3803179237Sjb		 * such as shufps, require explicit specification of
3804179237Sjb		 * the predicate.
3805179237Sjb		 */
3806179237Sjb		if (dp->it_name[0] == 'c' &&
3807179237Sjb		    dp->it_name[1] == 'm' &&
3808179237Sjb		    dp->it_name[2] == 'p' &&
3809179237Sjb		    strlen(dp->it_name) == 5) {
3810179237Sjb			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
3811179237Sjb
3812179237Sjb			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
3813179237Sjb				goto error;
3814179237Sjb
3815253772Savg			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
3816253772Savg			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
3817179237Sjb			    OPLEN);
3818253772Savg			(void) strlcat(x->d86_mnem,
3819179237Sjb			    dp->it_name + strlen(dp->it_name) - 2,
3820179237Sjb			    OPLEN);
3821179237Sjb			x->d86_opnd[0] = x->d86_opnd[1];
3822179237Sjb			x->d86_opnd[1] = x->d86_opnd[2];
3823179237Sjb			x->d86_numopnds = 2;
3824179237Sjb		}
3825179237Sjb#endif
3826179237Sjb		break;
3827179237Sjb
3828253772Savg	case XMMX2I:
3829253772Savg		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
3830253772Savg		    1);
3831253772Savg		NOMEM;
3832253772Savg		break;
3833253772Savg
3834253772Savg	case XMM2I:
3835253772Savg		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
3836253772Savg		NOMEM;
3837253772Savg		break;
3838253772Savg
3839179237Sjb	/* immediate operand to accumulator */
3840179237Sjb	case IA:
3841179237Sjb		wbit = WBIT(opcode2);
3842179237Sjb		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3843179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3844179237Sjb		NOMEM;
3845179237Sjb		break;
3846179237Sjb
3847179237Sjb	/* memory or register operand to accumulator */
3848179237Sjb	case MA:
3849179237Sjb		wbit = WBIT(opcode2);
3850179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3851179237Sjb		dtrace_get_operand(x, mode, r_m, wbit, 0);
3852179237Sjb		break;
3853179237Sjb
3854179237Sjb	/* si register to di register used to reference memory		*/
3855179237Sjb	case SD:
3856179237Sjb#ifdef DIS_TEXT
3857179237Sjb		dtrace_check_override(x, 0);
3858179237Sjb		x->d86_numopnds = 2;
3859179237Sjb		if (addr_size == SIZE64) {
3860179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3861179237Sjb			    OPLEN);
3862179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3863179237Sjb			    OPLEN);
3864179237Sjb		} else if (addr_size == SIZE32) {
3865179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3866179237Sjb			    OPLEN);
3867179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3868179237Sjb			    OPLEN);
3869179237Sjb		} else {
3870179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3871179237Sjb			    OPLEN);
3872179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3873179237Sjb			    OPLEN);
3874179237Sjb		}
3875179237Sjb#endif
3876179237Sjb		wbit = LONG_OPND;
3877179237Sjb		break;
3878179237Sjb
3879179237Sjb	/* accumulator to di register				*/
3880179237Sjb	case AD:
3881179237Sjb		wbit = WBIT(opcode2);
3882179237Sjb#ifdef DIS_TEXT
3883179237Sjb		dtrace_check_override(x, 1);
3884179237Sjb		x->d86_numopnds = 2;
3885179237Sjb		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
3886179237Sjb		if (addr_size == SIZE64)
3887179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3888179237Sjb			    OPLEN);
3889179237Sjb		else if (addr_size == SIZE32)
3890179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3891179237Sjb			    OPLEN);
3892179237Sjb		else
3893179237Sjb			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3894179237Sjb			    OPLEN);
3895179237Sjb#endif
3896179237Sjb		break;
3897179237Sjb
3898179237Sjb	/* si register to accumulator				*/
3899179237Sjb	case SA:
3900179237Sjb		wbit = WBIT(opcode2);
3901179237Sjb#ifdef DIS_TEXT
3902179237Sjb		dtrace_check_override(x, 0);
3903179237Sjb		x->d86_numopnds = 2;
3904179237Sjb		if (addr_size == SIZE64)
3905179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3906179237Sjb			    OPLEN);
3907179237Sjb		else if (addr_size == SIZE32)
3908179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3909179237Sjb			    OPLEN);
3910179237Sjb		else
3911179237Sjb			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3912179237Sjb			    OPLEN);
3913179237Sjb		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3914179237Sjb#endif
3915179237Sjb		break;
3916179237Sjb
3917179237Sjb	/*
3918179237Sjb	 * single operand, a 16/32 bit displacement
3919179237Sjb	 */
3920179237Sjb	case D:
3921179237Sjb		wbit = LONG_OPND;
3922179237Sjb		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3923179237Sjb		NOMEM;
3924179237Sjb		break;
3925179237Sjb
3926179237Sjb	/* jmp/call indirect to memory or register operand		*/
3927179237Sjb	case INM:
3928179237Sjb#ifdef DIS_TEXT
3929179237Sjb		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
3930179237Sjb#endif
3931179237Sjb		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3932179237Sjb		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
3933179237Sjb		wbit = LONG_OPND;
3934179237Sjb		break;
3935179237Sjb
3936179237Sjb	/*
3937179237Sjb	 * for long jumps and long calls -- a new code segment
3938179237Sjb	 * register and an offset in IP -- stored in object
3939179237Sjb	 * code in reverse order. Note - not valid in amd64
3940179237Sjb	 */
3941179237Sjb	case SO:
3942179237Sjb		dtrace_check_override(x, 1);
3943179237Sjb		wbit = LONG_OPND;
3944179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
3945179237Sjb#ifdef DIS_TEXT
3946179237Sjb		x->d86_opnd[1].d86_mode = MODE_SIGNED;
3947179237Sjb#endif
3948179237Sjb		/* will now get segment operand */
3949179237Sjb		dtrace_imm_opnd(x, wbit, 2, 0);
3950179237Sjb		break;
3951179237Sjb
3952179237Sjb	/*
3953179237Sjb	 * jmp/call. single operand, 8 bit displacement.
3954179237Sjb	 * added to current EIP in 'compofff'
3955179237Sjb	 */
3956179237Sjb	case BD:
3957179237Sjb		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
3958179237Sjb		NOMEM;
3959179237Sjb		break;
3960179237Sjb
3961179237Sjb	/* single 32/16 bit immediate operand			*/
3962179237Sjb	case I:
3963179237Sjb		wbit = LONG_OPND;
3964179237Sjb		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3965179237Sjb		break;
3966179237Sjb
3967179237Sjb	/* single 8 bit immediate operand			*/
3968179237Sjb	case Ib:
3969179237Sjb		wbit = LONG_OPND;
3970179237Sjb		dtrace_imm_opnd(x, wbit, 1, 0);
3971179237Sjb		break;
3972179237Sjb
3973179237Sjb	case ENTER:
3974179237Sjb		wbit = LONG_OPND;
3975179237Sjb		dtrace_imm_opnd(x, wbit, 2, 0);
3976179237Sjb		dtrace_imm_opnd(x, wbit, 1, 1);
3977179237Sjb		switch (opnd_size) {
3978179237Sjb		case SIZE64:
3979179237Sjb			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
3980179237Sjb			break;
3981179237Sjb		case SIZE32:
3982179237Sjb			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
3983179237Sjb			break;
3984179237Sjb		case SIZE16:
3985179237Sjb			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
3986179237Sjb			break;
3987179237Sjb		}
3988179237Sjb
3989179237Sjb		break;
3990179237Sjb
3991179237Sjb	/* 16-bit immediate operand */
3992179237Sjb	case RET:
3993179237Sjb		wbit = LONG_OPND;
3994179237Sjb		dtrace_imm_opnd(x, wbit, 2, 0);
3995179237Sjb		break;
3996179237Sjb
3997179237Sjb	/* single 8 bit port operand				*/
3998179237Sjb	case P:
3999179237Sjb		dtrace_check_override(x, 0);
4000179237Sjb		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4001179237Sjb		NOMEM;
4002179237Sjb		break;
4003179237Sjb
4004179237Sjb	/* single operand, dx register (variable port instruction) */
4005179237Sjb	case V:
4006179237Sjb		x->d86_numopnds = 1;
4007179237Sjb		dtrace_check_override(x, 0);
4008179237Sjb#ifdef DIS_TEXT
4009179237Sjb		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
4010179237Sjb#endif
4011179237Sjb		NOMEM;
4012179237Sjb		break;
4013179237Sjb
4014179237Sjb	/*
4015179237Sjb	 * The int instruction, which has two forms:
4016179237Sjb	 * int 3 (breakpoint) or
4017179237Sjb	 * int n, where n is indicated in the subsequent
4018179237Sjb	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
4019179237Sjb	 * where, although the 3 looks  like an operand,
4020179237Sjb	 * it is implied by the opcode. It must be converted
4021179237Sjb	 * to the correct base and output.
4022179237Sjb	 */
4023179237Sjb	case INT3:
4024179237Sjb#ifdef DIS_TEXT
4025179237Sjb		x->d86_numopnds = 1;
4026179237Sjb		x->d86_opnd[0].d86_mode = MODE_SIGNED;
4027179237Sjb		x->d86_opnd[0].d86_value_size = 1;
4028179237Sjb		x->d86_opnd[0].d86_value = 3;
4029179237Sjb#endif
4030179237Sjb		NOMEM;
4031179237Sjb		break;
4032179237Sjb
4033179237Sjb	/* single 8 bit immediate operand			*/
4034179237Sjb	case INTx:
4035179237Sjb		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4036179237Sjb		NOMEM;
4037179237Sjb		break;
4038179237Sjb
4039179237Sjb	/* an unused byte must be discarded */
4040179237Sjb	case U:
4041179237Sjb		if (x->d86_get_byte(x->d86_data) < 0)
4042179237Sjb			goto error;
4043179237Sjb		x->d86_len++;
4044179237Sjb		NOMEM;
4045179237Sjb		break;
4046179237Sjb
4047179237Sjb	case CBW:
4048179237Sjb#ifdef DIS_TEXT
4049179237Sjb		if (opnd_size == SIZE16)
4050253772Savg			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
4051179237Sjb		else if (opnd_size == SIZE32)
4052253772Savg			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
4053179237Sjb		else
4054253772Savg			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
4055179237Sjb#endif
4056179237Sjb		wbit = LONG_OPND;
4057179237Sjb		NOMEM;
4058179237Sjb		break;
4059179237Sjb
4060179237Sjb	case CWD:
4061179237Sjb#ifdef DIS_TEXT
4062179237Sjb		if (opnd_size == SIZE16)
4063253772Savg			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
4064179237Sjb		else if (opnd_size == SIZE32)
4065253772Savg			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
4066179237Sjb		else
4067253772Savg			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
4068179237Sjb#endif
4069179237Sjb		wbit = LONG_OPND;
4070179237Sjb		NOMEM;
4071179237Sjb		break;
4072179237Sjb
4073179237Sjb	case XMMSFNC:
4074179237Sjb		/*
4075179237Sjb		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
4076179237Sjb		 * REG_ONLY, mnemonic should be 'clflush'.
4077179237Sjb		 */
4078179237Sjb		dtrace_get_modrm(x, &mode, &reg, &r_m);
4079179237Sjb
4080179237Sjb		/* sfence doesn't take operands */
4081179237Sjb#ifdef DIS_TEXT
4082179237Sjb		if (mode == REG_ONLY) {
4083253772Savg			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
4084179237Sjb		} else {
4085253772Savg			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
4086179237Sjb			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4087179237Sjb			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4088179237Sjb			NOMEM;
4089179237Sjb		}
4090179237Sjb#else
4091179237Sjb		if (mode != REG_ONLY) {
4092179237Sjb			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4093253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4094179237Sjb			NOMEM;
4095179237Sjb		}
4096179237Sjb#endif
4097179237Sjb		break;
4098179237Sjb
4099179237Sjb	/*
4100179237Sjb	 * no disassembly, the mnemonic was all there was so go on
4101179237Sjb	 */
4102179237Sjb	case NORM:
4103179237Sjb		if (dp->it_invalid32 && cpu_mode != SIZE64)
4104179237Sjb			goto error;
4105179237Sjb		NOMEM;
4106179237Sjb		/*FALLTHROUGH*/
4107179237Sjb	case IMPLMEM:
4108179237Sjb		break;
4109179237Sjb
4110179237Sjb	case XMMFENCE:
4111179237Sjb		/*
4112253772Savg		 * XRSTOR and LFENCE share the same opcode but differ in mode
4113179237Sjb		 */
4114253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4115179237Sjb
4116253772Savg		if (mode == REG_ONLY) {
4117253772Savg			/*
4118253772Savg			 * Only the following exact byte sequences are allowed:
4119253772Savg			 *
4120253772Savg			 * 	0f ae e8	lfence
4121253772Savg			 * 	0f ae f0	mfence
4122253772Savg			 */
4123253772Savg			if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
4124253772Savg			    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
4125253772Savg				goto error;
4126253772Savg		} else {
4127253772Savg#ifdef DIS_TEXT
4128253772Savg			(void) strncpy(x->d86_mnem, "xrstor", OPLEN);
4129253772Savg#endif
4130253772Savg			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4131253772Savg			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4132253772Savg		}
4133179237Sjb		break;
4134179237Sjb
4135179237Sjb	/* float reg */
4136179237Sjb	case F:
4137179237Sjb#ifdef DIS_TEXT
4138179237Sjb		x->d86_numopnds = 1;
4139179237Sjb		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
4140179237Sjb		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
4141179237Sjb#endif
4142179237Sjb		NOMEM;
4143179237Sjb		break;
4144179237Sjb
4145179237Sjb	/* float reg to float reg, with ret bit present */
4146179237Sjb	case FF:
4147179237Sjb		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
4148179237Sjb		/*FALLTHROUGH*/
4149179237Sjb	case FFC:				/* case for vbit always = 0 */
4150179237Sjb#ifdef DIS_TEXT
4151179237Sjb		x->d86_numopnds = 2;
4152179237Sjb		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
4153179237Sjb		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
4154179237Sjb		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
4155179237Sjb#endif
4156179237Sjb		NOMEM;
4157179237Sjb		break;
4158179237Sjb
4159253772Savg	/* AVX instructions */
4160253772Savg	case VEX_MO:
4161253772Savg		/* op(ModR/M.r/m) */
4162253772Savg		x->d86_numopnds = 1;
4163253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4164253772Savg#ifdef DIS_TEXT
4165253772Savg		if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
4166253772Savg			(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
4167253772Savg#endif
4168253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4169253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 0);
4170253772Savg		break;
4171253772Savg	case VEX_RMrX:
4172253772Savg		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
4173253772Savg		x->d86_numopnds = 3;
4174253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4175253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4176253772Savg
4177253772Savg		if (mode != REG_ONLY) {
4178253772Savg			if ((dp == &dis_opAVXF20F[0x10]) ||
4179253772Savg			    (dp == &dis_opAVXF30F[0x10])) {
4180253772Savg				/* vmovsd <m64>, <xmm> */
4181253772Savg				/* or vmovss <m64>, <xmm> */
4182253772Savg				x->d86_numopnds = 2;
4183253772Savg				goto L_VEX_MX;
4184253772Savg			}
4185253772Savg		}
4186253772Savg
4187253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4188253772Savg		/*
4189253772Savg		 * VEX prefix uses the 1's complement form to encode the
4190253772Savg		 * XMM/YMM regs
4191253772Savg		 */
4192253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4193253772Savg
4194253772Savg		if ((dp == &dis_opAVXF20F[0x2A]) ||
4195253772Savg		    (dp == &dis_opAVXF30F[0x2A])) {
4196253772Savg			/*
4197253772Savg			 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
4198253772Savg			 * <xmm>, <xmm>
4199253772Savg			 */
4200253772Savg			wbit = LONG_OPND;
4201253772Savg		}
4202253772Savg#ifdef DIS_TEXT
4203253772Savg		else if ((mode == REG_ONLY) &&
4204253772Savg		    (dp == &dis_opAVX0F[0x1][0x6])) {	/* vmovlhps */
4205253772Savg			(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
4206253772Savg		} else if ((mode == REG_ONLY) &&
4207253772Savg		    (dp == &dis_opAVX0F[0x1][0x2])) {	/* vmovhlps */
4208253772Savg			(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
4209253772Savg		}
4210253772Savg#endif
4211253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 0);
4212253772Savg
4213253772Savg		break;
4214253772Savg
4215253772Savg	case VEX_RRX:
4216253772Savg		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
4217253772Savg		x->d86_numopnds = 3;
4218253772Savg
4219253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4220253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4221253772Savg
4222253772Savg		if (mode != REG_ONLY) {
4223253772Savg			if ((dp == &dis_opAVXF20F[0x11]) ||
4224253772Savg			    (dp == &dis_opAVXF30F[0x11])) {
4225253772Savg				/* vmovsd <xmm>, <m64> */
4226253772Savg				/* or vmovss <xmm>, <m64> */
4227253772Savg				x->d86_numopnds = 2;
4228253772Savg				goto L_VEX_RM;
4229253772Savg			}
4230253772Savg		}
4231253772Savg
4232253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 2);
4233253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4234253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4235253772Savg		break;
4236253772Savg
4237253772Savg	case VEX_RMRX:
4238253772Savg		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
4239253772Savg		x->d86_numopnds = 4;
4240253772Savg
4241253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4242253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4243253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
4244253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
4245253772Savg		if (dp == &dis_opAVX660F3A[0x18]) {
4246253772Savg			/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
4247253772Savg			dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
4248253772Savg		} else if ((dp == &dis_opAVX660F3A[0x20]) ||
4249253772Savg		    (dp == & dis_opAVX660F[0xC4])) {
4250253772Savg			/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
4251253772Savg			/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
4252253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4253253772Savg		} else if (dp == &dis_opAVX660F3A[0x22]) {
4254253772Savg			/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
4255253772Savg#ifdef DIS_TEXT
4256253772Savg			if (vex_W)
4257253772Savg				x->d86_mnem[6] = 'q';
4258253772Savg#endif
4259253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4260253772Savg		} else {
4261253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 1);
4262253772Savg		}
4263253772Savg
4264253772Savg		/* one byte immediate number */
4265253772Savg		dtrace_imm_opnd(x, wbit, 1, 0);
4266253772Savg
4267253772Savg		/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
4268253772Savg		if ((dp == &dis_opAVX660F3A[0x4A]) ||
4269253772Savg		    (dp == &dis_opAVX660F3A[0x4B]) ||
4270253772Savg		    (dp == &dis_opAVX660F3A[0x4C])) {
4271253772Savg#ifdef DIS_TEXT
4272253772Savg			int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
4273253772Savg#endif
4274253772Savg			x->d86_opnd[0].d86_mode = MODE_NONE;
4275253772Savg#ifdef DIS_TEXT
4276253772Savg			if (vex_L)
4277253772Savg				(void) strncpy(x->d86_opnd[0].d86_opnd,
4278253772Savg				    dis_YMMREG[regnum], OPLEN);
4279253772Savg			else
4280253772Savg				(void) strncpy(x->d86_opnd[0].d86_opnd,
4281253772Savg				    dis_XMMREG[regnum], OPLEN);
4282253772Savg#endif
4283253772Savg		}
4284253772Savg		break;
4285253772Savg
4286253772Savg	case VEX_MX:
4287253772Savg		/* ModR/M.reg := op(ModR/M.rm) */
4288253772Savg		x->d86_numopnds = 2;
4289253772Savg
4290253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4291253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4292253772SavgL_VEX_MX:
4293253772Savg
4294253772Savg		if ((dp == &dis_opAVXF20F[0xE6]) ||
4295253772Savg		    (dp == &dis_opAVX660F[0x5A]) ||
4296253772Savg		    (dp == &dis_opAVX660F[0xE6])) {
4297253772Savg			/* vcvtpd2dq <ymm>, <xmm> */
4298253772Savg			/* or vcvtpd2ps <ymm>, <xmm> */
4299253772Savg			/* or vcvttpd2dq <ymm>, <xmm> */
4300253772Savg			dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
4301253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 0);
4302253772Savg		} else if ((dp == &dis_opAVXF30F[0xE6]) ||
4303253772Savg		    (dp == &dis_opAVX0F[0x5][0xA])) {
4304253772Savg			/* vcvtdq2pd <xmm>, <ymm> */
4305253772Savg			/* or vcvtps2pd <xmm>, <ymm> */
4306253772Savg			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4307253772Savg			dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
4308253772Savg		} else if (dp == &dis_opAVX660F[0x6E]) {
4309253772Savg			/* vmovd/q <reg/mem 32/64>, <xmm> */
4310253772Savg#ifdef DIS_TEXT
4311253772Savg			if (vex_W)
4312253772Savg				x->d86_mnem[4] = 'q';
4313253772Savg#endif
4314253772Savg			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4315253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4316253772Savg		} else {
4317253772Savg			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4318253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 0);
4319253772Savg		}
4320253772Savg
4321253772Savg		break;
4322253772Savg
4323253772Savg	case VEX_MXI:
4324253772Savg		/* ModR/M.reg := op(ModR/M.rm, imm8) */
4325253772Savg		x->d86_numopnds = 3;
4326253772Savg
4327253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4328253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4329253772Savg
4330253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4331253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 1);
4332253772Savg
4333253772Savg		/* one byte immediate number */
4334253772Savg		dtrace_imm_opnd(x, wbit, 1, 0);
4335253772Savg		break;
4336253772Savg
4337253772Savg	case VEX_XXI:
4338253772Savg		/* VEX.vvvv := op(ModR/M.rm, imm8) */
4339253772Savg		x->d86_numopnds = 3;
4340253772Savg
4341253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4342253772Savg#ifdef DIS_TEXT
4343253772Savg		(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
4344253772Savg		    OPLEN);
4345253772Savg#endif
4346253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4347253772Savg
4348253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
4349253772Savg		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
4350253772Savg
4351253772Savg		/* one byte immediate number */
4352253772Savg		dtrace_imm_opnd(x, wbit, 1, 0);
4353253772Savg		break;
4354253772Savg
4355253772Savg	case VEX_MR:
4356253772Savg		/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
4357253772Savg		if (dp == &dis_opAVX660F[0xC5]) {
4358253772Savg			/* vpextrw <imm8>, <xmm>, <reg> */
4359253772Savg			x->d86_numopnds = 2;
4360253772Savg			vbit = 2;
4361253772Savg		} else {
4362253772Savg			x->d86_numopnds = 2;
4363253772Savg			vbit = 1;
4364253772Savg		}
4365253772Savg
4366253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4367253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4368253772Savg		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
4369253772Savg		dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
4370253772Savg
4371253772Savg		if (vbit == 2)
4372253772Savg			dtrace_imm_opnd(x, wbit, 1, 0);
4373253772Savg
4374253772Savg		break;
4375253772Savg
4376253772Savg	case VEX_RRI:
4377253772Savg		/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
4378253772Savg		x->d86_numopnds = 2;
4379253772Savg
4380253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4381253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4382253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4383253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 0);
4384253772Savg		break;
4385253772Savg
4386253772Savg	case VEX_RX:
4387253772Savg		/* ModR/M.rm := op(ModR/M.reg) */
4388253772Savg		if (dp == &dis_opAVX660F3A[0x19]) {	/* vextractf128 */
4389253772Savg			x->d86_numopnds = 3;
4390253772Savg
4391253772Savg			dtrace_get_modrm(x, &mode, &reg, &r_m);
4392253772Savg			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4393253772Savg
4394253772Savg			dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
4395253772Savg			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4396253772Savg
4397253772Savg			/* one byte immediate number */
4398253772Savg			dtrace_imm_opnd(x, wbit, 1, 0);
4399253772Savg			break;
4400253772Savg		}
4401253772Savg
4402253772Savg		x->d86_numopnds = 2;
4403253772Savg
4404253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4405253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4406253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 1);
4407253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4408253772Savg		break;
4409253772Savg
4410253772Savg	case VEX_RR:
4411253772Savg		/* ModR/M.rm := op(ModR/M.reg) */
4412253772Savg		x->d86_numopnds = 2;
4413253772Savg
4414253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4415253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4416253772Savg
4417253772Savg		if (dp == &dis_opAVX660F[0x7E]) {
4418253772Savg			/* vmovd/q <reg/mem 32/64>, <xmm> */
4419253772Savg#ifdef DIS_TEXT
4420253772Savg			if (vex_W)
4421253772Savg				x->d86_mnem[4] = 'q';
4422253772Savg#endif
4423253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4424253772Savg		} else
4425253772Savg			dtrace_get_operand(x, mode, r_m, wbit, 1);
4426253772Savg
4427253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4428253772Savg		break;
4429253772Savg
4430253772Savg	case VEX_RRi:
4431253772Savg		/* ModR/M.rm := op(ModR/M.reg, imm) */
4432253772Savg		x->d86_numopnds = 3;
4433253772Savg
4434253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4435253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4436253772Savg
4437253772Savg#ifdef DIS_TEXT
4438253772Savg		if (dp == &dis_opAVX660F3A[0x16]) {
4439253772Savg			/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
4440253772Savg			if (vex_W)
4441253772Savg				x->d86_mnem[6] = 'q';
4442253772Savg		}
4443253772Savg#endif
4444253772Savg		dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
4445253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4446253772Savg
4447253772Savg		/* one byte immediate number */
4448253772Savg		dtrace_imm_opnd(x, wbit, 1, 0);
4449253772Savg		break;
4450253772Savg
4451253772Savg	case VEX_RM:
4452253772Savg		/* ModR/M.rm := op(ModR/M.reg) */
4453253772Savg		if (dp == &dis_opAVX660F3A[0x17]) {	/* vextractps */
4454253772Savg			x->d86_numopnds = 3;
4455253772Savg
4456253772Savg			dtrace_get_modrm(x, &mode, &reg, &r_m);
4457253772Savg			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4458253772Savg
4459253772Savg			dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
4460253772Savg			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4461253772Savg			/* one byte immediate number */
4462253772Savg			dtrace_imm_opnd(x, wbit, 1, 0);
4463253772Savg			break;
4464253772Savg		}
4465253772Savg		x->d86_numopnds = 2;
4466253772Savg
4467253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4468253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4469253772SavgL_VEX_RM:
4470253772Savg		vbit = 1;
4471253772Savg		dtrace_get_operand(x, mode, r_m, wbit, vbit);
4472253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
4473253772Savg
4474253772Savg		break;
4475253772Savg
4476253772Savg	case VEX_RRM:
4477253772Savg		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
4478253772Savg		x->d86_numopnds = 3;
4479253772Savg
4480253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4481253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4482253772Savg		dtrace_get_operand(x, mode, r_m, wbit, 2);
4483253772Savg		/* VEX use the 1's complement form encode the XMM/YMM regs */
4484253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4485253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4486253772Savg		break;
4487253772Savg
4488253772Savg	case VEX_RMX:
4489253772Savg		/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
4490253772Savg		x->d86_numopnds = 3;
4491253772Savg
4492253772Savg		dtrace_get_modrm(x, &mode, &reg, &r_m);
4493253772Savg		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4494253772Savg		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4495253772Savg		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4496253772Savg		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
4497253772Savg		break;
4498253772Savg
4499253772Savg	case VEX_NONE:
4500253772Savg#ifdef DIS_TEXT
4501253772Savg		if (vex_L)
4502253772Savg			(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
4503253772Savg#endif
4504253772Savg		break;
4505179237Sjb	/* an invalid op code */
4506179237Sjb	case AM:
4507179237Sjb	case DM:
4508179237Sjb	case OVERRIDE:
4509179237Sjb	case PREFIX:
4510179237Sjb	case UNKNOWN:
4511179237Sjb		NOMEM;
4512179237Sjb	default:
4513179237Sjb		goto error;
4514179237Sjb	} /* end switch */
4515179237Sjb	if (x->d86_error)
4516179237Sjb		goto error;
4517179237Sjb
4518179237Sjbdone:
4519179237Sjb#ifdef DIS_MEM
4520179237Sjb	/*
4521179237Sjb	 * compute the size of any memory accessed by the instruction
4522179237Sjb	 */
4523179237Sjb	if (x->d86_memsize != 0) {
4524179237Sjb		return (0);
4525179237Sjb	} else if (dp->it_stackop) {
4526179237Sjb		switch (opnd_size) {
4527179237Sjb		case SIZE16:
4528179237Sjb			x->d86_memsize = 2;
4529179237Sjb			break;
4530179237Sjb		case SIZE32:
4531179237Sjb			x->d86_memsize = 4;
4532179237Sjb			break;
4533179237Sjb		case SIZE64:
4534179237Sjb			x->d86_memsize = 8;
4535179237Sjb			break;
4536179237Sjb		}
4537179237Sjb	} else if (nomem || mode == REG_ONLY) {
4538179237Sjb		x->d86_memsize = 0;
4539179237Sjb
4540179237Sjb	} else if (dp->it_size != 0) {
4541179237Sjb		/*
4542179237Sjb		 * In 64 bit mode descriptor table entries
4543179237Sjb		 * go up to 10 bytes and popf/pushf are always 8 bytes
4544179237Sjb		 */
4545179237Sjb		if (x->d86_mode == SIZE64 && dp->it_size == 6)
4546179237Sjb			x->d86_memsize = 10;
4547179237Sjb		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
4548179237Sjb		    (opcode2 == 0xc || opcode2 == 0xd))
4549179237Sjb			x->d86_memsize = 8;
4550179237Sjb		else
4551179237Sjb			x->d86_memsize = dp->it_size;
4552179237Sjb
4553179237Sjb	} else if (wbit == 0) {
4554179237Sjb		x->d86_memsize = 1;
4555179237Sjb
4556179237Sjb	} else if (wbit == LONG_OPND) {
4557179237Sjb		if (opnd_size == SIZE64)
4558179237Sjb			x->d86_memsize = 8;
4559179237Sjb		else if (opnd_size == SIZE32)
4560179237Sjb			x->d86_memsize = 4;
4561179237Sjb		else
4562179237Sjb			x->d86_memsize = 2;
4563179237Sjb
4564179237Sjb	} else if (wbit == SEG_OPND) {
4565179237Sjb		x->d86_memsize = 4;
4566179237Sjb
4567179237Sjb	} else {
4568179237Sjb		x->d86_memsize = 8;
4569179237Sjb	}
4570179237Sjb#endif
4571179237Sjb	return (0);
4572179237Sjb
4573179237Sjberror:
4574179237Sjb#ifdef DIS_TEXT
4575253772Savg	(void) strlcat(x->d86_mnem, "undef", OPLEN);
4576179237Sjb#endif
4577179237Sjb	return (1);
4578179237Sjb}
4579179237Sjb
4580179237Sjb#ifdef DIS_TEXT
4581179237Sjb
4582179237Sjb/*
4583179237Sjb * Some instructions should have immediate operands printed
4584179237Sjb * as unsigned integers. We compare against this table.
4585179237Sjb */
4586179237Sjbstatic char *unsigned_ops[] = {
4587179237Sjb	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
4588179237Sjb	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
4589179237Sjb	0
4590179237Sjb};
4591179237Sjb
4592253772Savg
4593179237Sjbstatic int
4594179237Sjbisunsigned_op(char *opcode)
4595179237Sjb{
4596179237Sjb	char *where;
4597179237Sjb	int i;
4598179237Sjb	int is_unsigned = 0;
4599179237Sjb
4600179237Sjb	/*
4601179237Sjb	 * Work back to start of last mnemonic, since we may have
4602179237Sjb	 * prefixes on some opcodes.
4603179237Sjb	 */
4604179237Sjb	where = opcode + strlen(opcode) - 1;
4605179237Sjb	while (where > opcode && *where != ' ')
4606179237Sjb		--where;
4607179237Sjb	if (*where == ' ')
4608179237Sjb		++where;
4609179237Sjb
4610179237Sjb	for (i = 0; unsigned_ops[i]; ++i) {
4611179237Sjb		if (strncmp(where, unsigned_ops[i],
4612179237Sjb		    strlen(unsigned_ops[i])))
4613179237Sjb			continue;
4614179237Sjb		is_unsigned = 1;
4615179237Sjb		break;
4616179237Sjb	}
4617179237Sjb	return (is_unsigned);
4618179237Sjb}
4619179237Sjb
4620253772Savg/*
4621253772Savg * Print a numeric immediate into end of buf, maximum length buflen.
4622253772Savg * The immediate may be an address or a displacement.  Mask is set
4623253772Savg * for address size.  If the immediate is a "small negative", or
4624253772Savg * if it's a negative displacement of any magnitude, print as -<absval>.
4625253772Savg * Respect the "octal" flag.  "Small negative" is defined as "in the
4626253772Savg * interval [NEG_LIMIT, 0)".
4627253772Savg *
4628253772Savg * Also, "isunsigned_op()" instructions never print negatives.
4629253772Savg *
4630253772Savg * Return whether we decided to print a negative value or not.
4631253772Savg */
4632253772Savg
4633253772Savg#define	NEG_LIMIT	-255
4634253772Savgenum {IMM, DISP};
4635253772Savgenum {POS, TRY_NEG};
4636253772Savg
4637253772Savgstatic int
4638253772Savgprint_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
4639253772Savg    size_t buflen, int disp, int try_neg)
4640253772Savg{
4641253772Savg	int curlen;
4642253772Savg	int64_t sv = (int64_t)usv;
4643253772Savg	int octal = dis->d86_flags & DIS_F_OCTAL;
4644253772Savg
4645253772Savg	curlen = strlen(buf);
4646253772Savg
4647253772Savg	if (try_neg == TRY_NEG && sv < 0 &&
4648253772Savg	    (disp || sv >= NEG_LIMIT) &&
4649253772Savg	    !isunsigned_op(dis->d86_mnem)) {
4650253772Savg		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4651253772Savg		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
4652253772Savg		return (1);
4653253772Savg	} else {
4654253772Savg		if (disp == DISP)
4655253772Savg			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4656253772Savg			    octal ? "+0%llo" : "+0x%llx", usv & mask);
4657253772Savg		else
4658253772Savg			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4659253772Savg			    octal ? "0%llo" : "0x%llx", usv & mask);
4660253772Savg		return (0);
4661253772Savg
4662253772Savg	}
4663253772Savg}
4664253772Savg
4665253772Savg
4666253772Savgstatic int
4667253772Savglog2(int size)
4668253772Savg{
4669253772Savg	switch (size) {
4670253772Savg	case 1: return (0);
4671253772Savg	case 2: return (1);
4672253772Savg	case 4: return (2);
4673253772Savg	case 8: return (3);
4674253772Savg	}
4675253772Savg	return (0);
4676253772Savg}
4677253772Savg
4678179237Sjb/* ARGSUSED */
4679179237Sjbvoid
4680253772Savgdtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
4681179237Sjb    size_t buflen)
4682179237Sjb{
4683253772Savg	uint64_t reltgt = 0;
4684253772Savg	uint64_t tgt = 0;
4685253772Savg	int curlen;
4686253772Savg	int (*lookup)(void *, uint64_t, char *, size_t);
4687179237Sjb	int i;
4688253772Savg	int64_t sv;
4689253772Savg	uint64_t usv, mask, save_mask, save_usv;
4690253772Savg	static uint64_t masks[] =
4691253772Savg	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
4692253772Savg	save_usv = 0;
4693179237Sjb
4694253772Savg	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
4695179237Sjb
4696179237Sjb	/*
4697179237Sjb	 * For PC-relative jumps, the pc is really the next pc after executing
4698179237Sjb	 * this instruction, so increment it appropriately.
4699179237Sjb	 */
4700179237Sjb	pc += dis->d86_len;
4701179237Sjb
4702179237Sjb	for (i = 0; i < dis->d86_numopnds; i++) {
4703179237Sjb		d86opnd_t *op = &dis->d86_opnd[i];
4704179237Sjb
4705179237Sjb		if (i != 0)
4706179237Sjb			(void) strlcat(buf, ",", buflen);
4707179237Sjb
4708179237Sjb		(void) strlcat(buf, op->d86_prefix, buflen);
4709179237Sjb
4710253772Savg		/*
4711253772Savg		 * sv is for the signed, possibly-truncated immediate or
4712253772Savg		 * displacement; usv retains the original size and
4713253772Savg		 * unsignedness for symbol lookup.
4714253772Savg		 */
4715179237Sjb
4716253772Savg		sv = usv = op->d86_value;
4717253772Savg
4718253772Savg		/*
4719253772Savg		 * About masks: for immediates that represent
4720253772Savg		 * addresses, the appropriate display size is
4721253772Savg		 * the effective address size of the instruction.
4722253772Savg		 * This includes MODE_OFFSET, MODE_IPREL, and
4723253772Savg		 * MODE_RIPREL.  Immediates that are simply
4724253772Savg		 * immediate values should display in the operand's
4725253772Savg		 * size, however, since they don't represent addresses.
4726253772Savg		 */
4727253772Savg
4728253772Savg		/* d86_addr_size is SIZEnn, which is log2(real size) */
4729253772Savg		mask = masks[dis->d86_addr_size];
4730253772Savg
4731253772Savg		/* d86_value_size and d86_imm_bytes are in bytes */
4732253772Savg		if (op->d86_mode == MODE_SIGNED ||
4733253772Savg		    op->d86_mode == MODE_IMPLIED)
4734253772Savg			mask = masks[log2(op->d86_value_size)];
4735253772Savg
4736179237Sjb		switch (op->d86_mode) {
4737179237Sjb
4738179237Sjb		case MODE_NONE:
4739179237Sjb
4740179237Sjb			(void) strlcat(buf, op->d86_opnd, buflen);
4741179237Sjb			break;
4742179237Sjb
4743179237Sjb		case MODE_SIGNED:
4744179237Sjb		case MODE_IMPLIED:
4745179237Sjb		case MODE_OFFSET:
4746179237Sjb
4747253772Savg			tgt = usv;
4748253772Savg
4749179237Sjb			if (dis->d86_seg_prefix)
4750179237Sjb				(void) strlcat(buf, dis->d86_seg_prefix,
4751179237Sjb				    buflen);
4752179237Sjb
4753179237Sjb			if (op->d86_mode == MODE_SIGNED ||
4754253772Savg			    op->d86_mode == MODE_IMPLIED) {
4755179237Sjb				(void) strlcat(buf, "$", buflen);
4756253772Savg			}
4757179237Sjb
4758253772Savg			if (print_imm(dis, usv, mask, buf, buflen,
4759253772Savg			    IMM, TRY_NEG) &&
4760253772Savg			    (op->d86_mode == MODE_SIGNED ||
4761253772Savg			    op->d86_mode == MODE_IMPLIED)) {
4762253772Savg
4763253772Savg				/*
4764253772Savg				 * We printed a negative value for an
4765253772Savg				 * immediate that wasn't a
4766253772Savg				 * displacement.  Note that fact so we can
4767253772Savg				 * print the positive value as an
4768253772Savg				 * annotation.
4769253772Savg				 */
4770253772Savg
4771253772Savg				save_usv = usv;
4772253772Savg				save_mask = mask;
4773179237Sjb			}
4774179237Sjb			(void) strlcat(buf, op->d86_opnd, buflen);
4775253772Savg
4776179237Sjb			break;
4777179237Sjb
4778179237Sjb		case MODE_IPREL:
4779253772Savg		case MODE_RIPREL:
4780179237Sjb
4781253772Savg			reltgt = pc + sv;
4782253772Savg
4783253772Savg			switch (mode) {
4784253772Savg			case SIZE16:
4785253772Savg				reltgt = (uint16_t)reltgt;
4786179237Sjb				break;
4787253772Savg			case SIZE32:
4788253772Savg				reltgt = (uint32_t)reltgt;
4789179237Sjb				break;
4790179237Sjb			}
4791179237Sjb
4792253772Savg			(void) print_imm(dis, usv, mask, buf, buflen,
4793253772Savg			    DISP, TRY_NEG);
4794179237Sjb
4795253772Savg			if (op->d86_mode == MODE_RIPREL)
4796253772Savg				(void) strlcat(buf, "(%rip)", buflen);
4797253772Savg			break;
4798253772Savg		}
4799253772Savg	}
4800179237Sjb
4801253772Savg	/*
4802253772Savg	 * The symbol lookups may result in false positives,
4803253772Savg	 * particularly on object files, where small numbers may match
4804253772Savg	 * the 0-relative non-relocated addresses of symbols.
4805253772Savg	 */
4806179237Sjb
4807253772Savg	lookup = dis->d86_sym_lookup;
4808253772Savg	if (tgt != 0) {
4809253772Savg		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
4810253772Savg		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
4811253772Savg			(void) strlcat(buf, "\t<", buflen);
4812253772Savg			curlen = strlen(buf);
4813253772Savg			lookup(dis->d86_data, tgt, buf + curlen,
4814253772Savg			    buflen - curlen);
4815179237Sjb			(void) strlcat(buf, ">", buflen);
4816253772Savg		}
4817179237Sjb
4818253772Savg		/*
4819253772Savg		 * If we printed a negative immediate above, print the
4820253772Savg		 * positive in case our heuristic was unhelpful
4821253772Savg		 */
4822253772Savg		if (save_usv) {
4823253772Savg			(void) strlcat(buf, "\t<", buflen);
4824253772Savg			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
4825253772Savg			    IMM, POS);
4826253772Savg			(void) strlcat(buf, ">", buflen);
4827179237Sjb		}
4828179237Sjb	}
4829253772Savg
4830253772Savg	if (reltgt != 0) {
4831253772Savg		/* Print symbol or effective address for reltgt */
4832253772Savg
4833253772Savg		(void) strlcat(buf, "\t<", buflen);
4834253772Savg		curlen = strlen(buf);
4835253772Savg		lookup(dis->d86_data, reltgt, buf + curlen,
4836253772Savg		    buflen - curlen);
4837253772Savg		(void) strlcat(buf, ">", buflen);
4838253772Savg	}
4839179237Sjb}
4840179237Sjb
4841179237Sjb#endif /* DIS_TEXT */
4842