xref: /original-bsd/old/adb/adb.tahoe/opset.c (revision 57124d5e)
1 #ifndef lint
2 static	char sccsid[] = "@(#)opset.c	1.1 (Berkeley) 02/25/86";
3 #endif
4 /*
5  *
6  *	UNIX debugger
7  *
8  */
9 
10 #include "defs.h"
11 #include "optab.h"
12 
13 STRING		errflg;
14 L_INT		dot;
15 INT		dotinc;
16 L_INT		var[];
17 
18 
19 /* instruction printing */
20 
21 POS	type, space, incp;
22 
23 OPTAB ioptab[256]; /* index by opcode to optab */
24 
25 mkioptab() {/* set up ioptab */
26 	REG OPTAB p=optab;
27 	while (p->iname){
28 		ioptab[p->val&LOBYTE]=p;
29 		p++;
30 	}
31 }
32 
33 printins(idsp,ins)
34 	REG L_INT	ins;
35 {
36 	short	argno;		/* argument index */
37 	REG	mode;		/* mode */
38 	REG	r;		/* register name */
39 	REG	d;		/* assembled byte, word, long or float */
40 	long	snarf();
41 	REG char *	ap;
42 	REG OPTAB	ip;
43 
44 	type = DSYM;
45 	space = idsp;
46 	ins = byte(ins);
47 	if((ip=ioptab[ins]) == (OPTAB)0) {
48 		printf("?%2x%8t", ins);
49 		dotinc = 1;
50 		return;
51 	}
52 	printf("%s%8t",ip->iname);
53 	incp = 1;
54 	ap = ip->argtype;
55 	for (argno=0; argno<ip->nargs; argno++,ap++) {
56 		var[argno] = 0x80000000;
57 		if (argno!=0) printc(',');
58 	  top:
59 		if (*ap&ACCB)
60 			mode = 0xAF + ((*ap&7)<<5);  /* branch displacement */
61 		else{
62 			mode = bchkget(inkdot(incp),idsp); ++incp;
63 		}
64 		r = mode&0xF;
65 		mode >>= 4;
66 		switch ((int)mode) {
67 			case 0:
68 			case 1:
69 			case 2:
70 			case 3:
71 				/* short literal */
72 				printc('$');
73 				d = mode<<4|r;
74 				goto immed;
75 			case 4: /* [r] */
76 				printf("[%s]",regname[r]);
77 				goto top;
78 			case 5: /* r */
79 				printf("%s",regname[r]);
80 				break;
81 			case 6: /* (r) */
82 				printf("(%s)",regname[r]);
83 				break;
84 			case 7: /* -(r) */
85 				printf("-(%s)",regname[r]);
86 				break;
87 			case 9: /* *(r)+ */
88 				printc('*');
89 			case 8: /* (r)+ */
90 				if(r==0xF || mode==8 && (r==8 || r==9)) {
91 					printc('$');
92 					d = snarf((r&03)+1, idsp);
93 				} else {	/*it's not PC immediate or abs*/
94 					printf("(%s)+",regname[r]);
95 					break;
96 				}
97 			immed:
98 				if(ins == KCALL && d>=0 && d<SYSSIZ) {
99 					if(systab[d])
100 						printf(systab[d]);
101 					else
102 						printf("%R", d);
103 					break;
104 				}
105 				goto disp;
106 			case 0xB:	/* byte displacement deferred */
107 			case 0xD:	/* word displacement deferred */
108 			case 0xF:	/* long displacement deferred */
109 				printc('*');
110 			case 0xA:	/* byte displacement */
111 			case 0xC:	/* word displacement */
112 			case 0xE:	/* long displacement */
113 				d = snarf(1<<((mode>>1&03)-1), idsp);
114 				if (r==0xF) { /* PC offset addressing */
115 					d += dot+incp;
116 					psymoff(d,type,"");
117 					var[argno]=d;
118 					break;
119 				}
120 			disp:
121 				if(d>=0 && d<maxoff)
122 					printf("%R", d);
123 				else
124 					psymoff(d,type,"");
125 				if (mode>=0xA)
126 					printf("(%s)",regname[r]);
127 				var[argno]=d;
128 				break;
129 		} /* end of the mode switch */
130 	}
131 	if (ins==CASEL) {
132 		if(inkdot(incp)&01)	/* align */
133 			incp++;
134 		for (argno=0; argno<=var[2]; ++argno) {
135 			printc(EOR);
136 			printf("    %R:  ",argno+var[1]);
137 			d=shorten(get(inkdot(incp+argno+argno),idsp));
138 			if (d&0x8000) d -= 0x10000;
139 			psymoff(inkdot(incp)+d,type,"");
140 		}
141 		incp += var[2]+var[2]+2;
142 	}
143 	dotinc=incp;
144 }
145 
146 long snarf (nbytes, idsp)
147 {
148 	register long value;
149 
150 	value = chkget(inkdot(incp), idsp);
151 	incp += nbytes;
152 	return(value>>(4-nbytes)*8);
153 }
154