Annotation of lucent/sys/src/libmach/6db.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:  * i960-specific debugger interface
                      8:  *     i960 has an as yet unknown stack format - presotto
                      9:  */
                     10: 
                     11: static char    *i960excep(Map*, Rgetter);
                     12: static int     i960inst(Map*, ulong, char, char*, int);
                     13: static int     i960das(Map*, ulong, char*, int);
                     14: static int     i960foll(Map*, ulong, Rgetter, ulong*);
                     15: static int     i960instlen(Map*, ulong);
                     16: 
                     17: Machdata i960mach =
                     18: {
                     19:        {0x66, 0, 0x06, 0},     /* break point: fmark */
                     20:        4,                      /* break point size */
                     21: 
                     22:        leswab,                 /* convert short to local byte order */
                     23:        leswal,                 /* convert long to local byte order */
                     24:        cisctrace,              /* C traceback */
                     25:        ciscframe,              /* frame finder */
                     26:        0,                      /* ublock fixup */
                     27:        i960excep,              /* print exception */
                     28:        0,                      /* breakpoint fixup */
                     29:        leieeesftos,            /* single precision float printer */
                     30:        leieeedftos,            /* double precision float printer */
                     31:        i960foll,               /* following addresses */
                     32:        i960inst,               /* print instruction */
                     33:        i960das,                /* dissembler */
                     34:        i960instlen,            /* 0 */
                     35: };
                     36: 
                     37: static char*
                     38: i960excep(Map *map, Rgetter rget)
                     39: {
                     40:        USED(map, rget);
                     41:        return "intel machine exceptions are too hard to decode";
                     42: }
                     43: 
                     44:        /* I960 disassembler and related functions */
                     45: 
                     46: typedef struct Instr   Instr;
                     47: typedef struct Opcode  Opcode;
                     48: 
                     49: /*
                     50:  * operand types
                     51:  */
                     52: enum
                     53: {
                     54:        EA=1,
                     55:        R1, R2, R3,
                     56:        S1, S2, S3,
                     57:        IR1, IR2, IR3,
                     58: };
                     59: 
                     60: enum
                     61: {
                     62:        Treg,
                     63:        Tctrl,
                     64:        Tcobr,
                     65:        Tmem,
                     66: };
                     67: 
                     68: 
                     69: struct Opcode
                     70: {
                     71:        ushort  code;
                     72:        char    *name;
                     73:        uchar   and[3];
                     74: };
                     75: 
                     76: struct Instr
                     77: {
                     78:        Opcode  *op;            /* opcode line */
                     79:        ulong   mem[2];         /* memory for this instruction */
                     80:        int     n;              /* # longs for this instruction */
                     81:        char    and[3][64];
                     82:        ulong   rel;
                     83:        char    *err;
                     84: 
                     85:        int     type;
                     86:        int     index;
                     87:        int     base;
                     88:        int     mult;
                     89:        char    *curr;          /* fill point in output buffer */
                     90:        char    *end;           /* end of output buffer */
                     91:        ulong   addr;           /* pc of instruction */
                     92: };
                     93: 
                     94: static Map* mymap;
                     95: 
                     96: Opcode optab[] = {
                     97:        { 0x08, "B", EA         },
                     98:        { 0x09, "CALL", EA      },
                     99:        { 0x0A, "RET"           },
                    100:        { 0x0B, "BAL", EA       },
                    101:        { 0x10, "BNO", EA       },
                    102:        { 0x11, "BG", EA        },
                    103:        { 0x12, "BE", EA        },
                    104:        { 0x13, "BGE", EA       },
                    105:        { 0x14, "BL", EA        },
                    106:        { 0x15, "BNE", EA       },
                    107:        { 0x16, "BLE", EA       },
                    108:        { 0x17, "BO", EA        },
                    109:        { 0x18, "FAULTNO"       },
                    110:        { 0x19, "FAULTG"        },
                    111:        { 0x1A, "FAULTE"        },
                    112:        { 0x1B, "FAULTGE"       },
                    113:        { 0x1C, "FAULTL"        },
                    114:        { 0x1D, "FAULTNE"       },
                    115:        { 0x1E, "FAULTLE"       },
                    116:        { 0x1F, "FAULTO"        },
                    117:        { 0x20, "TESTNO", R1    },
                    118:        { 0x21, "TESTG", R1     },
                    119:        { 0x22, "TESTE", R1     },
                    120:        { 0x23, "TESTGE", R1    },
                    121:        { 0x24, "TESTL", R1     },
                    122:        { 0x25, "TESTNE", R1    },
                    123:        { 0x26, "TESTLE", R1    },
                    124:        { 0x27, "TESTO", R1     },
                    125:        { 0x30, "BBC", S1, R2, EA       },
                    126:        { 0x31, "CMPOBG", S1, R2, EA    },
                    127:        { 0x32, "CMPOBE", S1, R2, EA    },
                    128:        { 0x33, "CMPOBGE", S1, R2, EA   },
                    129:        { 0x34, "CMPOBL", S1, R2, EA    },
                    130:        { 0x35, "CMPOBNE", S1, R2, EA   },
                    131:        { 0x36, "CMPOBLE", S1, R2, EA   },
                    132:        { 0x37, "CMPOBO", S1, R2, EA    },
                    133:        { 0x38, "CMPIBNO", S1, R2, EA   },
                    134:        { 0x39, "CMPIBG", S1, R2, EA    },
                    135:        { 0x3A, "CMPIBE", S1, R2, EA    },
                    136:        { 0x3B, "CMPIBGE", S1, R2, EA   },
                    137:        { 0x3C, "CMPIBL", S1, R2, EA    },
                    138:        { 0x3D, "CMPIBNE", S1, R2, EA   },
                    139:        { 0x3E, "CMPIBLE", S1, R2, EA   },
                    140:        { 0x3F, "CMPIBO", S1, R2, EA    },
                    141:        { 0x80, "MOVOB", EA, R1 },
                    142:        { 0x82, "MOVOB", R1, EA },
                    143:        { 0x84, "B", EA         },
                    144:        { 0x85, "BAL", EA, R1   },
                    145:        { 0x86, "CALL", EA      },
                    146:        { 0x88, "MOVOS", EA, R1 },
                    147:        { 0x8A, "MOVOS", R1, EA },
                    148:        { 0x8C, "LDA", EA, R1   },
                    149:        { 0x90, "MOV", EA, R1   },
                    150:        { 0x92, "MOV", R1, EA   },
                    151:        { 0x98, "MOVV", EA, R1  },
                    152:        { 0x9A, "MOVV", R1, EA  },
                    153:        { 0xA0, "MOVT", EA, R1  },
                    154:        { 0xA2, "MOVT", R1, EA  },
                    155:        { 0xB0, "MOVQ", EA, R1  },
                    156:        { 0xB2, "MOVQ", R1, EA  },
                    157:        { 0xC0, "MOVIB", EA, R1 },
                    158:        { 0xC2, "MOVIB", R1, EA },
                    159:        { 0xC8, "MOVIS", EA, R1 },
                    160:        { 0xCA, "MOVIS", R1, EA },
                    161:        { 0x580, "NOTBIT", S1, S2, R3   },
                    162:        { 0x581, "AND", S1, S2, R3      },
                    163:        { 0x582, "ANDNOT", S1, S2, R3   },
                    164:        { 0x583, "SETBIT", S1, S2, R3   },
                    165:        { 0x584, "NOTAND", S1, R3       },
                    166:        { 0x586, "XOR", S1, S2, R3      },
                    167:        { 0x587, "OR", S1, S2, R3       },
                    168:        { 0x588, "NOR", S1, S2, R3      },
                    169:        { 0x589, "XNOR", S1, S2, R3     },
                    170:        { 0x58A, "NOT", S1, R3          },
                    171:        { 0x58B, "ORNOT", S1, S2, R3    },
                    172:        { 0x58C, "CLRBIT", S1, S2, R3   },
                    173:        { 0x58D, "NOTOR", S1, S2, R3    },
                    174:        { 0x58E, "NAND", S1, S2, R3     },
                    175:        { 0x58F, "ALTERBIT", S1, S2, R3 },
                    176:        { 0x590, "ADDO", S1, S2, R3     },
                    177:        { 0x591, "ADDI", S1, S2, R3     },
                    178:        { 0x592, "SUBO", S1, S2, R3     },
                    179:        { 0x593, "SUBI", S1, S2, R3     },
                    180:        { 0x598, "SHRO", S1, S2, R3     },
                    181:        { 0x59A, "SHRDI", S1, S2, R3    },
                    182:        { 0x59B, "SHRI", S1, S2, R3     },
                    183:        { 0x59C, "SHLO", S1, S2, R3     },
                    184:        { 0x59D, "ROTATE", S1, S2, R3   },
                    185:        { 0x59E, "SHLI", S1, S2, R3     },
                    186:        { 0x5A0, "CMPO", S1, S2         },
                    187:        { 0x5A1, "CMPI", S1, S2         },
                    188:        { 0x5A2, "CONCMPO", S1, S2      },
                    189:        { 0x5A3, "CONCMPI", S1, S2      },
                    190:        { 0x5A4, "CMPINCI", S1, S2, R3  },
                    191:        { 0x5A5, "CMPINCO", S1, S2, R3  },
                    192:        { 0x5A6, "CMPDECI", S1, S2, R3  },
                    193:        { 0x5A7, "CMPDECO", S1, S2, R3  },
                    194:        { 0x5AC, "SCANBYTE", S1, S2     },
                    195:        { 0x5AE, "CHKBIT", S1, S2       },
                    196:        { 0x5B0, "ADDC", S1, S2, R3     },
                    197:        { 0x5B2, "SUBC", S1, S2, R3     },
                    198:        { 0x5CC, "MOV", S1, R3          },
                    199:        { 0x5DC, "MOVV", S1, R3         },
                    200:        { 0x5EC, "MOVT", S1, R3         },
                    201:        { 0x5FC, "MOVQ", S1, R3         },
                    202:        { 0x600, "SYNMOV", IR1, IR3     },
                    203:        { 0x601, "SYNMOVV", IR1, IR3    },
                    204:        { 0x602, "SYNMOVQ", IR1, IR3    },
                    205:        { 0x610, "ATMOD", IR1, S2, R3   },
                    206:        { 0x612, "ATADD", IR1, S2, R3   },
                    207:        { 0x615, "SYNMOV", IR1, R2      },
                    208:        { 0x640, "SPANBIT", S1, R2      },
                    209:        { 0x641, "SCANBIT", S1, R2      },
                    210:        { 0x642, "DADDC", S1, S2, R3    },
                    211:        { 0x643, "DSUBC", S1, S2, R3    },
                    212:        { 0x644, "DMOVT", S1, R2        },
                    213:        { 0x645, "MODAC", S1, S2, R3    },
                    214:        { 0x650, "MODIFY", S1, S2, R3   },
                    215:        { 0x651, "EXTRACT", S1, S2, R3  },
                    216:        { 0x654, "MODTC", S1, S2, R3    },
                    217:        { 0x655, "MODPC", S1, S2        },
                    218:        { 0x660, "CALLS", S1            },
                    219:        { 0x66B, "MARK"                 },
                    220:        { 0x66C, "FMARK"        },
                    221:        { 0x66D, "FLUSHREG"     },
                    222:        { 0x66F, "SYNCF"        },
                    223:        { 0x670, "EMUL", S1, S2, R3     },
                    224:        { 0x671, "EDIV", S1, S2, R3     },
                    225:        { 0x674, "CVTIF", S1, R2        },
                    226:        { 0x675, "CVTILF", S1, R2       },
                    227:        { 0x676, "SCALED", S1, S2, R3   },
                    228:        { 0x677, "SCALEF", S1, S2, R3   },
                    229:        { 0x680, "ATANF", S1, S2, R3    },
                    230:        { 0x681, "LOGEPF", S1, S2, R3   },
                    231:        { 0x682, "LOGF", S1, S2, R3     },
                    232:        { 0x683, "REMF", S1, S2, R3     },
                    233:        { 0x684, "CMPOF", S1, S2        },
                    234:        { 0x685, "CMPF", S1, S2 },
                    235:        { 0x688, "SQRTF", S1, R2        },
                    236:        { 0x689, "EXPF", S1, R2 },
                    237:        { 0x68A, "LOGBNTF", S1, R2      },
                    238:        { 0x68B, "ROUNDF", S1, R2       },
                    239:        { 0x68C, "SINF", S1, R2 },
                    240:        { 0x68D, "COSF", S1, R2 },
                    241:        { 0x68E, "TANF", S1, R2 },
                    242:        { 0x68F, "CLASSF", S1   },
                    243:        { 0x690, "ATAND", S1, S2, R3    },
                    244:        { 0x691, "LOGEPD", S1, S2, R3   },
                    245:        { 0x692, "LOGD", S1, S2, R3     },
                    246:        { 0x693, "REMD", S1, S2, R3     },
                    247:        { 0x694, "CMPOD", S1, S2        },
                    248:        { 0x695, "CMPD", S1, S2 },
                    249:        { 0x698, "SQRTD", S1, S2        },
                    250:        { 0x699, "EXPD", S1, S2 },
                    251:        { 0x69A, "LOGBND", S1, S2       },
                    252:        { 0x69B, "ROUNDD", S1, S2       },
                    253:        { 0x69C, "SIND", S1, S2 },
                    254:        { 0x69D, "COSD", S1, S2 },
                    255:        { 0x69E, "TAND", S1, S2 },
                    256:        { 0x69F, "CLASSD", S1   },
                    257:        { 0x6C0, "CVTRI", S1, R2        },
                    258:        { 0x6C1, "CVTRI", S1, R2        },
                    259:        { 0x6C2, "CVTRI", S1, R2        },
                    260:        { 0x6C3, "CVTRI", S1, R2        },
                    261:        { 0x6C9, "MOVF", S1, R2 },
                    262:        { 0x6D9, "MOVD", S1, R2 },
                    263:        { 0x6E2, "CPYSRE", S1, S2, R3   },
                    264:        { 0x6E3, "CPYRSRE", S1, S2, R3  },
                    265:        { 0x6E3, "MOVRE", S1, R2        },
                    266:        { 0x701, "MULO", S1, S2, R3     },
                    267:        { 0x708, "REMO", S1, S2, R3     },
                    268:        { 0x70B, "DIVO", S1, S2, R3     },
                    269:        { 0x741, "MULI", S1, S2, R3     },
                    270:        { 0x748, "REMI", S1, S2, R3     },
                    271:        { 0x749, "MODI", S1, S2, R3     },
                    272:        { 0x74B, "DIVI", S1, S2, R3     },
                    273:        { 0x78B, "DIVF", S1, S2, R3     },
                    274:        { 0x78C, "MULF", S1, S2, R3     },
                    275:        { 0x78D, "SUBF", S1, S2, R3     },
                    276:        { 0x78F, "ADDR", S1, S2, R3     },
                    277:        { 0x79B, "DIVD", S1, S2, R3     },
                    278:        { 0x79C, "MULD", S1, S2, R3     },
                    279:        { 0x79D, "SUBD", S1, S2, R3     },
                    280:        { 0x79F, "MODI", S1, S2, R3     },
                    281:        { 0 },
                    282: };
                    283: #define NOP (sizeof(optab)/sizeof(Opcode))
                    284: 
                    285: /*
                    286:  *  get an instruction long
                    287:  */
                    288: static int
                    289: igetl(Instr *ip, long *lp)
                    290: {
                    291:        if(ip->n >= 2){
                    292:                werrstr("instruction too big");
                    293:                return -1;
                    294:        }
                    295:        if (get4(mymap, ip->addr+ip->n*4, (long*) &ip->mem[ip->n]) < 0) {
                    296:                werrstr("can't read instruction: %r");
                    297:                return -1;
                    298:        }
                    299:        *lp = ip->mem[ip->n++];
                    300:        return 1;
                    301: }
                    302: 
                    303: static Opcode*
                    304: findopcode(ushort code)
                    305: {
                    306:        Opcode *o;
                    307: 
                    308:        for(o = optab; o->code; o++)
                    309:                if(code == o->code)
                    310:                        return o;
                    311:        werrstr("unknown opcode");
                    312:        return 0;
                    313: }
                    314: 
                    315: static char*
                    316: genname(ulong l, int reg, int mode, int regonly, int ind)
                    317: {
                    318:        static char name[32];
                    319: 
                    320:        reg = (l>>reg) & 0x1f;
                    321:        if(mode >= 0)
                    322:                mode = (l>>mode) & 1;
                    323:        else
                    324:                mode = 0;
                    325:        if(mode)
                    326:                sprint(name, regonly?"?$%d?":"$%d", reg);
                    327:        else
                    328:                sprint(name, ind?"(R%d)":"R%d", reg);
                    329:        return name;
                    330: }
                    331: 
                    332: /*
                    333:  *  decode a reg instruction
                    334:  */
                    335: static char*
                    336: regfield(Instr *ip, uchar and, ulong l)
                    337: {
                    338:        switch(and){
                    339:        case S1:
                    340:        case R1:
                    341:        case IR1:
                    342:                return genname(l, 0, 11, and!=S1, and==IR1);
                    343:        case S2:
                    344:        case R2:
                    345:        case IR2:
                    346:                return genname(l, 14, 12, and!=S2, and==IR2);
                    347:        case S3:
                    348:        case R3:
                    349:        case IR3:
                    350:                return genname(l, 19, 13, and!=S3, and==IR3);
                    351:        default:
                    352:                ip->err = "missing regfield";
                    353:                return("???");
                    354:        }
                    355: }
                    356: 
                    357: static void
                    358: chk56(Instr *ip, ulong l)
                    359: {
                    360:        if(l & (3<<5))
                    361:                ip->err = "bits 5 and 6 not 0";
                    362: }
                    363: 
                    364: static int
                    365: reginst(Instr *ip, ulong l)
                    366: {
                    367:        ushort code;
                    368:        int i;
                    369: 
                    370:        ip->type = Treg;
                    371:        code = ((l>>20)&0xff0) | ((l>>7)&0xf);
                    372:        ip->op = findopcode(code);
                    373:        if(ip->op == 0)
                    374:                return -1;
                    375:        for(i = 0; i < 3; i++){
                    376:                if(ip->op->and[i] == 0)
                    377:                        break;
                    378:                strcpy(ip->and[i], regfield(ip, ip->op->and[i], l));
                    379:        }
                    380:        return 0;
                    381: }
                    382: 
                    383: /*
                    384:  *  decode a control and branch instruction
                    385:  */
                    386: static char*
                    387: cobrfield(Instr *ip, uchar and, ulong l)
                    388: {
                    389:        long disp;
                    390: 
                    391:        switch(and){
                    392:        case S1:
                    393:        case R1:
                    394:        case IR1:
                    395:                return genname(l, 19, 13, and!=S1, and==IR1);
                    396:        case R2:
                    397:        case IR2:
                    398:                return genname(l, 14, -1, 1, and==IR2);
                    399:        case EA:
                    400:                if(l & (1<<12))
                    401:                        disp = -(((~l) & 0xfff)+1);
                    402:                else
                    403:                        disp = l & 0xfff;
                    404:                ip->rel = ip->addr + 4 + disp;
                    405:                return ".+";
                    406:        default:
                    407:                return "???";
                    408:        }
                    409: }
                    410: static int
                    411: cobrinst(Instr *ip, ulong l)
                    412: {
                    413:        ushort code;
                    414:        int i;
                    415: 
                    416:        ip->type = Tcobr;
                    417:        if(l&3)
                    418:                ip->err = "disp not mult of 4";
                    419:        code = l>>24;
                    420:        ip->op = findopcode(code);
                    421:        if(ip->op == 0)
                    422:                return -1;
                    423:        for(i = 0; i < 3; i++){
                    424:                if(ip->op->and[i] == 0)
                    425:                        break;
                    426:                strcpy(ip->and[i], cobrfield(ip, ip->op->and[i], l));
                    427:        }
                    428:        return 0;
                    429: }
                    430: 
                    431: /*
                    432:  *  decode a control instruction
                    433:  */
                    434: static int
                    435: ctrlinst(Instr *ip, ulong l)
                    436: {
                    437:        ushort code;
                    438:        long disp;
                    439: 
                    440:        ip->type = Tctrl;
                    441:        if(l&3)
                    442:                ip->err = "disp not mult of 4";
                    443:        code = l>>24;
                    444:        ip->op = findopcode(code);
                    445:        if(ip->op == 0)
                    446:                return -1;
                    447:        if(ip->op->and[0] == 0)
                    448:                return 0;
                    449:        if(l & (1<<23))
                    450:                disp = -(((~l) & 0x7fffff)+1);
                    451:        else
                    452:                disp = l & 0x7fffff;
                    453:        ip->rel = ip->addr + 4 + disp;
                    454:        strcpy(ip->and[0], ".+");
                    455:        return 0;
                    456: }
                    457: 
                    458: static int
                    459: sprintoff(char *addr, int n, char *fmt, ulong v)
                    460: {
                    461:        Symbol s;
                    462:        long w;
                    463: 
                    464:        w = v+mach->sb;
                    465:        if (findsym(w, CDATA, &s)) {
                    466:                w = s.value-w;
                    467:                if (w <= 4096) {
                    468:                        if (w)
                    469:                                return snprint(addr, n, "%s+%lux(SB)", s.name, w);
                    470:                        else
                    471:                                return snprint(addr, n, "%s(SB)", s.name);
                    472:                }
                    473:        }
                    474:        return snprint(addr, n, fmt, v);
                    475: }
                    476: 
                    477: /*
                    478:  *  decode a memory instruction
                    479:  */
                    480: static char*
                    481: memfield(Instr *ip, uchar and, ulong l)
                    482: {
                    483:        long disp;
                    484:        static char addr[64];
                    485:        int abase;
                    486:        int scale;
                    487:        int index;
                    488: 
                    489:        ip->mult = 1;
                    490:        switch(and){
                    491:        case R1:
                    492:        case IR1:
                    493:                return genname(l, 19, -1, 1, and==IR1);
                    494:        case EA:
                    495:                abase = (l>>14)&0x1f;
                    496:                scale = 1 << ((l>>7)&0x7);
                    497:                index = l & 0x1f;
                    498:                switch((l>>10)&0xf){
                    499:                case 0x4:
                    500:                        chk56(ip, l);
                    501:                        ip->base = abase + 1;
                    502:                        sprint(addr, "(R%d)", abase);
                    503:                        break;
                    504:                case 0x5:
                    505:                        chk56(ip, l);
                    506:                        if (igetl(ip, &disp) < 0) {
                    507:                                strcpy(addr, "???");
                    508:                                break;
                    509:                        }
                    510:                        ip->rel = disp + ip->addr + 8;
                    511:                        strcpy(addr, ".+");
                    512:                        break;
                    513:                case 0x6:
                    514:                        strcpy(addr, "???");
                    515:                        break;
                    516:                case 0x7:
                    517:                        chk56(ip, l);
                    518:                        ip->base = abase + 1;
                    519:                        ip->mult = scale;
                    520:                        ip->index = index + 1;
                    521:                        sprint(addr, "(R%d)(%d*R%d)", abase, scale, index);
                    522:                        break;
                    523:                case 0xc:
                    524:                        chk56(ip, l);
                    525:                        if (igetl(ip, &disp) < 0) {
                    526:                                strcpy(addr, "???");
                    527:                                break;
                    528:                        }
                    529:                        ip->rel = disp;
                    530:                        strcpy(addr, ".+");
                    531:                        break;
                    532:                case 0xd:
                    533:                        chk56(ip, l);
                    534:                        if (igetl(ip, &disp) < 0) {
                    535:                                strcpy(addr, "???");
                    536:                                break;
                    537:                        }
                    538:                        ip->rel = disp;
                    539:                        if(abase == 28)
                    540:                                sprintoff(addr, sizeof(addr), "%lux(R28)", disp);
                    541:                        else{
                    542:                                ip->base = abase + 1;
                    543:                                sprint(addr, "%lx(R%d)", disp, abase);
                    544:                        }
                    545:                        break;
                    546:                case 0xe:
                    547:                        chk56(ip, l);
                    548:                        if (igetl(ip, &disp) < 0) {
                    549:                                strcpy(addr, "???");
                    550:                                break;
                    551:                        }
                    552:                        ip->rel = disp;
                    553:                        ip->mult = scale;
                    554:                        ip->index = index + 1;
                    555:                        sprint(addr, "%lx(%d*R%d)", disp, scale, index);
                    556:                        break;
                    557:                case 0xf:
                    558:                        chk56(ip, l);
                    559:                        if (igetl(ip, &disp) < 0) {
                    560:                                strcpy(addr, "???");
                    561:                                break;
                    562:                        }
                    563:                        ip->rel = disp;
                    564:                        ip->mult = scale;
                    565:                        ip->index = index + 1;
                    566:                        ip->base = abase + 1;
                    567:                        sprint(addr, "%lx(R%d)(%d*R%d)", disp, abase,
                    568:                                scale, index);
                    569:                        break;
                    570:                default:
                    571:                        disp = l&0xfff;
                    572:                        ip->rel = disp;
                    573:                        if(l & (1<<13)){
                    574:                                if(abase == 28)
                    575:                                        sprintoff(addr, sizeof(addr), "%lux(R28)", disp);
                    576:                                else{
                    577:                                        ip->base = abase + 1;
                    578:                                        sprint(addr, "%lux(R%d)", disp, abase);
                    579:                                }
                    580:                        } else {
                    581:                                strcpy(addr, ".+");
                    582:                        }
                    583:                        break;
                    584:                }
                    585:                return addr;
                    586:        default:
                    587:                break;
                    588:        }
                    589:        return "???";
                    590: }
                    591: static int
                    592: meminst(Instr *ip, ulong l)
                    593: {
                    594:        ushort code;
                    595:        int i;
                    596: 
                    597:        ip->type = Tmem;
                    598:        code = l>>24;
                    599:        ip->op = findopcode(code);
                    600:        if(ip->op == 0)
                    601:                return -1;
                    602:        for(i = 0; i < 2; i++){
                    603:                if(ip->op->and[i] == 0)
                    604:                        break;
                    605:                strcpy(ip->and[i], memfield(ip, ip->op->and[i], l));
                    606:        }
                    607:        return 0;
                    608: }
                    609: 
                    610: static int
                    611: mkinstr(Instr *ip, ulong pc)
                    612: {
                    613:        long l;
                    614: 
                    615:        memset(ip, 0, sizeof(Instr));
                    616:        ip->addr = pc;
                    617:        if (igetl(ip, &l) < 0)
                    618:                return -1;
                    619:        switch(l>>28){
                    620:        case 0x0:
                    621:        case 0x1:
                    622:                return ctrlinst(ip, l);
                    623:        case 0x2:
                    624:        case 0x3:
                    625:                return cobrinst(ip, l);
                    626:        case 0x5:
                    627:        case 0x6:
                    628:        case 0x7:
                    629:                return reginst(ip, l);
                    630:        case 0x8:
                    631:        case 0x9:
                    632:        case 0xa:
                    633:        case 0xb:
                    634:        case 0xc:
                    635:                return meminst(ip, l);
                    636:        }
                    637:        werrstr("unknown opcode");
                    638:        return -1;
                    639: }
                    640: 
                    641: static int
                    642: i960inst(Map *map, ulong pc, char modifier, char *buf, int n)
                    643: {
                    644:        Instr instr;
                    645:        int i;
                    646:        char *and;
                    647:        char *end;
                    648: 
                    649:        USED(modifier);
                    650:        mymap = map;
                    651:        if(mkinstr(&instr, pc) < 0)
                    652:                return -1;
                    653: 
                    654:        end = buf+n-1;
                    655:        buf += snprint(buf, end-buf, "%s ", instr.op->name);
                    656:        for(i = 0; i < 3; i++){
                    657:                and = instr.and[i];
                    658:                if(*and == 0)
                    659:                        break;
                    660:                if(i != 0)
                    661:                        buf += snprint(buf, end-buf, ",");
                    662:                if(strcmp(and, ".+") == 0){
                    663:                        buf += sprintoff(buf, end-buf, "$%lux", instr.rel);
                    664:                } else
                    665:                        buf += snprint(buf, end-buf, "%s", and);
                    666:        }
                    667: 
                    668:        if(instr.err)
                    669:                snprint(buf, end-buf, "\t\t;%s", instr.err);
                    670: 
                    671:        return instr.n*4;
                    672: }
                    673: 
                    674: static int
                    675: i960das(Map *map, ulong pc, char *buf, int n)
                    676: {
                    677:        Instr   instr;
                    678: 
                    679:        mymap = map;
                    680:        if (mkinstr(&instr, pc) < 0)
                    681:                return -1;
                    682:        if (n > 8) {
                    683:                _hexify(buf, instr.mem[0], 7);
                    684:                n -= 8;
                    685:                buf += 8;
                    686:        }
                    687:        if (n > 9 && instr.n == 2) {
                    688:                *buf++ = ' ';
                    689:                _hexify(buf, instr.mem[1], 7);
                    690:                buf += 8;
                    691:        }
                    692:        *buf = 0;
                    693:        return instr.n*4;
                    694: }
                    695: 
                    696: static int
                    697: i960instlen(Map *map, ulong pc)
                    698: {
                    699:        Instr   instr;
                    700: 
                    701:        mymap = map;
                    702:        if (mkinstr(&instr, pc) < 0)
                    703:                return -1;
                    704:        return instr.n*4;
                    705: }
                    706: 
                    707: static int
                    708: i960foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
                    709: {
                    710:        Instr instr;
                    711:        ulong l;
                    712:        char buf[8];
                    713: 
                    714:        mymap = map;
                    715:        if (mkinstr(&instr, pc) < 0)
                    716:                return -1;
                    717:        foll[0] = pc + instr.n;
                    718:        switch(instr.type){
                    719:        case Tcobr:
                    720:        case Treg:
                    721:                break;
                    722:        case Tctrl:
                    723:                if(instr.op->name[0] == 'B'){
                    724:                        foll[1] = instr.rel;
                    725:                        return 2;
                    726:                }
                    727:                if(strcmp("CALL", instr.op->name) == 0){
                    728:                        foll[0] = instr.rel;
                    729:                        return 1;
                    730:                }
                    731:                if(strcmp("RET", instr.op->name) == 0)
                    732:                        return -1;
                    733:                break;
                    734:        case Tmem:
                    735:                if(strcmp("BAL", instr.op->name) == 0
                    736:                || strcmp("CALL", instr.op->name) == 0){
                    737:                        l = instr.rel;
                    738:                        if(instr.index){
                    739:                                sprint(buf, "R%d", instr.index - 1);
                    740:                                l += (*rget)(map, buf) * instr.mult;
                    741:                        }
                    742:                        if(instr.base){
                    743:                                sprint(buf, "R%d", instr.base - 1);
                    744:                                l += (*rget)(map, buf);
                    745:                        }
                    746:                        foll[0] = l;
                    747:                        return 1;
                    748:                }
                    749:                break;
                    750:        }
                    751:        return 1;
                    752: }

unix.superglobalmegacorp.com

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