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