|
|
1.1 root 1: /* Copyright 1989 by AT&T Bell Laboratories */
2: /* SPARC.dep.c
3: *
4: * J.H. Reppy
5: * Cornell University
6: * Ithaca, NY 14853
7: * [email protected]
8: *
9: * HISTORY:
10: * 11/20/89 created (extracted from callgc.c and run.c)
11: *
12: * SPARC dependent code for SML/NJ runtime kernel.
13: */
14:
15: #include <signal.h>
16: #include <floatingpoint.h>
17: #include "tags.h"
18:
19: /* When handling signals we need to know the context of the signal. We view
20: * execution as being at one of two levels, and use the flag inML to distinguish
21: * the levels:
22: * 0 -- in C code above ML
23: * 1 -- in ML code or in C/asm code called from ML.
24: * This is adjusted by the assembler code that implements the C/ML interface.
25: */
26: int inML = 0; /* == 1 when execution is in ML code */
27: int fault_pending = 0; /* == 1 when a fault is pending in level 0 */
28:
29:
30: extern int cause, fault_code;
31: extern int saved_pc;
32: extern int saveregs[];
33:
34:
35: /* ghandle:
36: * Handler for GC signals. This is based on what level execution is in.
37: * If a fault occurs in level 0 we note it and invoke the exn handler the next
38: * time ML code is run. If a fault occurs in level 1 we need to determine if
39: * it is in ML code or in C/asm code called from ML. If it is in ML code then
40: * we transfer control directly to the exn handler. If it is in C/asm code,
41: * then we call ml_longjmp() (in SPARC.prim.s) to restore the ML register window.
42: */
43: ghandle(sig, code, scp, addr)
44: int sig, code, addr;
45: struct sigcontext *scp;
46: {
47: extern datalist, startprim, endprim, endmo, etext, ml_longjmp;
48:
49: saved_pc = scp->sc_pc;
50:
51: if ((sig == SIGEMT) && (code == EMT_TAG)) {
52: /* GC related fault. There are three possible code sequences that may
53: * trigger GC (where n is an integer and %r is a temp register).
54: *
55: * taddcctv %g6,%g4,%g0 1000 0001 0001 0001 1000 0000 0000 0100
56: *
57: * add %g4,n,%r 10rr rrr0 0000 0001 001n nnnn nnnn nnnn
58: * taddcctv %g6,%r,%g0 1000 0001 0001 0001 1000 0000 000r rrrr
59: *
60: * sethi %hi(n),%r 00rr rrr1 00nn nnnn nnnn nnnn nnnn nnnn
61: * or %r,%lo(n),%r 10rr rrr0 0001 0rrr rr1n nnnn nnnn nnnn
62: * add %g4,%r,%r 10rr rrr0 0000 0001 0000 0000 000r rrrr
63: * taddcctv %g6,%r,%g0 1000 0001 0001 0001 1000 0000 000r rrrr
64: */
65: register unsigned int *pc = (unsigned int *)saved_pc;
66: register int pc_adjust;
67:
68: if (pc[0] == 0x81118004 /* taddcctv %g6,%r,%g0 */)
69: pc_adjust = 0;
70: else if ((pc[0] & 0xffffffe0) == 0x81118000 /* taddcctv %g6,%r,%g0 */)
71: pc_adjust = (pc[-1] & 0x00002000 /* immed flag */) ? 4 : 12;
72: else
73: die ("SIGEMT not related to gc\n");
74: if (((int)pc)+4 != scp->sc_npc)
75: die ("SIGEMT not related to garbage collection (bogus npc)\n");
76: saved_pc = ((int)pc) - pc_adjust;
77: scp->sc_pc = (int)saveregs;
78: scp->sc_npc = ((int)saveregs)+4;
79: cause = CAUSE_GC;
80: }
81: else if (! inML) {
82: /* execution above ML */
83: if (sig != SIGINT)
84: die ("Unknown signal %d (%#x)\n", sig, code);
85: fault_pending = 1;
86: fault_code = exnCode(sig, code);
87: }
88: else {
89: fault_code = exnCode(sig, code);
90: cause = CAUSE_FAULT;
91:
92: /* Check to see if we are in ML code or in C/asm called from ML */
93: if (((int)&etext <= saved_pc)
94: || (((int)&startprim <= saved_pc) && (saved_pc < (int)&endprim))
95: || (((int)&datalist != ML_NIL) && ((int)&datalist <= saved_pc)
96: && (saved_pc <= (int)&endmo)))
97: {
98: /* Execution is in ML code */
99: scp->sc_pc = (int)saveregs;
100: scp->sc_npc = ((int)saveregs)+4;
101: }
102: else {
103: /* Execution is in C/asm code called from ML. */
104: if (sig != SIGINT)
105: die ("Unknown signal %d (%#x)\n", sig, code);
106: scp->sc_pc = (int)&ml_longjmp;
107: scp->sc_npc = ((int)&ml_longjmp)+4;
108: }
109: }
110: }
111:
112: extern int handleprof();
113: extern void set_fsr();
114:
115: /* setupsignals:
116: * Install the signal handlers.
117: */
118: setupsignals()
119: {
120: struct sigvec a;
121:
122: a.sv_handler = (void (*)()) ghandle;
123: a.sv_mask = sigmask(SIGINT);
124: a.sv_onstack = 0;
125: sigvec(SIGEMT,&a,0);
126: a.sv_mask = 0;
127: sigvec(SIGINT,&a,0);
128: set_fsr (0x0f000000); /* enable FP exceptions NV, OF, UF & DZ */
129: sigvec(SIGFPE,&a,0);
130: a.sv_handler = SIG_IGN;
131: sigvec(SIGPIPE,&a,0);
132: a.sv_handler = (void (*)()) handleprof;
133: sigvec(SIGVTALRM,&a,0);
134: }
135:
136: /**** TEMP ****/
137: char *malloc(){die("malloc"); return 0;}
138: char *realloc(){die("realloc"); return 0;}
139: char *calloc(){die("calloc"); return 0;}
140: int free(){die("free");}
141: int cfree(){die("cfree");}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.