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