From b4194dfd5548262d72f4d521bb5895aa65dff172 Mon Sep 17 00:00:00 2001 From: kargl Date: Mon, 23 Jul 2012 19:13:55 +0000 Subject: Compute the exponential of x for Intel 80-bit format and IEEE 128-bit format. These implementations are based on PTP Tang, "Table-driven implementation of the exponential function in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 15, 144-157 (1989). PR: standards/152415 Submitted by: kargl Reviewed by: bde, das Approved by: das (mentor) --- lib/msun/src/e_exp.c | 4 ++++ lib/msun/src/math.h | 2 +- lib/msun/src/math_private.h | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'lib/msun/src') diff --git a/lib/msun/src/e_exp.c b/lib/msun/src/e_exp.c index b47aef5..e432bc8 100644 --- a/lib/msun/src/e_exp.c +++ b/lib/msun/src/e_exp.c @@ -158,3 +158,7 @@ __ieee754_exp(double x) /* default IEEE double exp */ return y*twopk*twom1000; } } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(exp, expl); +#endif diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h index cf34583..c6cee13 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -404,6 +404,7 @@ long double ceill(long double); long double copysignl(long double, long double) __pure2; long double cosl(long double); long double exp2l(long double); +long double expl(long double); long double fabsl(long double) __pure2; long double fdiml(long double, long double); long double floorl(long double); @@ -461,7 +462,6 @@ long double atanhl(long double); long double coshl(long double); long double erfcl(long double); long double erfl(long double); -long double expl(long double); long double expm1l(long double); long double lgammal(long double); long double log10l(long double); diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h index 79280e3..94e7507 100644 --- a/lib/msun/src/math_private.h +++ b/lib/msun/src/math_private.h @@ -207,6 +207,13 @@ do { \ (d) = se_u.e; \ } while (0) +/* Long double constants are broken on i386. This workaround is OK always. */ +#define LD80C(m, ex, s, v) { \ + /* .e = v, */ /* overwritten */ \ + .xbits.man = __CONCAT(m, ULL), \ + .xbits.expsign = (0x3fff + (ex)) | ((s) ? 0x8000 : 0), \ +} + #ifdef FLT_EVAL_METHOD /* * Attempt to get strict C99 semantics for assignment with non-C99 compilers. @@ -225,8 +232,30 @@ do { \ } \ } while (0) #endif +#endif /* FLT_EVAL_METHOD */ + +/* Support switching the mode to FP_PE if necessary. */ +#if defined(__i386__) && !defined(NO_FPSETPREC) +#define ENTERI() \ + long double __retval; \ + fp_prec_t __oprec; \ + \ + if ((__oprec = fpgetprec()) != FP_PE) \ + fpsetprec(FP_PE); +#define RETURNI(x) do { \ + __retval = (x); \ + if (__oprec != FP_PE) \ + fpsetprec(__oprec); \ + RETURNF(__retval); \ +} while (0) +#else +#define ENTERI(x) +#define RETURNI(x) RETURNF(x) #endif +/* Default return statement if hack*_t() is not used. */ +#define RETURNF(v) return (v) + /* * Common routine to process the arguments to nan(), nanf(), and nanl(). */ @@ -323,6 +352,18 @@ irint(double x) #define HAVE_EFFICIENT_IRINT #endif +#if defined(__amd64__) || defined(__i386__) +static __inline int +irintl(long double x) +{ + int n; + + asm("fistl %0" : "=m" (n) : "t" (x)); + return (n); +} +#define HAVE_EFFICIENT_IRINTL +#endif + #endif /* __GNUCLIKE_ASM */ /* -- cgit v1.1