xref: /trunk/main/sal/inc/sal/mathconf.h (revision bcc22a4c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #if !defined INCLUDED_SAL_MATHCONF_H
25 #define INCLUDED_SAL_MATHCONF_H
26 
27 #include "osl/endian.h"
28 
29 #include <float.h>
30 #include <math.h>
31 
32 #if defined SOLARIS
33 #include <ieeefp.h>
34 #endif /* SOLARIS */
35 
36 #if defined __cplusplus
37 extern "C" {
38 #endif /* __cplusplus */
39 
40 
41 /* Generally, the C standard guarantees that at program startup, "trapping or
42    stopping (if supported) is disabled on all [floating-point] exceptions"
43    (F.7.3/1 of the August 3, 1998 draft of C99), and that during program
44    execution, "a programmer can safely assume default modes (or be unaware of
45    them)" (7.6/2, footnote 161 of the August 3, 1998 draft of C99).  Reportedly,
46    on Windows there are printer drivers that switch on exceptions.  To avoid
47    problems, the SAL_MATH_FPEXCEPTIONS_OFF macro can be used to explicitly
48    switch off exceptions (on Windows).
49  */
50 #if defined WNT
51 #define SAL_MATH_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM )
52 #else /* WNT */
53 #define SAL_MATH_FPEXCEPTIONS_OFF()
54 #endif /* WNT */
55 
56 
57 /* SAL_MATH_FINITE(d): test double d on INFINITY, NaN et al. */
58 #if defined(__GNUC__) && !defined(__clang__) // workaround gcc bug 14608
59 	#if (__GNUC_MINOR__ >= 3) // gcc>=4.3 has a builtin
60 		#define SAL_MATH_FINITE(d) __builtin_isfinite(d)
61 	#else
62 		#define SAL_MATH_FINITE(d) finite(d) // fall back to pre-C99 name
63 	#endif
64 #elif defined(__STDC__) && !(defined(LINUX) && defined(__clang__))
65 	// isfinite() should be available in math.h according to C99,C++99,SUSv3,etc.
66 	// unless GCC bug 14608 hits us where cmath undefines isfinite() as macro.
67 	// Clang on Linux runs into that bug too.
68 	#define SAL_MATH_FINITE(d) isfinite(d)
69 #elif defined( WNT)
70 #define SAL_MATH_FINITE(d) _finite(d)
71 #elif defined OS2
72 #define SAL_MATH_FINITE(d) finite(d)
73 #elif defined LINUX || defined UNX
74 #define SAL_MATH_FINITE(d) finite(d)
75 #else /* WNT, LINUX, UNX */
76 #error "SAL_MATH_FINITE not defined"
77 #endif /* WNT, LINUX, UNX */
78 
79 
80 /* This needs to be fixed for non--IEEE-754 platforms: */
81 #if 1 /* IEEE 754 supported */
82 #if defined OSL_BIGENDIAN
83 
84 /* IEEE 754 double structures for BigEndian */
85 union sal_math_Double
86 {
87     struct
88     {
89         unsigned sign         : 1;
90         unsigned exponent     :11;
91         unsigned fraction_hi  :20;
92         unsigned fraction_lo  :32;
93     } inf_parts;
94     struct
95     {
96         unsigned sign         : 1;
97         unsigned exponent     :11;
98         unsigned qnan_bit     : 1;
99         unsigned bits         :19;
100         unsigned fraction_lo  :32;
101     } nan_parts;
102     struct
103     {
104         unsigned msw          :32;
105         unsigned lsw          :32;
106     } w32_parts;
107     double value;
108 };
109 
110 #elif defined OSL_LITENDIAN
111 
112 /* IEEE 754 double structures for LittleEndian */
113 union sal_math_Double
114 {
115     struct {
116         unsigned fraction_lo  :32;
117         unsigned fraction_hi  :20;
118         unsigned exponent     :11;
119         unsigned sign         : 1;
120     } inf_parts;
121     struct {
122         unsigned fraction_lo  :32;
123         unsigned bits         :19;
124         unsigned qnan_bit     : 1;
125         unsigned exponent     :11;
126         unsigned sign         : 1;
127     } nan_parts;
128     struct
129     {
130         unsigned lsw          :32;
131         unsigned msw          :32;
132     } w32_parts;
133     double value;
134 };
135 
136 #else /* OSL_BIGENDIAN, OSL_LITENDIAN */
137 
138 #error "neither OSL_BIGENDIAN nor OSL_LITENDIAN"
139 
140 #endif /* OSL_BIGENDIAN, OSL_LITENDIAN */
141 #else /* IEEE 754 supported */
142 
143 #error "don't know how to handle IEEE 754"
144 
145 #endif /* IEEE 754 supported */
146 
147 
148 #if defined __cplusplus
149 }
150 #endif /* __cplusplus */
151 
152 #endif /* INCLUDED_SAL_MATHCONF_H */
153