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