[Midnightbsd-cvs] src [10596] trunk/lib/msun/ld80: sync ld80

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jun 9 11:11:52 EDT 2018


Revision: 10596
          http://svnweb.midnightbsd.org/src/?rev=10596
Author:   laffer1
Date:     2018-06-09 11:11:51 -0400 (Sat, 09 Jun 2018)
Log Message:
-----------
sync ld80

Modified Paths:
--------------
    trunk/lib/msun/ld80/e_rem_pio2l.h
    trunk/lib/msun/ld80/invtrig.c
    trunk/lib/msun/ld80/invtrig.h
    trunk/lib/msun/ld80/k_cosl.c
    trunk/lib/msun/ld80/k_sinl.c
    trunk/lib/msun/ld80/k_tanl.c
    trunk/lib/msun/ld80/s_exp2l.c
    trunk/lib/msun/ld80/s_nanl.c

Added Paths:
-----------
    trunk/lib/msun/ld80/e_lgammal_r.c
    trunk/lib/msun/ld80/k_expl.h
    trunk/lib/msun/ld80/s_erfl.c
    trunk/lib/msun/ld80/s_expl.c
    trunk/lib/msun/ld80/s_logl.c

Added: trunk/lib/msun/ld80/e_lgammal_r.c
===================================================================
--- trunk/lib/msun/ld80/e_lgammal_r.c	                        (rev 0)
+++ trunk/lib/msun/ld80/e_lgammal_r.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,359 @@
+/* $MidnightBSD$ */
+/* @(#)e_lgamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/e_lgammal_r.c 284810 2015-06-25 13:01:10Z tijl $");
+
+/*
+ * See e_lgamma_r.c for complete comments.
+ *
+ * Converted to long double by Steven G. Kargl.
+ */
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+
+static const volatile double vzero = 0;
+
+static const double
+zero=  0,
+half=  0.5,
+one =  1;
+
+static const union IEEEl2bits
+piu = LD80C(0xc90fdaa22168c235, 1,  3.14159265358979323851e+00L);
+#define	pi	(piu.e)
+/*
+ * Domain y in [0x1p-70, 0.27], range ~[-4.5264e-22, 4.5264e-22]:
+ * |(lgamma(2 - y) + y / 2) / y - a(y)| < 2**-70.9
+ */
+static const union IEEEl2bits
+a0u = LD80C(0x9e233f1bed863d26, -4,  7.72156649015328606028e-02L),
+a1u = LD80C(0xa51a6625307d3249, -2,  3.22467033424113218889e-01L),
+a2u = LD80C(0x89f000d2abafda8c, -4,  6.73523010531979398946e-02L),
+a3u = LD80C(0xa8991563eca75f26, -6,  2.05808084277991211934e-02L),
+a4u = LD80C(0xf2027e10634ce6b6, -8,  7.38555102796070454026e-03L),
+a5u = LD80C(0xbd6eb76dd22187f4, -9,  2.89051035162703932972e-03L),
+a6u = LD80C(0x9c562ab05e0458ed, -10,  1.19275351624639999297e-03L),
+a7u = LD80C(0x859baed93ee48e46, -11,  5.09674593842117925320e-04L),
+a8u = LD80C(0xe9f28a4432949af2, -13,  2.23109648015769155122e-04L),
+a9u = LD80C(0xd12ad0d9b93c6bb0, -14,  9.97387167479808509830e-05L),
+a10u= LD80C(0xb7522643c78a219b, -15,  4.37071076331030136818e-05L),
+a11u= LD80C(0xca024dcdece2cb79, -16,  2.40813493372040143061e-05L),
+a12u= LD80C(0xbb90fb6968ebdbf9, -19,  2.79495621083634031729e-06L),
+a13u= LD80C(0xba1c9ffeeae07b37, -17,  1.10931287015513924136e-05L);
+#define	a0	(a0u.e)
+#define	a1	(a1u.e)
+#define	a2	(a2u.e)
+#define	a3	(a3u.e)
+#define	a4	(a4u.e)
+#define	a5	(a5u.e)
+#define	a6	(a6u.e)
+#define	a7	(a7u.e)
+#define	a8	(a8u.e)
+#define	a9	(a9u.e)
+#define	a10	(a10u.e)
+#define	a11	(a11u.e)
+#define	a12	(a12u.e)
+#define	a13	(a13u.e)
+/*
+ * Domain x in [tc-0.24, tc+0.28], range ~[-6.1205e-22, 6.1205e-22]:
+ * |(lgamma(x) - tf) -  t(x - tc)| < 2**-70.5
+ */
+static const union IEEEl2bits
+tcu  = LD80C(0xbb16c31ab5f1fb71, 0,  1.46163214496836234128e+00L),
+tfu  = LD80C(0xf8cdcde61c520e0f, -4, -1.21486290535849608093e-01L),
+ttu  = LD80C(0xd46ee54b27d4de99, -69, -2.81152980996018785880e-21L),
+t0u  = LD80C(0x80b9406556a62a6b, -68,  3.40728634996055147231e-21L),
+t1u  = LD80C(0xc7e9c6f6df3f8c39, -67, -1.05833162742737073665e-20L),
+t2u  = LD80C(0xf7b95e4771c55d51, -2,  4.83836122723810583532e-01L),
+t3u  = LD80C(0x97213c6e35e119ff, -3, -1.47587722994530691476e-01L),
+t4u  = LD80C(0x845a14a6a81dc94b, -4,  6.46249402389135358063e-02L),
+t5u  = LD80C(0x864d46fa89997796, -5, -3.27885410884846056084e-02L),
+t6u  = LD80C(0x93373cbd00297438, -6,  1.79706751150707171293e-02L),
+t7u  = LD80C(0xa8fcfca7eddc8d1d, -7, -1.03142230361450732547e-02L),
+t8u  = LD80C(0xc7e7015ff4bc45af, -8,  6.10053603296546099193e-03L),
+t9u  = LD80C(0xf178d2247adc5093, -9, -3.68456964904901200152e-03L),
+t10u = LD80C(0x94188d58f12e5e9f, -9,  2.25976420273774583089e-03L),
+t11u = LD80C(0xb7cbaef14e1406f1, -10, -1.40224943666225639823e-03L),
+t12u = LD80C(0xe63a671e6704ea4d, -11,  8.78250640744776944887e-04L),
+t13u = LD80C(0x914b6c9cae61783e, -11, -5.54255012657716808811e-04L),
+t14u = LD80C(0xb858f5bdb79276fe, -12,  3.51614951536825927370e-04L),
+t15u = LD80C(0xea73e744c34b9591, -13, -2.23591563824520112236e-04L),
+t16u = LD80C(0x99aeabb0d67ba835, -13,  1.46562869351659194136e-04L),
+t17u = LD80C(0xd7c6938325db2024, -14, -1.02889866046435680588e-04L),
+t18u = LD80C(0xe24cb1e3b0474775, -15,  5.39540265505221957652e-05L);
+#define	tc	(tcu.e)
+#define	tf	(tfu.e)
+#define	tt	(ttu.e)
+#define	t0	(t0u.e)
+#define	t1	(t1u.e)
+#define	t2	(t2u.e)
+#define	t3	(t3u.e)
+#define	t4	(t4u.e)
+#define	t5	(t5u.e)
+#define	t6	(t6u.e)
+#define	t7	(t7u.e)
+#define	t8	(t8u.e)
+#define	t9	(t9u.e)
+#define	t10	(t10u.e)
+#define	t11	(t11u.e)
+#define	t12	(t12u.e)
+#define	t13	(t13u.e)
+#define	t14	(t14u.e)
+#define	t15	(t15u.e)
+#define	t16	(t16u.e)
+#define	t17	(t17u.e)
+#define	t18	(t18u.e)
+/*
+ * Domain y in [-0.1, 0.232], range ~[-8.1938e-22, 8.3815e-22]:
+ * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-71.2
+ */
+static const union IEEEl2bits
+u0u = LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L),
+u1u = LD80C(0x98280ee45e4ddd3d, -1,  5.94361239198682739769e-01L),
+u2u = LD80C(0xe330c8ead4130733, 0,  1.77492629495841234275e+00L),
+u3u = LD80C(0xd4a213f1a002ec52, 0,  1.66119622514818078064e+00L),
+u4u = LD80C(0xa5a9ca6f5bc62163, -1,  6.47122051417476492989e-01L),
+u5u = LD80C(0xc980e49cd5b019e6, -4,  9.83903751718671509455e-02L),
+u6u = LD80C(0xff636a8bdce7025b, -9,  3.89691687802305743450e-03L),
+v1u = LD80C(0xbd109c533a19fbf5, 1,  2.95413883330948556544e+00L),
+v2u = LD80C(0xd295cbf96f31f099, 1,  3.29039286955665403176e+00L),
+v3u = LD80C(0xdab8bcfee40496cb, 0,  1.70876276441416471410e+00L),
+v4u = LD80C(0xd2f2dc3638567e9f, -2,  4.12009126299534668571e-01L),
+v5u = LD80C(0xa07d9b0851070f41, -5,  3.91822868305682491442e-02L),
+v6u = LD80C(0xe3cd8318f7adb2c4, -11,  8.68998648222144351114e-04L);
+#define	u0	(u0u.e)
+#define	u1	(u1u.e)
+#define	u2	(u2u.e)
+#define	u3	(u3u.e)
+#define	u4	(u4u.e)
+#define	u5	(u5u.e)
+#define	u6	(u6u.e)
+#define	v1	(v1u.e)
+#define	v2	(v2u.e)
+#define	v3	(v3u.e)
+#define	v4	(v4u.e)
+#define	v5	(v5u.e)
+#define	v6	(v6u.e)
+/*
+ * Domain x in (2, 3], range ~[-3.3648e-22, 3.4416e-22]:
+ * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-72.3
+ * with y = x - 2.
+ */
+static const union IEEEl2bits
+s0u = LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L),
+s1u = LD80C(0xd3ff0dcc7fa91f94, -3,  2.07027640921219389860e-01L),
+s2u = LD80C(0xb2bb62782478ef31, -2,  3.49085881391362090549e-01L),
+s3u = LD80C(0xb49f7438c4611a74, -3,  1.76389518704213357954e-01L),
+s4u = LD80C(0x9a957008fa27ecf9, -5,  3.77401710862930008071e-02L),
+s5u = LD80C(0xda9b389a6ca7a7ac, -9,  3.33566791452943399399e-03L),
+s6u = LD80C(0xbc7a2263faf59c14, -14,  8.98728786745638844395e-05L),
+r1u = LD80C(0xbf5cff5b11477d4d, 0,  1.49502555796294337722e+00L),
+r2u = LD80C(0xd9aec89de08e3da6, -1,  8.50323236984473285866e-01L),
+r3u = LD80C(0xeab7ae5057c443f9, -3,  2.29216312078225806131e-01L),
+r4u = LD80C(0xf29707d9bd2b1e37, -6,  2.96130326586640089145e-02L),
+r5u = LD80C(0xd376c2f09736c5a3, -10,  1.61334161411590662495e-03L),
+r6u = LD80C(0xc985983d0cd34e3d, -16,  2.40232770710953450636e-05L),
+r7u = LD80C(0xe5c7a4f7fc2ef13d, -25, -5.34997929289167573510e-08L);
+#define	s0	(s0u.e)
+#define	s1	(s1u.e)
+#define	s2	(s2u.e)
+#define	s3	(s3u.e)
+#define	s4	(s4u.e)
+#define	s5	(s5u.e)
+#define	s6	(s6u.e)
+#define	r1	(r1u.e)
+#define	r2	(r2u.e)
+#define	r3	(r3u.e)
+#define	r4	(r4u.e)
+#define	r5	(r5u.e)
+#define	r6	(r6u.e)
+#define	r7	(r7u.e)
+/*
+ * Domain z in [8, 0x1p70], range ~[-3.0235e-22, 3.0563e-22]:
+ * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-71.7
+ */
+static const union IEEEl2bits
+w0u = LD80C(0xd67f1c864beb4a69, -2,  4.18938533204672741776e-01L),
+w1u = LD80C(0xaaaaaaaaaaaaaaa1, -4,  8.33333333333333332678e-02L),
+w2u = LD80C(0xb60b60b60b5491c9, -9, -2.77777777777760927870e-03L),
+w3u = LD80C(0xd00d00cf58aede4c, -11,  7.93650793490637233668e-04L),
+w4u = LD80C(0x9c09bf626783d4a5, -11, -5.95238023926039051268e-04L),
+w5u = LD80C(0xdca7cadc5baa517b, -11,  8.41733700408000822962e-04L),
+w6u = LD80C(0xfb060e361e1ffd07, -10, -1.91515849570245136604e-03L),
+w7u = LD80C(0xcbd5101bb58d1f2b, -8,  6.22046743903262649294e-03L),
+w8u = LD80C(0xad27a668d32c821b, -6, -2.11370706734662081843e-02L);
+#define	w0	(w0u.e)
+#define	w1	(w1u.e)
+#define	w2	(w2u.e)
+#define	w3	(w3u.e)
+#define	w4	(w4u.e)
+#define	w5	(w5u.e)
+#define	w6	(w6u.e)
+#define	w7	(w7u.e)
+#define	w8	(w8u.e)
+
+static long double
+sin_pil(long double x)
+{
+	volatile long double vz;
+	long double y,z;
+	uint64_t n;
+	uint16_t hx;
+
+	y = -x;
+
+	vz = y+0x1p63;
+	z = vz-0x1p63;
+	if (z == y)
+	    return zero;
+
+	vz = y+0x1p61;
+	EXTRACT_LDBL80_WORDS(hx,n,vz);
+	z = vz-0x1p61;
+	if (z > y) {
+	    z -= 0.25;			/* adjust to round down */
+	    n--;
+	}
+	n &= 7;				/* octant of y mod 2 */
+	y = y - z + n * 0.25;		/* y mod 2 */
+
+	switch (n) {
+	    case 0:   y =  __kernel_sinl(pi*y,zero,0); break;
+	    case 1:
+	    case 2:   y =  __kernel_cosl(pi*(0.5-y),zero); break;
+	    case 3:
+	    case 4:   y =  __kernel_sinl(pi*(one-y),zero,0); break;
+	    case 5:
+	    case 6:   y = -__kernel_cosl(pi*(y-1.5),zero); break;
+	    default:  y =  __kernel_sinl(pi*(y-2.0),zero,0); break;
+	    }
+	return -y;
+}
+
+long double
+lgammal_r(long double x, int *signgamp)
+{
+	long double nadj,p,p1,p2,p3,q,r,t,w,y,z;
+	uint64_t lx;
+	int i;
+	uint16_t hx,ix;
+
+	EXTRACT_LDBL80_WORDS(hx,lx,x);
+
+    /* purge +-Inf and NaNs */
+	*signgamp = 1;
+	ix = hx&0x7fff;
+	if(ix==0x7fff) return x*x;
+
+	ENTERI();
+
+    /* purge +-0 and tiny arguments */
+	*signgamp = 1-2*(hx>>15);
+	if(ix<0x3fff-67) {		/* |x|<2**-(p+3), return -log(|x|) */
+	    if((ix|lx)==0)
+		RETURNI(one/vzero);
+	    RETURNI(-logl(fabsl(x)));
+	}
+
+    /* purge negative integers and start evaluation for other x < 0 */
+	if(hx&0x8000) {
+	    *signgamp = 1;
+	    if(ix>=0x3fff+63) 		/* |x|>=2**(p-1), must be -integer */
+		RETURNI(one/vzero);
+	    t = sin_pil(x);
+	    if(t==zero) RETURNI(one/vzero); /* -integer */
+	    nadj = logl(pi/fabsl(t*x));
+	    if(t<zero) *signgamp = -1;
+	    x = -x;
+	}
+
+    /* purge 1 and 2 */
+	if((ix==0x3fff || ix==0x4000) && lx==0x8000000000000000ULL) r = 0;
+    /* for x < 2.0 */
+	else if(ix<0x4000) {
+    /*
+     * XXX Supposedly, one can use the following information to replace the
+     * XXX FP rational expressions.  A similar approach is appropriate
+     * XXX for ld128, but one (may need?) needs to consider llx, too.
+     *
+     * 8.9999961853027344e-01 3ffe e666600000000000
+     * 7.3159980773925781e-01 3ffe bb4a200000000000
+     * 2.3163998126983643e-01 3ffc ed33080000000000
+     * 1.7316312789916992e+00 3fff dda6180000000000
+     * 1.2316322326660156e+00 3fff 9da6200000000000
+     */
+	    if(x<8.9999961853027344e-01) {
+		r = -logl(x);
+		if(x>=7.3159980773925781e-01) {y = 1-x; i= 0;}
+		else if(x>=2.3163998126983643e-01) {y= x-(tc-1); i=1;}
+		else {y = x; i=2;}
+	    } else {
+		r = 0;
+		if(x>=1.7316312789916992e+00) {y=2-x;i=0;}
+		else if(x>=1.2316322326660156e+00) {y=x-tc;i=1;}
+		else {y=x-1;i=2;}
+	    }
+	    switch(i) {
+	      case 0:
+		z = y*y;
+		p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*(a10+z*a12)))));
+		p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*(a11+z*a13))))));
+		p  = y*p1+p2;
+		r  += p-y/2; break;
+	      case 1:
+		p = t0+y*t1+tt+y*y*(t2+y*(t3+y*(t4+y*(t5+y*(t6+y*(t7+y*(t8+
+		    y*(t9+y*(t10+y*(t11+y*(t12+y*(t13+y*(t14+y*(t15+y*(t16+
+		    y*(t17+y*t18))))))))))))))));
+		r += tf + p; break;
+	      case 2:
+		p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*(u5+y*u6))))));
+		p2 = 1+y*(v1+y*(v2+y*(v3+y*(v4+y*(v5+y*v6)))));
+		r += p1/p2-y/2;
+	    }
+	}
+    /* x < 8.0 */
+	else if(ix<0x4002) {
+	    i = x;
+	    y = x-i;
+	    p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+	    q = 1+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*(r6+y*r7))))));
+	    r = y/2+p/q;
+	    z = 1;	/* lgamma(1+s) = log(s) + lgamma(s) */
+	    switch(i) {
+	    case 7: z *= (y+6);		/* FALLTHRU */
+	    case 6: z *= (y+5);		/* FALLTHRU */
+	    case 5: z *= (y+4);		/* FALLTHRU */
+	    case 4: z *= (y+3);		/* FALLTHRU */
+	    case 3: z *= (y+2);		/* FALLTHRU */
+		    r += logl(z); break;
+	    }
+    /* 8.0 <= x < 2**(p+3) */
+	} else if (ix<0x3fff+67) {
+	    t = logl(x);
+	    z = one/x;
+	    y = z*z;
+	    w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*(w6+y*(w7+y*w8)))))));
+	    r = (x-half)*(t-one)+w;
+    /* 2**(p+3) <= x <= inf */
+	} else 
+	    r =  x*(logl(x)-1);
+	if(hx&0x8000) r = nadj - r;
+	RETURNI(r);
+}


