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