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