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