Annotation of lucent/sys/src/libmach/vcodas.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 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.