# mathP.h

    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  * $Id: mathP_8h-source.html,v 1.3 2005/03/18 09:30:00 rpm Exp $
    00015  */
    00016
    00017 #ifndef _MATH_PRIVATE_H_
    00018 #define _MATH_PRIVATE_H_
    00019
    00020 #include <endian.h>
    00021 #include <sys/types.h>
    00022
    00023 /* The original fdlibm code used statements like:
    00024         n0 = ((*(int*)&one)>>29)^1;             * index of high word *
    00025         ix0 = *(n0+(int*)&x);                   * high word of x *
    00026         ix1 = *((1-n0)+(int*)&x);               * low word of x *
    00027    to dig two 32 bit words out of the 64 bit IEEE floating point
    00028    value.  That is non-ANSI, and, moreover, the gcc instruction
    00029    scheduler gets it wrong.  We instead use the following macros.
    00030    Unlike the original code, we determine the endianness at compile
    00031    time, not at run time; I don't see much benefit to selecting
    00032    endianness at run time.  */
    00033
    00034 /* A union which permits us to convert between a double and two 32 bit
    00035    ints.  */
    00036
    00037 /*
    00038  * Math on arm is little endian except for the FP word order which is
    00039  * big endian.
    00040  */
    00041
    00042 #if (__BYTE_ORDER == __BIG_ENDIAN) || defined(__arm__)
    00043
    00044 typedef union
    00045 {
    00046   double value;
    00047   struct
    00048   {
    00049     u_int32_t msw;
    00050     u_int32_t lsw;
    00051   } parts;
    00052 } ieee_double_shape_type;
    00053
    00054 #endif
    00055
    00056 #if (__BYTE_ORDER == __LITTLE_ENDIAN) && !defined(__arm__)
    00057
    00058 typedef union
    00059 {
    00060   double value;
    00061   struct
    00062   {
    00063     u_int32_t lsw;
    00064     u_int32_t msw;
    00065   } parts;
    00066 } ieee_double_shape_type;
    00067
    00068 #endif
    00069
    00070 /* Get two 32 bit ints from a double.  */
    00071
    00072 #define EXTRACT_WORDS(ix0,ix1,d)                                \
    00073 do {                                                            \
    00074   ieee_double_shape_type ew_u;                                  \
    00075   ew_u.value = (d);                                             \
    00076   (ix0) = ew_u.parts.msw;                                       \
    00077   (ix1) = ew_u.parts.lsw;                                       \
    00078 } while (0)
    00079
    00080 /* Get the more significant 32 bit int from a double.  */
    00081
    00082 #define GET_HIGH_WORD(i,d)                                      \
    00083 do {                                                            \
    00084   ieee_double_shape_type gh_u;                                  \
    00085   gh_u.value = (d);                                             \
    00086   (i) = gh_u.parts.msw;                                         \
    00087 } while (0)
    00088
    00089 /* Get the less significant 32 bit int from a double.  */
    00090
    00091 #define GET_LOW_WORD(i,d)                                       \
    00092 do {                                                            \
    00093   ieee_double_shape_type gl_u;                                  \
    00094   gl_u.value = (d);                                             \
    00095   (i) = gl_u.parts.lsw;                                         \
    00096 } while (0)
    00097
    00098 /* Set a double from two 32 bit ints.  */
    00099
    00100 #define INSERT_WORDS(d,ix0,ix1)                                 \
    00101 do {                                                            \
    00102   ieee_double_shape_type iw_u;                                  \
    00103   iw_u.parts.msw = (ix0);                                       \
    00104   iw_u.parts.lsw = (ix1);                                       \
    00105   (d) = iw_u.value;                                             \
    00106 } while (0)
    00107
    00108 /* Set the more significant 32 bits of a double from an int.  */
    00109
    00110 #define SET_HIGH_WORD(d,v)                                      \
    00111 do {                                                            \
    00112   ieee_double_shape_type sh_u;                                  \
    00113   sh_u.value = (d);                                             \
    00114   sh_u.parts.msw = (v);                                         \
    00115   (d) = sh_u.value;                                             \
    00116 } while (0)
    00117
    00118 /* Set the less significant 32 bits of a double from an int.  */
    00119
    00120 #define SET_LOW_WORD(d,v)                                       \
    00121 do {                                                            \
    00122   ieee_double_shape_type sl_u;                                  \
    00123   sl_u.value = (d);                                             \
    00124   sl_u.parts.lsw = (v);                                         \
    00125   (d) = sl_u.value;                                             \
    00126 } while (0)
    00127
    00128 /* A union which permits us to convert between a float and a 32 bit
    00129    int.  */
    00130
    00131 typedef union
    00132 {
    00133   float value;
    00134   u_int32_t word;
    00135 } ieee_float_shape_type;
    00136
    00137 /* Get a 32 bit int from a float.  */
    00138
    00139 #define GET_FLOAT_WORD(i,d)                                     \
    00140 do {                                                            \
    00141   ieee_float_shape_type gf_u;                                   \
    00142   gf_u.value = (d);                                             \
    00143   (i) = gf_u.word;                                              \
    00144 } while (0)
    00145
    00146 /* Set a float from a 32 bit int.  */
    00147
    00148 #define SET_FLOAT_WORD(d,i)                                     \
    00149 do {                                                            \
    00150   ieee_float_shape_type sf_u;                                   \
    00151   sf_u.word = (i);                                              \
    00152   (d) = sf_u.value;                                             \
    00153 } while (0)
    00154
    00155 /* ieee style elementary functions */
    00156 extern double __ieee754_sqrt __P((double));
    00157 extern double __ieee754_acos __P((double));
    00158 extern double __ieee754_acosh __P((double));
    00159 extern double __ieee754_log __P((double));
    00160 extern double __ieee754_atanh __P((double));
    00161 extern double __ieee754_asin __P((double));
    00162 extern double __ieee754_atan2 __P((double,double));
    00163 extern double __ieee754_exp __P((double));
    00164 extern double __ieee754_cosh __P((double));
    00165 extern double __ieee754_fmod __P((double,double));
    00166 extern double __ieee754_pow __P((double,double));
    00167 extern double __ieee754_lgamma_r __P((double,int *));
    00168 extern double __ieee754_gamma_r __P((double,int *));
    00169 extern double __ieee754_lgamma __P((double));
    00170 extern double __ieee754_gamma __P((double));
    00171 extern double __ieee754_log10 __P((double));
    00172 extern double __ieee754_sinh __P((double));
    00173 extern double __ieee754_hypot __P((double,double));
    00174 extern double __ieee754_j0 __P((double));
    00175 extern double __ieee754_j1 __P((double));
    00176 extern double __ieee754_y0 __P((double));
    00177 extern double __ieee754_y1 __P((double));
    00178 extern double __ieee754_jn __P((int,double));
    00179 extern double __ieee754_yn __P((int,double));
    00180 extern double __ieee754_remainder __P((double,double));
    00181 extern int    __ieee754_rem_pio2 __P((double,double*));
    00182 #if defined(_SCALB_INT)
    00183 extern double __ieee754_scalb __P((double,int));
    00184 #else
    00185 extern double __ieee754_scalb __P((double,double));
    00186 #endif
    00187
    00188 /* fdlibm kernel function */
    00189 extern double __kernel_standard __P((double,double,int));
    00190 extern double __kernel_sin __P((double,double,int));
    00191 extern double __kernel_cos __P((double,double));
    00192 extern double __kernel_tan __P((double,double,int));
    00193 extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
    00194
    00195
    00196 /* ieee style elementary float functions */
    00197 extern float __ieee754_sqrtf __P((float));
    00198 extern float __ieee754_acosf __P((float));
    00199 extern float __ieee754_acoshf __P((float));
    00200 extern float __ieee754_logf __P((float));
    00201 extern float __ieee754_atanhf __P((float));
    00202 extern float __ieee754_asinf __P((float));
    00203 extern float __ieee754_atan2f __P((float,float));
    00204 extern float __ieee754_expf __P((float));
    00205 extern float __ieee754_coshf __P((float));
    00206 extern float __ieee754_fmodf __P((float,float));
    00207 extern float __ieee754_powf __P((float,float));
    00208 extern float __ieee754_lgammaf_r __P((float,int *));
    00209 extern float __ieee754_gammaf_r __P((float,int *));
    00210 extern float __ieee754_lgammaf __P((float));
    00211 extern float __ieee754_gammaf __P((float));
    00212 extern float __ieee754_log10f __P((float));
    00213 extern float __ieee754_sinhf __P((float));
    00214 extern float __ieee754_hypotf __P((float,float));
    00215 extern float __ieee754_j0f __P((float));
    00216 extern float __ieee754_j1f __P((float));
    00217 extern float __ieee754_y0f __P((float));
    00218 extern float __ieee754_y1f __P((float));
    00219 extern float __ieee754_jnf __P((int,float));
    00220 extern float __ieee754_ynf __P((int,float));
    00221 extern float __ieee754_remainderf __P((float,float));
    00222 extern int   __ieee754_rem_pio2f __P((float,float*));
    00223 extern float __ieee754_scalbf __P((float,float));
    00224
    00225 /* float versions of fdlibm kernel functions */
    00226 extern float __kernel_sinf __P((float,float,int));
    00227 extern float __kernel_cosf __P((float,float));
    00228 extern float __kernel_tanf __P((float,float,int));
    00229 extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
    00230
    00231 #endif /* _MATH_PRIVATE_H_ */