|
|
1.1 root 1: /*
2: * @(#)trapov_.c 1.1
3: *
4: * Fortran/C floating-point overflow handler
5: *
6: * The idea of these routines is to catch floating-point overflows
7: * and print an eror message. When we then get a reserved operand
8: * exception, we then fix up the value to the highest possible
9: * number. Keen, no?
10: * Messy, yes!
11: *
12: * NO RESERVED OPERAND EXCEPTION ON RESULT OF FP OVERFLOW ON TAHOE.
13: * JUST PRINT THE OVERFLOW MESSAGE. RESULT IS 0 (zero).
14: *
15: * Synopsis:
16: * call trapov(n)
17: * causes overflows to be trapped, with the first 'n'
18: * overflows getting an "Overflow!" message printed.
19: * k = ovcnt(0)
20: * causes 'k' to get the number of overflows since the
21: * last call to trapov().
22: *
23: */
24:
25: # include <stdio.h>
26: # include <signal.h>
27: # include "../libI77/fiodefs.h"
28: # define SIG_VAL int (*)()
29:
30: /*
31: * trap type codes
32: */
33: # define INT_OVF_T 1
34: # define INT_DIV_T 2
35: # define FLT_OVF_T 3
36: # define FLT_DIV_T 4
37: # define FLT_UND_T 5
38:
39: /*
40: * Potential operand values
41: */
42: typedef union operand_types {
43: char o_byte;
44: short o_word;
45: long o_long;
46: float o_float;
47: long o_quad[2];
48: double o_double;
49: } anyval;
50:
51: /*
52: * GLOBAL VARIABLES (we need a few)
53: *
54: * Actual program counter and locations of registers.
55: */
56: static char *pc;
57: static int *regs0t1;
58: static int *regs2t12;
59: static int max_messages;
60: static int total_overflows;
61: static union {
62: long v_long[2];
63: double v_double;
64: } retrn;
65: static int (*sigill_default)() = (SIG_VAL)-1;
66: static int (*sigfpe_default)();
67:
68: /*
69: * the fortran unit control table
70: */
71: extern unit units[];
72:
73: /*
74: * Fortran message table is in main
75: */
76: struct msgtbl {
77: char *mesg;
78: int dummy;
79: };
80: extern struct msgtbl act_fpe[];
81:
82:
83:
84: anyval *get_operand_address(), *addr_of_reg();
85: char *opcode_name();
86:
87: /*
88: * This routine sets up the signal handler for the floating-point
89: * and reserved operand interrupts.
90: */
91:
92: trapov_(count, rtnval)
93: int *count;
94: double *rtnval;
95: {
96: extern got_overflow();
97:
98: sigfpe_default = signal(SIGFPE, got_overflow);
99: total_overflows = 0;
100: max_messages = *count;
101: retrn.v_double = *rtnval;
102: }
103:
104:
105:
106: /*
107: * got_overflow - routine called when overflow occurs
108: *
109: * This routine just prints a message about the overflow.
110: * It is impossible to find the bad result at this point.
111: * NEXT 2 LINES DON'T HOLD FOR TAHOE !
112: * Instead, we wait until we get the reserved operand exception
113: * when we try to use it. This raises the SIGILL signal.
114: */
115:
116: /*ARGSUSED*/
117: got_overflow(signo, codeword, sc)
118: int signo, codeword;
119: struct sigcontext *sc;
120: {
121: int *sp, i;
122: FILE *ef;
123:
124: signal(SIGFPE, got_overflow);
125: ef = units[STDERR].ufd;
126: switch (codeword) {
127: case INT_OVF_T:
128: case INT_DIV_T:
129: case FLT_UND_T:
130: case FLT_DIV_T:
131: if (sigfpe_default > (SIG_VAL)7)
132: return((*sigfpe_default)(signo, codeword, sc));
133: else
134: sigdie(signo, codeword, sc);
135: /* NOTREACHED */
136:
137: case FLT_OVF_T:
138: if (++total_overflows <= max_messages) {
139: fprintf(ef, "trapov: %s",
140: act_fpe[codeword-1].mesg);
141: fprintf(ef, ": Current PC = %X", sc->sc_pc);
142: if (total_overflows == max_messages)
143: fprintf(ef, ": No more messages will be printed.\n");
144: else
145: fputc('\n', ef);
146: }
147: return;
148: }
149: }
150: int
151: ovcnt_()
152: {
153: return total_overflows;
154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.