xref: /csrg-svn/old/adb/adb.tahoe/opset.c (revision 41101)
126420Ssam #ifndef lint
2*41101Storek static char sccsid[] = "@(#)opset.c	1.4 (Berkeley) 04/27/90";
326420Ssam #endif
436561Sbostic 
526420Ssam /*
636561Sbostic  * adb - instruction decoding
726420Ssam  */
826420Ssam 
926420Ssam #include "defs.h"
1026420Ssam #include "optab.h"
1126420Ssam 
1236561Sbostic struct	optab *ioptab[256];	/* index by opcode to optab */
1326420Ssam 
1436561Sbostic /* set up ioptab */
1536561Sbostic mkioptab()
1636561Sbostic {
1736561Sbostic 	register struct optab *p;
1826420Ssam 
1936561Sbostic 	for (p = optab; p->iname; p++)
2036561Sbostic 		ioptab[p->val] = p;
2126420Ssam }
2226420Ssam 
2336561Sbostic /*
2436561Sbostic  * Print one instruction, and leave dotinc set to the number of bytes
2536561Sbostic  * it occupied.
2636561Sbostic  */
2736561Sbostic printins(space)
2836561Sbostic 	int space;
2926420Ssam {
3036561Sbostic 	u_char ins;		/* instruction opcode */
3136561Sbostic 	int argno;		/* argument index */
3236561Sbostic 	register int mode;	/* mode */
3336561Sbostic 	register int r;		/* register name */
3436561Sbostic 	register int d;		/* assembled byte, word, long or float */
3536561Sbostic 	register int dotoff;	/* offset from dot of current byte */
3636561Sbostic 	register u_char *ap;
3736561Sbostic 	register struct optab *ip;
3836561Sbostic 	union {
3936561Sbostic 		u_char	ub;
4036561Sbostic 		char	b;
4136561Sbostic 		short	w;
4236561Sbostic 		int	l;
4336561Sbostic 	} mem;
4436561Sbostic 	extern char *syscalls[];
4536561Sbostic 	extern int nsys;
4636561Sbostic #define	snarfbytes(nbytes) \
4736561Sbostic 	(void) adbread(space, inkdot(dotoff), &mem.b, nbytes); \
4836561Sbostic 	checkerr(); \
4936561Sbostic 	dotoff += (nbytes)
5026420Ssam 
51*41101Storek 	if (space == SP_NONE)
52*41101Storek 		ins = (u_char)dot;
53*41101Storek 	else {
54*41101Storek 		(void) adbread(space, dot, &ins, 1);
55*41101Storek 		checkerr();
56*41101Storek 	}
5736561Sbostic 	if ((ip = ioptab[ins]) == NULL) {
5836561Sbostic 		adbprintf("?%2x", ins);
5926420Ssam 		dotinc = 1;
6026420Ssam 		return;
6126420Ssam 	}
6236561Sbostic 	adbprintf("%s%8t", ip->iname);
6336561Sbostic 	dotoff = 1;
6426420Ssam 	ap = ip->argtype;
6536561Sbostic 	for (argno = 0; argno < ip->nargs; argno++, ap++) {
6626420Ssam 		var[argno] = 0x80000000;
6736561Sbostic 		if (argno != 0)
6836561Sbostic 			printc(',');
6936561Sbostic again:
7036561Sbostic 		if (*ap & ACCB)		/* branch displacement */
7136561Sbostic 			mode = 0xAF + ((*ap & 7) << 5);
7236561Sbostic 		else {
7336561Sbostic 			snarfbytes(1);
7436561Sbostic 			mode = mem.ub;
7526420Ssam 		}
7636561Sbostic 		r = mode & 0xF;
7726420Ssam 		mode >>= 4;
7836561Sbostic 		switch (mode) {
7936561Sbostic 
8036561Sbostic 		case 0: case 1: case 2: case 3:
8136561Sbostic 			/* short literal */
8236561Sbostic 			d = mode << 4 | r;
8336561Sbostic 			goto immed;
8436561Sbostic 
8536561Sbostic 		case 4:	/* [r] */
8636561Sbostic 			adbprintf("[%s]", regname[r]);
8736561Sbostic 			goto again;
8836561Sbostic 
8936561Sbostic 		case 5:	/* r */
9036561Sbostic 			adbprintf("%s", regname[r]);
9136561Sbostic 			continue;
9236561Sbostic 
9336561Sbostic 		case 6:	/* (r) */
9436561Sbostic 			adbprintf("(%s)", regname[r]);
9536561Sbostic 			continue;
9636561Sbostic 
9736561Sbostic 		case 7:	/* -(r) */
9836561Sbostic 			adbprintf("-(%s)", regname[r]);
9936561Sbostic 			continue;
10036561Sbostic 
10136561Sbostic 		case 9:	/* *(r)+ */
10236561Sbostic 			printc('*');
10336561Sbostic 			/* FALLTHROUGH */
10436561Sbostic 
10536561Sbostic 		case 8:	/* (r)+ */
10636561Sbostic 			if (r == 0xf) {
10736561Sbostic 				/* PC immediate */
10836561Sbostic 				snarfbytes(4);
10936561Sbostic 				d = mem.l;
11036561Sbostic 			} else if (mode == 8 && (r == 8 || r == 9)) {
11136561Sbostic 				/* absolute */
11236561Sbostic 				snarfbytes((r & 1) + 1);
11336561Sbostic 				d = r == 8 ? mem.b : mem.w;
11436561Sbostic 			} else {
11536561Sbostic 				adbprintf("(%s)+", regname[r]);
11636561Sbostic 				continue;
11736561Sbostic 			}
11836561Sbostic 	immed:
11936561Sbostic 			printc('$');
12036561Sbostic 			if (ins == KCALL && (u_int)d < nsys && syscalls[d])
12136561Sbostic 				prints(syscalls[d]);
12236561Sbostic 			else
12336561Sbostic 				adbprintf("%R", d);
12436561Sbostic 			var[argno] = d;
12536561Sbostic 			continue;
12636561Sbostic 
12736561Sbostic 		case 0xA:	/* byte displacement */
12836561Sbostic 		case 0xB:	/* byte displacement deferred */
12936561Sbostic 			d = 1;
13036561Sbostic 			break;
13136561Sbostic 
13236561Sbostic 		case 0xC:	/* word displacement */
13336561Sbostic 		case 0xD:	/* word displacement deferred */
13436561Sbostic 			d = 2;
13536561Sbostic 			break;
13636561Sbostic 
13736561Sbostic 		case 0xE:	/* long displacement */
13836561Sbostic 		case 0xF:	/* long displacement deferred */
13936561Sbostic 			d = 4;
14036561Sbostic 			break;
14136561Sbostic 		}
14236561Sbostic 
14336561Sbostic 		/* displacement or displacement deferred */
14436561Sbostic 		if (mode & 1)
14536561Sbostic 			printc('*');
14636561Sbostic 		snarfbytes(d);
14736561Sbostic 		switch (d) {
14836561Sbostic 		case 1:
14936561Sbostic 			d = mem.b;
15036561Sbostic 			break;
15136561Sbostic 		case 2:
15236561Sbostic 			d = mem.w;
15336561Sbostic 			break;
15436561Sbostic 		case 4:
15536561Sbostic 			d = mem.l;
15636561Sbostic 			break;
15736561Sbostic 		}
15836561Sbostic 		if (r == 0xF) {	/* PC offset addressing */
15936561Sbostic 			d += dot + dotoff;
16036561Sbostic 			psymoff("%R", (addr_t)d, SP_DATA, maxoff, "");
16136561Sbostic 		} else
16236561Sbostic 			adbprintf("%V(%s)", d, regname[r]);
16336561Sbostic 		var[argno] = d;
16426420Ssam 	}
16536561Sbostic 	if (ins == CASEL) {
16636561Sbostic 		register addr_t adjdot;
16736561Sbostic 
16836561Sbostic 		if (inkdot(dotoff) & 01)	/* align */
16936561Sbostic 			dotoff++;
17036561Sbostic 		adjdot = inkdot(dotoff);
17136561Sbostic 		for (argno = 0; argno <= var[2]; ++argno) {
17236561Sbostic 			adbprintf("\n    %R:  ", argno + var[1]);
17336561Sbostic 			snarfbytes(2);
17436561Sbostic 			psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, "");
17526420Ssam 		}
17626420Ssam 	}
17736561Sbostic 	dotinc = dotoff;
17826420Ssam }
179