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 4.9 (Berkeley) 04/04/91";
10 #endif /* not lint */
11
12 /*
13 * adb - instruction printing routines: VAX version
14 */
15
16 #include "defs.h"
17
18 /*
19 * Get assembler definitions; declare tables that appear in optab.c.
20 */
21 #define ADB
22 #undef INSTTAB
23 #include "instrs.h"
24
25 extern struct insttab insttab[];
26 extern char *regname[];
27 extern char *fltimm[];
28
29 /* these are shared with the assembler: */
30 extern int ty_NORELOC[];
31 extern int ty_nbyte[];
32 #ifdef notyet
33 extern int ty_float[]; /* must update assizetab.c */
34 #endif
35
36 /*
37 * Definitions for registers and for operand classes.
38 */
39 #define R_PC 0xF
40
41 #define OC_IMM0 0x0 /* literal, aka immediate */
42 #define OC_IMM1 0x1
43 #define OC_IMM2 0x2
44 #define OC_IMM3 0x3
45 #define OC_INDEX 0x4 /* [rN] */
46 #define OC_REG 0x5 /* rN */
47 #define OC_DREG 0x6 /* (rN) */
48 #define OC_ADREG 0x7 /* -(rN) */
49 #define OC_AIREG 0x8 /* (rN)+ */
50 #define OC_DAIREG 0x9 /* *(rN)+ */
51 #define OC_BDISP 0xA /* b(rN) */
52 #define OC_DBDISP 0xB /* *b(rN) */
53 #define OC_WDISP 0xC /* w(rN) */
54 #define OC_DWDISP 0xD /* *w(rN) */
55 #define OC_LDISP 0xE /* l(rN) */
56 #define OC_DLDISP 0xF /* *l(rN) */
57
58 #define OC_SHIFT 4
59 #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
60 #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF)
61 #define OC_REGEXT(x) ((x) & 0xF)
62
63 /*
64 * Definitions for special instructions.
65 */
66 #define CASEB 0x8F
67 #define CASEW 0xAF
68 #define CASEL 0xCF
69 #define CHMK 0xBC
70
71 /*
72 * ioptab is a two level 1-based index by opcode into insttab.
73 * The first level into ioptab is given by mapescbyte().
74 * Since ioptab is 1-based, references would be expected to
75 * be of the form
76 *
77 * ptr = &insttab[ioptab[a][b] - 1];
78 *
79 * but the form
80 *
81 * ptr = &(insttab - 1)[ioptab[a][b]]
82 *
83 * is equivalent and generates less code (!) (time to work on the
84 * compiler again...).
85 */
86 static short ioptab[3][256];
87 #define mapescbyte(b) ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0)
88
mkioptab()89 mkioptab()
90 {
91 register struct insttab *p;
92 register int mapchar;
93 register short *iop;
94
95 /*
96 * The idea here is that whenever two opcodes have the same
97 * codes, but different mnemonics, we want to prefer the one
98 * with the `simpler' type. Here lower numbers make simpler
99 * types. This seems (likely) to work reasonably well.
100 *
101 * At present, this affects the following opcodes:
102 *
103 * 7c clrq | clrd | clrg
104 * 7e movaq | movad | movag
105 * 7f pushaq | pushad | pushag
106 * d4 clrl | clrf
107 * de moval | movaf
108 * df pushal | pushaf
109 *
110 * In each case, the leftmost mnemonics are preferred.
111 */
112 #define PREFER(a, b) (A_TYPEXT((a)->argtype[0]) < A_TYPEXT((b)->argtype[0]))
113
114 for (p = insttab; p->iname != NULL; p++) {
115 mapchar = mapescbyte(p->eopcode);
116 iop = &ioptab[mapchar][p->popcode];
117 if (*iop == 0 || PREFER(p, &(insttab - 1)[*iop]))
118 *iop = p - (insttab - 1);
119 }
120 #undef PREFER
121 }
122
123 /*
124 * Global variables for communication between the minions and printins.
125 */
126 static int idsp; /* which space we are in (INSTR or DATA) */
127 static int argno; /* which argument we are working on */
128 static int dotoff; /* offset from dot for this arg */
129 static int vset[7]; /* set by savevar, cleared by clrvar */
130
131 #define savevar(v) (vset[argno] = 1, var[argno] = v)
132 #define clrvar(v) (vset[argno] = 0, var[argno] = 0x80000000)
133
134 /*
135 * Read some bytes, checking for errors, and updating the offset.
136 */
137 #define getsomebytes(ptr, nbytes) \
138 (void) adbread(idsp, inkdot(dotoff), ptr, nbytes); \
139 checkerr(); \
140 dotoff += (nbytes)
141
142 /*
143 * Read one byte, and advance the offset.
144 */
145 static int
getbyte()146 getbyte()
147 {
148 u_char c;
149
150 getsomebytes(&c, sizeof(c));
151 return (c);
152 }
153
154 /*
155 * adb's view: printins() prints one instruction, and sets dotinc.
156 */
printins(space)157 printins(space)
158 int space;
159 {
160 register u_char *ap;
161 register struct insttab *ip;
162 int ins, mode, optype, mapchar, t;
163 char *lastix, *ixreg;
164 char *operandout();
165
166 /*
167 * Set up the module variables, pick up the instruction, and
168 * find its table entry.
169 */
170 idsp = space;
171 dotoff = 0;
172 ins = idsp == SP_NONE ? (u_char)dot : getbyte();
173 if ((mapchar = mapescbyte(ins)) != 0) {
174 t = getbyte();
175 if (ioptab[mapchar][t] == 0) {
176 /*
177 * Oops; not a defined instruction; back over this
178 * escape byte.
179 */
180 dotoff--;
181 mapchar = 0;
182 } else
183 ins = t;
184 }
185 if ((t = ioptab[mapchar][ins]) == 0) {
186 adbprintf("<undefined operator byte>: %x", ins);
187 dotinc = 1;
188 return;
189 }
190 ip = &(insttab - 1)[t];
191 adbprintf("%s%8t", ip->iname);
192
193 /*
194 * For each argument, decode that argument.
195 * We set t if we notice something fishy.
196 */
197 t = 0;
198 for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++) {
199 optype = *ap++;
200 clrvar();
201 if (argno != 0)
202 printc(',');
203 /*
204 * lastix and ixreg track the register indexed addressing
205 * mode, which is written as <stuff>[reg] but encoded as
206 * [reg]<stuff>. Only one [reg] is legal.
207 */
208 lastix = NULL;
209 do {
210 /* check for special pc-relative (branch) */
211 if (A_ACCEXT(optype) & ACCB) {
212 switch (A_TYPEXT(optype)) {
213 case TYPB:
214 mode = OC_CONS(OC_BDISP, R_PC);
215 break;
216 case TYPW:
217 mode = OC_CONS(OC_WDISP, R_PC);
218 break;
219 }
220 } else
221 mode = getbyte();
222 ixreg = operandout(mode, optype, ins == CHMK);
223 if (lastix) {
224 adbprintf("[%s]", lastix);
225 if (ixreg)
226 t = 1;
227 }
228 } while ((lastix = ixreg) != NULL);
229 }
230 if (t)
231 adbprintf("%4t# not code? illegal arguments detected ");
232 switch (ins) {
233 case CASEB:
234 case CASEW:
235 case CASEL:
236 if (mapchar == 0 && vset[1] && vset[2])
237 casebody(var[1], var[2]);
238 else
239 adbprintf("\n%4t# not code? non-constant cases ");
240 }
241 dotinc = dotoff;
242 }
243
244 /*
245 * Print out the locations to which each of the cases branch.
246 * This routine carefully allows expressions such as
247 *
248 * casel <val>,$<const>,$0x7fffffff
249 *
250 * even though they do not fit on a VAX.
251 */
252 static
casebody(base,limit)253 casebody(base, limit)
254 register expr_t base, limit;
255 {
256 register expr_t i = -1;
257 register addr_t a, baseaddr = inkdot(dotoff);
258 short displ;
259
260 argno = 0;
261 do {
262 i++;
263 adbprintf("\n %R: ", base++);
264 getsomebytes(&displ, sizeof(displ));
265 a = displ + baseaddr;
266 psymoff("%R", a, SP_DATA, maxoff, "");
267 savevar(a);
268 } while (i != limit);
269 }
270
271 /*
272 * Handle a normal operand. Return pointer to register
273 * name if this is an index instruction, else return NULL.
274 */
275 static char *
operandout(mode,optype,ischmk)276 operandout(mode, optype, ischmk)
277 register int mode;
278 int optype, ischmk;
279 {
280 register char *r;
281 register int regnumber, nbytes, n;
282 union {
283 char b;
284 short w;
285 int l;
286 } displ;
287 extern char *syscalls[];
288 extern int nsys;
289
290 regnumber = OC_REGEXT(mode);
291 r = regname[regnumber];
292 switch (OC_AMEXT(mode)) {
293
294 case OC_IMM0: case OC_IMM1:
295 case OC_IMM2: case OC_IMM3:
296 savevar(mode);
297 printc('$');
298 #ifdef notyet
299 if (ty_float[A_TYPEXT(optype)])
300 prints(fltimm[mode]);
301 else if (ischmk && (u_int)mode < nsys && syscalls[mode])
302 prints(syscalls[mode]);
303 else
304 adbprintf("%V", mode);
305 #else
306 switch (A_TYPEXT(optype)) {
307
308 case TYPF:
309 case TYPD:
310 case TYPG:
311 case TYPH:
312 prints(fltimm[mode]);
313 break;
314
315 default:
316 if (ischmk && (u_int)mode < nsys && syscalls[mode])
317 prints(syscalls[mode]);
318 else
319 adbprintf("%V", mode);
320 break;
321 }
322 #endif
323 return (0);
324
325 case OC_INDEX:
326 return (r); /* will be printed later */
327
328 case OC_REG:
329 adbprintf("%s", r);
330 return (0);
331
332 case OC_DREG:
333 adbprintf("(%s)", r);
334 return (0);
335
336 case OC_ADREG:
337 adbprintf("-(%s)", r);
338 return (0);
339
340 case OC_DAIREG:
341 printc('*');
342 /* FALLTHROUGH */
343
344 case OC_AIREG:
345 if (regnumber != R_PC) {
346 adbprintf("(%s)+", r);
347 return (0);
348 }
349 /* PC immediate */
350 printc('$');
351 if (mode == OC_CONS(OC_DAIREG, R_PC))
352 /* PC absolute, always 4 bytes */
353 nbytes = 4;
354 else {
355 nbytes = ty_nbyte[A_TYPEXT(optype)];
356 if (ty_NORELOC[A_TYPEXT(optype)]) {
357 bignumprint(nbytes, optype);
358 return (0);
359 }
360 }
361 break;
362
363 case OC_DBDISP:
364 printc('*');
365 /* FALLTHROUGH */
366
367 case OC_BDISP:
368 nbytes = 1;
369 break;
370
371 case OC_DWDISP:
372 printc('*');
373 /* FALLTHROUGH */
374
375 case OC_WDISP:
376 nbytes = 2;
377 break;
378
379 case OC_DLDISP:
380 printc('*');
381 /* FALLTHROUGH */
382
383 case OC_LDISP:
384 nbytes = 4;
385 break;
386
387 default:
388 panic("operandout 1");
389 /* NOTREACHED */
390 }
391
392 /*
393 * Print a displacement format.
394 */
395 getsomebytes(&displ, nbytes);
396 switch (nbytes) {
397 case 1:
398 n = displ.b;
399 break;
400 case 2:
401 n = displ.w;
402 break;
403 case 4:
404 n = displ.l;
405 break;
406 default:
407 panic("operandout 2");
408 /* NOTREACHED */
409 }
410 if (regnumber == R_PC) {
411 switch (OC_AMEXT(mode)) {
412
413 case OC_DAIREG:
414 if (ischmk && (u_int)n < nsys && syscalls[n]) {
415 prints(syscalls[n]);
416 return (0);
417 }
418 break;
419
420 case OC_BDISP: case OC_DBDISP:
421 case OC_WDISP: case OC_DWDISP:
422 case OC_LDISP: case OC_DLDISP:
423 /* PC offset */
424 n += dot + dotoff;
425 }
426 psymoff("%V", (addr_t)n, SP_DATA, maxoff, "");
427 } else
428 adbprintf("%V(%s)", (expr_t)n, regname[regnumber]);
429 savevar(n);
430 return (0);
431 }
432
433 /*
434 * Print an F-float, D-float, G-float, H-float, quadword, or octaword.
435 * F- and D-floating values are printed as themselves, unless they are
436 * reserved operand bit patterns; these, and the others, are printed
437 * instead in hex, with leading zeroes suppressed.
438 */
439 static
bignumprint(nbytes,optype)440 bignumprint(nbytes, optype)
441 int nbytes, optype;
442 {
443 register char *p;
444 register int i;
445 union {
446 float f; /* if f-floating */
447 double d; /* if d-floating */
448 u_char c[16]; /* if G, H, Q, or O */
449 } n;
450 char expbuf[4*8+1]; /* max 4 8-character hex ints */
451 static char tohex[] = "0123456789abcdef";
452
453 /*
454 * Read in the number, then figure out how to print it.
455 */
456 getsomebytes(&n, nbytes);
457 switch (A_TYPEXT(optype)) {
458
459 case TYPF:
460 if ((p = checkfloat((caddr_t)&n.f, 0)) == NULL) {
461 adbprintf("0f%f", n.f);
462 return;
463 }
464 adbprintf("%s 0f::", p);
465 break;
466
467 case TYPD:
468 if ((p = checkfloat((caddr_t)&n.d, 1)) == NULL) {
469 adbprintf("0d%f", n.d);
470 return;
471 }
472 adbprintf("%s 0d::", p);
473 break;
474
475 case TYPG:
476 adbprintf("0g::");
477 break;
478
479 case TYPH:
480 adbprintf("0h::");
481 break;
482
483 case TYPQ:
484 case TYPO:
485 break;
486
487 default:
488 panic("bignumprint");
489 }
490
491 /*
492 * Expand the number into expbuf, then skip leading zeroes.
493 * Be careful not to skip the entire number.
494 */
495 for (p = expbuf, i = nbytes; --i >= 0;) {
496 *p++ = tohex[n.c[i] >> 4];
497 *p++ = tohex[n.c[i] & 15];
498 }
499 for (p = expbuf; *p == '0'; p++)
500 /* void */;
501 prints(*p ? p : p - 1);
502 }
503