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