Property changes on: trunk/lib/msun/ld80/e_lgammal_r.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/e_rem_pio2l.h
===================================================================
--- trunk/lib/msun/ld80/e_rem_pio2l.h	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/e_rem_pio2l.h	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /* From: @(#)e_rem_pio2.c 1.4 95/01/18 */
 /*
  * ====================================================
@@ -14,7 +15,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/e_rem_pio2l.h 223262 2011-06-18 13:56:33Z benl $");
 
 /* ld80 version of __ieee754_rem_pio2l(x,y)
  * 

Modified: trunk/lib/msun/ld80/invtrig.c
===================================================================
--- trunk/lib/msun/ld80/invtrig.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/invtrig.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 David Schultz <das at FreeBSD.ORG>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/invtrig.c 181074 2008-07-31 22:41:26Z das $");
 
 #include "invtrig.h"
 

Modified: trunk/lib/msun/ld80/invtrig.h
===================================================================
--- trunk/lib/msun/ld80/invtrig.h	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/invtrig.h	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 David Schultz <das at FreeBSD.ORG>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/msun/ld80/invtrig.h 181152 2008-08-02 03:56:22Z das $
  */
 
 #include <float.h>

Modified: trunk/lib/msun/ld80/k_cosl.c
===================================================================
--- trunk/lib/msun/ld80/k_cosl.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_cosl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /* From: @(#)k_cos.c 1.3 95/01/18 */
 /*
  * ====================================================
@@ -12,7 +13,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_cosl.c 176357 2008-02-17 07:32:14Z das $");
 
 /*
  * ld80 version of k_cos.c.  See ../src/k_cos.c for most comments.

Added: trunk/lib/msun/ld80/k_expl.h
===================================================================
--- trunk/lib/msun/ld80/k_expl.h	                        (rev 0)
+++ trunk/lib/msun/ld80/k_expl.h	2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,306 @@
+/* $MidnightBSD$ */
+/* from: FreeBSD: head/lib/msun/ld80/s_expl.c 251343 2013-06-03 19:51:32Z kargl */
+
+/*-
+ * Copyright (c) 2009-2013 Steven G. Kargl
+ * 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 unmodified, 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 ``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 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.
+ *
+ * Optimized by Bruce D. Evans.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_expl.h 284810 2015-06-25 13:01:10Z tijl $");
+
+/*
+ * See s_expl.c for more comments about __k_expl().
+ *
+ * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comments
+ * about the secondary kernels.
+ */
+
+#define	INTERVALS	128
+#define	LOG2_INTERVALS	7
+#define	BIAS	(LDBL_MAX_EXP - 1)
+
+static const double
+/*
+ * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication).  L1 must
+ * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest
+ * bits zero so that multiplication of it by n is exact.
+ */
+INV_L = 1.8466496523378731e+2,		/*  0x171547652b82fe.0p-45 */
+L1 =  5.4152123484527692e-3,		/*  0x162e42ff000000.0p-60 */
+L2 = -3.2819649005320973e-13,		/* -0x1718432a1b0e26.0p-94 */
+/*
+ * Domain [-0.002708, 0.002708], range ~[-5.7136e-24, 5.7110e-24]:
+ * |exp(x) - p(x)| < 2**-77.2
+ * (0.002708 is ln2/(2*INTERVALS) rounded up a little).
+ */
+A2 =  0.5,
+A3 =  1.6666666666666119e-1,		/*  0x15555555555490.0p-55 */
+A4 =  4.1666666666665887e-2,		/*  0x155555555554e5.0p-57 */
+A5 =  8.3333354987869413e-3,		/*  0x1111115b789919.0p-59 */
+A6 =  1.3888891738560272e-3;		/*  0x16c16c651633ae.0p-62 */
+
+/*
+ * 2^(i/INTERVALS) for i in [0,INTERVALS] is represented by two values where
+ * the first 53 bits of the significand are stored in hi and the next 53
+ * bits are in lo.  Tang's paper states that the trailing 6 bits of hi must
+ * be zero for his algorithm in both single and double precision, because
+ * the table is re-used in the implementation of expm1() where a floating
+ * point addition involving hi must be exact.  Here hi is double, so
+ * converting it to long double gives 11 trailing zero bits.
+ */
+static const struct {
+	double	hi;
+	double	lo;
+} tbl[INTERVALS] = {
+	0x1p+0, 0x0p+0,
+	/*
+	 * XXX hi is rounded down, and the formatting is not quite normal.
+	 * But I rather like both.  The 0x1.*p format is good for 4N+1
+	 * mantissa bits.  Rounding down makes the lo terms positive,
+	 * so that the columnar formatting can be simpler.
+	 */
+	0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54,
+	0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53,
+	0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53,
+	0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55,
+	0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53,
+	0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57,
+	0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54,
+	0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54,
+	0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54,
+	0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59,
+	0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53,
+	0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53,
+	0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53,
+	0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53,
+	0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55,
+	0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53,
+	0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53,
+	0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55,
+	0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53,
+	0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54,
+	0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53,
+	0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55,
+	0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55,
+	0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54,
+	0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55,
+	0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55,
+	0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53,
+	0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55,
+	0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53,
+	0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54,
+	0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56,
+	0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55,
+	0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55,
+	0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54,
+	0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53,
+	0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53,
+	0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53,
+	0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53,
+	0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53,
+	0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55,
+	0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53,
+	0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53,
+	0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53,
+	0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59,
+	0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54,
+	0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56,
+	0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54,
+	0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56,
+	0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54,
+	0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53,
+	0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53,
+	0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53,
+	0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53,
+	0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54,
+	0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55,
+	0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54,
+	0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60,
+	0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54,
+	0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53,
+	0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53,
+	0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53,
+	0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53,
+	0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57,
+	0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53,
+	0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53,
+	0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53,
+	0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53,
+	0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53,
+	0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53,
+	0x1.75feb564267c8p+0, 0x1.7edd354674916p-53,
+	0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54,
+	0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53,
+	0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54,
+	0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56,
+	0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53,
+	0x1.82589994cce12p+0, 0x1.159f115f56694p-53,
+	0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53,
+	0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53,
+	0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54,
+	0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54,
+	0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53,
+	0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55,
+	0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53,
+	0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53,
+	0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53,
+	0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53,
+	0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53,
+	0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56,
+	0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56,
+	0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53,
+	0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54,
+	0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53,
+	0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54,
+	0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54,
+	0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53,
+	0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54,
+	0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53,
+	0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53,
+	0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53,
+	0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53,
+	0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53,
+	0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55,
+	0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53,
+	0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55,
+	0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54,
+	0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54,
+	0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56,
+	0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56,
+	0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53,
+	0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53,
+	0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53,
+	0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55,
+	0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53,
+	0x1.da9e603db3285p+0, 0x1.c2300696db532p-54,
+	0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54,
+	0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53,
+	0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53,
+	0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55,
+	0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54,
+	0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53,
+	0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53,
+	0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54,
+	0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54,
+	0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54,
+	0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53,
+	0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55,
+	0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57
+};
+
+/*
+ * Kernel for expl(x).  x must be finite and not tiny or huge.
+ * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN).
+ * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2).
+ */
+static inline void
+__k_expl(long double x, long double *hip, long double *lop, int *kp)
+{
+	long double fn, q, r, r1, r2, t, z;
+	int n, n2;
+
+	/* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */
+	/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+	fn = x * INV_L + 0x1.8p63 - 0x1.8p63;
+	r = x - fn * L1 - fn * L2;	/* r = r1 + r2 done independently. */
+#if defined(HAVE_EFFICIENT_IRINTL)
+	n = irintl(fn);
+#elif defined(HAVE_EFFICIENT_IRINT)
+	n = irint(fn);
+#else
+	n = (int)fn;
+#endif
+	n2 = (unsigned)n % INTERVALS;
+	/* Depend on the sign bit being propagated: */
+	*kp = n >> LOG2_INTERVALS;
+	r1 = x - fn * L1;
+	r2 = fn * -L2;
+
+	/* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */
+	z = r * r;
+#if 0
+	q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6;
+#else
+	q = r2 + z * A2 + z * r * (A3 + r * A4 + z * (A5 + r * A6));
+#endif
+	t = (long double)tbl[n2].lo + tbl[n2].hi;
+	*hip = tbl[n2].hi;
+	*lop = tbl[n2].lo + t * (q + r1);
+}
+
+static inline void
+k_hexpl(long double x, long double *hip, long double *lop)
+{
+	float twopkm1;
+	int k;
+
+	__k_expl(x, hip, lop, &k);
+	SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23));
+	*hip *= twopkm1;
+	*lop *= twopkm1;
+}
+
+static inline long double
+hexpl(long double x)
+{
+	long double hi, lo, twopkm2;
+	int k;
+
+	twopkm2 = 1;
+	__k_expl(x, &hi, &lo, &k);
+	SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2);
+	return (lo + hi) * 2 * twopkm2;
+}
+
+#ifdef _COMPLEX_H
+/*
+ * See ../src/k_exp.c for details.
+ */
+static inline long double complex
+__ldexp_cexpl(long double complex z, int expt)
+{
+	long double exp_x, hi, lo;
+	long double x, y, scale1, scale2;
+	int half_expt, k;
+
+	x = creall(z);
+	y = cimagl(z);
+	__k_expl(x, &hi, &lo, &k);
+
+	exp_x = (lo + hi) * 0x1p16382;
+	expt += k - 16382;
+
+	scale1 = 1;
+	half_expt = expt / 2;
+	SET_LDBL_EXPSIGN(scale1, BIAS + half_expt);
+	scale2 = 1;
+	SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt);
+
+	return (CMPLXL(cos(y) * exp_x * scale1 * scale2,
+	    sinl(y) * exp_x * scale1 * scale2));
+}
+#endif /* _COMPLEX_H */


