Home | History | Annotate | Download | only in codeflinger
      1 /*  $NetBSD: db_disasm.c,v 1.19 2007/02/28 04:21:53 thorpej 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 <stdarg.h>
     38 #include <stdbool.h>
     39 #include <stdint.h>
     40 #include <stdio.h>
     41 #include <sys/cdefs.h>
     42 #include <sys/types.h>
     43 
     44 #include <android/log.h>
     45 
     46 #include "mips_opcode.h"
     47 
     48 static char *sprintf_buffer;
     49 static int sprintf_buf_len;
     50 
     51 typedef uint64_t db_addr_t;
     52 static void db_printf(const char* fmt, ...);
     53 
     54 static const char * const op_name[64] = {
     55 /* 0 */ "spec", "bcond", "j", "jal", "beq", "bne", "blez", "bgtz",
     56 /* 8 */ "pop10", "addiu", "slti", "sltiu", "andi", "ori", "xori", "aui",
     57 /*16 */ "cop0", "cop1", "cop2", "?", "?", "?", "pop26", "pop27",
     58 /*24 */ "pop30", "daddiu", "?", "?", "?", "daui", "msa", "op37",
     59 /*32 */ "lb", "lh", "?",  "lw", "lbu", "lhu", "?", "lwu",
     60 /*40 */ "sb", "sh", "?", "sw", "?", "?", "?", "?",
     61 /*48 */ "?", "lwc1", "bc", "?", "?",  "ldc1", "pop66", "ld",
     62 /*56 */ "?", "swc1", "balc", "pcrel", "?", "sdc1", "pop76", "sd"
     63 };
     64 
     65 static const char * const spec_name[64] = {
     66 /* 0 */ "sll", "?", "srl", "sra", "sllv", "?", "srlv", "srav",
     67 /* 8 */ "?", "jalr", "?", "?", "syscall", "break", "sdbpp", "sync",
     68 /*16 */ "clz", "clo", "dclz", "dclo", "dsllv", "dlsa", "dsrlv", "dsrav",
     69 /*24 */ "sop30", "sop31", "sop32", "sop33", "sop34", "sop35", "sop36", "sop37",
     70 /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
     71 /*40 */ "?", "?", "slt", "sltu", "dadd", "daddu", "dsub", "dsubu",
     72 /*48 */ "tge", "tgeu", "tlt", "tltu", "teq", "seleqz", "tne", "selnez",
     73 /*56 */ "dsll", "?", "dsrl", "dsra", "dsll32", "?", "dsrl32", "dsra32"
     74 };
     75 
     76 static const char * const bcond_name[32] = {
     77 /* 0 */ "bltz", "bgez", "?", "?", "?", "?", "dahi", "?",
     78 /* 8 */ "?", "?", "?", "?", "?", "?", "?", "?",
     79 /*16 */ "nal", "bal", "?", "?", "?", "?", "?", "sigrie",
     80 /*24 */ "?", "?", "?", "?", "?", "?", "dati", "synci",
     81 };
     82 
     83 static const char * const cop1_name[64] = {
     84 /* 0 */ "fadd",  "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
     85 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
     86 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
     87 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
     88 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
     89 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
     90 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
     91     "fcmp.ole","fcmp.ule",
     92 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
     93     "fcmp.le","fcmp.ngt"
     94 };
     95 
     96 static const char * const fmt_name[16] = {
     97     "s",    "d",    "e",    "fmt3",
     98     "w",    "fmt5", "fmt6", "fmt7",
     99     "fmt8", "fmt9", "fmta", "fmtb",
    100     "fmtc", "fmtd", "fmte", "fmtf"
    101 };
    102 
    103 static char * const mips_reg_name[32] = {
    104     "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
    105     "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
    106     "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
    107     "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
    108 };
    109 
    110 static char * alt_arm_reg_name[32] = {  // hacked names for comparison with ARM code
    111     "zero", "at",   "r0",   "r1",   "r2",   "r3",   "r4",   "r5",
    112     "r6",   "r7",   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",
    113     "r14",  "r15",  "at2",  "cmp",  "s4",   "s5",   "s6",   "s7",
    114     "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
    115 };
    116 
    117 static char ** reg_name =  &mips_reg_name[0];
    118 
    119 static const char * const c0_opname[64] = {
    120     "c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
    121     "tlbp",  "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
    122     "rfe",   "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
    123     "eret",  "c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
    124     "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
    125     "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
    126     "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
    127     "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
    128 };
    129 
    130 static const char * const c0_reg[32] = {
    131     "index",    "random",   "tlblo0",  "tlblo1",
    132     "context",  "pagemask", "wired",   "cp0r7",
    133     "badvaddr", "count",    "tlbhi",   "compare",
    134     "status",   "cause",    "epc",     "prid",
    135     "config",   "lladdr",   "watchlo", "watchhi",
    136     "xcontext", "cp0r21",   "cp0r22",  "debug",
    137     "depc",     "perfcnt",  "ecc",     "cacheerr",
    138     "taglo",    "taghi",    "errepc",  "desave"
    139 };
    140 
    141 static void print_addr(db_addr_t);
    142 db_addr_t mips_disassem(db_addr_t loc, char *di_buffer, int alt_dis_format);
    143 
    144 
    145 /*
    146  * Disassemble instruction 'insn' nominally at 'loc'.
    147  * 'loc' may in fact contain a breakpoint instruction.
    148  */
    149 static db_addr_t
    150 db_disasm_insn(int insn, db_addr_t loc, bool altfmt)
    151 {
    152     bool bdslot = false;
    153     InstFmt i;
    154 
    155     i.word = insn;
    156 
    157     switch (i.JType.op) {
    158     case OP_SPECIAL:
    159         if (i.word == 0) {
    160             db_printf("nop");
    161             break;
    162         }
    163         if (i.word == 0x0080) {
    164             db_printf("NIY");
    165             break;
    166         }
    167         if (i.word == 0x00c0) {
    168             db_printf("NOT IMPL");
    169             break;
    170         }
    171         /* Special cases --------------------------------------------------
    172          * "addu" is a "move" only in 32-bit mode.  What's the correct
    173          * answer - never decode addu/daddu as "move"?
    174          */
    175         if ( (i.RType.func == OP_ADDU && i.RType.rt == 0)  ||
    176              (i.RType.func == OP_OR   && i.RType.rt == 0) ) {
    177             db_printf("move\t%s,%s",
    178                 reg_name[i.RType.rd],
    179                 reg_name[i.RType.rs]);
    180             break;
    181         }
    182 
    183         if (i.RType.func == OP_SRL && (i.RType.rs & 1) == 1) {
    184             db_printf("rotr\t%s,%s,%d", reg_name[i.RType.rd],
    185                 reg_name[i.RType.rt], i.RType.shamt);
    186             break;
    187         }
    188         if (i.RType.func == OP_SRLV && (i.RType.shamt & 1) == 1) {
    189             db_printf("rotrv\t%s,%s,%s", reg_name[i.RType.rd],
    190                 reg_name[i.RType.rt], reg_name[i.RType.rs]);
    191             break;
    192         }
    193 
    194         if (i.RType.func == OP_SOP30) {
    195             if (i.RType.shamt == OP_MUL) {
    196                 db_printf("mul");
    197             } else if (i.RType.shamt == OP_MUH) {
    198                 db_printf("muh");
    199             }
    200             db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
    201                 reg_name[i.RType.rs], reg_name[i.RType.rt]);
    202             break;
    203         }
    204         if (i.RType.func == OP_SOP31) {
    205             if (i.RType.shamt == OP_MUL) {
    206                 db_printf("mulu");
    207             } else if (i.RType.shamt == OP_MUH) {
    208                 db_printf("muhu");
    209             }
    210             db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
    211                 reg_name[i.RType.rs], reg_name[i.RType.rt]);
    212             break;
    213         }
    214 
    215         if (i.RType.func == OP_JALR && i.RType.rd == 0) {
    216             db_printf("jr\t%s", reg_name[i.RType.rs]);
    217             bdslot = true;
    218             break;
    219         }
    220 
    221         db_printf("%s", spec_name[i.RType.func]);
    222         switch (i.RType.func) {
    223         case OP_SLL:
    224         case OP_SRL:
    225         case OP_SRA:
    226         case OP_DSLL:
    227 
    228         case OP_DSRL:
    229         case OP_DSRA:
    230         case OP_DSLL32:
    231         case OP_DSRL32:
    232         case OP_DSRA32:
    233             db_printf("\t%s,%s,%d",
    234                 reg_name[i.RType.rd],
    235                 reg_name[i.RType.rt],
    236                 i.RType.shamt);
    237             break;
    238 
    239         case OP_SLLV:
    240         case OP_SRLV:
    241         case OP_SRAV:
    242         case OP_DSLLV:
    243         case OP_DSRLV:
    244         case OP_DSRAV:
    245             db_printf("\t%s,%s,%s",
    246                 reg_name[i.RType.rd],
    247                 reg_name[i.RType.rt],
    248                 reg_name[i.RType.rs]);
    249             break;
    250 
    251         case OP_CLZ:
    252         case OP_CLO:
    253         case OP_DCLZ:
    254         case OP_DCLO:
    255             db_printf("\t%s,%s",
    256                 reg_name[i.RType.rd],
    257                 reg_name[i.RType.rs]);
    258             break;
    259 
    260         case OP_JALR:
    261             db_printf("\t");
    262             if (i.RType.rd != 31) {
    263                 db_printf("%s,", reg_name[i.RType.rd]);
    264             }
    265             db_printf("%s", reg_name[i.RType.rs]);
    266             bdslot = true;
    267             break;
    268 
    269         case OP_SYSCALL:
    270         case OP_SYNC:
    271             break;
    272 
    273         case OP_BREAK:
    274             db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
    275             break;
    276 
    277         default:
    278             db_printf("\t%s,%s,%s",
    279                 reg_name[i.RType.rd],
    280                 reg_name[i.RType.rs],
    281                 reg_name[i.RType.rt]);
    282         }
    283         break;
    284 
    285     case OP_SPECIAL3:
    286         if (i.RType.func == OP_EXT)
    287             db_printf("ext\t%s,%s,%d,%d",
    288                     reg_name[i.RType.rt],
    289                     reg_name[i.RType.rs],
    290                     i.RType.shamt,
    291                     i.RType.rd+1);
    292         else if (i.RType.func == OP_DEXT)
    293             db_printf("dext\t%s,%s,%d,%d",
    294                     reg_name[i.RType.rt],
    295                     reg_name[i.RType.rs],
    296                     i.RType.shamt,
    297                     i.RType.rd+1);
    298         else if (i.RType.func == OP_DEXTM)
    299             db_printf("dextm\t%s,%s,%d,%d",
    300                     reg_name[i.RType.rt],
    301                     reg_name[i.RType.rs],
    302                     i.RType.shamt,
    303                     i.RType.rd+33);
    304         else if (i.RType.func == OP_DEXTU)
    305             db_printf("dextu\t%s,%s,%d,%d",
    306                     reg_name[i.RType.rt],
    307                     reg_name[i.RType.rs],
    308                     i.RType.shamt+32,
    309                     i.RType.rd+1);
    310         else if (i.RType.func == OP_INS)
    311             db_printf("ins\t%s,%s,%d,%d",
    312                     reg_name[i.RType.rt],
    313                     reg_name[i.RType.rs],
    314                     i.RType.shamt,
    315                     i.RType.rd-i.RType.shamt+1);
    316         else if (i.RType.func == OP_DINS)
    317             db_printf("dins\t%s,%s,%d,%d",
    318                     reg_name[i.RType.rt],
    319                     reg_name[i.RType.rs],
    320                     i.RType.shamt,
    321                     i.RType.rd-i.RType.shamt+1);
    322         else if (i.RType.func == OP_DINSM)
    323             db_printf("dinsm\t%s,%s,%d,%d",
    324                     reg_name[i.RType.rt],
    325                     reg_name[i.RType.rs],
    326                     i.RType.shamt,
    327                     i.RType.rd-i.RType.shamt+33);
    328         else if (i.RType.func == OP_DINSU)
    329             db_printf("dinsu\t%s,%s,%d,%d",
    330                     reg_name[i.RType.rt],
    331                     reg_name[i.RType.rs],
    332                     i.RType.shamt+32,
    333                     i.RType.rd-i.RType.shamt+1);
    334         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_WSBH)
    335             db_printf("wsbh\t%s,%s",
    336                 reg_name[i.RType.rd],
    337                 reg_name[i.RType.rt]);
    338         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_SEB)
    339             db_printf("seb\t%s,%s",
    340                 reg_name[i.RType.rd],
    341                 reg_name[i.RType.rt]);
    342         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_SEH)
    343             db_printf("seh\t%s,%s",
    344                 reg_name[i.RType.rd],
    345                 reg_name[i.RType.rt]);
    346         else if (i.RType.func == OP_RDHWR)
    347             db_printf("rdhwr\t%s,%s",
    348                 reg_name[i.RType.rd],
    349                 reg_name[i.RType.rt]);
    350         else
    351             db_printf("Unknown");
    352         break;
    353 
    354     case OP_BCOND:
    355         db_printf("%s\t%s,", bcond_name[i.IType.rt],
    356             reg_name[i.IType.rs]);
    357         goto pr_displ;
    358 
    359     case OP_BLEZ:
    360     case OP_BGTZ:
    361         db_printf("%s\t%s,", op_name[i.IType.op],
    362             reg_name[i.IType.rs]);
    363         goto pr_displ;
    364 
    365     case OP_BEQ:
    366         if (i.IType.rs == 0 && i.IType.rt == 0) {
    367             db_printf("b\t");
    368             goto pr_displ;
    369         }
    370         /* FALLTHROUGH */
    371     case OP_BNE:
    372         db_printf("%s\t%s,%s,", op_name[i.IType.op],
    373             reg_name[i.IType.rs],
    374             reg_name[i.IType.rt]);
    375     pr_displ:
    376         print_addr(loc + 4 + ((short)i.IType.imm << 2));
    377         bdslot = true;
    378         break;
    379 
    380     case OP_COP0:
    381         switch (i.RType.rs) {
    382         case OP_BCx:
    383         case OP_BCy:
    384 
    385             db_printf("bc0%c\t",
    386                 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
    387             goto pr_displ;
    388 
    389         case OP_MT:
    390             db_printf("mtc0\t%s,%s",
    391                 reg_name[i.RType.rt],
    392                 c0_reg[i.RType.rd]);
    393             break;
    394 
    395         case OP_DMT:
    396             db_printf("dmtc0\t%s,%s",
    397                 reg_name[i.RType.rt],
    398                 c0_reg[i.RType.rd]);
    399             break;
    400 
    401         case OP_MF:
    402             db_printf("mfc0\t%s,%s",
    403                 reg_name[i.RType.rt],
    404                 c0_reg[i.RType.rd]);
    405             break;
    406 
    407         case OP_DMF:
    408             db_printf("dmfc0\t%s,%s",
    409                 reg_name[i.RType.rt],
    410                 c0_reg[i.RType.rd]);
    411             break;
    412 
    413         default:
    414             db_printf("%s", c0_opname[i.FRType.func]);
    415         }
    416         break;
    417 
    418     case OP_COP1:
    419         switch (i.RType.rs) {
    420         case OP_BCx:
    421         case OP_BCy:
    422             db_printf("bc1%c\t",
    423                 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
    424             goto pr_displ;
    425 
    426         case OP_MT:
    427             db_printf("mtc1\t%s,f%d",
    428                 reg_name[i.RType.rt],
    429                 i.RType.rd);
    430             break;
    431 
    432         case OP_MF:
    433             db_printf("mfc1\t%s,f%d",
    434                 reg_name[i.RType.rt],
    435                 i.RType.rd);
    436             break;
    437 
    438         case OP_CT:
    439             db_printf("ctc1\t%s,f%d",
    440                 reg_name[i.RType.rt],
    441                 i.RType.rd);
    442             break;
    443 
    444         case OP_CF:
    445             db_printf("cfc1\t%s,f%d",
    446                 reg_name[i.RType.rt],
    447                 i.RType.rd);
    448             break;
    449 
    450         default:
    451             db_printf("%s.%s\tf%d,f%d,f%d",
    452                 cop1_name[i.FRType.func],
    453                 fmt_name[i.FRType.fmt],
    454                 i.FRType.fd, i.FRType.fs, i.FRType.ft);
    455         }
    456         break;
    457 
    458     case OP_J:
    459     case OP_JAL:
    460         db_printf("%s\t", op_name[i.JType.op]);
    461         print_addr((loc & 0xFFFFFFFFF0000000) | (i.JType.target << 2));
    462         bdslot = true;
    463         break;
    464 
    465     case OP_LWC1:
    466     case OP_SWC1:
    467         db_printf("%s\tf%d,", op_name[i.IType.op],
    468             i.IType.rt);
    469         goto loadstore;
    470 
    471     case OP_LB:
    472     case OP_LH:
    473     case OP_LW:
    474     case OP_LD:
    475     case OP_LBU:
    476     case OP_LHU:
    477     case OP_LWU:
    478     case OP_SB:
    479     case OP_SH:
    480     case OP_SW:
    481     case OP_SD:
    482         db_printf("%s\t%s,", op_name[i.IType.op],
    483             reg_name[i.IType.rt]);
    484     loadstore:
    485         db_printf("%d(%s)", (short)i.IType.imm,
    486             reg_name[i.IType.rs]);
    487         break;
    488 
    489     case OP_ORI:
    490     case OP_XORI:
    491         if (i.IType.rs == 0) {
    492             db_printf("li\t%s,0x%x",
    493                 reg_name[i.IType.rt],
    494                 i.IType.imm);
    495             break;
    496         }
    497         /* FALLTHROUGH */
    498     case OP_ANDI:
    499         db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
    500             reg_name[i.IType.rt],
    501             reg_name[i.IType.rs],
    502             i.IType.imm);
    503         break;
    504 
    505     case OP_AUI:
    506         if (i.IType.rs == 0) {
    507             db_printf("lui\t%s,0x%x", reg_name[i.IType.rt],
    508                 i.IType.imm);
    509         } else {
    510             db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
    511             reg_name[i.IType.rt], reg_name[i.IType.rs],
    512             (short)i.IType.imm);
    513         }
    514         break;
    515 
    516     case OP_ADDIU:
    517     case OP_DADDIU:
    518         if (i.IType.rs == 0) {
    519             db_printf("li\t%s,%d",
    520                 reg_name[i.IType.rt],
    521                 (short)i.IType.imm);
    522             break;
    523         }
    524         /* FALLTHROUGH */
    525     default:
    526         db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
    527             reg_name[i.IType.rt],
    528             reg_name[i.IType.rs],
    529             (short)i.IType.imm);
    530     }
    531     // db_printf("\n");
    532     // if (bdslot) {
    533     //     db_printf("   bd: ");
    534     //     mips_disassem(loc+4);
    535     //     return (loc + 8);
    536     // }
    537     return (loc + 4);
    538 }
    539 
    540 static void
    541 print_addr(db_addr_t loc)
    542 {
    543     db_printf("0x%08lx", loc);
    544 }
    545 
    546 static void db_printf(const char* fmt, ...)
    547 {
    548     int cnt;
    549     va_list argp;
    550     va_start(argp, fmt);
    551     if (sprintf_buffer) {
    552         cnt = vsnprintf(sprintf_buffer, sprintf_buf_len, fmt, argp);
    553         sprintf_buffer += cnt;
    554         sprintf_buf_len -= cnt;
    555     } else {
    556         vprintf(fmt, argp);
    557     }
    558     va_end(argp);
    559 }
    560 
    561 /*
    562  * Disassemble instruction at 'loc'.
    563  * Return address of start of next instruction.
    564  * Since this function is used by 'examine' and by 'step'
    565  * "next instruction" does NOT mean the next instruction to
    566  * be executed but the 'linear' next instruction.
    567  */
    568 db_addr_t
    569 mips_disassem(db_addr_t loc, char *di_buffer, int alt_dis_format)
    570 {
    571     u_int32_t instr;
    572 
    573     if (alt_dis_format) {   // use ARM register names for disassembly
    574         reg_name = &alt_arm_reg_name[0];
    575     }
    576 
    577     sprintf_buffer = di_buffer;     // quick 'n' dirty printf() vs sprintf()
    578     sprintf_buf_len = 39;           // should be passed in
    579 
    580     instr =  *(u_int32_t *)loc;
    581     return (db_disasm_insn(instr, loc, false));
    582 }
    583