/ base / math / mathP.h
mathP.h
  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   * $Id: mathP.h,v 1.6 2013/10/22 14:54:15 ando Exp $
 15   */
 16  
 17  #ifndef _MATH_PRIVATE_H_
 18  #define _MATH_PRIVATE_H_
 19  
 20  #include <endian.h>
 21  #include <sys/types.h>
 22  
 23  /* The original fdlibm code used statements like:
 24  	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
 25  	ix0 = *(n0+(int*)&x);			* high word of x *
 26  	ix1 = *((1-n0)+(int*)&x);		* low word of x *
 27     to dig two 32 bit words out of the 64 bit IEEE floating point
 28     value.  That is non-ANSI, and, moreover, the gcc instruction
 29     scheduler gets it wrong.  We instead use the following macros.
 30     Unlike the original code, we determine the endianness at compile
 31     time, not at run time; I don't see much benefit to selecting
 32     endianness at run time.  */
 33  
 34  /* A union which permits us to convert between a double and two 32 bit
 35     ints.  */
 36  
 37  /*
 38   * Math on arm is little endian except for the FP word order which is
 39   * big endian.
 40   */
 41  
 42  #if (__BYTE_ORDER == __BIG_ENDIAN) || defined(__arm__)
 43  
 44  typedef union 
 45  {
 46    double value;
 47    struct 
 48    {
 49      u_int32_t msw;
 50      u_int32_t lsw;
 51    } parts;
 52  } ieee_double_shape_type;
 53  
 54  #endif
 55  
 56  #if (__BYTE_ORDER == __LITTLE_ENDIAN) && !defined(__arm__)
 57  
 58  typedef union 
 59  {
 60    double value;
 61    struct 
 62    {
 63      u_int32_t lsw;
 64      u_int32_t msw;
 65    } parts;
 66  } ieee_double_shape_type;
 67  
 68  #endif
 69  
 70  /* Get two 32 bit ints from a double.  */
 71  
 72  #define EXTRACT_WORDS(ix0,ix1,d)				\
 73  do {								\
 74    ieee_double_shape_type ew_u;					\
 75    ew_u.value = (d);						\
 76    (ix0) = ew_u.parts.msw;					\
 77    (ix1) = ew_u.parts.lsw;					\
 78  } while (0)
 79  
 80  /* Get the more significant 32 bit int from a double.  */
 81  
 82  #define GET_HIGH_WORD(i,d)					\
 83  do {								\
 84    ieee_double_shape_type gh_u;					\
 85    gh_u.value = (d);						\
 86    (i) = gh_u.parts.msw;						\
 87  } while (0)
 88  
 89  /* Get the less significant 32 bit int from a double.  */
 90  
 91  #define GET_LOW_WORD(i,d)					\
 92  do {								\
 93    ieee_double_shape_type gl_u;					\
 94    gl_u.value = (d);						\
 95    (i) = gl_u.parts.lsw;						\
 96  } while (0)
 97  
 98  /* Set a double from two 32 bit ints.  */
 99  
