|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)opset.c 4.6 1/10/88";
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 1-based 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) + 1;
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] - 1];
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: if (regnumber == R_PC)
389: psymoff(valuep->num_ulong[0], type, &insoutfmt[0]);
390: else { /* } */
391: printf(LPRMODE, valuep->num_ulong[0]);
392: printf(insoutfmt);
393: #endif /* ADB */
394: #ifdef SDB
395: if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0])
396: && (regnumber != R_PC)){
397: #endif /* SDB */
398: printf("(%s)", insregname(regnumber));
399: }
400: savevar((long)valuep->num_ulong[0]);
401: }
402: /*
403: * get a register name
404: */
405: char *insregname(regnumber)
406: int regnumber;
407: {
408: char *r;
409: r = regname[regnumber];
410: #ifdef SDB
411: if ( (insoutfmt[0] == 'i')
412: && (regnumber >= 6)
413: && (regnumber <= 11)
414: && (adrtoregvar(regnumber, procp) != -1)) {
415: r = sl_name;
416: }
417: #endif /* SDB */
418: return(r);
419: }
420: /*
421: * print out a short literal
422: */
423: shortliteral(mode, optype)
424: u_char mode;
425: u_char optype;
426: {
427: savevar((long)mode);
428: switch(A_TYPEXT(optype)){
429: case TYPF:
430: case TYPD:
431: case TYPG:
432: case TYPH:
433: printf("$%s", fltimm[mode]);
434: break;
435: default:
436: #ifdef ADB
437: printf("$%r", mode);
438: #endif /* ADB */
439: #ifdef SDB
440: printf("$%d", mode);
441: #endif /* SDB */
442: break;
443: }
444: }
445:
446: pcimmediate(mode, optype)
447: u_char mode;
448: u_char optype;
449: {
450: int nbytes;
451:
452: printc('$');
453: if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/
454: dispaddress(snarfreloc(4), mode);
455: return;
456: }
457: nbytes = ty_nbyte[A_TYPEXT(optype)];
458: if (! ty_NORELOC[A_TYPEXT(optype)]){
459: dispaddress(snarfreloc(nbytes), mode);
460: return;
461: }
462: bignumprint(nbytes, optype);
463: }
464:
465: bignumprint(nbytes, optype)
466: int nbytes;
467: u_char optype;
468: {
469: numberp valuep;
470: int leading_zero = 1;
471: REG int bindex;
472: REG int nindex;
473: REG int ch;
474:
475: valuep = snarf(nbytes);
476: switch(A_TYPEXT(optype)){
477: case TYPF:
478: printf("0f%f", valuep->num_num.numFf_float.Ff_value);
479: break;
480: case TYPD:
481: printf("0d%f", valuep->num_num.numFd_float.Fd_value);
482: break;
483: case TYPG:
484: printf("0g::"); goto qprint;
485: case TYPH:
486: printf("0h::"); goto qprint;
487: case TYPQ:
488: case TYPO:
489: qprint:
490: for (bindex = nbytes - 1; bindex >= 0; --bindex){
491: for (nindex = 4; nindex >= 0; nindex -= 4){
492: ch = (valuep->num_uchar[bindex] >> nindex);
493: ch &= 0x0F;
494: if ( ! (leading_zero &= (ch == 0) ) ){
495: if (ch <= 0x09)
496: printc(ch + '0');
497: else
498: printc(ch - 0x0A + 'a');
499: }
500: }
501: }
502: break;
503: }
504: }
505: #ifdef SDB
506:
507: L_INT inkdot(incr)
508: int incr;
509: {
510: L_INT newdot;
511:
512: newdot = dot + incr;
513: return(newdot);
514: }
515:
516: printc(c)
517: char c;
518: {
519: printf("%c", c);
520: }
521:
522: psymoff(v, regnumber, fmt)
523: L_INT v;
524: char *fmt;
525: {
526: struct proct *procp;
527: REG int diff;
528: if (fmt[0] == 'i') {
529: switch(regnumber){
530: case 12: /* parameter */
531: if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot)))
532: != -1) {
533: printf("%s", sl_name);
534: prdiff(diff);
535: return(0);
536: }
537: break;
538: case 13: /* local */
539: if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot))
540: ) != -1) {
541: printf("%s", sl_name);
542: prdiff(diff);
543: return(0);
544: }
545: break;
546: default:
547: break;
548: }
549: if (v < firstdata) {
550: if ((procp = adrtoprocp((ADDR) v)) != badproc) {
551: prlnoff(procp, v);
552: return(0);
553: }
554: } else {
555: if ((diff = adrtoext((ADDR) v)) != -1) {
556: printf("%s", sl_name);
557: prdiff(diff);
558: return(0);
559: }
560: }
561: }
562: prhex(v);
563: return(1);
564: }
565:
566: prdiff(diff)
567: {
568: if (diff) {
569: printf("+");
570: prhex(diff);
571: }
572: }
573:
574: #endif /* SDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.