xref: /csrg-svn/old/adb/adb.tahoe/opset.c (revision 41100)
1 #ifndef lint
2 static char sccsid[] = "@(#)opset.c	1.3 (Berkeley) 04/27/90";
3 #endif
4 
5 /*
6  * adb - instruction decoding
7  */
8 
9 #include "defs.h"
10 #include "optab.h"
11 
12 struct	optab *ioptab[256];	/* index by opcode to optab */
13 
14 /* set up ioptab */
15 mkioptab()
16 {
17 	register struct optab *p;
18 
19 	for (p = optab; p->iname; p++)
20 		ioptab[p->val] = p;
21 }
22 
23 /*
24  * Print one instruction, and leave dotinc set to the number of bytes
25  * it occupied.
26  */
27 printins(space)
28 	int space;
29 {
30 	u_char ins;		/* instruction opcode */
31 	int argno;		/* argument index */
32 	register int mode;	/* mode */
33 	register int r;		/* register name */
34 	register int d;		/* assembled byte, word, long or float */
35 	register int dotoff;	/* offset from dot of current byte */
36 	register u_char *ap;
37 	register struct optab *ip;
38 	union {
39 		u_char	ub;
40 		char	b;
41 		short	w;
42 		int	l;
43 	} mem;
44 	extern char *syscalls[];
45 	extern int nsys;
46 #define	snarfbytes(nbytes) \
47 	(void) adbread(space, inkdot(dotoff), &mem.b, nbytes); \
48 	checkerr(); \
49 	dotoff += (nbytes)
50 
51 	(void) adbread(space, dot, &ins, 1);
52 	checkerr();
53 	if ((ip = ioptab[ins]) == NULL) {
54 		adbprintf("?%2x", ins);
55 		dotinc = 1;
56 		return;
57 	}
58 	adbprintf("%s%8t", ip->iname);
59 	dotoff = 1;
60 	ap = ip->argtype;
61 	for (argno = 0; argno < ip->nargs; argno++, ap++) {
62 		var[argno] = 0x80000000;
63 		if (argno != 0)
64 			printc(',');
65 again:
66 		if (*ap & ACCB)		/* branch displacement */
67 			mode = 0xAF + ((*ap & 7) << 5);
68 		else {
69 			snarfbytes(1);
70 			mode = mem.ub;
71 		}
72 		r = mode & 0xF;
73 		mode >>= 4;
74 		switch (mode) {
75 
76 		case 0: case 1: case 2: case 3:
77 			/* short literal */
78 			d = mode << 4 | r;
79 			goto immed;
80 
81 		case 4:	/* [r] */
82 			adbprintf("[%s]", regname[r]);
83 			goto again;
84 
85 		case 5:	/* r */
86 			adbprintf("%s", regname[r]);
87 			continue;
88 
89 		case 6:	/* (r) */
90 			adbprintf("(%s)", regname[r]);
91 			continue;
92 
93 		case 7:	/* -(r) */
94 			adbprintf("-(%s)", regname[r]);
95 			continue;
96 
97 		case 9:	/* *(r)+ */
98 			printc('*');
99 			/* FALLTHROUGH */
100 
101 		case 8:	/* (r)+ */
102 			if (r == 0xf) {
103 				/* PC immediate */
104 				snarfbytes(4);
105 				d = mem.l;
106 			} else if (mode == 8 && (r == 8 || r == 9)) {
107 				/* absolute */
108 				snarfbytes((r & 1) + 1);
109 				d = r == 8 ? mem.b : mem.w;
110 			} else {
111 				adbprintf("(%s)+", regname[r]);
112 				continue;
113 			}
114 	immed:
115 			printc('$');
116 			if (ins == KCALL && (u_int)d < nsys && syscalls[d])
117 				prints(syscalls[d]);
118 			else
119 				adbprintf("%R", d);
120 			var[argno] = d;
121 			continue;
122 
123 		case 0xA:	/* byte displacement */
124 		case 0xB:	/* byte displacement deferred */
125 			d = 1;
126 			break;
127 
128 		case 0xC:	/* word displacement */
129 		case 0xD:	/* word displacement deferred */
130 			d = 2;
131 			break;
132 
133 		case 0xE:	/* long displacement */
134 		case 0xF:	/* long displacement deferred */
135 			d = 4;
136 			break;
137 		}
138 
139 		/* displacement or displacement deferred */
140 		if (mode & 1)
141 			printc('*');
142 		snarfbytes(d);
143 		switch (d) {
144 		case 1:
145 			d = mem.b;
146 			break;
147 		case 2:
148 			d = mem.w;
149 			break;
150 		case 4:
151 			d = mem.l;
152 			break;
153 		}
154 		if (r == 0xF) {	/* PC offset addressing */
155 			d += dot + dotoff;
156 			psymoff("%R", (addr_t)d, SP_DATA, maxoff, "");
157 		} else
158 			adbprintf("%V(%s)", d, regname[r]);
159 		var[argno] = d;
160 	}
161 	if (ins == CASEL) {
162 		register addr_t adjdot;
163 
164 		if (inkdot(dotoff) & 01)	/* align */
165 			dotoff++;
166 		adjdot = inkdot(dotoff);
167 		for (argno = 0; argno <= var[2]; ++argno) {
168 			adbprintf("\n    %R:  ", argno + var[1]);
169 			snarfbytes(2);
170 			psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, "");
171 		}
172 	}
173 	dotinc = dotoff;
174 }
175