Property changes on: trunk/lib/msun/ld80/k_expl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/k_sinl.c
===================================================================
--- trunk/lib/msun/ld80/k_sinl.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_sinl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /* From: @(#)k_sin.c 1.3 95/01/18 */
 /*
  * ====================================================
@@ -12,7 +13,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_sinl.c 176357 2008-02-17 07:32:14Z das $");
 
 /*
  * ld80 version of k_sin.c.  See ../src/k_sin.c for most comments.

Modified: trunk/lib/msun/ld80/k_tanl.c
===================================================================
--- trunk/lib/msun/ld80/k_tanl.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_tanl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /* From: @(#)k_tan.c 1.5 04/04/22 SMI */
 
 /*
@@ -12,7 +13,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_tanl.c 176387 2008-02-18 15:39:52Z bde $");
 
 /*
  * ld80 version of k_tan.c.  See ../src/k_tan.c for most comments.

Added: trunk/lib/msun/ld80/s_erfl.c
===================================================================
--- trunk/lib/msun/ld80/s_erfl.c	                        (rev 0)
+++ trunk/lib/msun/ld80/s_erfl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,338 @@
+/* $MidnightBSD$ */
+/* @(#)s_erf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_erfl.c 271779 2014-09-18 15:10:22Z tijl $");
+
+/*
+ * See s_erf.c for complete comments.
+ *
+ * Converted to long double by Steven G. Kargl.
+ */
+#include <float.h>
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+
+/* XXX Prevent compilers from erroneously constant folding: */
+static const volatile long double tiny = 0x1p-10000L;
+
+static const double
+half= 0.5,
+one = 1,
+two = 2;
+/*
+ * In the domain [0, 2**-34], only the first term in the power series
+ * expansion of erf(x) is used.  The magnitude of the first neglected
+ * terms is less than 2**-102.
+ */
+static const union IEEEl2bits
+efxu  = LD80C(0x8375d410a6db446c, -3,  1.28379167095512573902e-1L),
+efx8u = LD80C(0x8375d410a6db446c,  0,  1.02703333676410059122e+0L),
+/*
+ * Domain [0, 0.84375], range ~[-1.423e-22, 1.423e-22]:
+ * |(erf(x) - x)/x - pp(x)/qq(x)| < 2**-72.573
+ */
+pp0u  = LD80C(0x8375d410a6db446c, -3,   1.28379167095512573902e-1L),
+pp1u  = LD80C(0xa46c7d09ec3d0cec, -2,  -3.21140201054840180596e-1L),
+pp2u  = LD80C(0x9b31e66325576f86, -5,  -3.78893851760347812082e-2L),
+pp3u  = LD80C(0x804ac72c9a0b97dd, -7,  -7.83032847030604679616e-3L),
+pp4u  = LD80C(0x9f42bcbc3d5a601d, -12, -3.03765663857082048459e-4L),
+pp5u  = LD80C(0x9ec4ad6193470693, -16, -1.89266527398167917502e-5L),
+qq1u  = LD80C(0xdb4b8eb713188d6b, -2,   4.28310832832310510579e-1L),
+qq2u  = LD80C(0xa5750835b2459bd1, -4,   8.07896272074540216658e-2L),
+qq3u  = LD80C(0x8b85d6bd6a90b51c, -7,   8.51579638189385354266e-3L),
+qq4u  = LD80C(0x87332f82cff4ff96, -11,  5.15746855583604912827e-4L),
+qq5u  = LD80C(0x83466cb6bf9dca00, -16,  1.56492109706256700009e-5L),
+qq6u  = LD80C(0xf5bf98c2f996bf63, -24,  1.14435527803073879724e-7L);
+#define	efx	(efxu.e)
+#define	efx8	(efx8u.e)
+#define	pp0	(pp0u.e)
+#define	pp1	(pp1u.e)
+#define	pp2	(pp2u.e)
+#define	pp3	(pp3u.e)
+#define	pp4	(pp4u.e)
+#define	pp5	(pp5u.e)
+#define	qq1	(qq1u.e)
+#define	qq2	(qq2u.e)
+#define	qq3	(qq3u.e)
+#define	qq4	(qq4u.e)
+#define	qq5	(qq5u.e)
+#define	qq6	(qq6u.e)
+static const union IEEEl2bits
+erxu  = LD80C(0xd7bb3d0000000000, -1,  8.42700779438018798828e-1L),
+/*
+ * Domain [0.84375, 1.25], range ~[-8.132e-22, 8.113e-22]:
+ * |(erf(x) - erx) - pa(x)/qa(x)| < 2**-71.762
+ */
+pa0u  = LD80C(0xe8211158da02c692, -27,  1.35116960705131296711e-8L),
+pa1u  = LD80C(0xd488f89f36988618, -2,   4.15107507167065612570e-1L),
+pa2u  = LD80C(0xece74f8c63fa3942, -4,  -1.15675565215949226989e-1L),
+pa3u  = LD80C(0xc8d31e020727c006, -4,   9.80589241379624665791e-2L),
+pa4u  = LD80C(0x985d5d5fafb0551f, -5,   3.71984145558422368847e-2L),
+pa5u  = LD80C(0xa5b6c4854d2f5452, -8,  -5.05718799340957673661e-3L),
+pa6u  = LD80C(0x85c8d58fe3993a47, -8,   4.08277919612202243721e-3L),
+pa7u  = LD80C(0xddbfbc23677b35cf, -13,  2.11476292145347530794e-4L),
+qa1u  = LD80C(0xb8a977896f5eff3f, -1,   7.21335860303380361298e-1L),
+qa2u  = LD80C(0x9fcd662c3d4eac86, -1,   6.24227891731886593333e-1L),
+qa3u  = LD80C(0x9d0b618eac67ba07, -2,   3.06727455774491855801e-1L),
+qa4u  = LD80C(0x881a4293f6d6c92d, -3,   1.32912674218195890535e-1L),
+qa5u  = LD80C(0xbab144f07dea45bf, -5,   4.55792134233613027584e-2L),
+qa6u  = LD80C(0xa6c34ba438bdc900, -7,   1.01783980070527682680e-2L),
+qa7u  = LD80C(0x8fa866dc20717a91, -9,   2.19204436518951438183e-3L);
+#define erx	(erxu.e)
+#define pa0	(pa0u.e)
+#define pa1	(pa1u.e)
+#define pa2	(pa2u.e)
+#define pa3	(pa3u.e)
+#define pa4	(pa4u.e)
+#define pa5	(pa5u.e)
+#define pa6	(pa6u.e)
+#define pa7	(pa7u.e)
+#define qa1	(qa1u.e)
+#define qa2	(qa2u.e)
+#define qa3	(qa3u.e)
+#define qa4	(qa4u.e)
+#define qa5	(qa5u.e)
+#define qa6	(qa6u.e)
+#define qa7	(qa7u.e)
+static const union IEEEl2bits
+/*
+ * Domain [1.25,2.85715], range ~[-2.334e-22,2.334e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - ra(x)/sa(x)| < 2**-71.860
+ */
+ra0u  = LD80C(0xa1a091e0fb4f335a, -7, -9.86494298915814308249e-3L),
+ra1u  = LD80C(0xc2b0d045ae37df6b, -1, -7.60510460864878271275e-1L),
+ra2u  = LD80C(0xf2cec3ee7da636c5, 3,  -1.51754798236892278250e+1L),
+ra3u  = LD80C(0x813cc205395adc7d, 7,  -1.29237335516455333420e+2L),
+ra4u  = LD80C(0x8737c8b7b4062c2f, 9,  -5.40871625829510494776e+2L),
+ra5u  = LD80C(0x8ffe5383c08d4943, 10, -1.15194769466026108551e+3L),
+ra6u  = LD80C(0x983573e64d5015a9, 10, -1.21767039790249025544e+3L),
+ra7u  = LD80C(0x92a794e763a6d4db, 9,  -5.86618463370624636688e+2L),
+ra8u  = LD80C(0xd5ad1fae77c3d9a3, 6,  -1.06838132335777049840e+2L),
+ra9u  = LD80C(0x934c1a247807bb9c, 2,  -4.60303980944467334806e+0L),
+sa1u  = LD80C(0xd342f90012bb1189, 4,   2.64077014928547064865e+1L),
+sa2u  = LD80C(0x839be13d9d5da883, 8,   2.63217811300123973067e+2L),
+sa3u  = LD80C(0x9f8cba6d1ae1b24b, 10,  1.27639775710344617587e+3L),
+sa4u  = LD80C(0xcaa83f403713e33e, 11,  3.24251544209971162003e+3L),
+sa5u  = LD80C(0x8796aff2f3c47968, 12,  4.33883591261332837874e+3L),
+sa6u  = LD80C(0xb6ef97f9c753157b, 11,  2.92697460344182158454e+3L),
+sa7u  = LD80C(0xe02aee5f83773d1c, 9,   8.96670799139389559818e+2L),
+sa8u  = LD80C(0xc82b83855b88e07e, 6,   1.00084987800048510018e+2L),
+sa9u  = LD80C(0x92f030aefadf28ad, 1,   2.29591004455459083843e+0L);
+#define ra0	(ra0u.e)
+#define ra1	(ra1u.e)
+#define ra2	(ra2u.e)
+#define ra3	(ra3u.e)
+#define ra4	(ra4u.e)
+#define ra5	(ra5u.e)
+#define ra6	(ra6u.e)
+#define ra7	(ra7u.e)
+#define ra8	(ra8u.e)
+#define ra9	(ra9u.e)
+#define sa1	(sa1u.e)
+#define sa2	(sa2u.e)
+#define sa3	(sa3u.e)
+#define sa4	(sa4u.e)
+#define sa5	(sa5u.e)
+#define sa6	(sa6u.e)
+#define sa7	(sa7u.e)
+#define sa8	(sa8u.e)
+#define sa9	(sa9u.e)
+/*
+ * Domain [2.85715,7], range ~[-8.323e-22,8.390e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - rb(x)/sb(x)| < 2**-70.326
+ */
+static const union IEEEl2bits
+rb0u = LD80C(0xa1a091cf43abcd26, -7, -9.86494292470284646962e-3L),
+rb1u = LD80C(0xd19d2df1cbb8da0a, -1, -8.18804618389296662837e-1L),
+rb2u = LD80C(0x9a4dd1383e5daf5b, 4,  -1.92879967111618594779e+1L),
+rb3u = LD80C(0xbff0ae9fc0751de6, 7,  -1.91940164551245394969e+2L),
+rb4u = LD80C(0xdde08465310b472b, 9,  -8.87508080766577324539e+2L),
+rb5u = LD80C(0xe796e1d38c8c70a9, 10, -1.85271506669474503781e+3L),
+rb6u = LD80C(0xbaf655a76e0ab3b5, 10, -1.49569795581333675349e+3L),
+rb7u = LD80C(0x95d21e3e75503c21, 8,  -2.99641547972948019157e+2L),
+sb1u = LD80C(0x814487ed823c8cbd, 5,   3.23169247732868256569e+1L),
+sb2u = LD80C(0xbe4bfbb1301304be, 8,   3.80593618534539961773e+2L),
+sb3u = LD80C(0x809c4ade46b927c7, 11,  2.05776827838541292848e+3L),
+sb4u = LD80C(0xa55284359f3395a8, 12,  5.29031455540062116327e+3L),
+sb5u = LD80C(0xbcfa72da9b820874, 12,  6.04730608102312640462e+3L),
+sb6u = LD80C(0x9d09a35988934631, 11,  2.51260238030767176221e+3L),
+sb7u = LD80C(0xd675bbe542c159fa, 7,   2.14459898308561015684e+2L);
+#define rb0	(rb0u.e)
+#define rb1	(rb1u.e)
+#define rb2	(rb2u.e)
+#define rb3	(rb3u.e)
+#define rb4	(rb4u.e)
+#define rb5	(rb5u.e)
+#define rb6	(rb6u.e)
+#define rb7	(rb7u.e)
+#define sb1	(sb1u.e)
+#define sb2	(sb2u.e)
+#define sb3	(sb3u.e)
+#define sb4	(sb4u.e)
+#define sb5	(sb5u.e)
+#define sb6	(sb6u.e)
+#define sb7	(sb7u.e)
+/*
+ * Domain [7,108], range ~[-4.422e-22,4.422e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - rc(x)/sc(x)| < 2**-70.938
+ */
+static const union IEEEl2bits
+/* err = -4.422092275318925082e-22 -70.937689 */
+rc0u = LD80C(0xa1a091cf437a17ad, -7, -9.86494292470008707260e-3L),
+rc1u = LD80C(0xbe79c5a978122b00, -1, -7.44045595049165939261e-1L),
+rc2u = LD80C(0xdb26f9bbe31a2794, 3,  -1.36970155085888424425e+1L),
+rc3u = LD80C(0xb5f69a38f5747ac8, 6,  -9.09816453742625888546e+1L),
+rc4u = LD80C(0xd79676d970d0a21a, 7,  -2.15587750997584074147e+2L),
+rc5u = LD80C(0xfe528153c45ec97c, 6,  -1.27161142938347796666e+2L),
+sc1u = LD80C(0xc5e8cd46d5604a96, 4,   2.47386727842204312937e+1L),
+sc2u = LD80C(0xc5f0f5a5484520eb, 7,   1.97941248254913378865e+2L),
+sc3u = LD80C(0x964e3c7b34db9170, 9,   6.01222441484087787522e+2L),
+sc4u = LD80C(0x99be1b89faa0596a, 9,   6.14970430845978077827e+2L),
+sc5u = LD80C(0xf80dfcbf37ffc5ea, 6,   1.24027318931184605891e+2L);
+#define rc0	(rc0u.e)
+#define rc1	(rc1u.e)
+#define rc2	(rc2u.e)
+#define rc3	(rc3u.e)
+#define rc4	(rc4u.e)
+#define rc5	(rc5u.e)
+#define sc1	(sc1u.e)
+#define sc2	(sc2u.e)
+#define sc3	(sc3u.e)
+#define sc4	(sc4u.e)
+#define sc5	(sc5u.e)
+
+long double
+erfl(long double x)
+{
+	long double ax,R,S,P,Q,s,y,z,r;
+	uint64_t lx;
+	int32_t i;
+	uint16_t hx;
+
+	EXTRACT_LDBL80_WORDS(hx, lx, x);
+
+	if((hx & 0x7fff) == 0x7fff) {	/* erfl(nan)=nan */
+		i = (hx>>15)<<1;
+		return (1-i)+one/x;	/* erfl(+-inf)=+-1 */
+	}
+
+	ENTERI();
+
+	ax = fabsl(x);
+	if(ax < 0.84375) {
+	    if(ax < 0x1p-34L) {
+	        if(ax < 0x1p-16373L)	
+		    RETURNI((8*x+efx8*x)/8);	/* avoid spurious underflow */
+		RETURNI(x + efx*x);
+	    }
+	    z = x*x;
+	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5))));
+	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6)))));
+	    y = r/s;
+	    RETURNI(x + x*y);
+	}
+	if(ax < 1.25) {
+	    s = ax-one;
+	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))));
+	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))));
+	    if(x>=0) RETURNI(erx + P/Q); else RETURNI(-erx - P/Q);
+	}
+	if(ax >= 7) {			/* inf>|x|>= 7 */
+	    if(x>=0) RETURNI(one-tiny); else RETURNI(tiny-one);
+	}
+	s = one/(ax*ax);
+	if(ax < 2.85715) {	/* |x| < 2.85715 */
+	    R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+
+		s*(ra8+s*ra9))))))));
+	    S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+
+		s*(sa8+s*sa9))))))));
+	} else {	/* |x| >= 2.85715 */
+	    R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7))))));
+	    S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))));
+	}
+	z=(float)ax;
+	r=expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S);
+	if(x>=0) RETURNI(one-r/ax); else RETURNI(r/ax-one);
+}
+
+long double
+erfcl(long double x)
+{
+	long double ax,R,S,P,Q,s,y,z,r;
+	uint64_t lx;
+	uint16_t hx;
+
+	EXTRACT_LDBL80_WORDS(hx, lx, x);
+
+	if((hx & 0x7fff) == 0x7fff) {	/* erfcl(nan)=nan */
+					/* erfcl(+-inf)=0,2 */
+	    return ((hx>>15)<<1)+one/x;
+	}
+
+	ENTERI();
+
+	ax = fabsl(x);
+	if(ax < 0.84375L) {
+	    if(ax < 0x1p-34L)
+		RETURNI(one-x);
+	    z = x*x;
+	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5))));
+	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6)))));
+	    y = r/s;
+	    if(ax < 0.25L) {  	/* x<1/4 */
+		RETURNI(one-(x+x*y));
+	    } else {
+		r = x*y;
+		r += (x-half);
+	       RETURNI(half - r);
+	    }
+	}
+	if(ax < 1.25L) {
+	    s = ax-one;
+	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))));
+	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))));
+	    if(x>=0) {
+	        z  = one-erx; RETURNI(z - P/Q);
+	    } else {
+		z = (erx+P/Q); RETURNI(one+z);
+	    }
+	}
+
+	if(ax < 108) {			/* |x| < 108 */
+ 	    s = one/(ax*ax);
+	    if(ax < 2.85715) {		/* |x| < 2.85715 */
+		R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+
+		    s*(ra8+s*ra9))))))));
+		S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+
+		    s*(sa8+s*sa9))))))));
+	    } else if(ax < 7) {		/* | |x| < 7 */
+		R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7))))));
+		S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))));
+	    } else {
+		if(x < -7) RETURNI(two-tiny);/* x < -7 */
+		R=rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*rc5))));
+		S=one+s*(sc1+s*(sc2+s*(sc3+s*(sc4+s*sc5))));
+	    }
+	    z = (float)ax;
+	    r = expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S);
+	    if(x>0) RETURNI(r/ax); else RETURNI(two-r/ax);
+	} else {
+	    if(x>0) RETURNI(tiny*tiny); else RETURNI(two-tiny);
+	}
+}


