xref: /csrg-svn/old/adb/adb.vax/opset.c (revision 3760)
1 #
2 /*
3  *
4  *	UNIX debugger
5  *
6  */
7 
8 #include "defs.h"
9 static	char sccsid[] = "@(#)opset.c 4.1 05/14/81";
10 
11 STRING		errflg;
12 L_INT		dot;
13 INT		dotinc;
14 L_INT		var[];
15 
16 
17 /* instruction printing */
18 
19 /*
20  * Argument access types
21  */
22 #define ACCA	(8<<3)	/* address only */
23 #define ACCR	(1<<3)	/* read */
24 #define ACCW	(2<<3)	/* write */
25 #define ACCM	(3<<3)	/* modify */
26 #define ACCB	(4<<3)	/* branch displacement */
27 #define ACCI	(5<<3)	/* XFC code */
28 
29 /*
30  * Argument data types
31  */
32 #define TYPB	0	/* byte */
33 #define TYPW	1	/* word */
34 #define TYPL	2	/* long */
35 #define TYPQ	3	/* quad */
36 #define TYPF	4	/* floating */
37 #define TYPD	5	/* double floating */
38 
39 
40 TYPE	struct optab	*OPTAB;
41 struct optab {
42 	char *iname;
43 	char val;
44 	char nargs;
45 	char argtype[6];
46 } optab[];
47 #define SYSTAB struct systab
48 SYSTAB {
49 	int	argc;
50 	char	*sname;
51 } systab[];
52 STRING	regname[];
53 STRING	fltimm[];
54 POS	type, space, incp;
55 
56 int ioptab[256]; /* index by opcode to optab */
57 
58 mkioptab() {/* set up ioptab */
59 	REG OPTAB p=optab;
60 	while (p->iname){
61 		ioptab[p->val&LOBYTE]=p-optab;
62 		p++;
63 	}
64 }
65 
66 extern char *fmtr;	/* not used */
67 extern char *fmtR;	/* not used */
68 
69 printins(f,idsp,ins)
70 #ifndef vax
71 	REG INT		ins;
72 #else
73 	REG L_INT	ins;
74 #endif
75 {
76 	short	argno;		/* argument index */
77 	short	mode;		/* mode */
78 	char	**r;		/* register name */
79 	long	d;		/* assembled byte, word, long or float */
80 	long	snarf();
81 	REG char *	ap;
82 	REG OPTAB	ip;
83 
84 	type = DSYM;
85 	space = idsp;
86 	ins &= LOBYTE;
87 	ip=optab+ioptab[ins];
88 	printf("%s%8t",ip->iname);
89 	incp = 1;
90 	ap = ip->argtype;
91 	for (argno=0; argno<ip->nargs; argno++,ap++) {
92 		var[argno] = 0x80000000;
93 		if (argno!=0) printc(',');
94 	  top:
95 		if (*ap&ACCB)
96 			mode = 0xAF + ((*ap&7)<<5);  /* branch displacement */
97 		else{
98 			mode = bchkget(inkdot(incp),idsp); ++incp;
99 		}
100 		if (mode & 0300) {/* not short literal */
101 			r = &regname[mode&0xF];
102 			mode >>= 4;
103 			switch ((int)mode) {
104 				case 4: /* [r] */
105 					printf("[%s]",*r);
106 					goto top;
107 				case 5: /* r */
108 					printf("%s",*r);
109 					break;
110 				case 6: /* (r) */
111 					printf("(%s)",*r);
112 					break;
113 				case 7: /* -(r) */
114 					printf("-(%s)",*r);
115 					break;
116 				case 9: /* *(r)+ */
117 					printc('*');
118 				case 8: /* (r)+ */
119 				  if (r==(regname+0xF)) {
120 					printc('$');
121 					if (mode==9){	/* PC absolute, always 4 bytes*/
122 						d = snarf(4, idsp);
123 						goto disp;
124 					}
125 					switch(*ap&7){
126 					 case TYPB:
127 						d = snarf(1, idsp);
128 						goto disp;
129 					 case TYPW:
130 						d = snarf(2, idsp);
131 						goto disp;
132 					 case TYPL:
133 						d = snarf(4, idsp);
134 						goto disp;
135 					 case TYPQ:
136 						d = snarf(4, idsp);
137 						printquad(d, snarf(4, idsp));
138 						break;
139 					 case TYPF:
140 						printfloating(TYPF, snarf(4, idsp), 0);
141 						break;
142 					 case TYPD:
143 						d = snarf(4, idsp);
144 						printfloating(TYPQ, d, snarf(4, idsp));
145 						break;
146 					} /*end of type switch */
147 					/*
148 					 *	here only for TYPQ, TYPf, TYPD
149 					 *	others went to disp
150 					 */
151 				  } else {	/*it's not PC immediate or abs*/
152 					  printf("(%s)+",*r);
153 				  }
154 				  break;
155 				case 0xB:	/* byte displacement defferred*/
156 					printc('*');
157 				case 0xA:	/* byte displacement */
158 					d = snarf(1, idsp);
159 					goto disp;
160 				case 0xD:	/* word displacement deferred */
161 					printc('*');
162 				case 0xC:	/* word displacement */
163 					d = snarf(2, idsp);
164 					goto disp;
165 				case 0xF:	/* long displacement deferred */
166 					printc('*');
167 				case 0xE:	/* long displacement */
168 					d = snarf(4, idsp);
169 					goto disp;
170 			disp:
171 					var[argno]=d;
172 					if (r==(regname+0xF) && mode>=0xA){
173 						/* PC offset addressing */
174 						var[argno] += dot+incp;
175 					}
176 					psymoff(var[argno],type,"");
177 					if (r != regname+0xF)
178 						printf("(%s)",*r);
179 					break;
180 			} /* end of the mode switch */
181 		} else {   /* short literal */
182 			var[argno]=mode;
183 			if(   (*ap&7)==TYPF
184 			   || (*ap&7)==TYPD)
185 				printf("$%s",fltimm[mode]);
186 			else
187 				printf("$%r",mode);
188 		}
189 	}
190 	if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */
191 		for (argno=0; argno<=var[2]; ++argno) {
192 			printc(EOR);
193 			printf("    %R:  ",argno+var[1]);
194 			d=get(inkdot(incp+argno+argno),idsp)&0xFFFF;
195 			if (d&0x8000) d -= 0x10000;
196 			psymoff(inkdot(incp)+d,type,"");
197 		}
198 		incp += var[2]+var[2]+2;
199 	}
200 	dotinc=incp;
201 }
202 
203 /*
204  *	magic values to mung an offset to a register into
205  *	something that psymoff can understand.. all magic
206  */
207 			      /* 0	1	2	3	4 */
208 static long magic_masks[5] =	{0,	0x80,	0x8000,	0,	0};
209 static long magic_compl[5] =	{0,	0x100,	0x10000,0,	0};
210 
211 /*
212  *	The following code is NO LONGER portable from the PDP 11 to the VAX
213  */
214 long snarf (nbytes, idsp)
215 			int	nbytes;
216 {
217 	register	int	byteindex;
218 	union Long{
219 		char	long_bytes[4];
220 		long	long_value;
221 	} d;
222 
223 	d.long_value = 0;
224 	for (byteindex = 0; byteindex < nbytes; byteindex++){
225 		d.long_bytes[byteindex] = bchkget(inkdot(incp), idsp);
226 		++incp;
227 	}
228 	if (d.long_value & magic_masks[nbytes])
229 		d.long_value -= magic_compl[nbytes];
230 	return(d.long_value);
231 }
232 
233 printfloating(type, word_first, word_last)
234 	int	type;
235 	long	word_first;
236 	long	word_last;
237 {
238 	union	Double{
239 		struct {
240 			long	word_first;
241 			long	word_last;
242 		} composite;
243 		double	dvalue;
244 	} reconstructed;
245 
246 	reconstructed.composite.word_first = word_first;
247 	reconstructed.composite.word_last = word_last;
248 	printf( "%f", reconstructed.dvalue);
249 }
250 
251 printquad(word_first, word_last)
252 	long	word_first;
253 	long	word_last;
254 {
255 	union Quad {
256 		char	quad_bytes[8];
257 		long	quad_long[2];
258 	} reconstructed;
259 	int	leading_zero = 1;
260 	int	byteindex;
261 	int	nibbleindex;
262 	register	int	ch;
263 
264 	reconstructed.quad_long[0] = word_first;
265 	reconstructed.quad_long[1] = word_last;
266 	for (byteindex = 7; byteindex >= 0; --byteindex){
267 		for (nibbleindex = 4; nibbleindex >= 0; nibbleindex -= 4){
268 			ch = (reconstructed.quad_bytes[byteindex]
269 				>> nibbleindex) & 0x0F;
270 			if ( ! (leading_zero &= (ch == 0) ) ){
271 				if (ch <= 0x09)
272 					printc(ch + '0');
273 				else
274 					printc(ch - 0x0A + 'a');
275 			}
276 		}
277 	}
278 }
279