xref: /onnv-gate/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c (revision 5198:a4512bf4070e)
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 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright 2007 Jason King.  All rights reserved.
29  * Use is subject to license terms.
30  */
31 
32 
33 #pragma ident	"%Z%%M%	%I%	%E% SMI"
34 
35 #include <sys/byteorder.h>
36 #include <stdarg.h>
37 
38 #if !defined(DIS_STANDALONE)
39 #include <stdio.h>
40 #endif /* DIS_STANDALONE */
41 
42 #include "libdisasm.h"
43 #include "libdisasm_impl.h"
44 #include "dis_sparc.h"
45 #include "dis_sparc_fmt.h"
46 
47 extern char *strncpy(char *, const char *, size_t);
48 extern size_t strlen(const char *);
49 extern int strcmp(const char *, const char *);
50 extern int strncmp(const char *, const char *, size_t);
51 extern size_t strlcat(char *, const char *, size_t);
52 extern size_t strlcpy(char *, const char *, size_t);
53 extern int snprintf(char *, size_t, const char *, ...);
54 extern int vsnprintf(char *, size_t, const char *, va_list);
55 
56 /*
57  * This file has the functions that do all the dirty work of outputting the
58  * disassembled instruction
59  *
60  * All the non-static functions follow the format_fcn (in dis_sparc.h):
61  * Input:
62  *	disassembler handle/context
63  *	instruction to disassemble
64  *	instruction definition pointer (inst_t *)
65  *	index in the table of the instruction
66  * Return:
67  *	0 Success
68  *    !0 Invalid instruction
69  *
70  * Generally, instructions found in the same table use the same output format
71  * or have a few minor differences (which are described in the 'flags' field
72  * of the instruction definition. In some cases, certain instructions differ
73  * radically enough from those in the same table, that their own format
74  * function is used.
75  *
76  * Typically each table has a unique format function defined in this file.  In
77  * some cases (such as branches) a common one for all the tables is used.
78  *
79  * When adding support for new instructions, it is largely a judgement call
80  * as to when a new format function is defined.
81  */
82 
83 /* The various instruction formats of a sparc instruction */
84 
85 #if defined(_BIT_FIELDS_HTOL)
86 typedef struct format1 {
87 	uint32_t op:2;
88 	uint32_t disp30:30;
89 } format1_t;
90 #elif defined(_BIT_FIELDS_LTOH)
91 typedef struct format1 {
92 	uint32_t disp30:30;
93 	uint32_t op:2;
94 } format1_t;
95 #else
96 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
97 #endif
98 
99 #if defined(_BIT_FIELDS_HTOL)
100 typedef struct format2 {
101 	uint32_t op:2;
102 	uint32_t rd:5;
103 	uint32_t op2:3;
104 	uint32_t imm22:22;
105 } format2_t;
106 #elif defined(_BIT_FIELDS_LTOH)
107 typedef struct format2 {
108 	uint32_t imm22:22;
109 	uint32_t op2:3;
110 	uint32_t rd:5;
111 	uint32_t op:2;
112 } format2_t;
113 #else
114 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
115 #endif
116 
117 #if defined(_BIT_FIELDS_HTOL)
118 typedef struct format2a {
119 	uint32_t op:2;
120 	uint32_t a:1;
121 	uint32_t cond:4;
122 	uint32_t op2:3;
123 	uint32_t disp22:22;
124 } format2a_t;
125 #elif defined(_BIT_FIELDS_LTOH)
126 typedef struct format2a {
127 	uint32_t disp22:22;
128 	uint32_t op2:3;
129 	uint32_t cond:4;
130 	uint32_t a:1;
131 	uint32_t op:2;
132 } format2a_t;
133 #else
134 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
135 #endif
136 
137 #if defined(_BIT_FIELDS_HTOL)
138 typedef struct format2b {
139 	uint32_t op:2;
140 	uint32_t a:1;
141 	uint32_t cond:4;
142 	uint32_t op2:3;
143 	uint32_t cc:2;
144 	uint32_t p:1;
145 	uint32_t disp19:19;
146 } format2b_t;
147 #elif defined(_BIT_FIELDS_LTOH)
148 typedef struct format2b {
149 	uint32_t disp19:19;
150 	uint32_t p:1;
151 	uint32_t cc:2;
152 	uint32_t op2:3;
153 	uint32_t cond:4;
154 	uint32_t a:1;
155 	uint32_t op:2;
156 } format2b_t;
157 #else
158 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
159 #endif
160 
161 #if defined(_BIT_FIELDS_HTOL)
162 typedef struct format2c {
163 	uint32_t op:2;
164 	uint32_t a:1;
165 	uint32_t cond:4;
166 	uint32_t op2:3;
167 	uint32_t d16hi:2;
168 	uint32_t p:1;
169 	uint32_t rs1:5;
170 	uint32_t d16lo:14;
171 } format2c_t;
172 #elif defined(_BIT_FIELDS_LTOH)
173 typedef struct format2c {
174 	uint32_t d16lo:14;
175 	uint32_t rs1:5;
176 	uint32_t p:1;
177 	uint32_t d16hi:2;
178 	uint32_t op2:3;
179 	uint32_t cond:4;
180 	uint32_t a:1;
181 	uint32_t op:2;
182 } format2c_t;
183 #else
184 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
185 #endif
186 
187 #if defined(_BIT_FIELDS_HTOL)
188 typedef struct format3 {
189 	uint32_t op:2;
190 	uint32_t rd:5;
191 	uint32_t op3:6;
192 	uint32_t rs1:5;
193 	uint32_t i:1;
194 	uint32_t asi:8;
195 	uint32_t rs2:5;
196 } format3_t;
197 #elif defined(_BIT_FIELDS_LTOH)
198 typedef struct format3 {
199 	uint32_t rs2:5;
200 	uint32_t asi:8;
201 	uint32_t i:1;
202 	uint32_t rs1:5;
203 	uint32_t op3:6;
204 	uint32_t rd:5;
205 	uint32_t op:2;
206 } format3_t;
207 #else
208 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
209 #endif
210 
211 #if defined(_BIT_FIELDS_HTOL)
212 typedef struct format3a {
213 	uint32_t op:2;
214 	uint32_t rd:5;
215 	uint32_t op3:6;
216 	uint32_t rs1:5;
217 	uint32_t i:1;
218 	uint32_t simm13:13;
219 } format3a_t;
220 #elif defined(_BIT_FIELDS_LTOH)
221 typedef struct format3a {
222 	uint32_t simm13:13;
223 	uint32_t i:1;
224 	uint32_t rs1:5;
225 	uint32_t op3:6;
226 	uint32_t rd:5;
227 	uint32_t op:2;
228 } format3a_t;
229 #else
230 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
231 #endif
232 
233 #if defined(_BIT_FIELDS_HTOL)
234 typedef struct format3b {
235 	uint32_t op:2;
236 	uint32_t rd:5;
237 	uint32_t op3:6;
238 	uint32_t rs1:5;
239 	uint32_t i:1;
240 	uint32_t x:1;
241 	uint32_t undef:6;
242 	uint32_t shcnt:6;
243 } format3b_t;
244 #elif defined(_BIT_FIELDS_LTOH)
245 typedef struct format3b {
246 	uint32_t shcnt:6;
247 	uint32_t undef:6;
248 	uint32_t x:1;
249 	uint32_t i:1;
250 	uint32_t rs1:5;
251 	uint32_t op3:6;
252 	uint32_t rd:5;
253 	uint32_t op:2;
254 } format3b_t;
255 #else
256 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
257 #endif
258 
259 #if defined(_BIT_FIELDS_HTOL)
260 typedef struct format3c {
261 	uint32_t op:2;
262 	uint32_t rd:5;
263 	uint32_t op3:6;
264 	uint32_t cc2:1;
265 	uint32_t cond:4;
266 	uint32_t i:1;
267 	uint32_t cc:2;
268 	uint32_t simm11:11;
269 } format3c_t;
270 #elif defined(_BIT_FIELDS_LTOH)
271 typedef struct format3c {
272 	uint32_t simm11:11;
273 	uint32_t cc:2;
274 	uint32_t i:1;
275 	uint32_t cond:4;
276 	uint32_t cc2:1;
277 	uint32_t op3:6;
278 	uint32_t rd:5;
279 	uint32_t op:2;
280 } format3c_t;
281 #else
282 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
283 #endif
284 
285 #if defined(_BIT_FIELDS_HTOL)
286 typedef struct format3d {
287 	uint32_t op:2;
288 	uint32_t rd:5;
289 	uint32_t op3:6;
290 	uint32_t rs1:5;
291 	uint32_t i:1;
292 	uint32_t rcond:3;
293 	uint32_t simm10:10;
294 } format3d_t;
295 #elif defined(_BIT_FIELDS_LTOH)
296 typedef struct format3d {
297 	uint32_t simm10:10;
298 	uint32_t rcond:3;
299 	uint32_t i:1;
300 	uint32_t rs1:5;
301 	uint32_t op3:6;
302 	uint32_t rd:5;
303 	uint32_t op:2;
304 } format3d_t;
305 #else
306 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
307 #endif
308 
309 #if defined(_BIT_FIELDS_HTOL)
310 typedef struct formatcp {
311 	uint32_t op:2;
312 	uint32_t rd:5;
313 	uint32_t op3:6;
314 	uint32_t rs1:5;
315 	uint32_t opc:9;
316 	uint32_t rs2:5;
317 } formatcp_t;
318 #elif defined(_BIT_FIELDS_LTOH)
319 typedef struct formatcp {
320 	uint32_t rs2:5;
321 	uint32_t opc:9;
322 	uint32_t rs1:5;
323 	uint32_t op3:6;
324 	uint32_t rd:5;
325 	uint32_t op:2;
326 } formatcp_t;
327 #else
328 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
329 #endif
330 
331 #if defined(_BIT_FIELDS_HTOL)
332 typedef struct formattcc {
333 	uint32_t op:2;
334 	uint32_t undef:1;
335 	uint32_t cond:4;
336 	uint32_t op3:6;
337 	uint32_t rs1:5;
338 	uint32_t i:1;
339 	uint32_t cc:2;
340 	uint32_t undef2:3;
341 	uint32_t immtrap:8;
342 } formattcc_t;
343 #elif defined(_BIT_FIELDS_LTOH)
344 typedef struct formattcc {
345 	uint32_t immtrap:8;
346 	uint32_t undef2:3;
347 	uint32_t cc:2;
348 	uint32_t i:1;
349 	uint32_t rs1:5;
350 	uint32_t op3:6;
351 	uint32_t cond:4;
352 	uint32_t undef:1;
353 	uint32_t op:2;
354 } formattcc_t;
355 #else
356 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
357 #endif
358 
359 #if defined(_BIT_FIELDS_HTOL)
360 typedef struct formattcc2 {
361 	uint32_t op:2;
362 	uint32_t undef:1;
363 	uint32_t cond:4;
364 	uint32_t op3:6;
365 	uint32_t rs1:5;
366 	uint32_t i:1;
367 	uint32_t cc:2;
368 	uint32_t undef2:6;
369 	uint32_t rs2:5;
370 } formattcc2_t;
371 #elif defined(_BIT_FIELDS_LTOH)
372 typedef struct formattcc2 {
373 	uint32_t rs2:5;
374 	uint32_t undef2:6;
375 	uint32_t cc:2;
376 	uint32_t i:1;
377 	uint32_t rs1:5;
378 	uint32_t op3:6;
379 	uint32_t cond:4;
380 	uint32_t undef:1;
381 	uint32_t op:2;
382 } formattcc2_t;
383 #else
384 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
385 #endif
386 
387 #if defined(_BIT_FIELDS_HTOL)
388 typedef struct formatmbr {
389 	uint32_t op:2;
390 	uint32_t rd:5;
391 	uint32_t op3:6;
392 	uint32_t rs1:5;
393 	uint32_t i:1;
394 	uint32_t undef:6;
395 	uint32_t cmask:3;
396 	uint32_t mmask:4;
397 } formatmbr_t;
398 #elif defined(_BIT_FIELDS_LTOH)
399 typedef struct formatmbr {
400 	uint32_t mmask:4;
401 	uint32_t cmask:3;
402 	uint32_t undef:6;
403 	uint32_t i:1;
404 	uint32_t rs1:5;
405 	uint32_t op3:6;
406 	uint32_t rd:5;
407 	uint32_t op:2;
408 } formatmbr_t;
409 #else
410 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
411 #endif
412 
413 #if defined(_BIT_FIELDS_HTOL)
414 typedef struct formatfcmp {
415 	uint32_t op:2;
416 	uint32_t undef:3;
417 	uint32_t cc:2;
418 	uint32_t op3:6;
419 	uint32_t rs1:5;
420 	uint32_t opf:9;
421 	uint32_t rs2:5;
422 } formatfcmp_t;
423 #elif defined(_BIT_FIELDS_LTOH)
424 typedef struct formatfcmp {
425 	uint32_t rs2:5;
426 	uint32_t opf:9;
427 	uint32_t rs1:5;
428 	uint32_t op3:6;
429 	uint32_t cc:2;
430 	uint32_t undef:3;
431 	uint32_t op:2;
432 } formatfcmp_t;
433 #else
434 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
435 #endif
436 
437 #if defined(_BIT_FIELDS_HTOL)
438 typedef struct formatfmov {
439 	uint32_t op:2;
440 	uint32_t rd:5;
441 	uint32_t op3:6;
442 	uint32_t undef:1;
443 	uint32_t cond:4;
444 	uint32_t cc:3;
445 	uint32_t opf:6;
446 	uint32_t rs2:5;
447 } formatfmov_t;
448 #elif defined(_BIT_FIELDS_LTOH)
449 typedef struct formatfmov {
450 	uint32_t rs2:5;
451 	uint32_t opf:6;
452 	uint32_t cc:3;
453 	uint32_t cond:4;
454 	uint32_t undef:1;
455 	uint32_t op3:6;
456 	uint32_t rd:5;
457 	uint32_t op:2;
458 } formatfmov_t;
459 #else
460 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
461 #endif
462 
463 #if defined(_BIT_FIELDS_HTOL)
464 typedef struct formatfused {
465 	uint32_t op:2;
466 	uint32_t rd:5;
467 	uint32_t op3:6;
468 	uint32_t rs1:5;
469 	uint32_t rs3:5;
470 	uint32_t op5:4;
471 	uint32_t rs2:5;
472 } formatfused_t;
473 #elif defined(_BIT_FIELDS_LTOH)
474 typedef struct formatfused {
475 	uint32_t rs2:5;
476 	uint32_t op5:4;
477 	uint32_t rs3:5;
478 	uint32_t rs1:5;
479 	uint32_t op3:6;
480 	uint32_t rd:5;
481 	uint32_t op:2;
482 } formatfused_t;
483 #else
484 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
485 #endif
486 
487 typedef union ifmt {
488 	uint32_t	i;
489 	format1_t	f1;
490 	format2_t	f2;
491 	format2a_t	f2a;
492 	format2b_t	f2b;
493 	format2c_t	f2c;
494 	format3_t	f3;
495 	format3a_t	f3a;
496 	format3b_t	f3b;
497 	format3c_t	f3c;
498 	format3d_t	f3d;
499 	formatcp_t	fcp;
500 	formattcc_t	ftcc;
501 	formattcc2_t	ftcc2;
502 	formatfcmp_t	fcmp;
503 	formatmbr_t	fmb;
504 	formatfmov_t	fmv;
505 	formatfused_t	fused;
506 } ifmt_t;
507 
508 /* integer register names */
509 static const char *reg_names[32] = {
510 	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
511 	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
512 	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
513 	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7"
514 };
515 
516 /* floating point register names */
517 static const char *freg_names[32] = {
518 	"%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
519 	"%f8",  "%f9",  "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
520 	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
521 	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
522 };
523 
524 /* double precision register names */
525 static const char *fdreg_names[32] = {
526 	"%d0",  "%d32", "%d2",  "%d34", "%d4",  "%d36", "%d6",  "%d38",
527 	"%d8",  "%d40", "%d10", "%d42", "%d12", "%d44", "%d14", "%d46",
528 	"%d16", "%d48", "%d18", "%d50", "%d20", "%d52", "%d22", "%d54",
529 	"%d24", "%d56", "%d26", "%d58", "%d28", "%d60", "%d30", "%d62"
530 };
531 
532 static const char *compat_fdreg_names[32] = {
533 	"%f0",  "%f32", "%f2",  "%f34", "%f4",  "%f36", "%f6",  "%f38",
534 	"%f8",  "%f40", "%f10", "%f42", "%f12", "%f44", "%f14", "%f46",
535 	"%f16", "%f48", "%f18", "%f50", "%f20", "%f52", "%f22", "%f54",
536 	"%f24", "%f56", "%f26", "%f58", "%f28", "%f60", "%f30", "%f62"
537 };
538 
539 
540 static const char *fqreg_names[32] = {
541 	"%q0",  "%q32", "%f2",  "%f3",  "%f4",  "%q4",  "%q36", "%f6",
542 	"%f7",  "%q8",  "%q40", "%f10", "%f11", "%q12", "%q44", "%f14",
543 	"%f15", "%q16", "%q48", "%f18", "%f19", "%q20", "%q52", "%f22",
544 	"%f23", "%q24", "%q56", "%f26", "%f27", "%q28", "%q60", "%f30",
545 };
546 
547 
548 /* coprocessor register names -- sparcv8 only */
549 static const char *cpreg_names[32] = {
550 	"%c0",  "%c1",  "%c2",  "%c3",  "%c4",  "%c5",  "%c6",  "%c7",
551 	"%c8",  "%c9",  "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
552 	"%c16", "%c17", "%c18", "%c19", "%c20", "%c21", "%c22", "%c23",
553 	"%c24", "%c25", "%c26", "%c27", "%c28", "%c29", "%c30", "%c31",
554 };
555 
556 /* floating point condition code names */
557 static const char *fcc_names[4] = {
558 	"%fcc0", "%fcc1", "%fcc2", "%fcc3"
559 };
560 
561 /* condition code names */
562 static const char *icc_names[4] = {
563 	"%icc", NULL, "%xcc", NULL
564 };
565 
566 /* bitmask values for membar */
567 static const char *membar_mmask[4] = {
568 	"#LoadLoad", "#StoreLoad", "#LoadStore", "#StoreStore"
569 };
570 
571 static const char *membar_cmask[3] = {
572 	"#Lookaside", "#MemIssue", "#Sync"
573 };
574 
575 /* v8 ancillary state register names */
576 static const char *asr_names[32] = {
577 	"%y",	"%asr1",  "%asr2",  "%asr3",
578 	"%asr4",  "%asr5",  "%asr6",  "%asr7",
579 	"%asr8",  "%asr9",  "%asr10", "%asr11",
580 	"%asr12", "%asr13", "%asr14", "%asr15",
581 	NULL,	NULL,	NULL,	NULL,
582 	NULL,	NULL,	NULL,	NULL,
583 	NULL,	NULL,	NULL,	NULL,
584 	NULL,	NULL,	NULL,	NULL
585 };
586 static const uint32_t asr_rdmask = 0x0000ffffL;
587 static const uint32_t asr_wrmask = 0x0000ffffL;
588 
589 static const char *v9_asr_names[32] = {
590 	"%y",		NULL,		"%ccr",	"%asi",
591 	"%tick",	"%pc",		"%fprs",	NULL,
592 	NULL,		NULL,		NULL,	NULL,
593 	NULL,		NULL,		NULL,	NULL,
594 	"%pcr",	"%pic",	NULL,	"%gsr",
595 	"%softint_set",	"%softint_clr",	"%softint",	"%tick_cmpr",
596 	"%stick",	"%stick_cmpr",	NULL,	NULL,
597 	NULL,		NULL,		NULL,	NULL
598 };
599 /*
600  * on v9, only certain registers are valid for read or writing
601  * these are bitmasks corresponding to which registers are valid in which
602  * case
603  */
604 static const uint32_t v9_asr_rdmask = 0x03cb007d;
605 static const uint32_t v9_asr_wrmask = 0x02fb004d;
606 
607 /* privledged register names on v9 */
608 /* TODO: compat - NULL to %priv_nn */
609 static const char *v9_privreg_names[32] = {
610 	"%tpc",	 "%tnpc",	"%tstate",  "%tt",
611 	"%tick",	"%tba",	 "%pstate",  "%tl",
612 	"%pil",	 "%cwp",	 "%cansave", "%canrestore",
613 	"%cleanwin", "%otherwin", "%wstate",  "%fq",
614 	"%gl",	NULL,	NULL,	NULL,
615 	NULL,	NULL,	NULL,	NULL,
616 	NULL,	NULL,	NULL,	NULL,
617 	NULL,	NULL,	NULL,	"%ver"
618 };
619 
620 static const uint32_t v9_pr_rdmask = 0x80017fff;
621 static const uint32_t v9_pr_wrmask = 0x00017fef;
622 
623 static const char *prefetch_str[32] = {
624 	"#n_reads", "#one_read",
625 	"#n_writes", "#one_write",
626 	"#page",    NULL, NULL, NULL,
627 	NULL, NULL, NULL, NULL,
628 	NULL, NULL, NULL, NULL,
629 	NULL, "#unified", NULL, NULL,
630 	"#n_reads_strong", "#one_read_strong",
631 	"#n_writes_strong", "#one_write_strong",
632 	NULL, NULL, NULL, NULL,
633 	NULL, NULL, NULL, NULL
634 };
635 
636 static void prt_field(const char *, uint32_t, int);
637 
638 static const char *get_regname(dis_handle_t *, int, uint32_t);
639 static int32_t sign_extend(int32_t, int32_t);
640 
641 static void prt_name(dis_handle_t *, const char *, int);
642 
643 #define	IMM_SIGNED 0x01  /* Is immediate value signed		*/
644 #define	IMM_ADDR   0x02  /* Is immediate value part of an address */
645 static void prt_imm(dis_handle_t *, uint32_t, int);
646 
647 static void prt_asi(dis_handle_t *, uint32_t);
648 static void prt_address(dis_handle_t *, uint32_t, int);
649 static void prt_aluargs(dis_handle_t *, uint32_t, uint32_t);
650 static void bprintf(dis_handle_t *, const char *, ...);
651 
652 /*
653  * print out val (which is 'bitlen' bits long) in binary
654  */
655 #if defined(DIS_STANDALONE)
656 /* ARGSUSED */
657 void
658 prt_binary(uint32_t val, int bitlen)
659 {
660 
661 }
662 
663 #else
664 
665 void
666 prt_binary(uint32_t val, int bitlen)
667 {
668 	int i;
669 
670 	for (i = bitlen - 1; i >= 0; --i) {
671 		(void) fprintf(stderr, ((val & (1L << i)) != 0) ? "1" : "0");
672 
673 		if (i % 4 == 0 && i != 0)
674 			(void) fprintf(stderr, " ");
675 	}
676 }
677 #endif /* DIS_STANDALONE */
678 
679 
680 /*
681  * print out a call instruction
682  * format: call address  <name>
683  */
684 /* ARGSUSED1 */
685 int
686 fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
687 {
688 	ifmt_t *f = (ifmt_t *)&instr;
689 
690 	int32_t disp;
691 	size_t curlen;
692 
693 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
694 
695 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
696 		prt_field("op", f->f1.op, 2);
697 		prt_field("disp30", f->f1.disp30, 30);
698 	}
699 
700 	disp = sign_extend(f->f1.disp30, 30) * 4;
701 
702 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
703 
704 	bprintf(dhp, (octal != 0) ? "%s0%-11lo" : "%s0x%-10lx",
705 	    (disp < 0) ? "-" : "+",
706 	    (disp < 0) ? (-disp) : disp);
707 
708 	(void) strlcat(dhp->dh_buf, " <", dhp->dh_buflen);
709 
710 	curlen = strlen(dhp->dh_buf);
711 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
712 	    dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL,
713 	    NULL);
714 	(void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
715 
716 
717 	return (0);
718 }
719 
720 int
721 fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
722 {
723 	ifmt_t *f = (ifmt_t *)&instr;
724 
725 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
726 		prt_field("op", f->f2.op, 2);
727 		prt_field("op2", f->f2.op2, 3);
728 		prt_field("rd", f->f2.rd, 5);
729 		prt_field("imm22", f->f2.imm22, 22);
730 	}
731 
732 	if (idx == 0) {
733 		/* unimp / illtrap */
734 		prt_name(dhp, inp->in_data.in_def.in_name, 1);
735 		prt_imm(dhp, f->f2.imm22, 0);
736 		return (0);
737 	}
738 
739 	if (f->f2.imm22 == 0 && f->f2.rd == 0) {
740 		prt_name(dhp, "nop", 0);
741 		return (0);
742 	}
743 
744 	/* ?? Should we return -1 if rd == 0 && disp != 0 */
745 
746 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
747 
748 	bprintf(dhp,
749 	    ((dhp->dh_flags & DIS_OCTAL) != 0) ?
750 	    "%%hi(0%lo), %s" : "%%hi(0x%lx), %s",
751 	    f->f2.imm22 << 10,
752 	    reg_names[f->f2.rd]);
753 
754 	return (0);
755 }
756 
757 /* ARGSUSED3 */
758 int
759 fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
760 {
761 	const char *name = inp->in_data.in_def.in_name;
762 	const char *r = NULL;
763 	const char *annul = "";
764 	const char *pred  = "";
765 
766 	char buf[15];
767 
768 	ifmt_t *f = (ifmt_t *)&instr;
769 
770 	size_t curlen;
771 	int32_t disp;
772 	uint32_t flags = inp->in_data.in_def.in_flags;
773 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
774 
775 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
776 		prt_field("op", f->f2.op, 2);
777 		prt_field("op2", f->f2.op2, 3);
778 
779 		switch (FLG_DISP_VAL(flags)) {
780 		case DISP22:
781 			prt_field("cond", f->f2a.cond, 4);
782 			prt_field("a", f->f2a.a, 1);
783 			prt_field("disp22", f->f2a.disp22, 22);
784 			break;
785 
786 		case DISP19:
787 			prt_field("cond", f->f2a.cond, 4);
788 			prt_field("a", f->f2a.a, 1);
789 			prt_field("p", f->f2b.p, 1);
790 			prt_field("cc", f->f2b.cc, 2);
791 			prt_field("disp19", f->f2b.disp19, 19);
792 			break;
793 
794 		case DISP16:
795 			prt_field("bit 28", ((instr & (1L << 28)) >> 28), 1);
796 			prt_field("rcond", f->f2c.cond, 3);
797 			prt_field("p", f->f2c.p, 1);
798 			prt_field("rs1", f->f2c.rs1, 5);
799 			prt_field("d16hi", f->f2c.d16hi, 2);
800 			prt_field("d16lo", f->f2c.d16lo, 14);
801 			break;
802 		}
803 	}
804 
805 	if (f->f2b.op2 == 0x01 && idx == 0x00 && f->f2b.p == 1 &&
806 	    f->f2b.cc == 0x02 && ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0)) {
807 		name = "iprefetch";
808 		flags = FLG_RS1(REG_NONE)|FLG_DISP(DISP19);
809 	}
810 
811 	switch (FLG_DISP_VAL(flags)) {
812 	case DISP22:
813 		disp = sign_extend(f->f2a.disp22, 22);
814 		break;
815 
816 	case DISP19:
817 		disp = sign_extend(f->f2b.disp19, 19);
818 		break;
819 
820 	case DISP16:
821 		disp = sign_extend((f->f2c.d16hi << 14)|f->f2c.d16lo, 16);
822 		break;
823 
824 	}
825 
826 	disp *= 4;
827 
828 	if ((FLG_RS1_VAL(flags) == REG_ICC) || (FLG_RS1_VAL(flags) == REG_FCC))
829 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2b.cc);
830 	else
831 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2c.rs1);
832 
833 	if (r == NULL)
834 		return (-1);
835 
836 	if (f->f2a.a == 1)
837 		annul = ",a";
838 
839 	if ((flags & FLG_PRED) != 0) {
840 		if (f->f2b.p == 0) {
841 			pred = ",pn";
842 		} else {
843 			if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
844 				pred = ",pt";
845 		}
846 	}
847 
848 	(void) snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
849 	prt_name(dhp, buf, 1);
850 
851 
852 	switch (FLG_DISP_VAL(flags)) {
853 	case DISP22:
854 		bprintf(dhp,
855 		    (octal != 0) ? "%s0%-11lo <" : "%s0x%-10lx <",
856 		    (disp < 0) ? "-" : "+",
857 		    (disp < 0) ? (-disp) : disp);
858 		break;
859 
860 	case DISP19:
861 		bprintf(dhp,
862 		    (octal != 0) ? "%s, %s0%-5lo <" : "%s, %s0x%-04lx <",
863 		    r,
864 		    (disp < 0) ? "-" : "+",
865 		    (disp < 0) ? (-disp) : disp);
866 		break;
867 
868 	case DISP16:
869 		bprintf(dhp,
870 		    (octal != 0) ? "%s, %s0%-6lo <" : "%s, %s0x%-5lx <",
871 		    r,
872 		    (disp < 0) ? "-" : "+",
873 		    (disp < 0) ? (-disp) : disp);
874 		break;
875 	}
876 
877 	curlen = strlen(dhp->dh_buf);
878 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
879 	    dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL, NULL);
880 
881 	(void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
882 
883 	return (0);
884 }
885 
886 
887 
888 /*
889  * print out the compare and swap instructions (casa/casxa)
890  * format: casa/casxa [%rs1] imm_asi, %rs2, %rd
891  *	    casa/casxa [%rs1] %asi, %rs2, %rd
892  *
893  * If DIS_DEBUG_SYN_ALL is set, synthetic instructions are emitted
894  * when an immediate ASI value is given as follows:
895  *
896  * casa  [%rs1]#ASI_P, %rs2, %rd    -> cas   [%rs1], %rs2, %rd
897  * casa  [%rs1]#ASI_P_L, %rs2, %rd  -> casl  [%rs1], %rs2, %rd
898  * casxa [%rs1]#ASI_P, %rs2, %rd    -> casx  [%rs1], %rs2, %rd
899  * casxa [%rs1]#ASI_P_L, %rs2, %rd  -> casxl [%rs1], %rs2, %rd
900  */
901 static int
902 fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
903 {
904 	ifmt_t *f = (ifmt_t *)&instr;
905 	int noasi = 0;
906 
907 	if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
908 		if (f->f3.op3 == 0x3c && f->f3.i == 0) {
909 			if (f->f3.asi == 0x80) {
910 				noasi = 1;
911 				name = "cas";
912 			}
913 
914 			if (f->f3.asi == 0x88) {
915 				noasi = 1;
916 				name = "casl";
917 			}
918 		}
919 
920 		if (f->f3.op3 == 0x3e && f->f3.i == 0) {
921 			if (f->f3.asi == 0x80) {
922 				noasi = 1;
923 				name = "casx";
924 			}
925 
926 			if (f->f3.asi == 0x88) {
927 				noasi = 1;
928 				name = "casxl";
929 			}
930 		}
931 	}
932 
933 	prt_name(dhp, name, 1);
934 
935 	bprintf(dhp, "[%s]", reg_names[f->f3.rs1]);
936 
937 	if (noasi == 0) {
938 		(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
939 		prt_asi(dhp, instr);
940 	}
941 
942 	bprintf(dhp, ", %s, %s", reg_names[f->f3.rs2], reg_names[f->f3.rd]);
943 
944 	return (0);
945 }
946 
947 /*
948  * format a load/store instruction
949  * format: ldXX [%rs1 + %rs2], %rd	  load, i==0
950  *	    ldXX [%rs1 +/- nn], %rd	  load, i==1
951  *	    ldXX [%rs1 + %rs2] #XX, %rd   load w/ imm_asi, i==0
952  *	    ldXX [%rs1 +/- nn] %asi, %rd  load from asi[%asi], i==1
953  *
954  *	    stXX %rd, [%rs1 + %rs2]	  store, i==0
955  *	    stXX %rd, [%rs1 +/- nn]	  store, i==1
956  *	    stXX %rd, [%rs1 + %rs1] #XX   store to imm_asi, i==0
957  *	    stXX %rd, [%rs1 +/-nn] %asi   store to asi[%asi], i==1
958  *
959  * The register sets used for %rd are set in the instructions flags field
960  * The asi variants are used if FLG_ASI is set in the instructions flags field
961  *
962  * If DIS_DEBUG_SYNTH_ALL or DIS_DEBUG_COMPAT are set,
963  * When %rs1, %rs2 or nn are 0, they are not printed, i.e.
964  * [ %rs1 + 0x0 ], %rd -> [%rs1], %rd for example
965  *
966  * The following synthetic instructions are also implemented:
967  *
968  * stb %g0, [addr] -> clrb [addr]    DIS_DEBUG_SYNTH_ALL
969  * sth %g0, [addr] -> crlh [addr]    DIS_DEBUG_SYNTH_ALL
970  * stw %g0, [addr] -> clr  [addr]    DIS_DEBUG_SYNTH_ALL|DIS_DEBUG_COMPAT
971  * stx %g0, [addr] -> clrx [addr]    DIS_DEBUG_SYNTH_ALL
972  *
973  * If DIS_DEBUG_COMPAT is set, the following substitutions also take place
974  *	lduw -> ld
975  *	ldtw -> ld
976  *	stuw -> st
977  *	sttw -> st
978  */
979 int
980 fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
981 {
982 	ifmt_t *f = (ifmt_t *)&instr;
983 	const char *regstr = NULL;
984 
985 	const char *iname = inp->in_data.in_def.in_name;
986 	uint32_t flags = inp->in_data.in_def.in_flags;
987 
988 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
989 		prt_field("op", f->f3.op, 2);
990 		prt_field("op3", f->f3.op3, 6);
991 		prt_field("rs1", f->f3.rs1, 5);
992 		prt_field("i", f->f3.i, 1);
993 		if (f->f3.i != 0) {
994 			prt_field("simm13", f->f3a.simm13, 13);
995 		} else {
996 			if ((flags & FLG_ASI) != 0)
997 				prt_field("imm_asi", f->f3.asi, 8);
998 			prt_field("rs2", f->f3.rs2, 5);
999 		}
1000 		prt_field("rd", f->f3.rd, 5);
1001 	}
1002 
1003 	if (idx == 0x2d || idx == 0x3d) {
1004 		/* prefetch / prefetcha */
1005 
1006 		prt_name(dhp, iname, 1);
1007 
1008 		prt_address(dhp, instr, 0);
1009 
1010 		if (idx == 0x3d) {
1011 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
1012 			prt_asi(dhp, instr);
1013 		}
1014 
1015 		(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
1016 
1017 		/* fcn field is the same as rd */
1018 		if (prefetch_str[f->f3.rd] != NULL)
1019 			(void) strlcat(dhp->dh_buf, prefetch_str[f->f3.rd],
1020 			    dhp->dh_buflen);
1021 		else
1022 			prt_imm(dhp, f->f3.rd, 0);
1023 
1024 		return (0);
1025 	}
1026 
1027 	/* casa / casxa */
1028 	if (idx == 0x3c || idx == 0x3e)
1029 		return (fmt_cas(dhp, instr, iname));
1030 
1031 	/* synthetic instructions & special cases */
1032 	switch (idx) {
1033 	case 0x00:
1034 		/* ld */
1035 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
1036 			iname = "lduw";
1037 		break;
1038 
1039 	case 0x03:
1040 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
1041 			iname = "ldtw";
1042 		break;
1043 
1044 	case 0x04:
1045 		/* stw */
1046 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
1047 			iname = "stuw";
1048 
1049 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1050 		    == 0)
1051 			break;
1052 
1053 		if (f->f3.rd == 0) {
1054 			iname = "clr";
1055 			flags = FLG_RD(REG_NONE);
1056 		}
1057 		break;
1058 
1059 	case 0x05:
1060 		/* stb */
1061 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1062 		    == 0)
1063 			break;
1064 
1065 		if (f->f3.rd == 0) {
1066 			iname = "clrb";
1067 			flags = FLG_RD(REG_NONE);
1068 		}
1069 		break;
1070 
1071 	case 0x06:
1072 		/* sth */
1073 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1074 		    == 0)
1075 			break;
1076 
1077 		if (f->f3.rd == 0) {
1078 			iname = "clrh";
1079 			flags = FLG_RD(REG_NONE);
1080 		}
1081 		break;
1082 
1083 	case 0x07:
1084 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
1085 			iname = "sttw";
1086 		break;
1087 
1088 	case 0x0e:
1089 		/* stx */
1090 
1091 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1092 		    == 0)
1093 			break;
1094 
1095 		if (f->f3.rd == 0) {
1096 			iname = "clrx";
1097 			flags = FLG_RD(REG_NONE);
1098 		}
1099 		break;
1100 
1101 	case 0x13:
1102 		/* ldtwa */
1103 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
1104 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
1105 			iname = "ldtwa";
1106 		break;
1107 
1108 	case 0x17:
1109 		/* sttwa */
1110 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
1111 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
1112 			iname = "sttwa";
1113 		break;
1114 
1115 	case 0x21:
1116 	case 0x25:
1117 		/*
1118 		 * on sparcv8 it merely says that rd != 1 should generate an
1119 		 * exception, on v9, it is illegal
1120 		 */
1121 		if ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0)
1122 			break;
1123 
1124 		iname = (idx == 0x21) ? "ldx" : "stx";
1125 
1126 		if (f->f3.rd > 1)
1127 			return (-1);
1128 
1129 		break;
1130 
1131 	case 0x31:
1132 		/* stda */
1133 		switch (f->f3.asi) {
1134 			case 0xc0:
1135 			case 0xc1:
1136 			case 0xc8:
1137 			case 0xc9:
1138 			case 0xc2:
1139 			case 0xc3:
1140 			case 0xca:
1141 			case 0xcb:
1142 			case 0xc4:
1143 			case 0xc5:
1144 			case 0xcc:
1145 			case 0xcd:
1146 				/*
1147 				 * store partial floating point, only valid w/
1148 				 * vis
1149 				 *
1150 				 * Somewhat confusingly, it uses the same op
1151 				 * code as 'stda' -- store double to alternate
1152 				 * space.  It is distinguised by specific
1153 				 * imm_asi values (as seen above), and
1154 				 * has a slightly different output syntax
1155 				 */
1156 
1157 				if ((dhp->dh_flags & DIS_SPARC_V9_SGI) == 0)
1158 					break;
1159 				if (f->f3.i != 0)
1160 					break;
1161 				prt_name(dhp, iname, 1);
1162 				bprintf(dhp, "%s, %s, [%s] ",
1163 				    get_regname(dhp, REG_FPD, f->f3.rd),
1164 				    get_regname(dhp, REG_FPD, f->f3.rs2),
1165 				    get_regname(dhp, REG_FPD, f->f3.rs1));
1166 				prt_asi(dhp, instr);
1167 				return (0);
1168 
1169 			default:
1170 				break;
1171 		}
1172 
1173 	}
1174 
1175 	regstr = get_regname(dhp, FLG_RD_VAL(flags), f->f3.rd);
1176 
1177 	prt_name(dhp, iname, 1);
1178 
1179 	if ((flags & FLG_STORE) != 0) {
1180 		if (regstr[0] != '\0') {
1181 			(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
1182 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
1183 		}
1184 
1185 		prt_address(dhp, instr, 0);
1186 		if ((flags & FLG_ASI) != 0) {
1187 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
1188 			prt_asi(dhp, instr);
1189 		}
1190 	} else {
1191 		prt_address(dhp, instr, 0);
1192 		if ((flags & FLG_ASI) != 0) {
1193 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
1194 			prt_asi(dhp, instr);
1195 		}
1196 
1197 		if (regstr[0] != '\0') {
1198 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
1199 			(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
1200 		}
1201 	}
1202 
1203 	return (0);
1204 }
1205 
1206 static int
1207 fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
1208 {
1209 	ifmt_t *f = (ifmt_t *)&instr;
1210 	int flags = FLG_P1(REG_CP)|FLG_P2(REG_CP)|FLG_NOIMM|FLG_P3(REG_CP);
1211 
1212 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
1213 		prt_field("op", f->fcp.op, 2);
1214 		prt_field("op3", f->fcp.op3, 6);
1215 		prt_field("opc", f->fcp.opc, 9);
1216 		prt_field("rs1", f->fcp.rs1, 5);
1217 		prt_field("rs2", f->fcp.rs2, 5);
1218 		prt_field("rd", f->fcp.rd, 5);
1219 	}
1220 
1221 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1222 	prt_imm(dhp, f->fcp.opc, 0);
1223 
1224 	(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
1225 	(void) prt_aluargs(dhp, instr, flags);
1226 
1227 	return (0);
1228 }
1229 
1230 static int
1231 dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1232 {
1233 	const char *psr_str = "%psr";
1234 	const char *wim_str = "%wim";
1235 	const char *tbr_str = "%tbr";
1236 
1237 	const char *name = inp->in_data.in_def.in_name;
1238 	const char *regstr = NULL;
1239 
1240 	ifmt_t *f = (ifmt_t *)&instr;
1241 
1242 	int rd = (idx < 0x30);
1243 	int v9 = (dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI));
1244 	int ridx = f->f3.rs1;
1245 	int i, first;
1246 	int pr_rs1 = 1;
1247 	int pr_rs2 = 1;
1248 
1249 	int use_mask = 1;
1250 	uint32_t mask;
1251 
1252 	if (rd == 0)
1253 		ridx = f->f3.rd;
1254 
1255 	switch (idx) {
1256 	case 0x28:
1257 		/* rd */
1258 
1259 		/* stbar */
1260 		if ((f->f3.rd == 0) && (f->f3.rs1 == 15) && (f->f3.i == 0)) {
1261 			prt_name(dhp, "stbar", 0);
1262 			return (0);
1263 		}
1264 
1265 		/* membar */
1266 		if ((v9 != 0) && (f->f3.rd == 0) && (f->f3.rs1 == 15) &&
1267 		    (f->f3.i == 1) && ((f->i & (1L << 12)) == 0)) {
1268 
1269 			prt_name(dhp, "membar",
1270 			    ((f->fmb.cmask != 0) || (f->fmb.mmask != 0)));
1271 
1272 			first = 0;
1273 
1274 			for (i = 0; i < 4; ++i) {
1275 				if ((f->fmb.cmask & (1L << i)) != 0) {
1276 					bprintf(dhp, "%s%s",
1277 					    (first != 0) ? "|" : "",
1278 					    membar_cmask[i]);
1279 					first = 1;
1280 				}
1281 			}
1282 
1283 			for (i = 0; i < 5; ++i) {
1284 				if ((f->fmb.mmask & (1L << i)) != 0) {
1285 					bprintf(dhp, "%s%s",
1286 					    (first != 0) ? "|" : "",
1287 					    membar_mmask[i]);
1288 					first = 1;
1289 				}
1290 			}
1291 
1292 			return (0);
1293 		}
1294 
1295 		if (v9 != 0) {
1296 			regstr = v9_asr_names[ridx];
1297 			mask = v9_asr_rdmask;
1298 		} else {
1299 			regstr = asr_names[ridx];
1300 			mask = asr_rdmask;
1301 		}
1302 		break;
1303 
1304 	case 0x29:
1305 		/*
1306 		 * NOTE: due to an overlay entry, this only gets executed when
1307 		 * disassembling v8 instructions
1308 		 */
1309 		regstr = psr_str;
1310 		use_mask = 0;
1311 		break;
1312 
1313 	case 0x2a:
1314 		if (v9 != 0) {
1315 			regstr = v9_privreg_names[ridx];
1316 			mask = v9_pr_rdmask;
1317 		} else {
1318 			regstr = wim_str;
1319 			use_mask = 0;
1320 		}
1321 		break;
1322 
1323 	case 0x2b:
1324 		if (v9 != 0) {
1325 			/* flushw */
1326 			prt_name(dhp, name, 0);
1327 			return (0);
1328 		}
1329 
1330 		regstr = tbr_str;
1331 		use_mask = 0;
1332 		break;
1333 
1334 	case 0x30:
1335 		if (v9 != 0) {
1336 			regstr = v9_asr_names[ridx];
1337 			mask = v9_asr_wrmask;
1338 		} else {
1339 			regstr = asr_names[ridx];
1340 			mask = asr_wrmask;
1341 		}
1342 
1343 		/* synth: mov */
1344 		if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1345 		    == 0)
1346 			break;
1347 
1348 		if (f->f3.rs1 == 0) {
1349 			name = "mov";
1350 			pr_rs1 = 0;
1351 		}
1352 
1353 		if ((f->f3.i == 0 && f->f3.rs2 == 0) ||
1354 		    (f->f3.i == 1 && f->f3a.simm13 == 0)) {
1355 			name = "mov";
1356 			pr_rs2 = 0;
1357 		}
1358 
1359 		if (pr_rs1 == 0)
1360 			pr_rs2 = 1;
1361 
1362 		break;
1363 
1364 	case 0x31:
1365 		/*
1366 		 * NOTE: due to the presence of an overlay entry for another
1367 		 * table, this case only happens when doing v8 instructions
1368 		 * only
1369 		 */
1370 		regstr = psr_str;
1371 		use_mask = 0;
1372 		break;
1373 
1374 	case 0x32:
1375 		if (v9 != 0) {
1376 			regstr = v9_privreg_names[ridx];
1377 			mask = v9_pr_wrmask;
1378 		} else {
1379 			regstr = wim_str;
1380 			use_mask = 0;
1381 		}
1382 		break;
1383 
1384 	case 0x33:
1385 		/* NOTE: due to an overlay entry, this is v8 only */
1386 		regstr = tbr_str;
1387 		use_mask = 0;
1388 		break;
1389 	}
1390 
1391 	if (regstr == NULL)
1392 		return (-1);
1393 
1394 	if (use_mask != 0 && ((1L << ridx) & mask) == 0)
1395 		return (-1);
1396 
1397 	prt_name(dhp, name, 1);
1398 
1399 	if (rd != 0) {
1400 		bprintf(dhp, "%s, %s", regstr, reg_names[f->f3.rd]);
1401 	} else {
1402 		if (pr_rs1 == 1)
1403 			bprintf(dhp, "%s, ", reg_names[f->f3.rs1]);
1404 
1405 		if (pr_rs2 != 0) {
1406 			if (f->f3.i == 1)
1407 				prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
1408 				    IMM_SIGNED);
1409 			else
1410 				(void) strlcat(dhp->dh_buf,
1411 				    reg_names[f->f3.rs2], dhp->dh_buflen);
1412 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
1413 		}
1414 
1415 		(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
1416 	}
1417 
1418 	return (0);
1419 }
1420 
1421 /* ARGSUSED3 */
1422 int
1423 fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1424 {
1425 	ifmt_t *f = (ifmt_t *)&instr;
1426 
1427 	int v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
1428 	int p_rs1, p_t;
1429 
1430 	if (f->ftcc.undef != 0)
1431 		return (-1);
1432 
1433 	if (icc_names[f->ftcc.cc] == NULL)
1434 		return (-1);
1435 
1436 	if (f->ftcc.i == 1 && f->ftcc.undef2 != 0)
1437 		return (-1);
1438 
1439 	if (f->ftcc2.i == 0 && f->ftcc2.undef2 != 0)
1440 		return (-1);
1441 
1442 	p_rs1 = ((f->ftcc.rs1 != 0) ||
1443 	    ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
1444 
1445 	if (f->ftcc.i == 0) {
1446 		p_t = (f->f3.rs2 != 0 || p_rs1 == 0);
1447 
1448 		bprintf(dhp, "%-9s %s%s%s%s%s", inp->in_data.in_def.in_name,
1449 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
1450 		    (v9 != 0) ? ", " : "",
1451 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
1452 		    (p_rs1 != 0) ? " + " : "",
1453 		    (p_t != 0) ? reg_names[f->f3.rs2] : "");
1454 	} else {
1455 		bprintf(dhp, "%-9s %s%s%s%s0x%x", inp->in_data.in_def.in_name,
1456 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
1457 		    (v9 != 0) ? ", " : "",
1458 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
1459 		    (p_rs1 != 0) ? " + " : "",
1460 		    f->ftcc.immtrap);
1461 	}
1462 
1463 	return (0);
1464 }
1465 
1466 static int
1467 prt_shift(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
1468 {
1469 	char name[5];
1470 	uint32_t cnt;
1471 
1472 	ifmt_t *f = (ifmt_t *)&instr;
1473 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
1474 
1475 	name[0] = '\0';
1476 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
1477 
1478 	if (f->f3b.i == 1)
1479 		cnt = f->f3.rs2;
1480 
1481 	if (f->f3b.x == 1 && ((dhp->dh_flags & DIS_SPARC_V8) == 0)) {
1482 		cnt = f->f3b.shcnt;
1483 		(void) strlcat(name, "x", sizeof (name));
1484 	}
1485 
1486 	prt_name(dhp, name, 1);
1487 
1488 	if (f->f3b.i == 1)
1489 		bprintf(dhp, (octal != 0) ? "%s, 0%lo, %s" : "%s, 0x%lx, %s",
1490 		    reg_names[f->f3.rs1], cnt, reg_names[f->f3.rd]);
1491 	else
1492 		bprintf(dhp, "%s, %s, %s", reg_names[f->f3.rs1],
1493 		    reg_names[f->f3.rs2], reg_names[f->f3.rd]);
1494 
1495 	return (0);
1496 }
1497 
1498 /* ARGSUSED3 */
1499 static int
1500 prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1501 {
1502 	const char *name = inp->in_data.in_def.in_name;
1503 	ifmt_t *f = (ifmt_t *)&instr;
1504 
1505 	if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
1506 		name = "call";
1507 
1508 	if (f->f3.rd == 0) {
1509 		if (f->f3.i == 1 && f->f3a.simm13 == 8) {
1510 			if (f->f3.rs1 == 15) {
1511 				prt_name(dhp, "retl", 0);
1512 				return (0);
1513 			}
1514 
1515 			if (f->f3.rs1 == 31) {
1516 				prt_name(dhp, "ret", 0);
1517 				return (0);
1518 			}
1519 		}
1520 
1521 		name = "jmp";
1522 	}
1523 
1524 	prt_name(dhp, name, 1);
1525 	prt_address(dhp, instr, 1);
1526 
1527 	if (f->f3.rd == 0)
1528 		return (0);
1529 
1530 	if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
1531 		return (0);
1532 
1533 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1534 
1535 	return (0);
1536 }
1537 
1538 int
1539 fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1540 {
1541 	ifmt_t *f = (ifmt_t *)&instr;
1542 
1543 	const char *name = inp->in_data.in_def.in_name;
1544 	int flags = inp->in_data.in_def.in_flags;
1545 	int arg = 0;
1546 
1547 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
1548 		prt_field("op", f->f3.op, 2);
1549 		prt_field("op3", f->f3.op3, 6);
1550 		prt_field("rs1", f->f3.rs1, 5);
1551 
1552 		switch (idx) {
1553 			/* TODO: more formats */
1554 
1555 		default:
1556 			if (f->f3.i == 0)
1557 				prt_field("rs2", f->f3.rs2, 5);
1558 			else
1559 				prt_field("simm13", f->f3a.simm13, 13);
1560 
1561 			prt_field("rd", f->f3.rd, 5);
1562 		}
1563 
1564 	}
1565 
1566 	switch (idx) {
1567 	case 0x00:
1568 		/* add */
1569 
1570 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
1571 			break;
1572 
1573 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1574 		    f->f3a.simm13 == 1) {
1575 			name = "inc";
1576 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1577 			break;
1578 		}
1579 
1580 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1581 		    f->f3a.simm13 != 1) {
1582 			name = "inc";
1583 			flags = FLG_P1(REG_NONE);
1584 			break;
1585 		}
1586 		break;
1587 
1588 	case 0x02:
1589 		/* or */
1590 
1591 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1592 		    == 0)
1593 			break;
1594 
1595 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0) {
1596 			if (f->f3.rs1 == f->f3.rd) {
1597 				name = "bset";
1598 				flags = FLG_P1(REG_NONE);
1599 				break;
1600 			}
1601 		}
1602 
1603 		if (((f->f3.i == 0 && f->f3.rs2 == 0) ||
1604 		    (f->f3.i == 1 && f->f3a.simm13 == 0)) &&
1605 		    (f->f3.rs1 == 0)) {
1606 			name = "clr";
1607 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1608 			break;
1609 		}
1610 
1611 		if (f->f3.rs1 == 0) {
1612 			name = "mov";
1613 			flags = FLG_P1(REG_NONE);
1614 			break;
1615 		}
1616 		break;
1617 
1618 	case 0x04:
1619 		/* sub */
1620 
1621 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1622 		    == 0)
1623 			break;
1624 
1625 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 == f->f3.rd) {
1626 			name = "neg";
1627 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE);
1628 			break;
1629 		}
1630 
1631 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 != f->f3.rd) {
1632 			name = "neg";
1633 			flags = FLG_P1(REG_NONE);
1634 			break;
1635 		}
1636 
1637 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
1638 			break;
1639 
1640 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1641 		    f->f3a.simm13 == 1) {
1642 			name = "dec";
1643 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1644 			break;
1645 		}
1646 
1647 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1648 		    f->f3a.simm13 != 1) {
1649 			name = "dec";
1650 			flags = FLG_P1(REG_NONE);
1651 			break;
1652 		}
1653 		break;
1654 
1655 	case 0x07:
1656 		/* xnor */
1657 
1658 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1659 		    == 0)
1660 			break;
1661 
1662 		/*
1663 		 * xnor -> not when you have:
1664 		 *	 xnor %rs1, 0x0 or %g0, %rd
1665 		 */
1666 		if ((f->f3.i == 0 && f->f3.rs2 != 0) ||
1667 		    (f->f3.i == 1 && f->f3a.simm13 != 0))
1668 			break;
1669 
1670 		name = "not";
1671 
1672 		if (f->f3.rs1 == f->f3.rd)
1673 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM|
1674 			    FLG_P3(REG_INT);
1675 		else
1676 			flags = FLG_P1(REG_INT)|FLG_P2(REG_NONE)|FLG_NOIMM|
1677 			    FLG_P3(REG_INT);
1678 
1679 		break;
1680 
1681 	case 0x10:
1682 		/* addcc */
1683 
1684 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
1685 			break;
1686 
1687 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1688 		    f->f3a.simm13 == 1) {
1689 			name = "inccc";
1690 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1691 			break;
1692 		}
1693 
1694 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1695 		    f->f3a.simm13 != 1) {
1696 			name = "inccc";
1697 			flags = FLG_P1(REG_NONE);
1698 			break;
1699 		}
1700 		break;
1701 
1702 	case 0x11:
1703 		/* andcc */
1704 
1705 		if (f->f3.rd != 0)
1706 			break;
1707 
1708 		if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
1709 		    == 0)
1710 			break;
1711 
1712 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0) &&
1713 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0))
1714 			break;
1715 
1716 		name = "btst";
1717 		flags = FLG_P1(REG_NONE);
1718 		f->f3.rd = f->f3.rs1;
1719 		break;
1720 
1721 	case 0x12:
1722 		/* orcc */
1723 
1724 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1725 		    == 0)
1726 			break;
1727 
1728 		if (f->f3.rs1 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
1729 			name = "tst";
1730 			flags = FLG_P1(REG_NONE)|FLG_P3(REG_NONE);
1731 			break;
1732 		}
1733 
1734 		if (f->f3.rs2 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
1735 			name = "tst";
1736 			flags = FLG_P2(REG_NONE)|FLG_P3(REG_NONE);
1737 			break;
1738 		}
1739 
1740 		break;
1741 
1742 	case 0x14:
1743 		/* subcc */
1744 
1745 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1746 		    == 0)
1747 			break;
1748 
1749 		if (f->f3.rd == 0) {
1750 			name = "cmp";
1751 			flags = FLG_P3(REG_NONE);
1752 			break;
1753 		}
1754 
1755 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
1756 			break;
1757 
1758 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1759 		    f->f3a.simm13 == 1) {
1760 			name = "deccc";
1761 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
1762 			break;
1763 		}
1764 
1765 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
1766 		    f->f3a.simm13 != 1) {
1767 			name = "deccc";
1768 			flags = FLG_P1(REG_NONE);
1769 			break;
1770 		}
1771 
1772 		break;
1773 
1774 	case 0x25:
1775 	case 0x26:
1776 	case 0x27:
1777 		return (prt_shift(dhp, instr, inp));
1778 
1779 	case 0x28:
1780 	case 0x29:
1781 	case 0x2a:
1782 	case 0x2b:
1783 	case 0x30:
1784 	case 0x31:
1785 	case 0x32:
1786 	case 0x33:
1787 		return (dis_fmt_rdwr(dhp, instr, inp, idx));
1788 
1789 	case 0x36:
1790 	case 0x37:
1791 		/* NOTE: overlayed on v9 */
1792 		if ((dhp->dh_flags & DIS_SPARC_V8) != 0)
1793 			return (fmt_cpop(dhp, instr, inp));
1794 		break;
1795 
1796 	case 0x38:
1797 		/* jmpl */
1798 		return (prt_jmpl(dhp, instr, inp, idx));
1799 
1800 	case 0x39:
1801 		/* rett / return */
1802 		prt_name(dhp, name, 1);
1803 		prt_address(dhp, instr, 1);
1804 		return (0);
1805 
1806 	case 0x3b:
1807 		/* flush */
1808 		prt_name(dhp, name, 1);
1809 		prt_address(dhp, instr, 0);
1810 		return (0);
1811 
1812 	case 0x3c:
1813 	case 0x3d:
1814 		/* save / restore */
1815 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
1816 		    == 0)
1817 			break;
1818 
1819 		if (f->f3.rs1 != 0 || f->f3.rs2 != 0 || f->f3.rd != 0)
1820 			break;
1821 
1822 		if (f->f3.i != 0 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0))
1823 			break;
1824 
1825 		prt_name(dhp, name, 0);
1826 		return (0);
1827 	}
1828 
1829 	if (FLG_P1_VAL(flags) != REG_NONE || FLG_P2_VAL(flags) != REG_NONE ||
1830 	    FLG_P3_VAL(flags) != REG_NONE)
1831 		arg = 1;
1832 
1833 	prt_name(dhp, name, (arg != 0));
1834 	prt_aluargs(dhp, instr, flags);
1835 
1836 	return (0);
1837 }
1838 
1839 /* ARGSUSED1 */
1840 int
1841 fmt_regwin(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1842 {
1843 	prt_name(dhp, inp->in_data.in_def.in_name, 0);
1844 	return (0);
1845 }
1846 
1847 /* ARGSUSED1 */
1848 int
1849 fmt_trap_ret(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1850 {
1851 	prt_name(dhp, inp->in_data.in_def.in_name, 0);
1852 	return (0);
1853 }
1854 
1855 /* ARGSUSED3 */
1856 int
1857 fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1858 {
1859 	ifmt_t *f = (ifmt_t *)&instr;
1860 	const char **regs = NULL;
1861 
1862 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
1863 		prt_field("op", f->f3c.op, 2);
1864 		prt_field("op3", f->f3c.op3, 6);
1865 		prt_field("cond", f->f3c.cond, 4);
1866 		prt_field("cc2", f->f3c.cc2, 1);
1867 		prt_field("cc", f->f3c.cc, 2);
1868 		prt_field("i", f->f3c.i, 1);
1869 
1870 		if (f->f3c.i == 0)
1871 			prt_field("rs2", f->f3.rs2, 5);
1872 		else
1873 			prt_field("simm11", f->f3c.simm11, 11);
1874 
1875 		prt_field("rd", f->f3.rd, 5);
1876 	}
1877 
1878 	if (f->f3c.cc2 == 0) {
1879 		regs = fcc_names;
1880 	} else {
1881 		regs = icc_names;
1882 		if (regs[f->f3c.cc] == NULL)
1883 			return (-1);
1884 	}
1885 
1886 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1887 
1888 	bprintf(dhp, "%s, ", regs[f->f3c.cc]);
1889 
1890 	if (f->f3c.i == 1)
1891 		prt_imm(dhp, sign_extend(f->f3c.simm11, 11), IMM_SIGNED);
1892 	else
1893 		(void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
1894 		    dhp->dh_buflen);
1895 
1896 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1897 
1898 	return (0);
1899 }
1900 
1901 /* ARGSUSED3 */
1902 int
1903 fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1904 {
1905 	ifmt_t *f = (ifmt_t *)&instr;
1906 
1907 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1908 
1909 	bprintf(dhp, "%s, ", reg_names[f->f3d.rs1]);
1910 
1911 	if (f->f3d.i == 1)
1912 		prt_imm(dhp, sign_extend(f->f3d.simm10, 10), IMM_SIGNED);
1913 	else
1914 		(void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
1915 		    dhp->dh_buflen);
1916 
1917 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
1918 
1919 	return (0);
1920 }
1921 
1922 /* ARGSUSED3 */
1923 int
1924 fmt_fpop1(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1925 {
1926 	ifmt_t *f = (ifmt_t *)&instr;
1927 	int flags = inp->in_data.in_def.in_flags;
1928 
1929 	flags |= FLG_NOIMM;
1930 
1931 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
1932 		prt_field("op", f->f3.op, 2);
1933 		prt_field("op3", f->f3.op3, 6);
1934 		prt_field("opf", f->fcmp.opf, 9);
1935 		prt_field("rs1", f->f3.rs1, 5);
1936 		prt_field("rs2", f->f3.rs2, 5);
1937 		prt_field("rd", f->f3.rd, 5);
1938 	}
1939 
1940 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
1941 	prt_aluargs(dhp, instr, flags);
1942 
1943 	return (0);
1944 }
1945 
1946 int
1947 fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
1948 {
1949 	static const char *condstr_icc[16] = {
1950 		"n", "e",  "le", "l",  "leu", "lu",  "neg", "vs",
1951 		"a", "nz", "g",  "ge", "gu",  "geu", "pos", "vc"
1952 	};
1953 
1954 	static const char *condstr_fcc[16] = {
1955 		"n", "nz", "lg", "ul", "l",   "ug", "g",   "u",
1956 		"a", "e",  "ue", "ge", "uge", "le", "ule", "o"
1957 	};
1958 
1959 	ifmt_t *f = (ifmt_t *)&instr;
1960 	const char *ccstr = "";
1961 	char name[15];
1962 
1963 	int flags = inp->in_data.in_def.in_flags;
1964 	int is_cmp = (idx == 0x51 || idx == 0x52 || idx == 0x53 ||
1965 	    idx == 0x55 || idx == 0x56 || idx == 0x57);
1966 	int is_fmov = (idx & 0x3f);
1967 	int is_v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
1968 	int is_compat = ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0);
1969 
1970 	int p_cc = 0;
1971 
1972 	is_fmov = (is_fmov == 0x1 || is_fmov == 0x2 || is_fmov == 0x3);
1973 
1974 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
1975 		prt_field("op", f->f3.op, 2);
1976 		prt_field("op3", f->f3.op3, 6);
1977 		prt_field("opf", f->fcmp.opf, 9);
1978 
1979 		switch (idx & 0x3f) {
1980 		case 0x51:
1981 		case 0x52:
1982 		case 0x53:
1983 		case 0x55:
1984 		case 0x56:
1985 		case 0x57:
1986 			prt_field("cc", f->fcmp.cc, 2);
1987 			prt_field("rs1", f->f3.rs1, 5);
1988 			prt_field("rs2", f->f3.rs2, 5);
1989 			break;
1990 
1991 		case 0x01:
1992 		case 0x02:
1993 		case 0x03:
1994 			prt_field("opf_low", f->fmv.opf, 6);
1995 			prt_field("cond", f->fmv.cond, 4);
1996 			prt_field("opf_cc", f->fmv.cc, 3);
1997 			prt_field("rs2", f->fmv.rs2, 5);
1998 			break;
1999 
2000 		default:
2001 			prt_field("rs1", f->f3.rs1, 5);
2002 			prt_field("rs2", f->f3.rs2, 5);
2003 			prt_field("rd", f->f3.rd, 5);
2004 		}
2005 	}
2006 
2007 	name[0] = '\0';
2008 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
2009 
2010 	if (is_fmov != 0) {
2011 		(void) strlcat(name,
2012 		    (f->fmv.cc < 4) ? condstr_fcc[f->fmv.cond]
2013 		    : condstr_icc[f->fmv.cond],
2014 		    sizeof (name));
2015 	}
2016 
2017 	prt_name(dhp, name, 1);
2018 
2019 	if (is_cmp != 0)
2020 		ccstr = fcc_names[f->fcmp.cc];
2021 
2022 	if (is_fmov != 0)
2023 		ccstr = (f->fmv.cc < 4) ? fcc_names[f->fmv.cc & 0x3]
2024 		    : icc_names[f->fmv.cc & 0x3];
2025 
2026 	if (ccstr == NULL)
2027 		return (-1);
2028 
2029 	p_cc = (is_compat == 0 || is_v9 != 0 ||
2030 	    (is_cmp != 0 && f->fcmp.cc != 0) ||
2031 	    (is_fmov != 0 && f->fmv.cc != 0));
2032 
2033 	if (p_cc != 0)
2034 		bprintf(dhp, "%s, ", ccstr);
2035 
2036 	prt_aluargs(dhp, instr, flags);
2037 
2038 	return (0);
2039 }
2040 
2041 int
2042 fmt_vis(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2043 {
2044 	ifmt_t *f = (ifmt_t *)&instr;
2045 	int flags = inp->in_data.in_def.in_flags;
2046 
2047 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
2048 		prt_field("op", f->f3.op, 2);
2049 		prt_field("op3", f->f3.op3, 6);
2050 		prt_field("opf", f->fcmp.opf, 9);
2051 
2052 		if (idx == 0x081) {
2053 			prt_field("mode", instr & 02L, 2);
2054 		} else {
2055 			prt_field("rs1", f->f3.rs1, 5);
2056 			prt_field("rs2", f->f3.rs2, 5);
2057 			prt_field("rd", f->f3.rd, 5);
2058 		}
2059 	}
2060 
2061 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
2062 
2063 	if (idx == 0x081) {
2064 		/* siam */
2065 		bprintf(dhp, "%d", instr & 0x7L);
2066 		return (0);
2067 	}
2068 
2069 	prt_aluargs(dhp, instr, flags);
2070 
2071 	return (0);
2072 }
2073 
2074 /* ARGSUSED3 */
2075 int
2076 fmt_fused(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
2077 {
2078 	ifmt_t *f = (ifmt_t *)&instr;
2079 	int flags = inp->in_data.in_def.in_flags;
2080 
2081 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
2082 	bprintf(dhp, "%s, %s, %s, %s",
2083 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs1),
2084 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs2),
2085 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs3),
2086 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rd));
2087 
2088 	return (0);
2089 }
2090 /*
2091  * put name into the output buffer
2092  * if add_space !=0, append a space after it
2093  */
2094 static void
2095 prt_name(dis_handle_t *dhp, const char *name, int add_space)
2096 {
2097 	bprintf(dhp, (add_space == 0) ? "%s" : "%-9s ", name);
2098 }
2099 
2100 /*
2101  * For debugging, print out a field of the instruction
2102  * field is the name of the field
2103  * val is the value of the field
2104  * len is the length of the field (in bits)
2105  */
2106 #if defined(DIS_STANDALONE)
2107 /* ARGSUSED */
2108 static void
2109 prt_field(const char *field, uint32_t val, int len)
2110 {
2111 
2112 }
2113 
2114 #else
2115 static void
2116 prt_field(const char *field, uint32_t val, int len)
2117 {
2118 	(void) fprintf(stderr, "DISASM: %8s = 0x%-8ulx (", field, val);
2119 	prt_binary(val, len);
2120 	(void) fprintf(stderr, ")\n");
2121 }
2122 #endif /* DIS_STANDALONE */
2123 
2124 /*
2125  * sign extend a val (that is 'bits' bits in length) to a 32-bit signed
2126  * integer
2127  */
2128 static int32_t
2129 sign_extend(int32_t val, int32_t bits)
2130 {
2131 	if ((val & (1L << (bits - 1))) == 0)
2132 		return (val);
2133 
2134 	return ((-1L << bits) | val);
2135 }
2136 
2137 /*
2138  * print out an immediate (i.e. constant) value
2139  * val is the value
2140  * format indicates if it is:
2141  * 0		 Unsigned
2142  * IMM_SIGNED  A signed value (prepend +/- to the value)
2143  * IMM_ADDR    Part of an address expression (prepend +/- but with a space
2144  *		   between the sign and the value for things like [%i1 + 0x55]
2145  */
2146 static void
2147 prt_imm(dis_handle_t *dhp, uint32_t val, int format)
2148 {
2149 	const char *fmtstr = NULL;
2150 	int32_t sv = (int32_t)val;
2151 	int octal = dhp->dh_flags & DIS_OCTAL;
2152 
2153 	switch (format) {
2154 	case IMM_ADDR:
2155 		if (sv < 0) {
2156 			sv = -sv;
2157 			fmtstr = (octal != 0) ? "- 0%lo" : "- 0x%lx";
2158 		} else {
2159 			fmtstr = (octal != 0) ? "+ 0%lo" : "+ 0x%lx";
2160 		}
2161 		break;
2162 
2163 	case IMM_SIGNED:
2164 		if (sv < 0) {
2165 			sv = -sv;
2166 			fmtstr = (octal != 0) ? "-0%lo" : "-0x%lx";
2167 			break;
2168 		}
2169 		/* fall through */
2170 
2171 	default:
2172 		fmtstr = (octal != 0) ? "0%lo" : "0x%lx";
2173 	}
2174 
2175 	bprintf(dhp, fmtstr, sv);
2176 }
2177 
2178 /*
2179  * return the symbolic name of a register
2180  * regset is one of the REG_* values indicating which type of register it is
2181  * such as integer, floating point, etc.
2182  * idx is the numeric value of the register
2183  *
2184  * If regset is REG_NONE, an empty, but non-NULL string is returned
2185  * NULL may be returned if the index indicates an invalid register value
2186  * such as with the %icc/%xcc sets
2187  */
2188 static const char *
2189 get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
2190 {
2191 	const char *regname = NULL;
2192 
2193 	switch (regset) {
2194 	case REG_INT:
2195 		regname = reg_names[idx];
2196 		break;
2197 
2198 	case REG_FP:
2199 		regname = freg_names[idx];
2200 		break;
2201 
2202 	case REG_FPD:
2203 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
2204 			regname = fdreg_names[idx];
2205 		else
2206 			regname = compat_fdreg_names[idx];
2207 
2208 		break;
2209 
2210 	case REG_FPQ:
2211 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
2212 			regname = fqreg_names[idx];
2213 		else
2214 			regname = freg_names[idx];
2215 
2216 		break;
2217 
2218 	case REG_CP:
2219 		regname = cpreg_names[idx];
2220 		break;
2221 
2222 	case REG_ICC:
2223 		regname = icc_names[idx];
2224 		break;
2225 
2226 	case REG_FCC:
2227 		regname = fcc_names[idx];
2228 		break;
2229 
2230 	case REG_FSR:
2231 		regname = "%fsr";
2232 		break;
2233 
2234 	case REG_CSR:
2235 		regname = "%csr";
2236 		break;
2237 
2238 	case REG_CQ:
2239 		regname = "%cq";
2240 		break;
2241 
2242 	case REG_NONE:
2243 		regname = "";
2244 		break;
2245 	}
2246 
2247 	return (regname);
2248 }
2249 
2250 /*
2251  * output the asi value from the instruction
2252  *
2253  * TODO: investigate if this should perhaps have a mask -- are undefined ASI
2254  *	  values for an instruction still disassembled??
2255  */
2256 static void
2257 prt_asi(dis_handle_t *dhp, uint32_t instr)
2258 {
2259 	ifmt_t *f = (ifmt_t *)&instr;
2260 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
2261 
2262 	if (f->f3.i != 0)
2263 		bprintf(dhp, "%%asi");
2264 	else
2265 		bprintf(dhp, (octal != 0) ? "0%03o" : "0x%02x", f->f3.asi);
2266 
2267 }
2268 
2269 /*
2270  * put an address expression into the output buffer
2271  *
2272  * instr is the instruction to use
2273  * if nobrackets != 0, [] are not added around the instruction
2274  *
2275  * Currently this option is set when printing out the address portion
2276  * of a jmpl instruction, but otherwise 0 for load/stores
2277  *
2278  * If no debug flags are set, the full expression is output, even when
2279  * %g0 or 0x0 appears in the address
2280  *
2281  * If DIS_DEBUG_SYN_ALL or DIS_DEBUG_COMPAT are set, when %g0 or 0x0
2282  * appear in the address, they are not output.  If the wierd (and probably
2283  * shouldn't happen) address of [%g0 + %g0] or [%g0 + 0x0] is encountered,
2284  * [%g0] is output
2285  */
2286 static void
2287 prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
2288 {
2289 	ifmt_t *f = (ifmt_t *)&instr;
2290 	int32_t simm13;
2291 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
2292 	int p1 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
2293 	int p2 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
2294 
2295 	if (f->f3a.i == 0) {
2296 		p1 |= ((f->f3a.rs1 != 0) || f->f3.rs2 == 0);
2297 		p2 |= (f->f3.rs2 != 0);
2298 
2299 		bprintf(dhp, "%s%s%s%s%s",
2300 		    (nobrackets == 0) ? "[" : "",
2301 		    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
2302 		    (p1 != 0 && p2 != 0) ? " + " : "",
2303 		    (p2 != 0) ? reg_names[f->f3.rs2] : "",
2304 		    (nobrackets == 0) ? "]" : "");
2305 	} else {
2306 		const char *sign;
2307 
2308 		simm13 = sign_extend(f->f3a.simm13, 13);
2309 		sign = (simm13 < 0) ? "-" : "+";
2310 
2311 		p1 |= (f->f3a.rs1 != 0);
2312 		p2 |= (p1 == 0 || simm13 != 0);
2313 
2314 		if (p1 == 0 && simm13 == 0)
2315 			p2 = 1;
2316 
2317 		if (p1 == 0 && simm13 >= 0)
2318 			sign = "";
2319 
2320 		if (p2 != 0)
2321 			bprintf(dhp,
2322 			    (octal != 0) ? "%s%s%s%s%s0%lo%s" :
2323 			    "%s%s%s%s%s0x%lx%s",
2324 			    (nobrackets == 0) ? "[" : "",
2325 			    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
2326 			    (p1 != 0) ? " " : "",
2327 			    sign,
2328 			    (p1 != 0) ? " " : "",
2329 			    (simm13 < 0) ? -(simm13) : simm13,
2330 			    (nobrackets == 0) ? "]" : "");
2331 		else
2332 			bprintf(dhp, "%s%s%s",
2333 			    (nobrackets == 0) ? "[" : "",
2334 			    reg_names[f->f3a.rs1],
2335 			    (nobrackets == 0) ? "]" : "");
2336 	}
2337 }
2338 
2339 /*
2340  * print out the arguments to an alu operation (add, sub, etc.)
2341  * conatined in 'instr'
2342  *
2343  * alu instructions have the following format:
2344  *	 %rs1, %rs2, %rd    (i == 0)
2345  *	 %rs1, 0xnnn, %rd   (i == 1)
2346  *	   ^	^	^
2347  *	   |	|	|
2348  *	  p1    p2	p3
2349  *
2350  * flags indicates the register set to use for each position (p1, p2, p3)
2351  * as well as if immediate values (i == 1) are allowed
2352  *
2353  * if flags indicates a specific position has REG_NONE set as it's register
2354  * set, it is omitted from the output.  This is primarly used for certain
2355  * floating point operations
2356  */
2357 static void
2358 prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
2359 {
2360 	ifmt_t *f = (ifmt_t *)&instr;
2361 	const char *r1, *r2, *r3;
2362 	int p1, p2, p3;
2363 
2364 	r1 = get_regname(dhp, FLG_P1_VAL(flags), f->f3.rs1);
2365 	r2 = get_regname(dhp, FLG_P2_VAL(flags), f->f3.rs2);
2366 	r3 = get_regname(dhp, FLG_P3_VAL(flags), f->f3.rd);
2367 
2368 	p1 = (FLG_P1_VAL(flags) != REG_NONE);
2369 	p2 = (((flags & FLG_NOIMM) == 0) || (FLG_P2_VAL(flags) != REG_NONE));
2370 	p3 = (FLG_RD_VAL(flags) != REG_NONE);
2371 
2372 	if (r1 == NULL || r1[0] == '\0')
2373 		p1 = 0;
2374 
2375 	if (f->f3a.i == 0 && (r2 == NULL || r2[0] == '\0'))
2376 		p2 = 0;
2377 
2378 	if (r3 == NULL || r3[0] == '\0')
2379 		p3 = 0;
2380 
2381 	if (p1 != 0) {
2382 		(void) strlcat(dhp->dh_buf, r1, dhp->dh_buflen);
2383 		if (p2 != 0 || p3 != 0)
2384 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
2385 	}
2386 
2387 	if (p2 != 0) {
2388 		if (f->f3.i == 0 || ((flags & FLG_NOIMM) != 0))
2389 			(void) strlcat(dhp->dh_buf, r2, dhp->dh_buflen);
2390 		else
2391 			prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
2392 			    IMM_SIGNED);
2393 
2394 		if (p3 != 0)
2395 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
2396 	}
2397 
2398 	if (p3 != 0)
2399 		(void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
2400 }
2401 
2402 /*
2403  * just a handy function that takes care of managing the buffer length
2404  * w/ printf
2405  */
2406 
2407 /*
2408  * PRINTF LIKE 1
2409  */
2410 static void
2411 bprintf(dis_handle_t *dhp, const char *fmt, ...)
2412 {
2413 	size_t curlen;
2414 	va_list ap;
2415 
2416 	curlen = strlen(dhp->dh_buf);
2417 
2418 	va_start(ap, fmt);
2419 	(void) vsnprintf(dhp->dh_buf + curlen, dhp->dh_buflen - curlen, fmt,
2420 	    ap);
2421 	va_end(ap);
2422 }
2423