Property changes on: trunk/lib/msun/ld80/s_erfl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/s_exp2l.c
===================================================================
--- trunk/lib/msun/ld80/s_exp2l.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/s_exp2l.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2008 David Schultz <das at FreeBSD.ORG>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_exp2l.c 251046 2013-05-27 22:45:05Z kargl $");
 
 #include <float.h>
 #include <stdint.h>
@@ -36,28 +37,31 @@
 
 #include "fpmath.h"
 #include "math.h"
+#include "math_private.h"
 
 #define	TBLBITS	7
 #define	TBLSIZE	(1 << TBLBITS)
 
 #define	BIAS	(LDBL_MAX_EXP - 1)
-#define	EXPMASK	(BIAS + LDBL_MAX_EXP)
 
-static const long double huge = 0x1p10000L;
-#if 0 /* XXX Prevent gcc from erroneously constant folding this. */
-static const long double twom10000 = 0x1p-10000L;
-#else
-static volatile long double twom10000 = 0x1p-10000L;
-#endif
+static volatile long double
+    huge = 0x1p10000L,
+    twom10000 = 0x1p-10000L;
 
+static const union IEEEl2bits
+P1 = LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309429e-1L);
+
 static const double
-    redux     = 0x1.8p63 / TBLSIZE,
-    P1        = 0x1.62e42fefa39efp-1,
-    P2        = 0x1.ebfbdff82c58fp-3,
-    P3        = 0x1.c6b08d7049fap-5,
-    P4        = 0x1.3b2ab6fba4da5p-7,
-    P5        = 0x1.5d8804780a736p-10,
-    P6        = 0x1.430918835e33dp-13;
+redux = 0x1.8p63 / TBLSIZE,
+/*
+ * Domain [-0.00390625, 0.00390625], range ~[-1.7079e-23, 1.7079e-23]
+ * |exp(x) - p(x)| < 2**-75.6
+ */
+P2 = 2.4022650695910072e-1,		/*  0x1ebfbdff82c58f.0p-55 */
+P3 = 5.5504108664816879e-2,		/*  0x1c6b08d7049e1a.0p-57 */
+P4 = 9.6181291055695180e-3,		/*  0x13b2ab6fa8321a.0p-59 */
+P5 = 1.3333563089183052e-3,		/*  0x15d8806f67f251.0p-62 */
+P6 = 1.5413361552277414e-4;		/*  0x1433ddacff3441.0p-65 */
 
 static const double tbl[TBLSIZE * 2] = {
 	0x1.6a09e667f3bcdp-1,	-0x1.bdd3413b2648p-55,
@@ -190,8 +194,8 @@
 	0x1.68155d44ca973p+0,	 0x1.038ae44f74p-57,
 };
 
-/*
- * exp2l(x): compute the base 2 exponential of x
+/**
+ * Compute the base 2 exponential of x for Intel 80-bit format.
  *
  * Accuracy: Peak error < 0.511 ulp.
  *
@@ -207,7 +211,7 @@
  *     with |z| <= 2**-(TBLBITS+1).
  *
  *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
- *   degree-6 minimax polynomial with maximum error under 2**-69.
+ *   degree-6 minimax polynomial with maximum error under 2**-75.6.
  *   The table entries each have 104 bits of accuracy, encoded as
  *   a pair of double precision values.
  */
@@ -222,30 +226,22 @@
 	/* Filter out exceptional cases. */
 	u.e = x;
 	hx = u.xbits.expsign;
-	ix = hx & EXPMASK;
+	ix = hx & 0x7fff;
 	if (ix >= BIAS + 14) {		/* |x| >= 16384 or x is NaN */
 		if (ix == BIAS + LDBL_MAX_EXP) {
-			if (u.xbits.man != 1ULL << 63 || (hx & 0x8000) == 0)
-				return (x + x);	/* x is +Inf or NaN */
-			else
-				return (0.0);	/* x is -Inf */
+			if (hx & 0x8000 && u.xbits.man == 1ULL << 63)
+				return (0.0L);	/* x is -Inf */
+			return (x + x); /* x is +Inf, NaN or unsupported */
 		}
 		if (x >= 16384)
 			return (huge * huge);	/* overflow */
 		if (x <= -16446)
 			return (twom10000 * twom10000);	/* underflow */
-	} else if (ix <= BIAS - 66) {		/* |x| < 0x1p-66 */
-		return (1.0 + x);
+	} else if (ix <= BIAS - 66) {	/* |x| < 0x1p-65 (includes pseudos) */
+		return (1.0L + x);	/* 1 with inexact */
 	}
 
