update from main archive 960829
authordrepper <drepper>
Fri, 30 Aug 1996 00:56:47 +0000 (00:56 +0000)
committerdrepper <drepper>
Fri, 30 Aug 1996 00:56:47 +0000 (00:56 +0000)
sysdeps/libm-ieee754/e_acoshl.c [new file with mode: 0644]
sysdeps/libm-ieee754/e_atanhl.c [new file with mode: 0644]
sysdeps/libm-ieee754/e_remainderl.c [new file with mode: 0644]
sysdeps/libm-ieee754/e_scalbl.c [new file with mode: 0644]
sysdeps/libm-ieee754/s_asinhl.c [new file with mode: 0644]
sysdeps/libm-ieee754/s_cosl.c [new file with mode: 0644]
sysdeps/libm-ieee754/s_sinl.c [new file with mode: 0644]
sysdeps/libm-ieee754/s_tanhl.c [new file with mode: 0644]
sysdeps/libm-ieee754/s_tanl.c [new file with mode: 0644]

diff --git a/sysdeps/libm-ieee754/e_acoshl.c b/sysdeps/libm-ieee754/e_acoshl.c
new file mode 100644 (file)
index 0000000..8af7c27
--- /dev/null
@@ -0,0 +1,72 @@
+/* e_acoshl.c -- long double version of e_acosh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_acoshl(x)
+ * Method :
+ *     Based on
+ *             acoshl(x) = logl [ x + sqrtl(x*x-1) ]
+ *     we have
+ *             acoshl(x) := logl(x)+ln2,       if x is large; else
+ *             acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else
+ *             acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ *     acoshl(x) is NaN with signal if x<1.
+ *     acoshl(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one    = 1.0,
+ln2    = 6.931471805599453094287e-01L; /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
+
+#ifdef __STDC__
+       long double __ieee754_acoshl(long double x)
+#else
+       long double __ieee754_acoshl(x)
+       long double x;
+#endif
+{
+       long double t;
+       u_int32_t se,i0,i1;
+       EXTRACT_LDOUBLE_WORDS(se,i0,i1,x);
+       if(se<0x3fff) {                 /* x < 1 */
+           return (x-x)/(x-x);
+       } else if(hx >=0x401b) {        /* x > 2**28 */
+           if(hx >=0x7fff) {           /* x is inf of NaN */
+               return x+x;
+           } else
+               return __ieee754_logl(x)+ln2;   /* acoshl(huge)=logl(2x) */
+       } else if(((se-0x3fff)|i0|i1)==0) {
+           return 0.0;                 /* acosh(1) = 0 */
+       } else if (hx > 0x4000) {       /* 2**28 > x > 2 */
+           t=x*x;
+           return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one)));
+       } else {                        /* 1<x<2 */
+           t = x-one;
+           return __log1pl(t+__sqrtl(2.0*t+t*t));
+       }
+}
diff --git a/sysdeps/libm-ieee754/e_atanhl.c b/sysdeps/libm-ieee754/e_atanhl.c
new file mode 100644 (file)
index 0000000..d74db48
--- /dev/null
@@ -0,0 +1,79 @@
+/* s_atanhl.c -- long double version of s_atan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_atanhl(x)
+ * Method :
+ *    1.Reduced x to positive by atanh(-x) = -atanh(x)
+ *    2.For x>=0.5
+ *                   1              2x                          x
+ *     atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ *                   2             1 - x                      1 - x
+ *
+ *     For x<0.5
+ *     atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ *     atanhl(x) is NaN if |x| > 1 with signal;
+ *     atanhl(NaN) is that NaN with no signal;
+ *     atanhl(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, huge = 1e16380;
+#else
+static long double one = 1.0, huge = 1e16380;
+#endif
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static double long zero = 0.0;
+#endif
+
+#ifdef __STDC__
+       long double __ieee754_atanhl(long double x)
+#else
+       long double __ieee754_atanhl(x)
+       long double x;
+#endif
+{
+       long double t;
+       int32_t ix;
+       u_int32_t se,i0,i1;
+       EXTRACT_LDOUBLE_WORDS(se,i0,i1,x);
+       ix = se&0x7fff;
+       if ((ix+((((i0&0x7fffffff)|i1)|(-((i0&0x7fffffff)|i1)))>>31))>0x3fff)
+         /* |x|>1 */
+           return (x-x)/(x-x);
+       if(ix==0x3fff)
+           return x/zero;
+       if(ix<0x3fe3&&(huge+x)>zero) return x;  /* x<2**-28 */
+       SET_LDOUBLE_EXP(x,ix);
+       if(ix<0x3ffe) {         /* x < 0.5 */
+           t = x+x;
+           t = 0.5*__log1pl(t+t*x/(one-x));
+       } else
+           t = 0.5*__log1pl((x+x)/(one-x));
+       if(se>0x7fff) return t; else return -t;
+}
diff --git a/sysdeps/libm-ieee754/e_remainderl.c b/sysdeps/libm-ieee754/e_remainderl.c
new file mode 100644 (file)
index 0000000..3b2cd7c
--- /dev/null
@@ -0,0 +1,83 @@
+/* e_remainderl.c -- long double version of e_remainder.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_remainderl(x,p)
+ * Return :
+ *     returns  x REM p  =  x - [x/p]*p as if in infinite
+ *     precise arithmetic, where [x/p] is the (infinite bit)
+ *     integer nearest x/p (in half way case choose the even one).
+ * Method :
+ *     Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static long double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+       long double __ieee754_remainderl(long double x, long double p)
+#else
+       long double __ieee754_remainderl(x,p)
+       long double x,p;
+#endif
+{
+       u_int32_t sx,sex,sep,x0,x1,p0,p1;
+       long double p_half;
+
+       EXTRACT_LDOUBLE_WORDS(sex,x0,x1,x);
+       EXTRACT_LDOUBLE_WORDS(sep,p0,p1,p);
+       sx = sex&0x8000;
+       sep &= 0x7fff;
+       sex &= 0x7fff;
+
+    /* purge off exception values */
+       if((sep|p0|p1)==0) return (x*p)/(x*p);  /* p = 0 */
+       if((sex==0x7fff)||                      /* x not finite */
+         ((sep==0x7fff)&&                      /* p is NaN */
+          ((p0|p1)!=0)))
+           return (x*p)/(x*p);
+
+
+       if (sep<0x7ffe) x = __ieee754_fmodl(x,p+p);     /* now x < 2p */
+       if (((sex-sep)|(x0-p0)|(x1-p1))==0) return zero*x;
+       x  = fabsl(x);
+       p  = fabsl(p);
+       if (sep<0x0002) {
+           if(x+x>p) {
+               x-=p;
+               if(x+x>=p) x -= p;
+           }
+       } else {
+           p_half = 0.5*p;
+           if(x>p_half) {
+               x-=p;
+               if(x>=p_half) x -= p;
+           }
+       }
+       GET_LDOUBLE_EXP(sex,x);
+       SET_LDOUBLE_EXP(x,sex^sx);
+       return x;
+}
diff --git a/sysdeps/libm-ieee754/e_scalbl.c b/sysdeps/libm-ieee754/e_scalbl.c
new file mode 100644 (file)
index 0000000..0dd36d4
--- /dev/null
@@ -0,0 +1,59 @@
+/* e_scalbl.c -- long double version of s_scalb.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * __ieee754_scalbl(x, fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbnl() instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef _SCALB_INT
+#ifdef __STDC__
+       long double __ieee754_scalbl(long double x, int fn)
+#else
+       long double __ieee754_scalbl(x,fn)
+       long double x; int fn;
+#endif
+#else
+#ifdef __STDC__
+       long double __ieee754_scalbl(long double x, long double fn)
+#else
+       long double __ieee754_scalbl(x,fn)
+       long double x, fn;
+#endif
+#endif
+{
+#ifdef _SCALB_INT
+       return scalbnl(x,fn);
+#else
+       if (isnanl(x)||isnanl(fn)) return x*fn;
+       if (!finitel(fn)) {
+           if(fn>0.0) return x*fn;
+           else       return x/(-fn);
+       }
+       if (rintl(fn)!=fn) return (fn-fn)/(fn-fn);
+       if ( fn > 65000.0) return scalbnl(x, 65000);
+       if (-fn > 65000.0) return scalbnl(x,-65000);
+       return scalbnl(x,(int)fn);
+#endif
+}
diff --git a/sysdeps/libm-ieee754/s_asinhl.c b/sysdeps/libm-ieee754/s_asinhl.c
new file mode 100644 (file)
index 0000000..823288a
--- /dev/null
@@ -0,0 +1,70 @@
+/* s_asinhl.c -- long double version of s_asinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* asinhl(x)
+ * Method :
+ *     Based on
+ *             asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ]
+ *     we have
+ *     asinhl(x) := x  if  1+x*x=1,
+ *               := signl(x)*(logl(x)+ln2)) for large |x|, else
+ *               := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else
+ *               := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one =  1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */
+ln2 =  6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
+huge=  1.000000000000000000e+16380L;
+
+#ifdef __STDC__
+       long double __asinhl(long double x)
+#else
+       long double __asinhl(x)
+       long double x;
+#endif
+{
+       long double t,w;
+       int32_t hx,ix;
+       GET_LDOUBLE_EXP(hx,x);
+       ix = hx&0x7fff;
+       if(ix==0x7fff) return x+x;      /* x is inf or NaN */
+       if(ix< 0x3fde) {        /* |x|<2**-34 */
+           if(huge+x>one) return x;    /* return x inexact except 0 */
+       }
+       if(ix>0x4020) {         /* |x| > 2**34 */
+           w = __ieee754_logl(fabsl(x))+ln2;
+       } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */
+           t = fabsl(x);
+           w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
+       } else {                /* 2.0 > |x| > 2**-28 */
+           t = x*x;
+           w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
+       }
+       if(hx>0x7fff) return w; else return -w;
+}
+weak_alias (__asinhl, asinhl)
diff --git a/sysdeps/libm-ieee754/s_cosl.c b/sysdeps/libm-ieee754/s_cosl.c
new file mode 100644 (file)
index 0000000..0e7a06d
--- /dev/null
@@ -0,0 +1,87 @@
+/* s_cosl.c -- long double version of s_cos.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* cosl(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ *     __kernel_sinl           ... sine function on [-pi/4,pi/4]
+ *     __kernel_cosl           ... cosine function on [-pi/4,pi/4]
+ *     __ieee754_rem_pio2l     ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *     [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *     in [-pi/4 , +pi/4], and let n = k mod 4.
+ *     We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *         0          S           C             T
+ *         1          C          -S            -1/T
+ *         2         -S          -C             T
+ *         3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *     TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+       long double __cosl(long double x)
+#else
+       long double __cosl(x)
+       long double x;
+#endif
+{
+       long double y[2],z=0.0;
+       int32_t n, se;
+
+    /* High word of x. */
+       GET_LDOUBLE_EXP(se,x);
+
+    /* |x| ~< pi/4 */
+       se &= 0x7fff;
+       if(ix <= 0x3ffe) return __kernel_cosl(x,z);
+
+    /* cos(Inf or NaN) is NaN */
+       else if (se==0x7fff) return x-x;
+
+    /* argument reduction needed */
+       else {
+           n = __ieee754_rem_pio2l(x,y);
+           switch(n&3) {
+               case 0: return  __kernel_cosl(y[0],y[1]);
+               case 1: return -__kernel_sinl(y[0],y[1],1);
+               case 2: return -__kernel_cosl(y[0],y[1]);
+               default:
+                       return  __kernel_sinl(y[0],y[1],1);
+           }
+       }
+}
+weak_alias (__cosl, cosl)
diff --git a/sysdeps/libm-ieee754/s_sinl.c b/sysdeps/libm-ieee754/s_sinl.c
new file mode 100644 (file)
index 0000000..ade86df
--- /dev/null
@@ -0,0 +1,87 @@
+/* s_sinl.c -- long double version of s_sin.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* sinl(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ *     __kernel_sinl           ... sine function on [-pi/4,pi/4]
+ *     __kernel_cosl           ... cose function on [-pi/4,pi/4]
+ *     __ieee754_rem_pio2l     ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *     [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *     in [-pi/4 , +pi/4], and let n = k mod 4.
+ *     We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *         0          S           C             T
+ *         1          C          -S            -1/T
+ *         2         -S          -C             T
+ *         3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *     TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+       long double __sinl(long double x)
+#else
+       long double __sinl(x)
+       long double x;
+#endif
+{
+       long double y[2],z=0.0;
+       int32_t n, se;
+
+    /* High word of x. */
+       GET_LDOUBLE_EXP(se,x);
+
+    /* |x| ~< pi/4 */
+       se &= 0x7fff;
+       if(se <= 0x3ffe) return __kernel_sinl(x,z,0);
+
+    /* sin(Inf or NaN) is NaN */
+       else if (se==0x7fff) return x-x;
+
+    /* argument reduction needed */
+       else {
+           n = __ieee754_rem_pio2l(x,y);
+           switch(n&3) {
+               case 0: return  __kernel_sinl(y[0],y[1],1);
+               case 1: return  __kernel_cosl(y[0],y[1]);
+               case 2: return -__kernel_sinl(y[0],y[1],1);
+               default:
+                       return -__kernel_cosl(y[0],y[1]);
+           }
+       }
+}
+weak_alias (__sinl, sinl)
diff --git a/sysdeps/libm-ieee754/s_tanhl.c b/sysdeps/libm-ieee754/s_tanhl.c
new file mode 100644 (file)
index 0000000..984f671
--- /dev/null
@@ -0,0 +1,91 @@
+/* s_tanhl.c -- long double version of s_tanh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* tanhl(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ *                                     x    -x
+ *                                    e  - e
+ *     0. tanhl(x) is defined to be -----------
+ *                                     x    -x
+ *                                    e  + e
+ *     1. reduce x to non-negative by tanhl(-x) = -tanhl(x).
+ *     2.  0      <= x <= 2**-55 : tanhl(x) := x*(one+x)
+ *                                              -t
+ *         2**-55 <  x <=  1     : tanhl(x) := -----; t = expm1l(-2x)
+ *                                             t + 2
+ *                                                   2
+ *         1      <= x <=  23.0  : tanhl(x) := 1-  ----- ; t=expm1l(2x)
+ *                                                 t + 2
+ *         23.0   <  x <= INF    : tanhl(x) := 1.
+ *
+ * Special cases:
+ *     tanhl(NaN) is NaN;
+ *     only tanhl(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one=1.0, two=2.0, tiny = 1.0e-16380L;
+#else
+static long double one=1.0, two=2.0, tiny = 1.0e-16380L;
+#endif
+
+#ifdef __STDC__
+       long double __tanhl(long double x)
+#else
+       long double __tanhl(x)
+       long double x;
+#endif
+{
+       long double t,z;
+       int32_t se,j0,j1,ix;
+
+    /* High word of |x|. */
+       GET_LDOUBLE_WORDS(se,j0,j1,x);
+       ix = se&0x7fff;
+
+    /* x is INF or NaN */
+       if(ix==0x7fff) {
+           if (se>=0x7fff) return one/x+one;    /* tanhl(+-inf)=+-1 */
+           else            return one/x-one;    /* tanhl(NaN) = NaN */
+       }
+
+    /* |x| < 23 */
+       if (ix < 0x4003 || (ix == 0x4003 && j0 < 0xb8000000)) { /* |x|<23 */
+           if (ix<0x3fc8)              /* |x|<2**-55 */
+               return x*(one+x);       /* tanh(small) = small */
+           if (ix>=0x3fff) {   /* |x|>=1  */
+               t = __expm1l(two*fabsl(x));
+               z = one - two/(t+two);
+           } else {
+               t = __expm1l(-two*fabsl(x));
+               z= -t/(t+two);
+           }
+    /* |x| > 23, return +-1 */
+       } else {
+           z = one - tiny;             /* raised inexact flag */
+       }
+       return (se>0x7fff)? z: -z;
+}
+weak_alias (__tanhl, tanhl)
diff --git a/sysdeps/libm-ieee754/s_tanl.c b/sysdeps/libm-ieee754/s_tanl.c
new file mode 100644 (file)
index 0000000..bce6d07
--- /dev/null
@@ -0,0 +1,81 @@
+/* s_tanl.c -- long double version of s_tan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* tanl(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ *     __kernel_tanl           ... tangent function on [-pi/4,pi/4]
+ *     __ieee754_rem_pio2l     ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *     [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *     in [-pi/4 , +pi/4], and let n = k mod 4.
+ *     We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *         0          S           C             T
+ *         1          C          -S            -1/T
+ *         2         -S          -C             T
+ *         3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *     TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+       long double __tanl(long double x)
+#else
+       long double __tanl(x)
+       long double x;
+#endif
+{
+       long double y[2],z=0.0;
+       int32_t n, se;
+
+    /* High word of x. */
+       GET_LDOUBLE_EXP(se,x);
+
+    /* |x| ~< pi/4 */
+       se &= 0x7fff;
+       if(ix <= 0x3ffe) return __kernel_tanl(x,z,1);
+
+    /* tan(Inf or NaN) is NaN */
+       else if (se==0x7fff) return x-x;                /* NaN */
+
+    /* argument reduction needed */
+       else {
+           n = __ieee754_rem_pio2l(x,y);
+           return __kernel_tanl(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
+                                                       -1 -- n odd */
+       }
+}
+weak_alias (__tanl, tanl)