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