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
db_disasm(db_addr_t loc,bool altfmt)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
db_disasm_insn(int insn,db_addr_t loc,bool altfmt)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
print_addr(db_addr_t loc)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