|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.