|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)opset.c 1.4 (Berkeley) 4/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.