Annotation of lucent/sys/src/libmach/vdb.c, revision 1.1.1.1

1.1       root        1: #include <u.h>
                      2: #include <libc.h>
                      3: #include <bio.h>
                      4: #include <mach.h>
                      5: /*
                      6:  * Mips-specific debugger interface
                      7:  */
                      8: 
                      9: static         char    *mipsexcep(Map*, Rgetter);
                     10: static int     mipsfoll(Map*, ulong, Rgetter, ulong*);
                     11: static int     mipsinst(Map*, ulong, char, char*, int);
                     12: static int     mipsdas(Map*, ulong, char*, int);
                     13: static int     mipsinstlen(Map*, ulong);
                     14: /*
                     15:  *     Debugger interface
                     16:  */
                     17: Machdata mipsmach =
                     18: {
                     19:        {0, 0, 0, 0xD},         /* break point */
                     20:        4,                      /* break point size */
                     21: 
                     22:        beswab,                 /* short to local byte order */
                     23:        beswal,                 /* long to local byte order */
                     24:        risctrace,              /* C traceback */
                     25:        riscframe,              /* Frame finder */
                     26:        0,                      /* ublock fixup */
                     27:        mipsexcep,              /* print exception */
                     28:        0,                      /* breakpoint fixup */
                     29:        beieeesftos,            /* single precision float printer */
                     30:        beieeedftos,            /* double precisioin float printer */
                     31:        mipsfoll,               /* following addresses */
                     32:        mipsinst,               /* print instruction */
                     33:        mipsdas,                /* dissembler */
                     34:        mipsinstlen,            /* instruction size */
                     35: };
                     36: 
                     37: static char *excname[] =
                     38: {
                     39:        "external interrupt",
                     40:        "TLB modification",
                     41:        "TLB miss (load or fetch)",
                     42:        "TLB miss (store)",
                     43:        "address error (load or fetch)",
                     44:        "address error (store)",
                     45:        "bus error (fetch)",
                     46:        "bus error (data load or store)",
                     47:        "system call",
                     48:        "breakpoint",
                     49:        "reserved instruction",
                     50:        "coprocessor unusable",
                     51:        "arithmetic overflow",
                     52:        "undefined 13",
                     53:        "undefined 14",
                     54:        "system call",
                     55:        /* the following is made up */
                     56:        "floating point exception"              /* FPEXC */
                     57: };
                     58: 
                     59: static char*
                     60: mipsexcep(Map *map, Rgetter rget)
                     61: {
                     62:        int e;
                     63:        long c;
                     64: 
                     65:        c = (*rget)(map, "CAUSE");
                     66:        if(c & 0x00002000)      /* INTR3 */
                     67:                e = 16;         /* Floating point exception */
                     68:        else
                     69:                e = (c>>2)&0x0F;
                     70:        return excname[e];
                     71: }
                     72: 
                     73:        /* mips disassembler and related functions */
                     74: 
                     75: static char FRAMENAME[] = ".frame";
                     76: 
                     77: typedef struct {
                     78:        ulong addr;
                     79:        uchar op;                       /* bits 31-26 */
                     80:        uchar rs;                       /* bits 25-21 */
                     81:        uchar rt;                       /* bits 20-16 */
                     82:        uchar rd;                       /* bits 15-11 */
                     83:        uchar sa;                       /* bits 10-6 */
                     84:        uchar function;                 /* bits 5-0 */
                     85:        long immediate;                 /* bits 15-0 */
                     86:        ulong cofun;                    /* bits 24-0 */
                     87:        ulong target;                   /* bits 25-0 */
                     88:        long w0;
                     89:        long w1;
                     90:        int size;                       /* instruction size */
                     91:        char *curr;                     /* fill point in buffer */
                     92:        char *end;                      /* end of buffer */
                     93:        char *err;                      /* error message */
                     94: } Instr;
                     95: 
                     96: static Map *mymap;
                     97: 
                     98: static int
                     99: decode (ulong pc, Instr *i)
                    100: {
                    101:        long w;
                    102: 
                    103:        if (get4(mymap, pc, &w) < 0) {
                    104:                werrstr("can't read instruction: %r");
                    105:                return -1;
                    106:        }
                    107:        i->addr = pc;
                    108:        i->size = 1;
                    109:        i->op = (w >> 26) & 0x3F;
                    110:        i->rs = (w >> 21) & 0x1F;
                    111:        i->rt = (w >> 16) & 0x1F;
                    112:        i->rd = (w >> 11) & 0x1F;
                    113:        i->sa = (w >> 6) & 0x1F;
                    114:        i->function = w & 0x3F;
                    115:        i->immediate = w & 0x0000FFFF;
                    116:        if (i->immediate & 0x8000)
                    117:                i->immediate |= ~0x0000FFFF;
                    118:        i->cofun = w & 0x01FFFFFF;
                    119:        i->target = w & 0x03FFFFFF;
                    120:        i->w0 = w;
                    121:        return 1;
                    122: }
                    123: 
                    124: static int
                    125: mkinstr(ulong pc, Instr *i)
                    126: {
                    127:        Instr x;
                    128: 
                    129:        if (decode(pc, i) < 0)
                    130:                return -1;
                    131:        /*
                    132:         * if it's a LUI followed by an ORI,
                    133:         * it's an immediate load of a large constant.
                    134:         * fix the LUI immediate in any case.
                    135:         */
                    136:        if (i->op == 0x0F) {
                    137:                if (decode(pc+4, &x) < 0)
                    138:                        return 0;
                    139:                i->immediate <<= 16;
                    140:                if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
                    141:                        i->immediate |= (x.immediate & 0xFFFF);
                    142:                        i->w1 = x.w0;
                    143:                        i->size++;
                    144:                        return 1;
                    145:                }
                    146:        }
                    147:        /*
                    148:         * if it's a LWC1 followed by another LWC1
                    149:         * into an adjacent register, it's a load of
                    150:         * a floating point double.
                    151:         */
                    152:        else if (i->op == 0x31 && (i->rt & 0x01)) {
                    153:                if (decode(pc+4, &x) < 0)
                    154:                        return 0;
                    155:                if (x.op == 0x31 && x.rt == (i->rt - 1) && x.rs == i->rs) {
                    156:                        i->rt -= 1;
                    157:                        i->w1 = x.w0;
                    158:                        i->size++;
                    159:                        return 1;
                    160:                }
                    161:        }
                    162:        /*
                    163:         * similarly for double stores
                    164:         */
                    165:        else if (i->op == 0x39 && (i->rt & 0x01)) {
                    166:                if (decode(pc+4, &x) < 0)
                    167:                        return 0;
                    168:                if (x.op == 0x39 && x.rt == (i->rt - 1) && x.rs == i->rs) {
                    169:                        i->rt -= 1;
                    170:                        i->w1 = x.w0;
                    171:                        i->size++;
                    172:                }
                    173:        }
                    174:        return 1;
                    175: }
                    176: 
                    177: static void
                    178: bprint(Instr *i, char *fmt, ...)
                    179: {
                    180:        i->curr = doprint(i->curr, i->end, fmt, (&fmt+1));
                    181: }
                    182: 
                    183: typedef struct Opcode Opcode;
                    184: 
                    185: struct Opcode {
                    186:        char *mnemonic;
                    187:        void (*f)(Opcode *, Instr *);
                    188:        char *ken;
                    189: };
                    190: 
                    191: static void format(char *, Instr *, char *);
                    192: 
                    193: static void
                    194: branch(Opcode *o, Instr *i)
                    195: {
                    196:        if (i->rs == 0 && i->rt == 0)
                    197:                format("JMP", i, "%b");
                    198:        else if (i->rs == 0)
                    199:                format(o->mnemonic, i, "R%t,%b");
                    200:        else if (i->rt < 2)
                    201:                format(o->mnemonic, i, "R%s,%b");
                    202:        else
                    203:                format(o->mnemonic, i, "R%s,R%t,%b");
                    204: }
                    205: 
                    206: static void
                    207: addi(Opcode *o, Instr *i)
                    208: {
                    209:        if (i->rs == i->rt)
                    210:                format(o->mnemonic, i, "%i,R%t");
                    211:        else if (i->rs == 0)
                    212:                format("MOVW", i, "%i,R%t");
                    213:        else if (i->rs == 30) {
                    214:                bprint(i, "MOVW\t$");
                    215:                i->curr += symoff(i->curr, i->end-i->curr,
                    216:                                        i->immediate+mach->sb, CANY);
                    217:                bprint(i, "(SB),R%d", i->rt);
                    218:        }
                    219:        else
                    220:                format(o->mnemonic, i, o->ken);
                    221: }
                    222: 
                    223: static void
                    224: andi(Opcode *o, Instr *i)
                    225: {
                    226:        if (i->rs == i->rt)
                    227:                format(o->mnemonic, i, "%i,R%t");
                    228:        else
                    229:                format(o->mnemonic, i, o->ken);
                    230: }
                    231: 
                    232: static int
                    233: plocal(Instr *i, char *m, char r, int store)
                    234: {
                    235:        int offset;
                    236:        char *reg;
                    237:        Symbol s;
                    238: 
                    239:        if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
                    240:                return 0;
                    241:        if (s.value > i->immediate) {
                    242:                if(!getauto(&s, s.value-i->immediate, CAUTO, &s))
                    243:                        return 0;
                    244:                reg = "(SP)";
                    245:                offset = i->immediate;
                    246:        } else {
                    247:                offset = i->immediate-s.value;
                    248:                if (!getauto(&s, offset-4, CPARAM, &s))
                    249:                        return 0;
                    250:                reg = "(FP)";
                    251:        }
                    252:        if (store)
                    253:                bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->rt, s.name, offset, reg);
                    254:        else
                    255:                bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->rt);
                    256:        return 1;
                    257: }
                    258: 
                    259: static void
                    260: lw(Opcode *o, Instr *i, char r)
                    261: {
                    262:        char *m;
                    263: 
                    264:        if (r == 'F') {
                    265:                if (i->size == 2)
                    266:                        m = "MOVD";
                    267:                else
                    268:                        m = "MOVF";
                    269:        }
                    270:        else
                    271:                m = o->mnemonic;
                    272:        if (i->rs == 29 && plocal(i, m, r, 0))
                    273:                        return;
                    274: 
                    275:        if (i->rs == 30 && mach->sb) {
                    276:                bprint(i, "%s\t", m);
                    277:                i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);
                    278:                bprint(i, "(SB),%c%d", r, i->rt);
                    279:                return;
                    280:        }
                    281:        if (r == 'F')
                    282:                format(m, i, "%l,F%t");
                    283:        else
                    284:                format(m, i, o->ken);
                    285: }
                    286: 
                    287: static void
                    288: load(Opcode *o, Instr *i)
                    289: {
                    290:        lw(o, i, 'R');
                    291: }
                    292: 
                    293: static void
                    294: lwc1(Opcode *o, Instr *i)
                    295: {
                    296:        lw(o, i, 'F');
                    297: }
                    298: 
                    299: static void
                    300: sw(Opcode *o, Instr *i, char r)
                    301: {
                    302:        char *m;
                    303: 
                    304:        if (r == 'F') {
                    305:                if (i->size == 2)
                    306:                        m = "MOVD";
                    307:                else
                    308:                        m = "MOVF";
                    309:        }
                    310:        else
                    311:                m = o->mnemonic;
                    312:        if (i->rs == 29 && plocal(i, m, r, 1))
                    313:                        return;
                    314: 
                    315:        if (i->rs == 30 && mach->sb) {
                    316:                bprint(i, "%s\t%c%d,", m, r, i->rt);
                    317:                i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);
                    318:                bprint(i, "(SB)");
                    319:                return;
                    320:        }
                    321:        if (r == 'F')
                    322:                format(m, i, "F%t,%l");
                    323:        else
                    324:                format(m, i, o->ken);
                    325: }
                    326: 
                    327: static void
                    328: store(Opcode *o, Instr *i)
                    329: {
                    330:        sw(o, i, 'R');
                    331: }
                    332: 
                    333: static void
                    334: swc1(Opcode *o, Instr *i)
                    335: {
                    336:        sw(o, i, 'F');
                    337: }
                    338: 
                    339: static void
                    340: sll(Opcode *o, Instr *i)
                    341: {
                    342:        if (i->w0 == 0)
                    343:                bprint(i, "NOOP");
                    344:        else if (i->rd == i->rt)
                    345:                format(o->mnemonic, i, "$%a,R%d");
                    346:        else
                    347:                format(o->mnemonic, i, o->ken);
                    348: }
                    349: 
                    350: static void
                    351: sl32(Opcode *o, Instr *i)
                    352: {
                    353:        i->sa += 32;
                    354:        if (i->rd == i->rt)
                    355:                format(o->mnemonic, i, "$%a,R%d");
                    356:        else
                    357:                format(o->mnemonic, i, o->ken);
                    358: }
                    359: 
                    360: static void
                    361: sllv(Opcode *o, Instr *i)
                    362: {
                    363:        if (i->rd == i->rt)
                    364:                format(o->mnemonic, i, "R%s,R%d");
                    365:        else
                    366:                format(o->mnemonic, i, o->ken);
                    367: }
                    368: 
                    369: static void
                    370: jal(Opcode *o, Instr *i)
                    371: {
                    372:        if (i->rd == 31)
                    373:                format("JAL", i, "(R%s)");
                    374:        else
                    375:                format(o->mnemonic, i, o->ken);
                    376: }
                    377: 
                    378: static void
                    379: add(Opcode *o, Instr *i)
                    380: {
                    381:        if (i->rd == i->rs)
                    382:                format(o->mnemonic, i, "R%t,R%d");
                    383:        else if (i->rd == i->rt)
                    384:                format(o->mnemonic, i, "R%s,R%d");
                    385:        else
                    386:                format(o->mnemonic, i, o->ken);
                    387: }
                    388: 
                    389: static void
                    390: sub(Opcode *o, Instr *i)
                    391: {
                    392:        if (i->rd == i->rs)
                    393:                format(o->mnemonic, i, "R%t,R%d");
                    394:        else
                    395:                format(o->mnemonic, i, o->ken);
                    396: }
                    397: 
                    398: static void
                    399: or(Opcode *o, Instr *i)
                    400: {
                    401:        if (i->rs == 0 && i->rt == 0)
                    402:                format("MOVW", i, "$0,R%d");
                    403:        else if (i->rs == 0)
                    404:                format("MOVW", i, "R%t,R%d");
                    405:        else if (i->rt == 0)
                    406:                format("MOVW", i, "R%s,R%d");
                    407:        else
                    408:                add(o, i);
                    409: }
                    410: 
                    411: static void
                    412: nor(Opcode *o, Instr *i)
                    413: {
                    414:        if (i->rs == 0 && i->rt == 0 && i->rd == 0)
                    415:                format("NOP", i, 0);
                    416:        else
                    417:                add(o, i);
                    418: }
                    419: 
                    420: static char mipscoload[] = "r%t,%l";
                    421: static char mipsload[] = "%l,R%t";
                    422: static char mipsstore[] = "R%t,%l";
                    423: static char mipsalui[] = "%i,R%s,R%t";
                    424: static char mipsalu3op[] = "R%t,R%s,R%d";
                    425: static char mipsrtrs[] = "R%t,R%s";
                    426: static char mipscorsrt[] = "r%s,r%t";
                    427: static char mipscorsi[] = "r%s,%i";
                    428: static char mipscoxxx[] = "%w";
                    429: static char mipscofp3[] = "f%a,f%d,f%t";       /* fd,fs,ft */
                    430: static char mipsfp3[] = "F%t,F%d,F%a";
                    431: static char mipscofp2[] = "f%a,f%d";           /* fd,fs */
                    432: static char mipsfp2[] = "F%d,F%a";
                    433: static char mipscofpc[] = "f%d,f%t";           /* fs,ft */
                    434: static char mipsfpc[] = "F%t,F%d";
                    435: 
                    436: static Opcode opcodes[64] = {
                    437:        0,              0,      0,
                    438:        0,              0,      0,
                    439:        "JMP",          0,      "%j",
                    440:        "JAL",          0,      "%j",
                    441:        "BEQ",     branch,      0,
                    442:        "BNE",     branch,      0,
                    443:        "BLEZ",    branch,      0,
                    444:        "BGTZ",    branch,      0,
                    445:        "ADD",       addi,      mipsalui,
                    446:        "ADDU",      addi,      mipsalui,
                    447:        "SGT",          0,      mipsalui,
                    448:        "SGTU",         0,      mipsalui,
                    449:        "AND",       andi,      mipsalui,
                    450:        "OR",        andi,      mipsalui,
                    451:        "XOR",       andi,      mipsalui,
                    452:        "MOVW",         0,      "$%u,R%t",
                    453:        "cop0",         0,      0,
                    454:        "cop1",         0,      0,
                    455:        "cop2",         0,      0,
                    456:        "cop3",         0,      0,
                    457:        "BEQL",    branch,      0,
                    458:        "BNEL",    branch,      0,
                    459:        "BLEZL",   branch,      0,
                    460:        "BGTZL",   branch,      0,
                    461:        "instr18",      0,      mipscoxxx,
                    462:        "instr19",      0,      mipscoxxx,
                    463:        "MOVVL",     load,      mipsload,
                    464:        "MOVVR",     load,      mipsload,
                    465:        "instr1C",      0,      mipscoxxx,
                    466:        "instr1D",      0,      mipscoxxx,
                    467:        "instr1E",      0,      mipscoxxx,
                    468:        "instr1F",      0,      mipscoxxx,
                    469:        "MOVB",      load,      mipsload,
                    470:        "MOVH",      load,      mipsload,
                    471:        "lwl",          0,      mipscoload,
                    472:        "MOVW",      load,      mipsload,
                    473:        "MOVBU",     load,      mipsload,
                    474:        "MOVHU",     load,      mipsload,
                    475:        "lwr",          0,      mipscoload,
                    476:        "instr27",      0,      mipscoxxx,
                    477:        "MOVB",     store,      mipsstore,
                    478:        "MOVH",     store,      mipsstore,
                    479:        "swl",          0,      mipscoload,
                    480:        "MOVW",     store,      mipsstore,
                    481:        "MOVVL",    store,      mipsstore,
                    482:        "MOVVR",    store,      mipsstore,
                    483:        "swr",          0,      mipscoload,
                    484:        "CACHE",        0,      "%C,%l",
                    485:        "ll",           0,      mipscoload,
                    486:        "MOVW",      lwc1,      mipscoload,
                    487:        "lwc2",         0,      mipscoload,
                    488:        "lwc3",         0,      mipscoload,
                    489:        "instr34",      0,      mipscoxxx,
                    490:        "ldc1",         0,      mipscoload,
                    491:        "ldc2",         0,      mipscoload,
                    492:        "MOVV",     load,       mipsload,
                    493:        "sc",           0,      mipscoload,
                    494:        "swc1",      swc1,      mipscoload,
                    495:        "swc2",         0,      mipscoload,
                    496:        "swc3",         0,      mipscoload,
                    497:        "instr3C",      0,      mipscoxxx,
                    498:        "sdc1",         0,      mipscoload,
                    499:        "sdc2",         0,      mipscoload,
                    500:        "MOVV",     store,      mipsstore,
                    501: };
                    502: 
                    503: static Opcode sopcodes[64] = {
                    504:        "SLL",        sll,      "$%a,R%t,R%d",
                    505:        "special01",    0,      mipscoxxx,
                    506:        "SRL",        sll,      "$%a,R%t,R%d",
                    507:        "SRA",        sll,      "$%a,R%t,R%d",
                    508:        "SLL",       sllv,      "R%s,R%t,R%d",
                    509:        "special05",    0,      mipscoxxx,
                    510:        "SRL",       sllv,      "R%s,R%t,R%d",
                    511:        "SRA",       sllv,      "R%s,R%t,R%d",
                    512:        "JMP",          0,      "(R%s)",
                    513:        "jal",        jal,      "r%d,r%s",
                    514:        "special0A",    0,      mipscoxxx,
                    515:        "special0B",    0,      mipscoxxx,
                    516:        "SYSCALL",      0,      0,
                    517:        "BREAK",        0,      0,
                    518:        "special0E",    0,      mipscoxxx,
                    519:        "SYNC",         0,      0,
                    520:        "MOVW",         0,      "HI,R%d",
                    521:        "MOVW",         0,      "R%s,HI",
                    522:        "MOVW",         0,      "LO,R%d",
                    523:        "MOVW",         0,      "R%s,LO",
                    524:        "SLLV",      sllv,      "R%s,R%t,R%d",
                    525:        "special15",    0,      mipscoxxx,
                    526:        "SRLV",      sllv,      "R%s,R%t,R%d",
                    527:        "SRAV",      sllv,      "R%s,R%t,R%d",
                    528:        "MUL",          0,      mipsrtrs,
                    529:        "MULU",         0,      mipsrtrs,
                    530:        "DIV",          0,      mipsrtrs,
                    531:        "DIVU",         0,      mipsrtrs,
                    532:        "special1C",    0,      mipscoxxx,
                    533:        "special1D",    0,      mipscoxxx,
                    534:        "special1E",    0,      mipscoxxx,
                    535:        "special1F",    0,      mipscoxxx,
                    536:        "ADD",        add,      mipsalu3op,
                    537:        "ADDU",       add,      mipsalu3op,
                    538:        "SUB",        sub,      mipsalu3op,
                    539:        "SUBU",       sub,      mipsalu3op,
                    540:        "AND",        add,      mipsalu3op,
                    541:        "OR",          or,      mipsalu3op,
                    542:        "XOR",        add,      mipsalu3op,
                    543:        "NOR",        nor,      mipsalu3op,
                    544:        "special28",    0,      mipscoxxx,
                    545:        "special29",    0,      mipscoxxx,
                    546:        "SGT",          0,      mipsalu3op,
                    547:        "SGTU",         0,      mipsalu3op,
                    548:        "special2C",    0,      mipscoxxx,
                    549:        "special2D",    0,      mipscoxxx,
                    550:        "special2E",    0,      mipscoxxx,
                    551:        "special2F",    0,      mipscoxxx,
                    552:        "tge",          0,      mipscorsrt,
                    553:        "tgeu",         0,      mipscorsrt,
                    554:        "tlt",          0,      mipscorsrt,
                    555:        "tltu",         0,      mipscorsrt,
                    556:        "teq",          0,      mipscorsrt,
                    557:        "special35",    0,      mipscoxxx,
                    558:        "tne",          0,      mipscorsrt,
                    559:        "special37",    0,      mipscoxxx,
                    560:        "SLLV",       sll,      "$%a,R%t,R%d",
                    561:        "special39",    0,      mipscoxxx,
                    562:        "SRLV",       sll,      "$%a,R%t,R%d",
                    563:        "SRAV",       sll,      "$%a,R%t,R%d",
                    564:        "SLLV",      sl32,      "$%a,R%t,R%d",
                    565:        "special3D",    0,      mipscoxxx,
                    566:        "SRLV",      sl32,      "$%a,R%t,R%d",
                    567:        "SRAV",      sl32,      "$%a,R%t,R%d",
                    568: };
                    569: 
                    570: static Opcode ropcodes[32] = {
                    571:        "BLTZ",    branch,      0,
                    572:        "BGEZ",    branch,      0,
                    573:        "BLTZL",   branch,      0,
                    574:        "BGEZL",   branch,      0,
                    575:        "regimm04",     0,      mipscoxxx,
                    576:        "regimm05",     0,      mipscoxxx,
                    577:        "regimm06",     0,      mipscoxxx,
                    578:        "regimm07",     0,      mipscoxxx,
                    579:        "tgei",         0,      mipscorsi,
                    580:        "tgeiu",        0,      mipscorsi,
                    581:        "tlti",         0,      mipscorsi,
                    582:        "tltiu",        0,      mipscorsi,
                    583:        "teqi",         0,      mipscorsi,
                    584:        "regimm0D",     0,      mipscoxxx,
                    585:        "tnei",         0,      mipscorsi,
                    586:        "regimm0F",     0,      mipscoxxx,
                    587:        "BLTZAL",  branch,      0,
                    588:        "BGEZAL",  branch,      0,
                    589:        "BLTZALL", branch,      0,
                    590:        "BGEZALL", branch,      0,
                    591:        "regimm14",     0,      mipscoxxx,
                    592:        "regimm15",     0,      mipscoxxx,
                    593:        "regimm16",     0,      mipscoxxx,
                    594:        "regimm17",     0,      mipscoxxx,
                    595:        "regimm18",     0,      mipscoxxx,
                    596:        "regimm19",     0,      mipscoxxx,
                    597:        "regimm1A",     0,      mipscoxxx,
                    598:        "regimm1B",     0,      mipscoxxx,
                    599:        "regimm1C",     0,      mipscoxxx,
                    600:        "regimm1D",     0,      mipscoxxx,
                    601:        "regimm1E",     0,      mipscoxxx,
                    602:        "regimm1F",     0,      mipscoxxx,
                    603: };
                    604: 
                    605: static Opcode fopcodes[64] = {
                    606:        "ADD%f",        0,      mipsfp3,
                    607:        "SUB%f",        0,      mipsfp3,
                    608:        "MUL%f",        0,      mipsfp3,
                    609:        "DIV%f",        0,      mipsfp3,
                    610:        "sqrt.%f",      0,      mipscofp2,
                    611:        "ABS%f",        0,      mipsfp2,
                    612:        "MOV%f",        0,      mipsfp2,
                    613:        "NEG%f",        0,      mipsfp2,
                    614:        "finstr08",     0,      mipscoxxx,
                    615:        "finstr09",     0,      mipscoxxx,
                    616:        "finstr0A",     0,      mipscoxxx,
                    617:        "finstr0B",     0,      mipscoxxx,
                    618:        "round.w.%f",   0,      mipscofp2,
                    619:        "trunc.w%f",    0,      mipscofp2,
                    620:        "ceil.w%f",     0,      mipscofp2,
                    621:        "floor.w%f",    0,      mipscofp2,
                    622:        "finstr10",     0,      mipscoxxx,
                    623:        "finstr11",     0,      mipscoxxx,
                    624:        "finstr12",     0,      mipscoxxx,
                    625:        "finstr13",     0,      mipscoxxx,
                    626:        "finstr14",     0,      mipscoxxx,
                    627:        "finstr15",     0,      mipscoxxx,
                    628:        "finstr16",     0,      mipscoxxx,
                    629:        "finstr17",     0,      mipscoxxx,
                    630:        "finstr18",     0,      mipscoxxx,
                    631:        "finstr19",     0,      mipscoxxx,
                    632:        "finstr1A",     0,      mipscoxxx,
                    633:        "finstr1B",     0,      mipscoxxx,
                    634:        "finstr1C",     0,      mipscoxxx,
                    635:        "finstr1D",     0,      mipscoxxx,
                    636:        "finstr1E",     0,      mipscoxxx,
                    637:        "finstr1F",     0,      mipscoxxx,
                    638:        "cvt.s.%f",     0,      mipscofp2,
                    639:        "cvt.d.%f",     0,      mipscofp2,
                    640:        "cvt.e.%f",     0,      mipscofp2,
                    641:        "cvt.q.%f",     0,      mipscofp2,
                    642:        "cvt.w.%f",     0,      mipscofp2,
                    643:        "finstr25",     0,      mipscoxxx,
                    644:        "finstr26",     0,      mipscoxxx,
                    645:        "finstr27",     0,      mipscoxxx,
                    646:        "finstr28",     0,      mipscoxxx,
                    647:        "finstr29",     0,      mipscoxxx,
                    648:        "finstr2A",     0,      mipscoxxx,
                    649:        "finstr2B",     0,      mipscoxxx,
                    650:        "finstr2C",     0,      mipscoxxx,
                    651:        "finstr2D",     0,      mipscoxxx,
                    652:        "finstr2E",     0,      mipscoxxx,
                    653:        "finstr2F",     0,      mipscoxxx,
                    654:        "c.f.%f",       0,      mipscofpc,
                    655:        "c.un.%f",      0,      mipscofpc,
                    656:        "CMPEQ%f",      0,      mipsfpc,
                    657:        "c.ueq.%f",     0,      mipscofpc,
                    658:        "c.olt.%f",     0,      mipscofpc,
                    659:        "c.ult.%f",     0,      mipscofpc,
                    660:        "c.ole.%f",     0,      mipscofpc,
                    661:        "c.ule.%f",     0,      mipscofpc,
                    662:        "c.sf.%f",      0,      mipscofpc,
                    663:        "c.ngle.%f",    0,      mipscofpc,
                    664:        "c.seq.%f",     0,      mipscofpc,
                    665:        "c.ngl.%f",     0,      mipscofpc,
                    666:        "CMPGT%f",      0,      mipsfpc,
                    667:        "c.nge.%f",     0,      mipscofpc,
                    668:        "CMPGE%f",      0,      mipsfpc,
                    669:        "c.ngt.%f",     0,      mipscofpc,
                    670: };
                    671: 
                    672: static char *cop0regs[32] = {
                    673:        "INDEX", "RANDOM", "TLBPHYS", "EntryLo0",
                    674:        "CONTEXT", "PageMask", "Wired", "Error",
                    675:        "BADVADDR", "Count", "TLBVIRT", "Compare",
                    676:        "STATUS", "CAUSE", "EPC", "PRID",
                    677:        "Config", "LLadr", "WatchLo", "WatchHi",
                    678:        "20", "21", "22", "23",
                    679:        "24", "25", "26", "CacheErr",
                    680:        "TagLo", "TagHi", "ErrorEPC", "31"
                    681: };
                    682: 
                    683: static char fsub[16] = {
                    684:        'F', 'D', 'e', 'q', 'W', '?', '?', '?',
                    685:        '?', '?', '?', '?', '?', '?', '?', '?'
                    686: };
                    687: 
                    688: static char *cacheps[] = {
                    689:        "I", "D", "SI", "SD"
                    690: };
                    691: 
                    692: static char *cacheop[] = {
                    693:        "IWBI", "ILT", "IST", "CDE", "HI", "HWBI", "HWB", "HSV"
                    694: };
                    695: 
                    696: static void
                    697: format(char *mnemonic, Instr *i, char *f)
                    698: {
                    699:        if (mnemonic)
                    700:                format(0, i, mnemonic);
                    701:        if (f == 0)
                    702:                return;
                    703:        if (mnemonic)
                    704:                if (i->curr < i->end)
                    705:                        *i->curr++ = '\t';
                    706:        for ( ; *f && i->curr < i->end; f++) {
                    707:                if (*f != '%') {
                    708:                        *i->curr++ = *f;
                    709:                        continue;
                    710:                }
                    711:                switch (*++f) {
                    712: 
                    713:                case 's':
                    714:                        bprint(i, "%d", i->rs);
                    715:                        break;
                    716: 
                    717:                case 't':
                    718:                        bprint(i, "%d", i->rt);
                    719:                        break;
                    720: 
                    721:                case 'd':
                    722:                        bprint(i, "%d", i->rd);
                    723:                        break;
                    724: 
                    725:                case 'a':
                    726:                        bprint(i, "%d", i->sa);
                    727:                        break;
                    728: 
                    729:                case 'l':
                    730:                        bprint(i, "%lx(R%d)",i->immediate, i->rs);
                    731:                        break;
                    732: 
                    733:                case 'i':
                    734:                        bprint(i, "$%lx", i->immediate);
                    735:                        break;
                    736: 
                    737:                case 'u':
                    738:                        i->curr += symoff(i->curr, i->end-i->curr, i->immediate, CANY);
                    739:                        bprint(i, "(SB)");
                    740:                        break;
                    741: 
                    742:                case 'j':
                    743:                        i->curr += symoff(i->curr, i->end-i->curr,
                    744:                                (i->target<<2)|(i->addr & 0xF0000000), CANY);
                    745:                        bprint(i, "(SB)");
                    746:                        break;
                    747: 
                    748:                case 'b':
                    749:                        i->curr += symoff(i->curr, i->end-i->curr,
                    750:                                (i->immediate<<2)+i->addr+4, CANY);
                    751:                        break;
                    752: 
                    753:                case 'c':
                    754:                        bprint(i, "$%lx", i->cofun);
                    755:                        break;
                    756: 
                    757:                case 'w':
                    758:                        bprint(i, "[%lux]", i->w0);
                    759:                        break;
                    760: 
                    761:                case 'm':
                    762:                        bprint(i, "M(%s)", cop0regs[i->rd]);
                    763:                        break;
                    764: 
                    765:                case 'f':
                    766:                        *i->curr++ = fsub[i->rs & 0x0F];
                    767:                        break;
                    768: 
                    769:                case 'C':
                    770:                        bprint(i, "%s%s", cacheps[i->rt & 3], cacheop[(i->rt>>2) & 7]);
                    771:                        break;
                    772: 
                    773:                case '\0':
                    774:                        *i->curr++ = '%';
                    775:                        return;
                    776: 
                    777:                default:
                    778:                        bprint(i, "%%%c", *f);
                    779:                        break;
                    780:                }
                    781:        }
                    782:        *i->curr = 0;
                    783: }
                    784: 
                    785: static void
                    786: copz(int cop, Instr *i)
                    787: {
                    788:        char *f, *m, buf[16];
                    789: 
                    790:        m = buf;
                    791:        f = "%t,%d";
                    792:        switch (i->rs) {
                    793: 
                    794:        case 0:
                    795:                sprint(buf, "mfc%d", cop);
                    796:                break;
                    797: 
                    798:        case 2:
                    799:                sprint(buf, "cfc%d", cop);
                    800:                break;
                    801: 
                    802:        case 4:
                    803:                sprint(buf, "mtc%d", cop);
                    804:                break;
                    805: 
                    806:        case 6:
                    807:                sprint(buf, "ctc%d", cop);
                    808:                break;
                    809: 
                    810:        case 8:
                    811:                f = "%b";
                    812:                switch (i->rt) {
                    813: 
                    814:                case 0:
                    815:                        sprint(buf, "bc%df", cop);
                    816:                        break;
                    817: 
                    818:                case 1:
                    819:                        sprint(buf, "bc%dt", cop);
                    820:                        break;
                    821: 
                    822:                case 2:
                    823:                        sprint(buf, "bc%dfl", cop);
                    824:                        break;
                    825: 
                    826:                case 3:
                    827:                        sprint(buf, "bc%dtl", cop);
                    828:                        break;
                    829: 
                    830:                default:
                    831:                        sprint(buf, "cop%d", cop);
                    832:                        f = mipscoxxx;
                    833:                        break;
                    834:                }
                    835:                break;
                    836: 
                    837:        default:
                    838:                sprint(buf, "cop%d", cop);
                    839:                if (i->rs & 0x10)
                    840:                        f = "function %c";
                    841:                else
                    842:                        f = mipscoxxx;
                    843:                break;
                    844:        }
                    845:        format(m, i, f);
                    846: }
                    847: 
                    848: static void
                    849: cop0(Instr *i)
                    850: {
                    851:        char *m = 0;
                    852: 
                    853:        if (i->rs < 8) {
                    854:                switch (i->rs) {
                    855: 
                    856:                case 0:
                    857:                case 1:
                    858:                        format("MOVW", i, "%m,R%t");
                    859:                        return;
                    860: 
                    861:                case 4:
                    862:                case 5:
                    863:                        format("MOVW", i, "R%t,%m");
                    864:                        return;
                    865:                }
                    866:        }
                    867:        else if (i->rs >= 0x10) {
                    868:                switch (i->cofun) {
                    869:        
                    870:                case 1:
                    871:                        m = "TLBR";
                    872:                        break;
                    873:        
                    874:                case 2:
                    875:                        m = "TLBWI";
                    876:                        break;
                    877:        
                    878:                case 6:
                    879:                        m = "TLBWR";
                    880:                        break;
                    881:        
                    882:                case 8:
                    883:                        m = "TLBP";
                    884:                        break;
                    885:        
                    886:                case 16:
                    887:                        m = "RFE";
                    888:                        break;
                    889:        
                    890:                case 32:
                    891:                        m = "ERET";
                    892:                        break;
                    893:                }
                    894:                if (m) {
                    895:                        format(m, i, 0);
                    896:                        return;
                    897:                }
                    898:        }
                    899:        copz(0, i);
                    900: }
                    901: 
                    902: static void
                    903: cop1(Instr *i)
                    904: {
                    905:        char *m = "MOVW";
                    906: 
                    907:        switch (i->rs) {
                    908: 
                    909:        case 0:
                    910:                format(m, i, "F%d,R%t");
                    911:                return;
                    912: 
                    913:        case 2:
                    914:                format(m, i, "FCR%d,R%t");
                    915:                return;
                    916: 
                    917:        case 4:
                    918:                format(m, i, "R%t,F%d");
                    919:                return;
                    920: 
                    921:        case 6:
                    922:                format(m, i, "R%t,FCR%d");
                    923:                return;
                    924: 
                    925:        case 8:
                    926:                switch (i->rt) {
                    927: 
                    928:                case 0:
                    929:                        format("BFPF", i, "%b");
                    930:                        return;
                    931: 
                    932:                case 1:
                    933:                        format("BFPT", i, "%b");
                    934:                        return;
                    935:                }
                    936:                break;
                    937:        }
                    938:        copz(1, i);
                    939: }
                    940: 
                    941: static int
                    942: printins(Map *map, ulong pc, char *buf, int n)
                    943: {
                    944:        Instr i;
                    945:        Opcode *o;
                    946:        uchar op;
                    947: 
                    948:        i.curr = buf;
                    949:        i.end = buf+n-1;
                    950:        mymap = map;
                    951:        if (mkinstr(pc, &i) < 0)
                    952:                return -1;
                    953:        switch (i.op) {
                    954: 
                    955:        case 0x00:                                      /* SPECIAL */
                    956:                o = sopcodes;
                    957:                op = i.function;
                    958:                break;
                    959: 
                    960:        case 0x01:                                      /* REGIMM */
                    961:                o = ropcodes;
                    962:                op = i.rt;
                    963:                break;
                    964: 
                    965:        case 0x10:                                      /* COP0 */
                    966:                cop0(&i);
                    967:                return i.size*4;
                    968: 
                    969:        case 0x11:                                      /* COP1 */
                    970:                if (i.rs & 0x10) {
                    971:                        o = fopcodes;
                    972:                        op = i.function;
                    973:                        break;
                    974:                }
                    975:                cop1(&i);
                    976:                return i.size*4;
                    977: 
                    978:        case 0x12:                                      /* COP2 */
                    979:        case 0x13:                                      /* COP3 */
                    980:                copz(i.op-0x10, &i);
                    981:                return i.size*4;
                    982: 
                    983:        default:
                    984:                o = opcodes;
                    985:                op = i.op;
                    986:                break;
                    987:        }
                    988:        if (o[op].f)
                    989:                (*o[op].f)(&o[op], &i);
                    990:        else
                    991:                format(o[op].mnemonic, &i, o[op].ken);
                    992:        return i.size*4;
                    993: }
                    994: 
                    995: extern int     _mipscoinst(Map *, ulong, char*, int);
                    996: 
                    997:        /* modifier 'I' toggles the default disassembler type */
                    998: static int
                    999: mipsinst(Map *map, ulong pc, char modifier, char *buf, int n)
                   1000: {
                   1001:        if ((asstype == AMIPSCO && modifier == 'i')
                   1002:                || (asstype == AMIPS && modifier == 'I'))
                   1003:                return _mipscoinst(map, pc, buf, n);
                   1004:        else
                   1005:                return printins(map, pc, buf, n);
                   1006: }
                   1007: 
                   1008: static int
                   1009: mipsdas(Map *map, ulong pc, char *buf, int n)
                   1010: {
                   1011:        Instr i;
                   1012: 
                   1013:        i.curr = buf;
                   1014:        i.end = buf+n;
                   1015:        mymap = map;
                   1016:        if (mkinstr(pc, &i) < 0)
                   1017:                return -1;
                   1018:        if (i.end-i.curr > 8)
                   1019:                i.curr = _hexify(buf, i.w0, 7);
                   1020:        if (i.size == 2 && i.end-i.curr > 9) {
                   1021:                *i.curr++ = ' ';
                   1022:                i.curr = _hexify(i.curr, i.w1, 7);
                   1023:        }
                   1024:        *i.curr = 0;
                   1025:        return i.size*4;
                   1026: }
                   1027: 
                   1028: static int
                   1029: mipsinstlen(Map *map, ulong pc)
                   1030: {
                   1031:        Instr i;
                   1032: 
                   1033:        mymap = map;
                   1034:        if (mkinstr(pc, &i) < 0)
                   1035:                return -1;
                   1036:        return i.size*4;
                   1037: }
                   1038: 
                   1039: static int
                   1040: mipsfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
                   1041: {
                   1042:        ulong w, l;
                   1043:        char buf[8];
                   1044:        Instr i;
                   1045: 
                   1046:        mymap = map;
                   1047:        if (mkinstr(pc, &i) < 0)
                   1048:                return -1;
                   1049:        w = i.w0;
                   1050:        if((w&0xF3600000) == 0x41000000){       /* branch on coprocessor */
                   1051:     Conditional:
                   1052:                foll[0] = pc+8;
                   1053:                l = ((w&0xFFFF)<<2);
                   1054:                if(w & 0x8000)
                   1055:                        l |= 0xFFFC0000;
                   1056:                foll[1] = pc+4 + l;
                   1057:                return 2;
                   1058:        }
                   1059: 
                   1060:        l = (w&0xFC000000)>>26;
                   1061:        switch(l){
                   1062:        case 0:         /* SPECIAL */
                   1063:                if((w&0x3E) == 0x08){   /* JR, JALR */
                   1064:                        sprint(buf, "R%d", (w>>21)&0x1F);
                   1065:                        foll[0] = (*rget)(map, buf);
                   1066:                        return 1;
                   1067:                }
                   1068:                foll[0] = pc+i.size*4;
                   1069:                return 1;
                   1070:        case 0x30:      /* Load-Linked followed by NOP, STC */
                   1071:                foll[0] = pc+12;
                   1072:                return 1;
                   1073:        case 1:         /* BCOND */
                   1074:        case 4:         /* BEQ */
                   1075:        case 5:         /* BNE */
                   1076:        case 6:         /* BLEZ */
                   1077:        case 7:         /* BGTZ */
                   1078:                goto Conditional;
                   1079:        case 2:         /* J */
                   1080:        case 3:         /* JAL */
                   1081:                foll[0] = (pc&0xF0000000) | ((w&0x03FFFFFF)<<2);
                   1082:                return 1;
                   1083:        }
                   1084: 
                   1085:        foll[0] = pc+i.size*4;
                   1086:        return 1;
                   1087: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.