libc
/* $Id$ */
							/* Copyright (c) 2008-2020 Pierre Pronchery <khorben@defora.org> */
							/* This file is part of DeforaOS System libc */
							/* All rights reserved.
							 *
							 * Redistribution and use in source and binary forms, with or without
							 * modification, are permitted provided that the following conditions are
							 * met:
							 *
							 * 1. Redistributions of source code must retain the above copyright
							 *    notice, this list of conditions and the following disclaimer.
							 *
							 * 2. Redistributions in binary form must reproduce the above copyright
							 *    notice, this list of conditions and the following disclaimer in the
							 *    documentation and/or other materials provided with the distribution.
							 *
							 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
							 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
							 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
							 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
							 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
							 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
							 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
							 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
							 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
							 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
							 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
							/* XXX in part from dietlibc */
							#include "sys/types.h"
							#include "stdlib.h"
							#include "string.h"
							#include "errno.h"
							#include "math.h"
							#include "arch.h"
							/* constants */
							#define B0      +            1.0l/   6/ 1/ 2
							#define B1      -            1.0l/  30/ 3/ 4
							#define B2      +            1.0l/  42/ 5/ 6
							#define B3      -            1.0l/  30/ 7/ 8
							#define B4      +            5.0l/  66/ 9/10
							#define B5      -          691.0l/2730/11/12
							#define B6      +            7.0l/   6/13/14
							#define B7      -         3617.0l/ 510/15/16
							#define B8      +        43867.0l/ 798/17/18
							#define B9      -       174611.0l/ 330/19/20
							#define B10     +       854513.0l/ 138/21/22
							#define B11     -    236364091.0l/2730/23/24
							#define B12     +      8553103.0l/   6/25/26
							#define M_C		0.5772156649015328
							/* variables */
							static const double _coeff[] = { B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10 };
							static int _signgam;
							/* macros */
							#define EXPL(x)   ((((short *)(void *)&x)[4] & 0x7FFF) >> 0)
							#define EXPD(x)   ((((short *)(void *)&x)[3] & 0x7FF0) >> 4)
							#define EXPF(x)   ((((short *)(void *)&x)[1] & 0x7F80) >> 7)
							#define SQUARE(x) (long) (My - (x) * (x) )
							/* prototypes */
							/* private */
							static double _logfact(long double x);
							static double _poly(double x, size_t n, const double * c);
							static long double _P(int My, double * x);
							static long double _Q(int My, double * x);
							static long double _jn(int n, double * x);
							static long double _yn(int n, double * x);
							/* functions */
							/* private */
							static double _logfact(long double x)
							{
								static unsigned char list [] = { 6, 4, 3, 3, 2, 2 };
								long double   z = 2. * M_PI * x;
								register int  e = EXPL (x);
								return (log(x) - 1) * x + 0.5 * log(z) + _poly(1. / (x * x),
										e < 0x4003 ? 10 : (e > 0x4008 ? 1 : list[e - 0x4003]),
										_coeff) / x;
							}
							static double _poly(double x, size_t n, const double * c)
							{
								long double ret;
								size_t i;
								i = n;
								c += n;
								ret = 0;
								do
									ret = ret * x + *c--;
								while(i--);
								return ret;
							}
							static long double _P(int My, double * x)
							{
							    long double Sum  = 0.;
							    long double Fact = 1.;
							    long double z182 = -0.015625 / (x[0] * x[0]);
							    register int i;
							    for ( i = 1; ; i += 2 ) {
							        Fact *= SQUARE(i+i-1) * SQUARE(i+i+1) * z182 / (i*(i+1));
							        if ( EXPL (Fact) < 0x3FFF-53 )
							            break;
							        Sum  += Fact;
							    }
							    return 1. + Sum;
							}
							static long double _Q(int My, double * x)
							{
							    long double Fact = (My-1) / x[0] * 0.125;
							    long double Sum  = Fact;
							    long double z182 = -0.015625 / (x[0]*x[0]);
							    register int i;
							    for ( i = 2; ; i += 2 ) {
							        Fact *= SQUARE(i+i-1) * SQUARE(i+i+1) * z182 / (i*(i+1));
							        if ( EXPL (Fact) < 0x3FFF-53 )
							            break;
							        Sum  += Fact;
							    }
							    return Sum;
							}
							static long double _jn(int n, double * x)
							{
							    long double   Sum;
							    long double   Fact;
							    long double   y;
							    register int  i;
							    double        xx;
							    long double   Xi;
							    int           My;
							    if ( n < 0 )
							        return n & 1 ? _jn(-n, x) : -_jn(-n, x);
							    if ((x[0] >= 17.7+0.0144*(n*n))) {
							        Xi = x[0] - M_PI * (n*0.5 + 0.25);
							        My = n*n << 2;
							        return sqrt(M_2_PI / x[0]) * (_P(My, x) * cos(Xi) - _Q(My,x) * sin(Xi));
							    }
							    xx   = x[0] * 0.5;
							    Sum  = 0.;
							    Fact = 1.;
							    y    = -xx * xx;
							    for ( i = 1; i <= n; i++ )
							        Fact *= xx/i;
							    for ( i = 1; ; i++ ) {
							        Sum  += Fact;
							        Fact *= y / (i*(n+i));
							        if ( EXPL (Sum) - EXPL(Fact) > 53 || !EXPL(Fact) )
							            break;
							    }
							    return Sum;
							}
							static long double  _yn ( int n, double* x )
							{
							    long double   Sum1;
							    long double   Sum2;
							    long double   Fact1;
							    long double   Fact2;
							    long double   F1;
							    long double   F2;
							    long double   y;
							    register int  i;
							    double        xx;
							    long double   Xi;
							    unsigned int  My;
							    if ( EXPD (x[0]) == 0 )
							        return -1./0.;	/* ignore the gcc warning, this is intentional */
							    if ( (x[0] >= (n>=32 ? 25.8 : (n<8 ? 17.4+0.1*n : 16.2+0.3*n))) ) {
							        Xi = x[0] - M_PI * (n*0.5+0.25);
							        My = n*n << 2;
							        return sqrt(M_2_PI / x[0]) * (_P(My,x) * sin(Xi) + _Q(My,x) * cos(Xi));
							    }
							    Sum1  = Sum2 = F1 = F2 = 0;
							    Fact1 = 1. / (xx = x[0] * 0.5 );
							    Fact2 = 1.;
							    y     = xx*xx;
							    for ( i = 1; i < n; i++ )
							        Fact1 *= (n-i) / xx;
							    for ( i = 1; i <= n; i++ ) {
							        Sum1  += Fact1;
							        if ( i == n )
							            break;
							        Fact1 *= y/(i*(n-i));
							    }
							    for (i=1; i<=n; i++) {
							        Fact2 *= xx / i;
							        F1    += 1. / i;
							    }
							    for ( i = 1; ; i++ ) {
							        Sum2  += Fact2 * (F1+F2);
							        Fact2 *= -y / (i*(n+i));
							        if ( EXPL (Sum2) - EXPL (Fact2) > 53 || !EXPL (Fact2) )
							            break;
							        F1 += 1. / (n+i);
							        F2 += 1. / i;
							    }
							    return M_1_PI * (2. * (M_C + log(xx)) * _jn (n, x) - Sum1 - Sum2);
							}
							/* public */
							/* acos */
							#ifndef ARCH_acos
							double acos(double x)
							{
								return acosl(x);
							}
							#endif
							/* acosf */
							#ifndef ARCH_acosf
							float acosf(float x)
							{
								return acos(x);
							}
							#endif
							/* acosh */
							#ifndef ARCH_acosh
							double acosh(double x)
							{
								return acoshl(x);
							}
							#endif
							/* acoshf */
							#ifndef ARCH_acoshf
							float acoshf(float x)
							{
								return acosh(x);
							}
							#endif
							/* acoshl */
							#ifndef ARCH_acoshl
							# warning Unsupported platform: acoshl() is not implemented
							long double acoshl(long double x)
							{
								if(x < 1.0)
								{
									errno = EDOM;
									return nanl(NULL);
								}
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* acosl */
							#ifndef ARCH_acosl
							# warning Unsupported platform: acosl() is not implemented
							long double acosl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* asin */
							#ifndef ARCH_asin
							double asin(double x)
							{
								return asinl(x);
							}
							#endif
							/* asinf */
							#ifndef ARCH_asinf
							float asinf(float x)
							{
								return asin(x);
							}
							#endif
							/* asinh */
							#ifndef ARCH_asinh
							double asinh(double x)
							{
								return asinhl(x);
							}
							#endif
							/* asinhf */
							#ifndef ARCH_asinhf
							float asinhf(float x)
							{
								return asinh(x);
							}
							#endif
							/* asinhl */
							#ifndef ARCH_asinhl
							# warning Unsupported platform: asinhl() is not implemented
							long double asinhl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* asinl */
							#ifndef ARCH_asinl
							# warning Unsupported platform: asinl() is not implemented
							long double asinl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* atan */
							#ifndef ARCH_atan
							double atan(double x)
							{
								return atanl(x);
							}
							#endif
							/* atan2 */
							#ifndef ARCH_atan2
							double atan2(double x, double y)
							{
								return atan2l(x, y);
							}
							#endif
							/* atan2f */
							#ifndef ARCH_atan2f
							float atan2f(float x, float y)
							{
								return atan2(x, y);
							}
							#endif
							/* atan2l */
							#ifndef ARCH_atan2l
							long double atan2l(long double x, long double y)
							{
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* atanf */
							#ifndef ARCH_atanf
							float atanf(float x)
							{
								return atan(x);
							}
							#endif
							/* atanh */
							#ifndef ARCH_atanh
							double atanh(double x)
							{
								return atanhl(x);
							}
							#endif
							/* atanhf */
							#ifndef ARCH_atanhf
							float atanhf(float x)
							{
								return atanh(x);
							}
							#endif
							/* atanhl */
							#ifndef ARCH_atanhl
							# warning Unsupported platform: atanhl() is not implemented
							long double atanhl(long double x)
							{
								if(abs(x) >= 1.0)
								{
									errno = EDOM;
									return nanl(NULL);
								}
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* atanl */
							#ifndef ARCH_atanl
							# warning Unsupported platform: atanl() is not implemented
							long double atanl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* cbrt */
							#ifndef ARCH_cbrt
							double cbrt(double x)
							{
								return cbrtl(x);
							}
							#endif
							/* cbrtf */
							#ifndef ARCH_cbrtf
							float cbrtf(float x)
							{
								return cbrt(x);
							}
							#endif
							/* cbrtl */
							#ifndef ARCH_cbrtl
							# warning Unsupported platform: cbrtl() is not implemented
							long double cbrtl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* ceil */
							#ifndef ARCH_ceil
							double ceil(double x)
							{
								return ceill(x);
							}
							#endif
							/* ceilf */
							#ifndef ARCH_ceilf
							float ceilf(float x)
							{
								return ceil(x);
							}
							#endif
							/* ceill */
							#ifndef ARCH_ceill
							long double ceill(long double x)
							{
								long double y;
								y = roundl(x);
								return (y >= x) ? y : y + 1.0;
							}
							#endif
							#if 0
							double copysign(double, double);
							float copysignf(float, float);
							long double copysignl(long double, long double);
							#endif
							/* cos */
							#ifndef ARCH_cos
							double cos(double x)
							{
								return cosl(x);
							}
							#endif
							/* cosf */
							#ifndef ARCH_cosf
							float cosf(float x)
							{
								return cos(x);
							}
							#endif
							/* cosh */
							#ifndef ARCH_cosh
							double cosh(double x)
							{
								return (exp(x) + exp(-x)) / 2;
							}
							#endif
							/* coshf */
							#ifndef ARCH_coshf
							float coshf(float x)
							{
								return (expf(x) + expf(-x)) / 2;
							}
							#endif
							/* coshl */
							#ifndef ARCH_coshl
							long double coshl(long double x)
							{
								return (expl(x) + expl(-x)) / 2;
							}
							#endif
							/* cosl */
							#ifndef ARCH_cosl
							# warning Unsupported platform: cosl() is not implemented
							long double cosl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							#if 0
							double erf(double);
							double erfc(double);
							float erfcf(float);
							long double erfcl(long double);
							float erff(float);
							long double erfl(long double);
							#endif
							/* exp */
							#ifndef ARCH_exp
							double exp(double x)
							{
								return expl(x);
							}
							#endif
							/* exp2 */
							#ifndef ARCH_exp2
							double exp2(double x)
							{
								return exp2l(x);
							}
							#endif
							/* exp2f */
							#ifndef ARCH_exp2f
							float exp2f(float x)
							{
								return exp2(x);
							}
							#endif
							/* exp2l */
							#ifndef ARCH_exp2l
							# warning Unsupported platform: exp2l() is not implemented
							long double exp2l(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* expf */
							#ifndef ARCH_expf
							float expf(float x)
							{
								return exp(x);
							}
							#endif
							/* expl */
							#ifndef ARCH_expl
							# warning Unsupported platform: expl() is not implemented
							long double expl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* expm1 */
							#ifndef ARCH_expm1
							double expm1(double x)
							{
								return expm1l(x);
							}
							#endif
							/* expm1f */
							#ifndef ARCH_expm1f
							float expm1f(float x)
							{
								return expm1(x);
							}
							#endif
							/* expm1l */
							#ifndef ARCH_expm1l
							# warning Unsupported platform: expm1l() is not implemented
							long double expm1l(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* fabs */
							#ifndef ARCH_fabs
							double fabs(double x)
							{
								return (x >= 0.0) ? x : -x;
							}
							#endif
							/* fabsf */
							#ifndef ARCH_fabsf
							float fabsf(float x)
							{
								return (x >= 0.0) ? x : -x;
							}
							#endif
							/* fabsl */
							#ifndef ARCH_fabsl
							long double fabsl(long double x)
							{
								return (x >= 0.0) ? x : -x;
							}
							#endif
							/* fdim */
							#ifndef ARCH_fdim
							double fdim(double x, double y)
							{
								return fdiml(x, y);
							}
							#endif
							/* fdimf */
							#ifndef ARCH_fdimf
							float fdimf(float x, float y)
							{
								return fdim(x, y);
							}
							#endif
							/* fdiml */
							#ifndef ARCH_fdiml
							# warning Unsupported platform: fdiml() is not implemented
							long double fdiml(long double x, long double y)
							{
								(void) x;
								(void) y;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* floor */
							#ifndef ARCH_floor
							double floor(double x)
							{
								return floorl(x);
							}
							#endif
							/* floorf */
							#ifndef ARCH_floorf
							float floorf(float x)
							{
								return floor(x);
							}
							#endif
							#ifndef ARCH_floorl
							long double floorl(long double x)
							{
								long double y;
								y = roundl(x);
								return (y <= x) ? y : y - 1.0;
							}
							#endif
							#if 0
							double fma(double, double, double);
							float fmaf(float, float, float);
							long double fmal(long double, long double, long double);
							#endif
							/* fmax */
							#ifndef ARCH_fmax
							double fmax(double x, double y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x >= y) ? x : y;
							}
							#endif
							/* fmaxf */
							#ifndef ARCH_fmaxf
							float fmaxf(float x, float y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x >= y) ? x : y;
							}
							#endif
							/* fmaxl */
							#ifndef ARCH_fmaxl
							long double fmaxl(long double x, long double y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x >= y) ? x : y;
							}
							#endif
							/* fmin */
							#ifndef ARCH_fmin
							double fmin(double x, double y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x <= y) ? x : y;
							}
							#endif
							/* fminf */
							#ifndef ARCH_fminf
							float fminf(float x, float y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x <= y) ? x : y;
							}
							#endif
							/* fminl */
							#ifndef ARCH_fminl
							long double fminl(long double x, long double y)
							{
								if(isnan(x))
									return y;
								if(isnan(y))
									return x;
								return (x <= y) ? x : y;
							}
							#endif
							/* fmod */
							#ifndef ARCH_fmod
							double fmod(double x, double y)
							{
								return fmodl(x, y);
							}
							#endif
							/* fmod */
							#ifndef ARCH_fmodf
							float fmodf(float x, float y)
							{
								return fmod(x, y);
							}
							#endif
							/* fmodl */
							#ifndef ARCH_fmodl
							long double fmodl(long double x, long double y)
							{
								long double z;
								z = floor(x / y);
								return x - (y * z);
							}
							#endif
							/* frexp */
							#ifndef ARCH_frexp
							double frexp(double x, int * y)
							{
								return frexpl(x, y);
							}
							#endif
							/* frexpf */
							#ifndef ARCH_frexpf
							float frexpf(float x, int * y)
							{
								return frexp(x, y);
							}
							#endif
							/* frexpl */
							#ifndef ARCH_frexpl
							# warning Unsupported platform: frexpl() is not implemented
							long double frexpl(long double x, int * y)
							{
								(void) x;
								(void) y;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* hypot */
							#ifndef ARCH_hypot
							double hypot(double x, double y)
							{
								return hypotl(x, y);
							}
							#endif
							/* hypotf */
							#ifndef ARCH_hypotf
							float hypotf(float x, float y)
							{
								return hypot(x, y);
							}
							#endif
							/* hypotl */
							#ifndef ARCH_hypotl
							long double hypotl(long double x, long double y)
							{
								/* XXX may overflow */
								return sqrt((x * x) + (y * y));
							}
							#endif
							#if 0
							int ilogb(double);
							int ilogbf(float);
							int ilogbl(long double);
							#endif
							/* isinf */
							int __isinf(double x)
							{
								return x == strtold("INF", NULL);
							}
							/* isnan */
							int __isnan(double x)
							{
								return x == nanl(NULL);
							}
							/* j0 */
							double j0(double x)
							{
								return _jn(0, &x);
							}
							/* j1 */
							double j1(double x)
							{
								return _jn(1, &x);
							}
							/* jn */
							double jn(int n, double x)
							{
								return _jn(n, &x);
							}
							/* ldexp */
							#ifndef ARCH_ldexp
							double ldexp(double x, int y)
							{
								return ldexpl(x, y);
							}
							#endif
							/* ldexpf */
							#ifndef ARCH_ldexpf
							float ldexpf(float x, int y)
							{
								return ldexp(x, y);
							}
							#endif
							/* ldexpl */
							#ifndef ARCH_ldexpl
							# warning Unsupported platform: ldexpl() is not implemented
							long double ldexpl(long double x, int y)
							{
								(void) x;
								(void) y;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* lgamma */
							#ifndef ARCH_lgamma
							double lgamma(double x)
							{
							    register int  k = floor (x);
							    long double   w;
							    long double   y;
							    long double   z;
							    _signgam = 0;
							    if ( k >= 7 )
							        return _logfact (x-1);
							    if ( k == x )
							        switch (k) {
							        case 1 :
							        case 2 : return 0.000000000000000000000000000l;
							        case 3 : return 0.693147180559945309432805516l;
							        case 4 : return 1.791759469228055000858148560l;
							        case 5 : return 3.178053830347945619723759592l;
							        case 6 : return 4.787491742782045994244981560l;
							        default: return 1./0.; /* ignore the gcc warning, this is intentional */
							        }
							    z = _logfact (y = x - k + 7.0 - 1);
							    w = 1;
							    for ( k = 7 - k; k--; )
							        w *= y, y -= 1.;
							    _signgam = k >= 0  ?  0  :  k & 1;
							    return z - log (w);
							}
							#endif
							/* lgammaf */
							#ifndef ARCH_lgammaf
							float lgammaf(float x)
							{
								return lgamma(x);
							}
							#endif
							/* lgammal */
							#ifndef ARCH_lgammal
							# warning Unsupported platform: lgammal() is not implemented
							long double lgammal(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							#if 0
							long long llrint(double);
							long long llrintf(float);
							long long llrintl(long double);
							long long llround(double);
							long long llroundf(float);
							long long llroundl(long double);
							#endif
							/* log */
							#ifndef ARCH_log
							double log(double x)
							{
								return logl(x);
							}
							#endif
							/* log10 */
							#ifndef ARCH_log10
							double log10(double x)
							{
								return log10l(x);
							}
							#endif
							/* log1p */
							#ifndef ARCH_log1p
							double log1p(double x)
							{
								return log1pl(x);
							}
							#endif
							/* log1pf */
							#ifndef ARCH_log1pf
							float log1pf(float x)
							{
								return log1p(x);
							}
							#endif
							/* log1pl */
							#ifndef ARCH_log1pl
							# warning Unsupported platform: log1pl() is not implemented
							long double log1pl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* log2 */
							#ifndef ARCH_log2
							double log2(double x)
							{
								return log2l(x);
							}
							#endif
							/* log2f */
							#ifndef ARCH_log2f
							float log2f(float x)
							{
								return log2(x);
							}
							#endif
							/* log2l */
							#ifndef ARCH_log2l
							# warning Unsupported platform: log2l() is not implemented
							long double log2l(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* logb */
							#ifndef ARCH_logb
							double logb(double x)
							{
								return logbl(x);
							}
							#endif
							/* logbf */
							#ifndef ARCH_logbf
							float logbf(float x)
							{
								return logb(x);
							}
							#endif
							/* logbl */
							#ifndef ARCH_logbl
							# warning Unsupported platform: logbl() is not implemented
							long double logbl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* log10f */
							#ifndef ARCH_log10f
							float log10f(float x)
							{
								return log10(x);
							}
							#endif
							/* log10l */
							#ifndef ARCH_log10l
							# warning Unsupported platform: log10l() is not implemented
							long double log10l(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* logf */
							#ifndef ARCH_logf
							float logf(float x)
							{
								return log(x);
							}
							#endif
							/* logl */
							#ifndef ARCH_logl
							# warning Unsupported platform: logl() is not implemented
							long double logl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							#if 0
							long lrint(double);
							long lrintf(float);
							long lrintl(long double);
							long lround(double);
							long lroundf(float);
							long lroundl(long double);
							#endif
							/* modf */
							#ifndef ARCH_modf
							double modf(double x, double * iptr)
							{
								double ret = fmod(x, 1.0);
								*iptr = x - ret;
								return ret;
							}
							#endif
							/* modff */
							#ifndef ARCH_modff
							float modff(float x, float * iptr)
							{
								float ret = fmodf(x, 1.0);
								*iptr = x - ret;
								return ret;
							}
							#endif
							/* modfl */
							#ifndef ARCH_modfl
							long double modfl(long double x, long double * iptr)
							{
								long double ret = fmodl(x, 1.0);
								*iptr = x - ret;
								return ret;
							}
							#endif
							/* nan */
							double nan(const char * tagp)
							{
								if(tagp == NULL || strlen(tagp) == 0)
									return strtod("NAN", NULL);
								/* FIXME implement */
								return 0.0;
							}
							/* nanf */
							float nanf(const char * tagp)
							{
								if(tagp == NULL || strlen(tagp) == 0)
									return strtof("NAN", NULL);
								/* FIXME implement */
								return 0.0;
							}
							/* nanl */
							long double nanl(const char * tagp)
							{
								if(tagp == NULL || strlen(tagp) == 0)
									return strtold("NAN", NULL);
								/* FIXME implement */
								return 0.0;
							}
							#if 0
							double nearbyint(double);
							float nearbyintf(float);
							long double nearbyintl(long double);
							double nextafter(double, double);
							float nextafterf(float, float);
							long double nextafterl(long double, long double);
							double nexttoward(double, long double);
							float nexttowardf(float, long double);
							long double nexttowardl(long double, long double);
							#endif
							/* pow */
							#ifndef ARCH_pow
							double pow(double x, double y)
							{
								return powl(x, y);
							}
							#endif
							/* powf */
							#ifndef ARCH_powf
							float powf(float x, float y)
							{
								return pow(x, y);
							}
							#endif
							/* powl */
							#ifndef ARCH_powl
							long double powl(long double x, long double y)
							{
								long double ret;
								if(x == 1.0 || y == 0.0)
									return 1.0;
								if(isnan(x))
									return x;
								else if(isnan(y))
									return y;
								if(x < 0.0 || roundl(y) != y)
								{
									/* XXX really report the error */
									errno = EDOM;
									return 0.0;
								}
								if(x == 0.0 && y > 0.0)
									return 0.0;
								/* XXX there are more corner cases with infinity */
								for(ret = 1.0; y >= 1.0; y -= 1.0)
									/* FIXME detect overflows and underflows */
									ret = ret * x;
								return ret;
							}
							#endif
							/* remainder */
							#ifndef ARCH_remainder
							double remainder(double x, double y)
							{
								return remainderl(x, y);
							}
							#endif
							/* remainderf */
							#ifndef ARCH_remainderf
							float remainderf(float x, float y)
							{
								return remainder(x, y);
							}
							#endif
							/* remainderl */
							#ifndef ARCH_remainderl
							long double remainderl(long double x, long double y)
							{
								return x - floor(x / y);
							}
							#endif
							#if 0
							double remquo(double, double, int *);
							float remquof(float, float, int *);
							long double remquol(long double, long double, int *);
							#endif
							/* rint */
							#ifndef ARCH_rint
							double rint(double x)
							{
								return floor(x + 0.5);
							}
							#endif
							/* rintf */
							#ifndef ARCH_rintf
							float rintf(float x)
							{
								return floorf(x + 0.5);
							}
							#endif
							/* rintl */
							#ifndef ARCH_rintl
							long double rintl(long double x)
							{
								return floorl(x + 0.5);
							}
							#endif
							/* round */
							#ifndef ARCH_round
							double round(double x)
							{
								return roundl(x);
							}
							#endif
							/* roundf */
							#ifndef ARCH_roundf
							float roundf(float x)
							{
								return round(x);
							}
							#endif
							/* roundl */
							#ifndef ARCH_roundl
							# warning Unsupported platform: roundl() is not implemented
							long double roundl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							#if 0
							double scalb(double, double);
							double scalbln(double, long);
							float scalblnf(float, long);
							long double scalblnl(long double, long);
							double scalbn(double, int);
							float scalbnf(float, int);
							long double scalbnl(long double, int);
							#endif
							/* sin */
							#ifndef ARCH_sin
							double sin(double x)
							{
								return sinl(x);
							}
							#endif
							/* sinf */
							#ifndef ARCH_sinf
							float sinf(float x)
							{
								return sin(x);
							}
							#endif
							/* sinh */
							#ifndef ARCH_sinh
							double sinh(double x)
							{
								return (exp(x) - exp(-x)) / 2;
							}
							#endif
							/* sinhf */
							#ifndef ARCH_sinhf
							float sinhf(float x)
							{
								return (expf(x) - expf(-x)) / 2;
							}
							#endif
							/* sinhl */
							#ifndef ARCH_sinhl
							long double sinhl(long double x)
							{
								return (expl(x) - expl(-x)) / 2;
							}
							#endif
							/* sinl */
							#ifndef ARCH_sinl
							# warning Unsupported platform: sinl() is not implemented
							long double sinl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* sqrt */
							#ifndef ARCH_sqrt
							double sqrt(double x)
							{
								return sqrtl(x);
							}
							#endif
							/* sqrtf */
							#ifndef ARCH_sqrtf
							float sqrtf(float x)
							{
								return sqrt(x);
							}
							#endif
							/* sqrtl */
							#ifndef ARCH_sqrtl
							# warning Unsupported platform: sqrtl() is not implemented
							long double sqrtl(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* tan */
							#ifndef ARCH_tan
							double tan(double x)
							{
								return sin(x) / cos(x);
							}
							#endif
							/* tanf */
							#ifndef ARCH_tanf
							float tanf(float x)
							{
								return sinf(x) / cosf(x);
							}
							#endif
							/* tanh */
							#ifndef ARCH_tanh
							double tanh(double x)
							{
								return sinh(x) / cosh(x);
							}
							#endif
							/* tanhf */
							#ifndef ARCH_tanhf
							float tanhf(float x)
							{
								return sinhf(x) / coshf(x);
							}
							#endif
							/* tanhl */
							#ifndef ARCH_tanhl
							long double tanhl(long double x)
							{
								return sinhl(x) / coshl(x);
							}
							#endif
							/* tanl */
							#ifndef ARCH_tanl
							long double tanl(long double x)
							{
								return sinl(x) / cosl(x);
							}
							#endif
							/* tgamma */
							#ifndef ARCH_tgamma
							double tgamma(double x)
							{
								return tgammal(x);
							}
							#endif
							/* tgammaf */
							#ifndef ARCH_tgammaf
							float tgammaf(float x)
							{
								return tgamma(x);
							}
							#endif
							/* tgammal */
							#ifndef ARCH_tgammal
							# warning Unsupported platform: tgammal() is not implemented
							long double tgammal(long double x)
							{
								(void) x;
								/* FIXME implement */
								return 0.0;
							}
							#endif
							/* trunc */
							#ifndef ARCH_trunc
							double trunc(double x)
							{
								return rint(x);
							}
							#endif
							/* truncf */
							#ifndef ARCH_truncf
							float truncf(float x)
							{
								return rintf(x);
							}
							#endif
							/* truncl */
							#ifndef ARCH_truncl
							long double truncl(long double x)
							{
								return rintl(x);
							}
							#endif
							/* y0 */
							double y0(double x)
							{
								return _yn(0, &x);
							}
							/* y1 */
							double y1(double x)
							{
								return _yn(1, &x);
							}
							/* yn */
							double yn(int n, double x)
							{
								return _yn(n, &x);
							}
							