Home | History | Annotate | Line # | Download | only in mips
      1 /*	$NetBSD: db_disasm.c,v 1.43 2021/05/23 23:22:55 dholland Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1991, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Ralph Campbell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  *
     34  *	from: @(#)kadb.c	8.1 (Berkeley) 6/10/93
     35  */
     36 
     37 #include <sys/cdefs.h>
     38 __KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.43 2021/05/23 23:22:55 dholland Exp $");
     39 
     40 #include <sys/param.h>
     41 #include <sys/cpu.h>
     42 #include <sys/systm.h>
     43 
     44 #include <mips/locore.h>
     45 #include <mips/mips_opcode.h>
     46 #include <mips/reg.h>
     47 
     48 #include <machine/db_machdep.h>
     49 
     50 #include <ddb/db_access.h>
     51 #include <ddb/db_user.h>
     52 #include <ddb/db_interface.h>
     53 #include <ddb/db_output.h>
     54 #include <ddb/db_extern.h>
     55 #include <ddb/db_sym.h>
     56 
     57 static const char * const op_name[64] = {
     58 /* 0 */ "spec", "regimm","j",	"jal",	"beq",	"bne",	"blez", "bgtz",
     59 /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori",	"xori", "lui",
     60 /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
     61 /*24 */ "daddi","daddiu","ldl", "ldr",	"op34", "op35", "op36", "op37",
     62 /*32 */ "lb",	"lh",	"lwl",	"lw",	"lbu",	"lhu",	"lwr",	"lwu",
     63 /*40 */ "sb",	"sh",	"swl",	"sw",	"sdl",	"sdr",	"swr",	"cache",
     64 #ifdef __OCTEON__
     65 /*48 */ "ll",	"lwc1", "bbit0", "lwc3", "lld",	"ldc1", "bbit032", "ld",
     66 /*56 */ "sc",	"swc1", "bbit1", "swc3", "scd",	"sdc1", "bbit132", "sd"
     67 #else
     68 /*48 */ "ll",	"lwc1", "lwc2", "lwc3", "lld",	"ldc1", "ldc2", "ld",
     69 /*56 */ "sc",	"swc1", "swc2", "swc3", "scd",	"sdc1", "sdc2", "sd"
     70 #endif
     71 };
     72 
     73 static const char * const spec_name[64] = {
     74 /* 0 */ "sll",	"movc1","srl", "sra",	"sllv", "spec05","srlv","srav",
     75 /* 8 */ "jr",	"jalr", "movz","movn","syscall","break","spec16","sync",
     76 /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
     77 /*24 */ "mult", "multu","div",	"divu", "dmult","dmultu","ddiv","ddivu",
     78 /*32 */ "add",	"addu", "sub",	"subu", "and",	"or",	"xor",	"nor",
     79 /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
     80 /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
     81 /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
     82 };
     83 
     84 static const char * const spec2_name[64] = {	/* QED, MIPS32/64, etc. */
     85 	[OP_MADD] = "madd",
     86 	[OP_MADDU] = "maddu",
     87 	[OP_MUL] = "mul",
     88 #ifdef __OCTEON__
     89 	[OP_CVM_DMUL] = "dmul",
     90 #endif
     91 	[OP_MSUB] = "msub",
     92 	[OP_MSUBU] = "msubu",
     93 	[OP_CLZ] = "clz",
     94 	[OP_CLO] = "clo",
     95 	[OP_DCLZ] = "dclz",
     96 	[OP_DCLO] = "dclo",
     97 #ifdef __OCTEON__
     98 	[OP_CVM_BADDU] = "baddu",
     99 	[OP_CVM_POP] = "pop",
    100 	[OP_CVM_DPOP] = "dpop",
    101 	[OP_CVM_CINS] = "cins",
    102 	[OP_CVM_CINS32] = "cins32",
    103 	[OP_CVM_EXTS] = "exts",
    104 	[OP_CVM_EXTS32] = "exts32",
    105 	[OP_CVM_SEQ] = "seq",
    106 	[OP_CVM_SEQI] = "seqi",
    107 	[OP_CVM_SNE] = "sne",
    108 	[OP_CVM_SNEI] = "snei",
    109 	[OP_CVM_SAA] = "saa",
    110 	[OP_CVM_SAAD] = "saad",
    111 #endif
    112 	[OP_SDBBP] = "sdbbp",
    113 };
    114 
    115 static const char * const spec3_name[64] = {
    116 	[OP_EXT] = "ext",
    117 	[OP_DEXTM] = "dextm",
    118 	[OP_DEXTU] = "dextu",
    119 	[OP_DEXT] = "dext",
    120 	[OP_INS] = "ins",
    121 	[OP_DINSM] = "dinsm",
    122 	[OP_DINSU] = "dinsu",
    123 	[OP_DINS] = "dins",
    124 	[OP_LWLE] = "lwle",
    125 	[OP_LWRE] = "lwre",
    126 	[OP_CACHEE] = "cachee",
    127 	[OP_SBE] = "sbe",
    128 	[OP_SHE] = "she",
    129 	[OP_SCE] = "sce",
    130 	[OP_SWE] = "swe",
    131 	[OP_BSHFL] = "bshfl",
    132 	[OP_SWLE] = "swle",
    133 	[OP_SWRE] = "swre",
    134 	[OP_PREFE] = "prefe",
    135 	[OP_DBSHFL] = "dbshfl",
    136 	[OP_CACHE_R6] = "cache",
    137 	[OP_LBUE] = "lbue",
    138 	[OP_LHUE] = "lhue",
    139 	[OP_LBE] = "lbe",
    140 	[OP_LHE] = "lhe",
    141 	[OP_LLE] = "lle",
    142 	[OP_LWE] = "lwe",
    143 	[OP_RDHWR] = "rdhwr",
    144 };
    145 
    146 static const char * const regimm_name[32] = {
    147 /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
    148 /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
    149 /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
    150 /*24 */ "?", "?", "?", "?", "bposge32", "?", "?", "?",
    151 };
    152 
    153 static const char * const cop1_name[64] = {
    154 /* 0 */ "fadd",  "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
    155 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
    156 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
    157 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
    158 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
    159 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
    160 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
    161 	"fcmp.ole","fcmp.ule",
    162 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
    163 	"fcmp.le","fcmp.ngt"
    164 };
    165 
    166 static const char * const fmt_name[16] = {
    167 	"s",	"d",	"e",	"fmt3",
    168 	"w",	"fmt5", "fmt6", "fmt7",
    169 	"fmt8", "fmt9", "fmta", "fmtb",
    170 	"fmtc", "fmtd", "fmte", "fmtf"
    171 };
    172 
    173 #if defined(__mips_n32) || defined(__mips_n64)
    174 static const char * const reg_name[32] = {
    175 	"zero", "at",	"v0",	"v1",	"a0",	"a1",	"a2",	"a3",
    176 	"a4",	"a5",	"a6",	"a7",	"t0",	"t1",	"t2",	"t3",
    177 	"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",
    178 	"t8",	"t9",	"k0",	"k1",	"gp",	"sp",	"s8",	"ra"
    179 };
    180 #else
    181 static const char * const reg_name[32] = {
    182 	"zero", "at",	"v0",	"v1",	"a0",	"a1",	"a2",	"a3",
    183 	"t0",	"t1",	"t2",	"t3",	"t4",	"t5",	"t6",	"t7",
    184 	"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",
    185 	"t8",	"t9",	"k0",	"k1",	"gp",	"sp",	"s8",	"ra"
    186 };
    187 #endif /* __mips_n32 || __mips_n64 */
    188 
    189 static const char * const c0_opname[64] = {
    190 	"c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
    191 	"tlbp",	 "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
    192 	"rfe",	 "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
    193 	"eret",  "c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
    194 	"c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
    195 	"c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
    196 	"c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
    197 	"c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
    198 };
    199 
    200 static const char * const c0_reg[32] = {
    201 	"index",    "random",   "tlblo0",  "tlblo1",
    202 	"context",  "pagemask", "wired",   "hwrena",
    203 	"badvaddr", "count",    "tlbhi",   "compare",
    204 	"status",   "cause",    "epc",     "prid",
    205 	"config",   "lladdr",   "watchlo", "watchhi",
    206 	"xcontext", "cp0r21",   "osscratch",  "debug",
    207 	"depc",     "perfcnt",  "ecc",     "cacheerr",
    208 	"taglo",    "taghi",    "errepc",  "desave"
    209 };
    210 
    211 static void print_addr(db_addr_t);
    212 
    213 /*
    214  * Disassemble instruction at 'loc'.  'altfmt' specifies an
    215  * (optional) alternate format (altfmt for vax: don't assume
    216  * that each external label is a procedure entry mask).
    217  * Return address of start of next instruction.
    218  * Since this function is used by 'examine' and by 'step'
    219  * "next instruction" does NOT mean the next instruction to
    220  * be executed but the 'linear' next instruction.
    221  */
    222 db_addr_t
    223 db_disasm(db_addr_t loc, bool altfmt)
    224 {
    225 	uint32_t instr;
    226 
    227 	/*
    228 	 * Take some care with addresses to not UTLB here as it
    229 	 * loses the current debugging context.  KSEG2 and XKSEG
    230 	 * are not checked.
    231 	 * Update: db_read_bytes is supposed to do that, and now
    232 	 * does, so we can use that.
    233 	 *
    234 	 * XXX db_read_bytes_can't return failure but instead zeros
    235 	 * the output. That's ok here, but if ever improved the
    236 	 * proper thing here on error is to return the original loc.
    237 	 */
    238 	db_read_bytes(loc, sizeof(instr), (void *)&instr);
    239 
    240 	return (db_disasm_insn(instr, loc, altfmt));
    241 }
    242 
    243 
    244 /*
    245  * Disassemble instruction 'insn' nominally at 'loc'.
    246  * 'loc' may in fact contain a breakpoint instruction.
    247  */
    248 db_addr_t
    249 db_disasm_insn(int insn, db_addr_t loc, bool altfmt)
    250 {
    251 	bool bdslot = false;
    252 	InstFmt i;
    253 
    254 	i.word = insn;
    255 
    256 	switch (i.JType.op) {
    257 	case OP_SPECIAL: {
    258 		const char *name = spec_name[i.RType.func];
    259 
    260 		/* Handle varations of NOPs */
    261 		if ((i.RType.func == OP_SLL) &&
    262 		    (i.RType.rs == 0) &&
    263 		    (i.RType.rt == 0) &&
    264 		    (i.RType.rd == 0)) {
    265 			switch (i.RType.shamt) {
    266 			case OP_SLL_NOP:
    267 				db_printf("nop");
    268 				break;
    269 			case OP_SLL_SSNOP:
    270 				db_printf("ssnop");
    271 				break;
    272 			case OP_SLL_EHB:
    273 				db_printf("ehb");
    274 				break;
    275 			case OP_SLL_PAUSE:
    276 				db_printf("pause");
    277 				break;
    278 			default:
    279 				db_printf("nop *");	/* "undefined" NOP */
    280 				break;
    281 			}
    282 			break;
    283 		}
    284 
    285 		/*
    286 		 * The following are equivalents of a "move dst,src":
    287 		 *	addu	dst,src,zero	(in 32-bit mode)
    288 		 *	daddu	dst,src,zero	(in 64-bit mode)
    289 		 *	or	dst,src,zero	(in 32- and 64-bit modes)
    290 		 */
    291 #ifdef __mips_o32
    292 #define	OP_MOVE_ADDU	OP_ADDU
    293 #else
    294 #define	OP_MOVE_ADDU	OP_DADDU
    295 #endif
    296 		if (true &&
    297 		    ((i.RType.func == OP_OR) || (i.RType.func == OP_MOVE_ADDU))
    298 		    && i.RType.rt == 0) {
    299 			db_printf("move\t%s,%s",
    300 			    reg_name[i.RType.rd],
    301 			    reg_name[i.RType.rs]);
    302 			break;
    303 		}
    304 
    305 		if ((i.RType.func == OP_SRL || i.RType.func == OP_SRLV)
    306 		    && i.RType.rs == 1) {
    307 			name = (i.RType.func == OP_SRL) ? "rotr" : "rotrv";
    308 		} else if ((i.RType.func == OP_DSRL || i.RType.func == OP_DSRLV)
    309 		    && i.RType.shamt == 1) {
    310 			name = (i.RType.func == OP_DSRL) ? "drotr" : "drotrv";
    311 		}
    312 
    313 		db_printf("%s", name);
    314 		switch (i.RType.func) {
    315 		case OP_SLL:
    316 		case OP_SRL:
    317 		case OP_SRA:
    318 		case OP_DSLL:
    319 		case OP_DSRL:
    320 		case OP_DSRA:
    321 		case OP_DSLL32:
    322 		case OP_DSRL32:
    323 		case OP_DSRA32:
    324 			db_printf("\t%s,%s,%d",
    325 			    reg_name[i.RType.rd],
    326 			    reg_name[i.RType.rt],
    327 			    i.RType.shamt);
    328 			break;
    329 
    330 		case OP_SLLV:
    331 		case OP_SRLV:
    332 		case OP_SRAV:
    333 		case OP_DSLLV:
    334 		case OP_DSRLV:
    335 		case OP_DSRAV:
    336 			db_printf("\t%s,%s,%s",
    337 			    reg_name[i.RType.rd],
    338 			    reg_name[i.RType.rt],
    339 			    reg_name[i.RType.rs]);
    340 			break;
    341 
    342 		case OP_MFHI:
    343 		case OP_MFLO:
    344 			db_printf("\t%s", reg_name[i.RType.rd]);
    345 			break;
    346 
    347 		case OP_JR:
    348 		case OP_JALR:
    349 			db_printf("\t%s%s", reg_name[i.RType.rs],
    350 			    (insn & __BIT(10)) ? ".hb" : "");
    351 			bdslot = true;
    352 			break;
    353 		case OP_MTLO:
    354 		case OP_MTHI:
    355 			db_printf("\t%s", reg_name[i.RType.rs]);
    356 			break;
    357 
    358 		case OP_MULT:
    359 		case OP_MULTU:
    360 		case OP_DMULT:
    361 		case OP_DMULTU:
    362 		case OP_DIV:
    363 		case OP_DIVU:
    364 		case OP_DDIV:
    365 		case OP_DDIVU:
    366 			db_printf("\t%s,%s",
    367 			    reg_name[i.RType.rs],
    368 			    reg_name[i.RType.rt]);
    369 			break;
    370 
    371 
    372 		case OP_SYSCALL:
    373 			break;
    374 		case OP_SYNC:
    375 			if (i.RType.shamt != 0)
    376 				db_printf("\t%d", i.RType.shamt);
    377 			break;
    378 
    379 		case OP_BREAK:
    380 			db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
    381 			break;
    382 
    383 		case OP_TEQ:
    384 			db_printf("\t%s,%s,%#x",
    385 			    reg_name[i.RType.rs],
    386 			    reg_name[i.RType.rt],
    387 			    (i.RType.rd << 5) | i.RType.shamt);
    388 			break;
    389 
    390 		default:
    391 			db_printf("\t%s,%s,%s",
    392 			    reg_name[i.RType.rd],
    393 			    reg_name[i.RType.rs],
    394 			    reg_name[i.RType.rt]);
    395 		}
    396 		break;
    397 	}
    398 
    399 	case OP_SPECIAL2:
    400 		if (spec_name[i.RType.func] == NULL) {
    401 			db_printf("spec2#%03o\t%s,%s",
    402 				i.RType.func,
    403 		    		reg_name[i.RType.rs],
    404 		    		reg_name[i.RType.rt]);
    405 			break;
    406 		}
    407 		if (i.RType.func == OP_MUL
    408 #ifdef __OCTEON__
    409 		    || i.RType.func == OP_CVM_DMUL
    410 		    || i.RType.func == OP_CVM_SEQ
    411 		    || i.RType.func == OP_CVM_SNE
    412 #endif
    413 		    || false) {
    414 			db_printf("%s\t%s,%s,%s",
    415 				spec2_name[i.RType.func],
    416 		    		reg_name[i.RType.rd],
    417 		    		reg_name[i.RType.rs],
    418 		    		reg_name[i.RType.rt]);
    419 			break;
    420 		}
    421 #ifdef __OCTEON__
    422 		if (i.RType.func == OP_CVM_CINS
    423 		    || i.RType.func == OP_CVM_CINS32
    424 		    || i.RType.func == OP_CVM_EXTS
    425 		    || i.RType.func == OP_CVM_EXTS32) {
    426 			db_printf("%s\t%s,%s,%d,%d",
    427 				spec2_name[i.RType.func],
    428 		    		reg_name[i.RType.rt],
    429 		    		reg_name[i.RType.rs],
    430 				i.RType.shamt,
    431 				i.RType.rd);
    432 			break;
    433 		}
    434 		if (i.RType.func == OP_CVM_SEQI
    435 		    || i.RType.func == OP_CVM_SNEI) {
    436 			db_printf("%s\t%s,%s,%d",
    437 				spec2_name[i.RType.func],
    438 		    		reg_name[i.RType.rs],
    439 		    		reg_name[i.RType.rt],
    440 				(short)i.IType.imm >> 6);
    441 			break;
    442 		}
    443 		if (i.RType.func == OP_CVM_SAA
    444 		    || i.RType.func == OP_CVM_SAAD) {
    445 			db_printf("%s\t%s,(%s)",
    446 				spec2_name[i.RType.func],
    447 		    		reg_name[i.RType.rt],
    448 		    		reg_name[i.RType.rs]);
    449 			break;
    450 		}
    451 #endif
    452 		if (i.RType.func == OP_CLO
    453 		    || i.RType.func == OP_DCLO
    454 #ifdef __OCTEON__
    455 		    || i.RType.func == OP_CVM_POP
    456 		    || i.RType.func == OP_CVM_DPOP
    457 #endif
    458 		    || i.RType.func == OP_CLZ
    459 		    || i.RType.func == OP_DCLZ) {
    460 			db_printf("%s\t%s,%s",
    461 				spec2_name[i.RType.func],
    462 		    		reg_name[i.RType.rs],
    463 		    		reg_name[i.RType.rd]);
    464 			break;
    465 		}
    466 		db_printf("%s\t%s,%s",
    467 			spec2_name[i.RType.func],
    468 	    		reg_name[i.RType.rs],
    469 	    		reg_name[i.RType.rt]);
    470 		break;
    471 
    472 	case OP_SPECIAL3:
    473 		if (spec3_name[i.RType.func] == NULL) {
    474 			db_printf("spec3#%03o\t%s,%s",
    475 				i.RType.func,
    476 		    		reg_name[i.RType.rs],
    477 		    		reg_name[i.RType.rt]);
    478 			break;
    479 		}
    480 		if (i.RType.func <= OP_DINS) {
    481 			int pos = i.RType.shamt;
    482 			int size = i.RType.rd - pos + 1;
    483 			size += (((i.RType.func & 3) == 1) ? 32 : 0);
    484 			pos  += (((i.RType.func & 3) == 2) ? 32 : 0);
    485 
    486 			db_printf("%s\t%s,%s,%d,%d",
    487 				spec3_name[i.RType.func],
    488 				reg_name[i.RType.rt],
    489 				reg_name[i.RType.rs],
    490 				pos, size);
    491 			break;
    492 		}
    493 		if (i.RType.func == OP_RDHWR) {
    494 			db_printf("%s\t%s,$%d",
    495 				spec3_name[i.RType.func],
    496 				reg_name[i.RType.rt],
    497 				i.RType.rd);
    498 			break;
    499 		}
    500 		if (i.RType.func == OP_BSHFL) {
    501 			if (i.RType.shamt == OP_BSHFL_SBH) {
    502 				db_printf("wsbh\t%s,%s",
    503 					reg_name[i.RType.rd],
    504 					reg_name[i.RType.rt]);
    505 			} else if (i.RType.shamt == OP_BSHFL_SEB) {
    506 				db_printf("seb\t%s,%s",
    507 					reg_name[i.RType.rd],
    508 					reg_name[i.RType.rt]);
    509 			} else if (i.RType.shamt == OP_BSHFL_SEH) {
    510 				db_printf("seh\t%s,%s",
    511 					reg_name[i.RType.rd],
    512 					reg_name[i.RType.rt]);
    513 			} else {
    514 				db_printf("bshfl\t%s,%s,%d",
    515 					reg_name[i.RType.rd],
    516 					reg_name[i.RType.rt],
    517 					i.RType.shamt);
    518 			}
    519 			break;
    520 		}
    521 		if (i.RType.func == OP_DBSHFL) {
    522 			if (i.RType.shamt == OP_BSHFL_SBH) {
    523 				db_printf("dsbh\t%s,%s",
    524 					reg_name[i.RType.rd],
    525 					reg_name[i.RType.rt]);
    526 			} else if (i.RType.shamt == OP_BSHFL_SHD) {
    527 				db_printf("dshd\t%s,%s",
    528 					reg_name[i.RType.rd],
    529 					reg_name[i.RType.rt]);
    530 			} else {
    531 				db_printf("dbshfl\t%s,%s,%d",
    532 					reg_name[i.RType.rd],
    533 					reg_name[i.RType.rt],
    534 					i.RType.shamt);
    535 			}
    536 			break;
    537 		}
    538 		switch (i.RType.func) {
    539 		case OP_LWLE:
    540 		case OP_LWRE:
    541 		case OP_CACHEE:
    542 		case OP_SBE:
    543 		case OP_SHE:
    544 		case OP_SCE:
    545 		case OP_SWE:
    546 		case OP_SWLE:
    547 		case OP_SWRE:
    548 		case OP_PREFE:
    549 		case OP_CACHE_R6:
    550 		case OP_LBUE:
    551 		case OP_LHUE:
    552 		case OP_LBE:
    553 		case OP_LHE:
    554 		case OP_LLE:
    555 		case OP_LWE:
    556 			db_printf("%s\t%s,%d(%s)",
    557 				spec3_name[i.RType.func],
    558 				reg_name[i.RType.rs],
    559 				i.S3OType.offset > 255 ?
    560 				  -i.S3OType.offset : i.S3OType.offset,
    561 				reg_name[i.RType.rt]);
    562 			break;
    563 		default:
    564 			db_printf("%s\t%s,%s",
    565 				spec3_name[i.RType.func],
    566 				reg_name[i.RType.rs],
    567 				reg_name[i.RType.rt]);
    568 		}
    569 		break;
    570 
    571 	case OP_REGIMM:
    572 		db_printf("%s\t%s,", regimm_name[i.IType.rt],
    573 		    reg_name[i.IType.rs]);
    574 		if (i.IType.rt >= OP_TGEI && i.IType.rt <= OP_TNEI) {
    575 			db_printf("%d",(int16_t)i.IType.imm);
    576 			break;
    577 		}
    578 		goto pr_displ;
    579 
    580 	case OP_BLEZ:
    581 	case OP_BLEZL:
    582 	case OP_BGTZ:
    583 	case OP_BGTZL:
    584 		db_printf("%s\t%s,", op_name[i.IType.op],
    585 		    reg_name[i.IType.rs]);
    586 		goto pr_displ;
    587 
    588 	case OP_BEQ:
    589 	case OP_BEQL:
    590 		if (i.IType.rs == 0 && i.IType.rt == 0) {
    591 			db_printf("b\t");
    592 			goto pr_displ;
    593 		}
    594 		/* FALLTHROUGH */
    595 	case OP_BNE:
    596 	case OP_BNEL:
    597 		db_printf("%s\t%s,%s,", op_name[i.IType.op],
    598 		    reg_name[i.IType.rs],
    599 		    reg_name[i.IType.rt]);
    600 	pr_displ:
    601 		print_addr(loc + 4 + ((short)i.IType.imm << 2));
    602 		bdslot = true;
    603 		break;
    604 
    605 	case OP_COP0:
    606 		switch (i.RType.rs) {
    607 		case OP_BCx:
    608 		case OP_BCy:
    609 
    610 			db_printf("bc0%c\t",
    611 			    "ft"[i.RType.rt & COPz_BC_TRUE]);
    612 			goto pr_displ;
    613 
    614 		case OP_MT:
    615 			db_printf("mtc0\t%s,%s",
    616 			    reg_name[i.RType.rt],
    617 			    c0_reg[i.RType.rd]);
    618 			break;
    619 
    620 		case OP_DMT:
    621 			db_printf("dmtc0\t%s,%s",
    622 			    reg_name[i.RType.rt],
    623 			    c0_reg[i.RType.rd]);
    624 			break;
    625 
    626 		case OP_MF:
    627 			db_printf("mfc0\t%s,%s",
    628 			    reg_name[i.RType.rt],
    629 			    c0_reg[i.RType.rd]);
    630 			break;
    631 
    632 		case OP_DMF:
    633 			db_printf("dmfc0\t%s,%s",
    634 			    reg_name[i.RType.rt],
    635 			    c0_reg[i.RType.rd]);
    636 			break;
    637 
    638 		case OP_MFM:
    639 			if (i.RType.rd == MIPS_COP_0_STATUS
    640 			    && i.RType.shamt == 0
    641 			    && (i.RType.func & 31) == 0) {
    642 				db_printf("%s",
    643 				    i.RType.func & 16 ? "ei" : "di");
    644 				if (i.RType.rt != 0) {
    645 					db_printf("\t%s",
    646 					    reg_name[i.RType.rt]);
    647 				}
    648 				break;
    649 			}
    650 			/* FALLTHROUGH */
    651 
    652 		default:
    653 			db_printf("%s", c0_opname[i.FRType.func]);
    654 		}
    655 		break;
    656 
    657 	case OP_COP1:
    658 		switch (i.RType.rs) {
    659 		case OP_BCx:
    660 		case OP_BCy:
    661 			db_printf("bc1%c\t",
    662 			    "ft"[i.RType.rt & COPz_BC_TRUE]);
    663 			goto pr_displ;
    664 
    665 		case OP_MT:
    666 			db_printf("mtc1\t%s,f%d",
    667 			    reg_name[i.RType.rt],
    668 			    i.RType.rd);
    669 			break;
    670 
    671 		case OP_MF:
    672 			db_printf("mfc1\t%s,f%d",
    673 			    reg_name[i.RType.rt],
    674 			    i.RType.rd);
    675 			break;
    676 
    677 		case OP_CT:
    678 			db_printf("ctc1\t%s,%d",
    679 			    reg_name[i.RType.rt],
    680 			    i.RType.rd);
    681 			break;
    682 
    683 		case OP_CF:
    684 			db_printf("cfc1\t%s,%d",
    685 			    reg_name[i.RType.rt],
    686 			    i.RType.rd);
    687 			break;
    688 
    689 		case OP_DMT:
    690 			db_printf("dmtc1\t%s,f%d",
    691 			    reg_name[i.RType.rt],
    692 			    i.RType.rd);
    693 			break;
    694 
    695 		case OP_DMF:
    696 			db_printf("dmfc1\t%s,f%d",
    697 			    reg_name[i.RType.rt],
    698 			    i.RType.rd);
    699 			break;
    700 
    701 		case OP_MTH:
    702 			db_printf("mthc1\t%s,f%d",
    703 			    reg_name[i.RType.rt],
    704 			    i.RType.rd);
    705 			break;
    706 
    707 		case OP_MFH:
    708 			db_printf("mfhc1\t%s,f%d",
    709 			    reg_name[i.RType.rt],
    710 			    i.RType.rd);
    711 			break;
    712 
    713 		default:
    714 			db_printf("%s.%s\tf%d,f%d,f%d",
    715 			    cop1_name[i.FRType.func],
    716 			    fmt_name[i.FRType.fmt],
    717 			    i.FRType.fd, i.FRType.fs, i.FRType.ft);
    718 		}
    719 		break;
    720 
    721 	case OP_COP2:
    722 		switch (i.RType.rs) {
    723 		case OP_BCx:
    724 		case OP_BCy:
    725 			db_printf("bc2%c\t",
    726 			    "ft"[i.RType.rt & COPz_BC_TRUE]);
    727 			goto pr_displ;
    728 
    729 		case OP_MT:
    730 			db_printf("mtc2\t%s,f%d",
    731 			    reg_name[i.RType.rt],
    732 			    i.RType.rd);
    733 			break;
    734 
    735 		case OP_MF:
    736 			db_printf("mfc2\t%s,f%d",
    737 			    reg_name[i.RType.rt],
    738 			    i.RType.rd);
    739 			break;
    740 
    741 		case OP_CT:
    742 			db_printf("ctc2\t%s,f%d",
    743 			    reg_name[i.RType.rt],
    744 			    i.RType.rd);
    745 			break;
    746 
    747 		case OP_CF:
    748 			db_printf("cfc2\t%s,f%d",
    749 			    reg_name[i.RType.rt],
    750 			    i.RType.rd);
    751 			break;
    752 
    753 		case OP_DMT:
    754 			db_printf("dmtc2\t%s,f%d",
    755 			    reg_name[i.RType.rt],
    756 			    i.RType.rd);
    757 			break;
    758 
    759 		case OP_DMF:
    760 			db_printf("dmfc2\t%s,f%d",
    761 			    reg_name[i.RType.rt],
    762 			    i.RType.rd);
    763 			break;
    764 
    765 		case OP_MTH:
    766 			db_printf("mthc2\t%s,f%d",
    767 			    reg_name[i.RType.rt],
    768 			    i.RType.rd);
    769 			break;
    770 
    771 		case OP_MFH:
    772 			db_printf("mfhc2\t%s,f%d",
    773 			    reg_name[i.RType.rt],
    774 			    i.RType.rd);
    775 			break;
    776 
    777 		default:
    778 			db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
    779 			    reg_name[i.IType.rt],
    780 			    reg_name[i.IType.rs],
    781 			    (short)i.IType.imm);
    782 		}
    783 		break;
    784 
    785 	case OP_J:
    786 	case OP_JAL:
    787 	case OP_JALX:
    788 		db_printf("%s\t", op_name[i.JType.op]);
    789 		print_addr((loc & ~0x0FFFFFFFL) | (i.JType.target << 2));
    790 		bdslot = true;
    791 		break;
    792 
    793 #ifdef __OCTEON__
    794 	case OP_CVM_BBIT0:
    795 	case OP_CVM_BBIT032:
    796 	case OP_CVM_BBIT1:
    797 	case OP_CVM_BBIT132:
    798 			db_printf("%s\t%s,%d,",
    799 			    op_name[i.IType.op],
    800 			    reg_name[i.IType.rs],
    801 			    i.IType.rt);
    802 			goto pr_displ;
    803 #else
    804 	case OP_LWC2:
    805 	case OP_LDC2:
    806 	case OP_SWC2:
    807 	case OP_SDC2:
    808 #endif
    809 
    810 	case OP_LWC1:
    811 	case OP_SWC1:
    812 	case OP_LDC1:
    813 	case OP_SDC1:
    814 		db_printf("%s\tf%d,", op_name[i.IType.op],
    815 		    i.IType.rt);
    816 		goto loadstore;
    817 
    818 	case OP_LB:
    819 	case OP_LH:
    820 	case OP_LW:
    821 	case OP_LD:
    822 	case OP_LBU:
    823 	case OP_LHU:
    824 	case OP_LWU:
    825 	case OP_SB:
    826 	case OP_SH:
    827 	case OP_SW:
    828 	case OP_SD:
    829 		db_printf("%s\t%s,", op_name[i.IType.op],
    830 		    reg_name[i.IType.rt]);
    831 	loadstore:
    832 		db_printf("%d(%s)", (short)i.IType.imm,
    833 		    reg_name[i.IType.rs]);
    834 		break;
    835 
    836 	case OP_ORI:
    837 	case OP_XORI:
    838 		if (i.IType.rs == 0) {
    839 			db_printf("li\t%s,0x%x",
    840 			    reg_name[i.IType.rt],
    841 			    i.IType.imm);
    842 			break;
    843 		}
    844 		/* FALLTHROUGH */
    845 	case OP_ANDI:
    846 		db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
    847 		    reg_name[i.IType.rt],
    848 		    reg_name[i.IType.rs],
    849 		    i.IType.imm);
    850 		break;
    851 
    852 	case OP_LUI:
    853 		db_printf("%s\t%s,0x%x", op_name[i.IType.op],
    854 		    reg_name[i.IType.rt],
    855 		    i.IType.imm);
    856 		break;
    857 
    858 	case OP_CACHE:
    859 		db_printf("%s\t0x%x,0x%x(%s)",
    860 		    op_name[i.IType.op],
    861 		    i.IType.rt,
    862 		    i.IType.imm,
    863 		    reg_name[i.IType.rs]);
    864 		break;
    865 
    866 	case OP_ADDI:
    867 	case OP_DADDI:
    868 	case OP_ADDIU:
    869 	case OP_DADDIU:
    870 		if (i.IType.rs == 0) {
    871 			db_printf("li\t%s,%d",
    872 			    reg_name[i.IType.rt],
    873 			    (short)i.IType.imm);
    874 			break;
    875 		}
    876 		/* FALLTHROUGH */
    877 	default:
    878 		db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
    879 		    reg_name[i.IType.rt],
    880 		    reg_name[i.IType.rs],
    881 		    (short)i.IType.imm);
    882 	}
    883 	db_printf("\n");
    884 	if (bdslot) {
    885 		db_printf("\t\tbdslot:\t");
    886 		db_disasm(loc+4, false);
    887 		return (loc + 8);
    888 	}
    889 	return (loc + 4);
    890 }
    891 
    892 static void
    893 print_addr(db_addr_t loc)
    894 {
    895 	db_expr_t diff;
    896 	db_sym_t sym;
    897 	const char *symname;
    898 
    899 	diff = INT_MAX;
    900 	symname = NULL;
    901 	sym = db_search_symbol(loc, DB_STGY_ANY, &diff);
    902 	db_symbol_values(sym, &symname, 0);
    903 
    904 	db_printf("%#"PRIxVADDR, loc);
    905 	if (symname) {
    906 		db_printf(" <%s", symname);
    907 		if (diff != 0)
    908 			db_printf("+%#"DDB_EXPR_FMT"x", diff);
    909 		db_printf(">");
    910 	}
    911 }
    912