Home | History | Annotate | Download | only in i386
      1 /*
      2  *
      3  * CDDL HEADER START
      4  *
      5  * The contents of this file are subject to the terms of the
      6  * Common Development and Distribution License (the "License").
      7  * You may not use this file except in compliance with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1988 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 
     31 #include	"dis_tables.h"
     32 
     33 /* BEGIN CSTYLED */
     34 
     35 /*
     36  * Disassembly begins in dis_distable, which is equivalent to the One-byte
     37  * Opcode Map in the Intel IA32 ISA Reference (page A-6 in my copy).  The
     38  * decoding loops then traverse out through the other tables as necessary to
     39  * decode a given instruction.
     40  *
     41  * The behavior of this file can be controlled by one of the following flags:
     42  *
     43  * 	DIS_TEXT	Include text for disassembly
     44  * 	DIS_MEM		Include memory-size calculations
     45  *
     46  * Either or both of these can be defined.
     47  *
     48  * This file is not, and will never be, cstyled.  If anything, the tables should
     49  * be taken out another tab stop or two so nothing overlaps.
     50  */
     51 
     52 /*
     53  * These functions must be provided for the consumer to do disassembly.
     54  */
     55 #ifdef DIS_TEXT
     56 extern char *strncpy(char *, const char *, size_t);
     57 extern size_t strlen(const char *);
     58 extern int strcmp(const char *, const char *);
     59 extern int strncmp(const char *, const char *, size_t);
     60 extern size_t strlcat(char *, const char *, size_t);
     61 #endif
     62 
     63 
     64 #define		TERM 	0	/* used to indicate that the 'indirect' */
     65 				/* field terminates - no pointer.	*/
     66 
     67 /* Used to decode instructions. */
     68 typedef struct	instable {
     69 	struct instable	*it_indirect;	/* for decode op codes */
     70 	uchar_t		it_adrmode;
     71 #ifdef DIS_TEXT
     72 	char		it_name[NCPS];
     73 	uint_t		it_suffix:1;		/* mnem + "w", "l", or "d" */
     74 #endif
     75 #ifdef DIS_MEM
     76 	uint_t		it_size:16;
     77 #endif
     78 	uint_t		it_invalid64:1;		/* opcode invalid in amd64 */
     79 	uint_t		it_always64:1;		/* 64 bit when in 64 bit mode */
     80 	uint_t		it_invalid32:1;		/* invalid in IA32 */
     81 	uint_t		it_stackop:1;		/* push/pop stack operation */
     82 } instable_t;
     83 
     84 /*
     85  * Instruction formats.
     86  */
     87 enum {
     88 	UNKNOWN,
     89 	MRw,
     90 	IMlw,
     91 	IMw,
     92 	IR,
     93 	OA,
     94 	AO,
     95 	MS,
     96 	SM,
     97 	Mv,
     98 	Mw,
     99 	M,		/* register or memory */
    100 	Mb,		/* register or memory, always byte sized */
    101 	MO,		/* memory only (no registers) */
    102 	PREF,
    103 	SWAPGS,
    104 	MONITOR_MWAIT,
    105 	R,
    106 	RA,
    107 	SEG,
    108 	MR,
    109 	RM,
    110 	IA,
    111 	MA,
    112 	SD,
    113 	AD,
    114 	SA,
    115 	D,
    116 	INM,
    117 	SO,
    118 	BD,
    119 	I,
    120 	P,
    121 	V,
    122 	DSHIFT,		/* for double shift that has an 8-bit immediate */
    123 	U,
    124 	OVERRIDE,
    125 	NORM,		/* instructions w/o ModR/M byte, no memory access */
    126 	IMPLMEM,	/* instructions w/o ModR/M byte, implicit mem access */
    127 	O,		/* for call	*/
    128 	JTAB,		/* jump table 	*/
    129 	IMUL,		/* for 186 iimul instr  */
    130 	CBW,		/* so data16 can be evaluated for cbw and variants */
    131 	MvI,		/* for 186 logicals */
    132 	ENTER,		/* for 186 enter instr  */
    133 	RMw,		/* for 286 arpl instr */
    134 	Ib,		/* for push immediate byte */
    135 	F,		/* for 287 instructions */
    136 	FF,		/* for 287 instructions */
    137 	FFC,		/* for 287 instructions */
    138 	DM,		/* 16-bit data */
    139 	AM,		/* 16-bit addr */
    140 	LSEG,		/* for 3-bit seg reg encoding */
    141 	MIb,		/* for 386 logicals */
    142 	SREG,		/* for 386 special registers */
    143 	PREFIX,		/* a REP instruction prefix */
    144 	LOCK,		/* a LOCK instruction prefix */
    145 	INT3,		/* The int 3 instruction, which has a fake operand */
    146 	INTx,		/* The normal int instruction, with explicit int num */
    147 	DSHIFTcl,	/* for double shift that implicitly uses %cl */
    148 	CWD,		/* so data16 can be evaluated for cwd and variants */
    149 	RET,		/* single immediate 16-bit operand */
    150 	MOVZ,		/* for movs and movz, with different size operands */
    151 	CRC32,		/* for crc32, with different size operands */
    152 	XADDB,		/* for xaddb */
    153 	MOVSXZ,		/* AMD64 mov sign extend 32 to 64 bit instruction */
    154 	MOVBE,		/* movbe instruction */
    155 
    156 /*
    157  * MMX/SIMD addressing modes.
    158  */
    159 
    160 	MMO,		/* Prefixable MMX/SIMD-Int	mm/mem	-> mm */
    161 	MMOIMPL,	/* Prefixable MMX/SIMD-Int	mm	-> mm (mem) */
    162 	MMO3P,		/* Prefixable MMX/SIMD-Int	mm	-> r32,imm8 */
    163 	MMOM3,		/* Prefixable MMX/SIMD-Int	mm	-> r32 	*/
    164 	MMOS,		/* Prefixable MMX/SIMD-Int	mm	-> mm/mem */
    165 	MMOMS,		/* Prefixable MMX/SIMD-Int	mm	-> mem */
    166 	MMOPM,		/* MMX/SIMD-Int			mm/mem	-> mm,imm8 */
    167 	MMOPM_66o,	/* MMX/SIMD-Int 0x66 optional	mm/mem	-> mm,imm8 */
    168 	MMOPRM,		/* Prefixable MMX/SIMD-Int	r32/mem	-> mm,imm8 */
    169 	MMOSH,		/* Prefixable MMX		mm,imm8	*/
    170 	MM,		/* MMX/SIMD-Int			mm/mem	-> mm	*/
    171 	MMS,		/* MMX/SIMD-Int			mm	-> mm/mem */
    172 	MMSH,		/* MMX				mm,imm8 */
    173 	XMMO,		/* Prefixable SIMD		xmm/mem	-> xmm */
    174 	XMMOS,		/* Prefixable SIMD		xmm	-> xmm/mem */
    175 	XMMOPM,		/* Prefixable SIMD		xmm/mem	w/to xmm,imm8 */
    176 	XMMOMX,		/* Prefixable SIMD		mm/mem	-> xmm */
    177 	XMMOX3,		/* Prefixable SIMD		xmm	-> r32 */
    178 	XMMOXMM,	/* Prefixable SIMD		xmm/mem	-> mm	*/
    179 	XMMOM,		/* Prefixable SIMD		xmm	-> mem */
    180 	XMMOMS,		/* Prefixable SIMD		mem	-> xmm */
    181 	XMM,		/* SIMD 			xmm/mem	-> xmm */
    182 	XMM_66r,	/* SIMD 0x66 prefix required	xmm/mem	-> xmm */
    183 	XMM_66o,	/* SIMD 0x66 prefix optional 	xmm/mem	-> xmm */
    184 	XMMXIMPL,	/* SIMD				xmm	-> xmm (mem) */
    185 	XMM3P,		/* SIMD				xmm	-> r32,imm8 */
    186 	XMM3PM_66r,	/* SIMD 0x66 prefix required	xmm	-> r32/mem,imm8 */
    187 	XMMP,		/* SIMD 			xmm/mem w/to xmm,imm8 */
    188 	XMMP_66o,	/* SIMD 0x66 prefix optional	xmm/mem w/to xmm,imm8 */
    189 	XMMP_66r,	/* SIMD 0x66 prefix required	xmm/mem w/to xmm,imm8 */
    190 	XMMPRM,		/* SIMD 			r32/mem -> xmm,imm8 */
    191 	XMMPRM_66r,	/* SIMD 0x66 prefix required	r32/mem -> xmm,imm8 */
    192 	XMMS,		/* SIMD				xmm	-> xmm/mem */
    193 	XMMM,		/* SIMD 			mem	-> xmm */
    194 	XMMM_66r,	/* SIMD	0x66 prefix required	mem	-> xmm */
    195 	XMMMS,		/* SIMD				xmm	-> mem */
    196 	XMM3MX,		/* SIMD 			r32/mem -> xmm */
    197 	XMM3MXS,	/* SIMD 			xmm	-> r32/mem */
    198 	XMMSH,		/* SIMD 			xmm,imm8 */
    199 	XMMXM3,		/* SIMD 			xmm/mem -> r32 */
    200 	XMMX3,		/* SIMD 			xmm	-> r32 */
    201 	XMMXMM,		/* SIMD 			xmm/mem	-> mm */
    202 	XMMMX,		/* SIMD 			mm	-> xmm */
    203 	XMMXM,		/* SIMD 			xmm	-> mm */
    204         XMMX2I,		/* SIMD				xmm -> xmm, imm, imm */
    205         XMM2I,		/* SIMD				xmm, imm, imm */
    206 	XMMFENCE,	/* SIMD lfence or mfence */
    207 	XMMSFNC		/* SIMD sfence (none or mem) */
    208 };
    209 
    210 #define	FILL	0x90	/* Fill byte used for alignment (nop)	*/
    211 
    212 /*
    213 ** Register numbers for the i386
    214 */
    215 #define	EAX_REGNO 0
    216 #define	ECX_REGNO 1
    217 #define	EDX_REGNO 2
    218 #define	EBX_REGNO 3
    219 #define	ESP_REGNO 4
    220 #define	EBP_REGNO 5
    221 #define	ESI_REGNO 6
    222 #define	EDI_REGNO 7
    223 
    224 /*
    225  * modes for immediate values
    226  */
    227 #define	MODE_NONE	0
    228 #define	MODE_IPREL	1	/* signed IP relative value */
    229 #define	MODE_SIGNED	2	/* sign extended immediate */
    230 #define	MODE_IMPLIED	3	/* constant value implied from opcode */
    231 #define	MODE_OFFSET	4	/* offset part of an address */
    232 #define	MODE_RIPREL	5	/* like IPREL, but from %rip (amd64) */
    233 
    234 /*
    235  * The letters used in these macros are:
    236  *   IND - indirect to another to another table
    237  *   "T" - means to Terminate indirections (this is the final opcode)
    238  *   "S" - means "operand length suffix required"
    239  *   "NS" - means "no suffix" which is the operand length suffix of the opcode
    240  *   "Z" - means instruction size arg required
    241  *   "u" - means the opcode is invalid in IA32 but valid in amd64
    242  *   "x" - means the opcode is invalid in amd64, but not IA32
    243  *   "y" - means the operand size is always 64 bits in 64 bit mode
    244  *   "p" - means push/pop stack operation
    245  */
    246 
    247 #if defined(DIS_TEXT) && defined(DIS_MEM)
    248 #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0, 0}
    249 #define	INDx(table)		{(instable_t *)table, 0, "", 0, 0, 1, 0, 0, 0}
    250 #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0, 0}
    251 #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 1, 0}
    252 #define	TNSx(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0, 0}
    253 #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 0}
    254 #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0, 1}
    255 #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 0, 0, 0}
    256 #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, sz, 0, 1, 0, 0}
    257 #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0, 0}
    258 #define	TSx(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0, 0}
    259 #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 0, 1, 0, 0}
    260 #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 0, 1}
    261 #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 0, 0, 0}
    262 #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, sz, 1, 0, 0, 0}
    263 #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, sz, 0, 1, 0, 0}
    264 #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
    265 #elif defined(DIS_TEXT)
    266 #define	IND(table)		{(instable_t *)table, 0, "", 0, 0, 0, 0, 0}
    267 #define	INDx(table)		{(instable_t *)table, 0, "", 0, 1, 0, 0, 0}
    268 #define	TNS(name, amode)	{TERM, amode, name, 0, 0, 0, 0, 0}
    269 #define	TNSu(name, amode)	{TERM, amode, name, 0, 0, 0, 1, 0}
    270 #define	TNSx(name, amode)	{TERM, amode, name, 0, 1, 0, 0, 0}
    271 #define	TNSy(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 0}
    272 #define	TNSyp(name, amode)	{TERM, amode, name, 0, 0, 1, 0, 1}
    273 #define	TNSZ(name, amode, sz)	{TERM, amode, name, 0, 0, 0, 0, 0}
    274 #define	TNSZy(name, amode, sz)	{TERM, amode, name, 0, 0, 1, 0, 0}
    275 #define	TS(name, amode)		{TERM, amode, name, 1, 0, 0, 0, 0}
    276 #define	TSx(name, amode)	{TERM, amode, name, 1, 1, 0, 0, 0}
    277 #define	TSy(name, amode)	{TERM, amode, name, 1, 0, 1, 0, 0}
    278 #define	TSp(name, amode)	{TERM, amode, name, 1, 0, 0, 0, 1}
    279 #define	TSZ(name, amode, sz)	{TERM, amode, name, 1, 0, 0, 0, 0}
    280 #define	TSZx(name, amode, sz)	{TERM, amode, name, 1, 1, 0, 0, 0}
    281 #define	TSZy(name, amode, sz)	{TERM, amode, name, 1, 0, 1, 0, 0}
    282 #define	INVALID			{TERM, UNKNOWN, "", 0, 0, 0, 0, 0}
    283 #elif defined(DIS_MEM)
    284 #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0, 0}
    285 #define	INDx(table)		{(instable_t *)table, 0, 0, 1, 0, 0, 0}
    286 #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0, 0}
    287 #define	TNSu(name, amode)	{TERM, amode,  0, 0, 0, 1, 0}
    288 #define	TNSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
    289 #define	TNSyp(name, amode)	{TERM, amode,  0, 0, 1, 0, 1}
    290 #define	TNSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
    291 #define	TNSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
    292 #define	TNSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
    293 #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0, 0}
    294 #define	TSx(name, amode)	{TERM, amode,  0, 1, 0, 0, 0}
    295 #define	TSy(name, amode)	{TERM, amode,  0, 0, 1, 0, 0}
    296 #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 0, 1}
    297 #define	TSZ(name, amode, sz)	{TERM, amode, sz, 0, 0, 0, 0}
    298 #define	TSZx(name, amode, sz)	{TERM, amode, sz, 1, 0, 0, 0}
    299 #define	TSZy(name, amode, sz)	{TERM, amode, sz, 0, 1, 0, 0}
    300 #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0, 0}
    301 #else
    302 #define	IND(table)		{(instable_t *)table, 0, 0, 0, 0, 0}
    303 #define	INDx(table)		{(instable_t *)table, 0, 1, 0, 0, 0}
    304 #define	TNS(name, amode)	{TERM, amode,  0, 0, 0, 0}
    305 #define	TNSu(name, amode)	{TERM, amode,  0, 0, 1, 0}
    306 #define	TNSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
    307 #define	TNSyp(name, amode)	{TERM, amode,  0, 1, 0, 1}
    308 #define	TNSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
    309 #define	TNSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
    310 #define	TNSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
    311 #define	TS(name, amode)		{TERM, amode,  0, 0, 0, 0}
    312 #define	TSx(name, amode)	{TERM, amode,  1, 0, 0, 0}
    313 #define	TSy(name, amode)	{TERM, amode,  0, 1, 0, 0}
    314 #define	TSp(name, amode)	{TERM, amode,  0, 0, 0, 1}
    315 #define	TSZ(name, amode, sz)	{TERM, amode,  0, 0, 0, 0}
    316 #define	TSZx(name, amode, sz)	{TERM, amode,  1, 0, 0, 0}
    317 #define	TSZy(name, amode, sz)	{TERM, amode,  0, 1, 0, 0}
    318 #define	INVALID			{TERM, UNKNOWN, 0, 0, 0, 0}
    319 #endif
    320 
    321 #ifdef DIS_TEXT
    322 /*
    323  * this decodes the r_m field for mode's 0, 1, 2 in 16 bit mode
    324  */
    325 const char *const dis_addr16[3][8] = {
    326 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "",
    327 									"(%bx)",
    328 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di", "(%bp)",
    329 									"(%bx)",
    330 "(%bx,%si)", "(%bx,%di)", "(%bp,%si)", "(%bp,%di)", "(%si)", "(%di)", "(%bp)",
    331 									"(%bx)",
    332 };
    333 
    334 
    335 /*
    336  * This decodes 32 bit addressing mode r_m field for modes 0, 1, 2
    337  */
    338 const char *const dis_addr32_mode0[16] = {
    339   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "",        "(%esi)",  "(%edi)",
    340   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "",        "(%r14d)", "(%r15d)"
    341 };
    342 
    343 const char *const dis_addr32_mode12[16] = {
    344   "(%eax)", "(%ecx)", "(%edx)",  "(%ebx)",  "", "(%ebp)",  "(%esi)",  "(%edi)",
    345   "(%r8d)", "(%r9d)", "(%r10d)", "(%r11d)", "", "(%r13d)", "(%r14d)", "(%r15d)"
    346 };
    347 
    348 /*
    349  * This decodes 64 bit addressing mode r_m field for modes 0, 1, 2
    350  */
    351 const char *const dis_addr64_mode0[16] = {
    352  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rip)", "(%rsi)", "(%rdi)",
    353  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%rip)", "(%r14)", "(%r15)"
    354 };
    355 const char *const dis_addr64_mode12[16] = {
    356  "(%rax)", "(%rcx)", "(%rdx)", "(%rbx)", "",       "(%rbp)", "(%rsi)", "(%rdi)",
    357  "(%r8)",  "(%r9)",  "(%r10)", "(%r11)", "(%r12)", "(%r13)", "(%r14)", "(%r15)"
    358 };
    359 
    360 /*
    361  * decode for scale from SIB byte
    362  */
    363 const char *const dis_scale_factor[4] = { ")", ",2)", ",4)", ",8)" };
    364 
    365 /*
    366  * register decoding for normal references to registers (ie. not addressing)
    367  */
    368 const char *const dis_REG8[16] = {
    369 	"%al",  "%cl",  "%dl",   "%bl",   "%ah",   "%ch",   "%dh",   "%bh",
    370 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
    371 };
    372 
    373 const char *const dis_REG8_REX[16] = {
    374 	"%al",  "%cl",  "%dl",   "%bl",   "%spl",  "%bpl",  "%sil",  "%dil",
    375 	"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
    376 };
    377 
    378 const char *const dis_REG16[16] = {
    379 	"%ax",  "%cx",  "%dx",   "%bx",   "%sp",   "%bp",   "%si",   "%di",
    380 	"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
    381 };
    382 
    383 const char *const dis_REG32[16] = {
    384 	"%eax", "%ecx", "%edx",  "%ebx",  "%esp",  "%ebp",  "%esi",  "%edi",
    385 	"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
    386 };
    387 
    388 const char *const dis_REG64[16] = {
    389 	"%rax", "%rcx", "%rdx",  "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
    390 	"%r8",  "%r9",  "%r10",  "%r11", "%r12", "%r13", "%r14", "%r15"
    391 };
    392 
    393 const char *const dis_DEBUGREG[16] = {
    394 	"%db0", "%db1", "%db2",  "%db3",  "%db4",  "%db5",  "%db6",  "%db7",
    395 	"%db8", "%db9", "%db10", "%db11", "%db12", "%db13", "%db14", "%db15"
    396 };
    397 
    398 const char *const dis_CONTROLREG[16] = {
    399     "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5?", "%cr6?", "%cr7?",
    400     "%cr8", "%cr9?", "%cr10?", "%cr11?", "%cr12?", "%cr13?", "%cr14?", "%cr15?"
    401 };
    402 
    403 const char *const dis_TESTREG[16] = {
    404 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7",
    405 	"%tr0?", "%tr1?", "%tr2?", "%tr3", "%tr4", "%tr5", "%tr6", "%tr7"
    406 };
    407 
    408 const char *const dis_MMREG[16] = {
    409 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
    410 	"%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
    411 };
    412 
    413 const char *const dis_XMMREG[16] = {
    414     "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
    415     "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
    416 };
    417 
    418 const char *const dis_SEGREG[16] = {
    419 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>",
    420 	"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "<reserved>", "<reserved>"
    421 };
    422 
    423 /*
    424  * SIMD predicate suffixes
    425  */
    426 const char *const dis_PREDSUFFIX[8] = {
    427 	"eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord"
    428 };
    429 
    430 
    431 
    432 #endif	/* DIS_TEXT */
    433 
    434 
    435 
    436 
    437 /*
    438  *	"decode table" for 64 bit mode MOVSXD instruction (opcode 0x63)
    439  */
    440 const instable_t dis_opMOVSLD = TNS("movslq",MOVSXZ);
    441 
    442 /*
    443  *	"decode table" for pause and clflush instructions
    444  */
    445 const instable_t dis_opPause = TNS("pause", NORM);
    446 
    447 /*
    448  *	Decode table for 0x0F00 opcodes
    449  */
    450 const instable_t dis_op0F00[8] = {
    451 
    452 /*  [0]  */	TNS("sldt",M),		TNS("str",M),		TNSy("lldt",M), 	TNSy("ltr",M),
    453 /*  [4]  */	TNSZ("verr",M,2),	TNSZ("verw",M,2),	INVALID,		INVALID,
    454 };
    455 
    456 
    457 /*
    458  *	Decode table for 0x0F01 opcodes
    459  */
    460 const instable_t dis_op0F01[8] = {
    461 
    462 /*  [0]  */	TNSZ("sgdt",MO,6),	TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",MO,6),	TNSZ("lidt",MO,6),
    463 /*  [4]  */	TNSZ("smsw",M,2),	INVALID, 		TNSZ("lmsw",M,2),	TNS("invlpg",SWAPGS),
    464 };
    465 
    466 /*
    467  *	Decode table for 0x0F18 opcodes -- SIMD prefetch
    468  */
    469 const instable_t dis_op0F18[8] = {
    470 
    471 /*  [0]  */	TNS("prefetchnta",PREF),TNS("prefetcht0",PREF),	TNS("prefetcht1",PREF),	TNS("prefetcht2",PREF),
    472 /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    473 };
    474 
    475 /*
    476  * 	Decode table for 0x0FAE opcodes -- SIMD state save/restore
    477  */
    478 const instable_t dis_op0FAE[8] = {
    479 /*  [0]  */	TNSZ("fxsave",M,512),	TNSZ("fxrstor",M,512),	TNS("ldmxcsr",M),	TNS("stmxcsr",M),
    480 /*  [4]  */	INVALID,		TNS("lfence",XMMFENCE), TNS("mfence",XMMFENCE),	TNS("sfence",XMMSFNC),
    481 };
    482 
    483 /*
    484  *	Decode table for 0x0FBA opcodes
    485  */
    486 
    487 const instable_t dis_op0FBA[8] = {
    488 
    489 /*  [0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    490 /*  [4]  */	TS("bt",MIb),		TS("bts",MIb),		TS("btr",MIb),		TS("btc",MIb),
    491 };
    492 
    493 /*
    494  * 	Decode table for 0x0FC7 opcode
    495  */
    496 
    497 const instable_t dis_op0FC7[8] = {
    498 
    499 /*  [0]  */	INVALID,		TNS("cmpxchg8b",M),	INVALID,		INVALID,
    500 /*  [4]  */	INVALID,		INVALID,	INVALID,		 INVALID,
    501 };
    502 
    503 
    504 /*
    505  *	Decode table for 0x0FC8 opcode -- 486 bswap instruction
    506  *
    507  *bit pattern: 0000 1111 1100 1reg
    508  */
    509 const instable_t dis_op0FC8[4] = {
    510 /*  [0]  */	TNS("bswap",R),		INVALID,		INVALID,		INVALID,
    511 };
    512 
    513 /*
    514  *	Decode table for 0x0F71, 0x0F72, and 0x0F73 opcodes -- MMX instructions
    515  */
    516 const instable_t dis_op0F7123[4][8] = {
    517 {
    518 /*  [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
    519 /*      .4 */	INVALID,		INVALID,		INVALID,		INVALID,
    520 }, {
    521 /*  [71].0 */	INVALID,		INVALID,		TNS("psrlw",MMOSH),	INVALID,
    522 /*      .4 */	TNS("psraw",MMOSH),	INVALID,		TNS("psllw",MMOSH),	INVALID,
    523 }, {
    524 /*  [72].0 */	INVALID,		INVALID,		TNS("psrld",MMOSH),	INVALID,
    525 /*      .4 */	TNS("psrad",MMOSH),	INVALID,		TNS("pslld",MMOSH),	INVALID,
    526 }, {
    527 /*  [73].0 */	INVALID,		INVALID,		TNS("psrlq",MMOSH),	TNS("INVALID",MMOSH),
    528 /*      .4 */	INVALID,		INVALID, 		TNS("psllq",MMOSH),	TNS("INVALID",MMOSH),
    529 } };
    530 
    531 /*
    532  *	Decode table for SIMD extensions to above 0x0F71-0x0F73 opcodes.
    533  */
    534 const instable_t dis_opSIMD7123[32] = {
    535 /* [70].0 */	INVALID,		INVALID,		INVALID,		INVALID,
    536 /*     .4 */	INVALID,		INVALID,		INVALID,		INVALID,
    537 
    538 /* [71].0 */	INVALID,		INVALID,		TNS("psrlw",XMMSH),	INVALID,
    539 /*     .4 */	TNS("psraw",XMMSH),	INVALID,		TNS("psllw",XMMSH),	INVALID,
    540 
    541 /* [72].0 */	INVALID,		INVALID,		TNS("psrld",XMMSH),	INVALID,
    542 /*     .4 */	TNS("psrad",XMMSH),	INVALID,		TNS("pslld",XMMSH),	INVALID,
    543 
    544 /* [73].0 */	INVALID,		INVALID,		TNS("psrlq",XMMSH),	TNS("psrldq",XMMSH),
    545 /*     .4 */	INVALID,		INVALID,		TNS("psllq",XMMSH),	TNS("pslldq",XMMSH),
    546 };
    547 
    548 /*
    549  *	SIMD instructions have been wedged into the existing IA32 instruction
    550  *	set through the use of prefixes.  That is, while 0xf0 0x58 may be
    551  *	addps, 0xf3 0xf0 0x58 (literally, repz addps) is a completely different
    552  *	instruction - addss.  At present, three prefixes have been coopted in
    553  *	this manner - address size (0x66), repnz (0xf2) and repz (0xf3).  The
    554  *	following tables are used to provide the prefixed instruction names.
    555  *	The arrays are sparse, but they're fast.
    556  */
    557 
    558 /*
    559  *	Decode table for SIMD instructions with the address size (0x66) prefix.
    560  */
    561 const instable_t dis_opSIMDdata16[256] = {
    562 /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
    563 /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
    564 /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
    565 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    566 
    567 /*  [10]  */	TNSZ("movupd",XMM,16),	TNSZ("movupd",XMMS,16),	TNSZ("movlpd",XMMM,8),	TNSZ("movlpd",XMMMS,8),
    568 /*  [14]  */	TNSZ("unpcklpd",XMM,16),TNSZ("unpckhpd",XMM,16),TNSZ("movhpd",XMMM,8),	TNSZ("movhpd",XMMMS,8),
    569 /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
    570 /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    571 
    572 /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
    573 /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
    574 /*  [28]  */	TNSZ("movapd",XMM,16),	TNSZ("movapd",XMMS,16),	TNSZ("cvtpi2pd",XMMOMX,8),TNSZ("movntpd",XMMOMS,16),
    575 /*  [2C]  */	TNSZ("cvttpd2pi",XMMXMM,16),TNSZ("cvtpd2pi",XMMXMM,16),TNSZ("ucomisd",XMM,8),TNSZ("comisd",XMM,8),
    576 
    577 /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
    578 /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
    579 /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
    580 /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    581 
    582 /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
    583 /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
    584 /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
    585 /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    586 
    587 /*  [50]  */	TNS("movmskpd",XMMOX3),	TNSZ("sqrtpd",XMM,16),	INVALID,		INVALID,
    588 /*  [54]  */	TNSZ("andpd",XMM,16),	TNSZ("andnpd",XMM,16),	TNSZ("orpd",XMM,16),	TNSZ("xorpd",XMM,16),
    589 /*  [58]  */	TNSZ("addpd",XMM,16),	TNSZ("mulpd",XMM,16),	TNSZ("cvtpd2ps",XMM,16),TNSZ("cvtps2dq",XMM,16),
    590 /*  [5C]  */	TNSZ("subpd",XMM,16),	TNSZ("minpd",XMM,16),	TNSZ("divpd",XMM,16),	TNSZ("maxpd",XMM,16),
    591 
    592 /*  [60]  */	TNSZ("punpcklbw",XMM,16),TNSZ("punpcklwd",XMM,16),TNSZ("punpckldq",XMM,16),TNSZ("packsswb",XMM,16),
    593 /*  [64]  */	TNSZ("pcmpgtb",XMM,16),	TNSZ("pcmpgtw",XMM,16),	TNSZ("pcmpgtd",XMM,16),	TNSZ("packuswb",XMM,16),
    594 /*  [68]  */	TNSZ("punpckhbw",XMM,16),TNSZ("punpckhwd",XMM,16),TNSZ("punpckhdq",XMM,16),TNSZ("packssdw",XMM,16),
    595 /*  [6C]  */	TNSZ("punpcklqdq",XMM,16),TNSZ("punpckhqdq",XMM,16),TNSZ("movd",XMM3MX,4),TNSZ("movdqa",XMM,16),
    596 
    597 /*  [70]  */	TNSZ("pshufd",XMMP,16),	INVALID,		INVALID,		INVALID,
    598 /*  [74]  */	TNSZ("pcmpeqb",XMM,16),	TNSZ("pcmpeqw",XMM,16),	TNSZ("pcmpeqd",XMM,16),	INVALID,
    599 /*  [78]  */	TNSZ("extrq",XMM2I,16),	TNSZ("extrq",XMM,16), INVALID,		INVALID,
    600 /*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",XMM3MXS,4),	TNSZ("movdqa",XMMS,16),
    601 
    602 /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
    603 /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
    604 /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
    605 /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    606 
    607 /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
    608 /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
    609 /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
    610 /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    611 
    612 /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    613 /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    614 /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    615 /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    616 
    617 /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    618 /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    619 /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    620 /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    621 
    622 /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmppd",XMMP,16),	INVALID,
    623 /*  [C4]  */	TNSZ("pinsrw",XMMPRM,2),TNS("pextrw",XMM3P),	TNSZ("shufpd",XMMP,16),	INVALID,
    624 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    625 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    626 
    627 /*  [D0]  */	INVALID,		TNSZ("psrlw",XMM,16),	TNSZ("psrld",XMM,16),	TNSZ("psrlq",XMM,16),
    628 /*  [D4]  */	TNSZ("paddq",XMM,16),	TNSZ("pmullw",XMM,16),	TNSZ("movq",XMMS,8),	TNS("pmovmskb",XMMX3),
    629 /*  [D8]  */	TNSZ("psubusb",XMM,16),	TNSZ("psubusw",XMM,16),	TNSZ("pminub",XMM,16),	TNSZ("pand",XMM,16),
    630 /*  [DC]  */	TNSZ("paddusb",XMM,16),	TNSZ("paddusw",XMM,16),	TNSZ("pmaxub",XMM,16),	TNSZ("pandn",XMM,16),
    631 
    632 /*  [E0]  */	TNSZ("pavgb",XMM,16),	TNSZ("psraw",XMM,16),	TNSZ("psrad",XMM,16),	TNSZ("pavgw",XMM,16),
    633 /*  [E4]  */	TNSZ("pmulhuw",XMM,16),	TNSZ("pmulhw",XMM,16),	TNSZ("cvttpd2dq",XMM,16),TNSZ("movntdq",XMMS,16),
    634 /*  [E8]  */	TNSZ("psubsb",XMM,16),	TNSZ("psubsw",XMM,16),	TNSZ("pminsw",XMM,16),	TNSZ("por",XMM,16),
    635 /*  [EC]  */	TNSZ("paddsb",XMM,16),	TNSZ("paddsw",XMM,16),	TNSZ("pmaxsw",XMM,16),	TNSZ("pxor",XMM,16),
    636 
    637 /*  [F0]  */	INVALID,		TNSZ("psllw",XMM,16),	TNSZ("pslld",XMM,16),	TNSZ("psllq",XMM,16),
    638 /*  [F4]  */	TNSZ("pmuludq",XMM,16),	TNSZ("pmaddwd",XMM,16),	TNSZ("psadbw",XMM,16),	TNSZ("maskmovdqu", XMMXIMPL,16),
    639 /*  [F8]  */	TNSZ("psubb",XMM,16),	TNSZ("psubw",XMM,16),	TNSZ("psubd",XMM,16),	TNSZ("psubq",XMM,16),
    640 /*  [FC]  */	TNSZ("paddb",XMM,16),	TNSZ("paddw",XMM,16),	TNSZ("paddd",XMM,16),	INVALID,
    641 };
    642 
    643 /*
    644  *	Decode table for SIMD instructions with the repnz (0xf2) prefix.
    645  */
    646 const instable_t dis_opSIMDrepnz[256] = {
    647 /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
    648 /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
    649 /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
    650 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    651 
    652 /*  [10]  */	TNSZ("movsd",XMM,8),	TNSZ("movsd",XMMS,8),	INVALID,		INVALID,
    653 /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
    654 /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
    655 /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    656 
    657 /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
    658 /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
    659 /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2sd",XMM3MX,4),TNSZ("movntsd",XMMMS,8),
    660 /*  [2C]  */	TNSZ("cvttsd2si",XMMXM3,8),TNSZ("cvtsd2si",XMMXM3,8),INVALID,		INVALID,
    661 
    662 /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
    663 /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
    664 /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
    665 /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    666 
    667 /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
    668 /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
    669 /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
    670 /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    671 
    672 /*  [50]  */	INVALID,		TNSZ("sqrtsd",XMM,8),	INVALID,		INVALID,
    673 /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
    674 /*  [58]  */	TNSZ("addsd",XMM,8),	TNSZ("mulsd",XMM,8),	TNSZ("cvtsd2ss",XMM,8),	INVALID,
    675 /*  [5C]  */	TNSZ("subsd",XMM,8),	TNSZ("minsd",XMM,8),	TNSZ("divsd",XMM,8),	TNSZ("maxsd",XMM,8),
    676 
    677 /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
    678 /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
    679 /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
    680 /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    681 
    682 /*  [70]  */	TNSZ("pshuflw",XMMP,16),INVALID,		INVALID,		INVALID,
    683 /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
    684 /*  [78]  */	TNSZ("insertq",XMMX2I,16),TNSZ("insertq",XMM,8),INVALID,		INVALID,
    685 /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    686 
    687 /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
    688 /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
    689 /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
    690 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    691 
    692 /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
    693 /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
    694 /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
    695 /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    696 
    697 /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    698 /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    699 /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    700 /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    701 
    702 /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    703 /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    704 /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    705 /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    706 
    707 /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpsd",XMMP,8),	INVALID,
    708 /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    709 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    710 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    711 
    712 /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    713 /*  [D4]  */	INVALID,		INVALID,		TNS("movdq2q",XMMXM),	INVALID,
    714 /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    715 /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    716 
    717 /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    718 /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtpd2dq",XMM,16),INVALID,
    719 /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    720 /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    721 
    722 /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    723 /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    724 /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    725 /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    726 };
    727 
    728 /*
    729  *	Decode table for SIMD instructions with the repz (0xf3) prefix.
    730  */
    731 const instable_t dis_opSIMDrepz[256] = {
    732 /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
    733 /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
    734 /*  [08]  */	INVALID,		INVALID,		INVALID,		INVALID,
    735 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    736 
    737 /*  [10]  */	TNSZ("movss",XMM,4),	TNSZ("movss",XMMS,4),	INVALID,		INVALID,
    738 /*  [14]  */	INVALID,		INVALID,		INVALID,		INVALID,
    739 /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
    740 /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    741 
    742 /*  [20]  */	INVALID,		INVALID,		INVALID,		INVALID,
    743 /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
    744 /*  [28]  */	INVALID,		INVALID,		TNSZ("cvtsi2ss",XMM3MX,4),TNSZ("movntss",XMMMS,4),
    745 /*  [2C]  */	TNSZ("cvttss2si",XMMXM3,4),TNSZ("cvtss2si",XMMXM3,4),INVALID,		INVALID,
    746 
    747 /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
    748 /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
    749 /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
    750 /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    751 
    752 /*  [40]  */	INVALID,		INVALID,		INVALID,		INVALID,
    753 /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
    754 /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
    755 /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    756 
    757 /*  [50]  */	INVALID,		TNSZ("sqrtss",XMM,4),	TNSZ("rsqrtss",XMM,4),	TNSZ("rcpss",XMM,4),
    758 /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
    759 /*  [58]  */	TNSZ("addss",XMM,4),	TNSZ("mulss",XMM,4),	TNSZ("cvtss2sd",XMM,4),	TNSZ("cvttps2dq",XMM,16),
    760 /*  [5C]  */	TNSZ("subss",XMM,4),	TNSZ("minss",XMM,4),	TNSZ("divss",XMM,4),	TNSZ("maxss",XMM,4),
    761 
    762 /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
    763 /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
    764 /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
    765 /*  [6C]  */	INVALID,		INVALID,		INVALID,		TNSZ("movdqu",XMM,16),
    766 
    767 /*  [70]  */	TNSZ("pshufhw",XMMP,16),INVALID,		INVALID,		INVALID,
    768 /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
    769 /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
    770 /*  [7C]  */	INVALID,		INVALID,		TNSZ("movq",XMM,8),	TNSZ("movdqu",XMMS,16),
    771 
    772 /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
    773 /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
    774 /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
    775 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    776 
    777 /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
    778 /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
    779 /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
    780 /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    781 
    782 /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    783 /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    784 /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    785 /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    786 
    787 /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    788 /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    789 /*  [B8]  */	TS("popcnt",MRw),	INVALID,		INVALID,		INVALID,
    790 /*  [BC]  */	INVALID,		TS("lzcnt",MRw),	INVALID,		INVALID,
    791 
    792 /*  [C0]  */	INVALID,		INVALID,		TNSZ("cmpss",XMMP,4),	INVALID,
    793 /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    794 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    795 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    796 
    797 /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    798 /*  [D4]  */	INVALID,		INVALID,		TNS("movq2dq",XMMMX),	INVALID,
    799 /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    800 /*  [DC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    801 
    802 /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    803 /*  [E4]  */	INVALID,		INVALID,		TNSZ("cvtdq2pd",XMM,8),	INVALID,
    804 /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    805 /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    806 
    807 /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    808 /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    809 /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    810 /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    811 };
    812 
    813 /*
    814  * The following two tables are used to encode crc32 and movbe
    815  * since they share the same opcodes.
    816  */
    817 const instable_t dis_op0F38F0[2] = {
    818 /*  [00]  */	TNS("crc32b",CRC32),
    819 		TS("movbe",MOVBE),
    820 };
    821 
    822 const instable_t dis_op0F38F1[2] = {
    823 /*  [00]  */	TS("crc32",CRC32),
    824 		TS("movbe",MOVBE),
    825 };
    826 
    827 const instable_t dis_op0F38[256] = {
    828 /*  [00]  */	TNSZ("pshufb",XMM_66o,16),TNSZ("phaddw",XMM_66o,16),TNSZ("phaddd",XMM_66o,16),TNSZ("phaddsw",XMM_66o,16),
    829 /*  [04]  */	TNSZ("pmaddubsw",XMM_66o,16),TNSZ("phsubw",XMM_66o,16),	TNSZ("phsubd",XMM_66o,16),TNSZ("phsubsw",XMM_66o,16),
    830 /*  [08]  */	TNSZ("psignb",XMM_66o,16),TNSZ("psignw",XMM_66o,16),TNSZ("psignd",XMM_66o,16),TNSZ("pmulhrsw",XMM_66o,16),
    831 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    832 
    833 /*  [10]  */	TNSZ("pblendvb",XMM_66r,16),INVALID,		INVALID,		INVALID,
    834 /*  [14]  */	TNSZ("blendvps",XMM_66r,16),TNSZ("blendvpd",XMM_66r,16),INVALID,	TNSZ("ptest",XMM_66r,16),
    835 /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
    836 /*  [1C]  */	TNSZ("pabsb",XMM_66o,16),TNSZ("pabsw",XMM_66o,16),TNSZ("pabsd",XMM_66o,16),INVALID,
    837 
    838 /*  [20]  */	TNSZ("pmovsxbw",XMM_66r,16),TNSZ("pmovsxbd",XMM_66r,16),TNSZ("pmovsxbq",XMM_66r,16),TNSZ("pmovsxwd",XMM_66r,16),
    839 /*  [24]  */	TNSZ("pmovsxwq",XMM_66r,16),TNSZ("pmovsxdq",XMM_66r,16),INVALID,	INVALID,
    840 /*  [28]  */	TNSZ("pmuldq",XMM_66r,16),TNSZ("pcmpeqq",XMM_66r,16),TNSZ("movntdqa",XMMM_66r,16),TNSZ("packusdw",XMM_66r,16),
    841 /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    842 
    843 /*  [30]  */	TNSZ("pmovzxbw",XMM_66r,16),TNSZ("pmovzxbd",XMM_66r,16),TNSZ("pmovzxbq",XMM_66r,16),TNSZ("pmovzxwd",XMM_66r,16),
    844 /*  [34]  */	TNSZ("pmovzxwq",XMM_66r,16),TNSZ("pmovzxdq",XMM_66r,16),INVALID,	TNSZ("pcmpgtq",XMM_66r,16),
    845 /*  [38]  */	TNSZ("pminsb",XMM_66r,16),TNSZ("pminsd",XMM_66r,16),TNSZ("pminuw",XMM_66r,16),TNSZ("pminud",XMM_66r,16),
    846 /*  [3C]  */	TNSZ("pmaxsb",XMM_66r,16),TNSZ("pmaxsd",XMM_66r,16),TNSZ("pmaxuw",XMM_66r,16),TNSZ("pmaxud",XMM_66r,16),
    847 
    848 /*  [40]  */	TNSZ("pmulld",XMM_66r,16),TNSZ("phminposuw",XMM_66r,16),INVALID,	INVALID,
    849 /*  [44]  */	INVALID,		INVALID,		INVALID,		INVALID,
    850 /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
    851 /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    852 
    853 /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
    854 /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
    855 /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
    856 /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    857 
    858 /*  [60]  */	INVALID,		INVALID,		INVALID,		INVALID,
    859 /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
    860 /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
    861 /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    862 
    863 /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
    864 /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
    865 /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
    866 /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    867 
    868 /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
    869 /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
    870 /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
    871 /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    872 
    873 /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
    874 /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
    875 /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
    876 /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    877 
    878 /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    879 /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    880 /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    881 /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    882 
    883 /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    884 /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    885 /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    886 /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    887 
    888 /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    889 /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    890 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    891 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    892 
    893 /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    894 /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    895 /*  [D8]  */	INVALID,		INVALID,		INVALID,		TNSZ("aesimc",XMM_66r,16),
    896 /*  [DC]  */	TNSZ("aesenc",XMM_66r,16),TNSZ("aesenclast",XMM_66r,16),TNSZ("aesdec",XMM_66r,16),TNSZ("aesdeclast",XMM_66r,16),
    897 
    898 /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    899 /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    900 /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    901 /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    902 /*  [F0]  */	IND(dis_op0F38F0),	IND(dis_op0F38F1),	INVALID,		INVALID,
    903 /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    904 /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    905 /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    906 };
    907 
    908 const instable_t dis_op0F3A[256] = {
    909 /*  [00]  */	INVALID,		INVALID,		INVALID,		INVALID,
    910 /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
    911 /*  [08]  */	TNSZ("roundps",XMMP_66r,16),TNSZ("roundpd",XMMP_66r,16),TNSZ("roundss",XMMP_66r,16),TNSZ("roundsd",XMMP_66r,16),
    912 /*  [0C]  */	TNSZ("blendps",XMMP_66r,16),TNSZ("blendpd",XMMP_66r,16),TNSZ("pblendw",XMMP_66r,16),TNSZ("palignr",XMMP_66o,16),
    913 
    914 /*  [10]  */	INVALID,		INVALID,		INVALID,		INVALID,
    915 /*  [14]  */	TNSZ("pextrb",XMM3PM_66r,8),TNSZ("pextrw",XMM3PM_66r,16),TSZ("pextr",XMM3PM_66r,16),TNSZ("extractps",XMM3PM_66r,16),
    916 /*  [18]  */	INVALID,		INVALID,		INVALID,		INVALID,
    917 /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    918 
    919 /*  [20]  */	TNSZ("pinsrb",XMMPRM_66r,8),TNSZ("insertps",XMMP_66r,16),TSZ("pinsr",XMMPRM_66r,16),INVALID,
    920 /*  [24]  */	INVALID,		INVALID,		INVALID,		INVALID,
    921 /*  [28]  */	INVALID,		INVALID,		INVALID,		INVALID,
    922 /*  [2C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    923 
    924 /*  [30]  */	INVALID,		INVALID,		INVALID,		INVALID,
    925 /*  [34]  */	INVALID,		INVALID,		INVALID,		INVALID,
    926 /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
    927 /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    928 
    929 /*  [40]  */	TNSZ("dpps",XMMP_66r,16),TNSZ("dppd",XMMP_66r,16),TNSZ("mpsadbw",XMMP_66r,16),INVALID,
    930 /*  [44]  */	TNSZ("pclmulqdq",XMMP_66r,16),INVALID,		INVALID,		INVALID,
    931 /*  [48]  */	INVALID,		INVALID,		INVALID,		INVALID,
    932 /*  [4C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    933 
    934 /*  [50]  */	INVALID,		INVALID,		INVALID,		INVALID,
    935 /*  [54]  */	INVALID,		INVALID,		INVALID,		INVALID,
    936 /*  [58]  */	INVALID,		INVALID,		INVALID,		INVALID,
    937 /*  [5C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    938 
    939 /*  [60]  */	TNSZ("pcmpestrm",XMMP_66r,16),TNSZ("pcmpestri",XMMP_66r,16),TNSZ("pcmpistrm",XMMP_66r,16),TNSZ("pcmpistri",XMMP_66r,16),
    940 /*  [64]  */	INVALID,		INVALID,		INVALID,		INVALID,
    941 /*  [68]  */	INVALID,		INVALID,		INVALID,		INVALID,
    942 /*  [6C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    943 
    944 /*  [70]  */	INVALID,		INVALID,		INVALID,		INVALID,
    945 /*  [74]  */	INVALID,		INVALID,		INVALID,		INVALID,
    946 /*  [78]  */	INVALID,		INVALID,		INVALID,		INVALID,
    947 /*  [7C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    948 
    949 /*  [80]  */	INVALID,		INVALID,		INVALID,		INVALID,
    950 /*  [84]  */	INVALID,		INVALID,		INVALID,		INVALID,
    951 /*  [88]  */	INVALID,		INVALID,		INVALID,		INVALID,
    952 /*  [8C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    953 
    954 /*  [90]  */	INVALID,		INVALID,		INVALID,		INVALID,
    955 /*  [94]  */	INVALID,		INVALID,		INVALID,		INVALID,
    956 /*  [98]  */	INVALID,		INVALID,		INVALID,		INVALID,
    957 /*  [9C]  */	INVALID,		INVALID,		INVALID,		INVALID,
    958 
    959 /*  [A0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    960 /*  [A4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    961 /*  [A8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    962 /*  [AC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    963 
    964 /*  [B0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    965 /*  [B4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    966 /*  [B8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    967 /*  [BC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    968 
    969 /*  [C0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    970 /*  [C4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    971 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    972 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    973 
    974 /*  [D0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    975 /*  [D4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    976 /*  [D8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    977 /*  [DC]  */	INVALID,		INVALID,		INVALID,		TNSZ("aeskeygenassist",XMMP_66r,16),
    978 
    979 /*  [E0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    980 /*  [E4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    981 /*  [E8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    982 /*  [EC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    983 
    984 /*  [F0]  */	INVALID,		INVALID,		INVALID,		INVALID,
    985 /*  [F4]  */	INVALID,		INVALID,		INVALID,		INVALID,
    986 /*  [F8]  */	INVALID,		INVALID,		INVALID,		INVALID,
    987 /*  [FC]  */	INVALID,		INVALID,		INVALID,		INVALID,
    988 };
    989 
    990 /*
    991  *	Decode table for 0x0F opcodes
    992  */
    993 
    994 const instable_t dis_op0F[16][16] = {
    995 {
    996 /*  [00]  */	IND(dis_op0F00),	IND(dis_op0F01),	TNS("lar",MR),		TNS("lsl",MR),
    997 /*  [04]  */	INVALID,		TNS("syscall",NORM),	TNS("clts",NORM),	TNS("sysret",NORM),
    998 /*  [08]  */	TNS("invd",NORM),	TNS("wbinvd",NORM),	INVALID,		TNS("ud2",NORM),
    999 /*  [0C]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1000 }, {
   1001 /*  [10]  */	TNSZ("movups",XMMO,16),	TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8),	TNSZ("movlps",XMMOS,8),
   1002 /*  [14]  */	TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
   1003 /*  [18]  */	IND(dis_op0F18),	INVALID,		INVALID,		INVALID,
   1004 /*  [1C]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1005 }, {
   1006 /*  [20]  */	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),	TSy("mov",SREG),
   1007 /*  [24]  */	TSx("mov",SREG),	INVALID,		TSx("mov",SREG),	INVALID,
   1008 /*  [28]  */	TNSZ("movaps",XMMO,16),	TNSZ("movaps",XMMOS,16),TNSZ("cvtpi2ps",XMMOMX,8),TNSZ("movntps",XMMOS,16),
   1009 /*  [2C]  */	TNSZ("cvttps2pi",XMMOXMM,8),TNSZ("cvtps2pi",XMMOXMM,8),TNSZ("ucomiss",XMMO,4),TNSZ("comiss",XMMO,4),
   1010 }, {
   1011 /*  [30]  */	TNS("wrmsr",NORM),	TNS("rdtsc",NORM),	TNS("rdmsr",NORM),	TNS("rdpmc",NORM),
   1012 /*  [34]  */	TNSx("sysenter",NORM),	TNSx("sysexit",NORM),	INVALID,		INVALID,
   1013 /*  [38]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1014 /*  [3C]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1015 }, {
   1016 /*  [40]  */	TS("cmovx.o",MR),	TS("cmovx.no",MR),	TS("cmovx.b",MR),	TS("cmovx.ae",MR),
   1017 /*  [44]  */	TS("cmovx.e",MR),	TS("cmovx.ne",MR),	TS("cmovx.be",MR),	TS("cmovx.a",MR),
   1018 /*  [48]  */	TS("cmovx.s",MR),	TS("cmovx.ns",MR),	TS("cmovx.pe",MR),	TS("cmovx.po",MR),
   1019 /*  [4C]  */	TS("cmovx.l",MR),	TS("cmovx.ge",MR),	TS("cmovx.le",MR),	TS("cmovx.g",MR),
   1020 }, {
   1021 /*  [50]  */	TNS("movmskps",XMMOX3),	TNSZ("sqrtps",XMMO,16),	TNSZ("rsqrtps",XMMO,16),TNSZ("rcpps",XMMO,16),
   1022 /*  [54]  */	TNSZ("andps",XMMO,16),	TNSZ("andnps",XMMO,16),	TNSZ("orps",XMMO,16),	TNSZ("xorps",XMMO,16),
   1023 /*  [58]  */	TNSZ("addps",XMMO,16),	TNSZ("mulps",XMMO,16),	TNSZ("cvtps2pd",XMMO,8),TNSZ("cvtdq2ps",XMMO,16),
   1024 /*  [5C]  */	TNSZ("subps",XMMO,16),	TNSZ("minps",XMMO,16),	TNSZ("divps",XMMO,16),	TNSZ("maxps",XMMO,16),
   1025 }, {
   1026 /*  [60]  */	TNSZ("punpcklbw",MMO,4),TNSZ("punpcklwd",MMO,4),TNSZ("punpckldq",MMO,4),TNSZ("packsswb",MMO,8),
   1027 /*  [64]  */	TNSZ("pcmpgtb",MMO,8),	TNSZ("pcmpgtw",MMO,8),	TNSZ("pcmpgtd",MMO,8),	TNSZ("packuswb",MMO,8),
   1028 /*  [68]  */	TNSZ("punpckhbw",MMO,8),TNSZ("punpckhwd",MMO,8),TNSZ("punpckhdq",MMO,8),TNSZ("packssdw",MMO,8),
   1029 /*  [6C]  */	TNSZ("INVALID",MMO,0),	TNSZ("INVALID",MMO,0),	TNSZ("movd",MMO,4),	TNSZ("movq",MMO,8),
   1030 }, {
   1031 /*  [70]  */	TNSZ("pshufw",MMOPM,8),	TNS("psrXXX",MR),	TNS("psrXXX",MR),	TNS("psrXXX",MR),
   1032 /*  [74]  */	TNSZ("pcmpeqb",MMO,8),	TNSZ("pcmpeqw",MMO,8),	TNSZ("pcmpeqd",MMO,8),	TNS("emms",NORM),
   1033 /*  [78]  */	TNS("INVALID",XMMO),	TNS("INVALID",XMMO),	INVALID,		INVALID,
   1034 /*  [7C]  */	INVALID,		INVALID,		TNSZ("movd",MMOS,4),	TNSZ("movq",MMOS,8),
   1035 }, {
   1036 /*  [80]  */	TNS("jo",D),		TNS("jno",D),		TNS("jb",D),		TNS("jae",D),
   1037 /*  [84]  */	TNS("je",D),		TNS("jne",D),		TNS("jbe",D),		TNS("ja",D),
   1038 /*  [88]  */	TNS("js",D),		TNS("jns",D),		TNS("jp",D),		TNS("jnp",D),
   1039 /*  [8C]  */	TNS("jl",D),		TNS("jge",D),		TNS("jle",D),		TNS("jg",D),
   1040 }, {
   1041 /*  [90]  */	TNS("seto",Mb),		TNS("setno",Mb),	TNS("setb",Mb),		TNS("setae",Mb),
   1042 /*  [94]  */	TNS("sete",Mb),		TNS("setne",Mb),	TNS("setbe",Mb),	TNS("seta",Mb),
   1043 /*  [98]  */	TNS("sets",Mb),		TNS("setns",Mb),	TNS("setp",Mb),		TNS("setnp",Mb),
   1044 /*  [9C]  */	TNS("setl",Mb),		TNS("setge",Mb),	TNS("setle",Mb),	TNS("setg",Mb),
   1045 }, {
   1046 /*  [A0]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("cpuid",NORM),	TS("bt",RMw),
   1047 /*  [A4]  */	TS("shld",DSHIFT),	TS("shld",DSHIFTcl),	INVALID,		INVALID,
   1048 /*  [A8]  */	TSp("push",LSEG),	TSp("pop",LSEG),	TNS("rsm",NORM),	TS("bts",RMw),
   1049 /*  [AC]  */	TS("shrd",DSHIFT),	TS("shrd",DSHIFTcl),	IND(dis_op0FAE),	TS("imul",MRw),
   1050 }, {
   1051 /*  [B0]  */	TNS("cmpxchgb",RMw),	TS("cmpxchg",RMw),	TS("lss",MR),		TS("btr",RMw),
   1052 /*  [B4]  */	TS("lfs",MR),		TS("lgs",MR),		TS("movzb",MOVZ),	TNS("movzwl",MOVZ),
   1053 /*  [B8]  */	TNS("INVALID",MRw),	INVALID,		IND(dis_op0FBA),	TS("btc",RMw),
   1054 /*  [BC]  */	TS("bsf",MRw),		TS("bsr",MRw),		TS("movsb",MOVZ),	TNS("movswl",MOVZ),
   1055 }, {
   1056 /*  [C0]  */	TNS("xaddb",XADDB),	TS("xadd",RMw),		TNSZ("cmpps",XMMOPM,16),TNS("movnti",RM),
   1057 /*  [C4]  */	TNSZ("pinsrw",MMOPRM,2),TNS("pextrw",MMO3P), 	TNSZ("shufps",XMMOPM,16),IND(dis_op0FC7),
   1058 /*  [C8]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1059 /*  [CC]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1060 }, {
   1061 /*  [D0]  */	INVALID,		TNSZ("psrlw",MMO,8),	TNSZ("psrld",MMO,8),	TNSZ("psrlq",MMO,8),
   1062 /*  [D4]  */	TNSZ("paddq",MMO,8),	TNSZ("pmullw",MMO,8),	TNSZ("INVALID",MMO,0),	TNS("pmovmskb",MMOM3),
   1063 /*  [D8]  */	TNSZ("psubusb",MMO,8),	TNSZ("psubusw",MMO,8),	TNSZ("pminub",MMO,8),	TNSZ("pand",MMO,8),
   1064 /*  [DC]  */	TNSZ("paddusb",MMO,8),	TNSZ("paddusw",MMO,8),	TNSZ("pmaxub",MMO,8),	TNSZ("pandn",MMO,8),
   1065 }, {
   1066 /*  [E0]  */	TNSZ("pavgb",MMO,8),	TNSZ("psraw",MMO,8),	TNSZ("psrad",MMO,8),	TNSZ("pavgw",MMO,8),
   1067 /*  [E4]  */	TNSZ("pmulhuw",MMO,8),	TNSZ("pmulhw",MMO,8),	TNS("INVALID",XMMO),	TNSZ("movntq",MMOMS,8),
   1068 /*  [E8]  */	TNSZ("psubsb",MMO,8),	TNSZ("psubsw",MMO,8),	TNSZ("pminsw",MMO,8),	TNSZ("por",MMO,8),
   1069 /*  [EC]  */	TNSZ("paddsb",MMO,8),	TNSZ("paddsw",MMO,8),	TNSZ("pmaxsw",MMO,8),	TNSZ("pxor",MMO,8),
   1070 }, {
   1071 /*  [F0]  */	INVALID,		TNSZ("psllw",MMO,8),	TNSZ("pslld",MMO,8),	TNSZ("psllq",MMO,8),
   1072 /*  [F4]  */	TNSZ("pmuludq",MMO,8),	TNSZ("pmaddwd",MMO,8),	TNSZ("psadbw",MMO,8),	TNSZ("maskmovq",MMOIMPL,8),
   1073 /*  [F8]  */	TNSZ("psubb",MMO,8),	TNSZ("psubw",MMO,8),	TNSZ("psubd",MMO,8),	TNSZ("psubq",MMO,8),
   1074 /*  [FC]  */	TNSZ("paddb",MMO,8),	TNSZ("paddw",MMO,8),	TNSZ("paddd",MMO,8),	INVALID,
   1075 } };
   1076 
   1077 
   1078 /*
   1079  *	Decode table for 0x80 opcodes
   1080  */
   1081 
   1082 const instable_t dis_op80[8] = {
   1083 
   1084 /*  [0]  */	TNS("addb",IMlw),	TNS("orb",IMw),		TNS("adcb",IMlw),	TNS("sbbb",IMlw),
   1085 /*  [4]  */	TNS("andb",IMw),	TNS("subb",IMlw),	TNS("xorb",IMw),	TNS("cmpb",IMlw),
   1086 };
   1087 
   1088 
   1089 /*
   1090  *	Decode table for 0x81 opcodes.
   1091  */
   1092 
   1093 const instable_t dis_op81[8] = {
   1094 
   1095 /*  [0]  */	TS("add",IMlw),		TS("or",IMw),		TS("adc",IMlw),		TS("sbb",IMlw),
   1096 /*  [4]  */	TS("and",IMw),		TS("sub",IMlw),		TS("xor",IMw),		TS("cmp",IMlw),
   1097 };
   1098 
   1099 
   1100 /*
   1101  *	Decode table for 0x82 opcodes.
   1102  */
   1103 
   1104 const instable_t dis_op82[8] = {
   1105 
   1106 /*  [0]  */	TNSx("addb",IMlw),	TNSx("orb",IMlw),	TNSx("adcb",IMlw),	TNSx("sbbb",IMlw),
   1107 /*  [4]  */	TNSx("andb",IMlw),	TNSx("subb",IMlw),	TNSx("xorb",IMlw),	TNSx("cmpb",IMlw),
   1108 };
   1109 /*
   1110  *	Decode table for 0x83 opcodes.
   1111  */
   1112 
   1113 const instable_t dis_op83[8] = {
   1114 
   1115 /*  [0]  */	TS("add",IMlw),		TS("or",IMlw),		TS("adc",IMlw),		TS("sbb",IMlw),
   1116 /*  [4]  */	TS("and",IMlw),		TS("sub",IMlw),		TS("xor",IMlw),		TS("cmp",IMlw),
   1117 };
   1118 
   1119 /*
   1120  *	Decode table for 0xC0 opcodes.
   1121  */
   1122 
   1123 const instable_t dis_opC0[8] = {
   1124 
   1125 /*  [0]  */	TNS("rolb",MvI),	TNS("rorb",MvI),	TNS("rclb",MvI),	TNS("rcrb",MvI),
   1126 /*  [4]  */	TNS("shlb",MvI),	TNS("shrb",MvI),	INVALID,		TNS("sarb",MvI),
   1127 };
   1128 
   1129 /*
   1130  *	Decode table for 0xD0 opcodes.
   1131  */
   1132 
   1133 const instable_t dis_opD0[8] = {
   1134 
   1135 /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
   1136 /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
   1137 };
   1138 
   1139 /*
   1140  *	Decode table for 0xC1 opcodes.
   1141  *	186 instruction set
   1142  */
   1143 
   1144 const instable_t dis_opC1[8] = {
   1145 
   1146 /*  [0]  */	TS("rol",MvI),		TS("ror",MvI),		TS("rcl",MvI),		TS("rcr",MvI),
   1147 /*  [4]  */	TS("shl",MvI),		TS("shr",MvI),		TS("sal",MvI),		TS("sar",MvI),
   1148 };
   1149 
   1150 /*
   1151  *	Decode table for 0xD1 opcodes.
   1152  */
   1153 
   1154 const instable_t dis_opD1[8] = {
   1155 
   1156 /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
   1157 /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("sal",Mv),		TS("sar",Mv),
   1158 };
   1159 
   1160 
   1161 /*
   1162  *	Decode table for 0xD2 opcodes.
   1163  */
   1164 
   1165 const instable_t dis_opD2[8] = {
   1166 
   1167 /*  [0]  */	TNS("rolb",Mv),		TNS("rorb",Mv),		TNS("rclb",Mv),		TNS("rcrb",Mv),
   1168 /*  [4]  */	TNS("shlb",Mv),		TNS("shrb",Mv),		TNS("salb",Mv),		TNS("sarb",Mv),
   1169 };
   1170 /*
   1171  *	Decode table for 0xD3 opcodes.
   1172  */
   1173 
   1174 const instable_t dis_opD3[8] = {
   1175 
   1176 /*  [0]  */	TS("rol",Mv),		TS("ror",Mv),		TS("rcl",Mv),		TS("rcr",Mv),
   1177 /*  [4]  */	TS("shl",Mv),		TS("shr",Mv),		TS("salb",Mv),		TS("sar",Mv),
   1178 };
   1179 
   1180 
   1181 /*
   1182  *	Decode table for 0xF6 opcodes.
   1183  */
   1184 
   1185 const instable_t dis_opF6[8] = {
   1186 
   1187 /*  [0]  */	TNS("testb",IMw),	TNS("testb",IMw),	TNS("notb",Mw),		TNS("negb",Mw),
   1188 /*  [4]  */	TNS("mulb",MA),		TNS("imulb",MA),	TNS("divb",MA),		TNS("idivb",MA),
   1189 };
   1190 
   1191 
   1192 /*
   1193  *	Decode table for 0xF7 opcodes.
   1194  */
   1195 
   1196 const instable_t dis_opF7[8] = {
   1197 
   1198 /*  [0]  */	TS("test",IMw),		TS("test",IMw),		TS("not",Mw),		TS("neg",Mw),
   1199 /*  [4]  */	TS("mul",MA),		TS("imul",MA),		TS("div",MA),		TS("idiv",MA),
   1200 };
   1201 
   1202 
   1203 /*
   1204  *	Decode table for 0xFE opcodes.
   1205  */
   1206 
   1207 const instable_t dis_opFE[8] = {
   1208 
   1209 /*  [0]  */	TNS("incb",Mw),		TNS("decb",Mw),		INVALID,		INVALID,
   1210 /*  [4]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1211 };
   1212 /*
   1213  *	Decode table for 0xFF opcodes.
   1214  */
   1215 
   1216 const instable_t dis_opFF[8] = {
   1217 
   1218 /*  [0]  */	TS("inc",Mw),		TS("dec",Mw),		TNSyp("call",INM),	TNS("lcall",INM),
   1219 /*  [4]  */	TNSy("jmp",INM),	TNS("ljmp",INM),	TSp("push",M),		INVALID,
   1220 };
   1221 
   1222 /* for 287 instructions, which are a mess to decode */
   1223 
   1224 const instable_t dis_opFP1n2[8][8] = {
   1225 {
   1226 /* bit pattern:	1101 1xxx MODxx xR/M */
   1227 /*  [0,0] */	TNS("fadds",M),		TNS("fmuls",M),		TNS("fcoms",M),		TNS("fcomps",M),
   1228 /*  [0,4] */	TNS("fsubs",M),		TNS("fsubrs",M),	TNS("fdivs",M),		TNS("fdivrs",M),
   1229 }, {
   1230 /*  [1,0]  */	TNS("flds",M),		INVALID,		TNS("fsts",M),		TNS("fstps",M),
   1231 /*  [1,4]  */	TNSZ("fldenv",M,28),	TNSZ("fldcw",M,2),	TNSZ("fnstenv",M,28),	TNSZ("fnstcw",M,2),
   1232 }, {
   1233 /*  [2,0]  */	TNS("fiaddl",M),	TNS("fimull",M),	TNS("ficoml",M),	TNS("ficompl",M),
   1234 /*  [2,4]  */	TNS("fisubl",M),	TNS("fisubrl",M),	TNS("fidivl",M),	TNS("fidivrl",M),
   1235 }, {
   1236 /*  [3,0]  */	TNS("fildl",M),		INVALID,		TNS("fistl",M),		TNS("fistpl",M),
   1237 /*  [3,4]  */	INVALID,		TNSZ("fldt",M,10),	INVALID,		TNSZ("fstpt",M,10),
   1238 }, {
   1239 /*  [4,0]  */	TNSZ("faddl",M,8),	TNSZ("fmull",M,8),	TNSZ("fcoml",M,8),	TNSZ("fcompl",M,8),
   1240 /*  [4,1]  */	TNSZ("fsubl",M,8),	TNSZ("fsubrl",M,8),	TNSZ("fdivl",M,8),	TNSZ("fdivrl",M,8),
   1241 }, {
   1242 /*  [5,0]  */	TNSZ("fldl",M,8),	INVALID,		TNSZ("fstl",M,8),	TNSZ("fstpl",M,8),
   1243 /*  [5,4]  */	TNSZ("frstor",M,108),	INVALID,		TNSZ("fnsave",M,108),	TNSZ("fnstsw",M,2),
   1244 }, {
   1245 /*  [6,0]  */	TNSZ("fiadd",M,2),	TNSZ("fimul",M,2),	TNSZ("ficom",M,2),	TNSZ("ficomp",M,2),
   1246 /*  [6,4]  */	TNSZ("fisub",M,2),	TNSZ("fisubr",M,2),	TNSZ("fidiv",M,2),	TNSZ("fidivr",M,2),
   1247 }, {
   1248 /*  [7,0]  */	TNSZ("fild",M,2),	INVALID,		TNSZ("fist",M,2),	TNSZ("fistp",M,2),
   1249 /*  [7,4]  */	TNSZ("fbld",M,10),	TNSZ("fildll",M,8),	TNSZ("fbstp",M,10),	TNSZ("fistpll",M,8),
   1250 } };
   1251 
   1252 const instable_t dis_opFP3[8][8] = {
   1253 {
   1254 /* bit  pattern:	1101 1xxx 11xx xREG */
   1255 /*  [0,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
   1256 /*  [0,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
   1257 }, {
   1258 /*  [1,0]  */	TNS("fld",F),		TNS("fxch",F),		TNS("fnop",NORM),	TNS("fstp",F),
   1259 /*  [1,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1260 }, {
   1261 /*  [2,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1262 /*  [2,4]  */	INVALID,		TNS("fucompp",NORM),	INVALID,		INVALID,
   1263 }, {
   1264 /*  [3,0]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1265 /*  [3,4]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1266 }, {
   1267 /*  [4,0]  */	TNS("fadd",FF),		TNS("fmul",FF),		TNS("fcom",F),		TNS("fcomp",F),
   1268 /*  [4,4]  */	TNS("fsub",FF),		TNS("fsubr",FF),	TNS("fdiv",FF),		TNS("fdivr",FF),
   1269 }, {
   1270 /*  [5,0]  */	TNS("ffree",F),		TNS("fxch",F),		TNS("fst",F),		TNS("fstp",F),
   1271 /*  [5,4]  */	TNS("fucom",F),		TNS("fucomp",F),	INVALID,		INVALID,
   1272 }, {
   1273 /*  [6,0]  */	TNS("faddp",FF),	TNS("fmulp",FF),	TNS("fcomp",F),		TNS("fcompp",NORM),
   1274 /*  [6,4]  */	TNS("fsubp",FF),	TNS("fsubrp",FF),	TNS("fdivp",FF),	TNS("fdivrp",FF),
   1275 }, {
   1276 /*  [7,0]  */	TNS("ffreep",F),		TNS("fxch",F),		TNS("fstp",F),		TNS("fstp",F),
   1277 /*  [7,4]  */	TNS("fnstsw",M),	TNS("fucomip",FFC),	TNS("fcomip",FFC),	INVALID,
   1278 } };
   1279 
   1280 const instable_t dis_opFP4[4][8] = {
   1281 {
   1282 /* bit pattern:	1101 1001 111x xxxx */
   1283 /*  [0,0]  */	TNS("fchs",NORM),	TNS("fabs",NORM),	INVALID,		INVALID,
   1284 /*  [0,4]  */	TNS("ftst",NORM),	TNS("fxam",NORM),	TNS("ftstp",NORM),	INVALID,
   1285 }, {
   1286 /*  [1,0]  */	TNS("fld1",NORM),	TNS("fldl2t",NORM),	TNS("fldl2e",NORM),	TNS("fldpi",NORM),
   1287 /*  [1,4]  */	TNS("fldlg2",NORM),	TNS("fldln2",NORM),	TNS("fldz",NORM),	INVALID,
   1288 }, {
   1289 /*  [2,0]  */	TNS("f2xm1",NORM),	TNS("fyl2x",NORM),	TNS("fptan",NORM),	TNS("fpatan",NORM),
   1290 /*  [2,4]  */	TNS("fxtract",NORM),	TNS("fprem1",NORM),	TNS("fdecstp",NORM),	TNS("fincstp",NORM),
   1291 }, {
   1292 /*  [3,0]  */	TNS("fprem",NORM),	TNS("fyl2xp1",NORM),	TNS("fsqrt",NORM),	TNS("fsincos",NORM),
   1293 /*  [3,4]  */	TNS("frndint",NORM),	TNS("fscale",NORM),	TNS("fsin",NORM),	TNS("fcos",NORM),
   1294 } };
   1295 
   1296 const instable_t dis_opFP5[8] = {
   1297 /* bit pattern:	1101 1011 111x xxxx */
   1298 /*  [0]  */	TNS("feni",NORM),	TNS("fdisi",NORM),	TNS("fnclex",NORM),	TNS("fninit",NORM),
   1299 /*  [4]  */	TNS("fsetpm",NORM),	TNS("frstpm",NORM),	INVALID,		INVALID,
   1300 };
   1301 
   1302 const instable_t dis_opFP6[8] = {
   1303 /* bit pattern:	1101 1011 11yy yxxx */
   1304 /*  [00]  */	TNS("fcmov.nb",FF),	TNS("fcmov.ne",FF),	TNS("fcmov.nbe",FF),	TNS("fcmov.nu",FF),
   1305 /*  [04]  */	INVALID,		TNS("fucomi",F),	TNS("fcomi",F),		INVALID,
   1306 };
   1307 
   1308 const instable_t dis_opFP7[8] = {
   1309 /* bit pattern:	1101 1010 11yy yxxx */
   1310 /*  [00]  */	TNS("fcmov.b",FF),	TNS("fcmov.e",FF),	TNS("fcmov.be",FF),	TNS("fcmov.u",FF),
   1311 /*  [04]  */	INVALID,		INVALID,		INVALID,		INVALID,
   1312 };
   1313 
   1314 /*
   1315  *	Main decode table for the op codes.  The first two nibbles
   1316  *	will be used as an index into the table.  If there is a
   1317  *	a need to further decode an instruction, the array to be
   1318  *	referenced is indicated with the other two entries being
   1319  *	empty.
   1320  */
   1321 
   1322 const instable_t dis_distable[16][16] = {
   1323 {
   1324 /* [0,0] */	TNS("addb",RMw),	TS("add",RMw),		TNS("addb",MRw),	TS("add",MRw),
   1325 /* [0,4] */	TNS("addb",IA),		TS("add",IA),		TSx("push",SEG),	TSx("pop",SEG),
   1326 /* [0,8] */	TNS("orb",RMw),		TS("or",RMw),		TNS("orb",MRw),		TS("or",MRw),
   1327 /* [0,C] */	TNS("orb",IA),		TS("or",IA),		TSx("push",SEG),	IND(dis_op0F),
   1328 }, {
   1329 /* [1,0] */	TNS("adcb",RMw),	TS("adc",RMw),		TNS("adcb",MRw),	TS("adc",MRw),
   1330 /* [1,4] */	TNS("adcb",IA),		TS("adc",IA),		TSx("push",SEG),	TSx("pop",SEG),
   1331 /* [1,8] */	TNS("sbbb",RMw),	TS("sbb",RMw),		TNS("sbbb",MRw),	TS("sbb",MRw),
   1332 /* [1,C] */	TNS("sbbb",IA),		TS("sbb",IA),		TSx("push",SEG),	TSx("pop",SEG),
   1333 }, {
   1334 /* [2,0] */	TNS("andb",RMw),	TS("and",RMw),		TNS("andb",MRw),	TS("and",MRw),
   1335 /* [2,4] */	TNS("andb",IA),		TS("and",IA),		TNSx("%es:",OVERRIDE),	TNSx("daa",NORM),
   1336 /* [2,8] */	TNS("subb",RMw),	TS("sub",RMw),		TNS("subb",MRw),	TS("sub",MRw),
   1337 /* [2,C] */	TNS("subb",IA),		TS("sub",IA),		TNSx("%cs:",OVERRIDE),	TNSx("das",NORM),
   1338 }, {
   1339 /* [3,0] */	TNS("xorb",RMw),	TS("xor",RMw),		TNS("xorb",MRw),	TS("xor",MRw),
   1340 /* [3,4] */	TNS("xorb",IA),		TS("xor",IA),		TNSx("%ss:",OVERRIDE),	TNSx("aaa",NORM),
   1341 /* [3,8] */	TNS("cmpb",RMw),	TS("cmp",RMw),		TNS("cmpb",MRw),	TS("cmp",MRw),
   1342 /* [3,C] */	TNS("cmpb",IA),		TS("cmp",IA),		TNSx("%ds:",OVERRIDE),	TNSx("aas",NORM),
   1343 }, {
   1344 /* [4,0] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
   1345 /* [4,4] */	TSx("inc",R),		TSx("inc",R),		TSx("inc",R),		TSx("inc",R),
   1346 /* [4,8] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
   1347 /* [4,C] */	TSx("dec",R),		TSx("dec",R),		TSx("dec",R),		TSx("dec",R),
   1348 }, {
   1349 /* [5,0] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
   1350 /* [5,4] */	TSp("push",R),		TSp("push",R),		TSp("push",R),		TSp("push",R),
   1351 /* [5,8] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
   1352 /* [5,C] */	TSp("pop",R),		TSp("pop",R),		TSp("pop",R),		TSp("pop",R),
   1353 }, {
   1354 /* [6,0] */	TSZx("pusha",IMPLMEM,28),TSZx("popa",IMPLMEM,28), TSx("bound",MR),	TNS("arpl",RMw),
   1355 /* [6,4] */	TNS("%fs:",OVERRIDE),	TNS("%gs:",OVERRIDE),	TNS("data16",DM),	TNS("addr16",AM),
   1356 /* [6,8] */	TSp("push",I),		TS("imul",IMUL),	TSp("push",Ib),	TS("imul",IMUL),
   1357 /* [6,C] */	TNSZ("insb",IMPLMEM,1),	TSZ("ins",IMPLMEM,4),	TNSZ("outsb",IMPLMEM,1),TSZ("outs",IMPLMEM,4),
   1358 }, {
   1359 /* [7,0] */	TNSy("jo",BD),		TNSy("jno",BD),		TNSy("jb",BD),		TNSy("jae",BD),
   1360 /* [7,4] */	TNSy("je",BD),		TNSy("jne",BD),		TNSy("jbe",BD),		TNSy("ja",BD),
   1361 /* [7,8] */	TNSy("js",BD),		TNSy("jns",BD),		TNSy("jp",BD),		TNSy("jnp",BD),
   1362 /* [7,C] */	TNSy("jl",BD),		TNSy("jge",BD),		TNSy("jle",BD),		TNSy("jg",BD),
   1363 }, {
   1364 /* [8,0] */	IND(dis_op80),		IND(dis_op81),		INDx(dis_op82),		IND(dis_op83),
   1365 /* [8,4] */	TNS("testb",RMw),	TS("test",RMw),		TNS("xchgb",RMw),	TS("xchg",RMw),
   1366 /* [8,8] */	TNS("movb",RMw),	TS("mov",RMw),		TNS("movb",MRw),	TS("mov",MRw),
   1367 /* [8,C] */	TNS("movw",SM),		TS("lea",MR),		TNS("movw",MS),		TSp("pop",M),
   1368 }, {
   1369 /* [9,0] */	TNS("nop",NORM),	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
   1370 /* [9,4] */	TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),		TS("xchg",RA),
   1371 /* [9,8] */	TNS("cXtX",CBW),	TNS("cXtX",CWD),	TNSx("lcall",SO),	TNS("fwait",NORM),
   1372 /* [9,C] */	TSZy("pushf",IMPLMEM,4),TSZy("popf",IMPLMEM,4),	TNSx("sahf",NORM),	TNSx("lahf",NORM),
   1373 }, {
   1374 /* [A,0] */	TNS("movb",OA),		TS("mov",OA),		TNS("movb",AO),		TS("mov",AO),
   1375 /* [A,4] */	TNSZ("movsb",SD,1),	TS("movs",SD),		TNSZ("cmpsb",SD,1),	TS("cmps",SD),
   1376 /* [A,8] */	TNS("testb",IA),	TS("test",IA),		TNS("stosb",AD),	TS("stos",AD),
   1377 /* [A,C] */	TNS("lodsb",SA),	TS("lods",SA),		TNS("scasb",AD),	TS("scas",AD),
   1378 }, {
   1379 /* [B,0] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
   1380 /* [B,4] */	TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),		TNS("movb",IR),
   1381 /* [B,8] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
   1382 /* [B,C] */	TS("mov",IR),		TS("mov",IR),		TS("mov",IR),		TS("mov",IR),
   1383 }, {
   1384 /* [C,0] */	IND(dis_opC0),		IND(dis_opC1), 		TNSyp("ret",RET),	TNSyp("ret",NORM),
   1385 /* [C,4] */	TNSx("les",MR),		TNSx("lds",MR),		TNS("movb",IMw),	TS("mov",IMw),
   1386 /* [C,8] */	TNSyp("enter",ENTER),	TNSyp("leave",NORM),	TNS("lret",RET),	TNS("lret",NORM),
   1387 /* [C,C] */	TNS("int",INT3),	TNS("int",INTx),	TNSx("into",NORM),	TNS("iret",NORM),
   1388 }, {
   1389 /* [D,0] */	IND(dis_opD0),		IND(dis_opD1),		IND(dis_opD2),		IND(dis_opD3),
   1390 /* [D,4] */	TNSx("aam",U),		TNSx("aad",U),		TNSx("falc",NORM),	TNSZ("xlat",IMPLMEM,1),
   1391 
   1392 /* 287 instructions.  Note that although the indirect field		*/
   1393 /* indicates opFP1n2 for further decoding, this is not necessarily	*/
   1394 /* the case since the opFP arrays are not partitioned according to key1	*/
   1395 /* and key2.  opFP1n2 is given only to indicate that we haven't		*/
   1396 /* finished decoding the instruction.					*/
   1397 /* [D,8] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
   1398 /* [D,C] */	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),	IND(dis_opFP1n2),
   1399 }, {
   1400 /* [E,0] */	TNSy("loopnz",BD),	TNSy("loopz",BD),	TNSy("loop",BD),	TNSy("jcxz",BD),
   1401 /* [E,4] */	TNS("inb",P),		TS("in",P),		TNS("outb",P),		TS("out",P),
   1402 /* [E,8] */	TNSyp("call",D),	TNSy("jmp",D),		TNSx("ljmp",SO),		TNSy("jmp",BD),
   1403 /* [E,C] */	TNS("inb",V),		TS("in",V),		TNS("outb",V),		TS("out",V),
   1404 }, {
   1405 /* [F,0] */	TNS("lock",LOCK),	TNS("icebp", NORM),	TNS("repnz",PREFIX),	TNS("repz",PREFIX),
   1406 /* [F,4] */	TNS("hlt",NORM),	TNS("cmc",NORM),	IND(dis_opF6),		IND(dis_opF7),
   1407 /* [F,8] */	TNS("clc",NORM),	TNS("stc",NORM),	TNS("cli",NORM),	TNS("sti",NORM),
   1408 /* [F,C] */	TNS("cld",NORM),	TNS("std",NORM),	IND(dis_opFE),		IND(dis_opFF),
   1409 } };
   1410 
   1411 /* END CSTYLED */
   1412 
   1413 /*
   1414  * common functions to decode and disassemble an x86 or amd64 instruction
   1415  */
   1416 
   1417 /*
   1418  * These are the individual fields of a REX prefix. Note that a REX
   1419  * prefix with none of these set is still needed to:
   1420  *	- use the MOVSXD (sign extend 32 to 64 bits) instruction
   1421  *	- access the %sil, %dil, %bpl, %spl registers
   1422  */
   1423 #define	REX_W 0x08	/* 64 bit operand size when set */
   1424 #define	REX_R 0x04	/* high order bit extension of ModRM reg field */
   1425 #define	REX_X 0x02	/* high order bit extension of SIB index field */
   1426 #define	REX_B 0x01	/* extends ModRM r_m, SIB base, or opcode reg */
   1427 
   1428 /*
   1429  * Even in 64 bit mode, usually only 4 byte immediate operands are supported.
   1430  */
   1431 static int isize[] = {1, 2, 4, 4};
   1432 static int isize64[] = {1, 2, 4, 8};
   1433 
   1434 /*
   1435  * Just a bunch of useful macros.
   1436  */
   1437 #define	WBIT(x)	(x & 0x1)		/* to get w bit	*/
   1438 #define	REGNO(x) (x & 0x7)		/* to get 3 bit register */
   1439 #define	VBIT(x)	((x)>>1 & 0x1)		/* to get 'v' bit */
   1440 #define	OPSIZE(osize, wbit) ((wbit) ? isize[osize] : 1)
   1441 #define	OPSIZE64(osize, wbit) ((wbit) ? isize64[osize] : 1)
   1442 
   1443 #define	REG_ONLY 3	/* mode to indicate a register operand (not memory) */
   1444 
   1445 #define	BYTE_OPND	0	/* w-bit value indicating byte register */
   1446 #define	LONG_OPND	1	/* w-bit value indicating opnd_size register */
   1447 #define	MM_OPND		2	/* "value" used to indicate a mmx reg */
   1448 #define	XMM_OPND	3	/* "value" used to indicate a xmm reg */
   1449 #define	SEG_OPND	4	/* "value" used to indicate a segment reg */
   1450 #define	CONTROL_OPND	5	/* "value" used to indicate a control reg */
   1451 #define	DEBUG_OPND	6	/* "value" used to indicate a debug reg */
   1452 #define	TEST_OPND	7	/* "value" used to indicate a test reg */
   1453 #define	WORD_OPND	8	/* w-bit value indicating word size reg */
   1454 
   1455 /*
   1456  * Get the next byte and separate the op code into the high and low nibbles.
   1457  */
   1458 static int
   1459 dtrace_get_opcode(dis86_t *x, uint_t *high, uint_t *low)
   1460 {
   1461 	int byte;
   1462 
   1463 	/*
   1464 	 * x86 instructions have a maximum length of 15 bytes.  Bail out if
   1465 	 * we try to read more.
   1466 	 */
   1467 	if (x->d86_len >= 15)
   1468 		return (x->d86_error = 1);
   1469 
   1470 	if (x->d86_error)
   1471 		return (1);
   1472 	byte = x->d86_get_byte(x->d86_data);
   1473 	if (byte < 0)
   1474 		return (x->d86_error = 1);
   1475 	x->d86_bytes[x->d86_len++] = byte;
   1476 	*low = byte & 0xf;		/* ----xxxx low 4 bits */
   1477 	*high = byte >> 4 & 0xf;	/* xxxx---- bits 7 to 4 */
   1478 	return (0);
   1479 }
   1480 
   1481 /*
   1482  * Get and decode an SIB (scaled index base) byte
   1483  */
   1484 static void
   1485 dtrace_get_SIB(dis86_t *x, uint_t *ss, uint_t *index, uint_t *base)
   1486 {
   1487 	int byte;
   1488 
   1489 	if (x->d86_error)
   1490 		return;
   1491 
   1492 	byte = x->d86_get_byte(x->d86_data);
   1493 	if (byte < 0) {
   1494 		x->d86_error = 1;
   1495 		return;
   1496 	}
   1497 	x->d86_bytes[x->d86_len++] = byte;
   1498 
   1499 	*base = byte & 0x7;
   1500 	*index = (byte >> 3) & 0x7;
   1501 	*ss = (byte >> 6) & 0x3;
   1502 }
   1503 
   1504 /*
   1505  * Get the byte following the op code and separate it into the
   1506  * mode, register, and r/m fields.
   1507  */
   1508 static void
   1509 dtrace_get_modrm(dis86_t *x, uint_t *mode, uint_t *reg, uint_t *r_m)
   1510 {
   1511 	if (x->d86_got_modrm == 0) {
   1512 		if (x->d86_rmindex == -1)
   1513 			x->d86_rmindex = x->d86_len;
   1514 		dtrace_get_SIB(x, mode, reg, r_m);
   1515 		x->d86_got_modrm = 1;
   1516 	}
   1517 }
   1518 
   1519 /*
   1520  * Adjust register selection based on any REX prefix bits present.
   1521  */
   1522 /*ARGSUSED*/
   1523 static void
   1524 dtrace_rex_adjust(uint_t rex_prefix, uint_t mode, uint_t *reg, uint_t *r_m)
   1525 {
   1526 	if (reg != NULL && r_m == NULL) {
   1527 		if (rex_prefix & REX_B)
   1528 			*reg += 8;
   1529 	} else {
   1530 		if (reg != NULL && (REX_R & rex_prefix) != 0)
   1531 			*reg += 8;
   1532 		if (r_m != NULL && (REX_B & rex_prefix) != 0)
   1533 			*r_m += 8;
   1534 	}
   1535 }
   1536 
   1537 /*
   1538  * Get an immediate operand of the given size, with sign extension.
   1539  */
   1540 static void
   1541 dtrace_imm_opnd(dis86_t *x, int wbit, int size, int opindex)
   1542 {
   1543 	int i;
   1544 	int byte;
   1545 	int valsize;
   1546 
   1547 	if (x->d86_numopnds < opindex + 1)
   1548 		x->d86_numopnds = opindex + 1;
   1549 
   1550 	switch (wbit) {
   1551 	case BYTE_OPND:
   1552 		valsize = 1;
   1553 		break;
   1554 	case LONG_OPND:
   1555 		if (x->d86_opnd_size == SIZE16)
   1556 			valsize = 2;
   1557 		else if (x->d86_opnd_size == SIZE32)
   1558 			valsize = 4;
   1559 		else
   1560 			valsize = 8;
   1561 		break;
   1562 	case MM_OPND:
   1563 	case XMM_OPND:
   1564 	case SEG_OPND:
   1565 	case CONTROL_OPND:
   1566 	case DEBUG_OPND:
   1567 	case TEST_OPND:
   1568 		valsize = size;
   1569 		break;
   1570 	case WORD_OPND:
   1571 		valsize = 2;
   1572 		break;
   1573 	}
   1574 	if (valsize < size)
   1575 		valsize = size;
   1576 
   1577 	if (x->d86_error)
   1578 		return;
   1579 	x->d86_opnd[opindex].d86_value = 0;
   1580 	for (i = 0; i < size; ++i) {
   1581 		byte = x->d86_get_byte(x->d86_data);
   1582 		if (byte < 0) {
   1583 			x->d86_error = 1;
   1584 			return;
   1585 		}
   1586 		x->d86_bytes[x->d86_len++] = byte;
   1587 		x->d86_opnd[opindex].d86_value |= (uint64_t)byte << (i * 8);
   1588 	}
   1589 	/* Do sign extension */
   1590 	if (x->d86_bytes[x->d86_len - 1] & 0x80) {
   1591 		for (; i < sizeof (uint64_t); i++)
   1592 			x->d86_opnd[opindex].d86_value |=
   1593 			    (uint64_t)0xff << (i * 8);
   1594 	}
   1595 #ifdef DIS_TEXT
   1596 	x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
   1597 	x->d86_opnd[opindex].d86_value_size = valsize;
   1598 	x->d86_imm_bytes += size;
   1599 #endif
   1600 }
   1601 
   1602 /*
   1603  * Get an ip relative operand of the given size, with sign extension.
   1604  */
   1605 static void
   1606 dtrace_disp_opnd(dis86_t *x, int wbit, int size, int opindex)
   1607 {
   1608 	dtrace_imm_opnd(x, wbit, size, opindex);
   1609 #ifdef DIS_TEXT
   1610 	x->d86_opnd[opindex].d86_mode = MODE_IPREL;
   1611 #endif
   1612 }
   1613 
   1614 /*
   1615  * Check to see if there is a segment override prefix pending.
   1616  * If so, print it in the current 'operand' location and set
   1617  * the override flag back to false.
   1618  */
   1619 /*ARGSUSED*/
   1620 static void
   1621 dtrace_check_override(dis86_t *x, int opindex)
   1622 {
   1623 #ifdef DIS_TEXT
   1624 	if (x->d86_seg_prefix) {
   1625 		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
   1626 		    x->d86_seg_prefix, PFIXLEN);
   1627 	}
   1628 #endif
   1629 	x->d86_seg_prefix = NULL;
   1630 }
   1631 
   1632 
   1633 /*
   1634  * Process a single instruction Register or Memory operand.
   1635  *
   1636  * mode = addressing mode from ModRM byte
   1637  * r_m = r_m (or reg if mode == 3) field from ModRM byte
   1638  * wbit = indicates which register (8bit, 16bit, ... MMX, etc.) set to use.
   1639  * o = index of operand that we are processing (0, 1 or 2)
   1640  *
   1641  * the value of reg or r_m must have already been adjusted for any REX prefix.
   1642  */
   1643 /*ARGSUSED*/
   1644 static void
   1645 dtrace_get_operand(dis86_t *x, uint_t mode, uint_t r_m, int wbit, int opindex)
   1646 {
   1647 	int have_SIB = 0;	/* flag presence of scale-index-byte */
   1648 	uint_t ss;		/* scale-factor from opcode */
   1649 	uint_t index;		/* index register number */
   1650 	uint_t base;		/* base register number */
   1651 	int dispsize;   	/* size of displacement in bytes */
   1652 #ifdef DIS_TEXT
   1653 	char *opnd = x->d86_opnd[opindex].d86_opnd;
   1654 #endif
   1655 
   1656 	if (x->d86_numopnds < opindex + 1)
   1657 		x->d86_numopnds = opindex + 1;
   1658 
   1659 	if (x->d86_error)
   1660 		return;
   1661 
   1662 	/*
   1663 	 * first handle a simple register
   1664 	 */
   1665 	if (mode == REG_ONLY) {
   1666 #ifdef DIS_TEXT
   1667 		switch (wbit) {
   1668 		case MM_OPND:
   1669 			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
   1670 			break;
   1671 		case XMM_OPND:
   1672 			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
   1673 			break;
   1674 		case SEG_OPND:
   1675 			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
   1676 			break;
   1677 		case CONTROL_OPND:
   1678 			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
   1679 			break;
   1680 		case DEBUG_OPND:
   1681 			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
   1682 			break;
   1683 		case TEST_OPND:
   1684 			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
   1685 			break;
   1686 		case BYTE_OPND:
   1687 			if (x->d86_rex_prefix == 0)
   1688 				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
   1689 			else
   1690 				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
   1691 			break;
   1692 		case WORD_OPND:
   1693 			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
   1694 			break;
   1695 		case LONG_OPND:
   1696 			if (x->d86_opnd_size == SIZE16)
   1697 				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
   1698 			else if (x->d86_opnd_size == SIZE32)
   1699 				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
   1700 			else
   1701 				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
   1702 			break;
   1703 		}
   1704 #endif /* DIS_TEXT */
   1705 		return;
   1706 	}
   1707 
   1708 	/*
   1709 	 * if symbolic representation, skip override prefix, if any
   1710 	 */
   1711 	dtrace_check_override(x, opindex);
   1712 
   1713 	/*
   1714 	 * Handle 16 bit memory references first, since they decode
   1715 	 * the mode values more simply.
   1716 	 * mode 1 is r_m + 8 bit displacement
   1717 	 * mode 2 is r_m + 16 bit displacement
   1718 	 * mode 0 is just r_m, unless r_m is 6 which is 16 bit disp
   1719 	 */
   1720 	if (x->d86_addr_size == SIZE16) {
   1721 		if ((mode == 0 && r_m == 6) || mode == 2)
   1722 			dtrace_imm_opnd(x, WORD_OPND, 2, opindex);
   1723 		else if (mode == 1)
   1724 			dtrace_imm_opnd(x, BYTE_OPND, 1, opindex);
   1725 #ifdef DIS_TEXT
   1726 		if (mode == 0 && r_m == 6)
   1727 			x->d86_opnd[opindex].d86_mode = MODE_SIGNED;
   1728 		else if (mode == 0)
   1729 			x->d86_opnd[opindex].d86_mode = MODE_NONE;
   1730 		else
   1731 			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
   1732 		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
   1733 #endif
   1734 		return;
   1735 	}
   1736 
   1737 	/*
   1738 	 * 32 and 64 bit addressing modes are more complex since they
   1739 	 * can involve an SIB (scaled index and base) byte to decode.
   1740 	 */
   1741 	if (r_m == ESP_REGNO || r_m == ESP_REGNO + 8) {
   1742 		have_SIB = 1;
   1743 		dtrace_get_SIB(x, &ss, &index, &base);
   1744 		if (x->d86_error)
   1745 			return;
   1746 		if (base != 5 || mode != 0)
   1747 			if (x->d86_rex_prefix & REX_B)
   1748 				base += 8;
   1749 		if (x->d86_rex_prefix & REX_X)
   1750 			index += 8;
   1751 	} else {
   1752 		base = r_m;
   1753 	}
   1754 
   1755 	/*
   1756 	 * Compute the displacement size and get its bytes
   1757 	 */
   1758 	dispsize = 0;
   1759 
   1760 	if (mode == 1)
   1761 		dispsize = 1;
   1762 	else if (mode == 2)
   1763 		dispsize = 4;
   1764 	else if ((r_m & 7) == EBP_REGNO ||
   1765 	    (have_SIB && (base & 7) == EBP_REGNO))
   1766 		dispsize = 4;
   1767 
   1768 	if (dispsize > 0) {
   1769 		dtrace_imm_opnd(x, dispsize == 4 ? LONG_OPND : BYTE_OPND,
   1770 		    dispsize, opindex);
   1771 		if (x->d86_error)
   1772 			return;
   1773 	}
   1774 
   1775 #ifdef DIS_TEXT
   1776 	if (dispsize > 0)
   1777 		x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
   1778 
   1779 	if (have_SIB == 0) {
   1780 		if (x->d86_mode == SIZE32) {
   1781 			if (mode == 0)
   1782 				(void) strlcat(opnd, dis_addr32_mode0[r_m],
   1783 				    OPLEN);
   1784 			else
   1785 				(void) strlcat(opnd, dis_addr32_mode12[r_m],
   1786 				    OPLEN);
   1787 		} else {
   1788 			if (mode == 0) {
   1789 				(void) strlcat(opnd, dis_addr64_mode0[r_m],
   1790 				    OPLEN);
   1791 				if (r_m == 5) {
   1792 					x->d86_opnd[opindex].d86_mode =
   1793 					    MODE_RIPREL;
   1794 				}
   1795 			} else {
   1796 				(void) strlcat(opnd, dis_addr64_mode12[r_m],
   1797 				    OPLEN);
   1798 			}
   1799 		}
   1800 	} else {
   1801 		uint_t need_paren = 0;
   1802 		char **regs;
   1803 		if (x->d86_mode == SIZE32) /* NOTE this is not addr_size! */
   1804 			regs = (char **)dis_REG32;
   1805 		else
   1806 			regs = (char **)dis_REG64;
   1807 
   1808 		/*
   1809 		 * print the base (if any)
   1810 		 */
   1811 		if (base == EBP_REGNO && mode == 0) {
   1812 			if (index != ESP_REGNO) {
   1813 				(void) strlcat(opnd, "(", OPLEN);
   1814 				need_paren = 1;
   1815 			}
   1816 		} else {
   1817 			(void) strlcat(opnd, "(", OPLEN);
   1818 			(void) strlcat(opnd, regs[base], OPLEN);
   1819 			need_paren = 1;
   1820 		}
   1821 
   1822 		/*
   1823 		 * print the index (if any)
   1824 		 */
   1825 		if (index != ESP_REGNO) {
   1826 			(void) strlcat(opnd, ",", OPLEN);
   1827 			(void) strlcat(opnd, regs[index], OPLEN);
   1828 			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
   1829 		} else
   1830 			if (need_paren)
   1831 				(void) strlcat(opnd, ")", OPLEN);
   1832 	}
   1833 #endif
   1834 }
   1835 
   1836 /*
   1837  * Operand sequence for standard instruction involving one register
   1838  * and one register/memory operand.
   1839  * wbit indicates a byte(0) or opnd_size(1) operation
   1840  * vbit indicates direction (0 for "opcode r,r_m") or (1 for "opcode r_m, r")
   1841  */
   1842 #define	STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, vbit)  {	\
   1843 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
   1844 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
   1845 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
   1846 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1 - vbit);	\
   1847 }
   1848 
   1849 /*
   1850  * Similar to above, but allows for the two operands to be of different
   1851  * classes (ie. wbit).
   1852  *	wbit is for the r_m operand
   1853  *	w2 is for the reg operand
   1854  */
   1855 #define	MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, w2, vbit)	{	\
   1856 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
   1857 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
   1858 		dtrace_get_operand(x, mode, r_m, wbit, vbit);		\
   1859 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1 - vbit);	\
   1860 }
   1861 
   1862 /*
   1863  * Similar, but for 2 operands plus an immediate.
   1864  * vbit indicates direction
   1865  * 	0 for "opcode imm, r, r_m" or
   1866  *	1 for "opcode imm, r_m, r"
   1867  */
   1868 #define	THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize, vbit) { \
   1869 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
   1870 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
   1871 		dtrace_get_operand(x, mode, r_m, wbit, 2-vbit);		\
   1872 		dtrace_get_operand(x, REG_ONLY, reg, w2, 1+vbit);	\
   1873 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
   1874 }
   1875 
   1876 /*
   1877  * Similar, but for 2 operands plus two immediates.
   1878  */
   1879 #define	FOUROPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, immsize) { \
   1880 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
   1881 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
   1882 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
   1883 		dtrace_get_operand(x, REG_ONLY, reg, w2, 3);		\
   1884 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
   1885 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
   1886 }
   1887 
   1888 /*
   1889  * 1 operands plus two immediates.
   1890  */
   1891 #define	ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, wbit, immsize) { \
   1892 		dtrace_get_modrm(x, &mode, &reg, &r_m);			\
   1893 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);	\
   1894 		dtrace_get_operand(x, mode, r_m, wbit, 2);		\
   1895 		dtrace_imm_opnd(x, wbit, immsize, 1);			\
   1896 		dtrace_imm_opnd(x, wbit, immsize, 0);			\
   1897 }
   1898 
   1899 /*
   1900  * Dissassemble a single x86 or amd64 instruction.
   1901  *
   1902  * Mode determines the default operating mode (SIZE16, SIZE32 or SIZE64)
   1903  * for interpreting instructions.
   1904  *
   1905  * returns non-zero for bad opcode
   1906  */
   1907 int
   1908 dtrace_disx86(dis86_t *x, uint_t cpu_mode)
   1909 {
   1910 	instable_t *dp;		/* decode table being used */
   1911 #ifdef DIS_TEXT
   1912 	uint_t i;
   1913 #endif
   1914 #ifdef DIS_MEM
   1915 	uint_t nomem = 0;
   1916 #define	NOMEM	(nomem = 1)
   1917 #else
   1918 #define	NOMEM	/* nothing */
   1919 #endif
   1920 	uint_t opnd_size;	/* SIZE16, SIZE32 or SIZE64 */
   1921 	uint_t addr_size;	/* SIZE16, SIZE32 or SIZE64 */
   1922 	uint_t wbit;		/* opcode wbit, 0 is 8 bit, !0 for opnd_size */
   1923 	uint_t w2;		/* wbit value for second operand */
   1924 	uint_t vbit;
   1925 	uint_t mode = 0;	/* mode value from ModRM byte */
   1926 	uint_t reg;		/* reg value from ModRM byte */
   1927 	uint_t r_m;		/* r_m value from ModRM byte */
   1928 
   1929 	uint_t opcode1;		/* high nibble of 1st byte */
   1930 	uint_t opcode2;		/* low nibble of 1st byte */
   1931 	uint_t opcode3;		/* extra opcode bits usually from ModRM byte */
   1932 	uint_t opcode4;		/* high nibble of 2nd byte */
   1933 	uint_t opcode5;		/* low nibble of 2nd byte */
   1934 	uint_t opcode6;		/* high nibble of 3rd byte */
   1935 	uint_t opcode7;		/* low nibble of 3rd byte */
   1936 	uint_t opcode_bytes = 1;
   1937 
   1938 	/*
   1939 	 * legacy prefixes come in 5 flavors, you should have only one of each
   1940 	 */
   1941 	uint_t	opnd_size_prefix = 0;
   1942 	uint_t	addr_size_prefix = 0;
   1943 	uint_t	segment_prefix = 0;
   1944 	uint_t	lock_prefix = 0;
   1945 	uint_t	rep_prefix = 0;
   1946 	uint_t	rex_prefix = 0;	/* amd64 register extension prefix */
   1947 	size_t	off;
   1948 
   1949 	instable_t dp_mmx;
   1950 
   1951 	x->d86_len = 0;
   1952 	x->d86_rmindex = -1;
   1953 	x->d86_error = 0;
   1954 #ifdef DIS_TEXT
   1955 	x->d86_numopnds = 0;
   1956 	x->d86_seg_prefix = NULL;
   1957 	x->d86_mnem[0] = 0;
   1958 	for (i = 0; i < 4; ++i) {
   1959 		x->d86_opnd[i].d86_opnd[0] = 0;
   1960 		x->d86_opnd[i].d86_prefix[0] = 0;
   1961 		x->d86_opnd[i].d86_value_size = 0;
   1962 		x->d86_opnd[i].d86_value = 0;
   1963 		x->d86_opnd[i].d86_mode = MODE_NONE;
   1964 	}
   1965 #endif
   1966 	x->d86_error = 0;
   1967 	x->d86_memsize = 0;
   1968 
   1969 	if (cpu_mode == SIZE16) {
   1970 		opnd_size = SIZE16;
   1971 		addr_size = SIZE16;
   1972 	} else if (cpu_mode == SIZE32) {
   1973 		opnd_size = SIZE32;
   1974 		addr_size = SIZE32;
   1975 	} else {
   1976 		opnd_size = SIZE32;
   1977 		addr_size = SIZE64;
   1978 	}
   1979 
   1980 	/*
   1981 	 * Get one opcode byte and check for zero padding that follows
   1982 	 * jump tables.
   1983 	 */
   1984 	if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
   1985 		goto error;
   1986 
   1987 	if (opcode1 == 0 && opcode2 == 0 &&
   1988 	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
   1989 #ifdef DIS_TEXT
   1990 		(void) strncpy(x->d86_mnem, ".byte\t0", OPLEN);
   1991 #endif
   1992 		goto done;
   1993 	}
   1994 
   1995 	/*
   1996 	 * Gather up legacy x86 prefix bytes.
   1997 	 */
   1998 	for (;;) {
   1999 		uint_t *which_prefix = NULL;
   2000 
   2001 		dp = (instable_t *)&dis_distable[opcode1][opcode2];
   2002 
   2003 		switch (dp->it_adrmode) {
   2004 		case PREFIX:
   2005 			which_prefix = &rep_prefix;
   2006 			break;
   2007 		case LOCK:
   2008 			which_prefix = &lock_prefix;
   2009 			break;
   2010 		case OVERRIDE:
   2011 			which_prefix = &segment_prefix;
   2012 #ifdef DIS_TEXT
   2013 			x->d86_seg_prefix = (char *)dp->it_name;
   2014 #endif
   2015 			if (dp->it_invalid64 && cpu_mode == SIZE64)
   2016 				goto error;
   2017 			break;
   2018 		case AM:
   2019 			which_prefix = &addr_size_prefix;
   2020 			break;
   2021 		case DM:
   2022 			which_prefix = &opnd_size_prefix;
   2023 			break;
   2024 		}
   2025 		if (which_prefix == NULL)
   2026 			break;
   2027 		*which_prefix = (opcode1 << 4) | opcode2;
   2028 		if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
   2029 			goto error;
   2030 	}
   2031 
   2032 	/*
   2033 	 * Handle amd64 mode PREFIX values.
   2034 	 * Some of the segment prefixes are no-ops. (only FS/GS actually work)
   2035 	 * We might have a REX prefix (opcodes 0x40-0x4f)
   2036 	 */
   2037 	if (cpu_mode == SIZE64) {
   2038 		if (segment_prefix != 0x64 && segment_prefix != 0x65)
   2039 			segment_prefix = 0;
   2040 
   2041 		if (opcode1 == 0x4) {
   2042 			rex_prefix = (opcode1 << 4) | opcode2;
   2043 			if (dtrace_get_opcode(x, &opcode1, &opcode2) != 0)
   2044 				goto error;
   2045 			dp = (instable_t *)&dis_distable[opcode1][opcode2];
   2046 		}
   2047 	}
   2048 
   2049 	/*
   2050 	 * Deal with selection of operand and address size now.
   2051 	 * Note that the REX.W bit being set causes opnd_size_prefix to be
   2052 	 * ignored.
   2053 	 */
   2054 	if (cpu_mode == SIZE64) {
   2055 		if (rex_prefix & REX_W)
   2056 			opnd_size = SIZE64;
   2057 		else if (opnd_size_prefix)
   2058 			opnd_size = SIZE16;
   2059 
   2060 		if (addr_size_prefix)
   2061 			addr_size = SIZE32;
   2062 	} else if (cpu_mode == SIZE32) {
   2063 		if (opnd_size_prefix)
   2064 			opnd_size = SIZE16;
   2065 		if (addr_size_prefix)
   2066 			addr_size = SIZE16;
   2067 	} else {
   2068 		if (opnd_size_prefix)
   2069 			opnd_size = SIZE32;
   2070 		if (addr_size_prefix)
   2071 			addr_size = SIZE32;
   2072 	}
   2073 
   2074 	/*
   2075 	 * The pause instruction - a repz'd nop.  This doesn't fit
   2076 	 * with any of the other prefix goop added for SSE, so we'll
   2077 	 * special-case it here.
   2078 	 */
   2079 	if (rep_prefix == 0xf3 && opcode1 == 0x9 && opcode2 == 0x0) {
   2080 		rep_prefix = 0;
   2081 		dp = (instable_t *)&dis_opPause;
   2082 	}
   2083 
   2084 	/*
   2085 	 * Some 386 instructions have 2 bytes of opcode before the mod_r/m
   2086 	 * byte so we may need to perform a table indirection.
   2087 	 */
   2088 	if (dp->it_indirect == (instable_t *)dis_op0F) {
   2089 		if (dtrace_get_opcode(x, &opcode4, &opcode5) != 0)
   2090 			goto error;
   2091 		opcode_bytes = 2;
   2092 		if (opcode4 == 0x7 && opcode5 >= 0x1 && opcode5 <= 0x3) {
   2093 			uint_t	subcode;
   2094 
   2095 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
   2096 				goto error;
   2097 			opcode_bytes = 3;
   2098 			subcode = ((opcode6 & 0x3) << 1) |
   2099 			    ((opcode7 & 0x8) >> 3);
   2100 			dp = (instable_t *)&dis_op0F7123[opcode5][subcode];
   2101 		} else if ((opcode4 == 0xc) && (opcode5 >= 0x8)) {
   2102 			dp = (instable_t *)&dis_op0FC8[0];
   2103 		} else if ((opcode4 == 0x3) && (opcode5 == 0xA)) {
   2104 			opcode_bytes = 3;
   2105 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
   2106 				goto error;
   2107 			if (opnd_size == SIZE16)
   2108 				opnd_size = SIZE32;
   2109 
   2110 			dp = (instable_t *)&dis_op0F3A[(opcode6<<4)|opcode7];
   2111 #ifdef DIS_TEXT
   2112 			if (strcmp(dp->it_name, "INVALID") == 0)
   2113 				goto error;
   2114 #endif
   2115 			switch (dp->it_adrmode) {
   2116 				case XMMP_66r:
   2117 				case XMMPRM_66r:
   2118 				case XMM3PM_66r:
   2119 					if (opnd_size_prefix == 0) {
   2120 						goto error;
   2121 					}
   2122 					break;
   2123 				case XMMP_66o:
   2124 					if (opnd_size_prefix == 0) {
   2125 						/* SSSE3 MMX instructions */
   2126 						dp_mmx = *dp;
   2127 						dp = &dp_mmx;
   2128 						dp->it_adrmode = MMOPM_66o;
   2129 #ifdef	DIS_MEM
   2130 						dp->it_size = 8;
   2131 #endif
   2132 					}
   2133 					break;
   2134 				default:
   2135 					goto error;
   2136 			}
   2137 		} else if ((opcode4 == 0x3) && (opcode5 == 0x8)) {
   2138 			opcode_bytes = 3;
   2139 			if (dtrace_get_opcode(x, &opcode6, &opcode7) != 0)
   2140 				goto error;
   2141 			dp = (instable_t *)&dis_op0F38[(opcode6<<4)|opcode7];
   2142 
   2143 			/*
   2144 			 * Both crc32 and movbe have the same 3rd opcode
   2145 			 * byte of either 0xF0 or 0xF1, so we use another
   2146 			 * indirection to distinguish between the two.
   2147 			 */
   2148 			if (dp->it_indirect == (instable_t *)dis_op0F38F0 ||
   2149 			    dp->it_indirect == (instable_t *)dis_op0F38F1) {
   2150 
   2151 				dp = dp->it_indirect;
   2152 				if (rep_prefix != 0xF2) {
   2153 					/* It is movbe */
   2154 					dp++;
   2155 				}
   2156 			}
   2157 #ifdef DIS_TEXT
   2158 			if (strcmp(dp->it_name, "INVALID") == 0)
   2159 				goto error;
   2160 #endif
   2161 			switch (dp->it_adrmode) {
   2162 				case XMM_66r:
   2163 				case XMMM_66r:
   2164 					if (opnd_size_prefix == 0) {
   2165 						goto error;
   2166 					}
   2167 					break;
   2168 				case XMM_66o:
   2169 					if (opnd_size_prefix == 0) {
   2170 						/* SSSE3 MMX instructions */
   2171 						dp_mmx = *dp;
   2172 						dp = &dp_mmx;
   2173 						dp->it_adrmode = MM;
   2174 #ifdef	DIS_MEM
   2175 						dp->it_size = 8;
   2176 #endif
   2177 					}
   2178 					break;
   2179 				case CRC32:
   2180 					if (rep_prefix != 0xF2) {
   2181 						goto error;
   2182 					}
   2183 					rep_prefix = 0;
   2184 					break;
   2185 				case MOVBE:
   2186 					if (rep_prefix != 0x0) {
   2187 						goto error;
   2188 					}
   2189 					break;
   2190 				default:
   2191 					goto error;
   2192 			}
   2193 		} else {
   2194 			dp = (instable_t *)&dis_op0F[opcode4][opcode5];
   2195 		}
   2196 	}
   2197 
   2198 	/*
   2199 	 * If still not at a TERM decode entry, then a ModRM byte
   2200 	 * exists and its fields further decode the instruction.
   2201 	 */
   2202 	x->d86_got_modrm = 0;
   2203 	if (dp->it_indirect != TERM) {
   2204 		dtrace_get_modrm(x, &mode, &opcode3, &r_m);
   2205 		if (x->d86_error)
   2206 			goto error;
   2207 		reg = opcode3;
   2208 
   2209 		/*
   2210 		 * decode 287 instructions (D8-DF) from opcodeN
   2211 		 */
   2212 		if (opcode1 == 0xD && opcode2 >= 0x8) {
   2213 			if (opcode2 == 0xB && mode == 0x3 && opcode3 == 4)
   2214 				dp = (instable_t *)&dis_opFP5[r_m];
   2215 			else if (opcode2 == 0xA && mode == 0x3 && opcode3 < 4)
   2216 				dp = (instable_t *)&dis_opFP7[opcode3];
   2217 			else if (opcode2 == 0xB && mode == 0x3)
   2218 				dp = (instable_t *)&dis_opFP6[opcode3];
   2219 			else if (opcode2 == 0x9 && mode == 0x3 && opcode3 >= 4)
   2220 				dp = (instable_t *)&dis_opFP4[opcode3 - 4][r_m];
   2221 			else if (mode == 0x3)
   2222 				dp = (instable_t *)
   2223 				    &dis_opFP3[opcode2 - 8][opcode3];
   2224 			else
   2225 				dp = (instable_t *)
   2226 				    &dis_opFP1n2[opcode2 - 8][opcode3];
   2227 		} else {
   2228 			dp = (instable_t *)dp->it_indirect + opcode3;
   2229 		}
   2230 	}
   2231 
   2232 	/*
   2233 	 * In amd64 bit mode, ARPL opcode is changed to MOVSXD
   2234 	 * (sign extend 32bit to 64 bit)
   2235 	 */
   2236 	if (cpu_mode == SIZE64 && opcode1 == 0x6 && opcode2 == 0x3)
   2237 		dp = (instable_t *)&dis_opMOVSLD;
   2238 
   2239 	/*
   2240 	 * at this point we should have a correct (or invalid) opcode
   2241 	 */
   2242 	if (cpu_mode == SIZE64 && dp->it_invalid64 ||
   2243 	    cpu_mode != SIZE64 && dp->it_invalid32)
   2244 		goto error;
   2245 	if (dp->it_indirect != TERM)
   2246 		goto error;
   2247 
   2248 	/*
   2249 	 * deal with MMX/SSE opcodes which are changed by prefixes
   2250 	 */
   2251 	switch (dp->it_adrmode) {
   2252 	case MMO:
   2253 	case MMOIMPL:
   2254 	case MMO3P:
   2255 	case MMOM3:
   2256 	case MMOMS:
   2257 	case MMOPM:
   2258 	case MMOPRM:
   2259 	case MMOS:
   2260 	case XMMO:
   2261 	case XMMOM:
   2262 	case XMMOMS:
   2263 	case XMMOPM:
   2264 	case XMMOS:
   2265 	case XMMOMX:
   2266 	case XMMOX3:
   2267 	case XMMOXMM:
   2268 		/*
   2269 		 * This is horrible.  Some SIMD instructions take the
   2270 		 * form 0x0F 0x?? ..., which is easily decoded using the
   2271 		 * existing tables.  Other SIMD instructions use various
   2272 		 * prefix bytes to overload existing instructions.  For
   2273 		 * Example, addps is F0, 58, whereas addss is F3 (repz),
   2274 		 * F0, 58.  Presumably someone got a raise for this.
   2275 		 *
   2276 		 * If we see one of the instructions which can be
   2277 		 * modified in this way (if we've got one of the SIMDO*
   2278 		 * address modes), we'll check to see if the last prefix
   2279 		 * was a repz.  If it was, we strip the prefix from the
   2280 		 * mnemonic, and we indirect using the dis_opSIMDrepz
   2281 		 * table.
   2282 		 */
   2283 
   2284 		/*
   2285 		 * Calculate our offset in dis_op0F
   2286 		 */
   2287 		if ((uintptr_t)dp - (uintptr_t)dis_op0F > sizeof (dis_op0F))
   2288 			goto error;
   2289 
   2290 		off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
   2291 		    sizeof (instable_t);
   2292 
   2293 		/*
   2294 		 * Rewrite if this instruction used one of the magic prefixes.
   2295 		 */
   2296 		if (rep_prefix) {
   2297 			if (rep_prefix == 0xf2)
   2298 				dp = (instable_t *)&dis_opSIMDrepnz[off];
   2299 			else
   2300 				dp = (instable_t *)&dis_opSIMDrepz[off];
   2301 			rep_prefix = 0;
   2302 		} else if (opnd_size_prefix) {
   2303 			dp = (instable_t *)&dis_opSIMDdata16[off];
   2304 			opnd_size_prefix = 0;
   2305 			if (opnd_size == SIZE16)
   2306 				opnd_size = SIZE32;
   2307 		}
   2308 		break;
   2309 
   2310 	case MMOSH:
   2311 		/*
   2312 		 * As with the "normal" SIMD instructions, the MMX
   2313 		 * shuffle instructions are overloaded.  These
   2314 		 * instructions, however, are special in that they use
   2315 		 * an extra byte, and thus an extra table.  As of this
   2316 		 * writing, they only use the opnd_size prefix.
   2317 		 */
   2318 
   2319 		/*
   2320 		 * Calculate our offset in dis_op0F7123
   2321 		 */
   2322 		if ((uintptr_t)dp - (uintptr_t)dis_op0F7123 >
   2323 		    sizeof (dis_op0F7123))
   2324 			goto error;
   2325 
   2326 		if (opnd_size_prefix) {
   2327 			off = ((uintptr_t)dp - (uintptr_t)dis_op0F7123) /
   2328 			    sizeof (instable_t);
   2329 			dp = (instable_t *)&dis_opSIMD7123[off];
   2330 			opnd_size_prefix = 0;
   2331 			if (opnd_size == SIZE16)
   2332 				opnd_size = SIZE32;
   2333 		}
   2334 		break;
   2335 	case MRw:
   2336 		if (rep_prefix) {
   2337 			if (rep_prefix == 0xf3) {
   2338 
   2339 				/*
   2340 				 * Calculate our offset in dis_op0F
   2341 				 */
   2342 				if ((uintptr_t)dp - (uintptr_t)dis_op0F
   2343 				    > sizeof (dis_op0F))
   2344 					goto error;
   2345 
   2346 				off = ((uintptr_t)dp - (uintptr_t)dis_op0F) /
   2347 				    sizeof (instable_t);
   2348 
   2349 				dp = (instable_t *)&dis_opSIMDrepz[off];
   2350 				rep_prefix = 0;
   2351 			} else {
   2352 				goto error;
   2353 			}
   2354 		}
   2355 		break;
   2356 	}
   2357 
   2358 	/*
   2359 	 * In 64 bit mode, some opcodes automatically use opnd_size == SIZE64.
   2360 	 */
   2361 	if (cpu_mode == SIZE64)
   2362 		if (dp->it_always64 || (opnd_size == SIZE32 && dp->it_stackop))
   2363 			opnd_size = SIZE64;
   2364 
   2365 #ifdef DIS_TEXT
   2366 	/*
   2367 	 * At this point most instructions can format the opcode mnemonic
   2368 	 * including the prefixes.
   2369 	 */
   2370 	if (lock_prefix)
   2371 		(void) strlcat(x->d86_mnem, "lock ", OPLEN);
   2372 
   2373 	if (rep_prefix == 0xf2)
   2374 		(void) strlcat(x->d86_mnem, "repnz ", OPLEN);
   2375 	else if (rep_prefix == 0xf3)
   2376 		(void) strlcat(x->d86_mnem, "repz ", OPLEN);
   2377 
   2378 	if (cpu_mode == SIZE64 && addr_size_prefix)
   2379 		(void) strlcat(x->d86_mnem, "addr32 ", OPLEN);
   2380 
   2381 	if (dp->it_adrmode != CBW &&
   2382 	    dp->it_adrmode != CWD &&
   2383 	    dp->it_adrmode != XMMSFNC) {
   2384 		if (strcmp(dp->it_name, "INVALID") == 0)
   2385 			goto error;
   2386 		(void) strlcat(x->d86_mnem, dp->it_name, OPLEN);
   2387 		if (dp->it_suffix) {
   2388 			char *types[] = {"", "w", "l", "q"};
   2389 			if (opcode_bytes == 2 && opcode4 == 4) {
   2390 				/* It's a cmovx.yy. Replace the suffix x */
   2391 				for (i = 5; i < OPLEN; i++) {
   2392 					if (x->d86_mnem[i] == '.')
   2393 						break;
   2394 				}
   2395 				x->d86_mnem[i - 1] = *types[opnd_size];
   2396 			} else if ((opnd_size == 2) && (opcode_bytes == 3) &&
   2397 			    ((opcode6 == 1 && opcode7 == 6) ||
   2398 			    (opcode6 == 2 && opcode7 == 2))) {
   2399 				/*
   2400 				 * To handle PINSRD and PEXTRD
   2401 				 */
   2402 				(void) strlcat(x->d86_mnem, "d", OPLEN);
   2403 			} else {
   2404 				(void) strlcat(x->d86_mnem, types[opnd_size],
   2405 				    OPLEN);
   2406 			}
   2407 		}
   2408 	}
   2409 #endif
   2410 
   2411 	/*
   2412 	 * Process operands based on the addressing modes.
   2413 	 */
   2414 	x->d86_mode = cpu_mode;
   2415 	x->d86_rex_prefix = rex_prefix;
   2416 	x->d86_opnd_size = opnd_size;
   2417 	x->d86_addr_size = addr_size;
   2418 	vbit = 0;		/* initialize for mem/reg -> reg */
   2419 	switch (dp->it_adrmode) {
   2420 		/*
   2421 		 * amd64 instruction to sign extend 32 bit reg/mem operands
   2422 		 * into 64 bit register values
   2423 		 */
   2424 	case MOVSXZ:
   2425 #ifdef DIS_TEXT
   2426 		if (rex_prefix == 0)
   2427 			(void) strncpy(x->d86_mnem, "movzld", OPLEN);
   2428 #endif
   2429 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2430 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2431 		x->d86_opnd_size = SIZE64;
   2432 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   2433 		x->d86_opnd_size = opnd_size = SIZE32;
   2434 		wbit = LONG_OPND;
   2435 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2436 		break;
   2437 
   2438 		/*
   2439 		 * movsbl movsbw movsbq (0x0FBE) or movswl movswq (0x0FBF)
   2440 		 * movzbl movzbw movzbq (0x0FB6) or movzwl movzwq (0x0FB7)
   2441 		 * wbit lives in 2nd byte, note that operands
   2442 		 * are different sized
   2443 		 */
   2444 	case MOVZ:
   2445 		if (rex_prefix & REX_W) {
   2446 			/* target register size = 64 bit */
   2447 			x->d86_mnem[5] = 'q';
   2448 		}
   2449 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2450 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2451 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   2452 		x->d86_opnd_size = opnd_size = SIZE16;
   2453 		wbit = WBIT(opcode5);
   2454 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2455 		break;
   2456 	case CRC32:
   2457 		opnd_size = SIZE32;
   2458 		if (rex_prefix & REX_W)
   2459 			opnd_size = SIZE64;
   2460 		x->d86_opnd_size = opnd_size;
   2461 
   2462 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2463 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2464 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   2465 		wbit = WBIT(opcode7);
   2466 		if (opnd_size_prefix)
   2467 			x->d86_opnd_size = opnd_size = SIZE16;
   2468 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2469 		break;
   2470 	case MOVBE:
   2471 		opnd_size = SIZE32;
   2472 		if (rex_prefix & REX_W)
   2473 			opnd_size = SIZE64;
   2474 		x->d86_opnd_size = opnd_size;
   2475 
   2476 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2477 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2478 		wbit = WBIT(opcode7);
   2479 		if (opnd_size_prefix)
   2480 			x->d86_opnd_size = opnd_size = SIZE16;
   2481 		if (wbit) {
   2482 			/* reg -> mem */
   2483 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
   2484 			dtrace_get_operand(x, mode, r_m, wbit, 1);
   2485 		} else {
   2486 			/* mem -> reg */
   2487 			dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   2488 			dtrace_get_operand(x, mode, r_m, wbit, 0);
   2489 		}
   2490 		break;
   2491 
   2492 	/*
   2493 	 * imul instruction, with either 8-bit or longer immediate
   2494 	 * opcode 0x6B for byte, sign-extended displacement, 0x69 for word(s)
   2495 	 */
   2496 	case IMUL:
   2497 		wbit = LONG_OPND;
   2498 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND,
   2499 		    OPSIZE(opnd_size, opcode2 == 0x9), 1);
   2500 		break;
   2501 
   2502 	/* memory or register operand to register, with 'w' bit	*/
   2503 	case MRw:
   2504 		wbit = WBIT(opcode2);
   2505 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
   2506 		break;
   2507 
   2508 	/* register to memory or register operand, with 'w' bit	*/
   2509 	/* arpl happens to fit here also because it is odd */
   2510 	case RMw:
   2511 		if (opcode_bytes == 2)
   2512 			wbit = WBIT(opcode5);
   2513 		else
   2514 			wbit = WBIT(opcode2);
   2515 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
   2516 		break;
   2517 
   2518 	/* xaddb instruction */
   2519 	case XADDB:
   2520 		wbit = 0;
   2521 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
   2522 		break;
   2523 
   2524 	/* MMX register to memory or register operand		*/
   2525 	case MMS:
   2526 	case MMOS:
   2527 #ifdef DIS_TEXT
   2528 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
   2529 #else
   2530 		wbit = LONG_OPND;
   2531 #endif
   2532 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
   2533 		break;
   2534 
   2535 	/* MMX register to memory */
   2536 	case MMOMS:
   2537 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2538 		if (mode == REG_ONLY)
   2539 			goto error;
   2540 		wbit = MM_OPND;
   2541 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 1);
   2542 		break;
   2543 
   2544 	/* Double shift. Has immediate operand specifying the shift. */
   2545 	case DSHIFT:
   2546 		wbit = LONG_OPND;
   2547 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2548 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2549 		dtrace_get_operand(x, mode, r_m, wbit, 2);
   2550 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   2551 		dtrace_imm_opnd(x, wbit, 1, 0);
   2552 		break;
   2553 
   2554 	/*
   2555 	 * Double shift. With no immediate operand, specifies using %cl.
   2556 	 */
   2557 	case DSHIFTcl:
   2558 		wbit = LONG_OPND;
   2559 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
   2560 		break;
   2561 
   2562 	/* immediate to memory or register operand */
   2563 	case IMlw:
   2564 		wbit = WBIT(opcode2);
   2565 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2566 		dtrace_get_operand(x, mode, r_m, wbit, 1);
   2567 		/*
   2568 		 * Have long immediate for opcode 0x81, but not 0x80 nor 0x83
   2569 		 */
   2570 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, opcode2 == 1), 0);
   2571 		break;
   2572 
   2573 	/* immediate to memory or register operand with the	*/
   2574 	/* 'w' bit present					*/
   2575 	case IMw:
   2576 		wbit = WBIT(opcode2);
   2577 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2578 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2579 		dtrace_get_operand(x, mode, r_m, wbit, 1);
   2580 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
   2581 		break;
   2582 
   2583 	/* immediate to register with register in low 3 bits	*/
   2584 	/* of op code						*/
   2585 	case IR:
   2586 		/* w-bit here (with regs) is bit 3 */
   2587 		wbit = opcode2 >>3 & 0x1;
   2588 		reg = REGNO(opcode2);
   2589 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
   2590 		mode = REG_ONLY;
   2591 		r_m = reg;
   2592 		dtrace_get_operand(x, mode, r_m, wbit, 1);
   2593 		dtrace_imm_opnd(x, wbit, OPSIZE64(opnd_size, wbit), 0);
   2594 		break;
   2595 
   2596 	/* MMX immediate shift of register */
   2597 	case MMSH:
   2598 	case MMOSH:
   2599 		wbit = MM_OPND;
   2600 		goto mm_shift;	/* in next case */
   2601 
   2602 	/* SIMD immediate shift of register */
   2603 	case XMMSH:
   2604 		wbit = XMM_OPND;
   2605 mm_shift:
   2606 		reg = REGNO(opcode7);
   2607 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
   2608 		dtrace_get_operand(x, REG_ONLY, reg, wbit, 1);
   2609 		dtrace_imm_opnd(x, wbit, 1, 0);
   2610 		NOMEM;
   2611 		break;
   2612 
   2613 	/* accumulator to memory operand */
   2614 	case AO:
   2615 		vbit = 1;
   2616 		/*FALLTHROUGH*/
   2617 
   2618 	/* memory operand to accumulator */
   2619 	case OA:
   2620 		wbit = WBIT(opcode2);
   2621 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1 - vbit);
   2622 		dtrace_imm_opnd(x, wbit, OPSIZE64(addr_size, LONG_OPND), vbit);
   2623 #ifdef DIS_TEXT
   2624 		x->d86_opnd[vbit].d86_mode = MODE_OFFSET;
   2625 #endif
   2626 		break;
   2627 
   2628 
   2629 	/* segment register to memory or register operand */
   2630 	case SM:
   2631 		vbit = 1;
   2632 		/*FALLTHROUGH*/
   2633 
   2634 	/* memory or register operand to segment register */
   2635 	case MS:
   2636 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2637 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2638 		dtrace_get_operand(x, mode, r_m, LONG_OPND, vbit);
   2639 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 1 - vbit);
   2640 		break;
   2641 
   2642 	/*
   2643 	 * rotate or shift instructions, which may shift by 1 or
   2644 	 * consult the cl register, depending on the 'v' bit
   2645 	 */
   2646 	case Mv:
   2647 		vbit = VBIT(opcode2);
   2648 		wbit = WBIT(opcode2);
   2649 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2650 		dtrace_get_operand(x, mode, r_m, wbit, 1);
   2651 #ifdef DIS_TEXT
   2652 		if (vbit) {
   2653 			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
   2654 		} else {
   2655 			x->d86_opnd[0].d86_mode = MODE_SIGNED;
   2656 			x->d86_opnd[0].d86_value_size = 1;
   2657 			x->d86_opnd[0].d86_value = 1;
   2658 		}
   2659 #endif
   2660 		break;
   2661 	/*
   2662 	 * immediate rotate or shift instructions
   2663 	 */
   2664 	case MvI:
   2665 		wbit = WBIT(opcode2);
   2666 normal_imm_mem:
   2667 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2668 		dtrace_get_operand(x, mode, r_m, wbit, 1);
   2669 		dtrace_imm_opnd(x, wbit, 1, 0);
   2670 		break;
   2671 
   2672 	/* bit test instructions */
   2673 	case MIb:
   2674 		wbit = LONG_OPND;
   2675 		goto normal_imm_mem;
   2676 
   2677 	/* single memory or register operand with 'w' bit present */
   2678 	case Mw:
   2679 		wbit = WBIT(opcode2);
   2680 just_mem:
   2681 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2682 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2683 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2684 		break;
   2685 
   2686 	case SWAPGS:
   2687 		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
   2688 #ifdef DIS_TEXT
   2689 			(void) strncpy(x->d86_mnem, "swapgs", OPLEN);
   2690 #endif
   2691 			NOMEM;
   2692 			break;
   2693 		}
   2694 		/*FALLTHROUGH*/
   2695 
   2696 	/* prefetch instruction - memory operand, but no memory acess */
   2697 	case PREF:
   2698 		NOMEM;
   2699 		/*FALLTHROUGH*/
   2700 
   2701 	/* single memory or register operand */
   2702 	case M:
   2703 		wbit = LONG_OPND;
   2704 		goto just_mem;
   2705 
   2706 	/* single memory or register byte operand */
   2707 	case Mb:
   2708 		wbit = BYTE_OPND;
   2709 		goto just_mem;
   2710 
   2711 	case MONITOR_MWAIT:
   2712 		if (mode == 3) {
   2713 			if (r_m == 0) {
   2714 #ifdef DIS_TEXT
   2715 				(void) strncpy(x->d86_mnem, "monitor", OPLEN);
   2716 #endif
   2717 				NOMEM;
   2718 				break;
   2719 			} else if (r_m == 1) {
   2720 #ifdef DIS_TEXT
   2721 				(void) strncpy(x->d86_mnem, "mwait", OPLEN);
   2722 #endif
   2723 				NOMEM;
   2724 				break;
   2725 			} else {
   2726 				goto error;
   2727 			}
   2728 		}
   2729 		/*FALLTHROUGH*/
   2730 
   2731 	case MO:
   2732 		/* Similar to M, but only memory (no direct registers) */
   2733 		wbit = LONG_OPND;
   2734 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2735 		if (mode == 3)
   2736 			goto error;
   2737 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   2738 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2739 		break;
   2740 
   2741 	/* move special register to register or reverse if vbit */
   2742 	case SREG:
   2743 		switch (opcode5) {
   2744 
   2745 		case 2:
   2746 			vbit = 1;
   2747 			/*FALLTHROUGH*/
   2748 		case 0:
   2749 			wbit = CONTROL_OPND;
   2750 			break;
   2751 
   2752 		case 3:
   2753 			vbit = 1;
   2754 			/*FALLTHROUGH*/
   2755 		case 1:
   2756 			wbit = DEBUG_OPND;
   2757 			break;
   2758 
   2759 		case 6:
   2760 			vbit = 1;
   2761 			/*FALLTHROUGH*/
   2762 		case 4:
   2763 			wbit = TEST_OPND;
   2764 			break;
   2765 
   2766 		}
   2767 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2768 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2769 		dtrace_get_operand(x, REG_ONLY, reg, wbit, vbit);
   2770 		dtrace_get_operand(x, REG_ONLY, r_m, LONG_OPND, 1 - vbit);
   2771 		NOMEM;
   2772 		break;
   2773 
   2774 	/*
   2775 	 * single register operand with register in the low 3
   2776 	 * bits of op code
   2777 	 */
   2778 	case R:
   2779 		if (opcode_bytes == 2)
   2780 			reg = REGNO(opcode5);
   2781 		else
   2782 			reg = REGNO(opcode2);
   2783 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
   2784 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
   2785 		NOMEM;
   2786 		break;
   2787 
   2788 	/*
   2789 	 * register to accumulator with register in the low 3
   2790 	 * bits of op code, xchg instructions
   2791 	 */
   2792 	case RA:
   2793 		NOMEM;
   2794 		reg = REGNO(opcode2);
   2795 		dtrace_rex_adjust(rex_prefix, mode, &reg, NULL);
   2796 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 0);
   2797 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, LONG_OPND, 1);
   2798 		break;
   2799 
   2800 	/*
   2801 	 * single segment register operand, with register in
   2802 	 * bits 3-4 of op code byte
   2803 	 */
   2804 	case SEG:
   2805 		NOMEM;
   2806 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x3;
   2807 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
   2808 		break;
   2809 
   2810 	/*
   2811 	 * single segment register operand, with register in
   2812 	 * bits 3-5 of op code
   2813 	 */
   2814 	case LSEG:
   2815 		NOMEM;
   2816 		/* long seg reg from opcode */
   2817 		reg = (x->d86_bytes[x->d86_len - 1] >> 3) & 0x7;
   2818 		dtrace_get_operand(x, REG_ONLY, reg, SEG_OPND, 0);
   2819 		break;
   2820 
   2821 	/* memory or register operand to register */
   2822 	case MR:
   2823 		wbit = LONG_OPND;
   2824 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
   2825 		break;
   2826 
   2827 	case RM:
   2828 		wbit = LONG_OPND;
   2829 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
   2830 		break;
   2831 
   2832 	/* MMX/SIMD-Int memory or mm reg to mm reg		*/
   2833 	case MM:
   2834 	case MMO:
   2835 #ifdef DIS_TEXT
   2836 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
   2837 #else
   2838 		wbit = LONG_OPND;
   2839 #endif
   2840 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
   2841 		break;
   2842 
   2843 	case MMOIMPL:
   2844 #ifdef DIS_TEXT
   2845 		wbit = strcmp(dp->it_name, "movd") ? MM_OPND : LONG_OPND;
   2846 #else
   2847 		wbit = LONG_OPND;
   2848 #endif
   2849 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2850 		if (mode != REG_ONLY)
   2851 			goto error;
   2852 
   2853 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   2854 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   2855 		dtrace_get_operand(x, REG_ONLY, reg, MM_OPND, 1);
   2856 		mode = 0;	/* change for memory access size... */
   2857 		break;
   2858 
   2859 	/* MMX/SIMD-Int and SIMD-FP predicated mm reg to r32 */
   2860 	case MMO3P:
   2861 		wbit = MM_OPND;
   2862 		goto xmm3p;
   2863 	case XMM3P:
   2864 		wbit = XMM_OPND;
   2865 xmm3p:
   2866 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2867 		if (mode != REG_ONLY)
   2868 			goto error;
   2869 
   2870 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 1,
   2871 		    1);
   2872 		NOMEM;
   2873 		break;
   2874 
   2875 	case XMM3PM_66r:
   2876 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, LONG_OPND, XMM_OPND,
   2877 		    1, 0);
   2878 		break;
   2879 
   2880 	/* MMX/SIMD-Int predicated r32/mem to mm reg */
   2881 	case MMOPRM:
   2882 		wbit = LONG_OPND;
   2883 		w2 = MM_OPND;
   2884 		goto xmmprm;
   2885 	case XMMPRM:
   2886 	case XMMPRM_66r:
   2887 		wbit = LONG_OPND;
   2888 		w2 = XMM_OPND;
   2889 xmmprm:
   2890 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, w2, 1, 1);
   2891 		break;
   2892 
   2893 	/* MMX/SIMD-Int predicated mm/mem to mm reg */
   2894 	case MMOPM:
   2895 	case MMOPM_66o:
   2896 		wbit = w2 = MM_OPND;
   2897 		goto xmmprm;
   2898 
   2899 	/* MMX/SIMD-Int mm reg to r32 */
   2900 	case MMOM3:
   2901 		NOMEM;
   2902 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2903 		if (mode != REG_ONLY)
   2904 			goto error;
   2905 		wbit = MM_OPND;
   2906 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
   2907 		break;
   2908 
   2909 	/* SIMD memory or xmm reg operand to xmm reg		*/
   2910 	case XMM:
   2911 	case XMM_66o:
   2912 	case XMM_66r:
   2913 	case XMMO:
   2914 	case XMMXIMPL:
   2915 		wbit = XMM_OPND;
   2916 		STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 0);
   2917 
   2918 		if (dp->it_adrmode == XMMXIMPL && mode != REG_ONLY)
   2919 			goto error;
   2920 
   2921 #ifdef DIS_TEXT
   2922 		/*
   2923 		 * movlps and movhlps share opcodes.  They differ in the
   2924 		 * addressing modes allowed for their operands.
   2925 		 * movhps and movlhps behave similarly.
   2926 		 */
   2927 		if (mode == REG_ONLY) {
   2928 			if (strcmp(dp->it_name, "movlps") == 0)
   2929 				(void) strncpy(x->d86_mnem, "movhlps", OPLEN);
   2930 			else if (strcmp(dp->it_name, "movhps") == 0)
   2931 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
   2932 		}
   2933 #endif
   2934 		if (dp->it_adrmode == XMMXIMPL)
   2935 			mode = 0;	/* change for memory access size... */
   2936 		break;
   2937 
   2938 	/* SIMD xmm reg to memory or xmm reg */
   2939 	case XMMS:
   2940 	case XMMOS:
   2941 	case XMMMS:
   2942 	case XMMOMS:
   2943 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2944 #ifdef DIS_TEXT
   2945 		if ((strcmp(dp->it_name, "movlps") == 0 ||
   2946 		    strcmp(dp->it_name, "movhps") == 0 ||
   2947 		    strcmp(dp->it_name, "movntps") == 0) &&
   2948 		    mode == REG_ONLY)
   2949 			goto error;
   2950 #endif
   2951 		wbit = XMM_OPND;
   2952 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
   2953 		break;
   2954 
   2955 	/* SIMD memory to xmm reg */
   2956 	case XMMM:
   2957 	case XMMM_66r:
   2958 	case XMMOM:
   2959 		wbit = XMM_OPND;
   2960 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   2961 #ifdef DIS_TEXT
   2962 		if (mode == REG_ONLY) {
   2963 			if (strcmp(dp->it_name, "movhps") == 0)
   2964 				(void) strncpy(x->d86_mnem, "movlhps", OPLEN);
   2965 			else
   2966 				goto error;
   2967 		}
   2968 #endif
   2969 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
   2970 		break;
   2971 
   2972 	/* SIMD memory or r32 to xmm reg			*/
   2973 	case XMM3MX:
   2974 		wbit = LONG_OPND;
   2975 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
   2976 		break;
   2977 
   2978 	case XMM3MXS:
   2979 		wbit = LONG_OPND;
   2980 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1);
   2981 		break;
   2982 
   2983 	/* SIMD memory or mm reg to xmm reg			*/
   2984 	case XMMOMX:
   2985 	/* SIMD mm to xmm */
   2986 	case XMMMX:
   2987 		wbit = MM_OPND;
   2988 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 0);
   2989 		break;
   2990 
   2991 	/* SIMD memory or xmm reg to mm reg			*/
   2992 	case XMMXMM:
   2993 	case XMMOXMM:
   2994 	case XMMXM:
   2995 		wbit = XMM_OPND;
   2996 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, MM_OPND, 0);
   2997 		break;
   2998 
   2999 
   3000 	/* SIMD memory or xmm reg to r32			*/
   3001 	case XMMXM3:
   3002 		wbit = XMM_OPND;
   3003 		MIXED_MM(x, mode, reg, r_m, rex_prefix, wbit, LONG_OPND, 0);
   3004 		break;
   3005 
   3006 	/* SIMD xmm to r32					*/
   3007 	case XMMX3:
   3008 	case XMMOX3:
   3009 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   3010 		if (mode != REG_ONLY)
   3011 			goto error;
   3012 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   3013 		dtrace_get_operand(x, mode, r_m, XMM_OPND, 0);
   3014 		dtrace_get_operand(x, REG_ONLY, reg, LONG_OPND, 1);
   3015 		NOMEM;
   3016 		break;
   3017 
   3018 	/* SIMD predicated memory or xmm reg with/to xmm reg */
   3019 	case XMMP:
   3020 	case XMMP_66r:
   3021 	case XMMP_66o:
   3022 	case XMMOPM:
   3023 		wbit = XMM_OPND;
   3024 		THREEOPERAND(x, mode, reg, r_m, rex_prefix, wbit, XMM_OPND, 1,
   3025 		    1);
   3026 
   3027 #ifdef DIS_TEXT
   3028 		/*
   3029 		 * cmpps and cmpss vary their instruction name based
   3030 		 * on the value of imm8.  Other XMMP instructions,
   3031 		 * such as shufps, require explicit specification of
   3032 		 * the predicate.
   3033 		 */
   3034 		if (dp->it_name[0] == 'c' &&
   3035 		    dp->it_name[1] == 'm' &&
   3036 		    dp->it_name[2] == 'p' &&
   3037 		    strlen(dp->it_name) == 5) {
   3038 			uchar_t pred = x->d86_opnd[0].d86_value & 0xff;
   3039 
   3040 			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
   3041 				goto error;
   3042 
   3043 			(void) strncpy(x->d86_mnem, "cmp", OPLEN);
   3044 			(void) strlcat(x->d86_mnem, dis_PREDSUFFIX[pred],
   3045 			    OPLEN);
   3046 			(void) strlcat(x->d86_mnem,
   3047 			    dp->it_name + strlen(dp->it_name) - 2,
   3048 			    OPLEN);
   3049 			x->d86_opnd[0] = x->d86_opnd[1];
   3050 			x->d86_opnd[1] = x->d86_opnd[2];
   3051 			x->d86_numopnds = 2;
   3052 		}
   3053 #endif
   3054 		break;
   3055 
   3056 	case XMMX2I:
   3057 		FOUROPERAND(x, mode, reg, r_m, rex_prefix, XMM_OPND, XMM_OPND,
   3058 		    1);
   3059 		NOMEM;
   3060 		break;
   3061 
   3062 	case XMM2I:
   3063 		ONEOPERAND_TWOIMM(x, mode, reg, r_m, rex_prefix, XMM_OPND, 1);
   3064 		NOMEM;
   3065 		break;
   3066 
   3067 	/* immediate operand to accumulator */
   3068 	case IA:
   3069 		wbit = WBIT(opcode2);
   3070 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
   3071 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, wbit), 0);
   3072 		NOMEM;
   3073 		break;
   3074 
   3075 	/* memory or register operand to accumulator */
   3076 	case MA:
   3077 		wbit = WBIT(opcode2);
   3078 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   3079 		dtrace_get_operand(x, mode, r_m, wbit, 0);
   3080 		break;
   3081 
   3082 	/* si register to di register used to reference memory		*/
   3083 	case SD:
   3084 #ifdef DIS_TEXT
   3085 		dtrace_check_override(x, 0);
   3086 		x->d86_numopnds = 2;
   3087 		if (addr_size == SIZE64) {
   3088 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
   3089 			    OPLEN);
   3090 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
   3091 			    OPLEN);
   3092 		} else if (addr_size == SIZE32) {
   3093 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
   3094 			    OPLEN);
   3095 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
   3096 			    OPLEN);
   3097 		} else {
   3098 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
   3099 			    OPLEN);
   3100 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
   3101 			    OPLEN);
   3102 		}
   3103 #endif
   3104 		wbit = LONG_OPND;
   3105 		break;
   3106 
   3107 	/* accumulator to di register				*/
   3108 	case AD:
   3109 		wbit = WBIT(opcode2);
   3110 #ifdef DIS_TEXT
   3111 		dtrace_check_override(x, 1);
   3112 		x->d86_numopnds = 2;
   3113 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
   3114 		if (addr_size == SIZE64)
   3115 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
   3116 			    OPLEN);
   3117 		else if (addr_size == SIZE32)
   3118 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
   3119 			    OPLEN);
   3120 		else
   3121 			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
   3122 			    OPLEN);
   3123 #endif
   3124 		break;
   3125 
   3126 	/* si register to accumulator				*/
   3127 	case SA:
   3128 		wbit = WBIT(opcode2);
   3129 #ifdef DIS_TEXT
   3130 		dtrace_check_override(x, 0);
   3131 		x->d86_numopnds = 2;
   3132 		if (addr_size == SIZE64)
   3133 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
   3134 			    OPLEN);
   3135 		else if (addr_size == SIZE32)
   3136 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
   3137 			    OPLEN);
   3138 		else
   3139 			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
   3140 			    OPLEN);
   3141 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
   3142 #endif
   3143 		break;
   3144 
   3145 	/*
   3146 	 * single operand, a 16/32 bit displacement
   3147 	 */
   3148 	case D:
   3149 		wbit = LONG_OPND;
   3150 		dtrace_disp_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
   3151 		NOMEM;
   3152 		break;
   3153 
   3154 	/* jmp/call indirect to memory or register operand		*/
   3155 	case INM:
   3156 #ifdef DIS_TEXT
   3157 		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
   3158 #endif
   3159 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
   3160 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
   3161 		wbit = LONG_OPND;
   3162 		break;
   3163 
   3164 	/*
   3165 	 * for long jumps and long calls -- a new code segment
   3166 	 * register and an offset in IP -- stored in object
   3167 	 * code in reverse order. Note - not valid in amd64
   3168 	 */
   3169 	case SO:
   3170 		dtrace_check_override(x, 1);
   3171 		wbit = LONG_OPND;
   3172 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 1);
   3173 #ifdef DIS_TEXT
   3174 		x->d86_opnd[1].d86_mode = MODE_SIGNED;
   3175 #endif
   3176 		/* will now get segment operand */
   3177 		dtrace_imm_opnd(x, wbit, 2, 0);
   3178 		break;
   3179 
   3180 	/*
   3181 	 * jmp/call. single operand, 8 bit displacement.
   3182 	 * added to current EIP in 'compofff'
   3183 	 */
   3184 	case BD:
   3185 		dtrace_disp_opnd(x, BYTE_OPND, 1, 0);
   3186 		NOMEM;
   3187 		break;
   3188 
   3189 	/* single 32/16 bit immediate operand			*/
   3190 	case I:
   3191 		wbit = LONG_OPND;
   3192 		dtrace_imm_opnd(x, wbit, OPSIZE(opnd_size, LONG_OPND), 0);
   3193 		break;
   3194 
   3195 	/* single 8 bit immediate operand			*/
   3196 	case Ib:
   3197 		wbit = LONG_OPND;
   3198 		dtrace_imm_opnd(x, wbit, 1, 0);
   3199 		break;
   3200 
   3201 	case ENTER:
   3202 		wbit = LONG_OPND;
   3203 		dtrace_imm_opnd(x, wbit, 2, 0);
   3204 		dtrace_imm_opnd(x, wbit, 1, 1);
   3205 		switch (opnd_size) {
   3206 		case SIZE64:
   3207 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 8;
   3208 			break;
   3209 		case SIZE32:
   3210 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 4;
   3211 			break;
   3212 		case SIZE16:
   3213 			x->d86_memsize = (x->d86_opnd[1].d86_value + 1) * 2;
   3214 			break;
   3215 		}
   3216 
   3217 		break;
   3218 
   3219 	/* 16-bit immediate operand */
   3220 	case RET:
   3221 		wbit = LONG_OPND;
   3222 		dtrace_imm_opnd(x, wbit, 2, 0);
   3223 		break;
   3224 
   3225 	/* single 8 bit port operand				*/
   3226 	case P:
   3227 		dtrace_check_override(x, 0);
   3228 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
   3229 		NOMEM;
   3230 		break;
   3231 
   3232 	/* single operand, dx register (variable port instruction) */
   3233 	case V:
   3234 		x->d86_numopnds = 1;
   3235 		dtrace_check_override(x, 0);
   3236 #ifdef DIS_TEXT
   3237 		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
   3238 #endif
   3239 		NOMEM;
   3240 		break;
   3241 
   3242 	/*
   3243 	 * The int instruction, which has two forms:
   3244 	 * int 3 (breakpoint) or
   3245 	 * int n, where n is indicated in the subsequent
   3246 	 * byte (format Ib).  The int 3 instruction (opcode 0xCC),
   3247 	 * where, although the 3 looks  like an operand,
   3248 	 * it is implied by the opcode. It must be converted
   3249 	 * to the correct base and output.
   3250 	 */
   3251 	case INT3:
   3252 #ifdef DIS_TEXT
   3253 		x->d86_numopnds = 1;
   3254 		x->d86_opnd[0].d86_mode = MODE_SIGNED;
   3255 		x->d86_opnd[0].d86_value_size = 1;
   3256 		x->d86_opnd[0].d86_value = 3;
   3257 #endif
   3258 		NOMEM;
   3259 		break;
   3260 
   3261 	/* single 8 bit immediate operand			*/
   3262 	case INTx:
   3263 		dtrace_imm_opnd(x, BYTE_OPND, 1, 0);
   3264 		NOMEM;
   3265 		break;
   3266 
   3267 	/* an unused byte must be discarded */
   3268 	case U:
   3269 		if (x->d86_get_byte(x->d86_data) < 0)
   3270 			goto error;
   3271 		x->d86_len++;
   3272 		NOMEM;
   3273 		break;
   3274 
   3275 	case CBW:
   3276 #ifdef DIS_TEXT
   3277 		if (opnd_size == SIZE16)
   3278 			(void) strlcat(x->d86_mnem, "cbtw", OPLEN);
   3279 		else if (opnd_size == SIZE32)
   3280 			(void) strlcat(x->d86_mnem, "cwtl", OPLEN);
   3281 		else
   3282 			(void) strlcat(x->d86_mnem, "cltq", OPLEN);
   3283 #endif
   3284 		wbit = LONG_OPND;
   3285 		NOMEM;
   3286 		break;
   3287 
   3288 	case CWD:
   3289 #ifdef DIS_TEXT
   3290 		if (opnd_size == SIZE16)
   3291 			(void) strlcat(x->d86_mnem, "cwtd", OPLEN);
   3292 		else if (opnd_size == SIZE32)
   3293 			(void) strlcat(x->d86_mnem, "cltd", OPLEN);
   3294 		else
   3295 			(void) strlcat(x->d86_mnem, "cqtd", OPLEN);
   3296 #endif
   3297 		wbit = LONG_OPND;
   3298 		NOMEM;
   3299 		break;
   3300 
   3301 	case XMMSFNC:
   3302 		/*
   3303 		 * sfence is sfence if mode is REG_ONLY.  If mode isn't
   3304 		 * REG_ONLY, mnemonic should be 'clflush'.
   3305 		 */
   3306 		dtrace_get_modrm(x, &mode, &reg, &r_m);
   3307 
   3308 		/* sfence doesn't take operands */
   3309 #ifdef DIS_TEXT
   3310 		if (mode == REG_ONLY) {
   3311 			(void) strlcat(x->d86_mnem, "sfence", OPLEN);
   3312 		} else {
   3313 			(void) strlcat(x->d86_mnem, "clflush", OPLEN);
   3314 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   3315 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
   3316 			NOMEM;
   3317 		}
   3318 #else
   3319 		if (mode != REG_ONLY) {
   3320 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
   3321 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
   3322 			NOMEM;
   3323 		}
   3324 #endif
   3325 		break;
   3326 
   3327 	/*
   3328 	 * no disassembly, the mnemonic was all there was so go on
   3329 	 */
   3330 	case NORM:
   3331 		if (dp->it_invalid32 && cpu_mode != SIZE64)
   3332 			goto error;
   3333 		NOMEM;
   3334 		/*FALLTHROUGH*/
   3335 	case IMPLMEM:
   3336 		break;
   3337 
   3338 	case XMMFENCE:
   3339 		/*
   3340 		 * Only the following exact byte sequences are allowed:
   3341 		 *
   3342 		 * 	0f ae e8	lfence
   3343 		 * 	0f ae f0	mfence
   3344 		 */
   3345 		if ((uint8_t)x->d86_bytes[x->d86_len - 1] != 0xe8 &&
   3346 		    (uint8_t)x->d86_bytes[x->d86_len - 1] != 0xf0)
   3347 			goto error;
   3348 
   3349 		break;
   3350 
   3351 
   3352 	/* float reg */
   3353 	case F:
   3354 #ifdef DIS_TEXT
   3355 		x->d86_numopnds = 1;
   3356 		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
   3357 		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
   3358 #endif
   3359 		NOMEM;
   3360 		break;
   3361 
   3362 	/* float reg to float reg, with ret bit present */
   3363 	case FF:
   3364 		vbit = opcode2 >> 2 & 0x1;	/* vbit = 1: st -> st(i) */
   3365 		/*FALLTHROUGH*/
   3366 	case FFC:				/* case for vbit always = 0 */
   3367 #ifdef DIS_TEXT
   3368 		x->d86_numopnds = 2;
   3369 		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
   3370 		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
   3371 		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
   3372 #endif
   3373 		NOMEM;
   3374 		break;
   3375 
   3376 	/* an invalid op code */
   3377 	case AM:
   3378 	case DM:
   3379 	case OVERRIDE:
   3380 	case PREFIX:
   3381 	case UNKNOWN:
   3382 		NOMEM;
   3383 	default:
   3384 		goto error;
   3385 	} /* end switch */
   3386 	if (x->d86_error)
   3387 		goto error;
   3388 
   3389 done:
   3390 #ifdef DIS_MEM
   3391 	/*
   3392 	 * compute the size of any memory accessed by the instruction
   3393 	 */
   3394 	if (x->d86_memsize != 0) {
   3395 		return (0);
   3396 	} else if (dp->it_stackop) {
   3397 		switch (opnd_size) {
   3398 		case SIZE16:
   3399 			x->d86_memsize = 2;
   3400 			break;
   3401 		case SIZE32:
   3402 			x->d86_memsize = 4;
   3403 			break;
   3404 		case SIZE64:
   3405 			x->d86_memsize = 8;
   3406 			break;
   3407 		}
   3408 	} else if (nomem || mode == REG_ONLY) {
   3409 		x->d86_memsize = 0;
   3410 
   3411 	} else if (dp->it_size != 0) {
   3412 		/*
   3413 		 * In 64 bit mode descriptor table entries
   3414 		 * go up to 10 bytes and popf/pushf are always 8 bytes
   3415 		 */
   3416 		if (x->d86_mode == SIZE64 && dp->it_size == 6)
   3417 			x->d86_memsize = 10;
   3418 		else if (x->d86_mode == SIZE64 && opcode1 == 0x9 &&
   3419 		    (opcode2 == 0xc || opcode2 == 0xd))
   3420 			x->d86_memsize = 8;
   3421 		else
   3422 			x->d86_memsize = dp->it_size;
   3423 
   3424 	} else if (wbit == 0) {
   3425 		x->d86_memsize = 1;
   3426 
   3427 	} else if (wbit == LONG_OPND) {
   3428 		if (opnd_size == SIZE64)
   3429 			x->d86_memsize = 8;
   3430 		else if (opnd_size == SIZE32)
   3431 			x->d86_memsize = 4;
   3432 		else
   3433 			x->d86_memsize = 2;
   3434 
   3435 	} else if (wbit == SEG_OPND) {
   3436 		x->d86_memsize = 4;
   3437 
   3438 	} else {
   3439 		x->d86_memsize = 8;
   3440 	}
   3441 #endif
   3442 	return (0);
   3443 
   3444 error:
   3445 #ifdef DIS_TEXT
   3446 	(void) strlcat(x->d86_mnem, "undef", OPLEN);
   3447 #endif
   3448 	return (1);
   3449 }
   3450 
   3451 #ifdef DIS_TEXT
   3452 
   3453 /*
   3454  * Some instructions should have immediate operands printed
   3455  * as unsigned integers. We compare against this table.
   3456  */
   3457 static char *unsigned_ops[] = {
   3458 	"or", "and", "xor", "test", "in", "out", "lcall", "ljmp",
   3459 	"rcr", "rcl", "ror", "rol", "shl", "shr", "sal", "psr", "psl",
   3460 	0
   3461 };
   3462 
   3463 
   3464 static int
   3465 isunsigned_op(char *opcode)
   3466 {
   3467 	char *where;
   3468 	int i;
   3469 	int is_unsigned = 0;
   3470 
   3471 	/*
   3472 	 * Work back to start of last mnemonic, since we may have
   3473 	 * prefixes on some opcodes.
   3474 	 */
   3475 	where = opcode + strlen(opcode) - 1;
   3476 	while (where > opcode && *where != ' ')
   3477 		--where;
   3478 	if (*where == ' ')
   3479 		++where;
   3480 
   3481 	for (i = 0; unsigned_ops[i]; ++i) {
   3482 		if (strncmp(where, unsigned_ops[i],
   3483 		    strlen(unsigned_ops[i])))
   3484 			continue;
   3485 		is_unsigned = 1;
   3486 		break;
   3487 	}
   3488 	return (is_unsigned);
   3489 }
   3490 
   3491 /*
   3492  * Print a numeric immediate into end of buf, maximum length buflen.
   3493  * The immediate may be an address or a displacement.  Mask is set
   3494  * for address size.  If the immediate is a "small negative", or
   3495  * if it's a negative displacement of any magnitude, print as -<absval>.
   3496  * Respect the "octal" flag.  "Small negative" is defined as "in the
   3497  * interval [NEG_LIMIT, 0)".
   3498  *
   3499  * Also, "isunsigned_op()" instructions never print negatives.
   3500  *
   3501  * Return whether we decided to print a negative value or not.
   3502  */
   3503 
   3504 #define	NEG_LIMIT	-255
   3505 enum {IMM, DISP};
   3506 enum {POS, TRY_NEG};
   3507 
   3508 static int
   3509 print_imm(dis86_t *dis, uint64_t usv, uint64_t mask, char *buf,
   3510     size_t buflen, int disp, int try_neg)
   3511 {
   3512 	int curlen;
   3513 	int64_t sv = (int64_t)usv;
   3514 	int octal = dis->d86_flags & DIS_F_OCTAL;
   3515 
   3516 	curlen = strlen(buf);
   3517 
   3518 	if (try_neg == TRY_NEG && sv < 0 &&
   3519 	    (disp || sv >= NEG_LIMIT) &&
   3520 	    !isunsigned_op(dis->d86_mnem)) {
   3521 		dis->d86_sprintf_func(buf + curlen, buflen - curlen,
   3522 		    octal ? "-0%llo" : "-0x%llx", (-sv) & mask);
   3523 		return (1);
   3524 	} else {
   3525 		if (disp == DISP)
   3526 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
   3527 			    octal ? "+0%llo" : "+0x%llx", usv & mask);
   3528 		else
   3529 			dis->d86_sprintf_func(buf + curlen, buflen - curlen,
   3530 			    octal ? "0%llo" : "0x%llx", usv & mask);
   3531 		return (0);
   3532 
   3533 	}
   3534 }
   3535 
   3536 
   3537 static int
   3538 log2(int size)
   3539 {
   3540 	switch (size) {
   3541 	case 1: return (0);
   3542 	case 2: return (1);
   3543 	case 4: return (2);
   3544 	case 8: return (3);
   3545 	}
   3546 	return (0);
   3547 }
   3548 
   3549 /* ARGSUSED */
   3550 void
   3551 dtrace_disx86_str(dis86_t *dis, uint_t mode, uint64_t pc, char *buf,
   3552     size_t buflen)
   3553 {
   3554 	uint64_t reltgt = 0;
   3555 	uint64_t tgt = 0;
   3556 	int curlen;
   3557 	int (*lookup)(void *, uint64_t, char *, size_t);
   3558 	int i;
   3559 	int64_t sv;
   3560 	uint64_t usv, mask, save_mask, save_usv;
   3561 	static uint64_t masks[] =
   3562 	    {0xffU, 0xffffU, 0xffffffffU, 0xffffffffffffffffULL};
   3563 	save_usv = 0;
   3564 
   3565 	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mnem);
   3566 
   3567 	/*
   3568 	 * For PC-relative jumps, the pc is really the next pc after executing
   3569 	 * this instruction, so increment it appropriately.
   3570 	 */
   3571 	pc += dis->d86_len;
   3572 
   3573 	for (i = 0; i < dis->d86_numopnds; i++) {
   3574 		d86opnd_t *op = &dis->d86_opnd[i];
   3575 
   3576 		if (i != 0)
   3577 			(void) strlcat(buf, ",", buflen);
   3578 
   3579 		(void) strlcat(buf, op->d86_prefix, buflen);
   3580 
   3581 		/*
   3582 		 * sv is for the signed, possibly-truncated immediate or
   3583 		 * displacement; usv retains the original size and
   3584 		 * unsignedness for symbol lookup.
   3585 		 */
   3586 
   3587 		sv = usv = op->d86_value;
   3588 
   3589 		/*
   3590 		 * About masks: for immediates that represent
   3591 		 * addresses, the appropriate display size is
   3592 		 * the effective address size of the instruction.
   3593 		 * This includes MODE_OFFSET, MODE_IPREL, and
   3594 		 * MODE_RIPREL.  Immediates that are simply
   3595 		 * immediate values should display in the operand's
   3596 		 * size, however, since they don't represent addresses.
   3597 		 */
   3598 
   3599 		/* d86_addr_size is SIZEnn, which is log2(real size) */
   3600 		mask = masks[dis->d86_addr_size];
   3601 
   3602 		/* d86_value_size and d86_imm_bytes are in bytes */
   3603 		if (op->d86_mode == MODE_SIGNED ||
   3604 		    op->d86_mode == MODE_IMPLIED)
   3605 			mask = masks[log2(op->d86_value_size)];
   3606 
   3607 		switch (op->d86_mode) {
   3608 
   3609 		case MODE_NONE:
   3610 
   3611 			(void) strlcat(buf, op->d86_opnd, buflen);
   3612 			break;
   3613 
   3614 		case MODE_SIGNED:
   3615 		case MODE_IMPLIED:
   3616 		case MODE_OFFSET:
   3617 
   3618 			tgt = usv;
   3619 
   3620 			if (dis->d86_seg_prefix)
   3621 				(void) strlcat(buf, dis->d86_seg_prefix,
   3622 				    buflen);
   3623 
   3624 			if (op->d86_mode == MODE_SIGNED ||
   3625 			    op->d86_mode == MODE_IMPLIED) {
   3626 				(void) strlcat(buf, "$", buflen);
   3627 			}
   3628 
   3629 			if (print_imm(dis, usv, mask, buf, buflen,
   3630 			    IMM, TRY_NEG) &&
   3631 			    (op->d86_mode == MODE_SIGNED ||
   3632 			    op->d86_mode == MODE_IMPLIED)) {
   3633 
   3634 				/*
   3635 				 * We printed a negative value for an
   3636 				 * immediate that wasn't a
   3637 				 * displacement.  Note that fact so we can
   3638 				 * print the positive value as an
   3639 				 * annotation.
   3640 				 */
   3641 
   3642 				save_usv = usv;
   3643 				save_mask = mask;
   3644 			}
   3645 			(void) strlcat(buf, op->d86_opnd, buflen);
   3646 
   3647 			break;
   3648 
   3649 		case MODE_IPREL:
   3650 		case MODE_RIPREL:
   3651 
   3652 			reltgt = pc + sv;
   3653 
   3654 			switch (mode) {
   3655 			case SIZE16:
   3656 				reltgt = (uint16_t)reltgt;
   3657 				break;
   3658 			case SIZE32:
   3659 				reltgt = (uint32_t)reltgt;
   3660 				break;
   3661 			}
   3662 
   3663 			(void) print_imm(dis, usv, mask, buf, buflen,
   3664 			    DISP, TRY_NEG);
   3665 
   3666 			if (op->d86_mode == MODE_RIPREL)
   3667 				(void) strlcat(buf, "(%rip)", buflen);
   3668 			break;
   3669 		}
   3670 	}
   3671 
   3672 	/*
   3673 	 * The symbol lookups may result in false positives,
   3674 	 * particularly on object files, where small numbers may match
   3675 	 * the 0-relative non-relocated addresses of symbols.
   3676 	 */
   3677 
   3678 	lookup = dis->d86_sym_lookup;
   3679 	if (tgt != 0) {
   3680 		if ((dis->d86_flags & DIS_F_NOIMMSYM) == 0 &&
   3681 		    lookup(dis->d86_data, tgt, NULL, 0) == 0) {
   3682 			(void) strlcat(buf, "\t<", buflen);
   3683 			curlen = strlen(buf);
   3684 			lookup(dis->d86_data, tgt, buf + curlen,
   3685 			    buflen - curlen);
   3686 			(void) strlcat(buf, ">", buflen);
   3687 		}
   3688 
   3689 		/*
   3690 		 * If we printed a negative immediate above, print the
   3691 		 * positive in case our heuristic was unhelpful
   3692 		 */
   3693 		if (save_usv) {
   3694 			(void) strlcat(buf, "\t<", buflen);
   3695 			(void) print_imm(dis, save_usv, save_mask, buf, buflen,
   3696 			    IMM, POS);
   3697 			(void) strlcat(buf, ">", buflen);
   3698 		}
   3699 	}
   3700 
   3701 	if (reltgt != 0) {
   3702 		/* Print symbol or effective address for reltgt */
   3703 
   3704 		(void) strlcat(buf, "\t<", buflen);
   3705 		curlen = strlen(buf);
   3706 		lookup(dis->d86_data, reltgt, buf + curlen,
   3707 		    buflen - curlen);
   3708 		(void) strlcat(buf, ">", buflen);
   3709 	}
   3710 }
   3711 
   3712 #endif /* DIS_TEXT */
   3713