From c8fcb04ad95386fea45e2cc0ad7277e5c9a27f4d Mon Sep 17 00:00:00 2001 From: theraven Date: Fri, 6 Sep 2013 07:58:23 +0000 Subject: Add stub implementations of the missing C++11 math functions. These are weak and so can be replaced by other versions in applications that choose to do so, and will give a linker warning when used so that applications that rely on the extra precision can avoid them. Note that since the C/C++ specs only guarantee that long double has precision equal to double, code that actually relies on these functions having greater precision is unportable at best and broken at worst. --- lib/msun/Makefile | 1 + lib/msun/Symbol.map | 9 +++++++ lib/msun/src/imprecise.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 lib/msun/src/imprecise.c (limited to 'lib/msun') diff --git a/lib/msun/Makefile b/lib/msun/Makefile index 14db97e..629d523 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -53,6 +53,7 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ e_pow.c e_powf.c e_rem_pio2.c \ e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c fenv.c \ + imprecise.c \ k_cos.c k_cosf.c k_exp.c k_expf.c k_rem_pio2.c k_sin.c k_sinf.c \ k_tan.c k_tanf.c \ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_carg.c s_cargf.c s_cargl.c \ diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map index f244af4..5b75f08 100644 --- a/lib/msun/Symbol.map +++ b/lib/msun/Symbol.map @@ -270,4 +270,13 @@ FBSD_1.3 { log1pl; log2l; logl; + # Implemented as weak aliases for imprecise versions + coshl; + erfcl; + erfl; + lgammal; + powl; + sinhl; + tanhl; + tgammal; }; diff --git a/lib/msun/src/imprecise.c b/lib/msun/src/imprecise.c new file mode 100644 index 0000000..a7503bf --- /dev/null +++ b/lib/msun/src/imprecise.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2013 David Chisnall + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +#include + +/* + * If long double is not the same size as double, then these will lose + * precision and we should emit a warning whenever something links against + * them. + */ +#if (LDBL_MANT_DIG > 53) +#define WARN_IMPRECISE(x) \ + __warn_references(x, # x " has lower than advertised precision"); +#else +#define WARN_IMPRECISE(x) +#endif +/* + * Declare the functions as weak variants so that other libraries providing + * real versions can override them. + */ +#define DECLARE_WEAK(x)\ + __weak_reference(imprecise_## x, x);\ + WARN_IMPRECISE(x) + +long double +imprecise_powl(long double x, long double y) +{ + + return pow(x, y); +} +DECLARE_WEAK(powl); + +#define DECLARE_IMPRECISE(f) \ + long double imprecise_ ## f ## l(long double v) { return f(v); }\ + DECLARE_WEAK(f ## l) + +DECLARE_IMPRECISE(cosh); +DECLARE_IMPRECISE(erfc); +DECLARE_IMPRECISE(erf); +DECLARE_IMPRECISE(lgamma); +DECLARE_IMPRECISE(sinh); +DECLARE_IMPRECISE(tanh); +DECLARE_IMPRECISE(tgamma); -- cgit v1.1