xref: /original-bsd/old/adb/adb.tahoe/opset.c (revision b079d642)
1 #ifndef lint
2 static char sccsid[] = "@(#)opset.c	1.4 (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 	if (space == SP_NONE)
52 		ins = (u_char)dot;
53 	else {
54 		(void) adbread(space, dot, &ins, 1);
55 		checkerr();
56 	}
57 	if ((ip = ioptab[ins]) == NULL) {
58 		adbprintf("?%2x", ins);
59 		dotinc = 1;
60 		return;
61 	}
62 	adbprintf("%s%8t", ip->iname);
63 	dotoff = 1;
64 	ap = ip->argtype;
65 	for (argno = 0; argno < ip->nargs; argno++, ap++) {
66 		var[argno] = 0x80000000;
67 		if (argno != 0)
68 			printc(',');
69 again:
70 		if (*ap & ACCB)		/* branch displacement */
71 			mode = 0xAF + ((*ap & 7) << 5);
72 		else {
73 			snarfbytes(1);
74 			mode = mem.ub;
75 		}
76 		r = mode & 0xF;
77 		mode >>= 4;
78 		switch (mode) {
79 
80 		case 0: case 1: case 2: case 3:
81 			/* short literal */
82 			d = mode << 4 | r;
83 			goto immed;
84 
85 		case 4:	/* [r] */
86 			adbprintf("[%s]", regname[r]);
87 			goto again;
88 
89 		case 5:	/* r */
90 			adbprintf("%s", regname[r]);
91 			continue;
92 
93 		case 6:	/* (r) */
94 			adbprintf("(%s)", regname[r]);
95 			continue;
96 
97 		case 7:	/* -(r) */
98 			adbprintf("-(%s)", regname[r]);
99 			continue;
100 
101 		case 9:	/* *(r)+ */
102 			printc('*');
103 			/* FALLTHROUGH */
104 
105 		case 8:	/* (r)+ */
106 			if (r == 0xf) {
107 				/* PC immediate */
108 				snarfbytes(4);
109 				d = mem.l;
110 			} else if (mode == 8 && (r == 8 || r == 9)) {
111 				/* absolute */
112 				snarfbytes((r & 1) + 1);
113 				d = r == 8 ? mem.b : mem.w;
114 			} else {
115 				adbprintf("(%s)+", regname[r]);
116 				continue;
117 			}
118 	immed:
119 			printc('$');
120 			if (ins == KCALL && (u_int)d < nsys && syscalls[d])
121 				prints(syscalls[d]);
122 			else
123 				adbprintf("%R", d);
124 			var[argno] = d;
125 			continue;
126 
127 		case 0xA:	/* byte displacement */
128 		case 0xB:	/* byte displacement deferred */
129 			d = 1;
130 			break;
131 
132 		case 0xC:	/* word displacement */
133 		case 0xD:	/* word displacement deferred */
134 			d = 2;
135 			break;
136 
137 		case 0xE:	/* long displacement */
138 		case 0xF:	/* long displacement deferred */
139 			d = 4;
140 			break;
141 		}
142 
143 		/* displacement or displacement deferred */
144 		if (mode & 1)
145 			printc('*');
146 		snarfbytes(d);
147 		switch (d) {
148 		case 1:
149 			d = mem.b;
150 			break;
151 		case 2:
152 			d = mem.w;
153 			break;
154 		case 4:
155 			d = mem.l;
156 			break;
157 		}
158 		if (r == 0xF) {	/* PC offset addressing */
159 			d += dot + dotoff;
160 			psymoff("%R", (addr_t)d, SP_DATA, maxoff, "");
161 		} else
162 			adbprintf("%V(%s)", d, regname[r]);
163 		var[argno] = d;
164 	}
165 	if (ins == CASEL) {
166 		register addr_t adjdot;
167 
168 		if (inkdot(dotoff) & 01)	/* align */
169 			dotoff++;
170 		adjdot = inkdot(dotoff);
171 		for (argno = 0; argno <= var[2]; ++argno) {
172 			adbprintf("\n    %R:  ", argno + var[1]);
173 			snarfbytes(2);
174 			psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, "");
175 		}
176 	}
177 	dotinc = dotoff;
178 }
179