1 
2 /* @(#)fdlibm.h 1.5 04/04/22 */
3 /*
4  * ====================================================
5  * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
6  *
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  */
12 
13 #ifndef __CLASSPATH_FDLIBM_H__
14 #define __CLASSPATH_FDLIBM_H__
15 
16 /*
17  * On AIX we need _ALL_SOURCE defined to compile/configure native-lib, but can't
18  *  have it defined to compile fdlibm.  UGH.
19  */
20 #ifdef _AIX
21 #undef _ALL_SOURCE
22 #endif
23 
24 #include <config.h>
25 #include <stdlib.h>
26 
27 /*
28  * AIX includes a header that defines hz,
29  * which conflicts with an fdlibm variable in some functions.
30  */
31 #ifdef _AIX
32 #undef hz
33 #endif
34 
35 /* GCJ LOCAL: Include files.  */
36 #include "ieeefp.h"
37 /* CLASSPATH LOCAL: */
38 #include "namespace.h"
39 
40 #include "mprec.h"
41 
42 /* CYGNUS LOCAL: Default to XOPEN_MODE.  */
43 #define _XOPEN_MODE
44 
45 #ifdef __P
46 #undef __P
47 #endif
48 
49 /* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly
50    but these catch some common cases. */
51 
52 #if 0
53 #if defined(i386) || defined(i486) || \
54 	defined(intel) || defined(x86) || defined(i86pc) || \
55 	defined(__alpha) || defined(__osf__)
56 #define __LITTLE_ENDIAN
57 #endif
58 
59 #ifdef __LITTLE_ENDIAN
60 #define __HI(x) *(1+(int*)&x)
61 #define __LO(x) *(int*)&x
62 #define __HIp(x) *(1+(int*)x)
63 #define __LOp(x) *(int*)x
64 #else
65 #define __HI(x) *(int*)&x
66 #define __LO(x) *(1+(int*)&x)
67 #define __HIp(x) *(int*)x
68 #define __LOp(x) *(1+(int*)x)
69 #endif
70 #endif
71 
72 #ifdef __STDC__
73 #define	__P(p)	p
74 #else
75 #define	__P(p)	()
76 #endif
77 
78 /*
79  * ANSI/POSIX
80  */
81 
82 extern int signgam;
83 
84 #define	MAXFLOAT	((float)3.40282346638528860e+38)
85 
86 enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
87 
88 #define _LIB_VERSION_TYPE enum fdversion
89 #define _LIB_VERSION _fdlib_version
90 
91 /* if global variable _LIB_VERSION is not desirable, one may
92  * change the following to be a constant by:
93  *	#define _LIB_VERSION_TYPE const enum version
94  * In that case, after one initializes the value _LIB_VERSION (see
95  * s_lib_version.c) during compile time, it cannot be modified
96  * in the middle of a program
97  */
98 extern  _LIB_VERSION_TYPE  _LIB_VERSION;
99 
100 #define _IEEE_  fdlibm_ieee
101 #define _SVID_  fdlibm_svid
102 #define _XOPEN_ fdlibm_xopen
103 #define _POSIX_ fdlibm_posix
104 
105 struct exception {
106 	int type;
107 	char *name;
108 	double arg1;
109 	double arg2;
110 	double retval;
111 };
112 
113 #define	HUGE		MAXFLOAT
114 
115 /*
116  * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
117  * (one may replace the following line by "#include <values.h>")
118  */
119 
120 #define X_TLOSS		1.41484755040568800000e+16
121 
122 #define	DOMAIN		1
123 #define	SING		2
124 #define	OVERFLOW	3
125 #define	UNDERFLOW	4
126 #define	TLOSS		5
127 #define	PLOSS		6
128 
129 /* These typedefs are true for the targets running Java. */
130 
131 #define _IEEE_LIBM
132 
133 #ifdef __cplusplus
134 extern "C" {
135 #endif
136 
137 /*
138  * ANSI/POSIX
139  */
140 extern double acos __P((double));
141 extern double asin __P((double));
142 extern double atan __P((double));
143 extern double atan2 __P((double, double));
144 extern double cos __P((double));
145 extern double sin __P((double));
146 extern double tan __P((double));
147 
148 extern double cosh __P((double));
149 extern double sinh __P((double));
150 extern double tanh __P((double));
151 
152 extern double exp __P((double));
153 extern double frexp __P((double, int *));
154 extern double ldexp __P((double, int));
155 extern double log __P((double));
156 extern double log10 __P((double));
157 extern double modf __P((double, double *));
158 
159 extern double pow __P((double, double));
160 extern double sqrt __P((double));
161 
162 extern double ceil __P((double));
163 extern double fabs __P((double));
164 extern double floor __P((double));
165 extern double fmod __P((double, double));
166 
167 extern double erf __P((double));
168 extern double erfc __P((double));
169 extern double gamma __P((double));
170 extern double hypot __P((double, double));
171 
172 #if !defined(isnan)
173 #define isnan(x) ((x) != (x))
174 #endif
175 
176 extern int finite __P((double));
177 extern double j0 __P((double));
178 extern double j1 __P((double));
179 extern double jn __P((int, double));
180 extern double lgamma __P((double));
181 extern double y0 __P((double));
182 extern double y1 __P((double));
183 extern double yn __P((int, double));
184 
185 extern double acosh __P((double));
186 extern double asinh __P((double));
187 extern double atanh __P((double));
188 extern double cbrt __P((double));
189 extern double logb __P((double));
190 extern double nextafter __P((double, double));
191 extern double remainder __P((double, double));
192 #ifdef _SCALB_INT
193 extern double scalb __P((double, int));
194 #else
195 extern double scalb __P((double, double));
196 #endif
197 
198 extern int matherr __P((struct exception *));
199 
200 /*
201  * IEEE Test Vector
202  */
203 extern double significand __P((double));
204 
205 /*
206  * Functions callable from C, intended to support IEEE arithmetic.
207  */
208 extern double copysign __P((double, double));
209 extern int ilogb __P((double));
210 extern double rint __P((double));
211 extern double scalbn __P((double, int));
212 
213 /*
214  * BSD math library entry points
215  */
216 extern double expm1 __P((double));
217 extern double log1p __P((double));
218 
219 /*
220  * Reentrant version of gamma & lgamma; passes signgam back by reference
221  * as the second argument; user must allocate space for signgam.
222  */
223 #ifdef _REENTRANT
224 extern double gamma_r __P((double, int *));
225 extern double lgamma_r __P((double, int *));
226 #endif	/* _REENTRANT */
227 
228 /* ieee style elementary functions */
229 extern double __ieee754_sqrt __P((double));
230 extern double __ieee754_acos __P((double));
231 extern double __ieee754_acosh __P((double));
232 extern double __ieee754_log __P((double));
233 extern double __ieee754_atanh __P((double));
234 extern double __ieee754_asin __P((double));
235 extern double __ieee754_atan2 __P((double,double));
236 extern double __ieee754_exp __P((double));
237 extern double __ieee754_cosh __P((double));
238 extern double __ieee754_fmod __P((double,double));
239 extern double __ieee754_pow __P((double,double));
240 extern double __ieee754_lgamma_r __P((double,int *));
241 extern double __ieee754_gamma_r __P((double,int *));
242 extern double __ieee754_lgamma __P((double));
243 extern double __ieee754_gamma __P((double));
244 extern double __ieee754_log10 __P((double));
245 extern double __ieee754_sinh __P((double));
246 extern double __ieee754_hypot __P((double,double));
247 extern double __ieee754_j0 __P((double));
248 extern double __ieee754_j1 __P((double));
249 extern double __ieee754_y0 __P((double));
250 extern double __ieee754_y1 __P((double));
251 extern double __ieee754_jn __P((int,double));
252 extern double __ieee754_yn __P((int,double));
253 extern double __ieee754_remainder __P((double,double));
254 extern int32_t    __ieee754_rem_pio2 __P((double,double*));
255 #ifdef _SCALB_INT
256 extern double __ieee754_scalb __P((double,int));
257 #else
258 extern double __ieee754_scalb __P((double,double));
259 #endif
260 
261 /* fdlibm kernel function */
262 extern double __kernel_standard __P((double,double,int));
263 extern double __kernel_sin __P((double,double,int));
264 extern double __kernel_cos __P((double,double));
265 extern double __kernel_tan __P((double,double,int));
266 extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
267 
268 /* Classpath extensions */
269 
270 /* The original code used statements like
271    n0 = ((*(int*)&one)>>29)^1;             * index of high word *
272    ix0 = *(n0+(int*)&x);                   * high word of x *
273    ix1 = *((1-n0)+(int*)&x);               * low word of x *
274    to dig two 32 bit words out of the 64 bit IEEE floating point
275    value.  That is non-ANSI, and, moreover, the gcc instruction
276    scheduler gets it wrong.  We instead use the following macros.
277    Unlike the original code, we determine the endianness at compile
278    time, not at run time; I don't see much benefit to selecting
279    endianness at run time.  */
280 
281 #ifndef __IEEE_BIG_ENDIAN
282 #ifndef __IEEE_LITTLE_ENDIAN
283 #error Must define endianness
284 #endif
285 #endif
286 
287 /* A union which permits us to convert between a double and two 32 bit
288    ints.  */
289 
290 #ifdef __IEEE_BIG_ENDIAN
291 
292   typedef union
293   {
294     double value;
295     struct
296     {
297       uint32_t msw;
298       uint32_t lsw;
299     } parts;
300   } ieee_double_shape_type;
301 
302 #endif
303 
304 #ifdef __IEEE_LITTLE_ENDIAN
305 
306   typedef union
307   {
308     double value;
309     struct
310     {
311       uint32_t lsw;
312       uint32_t msw;
313     } parts;
314   } ieee_double_shape_type;
315 
316 #endif
317 
318   /* Get two 32 bit ints from a double.  */
319 
320 #define EXTRACT_WORDS(ix0,ix1,d)                                  \
321   do {                                                            \
322     ieee_double_shape_type ew_u;                                  \
323     ew_u.value = (d);                                             \
324     (ix0) = ew_u.parts.msw;                                       \
325     (ix1) = ew_u.parts.lsw;                                       \
326   } while (0)
327 
328 /* Get the more significant 32 bit int from a double.  */
329 
330 #define GET_HIGH_WORD(i,d)                                      \
331   do {                                                            \
332     ieee_double_shape_type gh_u;                                  \
333     gh_u.value = (d);                                             \
334     (i) = gh_u.parts.msw;                                         \
335   } while (0)
336 
337 /* Get the less significant 32 bit int from a double.  */
338 
339 #define GET_LOW_WORD(i,d)                                       \
340   do {                                                            \
341     ieee_double_shape_type gl_u;                                  \
342     gl_u.value = (d);                                             \
343     (i) = gl_u.parts.lsw;                                         \
344   } while (0)
345 
346 /* Set a double from two 32 bit ints.  */
347 
348 #define INSERT_WORDS(d,ix0,ix1)                                 \
349   do {                                                            \
350     ieee_double_shape_type iw_u;                                  \
351     iw_u.parts.msw = (ix0);                                       \
352     iw_u.parts.lsw = (ix1);                                       \
353     (d) = iw_u.value;                                             \
354   } while (0)
355 
356 /* Set the more significant 32 bits of a double from an int.  */
357 
358 #define SET_HIGH_WORD(d,v)                                      \
359   do {                                                            \
360     ieee_double_shape_type sh_u;                                  \
361     sh_u.value = (d);                                             \
362     sh_u.parts.msw = (v);                                         \
363     (d) = sh_u.value;                                             \
364   } while (0)
365 
366 /* Set the less significant 32 bits of a double from an int.  */
367 
368 #define SET_LOW_WORD(d,v)                                       \
369   do {                                                            \
370     ieee_double_shape_type sl_u;                                  \
371     sl_u.value = (d);                                             \
372     sl_u.parts.lsw = (v);                                         \
373     (d) = sl_u.value;                                             \
374   } while (0)
375 
376 /* A union which permits us to convert between a float and a 32 bit
377    int.  */
378 
379 typedef union
380 {
381   float value;
382   uint32_t word;
383 } ieee_float_shape_type;
384 
385 /* Get a 32 bit int from a float.  */
386 
387 #define GET_FLOAT_WORD(i,d)					\
388 do {								\
389   ieee_float_shape_type gf_u;					\
390   gf_u.value = (d);						\
391   (i) = gf_u.word;						\
392 } while (0)
393 
394 /* Set a float from a 32 bit int.  */
395 
396 #define SET_FLOAT_WORD(d,i)					\
397 do {								\
398   ieee_float_shape_type sf_u;					\
399   sf_u.word = (i);						\
400   (d) = sf_u.value;						\
401 } while (0)
402 
403 #ifdef __cplusplus
404 }
405 #endif
406 
407 #endif /* __CLASSPATH_FDLIBM_H__ */
408 
409