Annotation of cci/usr/src/usr.lib/libF77/trpfpe_.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     @(#)trpfpe_.c   1.1     6/7/85
        !             3:  *
        !             4:  *
        !             5:  *     Fortran floating-point error handler
        !             6:  *
        !             7:  *     Synopsis:
        !             8:  *             call trpfpe (n, retval)
        !             9:  *                     causes floating point faults to be trapped, with the
        !            10:  *                     first 'n' errors getting a message printed.
        !            11:  *                     'retval' is put in place of the bad result.
        !            12:  *             k = fpecnt()
        !            13:  *                     causes 'k' to get the number of errors since the
        !            14:  *                     last call to trpfpe().
        !            15:  *
        !            16:  *             common /fpeflt/ fpflag
        !            17:  *             logical fpflag
        !            18:  *                     fpflag will become .true. on faults
        !            19:  *
        !            20:  *     This handler just prints a message. It cannot fix anything
        !            21:  *     on Power6 because of its fpp architecture. In any case, there
        !            22:  *     are no arithmetic faults (only traps) around, so that no instruction
        !            23:  *     is interrupted befor it completes, and PC points to the next floating
        !            24:  *     point instruction (not necessarily next executable instr after the one
        !            25:  *     that got the exception).
        !            26:  */
        !            27: 
        !            28: 
        !            29: #include <stdio.h>
        !            30: #include <signal.h>
        !            31: #include "../libI77/fiodefs.h"
        !            32: 
        !            33: #define        SIG_VAL         int (*)()
        !            34: 
        !            35: 
        !            36: struct arglist {               /* what AP points to */
        !            37:        long    al_arg[256];
        !            38: };
        !            39: 
        !            40: struct reg0_1 {
        !            41:        long    reg[2];
        !            42: };
        !            43: struct reg2_12 {
        !            44:        long    reg[11];
        !            45: };
        !            46: #include <sys/types.h>
        !            47: #include <frame.h>
        !            48: #include "sigframe.h"
        !            49: 
        !            50: /*
        !            51:  * bits in the PSL
        !            52:  */
        !            53: #include <machine/psl.h>
        !            54: 
        !            55: /*
        !            56:  * where the registers are stored as we see them in the handler
        !            57:  */
        !            58: 
        !            59: 
        !            60: #define        iR0     reg0_1->reg[1]
        !            61: #define        iR1     reg0_1->reg[0]
        !            62: 
        !            63: #define        iR2     reg2_12->reg[0]
        !            64: #define        iR3     reg2_12->reg[1]
        !            65: #define        iR4     reg2_12->reg[2]
        !            66: #define        iR5     reg2_12->reg[3]
        !            67: #define        iR6     reg2_12->reg[4]
        !            68: #define        iR7     reg2_12->reg[5]
        !            69: #define        iR8     reg2_12->reg[6]
        !            70: #define        iR9     reg2_12->reg[7]
        !            71: #define        iR10    reg2_12->reg[8]
        !            72: #define        iR11    reg2_12->reg[9]
        !            73: #define        iR12    reg2_12->reg[10]
        !            74: 
        !            75: union objects {                /* for load/store */
        !            76:        char    ua_byte;
        !            77:        short   ua_word;
        !            78:        long    ua_long;
        !            79:        float   ua_float;
        !            80:        double  ua_double;
        !            81:        union objects   *ua_anything;
        !            82: };
        !            83: 
        !            84: typedef union objects  anything;
        !            85: enum object_type { BYTE, WORD, LONG, FLOAT, QUAD, DOUBLE, UNKNOWN };
        !            86: 
        !            87: 
        !            88: /*
        !            89:  * assembly language assist
        !            90:  * There are some things you just can't do in C
        !            91:  */
        !            92: asm(".text");
        !            93: 
        !            94: long *myfp();
        !            95: asm("_myfp: .word 0");
        !            96:        asm("movl (fp),r0");
        !            97:        asm("ret");
        !            98: 
        !            99: struct frame *framep(p)
        !           100: long *p;
        !           101: {
        !           102:        return((struct frame *)(p-2));
        !           103: }
        !           104: 
        !           105: struct arglist *argp(p) 
        !           106: long *p;
        !           107: {
        !           108:        return((struct arglist *)(p+1));
        !           109: }
        !           110: 
        !           111: char   *mysp();
        !           112: asm("_mysp: .word 0");
        !           113:        asm("addl3 $4,fp,r0");
        !           114:        asm("ret");
        !           115: 
        !           116: char   *mypc();
        !           117: asm("_mypc: .word 0");
        !           118:        asm("movl -8(fp),r0");
        !           119:        asm("ret");
        !           120: 
        !           121: asm(".data");
        !           122: 
        !           123: 
        !           124: /*
        !           125:  * Where interrupted objects are
        !           126:  */
        !           127: static struct frame    *ifp;   /* addr of saved FP */
        !           128: static struct arglist  *iap;   /* addr of saved AP */
        !           129: static char             *isp;  /* value of interrupted SP */
        !           130: static char            **ipc;  /* addr of saved PC */
        !           131: static struct reg0_1   *reg0_1;/* registers 0-1 are saved on the exception */
        !           132: static struct reg2_12  *reg2_12;/* we save 2-12 by our entry mask */
        !           133: static anything                *result_addr;   /* where the dummy result goes */
        !           134: static enum object_type         result_type;   /* what kind of object it is */
        !           135: 
        !           136: /*
        !           137:  * some globals
        !           138:  */
        !           139: static union {
        !           140:        long    rv_long[2];
        !           141:        float   rv_float;
        !           142:        double  rv_double;
        !           143:                        } retval; /* the user specified dummy result */
        !           144: static int     max_messages    = 1;            /* the user can tell us */
        !           145: static int     fpe_count       = 0;            /* how bad is it ? */
        !           146:        long    fpeflt_         = 0;    /* fortran "common /fpeflt/ flag" */
        !           147: static int     (*sigfpe_dfl)() = SIG_DFL;      /* if we can't fix it ... */
        !           148: 
        !           149: /*
        !           150:  * The fortran unit control table
        !           151:  */
        !           152: extern unit units[];
        !           153: 
        !           154: /*
        !           155:  * Fortran message table is in main
        !           156:  */
        !           157: struct msgtbl {
        !           158:        char    *mesg;
        !           159:        int     dummy;
        !           160: };
        !           161: extern struct msgtbl   act_fpe[];
        !           162: 
        !           163: 
        !           164: /* VALID ONLY ON VAX !!!
        !           165:  *
        !           166:  * Get the address of the (saved) next operand & update saved PC.
        !           167:  * The major purpose of this is to determine where to store the result.
        !           168:  * There is one case we can't deal with: -(SP) or (SP)+
        !           169:  * since we can't change the size of the stack.
        !           170:  * Let's just hope compilers don't generate that for results.
        !           171:  */
        !           172: 
        !           173: 
        !           174: /*
        !           175:  * Trap & repair floating exceptions so that a program may proceed.
        !           176:  * There is no notion of "correctness" here; just the ability to continue.
        !           177:  *
        !           178:  * The on_fpe() routine first checks the type code to see if the
        !           179:  * exception is repairable. If so, it checks the opcode to see if
        !           180:  * it is one that it knows. If this is true, it then simulates the
        !           181:  * VAX cpu in retrieving operands in order to increment iPC correctly.
        !           182:  * It notes where the result of the operation would have been stored
        !           183:  * and substitutes a previously supplied value.
        !           184:  *  DOES NOT REPAIR ON TAHOE !!!
        !           185:  */
        !           186: 
        !           187: on_fpe(signo, code, sc)
        !           188:        int signo, code;
        !           189:        struct sigcontext *sc;
        !           190: {
        !           191:        /*
        !           192:         * There must be at least 11 register variables here
        !           193:         * so our entry mask will save R12-R2.
        !           194:         */
        !           195:        register long   *stk;
        !           196:        register long   *sp, *rfp;
        !           197:        register struct arglist *ap;
        !           198:        register struct frame   *fp;
        !           199:        register FILE   *ef;
        !           200:        register struct sigframe *sfp;
        !           201:        register long dmy1, dmy2, dmy3, dmy4;
        !           202: 
        !           203:        dmy1 = dmy2 = dmy3 = dmy4 = 0;
        !           204: 
        !           205:        ef = units[STDERR].ufd;         /* fortran error stream */
        !           206: 
        !           207:        switch (code)
        !           208:        {
        !           209:                case FPE_INTOVF_TRAP:   /* integer overflow */
        !           210:                case FPE_INTDIV_TRAP:   /* integer divide by zero */
        !           211:                case FPE_FLTOVF_TRAP:   /* floating overflow */
        !           212:                case FPE_FLTDIV_TRAP:   /* floating divide by zero */
        !           213:                case FPE_FLTUND_TRAP:   /* floating underflow */
        !           214:                default:
        !           215: cant_fix:
        !           216:                        if (sigfpe_dfl > (SIG_VAL)7)    /* user specified */
        !           217:                                return((*sigfpe_dfl)(signo, code, sc));
        !           218:                        else
        !           219:                        if (++fpe_count <= max_messages) {
        !           220:                                fprintf(ef, "trpfpe: %s",
        !           221:                                        act_fpe[code-1].mesg);
        !           222:                                if (fpe_count == max_messages)
        !           223:                                        fprintf(ef, ": No more messages will be printed.\n");
        !           224:                                else
        !           225:                                        fputc('\n', ef);
        !           226:                        }
        !           227:                        fpeflt_ = -1;
        !           228:                        break;
        !           229:        }
        !           230: 
        !           231: /*
        !           232:  * Find all the registers just in case something better can be done.
        !           233:  */
        !           234: 
        !           235:        rfp = myfp();                   /* contents of fp register */
        !           236:        ap = argp(rfp);                 /* my arglist pointer */
        !           237:        fp = framep(rfp);               /* my frame pointer */
        !           238:        ifp = framep(*rfp);             /* user's stored in next frame back */
        !           239:        iap = argp(*rfp);
        !           240: 
        !           241:        sfp = (struct sigframe *)ap;    /* sigframe contains at its bottom the
        !           242:                                           signal handler arguments */
        !           243: 
        !           244:        reg0_1 = (struct reg0_1 *)&sfp->r1;
        !           245:        reg2_12 = (struct reg2_12 *)((char *)fp - sizeof (struct reg2_12));
        !           246: 
        !           247:        ipc = (char **)&sc->sc_pc;
        !           248:        isp = (char *)sc + sizeof (struct sigcontext);
        !           249:        sc->sc_ps &= ~(PSL_V|PSL_FU);
        !           250: 
        !           251:        fprintf(ef, "Current PC = %X \n", sc->sc_pc);
        !           252: 
        !           253:        signal(SIGFPE, on_fpe);
        !           254:        sigdie(signo, code, sc);
        !           255: }
        !           256: 
        !           257: trpfpe_ (count, rval)
        !           258:        long    *count; /* how many to announce */
        !           259:        double  *rval;  /* dummy return value */
        !           260: {
        !           261:        max_messages = *count;
        !           262:        retval.rv_double = *rval;
        !           263:        sigfpe_dfl = signal(SIGFPE, on_fpe);
        !           264:        fpe_count = 0;
        !           265: }
        !           266: 
        !           267: long
        !           268: fpecnt_ ()
        !           269: {
        !           270:        return (fpe_count);
        !           271: }
        !           272: 

unix.superglobalmegacorp.com

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