summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Cherkashin <4erkashin@list.ru>2017-10-03 15:26:34 +0300
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2017-11-03 20:23:10 +0100
commitea38f4d89c9698895b1cf53a5946429dc1d8bbaa (patch)
treee05828ca1fedf55f104b837bc9c44215c2978e99
parent68de9946e914d8c30dcc6667a059ea59e5b74cac (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>
-rw-r--r--include/math.h26
-rw-r--r--libc/sysdeps/linux/common/bits/mathcalls.h7
-rw-r--r--libc/sysdeps/linux/powerpc/bits/mathdef.h10
-rw-r--r--libc/sysdeps/linux/powerpc/bits/wordsize.h11
-rw-r--r--libm/Makefile.in37
-rw-r--r--libm/e_acos.c5
-rw-r--r--libm/e_acosh.c5
-rw-r--r--libm/e_asin.c3
-rw-r--r--libm/e_atan2.c5
-rw-r--r--libm/e_atanh.c3
-rw-r--r--libm/e_cosh.c5
-rw-r--r--libm/e_exp.c3
-rw-r--r--libm/e_exp10.c2
-rw-r--r--libm/e_fmod.c3
-rw-r--r--libm/e_hypot.c5
-rw-r--r--libm/e_j0.c4
-rw-r--r--libm/e_j1.c4
-rw-r--r--libm/e_jn.c4
-rw-r--r--libm/e_lgamma_r.c30
-rw-r--r--libm/e_log.c3
-rw-r--r--libm/e_log10.c3
-rw-r--r--libm/e_log2.c2
-rw-r--r--libm/e_pow.c3
-rw-r--r--libm/e_remainder.c4
-rw-r--r--libm/e_scalb.c5
-rw-r--r--libm/e_sinh.c3
-rw-r--r--libm/e_sqrt.c3
-rw-r--r--libm/float_wrappers.c189
-rw-r--r--libm/k_standard.c973
-rw-r--r--libm/k_standardf.c31
-rw-r--r--libm/k_standardl.c107
-rw-r--r--libm/ldouble_wrappers.c171
-rw-r--r--libm/math_private.h10
-rw-r--r--libm/w_acos.c40
-rw-r--r--libm/w_acosf.c38
-rw-r--r--libm/w_acosh.c34
-rw-r--r--libm/w_acoshf.c33
-rw-r--r--libm/w_acoshl.c34
-rw-r--r--libm/w_acosl.c42
-rw-r--r--libm/w_asin.c39
-rw-r--r--libm/w_asinf.c38
-rw-r--r--libm/w_asinl.c41
-rw-r--r--libm/w_atan2.c46
-rw-r--r--libm/w_atan2f.c46
-rw-r--r--libm/w_atan2l.c44
-rw-r--r--libm/w_atanh.c37
-rw-r--r--libm/w_atanhf.c36
-rw-r--r--libm/w_atanhl.c38
-rw-r--r--libm/w_cosh.c34
-rw-r--r--libm/w_coshf.c37
-rw-r--r--libm/w_coshl.c40
-rw-r--r--libm/w_exp.c38
-rw-r--r--libm/w_exp10.c43
-rw-r--r--libm/w_exp10f.c42
-rw-r--r--libm/w_exp10l.c44
-rw-r--r--libm/w_exp2.c45
-rw-r--r--libm/w_exp2f.c22
-rw-r--r--libm/w_exp2l.c24
-rw-r--r--libm/w_expf.c38
-rw-r--r--libm/w_expl.c39
-rw-r--r--libm/w_fmod.c34
-rw-r--r--libm/w_fmodf.c33
-rw-r--r--libm/w_fmodl.c35
-rw-r--r--libm/w_hypot.c34
-rw-r--r--libm/w_hypotf.c37
-rw-r--r--libm/w_hypotl.c40
-rw-r--r--libm/w_j0.c63
-rw-r--r--libm/w_j0f.c68
-rw-r--r--libm/w_j0l.c68
-rw-r--r--libm/w_j1.c64
-rw-r--r--libm/w_j1f.c68
-rw-r--r--libm/w_j1l.c68
-rw-r--r--libm/w_jn.c63
-rw-r--r--libm/w_jnf.c66
-rw-r--r--libm/w_jnl.c95
-rw-r--r--libm/w_lgamma.c37
-rw-r--r--libm/w_lgamma_r.c38
-rw-r--r--libm/w_lgammaf.c30
-rw-r--r--libm/w_lgammaf_r.c41
-rw-r--r--libm/w_lgammal.c39
-rw-r--r--libm/w_lgammal_r.c44
-rw-r--r--libm/w_log.c46
-rw-r--r--libm/w_log10.c46
-rw-r--r--libm/w_log10f.c45
-rw-r--r--libm/w_log10l.c45
-rw-r--r--libm/w_log2.c46
-rw-r--r--libm/w_log2f.c45
-rw-r--r--libm/w_log2l.c47
-rw-r--r--libm/w_logf.c45
-rw-r--r--libm/w_logl.c47
-rw-r--r--libm/w_pow.c78
-rw-r--r--libm/w_powf.c76
-rw-r--r--libm/w_powl.c78
-rw-r--r--libm/w_remainder.c35
-rw-r--r--libm/w_remainderf.c34
-rw-r--r--libm/w_remainderl.c36
-rw-r--r--libm/w_scalb.c86
-rw-r--r--libm/w_scalbf.c80
-rw-r--r--libm/w_scalbl.c83
-rw-r--r--libm/w_sinh.c34
-rw-r--r--libm/w_sinhf.c37
-rw-r--r--libm/w_sinhl.c39
-rw-r--r--libm/w_sqrt.c32
-rw-r--r--libm/w_sqrtf.c32
-rw-r--r--libm/w_sqrtl.c33
-rw-r--r--libm/w_tgamma.c47
-rw-r--r--libm/w_tgammaf.c48
-rw-r--r--libm/w_tgammal.c51
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)