1 #ifndef lint 2 static char sccsid[] = "@(#)opset.c 1.2 (Berkeley) 01/16/89"; 3 #endif 4 5 /* 6 * adb - instruction decoding 7 */ 8 9 #include "defs.h" 10 #include "optab.h" 11 12 struct optab *ioptab[256]; /* index by opcode to optab */ 13 14 /* set up ioptab */ 15 mkioptab() 16 { 17 register struct optab *p; 18 19 for (p = optab; p->iname; p++) 20 ioptab[p->val] = p; 21 } 22 23 /* 24 * Print one instruction, and leave dotinc set to the number of bytes 25 * it occupied. 26 */ 27 printins(space) 28 int space; 29 { 30 u_char ins; /* instruction opcode */ 31 int argno; /* argument index */ 32 register int mode; /* mode */ 33 register int r; /* register name */ 34 register int d; /* assembled byte, word, long or float */ 35 register int dotoff; /* offset from dot of current byte */ 36 register u_char *ap; 37 register struct optab *ip; 38 union { 39 u_char ub; 40 char b; 41 short w; 42 int l; 43 } mem; 44 extern char *syscalls[]; 45 extern int nsys; 46 #define snarfbytes(nbytes) \ 47 (void) adbread(space, inkdot(dotoff), &mem.b, nbytes); \ 48 checkerr(); \ 49 dotoff += (nbytes) 50 51 (void) adbread(SP_INSTR, dot, &ins, 1); 52 checkerr(); 53 if ((ip = ioptab[ins]) == NULL) { 54 adbprintf("?%2x", ins); 55 dotinc = 1; 56 return; 57 } 58 adbprintf("%s%8t", ip->iname); 59 dotoff = 1; 60 ap = ip->argtype; 61 for (argno = 0; argno < ip->nargs; argno++, ap++) { 62 var[argno] = 0x80000000; 63 if (argno != 0) 64 printc(','); 65 again: 66 if (*ap & ACCB) /* branch displacement */ 67 mode = 0xAF + ((*ap & 7) << 5); 68 else { 69 snarfbytes(1); 70 mode = mem.ub; 71 } 72 r = mode & 0xF; 73 mode >>= 4; 74 switch (mode) { 75 76 case 0: case 1: case 2: case 3: 77 /* short literal */ 78 d = mode << 4 | r; 79 goto immed; 80 81 case 4: /* [r] */ 82 adbprintf("[%s]", regname[r]); 83 goto again; 84 85 case 5: /* r */ 86 adbprintf("%s", regname[r]); 87 continue; 88 89 case 6: /* (r) */ 90 adbprintf("(%s)", regname[r]); 91 continue; 92 93 case 7: /* -(r) */ 94 adbprintf("-(%s)", regname[r]); 95 continue; 96 97 case 9: /* *(r)+ */ 98 printc('*'); 99 /* FALLTHROUGH */ 100 101 case 8: /* (r)+ */ 102 if (r == 0xf) { 103 /* PC immediate */ 104 snarfbytes(4); 105 d = mem.l; 106 } else if (mode == 8 && (r == 8 || r == 9)) { 107 /* absolute */ 108 snarfbytes((r & 1) + 1); 109 d = r == 8 ? mem.b : mem.w; 110 } else { 111 adbprintf("(%s)+", regname[r]); 112 continue; 113 } 114 immed: 115 printc('$'); 116 if (ins == KCALL && (u_int)d < nsys && syscalls[d]) 117 prints(syscalls[d]); 118 else 119 adbprintf("%R", d); 120 var[argno] = d; 121 continue; 122 123 case 0xA: /* byte displacement */ 124 case 0xB: /* byte displacement deferred */ 125 d = 1; 126 break; 127 128 case 0xC: /* word displacement */ 129 case 0xD: /* word displacement deferred */ 130 d = 2; 131 break; 132 133 case 0xE: /* long displacement */ 134 case 0xF: /* long displacement deferred */ 135 d = 4; 136 break; 137 } 138 139 /* displacement or displacement deferred */ 140 if (mode & 1) 141 printc('*'); 142 snarfbytes(d); 143 switch (d) { 144 case 1: 145 d = mem.b; 146 break; 147 case 2: 148 d = mem.w; 149 break; 150 case 4: 151 d = mem.l; 152 break; 153 } 154 if (r == 0xF) { /* PC offset addressing */ 155 d += dot + dotoff; 156 psymoff("%R", (addr_t)d, SP_DATA, maxoff, ""); 157 } else 158 adbprintf("%V(%s)", d, regname[r]); 159 var[argno] = d; 160 } 161 if (ins == CASEL) { 162 register addr_t adjdot; 163 164 if (inkdot(dotoff) & 01) /* align */ 165 dotoff++; 166 adjdot = inkdot(dotoff); 167 for (argno = 0; argno <= var[2]; ++argno) { 168 adbprintf("\n %R: ", argno + var[1]); 169 snarfbytes(2); 170 psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, ""); 171 } 172 } 173 dotinc = dotoff; 174 } 175