-#ifdef __i386__
-	/*
-	 * The default precision on i386 is 53 bits, so long doubles are
-	 * broken. Call exp2() to get an accurate (double precision) result.
-	 */
-	if (fpgetprec() != FP_PE)
-		return (exp2(x));
-#endif
+	ENTERI();
 
 	/*
 	 * Reduce x, computing z, i0, and k. The low bits of x + redux
@@ -269,10 +265,10 @@
 	z = x - u.e;
 	v.xbits.man = 1ULL << 63;
 	if (k >= LDBL_MIN_EXP) {
-		v.xbits.expsign = LDBL_MAX_EXP - 1 + k;
+		v.xbits.expsign = BIAS + k;
 		twopk = v.e;
 	} else {
-		v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000;
+		v.xbits.expsign = BIAS + k + 10000;
 		twopkp10000 = v.e;
 	}
 
@@ -279,16 +275,15 @@
 	/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
 	long double t_hi = tbl[i0];
 	long double t_lo = tbl[i0 + 1];
-	/* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */
-	r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4
+	r = t_lo + (t_hi + t_lo) * z * (P1.e + z * (P2 + z * (P3 + z * (P4
 	    + z * (P5 + z * P6))))) + t_hi;
 
 	/* Scale by 2**k. */
 	if (k >= LDBL_MIN_EXP) {
 		if (k == LDBL_MAX_EXP)
-			return (r * 2.0 * 0x1p16383L);
-		return (r * twopk);
+			RETURNI(r * 2.0 * 0x1p16383L);
+		RETURNI(r * twopk);
 	} else {
-		return (r * twopkp10000 * twom10000);
+		RETURNI(r * twopkp10000 * twom10000);
 	}
 }

Added: trunk/lib/msun/ld80/s_expl.c
===================================================================
--- trunk/lib/msun/ld80/s_expl.c	                        (rev 0)
+++ trunk/lib/msun/ld80/s_expl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,285 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009-2013 Steven G. Kargl
+ * 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 unmodified, 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 ``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 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.
+ *
+ * Optimized by Bruce D. Evans.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_expl.c 271779 2014-09-18 15:10:22Z tijl $");
+
+/**
+ * Compute the exponential of x for Intel 80-bit format.  This is based on:
+ *
+ *   PTP Tang, "Table-driven implementation of the exponential function
+ *   in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 15,
+ *   144-157 (1989).
+ *
+ * where the 32 table entries have been expanded to INTERVALS (see below).
+ */
+
+#include <float.h>
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+#include "k_expl.h"
+
+/* XXX Prevent compilers from erroneously constant folding these: */
+static const volatile long double
+huge = 0x1p10000L,
+tiny = 0x1p-10000L;
+
+static const long double
+twom10000 = 0x1p-10000L;
+
+static const union IEEEl2bits
+/* log(2**16384 - 0.5) rounded towards zero: */
+/* log(2**16384 - 0.5 + 1) rounded towards zero for expm1l() is the same: */
+o_thresholdu = LD80C(0xb17217f7d1cf79ab, 13,  11356.5234062941439488L),
+#define o_threshold	 (o_thresholdu.e)
+/* log(2**(-16381-64-1)) rounded towards zero: */
+u_thresholdu = LD80C(0xb21dfe7f09e2baa9, 13, -11399.4985314888605581L);
+#define u_threshold	 (u_thresholdu.e)
+
+long double
+expl(long double x)
+{
+	union IEEEl2bits u;
+	long double hi, lo, t, twopk;
+	int k;
+	uint16_t hx, ix;
+
+	DOPRINT_START(&x);
+
+	/* Filter out exceptional cases. */
+	u.e = x;
+	hx = u.xbits.expsign;
+	ix = hx & 0x7fff;
+	if (ix >= BIAS + 13) {		/* |x| >= 8192 or x is NaN */
+		if (ix == BIAS + LDBL_MAX_EXP) {
+			if (hx & 0x8000)  /* x is -Inf, -NaN or unsupported */
+				RETURNP(-1 / x);
+			RETURNP(x + x);	/* x is +Inf, +NaN or unsupported */
+		}
+		if (x > o_threshold)
+			RETURNP(huge * huge);
+		if (x < u_threshold)
+			RETURNP(tiny * tiny);
+	} else if (ix < BIAS - 75) {	/* |x| < 0x1p-75 (includes pseudos) */
+		RETURN2P(1, x);		/* 1 with inexact iff x != 0 */
+	}
+
+	ENTERI();
+
+	twopk = 1;
+	__k_expl(x, &hi, &lo, &k);
+	t = SUM2P(hi, lo);
+
+	/* Scale by 2**k. */
+	if (k >= LDBL_MIN_EXP) {
+		if (k == LDBL_MAX_EXP)
+			RETURNI(t * 2 * 0x1p16383L);
+		SET_LDBL_EXPSIGN(twopk, BIAS + k);
+		RETURNI(t * twopk);
+	} else {
+		SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000);
+		RETURNI(t * twopk * twom10000);
+	}
+}
+
+/**
+ * Compute expm1l(x) for Intel 80-bit format.  This is based on:
+ *
+ *   PTP Tang, "Table-driven implementation of the Expm1 function
+ *   in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 18,
+ *   211-222 (1992).
+ */
+
+/*
+ * Our T1 and T2 are chosen to be approximately the points where method
+ * A and method B have the same accuracy.  Tang's T1 and T2 are the
+ * points where method A's accuracy changes by a full bit.  For Tang,
+ * this drop in accuracy makes method A immediately less accurate than
+ * method B, but our larger INTERVALS makes method A 2 bits more
+ * accurate so it remains the most accurate method significantly
+ * closer to the origin despite losing the full bit in our extended
+ * range for it.
+ */
+static const double
+T1 = -0.1659,				/* ~-30.625/128 * log(2) */
+T2 =  0.1659;				/* ~30.625/128 * log(2) */
+
+/*
+ * Domain [-0.1659, 0.1659], range ~[-2.6155e-22, 2.5507e-23]:
+ * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-71.6
+ *
+ * XXX the coeffs aren't very carefully rounded, and I get 2.8 more bits,
+ * but unlike for ld128 we can't drop any terms.
+ */
+static const union IEEEl2bits
+B3 = LD80C(0xaaaaaaaaaaaaaaab, -3,  1.66666666666666666671e-1L),
+B4 = LD80C(0xaaaaaaaaaaaaaaac, -5,  4.16666666666666666712e-2L);
+
+static const double
+B5  =  8.3333333333333245e-3,		/*  0x1.111111111110cp-7 */
+B6  =  1.3888888888888861e-3,		/*  0x1.6c16c16c16c0ap-10 */
+B7  =  1.9841269841532042e-4,		/*  0x1.a01a01a0319f9p-13 */
+B8  =  2.4801587302069236e-5,		/*  0x1.a01a01a03cbbcp-16 */
+B9  =  2.7557316558468562e-6,		/*  0x1.71de37fd33d67p-19 */
+B10 =  2.7557315829785151e-7,		/*  0x1.27e4f91418144p-22 */
+B11 =  2.5063168199779829e-8,		/*  0x1.ae94fabdc6b27p-26 */
+B12 =  2.0887164654459567e-9;		/*  0x1.1f122d6413fe1p-29 */
+
+long double
+expm1l(long double x)
+{
+	union IEEEl2bits u, v;
+	long double fn, hx2_hi, hx2_lo, q, r, r1, r2, t, twomk, twopk, x_hi;
+	long double x_lo, x2, z;
+	long double x4;
+	int k, n, n2;
+	uint16_t hx, ix;
+
+	DOPRINT_START(&x);
+
+	/* Filter out exceptional cases. */
+	u.e = x;
+	hx = u.xbits.expsign;
+	ix = hx & 0x7fff;
+	if (ix >= BIAS + 6) {		/* |x| >= 64 or x is NaN */
+		if (ix == BIAS + LDBL_MAX_EXP) {
+			if (hx & 0x8000)  /* x is -Inf, -NaN or unsupported */
+				RETURNP(-1 / x - 1);
+			RETURNP(x + x);	/* x is +Inf, +NaN or unsupported */
+		}
+		if (x > o_threshold)
+			RETURNP(huge * huge);
+		/*
+		 * expm1l() never underflows, but it must avoid
+		 * unrepresentable large negative exponents.  We used a
+		 * much smaller threshold for large |x| above than in
+		 * expl() so as to handle not so large negative exponents
+		 * in the same way as large ones here.
+		 */
+		if (hx & 0x8000)	/* x <= -64 */
+			RETURN2P(tiny, -1);	/* good for x < -65ln2 - eps */
+	}
+
+	ENTERI();
+
+	if (T1 < x && x < T2) {
+		if (ix < BIAS - 74) {	/* |x| < 0x1p-74 (includes pseudos) */
+			/* x (rounded) with inexact if x != 0: */
+			RETURNPI(x == 0 ? x :
+			    (0x1p100 * x + fabsl(x)) * 0x1p-100);
+		}
+
+		x2 = x * x;
+		x4 = x2 * x2;
+		q = x4 * (x2 * (x4 *
+		    /*
+		     * XXX the number of terms is no longer good for
+		     * pairwise grouping of all except B3, and the
+		     * grouping is no longer from highest down.
+		     */
+		    (x2 *            B12  + (x * B11 + B10)) +
+		    (x2 * (x * B9 +  B8) +  (x * B7 +  B6))) +
+			  (x * B5 +  B4.e)) + x2 * x * B3.e;
+
+		x_hi = (float)x;
+		x_lo = x - x_hi;
+		hx2_hi = x_hi * x_hi / 2;
+		hx2_lo = x_lo * (x + x_hi) / 2;
+		if (ix >= BIAS - 7)
+			RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q);
+		else
+			RETURN2PI(x, hx2_lo + q + hx2_hi);
+	}
+
+	/* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */
+	/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+	fn = x * INV_L + 0x1.8p63 - 0x1.8p63;
+#if defined(HAVE_EFFICIENT_IRINTL)
+	n = irintl(fn);
+#elif defined(HAVE_EFFICIENT_IRINT)
+	n = irint(fn);
+#else
+	n = (int)fn;
+#endif
+	n2 = (unsigned)n % INTERVALS;
+	k = n >> LOG2_INTERVALS;
+	r1 = x - fn * L1;
+	r2 = fn * -L2;
+	r = r1 + r2;
+
+	/* Prepare scale factor. */
+	v.e = 1;
+	v.xbits.expsign = BIAS + k;
+	twopk = v.e;
+
+	/*
+	 * Evaluate lower terms of
+	 * expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2).
+	 */
+	z = r * r;
+	q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6;
+
+	t = (long double)tbl[n2].lo + tbl[n2].hi;
+
+	if (k == 0) {
+		t = SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q +
+		    tbl[n2].hi * r1);
+		RETURNI(t);
+	}
+	if (k == -1) {
+		t = SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q +
+		    tbl[n2].hi * r1);
+		RETURNI(t / 2);
+	}
+	if (k < -7) {
+		t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1));
+		RETURNI(t * twopk - 1);
+	}
+	if (k > 2 * LDBL_MANT_DIG - 1) {
+		t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1));
+		if (k == LDBL_MAX_EXP)
+			RETURNI(t * 2 * 0x1p16383L - 1);
+		RETURNI(t * twopk - 1);
+	}
+
+	v.xbits.expsign = BIAS - k;
+	twomk = v.e;
+
+	if (k > LDBL_MANT_DIG - 1)
+		t = SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1));
+	else
+		t = SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1));
+	RETURNI(t * twopk);
+}


