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