xref: /freebsd/sys/cddl/dev/dtrace/x86/dis_tables.c (revision b3b5bfeb224c694b6eba9158a50b046cc3d71ebe)
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.
24*b3b5bfebSMark Johnston  * Copyright 2016 Joyent, Inc.
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 */
90*b3b5bfebSMark Johnston 	uint_t		it_vexwoxmm:1;		/* VEX instructions that don't use XMM/YMM */
91*b3b5bfebSMark Johnston 	uint_t		it_avxsuf:1;		/* AVX suffix required */
920339a1c2SMark Johnston } instable_t;
930339a1c2SMark Johnston 
940339a1c2SMark Johnston /*
950339a1c2SMark Johnston  * Instruction formats.
960339a1c2SMark Johnston  */
970339a1c2SMark Johnston enum {
980339a1c2SMark Johnston 	UNKNOWN,
990339a1c2SMark Johnston 	MRw,
1000339a1c2SMark Johnston 	IMlw,
1010339a1c2SMark Johnston 	IMw,
1020339a1c2SMark Johnston 	IR,
1030339a1c2SMark Johnston 	OA,
1040339a1c2SMark Johnston 	AO,
1050339a1c2SMark Johnston 	MS,
1060339a1c2SMark Johnston 	SM,
1070339a1c2SMark Johnston 	Mv,
1080339a1c2SMark Johnston 	Mw,
1090339a1c2SMark Johnston 	M,		/* register or memory */
110c3ddb60eSPeter Grehan 	MG9,		/* register or memory in group 9 (prefix optional) */
1110339a1c2SMark Johnston 	Mb,		/* register or memory, always byte sized */
1120339a1c2SMark Johnston 	MO,		/* memory only (no registers) */
1130339a1c2SMark Johnston 	PREF,
114c3ddb60eSPeter Grehan 	SWAPGS_RDTSCP,
1150339a1c2SMark Johnston 	MONITOR_MWAIT,
1160339a1c2SMark Johnston 	R,
1170339a1c2SMark Johnston 	RA,
1180339a1c2SMark Johnston 	SEG,
1190339a1c2SMark Johnston 	MR,
1200339a1c2SMark Johnston 	RM,
121c3ddb60eSPeter Grehan 	RM_66r,		/* RM, but with a required 0x66 prefix */
1220339a1c2SMark Johnston 	IA,
1230339a1c2SMark Johnston 	MA,
1240339a1c2SMark Johnston 	SD,
1250339a1c2SMark Johnston 	AD,
1260339a1c2SMark Johnston 	SA,
1270339a1c2SMark Johnston 	D,
1280339a1c2SMark Johnston 	INM,
1290339a1c2SMark Johnston 	SO,
1300339a1c2SMark Johnston 	BD,
1310339a1c2SMark Johnston 	I,
1320339a1c2SMark Johnston 	P,
1330339a1c2SMark Johnston 	V,
1340339a1c2SMark Johnston 	DSHIFT,		/* for double shift that has an 8-bit immediate */
1350339a1c2SMark Johnston 	U,
1360339a1c2SMark Johnston 	OVERRIDE,
1370339a1c2SMark Johnston 	NORM,		/* instructions w/o ModR/M byte, no memory access */
1380339a1c2SMark Johnston 	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
1390339a1c2SMark Johnston 	O,		/* for call	*/
1400339a1c2SMark Johnston 	JTAB,		/* jump table 	*/
1410339a1c2SMark Johnston 	IMUL,		/* for 186 iimul instr  */
1420339a1c2SMark Johnston 	CBW,		/* so data16 can be evaluated for cbw and variants */
1430339a1c2SMark Johnston 	MvI,		/* for 186 logicals */
1440339a1c2SMark Johnston 	ENTER,		/* for 186 enter instr  */
1450339a1c2SMark Johnston 	RMw,		/* for 286 arpl instr */
1460339a1c2SMark Johnston 	Ib,		/* for push immediate byte */
1470339a1c2SMark Johnston 	F,		/* for 287 instructions */
1480339a1c2SMark Johnston 	FF,		/* for 287 instructions */
1490339a1c2SMark Johnston 	FFC,		/* for 287 instructions */
1500339a1c2SMark Johnston 	DM,		/* 16-bit data */
1510339a1c2SMark Johnston 	AM,		/* 16-bit addr */
1520339a1c2SMark Johnston 	LSEG,		/* for 3-bit seg reg encoding */
1530339a1c2SMark Johnston 	MIb,		/* for 386 logicals */
1540339a1c2SMark Johnston 	SREG,		/* for 386 special registers */
1550339a1c2SMark Johnston 	PREFIX,		/* a REP instruction prefix */
1560339a1c2SMark Johnston 	LOCK,		/* a LOCK instruction prefix */
1570339a1c2SMark Johnston 	INT3,		/* The int 3 instruction, which has a fake operand */
1580339a1c2SMark Johnston 	INTx,		/* The normal int instruction, with explicit int num */
1590339a1c2SMark Johnston 	DSHIFTcl,	/* for double shift that implicitly uses %cl */
1600339a1c2SMark Johnston 	CWD,		/* so data16 can be evaluated for cwd and variants */
1610339a1c2SMark Johnston 	RET,		/* single immediate 16-bit operand */
1620339a1c2SMark Johnston 	MOVZ,		/* for movs and movz, with different size operands */
1630339a1c2SMark Johnston 	CRC32,		/* for crc32, with different size operands */
1640339a1c2SMark Johnston 	XADDB,		/* for xaddb */
1650339a1c2SMark Johnston 	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
1660339a1c2SMark Johnston 	MOVBE,		/* movbe instruction */
1670339a1c2SMark Johnston 
1680339a1c2SMark Johnston /*
1690339a1c2SMark Johnston  * MMX/SIMD addressing modes.
1700339a1c2SMark Johnston  */
1710339a1c2SMark Johnston 
1720339a1c2SMark Johnston 	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
1730339a1c2SMark Johnston 	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
1740339a1c2SMark Johnston 	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
1750339a1c2SMark Johnston 	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
1760339a1c2SMark Johnston 	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
1770339a1c2SMark Johnston 	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
1780339a1c2SMark Johnston 	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
1790339a1c2SMark Johnston 	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
1800339a1c2SMark Johnston 	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
1810339a1c2SMark Johnston 	MMOSH,		/* Prefixable MMX		mm,imm8	*/
1820339a1c2SMark Johnston 	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
1830339a1c2SMark Johnston 	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
1840339a1c2SMark Johnston 	MMSH,		/* MMX				mm,imm8 */
1850339a1c2SMark Johnston 	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
1860339a1c2SMark Johnston 	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
1870339a1c2SMark Johnston 	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
1880339a1c2SMark Johnston 	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
1890339a1c2SMark Johnston 	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
1900339a1c2SMark Johnston 	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
1910339a1c2SMark Johnston 	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
1920339a1c2SMark Johnston 	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
1930339a1c2SMark Johnston 	XMM,		/* SIMD 			xmm/mem	-> xmm */
1940339a1c2SMark Johnston 	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
1950339a1c2SMark Johnston 	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
1960339a1c2SMark Johnston 	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
1970339a1c2SMark Johnston 	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
1980339a1c2SMark Johnston 	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
1990339a1c2SMark Johnston 	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
2000339a1c2SMark Johnston 	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
2010339a1c2SMark Johnston 	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
2020339a1c2SMark Johnston 	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
2030339a1c2SMark Johnston 	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
2040339a1c2SMark Johnston 	XMMS,		/* SIMD				xmm	-> xmm/mem */
2050339a1c2SMark Johnston 	XMMM,		/* SIMD 			mem	-> xmm */
2060339a1c2SMark Johnston 	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
2070339a1c2SMark Johnston 	XMMMS,		/* SIMD				xmm	-> mem */
2080339a1c2SMark Johnston 	XMM3MX,		/* SIMD 			r32/mem -> xmm */
2090339a1c2SMark Johnston 	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
2100339a1c2SMark Johnston 	XMMSH,		/* SIMD 			xmm,imm8 */
2110339a1c2SMark Johnston 	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
2120339a1c2SMark Johnston 	XMMX3,		/* SIMD 			xmm	-> r32 */
2130339a1c2SMark Johnston 	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
2140339a1c2SMark Johnston 	XMMMX,		/* SIMD 			mm	-> xmm */
2150339a1c2SMark Johnston 	XMMXM,		/* SIMD 			xmm	-> mm */
2160339a1c2SMark Johnston         XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
2170339a1c2SMark Johnston         XMM2I,		/* SIMD				xmm, imm, imm */
2180339a1c2SMark Johnston 	XMMFENCE,	/* SIMD lfence or mfence */
2190339a1c2SMark Johnston 	XMMSFNC,	/* SIMD sfence (none or mem) */
2200339a1c2SMark Johnston 	XGETBV_XSETBV,
2210339a1c2SMark Johnston 	VEX_NONE,	/* VEX  no operand */
2220339a1c2SMark Johnston 	VEX_MO,		/* VEX	mod_rm		               -> implicit reg */
2230339a1c2SMark Johnston 	VEX_RMrX,	/* VEX  VEX.vvvv, mod_rm               -> mod_reg */
224*b3b5bfebSMark Johnston 	VEX_VRMrX,	/* VEX  mod_rm, VEX.vvvv               -> mod_rm */
2250339a1c2SMark Johnston 	VEX_RRX,	/* VEX  VEX.vvvv, mod_reg              -> mod_rm */
2260339a1c2SMark Johnston 	VEX_RMRX,	/* VEX  VEX.vvvv, mod_rm, imm8[7:4]    -> mod_reg */
2270339a1c2SMark Johnston 	VEX_MX,         /* VEX  mod_rm                         -> mod_reg */
2280339a1c2SMark Johnston 	VEX_MXI,        /* VEX  mod_rm, imm8                   -> mod_reg */
2290339a1c2SMark Johnston 	VEX_XXI,        /* VEX  mod_rm, imm8                   -> VEX.vvvv */
2300339a1c2SMark Johnston 	VEX_MR,         /* VEX  mod_rm                         -> mod_reg */
2310339a1c2SMark Johnston 	VEX_RRI,        /* VEX  mod_reg, mod_rm                -> implicit(eflags/r32) */
2320339a1c2SMark Johnston 	VEX_RX,         /* VEX  mod_reg                        -> mod_rm */
2330339a1c2SMark Johnston 	VEX_RR,         /* VEX  mod_rm                         -> mod_reg */
2340339a1c2SMark Johnston 	VEX_RRi,        /* VEX  mod_rm, imm8                   -> mod_reg */
2350339a1c2SMark Johnston 	VEX_RM,         /* VEX  mod_reg                        -> mod_rm */
236*b3b5bfebSMark Johnston 	VEX_RIM,	/* VEX  mod_reg, imm8                  -> mod_rm */
2370339a1c2SMark Johnston 	VEX_RRM,        /* VEX  VEX.vvvv, mod_reg              -> mod_rm */
238c3ddb60eSPeter Grehan 	VEX_RMX,        /* VEX  VEX.vvvv, mod_rm               -> mod_reg */
239*b3b5bfebSMark Johnston 	VEX_SbVM,	/* VEX  SIB, VEX.vvvv                  -> mod_rm */
240c3ddb60eSPeter Grehan 	VMx,		/* vmcall/vmlaunch/vmresume/vmxoff */
241c3ddb60eSPeter Grehan 	VMxo,		/* VMx instruction with optional prefix */
242*b3b5bfebSMark Johnston 	SVM,		/* AMD SVM instructions */
243*b3b5bfebSMark Johnston 	BLS,		/* BLSR, BLSMSK, BLSI */
244*b3b5bfebSMark Johnston 	FMA,		/* FMA instructions, all VEX_RMrX */
245*b3b5bfebSMark Johnston 	ADX		/* ADX instructions, support REX.w, mod_rm->mod_reg */
2460339a1c2SMark Johnston };
2470339a1c2SMark Johnston 
2480339a1c2SMark Johnston /*
2490339a1c2SMark Johnston  * VEX prefixes
2500339a1c2SMark Johnston  */
2510339a1c2SMark Johnston #define VEX_2bytes	0xC5	/* the first byte of two-byte form */
2520339a1c2SMark Johnston #define VEX_3bytes	0xC4	/* the first byte of three-byte form */
2530339a1c2SMark Johnston 
2540339a1c2SMark Johnston #define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
2550339a1c2SMark Johnston 
2560339a1c2SMark Johnston /*
2570339a1c2SMark Johnston ** Register numbers for the i386
2580339a1c2SMark Johnston */
2590339a1c2SMark Johnston #define	EAX_REGNO 0
2600339a1c2SMark Johnston #define	ECX_REGNO 1
2610339a1c2SMark Johnston #define	EDX_REGNO 2
2620339a1c2SMark Johnston #define	EBX_REGNO 3
2630339a1c2SMark Johnston #define	ESP_REGNO 4
2640339a1c2SMark Johnston #define	EBP_REGNO 5
2650339a1c2SMark Johnston #define	ESI_REGNO 6
2660339a1c2SMark Johnston #define	EDI_REGNO 7
2670339a1c2SMark Johnston 
2680339a1c2SMark Johnston /*
2690339a1c2SMark Johnston  * modes for immediate values
2700339a1c2SMark Johnston  */
2710339a1c2SMark Johnston #define	MODE_NONE	0
2720339a1c2SMark Johnston #define	MODE_IPREL	1	/* signed IP relative value */
2730339a1c2SMark Johnston #define	MODE_SIGNED	2	/* sign extended immediate */
2740339a1c2SMark Johnston #define	MODE_IMPLIED	3	/* constant value implied from opcode */
2750339a1c2SMark Johnston #define	MODE_OFFSET	4	/* offset part of an address */
2760339a1c2SMark Johnston #define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
2770339a1c2SMark Johnston 
2780339a1c2SMark Johnston /*
2790339a1c2SMark Johnston  * The letters used in these macros are:
2800339a1c2SMark Johnston  *   IND - indirect to another to another table
2810339a1c2SMark Johnston  *   "T" - means to Terminate indirections (this is the final opcode)
2820339a1c2SMark Johnston  *   "S" - means "operand length suffix required"
283*b3b5bfebSMark Johnston  *   "Sa" - means AVX2 suffix (d/q) required
2840339a1c2SMark Johnston  *   "NS" - means "no suffix" which is the operand length suffix of the opcode
2850339a1c2SMark Johnston  *   "Z" - means instruction size arg required
2860339a1c2SMark Johnston  *   "u" - means the opcode is invalid in IA32 but valid in amd64
2870339a1c2SMark Johnston  *   "x" - means the opcode is invalid in amd64, but not IA32
2880339a1c2SMark Johnston  *   "y" - means the operand size is always 64 bits in 64 bit mode
2890339a1c2SMark Johnston  *   "p" - means push/pop stack operation
290*b3b5bfebSMark Johnston  *   "vr" - means VEX instruction that operates on normal registers, not fpu
2910339a1c2SMark Johnston  */
2920339a1c2SMark Johnston 
2930339a1c2SMark Johnston #if defined(DIS_TEXT) && defined(DIS_MEM)
2940339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
2950339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
2960339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
2970339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
2980339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
2990339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
3000339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
3010339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
3020339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
303*b3b5bfebSMark Johnston #define	TNSZvr(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0, 1}
3040339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
3050339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
3060339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
3070339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
3080339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
309*b3b5bfebSMark Johnston #define	TSaZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0, 0, 1}
3100339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
3110339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
3120339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3130339a1c2SMark Johnston #elif defined(DIS_TEXT)
3140339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
3150339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
3160339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
3170339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
3180339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
3190339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
3200339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
3210339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
3220339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
323*b3b5bfebSMark Johnston #define	TNSZvr(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0, 1}
3240339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
3250339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
3260339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
3270339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
3280339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
329*b3b5bfebSMark Johnston #define	TSaZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0, 0, 1}
3300339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
3310339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
3320339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
3330339a1c2SMark Johnston #elif defined(DIS_MEM)
3340339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
3350339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
3360339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
3370339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
3380339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
3390339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
3400339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
3410339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
3420339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
343*b3b5bfebSMark Johnston #define	TNSZvr(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0, 1}
3440339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
3450339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
3460339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
3470339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
3480339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
349*b3b5bfebSMark Johnston #define	TSaZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0, 0, 1}
3500339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
3510339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
3520339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
3530339a1c2SMark Johnston #else
3540339a1c2SMark Johnston #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
3550339a1c2SMark Johnston #define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
3560339a1c2SMark Johnston #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
3570339a1c2SMark Johnston #define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
3580339a1c2SMark Johnston #define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3590339a1c2SMark Johnston #define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
3600339a1c2SMark Johnston #define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3610339a1c2SMark Johnston #define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
3620339a1c2SMark Johnston #define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
363*b3b5bfebSMark Johnston #define	TNSZvr(name, amode, sz)	{TERM, amode,  0, 0, 0, 0, 1}
3640339a1c2SMark Johnston #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
3650339a1c2SMark Johnston #define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
3660339a1c2SMark Johnston #define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
3670339a1c2SMark Johnston #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
3680339a1c2SMark Johnston #define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
369*b3b5bfebSMark Johnston #define	TSaZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0, 0, 1}
3700339a1c2SMark Johnston #define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
3710339a1c2SMark Johnston #define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
3720339a1c2SMark Johnston #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
3730339a1c2SMark Johnston #endif
3740339a1c2SMark Johnston 
3750339a1c2SMark Johnston #ifdef DIS_TEXT
3760339a1c2SMark Johnston /*
3770339a1c2SMark Johnston  * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
3780339a1c2SMark Johnston  */
3790339a1c2SMark Johnston const char *const dis_addr16[3][8] = {
3800339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
3810339a1c2SMark Johnston 									"(%bx)",
3820339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
3830339a1c2SMark Johnston 									"(%bx)",
3840339a1c2SMark Johnston "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
3850339a1c2SMark Johnston 									"(%bx)",
3860339a1c2SMark Johnston };
3870339a1c2SMark Johnston 
3880339a1c2SMark Johnston 
3890339a1c2SMark Johnston /*
3900339a1c2SMark Johnston  * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
3910339a1c2SMark Johnston  */
3920339a1c2SMark Johnston const char *const dis_addr32_mode0[16] = {
3930339a1c2SMark Johnston   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
3940339a1c2SMark Johnston   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
3950339a1c2SMark Johnston };
3960339a1c2SMark Johnston 
3970339a1c2SMark Johnston const char *const dis_addr32_mode12[16] = {
3980339a1c2SMark Johnston   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
3990339a1c2SMark Johnston   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
4000339a1c2SMark Johnston };
4010339a1c2SMark Johnston 
4020339a1c2SMark Johnston /*
4030339a1c2SMark Johnston  * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
4040339a1c2SMark Johnston  */
4050339a1c2SMark Johnston const char *const dis_addr64_mode0[16] = {
4060339a1c2SMark Johnston  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
4070339a1c2SMark Johnston  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
4080339a1c2SMark Johnston };
4090339a1c2SMark Johnston const char *const dis_addr64_mode12[16] = {
4100339a1c2SMark Johnston  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
4110339a1c2SMark Johnston  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
4120339a1c2SMark Johnston };
4130339a1c2SMark Johnston 
4140339a1c2SMark Johnston /*
4150339a1c2SMark Johnston  * decode for scale from SIB byte
4160339a1c2SMark Johnston  */
4170339a1c2SMark Johnston const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
4180339a1c2SMark Johnston 
4190339a1c2SMark Johnston /*
420*b3b5bfebSMark Johnston  * decode for scale from VSIB byte, note that we always include the scale factor
421*b3b5bfebSMark Johnston  * to match gas.
422*b3b5bfebSMark Johnston  */
423*b3b5bfebSMark Johnston const char *const dis_vscale_factor[4] = { ",1)", ",2)", ",4)", ",8)" };
424*b3b5bfebSMark Johnston 
425*b3b5bfebSMark Johnston /*
4260339a1c2SMark Johnston  * register decoding for normal references to registers (ie. not addressing)
4270339a1c2SMark Johnston  */
4280339a1c2SMark Johnston const char *const dis_REG8[16] = {
4290339a1c2SMark Johnston 	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
4300339a1c2SMark Johnston 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4310339a1c2SMark Johnston };
4320339a1c2SMark Johnston 
4330339a1c2SMark Johnston const char *const dis_REG8_REX[16] = {
4340339a1c2SMark Johnston 	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
4350339a1c2SMark Johnston 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
4360339a1c2SMark Johnston };
4370339a1c2SMark Johnston 
4380339a1c2SMark Johnston const char *const dis_REG16[16] = {
4390339a1c2SMark Johnston 	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
4400339a1c2SMark Johnston 	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
4410339a1c2SMark Johnston };
4420339a1c2SMark Johnston 
4430339a1c2SMark Johnston const char *const dis_REG32[16] = {
4440339a1c2SMark Johnston 	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
4450339a1c2SMark Johnston 	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
4460339a1c2SMark Johnston };
4470339a1c2SMark Johnston 
4480339a1c2SMark Johnston const char *const dis_REG64[16] = {
4490339a1c2SMark Johnston 	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
4500339a1c2SMark Johnston 	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
4510339a1c2SMark Johnston };
4520339a1c2SMark Johnston 
4530339a1c2SMark Johnston const char *const dis_DEBUGREG[16] = {
4540339a1c2SMark Johnston 	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
4550339a1c2SMark Johnston 	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
4560339a1c2SMark Johnston };
4570339a1c2SMark Johnston 
4580339a1c2SMark Johnston const char *const dis_CONTROLREG[16] = {
4590339a1c2SMark Johnston     "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
4600339a1c2SMark Johnston     "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
4610339a1c2SMark Johnston };
4620339a1c2SMark Johnston 
4630339a1c2SMark Johnston const char *const dis_TESTREG[16] = {
4640339a1c2SMark Johnston 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
4650339a1c2SMark Johnston 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
4660339a1c2SMark Johnston };
4670339a1c2SMark Johnston 
4680339a1c2SMark Johnston const char *const dis_MMREG[16] = {
4690339a1c2SMark Johnston 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
4700339a1c2SMark Johnston 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
4710339a1c2SMark Johnston };
4720339a1c2SMark Johnston 
4730339a1c2SMark Johnston const char *const dis_XMMREG[16] = {
4740339a1c2SMark Johnston     "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
4750339a1c2SMark Johnston     "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
4760339a1c2SMark Johnston };
4770339a1c2SMark Johnston 
4780339a1c2SMark Johnston const char *const dis_YMMREG[16] = {
4790339a1c2SMark Johnston     "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
4800339a1c2SMark Johnston     "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15"
4810339a1c2SMark Johnston };
4820339a1c2SMark Johnston 
4830339a1c2SMark Johnston const char *const dis_SEGREG[16] = {
4840339a1c2SMark Johnston 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
4850339a1c2SMark Johnston 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
4860339a1c2SMark Johnston };
4870339a1c2SMark Johnston 
4880339a1c2SMark Johnston /*
4890339a1c2SMark Johnston  * SIMD predicate suffixes
4900339a1c2SMark Johnston  */
4910339a1c2SMark Johnston const char *const dis_PREDSUFFIX[8] = {
4920339a1c2SMark Johnston 	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
4930339a1c2SMark Johnston };
4940339a1c2SMark Johnston 
4950339a1c2SMark Johnston const char *const dis_AVXvgrp7[3][8] = {
4960339a1c2SMark Johnston 	/*0	1	2		3		4		5	6		7*/
4970339a1c2SMark Johnston /*71*/	{"",	"",	"vpsrlw",	"",		"vpsraw",	"",	"vpsllw",	""},
4980339a1c2SMark Johnston /*72*/	{"",	"",	"vpsrld",	"",		"vpsrad",	"",	"vpslld",	""},
4990339a1c2SMark Johnston /*73*/	{"",	"",	"vpsrlq",	"vpsrldq",	"",		"",	"vpsllq",	"vpslldq"}
5000339a1c2SMark Johnston };
5010339a1c2SMark Johnston 
5020339a1c2SMark Johnston #endif	/* DIS_TEXT */
5030339a1c2SMark Johnston 
5040339a1c2SMark Johnston /*
5050339a1c2SMark Johnston  *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
5060339a1c2SMark Johnston  */
5070339a1c2SMark Johnston const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
5080339a1c2SMark Johnston 
5090339a1c2SMark Johnston /*
5100339a1c2SMark Johnston  *	"decode table" for pause and clflush instructions
5110339a1c2SMark Johnston  */
5120339a1c2SMark Johnston const instable_t dis_opPause = TNS("pause", NORM);
5130339a1c2SMark Johnston 
5140339a1c2SMark Johnston /*
5150339a1c2SMark Johnston  *	Decode table for 0x0F00 opcodes
5160339a1c2SMark Johnston  */
5170339a1c2SMark Johnston const instable_t dis_op0F00[8] = {
5180339a1c2SMark Johnston 
5190339a1c2SMark Johnston /*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
5200339a1c2SMark Johnston /*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
5210339a1c2SMark Johnston };
5220339a1c2SMark Johnston 
5230339a1c2SMark Johnston 
5240339a1c2SMark Johnston /*
5250339a1c2SMark Johnston  *	Decode table for 0x0F01 opcodes
5260339a1c2SMark Johnston  */
5270339a1c2SMark Johnston const instable_t dis_op0F01[8] = {
5280339a1c2SMark Johnston 
529c3ddb60eSPeter Grehan /*  [0]  */	TNSZ("sgdt",VMx,6),	TNSZ("sidt",MONITOR_MWAIT,6),	TNSZ("lgdt",XGETBV_XSETBV,6),	TNSZ("lidt",SVM,6),
530c3ddb60eSPeter Grehan /*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS_RDTSCP),
5310339a1c2SMark Johnston };
5320339a1c2SMark Johnston 
5330339a1c2SMark Johnston /*
5340339a1c2SMark Johnston  *	Decode table for 0x0F18 opcodes -- SIMD prefetch
5350339a1c2SMark Johnston  */
5360339a1c2SMark Johnston const instable_t dis_op0F18[8] = {
5370339a1c2SMark Johnston 
5380339a1c2SMark Johnston /*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
5390339a1c2SMark Johnston /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
5400339a1c2SMark Johnston };
5410339a1c2SMark Johnston 
5420339a1c2SMark Johnston /*
5430339a1c2SMark Johnston  * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
5440339a1c2SMark Johnston  */
5450339a1c2SMark Johnston const instable_t dis_op0FAE[8] = {
5460339a1c2SMark Johnston /*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
5470339a1c2SMark Johnston /*  [4]  */	TNSZ("xsave",M,512),	TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
5480339a1c2SMark Johnston };
5490339a1c2SMark Johnston 
5500339a1c2SMark Johnston /*
5510339a1c2SMark Johnston  *	Decode table for 0x0FBA opcodes
5520339a1c2SMark Johnston  */
5530339a1c2SMark Johnston 
5540339a1c2SMark Johnston const instable_t dis_op0FBA[8] = {
5550339a1c2SMark Johnston 
5560339a1c2SMark Johnston /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
5570339a1c2SMark Johnston /*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
5580339a1c2SMark Johnston };
5590339a1c2SMark Johnston 
5600339a1c2SMark Johnston /*
561c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode (group 9)
5620339a1c2SMark Johnston  */
5630339a1c2SMark Johnston 
5640339a1c2SMark Johnston const instable_t dis_op0FC7[8] = {
5650339a1c2SMark Johnston 
5660339a1c2SMark Johnston /*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
567c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmptrld",MG9),	TNS("vmptrst",MG9),
5680339a1c2SMark Johnston };
5690339a1c2SMark Johnston 
570c3ddb60eSPeter Grehan /*
571c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode (group 9) mode 3
572c3ddb60eSPeter Grehan  */
573c3ddb60eSPeter Grehan 
574c3ddb60eSPeter Grehan const instable_t dis_op0FC7m3[8] = {
575c3ddb60eSPeter Grehan 
576c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,	INVALID,		INVALID,
577*b3b5bfebSMark Johnston /*  [4]  */	INVALID,		INVALID,	TNS("rdrand",MG9),	TNS("rdseed", MG9),
578c3ddb60eSPeter Grehan };
579c3ddb60eSPeter Grehan 
580c3ddb60eSPeter Grehan /*
581c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode with 0x66 prefix
582c3ddb60eSPeter Grehan  */
583c3ddb60eSPeter Grehan 
584c3ddb60eSPeter Grehan const instable_t dis_op660FC7[8] = {
585c3ddb60eSPeter Grehan 
586c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
587c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmclear",M),	INVALID,
588c3ddb60eSPeter Grehan };
589c3ddb60eSPeter Grehan 
590c3ddb60eSPeter Grehan /*
591c3ddb60eSPeter Grehan  * 	Decode table for 0x0FC7 opcode with 0xF3 prefix
592c3ddb60eSPeter Grehan  */
593c3ddb60eSPeter Grehan 
594c3ddb60eSPeter Grehan const instable_t dis_opF30FC7[8] = {
595c3ddb60eSPeter Grehan 
596c3ddb60eSPeter Grehan /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
597c3ddb60eSPeter Grehan /*  [4]  */	INVALID,		INVALID,		TNS("vmxon",M),		INVALID,
598c3ddb60eSPeter Grehan };
5990339a1c2SMark Johnston 
6000339a1c2SMark Johnston /*
6010339a1c2SMark Johnston  *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
6020339a1c2SMark Johnston  *
6030339a1c2SMark Johnston  *bit pattern: 0000 1111 1100 1reg
6040339a1c2SMark Johnston  */
6050339a1c2SMark Johnston const instable_t dis_op0FC8[4] = {
6060339a1c2SMark Johnston /*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
6070339a1c2SMark Johnston };
6080339a1c2SMark Johnston 
6090339a1c2SMark Johnston /*
6100339a1c2SMark Johnston  *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
6110339a1c2SMark Johnston  */
6120339a1c2SMark Johnston const instable_t dis_op0F7123[4][8] = {
6130339a1c2SMark Johnston {
6140339a1c2SMark Johnston /*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
6150339a1c2SMark Johnston /*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
6160339a1c2SMark Johnston }, {
6170339a1c2SMark Johnston /*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
6180339a1c2SMark Johnston /*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
6190339a1c2SMark Johnston }, {
6200339a1c2SMark Johnston /*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
6210339a1c2SMark Johnston /*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
6220339a1c2SMark Johnston }, {
6230339a1c2SMark Johnston /*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
6240339a1c2SMark Johnston /*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
6250339a1c2SMark Johnston } };
6260339a1c2SMark Johnston 
6270339a1c2SMark Johnston /*
6280339a1c2SMark Johnston  *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
6290339a1c2SMark Johnston  */
6300339a1c2SMark Johnston const instable_t dis_opSIMD7123[32] = {
6310339a1c2SMark Johnston /* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
6320339a1c2SMark Johnston /*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
6330339a1c2SMark Johnston 
6340339a1c2SMark Johnston /* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
6350339a1c2SMark Johnston /*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
6360339a1c2SMark Johnston 
6370339a1c2SMark Johnston /* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
6380339a1c2SMark Johnston /*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
6390339a1c2SMark Johnston 
6400339a1c2SMark Johnston /* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
6410339a1c2SMark Johnston /*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
6420339a1c2SMark Johnston };
6430339a1c2SMark Johnston 
6440339a1c2SMark Johnston /*
6450339a1c2SMark Johnston  *	SIMD instructions have been wedged into the existing IA32 instruction
6460339a1c2SMark Johnston  *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
6470339a1c2SMark Johnston  *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
6480339a1c2SMark Johnston  *	instruction - addss.  At present, three prefixes have been coopted in
6490339a1c2SMark Johnston  *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
6500339a1c2SMark Johnston  *	following tables are used to provide the prefixed instruction names.
6510339a1c2SMark Johnston  *	The arrays are sparse, but they're fast.
6520339a1c2SMark Johnston  */
6530339a1c2SMark Johnston 
6540339a1c2SMark Johnston /*
6550339a1c2SMark Johnston  *	Decode table for SIMD instructions with the address size (0x66) prefix.
6560339a1c2SMark Johnston  */
6570339a1c2SMark Johnston const instable_t dis_opSIMDdata16[256] = {
6580339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
6590339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
6600339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
6610339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6620339a1c2SMark Johnston 
6630339a1c2SMark Johnston /*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
6640339a1c2SMark Johnston /*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
6650339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
6660339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6670339a1c2SMark Johnston 
6680339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
6690339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
6700339a1c2SMark Johnston /*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
6710339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
6720339a1c2SMark Johnston 
6730339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
6740339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
6750339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
6760339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6770339a1c2SMark Johnston 
6780339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
6790339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
6800339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
6810339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
6820339a1c2SMark Johnston 
6830339a1c2SMark Johnston /*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
6840339a1c2SMark Johnston /*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
6850339a1c2SMark Johnston /*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
6860339a1c2SMark Johnston /*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
6870339a1c2SMark Johnston 
6880339a1c2SMark Johnston /*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
6890339a1c2SMark Johnston /*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
6900339a1c2SMark Johnston /*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
6910339a1c2SMark Johnston /*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
6920339a1c2SMark Johnston 
6930339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
6940339a1c2SMark Johnston /*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
6950339a1c2SMark Johnston /*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
696*b3b5bfebSMark Johnston /*  [7C]  */	TNSZ("haddpd",XMM,16),	TNSZ("hsubpd",XMM,16),	TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
6970339a1c2SMark Johnston 
6980339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
6990339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
7000339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
7010339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7020339a1c2SMark Johnston 
7030339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
7040339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
7050339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
7060339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7070339a1c2SMark Johnston 
7080339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7090339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7100339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7110339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7120339a1c2SMark Johnston 
7130339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7140339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7150339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7160339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7170339a1c2SMark Johnston 
7180339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
7190339a1c2SMark Johnston /*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
7200339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7210339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7220339a1c2SMark Johnston 
723*b3b5bfebSMark Johnston /*  [D0]  */	TNSZ("addsubpd",XMM,16),TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
7240339a1c2SMark Johnston /*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
7250339a1c2SMark Johnston /*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
7260339a1c2SMark Johnston /*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
7270339a1c2SMark Johnston 
7280339a1c2SMark Johnston /*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
7290339a1c2SMark Johnston /*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
7300339a1c2SMark Johnston /*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
7310339a1c2SMark Johnston /*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
7320339a1c2SMark Johnston 
7330339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
7340339a1c2SMark Johnston /*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
7350339a1c2SMark Johnston /*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
7360339a1c2SMark Johnston /*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
7370339a1c2SMark Johnston };
7380339a1c2SMark Johnston 
7390339a1c2SMark Johnston const instable_t dis_opAVX660F[256] = {
7400339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
7410339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
7420339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
7430339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7440339a1c2SMark Johnston 
7450339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovupd",VEX_MX,16),	TNSZ("vmovupd",VEX_RX,16),	TNSZ("vmovlpd",VEX_RMrX,8),	TNSZ("vmovlpd",VEX_RM,8),
7460339a1c2SMark Johnston /*  [14]  */	TNSZ("vunpcklpd",VEX_RMrX,16),TNSZ("vunpckhpd",VEX_RMrX,16),TNSZ("vmovhpd",VEX_RMrX,8),	TNSZ("vmovhpd",VEX_RM,8),
7470339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
7480339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7490339a1c2SMark Johnston 
7500339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
7510339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
7520339a1c2SMark Johnston /*  [28]  */	TNSZ("vmovapd",VEX_MX,16),	TNSZ("vmovapd",VEX_RX,16),	INVALID,		TNSZ("vmovntpd",VEX_RM,16),
7530339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomisd",VEX_MX,8),TNSZ("vcomisd",VEX_MX,8),
7540339a1c2SMark Johnston 
7550339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
7560339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
7570339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
7580339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7590339a1c2SMark Johnston 
7600339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
7610339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
7620339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
7630339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7640339a1c2SMark Johnston 
7650339a1c2SMark Johnston /*  [50]  */	TNS("vmovmskpd",VEX_MR),	TNSZ("vsqrtpd",VEX_MX,16),	INVALID,		INVALID,
7660339a1c2SMark Johnston /*  [54]  */	TNSZ("vandpd",VEX_RMrX,16),	TNSZ("vandnpd",VEX_RMrX,16),	TNSZ("vorpd",VEX_RMrX,16),	TNSZ("vxorpd",VEX_RMrX,16),
7670339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddpd",VEX_RMrX,16),	TNSZ("vmulpd",VEX_RMrX,16),	TNSZ("vcvtpd2ps",VEX_MX,16),TNSZ("vcvtps2dq",VEX_MX,16),
7680339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubpd",VEX_RMrX,16),	TNSZ("vminpd",VEX_RMrX,16),	TNSZ("vdivpd",VEX_RMrX,16),	TNSZ("vmaxpd",VEX_RMrX,16),
7690339a1c2SMark Johnston 
7700339a1c2SMark Johnston /*  [60]  */	TNSZ("vpunpcklbw",VEX_RMrX,16),TNSZ("vpunpcklwd",VEX_RMrX,16),TNSZ("vpunpckldq",VEX_RMrX,16),TNSZ("vpacksswb",VEX_RMrX,16),
7710339a1c2SMark Johnston /*  [64]  */	TNSZ("vpcmpgtb",VEX_RMrX,16),	TNSZ("vpcmpgtw",VEX_RMrX,16),	TNSZ("vpcmpgtd",VEX_RMrX,16),	TNSZ("vpackuswb",VEX_RMrX,16),
7720339a1c2SMark Johnston /*  [68]  */	TNSZ("vpunpckhbw",VEX_RMrX,16),TNSZ("vpunpckhwd",VEX_RMrX,16),TNSZ("vpunpckhdq",VEX_RMrX,16),TNSZ("vpackssdw",VEX_RMrX,16),
7730339a1c2SMark Johnston /*  [6C]  */	TNSZ("vpunpcklqdq",VEX_RMrX,16),TNSZ("vpunpckhqdq",VEX_RMrX,16),TNSZ("vmovd",VEX_MX,4),TNSZ("vmovdqa",VEX_MX,16),
7740339a1c2SMark Johnston 
7750339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshufd",VEX_MXI,16),	TNSZ("vgrp71",VEX_XXI,16),	TNSZ("vgrp72",VEX_XXI,16),		TNSZ("vgrp73",VEX_XXI,16),
7760339a1c2SMark Johnston /*  [74]  */	TNSZ("vpcmpeqb",VEX_RMrX,16),	TNSZ("vpcmpeqw",VEX_RMrX,16),	TNSZ("vpcmpeqd",VEX_RMrX,16),	INVALID,
7770339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
7780339a1c2SMark Johnston /*  [7C]  */	TNSZ("vhaddpd",VEX_RMrX,16),	TNSZ("vhsubpd",VEX_RMrX,16),	TNSZ("vmovd",VEX_RR,4),	TNSZ("vmovdqa",VEX_RX,16),
7790339a1c2SMark Johnston 
7800339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
7810339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
7820339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
7830339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7840339a1c2SMark Johnston 
7850339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
7860339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
7870339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
7880339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
7890339a1c2SMark Johnston 
7900339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7910339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7920339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7930339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7940339a1c2SMark Johnston 
7950339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
7960339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
7970339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
7980339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
7990339a1c2SMark Johnston 
8000339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmppd",VEX_RMRX,16),	INVALID,
8010339a1c2SMark Johnston /*  [C4]  */	TNSZ("vpinsrw",VEX_RMRX,2),TNS("vpextrw",VEX_MR),	TNSZ("vshufpd",VEX_RMRX,16),	INVALID,
8020339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8030339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8040339a1c2SMark Johnston 
8050339a1c2SMark Johnston /*  [D0]  */	TNSZ("vaddsubpd",VEX_RMrX,16),TNSZ("vpsrlw",VEX_RMrX,16),	TNSZ("vpsrld",VEX_RMrX,16),	TNSZ("vpsrlq",VEX_RMrX,16),
8060339a1c2SMark Johnston /*  [D4]  */	TNSZ("vpaddq",VEX_RMrX,16),	TNSZ("vpmullw",VEX_RMrX,16),	TNSZ("vmovq",VEX_RX,8),	TNS("vpmovmskb",VEX_MR),
8070339a1c2SMark Johnston /*  [D8]  */	TNSZ("vpsubusb",VEX_RMrX,16),	TNSZ("vpsubusw",VEX_RMrX,16),	TNSZ("vpminub",VEX_RMrX,16),	TNSZ("vpand",VEX_RMrX,16),
8080339a1c2SMark Johnston /*  [DC]  */	TNSZ("vpaddusb",VEX_RMrX,16),	TNSZ("vpaddusw",VEX_RMrX,16),	TNSZ("vpmaxub",VEX_RMrX,16),	TNSZ("vpandn",VEX_RMrX,16),
8090339a1c2SMark Johnston 
8100339a1c2SMark Johnston /*  [E0]  */	TNSZ("vpavgb",VEX_RMrX,16),	TNSZ("vpsraw",VEX_RMrX,16),	TNSZ("vpsrad",VEX_RMrX,16),	TNSZ("vpavgw",VEX_RMrX,16),
8110339a1c2SMark Johnston /*  [E4]  */	TNSZ("vpmulhuw",VEX_RMrX,16),	TNSZ("vpmulhw",VEX_RMrX,16),	TNSZ("vcvttpd2dq",VEX_MX,16),TNSZ("vmovntdq",VEX_RM,16),
8120339a1c2SMark Johnston /*  [E8]  */	TNSZ("vpsubsb",VEX_RMrX,16),	TNSZ("vpsubsw",VEX_RMrX,16),	TNSZ("vpminsw",VEX_RMrX,16),	TNSZ("vpor",VEX_RMrX,16),
8130339a1c2SMark Johnston /*  [EC]  */	TNSZ("vpaddsb",VEX_RMrX,16),	TNSZ("vpaddsw",VEX_RMrX,16),	TNSZ("vpmaxsw",VEX_RMrX,16),	TNSZ("vpxor",VEX_RMrX,16),
8140339a1c2SMark Johnston 
8150339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("vpsllw",VEX_RMrX,16),	TNSZ("vpslld",VEX_RMrX,16),	TNSZ("vpsllq",VEX_RMrX,16),
8160339a1c2SMark Johnston /*  [F4]  */	TNSZ("vpmuludq",VEX_RMrX,16),	TNSZ("vpmaddwd",VEX_RMrX,16),	TNSZ("vpsadbw",VEX_RMrX,16),	TNS("vmaskmovdqu",VEX_MX),
8170339a1c2SMark Johnston /*  [F8]  */	TNSZ("vpsubb",VEX_RMrX,16),	TNSZ("vpsubw",VEX_RMrX,16),	TNSZ("vpsubd",VEX_RMrX,16),	TNSZ("vpsubq",VEX_RMrX,16),
8180339a1c2SMark Johnston /*  [FC]  */	TNSZ("vpaddb",VEX_RMrX,16),	TNSZ("vpaddw",VEX_RMrX,16),	TNSZ("vpaddd",VEX_RMrX,16),	INVALID,
8190339a1c2SMark Johnston };
8200339a1c2SMark Johnston 
8210339a1c2SMark Johnston /*
8220339a1c2SMark Johnston  *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
8230339a1c2SMark Johnston  */
8240339a1c2SMark Johnston const instable_t dis_opSIMDrepnz[256] = {
8250339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
8260339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
8270339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
8280339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8290339a1c2SMark Johnston 
830*b3b5bfebSMark Johnston /*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	TNSZ("movddup",XMM,8),	INVALID,
8310339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
8320339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
8330339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8340339a1c2SMark Johnston 
8350339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
8360339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
8370339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
8380339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
8390339a1c2SMark Johnston 
8400339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
8410339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
8420339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
8430339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8440339a1c2SMark Johnston 
8450339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
8460339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
8470339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
8480339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8490339a1c2SMark Johnston 
8500339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
8510339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
8520339a1c2SMark Johnston /*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
8530339a1c2SMark Johnston /*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
8540339a1c2SMark Johnston 
8550339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
8560339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
8570339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
8580339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8590339a1c2SMark Johnston 
8600339a1c2SMark Johnston /*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
8610339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
8620339a1c2SMark Johnston /*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
863*b3b5bfebSMark Johnston /*  [7C]  */	TNSZ("haddps",XMM,16),	TNSZ("hsubps",XMM,16),	INVALID,		INVALID,
8640339a1c2SMark Johnston 
8650339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
8660339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
8670339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
8680339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8690339a1c2SMark Johnston 
8700339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
8710339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
8720339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
8730339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
8740339a1c2SMark Johnston 
8750339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8760339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8770339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8780339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8790339a1c2SMark Johnston 
8800339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8810339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8820339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8830339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8840339a1c2SMark Johnston 
8850339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
8860339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
8870339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8880339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8890339a1c2SMark Johnston 
890*b3b5bfebSMark Johnston /*  [D0]  */	TNSZ("addsubps",XMM,16),INVALID,		INVALID,		INVALID,
8910339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
8920339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8930339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8940339a1c2SMark Johnston 
8950339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
8960339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
8970339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
8980339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
8990339a1c2SMark Johnston 
900*b3b5bfebSMark Johnston /*  [F0]  */	TNS("lddqu",XMMM),	INVALID,		INVALID,		INVALID,
9010339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9020339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9030339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9040339a1c2SMark Johnston };
9050339a1c2SMark Johnston 
9060339a1c2SMark Johnston const instable_t dis_opAVXF20F[256] = {
9070339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
9080339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
9090339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
9100339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9110339a1c2SMark Johnston 
9120339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovsd",VEX_RMrX,8),	TNSZ("vmovsd",VEX_RRX,8),	TNSZ("vmovddup",VEX_MX,8),	INVALID,
9130339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
9140339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
9150339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9160339a1c2SMark Johnston 
9170339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
9180339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
9190339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2sd",VEX_RMrX,4),INVALID,
9200339a1c2SMark Johnston /*  [2C]  */	TNSZ("vcvttsd2si",VEX_MR,8),TNSZ("vcvtsd2si",VEX_MR,8),INVALID,		INVALID,
9210339a1c2SMark Johnston 
9220339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
9230339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
9240339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
9250339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9260339a1c2SMark Johnston 
9270339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
9280339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
9290339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
9300339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9310339a1c2SMark Johnston 
9320339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("vsqrtsd",VEX_RMrX,8),	INVALID,		INVALID,
9330339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
9340339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddsd",VEX_RMrX,8),	TNSZ("vmulsd",VEX_RMrX,8),	TNSZ("vcvtsd2ss",VEX_RMrX,8),	INVALID,
9350339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubsd",VEX_RMrX,8),	TNSZ("vminsd",VEX_RMrX,8),	TNSZ("vdivsd",VEX_RMrX,8),	TNSZ("vmaxsd",VEX_RMrX,8),
9360339a1c2SMark Johnston 
9370339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
9380339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
9390339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
9400339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9410339a1c2SMark Johnston 
9420339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshuflw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
9430339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
9440339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
9450339a1c2SMark Johnston /*  [7C]  */	TNSZ("vhaddps",VEX_RMrX,8),	TNSZ("vhsubps",VEX_RMrX,8),	INVALID,		INVALID,
9460339a1c2SMark Johnston 
9470339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
9480339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
9490339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
9500339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9510339a1c2SMark Johnston 
9520339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
9530339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
9540339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
9550339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
9560339a1c2SMark Johnston 
9570339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9580339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9590339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9600339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9610339a1c2SMark Johnston 
9620339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9630339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9640339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9650339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9660339a1c2SMark Johnston 
9670339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpsd",VEX_RMRX,8),	INVALID,
9680339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9690339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9700339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9710339a1c2SMark Johnston 
9720339a1c2SMark Johnston /*  [D0]  */	TNSZ("vaddsubps",VEX_RMrX,8),	INVALID,		INVALID,		INVALID,
9730339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9740339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9750339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9760339a1c2SMark Johnston 
9770339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
9780339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtpd2dq",VEX_MX,16),INVALID,
9790339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9800339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9810339a1c2SMark Johnston 
9820339a1c2SMark Johnston /*  [F0]  */	TNSZ("vlddqu",VEX_MX,16),	INVALID,		INVALID,		INVALID,
9830339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
9840339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
9850339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
9860339a1c2SMark Johnston };
9870339a1c2SMark Johnston 
988*b3b5bfebSMark Johnston const instable_t dis_opAVXF20F3A[256] = {
989*b3b5bfebSMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
990*b3b5bfebSMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
991*b3b5bfebSMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
992*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
993*b3b5bfebSMark Johnston 
994*b3b5bfebSMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
995*b3b5bfebSMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
996*b3b5bfebSMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
997*b3b5bfebSMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
998*b3b5bfebSMark Johnston 
999*b3b5bfebSMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1000*b3b5bfebSMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1001*b3b5bfebSMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1002*b3b5bfebSMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1003*b3b5bfebSMark Johnston 
1004*b3b5bfebSMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1005*b3b5bfebSMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1006*b3b5bfebSMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1007*b3b5bfebSMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1008*b3b5bfebSMark Johnston 
1009*b3b5bfebSMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1010*b3b5bfebSMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1011*b3b5bfebSMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1012*b3b5bfebSMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1013*b3b5bfebSMark Johnston 
1014*b3b5bfebSMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1015*b3b5bfebSMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1016*b3b5bfebSMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1017*b3b5bfebSMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1018*b3b5bfebSMark Johnston 
1019*b3b5bfebSMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1020*b3b5bfebSMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1021*b3b5bfebSMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1022*b3b5bfebSMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1023*b3b5bfebSMark Johnston 
1024*b3b5bfebSMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1025*b3b5bfebSMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1026*b3b5bfebSMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1027*b3b5bfebSMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1028*b3b5bfebSMark Johnston 
1029*b3b5bfebSMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1030*b3b5bfebSMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1031*b3b5bfebSMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1032*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1033*b3b5bfebSMark Johnston 
1034*b3b5bfebSMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1035*b3b5bfebSMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1036*b3b5bfebSMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1037*b3b5bfebSMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1038*b3b5bfebSMark Johnston 
1039*b3b5bfebSMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1040*b3b5bfebSMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1041*b3b5bfebSMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1042*b3b5bfebSMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1043*b3b5bfebSMark Johnston 
1044*b3b5bfebSMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1045*b3b5bfebSMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1046*b3b5bfebSMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1047*b3b5bfebSMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1048*b3b5bfebSMark Johnston 
1049*b3b5bfebSMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1050*b3b5bfebSMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1051*b3b5bfebSMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1052*b3b5bfebSMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1053*b3b5bfebSMark Johnston 
1054*b3b5bfebSMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1055*b3b5bfebSMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1056*b3b5bfebSMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1057*b3b5bfebSMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1058*b3b5bfebSMark Johnston 
1059*b3b5bfebSMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1060*b3b5bfebSMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1061*b3b5bfebSMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1062*b3b5bfebSMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1063*b3b5bfebSMark Johnston 
1064*b3b5bfebSMark Johnston /*  [F0]  */	TNSZvr("rorx",VEX_MXI,6),INVALID,		INVALID,		INVALID,
1065*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1066*b3b5bfebSMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1067*b3b5bfebSMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1068*b3b5bfebSMark Johnston };
1069*b3b5bfebSMark Johnston 
1070*b3b5bfebSMark Johnston const instable_t dis_opAVXF20F38[256] = {
1071*b3b5bfebSMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1072*b3b5bfebSMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1073*b3b5bfebSMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1074*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1075*b3b5bfebSMark Johnston 
1076*b3b5bfebSMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1077*b3b5bfebSMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
1078*b3b5bfebSMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1079*b3b5bfebSMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1080*b3b5bfebSMark Johnston 
1081*b3b5bfebSMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1082*b3b5bfebSMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1083*b3b5bfebSMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1084*b3b5bfebSMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1085*b3b5bfebSMark Johnston 
1086*b3b5bfebSMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1087*b3b5bfebSMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1088*b3b5bfebSMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1089*b3b5bfebSMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1090*b3b5bfebSMark Johnston 
1091*b3b5bfebSMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1092*b3b5bfebSMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1093*b3b5bfebSMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1094*b3b5bfebSMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1095*b3b5bfebSMark Johnston 
1096*b3b5bfebSMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1097*b3b5bfebSMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1098*b3b5bfebSMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1099*b3b5bfebSMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1100*b3b5bfebSMark Johnston 
1101*b3b5bfebSMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1102*b3b5bfebSMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1103*b3b5bfebSMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1104*b3b5bfebSMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1105*b3b5bfebSMark Johnston 
1106*b3b5bfebSMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1107*b3b5bfebSMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1108*b3b5bfebSMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1109*b3b5bfebSMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1110*b3b5bfebSMark Johnston 
1111*b3b5bfebSMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1112*b3b5bfebSMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1113*b3b5bfebSMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1114*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1115*b3b5bfebSMark Johnston 
1116*b3b5bfebSMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1117*b3b5bfebSMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1118*b3b5bfebSMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1119*b3b5bfebSMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1120*b3b5bfebSMark Johnston 
1121*b3b5bfebSMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1122*b3b5bfebSMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1123*b3b5bfebSMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1124*b3b5bfebSMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1125*b3b5bfebSMark Johnston 
1126*b3b5bfebSMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1127*b3b5bfebSMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1128*b3b5bfebSMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1129*b3b5bfebSMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1130*b3b5bfebSMark Johnston 
1131*b3b5bfebSMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1132*b3b5bfebSMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1133*b3b5bfebSMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1134*b3b5bfebSMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1135*b3b5bfebSMark Johnston 
1136*b3b5bfebSMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1137*b3b5bfebSMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1138*b3b5bfebSMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1139*b3b5bfebSMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1140*b3b5bfebSMark Johnston 
1141*b3b5bfebSMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1142*b3b5bfebSMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1143*b3b5bfebSMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1144*b3b5bfebSMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1145*b3b5bfebSMark Johnston 
1146*b3b5bfebSMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1147*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		TNSZvr("pdep",VEX_RMrX,5),TNSZvr("mulx",VEX_RMrX,5),TNSZvr("shrx",VEX_VRMrX,5),
1148*b3b5bfebSMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1149*b3b5bfebSMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1150*b3b5bfebSMark Johnston };
1151*b3b5bfebSMark Johnston 
1152*b3b5bfebSMark Johnston const instable_t dis_opAVXF30F38[256] = {
1153*b3b5bfebSMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
1154*b3b5bfebSMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1155*b3b5bfebSMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
1156*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1157*b3b5bfebSMark Johnston 
1158*b3b5bfebSMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
1159*b3b5bfebSMark Johnston /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
1160*b3b5bfebSMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
1161*b3b5bfebSMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1162*b3b5bfebSMark Johnston 
1163*b3b5bfebSMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
1164*b3b5bfebSMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
1165*b3b5bfebSMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
1166*b3b5bfebSMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1167*b3b5bfebSMark Johnston 
1168*b3b5bfebSMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
1169*b3b5bfebSMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1170*b3b5bfebSMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
1171*b3b5bfebSMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1172*b3b5bfebSMark Johnston 
1173*b3b5bfebSMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
1174*b3b5bfebSMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
1175*b3b5bfebSMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
1176*b3b5bfebSMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1177*b3b5bfebSMark Johnston 
1178*b3b5bfebSMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
1179*b3b5bfebSMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1180*b3b5bfebSMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
1181*b3b5bfebSMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1182*b3b5bfebSMark Johnston 
1183*b3b5bfebSMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
1184*b3b5bfebSMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
1185*b3b5bfebSMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
1186*b3b5bfebSMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1187*b3b5bfebSMark Johnston 
1188*b3b5bfebSMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
1189*b3b5bfebSMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1190*b3b5bfebSMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
1191*b3b5bfebSMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1192*b3b5bfebSMark Johnston 
1193*b3b5bfebSMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
1194*b3b5bfebSMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
1195*b3b5bfebSMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1196*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1197*b3b5bfebSMark Johnston 
1198*b3b5bfebSMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
1199*b3b5bfebSMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
1200*b3b5bfebSMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
1201*b3b5bfebSMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
1202*b3b5bfebSMark Johnston 
1203*b3b5bfebSMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1204*b3b5bfebSMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1205*b3b5bfebSMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1206*b3b5bfebSMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1207*b3b5bfebSMark Johnston 
1208*b3b5bfebSMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1209*b3b5bfebSMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1210*b3b5bfebSMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1211*b3b5bfebSMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1212*b3b5bfebSMark Johnston 
1213*b3b5bfebSMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1214*b3b5bfebSMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1215*b3b5bfebSMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1216*b3b5bfebSMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1217*b3b5bfebSMark Johnston 
1218*b3b5bfebSMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1219*b3b5bfebSMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1220*b3b5bfebSMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1221*b3b5bfebSMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1222*b3b5bfebSMark Johnston 
1223*b3b5bfebSMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1224*b3b5bfebSMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1225*b3b5bfebSMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1226*b3b5bfebSMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1227*b3b5bfebSMark Johnston 
1228*b3b5bfebSMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1229*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		TNSZvr("pext",VEX_RMrX,5),INVALID,		TNSZvr("sarx",VEX_VRMrX,5),
1230*b3b5bfebSMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1231*b3b5bfebSMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
1232*b3b5bfebSMark Johnston };
12330339a1c2SMark Johnston /*
12340339a1c2SMark Johnston  *	Decode table for SIMD instructions with the repz (0xf3) prefix.
12350339a1c2SMark Johnston  */
12360339a1c2SMark Johnston const instable_t dis_opSIMDrepz[256] = {
12370339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
12380339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
12390339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
12400339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12410339a1c2SMark Johnston 
1242*b3b5bfebSMark Johnston /*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	TNSZ("movsldup",XMM,16),INVALID,
1243*b3b5bfebSMark Johnston /*  [14]  */	INVALID,		INVALID,		TNSZ("movshdup",XMM,16),INVALID,
12440339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
12450339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12460339a1c2SMark Johnston 
12470339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
12480339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
12490339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
12500339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
12510339a1c2SMark Johnston 
12520339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
12530339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
12540339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
12550339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12560339a1c2SMark Johnston 
12570339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
12580339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
12590339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
12600339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12610339a1c2SMark Johnston 
12620339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
12630339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
12640339a1c2SMark Johnston /*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
12650339a1c2SMark Johnston /*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
12660339a1c2SMark Johnston 
12670339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
12680339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
12690339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
12700339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
12710339a1c2SMark Johnston 
12720339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
12730339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
12740339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
12750339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
12760339a1c2SMark Johnston 
12770339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
12780339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
12790339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
12800339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12810339a1c2SMark Johnston 
12820339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
12830339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
12840339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
12850339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
12860339a1c2SMark Johnston 
12870339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12880339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12890339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
12900339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
12910339a1c2SMark Johnston 
12920339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
12930339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12940339a1c2SMark Johnston /*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
1295*b3b5bfebSMark Johnston /*  [BC]  */	TNSZ("tzcnt",MRw,5),	TS("lzcnt",MRw),	INVALID,		INVALID,
12960339a1c2SMark Johnston 
12970339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
12980339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
12990339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13000339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13010339a1c2SMark Johnston 
13020339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13030339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
13040339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13050339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13060339a1c2SMark Johnston 
13070339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13080339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
13090339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13100339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13110339a1c2SMark Johnston 
13120339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13130339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13140339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13150339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13160339a1c2SMark Johnston };
13170339a1c2SMark Johnston 
13180339a1c2SMark Johnston const instable_t dis_opAVXF30F[256] = {
13190339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
13200339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
13210339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
13220339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13230339a1c2SMark Johnston 
13240339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovss",VEX_RMrX,4),	TNSZ("vmovss",VEX_RRX,4),	TNSZ("vmovsldup",VEX_MX,4),	INVALID,
13250339a1c2SMark Johnston /*  [14]  */	INVALID,		INVALID,		TNSZ("vmovshdup",VEX_MX,4),	INVALID,
13260339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
13270339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13280339a1c2SMark Johnston 
13290339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
13300339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
13310339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		TNSZ("vcvtsi2ss",VEX_RMrX,4),INVALID,
13320339a1c2SMark Johnston /*  [2C]  */	TNSZ("vcvttss2si",VEX_MR,4),TNSZ("vcvtss2si",VEX_MR,4),INVALID,		INVALID,
13330339a1c2SMark Johnston 
13340339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
13350339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
13360339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
13370339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13380339a1c2SMark Johnston 
13390339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
13400339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
13410339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
13420339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13430339a1c2SMark Johnston 
13440339a1c2SMark Johnston /*  [50]  */	INVALID,		TNSZ("vsqrtss",VEX_RMrX,4),	TNSZ("vrsqrtss",VEX_RMrX,4),	TNSZ("vrcpss",VEX_RMrX,4),
13450339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
13460339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddss",VEX_RMrX,4),	TNSZ("vmulss",VEX_RMrX,4),	TNSZ("vcvtss2sd",VEX_RMrX,4),	TNSZ("vcvttps2dq",VEX_MX,16),
13470339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubss",VEX_RMrX,4),	TNSZ("vminss",VEX_RMrX,4),	TNSZ("vdivss",VEX_RMrX,4),	TNSZ("vmaxss",VEX_RMrX,4),
13480339a1c2SMark Johnston 
13490339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
13500339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
13510339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
13520339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("vmovdqu",VEX_MX,16),
13530339a1c2SMark Johnston 
13540339a1c2SMark Johnston /*  [70]  */	TNSZ("vpshufhw",VEX_MXI,16),INVALID,		INVALID,		INVALID,
13550339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
13560339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
13570339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("vmovq",VEX_MX,8),	TNSZ("vmovdqu",VEX_RX,16),
13580339a1c2SMark Johnston 
13590339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
13600339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
13610339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
13620339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13630339a1c2SMark Johnston 
13640339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
13650339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
13660339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
13670339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
13680339a1c2SMark Johnston 
13690339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13700339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13710339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13720339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13730339a1c2SMark Johnston 
13740339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13750339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13760339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13770339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13780339a1c2SMark Johnston 
13790339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpss",VEX_RMRX,4),	INVALID,
13800339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13810339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13820339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13830339a1c2SMark Johnston 
13840339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13850339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13860339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13870339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13880339a1c2SMark Johnston 
13890339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13900339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		TNSZ("vcvtdq2pd",VEX_MX,8),	INVALID,
13910339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13920339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13930339a1c2SMark Johnston 
13940339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
13950339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
13960339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
13970339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
13980339a1c2SMark Johnston };
13990339a1c2SMark Johnston /*
14000339a1c2SMark Johnston  * The following two tables are used to encode crc32 and movbe
14010339a1c2SMark Johnston  * since they share the same opcodes.
14020339a1c2SMark Johnston  */
14030339a1c2SMark Johnston const instable_t dis_op0F38F0[2] = {
14040339a1c2SMark Johnston /*  [00]  */	TNS("crc32b",CRC32),
14050339a1c2SMark Johnston 		TS("movbe",MOVBE),
14060339a1c2SMark Johnston };
14070339a1c2SMark Johnston 
14080339a1c2SMark Johnston const instable_t dis_op0F38F1[2] = {
14090339a1c2SMark Johnston /*  [00]  */	TS("crc32",CRC32),
14100339a1c2SMark Johnston 		TS("movbe",MOVBE),
14110339a1c2SMark Johnston };
14120339a1c2SMark Johnston 
1413*b3b5bfebSMark Johnston /*
1414*b3b5bfebSMark Johnston  * The following table is used to distinguish between adox and adcx which share
1415*b3b5bfebSMark Johnston  * the same opcodes.
1416*b3b5bfebSMark Johnston  */
1417*b3b5bfebSMark Johnston const instable_t dis_op0F38F6[2] = {
1418*b3b5bfebSMark Johnston /*  [00]  */	TNS("adcx",ADX),
1419*b3b5bfebSMark Johnston 		TNS("adox",ADX),
1420*b3b5bfebSMark Johnston };
1421*b3b5bfebSMark Johnston 
14220339a1c2SMark Johnston const instable_t dis_op0F38[256] = {
14230339a1c2SMark Johnston /*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
14240339a1c2SMark Johnston /*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
14250339a1c2SMark Johnston /*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
14260339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14270339a1c2SMark Johnston 
14280339a1c2SMark Johnston /*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
14290339a1c2SMark Johnston /*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
14300339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
14310339a1c2SMark Johnston /*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
14320339a1c2SMark Johnston 
14330339a1c2SMark Johnston /*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
14340339a1c2SMark Johnston /*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
14350339a1c2SMark Johnston /*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
14360339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14370339a1c2SMark Johnston 
14380339a1c2SMark Johnston /*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
14390339a1c2SMark Johnston /*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
14400339a1c2SMark Johnston /*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
14410339a1c2SMark Johnston /*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
14420339a1c2SMark Johnston 
14430339a1c2SMark Johnston /*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
14440339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
14450339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
14460339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14470339a1c2SMark Johnston 
14480339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
14490339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
14500339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
14510339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14520339a1c2SMark Johnston 
14530339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
14540339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
14550339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
14560339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14570339a1c2SMark Johnston 
14580339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
14590339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
14600339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
14610339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14620339a1c2SMark Johnston 
146327b6c497SAndriy Gapon /*  [80]  */	TNSy("invept", RM_66r),	TNSy("invvpid", RM_66r),TNSy("invpcid", RM_66r),INVALID,
14640339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
14650339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
14660339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14670339a1c2SMark Johnston 
14680339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
14690339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
14700339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
14710339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
14720339a1c2SMark Johnston 
14730339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14740339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14750339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14760339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14770339a1c2SMark Johnston 
14780339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14790339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14800339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14810339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14820339a1c2SMark Johnston 
14830339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14840339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
1485*b3b5bfebSMark Johnston /*  [C8]  */	TNSZ("sha1nexte",XMM,16),TNSZ("sha1msg1",XMM,16),TNSZ("sha1msg2",XMM,16),TNSZ("sha256rnds2",XMM,16),
1486*b3b5bfebSMark Johnston /*  [CC]  */	TNSZ("sha256msg1",XMM,16),TNSZ("sha256msg2",XMM,16),INVALID,		INVALID,
14870339a1c2SMark Johnston 
14880339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14890339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14900339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
14910339a1c2SMark Johnston /*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
14920339a1c2SMark Johnston 
14930339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
14940339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
14950339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
14960339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
14970339a1c2SMark Johnston /*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1498*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		INVALID,		IND(dis_op0F38F6),	INVALID,
14990339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
15000339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
15010339a1c2SMark Johnston };
15020339a1c2SMark Johnston 
15030339a1c2SMark Johnston const instable_t dis_opAVX660F38[256] = {
15040339a1c2SMark Johnston /*  [00]  */	TNSZ("vpshufb",VEX_RMrX,16),TNSZ("vphaddw",VEX_RMrX,16),TNSZ("vphaddd",VEX_RMrX,16),TNSZ("vphaddsw",VEX_RMrX,16),
15050339a1c2SMark Johnston /*  [04]  */	TNSZ("vpmaddubsw",VEX_RMrX,16),TNSZ("vphsubw",VEX_RMrX,16),	TNSZ("vphsubd",VEX_RMrX,16),TNSZ("vphsubsw",VEX_RMrX,16),
15060339a1c2SMark Johnston /*  [08]  */	TNSZ("vpsignb",VEX_RMrX,16),TNSZ("vpsignw",VEX_RMrX,16),TNSZ("vpsignd",VEX_RMrX,16),TNSZ("vpmulhrsw",VEX_RMrX,16),
15070339a1c2SMark Johnston /*  [0C]  */	TNSZ("vpermilps",VEX_RMrX,8),TNSZ("vpermilpd",VEX_RMrX,16),TNSZ("vtestps",VEX_RRI,8),	TNSZ("vtestpd",VEX_RRI,16),
15080339a1c2SMark Johnston 
1509c3ddb60eSPeter Grehan /*  [10]  */	INVALID,		INVALID,		INVALID,		TNSZ("vcvtph2ps",VEX_MX,16),
1510*b3b5bfebSMark Johnston /*  [14]  */	INVALID,		INVALID,		TNSZ("vpermps",VEX_RMrX,16),TNSZ("vptest",VEX_RRI,16),
15110339a1c2SMark Johnston /*  [18]  */	TNSZ("vbroadcastss",VEX_MX,4),TNSZ("vbroadcastsd",VEX_MX,8),TNSZ("vbroadcastf128",VEX_MX,16),INVALID,
15120339a1c2SMark Johnston /*  [1C]  */	TNSZ("vpabsb",VEX_MX,16),TNSZ("vpabsw",VEX_MX,16),TNSZ("vpabsd",VEX_MX,16),INVALID,
15130339a1c2SMark Johnston 
15140339a1c2SMark Johnston /*  [20]  */	TNSZ("vpmovsxbw",VEX_MX,16),TNSZ("vpmovsxbd",VEX_MX,16),TNSZ("vpmovsxbq",VEX_MX,16),TNSZ("vpmovsxwd",VEX_MX,16),
15150339a1c2SMark Johnston /*  [24]  */	TNSZ("vpmovsxwq",VEX_MX,16),TNSZ("vpmovsxdq",VEX_MX,16),INVALID,	INVALID,
15160339a1c2SMark Johnston /*  [28]  */	TNSZ("vpmuldq",VEX_RMrX,16),TNSZ("vpcmpeqq",VEX_RMrX,16),TNSZ("vmovntdqa",VEX_MX,16),TNSZ("vpackusdw",VEX_RMrX,16),
15170339a1c2SMark Johnston /*  [2C]  */	TNSZ("vmaskmovps",VEX_RMrX,8),TNSZ("vmaskmovpd",VEX_RMrX,16),TNSZ("vmaskmovps",VEX_RRM,8),TNSZ("vmaskmovpd",VEX_RRM,16),
15180339a1c2SMark Johnston 
15190339a1c2SMark Johnston /*  [30]  */	TNSZ("vpmovzxbw",VEX_MX,16),TNSZ("vpmovzxbd",VEX_MX,16),TNSZ("vpmovzxbq",VEX_MX,16),TNSZ("vpmovzxwd",VEX_MX,16),
1520*b3b5bfebSMark Johnston /*  [34]  */	TNSZ("vpmovzxwq",VEX_MX,16),TNSZ("vpmovzxdq",VEX_MX,16),TNSZ("vpermd",VEX_RMrX,16),TNSZ("vpcmpgtq",VEX_RMrX,16),
15210339a1c2SMark Johnston /*  [38]  */	TNSZ("vpminsb",VEX_RMrX,16),TNSZ("vpminsd",VEX_RMrX,16),TNSZ("vpminuw",VEX_RMrX,16),TNSZ("vpminud",VEX_RMrX,16),
15220339a1c2SMark Johnston /*  [3C]  */	TNSZ("vpmaxsb",VEX_RMrX,16),TNSZ("vpmaxsd",VEX_RMrX,16),TNSZ("vpmaxuw",VEX_RMrX,16),TNSZ("vpmaxud",VEX_RMrX,16),
15230339a1c2SMark Johnston 
15240339a1c2SMark Johnston /*  [40]  */	TNSZ("vpmulld",VEX_RMrX,16),TNSZ("vphminposuw",VEX_MX,16),INVALID,	INVALID,
1525*b3b5bfebSMark Johnston /*  [44]  */	INVALID,		TSaZ("vpsrlv",VEX_RMrX,16),TNSZ("vpsravd",VEX_RMrX,16),TSaZ("vpsllv",VEX_RMrX,16),
15260339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
15270339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15280339a1c2SMark Johnston 
15290339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
15300339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
1531*b3b5bfebSMark Johnston /*  [58]  */	TNSZ("vpbroadcastd",VEX_MX,16),TNSZ("vpbroadcastq",VEX_MX,16),TNSZ("vbroadcasti128",VEX_MX,16),INVALID,
15320339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15330339a1c2SMark Johnston 
15340339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
15350339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
15360339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
15370339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15380339a1c2SMark Johnston 
15390339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
15400339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
1541*b3b5bfebSMark Johnston /*  [78]  */	TNSZ("vpbroadcastb",VEX_MX,16),TNSZ("vpbroadcastw",VEX_MX,16),INVALID,	INVALID,
15420339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15430339a1c2SMark Johnston 
15440339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
15450339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
15460339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
1547*b3b5bfebSMark Johnston /*  [8C]  */	TSaZ("vpmaskmov",VEX_RMrX,16),INVALID,		TSaZ("vpmaskmov",VEX_RRM,16),INVALID,
15480339a1c2SMark Johnston 
1549*b3b5bfebSMark Johnston /*  [90]  */	TNSZ("vpgatherd",VEX_SbVM,16),TNSZ("vpgatherq",VEX_SbVM,16),TNSZ("vgatherdp",VEX_SbVM,16),TNSZ("vgatherqp",VEX_SbVM,16),
1550*b3b5bfebSMark Johnston /*  [94]  */	INVALID,		INVALID,		TNSZ("vfmaddsub132p",FMA,16),TNSZ("vfmsubadd132p",FMA,16),
1551*b3b5bfebSMark Johnston /*  [98]  */	TNSZ("vfmadd132p",FMA,16),TNSZ("vfmadd132s",FMA,16),TNSZ("vfmsub132p",FMA,16),TNSZ("vfmsub132s",FMA,16),
1552*b3b5bfebSMark Johnston /*  [9C]  */	TNSZ("vfnmadd132p",FMA,16),TNSZ("vfnmadd132s",FMA,16),TNSZ("vfnmsub132p",FMA,16),TNSZ("vfnmsub132s",FMA,16),
15530339a1c2SMark Johnston 
15540339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1555*b3b5bfebSMark Johnston /*  [A4]  */	INVALID,		INVALID,		TNSZ("vfmaddsub213p",FMA,16),TNSZ("vfmsubadd213p",FMA,16),
1556*b3b5bfebSMark Johnston /*  [A8]  */	TNSZ("vfmadd213p",FMA,16),TNSZ("vfmadd213s",FMA,16),TNSZ("vfmsub213p",FMA,16),TNSZ("vfmsub213s",FMA,16),
1557*b3b5bfebSMark Johnston /*  [AC]  */	TNSZ("vfnmadd213p",FMA,16),TNSZ("vfnmadd213s",FMA,16),TNSZ("vfnmsub213p",FMA,16),TNSZ("vfnmsub213s",FMA,16),
15580339a1c2SMark Johnston 
15590339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
1560*b3b5bfebSMark Johnston /*  [B4]  */	INVALID,		INVALID,		TNSZ("vfmaddsub231p",FMA,16),TNSZ("vfmsubadd231p",FMA,16),
1561*b3b5bfebSMark Johnston /*  [B8]  */	TNSZ("vfmadd231p",FMA,16),TNSZ("vfmadd231s",FMA,16),TNSZ("vfmsub231p",FMA,16),TNSZ("vfmsub231s",FMA,16),
1562*b3b5bfebSMark Johnston /*  [BC]  */	TNSZ("vfnmadd231p",FMA,16),TNSZ("vfnmadd231s",FMA,16),TNSZ("vfnmsub231p",FMA,16),TNSZ("vfnmsub231s",FMA,16),
15630339a1c2SMark Johnston 
15640339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
15650339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
15660339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
15670339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
15680339a1c2SMark Johnston 
15690339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
15700339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
15710339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaesimc",VEX_MX,16),
15720339a1c2SMark Johnston /*  [DC]  */	TNSZ("vaesenc",VEX_RMrX,16),TNSZ("vaesenclast",VEX_RMrX,16),TNSZ("vaesdec",VEX_RMrX,16),TNSZ("vaesdeclast",VEX_RMrX,16),
15730339a1c2SMark Johnston 
15740339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
15750339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
15760339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
15770339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
15780339a1c2SMark Johnston /*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
1579*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		TNSZvr("shlx",VEX_VRMrX,5),
15800339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
15810339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
15820339a1c2SMark Johnston };
15830339a1c2SMark Johnston 
15840339a1c2SMark Johnston const instable_t dis_op0F3A[256] = {
15850339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
15860339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
15870339a1c2SMark Johnston /*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
15880339a1c2SMark Johnston /*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
15890339a1c2SMark Johnston 
15900339a1c2SMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
15910339a1c2SMark Johnston /*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
15920339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
15930339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15940339a1c2SMark Johnston 
15950339a1c2SMark Johnston /*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
15960339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
15970339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
15980339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
15990339a1c2SMark Johnston 
16000339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
16010339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
16020339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
16030339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16040339a1c2SMark Johnston 
16050339a1c2SMark Johnston /*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
16060339a1c2SMark Johnston /*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
16070339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
16080339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16090339a1c2SMark Johnston 
16100339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
16110339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
16120339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
16130339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16140339a1c2SMark Johnston 
16150339a1c2SMark Johnston /*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
16160339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
16170339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
16180339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16190339a1c2SMark Johnston 
16200339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
16210339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
16220339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
16230339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16240339a1c2SMark Johnston 
16250339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
16260339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
16270339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
16280339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16290339a1c2SMark Johnston 
16300339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
16310339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
16320339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
16330339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16340339a1c2SMark Johnston 
16350339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16360339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16370339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16380339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16390339a1c2SMark Johnston 
16400339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16410339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16420339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16430339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16440339a1c2SMark Johnston 
16450339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16460339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16470339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
1648*b3b5bfebSMark Johnston /*  [CC]  */	TNSZ("sha1rnds4",XMMP,16),INVALID,		INVALID,		INVALID,
16490339a1c2SMark Johnston 
16500339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16510339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16520339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16530339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
16540339a1c2SMark Johnston 
16550339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16560339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16570339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16580339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16590339a1c2SMark Johnston 
16600339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
16610339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
16620339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
16630339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
16640339a1c2SMark Johnston };
16650339a1c2SMark Johnston 
16660339a1c2SMark Johnston const instable_t dis_opAVX660F3A[256] = {
1667*b3b5bfebSMark Johnston /*  [00]  */	TNSZ("vpermq",VEX_MXI,16),TNSZ("vpermpd",VEX_MXI,16),TNSZ("vpblendd",VEX_RMRX,16),INVALID,
16680339a1c2SMark Johnston /*  [04]  */	TNSZ("vpermilps",VEX_MXI,8),TNSZ("vpermilpd",VEX_MXI,16),TNSZ("vperm2f128",VEX_RMRX,16),INVALID,
16690339a1c2SMark Johnston /*  [08]  */	TNSZ("vroundps",VEX_MXI,16),TNSZ("vroundpd",VEX_MXI,16),TNSZ("vroundss",VEX_RMRX,16),TNSZ("vroundsd",VEX_RMRX,16),
16700339a1c2SMark Johnston /*  [0C]  */	TNSZ("vblendps",VEX_RMRX,16),TNSZ("vblendpd",VEX_RMRX,16),TNSZ("vpblendw",VEX_RMRX,16),TNSZ("vpalignr",VEX_RMRX,16),
16710339a1c2SMark Johnston 
16720339a1c2SMark Johnston /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
16730339a1c2SMark Johnston /*  [14]  */	TNSZ("vpextrb",VEX_RRi,8),TNSZ("vpextrw",VEX_RRi,16),TNSZ("vpextrd",VEX_RRi,16),TNSZ("vextractps",VEX_RM,16),
16740339a1c2SMark Johnston /*  [18]  */	TNSZ("vinsertf128",VEX_RMRX,16),TNSZ("vextractf128",VEX_RX,16),INVALID,		INVALID,
1675c3ddb60eSPeter Grehan /*  [1C]  */	INVALID,		TNSZ("vcvtps2ph",VEX_RX,16),		INVALID,		INVALID,
16760339a1c2SMark Johnston 
16770339a1c2SMark Johnston /*  [20]  */	TNSZ("vpinsrb",VEX_RMRX,8),TNSZ("vinsertps",VEX_RMRX,16),TNSZ("vpinsrd",VEX_RMRX,16),INVALID,
16780339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
16790339a1c2SMark Johnston /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
16800339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16810339a1c2SMark Johnston 
16820339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
16830339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
1684*b3b5bfebSMark Johnston /*  [38]  */	TNSZ("vinserti128",VEX_RMRX,16),TNSZ("vextracti128",VEX_RIM,16),INVALID,		INVALID,
16850339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16860339a1c2SMark Johnston 
16870339a1c2SMark Johnston /*  [40]  */	TNSZ("vdpps",VEX_RMRX,16),TNSZ("vdppd",VEX_RMRX,16),TNSZ("vmpsadbw",VEX_RMRX,16),INVALID,
1688*b3b5bfebSMark Johnston /*  [44]  */	TNSZ("vpclmulqdq",VEX_RMRX,16),INVALID,		TNSZ("vperm2i128",VEX_RMRX,16),INVALID,
16890339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		TNSZ("vblendvps",VEX_RMRX,8),	TNSZ("vblendvpd",VEX_RMRX,16),
16900339a1c2SMark Johnston /*  [4C]  */	TNSZ("vpblendvb",VEX_RMRX,16),INVALID,		INVALID,		INVALID,
16910339a1c2SMark Johnston 
16920339a1c2SMark Johnston /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
16930339a1c2SMark Johnston /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
16940339a1c2SMark Johnston /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
16950339a1c2SMark Johnston /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
16960339a1c2SMark Johnston 
16970339a1c2SMark Johnston /*  [60]  */	TNSZ("vpcmpestrm",VEX_MXI,16),TNSZ("vpcmpestri",VEX_MXI,16),TNSZ("vpcmpistrm",VEX_MXI,16),TNSZ("vpcmpistri",VEX_MXI,16),
16980339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
16990339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
17000339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
17010339a1c2SMark Johnston 
17020339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
17030339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
17040339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
17050339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
17060339a1c2SMark Johnston 
17070339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
17080339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
17090339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
17100339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
17110339a1c2SMark Johnston 
17120339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
17130339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
17140339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
17150339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
17160339a1c2SMark Johnston 
17170339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17180339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17190339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17200339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
17210339a1c2SMark Johnston 
17220339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17230339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17240339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17250339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
17260339a1c2SMark Johnston 
17270339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17280339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17290339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17300339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
17310339a1c2SMark Johnston 
17320339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17330339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17340339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17350339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("vaeskeygenassist",VEX_MXI,16),
17360339a1c2SMark Johnston 
17370339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17380339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17390339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17400339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
17410339a1c2SMark Johnston 
17420339a1c2SMark Johnston /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
17430339a1c2SMark Johnston /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
17440339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
17450339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
17460339a1c2SMark Johnston };
17470339a1c2SMark Johnston 
17480339a1c2SMark Johnston /*
1749*b3b5bfebSMark Johnston  * 	Decode table for 0x0F0D which uses the first byte of the mod_rm to
1750*b3b5bfebSMark Johnston  * 	indicate a sub-code.
1751*b3b5bfebSMark Johnston  */
1752*b3b5bfebSMark Johnston const instable_t dis_op0F0D[8] = {
1753*b3b5bfebSMark Johnston /*  [00]  */	INVALID,		TNS("prefetchw",PREF),	TNS("prefetchwt1",PREF),INVALID,
1754*b3b5bfebSMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
1755*b3b5bfebSMark Johnston };
1756*b3b5bfebSMark Johnston 
1757*b3b5bfebSMark Johnston /*
17580339a1c2SMark Johnston  *	Decode table for 0x0F opcodes
17590339a1c2SMark Johnston  */
17600339a1c2SMark Johnston 
17610339a1c2SMark Johnston const instable_t dis_op0F[16][16] = {
17620339a1c2SMark Johnston {
17630339a1c2SMark Johnston /*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
17640339a1c2SMark Johnston /*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
17650339a1c2SMark Johnston /*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
1766*b3b5bfebSMark Johnston /*  [0C]  */	INVALID,		IND(dis_op0F0D),	INVALID,		INVALID,
17670339a1c2SMark Johnston }, {
17680339a1c2SMark Johnston /*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
17690339a1c2SMark Johnston /*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
17700339a1c2SMark Johnston /*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
1771c3ddb60eSPeter Grehan /*  [1C]  */	INVALID,		INVALID,		INVALID,		TS("nop",Mw),
17720339a1c2SMark Johnston }, {
17730339a1c2SMark Johnston /*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
17740339a1c2SMark Johnston /*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
17750339a1c2SMark Johnston /*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
17760339a1c2SMark Johnston /*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
17770339a1c2SMark Johnston }, {
17780339a1c2SMark Johnston /*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
17790339a1c2SMark Johnston /*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
17800339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
17810339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
17820339a1c2SMark Johnston }, {
17830339a1c2SMark Johnston /*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
17840339a1c2SMark Johnston /*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
17850339a1c2SMark Johnston /*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
17860339a1c2SMark Johnston /*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
17870339a1c2SMark Johnston }, {
17880339a1c2SMark Johnston /*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
17890339a1c2SMark Johnston /*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
17900339a1c2SMark Johnston /*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
17910339a1c2SMark Johnston /*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
17920339a1c2SMark Johnston }, {
17930339a1c2SMark Johnston /*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
17940339a1c2SMark Johnston /*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
17950339a1c2SMark Johnston /*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
17960339a1c2SMark Johnston /*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
17970339a1c2SMark Johnston }, {
17980339a1c2SMark Johnston /*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
17990339a1c2SMark Johnston /*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
1800c3ddb60eSPeter Grehan /*  [78]  */	TNSy("vmread",RM),	TNSy("vmwrite",MR),	INVALID,		INVALID,
18010339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
18020339a1c2SMark Johnston }, {
18030339a1c2SMark Johnston /*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
18040339a1c2SMark Johnston /*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
18050339a1c2SMark Johnston /*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
18060339a1c2SMark Johnston /*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
18070339a1c2SMark Johnston }, {
18080339a1c2SMark Johnston /*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
18090339a1c2SMark Johnston /*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
18100339a1c2SMark Johnston /*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
18110339a1c2SMark Johnston /*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
18120339a1c2SMark Johnston }, {
18130339a1c2SMark Johnston /*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
18140339a1c2SMark Johnston /*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
18150339a1c2SMark Johnston /*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
18160339a1c2SMark Johnston /*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
18170339a1c2SMark Johnston }, {
18180339a1c2SMark Johnston /*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
18190339a1c2SMark Johnston /*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
18200339a1c2SMark Johnston /*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
18210339a1c2SMark Johnston /*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
18220339a1c2SMark Johnston }, {
18230339a1c2SMark Johnston /*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
18240339a1c2SMark Johnston /*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
18250339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
18260339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
18270339a1c2SMark Johnston }, {
18280339a1c2SMark Johnston /*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
18290339a1c2SMark Johnston /*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
18300339a1c2SMark Johnston /*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
18310339a1c2SMark Johnston /*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
18320339a1c2SMark Johnston }, {
18330339a1c2SMark Johnston /*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
18340339a1c2SMark Johnston /*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
18350339a1c2SMark Johnston /*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
18360339a1c2SMark Johnston /*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
18370339a1c2SMark Johnston }, {
18380339a1c2SMark Johnston /*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
18390339a1c2SMark Johnston /*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
18400339a1c2SMark Johnston /*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
18410339a1c2SMark Johnston /*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
18420339a1c2SMark Johnston } };
18430339a1c2SMark Johnston 
18440339a1c2SMark Johnston const instable_t dis_opAVX0F[16][16] = {
18450339a1c2SMark Johnston {
18460339a1c2SMark Johnston /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
18470339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
18480339a1c2SMark Johnston /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
18490339a1c2SMark Johnston /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18500339a1c2SMark Johnston }, {
18510339a1c2SMark Johnston /*  [10]  */	TNSZ("vmovups",VEX_MX,16),	TNSZ("vmovups",VEX_RM,16),TNSZ("vmovlps",VEX_RMrX,8),	TNSZ("vmovlps",VEX_RM,8),
18520339a1c2SMark Johnston /*  [14]  */	TNSZ("vunpcklps",VEX_RMrX,16),TNSZ("vunpckhps",VEX_RMrX,16),TNSZ("vmovhps",VEX_RMrX,8),TNSZ("vmovhps",VEX_RM,8),
18530339a1c2SMark Johnston /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
18540339a1c2SMark Johnston /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18550339a1c2SMark Johnston }, {
18560339a1c2SMark Johnston /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
18570339a1c2SMark Johnston /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
18580339a1c2SMark Johnston /*  [28]  */	TNSZ("vmovaps",VEX_MX,16),	TNSZ("vmovaps",VEX_RX,16),INVALID,		TNSZ("vmovntps",VEX_RM,16),
18590339a1c2SMark Johnston /*  [2C]  */	INVALID,		INVALID,		TNSZ("vucomiss",VEX_MX,4),TNSZ("vcomiss",VEX_MX,4),
18600339a1c2SMark Johnston }, {
18610339a1c2SMark Johnston /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
18620339a1c2SMark Johnston /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
18630339a1c2SMark Johnston /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
18640339a1c2SMark Johnston /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18650339a1c2SMark Johnston }, {
18660339a1c2SMark Johnston /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
18670339a1c2SMark Johnston /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
18680339a1c2SMark Johnston /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
18690339a1c2SMark Johnston /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18700339a1c2SMark Johnston }, {
18710339a1c2SMark Johnston /*  [50]  */	TNS("vmovmskps",VEX_MR),	TNSZ("vsqrtps",VEX_MX,16),	TNSZ("vrsqrtps",VEX_MX,16),TNSZ("vrcpps",VEX_MX,16),
18720339a1c2SMark Johnston /*  [54]  */	TNSZ("vandps",VEX_RMrX,16),	TNSZ("vandnps",VEX_RMrX,16),	TNSZ("vorps",VEX_RMrX,16),	TNSZ("vxorps",VEX_RMrX,16),
18730339a1c2SMark Johnston /*  [58]  */	TNSZ("vaddps",VEX_RMrX,16),	TNSZ("vmulps",VEX_RMrX,16),	TNSZ("vcvtps2pd",VEX_MX,8),TNSZ("vcvtdq2ps",VEX_MX,16),
18740339a1c2SMark Johnston /*  [5C]  */	TNSZ("vsubps",VEX_RMrX,16),	TNSZ("vminps",VEX_RMrX,16),	TNSZ("vdivps",VEX_RMrX,16),	TNSZ("vmaxps",VEX_RMrX,16),
18750339a1c2SMark Johnston }, {
18760339a1c2SMark Johnston /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
18770339a1c2SMark Johnston /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
18780339a1c2SMark Johnston /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
18790339a1c2SMark Johnston /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18800339a1c2SMark Johnston }, {
18810339a1c2SMark Johnston /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
18820339a1c2SMark Johnston /*  [74]  */	INVALID,		INVALID,		INVALID,		TNS("vzeroupper", VEX_NONE),
18830339a1c2SMark Johnston /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
18840339a1c2SMark Johnston /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18850339a1c2SMark Johnston }, {
18860339a1c2SMark Johnston /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
18870339a1c2SMark Johnston /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
18880339a1c2SMark Johnston /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
18890339a1c2SMark Johnston /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18900339a1c2SMark Johnston }, {
18910339a1c2SMark Johnston /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
18920339a1c2SMark Johnston /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
18930339a1c2SMark Johnston /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
18940339a1c2SMark Johnston /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
18950339a1c2SMark Johnston }, {
18960339a1c2SMark Johnston /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
18970339a1c2SMark Johnston /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
18980339a1c2SMark Johnston /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
18990339a1c2SMark Johnston /*  [AC]  */	INVALID,		INVALID,		TNSZ("vldmxcsr",VEX_MO,2),		INVALID,
19000339a1c2SMark Johnston }, {
19010339a1c2SMark Johnston /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
19020339a1c2SMark Johnston /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
19030339a1c2SMark Johnston /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
19040339a1c2SMark Johnston /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
19050339a1c2SMark Johnston }, {
19060339a1c2SMark Johnston /*  [C0]  */	INVALID,		INVALID,		TNSZ("vcmpps",VEX_RMRX,16),INVALID,
19070339a1c2SMark Johnston /*  [C4]  */	INVALID,		INVALID,	 	TNSZ("vshufps",VEX_RMRX,16),INVALID,
19080339a1c2SMark Johnston /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
19090339a1c2SMark Johnston /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
19100339a1c2SMark Johnston }, {
19110339a1c2SMark Johnston /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
19120339a1c2SMark Johnston /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
19130339a1c2SMark Johnston /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
19140339a1c2SMark Johnston /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
19150339a1c2SMark Johnston }, {
19160339a1c2SMark Johnston /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
19170339a1c2SMark Johnston /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
19180339a1c2SMark Johnston /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
19190339a1c2SMark Johnston /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
19200339a1c2SMark Johnston }, {
1921*b3b5bfebSMark Johnston /*  [F0]  */	INVALID,		INVALID,		TNSZvr("andn",VEX_RMrX,5),TNSZvr("bls",BLS,5),
1922*b3b5bfebSMark Johnston /*  [F4]  */	INVALID,		TNSZvr("bzhi",VEX_VRMrX,5),INVALID,		TNSZvr("bextr",VEX_VRMrX,5),
19230339a1c2SMark Johnston /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
19240339a1c2SMark Johnston /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
19250339a1c2SMark Johnston } };
19260339a1c2SMark Johnston 
19270339a1c2SMark Johnston /*
19280339a1c2SMark Johnston  *	Decode table for 0x80 opcodes
19290339a1c2SMark Johnston  */
19300339a1c2SMark Johnston 
19310339a1c2SMark Johnston const instable_t dis_op80[8] = {
19320339a1c2SMark Johnston 
19330339a1c2SMark Johnston /*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
19340339a1c2SMark Johnston /*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
19350339a1c2SMark Johnston };
19360339a1c2SMark Johnston 
19370339a1c2SMark Johnston 
19380339a1c2SMark Johnston /*
19390339a1c2SMark Johnston  *	Decode table for 0x81 opcodes.
19400339a1c2SMark Johnston  */
19410339a1c2SMark Johnston 
19420339a1c2SMark Johnston const instable_t dis_op81[8] = {
19430339a1c2SMark Johnston 
19440339a1c2SMark Johnston /*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
19450339a1c2SMark Johnston /*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
19460339a1c2SMark Johnston };
19470339a1c2SMark Johnston 
19480339a1c2SMark Johnston 
19490339a1c2SMark Johnston /*
19500339a1c2SMark Johnston  *	Decode table for 0x82 opcodes.
19510339a1c2SMark Johnston  */
19520339a1c2SMark Johnston 
19530339a1c2SMark Johnston const instable_t dis_op82[8] = {
19540339a1c2SMark Johnston 
19550339a1c2SMark Johnston /*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
19560339a1c2SMark Johnston /*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
19570339a1c2SMark Johnston };
19580339a1c2SMark Johnston /*
19590339a1c2SMark Johnston  *	Decode table for 0x83 opcodes.
19600339a1c2SMark Johnston  */
19610339a1c2SMark Johnston 
19620339a1c2SMark Johnston const instable_t dis_op83[8] = {
19630339a1c2SMark Johnston 
19640339a1c2SMark Johnston /*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
19650339a1c2SMark Johnston /*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
19660339a1c2SMark Johnston };
19670339a1c2SMark Johnston 
19680339a1c2SMark Johnston /*
19690339a1c2SMark Johnston  *	Decode table for 0xC0 opcodes.
19700339a1c2SMark Johnston  */
19710339a1c2SMark Johnston 
19720339a1c2SMark Johnston const instable_t dis_opC0[8] = {
19730339a1c2SMark Johnston 
19740339a1c2SMark Johnston /*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
19750339a1c2SMark Johnston /*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
19760339a1c2SMark Johnston };
19770339a1c2SMark Johnston 
19780339a1c2SMark Johnston /*
19790339a1c2SMark Johnston  *	Decode table for 0xD0 opcodes.
19800339a1c2SMark Johnston  */
19810339a1c2SMark Johnston 
19820339a1c2SMark Johnston const instable_t dis_opD0[8] = {
19830339a1c2SMark Johnston 
19840339a1c2SMark Johnston /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
19850339a1c2SMark Johnston /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
19860339a1c2SMark Johnston };
19870339a1c2SMark Johnston 
19880339a1c2SMark Johnston /*
19890339a1c2SMark Johnston  *	Decode table for 0xC1 opcodes.
19900339a1c2SMark Johnston  *	186 instruction set
19910339a1c2SMark Johnston  */
19920339a1c2SMark Johnston 
19930339a1c2SMark Johnston const instable_t dis_opC1[8] = {
19940339a1c2SMark Johnston 
19950339a1c2SMark Johnston /*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
19960339a1c2SMark Johnston /*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
19970339a1c2SMark Johnston };
19980339a1c2SMark Johnston 
19990339a1c2SMark Johnston /*
20000339a1c2SMark Johnston  *	Decode table for 0xD1 opcodes.
20010339a1c2SMark Johnston  */
20020339a1c2SMark Johnston 
20030339a1c2SMark Johnston const instable_t dis_opD1[8] = {
20040339a1c2SMark Johnston 
20050339a1c2SMark Johnston /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
20060339a1c2SMark Johnston /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
20070339a1c2SMark Johnston };
20080339a1c2SMark Johnston 
20090339a1c2SMark Johnston 
20100339a1c2SMark Johnston /*
20110339a1c2SMark Johnston  *	Decode table for 0xD2 opcodes.
20120339a1c2SMark Johnston  */
20130339a1c2SMark Johnston 
20140339a1c2SMark Johnston const instable_t dis_opD2[8] = {
20150339a1c2SMark Johnston 
20160339a1c2SMark Johnston /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
20170339a1c2SMark Johnston /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
20180339a1c2SMark Johnston };
20190339a1c2SMark Johnston /*
20200339a1c2SMark Johnston  *	Decode table for 0xD3 opcodes.
20210339a1c2SMark Johnston  */
20220339a1c2SMark Johnston 
20230339a1c2SMark Johnston const instable_t dis_opD3[8] = {
20240339a1c2SMark Johnston 
20250339a1c2SMark Johnston /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
20260339a1c2SMark Johnston /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
20270339a1c2SMark Johnston };
20280339a1c2SMark Johnston 
20290339a1c2SMark Johnston 
20300339a1c2SMark Johnston /*
20310339a1c2SMark Johnston  *	Decode table for 0xF6 opcodes.
20320339a1c2SMark Johnston  */
20330339a1c2SMark Johnston 
20340339a1c2SMark Johnston const instable_t dis_opF6[8] = {
20350339a1c2SMark Johnston 
20360339a1c2SMark Johnston /*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
20370339a1c2SMark Johnston /*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
20380339a1c2SMark Johnston };
20390339a1c2SMark Johnston 
20400339a1c2SMark Johnston 
20410339a1c2SMark Johnston /*
20420339a1c2SMark Johnston  *	Decode table for 0xF7 opcodes.
20430339a1c2SMark Johnston  */
20440339a1c2SMark Johnston 
20450339a1c2SMark Johnston const instable_t dis_opF7[8] = {
20460339a1c2SMark Johnston 
20470339a1c2SMark Johnston /*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
20480339a1c2SMark Johnston /*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
20490339a1c2SMark Johnston };
20500339a1c2SMark Johnston 
20510339a1c2SMark Johnston 
20520339a1c2SMark Johnston /*
20530339a1c2SMark Johnston  *	Decode table for 0xFE opcodes.
20540339a1c2SMark Johnston  */
20550339a1c2SMark Johnston 
20560339a1c2SMark Johnston const instable_t dis_opFE[8] = {
20570339a1c2SMark Johnston 
20580339a1c2SMark Johnston /*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
20590339a1c2SMark Johnston /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
20600339a1c2SMark Johnston };
20610339a1c2SMark Johnston /*
20620339a1c2SMark Johnston  *	Decode table for 0xFF opcodes.
20630339a1c2SMark Johnston  */
20640339a1c2SMark Johnston 
20650339a1c2SMark Johnston const instable_t dis_opFF[8] = {
20660339a1c2SMark Johnston 
20670339a1c2SMark Johnston /*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
20680339a1c2SMark Johnston /*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
20690339a1c2SMark Johnston };
20700339a1c2SMark Johnston 
20710339a1c2SMark Johnston /* for 287 instructions, which are a mess to decode */
20720339a1c2SMark Johnston 
20730339a1c2SMark Johnston const instable_t dis_opFP1n2[8][8] = {
20740339a1c2SMark Johnston {
20750339a1c2SMark Johnston /* bit pattern:	1101 1xxx MODxx xR/M */
20760339a1c2SMark Johnston /*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
20770339a1c2SMark Johnston /*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
20780339a1c2SMark Johnston }, {
20790339a1c2SMark Johnston /*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
20800339a1c2SMark Johnston /*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
20810339a1c2SMark Johnston }, {
20820339a1c2SMark Johnston /*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
20830339a1c2SMark Johnston /*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
20840339a1c2SMark Johnston }, {
2085*b3b5bfebSMark Johnston /*  [3,0]  */	TNS("fildl",M),		TNSZ("tisttpl",M,4),	TNS("fistl",M),		TNS("fistpl",M),
20860339a1c2SMark Johnston /*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
20870339a1c2SMark Johnston }, {
20880339a1c2SMark Johnston /*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
20890339a1c2SMark Johnston /*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
20900339a1c2SMark Johnston }, {
2091*b3b5bfebSMark Johnston /*  [5,0]  */	TNSZ("fldl",M,8),	TNSZ("fisttpll",M,8),	TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
20920339a1c2SMark Johnston /*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
20930339a1c2SMark Johnston }, {
20940339a1c2SMark Johnston /*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
20950339a1c2SMark Johnston /*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
20960339a1c2SMark Johnston }, {
2097*b3b5bfebSMark Johnston /*  [7,0]  */	TNSZ("fild",M,2),	TNSZ("fisttp",M,2),	TNSZ("fist",M,2),	TNSZ("fistp",M,2),
20980339a1c2SMark Johnston /*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
20990339a1c2SMark Johnston } };
21000339a1c2SMark Johnston 
21010339a1c2SMark Johnston const instable_t dis_opFP3[8][8] = {
21020339a1c2SMark Johnston {
21030339a1c2SMark Johnston /* bit  pattern:	1101 1xxx 11xx xREG */
21040339a1c2SMark Johnston /*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
21050339a1c2SMark Johnston /*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
21060339a1c2SMark Johnston }, {
21070339a1c2SMark Johnston /*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
21080339a1c2SMark Johnston /*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
21090339a1c2SMark Johnston }, {
21100339a1c2SMark Johnston /*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
21110339a1c2SMark Johnston /*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
21120339a1c2SMark Johnston }, {
21130339a1c2SMark Johnston /*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
21140339a1c2SMark Johnston /*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
21150339a1c2SMark Johnston }, {
21160339a1c2SMark Johnston /*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
21170339a1c2SMark Johnston /*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
21180339a1c2SMark Johnston }, {
21190339a1c2SMark Johnston /*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
21200339a1c2SMark Johnston /*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
21210339a1c2SMark Johnston }, {
21220339a1c2SMark Johnston /*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
21230339a1c2SMark Johnston /*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
21240339a1c2SMark Johnston }, {
21250339a1c2SMark Johnston /*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
21260339a1c2SMark Johnston /*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
21270339a1c2SMark Johnston } };
21280339a1c2SMark Johnston 
21290339a1c2SMark Johnston const instable_t dis_opFP4[4][8] = {
21300339a1c2SMark Johnston {
21310339a1c2SMark Johnston /* bit pattern:	1101 1001 111x xxxx */
21320339a1c2SMark Johnston /*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
21330339a1c2SMark Johnston /*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
21340339a1c2SMark Johnston }, {
21350339a1c2SMark Johnston /*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
21360339a1c2SMark Johnston /*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
21370339a1c2SMark Johnston }, {
21380339a1c2SMark Johnston /*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
21390339a1c2SMark Johnston /*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
21400339a1c2SMark Johnston }, {
21410339a1c2SMark Johnston /*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
21420339a1c2SMark Johnston /*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
21430339a1c2SMark Johnston } };
21440339a1c2SMark Johnston 
21450339a1c2SMark Johnston const instable_t dis_opFP5[8] = {
21460339a1c2SMark Johnston /* bit pattern:	1101 1011 111x xxxx */
21470339a1c2SMark Johnston /*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
21480339a1c2SMark Johnston /*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
21490339a1c2SMark Johnston };
21500339a1c2SMark Johnston 
21510339a1c2SMark Johnston const instable_t dis_opFP6[8] = {
21520339a1c2SMark Johnston /* bit pattern:	1101 1011 11yy yxxx */
21530339a1c2SMark Johnston /*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
21540339a1c2SMark Johnston /*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
21550339a1c2SMark Johnston };
21560339a1c2SMark Johnston 
21570339a1c2SMark Johnston const instable_t dis_opFP7[8] = {
21580339a1c2SMark Johnston /* bit pattern:	1101 1010 11yy yxxx */
21590339a1c2SMark Johnston /*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
21600339a1c2SMark Johnston /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
21610339a1c2SMark Johnston };
21620339a1c2SMark Johnston 
21630339a1c2SMark Johnston /*
21640339a1c2SMark Johnston  *	Main decode table for the op codes.  The first two nibbles
21650339a1c2SMark Johnston  *	will be used as an index into the table.  If there is a
21660339a1c2SMark Johnston  *	a need to further decode an instruction, the array to be
21670339a1c2SMark Johnston  *	referenced is indicated with the other two entries being
21680339a1c2SMark Johnston  *	empty.
21690339a1c2SMark Johnston  */
21700339a1c2SMark Johnston 
21710339a1c2SMark Johnston const instable_t dis_distable[16][16] = {
21720339a1c2SMark Johnston {
21730339a1c2SMark Johnston /* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
21740339a1c2SMark Johnston /* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
21750339a1c2SMark Johnston /* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
21760339a1c2SMark Johnston /* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
21770339a1c2SMark Johnston }, {
21780339a1c2SMark Johnston /* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
21790339a1c2SMark Johnston /* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
21800339a1c2SMark Johnston /* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
21810339a1c2SMark Johnston /* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
21820339a1c2SMark Johnston }, {
21830339a1c2SMark Johnston /* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
2184c3ddb60eSPeter Grehan /* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNSx("%es:",OVERRIDE),	TNSx("daa",NORM),
21850339a1c2SMark Johnston /* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
21860339a1c2SMark Johnston /* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNS("%cs:",OVERRIDE),	TNSx("das",NORM),
21870339a1c2SMark Johnston }, {
21880339a1c2SMark Johnston /* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
2189c3ddb60eSPeter Grehan /* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNSx("%ss:",OVERRIDE),	TNSx("aaa",NORM),
21900339a1c2SMark Johnston /* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
2191c3ddb60eSPeter Grehan /* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNSx("%ds:",OVERRIDE),	TNSx("aas",NORM),
21920339a1c2SMark Johnston }, {
21930339a1c2SMark Johnston /* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
21940339a1c2SMark Johnston /* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
21950339a1c2SMark Johnston /* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
21960339a1c2SMark Johnston /* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
21970339a1c2SMark Johnston }, {
21980339a1c2SMark Johnston /* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
21990339a1c2SMark Johnston /* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
22000339a1c2SMark Johnston /* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
22010339a1c2SMark Johnston /* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
22020339a1c2SMark Johnston }, {
22030339a1c2SMark Johnston /* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
22040339a1c2SMark Johnston /* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
22050339a1c2SMark Johnston /* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
22060339a1c2SMark Johnston /* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
22070339a1c2SMark Johnston }, {
22080339a1c2SMark Johnston /* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
22090339a1c2SMark Johnston /* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
22100339a1c2SMark Johnston /* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
22110339a1c2SMark Johnston /* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
22120339a1c2SMark Johnston }, {
22130339a1c2SMark Johnston /* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
22140339a1c2SMark Johnston /* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
22150339a1c2SMark Johnston /* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
22160339a1c2SMark Johnston /* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
22170339a1c2SMark Johnston }, {
22180339a1c2SMark Johnston /* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
22190339a1c2SMark Johnston /* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
22200339a1c2SMark Johnston /* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
22212d69831bSAndriy Gapon /* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNS("sahf",NORM),	TNS("lahf",NORM),
22220339a1c2SMark Johnston }, {
22230339a1c2SMark Johnston /* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
22240339a1c2SMark Johnston /* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
22250339a1c2SMark Johnston /* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
22260339a1c2SMark Johnston /* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
22270339a1c2SMark Johnston }, {
22280339a1c2SMark Johnston /* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
22290339a1c2SMark Johnston /* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
22300339a1c2SMark Johnston /* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
22310339a1c2SMark Johnston /* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
22320339a1c2SMark Johnston }, {
22330339a1c2SMark Johnston /* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
22340339a1c2SMark Johnston /* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
22350339a1c2SMark Johnston /* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
22360339a1c2SMark Johnston /* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
22370339a1c2SMark Johnston }, {
22380339a1c2SMark Johnston /* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
22390339a1c2SMark Johnston /* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
22400339a1c2SMark Johnston 
22410339a1c2SMark Johnston /* 287 instructions.  Note that although the indirect field		*/
22420339a1c2SMark Johnston /* indicates opFP1n2 for further decoding, this is not necessarily	*/
22430339a1c2SMark Johnston /* the case since the opFP arrays are not partitioned according to key1	*/
22440339a1c2SMark Johnston /* and key2.  opFP1n2 is given only to indicate that we haven't		*/
22450339a1c2SMark Johnston /* finished decoding the instruction.					*/
22460339a1c2SMark Johnston /* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
22470339a1c2SMark Johnston /* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
22480339a1c2SMark Johnston }, {
22490339a1c2SMark Johnston /* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
22500339a1c2SMark Johnston /* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
22510339a1c2SMark Johnston /* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
22520339a1c2SMark Johnston /* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
22530339a1c2SMark Johnston }, {
22540339a1c2SMark Johnston /* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
22550339a1c2SMark Johnston /* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
22560339a1c2SMark Johnston /* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
22570339a1c2SMark Johnston /* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
22580339a1c2SMark Johnston } };
22590339a1c2SMark Johnston 
22600339a1c2SMark Johnston /* END CSTYLED */
22610339a1c2SMark Johnston 
22620339a1c2SMark Johnston /*
22630339a1c2SMark Johnston  * common functions to decode and disassemble an x86 or amd64 instruction
22640339a1c2SMark Johnston  */
22650339a1c2SMark Johnston 
22660339a1c2SMark Johnston /*
22670339a1c2SMark Johnston  * These are the individual fields of a REX prefix. Note that a REX
22680339a1c2SMark Johnston  * prefix with none of these set is still needed to:
22690339a1c2SMark Johnston  *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
22700339a1c2SMark Johnston  *	- access the %sil, %dil, %bpl, %spl registers
22710339a1c2SMark Johnston  */
22720339a1c2SMark Johnston #define	REX_W 0x08	/* 64 bit operand size when set */
22730339a1c2SMark Johnston #define	REX_R 0x04	/* high order bit extension of ModRM reg field */
22740339a1c2SMark Johnston #define	REX_X 0x02	/* high order bit extension of SIB index field */
22750339a1c2SMark Johnston #define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
22760339a1c2SMark Johnston 
22770339a1c2SMark Johnston /*
22780339a1c2SMark Johnston  * These are the individual fields of a VEX prefix.
22790339a1c2SMark Johnston  */
22800339a1c2SMark Johnston #define	VEX_R 0x08	/* REX.R in 1's complement form */
22810339a1c2SMark Johnston #define	VEX_X 0x04	/* REX.X in 1's complement form */
22820339a1c2SMark Johnston #define	VEX_B 0x02	/* REX.B in 1's complement form */
22830339a1c2SMark Johnston /* Vector Length, 0: scalar or 128-bit vector, 1: 256-bit vector */
22840339a1c2SMark Johnston #define	VEX_L 0x04
22850339a1c2SMark Johnston #define	VEX_W 0x08	/* opcode specific, use like REX.W */
22860339a1c2SMark Johnston #define	VEX_m 0x1F	/* VEX m-mmmm field */
22870339a1c2SMark Johnston #define	VEX_v 0x78	/* VEX register specifier */
22880339a1c2SMark Johnston #define	VEX_p 0x03	/* VEX pp field, opcode extension */
22890339a1c2SMark Johnston 
22900339a1c2SMark Johnston /* VEX m-mmmm field, only used by three bytes prefix */
22910339a1c2SMark Johnston #define	VEX_m_0F 0x01   /* implied 0F leading opcode byte */
22920339a1c2SMark Johnston #define	VEX_m_0F38 0x02 /* implied 0F 38 leading opcode byte */
22930339a1c2SMark Johnston #define	VEX_m_0F3A 0x03 /* implied 0F 3A leading opcode byte */
22940339a1c2SMark Johnston 
22950339a1c2SMark Johnston /* VEX pp field, providing equivalent functionality of a SIMD prefix */
22960339a1c2SMark Johnston #define	VEX_p_66 0x01
22970339a1c2SMark Johnston #define	VEX_p_F3 0x02
22980339a1c2SMark Johnston #define	VEX_p_F2 0x03
22990339a1c2SMark Johnston 
23000339a1c2SMark Johnston /*
23010339a1c2SMark Johnston  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
23020339a1c2SMark Johnston  */
23030339a1c2SMark Johnston static int isize[] = {1, 2, 4, 4};
23040339a1c2SMark Johnston static int isize64[] = {1, 2, 4, 8};
23050339a1c2SMark Johnston 
23060339a1c2SMark Johnston /*
23070339a1c2SMark Johnston  * Just a bunch of useful macros.
23080339a1c2SMark Johnston  */
23090339a1c2SMark Johnston #define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
23100339a1c2SMark Johnston #define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
23110339a1c2SMark Johnston #define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
23120339a1c2SMark Johnston #define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
23130339a1c2SMark Johnston #define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
23140339a1c2SMark Johnston 
23150339a1c2SMark Johnston #define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
23160339a1c2SMark Johnston 
23170339a1c2SMark Johnston #define	BYTE_OPND	0	/* w-bit value indicating byte register */
23180339a1c2SMark Johnston #define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
23190339a1c2SMark Johnston #define	MM_OPND		2	/* "value" used to indicate a mmx reg */
23200339a1c2SMark Johnston #define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
23210339a1c2SMark Johnston #define	SEG_OPND	4	/* "value" used to indicate a segment reg */
23220339a1c2SMark Johnston #define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
23230339a1c2SMark Johnston #define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
23240339a1c2SMark Johnston #define	TEST_OPND	7	/* "value" used to indicate a test reg */
23250339a1c2SMark Johnston #define	WORD_OPND	8	/* w-bit value indicating word size reg */
23260339a1c2SMark Johnston #define	YMM_OPND	9	/* "value" used to indicate a ymm reg */
23270339a1c2SMark Johnston 
23280339a1c2SMark Johnston /*
2329*b3b5bfebSMark Johnston  * The AVX2 gather instructions are a bit of a mess. While there's a pattern,
2330*b3b5bfebSMark Johnston  * there's not really a consistent scheme that we can use to know what the mode
2331*b3b5bfebSMark Johnston  * is supposed to be for a given type. Various instructions, like VPGATHERDD,
2332*b3b5bfebSMark Johnston  * always match the value of VEX_L. Other instructions like VPGATHERDQ, have
2333*b3b5bfebSMark Johnston  * some registers match VEX_L, but the VSIB is always XMM.
2334*b3b5bfebSMark Johnston  *
2335*b3b5bfebSMark Johnston  * The simplest way to deal with this is to just define a table based on the
2336*b3b5bfebSMark Johnston  * instruction opcodes, which are 0x90-0x93, so we subtract 0x90 to index into
2337*b3b5bfebSMark Johnston  * them.
2338*b3b5bfebSMark Johnston  *
2339*b3b5bfebSMark Johnston  * We further have to subdivide this based on the value of VEX_W and the value
2340*b3b5bfebSMark Johnston  * of VEX_L. The array is constructed to be indexed as:
2341*b3b5bfebSMark Johnston  * 	[opcode - 0x90][VEX_W][VEX_L].
2342*b3b5bfebSMark Johnston  */
2343*b3b5bfebSMark Johnston /* w = 0, 0x90 */
2344*b3b5bfebSMark Johnston typedef struct dis_gather_regs {
2345*b3b5bfebSMark Johnston 	uint_t dgr_arg0;	/* src reg */
2346*b3b5bfebSMark Johnston 	uint_t dgr_arg1;	/* vsib reg */
2347*b3b5bfebSMark Johnston 	uint_t dgr_arg2;	/* dst reg */
2348*b3b5bfebSMark Johnston 	char   *dgr_suffix;	/* suffix to append */
2349*b3b5bfebSMark Johnston } dis_gather_regs_t;
2350*b3b5bfebSMark Johnston 
2351*b3b5bfebSMark Johnston static dis_gather_regs_t dis_vgather[4][2][2] = {
2352*b3b5bfebSMark Johnston 	{
2353*b3b5bfebSMark Johnston 		/* op 0x90, W.0 */
2354*b3b5bfebSMark Johnston 		{
2355*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2356*b3b5bfebSMark Johnston 			{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2357*b3b5bfebSMark Johnston 		},
2358*b3b5bfebSMark Johnston 		/* op 0x90, W.1 */
2359*b3b5bfebSMark Johnston 		{
2360*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2361*b3b5bfebSMark Johnston 			{ YMM_OPND, XMM_OPND, YMM_OPND, "q" }
2362*b3b5bfebSMark Johnston 		}
2363*b3b5bfebSMark Johnston 	},
2364*b3b5bfebSMark Johnston 	{
2365*b3b5bfebSMark Johnston 		/* op 0x91, W.0 */
2366*b3b5bfebSMark Johnston 		{
2367*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2368*b3b5bfebSMark Johnston 			{ XMM_OPND, YMM_OPND, XMM_OPND, "d" },
2369*b3b5bfebSMark Johnston 		},
2370*b3b5bfebSMark Johnston 		/* op 0x91, W.1 */
2371*b3b5bfebSMark Johnston 		{
2372*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "q" },
2373*b3b5bfebSMark Johnston 			{ YMM_OPND, YMM_OPND, YMM_OPND, "q" },
2374*b3b5bfebSMark Johnston 		}
2375*b3b5bfebSMark Johnston 	},
2376*b3b5bfebSMark Johnston 	{
2377*b3b5bfebSMark Johnston 		/* op 0x92, W.0 */
2378*b3b5bfebSMark Johnston 		{
2379*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2380*b3b5bfebSMark Johnston 			{ YMM_OPND, YMM_OPND, YMM_OPND, "s" }
2381*b3b5bfebSMark Johnston 		},
2382*b3b5bfebSMark Johnston 		/* op 0x92, W.1 */
2383*b3b5bfebSMark Johnston 		{
2384*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2385*b3b5bfebSMark Johnston 			{ YMM_OPND, XMM_OPND, YMM_OPND, "d" }
2386*b3b5bfebSMark Johnston 		}
2387*b3b5bfebSMark Johnston 	},
2388*b3b5bfebSMark Johnston 	{
2389*b3b5bfebSMark Johnston 		/* op 0x93, W.0 */
2390*b3b5bfebSMark Johnston 		{
2391*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "s" },
2392*b3b5bfebSMark Johnston 			{ XMM_OPND, YMM_OPND, XMM_OPND, "s" }
2393*b3b5bfebSMark Johnston 		},
2394*b3b5bfebSMark Johnston 		/* op 0x93, W.1 */
2395*b3b5bfebSMark Johnston 		{
2396*b3b5bfebSMark Johnston 			{ XMM_OPND, XMM_OPND, XMM_OPND, "d" },
2397*b3b5bfebSMark Johnston 			{ YMM_OPND, YMM_OPND, YMM_OPND, "d" }
2398*b3b5bfebSMark Johnston 		}
2399*b3b5bfebSMark Johnston 	}
2400*b3b5bfebSMark Johnston };
2401*b3b5bfebSMark Johnston 
2402*b3b5bfebSMark Johnston /*
24030339a1c2SMark Johnston  * Get the next byte and separate the op code into the high and low nibbles.
24040339a1c2SMark Johnston  */
24050339a1c2SMark Johnston static int
24060339a1c2SMark Johnston dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
24070339a1c2SMark Johnston {
24080339a1c2SMark Johnston 	int byte;
24090339a1c2SMark Johnston 
24100339a1c2SMark Johnston 	/*
24110339a1c2SMark Johnston 	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
24120339a1c2SMark Johnston 	 * we try to read more.
24130339a1c2SMark Johnston 	 */
24140339a1c2SMark Johnston 	if (x->d86_len >= 15)
24150339a1c2SMark Johnston 		return (x->d86_error = 1);
24160339a1c2SMark Johnston 
24170339a1c2SMark Johnston 	if (x->d86_error)
24180339a1c2SMark Johnston 		return (1);
24190339a1c2SMark Johnston 	byte = x->d86_get_byte(x->d86_data);
24200339a1c2SMark Johnston 	if (byte < 0)
24210339a1c2SMark Johnston 		return (x->d86_error = 1);
24220339a1c2SMark Johnston 	x->d86_bytes[x->d86_len++] = byte;
24230339a1c2SMark Johnston 	*low = byte & 0xf;		/* ----xxxx low 4 bits */
24240339a1c2SMark Johnston 	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
24250339a1c2SMark Johnston 	return (0);
24260339a1c2SMark Johnston }
24270339a1c2SMark Johnston 
24280339a1c2SMark Johnston /*
24290339a1c2SMark Johnston  * Get and decode an SIB (scaled index base) byte
24300339a1c2SMark Johnston  */
24310339a1c2SMark Johnston static void
24320339a1c2SMark Johnston dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
24330339a1c2SMark Johnston {
24340339a1c2SMark Johnston 	int byte;
24350339a1c2SMark Johnston 
24360339a1c2SMark Johnston 	if (x->d86_error)
24370339a1c2SMark Johnston 		return;
24380339a1c2SMark Johnston 
24390339a1c2SMark Johnston 	byte = x->d86_get_byte(x->d86_data);
24400339a1c2SMark Johnston 	if (byte < 0) {
24410339a1c2SMark Johnston 		x->d86_error = 1;
24420339a1c2SMark Johnston 		return;
24430339a1c2SMark Johnston 	}
24440339a1c2SMark Johnston 	x->d86_bytes[x->d86_len++] = byte;
24450339a1c2SMark Johnston 
24460339a1c2SMark Johnston 	*base = byte & 0x7;
24470339a1c2SMark Johnston 	*index = (byte >> 3) & 0x7;
24480339a1c2SMark Johnston 	*ss = (byte >> 6) & 0x3;
24490339a1c2SMark Johnston }
24500339a1c2SMark Johnston 
24510339a1c2SMark Johnston /*
24520339a1c2SMark Johnston  * Get the byte following the op code and separate it into the
24530339a1c2SMark Johnston  * mode, register, and r/m fields.
24540339a1c2SMark Johnston  */
24550339a1c2SMark Johnston static void
24560339a1c2SMark Johnston dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
24570339a1c2SMark Johnston {
24580339a1c2SMark Johnston 	if (x->d86_got_modrm == 0) {
24590339a1c2SMark Johnston 		if (x->d86_rmindex == -1)
24600339a1c2SMark Johnston 			x->d86_rmindex = x->d86_len;
24610339a1c2SMark Johnston 		dtrace_get_SIB(x, mode, reg, r_m);
24620339a1c2SMark Johnston 		x->d86_got_modrm = 1;
24630339a1c2SMark Johnston 	}
24640339a1c2SMark Johnston }
24650339a1c2SMark Johnston 
24660339a1c2SMark Johnston /*
24670339a1c2SMark Johnston  * Adjust register selection based on any REX prefix bits present.
24680339a1c2SMark Johnston  */
24690339a1c2SMark Johnston /*ARGSUSED*/
24700339a1c2SMark Johnston static void
24710339a1c2SMark Johnston dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
24720339a1c2SMark Johnston {
24730339a1c2SMark Johnston 	if (reg != NULL && r_m == NULL) {
24740339a1c2SMark Johnston 		if (rex_prefix & REX_B)
24750339a1c2SMark Johnston 			*reg += 8;
24760339a1c2SMark Johnston 	} else {
24770339a1c2SMark Johnston 		if (reg != NULL && (REX_R & rex_prefix) != 0)
24780339a1c2SMark Johnston 			*reg += 8;
24790339a1c2SMark Johnston 		if (r_m != NULL && (REX_B & rex_prefix) != 0)
24800339a1c2SMark Johnston 			*r_m += 8;
24810339a1c2SMark Johnston 	}
24820339a1c2SMark Johnston }
24830339a1c2SMark Johnston 
24840339a1c2SMark Johnston /*
24850339a1c2SMark Johnston  * Adjust register selection based on any VEX prefix bits present.
24860339a1c2SMark Johnston  * Notes: VEX.R, VEX.X and VEX.B use the inverted form compared with REX prefix
24870339a1c2SMark Johnston  */
24880339a1c2SMark Johnston /*ARGSUSED*/
24890339a1c2SMark Johnston static void
24900339a1c2SMark Johnston dtrace_vex_adjust(uint_t vex_byte1, uint_t mode, uint_t *reg, uint_t *r_m)
24910339a1c2SMark Johnston {
24920339a1c2SMark Johnston 	if (reg != NULL && r_m == NULL) {
24930339a1c2SMark Johnston 		if (!(vex_byte1 & VEX_B))
24940339a1c2SMark Johnston 			*reg += 8;
24950339a1c2SMark Johnston 	} else {
24960339a1c2SMark Johnston 		if (reg != NULL && ((VEX_R & vex_byte1) == 0))
24970339a1c2SMark Johnston 			*reg += 8;
24980339a1c2SMark Johnston 		if (r_m != NULL && ((VEX_B & vex_byte1) == 0))
24990339a1c2SMark Johnston 			*r_m += 8;
25000339a1c2SMark Johnston 	}
25010339a1c2SMark Johnston }
25020339a1c2SMark Johnston 
25030339a1c2SMark Johnston /*
25040339a1c2SMark Johnston  * Get an immediate operand of the given size, with sign extension.
25050339a1c2SMark Johnston  */
25060339a1c2SMark Johnston static void
25070339a1c2SMark Johnston dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
25080339a1c2SMark Johnston {
25090339a1c2SMark Johnston 	int i;
25100339a1c2SMark Johnston 	int byte;
25110339a1c2SMark Johnston 	int valsize;
25120339a1c2SMark Johnston 
25130339a1c2SMark Johnston 	if (x->d86_numopnds < opindex + 1)
25140339a1c2SMark Johnston 		x->d86_numopnds = opindex + 1;
25150339a1c2SMark Johnston 
25160339a1c2SMark Johnston 	switch (wbit) {
25170339a1c2SMark Johnston 	case BYTE_OPND:
25180339a1c2SMark Johnston 		valsize = 1;
25190339a1c2SMark Johnston 		break;
25200339a1c2SMark Johnston 	case LONG_OPND:
25210339a1c2SMark Johnston 		if (x->d86_opnd_size == SIZE16)
25220339a1c2SMark Johnston 			valsize = 2;
25230339a1c2SMark Johnston 		else if (x->d86_opnd_size == SIZE32)
25240339a1c2SMark Johnston 			valsize = 4;
25250339a1c2SMark Johnston 		else
25260339a1c2SMark Johnston 			valsize = 8;
25270339a1c2SMark Johnston 		break;
25280339a1c2SMark Johnston 	case MM_OPND:
25290339a1c2SMark Johnston 	case XMM_OPND:
25300339a1c2SMark Johnston 	case YMM_OPND:
25310339a1c2SMark Johnston 	case SEG_OPND:
25320339a1c2SMark Johnston 	case CONTROL_OPND:
25330339a1c2SMark Johnston 	case DEBUG_OPND:
25340339a1c2SMark Johnston 	case TEST_OPND:
25350339a1c2SMark Johnston 		valsize = size;
25360339a1c2SMark Johnston 		break;
25370339a1c2SMark Johnston 	case WORD_OPND:
25380339a1c2SMark Johnston 		valsize = 2;
25390339a1c2SMark Johnston 		break;
25400339a1c2SMark Johnston 	}
25410339a1c2SMark Johnston 	if (valsize < size)
25420339a1c2SMark Johnston 		valsize = size;
25430339a1c2SMark Johnston 
25440339a1c2SMark Johnston 	if (x->d86_error)
25450339a1c2SMark Johnston 		return;
25460339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_value = 0;
25470339a1c2SMark Johnston 	for (i = 0; i < size; ++i) {
25480339a1c2SMark Johnston 		byte = x->d86_get_byte(x->d86_data);
25490339a1c2SMark Johnston 		if (byte < 0) {
25500339a1c2SMark Johnston 			x->d86_error = 1;
25510339a1c2SMark Johnston 			return;
25520339a1c2SMark Johnston 		}
25530339a1c2SMark Johnston 		x->d86_bytes[x->d86_len++] = byte;
25540339a1c2SMark Johnston 		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
25550339a1c2SMark Johnston 	}
25560339a1c2SMark Johnston 	/* Do sign extension */
25570339a1c2SMark Johnston 	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
25580339a1c2SMark Johnston 		for (; i < sizeof (uint64_t); i++)
25590339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_value |=
25600339a1c2SMark Johnston 			    (uint64_t)0xff << (i * 8);
25610339a1c2SMark Johnston 	}
25620339a1c2SMark Johnston #ifdef DIS_TEXT
25630339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
25640339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_value_size = valsize;
25650339a1c2SMark Johnston 	x->d86_imm_bytes += size;
25660339a1c2SMark Johnston #endif
25670339a1c2SMark Johnston }
25680339a1c2SMark Johnston 
25690339a1c2SMark Johnston /*
25700339a1c2SMark Johnston  * Get an ip relative operand of the given size, with sign extension.
25710339a1c2SMark Johnston  */
25720339a1c2SMark Johnston static void
25730339a1c2SMark Johnston dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
25740339a1c2SMark Johnston {
25750339a1c2SMark Johnston 	dtrace_imm_opnd(x, wbit, size, opindex);
25760339a1c2SMark Johnston #ifdef DIS_TEXT
25770339a1c2SMark Johnston 	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
25780339a1c2SMark Johnston #endif
25790339a1c2SMark Johnston }
25800339a1c2SMark Johnston 
25810339a1c2SMark Johnston /*
25820339a1c2SMark Johnston  * Check to see if there is a segment override prefix pending.
25830339a1c2SMark Johnston  * If so, print it in the current 'operand' location and set
25840339a1c2SMark Johnston  * the override flag back to false.
25850339a1c2SMark Johnston  */
25860339a1c2SMark Johnston /*ARGSUSED*/
25870339a1c2SMark Johnston static void
25880339a1c2SMark Johnston dtrace_check_override(dis86_t *x, int opindex)
25890339a1c2SMark Johnston {
25900339a1c2SMark Johnston #ifdef DIS_TEXT
25910339a1c2SMark Johnston 	if (x->d86_seg_prefix) {
25920339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
25930339a1c2SMark Johnston 		    x->d86_seg_prefix, PFIXLEN);
25940339a1c2SMark Johnston 	}
25950339a1c2SMark Johnston #endif
25960339a1c2SMark Johnston 	x->d86_seg_prefix = NULL;
25970339a1c2SMark Johnston }
25980339a1c2SMark Johnston 
25990339a1c2SMark Johnston 
26000339a1c2SMark Johnston /*
26010339a1c2SMark Johnston  * Process a single instruction Register or Memory operand.
26020339a1c2SMark Johnston  *
26030339a1c2SMark Johnston  * mode = addressing mode from ModRM byte
26040339a1c2SMark Johnston  * r_m = r_m (or reg if mode == 3) field from ModRM byte
26050339a1c2SMark Johnston  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
26060339a1c2SMark Johnston  * o = index of operand that we are processing (0, 1 or 2)
26070339a1c2SMark Johnston  *
26080339a1c2SMark Johnston  * the value of reg or r_m must have already been adjusted for any REX prefix.
26090339a1c2SMark Johnston  */
26100339a1c2SMark Johnston /*ARGSUSED*/
26110339a1c2SMark Johnston static void
26120339a1c2SMark Johnston dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
26130339a1c2SMark Johnston {
26140339a1c2SMark Johnston 	int have_SIB = 0;	/* flag presence of scale-index-byte */
26150339a1c2SMark Johnston 	uint_t ss;		/* scale-factor from opcode */
26160339a1c2SMark Johnston 	uint_t index;		/* index register number */
26170339a1c2SMark Johnston 	uint_t base;		/* base register number */
26180339a1c2SMark Johnston 	int dispsize;   	/* size of displacement in bytes */
26190339a1c2SMark Johnston #ifdef DIS_TEXT
26200339a1c2SMark Johnston 	char *opnd = x->d86_opnd[opindex].d86_opnd;
26210339a1c2SMark Johnston #endif
26220339a1c2SMark Johnston 
26230339a1c2SMark Johnston 	if (x->d86_numopnds < opindex + 1)
26240339a1c2SMark Johnston 		x->d86_numopnds = opindex + 1;
26250339a1c2SMark Johnston 
26260339a1c2SMark Johnston 	if (x->d86_error)
26270339a1c2SMark Johnston 		return;
26280339a1c2SMark Johnston 
26290339a1c2SMark Johnston 	/*
26300339a1c2SMark Johnston 	 * first handle a simple register
26310339a1c2SMark Johnston 	 */
26320339a1c2SMark Johnston 	if (mode == REG_ONLY) {
26330339a1c2SMark Johnston #ifdef DIS_TEXT
26340339a1c2SMark Johnston 		switch (wbit) {
26350339a1c2SMark Johnston 		case MM_OPND:
26360339a1c2SMark Johnston 			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
26370339a1c2SMark Johnston 			break;
26380339a1c2SMark Johnston 		case XMM_OPND:
26390339a1c2SMark Johnston 			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
26400339a1c2SMark Johnston 			break;
26410339a1c2SMark Johnston 		case YMM_OPND:
26420339a1c2SMark Johnston 			(void) strlcat(opnd, dis_YMMREG[r_m], OPLEN);
26430339a1c2SMark Johnston 			break;
26440339a1c2SMark Johnston 		case SEG_OPND:
26450339a1c2SMark Johnston 			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
26460339a1c2SMark Johnston 			break;
26470339a1c2SMark Johnston 		case CONTROL_OPND:
26480339a1c2SMark Johnston 			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
26490339a1c2SMark Johnston 			break;
26500339a1c2SMark Johnston 		case DEBUG_OPND:
26510339a1c2SMark Johnston 			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
26520339a1c2SMark Johnston 			break;
26530339a1c2SMark Johnston 		case TEST_OPND:
26540339a1c2SMark Johnston 			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
26550339a1c2SMark Johnston 			break;
26560339a1c2SMark Johnston 		case BYTE_OPND:
26570339a1c2SMark Johnston 			if (x->d86_rex_prefix == 0)
26580339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
26590339a1c2SMark Johnston 			else
26600339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
26610339a1c2SMark Johnston 			break;
26620339a1c2SMark Johnston 		case WORD_OPND:
26630339a1c2SMark Johnston 			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
26640339a1c2SMark Johnston 			break;
26650339a1c2SMark Johnston 		case LONG_OPND:
26660339a1c2SMark Johnston 			if (x->d86_opnd_size == SIZE16)
26670339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
26680339a1c2SMark Johnston 			else if (x->d86_opnd_size == SIZE32)
26690339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
26700339a1c2SMark Johnston 			else
26710339a1c2SMark Johnston 				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
26720339a1c2SMark Johnston 			break;
26730339a1c2SMark Johnston 		}
26740339a1c2SMark Johnston #endif /* DIS_TEXT */
26750339a1c2SMark Johnston 		return;
26760339a1c2SMark Johnston 	}
26770339a1c2SMark Johnston 
26780339a1c2SMark Johnston 	/*
26790339a1c2SMark Johnston 	 * if symbolic representation, skip override prefix, if any
26800339a1c2SMark Johnston 	 */
26810339a1c2SMark Johnston 	dtrace_check_override(x, opindex);
26820339a1c2SMark Johnston 
26830339a1c2SMark Johnston 	/*
26840339a1c2SMark Johnston 	 * Handle 16 bit memory references first, since they decode
26850339a1c2SMark Johnston 	 * the mode values more simply.
26860339a1c2SMark Johnston 	 * mode 1 is r_m + 8 bit displacement
26870339a1c2SMark Johnston 	 * mode 2 is r_m + 16 bit displacement
26880339a1c2SMark Johnston 	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
26890339a1c2SMark Johnston 	 */
26900339a1c2SMark Johnston 	if (x->d86_addr_size == SIZE16) {
26910339a1c2SMark Johnston 		if ((mode == 0 && r_m == 6) || mode == 2)
26920339a1c2SMark Johnston 			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
26930339a1c2SMark Johnston 		else if (mode == 1)
26940339a1c2SMark Johnston 			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
26950339a1c2SMark Johnston #ifdef DIS_TEXT
26960339a1c2SMark Johnston 		if (mode == 0 && r_m == 6)
26970339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
26980339a1c2SMark Johnston 		else if (mode == 0)
26990339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_NONE;
27000339a1c2SMark Johnston 		else
27010339a1c2SMark Johnston 			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
27020339a1c2SMark Johnston 		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
27030339a1c2SMark Johnston #endif
27040339a1c2SMark Johnston 		return;
27050339a1c2SMark Johnston 	}
27060339a1c2SMark Johnston 
27070339a1c2SMark Johnston 	/*
27080339a1c2SMark Johnston 	 * 32 and 64 bit addressing modes are more complex since they
27090339a1c2SMark Johnston 	 * can involve an SIB (scaled index and base) byte to decode.
27100339a1c2SMark Johnston 	 */
27110339a1c2SMark Johnston 	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
27120339a1c2SMark Johnston 		have_SIB = 1;
27130339a1c2SMark Johnston 		dtrace_get_SIB(x, &ss, &index, &base);
27140339a1c2SMark Johnston 		if (x->d86_error)
27150339a1c2SMark Johnston 			return;
27160339a1c2SMark Johnston 		if (base != 5 || mode != 0)
27170339a1c2SMark Johnston 			if (x->d86_rex_prefix & REX_B)
27180339a1c2SMark Johnston 				base += 8;
27190339a1c2SMark Johnston 		if (x->d86_rex_prefix & REX_X)
27200339a1c2SMark Johnston 			index += 8;
27210339a1c2SMark Johnston 	} else {
27220339a1c2SMark Johnston 		base = r_m;
27230339a1c2SMark Johnston 	}
27240339a1c2SMark Johnston 
27250339a1c2SMark Johnston 	/*
27260339a1c2SMark Johnston 	 * Compute the displacement size and get its bytes
27270339a1c2SMark Johnston 	 */
27280339a1c2SMark Johnston 	dispsize = 0;
27290339a1c2SMark Johnston 
27300339a1c2SMark Johnston 	if (mode == 1)
27310339a1c2SMark Johnston 		dispsize = 1;
27320339a1c2SMark Johnston 	else if (mode == 2)
27330339a1c2SMark Johnston 		dispsize = 4;
27340339a1c2SMark Johnston 	else if ((r_m & 7) == EBP_REGNO ||
27350339a1c2SMark Johnston 	    (have_SIB && (base & 7) == EBP_REGNO))
27360339a1c2SMark Johnston 		dispsize = 4;
27370339a1c2SMark Johnston 
27380339a1c2SMark Johnston 	if (dispsize > 0) {
27390339a1c2SMark Johnston 		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
27400339a1c2SMark Johnston 		    dispsize, opindex);
27410339a1c2SMark Johnston 		if (x->d86_error)
27420339a1c2SMark Johnston 			return;
27430339a1c2SMark Johnston 	}
27440339a1c2SMark Johnston 
27450339a1c2SMark Johnston #ifdef DIS_TEXT
27460339a1c2SMark Johnston 	if (dispsize > 0)
27470339a1c2SMark Johnston 		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
27480339a1c2SMark Johnston 
27490339a1c2SMark Johnston 	if (have_SIB == 0) {
27500339a1c2SMark Johnston 		if (x->d86_mode == SIZE32) {
27510339a1c2SMark Johnston 			if (mode == 0)
27520339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr32_mode0[r_m],
27530339a1c2SMark Johnston 				    OPLEN);
27540339a1c2SMark Johnston 			else
27550339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr32_mode12[r_m],
27560339a1c2SMark Johnston 				    OPLEN);
27570339a1c2SMark Johnston 		} else {
27580339a1c2SMark Johnston 			if (mode == 0) {
27590339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr64_mode0[r_m],
27600339a1c2SMark Johnston 				    OPLEN);
27610339a1c2SMark Johnston 				if (r_m == 5) {
27620339a1c2SMark Johnston 					x->d86_opnd[opindex].d86_mode =
27630339a1c2SMark Johnston 					    MODE_RIPREL;
27640339a1c2SMark Johnston 				}
27650339a1c2SMark Johnston 			} else {
27660339a1c2SMark Johnston 				(void) strlcat(opnd, dis_addr64_mode12[r_m],
27670339a1c2SMark Johnston 				    OPLEN);
27680339a1c2SMark Johnston 			}
27690339a1c2SMark Johnston 		}
27700339a1c2SMark Johnston 	} else {
27710339a1c2SMark Johnston 		uint_t need_paren = 0;
27720339a1c2SMark Johnston 		char **regs;
2773*b3b5bfebSMark Johnston 		char **bregs;
2774*b3b5bfebSMark Johnston 		const char *const *sf;
27750339a1c2SMark Johnston 		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
27760339a1c2SMark Johnston 			regs = (char **)dis_REG32;
27770339a1c2SMark Johnston 		else
27780339a1c2SMark Johnston 			regs = (char **)dis_REG64;
27790339a1c2SMark Johnston 
2780*b3b5bfebSMark Johnston 		if (x->d86_vsib != 0) {
2781*b3b5bfebSMark Johnston 			if (wbit == YMM_OPND) /* NOTE this is not addr_size! */
2782*b3b5bfebSMark Johnston 				bregs = (char **)dis_YMMREG;
2783*b3b5bfebSMark Johnston 			else
2784*b3b5bfebSMark Johnston 				bregs = (char **)dis_XMMREG;
2785*b3b5bfebSMark Johnston 			sf = dis_vscale_factor;
2786*b3b5bfebSMark Johnston 		} else {
2787*b3b5bfebSMark Johnston 			bregs = regs;
2788*b3b5bfebSMark Johnston 			sf = dis_scale_factor;
2789*b3b5bfebSMark Johnston 		}
2790*b3b5bfebSMark Johnston 
27910339a1c2SMark Johnston 		/*
27920339a1c2SMark Johnston 		 * print the base (if any)
27930339a1c2SMark Johnston 		 */
27940339a1c2SMark Johnston 		if (base == EBP_REGNO && mode == 0) {
2795*b3b5bfebSMark Johnston 			if (index != ESP_REGNO || x->d86_vsib != 0) {
27960339a1c2SMark Johnston 				(void) strlcat(opnd, "(", OPLEN);
27970339a1c2SMark Johnston 				need_paren = 1;
27980339a1c2SMark Johnston 			}
27990339a1c2SMark Johnston 		} else {
28000339a1c2SMark Johnston 			(void) strlcat(opnd, "(", OPLEN);
28010339a1c2SMark Johnston 			(void) strlcat(opnd, regs[base], OPLEN);
28020339a1c2SMark Johnston 			need_paren = 1;
28030339a1c2SMark Johnston 		}
28040339a1c2SMark Johnston 
28050339a1c2SMark Johnston 		/*
28060339a1c2SMark Johnston 		 * print the index (if any)
28070339a1c2SMark Johnston 		 */
2808*b3b5bfebSMark Johnston 		if (index != ESP_REGNO || x->d86_vsib) {
28090339a1c2SMark Johnston 			(void) strlcat(opnd, ",", OPLEN);
2810*b3b5bfebSMark Johnston 			(void) strlcat(opnd, bregs[index], OPLEN);
2811*b3b5bfebSMark Johnston 			(void) strlcat(opnd, sf[ss], OPLEN);
28120339a1c2SMark Johnston 		} else
28130339a1c2SMark Johnston 			if (need_paren)
28140339a1c2SMark Johnston 				(void) strlcat(opnd, ")", OPLEN);
28150339a1c2SMark Johnston 	}
28160339a1c2SMark Johnston #endif
28170339a1c2SMark Johnston }
28180339a1c2SMark Johnston 
28190339a1c2SMark Johnston /*
28200339a1c2SMark Johnston  * Operand sequence for standard instruction involving one register
28210339a1c2SMark Johnston  * and one register/memory operand.
28220339a1c2SMark Johnston  * wbit indicates a byte(0) or opnd_size(1) operation
28230339a1c2SMark Johnston  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
28240339a1c2SMark Johnston  */
28250339a1c2SMark Johnston #define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
28260339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
28270339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
28280339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
28290339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
28300339a1c2SMark Johnston }
28310339a1c2SMark Johnston 
28320339a1c2SMark Johnston /*
28330339a1c2SMark Johnston  * Similar to above, but allows for the two operands to be of different
28340339a1c2SMark Johnston  * classes (ie. wbit).
28350339a1c2SMark Johnston  *	wbit is for the r_m operand
28360339a1c2SMark Johnston  *	w2 is for the reg operand
28370339a1c2SMark Johnston  */
28380339a1c2SMark Johnston #define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
28390339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
28400339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
28410339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
28420339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
28430339a1c2SMark Johnston }
28440339a1c2SMark Johnston 
28450339a1c2SMark Johnston /*
28460339a1c2SMark Johnston  * Similar, but for 2 operands plus an immediate.
28470339a1c2SMark Johnston  * vbit indicates direction
28480339a1c2SMark Johnston  * 	0 for "opcode imm, r, r_m" or
28490339a1c2SMark Johnston  *	1 for "opcode imm, r_m, r"
28500339a1c2SMark Johnston  */
28510339a1c2SMark Johnston #define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
28520339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
28530339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
28540339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
28550339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
28560339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
28570339a1c2SMark Johnston }
28580339a1c2SMark Johnston 
28590339a1c2SMark Johnston /*
28600339a1c2SMark Johnston  * Similar, but for 2 operands plus two immediates.
28610339a1c2SMark Johnston  */
28620339a1c2SMark Johnston #define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
28630339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
28640339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
28650339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
28660339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
28670339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
28680339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
28690339a1c2SMark Johnston }
28700339a1c2SMark Johnston 
28710339a1c2SMark Johnston /*
28720339a1c2SMark Johnston  * 1 operands plus two immediates.
28730339a1c2SMark Johnston  */
28740339a1c2SMark Johnston #define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
28750339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
28760339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
28770339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
28780339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
28790339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
28800339a1c2SMark Johnston }
28810339a1c2SMark Johnston 
28820339a1c2SMark Johnston /*
28830339a1c2SMark Johnston  * Dissassemble a single x86 or amd64 instruction.
28840339a1c2SMark Johnston  *
28850339a1c2SMark Johnston  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
28860339a1c2SMark Johnston  * for interpreting instructions.
28870339a1c2SMark Johnston  *
28880339a1c2SMark Johnston  * returns non-zero for bad opcode
28890339a1c2SMark Johnston  */
28900339a1c2SMark Johnston int
28910339a1c2SMark Johnston dtrace_disx86(dis86_t *x, uint_t cpu_mode)
28920339a1c2SMark Johnston {
28930339a1c2SMark Johnston 	instable_t *dp;		/* decode table being used */
28940339a1c2SMark Johnston #ifdef DIS_TEXT
28950339a1c2SMark Johnston 	uint_t i;
28960339a1c2SMark Johnston #endif
28970339a1c2SMark Johnston #ifdef DIS_MEM
28980339a1c2SMark Johnston 	uint_t nomem = 0;
28990339a1c2SMark Johnston #define	NOMEM	(nomem = 1)
29000339a1c2SMark Johnston #else
29010339a1c2SMark Johnston #define	NOMEM	/* nothing */
29020339a1c2SMark Johnston #endif
29030339a1c2SMark Johnston 	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
29040339a1c2SMark Johnston 	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
29050339a1c2SMark Johnston 	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
29060339a1c2SMark Johnston 	uint_t w2;		/* wbit value for second operand */
29070339a1c2SMark Johnston 	uint_t vbit;
29080339a1c2SMark Johnston 	uint_t mode = 0;	/* mode value from ModRM byte */
29090339a1c2SMark Johnston 	uint_t reg;		/* reg value from ModRM byte */
29100339a1c2SMark Johnston 	uint_t r_m;		/* r_m value from ModRM byte */
29110339a1c2SMark Johnston 
29120339a1c2SMark Johnston 	uint_t opcode1;		/* high nibble of 1st byte */
29130339a1c2SMark Johnston 	uint_t opcode2;		/* low nibble of 1st byte */
29140339a1c2SMark Johnston 	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
29150339a1c2SMark Johnston 	uint_t opcode4;		/* high nibble of 2nd byte */
29160339a1c2SMark Johnston 	uint_t opcode5;		/* low nibble of 2nd byte */
29170339a1c2SMark Johnston 	uint_t opcode6;		/* high nibble of 3rd byte */
29180339a1c2SMark Johnston 	uint_t opcode7;		/* low nibble of 3rd byte */
29190339a1c2SMark Johnston 	uint_t opcode_bytes = 1;
29200339a1c2SMark Johnston 
29210339a1c2SMark Johnston 	/*
29220339a1c2SMark Johnston 	 * legacy prefixes come in 5 flavors, you should have only one of each
29230339a1c2SMark Johnston 	 */
29240339a1c2SMark Johnston 	uint_t	opnd_size_prefix = 0;
29250339a1c2SMark Johnston 	uint_t	addr_size_prefix = 0;
29260339a1c2SMark Johnston 	uint_t	segment_prefix = 0;
29270339a1c2SMark Johnston 	uint_t	lock_prefix = 0;
29280339a1c2SMark Johnston 	uint_t	rep_prefix = 0;
29290339a1c2SMark Johnston 	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
29300339a1c2SMark Johnston 
29310339a1c2SMark Johnston 	/*
29320339a1c2SMark Johnston 	 * Intel VEX instruction encoding prefix and fields
29330339a1c2SMark Johnston 	 */
29340339a1c2SMark Johnston 
29350339a1c2SMark Johnston 	/* 0xC4 means 3 bytes prefix, 0xC5 means 2 bytes prefix */
29360339a1c2SMark Johnston 	uint_t vex_prefix = 0;
29370339a1c2SMark Johnston 
29380339a1c2SMark Johnston 	/*
29390339a1c2SMark Johnston 	 * VEX prefix byte 1, includes vex.r, vex.x and vex.b
29400339a1c2SMark Johnston 	 * (for 3 bytes prefix)
29410339a1c2SMark Johnston 	 */
29420339a1c2SMark Johnston 	uint_t vex_byte1 = 0;
29430339a1c2SMark Johnston 
29440339a1c2SMark Johnston 	/*
29450339a1c2SMark Johnston 	 * For 32-bit mode, it should prefetch the next byte to
29460339a1c2SMark Johnston 	 * distinguish between AVX and les/lds
29470339a1c2SMark Johnston 	 */
29480339a1c2SMark Johnston 	uint_t vex_prefetch = 0;
29490339a1c2SMark Johnston 
29500339a1c2SMark Johnston 	uint_t vex_m = 0;
29510339a1c2SMark Johnston 	uint_t vex_v = 0;
29520339a1c2SMark Johnston 	uint_t vex_p = 0;
29530339a1c2SMark Johnston 	uint_t vex_R = 1;
29540339a1c2SMark Johnston 	uint_t vex_X = 1;
29550339a1c2SMark Johnston 	uint_t vex_B = 1;
29560339a1c2SMark Johnston 	uint_t vex_W = 0;
29570339a1c2SMark Johnston 	uint_t vex_L;
2958*b3b5bfebSMark Johnston 	dis_gather_regs_t *vreg;
29590339a1c2SMark Johnston 
2960*b3b5bfebSMark Johnston #ifdef	DIS_TEXT
2961*b3b5bfebSMark Johnston 	/* Instruction name for BLS* family of instructions */
2962*b3b5bfebSMark Johnston 	char *blsinstr;
2963*b3b5bfebSMark Johnston #endif
29640339a1c2SMark Johnston 
29650339a1c2SMark Johnston 	size_t	off;
29660339a1c2SMark Johnston 
29670339a1c2SMark Johnston 	instable_t dp_mmx;
29680339a1c2SMark Johnston 
29690339a1c2SMark Johnston 	x->d86_len = 0;
29700339a1c2SMark Johnston 	x->d86_rmindex = -1;
29710339a1c2SMark Johnston 	x->d86_error = 0;
29720339a1c2SMark Johnston #ifdef DIS_TEXT
29730339a1c2SMark Johnston 	x->d86_numopnds = 0;
29740339a1c2SMark Johnston 	x->d86_seg_prefix = NULL;
29750339a1c2SMark Johnston 	x->d86_mnem[0] = 0;
29760339a1c2SMark Johnston 	for (i = 0; i < 4; ++i) {
29770339a1c2SMark Johnston 		x->d86_opnd[i].d86_opnd[0] = 0;
29780339a1c2SMark Johnston 		x->d86_opnd[i].d86_prefix[0] = 0;
29790339a1c2SMark Johnston 		x->d86_opnd[i].d86_value_size = 0;
29800339a1c2SMark Johnston 		x->d86_opnd[i].d86_value = 0;
29810339a1c2SMark Johnston 		x->d86_opnd[i].d86_mode = MODE_NONE;
29820339a1c2SMark Johnston 	}
29830339a1c2SMark Johnston #endif
29840339a1c2SMark Johnston 	x->d86_rex_prefix = 0;
29850339a1c2SMark Johnston 	x->d86_got_modrm = 0;
29860339a1c2SMark Johnston 	x->d86_memsize = 0;
2987*b3b5bfebSMark Johnston 	x->d86_vsib = 0;
29880339a1c2SMark Johnston 
29890339a1c2SMark Johnston 	if (cpu_mode == SIZE16) {
29900339a1c2SMark Johnston 		opnd_size = SIZE16;
29910339a1c2SMark Johnston 		addr_size = SIZE16;
29920339a1c2SMark Johnston 	} else if (cpu_mode == SIZE32) {
29930339a1c2SMark Johnston 		opnd_size = SIZE32;
29940339a1c2SMark Johnston 		addr_size = SIZE32;
29950339a1c2SMark Johnston 	} else {
29960339a1c2SMark Johnston 		opnd_size = SIZE32;
29970339a1c2SMark Johnston 		addr_size = SIZE64;
29980339a1c2SMark Johnston 	}
29990339a1c2SMark Johnston 
30000339a1c2SMark Johnston 	/*
30010339a1c2SMark Johnston 	 * Get one opcode byte and check for zero padding that follows
30020339a1c2SMark Johnston 	 * jump tables.
30030339a1c2SMark Johnston 	 */
30040339a1c2SMark Johnston 	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
30050339a1c2SMark Johnston 		goto error;
30060339a1c2SMark Johnston 
30070339a1c2SMark Johnston 	if (opcode1 == 0 && opcode2 == 0 &&
30080339a1c2SMark Johnston 	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
30090339a1c2SMark Johnston #ifdef DIS_TEXT
30100339a1c2SMark Johnston 		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
30110339a1c2SMark Johnston #endif
30120339a1c2SMark Johnston 		goto done;
30130339a1c2SMark Johnston 	}
30140339a1c2SMark Johnston 
30150339a1c2SMark Johnston 	/*
30160339a1c2SMark Johnston 	 * Gather up legacy x86 prefix bytes.
30170339a1c2SMark Johnston 	 */
30180339a1c2SMark Johnston 	for (;;) {
30190339a1c2SMark Johnston 		uint_t *which_prefix = NULL;
30200339a1c2SMark Johnston 
30210339a1c2SMark Johnston 		dp = (instable_t *)&dis_distable[opcode1][opcode2];
30220339a1c2SMark Johnston 
30230339a1c2SMark Johnston 		switch (dp->it_adrmode) {
30240339a1c2SMark Johnston 		case PREFIX:
30250339a1c2SMark Johnston 			which_prefix = &rep_prefix;
30260339a1c2SMark Johnston 			break;
30270339a1c2SMark Johnston 		case LOCK:
30280339a1c2SMark Johnston 			which_prefix = &lock_prefix;
30290339a1c2SMark Johnston 			break;
30300339a1c2SMark Johnston 		case OVERRIDE:
30310339a1c2SMark Johnston 			which_prefix = &segment_prefix;
30320339a1c2SMark Johnston #ifdef DIS_TEXT
30330339a1c2SMark Johnston 			x->d86_seg_prefix = (char *)dp->it_name;
30340339a1c2SMark Johnston #endif
30350339a1c2SMark Johnston 			if (dp->it_invalid64 && cpu_mode == SIZE64)
30360339a1c2SMark Johnston 				goto error;
30370339a1c2SMark Johnston 			break;
30380339a1c2SMark Johnston 		case AM:
30390339a1c2SMark Johnston 			which_prefix = &addr_size_prefix;
30400339a1c2SMark Johnston 			break;
30410339a1c2SMark Johnston 		case DM:
30420339a1c2SMark Johnston 			which_prefix = &opnd_size_prefix;
30430339a1c2SMark Johnston 			break;
30440339a1c2SMark Johnston 		}
30450339a1c2SMark Johnston 		if (which_prefix == NULL)
30460339a1c2SMark Johnston 			break;
30470339a1c2SMark Johnston 		*which_prefix = (opcode1 << 4) | opcode2;
30480339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
30490339a1c2SMark Johnston 			goto error;
30500339a1c2SMark Johnston 	}
30510339a1c2SMark Johnston 
30520339a1c2SMark Johnston 	/*
30530339a1c2SMark Johnston 	 * Handle amd64 mode PREFIX values.
30540339a1c2SMark Johnston 	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
30550339a1c2SMark Johnston 	 * We might have a REX prefix (opcodes 0x40-0x4f)
30560339a1c2SMark Johnston 	 */
30570339a1c2SMark Johnston 	if (cpu_mode == SIZE64) {
30580339a1c2SMark Johnston 		if (segment_prefix != 0x64 && segment_prefix != 0x65)
30590339a1c2SMark Johnston 			segment_prefix = 0;
30600339a1c2SMark Johnston 
30610339a1c2SMark Johnston 		if (opcode1 == 0x4) {
30620339a1c2SMark Johnston 			rex_prefix = (opcode1 << 4) | opcode2;
30630339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
30640339a1c2SMark Johnston 				goto error;
30650339a1c2SMark Johnston 			dp = (instable_t *)&dis_distable[opcode1][opcode2];
30660339a1c2SMark Johnston 		} else if (opcode1 == 0xC &&
30670339a1c2SMark Johnston 		    (opcode2 == 0x4 || opcode2 == 0x5)) {
30680339a1c2SMark Johnston 			/* AVX instructions */
30690339a1c2SMark Johnston 			vex_prefix = (opcode1 << 4) | opcode2;
30700339a1c2SMark Johnston 			x->d86_rex_prefix = 0x40;
30710339a1c2SMark Johnston 		}
30720339a1c2SMark Johnston 	} else if (opcode1 == 0xC && (opcode2 == 0x4 || opcode2 == 0x5)) {
30730339a1c2SMark Johnston 		/* LDS, LES or AVX */
30740339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
30750339a1c2SMark Johnston 		vex_prefetch = 1;
30760339a1c2SMark Johnston 
30770339a1c2SMark Johnston 		if (mode == REG_ONLY) {
30780339a1c2SMark Johnston 			/* AVX */
30790339a1c2SMark Johnston 			vex_prefix = (opcode1 << 4) | opcode2;
30800339a1c2SMark Johnston 			x->d86_rex_prefix = 0x40;
30810339a1c2SMark Johnston 			opcode3 = (((mode << 3) | reg)>>1) & 0x0F;
30820339a1c2SMark Johnston 			opcode4 = ((reg << 3) | r_m) & 0x0F;
30830339a1c2SMark Johnston 		}
30840339a1c2SMark Johnston 	}
30850339a1c2SMark Johnston 
30860339a1c2SMark Johnston 	if (vex_prefix == VEX_2bytes) {
30870339a1c2SMark Johnston 		if (!vex_prefetch) {
30880339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
30890339a1c2SMark Johnston 				goto error;
30900339a1c2SMark Johnston 		}
30910339a1c2SMark Johnston 		vex_R = ((opcode3 & VEX_R) & 0x0F) >> 3;
30920339a1c2SMark Johnston 		vex_L = ((opcode4 & VEX_L) & 0x0F) >> 2;
30930339a1c2SMark Johnston 		vex_v = (((opcode3 << 4) | opcode4) & VEX_v) >> 3;
30940339a1c2SMark Johnston 		vex_p = opcode4 & VEX_p;
30950339a1c2SMark Johnston 		/*
30960339a1c2SMark Johnston 		 * The vex.x and vex.b bits are not defined in two bytes
30970339a1c2SMark Johnston 		 * mode vex prefix, their default values are 1
30980339a1c2SMark Johnston 		 */
30990339a1c2SMark Johnston 		vex_byte1 = (opcode3 & VEX_R) | VEX_X | VEX_B;
31000339a1c2SMark Johnston 
31010339a1c2SMark Johnston 		if (vex_R == 0)
31020339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_R;
31030339a1c2SMark Johnston 
31040339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
31050339a1c2SMark Johnston 			goto error;
31060339a1c2SMark Johnston 
31070339a1c2SMark Johnston 		switch (vex_p) {
31080339a1c2SMark Johnston 			case VEX_p_66:
31090339a1c2SMark Johnston 				dp = (instable_t *)
31100339a1c2SMark Johnston 				    &dis_opAVX660F[(opcode1 << 4) | opcode2];
31110339a1c2SMark Johnston 				break;
31120339a1c2SMark Johnston 			case VEX_p_F3:
31130339a1c2SMark Johnston 				dp = (instable_t *)
31140339a1c2SMark Johnston 				    &dis_opAVXF30F[(opcode1 << 4) | opcode2];
31150339a1c2SMark Johnston 				break;
31160339a1c2SMark Johnston 			case VEX_p_F2:
31170339a1c2SMark Johnston 				dp = (instable_t *)
31180339a1c2SMark Johnston 				    &dis_opAVXF20F [(opcode1 << 4) | opcode2];
31190339a1c2SMark Johnston 				break;
31200339a1c2SMark Johnston 			default:
31210339a1c2SMark Johnston 				dp = (instable_t *)
31220339a1c2SMark Johnston 				    &dis_opAVX0F[opcode1][opcode2];
31230339a1c2SMark Johnston 
31240339a1c2SMark Johnston 		}
31250339a1c2SMark Johnston 
31260339a1c2SMark Johnston 	} else if (vex_prefix == VEX_3bytes) {
31270339a1c2SMark Johnston 		if (!vex_prefetch) {
31280339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode3, &opcode4) != 0)
31290339a1c2SMark Johnston 				goto error;
31300339a1c2SMark Johnston 		}
31310339a1c2SMark Johnston 		vex_R = (opcode3 & VEX_R) >> 3;
31320339a1c2SMark Johnston 		vex_X = (opcode3 & VEX_X) >> 2;
31330339a1c2SMark Johnston 		vex_B = (opcode3 & VEX_B) >> 1;
31340339a1c2SMark Johnston 		vex_m = (((opcode3 << 4) | opcode4) & VEX_m);
31350339a1c2SMark Johnston 		vex_byte1 = opcode3 & (VEX_R | VEX_X | VEX_B);
31360339a1c2SMark Johnston 
31370339a1c2SMark Johnston 		if (vex_R == 0)
31380339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_R;
31390339a1c2SMark Johnston 		if (vex_X == 0)
31400339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_X;
31410339a1c2SMark Johnston 		if (vex_B == 0)
31420339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_B;
31430339a1c2SMark Johnston 
31440339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode5, &opcode6) != 0)
31450339a1c2SMark Johnston 			goto error;
31460339a1c2SMark Johnston 		vex_W = (opcode5 & VEX_W) >> 3;
31470339a1c2SMark Johnston 		vex_L = (opcode6 & VEX_L) >> 2;
31480339a1c2SMark Johnston 		vex_v = (((opcode5 << 4) | opcode6) & VEX_v) >> 3;
31490339a1c2SMark Johnston 		vex_p = opcode6 & VEX_p;
31500339a1c2SMark Johnston 
31510339a1c2SMark Johnston 		if (vex_W)
31520339a1c2SMark Johnston 			x->d86_rex_prefix |= REX_W;
31530339a1c2SMark Johnston 
31540339a1c2SMark Johnston 		/* Only these three vex_m values valid; others are reserved */
31550339a1c2SMark Johnston 		if ((vex_m != VEX_m_0F) && (vex_m != VEX_m_0F38) &&
31560339a1c2SMark Johnston 		    (vex_m != VEX_m_0F3A))
31570339a1c2SMark Johnston 			goto error;
31580339a1c2SMark Johnston 
31590339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
31600339a1c2SMark Johnston 			goto error;
31610339a1c2SMark Johnston 
31620339a1c2SMark Johnston 		switch (vex_p) {
31630339a1c2SMark Johnston 			case VEX_p_66:
31640339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
31650339a1c2SMark Johnston 					dp = (instable_t *)
31660339a1c2SMark Johnston 					    &dis_opAVX660F
31670339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
31680339a1c2SMark Johnston 				} else if (vex_m == VEX_m_0F38) {
31690339a1c2SMark Johnston 					dp = (instable_t *)
31700339a1c2SMark Johnston 					    &dis_opAVX660F38
31710339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
31720339a1c2SMark Johnston 				} else if (vex_m == VEX_m_0F3A) {
31730339a1c2SMark Johnston 					dp = (instable_t *)
31740339a1c2SMark Johnston 					    &dis_opAVX660F3A
31750339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
31760339a1c2SMark Johnston 				} else {
31770339a1c2SMark Johnston 					goto error;
31780339a1c2SMark Johnston 				}
31790339a1c2SMark Johnston 				break;
31800339a1c2SMark Johnston 			case VEX_p_F3:
31810339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
31820339a1c2SMark Johnston 					dp = (instable_t *)
31830339a1c2SMark Johnston 					    &dis_opAVXF30F
31840339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
3185*b3b5bfebSMark Johnston 				} else if (vex_m == VEX_m_0F38) {
3186*b3b5bfebSMark Johnston 					dp = (instable_t *)
3187*b3b5bfebSMark Johnston 					    &dis_opAVXF30F38
3188*b3b5bfebSMark Johnston 					    [(opcode1 << 4) | opcode2];
31890339a1c2SMark Johnston 				} else {
31900339a1c2SMark Johnston 					goto error;
31910339a1c2SMark Johnston 				}
31920339a1c2SMark Johnston 				break;
31930339a1c2SMark Johnston 			case VEX_p_F2:
31940339a1c2SMark Johnston 				if (vex_m == VEX_m_0F) {
31950339a1c2SMark Johnston 					dp = (instable_t *)
31960339a1c2SMark Johnston 					    &dis_opAVXF20F
31970339a1c2SMark Johnston 					    [(opcode1 << 4) | opcode2];
3198*b3b5bfebSMark Johnston 				} else if (vex_m == VEX_m_0F3A) {
3199*b3b5bfebSMark Johnston 					dp = (instable_t *)
3200*b3b5bfebSMark Johnston 					    &dis_opAVXF20F3A
3201*b3b5bfebSMark Johnston 					    [(opcode1 << 4) | opcode2];
3202*b3b5bfebSMark Johnston 				} else if (vex_m == VEX_m_0F38) {
3203*b3b5bfebSMark Johnston 					dp = (instable_t *)
3204*b3b5bfebSMark Johnston 					    &dis_opAVXF20F38
3205*b3b5bfebSMark Johnston 					    [(opcode1 << 4) | opcode2];
32060339a1c2SMark Johnston 				} else {
32070339a1c2SMark Johnston 					goto error;
32080339a1c2SMark Johnston 				}
32090339a1c2SMark Johnston 				break;
32100339a1c2SMark Johnston 			default:
32110339a1c2SMark Johnston 				dp = (instable_t *)
32120339a1c2SMark Johnston 				    &dis_opAVX0F[opcode1][opcode2];
32130339a1c2SMark Johnston 
32140339a1c2SMark Johnston 		}
32150339a1c2SMark Johnston 	}
32160339a1c2SMark Johnston 	if (vex_prefix) {
3217*b3b5bfebSMark Johnston 		if (dp->it_vexwoxmm) {
3218*b3b5bfebSMark Johnston 			wbit = LONG_OPND;
3219*b3b5bfebSMark Johnston 		} else {
32200339a1c2SMark Johnston 			if (vex_L)
32210339a1c2SMark Johnston 				wbit = YMM_OPND;
32220339a1c2SMark Johnston 			else
32230339a1c2SMark Johnston 				wbit = XMM_OPND;
32240339a1c2SMark Johnston 		}
3225*b3b5bfebSMark Johnston 	}
32260339a1c2SMark Johnston 
32270339a1c2SMark Johnston 	/*
32280339a1c2SMark Johnston 	 * Deal with selection of operand and address size now.
32290339a1c2SMark Johnston 	 * Note that the REX.W bit being set causes opnd_size_prefix to be
32300339a1c2SMark Johnston 	 * ignored.
32310339a1c2SMark Johnston 	 */
32320339a1c2SMark Johnston 	if (cpu_mode == SIZE64) {
32330339a1c2SMark Johnston 		if ((rex_prefix & REX_W) || vex_W)
32340339a1c2SMark Johnston 			opnd_size = SIZE64;
32350339a1c2SMark Johnston 		else if (opnd_size_prefix)
32360339a1c2SMark Johnston 			opnd_size = SIZE16;
32370339a1c2SMark Johnston 
32380339a1c2SMark Johnston 		if (addr_size_prefix)
32390339a1c2SMark Johnston 			addr_size = SIZE32;
32400339a1c2SMark Johnston 	} else if (cpu_mode == SIZE32) {
32410339a1c2SMark Johnston 		if (opnd_size_prefix)
32420339a1c2SMark Johnston 			opnd_size = SIZE16;
32430339a1c2SMark Johnston 		if (addr_size_prefix)
32440339a1c2SMark Johnston 			addr_size = SIZE16;
32450339a1c2SMark Johnston 	} else {
32460339a1c2SMark Johnston 		if (opnd_size_prefix)
32470339a1c2SMark Johnston 			opnd_size = SIZE32;
32480339a1c2SMark Johnston 		if (addr_size_prefix)
32490339a1c2SMark Johnston 			addr_size = SIZE32;
32500339a1c2SMark Johnston 	}
32510339a1c2SMark Johnston 	/*
32520339a1c2SMark Johnston 	 * The pause instruction - a repz'd nop.  This doesn't fit
32530339a1c2SMark Johnston 	 * with any of the other prefix goop added for SSE, so we'll
32540339a1c2SMark Johnston 	 * special-case it here.
32550339a1c2SMark Johnston 	 */
32560339a1c2SMark Johnston 	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
32570339a1c2SMark Johnston 		rep_prefix = 0;
32580339a1c2SMark Johnston 		dp = (instable_t *)&dis_opPause;
32590339a1c2SMark Johnston 	}
32600339a1c2SMark Johnston 
32610339a1c2SMark Johnston 	/*
32620339a1c2SMark Johnston 	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
32630339a1c2SMark Johnston 	 * byte so we may need to perform a table indirection.
32640339a1c2SMark Johnston 	 */
32650339a1c2SMark Johnston 	if (dp->it_indirect == (instable_t *)dis_op0F) {
32660339a1c2SMark Johnston 		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
32670339a1c2SMark Johnston 			goto error;
32680339a1c2SMark Johnston 		opcode_bytes = 2;
32690339a1c2SMark Johnston 		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
32700339a1c2SMark Johnston 			uint_t	subcode;
32710339a1c2SMark Johnston 
32720339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
32730339a1c2SMark Johnston 				goto error;
32740339a1c2SMark Johnston 			opcode_bytes = 3;
32750339a1c2SMark Johnston 			subcode = ((opcode6 & 0x3) << 1) |
32760339a1c2SMark Johnston 			    ((opcode7 & 0x8) >> 3);
32770339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
32780339a1c2SMark Johnston 		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
32790339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0FC8[0];
32800339a1c2SMark Johnston 		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
32810339a1c2SMark Johnston 			opcode_bytes = 3;
32820339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
32830339a1c2SMark Johnston 				goto error;
32840339a1c2SMark Johnston 			if (opnd_size == SIZE16)
32850339a1c2SMark Johnston 				opnd_size = SIZE32;
32860339a1c2SMark Johnston 
32870339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
32880339a1c2SMark Johnston #ifdef DIS_TEXT
32890339a1c2SMark Johnston 			if (strcmp(dp->it_name, "INVALID") == 0)
32900339a1c2SMark Johnston 				goto error;
32910339a1c2SMark Johnston #endif
32920339a1c2SMark Johnston 			switch (dp->it_adrmode) {
3293*b3b5bfebSMark Johnston 				case XMMP:
3294*b3b5bfebSMark Johnston 					break;
32950339a1c2SMark Johnston 				case XMMP_66r:
32960339a1c2SMark Johnston 				case XMMPRM_66r:
32970339a1c2SMark Johnston 				case XMM3PM_66r:
32980339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
32990339a1c2SMark Johnston 						goto error;
33000339a1c2SMark Johnston 					}
33010339a1c2SMark Johnston 					break;
33020339a1c2SMark Johnston 				case XMMP_66o:
33030339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
33040339a1c2SMark Johnston 						/* SSSE3 MMX instructions */
33050339a1c2SMark Johnston 						dp_mmx = *dp;
33060339a1c2SMark Johnston 						dp = &dp_mmx;
33070339a1c2SMark Johnston 						dp->it_adrmode = MMOPM_66o;
33080339a1c2SMark Johnston #ifdef	DIS_MEM
33090339a1c2SMark Johnston 						dp->it_size = 8;
33100339a1c2SMark Johnston #endif
33110339a1c2SMark Johnston 					}
33120339a1c2SMark Johnston 					break;
33130339a1c2SMark Johnston 				default:
33140339a1c2SMark Johnston 					goto error;
33150339a1c2SMark Johnston 			}
33160339a1c2SMark Johnston 		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
33170339a1c2SMark Johnston 			opcode_bytes = 3;
33180339a1c2SMark Johnston 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
33190339a1c2SMark Johnston 				goto error;
33200339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
33210339a1c2SMark Johnston 
33220339a1c2SMark Johnston 			/*
33230339a1c2SMark Johnston 			 * Both crc32 and movbe have the same 3rd opcode
33240339a1c2SMark Johnston 			 * byte of either 0xF0 or 0xF1, so we use another
33250339a1c2SMark Johnston 			 * indirection to distinguish between the two.
33260339a1c2SMark Johnston 			 */
33270339a1c2SMark Johnston 			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
33280339a1c2SMark Johnston 			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
33290339a1c2SMark Johnston 
33300339a1c2SMark Johnston 				dp = dp->it_indirect;
33310339a1c2SMark Johnston 				if (rep_prefix != 0xF2) {
33320339a1c2SMark Johnston 					/* It is movbe */
33330339a1c2SMark Johnston 					dp++;
33340339a1c2SMark Johnston 				}
33350339a1c2SMark Johnston 			}
3336*b3b5bfebSMark Johnston 
3337*b3b5bfebSMark Johnston 			/*
3338*b3b5bfebSMark Johnston 			 * The adx family of instructions (adcx and adox)
3339*b3b5bfebSMark Johnston 			 * continue the classic Intel tradition of abusing
3340*b3b5bfebSMark Johnston 			 * arbitrary prefixes without actually meaning the
3341*b3b5bfebSMark Johnston 			 * prefix bit. Therefore, if we find either the
3342*b3b5bfebSMark Johnston 			 * opnd_size_prefix or rep_prefix we end up zeroing it
3343*b3b5bfebSMark Johnston 			 * out after making our determination so as to ensure
3344*b3b5bfebSMark Johnston 			 * that we don't get confused and accidentally print
3345*b3b5bfebSMark Johnston 			 * repz prefixes and the like on these instructions.
3346*b3b5bfebSMark Johnston 			 *
3347*b3b5bfebSMark Johnston 			 * In addition, these instructions are actually much
3348*b3b5bfebSMark Johnston 			 * closer to AVX instructions in semantics. Importantly,
3349*b3b5bfebSMark Johnston 			 * they always default to having 32-bit operands.
3350*b3b5bfebSMark Johnston 			 * However, if the CPU is in 64-bit mode, then and only
3351*b3b5bfebSMark Johnston 			 * then, does it use REX.w promotes things to 64-bits
3352*b3b5bfebSMark Johnston 			 * and REX.r allows 64-bit mode to use register r8-r15.
3353*b3b5bfebSMark Johnston 			 */
3354*b3b5bfebSMark Johnston 			if (dp->it_indirect == (instable_t *)dis_op0F38F6) {
3355*b3b5bfebSMark Johnston 				dp = dp->it_indirect;
3356*b3b5bfebSMark Johnston 				if (opnd_size_prefix == 0 &&
3357*b3b5bfebSMark Johnston 				    rep_prefix == 0xf3) {
3358*b3b5bfebSMark Johnston 					/* It is adox */
3359*b3b5bfebSMark Johnston 					dp++;
3360*b3b5bfebSMark Johnston 				} else if (opnd_size_prefix != 0x66 &&
3361*b3b5bfebSMark Johnston 				    rep_prefix != 0) {
3362*b3b5bfebSMark Johnston 					/* It isn't adcx */
3363*b3b5bfebSMark Johnston 					goto error;
3364*b3b5bfebSMark Johnston 				}
3365*b3b5bfebSMark Johnston 				opnd_size_prefix = 0;
3366*b3b5bfebSMark Johnston 				rep_prefix = 0;
3367*b3b5bfebSMark Johnston 				opnd_size = SIZE32;
3368*b3b5bfebSMark Johnston 				if (rex_prefix & REX_W)
3369*b3b5bfebSMark Johnston 					opnd_size = SIZE64;
3370*b3b5bfebSMark Johnston 			}
3371*b3b5bfebSMark Johnston 
33720339a1c2SMark Johnston #ifdef DIS_TEXT
33730339a1c2SMark Johnston 			if (strcmp(dp->it_name, "INVALID") == 0)
33740339a1c2SMark Johnston 				goto error;
33750339a1c2SMark Johnston #endif
33760339a1c2SMark Johnston 			switch (dp->it_adrmode) {
3377*b3b5bfebSMark Johnston 				case ADX:
3378*b3b5bfebSMark Johnston 				case XMM:
3379*b3b5bfebSMark Johnston 					break;
3380c3ddb60eSPeter Grehan 				case RM_66r:
33810339a1c2SMark Johnston 				case XMM_66r:
33820339a1c2SMark Johnston 				case XMMM_66r:
33830339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
33840339a1c2SMark Johnston 						goto error;
33850339a1c2SMark Johnston 					}
33860339a1c2SMark Johnston 					break;
33870339a1c2SMark Johnston 				case XMM_66o:
33880339a1c2SMark Johnston 					if (opnd_size_prefix == 0) {
33890339a1c2SMark Johnston 						/* SSSE3 MMX instructions */
33900339a1c2SMark Johnston 						dp_mmx = *dp;
33910339a1c2SMark Johnston 						dp = &dp_mmx;
33920339a1c2SMark Johnston 						dp->it_adrmode = MM;
33930339a1c2SMark Johnston #ifdef	DIS_MEM
33940339a1c2SMark Johnston 						dp->it_size = 8;
33950339a1c2SMark Johnston #endif
33960339a1c2SMark Johnston 					}
33970339a1c2SMark Johnston 					break;
33980339a1c2SMark Johnston 				case CRC32:
33990339a1c2SMark Johnston 					if (rep_prefix != 0xF2) {
34000339a1c2SMark Johnston 						goto error;
34010339a1c2SMark Johnston 					}
34020339a1c2SMark Johnston 					rep_prefix = 0;
34030339a1c2SMark Johnston 					break;
34040339a1c2SMark Johnston 				case MOVBE:
34050339a1c2SMark Johnston 					if (rep_prefix != 0x0) {
34060339a1c2SMark Johnston 						goto error;
34070339a1c2SMark Johnston 					}
34080339a1c2SMark Johnston 					break;
34090339a1c2SMark Johnston 				default:
34100339a1c2SMark Johnston 					goto error;
34110339a1c2SMark Johnston 			}
34120339a1c2SMark Johnston 		} else {
34130339a1c2SMark Johnston 			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
34140339a1c2SMark Johnston 		}
34150339a1c2SMark Johnston 	}
34160339a1c2SMark Johnston 
34170339a1c2SMark Johnston 	/*
34180339a1c2SMark Johnston 	 * If still not at a TERM decode entry, then a ModRM byte
34190339a1c2SMark Johnston 	 * exists and its fields further decode the instruction.
34200339a1c2SMark Johnston 	 */
34210339a1c2SMark Johnston 	x->d86_got_modrm = 0;
34220339a1c2SMark Johnston 	if (dp->it_indirect != TERM) {
34230339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
34240339a1c2SMark Johnston 		if (x->d86_error)
34250339a1c2SMark Johnston 			goto error;
34260339a1c2SMark Johnston 		reg = opcode3;
34270339a1c2SMark Johnston 
34280339a1c2SMark Johnston 		/*
34290339a1c2SMark Johnston 		 * decode 287 instructions (D8-DF) from opcodeN
34300339a1c2SMark Johnston 		 */
34310339a1c2SMark Johnston 		if (opcode1 == 0xD && opcode2 >= 0x8) {
34320339a1c2SMark Johnston 			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
34330339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP5[r_m];
34340339a1c2SMark Johnston 			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
34350339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP7[opcode3];
34360339a1c2SMark Johnston 			else if (opcode2 == 0xB && mode == 0x3)
34370339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP6[opcode3];
34380339a1c2SMark Johnston 			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
34390339a1c2SMark Johnston 				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
34400339a1c2SMark Johnston 			else if (mode == 0x3)
34410339a1c2SMark Johnston 				dp = (instable_t *)
34420339a1c2SMark Johnston 				    &dis_opFP3[opcode2 - 8][opcode3];
34430339a1c2SMark Johnston 			else
34440339a1c2SMark Johnston 				dp = (instable_t *)
34450339a1c2SMark Johnston 				    &dis_opFP1n2[opcode2 - 8][opcode3];
34460339a1c2SMark Johnston 		} else {
34470339a1c2SMark Johnston 			dp = (instable_t *)dp->it_indirect + opcode3;
34480339a1c2SMark Johnston 		}
34490339a1c2SMark Johnston 	}
34500339a1c2SMark Johnston 
34510339a1c2SMark Johnston 	/*
34520339a1c2SMark Johnston 	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
34530339a1c2SMark Johnston 	 * (sign extend 32bit to 64 bit)
34540339a1c2SMark Johnston 	 */
34550339a1c2SMark Johnston 	if ((vex_prefix == 0) && cpu_mode == SIZE64 &&
34560339a1c2SMark Johnston 	    opcode1 == 0x6 && opcode2 == 0x3)
34570339a1c2SMark Johnston 		dp = (instable_t *)&dis_opMOVSLD;
34580339a1c2SMark Johnston 
34590339a1c2SMark Johnston 	/*
34600339a1c2SMark Johnston 	 * at this point we should have a correct (or invalid) opcode
34610339a1c2SMark Johnston 	 */
34620339a1c2SMark Johnston 	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
34630339a1c2SMark Johnston 	    cpu_mode != SIZE64 && dp->it_invalid32)
34640339a1c2SMark Johnston 		goto error;
34650339a1c2SMark Johnston 	if (dp->it_indirect != TERM)
34660339a1c2SMark Johnston 		goto error;
34670339a1c2SMark Johnston 
34680339a1c2SMark Johnston 	/*
3469*b3b5bfebSMark Johnston 	 * Deal with MMX/SSE opcodes which are changed by prefixes. Note, we do
3470*b3b5bfebSMark Johnston 	 * need to include UNKNOWN below, as we may have instructions that
3471*b3b5bfebSMark Johnston 	 * actually have a prefix, but don't exist in any other form.
34720339a1c2SMark Johnston 	 */
34730339a1c2SMark Johnston 	switch (dp->it_adrmode) {
3474*b3b5bfebSMark Johnston 	case UNKNOWN:
34750339a1c2SMark Johnston 	case MMO:
34760339a1c2SMark Johnston 	case MMOIMPL:
34770339a1c2SMark Johnston 	case MMO3P:
34780339a1c2SMark Johnston 	case MMOM3:
34790339a1c2SMark Johnston 	case MMOMS:
34800339a1c2SMark Johnston 	case MMOPM:
34810339a1c2SMark Johnston 	case MMOPRM:
34820339a1c2SMark Johnston 	case MMOS:
34830339a1c2SMark Johnston 	case XMMO:
34840339a1c2SMark Johnston 	case XMMOM:
34850339a1c2SMark Johnston 	case XMMOMS:
34860339a1c2SMark Johnston 	case XMMOPM:
34870339a1c2SMark Johnston 	case XMMOS:
34880339a1c2SMark Johnston 	case XMMOMX:
34890339a1c2SMark Johnston 	case XMMOX3:
34900339a1c2SMark Johnston 	case XMMOXMM:
34910339a1c2SMark Johnston 		/*
34920339a1c2SMark Johnston 		 * This is horrible.  Some SIMD instructions take the
34930339a1c2SMark Johnston 		 * form 0x0F 0x?? ..., which is easily decoded using the
34940339a1c2SMark Johnston 		 * existing tables.  Other SIMD instructions use various
34950339a1c2SMark Johnston 		 * prefix bytes to overload existing instructions.  For
34960339a1c2SMark Johnston 		 * Example, addps is F0, 58, whereas addss is F3 (repz),
34970339a1c2SMark Johnston 		 * F0, 58.  Presumably someone got a raise for this.
34980339a1c2SMark Johnston 		 *
34990339a1c2SMark Johnston 		 * If we see one of the instructions which can be
35000339a1c2SMark Johnston 		 * modified in this way (if we've got one of the SIMDO*
35010339a1c2SMark Johnston 		 * address modes), we'll check to see if the last prefix
35020339a1c2SMark Johnston 		 * was a repz.  If it was, we strip the prefix from the
35030339a1c2SMark Johnston 		 * mnemonic, and we indirect using the dis_opSIMDrepz
35040339a1c2SMark Johnston 		 * table.
35050339a1c2SMark Johnston 		 */
35060339a1c2SMark Johnston 
35070339a1c2SMark Johnston 		/*
35080339a1c2SMark Johnston 		 * Calculate our offset in dis_op0F
35090339a1c2SMark Johnston 		 */
35100339a1c2SMark Johnston 		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
35110339a1c2SMark Johnston 			goto error;
35120339a1c2SMark Johnston 
35130339a1c2SMark Johnston 		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
35140339a1c2SMark Johnston 		    sizeof (instable_t);
35150339a1c2SMark Johnston 
35160339a1c2SMark Johnston 		/*
35170339a1c2SMark Johnston 		 * Rewrite if this instruction used one of the magic prefixes.
35180339a1c2SMark Johnston 		 */
35190339a1c2SMark Johnston 		if (rep_prefix) {
35200339a1c2SMark Johnston 			if (rep_prefix == 0xf2)
35210339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepnz[off];
35220339a1c2SMark Johnston 			else
35230339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepz[off];
35240339a1c2SMark Johnston 			rep_prefix = 0;
35250339a1c2SMark Johnston 		} else if (opnd_size_prefix) {
35260339a1c2SMark Johnston 			dp = (instable_t *)&dis_opSIMDdata16[off];
35270339a1c2SMark Johnston 			opnd_size_prefix = 0;
35280339a1c2SMark Johnston 			if (opnd_size == SIZE16)
35290339a1c2SMark Johnston 				opnd_size = SIZE32;
35300339a1c2SMark Johnston 		}
35310339a1c2SMark Johnston 		break;
35320339a1c2SMark Johnston 
3533c3ddb60eSPeter Grehan 	case MG9:
3534c3ddb60eSPeter Grehan 		/*
3535c3ddb60eSPeter Grehan 		 * More horribleness: the group 9 (0xF0 0xC7) instructions are
3536c3ddb60eSPeter Grehan 		 * allowed an optional prefix of 0x66 or 0xF3.  This is similar
3537c3ddb60eSPeter Grehan 		 * to the SIMD business described above, but with a different
3538c3ddb60eSPeter Grehan 		 * addressing mode (and an indirect table), so we deal with it
3539c3ddb60eSPeter Grehan 		 * separately (if similarly).
3540c3ddb60eSPeter Grehan 		 *
3541c3ddb60eSPeter Grehan 		 * Intel further complicated this with the release of Ivy Bridge
3542c3ddb60eSPeter Grehan 		 * where they overloaded these instructions based on the ModR/M
3543c3ddb60eSPeter Grehan 		 * bytes. The VMX instructions have a mode of 0 since they are
3544c3ddb60eSPeter Grehan 		 * memory instructions but rdrand instructions have a mode of
3545c3ddb60eSPeter Grehan 		 * 0b11 (REG_ONLY) because they only operate on registers. While
3546c3ddb60eSPeter Grehan 		 * there are different prefix formats, for now it is sufficient
3547c3ddb60eSPeter Grehan 		 * to use a single different table.
3548c3ddb60eSPeter Grehan 		 */
3549c3ddb60eSPeter Grehan 
3550c3ddb60eSPeter Grehan 		/*
3551c3ddb60eSPeter Grehan 		 * Calculate our offset in dis_op0FC7 (the group 9 table)
3552c3ddb60eSPeter Grehan 		 */
3553c3ddb60eSPeter Grehan 		if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
3554c3ddb60eSPeter Grehan 			goto error;
3555c3ddb60eSPeter Grehan 
3556c3ddb60eSPeter Grehan 		off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
3557c3ddb60eSPeter Grehan 		    sizeof (instable_t);
3558c3ddb60eSPeter Grehan 
3559c3ddb60eSPeter Grehan 		/*
3560c3ddb60eSPeter Grehan 		 * If we have a mode of 0b11 then we have to rewrite this.
3561c3ddb60eSPeter Grehan 		 */
3562c3ddb60eSPeter Grehan 		dtrace_get_modrm(x, &mode, &reg, &r_m);
3563c3ddb60eSPeter Grehan 		if (mode == REG_ONLY) {
3564c3ddb60eSPeter Grehan 			dp = (instable_t *)&dis_op0FC7m3[off];
3565c3ddb60eSPeter Grehan 			break;
3566c3ddb60eSPeter Grehan 		}
3567c3ddb60eSPeter Grehan 
3568c3ddb60eSPeter Grehan 		/*
3569c3ddb60eSPeter Grehan 		 * Rewrite if this instruction used one of the magic prefixes.
3570c3ddb60eSPeter Grehan 		 */
3571c3ddb60eSPeter Grehan 		if (rep_prefix) {
3572c3ddb60eSPeter Grehan 			if (rep_prefix == 0xf3)
3573c3ddb60eSPeter Grehan 				dp = (instable_t *)&dis_opF30FC7[off];
3574c3ddb60eSPeter Grehan 			else
3575c3ddb60eSPeter Grehan 				goto error;
3576c3ddb60eSPeter Grehan 			rep_prefix = 0;
3577c3ddb60eSPeter Grehan 		} else if (opnd_size_prefix) {
3578c3ddb60eSPeter Grehan 			dp = (instable_t *)&dis_op660FC7[off];
3579c3ddb60eSPeter Grehan 			opnd_size_prefix = 0;
3580c3ddb60eSPeter Grehan 			if (opnd_size == SIZE16)
3581c3ddb60eSPeter Grehan 				opnd_size = SIZE32;
3582c3ddb60eSPeter Grehan 		}
3583c3ddb60eSPeter Grehan 		break;
3584c3ddb60eSPeter Grehan 
3585c3ddb60eSPeter Grehan 
35860339a1c2SMark Johnston 	case MMOSH:
35870339a1c2SMark Johnston 		/*
35880339a1c2SMark Johnston 		 * As with the "normal" SIMD instructions, the MMX
35890339a1c2SMark Johnston 		 * shuffle instructions are overloaded.  These
35900339a1c2SMark Johnston 		 * instructions, however, are special in that they use
35910339a1c2SMark Johnston 		 * an extra byte, and thus an extra table.  As of this
35920339a1c2SMark Johnston 		 * writing, they only use the opnd_size prefix.
35930339a1c2SMark Johnston 		 */
35940339a1c2SMark Johnston 
35950339a1c2SMark Johnston 		/*
35960339a1c2SMark Johnston 		 * Calculate our offset in dis_op0F7123
35970339a1c2SMark Johnston 		 */
35980339a1c2SMark Johnston 		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
35990339a1c2SMark Johnston 		    sizeof (dis_op0F7123))
36000339a1c2SMark Johnston 			goto error;
36010339a1c2SMark Johnston 
36020339a1c2SMark Johnston 		if (opnd_size_prefix) {
36030339a1c2SMark Johnston 			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
36040339a1c2SMark Johnston 			    sizeof (instable_t);
36050339a1c2SMark Johnston 			dp = (instable_t *)&dis_opSIMD7123[off];
36060339a1c2SMark Johnston 			opnd_size_prefix = 0;
36070339a1c2SMark Johnston 			if (opnd_size == SIZE16)
36080339a1c2SMark Johnston 				opnd_size = SIZE32;
36090339a1c2SMark Johnston 		}
36100339a1c2SMark Johnston 		break;
36110339a1c2SMark Johnston 	case MRw:
36120339a1c2SMark Johnston 		if (rep_prefix) {
36130339a1c2SMark Johnston 			if (rep_prefix == 0xf3) {
36140339a1c2SMark Johnston 
36150339a1c2SMark Johnston 				/*
36160339a1c2SMark Johnston 				 * Calculate our offset in dis_op0F
36170339a1c2SMark Johnston 				 */
36180339a1c2SMark Johnston 				if ((uintptr_t)dp - (uintptr_t)dis_op0F
36190339a1c2SMark Johnston 				    > sizeof (dis_op0F))
36200339a1c2SMark Johnston 					goto error;
36210339a1c2SMark Johnston 
36220339a1c2SMark Johnston 				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
36230339a1c2SMark Johnston 				    sizeof (instable_t);
36240339a1c2SMark Johnston 
36250339a1c2SMark Johnston 				dp = (instable_t *)&dis_opSIMDrepz[off];
36260339a1c2SMark Johnston 				rep_prefix = 0;
36270339a1c2SMark Johnston 			} else {
36280339a1c2SMark Johnston 				goto error;
36290339a1c2SMark Johnston 			}
36300339a1c2SMark Johnston 		}
36310339a1c2SMark Johnston 		break;
36320339a1c2SMark Johnston 	}
36330339a1c2SMark Johnston 
36340339a1c2SMark Johnston 	/*
36350339a1c2SMark Johnston 	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
36360339a1c2SMark Johnston 	 */
36370339a1c2SMark Johnston 	if (cpu_mode == SIZE64)
36380339a1c2SMark Johnston 		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
36390339a1c2SMark Johnston 			opnd_size = SIZE64;
36400339a1c2SMark Johnston 
36410339a1c2SMark Johnston #ifdef DIS_TEXT
36420339a1c2SMark Johnston 	/*
36430339a1c2SMark Johnston 	 * At this point most instructions can format the opcode mnemonic
36440339a1c2SMark Johnston 	 * including the prefixes.
36450339a1c2SMark Johnston 	 */
36460339a1c2SMark Johnston 	if (lock_prefix)
36470339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
36480339a1c2SMark Johnston 
36490339a1c2SMark Johnston 	if (rep_prefix == 0xf2)
36500339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
36510339a1c2SMark Johnston 	else if (rep_prefix == 0xf3)
36520339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
36530339a1c2SMark Johnston 
36540339a1c2SMark Johnston 	if (cpu_mode == SIZE64 && addr_size_prefix)
36550339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
36560339a1c2SMark Johnston 
36570339a1c2SMark Johnston 	if (dp->it_adrmode != CBW &&
36580339a1c2SMark Johnston 	    dp->it_adrmode != CWD &&
36590339a1c2SMark Johnston 	    dp->it_adrmode != XMMSFNC) {
36600339a1c2SMark Johnston 		if (strcmp(dp->it_name, "INVALID") == 0)
36610339a1c2SMark Johnston 			goto error;
36620339a1c2SMark Johnston 		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
3663*b3b5bfebSMark Johnston 		if (dp->it_avxsuf && dp->it_suffix) {
3664*b3b5bfebSMark Johnston 			(void) strlcat(x->d86_mnem, vex_W != 0 ? "q" : "d",
3665*b3b5bfebSMark Johnston 			    OPLEN);
3666*b3b5bfebSMark Johnston 		} else if (dp->it_suffix) {
36670339a1c2SMark Johnston 			char *types[] = {"", "w", "l", "q"};
36680339a1c2SMark Johnston 			if (opcode_bytes == 2 && opcode4 == 4) {
36690339a1c2SMark Johnston 				/* It's a cmovx.yy. Replace the suffix x */
36700339a1c2SMark Johnston 				for (i = 5; i < OPLEN; i++) {
36710339a1c2SMark Johnston 					if (x->d86_mnem[i] == '.')
36720339a1c2SMark Johnston 						break;
36730339a1c2SMark Johnston 				}
36740339a1c2SMark Johnston 				x->d86_mnem[i - 1] = *types[opnd_size];
36750339a1c2SMark Johnston 			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
36760339a1c2SMark Johnston 			    ((opcode6 == 1 && opcode7 == 6) ||
36770339a1c2SMark Johnston 			    (opcode6 == 2 && opcode7 == 2))) {
36780339a1c2SMark Johnston 				/*
36790339a1c2SMark Johnston 				 * To handle PINSRD and PEXTRD
36800339a1c2SMark Johnston 				 */
36810339a1c2SMark Johnston 				(void) strlcat(x->d86_mnem, "d", OPLEN);
36820339a1c2SMark Johnston 			} else {
36830339a1c2SMark Johnston 				(void) strlcat(x->d86_mnem, types[opnd_size],
36840339a1c2SMark Johnston 				    OPLEN);
36850339a1c2SMark Johnston 			}
36860339a1c2SMark Johnston 		}
36870339a1c2SMark Johnston 	}
36880339a1c2SMark Johnston #endif
36890339a1c2SMark Johnston 
36900339a1c2SMark Johnston 	/*
36910339a1c2SMark Johnston 	 * Process operands based on the addressing modes.
36920339a1c2SMark Johnston 	 */
36930339a1c2SMark Johnston 	x->d86_mode = cpu_mode;
36940339a1c2SMark Johnston 	/*
36950339a1c2SMark Johnston 	 * In vex mode the rex_prefix has no meaning
36960339a1c2SMark Johnston 	 */
36970339a1c2SMark Johnston 	if (!vex_prefix)
36980339a1c2SMark Johnston 		x->d86_rex_prefix = rex_prefix;
36990339a1c2SMark Johnston 	x->d86_opnd_size = opnd_size;
37000339a1c2SMark Johnston 	x->d86_addr_size = addr_size;
37010339a1c2SMark Johnston 	vbit = 0;		/* initialize for mem/reg -> reg */
37020339a1c2SMark Johnston 	switch (dp->it_adrmode) {
37030339a1c2SMark Johnston 		/*
37040339a1c2SMark Johnston 		 * amd64 instruction to sign extend 32 bit reg/mem operands
37050339a1c2SMark Johnston 		 * into 64 bit register values
37060339a1c2SMark Johnston 		 */
37070339a1c2SMark Johnston 	case MOVSXZ:
37080339a1c2SMark Johnston #ifdef DIS_TEXT
37090339a1c2SMark Johnston 		if (rex_prefix == 0)
37100339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
37110339a1c2SMark Johnston #endif
37120339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37130339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37140339a1c2SMark Johnston 		x->d86_opnd_size = SIZE64;
37150339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
37160339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size = SIZE32;
37170339a1c2SMark Johnston 		wbit = LONG_OPND;
37180339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
37190339a1c2SMark Johnston 		break;
37200339a1c2SMark Johnston 
37210339a1c2SMark Johnston 		/*
37220339a1c2SMark Johnston 		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
37230339a1c2SMark Johnston 		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
37240339a1c2SMark Johnston 		 * wbit lives in 2nd byte, note that operands
37250339a1c2SMark Johnston 		 * are different sized
37260339a1c2SMark Johnston 		 */
37270339a1c2SMark Johnston 	case MOVZ:
37280339a1c2SMark Johnston 		if (rex_prefix & REX_W) {
37290339a1c2SMark Johnston 			/* target register size = 64 bit */
37300339a1c2SMark Johnston 			x->d86_mnem[5] = 'q';
37310339a1c2SMark Johnston 		}
37320339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37330339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37340339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
37350339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size = SIZE16;
37360339a1c2SMark Johnston 		wbit = WBIT(opcode5);
37370339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
37380339a1c2SMark Johnston 		break;
37390339a1c2SMark Johnston 	case CRC32:
37400339a1c2SMark Johnston 		opnd_size = SIZE32;
37410339a1c2SMark Johnston 		if (rex_prefix & REX_W)
37420339a1c2SMark Johnston 			opnd_size = SIZE64;
37430339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size;
37440339a1c2SMark Johnston 
37450339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37460339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37470339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
37480339a1c2SMark Johnston 		wbit = WBIT(opcode7);
37490339a1c2SMark Johnston 		if (opnd_size_prefix)
37500339a1c2SMark Johnston 			x->d86_opnd_size = opnd_size = SIZE16;
37510339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
37520339a1c2SMark Johnston 		break;
37530339a1c2SMark Johnston 	case MOVBE:
37540339a1c2SMark Johnston 		opnd_size = SIZE32;
37550339a1c2SMark Johnston 		if (rex_prefix & REX_W)
37560339a1c2SMark Johnston 			opnd_size = SIZE64;
37570339a1c2SMark Johnston 		x->d86_opnd_size = opnd_size;
37580339a1c2SMark Johnston 
37590339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
37600339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
37610339a1c2SMark Johnston 		wbit = WBIT(opcode7);
37620339a1c2SMark Johnston 		if (opnd_size_prefix)
37630339a1c2SMark Johnston 			x->d86_opnd_size = opnd_size = SIZE16;
37640339a1c2SMark Johnston 		if (wbit) {
37650339a1c2SMark Johnston 			/* reg -> mem */
37660339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
37670339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
37680339a1c2SMark Johnston 		} else {
37690339a1c2SMark Johnston 			/* mem -> reg */
37700339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
37710339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
37720339a1c2SMark Johnston 		}
37730339a1c2SMark Johnston 		break;
37740339a1c2SMark Johnston 
37750339a1c2SMark Johnston 	/*
37760339a1c2SMark Johnston 	 * imul instruction, with either 8-bit or longer immediate
37770339a1c2SMark Johnston 	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
37780339a1c2SMark Johnston 	 */
37790339a1c2SMark Johnston 	case IMUL:
37800339a1c2SMark Johnston 		wbit = LONG_OPND;
37810339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
37820339a1c2SMark Johnston 		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
37830339a1c2SMark Johnston 		break;
37840339a1c2SMark Johnston 
37850339a1c2SMark Johnston 	/* memory or register operand to register, with 'w' bit	*/
37860339a1c2SMark Johnston 	case MRw:
3787*b3b5bfebSMark Johnston 	case ADX:
37880339a1c2SMark Johnston 		wbit = WBIT(opcode2);
37890339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
37900339a1c2SMark Johnston 		break;
37910339a1c2SMark Johnston 
37920339a1c2SMark Johnston 	/* register to memory or register operand, with 'w' bit	*/
37930339a1c2SMark Johnston 	/* arpl happens to fit here also because it is odd */
37940339a1c2SMark Johnston 	case RMw:
37950339a1c2SMark Johnston 		if (opcode_bytes == 2)
37960339a1c2SMark Johnston 			wbit = WBIT(opcode5);
37970339a1c2SMark Johnston 		else
37980339a1c2SMark Johnston 			wbit = WBIT(opcode2);
37990339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
38000339a1c2SMark Johnston 		break;
38010339a1c2SMark Johnston 
38020339a1c2SMark Johnston 	/* xaddb instruction */
38030339a1c2SMark Johnston 	case XADDB:
38040339a1c2SMark Johnston 		wbit = 0;
38050339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
38060339a1c2SMark Johnston 		break;
38070339a1c2SMark Johnston 
38080339a1c2SMark Johnston 	/* MMX register to memory or register operand		*/
38090339a1c2SMark Johnston 	case MMS:
38100339a1c2SMark Johnston 	case MMOS:
38110339a1c2SMark Johnston #ifdef DIS_TEXT
38120339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
38130339a1c2SMark Johnston #else
38140339a1c2SMark Johnston 		wbit = LONG_OPND;
38150339a1c2SMark Johnston #endif
38160339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
38170339a1c2SMark Johnston 		break;
38180339a1c2SMark Johnston 
38190339a1c2SMark Johnston 	/* MMX register to memory */
38200339a1c2SMark Johnston 	case MMOMS:
38210339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38220339a1c2SMark Johnston 		if (mode == REG_ONLY)
38230339a1c2SMark Johnston 			goto error;
38240339a1c2SMark Johnston 		wbit = MM_OPND;
38250339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
38260339a1c2SMark Johnston 		break;
38270339a1c2SMark Johnston 
38280339a1c2SMark Johnston 	/* Double shift. Has immediate operand specifying the shift. */
38290339a1c2SMark Johnston 	case DSHIFT:
38300339a1c2SMark Johnston 		wbit = LONG_OPND;
38310339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38320339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
38330339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
38340339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
38350339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
38360339a1c2SMark Johnston 		break;
38370339a1c2SMark Johnston 
38380339a1c2SMark Johnston 	/*
38390339a1c2SMark Johnston 	 * Double shift. With no immediate operand, specifies using %cl.
38400339a1c2SMark Johnston 	 */
38410339a1c2SMark Johnston 	case DSHIFTcl:
38420339a1c2SMark Johnston 		wbit = LONG_OPND;
38430339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
38440339a1c2SMark Johnston 		break;
38450339a1c2SMark Johnston 
38460339a1c2SMark Johnston 	/* immediate to memory or register operand */
38470339a1c2SMark Johnston 	case IMlw:
38480339a1c2SMark Johnston 		wbit = WBIT(opcode2);
38490339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
38500339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
38510339a1c2SMark Johnston 		/*
38520339a1c2SMark Johnston 		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
38530339a1c2SMark Johnston 		 */
38540339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
38550339a1c2SMark Johnston 		break;
38560339a1c2SMark Johnston 
38570339a1c2SMark Johnston 	/* immediate to memory or register operand with the	*/
38580339a1c2SMark Johnston 	/* 'w' bit present					*/
38590339a1c2SMark Johnston 	case IMw:
38600339a1c2SMark Johnston 		wbit = WBIT(opcode2);
38610339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
38620339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
38630339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
38640339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
38650339a1c2SMark Johnston 		break;
38660339a1c2SMark Johnston 
38670339a1c2SMark Johnston 	/* immediate to register with register in low 3 bits	*/
38680339a1c2SMark Johnston 	/* of op code						*/
38690339a1c2SMark Johnston 	case IR:
38700339a1c2SMark Johnston 		/* w-bit here (with regs) is bit 3 */
38710339a1c2SMark Johnston 		wbit = opcode2 >>3 & 0x1;
38720339a1c2SMark Johnston 		reg = REGNO(opcode2);
38730339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
38740339a1c2SMark Johnston 		mode = REG_ONLY;
38750339a1c2SMark Johnston 		r_m = reg;
38760339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
38770339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
38780339a1c2SMark Johnston 		break;
38790339a1c2SMark Johnston 
38800339a1c2SMark Johnston 	/* MMX immediate shift of register */
38810339a1c2SMark Johnston 	case MMSH:
38820339a1c2SMark Johnston 	case MMOSH:
38830339a1c2SMark Johnston 		wbit = MM_OPND;
38840339a1c2SMark Johnston 		goto mm_shift;	/* in next case */
38850339a1c2SMark Johnston 
38860339a1c2SMark Johnston 	/* SIMD immediate shift of register */
38870339a1c2SMark Johnston 	case XMMSH:
38880339a1c2SMark Johnston 		wbit = XMM_OPND;
38890339a1c2SMark Johnston mm_shift:
38900339a1c2SMark Johnston 		reg = REGNO(opcode7);
38910339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
38920339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
38930339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
38940339a1c2SMark Johnston 		NOMEM;
38950339a1c2SMark Johnston 		break;
38960339a1c2SMark Johnston 
38970339a1c2SMark Johnston 	/* accumulator to memory operand */
38980339a1c2SMark Johnston 	case AO:
38990339a1c2SMark Johnston 		vbit = 1;
39000339a1c2SMark Johnston 		/*FALLTHROUGH*/
39010339a1c2SMark Johnston 
39020339a1c2SMark Johnston 	/* memory operand to accumulator */
39030339a1c2SMark Johnston 	case OA:
39040339a1c2SMark Johnston 		wbit = WBIT(opcode2);
39050339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
39060339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
39070339a1c2SMark Johnston #ifdef DIS_TEXT
39080339a1c2SMark Johnston 		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
39090339a1c2SMark Johnston #endif
39100339a1c2SMark Johnston 		break;
39110339a1c2SMark Johnston 
39120339a1c2SMark Johnston 
39130339a1c2SMark Johnston 	/* segment register to memory or register operand */
39140339a1c2SMark Johnston 	case SM:
39150339a1c2SMark Johnston 		vbit = 1;
39160339a1c2SMark Johnston 		/*FALLTHROUGH*/
39170339a1c2SMark Johnston 
39180339a1c2SMark Johnston 	/* memory or register operand to segment register */
39190339a1c2SMark Johnston 	case MS:
39200339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
39210339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
39220339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
39230339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
39240339a1c2SMark Johnston 		break;
39250339a1c2SMark Johnston 
39260339a1c2SMark Johnston 	/*
39270339a1c2SMark Johnston 	 * rotate or shift instructions, which may shift by 1 or
39280339a1c2SMark Johnston 	 * consult the cl register, depending on the 'v' bit
39290339a1c2SMark Johnston 	 */
39300339a1c2SMark Johnston 	case Mv:
39310339a1c2SMark Johnston 		vbit = VBIT(opcode2);
39320339a1c2SMark Johnston 		wbit = WBIT(opcode2);
39330339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
39340339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
39350339a1c2SMark Johnston #ifdef DIS_TEXT
39360339a1c2SMark Johnston 		if (vbit) {
39370339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
39380339a1c2SMark Johnston 		} else {
39390339a1c2SMark Johnston 			x->d86_opnd[0].d86_mode = MODE_SIGNED;
39400339a1c2SMark Johnston 			x->d86_opnd[0].d86_value_size = 1;
39410339a1c2SMark Johnston 			x->d86_opnd[0].d86_value = 1;
39420339a1c2SMark Johnston 		}
39430339a1c2SMark Johnston #endif
39440339a1c2SMark Johnston 		break;
39450339a1c2SMark Johnston 	/*
39460339a1c2SMark Johnston 	 * immediate rotate or shift instructions
39470339a1c2SMark Johnston 	 */
39480339a1c2SMark Johnston 	case MvI:
39490339a1c2SMark Johnston 		wbit = WBIT(opcode2);
39500339a1c2SMark Johnston normal_imm_mem:
39510339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
39520339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
39530339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
39540339a1c2SMark Johnston 		break;
39550339a1c2SMark Johnston 
39560339a1c2SMark Johnston 	/* bit test instructions */
39570339a1c2SMark Johnston 	case MIb:
39580339a1c2SMark Johnston 		wbit = LONG_OPND;
39590339a1c2SMark Johnston 		goto normal_imm_mem;
39600339a1c2SMark Johnston 
39610339a1c2SMark Johnston 	/* single memory or register operand with 'w' bit present */
39620339a1c2SMark Johnston 	case Mw:
39630339a1c2SMark Johnston 		wbit = WBIT(opcode2);
39640339a1c2SMark Johnston just_mem:
39650339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
39660339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
39670339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
39680339a1c2SMark Johnston 		break;
39690339a1c2SMark Johnston 
3970c3ddb60eSPeter Grehan 	case SWAPGS_RDTSCP:
39710339a1c2SMark Johnston 		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
39720339a1c2SMark Johnston #ifdef DIS_TEXT
39730339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
39740339a1c2SMark Johnston #endif
39750339a1c2SMark Johnston 			NOMEM;
39760339a1c2SMark Johnston 			break;
3977c3ddb60eSPeter Grehan 		} else if (mode == 3 && r_m == 1) {
3978c3ddb60eSPeter Grehan #ifdef DIS_TEXT
3979c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, "rdtscp", OPLEN);
3980c3ddb60eSPeter Grehan #endif
3981c3ddb60eSPeter Grehan 			NOMEM;
3982c3ddb60eSPeter Grehan 			break;
39830339a1c2SMark Johnston 		}
3984c3ddb60eSPeter Grehan 
39850339a1c2SMark Johnston 		/*FALLTHROUGH*/
39860339a1c2SMark Johnston 
39870339a1c2SMark Johnston 	/* prefetch instruction - memory operand, but no memory acess */
39880339a1c2SMark Johnston 	case PREF:
39890339a1c2SMark Johnston 		NOMEM;
39900339a1c2SMark Johnston 		/*FALLTHROUGH*/
39910339a1c2SMark Johnston 
39920339a1c2SMark Johnston 	/* single memory or register operand */
39930339a1c2SMark Johnston 	case M:
3994c3ddb60eSPeter Grehan 	case MG9:
39950339a1c2SMark Johnston 		wbit = LONG_OPND;
39960339a1c2SMark Johnston 		goto just_mem;
39970339a1c2SMark Johnston 
39980339a1c2SMark Johnston 	/* single memory or register byte operand */
39990339a1c2SMark Johnston 	case Mb:
40000339a1c2SMark Johnston 		wbit = BYTE_OPND;
40010339a1c2SMark Johnston 		goto just_mem;
40020339a1c2SMark Johnston 
4003c3ddb60eSPeter Grehan 	case VMx:
4004c3ddb60eSPeter Grehan 		if (mode == 3) {
4005c3ddb60eSPeter Grehan #ifdef DIS_TEXT
4006c3ddb60eSPeter Grehan 			char *vminstr;
4007c3ddb60eSPeter Grehan 
4008c3ddb60eSPeter Grehan 			switch (r_m) {
4009c3ddb60eSPeter Grehan 			case 1:
4010c3ddb60eSPeter Grehan 				vminstr = "vmcall";
4011c3ddb60eSPeter Grehan 				break;
4012c3ddb60eSPeter Grehan 			case 2:
4013c3ddb60eSPeter Grehan 				vminstr = "vmlaunch";
4014c3ddb60eSPeter Grehan 				break;
4015c3ddb60eSPeter Grehan 			case 3:
4016c3ddb60eSPeter Grehan 				vminstr = "vmresume";
4017c3ddb60eSPeter Grehan 				break;
4018c3ddb60eSPeter Grehan 			case 4:
4019c3ddb60eSPeter Grehan 				vminstr = "vmxoff";
4020c3ddb60eSPeter Grehan 				break;
4021c3ddb60eSPeter Grehan 			default:
4022c3ddb60eSPeter Grehan 				goto error;
4023c3ddb60eSPeter Grehan 			}
4024c3ddb60eSPeter Grehan 
4025c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, vminstr, OPLEN);
4026c3ddb60eSPeter Grehan #else
4027c3ddb60eSPeter Grehan 			if (r_m < 1 || r_m > 4)
4028c3ddb60eSPeter Grehan 				goto error;
4029c3ddb60eSPeter Grehan #endif
4030c3ddb60eSPeter Grehan 
4031c3ddb60eSPeter Grehan 			NOMEM;
4032c3ddb60eSPeter Grehan 			break;
4033c3ddb60eSPeter Grehan 		}
4034c3ddb60eSPeter Grehan 		/*FALLTHROUGH*/
4035c3ddb60eSPeter Grehan 	case SVM:
4036c3ddb60eSPeter Grehan 		if (mode == 3) {
4037c3ddb60eSPeter Grehan #ifdef DIS_TEXT
4038c3ddb60eSPeter Grehan 			char *vinstr;
4039c3ddb60eSPeter Grehan 
4040c3ddb60eSPeter Grehan 			switch (r_m) {
4041c3ddb60eSPeter Grehan 			case 0:
4042c3ddb60eSPeter Grehan 				vinstr = "vmrun";
4043c3ddb60eSPeter Grehan 				break;
4044c3ddb60eSPeter Grehan 			case 1:
4045c3ddb60eSPeter Grehan 				vinstr = "vmmcall";
4046c3ddb60eSPeter Grehan 				break;
4047c3ddb60eSPeter Grehan 			case 2:
4048c3ddb60eSPeter Grehan 				vinstr = "vmload";
4049c3ddb60eSPeter Grehan 				break;
4050c3ddb60eSPeter Grehan 			case 3:
4051c3ddb60eSPeter Grehan 				vinstr = "vmsave";
4052c3ddb60eSPeter Grehan 				break;
4053c3ddb60eSPeter Grehan 			case 4:
4054c3ddb60eSPeter Grehan 				vinstr = "stgi";
4055c3ddb60eSPeter Grehan 				break;
4056c3ddb60eSPeter Grehan 			case 5:
4057c3ddb60eSPeter Grehan 				vinstr = "clgi";
4058c3ddb60eSPeter Grehan 				break;
4059c3ddb60eSPeter Grehan 			case 6:
4060c3ddb60eSPeter Grehan 				vinstr = "skinit";
4061c3ddb60eSPeter Grehan 				break;
4062c3ddb60eSPeter Grehan 			case 7:
4063c3ddb60eSPeter Grehan 				vinstr = "invlpga";
4064c3ddb60eSPeter Grehan 				break;
4065c3ddb60eSPeter Grehan 			}
4066c3ddb60eSPeter Grehan 
4067c3ddb60eSPeter Grehan 			(void) strncpy(x->d86_mnem, vinstr, OPLEN);
4068c3ddb60eSPeter Grehan #endif
4069c3ddb60eSPeter Grehan 			NOMEM;
4070c3ddb60eSPeter Grehan 			break;
4071c3ddb60eSPeter Grehan 		}
4072c3ddb60eSPeter Grehan 		/*FALLTHROUGH*/
40730339a1c2SMark Johnston 	case MONITOR_MWAIT:
40740339a1c2SMark Johnston 		if (mode == 3) {
40750339a1c2SMark Johnston 			if (r_m == 0) {
40760339a1c2SMark Johnston #ifdef DIS_TEXT
40770339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
40780339a1c2SMark Johnston #endif
40790339a1c2SMark Johnston 				NOMEM;
40800339a1c2SMark Johnston 				break;
40810339a1c2SMark Johnston 			} else if (r_m == 1) {
40820339a1c2SMark Johnston #ifdef DIS_TEXT
40830339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
40840339a1c2SMark Johnston #endif
40850339a1c2SMark Johnston 				NOMEM;
40860339a1c2SMark Johnston 				break;
4087*b3b5bfebSMark Johnston 			} else if (r_m == 2) {
4088*b3b5bfebSMark Johnston #ifdef DIS_TEXT
4089*b3b5bfebSMark Johnston 				(void) strncpy(x->d86_mnem, "clac", OPLEN);
4090*b3b5bfebSMark Johnston #endif
4091*b3b5bfebSMark Johnston 				NOMEM;
4092*b3b5bfebSMark Johnston 				break;
4093*b3b5bfebSMark Johnston 			} else if (r_m == 3) {
4094*b3b5bfebSMark Johnston #ifdef DIS_TEXT
4095*b3b5bfebSMark Johnston 				(void) strncpy(x->d86_mnem, "stac", OPLEN);
4096*b3b5bfebSMark Johnston #endif
4097*b3b5bfebSMark Johnston 				NOMEM;
4098*b3b5bfebSMark Johnston 				break;
40990339a1c2SMark Johnston 			} else {
41000339a1c2SMark Johnston 				goto error;
41010339a1c2SMark Johnston 			}
41020339a1c2SMark Johnston 		}
41030339a1c2SMark Johnston 		/*FALLTHROUGH*/
41040339a1c2SMark Johnston 	case XGETBV_XSETBV:
41050339a1c2SMark Johnston 		if (mode == 3) {
41060339a1c2SMark Johnston 			if (r_m == 0) {
41070339a1c2SMark Johnston #ifdef DIS_TEXT
41080339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "xgetbv", OPLEN);
41090339a1c2SMark Johnston #endif
41100339a1c2SMark Johnston 				NOMEM;
41110339a1c2SMark Johnston 				break;
41120339a1c2SMark Johnston 			} else if (r_m == 1) {
41130339a1c2SMark Johnston #ifdef DIS_TEXT
41140339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "xsetbv", OPLEN);
41150339a1c2SMark Johnston #endif
41160339a1c2SMark Johnston 				NOMEM;
41170339a1c2SMark Johnston 				break;
41180339a1c2SMark Johnston 			} else {
41190339a1c2SMark Johnston 				goto error;
41200339a1c2SMark Johnston 			}
41210339a1c2SMark Johnston 
41220339a1c2SMark Johnston 		}
41230339a1c2SMark Johnston 		/*FALLTHROUGH*/
41240339a1c2SMark Johnston 	case MO:
41250339a1c2SMark Johnston 		/* Similar to M, but only memory (no direct registers) */
41260339a1c2SMark Johnston 		wbit = LONG_OPND;
41270339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
41280339a1c2SMark Johnston 		if (mode == 3)
41290339a1c2SMark Johnston 			goto error;
41300339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
41310339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
41320339a1c2SMark Johnston 		break;
41330339a1c2SMark Johnston 
41340339a1c2SMark Johnston 	/* move special register to register or reverse if vbit */
41350339a1c2SMark Johnston 	case SREG:
41360339a1c2SMark Johnston 		switch (opcode5) {
41370339a1c2SMark Johnston 
41380339a1c2SMark Johnston 		case 2:
41390339a1c2SMark Johnston 			vbit = 1;
41400339a1c2SMark Johnston 			/*FALLTHROUGH*/
41410339a1c2SMark Johnston 		case 0:
41420339a1c2SMark Johnston 			wbit = CONTROL_OPND;
41430339a1c2SMark Johnston 			break;
41440339a1c2SMark Johnston 
41450339a1c2SMark Johnston 		case 3:
41460339a1c2SMark Johnston 			vbit = 1;
41470339a1c2SMark Johnston 			/*FALLTHROUGH*/
41480339a1c2SMark Johnston 		case 1:
41490339a1c2SMark Johnston 			wbit = DEBUG_OPND;
41500339a1c2SMark Johnston 			break;
41510339a1c2SMark Johnston 
41520339a1c2SMark Johnston 		case 6:
41530339a1c2SMark Johnston 			vbit = 1;
41540339a1c2SMark Johnston 			/*FALLTHROUGH*/
41550339a1c2SMark Johnston 		case 4:
41560339a1c2SMark Johnston 			wbit = TEST_OPND;
41570339a1c2SMark Johnston 			break;
41580339a1c2SMark Johnston 
41590339a1c2SMark Johnston 		}
41600339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
41610339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
41620339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
41630339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
41640339a1c2SMark Johnston 		NOMEM;
41650339a1c2SMark Johnston 		break;
41660339a1c2SMark Johnston 
41670339a1c2SMark Johnston 	/*
41680339a1c2SMark Johnston 	 * single register operand with register in the low 3
41690339a1c2SMark Johnston 	 * bits of op code
41700339a1c2SMark Johnston 	 */
41710339a1c2SMark Johnston 	case R:
41720339a1c2SMark Johnston 		if (opcode_bytes == 2)
41730339a1c2SMark Johnston 			reg = REGNO(opcode5);
41740339a1c2SMark Johnston 		else
41750339a1c2SMark Johnston 			reg = REGNO(opcode2);
41760339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
41770339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
41780339a1c2SMark Johnston 		NOMEM;
41790339a1c2SMark Johnston 		break;
41800339a1c2SMark Johnston 
41810339a1c2SMark Johnston 	/*
41820339a1c2SMark Johnston 	 * register to accumulator with register in the low 3
41830339a1c2SMark Johnston 	 * bits of op code, xchg instructions
41840339a1c2SMark Johnston 	 */
41850339a1c2SMark Johnston 	case RA:
41860339a1c2SMark Johnston 		NOMEM;
41870339a1c2SMark Johnston 		reg = REGNO(opcode2);
41880339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
41890339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
41900339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
41910339a1c2SMark Johnston 		break;
41920339a1c2SMark Johnston 
41930339a1c2SMark Johnston 	/*
41940339a1c2SMark Johnston 	 * single segment register operand, with register in
41950339a1c2SMark Johnston 	 * bits 3-4 of op code byte
41960339a1c2SMark Johnston 	 */
41970339a1c2SMark Johnston 	case SEG:
41980339a1c2SMark Johnston 		NOMEM;
41990339a1c2SMark Johnston 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
42000339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
42010339a1c2SMark Johnston 		break;
42020339a1c2SMark Johnston 
42030339a1c2SMark Johnston 	/*
42040339a1c2SMark Johnston 	 * single segment register operand, with register in
42050339a1c2SMark Johnston 	 * bits 3-5 of op code
42060339a1c2SMark Johnston 	 */
42070339a1c2SMark Johnston 	case LSEG:
42080339a1c2SMark Johnston 		NOMEM;
42090339a1c2SMark Johnston 		/* long seg reg from opcode */
42100339a1c2SMark Johnston 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
42110339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
42120339a1c2SMark Johnston 		break;
42130339a1c2SMark Johnston 
42140339a1c2SMark Johnston 	/* memory or register operand to register */
42150339a1c2SMark Johnston 	case MR:
42160339a1c2SMark Johnston 		if (vex_prefetch)
42170339a1c2SMark Johnston 			x->d86_got_modrm = 1;
42180339a1c2SMark Johnston 		wbit = LONG_OPND;
42190339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
42200339a1c2SMark Johnston 		break;
42210339a1c2SMark Johnston 
42220339a1c2SMark Johnston 	case RM:
4223c3ddb60eSPeter Grehan 	case RM_66r:
42240339a1c2SMark Johnston 		wbit = LONG_OPND;
42250339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
42260339a1c2SMark Johnston 		break;
42270339a1c2SMark Johnston 
42280339a1c2SMark Johnston 	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
42290339a1c2SMark Johnston 	case MM:
42300339a1c2SMark Johnston 	case MMO:
42310339a1c2SMark Johnston #ifdef DIS_TEXT
42320339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
42330339a1c2SMark Johnston #else
42340339a1c2SMark Johnston 		wbit = LONG_OPND;
42350339a1c2SMark Johnston #endif
42360339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
42370339a1c2SMark Johnston 		break;
42380339a1c2SMark Johnston 
42390339a1c2SMark Johnston 	case MMOIMPL:
42400339a1c2SMark Johnston #ifdef DIS_TEXT
42410339a1c2SMark Johnston 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
42420339a1c2SMark Johnston #else
42430339a1c2SMark Johnston 		wbit = LONG_OPND;
42440339a1c2SMark Johnston #endif
42450339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
42460339a1c2SMark Johnston 		if (mode != REG_ONLY)
42470339a1c2SMark Johnston 			goto error;
42480339a1c2SMark Johnston 
42490339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
42500339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
42510339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
42520339a1c2SMark Johnston 		mode = 0;	/* change for memory access size... */
42530339a1c2SMark Johnston 		break;
42540339a1c2SMark Johnston 
42550339a1c2SMark Johnston 	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
42560339a1c2SMark Johnston 	case MMO3P:
42570339a1c2SMark Johnston 		wbit = MM_OPND;
42580339a1c2SMark Johnston 		goto xmm3p;
42590339a1c2SMark Johnston 	case XMM3P:
42600339a1c2SMark Johnston 		wbit = XMM_OPND;
42610339a1c2SMark Johnston xmm3p:
42620339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
42630339a1c2SMark Johnston 		if (mode != REG_ONLY)
42640339a1c2SMark Johnston 			goto error;
42650339a1c2SMark Johnston 
42660339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
42670339a1c2SMark Johnston 		    1);
42680339a1c2SMark Johnston 		NOMEM;
42690339a1c2SMark Johnston 		break;
42700339a1c2SMark Johnston 
42710339a1c2SMark Johnston 	case XMM3PM_66r:
42720339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
42730339a1c2SMark Johnston 		    1, 0);
42740339a1c2SMark Johnston 		break;
42750339a1c2SMark Johnston 
42760339a1c2SMark Johnston 	/* MMX/SIMD-Int predicated r32/mem to mm reg */
42770339a1c2SMark Johnston 	case MMOPRM:
42780339a1c2SMark Johnston 		wbit = LONG_OPND;
42790339a1c2SMark Johnston 		w2 = MM_OPND;
42800339a1c2SMark Johnston 		goto xmmprm;
42810339a1c2SMark Johnston 	case XMMPRM:
42820339a1c2SMark Johnston 	case XMMPRM_66r:
42830339a1c2SMark Johnston 		wbit = LONG_OPND;
42840339a1c2SMark Johnston 		w2 = XMM_OPND;
42850339a1c2SMark Johnston xmmprm:
42860339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
42870339a1c2SMark Johnston 		break;
42880339a1c2SMark Johnston 
42890339a1c2SMark Johnston 	/* MMX/SIMD-Int predicated mm/mem to mm reg */
42900339a1c2SMark Johnston 	case MMOPM:
42910339a1c2SMark Johnston 	case MMOPM_66o:
42920339a1c2SMark Johnston 		wbit = w2 = MM_OPND;
42930339a1c2SMark Johnston 		goto xmmprm;
42940339a1c2SMark Johnston 
42950339a1c2SMark Johnston 	/* MMX/SIMD-Int mm reg to r32 */
42960339a1c2SMark Johnston 	case MMOM3:
42970339a1c2SMark Johnston 		NOMEM;
42980339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
42990339a1c2SMark Johnston 		if (mode != REG_ONLY)
43000339a1c2SMark Johnston 			goto error;
43010339a1c2SMark Johnston 		wbit = MM_OPND;
43020339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
43030339a1c2SMark Johnston 		break;
43040339a1c2SMark Johnston 
43050339a1c2SMark Johnston 	/* SIMD memory or xmm reg operand to xmm reg		*/
43060339a1c2SMark Johnston 	case XMM:
43070339a1c2SMark Johnston 	case XMM_66o:
43080339a1c2SMark Johnston 	case XMM_66r:
43090339a1c2SMark Johnston 	case XMMO:
43100339a1c2SMark Johnston 	case XMMXIMPL:
43110339a1c2SMark Johnston 		wbit = XMM_OPND;
43120339a1c2SMark Johnston 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
43130339a1c2SMark Johnston 
43140339a1c2SMark Johnston 		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
43150339a1c2SMark Johnston 			goto error;
43160339a1c2SMark Johnston 
43170339a1c2SMark Johnston #ifdef DIS_TEXT
43180339a1c2SMark Johnston 		/*
43190339a1c2SMark Johnston 		 * movlps and movhlps share opcodes.  They differ in the
43200339a1c2SMark Johnston 		 * addressing modes allowed for their operands.
43210339a1c2SMark Johnston 		 * movhps and movlhps behave similarly.
43220339a1c2SMark Johnston 		 */
43230339a1c2SMark Johnston 		if (mode == REG_ONLY) {
43240339a1c2SMark Johnston 			if (strcmp(dp->it_name, "movlps") == 0)
43250339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
43260339a1c2SMark Johnston 			else if (strcmp(dp->it_name, "movhps") == 0)
43270339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
43280339a1c2SMark Johnston 		}
43290339a1c2SMark Johnston #endif
43300339a1c2SMark Johnston 		if (dp->it_adrmode == XMMXIMPL)
43310339a1c2SMark Johnston 			mode = 0;	/* change for memory access size... */
43320339a1c2SMark Johnston 		break;
43330339a1c2SMark Johnston 
43340339a1c2SMark Johnston 	/* SIMD xmm reg to memory or xmm reg */
43350339a1c2SMark Johnston 	case XMMS:
43360339a1c2SMark Johnston 	case XMMOS:
43370339a1c2SMark Johnston 	case XMMMS:
43380339a1c2SMark Johnston 	case XMMOMS:
43390339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
43400339a1c2SMark Johnston #ifdef DIS_TEXT
43410339a1c2SMark Johnston 		if ((strcmp(dp->it_name, "movlps") == 0 ||
43420339a1c2SMark Johnston 		    strcmp(dp->it_name, "movhps") == 0 ||
43430339a1c2SMark Johnston 		    strcmp(dp->it_name, "movntps") == 0) &&
43440339a1c2SMark Johnston 		    mode == REG_ONLY)
43450339a1c2SMark Johnston 			goto error;
43460339a1c2SMark Johnston #endif
43470339a1c2SMark Johnston 		wbit = XMM_OPND;
43480339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
43490339a1c2SMark Johnston 		break;
43500339a1c2SMark Johnston 
43510339a1c2SMark Johnston 	/* SIMD memory to xmm reg */
43520339a1c2SMark Johnston 	case XMMM:
43530339a1c2SMark Johnston 	case XMMM_66r:
43540339a1c2SMark Johnston 	case XMMOM:
43550339a1c2SMark Johnston 		wbit = XMM_OPND;
43560339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
43570339a1c2SMark Johnston #ifdef DIS_TEXT
43580339a1c2SMark Johnston 		if (mode == REG_ONLY) {
43590339a1c2SMark Johnston 			if (strcmp(dp->it_name, "movhps") == 0)
43600339a1c2SMark Johnston 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
43610339a1c2SMark Johnston 			else
43620339a1c2SMark Johnston 				goto error;
43630339a1c2SMark Johnston 		}
43640339a1c2SMark Johnston #endif
43650339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
43660339a1c2SMark Johnston 		break;
43670339a1c2SMark Johnston 
43680339a1c2SMark Johnston 	/* SIMD memory or r32 to xmm reg			*/
43690339a1c2SMark Johnston 	case XMM3MX:
43700339a1c2SMark Johnston 		wbit = LONG_OPND;
43710339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
43720339a1c2SMark Johnston 		break;
43730339a1c2SMark Johnston 
43740339a1c2SMark Johnston 	case XMM3MXS:
43750339a1c2SMark Johnston 		wbit = LONG_OPND;
43760339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
43770339a1c2SMark Johnston 		break;
43780339a1c2SMark Johnston 
43790339a1c2SMark Johnston 	/* SIMD memory or mm reg to xmm reg			*/
43800339a1c2SMark Johnston 	case XMMOMX:
43810339a1c2SMark Johnston 	/* SIMD mm to xmm */
43820339a1c2SMark Johnston 	case XMMMX:
43830339a1c2SMark Johnston 		wbit = MM_OPND;
43840339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
43850339a1c2SMark Johnston 		break;
43860339a1c2SMark Johnston 
43870339a1c2SMark Johnston 	/* SIMD memory or xmm reg to mm reg			*/
43880339a1c2SMark Johnston 	case XMMXMM:
43890339a1c2SMark Johnston 	case XMMOXMM:
43900339a1c2SMark Johnston 	case XMMXM:
43910339a1c2SMark Johnston 		wbit = XMM_OPND;
43920339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
43930339a1c2SMark Johnston 		break;
43940339a1c2SMark Johnston 
43950339a1c2SMark Johnston 
43960339a1c2SMark Johnston 	/* SIMD memory or xmm reg to r32			*/
43970339a1c2SMark Johnston 	case XMMXM3:
43980339a1c2SMark Johnston 		wbit = XMM_OPND;
43990339a1c2SMark Johnston 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
44000339a1c2SMark Johnston 		break;
44010339a1c2SMark Johnston 
44020339a1c2SMark Johnston 	/* SIMD xmm to r32					*/
44030339a1c2SMark Johnston 	case XMMX3:
44040339a1c2SMark Johnston 	case XMMOX3:
44050339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
44060339a1c2SMark Johnston 		if (mode != REG_ONLY)
44070339a1c2SMark Johnston 			goto error;
44080339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
44090339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
44100339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
44110339a1c2SMark Johnston 		NOMEM;
44120339a1c2SMark Johnston 		break;
44130339a1c2SMark Johnston 
44140339a1c2SMark Johnston 	/* SIMD predicated memory or xmm reg with/to xmm reg */
44150339a1c2SMark Johnston 	case XMMP:
44160339a1c2SMark Johnston 	case XMMP_66r:
44170339a1c2SMark Johnston 	case XMMP_66o:
44180339a1c2SMark Johnston 	case XMMOPM:
44190339a1c2SMark Johnston 		wbit = XMM_OPND;
44200339a1c2SMark Johnston 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
44210339a1c2SMark Johnston 		    1);
44220339a1c2SMark Johnston 
44230339a1c2SMark Johnston #ifdef DIS_TEXT
44240339a1c2SMark Johnston 		/*
44250339a1c2SMark Johnston 		 * cmpps and cmpss vary their instruction name based
44260339a1c2SMark Johnston 		 * on the value of imm8.  Other XMMP instructions,
44270339a1c2SMark Johnston 		 * such as shufps, require explicit specification of
44280339a1c2SMark Johnston 		 * the predicate.
44290339a1c2SMark Johnston 		 */
44300339a1c2SMark Johnston 		if (dp->it_name[0] == 'c' &&
44310339a1c2SMark Johnston 		    dp->it_name[1] == 'm' &&
44320339a1c2SMark Johnston 		    dp->it_name[2] == 'p' &&
44330339a1c2SMark Johnston 		    strlen(dp->it_name) == 5) {
44340339a1c2SMark Johnston 			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
44350339a1c2SMark Johnston 
44360339a1c2SMark Johnston 			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
44370339a1c2SMark Johnston 				goto error;
44380339a1c2SMark Johnston 
44390339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
44400339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
44410339a1c2SMark Johnston 			    OPLEN);
44420339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem,
44430339a1c2SMark Johnston 			    dp->it_name + strlen(dp->it_name) - 2,
44440339a1c2SMark Johnston 			    OPLEN);
44450339a1c2SMark Johnston 			x->d86_opnd[0] = x->d86_opnd[1];
44460339a1c2SMark Johnston 			x->d86_opnd[1] = x->d86_opnd[2];
44470339a1c2SMark Johnston 			x->d86_numopnds = 2;
44480339a1c2SMark Johnston 		}
44490339a1c2SMark Johnston #endif
44500339a1c2SMark Johnston 		break;
44510339a1c2SMark Johnston 
44520339a1c2SMark Johnston 	case XMMX2I:
44530339a1c2SMark Johnston 		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
44540339a1c2SMark Johnston 		    1);
44550339a1c2SMark Johnston 		NOMEM;
44560339a1c2SMark Johnston 		break;
44570339a1c2SMark Johnston 
44580339a1c2SMark Johnston 	case XMM2I:
44590339a1c2SMark Johnston 		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
44600339a1c2SMark Johnston 		NOMEM;
44610339a1c2SMark Johnston 		break;
44620339a1c2SMark Johnston 
44630339a1c2SMark Johnston 	/* immediate operand to accumulator */
44640339a1c2SMark Johnston 	case IA:
44650339a1c2SMark Johnston 		wbit = WBIT(opcode2);
44660339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
44670339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
44680339a1c2SMark Johnston 		NOMEM;
44690339a1c2SMark Johnston 		break;
44700339a1c2SMark Johnston 
44710339a1c2SMark Johnston 	/* memory or register operand to accumulator */
44720339a1c2SMark Johnston 	case MA:
44730339a1c2SMark Johnston 		wbit = WBIT(opcode2);
44740339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
44750339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
44760339a1c2SMark Johnston 		break;
44770339a1c2SMark Johnston 
44780339a1c2SMark Johnston 	/* si register to di register used to reference memory		*/
44790339a1c2SMark Johnston 	case SD:
44800339a1c2SMark Johnston #ifdef DIS_TEXT
44810339a1c2SMark Johnston 		dtrace_check_override(x, 0);
44820339a1c2SMark Johnston 		x->d86_numopnds = 2;
44830339a1c2SMark Johnston 		if (addr_size == SIZE64) {
44840339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
44850339a1c2SMark Johnston 			    OPLEN);
44860339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
44870339a1c2SMark Johnston 			    OPLEN);
44880339a1c2SMark Johnston 		} else if (addr_size == SIZE32) {
44890339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
44900339a1c2SMark Johnston 			    OPLEN);
44910339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
44920339a1c2SMark Johnston 			    OPLEN);
44930339a1c2SMark Johnston 		} else {
44940339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
44950339a1c2SMark Johnston 			    OPLEN);
44960339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
44970339a1c2SMark Johnston 			    OPLEN);
44980339a1c2SMark Johnston 		}
44990339a1c2SMark Johnston #endif
45000339a1c2SMark Johnston 		wbit = LONG_OPND;
45010339a1c2SMark Johnston 		break;
45020339a1c2SMark Johnston 
45030339a1c2SMark Johnston 	/* accumulator to di register				*/
45040339a1c2SMark Johnston 	case AD:
45050339a1c2SMark Johnston 		wbit = WBIT(opcode2);
45060339a1c2SMark Johnston #ifdef DIS_TEXT
45070339a1c2SMark Johnston 		dtrace_check_override(x, 1);
45080339a1c2SMark Johnston 		x->d86_numopnds = 2;
45090339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
45100339a1c2SMark Johnston 		if (addr_size == SIZE64)
45110339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
45120339a1c2SMark Johnston 			    OPLEN);
45130339a1c2SMark Johnston 		else if (addr_size == SIZE32)
45140339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
45150339a1c2SMark Johnston 			    OPLEN);
45160339a1c2SMark Johnston 		else
45170339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
45180339a1c2SMark Johnston 			    OPLEN);
45190339a1c2SMark Johnston #endif
45200339a1c2SMark Johnston 		break;
45210339a1c2SMark Johnston 
45220339a1c2SMark Johnston 	/* si register to accumulator				*/
45230339a1c2SMark Johnston 	case SA:
45240339a1c2SMark Johnston 		wbit = WBIT(opcode2);
45250339a1c2SMark Johnston #ifdef DIS_TEXT
45260339a1c2SMark Johnston 		dtrace_check_override(x, 0);
45270339a1c2SMark Johnston 		x->d86_numopnds = 2;
45280339a1c2SMark Johnston 		if (addr_size == SIZE64)
45290339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
45300339a1c2SMark Johnston 			    OPLEN);
45310339a1c2SMark Johnston 		else if (addr_size == SIZE32)
45320339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
45330339a1c2SMark Johnston 			    OPLEN);
45340339a1c2SMark Johnston 		else
45350339a1c2SMark Johnston 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
45360339a1c2SMark Johnston 			    OPLEN);
45370339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
45380339a1c2SMark Johnston #endif
45390339a1c2SMark Johnston 		break;
45400339a1c2SMark Johnston 
45410339a1c2SMark Johnston 	/*
45420339a1c2SMark Johnston 	 * single operand, a 16/32 bit displacement
45430339a1c2SMark Johnston 	 */
45440339a1c2SMark Johnston 	case D:
45450339a1c2SMark Johnston 		wbit = LONG_OPND;
45460339a1c2SMark Johnston 		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
45470339a1c2SMark Johnston 		NOMEM;
45480339a1c2SMark Johnston 		break;
45490339a1c2SMark Johnston 
45500339a1c2SMark Johnston 	/* jmp/call indirect to memory or register operand		*/
45510339a1c2SMark Johnston 	case INM:
45520339a1c2SMark Johnston #ifdef DIS_TEXT
45530339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
45540339a1c2SMark Johnston #endif
45550339a1c2SMark Johnston 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
45560339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
45570339a1c2SMark Johnston 		wbit = LONG_OPND;
45580339a1c2SMark Johnston 		break;
45590339a1c2SMark Johnston 
45600339a1c2SMark Johnston 	/*
45610339a1c2SMark Johnston 	 * for long jumps and long calls -- a new code segment
45620339a1c2SMark Johnston 	 * register and an offset in IP -- stored in object
45630339a1c2SMark Johnston 	 * code in reverse order. Note - not valid in amd64
45640339a1c2SMark Johnston 	 */
45650339a1c2SMark Johnston 	case SO:
45660339a1c2SMark Johnston 		dtrace_check_override(x, 1);
45670339a1c2SMark Johnston 		wbit = LONG_OPND;
45680339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
45690339a1c2SMark Johnston #ifdef DIS_TEXT
45700339a1c2SMark Johnston 		x->d86_opnd[1].d86_mode = MODE_SIGNED;
45710339a1c2SMark Johnston #endif
45720339a1c2SMark Johnston 		/* will now get segment operand */
45730339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
45740339a1c2SMark Johnston 		break;
45750339a1c2SMark Johnston 
45760339a1c2SMark Johnston 	/*
45770339a1c2SMark Johnston 	 * jmp/call. single operand, 8 bit displacement.
45780339a1c2SMark Johnston 	 * added to current EIP in 'compofff'
45790339a1c2SMark Johnston 	 */
45800339a1c2SMark Johnston 	case BD:
45810339a1c2SMark Johnston 		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
45820339a1c2SMark Johnston 		NOMEM;
45830339a1c2SMark Johnston 		break;
45840339a1c2SMark Johnston 
45850339a1c2SMark Johnston 	/* single 32/16 bit immediate operand			*/
45860339a1c2SMark Johnston 	case I:
45870339a1c2SMark Johnston 		wbit = LONG_OPND;
45880339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
45890339a1c2SMark Johnston 		break;
45900339a1c2SMark Johnston 
45910339a1c2SMark Johnston 	/* single 8 bit immediate operand			*/
45920339a1c2SMark Johnston 	case Ib:
45930339a1c2SMark Johnston 		wbit = LONG_OPND;
45940339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
45950339a1c2SMark Johnston 		break;
45960339a1c2SMark Johnston 
45970339a1c2SMark Johnston 	case ENTER:
45980339a1c2SMark Johnston 		wbit = LONG_OPND;
45990339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
46000339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 1);
46010339a1c2SMark Johnston 		switch (opnd_size) {
46020339a1c2SMark Johnston 		case SIZE64:
46030339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
46040339a1c2SMark Johnston 			break;
46050339a1c2SMark Johnston 		case SIZE32:
46060339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
46070339a1c2SMark Johnston 			break;
46080339a1c2SMark Johnston 		case SIZE16:
46090339a1c2SMark Johnston 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
46100339a1c2SMark Johnston 			break;
46110339a1c2SMark Johnston 		}
46120339a1c2SMark Johnston 
46130339a1c2SMark Johnston 		break;
46140339a1c2SMark Johnston 
46150339a1c2SMark Johnston 	/* 16-bit immediate operand */
46160339a1c2SMark Johnston 	case RET:
46170339a1c2SMark Johnston 		wbit = LONG_OPND;
46180339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 2, 0);
46190339a1c2SMark Johnston 		break;
46200339a1c2SMark Johnston 
46210339a1c2SMark Johnston 	/* single 8 bit port operand				*/
46220339a1c2SMark Johnston 	case P:
46230339a1c2SMark Johnston 		dtrace_check_override(x, 0);
46240339a1c2SMark Johnston 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
46250339a1c2SMark Johnston 		NOMEM;
46260339a1c2SMark Johnston 		break;
46270339a1c2SMark Johnston 
46280339a1c2SMark Johnston 	/* single operand, dx register (variable port instruction) */
46290339a1c2SMark Johnston 	case V:
46300339a1c2SMark Johnston 		x->d86_numopnds = 1;
46310339a1c2SMark Johnston 		dtrace_check_override(x, 0);
46320339a1c2SMark Johnston #ifdef DIS_TEXT
46330339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
46340339a1c2SMark Johnston #endif
46350339a1c2SMark Johnston 		NOMEM;
46360339a1c2SMark Johnston 		break;
46370339a1c2SMark Johnston 
46380339a1c2SMark Johnston 	/*
46390339a1c2SMark Johnston 	 * The int instruction, which has two forms:
46400339a1c2SMark Johnston 	 * int 3 (breakpoint) or
46410339a1c2SMark Johnston 	 * int n, where n is indicated in the subsequent
46420339a1c2SMark Johnston 	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
46430339a1c2SMark Johnston 	 * where, although the 3 looks  like an operand,
46440339a1c2SMark Johnston 	 * it is implied by the opcode. It must be converted
46450339a1c2SMark Johnston 	 * to the correct base and output.
46460339a1c2SMark Johnston 	 */
46470339a1c2SMark Johnston 	case INT3:
46480339a1c2SMark Johnston #ifdef DIS_TEXT
46490339a1c2SMark Johnston 		x->d86_numopnds = 1;
46500339a1c2SMark Johnston 		x->d86_opnd[0].d86_mode = MODE_SIGNED;
46510339a1c2SMark Johnston 		x->d86_opnd[0].d86_value_size = 1;
46520339a1c2SMark Johnston 		x->d86_opnd[0].d86_value = 3;
46530339a1c2SMark Johnston #endif
46540339a1c2SMark Johnston 		NOMEM;
46550339a1c2SMark Johnston 		break;
46560339a1c2SMark Johnston 
46570339a1c2SMark Johnston 	/* single 8 bit immediate operand			*/
46580339a1c2SMark Johnston 	case INTx:
46590339a1c2SMark Johnston 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
46600339a1c2SMark Johnston 		NOMEM;
46610339a1c2SMark Johnston 		break;
46620339a1c2SMark Johnston 
46630339a1c2SMark Johnston 	/* an unused byte must be discarded */
46640339a1c2SMark Johnston 	case U:
46650339a1c2SMark Johnston 		if (x->d86_get_byte(x->d86_data) < 0)
46660339a1c2SMark Johnston 			goto error;
46670339a1c2SMark Johnston 		x->d86_len++;
46680339a1c2SMark Johnston 		NOMEM;
46690339a1c2SMark Johnston 		break;
46700339a1c2SMark Johnston 
46710339a1c2SMark Johnston 	case CBW:
46720339a1c2SMark Johnston #ifdef DIS_TEXT
46730339a1c2SMark Johnston 		if (opnd_size == SIZE16)
46740339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
46750339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
46760339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
46770339a1c2SMark Johnston 		else
46780339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
46790339a1c2SMark Johnston #endif
46800339a1c2SMark Johnston 		wbit = LONG_OPND;
46810339a1c2SMark Johnston 		NOMEM;
46820339a1c2SMark Johnston 		break;
46830339a1c2SMark Johnston 
46840339a1c2SMark Johnston 	case CWD:
46850339a1c2SMark Johnston #ifdef DIS_TEXT
46860339a1c2SMark Johnston 		if (opnd_size == SIZE16)
46870339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
46880339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
46890339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
46900339a1c2SMark Johnston 		else
46910339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
46920339a1c2SMark Johnston #endif
46930339a1c2SMark Johnston 		wbit = LONG_OPND;
46940339a1c2SMark Johnston 		NOMEM;
46950339a1c2SMark Johnston 		break;
46960339a1c2SMark Johnston 
46970339a1c2SMark Johnston 	case XMMSFNC:
46980339a1c2SMark Johnston 		/*
46990339a1c2SMark Johnston 		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
47000339a1c2SMark Johnston 		 * REG_ONLY, mnemonic should be 'clflush'.
47010339a1c2SMark Johnston 		 */
47020339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
47030339a1c2SMark Johnston 
47040339a1c2SMark Johnston 		/* sfence doesn't take operands */
47050339a1c2SMark Johnston #ifdef DIS_TEXT
47060339a1c2SMark Johnston 		if (mode == REG_ONLY) {
47070339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
47080339a1c2SMark Johnston 		} else {
47090339a1c2SMark Johnston 			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
47100339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
47110339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
47120339a1c2SMark Johnston 			NOMEM;
47130339a1c2SMark Johnston 		}
47140339a1c2SMark Johnston #else
47150339a1c2SMark Johnston 		if (mode != REG_ONLY) {
47160339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
47170339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
47180339a1c2SMark Johnston 			NOMEM;
47190339a1c2SMark Johnston 		}
47200339a1c2SMark Johnston #endif
47210339a1c2SMark Johnston 		break;
47220339a1c2SMark Johnston 
47230339a1c2SMark Johnston 	/*
47240339a1c2SMark Johnston 	 * no disassembly, the mnemonic was all there was so go on
47250339a1c2SMark Johnston 	 */
47260339a1c2SMark Johnston 	case NORM:
47270339a1c2SMark Johnston 		if (dp->it_invalid32 && cpu_mode != SIZE64)
47280339a1c2SMark Johnston 			goto error;
47290339a1c2SMark Johnston 		NOMEM;
47300339a1c2SMark Johnston 		/*FALLTHROUGH*/
47310339a1c2SMark Johnston 	case IMPLMEM:
47320339a1c2SMark Johnston 		break;
47330339a1c2SMark Johnston 
47340339a1c2SMark Johnston 	case XMMFENCE:
47350339a1c2SMark Johnston 		/*
47360339a1c2SMark Johnston 		 * XRSTOR and LFENCE share the same opcode but differ in mode
47370339a1c2SMark Johnston 		 */
47380339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
47390339a1c2SMark Johnston 
47400339a1c2SMark Johnston 		if (mode == REG_ONLY) {
47410339a1c2SMark Johnston 			/*
47420339a1c2SMark Johnston 			 * Only the following exact byte sequences are allowed:
47430339a1c2SMark Johnston 			 *
47440339a1c2SMark Johnston 			 * 	0f ae e8	lfence
47450339a1c2SMark Johnston 			 * 	0f ae f0	mfence
47460339a1c2SMark Johnston 			 */
47470339a1c2SMark Johnston 			if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
47480339a1c2SMark Johnston 			    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
47490339a1c2SMark Johnston 				goto error;
47500339a1c2SMark Johnston 		} else {
47510339a1c2SMark Johnston #ifdef DIS_TEXT
47520339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "xrstor", OPLEN);
47530339a1c2SMark Johnston #endif
47540339a1c2SMark Johnston 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
47550339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
47560339a1c2SMark Johnston 		}
47570339a1c2SMark Johnston 		break;
47580339a1c2SMark Johnston 
47590339a1c2SMark Johnston 	/* float reg */
47600339a1c2SMark Johnston 	case F:
47610339a1c2SMark Johnston #ifdef DIS_TEXT
47620339a1c2SMark Johnston 		x->d86_numopnds = 1;
47630339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
47640339a1c2SMark Johnston 		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
47650339a1c2SMark Johnston #endif
47660339a1c2SMark Johnston 		NOMEM;
47670339a1c2SMark Johnston 		break;
47680339a1c2SMark Johnston 
47690339a1c2SMark Johnston 	/* float reg to float reg, with ret bit present */
47700339a1c2SMark Johnston 	case FF:
47710339a1c2SMark Johnston 		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
47720339a1c2SMark Johnston 		/*FALLTHROUGH*/
47730339a1c2SMark Johnston 	case FFC:				/* case for vbit always = 0 */
47740339a1c2SMark Johnston #ifdef DIS_TEXT
47750339a1c2SMark Johnston 		x->d86_numopnds = 2;
47760339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
47770339a1c2SMark Johnston 		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
47780339a1c2SMark Johnston 		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
47790339a1c2SMark Johnston #endif
47800339a1c2SMark Johnston 		NOMEM;
47810339a1c2SMark Johnston 		break;
47820339a1c2SMark Johnston 
47830339a1c2SMark Johnston 	/* AVX instructions */
47840339a1c2SMark Johnston 	case VEX_MO:
47850339a1c2SMark Johnston 		/* op(ModR/M.r/m) */
47860339a1c2SMark Johnston 		x->d86_numopnds = 1;
47870339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
47880339a1c2SMark Johnston #ifdef DIS_TEXT
47890339a1c2SMark Johnston 		if ((dp == &dis_opAVX0F[0xA][0xE]) && (reg == 3))
47900339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vstmxcsr", OPLEN);
47910339a1c2SMark Johnston #endif
47920339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
47930339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
47940339a1c2SMark Johnston 		break;
47950339a1c2SMark Johnston 	case VEX_RMrX:
4796*b3b5bfebSMark Johnston 	case FMA:
47970339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r/m) */
47980339a1c2SMark Johnston 		x->d86_numopnds = 3;
47990339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
48000339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
48010339a1c2SMark Johnston 
4802*b3b5bfebSMark Johnston 		/*
4803*b3b5bfebSMark Johnston 		 * In classic Intel fashion, the opcodes for all of the FMA
4804*b3b5bfebSMark Johnston 		 * instructions all have two possible mnemonics which vary by
4805*b3b5bfebSMark Johnston 		 * one letter, which is selected based on the value of the wbit.
4806*b3b5bfebSMark Johnston 		 * When wbit is one, they have the 'd' suffix and when 'wbit' is
4807*b3b5bfebSMark Johnston 		 * 0, they have the 's' suffix. Otherwise, the FMA instructions
4808*b3b5bfebSMark Johnston 		 * are all a standard VEX_RMrX.
4809*b3b5bfebSMark Johnston 		 */
4810*b3b5bfebSMark Johnston #ifdef DIS_TEXT
4811*b3b5bfebSMark Johnston 		if (dp->it_adrmode == FMA) {
4812*b3b5bfebSMark Johnston 			size_t len = strlen(dp->it_name);
4813*b3b5bfebSMark Johnston 			(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
4814*b3b5bfebSMark Johnston 			if (len + 1 < OPLEN) {
4815*b3b5bfebSMark Johnston 				(void) strncpy(x->d86_mnem + len,
4816*b3b5bfebSMark Johnston 				    vex_W != 0 ? "d" : "s", OPLEN - len);
4817*b3b5bfebSMark Johnston 			}
4818*b3b5bfebSMark Johnston 		}
4819*b3b5bfebSMark Johnston #endif
4820*b3b5bfebSMark Johnston 
48210339a1c2SMark Johnston 		if (mode != REG_ONLY) {
48220339a1c2SMark Johnston 			if ((dp == &dis_opAVXF20F[0x10]) ||
48230339a1c2SMark Johnston 			    (dp == &dis_opAVXF30F[0x10])) {
48240339a1c2SMark Johnston 				/* vmovsd <m64>, <xmm> */
48250339a1c2SMark Johnston 				/* or vmovss <m64>, <xmm> */
48260339a1c2SMark Johnston 				x->d86_numopnds = 2;
48270339a1c2SMark Johnston 				goto L_VEX_MX;
48280339a1c2SMark Johnston 			}
48290339a1c2SMark Johnston 		}
48300339a1c2SMark Johnston 
48310339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
48320339a1c2SMark Johnston 		/*
48330339a1c2SMark Johnston 		 * VEX prefix uses the 1's complement form to encode the
48340339a1c2SMark Johnston 		 * XMM/YMM regs
48350339a1c2SMark Johnston 		 */
48360339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
48370339a1c2SMark Johnston 
48380339a1c2SMark Johnston 		if ((dp == &dis_opAVXF20F[0x2A]) ||
48390339a1c2SMark Johnston 		    (dp == &dis_opAVXF30F[0x2A])) {
48400339a1c2SMark Johnston 			/*
48410339a1c2SMark Johnston 			 * vcvtsi2si </r,m>, <xmm>, <xmm> or vcvtsi2ss </r,m>,
48420339a1c2SMark Johnston 			 * <xmm>, <xmm>
48430339a1c2SMark Johnston 			 */
48440339a1c2SMark Johnston 			wbit = LONG_OPND;
48450339a1c2SMark Johnston 		}
48460339a1c2SMark Johnston #ifdef DIS_TEXT
48470339a1c2SMark Johnston 		else if ((mode == REG_ONLY) &&
48480339a1c2SMark Johnston 		    (dp == &dis_opAVX0F[0x1][0x6])) {	/* vmovlhps */
48490339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vmovlhps", OPLEN);
48500339a1c2SMark Johnston 		} else if ((mode == REG_ONLY) &&
48510339a1c2SMark Johnston 		    (dp == &dis_opAVX0F[0x1][0x2])) {	/* vmovhlps */
48520339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vmovhlps", OPLEN);
48530339a1c2SMark Johnston 		}
48540339a1c2SMark Johnston #endif
48550339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
48560339a1c2SMark Johnston 
48570339a1c2SMark Johnston 		break;
48580339a1c2SMark Johnston 
4859*b3b5bfebSMark Johnston 	case VEX_VRMrX:
4860*b3b5bfebSMark Johnston 		/* ModR/M.reg := op(MODR/M.r/m, VEX.vvvv) */
4861*b3b5bfebSMark Johnston 		x->d86_numopnds = 3;
4862*b3b5bfebSMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
4863*b3b5bfebSMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4864*b3b5bfebSMark Johnston 
4865*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
4866*b3b5bfebSMark Johnston 		/*
4867*b3b5bfebSMark Johnston 		 * VEX prefix uses the 1's complement form to encode the
4868*b3b5bfebSMark Johnston 		 * XMM/YMM regs
4869*b3b5bfebSMark Johnston 		 */
4870*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 0);
4871*b3b5bfebSMark Johnston 
4872*b3b5bfebSMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
4873*b3b5bfebSMark Johnston 		break;
4874*b3b5bfebSMark Johnston 
4875*b3b5bfebSMark Johnston 	case VEX_SbVM:
4876*b3b5bfebSMark Johnston 		/* ModR/M.reg := op(MODR/M.r/m, VSIB, VEX.vvvv) */
4877*b3b5bfebSMark Johnston 		x->d86_numopnds = 3;
4878*b3b5bfebSMark Johnston 		x->d86_vsib = 1;
4879*b3b5bfebSMark Johnston 
4880*b3b5bfebSMark Johnston 		/*
4881*b3b5bfebSMark Johnston 		 * All instructions that use VSIB are currently a mess. See the
4882*b3b5bfebSMark Johnston 		 * comment around the dis_gather_regs_t structure definition.
4883*b3b5bfebSMark Johnston 		 */
4884*b3b5bfebSMark Johnston 
4885*b3b5bfebSMark Johnston 		vreg = &dis_vgather[opcode2][vex_W][vex_L];
4886*b3b5bfebSMark Johnston 
4887*b3b5bfebSMark Johnston #ifdef DIS_TEXT
4888*b3b5bfebSMark Johnston 		(void) strncpy(x->d86_mnem, dp->it_name, OPLEN);
4889*b3b5bfebSMark Johnston 		(void) strlcat(x->d86_mnem + strlen(dp->it_name),
4890*b3b5bfebSMark Johnston 		    vreg->dgr_suffix, OPLEN - strlen(dp->it_name));
4891*b3b5bfebSMark Johnston #endif
4892*b3b5bfebSMark Johnston 
4893*b3b5bfebSMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
4894*b3b5bfebSMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
4895*b3b5bfebSMark Johnston 
4896*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, vreg->dgr_arg2, 2);
4897*b3b5bfebSMark Johnston 		/*
4898*b3b5bfebSMark Johnston 		 * VEX prefix uses the 1's complement form to encode the
4899*b3b5bfebSMark Johnston 		 * XMM/YMM regs
4900*b3b5bfebSMark Johnston 		 */
4901*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), vreg->dgr_arg0,
4902*b3b5bfebSMark Johnston 		    0);
4903*b3b5bfebSMark Johnston 		dtrace_get_operand(x, mode, r_m, vreg->dgr_arg1, 1);
4904*b3b5bfebSMark Johnston 		break;
4905*b3b5bfebSMark Johnston 
49060339a1c2SMark Johnston 	case VEX_RRX:
49070339a1c2SMark Johnston 		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
49080339a1c2SMark Johnston 		x->d86_numopnds = 3;
49090339a1c2SMark Johnston 
49100339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
49110339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
49120339a1c2SMark Johnston 
49130339a1c2SMark Johnston 		if (mode != REG_ONLY) {
49140339a1c2SMark Johnston 			if ((dp == &dis_opAVXF20F[0x11]) ||
49150339a1c2SMark Johnston 			    (dp == &dis_opAVXF30F[0x11])) {
49160339a1c2SMark Johnston 				/* vmovsd <xmm>, <m64> */
49170339a1c2SMark Johnston 				/* or vmovss <xmm>, <m64> */
49180339a1c2SMark Johnston 				x->d86_numopnds = 2;
49190339a1c2SMark Johnston 				goto L_VEX_RM;
49200339a1c2SMark Johnston 			}
49210339a1c2SMark Johnston 		}
49220339a1c2SMark Johnston 
49230339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
49240339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
49250339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
49260339a1c2SMark Johnston 		break;
49270339a1c2SMark Johnston 
49280339a1c2SMark Johnston 	case VEX_RMRX:
49290339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.r_m, imm8[7:4]) */
49300339a1c2SMark Johnston 		x->d86_numopnds = 4;
49310339a1c2SMark Johnston 
49320339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
49330339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
49340339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 3);
49350339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
49360339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x18]) {
49370339a1c2SMark Johnston 			/* vinsertf128 <imm8>, <xmm>, <ymm>, <ymm> */
49380339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 1);
49390339a1c2SMark Johnston 		} else if ((dp == &dis_opAVX660F3A[0x20]) ||
49400339a1c2SMark Johnston 		    (dp == & dis_opAVX660F[0xC4])) {
49410339a1c2SMark Johnston 			/* vpinsrb <imm8>, <reg/mm>, <xmm>, <xmm> */
49420339a1c2SMark Johnston 			/* or vpinsrw <imm8>, <reg/mm>, <xmm>, <xmm> */
49430339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
49440339a1c2SMark Johnston 		} else if (dp == &dis_opAVX660F3A[0x22]) {
49450339a1c2SMark Johnston 			/* vpinsrd/q <imm8>, <reg/mm>, <xmm>, <xmm> */
49460339a1c2SMark Johnston #ifdef DIS_TEXT
49470339a1c2SMark Johnston 			if (vex_W)
49480339a1c2SMark Johnston 				x->d86_mnem[6] = 'q';
49490339a1c2SMark Johnston #endif
49500339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
49510339a1c2SMark Johnston 		} else {
49520339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
49530339a1c2SMark Johnston 		}
49540339a1c2SMark Johnston 
49550339a1c2SMark Johnston 		/* one byte immediate number */
49560339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
49570339a1c2SMark Johnston 
49580339a1c2SMark Johnston 		/* vblendvpd, vblendvps, vblendvb use the imm encode the regs */
49590339a1c2SMark Johnston 		if ((dp == &dis_opAVX660F3A[0x4A]) ||
49600339a1c2SMark Johnston 		    (dp == &dis_opAVX660F3A[0x4B]) ||
49610339a1c2SMark Johnston 		    (dp == &dis_opAVX660F3A[0x4C])) {
49620339a1c2SMark Johnston #ifdef DIS_TEXT
49630339a1c2SMark Johnston 			int regnum = (x->d86_opnd[0].d86_value & 0xF0) >> 4;
49640339a1c2SMark Johnston #endif
49650339a1c2SMark Johnston 			x->d86_opnd[0].d86_mode = MODE_NONE;
49660339a1c2SMark Johnston #ifdef DIS_TEXT
49670339a1c2SMark Johnston 			if (vex_L)
49680339a1c2SMark Johnston 				(void) strncpy(x->d86_opnd[0].d86_opnd,
49690339a1c2SMark Johnston 				    dis_YMMREG[regnum], OPLEN);
49700339a1c2SMark Johnston 			else
49710339a1c2SMark Johnston 				(void) strncpy(x->d86_opnd[0].d86_opnd,
49720339a1c2SMark Johnston 				    dis_XMMREG[regnum], OPLEN);
49730339a1c2SMark Johnston #endif
49740339a1c2SMark Johnston 		}
49750339a1c2SMark Johnston 		break;
49760339a1c2SMark Johnston 
49770339a1c2SMark Johnston 	case VEX_MX:
49780339a1c2SMark Johnston 		/* ModR/M.reg := op(ModR/M.rm) */
49790339a1c2SMark Johnston 		x->d86_numopnds = 2;
49800339a1c2SMark Johnston 
49810339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
49820339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
49830339a1c2SMark Johnston L_VEX_MX:
49840339a1c2SMark Johnston 
49850339a1c2SMark Johnston 		if ((dp == &dis_opAVXF20F[0xE6]) ||
49860339a1c2SMark Johnston 		    (dp == &dis_opAVX660F[0x5A]) ||
49870339a1c2SMark Johnston 		    (dp == &dis_opAVX660F[0xE6])) {
49880339a1c2SMark Johnston 			/* vcvtpd2dq <ymm>, <xmm> */
49890339a1c2SMark Johnston 			/* or vcvtpd2ps <ymm>, <xmm> */
49900339a1c2SMark Johnston 			/* or vcvttpd2dq <ymm>, <xmm> */
49910339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, XMM_OPND, 1);
49920339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
49930339a1c2SMark Johnston 		} else if ((dp == &dis_opAVXF30F[0xE6]) ||
4994c3ddb60eSPeter Grehan 		    (dp == &dis_opAVX0F[0x5][0xA]) ||
4995*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x13]) ||
4996*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x18]) ||
4997*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x19]) ||
4998*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x58]) ||
4999*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x78]) ||
5000*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x79]) ||
5001*b3b5bfebSMark Johnston 		    (dp == &dis_opAVX660F38[0x59])) {
50020339a1c2SMark Johnston 			/* vcvtdq2pd <xmm>, <ymm> */
50030339a1c2SMark Johnston 			/* or vcvtps2pd <xmm>, <ymm> */
5004*b3b5bfebSMark Johnston 			/* or vcvtph2ps <xmm>, <ymm> */
5005*b3b5bfebSMark Johnston 			/* or vbroadcasts* <xmm>, <ymm> */
50060339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
50070339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
50080339a1c2SMark Johnston 		} else if (dp == &dis_opAVX660F[0x6E]) {
50090339a1c2SMark Johnston 			/* vmovd/q <reg/mem 32/64>, <xmm> */
50100339a1c2SMark Johnston #ifdef DIS_TEXT
50110339a1c2SMark Johnston 			if (vex_W)
50120339a1c2SMark Johnston 				x->d86_mnem[4] = 'q';
50130339a1c2SMark Johnston #endif
50140339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
50150339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
50160339a1c2SMark Johnston 		} else {
50170339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
50180339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 0);
50190339a1c2SMark Johnston 		}
50200339a1c2SMark Johnston 
50210339a1c2SMark Johnston 		break;
50220339a1c2SMark Johnston 
50230339a1c2SMark Johnston 	case VEX_MXI:
50240339a1c2SMark Johnston 		/* ModR/M.reg := op(ModR/M.rm, imm8) */
50250339a1c2SMark Johnston 		x->d86_numopnds = 3;
50260339a1c2SMark Johnston 
50270339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
50280339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
50290339a1c2SMark Johnston 
50300339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
50310339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
50320339a1c2SMark Johnston 
50330339a1c2SMark Johnston 		/* one byte immediate number */
50340339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
50350339a1c2SMark Johnston 		break;
50360339a1c2SMark Johnston 
50370339a1c2SMark Johnston 	case VEX_XXI:
50380339a1c2SMark Johnston 		/* VEX.vvvv := op(ModR/M.rm, imm8) */
50390339a1c2SMark Johnston 		x->d86_numopnds = 3;
50400339a1c2SMark Johnston 
50410339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
50420339a1c2SMark Johnston #ifdef DIS_TEXT
50430339a1c2SMark Johnston 		(void) strncpy(x->d86_mnem, dis_AVXvgrp7[opcode2 - 1][reg],
50440339a1c2SMark Johnston 		    OPLEN);
50450339a1c2SMark Johnston #endif
50460339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
50470339a1c2SMark Johnston 
50480339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 2);
50490339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 1);
50500339a1c2SMark Johnston 
50510339a1c2SMark Johnston 		/* one byte immediate number */
50520339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
50530339a1c2SMark Johnston 		break;
50540339a1c2SMark Johnston 
50550339a1c2SMark Johnston 	case VEX_MR:
50560339a1c2SMark Johnston 		/* ModR/M.reg (reg32/64) := op(ModR/M.rm) */
50570339a1c2SMark Johnston 		if (dp == &dis_opAVX660F[0xC5]) {
50580339a1c2SMark Johnston 			/* vpextrw <imm8>, <xmm>, <reg> */
50590339a1c2SMark Johnston 			x->d86_numopnds = 2;
50600339a1c2SMark Johnston 			vbit = 2;
50610339a1c2SMark Johnston 		} else {
50620339a1c2SMark Johnston 			x->d86_numopnds = 2;
50630339a1c2SMark Johnston 			vbit = 1;
50640339a1c2SMark Johnston 		}
50650339a1c2SMark Johnston 
50660339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
50670339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
50680339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, vbit);
50690339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit - 1);
50700339a1c2SMark Johnston 
50710339a1c2SMark Johnston 		if (vbit == 2)
50720339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
50730339a1c2SMark Johnston 
50740339a1c2SMark Johnston 		break;
50750339a1c2SMark Johnston 
50760339a1c2SMark Johnston 	case VEX_RRI:
50770339a1c2SMark Johnston 		/* implicit(eflags/r32) := op(ModR/M.reg, ModR/M.rm) */
50780339a1c2SMark Johnston 		x->d86_numopnds = 2;
50790339a1c2SMark Johnston 
50800339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
50810339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
50820339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
50830339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
50840339a1c2SMark Johnston 		break;
50850339a1c2SMark Johnston 
50860339a1c2SMark Johnston 	case VEX_RX:
50870339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
5088c3ddb60eSPeter Grehan 		/* vextractf128 || vcvtps2ph */
5089c3ddb60eSPeter Grehan 		if (dp == &dis_opAVX660F3A[0x19] ||
5090c3ddb60eSPeter Grehan 		    dp == &dis_opAVX660F3A[0x1d]) {
50910339a1c2SMark Johnston 			x->d86_numopnds = 3;
50920339a1c2SMark Johnston 
50930339a1c2SMark Johnston 			dtrace_get_modrm(x, &mode, &reg, &r_m);
50940339a1c2SMark Johnston 			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
50950339a1c2SMark Johnston 
50960339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
50970339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
50980339a1c2SMark Johnston 
50990339a1c2SMark Johnston 			/* one byte immediate number */
51000339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
51010339a1c2SMark Johnston 			break;
51020339a1c2SMark Johnston 		}
51030339a1c2SMark Johnston 
51040339a1c2SMark Johnston 		x->d86_numopnds = 2;
51050339a1c2SMark Johnston 
51060339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
51070339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51080339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 1);
51090339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
51100339a1c2SMark Johnston 		break;
51110339a1c2SMark Johnston 
51120339a1c2SMark Johnston 	case VEX_RR:
51130339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
51140339a1c2SMark Johnston 		x->d86_numopnds = 2;
51150339a1c2SMark Johnston 
51160339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
51170339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51180339a1c2SMark Johnston 
51190339a1c2SMark Johnston 		if (dp == &dis_opAVX660F[0x7E]) {
51200339a1c2SMark Johnston 			/* vmovd/q <reg/mem 32/64>, <xmm> */
51210339a1c2SMark Johnston #ifdef DIS_TEXT
51220339a1c2SMark Johnston 			if (vex_W)
51230339a1c2SMark Johnston 				x->d86_mnem[4] = 'q';
51240339a1c2SMark Johnston #endif
51250339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 1);
51260339a1c2SMark Johnston 		} else
51270339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, wbit, 1);
51280339a1c2SMark Johnston 
51290339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
51300339a1c2SMark Johnston 		break;
51310339a1c2SMark Johnston 
51320339a1c2SMark Johnston 	case VEX_RRi:
51330339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg, imm) */
51340339a1c2SMark Johnston 		x->d86_numopnds = 3;
51350339a1c2SMark Johnston 
51360339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
51370339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51380339a1c2SMark Johnston 
51390339a1c2SMark Johnston #ifdef DIS_TEXT
51400339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x16]) {
51410339a1c2SMark Johnston 			/* vpextrd/q <imm>, <xmm>, <reg/mem 32/64> */
51420339a1c2SMark Johnston 			if (vex_W)
51430339a1c2SMark Johnston 				x->d86_mnem[6] = 'q';
51440339a1c2SMark Johnston 		}
51450339a1c2SMark Johnston #endif
51460339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
51470339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
51480339a1c2SMark Johnston 
51490339a1c2SMark Johnston 		/* one byte immediate number */
51500339a1c2SMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
51510339a1c2SMark Johnston 		break;
5152*b3b5bfebSMark Johnston 	case VEX_RIM:
5153*b3b5bfebSMark Johnston 		/* ModR/M.rm := op(ModR/M.reg, imm) */
5154*b3b5bfebSMark Johnston 		x->d86_numopnds = 3;
5155*b3b5bfebSMark Johnston 
5156*b3b5bfebSMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
5157*b3b5bfebSMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5158*b3b5bfebSMark Johnston 
5159*b3b5bfebSMark Johnston 		dtrace_get_operand(x, mode, r_m, XMM_OPND, 2);
5160*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
5161*b3b5bfebSMark Johnston 		/* one byte immediate number */
5162*b3b5bfebSMark Johnston 		dtrace_imm_opnd(x, wbit, 1, 0);
5163*b3b5bfebSMark Johnston 		break;
51640339a1c2SMark Johnston 
51650339a1c2SMark Johnston 	case VEX_RM:
51660339a1c2SMark Johnston 		/* ModR/M.rm := op(ModR/M.reg) */
51670339a1c2SMark Johnston 		if (dp == &dis_opAVX660F3A[0x17]) {	/* vextractps */
51680339a1c2SMark Johnston 			x->d86_numopnds = 3;
51690339a1c2SMark Johnston 
51700339a1c2SMark Johnston 			dtrace_get_modrm(x, &mode, &reg, &r_m);
51710339a1c2SMark Johnston 			dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51720339a1c2SMark Johnston 
51730339a1c2SMark Johnston 			dtrace_get_operand(x, mode, r_m, LONG_OPND, 2);
51740339a1c2SMark Johnston 			dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
51750339a1c2SMark Johnston 			/* one byte immediate number */
51760339a1c2SMark Johnston 			dtrace_imm_opnd(x, wbit, 1, 0);
51770339a1c2SMark Johnston 			break;
51780339a1c2SMark Johnston 		}
51790339a1c2SMark Johnston 		x->d86_numopnds = 2;
51800339a1c2SMark Johnston 
51810339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
51820339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51830339a1c2SMark Johnston L_VEX_RM:
51840339a1c2SMark Johnston 		vbit = 1;
51850339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, vbit);
51860339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit - 1);
51870339a1c2SMark Johnston 
51880339a1c2SMark Johnston 		break;
51890339a1c2SMark Johnston 
51900339a1c2SMark Johnston 	case VEX_RRM:
51910339a1c2SMark Johnston 		/* ModR/M.rm := op(VEX.vvvv, ModR/M.reg) */
51920339a1c2SMark Johnston 		x->d86_numopnds = 3;
51930339a1c2SMark Johnston 
51940339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
51950339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
51960339a1c2SMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 2);
51970339a1c2SMark Johnston 		/* VEX use the 1's complement form encode the XMM/YMM regs */
51980339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
51990339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 0);
52000339a1c2SMark Johnston 		break;
52010339a1c2SMark Johnston 
52020339a1c2SMark Johnston 	case VEX_RMX:
52030339a1c2SMark Johnston 		/* ModR/M.reg := op(VEX.vvvv, ModR/M.rm) */
52040339a1c2SMark Johnston 		x->d86_numopnds = 3;
52050339a1c2SMark Johnston 
52060339a1c2SMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
52070339a1c2SMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
52080339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 2);
52090339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
52100339a1c2SMark Johnston 		dtrace_get_operand(x, REG_ONLY, r_m, wbit, 0);
52110339a1c2SMark Johnston 		break;
52120339a1c2SMark Johnston 
52130339a1c2SMark Johnston 	case VEX_NONE:
52140339a1c2SMark Johnston #ifdef DIS_TEXT
52150339a1c2SMark Johnston 		if (vex_L)
52160339a1c2SMark Johnston 			(void) strncpy(x->d86_mnem, "vzeroall", OPLEN);
52170339a1c2SMark Johnston #endif
52180339a1c2SMark Johnston 		break;
5219*b3b5bfebSMark Johnston 	case BLS: {
5220*b3b5bfebSMark Johnston 
5221*b3b5bfebSMark Johnston 		/*
5222*b3b5bfebSMark Johnston 		 * The BLS instructions are VEX instructions that are based on
5223*b3b5bfebSMark Johnston 		 * VEX.0F38.F3; however, they are considered special group 17
5224*b3b5bfebSMark Johnston 		 * and like everything else, they use the bits in 3-5 of the
5225*b3b5bfebSMark Johnston 		 * MOD R/M to determine the sub instruction. Unlike many others
5226*b3b5bfebSMark Johnston 		 * like the VMX instructions, these are valid both for memory
5227*b3b5bfebSMark Johnston 		 * and register forms.
5228*b3b5bfebSMark Johnston 		 */
5229*b3b5bfebSMark Johnston 
5230*b3b5bfebSMark Johnston 		dtrace_get_modrm(x, &mode, &reg, &r_m);
5231*b3b5bfebSMark Johnston 		dtrace_vex_adjust(vex_byte1, mode, &reg, &r_m);
5232*b3b5bfebSMark Johnston 
5233*b3b5bfebSMark Johnston 		switch (reg) {
5234*b3b5bfebSMark Johnston 		case 1:
5235*b3b5bfebSMark Johnston #ifdef	DIS_TEXT
5236*b3b5bfebSMark Johnston 			blsinstr = "blsr";
5237*b3b5bfebSMark Johnston #endif
5238*b3b5bfebSMark Johnston 			break;
5239*b3b5bfebSMark Johnston 		case 2:
5240*b3b5bfebSMark Johnston #ifdef	DIS_TEXT
5241*b3b5bfebSMark Johnston 			blsinstr = "blsmsk";
5242*b3b5bfebSMark Johnston #endif
5243*b3b5bfebSMark Johnston 			break;
5244*b3b5bfebSMark Johnston 		case 3:
5245*b3b5bfebSMark Johnston #ifdef	DIS_TEXT
5246*b3b5bfebSMark Johnston 			blsinstr = "blsi";
5247*b3b5bfebSMark Johnston #endif
5248*b3b5bfebSMark Johnston 			break;
5249*b3b5bfebSMark Johnston 		default:
5250*b3b5bfebSMark Johnston 			goto error;
5251*b3b5bfebSMark Johnston 		}
5252*b3b5bfebSMark Johnston 
5253*b3b5bfebSMark Johnston 		x->d86_numopnds = 2;
5254*b3b5bfebSMark Johnston #ifdef DIS_TEXT
5255*b3b5bfebSMark Johnston 		(void) strncpy(x->d86_mnem, blsinstr, OPLEN);
5256*b3b5bfebSMark Johnston #endif
5257*b3b5bfebSMark Johnston 		dtrace_get_operand(x, REG_ONLY, (0xF - vex_v), wbit, 1);
5258*b3b5bfebSMark Johnston 		dtrace_get_operand(x, mode, r_m, wbit, 0);
5259*b3b5bfebSMark Johnston 		break;
5260*b3b5bfebSMark Johnston 	}
52610339a1c2SMark Johnston 	/* an invalid op code */
52620339a1c2SMark Johnston 	case AM:
52630339a1c2SMark Johnston 	case DM:
52640339a1c2SMark Johnston 	case OVERRIDE:
52650339a1c2SMark Johnston 	case PREFIX:
52660339a1c2SMark Johnston 	case UNKNOWN:
52670339a1c2SMark Johnston 		NOMEM;
52680339a1c2SMark Johnston 	default:
52690339a1c2SMark Johnston 		goto error;
52700339a1c2SMark Johnston 	} /* end switch */
52710339a1c2SMark Johnston 	if (x->d86_error)
52720339a1c2SMark Johnston 		goto error;
52730339a1c2SMark Johnston 
52740339a1c2SMark Johnston done:
52750339a1c2SMark Johnston #ifdef DIS_MEM
52760339a1c2SMark Johnston 	/*
52770339a1c2SMark Johnston 	 * compute the size of any memory accessed by the instruction
52780339a1c2SMark Johnston 	 */
52790339a1c2SMark Johnston 	if (x->d86_memsize != 0) {
52800339a1c2SMark Johnston 		return (0);
52810339a1c2SMark Johnston 	} else if (dp->it_stackop) {
52820339a1c2SMark Johnston 		switch (opnd_size) {
52830339a1c2SMark Johnston 		case SIZE16:
52840339a1c2SMark Johnston 			x->d86_memsize = 2;
52850339a1c2SMark Johnston 			break;
52860339a1c2SMark Johnston 		case SIZE32:
52870339a1c2SMark Johnston 			x->d86_memsize = 4;
52880339a1c2SMark Johnston 			break;
52890339a1c2SMark Johnston 		case SIZE64:
52900339a1c2SMark Johnston 			x->d86_memsize = 8;
52910339a1c2SMark Johnston 			break;
52920339a1c2SMark Johnston 		}
52930339a1c2SMark Johnston 	} else if (nomem || mode == REG_ONLY) {
52940339a1c2SMark Johnston 		x->d86_memsize = 0;
52950339a1c2SMark Johnston 
52960339a1c2SMark Johnston 	} else if (dp->it_size != 0) {
52970339a1c2SMark Johnston 		/*
52980339a1c2SMark Johnston 		 * In 64 bit mode descriptor table entries
52990339a1c2SMark Johnston 		 * go up to 10 bytes and popf/pushf are always 8 bytes
53000339a1c2SMark Johnston 		 */
53010339a1c2SMark Johnston 		if (x->d86_mode == SIZE64 && dp->it_size == 6)
53020339a1c2SMark Johnston 			x->d86_memsize = 10;
53030339a1c2SMark Johnston 		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
53040339a1c2SMark Johnston 		    (opcode2 == 0xc || opcode2 == 0xd))
53050339a1c2SMark Johnston 			x->d86_memsize = 8;
53060339a1c2SMark Johnston 		else
53070339a1c2SMark Johnston 			x->d86_memsize = dp->it_size;
53080339a1c2SMark Johnston 
53090339a1c2SMark Johnston 	} else if (wbit == 0) {
53100339a1c2SMark Johnston 		x->d86_memsize = 1;
53110339a1c2SMark Johnston 
53120339a1c2SMark Johnston 	} else if (wbit == LONG_OPND) {
53130339a1c2SMark Johnston 		if (opnd_size == SIZE64)
53140339a1c2SMark Johnston 			x->d86_memsize = 8;
53150339a1c2SMark Johnston 		else if (opnd_size == SIZE32)
53160339a1c2SMark Johnston 			x->d86_memsize = 4;
53170339a1c2SMark Johnston 		else
53180339a1c2SMark Johnston 			x->d86_memsize = 2;
53190339a1c2SMark Johnston 
53200339a1c2SMark Johnston 	} else if (wbit == SEG_OPND) {
53210339a1c2SMark Johnston 		x->d86_memsize = 4;
53220339a1c2SMark Johnston 
53230339a1c2SMark Johnston 	} else {
53240339a1c2SMark Johnston 		x->d86_memsize = 8;
53250339a1c2SMark Johnston 	}
53260339a1c2SMark Johnston #endif
53270339a1c2SMark Johnston 	return (0);
53280339a1c2SMark Johnston 
53290339a1c2SMark Johnston error:
53300339a1c2SMark Johnston #ifdef DIS_TEXT
53310339a1c2SMark Johnston 	(void) strlcat(x->d86_mnem, "undef", OPLEN);
53320339a1c2SMark Johnston #endif
53330339a1c2SMark Johnston 	return (1);
53340339a1c2SMark Johnston }
53350339a1c2SMark Johnston 
53360339a1c2SMark Johnston #ifdef DIS_TEXT
53370339a1c2SMark Johnston 
53380339a1c2SMark Johnston /*
53390339a1c2SMark Johnston  * Some instructions should have immediate operands printed
53400339a1c2SMark Johnston  * as unsigned integers. We compare against this table.
53410339a1c2SMark Johnston  */
53420339a1c2SMark Johnston static char *unsigned_ops[] = {
53430339a1c2SMark Johnston 	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
53440339a1c2SMark Johnston 	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
53450339a1c2SMark Johnston 	0
53460339a1c2SMark Johnston };
53470339a1c2SMark Johnston 
53480339a1c2SMark Johnston 
53490339a1c2SMark Johnston static int
53500339a1c2SMark Johnston isunsigned_op(char *opcode)
53510339a1c2SMark Johnston {
53520339a1c2SMark Johnston 	char *where;
53530339a1c2SMark Johnston 	int i;
53540339a1c2SMark Johnston 	int is_unsigned = 0;
53550339a1c2SMark Johnston 
53560339a1c2SMark Johnston 	/*
53570339a1c2SMark Johnston 	 * Work back to start of last mnemonic, since we may have
53580339a1c2SMark Johnston 	 * prefixes on some opcodes.
53590339a1c2SMark Johnston 	 */
53600339a1c2SMark Johnston 	where = opcode + strlen(opcode) - 1;
53610339a1c2SMark Johnston 	while (where > opcode && *where != ' ')
53620339a1c2SMark Johnston 		--where;
53630339a1c2SMark Johnston 	if (*where == ' ')
53640339a1c2SMark Johnston 		++where;
53650339a1c2SMark Johnston 
53660339a1c2SMark Johnston 	for (i = 0; unsigned_ops[i]; ++i) {
53670339a1c2SMark Johnston 		if (strncmp(where, unsigned_ops[i],
53680339a1c2SMark Johnston 		    strlen(unsigned_ops[i])))
53690339a1c2SMark Johnston 			continue;
53700339a1c2SMark Johnston 		is_unsigned = 1;
53710339a1c2SMark Johnston 		break;
53720339a1c2SMark Johnston 	}
53730339a1c2SMark Johnston 	return (is_unsigned);
53740339a1c2SMark Johnston }
53750339a1c2SMark Johnston 
53760339a1c2SMark Johnston /*
53770339a1c2SMark Johnston  * Print a numeric immediate into end of buf, maximum length buflen.
53780339a1c2SMark Johnston  * The immediate may be an address or a displacement.  Mask is set
53790339a1c2SMark Johnston  * for address size.  If the immediate is a "small negative", or
53800339a1c2SMark Johnston  * if it's a negative displacement of any magnitude, print as -<absval>.
53810339a1c2SMark Johnston  * Respect the "octal" flag.  "Small negative" is defined as "in the
53820339a1c2SMark Johnston  * interval [NEG_LIMIT, 0)".
53830339a1c2SMark Johnston  *
53840339a1c2SMark Johnston  * Also, "isunsigned_op()" instructions never print negatives.
53850339a1c2SMark Johnston  *
53860339a1c2SMark Johnston  * Return whether we decided to print a negative value or not.
53870339a1c2SMark Johnston  */
53880339a1c2SMark Johnston 
53890339a1c2SMark Johnston #define	NEG_LIMIT	-255
53900339a1c2SMark Johnston enum {IMM, DISP};
53910339a1c2SMark Johnston enum {POS, TRY_NEG};
53920339a1c2SMark Johnston 
53930339a1c2SMark Johnston static int
53940339a1c2SMark Johnston print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
53950339a1c2SMark Johnston     size_t buflen, int disp, int try_neg)
53960339a1c2SMark Johnston {
53970339a1c2SMark Johnston 	int curlen;
53980339a1c2SMark Johnston 	int64_t sv = (int64_t)usv;
53990339a1c2SMark Johnston 	int octal = dis->d86_flags & DIS_F_OCTAL;
54000339a1c2SMark Johnston 
54010339a1c2SMark Johnston 	curlen = strlen(buf);
54020339a1c2SMark Johnston 
54030339a1c2SMark Johnston 	if (try_neg == TRY_NEG && sv < 0 &&
54040339a1c2SMark Johnston 	    (disp || sv >= NEG_LIMIT) &&
54050339a1c2SMark Johnston 	    !isunsigned_op(dis->d86_mnem)) {
54060339a1c2SMark Johnston 		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
54070339a1c2SMark Johnston 		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
54080339a1c2SMark Johnston 		return (1);
54090339a1c2SMark Johnston 	} else {
54100339a1c2SMark Johnston 		if (disp == DISP)
54110339a1c2SMark Johnston 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
54120339a1c2SMark Johnston 			    octal ? "+0%llo" : "+0x%llx", usv & mask);
54130339a1c2SMark Johnston 		else
54140339a1c2SMark Johnston 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
54150339a1c2SMark Johnston 			    octal ? "0%llo" : "0x%llx", usv & mask);
54160339a1c2SMark Johnston 		return (0);
54170339a1c2SMark Johnston 
54180339a1c2SMark Johnston 	}
54190339a1c2SMark Johnston }
54200339a1c2SMark Johnston 
54210339a1c2SMark Johnston 
54220339a1c2SMark Johnston static int
54230339a1c2SMark Johnston log2(int size)
54240339a1c2SMark Johnston {
54250339a1c2SMark Johnston 	switch (size) {
54260339a1c2SMark Johnston 	case 1: return (0);
54270339a1c2SMark Johnston 	case 2: return (1);
54280339a1c2SMark Johnston 	case 4: return (2);
54290339a1c2SMark Johnston 	case 8: return (3);
54300339a1c2SMark Johnston 	}
54310339a1c2SMark Johnston 	return (0);
54320339a1c2SMark Johnston }
54330339a1c2SMark Johnston 
54340339a1c2SMark Johnston /* ARGSUSED */
54350339a1c2SMark Johnston void
54360339a1c2SMark Johnston dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
54370339a1c2SMark Johnston     size_t buflen)
54380339a1c2SMark Johnston {
54390339a1c2SMark Johnston 	uint64_t reltgt = 0;
54400339a1c2SMark Johnston 	uint64_t tgt = 0;
54410339a1c2SMark Johnston 	int curlen;
54420339a1c2SMark Johnston 	int (*lookup)(void *, uint64_t, char *, size_t);
54430339a1c2SMark Johnston 	int i;
54440339a1c2SMark Johnston 	int64_t sv;
54450339a1c2SMark Johnston 	uint64_t usv, mask, save_mask, save_usv;
54460339a1c2SMark Johnston 	static uint64_t masks[] =
54470339a1c2SMark Johnston 	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
54480339a1c2SMark Johnston 	save_usv = 0;
54490339a1c2SMark Johnston 
54500339a1c2SMark Johnston 	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
54510339a1c2SMark Johnston 
54520339a1c2SMark Johnston 	/*
54530339a1c2SMark Johnston 	 * For PC-relative jumps, the pc is really the next pc after executing
54540339a1c2SMark Johnston 	 * this instruction, so increment it appropriately.
54550339a1c2SMark Johnston 	 */
54560339a1c2SMark Johnston 	pc += dis->d86_len;
54570339a1c2SMark Johnston 
54580339a1c2SMark Johnston 	for (i = 0; i < dis->d86_numopnds; i++) {
54590339a1c2SMark Johnston 		d86opnd_t *op = &dis->d86_opnd[i];
54600339a1c2SMark Johnston 
54610339a1c2SMark Johnston 		if (i != 0)
54620339a1c2SMark Johnston 			(void) strlcat(buf, ",", buflen);
54630339a1c2SMark Johnston 
54640339a1c2SMark Johnston 		(void) strlcat(buf, op->d86_prefix, buflen);
54650339a1c2SMark Johnston 
54660339a1c2SMark Johnston 		/*
54670339a1c2SMark Johnston 		 * sv is for the signed, possibly-truncated immediate or
54680339a1c2SMark Johnston 		 * displacement; usv retains the original size and
54690339a1c2SMark Johnston 		 * unsignedness for symbol lookup.
54700339a1c2SMark Johnston 		 */
54710339a1c2SMark Johnston 
54720339a1c2SMark Johnston 		sv = usv = op->d86_value;
54730339a1c2SMark Johnston 
54740339a1c2SMark Johnston 		/*
54750339a1c2SMark Johnston 		 * About masks: for immediates that represent
54760339a1c2SMark Johnston 		 * addresses, the appropriate display size is
54770339a1c2SMark Johnston 		 * the effective address size of the instruction.
54780339a1c2SMark Johnston 		 * This includes MODE_OFFSET, MODE_IPREL, and
54790339a1c2SMark Johnston 		 * MODE_RIPREL.  Immediates that are simply
54800339a1c2SMark Johnston 		 * immediate values should display in the operand's
54810339a1c2SMark Johnston 		 * size, however, since they don't represent addresses.
54820339a1c2SMark Johnston 		 */
54830339a1c2SMark Johnston 
54840339a1c2SMark Johnston 		/* d86_addr_size is SIZEnn, which is log2(real size) */
54850339a1c2SMark Johnston 		mask = masks[dis->d86_addr_size];
54860339a1c2SMark Johnston 
54870339a1c2SMark Johnston 		/* d86_value_size and d86_imm_bytes are in bytes */
54880339a1c2SMark Johnston 		if (op->d86_mode == MODE_SIGNED ||
54890339a1c2SMark Johnston 		    op->d86_mode == MODE_IMPLIED)
54900339a1c2SMark Johnston 			mask = masks[log2(op->d86_value_size)];
54910339a1c2SMark Johnston 
54920339a1c2SMark Johnston 		switch (op->d86_mode) {
54930339a1c2SMark Johnston 
54940339a1c2SMark Johnston 		case MODE_NONE:
54950339a1c2SMark Johnston 
54960339a1c2SMark Johnston 			(void) strlcat(buf, op->d86_opnd, buflen);
54970339a1c2SMark Johnston 			break;
54980339a1c2SMark Johnston 
54990339a1c2SMark Johnston 		case MODE_SIGNED:
55000339a1c2SMark Johnston 		case MODE_IMPLIED:
55010339a1c2SMark Johnston 		case MODE_OFFSET:
55020339a1c2SMark Johnston 
55030339a1c2SMark Johnston 			tgt = usv;
55040339a1c2SMark Johnston 
55050339a1c2SMark Johnston 			if (dis->d86_seg_prefix)
55060339a1c2SMark Johnston 				(void) strlcat(buf, dis->d86_seg_prefix,
55070339a1c2SMark Johnston 				    buflen);
55080339a1c2SMark Johnston 
55090339a1c2SMark Johnston 			if (op->d86_mode == MODE_SIGNED ||
55100339a1c2SMark Johnston 			    op->d86_mode == MODE_IMPLIED) {
55110339a1c2SMark Johnston 				(void) strlcat(buf, "$", buflen);
55120339a1c2SMark Johnston 			}
55130339a1c2SMark Johnston 
55140339a1c2SMark Johnston 			if (print_imm(dis, usv, mask, buf, buflen,
55150339a1c2SMark Johnston 			    IMM, TRY_NEG) &&
55160339a1c2SMark Johnston 			    (op->d86_mode == MODE_SIGNED ||
55170339a1c2SMark Johnston 			    op->d86_mode == MODE_IMPLIED)) {
55180339a1c2SMark Johnston 
55190339a1c2SMark Johnston 				/*
55200339a1c2SMark Johnston 				 * We printed a negative value for an
55210339a1c2SMark Johnston 				 * immediate that wasn't a
55220339a1c2SMark Johnston 				 * displacement.  Note that fact so we can
55230339a1c2SMark Johnston 				 * print the positive value as an
55240339a1c2SMark Johnston 				 * annotation.
55250339a1c2SMark Johnston 				 */
55260339a1c2SMark Johnston 
55270339a1c2SMark Johnston 				save_usv = usv;
55280339a1c2SMark Johnston 				save_mask = mask;
55290339a1c2SMark Johnston 			}
55300339a1c2SMark Johnston 			(void) strlcat(buf, op->d86_opnd, buflen);
55310339a1c2SMark Johnston 
55320339a1c2SMark Johnston 			break;
55330339a1c2SMark Johnston 
55340339a1c2SMark Johnston 		case MODE_IPREL:
55350339a1c2SMark Johnston 		case MODE_RIPREL:
55360339a1c2SMark Johnston 
55370339a1c2SMark Johnston 			reltgt = pc + sv;
55380339a1c2SMark Johnston 
55390339a1c2SMark Johnston 			switch (mode) {
55400339a1c2SMark Johnston 			case SIZE16:
55410339a1c2SMark Johnston 				reltgt = (uint16_t)reltgt;
55420339a1c2SMark Johnston 				break;
55430339a1c2SMark Johnston 			case SIZE32:
55440339a1c2SMark Johnston 				reltgt = (uint32_t)reltgt;
55450339a1c2SMark Johnston 				break;
55460339a1c2SMark Johnston 			}
55470339a1c2SMark Johnston 
55480339a1c2SMark Johnston 			(void) print_imm(dis, usv, mask, buf, buflen,
55490339a1c2SMark Johnston 			    DISP, TRY_NEG);
55500339a1c2SMark Johnston 
55510339a1c2SMark Johnston 			if (op->d86_mode == MODE_RIPREL)
55520339a1c2SMark Johnston 				(void) strlcat(buf, "(%rip)", buflen);
55530339a1c2SMark Johnston 			break;
55540339a1c2SMark Johnston 		}
55550339a1c2SMark Johnston 	}
55560339a1c2SMark Johnston 
55570339a1c2SMark Johnston 	/*
55580339a1c2SMark Johnston 	 * The symbol lookups may result in false positives,
55590339a1c2SMark Johnston 	 * particularly on object files, where small numbers may match
55600339a1c2SMark Johnston 	 * the 0-relative non-relocated addresses of symbols.
55610339a1c2SMark Johnston 	 */
55620339a1c2SMark Johnston 
55630339a1c2SMark Johnston 	lookup = dis->d86_sym_lookup;
55640339a1c2SMark Johnston 	if (tgt != 0) {
55650339a1c2SMark Johnston 		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
55660339a1c2SMark Johnston 		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
55670339a1c2SMark Johnston 			(void) strlcat(buf, "\t<", buflen);
55680339a1c2SMark Johnston 			curlen = strlen(buf);
55690339a1c2SMark Johnston 			lookup(dis->d86_data, tgt, buf + curlen,
55700339a1c2SMark Johnston 			    buflen - curlen);
55710339a1c2SMark Johnston 			(void) strlcat(buf, ">", buflen);
55720339a1c2SMark Johnston 		}
55730339a1c2SMark Johnston 
55740339a1c2SMark Johnston 		/*
55750339a1c2SMark Johnston 		 * If we printed a negative immediate above, print the
55760339a1c2SMark Johnston 		 * positive in case our heuristic was unhelpful
55770339a1c2SMark Johnston 		 */
55780339a1c2SMark Johnston 		if (save_usv) {
55790339a1c2SMark Johnston 			(void) strlcat(buf, "\t<", buflen);
55800339a1c2SMark Johnston 			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
55810339a1c2SMark Johnston 			    IMM, POS);
55820339a1c2SMark Johnston 			(void) strlcat(buf, ">", buflen);
55830339a1c2SMark Johnston 		}
55840339a1c2SMark Johnston 	}
55850339a1c2SMark Johnston 
55860339a1c2SMark Johnston 	if (reltgt != 0) {
55870339a1c2SMark Johnston 		/* Print symbol or effective address for reltgt */
55880339a1c2SMark Johnston 
55890339a1c2SMark Johnston 		(void) strlcat(buf, "\t<", buflen);
55900339a1c2SMark Johnston 		curlen = strlen(buf);
55910339a1c2SMark Johnston 		lookup(dis->d86_data, reltgt, buf + curlen,
55920339a1c2SMark Johnston 		    buflen - curlen);
55930339a1c2SMark Johnston 		(void) strlcat(buf, ">", buflen);
55940339a1c2SMark Johnston 	}
55950339a1c2SMark Johnston }
55960339a1c2SMark Johnston 
55970339a1c2SMark Johnston #endif /* DIS_TEXT */
5598