xref: /freebsd/lib/msun/src/math_private.h (revision 3a8617a83f16ffc9db4f96e1f0f21af94078e6b1)
13a8617a8SJordan K. Hubbard /*
23a8617a8SJordan K. Hubbard  * ====================================================
33a8617a8SJordan K. Hubbard  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
43a8617a8SJordan K. Hubbard  *
53a8617a8SJordan K. Hubbard  * Developed at SunPro, a Sun Microsystems, Inc. business.
63a8617a8SJordan K. Hubbard  * Permission to use, copy, modify, and distribute this
73a8617a8SJordan K. Hubbard  * software is freely granted, provided that this notice
83a8617a8SJordan K. Hubbard  * is preserved.
93a8617a8SJordan K. Hubbard  * ====================================================
103a8617a8SJordan K. Hubbard  */
113a8617a8SJordan K. Hubbard 
123a8617a8SJordan K. Hubbard /*
133a8617a8SJordan K. Hubbard  * from: @(#)fdlibm.h 5.1 93/09/24
143a8617a8SJordan K. Hubbard  * $Id: math_private.h,v 1.2 1994/08/18 23:06:19 jtc Exp $
153a8617a8SJordan K. Hubbard  */
163a8617a8SJordan K. Hubbard 
173a8617a8SJordan K. Hubbard #ifndef _MATH_PRIVATE_H_
183a8617a8SJordan K. Hubbard #define _MATH_PRIVATE_H_
193a8617a8SJordan K. Hubbard 
203a8617a8SJordan K. Hubbard #include <machine/endian.h>
213a8617a8SJordan K. Hubbard #include <sys/types.h>
223a8617a8SJordan K. Hubbard 
233a8617a8SJordan K. Hubbard /* The original fdlibm code used statements like:
243a8617a8SJordan K. Hubbard 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
253a8617a8SJordan K. Hubbard 	ix0 = *(n0+(int*)&x);			* high word of x *
263a8617a8SJordan K. Hubbard 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
273a8617a8SJordan K. Hubbard    to dig two 32 bit words out of the 64 bit IEEE floating point
283a8617a8SJordan K. Hubbard    value.  That is non-ANSI, and, moreover, the gcc instruction
293a8617a8SJordan K. Hubbard    scheduler gets it wrong.  We instead use the following macros.
303a8617a8SJordan K. Hubbard    Unlike the original code, we determine the endianness at compile
313a8617a8SJordan K. Hubbard    time, not at run time; I don't see much benefit to selecting
323a8617a8SJordan K. Hubbard    endianness at run time.  */
333a8617a8SJordan K. Hubbard 
343a8617a8SJordan K. Hubbard /* A union which permits us to convert between a double and two 32 bit
353a8617a8SJordan K. Hubbard    ints.  */
363a8617a8SJordan K. Hubbard 
373a8617a8SJordan K. Hubbard #if BYTE_ORDER == BIG_ENDIAN
383a8617a8SJordan K. Hubbard 
393a8617a8SJordan K. Hubbard typedef union
403a8617a8SJordan K. Hubbard {
413a8617a8SJordan K. Hubbard   double value;
423a8617a8SJordan K. Hubbard   struct
433a8617a8SJordan K. Hubbard   {
443a8617a8SJordan K. Hubbard     u_int32_t msw;
453a8617a8SJordan K. Hubbard     u_int32_t lsw;
463a8617a8SJordan K. Hubbard   } parts;
473a8617a8SJordan K. Hubbard } ieee_double_shape_type;
483a8617a8SJordan K. Hubbard 
493a8617a8SJordan K. Hubbard #endif
503a8617a8SJordan K. Hubbard 
513a8617a8SJordan K. Hubbard #if BYTE_ORDER == LITTLE_ENDIAN
523a8617a8SJordan K. Hubbard 
533a8617a8SJordan K. Hubbard typedef union
543a8617a8SJordan K. Hubbard {
553a8617a8SJordan K. Hubbard   double value;
563a8617a8SJordan K. Hubbard   struct
573a8617a8SJordan K. Hubbard   {
583a8617a8SJordan K. Hubbard     u_int32_t lsw;
593a8617a8SJordan K. Hubbard     u_int32_t msw;
603a8617a8SJordan K. Hubbard   } parts;
613a8617a8SJordan K. Hubbard } ieee_double_shape_type;
623a8617a8SJordan K. Hubbard 
633a8617a8SJordan K. Hubbard #endif
643a8617a8SJordan K. Hubbard 
653a8617a8SJordan K. Hubbard /* Get two 32 bit ints from a double.  */
663a8617a8SJordan K. Hubbard 
673a8617a8SJordan K. Hubbard #define EXTRACT_WORDS(ix0,ix1,d)				\
683a8617a8SJordan K. Hubbard do {								\
693a8617a8SJordan K. Hubbard   ieee_double_shape_type ew_u;					\
703a8617a8SJordan K. Hubbard   ew_u.value = (d);						\
713a8617a8SJordan K. Hubbard   (ix0) = ew_u.parts.msw;					\
723a8617a8SJordan K. Hubbard   (ix1) = ew_u.parts.lsw;					\
733a8617a8SJordan K. Hubbard } while (0)
743a8617a8SJordan K. Hubbard 
753a8617a8SJordan K. Hubbard /* Get the more significant 32 bit int from a double.  */
763a8617a8SJordan K. Hubbard 
773a8617a8SJordan K. Hubbard #define GET_HIGH_WORD(i,d)					\
783a8617a8SJordan K. Hubbard do {								\
793a8617a8SJordan K. Hubbard   ieee_double_shape_type gh_u;					\
803a8617a8SJordan K. Hubbard   gh_u.value = (d);						\
813a8617a8SJordan K. Hubbard   (i) = gh_u.parts.msw;						\
823a8617a8SJordan K. Hubbard } while (0)
833a8617a8SJordan K. Hubbard 
843a8617a8SJordan K. Hubbard /* Get the less significant 32 bit int from a double.  */
853a8617a8SJordan K. Hubbard 
863a8617a8SJordan K. Hubbard #define GET_LOW_WORD(i,d)					\
873a8617a8SJordan K. Hubbard do {								\
883a8617a8SJordan K. Hubbard   ieee_double_shape_type gl_u;					\
893a8617a8SJordan K. Hubbard   gl_u.value = (d);						\
903a8617a8SJordan K. Hubbard   (i) = gl_u.parts.lsw;						\
913a8617a8SJordan K. Hubbard } while (0)
923a8617a8SJordan K. Hubbard 
933a8617a8SJordan K. Hubbard /* Set a double from two 32 bit ints.  */
943a8617a8SJordan K. Hubbard 
953a8617a8SJordan K. Hubbard #define INSERT_WORDS(d,ix0,ix1)					\
963a8617a8SJordan K. Hubbard do {								\
973a8617a8SJordan K. Hubbard   ieee_double_shape_type iw_u;					\
983a8617a8SJordan K. Hubbard   iw_u.parts.msw = (ix0);					\
993a8617a8SJordan K. Hubbard   iw_u.parts.lsw = (ix1);					\
1003a8617a8SJordan K. Hubbard   (d) = iw_u.value;						\
1013a8617a8SJordan K. Hubbard } while (0)
1023a8617a8SJordan K. Hubbard 
1033a8617a8SJordan K. Hubbard /* Set the more significant 32 bits of a double from an int.  */
1043a8617a8SJordan K. Hubbard 
1053a8617a8SJordan K. Hubbard #define SET_HIGH_WORD(d,v)					\
1063a8617a8SJordan K. Hubbard do {								\
1073a8617a8SJordan K. Hubbard   ieee_double_shape_type sh_u;					\
1083a8617a8SJordan K. Hubbard   sh_u.value = (d);						\
1093a8617a8SJordan K. Hubbard   sh_u.parts.msw = (v);						\
1103a8617a8SJordan K. Hubbard   (d) = sh_u.value;						\
1113a8617a8SJordan K. Hubbard } while (0)
1123a8617a8SJordan K. Hubbard 
1133a8617a8SJordan K. Hubbard /* Set the less significant 32 bits of a double from an int.  */
1143a8617a8SJordan K. Hubbard 
1153a8617a8SJordan K. Hubbard #define SET_LOW_WORD(d,v)					\
1163a8617a8SJordan K. Hubbard do {								\
1173a8617a8SJordan K. Hubbard   ieee_double_shape_type sl_u;					\
1183a8617a8SJordan K. Hubbard   sl_u.value = (d);						\
1193a8617a8SJordan K. Hubbard   sl_u.parts.lsw = (v);						\
1203a8617a8SJordan K. Hubbard   (d) = sl_u.value;						\
1213a8617a8SJordan K. Hubbard } while (0)
1223a8617a8SJordan K. Hubbard 
1233a8617a8SJordan K. Hubbard /* A union which permits us to convert between a float and a 32 bit
1243a8617a8SJordan K. Hubbard    int.  */
1253a8617a8SJordan K. Hubbard 
1263a8617a8SJordan K. Hubbard typedef union
1273a8617a8SJordan K. Hubbard {
1283a8617a8SJordan K. Hubbard   float value;
1293a8617a8SJordan K. Hubbard   /* FIXME: Assumes 32 bit int.  */
1303a8617a8SJordan K. Hubbard   unsigned int word;
1313a8617a8SJordan K. Hubbard } ieee_float_shape_type;
1323a8617a8SJordan K. Hubbard 
1333a8617a8SJordan K. Hubbard /* Get a 32 bit int from a float.  */
1343a8617a8SJordan K. Hubbard 
1353a8617a8SJordan K. Hubbard #define GET_FLOAT_WORD(i,d)					\
1363a8617a8SJordan K. Hubbard do {								\
1373a8617a8SJordan K. Hubbard   ieee_float_shape_type gf_u;					\
1383a8617a8SJordan K. Hubbard   gf_u.value = (d);						\
1393a8617a8SJordan K. Hubbard   (i) = gf_u.word;						\
1403a8617a8SJordan K. Hubbard } while (0)
1413a8617a8SJordan K. Hubbard 
1423a8617a8SJordan K. Hubbard /* Set a float from a 32 bit int.  */
1433a8617a8SJordan K. Hubbard 
1443a8617a8SJordan K. Hubbard #define SET_FLOAT_WORD(d,i)					\
1453a8617a8SJordan K. Hubbard do {								\
1463a8617a8SJordan K. Hubbard   ieee_float_shape_type sf_u;					\
1473a8617a8SJordan K. Hubbard   sf_u.word = (i);						\
1483a8617a8SJordan K. Hubbard   (d) = sf_u.value;						\
1493a8617a8SJordan K. Hubbard } while (0)
1503a8617a8SJordan K. Hubbard 
1513a8617a8SJordan K. Hubbard /* ieee style elementary functions */
1523a8617a8SJordan K. Hubbard extern double __ieee754_sqrt __P((double));
1533a8617a8SJordan K. Hubbard extern double __ieee754_acos __P((double));
1543a8617a8SJordan K. Hubbard extern double __ieee754_acosh __P((double));
1553a8617a8SJordan K. Hubbard extern double __ieee754_log __P((double));
1563a8617a8SJordan K. Hubbard extern double __ieee754_atanh __P((double));
1573a8617a8SJordan K. Hubbard extern double __ieee754_asin __P((double));
1583a8617a8SJordan K. Hubbard extern double __ieee754_atan2 __P((double,double));
1593a8617a8SJordan K. Hubbard extern double __ieee754_exp __P((double));
1603a8617a8SJordan K. Hubbard extern double __ieee754_cosh __P((double));
1613a8617a8SJordan K. Hubbard extern double __ieee754_fmod __P((double,double));
1623a8617a8SJordan K. Hubbard extern double __ieee754_pow __P((double,double));
1633a8617a8SJordan K. Hubbard extern double __ieee754_lgamma_r __P((double,int *));
1643a8617a8SJordan K. Hubbard extern double __ieee754_gamma_r __P((double,int *));
1653a8617a8SJordan K. Hubbard extern double __ieee754_lgamma __P((double));
1663a8617a8SJordan K. Hubbard extern double __ieee754_gamma __P((double));
1673a8617a8SJordan K. Hubbard extern double __ieee754_log10 __P((double));
1683a8617a8SJordan K. Hubbard extern double __ieee754_sinh __P((double));
1693a8617a8SJordan K. Hubbard extern double __ieee754_hypot __P((double,double));
1703a8617a8SJordan K. Hubbard extern double __ieee754_j0 __P((double));
1713a8617a8SJordan K. Hubbard extern double __ieee754_j1 __P((double));
1723a8617a8SJordan K. Hubbard extern double __ieee754_y0 __P((double));
1733a8617a8SJordan K. Hubbard extern double __ieee754_y1 __P((double));
1743a8617a8SJordan K. Hubbard extern double __ieee754_jn __P((int,double));
1753a8617a8SJordan K. Hubbard extern double __ieee754_yn __P((int,double));
1763a8617a8SJordan K. Hubbard extern double __ieee754_remainder __P((double,double));
1773a8617a8SJordan K. Hubbard extern int    __ieee754_rem_pio2 __P((double,double*));
1783a8617a8SJordan K. Hubbard extern double __ieee754_scalb __P((double,double));
1793a8617a8SJordan K. Hubbard 
1803a8617a8SJordan K. Hubbard /* fdlibm kernel function */
1813a8617a8SJordan K. Hubbard extern double __kernel_standard __P((double,double,int));
1823a8617a8SJordan K. Hubbard extern double __kernel_sin __P((double,double,int));
1833a8617a8SJordan K. Hubbard extern double __kernel_cos __P((double,double));
1843a8617a8SJordan K. Hubbard extern double __kernel_tan __P((double,double,int));
1853a8617a8SJordan K. Hubbard extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
1863a8617a8SJordan K. Hubbard 
1873a8617a8SJordan K. Hubbard 
1883a8617a8SJordan K. Hubbard /* ieee style elementary float functions */
1893a8617a8SJordan K. Hubbard extern float __ieee754_sqrtf __P((float));
1903a8617a8SJordan K. Hubbard extern float __ieee754_acosf __P((float));
1913a8617a8SJordan K. Hubbard extern float __ieee754_acoshf __P((float));
1923a8617a8SJordan K. Hubbard extern float __ieee754_logf __P((float));
1933a8617a8SJordan K. Hubbard extern float __ieee754_atanhf __P((float));
1943a8617a8SJordan K. Hubbard extern float __ieee754_asinf __P((float));
1953a8617a8SJordan K. Hubbard extern float __ieee754_atan2f __P((float,float));
1963a8617a8SJordan K. Hubbard extern float __ieee754_expf __P((float));
1973a8617a8SJordan K. Hubbard extern float __ieee754_coshf __P((float));
1983a8617a8SJordan K. Hubbard extern float __ieee754_fmodf __P((float,float));
1993a8617a8SJordan K. Hubbard extern float __ieee754_powf __P((float,float));
2003a8617a8SJordan K. Hubbard extern float __ieee754_lgammaf_r __P((float,int *));
2013a8617a8SJordan K. Hubbard extern float __ieee754_gammaf_r __P((float,int *));
2023a8617a8SJordan K. Hubbard extern float __ieee754_lgammaf __P((float));
2033a8617a8SJordan K. Hubbard extern float __ieee754_gammaf __P((float));
2043a8617a8SJordan K. Hubbard extern float __ieee754_log10f __P((float));
2053a8617a8SJordan K. Hubbard extern float __ieee754_sinhf __P((float));
2063a8617a8SJordan K. Hubbard extern float __ieee754_hypotf __P((float,float));
2073a8617a8SJordan K. Hubbard extern float __ieee754_j0f __P((float));
2083a8617a8SJordan K. Hubbard extern float __ieee754_j1f __P((float));
2093a8617a8SJordan K. Hubbard extern float __ieee754_y0f __P((float));
2103a8617a8SJordan K. Hubbard extern float __ieee754_y1f __P((float));
2113a8617a8SJordan K. Hubbard extern float __ieee754_jnf __P((int,float));
2123a8617a8SJordan K. Hubbard extern float __ieee754_ynf __P((int,float));
2133a8617a8SJordan K. Hubbard extern float __ieee754_remainderf __P((float,float));
2143a8617a8SJordan K. Hubbard extern int   __ieee754_rem_pio2f __P((float,float*));
2153a8617a8SJordan K. Hubbard extern float __ieee754_scalbf __P((float,float));
2163a8617a8SJordan K. Hubbard 
2173a8617a8SJordan K. Hubbard /* float versions of fdlibm kernel functions */
2183a8617a8SJordan K. Hubbard extern float __kernel_sinf __P((float,float,int));
2193a8617a8SJordan K. Hubbard extern float __kernel_cosf __P((float,float));
2203a8617a8SJordan K. Hubbard extern float __kernel_tanf __P((float,float,int));
2213a8617a8SJordan K. Hubbard extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
2223a8617a8SJordan K. Hubbard 
2233a8617a8SJordan K. Hubbard #endif /* _MATH_PRIVATE_H_ */
224