123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mach.h>
- /*
- * i960-specific debugger interface
- * i960 has an as yet unknown stack format - presotto
- */
- static char *i960excep(Map*, Rgetter);
- static int i960inst(Map*, ulong, char, char*, int);
- static int i960das(Map*, ulong, char*, int);
- static int i960foll(Map*, ulong, Rgetter, ulong*);
- static int i960instlen(Map*, ulong);
- Machdata i960mach =
- {
- {0x66, 0, 0x06, 0}, /* break point: fmark */
- 4, /* break point size */
- leswab, /* convert short to local byte order */
- leswal, /* convert long to local byte order */
- leswav, /* vlong to local byte order */
- cisctrace, /* C traceback */
- ciscframe, /* frame finder */
- i960excep, /* print exception */
- 0, /* breakpoint fixup */
- leieeesftos, /* single precision float printer */
- leieeedftos, /* double precision float printer */
- i960foll, /* following addresses */
- i960inst, /* print instruction */
- i960das, /* dissembler */
- i960instlen, /* 0 */
- };
- static char*
- i960excep(Map *map, Rgetter rget)
- {
- USED(map, rget);
- return "intel machine exceptions are too hard to decode";
- }
- /* I960 disassembler and related functions */
- typedef struct Instr Instr;
- typedef struct Opcode Opcode;
- /*
- * operand types
- */
- enum
- {
- EA=1,
- R1, R2, R3,
- S1, S2, S3,
- IR1, IR2, IR3,
- };
- enum
- {
- Treg,
- Tctrl,
- Tcobr,
- Tmem,
- };
- struct Opcode
- {
- ushort code;
- char *name;
- uchar and[3];
- };
- struct Instr
- {
- Opcode *op; /* opcode line */
- ulong mem[2]; /* memory for this instruction */
- int n; /* # longs for this instruction */
- char and[3][64];
- ulong rel;
- char *err;
- int type;
- int index;
- int base;
- int mult;
- char *curr; /* fill point in output buffer */
- char *end; /* end of output buffer */
- ulong addr; /* pc of instruction */
- };
- static Map* mymap;
- Opcode optab[] = {
- { 0x08, "B", EA },
- { 0x09, "CALL", EA },
- { 0x0A, "RET" },
- { 0x0B, "BAL", EA },
- { 0x10, "BNO", EA },
- { 0x11, "BG", EA },
- { 0x12, "BE", EA },
- { 0x13, "BGE", EA },
- { 0x14, "BL", EA },
- { 0x15, "BNE", EA },
- { 0x16, "BLE", EA },
- { 0x17, "BO", EA },
- { 0x18, "FAULTNO" },
- { 0x19, "FAULTG" },
- { 0x1A, "FAULTE" },
- { 0x1B, "FAULTGE" },
- { 0x1C, "FAULTL" },
- { 0x1D, "FAULTNE" },
- { 0x1E, "FAULTLE" },
- { 0x1F, "FAULTO" },
- { 0x20, "TESTNO", R1 },
- { 0x21, "TESTG", R1 },
- { 0x22, "TESTE", R1 },
- { 0x23, "TESTGE", R1 },
- { 0x24, "TESTL", R1 },
- { 0x25, "TESTNE", R1 },
- { 0x26, "TESTLE", R1 },
- { 0x27, "TESTO", R1 },
- { 0x30, "BBC", S1, R2, EA },
- { 0x31, "CMPOBG", S1, R2, EA },
- { 0x32, "CMPOBE", S1, R2, EA },
- { 0x33, "CMPOBGE", S1, R2, EA },
- { 0x34, "CMPOBL", S1, R2, EA },
- { 0x35, "CMPOBNE", S1, R2, EA },
- { 0x36, "CMPOBLE", S1, R2, EA },
- { 0x37, "CMPOBO", S1, R2, EA },
- { 0x38, "CMPIBNO", S1, R2, EA },
- { 0x39, "CMPIBG", S1, R2, EA },
- { 0x3A, "CMPIBE", S1, R2, EA },
- { 0x3B, "CMPIBGE", S1, R2, EA },
- { 0x3C, "CMPIBL", S1, R2, EA },
- { 0x3D, "CMPIBNE", S1, R2, EA },
- { 0x3E, "CMPIBLE", S1, R2, EA },
- { 0x3F, "CMPIBO", S1, R2, EA },
- { 0x80, "MOVOB", EA, R1 },
- { 0x82, "MOVOB", R1, EA },
- { 0x84, "B", EA },
- { 0x85, "BAL", EA, R1 },
- { 0x86, "CALL", EA },
- { 0x88, "MOVOS", EA, R1 },
- { 0x8A, "MOVOS", R1, EA },
- { 0x8C, "LDA", EA, R1 },
- { 0x90, "MOV", EA, R1 },
- { 0x92, "MOV", R1, EA },
- { 0x98, "MOVV", EA, R1 },
- { 0x9A, "MOVV", R1, EA },
- { 0xA0, "MOVT", EA, R1 },
- { 0xA2, "MOVT", R1, EA },
- { 0xB0, "MOVQ", EA, R1 },
- { 0xB2, "MOVQ", R1, EA },
- { 0xC0, "MOVIB", EA, R1 },
- { 0xC2, "MOVIB", R1, EA },
- { 0xC8, "MOVIS", EA, R1 },
- { 0xCA, "MOVIS", R1, EA },
- { 0x580, "NOTBIT", S1, S2, R3 },
- { 0x581, "AND", S1, S2, R3 },
- { 0x582, "ANDNOT", S1, S2, R3 },
- { 0x583, "SETBIT", S1, S2, R3 },
- { 0x584, "NOTAND", S1, R3 },
- { 0x586, "XOR", S1, S2, R3 },
- { 0x587, "OR", S1, S2, R3 },
- { 0x588, "NOR", S1, S2, R3 },
- { 0x589, "XNOR", S1, S2, R3 },
- { 0x58A, "NOT", S1, R3 },
- { 0x58B, "ORNOT", S1, S2, R3 },
- { 0x58C, "CLRBIT", S1, S2, R3 },
- { 0x58D, "NOTOR", S1, S2, R3 },
- { 0x58E, "NAND", S1, S2, R3 },
- { 0x58F, "ALTERBIT", S1, S2, R3 },
- { 0x590, "ADDO", S1, S2, R3 },
- { 0x591, "ADDI", S1, S2, R3 },
- { 0x592, "SUBO", S1, S2, R3 },
- { 0x593, "SUBI", S1, S2, R3 },
- { 0x598, "SHRO", S1, S2, R3 },
- { 0x59A, "SHRDI", S1, S2, R3 },
- { 0x59B, "SHRI", S1, S2, R3 },
- { 0x59C, "SHLO", S1, S2, R3 },
- { 0x59D, "ROTATE", S1, S2, R3 },
- { 0x59E, "SHLI", S1, S2, R3 },
- { 0x5A0, "CMPO", S1, S2 },
- { 0x5A1, "CMPI", S1, S2 },
- { 0x5A2, "CONCMPO", S1, S2 },
- { 0x5A3, "CONCMPI", S1, S2 },
- { 0x5A4, "CMPINCI", S1, S2, R3 },
- { 0x5A5, "CMPINCO", S1, S2, R3 },
- { 0x5A6, "CMPDECI", S1, S2, R3 },
- { 0x5A7, "CMPDECO", S1, S2, R3 },
- { 0x5AC, "SCANBYTE", S1, S2 },
- { 0x5AE, "CHKBIT", S1, S2 },
- { 0x5B0, "ADDC", S1, S2, R3 },
- { 0x5B2, "SUBC", S1, S2, R3 },
- { 0x5CC, "MOV", S1, R3 },
- { 0x5DC, "MOVV", S1, R3 },
- { 0x5EC, "MOVT", S1, R3 },
- { 0x5FC, "MOVQ", S1, R3 },
- { 0x600, "SYNMOV", IR1, IR3 },
- { 0x601, "SYNMOVV", IR1, IR3 },
- { 0x602, "SYNMOVQ", IR1, IR3 },
- { 0x610, "ATMOD", IR1, S2, R3 },
- { 0x612, "ATADD", IR1, S2, R3 },
- { 0x615, "SYNMOV", IR1, R2 },
- { 0x640, "SPANBIT", S1, R2 },
- { 0x641, "SCANBIT", S1, R2 },
- { 0x642, "DADDC", S1, S2, R3 },
- { 0x643, "DSUBC", S1, S2, R3 },
- { 0x644, "DMOVT", S1, R2 },
- { 0x645, "MODAC", S1, S2, R3 },
- { 0x650, "MODIFY", S1, S2, R3 },
- { 0x651, "EXTRACT", S1, S2, R3 },
- { 0x654, "MODTC", S1, S2, R3 },
- { 0x655, "MODPC", S1, S2 },
- { 0x660, "CALLS", S1 },
- { 0x66B, "MARK" },
- { 0x66C, "FMARK" },
- { 0x66D, "FLUSHREG" },
- { 0x66F, "SYNCF" },
- { 0x670, "EMUL", S1, S2, R3 },
- { 0x671, "EDIV", S1, S2, R3 },
- { 0x674, "CVTIF", S1, R2 },
- { 0x675, "CVTILF", S1, R2 },
- { 0x676, "SCALED", S1, S2, R3 },
- { 0x677, "SCALEF", S1, S2, R3 },
- { 0x680, "ATANF", S1, S2, R3 },
- { 0x681, "LOGEPF", S1, S2, R3 },
- { 0x682, "LOGF", S1, S2, R3 },
- { 0x683, "REMF", S1, S2, R3 },
- { 0x684, "CMPOF", S1, S2 },
- { 0x685, "CMPF", S1, S2 },
- { 0x688, "SQRTF", S1, R2 },
- { 0x689, "EXPF", S1, R2 },
- { 0x68A, "LOGBNTF", S1, R2 },
- { 0x68B, "ROUNDF", S1, R2 },
- { 0x68C, "SINF", S1, R2 },
- { 0x68D, "COSF", S1, R2 },
- { 0x68E, "TANF", S1, R2 },
- { 0x68F, "CLASSF", S1 },
- { 0x690, "ATAND", S1, S2, R3 },
- { 0x691, "LOGEPD", S1, S2, R3 },
- { 0x692, "LOGD", S1, S2, R3 },
- { 0x693, "REMD", S1, S2, R3 },
- { 0x694, "CMPOD", S1, S2 },
- { 0x695, "CMPD", S1, S2 },
- { 0x698, "SQRTD", S1, S2 },
- { 0x699, "EXPD", S1, S2 },
- { 0x69A, "LOGBND", S1, S2 },
- { 0x69B, "ROUNDD", S1, S2 },
- { 0x69C, "SIND", S1, S2 },
- { 0x69D, "COSD", S1, S2 },
- { 0x69E, "TAND", S1, S2 },
- { 0x69F, "CLASSD", S1 },
- { 0x6C0, "CVTRI", S1, R2 },
- { 0x6C1, "CVTRI", S1, R2 },
- { 0x6C2, "CVTRI", S1, R2 },
- { 0x6C3, "CVTRI", S1, R2 },
- { 0x6C9, "MOVF", S1, R2 },
- { 0x6D9, "MOVD", S1, R2 },
- { 0x6E2, "CPYSRE", S1, S2, R3 },
- { 0x6E3, "CPYRSRE", S1, S2, R3 },
- { 0x6E3, "MOVRE", S1, R2 },
- { 0x701, "MULO", S1, S2, R3 },
- { 0x708, "REMO", S1, S2, R3 },
- { 0x70B, "DIVO", S1, S2, R3 },
- { 0x741, "MULI", S1, S2, R3 },
- { 0x748, "REMI", S1, S2, R3 },
- { 0x749, "MODI", S1, S2, R3 },
- { 0x74B, "DIVI", S1, S2, R3 },
- { 0x78B, "DIVF", S1, S2, R3 },
- { 0x78C, "MULF", S1, S2, R3 },
- { 0x78D, "SUBF", S1, S2, R3 },
- { 0x78F, "ADDR", S1, S2, R3 },
- { 0x79B, "DIVD", S1, S2, R3 },
- { 0x79C, "MULD", S1, S2, R3 },
- { 0x79D, "SUBD", S1, S2, R3 },
- { 0x79F, "MODI", S1, S2, R3 },
- { 0 },
- };
- #define NOP (sizeof(optab)/sizeof(Opcode))
- /*
- * get an instruction long
- */
- static int
- igetl(Instr *ip, long *lp)
- {
- if(ip->n >= 2){
- werrstr("instruction too big");
- return -1;
- }
- if (get4(mymap, ip->addr+ip->n*4, (long*) &ip->mem[ip->n]) < 0) {
- werrstr("can't read instruction: %r");
- return -1;
- }
- *lp = ip->mem[ip->n++];
- return 1;
- }
- static Opcode*
- findopcode(ushort code)
- {
- Opcode *o;
- for(o = optab; o->code; o++)
- if(code == o->code)
- return o;
- werrstr("unknown opcode");
- return 0;
- }
- static char*
- genname(ulong l, int reg, int mode, int regonly, int ind)
- {
- static char name[32];
- reg = (l>>reg) & 0x1f;
- if(mode >= 0)
- mode = (l>>mode) & 1;
- else
- mode = 0;
- if(mode)
- sprint(name, regonly?"?$%d?":"$%d", reg);
- else
- sprint(name, ind?"(R%d)":"R%d", reg);
- return name;
- }
- /*
- * decode a reg instruction
- */
- static char*
- regfield(Instr *ip, uchar and, ulong l)
- {
- switch(and){
- case S1:
- case R1:
- case IR1:
- return genname(l, 0, 11, and!=S1, and==IR1);
- case S2:
- case R2:
- case IR2:
- return genname(l, 14, 12, and!=S2, and==IR2);
- case S3:
- case R3:
- case IR3:
- return genname(l, 19, 13, and!=S3, and==IR3);
- default:
- ip->err = "missing regfield";
- return("???");
- }
- }
- static void
- chk56(Instr *ip, ulong l)
- {
- if(l & (3<<5))
- ip->err = "bits 5 and 6 not 0";
- }
- static int
- reginst(Instr *ip, ulong l)
- {
- ushort code;
- int i;
- ip->type = Treg;
- code = ((l>>20)&0xff0) | ((l>>7)&0xf);
- ip->op = findopcode(code);
- if(ip->op == 0)
- return -1;
- for(i = 0; i < 3; i++){
- if(ip->op->and[i] == 0)
- break;
- strcpy(ip->and[i], regfield(ip, ip->op->and[i], l));
- }
- return 0;
- }
- /*
- * decode a control and branch instruction
- */
- static char*
- cobrfield(Instr *ip, uchar and, ulong l)
- {
- long disp;
- switch(and){
- case S1:
- case R1:
- case IR1:
- return genname(l, 19, 13, and!=S1, and==IR1);
- case R2:
- case IR2:
- return genname(l, 14, -1, 1, and==IR2);
- case EA:
- if(l & (1<<12))
- disp = -(((~l) & 0xfff)+1);
- else
- disp = l & 0xfff;
- ip->rel = ip->addr + 4 + disp;
- return ".+";
- default:
- return "???";
- }
- }
- static int
- cobrinst(Instr *ip, ulong l)
- {
- ushort code;
- int i;
- ip->type = Tcobr;
- if(l&3)
- ip->err = "disp not mult of 4";
- code = l>>24;
- ip->op = findopcode(code);
- if(ip->op == 0)
- return -1;
- for(i = 0; i < 3; i++){
- if(ip->op->and[i] == 0)
- break;
- strcpy(ip->and[i], cobrfield(ip, ip->op->and[i], l));
- }
- return 0;
- }
- /*
- * decode a control instruction
- */
- static int
- ctrlinst(Instr *ip, ulong l)
- {
- ushort code;
- long disp;
- ip->type = Tctrl;
- if(l&3)
- ip->err = "disp not mult of 4";
- code = l>>24;
- ip->op = findopcode(code);
- if(ip->op == 0)
- return -1;
- if(ip->op->and[0] == 0)
- return 0;
- if(l & (1<<23))
- disp = -(((~l) & 0x7fffff)+1);
- else
- disp = l & 0x7fffff;
- ip->rel = ip->addr + 4 + disp;
- strcpy(ip->and[0], ".+");
- return 0;
- }
- static int
- sprintoff(char *addr, int n, char *fmt, ulong v)
- {
- Symbol s;
- long w;
- w = v+mach->sb;
- if (findsym(w, CDATA, &s)) {
- w = s.value-w;
- if (w <= 4096) {
- if (w)
- return snprint(addr, n, "%s+%lux(SB)", s.name, w);
- else
- return snprint(addr, n, "%s(SB)", s.name);
- }
- }
- return snprint(addr, n, fmt, v);
- }
- /*
- * decode a memory instruction
- */
- static char*
- memfield(Instr *ip, uchar and, ulong l)
- {
- long disp;
- static char addr[64];
- int abase;
- int scale;
- int index;
- ip->mult = 1;
- switch(and){
- case R1:
- case IR1:
- return genname(l, 19, -1, 1, and==IR1);
- case EA:
- abase = (l>>14)&0x1f;
- scale = 1 << ((l>>7)&0x7);
- index = l & 0x1f;
- switch((l>>10)&0xf){
- case 0x4:
- chk56(ip, l);
- ip->base = abase + 1;
- sprint(addr, "(R%d)", abase);
- break;
- case 0x5:
- chk56(ip, l);
- if (igetl(ip, &disp) < 0) {
- strcpy(addr, "???");
- break;
- }
- ip->rel = disp + ip->addr + 8;
- strcpy(addr, ".+");
- break;
- case 0x6:
- strcpy(addr, "???");
- break;
- case 0x7:
- chk56(ip, l);
- ip->base = abase + 1;
- ip->mult = scale;
- ip->index = index + 1;
- sprint(addr, "(R%d)(%d*R%d)", abase, scale, index);
- break;
- case 0xc:
- chk56(ip, l);
- if (igetl(ip, &disp) < 0) {
- strcpy(addr, "???");
- break;
- }
- ip->rel = disp;
- strcpy(addr, ".+");
- break;
- case 0xd:
- chk56(ip, l);
- if (igetl(ip, &disp) < 0) {
- strcpy(addr, "???");
- break;
- }
- ip->rel = disp;
- if(abase == 28)
- sprintoff(addr, sizeof(addr), "%lux(R28)", disp);
- else{
- ip->base = abase + 1;
- sprint(addr, "%lx(R%d)", disp, abase);
- }
- break;
- case 0xe:
- chk56(ip, l);
- if (igetl(ip, &disp) < 0) {
- strcpy(addr, "???");
- break;
- }
- ip->rel = disp;
- ip->mult = scale;
- ip->index = index + 1;
- sprint(addr, "%lx(%d*R%d)", disp, scale, index);
- break;
- case 0xf:
- chk56(ip, l);
- if (igetl(ip, &disp) < 0) {
- strcpy(addr, "???");
- break;
- }
- ip->rel = disp;
- ip->mult = scale;
- ip->index = index + 1;
- ip->base = abase + 1;
- sprint(addr, "%lx(R%d)(%d*R%d)", disp, abase,
- scale, index);
- break;
- default:
- disp = l&0xfff;
- ip->rel = disp;
- if(l & (1<<13)){
- if(abase == 28)
- sprintoff(addr, sizeof(addr), "%lux(R28)", disp);
- else{
- ip->base = abase + 1;
- sprint(addr, "%lux(R%d)", disp, abase);
- }
- } else {
- strcpy(addr, ".+");
- }
- break;
- }
- return addr;
- default:
- break;
- }
- return "???";
- }
- static int
- meminst(Instr *ip, ulong l)
- {
- ushort code;
- int i;
- ip->type = Tmem;
- code = l>>24;
- ip->op = findopcode(code);
- if(ip->op == 0)
- return -1;
- for(i = 0; i < 2; i++){
- if(ip->op->and[i] == 0)
- break;
- strcpy(ip->and[i], memfield(ip, ip->op->and[i], l));
- }
- return 0;
- }
- static int
- mkinstr(Instr *ip, ulong pc)
- {
- long l;
- memset(ip, 0, sizeof(Instr));
- ip->addr = pc;
- if (igetl(ip, &l) < 0)
- return -1;
- switch(l>>28){
- case 0x0:
- case 0x1:
- return ctrlinst(ip, l);
- case 0x2:
- case 0x3:
- return cobrinst(ip, l);
- case 0x5:
- case 0x6:
- case 0x7:
- return reginst(ip, l);
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- case 0xc:
- return meminst(ip, l);
- }
- werrstr("unknown opcode");
- return -1;
- }
- static int
- i960inst(Map *map, ulong pc, char modifier, char *buf, int n)
- {
- Instr instr;
- int i;
- char *and;
- char *end;
- USED(modifier);
- mymap = map;
- if(mkinstr(&instr, pc) < 0)
- return -1;
- end = buf+n-1;
- buf += snprint(buf, end-buf, "%s ", instr.op->name);
- for(i = 0; i < 3; i++){
- and = instr.and[i];
- if(*and == 0)
- break;
- if(i != 0)
- buf += snprint(buf, end-buf, ",");
- if(strcmp(and, ".+") == 0){
- buf += sprintoff(buf, end-buf, "$%lux", instr.rel);
- } else
- buf += snprint(buf, end-buf, "%s", and);
- }
- if(instr.err)
- snprint(buf, end-buf, "\t\t;%s", instr.err);
- return instr.n*4;
- }
- static int
- i960das(Map *map, ulong pc, char *buf, int n)
- {
- Instr instr;
- mymap = map;
- if (mkinstr(&instr, pc) < 0)
- return -1;
- if (n > 8) {
- _hexify(buf, instr.mem[0], 7);
- n -= 8;
- buf += 8;
- }
- if (n > 9 && instr.n == 2) {
- *buf++ = ' ';
- _hexify(buf, instr.mem[1], 7);
- buf += 8;
- }
- *buf = 0;
- return instr.n*4;
- }
- static int
- i960instlen(Map *map, ulong pc)
- {
- Instr instr;
- mymap = map;
- if (mkinstr(&instr, pc) < 0)
- return -1;
- return instr.n*4;
- }
- static int
- i960foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
- {
- Instr instr;
- ulong l;
- char buf[8];
- mymap = map;
- if (mkinstr(&instr, pc) < 0)
- return -1;
- foll[0] = pc + instr.n;
- switch(instr.type){
- case Tcobr:
- case Treg:
- break;
- case Tctrl:
- if(instr.op->name[0] == 'B'){
- foll[1] = instr.rel;
- return 2;
- }
- if(strcmp("CALL", instr.op->name) == 0){
- foll[0] = instr.rel;
- return 1;
- }
- if(strcmp("RET", instr.op->name) == 0)
- return -1;
- break;
- case Tmem:
- if(strcmp("BAL", instr.op->name) == 0
- || strcmp("CALL", instr.op->name) == 0){
- l = instr.rel;
- if(instr.index){
- sprint(buf, "R%d", instr.index - 1);
- l += (*rget)(map, buf) * instr.mult;
- }
- if(instr.base){
- sprint(buf, "R%d", instr.base - 1);
- l += (*rget)(map, buf);
- }
- foll[0] = l;
- return 1;
- }
- break;
- }
- return 1;
- }
|