1/*
2 *
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Joyent, Inc.
25 */
26
27/*
28 * Copyright (c) 2010, Intel Corporation.
29 * All rights reserved.
30 */
31
32/*	Copyright (c) 1988 AT&T	*/
33/*	  All Rights Reserved  	*/
34
35/*
36 * $FreeBSD: head/sys/cddl/dev/dtrace/x86/dis_tables.c 313133 2017-02-03 03:22:47Z markj $
37 */
38
39#include	"dis_tables.h"
40
41/* BEGIN CSTYLED */
42
43/*
44 * Disassembly begins in dis_distable, which is equivalent to the One-byte
45 * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
46 * decoding loops then traverse out through the other tables as necessary to
47 * decode a given instruction.
48 *
49 * The behavior of this file can be controlled by one of the following flags:
50 *
51 * 	DIS_TEXT	Include text for disassembly
52 * 	DIS_MEM		Include memory-size calculations
53 *
54 * Either or both of these can be defined.
55 *
56 * This file is not, and will never be, cstyled.  If anything, the tables should
57 * be taken out another tab stop or two so nothing overlaps.
58 */
59
60/*
61 * These functions must be provided for the consumer to do disassembly.
62 */
63#ifdef DIS_TEXT
64extern char *strncpy(char *, const char *, size_t);
65extern size_t strlen(const char *);
66extern int strcmp(const char *, const char *);
67extern int strncmp(const char *, const char *, size_t);
68extern size_t strlcat(char *, const char *, size_t);
69#endif
70
71
72#define		TERM 	0	/* used to indicate that the 'indirect' */
73				/* field terminates - no pointer.	*/
74
75/* Used to decode instructions. */
76typedef struct	instable {
77	struct instable	*it_indirect;	/* for decode op codes */
78	uchar_t		it_adrmode;
79#ifdef DIS_TEXT
80	char		it_name[NCPS];
81	uint_t		it_suffix:1;		/* mnem + "w", "l", or "d" */
82#endif
83#ifdef DIS_MEM
84	uint_t		it_size:16;
85#endif
86	uint_t		it_invalid64:1;		/* opcode invalid in amd64 */
87	uint_t		it_always64:1;		/* 64 bit when in 64 bit mode */
88	uint_t		it_invalid32:1;		/* invalid in IA32 */
89	uint_t		it_stackop:1;		/* push/pop stack operation */
90	uint_t		it_vexwoxmm:1;		/* VEX instructions that don't use XMM/YMM */
91	uint_t		it_avxsuf:1;		/* AVX suffix required */
92} instable_t;
93
94/*
95 * Instruction formats.
96 */
97enum {
98	UNKNOWN,
99	MRw,
100	IMlw,
101	IMw,
102	IR,
103	OA,
104	AO,
105	MS,
106	SM,
107	Mv,
108	Mw,
109	M,		/* register or memory */
110	MG9,		/* register or memory in group 9 (prefix optional) */
111	Mb,		/* register or memory, always byte sized */
112	MO,		/* memory only (no registers) */
113	PREF,
114	SWAPGS_RDTSCP,
115	MONITOR_MWAIT,
116	R,
117	RA,
118	SEG,
119	MR,
120	RM,
121	RM_66r,		/* RM, but with a required 0x66 prefix */
122	IA,
123	MA,
124	SD,
125	AD,
126	SA,
127	D,
128	INM,
129	SO,
130	BD,
131	I,
132	P,
133	V,
134	DSHIFT,		/* for double shift that has an 8-bit immediate */
135	U,
136	OVERRIDE,
137	NORM,		/* instructions w/o ModR/M byte, no memory access */
138	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
139	O,		/* for call	*/
140	JTAB,		/* jump table 	*/
141	IMUL,		/* for 186 iimul instr  */
142	CBW,		/* so data16 can be evaluated for cbw and variants */
143	MvI,		/* for 186 logicals */
144	ENTER,		/* for 186 enter instr  */
145	RMw,		/* for 286 arpl instr */
146	Ib,		/* for push immediate byte */
147	F,		/* for 287 instructions */
148	FF,		/* for 287 instructions */
149	FFC,		/* for 287 instructions */
150	DM,		/* 16-bit data */
151	AM,		/* 16-bit addr */
152	LSEG,		/* for 3-bit seg reg encoding */
153	MIb,		/* for 386 logicals */
154	SREG,		/* for 386 special registers */
155	PREFIX,		/* a REP instruction prefix */
156	LOCK,		/* a LOCK instruction prefix */
157	INT3,		/* The int 3 instruction, which has a fake operand */
158	INTx,		/* The normal int instruction, with explicit int num */
159	DSHIFTcl,	/* for double shift that implicitly uses %cl */
160	CWD,		/* so data16 can be evaluated for cwd and variants */
161	RET,		/* single immediate 16-bit operand */
162	MOVZ,		/* for movs and movz, with different size operands */
163	CRC32,		/* for crc32, with different size operands */
164	XADDB,		/* for xaddb */
165	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
166	MOVBE,		/* movbe instruction */
167
168/*
169 * MMX/SIMD addressing modes.
170 */
171
172	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
173	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
174	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
175	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
176	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
177	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
178	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
179	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
180	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
181	MMOSH,		/* Prefixable MMX		mm,imm8	*/
182	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
183	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
184	MMSH,		/* MMX				mm,imm8 */
185	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
186	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
187	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
188	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
189	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
190	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
191	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
192	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
193	XMM,		/* SIMD 			xmm/mem	-> xmm */
194	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
195	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
196	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
197	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
198	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
199	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
200	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
201	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
202	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
203	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
204	XMMS,		/* SIMD				xmm	-> xmm/mem */
205	XMMM,		/* SIMD 			mem	-> xmm */
206	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
207	XMMMS,		/* SIMD				xmm	-> mem */
208	XMM3MX,		/* SIMD 			r32/mem -> xmm */
209	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
210	XMMSH,		/* SIMD 			xmm,imm8 */
211	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
212	XMMX3,		/* SIMD 			xmm	-> r32 */
213	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
214	XMMMX,		/* SIMD 			mm	-> xmm */
215	XMMXM,		/* SIMD 			xmm	-> mm */
216        XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
217        XMM2I,		/* SIMD				xmm, imm, imm */
218	XMMFENCE,	/* SIMD lfence or mfence */
219	XMMSFNC,	/* SIMD sfence (none or mem) */
220	XGETBV_XSETBV,
221	VEX_NONE,	/* VEX  no operand */
222	VEX_MO,		/* VEX	mod_rm		               -> implicit reg */
223	VEX_RMrX,	/* VEX  VEX.vvvv, mod_rm               -> mod_reg */
224	VEX_VRMrX,	/* VEX  mod_rm, VEX.vvvv               -> mod_rm */
225	VEX_RRX,	/* VEX  VEX.vvvv, mod_reg              -> mod_rm */
226	VEX_RMRX,	/* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
227	VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
228	VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
229	VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
230	VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
231	VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
232	VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
233	VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
234	VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
235	VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
236	VEX_RIM,	/* VEX  mod_reg, imm8                  -> mod_rm */
237	VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
238	VEX_RMX,        /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
239	VEX_SbVM,	/* VEX  SIB, VEX.vvvv                  -> mod_rm */
240	VMx,		/* vmcall/vmlaunch/vmresume/vmxoff */
241	VMxo,		/* VMx instruction with optional prefix */
242	SVM,		/* AMD SVM instructions */
243	BLS,		/* BLSR, BLSMSK, BLSI */
244	FMA,		/* FMA instructions, all VEX_RMrX */
245	ADX		/* ADX instructions, support REX.w, mod_rm->mod_reg */
246};
247
248/*
249 * VEX prefixes
250 */
251#define VEX_2bytes	0xC5	/* the first byte of two-byte form */
252#define VEX_3bytes	0xC4	/* the first byte of three-byte form */
253
254#define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
255
256/*
257** Register numbers for the i386
258*/
259#define	EAX_REGNO 0
260#define	ECX_REGNO 1
261#define	EDX_REGNO 2
262#define	EBX_REGNO 3
263#define	ESP_REGNO 4
264#define	EBP_REGNO 5
265#define	ESI_REGNO 6
266#define	EDI_REGNO 7
267
268/*
269 * modes for immediate values
270 */
271#define	MODE_NONE	0
272#define	MODE_IPREL	1	/* signed IP relative value */
273#define	MODE_SIGNED	2	/* sign extended immediate */
274#define	MODE_IMPLIED	3	/* constant value implied from opcode */
275#define	MODE_OFFSET	4	/* offset part of an address */
276#define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
277
278/*
279 * The letters used in these macros are:
280 *   IND - indirect to another to another table
281 *   "T" - means to Terminate indirections (this is the final opcode)
282 *   "S" - means "operand length suffix required"
283 *   "Sa" - means AVX2 suffix (d/q) required
284 *   "NS" - means "no suffix" which is the operand length suffix of the opcode
285 *   "Z" - means instruction size arg required
286 *   "u" - means the opcode is invalid in IA32 but valid in amd64
287 *   "x" - means the opcode is invalid in amd64, but not IA32
288 *   "y" - means the operand size is always 64 bits in 64 bit mode
289 *   "p" - means push/pop stack operation
290 *   "vr" - means VEX instruction that operates on normal registers, not fpu
291 */
292
293#if defined(DIS_TEXT) && defined(DIS_MEM)
294#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
295#define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
296#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
297#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
298#define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
299#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
300#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
301#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
302#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
303#define	TNSZvr(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0, 1}
304#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
305#define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
306#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
307#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
308#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
309#define	TSaZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0, 0, 1}
310#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
311#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
312#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
313#elif defined(DIS_TEXT)
314#define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
315#define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
316#define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
317#define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
318#define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
319#define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
320#define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
321#define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
322#define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
323#define	TNSZvr(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0, 1}
324#define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
325#define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
326#define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
327#define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
328#define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
329#define	TSaZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0, 0, 1}
330#define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
331#define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
332#define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
333#elif defined(DIS_MEM)
334#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
335#define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
336#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
337#define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
338#define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
339#define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
340#define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
341#define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
342#define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
343#define	TNSZvr(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0, 1}
344#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
345#define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
346#define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
347#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
348#define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
349#define	TSaZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0, 0, 1}
350#define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
351#define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
352#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
353#else
354#define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
355#define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
356#define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
357#define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
358#define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
359#define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
360#define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
361#define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
362#define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
363#define	TNSZvr(name, amode, sz)	{TERM, amode,  0, 0, 0, 0, 1}
364#define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
365#define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
366#define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
367#define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
368#define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
369#define	TSaZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0, 0, 1}
370#define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
371#define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
372#define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
373#endif
374
375#ifdef DIS_TEXT
376/*
377 * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
378 */
379const char *const dis_addr16[3][8] = {
380"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
381									"(%bx)",
382"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
383									"(%bx)",
384"(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
385									"(%bx)",
386};
387
388
389/*
390 * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
391 */
392const char *const dis_addr32_mode0[16] = {
393  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
394  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
395};
396
397const char *const dis_addr32_mode12[16] = {
398  "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
399  "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
400};
401
402/*
403 * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
404 */
405const char *const dis_addr64_mode0[16] = {
406 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
407 "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
408};
409const char *const dis_addr64_mode12[16] = {
410 "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
411 "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
412};
413
414/*
415 * decode for scale from SIB byte
416 */
417const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
418
419/*
420 * decode for scale from VSIB byte, note that we always include the scale factor
421 * to match gas.
422 */
423const char *const dis_vscale_factor[4] = { ",1)", ",2)", ",4)", ",8)" };
424
425/*
426 * register decoding for normal references to registers (ie. not addressing)
427 */
428const char *const dis_REG8[16] = {
429	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
430	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
431};
432
433const char *const dis_REG8_REX[16] = {
434	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
435	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
436};
437
438const char *const dis_REG16[16] = {
439	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
440	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
441};
442
443const char *const dis_REG32[16] = {
444	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
445	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
446};
447
448const char *const dis_REG64[16] = {
449	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
450	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
451};
452
453const char *const dis_DEBUGREG[16] = {
454	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
455	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
456};
457
458const char *const dis_CONTROLREG[16] = {
459    "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
460    "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
461};
462
463const char *const dis_TESTREG[16] = {
464	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
465	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
466};
467
468const char *const dis_MMREG[16] = {
469	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
470	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
471};
472
473const char *const dis_XMMREG[16] = {
474    "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
475    "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
476};
477
478const char *const dis_YMMREG[16] = {
479    "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
480    "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
481};
482
483const char *const dis_SEGREG[16] = {
484	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
485	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
486};
487
488/*
489 * SIMD predicate suffixes
490 */
491const char *const dis_PREDSUFFIX[8] = {
492	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
493};
494
495const char *const dis_AVXvgrp7[3][8] = {
496	/*0	1	2		3		4		5	6		7*/
497/*71*/	{"",	"",	"vpsrlw",	"",		"vpsraw",	"",	"vpsllw",	""},
498/*72*/	{"",	"",	"vpsrld",	"",		"vpsrad",	"",	"vpslld",	""},
499/*73*/	{"",	"",	"vpsrlq",	"vpsrldq",	"",		"",	"vpsllq",	"vpslldq"}
500};
501
502#endif	/* DIS_TEXT */
503
504/*
505 *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
506 */
507const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
508
509/*
510 *	"decode table" for pause and clflush instructions
511 */
512const instable_t dis_opPause = TNS("pause", NORM);
513
514/*
515 *	Decode table for 0x0F00 opcodes
516 */
517const instable_t dis_op0F00[8] = {
518
519/*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
520/*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
521};
522
523
524/*
525 *	Decode table for 0x0F01 opcodes
526 */
527const instable_t dis_op0F01[8] = {
528
529/*  [0]  */	TNSZ("sgdt",VMx,6),	TNSZ("sidt",MONITOR_MWAIT,6),	TNSZ("lgdt",XGETBV_XSETBV,6),	TNSZ("lidt",SVM,6),
530/*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS_RDTSCP),
531};
532
533/*
534 *	Decode table for 0x0F18 opcodes -- SIMD prefetch
535 */
536const instable_t dis_op0F18[8] = {
537
538/*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
539/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
540};
541
542/*
543 * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
544 */
545const instable_t dis_op0FAE[8] = {
546/*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
547/*  [4]  */	TNSZ("xsave",M,512),	TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
548};
549
550/*
551 *	Decode table for 0x0FBA opcodes
552 */
553
554const instable_t dis_op0FBA[8] = {
555
556/*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
557/*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
558};
559
560/*
561 * 	Decode table for 0x0FC7 opcode (group 9)
562 */
563
564const instable_t dis_op0FC7[8] = {
565
566/*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
567/*  [4]  */	INVALID,		INVALID,		TNS("vmptrld",MG9),	TNS("vmptrst",MG9),
568};
569
570/*
571 * 	Decode table for 0x0FC7 opcode (group 9) mode 3
572 */
573
574const instable_t dis_op0FC7m3[8] = {
575
576/*  [0]  */	INVALID,		INVALID,	INVALID,		INVALID,
577/*  [4]  */	INVALID,		INVALID,	TNS("rdrand",MG9),	TNS("rdseed", MG9),
578};
579
580/*
581 * 	Decode table for 0x0FC7 opcode with 0x66 prefix
582 */
583
584const instable_t dis_op660FC7[8] = {
585
586/*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
587/*  [4]  */	INVALID,		INVALID,		TNS("vmclear",M),	INVALID,
588};
589
590/*
591 * 	Decode table for 0x0FC7 opcode with 0xF3 prefix
592 */
593
594const instable_t dis_opF30FC7[8] = {
595
596/*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
597/*  [4]  */	INVALID,		INVALID,		TNS("vmxon",M),		INVALID,
598};
599
600/*
601 *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
602 *
603 *bit pattern: 0000 1111 1100 1reg
604 */
605const instable_t dis_op0FC8[4] = {
606/*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
607};
608
609/*
610 *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
611 */
612const instable_t dis_op0F7123[4][8] = {
613{
614/*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
615/*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
616}, {
617/*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
618/*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
619}, {
620/*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
621/*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
622}, {
623/*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
624/*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
625} };
626
627/*
628 *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
629 */
630const instable_t dis_opSIMD7123[32] = {
631/* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
632/*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
633
634/* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
635/*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
636
637/* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
638/*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
639
640/* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
641/*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
642};
643
644/*
645 *	SIMD instructions have been wedged into the existing IA32 instruction
646 *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
647 *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
648 *	instruction - addss.  At present, three prefixes have been coopted in
649 *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
650 *	following tables are used to provide the prefixed instruction names.
651 *	The arrays are sparse, but they're fast.
652 */
653
654/*
655 *	Decode table for SIMD instructions with the address size (0x66) prefix.
656 */
657const instable_t dis_opSIMDdata16[256] = {
658/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
659/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
660/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
661/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
662
663/*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
664/*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
665/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
666/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
667
668/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
669/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
670/*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
671/*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
672
673/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
674/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
675/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
676/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
677
678/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
679/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
680/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
681/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
682
683/*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
684/*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
685/*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
686/*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
687
688/*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
689/*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
690/*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
691/*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
692
693/*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
694/*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
695/*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
696/*  [7C]  */	TNSZ("haddpd",XMM,16),	TNSZ("hsubpd",XMM,16),	TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
697
698/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
699/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
700/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
701/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
702
703/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
704/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
705/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
706/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
707
708/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
709/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
710/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
711/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
712
713/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
714/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
715/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
716/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
717
718/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
719/*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
720/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
721/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
722
723/*  [D0]  */	TNSZ("addsubpd",XMM,16),TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
724/*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
725/*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
726/*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
727
728/*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
729/*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
730/*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
731/*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
732
733/*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
734/*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
735/*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
736/*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
737};
738
739const instable_t dis_opAVX660F[256] = {
740/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
741/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
742/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
743/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
744
745/*  [10]  */	TNSZ("vmovupd",VEX_MX,16),	TNSZ("vmovupd",VEX_RX,16),	TNSZ("vmovlpd",VEX_RMrX,8),	TNSZ("vmovlpd",VEX_RM,8),
746/*  [14]  */	TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8),	TNSZ("vmovhpd",VEX_RM,8),
747/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
748/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
749
750/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
751/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
752/*  [28]  */	TNSZ("vmovapd",VEX_MX,16),	TNSZ("vmovapd",VEX_RX,16),	INVALID,		TNSZ("vmovntpd",VEX_RM,16),
753/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
754
755/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
756/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
757/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
758/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
759
760/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
761/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
762/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
763/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
764
765/*  [50]  */	TNS("vmovmskpd",VEX_MR),	TNSZ("vsqrtpd",VEX_MX,16),	INVALID,		INVALID,
766/*  [54]  */	TNSZ("vandpd",VEX_RMrX,16),	TNSZ("vandnpd",VEX_RMrX,16),	TNSZ("vorpd",VEX_RMrX,16),	TNSZ("vxorpd",VEX_RMrX,16),
767/*  [58]  */	TNSZ("vaddpd",VEX_RMrX,16),	TNSZ("vmulpd",VEX_RMrX,16),	TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
768/*  [5C]  */	TNSZ("vsubpd",VEX_RMrX,16),	TNSZ("vminpd",VEX_RMrX,16),	TNSZ("vdivpd",VEX_RMrX,16),	TNSZ("vmaxpd",VEX_RMrX,16),
769
770/*  [60]  */	TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
771/*  [64]  */	TNSZ("vpcmpgtb",VEX_RMrX,16),	TNSZ("vpcmpgtw",VEX_RMrX,16),	TNSZ("vpcmpgtd",VEX_RMrX,16),	TNSZ("vpackuswb",VEX_RMrX,16),
772/*  [68]  */	TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
773/*  [6C]  */	TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
774
775/*  [70]  */	TNSZ("vpshufd",VEX_MXI,16),	TNSZ("vgrp71",VEX_XXI,16),	TNSZ("vgrp72",VEX_XXI,16),		TNSZ("vgrp73",VEX_XXI,16),
776/*  [74]  */	TNSZ("vpcmpeqb",VEX_RMrX,16),	TNSZ("vpcmpeqw",VEX_RMrX,16),	TNSZ("vpcmpeqd",VEX_RMrX,16),	INVALID,
777/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
778/*  [7C]  */	TNSZ("vhaddpd",VEX_RMrX,16),	TNSZ("vhsubpd",VEX_RMrX,16),	TNSZ("vmovd",VEX_RR,4),	TNSZ("vmovdqa",VEX_RX,16),
779
780/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
781/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
782/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
783/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
784
785/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
786/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
787/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
788/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
789
790/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
791/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
792/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
793/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
794
795/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
796/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
797/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
798/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
799
800/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmppd",VEX_RMRX,16),	INVALID,
801/*  [C4]  */	TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),	TNSZ("vshufpd",VEX_RMRX,16),	INVALID,
802/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
803/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
804
805/*  [D0]  */	TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),	TNSZ("vpsrld",VEX_RMrX,16),	TNSZ("vpsrlq",VEX_RMrX,16),
806/*  [D4]  */	TNSZ("vpaddq",VEX_RMrX,16),	TNSZ("vpmullw",VEX_RMrX,16),	TNSZ("vmovq",VEX_RX,8),	TNS("vpmovmskb",VEX_MR),
807/*  [D8]  */	TNSZ("vpsubusb",VEX_RMrX,16),	TNSZ("vpsubusw",VEX_RMrX,16),	TNSZ("vpminub",VEX_RMrX,16),	TNSZ("vpand",VEX_RMrX,16),
808/*  [DC]  */	TNSZ("vpaddusb",VEX_RMrX,16),	TNSZ("vpaddusw",VEX_RMrX,16),	TNSZ("vpmaxub",VEX_RMrX,16),	TNSZ("vpandn",VEX_RMrX,16),
809
810/*  [E0]  */	TNSZ("vpavgb",VEX_RMrX,16),	TNSZ("vpsraw",VEX_RMrX,16),	TNSZ("vpsrad",VEX_RMrX,16),	TNSZ("vpavgw",VEX_RMrX,16),
811/*  [E4]  */	TNSZ("vpmulhuw",VEX_RMrX,16),	TNSZ("vpmulhw",VEX_RMrX,16),	TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
812/*  [E8]  */	TNSZ("vpsubsb",VEX_RMrX,16),	TNSZ("vpsubsw",VEX_RMrX,16),	TNSZ("vpminsw",VEX_RMrX,16),	TNSZ("vpor",VEX_RMrX,16),
813/*  [EC]  */	TNSZ("vpaddsb",VEX_RMrX,16),	TNSZ("vpaddsw",VEX_RMrX,16),	TNSZ("vpmaxsw",VEX_RMrX,16),	TNSZ("vpxor",VEX_RMrX,16),
814
815/*  [F0]  */	INVALID,		TNSZ("vpsllw",VEX_RMrX,16),	TNSZ("vpslld",VEX_RMrX,16),	TNSZ("vpsllq",VEX_RMrX,16),
816/*  [F4]  */	TNSZ("vpmuludq",VEX_RMrX,16),	TNSZ("vpmaddwd",VEX_RMrX,16),	TNSZ("vpsadbw",VEX_RMrX,16),	TNS("vmaskmovdqu",VEX_MX),
817/*  [F8]  */	TNSZ("vpsubb",VEX_RMrX,16),	TNSZ("vpsubw",VEX_RMrX,16),	TNSZ("vpsubd",VEX_RMrX,16),	TNSZ("vpsubq",VEX_RMrX,16),
818/*  [FC]  */	TNSZ("vpaddb",VEX_RMrX,16),	TNSZ("vpaddw",VEX_RMrX,16),	TNSZ("vpaddd",VEX_RMrX,16),	INVALID,
819};
820
821/*
822 *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
823 */
824const instable_t dis_opSIMDrepnz[256] = {
825/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
826/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
827/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
828/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
829
830/*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	TNSZ("movddup",XMM,8),	INVALID,
831/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
832/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
833/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
834
835/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
836/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
837/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
838/*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
839
840/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
841/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
842/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
843/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
844
845/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
846/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
847/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
848/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
849
850/*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
851/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
852/*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
853/*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
854
855/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
856/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
857/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
858/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
859
860/*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
861/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
862/*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
863/*  [7C]  */	TNSZ("haddps",XMM,16),	TNSZ("hsubps",XMM,16),	INVALID,		INVALID,
864
865/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
866/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
867/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
868/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
869
870/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
871/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
872/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
873/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
874
875/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
876/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
877/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
878/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
879
880/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
881/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
882/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
883/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
884
885/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
886/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
887/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
888/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
889
890/*  [D0]  */	TNSZ("addsubps",XMM,16),INVALID,		INVALID,		INVALID,
891/*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
892/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
893/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
894
895/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
896/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
897/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
898/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
899
900/*  [F0]  */	TNS("lddqu",XMMM),	INVALID,		INVALID,		INVALID,
901/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
902/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
903/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
904};
905
906const instable_t dis_opAVXF20F[256] = {
907/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
908/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
909/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
910/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
911
912/*  [10]  */	TNSZ("vmovsd",VEX_RMrX,8),	TNSZ("vmovsd",VEX_RRX,8),	TNSZ("vmovddup",VEX_MX,8),	INVALID,
913/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
914/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
915/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
916
917/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
918/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
919/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
920/*  [2C]  */	TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,		INVALID,
921
922/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
923/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
924/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
925/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
926
927/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
928/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
929/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
930/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
931
932/*  [50]  */	INVALID,		TNSZ("vsqrtsd",VEX_RMrX,8),	INVALID,		INVALID,
933/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
934/*  [58]  */	TNSZ("vaddsd",VEX_RMrX,8),	TNSZ("vmulsd",VEX_RMrX,8),	TNSZ("vcvtsd2ss",VEX_RMrX,8),	INVALID,
935/*  [5C]  */	TNSZ("vsubsd",VEX_RMrX,8),	TNSZ("vminsd",VEX_RMrX,8),	TNSZ("vdivsd",VEX_RMrX,8),	TNSZ("vmaxsd",VEX_RMrX,8),
936
937/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
938/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
939/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
940/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
941
942/*  [70]  */	TNSZ("vpshuflw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
943/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
944/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
945/*  [7C]  */	TNSZ("vhaddps",VEX_RMrX,8),	TNSZ("vhsubps",VEX_RMrX,8),	INVALID,		INVALID,
946
947/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
948/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
949/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
950/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
951
952/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
953/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
954/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
955/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
956
957/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
958/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
959/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
960/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
961
962/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
963/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
964/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
965/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
966
967/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpsd",VEX_RMRX,8),	INVALID,
968/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
969/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
970/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
971
972/*  [D0]  */	TNSZ("vaddsubps",VEX_RMrX,8),	INVALID,		INVALID,		INVALID,
973/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
974/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
975/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
976
977/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
978/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
979/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
980/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
981
982/*  [F0]  */	TNSZ("vlddqu",VEX_MX,16),	INVALID,		INVALID,		INVALID,
983/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
984/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
985/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
986};
987
988const instable_t dis_opAVXF20F3A[256] = {
989/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
990/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
991/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
992/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
993
994/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
995/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
996/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
997/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
998
999/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1000/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1001/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1002/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1003
1004/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1005/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1006/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1007/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1008
1009/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1010/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1011/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1012/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1013
1014/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1015/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1016/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1017/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1018
1019/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1020/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1021/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1022/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1023
1024/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1025/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1026/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1027/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1028
1029/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1030/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1031/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1032/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1033
1034/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1035/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1036/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1037/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1038
1039/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1040/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1041/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1042/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1043
1044/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1045/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1046/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1047/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1048
1049/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1050/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1051/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1052/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1053
1054/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1055/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1056/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1057/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1058
1059/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1060/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1061/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1062/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1063
1064/*  [F0]  */	TNSZvr("rorx",VEX_MXI,6),INVALID,		INVALID,		INVALID,
1065/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1066/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1067/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1068};
1069
1070const instable_t dis_opAVXF20F38[256] = {
1071/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1072/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1073/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1074/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1075
1076/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1077/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
1078/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1079/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1080
1081/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1082/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1083/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1084/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1085
1086/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1087/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1088/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1089/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1090
1091/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1092/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1093/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1094/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1095
1096/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1097/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1098/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1099/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1100
1101/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1102/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1103/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1104/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1105
1106/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1107/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1108/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1109/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1110
1111/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1112/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1113/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1114/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1115
1116/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1117/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1118/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1119/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1120
1121/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1122/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1123/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1124/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1125
1126/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1127/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1128/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1129/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1130
1131/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1132/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1133/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1134/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1135
1136/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1137/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1138/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1139/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1140
1141/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1142/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1143/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1144/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1145
1146/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1147/*  [F4]  */	INVALID,		TNSZvr("pdep",VEX_RMrX,5),TNSZvr("mulx",VEX_RMrX,5),TNSZvr("shrx",VEX_VRMrX,5),
1148/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1149/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1150};
1151
1152const instable_t dis_opAVXF30F38[256] = {
1153/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1154/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1155/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1156/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1157
1158/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1159/*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
1160/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1161/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1162
1163/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1164/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1165/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1166/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1167
1168/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1169/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1170/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1171/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1172
1173/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1174/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1175/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1176/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1177
1178/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1179/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1180/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1181/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1182
1183/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1184/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1185/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1186/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1187
1188/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1189/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1190/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1191/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1192
1193/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1194/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1195/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1196/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1197
1198/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1199/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1200/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1201/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1202
1203/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1204/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1205/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1206/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1207
1208/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1209/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1210/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1211/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1212
1213/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1214/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1215/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1216/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1217
1218/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1219/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1220/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1221/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1222
1223/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1224/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1225/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1226/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1227
1228/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1229/*  [F4]  */	INVALID,		TNSZvr("pext",VEX_RMrX,5),INVALID,		TNSZvr("sarx",VEX_VRMrX,5),
1230/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1231/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1232};
1233/*
1234 *	Decode table for SIMD instructions with the repz (0xf3) prefix.
1235 */
1236const instable_t dis_opSIMDrepz[256] = {
1237/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1238/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1239/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1240/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1241
1242/*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	TNSZ("movsldup",XMM,16),INVALID,
1243/*  [14]  */	INVALID,		INVALID,		TNSZ("movshdup",XMM,16),INVALID,
1244/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1245/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1246
1247/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1248/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1249/*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
1250/*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
1251
1252/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1253/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1254/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1255/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1256
1257/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1258/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1259/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1260/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1261
1262/*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
1263/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1264/*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
1265/*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
1266
1267/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1268/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1269/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1270/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
1271
1272/*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
1273/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1274/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1275/*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
1276
1277/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1278/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1279/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1280/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1281
1282/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1283/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1284/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1285/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1286
1287/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1288/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1289/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1290/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1291
1292/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1293/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1294/*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
1295/*  [BC]  */	TNSZ("tzcnt",MRw,5),	TS("lzcnt",MRw),	INVALID,		INVALID,
1296
1297/*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
1298/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1299/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1300/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1301
1302/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1303/*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
1304/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1305/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1306
1307/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1308/*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
1309/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1310/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1311
1312/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1313/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1314/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1315/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1316};
1317
1318const instable_t dis_opAVXF30F[256] = {
1319/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1320/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1321/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1322/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1323
1324/*  [10]  */	TNSZ("vmovss",VEX_RMrX,4),	TNSZ("vmovss",VEX_RRX,4),	TNSZ("vmovsldup",VEX_MX,4),	INVALID,
1325/*  [14]  */	INVALID,		INVALID,		TNSZ("vmovshdup",VEX_MX,4),	INVALID,
1326/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1327/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1328
1329/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1330/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1331/*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
1332/*  [2C]  */	TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,		INVALID,
1333
1334/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1335/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1336/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1337/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1338
1339/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1340/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1341/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1342/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1343
1344/*  [50]  */	INVALID,		TNSZ("vsqrtss",VEX_RMrX,4),	TNSZ("vrsqrtss",VEX_RMrX,4),	TNSZ("vrcpss",VEX_RMrX,4),
1345/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1346/*  [58]  */	TNSZ("vaddss",VEX_RMrX,4),	TNSZ("vmulss",VEX_RMrX,4),	TNSZ("vcvtss2sd",VEX_RMrX,4),	TNSZ("vcvttps2dq",VEX_MX,16),
1347/*  [5C]  */	TNSZ("vsubss",VEX_RMrX,4),	TNSZ("vminss",VEX_RMrX,4),	TNSZ("vdivss",VEX_RMrX,4),	TNSZ("vmaxss",VEX_RMrX,4),
1348
1349/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1350/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1351/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1352/*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("vmovdqu",VEX_MX,16),
1353
1354/*  [70]  */	TNSZ("vpshufhw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
1355/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1356/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1357/*  [7C]  */	INVALID,		INVALID,		TNSZ("vmovq",VEX_MX,8),	TNSZ("vmovdqu",VEX_RX,16),
1358
1359/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1360/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1361/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1362/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1363
1364/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1365/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1366/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1367/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1368
1369/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1370/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1371/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1372/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1373
1374/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1375/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1376/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1377/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1378
1379/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpss",VEX_RMRX,4),	INVALID,
1380/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1381/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1382/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1383
1384/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1385/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1386/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1387/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1388
1389/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1390/*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtdq2pd",VEX_MX,8),	INVALID,
1391/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1392/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1393
1394/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1395/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1396/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1397/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1398};
1399/*
1400 * The following two tables are used to encode crc32 and movbe
1401 * since they share the same opcodes.
1402 */
1403const instable_t dis_op0F38F0[2] = {
1404/*  [00]  */	TNS("crc32b",CRC32),
1405		TS("movbe",MOVBE),
1406};
1407
1408const instable_t dis_op0F38F1[2] = {
1409/*  [00]  */	TS("crc32",CRC32),
1410		TS("movbe",MOVBE),
1411};
1412
1413/*
1414 * The following table is used to distinguish between adox and adcx which share
1415 * the same opcodes.
1416 */
1417const instable_t dis_op0F38F6[2] = {
1418/*  [00]  */	TNS("adcx",ADX),
1419		TNS("adox",ADX),
1420};
1421
1422const instable_t dis_op0F38[256] = {
1423/*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
1424/*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
1425/*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
1426/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1427
1428/*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
1429/*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
1430/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1431/*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
1432
1433/*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
1434/*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
1435/*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
1436/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1437
1438/*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
1439/*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
1440/*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
1441/*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
1442
1443/*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
1444/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1445/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1446/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1447
1448/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1449/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1450/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1451/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1452
1453/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1454/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1455/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1456/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1457
1458/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1459/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1460/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1461/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1462
1463/*  [80]  */	TNSy("invept", RM_66r),	TNSy("invvpid", RM_66r),TNSy("invpcid", RM_66r),INVALID,
1464/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1465/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1466/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1467
1468/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1469/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1470/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1471/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1472
1473/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1474/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1475/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1476/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1477
1478/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1479/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1480/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1481/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1482
1483/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1484/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1485/*  [C8]  */	TNSZ("sha1nexte",XMM,16),TNSZ("sha1msg1",XMM,16),TNSZ("sha1msg2",XMM,16),TNSZ("sha256rnds2",XMM,16),
1486/*  [CC]  */	TNSZ("sha256msg1",XMM,16),TNSZ("sha256msg2",XMM,16),INVALID,		INVALID,
1487
1488/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1489/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1490/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
1491/*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
1492
1493/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1494/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1495/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1496/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1497/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1498/*  [F4]  */	INVALID,		INVALID,		IND(dis_op0F38F6),	INVALID,
1499/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1500/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1501};
1502
1503const instable_t dis_opAVX660F38[256] = {
1504/*  [00]  */	TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
1505/*  [04]  */	TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),	TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
1506/*  [08]  */	TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
1507/*  [0C]  */	TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),	TNSZ("vtestpd",VEX_RRI,16),
1508
1509/*  [10]  */	INVALID,		INVALID,		INVALID,		TNSZ("vcvtph2ps",VEX_MX,16),
1510/*  [14]  */	INVALID,		INVALID,		TNSZ("vpermps",VEX_RMrX,16),TNSZ("vptest",VEX_RRI,16),
1511/*  [18]  */	TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
1512/*  [1C]  */	TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
1513
1514/*  [20]  */	TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
1515/*  [24]  */	TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,	INVALID,
1516/*  [28]  */	TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
1517/*  [2C]  */	TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
1518
1519/*  [30]  */	TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
1520/*  [34]  */	TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),TNSZ("vpermd",VEX_RMrX,16),TNSZ("vpcmpgtq",VEX_RMrX,16),
1521/*  [38]  */	TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
1522/*  [3C]  */	TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
1523
1524/*  [40]  */	TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,	INVALID,
1525/*  [44]  */	INVALID,		TSaZ("vpsrlv",VEX_RMrX,16),TNSZ("vpsravd",VEX_RMrX,16),TSaZ("vpsllv",VEX_RMrX,16),
1526/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1527/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1528
1529/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1530/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1531/*  [58]  */	TNSZ("vpbroadcastd",VEX_MX,16),TNSZ("vpbroadcastq",VEX_MX,16),TNSZ("vbroadcasti128",VEX_MX,16),INVALID,
1532/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1533
1534/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1535/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1536/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1537/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1538
1539/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1540/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1541/*  [78]  */	TNSZ("vpbroadcastb",VEX_MX,16),TNSZ("vpbroadcastw",VEX_MX,16),INVALID,	INVALID,
1542/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1543
1544/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1545/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1546/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1547/*  [8C]  */	TSaZ("vpmaskmov",VEX_RMrX,16),INVALID,		TSaZ("vpmaskmov",VEX_RRM,16),INVALID,
1548
1549/*  [90]  */	TNSZ("vpgatherd",VEX_SbVM,16),TNSZ("vpgatherq",VEX_SbVM,16),TNSZ("vgatherdp",VEX_SbVM,16),TNSZ("vgatherqp",VEX_SbVM,16),
1550/*  [94]  */	INVALID,		INVALID,		TNSZ("vfmaddsub132p",FMA,16),TNSZ("vfmsubadd132p",FMA,16),
1551/*  [98]  */	TNSZ("vfmadd132p",FMA,16),TNSZ("vfmadd132s",FMA,16),TNSZ("vfmsub132p",FMA,16),TNSZ("vfmsub132s",FMA,16),
1552/*  [9C]  */	TNSZ("vfnmadd132p",FMA,16),TNSZ("vfnmadd132s",FMA,16),TNSZ("vfnmsub132p",FMA,16),TNSZ("vfnmsub132s",FMA,16),
1553
1554/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1555/*  [A4]  */	INVALID,		INVALID,		TNSZ("vfmaddsub213p",FMA,16),TNSZ("vfmsubadd213p",FMA,16),
1556/*  [A8]  */	TNSZ("vfmadd213p",FMA,16),TNSZ("vfmadd213s",FMA,16),TNSZ("vfmsub213p",FMA,16),TNSZ("vfmsub213s",FMA,16),
1557/*  [AC]  */	TNSZ("vfnmadd213p",FMA,16),TNSZ("vfnmadd213s",FMA,16),TNSZ("vfnmsub213p",FMA,16),TNSZ("vfnmsub213s",FMA,16),
1558
1559/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1560/*  [B4]  */	INVALID,		INVALID,		TNSZ("vfmaddsub231p",FMA,16),TNSZ("vfmsubadd231p",FMA,16),
1561/*  [B8]  */	TNSZ("vfmadd231p",FMA,16),TNSZ("vfmadd231s",FMA,16),TNSZ("vfmsub231p",FMA,16),TNSZ("vfmsub231s",FMA,16),
1562/*  [BC]  */	TNSZ("vfnmadd231p",FMA,16),TNSZ("vfnmadd231s",FMA,16),TNSZ("vfnmsub231p",FMA,16),TNSZ("vfnmsub231s",FMA,16),
1563
1564/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1565/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1566/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1567/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1568
1569/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1570/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1571/*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaesimc",VEX_MX,16),
1572/*  [DC]  */	TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
1573
1574/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1575/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1576/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1577/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1578/*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1579/*  [F4]  */	INVALID,		INVALID,		INVALID,		TNSZvr("shlx",VEX_VRMrX,5),
1580/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1581/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1582};
1583
1584const instable_t dis_op0F3A[256] = {
1585/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1586/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1587/*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
1588/*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
1589
1590/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1591/*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
1592/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1593/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1594
1595/*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
1596/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1597/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1598/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1599
1600/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1601/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1602/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1603/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1604
1605/*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
1606/*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
1607/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1608/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1609
1610/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1611/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1612/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1613/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1614
1615/*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
1616/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1617/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1618/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1619
1620/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1621/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1622/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1623/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1624
1625/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1626/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1627/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1628/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1629
1630/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1631/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1632/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1633/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1634
1635/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1636/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1637/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1638/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1639
1640/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1641/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1642/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1643/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1644
1645/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1646/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1647/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1648/*  [CC]  */	TNSZ("sha1rnds4",XMMP,16),INVALID,		INVALID,		INVALID,
1649
1650/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1651/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1652/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1653/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
1654
1655/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1656/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1657/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1658/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1659
1660/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1661/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1662/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1663/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1664};
1665
1666const instable_t dis_opAVX660F3A[256] = {
1667/*  [00]  */	TNSZ("vpermq",VEX_MXI,16),TNSZ("vpermpd",VEX_MXI,16),TNSZ("vpblendd",VEX_RMRX,16),INVALID,
1668/*  [04]  */	TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
1669/*  [08]  */	TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
1670/*  [0C]  */	TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
1671
1672/*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1673/*  [14]  */	TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
1674/*  [18]  */	TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,		INVALID,
1675/*  [1C]  */	INVALID,		TNSZ("vcvtps2ph",VEX_RX,16),		INVALID,		INVALID,
1676
1677/*  [20]  */	TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
1678/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1679/*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1680/*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1681
1682/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1683/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1684/*  [38]  */	TNSZ("vinserti128",VEX_RMRX,16),TNSZ("vextracti128",VEX_RIM,16),INVALID,		INVALID,
1685/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1686
1687/*  [40]  */	TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
1688/*  [44]  */	TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,		TNSZ("vperm2i128",VEX_RMRX,16),INVALID,
1689/*  [48]  */	INVALID,		INVALID,		TNSZ("vblendvps",VEX_RMRX,8),	TNSZ("vblendvpd",VEX_RMRX,16),
1690/*  [4C]  */	TNSZ("vpblendvb",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
1691
1692/*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1693/*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1694/*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1695/*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1696
1697/*  [60]  */	TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
1698/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1699/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1700/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1701
1702/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1703/*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1704/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1705/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1706
1707/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1708/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1709/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1710/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1711
1712/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1713/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1714/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1715/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1716
1717/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1718/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1719/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1720/*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1721
1722/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1723/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1724/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1725/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1726
1727/*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1728/*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1729/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1730/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1731
1732/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1733/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1734/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1735/*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaeskeygenassist",VEX_MXI,16),
1736
1737/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1738/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1739/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1740/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1741
1742/*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1743/*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1744/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1745/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1746};
1747
1748/*
1749 * 	Decode table for 0x0F0D which uses the first byte of the mod_rm to
1750 * 	indicate a sub-code.
1751 */
1752const instable_t dis_op0F0D[8] = {
1753/*  [00]  */	INVALID,		TNS("prefetchw",PREF),	TNS("prefetchwt1",PREF),INVALID,
1754/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1755};
1756
1757/*
1758 *	Decode table for 0x0F opcodes
1759 */
1760
1761const instable_t dis_op0F[16][16] = {
1762{
1763/*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
1764/*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
1765/*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
1766/*  [0C]  */	INVALID,		IND(dis_op0F0D),	INVALID,		INVALID,
1767}, {
1768/*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
1769/*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
1770/*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
1771/*  [1C]  */	INVALID,		INVALID,		INVALID,		TS("nop",Mw),
1772}, {
1773/*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
1774/*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
1775/*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
1776/*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
1777}, {
1778/*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
1779/*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
1780/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1781/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1782}, {
1783/*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
1784/*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
1785/*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
1786/*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
1787}, {
1788/*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
1789/*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
1790/*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
1791/*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
1792}, {
1793/*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
1794/*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
1795/*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
1796/*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
1797}, {
1798/*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
1799/*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
1800/*  [78]  */	TNSy("vmread",RM),	TNSy("vmwrite",MR),	INVALID,		INVALID,
1801/*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
1802}, {
1803/*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
1804/*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
1805/*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
1806/*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
1807}, {
1808/*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
1809/*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
1810/*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
1811/*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
1812}, {
1813/*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
1814/*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
1815/*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
1816/*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
1817}, {
1818/*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
1819/*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
1820/*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
1821/*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
1822}, {
1823/*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
1824/*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
1825/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1826/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1827}, {
1828/*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
1829/*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
1830/*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
1831/*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
1832}, {
1833/*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
1834/*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
1835/*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
1836/*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
1837}, {
1838/*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
1839/*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
1840/*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
1841/*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
1842} };
1843
1844const instable_t dis_opAVX0F[16][16] = {
1845{
1846/*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1847/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1848/*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1849/*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1850}, {
1851/*  [10]  */	TNSZ("vmovups",VEX_MX,16),	TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),	TNSZ("vmovlps",VEX_RM,8),
1852/*  [14]  */	TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
1853/*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1854/*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1855}, {
1856/*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1857/*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1858/*  [28]  */	TNSZ("vmovaps",VEX_MX,16),	TNSZ("vmovaps",VEX_RX,16),INVALID,		TNSZ("vmovntps",VEX_RM,16),
1859/*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
1860}, {
1861/*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1862/*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1863/*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1864/*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1865}, {
1866/*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1867/*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1868/*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1869/*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1870}, {
1871/*  [50]  */	TNS("vmovmskps",VEX_MR),	TNSZ("vsqrtps",VEX_MX,16),	TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
1872/*  [54]  */	TNSZ("vandps",VEX_RMrX,16),	TNSZ("vandnps",VEX_RMrX,16),	TNSZ("vorps",VEX_RMrX,16),	TNSZ("vxorps",VEX_RMrX,16),
1873/*  [58]  */	TNSZ("vaddps",VEX_RMrX,16),	TNSZ("vmulps",VEX_RMrX,16),	TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
1874/*  [5C]  */	TNSZ("vsubps",VEX_RMrX,16),	TNSZ("vminps",VEX_RMrX,16),	TNSZ("vdivps",VEX_RMrX,16),	TNSZ("vmaxps",VEX_RMrX,16),
1875}, {
1876/*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1877/*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1878/*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1879/*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1880}, {
1881/*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1882/*  [74]  */	INVALID,		INVALID,		INVALID,		TNS("vzeroupper", VEX_NONE),
1883/*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1884/*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1885}, {
1886/*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1887/*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1888/*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1889/*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1890}, {
1891/*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1892/*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1893/*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1894/*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1895}, {
1896/*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1897/*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1898/*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1899/*  [AC]  */	INVALID,		INVALID,		TNSZ("vldmxcsr",VEX_MO,2),		INVALID,
1900}, {
1901/*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1902/*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1903/*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1904/*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1905}, {
1906/*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpps",VEX_RMRX,16),INVALID,
1907/*  [C4]  */	INVALID,		INVALID,	 	TNSZ("vshufps",VEX_RMRX,16),INVALID,
1908/*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1909/*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1910}, {
1911/*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1912/*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1913/*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1914/*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1915}, {
1916/*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1917/*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1918/*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1919/*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1920}, {
1921/*  [F0]  */	INVALID,		INVALID,		TNSZvr("andn",VEX_RMrX,5),TNSZvr("bls",BLS,5),
1922/*  [F4]  */	INVALID,		TNSZvr("bzhi",VEX_VRMrX,5),INVALID,		TNSZvr("bextr",VEX_VRMrX,5),
1923/*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1924/*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1925} };
1926
1927/*
1928 *	Decode table for 0x80 opcodes
1929 */
1930
1931const instable_t dis_op80[8] = {
1932
1933/*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
1934/*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
1935};
1936
1937
1938/*
1939 *	Decode table for 0x81 opcodes.
1940 */
1941
1942const instable_t dis_op81[8] = {
1943
1944/*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
1945/*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
1946};
1947
1948
1949/*
1950 *	Decode table for 0x82 opcodes.
1951 */
1952
1953const instable_t dis_op82[8] = {
1954
1955/*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
1956/*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
1957};
1958/*
1959 *	Decode table for 0x83 opcodes.
1960 */
1961
1962const instable_t dis_op83[8] = {
1963
1964/*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
1965/*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
1966};
1967
1968/*
1969 *	Decode table for 0xC0 opcodes.
1970 */
1971
1972const instable_t dis_opC0[8] = {
1973
1974/*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
1975/*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
1976};
1977
1978/*
1979 *	Decode table for 0xD0 opcodes.
1980 */
1981
1982const instable_t dis_opD0[8] = {
1983
1984/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
1985/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
1986};
1987
1988/*
1989 *	Decode table for 0xC1 opcodes.
1990 *	186 instruction set
1991 */
1992
1993const instable_t dis_opC1[8] = {
1994
1995/*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
1996/*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
1997};
1998
1999/*
2000 *	Decode table for 0xD1 opcodes.
2001 */
2002
2003const instable_t dis_opD1[8] = {
2004
2005/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
2006/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
2007};
2008
2009
2010/*
2011 *	Decode table for 0xD2 opcodes.
2012 */
2013
2014const instable_t dis_opD2[8] = {
2015
2016/*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
2017/*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
2018};
2019/*
2020 *	Decode table for 0xD3 opcodes.
2021 */
2022
2023const instable_t dis_opD3[8] = {
2024
2025/*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
2026/*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
2027};
2028
2029
2030/*
2031 *	Decode table for 0xF6 opcodes.
2032 */
2033
2034const instable_t dis_opF6[8] = {
2035
2036/*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
2037/*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
2038};
2039
2040
2041/*
2042 *	Decode table for 0xF7 opcodes.
2043 */
2044
2045const instable_t dis_opF7[8] = {
2046
2047/*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
2048/*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
2049};
2050
2051
2052/*
2053 *	Decode table for 0xFE opcodes.
2054 */
2055
2056const instable_t dis_opFE[8] = {
2057
2058/*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
2059/*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
2060};
2061/*
2062 *	Decode table for 0xFF opcodes.
2063 */
2064
2065const instable_t dis_opFF[8] = {
2066
2067/*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
2068/*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
2069};
2070
2071/* for 287 instructions, which are a mess to decode */
2072
2073const instable_t dis_opFP1n2[8][8] = {
2074{
2075/* bit pattern:	1101 1xxx MODxx xR/M */
2076/*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
2077/*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
2078}, {
2079/*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
2080/*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
2081}, {
2082/*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
2083/*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
2084}, {
2085/*  [3,0]  */	TNS("fildl",M),		TNSZ("tisttpl",M,4),	TNS("fistl",M),		TNS("fistpl",M),
2086/*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
2087}, {
2088/*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
2089/*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
2090}, {
2091/*  [5,0]  */	TNSZ("fldl",M,8),	TNSZ("fisttpll",M,8),	TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
2092/*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
2093}, {
2094/*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
2095/*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
2096}, {
2097/*  [7,0]  */	TNSZ("fild",M,2),	TNSZ("fisttp",M,2),	TNSZ("fist",M,2),	TNSZ("fistp",M,2),
2098/*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
2099} };
2100
2101const instable_t dis_opFP3[8][8] = {
2102{
2103/* bit  pattern:	1101 1xxx 11xx xREG */
2104/*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
2105/*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
2106}, {
2107/*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
2108/*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
2109}, {
2110/*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
2111/*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
2112}, {
2113/*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
2114/*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
2115}, {
2116/*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
2117/*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
2118}, {
2119/*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
2120/*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
2121}, {
2122/*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
2123/*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
2124}, {
2125/*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
2126/*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
2127} };
2128
2129const instable_t dis_opFP4[4][8] = {
2130{
2131/* bit pattern:	1101 1001 111x xxxx */
2132/*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
2133/*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
2134}, {
2135/*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
2136/*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
2137}, {
2138/*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
2139/*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
2140}, {
2141/*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
2142/*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
2143} };
2144
2145const instable_t dis_opFP5[8] = {
2146/* bit pattern:	1101 1011 111x xxxx */
2147/*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
2148/*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
2149};
2150
2151const instable_t dis_opFP6[8] = {
2152/* bit pattern:	1101 1011 11yy yxxx */
2153/*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
2154/*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
2155};
2156
2157const instable_t dis_opFP7[8] = {
2158/* bit pattern:	1101 1010 11yy yxxx */
2159/*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
2160/*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
2161};
2162
2163/*
2164 *	Main decode table for the op codes.  The first two nibbles
2165 *	will be used as an index into the table.  If there is a
2166 *	a need to further decode an instruction, the array to be
2167 *	referenced is indicated with the other two entries being
2168 *	empty.
2169 */
2170
2171const instable_t dis_distable[16][16] = {
2172{
2173/* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
2174/* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
2175/* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
2176/* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
2177}, {
2178/* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
2179/* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
2180/* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
2181/* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
2182}, {
2183/* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
2184/* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNSx("%es:",OVERRIDE),	TNSx("daa",NORM),
2185/* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
2186/* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNS("%cs:",OVERRIDE),	TNSx("das",NORM),
2187}, {
2188/* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
2189/* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNSx("%ss:",OVERRIDE),	TNSx("aaa",NORM),
2190/* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
2191/* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNSx("%ds:",OVERRIDE),	TNSx("aas",NORM),
2192}, {
2193/* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
2194/* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
2195/* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
2196/* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
2197}, {
2198/* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
2199/* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
2200/* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
2201/* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
2202}, {
2203/* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
2204/* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
2205/* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
2206/* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
2207}, {
2208/* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
2209/* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
2210/* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
2211/* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
2212}, {
2213/* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
2214/* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
2215/* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
2216/* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
2217}, {
2218/* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
2219/* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
2220/* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
2221/* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNS("sahf",NORM),	TNS("lahf",NORM),
2222}, {
2223/* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
2224/* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
2225/* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
2226/* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
2227}, {
2228/* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
2229/* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
2230/* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
2231/* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
2232}, {
2233/* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
2234/* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
2235/* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
2236/* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
2237}, {
2238/* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
2239/* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
2240
2241/* 287 instructions.  Note that although the indirect field		*/
2242/* indicates opFP1n2 for further decoding, this is not necessarily	*/
2243/* the case since the opFP arrays are not partitioned according to key1	*/
2244/* and key2.  opFP1n2 is given only to indicate that we haven't		*/
2245/* finished decoding the instruction.					*/
2246/* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
2247/* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
2248}, {
2249/* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
2250/* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
2251/* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
2252/* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
2253}, {
2254/* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
2255/* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
2256/* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
2257/* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
2258} };
2259
2260/* END CSTYLED */
2261
2262/*
2263 * common functions to decode and disassemble an x86 or amd64 instruction
2264 */
2265
2266/*
2267 * These are the individual fields of a REX prefix. Note that a REX
2268 * prefix with none of these set is still needed to:
2269 *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
2270 *	- access the %sil, %dil, %bpl, %spl registers
2271 */
2272#define	REX_W 0x08	/* 64 bit operand size when set */
2273#define	REX_R 0x04	/* high order bit extension of ModRM reg field */
2274#define	REX_X 0x02	/* high order bit extension of SIB index field */
2275#define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
2276
2277/*
2278 * These are the individual fields of a VEX prefix.
2279 */
2280#define	VEX_R 0x08	/* REX.R in 1's complement form */
2281#define	VEX_X 0x04	/* REX.X in 1's complement form */
2282#define	VEX_B 0x02	/* REX.B in 1's complement form */
2283/* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
2284#define	VEX_L 0x04
2285#define	VEX_W 0x08	/* opcode specific, use like REX.W */
2286#define	VEX_m 0x1F	/* VEX m-mmmm field */
2287#define	VEX_v 0x78	/* VEX register specifier */
2288#define	VEX_p 0x03	/* VEX pp field, opcode extension */
2289
2290/* VEX m-mmmm field, only used by three bytes prefix */
2291#define	VEX_m_0F 0x01   /* implied 0F leading opcode byte */
2292#define	VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
2293#define	VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
2294
2295/* VEX pp field, providing equivalent functionality of a SIMD prefix */
2296#define	VEX_p_66 0x01
2297#define	VEX_p_F3 0x02
2298#define	VEX_p_F2 0x03
2299
2300/*
2301 * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
2302 */
2303static int isize[] = {1, 2, 4, 4};
2304static int isize64[] = {1, 2, 4, 8};
2305
2306/*
2307 * Just a bunch of useful macros.
2308 */
2309#define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
2310#define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
2311#define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
2312#define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
2313#define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
2314
2315#define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
2316
2317#define	BYTE_OPND	0	/* w-bit value indicating byte register */
2318#define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
2319#define	MM_OPND		2	/* "value" used to indicate a mmx reg */
2320#define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
2321#define	SEG_OPND	4	/* "value" used to indicate a segment reg */
2322#define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
2323#define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
2324#define	TEST_OPND	7	/* "value" used to indicate a test reg */
2325#define	WORD_OPND	8	/* w-bit value indicating word size reg */
2326#define	YMM_OPND	9	/* "value" used to indicate a ymm reg */
2327
2328/*
2329 * The AVX2 gather instructions are a bit of a mess. While there's a pattern,
2330 * there's not really a consistent scheme that we can use to know what the mode
2331 * is supposed to be for a given type. Various instructions, like VPGATHERDD,
2332 * always match the value of VEX_L. Other instructions like VPGATHERDQ, have
2333 * some registers match VEX_L, but the VSIB is always XMM.
2334 *
2335 * The simplest way to deal with this is to just define a table based on the
2336 * instruction opcodes, which are 0x90-0x93, so we subtract 0x90 to index into
2337 * them.
2338 *
2339 * We further have to subdivide this based on the value of VEX_W and the value
2340 * of VEX_L. The array is constructed to be indexed as:
2341 * 	[opcode - 0x90][VEX_W][VEX_L].
2342 */
2343/* w = 0, 0x90 */
2344typedef struct dis_gather_regs {
2345	uint_t dgr_arg0;	/* src reg */
2346	uint_t dgr_arg1;	/* vsib reg */
2347	uint_t dgr_arg2;	/* dst reg */
2348	char   *dgr_suffix;	/* suffix to append */
2349} dis_gather_regs_t;
2350
2351static dis_gather_regs_t dis_vgather[4][2][2] = {
2352	{
2353		/* op 0x90, W.0 */
2354		{
2355			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2356			{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2357		},
2358		/* op 0x90, W.1 */
2359		{
2360			{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2361			{ YMM_OPND, XMM_OPND, YMM_OPND, "q" }
2362		}
2363	},
2364	{
2365		/* op 0x91, W.0 */
2366		{
2367			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2368			{ XMM_OPND, YMM_OPND, XMM_OPND, "d" },
2369		},
2370		/* op 0x91, W.1 */
2371		{
2372			{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2373			{ YMM_OPND, YMM_OPND, YMM_OPND, "q" },
2374		}
2375	},
2376	{
2377		/* op 0x92, W.0 */
2378		{
2379			{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2380			{ YMM_OPND, YMM_OPND, YMM_OPND, "s" }
2381		},
2382		/* op 0x92, W.1 */
2383		{
2384			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2385			{ YMM_OPND, XMM_OPND, YMM_OPND, "d" }
2386		}
2387	},
2388	{
2389		/* op 0x93, W.0 */
2390		{
2391			{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2392			{ XMM_OPND, YMM_OPND, XMM_OPND, "s" }
2393		},
2394		/* op 0x93, W.1 */
2395		{
2396			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2397			{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2398		}
2399	}
2400};
2401
2402/*
2403 * Get the next byte and separate the op code into the high and low nibbles.
2404 */
2405static int
2406dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
2407{
2408	int byte;
2409
2410	/*
2411	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
2412	 * we try to read more.
2413	 */
2414	if (x->d86_len >= 15)
2415		return (x->d86_error = 1);
2416
2417	if (x->d86_error)
2418		return (1);
2419	byte = x->d86_get_byte(x->d86_data);
2420	if (byte < 0)
2421		return (x->d86_error = 1);
2422	x->d86_bytes[x->d86_len++] = byte;
2423	*low = byte & 0xf;		/* ----xxxx low 4 bits */
2424	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
2425	return (0);
2426}
2427
2428/*
2429 * Get and decode an SIB (scaled index base) byte
2430 */
2431static void
2432dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
2433{
2434	int byte;
2435
2436	if (x->d86_error)
2437		return;
2438
2439	byte = x->d86_get_byte(x->d86_data);
2440	if (byte < 0) {
2441		x->d86_error = 1;
2442		return;
2443	}
2444	x->d86_bytes[x->d86_len++] = byte;
2445
2446	*base = byte & 0x7;
2447	*index = (byte >> 3) & 0x7;
2448	*ss = (byte >> 6) & 0x3;
2449}
2450
2451/*
2452 * Get the byte following the op code and separate it into the
2453 * mode, register, and r/m fields.
2454 */
2455static void
2456dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
2457{
2458	if (x->d86_got_modrm == 0) {
2459		if (x->d86_rmindex == -1)
2460			x->d86_rmindex = x->d86_len;
2461		dtrace_get_SIB(x, mode, reg, r_m);
2462		x->d86_got_modrm = 1;
2463	}
2464}
2465
2466/*
2467 * Adjust register selection based on any REX prefix bits present.
2468 */
2469/*ARGSUSED*/
2470static void
2471dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
2472{
2473	if (reg != NULL && r_m == NULL) {
2474		if (rex_prefix & REX_B)
2475			*reg += 8;
2476	} else {
2477		if (reg != NULL && (REX_R & rex_prefix) != 0)
2478			*reg += 8;
2479		if (r_m != NULL && (REX_B & rex_prefix) != 0)
2480			*r_m += 8;
2481	}
2482}
2483
2484/*
2485 * Adjust register selection based on any VEX prefix bits present.
2486 * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
2487 */
2488/*ARGSUSED*/
2489static void
2490dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
2491{
2492	if (reg != NULL && r_m == NULL) {
2493		if (!(vex_byte1 & VEX_B))
2494			*reg += 8;
2495	} else {
2496		if (reg != NULL && ((VEX_R & vex_byte1) == 0))
2497			*reg += 8;
2498		if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
2499			*r_m += 8;
2500	}
2501}
2502
2503/*
2504 * Get an immediate operand of the given size, with sign extension.
2505 */
2506static void
2507dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
2508{
2509	int i;
2510	int byte;
2511	int valsize;
2512
2513	if (x->d86_numopnds < opindex + 1)
2514		x->d86_numopnds = opindex + 1;
2515
2516	switch (wbit) {
2517	case BYTE_OPND:
2518		valsize = 1;
2519		break;
2520	case LONG_OPND:
2521		if (x->d86_opnd_size == SIZE16)
2522			valsize = 2;
2523		else if (x->d86_opnd_size == SIZE32)
2524			valsize = 4;
2525		else
2526			valsize = 8;
2527		break;
2528	case MM_OPND:
2529	case XMM_OPND:
2530	case YMM_OPND:
2531	case SEG_OPND:
2532	case CONTROL_OPND:
2533	case DEBUG_OPND:
2534	case TEST_OPND:
2535		valsize = size;
2536		break;
2537	case WORD_OPND:
2538		valsize = 2;
2539		break;
2540	}
2541	if (valsize < size)
2542		valsize = size;
2543
2544	if (x->d86_error)
2545		return;
2546	x->d86_opnd[opindex].d86_value = 0;
2547	for (i = 0; i < size; ++i) {
2548		byte = x->d86_get_byte(x->d86_data);
2549		if (byte < 0) {
2550			x->d86_error = 1;
2551			return;
2552		}
2553		x->d86_bytes[x->d86_len++] = byte;
2554		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
2555	}
2556	/* Do sign extension */
2557	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
2558		for (; i < sizeof (uint64_t); i++)
2559			x->d86_opnd[opindex].d86_value |=
2560			    (uint64_t)0xff << (i * 8);
2561	}
2562#ifdef DIS_TEXT
2563	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2564	x->d86_opnd[opindex].d86_value_size = valsize;
2565	x->d86_imm_bytes += size;
2566#endif
2567}
2568
2569/*
2570 * Get an ip relative operand of the given size, with sign extension.
2571 */
2572static void
2573dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
2574{
2575	dtrace_imm_opnd(x, wbit, size, opindex);
2576#ifdef DIS_TEXT
2577	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
2578#endif
2579}
2580
2581/*
2582 * Check to see if there is a segment override prefix pending.
2583 * If so, print it in the current 'operand' location and set
2584 * the override flag back to false.
2585 */
2586/*ARGSUSED*/
2587static void
2588dtrace_check_override(dis86_t *x, int opindex)
2589{
2590#ifdef DIS_TEXT
2591	if (x->d86_seg_prefix) {
2592		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
2593		    x->d86_seg_prefix, PFIXLEN);
2594	}
2595#endif
2596	x->d86_seg_prefix = NULL;
2597}
2598
2599
2600/*
2601 * Process a single instruction Register or Memory operand.
2602 *
2603 * mode = addressing mode from ModRM byte
2604 * r_m = r_m (or reg if mode == 3) field from ModRM byte
2605 * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
2606 * o = index of operand that we are processing (0, 1 or 2)
2607 *
2608 * the value of reg or r_m must have already been adjusted for any REX prefix.
2609 */
2610/*ARGSUSED*/
2611static void
2612dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
2613{
2614	int have_SIB = 0;	/* flag presence of scale-index-byte */
2615	uint_t ss;		/* scale-factor from opcode */
2616	uint_t index;		/* index register number */
2617	uint_t base;		/* base register number */
2618	int dispsize;   	/* size of displacement in bytes */
2619#ifdef DIS_TEXT
2620	char *opnd = x->d86_opnd[opindex].d86_opnd;
2621#endif
2622
2623	if (x->d86_numopnds < opindex + 1)
2624		x->d86_numopnds = opindex + 1;
2625
2626	if (x->d86_error)
2627		return;
2628
2629	/*
2630	 * first handle a simple register
2631	 */
2632	if (mode == REG_ONLY) {
2633#ifdef DIS_TEXT
2634		switch (wbit) {
2635		case MM_OPND:
2636			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
2637			break;
2638		case XMM_OPND:
2639			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
2640			break;
2641		case YMM_OPND:
2642			(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
2643			break;
2644		case SEG_OPND:
2645			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
2646			break;
2647		case CONTROL_OPND:
2648			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
2649			break;
2650		case DEBUG_OPND:
2651			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
2652			break;
2653		case TEST_OPND:
2654			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
2655			break;
2656		case BYTE_OPND:
2657			if (x->d86_rex_prefix == 0)
2658				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
2659			else
2660				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
2661			break;
2662		case WORD_OPND:
2663			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2664			break;
2665		case LONG_OPND:
2666			if (x->d86_opnd_size == SIZE16)
2667				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
2668			else if (x->d86_opnd_size == SIZE32)
2669				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
2670			else
2671				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
2672			break;
2673		}
2674#endif /* DIS_TEXT */
2675		return;
2676	}
2677
2678	/*
2679	 * if symbolic representation, skip override prefix, if any
2680	 */
2681	dtrace_check_override(x, opindex);
2682
2683	/*
2684	 * Handle 16 bit memory references first, since they decode
2685	 * the mode values more simply.
2686	 * mode 1 is r_m + 8 bit displacement
2687	 * mode 2 is r_m + 16 bit displacement
2688	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
2689	 */
2690	if (x->d86_addr_size == SIZE16) {
2691		if ((mode == 0 && r_m == 6) || mode == 2)
2692			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
2693		else if (mode == 1)
2694			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
2695#ifdef DIS_TEXT
2696		if (mode == 0 && r_m == 6)
2697			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
2698		else if (mode == 0)
2699			x->d86_opnd[opindex].d86_mode = MODE_NONE;
2700		else
2701			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2702		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
2703#endif
2704		return;
2705	}
2706
2707	/*
2708	 * 32 and 64 bit addressing modes are more complex since they
2709	 * can involve an SIB (scaled index and base) byte to decode.
2710	 */
2711	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
2712		have_SIB = 1;
2713		dtrace_get_SIB(x, &ss, &index, &base);
2714		if (x->d86_error)
2715			return;
2716		if (base != 5 || mode != 0)
2717			if (x->d86_rex_prefix & REX_B)
2718				base += 8;
2719		if (x->d86_rex_prefix & REX_X)
2720			index += 8;
2721	} else {
2722		base = r_m;
2723	}
2724
2725	/*
2726	 * Compute the displacement size and get its bytes
2727	 */
2728	dispsize = 0;
2729
2730	if (mode == 1)
2731		dispsize = 1;
2732	else if (mode == 2)
2733		dispsize = 4;
2734	else if ((r_m & 7) == EBP_REGNO ||
2735	    (have_SIB && (base & 7) == EBP_REGNO))
2736		dispsize = 4;
2737
2738	if (dispsize > 0) {
2739		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
2740		    dispsize, opindex);
2741		if (x->d86_error)
2742			return;
2743	}
2744
2745#ifdef DIS_TEXT
2746	if (dispsize > 0)
2747		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
2748
2749	if (have_SIB == 0) {
2750		if (x->d86_mode == SIZE32) {
2751			if (mode == 0)
2752				(void) strlcat(opnd, dis_addr32_mode0[r_m],
2753				    OPLEN);
2754			else
2755				(void) strlcat(opnd, dis_addr32_mode12[r_m],
2756				    OPLEN);
2757		} else {
2758			if (mode == 0) {
2759				(void) strlcat(opnd, dis_addr64_mode0[r_m],
2760				    OPLEN);
2761				if (r_m == 5) {
2762					x->d86_opnd[opindex].d86_mode =
2763					    MODE_RIPREL;
2764				}
2765			} else {
2766				(void) strlcat(opnd, dis_addr64_mode12[r_m],
2767				    OPLEN);
2768			}
2769		}
2770	} else {
2771		uint_t need_paren = 0;
2772		char **regs;
2773		char **bregs;
2774		const char *const *sf;
2775		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
2776			regs = (char **)dis_REG32;
2777		else
2778			regs = (char **)dis_REG64;
2779
2780		if (x->d86_vsib != 0) {
2781			if (wbit == YMM_OPND) /* NOTE this is not addr_size! */
2782				bregs = (char **)dis_YMMREG;
2783			else
2784				bregs = (char **)dis_XMMREG;
2785			sf = dis_vscale_factor;
2786		} else {
2787			bregs = regs;
2788			sf = dis_scale_factor;
2789		}
2790
2791		/*
2792		 * print the base (if any)
2793		 */
2794		if (base == EBP_REGNO && mode == 0) {
2795			if (index != ESP_REGNO || x->d86_vsib != 0) {
2796				(void) strlcat(opnd, "(", OPLEN);
2797				need_paren = 1;
2798			}
2799		} else {
2800			(void) strlcat(opnd, "(", OPLEN);
2801			(void) strlcat(opnd, regs[base], OPLEN);
2802			need_paren = 1;
2803		}
2804
2805		/*
2806		 * print the index (if any)
2807		 */
2808		if (index != ESP_REGNO || x->d86_vsib) {
2809			(void) strlcat(opnd, ",", OPLEN);
2810			(void) strlcat(opnd, bregs[index], OPLEN);
2811			(void) strlcat(opnd, sf[ss], OPLEN);
2812		} else
2813			if (need_paren)
2814				(void) strlcat(opnd, ")", OPLEN);
2815	}
2816#endif
2817}
2818
2819/*
2820 * Operand sequence for standard instruction involving one register
2821 * and one register/memory operand.
2822 * wbit indicates a byte(0) or opnd_size(1) operation
2823 * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
2824 */
2825#define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
2826		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2827		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2828		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2829		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
2830}
2831
2832/*
2833 * Similar to above, but allows for the two operands to be of different
2834 * classes (ie. wbit).
2835 *	wbit is for the r_m operand
2836 *	w2 is for the reg operand
2837 */
2838#define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
2839		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2840		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2841		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
2842		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
2843}
2844
2845/*
2846 * Similar, but for 2 operands plus an immediate.
2847 * vbit indicates direction
2848 * 	0 for "opcode imm, r, r_m" or
2849 *	1 for "opcode imm, r_m, r"
2850 */
2851#define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
2852		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2853		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2854		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
2855		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
2856		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2857}
2858
2859/*
2860 * Similar, but for 2 operands plus two immediates.
2861 */
2862#define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
2863		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2864		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2865		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2866		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
2867		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2868		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2869}
2870
2871/*
2872 * 1 operands plus two immediates.
2873 */
2874#define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
2875		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
2876		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
2877		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
2878		dtrace_imm_opnd(x, wbit, immsize, 1);			\
2879		dtrace_imm_opnd(x, wbit, immsize, 0);			\
2880}
2881
2882/*
2883 * Dissassemble a single x86 or amd64 instruction.
2884 *
2885 * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
2886 * for interpreting instructions.
2887 *
2888 * returns non-zero for bad opcode
2889 */
2890int
2891dtrace_disx86(dis86_t *x, uint_t cpu_mode)
2892{
2893	instable_t *dp;		/* decode table being used */
2894#ifdef DIS_TEXT
2895	uint_t i;
2896#endif
2897#ifdef DIS_MEM
2898	uint_t nomem = 0;
2899#define	NOMEM	(nomem = 1)
2900#else
2901#define	NOMEM	/* nothing */
2902#endif
2903	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
2904	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
2905	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
2906	uint_t w2;		/* wbit value for second operand */
2907	uint_t vbit;
2908	uint_t mode = 0;	/* mode value from ModRM byte */
2909	uint_t reg;		/* reg value from ModRM byte */
2910	uint_t r_m;		/* r_m value from ModRM byte */
2911
2912	uint_t opcode1;		/* high nibble of 1st byte */
2913	uint_t opcode2;		/* low nibble of 1st byte */
2914	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
2915	uint_t opcode4;		/* high nibble of 2nd byte */
2916	uint_t opcode5;		/* low nibble of 2nd byte */
2917	uint_t opcode6;		/* high nibble of 3rd byte */
2918	uint_t opcode7;		/* low nibble of 3rd byte */
2919	uint_t opcode_bytes = 1;
2920
2921	/*
2922	 * legacy prefixes come in 5 flavors, you should have only one of each
2923	 */
2924	uint_t	opnd_size_prefix = 0;
2925	uint_t	addr_size_prefix = 0;
2926	uint_t	segment_prefix = 0;
2927	uint_t	lock_prefix = 0;
2928	uint_t	rep_prefix = 0;
2929	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
2930
2931	/*
2932	 * Intel VEX instruction encoding prefix and fields
2933	 */
2934
2935	/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
2936	uint_t vex_prefix = 0;
2937
2938	/*
2939	 * VEX prefix byte 1, includes vex.r, vex.x and vex.b
2940	 * (for 3 bytes prefix)
2941	 */
2942	uint_t vex_byte1 = 0;
2943
2944	/*
2945	 * For 32-bit mode, it should prefetch the next byte to
2946	 * distinguish between AVX and les/lds
2947	 */
2948	uint_t vex_prefetch = 0;
2949
2950	uint_t vex_m = 0;
2951	uint_t vex_v = 0;
2952	uint_t vex_p = 0;
2953	uint_t vex_R = 1;
2954	uint_t vex_X = 1;
2955	uint_t vex_B = 1;
2956	uint_t vex_W = 0;
2957	uint_t vex_L;
2958	dis_gather_regs_t *vreg;
2959
2960#ifdef	DIS_TEXT
2961	/* Instruction name for BLS* family of instructions */
2962	char *blsinstr;
2963#endif
2964
2965	size_t	off;
2966
2967	instable_t dp_mmx;
2968
2969	x->d86_len = 0;
2970	x->d86_rmindex = -1;
2971	x->d86_error = 0;
2972#ifdef DIS_TEXT
2973	x->d86_numopnds = 0;
2974	x->d86_seg_prefix = NULL;
2975	x->d86_mnem[0] = 0;
2976	for (i = 0; i < 4; ++i) {
2977		x->d86_opnd[i].d86_opnd[0] = 0;
2978		x->d86_opnd[i].d86_prefix[0] = 0;
2979		x->d86_opnd[i].d86_value_size = 0;
2980		x->d86_opnd[i].d86_value = 0;
2981		x->d86_opnd[i].d86_mode = MODE_NONE;
2982	}
2983#endif
2984	x->d86_rex_prefix = 0;
2985	x->d86_got_modrm = 0;
2986	x->d86_memsize = 0;
2987	x->d86_vsib = 0;
2988
2989	if (cpu_mode == SIZE16) {
2990		opnd_size = SIZE16;
2991		addr_size = SIZE16;
2992	} else if (cpu_mode == SIZE32) {
2993		opnd_size = SIZE32;
2994		addr_size = SIZE32;
2995	} else {
2996		opnd_size = SIZE32;
2997		addr_size = SIZE64;
2998	}
2999
3000	/*
3001	 * Get one opcode byte and check for zero padding that follows
3002	 * jump tables.
3003	 */
3004	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3005		goto error;
3006
3007	if (opcode1 == 0 && opcode2 == 0 &&
3008	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
3009#ifdef DIS_TEXT
3010		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
3011#endif
3012		goto done;
3013	}
3014
3015	/*
3016	 * Gather up legacy x86 prefix bytes.
3017	 */
3018	for (;;) {
3019		uint_t *which_prefix = NULL;
3020
3021		dp = (instable_t *)&dis_distable[opcode1][opcode2];
3022
3023		switch (dp->it_adrmode) {
3024		case PREFIX:
3025			which_prefix = &rep_prefix;
3026			break;
3027		case LOCK:
3028			which_prefix = &lock_prefix;
3029			break;
3030		case OVERRIDE:
3031			which_prefix = &segment_prefix;
3032#ifdef DIS_TEXT
3033			x->d86_seg_prefix = (char *)dp->it_name;
3034#endif
3035			if (dp->it_invalid64 && cpu_mode == SIZE64)
3036				goto error;
3037			break;
3038		case AM:
3039			which_prefix = &addr_size_prefix;
3040			break;
3041		case DM:
3042			which_prefix = &opnd_size_prefix;
3043			break;
3044		}
3045		if (which_prefix == NULL)
3046			break;
3047		*which_prefix = (opcode1 << 4) | opcode2;
3048		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3049			goto error;
3050	}
3051
3052	/*
3053	 * Handle amd64 mode PREFIX values.
3054	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
3055	 * We might have a REX prefix (opcodes 0x40-0x4f)
3056	 */
3057	if (cpu_mode == SIZE64) {
3058		if (segment_prefix != 0x64 && segment_prefix != 0x65)
3059			segment_prefix = 0;
3060
3061		if (opcode1 == 0x4) {
3062			rex_prefix = (opcode1 << 4) | opcode2;
3063			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3064				goto error;
3065			dp = (instable_t *)&dis_distable[opcode1][opcode2];
3066		} else if (opcode1 == 0xC &&
3067		    (opcode2 == 0x4 || opcode2 == 0x5)) {
3068			/* AVX instructions */
3069			vex_prefix = (opcode1 << 4) | opcode2;
3070			x->d86_rex_prefix = 0x40;
3071		}
3072	} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
3073		/* LDS, LES or AVX */
3074		dtrace_get_modrm(x, &mode, &reg, &r_m);
3075		vex_prefetch = 1;
3076
3077		if (mode == REG_ONLY) {
3078			/* AVX */
3079			vex_prefix = (opcode1 << 4) | opcode2;
3080			x->d86_rex_prefix = 0x40;
3081			opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
3082			opcode4 = ((reg << 3) | r_m) & 0x0F;
3083		}
3084	}
3085
3086	if (vex_prefix == VEX_2bytes) {
3087		if (!vex_prefetch) {
3088			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
3089				goto error;
3090		}
3091		vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
3092		vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
3093		vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
3094		vex_p = opcode4 & VEX_p;
3095		/*
3096		 * The vex.x and vex.b bits are not defined in two bytes
3097		 * mode vex prefix, their default values are 1
3098		 */
3099		vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
3100
3101		if (vex_R == 0)
3102			x->d86_rex_prefix |= REX_R;
3103
3104		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3105			goto error;
3106
3107		switch (vex_p) {
3108			case VEX_p_66:
3109				dp = (instable_t *)
3110				    &dis_opAVX660F[(opcode1 << 4) | opcode2];
3111				break;
3112			case VEX_p_F3:
3113				dp = (instable_t *)
3114				    &dis_opAVXF30F[(opcode1 << 4) | opcode2];
3115				break;
3116			case VEX_p_F2:
3117				dp = (instable_t *)
3118				    &dis_opAVXF20F [(opcode1 << 4) | opcode2];
3119				break;
3120			default:
3121				dp = (instable_t *)
3122				    &dis_opAVX0F[opcode1][opcode2];
3123
3124		}
3125
3126	} else if (vex_prefix == VEX_3bytes) {
3127		if (!vex_prefetch) {
3128			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
3129				goto error;
3130		}
3131		vex_R = (opcode3 & VEX_R) >> 3;
3132		vex_X = (opcode3 & VEX_X) >> 2;
3133		vex_B = (opcode3 & VEX_B) >> 1;
3134		vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
3135		vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
3136
3137		if (vex_R == 0)
3138			x->d86_rex_prefix |= REX_R;
3139		if (vex_X == 0)
3140			x->d86_rex_prefix |= REX_X;
3141		if (vex_B == 0)
3142			x->d86_rex_prefix |= REX_B;
3143
3144		if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
3145			goto error;
3146		vex_W = (opcode5 & VEX_W) >> 3;
3147		vex_L = (opcode6 & VEX_L) >> 2;
3148		vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
3149		vex_p = opcode6 & VEX_p;
3150
3151		if (vex_W)
3152			x->d86_rex_prefix |= REX_W;
3153
3154		/* Only these three vex_m values valid; others are reserved */
3155		if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
3156		    (vex_m != VEX_m_0F3A))
3157			goto error;
3158
3159		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
3160			goto error;
3161
3162		switch (vex_p) {
3163			case VEX_p_66:
3164				if (vex_m == VEX_m_0F) {
3165					dp = (instable_t *)
3166					    &dis_opAVX660F
3167					    [(opcode1 << 4) | opcode2];
3168				} else if (vex_m == VEX_m_0F38) {
3169					dp = (instable_t *)
3170					    &dis_opAVX660F38
3171					    [(opcode1 << 4) | opcode2];
3172				} else if (vex_m == VEX_m_0F3A) {
3173					dp = (instable_t *)
3174					    &dis_opAVX660F3A
3175					    [(opcode1 << 4) | opcode2];
3176				} else {
3177					goto error;
3178				}
3179				break;
3180			case VEX_p_F3:
3181				if (vex_m == VEX_m_0F) {
3182					dp = (instable_t *)
3183					    &dis_opAVXF30F
3184					    [(opcode1 << 4) | opcode2];
3185				} else if (vex_m == VEX_m_0F38) {
3186					dp = (instable_t *)
3187					    &dis_opAVXF30F38
3188					    [(opcode1 << 4) | opcode2];
3189				} else {
3190					goto error;
3191				}
3192				break;
3193			case VEX_p_F2:
3194				if (vex_m == VEX_m_0F) {
3195					dp = (instable_t *)
3196					    &dis_opAVXF20F
3197					    [(opcode1 << 4) | opcode2];
3198				} else if (vex_m == VEX_m_0F3A) {
3199					dp = (instable_t *)
3200					    &dis_opAVXF20F3A
3201					    [(opcode1 << 4) | opcode2];
3202				} else if (vex_m == VEX_m_0F38) {
3203					dp = (instable_t *)
3204					    &dis_opAVXF20F38
3205					    [(opcode1 << 4) | opcode2];
3206				} else {
3207					goto error;
3208				}
3209				break;
3210			default:
3211				dp = (instable_t *)
3212				    &dis_opAVX0F[opcode1][opcode2];
3213
3214		}
3215	}
3216	if (vex_prefix) {
3217		if (dp->it_vexwoxmm) {
3218			wbit = LONG_OPND;
3219		} else {
3220			if (vex_L)
3221				wbit = YMM_OPND;
3222			else
3223				wbit = XMM_OPND;
3224		}
3225	}
3226
3227	/*
3228	 * Deal with selection of operand and address size now.
3229	 * Note that the REX.W bit being set causes opnd_size_prefix to be
3230	 * ignored.
3231	 */
3232	if (cpu_mode == SIZE64) {
3233		if ((rex_prefix & REX_W) || vex_W)
3234			opnd_size = SIZE64;
3235		else if (opnd_size_prefix)
3236			opnd_size = SIZE16;
3237
3238		if (addr_size_prefix)
3239			addr_size = SIZE32;
3240	} else if (cpu_mode == SIZE32) {
3241		if (opnd_size_prefix)
3242			opnd_size = SIZE16;
3243		if (addr_size_prefix)
3244			addr_size = SIZE16;
3245	} else {
3246		if (opnd_size_prefix)
3247			opnd_size = SIZE32;
3248		if (addr_size_prefix)
3249			addr_size = SIZE32;
3250	}
3251	/*
3252	 * The pause instruction - a repz'd nop.  This doesn't fit
3253	 * with any of the other prefix goop added for SSE, so we'll
3254	 * special-case it here.
3255	 */
3256	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
3257		rep_prefix = 0;
3258		dp = (instable_t *)&dis_opPause;
3259	}
3260
3261	/*
3262	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
3263	 * byte so we may need to perform a table indirection.
3264	 */
3265	if (dp->it_indirect == (instable_t *)dis_op0F) {
3266		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
3267			goto error;
3268		opcode_bytes = 2;
3269		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
3270			uint_t	subcode;
3271
3272			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
3273				goto error;
3274			opcode_bytes = 3;
3275			subcode = ((opcode6 & 0x3) << 1) |
3276			    ((opcode7 & 0x8) >> 3);
3277			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
3278		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
3279			dp = (instable_t *)&dis_op0FC8[0];
3280		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
3281			opcode_bytes = 3;
3282			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
3283				goto error;
3284			if (opnd_size == SIZE16)
3285				opnd_size = SIZE32;
3286
3287			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
3288#ifdef DIS_TEXT
3289			if (strcmp(dp->it_name, "INVALID") == 0)
3290				goto error;
3291#endif
3292			switch (dp->it_adrmode) {
3293				case XMMP:
3294					break;
3295				case XMMP_66r:
3296				case XMMPRM_66r:
3297				case XMM3PM_66r:
3298					if (opnd_size_prefix == 0) {
3299						goto error;
3300					}
3301					break;
3302				case XMMP_66o:
3303					if (opnd_size_prefix == 0) {
3304						/* SSSE3 MMX instructions */
3305						dp_mmx = *dp;
3306						dp = &dp_mmx;
3307						dp->it_adrmode = MMOPM_66o;
3308#ifdef	DIS_MEM
3309						dp->it_size = 8;
3310#endif
3311					}
3312					break;
3313				default:
3314					goto error;
3315			}
3316		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
3317			opcode_bytes = 3;
3318			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
3319				goto error;
3320			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
3321
3322			/*
3323			 * Both crc32 and movbe have the same 3rd opcode
3324			 * byte of either 0xF0 or 0xF1, so we use another
3325			 * indirection to distinguish between the two.
3326			 */
3327			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
3328			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
3329
3330				dp = dp->it_indirect;
3331				if (rep_prefix != 0xF2) {
3332					/* It is movbe */
3333					dp++;
3334				}
3335			}
3336
3337			/*
3338			 * The adx family of instructions (adcx and adox)
3339			 * continue the classic Intel tradition of abusing
3340			 * arbitrary prefixes without actually meaning the
3341			 * prefix bit. Therefore, if we find either the
3342			 * opnd_size_prefix or rep_prefix we end up zeroing it
3343			 * out after making our determination so as to ensure
3344			 * that we don't get confused and accidentally print
3345			 * repz prefixes and the like on these instructions.
3346			 *
3347			 * In addition, these instructions are actually much
3348			 * closer to AVX instructions in semantics. Importantly,
3349			 * they always default to having 32-bit operands.
3350			 * However, if the CPU is in 64-bit mode, then and only
3351			 * then, does it use REX.w promotes things to 64-bits
3352			 * and REX.r allows 64-bit mode to use register r8-r15.
3353			 */
3354			if (dp->it_indirect == (instable_t *)dis_op0F38F6) {
3355				dp = dp->it_indirect;
3356				if (opnd_size_prefix == 0 &&
3357				    rep_prefix == 0xf3) {
3358					/* It is adox */
3359					dp++;
3360				} else if (opnd_size_prefix != 0x66 &&
3361				    rep_prefix != 0) {
3362					/* It isn't adcx */
3363					goto error;
3364				}
3365				opnd_size_prefix = 0;
3366				rep_prefix = 0;
3367				opnd_size = SIZE32;
3368				if (rex_prefix & REX_W)
3369					opnd_size = SIZE64;
3370			}
3371
3372#ifdef DIS_TEXT
3373			if (strcmp(dp->it_name, "INVALID") == 0)
3374				goto error;
3375#endif
3376			switch (dp->it_adrmode) {
3377				case ADX:
3378				case XMM:
3379					break;
3380				case RM_66r:
3381				case XMM_66r:
3382				case XMMM_66r:
3383					if (opnd_size_prefix == 0) {
3384						goto error;
3385					}
3386					break;
3387				case XMM_66o:
3388					if (opnd_size_prefix == 0) {
3389						/* SSSE3 MMX instructions */
3390						dp_mmx = *dp;
3391						dp = &dp_mmx;
3392						dp->it_adrmode = MM;
3393#ifdef	DIS_MEM
3394						dp->it_size = 8;
3395#endif
3396					}
3397					break;
3398				case CRC32:
3399					if (rep_prefix != 0xF2) {
3400						goto error;
3401					}
3402					rep_prefix = 0;
3403					break;
3404				case MOVBE:
3405					if (rep_prefix != 0x0) {
3406						goto error;
3407					}
3408					break;
3409				default:
3410					goto error;
3411			}
3412		} else {
3413			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
3414		}
3415	}
3416
3417	/*
3418	 * If still not at a TERM decode entry, then a ModRM byte
3419	 * exists and its fields further decode the instruction.
3420	 */
3421	x->d86_got_modrm = 0;
3422	if (dp->it_indirect != TERM) {
3423		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
3424		if (x->d86_error)
3425			goto error;
3426		reg = opcode3;
3427
3428		/*
3429		 * decode 287 instructions (D8-DF) from opcodeN
3430		 */
3431		if (opcode1 == 0xD && opcode2 >= 0x8) {
3432			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
3433				dp = (instable_t *)&dis_opFP5[r_m];
3434			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
3435				dp = (instable_t *)&dis_opFP7[opcode3];
3436			else if (opcode2 == 0xB && mode == 0x3)
3437				dp = (instable_t *)&dis_opFP6[opcode3];
3438			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
3439				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
3440			else if (mode == 0x3)
3441				dp = (instable_t *)
3442				    &dis_opFP3[opcode2 - 8][opcode3];
3443			else
3444				dp = (instable_t *)
3445				    &dis_opFP1n2[opcode2 - 8][opcode3];
3446		} else {
3447			dp = (instable_t *)dp->it_indirect + opcode3;
3448		}
3449	}
3450
3451	/*
3452	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
3453	 * (sign extend 32bit to 64 bit)
3454	 */
3455	if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
3456	    opcode1 == 0x6 && opcode2 == 0x3)
3457		dp = (instable_t *)&dis_opMOVSLD;
3458
3459	/*
3460	 * at this point we should have a correct (or invalid) opcode
3461	 */
3462	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
3463	    cpu_mode != SIZE64 && dp->it_invalid32)
3464		goto error;
3465	if (dp->it_indirect != TERM)
3466		goto error;
3467
3468	/*
3469	 * Deal with MMX/SSE opcodes which are changed by prefixes. Note, we do
3470	 * need to include UNKNOWN below, as we may have instructions that
3471	 * actually have a prefix, but don't exist in any other form.
3472	 */
3473	switch (dp->it_adrmode) {
3474	case UNKNOWN:
3475	case MMO:
3476	case MMOIMPL:
3477	case MMO3P:
3478	case MMOM3:
3479	case MMOMS:
3480	case MMOPM:
3481	case MMOPRM:
3482	case MMOS:
3483	case XMMO:
3484	case XMMOM:
3485	case XMMOMS:
3486	case XMMOPM:
3487	case XMMOS:
3488	case XMMOMX:
3489	case XMMOX3:
3490	case XMMOXMM:
3491		/*
3492		 * This is horrible.  Some SIMD instructions take the
3493		 * form 0x0F 0x?? ..., which is easily decoded using the
3494		 * existing tables.  Other SIMD instructions use various
3495		 * prefix bytes to overload existing instructions.  For
3496		 * Example, addps is F0, 58, whereas addss is F3 (repz),
3497		 * F0, 58.  Presumably someone got a raise for this.
3498		 *
3499		 * If we see one of the instructions which can be
3500		 * modified in this way (if we've got one of the SIMDO*
3501		 * address modes), we'll check to see if the last prefix
3502		 * was a repz.  If it was, we strip the prefix from the
3503		 * mnemonic, and we indirect using the dis_opSIMDrepz
3504		 * table.
3505		 */
3506
3507		/*
3508		 * Calculate our offset in dis_op0F
3509		 */
3510		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
3511			goto error;
3512
3513		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3514		    sizeof (instable_t);
3515
3516		/*
3517		 * Rewrite if this instruction used one of the magic prefixes.
3518		 */
3519		if (rep_prefix) {
3520			if (rep_prefix == 0xf2)
3521				dp = (instable_t *)&dis_opSIMDrepnz[off];
3522			else
3523				dp = (instable_t *)&dis_opSIMDrepz[off];
3524			rep_prefix = 0;
3525		} else if (opnd_size_prefix) {
3526			dp = (instable_t *)&dis_opSIMDdata16[off];
3527			opnd_size_prefix = 0;
3528			if (opnd_size == SIZE16)
3529				opnd_size = SIZE32;
3530		}
3531		break;
3532
3533	case MG9:
3534		/*
3535		 * More horribleness: the group 9 (0xF0 0xC7) instructions are
3536		 * allowed an optional prefix of 0x66 or 0xF3.  This is similar
3537		 * to the SIMD business described above, but with a different
3538		 * addressing mode (and an indirect table), so we deal with it
3539		 * separately (if similarly).
3540		 *
3541		 * Intel further complicated this with the release of Ivy Bridge
3542		 * where they overloaded these instructions based on the ModR/M
3543		 * bytes. The VMX instructions have a mode of 0 since they are
3544		 * memory instructions but rdrand instructions have a mode of
3545		 * 0b11 (REG_ONLY) because they only operate on registers. While
3546		 * there are different prefix formats, for now it is sufficient
3547		 * to use a single different table.
3548		 */
3549
3550		/*
3551		 * Calculate our offset in dis_op0FC7 (the group 9 table)
3552		 */
3553		if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
3554			goto error;
3555
3556		off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
3557		    sizeof (instable_t);
3558
3559		/*
3560		 * If we have a mode of 0b11 then we have to rewrite this.
3561		 */
3562		dtrace_get_modrm(x, &mode, &reg, &r_m);
3563		if (mode == REG_ONLY) {
3564			dp = (instable_t *)&dis_op0FC7m3[off];
3565			break;
3566		}
3567
3568		/*
3569		 * Rewrite if this instruction used one of the magic prefixes.
3570		 */
3571		if (rep_prefix) {
3572			if (rep_prefix == 0xf3)
3573				dp = (instable_t *)&dis_opF30FC7[off];
3574			else
3575				goto error;
3576			rep_prefix = 0;
3577		} else if (opnd_size_prefix) {
3578			dp = (instable_t *)&dis_op660FC7[off];
3579			opnd_size_prefix = 0;
3580			if (opnd_size == SIZE16)
3581				opnd_size = SIZE32;
3582		}
3583		break;
3584
3585
3586	case MMOSH:
3587		/*
3588		 * As with the "normal" SIMD instructions, the MMX
3589		 * shuffle instructions are overloaded.  These
3590		 * instructions, however, are special in that they use
3591		 * an extra byte, and thus an extra table.  As of this
3592		 * writing, they only use the opnd_size prefix.
3593		 */
3594
3595		/*
3596		 * Calculate our offset in dis_op0F7123
3597		 */
3598		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
3599		    sizeof (dis_op0F7123))
3600			goto error;
3601
3602		if (opnd_size_prefix) {
3603			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
3604			    sizeof (instable_t);
3605			dp = (instable_t *)&dis_opSIMD7123[off];
3606			opnd_size_prefix = 0;
3607			if (opnd_size == SIZE16)
3608				opnd_size = SIZE32;
3609		}
3610		break;
3611	case MRw:
3612		if (rep_prefix) {
3613			if (rep_prefix == 0xf3) {
3614
3615				/*
3616				 * Calculate our offset in dis_op0F
3617				 */
3618				if ((uintptr_t)dp - (uintptr_t)dis_op0F
3619				    > sizeof (dis_op0F))
3620					goto error;
3621
3622				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
3623				    sizeof (instable_t);
3624
3625				dp = (instable_t *)&dis_opSIMDrepz[off];
3626				rep_prefix = 0;
3627			} else {
3628				goto error;
3629			}
3630		}
3631		break;
3632	}
3633
3634	/*
3635	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
3636	 */
3637	if (cpu_mode == SIZE64)
3638		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
3639			opnd_size = SIZE64;
3640
3641#ifdef DIS_TEXT
3642	/*
3643	 * At this point most instructions can format the opcode mnemonic
3644	 * including the prefixes.
3645	 */
3646	if (lock_prefix)
3647		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
3648
3649	if (rep_prefix == 0xf2)
3650		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
3651	else if (rep_prefix == 0xf3)
3652		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
3653
3654	if (cpu_mode == SIZE64 && addr_size_prefix)
3655		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
3656
3657	if (dp->it_adrmode != CBW &&
3658	    dp->it_adrmode != CWD &&
3659	    dp->it_adrmode != XMMSFNC) {
3660		if (strcmp(dp->it_name, "INVALID") == 0)
3661			goto error;
3662		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
3663		if (dp->it_avxsuf && dp->it_suffix) {
3664			(void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",
3665			    OPLEN);
3666		} else if (dp->it_suffix) {
3667			char *types[] = {"", "w", "l", "q"};
3668			if (opcode_bytes == 2 && opcode4 == 4) {
3669				/* It's a cmovx.yy. Replace the suffix x */
3670				for (i = 5; i < OPLEN; i++) {
3671					if (x->d86_mnem[i] == '.')
3672						break;
3673				}
3674				x->d86_mnem[i - 1] = *types[opnd_size];
3675			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
3676			    ((opcode6 == 1 && opcode7 == 6) ||
3677			    (opcode6 == 2 && opcode7 == 2))) {
3678				/*
3679				 * To handle PINSRD and PEXTRD
3680				 */
3681				(void) strlcat(x->d86_mnem, "d", OPLEN);
3682			} else {
3683				(void) strlcat(x->d86_mnem, types[opnd_size],
3684				    OPLEN);
3685			}
3686		}
3687	}
3688#endif
3689
3690	/*
3691	 * Process operands based on the addressing modes.
3692	 */
3693	x->d86_mode = cpu_mode;
3694	/*
3695	 * In vex mode the rex_prefix has no meaning
3696	 */
3697	if (!vex_prefix)
3698		x->d86_rex_prefix = rex_prefix;
3699	x->d86_opnd_size = opnd_size;
3700	x->d86_addr_size = addr_size;
3701	vbit = 0;		/* initialize for mem/reg -> reg */
3702	switch (dp->it_adrmode) {
3703		/*
3704		 * amd64 instruction to sign extend 32 bit reg/mem operands
3705		 * into 64 bit register values
3706		 */
3707	case MOVSXZ:
3708#ifdef DIS_TEXT
3709		if (rex_prefix == 0)
3710			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
3711#endif
3712		dtrace_get_modrm(x, &mode, &reg, &r_m);
3713		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3714		x->d86_opnd_size = SIZE64;
3715		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3716		x->d86_opnd_size = opnd_size = SIZE32;
3717		wbit = LONG_OPND;
3718		dtrace_get_operand(x, mode, r_m, wbit, 0);
3719		break;
3720
3721		/*
3722		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
3723		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
3724		 * wbit lives in 2nd byte, note that operands
3725		 * are different sized
3726		 */
3727	case MOVZ:
3728		if (rex_prefix & REX_W) {
3729			/* target register size = 64 bit */
3730			x->d86_mnem[5] = 'q';
3731		}
3732		dtrace_get_modrm(x, &mode, &reg, &r_m);
3733		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3734		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3735		x->d86_opnd_size = opnd_size = SIZE16;
3736		wbit = WBIT(opcode5);
3737		dtrace_get_operand(x, mode, r_m, wbit, 0);
3738		break;
3739	case CRC32:
3740		opnd_size = SIZE32;
3741		if (rex_prefix & REX_W)
3742			opnd_size = SIZE64;
3743		x->d86_opnd_size = opnd_size;
3744
3745		dtrace_get_modrm(x, &mode, &reg, &r_m);
3746		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3747		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3748		wbit = WBIT(opcode7);
3749		if (opnd_size_prefix)
3750			x->d86_opnd_size = opnd_size = SIZE16;
3751		dtrace_get_operand(x, mode, r_m, wbit, 0);
3752		break;
3753	case MOVBE:
3754		opnd_size = SIZE32;
3755		if (rex_prefix & REX_W)
3756			opnd_size = SIZE64;
3757		x->d86_opnd_size = opnd_size;
3758
3759		dtrace_get_modrm(x, &mode, &reg, &r_m);
3760		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3761		wbit = WBIT(opcode7);
3762		if (opnd_size_prefix)
3763			x->d86_opnd_size = opnd_size = SIZE16;
3764		if (wbit) {
3765			/* reg -> mem */
3766			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
3767			dtrace_get_operand(x, mode, r_m, wbit, 1);
3768		} else {
3769			/* mem -> reg */
3770			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3771			dtrace_get_operand(x, mode, r_m, wbit, 0);
3772		}
3773		break;
3774
3775	/*
3776	 * imul instruction, with either 8-bit or longer immediate
3777	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
3778	 */
3779	case IMUL:
3780		wbit = LONG_OPND;
3781		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
3782		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
3783		break;
3784
3785	/* memory or register operand to register, with 'w' bit	*/
3786	case MRw:
3787	case ADX:
3788		wbit = WBIT(opcode2);
3789		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
3790		break;
3791
3792	/* register to memory or register operand, with 'w' bit	*/
3793	/* arpl happens to fit here also because it is odd */
3794	case RMw:
3795		if (opcode_bytes == 2)
3796			wbit = WBIT(opcode5);
3797		else
3798			wbit = WBIT(opcode2);
3799		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3800		break;
3801
3802	/* xaddb instruction */
3803	case XADDB:
3804		wbit = 0;
3805		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3806		break;
3807
3808	/* MMX register to memory or register operand		*/
3809	case MMS:
3810	case MMOS:
3811#ifdef DIS_TEXT
3812		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
3813#else
3814		wbit = LONG_OPND;
3815#endif
3816		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3817		break;
3818
3819	/* MMX register to memory */
3820	case MMOMS:
3821		dtrace_get_modrm(x, &mode, &reg, &r_m);
3822		if (mode == REG_ONLY)
3823			goto error;
3824		wbit = MM_OPND;
3825		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
3826		break;
3827
3828	/* Double shift. Has immediate operand specifying the shift. */
3829	case DSHIFT:
3830		wbit = LONG_OPND;
3831		dtrace_get_modrm(x, &mode, &reg, &r_m);
3832		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
3833		dtrace_get_operand(x, mode, r_m, wbit, 2);
3834		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
3835		dtrace_imm_opnd(x, wbit, 1, 0);
3836		break;
3837
3838	/*
3839	 * Double shift. With no immediate operand, specifies using %cl.
3840	 */
3841	case DSHIFTcl:
3842		wbit = LONG_OPND;
3843		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
3844		break;
3845
3846	/* immediate to memory or register operand */
3847	case IMlw:
3848		wbit = WBIT(opcode2);
3849		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3850		dtrace_get_operand(x, mode, r_m, wbit, 1);
3851		/*
3852		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
3853		 */
3854		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
3855		break;
3856
3857	/* immediate to memory or register operand with the	*/
3858	/* 'w' bit present					*/
3859	case IMw:
3860		wbit = WBIT(opcode2);
3861		dtrace_get_modrm(x, &mode, &reg, &r_m);
3862		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3863		dtrace_get_operand(x, mode, r_m, wbit, 1);
3864		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
3865		break;
3866
3867	/* immediate to register with register in low 3 bits	*/
3868	/* of op code						*/
3869	case IR:
3870		/* w-bit here (with regs) is bit 3 */
3871		wbit = opcode2 >>3 & 0x1;
3872		reg = REGNO(opcode2);
3873		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3874		mode = REG_ONLY;
3875		r_m = reg;
3876		dtrace_get_operand(x, mode, r_m, wbit, 1);
3877		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
3878		break;
3879
3880	/* MMX immediate shift of register */
3881	case MMSH:
3882	case MMOSH:
3883		wbit = MM_OPND;
3884		goto mm_shift;	/* in next case */
3885
3886	/* SIMD immediate shift of register */
3887	case XMMSH:
3888		wbit = XMM_OPND;
3889mm_shift:
3890		reg = REGNO(opcode7);
3891		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
3892		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
3893		dtrace_imm_opnd(x, wbit, 1, 0);
3894		NOMEM;
3895		break;
3896
3897	/* accumulator to memory operand */
3898	case AO:
3899		vbit = 1;
3900		/*FALLTHROUGH*/
3901
3902	/* memory operand to accumulator */
3903	case OA:
3904		wbit = WBIT(opcode2);
3905		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
3906		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
3907#ifdef DIS_TEXT
3908		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
3909#endif
3910		break;
3911
3912
3913	/* segment register to memory or register operand */
3914	case SM:
3915		vbit = 1;
3916		/*FALLTHROUGH*/
3917
3918	/* memory or register operand to segment register */
3919	case MS:
3920		dtrace_get_modrm(x, &mode, &reg, &r_m);
3921		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3922		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
3923		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
3924		break;
3925
3926	/*
3927	 * rotate or shift instructions, which may shift by 1 or
3928	 * consult the cl register, depending on the 'v' bit
3929	 */
3930	case Mv:
3931		vbit = VBIT(opcode2);
3932		wbit = WBIT(opcode2);
3933		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3934		dtrace_get_operand(x, mode, r_m, wbit, 1);
3935#ifdef DIS_TEXT
3936		if (vbit) {
3937			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
3938		} else {
3939			x->d86_opnd[0].d86_mode = MODE_SIGNED;
3940			x->d86_opnd[0].d86_value_size = 1;
3941			x->d86_opnd[0].d86_value = 1;
3942		}
3943#endif
3944		break;
3945	/*
3946	 * immediate rotate or shift instructions
3947	 */
3948	case MvI:
3949		wbit = WBIT(opcode2);
3950normal_imm_mem:
3951		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3952		dtrace_get_operand(x, mode, r_m, wbit, 1);
3953		dtrace_imm_opnd(x, wbit, 1, 0);
3954		break;
3955
3956	/* bit test instructions */
3957	case MIb:
3958		wbit = LONG_OPND;
3959		goto normal_imm_mem;
3960
3961	/* single memory or register operand with 'w' bit present */
3962	case Mw:
3963		wbit = WBIT(opcode2);
3964just_mem:
3965		dtrace_get_modrm(x, &mode, &reg, &r_m);
3966		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
3967		dtrace_get_operand(x, mode, r_m, wbit, 0);
3968		break;
3969
3970	case SWAPGS_RDTSCP:
3971		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
3972#ifdef DIS_TEXT
3973			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
3974#endif
3975			NOMEM;
3976			break;
3977		} else if (mode == 3 && r_m == 1) {
3978#ifdef DIS_TEXT
3979			(void) strncpy(x->d86_mnem, "rdtscp", OPLEN);
3980#endif
3981			NOMEM;
3982			break;
3983		}
3984
3985		/*FALLTHROUGH*/
3986
3987	/* prefetch instruction - memory operand, but no memory acess */
3988	case PREF:
3989		NOMEM;
3990		/*FALLTHROUGH*/
3991
3992	/* single memory or register operand */
3993	case M:
3994	case MG9:
3995		wbit = LONG_OPND;
3996		goto just_mem;
3997
3998	/* single memory or register byte operand */
3999	case Mb:
4000		wbit = BYTE_OPND;
4001		goto just_mem;
4002
4003	case VMx:
4004		if (mode == 3) {
4005#ifdef DIS_TEXT
4006			char *vminstr;
4007
4008			switch (r_m) {
4009			case 1:
4010				vminstr = "vmcall";
4011				break;
4012			case 2:
4013				vminstr = "vmlaunch";
4014				break;
4015			case 3:
4016				vminstr = "vmresume";
4017				break;
4018			case 4:
4019				vminstr = "vmxoff";
4020				break;
4021			default:
4022				goto error;
4023			}
4024
4025			(void) strncpy(x->d86_mnem, vminstr, OPLEN);
4026#else
4027			if (r_m < 1 || r_m > 4)
4028				goto error;
4029#endif
4030
4031			NOMEM;
4032			break;
4033		}
4034		/*FALLTHROUGH*/
4035	case SVM:
4036		if (mode == 3) {
4037#ifdef DIS_TEXT
4038			char *vinstr;
4039
4040			switch (r_m) {
4041			case 0:
4042				vinstr = "vmrun";
4043				break;
4044			case 1:
4045				vinstr = "vmmcall";
4046				break;
4047			case 2:
4048				vinstr = "vmload";
4049				break;
4050			case 3:
4051				vinstr = "vmsave";
4052				break;
4053			case 4:
4054				vinstr = "stgi";
4055				break;
4056			case 5:
4057				vinstr = "clgi";
4058				break;
4059			case 6:
4060				vinstr = "skinit";
4061				break;
4062			case 7:
4063				vinstr = "invlpga";
4064				break;
4065			}
4066
4067			(void) strncpy(x->d86_mnem, vinstr, OPLEN);
4068#endif
4069			NOMEM;
4070			break;
4071		}
4072		/*FALLTHROUGH*/
4073	case MONITOR_MWAIT:
4074		if (mode == 3) {
4075			if (r_m == 0) {
4076#ifdef DIS_TEXT
4077				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
4078#endif
4079				NOMEM;
4080				break;
4081			} else if (r_m == 1) {
4082#ifdef DIS_TEXT
4083				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
4084#endif
4085				NOMEM;
4086				break;
4087			} else if (r_m == 2) {
4088#ifdef DIS_TEXT
4089				(void) strncpy(x->d86_mnem, "clac", OPLEN);
4090#endif
4091				NOMEM;
4092				break;
4093			} else if (r_m == 3) {
4094#ifdef DIS_TEXT
4095				(void) strncpy(x->d86_mnem, "stac", OPLEN);
4096#endif
4097				NOMEM;
4098				break;
4099			} else {
4100				goto error;
4101			}
4102		}
4103		/*FALLTHROUGH*/
4104	case XGETBV_XSETBV:
4105		if (mode == 3) {
4106			if (r_m == 0) {
4107#ifdef DIS_TEXT
4108				(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
4109#endif
4110				NOMEM;
4111				break;
4112			} else if (r_m == 1) {
4113#ifdef DIS_TEXT
4114				(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
4115#endif
4116				NOMEM;
4117				break;
4118			} else {
4119				goto error;
4120			}
4121
4122		}
4123		/*FALLTHROUGH*/
4124	case MO:
4125		/* Similar to M, but only memory (no direct registers) */
4126		wbit = LONG_OPND;
4127		dtrace_get_modrm(x, &mode, &reg, &r_m);
4128		if (mode == 3)
4129			goto error;
4130		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
4131		dtrace_get_operand(x, mode, r_m, wbit, 0);
4132		break;
4133
4134	/* move special register to register or reverse if vbit */
4135	case SREG:
4136		switch (opcode5) {
4137
4138		case 2:
4139			vbit = 1;
4140			/*FALLTHROUGH*/
4141		case 0:
4142			wbit = CONTROL_OPND;
4143			break;
4144
4145		case 3:
4146			vbit = 1;
4147			/*FALLTHROUGH*/
4148		case 1:
4149			wbit = DEBUG_OPND;
4150			break;
4151
4152		case 6:
4153			vbit = 1;
4154			/*FALLTHROUGH*/
4155		case 4:
4156			wbit = TEST_OPND;
4157			break;
4158
4159		}
4160		dtrace_get_modrm(x, &mode, &reg, &r_m);
4161		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4162		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
4163		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
4164		NOMEM;
4165		break;
4166
4167	/*
4168	 * single register operand with register in the low 3
4169	 * bits of op code
4170	 */
4171	case R:
4172		if (opcode_bytes == 2)
4173			reg = REGNO(opcode5);
4174		else
4175			reg = REGNO(opcode2);
4176		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
4177		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
4178		NOMEM;
4179		break;
4180
4181	/*
4182	 * register to accumulator with register in the low 3
4183	 * bits of op code, xchg instructions
4184	 */
4185	case RA:
4186		NOMEM;
4187		reg = REGNO(opcode2);
4188		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
4189		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
4190		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
4191		break;
4192
4193	/*
4194	 * single segment register operand, with register in
4195	 * bits 3-4 of op code byte
4196	 */
4197	case SEG:
4198		NOMEM;
4199		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
4200		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
4201		break;
4202
4203	/*
4204	 * single segment register operand, with register in
4205	 * bits 3-5 of op code
4206	 */
4207	case LSEG:
4208		NOMEM;
4209		/* long seg reg from opcode */
4210		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
4211		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
4212		break;
4213
4214	/* memory or register operand to register */
4215	case MR:
4216		if (vex_prefetch)
4217			x->d86_got_modrm = 1;
4218		wbit = LONG_OPND;
4219		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
4220		break;
4221
4222	case RM:
4223	case RM_66r:
4224		wbit = LONG_OPND;
4225		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
4226		break;
4227
4228	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
4229	case MM:
4230	case MMO:
4231#ifdef DIS_TEXT
4232		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
4233#else
4234		wbit = LONG_OPND;
4235#endif
4236		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
4237		break;
4238
4239	case MMOIMPL:
4240#ifdef DIS_TEXT
4241		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
4242#else
4243		wbit = LONG_OPND;
4244#endif
4245		dtrace_get_modrm(x, &mode, &reg, &r_m);
4246		if (mode != REG_ONLY)
4247			goto error;
4248
4249		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4250		dtrace_get_operand(x, mode, r_m, wbit, 0);
4251		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
4252		mode = 0;	/* change for memory access size... */
4253		break;
4254
4255	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
4256	case MMO3P:
4257		wbit = MM_OPND;
4258		goto xmm3p;
4259	case XMM3P:
4260		wbit = XMM_OPND;
4261xmm3p:
4262		dtrace_get_modrm(x, &mode, &reg, &r_m);
4263		if (mode != REG_ONLY)
4264			goto error;
4265
4266		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
4267		    1);
4268		NOMEM;
4269		break;
4270
4271	case XMM3PM_66r:
4272		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
4273		    1, 0);
4274		break;
4275
4276	/* MMX/SIMD-Int predicated r32/mem to mm reg */
4277	case MMOPRM:
4278		wbit = LONG_OPND;
4279		w2 = MM_OPND;
4280		goto xmmprm;
4281	case XMMPRM:
4282	case XMMPRM_66r:
4283		wbit = LONG_OPND;
4284		w2 = XMM_OPND;
4285xmmprm:
4286		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
4287		break;
4288
4289	/* MMX/SIMD-Int predicated mm/mem to mm reg */
4290	case MMOPM:
4291	case MMOPM_66o:
4292		wbit = w2 = MM_OPND;
4293		goto xmmprm;
4294
4295	/* MMX/SIMD-Int mm reg to r32 */
4296	case MMOM3:
4297		NOMEM;
4298		dtrace_get_modrm(x, &mode, &reg, &r_m);
4299		if (mode != REG_ONLY)
4300			goto error;
4301		wbit = MM_OPND;
4302		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
4303		break;
4304
4305	/* SIMD memory or xmm reg operand to xmm reg		*/
4306	case XMM:
4307	case XMM_66o:
4308	case XMM_66r:
4309	case XMMO:
4310	case XMMXIMPL:
4311		wbit = XMM_OPND;
4312		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
4313
4314		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
4315			goto error;
4316
4317#ifdef DIS_TEXT
4318		/*
4319		 * movlps and movhlps share opcodes.  They differ in the
4320		 * addressing modes allowed for their operands.
4321		 * movhps and movlhps behave similarly.
4322		 */
4323		if (mode == REG_ONLY) {
4324			if (strcmp(dp->it_name, "movlps") == 0)
4325				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
4326			else if (strcmp(dp->it_name, "movhps") == 0)
4327				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
4328		}
4329#endif
4330		if (dp->it_adrmode == XMMXIMPL)
4331			mode = 0;	/* change for memory access size... */
4332		break;
4333
4334	/* SIMD xmm reg to memory or xmm reg */
4335	case XMMS:
4336	case XMMOS:
4337	case XMMMS:
4338	case XMMOMS:
4339		dtrace_get_modrm(x, &mode, &reg, &r_m);
4340#ifdef DIS_TEXT
4341		if ((strcmp(dp->it_name, "movlps") == 0 ||
4342		    strcmp(dp->it_name, "movhps") == 0 ||
4343		    strcmp(dp->it_name, "movntps") == 0) &&
4344		    mode == REG_ONLY)
4345			goto error;
4346#endif
4347		wbit = XMM_OPND;
4348		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
4349		break;
4350
4351	/* SIMD memory to xmm reg */
4352	case XMMM:
4353	case XMMM_66r:
4354	case XMMOM:
4355		wbit = XMM_OPND;
4356		dtrace_get_modrm(x, &mode, &reg, &r_m);
4357#ifdef DIS_TEXT
4358		if (mode == REG_ONLY) {
4359			if (strcmp(dp->it_name, "movhps") == 0)
4360				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
4361			else
4362				goto error;
4363		}
4364#endif
4365		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
4366		break;
4367
4368	/* SIMD memory or r32 to xmm reg			*/
4369	case XMM3MX:
4370		wbit = LONG_OPND;
4371		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
4372		break;
4373
4374	case XMM3MXS:
4375		wbit = LONG_OPND;
4376		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
4377		break;
4378
4379	/* SIMD memory or mm reg to xmm reg			*/
4380	case XMMOMX:
4381	/* SIMD mm to xmm */
4382	case XMMMX:
4383		wbit = MM_OPND;
4384		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
4385		break;
4386
4387	/* SIMD memory or xmm reg to mm reg			*/
4388	case XMMXMM:
4389	case XMMOXMM:
4390	case XMMXM:
4391		wbit = XMM_OPND;
4392		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
4393		break;
4394
4395
4396	/* SIMD memory or xmm reg to r32			*/
4397	case XMMXM3:
4398		wbit = XMM_OPND;
4399		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
4400		break;
4401
4402	/* SIMD xmm to r32					*/
4403	case XMMX3:
4404	case XMMOX3:
4405		dtrace_get_modrm(x, &mode, &reg, &r_m);
4406		if (mode != REG_ONLY)
4407			goto error;
4408		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4409		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
4410		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
4411		NOMEM;
4412		break;
4413
4414	/* SIMD predicated memory or xmm reg with/to xmm reg */
4415	case XMMP:
4416	case XMMP_66r:
4417	case XMMP_66o:
4418	case XMMOPM:
4419		wbit = XMM_OPND;
4420		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
4421		    1);
4422
4423#ifdef DIS_TEXT
4424		/*
4425		 * cmpps and cmpss vary their instruction name based
4426		 * on the value of imm8.  Other XMMP instructions,
4427		 * such as shufps, require explicit specification of
4428		 * the predicate.
4429		 */
4430		if (dp->it_name[0] == 'c' &&
4431		    dp->it_name[1] == 'm' &&
4432		    dp->it_name[2] == 'p' &&
4433		    strlen(dp->it_name) == 5) {
4434			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
4435
4436			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
4437				goto error;
4438
4439			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
4440			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
4441			    OPLEN);
4442			(void) strlcat(x->d86_mnem,
4443			    dp->it_name + strlen(dp->it_name) - 2,
4444			    OPLEN);
4445			x->d86_opnd[0] = x->d86_opnd[1];
4446			x->d86_opnd[1] = x->d86_opnd[2];
4447			x->d86_numopnds = 2;
4448		}
4449#endif
4450		break;
4451
4452	case XMMX2I:
4453		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
4454		    1);
4455		NOMEM;
4456		break;
4457
4458	case XMM2I:
4459		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
4460		NOMEM;
4461		break;
4462
4463	/* immediate operand to accumulator */
4464	case IA:
4465		wbit = WBIT(opcode2);
4466		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
4467		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
4468		NOMEM;
4469		break;
4470
4471	/* memory or register operand to accumulator */
4472	case MA:
4473		wbit = WBIT(opcode2);
4474		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
4475		dtrace_get_operand(x, mode, r_m, wbit, 0);
4476		break;
4477
4478	/* si register to di register used to reference memory		*/
4479	case SD:
4480#ifdef DIS_TEXT
4481		dtrace_check_override(x, 0);
4482		x->d86_numopnds = 2;
4483		if (addr_size == SIZE64) {
4484			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
4485			    OPLEN);
4486			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
4487			    OPLEN);
4488		} else if (addr_size == SIZE32) {
4489			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
4490			    OPLEN);
4491			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
4492			    OPLEN);
4493		} else {
4494			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
4495			    OPLEN);
4496			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
4497			    OPLEN);
4498		}
4499#endif
4500		wbit = LONG_OPND;
4501		break;
4502
4503	/* accumulator to di register				*/
4504	case AD:
4505		wbit = WBIT(opcode2);
4506#ifdef DIS_TEXT
4507		dtrace_check_override(x, 1);
4508		x->d86_numopnds = 2;
4509		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
4510		if (addr_size == SIZE64)
4511			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
4512			    OPLEN);
4513		else if (addr_size == SIZE32)
4514			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
4515			    OPLEN);
4516		else
4517			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
4518			    OPLEN);
4519#endif
4520		break;
4521
4522	/* si register to accumulator				*/
4523	case SA:
4524		wbit = WBIT(opcode2);
4525#ifdef DIS_TEXT
4526		dtrace_check_override(x, 0);
4527		x->d86_numopnds = 2;
4528		if (addr_size == SIZE64)
4529			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
4530			    OPLEN);
4531		else if (addr_size == SIZE32)
4532			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
4533			    OPLEN);
4534		else
4535			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
4536			    OPLEN);
4537		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
4538#endif
4539		break;
4540
4541	/*
4542	 * single operand, a 16/32 bit displacement
4543	 */
4544	case D:
4545		wbit = LONG_OPND;
4546		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
4547		NOMEM;
4548		break;
4549
4550	/* jmp/call indirect to memory or register operand		*/
4551	case INM:
4552#ifdef DIS_TEXT
4553		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
4554#endif
4555		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
4556		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4557		wbit = LONG_OPND;
4558		break;
4559
4560	/*
4561	 * for long jumps and long calls -- a new code segment
4562	 * register and an offset in IP -- stored in object
4563	 * code in reverse order. Note - not valid in amd64
4564	 */
4565	case SO:
4566		dtrace_check_override(x, 1);
4567		wbit = LONG_OPND;
4568		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
4569#ifdef DIS_TEXT
4570		x->d86_opnd[1].d86_mode = MODE_SIGNED;
4571#endif
4572		/* will now get segment operand */
4573		dtrace_imm_opnd(x, wbit, 2, 0);
4574		break;
4575
4576	/*
4577	 * jmp/call. single operand, 8 bit displacement.
4578	 * added to current EIP in 'compofff'
4579	 */
4580	case BD:
4581		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
4582		NOMEM;
4583		break;
4584
4585	/* single 32/16 bit immediate operand			*/
4586	case I:
4587		wbit = LONG_OPND;
4588		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
4589		break;
4590
4591	/* single 8 bit immediate operand			*/
4592	case Ib:
4593		wbit = LONG_OPND;
4594		dtrace_imm_opnd(x, wbit, 1, 0);
4595		break;
4596
4597	case ENTER:
4598		wbit = LONG_OPND;
4599		dtrace_imm_opnd(x, wbit, 2, 0);
4600		dtrace_imm_opnd(x, wbit, 1, 1);
4601		switch (opnd_size) {
4602		case SIZE64:
4603			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
4604			break;
4605		case SIZE32:
4606			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
4607			break;
4608		case SIZE16:
4609			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
4610			break;
4611		}
4612
4613		break;
4614
4615	/* 16-bit immediate operand */
4616	case RET:
4617		wbit = LONG_OPND;
4618		dtrace_imm_opnd(x, wbit, 2, 0);
4619		break;
4620
4621	/* single 8 bit port operand				*/
4622	case P:
4623		dtrace_check_override(x, 0);
4624		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4625		NOMEM;
4626		break;
4627
4628	/* single operand, dx register (variable port instruction) */
4629	case V:
4630		x->d86_numopnds = 1;
4631		dtrace_check_override(x, 0);
4632#ifdef DIS_TEXT
4633		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
4634#endif
4635		NOMEM;
4636		break;
4637
4638	/*
4639	 * The int instruction, which has two forms:
4640	 * int 3 (breakpoint) or
4641	 * int n, where n is indicated in the subsequent
4642	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
4643	 * where, although the 3 looks  like an operand,
4644	 * it is implied by the opcode. It must be converted
4645	 * to the correct base and output.
4646	 */
4647	case INT3:
4648#ifdef DIS_TEXT
4649		x->d86_numopnds = 1;
4650		x->d86_opnd[0].d86_mode = MODE_SIGNED;
4651		x->d86_opnd[0].d86_value_size = 1;
4652		x->d86_opnd[0].d86_value = 3;
4653#endif
4654		NOMEM;
4655		break;
4656
4657	/* single 8 bit immediate operand			*/
4658	case INTx:
4659		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
4660		NOMEM;
4661		break;
4662
4663	/* an unused byte must be discarded */
4664	case U:
4665		if (x->d86_get_byte(x->d86_data) < 0)
4666			goto error;
4667		x->d86_len++;
4668		NOMEM;
4669		break;
4670
4671	case CBW:
4672#ifdef DIS_TEXT
4673		if (opnd_size == SIZE16)
4674			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
4675		else if (opnd_size == SIZE32)
4676			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
4677		else
4678			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
4679#endif
4680		wbit = LONG_OPND;
4681		NOMEM;
4682		break;
4683
4684	case CWD:
4685#ifdef DIS_TEXT
4686		if (opnd_size == SIZE16)
4687			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
4688		else if (opnd_size == SIZE32)
4689			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
4690		else
4691			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
4692#endif
4693		wbit = LONG_OPND;
4694		NOMEM;
4695		break;
4696
4697	case XMMSFNC:
4698		/*
4699		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
4700		 * REG_ONLY, mnemonic should be 'clflush'.
4701		 */
4702		dtrace_get_modrm(x, &mode, &reg, &r_m);
4703
4704		/* sfence doesn't take operands */
4705#ifdef DIS_TEXT
4706		if (mode == REG_ONLY) {
4707			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
4708		} else {
4709			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
4710			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4711			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4712			NOMEM;
4713		}
4714#else
4715		if (mode != REG_ONLY) {
4716			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4717			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
4718			NOMEM;
4719		}
4720#endif
4721		break;
4722
4723	/*
4724	 * no disassembly, the mnemonic was all there was so go on
4725	 */
4726	case NORM:
4727		if (dp->it_invalid32 && cpu_mode != SIZE64)
4728			goto error;
4729		NOMEM;
4730		/*FALLTHROUGH*/
4731	case IMPLMEM:
4732		break;
4733
4734	case XMMFENCE:
4735		/*
4736		 * XRSTOR and LFENCE share the same opcode but differ in mode
4737		 */
4738		dtrace_get_modrm(x, &mode, &reg, &r_m);
4739
4740		if (mode == REG_ONLY) {
4741			/*
4742			 * Only the following exact byte sequences are allowed:
4743			 *
4744			 * 	0f ae e8	lfence
4745			 * 	0f ae f0	mfence
4746			 */
4747			if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
4748			    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
4749				goto error;
4750		} else {
4751#ifdef DIS_TEXT
4752			(void) strncpy(x->d86_mnem, "xrstor", OPLEN);
4753#endif
4754			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
4755			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
4756		}
4757		break;
4758
4759	/* float reg */
4760	case F:
4761#ifdef DIS_TEXT
4762		x->d86_numopnds = 1;
4763		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
4764		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
4765#endif
4766		NOMEM;
4767		break;
4768
4769	/* float reg to float reg, with ret bit present */
4770	case FF:
4771		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
4772		/*FALLTHROUGH*/
4773	case FFC:				/* case for vbit always = 0 */
4774#ifdef DIS_TEXT
4775		x->d86_numopnds = 2;
4776		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
4777		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
4778		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
4779#endif
4780		NOMEM;
4781		break;
4782
4783	/* AVX instructions */
4784	case VEX_MO:
4785		/* op(ModR/M.r/m) */
4786		x->d86_numopnds = 1;
4787		dtrace_get_modrm(x, &mode, &reg, &r_m);
4788#ifdef DIS_TEXT
4789		if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
4790			(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
4791#endif
4792		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4793		dtrace_get_operand(x, mode, r_m, wbit, 0);
4794		break;
4795	case VEX_RMrX:
4796	case FMA:
4797		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
4798		x->d86_numopnds = 3;
4799		dtrace_get_modrm(x, &mode, &reg, &r_m);
4800		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4801
4802		/*
4803		 * In classic Intel fashion, the opcodes for all of the FMA
4804		 * instructions all have two possible mnemonics which vary by
4805		 * one letter, which is selected based on the value of the wbit.
4806		 * When wbit is one, they have the 'd' suffix and when 'wbit' is
4807		 * 0, they have the 's' suffix. Otherwise, the FMA instructions
4808		 * are all a standard VEX_RMrX.
4809		 */
4810#ifdef DIS_TEXT
4811		if (dp->it_adrmode == FMA) {
4812			size_t len = strlen(dp->it_name);
4813			(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
4814			if (len + 1 < OPLEN) {
4815				(void) strncpy(x->d86_mnem + len,
4816				    vex_W != 0 ? "d" : "s", OPLEN - len);
4817			}
4818		}
4819#endif
4820
4821		if (mode != REG_ONLY) {
4822			if ((dp == &dis_opAVXF20F[0x10]) ||
4823			    (dp == &dis_opAVXF30F[0x10])) {
4824				/* vmovsd <m64>, <xmm> */
4825				/* or vmovss <m64>, <xmm> */
4826				x->d86_numopnds = 2;
4827				goto L_VEX_MX;
4828			}
4829		}
4830
4831		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4832		/*
4833		 * VEX prefix uses the 1's complement form to encode the
4834		 * XMM/YMM regs
4835		 */
4836		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4837
4838		if ((dp == &dis_opAVXF20F[0x2A]) ||
4839		    (dp == &dis_opAVXF30F[0x2A])) {
4840			/*
4841			 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
4842			 * <xmm>, <xmm>
4843			 */
4844			wbit = LONG_OPND;
4845		}
4846#ifdef DIS_TEXT
4847		else if ((mode == REG_ONLY) &&
4848		    (dp == &dis_opAVX0F[0x1][0x6])) {	/* vmovlhps */
4849			(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
4850		} else if ((mode == REG_ONLY) &&
4851		    (dp == &dis_opAVX0F[0x1][0x2])) {	/* vmovhlps */
4852			(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
4853		}
4854#endif
4855		dtrace_get_operand(x, mode, r_m, wbit, 0);
4856
4857		break;
4858
4859	case VEX_VRMrX:
4860		/* ModR/M.reg := op(MODR/M.r/m, VEX.vvvv) */
4861		x->d86_numopnds = 3;
4862		dtrace_get_modrm(x, &mode, &reg, &r_m);
4863		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4864
4865		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4866		/*
4867		 * VEX prefix uses the 1's complement form to encode the
4868		 * XMM/YMM regs
4869		 */
4870		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 0);
4871
4872		dtrace_get_operand(x, mode, r_m, wbit, 1);
4873		break;
4874
4875	case VEX_SbVM:
4876		/* ModR/M.reg := op(MODR/M.r/m, VSIB, VEX.vvvv) */
4877		x->d86_numopnds = 3;
4878		x->d86_vsib = 1;
4879
4880		/*
4881		 * All instructions that use VSIB are currently a mess. See the
4882		 * comment around the dis_gather_regs_t structure definition.
4883		 */
4884
4885		vreg = &dis_vgather[opcode2][vex_W][vex_L];
4886
4887#ifdef DIS_TEXT
4888		(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
4889		(void) strlcat(x->d86_mnem + strlen(dp->it_name),
4890		    vreg->dgr_suffix, OPLEN - strlen(dp->it_name));
4891#endif
4892
4893		dtrace_get_modrm(x, &mode, &reg, &r_m);
4894		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4895
4896		dtrace_get_operand(x, REG_ONLY, reg, vreg->dgr_arg2, 2);
4897		/*
4898		 * VEX prefix uses the 1's complement form to encode the
4899		 * XMM/YMM regs
4900		 */
4901		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), vreg->dgr_arg0,
4902		    0);
4903		dtrace_get_operand(x, mode, r_m, vreg->dgr_arg1, 1);
4904		break;
4905
4906	case VEX_RRX:
4907		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
4908		x->d86_numopnds = 3;
4909
4910		dtrace_get_modrm(x, &mode, &reg, &r_m);
4911		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4912
4913		if (mode != REG_ONLY) {
4914			if ((dp == &dis_opAVXF20F[0x11]) ||
4915			    (dp == &dis_opAVXF30F[0x11])) {
4916				/* vmovsd <xmm>, <m64> */
4917				/* or vmovss <xmm>, <m64> */
4918				x->d86_numopnds = 2;
4919				goto L_VEX_RM;
4920			}
4921		}
4922
4923		dtrace_get_operand(x, mode, r_m, wbit, 2);
4924		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
4925		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
4926		break;
4927
4928	case VEX_RMRX:
4929		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
4930		x->d86_numopnds = 4;
4931
4932		dtrace_get_modrm(x, &mode, &reg, &r_m);
4933		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4934		dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
4935		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
4936		if (dp == &dis_opAVX660F3A[0x18]) {
4937			/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
4938			dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
4939		} else if ((dp == &dis_opAVX660F3A[0x20]) ||
4940		    (dp == & dis_opAVX660F[0xC4])) {
4941			/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
4942			/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
4943			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4944		} else if (dp == &dis_opAVX660F3A[0x22]) {
4945			/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
4946#ifdef DIS_TEXT
4947			if (vex_W)
4948				x->d86_mnem[6] = 'q';
4949#endif
4950			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
4951		} else {
4952			dtrace_get_operand(x, mode, r_m, wbit, 1);
4953		}
4954
4955		/* one byte immediate number */
4956		dtrace_imm_opnd(x, wbit, 1, 0);
4957
4958		/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
4959		if ((dp == &dis_opAVX660F3A[0x4A]) ||
4960		    (dp == &dis_opAVX660F3A[0x4B]) ||
4961		    (dp == &dis_opAVX660F3A[0x4C])) {
4962#ifdef DIS_TEXT
4963			int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
4964#endif
4965			x->d86_opnd[0].d86_mode = MODE_NONE;
4966#ifdef DIS_TEXT
4967			if (vex_L)
4968				(void) strncpy(x->d86_opnd[0].d86_opnd,
4969				    dis_YMMREG[regnum], OPLEN);
4970			else
4971				(void) strncpy(x->d86_opnd[0].d86_opnd,
4972				    dis_XMMREG[regnum], OPLEN);
4973#endif
4974		}
4975		break;
4976
4977	case VEX_MX:
4978		/* ModR/M.reg := op(ModR/M.rm) */
4979		x->d86_numopnds = 2;
4980
4981		dtrace_get_modrm(x, &mode, &reg, &r_m);
4982		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4983L_VEX_MX:
4984
4985		if ((dp == &dis_opAVXF20F[0xE6]) ||
4986		    (dp == &dis_opAVX660F[0x5A]) ||
4987		    (dp == &dis_opAVX660F[0xE6])) {
4988			/* vcvtpd2dq <ymm>, <xmm> */
4989			/* or vcvtpd2ps <ymm>, <xmm> */
4990			/* or vcvttpd2dq <ymm>, <xmm> */
4991			dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
4992			dtrace_get_operand(x, mode, r_m, wbit, 0);
4993		} else if ((dp == &dis_opAVXF30F[0xE6]) ||
4994		    (dp == &dis_opAVX0F[0x5][0xA]) ||
4995		    (dp == &dis_opAVX660F38[0x13]) ||
4996		    (dp == &dis_opAVX660F38[0x18]) ||
4997		    (dp == &dis_opAVX660F38[0x19]) ||
4998		    (dp == &dis_opAVX660F38[0x58]) ||
4999		    (dp == &dis_opAVX660F38[0x78]) ||
5000		    (dp == &dis_opAVX660F38[0x79]) ||
5001		    (dp == &dis_opAVX660F38[0x59])) {
5002			/* vcvtdq2pd <xmm>, <ymm> */
5003			/* or vcvtps2pd <xmm>, <ymm> */
5004			/* or vcvtph2ps <xmm>, <ymm> */
5005			/* or vbroadcasts* <xmm>, <ymm> */
5006			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5007			dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
5008		} else if (dp == &dis_opAVX660F[0x6E]) {
5009			/* vmovd/q <reg/mem 32/64>, <xmm> */
5010#ifdef DIS_TEXT
5011			if (vex_W)
5012				x->d86_mnem[4] = 'q';
5013#endif
5014			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5015			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
5016		} else {
5017			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5018			dtrace_get_operand(x, mode, r_m, wbit, 0);
5019		}
5020
5021		break;
5022
5023	case VEX_MXI:
5024		/* ModR/M.reg := op(ModR/M.rm, imm8) */
5025		x->d86_numopnds = 3;
5026
5027		dtrace_get_modrm(x, &mode, &reg, &r_m);
5028		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5029
5030		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
5031		dtrace_get_operand(x, mode, r_m, wbit, 1);
5032
5033		/* one byte immediate number */
5034		dtrace_imm_opnd(x, wbit, 1, 0);
5035		break;
5036
5037	case VEX_XXI:
5038		/* VEX.vvvv := op(ModR/M.rm, imm8) */
5039		x->d86_numopnds = 3;
5040
5041		dtrace_get_modrm(x, &mode, &reg, &r_m);
5042#ifdef DIS_TEXT
5043		(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
5044		    OPLEN);
5045#endif
5046		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5047
5048		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
5049		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
5050
5051		/* one byte immediate number */
5052		dtrace_imm_opnd(x, wbit, 1, 0);
5053		break;
5054
5055	case VEX_MR:
5056		/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
5057		if (dp == &dis_opAVX660F[0xC5]) {
5058			/* vpextrw <imm8>, <xmm>, <reg> */
5059			x->d86_numopnds = 2;
5060			vbit = 2;
5061		} else {
5062			x->d86_numopnds = 2;
5063			vbit = 1;
5064		}
5065
5066		dtrace_get_modrm(x, &mode, &reg, &r_m);
5067		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5068		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
5069		dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
5070
5071		if (vbit == 2)
5072			dtrace_imm_opnd(x, wbit, 1, 0);
5073
5074		break;
5075
5076	case VEX_RRI:
5077		/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
5078		x->d86_numopnds = 2;
5079
5080		dtrace_get_modrm(x, &mode, &reg, &r_m);
5081		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5082		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5083		dtrace_get_operand(x, mode, r_m, wbit, 0);
5084		break;
5085
5086	case VEX_RX:
5087		/* ModR/M.rm := op(ModR/M.reg) */
5088		/* vextractf128 || vcvtps2ph */
5089		if (dp == &dis_opAVX660F3A[0x19] ||
5090		    dp == &dis_opAVX660F3A[0x1d]) {
5091			x->d86_numopnds = 3;
5092
5093			dtrace_get_modrm(x, &mode, &reg, &r_m);
5094			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5095
5096			dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
5097			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5098
5099			/* one byte immediate number */
5100			dtrace_imm_opnd(x, wbit, 1, 0);
5101			break;
5102		}
5103
5104		x->d86_numopnds = 2;
5105
5106		dtrace_get_modrm(x, &mode, &reg, &r_m);
5107		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5108		dtrace_get_operand(x, mode, r_m, wbit, 1);
5109		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
5110		break;
5111
5112	case VEX_RR:
5113		/* ModR/M.rm := op(ModR/M.reg) */
5114		x->d86_numopnds = 2;
5115
5116		dtrace_get_modrm(x, &mode, &reg, &r_m);
5117		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5118
5119		if (dp == &dis_opAVX660F[0x7E]) {
5120			/* vmovd/q <reg/mem 32/64>, <xmm> */
5121#ifdef DIS_TEXT
5122			if (vex_W)
5123				x->d86_mnem[4] = 'q';
5124#endif
5125			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
5126		} else
5127			dtrace_get_operand(x, mode, r_m, wbit, 1);
5128
5129		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
5130		break;
5131
5132	case VEX_RRi:
5133		/* ModR/M.rm := op(ModR/M.reg, imm) */
5134		x->d86_numopnds = 3;
5135
5136		dtrace_get_modrm(x, &mode, &reg, &r_m);
5137		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5138
5139#ifdef DIS_TEXT
5140		if (dp == &dis_opAVX660F3A[0x16]) {
5141			/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
5142			if (vex_W)
5143				x->d86_mnem[6] = 'q';
5144		}
5145#endif
5146		dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
5147		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5148
5149		/* one byte immediate number */
5150		dtrace_imm_opnd(x, wbit, 1, 0);
5151		break;
5152	case VEX_RIM:
5153		/* ModR/M.rm := op(ModR/M.reg, imm) */
5154		x->d86_numopnds = 3;
5155
5156		dtrace_get_modrm(x, &mode, &reg, &r_m);
5157		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5158
5159		dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
5160		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5161		/* one byte immediate number */
5162		dtrace_imm_opnd(x, wbit, 1, 0);
5163		break;
5164
5165	case VEX_RM:
5166		/* ModR/M.rm := op(ModR/M.reg) */
5167		if (dp == &dis_opAVX660F3A[0x17]) {	/* vextractps */
5168			x->d86_numopnds = 3;
5169
5170			dtrace_get_modrm(x, &mode, &reg, &r_m);
5171			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5172
5173			dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
5174			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5175			/* one byte immediate number */
5176			dtrace_imm_opnd(x, wbit, 1, 0);
5177			break;
5178		}
5179		x->d86_numopnds = 2;
5180
5181		dtrace_get_modrm(x, &mode, &reg, &r_m);
5182		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5183L_VEX_RM:
5184		vbit = 1;
5185		dtrace_get_operand(x, mode, r_m, wbit, vbit);
5186		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
5187
5188		break;
5189
5190	case VEX_RRM:
5191		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
5192		x->d86_numopnds = 3;
5193
5194		dtrace_get_modrm(x, &mode, &reg, &r_m);
5195		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5196		dtrace_get_operand(x, mode, r_m, wbit, 2);
5197		/* VEX use the 1's complement form encode the XMM/YMM regs */
5198		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
5199		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
5200		break;
5201
5202	case VEX_RMX:
5203		/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
5204		x->d86_numopnds = 3;
5205
5206		dtrace_get_modrm(x, &mode, &reg, &r_m);
5207		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5208		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
5209		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
5210		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
5211		break;
5212
5213	case VEX_NONE:
5214#ifdef DIS_TEXT
5215		if (vex_L)
5216			(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
5217#endif
5218		break;
5219	case BLS: {
5220
5221		/*
5222		 * The BLS instructions are VEX instructions that are based on
5223		 * VEX.0F38.F3; however, they are considered special group 17
5224		 * and like everything else, they use the bits in 3-5 of the
5225		 * MOD R/M to determine the sub instruction. Unlike many others
5226		 * like the VMX instructions, these are valid both for memory
5227		 * and register forms.
5228		 */
5229
5230		dtrace_get_modrm(x, &mode, &reg, &r_m);
5231		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5232
5233		switch (reg) {
5234		case 1:
5235#ifdef	DIS_TEXT
5236			blsinstr = "blsr";
5237#endif
5238			break;
5239		case 2:
5240#ifdef	DIS_TEXT
5241			blsinstr = "blsmsk";
5242#endif
5243			break;
5244		case 3:
5245#ifdef	DIS_TEXT
5246			blsinstr = "blsi";
5247#endif
5248			break;
5249		default:
5250			goto error;
5251		}
5252
5253		x->d86_numopnds = 2;
5254#ifdef DIS_TEXT
5255		(void) strncpy(x->d86_mnem, blsinstr, OPLEN);
5256#endif
5257		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
5258		dtrace_get_operand(x, mode, r_m, wbit, 0);
5259		break;
5260	}
5261	/* an invalid op code */
5262	case AM:
5263	case DM:
5264	case OVERRIDE:
5265	case PREFIX:
5266	case UNKNOWN:
5267		NOMEM;
5268	default:
5269		goto error;
5270	} /* end switch */
5271	if (x->d86_error)
5272		goto error;
5273
5274done:
5275#ifdef DIS_MEM
5276	/*
5277	 * compute the size of any memory accessed by the instruction
5278	 */
5279	if (x->d86_memsize != 0) {
5280		return (0);
5281	} else if (dp->it_stackop) {
5282		switch (opnd_size) {
5283		case SIZE16:
5284			x->d86_memsize = 2;
5285			break;
5286		case SIZE32:
5287			x->d86_memsize = 4;
5288			break;
5289		case SIZE64:
5290			x->d86_memsize = 8;
5291			break;
5292		}
5293	} else if (nomem || mode == REG_ONLY) {
5294		x->d86_memsize = 0;
5295
5296	} else if (dp->it_size != 0) {
5297		/*
5298		 * In 64 bit mode descriptor table entries
5299		 * go up to 10 bytes and popf/pushf are always 8 bytes
5300		 */
5301		if (x->d86_mode == SIZE64 && dp->it_size == 6)
5302			x->d86_memsize = 10;
5303		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
5304		    (opcode2 == 0xc || opcode2 == 0xd))
5305			x->d86_memsize = 8;
5306		else
5307			x->d86_memsize = dp->it_size;
5308
5309	} else if (wbit == 0) {
5310		x->d86_memsize = 1;
5311
5312	} else if (wbit == LONG_OPND) {
5313		if (opnd_size == SIZE64)
5314			x->d86_memsize = 8;
5315		else if (opnd_size == SIZE32)
5316			x->d86_memsize = 4;
5317		else
5318			x->d86_memsize = 2;
5319
5320	} else if (wbit == SEG_OPND) {
5321		x->d86_memsize = 4;
5322
5323	} else {
5324		x->d86_memsize = 8;
5325	}
5326#endif
5327	return (0);
5328
5329error:
5330#ifdef DIS_TEXT
5331	(void) strlcat(x->d86_mnem, "undef", OPLEN);
5332#endif
5333	return (1);
5334}
5335
5336#ifdef DIS_TEXT
5337
5338/*
5339 * Some instructions should have immediate operands printed
5340 * as unsigned integers. We compare against this table.
5341 */
5342static char *unsigned_ops[] = {
5343	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
5344	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
5345	0
5346};
5347
5348
5349static int
5350isunsigned_op(char *opcode)
5351{
5352	char *where;
5353	int i;
5354	int is_unsigned = 0;
5355
5356	/*
5357	 * Work back to start of last mnemonic, since we may have
5358	 * prefixes on some opcodes.
5359	 */
5360	where = opcode + strlen(opcode) - 1;
5361	while (where > opcode && *where != ' ')
5362		--where;
5363	if (*where == ' ')
5364		++where;
5365
5366	for (i = 0; unsigned_ops[i]; ++i) {
5367		if (strncmp(where, unsigned_ops[i],
5368		    strlen(unsigned_ops[i])))
5369			continue;
5370		is_unsigned = 1;
5371		break;
5372	}
5373	return (is_unsigned);
5374}
5375
5376/*
5377 * Print a numeric immediate into end of buf, maximum length buflen.
5378 * The immediate may be an address or a displacement.  Mask is set
5379 * for address size.  If the immediate is a "small negative", or
5380 * if it's a negative displacement of any magnitude, print as -<absval>.
5381 * Respect the "octal" flag.  "Small negative" is defined as "in the
5382 * interval [NEG_LIMIT, 0)".
5383 *
5384 * Also, "isunsigned_op()" instructions never print negatives.
5385 *
5386 * Return whether we decided to print a negative value or not.
5387 */
5388
5389#define	NEG_LIMIT	-255
5390enum {IMM, DISP};
5391enum {POS, TRY_NEG};
5392
5393static int
5394print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
5395    size_t buflen, int disp, int try_neg)
5396{
5397	int curlen;
5398	int64_t sv = (int64_t)usv;
5399	int octal = dis->d86_flags & DIS_F_OCTAL;
5400
5401	curlen = strlen(buf);
5402
5403	if (try_neg == TRY_NEG && sv < 0 &&
5404	    (disp || sv >= NEG_LIMIT) &&
5405	    !isunsigned_op(dis->d86_mnem)) {
5406		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
5407		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
5408		return (1);
5409	} else {
5410		if (disp == DISP)
5411			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
5412			    octal ? "+0%llo" : "+0x%llx", usv & mask);
5413		else
5414			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
5415			    octal ? "0%llo" : "0x%llx", usv & mask);
5416		return (0);
5417
5418	}
5419}
5420
5421
5422static int
5423log2(int size)
5424{
5425	switch (size) {
5426	case 1: return (0);
5427	case 2: return (1);
5428	case 4: return (2);
5429	case 8: return (3);
5430	}
5431	return (0);
5432}
5433
5434/* ARGSUSED */
5435void
5436dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
5437    size_t buflen)
5438{
5439	uint64_t reltgt = 0;
5440	uint64_t tgt = 0;
5441	int curlen;
5442	int (*lookup)(void *, uint64_t, char *, size_t);
5443	int i;
5444	int64_t sv;
5445	uint64_t usv, mask, save_mask, save_usv;
5446	static uint64_t masks[] =
5447	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
5448	save_usv = 0;
5449
5450	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
5451
5452	/*
5453	 * For PC-relative jumps, the pc is really the next pc after executing
5454	 * this instruction, so increment it appropriately.
5455	 */
5456	pc += dis->d86_len;
5457
5458	for (i = 0; i < dis->d86_numopnds; i++) {
5459		d86opnd_t *op = &dis->d86_opnd[i];
5460
5461		if (i != 0)
5462			(void) strlcat(buf, ",", buflen);
5463
5464		(void) strlcat(buf, op->d86_prefix, buflen);
5465
5466		/*
5467		 * sv is for the signed, possibly-truncated immediate or
5468		 * displacement; usv retains the original size and
5469		 * unsignedness for symbol lookup.
5470		 */
5471
5472		sv = usv = op->d86_value;
5473
5474		/*
5475		 * About masks: for immediates that represent
5476		 * addresses, the appropriate display size is
5477		 * the effective address size of the instruction.
5478		 * This includes MODE_OFFSET, MODE_IPREL, and
5479		 * MODE_RIPREL.  Immediates that are simply
5480		 * immediate values should display in the operand's
5481		 * size, however, since they don't represent addresses.
5482		 */
5483
5484		/* d86_addr_size is SIZEnn, which is log2(real size) */
5485		mask = masks[dis->d86_addr_size];
5486
5487		/* d86_value_size and d86_imm_bytes are in bytes */
5488		if (op->d86_mode == MODE_SIGNED ||
5489		    op->d86_mode == MODE_IMPLIED)
5490			mask = masks[log2(op->d86_value_size)];
5491
5492		switch (op->d86_mode) {
5493
5494		case MODE_NONE:
5495
5496			(void) strlcat(buf, op->d86_opnd, buflen);
5497			break;
5498
5499		case MODE_SIGNED:
5500		case MODE_IMPLIED:
5501		case MODE_OFFSET:
5502
5503			tgt = usv;
5504
5505			if (dis->d86_seg_prefix)
5506				(void) strlcat(buf, dis->d86_seg_prefix,
5507				    buflen);
5508
5509			if (op->d86_mode == MODE_SIGNED ||
5510			    op->d86_mode == MODE_IMPLIED) {
5511				(void) strlcat(buf, "$", buflen);
5512			}
5513
5514			if (print_imm(dis, usv, mask, buf, buflen,
5515			    IMM, TRY_NEG) &&
5516			    (op->d86_mode == MODE_SIGNED ||
5517			    op->d86_mode == MODE_IMPLIED)) {
5518
5519				/*
5520				 * We printed a negative value for an
5521				 * immediate that wasn't a
5522				 * displacement.  Note that fact so we can
5523				 * print the positive value as an
5524				 * annotation.
5525				 */
5526
5527				save_usv = usv;
5528				save_mask = mask;
5529			}
5530			(void) strlcat(buf, op->d86_opnd, buflen);
5531
5532			break;
5533
5534		case MODE_IPREL:
5535		case MODE_RIPREL:
5536
5537			reltgt = pc + sv;
5538
5539			switch (mode) {
5540			case SIZE16:
5541				reltgt = (uint16_t)reltgt;
5542				break;
5543			case SIZE32:
5544				reltgt = (uint32_t)reltgt;
5545				break;
5546			}
5547
5548			(void) print_imm(dis, usv, mask, buf, buflen,
5549			    DISP, TRY_NEG);
5550
5551			if (op->d86_mode == MODE_RIPREL)
5552				(void) strlcat(buf, "(%rip)", buflen);
5553			break;
5554		}
5555	}
5556
5557	/*
5558	 * The symbol lookups may result in false positives,
5559	 * particularly on object files, where small numbers may match
5560	 * the 0-relative non-relocated addresses of symbols.
5561	 */
5562
5563	lookup = dis->d86_sym_lookup;
5564	if (tgt != 0) {
5565		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
5566		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
5567			(void) strlcat(buf, "\t<", buflen);
5568			curlen = strlen(buf);
5569			lookup(dis->d86_data, tgt, buf + curlen,
5570			    buflen - curlen);
5571			(void) strlcat(buf, ">", buflen);
5572		}
5573
5574		/*
5575		 * If we printed a negative immediate above, print the
5576		 * positive in case our heuristic was unhelpful
5577		 */
5578		if (save_usv) {
5579			(void) strlcat(buf, "\t<", buflen);
5580			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
5581			    IMM, POS);
5582			(void) strlcat(buf, ">", buflen);
5583		}
5584	}
5585
5586	if (reltgt != 0) {
5587		/* Print symbol or effective address for reltgt */
5588
5589		(void) strlcat(buf, "\t<", buflen);
5590		curlen = strlen(buf);
5591		lookup(dis->d86_data, reltgt, buf + curlen,
5592		    buflen - curlen);
5593		(void) strlcat(buf, ">", buflen);
5594	}
5595}
5596
5597#endif /* DIS_TEXT */
5598