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