xref: /freebsd/lib/msun/src/math_private.h (revision 25a4d6bfda29119996f6bd93c02914ba646634fa)
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 
23ef1ee63eSAlexey Zelkin /*
24ef1ee63eSAlexey Zelkin  * The original fdlibm code used statements like:
25ef1ee63eSAlexey Zelkin  *	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
26ef1ee63eSAlexey Zelkin  *	ix0 = *(n0+(int*)&x);			* high word of x *
27ef1ee63eSAlexey Zelkin  *	ix1 = *((1-n0)+(int*)&x);		* low word of x *
28ef1ee63eSAlexey Zelkin  * to dig two 32 bit words out of the 64 bit IEEE floating point
29ef1ee63eSAlexey Zelkin  * value.  That is non-ANSI, and, moreover, the gcc instruction
30ef1ee63eSAlexey Zelkin  * scheduler gets it wrong.  We instead use the following macros.
31ef1ee63eSAlexey Zelkin  * Unlike the original code, we determine the endianness at compile
32ef1ee63eSAlexey Zelkin  * time, not at run time; I don't see much benefit to selecting
33ef1ee63eSAlexey Zelkin  * endianness at run time.
34ef1ee63eSAlexey Zelkin  */
353a8617a8SJordan K. Hubbard 
36ef1ee63eSAlexey Zelkin /*
37ef1ee63eSAlexey Zelkin  * A union which permits us to convert between a double and two 32 bit
38ef1ee63eSAlexey Zelkin  * ints.
39ef1ee63eSAlexey Zelkin  */
403a8617a8SJordan K. Hubbard 
4174aed985SMarcel Moolenaar #ifdef __arm__
4274aed985SMarcel Moolenaar #if defined(__VFP_FP__)
4374aed985SMarcel Moolenaar #define	IEEE_WORD_ORDER	BYTE_ORDER
4474aed985SMarcel Moolenaar #else
4574aed985SMarcel Moolenaar #define	IEEE_WORD_ORDER	BIG_ENDIAN
4674aed985SMarcel Moolenaar #endif
4774aed985SMarcel Moolenaar #else /* __arm__ */
4874aed985SMarcel Moolenaar #define	IEEE_WORD_ORDER	BYTE_ORDER
4974aed985SMarcel Moolenaar #endif
5074aed985SMarcel Moolenaar 
5174aed985SMarcel Moolenaar #if IEEE_WORD_ORDER == BIG_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 msw;
593a8617a8SJordan K. Hubbard     u_int32_t lsw;
603a8617a8SJordan K. Hubbard   } parts;
613d4dfde4SDavid Schultz   struct
623d4dfde4SDavid Schultz   {
633d4dfde4SDavid Schultz     u_int64_t w;
643d4dfde4SDavid Schultz   } xparts;
653a8617a8SJordan K. Hubbard } ieee_double_shape_type;
663a8617a8SJordan K. Hubbard 
673a8617a8SJordan K. Hubbard #endif
683a8617a8SJordan K. Hubbard 
6974aed985SMarcel Moolenaar #if IEEE_WORD_ORDER == LITTLE_ENDIAN
703a8617a8SJordan K. Hubbard 
713a8617a8SJordan K. Hubbard typedef union
723a8617a8SJordan K. Hubbard {
733a8617a8SJordan K. Hubbard   double value;
743a8617a8SJordan K. Hubbard   struct
753a8617a8SJordan K. Hubbard   {
763a8617a8SJordan K. Hubbard     u_int32_t lsw;
773a8617a8SJordan K. Hubbard     u_int32_t msw;
783a8617a8SJordan K. Hubbard   } parts;
793d4dfde4SDavid Schultz   struct
803d4dfde4SDavid Schultz   {
813d4dfde4SDavid Schultz     u_int64_t w;
823d4dfde4SDavid Schultz   } xparts;
833a8617a8SJordan K. Hubbard } ieee_double_shape_type;
843a8617a8SJordan K. Hubbard 
853a8617a8SJordan K. Hubbard #endif
863a8617a8SJordan K. Hubbard 
873a8617a8SJordan K. Hubbard /* Get two 32 bit ints from a double.  */
883a8617a8SJordan K. Hubbard 
893a8617a8SJordan K. Hubbard #define EXTRACT_WORDS(ix0,ix1,d)				\
903a8617a8SJordan K. Hubbard do {								\
913a8617a8SJordan K. Hubbard   ieee_double_shape_type ew_u;					\
923a8617a8SJordan K. Hubbard   ew_u.value = (d);						\
933a8617a8SJordan K. Hubbard   (ix0) = ew_u.parts.msw;					\
943a8617a8SJordan K. Hubbard   (ix1) = ew_u.parts.lsw;					\
953a8617a8SJordan K. Hubbard } while (0)
963a8617a8SJordan K. Hubbard 
973d4dfde4SDavid Schultz /* Get a 64-bit int from a double. */
983d4dfde4SDavid Schultz #define EXTRACT_WORD64(ix,d)					\
993d4dfde4SDavid Schultz do {								\
1003d4dfde4SDavid Schultz   ieee_double_shape_type ew_u;					\
1013d4dfde4SDavid Schultz   ew_u.value = (d);						\
1023d4dfde4SDavid Schultz   (ix) = ew_u.xparts.w;						\
1033d4dfde4SDavid Schultz } while (0)
1043d4dfde4SDavid Schultz 
1053a8617a8SJordan K. Hubbard /* Get the more significant 32 bit int from a double.  */
1063a8617a8SJordan K. Hubbard 
1073a8617a8SJordan K. Hubbard #define GET_HIGH_WORD(i,d)					\
1083a8617a8SJordan K. Hubbard do {								\
1093a8617a8SJordan K. Hubbard   ieee_double_shape_type gh_u;					\
1103a8617a8SJordan K. Hubbard   gh_u.value = (d);						\
1113a8617a8SJordan K. Hubbard   (i) = gh_u.parts.msw;						\
1123a8617a8SJordan K. Hubbard } while (0)
1133a8617a8SJordan K. Hubbard 
1143a8617a8SJordan K. Hubbard /* Get the less significant 32 bit int from a double.  */
1153a8617a8SJordan K. Hubbard 
1163a8617a8SJordan K. Hubbard #define GET_LOW_WORD(i,d)					\
1173a8617a8SJordan K. Hubbard do {								\
1183a8617a8SJordan K. Hubbard   ieee_double_shape_type gl_u;					\
1193a8617a8SJordan K. Hubbard   gl_u.value = (d);						\
1203a8617a8SJordan K. Hubbard   (i) = gl_u.parts.lsw;						\
1213a8617a8SJordan K. Hubbard } while (0)
1223a8617a8SJordan K. Hubbard 
1233a8617a8SJordan K. Hubbard /* Set a double from two 32 bit ints.  */
1243a8617a8SJordan K. Hubbard 
1253a8617a8SJordan K. Hubbard #define INSERT_WORDS(d,ix0,ix1)					\
1263a8617a8SJordan K. Hubbard do {								\
1273a8617a8SJordan K. Hubbard   ieee_double_shape_type iw_u;					\
1283a8617a8SJordan K. Hubbard   iw_u.parts.msw = (ix0);					\
1293a8617a8SJordan K. Hubbard   iw_u.parts.lsw = (ix1);					\
1303a8617a8SJordan K. Hubbard   (d) = iw_u.value;						\
1313a8617a8SJordan K. Hubbard } while (0)
1323a8617a8SJordan K. Hubbard 
1333d4dfde4SDavid Schultz /* Set a double from a 64-bit int. */
1343d4dfde4SDavid Schultz #define INSERT_WORD64(d,ix)					\
1353d4dfde4SDavid Schultz do {								\
1363d4dfde4SDavid Schultz   ieee_double_shape_type iw_u;					\
1373d4dfde4SDavid Schultz   iw_u.xparts.w = (ix);						\
1383d4dfde4SDavid Schultz   (d) = iw_u.value;						\
1393d4dfde4SDavid Schultz } while (0)
1403d4dfde4SDavid Schultz 
1413a8617a8SJordan K. Hubbard /* Set the more significant 32 bits of a double from an int.  */
1423a8617a8SJordan K. Hubbard 
1433a8617a8SJordan K. Hubbard #define SET_HIGH_WORD(d,v)					\
1443a8617a8SJordan K. Hubbard do {								\
1453a8617a8SJordan K. Hubbard   ieee_double_shape_type sh_u;					\
1463a8617a8SJordan K. Hubbard   sh_u.value = (d);						\
1473a8617a8SJordan K. Hubbard   sh_u.parts.msw = (v);						\
1483a8617a8SJordan K. Hubbard   (d) = sh_u.value;						\
1493a8617a8SJordan K. Hubbard } while (0)
1503a8617a8SJordan K. Hubbard 
1513a8617a8SJordan K. Hubbard /* Set the less significant 32 bits of a double from an int.  */
1523a8617a8SJordan K. Hubbard 
1533a8617a8SJordan K. Hubbard #define SET_LOW_WORD(d,v)					\
1543a8617a8SJordan K. Hubbard do {								\
1553a8617a8SJordan K. Hubbard   ieee_double_shape_type sl_u;					\
1563a8617a8SJordan K. Hubbard   sl_u.value = (d);						\
1573a8617a8SJordan K. Hubbard   sl_u.parts.lsw = (v);						\
1583a8617a8SJordan K. Hubbard   (d) = sl_u.value;						\
1593a8617a8SJordan K. Hubbard } while (0)
1603a8617a8SJordan K. Hubbard 
161ef1ee63eSAlexey Zelkin /*
162ef1ee63eSAlexey Zelkin  * A union which permits us to convert between a float and a 32 bit
163ef1ee63eSAlexey Zelkin  * int.
164ef1ee63eSAlexey Zelkin  */
1653a8617a8SJordan K. Hubbard 
1663a8617a8SJordan K. Hubbard typedef union
1673a8617a8SJordan K. Hubbard {
1683a8617a8SJordan K. Hubbard   float value;
1693a8617a8SJordan K. Hubbard   /* FIXME: Assumes 32 bit int.  */
1703a8617a8SJordan K. Hubbard   unsigned int word;
1713a8617a8SJordan K. Hubbard } ieee_float_shape_type;
1723a8617a8SJordan K. Hubbard 
1733a8617a8SJordan K. Hubbard /* Get a 32 bit int from a float.  */
1743a8617a8SJordan K. Hubbard 
1753a8617a8SJordan K. Hubbard #define GET_FLOAT_WORD(i,d)					\
1763a8617a8SJordan K. Hubbard do {								\
1773a8617a8SJordan K. Hubbard   ieee_float_shape_type gf_u;					\
1783a8617a8SJordan K. Hubbard   gf_u.value = (d);						\
1793a8617a8SJordan K. Hubbard   (i) = gf_u.word;						\
1803a8617a8SJordan K. Hubbard } while (0)
1813a8617a8SJordan K. Hubbard 
1823a8617a8SJordan K. Hubbard /* Set a float from a 32 bit int.  */
1833a8617a8SJordan K. Hubbard 
1843a8617a8SJordan K. Hubbard #define SET_FLOAT_WORD(d,i)					\
1853a8617a8SJordan K. Hubbard do {								\
1863a8617a8SJordan K. Hubbard   ieee_float_shape_type sf_u;					\
1873a8617a8SJordan K. Hubbard   sf_u.word = (i);						\
1883a8617a8SJordan K. Hubbard   (d) = sf_u.value;						\
1893a8617a8SJordan K. Hubbard } while (0)
1903a8617a8SJordan K. Hubbard 
191*25a4d6bfSDavid Schultz /*
192*25a4d6bfSDavid Schultz  * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long
193*25a4d6bfSDavid Schultz  * double.
194*25a4d6bfSDavid Schultz  */
195*25a4d6bfSDavid Schultz 
196*25a4d6bfSDavid Schultz #define	EXTRACT_LDBL80_WORDS(ix0,ix1,d)				\
197*25a4d6bfSDavid Schultz do {								\
198*25a4d6bfSDavid Schultz   union IEEEl2bits ew_u;					\
199*25a4d6bfSDavid Schultz   ew_u.e = (d);							\
200*25a4d6bfSDavid Schultz   (ix0) = ew_u.xbits.expsign;					\
201*25a4d6bfSDavid Schultz   (ix1) = ew_u.xbits.man;					\
202*25a4d6bfSDavid Schultz } while (0)
203*25a4d6bfSDavid Schultz 
204*25a4d6bfSDavid Schultz /*
205*25a4d6bfSDavid Schultz  * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit
206*25a4d6bfSDavid Schultz  * long double.
207*25a4d6bfSDavid Schultz  */
208*25a4d6bfSDavid Schultz 
209*25a4d6bfSDavid Schultz #define	EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d)			\
210*25a4d6bfSDavid Schultz do {								\
211*25a4d6bfSDavid Schultz   union IEEEl2bits ew_u;					\
212*25a4d6bfSDavid Schultz   ew_u.e = (d);							\
213*25a4d6bfSDavid Schultz   (ix0) = ew_u.xbits.expsign;					\
214*25a4d6bfSDavid Schultz   (ix1) = ew_u.xbits.manh;					\
215*25a4d6bfSDavid Schultz   (ix2) = ew_u.xbits.manl;					\
216*25a4d6bfSDavid Schultz } while (0)
217*25a4d6bfSDavid Schultz 
218e6239486SDavid Schultz /* Get expsign as a 16 bit int from a long double.  */
219e6239486SDavid Schultz 
220e6239486SDavid Schultz #define	GET_LDBL_EXPSIGN(i,d)					\
221e6239486SDavid Schultz do {								\
222e6239486SDavid Schultz   union IEEEl2bits ge_u;					\
223e6239486SDavid Schultz   ge_u.e = (d);							\
224e6239486SDavid Schultz   (i) = ge_u.xbits.expsign;					\
225e6239486SDavid Schultz } while (0)
226e6239486SDavid Schultz 
227*25a4d6bfSDavid Schultz /*
228*25a4d6bfSDavid Schultz  * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int
229*25a4d6bfSDavid Schultz  * mantissa.
230*25a4d6bfSDavid Schultz  */
231*25a4d6bfSDavid Schultz 
232*25a4d6bfSDavid Schultz #define	INSERT_LDBL80_WORDS(d,ix0,ix1)				\
233*25a4d6bfSDavid Schultz do {								\
234*25a4d6bfSDavid Schultz   union IEEEl2bits iw_u;					\
235*25a4d6bfSDavid Schultz   iw_u.xbits.expsign = (ix0);					\
236*25a4d6bfSDavid Schultz   iw_u.xbits.man = (ix1);					\
237*25a4d6bfSDavid Schultz   (d) = iw_u.e;							\
238*25a4d6bfSDavid Schultz } while (0)
239*25a4d6bfSDavid Schultz 
240*25a4d6bfSDavid Schultz /*
241*25a4d6bfSDavid Schultz  * Set a 128 bit long double from a 16 bit int expsign and two 64 bit ints
242*25a4d6bfSDavid Schultz  * comprising the mantissa.
243*25a4d6bfSDavid Schultz  */
244*25a4d6bfSDavid Schultz 
245*25a4d6bfSDavid Schultz #define	INSERT_LDBL128_WORDS(d,ix0,ix1,ix2)			\
246*25a4d6bfSDavid Schultz do {								\
247*25a4d6bfSDavid Schultz   union IEEEl2bits iw_u;					\
248*25a4d6bfSDavid Schultz   iw_u.xbits.expsign = (ix0);					\
249*25a4d6bfSDavid Schultz   iw_u.xbits.manh = (ix1);					\
250*25a4d6bfSDavid Schultz   iw_u.xbits.manl = (ix2);					\
251*25a4d6bfSDavid Schultz   (d) = iw_u.e;							\
252*25a4d6bfSDavid Schultz } while (0)
253*25a4d6bfSDavid Schultz 
254e6239486SDavid Schultz /* Set expsign of a long double from a 16 bit int.  */
255e6239486SDavid Schultz 
256e6239486SDavid Schultz #define	SET_LDBL_EXPSIGN(d,v)					\
257e6239486SDavid Schultz do {								\
258e6239486SDavid Schultz   union IEEEl2bits se_u;					\
259e6239486SDavid Schultz   se_u.e = (d);							\
260e6239486SDavid Schultz   se_u.xbits.expsign = (v);					\
261e6239486SDavid Schultz   (d) = se_u.e;							\
262e6239486SDavid Schultz } while (0)
263e6239486SDavid Schultz 
264a077586cSSteve Kargl #ifdef __i386__
265a077586cSSteve Kargl /* Long double constants are broken on i386. */
266a077586cSSteve Kargl #define	LD80C(m, ex, v) {						\
267b83ccea3SSteve Kargl 	.xbits.man = __CONCAT(m, ULL),					\
268a077586cSSteve Kargl 	.xbits.expsign = (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0),	\
269b83ccea3SSteve Kargl }
270a077586cSSteve Kargl #else
271a077586cSSteve Kargl /* The above works on non-i386 too, but we use this to check v. */
272a077586cSSteve Kargl #define	LD80C(m, ex, v)	{ .e = (v), }
273a077586cSSteve Kargl #endif
274b83ccea3SSteve Kargl 
2751880ccbdSBruce Evans #ifdef FLT_EVAL_METHOD
2761880ccbdSBruce Evans /*
2771880ccbdSBruce Evans  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
2781880ccbdSBruce Evans  */
2791880ccbdSBruce Evans #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
2801880ccbdSBruce Evans #define	STRICT_ASSIGN(type, lval, rval)	((lval) = (rval))
2811880ccbdSBruce Evans #else
2821880ccbdSBruce Evans #define	STRICT_ASSIGN(type, lval, rval) do {	\
2831880ccbdSBruce Evans 	volatile type __lval;			\
2841880ccbdSBruce Evans 						\
285e6f9129aSSteve Kargl 	if (sizeof(type) >= sizeof(long double))	\
2865b62c380SBruce Evans 		(lval) = (rval);		\
2875b62c380SBruce Evans 	else {					\
2881880ccbdSBruce Evans 		__lval = (rval);		\
2891880ccbdSBruce Evans 		(lval) = __lval;		\
2905b62c380SBruce Evans 	}					\
2911880ccbdSBruce Evans } while (0)
2921880ccbdSBruce Evans #endif
293b83ccea3SSteve Kargl #endif /* FLT_EVAL_METHOD */
294b83ccea3SSteve Kargl 
295b83ccea3SSteve Kargl /* Support switching the mode to FP_PE if necessary. */
296b83ccea3SSteve Kargl #if defined(__i386__) && !defined(NO_FPSETPREC)
297b83ccea3SSteve Kargl #define	ENTERI()				\
298b83ccea3SSteve Kargl 	long double __retval;			\
299b83ccea3SSteve Kargl 	fp_prec_t __oprec;			\
300b83ccea3SSteve Kargl 						\
301b83ccea3SSteve Kargl 	if ((__oprec = fpgetprec()) != FP_PE)	\
302e6f9129aSSteve Kargl 		fpsetprec(FP_PE)
303b83ccea3SSteve Kargl #define	RETURNI(x) do {				\
304b83ccea3SSteve Kargl 	__retval = (x);				\
305b83ccea3SSteve Kargl 	if (__oprec != FP_PE)			\
306b83ccea3SSteve Kargl 		fpsetprec(__oprec);		\
307b83ccea3SSteve Kargl 	RETURNF(__retval);			\
308b83ccea3SSteve Kargl } while (0)
309b83ccea3SSteve Kargl #else
310b83ccea3SSteve Kargl #define	ENTERI(x)
311b83ccea3SSteve Kargl #define	RETURNI(x)	RETURNF(x)
3121880ccbdSBruce Evans #endif
3131880ccbdSBruce Evans 
314b83ccea3SSteve Kargl /* Default return statement if hack*_t() is not used. */
315b83ccea3SSteve Kargl #define      RETURNF(v)      return (v)
316b83ccea3SSteve Kargl 
3177cd4a832SDavid Schultz /*
318*25a4d6bfSDavid Schultz  * 2sum gives the same result as 2sumF without requiring |a| >= |b| or
319*25a4d6bfSDavid Schultz  * a == 0, but is slower.
320*25a4d6bfSDavid Schultz  */
321*25a4d6bfSDavid Schultz #define	_2sum(a, b) do {	\
322*25a4d6bfSDavid Schultz 	__typeof(a) __s, __w;	\
323*25a4d6bfSDavid Schultz 				\
324*25a4d6bfSDavid Schultz 	__w = (a) + (b);	\
325*25a4d6bfSDavid Schultz 	__s = __w - (a);	\
326*25a4d6bfSDavid Schultz 	(b) = ((a) - (__w - __s)) + ((b) - __s); \
327*25a4d6bfSDavid Schultz 	(a) = __w;		\
328*25a4d6bfSDavid Schultz } while (0)
329*25a4d6bfSDavid Schultz 
330*25a4d6bfSDavid Schultz /*
331*25a4d6bfSDavid Schultz  * 2sumF algorithm.
332*25a4d6bfSDavid Schultz  *
333*25a4d6bfSDavid Schultz  * "Normalize" the terms in the infinite-precision expression a + b for
334*25a4d6bfSDavid Schultz  * the sum of 2 floating point values so that b is as small as possible
335*25a4d6bfSDavid Schultz  * relative to 'a'.  (The resulting 'a' is the value of the expression in
336*25a4d6bfSDavid Schultz  * the same precision as 'a' and the resulting b is the rounding error.)
337*25a4d6bfSDavid Schultz  * |a| must be >= |b| or 0, b's type must be no larger than 'a's type, and
338*25a4d6bfSDavid Schultz  * exponent overflow or underflow must not occur.  This uses a Theorem of
339*25a4d6bfSDavid Schultz  * Dekker (1971).  See Knuth (1981) 4.2.2 Theorem C.  The name "TwoSum"
340*25a4d6bfSDavid Schultz  * is apparently due to Skewchuk (1997).
341*25a4d6bfSDavid Schultz  *
342*25a4d6bfSDavid Schultz  * For this to always work, assignment of a + b to 'a' must not retain any
343*25a4d6bfSDavid Schultz  * extra precision in a + b.  This is required by C standards but broken
344*25a4d6bfSDavid Schultz  * in many compilers.  The brokenness cannot be worked around using
345*25a4d6bfSDavid Schultz  * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this
346*25a4d6bfSDavid Schultz  * algorithm would be destroyed by non-null strict assignments.  (The
347*25a4d6bfSDavid Schultz  * compilers are correct to be broken -- the efficiency of all floating
348*25a4d6bfSDavid Schultz  * point code calculations would be destroyed similarly if they forced the
349*25a4d6bfSDavid Schultz  * conversions.)
350*25a4d6bfSDavid Schultz  *
351*25a4d6bfSDavid Schultz  * Fortunately, a case that works well can usually be arranged by building
352*25a4d6bfSDavid Schultz  * any extra precision into the type of 'a' -- 'a' should have type float_t,
353*25a4d6bfSDavid Schultz  * double_t or long double.  b's type should be no larger than 'a's type.
354*25a4d6bfSDavid Schultz  * Callers should use these types with scopes as large as possible, to
355*25a4d6bfSDavid Schultz  * reduce their own extra-precision and efficiciency problems.  In
356*25a4d6bfSDavid Schultz  * particular, they shouldn't convert back and forth just to call here.
357*25a4d6bfSDavid Schultz  */
358*25a4d6bfSDavid Schultz #ifdef DEBUG
359*25a4d6bfSDavid Schultz #define	_2sumF(a, b) do {				\
360*25a4d6bfSDavid Schultz 	__typeof(a) __w;				\
361*25a4d6bfSDavid Schultz 	volatile __typeof(a) __ia, __ib, __r, __vw;	\
362*25a4d6bfSDavid Schultz 							\
363*25a4d6bfSDavid Schultz 	__ia = (a);					\
364*25a4d6bfSDavid Schultz 	__ib = (b);					\
365*25a4d6bfSDavid Schultz 	assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib));	\
366*25a4d6bfSDavid Schultz 							\
367*25a4d6bfSDavid Schultz 	__w = (a) + (b);				\
368*25a4d6bfSDavid Schultz 	(b) = ((a) - __w) + (b);			\
369*25a4d6bfSDavid Schultz 	(a) = __w;					\
370*25a4d6bfSDavid Schultz 							\
371*25a4d6bfSDavid Schultz 	/* The next 2 assertions are weak if (a) is already long double. */ \
372*25a4d6bfSDavid Schultz 	assert((long double)__ia + __ib == (long double)(a) + (b));	\
373*25a4d6bfSDavid Schultz 	__vw = __ia + __ib;				\
374*25a4d6bfSDavid Schultz 	__r = __ia - __vw;				\
375*25a4d6bfSDavid Schultz 	__r += __ib;					\
376*25a4d6bfSDavid Schultz 	assert(__vw == (a) && __r == (b));		\
377*25a4d6bfSDavid Schultz } while (0)
378*25a4d6bfSDavid Schultz #else /* !DEBUG */
379*25a4d6bfSDavid Schultz #define	_2sumF(a, b) do {	\
380*25a4d6bfSDavid Schultz 	__typeof(a) __w;	\
381*25a4d6bfSDavid Schultz 				\
382*25a4d6bfSDavid Schultz 	__w = (a) + (b);	\
383*25a4d6bfSDavid Schultz 	(b) = ((a) - __w) + (b); \
384*25a4d6bfSDavid Schultz 	(a) = __w;		\
385*25a4d6bfSDavid Schultz } while (0)
386*25a4d6bfSDavid Schultz #endif /* DEBUG */
387*25a4d6bfSDavid Schultz 
388*25a4d6bfSDavid Schultz /*
389*25a4d6bfSDavid Schultz  * Set x += c, where x is represented in extra precision as a + b.
390*25a4d6bfSDavid Schultz  * x must be sufficiently normalized and sufficiently larger than c,
391*25a4d6bfSDavid Schultz  * and the result is then sufficiently normalized.
392*25a4d6bfSDavid Schultz  *
393*25a4d6bfSDavid Schultz  * The details of ordering are that |a| must be >= |c| (so that (a, c)
394*25a4d6bfSDavid Schultz  * can be normalized without extra work to swap 'a' with c).  The details of
395*25a4d6bfSDavid Schultz  * the normalization are that b must be small relative to the normalized 'a'.
396*25a4d6bfSDavid Schultz  * Normalization of (a, c) makes the normalized c tiny relative to the
397*25a4d6bfSDavid Schultz  * normalized a, so b remains small relative to 'a' in the result.  However,
398*25a4d6bfSDavid Schultz  * b need not ever be tiny relative to 'a'.  For example, b might be about
399*25a4d6bfSDavid Schultz  * 2**20 times smaller than 'a' to give about 20 extra bits of precision.
400*25a4d6bfSDavid Schultz  * That is usually enough, and adding c (which by normalization is about
401*25a4d6bfSDavid Schultz  * 2**53 times smaller than a) cannot change b significantly.  However,
402*25a4d6bfSDavid Schultz  * cancellation of 'a' with c in normalization of (a, c) may reduce 'a'
403*25a4d6bfSDavid Schultz  * significantly relative to b.  The caller must ensure that significant
404*25a4d6bfSDavid Schultz  * cancellation doesn't occur, either by having c of the same sign as 'a',
405*25a4d6bfSDavid Schultz  * or by having |c| a few percent smaller than |a|.  Pre-normalization of
406*25a4d6bfSDavid Schultz  * (a, b) may help.
407*25a4d6bfSDavid Schultz  *
408*25a4d6bfSDavid Schultz  * This is is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2
409*25a4d6bfSDavid Schultz  * exercise 19).  We gain considerable efficiency by requiring the terms to
410*25a4d6bfSDavid Schultz  * be sufficiently normalized and sufficiently increasing.
411*25a4d6bfSDavid Schultz  */
412*25a4d6bfSDavid Schultz #define	_3sumF(a, b, c) do {	\
413*25a4d6bfSDavid Schultz 	__typeof(a) __tmp;	\
414*25a4d6bfSDavid Schultz 				\
415*25a4d6bfSDavid Schultz 	__tmp = (c);		\
416*25a4d6bfSDavid Schultz 	_2sumF(__tmp, (a));	\
417*25a4d6bfSDavid Schultz 	(b) += (a);		\
418*25a4d6bfSDavid Schultz 	(a) = __tmp;		\
419*25a4d6bfSDavid Schultz } while (0)
420*25a4d6bfSDavid Schultz 
421*25a4d6bfSDavid Schultz /*
4227cd4a832SDavid Schultz  * Common routine to process the arguments to nan(), nanf(), and nanl().
4237cd4a832SDavid Schultz  */
4247cd4a832SDavid Schultz void _scan_nan(uint32_t *__words, int __num_words, const char *__s);
4257cd4a832SDavid Schultz 
42619b114daSBruce Evans #ifdef _COMPLEX_H
42724863729SDavid Schultz 
42824863729SDavid Schultz /*
42924863729SDavid Schultz  * C99 specifies that complex numbers have the same representation as
43024863729SDavid Schultz  * an array of two elements, where the first element is the real part
43124863729SDavid Schultz  * and the second element is the imaginary part.
43224863729SDavid Schultz  */
43324863729SDavid Schultz typedef union {
43424863729SDavid Schultz 	float complex f;
43524863729SDavid Schultz 	float a[2];
43624863729SDavid Schultz } float_complex;
43724863729SDavid Schultz typedef union {
43824863729SDavid Schultz 	double complex f;
43924863729SDavid Schultz 	double a[2];
44024863729SDavid Schultz } double_complex;
44124863729SDavid Schultz typedef union {
44224863729SDavid Schultz 	long double complex f;
44324863729SDavid Schultz 	long double a[2];
44424863729SDavid Schultz } long_double_complex;
44524863729SDavid Schultz #define	REALPART(z)	((z).a[0])
44624863729SDavid Schultz #define	IMAGPART(z)	((z).a[1])
44724863729SDavid Schultz 
44819b114daSBruce Evans /*
44919b114daSBruce Evans  * Inline functions that can be used to construct complex values.
45019b114daSBruce Evans  *
45119b114daSBruce Evans  * The C99 standard intends x+I*y to be used for this, but x+I*y is
45219b114daSBruce Evans  * currently unusable in general since gcc introduces many overflow,
45319b114daSBruce Evans  * underflow, sign and efficiency bugs by rewriting I*y as
45419b114daSBruce Evans  * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product.
45519b114daSBruce Evans  * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted
45619b114daSBruce Evans  * to -0.0+I*0.0.
45719b114daSBruce Evans  */
45819b114daSBruce Evans static __inline float complex
45919b114daSBruce Evans cpackf(float x, float y)
46019b114daSBruce Evans {
46124863729SDavid Schultz 	float_complex z;
46219b114daSBruce Evans 
46324863729SDavid Schultz 	REALPART(z) = x;
46424863729SDavid Schultz 	IMAGPART(z) = y;
46524863729SDavid Schultz 	return (z.f);
46619b114daSBruce Evans }
46719b114daSBruce Evans 
46819b114daSBruce Evans static __inline double complex
46919b114daSBruce Evans cpack(double x, double y)
47019b114daSBruce Evans {
47124863729SDavid Schultz 	double_complex z;
47219b114daSBruce Evans 
47324863729SDavid Schultz 	REALPART(z) = x;
47424863729SDavid Schultz 	IMAGPART(z) = y;
47524863729SDavid Schultz 	return (z.f);
47619b114daSBruce Evans }
47719b114daSBruce Evans 
47819b114daSBruce Evans static __inline long double complex
47919b114daSBruce Evans cpackl(long double x, long double y)
48019b114daSBruce Evans {
48124863729SDavid Schultz 	long_double_complex z;
48219b114daSBruce Evans 
48324863729SDavid Schultz 	REALPART(z) = x;
48424863729SDavid Schultz 	IMAGPART(z) = y;
48524863729SDavid Schultz 	return (z.f);
48619b114daSBruce Evans }
48719b114daSBruce Evans #endif /* _COMPLEX_H */
48819b114daSBruce Evans 
4890ddfa46bSBruce Evans #ifdef __GNUCLIKE_ASM
4900ddfa46bSBruce Evans 
4910ddfa46bSBruce Evans /* Asm versions of some functions. */
4920ddfa46bSBruce Evans 
4930ddfa46bSBruce Evans #ifdef __amd64__
4940ddfa46bSBruce Evans static __inline int
4950ddfa46bSBruce Evans irint(double x)
4960ddfa46bSBruce Evans {
4970ddfa46bSBruce Evans 	int n;
4980ddfa46bSBruce Evans 
499a4f326ddSEd Schouten 	asm("cvtsd2si %1,%0" : "=r" (n) : "x" (x));
5000ddfa46bSBruce Evans 	return (n);
5010ddfa46bSBruce Evans }
5020ddfa46bSBruce Evans #define	HAVE_EFFICIENT_IRINT
5030ddfa46bSBruce Evans #endif
5040ddfa46bSBruce Evans 
5050ddfa46bSBruce Evans #ifdef __i386__
5060ddfa46bSBruce Evans static __inline int
5070ddfa46bSBruce Evans irint(double x)
5080ddfa46bSBruce Evans {
5090ddfa46bSBruce Evans 	int n;
5100ddfa46bSBruce Evans 
5110ddfa46bSBruce Evans 	asm("fistl %0" : "=m" (n) : "t" (x));
5120ddfa46bSBruce Evans 	return (n);
5130ddfa46bSBruce Evans }
5140ddfa46bSBruce Evans #define	HAVE_EFFICIENT_IRINT
5150ddfa46bSBruce Evans #endif
5160ddfa46bSBruce Evans 
517b83ccea3SSteve Kargl #if defined(__amd64__) || defined(__i386__)
518b83ccea3SSteve Kargl static __inline int
519b83ccea3SSteve Kargl irintl(long double x)
520b83ccea3SSteve Kargl {
521b83ccea3SSteve Kargl 	int n;
522b83ccea3SSteve Kargl 
523b83ccea3SSteve Kargl 	asm("fistl %0" : "=m" (n) : "t" (x));
524b83ccea3SSteve Kargl 	return (n);
525b83ccea3SSteve Kargl }
526b83ccea3SSteve Kargl #define	HAVE_EFFICIENT_IRINTL
527b83ccea3SSteve Kargl #endif
528b83ccea3SSteve Kargl 
5290ddfa46bSBruce Evans #endif /* __GNUCLIKE_ASM */
5300ddfa46bSBruce Evans 
531*25a4d6bfSDavid Schultz #ifdef DEBUG
532*25a4d6bfSDavid Schultz #if defined(__amd64__) || defined(__i386__)
533*25a4d6bfSDavid Schultz #define	breakpoint()	asm("int $3")
534*25a4d6bfSDavid Schultz #else
535*25a4d6bfSDavid Schultz #include <signal.h>
536*25a4d6bfSDavid Schultz 
537*25a4d6bfSDavid Schultz #define	breakpoint()	raise(SIGTRAP)
538*25a4d6bfSDavid Schultz #endif
539*25a4d6bfSDavid Schultz #endif
540*25a4d6bfSDavid Schultz 
541*25a4d6bfSDavid Schultz /* Write a pari script to test things externally. */
542*25a4d6bfSDavid Schultz #ifdef DOPRINT
543*25a4d6bfSDavid Schultz #include <stdio.h>
544*25a4d6bfSDavid Schultz 
545*25a4d6bfSDavid Schultz #ifndef DOPRINT_SWIZZLE
546*25a4d6bfSDavid Schultz #define	DOPRINT_SWIZZLE		0
547*25a4d6bfSDavid Schultz #endif
548*25a4d6bfSDavid Schultz 
549*25a4d6bfSDavid Schultz #ifdef DOPRINT_LD80
550*25a4d6bfSDavid Schultz 
551*25a4d6bfSDavid Schultz #define	DOPRINT_START(xp) do {						\
552*25a4d6bfSDavid Schultz 	uint64_t __lx;							\
553*25a4d6bfSDavid Schultz 	uint16_t __hx;							\
554*25a4d6bfSDavid Schultz 									\
555*25a4d6bfSDavid Schultz 	/* Hack to give more-problematic args. */			\
556*25a4d6bfSDavid Schultz 	EXTRACT_LDBL80_WORDS(__hx, __lx, *xp);				\
557*25a4d6bfSDavid Schultz 	__lx ^= DOPRINT_SWIZZLE;					\
558*25a4d6bfSDavid Schultz 	INSERT_LDBL80_WORDS(*xp, __hx, __lx);				\
559*25a4d6bfSDavid Schultz 	printf("x = %.21Lg; ", (long double)*xp);			\
560*25a4d6bfSDavid Schultz } while (0)
561*25a4d6bfSDavid Schultz #define	DOPRINT_END1(v)							\
562*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
563*25a4d6bfSDavid Schultz #define	DOPRINT_END2(hi, lo)						\
564*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
565*25a4d6bfSDavid Schultz 	    (long double)(hi), (long double)(lo))
566*25a4d6bfSDavid Schultz 
567*25a4d6bfSDavid Schultz #elif defined(DOPRINT_D64)
568*25a4d6bfSDavid Schultz 
569*25a4d6bfSDavid Schultz #define	DOPRINT_START(xp) do {						\
570*25a4d6bfSDavid Schultz 	uint32_t __hx, __lx;						\
571*25a4d6bfSDavid Schultz 									\
572*25a4d6bfSDavid Schultz 	EXTRACT_WORDS(__hx, __lx, *xp);					\
573*25a4d6bfSDavid Schultz 	__lx ^= DOPRINT_SWIZZLE;					\
574*25a4d6bfSDavid Schultz 	INSERT_WORDS(*xp, __hx, __lx);					\
575*25a4d6bfSDavid Schultz 	printf("x = %.21Lg; ", (long double)*xp);			\
576*25a4d6bfSDavid Schultz } while (0)
577*25a4d6bfSDavid Schultz #define	DOPRINT_END1(v)							\
578*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
579*25a4d6bfSDavid Schultz #define	DOPRINT_END2(hi, lo)						\
580*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
581*25a4d6bfSDavid Schultz 	    (long double)(hi), (long double)(lo))
582*25a4d6bfSDavid Schultz 
583*25a4d6bfSDavid Schultz #elif defined(DOPRINT_F32)
584*25a4d6bfSDavid Schultz 
585*25a4d6bfSDavid Schultz #define	DOPRINT_START(xp) do {						\
586*25a4d6bfSDavid Schultz 	uint32_t __hx;							\
587*25a4d6bfSDavid Schultz 									\
588*25a4d6bfSDavid Schultz 	GET_FLOAT_WORD(__hx, *xp);					\
589*25a4d6bfSDavid Schultz 	__hx ^= DOPRINT_SWIZZLE;					\
590*25a4d6bfSDavid Schultz 	SET_FLOAT_WORD(*xp, __hx);					\
591*25a4d6bfSDavid Schultz 	printf("x = %.21Lg; ", (long double)*xp);			\
592*25a4d6bfSDavid Schultz } while (0)
593*25a4d6bfSDavid Schultz #define	DOPRINT_END1(v)							\
594*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
595*25a4d6bfSDavid Schultz #define	DOPRINT_END2(hi, lo)						\
596*25a4d6bfSDavid Schultz 	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
597*25a4d6bfSDavid Schultz 	    (long double)(hi), (long double)(lo))
598*25a4d6bfSDavid Schultz 
599*25a4d6bfSDavid Schultz #else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */
600*25a4d6bfSDavid Schultz 
601*25a4d6bfSDavid Schultz #ifndef DOPRINT_SWIZZLE_HIGH
602*25a4d6bfSDavid Schultz #define	DOPRINT_SWIZZLE_HIGH	0
603*25a4d6bfSDavid Schultz #endif
604*25a4d6bfSDavid Schultz 
605*25a4d6bfSDavid Schultz #define	DOPRINT_START(xp) do {						\
606*25a4d6bfSDavid Schultz 	uint64_t __lx, __llx;						\
607*25a4d6bfSDavid Schultz 	uint16_t __hx;							\
608*25a4d6bfSDavid Schultz 									\
609*25a4d6bfSDavid Schultz 	EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp);			\
610*25a4d6bfSDavid Schultz 	__llx ^= DOPRINT_SWIZZLE;					\
611*25a4d6bfSDavid Schultz 	__lx ^= DOPRINT_SWIZZLE_HIGH;					\
612*25a4d6bfSDavid Schultz 	INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx);			\
613*25a4d6bfSDavid Schultz 	printf("x = %.36Lg; ", (long double)*xp);					\
614*25a4d6bfSDavid Schultz } while (0)
615*25a4d6bfSDavid Schultz #define	DOPRINT_END1(v)							\
616*25a4d6bfSDavid Schultz 	printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v))
617*25a4d6bfSDavid Schultz #define	DOPRINT_END2(hi, lo)						\
618*25a4d6bfSDavid Schultz 	printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n",		\
619*25a4d6bfSDavid Schultz 	    (long double)(hi), (long double)(lo))
620*25a4d6bfSDavid Schultz 
621*25a4d6bfSDavid Schultz #endif /* DOPRINT_LD80 */
622*25a4d6bfSDavid Schultz 
623*25a4d6bfSDavid Schultz #else /* !DOPRINT */
624*25a4d6bfSDavid Schultz #define	DOPRINT_START(xp)
625*25a4d6bfSDavid Schultz #define	DOPRINT_END1(v)
626*25a4d6bfSDavid Schultz #define	DOPRINT_END2(hi, lo)
627*25a4d6bfSDavid Schultz #endif /* DOPRINT */
628*25a4d6bfSDavid Schultz 
629*25a4d6bfSDavid Schultz #define	RETURNP(x) do {			\
630*25a4d6bfSDavid Schultz 	DOPRINT_END1(x);		\
631*25a4d6bfSDavid Schultz 	RETURNF(x);			\
632*25a4d6bfSDavid Schultz } while (0)
633*25a4d6bfSDavid Schultz #define	RETURNPI(x) do {		\
634*25a4d6bfSDavid Schultz 	DOPRINT_END1(x);		\
635*25a4d6bfSDavid Schultz 	RETURNI(x);			\
636*25a4d6bfSDavid Schultz } while (0)
637*25a4d6bfSDavid Schultz #define	RETURN2P(x, y) do {		\
638*25a4d6bfSDavid Schultz 	DOPRINT_END2((x), (y));		\
639*25a4d6bfSDavid Schultz 	RETURNF((x) + (y));		\
640*25a4d6bfSDavid Schultz } while (0)
641*25a4d6bfSDavid Schultz #define	RETURN2PI(x, y) do {		\
642*25a4d6bfSDavid Schultz 	DOPRINT_END2((x), (y));		\
643*25a4d6bfSDavid Schultz 	RETURNI((x) + (y));		\
644*25a4d6bfSDavid Schultz } while (0)
645*25a4d6bfSDavid Schultz #ifdef STRUCT_RETURN
646*25a4d6bfSDavid Schultz #define	RETURNSP(rp) do {		\
647*25a4d6bfSDavid Schultz 	if (!(rp)->lo_set)		\
648*25a4d6bfSDavid Schultz 		RETURNP((rp)->hi);	\
649*25a4d6bfSDavid Schultz 	RETURN2P((rp)->hi, (rp)->lo);	\
650*25a4d6bfSDavid Schultz } while (0)
651*25a4d6bfSDavid Schultz #define	RETURNSPI(rp) do {		\
652*25a4d6bfSDavid Schultz 	if (!(rp)->lo_set)		\
653*25a4d6bfSDavid Schultz 		RETURNPI((rp)->hi);	\
654*25a4d6bfSDavid Schultz 	RETURN2PI((rp)->hi, (rp)->lo);	\
655*25a4d6bfSDavid Schultz } while (0)
656*25a4d6bfSDavid Schultz #endif
657*25a4d6bfSDavid Schultz #define	SUM2P(x, y) ({			\
658*25a4d6bfSDavid Schultz 	const __typeof (x) __x = (x);	\
659*25a4d6bfSDavid Schultz 	const __typeof (y) __y = (y);	\
660*25a4d6bfSDavid Schultz 					\
661*25a4d6bfSDavid Schultz 	DOPRINT_END2(__x, __y);		\
662*25a4d6bfSDavid Schultz 	__x + __y;			\
663*25a4d6bfSDavid Schultz })
664*25a4d6bfSDavid Schultz 
665e1b61b5bSDavid Schultz /*
666e1b61b5bSDavid Schultz  * ieee style elementary functions
667e1b61b5bSDavid Schultz  *
668e1b61b5bSDavid Schultz  * We rename functions here to improve other sources' diffability
669e1b61b5bSDavid Schultz  * against fdlibm.
670e1b61b5bSDavid Schultz  */
671e1b61b5bSDavid Schultz #define	__ieee754_sqrt	sqrt
672e1b61b5bSDavid Schultz #define	__ieee754_acos	acos
673e1b61b5bSDavid Schultz #define	__ieee754_acosh	acosh
674e1b61b5bSDavid Schultz #define	__ieee754_log	log
675177668d1SDavid Schultz #define	__ieee754_log2	log2
676e1b61b5bSDavid Schultz #define	__ieee754_atanh	atanh
677e1b61b5bSDavid Schultz #define	__ieee754_asin	asin
678e1b61b5bSDavid Schultz #define	__ieee754_atan2	atan2
679e1b61b5bSDavid Schultz #define	__ieee754_exp	exp
680e1b61b5bSDavid Schultz #define	__ieee754_cosh	cosh
681e1b61b5bSDavid Schultz #define	__ieee754_fmod	fmod
682e1b61b5bSDavid Schultz #define	__ieee754_pow	pow
683e1b61b5bSDavid Schultz #define	__ieee754_lgamma lgamma
684e1b61b5bSDavid Schultz #define	__ieee754_gamma	gamma
685e1b61b5bSDavid Schultz #define	__ieee754_lgamma_r lgamma_r
686e1b61b5bSDavid Schultz #define	__ieee754_gamma_r gamma_r
687e1b61b5bSDavid Schultz #define	__ieee754_log10	log10
688e1b61b5bSDavid Schultz #define	__ieee754_sinh	sinh
689e1b61b5bSDavid Schultz #define	__ieee754_hypot	hypot
690e1b61b5bSDavid Schultz #define	__ieee754_j0	j0
691e1b61b5bSDavid Schultz #define	__ieee754_j1	j1
692e1b61b5bSDavid Schultz #define	__ieee754_y0	y0
693e1b61b5bSDavid Schultz #define	__ieee754_y1	y1
694e1b61b5bSDavid Schultz #define	__ieee754_jn	jn
695e1b61b5bSDavid Schultz #define	__ieee754_yn	yn
696e1b61b5bSDavid Schultz #define	__ieee754_remainder remainder
697e1b61b5bSDavid Schultz #define	__ieee754_scalb	scalb
698e1b61b5bSDavid Schultz #define	__ieee754_sqrtf	sqrtf
699e1b61b5bSDavid Schultz #define	__ieee754_acosf	acosf
700e1b61b5bSDavid Schultz #define	__ieee754_acoshf acoshf
701e1b61b5bSDavid Schultz #define	__ieee754_logf	logf
702e1b61b5bSDavid Schultz #define	__ieee754_atanhf atanhf
703e1b61b5bSDavid Schultz #define	__ieee754_asinf	asinf
704e1b61b5bSDavid Schultz #define	__ieee754_atan2f atan2f
705e1b61b5bSDavid Schultz #define	__ieee754_expf	expf
706e1b61b5bSDavid Schultz #define	__ieee754_coshf	coshf
707e1b61b5bSDavid Schultz #define	__ieee754_fmodf	fmodf
708e1b61b5bSDavid Schultz #define	__ieee754_powf	powf
709e1b61b5bSDavid Schultz #define	__ieee754_lgammaf lgammaf
710e1b61b5bSDavid Schultz #define	__ieee754_gammaf gammaf
711e1b61b5bSDavid Schultz #define	__ieee754_lgammaf_r lgammaf_r
712e1b61b5bSDavid Schultz #define	__ieee754_gammaf_r gammaf_r
713e1b61b5bSDavid Schultz #define	__ieee754_log10f log10f
714177668d1SDavid Schultz #define	__ieee754_log2f log2f
715e1b61b5bSDavid Schultz #define	__ieee754_sinhf	sinhf
716e1b61b5bSDavid Schultz #define	__ieee754_hypotf hypotf
717e1b61b5bSDavid Schultz #define	__ieee754_j0f	j0f
718e1b61b5bSDavid Schultz #define	__ieee754_j1f	j1f
719e1b61b5bSDavid Schultz #define	__ieee754_y0f	y0f
720e1b61b5bSDavid Schultz #define	__ieee754_y1f	y1f
721e1b61b5bSDavid Schultz #define	__ieee754_jnf	jnf
722e1b61b5bSDavid Schultz #define	__ieee754_ynf	ynf
723e1b61b5bSDavid Schultz #define	__ieee754_remainderf remainderf
724e1b61b5bSDavid Schultz #define	__ieee754_scalbf scalbf
7253a8617a8SJordan K. Hubbard 
7263a8617a8SJordan K. Hubbard /* fdlibm kernel function */
727079299f7SDavid Schultz int	__kernel_rem_pio2(double*,double*,int,int,int);
728079299f7SDavid Schultz 
729079299f7SDavid Schultz /* double precision kernel functions */
7302b795b29SDimitry Andric #ifndef INLINE_REM_PIO2
731e02846ceSDavid Schultz int	__ieee754_rem_pio2(double,double*);
7322b795b29SDimitry Andric #endif
73369160b1eSDavid E. O'Brien double	__kernel_sin(double,double,int);
73469160b1eSDavid E. O'Brien double	__kernel_cos(double,double);
73569160b1eSDavid E. O'Brien double	__kernel_tan(double,double,int);
73612188b77SDavid Schultz double	__ldexp_exp(double,int);
73712188b77SDavid Schultz #ifdef _COMPLEX_H
73812188b77SDavid Schultz double complex __ldexp_cexp(double complex,int);
73912188b77SDavid Schultz #endif
7403a8617a8SJordan K. Hubbard 
741079299f7SDavid Schultz /* float precision kernel functions */
7422b795b29SDimitry Andric #ifndef INLINE_REM_PIO2F
74370d818a2SBruce Evans int	__ieee754_rem_pio2f(float,double*);
744b492f289SEd Schouten #endif
7452b795b29SDimitry Andric #ifndef INLINE_KERNEL_SINDF
74659aad933SBruce Evans float	__kernel_sindf(double);
747b492f289SEd Schouten #endif
7482b795b29SDimitry Andric #ifndef INLINE_KERNEL_COSDF
74959aad933SBruce Evans float	__kernel_cosdf(double);
750b492f289SEd Schouten #endif
7512b795b29SDimitry Andric #ifndef INLINE_KERNEL_TANDF
75294a5f9beSBruce Evans float	__kernel_tandf(double,int);
7532b795b29SDimitry Andric #endif
75412188b77SDavid Schultz float	__ldexp_expf(float,int);
75512188b77SDavid Schultz #ifdef _COMPLEX_H
75612188b77SDavid Schultz float complex __ldexp_cexpf(float complex,int);
75712188b77SDavid Schultz #endif
758079299f7SDavid Schultz 
759079299f7SDavid Schultz /* long double precision kernel functions */
760079299f7SDavid Schultz long double __kernel_sinl(long double, long double, int);
761079299f7SDavid Schultz long double __kernel_cosl(long double, long double);
762079299f7SDavid Schultz long double __kernel_tanl(long double, long double, int);
7633a8617a8SJordan K. Hubbard 
764ef1ee63eSAlexey Zelkin #endif /* !_MATH_PRIVATE_H_ */
765