diff options
author | Sergey Cherkashin <4erkashin@list.ru> | 2017-10-03 15:26:34 +0300 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2017-11-03 20:23:10 +0100 |
commit | ea38f4d89c9698895b1cf53a5946429dc1d8bbaa (patch) | |
tree | e05828ca1fedf55f104b837bc9c44215c2978e99 | |
parent | 68de9946e914d8c30dcc6667a059ea59e5b74cac (diff) |
math: add exception handling functionality
According to standards SVID and SYSV.
Modified lgamma calling in case when 'signgam' variable should not be used.
Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
108 files changed, 4694 insertions, 433 deletions
diff --git a/include/math.h b/include/math.h index 25454764a..70f04f230 100644 --- a/include/math.h +++ b/include/math.h @@ -192,6 +192,30 @@ extern long double __REDIRECT_NTH (nexttowardl, (long double __x, long double __ #if defined __USE_MISC || defined __USE_XOPEN /* This variable is used by `gamma' and `lgamma'. */ extern int signgam; +#else +/* This is used when standart of libm + * should prevent lgamma(x) of modifying signgam variable. + */ +# define lgammaf(arg) \ +({ \ +int local_signgam = 0; \ +float result = lgammaf_r((float)arg, &local_signgam); \ +result; \ +}) + +# define lgamma(arg) \ +({ \ +int local_signgam = 0; \ +double result = lgamma_r(arg, &local_signgam); \ +result; \ +}) + +# define lgammal(arg) \ +({ \ +int local_signgam = 0; \ +long double result = lgammal_r(arg, &local_signgam); \ +result; \ +}) #endif @@ -361,7 +385,7 @@ struct exception # ifdef __cplusplus extern int matherr (struct __exception *__exc) throw (); # else -extern int matherr (struct exception *__exc); +extern int __attribute__ ((weak)) matherr (struct exception *__exc); # endif # define X_TLOSS 1.41484755040568800000e+16 diff --git a/libc/sysdeps/linux/common/bits/mathcalls.h b/libc/sysdeps/linux/common/bits/mathcalls.h index 8ab807578..a9e8a2931 100644 --- a/libc/sysdeps/linux/common/bits/mathcalls.h +++ b/libc/sysdeps/linux/common/bits/mathcalls.h @@ -300,14 +300,17 @@ __END_NAMESPACE_C99 __MATHCALLI (gamma,, (_Mdouble_)) #endif -#ifdef __USE_MISC +//#ifdef __USE_MISC +/* To provide compatibility with finite-math-only in C99 and C11 + * standerts function lgamma_r should be declared, when defined __USE_MISC. + */ /* Reentrant version of lgamma. This function uses the global variable `signgam'. The reentrant version instead takes a pointer and stores the value through it. */ __MATHCALL (lgamma,_r, (_Mdouble_, int *__signgamp)) /* __MATHCALLI does not work here, probably due to ,_r, */ libm_hidden_proto(lgamma_r) -#endif +//#endif #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 diff --git a/libc/sysdeps/linux/powerpc/bits/mathdef.h b/libc/sysdeps/linux/powerpc/bits/mathdef.h index 2c0cad116..97a05b6b2 100644 --- a/libc/sysdeps/linux/powerpc/bits/mathdef.h +++ b/libc/sysdeps/linux/powerpc/bits/mathdef.h @@ -44,10 +44,6 @@ typedef double double_t; /* `double' expressions are evaluated as #endif /* ISO C99 */ -#ifndef __NO_LONG_DOUBLE_MATH -/* Signal that we do not really have a `long double'. The disables the - declaration of all the `long double' function variants. */ -# if !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ -# define __NO_LONG_DOUBLE_MATH 1 -# endif -#endif /* __NO_LONG_DOUBLE_MATH */ +#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ +# define __NO_LONG_DOUBLE_MATH 1 +#endif diff --git a/libc/sysdeps/linux/powerpc/bits/wordsize.h b/libc/sysdeps/linux/powerpc/bits/wordsize.h index 0c0d31b98..da587a2f1 100644 --- a/libc/sysdeps/linux/powerpc/bits/wordsize.h +++ b/libc/sysdeps/linux/powerpc/bits/wordsize.h @@ -1,14 +1,3 @@ /* Determine the wordsize from the preprocessor defines. */ #define __WORDSIZE 32 - -#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL - -/* Signal the glibc ABI didn't used to have a `long double'. - The changes all the `long double' function variants to be redirects - to the double functions. */ -# define __LONG_DOUBLE_MATH_OPTIONAL 1 -# ifndef __LONG_DOUBLE_128__ -# define __NO_LONG_DOUBLE_MATH 1 -# endif -#endif diff --git a/libm/Makefile.in b/libm/Makefile.in index 9b40a9400..e2f4ff808 100644 --- a/libm/Makefile.in +++ b/libm/Makefile.in @@ -64,8 +64,37 @@ libm_CSRC := \ s_fpclassify.c s_fpclassifyf.c s_signbit.c s_signbitf.c \ s_isnan.c s_isnanf.c s_isinf.c s_isinff.c s_finitef.c \ s_fdim.c s_fma.c s_fmax.c s_fmin.c \ - s_remquo.c w_exp2.c \ - cexp.c sincos.c + s_remquo.c \ + cexp.c sincos.c \ + w_acos.c w_acosf.c w_acosl.c \ + w_asin.c w_asinf.c w_asinl.c \ + w_atan2.c w_atan2f.c w_atan2l.c \ + w_hypot.c w_hypotf.c w_hypotl.c \ + w_cosh.c w_coshf.c w_coshl.c \ + w_exp.c w_expf.c w_expl.c \ + w_exp2.c w_exp2f.c w_exp2l.c \ + w_exp10.c w_exp10f.c w_exp10l.c \ + w_j0.c w_j0f.c w_j0l.c \ + w_j1.c w_j1f.c w_j1l.c \ + w_jn.c w_jnf.c w_jnl.c \ + w_lgamma_r.c w_lgammaf_r.c w_lgammal_r.c \ + w_lgamma.c w_lgammaf.c w_lgammal.c \ + w_tgamma.c w_tgammaf.c w_tgammal.c \ + w_log.c w_logf.c w_logl.c \ + w_log2.c w_log2f.c w_log2l.c \ + w_log10.c w_log10f.c w_log10l.c \ + w_pow.c w_powf.c w_powl.c \ + w_sinh.c w_sinhf.c w_sinhl.c \ + w_fmod.c w_fmodf.c w_fmodl.c \ + w_sqrt.c w_sqrtf.c w_sqrtl.c \ + w_remainder.c w_remainderf.c w_remainderl.c \ + w_acosh.c w_acoshf.c w_acoshl.c \ + w_atanh.c w_atanhf.c w_atanhl.c \ + w_scalb.c w_scalbf.c w_scalbl.c + +ifeq ($(UCLIBC_HAS_FENV),y) + libm_CSRC += k_standard.c k_standardf.c k_standardl.c +endif FL_MOBJ := \ acosf.o \ @@ -230,7 +259,9 @@ libm_CSRC := \ s_expm1.c s_scalbn.c s_copysign.c e_acos.c e_asin.c e_atan2.c \ k_cos.c e_cosh.c e_exp.c e_fmod.c e_log.c e_log10.c e_pow.c \ k_sin.c e_sinh.c e_sqrt.c k_tan.c e_rem_pio2.c k_rem_pio2.c \ - s_finite.c e_exp10.c + s_finite.c e_exp10.c \ + matherr_wrapers.c k_standart.c + # We'll add sqrtf to avoid problems with libstdc++ FL_MOBJ := sqrtf.o endif diff --git a/libm/e_acos.c b/libm/e_acos.c index acf10130e..0f3ea2e09 100644 --- a/libm/e_acos.c +++ b/libm/e_acos.c @@ -94,7 +94,4 @@ double __ieee754_acos(double x) w = r*s+c; return 2.0*(df+w); } -} - -strong_alias(__ieee754_acos, acos) -libm_hidden_def(acos) +}
\ No newline at end of file diff --git a/libm/e_acosh.c b/libm/e_acosh.c index 17e29c824..ac4ea088e 100644 --- a/libm/e_acosh.c +++ b/libm/e_acosh.c @@ -50,9 +50,6 @@ double __ieee754_acosh(double x) return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one))); } else { /* 1<x<2 */ t = x-one; - return log1p(t+sqrt(2.0*t+t*t)); + return log1p(t+__ieee754_sqrt(2.0*t+t*t)); } } - -strong_alias(__ieee754_acosh, acosh) -libm_hidden_def(acosh) diff --git a/libm/e_asin.c b/libm/e_asin.c index 1441acb3d..07e0fd0d8 100644 --- a/libm/e_asin.c +++ b/libm/e_asin.c @@ -104,6 +104,3 @@ double __ieee754_asin(double x) } if(hx>0) return t; else return -t; } - -strong_alias(__ieee754_asin, asin) -libm_hidden_def(asin) diff --git a/libm/e_atan2.c b/libm/e_atan2.c index ef379aa7a..06a47e89d 100644 --- a/libm/e_atan2.c +++ b/libm/e_atan2.c @@ -113,7 +113,4 @@ double __ieee754_atan2(double y, double x) default: /* case 3 */ return (z-pi_lo)-pi;/* atan(-,-) */ } -} - -strong_alias(__ieee754_atan2, atan2) -libm_hidden_def(atan2) +}
\ No newline at end of file diff --git a/libm/e_atanh.c b/libm/e_atanh.c index fb36a1af1..9fc8f7de9 100644 --- a/libm/e_atanh.c +++ b/libm/e_atanh.c @@ -54,6 +54,3 @@ double __ieee754_atanh(double x) t = 0.5*log1p((x+x)/(one-x)); if(hx>=0) return t; else return -t; } - -strong_alias(__ieee754_atanh, atanh) -libm_hidden_def(atanh) diff --git a/libm/e_cosh.c b/libm/e_cosh.c index a8e34aa45..27dcbefc0 100644 --- a/libm/e_cosh.c +++ b/libm/e_cosh.c @@ -76,7 +76,4 @@ double __ieee754_cosh(double x) /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; -} - -strong_alias(__ieee754_cosh, cosh) |