xref: /original-bsd/old/sdb/opset.c (revision ba72ef4c)
1 static	char sccsid[] = "@(#)opset.c 4.1 10/09/80";
2 #
3 /*
4  *
5  *	UNIX debugger
6  *
7  *		Instruction printing routines.
8  *		MACHINE DEPENDENT.
9  */
10 
11 #include "head.h"
12 SCCSID(@(#)opset.c	2.4);
13 
14 STRING		errflg;
15 L_INT		dot;
16 INT		dotinc;
17 L_INT		vvar[36];
18 
19 
20 /* instruction printing */
21 
22 /*
23  * Argument access types
24  */
25 #define ACCA	(8<<3)	/* address only */
26 #define ACCR	(1<<3)	/* read */
27 #define ACCW	(2<<3)	/* write */
28 #define ACCM	(3<<3)	/* modify */
29 #define ACCB	(4<<3)	/* branch displacement */
30 #define ACCI	(5<<3)	/* XFC code */
31 
32 /*
33  * Argument data types
34  */
35 #define TYPB	0	/* byte */
36 #define TYPW	1	/* word */
37 #define TYPL	2	/* long */
38 #define TYPQ	3	/* quad */
39 #define TYPF	4	/* floating */
40 #define TYPD	5	/* double floating */
41 
42 
43 TYPE	struct optab	*OPTAB;
44 struct optab {
45 	char *iname;
46 	char val;
47 	char nargs;
48 	char argtype[6];
49 } optab[];
50 #define SYSTAB struct systab
51 SYSTAB {
52 	int	argc;
53 	char	*sname;
54 } systab[];
55 STRING	regname[];
56 STRING	fltimm[];
57 POS	type, space, incp;
58 
59 int ioptab[256]; /* index by opcode to optab */
60 
61 mkioptab() {/* set up ioptab */
62 REG OPTAB p=optab; while (p->iname) {ioptab[p->val&LOBYTE]=p-optab; p++;}
63 }
64 
65 extern char *fmtr;
66 extern char *fmtR;
67 
68 printins(fmt,idsp,ins)
69 char fmt;
70 #ifndef vax
71 REG INT		ins;
72 #else
73 REG L_INT	ins;
74 #endif
75 {
76 	short i,b,mode; char **r; long d; char *fmat;
77 	struct proct *procp;
78 	REG char *	ap;
79 	REG OPTAB	ip;
80 #ifndef vax
81 	struct {char b_2,b_3,b_0,b_1;};
82 #else
83 	struct {char b_0,b_1,b_2,b_3;};
84 #endif
85 	procp = adrtoprocp(dot);
86 	if (procp->paddr == dot) {
87 		printf("0x%04.4x", ins & 0xffff);
88 		oincr = 2;
89 		return;
90 	}
91 
92 	type=DSYM; space=idsp;
93 	ins &= LOBYTE;
94 	ip=optab+ioptab[ins]; printf("%s\t",ip->iname); incp=1;
95 	ap=ip->argtype;
96 	for (i=0; i<ip->nargs; i++,ap++) {
97 		vvar[i]=0x80000000;
98 		if (i!=0) printc(',');
99 	  top:
100 		if (*ap&ACCB) b= 0xAF + ((*ap&7)<<5);  /* branch displacement */
101 		else {b=bchkget(inkdot(incp),idsp); ++incp;}
102 		if (b&0300) {/* not short literal */
103 			char *slnptr;
104 			int regno;
105 			regno = b & 0xF;
106 			if (fmt=='i' && regno >= 6 && regno <= 11 &&
107 			    adrtoregvar(regno, procp) != -1) {
108 				slnptr = sl_name;
109 				r = &slnptr;
110 			}
111 			else
112 				r= &regname[regno];
113 			mode= b >>= 4;
114 		  mid:
115 			switch ((int)mode) {
116 				case 4: /* [r] */ printf("[%s]",*r); goto top;
117 				case 5: /* r */ printf("%s",*r); break;
118 				case 7: /* -(r) */ printc('-');
119 			  base:
120 				case 6: /* (r) */ printf("(%s)",*r); break;
121 				case 9: /* *(r)+ */ printc('*');
122 				case 8: /* (r)+ */
123 				  if (r==(regname+0xF)) {/* PC: immediate or absolute */
124 					printc('$'); if (b==9) goto abs;
125 					mode=((*ap&7)<<1)+0xA; goto mid;
126 				  }
127 				  printf("(%s)+",*r); break;
128 				case 0xB: printc('*');
129 				case 0xA: d=bchkget(inkdot(incp),idsp); ++incp;
130 				  if (d&0x80) d -= 0x100; fmat=fmtr;
131 			  disp:
132 				  vvar[i]=d;
133 				  if (r==(regname+0xF) && b>=0xA) vvar[i] += dot+incp;
134 				  if (psymoff(vvar[i],r,fmt) && r!=regname+0xF)
135 					goto base;
136 				  break;
137 				case 0xD: printc('*');
138 				case 0xC: d=0;
139 					d.b_0 = bchkget(inkdot(incp),idsp); ++incp;
140 					d.b_1 = bchkget(inkdot(incp),idsp); ++incp;
141 					if (d&0x8000) d -= 0x10000; fmat=fmtr;
142 					goto disp;
143 				case 0xF: printc('*');
144 				case 0xE:
145 			  abs:
146 					d.b_0 = bchkget(inkdot(incp),idsp); ++incp;
147 					d.b_1 = bchkget(inkdot(incp),idsp); ++incp;
148 					d.b_2 = bchkget(inkdot(incp),idsp); ++incp;
149 					d.b_3 = bchkget(inkdot(incp),idsp); ++incp;
150 					fmat=fmtR; goto disp;
151 			}
152 		} else {/* short literal */
153 			vvar[i]=b;
154 			if ((*ap&7)==TYPF || (*ap&7)==TYPD)
155 				printf("$%s",fltimm[b]);
156 			else printf("$%d",b);
157 		}
158 	}
159 	if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */
160 		for (i=0; i<=vvar[2]; ++i) {
161 			printc(EOR); printf("    %d:  ",i+vvar[1]);
162 			d=get(inkdot(incp+i+i),idsp)&0xFFFF;
163 			if (d&0x8000) d -= 0x10000;
164 			psymoff(inkdot(incp)+d,type,fmt);
165 		}
166 		incp += vvar[2]+vvar[2]+2;
167 	}
168 	oincr=incp;
169 }
170 
171 L_INT	inkdot(incr)
172 {
173 	L_INT		newdot;
174 
175 	newdot=dot+incr;
176 	return(newdot);
177 }
178 
179 printc(c)
180 char c; {
181 	printf("%c", c);
182 }
183 
184 psymoff(v, r, fmt)
185 L_INT v; char fmt, **r; {
186 	struct proct *procp;
187 	register int diff;
188 	if (fmt == 'i') {
189 		if (r == regname + 12) {   /* parameter */
190 			if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot)))
191 					!= -1) {
192 				printf("%s", sl_name);
193 				prdiff(diff);
194 				return(0);
195 			}
196 		}
197 		if (r == regname + 13) {   /* local */
198 			if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot))
199 					) != -1) {
200 				printf("%s", sl_name);
201 				prdiff(diff);
202 				return(0);
203 			}
204 		}
205 		if (v < firstdata) {
206 			if ((procp = adrtoprocp((ADDR) v)) != badproc) {
207 				prlnoff(procp, v);
208 				return(0);
209 			}
210 		} else {
211 			if ((diff = adrtoext((ADDR) v)) != -1) {
212 				printf("%s", sl_name);
213 				prdiff(diff);
214 				return(0);
215 			}
216 		}
217 	}
218 	prhex(v);
219 	return(1);
220 }
221 
222 
223 prdiff(diff) {
224 	if (diff) {
225 		printf("+");
226 		prhex(diff);
227 	}
228 }
229