1 #ifndef lint 2 static char sccsid[] = "@(#)opset.c 1.4 (Berkeley) 04/27/90"; 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 if (space == SP_NONE) 52 ins = (u_char)dot; 53 else { 54 (void) adbread(space, dot, &ins, 1); 55 checkerr(); 56 } 57 if ((ip = ioptab[ins]) == NULL) { 58 adbprintf("?%2x", ins); 59 dotinc = 1; 60 return; 61 } 62 adbprintf("%s%8t", ip->iname); 63 dotoff = 1; 64 ap = ip->argtype; 65 for (argno = 0; argno < ip->nargs; argno++, ap++) { 66 var[argno] = 0x80000000; 67 if (argno != 0) 68 printc(','); 69 again: 70 if (*ap & ACCB) /* branch displacement */ 71 mode = 0xAF + ((*ap & 7) << 5); 72 else { 73 snarfbytes(1); 74 mode = mem.ub; 75 } 76 r = mode & 0xF; 77 mode >>= 4; 78 switch (mode) { 79 80 case 0: case 1: case 2: case 3: 81 /* short literal */ 82 d = mode << 4 | r; 83 goto immed; 84 85 case 4: /* [r] */ 86 adbprintf("[%s]", regname[r]); 87 goto again; 88 89 case 5: /* r */ 90 adbprintf("%s", regname[r]); 91 continue; 92 93 case 6: /* (r) */ 94 adbprintf("(%s)", regname[r]); 95 continue; 96 97 case 7: /* -(r) */ 98 adbprintf("-(%s)", regname[r]); 99 continue; 100 101 case 9: /* *(r)+ */ 102 printc('*'); 103 /* FALLTHROUGH */ 104 105 case 8: /* (r)+ */ 106 if (r == 0xf) { 107 /* PC immediate */ 108 snarfbytes(4); 109 d = mem.l; 110 } else if (mode == 8 && (r == 8 || r == 9)) { 111 /* absolute */ 112 snarfbytes((r & 1) + 1); 113 d = r == 8 ? mem.b : mem.w; 114 } else { 115 adbprintf("(%s)+", regname[r]); 116 continue; 117 } 118 immed: 119 printc('$'); 120 if (ins == KCALL && (u_int)d < nsys && syscalls[d]) 121 prints(syscalls[d]); 122 else 123 adbprintf("%R", d); 124 var[argno] = d; 125 continue; 126 127 case 0xA: /* byte displacement */ 128 case 0xB: /* byte displacement deferred */ 129 d = 1; 130 break; 131 132 case 0xC: /* word displacement */ 133 case 0xD: /* word displacement deferred */ 134 d = 2; 135 break; 136 137 case 0xE: /* long displacement */ 138 case 0xF: /* long displacement deferred */ 139 d = 4; 140 break; 141 } 142 143 /* displacement or displacement deferred */ 144 if (mode & 1) 145 printc('*'); 146 snarfbytes(d); 147 switch (d) { 148 case 1: 149 d = mem.b; 150 break; 151 case 2: 152 d = mem.w; 153 break; 154 case 4: 155 d = mem.l; 156 break; 157 } 158 if (r == 0xF) { /* PC offset addressing */ 159 d += dot + dotoff; 160 psymoff("%R", (addr_t)d, SP_DATA, maxoff, ""); 161 } else 162 adbprintf("%V(%s)", d, regname[r]); 163 var[argno] = d; 164 } 165 if (ins == CASEL) { 166 register addr_t adjdot; 167 168 if (inkdot(dotoff) & 01) /* align */ 169 dotoff++; 170 adjdot = inkdot(dotoff); 171 for (argno = 0; argno <= var[2]; ++argno) { 172 adbprintf("\n %R: ", argno + var[1]); 173 snarfbytes(2); 174 psymoff("%R", adjdot + mem.w, SP_DATA, maxoff, ""); 175 } 176 } 177 dotinc = dotoff; 178 } 179