xref: /csrg-svn/old/adb/adb.tahoe/opset.c (revision 47819)
1*47819Sbostic /*-
2*47819Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*47819Sbostic  * All rights reserved.
4*47819Sbostic  *
5*47819Sbostic  * %sccs.include.proprietary.c%
6*47819Sbostic  */
7*47819Sbostic 
826420Ssam #ifndef lint
9*47819Sbostic static char sccsid[] = "@(#)opset.c	5.1 (Berkeley) 04/04/91";
10*47819Sbostic #endif /* not lint */
1136561Sbostic 
1226420Ssam /*
1336561Sbostic  * adb - instruction decoding
1426420Ssam  */
1526420Ssam 
1626420Ssam #include "defs.h"
1726420Ssam #include "optab.h"
1826420Ssam 
1936561Sbostic struct	optab *ioptab[256];	/* index by opcode to optab */
2026420Ssam 
2136561Sbostic /* set up ioptab */
mkioptab()2236561Sbostic mkioptab()
2336561Sbostic {
2436561Sbostic 	register struct optab *p;
2526420Ssam 
2636561Sbostic 	for (p = optab; p->iname; p++)
2736561Sbostic 		ioptab[p->val] = p;
2826420Ssam }
2926420Ssam 
3036561Sbostic /*
3136561Sbostic  * Print one instruction, and leave dotinc set to the number of bytes
3236561Sbostic  * it occupied.
3336561Sbostic  */
printins(space)3436561Sbostic printins(space)
3536561Sbostic 	int space;
3626420Ssam {
3736561Sbostic 	u_char ins;		/* instruction opcode */
3836561Sbostic 	int argno;		/* argument index */
3936561Sbostic 	register int mode;	/* mode */
4036561Sbostic 	register int r;		/* register name */
4136561Sbostic 	register int d;		/* assembled byte, word, long or float */
4236561Sbostic 	register int dotoff;	/* offset from dot of current byte */
4336561Sbostic 	register u_char *ap;
4436561Sbostic 	register struct optab *ip;
4536561Sbostic 	union {
4636561Sbostic 		u_char	ub;
4736561Sbostic 		char	b;
4836561Sbostic 		short	w;
4936561Sbostic 		int	l;
5036561Sbostic 	} mem;
5136561Sbostic 	extern char *syscalls[];
5236561Sbostic 	extern int nsys;
5336561Sbostic #define	snarfbytes(nbytes) \
5436561Sbostic 	(void) adbread(space, inkdot(dotoff), &mem.b, nbytes); \
5536561Sbostic 	checkerr(); \
5636561Sbostic 	dotoff += (nbytes)
5726420Ssam 
5841101Storek 	if (space == SP_NONE)
5941101Storek 		ins = (u_char)dot;
6041101Storek 	else {
6141101Storek 		(void) adbread(space, dot, &ins, 1);
6241101Storek 		checkerr();
6341101Storek 	}
6436561Sbostic 	if ((ip = ioptab[ins]) == NULL) {
6536561Sbostic 		adbprintf("?%2x", ins);
6626420Ssam 		dotinc = 1;
6726420Ssam 		return;
6826420Ssam 	}
6936561Sbostic 	adbprintf("%s%8t", ip->iname);
7036561Sbostic 	dotoff = 1;
7126420Ssam 	ap = ip->argtype;
7236561Sbostic 	for (argno = 0; argno < ip->nargs; argno++, ap++) {
7326420Ssam 		var[argno] = 0x80000000;
7436561Sbostic 		if (argno != 0)
7536561Sbostic 			printc(',');
7636561Sbostic again:
7736561Sbostic 		if (*ap & ACCB)		/* branch displacement */
7836561Sbostic 			mode = 0xAF + ((*ap & 7) << 5);
7936561Sbostic 		else {
8036561Sbostic 			snarfbytes(1);
8136561Sbostic 			mode = mem.ub;
8226420Ssam 		}
8336561Sbostic 		r = mode & 0xF;
8426420Ssam 		mode >>= 4;
8536561Sbostic 		switch (mode) {
8636561Sbostic 
8736561Sbostic 		case 0: case 1: case 2: case 3:
8836561Sbostic 			/* short literal */
8936561Sbostic 			d = mode << 4 | r;
9036561Sbostic 			goto immed;
9136561Sbostic 
9236561Sbostic 		case 4:	/* [r] */
9336561Sbostic 			adbprintf("[%s]", regname[r]);
9436561Sbostic 			goto again;
9536561Sbostic 
9636561Sbostic 		case 5:	/* r */
9736561Sbostic 			adbprintf("%s", regname[r]);
9836561Sbostic 			continue;
9936561Sbostic 
10036561Sbostic 		case 6:	/* (r) */
10136561Sbostic 			adbprintf("(%s)", regname[r]);
10236561Sbostic 			continue;
10336561Sbostic 
10436561Sbostic 		case 7:	/* -(r) */
10536561Sbostic 			adbprintf("-(%s)", regname[r]);
10636561Sbostic 			continue;
10736561Sbostic 
10836561Sbostic 		case 9:	/* *(r)+ */
10936561Sbostic 			printc('*');
11036561Sbostic 			/* FALLTHROUGH */
11136561Sbostic 
11236561Sbostic 		case 8:	/* (r)+ */
11336561Sbostic 			if (r == 0xf) {
11436561Sbostic 				/* PC immediate */
11536561Sbostic 				snarfbytes(4);
11636561Sbostic 				d = mem.l;
11736561Sbostic 			} else if (mode == 8 && (r == 8 || r == 9)) {
11836561Sbostic 				/* absolute */
11936561Sbostic 				snarfbytes((r & 1) + 1);
12036561Sbostic 				d = r == 8 ? mem.b : mem.w;
12136561Sbostic 			} else {
12236561Sbostic 				adbprintf("(%s)+", regname[r]);
12336561Sbostic 				continue;
12436561Sbostic 			}
12536561Sbostic 	immed:
12636561Sbostic 			printc('$');
12736561Sbostic 			if (ins == KCALL && (u_int)d < nsys && syscalls[d])
12836561Sbostic 				prints(syscalls[d]);
12936561Sbostic 			else
13036561Sbostic 				adbprintf("%R", d);
13136561Sbostic 			var[argno] = d;
13236561Sbostic 			continue;
13336561Sbostic 
13436561Sbostic 		case 0xA:	/* byte displacement */
13536561Sbostic 		case 0xB:	/* byte displacement deferred */
13636561Sbostic 			d = 1;
13736561Sbostic 			break;
13836561Sbostic 
13936561Sbostic 		case 0xC:	/* word displacement */
14036561Sbostic 		case 0xD:	/* word displacement deferred */
14136561Sbostic 			d = 2;
14236561Sbostic 			break;
14336561Sbostic 
14436561Sbostic 		case 0xE:	/* long displacement */
14536561Sbostic 		case 0xF:	/* long displacement deferred */
14636561Sbostic 			d = 4;
14736561Sbostic 			break;
14836561Sbostic 		}
14936561Sbostic 
15036561Sbostic 		/* displacement or displacement deferred */
15136561Sbostic 		if (mode & 1)
15236561Sbostic 			printc('*');
15336561Sbostic 		snarfbytes(d);
15436561Sbostic 		switch (d) {
15536561Sbostic 		case 1:
15636561Sbostic 			d = mem.b;
15736561Sbostic 			break;
15836561Sbostic 		case 2:
15936561Sbostic 			d = mem.w;
16036561Sbostic 			break;
16136561Sbostic 		case 4:
16236561Sbostic 			d = mem.l;
16336561Sbostic 			break;
16436561Sbostic 		}
16536561Sbostic 		if (r == 0xF) {	/* PC offset addressing */
16636561Sbostic 			d += dot + dotoff;
16736561Sbostic 			psymoff("%R", (addr_t)d, SP_DATA, maxoff, "");
16836561Sbostic 		} else
16936561Sbostic 			adbprintf("%V(%s)", d, regname[r]);
17036561Sbostic 		var[argno] = d;
17126420Ssam 	}
17236561Sbostic 	if (ins == CASEL) {
17336561Sbostic 		register addr_t adjdot;
17436561Sbostic 
17536561Sbostic 		if (inkdot(dotoff) & 01)	/* align */
17636561Sbostic 			dotoff++;
17736561Sbostic 		adjdot = inkdot(dotoff);
17836561Sbostic 		for (argno = 0; argno <= var[2]; ++argno) {
17936561Sbostic 			adbprintf("\n    %R:  ", argno + var[1]);
18036561Sbostic 			snarfbytes(2);
18136561Sbostic 			psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, "");
18226420Ssam 		}
18326420Ssam 	}
18436561Sbostic 	dotinc = dotoff;
18526420Ssam }
186