100  #define INSERT_WORDS(d,ix0,ix1)					\
101  do {								\
102    ieee_double_shape_type iw_u;					\
103    iw_u.parts.msw = (ix0);					\
104    iw_u.parts.lsw = (ix1);					\
105    (d) = iw_u.value;						\
106  } while (0)
107  
108  /* Set the more significant 32 bits of a double from an int.  */
109  
110  #define SET_HIGH_WORD(d,v)					\
111  do {								\
112    ieee_double_shape_type sh_u;					\
113    sh_u.value = (d);						\
114    sh_u.parts.msw = (v);						\
115    (d) = sh_u.value;						\
116  } while (0)
117  
118  /* Set the less significant 32 bits of a double from an int.  */
119  
120  #define SET_LOW_WORD(d,v)					\
121  do {								\
122    ieee_double_shape_type sl_u;					\
123    sl_u.value = (d);						\
124    sl_u.parts.lsw = (v);						\
125    (d) = sl_u.value;						\
126  } while (0)
127  
128  /* A union which permits us to convert between a float and a 32 bit
129     int.  */
130  
131  typedef union
132  {
133    float value;
134    u_int32_t word;
135  } ieee_float_shape_type;
136  
137  /* Get a 32 bit int from a float.  */
138  
139  #define GET_FLOAT_WORD(i,d)					\
140  do {								\
141    ieee_float_shape_type gf_u;					\
142    gf_u.value = (d);						\
143    (i) = gf_u.word;						\
144  } while (0)
145  
146  /* Set a float from a 32 bit int.  */
147  
148  #define SET_FLOAT_WORD(d,i)					\
149  do {								\
150    ieee_float_shape_type sf_u;					\
151    sf_u.word = (i);						\
152    (d) = sf_u.value;						\
153  } while (0)
154  
155  /* ieee style elementary functions */
156  extern double __ieee754_sqrt __P((double));			
157  extern double __ieee754_acos __P((double));			
158  extern double __ieee754_acosh __P((double));			
159  extern double __ieee754_log __P((double));			
160  extern double __ieee754_atanh __P((double));			
161  extern double __ieee754_asin __P((double));			
162  extern double __ieee754_atan2 __P((double,double));			
163  extern double __ieee754_exp __P((double));
164  extern double __ieee754_cosh __P((double));
165  extern double __ieee754_fmod __P((double,double));
166  extern double __ieee754_pow __P((double,double));
167  extern double __ieee754_lgamma_r __P((double,int *));
168  extern double __ieee754_gamma_r __P((double,int *));
169  extern double __ieee754_lgamma __P((double));
170  extern double __ieee754_gamma __P((double));
171  extern double __ieee754_log10 __P((double));
172  extern double __ieee754_sinh __P((double));
173  extern double __ieee754_hypot __P((double,double));
174  extern double __ieee754_j0 __P((double));
175  extern double __ieee754_j1 __P((double));
176  extern double __ieee754_y0 __P((double));
177  extern double __ieee754_y1 __P((double));
178  extern double __ieee754_jn __P((int,double));
179  extern double __ieee754_yn __P((int,double));
180  extern double __ieee754_remainder __P((double,double));
181  extern int    __ieee754_rem_pio2 __P((double,double*));
182  #if defined(_SCALB_INT)
183  extern double __ieee754_scalb __P((double,int));
184  #else
185  extern double __ieee754_scalb __P((double,double));
186  #endif
187  
188  /* fdlibm kernel function */
189  extern double __kernel_standard __P((double,double,int));	
190  extern double __kernel_sin __P((double,double,int));
191  extern double __kernel_cos __P((double,double));
192  extern double __kernel_tan __P((double,double,int));
193  extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
194  
195  
196  /* ieee style elementary float functions */
197  extern float __ieee754_sqrtf __P((float));			
198  extern float __ieee754_acosf __P((float));			
199  extern float __ieee754_acoshf __P((float));			
200  extern float __ieee754_logf __P((float));			
201  extern float __ieee754_atanhf __P((float));			
202  extern float __ieee754_asinf __P((float));			
203  extern float __ieee754_atan2f __P((float,float));			
204  extern float __ieee754_expf __P((float));
205  extern float __ieee754_coshf __P((float));
206  extern float __ieee754_fmodf __P((float,float));
207  extern float __ieee754_powf __P((float,float));
208  extern float __ieee754_lgammaf_r __P((float,int *));
209  extern float __ieee754_gammaf_r __P((float,int *));
210  extern float __ieee754_lgammaf __P((float));
211  extern float __ieee754_gammaf __P((float));
212  extern float __ieee754_log10f __P((float));
213  extern float __ieee754_sinhf __P((float));
214  extern float __ieee754_hypotf __P((float,float));
215  extern float __ieee754_j0f __P((float));
216  extern float __ieee754_j1f __P((float));
217  extern float __ieee754_y0f __P((float));
218  extern float __ieee754_y1f __P((float));
219  extern float __ieee754_jnf __P((int,float));
220  extern float __ieee754_ynf __P((int,float));
221  extern float __ieee754_remainderf __P((float,float));
222  extern int   __ieee754_rem_pio2f __P((float,float*));
223  extern float __ieee754_scalbf __P((float,float));
224  
225  /* float versions of fdlibm kernel functions */
226  extern float __kernel_sinf __P((float,float,int));
227  extern float __kernel_cosf __P((float,float));
228  extern float __kernel_tanf __P((float,float,int));
229  extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
230  
231  #endif /* _MATH_PRIVATE_H_ */