Annotation of lucent/sys/src/libmach/vdb.c, revision 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.