xref: /onnv-gate/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c (revision 10271:7c80b70bb8de)
15198Sjmcp /*
25198Sjmcp  * CDDL HEADER START
35198Sjmcp  *
45198Sjmcp  * The contents of this file are subject to the terms of the
55198Sjmcp  * Common Development and Distribution License (the "License").
65198Sjmcp  * You may not use this file except in compliance with the License.
75198Sjmcp  *
85198Sjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95198Sjmcp  * or http://www.opensolaris.org/os/licensing.
105198Sjmcp  * See the License for the specific language governing permissions
115198Sjmcp  * and limitations under the License.
125198Sjmcp  *
135198Sjmcp  * When distributing Covered Code, include this CDDL HEADER in each
145198Sjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155198Sjmcp  * If applicable, add the following below this CDDL HEADER, with the
165198Sjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
175198Sjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
185198Sjmcp  *
195198Sjmcp  * CDDL HEADER END
205198Sjmcp  */
215198Sjmcp 
225198Sjmcp /*
23*10271SJason.Beloro@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245198Sjmcp  * Use is subject to license terms.
255198Sjmcp  */
265198Sjmcp 
275198Sjmcp /*
28*10271SJason.Beloro@Sun.COM  * Copyright 2009 Jason King.  All rights reserved.
295198Sjmcp  * Use is subject to license terms.
305198Sjmcp  */
315198Sjmcp 
325198Sjmcp 
335198Sjmcp #include <sys/byteorder.h>
345198Sjmcp #include <stdarg.h>
355198Sjmcp 
365198Sjmcp #if !defined(DIS_STANDALONE)
375198Sjmcp #include <stdio.h>
385198Sjmcp #endif /* DIS_STANDALONE */
395198Sjmcp 
405198Sjmcp #include "libdisasm.h"
415198Sjmcp #include "libdisasm_impl.h"
425198Sjmcp #include "dis_sparc.h"
435198Sjmcp #include "dis_sparc_fmt.h"
445198Sjmcp 
455198Sjmcp extern char *strncpy(char *, const char *, size_t);
465198Sjmcp extern size_t strlen(const char *);
475198Sjmcp extern int strcmp(const char *, const char *);
485198Sjmcp extern int strncmp(const char *, const char *, size_t);
495198Sjmcp extern size_t strlcat(char *, const char *, size_t);
505198Sjmcp extern size_t strlcpy(char *, const char *, size_t);
515198Sjmcp extern int snprintf(char *, size_t, const char *, ...);
525198Sjmcp extern int vsnprintf(char *, size_t, const char *, va_list);
535198Sjmcp 
545198Sjmcp /*
555198Sjmcp  * This file has the functions that do all the dirty work of outputting the
565198Sjmcp  * disassembled instruction
575198Sjmcp  *
585198Sjmcp  * All the non-static functions follow the format_fcn (in dis_sparc.h):
595198Sjmcp  * Input:
605198Sjmcp  *	disassembler handle/context
615198Sjmcp  *	instruction to disassemble
625198Sjmcp  *	instruction definition pointer (inst_t *)
635198Sjmcp  *	index in the table of the instruction
645198Sjmcp  * Return:
655198Sjmcp  *	0 Success
665198Sjmcp  *    !0 Invalid instruction
675198Sjmcp  *
685198Sjmcp  * Generally, instructions found in the same table use the same output format
695198Sjmcp  * or have a few minor differences (which are described in the 'flags' field
705198Sjmcp  * of the instruction definition. In some cases, certain instructions differ
715198Sjmcp  * radically enough from those in the same table, that their own format
725198Sjmcp  * function is used.
735198Sjmcp  *
745198Sjmcp  * Typically each table has a unique format function defined in this file.  In
755198Sjmcp  * some cases (such as branches) a common one for all the tables is used.
765198Sjmcp  *
775198Sjmcp  * When adding support for new instructions, it is largely a judgement call
785198Sjmcp  * as to when a new format function is defined.
795198Sjmcp  */
805198Sjmcp 
815198Sjmcp /* The various instruction formats of a sparc instruction */
825198Sjmcp 
835198Sjmcp #if defined(_BIT_FIELDS_HTOL)
845198Sjmcp typedef struct format1 {
855198Sjmcp 	uint32_t op:2;
865198Sjmcp 	uint32_t disp30:30;
875198Sjmcp } format1_t;
885198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
895198Sjmcp typedef struct format1 {
905198Sjmcp 	uint32_t disp30:30;
915198Sjmcp 	uint32_t op:2;
925198Sjmcp } format1_t;
935198Sjmcp #else
945198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
955198Sjmcp #endif
965198Sjmcp 
975198Sjmcp #if defined(_BIT_FIELDS_HTOL)
985198Sjmcp typedef struct format2 {
995198Sjmcp 	uint32_t op:2;
1005198Sjmcp 	uint32_t rd:5;
1015198Sjmcp 	uint32_t op2:3;
1025198Sjmcp 	uint32_t imm22:22;
1035198Sjmcp } format2_t;
1045198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
1055198Sjmcp typedef struct format2 {
1065198Sjmcp 	uint32_t imm22:22;
1075198Sjmcp 	uint32_t op2:3;
1085198Sjmcp 	uint32_t rd:5;
1095198Sjmcp 	uint32_t op:2;
1105198Sjmcp } format2_t;
1115198Sjmcp #else
1125198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
1135198Sjmcp #endif
1145198Sjmcp 
1155198Sjmcp #if defined(_BIT_FIELDS_HTOL)
1165198Sjmcp typedef struct format2a {
1175198Sjmcp 	uint32_t op:2;
1185198Sjmcp 	uint32_t a:1;
1195198Sjmcp 	uint32_t cond:4;
1205198Sjmcp 	uint32_t op2:3;
1215198Sjmcp 	uint32_t disp22:22;
1225198Sjmcp } format2a_t;
1235198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
1245198Sjmcp typedef struct format2a {
1255198Sjmcp 	uint32_t disp22:22;
1265198Sjmcp 	uint32_t op2:3;
1275198Sjmcp 	uint32_t cond:4;
1285198Sjmcp 	uint32_t a:1;
1295198Sjmcp 	uint32_t op:2;
1305198Sjmcp } format2a_t;
1315198Sjmcp #else
1325198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
1335198Sjmcp #endif
1345198Sjmcp 
1355198Sjmcp #if defined(_BIT_FIELDS_HTOL)
1365198Sjmcp typedef struct format2b {
1375198Sjmcp 	uint32_t op:2;
1385198Sjmcp 	uint32_t a:1;
1395198Sjmcp 	uint32_t cond:4;
1405198Sjmcp 	uint32_t op2:3;
1415198Sjmcp 	uint32_t cc:2;
1425198Sjmcp 	uint32_t p:1;
1435198Sjmcp 	uint32_t disp19:19;
1445198Sjmcp } format2b_t;
1455198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
1465198Sjmcp typedef struct format2b {
1475198Sjmcp 	uint32_t disp19:19;
1485198Sjmcp 	uint32_t p:1;
1495198Sjmcp 	uint32_t cc:2;
1505198Sjmcp 	uint32_t op2:3;
1515198Sjmcp 	uint32_t cond:4;
1525198Sjmcp 	uint32_t a:1;
1535198Sjmcp 	uint32_t op:2;
1545198Sjmcp } format2b_t;
1555198Sjmcp #else
1565198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
1575198Sjmcp #endif
1585198Sjmcp 
1595198Sjmcp #if defined(_BIT_FIELDS_HTOL)
1605198Sjmcp typedef struct format2c {
1615198Sjmcp 	uint32_t op:2;
1625198Sjmcp 	uint32_t a:1;
1635198Sjmcp 	uint32_t cond:4;
1645198Sjmcp 	uint32_t op2:3;
1655198Sjmcp 	uint32_t d16hi:2;
1665198Sjmcp 	uint32_t p:1;
1675198Sjmcp 	uint32_t rs1:5;
1685198Sjmcp 	uint32_t d16lo:14;
1695198Sjmcp } format2c_t;
1705198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
1715198Sjmcp typedef struct format2c {
1725198Sjmcp 	uint32_t d16lo:14;
1735198Sjmcp 	uint32_t rs1:5;
1745198Sjmcp 	uint32_t p:1;
1755198Sjmcp 	uint32_t d16hi:2;
1765198Sjmcp 	uint32_t op2:3;
1775198Sjmcp 	uint32_t cond:4;
1785198Sjmcp 	uint32_t a:1;
1795198Sjmcp 	uint32_t op:2;
1805198Sjmcp } format2c_t;
1815198Sjmcp #else
1825198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
1835198Sjmcp #endif
1845198Sjmcp 
1855198Sjmcp #if defined(_BIT_FIELDS_HTOL)
1865198Sjmcp typedef struct format3 {
1875198Sjmcp 	uint32_t op:2;
1885198Sjmcp 	uint32_t rd:5;
1895198Sjmcp 	uint32_t op3:6;
1905198Sjmcp 	uint32_t rs1:5;
1915198Sjmcp 	uint32_t i:1;
1925198Sjmcp 	uint32_t asi:8;
1935198Sjmcp 	uint32_t rs2:5;
1945198Sjmcp } format3_t;
1955198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
1965198Sjmcp typedef struct format3 {
1975198Sjmcp 	uint32_t rs2:5;
1985198Sjmcp 	uint32_t asi:8;
1995198Sjmcp 	uint32_t i:1;
2005198Sjmcp 	uint32_t rs1:5;
2015198Sjmcp 	uint32_t op3:6;
2025198Sjmcp 	uint32_t rd:5;
2035198Sjmcp 	uint32_t op:2;
2045198Sjmcp } format3_t;
2055198Sjmcp #else
2065198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
2075198Sjmcp #endif
2085198Sjmcp 
2095198Sjmcp #if defined(_BIT_FIELDS_HTOL)
2105198Sjmcp typedef struct format3a {
2115198Sjmcp 	uint32_t op:2;
2125198Sjmcp 	uint32_t rd:5;
2135198Sjmcp 	uint32_t op3:6;
2145198Sjmcp 	uint32_t rs1:5;
2155198Sjmcp 	uint32_t i:1;
2165198Sjmcp 	uint32_t simm13:13;
2175198Sjmcp } format3a_t;
2185198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
2195198Sjmcp typedef struct format3a {
2205198Sjmcp 	uint32_t simm13:13;
2215198Sjmcp 	uint32_t i:1;
2225198Sjmcp 	uint32_t rs1:5;
2235198Sjmcp 	uint32_t op3:6;
2245198Sjmcp 	uint32_t rd:5;
2255198Sjmcp 	uint32_t op:2;
2265198Sjmcp } format3a_t;
2275198Sjmcp #else
2285198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
2295198Sjmcp #endif
2305198Sjmcp 
2315198Sjmcp #if defined(_BIT_FIELDS_HTOL)
2325198Sjmcp typedef struct format3b {
2335198Sjmcp 	uint32_t op:2;
2345198Sjmcp 	uint32_t rd:5;
2355198Sjmcp 	uint32_t op3:6;
2365198Sjmcp 	uint32_t rs1:5;
2375198Sjmcp 	uint32_t i:1;
2385198Sjmcp 	uint32_t x:1;
2395198Sjmcp 	uint32_t undef:6;
2405198Sjmcp 	uint32_t shcnt:6;
2415198Sjmcp } format3b_t;
2425198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
2435198Sjmcp typedef struct format3b {
2445198Sjmcp 	uint32_t shcnt:6;
2455198Sjmcp 	uint32_t undef:6;
2465198Sjmcp 	uint32_t x:1;
2475198Sjmcp 	uint32_t i:1;
2485198Sjmcp 	uint32_t rs1:5;
2495198Sjmcp 	uint32_t op3:6;
2505198Sjmcp 	uint32_t rd:5;
2515198Sjmcp 	uint32_t op:2;
2525198Sjmcp } format3b_t;
2535198Sjmcp #else
2545198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
2555198Sjmcp #endif
2565198Sjmcp 
2575198Sjmcp #if defined(_BIT_FIELDS_HTOL)
2585198Sjmcp typedef struct format3c {
2595198Sjmcp 	uint32_t op:2;
2605198Sjmcp 	uint32_t rd:5;
2615198Sjmcp 	uint32_t op3:6;
2625198Sjmcp 	uint32_t cc2:1;
2635198Sjmcp 	uint32_t cond:4;
2645198Sjmcp 	uint32_t i:1;
2655198Sjmcp 	uint32_t cc:2;
2665198Sjmcp 	uint32_t simm11:11;
2675198Sjmcp } format3c_t;
2685198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
2695198Sjmcp typedef struct format3c {
2705198Sjmcp 	uint32_t simm11:11;
2715198Sjmcp 	uint32_t cc:2;
2725198Sjmcp 	uint32_t i:1;
2735198Sjmcp 	uint32_t cond:4;
2745198Sjmcp 	uint32_t cc2:1;
2755198Sjmcp 	uint32_t op3:6;
2765198Sjmcp 	uint32_t rd:5;
2775198Sjmcp 	uint32_t op:2;
2785198Sjmcp } format3c_t;
2795198Sjmcp #else
2805198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
2815198Sjmcp #endif
2825198Sjmcp 
2835198Sjmcp #if defined(_BIT_FIELDS_HTOL)
2845198Sjmcp typedef struct format3d {
2855198Sjmcp 	uint32_t op:2;
2865198Sjmcp 	uint32_t rd:5;
2875198Sjmcp 	uint32_t op3:6;
2885198Sjmcp 	uint32_t rs1:5;
2895198Sjmcp 	uint32_t i:1;
2905198Sjmcp 	uint32_t rcond:3;
2915198Sjmcp 	uint32_t simm10:10;
2925198Sjmcp } format3d_t;
2935198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
2945198Sjmcp typedef struct format3d {
2955198Sjmcp 	uint32_t simm10:10;
2965198Sjmcp 	uint32_t rcond:3;
2975198Sjmcp 	uint32_t i:1;
2985198Sjmcp 	uint32_t rs1:5;
2995198Sjmcp 	uint32_t op3:6;
3005198Sjmcp 	uint32_t rd:5;
3015198Sjmcp 	uint32_t op:2;
3025198Sjmcp } format3d_t;
3035198Sjmcp #else
3045198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
3055198Sjmcp #endif
3065198Sjmcp 
3075198Sjmcp #if defined(_BIT_FIELDS_HTOL)
3085198Sjmcp typedef struct formatcp {
3095198Sjmcp 	uint32_t op:2;
3105198Sjmcp 	uint32_t rd:5;
3115198Sjmcp 	uint32_t op3:6;
3125198Sjmcp 	uint32_t rs1:5;
3135198Sjmcp 	uint32_t opc:9;
3145198Sjmcp 	uint32_t rs2:5;
3155198Sjmcp } formatcp_t;
3165198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
3175198Sjmcp typedef struct formatcp {
3185198Sjmcp 	uint32_t rs2:5;
3195198Sjmcp 	uint32_t opc:9;
3205198Sjmcp 	uint32_t rs1:5;
3215198Sjmcp 	uint32_t op3:6;
3225198Sjmcp 	uint32_t rd:5;
3235198Sjmcp 	uint32_t op:2;
3245198Sjmcp } formatcp_t;
3255198Sjmcp #else
3265198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
3275198Sjmcp #endif
3285198Sjmcp 
3295198Sjmcp #if defined(_BIT_FIELDS_HTOL)
3305198Sjmcp typedef struct formattcc {
3315198Sjmcp 	uint32_t op:2;
3325198Sjmcp 	uint32_t undef:1;
3335198Sjmcp 	uint32_t cond:4;
3345198Sjmcp 	uint32_t op3:6;
3355198Sjmcp 	uint32_t rs1:5;
3365198Sjmcp 	uint32_t i:1;
3375198Sjmcp 	uint32_t cc:2;
3385198Sjmcp 	uint32_t undef2:3;
3395198Sjmcp 	uint32_t immtrap:8;
3405198Sjmcp } formattcc_t;
3415198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
3425198Sjmcp typedef struct formattcc {
3435198Sjmcp 	uint32_t immtrap:8;
3445198Sjmcp 	uint32_t undef2:3;
3455198Sjmcp 	uint32_t cc:2;
3465198Sjmcp 	uint32_t i:1;
3475198Sjmcp 	uint32_t rs1:5;
3485198Sjmcp 	uint32_t op3:6;
3495198Sjmcp 	uint32_t cond:4;
3505198Sjmcp 	uint32_t undef:1;
3515198Sjmcp 	uint32_t op:2;
3525198Sjmcp } formattcc_t;
3535198Sjmcp #else
3545198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
3555198Sjmcp #endif
3565198Sjmcp 
3575198Sjmcp #if defined(_BIT_FIELDS_HTOL)
3585198Sjmcp typedef struct formattcc2 {
3595198Sjmcp 	uint32_t op:2;
3605198Sjmcp 	uint32_t undef:1;
3615198Sjmcp 	uint32_t cond:4;
3625198Sjmcp 	uint32_t op3:6;
3635198Sjmcp 	uint32_t rs1:5;
3645198Sjmcp 	uint32_t i:1;
3655198Sjmcp 	uint32_t cc:2;
3665198Sjmcp 	uint32_t undef2:6;
3675198Sjmcp 	uint32_t rs2:5;
3685198Sjmcp } formattcc2_t;
3695198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
3705198Sjmcp typedef struct formattcc2 {
3715198Sjmcp 	uint32_t rs2:5;
3725198Sjmcp 	uint32_t undef2:6;
3735198Sjmcp 	uint32_t cc:2;
3745198Sjmcp 	uint32_t i:1;
3755198Sjmcp 	uint32_t rs1:5;
3765198Sjmcp 	uint32_t op3:6;
3775198Sjmcp 	uint32_t cond:4;
3785198Sjmcp 	uint32_t undef:1;
3795198Sjmcp 	uint32_t op:2;
3805198Sjmcp } formattcc2_t;
3815198Sjmcp #else
3825198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
3835198Sjmcp #endif
3845198Sjmcp 
3855198Sjmcp #if defined(_BIT_FIELDS_HTOL)
3865198Sjmcp typedef struct formatmbr {
3875198Sjmcp 	uint32_t op:2;
3885198Sjmcp 	uint32_t rd:5;
3895198Sjmcp 	uint32_t op3:6;
3905198Sjmcp 	uint32_t rs1:5;
3915198Sjmcp 	uint32_t i:1;
392*10271SJason.Beloro@Sun.COM 	uint32_t undef:6;
393*10271SJason.Beloro@Sun.COM 	uint32_t cmask:3;
3945198Sjmcp 	uint32_t mmask:4;
3955198Sjmcp } formatmbr_t;
3965198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
3975198Sjmcp typedef struct formatmbr {
3985198Sjmcp 	uint32_t mmask:4;
399*10271SJason.Beloro@Sun.COM 	uint32_t cmask:3;
400*10271SJason.Beloro@Sun.COM 	uint32_t undef:6;
4015198Sjmcp 	uint32_t i:1;
4025198Sjmcp 	uint32_t rs1:5;
4035198Sjmcp 	uint32_t op3:6;
4045198Sjmcp 	uint32_t rd:5;
4055198Sjmcp 	uint32_t op:2;
4065198Sjmcp } formatmbr_t;
4075198Sjmcp #else
4085198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
4095198Sjmcp #endif
4105198Sjmcp 
4115198Sjmcp #if defined(_BIT_FIELDS_HTOL)
4125198Sjmcp typedef struct formatfcmp {
4135198Sjmcp 	uint32_t op:2;
4145198Sjmcp 	uint32_t undef:3;
4155198Sjmcp 	uint32_t cc:2;
4165198Sjmcp 	uint32_t op3:6;
4175198Sjmcp 	uint32_t rs1:5;
4185198Sjmcp 	uint32_t opf:9;
4195198Sjmcp 	uint32_t rs2:5;
4205198Sjmcp } formatfcmp_t;
4215198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
4225198Sjmcp typedef struct formatfcmp {
4235198Sjmcp 	uint32_t rs2:5;
4245198Sjmcp 	uint32_t opf:9;
4255198Sjmcp 	uint32_t rs1:5;
4265198Sjmcp 	uint32_t op3:6;
4275198Sjmcp 	uint32_t cc:2;
4285198Sjmcp 	uint32_t undef:3;
4295198Sjmcp 	uint32_t op:2;
4305198Sjmcp } formatfcmp_t;
4315198Sjmcp #else
4325198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
4335198Sjmcp #endif
4345198Sjmcp 
4355198Sjmcp #if defined(_BIT_FIELDS_HTOL)
4365198Sjmcp typedef struct formatfmov {
4375198Sjmcp 	uint32_t op:2;
4385198Sjmcp 	uint32_t rd:5;
4395198Sjmcp 	uint32_t op3:6;
4405198Sjmcp 	uint32_t undef:1;
4415198Sjmcp 	uint32_t cond:4;
4425198Sjmcp 	uint32_t cc:3;
4435198Sjmcp 	uint32_t opf:6;
4445198Sjmcp 	uint32_t rs2:5;
4455198Sjmcp } formatfmov_t;
4465198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
4475198Sjmcp typedef struct formatfmov {
4485198Sjmcp 	uint32_t rs2:5;
4495198Sjmcp 	uint32_t opf:6;
4505198Sjmcp 	uint32_t cc:3;
4515198Sjmcp 	uint32_t cond:4;
4525198Sjmcp 	uint32_t undef:1;
4535198Sjmcp 	uint32_t op3:6;
4545198Sjmcp 	uint32_t rd:5;
4555198Sjmcp 	uint32_t op:2;
4565198Sjmcp } formatfmov_t;
4575198Sjmcp #else
4585198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
4595198Sjmcp #endif
4605198Sjmcp 
4615198Sjmcp #if defined(_BIT_FIELDS_HTOL)
4625198Sjmcp typedef struct formatfused {
4635198Sjmcp 	uint32_t op:2;
4645198Sjmcp 	uint32_t rd:5;
4655198Sjmcp 	uint32_t op3:6;
4665198Sjmcp 	uint32_t rs1:5;
4675198Sjmcp 	uint32_t rs3:5;
4685198Sjmcp 	uint32_t op5:4;
4695198Sjmcp 	uint32_t rs2:5;
4705198Sjmcp } formatfused_t;
4715198Sjmcp #elif defined(_BIT_FIELDS_LTOH)
4725198Sjmcp typedef struct formatfused {
4735198Sjmcp 	uint32_t rs2:5;
4745198Sjmcp 	uint32_t op5:4;
4755198Sjmcp 	uint32_t rs3:5;
4765198Sjmcp 	uint32_t rs1:5;
4775198Sjmcp 	uint32_t op3:6;
4785198Sjmcp 	uint32_t rd:5;
4795198Sjmcp 	uint32_t op:2;
4805198Sjmcp } formatfused_t;
4815198Sjmcp #else
4825198Sjmcp #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
4835198Sjmcp #endif
4845198Sjmcp 
4855198Sjmcp typedef union ifmt {
4865198Sjmcp 	uint32_t	i;
4875198Sjmcp 	format1_t	f1;
4885198Sjmcp 	format2_t	f2;
4895198Sjmcp 	format2a_t	f2a;
4905198Sjmcp 	format2b_t	f2b;
4915198Sjmcp 	format2c_t	f2c;
4925198Sjmcp 	format3_t	f3;
4935198Sjmcp 	format3a_t	f3a;
4945198Sjmcp 	format3b_t	f3b;
4955198Sjmcp 	format3c_t	f3c;
4965198Sjmcp 	format3d_t	f3d;
4975198Sjmcp 	formatcp_t	fcp;
4985198Sjmcp 	formattcc_t	ftcc;
4995198Sjmcp 	formattcc2_t	ftcc2;
5005198Sjmcp 	formatfcmp_t	fcmp;
5015198Sjmcp 	formatmbr_t	fmb;
5025198Sjmcp 	formatfmov_t	fmv;
5035198Sjmcp 	formatfused_t	fused;
5045198Sjmcp } ifmt_t;
5055198Sjmcp 
5065198Sjmcp /* integer register names */
5075198Sjmcp static const char *reg_names[32] = {
5085198Sjmcp 	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
5095198Sjmcp 	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
5105198Sjmcp 	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
5115198Sjmcp 	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7"
5125198Sjmcp };
5135198Sjmcp 
5145198Sjmcp /* floating point register names */
5155198Sjmcp static const char *freg_names[32] = {
5165198Sjmcp 	"%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
5175198Sjmcp 	"%f8",  "%f9",  "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
5185198Sjmcp 	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
5195198Sjmcp 	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
5205198Sjmcp };
5215198Sjmcp 
5225198Sjmcp /* double precision register names */
5235198Sjmcp static const char *fdreg_names[32] = {
5245198Sjmcp 	"%d0",  "%d32", "%d2",  "%d34", "%d4",  "%d36", "%d6",  "%d38",
5255198Sjmcp 	"%d8",  "%d40", "%d10", "%d42", "%d12", "%d44", "%d14", "%d46",
5265198Sjmcp 	"%d16", "%d48", "%d18", "%d50", "%d20", "%d52", "%d22", "%d54",
5275198Sjmcp 	"%d24", "%d56", "%d26", "%d58", "%d28", "%d60", "%d30", "%d62"
5285198Sjmcp };
5295198Sjmcp 
5305198Sjmcp static const char *compat_fdreg_names[32] = {
5315198Sjmcp 	"%f0",  "%f32", "%f2",  "%f34", "%f4",  "%f36", "%f6",  "%f38",
5325198Sjmcp 	"%f8",  "%f40", "%f10", "%f42", "%f12", "%f44", "%f14", "%f46",
5335198Sjmcp 	"%f16", "%f48", "%f18", "%f50", "%f20", "%f52", "%f22", "%f54",
5345198Sjmcp 	"%f24", "%f56", "%f26", "%f58", "%f28", "%f60", "%f30", "%f62"
5355198Sjmcp };
5365198Sjmcp 
5375198Sjmcp 
5385198Sjmcp static const char *fqreg_names[32] = {
5395198Sjmcp 	"%q0",  "%q32", "%f2",  "%f3",  "%f4",  "%q4",  "%q36", "%f6",
5405198Sjmcp 	"%f7",  "%q8",  "%q40", "%f10", "%f11", "%q12", "%q44", "%f14",
5415198Sjmcp 	"%f15", "%q16", "%q48", "%f18", "%f19", "%q20", "%q52", "%f22",
5425198Sjmcp 	"%f23", "%q24", "%q56", "%f26", "%f27", "%q28", "%q60", "%f30",
5435198Sjmcp };
5445198Sjmcp 
5455198Sjmcp 
5465198Sjmcp /* coprocessor register names -- sparcv8 only */
5475198Sjmcp static const char *cpreg_names[32] = {
5485198Sjmcp 	"%c0",  "%c1",  "%c2",  "%c3",  "%c4",  "%c5",  "%c6",  "%c7",
5495198Sjmcp 	"%c8",  "%c9",  "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
5505198Sjmcp 	"%c16", "%c17", "%c18", "%c19", "%c20", "%c21", "%c22", "%c23",
5515198Sjmcp 	"%c24", "%c25", "%c26", "%c27", "%c28", "%c29", "%c30", "%c31",
5525198Sjmcp };
5535198Sjmcp 
5545198Sjmcp /* floating point condition code names */
5555198Sjmcp static const char *fcc_names[4] = {
5565198Sjmcp 	"%fcc0", "%fcc1", "%fcc2", "%fcc3"
5575198Sjmcp };
5585198Sjmcp 
5595198Sjmcp /* condition code names */
5605198Sjmcp static const char *icc_names[4] = {
5615198Sjmcp 	"%icc", NULL, "%xcc", NULL
5625198Sjmcp };
5635198Sjmcp 
5645198Sjmcp /* bitmask values for membar */
5655198Sjmcp static const char *membar_mmask[4] = {
5665198Sjmcp 	"#LoadLoad", "#StoreLoad", "#LoadStore", "#StoreStore"
5675198Sjmcp };
5685198Sjmcp 
569*10271SJason.Beloro@Sun.COM static const char *membar_cmask[3] = {
570*10271SJason.Beloro@Sun.COM 	"#Lookaside", "#MemIssue", "#Sync"
5715198Sjmcp };
5725198Sjmcp 
5735198Sjmcp /* v8 ancillary state register names */
5745198Sjmcp static const char *asr_names[32] = {
5755198Sjmcp 	"%y",	"%asr1",  "%asr2",  "%asr3",
5765198Sjmcp 	"%asr4",  "%asr5",  "%asr6",  "%asr7",
5775198Sjmcp 	"%asr8",  "%asr9",  "%asr10", "%asr11",
5785198Sjmcp 	"%asr12", "%asr13", "%asr14", "%asr15",
5795198Sjmcp 	NULL,	NULL,	NULL,	NULL,
5805198Sjmcp 	NULL,	NULL,	NULL,	NULL,
5815198Sjmcp 	NULL,	NULL,	NULL,	NULL,
5825198Sjmcp 	NULL,	NULL,	NULL,	NULL
5835198Sjmcp };
5845198Sjmcp static const uint32_t asr_rdmask = 0x0000ffffL;
5855198Sjmcp static const uint32_t asr_wrmask = 0x0000ffffL;
5865198Sjmcp 
5875198Sjmcp static const char *v9_asr_names[32] = {
5885198Sjmcp 	"%y",		NULL,		"%ccr",	"%asi",
5895198Sjmcp 	"%tick",	"%pc",		"%fprs",	NULL,
5905198Sjmcp 	NULL,		NULL,		NULL,	NULL,
5915198Sjmcp 	NULL,		NULL,		NULL,	NULL,
5927718SJason.Beloro@Sun.COM 	"%pcr",		"%pic",		"%dcr",	"%gsr",
5935198Sjmcp 	"%softint_set",	"%softint_clr",	"%softint",	"%tick_cmpr",
5945198Sjmcp 	"%stick",	"%stick_cmpr",	NULL,	NULL,
595*10271SJason.Beloro@Sun.COM 	NULL,		NULL,		NULL,	NULL
5965198Sjmcp };
5975198Sjmcp /*
5985198Sjmcp  * on v9, only certain registers are valid for read or writing
5995198Sjmcp  * these are bitmasks corresponding to which registers are valid in which
600*10271SJason.Beloro@Sun.COM  * case. Any access to %dcr is illegal.
6015198Sjmcp  */
602*10271SJason.Beloro@Sun.COM static const uint32_t v9_asr_rdmask = 0x03cb007d;
603*10271SJason.Beloro@Sun.COM static const uint32_t v9_asr_wrmask = 0x03fb004d;
6045198Sjmcp 
6055198Sjmcp /* privledged register names on v9 */
6065198Sjmcp /* TODO: compat - NULL to %priv_nn */
6075198Sjmcp static const char *v9_privreg_names[32] = {
6085198Sjmcp 	"%tpc",	 "%tnpc",	"%tstate",  "%tt",
6095198Sjmcp 	"%tick",	"%tba",	 "%pstate",  "%tl",
6105198Sjmcp 	"%pil",	 "%cwp",	 "%cansave", "%canrestore",
6115198Sjmcp 	"%cleanwin", "%otherwin", "%wstate",  "%fq",
6125198Sjmcp 	"%gl",	NULL,	NULL,	NULL,
6135198Sjmcp 	NULL,	NULL,	NULL,	NULL,
6145198Sjmcp 	NULL,	NULL,	NULL,	NULL,
6155198Sjmcp 	NULL,	NULL,	NULL,	"%ver"
6165198Sjmcp };
6175198Sjmcp 
6188430Sjason@ansipunx.net /* hyper privileged register names on v9 */
6197718SJason.Beloro@Sun.COM static const char *v9_hprivreg_names[32] = {
620*10271SJason.Beloro@Sun.COM 	"%hpstate",	 "%htstate",	NULL,  "%hintp",
6217718SJason.Beloro@Sun.COM 	NULL,	"%htba",	 "%hver",  NULL,
6227718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	NULL,
6237718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	NULL,
6247718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	NULL,
6257718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	NULL,
6267718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	NULL,
6277718SJason.Beloro@Sun.COM 	NULL,	NULL,	NULL,	"%hstick_cmpr"
6287718SJason.Beloro@Sun.COM };
6297718SJason.Beloro@Sun.COM 
6305198Sjmcp static const uint32_t v9_pr_rdmask = 0x80017fff;
6317718SJason.Beloro@Sun.COM static const uint32_t v9_pr_wrmask = 0x00017fff;
632*10271SJason.Beloro@Sun.COM static const uint32_t v9_hpr_rdmask = 0x8000006b;
633*10271SJason.Beloro@Sun.COM static const uint32_t v9_hpr_wrmask = 0x8000006b;
6345198Sjmcp 
6355198Sjmcp static const char *prefetch_str[32] = {
6365198Sjmcp 	"#n_reads", "#one_read",
6375198Sjmcp 	"#n_writes", "#one_write",
6385198Sjmcp 	"#page",    NULL, NULL, NULL,
6395198Sjmcp 	NULL, NULL, NULL, NULL,
6405198Sjmcp 	NULL, NULL, NULL, NULL,
6415198Sjmcp 	NULL, "#unified", NULL, NULL,
6425198Sjmcp 	"#n_reads_strong", "#one_read_strong",
6435198Sjmcp 	"#n_writes_strong", "#one_write_strong",
6445198Sjmcp 	NULL, NULL, NULL, NULL,
6455198Sjmcp 	NULL, NULL, NULL, NULL
6465198Sjmcp };
6475198Sjmcp 
6485198Sjmcp static void prt_field(const char *, uint32_t, int);
6495198Sjmcp 
6505198Sjmcp static const char *get_regname(dis_handle_t *, int, uint32_t);
6515198Sjmcp static int32_t sign_extend(int32_t, int32_t);
6525198Sjmcp 
6535198Sjmcp static void prt_name(dis_handle_t *, const char *, int);
6545198Sjmcp 
6555198Sjmcp #define	IMM_SIGNED 0x01  /* Is immediate value signed		*/
6565198Sjmcp #define	IMM_ADDR   0x02  /* Is immediate value part of an address */
6575198Sjmcp static void prt_imm(dis_handle_t *, uint32_t, int);
6585198Sjmcp 
6595198Sjmcp static void prt_asi(dis_handle_t *, uint32_t);
6608430Sjason@ansipunx.net static const char *get_asi_name(uint8_t);
6615198Sjmcp static void prt_address(dis_handle_t *, uint32_t, int);
6625198Sjmcp static void prt_aluargs(dis_handle_t *, uint32_t, uint32_t);
6635198Sjmcp static void bprintf(dis_handle_t *, const char *, ...);
6645198Sjmcp 
6655198Sjmcp /*
6665198Sjmcp  * print out val (which is 'bitlen' bits long) in binary
6675198Sjmcp  */
6685198Sjmcp #if defined(DIS_STANDALONE)
6695198Sjmcp /* ARGSUSED */
6705198Sjmcp void
prt_binary(uint32_t val,int bitlen)6715198Sjmcp prt_binary(uint32_t val, int bitlen)
6725198Sjmcp {
6735198Sjmcp 
6745198Sjmcp }
6755198Sjmcp 
6765198Sjmcp #else
6775198Sjmcp 
6785198Sjmcp void
prt_binary(uint32_t val,int bitlen)6795198Sjmcp prt_binary(uint32_t val, int bitlen)
6805198Sjmcp {
6815198Sjmcp 	int i;
6825198Sjmcp 
6835198Sjmcp 	for (i = bitlen - 1; i >= 0; --i) {
6845198Sjmcp 		(void) fprintf(stderr, ((val & (1L << i)) != 0) ? "1" : "0");
6855198Sjmcp 
6865198Sjmcp 		if (i % 4 == 0 && i != 0)
6875198Sjmcp 			(void) fprintf(stderr, " ");
6885198Sjmcp 	}
6895198Sjmcp }
6905198Sjmcp #endif /* DIS_STANDALONE */
6915198Sjmcp 
6925198Sjmcp 
6935198Sjmcp /*
6945198Sjmcp  * print out a call instruction
6955198Sjmcp  * format: call address  <name>
6965198Sjmcp  */
6975198Sjmcp /* ARGSUSED1 */
6985198Sjmcp int
fmt_call(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)6995198Sjmcp fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
7005198Sjmcp {
7015198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
7025198Sjmcp 
7035198Sjmcp 	int32_t disp;
7045198Sjmcp 	size_t curlen;
7055198Sjmcp 
7065198Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
7075198Sjmcp 
7085198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
7095198Sjmcp 		prt_field("op", f->f1.op, 2);
7105198Sjmcp 		prt_field("disp30", f->f1.disp30, 30);
7115198Sjmcp 	}
7125198Sjmcp 
7135198Sjmcp 	disp = sign_extend(f->f1.disp30, 30) * 4;
7145198Sjmcp 
7155198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
7165198Sjmcp 
7175198Sjmcp 	bprintf(dhp, (octal != 0) ? "%s0%-11lo" : "%s0x%-10lx",
7185198Sjmcp 	    (disp < 0) ? "-" : "+",
7195198Sjmcp 	    (disp < 0) ? (-disp) : disp);
7205198Sjmcp 
7215198Sjmcp 	(void) strlcat(dhp->dh_buf, " <", dhp->dh_buflen);
7225198Sjmcp 
7235198Sjmcp 	curlen = strlen(dhp->dh_buf);
7245198Sjmcp 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
7255198Sjmcp 	    dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL,
7265198Sjmcp 	    NULL);
7275198Sjmcp 	(void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
7285198Sjmcp 
7295198Sjmcp 
7305198Sjmcp 	return (0);
7315198Sjmcp }
7325198Sjmcp 
7335198Sjmcp int
fmt_sethi(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)7345198Sjmcp fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
7355198Sjmcp {
7365198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
7375198Sjmcp 
7385198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
7395198Sjmcp 		prt_field("op", f->f2.op, 2);
7405198Sjmcp 		prt_field("op2", f->f2.op2, 3);
7415198Sjmcp 		prt_field("rd", f->f2.rd, 5);
7425198Sjmcp 		prt_field("imm22", f->f2.imm22, 22);
7435198Sjmcp 	}
7445198Sjmcp 
7455198Sjmcp 	if (idx == 0) {
7465198Sjmcp 		/* unimp / illtrap */
7475198Sjmcp 		prt_name(dhp, inp->in_data.in_def.in_name, 1);
7485198Sjmcp 		prt_imm(dhp, f->f2.imm22, 0);
7495198Sjmcp 		return (0);
7505198Sjmcp 	}
7515198Sjmcp 
7525198Sjmcp 	if (f->f2.imm22 == 0 && f->f2.rd == 0) {
7535198Sjmcp 		prt_name(dhp, "nop", 0);
7545198Sjmcp 		return (0);
7555198Sjmcp 	}
7565198Sjmcp 
7575198Sjmcp 	/* ?? Should we return -1 if rd == 0 && disp != 0 */
7585198Sjmcp 
7595198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
7605198Sjmcp 
7615198Sjmcp 	bprintf(dhp,
7625198Sjmcp 	    ((dhp->dh_flags & DIS_OCTAL) != 0) ?
7635198Sjmcp 	    "%%hi(0%lo), %s" : "%%hi(0x%lx), %s",
7645198Sjmcp 	    f->f2.imm22 << 10,
7655198Sjmcp 	    reg_names[f->f2.rd]);
7665198Sjmcp 
7675198Sjmcp 	return (0);
7685198Sjmcp }
7695198Sjmcp 
7705198Sjmcp /* ARGSUSED3 */
7715198Sjmcp int
fmt_branch(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)7725198Sjmcp fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
7735198Sjmcp {
7745198Sjmcp 	const char *name = inp->in_data.in_def.in_name;
7755198Sjmcp 	const char *r = NULL;
7765198Sjmcp 	const char *annul = "";
7775198Sjmcp 	const char *pred  = "";
7785198Sjmcp 
7795198Sjmcp 	char buf[15];
7805198Sjmcp 
7815198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
7825198Sjmcp 
7835198Sjmcp 	size_t curlen;
7845198Sjmcp 	int32_t disp;
7855198Sjmcp 	uint32_t flags = inp->in_data.in_def.in_flags;
7865198Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
7875198Sjmcp 
7885198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
7895198Sjmcp 		prt_field("op", f->f2.op, 2);
7905198Sjmcp 		prt_field("op2", f->f2.op2, 3);
7915198Sjmcp 
7925198Sjmcp 		switch (FLG_DISP_VAL(flags)) {
7935198Sjmcp 		case DISP22:
7945198Sjmcp 			prt_field("cond", f->f2a.cond, 4);
7955198Sjmcp 			prt_field("a", f->f2a.a, 1);
7965198Sjmcp 			prt_field("disp22", f->f2a.disp22, 22);
7975198Sjmcp 			break;
7985198Sjmcp 
7995198Sjmcp 		case DISP19:
8005198Sjmcp 			prt_field("cond", f->f2a.cond, 4);
8015198Sjmcp 			prt_field("a", f->f2a.a, 1);
8025198Sjmcp 			prt_field("p", f->f2b.p, 1);
8035198Sjmcp 			prt_field("cc", f->f2b.cc, 2);
8045198Sjmcp 			prt_field("disp19", f->f2b.disp19, 19);
8055198Sjmcp 			break;
8065198Sjmcp 
8075198Sjmcp 		case DISP16:
8085198Sjmcp 			prt_field("bit 28", ((instr & (1L << 28)) >> 28), 1);
8095198Sjmcp 			prt_field("rcond", f->f2c.cond, 3);
8105198Sjmcp 			prt_field("p", f->f2c.p, 1);
8115198Sjmcp 			prt_field("rs1", f->f2c.rs1, 5);
8125198Sjmcp 			prt_field("d16hi", f->f2c.d16hi, 2);
8135198Sjmcp 			prt_field("d16lo", f->f2c.d16lo, 14);
8145198Sjmcp 			break;
8155198Sjmcp 		}
8165198Sjmcp 	}
8175198Sjmcp 
8185198Sjmcp 	if (f->f2b.op2 == 0x01 && idx == 0x00 && f->f2b.p == 1 &&
8195198Sjmcp 	    f->f2b.cc == 0x02 && ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0)) {
8205198Sjmcp 		name = "iprefetch";
8215198Sjmcp 		flags = FLG_RS1(REG_NONE)|FLG_DISP(DISP19);
8225198Sjmcp 	}
8235198Sjmcp 
8247718SJason.Beloro@Sun.COM 
8255198Sjmcp 	switch (FLG_DISP_VAL(flags)) {
8265198Sjmcp 	case DISP22:
8275198Sjmcp 		disp = sign_extend(f->f2a.disp22, 22);
8285198Sjmcp 		break;
8295198Sjmcp 
8305198Sjmcp 	case DISP19:
8315198Sjmcp 		disp = sign_extend(f->f2b.disp19, 19);
8325198Sjmcp 		break;
8335198Sjmcp 
8345198Sjmcp 	case DISP16:
8355198Sjmcp 		disp = sign_extend((f->f2c.d16hi << 14)|f->f2c.d16lo, 16);
8365198Sjmcp 		break;
8375198Sjmcp 
8385198Sjmcp 	}
8395198Sjmcp 
8405198Sjmcp 	disp *= 4;
8415198Sjmcp 
8425198Sjmcp 	if ((FLG_RS1_VAL(flags) == REG_ICC) || (FLG_RS1_VAL(flags) == REG_FCC))
8435198Sjmcp 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2b.cc);
8445198Sjmcp 	else
8455198Sjmcp 		r = get_regname(dhp, FLG_RS1_VAL(flags), f->f2c.rs1);
8465198Sjmcp 
8475198Sjmcp 	if (r == NULL)
8485198Sjmcp 		return (-1);
8495198Sjmcp 
8505198Sjmcp 	if (f->f2a.a == 1)
8515198Sjmcp 		annul = ",a";
8525198Sjmcp 
8535198Sjmcp 	if ((flags & FLG_PRED) != 0) {
8545198Sjmcp 		if (f->f2b.p == 0) {
8555198Sjmcp 			pred = ",pn";
8565198Sjmcp 		} else {
8575198Sjmcp 			if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
8585198Sjmcp 				pred = ",pt";
8595198Sjmcp 		}
8605198Sjmcp 	}
8615198Sjmcp 
862*10271SJason.Beloro@Sun.COM 	(void) snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
8635198Sjmcp 	prt_name(dhp, buf, 1);
8645198Sjmcp 
8655198Sjmcp 
8665198Sjmcp 	switch (FLG_DISP_VAL(flags)) {
8675198Sjmcp 	case DISP22:
8685198Sjmcp 		bprintf(dhp,
8695198Sjmcp 		    (octal != 0) ? "%s0%-11lo <" : "%s0x%-10lx <",
8705198Sjmcp 		    (disp < 0) ? "-" : "+",
8715198Sjmcp 		    (disp < 0) ? (-disp) : disp);
8725198Sjmcp 		break;
8735198Sjmcp 
8745198Sjmcp 	case DISP19:
875*10271SJason.Beloro@Sun.COM 		bprintf(dhp,
876*10271SJason.Beloro@Sun.COM 		    (octal != 0) ? "%s, %s0%-5lo <" :
877*10271SJason.Beloro@Sun.COM 		    "%s, %s0x%-04lx <", r,
878*10271SJason.Beloro@Sun.COM 		    (disp < 0) ? "-" : "+",
879*10271SJason.Beloro@Sun.COM 		    (disp < 0) ? (-disp) : disp);
8805198Sjmcp 		break;
8815198Sjmcp 
8825198Sjmcp 	case DISP16:
8835198Sjmcp 		bprintf(dhp,
8845198Sjmcp 		    (octal != 0) ? "%s, %s0%-6lo <" : "%s, %s0x%-5lx <",
8855198Sjmcp 		    r,
8865198Sjmcp 		    (disp < 0) ? "-" : "+",
8875198Sjmcp 		    (disp < 0) ? (-disp) : disp);
8885198Sjmcp 		break;
8895198Sjmcp 	}
8905198Sjmcp 
8915198Sjmcp 	curlen = strlen(dhp->dh_buf);
8925198Sjmcp 	dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
8935198Sjmcp 	    dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL, NULL);
8945198Sjmcp 
8955198Sjmcp 	(void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
8965198Sjmcp 
8975198Sjmcp 	return (0);
8985198Sjmcp }
8995198Sjmcp 
9005198Sjmcp 
9015198Sjmcp 
9025198Sjmcp /*
9035198Sjmcp  * print out the compare and swap instructions (casa/casxa)
9045198Sjmcp  * format: casa/casxa [%rs1] imm_asi, %rs2, %rd
9055198Sjmcp  *	    casa/casxa [%rs1] %asi, %rs2, %rd
9065198Sjmcp  *
9075198Sjmcp  * If DIS_DEBUG_SYN_ALL is set, synthetic instructions are emitted
9085198Sjmcp  * when an immediate ASI value is given as follows:
9095198Sjmcp  *
9105198Sjmcp  * casa  [%rs1]#ASI_P, %rs2, %rd    -> cas   [%rs1], %rs2, %rd
9115198Sjmcp  * casa  [%rs1]#ASI_P_L, %rs2, %rd  -> casl  [%rs1], %rs2, %rd
9125198Sjmcp  * casxa [%rs1]#ASI_P, %rs2, %rd    -> casx  [%rs1], %rs2, %rd
9135198Sjmcp  * casxa [%rs1]#ASI_P_L, %rs2, %rd  -> casxl [%rs1], %rs2, %rd
9145198Sjmcp  */
9155198Sjmcp static int
fmt_cas(dis_handle_t * dhp,uint32_t instr,const char * name)9165198Sjmcp fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
9175198Sjmcp {
9185198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
9198430Sjason@ansipunx.net 	const char *asistr = NULL;
9205198Sjmcp 	int noasi = 0;
9215198Sjmcp 
9228430Sjason@ansipunx.net 	asistr = get_asi_name(f->f3.asi);
9238430Sjason@ansipunx.net 
9245198Sjmcp 	if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
9255198Sjmcp 		if (f->f3.op3 == 0x3c && f->f3.i == 0) {
9265198Sjmcp 			if (f->f3.asi == 0x80) {
9275198Sjmcp 				noasi = 1;
9285198Sjmcp 				name = "cas";
9295198Sjmcp 			}
9305198Sjmcp 
9315198Sjmcp 			if (f->f3.asi == 0x88) {
9325198Sjmcp 				noasi = 1;
9335198Sjmcp 				name = "casl";
9345198Sjmcp 			}
9355198Sjmcp 		}
9365198Sjmcp 
9375198Sjmcp 		if (f->f3.op3 == 0x3e && f->f3.i == 0) {
9385198Sjmcp 			if (f->f3.asi == 0x80) {
9395198Sjmcp 				noasi = 1;
9405198Sjmcp 				name = "casx";
9415198Sjmcp 			}
9425198Sjmcp 
9435198Sjmcp 			if (f->f3.asi == 0x88) {
9445198Sjmcp 				noasi = 1;
9455198Sjmcp 				name = "casxl";
9465198Sjmcp 			}
9475198Sjmcp 		}
9485198Sjmcp 	}
9495198Sjmcp 
9505198Sjmcp 	prt_name(dhp, name, 1);
9515198Sjmcp 
9525198Sjmcp 	bprintf(dhp, "[%s]", reg_names[f->f3.rs1]);
9535198Sjmcp 
9545198Sjmcp 	if (noasi == 0) {
9555198Sjmcp 		(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
9565198Sjmcp 		prt_asi(dhp, instr);
9575198Sjmcp 	}
9585198Sjmcp 
9595198Sjmcp 	bprintf(dhp, ", %s, %s", reg_names[f->f3.rs2], reg_names[f->f3.rd]);
9605198Sjmcp 
9618430Sjason@ansipunx.net 	if (noasi == 0 && asistr != NULL)
9628430Sjason@ansipunx.net 		bprintf(dhp, "\t<%s>", asistr);
9638430Sjason@ansipunx.net 
9645198Sjmcp 	return (0);
9655198Sjmcp }
9665198Sjmcp 
9675198Sjmcp /*
9685198Sjmcp  * format a load/store instruction
9695198Sjmcp  * format: ldXX [%rs1 + %rs2], %rd	  load, i==0
9705198Sjmcp  *	    ldXX [%rs1 +/- nn], %rd	  load, i==1
9715198Sjmcp  *	    ldXX [%rs1 + %rs2] #XX, %rd   load w/ imm_asi, i==0
9725198Sjmcp  *	    ldXX [%rs1 +/- nn] %asi, %rd  load from asi[%asi], i==1
9735198Sjmcp  *
9745198Sjmcp  *	    stXX %rd, [%rs1 + %rs2]	  store, i==0
9755198Sjmcp  *	    stXX %rd, [%rs1 +/- nn]	  store, i==1
9765198Sjmcp  *	    stXX %rd, [%rs1 + %rs1] #XX   store to imm_asi, i==0
9775198Sjmcp  *	    stXX %rd, [%rs1 +/-nn] %asi   store to asi[%asi], i==1
9785198Sjmcp  *
9795198Sjmcp  * The register sets used for %rd are set in the instructions flags field
9805198Sjmcp  * The asi variants are used if FLG_ASI is set in the instructions flags field
9815198Sjmcp  *
9825198Sjmcp  * If DIS_DEBUG_SYNTH_ALL or DIS_DEBUG_COMPAT are set,
9835198Sjmcp  * When %rs1, %rs2 or nn are 0, they are not printed, i.e.
9845198Sjmcp  * [ %rs1 + 0x0 ], %rd -> [%rs1], %rd for example
9855198Sjmcp  *
9865198Sjmcp  * The following synthetic instructions are also implemented:
9875198Sjmcp  *
9885198Sjmcp  * stb %g0, [addr] -> clrb [addr]    DIS_DEBUG_SYNTH_ALL
9895198Sjmcp  * sth %g0, [addr] -> crlh [addr]    DIS_DEBUG_SYNTH_ALL
9905198Sjmcp  * stw %g0, [addr] -> clr  [addr]    DIS_DEBUG_SYNTH_ALL|DIS_DEBUG_COMPAT
9915198Sjmcp  * stx %g0, [addr] -> clrx [addr]    DIS_DEBUG_SYNTH_ALL
9925198Sjmcp  *
9935198Sjmcp  * If DIS_DEBUG_COMPAT is set, the following substitutions also take place
9945198Sjmcp  *	lduw -> ld
9955198Sjmcp  *	ldtw -> ld
9965198Sjmcp  *	stuw -> st
9975198Sjmcp  *	sttw -> st
9985198Sjmcp  */
9995198Sjmcp int
fmt_ls(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)10005198Sjmcp fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
10015198Sjmcp {
10025198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
10035198Sjmcp 	const char *regstr = NULL;
10048430Sjason@ansipunx.net 	const char *asistr = NULL;
10055198Sjmcp 
10065198Sjmcp 	const char *iname = inp->in_data.in_def.in_name;
10075198Sjmcp 	uint32_t flags = inp->in_data.in_def.in_flags;
10085198Sjmcp 
10095198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
10105198Sjmcp 		prt_field("op", f->f3.op, 2);
10115198Sjmcp 		prt_field("op3", f->f3.op3, 6);
10125198Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
10135198Sjmcp 		prt_field("i", f->f3.i, 1);
10145198Sjmcp 		if (f->f3.i != 0) {
10155198Sjmcp 			prt_field("simm13", f->f3a.simm13, 13);
10165198Sjmcp 		} else {
10175198Sjmcp 			if ((flags & FLG_ASI) != 0)
10185198Sjmcp 				prt_field("imm_asi", f->f3.asi, 8);
10195198Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
10205198Sjmcp 		}
10215198Sjmcp 		prt_field("rd", f->f3.rd, 5);
10225198Sjmcp 	}
10235198Sjmcp 
10245198Sjmcp 	if (idx == 0x2d || idx == 0x3d) {
10255198Sjmcp 		/* prefetch / prefetcha */
10265198Sjmcp 
10275198Sjmcp 		prt_name(dhp, iname, 1);
10285198Sjmcp 
10295198Sjmcp 		prt_address(dhp, instr, 0);
10305198Sjmcp 
10315198Sjmcp 		if (idx == 0x3d) {
10325198Sjmcp 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
10335198Sjmcp 			prt_asi(dhp, instr);
10345198Sjmcp 		}
10355198Sjmcp 
10365198Sjmcp 		(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
10375198Sjmcp 
10385198Sjmcp 		/* fcn field is the same as rd */
10395198Sjmcp 		if (prefetch_str[f->f3.rd] != NULL)
10405198Sjmcp 			(void) strlcat(dhp->dh_buf, prefetch_str[f->f3.rd],
10415198Sjmcp 			    dhp->dh_buflen);
10425198Sjmcp 		else
10435198Sjmcp 			prt_imm(dhp, f->f3.rd, 0);
10445198Sjmcp 
10458430Sjason@ansipunx.net 		if (idx == 0x3d && f->f3.i == 0) {
10468430Sjason@ansipunx.net 			asistr = get_asi_name(f->f3.asi);
10478430Sjason@ansipunx.net 			if (asistr != NULL)
10488430Sjason@ansipunx.net 				bprintf(dhp, "\t<%s>", asistr);
10498430Sjason@ansipunx.net 		}
10508430Sjason@ansipunx.net 
10515198Sjmcp 		return (0);
10525198Sjmcp 	}
10535198Sjmcp 
10545198Sjmcp 	/* casa / casxa */
10555198Sjmcp 	if (idx == 0x3c || idx == 0x3e)
10565198Sjmcp 		return (fmt_cas(dhp, instr, iname));
10575198Sjmcp 
10585198Sjmcp 	/* synthetic instructions & special cases */
10595198Sjmcp 	switch (idx) {
10605198Sjmcp 	case 0x00:
10615198Sjmcp 		/* ld */
10625198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
10635198Sjmcp 			iname = "lduw";
10645198Sjmcp 		break;
10655198Sjmcp 
10665198Sjmcp 	case 0x03:
10675198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
10685198Sjmcp 			iname = "ldtw";
10695198Sjmcp 		break;
10705198Sjmcp 
10715198Sjmcp 	case 0x04:
10725198Sjmcp 		/* stw */
10735198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
10745198Sjmcp 			iname = "stuw";
10755198Sjmcp 
10765198Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
10775198Sjmcp 		    == 0)
10785198Sjmcp 			break;
10795198Sjmcp 
10805198Sjmcp 		if (f->f3.rd == 0) {
10815198Sjmcp 			iname = "clr";
10825198Sjmcp 			flags = FLG_RD(REG_NONE);
10835198Sjmcp 		}
10845198Sjmcp 		break;
10855198Sjmcp 
10865198Sjmcp 	case 0x05:
10875198Sjmcp 		/* stb */
10885198Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
10895198Sjmcp 		    == 0)
10905198Sjmcp 			break;
10915198Sjmcp 
10925198Sjmcp 		if (f->f3.rd == 0) {
10935198Sjmcp 			iname = "clrb";
10945198Sjmcp 			flags = FLG_RD(REG_NONE);
10955198Sjmcp 		}
10965198Sjmcp 		break;
10975198Sjmcp 
10985198Sjmcp 	case 0x06:
10995198Sjmcp 		/* sth */
11005198Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
11015198Sjmcp 		    == 0)
11025198Sjmcp 			break;
11035198Sjmcp 
11045198Sjmcp 		if (f->f3.rd == 0) {
11055198Sjmcp 			iname = "clrh";
11065198Sjmcp 			flags = FLG_RD(REG_NONE);
11075198Sjmcp 		}
11085198Sjmcp 		break;
11095198Sjmcp 
11105198Sjmcp 	case 0x07:
11115198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
11125198Sjmcp 			iname = "sttw";
11135198Sjmcp 		break;
11145198Sjmcp 
11155198Sjmcp 	case 0x0e:
11165198Sjmcp 		/* stx */
11175198Sjmcp 
11185198Sjmcp 		if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
11195198Sjmcp 		    == 0)
11205198Sjmcp 			break;
11215198Sjmcp 
11225198Sjmcp 		if (f->f3.rd == 0) {
11235198Sjmcp 			iname = "clrx";
11245198Sjmcp 			flags = FLG_RD(REG_NONE);
11255198Sjmcp 		}
11265198Sjmcp 		break;
11275198Sjmcp 
11285198Sjmcp 	case 0x13:
11295198Sjmcp 		/* ldtwa */
11305198Sjmcp 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
11315198Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
11325198Sjmcp 			iname = "ldtwa";
11335198Sjmcp 		break;
11345198Sjmcp 
11355198Sjmcp 	case 0x17:
11365198Sjmcp 		/* sttwa */
11375198Sjmcp 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
11385198Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
11395198Sjmcp 			iname = "sttwa";
11405198Sjmcp 		break;
11415198Sjmcp 
11425198Sjmcp 	case 0x21:
11435198Sjmcp 	case 0x25:
11445198Sjmcp 		/*
11455198Sjmcp 		 * on sparcv8 it merely says that rd != 1 should generate an
11465198Sjmcp 		 * exception, on v9, it is illegal
11475198Sjmcp 		 */
11485198Sjmcp 		if ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0)
11495198Sjmcp 			break;
11505198Sjmcp 
11515198Sjmcp 		iname = (idx == 0x21) ? "ldx" : "stx";
11525198Sjmcp 
11535198Sjmcp 		if (f->f3.rd > 1)
11545198Sjmcp 			return (-1);
11555198Sjmcp 
11565198Sjmcp 		break;
11575198Sjmcp 
11585198Sjmcp 	case 0x31:
11595198Sjmcp 		/* stda */
11605198Sjmcp 		switch (f->f3.asi) {
11615198Sjmcp 			case 0xc0:
11625198Sjmcp 			case 0xc1:
11635198Sjmcp 			case 0xc8:
11645198Sjmcp 			case 0xc9:
11655198Sjmcp 			case 0xc2:
11665198Sjmcp 			case 0xc3:
11675198Sjmcp 			case 0xca:
11685198Sjmcp 			case 0xcb:
11695198Sjmcp 			case 0xc4:
11705198Sjmcp 			case 0xc5:
11715198Sjmcp 			case 0xcc:
11725198Sjmcp 			case 0xcd:
11735198Sjmcp 				/*
11745198Sjmcp 				 * store partial floating point, only valid w/
11755198Sjmcp 				 * vis
11765198Sjmcp 				 *
11775198Sjmcp 				 * Somewhat confusingly, it uses the same op
11785198Sjmcp 				 * code as 'stda' -- store double to alternate
11795198Sjmcp 				 * space.  It is distinguised by specific
11805198Sjmcp 				 * imm_asi values (as seen above), and
11815198Sjmcp 				 * has a slightly different output syntax
11825198Sjmcp 				 */
11835198Sjmcp 
11845198Sjmcp 				if ((dhp->dh_flags & DIS_SPARC_V9_SGI) == 0)
11855198Sjmcp 					break;
11865198Sjmcp 				if (f->f3.i != 0)
11875198Sjmcp 					break;
11885198Sjmcp 				prt_name(dhp, iname, 1);
11895198Sjmcp 				bprintf(dhp, "%s, %s, [%s] ",
11905198Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rd),
11915198Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rs2),
11925198Sjmcp 				    get_regname(dhp, REG_FPD, f->f3.rs1));
11935198Sjmcp 				prt_asi(dhp, instr);
11948430Sjason@ansipunx.net 				asistr = get_asi_name(f->f3.asi);
11958430Sjason@ansipunx.net 				if (asistr != NULL)
11968430Sjason@ansipunx.net 					bprintf(dhp, "\t<%s>", asistr);
11978430Sjason@ansipunx.net 
11985198Sjmcp 				return (0);
11995198Sjmcp 
12005198Sjmcp 			default:
12015198Sjmcp 				break;
12025198Sjmcp 		}
12035198Sjmcp 
12045198Sjmcp 	}
12055198Sjmcp 
12065198Sjmcp 	regstr = get_regname(dhp, FLG_RD_VAL(flags), f->f3.rd);
12075198Sjmcp 
12088430Sjason@ansipunx.net 	if (f->f3.i == 0)
12098430Sjason@ansipunx.net 		asistr = get_asi_name(f->f3.asi);
12108430Sjason@ansipunx.net 
12115198Sjmcp 	prt_name(dhp, iname, 1);
12125198Sjmcp 
12135198Sjmcp 	if ((flags & FLG_STORE) != 0) {
12145198Sjmcp 		if (regstr[0] != '\0') {
12155198Sjmcp 			(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
12165198Sjmcp 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
12175198Sjmcp 		}
12185198Sjmcp 
12195198Sjmcp 		prt_address(dhp, instr, 0);
12205198Sjmcp 		if ((flags & FLG_ASI) != 0) {
12215198Sjmcp 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
12225198Sjmcp 			prt_asi(dhp, instr);
12235198Sjmcp 		}
12245198Sjmcp 	} else {
12255198Sjmcp 		prt_address(dhp, instr, 0);
12265198Sjmcp 		if ((flags & FLG_ASI) != 0) {
12275198Sjmcp 			(void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
12285198Sjmcp 			prt_asi(dhp, instr);
12295198Sjmcp 		}
12305198Sjmcp 
12315198Sjmcp 		if (regstr[0] != '\0') {
12325198Sjmcp 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
12335198Sjmcp 			(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
12345198Sjmcp 		}
12355198Sjmcp 	}
12365198Sjmcp 
12378430Sjason@ansipunx.net 	if ((flags & FLG_ASI) != 0 && asistr != NULL)
12388430Sjason@ansipunx.net 		bprintf(dhp, "\t<%s>", asistr);
12398430Sjason@ansipunx.net 
12405198Sjmcp 	return (0);
12415198Sjmcp }
12425198Sjmcp 
12435198Sjmcp static int
fmt_cpop(dis_handle_t * dhp,uint32_t instr,const inst_t * inp)12445198Sjmcp fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
12455198Sjmcp {
12465198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
12475198Sjmcp 	int flags = FLG_P1(REG_CP)|FLG_P2(REG_CP)|FLG_NOIMM|FLG_P3(REG_CP);
12485198Sjmcp 
12495198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
12505198Sjmcp 		prt_field("op", f->fcp.op, 2);
12515198Sjmcp 		prt_field("op3", f->fcp.op3, 6);
12525198Sjmcp 		prt_field("opc", f->fcp.opc, 9);
12535198Sjmcp 		prt_field("rs1", f->fcp.rs1, 5);
12545198Sjmcp 		prt_field("rs2", f->fcp.rs2, 5);
12555198Sjmcp 		prt_field("rd", f->fcp.rd, 5);
12565198Sjmcp 	}
12575198Sjmcp 
12585198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
12595198Sjmcp 	prt_imm(dhp, f->fcp.opc, 0);
12605198Sjmcp 
12615198Sjmcp 	(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
12625198Sjmcp 	(void) prt_aluargs(dhp, instr, flags);
12635198Sjmcp 
12645198Sjmcp 	return (0);
12655198Sjmcp }
12665198Sjmcp 
12675198Sjmcp static int
dis_fmt_rdwr(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)12685198Sjmcp dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
12695198Sjmcp {
12705198Sjmcp 	const char *psr_str = "%psr";
12715198Sjmcp 	const char *wim_str = "%wim";
12725198Sjmcp 	const char *tbr_str = "%tbr";
12735198Sjmcp 
12745198Sjmcp 	const char *name = inp->in_data.in_def.in_name;
12755198Sjmcp 	const char *regstr = NULL;
12765198Sjmcp 
12775198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
12785198Sjmcp 
12795198Sjmcp 	int rd = (idx < 0x30);
12805198Sjmcp 	int v9 = (dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI));
12815198Sjmcp 	int ridx = f->f3.rs1;
12825198Sjmcp 	int i, first;
12835198Sjmcp 	int pr_rs1 = 1;
12845198Sjmcp 	int pr_rs2 = 1;
12855198Sjmcp 
12865198Sjmcp 	int use_mask = 1;
12875198Sjmcp 	uint32_t mask;
12885198Sjmcp 
12895198Sjmcp 	if (rd == 0)
12905198Sjmcp 		ridx = f->f3.rd;
12915198Sjmcp 
12925198Sjmcp 	switch (idx) {
12935198Sjmcp 	case 0x28:
12945198Sjmcp 		/* rd */
12955198Sjmcp 
12965198Sjmcp 		/* stbar */
12975198Sjmcp 		if ((f->f3.rd == 0) && (f->f3.rs1 == 15) && (f->f3.i == 0)) {
12985198Sjmcp 			prt_name(dhp, "stbar", 0);
12995198Sjmcp 			return (0);
13005198Sjmcp 		}
13015198Sjmcp 
13025198Sjmcp 		/* membar */
13035198Sjmcp 		if ((v9 != 0) && (f->f3.rd == 0) && (f->f3.rs1 == 15) &&
13045198Sjmcp 		    (f->f3.i == 1) && ((f->i & (1L << 12)) == 0)) {
13055198Sjmcp 
13065198Sjmcp 			prt_name(dhp, "membar",
13075198Sjmcp 			    ((f->fmb.cmask != 0) || (f->fmb.mmask != 0)));
13085198Sjmcp 
13095198Sjmcp 			first = 0;
13105198Sjmcp 
1311*10271SJason.Beloro@Sun.COM 			for (i = 0; i < 4; ++i) {
13125198Sjmcp 				if ((f->fmb.cmask & (1L << i)) != 0) {
13135198Sjmcp 					bprintf(dhp, "%s%s",
13145198Sjmcp 					    (first != 0) ? "|" : "",
13155198Sjmcp 					    membar_cmask[i]);
13165198Sjmcp 					first = 1;
13175198Sjmcp 				}
13185198Sjmcp 			}
13195198Sjmcp 
13205198Sjmcp 			for (i = 0; i < 5; ++i) {
13215198Sjmcp 				if ((f->fmb.mmask & (1L << i)) != 0) {
13225198Sjmcp 					bprintf(dhp, "%s%s",
13235198Sjmcp 					    (first != 0) ? "|" : "",
13245198Sjmcp 					    membar_mmask[i]);
13255198Sjmcp 					first = 1;
13265198Sjmcp 				}
13275198Sjmcp 			}
13285198Sjmcp 
13295198Sjmcp 			return (0);
13305198Sjmcp 		}
13315198Sjmcp 
13325198Sjmcp 		if (v9 != 0) {
13335198Sjmcp 			regstr = v9_asr_names[ridx];
13345198Sjmcp 			mask = v9_asr_rdmask;
13355198Sjmcp 		} else {
13365198Sjmcp 			regstr = asr_names[ridx];
13375198Sjmcp 			mask = asr_rdmask;
13385198Sjmcp 		}
13395198Sjmcp 		break;
13405198Sjmcp 
13415198Sjmcp 	case 0x29:
13427718SJason.Beloro@Sun.COM 		if (v9 != 0) {
13437718SJason.Beloro@Sun.COM 			regstr = v9_hprivreg_names[ridx];
13447718SJason.Beloro@Sun.COM 			mask = v9_hpr_rdmask;
13457718SJason.Beloro@Sun.COM 		} else {
13467718SJason.Beloro@Sun.COM 			regstr = psr_str;
13477718SJason.Beloro@Sun.COM 			use_mask = 0;
13487718SJason.Beloro@Sun.COM 		}
13495198Sjmcp 		break;
13505198Sjmcp 
13515198Sjmcp 	case 0x2a:
13525198Sjmcp 		if (v9 != 0) {
13535198Sjmcp 			regstr = v9_privreg_names[ridx];
13545198Sjmcp 			mask = v9_pr_rdmask;
13555198Sjmcp 		} else {
13565198Sjmcp 			regstr = wim_str;
13575198Sjmcp 			use_mask = 0;
13585198Sjmcp 		}
13595198Sjmcp 		break;
13605198Sjmcp 
13615198Sjmcp 	case 0x2b:
13625198Sjmcp 		if (v9 != 0) {
13635198Sjmcp 			/* flushw */
13645198Sjmcp 			prt_name(dhp, name, 0);
13655198Sjmcp 			return (0);
13665198Sjmcp 		}
13675198Sjmcp 
13685198Sjmcp 		regstr = tbr_str;
13695198Sjmcp 		use_mask = 0;
13705198Sjmcp 		break;
13715198Sjmcp 
13725198Sjmcp 	case 0x30:
13735198Sjmcp 		if (v9 != 0) {
13745198Sjmcp 			regstr = v9_asr_names[ridx];
13755198Sjmcp 			mask = v9_asr_wrmask;
13765198Sjmcp 		} else {
13775198Sjmcp 			regstr = asr_names[ridx];
13785198Sjmcp 			mask = asr_wrmask;
13795198Sjmcp 		}
13805198Sjmcp 
13818430Sjason@ansipunx.net 		/*
13828430Sjason@ansipunx.net 		 * sir is shoehorned in here, per Ultrasparc 2007
13838430Sjason@ansipunx.net 		 * hyperprivileged edition, section 7.88, all of
13848430Sjason@ansipunx.net 		 * these must be true to distinguish from WRasr
13858430Sjason@ansipunx.net 		 */
13868430Sjason@ansipunx.net 		if (v9 != 0 && f->f3.rd == 15 && f->f3.rs1 == 0 &&
13878430Sjason@ansipunx.net 		    f->f3.i == 1) {
13888430Sjason@ansipunx.net 			prt_name(dhp, "sir", 1);
13898430Sjason@ansipunx.net 			prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
13908430Sjason@ansipunx.net 			    IMM_SIGNED);
13918430Sjason@ansipunx.net 			return (0);
13928430Sjason@ansipunx.net 		}
13938430Sjason@ansipunx.net 
13945198Sjmcp 		/* synth: mov */
13955198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
13965198Sjmcp 		    == 0)
13975198Sjmcp 			break;
13985198Sjmcp 
13997718SJason.Beloro@Sun.COM 		if (v9 == 0) {
14007718SJason.Beloro@Sun.COM 			if (f->f3.rs1 == 0) {
14017718SJason.Beloro@Sun.COM 				name = "mov";
14027718SJason.Beloro@Sun.COM 				pr_rs1 = 0;
14037718SJason.Beloro@Sun.COM 			}
14045198Sjmcp 
14057718SJason.Beloro@Sun.COM 			if ((f->f3.i == 0 && f->f3.rs2 == 0) ||
14067718SJason.Beloro@Sun.COM 			    (f->f3.i == 1 && f->f3a.simm13 == 0)) {
14077718SJason.Beloro@Sun.COM 				name = "mov";
14087718SJason.Beloro@Sun.COM 				pr_rs2 = 0;
14097718SJason.Beloro@Sun.COM 			}
14105198Sjmcp 		}
14115198Sjmcp 
14125198Sjmcp 		if (pr_rs1 == 0)
14135198Sjmcp 			pr_rs2 = 1;
14145198Sjmcp 
14155198Sjmcp 		break;
14165198Sjmcp 
14175198Sjmcp 	case 0x31:
14185198Sjmcp 		/*
14195198Sjmcp 		 * NOTE: due to the presence of an overlay entry for another
14205198Sjmcp 		 * table, this case only happens when doing v8 instructions
14215198Sjmcp 		 * only
14225198Sjmcp 		 */
14235198Sjmcp 		regstr = psr_str;
14245198Sjmcp 		use_mask = 0;
14255198Sjmcp 		break;
14265198Sjmcp 
14275198Sjmcp 	case 0x32:
14285198Sjmcp 		if (v9 != 0) {
14295198Sjmcp 			regstr = v9_privreg_names[ridx];
14305198Sjmcp 			mask = v9_pr_wrmask;
14315198Sjmcp 		} else {
14325198Sjmcp 			regstr = wim_str;
14335198Sjmcp 			use_mask = 0;
14345198Sjmcp 		}
14355198Sjmcp 		break;
14365198Sjmcp 
14375198Sjmcp 	case 0x33:
14387718SJason.Beloro@Sun.COM 		if (v9 != 0) {
14397718SJason.Beloro@Sun.COM 			regstr = v9_hprivreg_names[ridx];
14407718SJason.Beloro@Sun.COM 			mask = v9_hpr_wrmask;
14417718SJason.Beloro@Sun.COM 		} else {
14427718SJason.Beloro@Sun.COM 			regstr = tbr_str;
14437718SJason.Beloro@Sun.COM 			use_mask = 0;
14447718SJason.Beloro@Sun.COM 		}
14455198Sjmcp 		break;
14465198Sjmcp 	}
14475198Sjmcp 
14485198Sjmcp 	if (regstr == NULL)
14495198Sjmcp 		return (-1);
14505198Sjmcp 
14515198Sjmcp 	if (use_mask != 0 && ((1L << ridx) & mask) == 0)
14525198Sjmcp 		return (-1);
14535198Sjmcp 
14545198Sjmcp 	prt_name(dhp, name, 1);
14555198Sjmcp 
14565198Sjmcp 	if (rd != 0) {
14575198Sjmcp 		bprintf(dhp, "%s, %s", regstr, reg_names[f->f3.rd]);
14585198Sjmcp 	} else {
14595198Sjmcp 		if (pr_rs1 == 1)
14605198Sjmcp 			bprintf(dhp, "%s, ", reg_names[f->f3.rs1]);
14615198Sjmcp 
14625198Sjmcp 		if (pr_rs2 != 0) {
14635198Sjmcp 			if (f->f3.i == 1)
14645198Sjmcp 				prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
14655198Sjmcp 				    IMM_SIGNED);
14665198Sjmcp 			else
14675198Sjmcp 				(void) strlcat(dhp->dh_buf,
14685198Sjmcp 				    reg_names[f->f3.rs2], dhp->dh_buflen);
14695198Sjmcp 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
14705198Sjmcp 		}
14715198Sjmcp 
14725198Sjmcp 		(void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
14735198Sjmcp 	}
14745198Sjmcp 
14755198Sjmcp 	return (0);
14765198Sjmcp }
14775198Sjmcp 
14785198Sjmcp /* ARGSUSED3 */
14795198Sjmcp int
fmt_trap(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)14805198Sjmcp fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
14815198Sjmcp {
14825198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
14835198Sjmcp 
14845198Sjmcp 	int v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
14855198Sjmcp 	int p_rs1, p_t;
14865198Sjmcp 
14875198Sjmcp 	if (f->ftcc.undef != 0)
14885198Sjmcp 		return (-1);
14895198Sjmcp 
14905198Sjmcp 	if (icc_names[f->ftcc.cc] == NULL)
14915198Sjmcp 		return (-1);
14925198Sjmcp 
14935198Sjmcp 	if (f->ftcc.i == 1 && f->ftcc.undef2 != 0)
14945198Sjmcp 		return (-1);
14955198Sjmcp 
14965198Sjmcp 	if (f->ftcc2.i == 0 && f->ftcc2.undef2 != 0)
14975198Sjmcp 		return (-1);
14985198Sjmcp 
14995198Sjmcp 	p_rs1 = ((f->ftcc.rs1 != 0) ||
15005198Sjmcp 	    ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
15015198Sjmcp 
15025198Sjmcp 	if (f->ftcc.i == 0) {
15035198Sjmcp 		p_t = (f->f3.rs2 != 0 || p_rs1 == 0);
15045198Sjmcp 
15055198Sjmcp 		bprintf(dhp, "%-9s %s%s%s%s%s", inp->in_data.in_def.in_name,
15065198Sjmcp 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
15075198Sjmcp 		    (v9 != 0) ? ", " : "",
15085198Sjmcp 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
15095198Sjmcp 		    (p_rs1 != 0) ? " + " : "",
15105198Sjmcp 		    (p_t != 0) ? reg_names[f->f3.rs2] : "");
15115198Sjmcp 	} else {
15125198Sjmcp 		bprintf(dhp, "%-9s %s%s%s%s0x%x", inp->in_data.in_def.in_name,
15135198Sjmcp 		    (v9 != 0) ? icc_names[f->ftcc2.cc] : "",
15145198Sjmcp 		    (v9 != 0) ? ", " : "",
15155198Sjmcp 		    (p_rs1 != 0) ? reg_names[f->ftcc2.rs1] : "",
15165198Sjmcp 		    (p_rs1 != 0) ? " + " : "",
15175198Sjmcp 		    f->ftcc.immtrap);
15185198Sjmcp 	}
15195198Sjmcp 	return (0);
15205198Sjmcp }
15215198Sjmcp 
15225198Sjmcp static int
prt_shift(dis_handle_t * dhp,uint32_t instr,const inst_t * inp)15235198Sjmcp prt_shift(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
15245198Sjmcp {
15255198Sjmcp 	char name[5];
15265198Sjmcp 	uint32_t cnt;
15275198Sjmcp 
15285198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
15295198Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
15305198Sjmcp 
15315198Sjmcp 	name[0] = '\0';
15325198Sjmcp 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
15335198Sjmcp 
15345198Sjmcp 	if (f->f3b.i == 1)
15355198Sjmcp 		cnt = f->f3.rs2;
15365198Sjmcp 
15375198Sjmcp 	if (f->f3b.x == 1 && ((dhp->dh_flags & DIS_SPARC_V8) == 0)) {
15385198Sjmcp 		cnt = f->f3b.shcnt;
15395198Sjmcp 		(void) strlcat(name, "x", sizeof (name));
15405198Sjmcp 	}
15415198Sjmcp 
15425198Sjmcp 	prt_name(dhp, name, 1);
15435198Sjmcp 
15445198Sjmcp 	if (f->f3b.i == 1)
15455198Sjmcp 		bprintf(dhp, (octal != 0) ? "%s, 0%lo, %s" : "%s, 0x%lx, %s",
15465198Sjmcp 		    reg_names[f->f3.rs1], cnt, reg_names[f->f3.rd]);
15475198Sjmcp 	else
15485198Sjmcp 		bprintf(dhp, "%s, %s, %s", reg_names[f->f3.rs1],
15495198Sjmcp 		    reg_names[f->f3.rs2], reg_names[f->f3.rd]);
15505198Sjmcp 
15515198Sjmcp 	return (0);
15525198Sjmcp }
15535198Sjmcp 
15545198Sjmcp /* ARGSUSED3 */
15555198Sjmcp static int
prt_jmpl(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)15565198Sjmcp prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
15575198Sjmcp {
15585198Sjmcp 	const char *name = inp->in_data.in_def.in_name;
15595198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
15605198Sjmcp 
15615198Sjmcp 	if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
15625198Sjmcp 		name = "call";
15635198Sjmcp 
15645198Sjmcp 	if (f->f3.rd == 0) {
15655198Sjmcp 		if (f->f3.i == 1 && f->f3a.simm13 == 8) {
15665198Sjmcp 			if (f->f3.rs1 == 15) {
15675198Sjmcp 				prt_name(dhp, "retl", 0);
15685198Sjmcp 				return (0);
15695198Sjmcp 			}
15705198Sjmcp 
15715198Sjmcp 			if (f->f3.rs1 == 31) {
15725198Sjmcp 				prt_name(dhp, "ret", 0);
15735198Sjmcp 				return (0);
15745198Sjmcp 			}
15755198Sjmcp 		}
15765198Sjmcp 
15775198Sjmcp 		name = "jmp";
15785198Sjmcp 	}
15795198Sjmcp 
15805198Sjmcp 	prt_name(dhp, name, 1);
15815198Sjmcp 	prt_address(dhp, instr, 1);
15825198Sjmcp 
15835198Sjmcp 	if (f->f3.rd == 0)
15845198Sjmcp 		return (0);
15855198Sjmcp 
15865198Sjmcp 	if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
15875198Sjmcp 		return (0);
15885198Sjmcp 
15895198Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
15905198Sjmcp 
15915198Sjmcp 	return (0);
15925198Sjmcp }
15935198Sjmcp 
15945198Sjmcp int
fmt_alu(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)15955198Sjmcp fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
15965198Sjmcp {
15975198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
15985198Sjmcp 
15995198Sjmcp 	const char *name = inp->in_data.in_def.in_name;
16005198Sjmcp 	int flags = inp->in_data.in_def.in_flags;
16015198Sjmcp 	int arg = 0;
16025198Sjmcp 
16035198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
16045198Sjmcp 		prt_field("op", f->f3.op, 2);
16055198Sjmcp 		prt_field("op3", f->f3.op3, 6);
16065198Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
16075198Sjmcp 
16085198Sjmcp 		switch (idx) {
16095198Sjmcp 			/* TODO: more formats */
16105198Sjmcp 
16115198Sjmcp 		default:
16125198Sjmcp 			if (f->f3.i == 0)
16135198Sjmcp 				prt_field("rs2", f->f3.rs2, 5);
16145198Sjmcp 			else
16155198Sjmcp 				prt_field("simm13", f->f3a.simm13, 13);
16165198Sjmcp 
16175198Sjmcp 			prt_field("rd", f->f3.rd, 5);
16185198Sjmcp 		}
16195198Sjmcp 
16205198Sjmcp 	}
16215198Sjmcp 
16225198Sjmcp 	switch (idx) {
16235198Sjmcp 	case 0x00:
16245198Sjmcp 		/* add */
16255198Sjmcp 
16265198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
16275198Sjmcp 			break;
16285198Sjmcp 
16295198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
16305198Sjmcp 		    f->f3a.simm13 == 1) {
16315198Sjmcp 			name = "inc";
16325198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
16335198Sjmcp 			break;
16345198Sjmcp 		}
16355198Sjmcp 
16365198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
16375198Sjmcp 		    f->f3a.simm13 != 1) {
16385198Sjmcp 			name = "inc";
16395198Sjmcp 			flags = FLG_P1(REG_NONE);
16405198Sjmcp 			break;
16415198Sjmcp 		}
16425198Sjmcp 		break;
16435198Sjmcp 
16445198Sjmcp 	case 0x02:
16455198Sjmcp 		/* or */
16465198Sjmcp 
16475198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
16485198Sjmcp 		    == 0)
16495198Sjmcp 			break;
16505198Sjmcp 
16515198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0) {
16525198Sjmcp 			if (f->f3.rs1 == f->f3.rd) {
16535198Sjmcp 				name = "bset";
16545198Sjmcp 				flags = FLG_P1(REG_NONE);
16555198Sjmcp 				break;
16565198Sjmcp 			}
16575198Sjmcp 		}
16585198Sjmcp 
16595198Sjmcp 		if (((f->f3.i == 0 && f->f3.rs2 == 0) ||
16605198Sjmcp 		    (f->f3.i == 1 && f->f3a.simm13 == 0)) &&
16615198Sjmcp 		    (f->f3.rs1 == 0)) {
16625198Sjmcp 			name = "clr";
16635198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
16645198Sjmcp 			break;
16655198Sjmcp 		}
16665198Sjmcp 
16675198Sjmcp 		if (f->f3.rs1 == 0) {
16685198Sjmcp 			name = "mov";
16695198Sjmcp 			flags = FLG_P1(REG_NONE);
16705198Sjmcp 			break;
16715198Sjmcp 		}
16725198Sjmcp 		break;
16735198Sjmcp 
16745198Sjmcp 	case 0x04:
16755198Sjmcp 		/* sub */
16765198Sjmcp 
16775198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
16785198Sjmcp 		    == 0)
16795198Sjmcp 			break;
16805198Sjmcp 
16815198Sjmcp 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 == f->f3.rd) {
16825198Sjmcp 			name = "neg";
16835198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE);
16845198Sjmcp 			break;
16855198Sjmcp 		}
16865198Sjmcp 
16875198Sjmcp 		if (f->f3.rs1 == 0 && f->f3.i == 0 && f->f3.rs2 != f->f3.rd) {
16885198Sjmcp 			name = "neg";
16895198Sjmcp 			flags = FLG_P1(REG_NONE);
16905198Sjmcp 			break;
16915198Sjmcp 		}
16925198Sjmcp 
16935198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
16945198Sjmcp 			break;
16955198Sjmcp 
16965198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
16975198Sjmcp 		    f->f3a.simm13 == 1) {
16985198Sjmcp 			name = "dec";
16995198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
17005198Sjmcp 			break;
17015198Sjmcp 		}
17025198Sjmcp 
17035198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
17045198Sjmcp 		    f->f3a.simm13 != 1) {
17055198Sjmcp 			name = "dec";
17065198Sjmcp 			flags = FLG_P1(REG_NONE);
17075198Sjmcp 			break;
17085198Sjmcp 		}
17095198Sjmcp 		break;
17105198Sjmcp 
17115198Sjmcp 	case 0x07:
17125198Sjmcp 		/* xnor */
17135198Sjmcp 
17145198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
17155198Sjmcp 		    == 0)
17165198Sjmcp 			break;
17175198Sjmcp 
17185198Sjmcp 		/*
17195198Sjmcp 		 * xnor -> not when you have:
17205198Sjmcp 		 *	 xnor %rs1, 0x0 or %g0, %rd
17215198Sjmcp 		 */
17225198Sjmcp 		if ((f->f3.i == 0 && f->f3.rs2 != 0) ||
17235198Sjmcp 		    (f->f3.i == 1 && f->f3a.simm13 != 0))
17245198Sjmcp 			break;
17255198Sjmcp 
17265198Sjmcp 		name = "not";
17275198Sjmcp 
17285198Sjmcp 		if (f->f3.rs1 == f->f3.rd)
17295198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM|
17305198Sjmcp 			    FLG_P3(REG_INT);
17315198Sjmcp 		else
17325198Sjmcp 			flags = FLG_P1(REG_INT)|FLG_P2(REG_NONE)|FLG_NOIMM|
17335198Sjmcp 			    FLG_P3(REG_INT);
17345198Sjmcp 
17355198Sjmcp 		break;
17365198Sjmcp 
17375198Sjmcp 	case 0x10:
17385198Sjmcp 		/* addcc */
17395198Sjmcp 
17405198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
17415198Sjmcp 			break;
17425198Sjmcp 
17435198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
17445198Sjmcp 		    f->f3a.simm13 == 1) {
17455198Sjmcp 			name = "inccc";
17465198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
17475198Sjmcp 			break;
17485198Sjmcp 		}
17495198Sjmcp 
17505198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
17515198Sjmcp 		    f->f3a.simm13 != 1) {
17525198Sjmcp 			name = "inccc";
17535198Sjmcp 			flags = FLG_P1(REG_NONE);
17545198Sjmcp 			break;
17555198Sjmcp 		}
17565198Sjmcp 		break;
17575198Sjmcp 
17585198Sjmcp 	case 0x11:
17595198Sjmcp 		/* andcc */
17605198Sjmcp 
17615198Sjmcp 		if (f->f3.rd != 0)
17625198Sjmcp 			break;
17635198Sjmcp 
17645198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
17655198Sjmcp 		    == 0)
17665198Sjmcp 			break;
17675198Sjmcp 
17685198Sjmcp 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0) &&
17695198Sjmcp 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0))
17705198Sjmcp 			break;
17715198Sjmcp 
17725198Sjmcp 		name = "btst";
17735198Sjmcp 		flags = FLG_P1(REG_NONE);
17745198Sjmcp 		f->f3.rd = f->f3.rs1;
17755198Sjmcp 		break;
17765198Sjmcp 
17775198Sjmcp 	case 0x12:
17785198Sjmcp 		/* orcc */
17795198Sjmcp 
17805198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
17815198Sjmcp 		    == 0)
17825198Sjmcp 			break;
17835198Sjmcp 
17845198Sjmcp 		if (f->f3.rs1 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
17855198Sjmcp 			name = "tst";
17865198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P3(REG_NONE);
17875198Sjmcp 			break;
17885198Sjmcp 		}
17895198Sjmcp 
17905198Sjmcp 		if (f->f3.rs2 == 0 && f->f3.rd == 0 && f->f3.i == 0) {
17915198Sjmcp 			name = "tst";
17925198Sjmcp 			flags = FLG_P2(REG_NONE)|FLG_P3(REG_NONE);
17935198Sjmcp 			break;
17945198Sjmcp 		}
17955198Sjmcp 
17965198Sjmcp 		break;
17975198Sjmcp 
17985198Sjmcp 	case 0x14:
17995198Sjmcp 		/* subcc */
18005198Sjmcp 
18015198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
18025198Sjmcp 		    == 0)
18035198Sjmcp 			break;
18045198Sjmcp 
18055198Sjmcp 		if (f->f3.rd == 0) {
18065198Sjmcp 			name = "cmp";
18075198Sjmcp 			flags = FLG_P3(REG_NONE);
18085198Sjmcp 			break;
18095198Sjmcp 		}
18105198Sjmcp 
18115198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
18125198Sjmcp 			break;
18135198Sjmcp 
18145198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
18155198Sjmcp 		    f->f3a.simm13 == 1) {
18165198Sjmcp 			name = "deccc";
18175198Sjmcp 			flags = FLG_P1(REG_NONE)|FLG_P2(REG_NONE)|FLG_NOIMM;
18185198Sjmcp 			break;
18195198Sjmcp 		}
18205198Sjmcp 
18215198Sjmcp 		if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
18225198Sjmcp 		    f->f3a.simm13 != 1) {
18235198Sjmcp 			name = "deccc";
18245198Sjmcp 			flags = FLG_P1(REG_NONE);
18255198Sjmcp 			break;
18265198Sjmcp 		}
18275198Sjmcp 
18285198Sjmcp 		break;
18295198Sjmcp 
18305198Sjmcp 	case 0x25:
18315198Sjmcp 	case 0x26:
18325198Sjmcp 	case 0x27:
18335198Sjmcp 		return (prt_shift(dhp, instr, inp));
18345198Sjmcp 
18355198Sjmcp 	case 0x28:
18365198Sjmcp 	case 0x29:
18375198Sjmcp 	case 0x2a:
18385198Sjmcp 	case 0x2b:
18395198Sjmcp 	case 0x30:
18405198Sjmcp 	case 0x31:
18415198Sjmcp 	case 0x32:
18425198Sjmcp 	case 0x33:
18435198Sjmcp 		return (dis_fmt_rdwr(dhp, instr, inp, idx));
18445198Sjmcp 
18455198Sjmcp 	case 0x36:
18465198Sjmcp 	case 0x37:
18475198Sjmcp 		/* NOTE: overlayed on v9 */
18485198Sjmcp 		if ((dhp->dh_flags & DIS_SPARC_V8) != 0)
18495198Sjmcp 			return (fmt_cpop(dhp, instr, inp));
18505198Sjmcp 		break;
18515198Sjmcp 
18525198Sjmcp 	case 0x38:
18535198Sjmcp 		/* jmpl */
18545198Sjmcp 		return (prt_jmpl(dhp, instr, inp, idx));
18555198Sjmcp 
18565198Sjmcp 	case 0x39:
18575198Sjmcp 		/* rett / return */
18585198Sjmcp 		prt_name(dhp, name, 1);
18595198Sjmcp 		prt_address(dhp, instr, 1);
18605198Sjmcp 		return (0);
18615198Sjmcp 
18625198Sjmcp 	case 0x3b:
1863*10271SJason.Beloro@Sun.COM 		/* flush */
1864*10271SJason.Beloro@Sun.COM 		prt_name(dhp, name, 1);
1865*10271SJason.Beloro@Sun.COM 		prt_address(dhp, instr, 0);
18665198Sjmcp 		return (0);
18675198Sjmcp 
18685198Sjmcp 	case 0x3c:
18695198Sjmcp 	case 0x3d:
18705198Sjmcp 		/* save / restore */
18715198Sjmcp 		if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
18725198Sjmcp 		    == 0)
18735198Sjmcp 			break;
18745198Sjmcp 
18755198Sjmcp 		if (f->f3.rs1 != 0 || f->f3.rs2 != 0 || f->f3.rd != 0)
18765198Sjmcp 			break;
18775198Sjmcp 
18785198Sjmcp 		if (f->f3.i != 0 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0))
18795198Sjmcp 			break;
18805198Sjmcp 
18815198Sjmcp 		prt_name(dhp, name, 0);
18825198Sjmcp 		return (0);
18835198Sjmcp 	}
18845198Sjmcp 
18855198Sjmcp 	if (FLG_P1_VAL(flags) != REG_NONE || FLG_P2_VAL(flags) != REG_NONE ||
18865198Sjmcp 	    FLG_P3_VAL(flags) != REG_NONE)
18875198Sjmcp 		arg = 1;
18885198Sjmcp 
18895198Sjmcp 	prt_name(dhp, name, (arg != 0));
18905198Sjmcp 	prt_aluargs(dhp, instr, flags);
18915198Sjmcp 
18925198Sjmcp 	return (0);
18935198Sjmcp }
18945198Sjmcp 
18955198Sjmcp /* ARGSUSED1 */
18965198Sjmcp int
fmt_regwin(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)18975198Sjmcp fmt_regwin(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
18985198Sjmcp {
18995198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 0);
19005198Sjmcp 	return (0);
19015198Sjmcp }
19025198Sjmcp 
19035198Sjmcp /* ARGSUSED1 */
19045198Sjmcp int
fmt_trap_ret(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)19055198Sjmcp fmt_trap_ret(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
19065198Sjmcp {
19077718SJason.Beloro@Sun.COM 	ifmt_t *f = (ifmt_t *)&instr;
19087718SJason.Beloro@Sun.COM 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
19097718SJason.Beloro@Sun.COM 
19107718SJason.Beloro@Sun.COM 	if (f->f3.rd == 0xf) {
19117718SJason.Beloro@Sun.COM 		/* jpriv */
19127718SJason.Beloro@Sun.COM 		prt_address(dhp, instr, 1);
19137718SJason.Beloro@Sun.COM 	}
19147718SJason.Beloro@Sun.COM 
19155198Sjmcp 	return (0);
19165198Sjmcp }
19175198Sjmcp 
19185198Sjmcp /* ARGSUSED3 */
19195198Sjmcp int
fmt_movcc(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)19205198Sjmcp fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
19215198Sjmcp {
19225198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
19235198Sjmcp 	const char **regs = NULL;
19245198Sjmcp 
19255198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
19265198Sjmcp 		prt_field("op", f->f3c.op, 2);
19275198Sjmcp 		prt_field("op3", f->f3c.op3, 6);
19285198Sjmcp 		prt_field("cond", f->f3c.cond, 4);
19295198Sjmcp 		prt_field("cc2", f->f3c.cc2, 1);
19305198Sjmcp 		prt_field("cc", f->f3c.cc, 2);
19315198Sjmcp 		prt_field("i", f->f3c.i, 1);
19325198Sjmcp 
19335198Sjmcp 		if (f->f3c.i == 0)
19345198Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
19355198Sjmcp 		else
19365198Sjmcp 			prt_field("simm11", f->f3c.simm11, 11);
19375198Sjmcp 
19385198Sjmcp 		prt_field("rd", f->f3.rd, 5);
19395198Sjmcp 	}
19405198Sjmcp 
19415198Sjmcp 	if (f->f3c.cc2 == 0) {
19425198Sjmcp 		regs = fcc_names;
19435198Sjmcp 	} else {
19445198Sjmcp 		regs = icc_names;
19455198Sjmcp 		if (regs[f->f3c.cc] == NULL)
19465198Sjmcp 			return (-1);
19475198Sjmcp 	}
19485198Sjmcp 
19495198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
19505198Sjmcp 
19515198Sjmcp 	bprintf(dhp, "%s, ", regs[f->f3c.cc]);
19525198Sjmcp 
19535198Sjmcp 	if (f->f3c.i == 1)
19545198Sjmcp 		prt_imm(dhp, sign_extend(f->f3c.simm11, 11), IMM_SIGNED);
19555198Sjmcp 	else
19565198Sjmcp 		(void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
19575198Sjmcp 		    dhp->dh_buflen);
19585198Sjmcp 
19595198Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
19605198Sjmcp 
19615198Sjmcp 	return (0);
19625198Sjmcp }
19635198Sjmcp 
19645198Sjmcp /* ARGSUSED3 */
19655198Sjmcp int
fmt_movr(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)19665198Sjmcp fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
19675198Sjmcp {
19685198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
19695198Sjmcp 
19705198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
19715198Sjmcp 
19725198Sjmcp 	bprintf(dhp, "%s, ", reg_names[f->f3d.rs1]);
19735198Sjmcp 
19745198Sjmcp 	if (f->f3d.i == 1)
19755198Sjmcp 		prt_imm(dhp, sign_extend(f->f3d.simm10, 10), IMM_SIGNED);
19765198Sjmcp 	else
19775198Sjmcp 		(void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
19785198Sjmcp 		    dhp->dh_buflen);
19795198Sjmcp 
19805198Sjmcp 	bprintf(dhp, ", %s", reg_names[f->f3.rd]);
19815198Sjmcp 
19825198Sjmcp 	return (0);
19835198Sjmcp }
19845198Sjmcp 
19855198Sjmcp /* ARGSUSED3 */
19865198Sjmcp int
fmt_fpop1(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)19875198Sjmcp fmt_fpop1(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
19885198Sjmcp {
19895198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
19905198Sjmcp 	int flags = inp->in_data.in_def.in_flags;
19915198Sjmcp 
19925198Sjmcp 	flags |= FLG_NOIMM;
19935198Sjmcp 
19945198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
19955198Sjmcp 		prt_field("op", f->f3.op, 2);
19965198Sjmcp 		prt_field("op3", f->f3.op3, 6);
19975198Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
19985198Sjmcp 		prt_field("rs1", f->f3.rs1, 5);
19995198Sjmcp 		prt_field("rs2", f->f3.rs2, 5);
20005198Sjmcp 		prt_field("rd", f->f3.rd, 5);
20015198Sjmcp 	}
20025198Sjmcp 
20035198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
20045198Sjmcp 	prt_aluargs(dhp, instr, flags);
20055198Sjmcp 
20065198Sjmcp 	return (0);
20075198Sjmcp }
20085198Sjmcp 
20095198Sjmcp int
fmt_fpop2(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)20105198Sjmcp fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
20115198Sjmcp {
20125198Sjmcp 	static const char *condstr_icc[16] = {
20135198Sjmcp 		"n", "e",  "le", "l",  "leu", "lu",  "neg", "vs",
20145198Sjmcp 		"a", "nz", "g",  "ge", "gu",  "geu", "pos", "vc"
20155198Sjmcp 	};
20165198Sjmcp 
20175198Sjmcp 	static const char *condstr_fcc[16] = {
20185198Sjmcp 		"n", "nz", "lg", "ul", "l",   "ug", "g",   "u",
20195198Sjmcp 		"a", "e",  "ue", "ge", "uge", "le", "ule", "o"
20205198Sjmcp 	};
20215198Sjmcp 
20225198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
20235198Sjmcp 	const char *ccstr = "";
20245198Sjmcp 	char name[15];
20255198Sjmcp 
20265198Sjmcp 	int flags = inp->in_data.in_def.in_flags;
20275198Sjmcp 	int is_cmp = (idx == 0x51 || idx == 0x52 || idx == 0x53 ||
20285198Sjmcp 	    idx == 0x55 || idx == 0x56 || idx == 0x57);
20295198Sjmcp 	int is_fmov = (idx & 0x3f);
20305198Sjmcp 	int is_v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
20315198Sjmcp 	int is_compat = ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0);
20325198Sjmcp 
20335198Sjmcp 	int p_cc = 0;
20345198Sjmcp 
20355198Sjmcp 	is_fmov = (is_fmov == 0x1 || is_fmov == 0x2 || is_fmov == 0x3);
20365198Sjmcp 
20375198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
20385198Sjmcp 		prt_field("op", f->f3.op, 2);
20395198Sjmcp 		prt_field("op3", f->f3.op3, 6);
20405198Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
20415198Sjmcp 
20425198Sjmcp 		switch (idx & 0x3f) {
20435198Sjmcp 		case 0x51:
20445198Sjmcp 		case 0x52:
20455198Sjmcp 		case 0x53:
20465198Sjmcp 		case 0x55:
20475198Sjmcp 		case 0x56:
20485198Sjmcp 		case 0x57:
20495198Sjmcp 			prt_field("cc", f->fcmp.cc, 2);
20505198Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
20515198Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
20525198Sjmcp 			break;
20535198Sjmcp 
20545198Sjmcp 		case 0x01:
20555198Sjmcp 		case 0x02:
20565198Sjmcp 		case 0x03:
20575198Sjmcp 			prt_field("opf_low", f->fmv.opf, 6);
20585198Sjmcp 			prt_field("cond", f->fmv.cond, 4);
20595198Sjmcp 			prt_field("opf_cc", f->fmv.cc, 3);
20605198Sjmcp 			prt_field("rs2", f->fmv.rs2, 5);
20615198Sjmcp 			break;
20625198Sjmcp 
20635198Sjmcp 		default:
20645198Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
20655198Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
20665198Sjmcp 			prt_field("rd", f->f3.rd, 5);
20675198Sjmcp 		}
20685198Sjmcp 	}
20695198Sjmcp 
20705198Sjmcp 	name[0] = '\0';
20715198Sjmcp 	(void) strlcat(name, inp->in_data.in_def.in_name, sizeof (name));
20725198Sjmcp 
20735198Sjmcp 	if (is_fmov != 0) {
20745198Sjmcp 		(void) strlcat(name,
20755198Sjmcp 		    (f->fmv.cc < 4) ? condstr_fcc[f->fmv.cond]
20765198Sjmcp 		    : condstr_icc[f->fmv.cond],
20775198Sjmcp 		    sizeof (name));
20785198Sjmcp 	}
20795198Sjmcp 
20805198Sjmcp 	prt_name(dhp, name, 1);
20815198Sjmcp 
20825198Sjmcp 	if (is_cmp != 0)
20835198Sjmcp 		ccstr = fcc_names[f->fcmp.cc];
20845198Sjmcp 
20855198Sjmcp 	if (is_fmov != 0)
20865198Sjmcp 		ccstr = (f->fmv.cc < 4) ? fcc_names[f->fmv.cc & 0x3]
20875198Sjmcp 		    : icc_names[f->fmv.cc & 0x3];
20885198Sjmcp 
20895198Sjmcp 	if (ccstr == NULL)
20905198Sjmcp 		return (-1);
20915198Sjmcp 
20925198Sjmcp 	p_cc = (is_compat == 0 || is_v9 != 0 ||
20935198Sjmcp 	    (is_cmp != 0 && f->fcmp.cc != 0) ||
20945198Sjmcp 	    (is_fmov != 0 && f->fmv.cc != 0));
20955198Sjmcp 
20965198Sjmcp 	if (p_cc != 0)
20975198Sjmcp 		bprintf(dhp, "%s, ", ccstr);
20985198Sjmcp 
20995198Sjmcp 	prt_aluargs(dhp, instr, flags);
21005198Sjmcp 
21015198Sjmcp 	return (0);
21025198Sjmcp }
21035198Sjmcp 
21045198Sjmcp int
fmt_vis(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)21055198Sjmcp fmt_vis(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
21065198Sjmcp {
21075198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
21085198Sjmcp 	int flags = inp->in_data.in_def.in_flags;
21095198Sjmcp 
21105198Sjmcp 	if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
21115198Sjmcp 		prt_field("op", f->f3.op, 2);
21125198Sjmcp 		prt_field("op3", f->f3.op3, 6);
21135198Sjmcp 		prt_field("opf", f->fcmp.opf, 9);
21145198Sjmcp 
21155198Sjmcp 		if (idx == 0x081) {
21165198Sjmcp 			prt_field("mode", instr & 02L, 2);
21175198Sjmcp 		} else {
21185198Sjmcp 			prt_field("rs1", f->f3.rs1, 5);
21195198Sjmcp 			prt_field("rs2", f->f3.rs2, 5);
21205198Sjmcp 			prt_field("rd", f->f3.rd, 5);
21215198Sjmcp 		}
21225198Sjmcp 	}
21235198Sjmcp 
21245198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
21255198Sjmcp 
21265198Sjmcp 	if (idx == 0x081) {
21275198Sjmcp 		/* siam */
21285198Sjmcp 		bprintf(dhp, "%d", instr & 0x7L);
21295198Sjmcp 		return (0);
21305198Sjmcp 	}
21315198Sjmcp 
21325198Sjmcp 	prt_aluargs(dhp, instr, flags);
21335198Sjmcp 
21345198Sjmcp 	return (0);
21355198Sjmcp }
21365198Sjmcp 
21375198Sjmcp /* ARGSUSED3 */
21385198Sjmcp int
fmt_fused(dis_handle_t * dhp,uint32_t instr,const inst_t * inp,int idx)21395198Sjmcp fmt_fused(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
21405198Sjmcp {
21415198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
21425198Sjmcp 	int flags = inp->in_data.in_def.in_flags;
21435198Sjmcp 
21445198Sjmcp 	prt_name(dhp, inp->in_data.in_def.in_name, 1);
21455198Sjmcp 	bprintf(dhp, "%s, %s, %s, %s",
21465198Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs1),
21475198Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs2),
21485198Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rs3),
21495198Sjmcp 	    get_regname(dhp, FLG_P1_VAL(flags), f->fused.rd));
21505198Sjmcp 
21515198Sjmcp 	return (0);
21525198Sjmcp }
21535198Sjmcp /*
21545198Sjmcp  * put name into the output buffer
21555198Sjmcp  * if add_space !=0, append a space after it
21565198Sjmcp  */
21575198Sjmcp static void
prt_name(dis_handle_t * dhp,const char * name,int add_space)21585198Sjmcp prt_name(dis_handle_t *dhp, const char *name, int add_space)
21595198Sjmcp {
21605198Sjmcp 	bprintf(dhp, (add_space == 0) ? "%s" : "%-9s ", name);
21615198Sjmcp }
21625198Sjmcp 
21635198Sjmcp /*
21645198Sjmcp  * For debugging, print out a field of the instruction
21655198Sjmcp  * field is the name of the field
21665198Sjmcp  * val is the value of the field
21675198Sjmcp  * len is the length of the field (in bits)
21685198Sjmcp  */
21695198Sjmcp #if defined(DIS_STANDALONE)
21705198Sjmcp /* ARGSUSED */
21715198Sjmcp static void
prt_field(const char * field,uint32_t val,int len)21725198Sjmcp prt_field(const char *field, uint32_t val, int len)
21735198Sjmcp {
21745198Sjmcp 
21755198Sjmcp }
21765198Sjmcp 
21775198Sjmcp #else
21785198Sjmcp static void
prt_field(const char * field,uint32_t val,int len)21795198Sjmcp prt_field(const char *field, uint32_t val, int len)
21805198Sjmcp {
21818430Sjason@ansipunx.net 	(void) fprintf(stderr, "DISASM: %8s = 0x%-8x (", field, val);
21825198Sjmcp 	prt_binary(val, len);
21835198Sjmcp 	(void) fprintf(stderr, ")\n");
21845198Sjmcp }
21855198Sjmcp #endif /* DIS_STANDALONE */
21865198Sjmcp 
21875198Sjmcp /*
21885198Sjmcp  * sign extend a val (that is 'bits' bits in length) to a 32-bit signed
21895198Sjmcp  * integer
21905198Sjmcp  */
21915198Sjmcp static int32_t
sign_extend(int32_t val,int32_t bits)21925198Sjmcp sign_extend(int32_t val, int32_t bits)
21935198Sjmcp {
21945198Sjmcp 	if ((val & (1L << (bits - 1))) == 0)
21955198Sjmcp 		return (val);
21965198Sjmcp 
21975198Sjmcp 	return ((-1L << bits) | val);
21985198Sjmcp }
21995198Sjmcp 
22005198Sjmcp /*
22015198Sjmcp  * print out an immediate (i.e. constant) value
22025198Sjmcp  * val is the value
22035198Sjmcp  * format indicates if it is:
22045198Sjmcp  * 0		 Unsigned
22055198Sjmcp  * IMM_SIGNED  A signed value (prepend +/- to the value)
22065198Sjmcp  * IMM_ADDR    Part of an address expression (prepend +/- but with a space
22075198Sjmcp  *		   between the sign and the value for things like [%i1 + 0x55]
22085198Sjmcp  */
22095198Sjmcp static void
prt_imm(dis_handle_t * dhp,uint32_t val,int format)22105198Sjmcp prt_imm(dis_handle_t *dhp, uint32_t val, int format)
22115198Sjmcp {
22125198Sjmcp 	const char *fmtstr = NULL;
22135198Sjmcp 	int32_t sv = (int32_t)val;
22145198Sjmcp 	int octal = dhp->dh_flags & DIS_OCTAL;
22155198Sjmcp 
22165198Sjmcp 	switch (format) {
22175198Sjmcp 	case IMM_ADDR:
22185198Sjmcp 		if (sv < 0) {
22195198Sjmcp 			sv = -sv;
22205198Sjmcp 			fmtstr = (octal != 0) ? "- 0%lo" : "- 0x%lx";
22215198Sjmcp 		} else {
22225198Sjmcp 			fmtstr = (octal != 0) ? "+ 0%lo" : "+ 0x%lx";
22235198Sjmcp 		}
22245198Sjmcp 		break;
22255198Sjmcp 
22265198Sjmcp 	case IMM_SIGNED:
22275198Sjmcp 		if (sv < 0) {
22285198Sjmcp 			sv = -sv;
22295198Sjmcp 			fmtstr = (octal != 0) ? "-0%lo" : "-0x%lx";
22305198Sjmcp 			break;
22315198Sjmcp 		}
22325198Sjmcp 		/* fall through */
22335198Sjmcp 
22345198Sjmcp 	default:
22355198Sjmcp 		fmtstr = (octal != 0) ? "0%lo" : "0x%lx";
22365198Sjmcp 	}
22375198Sjmcp 
22385198Sjmcp 	bprintf(dhp, fmtstr, sv);
22395198Sjmcp }
22405198Sjmcp 
22415198Sjmcp /*
22425198Sjmcp  * return the symbolic name of a register
22435198Sjmcp  * regset is one of the REG_* values indicating which type of register it is
22445198Sjmcp  * such as integer, floating point, etc.
22455198Sjmcp  * idx is the numeric value of the register
22465198Sjmcp  *
22475198Sjmcp  * If regset is REG_NONE, an empty, but non-NULL string is returned
22485198Sjmcp  * NULL may be returned if the index indicates an invalid register value
22495198Sjmcp  * such as with the %icc/%xcc sets
22505198Sjmcp  */
22515198Sjmcp static const char *
get_regname(dis_handle_t * dhp,int regset,uint32_t idx)22525198Sjmcp get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
22535198Sjmcp {
22545198Sjmcp 	const char *regname = NULL;
22555198Sjmcp 
22565198Sjmcp 	switch (regset) {
22575198Sjmcp 	case REG_INT:
22585198Sjmcp 		regname = reg_names[idx];
22595198Sjmcp 		break;
22605198Sjmcp 
22615198Sjmcp 	case REG_FP:
22625198Sjmcp 		regname = freg_names[idx];
22635198Sjmcp 		break;
22645198Sjmcp 
22655198Sjmcp 	case REG_FPD:
22667718SJason.Beloro@Sun.COM 		if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) ||
22677718SJason.Beloro@Sun.COM 		    ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
22685198Sjmcp 			regname = fdreg_names[idx];
22695198Sjmcp 		else
22705198Sjmcp 			regname = compat_fdreg_names[idx];
22715198Sjmcp 
22725198Sjmcp 		break;
22735198Sjmcp 
22745198Sjmcp 	case REG_FPQ:
22755198Sjmcp 		if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
22765198Sjmcp 			regname = fqreg_names[idx];
22775198Sjmcp 		else
22785198Sjmcp 			regname = freg_names[idx];
22795198Sjmcp 
22805198Sjmcp 		break;
22815198Sjmcp 
22825198Sjmcp 	case REG_CP:
22835198Sjmcp 		regname = cpreg_names[idx];
22845198Sjmcp 		break;
22855198Sjmcp 
22865198Sjmcp 	case REG_ICC:
22875198Sjmcp 		regname = icc_names[idx];
22885198Sjmcp 		break;
22895198Sjmcp 
22905198Sjmcp 	case REG_FCC:
22915198Sjmcp 		regname = fcc_names[idx];
22925198Sjmcp 		break;
22935198Sjmcp 
22945198Sjmcp 	case REG_FSR:
22955198Sjmcp 		regname = "%fsr";
22965198Sjmcp 		break;
22975198Sjmcp 
22985198Sjmcp 	case REG_CSR:
22995198Sjmcp 		regname = "%csr";
23005198Sjmcp 		break;
23015198Sjmcp 
23025198Sjmcp 	case REG_CQ:
23035198Sjmcp 		regname = "%cq";
23045198Sjmcp 		break;
23055198Sjmcp 
23065198Sjmcp 	case REG_NONE:
23075198Sjmcp 		regname = "";
23085198Sjmcp 		break;
23095198Sjmcp 	}
23105198Sjmcp 
23115198Sjmcp 	return (regname);
23125198Sjmcp }
23135198Sjmcp 
23145198Sjmcp /*
23155198Sjmcp  * output the asi value from the instruction
23165198Sjmcp  *
23175198Sjmcp  * TODO: investigate if this should perhaps have a mask -- are undefined ASI
23185198Sjmcp  *	  values for an instruction still disassembled??
23195198Sjmcp  */
23205198Sjmcp static void
prt_asi(dis_handle_t * dhp,uint32_t instr)23215198Sjmcp prt_asi(dis_handle_t *dhp, uint32_t instr)
23225198Sjmcp {
23235198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
23245198Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
23255198Sjmcp 
23265198Sjmcp 	if (f->f3.i != 0)
23275198Sjmcp 		bprintf(dhp, "%%asi");
23285198Sjmcp 	else
23295198Sjmcp 		bprintf(dhp, (octal != 0) ? "0%03o" : "0x%02x", f->f3.asi);
23305198Sjmcp 
23315198Sjmcp }
23325198Sjmcp 
23335198Sjmcp /*
23345198Sjmcp  * put an address expression into the output buffer
23355198Sjmcp  *
23365198Sjmcp  * instr is the instruction to use
23375198Sjmcp  * if nobrackets != 0, [] are not added around the instruction
23385198Sjmcp  *
23395198Sjmcp  * Currently this option is set when printing out the address portion
23405198Sjmcp  * of a jmpl instruction, but otherwise 0 for load/stores
23415198Sjmcp  *
23425198Sjmcp  * If no debug flags are set, the full expression is output, even when
23435198Sjmcp  * %g0 or 0x0 appears in the address
23445198Sjmcp  *
23455198Sjmcp  * If DIS_DEBUG_SYN_ALL or DIS_DEBUG_COMPAT are set, when %g0 or 0x0
23465198Sjmcp  * appear in the address, they are not output.  If the wierd (and probably
23475198Sjmcp  * shouldn't happen) address of [%g0 + %g0] or [%g0 + 0x0] is encountered,
23485198Sjmcp  * [%g0] is output
23495198Sjmcp  */
23505198Sjmcp static void
prt_address(dis_handle_t * dhp,uint32_t instr,int nobrackets)23515198Sjmcp prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
23525198Sjmcp {
23535198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
23545198Sjmcp 	int32_t simm13;
23555198Sjmcp 	int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
23565198Sjmcp 	int p1 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
23575198Sjmcp 	int p2 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
23585198Sjmcp 
23595198Sjmcp 	if (f->f3a.i == 0) {
23605198Sjmcp 		p1 |= ((f->f3a.rs1 != 0) || f->f3.rs2 == 0);
23615198Sjmcp 		p2 |= (f->f3.rs2 != 0);
23625198Sjmcp 
23635198Sjmcp 		bprintf(dhp, "%s%s%s%s%s",
23645198Sjmcp 		    (nobrackets == 0) ? "[" : "",
23655198Sjmcp 		    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
23665198Sjmcp 		    (p1 != 0 && p2 != 0) ? " + " : "",
23675198Sjmcp 		    (p2 != 0) ? reg_names[f->f3.rs2] : "",
23685198Sjmcp 		    (nobrackets == 0) ? "]" : "");
23695198Sjmcp 	} else {
23705198Sjmcp 		const char *sign;
23715198Sjmcp 
23725198Sjmcp 		simm13 = sign_extend(f->f3a.simm13, 13);
23735198Sjmcp 		sign = (simm13 < 0) ? "-" : "+";
23745198Sjmcp 
23755198Sjmcp 		p1 |= (f->f3a.rs1 != 0);
23765198Sjmcp 		p2 |= (p1 == 0 || simm13 != 0);
23775198Sjmcp 
23785198Sjmcp 		if (p1 == 0 && simm13 == 0)
23795198Sjmcp 			p2 = 1;
23805198Sjmcp 
23815198Sjmcp 		if (p1 == 0 && simm13 >= 0)
23825198Sjmcp 			sign = "";
23835198Sjmcp 
23845198Sjmcp 		if (p2 != 0)
23855198Sjmcp 			bprintf(dhp,
23865198Sjmcp 			    (octal != 0) ? "%s%s%s%s%s0%lo%s" :
23875198Sjmcp 			    "%s%s%s%s%s0x%lx%s",
23885198Sjmcp 			    (nobrackets == 0) ? "[" : "",
23895198Sjmcp 			    (p1 != 0) ? reg_names[f->f3a.rs1] : "",
23905198Sjmcp 			    (p1 != 0) ? " " : "",
23915198Sjmcp 			    sign,
23925198Sjmcp 			    (p1 != 0) ? " " : "",
23935198Sjmcp 			    (simm13 < 0) ? -(simm13) : simm13,
23945198Sjmcp 			    (nobrackets == 0) ? "]" : "");
23955198Sjmcp 		else
23965198Sjmcp 			bprintf(dhp, "%s%s%s",
23975198Sjmcp 			    (nobrackets == 0) ? "[" : "",
23985198Sjmcp 			    reg_names[f->f3a.rs1],
23995198Sjmcp 			    (nobrackets == 0) ? "]" : "");
24005198Sjmcp 	}
24015198Sjmcp }
24025198Sjmcp 
24035198Sjmcp /*
24045198Sjmcp  * print out the arguments to an alu operation (add, sub, etc.)
24055198Sjmcp  * conatined in 'instr'
24065198Sjmcp  *
24075198Sjmcp  * alu instructions have the following format:
24085198Sjmcp  *	 %rs1, %rs2, %rd    (i == 0)
24095198Sjmcp  *	 %rs1, 0xnnn, %rd   (i == 1)
24105198Sjmcp  *	   ^	^	^
24115198Sjmcp  *	   |	|	|
24125198Sjmcp  *	  p1    p2	p3
24135198Sjmcp  *
24145198Sjmcp  * flags indicates the register set to use for each position (p1, p2, p3)
24155198Sjmcp  * as well as if immediate values (i == 1) are allowed
24165198Sjmcp  *
24175198Sjmcp  * if flags indicates a specific position has REG_NONE set as it's register
24185198Sjmcp  * set, it is omitted from the output.  This is primarly used for certain
24195198Sjmcp  * floating point operations
24205198Sjmcp  */
24215198Sjmcp static void
prt_aluargs(dis_handle_t * dhp,uint32_t instr,uint32_t flags)24225198Sjmcp prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
24235198Sjmcp {
24245198Sjmcp 	ifmt_t *f = (ifmt_t *)&instr;
24255198Sjmcp 	const char *r1, *r2, *r3;
24265198Sjmcp 	int p1, p2, p3;
24277718SJason.Beloro@Sun.COM 	unsigned int opf = 0;
24285198Sjmcp 
24295198Sjmcp 	r1 = get_regname(dhp, FLG_P1_VAL(flags), f->f3.rs1);
24305198Sjmcp 	r2 = get_regname(dhp, FLG_P2_VAL(flags), f->f3.rs2);
24315198Sjmcp 	r3 = get_regname(dhp, FLG_P3_VAL(flags), f->f3.rd);
24325198Sjmcp 
24335198Sjmcp 	p1 = (FLG_P1_VAL(flags) != REG_NONE);
24345198Sjmcp 	p2 = (((flags & FLG_NOIMM) == 0) || (FLG_P2_VAL(flags) != REG_NONE));
24355198Sjmcp 	p3 = (FLG_RD_VAL(flags) != REG_NONE);
24365198Sjmcp 
24375198Sjmcp 	if (r1 == NULL || r1[0] == '\0')
24385198Sjmcp 		p1 = 0;
24395198Sjmcp 
24405198Sjmcp 	if (f->f3a.i == 0 && (r2 == NULL || r2[0] == '\0'))
24415198Sjmcp 		p2 = 0;
24425198Sjmcp 
24435198Sjmcp 	if (r3 == NULL || r3[0] == '\0')
24445198Sjmcp 		p3 = 0;
24455198Sjmcp 
24467718SJason.Beloro@Sun.COM 	if ((f->fcmp.op == 2) && (f->fcmp.op3 == 0x36) && (f->fcmp.cc != 0))
24477718SJason.Beloro@Sun.COM 		opf = f->fcmp.opf;
24487718SJason.Beloro@Sun.COM 
24497718SJason.Beloro@Sun.COM 	if ((opf == 0x151) || (opf == 0x152)) {
24507718SJason.Beloro@Sun.COM 		(void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
24517718SJason.Beloro@Sun.COM 		(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
24527718SJason.Beloro@Sun.COM 		p3 = 0;
24537718SJason.Beloro@Sun.COM 	}
24547718SJason.Beloro@Sun.COM 
24555198Sjmcp 	if (p1 != 0) {
24565198Sjmcp 		(void) strlcat(dhp->dh_buf, r1, dhp->dh_buflen);
24575198Sjmcp 		if (p2 != 0 || p3 != 0)
24585198Sjmcp 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
24595198Sjmcp 	}
24605198Sjmcp 
24615198Sjmcp 	if (p2 != 0) {
24625198Sjmcp 		if (f->f3.i == 0 || ((flags & FLG_NOIMM) != 0))
24635198Sjmcp 			(void) strlcat(dhp->dh_buf, r2, dhp->dh_buflen);
24645198Sjmcp 		else
24655198Sjmcp 			prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
24665198Sjmcp 			    IMM_SIGNED);
24675198Sjmcp 
24685198Sjmcp 		if (p3 != 0)
24695198Sjmcp 			(void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
24705198Sjmcp 	}
24715198Sjmcp 
24725198Sjmcp 	if (p3 != 0)
24735198Sjmcp 		(void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
24745198Sjmcp }
24755198Sjmcp 
24768430Sjason@ansipunx.net static const char *
get_asi_name(uint8_t asi)24778430Sjason@ansipunx.net get_asi_name(uint8_t asi)
24788430Sjason@ansipunx.net {
24798430Sjason@ansipunx.net 	switch (asi) {
24808430Sjason@ansipunx.net 		case 0x04:
24818430Sjason@ansipunx.net 			return ("ASI_N");
24828430Sjason@ansipunx.net 
24838430Sjason@ansipunx.net 		case 0x0c:
24848430Sjason@ansipunx.net 			return ("ASI_NL");
24858430Sjason@ansipunx.net 
24868430Sjason@ansipunx.net 		case 0x10:
24878430Sjason@ansipunx.net 			return ("ASI_AIUP");
24888430Sjason@ansipunx.net 
24898430Sjason@ansipunx.net 		case 0x11:
24908430Sjason@ansipunx.net 			return ("ASI_AIUS");
24918430Sjason@ansipunx.net 
24928430Sjason@ansipunx.net 		case 0x14:
24938430Sjason@ansipunx.net 			return ("ASI_REAL");
24948430Sjason@ansipunx.net 
24958430Sjason@ansipunx.net 		case 0x15:
24968430Sjason@ansipunx.net 			return ("ASI_REAL_IO");
24978430Sjason@ansipunx.net 
24988430Sjason@ansipunx.net 		case 0x16:
24998430Sjason@ansipunx.net 			return ("ASI_BLK_AIUP");
25008430Sjason@ansipunx.net 
25018430Sjason@ansipunx.net 		case 0x17:
25028430Sjason@ansipunx.net 			return ("ASI_BLK_AIUS");
25038430Sjason@ansipunx.net 
25048430Sjason@ansipunx.net 		case 0x18:
25058430Sjason@ansipunx.net 			return ("ASI_AIUPL");
25068430Sjason@ansipunx.net 
25078430Sjason@ansipunx.net 		case 0x19:
25088430Sjason@ansipunx.net 			return ("ASI_AIUSL");
25098430Sjason@ansipunx.net 
25108430Sjason@ansipunx.net 		case 0x1c:
25118430Sjason@ansipunx.net 			return ("ASI_REAL_L");
25128430Sjason@ansipunx.net 
25138430Sjason@ansipunx.net 		case 0x1d:
25148430Sjason@ansipunx.net 			return ("ASI_REAL_IO_L");
25158430Sjason@ansipunx.net 
25168430Sjason@ansipunx.net 		case 0x1e:
25178430Sjason@ansipunx.net 			return ("ASI_BLK_AIUPL");
25188430Sjason@ansipunx.net 
25198430Sjason@ansipunx.net 		case 0x1f:
25208430Sjason@ansipunx.net 			return ("ASI_BLK_AIUS_L");
25218430Sjason@ansipunx.net 
25228430Sjason@ansipunx.net 		case 0x20:
25238430Sjason@ansipunx.net 			return ("ASI_SCRATCHPAD");
25248430Sjason@ansipunx.net 
25258430Sjason@ansipunx.net 		case 0x21:
25268430Sjason@ansipunx.net 			return ("ASI_MMU_CONTEXTID");
25278430Sjason@ansipunx.net 
25288430Sjason@ansipunx.net 		case 0x22:
25298430Sjason@ansipunx.net 			return ("ASI_TWINX_AIUP");
25308430Sjason@ansipunx.net 
25318430Sjason@ansipunx.net 		case 0x23:
25328430Sjason@ansipunx.net 			return ("ASI_TWINX_AIUS");
25338430Sjason@ansipunx.net 
25348430Sjason@ansipunx.net 		case 0x25:
25358430Sjason@ansipunx.net 			return ("ASI_QUEUE");
25368430Sjason@ansipunx.net 
25378430Sjason@ansipunx.net 		case 0x26:
25388430Sjason@ansipunx.net 			return ("ASI_TWINX_R");
25398430Sjason@ansipunx.net 
25408430Sjason@ansipunx.net 		case 0x27:
25418430Sjason@ansipunx.net 			return ("ASI_TWINX_N");
25428430Sjason@ansipunx.net 
25438430Sjason@ansipunx.net 		case 0x2a:
25448430Sjason@ansipunx.net 			return ("ASI_LDTX_AIUPL");
25458430Sjason@ansipunx.net 
25468430Sjason@ansipunx.net 		case 0x2b:
25478430Sjason@ansipunx.net 			return ("ASI_TWINX_AIUS_L");
25488430Sjason@ansipunx.net 
25498430Sjason@ansipunx.net 		case 0x2e:
25508430Sjason@ansipunx.net 			return ("ASI_TWINX_REAL_L");
25518430Sjason@ansipunx.net 
25528430Sjason@ansipunx.net 		case 0x2f:
25538430Sjason@ansipunx.net 			return ("ASI_TWINX_NL");
25548430Sjason@ansipunx.net 
25558430Sjason@ansipunx.net 		case 0x30:
25568430Sjason@ansipunx.net 			return ("ASI_AIPP");
25578430Sjason@ansipunx.net 
25588430Sjason@ansipunx.net 		case 0x31:
25598430Sjason@ansipunx.net 			return ("ASI_AIPS");
25608430Sjason@ansipunx.net 
25618430Sjason@ansipunx.net 		case 0x36:
25628430Sjason@ansipunx.net 			return ("ASI_AIPN");
25638430Sjason@ansipunx.net 
25648430Sjason@ansipunx.net 		case 0x38:
25658430Sjason@ansipunx.net 			return ("ASI_AIPP_L");
25668430Sjason@ansipunx.net 
25678430Sjason@ansipunx.net 		case 0x39:
25688430Sjason@ansipunx.net 			return ("ASI_AIPS_L");
25698430Sjason@ansipunx.net 
25708430Sjason@ansipunx.net 		case 0x3e:
25718430Sjason@ansipunx.net 			return ("ASI_AIPN_L");
25728430Sjason@ansipunx.net 
25738430Sjason@ansipunx.net 		case 0x41:
25748430Sjason@ansipunx.net 			return ("ASI_CMT_SHARED");
25758430Sjason@ansipunx.net 
25768430Sjason@ansipunx.net 		case 0x4f:
25778430Sjason@ansipunx.net 			return ("ASI_HYP_SCRATCHPAD");
25788430Sjason@ansipunx.net 
25798430Sjason@ansipunx.net 		case 0x50:
25808430Sjason@ansipunx.net 			return ("ASI_IMMU");
25818430Sjason@ansipunx.net 
25828430Sjason@ansipunx.net 		case 0x52:
25838430Sjason@ansipunx.net 			return ("ASI_MMU_REAL");
25848430Sjason@ansipunx.net 
25858430Sjason@ansipunx.net 		case 0x54:
25868430Sjason@ansipunx.net 			return ("ASI_MMU");
25878430Sjason@ansipunx.net 
25888430Sjason@ansipunx.net 		case 0x55:
25898430Sjason@ansipunx.net 			return ("ASI_ITLB_DATA_ACCESS_REG");
25908430Sjason@ansipunx.net 
25918430Sjason@ansipunx.net 		case 0x56:
25928430Sjason@ansipunx.net 			return ("ASI_ITLB_TAG_READ_REG");
25938430Sjason@ansipunx.net 
25948430Sjason@ansipunx.net 		case 0x57:
25958430Sjason@ansipunx.net 			return ("ASI_IMMU_DEMAP");
25968430Sjason@ansipunx.net 
25978430Sjason@ansipunx.net 		case 0x58:
25988430Sjason@ansipunx.net 			return ("ASI_DMMU / ASI_UMMU");
25998430Sjason@ansipunx.net 
26008430Sjason@ansipunx.net 		case 0x5c:
26018430Sjason@ansipunx.net 			return ("ASI_DTLB_DATA_IN_REG");
26028430Sjason@ansipunx.net 
26038430Sjason@ansipunx.net 		case 0x5d:
26048430Sjason@ansipunx.net 			return ("ASI_DTLB_DATA_ACCESS_REG");
26058430Sjason@ansipunx.net 
26068430Sjason@ansipunx.net 		case 0x5e:
26078430Sjason@ansipunx.net 			return ("ASI_DTLB_TAG_READ_REG");
26088430Sjason@ansipunx.net 
26098430Sjason@ansipunx.net 		case 0x5f:
26108430Sjason@ansipunx.net 			return ("ASI_DMMU_DEMAP");
26118430Sjason@ansipunx.net 
26128430Sjason@ansipunx.net 		case 0x63:
26138430Sjason@ansipunx.net 			return ("ASI_CMT_PER_STRAND / ASI_CMT_PER_CORE");
26148430Sjason@ansipunx.net 
26158430Sjason@ansipunx.net 		case 0x80:
26168430Sjason@ansipunx.net 			return ("ASI_P");
26178430Sjason@ansipunx.net 
26188430Sjason@ansipunx.net 		case 0x81:
26198430Sjason@ansipunx.net 			return ("ASI_S");
26208430Sjason@ansipunx.net 
26218430Sjason@ansipunx.net 		case 0x82:
26228430Sjason@ansipunx.net 			return ("ASI_PNF");
26238430Sjason@ansipunx.net 
26248430Sjason@ansipunx.net 		case 0x83:
26258430Sjason@ansipunx.net 			return ("ASI_SNF");
26268430Sjason@ansipunx.net 
26278430Sjason@ansipunx.net 		case 0x88:
26288430Sjason@ansipunx.net 			return ("ASI_PL");
26298430Sjason@ansipunx.net 
26308430Sjason@ansipunx.net 		case 0x89:
26318430Sjason@ansipunx.net 			return ("ASI_SL");
26328430Sjason@ansipunx.net 
26338430Sjason@ansipunx.net 		case 0x8a:
26348430Sjason@ansipunx.net 			return ("ASI_PNFL");
26358430Sjason@ansipunx.net 
26368430Sjason@ansipunx.net 		case 0x8b:
26378430Sjason@ansipunx.net 			return ("ASI_SNFL");
26388430Sjason@ansipunx.net 
26398430Sjason@ansipunx.net 		case 0xc0:
26408430Sjason@ansipunx.net 			return ("ASI_PST8_P");
26418430Sjason@ansipunx.net 
26428430Sjason@ansipunx.net 		case 0xc1:
26438430Sjason@ansipunx.net 			return ("ASI_PST8_S");
26448430Sjason@ansipunx.net 
26458430Sjason@ansipunx.net 		case 0xc2:
26468430Sjason@ansipunx.net 			return ("ASI_PST16_P");
26478430Sjason@ansipunx.net 
26488430Sjason@ansipunx.net 		case 0xc3:
26498430Sjason@ansipunx.net 			return ("ASI_PST16_S");
26508430Sjason@ansipunx.net 
26518430Sjason@ansipunx.net 		case 0xc4:
26528430Sjason@ansipunx.net 			return ("ASI_PST32_P");
26538430Sjason@ansipunx.net 
26548430Sjason@ansipunx.net 		case 0xc5:
26558430Sjason@ansipunx.net 			return ("ASI_PST32_S");
26568430Sjason@ansipunx.net 
26578430Sjason@ansipunx.net 		case 0xc8:
26588430Sjason@ansipunx.net 			return ("ASI_PST8_PL");
26598430Sjason@ansipunx.net 
26608430Sjason@ansipunx.net 		case 0xc9:
26618430Sjason@ansipunx.net 			return ("ASI_PST8_SL");
26628430Sjason@ansipunx.net 
26638430Sjason@ansipunx.net 		case 0xca:
26648430Sjason@ansipunx.net 			return ("ASI_PST16_PL");
26658430Sjason@ansipunx.net 
26668430Sjason@ansipunx.net 		case 0xcb:
26678430Sjason@ansipunx.net 			return ("ASI_PST16_SL");
26688430Sjason@ansipunx.net 
26698430Sjason@ansipunx.net 		case 0xcc:
26708430Sjason@ansipunx.net 			return ("ASI_PST32_PL");
26718430Sjason@ansipunx.net 
26728430Sjason@ansipunx.net 		case 0xcd:
26738430Sjason@ansipunx.net 			return ("ASI_PST32_SL");
26748430Sjason@ansipunx.net 
26758430Sjason@ansipunx.net 		case 0xd0:
26768430Sjason@ansipunx.net 			return ("ASI_FL8_P");
26778430Sjason@ansipunx.net 
26788430Sjason@ansipunx.net 		case 0xd1:
26798430Sjason@ansipunx.net 			return ("ASI_FL8_S");
26808430Sjason@ansipunx.net 
26818430Sjason@ansipunx.net 		case 0xd2:
26828430Sjason@ansipunx.net 			return ("ASI_FL16_P");
26838430Sjason@ansipunx.net 
26848430Sjason@ansipunx.net 		case 0xd3:
26858430Sjason@ansipunx.net 			return ("ASI_FL16_S");
26868430Sjason@ansipunx.net 
26878430Sjason@ansipunx.net 		case 0xd8:
26888430Sjason@ansipunx.net 			return ("ASI_FL8_PL");
26898430Sjason@ansipunx.net 
26908430Sjason@ansipunx.net 		case 0xd9:
26918430Sjason@ansipunx.net 			return ("ASI_FL8_SL");
26928430Sjason@ansipunx.net 
26938430Sjason@ansipunx.net 		case 0xda:
26948430Sjason@ansipunx.net 			return ("ASI_FL16_PL");
26958430Sjason@ansipunx.net 
26968430Sjason@ansipunx.net 		case 0xdb:
26978430Sjason@ansipunx.net 			return ("ASI_FL16_SL");
26988430Sjason@ansipunx.net 
26998430Sjason@ansipunx.net 		case 0xe0:
27008430Sjason@ansipunx.net 			return ("ASI_BLK_COMMIT_P");
27018430Sjason@ansipunx.net 
27028430Sjason@ansipunx.net 		case 0xe1:
27038430Sjason@ansipunx.net 			return ("ASI_BLK_SOMMIT_S");
27048430Sjason@ansipunx.net 
27058430Sjason@ansipunx.net 		case 0xe2:
27068430Sjason@ansipunx.net 			return ("ASI_TWINX_P");
27078430Sjason@ansipunx.net 
27088430Sjason@ansipunx.net 		case 0xe3:
27098430Sjason@ansipunx.net 			return ("ASI_TWINX_S");
27108430Sjason@ansipunx.net 
27118430Sjason@ansipunx.net 		case 0xea:
27128430Sjason@ansipunx.net 			return ("ASI_TWINX_PL");
27138430Sjason@ansipunx.net 
27148430Sjason@ansipunx.net 		case 0xeb:
27158430Sjason@ansipunx.net 			return ("ASI_TWINX_SL");
27168430Sjason@ansipunx.net 
27178430Sjason@ansipunx.net 		case 0xf0:
27188430Sjason@ansipunx.net 			return ("ASI_BLK_P");
27198430Sjason@ansipunx.net 
27208430Sjason@ansipunx.net 		case 0xf1:
27218430Sjason@ansipunx.net 			return ("ASI_BLK_S");
27228430Sjason@ansipunx.net 
27238430Sjason@ansipunx.net 		case 0xf8:
27248430Sjason@ansipunx.net 			return ("ASI_BLK_PL");
27258430Sjason@ansipunx.net 
27268430Sjason@ansipunx.net 		case 0xf9:
27278430Sjason@ansipunx.net 			return ("ASI_BLK_SL");
27288430Sjason@ansipunx.net 
27298430Sjason@ansipunx.net 		default:
27308430Sjason@ansipunx.net 			return (NULL);
27318430Sjason@ansipunx.net 	}
27328430Sjason@ansipunx.net }
27338430Sjason@ansipunx.net 
27345198Sjmcp /*
27355198Sjmcp  * just a handy function that takes care of managing the buffer length
27365198Sjmcp  * w/ printf
27375198Sjmcp  */
27385198Sjmcp 
27395198Sjmcp /*
27405198Sjmcp  * PRINTF LIKE 1
27415198Sjmcp  */
27425198Sjmcp static void
bprintf(dis_handle_t * dhp,const char * fmt,...)27435198Sjmcp bprintf(dis_handle_t *dhp, const char *fmt, ...)
27445198Sjmcp {
27455198Sjmcp 	size_t curlen;
27465198Sjmcp 	va_list ap;
27475198Sjmcp 
27485198Sjmcp 	curlen = strlen(dhp->dh_buf);
27495198Sjmcp 
27505198Sjmcp 	va_start(ap, fmt);
27515198Sjmcp 	(void) vsnprintf(dhp->dh_buf + curlen, dhp->dh_buflen - curlen, fmt,
27525198Sjmcp 	    ap);
27535198Sjmcp 	va_end(ap);
27545198Sjmcp }
2755