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