xref: /csrg-svn/old/dbx/sun.c (revision 38103)
1*38103Sbostic /*
2*38103Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*38103Sbostic  * All rights reserved.
4*38103Sbostic  *
5*38103Sbostic  * Redistribution and use in source and binary forms are permitted
6*38103Sbostic  * provided that the above copyright notice and this paragraph are
7*38103Sbostic  * duplicated in all such forms and that any documentation,
8*38103Sbostic  * advertising materials, and other materials related to such
9*38103Sbostic  * distribution and use acknowledge that the software was developed
10*38103Sbostic  * by the University of California, Berkeley.  The name of the
11*38103Sbostic  * University may not be used to endorse or promote products derived
12*38103Sbostic  * from this software without specific prior written permission.
13*38103Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38103Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38103Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*38103Sbostic  */
17*38103Sbostic 
18*38103Sbostic #ifndef lint
19*38103Sbostic static char sccsid[] = "@(#)sun.c	5.1 (Berkeley) 05/23/89";
20*38103Sbostic #endif /* not lint */
21*38103Sbostic 
22*38103Sbostic /*
23*38103Sbostic  * Target machine dependent stuff.
24*38103Sbostic  */
25*38103Sbostic 
26*38103Sbostic #include "defs.h"
27*38103Sbostic #include "machine.h"
28*38103Sbostic #include "process.h"
29*38103Sbostic #include "runtime.h"
30*38103Sbostic #include "events.h"
31*38103Sbostic #include "main.h"
32*38103Sbostic #include "symbols.h"
33*38103Sbostic #include "source.h"
34*38103Sbostic #include "mappings.h"
35*38103Sbostic #include "object.h"
36*38103Sbostic #include "tree.h"
37*38103Sbostic #include "eval.h"
38*38103Sbostic #include "keywords.h"
39*38103Sbostic #include "ops.h"
40*38103Sbostic 
41*38103Sbostic #ifndef public
42*38103Sbostic typedef unsigned int Address;
43*38103Sbostic typedef unsigned char Byte;
44*38103Sbostic typedef unsigned int Word;
45*38103Sbostic 
46*38103Sbostic /*
47*38103Sbostic  * On the 68000, the pc isn't in a register, but we make believe
48*38103Sbostic  * so there's one more register.
49*38103Sbostic  *
50*38103Sbostic  * Note that there's also no argument pointer, this means code
51*38103Sbostic  * involving "ARGP" should always be #ifdef'd.
52*38103Sbostic  *
53*38103Sbostic  * The address corresponding to the beginning of a function is recorded
54*38103Sbostic  * as the address + FUNCOFFSET (skip the link instruction so that
55*38103Sbostic  * local information is available).
56*38103Sbostic  */
57*38103Sbostic 
58*38103Sbostic #define NREG 17
59*38103Sbostic 
60*38103Sbostic #define FRP 14
61*38103Sbostic #define STKP 15
62*38103Sbostic #define PROGCTR 16
63*38103Sbostic 
64*38103Sbostic #define CALL_RETADDR	0x800c		/* Return address for 'call' command */
65*38103Sbostic #define FUNCOFFSET 4
66*38103Sbostic 
67*38103Sbostic #ifdef sun
68*38103Sbostic #    define CODESTART 0x8000
69*38103Sbostic #else /* IRIS */
70*38103Sbostic #   define CODESTART 0x1000
71*38103Sbostic #endif
72*38103Sbostic 
73*38103Sbostic #define optab_init()
74*38103Sbostic 
75*38103Sbostic #define BITSPERBYTE 8
76*38103Sbostic #define BITSPERWORD (BITSPERBYTE * sizeof(Word))
77*38103Sbostic 
78*38103Sbostic /*
79*38103Sbostic  * This magic macro enables us to look at the process' registers
80*38103Sbostic  * in its user structure.
81*38103Sbostic  */
82*38103Sbostic 
83*38103Sbostic #define regloc(reg)	(ctob(UPAGES) + (sizeof(Word) * ((reg) - PC)) - 10)
84*38103Sbostic 
85*38103Sbostic #include "source.h"
86*38103Sbostic #include "symbols.h"
87*38103Sbostic #include <signal.h>
88*38103Sbostic #include <sys/param.h>
89*38103Sbostic #include <sys/dir.h>
90*38103Sbostic #include <machine/psl.h>
91*38103Sbostic #include <machine/pte.h>
92*38103Sbostic #include <sys/user.h>
93*38103Sbostic #undef DELETE /* XXX */
94*38103Sbostic #include <sys/vm.h>
95*38103Sbostic #include <machine/reg.h>
96*38103Sbostic 
97*38103Sbostic Address pc;
98*38103Sbostic Address prtaddr;
99*38103Sbostic 
100*38103Sbostic #endif
101*38103Sbostic 
102*38103Sbostic /*
103*38103Sbostic  * Indices into u. for use in collecting registers values.
104*38103Sbostic  */
105*38103Sbostic public int rloc[] ={
106*38103Sbostic #ifdef sun
107*38103Sbostic     R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, PC
108*38103Sbostic #else /* IRIS */
109*38103Sbostic     R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, 16
110*38103Sbostic #endif
111*38103Sbostic };
112*38103Sbostic 
113*38103Sbostic private Address printop();
114*38103Sbostic 
115*38103Sbostic /*
116*38103Sbostic  * Decode and print the instructions within the given address range.
117*38103Sbostic  */
118*38103Sbostic 
119*38103Sbostic public printinst(lowaddr, highaddr)
120*38103Sbostic Address lowaddr;
121*38103Sbostic Address highaddr;
122*38103Sbostic {
123*38103Sbostic     register Address addr;
124*38103Sbostic 
125*38103Sbostic     for (addr = lowaddr; addr <= highaddr; ) {
126*38103Sbostic 	addr = printop(addr);
127*38103Sbostic     }
128*38103Sbostic     prtaddr = addr;
129*38103Sbostic }
130*38103Sbostic 
131*38103Sbostic /*
132*38103Sbostic  * Another approach:  print n instructions starting at the given address.
133*38103Sbostic  */
134*38103Sbostic 
135*38103Sbostic public printninst(count, addr)
136*38103Sbostic int count;
137*38103Sbostic Address addr;
138*38103Sbostic {
139*38103Sbostic     register Integer i;
140*38103Sbostic     register Address newaddr;
141*38103Sbostic 
142*38103Sbostic     if (count <= 0) {
143*38103Sbostic 	error("non-positive repetition count");
144*38103Sbostic     } else {
145*38103Sbostic 	newaddr = addr;
146*38103Sbostic 	for (i = 0; i < count; i++) {
147*38103Sbostic 	    newaddr = printop(newaddr);
148*38103Sbostic 	}
149*38103Sbostic 	prtaddr = newaddr;
150*38103Sbostic     }
151*38103Sbostic }
152*38103Sbostic 
153*38103Sbostic /*
154*38103Sbostic  * Print the contents of the addresses within the given range
155*38103Sbostic  * according to the given format.
156*38103Sbostic  */
157*38103Sbostic 
158*38103Sbostic typedef struct {
159*38103Sbostic     String name;
160*38103Sbostic     String printfstring;
161*38103Sbostic     int length;
162*38103Sbostic } Format;
163*38103Sbostic 
164*38103Sbostic private Format fmt[] = {
165*38103Sbostic     { "d", " %d", sizeof(short) },
166*38103Sbostic     { "D", " %ld", sizeof(long) },
167*38103Sbostic     { "o", " %o", sizeof(short) },
168*38103Sbostic     { "O", " %lo", sizeof(long) },
169*38103Sbostic     { "x", " %04x", sizeof(short) },
170*38103Sbostic     { "X", " %08x", sizeof(long) },
171*38103Sbostic     { "b", " \\%o", sizeof(char) },
172*38103Sbostic     { "c", " '%c'", sizeof(char) },
173*38103Sbostic     { "s", "%c", sizeof(char) },
174*38103Sbostic     { "f", " %f", sizeof(float) },
175*38103Sbostic     { "g", " %g", sizeof(double) },
176*38103Sbostic     { nil, nil, 0 }
177*38103Sbostic };
178*38103Sbostic 
179*38103Sbostic private Format *findformat(s)
180*38103Sbostic String s;
181*38103Sbostic {
182*38103Sbostic     register Format *f;
183*38103Sbostic 
184*38103Sbostic     f = &fmt[0];
185*38103Sbostic     while (f->name != nil and not streq(f->name, s)) {
186*38103Sbostic 	++f;
187*38103Sbostic     }
188*38103Sbostic     if (f->name == nil) {
189*38103Sbostic 	error("bad print format \"%s\"", s);
190*38103Sbostic     }
191*38103Sbostic     return f;
192*38103Sbostic }
193*38103Sbostic 
194*38103Sbostic /*
195*38103Sbostic  * Retrieve and print out the appropriate data in the given format.
196*38103Sbostic  * Floats have to be handled specially to allow the compiler to
197*38103Sbostic  * convert them to doubles when passing to printf.
198*38103Sbostic  */
199*38103Sbostic 
200*38103Sbostic private printformat (f, addr)
201*38103Sbostic Format *f;
202*38103Sbostic Address addr;
203*38103Sbostic {
204*38103Sbostic     union {
205*38103Sbostic 	char charv;
206*38103Sbostic 	short shortv;
207*38103Sbostic 	int intv;
208*38103Sbostic 	float floatv;
209*38103Sbostic 	double doublev;
210*38103Sbostic     } value;
211*38103Sbostic 
212*38103Sbostic     value.intv = 0;
213*38103Sbostic     dread(&value, addr, f->length);
214*38103Sbostic     if (streq(f->name, "f")) {
215*38103Sbostic 	printf(f->printfstring, value.floatv);
216*38103Sbostic     } else {
217*38103Sbostic 	printf(f->printfstring, value);
218*38103Sbostic     }
219*38103Sbostic }
220*38103Sbostic 
221*38103Sbostic public Address printdata(lowaddr, highaddr, format)
222*38103Sbostic Address lowaddr;
223*38103Sbostic Address highaddr;
224*38103Sbostic String format;
225*38103Sbostic {
226*38103Sbostic     int n;
227*38103Sbostic     register Address addr;
228*38103Sbostic     Format *f;
229*38103Sbostic 
230*38103Sbostic     if (lowaddr > highaddr) {
231*38103Sbostic 	error("first address larger than second");
232*38103Sbostic     }
233*38103Sbostic     f = findformat(format);
234*38103Sbostic     n = 0;
235*38103Sbostic     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
236*38103Sbostic 	if (n == 0) {
237*38103Sbostic 	    printf("%08x: ", addr);
238*38103Sbostic 	}
239*38103Sbostic 	printformat(f, addr);
240*38103Sbostic 	++n;
241*38103Sbostic 	if (n >= (16 div f->length)) {
242*38103Sbostic 	    printf("\n");
243*38103Sbostic 	    n = 0;
244*38103Sbostic 	}
245*38103Sbostic     }
246*38103Sbostic     if (n != 0) {
247*38103Sbostic 	printf("\n");
248*38103Sbostic     }
249*38103Sbostic     prtaddr = addr;
250*38103Sbostic     return addr;
251*38103Sbostic }
252*38103Sbostic 
253*38103Sbostic /*
254*38103Sbostic  * The other approach is to print n items starting with a given address.
255*38103Sbostic  */
256*38103Sbostic 
257*38103Sbostic public printndata(count, startaddr, format)
258*38103Sbostic int count;
259*38103Sbostic Address startaddr;
260*38103Sbostic String format;
261*38103Sbostic {
262*38103Sbostic     int i, n;
263*38103Sbostic     Address addr;
264*38103Sbostic     Format *f;
265*38103Sbostic     Boolean isstring;
266*38103Sbostic     char c;
267*38103Sbostic 
268*38103Sbostic     if (count <= 0) {
269*38103Sbostic 	error("non-positive repetition count");
270*38103Sbostic     }
271*38103Sbostic     f = findformat(format);
272*38103Sbostic     isstring = (Boolean) streq(f->name, "s");
273*38103Sbostic     n = 0;
274*38103Sbostic     addr = startaddr;
275*38103Sbostic     for (i = 0; i < count; i++) {
276*38103Sbostic 	if (n == 0) {
277*38103Sbostic 	    printf("%08x: ", addr);
278*38103Sbostic 	}
279*38103Sbostic 	if (isstring) {
280*38103Sbostic 	    printf("\"");
281*38103Sbostic 	    dread(&c, addr, sizeof(char));
282*38103Sbostic 	    while (c != '\0') {
283*38103Sbostic 		printchar(c);
284*38103Sbostic 		++addr;
285*38103Sbostic 		dread(&c, addr, sizeof(char));
286*38103Sbostic 	    }
287*38103Sbostic 	    printf("\"\n");
288*38103Sbostic 	    n = 0;
289*38103Sbostic 	    addr += sizeof(String);
290*38103Sbostic 	} else {
291*38103Sbostic 	    printformat(f, addr);
292*38103Sbostic 	    ++n;
293*38103Sbostic 	    if (n >= (16 div f->length)) {
294*38103Sbostic 		printf("\n");
295*38103Sbostic 		n = 0;
296*38103Sbostic 	    }
297*38103Sbostic 	    addr += f->length;
298*38103Sbostic 	}
299*38103Sbostic     }
300*38103Sbostic     if (n != 0) {
301*38103Sbostic 	printf("\n");
302*38103Sbostic     }
303*38103Sbostic     prtaddr = addr;
304*38103Sbostic }
305*38103Sbostic 
306*38103Sbostic /*
307*38103Sbostic  * Print out a value according to the given format.
308*38103Sbostic  */
309*38103Sbostic 
310*38103Sbostic public printvalue(v, format)
311*38103Sbostic long v;
312*38103Sbostic String format;
313*38103Sbostic {
314*38103Sbostic     Format *f;
315*38103Sbostic     char *p, *q;
316*38103Sbostic 
317*38103Sbostic     f = findformat(format);
318*38103Sbostic     if (streq(f->name, "s")) {
319*38103Sbostic 	putchar('"');
320*38103Sbostic 	p = (char *) &v;
321*38103Sbostic 	q = p + sizeof(v);
322*38103Sbostic 	while (p < q) {
323*38103Sbostic 	    printchar(*p);
324*38103Sbostic 	    ++p;
325*38103Sbostic 	}
326*38103Sbostic 	putchar('"');
327*38103Sbostic     } else {
328*38103Sbostic 	printf(f->printfstring, v);
329*38103Sbostic     }
330*38103Sbostic     putchar('\n');
331*38103Sbostic }
332*38103Sbostic 
333*38103Sbostic /*
334*38103Sbostic  * Print out an execution time error.
335*38103Sbostic  * Assumes the source position of the error has been calculated.
336*38103Sbostic  *
337*38103Sbostic  * Have to check if the -r option was specified; if so then
338*38103Sbostic  * the object file information hasn't been read in yet.
339*38103Sbostic  */
340*38103Sbostic 
341*38103Sbostic public printerror()
342*38103Sbostic {
343*38103Sbostic     extern Integer sys_nsig;
344*38103Sbostic     extern String sys_siglist[];
345*38103Sbostic     integer err;
346*38103Sbostic 
347*38103Sbostic     if (isfinished(process)) {
348*38103Sbostic 	err = exitcode(process);
349*38103Sbostic 	if (err == 0) {
350*38103Sbostic 	    printf("\"%s\" terminated normally\n", objname);
351*38103Sbostic 	} else {
352*38103Sbostic 	    printf("\"%s\" terminated abnormally (exit code %d)\n",
353*38103Sbostic 		objname, err
354*38103Sbostic 	    );
355*38103Sbostic 	}
356*38103Sbostic 	erecover();
357*38103Sbostic     }
358*38103Sbostic     err = errnum(process);
359*38103Sbostic     putchar('\n');
360*38103Sbostic     printsig(err);
361*38103Sbostic     putchar(' ');
362*38103Sbostic     printloc();
363*38103Sbostic     putchar('\n');
364*38103Sbostic     if (curline > 0) {
365*38103Sbostic 	printlines(curline, curline);
366*38103Sbostic     } else {
367*38103Sbostic 	printinst(pc, pc);
368*38103Sbostic     }
369*38103Sbostic     erecover();
370*38103Sbostic }
371*38103Sbostic 
372*38103Sbostic /*
373*38103Sbostic  * Print out a signal.
374*38103Sbostic  */
375*38103Sbostic 
376*38103Sbostic private String illinames[] = {
377*38103Sbostic     "reserved addressing fault",
378*38103Sbostic     "privileged instruction fault",
379*38103Sbostic     "reserved operand fault"
380*38103Sbostic };
381*38103Sbostic 
382*38103Sbostic private String fpenames[] = {
383*38103Sbostic     nil,
384*38103Sbostic     "integer overflow trap",
385*38103Sbostic     "integer divide by zero trap",
386*38103Sbostic     "floating overflow trap",
387*38103Sbostic     "floating/decimal divide by zero trap",
388*38103Sbostic     "floating underflow trap",
389*38103Sbostic     "decimal overflow trap",
390*38103Sbostic     "subscript out of range trap",
391*38103Sbostic     "floating overflow fault",
392*38103Sbostic     "floating divide by zero fault",
393*38103Sbostic     "floating underflow fault"
394*38103Sbostic };
395*38103Sbostic 
396*38103Sbostic public printsig (signo)
397*38103Sbostic integer signo;
398*38103Sbostic {
399*38103Sbostic     integer code;
400*38103Sbostic 
401*38103Sbostic     if (signo < 0 or signo > sys_nsig) {
402*38103Sbostic 	printf("[signal %d]", signo);
403*38103Sbostic     } else {
404*38103Sbostic 	printf("%s", sys_siglist[signo]);
405*38103Sbostic     }
406*38103Sbostic     code = errcode(process);
407*38103Sbostic     if (signo == SIGILL) {
408*38103Sbostic 	if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {
409*38103Sbostic 	    printf(" (%s)", illinames[code]);
410*38103Sbostic 	}
411*38103Sbostic     } else if (signo == SIGFPE) {
412*38103Sbostic 	if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {
413*38103Sbostic 	    printf(" (%s)", fpenames[code]);
414*38103Sbostic 	}
415*38103Sbostic     }
416*38103Sbostic }
417*38103Sbostic 
418*38103Sbostic /*
419*38103Sbostic  * Note the termination of the program.  We do this so as to avoid
420*38103Sbostic  * having the process exit, which would make the values of variables
421*38103Sbostic  * inaccessible.  We do want to flush all output buffers here,
422*38103Sbostic  * otherwise it'll never get done.
423*38103Sbostic  */
424*38103Sbostic 
425*38103Sbostic public endprogram()
426*38103Sbostic {
427*38103Sbostic     Integer exitcode;
428*38103Sbostic 
429*38103Sbostic     stepto(nextaddr(pc, true));
430*38103Sbostic     printnews();
431*38103Sbostic     exitcode = argn(1, nil);
432*38103Sbostic     if (exitcode != 0) {
433*38103Sbostic 	printf("\nexecution completed (exit code %d)\n", exitcode);
434*38103Sbostic     } else {
435*38103Sbostic 	printf("\nexecution completed\n");
436*38103Sbostic     }
437*38103Sbostic     getsrcpos();
438*38103Sbostic     erecover();
439*38103Sbostic }
440*38103Sbostic 
441*38103Sbostic /*
442*38103Sbostic  * Single step the machine a source line (or instruction if "inst_tracing"
443*38103Sbostic  * is true).  If "isnext" is true, skip over procedure calls.
444*38103Sbostic  */
445*38103Sbostic 
446*38103Sbostic private Address getcall();
447*38103Sbostic 
448*38103Sbostic public dostep(isnext)
449*38103Sbostic Boolean isnext;
450*38103Sbostic {
451*38103Sbostic     register Address addr;
452*38103Sbostic     register Lineno line;
453*38103Sbostic     String filename;
454*38103Sbostic     Address startaddr;
455*38103Sbostic 
456*38103Sbostic     startaddr = pc;
457*38103Sbostic     addr = nextaddr(pc, isnext);
458*38103Sbostic     if (not inst_tracing and nlhdr.nlines != 0) {
459*38103Sbostic 	line = linelookup(addr);
460*38103Sbostic 	while (line == 0) {
461*38103Sbostic 	    addr = nextaddr(addr, isnext);
462*38103Sbostic 	    line = linelookup(addr);
463*38103Sbostic 	}
464*38103Sbostic 	curline = line;
465*38103Sbostic     } else {
466*38103Sbostic 	curline = 0;
467*38103Sbostic     }
468*38103Sbostic     stepto(addr);
469*38103Sbostic     filename = srcfilename(addr);
470*38103Sbostic     setsource(filename);
471*38103Sbostic }
472*38103Sbostic 
473*38103Sbostic typedef short Bpinst;
474*38103Sbostic 
475*38103Sbostic extern Bpinst BP_OP;
476*38103Sbostic #ifdef sun
477*38103Sbostic 	asm("_BP_OP: trap #15");
478*38103Sbostic #else /* IRIS */
479*38103Sbostic 	asm("_BP_OP: trap #1");
480*38103Sbostic #endif
481*38103Sbostic 
482*38103Sbostic #define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint */
483*38103Sbostic 
484*38103Sbostic /*
485*38103Sbostic  * Setting a breakpoint at a location consists of saving
486*38103Sbostic  * the word at the location and poking a BP_OP there.
487*38103Sbostic  *
488*38103Sbostic  * We save the locations and words on a list for use in unsetting.
489*38103Sbostic  */
490*38103Sbostic 
491*38103Sbostic typedef struct Savelist *Savelist;
492*38103Sbostic 
493*38103Sbostic struct Savelist {
494*38103Sbostic     Address location;
495*38103Sbostic     Bpinst save;
496*38103Sbostic     short refcount;
497*38103Sbostic     Savelist link;
498*38103Sbostic };
499*38103Sbostic 
500*38103Sbostic private Savelist savelist;
501*38103Sbostic 
502*38103Sbostic /*
503*38103Sbostic  * Set a breakpoint at the given address.  Only save the word there
504*38103Sbostic  * if it's not already a breakpoint.
505*38103Sbostic  */
506*38103Sbostic 
507*38103Sbostic public setbp(addr)
508*38103Sbostic Address addr;
509*38103Sbostic {
510*38103Sbostic     Bpinst w, save;
511*38103Sbostic     register Savelist newsave, s;
512*38103Sbostic 
513*38103Sbostic     for (s = savelist; s != nil; s = s->link) {
514*38103Sbostic 	if (s->location == addr) {
515*38103Sbostic 	    s->refcount++;
516*38103Sbostic 	    return;
517*38103Sbostic 	}
518*38103Sbostic     }
519*38103Sbostic     iread(&save, addr, sizeof(save));
520*38103Sbostic     newsave = new(Savelist);
521*38103Sbostic     newsave->location = addr;
522*38103Sbostic     newsave->save = save;
523*38103Sbostic     newsave->refcount = 1;
524*38103Sbostic     newsave->link = savelist;
525*38103Sbostic     savelist = newsave;
526*38103Sbostic     w = BP_OP;
527*38103Sbostic     iwrite(&w, addr, sizeof(w));
528*38103Sbostic }
529*38103Sbostic 
530*38103Sbostic /*
531*38103Sbostic  * Unset a breakpoint; unfortunately we have to search the SAVELIST
532*38103Sbostic  * to find the saved value.  The assumption is that the SAVELIST will
533*38103Sbostic  * usually be quite small.
534*38103Sbostic  */
535*38103Sbostic 
536*38103Sbostic public unsetbp(addr)
537*38103Sbostic Address addr;
538*38103Sbostic {
539*38103Sbostic     register Savelist s, prev;
540*38103Sbostic 
541*38103Sbostic     prev = nil;
542*38103Sbostic     for (s = savelist; s != nil; s = s->link) {
543*38103Sbostic 	if (s->location == addr) {
544*38103Sbostic 	    iwrite(&s->save, addr, sizeof(s->save));
545*38103Sbostic 	    s->refcount--;
546*38103Sbostic 	    if (s->refcount == 0) {
547*38103Sbostic 		if (prev == nil) {
548*38103Sbostic 		    savelist = s->link;
549*38103Sbostic 		} else {
550*38103Sbostic 		    prev->link = s->link;
551*38103Sbostic 		}
552*38103Sbostic 		dispose(s);
553*38103Sbostic 	    }
554*38103Sbostic 	    return;
555*38103Sbostic 	}
556*38103Sbostic 	prev = s;
557*38103Sbostic     }
558*38103Sbostic     panic("unsetbp: couldn't find address %d", addr);
559*38103Sbostic }
560*38103Sbostic 
561*38103Sbostic /*
562*38103Sbostic  * Instruction decoding routines for 68000, derived from adb.
563*38103Sbostic  *
564*38103Sbostic  * The shared boolean variable "printing" is true if the decoded
565*38103Sbostic  * instruction is to be printed, false if not.  In either case,
566*38103Sbostic  * the address of the next instruction after the given one is returned.
567*38103Sbostic  */
568*38103Sbostic 
569*38103Sbostic private Boolean printing;
570*38103Sbostic private Boolean following;
571*38103Sbostic private Boolean followcalls;
572*38103Sbostic private Address instaddr;
573*38103Sbostic 
574*38103Sbostic #define instread(var) \
575*38103Sbostic { \
576*38103Sbostic     iread(&var, instaddr, sizeof(var)); \
577*38103Sbostic     instaddr += sizeof(var); \
578*38103Sbostic }
579*38103Sbostic 
580*38103Sbostic private Optab *decode(inst, addr)
581*38103Sbostic Word inst;
582*38103Sbostic Address addr;
583*38103Sbostic {
584*38103Sbostic     register Optab *o;
585*38103Sbostic 
586*38103Sbostic     o = &optab[0];
587*38103Sbostic     while (o->mask != 0 and (inst&o->mask) != o->match) {
588*38103Sbostic 	++o;
589*38103Sbostic     }
590*38103Sbostic     return o;
591*38103Sbostic }
592*38103Sbostic 
593*38103Sbostic private Address printop(addr)
594*38103Sbostic Address addr;
595*38103Sbostic {
596*38103Sbostic     Optab *o;
597*38103Sbostic     short inst;
598*38103Sbostic 
599*38103Sbostic     printf("%08x  ", addr);
600*38103Sbostic     iread(&inst, addr, sizeof(inst));
601*38103Sbostic     o = decode(inst, addr);
602*38103Sbostic     if (o->mask == 0) {
603*38103Sbostic 	printf("\tbadop");
604*38103Sbostic 	instaddr = addr + sizeof(inst);
605*38103Sbostic     } else {
606*38103Sbostic 	printing = true;
607*38103Sbostic 	following = false;
608*38103Sbostic 	instaddr = addr + sizeof(inst);
609*38103Sbostic 	(*o->opfun)(inst, o->farg);
610*38103Sbostic 	printing = false;
611*38103Sbostic     }
612*38103Sbostic     printf("\n");
613*38103Sbostic     return instaddr;
614*38103Sbostic }
615*38103Sbostic 
616*38103Sbostic /*
617*38103Sbostic  * Quickly find the return address of the current procedure or function
618*38103Sbostic  * while single stepping.  Just get the word pointed at by sp.
619*38103Sbostic  */
620*38103Sbostic 
621*38103Sbostic private Address currtnaddr ()
622*38103Sbostic {
623*38103Sbostic     Address retaddr;
624*38103Sbostic 
625*38103Sbostic     dread(&retaddr, reg(STKP), sizeof(retaddr));
626*38103Sbostic     return retaddr;
627*38103Sbostic }
628*38103Sbostic 
629*38103Sbostic /*
630*38103Sbostic  * Print out the effective address for the given parameters.
631*38103Sbostic  */
632*38103Sbostic 
633*38103Sbostic private printea(mode, reg, size)
634*38103Sbostic long mode, reg;
635*38103Sbostic int size;
636*38103Sbostic {
637*38103Sbostic     long index, disp;
638*38103Sbostic     static char *aregs[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp" };
639*38103Sbostic     Byte b;
640*38103Sbostic     short w;
641*38103Sbostic     long l;
642*38103Sbostic 
643*38103Sbostic     switch ((int)(mode)) {
644*38103Sbostic 	case 0:
645*38103Sbostic 	    if (printing) {
646*38103Sbostic 		printf("d%D", reg);
647*38103Sbostic 	    }
648*38103Sbostic 	    break;
649*38103Sbostic 
650*38103Sbostic 	case 1:
651*38103Sbostic 	    if (printing) {
652*38103Sbostic 		printf("%s", aregs[reg]);
653*38103Sbostic 	    }
654*38103Sbostic 	    break;
655*38103Sbostic 
656*38103Sbostic 	case 2:
657*38103Sbostic 	    if (printing) {
658*38103Sbostic 		printf("%s@", aregs[reg]);
659*38103Sbostic 	    }
660*38103Sbostic 	    break;
661*38103Sbostic 
662*38103Sbostic 	case 3:
663*38103Sbostic 	    if (printing) {
664*38103Sbostic 		printf("%s@+", aregs[reg]);
665*38103Sbostic 	    }
666*38103Sbostic 	    break;
667*38103Sbostic 
668*38103Sbostic 	case 4:
669*38103Sbostic 	    if (printing) {
670*38103Sbostic 		printf("%s@-", aregs[reg]);
671*38103Sbostic 	    }
672*38103Sbostic 	    break;
673*38103Sbostic 
674*38103Sbostic 	case 5:
675*38103Sbostic 	    instread(w);
676*38103Sbostic 	    if (printing) {
677*38103Sbostic 		printf("%s@(%D)", aregs[reg], w);
678*38103Sbostic 	    }
679*38103Sbostic 	    break;
680*38103Sbostic 
681*38103Sbostic 	case 6:
682*38103Sbostic 	    instread(w);
683*38103Sbostic 	    if (printing) {
684*38103Sbostic 		index = w;
685*38103Sbostic 		disp = (char)(index&0377);
686*38103Sbostic 		printf("%s@(%d,%c%D:%c)", aregs[reg], disp,
687*38103Sbostic 		    (index&0100000)?'a':'d',(index>>12)&07,
688*38103Sbostic 		    (index&04000)?'l':'w');
689*38103Sbostic 	    }
690*38103Sbostic 	    break;
691*38103Sbostic 
692*38103Sbostic 	case 7:
693*38103Sbostic 	    switch ((int)(reg)) {
694*38103Sbostic 		case 0:
695*38103Sbostic 		    instread(w);
696*38103Sbostic 		    if (printing) {
697*38103Sbostic 			index = w;
698*38103Sbostic 			psymoff(index);
699*38103Sbostic 		    }
700*38103Sbostic 		    break;
701*38103Sbostic 
702*38103Sbostic 		case 1:
703*38103Sbostic 		    instread(l);
704*38103Sbostic 		    if (printing) {
705*38103Sbostic 			index = l;
706*38103Sbostic 			psymoff(index);
707*38103Sbostic 		    }
708*38103Sbostic 		    break;
709*38103Sbostic 
710*38103Sbostic 		case 2:
711*38103Sbostic 		    instread(w);
712*38103Sbostic 		    if (printing) {
713*38103Sbostic 			disp = w;
714*38103Sbostic 			psymoff(disp + instaddr);
715*38103Sbostic 		    }
716*38103Sbostic 		    break;
717*38103Sbostic 
718*38103Sbostic 		case 3:
719*38103Sbostic 		    instread(w);
720*38103Sbostic 		    if (printing) {
721*38103Sbostic 			index = w;
722*38103Sbostic 			disp = (char)(index&0377);
723*38103Sbostic 			printf("pc@(%D,%c%D:%c)", disp,
724*38103Sbostic 			    (index&0100000)?'a':'d',(index>>12)&07,
725*38103Sbostic 			    (index&04000)?'l':'w');
726*38103Sbostic 		    }
727*38103Sbostic 		    break;
728*38103Sbostic 
729*38103Sbostic 		case 4:
730*38103Sbostic 		    switch (size) {
731*38103Sbostic 			case sizeof(b):
732*38103Sbostic 			    instread(w);
733*38103Sbostic 			    index = (w&0xff);
734*38103Sbostic 			    break;
735*38103Sbostic 
736*38103Sbostic 			case sizeof(w):
737*38103Sbostic 			    instread(w);
738*38103Sbostic 			    index = w;
739*38103Sbostic 			    break;
740*38103Sbostic 
741*38103Sbostic 			case sizeof(l):
742*38103Sbostic 			    instread(l);
743*38103Sbostic 			    index = l;
744*38103Sbostic 			    break;
745*38103Sbostic 
746*38103Sbostic 			default:
747*38103Sbostic 			    if (printing) {
748*38103Sbostic 			    	printf("unexpected size %d in printea\n", size);
749*38103Sbostic 			    }
750*38103Sbostic 			    instread(l);
751*38103Sbostic 			    index = l;
752*38103Sbostic 			    break;
753*38103Sbostic 		    }
754*38103Sbostic 		    if (printing) {
755*38103Sbostic 			printf(IMDF, index);
756*38103Sbostic 		    }
757*38103Sbostic 		    break;
758*38103Sbostic 
759*38103Sbostic 		default:
760*38103Sbostic 		    if (printing) {
761*38103Sbostic 			printf("???");
762*38103Sbostic 		    }
763*38103Sbostic 		    break;
764*38103Sbostic 	    }
765*38103Sbostic 	    break;
766*38103Sbostic 
767*38103Sbostic 	default:
768*38103Sbostic 	    if (printing) {
769*38103Sbostic 		printf("???");
770*38103Sbostic 	    }
771*38103Sbostic 	    break;
772*38103Sbostic     }
773*38103Sbostic }
774*38103Sbostic 
775*38103Sbostic private printEA(ea, size)
776*38103Sbostic long ea;
777*38103Sbostic int size;
778*38103Sbostic {
779*38103Sbostic     printea((ea>>3)&07, ea&07, size);
780*38103Sbostic }
781*38103Sbostic 
782*38103Sbostic private mapsize(inst)
783*38103Sbostic register long inst;
784*38103Sbostic {
785*38103Sbostic     int m;
786*38103Sbostic 
787*38103Sbostic     inst >>= 6;
788*38103Sbostic     inst &= 03;
789*38103Sbostic     switch (inst) {
790*38103Sbostic 	case 0:
791*38103Sbostic 	    m = 1;
792*38103Sbostic 	    break;
793*38103Sbostic 
794*38103Sbostic 	case 1:
795*38103Sbostic 	    m = 2;
796*38103Sbostic 	    break;
797*38103Sbostic 
798*38103Sbostic 	case 2:
799*38103Sbostic 	    m = 4;
800*38103Sbostic 	    break;
801*38103Sbostic 
802*38103Sbostic 	default:
803*38103Sbostic 	    m = -1;
804*38103Sbostic 	    break;
805*38103Sbostic     }
806*38103Sbostic     return m;
807*38103Sbostic }
808*38103Sbostic 
809*38103Sbostic private char suffix(size)
810*38103Sbostic int size;
811*38103Sbostic {
812*38103Sbostic     char c;
813*38103Sbostic 
814*38103Sbostic     switch (size) {
815*38103Sbostic 	case 1:
816*38103Sbostic 	    c = 'b';
817*38103Sbostic 	    break;
818*38103Sbostic 
819*38103Sbostic 	case 2:
820*38103Sbostic 	    c = 'w';
821*38103Sbostic 	    break;
822*38103Sbostic 
823*38103Sbostic 	case 4:
824*38103Sbostic 	    c = 'l';
825*38103Sbostic 	    break;
826*38103Sbostic 
827*38103Sbostic 	default:
828*38103Sbostic 	    panic("bad size %d in suffix", size);
829*38103Sbostic     }
830*38103Sbostic     return c;
831*38103Sbostic }
832*38103Sbostic 
833*38103Sbostic /*
834*38103Sbostic  * Print an address offset.  Eventually this should attempt to be symbolic,
835*38103Sbostic  * but for now its just printed in hex.
836*38103Sbostic  */
837*38103Sbostic 
838*38103Sbostic private psymoff (off)
839*38103Sbostic Word off;
840*38103Sbostic {
841*38103Sbostic     Symbol f;
842*38103Sbostic 
843*38103Sbostic     f = whatblock((Address) (off + FUNCOFFSET));
844*38103Sbostic     if (codeloc(f) == off + FUNCOFFSET) {
845*38103Sbostic 	printf("%s", symname(f));
846*38103Sbostic     } else {
847*38103Sbostic 	printf("0x%x", off);
848*38103Sbostic     }
849*38103Sbostic }
850*38103Sbostic 
851*38103Sbostic /*
852*38103Sbostic  * Instruction class specific routines.
853*38103Sbostic  */
854*38103Sbostic 
855*38103Sbostic public omove(inst, s)
856*38103Sbostic long inst;
857*38103Sbostic String s;
858*38103Sbostic {
859*38103Sbostic     register int c;
860*38103Sbostic     int size;
861*38103Sbostic 
862*38103Sbostic     c = s[0];
863*38103Sbostic     if (printing) {
864*38103Sbostic 	printf("\tmov%c\t", c);
865*38103Sbostic     }
866*38103Sbostic     size = ((c == 'b') ? 1 : (c == 'w') ? 2 : 4);
867*38103Sbostic     printea((inst>>3)&07, inst&07, size);
868*38103Sbostic     if (printing) {
869*38103Sbostic 	printf(",");
870*38103Sbostic     }
871*38103Sbostic     printea((inst>>6)&07, (inst>>9)&07, size);
872*38103Sbostic }
873*38103Sbostic 
874*38103Sbostic /*
875*38103Sbostic  * Two types: bsr (4 bytes) and bsrs (2 bytes)
876*38103Sbostic  */
877*38103Sbostic 
878*38103Sbostic public obranch(inst, dummy)
879*38103Sbostic long inst;
880*38103Sbostic {
881*38103Sbostic     long disp;
882*38103Sbostic     String s;
883*38103Sbostic     short w;
884*38103Sbostic     Address startingaddr;	/* address of branch instruction */
885*38103Sbostic     int branchtype;		/* type of branch (0 = unconditional) */
886*38103Sbostic     Address dest;
887*38103Sbostic     Address retaddr;		/* for bsr instruction */
888*38103Sbostic 
889*38103Sbostic     startingaddr = instaddr - 2;
890*38103Sbostic     disp = inst&0377;
891*38103Sbostic     s = "s ";
892*38103Sbostic     if (disp == 0) {
893*38103Sbostic 	retaddr = startingaddr + 4;
894*38103Sbostic     } else {
895*38103Sbostic 	retaddr = startingaddr + 2;
896*38103Sbostic     }
897*38103Sbostic     if (disp > 127) {
898*38103Sbostic 	disp |= ~0377;
899*38103Sbostic     } else if (disp == 0){
900*38103Sbostic 	s = " ";
901*38103Sbostic 	instread(w);
902*38103Sbostic 	disp = w;
903*38103Sbostic     }
904*38103Sbostic     branchtype = (int)((inst>>8)&017);
905*38103Sbostic     dest = startingaddr + 2 + disp;
906*38103Sbostic     if (printing) {
907*38103Sbostic 	printf("\tb%s%s\t", bname[branchtype], s);
908*38103Sbostic 	psymoff(dest);
909*38103Sbostic     }
910*38103Sbostic     if (following) {
911*38103Sbostic 	/*
912*38103Sbostic 	 * If we're to follow the dynamic flow of instructions,
913*38103Sbostic 	 * we must see where the branch leads.  A branchtype of 0
914*38103Sbostic 	 * indicates an unconditional branch which we simply take
915*38103Sbostic 	 * as the new instruction address.  For a conditional branch,
916*38103Sbostic 	 * we continue execution up to the current address, single step,
917*38103Sbostic 	 * and keep going.
918*38103Sbostic 	 */
919*38103Sbostic 	if (branchtype == 0) {
920*38103Sbostic 	    instaddr = dest;
921*38103Sbostic 	} else if (branchtype == 01) {		/* bsr */
922*38103Sbostic 	    if (followcalls) {
923*38103Sbostic 		steppast(startingaddr);
924*38103Sbostic 		curfunc = whatblock(pc, true);
925*38103Sbostic 		if (not isbperr()) {
926*38103Sbostic 		    printstatus();
927*38103Sbostic 		    /* NOTREACHED */
928*38103Sbostic 		}
929*38103Sbostic 		bpact();
930*38103Sbostic 		if (nosource(curfunc) and canskip(curfunc) and
931*38103Sbostic 		  nlhdr.nlines != 0) {
932*38103Sbostic 		    stepto(retaddr);
933*38103Sbostic 		    instaddr = pc;
934*38103Sbostic 		    bpact();
935*38103Sbostic 		} else {
936*38103Sbostic 		    callnews(/* iscall = */ true);
937*38103Sbostic 		}
938*38103Sbostic 	    }
939*38103Sbostic 	} else {
940*38103Sbostic 	    steppast(startingaddr);
941*38103Sbostic 	}
942*38103Sbostic     }
943*38103Sbostic }
944*38103Sbostic 
945*38103Sbostic public odbcc(inst, form)
946*38103Sbostic long inst;
947*38103Sbostic String form;
948*38103Sbostic {
949*38103Sbostic     long disp;
950*38103Sbostic     short w;
951*38103Sbostic 
952*38103Sbostic     instread(w);
953*38103Sbostic     if (printing) {
954*38103Sbostic     	printf(form, dbname[(int)((inst>>8)&017)], inst&07);
955*38103Sbostic 	psymoff(w + sizeof(w));
956*38103Sbostic     }
957*38103Sbostic }
958*38103Sbostic 
959*38103Sbostic public oscc(inst, dummy)
960*38103Sbostic long inst;
961*38103Sbostic long dummy;
962*38103Sbostic {
963*38103Sbostic     if (printing) {
964*38103Sbostic 	printf("\ts%s\t", cname[(int)((inst>>8)&017)]);
965*38103Sbostic     }
966*38103Sbostic     printea((inst>>3)&07, inst&07, 1);
967*38103Sbostic }
968*38103Sbostic 
969*38103Sbostic public biti(inst, dummy)
970*38103Sbostic long inst;
971*38103Sbostic long dummy;
972*38103Sbostic {
973*38103Sbostic     short w;
974*38103Sbostic 
975*38103Sbostic     if (printing) {
976*38103Sbostic 	printf("\t%s\t", bit[(int)((inst>>6)&03)]);
977*38103Sbostic     }
978*38103Sbostic     if (inst&0x0100) {
979*38103Sbostic 	if (printing) {
980*38103Sbostic 	    printf("d%D,", inst>>9);
981*38103Sbostic 	}
982*38103Sbostic     } else {
983*38103Sbostic 	instread(w);
984*38103Sbostic 	if (printing) {
985*38103Sbostic 	    printf(IMDF, w);
986*38103Sbostic 	    printf(",");
987*38103Sbostic 	}
988*38103Sbostic     }
989*38103Sbostic     printEA(inst);
990*38103Sbostic }
991*38103Sbostic 
992*38103Sbostic public opmode(inst, opcode)
993*38103Sbostic long inst;
994*38103Sbostic long opcode;
995*38103Sbostic {
996*38103Sbostic     register int opmode;
997*38103Sbostic     register int reg;
998*38103Sbostic     int size;
999*38103Sbostic 
1000*38103Sbostic     opmode = (int)((inst>>6) & 07);
1001*38103Sbostic     reg = (int)((inst>>9) & 07);
1002*38103Sbostic     if (opmode == 0 or opmode == 4) {
1003*38103Sbostic 	size = 1;
1004*38103Sbostic     } else if (opmode == 1 or opmode == 3 or opmode == 5) {
1005*38103Sbostic 	size = 2;
1006*38103Sbostic     } else {
1007*38103Sbostic 	size = 4;
1008*38103Sbostic     }
1009*38103Sbostic     if (printing) {
1010*38103Sbostic 	printf("\t%s%c\t", opcode, suffix(size));
1011*38103Sbostic     }
1012*38103Sbostic     if (opmode >= 4 and opmode <= 6) {
1013*38103Sbostic 	if (printing) {
1014*38103Sbostic 	    printf("d%d,", reg);
1015*38103Sbostic 	}
1016*38103Sbostic 	printea((inst>>3)&07, inst&07, size);
1017*38103Sbostic     } else {
1018*38103Sbostic 	printea((inst>>3)&07, inst&07, size);
1019*38103Sbostic 	if (printing) {
1020*38103Sbostic 	    printf(",%c%d",(opmode<=2) ? 'd' : 'a', reg);
1021*38103Sbostic 	}
1022*38103Sbostic     }
1023*38103Sbostic }
1024*38103Sbostic 
1025*38103Sbostic public shroi(inst, ds)
1026*38103Sbostic long inst;
1027*38103Sbostic String ds;
1028*38103Sbostic {
1029*38103Sbostic     int rx, ry;
1030*38103Sbostic     String opcode;
1031*38103Sbostic 
1032*38103Sbostic     if ((inst & 0xC0) == 0xC0) {
1033*38103Sbostic 	opcode = shro[(int)((inst>>9)&03)];
1034*38103Sbostic 	if (printing) {
1035*38103Sbostic 	    printf("\t%s%s\t", opcode, ds);
1036*38103Sbostic 	}
1037*38103Sbostic 	printEA(inst);
1038*38103Sbostic     } else {
1039*38103Sbostic 	if (printing) {
1040*38103Sbostic 	    opcode = shro[(int)((inst>>3)&03)];
1041*38103Sbostic 	    printf("\t%s%s%c\t", opcode, ds, suffix(mapsize(inst)));
1042*38103Sbostic 	    rx = (int)((inst>>9)&07); ry = (int)(inst&07);
1043*38103Sbostic 	    if ((inst>>5)&01) {
1044*38103Sbostic 		printf("d%d,d%d", rx, ry);
1045*38103Sbostic 	    } else {
1046*38103Sbostic 		printf(IMDF, (rx ? rx : 8));
1047*38103Sbostic 		printf(",d%d", ry);
1048*38103Sbostic 	    }
1049*38103Sbostic 	}
1050*38103Sbostic     }
1051*38103Sbostic }
1052*38103Sbostic 
1053*38103Sbostic public oimmed(inst, opcode)
1054*38103Sbostic long inst;
1055*38103Sbostic register String opcode;
1056*38103Sbostic {
1057*38103Sbostic     register int size;
1058*38103Sbostic     long const;
1059*38103Sbostic     short w;
1060*38103Sbostic 
1061*38103Sbostic     size = mapsize(inst);
1062*38103Sbostic     if (size > 0) {
1063*38103Sbostic 	if (size == 4) {
1064*38103Sbostic 	    instread(const);
1065*38103Sbostic 	} else {
1066*38103Sbostic 	    instread(w);
1067*38103Sbostic 	    const = w;
1068*38103Sbostic 	}
1069*38103Sbostic 	if (printing) {
1070*38103Sbostic 	    printf("\t%s%c\t", opcode, suffix(size));
1071*38103Sbostic 	    printf(IMDF, const);
1072*38103Sbostic 	    printf(",");
1073*38103Sbostic 	}
1074*38103Sbostic 	printEA(inst, size);
1075*38103Sbostic     } else {
1076*38103Sbostic 	if (printing) {
1077*38103Sbostic 	    printf("\tbadop");
1078*38103Sbostic 	}
1079*38103Sbostic     }
1080*38103Sbostic }
1081*38103Sbostic 
1082*38103Sbostic public oreg(inst, opcode)
1083*38103Sbostic long inst;
1084*38103Sbostic register String opcode;
1085*38103Sbostic {
1086*38103Sbostic     if (printing) {
1087*38103Sbostic 	printf(opcode, (inst & 07));
1088*38103Sbostic     }
1089*38103Sbostic }
1090*38103Sbostic 
1091*38103Sbostic public extend(inst, opcode)
1092*38103Sbostic long inst;
1093*38103Sbostic String opcode;
1094*38103Sbostic {
1095*38103Sbostic     register int size;
1096*38103Sbostic     int ry, rx;
1097*38103Sbostic     char c;
1098*38103Sbostic 
1099*38103Sbostic     if (printing) {
1100*38103Sbostic 	size = mapsize(inst);
1101*38103Sbostic 	ry = (inst&07);
1102*38103Sbostic 	rx = ((inst>>9)&07);
1103*38103Sbostic 	c = ((inst & 0x1000) ? suffix(size) : ' ');
1104*38103Sbostic 	printf("\t%s%c\t", opcode, c);
1105*38103Sbostic 	if (opcode[0] == 'e') {
1106*38103Sbostic 	    if (inst & 0x0080) {
1107*38103Sbostic 		printf("d%D,a%D", rx, ry);
1108*38103Sbostic 	    } else if (inst & 0x0008) {
1109*38103Sbostic 		printf("a%D,a%D", rx, ry);
1110*38103Sbostic 	    } else {
1111*38103Sbostic 		printf("d%D,d%D", rx, ry);
1112*38103Sbostic 	    }
1113*38103Sbostic 	} else if ((inst & 0xF000) == 0xB000) {
1114*38103Sbostic 	    printf("a%D@+,a%D@+", ry, rx);
1115*38103Sbostic 	} else if (inst & 0x8) {
1116*38103Sbostic 	    printf("a%D@-,a%D@-", ry, rx);
1117*38103Sbostic 	} else {
1118*38103Sbostic 	    printf("d%D,d%D", ry, rx);
1119*38103Sbostic 	}
1120*38103Sbostic     }
1121*38103Sbostic }
1122*38103Sbostic 
1123*38103Sbostic public olink(inst, dummy)
1124*38103Sbostic long inst;
1125*38103Sbostic long dummy;
1126*38103Sbostic {
1127*38103Sbostic     short w;
1128*38103Sbostic 
1129*38103Sbostic     instread(w);
1130*38103Sbostic     if (printing) {
1131*38103Sbostic 	printf("\tlink\ta%D,", inst&07);
1132*38103Sbostic 	printf(IMDF, w);
1133*38103Sbostic     }
1134*38103Sbostic }
1135*38103Sbostic 
1136*38103Sbostic public otrap(inst, dummy)
1137*38103Sbostic long inst;
1138*38103Sbostic {
1139*38103Sbostic     if (printing) {
1140*38103Sbostic 	printf("\ttrap\t");
1141*38103Sbostic 	printf(IMDF, inst&017);
1142*38103Sbostic     }
1143*38103Sbostic }
1144*38103Sbostic 
1145*38103Sbostic public oneop(inst, opcode)
1146*38103Sbostic long inst;
1147*38103Sbostic register String opcode;
1148*38103Sbostic {
1149*38103Sbostic     if (printing) {
1150*38103Sbostic 	printf("\t%s",opcode);
1151*38103Sbostic     }
1152*38103Sbostic     printEA(inst);
1153*38103Sbostic }
1154*38103Sbostic 
1155*38103Sbostic public jsrop(inst, opcode)
1156*38103Sbostic long inst;
1157*38103Sbostic register String opcode;
1158*38103Sbostic {
1159*38103Sbostic     Address startingaddr;	/* beginning of jsr instruction */
1160*38103Sbostic     Address retaddr; /* can't call return_addr (frame not set up yet) */
1161*38103Sbostic 
1162*38103Sbostic     startingaddr = instaddr - 2;
1163*38103Sbostic     switch ((inst >> 3) & 07) {
1164*38103Sbostic 	case 2:
1165*38103Sbostic 	    retaddr = instaddr;		/* two byte instruction */
1166*38103Sbostic 	    break;
1167*38103Sbostic 	case 5:
1168*38103Sbostic 	case 6:
1169*38103Sbostic 	    retaddr = instaddr + 2;	/* four byte instruction */
1170*38103Sbostic 	    break;
1171*38103Sbostic 	case 7:
1172*38103Sbostic 	default:
1173*38103Sbostic 	    switch (inst & 07) {
1174*38103Sbostic 		case 0:
1175*38103Sbostic 		case 2:
1176*38103Sbostic 		case 3:
1177*38103Sbostic 		    retaddr = instaddr + 2;
1178*38103Sbostic 		    break;
1179*38103Sbostic 		case 1:
1180*38103Sbostic 		default:
1181*38103Sbostic 		    retaddr = instaddr + 4;	/* six byte instruction */
1182*38103Sbostic 		    break;
1183*38103Sbostic 	    }
1184*38103Sbostic 	    break;
1185*38103Sbostic     }
1186*38103Sbostic     if (printing) {
1187*38103Sbostic 	printf("\t%s",opcode);
1188*38103Sbostic     }
1189*38103Sbostic     printEA(inst);
1190*38103Sbostic     if (following and followcalls) {
1191*38103Sbostic 	steppast(startingaddr);
1192*38103Sbostic 	curfunc = whatblock(pc, true);
1193*38103Sbostic 	if (not isbperr()) {
1194*38103Sbostic 	    printstatus();
1195*38103Sbostic 	    /* NOTREACHED */
1196*38103Sbostic 	}
1197*38103Sbostic 	bpact();
1198*38103Sbostic 	if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) {
1199*38103Sbostic 	    stepto(retaddr);
1200*38103Sbostic 	    instaddr = pc;
1201*38103Sbostic 	    bpact();
1202*38103Sbostic 	} else {
1203*38103Sbostic 	    callnews(/* iscall = */ true);
1204*38103Sbostic 	}
1205*38103Sbostic     }
1206*38103Sbostic }
1207*38103Sbostic 
1208*38103Sbostic public jmpop(inst, opcode)
1209*38103Sbostic long inst;
1210*38103Sbostic register String opcode;
1211*38103Sbostic {
1212*38103Sbostic     Address startingaddr;	/* beginning of jump instruction */
1213*38103Sbostic 
1214*38103Sbostic     startingaddr = instaddr - 2;
1215*38103Sbostic     if (printing) {
1216*38103Sbostic 	printf("\t%s",opcode);
1217*38103Sbostic     }
1218*38103Sbostic     printEA(inst);
1219*38103Sbostic     if (following) {
1220*38103Sbostic 	steppast(startingaddr);
1221*38103Sbostic     }
1222*38103Sbostic }
1223*38103Sbostic 
1224*38103Sbostic public pregmask(mask)
1225*38103Sbostic register int mask;
1226*38103Sbostic {
1227*38103Sbostic     register int i;
1228*38103Sbostic     register int flag = 0;
1229*38103Sbostic 
1230*38103Sbostic     if (printing) {
1231*38103Sbostic 	printf("#<");
1232*38103Sbostic 	for (i=0; i<16; i++) {
1233*38103Sbostic 	    if (mask&1) {
1234*38103Sbostic 		if (flag) {
1235*38103Sbostic 		    printf(",");
1236*38103Sbostic 		} else {
1237*38103Sbostic 		    ++flag;
1238*38103Sbostic 		}
1239*38103Sbostic 		printf("%c%d",(i<8) ? 'd' : 'a', i&07);
1240*38103Sbostic 	    }
1241*38103Sbostic 	    mask >>= 1;
1242*38103Sbostic 	}
1243*38103Sbostic 	printf(">");
1244*38103Sbostic     }
1245*38103Sbostic }
1246*38103Sbostic 
1247*38103Sbostic public omovem(inst, dummy)
1248*38103Sbostic long inst;
1249*38103Sbostic long dummy;
1250*38103Sbostic {
1251*38103Sbostic     register int i, list, mask;
1252*38103Sbostic     register int reglist;
1253*38103Sbostic     short w;
1254*38103Sbostic 
1255*38103Sbostic     i = 0;
1256*38103Sbostic     list = 0;
1257*38103Sbostic     mask = 0100000;
1258*38103Sbostic     instread(w);
1259*38103Sbostic     reglist = w;
1260*38103Sbostic     if ((inst & 070) == 040) {	/* predecrement */
1261*38103Sbostic 	for (i = 15; i > 0; i -= 2) {
1262*38103Sbostic 	    list |= ((mask & reglist) >> i);
1263*38103Sbostic 	    mask >>= 1;
1264*38103Sbostic 	}
1265*38103Sbostic 	for (i = 1; i < 16; i += 2) {
1266*38103Sbostic 	    list |= ((mask & reglist) << i);
1267*38103Sbostic 	    mask >>= 1;
1268*38103Sbostic 	}
1269*38103Sbostic 	reglist = list;
1270*38103Sbostic     }
1271*38103Sbostic     if (printing) {
1272*38103Sbostic 	printf("\tmovem%c\t",(inst&100)?'l':'w');
1273*38103Sbostic     }
1274*38103Sbostic     if (inst&02000) {
1275*38103Sbostic 	printEA(inst);
1276*38103Sbostic 	if (printing) {
1277*38103Sbostic 	    printf(",");
1278*38103Sbostic 	}
1279*38103Sbostic 	pregmask(reglist);
1280*38103Sbostic     } else {
1281*38103Sbostic 	pregmask(reglist);
1282*38103Sbostic 	if (printing) {
1283*38103Sbostic 	    printf(",");
1284*38103Sbostic 	}
1285*38103Sbostic 	printEA(inst);
1286*38103Sbostic     }
1287*38103Sbostic }
1288*38103Sbostic 
1289*38103Sbostic public ochk(inst, opcode)
1290*38103Sbostic long inst;
1291*38103Sbostic register String opcode;
1292*38103Sbostic {
1293*38103Sbostic     if (printing) {
1294*38103Sbostic 	printf("\t%s\t", opcode);
1295*38103Sbostic     }
1296*38103Sbostic     printEA(inst, sizeof(Byte));
1297*38103Sbostic     if (printing) {
1298*38103Sbostic 	printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07);
1299*38103Sbostic     }
1300*38103Sbostic }
1301*38103Sbostic 
1302*38103Sbostic public soneop(inst, opcode)
1303*38103Sbostic long inst;
1304*38103Sbostic register String opcode;
1305*38103Sbostic {
1306*38103Sbostic     register int size;
1307*38103Sbostic 
1308*38103Sbostic     size = mapsize(inst);
1309*38103Sbostic     if (size > 0) {
1310*38103Sbostic 	if (printing) {
1311*38103Sbostic 	    printf("\t%s%c\t", opcode, suffix(size));
1312*38103Sbostic 	}
1313*38103Sbostic 	printEA(inst);
1314*38103Sbostic     } else {
1315*38103Sbostic 	if (printing) {
1316*38103Sbostic 	    printf("\tbadop");
1317*38103Sbostic 	}
1318*38103Sbostic     }
1319*38103Sbostic }
1320*38103Sbostic 
1321*38103Sbostic public oquick(inst, opcode)
1322*38103Sbostic long inst;
1323*38103Sbostic register String opcode;
1324*38103Sbostic {
1325*38103Sbostic     register int size;
1326*38103Sbostic     register int data;
1327*38103Sbostic 
1328*38103Sbostic     size = mapsize(inst);
1329*38103Sbostic     data = (int)((inst>>9) & 07);
1330*38103Sbostic     if (data == 0) {
1331*38103Sbostic 	data = 8;
1332*38103Sbostic     }
1333*38103Sbostic     if (size > 0) {
1334*38103Sbostic 	if (printing) {
1335*38103Sbostic 	    printf("\t%s%c\t", opcode, suffix(size));
1336*38103Sbostic 	    printf(IMDF, data);
1337*38103Sbostic 	    printf(",");
1338*38103Sbostic 	}
1339*38103Sbostic 	printEA(inst);
1340*38103Sbostic     } else {
1341*38103Sbostic 	if (printing) {
1342*38103Sbostic 	    printf("\tbadop");
1343*38103Sbostic 	}
1344*38103Sbostic     }
1345*38103Sbostic }
1346*38103Sbostic 
1347*38103Sbostic public omoveq(inst, dummy)
1348*38103Sbostic long inst;
1349*38103Sbostic long dummy;
1350*38103Sbostic {
1351*38103Sbostic     register int data;
1352*38103Sbostic 
1353*38103Sbostic     if (printing) {
1354*38103Sbostic 	data = (int)(inst & 0377);
1355*38103Sbostic 	if (data > 127) {
1356*38103Sbostic 	    data |= ~0377;
1357*38103Sbostic 	}
1358*38103Sbostic 	printf("\tmoveq\t");
1359*38103Sbostic 	printf(IMDF, data);
1360*38103Sbostic 	printf(",d%D", (inst>>9)&07);
1361*38103Sbostic     }
1362*38103Sbostic }
1363*38103Sbostic 
1364*38103Sbostic public oprint(inst, opcode)
1365*38103Sbostic long inst;
1366*38103Sbostic register String opcode;
1367*38103Sbostic {
1368*38103Sbostic     if (printing) {
1369*38103Sbostic 	printf("\t%s",opcode);
1370*38103Sbostic     }
1371*38103Sbostic }
1372*38103Sbostic 
1373*38103Sbostic public ostop(inst, opcode)
1374*38103Sbostic long inst;
1375*38103Sbostic register String opcode;
1376*38103Sbostic {
1377*38103Sbostic     short w;
1378*38103Sbostic 
1379*38103Sbostic     instread(w);
1380*38103Sbostic     if (printing) {
1381*38103Sbostic 	printf(opcode, w);
1382*38103Sbostic     }
1383*38103Sbostic }
1384*38103Sbostic 
1385*38103Sbostic public orts(inst, opcode)
1386*38103Sbostic long inst;
1387*38103Sbostic register String opcode;
1388*38103Sbostic {
1389*38103Sbostic     Address addr;
1390*38103Sbostic 
1391*38103Sbostic     if (following) {
1392*38103Sbostic 	callnews(/* iscall = */ false);
1393*38103Sbostic     	if (inst_tracing) {
1394*38103Sbostic 	    addr = currtnaddr();
1395*38103Sbostic     	} else {
1396*38103Sbostic 	    addr = return_addr();
1397*38103Sbostic 	    if (addr == 0) {
1398*38103Sbostic 		stepto(instaddr - 2);
1399*38103Sbostic 		addr = currtnaddr();
1400*38103Sbostic 	    }
1401*38103Sbostic 	}
1402*38103Sbostic 	stepto(addr);
1403*38103Sbostic 	instaddr = pc;
1404*38103Sbostic     }
1405*38103Sbostic     if (printing) {
1406*38103Sbostic 	printf("\t%s",opcode);
1407*38103Sbostic     }
1408*38103Sbostic }
1409*38103Sbostic 
1410*38103Sbostic /*
1411*38103Sbostic  * Not used by C compiler; does an rts but before doing so, pops
1412*38103Sbostic  * arg bytes from the stack.
1413*38103Sbostic  */
1414*38103Sbostic 
1415*38103Sbostic public ortspop(inst, opcode)
1416*38103Sbostic long inst;
1417*38103Sbostic register String opcode;
1418*38103Sbostic {
1419*38103Sbostic     Address addr;
1420*38103Sbostic     short w;
1421*38103Sbostic 
1422*38103Sbostic     instread(w);
1423*38103Sbostic     if (following) {
1424*38103Sbostic 	callnews(/* iscall = */ false);
1425*38103Sbostic     	if (inst_tracing) {
1426*38103Sbostic 	    addr = currtnaddr();
1427*38103Sbostic     	} else {
1428*38103Sbostic 	    addr = return_addr();
1429*38103Sbostic 	}
1430*38103Sbostic 	stepto(addr);
1431*38103Sbostic 	instaddr = pc;
1432*38103Sbostic     }
1433*38103Sbostic     if (printing) {
1434*38103Sbostic 	printf(opcode, w);
1435*38103Sbostic     }
1436*38103Sbostic }
1437*38103Sbostic 
1438*38103Sbostic public omovs(inst, opcode)
1439*38103Sbostic long inst;
1440*38103Sbostic String opcode;
1441*38103Sbostic {
1442*38103Sbostic     register int size;
1443*38103Sbostic     register unsigned int controlword;
1444*38103Sbostic     short w;
1445*38103Sbostic 
1446*38103Sbostic     size = mapsize(inst);
1447*38103Sbostic     instread(w);
1448*38103Sbostic     controlword = w >> 11;
1449*38103Sbostic     if (printing) {
1450*38103Sbostic 	printf("\t%s%c\t", opcode, suffix(size));
1451*38103Sbostic     }
1452*38103Sbostic     if (controlword & 1){
1453*38103Sbostic 	controlword >>= 1;
1454*38103Sbostic 	if (printing) {
1455*38103Sbostic 	    printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 );
1456*38103Sbostic 	}
1457*38103Sbostic 	printEA(inst&0xff, size);
1458*38103Sbostic     } else {
1459*38103Sbostic 	controlword >>= 1;
1460*38103Sbostic 	printEA(inst&0xff, size);
1461*38103Sbostic 	if (printing) {
1462*38103Sbostic 	    printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7);
1463*38103Sbostic 	}
1464*38103Sbostic     }
1465*38103Sbostic }
1466*38103Sbostic 
1467*38103Sbostic public omovc(inst, opcode)
1468*38103Sbostic long inst;
1469*38103Sbostic String opcode;
1470*38103Sbostic {
1471*38103Sbostic     register unsigned int controlword;
1472*38103Sbostic     String creg;
1473*38103Sbostic     short w;
1474*38103Sbostic 
1475*38103Sbostic     instread(w);
1476*38103Sbostic     if (printing) {
1477*38103Sbostic 	controlword = w;
1478*38103Sbostic 	switch (controlword & 0xfff) {
1479*38103Sbostic 	    case 0:
1480*38103Sbostic 		creg = "sfc";
1481*38103Sbostic 		break;
1482*38103Sbostic 
1483*38103Sbostic 	    case 1:
1484*38103Sbostic 		creg = "dfc";
1485*38103Sbostic 		break;
1486*38103Sbostic 
1487*38103Sbostic 	    case 0x800:
1488*38103Sbostic 		creg = "usp";
1489*38103Sbostic 		break;
1490*38103Sbostic 
1491*38103Sbostic 	    case 0x801:
1492*38103Sbostic 		creg = "vbr";
1493*38103Sbostic 		break;
1494*38103Sbostic 
1495*38103Sbostic 	    default:
1496*38103Sbostic 		creg = "???";
1497*38103Sbostic 		break;
1498*38103Sbostic 	}
1499*38103Sbostic 	controlword >>= 12;
1500*38103Sbostic 	if (inst & 1){
1501*38103Sbostic 	    printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s",
1502*38103Sbostic 		opcode, controlword&7, creg );
1503*38103Sbostic 	} else {
1504*38103Sbostic 	    printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D",
1505*38103Sbostic 		opcode, creg, controlword&7 );
1506*38103Sbostic 	}
1507*38103Sbostic     }
1508*38103Sbostic }
1509*38103Sbostic 
1510*38103Sbostic /*
1511*38103Sbostic  * Compute the next address that will be executed from the given one.
1512*38103Sbostic  * If "isnext" is true then consider a procedure call as straight line code.
1513*38103Sbostic  *
1514*38103Sbostic  * Unconditional branches we just follow, for conditional branches
1515*38103Sbostic  * we continue execution to the current location and then single step
1516*38103Sbostic  * the machine.
1517*38103Sbostic  */
1518*38103Sbostic 
1519*38103Sbostic public Address nextaddr(startaddr, isnext)
1520*38103Sbostic Address startaddr;
1521*38103Sbostic Boolean isnext;
1522*38103Sbostic {
1523*38103Sbostic     Optab *o;
1524*38103Sbostic     short inst;
1525*38103Sbostic 
1526*38103Sbostic     instaddr = usignal(process);
1527*38103Sbostic     if (instaddr == 0 or instaddr == 1) {
1528*38103Sbostic 	following = true;
1529*38103Sbostic 	followcalls = (Boolean) (not isnext);
1530*38103Sbostic 	printing = false;
1531*38103Sbostic 	iread(&inst, startaddr, sizeof(inst));
1532*38103Sbostic 	instaddr = startaddr + sizeof(inst);
1533*38103Sbostic 	o = decode(inst, startaddr);
1534*38103Sbostic 	if (o->mask == 0) {
1535*38103Sbostic 	    fprintf(stderr,
1536*38103Sbostic 		"[internal error: undecodable op at 0x%x]\n", startaddr);
1537*38103Sbostic 	    fflush(stderr);
1538*38103Sbostic 	} else {
1539*38103Sbostic 	    (*o->opfun)(inst, o->farg);
1540*38103Sbostic 	}
1541*38103Sbostic 	following = false;
1542*38103Sbostic     }
1543*38103Sbostic     return instaddr;
1544*38103Sbostic }
1545*38103Sbostic 
1546*38103Sbostic /*
1547*38103Sbostic  * Step to the given address and then execute one instruction past it.
1548*38103Sbostic  * Set instaddr to the new instruction address.
1549*38103Sbostic  */
1550*38103Sbostic 
1551*38103Sbostic private steppast(addr)
1552*38103Sbostic Address addr;
1553*38103Sbostic {
1554*38103Sbostic     stepto(addr);
1555*38103Sbostic     pstep(process, DEFSIG);
1556*38103Sbostic     pc = reg(PROGCTR);
1557*38103Sbostic     instaddr = pc;
1558*38103Sbostic }
1559*38103Sbostic 
1560*38103Sbostic /*
1561*38103Sbostic  * Enter a procedure by creating and executing a call instruction.
1562*38103Sbostic  */
1563*38103Sbostic 
1564*38103Sbostic #define CALLSIZE 6	/* size of call instruction */
1565*38103Sbostic 
1566*38103Sbostic public beginproc(p)
1567*38103Sbostic Symbol p;
1568*38103Sbostic {
1569*38103Sbostic     char save[CALLSIZE];
1570*38103Sbostic     struct {
1571*38103Sbostic 	short op;
1572*38103Sbostic 	char addr[sizeof(long)];	/* unaligned long */
1573*38103Sbostic     } call;
1574*38103Sbostic     long dest;
1575*38103Sbostic 
1576*38103Sbostic     pc = CODESTART + 6;
1577*38103Sbostic     iread(save, pc, sizeof(save));
1578*38103Sbostic     call.op = 0x4eb9;			/* jsr */
1579*38103Sbostic     dest = codeloc(p) - FUNCOFFSET;
1580*38103Sbostic     mov(&dest, call.addr, sizeof(call.addr));
1581*38103Sbostic     iwrite(&call, pc, sizeof(call));
1582*38103Sbostic     setreg(PROGCTR, pc);
1583*38103Sbostic     pstep(process, DEFSIG);
1584*38103Sbostic     iwrite(save, pc, sizeof(save));
1585*38103Sbostic     pc = reg(PROGCTR);
1586*38103Sbostic     if (not isbperr()) {
1587*38103Sbostic 	printstatus();
1588*38103Sbostic     }
1589*38103Sbostic     /*
1590*38103Sbostic      * Execute link instruction so the return addr is visible.
1591*38103Sbostic      */
1592*38103Sbostic     pstep(process, DEFSIG);
1593*38103Sbostic     pc = reg(PROGCTR);
1594*38103Sbostic     if (not isbperr()) {
1595*38103Sbostic 	printstatus();
1596*38103Sbostic     }
1597*38103Sbostic }
1598*38103Sbostic 
1599*38103Sbostic /*
1600*38103Sbostic  * Special variables for debugging the kernel.
1601*38103Sbostic  */
1602*38103Sbostic 
1603*38103Sbostic public integer masterpcbb;
1604*38103Sbostic public integer slr;
1605*38103Sbostic public struct pte *sbr;
1606*38103Sbostic private struct pcb pcb;
1607*38103Sbostic 
1608*38103Sbostic public getpcb ()
1609*38103Sbostic {
1610*38103Sbostic     integer i;
1611*38103Sbostic 
1612*38103Sbostic     fseek(corefile, masterpcbb & ~0x80000000, 0);
1613*38103Sbostic     get(corefile, pcb);
1614*38103Sbostic     pcb.pcb_p0lr &= ~AST_CLR;
1615*38103Sbostic     printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
1616*38103Sbostic 	pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
1617*38103Sbostic     );
1618*38103Sbostic #   ifdef sun
1619*38103Sbostic     for (i = 0; i < 14; i++) {
1620*38103Sbostic 	setreg(i, pcb.pcb_regs.val[i]);
1621*38103Sbostic     }
1622*38103Sbostic #   else /* IRIS */
1623*38103Sbostic     for (i = 0; i < 14; i++) {
1624*38103Sbostic 	setreg(i, pcb.pcb_regs[i]);
1625*38103Sbostic     }
1626*38103Sbostic #   endif
1627*38103Sbostic }
1628*38103Sbostic 
1629*38103Sbostic public copyregs (savreg, reg)
1630*38103Sbostic Word savreg[], reg[];
1631*38103Sbostic {
1632*38103Sbostic     reg[0] = savreg[R0];
1633*38103Sbostic     reg[1] = savreg[R1];
1634*38103Sbostic     reg[2] = savreg[R2];
1635*38103Sbostic     reg[3] = savreg[R3];
1636*38103Sbostic     reg[4] = savreg[R4];
1637*38103Sbostic     reg[5] = savreg[R5];
1638*38103Sbostic     reg[6] = savreg[R6];
1639*38103Sbostic     reg[7] = savreg[R7];
1640*38103Sbostic     reg[8] = savreg[AR0];
1641*38103Sbostic     reg[9] = savreg[AR1];
1642*38103Sbostic     reg[10] = savreg[AR2];
1643*38103Sbostic     reg[11] = savreg[AR3];
1644*38103Sbostic     reg[12] = savreg[AR4];
1645*38103Sbostic     reg[13] = savreg[AR5];
1646*38103Sbostic     reg[14] = savreg[AR6];
1647*38103Sbostic     reg[15] = savreg[AR7];
1648*38103Sbostic     reg[PROGCTR] = savreg[PC];
1649*38103Sbostic }
1650*38103Sbostic 
1651*38103Sbostic /*
1652*38103Sbostic  * Map a virtual address to a physical address.
1653*38103Sbostic  * XXX THIS CAN'T BE RIGHT... XXX
1654*38103Sbostic  */
1655*38103Sbostic 
1656*38103Sbostic public Address vmap (addr)
1657*38103Sbostic Address addr;
1658*38103Sbostic {
1659*38103Sbostic     Address r;
1660*38103Sbostic     integer v, n;
1661*38103Sbostic     struct pte pte;
1662*38103Sbostic 
1663*38103Sbostic     r = addr & ~0xc0000000;
1664*38103Sbostic     v = btop(r);
1665*38103Sbostic     switch (addr&0xc0000000) {
1666*38103Sbostic 	case 0xc0000000:
1667*38103Sbostic 	case 0x80000000:
1668*38103Sbostic 	    /*
1669*38103Sbostic 	     * In system space, so get system pte.
1670*38103Sbostic 	     * If it is valid or reclaimable then the physical address
1671*38103Sbostic 	     * is the combination of its page number and the page offset
1672*38103Sbostic 	     * of the original address.
1673*38103Sbostic 	     */
1674*38103Sbostic 	    if (v >= slr) {
1675*38103Sbostic 		error("address %x out of segment", addr);
1676*38103Sbostic 	    }
1677*38103Sbostic 	    r = ((long) (sbr + v)) & ~0x80000000;
1678*38103Sbostic 	    goto simple;
1679*38103Sbostic 
1680*38103Sbostic 	case 0x40000000:
1681*38103Sbostic 	    /*
1682*38103Sbostic 	     * In p1 space, must not be in shadow region.
1683*38103Sbostic 	     */
1684*38103Sbostic 	    if (v < pcb.pcb_p1lr) {
1685*38103Sbostic 		error("address %x out of segment", addr);
1686*38103Sbostic 	    }
1687*38103Sbostic 	    r = (Address) (pcb.pcb_p1br + v);
1688*38103Sbostic 	    break;
1689*38103Sbostic 
1690*38103Sbostic 	case 0x00000000:
1691*38103Sbostic 	    /*
1692*38103Sbostic 	     * In p0 space, must not be off end of region.
1693*38103Sbostic 	     */
1694*38103Sbostic 	    if (v >= pcb.pcb_p0lr) {
1695*38103Sbostic 		error("address %x out of segment", addr);
1696*38103Sbostic 	    }
1697*38103Sbostic 	    r = (Address) (pcb.pcb_p0br + v);
1698*38103Sbostic 	    break;
1699*38103Sbostic 
1700*38103Sbostic 	default:
1701*38103Sbostic 	    /* do nothing */
1702*38103Sbostic 	    break;
1703*38103Sbostic     }
1704*38103Sbostic     /*
1705*38103Sbostic      * For p0/p1 address, user-level page table should be in
1706*38103Sbostic      * kernel virtual memory.  Do second-level indirect by recursing.
1707*38103Sbostic      */
1708*38103Sbostic     if ((r & 0x80000000) == 0) {
1709*38103Sbostic 	error("bad p0br or p1br in pcb");
1710*38103Sbostic     }
1711*38103Sbostic     r = vmap(r);
1712*38103Sbostic simple:
1713*38103Sbostic     /*
1714*38103Sbostic      * "r" is now the address of the pte of the page
1715*38103Sbostic      * we are interested in; get the pte and paste up the physical address.
1716*38103Sbostic      */
1717*38103Sbostic     fseek(corefile, r, 0);
1718*38103Sbostic     n = fread(&pte, sizeof(pte), 1, corefile);
1719*38103Sbostic     if (n != 1) {
1720*38103Sbostic 	error("page table botch (fread at %x returns %d)", r, n);
1721*38103Sbostic     }
1722*38103Sbostic     if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
1723*38103Sbostic 	error("page no valid or reclamable");
1724*38103Sbostic     }
1725*38103Sbostic     return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
1726*38103Sbostic }
1727*38103Sbostic 
1728*38103Sbostic /*
1729*38103Sbostic  * Extract a bit field from an integer.
1730*38103Sbostic  */
1731*38103Sbostic 
1732*38103Sbostic public integer extractField (s)
1733*38103Sbostic Symbol s;
1734*38103Sbostic {
1735*38103Sbostic     integer nbytes, nbits, n, r, off, len;
1736*38103Sbostic 
1737*38103Sbostic     off = s->symvalue.field.offset;
1738*38103Sbostic     len = s->symvalue.field.length;
1739*38103Sbostic     nbytes = size(s);
1740*38103Sbostic     n = 0;
1741*38103Sbostic     if (nbytes > sizeof(n)) {
1742*38103Sbostic 	printf("[bad size in extractField -- word assumed]\n");
1743*38103Sbostic 	nbytes = sizeof(n);
1744*38103Sbostic     }
1745*38103Sbostic     popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes));
1746*38103Sbostic     nbits = nbytes * BITSPERBYTE;
1747*38103Sbostic     r = n >> (nbits - ((off mod nbits) + len));
1748*38103Sbostic     r &= ((1 << len) - 1);
1749*38103Sbostic     return r;
1750*38103Sbostic }
1751*38103Sbostic 
1752*38103Sbostic /*
1753*38103Sbostic  * Change the length of a value in memory according to a given difference
1754*38103Sbostic  * in the lengths of its new and old types.
1755*38103Sbostic  */
1756*38103Sbostic 
1757*38103Sbostic public loophole (oldlen, newlen)
1758*38103Sbostic integer oldlen, newlen;
1759*38103Sbostic {
1760*38103Sbostic     integer i, n;
1761*38103Sbostic     Stack *oldsp;
1762*38103Sbostic 
1763*38103Sbostic     n = newlen - oldlen;
1764*38103Sbostic     oldsp = sp - oldlen;
1765*38103Sbostic     if (n > 0) {
1766*38103Sbostic 	for (i = oldlen - 1; i >= 0; i--) {
1767*38103Sbostic 	    oldsp[n + i] = oldsp[i];
1768*38103Sbostic 	}
1769*38103Sbostic 	for (i = 0; i < n; i++) {
1770*38103Sbostic 	    oldsp[i] = '\0';
1771*38103Sbostic 	}
1772*38103Sbostic     } else {
1773*38103Sbostic 	for (i = 0; i < newlen; i++) {
1774*38103Sbostic 	    oldsp[i] = oldsp[i - n];
1775*38103Sbostic 	}
1776*38103Sbostic     }
1777*38103Sbostic     sp += n;
1778*38103Sbostic }
1779