Property changes on: trunk/lib/msun/ld80/s_expl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/lib/msun/ld80/s_logl.c
===================================================================
--- trunk/lib/msun/ld80/s_logl.c	                        (rev 0)
+++ trunk/lib/msun/ld80/s_logl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,718 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2007-2013 Bruce D. Evans
+ * 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 unmodified, 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 ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_logl.c 251292 2013-06-03 09:14:31Z das $");
+
+/**
+ * Implementation of the natural logarithm of x for Intel 80-bit format.
+ *
+ * First decompose x into its base 2 representation:
+ *
+ *    log(x) = log(X * 2**k), where X is in [1, 2)
+ *           = log(X) + k * log(2).
+ *
+ * Let X = X_i + e, where X_i is the center of one of the intervals
+ * [-1.0/256, 1.0/256), [1.0/256, 3.0/256), .... [2.0-1.0/256, 2.0+1.0/256)
+ * and X is in this interval.  Then
+ *
+ *    log(X) = log(X_i + e)
+ *           = log(X_i * (1 + e / X_i))
+ *           = log(X_i) + log(1 + e / X_i).
+ *
+ * The values log(X_i) are tabulated below.  Let d = e / X_i and use
+ *
+ *    log(1 + d) = p(d)
+ *
+ * where p(d) = d - 0.5*d*d + ... is a special minimax polynomial of
+ * suitably high degree.
+ *
+ * To get sufficiently small roundoff errors, k * log(2), log(X_i), and
+ * sometimes (if |k| is not large) the first term in p(d) must be evaluated
+ * and added up in extra precision.  Extra precision is not needed for the
+ * rest of p(d).  In the worst case when k = 0 and log(X_i) is 0, the final
+ * error is controlled mainly by the error in the second term in p(d).  The
+ * error in this term itself is at most 0.5 ulps from the d*d operation in
+ * it.  The error in this term relative to the first term is thus at most
+ * 0.5 * |-0.5| * |d| < 1.0/1024 ulps.  We aim for an accumulated error of
+ * at most twice this at the point of the final rounding step.  Thus the
+ * final error should be at most 0.5 + 1.0/512 = 0.5020 ulps.  Exhaustive
+ * testing of a float variant of this function showed a maximum final error
+ * of 0.5008 ulps.  Non-exhaustive testing of a double variant of this
+ * function showed a maximum final error of 0.5078 ulps (near 1+1.0/256).
+ *
+ * We made the maximum of |d| (and thus the total relative error and the
+ * degree of p(d)) small by using a large number of intervals.  Using
+ * centers of intervals instead of endpoints reduces this maximum by a
+ * factor of 2 for a given number of intervals.  p(d) is special only
+ * in beginning with the Taylor coefficients 0 + 1*d, which tends to happen
+ * naturally.  The most accurate minimax polynomial of a given degree might
+ * be different, but then we wouldn't want it since we would have to do
+ * extra work to avoid roundoff error (especially for P0*d instead of d).
+ */
+
+#ifdef DEBUG
+#include <assert.h>
+#include <fenv.h>
+#endif
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#define	i386_SSE_GOOD
+#ifndef NO_STRUCT_RETURN
+#define	STRUCT_RETURN
+#endif
+#include "math_private.h"
+
+#if !defined(NO_UTAB) && !defined(NO_UTABL)
+#define	USE_UTAB
+#endif
+
+/*
+ * Domain [-0.005280, 0.004838], range ~[-5.1736e-22, 5.1738e-22]:
+ * |log(1 + d)/d - p(d)| < 2**-70.7
+ */
+static const double
+P2 = -0.5,
+P3 =  3.3333333333333359e-1,		/*  0x1555555555555a.0p-54 */
+P4 = -2.5000000000004424e-1,		/* -0x1000000000031d.0p-54 */
+P5 =  1.9999999992970016e-1,		/*  0x1999999972f3c7.0p-55 */
+P6 = -1.6666666072191585e-1,		/* -0x15555548912c09.0p-55 */
+P7 =  1.4286227413310518e-1,		/*  0x12494f9d9def91.0p-55 */
+P8 = -1.2518388626763144e-1;		/* -0x1006068cc0b97c.0p-55 */
+
+static volatile const double zero = 0;
+
+#define	INTERVALS	128
+#define	LOG2_INTERVALS	7
+#define	TSIZE		(INTERVALS + 1)
+#define	G(i)		(T[(i)].G)
+#define	F_hi(i)		(T[(i)].F_hi)
+#define	F_lo(i)		(T[(i)].F_lo)
+#define	ln2_hi		F_hi(TSIZE - 1)
+#define	ln2_lo		F_lo(TSIZE - 1)
+#define	E(i)		(U[(i)].E)
+#define	H(i)		(U[(i)].H)
+
+static const struct {
+	float	G;			/* 1/(1 + i/128) rounded to 8/9 bits */
+	float	F_hi;			/* log(1 / G_i) rounded (see below) */
+	double	F_lo;			/* next 53 bits for log(1 / G_i) */
+} T[TSIZE] = {
+	/*
+	 * ln2_hi and each F_hi(i) are rounded to a number of bits that
+	 * makes F_hi(i) + dk*ln2_hi exact for all i and all dk.
+	 *
+	 * The last entry (for X just below 2) is used to define ln2_hi
+	 * and ln2_lo, to ensure that F_hi(i) and F_lo(i) cancel exactly
+	 * with dk*ln2_hi and dk*ln2_lo, respectively, when dk = -1.
+	 * This is needed for accuracy when x is just below 1.  (To avoid
+	 * special cases, such x are "reduced" strangely to X just below
+	 * 2 and dk = -1, and then the exact cancellation is needed
+	 * because any the error from any non-exactness would be too
+	 * large).
+	 *
+	 * We want to share this table between double precision and ld80,
+	 * so the relevant range of dk is the larger one of ld80
+	 * ([-16445, 16383]) and the relevant exactness requirement is
+	 * the stricter one of double precision.  The maximum number of
+	 * bits in F_hi(i) that works is very dependent on i but has
+	 * a minimum of 33.  We only need about 12 bits in F_hi(i) for
+	 * it to provide enough extra precision in double precision (11
+	 * more than that are required for ld80).
+	 *
+	 * We round F_hi(i) to 24 bits so that it can have type float,
+	 * mainly to minimize the size of the table.  Using all 24 bits
+	 * in a float for it automatically satisfies the above constraints.
+	 */
+	 0x800000.0p-23,  0,               0,
+	 0xfe0000.0p-24,  0x8080ac.0p-30, -0x14ee431dae6675.0p-84,
+	 0xfc0000.0p-24,  0x8102b3.0p-29, -0x1db29ee2d83718.0p-84,
+	 0xfa0000.0p-24,  0xc24929.0p-29,  0x1191957d173698.0p-83,
+	 0xf80000.0p-24,  0x820aec.0p-28,  0x13ce8888e02e79.0p-82,
+	 0xf60000.0p-24,  0xa33577.0p-28, -0x17a4382ce6eb7c.0p-82,
+	 0xf48000.0p-24,  0xbc42cb.0p-28, -0x172a21161a1076.0p-83,
+	 0xf30000.0p-24,  0xd57797.0p-28, -0x1e09de07cb9589.0p-82,
+	 0xf10000.0p-24,  0xf7518e.0p-28,  0x1ae1eec1b036c5.0p-91,
+	 0xef0000.0p-24,  0x8cb9df.0p-27, -0x1d7355325d560e.0p-81,
+	 0xed8000.0p-24,  0x999ec0.0p-27, -0x1f9f02d256d503.0p-82,
+	 0xec0000.0p-24,  0xa6988b.0p-27, -0x16fc0a9d12c17a.0p-83,
+	 0xea0000.0p-24,  0xb80698.0p-27,  0x15d581c1e8da9a.0p-81,
+	 0xe80000.0p-24,  0xc99af3.0p-27, -0x1535b3ba8f150b.0p-83,
+	 0xe70000.0p-24,  0xd273b2.0p-27,  0x163786f5251af0.0p-85,
+	 0xe50000.0p-24,  0xe442c0.0p-27,  0x1bc4b2368e32d5.0p-84,
+	 0xe38000.0p-24,  0xf1b83f.0p-27,  0x1c6090f684e676.0p-81,
+	 0xe20000.0p-24,  0xff448a.0p-27, -0x1890aa69ac9f42.0p-82,
+	 0xe08000.0p-24,  0x8673f6.0p-26,  0x1b9985194b6b00.0p-80,
+	 0xdf0000.0p-24,  0x8d515c.0p-26, -0x1dc08d61c6ef1e.0p-83,
+	 0xdd8000.0p-24,  0x943a9e.0p-26, -0x1f72a2dac729b4.0p-82,
+	 0xdc0000.0p-24,  0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9.0p-80,
+	 0xda8000.0p-24,  0xa2315d.0p-26, -0x11b26121629c47.0p-82,
+	 0xd90000.0p-24,  0xa93f2f.0p-26,  0x1286d633e8e569.0p-81,
+	 0xd78000.0p-24,  0xb05988.0p-26,  0x16128eba936770.0p-84,
+	 0xd60000.0p-24,  0xb78094.0p-26,  0x16ead577390d32.0p-80,
+	 0xd50000.0p-24,  0xbc4c6c.0p-26,  0x151131ccf7c7b7.0p-81,
+	 0xd38000.0p-24,  0xc3890a.0p-26, -0x115e2cd714bd06.0p-80,
+	 0xd20000.0p-24,  0xcad2d7.0p-26, -0x1847f406ebd3b0.0p-82,
+	 0xd10000.0p-24,  0xcfb620.0p-26,  0x1c2259904d6866.0p-81,
+	 0xcf8000.0p-24,  0xd71653.0p-26,  0x1ece57a8d5ae55.0p-80,
+	 0xce0000.0p-24,  0xde843a.0p-26, -0x1f109d4bc45954.0p-81,
+	 0xcd0000.0p-24,  0xe37fde.0p-26,  0x1bc03dc271a74d.0p-81,
+	 0xcb8000.0p-24,  0xeb050c.0p-26, -0x1bf2badc0df842.0p-85,
+	 0xca0000.0p-24,  0xf29878.0p-26, -0x18efededd89fbe.0p-87,
+	 0xc90000.0p-24,  0xf7ad6f.0p-26,  0x1373ff977baa69.0p-81,
+	 0xc80000.0p-24,  0xfcc8e3.0p-26,  0x196766f2fb3283.0p-80,
+	 0xc68000.0p-24,  0x823f30.0p-25,  0x19bd076f7c434e.0p-79,
+	 0xc58000.0p-24,  0x84d52c.0p-25, -0x1a327257af0f46.0p-79,
+	 0xc40000.0p-24,  0x88bc74.0p-25,  0x113f23def19c5a.0p-81,
+	 0xc30000.0p-24,  0x8b5ae6.0p-25,  0x1759f6e6b37de9.0p-79,
+	 0xc20000.0p-24,  0x8dfccb.0p-25,  0x1ad35ca6ed5148.0p-81,
+	 0xc10000.0p-24,  0x90a22b.0p-25,  0x1a1d71a87deba4.0p-79,
+	 0xbf8000.0p-24,  0x94a0d8.0p-25, -0x139e5210c2b731.0p-80,
+	 0xbe8000.0p-24,  0x974f16.0p-25, -0x18f6ebcff3ed73.0p-81,
+	 0xbd8000.0p-24,  0x9a00f1.0p-25, -0x1aa268be39aab7.0p-79,
+	 0xbc8000.0p-24,  0x9cb672.0p-25, -0x14c8815839c566.0p-79,
+	 0xbb0000.0p-24,  0xa0cda1.0p-25,  0x1eaf46390dbb24.0p-81,
+	 0xba0000.0p-24,  0xa38c6e.0p-25,  0x138e20d831f698.0p-81,
+	 0xb90000.0p-24,  0xa64f05.0p-25, -0x1e8d3c41123616.0p-82,
+	 0xb80000.0p-24,  0xa91570.0p-25,  0x1ce28f5f3840b2.0p-80,
+	 0xb70000.0p-24,  0xabdfbb.0p-25, -0x186e5c0a424234.0p-79,
+	 0xb60000.0p-24,  0xaeadef.0p-25, -0x14d41a0b2a08a4.0p-83,
+	 0xb50000.0p-24,  0xb18018.0p-25,  0x16755892770634.0p-79,
+	 0xb40000.0p-24,  0xb45642.0p-25, -0x16395ebe59b152.0p-82,
+	 0xb30000.0p-24,  0xb73077.0p-25,  0x1abc65c8595f09.0p-80,
+	 0xb20000.0p-24,  0xba0ec4.0p-25, -0x1273089d3dad89.0p-79,
+	 0xb10000.0p-24,  0xbcf133.0p-25,  0x10f9f67b1f4bbf.0p-79,
+	 0xb00000.0p-24,  0xbfd7d2.0p-25, -0x109fab90486409.0p-80,
+	 0xaf0000.0p-24,  0xc2c2ac.0p-25, -0x1124680aa43333.0p-79,
+	 0xae8000.0p-24,  0xc439b3.0p-25, -0x1f360cc4710fc0.0p-80,
+	 0xad8000.0p-24,  0xc72afd.0p-25, -0x132d91f21d89c9.0p-80,
+	 0xac8000.0p-24,  0xca20a2.0p-25, -0x16bf9b4d1f8da8.0p-79,
+	 0xab8000.0p-24,  0xcd1aae.0p-25,  0x19deb5ce6a6a87.0p-81,
+	 0xaa8000.0p-24,  0xd0192f.0p-25,  0x1a29fb48f7d3cb.0p-79,
+	 0xaa0000.0p-24,  0xd19a20.0p-25,  0x1127d3c6457f9d.0p-81,
+	 0xa90000.0p-24,  0xd49f6a.0p-25, -0x1ba930e486a0ac.0p-81,
+	 0xa80000.0p-24,  0xd7a94b.0p-25, -0x1b6e645f31549e.0p-79,
+	 0xa70000.0p-24,  0xdab7d0.0p-25,  0x1118a425494b61.0p-80,
+	 0xa68000.0p-24,  0xdc40d5.0p-25,  0x1966f24d29d3a3.0p-80,
+	 0xa58000.0p-24,  0xdf566d.0p-25, -0x1d8e52eb2248f1.0p-82,
+	 0xa48000.0p-24,  0xe270ce.0p-25, -0x1ee370f96e6b68.0p-80,
+	 0xa40000.0p-24,  0xe3ffce.0p-25,  0x1d155324911f57.0p-80,
+	 0xa30000.0p-24,  0xe72179.0p-25, -0x1fe6e2f2f867d9.0p-80,
+	 0xa20000.0p-24,  0xea4812.0p-25,  0x1b7be9add7f4d4.0p-80,
+	 0xa18000.0p-24,  0xebdd3d.0p-25,  0x1b3cfb3f7511dd.0p-79,
+	 0xa08000.0p-24,  0xef0b5b.0p-25, -0x1220de1f730190.0p-79,
+	 0xa00000.0p-24,  0xf0a451.0p-25, -0x176364c9ac81cd.0p-80,
+	 0x9f0000.0p-24,  0xf3da16.0p-25,  0x1eed6b9aafac8d.0p-81,
+	 0x9e8000.0p-24,  0xf576e9.0p-25,  0x1d593218675af2.0p-79,
+	 0x9d8000.0p-24,  0xf8b47c.0p-25, -0x13e8eb7da053e0.0p-84,
+	 0x9d0000.0p-24,  0xfa553f.0p-25,  0x1c063259bcade0.0p-79,
+	 0x9c0000.0p-24,  0xfd9ac5.0p-25,  0x1ef491085fa3c1.0p-79,
+	 0x9b8000.0p-24,  0xff3f8c.0p-25,  0x1d607a7c2b8c53.0p-79,
+	 0x9a8000.0p-24,  0x814697.0p-24, -0x12ad3817004f3f.0p-78,
+	 0x9a0000.0p-24,  0x821b06.0p-24, -0x189fc53117f9e5.0p-81,
+	 0x990000.0p-24,  0x83c5f8.0p-24,  0x14cf15a048907b.0p-79,
+	 0x988000.0p-24,  0x849c7d.0p-24,  0x1cbb1d35fb8287.0p-78,
+	 0x978000.0p-24,  0x864ba6.0p-24,  0x1128639b814f9c.0p-78,
+	 0x970000.0p-24,  0x87244c.0p-24,  0x184733853300f0.0p-79,
+	 0x968000.0p-24,  0x87fdaa.0p-24,  0x109d23aef77dd6.0p-80,
+	 0x958000.0p-24,  0x89b293.0p-24, -0x1a81ef367a59de.0p-78,
+	 0x950000.0p-24,  0x8a8e20.0p-24, -0x121ad3dbb2f452.0p-78,
+	 0x948000.0p-24,  0x8b6a6a.0p-24, -0x1cfb981628af72.0p-79,
+	 0x938000.0p-24,  0x8d253a.0p-24, -0x1d21730ea76cfe.0p-79,
+	 0x930000.0p-24,  0x8e03c2.0p-24,  0x135cc00e566f77.0p-78,
+	 0x928000.0p-24,  0x8ee30d.0p-24, -0x10fcb5df257a26.0p-80,
+	 0x918000.0p-24,  0x90a3ee.0p-24, -0x16e171b15433d7.0p-79,
+	 0x910000.0p-24,  0x918587.0p-24, -0x1d050da07f3237.0p-79,
+	 0x908000.0p-24,  0x9267e7.0p-24,  0x1be03669a5268d.0p-79,
+	 0x8f8000.0p-24,  0x942f04.0p-24,  0x10b28e0e26c337.0p-79,
+	 0x8f0000.0p-24,  0x9513c3.0p-24,  0x1a1d820da57cf3.0p-78,
+	 0x8e8000.0p-24,  0x95f950.0p-24, -0x19ef8f13ae3cf1.0p-79,
+	 0x8e0000.0p-24,  0x96dfab.0p-24, -0x109e417a6e507c.0p-78,
+	 0x8d0000.0p-24,  0x98aed2.0p-24,  0x10d01a2c5b0e98.0p-79,
+	 0x8c8000.0p-24,  0x9997a2.0p-24, -0x1d6a50d4b61ea7.0p-78,
+	 0x8c0000.0p-24,  0x9a8145.0p-24,  0x1b3b190b83f952.0p-78,
+	 0x8b8000.0p-24,  0x9b6bbf.0p-24,  0x13a69fad7e7abe.0p-78,
+	 0x8b0000.0p-24,  0x9c5711.0p-24, -0x11cd12316f576b.0p-78,
+	 0x8a8000.0p-24,  0x9d433b.0p-24,  0x1c95c444b807a2.0p-79,
+	 0x898000.0p-24,  0x9f1e22.0p-24, -0x1b9c224ea698c3.0p-79,
+	 0x890000.0p-24,  0xa00ce1.0p-24,  0x125ca93186cf0f.0p-81,
+	 0x888000.0p-24,  0xa0fc80.0p-24, -0x1ee38a7bc228b3.0p-79,
+	 0x880000.0p-24,  0xa1ed00.0p-24, -0x1a0db876613d20.0p-78,
+	 0x878000.0p-24,  0xa2de62.0p-24,  0x193224e8516c01.0p-79,
+	 0x870000.0p-24,  0xa3d0a9.0p-24,  0x1fa28b4d2541ad.0p-79,
+	 0x868000.0p-24,  0xa4c3d6.0p-24,  0x1c1b5760fb4572.0p-78,
+	 0x858000.0p-24,  0xa6acea.0p-24,  0x1fed5d0f65949c.0p-80,
+	 0x850000.0p-24,  0xa7a2d4.0p-24,  0x1ad270c9d74936.0p-80,
+	 0x848000.0p-24,  0xa899ab.0p-24,  0x199ff15ce53266.0p-79,
+	 0x840000.0p-24,  0xa99171.0p-24,  0x1a19e15ccc45d2.0p-79,
+	 0x838000.0p-24,  0xaa8a28.0p-24, -0x121a14ec532b36.0p-80,
+	 0x830000.0p-24,  0xab83d1.0p-24,  0x1aee319980bff3.0p-79,
+	 0x828000.0p-24,  0xac7e6f.0p-24, -0x18ffd9e3900346.0p-80,
+	 0x820000.0p-24,  0xad7a03.0p-24, -0x1e4db102ce29f8.0p-80,
+	 0x818000.0p-24,  0xae768f.0p-24,  0x17c35c55a04a83.0p-81,
+	 0x810000.0p-24,  0xaf7415.0p-24,  0x1448324047019b.0p-78,
+	 0x808000.0p-24,  0xb07298.0p-24, -0x1750ee3915a198.0p-78,
+	 0x800000.0p-24,  0xb17218.0p-24, -0x105c610ca86c39.0p-81,
+};
+
+#ifdef USE_UTAB
+static const struct {
+	float	H;			/* 1 + i/INTERVALS (exact) */
+	float	E;			/* H(i) * G(i) - 1 (exact) */
+} U[TSIZE] = {
+	 0x800000.0p-23,  0,
+	 0x810000.0p-23, -0x800000.0p-37,
+	 0x820000.0p-23, -0x800000.0p-35,
+	 0x830000.0p-23, -0x900000.0p-34,
+	 0x840000.0p-23, -0x800000.0p-33,
+	 0x850000.0p-23, -0xc80000.0p-33,
+	 0x860000.0p-23, -0xa00000.0p-36,
+	 0x870000.0p-23,  0x940000.0p-33,
+	 0x880000.0p-23,  0x800000.0p-35,
+	 0x890000.0p-23, -0xc80000.0p-34,
+	 0x8a0000.0p-23,  0xe00000.0p-36,
+	 0x8b0000.0p-23,  0x900000.0p-33,
+	 0x8c0000.0p-23, -0x800000.0p-35,
+	 0x8d0000.0p-23, -0xe00000.0p-33,
+	 0x8e0000.0p-23,  0x880000.0p-33,
+	 0x8f0000.0p-23, -0xa80000.0p-34,
+	 0x900000.0p-23, -0x800000.0p-35,
+	 0x910000.0p-23,  0x800000.0p-37,
+	 0x920000.0p-23,  0x900000.0p-35,
+	 0x930000.0p-23,  0xd00000.0p-35,
+	 0x940000.0p-23,  0xe00000.0p-35,
+	 0x950000.0p-23,  0xc00000.0p-35,
+	 0x960000.0p-23,  0xe00000.0p-36,
+	 0x970000.0p-23, -0x800000.0p-38,
+	 0x980000.0p-23, -0xc00000.0p-35,
+	 0x990000.0p-23, -0xd00000.0p-34,
+	 0x9a0000.0p-23,  0x880000.0p-33,
+	 0x9b0000.0p-23,  0xe80000.0p-35,
+	 0x9c0000.0p-23, -0x800000.0p-35,
+	 0x9d0000.0p-23,  0xb40000.0p-33,
+	 0x9e0000.0p-23,  0x880000.0p-34,
+	 0x9f0000.0p-23, -0xe00000.0p-35,
+	 0xa00000.0p-23,  0x800000.0p-33,
+	 0xa10000.0p-23, -0x900000.0p-36,
+	 0xa20000.0p-23, -0xb00000.0p-33,
+	 0xa30000.0p-23, -0xa00000.0p-36,
+	 0xa40000.0p-23,  0x800000.0p-33,
+	 0xa50000.0p-23, -0xf80000.0p-35,
+	 0xa60000.0p-23,  0x880000.0p-34,
+	 0xa70000.0p-23, -0x900000.0p-33,
+	 0xa80000.0p-23, -0x800000.0p-35,
+	 0xa90000.0p-23,  0x900000.0p-34,
+	 0xaa0000.0p-23,  0xa80000.0p-33,
+	 0xab0000.0p-23, -0xac0000.0p-34,
+	 0xac0000.0p-23, -0x800000.0p-37,
+	 0xad0000.0p-23,  0xf80000.0p-35,
+	 0xae0000.0p-23,  0xf80000.0p-34,
+	 0xaf0000.0p-23, -0xac0000.0p-33,
+	 0xb00000.0p-23, -0x800000.0p-33,
+	 0xb10000.0p-23, -0xb80000.0p-34,
+	 0xb20000.0p-23, -0x800000.0p-34,
+	 0xb30000.0p-23, -0xb00000.0p-35,
+	 0xb40000.0p-23, -0x800000.0p-35,
+	 0xb50000.0p-23, -0xe00000.0p-36,
+	 0xb60000.0p-23, -0x800000.0p-35,
+	 0xb70000.0p-23, -0xb00000.0p-35,
+	 0xb80000.0p-23, -0x800000.0p-34,
+	 0xb90000.0p-23, -0xb80000.0p-34,
+	 0xba0000.0p-23, -0x800000.0p-33,
+	 0xbb0000.0p-23, -0xac0000.0p-33,
+	 0xbc0000.0p-23,  0x980000.0p-33,
+	 0xbd0000.0p-23,  0xbc0000.0p-34,
+	 0xbe0000.0p-23,  0xe00000.0p-36,
+	 0xbf0000.0p-23, -0xb80000.0p-35,
+	 0xc00000.0p-23, -0x800000.0p-33,
+	 0xc10000.0p-23,  0xa80000.0p-33,
+	 0xc20000.0p-23,  0x900000.0p-34,
+	 0xc30000.0p-23, -0x800000.0p-35,
+	 0xc40000.0p-23, -0x900000.0p-33,
+	 0xc50000.0p-23,  0x820000.0p-33,
+	 0xc60000.0p-23,  0x800000.0p-38,
+	 0xc70000.0p-23, -0x820000.0p-33,
+	 0xc80000.0p-23,  0x800000.0p-33,
+	 0xc90000.0p-23, -0xa00000.0p-36,
+	 0xca0000.0p-23, -0xb00000.0p-33,
+	 0xcb0000.0p-23,  0x840000.0p-34,
+	 0xcc0000.0p-23, -0xd00000.0p-34,
+	 0xcd0000.0p-23,  0x800000.0p-33,
+	 0xce0000.0p-23, -0xe00000.0p-35,
+	 0xcf0000.0p-23,  0xa60000.0p-33,
+	 0xd00000.0p-23, -0x800000.0p-35,
+	 0xd10000.0p-23,  0xb40000.0p-33,
+	 0xd20000.0p-23, -0x800000.0p-35,
+	 0xd30000.0p-23,  0xaa0000.0p-33,
+	 0xd40000.0p-23, -0xe00000.0p-35,
+	 0xd50000.0p-23,  0x880000.0p-33,
+	 0xd60000.0p-23, -0xd00000.0p-34,
+	 0xd70000.0p-23,  0x9c0000.0p-34,
+	 0xd80000.0p-23, -0xb00000.0p-33,
+	 0xd90000.0p-23, -0x800000.0p-38,
+	 0xda0000.0p-23,  0xa40000.0p-33,
+	 0xdb0000.0p-23, -0xdc0000.0p-34,
+	 0xdc0000.0p-23,  0xc00000.0p-35,
+	 0xdd0000.0p-23,  0xca0000.0p-33,
+	 0xde0000.0p-23, -0xb80000.0p-34,
+	 0xdf0000.0p-23,  0xd00000.0p-35,
+	 0xe00000.0p-23,  0xc00000.0p-33,
+	 0xe10000.0p-23, -0xf40000.0p-34,
+	 0xe20000.0p-23,  0x800000.0p-37,
+	 0xe30000.0p-23,  0x860000.0p-33,
+	 0xe40000.0p-23, -0xc80000.0p-33,
+	 0xe50000.0p-23, -0xa80000.0p-34,
+	 0xe60000.0p-23,  0xe00000.0p-36,
+	 0xe70000.0p-23,  0x880000.0p-33,
+	 0xe80000.0p-23, -0xe00000.0p-33,
+	 0xe90000.0p-23, -0xfc0000.0p-34,
+	 0xea0000.0p-23, -0x800000.0p-35,
+	 0xeb0000.0p-23,  0xe80000.0p-35,
+	 0xec0000.0p-23,  0x900000.0p-33,
+	 0xed0000.0p-23,  0xe20000.0p-33,
+	 0xee0000.0p-23, -0xac0000.0p-33,
+	 0xef0000.0p-23, -0xc80000.0p-34,
+	 0xf00000.0p-23, -0x800000.0p-35,
+	 0xf10000.0p-23,  0x800000.0p-35,
+	 0xf20000.0p-23,  0xb80000.0p-34,
+	 0xf30000.0p-23,  0x940000.0p-33,
+	 0xf40000.0p-23,  0xc80000.0p-33,
+	 0xf50000.0p-23, -0xf20000.0p-33,
+	 0xf60000.0p-23, -0xc80000.0p-33,
+	 0xf70000.0p-23, -0xa20000.0p-33,
+	 0xf80000.0p-23, -0x800000.0p-33,
+	 0xf90000.0p-23, -0xc40000.0p-34,
+	 0xfa0000.0p-23, -0x900000.0p-34,
+	 0xfb0000.0p-23, -0xc80000.0p-35,
+	 0xfc0000.0p-23, -0x800000.0p-35,
+	 0xfd0000.0p-23, -0x900000.0p-36,
+	 0xfe0000.0p-23, -0x800000.0p-37,
+	 0xff0000.0p-23, -0x800000.0p-39,
+	 0x800000.0p-22,  0,
+};
+#endif /* USE_UTAB */
+
+#ifdef STRUCT_RETURN
+#define	RETURN1(rp, v) do {	\
+	(rp)->hi = (v);		\
+	(rp)->lo_set = 0;	\
+	return;			\
+} while (0)
+
+#define	RETURN2(rp, h, l) do {	\
+	(rp)->hi = (h);		\
+	(rp)->lo = (l);		\
+	(rp)->lo_set = 1;	\
+	return;			\
+} while (0)
+
+struct ld {
+	long double hi;
+	long double lo;
+	int	lo_set;
+};
+#else
+#define	RETURN1(rp, v)	RETURNF(v)
+#define	RETURN2(rp, h, l)	RETURNI((h) + (l))
+#endif
+
+#ifdef STRUCT_RETURN
+static inline __always_inline void
+k_logl(long double x, struct ld *rp)
+#else
+long double
+logl(long double x)
+#endif
+{
+	long double d, dk, val_hi, val_lo, z;
+	uint64_t ix, lx;
+	int i, k;
+	uint16_t hx;
+
+	EXTRACT_LDBL80_WORDS(hx, lx, x);
+	k = -16383;
+#if 0 /* Hard to do efficiently.  Don't do it until we support all modes. */
+	if (x == 1)
+		RETURN1(rp, 0);		/* log(1) = +0 in all rounding modes */
+#endif
+	if (hx == 0 || hx >= 0x8000) {	/* zero, negative or subnormal? */
+		if (((hx & 0x7fff) | lx) == 0)
+			RETURN1(rp, -1 / zero);	/* log(+-0) = -Inf */
+		if (hx != 0)
+			/* log(neg or [pseudo-]NaN) = qNaN: */
+			RETURN1(rp, (x - x) / zero);
+		x *= 0x1.0p65;		/* subnormal; scale up x */
+					/* including pseudo-subnormals */
+		EXTRACT_LDBL80_WORDS(hx, lx, x);
+		k = -16383 - 65;
+	} else if (hx >= 0x7fff || (lx & 0x8000000000000000ULL) == 0)
+		RETURN1(rp, x + x);	/* log(Inf or NaN) = Inf or qNaN */
+					/* log(pseudo-Inf) = qNaN */
+					/* log(pseudo-NaN) = qNaN */
+					/* log(unnormal) = qNaN */
+#ifndef STRUCT_RETURN
+	ENTERI();
+#endif
+	k += hx;
+	ix = lx & 0x7fffffffffffffffULL;
+	dk = k;
+
+	/* Scale x to be in [1, 2). */
+	SET_LDBL_EXPSIGN(x, 0x3fff);
+
+	/* 0 <= i <= INTERVALS: */
+#define	L2I	(64 - LOG2_INTERVALS)
+	i = (ix + (1LL << (L2I - 2))) >> (L2I - 1);
+
+	/*
+	 * -0.005280 < d < 0.004838.  In particular, the infinite-
+	 * precision |d| is <= 2**-7.  Rounding of G(i) to 8 bits
+	 * ensures that d is representable without extra precision for
+	 * this bound on |d| (since when this calculation is expressed
+	 * as x*G(i)-1, the multiplication needs as many extra bits as
+	 * G(i) has and the subtraction cancels 8 bits).  But for
+	 * most i (107 cases out of 129), the infinite-precision |d|
+	 * is <= 2**-8.  G(i) is rounded to 9 bits for such i to give
+	 * better accuracy (this works by improving the bound on |d|,
+	 * which in turn allows rounding to 9 bits in more cases).
+	 * This is only important when the original x is near 1 -- it
+	 * lets us avoid using a special method to give the desired
+	 * accuracy for such x.
+	 */
+	if (0)
+		d = x * G(i) - 1;
+	else {
+#ifdef USE_UTAB
+		d = (x - H(i)) * G(i) + E(i);
+#else
+		long double x_hi, x_lo;
+		float fx_hi;
+
+		/*
+		 * Split x into x_hi + x_lo to calculate x*G(i)-1 exactly.
+		 * G(i) has at most 9 bits, so the splitting point is not
+		 * critical.
+		 */
+		SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000);
+		x_hi = fx_hi;
+		x_lo = x - x_hi;
+		d = x_hi * G(i) - 1 + x_lo * G(i);
+#endif
+	}
+
+	/*
+	 * Our algorithm depends on exact cancellation of F_lo(i) and
+	 * F_hi(i) with dk*ln_2_lo and dk*ln2_hi when k is -1 and i is
+	 * at the end of the table.  This and other technical complications
+	 * make it difficult to avoid the double scaling in (dk*ln2) *
+	 * log(base) for base != e without losing more accuracy and/or
+	 * efficiency than is gained.
+	 */
+	z = d * d;
+	val_lo = z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) +
+	    (F_lo(i) + dk * ln2_lo + z * d * (d * P4 + P3)) + z * P2;
+	val_hi = d;
+#ifdef DEBUG
+	if (fetestexcept(FE_UNDERFLOW))
+		breakpoint();
+#endif
+
+	_3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi);
+	RETURN2(rp, val_hi, val_lo);
+}
+
+long double
+log1pl(long double x)
+{
+	long double d, d_hi, d_lo, dk, f_lo, val_hi, val_lo, z;
+	long double f_hi, twopminusk;
+	uint64_t ix, lx;
+	int i, k;
+	int16_t ax, hx;
+
+	DOPRINT_START(&x);
+	EXTRACT_LDBL80_WORDS(hx, lx, x);
+	if (hx < 0x3fff) {		/* x < 1, or x neg NaN */
+		ax = hx & 0x7fff;
+		if (ax >= 0x3fff) {	/* x <= -1, or x neg NaN */
+			if (ax == 0x3fff && lx == 0x8000000000000000ULL)
+				RETURNP(-1 / zero);	/* log1p(-1) = -Inf */
+			/* log1p(x < 1, or x [pseudo-]NaN) = qNaN: */
+			RETURNP((x - x) / (x - x));
+		}
+		if (ax <= 0x3fbe) {	/* |x| < 2**-64 */
+			if ((int)x == 0)
+				RETURNP(x);	/* x with inexact if x != 0 */
+		}
+		f_hi = 1;
+		f_lo = x;
+	} else if (hx >= 0x7fff) {	/* x +Inf or non-neg NaN */
+		RETURNP(x + x);		/* log1p(Inf or NaN) = Inf or qNaN */
+					/* log1p(pseudo-Inf) = qNaN */
+					/* log1p(pseudo-NaN) = qNaN */
+					/* log1p(unnormal) = qNaN */
+	} else if (hx < 0x407f) {	/* 1 <= x < 2**128 */
+		f_hi = x;
+		f_lo = 1;
+	} else {			/* 2**128 <= x < +Inf */
+		f_hi = x;
+		f_lo = 0;		/* avoid underflow of the P5 term */
+	}
+	ENTERI();
+	x = f_hi + f_lo;
+	f_lo = (f_hi - x) + f_lo;
+
+	EXTRACT_LDBL80_WORDS(hx, lx, x);
+	k = -16383;
+
+	k += hx;
+	ix = lx & 0x7fffffffffffffffULL;
+	dk = k;
+
+	SET_LDBL_EXPSIGN(x, 0x3fff);
+	twopminusk = 1;
+	SET_LDBL_EXPSIGN(twopminusk, 0x7ffe - (hx & 0x7fff));
+	f_lo *= twopminusk;
+
+	i = (ix + (1LL << (L2I - 2))) >> (L2I - 1);
+
+	/*
+	 * x*G(i)-1 (with a reduced x) can be represented exactly, as
+	 * above, but now we need to evaluate the polynomial on d =
+	 * (x+f_lo)*G(i)-1 and extra precision is needed for that.
+	 * Since x+x_lo is a hi+lo decomposition and subtracting 1
+	 * doesn't lose too many bits, an inexact calculation for
+	 * f_lo*G(i) is good enough.
+	 */
+	if (0)
+		d_hi = x * G(i) - 1;
+	else {
+#ifdef USE_UTAB
+		d_hi = (x - H(i)) * G(i) + E(i);
+#else
+		long double x_hi, x_lo;
+		float fx_hi;
+
+		SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000);
+		x_hi = fx_hi;
+		x_lo = x - x_hi;
+		d_hi = x_hi * G(i) - 1 + x_lo * G(i);
+#endif
+	}
+	d_lo = f_lo * G(i);
+
+	/*
+	 * This is _2sumF(d_hi, d_lo) inlined.  The condition
+	 * (d_hi == 0 || |d_hi| >= |d_lo|) for using _2sumF() is not
+	 * always satisifed, so it is not clear that this works, but
+	 * it works in practice.  It works even if it gives a wrong
+	 * normalized d_lo, since |d_lo| > |d_hi| implies that i is
+	 * nonzero and d is tiny, so the F(i) term dominates d_lo.
+	 * In float precision:
+	 * (By exhaustive testing, the worst case is d_hi = 0x1.bp-25.
+	 * And if d is only a little tinier than that, we would have
+	 * another underflow problem for the P3 term; this is also ruled
+	 * out by exhaustive testing.)
+	 */
+	d = d_hi + d_lo;
+	d_lo = d_hi - d + d_lo;
+	d_hi = d;
+
+	z = d * d;
+	val_lo = z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) +
+	    (F_lo(i) + dk * ln2_lo + d_lo + z * d * (d * P4 + P3)) + z * P2;
+	val_hi = d_hi;
+#ifdef DEBUG
+	if (fetestexcept(FE_UNDERFLOW))
+		breakpoint();
+#endif
+
+	_3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi);
+	RETURN2PI(val_hi, val_lo);
+}
+
+#ifdef STRUCT_RETURN
+
+long double
+logl(long double x)
+{
+	struct ld r;
+
+	ENTERI();
+	DOPRINT_START(&x);
+	k_logl(x, &r);
+	RETURNSPI(&r);
+}
+
+static const double
+invln10_hi =  4.3429448190317999e-1,		/*  0x1bcb7b1526e000.0p-54 */
+invln10_lo =  7.1842412889749798e-14,		/*  0x1438ca9aadd558.0p-96 */
+invln2_hi =  1.4426950408887933e0,		/*  0x171547652b8000.0p-52 */
+invln2_lo =  1.7010652264631490e-13;		/*  0x17f0bbbe87fed0.0p-95 */
+
+long double
+log10l(long double x)
+{
+	struct ld r;
+	long double hi, lo;
+
+	ENTERI();
+	DOPRINT_START(&x);
+	k_logl(x, &r);
+	if (!r.lo_set)
+		RETURNPI(r.hi);
+	_2sumF(r.hi, r.lo);
+	hi = (float)r.hi;
+	lo = r.lo + (r.hi - hi);
+	RETURN2PI(invln10_hi * hi,
+	    (invln10_lo + invln10_hi) * lo + invln10_lo * hi);
+}
+
+long double
+log2l(long double x)
+{
+	struct ld r;
+	long double hi, lo;
+
+	ENTERI();
+	DOPRINT_START(&x);
+	k_logl(x, &r);
+	if (!r.lo_set)
+		RETURNPI(r.hi);
+	_2sumF(r.hi, r.lo);
+	hi = (float)r.hi;
+	lo = r.lo + (r.hi - hi);
+	RETURN2PI(invln2_hi * hi,
+	    (invln2_lo + invln2_hi) * lo + invln2_lo * hi);
+}
+
+#endif /* STRUCT_RETURN */


Property changes on: trunk/lib/msun/ld80/s_logl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/s_nanl.c
===================================================================
--- trunk/lib/msun/ld80/s_nanl.c	2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/s_nanl.c	2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 David Schultz
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/msun/ld80/s_nanl.c 174759 2007-12-18 23:46:32Z das $
  */
 
 #include <math.h>



More information about the Midnightbsd-cvs mailing list