Back to index

glibc  2.9
math_private.h
Go to the documentation of this file.
00001 /*
00002  * ====================================================
00003  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00004  *
00005  * Developed at SunPro, a Sun Microsystems, Inc. business.
00006  * Permission to use, copy, modify, and distribute this
00007  * software is freely granted, provided that this notice
00008  * is preserved.
00009  * ====================================================
00010  */
00011 
00012 /*
00013  * from: @(#)fdlibm.h 5.1 93/09/24
00014  */
00015 
00016 #ifndef _MATH_PRIVATE_H_
00017 #define _MATH_PRIVATE_H_
00018 
00019 #include <endian.h>
00020 #include <sys/types.h>
00021 
00022 /* The original fdlibm code used statements like:
00023        n0 = ((*(int*)&one)>>29)^1;        * index of high word *
00024        ix0 = *(n0+(int*)&x);                     * high word of x *
00025        ix1 = *((1-n0)+(int*)&x);          * low word of x *
00026    to dig two 32 bit words out of the 64 bit IEEE floating point
00027    value.  That is non-ANSI, and, moreover, the gcc instruction
00028    scheduler gets it wrong.  We instead use the following macros.
00029    Unlike the original code, we determine the endianness at compile
00030    time, not at run time; I don't see much benefit to selecting
00031    endianness at run time.  */
00032 
00033 /* A union which permits us to convert between a double and two 32 bit
00034    ints.  */
00035 
00036 #if __FLOAT_WORD_ORDER == BIG_ENDIAN
00037 
00038 typedef union
00039 {
00040   double value;
00041   struct
00042   {
00043     u_int32_t msw;
00044     u_int32_t lsw;
00045   } parts;
00046 } ieee_double_shape_type;
00047 
00048 #endif
00049 
00050 #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
00051 
00052 typedef union
00053 {
00054   double value;
00055   struct
00056   {
00057     u_int32_t lsw;
00058     u_int32_t msw;
00059   } parts;
00060 } ieee_double_shape_type;
00061 
00062 #endif
00063 
00064 /* Get two 32 bit ints from a double.  */
00065 
00066 #define EXTRACT_WORDS(ix0,ix1,d)                        \
00067 do {                                                    \
00068   ieee_double_shape_type ew_u;                                 \
00069   ew_u.value = (d);                                     \
00070   (ix0) = ew_u.parts.msw;                               \
00071   (ix1) = ew_u.parts.lsw;                               \
00072 } while (0)
00073 
00074 /* Get the more significant 32 bit int from a double.  */
00075 
00076 #define GET_HIGH_WORD(i,d)                              \
00077 do {                                                    \
00078   ieee_double_shape_type gh_u;                                 \
00079   gh_u.value = (d);                                     \
00080   (i) = gh_u.parts.msw;                                        \
00081 } while (0)
00082 
00083 /* Get the less significant 32 bit int from a double.  */
00084 
00085 #define GET_LOW_WORD(i,d)                               \
00086 do {                                                    \
00087   ieee_double_shape_type gl_u;                                 \
00088   gl_u.value = (d);                                     \
00089   (i) = gl_u.parts.lsw;                                        \
00090 } while (0)
00091 
00092 /* Set a double from two 32 bit ints.  */
00093 
00094 #define INSERT_WORDS(d,ix0,ix1)                                \
00095 do {                                                    \
00096   ieee_double_shape_type iw_u;                                 \
00097   iw_u.parts.msw = (ix0);                               \
00098   iw_u.parts.lsw = (ix1);                               \
00099   (d) = iw_u.value;                                     \
00100 } while (0)
00101 
00102 /* Set the more significant 32 bits of a double from an int.  */
00103 
00104 #define SET_HIGH_WORD(d,v)                              \
00105 do {                                                    \
00106   ieee_double_shape_type sh_u;                                 \
00107   sh_u.value = (d);                                     \
00108   sh_u.parts.msw = (v);                                        \
00109   (d) = sh_u.value;                                     \
00110 } while (0)
00111 
00112 /* Set the less significant 32 bits of a double from an int.  */
00113 
00114 #define SET_LOW_WORD(d,v)                               \
00115 do {                                                    \
00116   ieee_double_shape_type sl_u;                                 \
00117   sl_u.value = (d);                                     \
00118   sl_u.parts.lsw = (v);                                        \
00119   (d) = sl_u.value;                                     \
00120 } while (0)
00121 
00122 /* A union which permits us to convert between a float and a 32 bit
00123    int.  */
00124 
00125 typedef union
00126 {
00127   float value;
00128   u_int32_t word;
00129 } ieee_float_shape_type;
00130 
00131 /* Get a 32 bit int from a float.  */
00132 
00133 #define GET_FLOAT_WORD(i,d)                             \
00134 do {                                                    \
00135   ieee_float_shape_type gf_u;                                  \
00136   gf_u.value = (d);                                     \
00137   (i) = gf_u.word;                                      \
00138 } while (0)
00139 
00140 /* Set a float from a 32 bit int.  */
00141 
00142 #define SET_FLOAT_WORD(d,i)                             \
00143 do {                                                    \
00144   ieee_float_shape_type sf_u;                                  \
00145   sf_u.word = (i);                                      \
00146   (d) = sf_u.value;                                     \
00147 } while (0)
00148 
00149 /* Get long double macros from a separate header.  */
00150 #include <math_ldbl.h>
00151 
00152 /* ieee style elementary functions */
00153 extern double __ieee754_sqrt (double);
00154 extern double __ieee754_acos (double);
00155 extern double __ieee754_acosh (double);
00156 extern double __ieee754_log (double);
00157 extern double __ieee754_atanh (double);
00158 extern double __ieee754_asin (double);
00159 extern double __ieee754_atan2 (double,double);
00160 extern double __ieee754_exp (double);
00161 extern double __ieee754_exp2 (double);
00162 extern double __ieee754_exp10 (double);
00163 extern double __ieee754_cosh (double);
00164 extern double __ieee754_fmod (double,double);
00165 extern double __ieee754_pow (double,double);
00166 extern double __ieee754_lgamma_r (double,int *);
00167 extern double __ieee754_gamma_r (double,int *);
00168 extern double __ieee754_lgamma (double);
00169 extern double __ieee754_gamma (double);
00170 extern double __ieee754_log10 (double);
00171 extern double __ieee754_log2 (double);
00172 extern double __ieee754_sinh (double);
00173 extern double __ieee754_hypot (double,double);
00174 extern double __ieee754_j0 (double);
00175 extern double __ieee754_j1 (double);
00176 extern double __ieee754_y0 (double);
00177 extern double __ieee754_y1 (double);
00178 extern double __ieee754_jn (int,double);
00179 extern double __ieee754_yn (int,double);
00180 extern double __ieee754_remainder (double,double);
00181 extern int32_t __ieee754_rem_pio2 (double,double*);
00182 extern double __ieee754_scalb (double,double);
00183 
00184 /* fdlibm kernel function */
00185 extern double __kernel_standard (double,double,int);
00186 extern double __kernel_sin (double,double,int);
00187 extern double __kernel_cos (double,double);
00188 extern double __kernel_tan (double,double,int);
00189 extern int    __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*);
00190 
00191 /* internal functions.  */
00192 extern double __copysign (double x, double __y);
00193 
00194 #if __GNUC_PREREQ (4, 0)
00195 extern inline double __copysign (double x, double y)
00196 { return __builtin_copysign (x, y); }
00197 #endif
00198 
00199 /* ieee style elementary float functions */
00200 extern float __ieee754_sqrtf (float);
00201 extern float __ieee754_acosf (float);
00202 extern float __ieee754_acoshf (float);
00203 extern float __ieee754_logf (float);
00204 extern float __ieee754_atanhf (float);
00205 extern float __ieee754_asinf (float);
00206 extern float __ieee754_atan2f (float,float);
00207 extern float __ieee754_expf (float);
00208 extern float __ieee754_exp2f (float);
00209 extern float __ieee754_exp10f (float);
00210 extern float __ieee754_coshf (float);
00211 extern float __ieee754_fmodf (float,float);
00212 extern float __ieee754_powf (float,float);
00213 extern float __ieee754_lgammaf_r (float,int *);
00214 extern float __ieee754_gammaf_r (float,int *);
00215 extern float __ieee754_lgammaf (float);
00216 extern float __ieee754_gammaf (float);
00217 extern float __ieee754_log10f (float);
00218 extern float __ieee754_log2f (float);
00219 extern float __ieee754_sinhf (float);
00220 extern float __ieee754_hypotf (float,float);
00221 extern float __ieee754_j0f (float);
00222 extern float __ieee754_j1f (float);
00223 extern float __ieee754_y0f (float);
00224 extern float __ieee754_y1f (float);
00225 extern float __ieee754_jnf (int,float);
00226 extern float __ieee754_ynf (int,float);
00227 extern float __ieee754_remainderf (float,float);
00228 extern int32_t __ieee754_rem_pio2f (float,float*);
00229 extern float __ieee754_scalbf (float,float);
00230 
00231 
00232 /* float versions of fdlibm kernel functions */
00233 extern float __kernel_sinf (float,float,int);
00234 extern float __kernel_cosf (float,float);
00235 extern float __kernel_tanf (float,float,int);
00236 extern int   __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*);
00237 
00238 /* internal functions.  */
00239 extern float __copysignf (float x, float __y);
00240 
00241 #if __GNUC_PREREQ (4, 0)
00242 extern inline float __copysignf (float x, float y)
00243 { return __builtin_copysignf (x, y); }
00244 #endif
00245 
00246 /* ieee style elementary long double functions */
00247 extern long double __ieee754_sqrtl (long double);
00248 extern long double __ieee754_acosl (long double);
00249 extern long double __ieee754_acoshl (long double);
00250 extern long double __ieee754_logl (long double);
00251 extern long double __ieee754_atanhl (long double);
00252 extern long double __ieee754_asinl (long double);
00253 extern long double __ieee754_atan2l (long double,long double);
00254 extern long double __ieee754_expl (long double);
00255 extern long double __ieee754_exp2l (long double);
00256 extern long double __ieee754_exp10l (long double);
00257 extern long double __ieee754_coshl (long double);
00258 extern long double __ieee754_fmodl (long double,long double);
00259 extern long double __ieee754_powl (long double,long double);
00260 extern long double __ieee754_lgammal_r (long double,int *);
00261 extern long double __ieee754_gammal_r (long double,int *);
00262 extern long double __ieee754_lgammal (long double);
00263 extern long double __ieee754_gammal (long double);
00264 extern long double __ieee754_log10l (long double);
00265 extern long double __ieee754_log2l (long double);
00266 extern long double __ieee754_sinhl (long double);
00267 extern long double __ieee754_hypotl (long double,long double);
00268 extern long double __ieee754_j0l (long double);
00269 extern long double __ieee754_j1l (long double);
00270 extern long double __ieee754_y0l (long double);
00271 extern long double __ieee754_y1l (long double);
00272 extern long double __ieee754_jnl (int,long double);
00273 extern long double __ieee754_ynl (int,long double);
00274 extern long double __ieee754_remainderl (long double,long double);
00275 extern int   __ieee754_rem_pio2l (long double,long double*);
00276 extern long double __ieee754_scalbl (long double,long double);
00277 
00278 /* long double versions of fdlibm kernel functions */
00279 extern long double __kernel_sinl (long double,long double,int);
00280 extern long double __kernel_cosl (long double,long double);
00281 extern long double __kernel_tanl (long double,long double,int);
00282 extern void __kernel_sincosl (long double,long double,
00283                            long double *,long double *, int);
00284 extern int   __kernel_rem_pio2l (long double*,long double*,int,int,
00285                              int,const int*);
00286 
00287 #ifndef NO_LONG_DOUBLE
00288 /* prototypes required to compile the ldbl-96 support without warnings */
00289 extern int __finitel (long double);
00290 extern int __ilogbl (long double);
00291 extern int __isinfl (long double);
00292 extern int __isnanl (long double);
00293 extern long double __atanl (long double);
00294 extern long double __copysignl (long double, long double);
00295 extern long double __expm1l (long double);
00296 extern long double __floorl (long double);
00297 extern long double __frexpl (long double, int *);
00298 extern long double __ldexpl (long double, int);
00299 extern long double __log1pl (long double);
00300 extern long double __nanl (const char *);
00301 extern long double __rintl (long double);
00302 extern long double __scalbnl (long double, int);
00303 extern long double __sqrtl (long double x);
00304 extern long double fabsl (long double x);
00305 extern void __sincosl (long double, long double *, long double *);
00306 extern long double __logbl (long double x);
00307 extern long double __significandl (long double x);
00308 
00309 #if __GNUC_PREREQ (4, 0)
00310 extern inline long double __copysignl (long double x, long double y)
00311 { return __builtin_copysignl (x, y); }
00312 #endif
00313 
00314 #endif
00315 
00316 /* Prototypes for functions of the IBM Accurate Mathematical Library.  */
00317 extern double __exp1 (double __x, double __xx, double __error);
00318 extern double __sin (double __x);
00319 extern double __cos (double __x);
00320 extern int __branred (double __x, double *__a, double *__aa);
00321 extern void __doasin (double __x, double __dx, double __v[]);
00322 extern void __dubsin (double __x, double __dx, double __v[]);
00323 extern void __dubcos (double __x, double __dx, double __v[]);
00324 extern double __halfulp (double __x, double __y);
00325 extern double __sin32 (double __x, double __res, double __res1);
00326 extern double __cos32 (double __x, double __res, double __res1);
00327 extern double __mpsin (double __x, double __dx);
00328 extern double __mpcos (double __x, double __dx);
00329 extern double __mpsin1 (double __x);
00330 extern double __mpcos1 (double __x);
00331 extern double __slowexp (double __x);
00332 extern double __slowpow (double __x, double __y, double __z);
00333 extern void __docos (double __x, double __dx, double __v[]);
00334 
00335 #ifndef math_opt_barrier
00336 #define math_opt_barrier(x) \
00337 ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
00338 #define math_force_eval(x) __asm __volatile ("" : : "m" (x))
00339 #endif
00340 
00341 #endif /* _MATH_PRIVATE_H_ */