xref: /freebsd/sys/cddl/dev/dtrace/x86/dis_tables.c (revision 2d69831b850cfda3faaae6ead1b661b95cb0e6e7)
10339a1c2SMark Johnston /*
20339a1c2SMark Johnston  *
30339a1c2SMark Johnston  * CDDL HEADER START
40339a1c2SMark Johnston  *
50339a1c2SMark Johnston  * The contents of this file are subject to the terms of the
60339a1c2SMark Johnston  * Common Development and Distribution License (the "License").
70339a1c2SMark Johnston  * You may not use this file except in compliance with the License.
80339a1c2SMark Johnston  *
90339a1c2SMark Johnston  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100339a1c2SMark Johnston  * or http://www.opensolaris.org/os/licensing.
110339a1c2SMark Johnston  * See the License for the specific language governing permissions
120339a1c2SMark Johnston  * and limitations under the License.
130339a1c2SMark Johnston  *
140339a1c2SMark Johnston  * When distributing Covered Code, include this CDDL HEADER in each
150339a1c2SMark Johnston  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160339a1c2SMark Johnston  * If applicable, add the following below this CDDL HEADER, with the
170339a1c2SMark Johnston  * fields enclosed by brackets "[]" replaced with your own identifying
180339a1c2SMark Johnston  * information: Portions Copyright [yyyy] [name of copyright owner]
190339a1c2SMark Johnston  *
200339a1c2SMark Johnston  * CDDL HEADER END
210339a1c2SMark Johnston  */
220339a1c2SMark Johnston /*
230339a1c2SMark Johnston  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24c3ddb60eSPeter Grehan  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
250339a1c2SMark Johnston  */
260339a1c2SMark Johnston 
270339a1c2SMark Johnston /*
280339a1c2SMark Johnston  * Copyright (c) 2010, Intel Corporation.
290339a1c2SMark Johnston  * All rights reserved.
300339a1c2SMark Johnston  */
310339a1c2SMark Johnston 
320339a1c2SMark Johnston /*	Copyright (c) 1988 AT&T	*/
330339a1c2SMark Johnston /*	  All Rights Reserved  	*/
340339a1c2SMark Johnston 
350339a1c2SMark Johnston /*
360339a1c2SMark Johnston  * $FreeBSD$
370339a1c2SMark Johnston  */
380339a1c2SMark Johnston 
390339a1c2SMark Johnston #include	"dis_tables.h"
400339a1c2SMark Johnston 
410339a1c2SMark Johnston /* BEGIN CSTYLED */
420339a1c2SMark Johnston 
430339a1c2SMark Johnston /*
440339a1c2SMark Johnston  * Disassembly begins in dis_distable, which is equivalent to the One-byte
450339a1c2SMark Johnston  * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
460339a1c2SMark Johnston  * decoding loops then traverse out through the other tables as necessary to
470339a1c2SMark Johnston  * decode a given instruction.
480339a1c2SMark Johnston  *
490339a1c2SMark Johnston  * The behavior of this file can be controlled by one of the following flags:
500339a1c2SMark Johnston  *
510339a1c2SMark Johnston  * 	DIS_TEXT	Include text for disassembly
520339a1c2SMark Johnston  * 	DIS_MEM		Include memory-size calculations
530339a1c2SMark Johnston  *
540339a1c2SMark Johnston  * Either or both of these can be defined.
550339a1c2SMark Johnston  *
560339a1c2SMark Johnston  * This file is not, and will never be, cstyled.  If anything, the tables should
570339a1c2SMark Johnston  * be taken out another tab stop or two so nothing overlaps.
580339a1c2SMark Johnston  */
590339a1c2SMark Johnston 
600339a1c2SMark Johnston /*
610339a1c2SMark Johnston  * These functions must be provided for the consumer to do disassembly.
620339a1c2SMark Johnston  */
630339a1c2SMark Johnston #ifdef DIS_TEXT
640339a1c2SMark Johnston extern char *strncpy(char *, const char *, size_t);
650339a1c2SMark Johnston extern size_t strlen(const char *);
660339a1c2SMark Johnston extern int strcmp(const char *, const char *);
670339a1c2SMark Johnston extern int strncmp(const char *, const char *, size_t);
680339a1c2SMark Johnston extern size_t strlcat(char *, const char *, size_t);
690339a1c2SMark Johnston #endif
700339a1c2SMark Johnston 
710339a1c2SMark Johnston 
720339a1c2SMark Johnston #define		TERM 	0	/* used to indicate that the 'indirect' */
730339a1c2SMark Johnston 				/* field terminates - no pointer.	*/
740339a1c2SMark Johnston 
750339a1c2SMark Johnston /* Used to decode instructions. */
760339a1c2SMark Johnston typedef struct	instable {
770339a1c2SMark Johnston 	struct instable	*it_indirect;	/* for decode op codes */
780339a1c2SMark Johnston 	uchar_t		it_adrmode;
790339a1c2SMark Johnston #ifdef DIS_TEXT
800339a1c2SMark Johnston 	char		it_name[NCPS];
810339a1c2SMark Johnston 	uint_t		it_suffix:1;		/* mnem + "w", "l", or "d" */
820339a1c2SMark Johnston #endif
830339a1c2SMark Johnston #ifdef DIS_MEM
840339a1c2SMark Johnston 	uint_t		it_size:16;
850339a1c2SMark Johnston #endif
860339a1c2SMark Johnston 	uint_t		it_invalid64:1;		/* opcode invalid in amd64 */
870339a1c2SMark Johnston 	uint_t		it_always64:1;		/* 64 bit when in 64 bit mode */
880339a1c2SMark Johnston 	uint_t		it_invalid32:1;		/* invalid in IA32 */
890339a1c2SMark Johnston 	uint_t		it_stackop:1;		/* push/pop stack operation */
900339a1c2SMark Johnston } instable_t;
910339a1c2SMark Johnston 
920339a1c2SMark Johnston /*
930339a1c2SMark Johnston  * Instruction formats.
940339a1c2SMark Johnston  */
950339a1c2SMark Johnston enum {
960339a1c2SMark Johnston 	UNKNOWN,
970339a1c2SMark Johnston 	MRw,
980339a1c2SMark Johnston 	IMlw,
990339a1c2SMark Johnston 	IMw,
1000339a1c2SMark Johnston 	IR,
1010339a1c2SMark Johnston 	OA,
1020339a1c2SMark Johnston 	AO,
1030339a1c2SMark Johnston 	MS,
1040339a1c2SMark Johnston 	SM,
1050339a1c2SMark Johnston 	Mv,
1060339a1c2SMark Johnston 	Mw,
1070339a1c2SMark Johnston 	M,		/* register or memory */
108c3ddb60eSPeter Grehan 	MG9,		/* register or memory in group 9 (prefix optional) */
1090339a1c2SMark Johnston 	Mb,		/* register or memory, always byte sized */
1100339a1c2SMark Johnston 	MO,		/* memory only (no registers) */
1110339a1c2SMark Johnston 	PREF,
112c3ddb60eSPeter Grehan 	SWAPGS_RDTSCP,
1130339a1c2SMark Johnston 	MONITOR_MWAIT,
1140339a1c2SMark Johnston 	R,
1150339a1c2SMark Johnston 	RA,
1160339a1c2SMark Johnston 	SEG,
1170339a1c2SMark Johnston 	MR,
1180339a1c2SMark Johnston 	RM,
119c3ddb60eSPeter Grehan 	RM_66r,		/* RM, but with a required 0x66 prefix */
1200339a1c2SMark Johnston 	IA,
1210339a1c2SMark Johnston 	MA,
1220339a1c2SMark Johnston 	SD,
1230339a1c2SMark Johnston 	AD,
1240339a1c2SMark Johnston 	SA,
1250339a1c2SMark Johnston 	D,
1260339a1c2SMark Johnston 	INM,
1270339a1c2SMark Johnston 	SO,
1280339a1c2SMark Johnston 	BD,
1290339a1c2SMark Johnston 	I,
1300339a1c2SMark Johnston 	P,
1310339a1c2SMark Johnston 	V,
1320339a1c2SMark Johnston 	DSHIFT,		/* for double shift that has an 8-bit immediate */
1330339a1c2SMark Johnston 	U,
1340339a1c2SMark Johnston 	OVERRIDE,
1350339a1c2SMark Johnston 	NORM,		/* instructions w/o ModR/M byte, no memory access */
1360339a1c2SMark Johnston 	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
1370339a1c2SMark Johnston 	O,		/* for call	*/
1380339a1c2SMark Johnston 	JTAB,		/* jump table 	*/
1390339a1c2SMark Johnston 	IMUL,		/* for 186 iimul instr  */
1400339a1c2SMark Johnston 	CBW,		/* so data16 can be evaluated for cbw and variants */
1410339a1c2SMark Johnston 	MvI,		/* for 186 logicals */
1420339a1c2SMark Johnston 	ENTER,		/* for 186 enter instr  */
1430339a1c2SMark Johnston 	RMw,		/* for 286 arpl instr */
1440339a1c2SMark Johnston 	Ib,		/* for push immediate byte */
1450339a1c2SMark Johnston 	F,		/* for 287 instructions */
1460339a1c2SMark Johnston 	FF,		/* for 287 instructions */
1470339a1c2SMark Johnston 	FFC,		/* for 287 instructions */
1480339a1c2SMark Johnston 	DM,		/* 16-bit data */
1490339a1c2SMark Johnston 	AM,		/* 16-bit addr */
1500339a1c2SMark Johnston 	LSEG,		/* for 3-bit seg reg encoding */
1510339a1c2SMark Johnston 	MIb,		/* for 386 logicals */
1520339a1c2SMark Johnston 	SREG,		/* for 386 special registers */
1530339a1c2SMark Johnston 	PREFIX,		/* a REP instruction prefix */
1540339a1c2SMark Johnston 	LOCK,		/* a LOCK instruction prefix */
1550339a1c2SMark Johnston 	INT3,		/* The int 3 instruction, which has a fake operand */
1560339a1c2SMark Johnston 	INTx,		/* The normal int instruction, with explicit int num */
1570339a1c2SMark Johnston 	DSHIFTcl,	/* for double shift that implicitly uses %cl */
1580339a1c2SMark Johnston 	CWD,		/* so data16 can be evaluated for cwd and variants */
1590339a1c2SMark Johnston 	RET,		/* single immediate 16-bit operand */
1600339a1c2SMark Johnston 	MOVZ,		/* for movs and movz, with different size operands */
1610339a1c2SMark Johnston 	CRC32,		/* for crc32, with different size operands */
1620339a1c2SMark Johnston 	XADDB,		/* for xaddb */
1630339a1c2SMark Johnston 	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
1640339a1c2SMark Johnston 	MOVBE,		/* movbe instruction */
1650339a1c2SMark Johnston 
1660339a1c2SMark Johnston /*
1670339a1c2SMark Johnston  * MMX/SIMD addressing modes.
1680339a1c2SMark Johnston  */
1690339a1c2SMark Johnston 
1700339a1c2SMark Johnston 	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
1710339a1c2SMark Johnston 	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
1720339a1c2SMark Johnston 	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
1730339a1c2SMark Johnston 	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
1740339a1c2SMark Johnston 	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
1750339a1c2SMark Johnston 	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
1760339a1c2SMark Johnston 	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
1770339a1c2SMark Johnston 	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
1780339a1c2SMark Johnston 	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
1790339a1c2SMark Johnston 	MMOSH,		/* Prefixable MMX		mm,imm8	*/
1800339a1c2SMark Johnston 	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
1810339a1c2SMark Johnston 	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
1820339a1c2SMark Johnston 	MMSH,		/* MMX				mm,imm8 */
1830339a1c2SMark Johnston 	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
1840339a1c2SMark Johnston 	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
1850339a1c2SMark Johnston 	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
1860339a1c2SMark Johnston 	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
1870339a1c2SMark Johnston 	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
1880339a1c2SMark Johnston 	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
1890339a1c2SMark Johnston 	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
1900339a1c2SMark Johnston 	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
1910339a1c2SMark Johnston 	XMM,		/* SIMD 			xmm/mem	-> xmm */
1920339a1c2SMark Johnston 	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
1930339a1c2SMark Johnston 	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
1940339a1c2SMark Johnston 	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
1950339a1c2SMark Johnston 	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
1960339a1c2SMark Johnston 	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
1970339a1c2SMark Johnston 	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
1980339a1c2SMark Johnston 	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
1990339a1c2SMark Johnston 	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
2000339a1c2SMark Johnston 	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
2010339a1c2SMark Johnston 	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
2020339a1c2SMark Johnston 	XMMS,		/* SIMD				xmm	-> xmm/mem */
2030339a1c2SMark Johnston 	XMMM,		/* SIMD 			mem	-> xmm */
2040339a1c2SMark Johnston 	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
2050339a1c2SMark Johnston 	XMMMS,		/* SIMD				xmm	-> mem */
2060339a1c2SMark Johnston 	XMM3MX,		/* SIMD 			r32/mem -> xmm */
2070339a1c2SMark Johnston 	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
2080339a1c2SMark Johnston 	XMMSH,		/* SIMD 			xmm,imm8 */
2090339a1c2SMark Johnston 	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
2100339a1c2SMark Johnston 	XMMX3,		/* SIMD 			xmm	-> r32 */
2110339a1c2SMark Johnston 	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
2120339a1c2SMark Johnston 	XMMMX,		/* SIMD 			mm	-> xmm */
2130339a1c2SMark Johnston 	XMMXM,		/* SIMD 			xmm	-> mm */
2140339a1c2SMark Johnston         XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
2150339a1c2SMark Johnston         XMM2I,		/* SIMD				xmm, imm, imm */
2160339a1c2SMark Johnston 	XMMFENCE,	/* SIMD lfence or mfence */
2170339a1c2SMark Johnston 	XMMSFNC,	/* SIMD sfence (none or mem) */
2180339a1c2SMark Johnston 	XGETBV_XSETBV,
2190339a1c2SMark Johnston 	VEX_NONE,	/* VEX  no operand */
2200339a1c2SMark Johnston 	VEX_MO,		/* VEX	mod_rm		               -> implicit reg */
2210339a1c2SMark Johnston 	VEX_RMrX,	/* VEX  VEX.vvvv, mod_rm               -> mod_reg */
2220339a1c2SMark Johnston 	VEX_RRX,	/* VEX  VEX.vvvv, mod_reg              -> mod_rm */
2230339a1c2SMark Johnston 	VEX_RMRX,	/* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
2240339a1c2SMark Johnston 	VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
2250339a1c2SMark Johnston 	VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
2260339a1c2SMark Johnston 	VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
2270339a1c2SMark Johnston 	VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
2280339a1c2SMark Johnston 	VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
2290339a1c2SMark Johnston 	VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
2300339a1c2SMark Johnston 	VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
2310339a1c2SMark Johnston 	VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
2320339a1c2SMark Johnston 	VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
2330339a1c2SMark Johnston 	VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
234c3ddb60eSPeter Grehan 	VEX_RMX,        /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
235c3ddb60eSPeter Grehan 	VMx,		/* vmcall/vmlaunch/vmresume/vmxoff */
236c3ddb60eSPeter Grehan 	VMxo,		/* VMx instruction with optional prefix */
237c3ddb60eSPeter Grehan 	SVM		/* AMD SVM instructions */
2380339a1c2SMark Johnston };
2390339a1c2SMark Johnston 
2400339a1c2SMark Johnston /*
2410339a1c2SMark Johnston  * VEX prefixes
2420339a1c2SMark Johnston  */
2430339a1c2SMark Johnston #define VEX_2bytes	0xC5	/* the first byte of two-byte form */
2440339a1c2SMark Johnston #define VEX_3bytes	0xC4	/* the first byte of three-byte form */
2450339a1c2SMark Johnston 
2460339a1c2SMark Johnston #define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
2470339a1c2SMark Johnston 
2480339a1c2SMark Johnston /*
2490339a1c2SMark Johnston ** Register numbers for the i386
2500339a1c2SMark Johnston */
2510339a1c2SMark Johnston #define	EAX_REGNO 0
2520339a1c2SMark Johnston #define	ECX_REGNO 1
2530339a1c2SMark Johnston #define	EDX_REGNO 2
2540339a1c2SMark Johnston #define	EBX_REGNO 3
2550339a1c2SMark Johnston #define	ESP_REGNO 4
2560339a1c2SMark Johnston #define	EBP_REGNO 5
2570339a1c2SMark Johnston #define	ESI_REGNO 6
2580339a1c2SMark Johnston #define	EDI_REGNO 7
2590339a1c2SMark Johnston 
2600339a1c2SMark Johnston /*
2610339a1c2SMark Johnston  * modes for immediate values
2620339a1c2SMark Johnston  */
2630339a1c2SMark Johnston #define	MODE_NONE	0
2640339a1c2SMark Johnston #define	MODE_IPREL	1	/* signed IP relative value */
2650339a1c2SMark Johnston #define	MODE_SIGNED	2	/* sign extended immediate */
2660339a1c2SMark Johnston #define	MODE_IMPLIED	3	/* constant value implied from opcode */
2670339a1c2SMark Johnston #define	MODE_OFFSET	4	/* offset part of an address */
2680339a1c2SMark Johnston #define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
2690339a1c2SMark Johnston 
2700339a1c2SMark Johnston /*
2710339a1c2SMark Johnston  * The letters used in these macros are:
2720339a1c2SMark Johnston  *   IND - indirect to another to another table
2730339a1c2SMark Johnston  *   "T" - means to Terminate indirections (this is the final opcode)
2740339a1c2SMark Johnston  *   "S" - means "operand length suffix required"
2750339a1c2SMark Johnston  *   "NS" - means "no suffix" which is the operand length suffix of the opcode
2760339a1c2SMark Johnston  *   "Z" - means instruction size arg required
2770339a1c2SMark Johnston  *   "u" - means the opcode is invalid in IA32 but valid in amd64
2780339a1c2SMark Johnston  *   "x" - means the opcode is invalid in amd64, but not IA32
2790339a1c2SMark Johnston  *   "y" - means the operand size is always 64 bits in 64 bit mode
2800339a1c2SMark Johnston  *   "p" - means push/pop stack operation
2810339a1c2SMark Johnston  */
2820339a1c2SMark Johnston 
2830339a1c2SMark Johnston #if defined(DIS_TEXT) && defined(DIS_MEM)
2840339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
2850339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
2860339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
2870339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
2880339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
2890339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
2900339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
2910339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
2920339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
2930339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
2940339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
2950339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
2960339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
2970339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
2980339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
2990339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
3000339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3010339a1c2SMark Johnston #elif defined(DIS_TEXT)
3020339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
3030339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
3040339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
3050339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
3060339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
3070339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
3080339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
3090339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
3100339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
3110339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
3120339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
3130339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
3140339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
3150339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
3160339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
3170339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
3180339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3190339a1c2SMark Johnston #elif defined(DIS_MEM)
3200339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
3210339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
3220339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
3230339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
3240339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
3250339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
3260339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
3270339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
3280339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
3290339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
3300339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
3310339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
3320339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
3330339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
3340339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
3350339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
3360339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
3370339a1c2SMark Johnston #else
3380339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
3390339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
3400339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
3410339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
3420339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3430339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
3440339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3450339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
3460339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
3470339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
3480339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3490339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3500339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
3510339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
3520339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
3530339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
3540339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
3550339a1c2SMark Johnston #endif
3560339a1c2SMark Johnston 
3570339a1c2SMark Johnston #ifdef DIS_TEXT
3580339a1c2SMark Johnston /*
3590339a1c2SMark Johnston  * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
3600339a1c2SMark Johnston  */
3610339a1c2SMark Johnston const char *const dis_addr16[3][8] = {
3620339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
3630339a1c2SMark Johnston 									"(%bx)",
3640339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
3650339a1c2SMark Johnston 									"(%bx)",
3660339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
3670339a1c2SMark Johnston 									"(%bx)",
3680339a1c2SMark Johnston };
3690339a1c2SMark Johnston 
3700339a1c2SMark Johnston 
3710339a1c2SMark Johnston /*
3720339a1c2SMark Johnston  * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
3730339a1c2SMark Johnston  */
3740339a1c2SMark Johnston const char *const dis_addr32_mode0[16] = {
3750339a1c2SMark Johnston   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
3760339a1c2SMark Johnston   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
3770339a1c2SMark Johnston };
3780339a1c2SMark Johnston 
3790339a1c2SMark Johnston const char *const dis_addr32_mode12[16] = {
3800339a1c2SMark Johnston   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
3810339a1c2SMark Johnston   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
3820339a1c2SMark Johnston };
3830339a1c2SMark Johnston 
3840339a1c2SMark Johnston /*
3850339a1c2SMark Johnston  * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
3860339a1c2SMark Johnston  */
3870339a1c2SMark Johnston const char *const dis_addr64_mode0[16] = {
3880339a1c2SMark Johnston  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
3890339a1c2SMark Johnston  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
3900339a1c2SMark Johnston };
3910339a1c2SMark Johnston const char *const dis_addr64_mode12[16] = {
3920339a1c2SMark Johnston  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
3930339a1c2SMark Johnston  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
3940339a1c2SMark Johnston };
3950339a1c2SMark Johnston 
3960339a1c2SMark Johnston /*
3970339a1c2SMark Johnston  * decode for scale from SIB byte
3980339a1c2SMark Johnston  */
3990339a1c2SMark Johnston const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
4000339a1c2SMark Johnston 
4010339a1c2SMark Johnston /*
4020339a1c2SMark Johnston  * register decoding for normal references to registers (ie. not addressing)
4030339a1c2SMark Johnston  */
4040339a1c2SMark Johnston const char *const dis_REG8[16] = {
4050339a1c2SMark Johnston 	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
4060339a1c2SMark Johnston 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4070339a1c2SMark Johnston };
4080339a1c2SMark Johnston 
4090339a1c2SMark Johnston const char *const dis_REG8_REX[16] = {
4100339a1c2SMark Johnston 	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
4110339a1c2SMark Johnston 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4120339a1c2SMark Johnston };
4130339a1c2SMark Johnston 
4140339a1c2SMark Johnston const char *const dis_REG16[16] = {
4150339a1c2SMark Johnston 	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
4160339a1c2SMark Johnston 	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
4170339a1c2SMark Johnston };
4180339a1c2SMark Johnston 
4190339a1c2SMark Johnston const char *const dis_REG32[16] = {
4200339a1c2SMark Johnston 	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
4210339a1c2SMark Johnston 	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
4220339a1c2SMark Johnston };
4230339a1c2SMark Johnston 
4240339a1c2SMark Johnston const char *const dis_REG64[16] = {
4250339a1c2SMark Johnston 	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
4260339a1c2SMark Johnston 	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
4270339a1c2SMark Johnston };
4280339a1c2SMark Johnston 
4290339a1c2SMark Johnston const char *const dis_DEBUGREG[16] = {
4300339a1c2SMark Johnston 	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
4310339a1c2SMark Johnston 	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
4320339a1c2SMark Johnston };
4330339a1c2SMark Johnston 
4340339a1c2SMark Johnston const char *const dis_CONTROLREG[16] = {
4350339a1c2SMark Johnston     "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
4360339a1c2SMark Johnston     "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
4370339a1c2SMark Johnston };
4380339a1c2SMark Johnston 
4390339a1c2SMark Johnston const char *const dis_TESTREG[16] = {
4400339a1c2SMark Johnston 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
4410339a1c2SMark Johnston 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
4420339a1c2SMark Johnston };
4430339a1c2SMark Johnston 
4440339a1c2SMark Johnston const char *const dis_MMREG[16] = {
4450339a1c2SMark Johnston 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
4460339a1c2SMark Johnston 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
4470339a1c2SMark Johnston };
4480339a1c2SMark Johnston 
4490339a1c2SMark Johnston const char *const dis_XMMREG[16] = {
4500339a1c2SMark Johnston     "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
4510339a1c2SMark Johnston     "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
4520339a1c2SMark Johnston };
4530339a1c2SMark Johnston 
4540339a1c2SMark Johnston const char *const dis_YMMREG[16] = {
4550339a1c2SMark Johnston     "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
4560339a1c2SMark Johnston     "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
4570339a1c2SMark Johnston };
4580339a1c2SMark Johnston 
4590339a1c2SMark Johnston const char *const dis_SEGREG[16] = {
4600339a1c2SMark Johnston 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
4610339a1c2SMark Johnston 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
4620339a1c2SMark Johnston };
4630339a1c2SMark Johnston 
4640339a1c2SMark Johnston /*
4650339a1c2SMark Johnston  * SIMD predicate suffixes
4660339a1c2SMark Johnston  */
4670339a1c2SMark Johnston const char *const dis_PREDSUFFIX[8] = {
4680339a1c2SMark Johnston 	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
4690339a1c2SMark Johnston };
4700339a1c2SMark Johnston 
4710339a1c2SMark Johnston const char *const dis_AVXvgrp7[3][8] = {
4720339a1c2SMark Johnston 	/*0	1	2		3		4		5	6		7*/
4730339a1c2SMark Johnston /*71*/	{"",	"",	"vpsrlw",	"",		"vpsraw",	"",	"vpsllw",	""},
4740339a1c2SMark Johnston /*72*/	{"",	"",	"vpsrld",	"",		"vpsrad",	"",	"vpslld",	""},
4750339a1c2SMark Johnston /*73*/	{"",	"",	"vpsrlq",	"vpsrldq",	"",		"",	"vpsllq",	"vpslldq"}
4760339a1c2SMark Johnston };
4770339a1c2SMark Johnston 
4780339a1c2SMark Johnston #endif	/* DIS_TEXT */
4790339a1c2SMark Johnston 
4800339a1c2SMark Johnston /*
4810339a1c2SMark Johnston  *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
4820339a1c2SMark Johnston  */
4830339a1c2SMark Johnston const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
4840339a1c2SMark Johnston 
4850339a1c2SMark Johnston /*
4860339a1c2SMark Johnston  *	"decode table" for pause and clflush instructions
4870339a1c2SMark Johnston  */
4880339a1c2SMark Johnston const instable_t dis_opPause = TNS("pause", NORM);
4890339a1c2SMark Johnston 
4900339a1c2SMark Johnston /*
4910339a1c2SMark Johnston  *	Decode table for 0x0F00 opcodes
4920339a1c2SMark Johnston  */
4930339a1c2SMark Johnston const instable_t dis_op0F00[8] = {
4940339a1c2SMark Johnston 
4950339a1c2SMark Johnston /*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
4960339a1c2SMark Johnston /*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
4970339a1c2SMark Johnston };
4980339a1c2SMark Johnston 
4990339a1c2SMark Johnston 
5000339a1c2SMark Johnston /*
5010339a1c2SMark Johnston  *	Decode table for 0x0F01 opcodes
5020339a1c2SMark Johnston  */
5030339a1c2SMark Johnston const instable_t dis_op0F01[8] = {
5040339a1c2SMark Johnston 
505c3ddb60eSPeter Grehan /*  [0]  */	TNSZ("sgdt",VMx,6),	TNSZ("sidt",MONITOR_MWAIT,6),	TNSZ("lgdt",XGETBV_XSETBV,6),	TNSZ("lidt",SVM,6),
506c3ddb60eSPeter Grehan /*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS_RDTSCP),
5070339a1c2SMark Johnston };
5080339a1c2SMark Johnston 
5090339a1c2SMark Johnston /*
5100339a1c2SMark Johnston  *	Decode table for 0x0F18 opcodes -- SIMD prefetch
5110339a1c2SMark Johnston  */
5120339a1c2SMark Johnston const instable_t dis_op0F18[8] = {
5130339a1c2SMark Johnston 
5140339a1c2SMark Johnston /*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
5150339a1c2SMark Johnston /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
5160339a1c2SMark Johnston };
5170339a1c2SMark Johnston 
5180339a1c2SMark Johnston /*
5190339a1c2SMark Johnston  * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
5200339a1c2SMark Johnston  */
5210339a1c2SMark Johnston const instable_t dis_op0FAE[8] = {
5220339a1c2SMark Johnston /*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
5230339a1c2SMark Johnston /*  [4]  */	TNSZ("xsave",M,512),	TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
5240339a1c2SMark Johnston };
5250339a1c2SMark Johnston 
5260339a1c2SMark Johnston /*
5270339a1c2SMark Johnston  *	Decode table for 0x0FBA opcodes
5280339a1c2SMark Johnston  */
5290339a1c2SMark Johnston 
5300339a1c2SMark Johnston const instable_t dis_op0FBA[8] = {
5310339a1c2SMark Johnston 
5320339a1c2SMark Johnston /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
5330339a1c2SMark Johnston /*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
5340339a1c2SMark Johnston };
5350339a1c2SMark Johnston 
5360339a1c2SMark Johnston /*
537c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode (group 9)
5380339a1c2SMark Johnston  */
5390339a1c2SMark Johnston 
5400339a1c2SMark Johnston const instable_t dis_op0FC7[8] = {
5410339a1c2SMark Johnston 
5420339a1c2SMark Johnston /*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
543c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmptrld",MG9),	TNS("vmptrst",MG9),
5440339a1c2SMark Johnston };
5450339a1c2SMark Johnston 
546c3ddb60eSPeter Grehan /*
547c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode (group 9) mode 3
548c3ddb60eSPeter Grehan  */
549c3ddb60eSPeter Grehan 
550c3ddb60eSPeter Grehan const instable_t dis_op0FC7m3[8] = {
551c3ddb60eSPeter Grehan 
552c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,	INVALID,		INVALID,
553c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,	TNS("rdrand",MG9),	INVALID,
554c3ddb60eSPeter Grehan };
555c3ddb60eSPeter Grehan 
556c3ddb60eSPeter Grehan /*
557c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode with 0x66 prefix
558c3ddb60eSPeter Grehan  */
559c3ddb60eSPeter Grehan 
560c3ddb60eSPeter Grehan const instable_t dis_op660FC7[8] = {
561c3ddb60eSPeter Grehan 
562c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
563c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmclear",M),	INVALID,
564c3ddb60eSPeter Grehan };
565c3ddb60eSPeter Grehan 
566c3ddb60eSPeter Grehan /*
567c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode with 0xF3 prefix
568c3ddb60eSPeter Grehan  */
569c3ddb60eSPeter Grehan 
570c3ddb60eSPeter Grehan const instable_t dis_opF30FC7[8] = {
571c3ddb60eSPeter Grehan 
572c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
573c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmxon",M),		INVALID,
574c3ddb60eSPeter Grehan };
5750339a1c2SMark Johnston 
5760339a1c2SMark Johnston /*
5770339a1c2SMark Johnston  *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
5780339a1c2SMark Johnston  *
5790339a1c2SMark Johnston  *bit pattern: 0000 1111 1100 1reg
5800339a1c2SMark Johnston  */
5810339a1c2SMark Johnston const instable_t dis_op0FC8[4] = {
5820339a1c2SMark Johnston /*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
5830339a1c2SMark Johnston };
5840339a1c2SMark Johnston 
5850339a1c2SMark Johnston /*
5860339a1c2SMark Johnston  *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
5870339a1c2SMark Johnston  */
5880339a1c2SMark Johnston const instable_t dis_op0F7123[4][8] = {
5890339a1c2SMark Johnston {
5900339a1c2SMark Johnston /*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
5910339a1c2SMark Johnston /*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
5920339a1c2SMark Johnston }, {
5930339a1c2SMark Johnston /*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
5940339a1c2SMark Johnston /*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
5950339a1c2SMark Johnston }, {
5960339a1c2SMark Johnston /*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
5970339a1c2SMark Johnston /*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
5980339a1c2SMark Johnston }, {
5990339a1c2SMark Johnston /*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
6000339a1c2SMark Johnston /*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
6010339a1c2SMark Johnston } };
6020339a1c2SMark Johnston 
6030339a1c2SMark Johnston /*
6040339a1c2SMark Johnston  *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
6050339a1c2SMark Johnston  */
6060339a1c2SMark Johnston const instable_t dis_opSIMD7123[32] = {
6070339a1c2SMark Johnston /* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
6080339a1c2SMark Johnston /*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
6090339a1c2SMark Johnston 
6100339a1c2SMark Johnston /* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
6110339a1c2SMark Johnston /*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
6120339a1c2SMark Johnston 
6130339a1c2SMark Johnston /* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
6140339a1c2SMark Johnston /*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
6150339a1c2SMark Johnston 
6160339a1c2SMark Johnston /* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
6170339a1c2SMark Johnston /*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
6180339a1c2SMark Johnston };
6190339a1c2SMark Johnston 
6200339a1c2SMark Johnston /*
6210339a1c2SMark Johnston  *	SIMD instructions have been wedged into the existing IA32 instruction
6220339a1c2SMark Johnston  *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
6230339a1c2SMark Johnston  *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
6240339a1c2SMark Johnston  *	instruction - addss.  At present, three prefixes have been coopted in
6250339a1c2SMark Johnston  *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
6260339a1c2SMark Johnston  *	following tables are used to provide the prefixed instruction names.
6270339a1c2SMark Johnston  *	The arrays are sparse, but they're fast.
6280339a1c2SMark Johnston  */
6290339a1c2SMark Johnston 
6300339a1c2SMark Johnston /*
6310339a1c2SMark Johnston  *	Decode table for SIMD instructions with the address size (0x66) prefix.
6320339a1c2SMark Johnston  */
6330339a1c2SMark Johnston const instable_t dis_opSIMDdata16[256] = {
6340339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
6350339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
6360339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
6370339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6380339a1c2SMark Johnston 
6390339a1c2SMark Johnston /*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
6400339a1c2SMark Johnston /*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
6410339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
6420339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6430339a1c2SMark Johnston 
6440339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
6450339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
6460339a1c2SMark Johnston /*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
6470339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
6480339a1c2SMark Johnston 
6490339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
6500339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
6510339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
6520339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6530339a1c2SMark Johnston 
6540339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
6550339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
6560339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
6570339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6580339a1c2SMark Johnston 
6590339a1c2SMark Johnston /*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
6600339a1c2SMark Johnston /*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
6610339a1c2SMark Johnston /*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
6620339a1c2SMark Johnston /*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
6630339a1c2SMark Johnston 
6640339a1c2SMark Johnston /*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
6650339a1c2SMark Johnston /*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
6660339a1c2SMark Johnston /*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
6670339a1c2SMark Johnston /*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
6680339a1c2SMark Johnston 
6690339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
6700339a1c2SMark Johnston /*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
6710339a1c2SMark Johnston /*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
6720339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
6730339a1c2SMark Johnston 
6740339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
6750339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
6760339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
6770339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6780339a1c2SMark Johnston 
6790339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
6800339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
6810339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
6820339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6830339a1c2SMark Johnston 
6840339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
6850339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
6860339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
6870339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
6880339a1c2SMark Johnston 
6890339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
6900339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
6910339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
6920339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
6930339a1c2SMark Johnston 
6940339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
6950339a1c2SMark Johnston /*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
6960339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
6970339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
6980339a1c2SMark Johnston 
6990339a1c2SMark Johnston /*  [D0]  */	INVALID,		TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
7000339a1c2SMark Johnston /*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
7010339a1c2SMark Johnston /*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
7020339a1c2SMark Johnston /*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
7030339a1c2SMark Johnston 
7040339a1c2SMark Johnston /*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
7050339a1c2SMark Johnston /*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
7060339a1c2SMark Johnston /*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
7070339a1c2SMark Johnston /*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
7080339a1c2SMark Johnston 
7090339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
7100339a1c2SMark Johnston /*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
7110339a1c2SMark Johnston /*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
7120339a1c2SMark Johnston /*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
7130339a1c2SMark Johnston };
7140339a1c2SMark Johnston 
7150339a1c2SMark Johnston const instable_t dis_opAVX660F[256] = {
7160339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
7170339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
7180339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
7190339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7200339a1c2SMark Johnston 
7210339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovupd",VEX_MX,16),	TNSZ("vmovupd",VEX_RX,16),	TNSZ("vmovlpd",VEX_RMrX,8),	TNSZ("vmovlpd",VEX_RM,8),
7220339a1c2SMark Johnston /*  [14]  */	TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8),	TNSZ("vmovhpd",VEX_RM,8),
7230339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
7240339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7250339a1c2SMark Johnston 
7260339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
7270339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
7280339a1c2SMark Johnston /*  [28]  */	TNSZ("vmovapd",VEX_MX,16),	TNSZ("vmovapd",VEX_RX,16),	INVALID,		TNSZ("vmovntpd",VEX_RM,16),
7290339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
7300339a1c2SMark Johnston 
7310339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
7320339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
7330339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
7340339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7350339a1c2SMark Johnston 
7360339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
7370339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
7380339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
7390339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7400339a1c2SMark Johnston 
7410339a1c2SMark Johnston /*  [50]  */	TNS("vmovmskpd",VEX_MR),	TNSZ("vsqrtpd",VEX_MX,16),	INVALID,		INVALID,
7420339a1c2SMark Johnston /*  [54]  */	TNSZ("vandpd",VEX_RMrX,16),	TNSZ("vandnpd",VEX_RMrX,16),	TNSZ("vorpd",VEX_RMrX,16),	TNSZ("vxorpd",VEX_RMrX,16),
7430339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddpd",VEX_RMrX,16),	TNSZ("vmulpd",VEX_RMrX,16),	TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
7440339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubpd",VEX_RMrX,16),	TNSZ("vminpd",VEX_RMrX,16),	TNSZ("vdivpd",VEX_RMrX,16),	TNSZ("vmaxpd",VEX_RMrX,16),
7450339a1c2SMark Johnston 
7460339a1c2SMark Johnston /*  [60]  */	TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
7470339a1c2SMark Johnston /*  [64]  */	TNSZ("vpcmpgtb",VEX_RMrX,16),	TNSZ("vpcmpgtw",VEX_RMrX,16),	TNSZ("vpcmpgtd",VEX_RMrX,16),	TNSZ("vpackuswb",VEX_RMrX,16),
7480339a1c2SMark Johnston /*  [68]  */	TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
7490339a1c2SMark Johnston /*  [6C]  */	TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
7500339a1c2SMark Johnston 
7510339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshufd",VEX_MXI,16),	TNSZ("vgrp71",VEX_XXI,16),	TNSZ("vgrp72",VEX_XXI,16),		TNSZ("vgrp73",VEX_XXI,16),
7520339a1c2SMark Johnston /*  [74]  */	TNSZ("vpcmpeqb",VEX_RMrX,16),	TNSZ("vpcmpeqw",VEX_RMrX,16),	TNSZ("vpcmpeqd",VEX_RMrX,16),	INVALID,
7530339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
7540339a1c2SMark Johnston /*  [7C]  */	TNSZ("vhaddpd",VEX_RMrX,16),	TNSZ("vhsubpd",VEX_RMrX,16),	TNSZ("vmovd",VEX_RR,4),	TNSZ("vmovdqa",VEX_RX,16),
7550339a1c2SMark Johnston 
7560339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
7570339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
7580339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
7590339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7600339a1c2SMark Johnston 
7610339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
7620339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
7630339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
7640339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7650339a1c2SMark Johnston 
7660339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7670339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7680339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7690339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7700339a1c2SMark Johnston 
7710339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7720339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7730339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7740339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7750339a1c2SMark Johnston 
7760339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmppd",VEX_RMRX,16),	INVALID,
7770339a1c2SMark Johnston /*  [C4]  */	TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),	TNSZ("vshufpd",VEX_RMRX,16),	INVALID,
7780339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7790339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7800339a1c2SMark Johnston 
7810339a1c2SMark Johnston /*  [D0]  */	TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),	TNSZ("vpsrld",VEX_RMrX,16),	TNSZ("vpsrlq",VEX_RMrX,16),
7820339a1c2SMark Johnston /*  [D4]  */	TNSZ("vpaddq",VEX_RMrX,16),	TNSZ("vpmullw",VEX_RMrX,16),	TNSZ("vmovq",VEX_RX,8),	TNS("vpmovmskb",VEX_MR),
7830339a1c2SMark Johnston /*  [D8]  */	TNSZ("vpsubusb",VEX_RMrX,16),	TNSZ("vpsubusw",VEX_RMrX,16),	TNSZ("vpminub",VEX_RMrX,16),	TNSZ("vpand",VEX_RMrX,16),
7840339a1c2SMark Johnston /*  [DC]  */	TNSZ("vpaddusb",VEX_RMrX,16),	TNSZ("vpaddusw",VEX_RMrX,16),	TNSZ("vpmaxub",VEX_RMrX,16),	TNSZ("vpandn",VEX_RMrX,16),
7850339a1c2SMark Johnston 
7860339a1c2SMark Johnston /*  [E0]  */	TNSZ("vpavgb",VEX_RMrX,16),	TNSZ("vpsraw",VEX_RMrX,16),	TNSZ("vpsrad",VEX_RMrX,16),	TNSZ("vpavgw",VEX_RMrX,16),
7870339a1c2SMark Johnston /*  [E4]  */	TNSZ("vpmulhuw",VEX_RMrX,16),	TNSZ("vpmulhw",VEX_RMrX,16),	TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
7880339a1c2SMark Johnston /*  [E8]  */	TNSZ("vpsubsb",VEX_RMrX,16),	TNSZ("vpsubsw",VEX_RMrX,16),	TNSZ("vpminsw",VEX_RMrX,16),	TNSZ("vpor",VEX_RMrX,16),
7890339a1c2SMark Johnston /*  [EC]  */	TNSZ("vpaddsb",VEX_RMrX,16),	TNSZ("vpaddsw",VEX_RMrX,16),	TNSZ("vpmaxsw",VEX_RMrX,16),	TNSZ("vpxor",VEX_RMrX,16),
7900339a1c2SMark Johnston 
7910339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("vpsllw",VEX_RMrX,16),	TNSZ("vpslld",VEX_RMrX,16),	TNSZ("vpsllq",VEX_RMrX,16),
7920339a1c2SMark Johnston /*  [F4]  */	TNSZ("vpmuludq",VEX_RMrX,16),	TNSZ("vpmaddwd",VEX_RMrX,16),	TNSZ("vpsadbw",VEX_RMrX,16),	TNS("vmaskmovdqu",VEX_MX),
7930339a1c2SMark Johnston /*  [F8]  */	TNSZ("vpsubb",VEX_RMrX,16),	TNSZ("vpsubw",VEX_RMrX,16),	TNSZ("vpsubd",VEX_RMrX,16),	TNSZ("vpsubq",VEX_RMrX,16),
7940339a1c2SMark Johnston /*  [FC]  */	TNSZ("vpaddb",VEX_RMrX,16),	TNSZ("vpaddw",VEX_RMrX,16),	TNSZ("vpaddd",VEX_RMrX,16),	INVALID,
7950339a1c2SMark Johnston };
7960339a1c2SMark Johnston 
7970339a1c2SMark Johnston /*
7980339a1c2SMark Johnston  *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
7990339a1c2SMark Johnston  */
8000339a1c2SMark Johnston const instable_t dis_opSIMDrepnz[256] = {
8010339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
8020339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
8030339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
8040339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8050339a1c2SMark Johnston 
8060339a1c2SMark Johnston /*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	INVALID,		INVALID,
8070339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
8080339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
8090339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8100339a1c2SMark Johnston 
8110339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
8120339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
8130339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
8140339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
8150339a1c2SMark Johnston 
8160339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
8170339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
8180339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
8190339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8200339a1c2SMark Johnston 
8210339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
8220339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
8230339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
8240339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8250339a1c2SMark Johnston 
8260339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
8270339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
8280339a1c2SMark Johnston /*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
8290339a1c2SMark Johnston /*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
8300339a1c2SMark Johnston 
8310339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
8320339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
8330339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
8340339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8350339a1c2SMark Johnston 
8360339a1c2SMark Johnston /*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
8370339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
8380339a1c2SMark Johnston /*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
8390339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8400339a1c2SMark Johnston 
8410339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
8420339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
8430339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
8440339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8450339a1c2SMark Johnston 
8460339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
8470339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
8480339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
8490339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8500339a1c2SMark Johnston 
8510339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8520339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8530339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8540339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8550339a1c2SMark Johnston 
8560339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8570339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8580339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8590339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8600339a1c2SMark Johnston 
8610339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
8620339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8630339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8640339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8650339a1c2SMark Johnston 
8660339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8670339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
8680339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8690339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8700339a1c2SMark Johnston 
8710339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8720339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
8730339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8740339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8750339a1c2SMark Johnston 
8760339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8770339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8780339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8790339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8800339a1c2SMark Johnston };
8810339a1c2SMark Johnston 
8820339a1c2SMark Johnston const instable_t dis_opAVXF20F[256] = {
8830339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
8840339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
8850339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
8860339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8870339a1c2SMark Johnston 
8880339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovsd",VEX_RMrX,8),	TNSZ("vmovsd",VEX_RRX,8),	TNSZ("vmovddup",VEX_MX,8),	INVALID,
8890339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
8900339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
8910339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8920339a1c2SMark Johnston 
8930339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
8940339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
8950339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
8960339a1c2SMark Johnston /*  [2C]  */	TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,		INVALID,
8970339a1c2SMark Johnston 
8980339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
8990339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
9000339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
9010339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9020339a1c2SMark Johnston 
9030339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
9040339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
9050339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
9060339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9070339a1c2SMark Johnston 
9080339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("vsqrtsd",VEX_RMrX,8),	INVALID,		INVALID,
9090339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
9100339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddsd",VEX_RMrX,8),	TNSZ("vmulsd",VEX_RMrX,8),	TNSZ("vcvtsd2ss",VEX_RMrX,8),	INVALID,
9110339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubsd",VEX_RMrX,8),	TNSZ("vminsd",VEX_RMrX,8),	TNSZ("vdivsd",VEX_RMrX,8),	TNSZ("vmaxsd",VEX_RMrX,8),
9120339a1c2SMark Johnston 
9130339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
9140339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
9150339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
9160339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9170339a1c2SMark Johnston 
9180339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshuflw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
9190339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
9200339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
9210339a1c2SMark Johnston /*  [7C]  */	TNSZ("vhaddps",VEX_RMrX,8),	TNSZ("vhsubps",VEX_RMrX,8),	INVALID,		INVALID,
9220339a1c2SMark Johnston 
9230339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
9240339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
9250339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
9260339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9270339a1c2SMark Johnston 
9280339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
9290339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
9300339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
9310339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9320339a1c2SMark Johnston 
9330339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9340339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9350339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9360339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9370339a1c2SMark Johnston 
9380339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9390339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9400339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9410339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9420339a1c2SMark Johnston 
9430339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpsd",VEX_RMRX,8),	INVALID,
9440339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9450339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9460339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9470339a1c2SMark Johnston 
9480339a1c2SMark Johnston /*  [D0]  */	TNSZ("vaddsubps",VEX_RMrX,8),	INVALID,		INVALID,		INVALID,
9490339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9500339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9510339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9520339a1c2SMark Johnston 
9530339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9540339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
9550339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9560339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9570339a1c2SMark Johnston 
9580339a1c2SMark Johnston /*  [F0]  */	TNSZ("vlddqu",VEX_MX,16),	INVALID,		INVALID,		INVALID,
9590339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9600339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9610339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9620339a1c2SMark Johnston };
9630339a1c2SMark Johnston 
9640339a1c2SMark Johnston /*
9650339a1c2SMark Johnston  *	Decode table for SIMD instructions with the repz (0xf3) prefix.
9660339a1c2SMark Johnston  */
9670339a1c2SMark Johnston const instable_t dis_opSIMDrepz[256] = {
9680339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
9690339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
9700339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
9710339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9720339a1c2SMark Johnston 
9730339a1c2SMark Johnston /*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	INVALID,		INVALID,
9740339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
9750339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
9760339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9770339a1c2SMark Johnston 
9780339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
9790339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
9800339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
9810339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
9820339a1c2SMark Johnston 
9830339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
9840339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
9850339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
9860339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9870339a1c2SMark Johnston 
9880339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
9890339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
9900339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
9910339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9920339a1c2SMark Johnston 
9930339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
9940339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
9950339a1c2SMark Johnston /*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
9960339a1c2SMark Johnston /*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
9970339a1c2SMark Johnston 
9980339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
9990339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
10000339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
10010339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
10020339a1c2SMark Johnston 
10030339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
10040339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
10050339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
10060339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
10070339a1c2SMark Johnston 
10080339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
10090339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
10100339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
10110339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10120339a1c2SMark Johnston 
10130339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
10140339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
10150339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
10160339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10170339a1c2SMark Johnston 
10180339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
10190339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
10200339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
10210339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
10220339a1c2SMark Johnston 
10230339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
10240339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
10250339a1c2SMark Johnston /*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
10260339a1c2SMark Johnston /*  [BC]  */	INVALID,		TS("lzcnt",MRw),	INVALID,		INVALID,
10270339a1c2SMark Johnston 
10280339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
10290339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
10300339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
10310339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
10320339a1c2SMark Johnston 
10330339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
10340339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
10350339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
10360339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
10370339a1c2SMark Johnston 
10380339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
10390339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
10400339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
10410339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
10420339a1c2SMark Johnston 
10430339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
10440339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
10450339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
10460339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
10470339a1c2SMark Johnston };
10480339a1c2SMark Johnston 
10490339a1c2SMark Johnston const instable_t dis_opAVXF30F[256] = {
10500339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
10510339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
10520339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
10530339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10540339a1c2SMark Johnston 
10550339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovss",VEX_RMrX,4),	TNSZ("vmovss",VEX_RRX,4),	TNSZ("vmovsldup",VEX_MX,4),	INVALID,
10560339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		TNSZ("vmovshdup",VEX_MX,4),	INVALID,
10570339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
10580339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10590339a1c2SMark Johnston 
10600339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
10610339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
10620339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
10630339a1c2SMark Johnston /*  [2C]  */	TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,		INVALID,
10640339a1c2SMark Johnston 
10650339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
10660339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
10670339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
10680339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10690339a1c2SMark Johnston 
10700339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
10710339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
10720339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
10730339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10740339a1c2SMark Johnston 
10750339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("vsqrtss",VEX_RMrX,4),	TNSZ("vrsqrtss",VEX_RMrX,4),	TNSZ("vrcpss",VEX_RMrX,4),
10760339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
10770339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddss",VEX_RMrX,4),	TNSZ("vmulss",VEX_RMrX,4),	TNSZ("vcvtss2sd",VEX_RMrX,4),	TNSZ("vcvttps2dq",VEX_MX,16),
10780339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubss",VEX_RMrX,4),	TNSZ("vminss",VEX_RMrX,4),	TNSZ("vdivss",VEX_RMrX,4),	TNSZ("vmaxss",VEX_RMrX,4),
10790339a1c2SMark Johnston 
10800339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
10810339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
10820339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
10830339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("vmovdqu",VEX_MX,16),
10840339a1c2SMark Johnston 
10850339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshufhw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
10860339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
10870339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
10880339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("vmovq",VEX_MX,8),	TNSZ("vmovdqu",VEX_RX,16),
10890339a1c2SMark Johnston 
10900339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
10910339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
10920339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
10930339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10940339a1c2SMark Johnston 
10950339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
10960339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
10970339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
10980339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
10990339a1c2SMark Johnston 
11000339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11010339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11020339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11030339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11040339a1c2SMark Johnston 
11050339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11060339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11070339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11080339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11090339a1c2SMark Johnston 
11100339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpss",VEX_RMRX,4),	INVALID,
11110339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11120339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11130339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11140339a1c2SMark Johnston 
11150339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11160339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11170339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11180339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11190339a1c2SMark Johnston 
11200339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11210339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtdq2pd",VEX_MX,8),	INVALID,
11220339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11230339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11240339a1c2SMark Johnston 
11250339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11260339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11270339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11280339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11290339a1c2SMark Johnston };
11300339a1c2SMark Johnston /*
11310339a1c2SMark Johnston  * The following two tables are used to encode crc32 and movbe
11320339a1c2SMark Johnston  * since they share the same opcodes.
11330339a1c2SMark Johnston  */
11340339a1c2SMark Johnston const instable_t dis_op0F38F0[2] = {
11350339a1c2SMark Johnston /*  [00]  */	TNS("crc32b",CRC32),
11360339a1c2SMark Johnston 		TS("movbe",MOVBE),
11370339a1c2SMark Johnston };
11380339a1c2SMark Johnston 
11390339a1c2SMark Johnston const instable_t dis_op0F38F1[2] = {
11400339a1c2SMark Johnston /*  [00]  */	TS("crc32",CRC32),
11410339a1c2SMark Johnston 		TS("movbe",MOVBE),
11420339a1c2SMark Johnston };
11430339a1c2SMark Johnston 
11440339a1c2SMark Johnston const instable_t dis_op0F38[256] = {
11450339a1c2SMark Johnston /*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
11460339a1c2SMark Johnston /*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
11470339a1c2SMark Johnston /*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
11480339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11490339a1c2SMark Johnston 
11500339a1c2SMark Johnston /*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
11510339a1c2SMark Johnston /*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
11520339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
11530339a1c2SMark Johnston /*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
11540339a1c2SMark Johnston 
11550339a1c2SMark Johnston /*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
11560339a1c2SMark Johnston /*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
11570339a1c2SMark Johnston /*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
11580339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11590339a1c2SMark Johnston 
11600339a1c2SMark Johnston /*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
11610339a1c2SMark Johnston /*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
11620339a1c2SMark Johnston /*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
11630339a1c2SMark Johnston /*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
11640339a1c2SMark Johnston 
11650339a1c2SMark Johnston /*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
11660339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
11670339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
11680339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11690339a1c2SMark Johnston 
11700339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
11710339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
11720339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
11730339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11740339a1c2SMark Johnston 
11750339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
11760339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
11770339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
11780339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11790339a1c2SMark Johnston 
11800339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
11810339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
11820339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
11830339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11840339a1c2SMark Johnston 
1185c3ddb60eSPeter Grehan /*  [80]  */	TNSy("invept", RM_66r),	TNSy("invvpid", RM_66r),INVALID,		INVALID,
11860339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
11870339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
11880339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11890339a1c2SMark Johnston 
11900339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
11910339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
11920339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
11930339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
11940339a1c2SMark Johnston 
11950339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
11960339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
11970339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
11980339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
11990339a1c2SMark Johnston 
12000339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12010339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12020339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12030339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12040339a1c2SMark Johnston 
12050339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12060339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12070339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12080339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12090339a1c2SMark Johnston 
12100339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12110339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12120339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
12130339a1c2SMark Johnston /*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
12140339a1c2SMark Johnston 
12150339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12160339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12170339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12180339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12190339a1c2SMark Johnston /*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
12200339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12210339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12220339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12230339a1c2SMark Johnston };
12240339a1c2SMark Johnston 
12250339a1c2SMark Johnston const instable_t dis_opAVX660F38[256] = {
12260339a1c2SMark Johnston /*  [00]  */	TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
12270339a1c2SMark Johnston /*  [04]  */	TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),	TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
12280339a1c2SMark Johnston /*  [08]  */	TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
12290339a1c2SMark Johnston /*  [0C]  */	TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),	TNSZ("vtestpd",VEX_RRI,16),
12300339a1c2SMark Johnston 
1231c3ddb60eSPeter Grehan /*  [10]  */	INVALID,		INVALID,		INVALID,		TNSZ("vcvtph2ps",VEX_MX,16),
12320339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		TNSZ("vptest",VEX_RRI,16),
12330339a1c2SMark Johnston /*  [18]  */	TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
12340339a1c2SMark Johnston /*  [1C]  */	TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
12350339a1c2SMark Johnston 
12360339a1c2SMark Johnston /*  [20]  */	TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
12370339a1c2SMark Johnston /*  [24]  */	TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,	INVALID,
12380339a1c2SMark Johnston /*  [28]  */	TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
12390339a1c2SMark Johnston /*  [2C]  */	TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
12400339a1c2SMark Johnston 
12410339a1c2SMark Johnston /*  [30]  */	TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
12420339a1c2SMark Johnston /*  [34]  */	TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),INVALID,	TNSZ("vpcmpgtq",VEX_RMrX,16),
12430339a1c2SMark Johnston /*  [38]  */	TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
12440339a1c2SMark Johnston /*  [3C]  */	TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
12450339a1c2SMark Johnston 
12460339a1c2SMark Johnston /*  [40]  */	TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,	INVALID,
12470339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
12480339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
12490339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12500339a1c2SMark Johnston 
12510339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
12520339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
12530339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
12540339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12550339a1c2SMark Johnston 
12560339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
12570339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
12580339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
12590339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12600339a1c2SMark Johnston 
12610339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
12620339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
12630339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
12640339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12650339a1c2SMark Johnston 
12660339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
12670339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
12680339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
12690339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12700339a1c2SMark Johnston 
12710339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
12720339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
12730339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
12740339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12750339a1c2SMark Johnston 
12760339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12770339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12780339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12790339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12800339a1c2SMark Johnston 
12810339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12820339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12830339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12840339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12850339a1c2SMark Johnston 
12860339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12870339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12880339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12890339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12900339a1c2SMark Johnston 
12910339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12920339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12930339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaesimc",VEX_MX,16),
12940339a1c2SMark Johnston /*  [DC]  */	TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
12950339a1c2SMark Johnston 
12960339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12970339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12980339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12990339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13000339a1c2SMark Johnston /*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
13010339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13020339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13030339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13040339a1c2SMark Johnston };
13050339a1c2SMark Johnston 
13060339a1c2SMark Johnston const instable_t dis_op0F3A[256] = {
13070339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
13080339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
13090339a1c2SMark Johnston /*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
13100339a1c2SMark Johnston /*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
13110339a1c2SMark Johnston 
13120339a1c2SMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
13130339a1c2SMark Johnston /*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
13140339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
13150339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13160339a1c2SMark Johnston 
13170339a1c2SMark Johnston /*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
13180339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
13190339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
13200339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13210339a1c2SMark Johnston 
13220339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
13230339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
13240339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
13250339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13260339a1c2SMark Johnston 
13270339a1c2SMark Johnston /*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
13280339a1c2SMark Johnston /*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
13290339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
13300339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13310339a1c2SMark Johnston 
13320339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
13330339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
13340339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
13350339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13360339a1c2SMark Johnston 
13370339a1c2SMark Johnston /*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
13380339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
13390339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
13400339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13410339a1c2SMark Johnston 
13420339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
13430339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
13440339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
13450339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13460339a1c2SMark Johnston 
13470339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
13480339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
13490339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
13500339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13510339a1c2SMark Johnston 
13520339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
13530339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
13540339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
13550339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13560339a1c2SMark Johnston 
13570339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13580339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13590339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13600339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13610339a1c2SMark Johnston 
13620339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13630339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13640339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13650339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13660339a1c2SMark Johnston 
13670339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13680339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13690339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13700339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13710339a1c2SMark Johnston 
13720339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13730339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13740339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13750339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
13760339a1c2SMark Johnston 
13770339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13780339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13790339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13800339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13810339a1c2SMark Johnston 
13820339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13830339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13840339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13850339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13860339a1c2SMark Johnston };
13870339a1c2SMark Johnston 
13880339a1c2SMark Johnston const instable_t dis_opAVX660F3A[256] = {
13890339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
13900339a1c2SMark Johnston /*  [04]  */	TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
13910339a1c2SMark Johnston /*  [08]  */	TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
13920339a1c2SMark Johnston /*  [0C]  */	TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
13930339a1c2SMark Johnston 
13940339a1c2SMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
13950339a1c2SMark Johnston /*  [14]  */	TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
13960339a1c2SMark Johnston /*  [18]  */	TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,		INVALID,
1397c3ddb60eSPeter Grehan /*  [1C]  */	INVALID,		TNSZ("vcvtps2ph",VEX_RX,16),		INVALID,		INVALID,
13980339a1c2SMark Johnston 
13990339a1c2SMark Johnston /*  [20]  */	TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
14000339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
14010339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
14020339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14030339a1c2SMark Johnston 
14040339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
14050339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
14060339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
14070339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14080339a1c2SMark Johnston 
14090339a1c2SMark Johnston /*  [40]  */	TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
14100339a1c2SMark Johnston /*  [44]  */	TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
14110339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		TNSZ("vblendvps",VEX_RMRX,8),	TNSZ("vblendvpd",VEX_RMRX,16),
14120339a1c2SMark Johnston /*  [4C]  */	TNSZ("vpblendvb",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
14130339a1c2SMark Johnston 
14140339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
14150339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
14160339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
14170339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14180339a1c2SMark Johnston 
14190339a1c2SMark Johnston /*  [60]  */	TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
14200339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
14210339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
14220339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14230339a1c2SMark Johnston 
14240339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
14250339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
14260339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
14270339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14280339a1c2SMark Johnston 
14290339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
14300339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
14310339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
14320339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14330339a1c2SMark Johnston 
14340339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
14350339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
14360339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
14370339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14380339a1c2SMark Johnston 
14390339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14400339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14410339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14420339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14430339a1c2SMark Johnston 
14440339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14450339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14460339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14470339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14480339a1c2SMark Johnston 
14490339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14500339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14510339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14520339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14530339a1c2SMark Johnston 
14540339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14550339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14560339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14570339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaeskeygenassist",VEX_MXI,16),
14580339a1c2SMark Johnston 
14590339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14600339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14610339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14620339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14630339a1c2SMark Johnston 
14640339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14650339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14660339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14670339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14680339a1c2SMark Johnston };
14690339a1c2SMark Johnston 
14700339a1c2SMark Johnston /*
14710339a1c2SMark Johnston  *	Decode table for 0x0F opcodes
14720339a1c2SMark Johnston  */
14730339a1c2SMark Johnston 
14740339a1c2SMark Johnston const instable_t dis_op0F[16][16] = {
14750339a1c2SMark Johnston {
14760339a1c2SMark Johnston /*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
14770339a1c2SMark Johnston /*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
14780339a1c2SMark Johnston /*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
14790339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14800339a1c2SMark Johnston }, {
14810339a1c2SMark Johnston /*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
14820339a1c2SMark Johnston /*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
14830339a1c2SMark Johnston /*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
1484c3ddb60eSPeter Grehan /*  [1C]  */	INVALID,		INVALID,		INVALID,		TS("nop",Mw),
14850339a1c2SMark Johnston }, {
14860339a1c2SMark Johnston /*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
14870339a1c2SMark Johnston /*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
14880339a1c2SMark Johnston /*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
14890339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
14900339a1c2SMark Johnston }, {
14910339a1c2SMark Johnston /*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
14920339a1c2SMark Johnston /*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
14930339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
14940339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14950339a1c2SMark Johnston }, {
14960339a1c2SMark Johnston /*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
14970339a1c2SMark Johnston /*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
14980339a1c2SMark Johnston /*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
14990339a1c2SMark Johnston /*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
15000339a1c2SMark Johnston }, {
15010339a1c2SMark Johnston /*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
15020339a1c2SMark Johnston /*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
15030339a1c2SMark Johnston /*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
15040339a1c2SMark Johnston /*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
15050339a1c2SMark Johnston }, {
15060339a1c2SMark Johnston /*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
15070339a1c2SMark Johnston /*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
15080339a1c2SMark Johnston /*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
15090339a1c2SMark Johnston /*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
15100339a1c2SMark Johnston }, {
15110339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
15120339a1c2SMark Johnston /*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
1513c3ddb60eSPeter Grehan /*  [78]  */	TNSy("vmread",RM),	TNSy("vmwrite",MR),	INVALID,		INVALID,
15140339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
15150339a1c2SMark Johnston }, {
15160339a1c2SMark Johnston /*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
15170339a1c2SMark Johnston /*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
15180339a1c2SMark Johnston /*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
15190339a1c2SMark Johnston /*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
15200339a1c2SMark Johnston }, {
15210339a1c2SMark Johnston /*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
15220339a1c2SMark Johnston /*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
15230339a1c2SMark Johnston /*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
15240339a1c2SMark Johnston /*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
15250339a1c2SMark Johnston }, {
15260339a1c2SMark Johnston /*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
15270339a1c2SMark Johnston /*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
15280339a1c2SMark Johnston /*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
15290339a1c2SMark Johnston /*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
15300339a1c2SMark Johnston }, {
15310339a1c2SMark Johnston /*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
15320339a1c2SMark Johnston /*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
15330339a1c2SMark Johnston /*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
15340339a1c2SMark Johnston /*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
15350339a1c2SMark Johnston }, {
15360339a1c2SMark Johnston /*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
15370339a1c2SMark Johnston /*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
15380339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
15390339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
15400339a1c2SMark Johnston }, {
15410339a1c2SMark Johnston /*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
15420339a1c2SMark Johnston /*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
15430339a1c2SMark Johnston /*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
15440339a1c2SMark Johnston /*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
15450339a1c2SMark Johnston }, {
15460339a1c2SMark Johnston /*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
15470339a1c2SMark Johnston /*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
15480339a1c2SMark Johnston /*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
15490339a1c2SMark Johnston /*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
15500339a1c2SMark Johnston }, {
15510339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
15520339a1c2SMark Johnston /*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
15530339a1c2SMark Johnston /*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
15540339a1c2SMark Johnston /*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
15550339a1c2SMark Johnston } };
15560339a1c2SMark Johnston 
15570339a1c2SMark Johnston const instable_t dis_opAVX0F[16][16] = {
15580339a1c2SMark Johnston {
15590339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
15600339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
15610339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
15620339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15630339a1c2SMark Johnston }, {
15640339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovups",VEX_MX,16),	TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),	TNSZ("vmovlps",VEX_RM,8),
15650339a1c2SMark Johnston /*  [14]  */	TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
15660339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
15670339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15680339a1c2SMark Johnston }, {
15690339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
15700339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
15710339a1c2SMark Johnston /*  [28]  */	TNSZ("vmovaps",VEX_MX,16),	TNSZ("vmovaps",VEX_RX,16),INVALID,		TNSZ("vmovntps",VEX_RM,16),
15720339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
15730339a1c2SMark Johnston }, {
15740339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
15750339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
15760339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
15770339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15780339a1c2SMark Johnston }, {
15790339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
15800339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
15810339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
15820339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15830339a1c2SMark Johnston }, {
15840339a1c2SMark Johnston /*  [50]  */	TNS("vmovmskps",VEX_MR),	TNSZ("vsqrtps",VEX_MX,16),	TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
15850339a1c2SMark Johnston /*  [54]  */	TNSZ("vandps",VEX_RMrX,16),	TNSZ("vandnps",VEX_RMrX,16),	TNSZ("vorps",VEX_RMrX,16),	TNSZ("vxorps",VEX_RMrX,16),
15860339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddps",VEX_RMrX,16),	TNSZ("vmulps",VEX_RMrX,16),	TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
15870339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubps",VEX_RMrX,16),	TNSZ("vminps",VEX_RMrX,16),	TNSZ("vdivps",VEX_RMrX,16),	TNSZ("vmaxps",VEX_RMrX,16),
15880339a1c2SMark Johnston }, {
15890339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
15900339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
15910339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
15920339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15930339a1c2SMark Johnston }, {
15940339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
15950339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		TNS("vzeroupper", VEX_NONE),
15960339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
15970339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15980339a1c2SMark Johnston }, {
15990339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
16000339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
16010339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
16020339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16030339a1c2SMark Johnston }, {
16040339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
16050339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
16060339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
16070339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16080339a1c2SMark Johnston }, {
16090339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16100339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16110339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16120339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		TNSZ("vldmxcsr",VEX_MO,2),		INVALID,
16130339a1c2SMark Johnston }, {
16140339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16150339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16160339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16170339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16180339a1c2SMark Johnston }, {
16190339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpps",VEX_RMRX,16),INVALID,
16200339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,	 	TNSZ("vshufps",VEX_RMRX,16),INVALID,
16210339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16220339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16230339a1c2SMark Johnston }, {
16240339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16250339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16260339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16270339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16280339a1c2SMark Johnston }, {
16290339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16300339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16310339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16320339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16330339a1c2SMark Johnston }, {
16340339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16350339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16360339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16370339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16380339a1c2SMark Johnston } };
16390339a1c2SMark Johnston 
16400339a1c2SMark Johnston /*
16410339a1c2SMark Johnston  *	Decode table for 0x80 opcodes
16420339a1c2SMark Johnston  */
16430339a1c2SMark Johnston 
16440339a1c2SMark Johnston const instable_t dis_op80[8] = {
16450339a1c2SMark Johnston 
16460339a1c2SMark Johnston /*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
16470339a1c2SMark Johnston /*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
16480339a1c2SMark Johnston };
16490339a1c2SMark Johnston 
16500339a1c2SMark Johnston 
16510339a1c2SMark Johnston /*
16520339a1c2SMark Johnston  *	Decode table for 0x81 opcodes.
16530339a1c2SMark Johnston  */
16540339a1c2SMark Johnston 
16550339a1c2SMark Johnston const instable_t dis_op81[8] = {
16560339a1c2SMark Johnston 
16570339a1c2SMark Johnston /*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
16580339a1c2SMark Johnston /*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
16590339a1c2SMark Johnston };
16600339a1c2SMark Johnston 
16610339a1c2SMark Johnston 
16620339a1c2SMark Johnston /*
16630339a1c2SMark Johnston  *	Decode table for 0x82 opcodes.
16640339a1c2SMark Johnston  */
16650339a1c2SMark Johnston 
16660339a1c2SMark Johnston const instable_t dis_op82[8] = {
16670339a1c2SMark Johnston 
16680339a1c2SMark Johnston /*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
16690339a1c2SMark Johnston /*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
16700339a1c2SMark Johnston };
16710339a1c2SMark Johnston /*
16720339a1c2SMark Johnston  *	Decode table for 0x83 opcodes.
16730339a1c2SMark Johnston  */
16740339a1c2SMark Johnston 
16750339a1c2SMark Johnston const instable_t dis_op83[8] = {
16760339a1c2SMark Johnston 
16770339a1c2SMark Johnston /*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
16780339a1c2SMark Johnston /*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
16790339a1c2SMark Johnston };
16800339a1c2SMark Johnston 
16810339a1c2SMark Johnston /*
16820339a1c2SMark Johnston  *	Decode table for 0xC0 opcodes.
16830339a1c2SMark Johnston  */
16840339a1c2SMark Johnston 
16850339a1c2SMark Johnston const instable_t dis_opC0[8] = {
16860339a1c2SMark Johnston 
16870339a1c2SMark Johnston /*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
16880339a1c2SMark Johnston /*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
16890339a1c2SMark Johnston };
16900339a1c2SMark Johnston 
16910339a1c2SMark Johnston /*
16920339a1c2SMark Johnston  *	Decode table for 0xD0 opcodes.
16930339a1c2SMark Johnston  */
16940339a1c2SMark Johnston 
16950339a1c2SMark Johnston const instable_t dis_opD0[8] = {
16960339a1c2SMark Johnston 
16970339a1c2SMark Johnston /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
16980339a1c2SMark Johnston /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
16990339a1c2SMark Johnston };
17000339a1c2SMark Johnston 
17010339a1c2SMark Johnston /*
17020339a1c2SMark Johnston  *	Decode table for 0xC1 opcodes.
17030339a1c2SMark Johnston  *	186 instruction set
17040339a1c2SMark Johnston  */
17050339a1c2SMark Johnston 
17060339a1c2SMark Johnston const instable_t dis_opC1[8] = {
17070339a1c2SMark Johnston 
17080339a1c2SMark Johnston /*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
17090339a1c2SMark Johnston /*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
17100339a1c2SMark Johnston };
17110339a1c2SMark Johnston 
17120339a1c2SMark Johnston /*
17130339a1c2SMark Johnston  *	Decode table for 0xD1 opcodes.
17140339a1c2SMark Johnston  */
17150339a1c2SMark Johnston 
17160339a1c2SMark Johnston const instable_t dis_opD1[8] = {
17170339a1c2SMark Johnston 
17180339a1c2SMark Johnston /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
17190339a1c2SMark Johnston /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
17200339a1c2SMark Johnston };
17210339a1c2SMark Johnston 
17220339a1c2SMark Johnston 
17230339a1c2SMark Johnston /*
17240339a1c2SMark Johnston  *	Decode table for 0xD2 opcodes.
17250339a1c2SMark Johnston  */
17260339a1c2SMark Johnston 
17270339a1c2SMark Johnston const instable_t dis_opD2[8] = {
17280339a1c2SMark Johnston 
17290339a1c2SMark Johnston /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
17300339a1c2SMark Johnston /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
17310339a1c2SMark Johnston };
17320339a1c2SMark Johnston /*
17330339a1c2SMark Johnston  *	Decode table for 0xD3 opcodes.
17340339a1c2SMark Johnston  */
17350339a1c2SMark Johnston 
17360339a1c2SMark Johnston const instable_t dis_opD3[8] = {
17370339a1c2SMark Johnston 
17380339a1c2SMark Johnston /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
17390339a1c2SMark Johnston /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
17400339a1c2SMark Johnston };
17410339a1c2SMark Johnston 
17420339a1c2SMark Johnston 
17430339a1c2SMark Johnston /*
17440339a1c2SMark Johnston  *	Decode table for 0xF6 opcodes.
17450339a1c2SMark Johnston  */
17460339a1c2SMark Johnston 
17470339a1c2SMark Johnston const instable_t dis_opF6[8] = {
17480339a1c2SMark Johnston 
17490339a1c2SMark Johnston /*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
17500339a1c2SMark Johnston /*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
17510339a1c2SMark Johnston };
17520339a1c2SMark Johnston 
17530339a1c2SMark Johnston 
17540339a1c2SMark Johnston /*
17550339a1c2SMark Johnston  *	Decode table for 0xF7 opcodes.
17560339a1c2SMark Johnston  */
17570339a1c2SMark Johnston 
17580339a1c2SMark Johnston const instable_t dis_opF7[8] = {
17590339a1c2SMark Johnston 
17600339a1c2SMark Johnston /*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
17610339a1c2SMark Johnston /*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
17620339a1c2SMark Johnston };
17630339a1c2SMark Johnston 
17640339a1c2SMark Johnston 
17650339a1c2SMark Johnston /*
17660339a1c2SMark Johnston  *	Decode table for 0xFE opcodes.
17670339a1c2SMark Johnston  */
17680339a1c2SMark Johnston 
17690339a1c2SMark Johnston const instable_t dis_opFE[8] = {
17700339a1c2SMark Johnston 
17710339a1c2SMark Johnston /*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
17720339a1c2SMark Johnston /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17730339a1c2SMark Johnston };
17740339a1c2SMark Johnston /*
17750339a1c2SMark Johnston  *	Decode table for 0xFF opcodes.
17760339a1c2SMark Johnston  */
17770339a1c2SMark Johnston 
17780339a1c2SMark Johnston const instable_t dis_opFF[8] = {
17790339a1c2SMark Johnston 
17800339a1c2SMark Johnston /*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
17810339a1c2SMark Johnston /*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
17820339a1c2SMark Johnston };
17830339a1c2SMark Johnston 
17840339a1c2SMark Johnston /* for 287 instructions, which are a mess to decode */
17850339a1c2SMark Johnston 
17860339a1c2SMark Johnston const instable_t dis_opFP1n2[8][8] = {
17870339a1c2SMark Johnston {
17880339a1c2SMark Johnston /* bit pattern:	1101 1xxx MODxx xR/M */
17890339a1c2SMark Johnston /*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
17900339a1c2SMark Johnston /*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
17910339a1c2SMark Johnston }, {
17920339a1c2SMark Johnston /*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
17930339a1c2SMark Johnston /*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
17940339a1c2SMark Johnston }, {
17950339a1c2SMark Johnston /*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
17960339a1c2SMark Johnston /*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
17970339a1c2SMark Johnston }, {
17980339a1c2SMark Johnston /*  [3,0]  */	TNS("fildl",M),		INVALID,		TNS("fistl",M),		TNS("fistpl",M),
17990339a1c2SMark Johnston /*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
18000339a1c2SMark Johnston }, {
18010339a1c2SMark Johnston /*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
18020339a1c2SMark Johnston /*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
18030339a1c2SMark Johnston }, {
18040339a1c2SMark Johnston /*  [5,0]  */	TNSZ("fldl",M,8),	INVALID,		TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
18050339a1c2SMark Johnston /*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
18060339a1c2SMark Johnston }, {
18070339a1c2SMark Johnston /*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
18080339a1c2SMark Johnston /*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
18090339a1c2SMark Johnston }, {
18100339a1c2SMark Johnston /*  [7,0]  */	TNSZ("fild",M,2),	INVALID,		TNSZ("fist",M,2),	TNSZ("fistp",M,2),
18110339a1c2SMark Johnston /*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
18120339a1c2SMark Johnston } };
18130339a1c2SMark Johnston 
18140339a1c2SMark Johnston const instable_t dis_opFP3[8][8] = {
18150339a1c2SMark Johnston {
18160339a1c2SMark Johnston /* bit  pattern:	1101 1xxx 11xx xREG */
18170339a1c2SMark Johnston /*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
18180339a1c2SMark Johnston /*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
18190339a1c2SMark Johnston }, {
18200339a1c2SMark Johnston /*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
18210339a1c2SMark Johnston /*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
18220339a1c2SMark Johnston }, {
18230339a1c2SMark Johnston /*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
18240339a1c2SMark Johnston /*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
18250339a1c2SMark Johnston }, {
18260339a1c2SMark Johnston /*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
18270339a1c2SMark Johnston /*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
18280339a1c2SMark Johnston }, {
18290339a1c2SMark Johnston /*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
18300339a1c2SMark Johnston /*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
18310339a1c2SMark Johnston }, {
18320339a1c2SMark Johnston /*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
18330339a1c2SMark Johnston /*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
18340339a1c2SMark Johnston }, {
18350339a1c2SMark Johnston /*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
18360339a1c2SMark Johnston /*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
18370339a1c2SMark Johnston }, {
18380339a1c2SMark Johnston /*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
18390339a1c2SMark Johnston /*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
18400339a1c2SMark Johnston } };
18410339a1c2SMark Johnston 
18420339a1c2SMark Johnston const instable_t dis_opFP4[4][8] = {
18430339a1c2SMark Johnston {
18440339a1c2SMark Johnston /* bit pattern:	1101 1001 111x xxxx */
18450339a1c2SMark Johnston /*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
18460339a1c2SMark Johnston /*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
18470339a1c2SMark Johnston }, {
18480339a1c2SMark Johnston /*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
18490339a1c2SMark Johnston /*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
18500339a1c2SMark Johnston }, {
18510339a1c2SMark Johnston /*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
18520339a1c2SMark Johnston /*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
18530339a1c2SMark Johnston }, {
18540339a1c2SMark Johnston /*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
18550339a1c2SMark Johnston /*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
18560339a1c2SMark Johnston } };
18570339a1c2SMark Johnston 
18580339a1c2SMark Johnston const instable_t dis_opFP5[8] = {
18590339a1c2SMark Johnston /* bit pattern:	1101 1011 111x xxxx */
18600339a1c2SMark Johnston /*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
18610339a1c2SMark Johnston /*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
18620339a1c2SMark Johnston };
18630339a1c2SMark Johnston 
18640339a1c2SMark Johnston const instable_t dis_opFP6[8] = {
18650339a1c2SMark Johnston /* bit pattern:	1101 1011 11yy yxxx */
18660339a1c2SMark Johnston /*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
18670339a1c2SMark Johnston /*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
18680339a1c2SMark Johnston };
18690339a1c2SMark Johnston 
18700339a1c2SMark Johnston const instable_t dis_opFP7[8] = {
18710339a1c2SMark Johnston /* bit pattern:	1101 1010 11yy yxxx */
18720339a1c2SMark Johnston /*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
18730339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
18740339a1c2SMark Johnston };
18750339a1c2SMark Johnston 
18760339a1c2SMark Johnston /*
18770339a1c2SMark Johnston  *	Main decode table for the op codes.  The first two nibbles
18780339a1c2SMark Johnston  *	will be used as an index into the table.  If there is a
18790339a1c2SMark Johnston  *	a need to further decode an instruction, the array to be
18800339a1c2SMark Johnston  *	referenced is indicated with the other two entries being
18810339a1c2SMark Johnston  *	empty.
18820339a1c2SMark Johnston  */
18830339a1c2SMark Johnston 
18840339a1c2SMark Johnston const instable_t dis_distable[16][16] = {
18850339a1c2SMark Johnston {
18860339a1c2SMark Johnston /* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
18870339a1c2SMark Johnston /* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
18880339a1c2SMark Johnston /* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
18890339a1c2SMark Johnston /* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
18900339a1c2SMark Johnston }, {
18910339a1c2SMark Johnston /* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
18920339a1c2SMark Johnston /* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
18930339a1c2SMark Johnston /* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
18940339a1c2SMark Johnston /* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
18950339a1c2SMark Johnston }, {
18960339a1c2SMark Johnston /* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
1897c3ddb60eSPeter Grehan /* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNSx("%es:",OVERRIDE),	TNSx("daa",NORM),
18980339a1c2SMark Johnston /* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
18990339a1c2SMark Johnston /* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNS("%cs:",OVERRIDE),	TNSx("das",NORM),
19000339a1c2SMark Johnston }, {
19010339a1c2SMark Johnston /* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
1902c3ddb60eSPeter Grehan /* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNSx("%ss:",OVERRIDE),	TNSx("aaa",NORM),
19030339a1c2SMark Johnston /* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
1904c3ddb60eSPeter Grehan /* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNSx("%ds:",OVERRIDE),	TNSx("aas",NORM),
19050339a1c2SMark Johnston }, {
19060339a1c2SMark Johnston /* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
19070339a1c2SMark Johnston /* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
19080339a1c2SMark Johnston /* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
19090339a1c2SMark Johnston /* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
19100339a1c2SMark Johnston }, {
19110339a1c2SMark Johnston /* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
19120339a1c2SMark Johnston /* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
19130339a1c2SMark Johnston /* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
19140339a1c2SMark Johnston /* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
19150339a1c2SMark Johnston }, {
19160339a1c2SMark Johnston /* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
19170339a1c2SMark Johnston /* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
19180339a1c2SMark Johnston /* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
19190339a1c2SMark Johnston /* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
19200339a1c2SMark Johnston }, {
19210339a1c2SMark Johnston /* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
19220339a1c2SMark Johnston /* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
19230339a1c2SMark Johnston /* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
19240339a1c2SMark Johnston /* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
19250339a1c2SMark Johnston }, {
19260339a1c2SMark Johnston /* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
19270339a1c2SMark Johnston /* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
19280339a1c2SMark Johnston /* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
19290339a1c2SMark Johnston /* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
19300339a1c2SMark Johnston }, {
19310339a1c2SMark Johnston /* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
19320339a1c2SMark Johnston /* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
19330339a1c2SMark Johnston /* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
1934*2d69831bSAndriy Gapon /* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNS("sahf",NORM),	TNS("lahf",NORM),
19350339a1c2SMark Johnston }, {
19360339a1c2SMark Johnston /* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
19370339a1c2SMark Johnston /* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
19380339a1c2SMark Johnston /* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
19390339a1c2SMark Johnston /* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
19400339a1c2SMark Johnston }, {
19410339a1c2SMark Johnston /* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
19420339a1c2SMark Johnston /* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
19430339a1c2SMark Johnston /* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
19440339a1c2SMark Johnston /* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
19450339a1c2SMark Johnston }, {
19460339a1c2SMark Johnston /* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
19470339a1c2SMark Johnston /* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
19480339a1c2SMark Johnston /* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
19490339a1c2SMark Johnston /* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
19500339a1c2SMark Johnston }, {
19510339a1c2SMark Johnston /* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
19520339a1c2SMark Johnston /* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
19530339a1c2SMark Johnston 
19540339a1c2SMark Johnston /* 287 instructions.  Note that although the indirect field		*/
19550339a1c2SMark Johnston /* indicates opFP1n2 for further decoding, this is not necessarily	*/
19560339a1c2SMark Johnston /* the case since the opFP arrays are not partitioned according to key1	*/
19570339a1c2SMark Johnston /* and key2.  opFP1n2 is given only to indicate that we haven't		*/
19580339a1c2SMark Johnston /* finished decoding the instruction.					*/
19590339a1c2SMark Johnston /* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
19600339a1c2SMark Johnston /* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
19610339a1c2SMark Johnston }, {
19620339a1c2SMark Johnston /* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
19630339a1c2SMark Johnston /* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
19640339a1c2SMark Johnston /* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
19650339a1c2SMark Johnston /* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
19660339a1c2SMark Johnston }, {
19670339a1c2SMark Johnston /* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
19680339a1c2SMark Johnston /* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
19690339a1c2SMark Johnston /* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
19700339a1c2SMark Johnston /* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
19710339a1c2SMark Johnston } };
19720339a1c2SMark Johnston 
19730339a1c2SMark Johnston /* END CSTYLED */
19740339a1c2SMark Johnston 
19750339a1c2SMark Johnston /*
19760339a1c2SMark Johnston  * common functions to decode and disassemble an x86 or amd64 instruction
19770339a1c2SMark Johnston  */
19780339a1c2SMark Johnston 
19790339a1c2SMark Johnston /*
19800339a1c2SMark Johnston  * These are the individual fields of a REX prefix. Note that a REX
19810339a1c2SMark Johnston  * prefix with none of these set is still needed to:
19820339a1c2SMark Johnston  *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
19830339a1c2SMark Johnston  *	- access the %sil, %dil, %bpl, %spl registers
19840339a1c2SMark Johnston  */
19850339a1c2SMark Johnston #define	REX_W 0x08	/* 64 bit operand size when set */
19860339a1c2SMark Johnston #define	REX_R 0x04	/* high order bit extension of ModRM reg field */
19870339a1c2SMark Johnston #define	REX_X 0x02	/* high order bit extension of SIB index field */
19880339a1c2SMark Johnston #define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
19890339a1c2SMark Johnston 
19900339a1c2SMark Johnston /*
19910339a1c2SMark Johnston  * These are the individual fields of a VEX prefix.
19920339a1c2SMark Johnston  */
19930339a1c2SMark Johnston #define	VEX_R 0x08	/* REX.R in 1's complement form */
19940339a1c2SMark Johnston #define	VEX_X 0x04	/* REX.X in 1's complement form */
19950339a1c2SMark Johnston #define	VEX_B 0x02	/* REX.B in 1's complement form */
19960339a1c2SMark Johnston /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
19970339a1c2SMark Johnston #define	VEX_L 0x04
19980339a1c2SMark Johnston #define	VEX_W 0x08	/* opcode specific, use like REX.W */
19990339a1c2SMark Johnston #define	VEX_m 0x1F	/* VEX m-mmmm field */
20000339a1c2SMark Johnston #define	VEX_v 0x78	/* VEX register specifier */
20010339a1c2SMark Johnston #define	VEX_p 0x03	/* VEX pp field, opcode extension */
20020339a1c2SMark Johnston 
20030339a1c2SMark Johnston /* VEX m-mmmm field, only used by three bytes prefix */
20040339a1c2SMark Johnston #define	VEX_m_0F 0x01   /* implied 0F leading opcode byte */
20050339a1c2SMark Johnston #define	VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
20060339a1c2SMark Johnston #define	VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
20070339a1c2SMark Johnston 
20080339a1c2SMark Johnston /* VEX pp field, providing equivalent functionality of a SIMD prefix */
20090339a1c2SMark Johnston #define	VEX_p_66 0x01
20100339a1c2SMark Johnston #define	VEX_p_F3 0x02
20110339a1c2SMark Johnston #define	VEX_p_F2 0x03
20120339a1c2SMark Johnston 
20130339a1c2SMark Johnston /*
20140339a1c2SMark Johnston  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
20150339a1c2SMark Johnston  */
20160339a1c2SMark Johnston static int isize[] = {1, 2, 4, 4};
20170339a1c2SMark Johnston static int isize64[] = {1, 2, 4, 8};
20180339a1c2SMark Johnston 
20190339a1c2SMark Johnston /*
20200339a1c2SMark Johnston  * Just a bunch of useful macros.
20210339a1c2SMark Johnston  */
20220339a1c2SMark Johnston #define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
20230339a1c2SMark Johnston #define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
20240339a1c2SMark Johnston #define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
20250339a1c2SMark Johnston #define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
20260339a1c2SMark Johnston #define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
20270339a1c2SMark Johnston 
20280339a1c2SMark Johnston #define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
20290339a1c2SMark Johnston 
20300339a1c2SMark Johnston #define	BYTE_OPND	0	/* w-bit value indicating byte register */
20310339a1c2SMark Johnston #define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
20320339a1c2SMark Johnston #define	MM_OPND		2	/* "value" used to indicate a mmx reg */
20330339a1c2SMark Johnston #define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
20340339a1c2SMark Johnston #define	SEG_OPND	4	/* "value" used to indicate a segment reg */
20350339a1c2SMark Johnston #define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
20360339a1c2SMark Johnston #define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
20370339a1c2SMark Johnston #define	TEST_OPND	7	/* "value" used to indicate a test reg */
20380339a1c2SMark Johnston #define	WORD_OPND	8	/* w-bit value indicating word size reg */
20390339a1c2SMark Johnston #define	YMM_OPND	9	/* "value" used to indicate a ymm reg */
20400339a1c2SMark Johnston 
20410339a1c2SMark Johnston /*
20420339a1c2SMark Johnston  * Get the next byte and separate the op code into the high and low nibbles.
20430339a1c2SMark Johnston  */
20440339a1c2SMark Johnston static int
20450339a1c2SMark Johnston dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
20460339a1c2SMark Johnston {
20470339a1c2SMark Johnston 	int byte;
20480339a1c2SMark Johnston 
20490339a1c2SMark Johnston 	/*
20500339a1c2SMark Johnston 	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
20510339a1c2SMark Johnston 	 * we try to read more.
20520339a1c2SMark Johnston 	 */
20530339a1c2SMark Johnston 	if (x->d86_len >= 15)
20540339a1c2SMark Johnston 		return (x->d86_error = 1);
20550339a1c2SMark Johnston 
20560339a1c2SMark Johnston 	if (x->d86_error)
20570339a1c2SMark Johnston 		return (1);
20580339a1c2SMark Johnston 	byte = x->d86_get_byte(x->d86_data);
20590339a1c2SMark Johnston 	if (byte < 0)
20600339a1c2SMark Johnston 		return (x->d86_error = 1);
20610339a1c2SMark Johnston 	x->d86_bytes[x->d86_len++] = byte;
20620339a1c2SMark Johnston 	*low = byte & 0xf;		/* ----xxxx low 4 bits */
20630339a1c2SMark Johnston 	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
20640339a1c2SMark Johnston 	return (0);
20650339a1c2SMark Johnston }
20660339a1c2SMark Johnston 
20670339a1c2SMark Johnston /*
20680339a1c2SMark Johnston  * Get and decode an SIB (scaled index base) byte
20690339a1c2SMark Johnston  */
20700339a1c2SMark Johnston static void
20710339a1c2SMark Johnston dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
20720339a1c2SMark Johnston {
20730339a1c2SMark Johnston 	int byte;
20740339a1c2SMark Johnston 
20750339a1c2SMark Johnston 	if (x->d86_error)
20760339a1c2SMark Johnston 		return;
20770339a1c2SMark Johnston 
20780339a1c2SMark Johnston 	byte = x->d86_get_byte(x->d86_data);
20790339a1c2SMark Johnston 	if (byte < 0) {
20800339a1c2SMark Johnston 		x->d86_error = 1;
20810339a1c2SMark Johnston 		return;
20820339a1c2SMark Johnston 	}
20830339a1c2SMark Johnston 	x->d86_bytes[x->d86_len++] = byte;
20840339a1c2SMark Johnston 
20850339a1c2SMark Johnston 	*base = byte & 0x7;
20860339a1c2SMark Johnston 	*index = (byte >> 3) & 0x7;
20870339a1c2SMark Johnston 	*ss = (byte >> 6) & 0x3;
20880339a1c2SMark Johnston }
20890339a1c2SMark Johnston 
20900339a1c2SMark Johnston /*
20910339a1c2SMark Johnston  * Get the byte following the op code and separate it into the
20920339a1c2SMark Johnston  * mode, register, and r/m fields.
20930339a1c2SMark Johnston  */
20940339a1c2SMark Johnston static void
20950339a1c2SMark Johnston dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
20960339a1c2SMark Johnston {
20970339a1c2SMark Johnston 	if (x->d86_got_modrm == 0) {
20980339a1c2SMark Johnston 		if (x->d86_rmindex == -1)
20990339a1c2SMark Johnston 			x->d86_rmindex = x->d86_len;
21000339a1c2SMark Johnston 		dtrace_get_SIB(x, mode, reg, r_m);
21010339a1c2SMark Johnston 		x->d86_got_modrm = 1;
21020339a1c2SMark Johnston 	}
21030339a1c2SMark Johnston }
21040339a1c2SMark Johnston 
21050339a1c2SMark Johnston /*
21060339a1c2SMark Johnston  * Adjust register selection based on any REX prefix bits present.
21070339a1c2SMark Johnston  */
21080339a1c2SMark Johnston /*ARGSUSED*/
21090339a1c2SMark Johnston static void
21100339a1c2SMark Johnston dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
21110339a1c2SMark Johnston {
21120339a1c2SMark Johnston 	if (reg != NULL && r_m == NULL) {
21130339a1c2SMark Johnston 		if (rex_prefix & REX_B)
21140339a1c2SMark Johnston 			*reg += 8;
21150339a1c2SMark Johnston 	} else {
21160339a1c2SMark Johnston 		if (reg != NULL && (REX_R & rex_prefix) != 0)
21170339a1c2SMark Johnston 			*reg += 8;
21180339a1c2SMark Johnston 		if (r_m != NULL && (REX_B & rex_prefix) != 0)
21190339a1c2SMark Johnston 			*r_m += 8;
21200339a1c2SMark Johnston 	}
21210339a1c2SMark Johnston }
21220339a1c2SMark Johnston 
21230339a1c2SMark Johnston /*
21240339a1c2SMark Johnston  * Adjust register selection based on any VEX prefix bits present.
21250339a1c2SMark Johnston  * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
21260339a1c2SMark Johnston  */
21270339a1c2SMark Johnston /*ARGSUSED*/
21280339a1c2SMark Johnston static void
21290339a1c2SMark Johnston dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
21300339a1c2SMark Johnston {
21310339a1c2SMark Johnston 	if (reg != NULL && r_m == NULL) {
21320339a1c2SMark Johnston 		if (!(vex_byte1 & VEX_B))
21330339a1c2SMark Johnston 			*reg += 8;
21340339a1c2SMark Johnston 	} else {
21350339a1c2SMark Johnston 		if (reg != NULL && ((VEX_R & vex_byte1) == 0))
21360339a1c2SMark Johnston 			*reg += 8;
21370339a1c2SMark Johnston 		if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
21380339a1c2SMark Johnston 			*r_m += 8;
21390339a1c2SMark Johnston 	}
21400339a1c2SMark Johnston }
21410339a1c2SMark Johnston 
21420339a1c2SMark Johnston /*
21430339a1c2SMark Johnston  * Get an immediate operand of the given size, with sign extension.
21440339a1c2SMark Johnston  */
21450339a1c2SMark Johnston static void
21460339a1c2SMark Johnston dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
21470339a1c2SMark Johnston {
21480339a1c2SMark Johnston 	int i;
21490339a1c2SMark Johnston 	int byte;
21500339a1c2SMark Johnston 	int valsize;
21510339a1c2SMark Johnston 
21520339a1c2SMark Johnston 	if (x->d86_numopnds < opindex + 1)
21530339a1c2SMark Johnston 		x->d86_numopnds = opindex + 1;
21540339a1c2SMark Johnston 
21550339a1c2SMark Johnston 	switch (wbit) {
21560339a1c2SMark Johnston 	case BYTE_OPND:
21570339a1c2SMark Johnston 		valsize = 1;
21580339a1c2SMark Johnston 		break;
21590339a1c2SMark Johnston 	case LONG_OPND:
21600339a1c2SMark Johnston 		if (x->d86_opnd_size == SIZE16)
21610339a1c2SMark Johnston 			valsize = 2;
21620339a1c2SMark Johnston 		else if (x->d86_opnd_size == SIZE32)
21630339a1c2SMark Johnston 			valsize = 4;
21640339a1c2SMark Johnston 		else
21650339a1c2SMark Johnston 			valsize = 8;
21660339a1c2SMark Johnston 		break;
21670339a1c2SMark Johnston 	case MM_OPND:
21680339a1c2SMark Johnston 	case XMM_OPND:
21690339a1c2SMark Johnston 	case YMM_OPND:
21700339a1c2SMark Johnston 	case SEG_OPND:
21710339a1c2SMark Johnston 	case CONTROL_OPND:
21720339a1c2SMark Johnston 	case DEBUG_OPND:
21730339a1c2SMark Johnston 	case TEST_OPND:
21740339a1c2SMark Johnston 		valsize = size;
21750339a1c2SMark Johnston 		break;
21760339a1c2SMark Johnston 	case WORD_OPND:
21770339a1c2SMark Johnston 		valsize = 2;
21780339a1c2SMark Johnston 		break;
21790339a1c2SMark Johnston 	}
21800339a1c2SMark Johnston 	if (valsize < size)
21810339a1c2SMark Johnston 		valsize = size;
21820339a1c2SMark Johnston 
21830339a1c2SMark Johnston 	if (x->d86_error)
21840339a1c2SMark Johnston 		return;
21850339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_value = 0;
21860339a1c2SMark Johnston 	for (i = 0; i < size; ++i) {
21870339a1c2SMark Johnston 		byte = x->d86_get_byte(x->d86_data);
21880339a1c2SMark Johnston 		if (byte < 0) {
21890339a1c2SMark Johnston 			x->d86_error = 1;
21900339a1c2SMark Johnston 			return;
21910339a1c2SMark Johnston 		}
21920339a1c2SMark Johnston 		x->d86_bytes[x->d86_len++] = byte;
21930339a1c2SMark Johnston 		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
21940339a1c2SMark Johnston 	}
21950339a1c2SMark Johnston 	/* Do sign extension */
21960339a1c2SMark Johnston 	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
21970339a1c2SMark Johnston 		for (; i < sizeof (uint64_t); i++)
21980339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_value |=
21990339a1c2SMark Johnston 			    (uint64_t)0xff << (i * 8);
22000339a1c2SMark Johnston 	}
22010339a1c2SMark Johnston #ifdef DIS_TEXT
22020339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
22030339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_value_size = valsize;
22040339a1c2SMark Johnston 	x->d86_imm_bytes += size;
22050339a1c2SMark Johnston #endif
22060339a1c2SMark Johnston }
22070339a1c2SMark Johnston 
22080339a1c2SMark Johnston /*
22090339a1c2SMark Johnston  * Get an ip relative operand of the given size, with sign extension.
22100339a1c2SMark Johnston  */
22110339a1c2SMark Johnston static void
22120339a1c2SMark Johnston dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
22130339a1c2SMark Johnston {
22140339a1c2SMark Johnston 	dtrace_imm_opnd(x, wbit, size, opindex);
22150339a1c2SMark Johnston #ifdef DIS_TEXT
22160339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
22170339a1c2SMark Johnston #endif
22180339a1c2SMark Johnston }
22190339a1c2SMark Johnston 
22200339a1c2SMark Johnston /*
22210339a1c2SMark Johnston  * Check to see if there is a segment override prefix pending.
22220339a1c2SMark Johnston  * If so, print it in the current 'operand' location and set
22230339a1c2SMark Johnston  * the override flag back to false.
22240339a1c2SMark Johnston  */
22250339a1c2SMark Johnston /*ARGSUSED*/
22260339a1c2SMark Johnston static void
22270339a1c2SMark Johnston dtrace_check_override(dis86_t *x, int opindex)
22280339a1c2SMark Johnston {
22290339a1c2SMark Johnston #ifdef DIS_TEXT
22300339a1c2SMark Johnston 	if (x->d86_seg_prefix) {
22310339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
22320339a1c2SMark Johnston 		    x->d86_seg_prefix, PFIXLEN);
22330339a1c2SMark Johnston 	}
22340339a1c2SMark Johnston #endif
22350339a1c2SMark Johnston 	x->d86_seg_prefix = NULL;
22360339a1c2SMark Johnston }
22370339a1c2SMark Johnston 
22380339a1c2SMark Johnston 
22390339a1c2SMark Johnston /*
22400339a1c2SMark Johnston  * Process a single instruction Register or Memory operand.
22410339a1c2SMark Johnston  *
22420339a1c2SMark Johnston  * mode = addressing mode from ModRM byte
22430339a1c2SMark Johnston  * r_m = r_m (or reg if mode == 3) field from ModRM byte
22440339a1c2SMark Johnston  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
22450339a1c2SMark Johnston  * o = index of operand that we are processing (0, 1 or 2)
22460339a1c2SMark Johnston  *
22470339a1c2SMark Johnston  * the value of reg or r_m must have already been adjusted for any REX prefix.
22480339a1c2SMark Johnston  */
22490339a1c2SMark Johnston /*ARGSUSED*/
22500339a1c2SMark Johnston static void
22510339a1c2SMark Johnston dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
22520339a1c2SMark Johnston {
22530339a1c2SMark Johnston 	int have_SIB = 0;	/* flag presence of scale-index-byte */
22540339a1c2SMark Johnston 	uint_t ss;		/* scale-factor from opcode */
22550339a1c2SMark Johnston 	uint_t index;		/* index register number */
22560339a1c2SMark Johnston 	uint_t base;		/* base register number */
22570339a1c2SMark Johnston 	int dispsize;   	/* size of displacement in bytes */
22580339a1c2SMark Johnston #ifdef DIS_TEXT
22590339a1c2SMark Johnston 	char *opnd = x->d86_opnd[opindex].d86_opnd;
22600339a1c2SMark Johnston #endif
22610339a1c2SMark Johnston 
22620339a1c2SMark Johnston 	if (x->d86_numopnds < opindex + 1)
22630339a1c2SMark Johnston 		x->d86_numopnds = opindex + 1;
22640339a1c2SMark Johnston 
22650339a1c2SMark Johnston 	if (x->d86_error)
22660339a1c2SMark Johnston 		return;
22670339a1c2SMark Johnston 
22680339a1c2SMark Johnston 	/*
22690339a1c2SMark Johnston 	 * first handle a simple register
22700339a1c2SMark Johnston 	 */
22710339a1c2SMark Johnston 	if (mode == REG_ONLY) {
22720339a1c2SMark Johnston #ifdef DIS_TEXT
22730339a1c2SMark Johnston 		switch (wbit) {
22740339a1c2SMark Johnston 		case MM_OPND:
22750339a1c2SMark Johnston 			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
22760339a1c2SMark Johnston 			break;
22770339a1c2SMark Johnston 		case XMM_OPND:
22780339a1c2SMark Johnston 			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
22790339a1c2SMark Johnston 			break;
22800339a1c2SMark Johnston 		case YMM_OPND:
22810339a1c2SMark Johnston 			(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
22820339a1c2SMark Johnston 			break;
22830339a1c2SMark Johnston 		case SEG_OPND:
22840339a1c2SMark Johnston 			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
22850339a1c2SMark Johnston 			break;
22860339a1c2SMark Johnston 		case CONTROL_OPND:
22870339a1c2SMark Johnston 			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
22880339a1c2SMark Johnston 			break;
22890339a1c2SMark Johnston 		case DEBUG_OPND:
22900339a1c2SMark Johnston 			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
22910339a1c2SMark Johnston 			break;
22920339a1c2SMark Johnston 		case TEST_OPND:
22930339a1c2SMark Johnston 			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
22940339a1c2SMark Johnston 			break;
22950339a1c2SMark Johnston 		case BYTE_OPND:
22960339a1c2SMark Johnston 			if (x->d86_rex_prefix == 0)
22970339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
22980339a1c2SMark Johnston 			else
22990339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
23000339a1c2SMark Johnston 			break;
23010339a1c2SMark Johnston 		case WORD_OPND:
23020339a1c2SMark Johnston 			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
23030339a1c2SMark Johnston 			break;
23040339a1c2SMark Johnston 		case LONG_OPND:
23050339a1c2SMark Johnston 			if (x->d86_opnd_size == SIZE16)
23060339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
23070339a1c2SMark Johnston 			else if (x->d86_opnd_size == SIZE32)
23080339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
23090339a1c2SMark Johnston 			else
23100339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
23110339a1c2SMark Johnston 			break;
23120339a1c2SMark Johnston 		}
23130339a1c2SMark Johnston #endif /* DIS_TEXT */
23140339a1c2SMark Johnston 		return;
23150339a1c2SMark Johnston 	}
23160339a1c2SMark Johnston 
23170339a1c2SMark Johnston 	/*
23180339a1c2SMark Johnston 	 * if symbolic representation, skip override prefix, if any
23190339a1c2SMark Johnston 	 */
23200339a1c2SMark Johnston 	dtrace_check_override(x, opindex);
23210339a1c2SMark Johnston 
23220339a1c2SMark Johnston 	/*
23230339a1c2SMark Johnston 	 * Handle 16 bit memory references first, since they decode
23240339a1c2SMark Johnston 	 * the mode values more simply.
23250339a1c2SMark Johnston 	 * mode 1 is r_m + 8 bit displacement
23260339a1c2SMark Johnston 	 * mode 2 is r_m + 16 bit displacement
23270339a1c2SMark Johnston 	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
23280339a1c2SMark Johnston 	 */
23290339a1c2SMark Johnston 	if (x->d86_addr_size == SIZE16) {
23300339a1c2SMark Johnston 		if ((mode == 0 && r_m == 6) || mode == 2)
23310339a1c2SMark Johnston 			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
23320339a1c2SMark Johnston 		else if (mode == 1)
23330339a1c2SMark Johnston 			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
23340339a1c2SMark Johnston #ifdef DIS_TEXT
23350339a1c2SMark Johnston 		if (mode == 0 && r_m == 6)
23360339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
23370339a1c2SMark Johnston 		else if (mode == 0)
23380339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_NONE;
23390339a1c2SMark Johnston 		else
23400339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
23410339a1c2SMark Johnston 		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
23420339a1c2SMark Johnston #endif
23430339a1c2SMark Johnston 		return;
23440339a1c2SMark Johnston 	}
23450339a1c2SMark Johnston 
23460339a1c2SMark Johnston 	/*
23470339a1c2SMark Johnston 	 * 32 and 64 bit addressing modes are more complex since they
23480339a1c2SMark Johnston 	 * can involve an SIB (scaled index and base) byte to decode.
23490339a1c2SMark Johnston 	 */
23500339a1c2SMark Johnston 	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
23510339a1c2SMark Johnston 		have_SIB = 1;
23520339a1c2SMark Johnston 		dtrace_get_SIB(x, &ss, &index, &base);
23530339a1c2SMark Johnston 		if (x->d86_error)
23540339a1c2SMark Johnston 			return;
23550339a1c2SMark Johnston 		if (base != 5 || mode != 0)
23560339a1c2SMark Johnston 			if (x->d86_rex_prefix & REX_B)
23570339a1c2SMark Johnston 				base += 8;
23580339a1c2SMark Johnston 		if (x->d86_rex_prefix & REX_X)
23590339a1c2SMark Johnston 			index += 8;
23600339a1c2SMark Johnston 	} else {
23610339a1c2SMark Johnston 		base = r_m;
23620339a1c2SMark Johnston 	}
23630339a1c2SMark Johnston 
23640339a1c2SMark Johnston 	/*
23650339a1c2SMark Johnston 	 * Compute the displacement size and get its bytes
23660339a1c2SMark Johnston 	 */
23670339a1c2SMark Johnston 	dispsize = 0;
23680339a1c2SMark Johnston 
23690339a1c2SMark Johnston 	if (mode == 1)
23700339a1c2SMark Johnston 		dispsize = 1;
23710339a1c2SMark Johnston 	else if (mode == 2)
23720339a1c2SMark Johnston 		dispsize = 4;
23730339a1c2SMark Johnston 	else if ((r_m & 7) == EBP_REGNO ||
23740339a1c2SMark Johnston 	    (have_SIB && (base & 7) == EBP_REGNO))
23750339a1c2SMark Johnston 		dispsize = 4;
23760339a1c2SMark Johnston 
23770339a1c2SMark Johnston 	if (dispsize > 0) {
23780339a1c2SMark Johnston 		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
23790339a1c2SMark Johnston 		    dispsize, opindex);
23800339a1c2SMark Johnston 		if (x->d86_error)
23810339a1c2SMark Johnston 			return;
23820339a1c2SMark Johnston 	}
23830339a1c2SMark Johnston 
23840339a1c2SMark Johnston #ifdef DIS_TEXT
23850339a1c2SMark Johnston 	if (dispsize > 0)
23860339a1c2SMark Johnston 		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
23870339a1c2SMark Johnston 
23880339a1c2SMark Johnston 	if (have_SIB == 0) {
23890339a1c2SMark Johnston 		if (x->d86_mode == SIZE32) {
23900339a1c2SMark Johnston 			if (mode == 0)
23910339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr32_mode0[r_m],
23920339a1c2SMark Johnston 				    OPLEN);
23930339a1c2SMark Johnston 			else
23940339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr32_mode12[r_m],
23950339a1c2SMark Johnston 				    OPLEN);
23960339a1c2SMark Johnston 		} else {
23970339a1c2SMark Johnston 			if (mode == 0) {
23980339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr64_mode0[r_m],
23990339a1c2SMark Johnston 				    OPLEN);
24000339a1c2SMark Johnston 				if (r_m == 5) {
24010339a1c2SMark Johnston 					x->d86_opnd[opindex].d86_mode =
24020339a1c2SMark Johnston 					    MODE_RIPREL;
24030339a1c2SMark Johnston 				}
24040339a1c2SMark Johnston 			} else {
24050339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr64_mode12[r_m],
24060339a1c2SMark Johnston 				    OPLEN);
24070339a1c2SMark Johnston 			}
24080339a1c2SMark Johnston 		}
24090339a1c2SMark Johnston 	} else {
24100339a1c2SMark Johnston 		uint_t need_paren = 0;
24110339a1c2SMark Johnston 		char **regs;
24120339a1c2SMark Johnston 		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
24130339a1c2SMark Johnston 			regs = (char **)dis_REG32;
24140339a1c2SMark Johnston 		else
24150339a1c2SMark Johnston 			regs = (char **)dis_REG64;
24160339a1c2SMark Johnston 
24170339a1c2SMark Johnston 		/*
24180339a1c2SMark Johnston 		 * print the base (if any)
24190339a1c2SMark Johnston 		 */
24200339a1c2SMark Johnston 		if (base == EBP_REGNO && mode == 0) {
24210339a1c2SMark Johnston 			if (index != ESP_REGNO) {
24220339a1c2SMark Johnston 				(void) strlcat(opnd, "(", OPLEN);
24230339a1c2SMark Johnston 				need_paren = 1;
24240339a1c2SMark Johnston 			}
24250339a1c2SMark Johnston 		} else {
24260339a1c2SMark Johnston 			(void) strlcat(opnd, "(", OPLEN);
24270339a1c2SMark Johnston 			(void) strlcat(opnd, regs[base], OPLEN);
24280339a1c2SMark Johnston 			need_paren = 1;
24290339a1c2SMark Johnston 		}
24300339a1c2SMark Johnston 
24310339a1c2SMark Johnston 		/*
24320339a1c2SMark Johnston 		 * print the index (if any)
24330339a1c2SMark Johnston 		 */
24340339a1c2SMark Johnston 		if (index != ESP_REGNO) {
24350339a1c2SMark Johnston 			(void) strlcat(opnd, ",", OPLEN);
24360339a1c2SMark Johnston 			(void) strlcat(opnd, regs[index], OPLEN);
24370339a1c2SMark Johnston 			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
24380339a1c2SMark Johnston 		} else
24390339a1c2SMark Johnston 			if (need_paren)
24400339a1c2SMark Johnston 				(void) strlcat(opnd, ")", OPLEN);
24410339a1c2SMark Johnston 	}
24420339a1c2SMark Johnston #endif
24430339a1c2SMark Johnston }
24440339a1c2SMark Johnston 
24450339a1c2SMark Johnston /*
24460339a1c2SMark Johnston  * Operand sequence for standard instruction involving one register
24470339a1c2SMark Johnston  * and one register/memory operand.
24480339a1c2SMark Johnston  * wbit indicates a byte(0) or opnd_size(1) operation
24490339a1c2SMark Johnston  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
24500339a1c2SMark Johnston  */
24510339a1c2SMark Johnston #define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
24520339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
24530339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
24540339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
24550339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
24560339a1c2SMark Johnston }
24570339a1c2SMark Johnston 
24580339a1c2SMark Johnston /*
24590339a1c2SMark Johnston  * Similar to above, but allows for the two operands to be of different
24600339a1c2SMark Johnston  * classes (ie. wbit).
24610339a1c2SMark Johnston  *	wbit is for the r_m operand
24620339a1c2SMark Johnston  *	w2 is for the reg operand
24630339a1c2SMark Johnston  */
24640339a1c2SMark Johnston #define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
24650339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
24660339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
24670339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
24680339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
24690339a1c2SMark Johnston }
24700339a1c2SMark Johnston 
24710339a1c2SMark Johnston /*
24720339a1c2SMark Johnston  * Similar, but for 2 operands plus an immediate.
24730339a1c2SMark Johnston  * vbit indicates direction
24740339a1c2SMark Johnston  * 	0 for "opcode imm, r, r_m" or
24750339a1c2SMark Johnston  *	1 for "opcode imm, r_m, r"
24760339a1c2SMark Johnston  */
24770339a1c2SMark Johnston #define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
24780339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
24790339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
24800339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
24810339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
24820339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
24830339a1c2SMark Johnston }
24840339a1c2SMark Johnston 
24850339a1c2SMark Johnston /*
24860339a1c2SMark Johnston  * Similar, but for 2 operands plus two immediates.
24870339a1c2SMark Johnston  */
24880339a1c2SMark Johnston #define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
24890339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
24900339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
24910339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
24920339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
24930339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
24940339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
24950339a1c2SMark Johnston }
24960339a1c2SMark Johnston 
24970339a1c2SMark Johnston /*
24980339a1c2SMark Johnston  * 1 operands plus two immediates.
24990339a1c2SMark Johnston  */
25000339a1c2SMark Johnston #define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
25010339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
25020339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
25030339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
25040339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
25050339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
25060339a1c2SMark Johnston }
25070339a1c2SMark Johnston 
25080339a1c2SMark Johnston /*
25090339a1c2SMark Johnston  * Dissassemble a single x86 or amd64 instruction.
25100339a1c2SMark Johnston  *
25110339a1c2SMark Johnston  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
25120339a1c2SMark Johnston  * for interpreting instructions.
25130339a1c2SMark Johnston  *
25140339a1c2SMark Johnston  * returns non-zero for bad opcode
25150339a1c2SMark Johnston  */
25160339a1c2SMark Johnston int
25170339a1c2SMark Johnston dtrace_disx86(dis86_t *x, uint_t cpu_mode)
25180339a1c2SMark Johnston {
25190339a1c2SMark Johnston 	instable_t *dp;		/* decode table being used */
25200339a1c2SMark Johnston #ifdef DIS_TEXT
25210339a1c2SMark Johnston 	uint_t i;
25220339a1c2SMark Johnston #endif
25230339a1c2SMark Johnston #ifdef DIS_MEM
25240339a1c2SMark Johnston 	uint_t nomem = 0;
25250339a1c2SMark Johnston #define	NOMEM	(nomem = 1)
25260339a1c2SMark Johnston #else
25270339a1c2SMark Johnston #define	NOMEM	/* nothing */
25280339a1c2SMark Johnston #endif
25290339a1c2SMark Johnston 	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
25300339a1c2SMark Johnston 	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
25310339a1c2SMark Johnston 	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
25320339a1c2SMark Johnston 	uint_t w2;		/* wbit value for second operand */
25330339a1c2SMark Johnston 	uint_t vbit;
25340339a1c2SMark Johnston 	uint_t mode = 0;	/* mode value from ModRM byte */
25350339a1c2SMark Johnston 	uint_t reg;		/* reg value from ModRM byte */
25360339a1c2SMark Johnston 	uint_t r_m;		/* r_m value from ModRM byte */
25370339a1c2SMark Johnston 
25380339a1c2SMark Johnston 	uint_t opcode1;		/* high nibble of 1st byte */
25390339a1c2SMark Johnston 	uint_t opcode2;		/* low nibble of 1st byte */
25400339a1c2SMark Johnston 	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
25410339a1c2SMark Johnston 	uint_t opcode4;		/* high nibble of 2nd byte */
25420339a1c2SMark Johnston 	uint_t opcode5;		/* low nibble of 2nd byte */
25430339a1c2SMark Johnston 	uint_t opcode6;		/* high nibble of 3rd byte */
25440339a1c2SMark Johnston 	uint_t opcode7;		/* low nibble of 3rd byte */
25450339a1c2SMark Johnston 	uint_t opcode_bytes = 1;
25460339a1c2SMark Johnston 
25470339a1c2SMark Johnston 	/*
25480339a1c2SMark Johnston 	 * legacy prefixes come in 5 flavors, you should have only one of each
25490339a1c2SMark Johnston 	 */
25500339a1c2SMark Johnston 	uint_t	opnd_size_prefix = 0;
25510339a1c2SMark Johnston 	uint_t	addr_size_prefix = 0;
25520339a1c2SMark Johnston 	uint_t	segment_prefix = 0;
25530339a1c2SMark Johnston 	uint_t	lock_prefix = 0;
25540339a1c2SMark Johnston 	uint_t	rep_prefix = 0;
25550339a1c2SMark Johnston 	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
25560339a1c2SMark Johnston 
25570339a1c2SMark Johnston 	/*
25580339a1c2SMark Johnston 	 * Intel VEX instruction encoding prefix and fields
25590339a1c2SMark Johnston 	 */
25600339a1c2SMark Johnston 
25610339a1c2SMark Johnston 	/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
25620339a1c2SMark Johnston 	uint_t vex_prefix = 0;
25630339a1c2SMark Johnston 
25640339a1c2SMark Johnston 	/*
25650339a1c2SMark Johnston 	 * VEX prefix byte 1, includes vex.r, vex.x and vex.b
25660339a1c2SMark Johnston 	 * (for 3 bytes prefix)
25670339a1c2SMark Johnston 	 */
25680339a1c2SMark Johnston 	uint_t vex_byte1 = 0;
25690339a1c2SMark Johnston 
25700339a1c2SMark Johnston 	/*
25710339a1c2SMark Johnston 	 * For 32-bit mode, it should prefetch the next byte to
25720339a1c2SMark Johnston 	 * distinguish between AVX and les/lds
25730339a1c2SMark Johnston 	 */
25740339a1c2SMark Johnston 	uint_t vex_prefetch = 0;
25750339a1c2SMark Johnston 
25760339a1c2SMark Johnston 	uint_t vex_m = 0;
25770339a1c2SMark Johnston 	uint_t vex_v = 0;
25780339a1c2SMark Johnston 	uint_t vex_p = 0;
25790339a1c2SMark Johnston 	uint_t vex_R = 1;
25800339a1c2SMark Johnston 	uint_t vex_X = 1;
25810339a1c2SMark Johnston 	uint_t vex_B = 1;
25820339a1c2SMark Johnston 	uint_t vex_W = 0;
25830339a1c2SMark Johnston 	uint_t vex_L;
25840339a1c2SMark Johnston 
25850339a1c2SMark Johnston 
25860339a1c2SMark Johnston 	size_t	off;
25870339a1c2SMark Johnston 
25880339a1c2SMark Johnston 	instable_t dp_mmx;
25890339a1c2SMark Johnston 
25900339a1c2SMark Johnston 	x->d86_len = 0;
25910339a1c2SMark Johnston 	x->d86_rmindex = -1;
25920339a1c2SMark Johnston 	x->d86_error = 0;
25930339a1c2SMark Johnston #ifdef DIS_TEXT
25940339a1c2SMark Johnston 	x->d86_numopnds = 0;
25950339a1c2SMark Johnston 	x->d86_seg_prefix = NULL;
25960339a1c2SMark Johnston 	x->d86_mnem[0] = 0;
25970339a1c2SMark Johnston 	for (i = 0; i < 4; ++i) {
25980339a1c2SMark Johnston 		x->d86_opnd[i].d86_opnd[0] = 0;
25990339a1c2SMark Johnston 		x->d86_opnd[i].d86_prefix[0] = 0;
26000339a1c2SMark Johnston 		x->d86_opnd[i].d86_value_size = 0;
26010339a1c2SMark Johnston 		x->d86_opnd[i].d86_value = 0;
26020339a1c2SMark Johnston 		x->d86_opnd[i].d86_mode = MODE_NONE;
26030339a1c2SMark Johnston 	}
26040339a1c2SMark Johnston #endif
26050339a1c2SMark Johnston 	x->d86_rex_prefix = 0;
26060339a1c2SMark Johnston 	x->d86_got_modrm = 0;
26070339a1c2SMark Johnston 	x->d86_memsize = 0;
26080339a1c2SMark Johnston 
26090339a1c2SMark Johnston 	if (cpu_mode == SIZE16) {
26100339a1c2SMark Johnston 		opnd_size = SIZE16;
26110339a1c2SMark Johnston 		addr_size = SIZE16;
26120339a1c2SMark Johnston 	} else if (cpu_mode == SIZE32) {
26130339a1c2SMark Johnston 		opnd_size = SIZE32;
26140339a1c2SMark Johnston 		addr_size = SIZE32;
26150339a1c2SMark Johnston 	} else {
26160339a1c2SMark Johnston 		opnd_size = SIZE32;
26170339a1c2SMark Johnston 		addr_size = SIZE64;
26180339a1c2SMark Johnston 	}
26190339a1c2SMark Johnston 
26200339a1c2SMark Johnston 	/*
26210339a1c2SMark Johnston 	 * Get one opcode byte and check for zero padding that follows
26220339a1c2SMark Johnston 	 * jump tables.
26230339a1c2SMark Johnston 	 */
26240339a1c2SMark Johnston 	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
26250339a1c2SMark Johnston 		goto error;
26260339a1c2SMark Johnston 
26270339a1c2SMark Johnston 	if (opcode1 == 0 && opcode2 == 0 &&
26280339a1c2SMark Johnston 	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
26290339a1c2SMark Johnston #ifdef DIS_TEXT
26300339a1c2SMark Johnston 		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
26310339a1c2SMark Johnston #endif
26320339a1c2SMark Johnston 		goto done;
26330339a1c2SMark Johnston 	}
26340339a1c2SMark Johnston 
26350339a1c2SMark Johnston 	/*
26360339a1c2SMark Johnston 	 * Gather up legacy x86 prefix bytes.
26370339a1c2SMark Johnston 	 */
26380339a1c2SMark Johnston 	for (;;) {
26390339a1c2SMark Johnston 		uint_t *which_prefix = NULL;
26400339a1c2SMark Johnston 
26410339a1c2SMark Johnston 		dp = (instable_t *)&dis_distable[opcode1][opcode2];
26420339a1c2SMark Johnston 
26430339a1c2SMark Johnston 		switch (dp->it_adrmode) {
26440339a1c2SMark Johnston 		case PREFIX:
26450339a1c2SMark Johnston 			which_prefix = &rep_prefix;
26460339a1c2SMark Johnston 			break;
26470339a1c2SMark Johnston 		case LOCK:
26480339a1c2SMark Johnston 			which_prefix = &lock_prefix;
26490339a1c2SMark Johnston 			break;
26500339a1c2SMark Johnston 		case OVERRIDE:
26510339a1c2SMark Johnston 			which_prefix = &segment_prefix;
26520339a1c2SMark Johnston #ifdef DIS_TEXT
26530339a1c2SMark Johnston 			x->d86_seg_prefix = (char *)dp->it_name;
26540339a1c2SMark Johnston #endif
26550339a1c2SMark Johnston 			if (dp->it_invalid64 && cpu_mode == SIZE64)
26560339a1c2SMark Johnston 				goto error;
26570339a1c2SMark Johnston 			break;
26580339a1c2SMark Johnston 		case AM:
26590339a1c2SMark Johnston 			which_prefix = &addr_size_prefix;
26600339a1c2SMark Johnston 			break;
26610339a1c2SMark Johnston 		case DM:
26620339a1c2SMark Johnston 			which_prefix = &opnd_size_prefix;
26630339a1c2SMark Johnston 			break;
26640339a1c2SMark Johnston 		}
26650339a1c2SMark Johnston 		if (which_prefix == NULL)
26660339a1c2SMark Johnston 			break;
26670339a1c2SMark Johnston 		*which_prefix = (opcode1 << 4) | opcode2;
26680339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
26690339a1c2SMark Johnston 			goto error;
26700339a1c2SMark Johnston 	}
26710339a1c2SMark Johnston 
26720339a1c2SMark Johnston 	/*
26730339a1c2SMark Johnston 	 * Handle amd64 mode PREFIX values.
26740339a1c2SMark Johnston 	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
26750339a1c2SMark Johnston 	 * We might have a REX prefix (opcodes 0x40-0x4f)
26760339a1c2SMark Johnston 	 */
26770339a1c2SMark Johnston 	if (cpu_mode == SIZE64) {
26780339a1c2SMark Johnston 		if (segment_prefix != 0x64 && segment_prefix != 0x65)
26790339a1c2SMark Johnston 			segment_prefix = 0;
26800339a1c2SMark Johnston 
26810339a1c2SMark Johnston 		if (opcode1 == 0x4) {
26820339a1c2SMark Johnston 			rex_prefix = (opcode1 << 4) | opcode2;
26830339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
26840339a1c2SMark Johnston 				goto error;
26850339a1c2SMark Johnston 			dp = (instable_t *)&dis_distable[opcode1][opcode2];
26860339a1c2SMark Johnston 		} else if (opcode1 == 0xC &&
26870339a1c2SMark Johnston 		    (opcode2 == 0x4 || opcode2 == 0x5)) {
26880339a1c2SMark Johnston 			/* AVX instructions */
26890339a1c2SMark Johnston 			vex_prefix = (opcode1 << 4) | opcode2;
26900339a1c2SMark Johnston 			x->d86_rex_prefix = 0x40;
26910339a1c2SMark Johnston 		}
26920339a1c2SMark Johnston 	} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
26930339a1c2SMark Johnston 		/* LDS, LES or AVX */
26940339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
26950339a1c2SMark Johnston 		vex_prefetch = 1;
26960339a1c2SMark Johnston 
26970339a1c2SMark Johnston 		if (mode == REG_ONLY) {
26980339a1c2SMark Johnston 			/* AVX */
26990339a1c2SMark Johnston 			vex_prefix = (opcode1 << 4) | opcode2;
27000339a1c2SMark Johnston 			x->d86_rex_prefix = 0x40;
27010339a1c2SMark Johnston 			opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
27020339a1c2SMark Johnston 			opcode4 = ((reg << 3) | r_m) & 0x0F;
27030339a1c2SMark Johnston 		}
27040339a1c2SMark Johnston 	}
27050339a1c2SMark Johnston 
27060339a1c2SMark Johnston 	if (vex_prefix == VEX_2bytes) {
27070339a1c2SMark Johnston 		if (!vex_prefetch) {
27080339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
27090339a1c2SMark Johnston 				goto error;
27100339a1c2SMark Johnston 		}
27110339a1c2SMark Johnston 		vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
27120339a1c2SMark Johnston 		vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
27130339a1c2SMark Johnston 		vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
27140339a1c2SMark Johnston 		vex_p = opcode4 & VEX_p;
27150339a1c2SMark Johnston 		/*
27160339a1c2SMark Johnston 		 * The vex.x and vex.b bits are not defined in two bytes
27170339a1c2SMark Johnston 		 * mode vex prefix, their default values are 1
27180339a1c2SMark Johnston 		 */
27190339a1c2SMark Johnston 		vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
27200339a1c2SMark Johnston 
27210339a1c2SMark Johnston 		if (vex_R == 0)
27220339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_R;
27230339a1c2SMark Johnston 
27240339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
27250339a1c2SMark Johnston 			goto error;
27260339a1c2SMark Johnston 
27270339a1c2SMark Johnston 		switch (vex_p) {
27280339a1c2SMark Johnston 			case VEX_p_66:
27290339a1c2SMark Johnston 				dp = (instable_t *)
27300339a1c2SMark Johnston 				    &dis_opAVX660F[(opcode1 << 4) | opcode2];
27310339a1c2SMark Johnston 				break;
27320339a1c2SMark Johnston 			case VEX_p_F3:
27330339a1c2SMark Johnston 				dp = (instable_t *)
27340339a1c2SMark Johnston 				    &dis_opAVXF30F[(opcode1 << 4) | opcode2];
27350339a1c2SMark Johnston 				break;
27360339a1c2SMark Johnston 			case VEX_p_F2:
27370339a1c2SMark Johnston 				dp = (instable_t *)
27380339a1c2SMark Johnston 				    &dis_opAVXF20F [(opcode1 << 4) | opcode2];
27390339a1c2SMark Johnston 				break;
27400339a1c2SMark Johnston 			default:
27410339a1c2SMark Johnston 				dp = (instable_t *)
27420339a1c2SMark Johnston 				    &dis_opAVX0F[opcode1][opcode2];
27430339a1c2SMark Johnston 
27440339a1c2SMark Johnston 		}
27450339a1c2SMark Johnston 
27460339a1c2SMark Johnston 	} else if (vex_prefix == VEX_3bytes) {
27470339a1c2SMark Johnston 		if (!vex_prefetch) {
27480339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
27490339a1c2SMark Johnston 				goto error;
27500339a1c2SMark Johnston 		}
27510339a1c2SMark Johnston 		vex_R = (opcode3 & VEX_R) >> 3;
27520339a1c2SMark Johnston 		vex_X = (opcode3 & VEX_X) >> 2;
27530339a1c2SMark Johnston 		vex_B = (opcode3 & VEX_B) >> 1;
27540339a1c2SMark Johnston 		vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
27550339a1c2SMark Johnston 		vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
27560339a1c2SMark Johnston 
27570339a1c2SMark Johnston 		if (vex_R == 0)
27580339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_R;
27590339a1c2SMark Johnston 		if (vex_X == 0)
27600339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_X;
27610339a1c2SMark Johnston 		if (vex_B == 0)
27620339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_B;
27630339a1c2SMark Johnston 
27640339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
27650339a1c2SMark Johnston 			goto error;
27660339a1c2SMark Johnston 		vex_W = (opcode5 & VEX_W) >> 3;
27670339a1c2SMark Johnston 		vex_L = (opcode6 & VEX_L) >> 2;
27680339a1c2SMark Johnston 		vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
27690339a1c2SMark Johnston 		vex_p = opcode6 & VEX_p;
27700339a1c2SMark Johnston 
27710339a1c2SMark Johnston 		if (vex_W)
27720339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_W;
27730339a1c2SMark Johnston 
27740339a1c2SMark Johnston 		/* Only these three vex_m values valid; others are reserved */
27750339a1c2SMark Johnston 		if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
27760339a1c2SMark Johnston 		    (vex_m != VEX_m_0F3A))
27770339a1c2SMark Johnston 			goto error;
27780339a1c2SMark Johnston 
27790339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
27800339a1c2SMark Johnston 			goto error;
27810339a1c2SMark Johnston 
27820339a1c2SMark Johnston 		switch (vex_p) {
27830339a1c2SMark Johnston 			case VEX_p_66:
27840339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
27850339a1c2SMark Johnston 					dp = (instable_t *)
27860339a1c2SMark Johnston 					    &dis_opAVX660F
27870339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
27880339a1c2SMark Johnston 				} else if (vex_m == VEX_m_0F38) {
27890339a1c2SMark Johnston 					dp = (instable_t *)
27900339a1c2SMark Johnston 					    &dis_opAVX660F38
27910339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
27920339a1c2SMark Johnston 				} else if (vex_m == VEX_m_0F3A) {
27930339a1c2SMark Johnston 					dp = (instable_t *)
27940339a1c2SMark Johnston 					    &dis_opAVX660F3A
27950339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
27960339a1c2SMark Johnston 				} else {
27970339a1c2SMark Johnston 					goto error;
27980339a1c2SMark Johnston 				}
27990339a1c2SMark Johnston 				break;
28000339a1c2SMark Johnston 			case VEX_p_F3:
28010339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
28020339a1c2SMark Johnston 					dp = (instable_t *)
28030339a1c2SMark Johnston 					    &dis_opAVXF30F
28040339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
28050339a1c2SMark Johnston 				} else {
28060339a1c2SMark Johnston 					goto error;
28070339a1c2SMark Johnston 				}
28080339a1c2SMark Johnston 				break;
28090339a1c2SMark Johnston 			case VEX_p_F2:
28100339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
28110339a1c2SMark Johnston 					dp = (instable_t *)
28120339a1c2SMark Johnston 					    &dis_opAVXF20F
28130339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
28140339a1c2SMark Johnston 				} else {
28150339a1c2SMark Johnston 					goto error;
28160339a1c2SMark Johnston 				}
28170339a1c2SMark Johnston 				break;
28180339a1c2SMark Johnston 			default:
28190339a1c2SMark Johnston 				dp = (instable_t *)
28200339a1c2SMark Johnston 				    &dis_opAVX0F[opcode1][opcode2];
28210339a1c2SMark Johnston 
28220339a1c2SMark Johnston 		}
28230339a1c2SMark Johnston 	}
28240339a1c2SMark Johnston 	if (vex_prefix) {
28250339a1c2SMark Johnston 		if (vex_L)
28260339a1c2SMark Johnston 			wbit = YMM_OPND;
28270339a1c2SMark Johnston 		else
28280339a1c2SMark Johnston 			wbit = XMM_OPND;
28290339a1c2SMark Johnston 	}
28300339a1c2SMark Johnston 
28310339a1c2SMark Johnston 	/*
28320339a1c2SMark Johnston 	 * Deal with selection of operand and address size now.
28330339a1c2SMark Johnston 	 * Note that the REX.W bit being set causes opnd_size_prefix to be
28340339a1c2SMark Johnston 	 * ignored.
28350339a1c2SMark Johnston 	 */
28360339a1c2SMark Johnston 	if (cpu_mode == SIZE64) {
28370339a1c2SMark Johnston 		if ((rex_prefix & REX_W) || vex_W)
28380339a1c2SMark Johnston 			opnd_size = SIZE64;
28390339a1c2SMark Johnston 		else if (opnd_size_prefix)
28400339a1c2SMark Johnston 			opnd_size = SIZE16;
28410339a1c2SMark Johnston 
28420339a1c2SMark Johnston 		if (addr_size_prefix)
28430339a1c2SMark Johnston 			addr_size = SIZE32;
28440339a1c2SMark Johnston 	} else if (cpu_mode == SIZE32) {
28450339a1c2SMark Johnston 		if (opnd_size_prefix)
28460339a1c2SMark Johnston 			opnd_size = SIZE16;
28470339a1c2SMark Johnston 		if (addr_size_prefix)
28480339a1c2SMark Johnston 			addr_size = SIZE16;
28490339a1c2SMark Johnston 	} else {
28500339a1c2SMark Johnston 		if (opnd_size_prefix)
28510339a1c2SMark Johnston 			opnd_size = SIZE32;
28520339a1c2SMark Johnston 		if (addr_size_prefix)
28530339a1c2SMark Johnston 			addr_size = SIZE32;
28540339a1c2SMark Johnston 	}
28550339a1c2SMark Johnston 	/*
28560339a1c2SMark Johnston 	 * The pause instruction - a repz'd nop.  This doesn't fit
28570339a1c2SMark Johnston 	 * with any of the other prefix goop added for SSE, so we'll
28580339a1c2SMark Johnston 	 * special-case it here.
28590339a1c2SMark Johnston 	 */
28600339a1c2SMark Johnston 	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
28610339a1c2SMark Johnston 		rep_prefix = 0;
28620339a1c2SMark Johnston 		dp = (instable_t *)&dis_opPause;
28630339a1c2SMark Johnston 	}
28640339a1c2SMark Johnston 
28650339a1c2SMark Johnston 	/*
28660339a1c2SMark Johnston 	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
28670339a1c2SMark Johnston 	 * byte so we may need to perform a table indirection.
28680339a1c2SMark Johnston 	 */
28690339a1c2SMark Johnston 	if (dp->it_indirect == (instable_t *)dis_op0F) {
28700339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
28710339a1c2SMark Johnston 			goto error;
28720339a1c2SMark Johnston 		opcode_bytes = 2;
28730339a1c2SMark Johnston 		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
28740339a1c2SMark Johnston 			uint_t	subcode;
28750339a1c2SMark Johnston 
28760339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
28770339a1c2SMark Johnston 				goto error;
28780339a1c2SMark Johnston 			opcode_bytes = 3;
28790339a1c2SMark Johnston 			subcode = ((opcode6 & 0x3) << 1) |
28800339a1c2SMark Johnston 			    ((opcode7 & 0x8) >> 3);
28810339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
28820339a1c2SMark Johnston 		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
28830339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0FC8[0];
28840339a1c2SMark Johnston 		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
28850339a1c2SMark Johnston 			opcode_bytes = 3;
28860339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
28870339a1c2SMark Johnston 				goto error;
28880339a1c2SMark Johnston 			if (opnd_size == SIZE16)
28890339a1c2SMark Johnston 				opnd_size = SIZE32;
28900339a1c2SMark Johnston 
28910339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
28920339a1c2SMark Johnston #ifdef DIS_TEXT
28930339a1c2SMark Johnston 			if (strcmp(dp->it_name, "INVALID") == 0)
28940339a1c2SMark Johnston 				goto error;
28950339a1c2SMark Johnston #endif
28960339a1c2SMark Johnston 			switch (dp->it_adrmode) {
28970339a1c2SMark Johnston 				case XMMP_66r:
28980339a1c2SMark Johnston 				case XMMPRM_66r:
28990339a1c2SMark Johnston 				case XMM3PM_66r:
29000339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
29010339a1c2SMark Johnston 						goto error;
29020339a1c2SMark Johnston 					}
29030339a1c2SMark Johnston 					break;
29040339a1c2SMark Johnston 				case XMMP_66o:
29050339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
29060339a1c2SMark Johnston 						/* SSSE3 MMX instructions */
29070339a1c2SMark Johnston 						dp_mmx = *dp;
29080339a1c2SMark Johnston 						dp = &dp_mmx;
29090339a1c2SMark Johnston 						dp->it_adrmode = MMOPM_66o;
29100339a1c2SMark Johnston #ifdef	DIS_MEM
29110339a1c2SMark Johnston 						dp->it_size = 8;
29120339a1c2SMark Johnston #endif
29130339a1c2SMark Johnston 					}
29140339a1c2SMark Johnston 					break;
29150339a1c2SMark Johnston 				default:
29160339a1c2SMark Johnston 					goto error;
29170339a1c2SMark Johnston 			}
29180339a1c2SMark Johnston 		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
29190339a1c2SMark Johnston 			opcode_bytes = 3;
29200339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
29210339a1c2SMark Johnston 				goto error;
29220339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
29230339a1c2SMark Johnston 
29240339a1c2SMark Johnston 			/*
29250339a1c2SMark Johnston 			 * Both crc32 and movbe have the same 3rd opcode
29260339a1c2SMark Johnston 			 * byte of either 0xF0 or 0xF1, so we use another
29270339a1c2SMark Johnston 			 * indirection to distinguish between the two.
29280339a1c2SMark Johnston 			 */
29290339a1c2SMark Johnston 			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
29300339a1c2SMark Johnston 			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
29310339a1c2SMark Johnston 
29320339a1c2SMark Johnston 				dp = dp->it_indirect;
29330339a1c2SMark Johnston 				if (rep_prefix != 0xF2) {
29340339a1c2SMark Johnston 					/* It is movbe */
29350339a1c2SMark Johnston 					dp++;
29360339a1c2SMark Johnston 				}
29370339a1c2SMark Johnston 			}
29380339a1c2SMark Johnston #ifdef DIS_TEXT
29390339a1c2SMark Johnston 			if (strcmp(dp->it_name, "INVALID") == 0)
29400339a1c2SMark Johnston 				goto error;
29410339a1c2SMark Johnston #endif
29420339a1c2SMark Johnston 			switch (dp->it_adrmode) {
2943c3ddb60eSPeter Grehan 				case RM_66r:
29440339a1c2SMark Johnston 				case XMM_66r:
29450339a1c2SMark Johnston 				case XMMM_66r:
29460339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
29470339a1c2SMark Johnston 						goto error;
29480339a1c2SMark Johnston 					}
29490339a1c2SMark Johnston 					break;
29500339a1c2SMark Johnston 				case XMM_66o:
29510339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
29520339a1c2SMark Johnston 						/* SSSE3 MMX instructions */
29530339a1c2SMark Johnston 						dp_mmx = *dp;
29540339a1c2SMark Johnston 						dp = &dp_mmx;
29550339a1c2SMark Johnston 						dp->it_adrmode = MM;
29560339a1c2SMark Johnston #ifdef	DIS_MEM
29570339a1c2SMark Johnston 						dp->it_size = 8;
29580339a1c2SMark Johnston #endif
29590339a1c2SMark Johnston 					}
29600339a1c2SMark Johnston 					break;
29610339a1c2SMark Johnston 				case CRC32:
29620339a1c2SMark Johnston 					if (rep_prefix != 0xF2) {
29630339a1c2SMark Johnston 						goto error;
29640339a1c2SMark Johnston 					}
29650339a1c2SMark Johnston 					rep_prefix = 0;
29660339a1c2SMark Johnston 					break;
29670339a1c2SMark Johnston 				case MOVBE:
29680339a1c2SMark Johnston 					if (rep_prefix != 0x0) {
29690339a1c2SMark Johnston 						goto error;
29700339a1c2SMark Johnston 					}
29710339a1c2SMark Johnston 					break;
29720339a1c2SMark Johnston 				default:
29730339a1c2SMark Johnston 					goto error;
29740339a1c2SMark Johnston 			}
29750339a1c2SMark Johnston 		} else {
29760339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
29770339a1c2SMark Johnston 		}
29780339a1c2SMark Johnston 	}
29790339a1c2SMark Johnston 
29800339a1c2SMark Johnston 	/*
29810339a1c2SMark Johnston 	 * If still not at a TERM decode entry, then a ModRM byte
29820339a1c2SMark Johnston 	 * exists and its fields further decode the instruction.
29830339a1c2SMark Johnston 	 */
29840339a1c2SMark Johnston 	x->d86_got_modrm = 0;
29850339a1c2SMark Johnston 	if (dp->it_indirect != TERM) {
29860339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
29870339a1c2SMark Johnston 		if (x->d86_error)
29880339a1c2SMark Johnston 			goto error;
29890339a1c2SMark Johnston 		reg = opcode3;
29900339a1c2SMark Johnston 
29910339a1c2SMark Johnston 		/*
29920339a1c2SMark Johnston 		 * decode 287 instructions (D8-DF) from opcodeN
29930339a1c2SMark Johnston 		 */
29940339a1c2SMark Johnston 		if (opcode1 == 0xD && opcode2 >= 0x8) {
29950339a1c2SMark Johnston 			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
29960339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP5[r_m];
29970339a1c2SMark Johnston 			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
29980339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP7[opcode3];
29990339a1c2SMark Johnston 			else if (opcode2 == 0xB && mode == 0x3)
30000339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP6[opcode3];
30010339a1c2SMark Johnston 			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
30020339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
30030339a1c2SMark Johnston 			else if (mode == 0x3)
30040339a1c2SMark Johnston 				dp = (instable_t *)
30050339a1c2SMark Johnston 				    &dis_opFP3[opcode2 - 8][opcode3];
30060339a1c2SMark Johnston 			else
30070339a1c2SMark Johnston 				dp = (instable_t *)
30080339a1c2SMark Johnston 				    &dis_opFP1n2[opcode2 - 8][opcode3];
30090339a1c2SMark Johnston 		} else {
30100339a1c2SMark Johnston 			dp = (instable_t *)dp->it_indirect + opcode3;
30110339a1c2SMark Johnston 		}
30120339a1c2SMark Johnston 	}
30130339a1c2SMark Johnston 
30140339a1c2SMark Johnston 	/*
30150339a1c2SMark Johnston 	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
30160339a1c2SMark Johnston 	 * (sign extend 32bit to 64 bit)
30170339a1c2SMark Johnston 	 */
30180339a1c2SMark Johnston 	if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
30190339a1c2SMark Johnston 	    opcode1 == 0x6 && opcode2 == 0x3)
30200339a1c2SMark Johnston 		dp = (instable_t *)&dis_opMOVSLD;
30210339a1c2SMark Johnston 
30220339a1c2SMark Johnston 	/*
30230339a1c2SMark Johnston 	 * at this point we should have a correct (or invalid) opcode
30240339a1c2SMark Johnston 	 */
30250339a1c2SMark Johnston 	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
30260339a1c2SMark Johnston 	    cpu_mode != SIZE64 && dp->it_invalid32)
30270339a1c2SMark Johnston 		goto error;
30280339a1c2SMark Johnston 	if (dp->it_indirect != TERM)
30290339a1c2SMark Johnston 		goto error;
30300339a1c2SMark Johnston 
30310339a1c2SMark Johnston 	/*
30320339a1c2SMark Johnston 	 * deal with MMX/SSE opcodes which are changed by prefixes
30330339a1c2SMark Johnston 	 */
30340339a1c2SMark Johnston 	switch (dp->it_adrmode) {
30350339a1c2SMark Johnston 	case MMO:
30360339a1c2SMark Johnston 	case MMOIMPL:
30370339a1c2SMark Johnston 	case MMO3P:
30380339a1c2SMark Johnston 	case MMOM3:
30390339a1c2SMark Johnston 	case MMOMS:
30400339a1c2SMark Johnston 	case MMOPM:
30410339a1c2SMark Johnston 	case MMOPRM:
30420339a1c2SMark Johnston 	case MMOS:
30430339a1c2SMark Johnston 	case XMMO:
30440339a1c2SMark Johnston 	case XMMOM:
30450339a1c2SMark Johnston 	case XMMOMS:
30460339a1c2SMark Johnston 	case XMMOPM:
30470339a1c2SMark Johnston 	case XMMOS:
30480339a1c2SMark Johnston 	case XMMOMX:
30490339a1c2SMark Johnston 	case XMMOX3:
30500339a1c2SMark Johnston 	case XMMOXMM:
30510339a1c2SMark Johnston 		/*
30520339a1c2SMark Johnston 		 * This is horrible.  Some SIMD instructions take the
30530339a1c2SMark Johnston 		 * form 0x0F 0x?? ..., which is easily decoded using the
30540339a1c2SMark Johnston 		 * existing tables.  Other SIMD instructions use various
30550339a1c2SMark Johnston 		 * prefix bytes to overload existing instructions.  For
30560339a1c2SMark Johnston 		 * Example, addps is F0, 58, whereas addss is F3 (repz),
30570339a1c2SMark Johnston 		 * F0, 58.  Presumably someone got a raise for this.
30580339a1c2SMark Johnston 		 *
30590339a1c2SMark Johnston 		 * If we see one of the instructions which can be
30600339a1c2SMark Johnston 		 * modified in this way (if we've got one of the SIMDO*
30610339a1c2SMark Johnston 		 * address modes), we'll check to see if the last prefix
30620339a1c2SMark Johnston 		 * was a repz.  If it was, we strip the prefix from the
30630339a1c2SMark Johnston 		 * mnemonic, and we indirect using the dis_opSIMDrepz
30640339a1c2SMark Johnston 		 * table.
30650339a1c2SMark Johnston 		 */
30660339a1c2SMark Johnston 
30670339a1c2SMark Johnston 		/*
30680339a1c2SMark Johnston 		 * Calculate our offset in dis_op0F
30690339a1c2SMark Johnston 		 */
30700339a1c2SMark Johnston 		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
30710339a1c2SMark Johnston 			goto error;
30720339a1c2SMark Johnston 
30730339a1c2SMark Johnston 		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
30740339a1c2SMark Johnston 		    sizeof (instable_t);
30750339a1c2SMark Johnston 
30760339a1c2SMark Johnston 		/*
30770339a1c2SMark Johnston 		 * Rewrite if this instruction used one of the magic prefixes.
30780339a1c2SMark Johnston 		 */
30790339a1c2SMark Johnston 		if (rep_prefix) {
30800339a1c2SMark Johnston 			if (rep_prefix == 0xf2)
30810339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepnz[off];
30820339a1c2SMark Johnston 			else
30830339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepz[off];
30840339a1c2SMark Johnston 			rep_prefix = 0;
30850339a1c2SMark Johnston 		} else if (opnd_size_prefix) {
30860339a1c2SMark Johnston 			dp = (instable_t *)&dis_opSIMDdata16[off];
30870339a1c2SMark Johnston 			opnd_size_prefix = 0;
30880339a1c2SMark Johnston 			if (opnd_size == SIZE16)
30890339a1c2SMark Johnston 				opnd_size = SIZE32;
30900339a1c2SMark Johnston 		}
30910339a1c2SMark Johnston 		break;
30920339a1c2SMark Johnston 
3093c3ddb60eSPeter Grehan 	case MG9:
3094c3ddb60eSPeter Grehan 		/*
3095c3ddb60eSPeter Grehan 		 * More horribleness: the group 9 (0xF0 0xC7) instructions are
3096c3ddb60eSPeter Grehan 		 * allowed an optional prefix of 0x66 or 0xF3.  This is similar
3097c3ddb60eSPeter Grehan 		 * to the SIMD business described above, but with a different
3098c3ddb60eSPeter Grehan 		 * addressing mode (and an indirect table), so we deal with it
3099c3ddb60eSPeter Grehan 		 * separately (if similarly).
3100c3ddb60eSPeter Grehan 		 *
3101c3ddb60eSPeter Grehan 		 * Intel further complicated this with the release of Ivy Bridge
3102c3ddb60eSPeter Grehan 		 * where they overloaded these instructions based on the ModR/M
3103c3ddb60eSPeter Grehan 		 * bytes. The VMX instructions have a mode of 0 since they are
3104c3ddb60eSPeter Grehan 		 * memory instructions but rdrand instructions have a mode of
3105c3ddb60eSPeter Grehan 		 * 0b11 (REG_ONLY) because they only operate on registers. While
3106c3ddb60eSPeter Grehan 		 * there are different prefix formats, for now it is sufficient
3107c3ddb60eSPeter Grehan 		 * to use a single different table.
3108c3ddb60eSPeter Grehan 		 */
3109c3ddb60eSPeter Grehan 
3110c3ddb60eSPeter Grehan 		/*
3111c3ddb60eSPeter Grehan 		 * Calculate our offset in dis_op0FC7 (the group 9 table)
3112c3ddb60eSPeter Grehan 		 */
3113c3ddb60eSPeter Grehan 		if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
3114c3ddb60eSPeter Grehan 			goto error;
3115c3ddb60eSPeter Grehan 
3116c3ddb60eSPeter Grehan 		off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
3117c3ddb60eSPeter Grehan 		    sizeof (instable_t);
3118c3ddb60eSPeter Grehan 
3119c3ddb60eSPeter Grehan 		/*
3120c3ddb60eSPeter Grehan 		 * If we have a mode of 0b11 then we have to rewrite this.
3121c3ddb60eSPeter Grehan 		 */
3122c3ddb60eSPeter Grehan 		dtrace_get_modrm(x, &mode, &reg, &r_m);
3123c3ddb60eSPeter Grehan 		if (mode == REG_ONLY) {
3124c3ddb60eSPeter Grehan 			dp = (instable_t *)&dis_op0FC7m3[off];
3125c3ddb60eSPeter Grehan 			break;
3126c3ddb60eSPeter Grehan 		}
3127c3ddb60eSPeter Grehan 
3128c3ddb60eSPeter Grehan 		/*
3129c3ddb60eSPeter Grehan 		 * Rewrite if this instruction used one of the magic prefixes.
3130c3ddb60eSPeter Grehan 		 */
3131c3ddb60eSPeter Grehan 		if (rep_prefix) {
3132c3ddb60eSPeter Grehan 			if (rep_prefix == 0xf3)
3133c3ddb60eSPeter Grehan 				dp = (instable_t *)&dis_opF30FC7[off];
3134c3ddb60eSPeter Grehan 			else
3135c3ddb60eSPeter Grehan 				goto error;
3136c3ddb60eSPeter Grehan 			rep_prefix = 0;
3137c3ddb60eSPeter Grehan 		} else if (opnd_size_prefix) {
3138c3ddb60eSPeter Grehan 			dp = (instable_t *)&dis_op660FC7[off];
3139c3ddb60eSPeter Grehan 			opnd_size_prefix = 0;
3140c3ddb60eSPeter Grehan 			if (opnd_size == SIZE16)
3141c3ddb60eSPeter Grehan 				opnd_size = SIZE32;
3142c3ddb60eSPeter Grehan 		}
3143c3ddb60eSPeter Grehan 		break;
3144c3ddb60eSPeter Grehan 
3145c3ddb60eSPeter Grehan 
31460339a1c2SMark Johnston 	case MMOSH:
31470339a1c2SMark Johnston 		/*
31480339a1c2SMark Johnston 		 * As with the "normal" SIMD instructions, the MMX
31490339a1c2SMark Johnston 		 * shuffle instructions are overloaded.  These
31500339a1c2SMark Johnston 		 * instructions, however, are special in that they use
31510339a1c2SMark Johnston 		 * an extra byte, and thus an extra table.  As of this
31520339a1c2SMark Johnston 		 * writing, they only use the opnd_size prefix.
31530339a1c2SMark Johnston 		 */
31540339a1c2SMark Johnston 
31550339a1c2SMark Johnston 		/*
31560339a1c2SMark Johnston 		 * Calculate our offset in dis_op0F7123
31570339a1c2SMark Johnston 		 */
31580339a1c2SMark Johnston 		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
31590339a1c2SMark Johnston 		    sizeof (dis_op0F7123))
31600339a1c2SMark Johnston 			goto error;
31610339a1c2SMark Johnston 
31620339a1c2SMark Johnston 		if (opnd_size_prefix) {
31630339a1c2SMark Johnston 			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
31640339a1c2SMark Johnston 			    sizeof (instable_t);
31650339a1c2SMark Johnston 			dp = (instable_t *)&dis_opSIMD7123[off];
31660339a1c2SMark Johnston 			opnd_size_prefix = 0;
31670339a1c2SMark Johnston 			if (opnd_size == SIZE16)
31680339a1c2SMark Johnston 				opnd_size = SIZE32;
31690339a1c2SMark Johnston 		}
31700339a1c2SMark Johnston 		break;
31710339a1c2SMark Johnston 	case MRw:
31720339a1c2SMark Johnston 		if (rep_prefix) {
31730339a1c2SMark Johnston 			if (rep_prefix == 0xf3) {
31740339a1c2SMark Johnston 
31750339a1c2SMark Johnston 				/*
31760339a1c2SMark Johnston 				 * Calculate our offset in dis_op0F
31770339a1c2SMark Johnston 				 */
31780339a1c2SMark Johnston 				if ((uintptr_t)dp - (uintptr_t)dis_op0F
31790339a1c2SMark Johnston 				    > sizeof (dis_op0F))
31800339a1c2SMark Johnston 					goto error;
31810339a1c2SMark Johnston 
31820339a1c2SMark Johnston 				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
31830339a1c2SMark Johnston 				    sizeof (instable_t);
31840339a1c2SMark Johnston 
31850339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepz[off];
31860339a1c2SMark Johnston 				rep_prefix = 0;
31870339a1c2SMark Johnston 			} else {
31880339a1c2SMark Johnston 				goto error;
31890339a1c2SMark Johnston 			}
31900339a1c2SMark Johnston 		}
31910339a1c2SMark Johnston 		break;
31920339a1c2SMark Johnston 	}
31930339a1c2SMark Johnston 
31940339a1c2SMark Johnston 	/*
31950339a1c2SMark Johnston 	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
31960339a1c2SMark Johnston 	 */
31970339a1c2SMark Johnston 	if (cpu_mode == SIZE64)
31980339a1c2SMark Johnston 		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
31990339a1c2SMark Johnston 			opnd_size = SIZE64;
32000339a1c2SMark Johnston 
32010339a1c2SMark Johnston #ifdef DIS_TEXT
32020339a1c2SMark Johnston 	/*
32030339a1c2SMark Johnston 	 * At this point most instructions can format the opcode mnemonic
32040339a1c2SMark Johnston 	 * including the prefixes.
32050339a1c2SMark Johnston 	 */
32060339a1c2SMark Johnston 	if (lock_prefix)
32070339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
32080339a1c2SMark Johnston 
32090339a1c2SMark Johnston 	if (rep_prefix == 0xf2)
32100339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
32110339a1c2SMark Johnston 	else if (rep_prefix == 0xf3)
32120339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
32130339a1c2SMark Johnston 
32140339a1c2SMark Johnston 	if (cpu_mode == SIZE64 && addr_size_prefix)
32150339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
32160339a1c2SMark Johnston 
32170339a1c2SMark Johnston 	if (dp->it_adrmode != CBW &&
32180339a1c2SMark Johnston 	    dp->it_adrmode != CWD &&
32190339a1c2SMark Johnston 	    dp->it_adrmode != XMMSFNC) {
32200339a1c2SMark Johnston 		if (strcmp(dp->it_name, "INVALID") == 0)
32210339a1c2SMark Johnston 			goto error;
32220339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
32230339a1c2SMark Johnston 		if (dp->it_suffix) {
32240339a1c2SMark Johnston 			char *types[] = {"", "w", "l", "q"};
32250339a1c2SMark Johnston 			if (opcode_bytes == 2 && opcode4 == 4) {
32260339a1c2SMark Johnston 				/* It's a cmovx.yy. Replace the suffix x */
32270339a1c2SMark Johnston 				for (i = 5; i < OPLEN; i++) {
32280339a1c2SMark Johnston 					if (x->d86_mnem[i] == '.')
32290339a1c2SMark Johnston 						break;
32300339a1c2SMark Johnston 				}
32310339a1c2SMark Johnston 				x->d86_mnem[i - 1] = *types[opnd_size];
32320339a1c2SMark Johnston 			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
32330339a1c2SMark Johnston 			    ((opcode6 == 1 && opcode7 == 6) ||
32340339a1c2SMark Johnston 			    (opcode6 == 2 && opcode7 == 2))) {
32350339a1c2SMark Johnston 				/*
32360339a1c2SMark Johnston 				 * To handle PINSRD and PEXTRD
32370339a1c2SMark Johnston 				 */
32380339a1c2SMark Johnston 				(void) strlcat(x->d86_mnem, "d", OPLEN);
32390339a1c2SMark Johnston 			} else {
32400339a1c2SMark Johnston 				(void) strlcat(x->d86_mnem, types[opnd_size],
32410339a1c2SMark Johnston 				    OPLEN);
32420339a1c2SMark Johnston 			}
32430339a1c2SMark Johnston 		}
32440339a1c2SMark Johnston 	}
32450339a1c2SMark Johnston #endif
32460339a1c2SMark Johnston 
32470339a1c2SMark Johnston 	/*
32480339a1c2SMark Johnston 	 * Process operands based on the addressing modes.
32490339a1c2SMark Johnston 	 */
32500339a1c2SMark Johnston 	x->d86_mode = cpu_mode;
32510339a1c2SMark Johnston 	/*
32520339a1c2SMark Johnston 	 * In vex mode the rex_prefix has no meaning
32530339a1c2SMark Johnston 	 */
32540339a1c2SMark Johnston 	if (!vex_prefix)
32550339a1c2SMark Johnston 		x->d86_rex_prefix = rex_prefix;
32560339a1c2SMark Johnston 	x->d86_opnd_size = opnd_size;
32570339a1c2SMark Johnston 	x->d86_addr_size = addr_size;
32580339a1c2SMark Johnston 	vbit = 0;		/* initialize for mem/reg -> reg */
32590339a1c2SMark Johnston 	switch (dp->it_adrmode) {
32600339a1c2SMark Johnston 		/*
32610339a1c2SMark Johnston 		 * amd64 instruction to sign extend 32 bit reg/mem operands
32620339a1c2SMark Johnston 		 * into 64 bit register values
32630339a1c2SMark Johnston 		 */
32640339a1c2SMark Johnston 	case MOVSXZ:
32650339a1c2SMark Johnston #ifdef DIS_TEXT
32660339a1c2SMark Johnston 		if (rex_prefix == 0)
32670339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
32680339a1c2SMark Johnston #endif
32690339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
32700339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
32710339a1c2SMark Johnston 		x->d86_opnd_size = SIZE64;
32720339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
32730339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size = SIZE32;
32740339a1c2SMark Johnston 		wbit = LONG_OPND;
32750339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
32760339a1c2SMark Johnston 		break;
32770339a1c2SMark Johnston 
32780339a1c2SMark Johnston 		/*
32790339a1c2SMark Johnston 		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
32800339a1c2SMark Johnston 		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
32810339a1c2SMark Johnston 		 * wbit lives in 2nd byte, note that operands
32820339a1c2SMark Johnston 		 * are different sized
32830339a1c2SMark Johnston 		 */
32840339a1c2SMark Johnston 	case MOVZ:
32850339a1c2SMark Johnston 		if (rex_prefix & REX_W) {
32860339a1c2SMark Johnston 			/* target register size = 64 bit */
32870339a1c2SMark Johnston 			x->d86_mnem[5] = 'q';
32880339a1c2SMark Johnston 		}
32890339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
32900339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
32910339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
32920339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size = SIZE16;
32930339a1c2SMark Johnston 		wbit = WBIT(opcode5);
32940339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
32950339a1c2SMark Johnston 		break;
32960339a1c2SMark Johnston 	case CRC32:
32970339a1c2SMark Johnston 		opnd_size = SIZE32;
32980339a1c2SMark Johnston 		if (rex_prefix & REX_W)
32990339a1c2SMark Johnston 			opnd_size = SIZE64;
33000339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size;
33010339a1c2SMark Johnston 
33020339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
33030339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
33040339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
33050339a1c2SMark Johnston 		wbit = WBIT(opcode7);
33060339a1c2SMark Johnston 		if (opnd_size_prefix)
33070339a1c2SMark Johnston 			x->d86_opnd_size = opnd_size = SIZE16;
33080339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
33090339a1c2SMark Johnston 		break;
33100339a1c2SMark Johnston 	case MOVBE:
33110339a1c2SMark Johnston 		opnd_size = SIZE32;
33120339a1c2SMark Johnston 		if (rex_prefix & REX_W)
33130339a1c2SMark Johnston 			opnd_size = SIZE64;
33140339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size;
33150339a1c2SMark Johnston 
33160339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
33170339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
33180339a1c2SMark Johnston 		wbit = WBIT(opcode7);
33190339a1c2SMark Johnston 		if (opnd_size_prefix)
33200339a1c2SMark Johnston 			x->d86_opnd_size = opnd_size = SIZE16;
33210339a1c2SMark Johnston 		if (wbit) {
33220339a1c2SMark Johnston 			/* reg -> mem */
33230339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
33240339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
33250339a1c2SMark Johnston 		} else {
33260339a1c2SMark Johnston 			/* mem -> reg */
33270339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
33280339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
33290339a1c2SMark Johnston 		}
33300339a1c2SMark Johnston 		break;
33310339a1c2SMark Johnston 
33320339a1c2SMark Johnston 	/*
33330339a1c2SMark Johnston 	 * imul instruction, with either 8-bit or longer immediate
33340339a1c2SMark Johnston 	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
33350339a1c2SMark Johnston 	 */
33360339a1c2SMark Johnston 	case IMUL:
33370339a1c2SMark Johnston 		wbit = LONG_OPND;
33380339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
33390339a1c2SMark Johnston 		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
33400339a1c2SMark Johnston 		break;
33410339a1c2SMark Johnston 
33420339a1c2SMark Johnston 	/* memory or register operand to register, with 'w' bit	*/
33430339a1c2SMark Johnston 	case MRw:
33440339a1c2SMark Johnston 		wbit = WBIT(opcode2);
33450339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
33460339a1c2SMark Johnston 		break;
33470339a1c2SMark Johnston 
33480339a1c2SMark Johnston 	/* register to memory or register operand, with 'w' bit	*/
33490339a1c2SMark Johnston 	/* arpl happens to fit here also because it is odd */
33500339a1c2SMark Johnston 	case RMw:
33510339a1c2SMark Johnston 		if (opcode_bytes == 2)
33520339a1c2SMark Johnston 			wbit = WBIT(opcode5);
33530339a1c2SMark Johnston 		else
33540339a1c2SMark Johnston 			wbit = WBIT(opcode2);
33550339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
33560339a1c2SMark Johnston 		break;
33570339a1c2SMark Johnston 
33580339a1c2SMark Johnston 	/* xaddb instruction */
33590339a1c2SMark Johnston 	case XADDB:
33600339a1c2SMark Johnston 		wbit = 0;
33610339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
33620339a1c2SMark Johnston 		break;
33630339a1c2SMark Johnston 
33640339a1c2SMark Johnston 	/* MMX register to memory or register operand		*/
33650339a1c2SMark Johnston 	case MMS:
33660339a1c2SMark Johnston 	case MMOS:
33670339a1c2SMark Johnston #ifdef DIS_TEXT
33680339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
33690339a1c2SMark Johnston #else
33700339a1c2SMark Johnston 		wbit = LONG_OPND;
33710339a1c2SMark Johnston #endif
33720339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
33730339a1c2SMark Johnston 		break;
33740339a1c2SMark Johnston 
33750339a1c2SMark Johnston 	/* MMX register to memory */
33760339a1c2SMark Johnston 	case MMOMS:
33770339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
33780339a1c2SMark Johnston 		if (mode == REG_ONLY)
33790339a1c2SMark Johnston 			goto error;
33800339a1c2SMark Johnston 		wbit = MM_OPND;
33810339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
33820339a1c2SMark Johnston 		break;
33830339a1c2SMark Johnston 
33840339a1c2SMark Johnston 	/* Double shift. Has immediate operand specifying the shift. */
33850339a1c2SMark Johnston 	case DSHIFT:
33860339a1c2SMark Johnston 		wbit = LONG_OPND;
33870339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
33880339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
33890339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
33900339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
33910339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
33920339a1c2SMark Johnston 		break;
33930339a1c2SMark Johnston 
33940339a1c2SMark Johnston 	/*
33950339a1c2SMark Johnston 	 * Double shift. With no immediate operand, specifies using %cl.
33960339a1c2SMark Johnston 	 */
33970339a1c2SMark Johnston 	case DSHIFTcl:
33980339a1c2SMark Johnston 		wbit = LONG_OPND;
33990339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
34000339a1c2SMark Johnston 		break;
34010339a1c2SMark Johnston 
34020339a1c2SMark Johnston 	/* immediate to memory or register operand */
34030339a1c2SMark Johnston 	case IMlw:
34040339a1c2SMark Johnston 		wbit = WBIT(opcode2);
34050339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
34060339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
34070339a1c2SMark Johnston 		/*
34080339a1c2SMark Johnston 		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
34090339a1c2SMark Johnston 		 */
34100339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
34110339a1c2SMark Johnston 		break;
34120339a1c2SMark Johnston 
34130339a1c2SMark Johnston 	/* immediate to memory or register operand with the	*/
34140339a1c2SMark Johnston 	/* 'w' bit present					*/
34150339a1c2SMark Johnston 	case IMw:
34160339a1c2SMark Johnston 		wbit = WBIT(opcode2);
34170339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
34180339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
34190339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
34200339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
34210339a1c2SMark Johnston 		break;
34220339a1c2SMark Johnston 
34230339a1c2SMark Johnston 	/* immediate to register with register in low 3 bits	*/
34240339a1c2SMark Johnston 	/* of op code						*/
34250339a1c2SMark Johnston 	case IR:
34260339a1c2SMark Johnston 		/* w-bit here (with regs) is bit 3 */
34270339a1c2SMark Johnston 		wbit = opcode2 >>3 & 0x1;
34280339a1c2SMark Johnston 		reg = REGNO(opcode2);
34290339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
34300339a1c2SMark Johnston 		mode = REG_ONLY;
34310339a1c2SMark Johnston 		r_m = reg;
34320339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
34330339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
34340339a1c2SMark Johnston 		break;
34350339a1c2SMark Johnston 
34360339a1c2SMark Johnston 	/* MMX immediate shift of register */
34370339a1c2SMark Johnston 	case MMSH:
34380339a1c2SMark Johnston 	case MMOSH:
34390339a1c2SMark Johnston 		wbit = MM_OPND;
34400339a1c2SMark Johnston 		goto mm_shift;	/* in next case */
34410339a1c2SMark Johnston 
34420339a1c2SMark Johnston 	/* SIMD immediate shift of register */
34430339a1c2SMark Johnston 	case XMMSH:
34440339a1c2SMark Johnston 		wbit = XMM_OPND;
34450339a1c2SMark Johnston mm_shift:
34460339a1c2SMark Johnston 		reg = REGNO(opcode7);
34470339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
34480339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
34490339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
34500339a1c2SMark Johnston 		NOMEM;
34510339a1c2SMark Johnston 		break;
34520339a1c2SMark Johnston 
34530339a1c2SMark Johnston 	/* accumulator to memory operand */
34540339a1c2SMark Johnston 	case AO:
34550339a1c2SMark Johnston 		vbit = 1;
34560339a1c2SMark Johnston 		/*FALLTHROUGH*/
34570339a1c2SMark Johnston 
34580339a1c2SMark Johnston 	/* memory operand to accumulator */
34590339a1c2SMark Johnston 	case OA:
34600339a1c2SMark Johnston 		wbit = WBIT(opcode2);
34610339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
34620339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
34630339a1c2SMark Johnston #ifdef DIS_TEXT
34640339a1c2SMark Johnston 		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
34650339a1c2SMark Johnston #endif
34660339a1c2SMark Johnston 		break;
34670339a1c2SMark Johnston 
34680339a1c2SMark Johnston 
34690339a1c2SMark Johnston 	/* segment register to memory or register operand */
34700339a1c2SMark Johnston 	case SM:
34710339a1c2SMark Johnston 		vbit = 1;
34720339a1c2SMark Johnston 		/*FALLTHROUGH*/
34730339a1c2SMark Johnston 
34740339a1c2SMark Johnston 	/* memory or register operand to segment register */
34750339a1c2SMark Johnston 	case MS:
34760339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
34770339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
34780339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
34790339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
34800339a1c2SMark Johnston 		break;
34810339a1c2SMark Johnston 
34820339a1c2SMark Johnston 	/*
34830339a1c2SMark Johnston 	 * rotate or shift instructions, which may shift by 1 or
34840339a1c2SMark Johnston 	 * consult the cl register, depending on the 'v' bit
34850339a1c2SMark Johnston 	 */
34860339a1c2SMark Johnston 	case Mv:
34870339a1c2SMark Johnston 		vbit = VBIT(opcode2);
34880339a1c2SMark Johnston 		wbit = WBIT(opcode2);
34890339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
34900339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
34910339a1c2SMark Johnston #ifdef DIS_TEXT
34920339a1c2SMark Johnston 		if (vbit) {
34930339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
34940339a1c2SMark Johnston 		} else {
34950339a1c2SMark Johnston 			x->d86_opnd[0].d86_mode = MODE_SIGNED;
34960339a1c2SMark Johnston 			x->d86_opnd[0].d86_value_size = 1;
34970339a1c2SMark Johnston 			x->d86_opnd[0].d86_value = 1;
34980339a1c2SMark Johnston 		}
34990339a1c2SMark Johnston #endif
35000339a1c2SMark Johnston 		break;
35010339a1c2SMark Johnston 	/*
35020339a1c2SMark Johnston 	 * immediate rotate or shift instructions
35030339a1c2SMark Johnston 	 */
35040339a1c2SMark Johnston 	case MvI:
35050339a1c2SMark Johnston 		wbit = WBIT(opcode2);
35060339a1c2SMark Johnston normal_imm_mem:
35070339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
35080339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
35090339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
35100339a1c2SMark Johnston 		break;
35110339a1c2SMark Johnston 
35120339a1c2SMark Johnston 	/* bit test instructions */
35130339a1c2SMark Johnston 	case MIb:
35140339a1c2SMark Johnston 		wbit = LONG_OPND;
35150339a1c2SMark Johnston 		goto normal_imm_mem;
35160339a1c2SMark Johnston 
35170339a1c2SMark Johnston 	/* single memory or register operand with 'w' bit present */
35180339a1c2SMark Johnston 	case Mw:
35190339a1c2SMark Johnston 		wbit = WBIT(opcode2);
35200339a1c2SMark Johnston just_mem:
35210339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
35220339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
35230339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
35240339a1c2SMark Johnston 		break;
35250339a1c2SMark Johnston 
3526c3ddb60eSPeter Grehan 	case SWAPGS_RDTSCP:
35270339a1c2SMark Johnston 		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
35280339a1c2SMark Johnston #ifdef DIS_TEXT
35290339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
35300339a1c2SMark Johnston #endif
35310339a1c2SMark Johnston 			NOMEM;
35320339a1c2SMark Johnston 			break;
3533c3ddb60eSPeter Grehan 		} else if (mode == 3 && r_m == 1) {
3534c3ddb60eSPeter Grehan #ifdef DIS_TEXT
3535c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, "rdtscp", OPLEN);
3536c3ddb60eSPeter Grehan #endif
3537c3ddb60eSPeter Grehan 			NOMEM;
3538c3ddb60eSPeter Grehan 			break;
35390339a1c2SMark Johnston 		}
3540c3ddb60eSPeter Grehan 
35410339a1c2SMark Johnston 		/*FALLTHROUGH*/
35420339a1c2SMark Johnston 
35430339a1c2SMark Johnston 	/* prefetch instruction - memory operand, but no memory acess */
35440339a1c2SMark Johnston 	case PREF:
35450339a1c2SMark Johnston 		NOMEM;
35460339a1c2SMark Johnston 		/*FALLTHROUGH*/
35470339a1c2SMark Johnston 
35480339a1c2SMark Johnston 	/* single memory or register operand */
35490339a1c2SMark Johnston 	case M:
3550c3ddb60eSPeter Grehan 	case MG9:
35510339a1c2SMark Johnston 		wbit = LONG_OPND;
35520339a1c2SMark Johnston 		goto just_mem;
35530339a1c2SMark Johnston 
35540339a1c2SMark Johnston 	/* single memory or register byte operand */
35550339a1c2SMark Johnston 	case Mb:
35560339a1c2SMark Johnston 		wbit = BYTE_OPND;
35570339a1c2SMark Johnston 		goto just_mem;
35580339a1c2SMark Johnston 
3559c3ddb60eSPeter Grehan 	case VMx:
3560c3ddb60eSPeter Grehan 		if (mode == 3) {
3561c3ddb60eSPeter Grehan #ifdef DIS_TEXT
3562c3ddb60eSPeter Grehan 			char *vminstr;
3563c3ddb60eSPeter Grehan 
3564c3ddb60eSPeter Grehan 			switch (r_m) {
3565c3ddb60eSPeter Grehan 			case 1:
3566c3ddb60eSPeter Grehan 				vminstr = "vmcall";
3567c3ddb60eSPeter Grehan 				break;
3568c3ddb60eSPeter Grehan 			case 2:
3569c3ddb60eSPeter Grehan 				vminstr = "vmlaunch";
3570c3ddb60eSPeter Grehan 				break;
3571c3ddb60eSPeter Grehan 			case 3:
3572c3ddb60eSPeter Grehan 				vminstr = "vmresume";
3573c3ddb60eSPeter Grehan 				break;
3574c3ddb60eSPeter Grehan 			case 4:
3575c3ddb60eSPeter Grehan 				vminstr = "vmxoff";
3576c3ddb60eSPeter Grehan 				break;
3577c3ddb60eSPeter Grehan 			default:
3578c3ddb60eSPeter Grehan 				goto error;
3579c3ddb60eSPeter Grehan 			}
3580c3ddb60eSPeter Grehan 
3581c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, vminstr, OPLEN);
3582c3ddb60eSPeter Grehan #else
3583c3ddb60eSPeter Grehan 			if (r_m < 1 || r_m > 4)
3584c3ddb60eSPeter Grehan 				goto error;
3585c3ddb60eSPeter Grehan #endif
3586c3ddb60eSPeter Grehan 
3587c3ddb60eSPeter Grehan 			NOMEM;
3588c3ddb60eSPeter Grehan 			break;
3589c3ddb60eSPeter Grehan 		}
3590c3ddb60eSPeter Grehan 		/*FALLTHROUGH*/
3591c3ddb60eSPeter Grehan 	case SVM:
3592c3ddb60eSPeter Grehan 		if (mode == 3) {
3593c3ddb60eSPeter Grehan #ifdef DIS_TEXT
3594c3ddb60eSPeter Grehan 			char *vinstr;
3595c3ddb60eSPeter Grehan 
3596c3ddb60eSPeter Grehan 			switch (r_m) {
3597c3ddb60eSPeter Grehan 			case 0:
3598c3ddb60eSPeter Grehan 				vinstr = "vmrun";
3599c3ddb60eSPeter Grehan 				break;
3600c3ddb60eSPeter Grehan 			case 1:
3601c3ddb60eSPeter Grehan 				vinstr = "vmmcall";
3602c3ddb60eSPeter Grehan 				break;
3603c3ddb60eSPeter Grehan 			case 2:
3604c3ddb60eSPeter Grehan 				vinstr = "vmload";
3605c3ddb60eSPeter Grehan 				break;
3606c3ddb60eSPeter Grehan 			case 3:
3607c3ddb60eSPeter Grehan 				vinstr = "vmsave";
3608c3ddb60eSPeter Grehan 				break;
3609c3ddb60eSPeter Grehan 			case 4:
3610c3ddb60eSPeter Grehan 				vinstr = "stgi";
3611c3ddb60eSPeter Grehan 				break;
3612c3ddb60eSPeter Grehan 			case 5:
3613c3ddb60eSPeter Grehan 				vinstr = "clgi";
3614c3ddb60eSPeter Grehan 				break;
3615c3ddb60eSPeter Grehan 			case 6:
3616c3ddb60eSPeter Grehan 				vinstr = "skinit";
3617c3ddb60eSPeter Grehan 				break;
3618c3ddb60eSPeter Grehan 			case 7:
3619c3ddb60eSPeter Grehan 				vinstr = "invlpga";
3620c3ddb60eSPeter Grehan 				break;
3621c3ddb60eSPeter Grehan 			}
3622c3ddb60eSPeter Grehan 
3623c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, vinstr, OPLEN);
3624c3ddb60eSPeter Grehan #endif
3625c3ddb60eSPeter Grehan 			NOMEM;
3626c3ddb60eSPeter Grehan 			break;
3627c3ddb60eSPeter Grehan 		}
3628c3ddb60eSPeter Grehan 		/*FALLTHROUGH*/
36290339a1c2SMark Johnston 	case MONITOR_MWAIT:
36300339a1c2SMark Johnston 		if (mode == 3) {
36310339a1c2SMark Johnston 			if (r_m == 0) {
36320339a1c2SMark Johnston #ifdef DIS_TEXT
36330339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
36340339a1c2SMark Johnston #endif
36350339a1c2SMark Johnston 				NOMEM;
36360339a1c2SMark Johnston 				break;
36370339a1c2SMark Johnston 			} else if (r_m == 1) {
36380339a1c2SMark Johnston #ifdef DIS_TEXT
36390339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
36400339a1c2SMark Johnston #endif
36410339a1c2SMark Johnston 				NOMEM;
36420339a1c2SMark Johnston 				break;
36430339a1c2SMark Johnston 			} else {
36440339a1c2SMark Johnston 				goto error;
36450339a1c2SMark Johnston 			}
36460339a1c2SMark Johnston 		}
36470339a1c2SMark Johnston 		/*FALLTHROUGH*/
36480339a1c2SMark Johnston 	case XGETBV_XSETBV:
36490339a1c2SMark Johnston 		if (mode == 3) {
36500339a1c2SMark Johnston 			if (r_m == 0) {
36510339a1c2SMark Johnston #ifdef DIS_TEXT
36520339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
36530339a1c2SMark Johnston #endif
36540339a1c2SMark Johnston 				NOMEM;
36550339a1c2SMark Johnston 				break;
36560339a1c2SMark Johnston 			} else if (r_m == 1) {
36570339a1c2SMark Johnston #ifdef DIS_TEXT
36580339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
36590339a1c2SMark Johnston #endif
36600339a1c2SMark Johnston 				NOMEM;
36610339a1c2SMark Johnston 				break;
36620339a1c2SMark Johnston 			} else {
36630339a1c2SMark Johnston 				goto error;
36640339a1c2SMark Johnston 			}
36650339a1c2SMark Johnston 
36660339a1c2SMark Johnston 		}
36670339a1c2SMark Johnston 		/*FALLTHROUGH*/
36680339a1c2SMark Johnston 	case MO:
36690339a1c2SMark Johnston 		/* Similar to M, but only memory (no direct registers) */
36700339a1c2SMark Johnston 		wbit = LONG_OPND;
36710339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
36720339a1c2SMark Johnston 		if (mode == 3)
36730339a1c2SMark Johnston 			goto error;
36740339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
36750339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
36760339a1c2SMark Johnston 		break;
36770339a1c2SMark Johnston 
36780339a1c2SMark Johnston 	/* move special register to register or reverse if vbit */
36790339a1c2SMark Johnston 	case SREG:
36800339a1c2SMark Johnston 		switch (opcode5) {
36810339a1c2SMark Johnston 
36820339a1c2SMark Johnston 		case 2:
36830339a1c2SMark Johnston 			vbit = 1;
36840339a1c2SMark Johnston 			/*FALLTHROUGH*/
36850339a1c2SMark Johnston 		case 0:
36860339a1c2SMark Johnston 			wbit = CONTROL_OPND;
36870339a1c2SMark Johnston 			break;
36880339a1c2SMark Johnston 
36890339a1c2SMark Johnston 		case 3:
36900339a1c2SMark Johnston 			vbit = 1;
36910339a1c2SMark Johnston 			/*FALLTHROUGH*/
36920339a1c2SMark Johnston 		case 1:
36930339a1c2SMark Johnston 			wbit = DEBUG_OPND;
36940339a1c2SMark Johnston 			break;
36950339a1c2SMark Johnston 
36960339a1c2SMark Johnston 		case 6:
36970339a1c2SMark Johnston 			vbit = 1;
36980339a1c2SMark Johnston 			/*FALLTHROUGH*/
36990339a1c2SMark Johnston 		case 4:
37000339a1c2SMark Johnston 			wbit = TEST_OPND;
37010339a1c2SMark Johnston 			break;
37020339a1c2SMark Johnston 
37030339a1c2SMark Johnston 		}
37040339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37050339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37060339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
37070339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
37080339a1c2SMark Johnston 		NOMEM;
37090339a1c2SMark Johnston 		break;
37100339a1c2SMark Johnston 
37110339a1c2SMark Johnston 	/*
37120339a1c2SMark Johnston 	 * single register operand with register in the low 3
37130339a1c2SMark Johnston 	 * bits of op code
37140339a1c2SMark Johnston 	 */
37150339a1c2SMark Johnston 	case R:
37160339a1c2SMark Johnston 		if (opcode_bytes == 2)
37170339a1c2SMark Johnston 			reg = REGNO(opcode5);
37180339a1c2SMark Johnston 		else
37190339a1c2SMark Johnston 			reg = REGNO(opcode2);
37200339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
37210339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
37220339a1c2SMark Johnston 		NOMEM;
37230339a1c2SMark Johnston 		break;
37240339a1c2SMark Johnston 
37250339a1c2SMark Johnston 	/*
37260339a1c2SMark Johnston 	 * register to accumulator with register in the low 3
37270339a1c2SMark Johnston 	 * bits of op code, xchg instructions
37280339a1c2SMark Johnston 	 */
37290339a1c2SMark Johnston 	case RA:
37300339a1c2SMark Johnston 		NOMEM;
37310339a1c2SMark Johnston 		reg = REGNO(opcode2);
37320339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
37330339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
37340339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
37350339a1c2SMark Johnston 		break;
37360339a1c2SMark Johnston 
37370339a1c2SMark Johnston 	/*
37380339a1c2SMark Johnston 	 * single segment register operand, with register in
37390339a1c2SMark Johnston 	 * bits 3-4 of op code byte
37400339a1c2SMark Johnston 	 */
37410339a1c2SMark Johnston 	case SEG:
37420339a1c2SMark Johnston 		NOMEM;
37430339a1c2SMark Johnston 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
37440339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
37450339a1c2SMark Johnston 		break;
37460339a1c2SMark Johnston 
37470339a1c2SMark Johnston 	/*
37480339a1c2SMark Johnston 	 * single segment register operand, with register in
37490339a1c2SMark Johnston 	 * bits 3-5 of op code
37500339a1c2SMark Johnston 	 */
37510339a1c2SMark Johnston 	case LSEG:
37520339a1c2SMark Johnston 		NOMEM;
37530339a1c2SMark Johnston 		/* long seg reg from opcode */
37540339a1c2SMark Johnston 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
37550339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
37560339a1c2SMark Johnston 		break;
37570339a1c2SMark Johnston 
37580339a1c2SMark Johnston 	/* memory or register operand to register */
37590339a1c2SMark Johnston 	case MR:
37600339a1c2SMark Johnston 		if (vex_prefetch)
37610339a1c2SMark Johnston 			x->d86_got_modrm = 1;
37620339a1c2SMark Johnston 		wbit = LONG_OPND;
37630339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
37640339a1c2SMark Johnston 		break;
37650339a1c2SMark Johnston 
37660339a1c2SMark Johnston 	case RM:
3767c3ddb60eSPeter Grehan 	case RM_66r:
37680339a1c2SMark Johnston 		wbit = LONG_OPND;
37690339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
37700339a1c2SMark Johnston 		break;
37710339a1c2SMark Johnston 
37720339a1c2SMark Johnston 	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
37730339a1c2SMark Johnston 	case MM:
37740339a1c2SMark Johnston 	case MMO:
37750339a1c2SMark Johnston #ifdef DIS_TEXT
37760339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
37770339a1c2SMark Johnston #else
37780339a1c2SMark Johnston 		wbit = LONG_OPND;
37790339a1c2SMark Johnston #endif
37800339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
37810339a1c2SMark Johnston 		break;
37820339a1c2SMark Johnston 
37830339a1c2SMark Johnston 	case MMOIMPL:
37840339a1c2SMark Johnston #ifdef DIS_TEXT
37850339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
37860339a1c2SMark Johnston #else
37870339a1c2SMark Johnston 		wbit = LONG_OPND;
37880339a1c2SMark Johnston #endif
37890339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37900339a1c2SMark Johnston 		if (mode != REG_ONLY)
37910339a1c2SMark Johnston 			goto error;
37920339a1c2SMark Johnston 
37930339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37940339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
37950339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
37960339a1c2SMark Johnston 		mode = 0;	/* change for memory access size... */
37970339a1c2SMark Johnston 		break;
37980339a1c2SMark Johnston 
37990339a1c2SMark Johnston 	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
38000339a1c2SMark Johnston 	case MMO3P:
38010339a1c2SMark Johnston 		wbit = MM_OPND;
38020339a1c2SMark Johnston 		goto xmm3p;
38030339a1c2SMark Johnston 	case XMM3P:
38040339a1c2SMark Johnston 		wbit = XMM_OPND;
38050339a1c2SMark Johnston xmm3p:
38060339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38070339a1c2SMark Johnston 		if (mode != REG_ONLY)
38080339a1c2SMark Johnston 			goto error;
38090339a1c2SMark Johnston 
38100339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
38110339a1c2SMark Johnston 		    1);
38120339a1c2SMark Johnston 		NOMEM;
38130339a1c2SMark Johnston 		break;
38140339a1c2SMark Johnston 
38150339a1c2SMark Johnston 	case XMM3PM_66r:
38160339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
38170339a1c2SMark Johnston 		    1, 0);
38180339a1c2SMark Johnston 		break;
38190339a1c2SMark Johnston 
38200339a1c2SMark Johnston 	/* MMX/SIMD-Int predicated r32/mem to mm reg */
38210339a1c2SMark Johnston 	case MMOPRM:
38220339a1c2SMark Johnston 		wbit = LONG_OPND;
38230339a1c2SMark Johnston 		w2 = MM_OPND;
38240339a1c2SMark Johnston 		goto xmmprm;
38250339a1c2SMark Johnston 	case XMMPRM:
38260339a1c2SMark Johnston 	case XMMPRM_66r:
38270339a1c2SMark Johnston 		wbit = LONG_OPND;
38280339a1c2SMark Johnston 		w2 = XMM_OPND;
38290339a1c2SMark Johnston xmmprm:
38300339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
38310339a1c2SMark Johnston 		break;
38320339a1c2SMark Johnston 
38330339a1c2SMark Johnston 	/* MMX/SIMD-Int predicated mm/mem to mm reg */
38340339a1c2SMark Johnston 	case MMOPM:
38350339a1c2SMark Johnston 	case MMOPM_66o:
38360339a1c2SMark Johnston 		wbit = w2 = MM_OPND;
38370339a1c2SMark Johnston 		goto xmmprm;
38380339a1c2SMark Johnston 
38390339a1c2SMark Johnston 	/* MMX/SIMD-Int mm reg to r32 */
38400339a1c2SMark Johnston 	case MMOM3:
38410339a1c2SMark Johnston 		NOMEM;
38420339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38430339a1c2SMark Johnston 		if (mode != REG_ONLY)
38440339a1c2SMark Johnston 			goto error;
38450339a1c2SMark Johnston 		wbit = MM_OPND;
38460339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
38470339a1c2SMark Johnston 		break;
38480339a1c2SMark Johnston 
38490339a1c2SMark Johnston 	/* SIMD memory or xmm reg operand to xmm reg		*/
38500339a1c2SMark Johnston 	case XMM:
38510339a1c2SMark Johnston 	case XMM_66o:
38520339a1c2SMark Johnston 	case XMM_66r:
38530339a1c2SMark Johnston 	case XMMO:
38540339a1c2SMark Johnston 	case XMMXIMPL:
38550339a1c2SMark Johnston 		wbit = XMM_OPND;
38560339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
38570339a1c2SMark Johnston 
38580339a1c2SMark Johnston 		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
38590339a1c2SMark Johnston 			goto error;
38600339a1c2SMark Johnston 
38610339a1c2SMark Johnston #ifdef DIS_TEXT
38620339a1c2SMark Johnston 		/*
38630339a1c2SMark Johnston 		 * movlps and movhlps share opcodes.  They differ in the
38640339a1c2SMark Johnston 		 * addressing modes allowed for their operands.
38650339a1c2SMark Johnston 		 * movhps and movlhps behave similarly.
38660339a1c2SMark Johnston 		 */
38670339a1c2SMark Johnston 		if (mode == REG_ONLY) {
38680339a1c2SMark Johnston 			if (strcmp(dp->it_name, "movlps") == 0)
38690339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
38700339a1c2SMark Johnston 			else if (strcmp(dp->it_name, "movhps") == 0)
38710339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
38720339a1c2SMark Johnston 		}
38730339a1c2SMark Johnston #endif
38740339a1c2SMark Johnston 		if (dp->it_adrmode == XMMXIMPL)
38750339a1c2SMark Johnston 			mode = 0;	/* change for memory access size... */
38760339a1c2SMark Johnston 		break;
38770339a1c2SMark Johnston 
38780339a1c2SMark Johnston 	/* SIMD xmm reg to memory or xmm reg */
38790339a1c2SMark Johnston 	case XMMS:
38800339a1c2SMark Johnston 	case XMMOS:
38810339a1c2SMark Johnston 	case XMMMS:
38820339a1c2SMark Johnston 	case XMMOMS:
38830339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38840339a1c2SMark Johnston #ifdef DIS_TEXT
38850339a1c2SMark Johnston 		if ((strcmp(dp->it_name, "movlps") == 0 ||
38860339a1c2SMark Johnston 		    strcmp(dp->it_name, "movhps") == 0 ||
38870339a1c2SMark Johnston 		    strcmp(dp->it_name, "movntps") == 0) &&
38880339a1c2SMark Johnston 		    mode == REG_ONLY)
38890339a1c2SMark Johnston 			goto error;
38900339a1c2SMark Johnston #endif
38910339a1c2SMark Johnston 		wbit = XMM_OPND;
38920339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
38930339a1c2SMark Johnston 		break;
38940339a1c2SMark Johnston 
38950339a1c2SMark Johnston 	/* SIMD memory to xmm reg */
38960339a1c2SMark Johnston 	case XMMM:
38970339a1c2SMark Johnston 	case XMMM_66r:
38980339a1c2SMark Johnston 	case XMMOM:
38990339a1c2SMark Johnston 		wbit = XMM_OPND;
39000339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
39010339a1c2SMark Johnston #ifdef DIS_TEXT
39020339a1c2SMark Johnston 		if (mode == REG_ONLY) {
39030339a1c2SMark Johnston 			if (strcmp(dp->it_name, "movhps") == 0)
39040339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
39050339a1c2SMark Johnston 			else
39060339a1c2SMark Johnston 				goto error;
39070339a1c2SMark Johnston 		}
39080339a1c2SMark Johnston #endif
39090339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
39100339a1c2SMark Johnston 		break;
39110339a1c2SMark Johnston 
39120339a1c2SMark Johnston 	/* SIMD memory or r32 to xmm reg			*/
39130339a1c2SMark Johnston 	case XMM3MX:
39140339a1c2SMark Johnston 		wbit = LONG_OPND;
39150339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
39160339a1c2SMark Johnston 		break;
39170339a1c2SMark Johnston 
39180339a1c2SMark Johnston 	case XMM3MXS:
39190339a1c2SMark Johnston 		wbit = LONG_OPND;
39200339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
39210339a1c2SMark Johnston 		break;
39220339a1c2SMark Johnston 
39230339a1c2SMark Johnston 	/* SIMD memory or mm reg to xmm reg			*/
39240339a1c2SMark Johnston 	case XMMOMX:
39250339a1c2SMark Johnston 	/* SIMD mm to xmm */
39260339a1c2SMark Johnston 	case XMMMX:
39270339a1c2SMark Johnston 		wbit = MM_OPND;
39280339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
39290339a1c2SMark Johnston 		break;
39300339a1c2SMark Johnston 
39310339a1c2SMark Johnston 	/* SIMD memory or xmm reg to mm reg			*/
39320339a1c2SMark Johnston 	case XMMXMM:
39330339a1c2SMark Johnston 	case XMMOXMM:
39340339a1c2SMark Johnston 	case XMMXM:
39350339a1c2SMark Johnston 		wbit = XMM_OPND;
39360339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
39370339a1c2SMark Johnston 		break;
39380339a1c2SMark Johnston 
39390339a1c2SMark Johnston 
39400339a1c2SMark Johnston 	/* SIMD memory or xmm reg to r32			*/
39410339a1c2SMark Johnston 	case XMMXM3:
39420339a1c2SMark Johnston 		wbit = XMM_OPND;
39430339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
39440339a1c2SMark Johnston 		break;
39450339a1c2SMark Johnston 
39460339a1c2SMark Johnston 	/* SIMD xmm to r32					*/
39470339a1c2SMark Johnston 	case XMMX3:
39480339a1c2SMark Johnston 	case XMMOX3:
39490339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
39500339a1c2SMark Johnston 		if (mode != REG_ONLY)
39510339a1c2SMark Johnston 			goto error;
39520339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
39530339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
39540339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
39550339a1c2SMark Johnston 		NOMEM;
39560339a1c2SMark Johnston 		break;
39570339a1c2SMark Johnston 
39580339a1c2SMark Johnston 	/* SIMD predicated memory or xmm reg with/to xmm reg */
39590339a1c2SMark Johnston 	case XMMP:
39600339a1c2SMark Johnston 	case XMMP_66r:
39610339a1c2SMark Johnston 	case XMMP_66o:
39620339a1c2SMark Johnston 	case XMMOPM:
39630339a1c2SMark Johnston 		wbit = XMM_OPND;
39640339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
39650339a1c2SMark Johnston 		    1);
39660339a1c2SMark Johnston 
39670339a1c2SMark Johnston #ifdef DIS_TEXT
39680339a1c2SMark Johnston 		/*
39690339a1c2SMark Johnston 		 * cmpps and cmpss vary their instruction name based
39700339a1c2SMark Johnston 		 * on the value of imm8.  Other XMMP instructions,
39710339a1c2SMark Johnston 		 * such as shufps, require explicit specification of
39720339a1c2SMark Johnston 		 * the predicate.
39730339a1c2SMark Johnston 		 */
39740339a1c2SMark Johnston 		if (dp->it_name[0] == 'c' &&
39750339a1c2SMark Johnston 		    dp->it_name[1] == 'm' &&
39760339a1c2SMark Johnston 		    dp->it_name[2] == 'p' &&
39770339a1c2SMark Johnston 		    strlen(dp->it_name) == 5) {
39780339a1c2SMark Johnston 			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
39790339a1c2SMark Johnston 
39800339a1c2SMark Johnston 			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
39810339a1c2SMark Johnston 				goto error;
39820339a1c2SMark Johnston 
39830339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
39840339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
39850339a1c2SMark Johnston 			    OPLEN);
39860339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem,
39870339a1c2SMark Johnston 			    dp->it_name + strlen(dp->it_name) - 2,
39880339a1c2SMark Johnston 			    OPLEN);
39890339a1c2SMark Johnston 			x->d86_opnd[0] = x->d86_opnd[1];
39900339a1c2SMark Johnston 			x->d86_opnd[1] = x->d86_opnd[2];
39910339a1c2SMark Johnston 			x->d86_numopnds = 2;
39920339a1c2SMark Johnston 		}
39930339a1c2SMark Johnston #endif
39940339a1c2SMark Johnston 		break;
39950339a1c2SMark Johnston 
39960339a1c2SMark Johnston 	case XMMX2I:
39970339a1c2SMark Johnston 		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
39980339a1c2SMark Johnston 		    1);
39990339a1c2SMark Johnston 		NOMEM;
40000339a1c2SMark Johnston 		break;
40010339a1c2SMark Johnston 
40020339a1c2SMark Johnston 	case XMM2I:
40030339a1c2SMark Johnston 		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
40040339a1c2SMark Johnston 		NOMEM;
40050339a1c2SMark Johnston 		break;
40060339a1c2SMark Johnston 
40070339a1c2SMark Johnston 	/* immediate operand to accumulator */
40080339a1c2SMark Johnston 	case IA:
40090339a1c2SMark Johnston 		wbit = WBIT(opcode2);
40100339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
40110339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
40120339a1c2SMark Johnston 		NOMEM;
40130339a1c2SMark Johnston 		break;
40140339a1c2SMark Johnston 
40150339a1c2SMark Johnston 	/* memory or register operand to accumulator */
40160339a1c2SMark Johnston 	case MA:
40170339a1c2SMark Johnston 		wbit = WBIT(opcode2);
40180339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
40190339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
40200339a1c2SMark Johnston 		break;
40210339a1c2SMark Johnston 
40220339a1c2SMark Johnston 	/* si register to di register used to reference memory		*/
40230339a1c2SMark Johnston 	case SD:
40240339a1c2SMark Johnston #ifdef DIS_TEXT
40250339a1c2SMark Johnston 		dtrace_check_override(x, 0);
40260339a1c2SMark Johnston 		x->d86_numopnds = 2;
40270339a1c2SMark Johnston 		if (addr_size == SIZE64) {
40280339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
40290339a1c2SMark Johnston 			    OPLEN);
40300339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
40310339a1c2SMark Johnston 			    OPLEN);
40320339a1c2SMark Johnston 		} else if (addr_size == SIZE32) {
40330339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
40340339a1c2SMark Johnston 			    OPLEN);
40350339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
40360339a1c2SMark Johnston 			    OPLEN);
40370339a1c2SMark Johnston 		} else {
40380339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
40390339a1c2SMark Johnston 			    OPLEN);
40400339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
40410339a1c2SMark Johnston 			    OPLEN);
40420339a1c2SMark Johnston 		}
40430339a1c2SMark Johnston #endif
40440339a1c2SMark Johnston 		wbit = LONG_OPND;
40450339a1c2SMark Johnston 		break;
40460339a1c2SMark Johnston 
40470339a1c2SMark Johnston 	/* accumulator to di register				*/
40480339a1c2SMark Johnston 	case AD:
40490339a1c2SMark Johnston 		wbit = WBIT(opcode2);
40500339a1c2SMark Johnston #ifdef DIS_TEXT
40510339a1c2SMark Johnston 		dtrace_check_override(x, 1);
40520339a1c2SMark Johnston 		x->d86_numopnds = 2;
40530339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
40540339a1c2SMark Johnston 		if (addr_size == SIZE64)
40550339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
40560339a1c2SMark Johnston 			    OPLEN);
40570339a1c2SMark Johnston 		else if (addr_size == SIZE32)
40580339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
40590339a1c2SMark Johnston 			    OPLEN);
40600339a1c2SMark Johnston 		else
40610339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
40620339a1c2SMark Johnston 			    OPLEN);
40630339a1c2SMark Johnston #endif
40640339a1c2SMark Johnston 		break;
40650339a1c2SMark Johnston 
40660339a1c2SMark Johnston 	/* si register to accumulator				*/
40670339a1c2SMark Johnston 	case SA:
40680339a1c2SMark Johnston 		wbit = WBIT(opcode2);
40690339a1c2SMark Johnston #ifdef DIS_TEXT
40700339a1c2SMark Johnston 		dtrace_check_override(x, 0);
40710339a1c2SMark Johnston 		x->d86_numopnds = 2;
40720339a1c2SMark Johnston 		if (addr_size == SIZE64)
40730339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
40740339a1c2SMark Johnston 			    OPLEN);
40750339a1c2SMark Johnston 		else if (addr_size == SIZE32)
40760339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
40770339a1c2SMark Johnston 			    OPLEN);
40780339a1c2SMark Johnston 		else
40790339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
40800339a1c2SMark Johnston 			    OPLEN);
40810339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
40820339a1c2SMark Johnston #endif
40830339a1c2SMark Johnston 		break;
40840339a1c2SMark Johnston 
40850339a1c2SMark Johnston 	/*
40860339a1c2SMark Johnston 	 * single operand, a 16/32 bit displacement
40870339a1c2SMark Johnston 	 */
40880339a1c2SMark Johnston 	case D:
40890339a1c2SMark Johnston 		wbit = LONG_OPND;
40900339a1c2SMark Johnston 		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
40910339a1c2SMark Johnston 		NOMEM;
40920339a1c2SMark Johnston 		break;
40930339a1c2SMark Johnston 
40940339a1c2SMark Johnston 	/* jmp/call indirect to memory or register operand		*/
40950339a1c2SMark Johnston 	case INM:
40960339a1c2SMark Johnston #ifdef DIS_TEXT
40970339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
40980339a1c2SMark Johnston #endif
40990339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
41000339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
41010339a1c2SMark Johnston 		wbit = LONG_OPND;
41020339a1c2SMark Johnston 		break;
41030339a1c2SMark Johnston 
41040339a1c2SMark Johnston 	/*
41050339a1c2SMark Johnston 	 * for long jumps and long calls -- a new code segment
41060339a1c2SMark Johnston 	 * register and an offset in IP -- stored in object
41070339a1c2SMark Johnston 	 * code in reverse order. Note - not valid in amd64
41080339a1c2SMark Johnston 	 */
41090339a1c2SMark Johnston 	case SO:
41100339a1c2SMark Johnston 		dtrace_check_override(x, 1);
41110339a1c2SMark Johnston 		wbit = LONG_OPND;
41120339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
41130339a1c2SMark Johnston #ifdef DIS_TEXT
41140339a1c2SMark Johnston 		x->d86_opnd[1].d86_mode = MODE_SIGNED;
41150339a1c2SMark Johnston #endif
41160339a1c2SMark Johnston 		/* will now get segment operand */
41170339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
41180339a1c2SMark Johnston 		break;
41190339a1c2SMark Johnston 
41200339a1c2SMark Johnston 	/*
41210339a1c2SMark Johnston 	 * jmp/call. single operand, 8 bit displacement.
41220339a1c2SMark Johnston 	 * added to current EIP in 'compofff'
41230339a1c2SMark Johnston 	 */
41240339a1c2SMark Johnston 	case BD:
41250339a1c2SMark Johnston 		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
41260339a1c2SMark Johnston 		NOMEM;
41270339a1c2SMark Johnston 		break;
41280339a1c2SMark Johnston 
41290339a1c2SMark Johnston 	/* single 32/16 bit immediate operand			*/
41300339a1c2SMark Johnston 	case I:
41310339a1c2SMark Johnston 		wbit = LONG_OPND;
41320339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
41330339a1c2SMark Johnston 		break;
41340339a1c2SMark Johnston 
41350339a1c2SMark Johnston 	/* single 8 bit immediate operand			*/
41360339a1c2SMark Johnston 	case Ib:
41370339a1c2SMark Johnston 		wbit = LONG_OPND;
41380339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
41390339a1c2SMark Johnston 		break;
41400339a1c2SMark Johnston 
41410339a1c2SMark Johnston 	case ENTER:
41420339a1c2SMark Johnston 		wbit = LONG_OPND;
41430339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
41440339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 1);
41450339a1c2SMark Johnston 		switch (opnd_size) {
41460339a1c2SMark Johnston 		case SIZE64:
41470339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
41480339a1c2SMark Johnston 			break;
41490339a1c2SMark Johnston 		case SIZE32:
41500339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
41510339a1c2SMark Johnston 			break;
41520339a1c2SMark Johnston 		case SIZE16:
41530339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
41540339a1c2SMark Johnston 			break;
41550339a1c2SMark Johnston 		}
41560339a1c2SMark Johnston 
41570339a1c2SMark Johnston 		break;
41580339a1c2SMark Johnston 
41590339a1c2SMark Johnston 	/* 16-bit immediate operand */
41600339a1c2SMark Johnston 	case RET:
41610339a1c2SMark Johnston 		wbit = LONG_OPND;
41620339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
41630339a1c2SMark Johnston 		break;
41640339a1c2SMark Johnston 
41650339a1c2SMark Johnston 	/* single 8 bit port operand				*/
41660339a1c2SMark Johnston 	case P:
41670339a1c2SMark Johnston 		dtrace_check_override(x, 0);
41680339a1c2SMark Johnston 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
41690339a1c2SMark Johnston 		NOMEM;
41700339a1c2SMark Johnston 		break;
41710339a1c2SMark Johnston 
41720339a1c2SMark Johnston 	/* single operand, dx register (variable port instruction) */
41730339a1c2SMark Johnston 	case V:
41740339a1c2SMark Johnston 		x->d86_numopnds = 1;
41750339a1c2SMark Johnston 		dtrace_check_override(x, 0);
41760339a1c2SMark Johnston #ifdef DIS_TEXT
41770339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
41780339a1c2SMark Johnston #endif
41790339a1c2SMark Johnston 		NOMEM;
41800339a1c2SMark Johnston 		break;
41810339a1c2SMark Johnston 
41820339a1c2SMark Johnston 	/*
41830339a1c2SMark Johnston 	 * The int instruction, which has two forms:
41840339a1c2SMark Johnston 	 * int 3 (breakpoint) or
41850339a1c2SMark Johnston 	 * int n, where n is indicated in the subsequent
41860339a1c2SMark Johnston 	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
41870339a1c2SMark Johnston 	 * where, although the 3 looks  like an operand,
41880339a1c2SMark Johnston 	 * it is implied by the opcode. It must be converted
41890339a1c2SMark Johnston 	 * to the correct base and output.
41900339a1c2SMark Johnston 	 */
41910339a1c2SMark Johnston 	case INT3:
41920339a1c2SMark Johnston #ifdef DIS_TEXT
41930339a1c2SMark Johnston 		x->d86_numopnds = 1;
41940339a1c2SMark Johnston 		x->d86_opnd[0].d86_mode = MODE_SIGNED;
41950339a1c2SMark Johnston 		x->d86_opnd[0].d86_value_size = 1;
41960339a1c2SMark Johnston 		x->d86_opnd[0].d86_value = 3;
41970339a1c2SMark Johnston #endif
41980339a1c2SMark Johnston 		NOMEM;
41990339a1c2SMark Johnston 		break;
42000339a1c2SMark Johnston 
42010339a1c2SMark Johnston 	/* single 8 bit immediate operand			*/
42020339a1c2SMark Johnston 	case INTx:
42030339a1c2SMark Johnston 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
42040339a1c2SMark Johnston 		NOMEM;
42050339a1c2SMark Johnston 		break;
42060339a1c2SMark Johnston 
42070339a1c2SMark Johnston 	/* an unused byte must be discarded */
42080339a1c2SMark Johnston 	case U:
42090339a1c2SMark Johnston 		if (x->d86_get_byte(x->d86_data) < 0)
42100339a1c2SMark Johnston 			goto error;
42110339a1c2SMark Johnston 		x->d86_len++;
42120339a1c2SMark Johnston 		NOMEM;
42130339a1c2SMark Johnston 		break;
42140339a1c2SMark Johnston 
42150339a1c2SMark Johnston 	case CBW:
42160339a1c2SMark Johnston #ifdef DIS_TEXT
42170339a1c2SMark Johnston 		if (opnd_size == SIZE16)
42180339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
42190339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
42200339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
42210339a1c2SMark Johnston 		else
42220339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
42230339a1c2SMark Johnston #endif
42240339a1c2SMark Johnston 		wbit = LONG_OPND;
42250339a1c2SMark Johnston 		NOMEM;
42260339a1c2SMark Johnston 		break;
42270339a1c2SMark Johnston 
42280339a1c2SMark Johnston 	case CWD:
42290339a1c2SMark Johnston #ifdef DIS_TEXT
42300339a1c2SMark Johnston 		if (opnd_size == SIZE16)
42310339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
42320339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
42330339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
42340339a1c2SMark Johnston 		else
42350339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
42360339a1c2SMark Johnston #endif
42370339a1c2SMark Johnston 		wbit = LONG_OPND;
42380339a1c2SMark Johnston 		NOMEM;
42390339a1c2SMark Johnston 		break;
42400339a1c2SMark Johnston 
42410339a1c2SMark Johnston 	case XMMSFNC:
42420339a1c2SMark Johnston 		/*
42430339a1c2SMark Johnston 		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
42440339a1c2SMark Johnston 		 * REG_ONLY, mnemonic should be 'clflush'.
42450339a1c2SMark Johnston 		 */
42460339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
42470339a1c2SMark Johnston 
42480339a1c2SMark Johnston 		/* sfence doesn't take operands */
42490339a1c2SMark Johnston #ifdef DIS_TEXT
42500339a1c2SMark Johnston 		if (mode == REG_ONLY) {
42510339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
42520339a1c2SMark Johnston 		} else {
42530339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
42540339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
42550339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
42560339a1c2SMark Johnston 			NOMEM;
42570339a1c2SMark Johnston 		}
42580339a1c2SMark Johnston #else
42590339a1c2SMark Johnston 		if (mode != REG_ONLY) {
42600339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
42610339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
42620339a1c2SMark Johnston 			NOMEM;
42630339a1c2SMark Johnston 		}
42640339a1c2SMark Johnston #endif
42650339a1c2SMark Johnston 		break;
42660339a1c2SMark Johnston 
42670339a1c2SMark Johnston 	/*
42680339a1c2SMark Johnston 	 * no disassembly, the mnemonic was all there was so go on
42690339a1c2SMark Johnston 	 */
42700339a1c2SMark Johnston 	case NORM:
42710339a1c2SMark Johnston 		if (dp->it_invalid32 && cpu_mode != SIZE64)
42720339a1c2SMark Johnston 			goto error;
42730339a1c2SMark Johnston 		NOMEM;
42740339a1c2SMark Johnston 		/*FALLTHROUGH*/
42750339a1c2SMark Johnston 	case IMPLMEM:
42760339a1c2SMark Johnston 		break;
42770339a1c2SMark Johnston 
42780339a1c2SMark Johnston 	case XMMFENCE:
42790339a1c2SMark Johnston 		/*
42800339a1c2SMark Johnston 		 * XRSTOR and LFENCE share the same opcode but differ in mode
42810339a1c2SMark Johnston 		 */
42820339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
42830339a1c2SMark Johnston 
42840339a1c2SMark Johnston 		if (mode == REG_ONLY) {
42850339a1c2SMark Johnston 			/*
42860339a1c2SMark Johnston 			 * Only the following exact byte sequences are allowed:
42870339a1c2SMark Johnston 			 *
42880339a1c2SMark Johnston 			 * 	0f ae e8	lfence
42890339a1c2SMark Johnston 			 * 	0f ae f0	mfence
42900339a1c2SMark Johnston 			 */
42910339a1c2SMark Johnston 			if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
42920339a1c2SMark Johnston 			    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
42930339a1c2SMark Johnston 				goto error;
42940339a1c2SMark Johnston 		} else {
42950339a1c2SMark Johnston #ifdef DIS_TEXT
42960339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "xrstor", OPLEN);
42970339a1c2SMark Johnston #endif
42980339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
42990339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
43000339a1c2SMark Johnston 		}
43010339a1c2SMark Johnston 		break;
43020339a1c2SMark Johnston 
43030339a1c2SMark Johnston 	/* float reg */
43040339a1c2SMark Johnston 	case F:
43050339a1c2SMark Johnston #ifdef DIS_TEXT
43060339a1c2SMark Johnston 		x->d86_numopnds = 1;
43070339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
43080339a1c2SMark Johnston 		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
43090339a1c2SMark Johnston #endif
43100339a1c2SMark Johnston 		NOMEM;
43110339a1c2SMark Johnston 		break;
43120339a1c2SMark Johnston 
43130339a1c2SMark Johnston 	/* float reg to float reg, with ret bit present */
43140339a1c2SMark Johnston 	case FF:
43150339a1c2SMark Johnston 		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
43160339a1c2SMark Johnston 		/*FALLTHROUGH*/
43170339a1c2SMark Johnston 	case FFC:				/* case for vbit always = 0 */
43180339a1c2SMark Johnston #ifdef DIS_TEXT
43190339a1c2SMark Johnston 		x->d86_numopnds = 2;
43200339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
43210339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
43220339a1c2SMark Johnston 		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
43230339a1c2SMark Johnston #endif
43240339a1c2SMark Johnston 		NOMEM;
43250339a1c2SMark Johnston 		break;
43260339a1c2SMark Johnston 
43270339a1c2SMark Johnston 	/* AVX instructions */
43280339a1c2SMark Johnston 	case VEX_MO:
43290339a1c2SMark Johnston 		/* op(ModR/M.r/m) */
43300339a1c2SMark Johnston 		x->d86_numopnds = 1;
43310339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
43320339a1c2SMark Johnston #ifdef DIS_TEXT
43330339a1c2SMark Johnston 		if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
43340339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
43350339a1c2SMark Johnston #endif
43360339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
43370339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
43380339a1c2SMark Johnston 		break;
43390339a1c2SMark Johnston 	case VEX_RMrX:
43400339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
43410339a1c2SMark Johnston 		x->d86_numopnds = 3;
43420339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
43430339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
43440339a1c2SMark Johnston 
43450339a1c2SMark Johnston 		if (mode != REG_ONLY) {
43460339a1c2SMark Johnston 			if ((dp == &dis_opAVXF20F[0x10]) ||
43470339a1c2SMark Johnston 			    (dp == &dis_opAVXF30F[0x10])) {
43480339a1c2SMark Johnston 				/* vmovsd <m64>, <xmm> */
43490339a1c2SMark Johnston 				/* or vmovss <m64>, <xmm> */
43500339a1c2SMark Johnston 				x->d86_numopnds = 2;
43510339a1c2SMark Johnston 				goto L_VEX_MX;
43520339a1c2SMark Johnston 			}
43530339a1c2SMark Johnston 		}
43540339a1c2SMark Johnston 
43550339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
43560339a1c2SMark Johnston 		/*
43570339a1c2SMark Johnston 		 * VEX prefix uses the 1's complement form to encode the
43580339a1c2SMark Johnston 		 * XMM/YMM regs
43590339a1c2SMark Johnston 		 */
43600339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
43610339a1c2SMark Johnston 
43620339a1c2SMark Johnston 		if ((dp == &dis_opAVXF20F[0x2A]) ||
43630339a1c2SMark Johnston 		    (dp == &dis_opAVXF30F[0x2A])) {
43640339a1c2SMark Johnston 			/*
43650339a1c2SMark Johnston 			 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
43660339a1c2SMark Johnston 			 * <xmm>, <xmm>
43670339a1c2SMark Johnston 			 */
43680339a1c2SMark Johnston 			wbit = LONG_OPND;
43690339a1c2SMark Johnston 		}
43700339a1c2SMark Johnston #ifdef DIS_TEXT
43710339a1c2SMark Johnston 		else if ((mode == REG_ONLY) &&
43720339a1c2SMark Johnston 		    (dp == &dis_opAVX0F[0x1][0x6])) {	/* vmovlhps */
43730339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
43740339a1c2SMark Johnston 		} else if ((mode == REG_ONLY) &&
43750339a1c2SMark Johnston 		    (dp == &dis_opAVX0F[0x1][0x2])) {	/* vmovhlps */
43760339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
43770339a1c2SMark Johnston 		}
43780339a1c2SMark Johnston #endif
43790339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
43800339a1c2SMark Johnston 
43810339a1c2SMark Johnston 		break;
43820339a1c2SMark Johnston 
43830339a1c2SMark Johnston 	case VEX_RRX:
43840339a1c2SMark Johnston 		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
43850339a1c2SMark Johnston 		x->d86_numopnds = 3;
43860339a1c2SMark Johnston 
43870339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
43880339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
43890339a1c2SMark Johnston 
43900339a1c2SMark Johnston 		if (mode != REG_ONLY) {
43910339a1c2SMark Johnston 			if ((dp == &dis_opAVXF20F[0x11]) ||
43920339a1c2SMark Johnston 			    (dp == &dis_opAVXF30F[0x11])) {
43930339a1c2SMark Johnston 				/* vmovsd <xmm>, <m64> */
43940339a1c2SMark Johnston 				/* or vmovss <xmm>, <m64> */
43950339a1c2SMark Johnston 				x->d86_numopnds = 2;
43960339a1c2SMark Johnston 				goto L_VEX_RM;
43970339a1c2SMark Johnston 			}
43980339a1c2SMark Johnston 		}
43990339a1c2SMark Johnston 
44000339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
44010339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
44020339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
44030339a1c2SMark Johnston 		break;
44040339a1c2SMark Johnston 
44050339a1c2SMark Johnston 	case VEX_RMRX:
44060339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
44070339a1c2SMark Johnston 		x->d86_numopnds = 4;
44080339a1c2SMark Johnston 
44090339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
44100339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
44110339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
44120339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
44130339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x18]) {
44140339a1c2SMark Johnston 			/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
44150339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
44160339a1c2SMark Johnston 		} else if ((dp == &dis_opAVX660F3A[0x20]) ||
44170339a1c2SMark Johnston 		    (dp == & dis_opAVX660F[0xC4])) {
44180339a1c2SMark Johnston 			/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
44190339a1c2SMark Johnston 			/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
44200339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
44210339a1c2SMark Johnston 		} else if (dp == &dis_opAVX660F3A[0x22]) {
44220339a1c2SMark Johnston 			/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
44230339a1c2SMark Johnston #ifdef DIS_TEXT
44240339a1c2SMark Johnston 			if (vex_W)
44250339a1c2SMark Johnston 				x->d86_mnem[6] = 'q';
44260339a1c2SMark Johnston #endif
44270339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
44280339a1c2SMark Johnston 		} else {
44290339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
44300339a1c2SMark Johnston 		}
44310339a1c2SMark Johnston 
44320339a1c2SMark Johnston 		/* one byte immediate number */
44330339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
44340339a1c2SMark Johnston 
44350339a1c2SMark Johnston 		/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
44360339a1c2SMark Johnston 		if ((dp == &dis_opAVX660F3A[0x4A]) ||
44370339a1c2SMark Johnston 		    (dp == &dis_opAVX660F3A[0x4B]) ||
44380339a1c2SMark Johnston 		    (dp == &dis_opAVX660F3A[0x4C])) {
44390339a1c2SMark Johnston #ifdef DIS_TEXT
44400339a1c2SMark Johnston 			int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
44410339a1c2SMark Johnston #endif
44420339a1c2SMark Johnston 			x->d86_opnd[0].d86_mode = MODE_NONE;
44430339a1c2SMark Johnston #ifdef DIS_TEXT
44440339a1c2SMark Johnston 			if (vex_L)
44450339a1c2SMark Johnston 				(void) strncpy(x->d86_opnd[0].d86_opnd,
44460339a1c2SMark Johnston 				    dis_YMMREG[regnum], OPLEN);
44470339a1c2SMark Johnston 			else
44480339a1c2SMark Johnston 				(void) strncpy(x->d86_opnd[0].d86_opnd,
44490339a1c2SMark Johnston 				    dis_XMMREG[regnum], OPLEN);
44500339a1c2SMark Johnston #endif
44510339a1c2SMark Johnston 		}
44520339a1c2SMark Johnston 		break;
44530339a1c2SMark Johnston 
44540339a1c2SMark Johnston 	case VEX_MX:
44550339a1c2SMark Johnston 		/* ModR/M.reg := op(ModR/M.rm) */
44560339a1c2SMark Johnston 		x->d86_numopnds = 2;
44570339a1c2SMark Johnston 
44580339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
44590339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
44600339a1c2SMark Johnston L_VEX_MX:
44610339a1c2SMark Johnston 
44620339a1c2SMark Johnston 		if ((dp == &dis_opAVXF20F[0xE6]) ||
44630339a1c2SMark Johnston 		    (dp == &dis_opAVX660F[0x5A]) ||
44640339a1c2SMark Johnston 		    (dp == &dis_opAVX660F[0xE6])) {
44650339a1c2SMark Johnston 			/* vcvtpd2dq <ymm>, <xmm> */
44660339a1c2SMark Johnston 			/* or vcvtpd2ps <ymm>, <xmm> */
44670339a1c2SMark Johnston 			/* or vcvttpd2dq <ymm>, <xmm> */
44680339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
44690339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
44700339a1c2SMark Johnston 		} else if ((dp == &dis_opAVXF30F[0xE6]) ||
4471c3ddb60eSPeter Grehan 		    (dp == &dis_opAVX0F[0x5][0xA]) ||
4472c3ddb60eSPeter Grehan 		    (dp == &dis_opAVX660F38[0x13])) {
44730339a1c2SMark Johnston 			/* vcvtdq2pd <xmm>, <ymm> */
44740339a1c2SMark Johnston 			/* or vcvtps2pd <xmm>, <ymm> */
44750339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
44760339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
44770339a1c2SMark Johnston 		} else if (dp == &dis_opAVX660F[0x6E]) {
44780339a1c2SMark Johnston 			/* vmovd/q <reg/mem 32/64>, <xmm> */
44790339a1c2SMark Johnston #ifdef DIS_TEXT
44800339a1c2SMark Johnston 			if (vex_W)
44810339a1c2SMark Johnston 				x->d86_mnem[4] = 'q';
44820339a1c2SMark Johnston #endif
44830339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
44840339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
44850339a1c2SMark Johnston 		} else {
44860339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
44870339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
44880339a1c2SMark Johnston 		}
44890339a1c2SMark Johnston 
44900339a1c2SMark Johnston 		break;
44910339a1c2SMark Johnston 
44920339a1c2SMark Johnston 	case VEX_MXI:
44930339a1c2SMark Johnston 		/* ModR/M.reg := op(ModR/M.rm, imm8) */
44940339a1c2SMark Johnston 		x->d86_numopnds = 3;
44950339a1c2SMark Johnston 
44960339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
44970339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
44980339a1c2SMark Johnston 
44990339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
45000339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
45010339a1c2SMark Johnston 
45020339a1c2SMark Johnston 		/* one byte immediate number */
45030339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
45040339a1c2SMark Johnston 		break;
45050339a1c2SMark Johnston 
45060339a1c2SMark Johnston 	case VEX_XXI:
45070339a1c2SMark Johnston 		/* VEX.vvvv := op(ModR/M.rm, imm8) */
45080339a1c2SMark Johnston 		x->d86_numopnds = 3;
45090339a1c2SMark Johnston 
45100339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
45110339a1c2SMark Johnston #ifdef DIS_TEXT
45120339a1c2SMark Johnston 		(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
45130339a1c2SMark Johnston 		    OPLEN);
45140339a1c2SMark Johnston #endif
45150339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45160339a1c2SMark Johnston 
45170339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
45180339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
45190339a1c2SMark Johnston 
45200339a1c2SMark Johnston 		/* one byte immediate number */
45210339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
45220339a1c2SMark Johnston 		break;
45230339a1c2SMark Johnston 
45240339a1c2SMark Johnston 	case VEX_MR:
45250339a1c2SMark Johnston 		/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
45260339a1c2SMark Johnston 		if (dp == &dis_opAVX660F[0xC5]) {
45270339a1c2SMark Johnston 			/* vpextrw <imm8>, <xmm>, <reg> */
45280339a1c2SMark Johnston 			x->d86_numopnds = 2;
45290339a1c2SMark Johnston 			vbit = 2;
45300339a1c2SMark Johnston 		} else {
45310339a1c2SMark Johnston 			x->d86_numopnds = 2;
45320339a1c2SMark Johnston 			vbit = 1;
45330339a1c2SMark Johnston 		}
45340339a1c2SMark Johnston 
45350339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
45360339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45370339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
45380339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
45390339a1c2SMark Johnston 
45400339a1c2SMark Johnston 		if (vbit == 2)
45410339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
45420339a1c2SMark Johnston 
45430339a1c2SMark Johnston 		break;
45440339a1c2SMark Johnston 
45450339a1c2SMark Johnston 	case VEX_RRI:
45460339a1c2SMark Johnston 		/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
45470339a1c2SMark Johnston 		x->d86_numopnds = 2;
45480339a1c2SMark Johnston 
45490339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
45500339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45510339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
45520339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
45530339a1c2SMark Johnston 		break;
45540339a1c2SMark Johnston 
45550339a1c2SMark Johnston 	case VEX_RX:
45560339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
4557c3ddb60eSPeter Grehan 		/* vextractf128 || vcvtps2ph */
4558c3ddb60eSPeter Grehan 		if (dp == &dis_opAVX660F3A[0x19] ||
4559c3ddb60eSPeter Grehan 		    dp == &dis_opAVX660F3A[0x1d]) {
45600339a1c2SMark Johnston 			x->d86_numopnds = 3;
45610339a1c2SMark Johnston 
45620339a1c2SMark Johnston 			dtrace_get_modrm(x, &mode, &reg, &r_m);
45630339a1c2SMark Johnston 			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45640339a1c2SMark Johnston 
45650339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
45660339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
45670339a1c2SMark Johnston 
45680339a1c2SMark Johnston 			/* one byte immediate number */
45690339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
45700339a1c2SMark Johnston 			break;
45710339a1c2SMark Johnston 		}
45720339a1c2SMark Johnston 
45730339a1c2SMark Johnston 		x->d86_numopnds = 2;
45740339a1c2SMark Johnston 
45750339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
45760339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45770339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
45780339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
45790339a1c2SMark Johnston 		break;
45800339a1c2SMark Johnston 
45810339a1c2SMark Johnston 	case VEX_RR:
45820339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
45830339a1c2SMark Johnston 		x->d86_numopnds = 2;
45840339a1c2SMark Johnston 
45850339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
45860339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
45870339a1c2SMark Johnston 
45880339a1c2SMark Johnston 		if (dp == &dis_opAVX660F[0x7E]) {
45890339a1c2SMark Johnston 			/* vmovd/q <reg/mem 32/64>, <xmm> */
45900339a1c2SMark Johnston #ifdef DIS_TEXT
45910339a1c2SMark Johnston 			if (vex_W)
45920339a1c2SMark Johnston 				x->d86_mnem[4] = 'q';
45930339a1c2SMark Johnston #endif
45940339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
45950339a1c2SMark Johnston 		} else
45960339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
45970339a1c2SMark Johnston 
45980339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
45990339a1c2SMark Johnston 		break;
46000339a1c2SMark Johnston 
46010339a1c2SMark Johnston 	case VEX_RRi:
46020339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg, imm) */
46030339a1c2SMark Johnston 		x->d86_numopnds = 3;
46040339a1c2SMark Johnston 
46050339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
46060339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
46070339a1c2SMark Johnston 
46080339a1c2SMark Johnston #ifdef DIS_TEXT
46090339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x16]) {
46100339a1c2SMark Johnston 			/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
46110339a1c2SMark Johnston 			if (vex_W)
46120339a1c2SMark Johnston 				x->d86_mnem[6] = 'q';
46130339a1c2SMark Johnston 		}
46140339a1c2SMark Johnston #endif
46150339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
46160339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
46170339a1c2SMark Johnston 
46180339a1c2SMark Johnston 		/* one byte immediate number */
46190339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
46200339a1c2SMark Johnston 		break;
46210339a1c2SMark Johnston 
46220339a1c2SMark Johnston 	case VEX_RM:
46230339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
46240339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x17]) {	/* vextractps */
46250339a1c2SMark Johnston 			x->d86_numopnds = 3;
46260339a1c2SMark Johnston 
46270339a1c2SMark Johnston 			dtrace_get_modrm(x, &mode, &reg, &r_m);
46280339a1c2SMark Johnston 			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
46290339a1c2SMark Johnston 
46300339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
46310339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
46320339a1c2SMark Johnston 			/* one byte immediate number */
46330339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
46340339a1c2SMark Johnston 			break;
46350339a1c2SMark Johnston 		}
46360339a1c2SMark Johnston 		x->d86_numopnds = 2;
46370339a1c2SMark Johnston 
46380339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
46390339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
46400339a1c2SMark Johnston L_VEX_RM:
46410339a1c2SMark Johnston 		vbit = 1;
46420339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);
46430339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
46440339a1c2SMark Johnston 
46450339a1c2SMark Johnston 		break;
46460339a1c2SMark Johnston 
46470339a1c2SMark Johnston 	case VEX_RRM:
46480339a1c2SMark Johnston 		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
46490339a1c2SMark Johnston 		x->d86_numopnds = 3;
46500339a1c2SMark Johnston 
46510339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
46520339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
46530339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
46540339a1c2SMark Johnston 		/* VEX use the 1's complement form encode the XMM/YMM regs */
46550339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
46560339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
46570339a1c2SMark Johnston 		break;
46580339a1c2SMark Johnston 
46590339a1c2SMark Johnston 	case VEX_RMX:
46600339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
46610339a1c2SMark Johnston 		x->d86_numopnds = 3;
46620339a1c2SMark Johnston 
46630339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
46640339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
46650339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
46660339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
46670339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
46680339a1c2SMark Johnston 		break;
46690339a1c2SMark Johnston 
46700339a1c2SMark Johnston 	case VEX_NONE:
46710339a1c2SMark Johnston #ifdef DIS_TEXT
46720339a1c2SMark Johnston 		if (vex_L)
46730339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
46740339a1c2SMark Johnston #endif
46750339a1c2SMark Johnston 		break;
46760339a1c2SMark Johnston 	/* an invalid op code */
46770339a1c2SMark Johnston 	case AM:
46780339a1c2SMark Johnston 	case DM:
46790339a1c2SMark Johnston 	case OVERRIDE:
46800339a1c2SMark Johnston 	case PREFIX:
46810339a1c2SMark Johnston 	case UNKNOWN:
46820339a1c2SMark Johnston 		NOMEM;
46830339a1c2SMark Johnston 	default:
46840339a1c2SMark Johnston 		goto error;
46850339a1c2SMark Johnston 	} /* end switch */
46860339a1c2SMark Johnston 	if (x->d86_error)
46870339a1c2SMark Johnston 		goto error;
46880339a1c2SMark Johnston 
46890339a1c2SMark Johnston done:
46900339a1c2SMark Johnston #ifdef DIS_MEM
46910339a1c2SMark Johnston 	/*
46920339a1c2SMark Johnston 	 * compute the size of any memory accessed by the instruction
46930339a1c2SMark Johnston 	 */
46940339a1c2SMark Johnston 	if (x->d86_memsize != 0) {
46950339a1c2SMark Johnston 		return (0);
46960339a1c2SMark Johnston 	} else if (dp->it_stackop) {
46970339a1c2SMark Johnston 		switch (opnd_size) {
46980339a1c2SMark Johnston 		case SIZE16:
46990339a1c2SMark Johnston 			x->d86_memsize = 2;
47000339a1c2SMark Johnston 			break;
47010339a1c2SMark Johnston 		case SIZE32:
47020339a1c2SMark Johnston 			x->d86_memsize = 4;
47030339a1c2SMark Johnston 			break;
47040339a1c2SMark Johnston 		case SIZE64:
47050339a1c2SMark Johnston 			x->d86_memsize = 8;
47060339a1c2SMark Johnston 			break;
47070339a1c2SMark Johnston 		}
47080339a1c2SMark Johnston 	} else if (nomem || mode == REG_ONLY) {
47090339a1c2SMark Johnston 		x->d86_memsize = 0;
47100339a1c2SMark Johnston 
47110339a1c2SMark Johnston 	} else if (dp->it_size != 0) {
47120339a1c2SMark Johnston 		/*
47130339a1c2SMark Johnston 		 * In 64 bit mode descriptor table entries
47140339a1c2SMark Johnston 		 * go up to 10 bytes and popf/pushf are always 8 bytes
47150339a1c2SMark Johnston 		 */
47160339a1c2SMark Johnston 		if (x->d86_mode == SIZE64 && dp->it_size == 6)
47170339a1c2SMark Johnston 			x->d86_memsize = 10;
47180339a1c2SMark Johnston 		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
47190339a1c2SMark Johnston 		    (opcode2 == 0xc || opcode2 == 0xd))
47200339a1c2SMark Johnston 			x->d86_memsize = 8;
47210339a1c2SMark Johnston 		else
47220339a1c2SMark Johnston 			x->d86_memsize = dp->it_size;
47230339a1c2SMark Johnston 
47240339a1c2SMark Johnston 	} else if (wbit == 0) {
47250339a1c2SMark Johnston 		x->d86_memsize = 1;
47260339a1c2SMark Johnston 
47270339a1c2SMark Johnston 	} else if (wbit == LONG_OPND) {
47280339a1c2SMark Johnston 		if (opnd_size == SIZE64)
47290339a1c2SMark Johnston 			x->d86_memsize = 8;
47300339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
47310339a1c2SMark Johnston 			x->d86_memsize = 4;
47320339a1c2SMark Johnston 		else
47330339a1c2SMark Johnston 			x->d86_memsize = 2;
47340339a1c2SMark Johnston 
47350339a1c2SMark Johnston 	} else if (wbit == SEG_OPND) {
47360339a1c2SMark Johnston 		x->d86_memsize = 4;
47370339a1c2SMark Johnston 
47380339a1c2SMark Johnston 	} else {
47390339a1c2SMark Johnston 		x->d86_memsize = 8;
47400339a1c2SMark Johnston 	}
47410339a1c2SMark Johnston #endif
47420339a1c2SMark Johnston 	return (0);
47430339a1c2SMark Johnston 
47440339a1c2SMark Johnston error:
47450339a1c2SMark Johnston #ifdef DIS_TEXT
47460339a1c2SMark Johnston 	(void) strlcat(x->d86_mnem, "undef", OPLEN);
47470339a1c2SMark Johnston #endif
47480339a1c2SMark Johnston 	return (1);
47490339a1c2SMark Johnston }
47500339a1c2SMark Johnston 
47510339a1c2SMark Johnston #ifdef DIS_TEXT
47520339a1c2SMark Johnston 
47530339a1c2SMark Johnston /*
47540339a1c2SMark Johnston  * Some instructions should have immediate operands printed
47550339a1c2SMark Johnston  * as unsigned integers. We compare against this table.
47560339a1c2SMark Johnston  */
47570339a1c2SMark Johnston static char *unsigned_ops[] = {
47580339a1c2SMark Johnston 	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
47590339a1c2SMark Johnston 	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
47600339a1c2SMark Johnston 	0
47610339a1c2SMark Johnston };
47620339a1c2SMark Johnston 
47630339a1c2SMark Johnston 
47640339a1c2SMark Johnston static int
47650339a1c2SMark Johnston isunsigned_op(char *opcode)
47660339a1c2SMark Johnston {
47670339a1c2SMark Johnston 	char *where;
47680339a1c2SMark Johnston 	int i;
47690339a1c2SMark Johnston 	int is_unsigned = 0;
47700339a1c2SMark Johnston 
47710339a1c2SMark Johnston 	/*
47720339a1c2SMark Johnston 	 * Work back to start of last mnemonic, since we may have
47730339a1c2SMark Johnston 	 * prefixes on some opcodes.
47740339a1c2SMark Johnston 	 */
47750339a1c2SMark Johnston 	where = opcode + strlen(opcode) - 1;
47760339a1c2SMark Johnston 	while (where > opcode && *where != ' ')
47770339a1c2SMark Johnston 		--where;
47780339a1c2SMark Johnston 	if (*where == ' ')
47790339a1c2SMark Johnston 		++where;
47800339a1c2SMark Johnston 
47810339a1c2SMark Johnston 	for (i = 0; unsigned_ops[i]; ++i) {
47820339a1c2SMark Johnston 		if (strncmp(where, unsigned_ops[i],
47830339a1c2SMark Johnston 		    strlen(unsigned_ops[i])))
47840339a1c2SMark Johnston 			continue;
47850339a1c2SMark Johnston 		is_unsigned = 1;
47860339a1c2SMark Johnston 		break;
47870339a1c2SMark Johnston 	}
47880339a1c2SMark Johnston 	return (is_unsigned);
47890339a1c2SMark Johnston }
47900339a1c2SMark Johnston 
47910339a1c2SMark Johnston /*
47920339a1c2SMark Johnston  * Print a numeric immediate into end of buf, maximum length buflen.
47930339a1c2SMark Johnston  * The immediate may be an address or a displacement.  Mask is set
47940339a1c2SMark Johnston  * for address size.  If the immediate is a "small negative", or
47950339a1c2SMark Johnston  * if it's a negative displacement of any magnitude, print as -<absval>.
47960339a1c2SMark Johnston  * Respect the "octal" flag.  "Small negative" is defined as "in the
47970339a1c2SMark Johnston  * interval [NEG_LIMIT, 0)".
47980339a1c2SMark Johnston  *
47990339a1c2SMark Johnston  * Also, "isunsigned_op()" instructions never print negatives.
48000339a1c2SMark Johnston  *
48010339a1c2SMark Johnston  * Return whether we decided to print a negative value or not.
48020339a1c2SMark Johnston  */
48030339a1c2SMark Johnston 
48040339a1c2SMark Johnston #define	NEG_LIMIT	-255
48050339a1c2SMark Johnston enum {IMM, DISP};
48060339a1c2SMark Johnston enum {POS, TRY_NEG};
48070339a1c2SMark Johnston 
48080339a1c2SMark Johnston static int
48090339a1c2SMark Johnston print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
48100339a1c2SMark Johnston     size_t buflen, int disp, int try_neg)
48110339a1c2SMark Johnston {
48120339a1c2SMark Johnston 	int curlen;
48130339a1c2SMark Johnston 	int64_t sv = (int64_t)usv;
48140339a1c2SMark Johnston 	int octal = dis->d86_flags & DIS_F_OCTAL;
48150339a1c2SMark Johnston 
48160339a1c2SMark Johnston 	curlen = strlen(buf);
48170339a1c2SMark Johnston 
48180339a1c2SMark Johnston 	if (try_neg == TRY_NEG && sv < 0 &&
48190339a1c2SMark Johnston 	    (disp || sv >= NEG_LIMIT) &&
48200339a1c2SMark Johnston 	    !isunsigned_op(dis->d86_mnem)) {
48210339a1c2SMark Johnston 		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
48220339a1c2SMark Johnston 		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
48230339a1c2SMark Johnston 		return (1);
48240339a1c2SMark Johnston 	} else {
48250339a1c2SMark Johnston 		if (disp == DISP)
48260339a1c2SMark Johnston 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
48270339a1c2SMark Johnston 			    octal ? "+0%llo" : "+0x%llx", usv & mask);
48280339a1c2SMark Johnston 		else
48290339a1c2SMark Johnston 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
48300339a1c2SMark Johnston 			    octal ? "0%llo" : "0x%llx", usv & mask);
48310339a1c2SMark Johnston 		return (0);
48320339a1c2SMark Johnston 
48330339a1c2SMark Johnston 	}
48340339a1c2SMark Johnston }
48350339a1c2SMark Johnston 
48360339a1c2SMark Johnston 
48370339a1c2SMark Johnston static int
48380339a1c2SMark Johnston log2(int size)
48390339a1c2SMark Johnston {
48400339a1c2SMark Johnston 	switch (size) {
48410339a1c2SMark Johnston 	case 1: return (0);
48420339a1c2SMark Johnston 	case 2: return (1);
48430339a1c2SMark Johnston 	case 4: return (2);
48440339a1c2SMark Johnston 	case 8: return (3);
48450339a1c2SMark Johnston 	}
48460339a1c2SMark Johnston 	return (0);
48470339a1c2SMark Johnston }
48480339a1c2SMark Johnston 
48490339a1c2SMark Johnston /* ARGSUSED */
48500339a1c2SMark Johnston void
48510339a1c2SMark Johnston dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
48520339a1c2SMark Johnston     size_t buflen)
48530339a1c2SMark Johnston {
48540339a1c2SMark Johnston 	uint64_t reltgt = 0;
48550339a1c2SMark Johnston 	uint64_t tgt = 0;
48560339a1c2SMark Johnston 	int curlen;
48570339a1c2SMark Johnston 	int (*lookup)(void *, uint64_t, char *, size_t);
48580339a1c2SMark Johnston 	int i;
48590339a1c2SMark Johnston 	int64_t sv;
48600339a1c2SMark Johnston 	uint64_t usv, mask, save_mask, save_usv;
48610339a1c2SMark Johnston 	static uint64_t masks[] =
48620339a1c2SMark Johnston 	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
48630339a1c2SMark Johnston 	save_usv = 0;
48640339a1c2SMark Johnston 
48650339a1c2SMark Johnston 	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
48660339a1c2SMark Johnston 
48670339a1c2SMark Johnston 	/*
48680339a1c2SMark Johnston 	 * For PC-relative jumps, the pc is really the next pc after executing
48690339a1c2SMark Johnston 	 * this instruction, so increment it appropriately.
48700339a1c2SMark Johnston 	 */
48710339a1c2SMark Johnston 	pc += dis->d86_len;
48720339a1c2SMark Johnston 
48730339a1c2SMark Johnston 	for (i = 0; i < dis->d86_numopnds; i++) {
48740339a1c2SMark Johnston 		d86opnd_t *op = &dis->d86_opnd[i];
48750339a1c2SMark Johnston 
48760339a1c2SMark Johnston 		if (i != 0)
48770339a1c2SMark Johnston 			(void) strlcat(buf, ",", buflen);
48780339a1c2SMark Johnston 
48790339a1c2SMark Johnston 		(void) strlcat(buf, op->d86_prefix, buflen);
48800339a1c2SMark Johnston 
48810339a1c2SMark Johnston 		/*
48820339a1c2SMark Johnston 		 * sv is for the signed, possibly-truncated immediate or
48830339a1c2SMark Johnston 		 * displacement; usv retains the original size and
48840339a1c2SMark Johnston 		 * unsignedness for symbol lookup.
48850339a1c2SMark Johnston 		 */
48860339a1c2SMark Johnston 
48870339a1c2SMark Johnston 		sv = usv = op->d86_value;
48880339a1c2SMark Johnston 
48890339a1c2SMark Johnston 		/*
48900339a1c2SMark Johnston 		 * About masks: for immediates that represent
48910339a1c2SMark Johnston 		 * addresses, the appropriate display size is
48920339a1c2SMark Johnston 		 * the effective address size of the instruction.
48930339a1c2SMark Johnston 		 * This includes MODE_OFFSET, MODE_IPREL, and
48940339a1c2SMark Johnston 		 * MODE_RIPREL.  Immediates that are simply
48950339a1c2SMark Johnston 		 * immediate values should display in the operand's
48960339a1c2SMark Johnston 		 * size, however, since they don't represent addresses.
48970339a1c2SMark Johnston 		 */
48980339a1c2SMark Johnston 
48990339a1c2SMark Johnston 		/* d86_addr_size is SIZEnn, which is log2(real size) */
49000339a1c2SMark Johnston 		mask = masks[dis->d86_addr_size];
49010339a1c2SMark Johnston 
49020339a1c2SMark Johnston 		/* d86_value_size and d86_imm_bytes are in bytes */
49030339a1c2SMark Johnston 		if (op->d86_mode == MODE_SIGNED ||
49040339a1c2SMark Johnston 		    op->d86_mode == MODE_IMPLIED)
49050339a1c2SMark Johnston 			mask = masks[log2(op->d86_value_size)];
49060339a1c2SMark Johnston 
49070339a1c2SMark Johnston 		switch (op->d86_mode) {
49080339a1c2SMark Johnston 
49090339a1c2SMark Johnston 		case MODE_NONE:
49100339a1c2SMark Johnston 
49110339a1c2SMark Johnston 			(void) strlcat(buf, op->d86_opnd, buflen);
49120339a1c2SMark Johnston 			break;
49130339a1c2SMark Johnston 
49140339a1c2SMark Johnston 		case MODE_SIGNED:
49150339a1c2SMark Johnston 		case MODE_IMPLIED:
49160339a1c2SMark Johnston 		case MODE_OFFSET:
49170339a1c2SMark Johnston 
49180339a1c2SMark Johnston 			tgt = usv;
49190339a1c2SMark Johnston 
49200339a1c2SMark Johnston 			if (dis->d86_seg_prefix)
49210339a1c2SMark Johnston 				(void) strlcat(buf, dis->d86_seg_prefix,
49220339a1c2SMark Johnston 				    buflen);
49230339a1c2SMark Johnston 
49240339a1c2SMark Johnston 			if (op->d86_mode == MODE_SIGNED ||
49250339a1c2SMark Johnston 			    op->d86_mode == MODE_IMPLIED) {
49260339a1c2SMark Johnston 				(void) strlcat(buf, "$", buflen);
49270339a1c2SMark Johnston 			}
49280339a1c2SMark Johnston 
49290339a1c2SMark Johnston 			if (print_imm(dis, usv, mask, buf, buflen,
49300339a1c2SMark Johnston 			    IMM, TRY_NEG) &&
49310339a1c2SMark Johnston 			    (op->d86_mode == MODE_SIGNED ||
49320339a1c2SMark Johnston 			    op->d86_mode == MODE_IMPLIED)) {
49330339a1c2SMark Johnston 
49340339a1c2SMark Johnston 				/*
49350339a1c2SMark Johnston 				 * We printed a negative value for an
49360339a1c2SMark Johnston 				 * immediate that wasn't a
49370339a1c2SMark Johnston 				 * displacement.  Note that fact so we can
49380339a1c2SMark Johnston 				 * print the positive value as an
49390339a1c2SMark Johnston 				 * annotation.
49400339a1c2SMark Johnston 				 */
49410339a1c2SMark Johnston 
49420339a1c2SMark Johnston 				save_usv = usv;
49430339a1c2SMark Johnston 				save_mask = mask;
49440339a1c2SMark Johnston 			}
49450339a1c2SMark Johnston 			(void) strlcat(buf, op->d86_opnd, buflen);
49460339a1c2SMark Johnston 
49470339a1c2SMark Johnston 			break;
49480339a1c2SMark Johnston 
49490339a1c2SMark Johnston 		case MODE_IPREL:
49500339a1c2SMark Johnston 		case MODE_RIPREL:
49510339a1c2SMark Johnston 
49520339a1c2SMark Johnston 			reltgt = pc + sv;
49530339a1c2SMark Johnston 
49540339a1c2SMark Johnston 			switch (mode) {
49550339a1c2SMark Johnston 			case SIZE16:
49560339a1c2SMark Johnston 				reltgt = (uint16_t)reltgt;
49570339a1c2SMark Johnston 				break;
49580339a1c2SMark Johnston 			case SIZE32:
49590339a1c2SMark Johnston 				reltgt = (uint32_t)reltgt;
49600339a1c2SMark Johnston 				break;
49610339a1c2SMark Johnston 			}
49620339a1c2SMark Johnston 
49630339a1c2SMark Johnston 			(void) print_imm(dis, usv, mask, buf, buflen,
49640339a1c2SMark Johnston 			    DISP, TRY_NEG);
49650339a1c2SMark Johnston 
49660339a1c2SMark Johnston 			if (op->d86_mode == MODE_RIPREL)
49670339a1c2SMark Johnston 				(void) strlcat(buf, "(%rip)", buflen);
49680339a1c2SMark Johnston 			break;
49690339a1c2SMark Johnston 		}
49700339a1c2SMark Johnston 	}
49710339a1c2SMark Johnston 
49720339a1c2SMark Johnston 	/*
49730339a1c2SMark Johnston 	 * The symbol lookups may result in false positives,
49740339a1c2SMark Johnston 	 * particularly on object files, where small numbers may match
49750339a1c2SMark Johnston 	 * the 0-relative non-relocated addresses of symbols.
49760339a1c2SMark Johnston 	 */
49770339a1c2SMark Johnston 
49780339a1c2SMark Johnston 	lookup = dis->d86_sym_lookup;
49790339a1c2SMark Johnston 	if (tgt != 0) {
49800339a1c2SMark Johnston 		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
49810339a1c2SMark Johnston 		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
49820339a1c2SMark Johnston 			(void) strlcat(buf, "\t<", buflen);
49830339a1c2SMark Johnston 			curlen = strlen(buf);
49840339a1c2SMark Johnston 			lookup(dis->d86_data, tgt, buf + curlen,
49850339a1c2SMark Johnston 			    buflen - curlen);
49860339a1c2SMark Johnston 			(void) strlcat(buf, ">", buflen);
49870339a1c2SMark Johnston 		}
49880339a1c2SMark Johnston 
49890339a1c2SMark Johnston 		/*
49900339a1c2SMark Johnston 		 * If we printed a negative immediate above, print the
49910339a1c2SMark Johnston 		 * positive in case our heuristic was unhelpful
49920339a1c2SMark Johnston 		 */
49930339a1c2SMark Johnston 		if (save_usv) {
49940339a1c2SMark Johnston 			(void) strlcat(buf, "\t<", buflen);
49950339a1c2SMark Johnston 			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
49960339a1c2SMark Johnston 			    IMM, POS);
49970339a1c2SMark Johnston 			(void) strlcat(buf, ">", buflen);
49980339a1c2SMark Johnston 		}
49990339a1c2SMark Johnston 	}
50000339a1c2SMark Johnston 
50010339a1c2SMark Johnston 	if (reltgt != 0) {
50020339a1c2SMark Johnston 		/* Print symbol or effective address for reltgt */
50030339a1c2SMark Johnston 
50040339a1c2SMark Johnston 		(void) strlcat(buf, "\t<", buflen);
50050339a1c2SMark Johnston 		curlen = strlen(buf);
50060339a1c2SMark Johnston 		lookup(dis->d86_data, reltgt, buf + curlen,
50070339a1c2SMark Johnston 		    buflen - curlen);
50080339a1c2SMark Johnston 		(void) strlcat(buf, ">", buflen);
50090339a1c2SMark Johnston 	}
50100339a1c2SMark Johnston }
50110339a1c2SMark Johnston 
50120339a1c2SMark Johnston #endif /* DIS_TEXT */
5013