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