Annotation of researchv10no/cmd/sml/src/runtime/SPARC.dep.c, revision 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.