Annotation of lucent/sys/src/libmach/vcodas.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 native disassembler */
                      7: 
                      8: typedef struct {
                      9:        long addr;                      /* pc of instr */
                     10:        uchar op;                       /* bits 31-26 */
                     11:        uchar rs;                       /* bits 25-21 */
                     12:        uchar rt;                       /* bits 20-16 */
                     13:        uchar rd;                       /* bits 15-11 */
                     14:        uchar sa;                       /* bits 10-6 */
                     15:        uchar function;                 /* bits 5-0 */
                     16:        long immediate;                 /* bits 15-0 */
                     17:        ulong cofun;                    /* bits 24-0 */
                     18:        ulong target;                   /* bits 25-0 */
                     19:        long w0;
                     20:        char *curr;                     /* current fill point */
                     21:        char *end;                      /* end of buffer */
                     22:        char *err;
                     23: } Instr;
                     24: 
                     25: typedef struct {
                     26:        char *mnemonic;
                     27:        char *mipsco;
                     28: } Opcode;
                     29: 
                     30: static char mipscoload[] = "r%t,%l";
                     31: static char mipscoalui[] = "r%t,r%s,%i";
                     32: static char mipscoalu3op[] = "r%d,r%s,r%t";
                     33: static char mipscoboc[] = "r%s,r%t,%b";
                     34: static char mipscoboc0[] = "r%s,%b";
                     35: static char mipscorsrt[] = "r%s,r%t";
                     36: static char mipscorsi[] = "r%s,%i";
                     37: static char mipscoxxx[] = "%w";
                     38: static char mipscofp3[] = "f%a,f%d,f%t";       /* fd,fs,ft */
                     39: static char mipscofp2[] = "f%a,f%d";           /* fd,fs */
                     40: static char mipscofpc[] = "f%d,f%t";           /* fs,ft */
                     41: 
                     42: static Opcode opcodes[64] = {
                     43:        0,              0,
                     44:        0,              0,
                     45:        "j",            "%j",
                     46:        "jal",          "%j",
                     47:        "beq",          mipscoboc,
                     48:        "bne",          mipscoboc,
                     49:        "blez",         mipscoboc0,
                     50:        "bgtz",         mipscoboc0,
                     51:        "addi",         mipscoalui,
                     52:        "addiu",        mipscoalui,
                     53:        "slti",         mipscoalui,
                     54:        "sltiu",        mipscoalui,
                     55:        "andi",         mipscoalui,
                     56:        "ori",          mipscoalui,
                     57:        "xori",         mipscoalui,
                     58:        "lui",          "r%t,%u",
                     59:        "cop0",         0,
                     60:        "cop1",         0,
                     61:        "cop2",         0,
                     62:        "cop3",         0,
                     63:        "beql",         mipscoboc,
                     64:        "bnel",         mipscoboc,
                     65:        "blezl",        mipscoboc0,
                     66:        "bgtzl",        mipscoboc0,
                     67:        "instr18",      mipscoxxx,
                     68:        "instr19",      mipscoxxx,
                     69:        "instr1A",      mipscoxxx,
                     70:        "instr1B",      mipscoxxx,
                     71:        "instr1C",      mipscoxxx,
                     72:        "instr1D",      mipscoxxx,
                     73:        "instr1E",      mipscoxxx,
                     74:        "instr1F",      mipscoxxx,
                     75:        "lb",           mipscoload,
                     76:        "lh",           mipscoload,
                     77:        "lwl",          mipscoload,
                     78:        "lw",           mipscoload,
                     79:        "lbu",          mipscoload,
                     80:        "lhu",          mipscoload,
                     81:        "lwr",          mipscoload,
                     82:        "instr27",      mipscoxxx,
                     83:        "sb",           mipscoload,
                     84:        "sh",           mipscoload,
                     85:        "swl",          mipscoload,
                     86:        "sw",           mipscoload,
                     87:        "instr2C",      mipscoxxx,
                     88:        "instr2D",      mipscoxxx,
                     89:        "swr",          mipscoload,
                     90:        "cache",        "",
                     91:        "ll",           mipscoload,
                     92:        "lwc1",         mipscoload,
                     93:        "lwc2",         mipscoload,
                     94:        "lwc3",         mipscoload,
                     95:        "instr34",      mipscoxxx,
                     96:        "ld",           mipscoload,
                     97:        "ld",           mipscoload,
                     98:        "ld",           mipscoload,
                     99:        "sc",           mipscoload,
                    100:        "swc1",         mipscoload,
                    101:        "swc2",         mipscoload,
                    102:        "swc3",         mipscoload,
                    103:        "instr3C",      mipscoxxx,
                    104:        "sd",           mipscoload,
                    105:        "sd",           mipscoload,
                    106:        "sd",           mipscoload,
                    107: };
                    108: 
                    109: static Opcode sopcodes[64] = {
                    110:        "sll",          "r%d,r%t,$%a",
                    111:        "special01",    mipscoxxx,
                    112:        "srl",          "r%d,r%t,$%a",
                    113:        "sra",          "r%d,r%t,$%a",
                    114:        "sllv",         "r%d,r%t,R%s",
                    115:        "special05",    mipscoxxx,
                    116:        "srlv",         "r%d,r%t,r%s",
                    117:        "srav",         "r%d,r%t,r%s",
                    118:        "jr",           "r%s",
                    119:        "jalr",         "r%d,r%s",
                    120:        "special0A",    mipscoxxx,
                    121:        "special0B",    mipscoxxx,
                    122:        "syscall",      "",
                    123:        "break",        "",
                    124:        "special0E",    mipscoxxx,
                    125:        "sync",         "",
                    126:        "mfhi",         "r%d",
                    127:        "mthi",         "r%s",
                    128:        "mflo",         "r%d",
                    129:        "mtlo",         "r%s",
                    130:        "special14",    mipscoxxx,
                    131:        "special15",    mipscoxxx,
                    132:        "special16",    mipscoxxx,
                    133:        "special17",    mipscoxxx,
                    134:        "mult",         mipscorsrt,
                    135:        "multu",        mipscorsrt,
                    136:        "div",          mipscorsrt,
                    137:        "divu",         mipscorsrt,
                    138:        "special1C",    mipscoxxx,
                    139:        "special1D",    mipscoxxx,
                    140:        "special1E",    mipscoxxx,
                    141:        "special1F",    mipscoxxx,
                    142:        "add",          mipscoalu3op,
                    143:        "addu",         mipscoalu3op,
                    144:        "sub",          mipscoalu3op,
                    145:        "subu",         mipscoalu3op,
                    146:        "and",          mipscoalu3op,
                    147:        "or",           mipscoalu3op,
                    148:        "xor",          mipscoalu3op,
                    149:        "nor",          mipscoalu3op,
                    150:        "special28",    mipscoxxx,
                    151:        "special29",    mipscoxxx,
                    152:        "slt",          mipscoalu3op,
                    153:        "sltu",         mipscoalu3op,
                    154:        "special2C",    mipscoxxx,
                    155:        "special2D",    mipscoxxx,
                    156:        "special2E",    mipscoxxx,
                    157:        "special2F",    mipscoxxx,
                    158:        "tge",          mipscorsrt,
                    159:        "tgeu",         mipscorsrt,
                    160:        "tlt",          mipscorsrt,
                    161:        "tltu",         mipscorsrt,
                    162:        "teq",          mipscorsrt,
                    163:        "special35",    mipscoxxx,
                    164:        "tne",          mipscorsrt,
                    165:        "special37",    mipscoxxx,
                    166:        "special38",    mipscoxxx,
                    167:        "special39",    mipscoxxx,
                    168:        "special3A",    mipscoxxx,
                    169:        "special3B",    mipscoxxx,
                    170:        "special3C",    mipscoxxx,
                    171:        "special3D",    mipscoxxx,
                    172:        "special3E",    mipscoxxx,
                    173:        "special3F",    mipscoxxx,
                    174: };
                    175: 
                    176: static Opcode ropcodes[32] = {
                    177:        "bltz",         mipscoboc0,
                    178:        "bgez",         mipscoboc0,
                    179:        "bltzl",        mipscoboc0,
                    180:        "bgezl",        mipscoboc0,
                    181:        "regimm04",     mipscoxxx,
                    182:        "regimm05",     mipscoxxx,
                    183:        "regimm06",     mipscoxxx,
                    184:        "regimm07",     mipscoxxx,
                    185:        "tgei",         mipscorsi,
                    186:        "tgeiu",        mipscorsi,
                    187:        "tlti",         mipscorsi,
                    188:        "tltiu",        mipscorsi,
                    189:        "teqi",         mipscorsi,
                    190:        "regimm0D",     mipscoxxx,
                    191:        "tnei",         mipscorsi,
                    192:        "regimm0F",     mipscoxxx,
                    193:        "bltzal",       mipscoboc0,
                    194:        "bgezal",       mipscoboc0,
                    195:        "bltzall",      mipscoboc0,
                    196:        "bgezall",      mipscoboc0,
                    197:        "regimm14",     mipscoxxx,
                    198:        "regimm15",     mipscoxxx,
                    199:        "regimm16",     mipscoxxx,
                    200:        "regimm17",     mipscoxxx,
                    201:        "regimm18",     mipscoxxx,
                    202:        "regimm19",     mipscoxxx,
                    203:        "regimm1A",     mipscoxxx,
                    204:        "regimm1B",     mipscoxxx,
                    205:        "regimm1C",     mipscoxxx,
                    206:        "regimm1D",     mipscoxxx,
                    207:        "regimm1E",     mipscoxxx,
                    208:        "regimm1F",     mipscoxxx,
                    209: };
                    210: 
                    211: static Opcode fopcodes[64] = {
                    212:        "add.%f",       mipscofp3,
                    213:        "sub.%f",       mipscofp3,
                    214:        "mul.%f",       mipscofp3,
                    215:        "div.%f",       mipscofp3,
                    216:        "sqrt.%f",      mipscofp2,
                    217:        "abs.%f",       mipscofp2,
                    218:        "mov.%f",       mipscofp2,
                    219:        "neg.%f",       mipscofp2,
                    220:        "finstr08",     mipscoxxx,
                    221:        "finstr09",     mipscoxxx,
                    222:        "finstr0A",     mipscoxxx,
                    223:        "finstr0B",     mipscoxxx,
                    224:        "round.w.%f",   mipscofp2,
                    225:        "trunc.w%f",    mipscofp2,
                    226:        "ceil.w%f",     mipscofp2,
                    227:        "floor.w%f",    mipscofp2,
                    228:        "finstr10",     mipscoxxx,
                    229:        "finstr11",     mipscoxxx,
                    230:        "finstr12",     mipscoxxx,
                    231:        "finstr13",     mipscoxxx,
                    232:        "finstr14",     mipscoxxx,
                    233:        "finstr15",     mipscoxxx,
                    234:        "finstr16",     mipscoxxx,
                    235:        "finstr17",     mipscoxxx,
                    236:        "finstr18",     mipscoxxx,
                    237:        "finstr19",     mipscoxxx,
                    238:        "finstr1A",     mipscoxxx,
                    239:        "finstr1B",     mipscoxxx,
                    240:        "finstr1C",     mipscoxxx,
                    241:        "finstr1D",     mipscoxxx,
                    242:        "finstr1E",     mipscoxxx,
                    243:        "finstr1F",     mipscoxxx,
                    244:        "cvt.s.%f",     mipscofp2,
                    245:        "cvt.d.%f",     mipscofp2,
                    246:        "cvt.e.%f",     mipscofp2,
                    247:        "cvt.q.%f",     mipscofp2,
                    248:        "cvt.w.%f",     mipscofp2,
                    249:        "finstr25",     mipscoxxx,
                    250:        "finstr26",     mipscoxxx,
                    251:        "finstr27",     mipscoxxx,
                    252:        "finstr28",     mipscoxxx,
                    253:        "finstr29",     mipscoxxx,
                    254:        "finstr2A",     mipscoxxx,
                    255:        "finstr2B",     mipscoxxx,
                    256:        "finstr2C",     mipscoxxx,
                    257:        "finstr2D",     mipscoxxx,
                    258:        "finstr2E",     mipscoxxx,
                    259:        "finstr2F",     mipscoxxx,
                    260:        "c.f.%f",       mipscofpc,
                    261:        "c.un.%f",      mipscofpc,
                    262:        "c.eq.%f",      mipscofpc,
                    263:        "c.ueq.%f",     mipscofpc,
                    264:        "c.olt.%f",     mipscofpc,
                    265:        "c.ult.%f",     mipscofpc,
                    266:        "c.ole.%f",     mipscofpc,
                    267:        "c.ule.%f",     mipscofpc,
                    268:        "c.sf.%f",      mipscofpc,
                    269:        "c.ngle.%f",    mipscofpc,
                    270:        "c.seq.%f",     mipscofpc,
                    271:        "c.ngl.%f",     mipscofpc,
                    272:        "c.lt.%f",      mipscofpc,
                    273:        "c.nge.%f",     mipscofpc,
                    274:        "c.le.%f",      mipscofpc,
                    275:        "c.ngt.%f",     mipscofpc,
                    276: };
                    277: 
                    278: static char fsub[16] = {
                    279:        's', 'd', 'e', 'q', 'w', '?', '?', '?',
                    280:        '?', '?', '?', '?', '?', '?', '?', '?'
                    281: };
                    282: 
                    283: 
                    284: static int
                    285: mkinstr(Instr *i, Map *map, ulong pc)
                    286: {
                    287:        long w;
                    288: 
                    289:        if (get4(map, pc, &w) < 0) {
                    290:                werrstr("can't read instruction: %r");
                    291:                return -1;
                    292:        }
                    293:        i->addr = pc;
                    294:        i->op = (w >> 26) & 0x3F;
                    295:        i->rs = (w >> 21) & 0x1F;
                    296:        i->rt = (w >> 16) & 0x1F;
                    297:        i->rd = (w >> 11) & 0x1F;
                    298:        i->sa = (w >> 6) & 0x1F;
                    299:        i->function = w & 0x3F;
                    300:        i->immediate = w & 0x0000FFFF;
                    301:        if (i->immediate & 0x8000)
                    302:                i->immediate |= ~0x0000FFFF;
                    303:        i->cofun = w & 0x01FFFFFF;
                    304:        i->target = w & 0x03FFFFFF;
                    305:        i->w0 = w;
                    306:        return 1;
                    307: }
                    308: 
                    309: static void
                    310: bprint(Instr *i, char *fmt, ...)
                    311: {
                    312:        i->curr = doprint(i->curr, i->end, fmt, (&fmt+1));
                    313: }
                    314: 
                    315: static void
                    316: format(char *mnemonic, Instr *i, char *f)
                    317: {
                    318:        if (mnemonic)
                    319:                format(0, i, mnemonic);
                    320:        if (f == 0)
                    321:                return;
                    322:        if (i->curr < i->end)
                    323:                *i->curr++ = '\t';
                    324:        for ( ; *f && i->curr < i->end; f++) {
                    325:                if (*f != '%') {
                    326:                        *i->curr++ = *f;
                    327:                        continue;
                    328:                }
                    329:                switch (*++f) {
                    330: 
                    331:                case 's':
                    332:                        bprint(i, "%d", i->rs);
                    333:                        break;
                    334: 
                    335:                case 't':
                    336:                        bprint(i, "%d", i->rt);
                    337:                        break;
                    338: 
                    339:                case 'd':
                    340:                        bprint(i, "%d", i->rd);
                    341:                        break;
                    342: 
                    343:                case 'a':
                    344:                        bprint(i, "%d", i->sa);
                    345:                        break;
                    346: 
                    347:                case 'l':
                    348:                        if (i->rs == 30) {
                    349:                                i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);
                    350:                                bprint(i, "(SB)");
                    351:                        } else 
                    352:                                bprint(i, "%lx(r%d)", i->immediate, i->rs);
                    353:                        break;
                    354: 
                    355:                case 'i':
                    356:                        bprint(i, "$%lx", i->immediate);
                    357:                        break;
                    358: 
                    359:                case 'u':
                    360:                        *i->curr++ = '$';
                    361:                        i->curr += symoff(i->curr, i->end-i->curr, i->immediate, CANY);
                    362:                        bprint(i, "(SB)");
                    363:                        break;
                    364: 
                    365:                case 'j':
                    366:                        i->curr += symoff(i->curr, i->end-i->curr,
                    367:                                (i->target<<2)|(i->addr & 0xF0000000), CANY);
                    368:                        bprint(i, "(SB)");
                    369:                        break;
                    370: 
                    371:                case 'b':
                    372:                        i->curr += symoff(i->curr, i->end-i->curr,
                    373:                                (i->immediate<<2)+i->addr+4, CANY);
                    374:                        break;
                    375: 
                    376:                case 'c':
                    377:                        bprint(i, "%lux", i->cofun);
                    378:                        break;
                    379: 
                    380:                case 'w':
                    381:                        bprint(i, "[%lux]", i->w0);
                    382:                        break;
                    383: 
                    384:                case 'f':
                    385:                        *i->curr++ = fsub[i->rs & 0x0F];
                    386:                        break;
                    387: 
                    388:                case '\0':
                    389:                        *i->curr++ = '%';
                    390:                        return;
                    391: 
                    392:                default:
                    393:                        bprint(i, "%%%c", *f);
                    394:                        break;
                    395:                }
                    396:        }
                    397: }
                    398: 
                    399: static void
                    400: copz(int cop, Instr *i)
                    401: {
                    402:        char *f, *m, buf[16];
                    403: 
                    404:        m = buf;
                    405:        f = "%t,%d";
                    406:        switch (i->rs) {
                    407: 
                    408:        case 0:
                    409:                sprint(buf, "mfc%d", cop);
                    410:                break;
                    411: 
                    412:        case 2:
                    413:                sprint(buf, "cfc%d", cop);
                    414:                break;
                    415: 
                    416:        case 4:
                    417:                sprint(buf, "mtc%d", cop);
                    418:                break;
                    419: 
                    420:        case 6:
                    421:                sprint(buf, "ctc%d", cop);
                    422:                break;
                    423: 
                    424:        case 8:
                    425:                f = "%b";
                    426:                switch (i->rt) {
                    427: 
                    428:                case 0:
                    429:                        sprint(buf, "bc%df", cop);
                    430:                        break;
                    431: 
                    432:                case 1:
                    433:                        sprint(buf, "bc%dt", cop);
                    434:                        break;
                    435: 
                    436:                case 2:
                    437:                        sprint(buf, "bc%dfl", cop);
                    438:                        break;
                    439: 
                    440:                case 3:
                    441:                        sprint(buf, "bc%dtl", cop);
                    442:                        break;
                    443: 
                    444:                default:
                    445:                        sprint(buf, "cop%d", cop);
                    446:                        f = mipscoxxx;
                    447:                        break;
                    448:                }
                    449:                break;
                    450: 
                    451:        default:
                    452:                sprint(buf, "cop%d", cop);
                    453:                if (i->rs & 0x10)
                    454:                        f = "function %c";
                    455:                else
                    456:                        f = mipscoxxx;
                    457:                break;
                    458:        }
                    459:        format(m, i, f);
                    460: }
                    461: 
                    462: static void
                    463: cop0(Instr *i)
                    464: {
                    465:        char *m = 0;
                    466: 
                    467:        if (i->rs >= 0x10) {
                    468:                switch (i->cofun) {
                    469:        
                    470:                case 1:
                    471:                        m = "tlbr";
                    472:                        break;
                    473:        
                    474:                case 2:
                    475:                        m = "tlbwi";
                    476:                        break;
                    477:        
                    478:                case 6:
                    479:                        m = "tlbwr";
                    480:                        break;
                    481:        
                    482:                case 8:
                    483:                        m = "tlbp";
                    484:                        break;
                    485:        
                    486:                case 16:
                    487:                        m = "rfe";
                    488:                        break;
                    489:        
                    490:                case 32:
                    491:                        m = "eret";
                    492:                        break;
                    493:                }
                    494:                if (m) {
                    495:                        format(m, i, 0);
                    496:                        if (i->curr < i->end)
                    497:                                *i->curr++ = 0;
                    498:                        return;
                    499:                }
                    500:        }
                    501:        copz(0, i);
                    502: }
                    503: 
                    504: int
                    505: _mipscoinst(Map *map, ulong pc, char *buf, int n)
                    506: {
                    507:        Instr i;
                    508:        Opcode *o;
                    509:        uchar op;
                    510: 
                    511:        i.curr = buf;
                    512:        i.end = buf+n-1;
                    513:        if (mkinstr(&i, map, pc) < 0)
                    514:                return -1;
                    515:        switch (i.op) {
                    516: 
                    517:        case 0x00:                                      /* SPECIAL */
                    518:                o = sopcodes;
                    519:                op = i.function;
                    520:                break;
                    521: 
                    522:        case 0x01:                                      /* REGIMM */
                    523:                o = ropcodes;
                    524:                op = i.rt;
                    525:                break;
                    526: 
                    527:        case 0x10:                                      /* COP0 */
                    528:                cop0(&i);
                    529:                return 4;
                    530: 
                    531:        case 0x11:                                      /* COP1 */
                    532:                if (i.rs & 0x10) {
                    533:                        o = fopcodes;
                    534:                        op = i.function;
                    535:                        break;
                    536:                }
                    537:                /*FALLTHROUGH*/
                    538:        case 0x12:                                      /* COP2 */
                    539:        case 0x13:                                      /* COP3 */
                    540:                copz(i.op-0x10, &i);
                    541:                return 4;
                    542: 
                    543:        default:
                    544:                o = opcodes;
                    545:                op = i.op;
                    546:                break;
                    547:        }
                    548:        format(o[op].mnemonic, &i, o[op].mipsco);
                    549:        return 4;
                    550: }

unix.superglobalmegacorp.com

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