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