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