1 /* Floating point exceptions */
2 /*
3 Copyright (C) 2004-2017,2018 John E. Davis
4 
5 This file is part of the S-Lang Library.
6 
7 The S-Lang Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11 
12 The S-Lang Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 USA.
21 */
22 
23 #include "slinclud.h"
24 
25 #include <float.h>
26 #include <math.h>
27 
28 #ifdef HAVE_FLOATINGPOINT_H
29 # include <floatingpoint.h>
30 #endif
31 
32 #ifdef HAVE_FENV_H
33 # include <fenv.h>
34 #endif
35 
36 #ifdef HAVE_IEEEFP_H
37 # include <ieeefp.h>
38 #endif
39 
40 #include "slang.h"
41 #include "_slang.h"
42 
43 #ifdef HAVE_FECLEAREXCEPT
44 # define CLEAR_FP_EXCEPTION	(void)feclearexcept(FE_ALL_EXCEPT);
45 # define GET_FP_EXCEPTION	fetestexcept(FE_ALL_EXCEPT)
46 # ifndef FE_DIVBYZERO
47 #  define FE_DIVBYZERO	0
48 # endif
49 # ifndef FE_INVALID
50 #  define FE_INVALID	0
51 # endif
52 # ifndef FE_OVERFLOW
53 #  define FE_OVERFLOW	0
54 # endif
55 # ifndef FE_UNDERFLOW
56 #  define FE_UNDERFLOW	0
57 # endif
58 # ifndef FE_INEXACT
59 #  define FE_INEXACT	0
60 # endif
61 # define SYS_FE_DIVBYZERO	FE_DIVBYZERO
62 # define SYS_FE_INVALID		FE_INVALID
63 # define SYS_FE_OVERFLOW	FE_OVERFLOW
64 # define SYS_FE_UNDERFLOW	FE_UNDERFLOW
65 # define SYS_FE_INEXACT		FE_INEXACT
66 #else
67 # ifdef HAVE_FPSETSTICKY
68 #  define CLEAR_FP_EXCEPTION	(void)fpsetsticky(0)
69 #  define GET_FP_EXCEPTION	fpgetsticky()
70 #  define SYS_FE_DIVBYZERO	FP_X_DZ
71 #  define SYS_FE_INVALID	FP_X_INV
72 #  define SYS_FE_OVERFLOW	FP_X_OFL
73 #  define SYS_FE_UNDERFLOW	FP_X_UFL
74 #  define SYS_FE_INEXACT	FP_X_IMP
75 # else
76 /* ??? */
77 #  define CLEAR_FP_EXCEPTION	(void)0
78 #  define GET_FP_EXCEPTION	(0)
79 #  define SYS_FE_DIVBYZERO	0
80 #  define SYS_FE_INVALID	0
81 #  define SYS_FE_OVERFLOW	0
82 #  define SYS_FE_UNDERFLOW	0
83 #  define SYS_FE_INEXACT	0
84 # endif
85 #endif
86 
SLfpu_clear_except_bits(void)87 void SLfpu_clear_except_bits (void)
88 {
89    CLEAR_FP_EXCEPTION;
90 }
91 
SLfpu_test_except_bits(unsigned int bits)92 unsigned int SLfpu_test_except_bits (unsigned int bits)
93 {
94    unsigned int rbits;
95    unsigned long sysbits;
96 
97    sysbits = GET_FP_EXCEPTION;
98 
99    rbits = 0;
100    if (sysbits & SYS_FE_DIVBYZERO) rbits |= SL_FE_DIVBYZERO;
101    if (sysbits & SYS_FE_INVALID) rbits |= SL_FE_INVALID;
102    if (sysbits & SYS_FE_OVERFLOW) rbits |= SL_FE_OVERFLOW;
103    if (sysbits & SYS_FE_UNDERFLOW) rbits |= SL_FE_UNDERFLOW;
104    if (sysbits & SYS_FE_INEXACT) rbits |= SL_FE_INEXACT;
105 
106    return rbits & bits;
107 }
108