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