Annotation of researchv10no/cmd/sml/src/runtime/SPARC.dep.c, revision 1.1.1.1

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");}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.