18
#define RNAN 0xffc00000 /* Quiet NaN */
19
#define DNAN0 0xfff80000 /* Signalling NaN double Big endian */
24
#define RNAN 0xffc00000 /* Quiet Nan -- big endian */
25
#define DNAN0 0xfff80000
30
#define RNAN 0xff800001
31
#ifdef IEEE_MC68k /* set on PPC*/
32
#define DNAN0 0xfff00000 /* Quiet NaN big endian */
35
#define DNAN0 1 /* LSB, MSB for little endian machines */
36
#define DNAN1 0xfff00000
42
#define FA7UL (unsigned Long) 0xfa7a7a7aL
45
#define FA7UL 0xfa7a7a7aUL
52
static void ieee0(Void);
54
static unsigned Long rnan = RNAN,
60
void unsupported_error()
62
fprintf(stderr,"Runtime Error: Your Architecture is not supported by the"
63
" -trapuv option of f2c\n");
71
_uninit_f2c(x, type, len) void *x; int type; long len;
73
_uninit_f2c(void *x, int type, long len)
78
unsigned Long *lx, *lxe;
93
*(unsigned Long*)x = FA7UL;
100
*(unsigned Long*)x = rnan;
103
lx = (unsigned Long*)x;
108
printf("Surprise type %d in _uninit_f2c\n", type);
121
lx = (unsigned Long*)x;
130
lx = (unsigned Long*)x;
139
lx = (unsigned Long*)x;
140
for(lxe = lx + 2*len; lx < lxe; lx += 2) {
170
#define EM_DENORMAL _EM_DENORMAL
173
#define EM_UNDERFLOW _EM_UNDERFLOW
176
#define EM_INEXACT _EM_INEXACT
179
#define MCW_EM _MCW_EM
181
_control87(EM_DENORMAL | EM_UNDERFLOW | EM_INEXACT, MCW_EM);
183
/* With MS VC++, compiling and linking with -Zi will permit */
184
/* clicking to invoke the MS C++ debugger, which will show */
185
/* the point of error -- provided SIGFPE is SIG_DFL. */
186
signal(SIGFPE, SIG_DFL);
190
/* What follows is for SGI IRIX only */
191
#if defined(__mips) && defined(__sgi) /* must link with -lfpe */
193
/* code from Eric Grosse */
196
#include "/usr/include/sigfpe.h" /* full pathname for lcc -N */
197
#include "/usr/include/sys/fpu.h"
201
ieeeuserhand(exception, val) unsigned exception[5]; int val[2];
203
ieeeuserhand(unsigned exception[5], int val[2])
207
fprintf(stderr,"ieee0() aborting because of ");
208
if(exception[0]==_OVERFL) fprintf(stderr,"overflow\n");
209
else if(exception[0]==_UNDERFL) fprintf(stderr,"underflow\n");
210
else if(exception[0]==_DIVZERO) fprintf(stderr,"divide by 0\n");
211
else if(exception[0]==_INVALID) fprintf(stderr,"invalid operation\n");
212
else fprintf(stderr,"\tunknown reason\n");
219
ieeeuserhand2(j) unsigned int **j;
221
ieeeuserhand2(unsigned int **j)
224
fprintf(stderr,"ieee0() aborting because of confusion\n");
233
sigfpe_[i].count = 1000;
234
sigfpe_[i].trace = 1;
235
sigfpe_[i].repls = _USER_DETERMINED;
237
sigfpe_[1].repls = _ZERO; /* underflow */
239
_EN_UNDERFL|_EN_OVERFL|_EN_DIVZERO|_EN_INVALID,
240
ieeeuserhand,_ABORT_ON_ERROR,ieeeuserhand2);
242
#endif /* IRIX mips */
245
* The following is the preferred method but depends upon a GLIBC extension only
246
* to be found in GLIBC 2.2 or later. It is a GNU extension, not included in the
247
* C99 extensions which allow the FP status register to be examined in a platform
248
* independent way. It should be used if at all possible -- AFRB
251
#if (defined(__GLIBC__)&&(!(__GLIBC__==2&&__GLIBC_MINOR<2)&&(!__GLIBC__<2)))
253
#define _GNU_SOURCE 1
260
/* Clear all exception flags */
261
if (fedisableexcept(FE_ALL_EXCEPT)==-1)
263
if (feenableexcept(FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW)==-1)
267
#endif /* Glibc control */
269
/* Many linux cases will be treated through GLIBC. Note that modern
270
* linux runs on many non-i86 plaforms and as a result the following code
271
* must be processor dependent rather than simply OS specific */
273
#if (defined(__linux__)&&(!defined(IEEE0_done)))
275
#include <fpu_control.h>
279
#define __setfpucw(x) __fpu_control = (x)
283
/* Not all versions of libc define _FPU_SETCW;
284
* * some only provide the __setfpucw() function.
287
#define _FPU_SETCW(cw) __setfpucw(cw)
290
/* The exact set of flags we want to set in the FPU control word
291
* depends on the architecture.
292
* Note also that whether an exception is enabled or disabled when
293
* the _FPU_MASK_nn bit is set is architecture dependent!
294
* Enabled-when-set: M68k, ARM, MIPS, PowerPC
295
* Disabled-when-set: x86, Alpha
296
* The state we are after is:
297
* exceptions on division by zero, overflow and invalid operation.
303
#define __setfpucw(x) __fpu_control = (x)
309
#undef Can_use__setfpucw
310
#define Can_use__setfpucw
314
#undef RQD_FPU_CLEAR_MASK
316
#if (defined(__mc68000__) || defined(__mc68020__) || defined(mc68020) || defined (__mc68k__))
317
/* Reported 20010705 by Alan Bain <alanb@chiark.greenend.org.uk> */
318
/* Note that IEEE 754 IOP (illegal operation) */
319
/* = Signaling NAN (SNAN) + operation error (OPERR). */
320
#define RQD_FPU_STATE (_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + \
321
_FPU_MASK_DZ + _FPU_MASK_SNAN+_FPU_MASK_OVFL)
322
#define RQD_FPU_MASK (_FPU_MASK_OPERR+_FPU_MASK_DZ+_FPU_MASK_SNAN+_FPU_MASK_OVFL)
324
#elif (defined(__powerpc__)||defined(_ARCH_PPC)||defined(_ARCH_PWR)) /* !__mc68k__ */
325
/* The following is NOT a mistake -- the author of the fpu_control.h
326
* for the PPC has erroneously defined IEEE mode to turn on exceptions
327
* other than Inexact! Start from default then and turn on only the ones
330
/* I have changed _FPU_MASK_UM here to _FPU_MASK_ZM, because that is
331
* in line with all the other architectures specified here. -- AFRB
333
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
334
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
336
#elif (defined(__arm__))
337
/* On ARM too, IEEE implies all exceptions enabled.
338
* -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
339
* Unfortunately some version of ARMlinux don't include any
340
* flags in the fpu_control.h file
342
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
343
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
345
#elif (defined(__mips__))
346
/* And same again for MIPS; _FPU_IEEE => exceptions seems a common meme.
347
* * MIPS uses different MASK constant names, no idea why -- PMM
349
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_O+_FPU_MASK_V+_FPU_MASK_Z)
350
#define RQD_FPU_MASK (_FPU_MASK_O+_FPU_MASK_V+_FPU_MASK_Z)
352
#elif (defined(__sparc__))
353
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_DOUBLE+_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
354
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
356
#elif (defined(__i386__) || defined(__alpha__))
357
/* This case is for Intel, and also Alpha, because the Alpha header
358
* purposely emulates x86 flags and meanings for compatibility with
360
* We used to try this case for anything defining _FPU_IEEE, but I think
361
* that that's a bad idea because it isn't really likely to work.
362
* Instead for unknown architectures we just won't allow -trapuv to work.
363
* Trying this case was just getting us
364
* (a) compile errors on archs which didn't know all these constants
365
* (b) silent wrong behaviour on archs (like SPARC) which do know all
366
* constants but have different semantics for them
368
#define RQD_FPU_STATE (_FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM)
369
#define RQD_FPU_CLEAR_MASK (_FPU_MASK_IM + _FPU_MASK_ZM + _FPU_MASK_OM)
372
static void ieee0(Void)
376
#ifndef UNINIT_F2C_PRECISION_53 /* 20051004 */
377
__fpu_control = RQD_FPU_STATE;
378
_FPU_SETCW(__fpu_control);
380
/* unmask invalid, etc., and keep current rounding precision */
383
#ifdef RQD_FPU_CLEAR_MASK
384
cw &= ~ RQD_FPU_CLEAR_MASK;
391
#else /* !_FPU_IEEE */
393
fprintf(stderr, "\n%s\n%s\n%s\n%s\n",
394
"WARNING: _uninit_f2c in libf2c does not know how",
395
"to enable trapping on this system, so f2c's -trapuv",
396
"option will not detect uninitialized variables unless",
397
"you can enable trapping manually.");
400
#endif /* _FPU_IEEE */
402
#endif /* __linux__ */
404
/* Specific to OSF/1 */
405
#if (defined(__alpha)&&defined(__osf__))
408
#include <machine/fpu.h>
412
ieee_set_fp_control(IEEE_TRAP_ENABLE_INV);
414
#endif /*IEEE0_done*/
415
#endif /*__alpha OSF/1*/
419
#define _INCLUDE_HPUX_SOURCE
424
#define fpsetmask fesettrapenable
425
#define FP_X_INV FE_INVALID
442
fp_enable(TRP_INVALID);
443
fp_trap(FP_TRAP_SYNC);