|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)opset.c 4.2 10/27/82";
3: #endif lint
4: /*
5: * UNIX debugger
6: * Instruction printing routines.
7: * MACHINE DEPENDENT
8: */
9:
10: #ifdef ADB
11: #include "defs.h"
12: #endif ADB
13: #ifdef SDB
14: #include "head.h"
15: #endif SDB
16:
17: L_INT dot;
18: INT dotinc;
19: L_INT insoutvar[36];
20: #ifdef ADB
21: L_INT var[36];
22: #endif ADB
23:
24: #undef INSTTAB
25: #include "instrs.h"
26:
27: STRING regname[];
28: STRING fltimm[];
29: POS type, space, incp;
30: /*
31: * Definitions for registers and for operand classes
32: */
33: char *insregname(); /* how to print a register */
34:
35: #define R_PC 0xF
36:
37: #define OC_IMM0 0x0
38: #define OC_IMM1 0x1
39: #define OC_IMM2 0x2
40: #define OC_IMM3 0x3
41: #define OC_INDEX 0x4
42: #define OC_REG 0x5
43: #define OC_DREG 0x6
44: #define OC_ADREG 0x7
45: #define OC_AIREG 0x8
46: #define OC_DAIREG 0x9
47:
48: #define OC_BDISP 0xA
49: #define OC_DBDISP 0xB
50: #define OC_WDISP 0xC
51: #define OC_DWDISP 0xD
52: #define OC_LDISP 0xE
53: #define OC_DLDISP 0xF
54:
55: #define OC_SHIFT 4
56: #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
57: #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF)
58: #define OC_REGEXT(x) ((x) & 0xF)
59:
60: /*
61: * Definitions for large numbers
62: */
63: #include "asnumber.h"
64: typedef struct as_number *numberp;
65: numberp snarf();
66: numberp snarfreloc();
67: /*
68: * Definitions for special instructions
69: */
70: #define CASEB 0x8F
71: #define CASEW 0xAF
72: #define CASEL 0xCF
73: /*
74: * Definitions for converting TYP's into numbers, booleans, etc.
75: * These are shared with the assembler.
76: */
77: extern int ty_NORELOC[];
78: extern int ty_float[];
79: extern int ty_nbyte[];
80: extern int ty_nlg[];
81: extern char *ty_string[];
82:
83: short ioptab[3][256]; /* two level index by opcode into insttab */
84:
85: int mapescbyte(byte)
86: u_char byte;
87: {
88: switch(byte){
89: default: return(0);
90: case ESCD: return(1);
91: case ESCF: return(2);
92: }
93: }
94:
95: mkioptab()
96: {
97: REG struct insttab *p;
98: int mapchar;
99:
100: for(p = insttab; p->iname; p++){
101: mapchar = mapescbyte(p->eopcode);
102: if (ioptab[mapchar][p->popcode])
103: continue;
104: ioptab[mapchar][p->popcode] = p - insttab;
105: }
106: }
107:
108: u_char snarfuchar();
109: /*
110: * Global variables for communicating with the minions and printins
111: */
112: static int idsp;
113: static short argno; /* which argument one is working on */
114: static char insoutfmt[2]; /* how to format the relocated symbols */
115: #ifdef SDB
116: static struct proct *procp;
117: #endif SDB
118:
119: static savevar(val)
120: long val;
121: {
122: var[argno] = val;
123: insoutvar[argno] = val;
124: }
125:
126: printins(fmt, Idsp, ins)
127: char fmt;
128: #ifndef vax
129: u_char ins;
130: #else
131: u_char ins;
132: #endif
133: int Idsp;
134: {
135: u_char mode; /* mode */
136: u_char ins2;
137: char *indexreg; /* print of which register indexes */
138: char *indexed; /* we indexed */
139: char *operandout();
140: REG u_char *ap;
141: REG struct insttab *ip;
142: u_char optype;
143: int mapchar;
144:
145: idsp = Idsp;
146: type = DSYM;
147: space = idsp;
148: #ifdef SDB
149: procp = adrtoprocp(dot);
150: if (procp->paddr == dot){
151: printf("0x%04.4x", ins);
152: incp = 2;
153: goto ret;
154: }
155: #endif SDB
156:
157: #ifdef ADB
158: insoutfmt[0] = 0;
159: #endif ADB
160: #ifdef SDB
161: insoutfmt[0] = fmt;
162: #endif SDB
163:
164: incp = 1;
165: if ((mapchar = mapescbyte(ins)) != 0){
166: ins2 = snarfuchar();
167: if (ioptab[mapchar][ins2] == 0){
168: /*
169: * Oops; not a defined instruction;
170: * back over this escape byte.
171: */
172: incp -= 1;
173: mapchar = 0;
174: } else {
175: ins = ins2;
176: }
177: }
178: if (ioptab[mapchar][ins] == 0){
179: printf("<undefined operator byte>: %x", ins);
180: goto ret;
181: }
182: ip = &insttab[ioptab[mapchar][ins]];
183: printf("%s\t", ip->iname);
184:
185: for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) {
186: savevar(0x80000000); /* an illegal symbol */
187: optype = *ap;
188: if (argno != 0)
189: printc(',');
190: indexreg = 0;
191: indexed = 0;
192: do{
193: if (A_ACCEXT(optype) & ACCB){
194: switch(A_TYPEXT(optype)){
195: case TYPB:
196: mode = OC_CONS(OC_BDISP, R_PC);
197: break;
198: case TYPW:
199: mode = OC_CONS(OC_WDISP, R_PC);
200: break;
201: }
202: } else {
203: mode = snarfuchar();
204: }
205: indexreg = operandout(mode, optype);
206: if (indexed)
207: printf("[%s]", indexed);
208: indexed = indexreg;
209: } while(indexed);
210: }
211: if (mapchar == 0){
212: switch(ins){
213: case CASEB:
214: case CASEW:
215: case CASEL:
216: casebody(insoutvar[1], insoutvar[2]);
217: break;
218: default:
219: break;
220: }
221: }
222: ret: ;
223:
224: #ifdef SDB
225: oincr = incp;
226: #endif SDB
227: #ifdef ADB
228: dotinc = incp;
229: #endif ADB
230: }
231:
232: casebody(base, limit)
233: long base;
234: long limit;
235: {
236: int i;
237: POS baseincp;
238: POS advincp;
239: struct as_number *valuep;
240: #define OSIZE (sizeof(short))
241: argno = 0;
242: baseincp = incp;
243: for (i = 0; i <= limit; i++) {
244: printc(EOR);
245: #ifdef SDB
246: printf(" %d: ", i + base);
247: #endif SDB
248: #ifdef ADB
249: printf(" %R: ", i + base);
250: #endif ADB
251: valuep = snarfreloc(OSIZE, 0);
252: advincp = incp;
253: incp = baseincp;
254: dispaddress(valuep, OC_CONS(OC_WDISP, R_PC));
255: incp = advincp;
256: }
257: }
258:
259: /*
260: * magic values to mung an offset to a register into
261: * something that psymoff can understand.. all magic
262: */
263: /* 0 1 2 3 4 */
264: static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0};
265: static long magic_compl[5] = {0, 0x100, 0x10000,0, 0};
266: /*
267: * Snarf up some bytes, and put in the magic relocation flags
268: */
269: numberp snarfreloc(nbytes)
270: int nbytes;
271: {
272: numberp back;
273: back = snarf(nbytes);
274: if (back->num_ulong[0] & magic_masks[nbytes])
275: back->num_ulong[0] -= magic_compl[nbytes];
276: return(back);
277: }
278: /*
279: * The following code is NOT portable from the PDP 11 to the VAX
280: * because of the byte ordering problem.
281: */
282: numberp snarf(nbytes)
283: int nbytes;
284: {
285: REG int i;
286:
287: static struct as_number backnumber;
288: static struct as_number znumber; /* init'ed to 0 */
289:
290: backnumber = znumber;
291: for (i = 0; i < nbytes; i++)
292: backnumber.num_uchar[i] = snarfuchar();
293: return(&backnumber);
294: }
295: /*
296: * Read one single character, and advance the dot
297: */
298: u_char snarfuchar()
299: {
300: u_char back;
301: /*
302: * assert: bchkget and inkdot don't have side effects
303: */
304: back = (u_char)bchkget(inkdot(incp), idsp);
305: incp += 1;
306: return(back);
307: }
308: /*
309: * normal operand; return non zero pointer to register
310: * name if this is an index instruction.
311: */
312: char *operandout(mode, optype)
313: u_char mode;
314: u_char optype;
315: {
316: char *r;
317: int regnumber;
318: int nbytes;
319:
320: regnumber = OC_REGEXT(mode);
321: r = insregname(regnumber);
322: switch (OC_AMEXT(mode)){
323: case OC_IMM0:
324: case OC_IMM1:
325: case OC_IMM2:
326: case OC_IMM3:
327: shortliteral(mode, optype);
328: return(0);
329: case OC_INDEX:
330: return(r); /* will be printed later */
331: case OC_REG:
332: printf("%s", r);
333: return(0);
334: case OC_DREG:
335: printf("(%s)", r);
336: return(0);
337: case OC_ADREG:
338: printf("-(%s)", r);
339: return(0);
340: case OC_DAIREG:
341: printc('*');
342: case OC_AIREG:
343: if (regnumber == R_PC){
344: pcimmediate(mode, optype);
345: } else {
346: printf("(%s)+", r);
347: }
348: return(0);
349: case OC_DBDISP:
350: printc('*');
351: case OC_BDISP:
352: nbytes = 1;
353: break;
354: case OC_DWDISP:
355: printc('*');
356: case OC_WDISP:
357: nbytes = 2;
358: break;
359: case OC_DLDISP:
360: printc('*');
361: case OC_LDISP:
362: nbytes = 4;
363: break;
364: }
365: dispaddress(snarfreloc(nbytes), mode);
366: return(0);
367: }
368:
369: dispaddress(valuep, mode)
370: numberp valuep;
371: u_char mode;
372: {
373: int regnumber = OC_REGEXT(mode);
374:
375: switch(OC_AMEXT(mode)){
376: case OC_BDISP:
377: case OC_DBDISP:
378: case OC_WDISP:
379: case OC_DWDISP:
380: case OC_LDISP:
381: case OC_DLDISP:
382: if (regnumber == R_PC){
383: /* PC offset addressing */
384: valuep->num_ulong[0] += inkdot(incp);
385: }
386: }
387: #ifdef ADB
388: psymoff(valuep->num_ulong[0], type, &insoutfmt[0]);
389: if (regnumber != R_PC){ /* } */
390: #endif ADB
391: #ifdef SDB
392: if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0])
393: && (regnumber != R_PC)){
394: #endif SDB
395: printf("(%s)", insregname(regnumber));
396: }
397: savevar((long)valuep->num_ulong[0]);
398: }
399: /*
400: * get a register name
401: */
402: char *insregname(regnumber)
403: int regnumber;
404: {
405: char *r;
406: r = regname[regnumber];
407: #ifdef SDB
408: if ( (insoutfmt[0] == 'i')
409: && (regnumber >= 6)
410: && (regnumber <= 11)
411: && (adrtoregvar(regnumber, procp) != -1)) {
412: r = sl_name;
413: }
414: #endif SDB
415: return(r);
416: }
417: /*
418: * print out a short literal
419: */
420: shortliteral(mode, optype)
421: u_char mode;
422: u_char optype;
423: {
424: savevar((long)mode);
425: switch(A_TYPEXT(optype)){
426: case TYPF:
427: case TYPD:
428: case TYPG:
429: case TYPH:
430: printf("$%s", fltimm[mode]);
431: break;
432: default:
433: #ifdef ADB
434: printf("$%r", mode);
435: #endif ADB
436: #ifdef SDB
437: printf("$%d", mode);
438: #endif SDB
439: break;
440: }
441: }
442:
443: pcimmediate(mode, optype)
444: u_char mode;
445: u_char optype;
446: {
447: int nbytes;
448:
449: printc('$');
450: if (mode == OC_DAIREG){ /* PC absolute, always 4 bytes*/
451: dispaddress(snarfreloc(4), mode);
452: return;
453: }
454: nbytes = ty_nbyte[A_TYPEXT(optype)];
455: if (! ty_NORELOC[A_TYPEXT(optype)]){
456: dispaddress(snarfreloc(nbytes), mode);
457: return;
458: }
459: bignumprint(nbytes, optype);
460: }
461:
462: bignumprint(nbytes, optype)
463: int nbytes;
464: u_char optype;
465: {
466: numberp valuep;
467: int leading_zero = 1;
468: REG int bindex;
469: REG int nindex;
470: REG int ch;
471:
472: valuep = snarf(nbytes);
473: switch(A_TYPEXT(optype)){
474: case TYPF:
475: printf("0f%f", valuep->num_num.numFf_float.Ff_value);
476: break;
477: case TYPD:
478: printf("0d%f", valuep->num_num.numFd_float.Fd_value);
479: break;
480: case TYPG:
481: printf("0g::"); goto qprint;
482: case TYPH:
483: printf("0h::"); goto qprint;
484: case TYPQ:
485: case TYPO:
486: qprint:
487: for (bindex = nbytes - 1; bindex >= 0; --bindex){
488: for (nindex = 4; nindex >= 0; nindex -= 4){
489: ch = (valuep->num_uchar[bindex] >> nindex);
490: ch &= 0x0F;
491: if ( ! (leading_zero &= (ch == 0) ) ){
492: if (ch <= 0x09)
493: printc(ch + '0');
494: else
495: printc(ch - 0x0A + 'a');
496: }
497: }
498: }
499: break;
500: }
501: }
502: #ifdef SDB
503:
504: L_INT inkdot(incr)
505: int incr;
506: {
507: L_INT newdot;
508:
509: newdot = dot + incr;
510: return(newdot);
511: }
512:
513: printc(c)
514: char c;
515: {
516: printf("%c", c);
517: }
518:
519: psymoff(v, regnumber, fmt)
520: L_INT v;
521: char *fmt;
522: {
523: struct proct *procp;
524: REG int diff;
525: if (fmt[0] == 'i') {
526: switch(regnumber){
527: case 12: /* parameter */
528: if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot)))
529: != -1) {
530: printf("%s", sl_name);
531: prdiff(diff);
532: return(0);
533: }
534: break;
535: case 13: /* local */
536: if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot))
537: ) != -1) {
538: printf("%s", sl_name);
539: prdiff(diff);
540: return(0);
541: }
542: break;
543: default:
544: break;
545: }
546: if (v < firstdata) {
547: if ((procp = adrtoprocp((ADDR) v)) != badproc) {
548: prlnoff(procp, v);
549: return(0);
550: }
551: } else {
552: if ((diff = adrtoext((ADDR) v)) != -1) {
553: printf("%s", sl_name);
554: prdiff(diff);
555: return(0);
556: }
557: }
558: }
559: prhex(v);
560: return(1);
561: }
562:
563: prdiff(diff)
564: {
565: if (diff) {
566: printf("+");
567: prhex(diff);
568: }
569: }
570:
571: #endif SDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.