math_private.h (6302B)
1 /* 2 * ==================================================== 3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 4 * 5 * Developed at SunPro, a Sun Microsystems, Inc. business. 6 * Permission to use, copy, modify, and distribute this 7 * software is freely granted, provided that this notice 8 * is preserved. 9 * ==================================================== 10 */ 11 12 /* 13 * from: @(#)fdlibm.h 5.1 93/09/24 14 * $FreeBSD: src/lib/msun/src/math_private.h,v 1.15 2003/07/23 04:53:46 peter Exp $ 15 */ 16 17 #ifndef _MATH_PRIVATE_H_ 18 #define _MATH_PRIVATE_H_ 19 20 21 #include <stdint.h> 22 23 typedef uint32_t u_int32_t; 24 25 26 /* 27 * VX32: Only provide the "raw" IEEE-compatible error handling behaviors, 28 * since we're not trying to be exactly POSIX/UNIX standards-compliant. 29 */ 30 #define _IEEE_LIBM 1 31 32 33 /* 34 * The original fdlibm code used statements like: 35 * n0 = ((*(int*)&one)>>29)^1; * index of high word * 36 * ix0 = *(n0+(int*)&x); * high word of x * 37 * ix1 = *((1-n0)+(int*)&x); * low word of x * 38 * to dig two 32 bit words out of the 64 bit IEEE floating point 39 * value. That is non-ANSI, and, moreover, the gcc instruction 40 * scheduler gets it wrong. We instead use the following macros. 41 * Unlike the original code, we determine the endianness at compile 42 * time, not at run time; I don't see much benefit to selecting 43 * endianness at run time. 44 */ 45 46 /* 47 * A union which permits us to convert between a double and two 32 bit ints. 48 * VX32: we know we're a little-endian machine. 49 */ 50 51 typedef union 52 { 53 double value; 54 struct 55 { 56 u_int32_t lsw; 57 u_int32_t msw; 58 } parts; 59 } ieee_double_shape_type; 60 61 62 /* Get two 32 bit ints from a double. */ 63 64 #define EXTRACT_WORDS(ix0,ix1,d) \ 65 do { \ 66 ieee_double_shape_type ew_u; \ 67 ew_u.value = (d); \ 68 (ix0) = ew_u.parts.msw; \ 69 (ix1) = ew_u.parts.lsw; \ 70 } while (0) 71 72 /* Get the more significant 32 bit int from a double. */ 73 74 #define GET_HIGH_WORD(i,d) \ 75 do { \ 76 ieee_double_shape_type gh_u; \ 77 gh_u.value = (d); \ 78 (i) = gh_u.parts.msw; \ 79 } while (0) 80 81 /* Get the less significant 32 bit int from a double. */ 82 83 #define GET_LOW_WORD(i,d) \ 84 do { \ 85 ieee_double_shape_type gl_u; \ 86 gl_u.value = (d); \ 87 (i) = gl_u.parts.lsw; \ 88 } while (0) 89 90 /* Set a double from two 32 bit ints. */ 91 92 #define INSERT_WORDS(d,ix0,ix1) \ 93 do { \ 94 ieee_double_shape_type iw_u; \ 95 iw_u.parts.msw = (ix0); \ 96 iw_u.parts.lsw = (ix1); \ 97 (d) = iw_u.value; \ 98 } while (0) 99 100 /* Set the more significant 32 bits of a double from an int. */ 101 102 #define SET_HIGH_WORD(d,v) \ 103 do { \ 104 ieee_double_shape_type sh_u; \ 105 sh_u.value = (d); \ 106 sh_u.parts.msw = (v); \ 107 (d) = sh_u.value; \ 108 } while (0) 109 110 /* Set the less significant 32 bits of a double from an int. */ 111 112 #define SET_LOW_WORD(d,v) \ 113 do { \ 114 ieee_double_shape_type sl_u; \ 115 sl_u.value = (d); \ 116 sl_u.parts.lsw = (v); \ 117 (d) = sl_u.value; \ 118 } while (0) 119 120 /* 121 * A union which permits us to convert between a float and a 32 bit 122 * int. 123 */ 124 125 typedef union 126 { 127 float value; 128 /* FIXME: Assumes 32 bit int. */ 129 unsigned int word; 130 } ieee_float_shape_type; 131 132 /* Get a 32 bit int from a float. */ 133 134 #define GET_FLOAT_WORD(i,d) \ 135 do { \ 136 ieee_float_shape_type gf_u; \ 137 gf_u.value = (d); \ 138 (i) = gf_u.word; \ 139 } while (0) 140 141 /* Set a float from a 32 bit int. */ 142 143 #define SET_FLOAT_WORD(d,i) \ 144 do { \ 145 ieee_float_shape_type sf_u; \ 146 sf_u.word = (i); \ 147 (d) = sf_u.value; \ 148 } while (0) 149 150 151 /* Some additional crap needed by routines added later in BSD... */ 152 union IEEEf2bits { 153 float f; 154 struct { 155 unsigned int man :23; 156 unsigned int exp :8; 157 unsigned int sign :1; 158 } bits; 159 }; 160 161 union IEEEd2bits { 162 double d; 163 struct { 164 unsigned int manl :32; 165 unsigned int manh :20; 166 unsigned int exp :11; 167 unsigned int sign :1; 168 } bits; 169 }; 170 171 172 /* ieee style elementary functions */ 173 double __ieee754_sqrt(double); 174 double __ieee754_acos(double); 175 double __ieee754_acosh(double); 176 double __ieee754_log(double); 177 double __ieee754_atanh(double); 178 double __ieee754_asin(double); 179 double __ieee754_atan2(double,double); 180 double __ieee754_exp(double); 181 double __ieee754_cosh(double); 182 double __ieee754_fmod(double,double); 183 double __ieee754_pow(double,double); 184 double __ieee754_lgamma_r(double,int *); 185 double __ieee754_gamma_r(double,int *); 186 double __ieee754_lgamma(double); 187 double __ieee754_gamma(double); 188 double __ieee754_log10(double); 189 double __ieee754_sinh(double); 190 double __ieee754_hypot(double,double); 191 double __ieee754_j0(double); 192 double __ieee754_j1(double); 193 double __ieee754_y0(double); 194 double __ieee754_y1(double); 195 double __ieee754_jn(int,double); 196 double __ieee754_yn(int,double); 197 double __ieee754_remainder(double,double); 198 int __ieee754_rem_pio2(double,double*); 199 double __ieee754_scalb(double,double); 200 201 /* fdlibm kernel function */ 202 double __kernel_standard(double,double,int); 203 double __kernel_sin(double,double,int); 204 double __kernel_cos(double,double); 205 double __kernel_tan(double,double,int); 206 int __kernel_rem_pio2(double*,double*,int,int,int,const int*); 207 208 /* ieee style elementary float functions */ 209 float __ieee754_sqrtf(float); 210 float __ieee754_acosf(float); 211 float __ieee754_acoshf(float); 212 float __ieee754_logf(float); 213 float __ieee754_atanhf(float); 214 float __ieee754_asinf(float); 215 float __ieee754_atan2f(float,float); 216 float __ieee754_expf(float); 217 float __ieee754_coshf(float); 218 float __ieee754_fmodf(float,float); 219 float __ieee754_powf(float,float); 220 float __ieee754_lgammaf_r(float,int *); 221 float __ieee754_gammaf_r(float,int *); 222 float __ieee754_lgammaf(float); 223 float __ieee754_gammaf(float); 224 float __ieee754_log10f(float); 225 float __ieee754_sinhf(float); 226 float __ieee754_hypotf(float,float); 227 float __ieee754_j0f(float); 228 float __ieee754_j1f(float); 229 float __ieee754_y0f(float); 230 float __ieee754_y1f(float); 231 float __ieee754_jnf(int,float); 232 float __ieee754_ynf(int,float); 233 float __ieee754_remainderf(float,float); 234 int __ieee754_rem_pio2f(float,float*); 235 float __ieee754_scalbf(float,float); 236 237 /* float versions of fdlibm kernel functions */ 238 float __kernel_sinf(float,float,int); 239 float __kernel_cosf(float,float); 240 float __kernel_tanf(float,float,int); 241 int __kernel_rem_pio2f(float*,float*,int,int,int,const int*); 242 243 #endif /* !_MATH_PRIVATE_H_ */