dis_tables.c revision 253772
1893SN/A/*
26230SN/A *
3893SN/A * CDDL HEADER START
4893SN/A *
5893SN/A * The contents of this file are subject to the terms of the
6893SN/A * Common Development and Distribution License (the "License").
72362SN/A * You may not use this file except in compliance with the License.
8893SN/A *
92362SN/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10893SN/A * or http://www.opensolaris.org/os/licensing.
11893SN/A * See the License for the specific language governing permissions
12893SN/A * and limitations under the License.
13893SN/A *
14893SN/A * When distributing Covered Code, include this CDDL HEADER in each
15893SN/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16893SN/A * If applicable, add the following below this CDDL HEADER, with the
17893SN/A * fields enclosed by brackets "[]" replaced with your own identifying
18893SN/A * information: Portions Copyright [yyyy] [name of copyright owner]
19893SN/A *
20893SN/A * CDDL HEADER END
212362SN/A */
222362SN/A/*
232362SN/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24893SN/A */
25893SN/A
26893SN/A/*
27893SN/A * Copyright (c) 2010, Intel Corporation.
28893SN/A * All rights reserved.
29893SN/A */
3013050Schegar
31893SN/A/*	Copyright (c) 1988 AT&T	*/
32893SN/A/*	  All Rights Reserved  	*/
33893SN/A
34893SN/A/*
35893SN/A * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/dis_tables.c 253772 2013-07-29 16:56:38Z avg $
36893SN/A */
37893SN/A
38893SN/A#include	"dis_tables.h"
39893SN/A
40893SN/A/* BEGIN CSTYLED */
41893SN/A
42893SN/A/*
43893SN/A * Disassembly begins in dis_distable, which is equivalent to the One-byte
44893SN/A * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
45893SN/A * decoding loops then traverse out through the other tables as necessary to
46893SN/A * decode a given instruction.
47893SN/A *
48893SN/A * The behavior of this file can be controlled by one of the following flags:
49893SN/A *
50893SN/A * 	DIS_TEXT	Include text for disassembly
51893SN/A * 	DIS_MEM		Include memory-size calculations
52893SN/A *
53893SN/A * Either or both of these can be defined.
54893SN/A *
55893SN/A * This file is not, and will never be, cstyled.  If anything, the tables should
56893SN/A * be taken out another tab stop or two so nothing overlaps.
57893SN/A */
58893SN/A
59893SN/A/*
60893SN/A * These functions must be provided for the consumer to do disassembly.
61893SN/A */
62893SN/A#ifdef DIS_TEXT
63893SN/Aextern char *strncpy(char *, const char *, size_t);
64893SN/Aextern size_t strlen(const char *);
65893SN/Aextern int strcmp(const char *, const char *);
66893SN/Aextern int strncmp(const char *, const char *, size_t);
67893SN/Aextern size_t strlcat(char *, const char *, size_t);
68893SN/A#endif
69893SN/A
70893SN/A
71893SN/A#define		TERM 	0	/* used to indicate that the 'indirect' */
72893SN/A				/* field terminates - no pointer.	*/
73893SN/A
74893SN/A/* Used to decode instructions. */
75893SN/Atypedef struct	instable {
76893SN/A	struct instable	*it_indirect;	/* for decode op codes */
77893SN/A	uchar_t		it_adrmode;
78893SN/A#ifdef DIS_TEXT
79893SN/A	char		it_name[NCPS];
80893SN/A	uint_t		it_suffix:1;		/* mnem + "w", "l", or "d" */
81893SN/A#endif
82893SN/A#ifdef DIS_MEM
83893SN/A	uint_t		it_size:16;
84893SN/A#endif
85893SN/A	uint_t		it_invalid64:1;		/* opcode invalid in amd64 */
86893SN/A	uint_t		it_always64:1;		/* 64 bit when in 64 bit mode */
87893SN/A	uint_t		it_invalid32:1;		/* invalid in IA32 */
88907SN/A	uint_t		it_stackop:1;		/* push/pop stack operation */
89907SN/A} instable_t;
90907SN/A
91907SN/A/*
92907SN/A * Instruction formats.
93907SN/A */
94907SN/Aenum {
95907SN/A	UNKNOWN,
96907SN/A	MRw,
97907SN/A	IMlw,
98907SN/A	IMw,
99907SN/A	IR,
100907SN/A	OA,
101907SN/A	AO,
102907SN/A	MS,
103907SN/A	SM,
104907SN/A	Mv,
105907SN/A	Mw,
106907SN/A	M,		/* register or memory */
107907SN/A	Mb,		/* register or memory, always byte sized */
108907SN/A	MO,		/* memory only (no registers) */
109907SN/A	PREF,
110907SN/A	SWAPGS,
1111319SN/A	MONITOR_MWAIT,
1121319SN/A	R,
1131319SN/A	RA,
114893SN/A	SEG,
115893SN/A	MR,
116893SN/A	RM,
11714359Sredestad	IA,
11814359Sredestad	MA,
119893SN/A	SD,
120893SN/A	AD,
121893SN/A	SA,
122893SN/A	D,
123893SN/A	INM,
124893SN/A	SO,
125893SN/A	BD,
126893SN/A	I,
127893SN/A	P,
128893SN/A	V,
129893SN/A	DSHIFT,		/* for double shift that has an 8-bit immediate */
130893SN/A	U,
131893SN/A	OVERRIDE,
132893SN/A	NORM,		/* instructions w/o ModR/M byte, no memory access */
133893SN/A	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
134893SN/A	O,		/* for call	*/
135893SN/A	JTAB,		/* jump table 	*/
136893SN/A	IMUL,		/* for 186 iimul instr  */
137893SN/A	CBW,		/* so data16 can be evaluated for cbw and variants */
1381319SN/A	MvI,		/* for 186 logicals */
139893SN/A	ENTER,		/* for 186 enter instr  */
1401319SN/A	RMw,		/* for 286 arpl instr */
1411319SN/A	Ib,		/* for push immediate byte */
1421319SN/A	F,		/* for 287 instructions */
1431319SN/A	FF,		/* for 287 instructions */
1441319SN/A	FFC,		/* for 287 instructions */
1451319SN/A	DM,		/* 16-bit data */
146893SN/A	AM,		/* 16-bit addr */
147893SN/A	LSEG,		/* for 3-bit seg reg encoding */
148893SN/A	MIb,		/* for 386 logicals */
1491319SN/A	SREG,		/* for 386 special registers */
150893SN/A	PREFIX,		/* a REP instruction prefix */
151893SN/A	LOCK,		/* a LOCK instruction prefix */
1521319SN/A	INT3,		/* The int 3 instruction, which has a fake operand */
1531319SN/A	INTx,		/* The normal int instruction, with explicit int num */
1541319SN/A	DSHIFTcl,	/* for double shift that implicitly uses %cl */
1551319SN/A	CWD,		/* so data16 can be evaluated for cwd and variants */
1561319SN/A	RET,		/* single immediate 16-bit operand */
1571319SN/A	MOVZ,		/* for movs and movz, with different size operands */
1581319SN/A	CRC32,		/* for crc32, with different size operands */
159893SN/A	XADDB,		/* for xaddb */
160893SN/A	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
161893SN/A	MOVBE,		/* movbe instruction */
162893SN/A
163893SN/A/*
164893SN/A * MMX/SIMD addressing modes.
165893SN/A */
166893SN/A
167893SN/A	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
168893SN/A	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
169893SN/A	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
170893SN/A	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
171893SN/A	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
172893SN/A	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
173893SN/A	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
174893SN/A	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
175893SN/A	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
176893SN/A	MMOSH,		/* Prefixable MMX		mm,imm8	*/
177893SN/A	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
178893SN/A	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
179893SN/A	MMSH,		/* MMX				mm,imm8 */
180893SN/A	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
181893SN/A	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
182893SN/A	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
183893SN/A	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
184893SN/A	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
185893SN/A	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
186893SN/A	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
187893SN/A	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
188893SN/A	XMM,		/* SIMD 			xmm/mem	-> xmm */
189893SN/A	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
1901319SN/A	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
1911319SN/A	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
1921319SN/A	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
193893SN/A	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
194893SN/A	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
195893SN/A	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
196893SN/A	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
197893SN/A	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
198893SN/A	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
199893SN/A	XMMS,		/* SIMD				xmm	-> xmm/mem */
200893SN/A	XMMM,		/* SIMD 			mem	-> xmm */
201893SN/A	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
202893SN/A	XMMMS,		/* SIMD				xmm	-> mem */
203893SN/A	XMM3MX,		/* SIMD 			r32/mem -> xmm */
204893SN/A	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
205893SN/A	XMMSH,		/* SIMD 			xmm,imm8 */
206893SN/A	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
207893SN/A	XMMX3,		/* SIMD 			xmm	-> r32 */
208893SN/A	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
209893SN/A	XMMMX,		/* SIMD 			mm	-> xmm */
210893SN/A	XMMXM,		/* SIMD 			xmm	-> mm */
211893SN/A        XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
212893SN/A        XMM2I,		/* SIMD				xmm, imm, imm */
213893SN/A	XMMFENCE,	/* SIMD lfence or mfence */
2141319SN/A	XMMSFNC,	/* SIMD sfence (none or mem) */
2151319SN/A	XGETBV_XSETBV,
2161319SN/A	VEX_NONE,	/* VEX  no operand */
217893SN/A	VEX_MO,		/* VEX	mod_rm		               -> implicit reg */
218893SN/A	VEX_RMrX,	/* VEX  VEX.vvvv, mod_rm               -> mod_reg */
219893SN/A	VEX_RRX,	/* VEX  VEX.vvvv, mod_reg              -> mod_rm */
220893SN/A	VEX_RMRX,	/* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
221893SN/A	VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
222893SN/A	VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
223893SN/A	VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
224893SN/A	VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
225893SN/A	VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
226893SN/A	VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
227893SN/A	VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
228893SN/A	VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
229893SN/A	VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
230907SN/A	VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
231907SN/A	VEX_RMX         /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
232907SN/A};
233907SN/A
234907SN/A/*
235907SN/A * VEX prefixes
236907SN/A */
237907SN/A#define VEX_2bytes	0xC5	/* the first byte of two-byte form */
238907SN/A#define VEX_3bytes	0xC4	/* the first byte of three-byte form */
239907SN/A
240907SN/A#define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
241907SN/A
242907SN/A/*
2431319SN/A** Register numbers for the i386
2441319SN/A*/
2451319SN/A#define	EAX_REGNO 0
246907SN/A#define	ECX_REGNO 1
247907SN/A#define	EDX_REGNO 2
2481576SN/A#define	EBX_REGNO 3
2491576SN/A#define	ESP_REGNO 4
250907SN/A#define	EBP_REGNO 5
251907SN/A#define	ESI_REGNO 6
252907SN/A#define	EDI_REGNO 7
253907SN/A
254907SN/A/*
255907SN/A * modes for immediate values
256907SN/A */
257907SN/A#define	MODE_NONE	0
258907SN/A#define	MODE_IPREL	1	/* signed IP relative value */
259907SN/A#define	MODE_SIGNED	2	/* sign extended immediate */
260907SN/A#define	MODE_IMPLIED	3	/* constant value implied from opcode */
261893SN/A#define	MODE_OFFSET	4	/* offset part of an address */
262893SN/A#define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
263893SN/A
264893SN/A/*
265893SN/A * The letters used in these macros are:
266893SN/A *   IND - indirect to another to another table
267893SN/A *   "T" - means to Terminate indirections (this is the final opcode)
268893SN/A *   "S" - means "operand length suffix required"
269893SN/A *   "NS" - means "no suffix" which is the operand length suffix of the opcode
270893SN/A *   "Z" - means instruction size arg required
271893SN/A *   "u" - means the opcode is invalid in IA32 but valid in amd64
272893SN/A *   "x" - means the opcode is invalid in amd64, but not IA32
273893SN/A *   "y" - means the operand size is always 64 bits in 64 bit mode
274893SN/A *   "p" - means push/pop stack operation
275893SN/A */
276893SN/A
2771576SN/A#if defined(DIS_TEXT) && defined(DIS_MEM)
278893SN/A#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
279893SN/A#define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
280893SN/A#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
281893SN/A#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
282893SN/A#define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
283893SN/A#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
284893SN/A#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
285893SN/A#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
286893SN/A#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
287893SN/A#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
288893SN/A#define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
289893SN/A#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
290893SN/A#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
291893SN/A#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
292893SN/A#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
293893SN/A#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
294893SN/A#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
295893SN/A#elif defined(DIS_TEXT)
296893SN/A#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
297893SN/A#define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
298893SN/A#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
299893SN/A#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
300893SN/A#define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
3011476SN/A#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
3021476SN/A#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
3031476SN/A#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
304893SN/A#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
305893SN/A#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
306893SN/A#define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
307893SN/A#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
308893SN/A#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
309893SN/A#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
310893SN/A#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
311893SN/A#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
312893SN/A#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3131576SN/A#elif defined(DIS_MEM)
314893SN/A#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
3151476SN/A#define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
3161476SN/A#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
3171476SN/A#define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
3181476SN/A#define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
319893SN/A#define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
320893SN/A#define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
321893SN/A#define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
3221476SN/A#define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
3231476SN/A#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
3241476SN/A#define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
3251476SN/A#define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
3261476SN/A#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
3271476SN/A#define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
3281476SN/A#define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
3291476SN/A#define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
3301476SN/A#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
3311476SN/A#else
3321476SN/A#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
3331476SN/A#define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
3341476SN/A#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
3351476SN/A#define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
3361476SN/A#define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3371476SN/A#define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
3381476SN/A#define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3391476SN/A#define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
3401476SN/A#define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
3411476SN/A#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
3421476SN/A#define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3431476SN/A#define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3441476SN/A#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
3451476SN/A#define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
3461476SN/A#define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
3471476SN/A#define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
348893SN/A#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
349893SN/A#endif
350893SN/A
351893SN/A#ifdef DIS_TEXT
352893SN/A/*
353893SN/A * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
354893SN/A */
355893SN/Aconst char *const dis_addr16[3][8] = {
356893SN/A"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
357893SN/A									"(%bx)",
358893SN/A"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
359893SN/A									"(%bx)",
3601576SN/A"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
361893SN/A									"(%bx)",
362893SN/A};
363893SN/A
364893SN/A
365893SN/A/*
366893SN/A * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
367893SN/A */
368893SN/Aconst char *const dis_addr32_mode0[16] = {
369893SN/A  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
370893SN/A  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
371893SN/A};
3721576SN/A
3731576SN/Aconst char *const dis_addr32_mode12[16] = {
3741576SN/A  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
3751576SN/A  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
3761576SN/A};
3771576SN/A
3781576SN/A/*
379893SN/A * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
380893SN/A */
381893SN/Aconst char *const dis_addr64_mode0[16] = {
382893SN/A "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
383893SN/A "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
384893SN/A};
385893SN/Aconst char *const dis_addr64_mode12[16] = {
386893SN/A "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
387893SN/A "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
388893SN/A};
389893SN/A
390893SN/A/*
391893SN/A * decode for scale from SIB byte
392893SN/A */
393893SN/Aconst char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
394893SN/A
395893SN/A/*
396893SN/A * register decoding for normal references to registers (ie. not addressing)
397893SN/A */
398893SN/Aconst char *const dis_REG8[16] = {
399893SN/A	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
400893SN/A	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
401893SN/A};
4021319SN/A
4031319SN/Aconst char *const dis_REG8_REX[16] = {
404893SN/A	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
405893SN/A	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
406893SN/A};
4071319SN/A
4081319SN/Aconst char *const dis_REG16[16] = {
409893SN/A	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
410893SN/A	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
411893SN/A};
4121319SN/A
4131319SN/Aconst char *const dis_REG32[16] = {
414893SN/A	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
415893SN/A	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
416893SN/A};
417893SN/A
418893SN/Aconst char *const dis_REG64[16] = {
419893SN/A	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
420893SN/A	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
421893SN/A};
422893SN/A
4231576SN/Aconst char *const dis_DEBUGREG[16] = {
424893SN/A	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
425893SN/A	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
426893SN/A};
427893SN/A
428893SN/Aconst char *const dis_CONTROLREG[16] = {
429893SN/A    "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
430893SN/A    "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
431893SN/A};
432893SN/A
433893SN/Aconst char *const dis_TESTREG[16] = {
434893SN/A	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
435893SN/A	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
436893SN/A};
437893SN/A
438893SN/Aconst char *const dis_MMREG[16] = {
439893SN/A	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
440893SN/A	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
441893SN/A};
442893SN/A
443893SN/Aconst char *const dis_XMMREG[16] = {
444893SN/A    "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
445893SN/A    "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
446893SN/A};
447893SN/A
448893SN/Aconst char *const dis_YMMREG[16] = {
449893SN/A    "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
450893SN/A    "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
451893SN/A};
452893SN/A
453893SN/Aconst char *const dis_SEGREG[16] = {
454893SN/A	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
455893SN/A	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
456893SN/A};
457893SN/A
458893SN/A/*
459893SN/A * SIMD predicate suffixes
460893SN/A */
461893SN/Aconst char *const dis_PREDSUFFIX[8] = {
462893SN/A	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
463893SN/A};
464893SN/A
465893SN/Aconst char *const dis_AVXvgrp7[3][8] = {
466893SN/A	/*0	1	2		3		4		5	6		7*/
467893SN/A/*71*/	{"",	"",	"vpsrlw",	"",		"vpsraw",	"",	"vpsllw",	""},
468893SN/A/*72*/	{"",	"",	"vpsrld",	"",		"vpsrad",	"",	"vpslld",	""},
469893SN/A/*73*/	{"",	"",	"vpsrlq",	"vpsrldq",	"",		"",	"vpsllq",	"vpslldq"}
470893SN/A};
471893SN/A
472893SN/A#endif	/* DIS_TEXT */
473893SN/A
474893SN/A/*
475893SN/A *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
476 */
477const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
478
479/*
480 *	"decode table" for pause and clflush instructions
481 */
482const instable_t dis_opPause = TNS("pause", NORM);
483
484/*
485 *	Decode table for 0x0F00 opcodes
486 */
487const instable_t dis_op0F00[8] = {
488
489/*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
490/*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
491};
492
493
494/*
495 *	Decode table for 0x0F01 opcodes
496 */
497const instable_t dis_op0F01[8] = {
498
499/*  [0]  */	TNSZ("sgdt",MO,6),	TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6),	TNSZ("lidt",MO,6),
500/*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS),
501};
502
503/*
504 *	Decode table for 0x0F18 opcodes -- SIMD prefetch
505 */
506const instable_t dis_op0F18[8] = {
507
508/*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
509/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
510};
511
512/*
513 * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
514 */
515const instable_t dis_op0FAE[8] = {
516/*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
517/*  [4]  */	TNSZ("xsave",M,512),	TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
518};
519
520/*
521 *	Decode table for 0x0FBA opcodes
522 */
523
524const instable_t dis_op0FBA[8] = {
525
526/*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
527/*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
528};
529
530/*
531 * 	Decode table for 0x0FC7 opcode
532 */
533
534const instable_t dis_op0FC7[8] = {
535
536/*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
537/*  [4]  */	INVALID,		INVALID,	INVALID,		 INVALID,
538};
539
540
541/*
542 *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
543 *
544 *bit pattern: 0000 1111 1100 1reg
545 */
546const instable_t dis_op0FC8[4] = {
547/*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
548};
549
550/*
551 *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
552 */
553const instable_t dis_op0F7123[4][8] = {
554{
555/*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
556/*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
557}, {
558/*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
559/*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
560}, {
561/*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
562/*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
563}, {
564/*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
565/*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
566} };
567
568/*
569 *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
570 */
571const instable_t dis_opSIMD7123[32] = {
572/* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
573/*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
574
575/* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
576/*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
577
578/* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
579/*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
580
581/* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
582/*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
583};
584
585/*
586 *	SIMD instructions have been wedged into the existing IA32 instruction
587 *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
588 *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
589 *	instruction - addss.  At present, three prefixes have been coopted in
590 *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
591 *	following tables are used to provide the prefixed instruction names.
592 *	The arrays are sparse, but they're fast.
593 */
594
595/*
596 *	Decode table for SIMD instructions with the address size (0x66) prefix.
597 */
598const instable_t dis_opSIMDdata16[256] = {
599/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
600/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
601/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
602/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
603
604/*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
605/*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
606/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
607/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
608
609/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
610/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
611/*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
612/*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
613
614/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
615/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
616/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
617/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
618
619/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
620/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
621/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
622/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
623
624/*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
625/*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
626/*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
627/*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
628
629/*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
630/*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
631/*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
632/*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
633
634/*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
635/*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
636/*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
637/*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
638
639/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
640/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
641/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
642/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
643
644/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
645/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
646/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
647/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
648
649/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
650/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
651/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
652/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
653
654/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
655/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
656/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
657/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
658
659/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
660/*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
661/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
662/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
663
664/*  [D0]  */	INVALID,		TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
665/*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
666/*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
667/*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
668
669/*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
670/*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
671/*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
672/*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
673
674/*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
675/*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
676/*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
677/*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
678};
679
680const instable_t dis_opAVX660F[256] = {
681/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
682/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
683/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
684/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
685
686/*  [10]  */	TNSZ("vmovupd",VEX_MX,16),	TNSZ("vmovupd",VEX_RX,16),	TNSZ("vmovlpd",VEX_RMrX,8),	TNSZ("vmovlpd",VEX_RM,8),
687/*  [14]  */	TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8),	TNSZ("vmovhpd",VEX_RM,8),
688/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
689/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
690
691/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
692/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
693/*  [28]  */	TNSZ("vmovapd",VEX_MX,16),	TNSZ("vmovapd",VEX_RX,16),	INVALID,		TNSZ("vmovntpd",VEX_RM,16),
694/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
695
696/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
697/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
698/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
699/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
700
701/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
702/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
703/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
704/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
705
706/*  [50]  */	TNS("vmovmskpd",VEX_MR),	TNSZ("vsqrtpd",VEX_MX,16),	INVALID,		INVALID,
707/*  [54]  */	TNSZ("vandpd",VEX_RMrX,16),	TNSZ("vandnpd",VEX_RMrX,16),	TNSZ("vorpd",VEX_RMrX,16),	TNSZ("vxorpd",VEX_RMrX,16),
708/*  [58]  */	TNSZ("vaddpd",VEX_RMrX,16),	TNSZ("vmulpd",VEX_RMrX,16),	TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
709/*  [5C]  */	TNSZ("vsubpd",VEX_RMrX,16),	TNSZ("vminpd",VEX_RMrX,16),	TNSZ("vdivpd",VEX_RMrX,16),	TNSZ("vmaxpd",VEX_RMrX,16),
710
711/*  [60]  */	TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
712/*  [64]  */	TNSZ("vpcmpgtb",VEX_RMrX,16),	TNSZ("vpcmpgtw",VEX_RMrX,16),	TNSZ("vpcmpgtd",VEX_RMrX,16),	TNSZ("vpackuswb",VEX_RMrX,16),
713/*  [68]  */	TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
714/*  [6C]  */	TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
715
716/*  [70]  */	TNSZ("vpshufd",VEX_MXI,16),	TNSZ("vgrp71",VEX_XXI,16),	TNSZ("vgrp72",VEX_XXI,16),		TNSZ("vgrp73",VEX_XXI,16),
717/*  [74]  */	TNSZ("vpcmpeqb",VEX_RMrX,16),	TNSZ("vpcmpeqw",VEX_RMrX,16),	TNSZ("vpcmpeqd",VEX_RMrX,16),	INVALID,
718/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
719/*  [7C]  */	TNSZ("vhaddpd",VEX_RMrX,16),	TNSZ("vhsubpd",VEX_RMrX,16),	TNSZ("vmovd",VEX_RR,4),	TNSZ("vmovdqa",VEX_RX,16),
720
721/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
722/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
723/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
724/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
725
726/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
727/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
728/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
729/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
730
731/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
732/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
733/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
734/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
735
736/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
737/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
738/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
739/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
740
741/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmppd",VEX_RMRX,16),	INVALID,
742/*  [C4]  */	TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),	TNSZ("vshufpd",VEX_RMRX,16),	INVALID,
743/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
744/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
745
746/*  [D0]  */	TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),	TNSZ("vpsrld",VEX_RMrX,16),	TNSZ("vpsrlq",VEX_RMrX,16),
747/*  [D4]  */	TNSZ("vpaddq",VEX_RMrX,16),	TNSZ("vpmullw",VEX_RMrX,16),	TNSZ("vmovq",VEX_RX,8),	TNS("vpmovmskb",VEX_MR),
748/*  [D8]  */	TNSZ("vpsubusb",VEX_RMrX,16),	TNSZ("vpsubusw",VEX_RMrX,16),	TNSZ("vpminub",VEX_RMrX,16),	TNSZ("vpand",VEX_RMrX,16),
749/*  [DC]  */	TNSZ("vpaddusb",VEX_RMrX,16),	TNSZ("vpaddusw",VEX_RMrX,16),	TNSZ("vpmaxub",VEX_RMrX,16),	TNSZ("vpandn",VEX_RMrX,16),
750
751/*  [E0]  */	TNSZ("vpavgb",VEX_RMrX,16),	TNSZ("vpsraw",VEX_RMrX,16),	TNSZ("vpsrad",VEX_RMrX,16),	TNSZ("vpavgw",VEX_RMrX,16),
752/*  [E4]  */	TNSZ("vpmulhuw",VEX_RMrX,16),	TNSZ("vpmulhw",VEX_RMrX,16),	TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
753/*  [E8]  */	TNSZ("vpsubsb",VEX_RMrX,16),	TNSZ("vpsubsw",VEX_RMrX,16),	TNSZ("vpminsw",VEX_RMrX,16),	TNSZ("vpor",VEX_RMrX,16),
754/*  [EC]  */	TNSZ("vpaddsb",VEX_RMrX,16),	TNSZ("vpaddsw",VEX_RMrX,16),	TNSZ("vpmaxsw",VEX_RMrX,16),	TNSZ("vpxor",VEX_RMrX,16),
755
756/*  [F0]  */	INVALID,		TNSZ("vpsllw",VEX_RMrX,16),	TNSZ("vpslld",VEX_RMrX,16),	TNSZ("vpsllq",VEX_RMrX,16),
757/*  [F4]  */	TNSZ("vpmuludq",VEX_RMrX,16),	TNSZ("vpmaddwd",VEX_RMrX,16),	TNSZ("vpsadbw",VEX_RMrX,16),	TNS("vmaskmovdqu",VEX_MX),
758/*  [F8]  */	TNSZ("vpsubb",VEX_RMrX,16),	TNSZ("vpsubw",VEX_RMrX,16),	TNSZ("vpsubd",VEX_RMrX,16),	TNSZ("vpsubq",VEX_RMrX,16),
759/*  [FC]  */	TNSZ("vpaddb",VEX_RMrX,16),	TNSZ("vpaddw",VEX_RMrX,16),	TNSZ("vpaddd",VEX_RMrX,16),	INVALID,
760};
761
762/*
763 *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
764 */
765const instable_t dis_opSIMDrepnz[256] = {
766/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
767/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
768/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
769/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
770
771/*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	INVALID,		INVALID,
772/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
773/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
774/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
775
776/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
777/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
778/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
779/*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
780
781/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
782/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
783/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
784/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
785
786/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
787/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
788/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
789/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
790
791/*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
792/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
793/*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
794/*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
795
796/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
797/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
798/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
799/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
800
801/*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
802/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
803/*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
804/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
805
806/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
807/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
808/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
809/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
810
811/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
812/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
813/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
814/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
815
816/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
817/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
818/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
819/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
820
821/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
822/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
823/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
824/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
825
826/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
827/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
828/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
829/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
830
831/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
832/*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
833/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
834/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
835
836/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
837/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
838/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
839/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
840
841/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
842/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
843/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
844/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
845};
846
847const instable_t dis_opAVXF20F[256] = {
848/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
849/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
850/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
851/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
852
853/*  [10]  */	TNSZ("vmovsd",VEX_RMrX,8),	TNSZ("vmovsd",VEX_RRX,8),	TNSZ("vmovddup",VEX_MX,8),	INVALID,
854/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
855/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
856/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
857
858/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
859/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
860/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
861/*  [2C]  */	TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,		INVALID,
862
863/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
864/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
865/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
866/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
867
868/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
869/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
870/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
871/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
872
873/*  [50]  */	INVALID,		TNSZ("vsqrtsd",VEX_RMrX,8),	INVALID,		INVALID,
874/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
875/*  [58]  */	TNSZ("vaddsd",VEX_RMrX,8),	TNSZ("vmulsd",VEX_RMrX,8),	TNSZ("vcvtsd2ss",VEX_RMrX,8),	INVALID,
876/*  [5C]  */	TNSZ("vsubsd",VEX_RMrX,8),	TNSZ("vminsd",VEX_RMrX,8),	TNSZ("vdivsd",VEX_RMrX,8),	TNSZ("vmaxsd",VEX_RMrX,8),
877
878/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
879/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
880/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
881/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
882
883/*  [70]  */	TNSZ("vpshuflw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
884/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
885/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
886/*  [7C]  */	TNSZ("vhaddps",VEX_RMrX,8),	TNSZ("vhsubps",VEX_RMrX,8),	INVALID,		INVALID,
887
888/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
889/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
890/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
891/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
892
893/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
894/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
895/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
896/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
897
898/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
899/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
900/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
901/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
902
903/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
904/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
905/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
906/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
907
908/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpsd",VEX_RMRX,8),	INVALID,
909/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
910/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
911/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
912
913/*  [D0]  */	TNSZ("vaddsubps",VEX_RMrX,8),	INVALID,		INVALID,		INVALID,
914/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
915/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
916/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
917
918/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
919/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
920/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
921/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
922
923/*  [F0]  */	TNSZ("vlddqu",VEX_MX,16),	INVALID,		INVALID,		INVALID,
924/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
925/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
926/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
927};
928
929/*
930 *	Decode table for SIMD instructions with the repz (0xf3) prefix.
931 */
932const instable_t dis_opSIMDrepz[256] = {
933/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
934/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
935/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
936/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
937
938/*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	INVALID,		INVALID,
939/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
940/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
941/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
942
943/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
944/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
945/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
946/*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
947
948/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
949/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
950/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
951/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
952
953/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
954/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
955/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
956/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
957
958/*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
959/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
960/*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
961/*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
962
963/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
964/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
965/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
966/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
967
968/*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
969/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
970/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
971/*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
972
973/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
974/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
975/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
976/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
977
978/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
979/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
980/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
981/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
982
983/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
984/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
985/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
986/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
987
988/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
989/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
990/*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
991/*  [BC]  */	INVALID,		TS("lzcnt",MRw),	INVALID,		INVALID,
992
993/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
994/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
995/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
996/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
997
998/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
999/*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
1000/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1001/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1002
1003/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1004/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
1005/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1006/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1007
1008/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1009/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1010/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1011/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1012};
1013
1014const instable_t dis_opAVXF30F[256] = {
1015/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1016/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1017/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1018/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1019
1020/*  [10]  */	TNSZ("vmovss",VEX_RMrX,4),	TNSZ("vmovss",VEX_RRX,4),	TNSZ("vmovsldup",VEX_MX,4),	INVALID,
1021/*  [14]  */	INVALID,		INVALID,		TNSZ("vmovshdup",VEX_MX,4),	INVALID,
1022/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1023/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1024
1025/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1026/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1027/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
1028/*  [2C]  */	TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,		INVALID,
1029
1030/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1031/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1032/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1033/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1034
1035/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1036/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1037/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1038/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1039
1040/*  [50]  */	INVALID,		TNSZ("vsqrtss",VEX_RMrX,4),	TNSZ("vrsqrtss",VEX_RMrX,4),	TNSZ("vrcpss",VEX_RMrX,4),
1041/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1042/*  [58]  */	TNSZ("vaddss",VEX_RMrX,4),	TNSZ("vmulss",VEX_RMrX,4),	TNSZ("vcvtss2sd",VEX_RMrX,4),	TNSZ("vcvttps2dq",VEX_MX,16),
1043/*  [5C]  */	TNSZ("vsubss",VEX_RMrX,4),	TNSZ("vminss",VEX_RMrX,4),	TNSZ("vdivss",VEX_RMrX,4),	TNSZ("vmaxss",VEX_RMrX,4),
1044
1045/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1046/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1047/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1048/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("vmovdqu",VEX_MX,16),
1049
1050/*  [70]  */	TNSZ("vpshufhw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
1051/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1052/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1053/*  [7C]  */	INVALID,		INVALID,		TNSZ("vmovq",VEX_MX,8),	TNSZ("vmovdqu",VEX_RX,16),
1054
1055/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1056/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1057/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1058/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1059
1060/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1061/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1062/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1063/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1064
1065/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1066/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1067/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1068/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1069
1070/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1071/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1072/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1073/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1074
1075/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpss",VEX_RMRX,4),	INVALID,
1076/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1077/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1078/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1079
1080/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1081/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1082/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1083/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1084
1085/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1086/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtdq2pd",VEX_MX,8),	INVALID,
1087/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1088/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1089
1090/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1091/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1092/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1093/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1094};
1095/*
1096 * The following two tables are used to encode crc32 and movbe
1097 * since they share the same opcodes.
1098 */
1099const instable_t dis_op0F38F0[2] = {
1100/*  [00]  */	TNS("crc32b",CRC32),
1101		TS("movbe",MOVBE),
1102};
1103
1104const instable_t dis_op0F38F1[2] = {
1105/*  [00]  */	TS("crc32",CRC32),
1106		TS("movbe",MOVBE),
1107};
1108
1109const instable_t dis_op0F38[256] = {
1110/*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
1111/*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
1112/*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
1113/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1114
1115/*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
1116/*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
1117/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1118/*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
1119
1120/*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
1121/*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
1122/*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
1123/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1124
1125/*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
1126/*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
1127/*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
1128/*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
1129
1130/*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
1131/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1132/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1133/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1134
1135/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1136/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1137/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1138/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1139
1140/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1141/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1142/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1143/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1144
1145/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1146/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1147/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1148/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1149
1150/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1151/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1152/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1153/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1154
1155/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1156/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1157/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1158/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1159
1160/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1161/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1162/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1163/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1164
1165/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1166/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1167/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1168/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1169
1170/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1171/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1172/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1173/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1174
1175/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1176/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1177/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
1178/*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
1179
1180/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1181/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1182/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1183/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1184/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1185/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1186/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1187/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1188};
1189
1190const instable_t dis_opAVX660F38[256] = {
1191/*  [00]  */	TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
1192/*  [04]  */	TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),	TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
1193/*  [08]  */	TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
1194/*  [0C]  */	TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),	TNSZ("vtestpd",VEX_RRI,16),
1195
1196/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1197/*  [14]  */	INVALID,		INVALID,		INVALID,		TNSZ("vptest",VEX_RRI,16),
1198/*  [18]  */	TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
1199/*  [1C]  */	TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
1200
1201/*  [20]  */	TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
1202/*  [24]  */	TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,	INVALID,
1203/*  [28]  */	TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
1204/*  [2C]  */	TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
1205
1206/*  [30]  */	TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
1207/*  [34]  */	TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),INVALID,	TNSZ("vpcmpgtq",VEX_RMrX,16),
1208/*  [38]  */	TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
1209/*  [3C]  */	TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
1210
1211/*  [40]  */	TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,	INVALID,
1212/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1213/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1214/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1215
1216/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1217/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1218/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1219/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1220
1221/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1222/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1223/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1224/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1225
1226/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1227/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1228/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1229/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1230
1231/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1232/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1233/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1234/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1235
1236/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1237/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1238/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1239/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1240
1241/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1242/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1243/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1244/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1245
1246/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1247/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1248/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1249/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1250
1251/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1252/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1253/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1254/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1255
1256/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1257/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1258/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaesimc",VEX_MX,16),
1259/*  [DC]  */	TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
1260
1261/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1262/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1263/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1264/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1265/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1266/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1267/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1268/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1269};
1270
1271const instable_t dis_op0F3A[256] = {
1272/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1273/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1274/*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
1275/*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
1276
1277/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1278/*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
1279/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1280/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1281
1282/*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
1283/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1284/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1285/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1286
1287/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1288/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1289/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1290/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1291
1292/*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
1293/*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
1294/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1295/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1296
1297/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1298/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1299/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1300/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1301
1302/*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
1303/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1304/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1305/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1306
1307/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1308/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1309/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1310/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1311
1312/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1313/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1314/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1315/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1316
1317/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1318/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1319/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1320/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1321
1322/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1323/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1324/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1325/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1326
1327/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1328/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1329/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1330/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1331
1332/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1333/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1334/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1335/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1336
1337/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1338/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1339/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1340/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
1341
1342/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1343/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1344/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1345/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1346
1347/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1348/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1349/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1350/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1351};
1352
1353const instable_t dis_opAVX660F3A[256] = {
1354/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1355/*  [04]  */	TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
1356/*  [08]  */	TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
1357/*  [0C]  */	TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
1358
1359/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1360/*  [14]  */	TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
1361/*  [18]  */	TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,		INVALID,
1362/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1363
1364/*  [20]  */	TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
1365/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1366/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1367/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1368
1369/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1370/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1371/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1372/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1373
1374/*  [40]  */	TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
1375/*  [44]  */	TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
1376/*  [48]  */	INVALID,		INVALID,		TNSZ("vblendvps",VEX_RMRX,8),	TNSZ("vblendvpd",VEX_RMRX,16),
1377/*  [4C]  */	TNSZ("vpblendvb",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
1378
1379/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1380/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1381/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1382/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1383
1384/*  [60]  */	TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
1385/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1386/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1387/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1388
1389/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1390/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1391/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1392/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1393
1394/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1395/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1396/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1397/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1398
1399/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1400/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1401/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1402/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1403
1404/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1405/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1406/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1407/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1408
1409/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1410/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1411/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1412/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1413
1414/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1415/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1416/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1417/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1418
1419/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1420/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1421/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1422/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaeskeygenassist",VEX_MXI,16),
1423
1424/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1425/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1426/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1427/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1428
1429/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1430/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1431/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1432/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1433};
1434
1435/*
1436 *	Decode table for 0x0F opcodes
1437 */
1438
1439const instable_t dis_op0F[16][16] = {
1440{
1441/*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
1442/*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
1443/*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
1444/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1445}, {
1446/*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
1447/*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
1448/*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
1449/*  [1C]  */	INVALID,		INVALID,		INVALID,		TS("nopw", Mw),
1450}, {
1451/*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
1452/*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
1453/*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
1454/*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
1455}, {
1456/*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
1457/*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
1458/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1459/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1460}, {
1461/*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
1462/*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
1463/*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
1464/*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
1465}, {
1466/*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
1467/*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
1468/*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
1469/*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
1470}, {
1471/*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
1472/*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
1473/*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
1474/*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
1475}, {
1476/*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
1477/*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
1478/*  [78]  */	TNS("INVALID",XMMO),	TNS("INVALID",XMMO),	INVALID,		INVALID,
1479/*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
1480}, {
1481/*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
1482/*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
1483/*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
1484/*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
1485}, {
1486/*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
1487/*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
1488/*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
1489/*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
1490}, {
1491/*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
1492/*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
1493/*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
1494/*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
1495}, {
1496/*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
1497/*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
1498/*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
1499/*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
1500}, {
1501/*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
1502/*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
1503/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1504/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1505}, {
1506/*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
1507/*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
1508/*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
1509/*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
1510}, {
1511/*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
1512/*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
1513/*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
1514/*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
1515}, {
1516/*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
1517/*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
1518/*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
1519/*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
1520} };
1521
1522const instable_t dis_opAVX0F[16][16] = {
1523{
1524/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1525/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1526/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1527/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1528}, {
1529/*  [10]  */	TNSZ("vmovups",VEX_MX,16),	TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),	TNSZ("vmovlps",VEX_RM,8),
1530/*  [14]  */	TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
1531/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1532/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1533}, {
1534/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1535/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1536/*  [28]  */	TNSZ("vmovaps",VEX_MX,16),	TNSZ("vmovaps",VEX_RX,16),INVALID,		TNSZ("vmovntps",VEX_RM,16),
1537/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
1538}, {
1539/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1540/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1541/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1542/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1543}, {
1544/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1545/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1546/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1547/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1548}, {
1549/*  [50]  */	TNS("vmovmskps",VEX_MR),	TNSZ("vsqrtps",VEX_MX,16),	TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
1550/*  [54]  */	TNSZ("vandps",VEX_RMrX,16),	TNSZ("vandnps",VEX_RMrX,16),	TNSZ("vorps",VEX_RMrX,16),	TNSZ("vxorps",VEX_RMrX,16),
1551/*  [58]  */	TNSZ("vaddps",VEX_RMrX,16),	TNSZ("vmulps",VEX_RMrX,16),	TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
1552/*  [5C]  */	TNSZ("vsubps",VEX_RMrX,16),	TNSZ("vminps",VEX_RMrX,16),	TNSZ("vdivps",VEX_RMrX,16),	TNSZ("vmaxps",VEX_RMrX,16),
1553}, {
1554/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1555/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1556/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1557/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1558}, {
1559/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1560/*  [74]  */	INVALID,		INVALID,		INVALID,		TNS("vzeroupper", VEX_NONE),
1561/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1562/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1563}, {
1564/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1565/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1566/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1567/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1568}, {
1569/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1570/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1571/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1572/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1573}, {
1574/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1575/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1576/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1577/*  [AC]  */	INVALID,		INVALID,		TNSZ("vldmxcsr",VEX_MO,2),		INVALID,
1578}, {
1579/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1580/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1581/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1582/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1583}, {
1584/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpps",VEX_RMRX,16),INVALID,
1585/*  [C4]  */	INVALID,		INVALID,	 	TNSZ("vshufps",VEX_RMRX,16),INVALID,
1586/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1587/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1588}, {
1589/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1590/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1591/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1592/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1593}, {
1594/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1595/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1596/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1597/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1598}, {
1599/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1600/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1601/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1602/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1603} };
1604
1605/*
1606 *	Decode table for 0x80 opcodes
1607 */
1608
1609const instable_t dis_op80[8] = {
1610
1611/*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
1612/*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
1613};
1614
1615
1616/*
1617 *	Decode table for 0x81 opcodes.
1618 */
1619
1620const instable_t dis_op81[8] = {
1621
1622/*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
1623/*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
1624};
1625
1626
1627/*
1628 *	Decode table for 0x82 opcodes.
1629 */
1630
1631const instable_t dis_op82[8] = {
1632
1633/*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
1634/*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
1635};
1636/*
1637 *	Decode table for 0x83 opcodes.
1638 */
1639
1640const instable_t dis_op83[8] = {
1641
1642/*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
1643/*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
1644};
1645
1646/*
1647 *	Decode table for 0xC0 opcodes.
1648 */
1649
1650const instable_t dis_opC0[8] = {
1651
1652/*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
1653/*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
1654};
1655
1656/*
1657 *	Decode table for 0xD0 opcodes.
1658 */
1659
1660const instable_t dis_opD0[8] = {
1661
1662/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
1663/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
1664};
1665
1666/*
1667 *	Decode table for 0xC1 opcodes.
1668 *	186 instruction set
1669 */
1670
1671const instable_t dis_opC1[8] = {
1672
1673/*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
1674/*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
1675};
1676
1677/*
1678 *	Decode table for 0xD1 opcodes.
1679 */
1680
1681const instable_t dis_opD1[8] = {
1682
1683/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
1684/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
1685};
1686
1687
1688/*
1689 *	Decode table for 0xD2 opcodes.
1690 */
1691
1692const instable_t dis_opD2[8] = {
1693
1694/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
1695/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
1696};
1697/*
1698 *	Decode table for 0xD3 opcodes.
1699 */
1700
1701const instable_t dis_opD3[8] = {
1702
1703/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
1704/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
1705};
1706
1707
1708/*
1709 *	Decode table for 0xF6 opcodes.
1710 */
1711
1712const instable_t dis_opF6[8] = {
1713
1714/*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
1715/*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
1716};
1717
1718
1719/*
1720 *	Decode table for 0xF7 opcodes.
1721 */
1722
1723const instable_t dis_opF7[8] = {
1724
1725/*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
1726/*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
1727};
1728
1729
1730/*
1731 *	Decode table for 0xFE opcodes.
1732 */
1733
1734const instable_t dis_opFE[8] = {
1735
1736/*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
1737/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1738};
1739/*
1740 *	Decode table for 0xFF opcodes.
1741 */
1742
1743const instable_t dis_opFF[8] = {
1744
1745/*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
1746/*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
1747};
1748
1749/* for 287 instructions, which are a mess to decode */
1750
1751const instable_t dis_opFP1n2[8][8] = {
1752{
1753/* bit pattern:	1101 1xxx MODxx xR/M */
1754/*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
1755/*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
1756}, {
1757/*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
1758/*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
1759}, {
1760/*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
1761/*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
1762}, {
1763/*  [3,0]  */	TNS("fildl",M),		INVALID,		TNS("fistl",M),		TNS("fistpl",M),
1764/*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
1765}, {
1766/*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
1767/*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
1768}, {
1769/*  [5,0]  */	TNSZ("fldl",M,8),	INVALID,		TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
1770/*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
1771}, {
1772/*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
1773/*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
1774}, {
1775/*  [7,0]  */	TNSZ("fild",M,2),	INVALID,		TNSZ("fist",M,2),	TNSZ("fistp",M,2),
1776/*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
1777} };
1778
1779const instable_t dis_opFP3[8][8] = {
1780{
1781/* bit  pattern:	1101 1xxx 11xx xREG */
1782/*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
1783/*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
1784}, {
1785/*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
1786/*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1787}, {
1788/*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1789/*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
1790}, {
1791/*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1792/*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1793}, {
1794/*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
1795/*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
1796}, {
1797/*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
1798/*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
1799}, {
1800/*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
1801/*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
1802}, {
1803/*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
1804/*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
1805} };
1806
1807const instable_t dis_opFP4[4][8] = {
1808{
1809/* bit pattern:	1101 1001 111x xxxx */
1810/*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
1811/*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
1812}, {
1813/*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
1814/*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
1815}, {
1816/*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
1817/*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
1818}, {
1819/*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
1820/*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
1821} };
1822
1823const instable_t dis_opFP5[8] = {
1824/* bit pattern:	1101 1011 111x xxxx */
1825/*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
1826/*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
1827};
1828
1829const instable_t dis_opFP6[8] = {
1830/* bit pattern:	1101 1011 11yy yxxx */
1831/*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
1832/*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
1833};
1834
1835const instable_t dis_opFP7[8] = {
1836/* bit pattern:	1101 1010 11yy yxxx */
1837/*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
1838/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1839};
1840
1841/*
1842 *	Main decode table for the op codes.  The first two nibbles
1843 *	will be used as an index into the table.  If there is a
1844 *	a need to further decode an instruction, the array to be
1845 *	referenced is indicated with the other two entries being
1846 *	empty.
1847 */
1848
1849const instable_t dis_distable[16][16] = {
1850{
1851/* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
1852/* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
1853/* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
1854/* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
1855}, {
1856/* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
1857/* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
1858/* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
1859/* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
1860}, {
1861/* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
1862/* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNS("%es:",OVERRIDE),	TNSx("daa",NORM),
1863/* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
1864/* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNS("%cs:",OVERRIDE),	TNSx("das",NORM),
1865}, {
1866/* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
1867/* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNS("%ss:",OVERRIDE),	TNSx("aaa",NORM),
1868/* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
1869/* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNS("%ds:",OVERRIDE),	TNSx("aas",NORM),
1870}, {
1871/* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
1872/* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
1873/* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
1874/* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
1875}, {
1876/* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
1877/* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
1878/* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
1879/* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
1880}, {
1881/* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
1882/* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
1883/* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
1884/* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
1885}, {
1886/* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
1887/* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
1888/* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
1889/* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
1890}, {
1891/* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
1892/* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
1893/* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
1894/* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
1895}, {
1896/* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
1897/* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
1898/* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
1899/* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNSx("sahf",NORM),	TNSx("lahf",NORM),
1900}, {
1901/* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
1902/* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
1903/* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
1904/* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
1905}, {
1906/* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
1907/* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
1908/* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
1909/* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
1910}, {
1911/* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
1912/* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
1913/* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
1914/* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
1915}, {
1916/* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
1917/* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
1918
1919/* 287 instructions.  Note that although the indirect field		*/
1920/* indicates opFP1n2 for further decoding, this is not necessarily	*/
1921/* the case since the opFP arrays are not partitioned according to key1	*/
1922/* and key2.  opFP1n2 is given only to indicate that we haven't		*/
1923/* finished decoding the instruction.					*/
1924/* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
1925/* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
1926}, {
1927/* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
1928/* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
1929/* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
1930/* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
1931}, {
1932/* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
1933/* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
1934/* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
1935/* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
1936} };
1937
1938/* END CSTYLED */
1939
1940/*
1941 * common functions to decode and disassemble an x86 or amd64 instruction
1942 */
1943
1944/*
1945 * These are the individual fields of a REX prefix. Note that a REX
1946 * prefix with none of these set is still needed to:
1947 *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
1948 *	- access the %sil, %dil, %bpl, %spl registers
1949 */
1950#define	REX_W 0x08	/* 64 bit operand size when set */
1951#define	REX_R 0x04	/* high order bit extension of ModRM reg field */
1952#define	REX_X 0x02	/* high order bit extension of SIB index field */
1953#define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
1954
1955/*
1956 * These are the individual fields of a VEX prefix.
1957 */
1958#define	VEX_R 0x08	/* REX.R in 1's complement form */
1959#define	VEX_X 0x04	/* REX.X in 1's complement form */
1960#define	VEX_B 0x02	/* REX.B in 1's complement form */
1961/* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
1962#define	VEX_L 0x04
1963#define	VEX_W 0x08	/* opcode specific, use like REX.W */
1964#define	VEX_m 0x1F	/* VEX m-mmmm field */
1965#define	VEX_v 0x78	/* VEX register specifier */
1966#define	VEX_p 0x03	/* VEX pp field, opcode extension */
1967
1968/* VEX m-mmmm field, only used by three bytes prefix */
1969#define	VEX_m_0F 0x01   /* implied 0F leading opcode byte */
1970#define	VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
1971#define	VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
1972
1973/* VEX pp field, providing equivalent functionality of a SIMD prefix */
1974#define	VEX_p_66 0x01
1975#define	VEX_p_F3 0x02
1976#define	VEX_p_F2 0x03
1977
1978/*
1979 * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
1980 */
1981static int isize[] = {1, 2, 4, 4};
1982static int isize64[] = {1, 2, 4, 8};
1983
1984/*
1985 * Just a bunch of useful macros.
1986 */
1987#define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
1988#define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
1989#define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
1990#define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
1991#define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
1992
1993#define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
1994
1995#define	BYTE_OPND	0	/* w-bit value indicating byte register */
1996#define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
1997#define	MM_OPND		2	/* "value" used to indicate a mmx reg */
1998#define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
1999#define	SEG_OPND	4	/* "value" used to indicate a segment reg */
2000#define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
2001#define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
2002#define	TEST_OPND	7	/* "value" used to indicate a test reg */
2003#define	WORD_OPND	8	/* w-bit value indicating word size reg */
2004#define	YMM_OPND	9	/* "value" used to indicate a ymm reg */
2005
2006/*
2007 * Get the next byte and separate the op code into the high and low nibbles.
2008 */
2009static int
2010dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
2011{
2012	int byte;
2013
2014	/*
2015	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
2016	 * we try to read more.
2017	 */
2018	if (x->d86_len >= 15)
2019		return (x->d86_error = 1);
2020
2021	if (x->d86_error)
2022		return (1);
2023	byte = x->d86_get_byte(x->d86_data);
2024	if (byte < 0)
2025		return (x->d86_error = 1);
2026	x->d86_bytes[x->d86_len++] = byte;
2027	*low = byte & 0xf;		/* ----xxxx low 4 bits */
2028	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
2029	return (0);
2030}
2031
2032/*
2033 * Get and decode an SIB (scaled index base) byte
2034 */
2035static void
2036dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
2037{
2038	int byte;
2039
2040	if (x->d86_error)
2041		return;
2042
2043	byte = x->d86_get_byte(x->d86_data);
2044	if (byte < 0) {
2045		x->d86_error = 1;
2046		return;
2047	}
2048	x->d86_bytes[x->d86_len++] = byte;
2049
2050	*base = byte & 0x7;
2051	*index = (byte >> 3) & 0x7;
2052	*ss = (byte >> 6) & 0x3;
2053}
2054
2055/*
2056 * Get the byte following the op code and separate it into the
2057 * mode, register, and r/m fields.
2058 */
2059static void
2060dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
2061{
2062	if (x->d86_got_modrm == 0) {
2063		if (x->d86_rmindex == -1)
2064			x->d86_rmindex = x->d86_len;
2065		dtrace_get_SIB(x, mode, reg, r_m);
2066		x->d86_got_modrm = 1;
2067	}
2068}
2069
2070/*
2071 * Adjust register selection based on any REX prefix bits present.
2072 */
2073/*ARGSUSED*/
2074static void
2075dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
2076{
2077	if (reg != NULL && r_m == NULL) {
2078		if (rex_prefix & REX_B)
2079			*reg += 8;
2080	} else {
2081		if (reg != NULL && (REX_R & rex_prefix) != 0)
2082			*reg += 8;
2083		if (r_m != NULL && (REX_B & rex_prefix) != 0)
2084			*r_m += 8;
2085	}
2086}
2087
2088/*
2089 * Adjust register selection based on any VEX prefix bits present.
2090 * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
2091 */
2092/*ARGSUSED*/
2093static void
2094dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
2095{
2096	if (reg != NULL && r_m == NULL) {
2097		if (!(vex_byte1 & VEX_B))
2098			*reg += 8;
2099	} else {
2100		if (reg != NULL && ((VEX_R & vex_byte1) == 0))
2101			*reg += 8;
2102		if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
2103			*r_m += 8;
2104	}
2105}
2106
2107/*
2108 * Get an immediate operand of the given size, with sign extension.
2109 */
2110static void
2111dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
2112{
2113	int i;
2114	int byte;
2115	int valsize;
2116
2117	if (x->d86_numopnds < opindex + 1)
2118		x->d86_numopnds = opindex + 1;
2119
2120	switch (wbit) {
2121	case BYTE_OPND:
2122		valsize = 1;
2123		break;
2124	case LONG_OPND:
2125		if (x->d86_opnd_size == SIZE16)
2126			valsize = 2;
2127		else if (x->d86_opnd_size == SIZE32)
2128			valsize = 4;
2129		else
2130			valsize = 8;
2131		break;
2132	case MM_OPND:
2133	case XMM_OPND:
2134	case YMM_OPND:
2135	case SEG_OPND:
2136	case CONTROL_OPND:
2137	case DEBUG_OPND:
2138	case TEST_OPND:
2139		valsize = size;
2140		break;
2141	case WORD_OPND:
2142		valsize = 2;
2143		break;
2144	}
2145	if (valsize < size)
2146		valsize = size;
2147
2148	if (x->d86_error)
2149		return;
2150	x->d86_opnd[opindex].d86_value = 0;
2151	for (i = 0; i < size; ++i) {
2152		byte = x->d86_get_byte(x->d86_data);
2153		if (byte < 0) {
2154			x->d86_error = 1;
2155			return;
2156		}
2157		x->d86_bytes[x->d86_len++] = byte;
2158		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
2159	}
2160	/* Do sign extension */
2161	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
2162		for (; i < sizeof (uint64_t); i++)
2163			x->d86_opnd[opindex].d86_value |=
2164			    (uint64_t)0xff << (i * 8);
2165	}
2166#ifdef DIS_TEXT
2167	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2168	x->d86_opnd[opindex].d86_value_size = valsize;
2169	x->d86_imm_bytes += size;
2170#endif
2171}
2172
2173/*
2174 * Get an ip relative operand of the given size, with sign extension.
2175 */
2176static void
2177dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
2178{
2179	dtrace_imm_opnd(x, wbit, size, opindex);
2180#ifdef DIS_TEXT
2181	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
2182#endif
2183}
2184
2185/*
2186 * Check to see if there is a segment override prefix pending.
2187 * If so, print it in the current 'operand' location and set
2188 * the override flag back to false.
2189 */
2190/*ARGSUSED*/
2191static void
2192dtrace_check_override(dis86_t *x, int opindex)
2193{
2194#ifdef DIS_TEXT
2195	if (x->d86_seg_prefix) {
2196		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
2197		    x->d86_seg_prefix, PFIXLEN);
2198	}
2199#endif
2200	x->d86_seg_prefix = NULL;
2201}
2202
2203
2204/*
2205 * Process a single instruction Register or Memory operand.
2206 *
2207 * mode = addressing mode from ModRM byte
2208 * r_m = r_m (or reg if mode == 3) field from ModRM byte
2209 * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
2210 * o = index of operand that we are processing (0, 1 or 2)
2211 *
2212 * the value of reg or r_m must have already been adjusted for any REX prefix.
2213 */
2214/*ARGSUSED*/
2215static void
2216dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
2217{
2218	int have_SIB = 0;	/* flag presence of scale-index-byte */
2219	uint_t ss;		/* scale-factor from opcode */
2220	uint_t index;		/* index register number */
2221	uint_t base;		/* base register number */
2222	int dispsize;   	/* size of displacement in bytes */
2223#ifdef DIS_TEXT
2224	char *opnd = x->d86_opnd[opindex].d86_opnd;
2225#endif
2226
2227	if (x->d86_numopnds < opindex + 1)
2228		x->d86_numopnds = opindex + 1;
2229
2230	if (x->d86_error)
2231		return;
2232
2233	/*
2234	 * first handle a simple register
2235	 */
2236	if (mode == REG_ONLY) {
2237#ifdef DIS_TEXT
2238		switch (wbit) {
2239		case MM_OPND:
2240			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
2241			break;
2242		case XMM_OPND:
2243			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
2244			break;
2245		case YMM_OPND:
2246			(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
2247			break;
2248		case SEG_OPND:
2249			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
2250			break;
2251		case CONTROL_OPND:
2252			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
2253			break;
2254		case DEBUG_OPND:
2255			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
2256			break;
2257		case TEST_OPND:
2258			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
2259			break;
2260		case BYTE_OPND:
2261			if (x->d86_rex_prefix == 0)
2262				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
2263			else
2264				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
2265			break;
2266		case WORD_OPND:
2267			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2268			break;
2269		case LONG_OPND:
2270			if (x->d86_opnd_size == SIZE16)
2271				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2272			else if (x->d86_opnd_size == SIZE32)
2273				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
2274			else
2275				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
2276			break;
2277		}
2278#endif /* DIS_TEXT */
2279		return;
2280	}
2281
2282	/*
2283	 * if symbolic representation, skip override prefix, if any
2284	 */
2285	dtrace_check_override(x, opindex);
2286
2287	/*
2288	 * Handle 16 bit memory references first, since they decode
2289	 * the mode values more simply.
2290	 * mode 1 is r_m + 8 bit displacement
2291	 * mode 2 is r_m + 16 bit displacement
2292	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
2293	 */
2294	if (x->d86_addr_size == SIZE16) {
2295		if ((mode == 0 && r_m == 6) || mode == 2)
2296			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
2297		else if (mode == 1)
2298			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
2299#ifdef DIS_TEXT
2300		if (mode == 0 && r_m == 6)
2301			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2302		else if (mode == 0)
2303			x->d86_opnd[opindex].d86_mode = MODE_NONE;
2304		else
2305			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2306		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
2307#endif
2308		return;
2309	}
2310
2311	/*
2312	 * 32 and 64 bit addressing modes are more complex since they
2313	 * can involve an SIB (scaled index and base) byte to decode.
2314	 */
2315	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
2316		have_SIB = 1;
2317		dtrace_get_SIB(x, &ss, &index, &base);
2318		if (x->d86_error)
2319			return;
2320		if (base != 5 || mode != 0)
2321			if (x->d86_rex_prefix & REX_B)
2322				base += 8;
2323		if (x->d86_rex_prefix & REX_X)
2324			index += 8;
2325	} else {
2326		base = r_m;
2327	}
2328
2329	/*
2330	 * Compute the displacement size and get its bytes
2331	 */
2332	dispsize = 0;
2333
2334	if (mode == 1)
2335		dispsize = 1;
2336	else if (mode == 2)
2337		dispsize = 4;
2338	else if ((r_m & 7) == EBP_REGNO ||
2339	    (have_SIB && (base & 7) == EBP_REGNO))
2340		dispsize = 4;
2341
2342	if (dispsize > 0) {
2343		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
2344		    dispsize, opindex);
2345		if (x->d86_error)
2346			return;
2347	}
2348
2349#ifdef DIS_TEXT
2350	if (dispsize > 0)
2351		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2352
2353	if (have_SIB == 0) {
2354		if (x->d86_mode == SIZE32) {
2355			if (mode == 0)
2356				(void) strlcat(opnd, dis_addr32_mode0[r_m],
2357				    OPLEN);
2358			else
2359				(void) strlcat(opnd, dis_addr32_mode12[r_m],
2360				    OPLEN);
2361		} else {
2362			if (mode == 0) {
2363				(void) strlcat(opnd, dis_addr64_mode0[r_m],
2364				    OPLEN);
2365				if (r_m == 5) {
2366					x->d86_opnd[opindex].d86_mode =
2367					    MODE_RIPREL;
2368				}
2369			} else {
2370				(void) strlcat(opnd, dis_addr64_mode12[r_m],
2371				    OPLEN);
2372			}
2373		}
2374	} else {
2375		uint_t need_paren = 0;
2376		char **regs;
2377		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
2378			regs = (char **)dis_REG32;
2379		else
2380			regs = (char **)dis_REG64;
2381
2382		/*
2383		 * print the base (if any)
2384		 */
2385		if (base == EBP_REGNO && mode == 0) {
2386			if (index != ESP_REGNO) {
2387				(void) strlcat(opnd, "(", OPLEN);
2388				need_paren = 1;
2389			}
2390		} else {
2391			(void) strlcat(opnd, "(", OPLEN);
2392			(void) strlcat(opnd, regs[base], OPLEN);
2393			need_paren = 1;
2394		}
2395
2396		/*
2397		 * print the index (if any)
2398		 */
2399		if (index != ESP_REGNO) {
2400			(void) strlcat(opnd, ",", OPLEN);
2401			(void) strlcat(opnd, regs[index], OPLEN);
2402			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
2403		} else
2404			if (need_paren)
2405				(void) strlcat(opnd, ")", OPLEN);
2406	}
2407#endif
2408}
2409
2410/*
2411 * Operand sequence for standard instruction involving one register
2412 * and one register/memory operand.
2413 * wbit indicates a byte(0) or opnd_size(1) operation
2414 * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
2415 */
2416#define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
2417		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2418		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2419		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2420		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
2421}
2422
2423/*
2424 * Similar to above, but allows for the two operands to be of different
2425 * classes (ie. wbit).
2426 *	wbit is for the r_m operand
2427 *	w2 is for the reg operand
2428 */
2429#define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
2430		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2431		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2432		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2433		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
2434}
2435
2436/*
2437 * Similar, but for 2 operands plus an immediate.
2438 * vbit indicates direction
2439 * 	0 for "opcode imm, r, r_m" or
2440 *	1 for "opcode imm, r_m, r"
2441 */
2442#define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
2443		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2444		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2445		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
2446		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
2447		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2448}
2449
2450/*
2451 * Similar, but for 2 operands plus two immediates.
2452 */
2453#define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
2454		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2455		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2456		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2457		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
2458		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2459		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2460}
2461
2462/*
2463 * 1 operands plus two immediates.
2464 */
2465#define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
2466		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2467		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2468		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2469		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2470		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2471}
2472
2473/*
2474 * Dissassemble a single x86 or amd64 instruction.
2475 *
2476 * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
2477 * for interpreting instructions.
2478 *
2479 * returns non-zero for bad opcode
2480 */
2481int
2482dtrace_disx86(dis86_t *x, uint_t cpu_mode)
2483{
2484	instable_t *dp;		/* decode table being used */
2485#ifdef DIS_TEXT
2486	uint_t i;
2487#endif
2488#ifdef DIS_MEM
2489	uint_t nomem = 0;
2490#define	NOMEM	(nomem = 1)
2491#else
2492#define	NOMEM	/* nothing */
2493#endif
2494	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
2495	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
2496	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
2497	uint_t w2;		/* wbit value for second operand */
2498	uint_t vbit;
2499	uint_t mode = 0;	/* mode value from ModRM byte */
2500	uint_t reg;		/* reg value from ModRM byte */
2501	uint_t r_m;		/* r_m value from ModRM byte */
2502
2503	uint_t opcode1;		/* high nibble of 1st byte */
2504	uint_t opcode2;		/* low nibble of 1st byte */
2505	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
2506	uint_t opcode4;		/* high nibble of 2nd byte */
2507	uint_t opcode5;		/* low nibble of 2nd byte */
2508	uint_t opcode6;		/* high nibble of 3rd byte */
2509	uint_t opcode7;		/* low nibble of 3rd byte */
2510	uint_t opcode_bytes = 1;
2511
2512	/*
2513	 * legacy prefixes come in 5 flavors, you should have only one of each
2514	 */
2515	uint_t	opnd_size_prefix = 0;
2516	uint_t	addr_size_prefix = 0;
2517	uint_t	segment_prefix = 0;
2518	uint_t	lock_prefix = 0;
2519	uint_t	rep_prefix = 0;
2520	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
2521
2522	/*
2523	 * Intel VEX instruction encoding prefix and fields
2524	 */
2525
2526	/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
2527	uint_t vex_prefix = 0;
2528
2529	/*
2530	 * VEX prefix byte 1, includes vex.r, vex.x and vex.b
2531	 * (for 3 bytes prefix)
2532	 */
2533	uint_t vex_byte1 = 0;
2534
2535	/*
2536	 * For 32-bit mode, it should prefetch the next byte to
2537	 * distinguish between AVX and les/lds
2538	 */
2539	uint_t vex_prefetch = 0;
2540
2541	uint_t vex_m = 0;
2542	uint_t vex_v = 0;
2543	uint_t vex_p = 0;
2544	uint_t vex_R = 1;
2545	uint_t vex_X = 1;
2546	uint_t vex_B = 1;
2547	uint_t vex_W = 0;
2548	uint_t vex_L;
2549
2550
2551	size_t	off;
2552
2553	instable_t dp_mmx;
2554
2555	x->d86_len = 0;
2556	x->d86_rmindex = -1;
2557	x->d86_error = 0;
2558#ifdef DIS_TEXT
2559	x->d86_numopnds = 0;
2560	x->d86_seg_prefix = NULL;
2561	x->d86_mnem[0] = 0;
2562	for (i = 0; i < 4; ++i) {
2563		x->d86_opnd[i].d86_opnd[0] = 0;
2564		x->d86_opnd[i].d86_prefix[0] = 0;
2565		x->d86_opnd[i].d86_value_size = 0;
2566		x->d86_opnd[i].d86_value = 0;
2567		x->d86_opnd[i].d86_mode = MODE_NONE;
2568	}
2569#endif
2570	x->d86_rex_prefix = 0;
2571	x->d86_got_modrm = 0;
2572	x->d86_memsize = 0;
2573
2574	if (cpu_mode == SIZE16) {
2575		opnd_size = SIZE16;
2576		addr_size = SIZE16;
2577	} else if (cpu_mode == SIZE32) {
2578		opnd_size = SIZE32;
2579		addr_size = SIZE32;
2580	} else {
2581		opnd_size = SIZE32;
2582		addr_size = SIZE64;
2583	}
2584
2585	/*
2586	 * Get one opcode byte and check for zero padding that follows
2587	 * jump tables.
2588	 */
2589	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2590		goto error;
2591
2592	if (opcode1 == 0 && opcode2 == 0 &&
2593	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
2594#ifdef DIS_TEXT
2595		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
2596#endif
2597		goto done;
2598	}
2599
2600	/*
2601	 * Gather up legacy x86 prefix bytes.
2602	 */
2603	for (;;) {
2604		uint_t *which_prefix = NULL;
2605
2606		dp = (instable_t *)&dis_distable[opcode1][opcode2];
2607
2608		switch (dp->it_adrmode) {
2609		case PREFIX:
2610			which_prefix = &rep_prefix;
2611			break;
2612		case LOCK:
2613			which_prefix = &lock_prefix;
2614			break;
2615		case OVERRIDE:
2616			which_prefix = &segment_prefix;
2617#ifdef DIS_TEXT
2618			x->d86_seg_prefix = (char *)dp->it_name;
2619#endif
2620			if (dp->it_invalid64 && cpu_mode == SIZE64)
2621				goto error;
2622			break;
2623		case AM:
2624			which_prefix = &addr_size_prefix;
2625			break;
2626		case DM:
2627			which_prefix = &opnd_size_prefix;
2628			break;
2629		}
2630		if (which_prefix == NULL)
2631			break;
2632		*which_prefix = (opcode1 << 4) | opcode2;
2633		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2634			goto error;
2635	}
2636
2637	/*
2638	 * Handle amd64 mode PREFIX values.
2639	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
2640	 * We might have a REX prefix (opcodes 0x40-0x4f)
2641	 */
2642	if (cpu_mode == SIZE64) {
2643		if (segment_prefix != 0x64 && segment_prefix != 0x65)
2644			segment_prefix = 0;
2645
2646		if (opcode1 == 0x4) {
2647			rex_prefix = (opcode1 << 4) | opcode2;
2648			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2649				goto error;
2650			dp = (instable_t *)&dis_distable[opcode1][opcode2];
2651		} else if (opcode1 == 0xC &&
2652		    (opcode2 == 0x4 || opcode2 == 0x5)) {
2653			/* AVX instructions */
2654			vex_prefix = (opcode1 << 4) | opcode2;
2655			x->d86_rex_prefix = 0x40;
2656		}
2657	} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
2658		/* LDS, LES or AVX */
2659		dtrace_get_modrm(x, &mode, &reg, &r_m);
2660		vex_prefetch = 1;
2661
2662		if (mode == REG_ONLY) {
2663			/* AVX */
2664			vex_prefix = (opcode1 << 4) | opcode2;
2665			x->d86_rex_prefix = 0x40;
2666			opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
2667			opcode4 = ((reg << 3) | r_m) & 0x0F;
2668		}
2669	}
2670
2671	if (vex_prefix == VEX_2bytes) {
2672		if (!vex_prefetch) {
2673			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
2674				goto error;
2675		}
2676		vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
2677		vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
2678		vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
2679		vex_p = opcode4 & VEX_p;
2680		/*
2681		 * The vex.x and vex.b bits are not defined in two bytes
2682		 * mode vex prefix, their default values are 1
2683		 */
2684		vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
2685
2686		if (vex_R == 0)
2687			x->d86_rex_prefix |= REX_R;
2688
2689		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2690			goto error;
2691
2692		switch (vex_p) {
2693			case VEX_p_66:
2694				dp = (instable_t *)
2695				    &dis_opAVX660F[(opcode1 << 4) | opcode2];
2696				break;
2697			case VEX_p_F3:
2698				dp = (instable_t *)
2699				    &dis_opAVXF30F[(opcode1 << 4) | opcode2];
2700				break;
2701			case VEX_p_F2:
2702				dp = (instable_t *)
2703				    &dis_opAVXF20F [(opcode1 << 4) | opcode2];
2704				break;
2705			default:
2706				dp = (instable_t *)
2707				    &dis_opAVX0F[opcode1][opcode2];
2708
2709		}
2710
2711	} else if (vex_prefix == VEX_3bytes) {
2712		if (!vex_prefetch) {
2713			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
2714				goto error;
2715		}
2716		vex_R = (opcode3 & VEX_R) >> 3;
2717		vex_X = (opcode3 & VEX_X) >> 2;
2718		vex_B = (opcode3 & VEX_B) >> 1;
2719		vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
2720		vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
2721
2722		if (vex_R == 0)
2723			x->d86_rex_prefix |= REX_R;
2724		if (vex_X == 0)
2725			x->d86_rex_prefix |= REX_X;
2726		if (vex_B == 0)
2727			x->d86_rex_prefix |= REX_B;
2728
2729		if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
2730			goto error;
2731		vex_W = (opcode5 & VEX_W) >> 3;
2732		vex_L = (opcode6 & VEX_L) >> 2;
2733		vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
2734		vex_p = opcode6 & VEX_p;
2735
2736		if (vex_W)
2737			x->d86_rex_prefix |= REX_W;
2738
2739		/* Only these three vex_m values valid; others are reserved */
2740		if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
2741		    (vex_m != VEX_m_0F3A))
2742			goto error;
2743
2744		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
2745			goto error;
2746
2747		switch (vex_p) {
2748			case VEX_p_66:
2749				if (vex_m == VEX_m_0F) {
2750					dp = (instable_t *)
2751					    &dis_opAVX660F
2752					    [(opcode1 << 4) | opcode2];
2753				} else if (vex_m == VEX_m_0F38) {
2754					dp = (instable_t *)
2755					    &dis_opAVX660F38
2756					    [(opcode1 << 4) | opcode2];
2757				} else if (vex_m == VEX_m_0F3A) {
2758					dp = (instable_t *)
2759					    &dis_opAVX660F3A
2760					    [(opcode1 << 4) | opcode2];
2761				} else {
2762					goto error;
2763				}
2764				break;
2765			case VEX_p_F3:
2766				if (vex_m == VEX_m_0F) {
2767					dp = (instable_t *)
2768					    &dis_opAVXF30F
2769					    [(opcode1 << 4) | opcode2];
2770				} else {
2771					goto error;
2772				}
2773				break;
2774			case VEX_p_F2:
2775				if (vex_m == VEX_m_0F) {
2776					dp = (instable_t *)
2777					    &dis_opAVXF20F
2778					    [(opcode1 << 4) | opcode2];
2779				} else {
2780					goto error;
2781				}
2782				break;
2783			default:
2784				dp = (instable_t *)
2785				    &dis_opAVX0F[opcode1][opcode2];
2786
2787		}
2788	}
2789	if (vex_prefix) {
2790		if (vex_L)
2791			wbit = YMM_OPND;
2792		else
2793			wbit = XMM_OPND;
2794	}
2795
2796	/*
2797	 * Deal with selection of operand and address size now.
2798	 * Note that the REX.W bit being set causes opnd_size_prefix to be
2799	 * ignored.
2800	 */
2801	if (cpu_mode == SIZE64) {
2802		if ((rex_prefix & REX_W) || vex_W)
2803			opnd_size = SIZE64;
2804		else if (opnd_size_prefix)
2805			opnd_size = SIZE16;
2806
2807		if (addr_size_prefix)
2808			addr_size = SIZE32;
2809	} else if (cpu_mode == SIZE32) {
2810		if (opnd_size_prefix)
2811			opnd_size = SIZE16;
2812		if (addr_size_prefix)
2813			addr_size = SIZE16;
2814	} else {
2815		if (opnd_size_prefix)
2816			opnd_size = SIZE32;
2817		if (addr_size_prefix)
2818			addr_size = SIZE32;
2819	}
2820	/*
2821	 * The pause instruction - a repz'd nop.  This doesn't fit
2822	 * with any of the other prefix goop added for SSE, so we'll
2823	 * special-case it here.
2824	 */
2825	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
2826		rep_prefix = 0;
2827		dp = (instable_t *)&dis_opPause;
2828	}
2829
2830	/*
2831	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
2832	 * byte so we may need to perform a table indirection.
2833	 */
2834	if (dp->it_indirect == (instable_t *)dis_op0F) {
2835		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
2836			goto error;
2837		opcode_bytes = 2;
2838		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
2839			uint_t	subcode;
2840
2841			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2842				goto error;
2843			opcode_bytes = 3;
2844			subcode = ((opcode6 & 0x3) << 1) |
2845			    ((opcode7 & 0x8) >> 3);
2846			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
2847		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
2848			dp = (instable_t *)&dis_op0FC8[0];
2849		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
2850			opcode_bytes = 3;
2851			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2852				goto error;
2853			if (opnd_size == SIZE16)
2854				opnd_size = SIZE32;
2855
2856			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
2857#ifdef DIS_TEXT
2858			if (strcmp(dp->it_name, "INVALID") == 0)
2859				goto error;
2860#endif
2861			switch (dp->it_adrmode) {
2862				case XMMP_66r:
2863				case XMMPRM_66r:
2864				case XMM3PM_66r:
2865					if (opnd_size_prefix == 0) {
2866						goto error;
2867					}
2868					break;
2869				case XMMP_66o:
2870					if (opnd_size_prefix == 0) {
2871						/* SSSE3 MMX instructions */
2872						dp_mmx = *dp;
2873						dp = &dp_mmx;
2874						dp->it_adrmode = MMOPM_66o;
2875#ifdef	DIS_MEM
2876						dp->it_size = 8;
2877#endif
2878					}
2879					break;
2880				default:
2881					goto error;
2882			}
2883		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
2884			opcode_bytes = 3;
2885			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
2886				goto error;
2887			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
2888
2889			/*
2890			 * Both crc32 and movbe have the same 3rd opcode
2891			 * byte of either 0xF0 or 0xF1, so we use another
2892			 * indirection to distinguish between the two.
2893			 */
2894			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
2895			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
2896
2897				dp = dp->it_indirect;
2898				if (rep_prefix != 0xF2) {
2899					/* It is movbe */
2900					dp++;
2901				}
2902			}
2903#ifdef DIS_TEXT
2904			if (strcmp(dp->it_name, "INVALID") == 0)
2905				goto error;
2906#endif
2907			switch (dp->it_adrmode) {
2908				case XMM_66r:
2909				case XMMM_66r:
2910					if (opnd_size_prefix == 0) {
2911						goto error;
2912					}
2913					break;
2914				case XMM_66o:
2915					if (opnd_size_prefix == 0) {
2916						/* SSSE3 MMX instructions */
2917						dp_mmx = *dp;
2918						dp = &dp_mmx;
2919						dp->it_adrmode = MM;
2920#ifdef	DIS_MEM
2921						dp->it_size = 8;
2922#endif
2923					}
2924					break;
2925				case CRC32:
2926					if (rep_prefix != 0xF2) {
2927						goto error;
2928					}
2929					rep_prefix = 0;
2930					break;
2931				case MOVBE:
2932					if (rep_prefix != 0x0) {
2933						goto error;
2934					}
2935					break;
2936				default:
2937					goto error;
2938			}
2939		} else {
2940			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
2941		}
2942	}
2943
2944	/*
2945	 * If still not at a TERM decode entry, then a ModRM byte
2946	 * exists and its fields further decode the instruction.
2947	 */
2948	x->d86_got_modrm = 0;
2949	if (dp->it_indirect != TERM) {
2950		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
2951		if (x->d86_error)
2952			goto error;
2953		reg = opcode3;
2954
2955		/*
2956		 * decode 287 instructions (D8-DF) from opcodeN
2957		 */
2958		if (opcode1 == 0xD && opcode2 >= 0x8) {
2959			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
2960				dp = (instable_t *)&dis_opFP5[r_m];
2961			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
2962				dp = (instable_t *)&dis_opFP7[opcode3];
2963			else if (opcode2 == 0xB && mode == 0x3)
2964				dp = (instable_t *)&dis_opFP6[opcode3];
2965			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
2966				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
2967			else if (mode == 0x3)
2968				dp = (instable_t *)
2969				    &dis_opFP3[opcode2 - 8][opcode3];
2970			else
2971				dp = (instable_t *)
2972				    &dis_opFP1n2[opcode2 - 8][opcode3];
2973		} else {
2974			dp = (instable_t *)dp->it_indirect + opcode3;
2975		}
2976	}
2977
2978	/*
2979	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
2980	 * (sign extend 32bit to 64 bit)
2981	 */
2982	if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
2983	    opcode1 == 0x6 && opcode2 == 0x3)
2984		dp = (instable_t *)&dis_opMOVSLD;
2985
2986	/*
2987	 * at this point we should have a correct (or invalid) opcode
2988	 */
2989	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
2990	    cpu_mode != SIZE64 && dp->it_invalid32)
2991		goto error;
2992	if (dp->it_indirect != TERM)
2993		goto error;
2994
2995	/*
2996	 * deal with MMX/SSE opcodes which are changed by prefixes
2997	 */
2998	switch (dp->it_adrmode) {
2999	case MMO:
3000	case MMOIMPL:
3001	case MMO3P:
3002	case MMOM3:
3003	case MMOMS:
3004	case MMOPM:
3005	case MMOPRM:
3006	case MMOS:
3007	case XMMO:
3008	case XMMOM:
3009	case XMMOMS:
3010	case XMMOPM:
3011	case XMMOS:
3012	case XMMOMX:
3013	case XMMOX3:
3014	case XMMOXMM:
3015		/*
3016		 * This is horrible.  Some SIMD instructions take the
3017		 * form 0x0F 0x?? ..., which is easily decoded using the
3018		 * existing tables.  Other SIMD instructions use various
3019		 * prefix bytes to overload existing instructions.  For
3020		 * Example, addps is F0, 58, whereas addss is F3 (repz),
3021		 * F0, 58.  Presumably someone got a raise for this.
3022		 *
3023		 * If we see one of the instructions which can be
3024		 * modified in this way (if we've got one of the SIMDO*
3025		 * address modes), we'll check to see if the last prefix
3026		 * was a repz.  If it was, we strip the prefix from the
3027		 * mnemonic, and we indirect using the dis_opSIMDrepz
3028		 * table.
3029		 */
3030
3031		/*
3032		 * Calculate our offset in dis_op0F
3033		 */
3034		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
3035			goto error;
3036
3037		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3038		    sizeof (instable_t);
3039
3040		/*
3041		 * Rewrite if this instruction used one of the magic prefixes.
3042		 */
3043		if (rep_prefix) {
3044			if (rep_prefix == 0xf2)
3045				dp = (instable_t *)&dis_opSIMDrepnz[off];
3046			else
3047				dp = (instable_t *)&dis_opSIMDrepz[off];
3048			rep_prefix = 0;
3049		} else if (opnd_size_prefix) {
3050			dp = (instable_t *)&dis_opSIMDdata16[off];
3051			opnd_size_prefix = 0;
3052			if (opnd_size == SIZE16)
3053				opnd_size = SIZE32;
3054		}
3055		break;
3056
3057	case MMOSH:
3058		/*
3059		 * As with the "normal" SIMD instructions, the MMX
3060		 * shuffle instructions are overloaded.  These
3061		 * instructions, however, are special in that they use
3062		 * an extra byte, and thus an extra table.  As of this
3063		 * writing, they only use the opnd_size prefix.
3064		 */
3065
3066		/*
3067		 * Calculate our offset in dis_op0F7123
3068		 */
3069		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
3070		    sizeof (dis_op0F7123))
3071			goto error;
3072
3073		if (opnd_size_prefix) {
3074			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
3075			    sizeof (instable_t);
3076			dp = (instable_t *)&dis_opSIMD7123[off];
3077			opnd_size_prefix = 0;
3078			if (opnd_size == SIZE16)
3079				opnd_size = SIZE32;
3080		}
3081		break;
3082	case MRw:
3083		if (rep_prefix) {
3084			if (rep_prefix == 0xf3) {
3085
3086				/*
3087				 * Calculate our offset in dis_op0F
3088				 */
3089				if ((uintptr_t)dp - (uintptr_t)dis_op0F
3090				    > sizeof (dis_op0F))
3091					goto error;
3092
3093				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3094				    sizeof (instable_t);
3095
3096				dp = (instable_t *)&dis_opSIMDrepz[off];
3097				rep_prefix = 0;
3098			} else {
3099				goto error;
3100			}
3101		}
3102		break;
3103	}
3104
3105	/*
3106	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
3107	 */
3108	if (cpu_mode == SIZE64)
3109		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
3110			opnd_size = SIZE64;
3111
3112#ifdef DIS_TEXT
3113	/*
3114	 * At this point most instructions can format the opcode mnemonic
3115	 * including the prefixes.
3116	 */
3117	if (lock_prefix)
3118		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
3119
3120	if (rep_prefix == 0xf2)
3121		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
3122	else if (rep_prefix == 0xf3)
3123		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
3124
3125	if (cpu_mode == SIZE64 && addr_size_prefix)
3126		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
3127
3128	if (dp->it_adrmode != CBW &&
3129	    dp->it_adrmode != CWD &&
3130	    dp->it_adrmode != XMMSFNC) {
3131		if (strcmp(dp->it_name, "INVALID") == 0)
3132			goto error;
3133		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
3134		if (dp->it_suffix) {
3135			char *types[] = {"", "w", "l", "q"};
3136			if (opcode_bytes == 2 && opcode4 == 4) {
3137				/* It's a cmovx.yy. Replace the suffix x */
3138				for (i = 5; i < OPLEN; i++) {
3139					if (x->d86_mnem[i] == '.')
3140						break;
3141				}
3142				x->d86_mnem[i - 1] = *types[opnd_size];
3143			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
3144			    ((opcode6 == 1 && opcode7 == 6) ||
3145			    (opcode6 == 2 && opcode7 == 2))) {
3146				/*
3147				 * To handle PINSRD and PEXTRD
3148				 */
3149				(void) strlcat(x->d86_mnem, "d", OPLEN);
3150			} else {
3151				(void) strlcat(x->d86_mnem, types[opnd_size],
3152				    OPLEN);
3153			}
3154		}
3155	}
3156#endif
3157
3158	/*
3159	 * Process operands based on the addressing modes.
3160	 */
3161	x->d86_mode = cpu_mode;
3162	/*
3163	 * In vex mode the rex_prefix has no meaning
3164	 */
3165	if (!vex_prefix)
3166		x->d86_rex_prefix = rex_prefix;
3167	x->d86_opnd_size = opnd_size;
3168	x->d86_addr_size = addr_size;
3169	vbit = 0;		/* initialize for mem/reg -> reg */
3170	switch (dp->it_adrmode) {
3171		/*
3172		 * amd64 instruction to sign extend 32 bit reg/mem operands
3173		 * into 64 bit register values
3174		 */
3175	case MOVSXZ:
3176#ifdef DIS_TEXT
3177		if (rex_prefix == 0)
3178			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
3179#endif
3180		dtrace_get_modrm(x, &mode, &reg, &r_m);
3181		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3182		x->d86_opnd_size = SIZE64;
3183		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3184		x->d86_opnd_size = opnd_size = SIZE32;
3185		wbit = LONG_OPND;
3186		dtrace_get_operand(x, mode, r_m, wbit, 0);
3187		break;
3188
3189		/*
3190		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
3191		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
3192		 * wbit lives in 2nd byte, note that operands
3193		 * are different sized
3194		 */
3195	case MOVZ:
3196		if (rex_prefix & REX_W) {
3197			/* target register size = 64 bit */
3198			x->d86_mnem[5] = 'q';
3199		}
3200		dtrace_get_modrm(x, &mode, &reg, &r_m);
3201		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3202		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3203		x->d86_opnd_size = opnd_size = SIZE16;
3204		wbit = WBIT(opcode5);
3205		dtrace_get_operand(x, mode, r_m, wbit, 0);
3206		break;
3207	case CRC32:
3208		opnd_size = SIZE32;
3209		if (rex_prefix & REX_W)
3210			opnd_size = SIZE64;
3211		x->d86_opnd_size = opnd_size;
3212
3213		dtrace_get_modrm(x, &mode, &reg, &r_m);
3214		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3215		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3216		wbit = WBIT(opcode7);
3217		if (opnd_size_prefix)
3218			x->d86_opnd_size = opnd_size = SIZE16;
3219		dtrace_get_operand(x, mode, r_m, wbit, 0);
3220		break;
3221	case MOVBE:
3222		opnd_size = SIZE32;
3223		if (rex_prefix & REX_W)
3224			opnd_size = SIZE64;
3225		x->d86_opnd_size = opnd_size;
3226
3227		dtrace_get_modrm(x, &mode, &reg, &r_m);
3228		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3229		wbit = WBIT(opcode7);
3230		if (opnd_size_prefix)
3231			x->d86_opnd_size = opnd_size = SIZE16;
3232		if (wbit) {
3233			/* reg -> mem */
3234			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3235			dtrace_get_operand(x, mode, r_m, wbit, 1);
3236		} else {
3237			/* mem -> reg */
3238			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3239			dtrace_get_operand(x, mode, r_m, wbit, 0);
3240		}
3241		break;
3242
3243	/*
3244	 * imul instruction, with either 8-bit or longer immediate
3245	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
3246	 */
3247	case IMUL:
3248		wbit = LONG_OPND;
3249		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
3250		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
3251		break;
3252
3253	/* memory or register operand to register, with 'w' bit	*/
3254	case MRw:
3255		wbit = WBIT(opcode2);
3256		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3257		break;
3258
3259	/* register to memory or register operand, with 'w' bit	*/
3260	/* arpl happens to fit here also because it is odd */
3261	case RMw:
3262		if (opcode_bytes == 2)
3263			wbit = WBIT(opcode5);
3264		else
3265			wbit = WBIT(opcode2);
3266		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3267		break;
3268
3269	/* xaddb instruction */
3270	case XADDB:
3271		wbit = 0;
3272		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3273		break;
3274
3275	/* MMX register to memory or register operand		*/
3276	case MMS:
3277	case MMOS:
3278#ifdef DIS_TEXT
3279		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3280#else
3281		wbit = LONG_OPND;
3282#endif
3283		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3284		break;
3285
3286	/* MMX register to memory */
3287	case MMOMS:
3288		dtrace_get_modrm(x, &mode, &reg, &r_m);
3289		if (mode == REG_ONLY)
3290			goto error;
3291		wbit = MM_OPND;
3292		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3293		break;
3294
3295	/* Double shift. Has immediate operand specifying the shift. */
3296	case DSHIFT:
3297		wbit = LONG_OPND;
3298		dtrace_get_modrm(x, &mode, &reg, &r_m);
3299		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3300		dtrace_get_operand(x, mode, r_m, wbit, 2);
3301		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3302		dtrace_imm_opnd(x, wbit, 1, 0);
3303		break;
3304
3305	/*
3306	 * Double shift. With no immediate operand, specifies using %cl.
3307	 */
3308	case DSHIFTcl:
3309		wbit = LONG_OPND;
3310		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3311		break;
3312
3313	/* immediate to memory or register operand */
3314	case IMlw:
3315		wbit = WBIT(opcode2);
3316		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3317		dtrace_get_operand(x, mode, r_m, wbit, 1);
3318		/*
3319		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
3320		 */
3321		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
3322		break;
3323
3324	/* immediate to memory or register operand with the	*/
3325	/* 'w' bit present					*/
3326	case IMw:
3327		wbit = WBIT(opcode2);
3328		dtrace_get_modrm(x, &mode, &reg, &r_m);
3329		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3330		dtrace_get_operand(x, mode, r_m, wbit, 1);
3331		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3332		break;
3333
3334	/* immediate to register with register in low 3 bits	*/
3335	/* of op code						*/
3336	case IR:
3337		/* w-bit here (with regs) is bit 3 */
3338		wbit = opcode2 >>3 & 0x1;
3339		reg = REGNO(opcode2);
3340		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3341		mode = REG_ONLY;
3342		r_m = reg;
3343		dtrace_get_operand(x, mode, r_m, wbit, 1);
3344		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
3345		break;
3346
3347	/* MMX immediate shift of register */
3348	case MMSH:
3349	case MMOSH:
3350		wbit = MM_OPND;
3351		goto mm_shift;	/* in next case */
3352
3353	/* SIMD immediate shift of register */
3354	case XMMSH:
3355		wbit = XMM_OPND;
3356mm_shift:
3357		reg = REGNO(opcode7);
3358		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3359		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
3360		dtrace_imm_opnd(x, wbit, 1, 0);
3361		NOMEM;
3362		break;
3363
3364	/* accumulator to memory operand */
3365	case AO:
3366		vbit = 1;
3367		/*FALLTHROUGH*/
3368
3369	/* memory operand to accumulator */
3370	case OA:
3371		wbit = WBIT(opcode2);
3372		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
3373		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
3374#ifdef DIS_TEXT
3375		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
3376#endif
3377		break;
3378
3379
3380	/* segment register to memory or register operand */
3381	case SM:
3382		vbit = 1;
3383		/*FALLTHROUGH*/
3384
3385	/* memory or register operand to segment register */
3386	case MS:
3387		dtrace_get_modrm(x, &mode, &reg, &r_m);
3388		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3389		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
3390		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
3391		break;
3392
3393	/*
3394	 * rotate or shift instructions, which may shift by 1 or
3395	 * consult the cl register, depending on the 'v' bit
3396	 */
3397	case Mv:
3398		vbit = VBIT(opcode2);
3399		wbit = WBIT(opcode2);
3400		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3401		dtrace_get_operand(x, mode, r_m, wbit, 1);
3402#ifdef DIS_TEXT
3403		if (vbit) {
3404			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
3405		} else {
3406			x->d86_opnd[0].d86_mode = MODE_SIGNED;
3407			x->d86_opnd[0].d86_value_size = 1;
3408			x->d86_opnd[0].d86_value = 1;
3409		}
3410#endif
3411		break;
3412	/*
3413	 * immediate rotate or shift instructions
3414	 */
3415	case MvI:
3416		wbit = WBIT(opcode2);
3417normal_imm_mem:
3418		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3419		dtrace_get_operand(x, mode, r_m, wbit, 1);
3420		dtrace_imm_opnd(x, wbit, 1, 0);
3421		break;
3422
3423	/* bit test instructions */
3424	case MIb:
3425		wbit = LONG_OPND;
3426		goto normal_imm_mem;
3427
3428	/* single memory or register operand with 'w' bit present */
3429	case Mw:
3430		wbit = WBIT(opcode2);
3431just_mem:
3432		dtrace_get_modrm(x, &mode, &reg, &r_m);
3433		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3434		dtrace_get_operand(x, mode, r_m, wbit, 0);
3435		break;
3436
3437	case SWAPGS:
3438		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
3439#ifdef DIS_TEXT
3440			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
3441#endif
3442			NOMEM;
3443			break;
3444		}
3445		/*FALLTHROUGH*/
3446
3447	/* prefetch instruction - memory operand, but no memory acess */
3448	case PREF:
3449		NOMEM;
3450		/*FALLTHROUGH*/
3451
3452	/* single memory or register operand */
3453	case M:
3454		wbit = LONG_OPND;
3455		goto just_mem;
3456
3457	/* single memory or register byte operand */
3458	case Mb:
3459		wbit = BYTE_OPND;
3460		goto just_mem;
3461
3462	case MONITOR_MWAIT:
3463		if (mode == 3) {
3464			if (r_m == 0) {
3465#ifdef DIS_TEXT
3466				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
3467#endif
3468				NOMEM;
3469				break;
3470			} else if (r_m == 1) {
3471#ifdef DIS_TEXT
3472				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
3473#endif
3474				NOMEM;
3475				break;
3476			} else {
3477				goto error;
3478			}
3479		}
3480		/*FALLTHROUGH*/
3481	case XGETBV_XSETBV:
3482		if (mode == 3) {
3483			if (r_m == 0) {
3484#ifdef DIS_TEXT
3485				(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
3486#endif
3487				NOMEM;
3488				break;
3489			} else if (r_m == 1) {
3490#ifdef DIS_TEXT
3491				(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
3492#endif
3493				NOMEM;
3494				break;
3495			} else {
3496				goto error;
3497			}
3498
3499		}
3500		/*FALLTHROUGH*/
3501	case MO:
3502		/* Similar to M, but only memory (no direct registers) */
3503		wbit = LONG_OPND;
3504		dtrace_get_modrm(x, &mode, &reg, &r_m);
3505		if (mode == 3)
3506			goto error;
3507		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3508		dtrace_get_operand(x, mode, r_m, wbit, 0);
3509		break;
3510
3511	/* move special register to register or reverse if vbit */
3512	case SREG:
3513		switch (opcode5) {
3514
3515		case 2:
3516			vbit = 1;
3517			/*FALLTHROUGH*/
3518		case 0:
3519			wbit = CONTROL_OPND;
3520			break;
3521
3522		case 3:
3523			vbit = 1;
3524			/*FALLTHROUGH*/
3525		case 1:
3526			wbit = DEBUG_OPND;
3527			break;
3528
3529		case 6:
3530			vbit = 1;
3531			/*FALLTHROUGH*/
3532		case 4:
3533			wbit = TEST_OPND;
3534			break;
3535
3536		}
3537		dtrace_get_modrm(x, &mode, &reg, &r_m);
3538		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3539		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
3540		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
3541		NOMEM;
3542		break;
3543
3544	/*
3545	 * single register operand with register in the low 3
3546	 * bits of op code
3547	 */
3548	case R:
3549		if (opcode_bytes == 2)
3550			reg = REGNO(opcode5);
3551		else
3552			reg = REGNO(opcode2);
3553		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3554		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3555		NOMEM;
3556		break;
3557
3558	/*
3559	 * register to accumulator with register in the low 3
3560	 * bits of op code, xchg instructions
3561	 */
3562	case RA:
3563		NOMEM;
3564		reg = REGNO(opcode2);
3565		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3566		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3567		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
3568		break;
3569
3570	/*
3571	 * single segment register operand, with register in
3572	 * bits 3-4 of op code byte
3573	 */
3574	case SEG:
3575		NOMEM;
3576		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
3577		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
3578		break;
3579
3580	/*
3581	 * single segment register operand, with register in
3582	 * bits 3-5 of op code
3583	 */
3584	case LSEG:
3585		NOMEM;
3586		/* long seg reg from opcode */
3587		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
3588		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
3589		break;
3590
3591	/* memory or register operand to register */
3592	case MR:
3593		if (vex_prefetch)
3594			x->d86_got_modrm = 1;
3595		wbit = LONG_OPND;
3596		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3597		break;
3598
3599	case RM:
3600		wbit = LONG_OPND;
3601		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3602		break;
3603
3604	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
3605	case MM:
3606	case MMO:
3607#ifdef DIS_TEXT
3608		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3609#else
3610		wbit = LONG_OPND;
3611#endif
3612		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
3613		break;
3614
3615	case MMOIMPL:
3616#ifdef DIS_TEXT
3617		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3618#else
3619		wbit = LONG_OPND;
3620#endif
3621		dtrace_get_modrm(x, &mode, &reg, &r_m);
3622		if (mode != REG_ONLY)
3623			goto error;
3624
3625		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3626		dtrace_get_operand(x, mode, r_m, wbit, 0);
3627		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
3628		mode = 0;	/* change for memory access size... */
3629		break;
3630
3631	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
3632	case MMO3P:
3633		wbit = MM_OPND;
3634		goto xmm3p;
3635	case XMM3P:
3636		wbit = XMM_OPND;
3637xmm3p:
3638		dtrace_get_modrm(x, &mode, &reg, &r_m);
3639		if (mode != REG_ONLY)
3640			goto error;
3641
3642		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
3643		    1);
3644		NOMEM;
3645		break;
3646
3647	case XMM3PM_66r:
3648		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
3649		    1, 0);
3650		break;
3651
3652	/* MMX/SIMD-Int predicated r32/mem to mm reg */
3653	case MMOPRM:
3654		wbit = LONG_OPND;
3655		w2 = MM_OPND;
3656		goto xmmprm;
3657	case XMMPRM:
3658	case XMMPRM_66r:
3659		wbit = LONG_OPND;
3660		w2 = XMM_OPND;
3661xmmprm:
3662		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
3663		break;
3664
3665	/* MMX/SIMD-Int predicated mm/mem to mm reg */
3666	case MMOPM:
3667	case MMOPM_66o:
3668		wbit = w2 = MM_OPND;
3669		goto xmmprm;
3670
3671	/* MMX/SIMD-Int mm reg to r32 */
3672	case MMOM3:
3673		NOMEM;
3674		dtrace_get_modrm(x, &mode, &reg, &r_m);
3675		if (mode != REG_ONLY)
3676			goto error;
3677		wbit = MM_OPND;
3678		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
3679		break;
3680
3681	/* SIMD memory or xmm reg operand to xmm reg		*/
3682	case XMM:
3683	case XMM_66o:
3684	case XMM_66r:
3685	case XMMO:
3686	case XMMXIMPL:
3687		wbit = XMM_OPND;
3688		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3689
3690		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
3691			goto error;
3692
3693#ifdef DIS_TEXT
3694		/*
3695		 * movlps and movhlps share opcodes.  They differ in the
3696		 * addressing modes allowed for their operands.
3697		 * movhps and movlhps behave similarly.
3698		 */
3699		if (mode == REG_ONLY) {
3700			if (strcmp(dp->it_name, "movlps") == 0)
3701				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
3702			else if (strcmp(dp->it_name, "movhps") == 0)
3703				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
3704		}
3705#endif
3706		if (dp->it_adrmode == XMMXIMPL)
3707			mode = 0;	/* change for memory access size... */
3708		break;
3709
3710	/* SIMD xmm reg to memory or xmm reg */
3711	case XMMS:
3712	case XMMOS:
3713	case XMMMS:
3714	case XMMOMS:
3715		dtrace_get_modrm(x, &mode, &reg, &r_m);
3716#ifdef DIS_TEXT
3717		if ((strcmp(dp->it_name, "movlps") == 0 ||
3718		    strcmp(dp->it_name, "movhps") == 0 ||
3719		    strcmp(dp->it_name, "movntps") == 0) &&
3720		    mode == REG_ONLY)
3721			goto error;
3722#endif
3723		wbit = XMM_OPND;
3724		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
3725		break;
3726
3727	/* SIMD memory to xmm reg */
3728	case XMMM:
3729	case XMMM_66r:
3730	case XMMOM:
3731		wbit = XMM_OPND;
3732		dtrace_get_modrm(x, &mode, &reg, &r_m);
3733#ifdef DIS_TEXT
3734		if (mode == REG_ONLY) {
3735			if (strcmp(dp->it_name, "movhps") == 0)
3736				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
3737			else
3738				goto error;
3739		}
3740#endif
3741		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3742		break;
3743
3744	/* SIMD memory or r32 to xmm reg			*/
3745	case XMM3MX:
3746		wbit = LONG_OPND;
3747		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3748		break;
3749
3750	case XMM3MXS:
3751		wbit = LONG_OPND;
3752		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
3753		break;
3754
3755	/* SIMD memory or mm reg to xmm reg			*/
3756	case XMMOMX:
3757	/* SIMD mm to xmm */
3758	case XMMMX:
3759		wbit = MM_OPND;
3760		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
3761		break;
3762
3763	/* SIMD memory or xmm reg to mm reg			*/
3764	case XMMXMM:
3765	case XMMOXMM:
3766	case XMMXM:
3767		wbit = XMM_OPND;
3768		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
3769		break;
3770
3771
3772	/* SIMD memory or xmm reg to r32			*/
3773	case XMMXM3:
3774		wbit = XMM_OPND;
3775		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
3776		break;
3777
3778	/* SIMD xmm to r32					*/
3779	case XMMX3:
3780	case XMMOX3:
3781		dtrace_get_modrm(x, &mode, &reg, &r_m);
3782		if (mode != REG_ONLY)
3783			goto error;
3784		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3785		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
3786		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3787		NOMEM;
3788		break;
3789
3790	/* SIMD predicated memory or xmm reg with/to xmm reg */
3791	case XMMP:
3792	case XMMP_66r:
3793	case XMMP_66o:
3794	case XMMOPM:
3795		wbit = XMM_OPND;
3796		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
3797		    1);
3798
3799#ifdef DIS_TEXT
3800		/*
3801		 * cmpps and cmpss vary their instruction name based
3802		 * on the value of imm8.  Other XMMP instructions,
3803		 * such as shufps, require explicit specification of
3804		 * the predicate.
3805		 */
3806		if (dp->it_name[0] == 'c' &&
3807		    dp->it_name[1] == 'm' &&
3808		    dp->it_name[2] == 'p' &&
3809		    strlen(dp->it_name) == 5) {
3810			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
3811
3812			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
3813				goto error;
3814
3815			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
3816			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
3817			    OPLEN);
3818			(void) strlcat(x->d86_mnem,
3819			    dp->it_name + strlen(dp->it_name) - 2,
3820			    OPLEN);
3821			x->d86_opnd[0] = x->d86_opnd[1];
3822			x->d86_opnd[1] = x->d86_opnd[2];
3823			x->d86_numopnds = 2;
3824		}
3825#endif
3826		break;
3827
3828	case XMMX2I:
3829		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
3830		    1);
3831		NOMEM;
3832		break;
3833
3834	case XMM2I:
3835		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
3836		NOMEM;
3837		break;
3838
3839	/* immediate operand to accumulator */
3840	case IA:
3841		wbit = WBIT(opcode2);
3842		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3843		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3844		NOMEM;
3845		break;
3846
3847	/* memory or register operand to accumulator */
3848	case MA:
3849		wbit = WBIT(opcode2);
3850		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3851		dtrace_get_operand(x, mode, r_m, wbit, 0);
3852		break;
3853
3854	/* si register to di register used to reference memory		*/
3855	case SD:
3856#ifdef DIS_TEXT
3857		dtrace_check_override(x, 0);
3858		x->d86_numopnds = 2;
3859		if (addr_size == SIZE64) {
3860			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3861			    OPLEN);
3862			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3863			    OPLEN);
3864		} else if (addr_size == SIZE32) {
3865			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3866			    OPLEN);
3867			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3868			    OPLEN);
3869		} else {
3870			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3871			    OPLEN);
3872			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3873			    OPLEN);
3874		}
3875#endif
3876		wbit = LONG_OPND;
3877		break;
3878
3879	/* accumulator to di register				*/
3880	case AD:
3881		wbit = WBIT(opcode2);
3882#ifdef DIS_TEXT
3883		dtrace_check_override(x, 1);
3884		x->d86_numopnds = 2;
3885		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
3886		if (addr_size == SIZE64)
3887			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
3888			    OPLEN);
3889		else if (addr_size == SIZE32)
3890			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
3891			    OPLEN);
3892		else
3893			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
3894			    OPLEN);
3895#endif
3896		break;
3897
3898	/* si register to accumulator				*/
3899	case SA:
3900		wbit = WBIT(opcode2);
3901#ifdef DIS_TEXT
3902		dtrace_check_override(x, 0);
3903		x->d86_numopnds = 2;
3904		if (addr_size == SIZE64)
3905			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
3906			    OPLEN);
3907		else if (addr_size == SIZE32)
3908			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
3909			    OPLEN);
3910		else
3911			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
3912			    OPLEN);
3913		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
3914#endif
3915		break;
3916
3917	/*
3918	 * single operand, a 16/32 bit displacement
3919	 */
3920	case D:
3921		wbit = LONG_OPND;
3922		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3923		NOMEM;
3924		break;
3925
3926	/* jmp/call indirect to memory or register operand		*/
3927	case INM:
3928#ifdef DIS_TEXT
3929		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
3930#endif
3931		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3932		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
3933		wbit = LONG_OPND;
3934		break;
3935
3936	/*
3937	 * for long jumps and long calls -- a new code segment
3938	 * register and an offset in IP -- stored in object
3939	 * code in reverse order. Note - not valid in amd64
3940	 */
3941	case SO:
3942		dtrace_check_override(x, 1);
3943		wbit = LONG_OPND;
3944		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
3945#ifdef DIS_TEXT
3946		x->d86_opnd[1].d86_mode = MODE_SIGNED;
3947#endif
3948		/* will now get segment operand */
3949		dtrace_imm_opnd(x, wbit, 2, 0);
3950		break;
3951
3952	/*
3953	 * jmp/call. single operand, 8 bit displacement.
3954	 * added to current EIP in 'compofff'
3955	 */
3956	case BD:
3957		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
3958		NOMEM;
3959		break;
3960
3961	/* single 32/16 bit immediate operand			*/
3962	case I:
3963		wbit = LONG_OPND;
3964		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
3965		break;
3966
3967	/* single 8 bit immediate operand			*/
3968	case Ib:
3969		wbit = LONG_OPND;
3970		dtrace_imm_opnd(x, wbit, 1, 0);
3971		break;
3972
3973	case ENTER:
3974		wbit = LONG_OPND;
3975		dtrace_imm_opnd(x, wbit, 2, 0);
3976		dtrace_imm_opnd(x, wbit, 1, 1);
3977		switch (opnd_size) {
3978		case SIZE64:
3979			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
3980			break;
3981		case SIZE32:
3982			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
3983			break;
3984		case SIZE16:
3985			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
3986			break;
3987		}
3988
3989		break;
3990
3991	/* 16-bit immediate operand */
3992	case RET:
3993		wbit = LONG_OPND;
3994		dtrace_imm_opnd(x, wbit, 2, 0);
3995		break;
3996
3997	/* single 8 bit port operand				*/
3998	case P:
3999		dtrace_check_override(x, 0);
4000		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4001		NOMEM;
4002		break;
4003
4004	/* single operand, dx register (variable port instruction) */
4005	case V:
4006		x->d86_numopnds = 1;
4007		dtrace_check_override(x, 0);
4008#ifdef DIS_TEXT
4009		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
4010#endif
4011		NOMEM;
4012		break;
4013
4014	/*
4015	 * The int instruction, which has two forms:
4016	 * int 3 (breakpoint) or
4017	 * int n, where n is indicated in the subsequent
4018	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
4019	 * where, although the 3 looks  like an operand,
4020	 * it is implied by the opcode. It must be converted
4021	 * to the correct base and output.
4022	 */
4023	case INT3:
4024#ifdef DIS_TEXT
4025		x->d86_numopnds = 1;
4026		x->d86_opnd[0].d86_mode = MODE_SIGNED;
4027		x->d86_opnd[0].d86_value_size = 1;
4028		x->d86_opnd[0].d86_value = 3;
4029#endif
4030		NOMEM;
4031		break;
4032
4033	/* single 8 bit immediate operand			*/
4034	case INTx:
4035		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4036		NOMEM;
4037		break;
4038
4039	/* an unused byte must be discarded */
4040	case U:
4041		if (x->d86_get_byte(x->d86_data) < 0)
4042			goto error;
4043		x->d86_len++;
4044		NOMEM;
4045		break;
4046
4047	case CBW:
4048#ifdef DIS_TEXT
4049		if (opnd_size == SIZE16)
4050			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
4051		else if (opnd_size == SIZE32)
4052			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
4053		else
4054			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
4055#endif
4056		wbit = LONG_OPND;
4057		NOMEM;
4058		break;
4059
4060	case CWD:
4061#ifdef DIS_TEXT
4062		if (opnd_size == SIZE16)
4063			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
4064		else if (opnd_size == SIZE32)
4065			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
4066		else
4067			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
4068#endif
4069		wbit = LONG_OPND;
4070		NOMEM;
4071		break;
4072
4073	case XMMSFNC:
4074		/*
4075		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
4076		 * REG_ONLY, mnemonic should be 'clflush'.
4077		 */
4078		dtrace_get_modrm(x, &mode, &reg, &r_m);
4079
4080		/* sfence doesn't take operands */
4081#ifdef DIS_TEXT
4082		if (mode == REG_ONLY) {
4083			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
4084		} else {
4085			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
4086			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4087			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4088			NOMEM;
4089		}
4090#else
4091		if (mode != REG_ONLY) {
4092			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4093			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4094			NOMEM;
4095		}
4096#endif
4097		break;
4098
4099	/*
4100	 * no disassembly, the mnemonic was all there was so go on
4101	 */
4102	case NORM:
4103		if (dp->it_invalid32 && cpu_mode != SIZE64)
4104			goto error;
4105		NOMEM;
4106		/*FALLTHROUGH*/
4107	case IMPLMEM:
4108		break;
4109
4110	case XMMFENCE:
4111		/*
4112		 * XRSTOR and LFENCE share the same opcode but differ in mode
4113		 */
4114		dtrace_get_modrm(x, &mode, &reg, &r_m);
4115
4116		if (mode == REG_ONLY) {
4117			/*
4118			 * Only the following exact byte sequences are allowed:
4119			 *
4120			 * 	0f ae e8	lfence
4121			 * 	0f ae f0	mfence
4122			 */
4123			if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
4124			    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
4125				goto error;
4126		} else {
4127#ifdef DIS_TEXT
4128			(void) strncpy(x->d86_mnem, "xrstor", OPLEN);
4129#endif
4130			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4131			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4132		}
4133		break;
4134
4135	/* float reg */
4136	case F:
4137#ifdef DIS_TEXT
4138		x->d86_numopnds = 1;
4139		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
4140		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
4141#endif
4142		NOMEM;
4143		break;
4144
4145	/* float reg to float reg, with ret bit present */
4146	case FF:
4147		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
4148		/*FALLTHROUGH*/
4149	case FFC:				/* case for vbit always = 0 */
4150#ifdef DIS_TEXT
4151		x->d86_numopnds = 2;
4152		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
4153		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
4154		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
4155#endif
4156		NOMEM;
4157		break;
4158
4159	/* AVX instructions */
4160	case VEX_MO:
4161		/* op(ModR/M.r/m) */
4162		x->d86_numopnds = 1;
4163		dtrace_get_modrm(x, &mode, &reg, &r_m);
4164#ifdef DIS_TEXT
4165		if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
4166			(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
4167#endif
4168		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4169		dtrace_get_operand(x, mode, r_m, wbit, 0);
4170		break;
4171	case VEX_RMrX:
4172		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
4173		x->d86_numopnds = 3;
4174		dtrace_get_modrm(x, &mode, &reg, &r_m);
4175		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4176
4177		if (mode != REG_ONLY) {
4178			if ((dp == &dis_opAVXF20F[0x10]) ||
4179			    (dp == &dis_opAVXF30F[0x10])) {
4180				/* vmovsd <m64>, <xmm> */
4181				/* or vmovss <m64>, <xmm> */
4182				x->d86_numopnds = 2;
4183				goto L_VEX_MX;
4184			}
4185		}
4186
4187		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4188		/*
4189		 * VEX prefix uses the 1's complement form to encode the
4190		 * XMM/YMM regs
4191		 */
4192		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4193
4194		if ((dp == &dis_opAVXF20F[0x2A]) ||
4195		    (dp == &dis_opAVXF30F[0x2A])) {
4196			/*
4197			 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
4198			 * <xmm>, <xmm>
4199			 */
4200			wbit = LONG_OPND;
4201		}
4202#ifdef DIS_TEXT
4203		else if ((mode == REG_ONLY) &&
4204		    (dp == &dis_opAVX0F[0x1][0x6])) {	/* vmovlhps */
4205			(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
4206		} else if ((mode == REG_ONLY) &&
4207		    (dp == &dis_opAVX0F[0x1][0x2])) {	/* vmovhlps */
4208			(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
4209		}
4210#endif
4211		dtrace_get_operand(x, mode, r_m, wbit, 0);
4212
4213		break;
4214
4215	case VEX_RRX:
4216		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
4217		x->d86_numopnds = 3;
4218
4219		dtrace_get_modrm(x, &mode, &reg, &r_m);
4220		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4221
4222		if (mode != REG_ONLY) {
4223			if ((dp == &dis_opAVXF20F[0x11]) ||
4224			    (dp == &dis_opAVXF30F[0x11])) {
4225				/* vmovsd <xmm>, <m64> */
4226				/* or vmovss <xmm>, <m64> */
4227				x->d86_numopnds = 2;
4228				goto L_VEX_RM;
4229			}
4230		}
4231
4232		dtrace_get_operand(x, mode, r_m, wbit, 2);
4233		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4234		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4235		break;
4236
4237	case VEX_RMRX:
4238		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
4239		x->d86_numopnds = 4;
4240
4241		dtrace_get_modrm(x, &mode, &reg, &r_m);
4242		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4243		dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
4244		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
4245		if (dp == &dis_opAVX660F3A[0x18]) {
4246			/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
4247			dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
4248		} else if ((dp == &dis_opAVX660F3A[0x20]) ||
4249		    (dp == & dis_opAVX660F[0xC4])) {
4250			/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
4251			/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
4252			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4253		} else if (dp == &dis_opAVX660F3A[0x22]) {
4254			/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
4255#ifdef DIS_TEXT
4256			if (vex_W)
4257				x->d86_mnem[6] = 'q';
4258#endif
4259			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4260		} else {
4261			dtrace_get_operand(x, mode, r_m, wbit, 1);
4262		}
4263
4264		/* one byte immediate number */
4265		dtrace_imm_opnd(x, wbit, 1, 0);
4266
4267		/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
4268		if ((dp == &dis_opAVX660F3A[0x4A]) ||
4269		    (dp == &dis_opAVX660F3A[0x4B]) ||
4270		    (dp == &dis_opAVX660F3A[0x4C])) {
4271#ifdef DIS_TEXT
4272			int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
4273#endif
4274			x->d86_opnd[0].d86_mode = MODE_NONE;
4275#ifdef DIS_TEXT
4276			if (vex_L)
4277				(void) strncpy(x->d86_opnd[0].d86_opnd,
4278				    dis_YMMREG[regnum], OPLEN);
4279			else
4280				(void) strncpy(x->d86_opnd[0].d86_opnd,
4281				    dis_XMMREG[regnum], OPLEN);
4282#endif
4283		}
4284		break;
4285
4286	case VEX_MX:
4287		/* ModR/M.reg := op(ModR/M.rm) */
4288		x->d86_numopnds = 2;
4289
4290		dtrace_get_modrm(x, &mode, &reg, &r_m);
4291		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4292L_VEX_MX:
4293
4294		if ((dp == &dis_opAVXF20F[0xE6]) ||
4295		    (dp == &dis_opAVX660F[0x5A]) ||
4296		    (dp == &dis_opAVX660F[0xE6])) {
4297			/* vcvtpd2dq <ymm>, <xmm> */
4298			/* or vcvtpd2ps <ymm>, <xmm> */
4299			/* or vcvttpd2dq <ymm>, <xmm> */
4300			dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
4301			dtrace_get_operand(x, mode, r_m, wbit, 0);
4302		} else if ((dp == &dis_opAVXF30F[0xE6]) ||
4303		    (dp == &dis_opAVX0F[0x5][0xA])) {
4304			/* vcvtdq2pd <xmm>, <ymm> */
4305			/* or vcvtps2pd <xmm>, <ymm> */
4306			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4307			dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
4308		} else if (dp == &dis_opAVX660F[0x6E]) {
4309			/* vmovd/q <reg/mem 32/64>, <xmm> */
4310#ifdef DIS_TEXT
4311			if (vex_W)
4312				x->d86_mnem[4] = 'q';
4313#endif
4314			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4315			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4316		} else {
4317			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4318			dtrace_get_operand(x, mode, r_m, wbit, 0);
4319		}
4320
4321		break;
4322
4323	case VEX_MXI:
4324		/* ModR/M.reg := op(ModR/M.rm, imm8) */
4325		x->d86_numopnds = 3;
4326
4327		dtrace_get_modrm(x, &mode, &reg, &r_m);
4328		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4329
4330		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4331		dtrace_get_operand(x, mode, r_m, wbit, 1);
4332
4333		/* one byte immediate number */
4334		dtrace_imm_opnd(x, wbit, 1, 0);
4335		break;
4336
4337	case VEX_XXI:
4338		/* VEX.vvvv := op(ModR/M.rm, imm8) */
4339		x->d86_numopnds = 3;
4340
4341		dtrace_get_modrm(x, &mode, &reg, &r_m);
4342#ifdef DIS_TEXT
4343		(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
4344		    OPLEN);
4345#endif
4346		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4347
4348		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
4349		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
4350
4351		/* one byte immediate number */
4352		dtrace_imm_opnd(x, wbit, 1, 0);
4353		break;
4354
4355	case VEX_MR:
4356		/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
4357		if (dp == &dis_opAVX660F[0xC5]) {
4358			/* vpextrw <imm8>, <xmm>, <reg> */
4359			x->d86_numopnds = 2;
4360			vbit = 2;
4361		} else {
4362			x->d86_numopnds = 2;
4363			vbit = 1;
4364		}
4365
4366		dtrace_get_modrm(x, &mode, &reg, &r_m);
4367		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4368		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
4369		dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
4370
4371		if (vbit == 2)
4372			dtrace_imm_opnd(x, wbit, 1, 0);
4373
4374		break;
4375
4376	case VEX_RRI:
4377		/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
4378		x->d86_numopnds = 2;
4379
4380		dtrace_get_modrm(x, &mode, &reg, &r_m);
4381		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4382		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4383		dtrace_get_operand(x, mode, r_m, wbit, 0);
4384		break;
4385
4386	case VEX_RX:
4387		/* ModR/M.rm := op(ModR/M.reg) */
4388		if (dp == &dis_opAVX660F3A[0x19]) {	/* vextractf128 */
4389			x->d86_numopnds = 3;
4390
4391			dtrace_get_modrm(x, &mode, &reg, &r_m);
4392			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4393
4394			dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
4395			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4396
4397			/* one byte immediate number */
4398			dtrace_imm_opnd(x, wbit, 1, 0);
4399			break;
4400		}
4401
4402		x->d86_numopnds = 2;
4403
4404		dtrace_get_modrm(x, &mode, &reg, &r_m);
4405		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4406		dtrace_get_operand(x, mode, r_m, wbit, 1);
4407		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4408		break;
4409
4410	case VEX_RR:
4411		/* ModR/M.rm := op(ModR/M.reg) */
4412		x->d86_numopnds = 2;
4413
4414		dtrace_get_modrm(x, &mode, &reg, &r_m);
4415		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4416
4417		if (dp == &dis_opAVX660F[0x7E]) {
4418			/* vmovd/q <reg/mem 32/64>, <xmm> */
4419#ifdef DIS_TEXT
4420			if (vex_W)
4421				x->d86_mnem[4] = 'q';
4422#endif
4423			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4424		} else
4425			dtrace_get_operand(x, mode, r_m, wbit, 1);
4426
4427		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4428		break;
4429
4430	case VEX_RRi:
4431		/* ModR/M.rm := op(ModR/M.reg, imm) */
4432		x->d86_numopnds = 3;
4433
4434		dtrace_get_modrm(x, &mode, &reg, &r_m);
4435		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4436
4437#ifdef DIS_TEXT
4438		if (dp == &dis_opAVX660F3A[0x16]) {
4439			/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
4440			if (vex_W)
4441				x->d86_mnem[6] = 'q';
4442		}
4443#endif
4444		dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
4445		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4446
4447		/* one byte immediate number */
4448		dtrace_imm_opnd(x, wbit, 1, 0);
4449		break;
4450
4451	case VEX_RM:
4452		/* ModR/M.rm := op(ModR/M.reg) */
4453		if (dp == &dis_opAVX660F3A[0x17]) {	/* vextractps */
4454			x->d86_numopnds = 3;
4455
4456			dtrace_get_modrm(x, &mode, &reg, &r_m);
4457			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4458
4459			dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
4460			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
4461			/* one byte immediate number */
4462			dtrace_imm_opnd(x, wbit, 1, 0);
4463			break;
4464		}
4465		x->d86_numopnds = 2;
4466
4467		dtrace_get_modrm(x, &mode, &reg, &r_m);
4468		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4469L_VEX_RM:
4470		vbit = 1;
4471		dtrace_get_operand(x, mode, r_m, wbit, vbit);
4472		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
4473
4474		break;
4475
4476	case VEX_RRM:
4477		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
4478		x->d86_numopnds = 3;
4479
4480		dtrace_get_modrm(x, &mode, &reg, &r_m);
4481		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4482		dtrace_get_operand(x, mode, r_m, wbit, 2);
4483		/* VEX use the 1's complement form encode the XMM/YMM regs */
4484		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4485		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4486		break;
4487
4488	case VEX_RMX:
4489		/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
4490		x->d86_numopnds = 3;
4491
4492		dtrace_get_modrm(x, &mode, &reg, &r_m);
4493		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4494		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4495		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4496		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
4497		break;
4498
4499	case VEX_NONE:
4500#ifdef DIS_TEXT
4501		if (vex_L)
4502			(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
4503#endif
4504		break;
4505	/* an invalid op code */
4506	case AM:
4507	case DM:
4508	case OVERRIDE:
4509	case PREFIX:
4510	case UNKNOWN:
4511		NOMEM;
4512	default:
4513		goto error;
4514	} /* end switch */
4515	if (x->d86_error)
4516		goto error;
4517
4518done:
4519#ifdef DIS_MEM
4520	/*
4521	 * compute the size of any memory accessed by the instruction
4522	 */
4523	if (x->d86_memsize != 0) {
4524		return (0);
4525	} else if (dp->it_stackop) {
4526		switch (opnd_size) {
4527		case SIZE16:
4528			x->d86_memsize = 2;
4529			break;
4530		case SIZE32:
4531			x->d86_memsize = 4;
4532			break;
4533		case SIZE64:
4534			x->d86_memsize = 8;
4535			break;
4536		}
4537	} else if (nomem || mode == REG_ONLY) {
4538		x->d86_memsize = 0;
4539
4540	} else if (dp->it_size != 0) {
4541		/*
4542		 * In 64 bit mode descriptor table entries
4543		 * go up to 10 bytes and popf/pushf are always 8 bytes
4544		 */
4545		if (x->d86_mode == SIZE64 && dp->it_size == 6)
4546			x->d86_memsize = 10;
4547		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
4548		    (opcode2 == 0xc || opcode2 == 0xd))
4549			x->d86_memsize = 8;
4550		else
4551			x->d86_memsize = dp->it_size;
4552
4553	} else if (wbit == 0) {
4554		x->d86_memsize = 1;
4555
4556	} else if (wbit == LONG_OPND) {
4557		if (opnd_size == SIZE64)
4558			x->d86_memsize = 8;
4559		else if (opnd_size == SIZE32)
4560			x->d86_memsize = 4;
4561		else
4562			x->d86_memsize = 2;
4563
4564	} else if (wbit == SEG_OPND) {
4565		x->d86_memsize = 4;
4566
4567	} else {
4568		x->d86_memsize = 8;
4569	}
4570#endif
4571	return (0);
4572
4573error:
4574#ifdef DIS_TEXT
4575	(void) strlcat(x->d86_mnem, "undef", OPLEN);
4576#endif
4577	return (1);
4578}
4579
4580#ifdef DIS_TEXT
4581
4582/*
4583 * Some instructions should have immediate operands printed
4584 * as unsigned integers. We compare against this table.
4585 */
4586static char *unsigned_ops[] = {
4587	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
4588	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
4589	0
4590};
4591
4592
4593static int
4594isunsigned_op(char *opcode)
4595{
4596	char *where;
4597	int i;
4598	int is_unsigned = 0;
4599
4600	/*
4601	 * Work back to start of last mnemonic, since we may have
4602	 * prefixes on some opcodes.
4603	 */
4604	where = opcode + strlen(opcode) - 1;
4605	while (where > opcode && *where != ' ')
4606		--where;
4607	if (*where == ' ')
4608		++where;
4609
4610	for (i = 0; unsigned_ops[i]; ++i) {
4611		if (strncmp(where, unsigned_ops[i],
4612		    strlen(unsigned_ops[i])))
4613			continue;
4614		is_unsigned = 1;
4615		break;
4616	}
4617	return (is_unsigned);
4618}
4619
4620/*
4621 * Print a numeric immediate into end of buf, maximum length buflen.
4622 * The immediate may be an address or a displacement.  Mask is set
4623 * for address size.  If the immediate is a "small negative", or
4624 * if it's a negative displacement of any magnitude, print as -<absval>.
4625 * Respect the "octal" flag.  "Small negative" is defined as "in the
4626 * interval [NEG_LIMIT, 0)".
4627 *
4628 * Also, "isunsigned_op()" instructions never print negatives.
4629 *
4630 * Return whether we decided to print a negative value or not.
4631 */
4632
4633#define	NEG_LIMIT	-255
4634enum {IMM, DISP};
4635enum {POS, TRY_NEG};
4636
4637static int
4638print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
4639    size_t buflen, int disp, int try_neg)
4640{
4641	int curlen;
4642	int64_t sv = (int64_t)usv;
4643	int octal = dis->d86_flags & DIS_F_OCTAL;
4644
4645	curlen = strlen(buf);
4646
4647	if (try_neg == TRY_NEG && sv < 0 &&
4648	    (disp || sv >= NEG_LIMIT) &&
4649	    !isunsigned_op(dis->d86_mnem)) {
4650		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4651		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
4652		return (1);
4653	} else {
4654		if (disp == DISP)
4655			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4656			    octal ? "+0%llo" : "+0x%llx", usv & mask);
4657		else
4658			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
4659			    octal ? "0%llo" : "0x%llx", usv & mask);
4660		return (0);
4661
4662	}
4663}
4664
4665
4666static int
4667log2(int size)
4668{
4669	switch (size) {
4670	case 1: return (0);
4671	case 2: return (1);
4672	case 4: return (2);
4673	case 8: return (3);
4674	}
4675	return (0);
4676}
4677
4678/* ARGSUSED */
4679void
4680dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
4681    size_t buflen)
4682{
4683	uint64_t reltgt = 0;
4684	uint64_t tgt = 0;
4685	int curlen;
4686	int (*lookup)(void *, uint64_t, char *, size_t);
4687	int i;
4688	int64_t sv;
4689	uint64_t usv, mask, save_mask, save_usv;
4690	static uint64_t masks[] =
4691	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
4692	save_usv = 0;
4693
4694	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
4695
4696	/*
4697	 * For PC-relative jumps, the pc is really the next pc after executing
4698	 * this instruction, so increment it appropriately.
4699	 */
4700	pc += dis->d86_len;
4701
4702	for (i = 0; i < dis->d86_numopnds; i++) {
4703		d86opnd_t *op = &dis->d86_opnd[i];
4704
4705		if (i != 0)
4706			(void) strlcat(buf, ",", buflen);
4707
4708		(void) strlcat(buf, op->d86_prefix, buflen);
4709
4710		/*
4711		 * sv is for the signed, possibly-truncated immediate or
4712		 * displacement; usv retains the original size and
4713		 * unsignedness for symbol lookup.
4714		 */
4715
4716		sv = usv = op->d86_value;
4717
4718		/*
4719		 * About masks: for immediates that represent
4720		 * addresses, the appropriate display size is
4721		 * the effective address size of the instruction.
4722		 * This includes MODE_OFFSET, MODE_IPREL, and
4723		 * MODE_RIPREL.  Immediates that are simply
4724		 * immediate values should display in the operand's
4725		 * size, however, since they don't represent addresses.
4726		 */
4727
4728		/* d86_addr_size is SIZEnn, which is log2(real size) */
4729		mask = masks[dis->d86_addr_size];
4730
4731		/* d86_value_size and d86_imm_bytes are in bytes */
4732		if (op->d86_mode == MODE_SIGNED ||
4733		    op->d86_mode == MODE_IMPLIED)
4734			mask = masks[log2(op->d86_value_size)];
4735
4736		switch (op->d86_mode) {
4737
4738		case MODE_NONE:
4739
4740			(void) strlcat(buf, op->d86_opnd, buflen);
4741			break;
4742
4743		case MODE_SIGNED:
4744		case MODE_IMPLIED:
4745		case MODE_OFFSET:
4746
4747			tgt = usv;
4748
4749			if (dis->d86_seg_prefix)
4750				(void) strlcat(buf, dis->d86_seg_prefix,
4751				    buflen);
4752
4753			if (op->d86_mode == MODE_SIGNED ||
4754			    op->d86_mode == MODE_IMPLIED) {
4755				(void) strlcat(buf, "$", buflen);
4756			}
4757
4758			if (print_imm(dis, usv, mask, buf, buflen,
4759			    IMM, TRY_NEG) &&
4760			    (op->d86_mode == MODE_SIGNED ||
4761			    op->d86_mode == MODE_IMPLIED)) {
4762
4763				/*
4764				 * We printed a negative value for an
4765				 * immediate that wasn't a
4766				 * displacement.  Note that fact so we can
4767				 * print the positive value as an
4768				 * annotation.
4769				 */
4770
4771				save_usv = usv;
4772				save_mask = mask;
4773			}
4774			(void) strlcat(buf, op->d86_opnd, buflen);
4775
4776			break;
4777
4778		case MODE_IPREL:
4779		case MODE_RIPREL:
4780
4781			reltgt = pc + sv;
4782
4783			switch (mode) {
4784			case SIZE16:
4785				reltgt = (uint16_t)reltgt;
4786				break;
4787			case SIZE32:
4788				reltgt = (uint32_t)reltgt;
4789				break;
4790			}
4791
4792			(void) print_imm(dis, usv, mask, buf, buflen,
4793			    DISP, TRY_NEG);
4794
4795			if (op->d86_mode == MODE_RIPREL)
4796				(void) strlcat(buf, "(%rip)", buflen);
4797			break;
4798		}
4799	}
4800
4801	/*
4802	 * The symbol lookups may result in false positives,
4803	 * particularly on object files, where small numbers may match
4804	 * the 0-relative non-relocated addresses of symbols.
4805	 */
4806
4807	lookup = dis->d86_sym_lookup;
4808	if (tgt != 0) {
4809		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
4810		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
4811			(void) strlcat(buf, "\t<", buflen);
4812			curlen = strlen(buf);
4813			lookup(dis->d86_data, tgt, buf + curlen,
4814			    buflen - curlen);
4815			(void) strlcat(buf, ">", buflen);
4816		}
4817
4818		/*
4819		 * If we printed a negative immediate above, print the
4820		 * positive in case our heuristic was unhelpful
4821		 */
4822		if (save_usv) {
4823			(void) strlcat(buf, "\t<", buflen);
4824			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
4825			    IMM, POS);
4826			(void) strlcat(buf, ">", buflen);
4827		}
4828	}
4829
4830	if (reltgt != 0) {
4831		/* Print symbol or effective address for reltgt */
4832
4833		(void) strlcat(buf, "\t<", buflen);
4834		curlen = strlen(buf);
4835		lookup(dis->d86_data, reltgt, buf + curlen,
4836		    buflen - curlen);
4837		(void) strlcat(buf, ">", buflen);
4838	}
4839}
4840
4841#endif /* DIS_TEXT */
4842