Annotation of lucent/sys/src/libmach/kdb.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: /*
        !             7:  * Sparc-specific debugger interface
        !             8:  */
        !             9: 
        !            10: static char    *sparcexcep(Map*, Rgetter);
        !            11: static int     sparcfoll(Map*, ulong, Rgetter, ulong*);
        !            12: static int     sparcinst(Map*, ulong, char, char*, int);
        !            13: static int     sparcdas(Map*, ulong, char*, int);
        !            14: static int     sparcinstlen(Map*, ulong);
        !            15: 
        !            16: Machdata sparcmach =
        !            17: {
        !            18:        {0x91, 0xd0, 0x20, 0x01},       /* breakpoint: TA $1 */
        !            19:        4,                      /* break point size */
        !            20: 
        !            21:        beswab,                 /* convert short to local byte order */
        !            22:        beswal,                 /* convert long to local byte order */
        !            23:        risctrace,              /* C traceback */
        !            24:        riscframe,              /* frame finder */
        !            25:        0,                      /* ublock fixup */
        !            26:        sparcexcep,             /* print exception */
        !            27:        0,                      /* breakpoint fixup */
        !            28:        beieeesftos,            /* single precision float printer */
        !            29:        beieeedftos,            /* double precision float printer */
        !            30:        sparcfoll,              /* following addresses */
        !            31:        sparcinst,              /* print instruction */
        !            32:        sparcdas,               /* dissembler */
        !            33:        sparcinstlen,           /* instruction size */
        !            34: };
        !            35: 
        !            36: static char *trapname[] =
        !            37: {
        !            38:        "reset",
        !            39:        "instruction access exception",
        !            40:        "illegal instruction",
        !            41:        "privileged instruction",
        !            42:        "fp disabled",
        !            43:        "window overflow",
        !            44:        "window underflow",
        !            45:        "unaligned address",
        !            46:        "fp exception",
        !            47:        "data access exception",
        !            48:        "tag overflow",
        !            49: };
        !            50: 
        !            51: static char*
        !            52: excname(ulong tbr)
        !            53: {
        !            54:        static char buf[32];
        !            55: 
        !            56:        if(tbr < sizeof trapname/sizeof(char*))
        !            57:                return trapname[tbr];
        !            58:        if(tbr >= 130)
        !            59:                sprint(buf, "trap instruction %d", tbr-128);
        !            60:        else if(17<=tbr && tbr<=31)
        !            61:                sprint(buf, "interrupt level %d", tbr-16);
        !            62:        else switch(tbr){
        !            63:        case 36:
        !            64:                return "cp disabled";
        !            65:        case 40:
        !            66:                return "cp exception";
        !            67:        case 128:
        !            68:                return "syscall";
        !            69:        case 129:
        !            70:                return "breakpoint";
        !            71:        default:
        !            72:                sprint(buf, "unknown trap %d", tbr);
        !            73:        }
        !            74:     Return:
        !            75:        return buf;
        !            76: }
        !            77: 
        !            78: static char*
        !            79: sparcexcep(Map *map, Rgetter rget)
        !            80: {
        !            81:        long tbr;
        !            82: 
        !            83:        tbr = (*rget)(map, "TBR");
        !            84:        tbr = (tbr&0xFFF)>>4;
        !            85:        return excname(tbr);
        !            86: }
        !            87: 
        !            88:        /* Sparc disassembler and related functions */
        !            89: 
        !            90: struct opcode {
        !            91:        char    *mnemonic;
        !            92:        void    (*f)(struct instr*, char*);
        !            93:        int     flag;
        !            94: };
        !            95: 
        !            96: static char FRAMENAME[] = ".frame";
        !            97: 
        !            98: typedef struct instr Instr;
        !            99: 
        !           100: struct instr {
        !           101:        uchar   op;             /* bits 31-30 */
        !           102:        uchar   rd;             /* bits 29-25 */
        !           103:        uchar   op2;            /* bits 24-22 */
        !           104:        uchar   a;              /* bit  29    */
        !           105:        uchar   cond;           /* bits 28-25 */
        !           106:        uchar   op3;            /* bits 24-19 */
        !           107:        uchar   rs1;            /* bits 18-14 */
        !           108:        uchar   i;              /* bit  13    */
        !           109:        uchar   asi;            /* bits 12-05 */
        !           110:        uchar   rs2;            /* bits 04-00 */
        !           111:        short   simm13;         /* bits 12-00, signed */
        !           112:        ushort  opf;            /* bits 13-05 */
        !           113:        ulong   immdisp22;      /* bits 21-00 */
        !           114:        ulong   simmdisp22;     /* bits 21-00, signed */
        !           115:        ulong   disp30;         /* bits 30-00 */
        !           116:        ulong   imm32;          /* SETHI+ADD constant */
        !           117:        int     target;         /* SETHI+ADD dest reg */
        !           118:        long    w0;
        !           119:        long    w1;
        !           120:        ulong   addr;           /* pc of instruction */
        !           121:        char    *curr;          /* current fill level in output buffer */
        !           122:        char    *end;           /* end of buffer */
        !           123:        int     size;           /* number of longs in instr */
        !           124:        char    *err;           /* errmsg */
        !           125: };
        !           126: 
        !           127: static Map     *mymap;         /* disassembler context */
        !           128: static int     dascase;
        !           129: 
        !           130: static int     mkinstr(ulong, Instr*);
        !           131: static void    bra1(Instr*, char*, char*[]);
        !           132: static void    bra(Instr*, char*);
        !           133: static void    fbra(Instr*, char*);
        !           134: static void    cbra(Instr*, char*);
        !           135: static void    unimp(Instr*, char*);
        !           136: static void    fpop(Instr*, char*);
        !           137: static void    shift(Instr*, char*);
        !           138: static void    sethi(Instr*, char*);
        !           139: static void    load(Instr*, char*);
        !           140: static void    loada(Instr*, char*);
        !           141: static void    store(Instr*, char*);
        !           142: static void    storea(Instr*, char*);
        !           143: static void    add(Instr*, char*);
        !           144: static void    cmp(Instr*, char*);
        !           145: static void    wr(Instr*, char*);
        !           146: static void    jmpl(Instr*, char*);
        !           147: static void    rd(Instr*, char*);
        !           148: static void    loadf(Instr*, char*);
        !           149: static void    storef(Instr*, char*);
        !           150: static void    loadc(Instr*, char*);
        !           151: static void    loadcsr(Instr*, char*);
        !           152: static void    trap(Instr*, char*);
        !           153: 
        !           154: static struct opcode sparcop0[8] = {
        !           155:        [0]     "UNIMP",        unimp,  0,      /* page 137 */
        !           156:        [2]     "B",            bra,    0,      /* page 119 */
        !           157:        [4]     "SETHI",        sethi,  0,      /* page 104 */
        !           158:        [6]     "FB",           fbra,   0,      /* page 121 */
        !           159:        [7]     "CB",           cbra,   0,      /* page 123 */
        !           160: };
        !           161: 
        !           162: static struct opcode sparcop2[64] = {
        !           163:        [0x00]  "ADD",          add,    0,      /* page 108 */
        !           164:        [0x10]  "ADDCC",        add,    0,
        !           165:        [0x08]  "ADDX",         add,    0,
        !           166:        [0x18]  "ADDXCC",       add,    0,
        !           167: 
        !           168:        [0x20]  "TADD",         add,    0,      /* page 109 */
        !           169:        [0x22]  "TADDCCTV",     add,    0,
        !           170: 
        !           171:        [0x04]  "SUB",          add,    0,      /* page 110 */
        !           172:        [0x14]  "SUBCC",        cmp,    0,
        !           173:        [0x0C]  "SUBX",         add,    0,
        !           174:        [0x1C]  "SUBXCC",       add,    0,
        !           175: 
        !           176:        [0x21]  "TSUB",         add,    0,      /* page 111 */
        !           177:        [0x23]  "TSUBCCTV",     add,    0,
        !           178: 
        !           179:        [0x24]  "MULSCC",       add,    0,      /* page 112 */
        !           180: 
        !           181:        [0x0A]  "UMUL",         add,    0,      /* page 113 */
        !           182:        [0x0B]  "SMUL",         add,    0,
        !           183:        [0x1A]  "UMULCC",       add,    0,
        !           184:        [0x1B]  "SMULCC",       add,    0,
        !           185: 
        !           186:        [0x0E]  "UDIV",         add,    0,      /* page 115 */
        !           187:        [0x0F]  "SDIV",         add,    0,
        !           188:        [0x1E]  "UDIVCC",       add,    0,
        !           189:        [0x1F]  "SDIVCC",       add,    0,
        !           190: 
        !           191:        [0x01]  "AND",          add,    0,      /* page 106 */
        !           192:        [0x11]  "ANDCC",        add,    0,
        !           193:        [0x05]  "ANDN",         add,    0,
        !           194:        [0x15]  "ANDNCC",       add,    0,
        !           195:        [0x02]  "OR",           add,    0,
        !           196:        [0x12]  "ORCC",         add,    0,
        !           197:        [0x06]  "ORN",          add,    0,
        !           198:        [0x16]  "ORNCC",        add,    0,
        !           199:        [0x03]  "XOR",          add,    0,
        !           200:        [0x13]  "XORCC",        add,    0,
        !           201:        [0x07]  "XORN",         add,    0,
        !           202:        [0x17]  "XORNCC",       add,    0,
        !           203: 
        !           204:        [0x25]  "SLL",          shift,  0,      /* page 107 */
        !           205:        [0x26]  "SRL",          shift,  0,
        !           206:        [0x27]  "SRA",          shift,  0,
        !           207: 
        !           208:        [0x3C]  "SAVE",         add,    0,      /* page 117 */
        !           209:        [0x3D]  "RESTORE",      add,    0,
        !           210: 
        !           211:        [0x38]  "JMPL",         jmpl,   0,      /* page 126 */
        !           212: 
        !           213:        [0x39]  "RETT",         add,    0,      /* page 127 */
        !           214: 
        !           215:        [0x3A]  "T",            trap,   0,      /* page 129 */
        !           216: 
        !           217:        [0x28]  "rdy",          rd,     0,      /* page 131 */
        !           218:        [0x29]  "rdpsr",        rd,     0,
        !           219:        [0x2A]  "rdwim",        rd,     0,
        !           220:        [0x2B]  "rdtbr",        rd,     0,
        !           221: 
        !           222:        [0x30]  "wry",          wr,     0,      /* page 133 */
        !           223:        [0x31]  "wrpsr",        wr,     0,
        !           224:        [0x32]  "wrwim",        wr,     0,
        !           225:        [0x33]  "wrtbr",        wr,     0,
        !           226: 
        !           227:        [0x3B]  "flush",        add,    0,      /* page 138 */
        !           228: 
        !           229:        [0x34]  "FPOP",         fpop,   0,      /* page 140 */
        !           230:        [0x35]  "FPOP",         fpop,   0,
        !           231: };
        !           232: 
        !           233: static struct opcode sparcop3[64]={
        !           234:        [0x09]  "ldsb",         load,   0,      /* page 90 */
        !           235:        [0x19]  "ldsba",        loada,  0,
        !           236:        [0x0A]  "ldsh",         load,   0,
        !           237:        [0x1A]  "ldsha",        loada,  0,
        !           238:        [0x01]  "ldub",         load,   0,
        !           239:        [0x11]  "lduba",        loada,  0,
        !           240:        [0x02]  "lduh",         load,   0,
        !           241:        [0x12]  "lduha",        loada,  0,
        !           242:        [0x00]  "ld",           load,   0,
        !           243:        [0x10]  "lda",          loada,  0,
        !           244:        [0x03]  "ldd",          load,   0,
        !           245:        [0x13]  "ldda",         loada,  0,
        !           246: 
        !           247:        [0x20]  "ldf",          loadf,  0,      /* page 92 */
        !           248:        [0x23]  "lddf",         loadf,  0,
        !           249:        [0x21]  "ldfsr",        loadf,0,
        !           250: 
        !           251:        [0x30]  "ldc",          loadc,  0,      /* page 94 */
        !           252:        [0x33]  "lddc",         loadc,  0,
        !           253:        [0x31]  "ldcsr",        loadcsr,0,
        !           254: 
        !           255:        [0x05]  "stb",          store,  0,      /* page 95 */
        !           256:        [0x15]  "stba",         storea, 0,
        !           257:        [0x06]  "sth",          store,  0,
        !           258:        [0x16]  "stha",         storea, 0,
        !           259:        [0x04]  "st",           store,  0,
        !           260:        [0x14]  "sta",          storea, 0,
        !           261:        [0x07]  "std",          store,  0,
        !           262:        [0x17]  "stda",         storea, 0,
        !           263: 
        !           264:        [0x24]  "stf",          storef, 0,      /* page 97 */
        !           265:        [0x27]  "stdf",         storef, 0,
        !           266:        [0x25]  "stfsr",        storef,0,
        !           267:        [0x26]  "stdfq",        storef,0,
        !           268: 
        !           269:        [0x34]  "stc",          loadc,  0,      /* page 99 */
        !           270:        [0x37]  "stdc",         loadc,  0,
        !           271:        [0x35]  "stcsr",        loadcsr,0,
        !           272:        [0x36]  "stdcq",        loadcsr,0,
        !           273: 
        !           274:        [0x0D]  "ldstub",       store,  0,      /* page 101 */
        !           275:        [0x1D]  "ldstuba",      storea, 0,
        !           276: 
        !           277:        [0x0F]  "swap",         load,   0,      /* page 102 */
        !           278:        [0x1F]  "swapa",        loada,  0,
        !           279: };
        !           280: 
        !           281: static void
        !           282: bprint(Instr *i, char *fmt, ...)
        !           283: {
        !           284:        i->curr = doprint(i->curr, i->end, fmt, (&fmt+1));
        !           285: }
        !           286: 
        !           287: static int
        !           288: decode(ulong pc, Instr *i)
        !           289: {
        !           290:        long w;
        !           291: 
        !           292:        if (get4(mymap, pc, &w) < 0) {
        !           293:                werrstr("can't read instruction: %r");
        !           294:                return -1;
        !           295:        }
        !           296:        i->op = (w >> 30) & 0x03;
        !           297:        i->rd = (w >> 25) & 0x1F;
        !           298:        i->op2 = (w >> 22) & 0x07;
        !           299:        i->a = (w >> 29) & 0x01;
        !           300:        i->cond = (w >> 25) & 0x0F;
        !           301:        i->op3 = (w >> 19) & 0x3F;
        !           302:        i->rs1 = (w >> 14) & 0x1F;
        !           303:        i->i = (w >> 13) & 0x01;
        !           304:        i->asi = (w >> 5) & 0xFF;
        !           305:        i->rs2 = (w >> 0) & 0x1F;
        !           306:        i->simm13 = (w >> 0) & 0x1FFF;
        !           307:        if(i->simm13 & (1<<12))
        !           308:                i->simm13 |= ~((1<<13)-1);
        !           309:        i->opf = (w >> 5) & 0x1FF;
        !           310:        i->immdisp22 = (w >> 0) & 0x3FFFFF;
        !           311:        i->simmdisp22 = i->immdisp22;
        !           312:        if(i->simmdisp22 & (1<<21))
        !           313:                i->simmdisp22 |= ~((1<<22)-1);
        !           314:        i->disp30 = (w >> 0) & 0x3FFFFFFF;
        !           315:        i->w0 = w;
        !           316:        i->target = -1;
        !           317:        i->addr = pc;
        !           318:        i->size = 1;
        !           319:        return 1;
        !           320: }
        !           321: 
        !           322: static int
        !           323: mkinstr(ulong pc, Instr *i)
        !           324: {
        !           325:        Instr xi;
        !           326: 
        !           327:        if (decode(pc, i) < 0)
        !           328:                return -1;
        !           329:        if(i->op==0 && i->op2==4 && !dascase){  /* SETHI */
        !           330:                if (decode(pc+4, &xi) < 0)
        !           331:                        return -1;
        !           332:                if(xi.op==2 && xi.op3==0)               /* ADD */
        !           333:                if(xi.i == 1 && xi.rs1 == i->rd){       /* immediate to same reg */
        !           334:                        i->imm32 = xi.simm13 + (i->immdisp22<<10);
        !           335:                        i->target = xi.rd;
        !           336:                        i->w1 = xi.w0;
        !           337:                        i->size++;
        !           338:                        return 1;
        !           339:                }
        !           340:        }
        !           341:        if(i->op==2 && i->opf==1 && !dascase){  /* FMOVS */
        !           342:                if (decode(pc+4, &xi) < 0)
        !           343:                        return -1;
        !           344:                if(i->op==2 && i->opf==1)               /* FMOVS */
        !           345:                if(xi.rd==i->rd+1 && xi.rs2==i->rs2+1){ /* next pair */
        !           346:                        i->w1 = xi.w0;
        !           347:                        i->size++;
        !           348:                }
        !           349:        }
        !           350:        return 1;
        !           351: }
        !           352: 
        !           353: static int
        !           354: printins(Map *map, ulong pc, char *buf, int n)
        !           355: {
        !           356:        Instr instr;
        !           357:        void (*f)(Instr*, char*);
        !           358: 
        !           359:        mymap = map;
        !           360:        memset(&instr, 0, sizeof(instr));
        !           361:        instr.curr = buf;
        !           362:        instr.end = buf+n-1;
        !           363:        if (mkinstr(pc, &instr) < 0)
        !           364:                return -1;
        !           365:        switch(instr.op){
        !           366:        case 0:
        !           367:                f = sparcop0[instr.op2].f;
        !           368:                if(f)
        !           369:                        (*f)(&instr, sparcop0[instr.op2].mnemonic);
        !           370:                else
        !           371:                        bprint(&instr, "unknown %lux", instr.w0);
        !           372:                break;
        !           373: 
        !           374:        case 1:
        !           375:                bprint(&instr, "%X", "CALL\t");
        !           376:                instr.curr += symoff(instr.curr, instr.end-instr.curr,
        !           377:                                        pc+instr.disp30*4, CTEXT);
        !           378:                if (!dascase)
        !           379:                        bprint(&instr, "(SB)");
        !           380:                break;
        !           381: 
        !           382:        case 2:
        !           383:                f = sparcop2[instr.op3].f;
        !           384:                if(f)
        !           385:                        (*f)(&instr, sparcop2[instr.op3].mnemonic);
        !           386:                else
        !           387:                        bprint(&instr, "unknown %lux", instr.w0);
        !           388:                break;
        !           389: 
        !           390:        case 3:
        !           391:                f = sparcop3[instr.op3].f;
        !           392:                if(f)
        !           393:                        (*f)(&instr, sparcop3[instr.op3].mnemonic);
        !           394:                else
        !           395:                        bprint(&instr, "unknown %lux", instr.w0);
        !           396:                break;
        !           397:        }
        !           398:        if (instr.err) {
        !           399:                if (instr.curr != buf)
        !           400:                        bprint(&instr, "\t\t;");
        !           401:                bprint(&instr, instr.err);
        !           402:        }
        !           403:        return instr.size*4;
        !           404: }
        !           405: 
        !           406: /* convert to lower case from upper, according to dascase */
        !           407: static int
        !           408: Xconv(void *oa, Fconv *f)
        !           409: {
        !           410:        char buf[128];
        !           411:        char *s, *t;
        !           412: 
        !           413:        if(dascase){
        !           414:                for(s=*(char**)oa,t=buf; *t = *s; s++,t++)
        !           415:                        if('A'<=*t && *t<='Z')
        !           416:                                *t += 'a'-'A';
        !           417:                strconv(buf, f);
        !           418:        }else
        !           419:                strconv(*(char**)oa, f);
        !           420:        return sizeof(char*);
        !           421: }
        !           422: 
        !           423: static int
        !           424: sparcinst(Map *map, ulong pc, char modifier, char *buf, int n)
        !           425: {
        !           426:        static int fmtinstalled = 0;
        !           427: 
        !           428:                /* a modifier of 'I' toggles the dissassembler type */
        !           429:        if (!fmtinstalled) {
        !           430:                fmtinstalled = 1;
        !           431:                fmtinstall('X', Xconv);
        !           432:        }
        !           433:        if ((asstype == ASUNSPARC && modifier == 'i')
        !           434:                || (asstype == ASPARC && modifier == 'I'))
        !           435:                dascase = 'a'-'A';
        !           436:        else
        !           437:                dascase = 0;
        !           438:        return printins(map, pc, buf, n);
        !           439: }
        !           440: 
        !           441: static int
        !           442: sparcdas(Map *map, ulong pc, char *buf, int n)
        !           443: {
        !           444:        Instr instr;
        !           445: 
        !           446:        mymap = map;
        !           447:        memset(&instr, 0, sizeof(instr));
        !           448:        instr.curr = buf;
        !           449:        instr.end = buf+n-1;
        !           450:        if (mkinstr(pc, &instr) < 0)
        !           451:                return -1;
        !           452:        if (instr.end-instr.curr > 8)
        !           453:                instr.curr = _hexify(instr.curr, instr.w0, 7);
        !           454:        if (instr.end-instr.curr > 9 && instr.size == 2) {
        !           455:                *instr.curr++ = ' ';
        !           456:                instr.curr = _hexify(instr.curr, instr.w1, 7);
        !           457:        }
        !           458:        *instr.curr = 0;
        !           459:        return instr.size*4;
        !           460: }
        !           461: 
        !           462: static int
        !           463: sparcinstlen(Map *map, ulong pc)
        !           464: {
        !           465:        Instr i;
        !           466: 
        !           467:        mymap = map;
        !           468:        if (mkinstr(pc, &i) < 0)
        !           469:                return -1;
        !           470:        return i.size*4;
        !           471: }
        !           472: 
        !           473: static int
        !           474: plocal(Instr *i)
        !           475: {
        !           476:        int offset;
        !           477:        Symbol s;
        !           478: 
        !           479:        if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
        !           480:                return -1;
        !           481:        if (s.value > i->simm13) {
        !           482:                if(getauto(&s, s.value-i->simm13, CAUTO, &s)) {
        !           483:                        bprint(i, "%s+%d(SP)", s.name, s.value);
        !           484:                        return 1;
        !           485:                }
        !           486:        } else {
        !           487:                offset = i->simm13-s.value;
        !           488:                if (getauto(&s, offset-4, CPARAM, &s)) {
        !           489:                        bprint(i, "%s+%d(FP)", s.name, offset);
        !           490:                        return 1;
        !           491:                }
        !           492:        }
        !           493:        return -1;
        !           494: }
        !           495: 
        !           496: static void
        !           497: address(Instr *i)
        !           498: {
        !           499:        Symbol s, s2;
        !           500:        long off, off1;
        !           501: 
        !           502:        if (i->rs1 == 1 && plocal(i) >= 0)
        !           503:                return;
        !           504:        off = mach->sb+i->simm13;
        !           505:        if(i->rs1 == 2  && findsym(off, CANY, &s)
        !           506:                        && s.value-off < 4096
        !           507:                        && (s.class == CDATA || s.class == CTEXT)) {
        !           508:                if(off==s.value && s.name[0]=='$'){
        !           509:                        off1 = 0;
        !           510:                        get4(mymap, s.value, &off1);
        !           511:                        if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){
        !           512:                                bprint(i, "$%s(SB)", s2.name);
        !           513:                                return;
        !           514:                        }
        !           515:                }
        !           516:                bprint(i, "%s", s.name);
        !           517:                if (s.value != off)
        !           518:                        bprint(i, "+%lux", s.value-off);
        !           519:                bprint(i, "(SB)");
        !           520:                return;
        !           521:        }
        !           522:        bprint(i, "%lux(R%d)", i->simm13, i->rs1);
        !           523: }
        !           524: 
        !           525: static void
        !           526: unimp(Instr *i, char *m)
        !           527: {
        !           528:        bprint(i, "%X", m);
        !           529: }
        !           530: 
        !           531: static char    *bratab[16] = { /* page 91 */
        !           532:        [0X8]   "A",
        !           533:        [0X0]   "N",
        !           534:        [0X9]   "NE",
        !           535:        [0X1]   "E",
        !           536:        [0XA]   "G",
        !           537:        [0X2]   "LE",
        !           538:        [0XB]   "GE",
        !           539:        [0X3]   "L",
        !           540:        [0XC]   "GU",
        !           541:        [0X4]   "LEU",
        !           542:        [0XD]   "CC",
        !           543:        [0X5]   "CS",
        !           544:        [0XE]   "POS",
        !           545:        [0X6]   "NEG",
        !           546:        [0XF]   "VC",
        !           547:        [0X7]   "VS",
        !           548: };
        !           549: 
        !           550: static char    *fbratab[16] = {        /* page 91 */
        !           551:        [0X8]   "A",
        !           552:        [0X0]   "N",
        !           553:        [0X7]   "U",
        !           554:        [0X6]   "G",
        !           555:        [0X5]   "UG",
        !           556:        [0X4]   "L",
        !           557:        [0X3]   "UL",
        !           558:        [0X2]   "LG",
        !           559:        [0X1]   "NE",
        !           560:        [0X9]   "E",
        !           561:        [0XA]   "UE",
        !           562:        [0XB]   "GE",
        !           563:        [0XC]   "UGE",
        !           564:        [0XD]   "LE",
        !           565:        [0XE]   "ULE",
        !           566:        [0XF]   "O",
        !           567: };
        !           568: 
        !           569: static char    *cbratab[16] = {        /* page 91 */
        !           570:        [0X8]   "A",
        !           571:        [0X0]   "N",
        !           572:        [0X7]   "3",
        !           573:        [0X6]   "2",
        !           574:        [0X5]   "23",
        !           575:        [0X4]   "1",
        !           576:        [0X3]   "13",
        !           577:        [0X2]   "12",
        !           578:        [0X1]   "123",
        !           579:        [0X9]   "0",
        !           580:        [0XA]   "03",
        !           581:        [0XB]   "02",
        !           582:        [0XC]   "023",
        !           583:        [0XD]   "01",
        !           584:        [0XE]   "013",
        !           585:        [0XF]   "012",
        !           586: };
        !           587: 
        !           588: static void
        !           589: bra1(Instr *i, char *m, char *tab[])
        !           590: {
        !           591:        long imm;
        !           592: 
        !           593:        imm = i->simmdisp22;
        !           594:        if(i->a)
        !           595:                bprint(i, "%X%X.%c\t", m, tab[i->cond], 'A'+dascase);
        !           596:        else
        !           597:                bprint(i, "%X%X\t", m, tab[i->cond]);
        !           598:        i->curr += symoff(i->curr, i->end-i->curr, i->addr+4*imm, CTEXT);
        !           599:        if (!dascase)
        !           600:                bprint(i, "(SB)");
        !           601: }
        !           602: 
        !           603: static void
        !           604: bra(Instr *i, char *m)                 /* page 91 */
        !           605: {
        !           606:        bra1(i, m, bratab);
        !           607: }
        !           608: 
        !           609: static void
        !           610: fbra(Instr *i, char *m)                        /* page 93 */
        !           611: {
        !           612:        bra1(i, m, fbratab);
        !           613: }
        !           614: 
        !           615: static void
        !           616: cbra(Instr *i, char *m)                        /* page 95 */
        !           617: {
        !           618:        bra1(i, m, cbratab);
        !           619: }
        !           620: 
        !           621: static void
        !           622: trap(Instr *i, char *m)                        /* page 101 */
        !           623: {
        !           624:        if(i->i == 0)
        !           625:                bprint(i, "%X%X\tR%d+R%d", m, bratab[i->cond], i->rs2, i->rs1);
        !           626:        else
        !           627:                bprint(i, "%X%X\t$%lux+R%d", m, bratab[i->cond], i->simm13, i->rs1);
        !           628: }
        !           629: 
        !           630: static void
        !           631: sethi(Instr *i, char *m)               /* page 89 */
        !           632: {
        !           633:        ulong imm;
        !           634: 
        !           635:        imm = i->immdisp22<<10;
        !           636:        if(dascase){
        !           637:                bprint(i, "%X\t%lux, R%d", m, imm, i->rd);
        !           638:                return;
        !           639:        }
        !           640:        if(imm==0 && i->rd==0){
        !           641:                bprint(i, "NOP");
        !           642:                return;
        !           643:        }
        !           644:        if(i->target < 0){
        !           645:                bprint(i, "MOVW\t$%lux, R%d", imm, i->rd);
        !           646:                return;
        !           647:        }
        !           648:        bprint(i, "MOVW\t$%lux, R%d", i->imm32, i->target);
        !           649: }
        !           650: 
        !           651: static char ldtab[] = {
        !           652:        'W',
        !           653:        'B',
        !           654:        'H',
        !           655:        'D',
        !           656: };
        !           657: 
        !           658: static char*
        !           659: moveinstr(int op3, char *m)
        !           660: {
        !           661:        char *s;
        !           662:        int c;
        !           663:        static char buf[8];
        !           664: 
        !           665:        if(!dascase){
        !           666:                /* batshit cases */
        !           667:                if(op3 == 0xF || op3 == 0x1F)
        !           668:                        return "SWAP";
        !           669:                if(op3 == 0xD || op3 == 0x1D)
        !           670:                        return "TAS";   /* really LDSTUB */
        !           671:                c = ldtab[op3&3];
        !           672:                s = "";
        !           673:                if((op3&11)==1 || (op3&11)==2)
        !           674:                        s="U";
        !           675:                sprint(buf, "MOV%c%s", c, s);
        !           676:                return buf;
        !           677:        }
        !           678:        return m;
        !           679: }
        !           680: 
        !           681: static void
        !           682: load(Instr *i, char *m)                        /* page 68 */
        !           683: {
        !           684:        m = moveinstr(i->op3, m);
        !           685:        if(i->i == 0)
        !           686:                bprint(i, "%s\t(R%d+R%d), R%d", m, i->rs1, i->rs2, i->rd);
        !           687:        else{
        !           688:                bprint(i, "%s\t", m);
        !           689:                address(i);
        !           690:                bprint(i, ", R%d", i->rd);
        !           691:        }
        !           692: }
        !           693: 
        !           694: static void
        !           695: loada(Instr *i, char *m)               /* page 68 */
        !           696: {
        !           697:        m = moveinstr(i->op3, m);
        !           698:        if(i->i == 0)
        !           699:                bprint(i, "%s\t(R%d+R%d, %d), R%d", m, i->rs1, i->rs2, i->asi, i->rd);
        !           700:        else
        !           701:                bprint(i, "unknown ld asi %lux", i->w0);
        !           702: }
        !           703: 
        !           704: static void
        !           705: store(Instr *i, char *m)               /* page 74 */
        !           706: {
        !           707:        m = moveinstr(i->op3, m);
        !           708:        if(i->i == 0)
        !           709:                bprint(i, "%s\tR%d, (R%d+R%d)",
        !           710:                                m, i->rd, i->rs1, i->rs2);
        !           711:        else{
        !           712:                bprint(i, "%s\tR%d, ", m, i->rd);
        !           713:                address(i);
        !           714:        }
        !           715: }
        !           716: 
        !           717: static void
        !           718: storea(Instr *i, char *m)              /* page 74 */
        !           719: {
        !           720:        m = moveinstr(i->op3, m);
        !           721:        if(i->i == 0)
        !           722:                bprint(i, "%s\tR%d, (R%d+R%d, %d)", m, i->rd, i->rs1, i->rs2, i->asi);
        !           723:        else
        !           724:                bprint(i, "%s\tR%d, %d(R%d, %d), ???", m, i->rd, i->simm13, i->rs1, i->asi);
        !           725: }
        !           726: 
        !           727: void
        !           728: shift(Instr *i, char *m)       /* page 88 */
        !           729: {
        !           730:        if(i->i == 0){
        !           731:                if(i->rs1 == i->rd)
        !           732:                        if(dascase)
        !           733:                                bprint(i, "%X\tR%d, R%d", m, i->rs1, i->rs2);
        !           734:                        else
        !           735:                                bprint(i, "%X\tR%d, R%d", m, i->rs2, i->rs1);
        !           736:                else
        !           737:                        if(dascase)
        !           738:                                bprint(i, "%X\tR%d, R%d, R%d", m, i->rs1, i->rs2, i->rd);
        !           739:                        else
        !           740:                                bprint(i, "%X\tR%d, R%d, R%d", m, i->rs2, i->rs1, i->rd);
        !           741:        }else{
        !           742:                if(i->rs1 == i->rd)
        !           743:                        if(dascase)
        !           744:                                bprint(i, "%X\t$%d,R%d", m, i->simm13&0x1F, i->rs1);
        !           745:                        else
        !           746:                                bprint(i, "%X\tR%d, $%d", m,  i->rs1, i->simm13&0x1F);
        !           747:                else
        !           748:                        if(dascase)
        !           749:                                bprint(i, "%X\tR%d, $%d, R%d",m,i->rs1,i->simm13&0x1F,i->rd);
        !           750:                        else
        !           751:                                bprint(i, "%X\t$%d, R%d, R%d",m,i->simm13&0x1F,i->rs1,i->rd);
        !           752:        }
        !           753: }
        !           754: 
        !           755: static void
        !           756: add(Instr *i, char *m) /* page 82 */
        !           757: {
        !           758:        if(i->i == 0){
        !           759:                if(dascase)
        !           760:                        bprint(i, "%X\tR%d, R%d", m, i->rs1, i->rs2);
        !           761:                else
        !           762:                        if(i->op3==2 && i->rs1==0 && i->rd)  /* OR R2, R0, R1 */
        !           763:                                bprint(i, "MOVW\tR%d", i->rs2);
        !           764:                        else
        !           765:                                bprint(i, "%X\tR%d, R%d", m, i->rs2, i->rs1);
        !           766:        }else{
        !           767:                if(dascase)
        !           768:                        bprint(i, "%X\tR%d, $%lux", m, i->rs1, i->simm13);
        !           769:                else
        !           770:                        if(i->op3==0 && i->rd && i->rs1==0)     /* ADD $x, R0, R1 */
        !           771:                                bprint(i, "MOVW\t$%lux", i->simm13);
        !           772:                        else if(i->op3==0 && i->rd && i->rs1==2){
        !           773:                                /* ADD $x, R2, R1 -> MOVW $x(SB), R1 */
        !           774:                                bprint(i, "MOVW\t$");
        !           775:                                address(i);
        !           776:                        } else
        !           777:                                bprint(i, "%X\t$%lux, R%d", m, i->simm13, i->rs1);
        !           778:        }
        !           779:        if(i->rs1 != i->rd)
        !           780:                bprint(i, ", R%d", i->rd);
        !           781: }
        !           782: 
        !           783: static void
        !           784: cmp(Instr *i, char *m)
        !           785: {
        !           786:        if(dascase || i->rd){
        !           787:                add(i, m);
        !           788:                return;
        !           789:        }
        !           790:        if(i->i == 0)
        !           791:                bprint(i, "CMP\tR%d, R%d", i->rs1, i->rs2);
        !           792:        else
        !           793:                bprint(i, "CMP\tR%d, $%lux", i->rs1, i->simm13);
        !           794: }
        !           795: 
        !           796: static char *regtab[4] = {
        !           797:        "Y",
        !           798:        "PSR",
        !           799:        "WIM",
        !           800:        "TBR",
        !           801: };
        !           802: 
        !           803: static void
        !           804: wr(Instr *i, char *m)          /* page 82 */
        !           805: {
        !           806:        if(dascase){
        !           807:                if(i->i == 0)
        !           808:                        bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
        !           809:                else
        !           810:                        bprint(i, "%s\tR%d, $%lux", m, i->rs1, i->simm13);
        !           811:        }else{
        !           812:                if(i->i && i->simm13==0)
        !           813:                        bprint(i, "MOVW\tR%d", i->rs1);
        !           814:                else if(i->i == 0)
        !           815:                        bprint(i, "wr\tR%d, R%d", i->rs2, i->rs1);
        !           816:                else
        !           817:                        bprint(i, "wr\t$%lux, R%d", i->simm13, i->rs1);
        !           818:        }
        !           819:        bprint(i, ", %s", regtab[i->op3&3]);
        !           820: }
        !           821: 
        !           822: static void
        !           823: rd(Instr *i, char *m)          /* page 103 */
        !           824: {
        !           825:        if(i->rs1==15 && i->rd==0){
        !           826:                m = "stbar";
        !           827:                if(!dascase)
        !           828:                        m = "STBAR";
        !           829:                bprint(i, "%s", m);
        !           830:        }else{
        !           831:                if(!dascase)
        !           832:                        m = "MOVW";
        !           833:                bprint(i, "%s\t%s, R%d", m, regtab[i->op3&3], i->rd);
        !           834:        }
        !           835: }
        !           836: 
        !           837: static void
        !           838: jmpl(Instr *i, char *m)                /* page 82 */
        !           839: {
        !           840:        if(i->i == 0){
        !           841:                if(i->rd == 15)
        !           842:                        bprint(i, "%X\t(R%d+R%d)", "CALL", i->rs2, i->rs1);
        !           843:                else
        !           844:                        bprint(i, "%X\t(R%d+R%d), R%d", m, i->rs2, i->rs1, i->rd);
        !           845:        }else{
        !           846:                if(!dascase && i->simm13==8 && i->rs1==15 && i->rd==0)
        !           847:                        bprint(i, "RETURN");
        !           848:                else{
        !           849:                        bprint(i, "%X\t", m);
        !           850:                        address(i);
        !           851:                        bprint(i, ", R%d", i->rd);
        !           852:                }
        !           853:        }
        !           854: }
        !           855: 
        !           856: static void
        !           857: loadf(Instr *i, char *m)               /* page 70 */
        !           858: {
        !           859:        if(!dascase){
        !           860:                m = "FMOVD";
        !           861:                if(i->op3 == 0x20)
        !           862:                        m = "FMOVF";
        !           863:                else if(i->op3 == 0x21)
        !           864:                        m = "MOVW";
        !           865:        }
        !           866:        if(i->i == 0)
        !           867:                bprint(i, "%s\t(R%d+R%d)", m, i->rs1, i->rs2);
        !           868:        else{
        !           869:                bprint(i, "%s\t", m);
        !           870:                address(i);
        !           871:        }
        !           872:        if(i->op3 == 0x21)
        !           873:                bprint(i, ", FSR");
        !           874:        else
        !           875:                bprint(i, ", R%d", i->rd);
        !           876: }
        !           877: 
        !           878: static
        !           879: void storef(Instr *i, char *m)         /* page 70 */
        !           880: {
        !           881:        if(!dascase){
        !           882:                m = "FMOVD";
        !           883:                if(i->op3 == 0x25 || i->op3 == 0x26)
        !           884:                        m = "MOVW";
        !           885:                else if(i->op3 == 0x20)
        !           886:                        m = "FMOVF";
        !           887:        }
        !           888:        bprint(i, "%s\t", m);
        !           889:        if(i->op3 == 0x25)
        !           890:                bprint(i, "FSR, ");
        !           891:        else if(i->op3 == 0x26)
        !           892:                bprint(i, "FQ, ");
        !           893:        else
        !           894:                bprint(i, "R%d, ", i->rd);
        !           895:        if(i->i == 0)
        !           896:                bprint(i, "(R%d+R%d)", i->rs1, i->rs2);
        !           897:        else
        !           898:                address(i);
        !           899: }
        !           900: 
        !           901: static
        !           902: void loadc(Instr *i, char *m)                  /* page 72 */
        !           903: {
        !           904:        if(i->i == 0)
        !           905:                bprint(i, "%s\t(R%d+R%d), C%d", m, i->rs1, i->rs2, i->rd);
        !           906:        else{
        !           907:                bprint(i, "%s\t", m);
        !           908:                address(i);
        !           909:                bprint(i, ", C%d", i->rd);
        !           910:        }
        !           911: }
        !           912: 
        !           913: static
        !           914: void loadcsr(Instr *i, char *m)                        /* page 72 */
        !           915: {
        !           916:        if(i->i == 0)
        !           917:                bprint(i, "%s\t(R%d+R%d), CSR", m, i->rs1, i->rs2);
        !           918:        else{
        !           919:                bprint(i, "%s\t", m);
        !           920:                address(i);
        !           921:                bprint(i, ", CSR");
        !           922:        }
        !           923: }
        !           924: 
        !           925: static struct{
        !           926:        int     opf;
        !           927:        char    *name;
        !           928: } fptab1[] = {                 /* ignores rs1 */
        !           929:        0xC4,   "FITOS",        /* page 109 */
        !           930:        0xC8,   "FITOD",
        !           931:        0xCC,   "FITOX",
        !           932: 
        !           933:        0xD1,   "FSTOI",        /* page 110 */
        !           934:        0xD2,   "FDTOI",
        !           935:        0xD3,   "FXTOI",
        !           936: 
        !           937:        0xC9,   "FSTOD",        /* page 111 */
        !           938:        0xCD,   "FSTOX",
        !           939:        0xC6,   "FDTOS",
        !           940:        0xCE,   "FDTOX",
        !           941:        0xC7,   "FXTOS",
        !           942:        0xCB,   "FXTOD",
        !           943: 
        !           944:        0x01,   "FMOVS",        /* page 112 */
        !           945:        0x05,   "FNEGS",
        !           946:        0x09,   "FABSS",
        !           947: 
        !           948:        0x29,   "FSQRTS",       /* page 113 */
        !           949:        0x2A,   "FSQRTD",
        !           950:        0x2B,   "FSQRTX",
        !           951: 
        !           952:        0,      0,
        !           953: };
        !           954: 
        !           955: static struct{
        !           956:        int     opf;
        !           957:        char    *name;
        !           958: } fptab2[] = {                 /* uses rs1 */
        !           959: 
        !           960:        0x41,   "FADDS",        /* page 114 */
        !           961:        0x42,   "FADDD",
        !           962:        0x43,   "FADDX",
        !           963:        0x45,   "FSUBS",
        !           964:        0x46,   "FSUBD",
        !           965:        0x47,   "FSUBX",
        !           966: 
        !           967:        0x49,   "FMULS",        /* page 115 */
        !           968:        0x4A,   "FMULD",
        !           969:        0x4B,   "FMULX",
        !           970:        0x4D,   "FDIVS",
        !           971:        0x4E,   "FDIVD",
        !           972:        0x4F,   "FDIVX",
        !           973: 
        !           974:        0x51,   "FCMPS",        /* page 116 */
        !           975:        0x52,   "FCMPD",
        !           976:        0x53,   "FCMPX",
        !           977:        0x55,   "FCMPES",
        !           978:        0x56,   "FCMPED",
        !           979:        0x57,   "FCMPEX",
        !           980: 
        !           981:        0, 0
        !           982: };
        !           983: 
        !           984: static void
        !           985: fpop(Instr *i, char *m)        /* page 108-116 */
        !           986: {
        !           987:        int j;
        !           988: 
        !           989:        if(dascase==0 && i->size==2){
        !           990:                bprint(i, "FMOVD\tF%d, F%d", i->rs2, i->rd);
        !           991:                return;
        !           992:        }
        !           993:        for(j=0; fptab1[j].name; j++)
        !           994:                if(fptab1[j].opf == i->opf){
        !           995:                        bprint(i, "%X\tF%d, F%d", fptab1[j].name, i->rs2, i->rd);
        !           996:                        return;
        !           997:                }
        !           998:        for(j=0; fptab2[j].name; j++)
        !           999:                if(fptab2[j].opf == i->opf){
        !          1000:                        bprint(i, "%X\tF%d, F%d, F%d", fptab2[j].name, i->rs1, i->rs2, i->rd);
        !          1001:                        return;
        !          1002:                }
        !          1003:        bprint(i, "%X%ux\tF%d, F%d, F%d", m, i->opf, i->rs1, i->rs2, i->rd);
        !          1004: }
        !          1005: 
        !          1006: static int
        !          1007: sparcfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
        !          1008: {
        !          1009:        ulong w, r1, r2;
        !          1010:        char buf[8];
        !          1011:        Instr i;
        !          1012: 
        !          1013:        mymap = map;
        !          1014:        if (mkinstr(pc, &i) < 0)
        !          1015:                return -1;
        !          1016:        w = i.w0;
        !          1017:        switch(w & 0xC1C00000){
        !          1018:        case 0x00800000:                /* branch on int cond */
        !          1019:        case 0x01800000:                /* branch on fp cond */
        !          1020:        case 0x01C00000:                /* branch on copr cond */
        !          1021:                foll[0] = pc+8;
        !          1022:                foll[1] = pc + (i.simmdisp22<<2);
        !          1023:                return 2;
        !          1024:        }
        !          1025: 
        !          1026:        if((w&0xC0000000) == 0x40000000){       /* CALL */
        !          1027:                foll[0] = pc + (i.disp30<<2);
        !          1028:                return 1;
        !          1029:        }
        !          1030: 
        !          1031:        if((w&0xC1F80000) == 0x81C00000){       /* JMPL */
        !          1032:                sprint(buf, "R%d", (w>>14)&0xF);
        !          1033:                r1 = (*rget)(map, buf);
        !          1034:                if(w & 0x2000)                  /* JMPL R1+simm13 */
        !          1035:                        r2 = i.simm13;
        !          1036:                else{                           /* JMPL R1+R2 */
        !          1037:                        sprint(buf, "R%d", w&0xF);
        !          1038:                        r2 = (*rget)(map, buf);
        !          1039:                }
        !          1040:                foll[0] = r1 + r2;
        !          1041:                return 1;
        !          1042:        }
        !          1043:        foll[0] = pc+i.size*4;
        !          1044:        return 1;
        !          1045: }

unix.superglobalmegacorp.com

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