xref: /freebsd/lib/msun/src/math_private.h (revision bcfa175910f3a432a4cea513bf0f487906e969f9)
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
147f3dea24SPeter Wemm  * $FreeBSD$
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 <sys/types.h>
21bcfa1759SBrian Somers #include <machine/endian.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 
22343f3c8edSJohn Birrell #ifdef	__alpha__
22443f3c8edSJohn Birrell #define __generic___ieee754_acos	__ieee754_acos
22543f3c8edSJohn Birrell #define __generic___ieee754_asin	__ieee754_asin
22643f3c8edSJohn Birrell #define __generic___ieee754_atan2	__ieee754_atan2
22743f3c8edSJohn Birrell #define __generic___ieee754_exp		__ieee754_exp
22843f3c8edSJohn Birrell #define __generic___ieee754_fmod	__ieee754_fmod
22943f3c8edSJohn Birrell #define __generic___ieee754_log		__ieee754_log
23043f3c8edSJohn Birrell #define __generic___ieee754_log10	__ieee754_log10
23143f3c8edSJohn Birrell #define __generic___ieee754_remainder	__ieee754_remainder
23243f3c8edSJohn Birrell #define __generic___ieee754_scalb	__ieee754_scalb
23343f3c8edSJohn Birrell #define __generic___ieee754_sqrt	__ieee754_sqrt
23443f3c8edSJohn Birrell #define	__generic_atan			atan
23543f3c8edSJohn Birrell #define	__generic_ceil			ceil
23643f3c8edSJohn Birrell #define	__generic_copysign		copysign
23743f3c8edSJohn Birrell #define	__generic_cos			cos
23843f3c8edSJohn Birrell #define	__generic_finite		finite
23943f3c8edSJohn Birrell #define	__generic_floor			floor
24043f3c8edSJohn Birrell #define	__generic_ilogb			ilogb
24143f3c8edSJohn Birrell #define	__generic_log1p			log1p
24243f3c8edSJohn Birrell #define	__generic_logb			logb
24343f3c8edSJohn Birrell #define	__generic_rint			rint
24443f3c8edSJohn Birrell #define	__generic_scalbn		scalbn
24543f3c8edSJohn Birrell #define	__generic_significand		significand
24643f3c8edSJohn Birrell #define	__generic_sin			sin
24743f3c8edSJohn Birrell #define	__generic_tan			tan
24843f3c8edSJohn Birrell #endif
24943f3c8edSJohn Birrell 
2503a8617a8SJordan K. Hubbard #endif /* _MATH_PRIVATE_H_ */
251